+Mon Jan 24 16:50:08 MET 2000 Jan Hubicka <jh@suse.cz>
+
+ * 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 <zack@wolery.cumb.org>
* fixinc/fixfixes.c (fix_char_macro_uses): Correct regular
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));
#endif
}
\f
-/* 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;
-}
-\f
/* 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. */
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;
+}
\f
/* 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
#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}}, \
}
}"
[(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))
(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")))
[(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
(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" "")
(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