[ARM] fix movdi expander to avoid illegal ldrd/strd
* config/arm/arm.md (movdi): Avoid odd-number ldrd/strd in ARM state. From-SVN: r225461
This commit is contained in:
parent
385e3f0c2b
commit
9c769a65e9
@ -1,3 +1,7 @@
|
||||
2015-07-06 Alan Lawrence <alan.lawrence@arm.com>
|
||||
|
||||
* config/arm/arm.md (movdi): Avoid odd-number ldrd/strd in ARM state.
|
||||
|
||||
2015-07-06 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/66772
|
||||
|
@ -5481,6 +5481,42 @@
|
||||
if (!REG_P (operands[0]))
|
||||
operands[1] = force_reg (DImode, operands[1]);
|
||||
}
|
||||
if (REG_P (operands[0]) && REGNO (operands[0]) < FIRST_VIRTUAL_REGISTER
|
||||
&& !HARD_REGNO_MODE_OK (REGNO (operands[0]), DImode))
|
||||
{
|
||||
/* Avoid LDRD's into an odd-numbered register pair in ARM state
|
||||
when expanding function calls. */
|
||||
gcc_assert (can_create_pseudo_p ());
|
||||
if (MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))
|
||||
{
|
||||
/* Perform load into legal reg pair first, then move. */
|
||||
rtx reg = gen_reg_rtx (DImode);
|
||||
emit_insn (gen_movdi (reg, operands[1]));
|
||||
operands[1] = reg;
|
||||
}
|
||||
emit_move_insn (gen_lowpart (SImode, operands[0]),
|
||||
gen_lowpart (SImode, operands[1]));
|
||||
emit_move_insn (gen_highpart (SImode, operands[0]),
|
||||
gen_highpart (SImode, operands[1]));
|
||||
DONE;
|
||||
}
|
||||
else if (REG_P (operands[1]) && REGNO (operands[1]) < FIRST_VIRTUAL_REGISTER
|
||||
&& !HARD_REGNO_MODE_OK (REGNO (operands[1]), DImode))
|
||||
{
|
||||
/* Avoid STRD's from an odd-numbered register pair in ARM state
|
||||
when expanding function prologue. */
|
||||
gcc_assert (can_create_pseudo_p ());
|
||||
rtx split_dest = (MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
|
||||
? gen_reg_rtx (DImode)
|
||||
: operands[0];
|
||||
emit_move_insn (gen_lowpart (SImode, split_dest),
|
||||
gen_lowpart (SImode, operands[1]));
|
||||
emit_move_insn (gen_highpart (SImode, split_dest),
|
||||
gen_highpart (SImode, operands[1]));
|
||||
if (split_dest != operands[0])
|
||||
emit_insn (gen_movdi (operands[0], split_dest));
|
||||
DONE;
|
||||
}
|
||||
"
|
||||
)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user