Fix DImode move problems.
authorMichael Meissner <meissner@gcc.gnu.org>
Sat, 3 Sep 1994 18:18:53 +0000 (18:18 +0000)
committerMichael Meissner <meissner@gcc.gnu.org>
Sat, 3 Sep 1994 18:18:53 +0000 (18:18 +0000)
From-SVN: r8022

gcc/config/i386/i386.md

index 1b6017e..f2fccf8 100644 (file)
   "* return output_move_double (operands);")
 
 (define_insn ""
-  [(set (match_operand:DI 0 "push_operand" "=<")
-       (match_operand:DI 1 "nonmemory_operand" "riF"))
-   (clobber (match_scratch:SI 2 "X"))
-   (clobber (match_scratch:SI 3 "X"))]
-  "!TARGET_386 && TARGET_MOVE"
-  "* return output_move_double (operands);")
+  [(set (match_operand:DI 0 "push_operand" "=<,<,<")
+       (match_operand:DI 1 "general_operand" "riF,o,o"))
+   (clobber (match_scratch:SI 2 "X,=&r,=&r"))
+   (clobber (match_scratch:SI 3 "X,=&r,X"))]
+  "!TARGET_386"
+  "*
+{
+  rtx low[1], high[1], xop[4];
 
-(define_insn ""
-  [(set (match_operand:DI 0 "push_operand" "=<")
-       (match_operand:DI 1 "general_operand" "roiF"))
-   (clobber (match_scratch:SI 2 "X"))
-   (clobber (match_scratch:SI 3 "X"))]
-  "!TARGET_386 && !TARGET_MOVE"
-  "* return output_move_double (operands);")
+  split_di (&operands[1], 1, low, high);
+  xop[0] = operands[2];
+  xop[1] = operands[3];
+  xop[2] = high[0];
+  xop[3] = low[0];
 
-(define_expand "movdi"
-  [(parallel [(set (match_operand:DI 0 "general_operand" "")
-                  (match_operand:DI 1 "general_operand" ""))
-             (clobber (match_scratch:SI 2 ""))
-             (clobber (match_scratch:SI 3 ""))])]
-  ""
-  "
-{
-  /* Don't generate memory->memory moves, go through a register */
-  if (TARGET_MOVE
-      && (reload_in_progress | reload_completed) == 0
-      && GET_CODE (operands[0]) == MEM
-      && GET_CODE (operands[1]) == MEM)
+  if (GET_CODE (operands[1]) != MEM)
     {
-      operands[1] = force_reg (DImode, operands[1]);
+      output_asm_insn (AS1 (push%L0,%2), xop);
+      output_asm_insn (AS1 (push%L0,%3), xop);
     }
+  else if (GET_CODE (operands[3]) == REG)
+    {                          /* 2 scratch registers available */
+      output_asm_insn (AS2 (mov%L0,%2,%0), xop);
+      output_asm_insn (AS2 (mov%L0,%3,%1), xop);
+      output_asm_insn (AS1 (push%L0,%0), xop);
+      output_asm_insn (AS1 (push%L0,%1), xop);
+    }
+  else
+    {                          /* 1 scratch register */
+      output_asm_insn (AS2 (mov%L0,%2,%0), xop);
+      output_asm_insn (AS1 (push%L0,%0), xop);
+      output_asm_insn (AS2 (mov%L0,%3,%0), xop);
+      output_asm_insn (AS1 (push%L0,%0), xop);
+    }
+
+  RET;
 }")
 
-(define_insn ""
+(define_insn "movdi"
   [(set (match_operand:DI 0 "general_operand" "=r,rm,o,o")
        (match_operand:DI 1 "general_operand" "m,riF,o,o"))
    (clobber (match_scratch:SI 2 "X,X,=&r,=&r"))