of the register, once we have that information we may be able
to handle some of them more efficiently. */
if (can_create_pseudo_p ()
- && register_operand (op0, mode)
&& (CONSTANT_P (op1)
|| (SUBREG_P (op1)
&& CONSTANT_P (SUBREG_REG (op1))))
- && !standard_sse_constant_p (op1, mode))
- op1 = validize_mem (force_const_mem (mode, op1));
+ && ((register_operand (op0, mode)
+ && !standard_sse_constant_p (op1, mode))
+ /* ix86_expand_vector_move_misalign() does not like constants. */
+ || (SSE_REG_MODE_P (mode)
+ && MEM_P (op0)
+ && MEM_ALIGN (op0) < align)))
+ {
+ if (SUBREG_P (op1))
+ {
+ machine_mode imode = GET_MODE (SUBREG_REG (op1));
+ rtx r = force_const_mem (imode, SUBREG_REG (op1));
+ if (r)
+ r = validize_mem (r);
+ else
+ r = force_reg (imode, SUBREG_REG (op1));
+ op1 = simplify_gen_subreg (mode, r, imode, SUBREG_BYTE (op1));
+ }
+ else
+ op1 = validize_mem (force_const_mem (mode, op1));
+ }
/* We need to check memory alignment for SSE mode since attribute
can make operands unaligned. */
{
rtx tmp[2];
- /* ix86_expand_vector_move_misalign() does not like constants ... */
- if (CONSTANT_P (op1)
- || (SUBREG_P (op1)
- && CONSTANT_P (SUBREG_REG (op1))))
- op1 = validize_mem (force_const_mem (mode, op1));
-
- /* ... nor both arguments in memory. */
+ /* ix86_expand_vector_move_misalign() does not like both
+ arguments in memory. */
if (!register_operand (op0, mode)
&& !register_operand (op1, mode))
op1 = force_reg (mode, op1);