aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Stallman <rms@gnu.org>1992-10-25 22:21:26 +0000
committerRichard Stallman <rms@gnu.org>1992-10-25 22:21:26 +0000
commit81fd0956da41b5cb6986fcb6b20f24bc4569367e (patch)
tree9fd56925d2e375655a7f4552eaa1b5606b8fe026
parent555b950bd1b8f0605f62913ef845bafcf697d1f6 (diff)
downloadgcc-81fd0956da41b5cb6986fcb6b20f24bc4569367e.zip
gcc-81fd0956da41b5cb6986fcb6b20f24bc4569367e.tar.gz
gcc-81fd0956da41b5cb6986fcb6b20f24bc4569367e.tar.bz2
(output_move_double): Divert first word via the stack
if it's a register used in the input operand. From-SVN: r2602
-rw-r--r--gcc/config/i386/i386.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 70c3cba..c9265c6 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -42,6 +42,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#define AT_BP(mode) (gen_rtx (MEM, (mode), frame_pointer_rtx))
+extern rtx gen_push_operand ();
extern FILE *asm_out_file;
extern char *strcat ();
@@ -243,6 +244,7 @@ output_move_double (operands)
enum {REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP } optype0, optype1;
rtx latehalf[2];
rtx addreg0 = 0, addreg1 = 0;
+ rtx pop_after = 0;
/* First classify both operands. */
@@ -352,6 +354,16 @@ output_move_double (operands)
&& reg_overlap_mentioned_p (stack_pointer_rtx, operands[1]))
operands[1] = latehalf[1];
+ /* For (set (reg:DI N) (mem:DI ... (reg:SI N) ...)),
+ push the first word on the stack, and pop it off afterward. */
+ if (optype0 == REGOP
+ && refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
+ operands[1], 0))
+ {
+ pop_after = operands[0];
+ operands[0] = gen_rtx (MEM, SImode, gen_push_operand ());
+ }
+
/* If one or both operands autodecrementing,
do the two words, high-numbered first. */
@@ -402,6 +414,11 @@ output_move_double (operands)
if (addreg1)
asm_add (-4, addreg1);
+ /* If we diverted a word to the stack, pop it now
+ to the proper register. */
+ if (pop_after != 0)
+ output_asm_insn ("pop%L0 %0", &pop_after);
+
return "";
}