diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3dbfb112cda..40053440e88 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +Mon Jan 24 16:50:08 MET 2000 Jan Hubicka + + * i386.h (PREDICATE_CODES): Add aligned_operand. + * i386.c (aligned_operand): New function. + (ix86_aligned_p): Kill. + * i386.md (movhi_1): Emit mov for aligned operands. + (promoting peep2s): Use aligned_operand. + 2000-01-23 Zack Weinberg * fixinc/fixfixes.c (fix_char_macro_uses): Correct regular diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h index 02ef4d08da6..d589e4f110a 100644 --- a/gcc/config/i386/i386-protos.h +++ b/gcc/config/i386/i386-protos.h @@ -64,6 +64,7 @@ extern int promotable_binary_operator PARAMS ((rtx, enum machine_mode)); extern int memory_displacement_operand PARAMS ((rtx, enum machine_mode)); extern int cmpsi_operand PARAMS ((rtx, enum machine_mode)); extern int long_memory_operand PARAMS ((rtx, enum machine_mode)); +extern int aligned_operand PARAMS ((rtx, enum machine_mode)); extern int legitimate_pic_address_disp_p PARAMS ((rtx)); diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index c002262f542..320237e8a7a 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -678,57 +678,6 @@ optimization_options (level, size) #endif } -/* Return nonzero if the rtx is known aligned. */ -/* ??? Unused. */ - -int -ix86_aligned_p (op) - rtx op; -{ - struct ix86_address parts; - - /* Registers and immediate operands are always "aligned". */ - if (GET_CODE (op) != MEM) - return 1; - - /* Don't even try to do any aligned optimizations with volatiles. */ - if (MEM_VOLATILE_P (op)) - return 0; - - op = XEXP (op, 0); - - /* Pushes and pops are only valid on the stack pointer. */ - if (GET_CODE (op) == PRE_DEC - || GET_CODE (op) == POST_INC) - return 1; - - /* Decode the address. */ - if (! ix86_decompose_address (op, &parts)) - abort (); - - /* Look for some component that isn't known to be aligned. */ - if (parts.index) - { - if (parts.scale < 4 - && REGNO_POINTER_ALIGN (REGNO (parts.index)) < 4) - return 0; - } - if (parts.base) - { - if (REGNO_POINTER_ALIGN (REGNO (parts.index)) < 4) - return 0; - } - if (parts.disp) - { - if (GET_CODE (parts.disp) != CONST_INT - || (INTVAL (parts.disp) & 3) != 0) - return 0; - } - - /* Didn't find one -- this must be an aligned address. */ - return 1; -} - /* Return nonzero if IDENTIFIER with arguments ARGS is a valid machine specific attribute for DECL. The attributes in ATTRIBUTES have previously been assigned to DECL. */ @@ -1422,6 +1371,60 @@ long_memory_operand (op, mode) return memory_address_length (op) != 0; } + +/* Return nonzero if the rtx is known aligned. */ + +int +aligned_operand (op, mode) + rtx op; + enum machine_mode mode; +{ + struct ix86_address parts; + + if (!general_operand (op, mode)) + return 0; + + /* Registers and immediate operands are always "aligned". */ + if (GET_CODE (op) != MEM) + return 1; + + /* Don't even try to do any aligned optimizations with volatiles. */ + if (MEM_VOLATILE_P (op)) + return 0; + + op = XEXP (op, 0); + + /* Pushes and pops are only valid on the stack pointer. */ + if (GET_CODE (op) == PRE_DEC + || GET_CODE (op) == POST_INC) + return 1; + + /* Decode the address. */ + if (! ix86_decompose_address (op, &parts)) + abort (); + + /* Look for some component that isn't known to be aligned. */ + if (parts.index) + { + if (parts.scale < 4 + && REGNO_POINTER_ALIGN (REGNO (parts.index)) < 4) + return 0; + } + if (parts.base) + { + if (REGNO_POINTER_ALIGN (REGNO (parts.base)) < 4) + return 0; + } + if (parts.disp) + { + if (GET_CODE (parts.disp) != CONST_INT + || (INTVAL (parts.disp) & 3) != 0) + return 0; + } + + /* Didn't find one -- this must be an aligned address. */ + return 1; +} /* Return true if the constant is something that can be loaded with a special instruction. Only handle 0.0 and 1.0; others are less diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index 859b4604e09..74cd5d69399 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -2400,6 +2400,8 @@ do { long l; \ #define PREDICATE_CODES \ {"symbolic_operand", {SYMBOL_REF, LABEL_REF, CONST}}, \ + {"aligned_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF, \ + LABEL_REF, SUBREG, REG, MEM}}, \ {"pic_symbolic_operand", {CONST}}, \ {"call_insn_operand", {MEM}}, \ {"expander_call_insn_operand", {MEM}}, \ diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 0bd53241690..fac96f5b5c0 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -1397,7 +1397,8 @@ } }" [(set (attr "type") - (cond [(eq_attr "alternative" "0") + (cond [(and (eq_attr "alternative" "0,1") + (match_operand:HI 1 "aligned_operand" "")) (const_string "imov") (and (ne (symbol_ref "TARGET_MOVX") (const_int 0)) @@ -1408,9 +1409,10 @@ (set (attr "length_prefix") (cond [(eq_attr "type" "imovx") (const_string "0") - (and (eq_attr "alternative" "0") - (eq (symbol_ref "TARGET_PARTIAL_REG_STALL") - (const_int 0))) + (and (eq_attr "alternative" "0,1") + (and (match_operand:HI 1 "aligned_operand" "") + (eq (symbol_ref "TARGET_PARTIAL_REG_STALL") + (const_int 0)))) (const_string "0") ] (const_string "1"))) @@ -8562,7 +8564,7 @@ [(set (match_operand 0 "register_operand" "") (match_operator 3 "promotable_binary_operator" [(match_operand 1 "register_operand" "") - (match_operand 2 "nonmemory_operand" "")])) + (match_operand 2 "aligned_operand" "")])) (clobber (reg:CC 17))] "! TARGET_PARTIAL_REG_STALL && reload_completed && ((GET_MODE (operands[0]) == HImode @@ -8581,7 +8583,7 @@ (define_split [(set (reg:CCNO 17) - (compare:CCNO (and (match_operand 1 "register_operand" "") + (compare:CCNO (and (match_operand 1 "aligned_operand" "") (match_operand 2 "immediate_operand" "")) (const_int 0))) (set (match_operand 0 "register_operand" "") @@ -8601,7 +8603,7 @@ (define_split [(set (reg:CCNO 17) - (compare:CCNO (and (match_operand 0 "register_operand" "") + (compare:CCNO (and (match_operand 0 "aligned_operand" "") (match_operand 1 "immediate_operand" "")) (const_int 0)))] "! TARGET_PARTIAL_REG_STALL && reload_completed