OSDN Git Service

(movdf): Simplify by taking advantage of having SECONDARY_MEMORY_NEEDED.
authorkenner <kenner@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 1 Sep 1993 22:42:37 +0000 (22:42 +0000)
committerkenner <kenner@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 1 Sep 1993 22:42:37 +0000 (22:42 +0000)
Fix bugs relating to order in which moves are done.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@5243 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/config/rs6000/rs6000.md

index de33ba9..d60358e 100644 (file)
   ""
   "
 {
-  /* If we are called from reload, we might be getting a SUBREG of a hard
-     reg.  So expand it.  */
-  if (GET_CODE (operands[0]) == SUBREG
-      && GET_CODE (SUBREG_REG (operands[0])) == REG
-      && REGNO (SUBREG_REG (operands[0])) < FIRST_PSEUDO_REGISTER)
-    operands[0] = alter_subreg (operands[0]);
-  if (GET_CODE (operands[1]) == SUBREG
-      && GET_CODE (SUBREG_REG (operands[1])) == REG
-      && REGNO (SUBREG_REG (operands[1])) < FIRST_PSEUDO_REGISTER)
-    operands[1] = alter_subreg (operands[1]);
-
-  if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) < 32)
+  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
     {
-      rtx stack_slot;
-
-      /* If this is a store to memory or another integer register do the
-        move directly.  Otherwise store to a temporary stack slot and
-        load from there into a floating point register.  */
-
-      if (GET_CODE (operands[0]) == MEM
-         || (GET_CODE (operands[0]) == REG
-             && (REGNO (operands[0]) < 32
-                 || (reload_in_progress
-                     && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER))))
-       {
-         emit_move_insn (operand_subword (operands[0], 0, 0, DFmode),
-                         operand_subword (operands[1], 0, 0, DFmode));
-         emit_move_insn (operand_subword (operands[0], 1, 0, DFmode),
-                         operand_subword (operands[1], 1, 0, DFmode));
-         DONE;
-       }
-
-      stack_slot = gen_rtx (MEM, DFmode, plus_constant (stack_pointer_rtx, 8));
-      emit_move_insn (stack_slot, operands[1]);
-      emit_move_insn (operands[0], stack_slot);
+      emit_move_insn (operand_subword (operands[0], 1, 1, DFmode),
+                     operand_subword_force (operands[1], 1, DFmode));
+      emit_move_insn (operand_subword (operands[0], 0, 1, DFmode),
+                     operand_subword_force (operands[1], 0, DFmode));
       DONE;
     }
 
-  if (GET_CODE (operands[0]) == MEM)
-    {
-      if (GET_CODE (operands[1]) == MEM)
-       {
-         emit_move_insn (operand_subword (operands[0], 0, 0, DFmode),
-                         operand_subword (operands[1], 0, 0, DFmode));
-         emit_move_insn (operand_subword (operands[0], 1, 0, DFmode),
-                         operand_subword (operands[1], 1, 0, DFmode));
-         DONE;
-       }
-      
-      operands[1] = force_reg (DFmode, operands[1]);
-    }
-
-  if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) < 32)
-    {
-      rtx stack_slot;
-
-      if (GET_CODE (operands[1]) == MEM
-#if HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT && ! defined(REAL_IS_NOT_DOUBLE)
-         || GET_CODE (operands[1]) == CONST_DOUBLE
-#endif
-         || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) < 32)
-         || (reload_in_progress && GET_CODE (operands[1]) == REG
-             && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER))
-       {
-         emit_move_insn (operand_subword (operands[0], 0, 0, DFmode),
-                         operand_subword (operands[1], 0, 0, DFmode));
-         emit_move_insn (operand_subword (operands[0], 1, 0, DFmode),
-                         operand_subword (operands[1], 1, 0, DFmode));
-         DONE;
-       }
-
-      if (reload_in_progress)
-       stack_slot = gen_rtx (MEM, DFmode,
-                             plus_constant (stack_pointer_rtx, 8));
-      else
-       stack_slot = assign_stack_temp (DFmode, 8, 0);
-      emit_move_insn (stack_slot, operands[1]);
-      emit_move_insn (operands[0], stack_slot);
-      DONE;
-    }
+  if (GET_CODE (operands[0]) != REG)
+    operands[1] = force_reg (DFmode, operands[1]);
 
-  if (CONSTANT_P (operands[1]))
+  if (CONSTANT_P (operands[1]) && ! easy_fp_constant (operands[1], DFmode))
     {
       operands[1] = force_const_mem (DFmode, operands[1]);
       if (! memory_address_p (DFmode, XEXP (operands[1], 0))
        operands[1] = change_address (operands[1], DFmode,
                                      XEXP (operands[1], 0));
     }
-}")
 
-(define_insn ""
-  [(set (match_operand:DF 0 "gpc_reg_operand" "=r,r")
-       (match_operand:DF 1 "mem_or_easy_const_operand" "G,m"))]
-  "REGNO (operands[0]) <= 31"
-  "@
-   #
-   l %0,%1\;l %L0,%L1"
-  [(set_attr "type" "*,load")
-   (set_attr "length" "*,8")])
+}")
 
 (define_split
   [(set (match_operand:DF 0 "gpc_reg_operand" "")
   operands[3] = operand_subword (operands[1], 0, 0, DFmode);
   operands[4] = operand_subword (operands[0], 1, 0, DFmode);
   operands[5] = operand_subword (operands[1], 1, 0, DFmode); }")
-  
+
 (define_insn ""
-  [(set (match_operand:DF 0 "fp_reg_or_mem_operand" "=f,f,m")
-       (match_operand:DF 1 "fp_reg_or_mem_operand" "f,m,f"))]
-  "gpc_reg_operand (operands[0], DFmode)
-   || gpc_reg_operand (operands[1], DFmode)"
-  "@
-   fmr %0,%1
-   lfd%U1%X1 %0,%1
-   stfd%U0%X0 %1,%0"
-  [(set_attr "type" "fp,load,*")])
+  [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,r,o,r,f,f,m")
+       (match_operand:DF 1 "input_operand" "r,o,r,G,f,m,f"))]
+  "register_operand (operands[0], DFmode)
+   || register_operand (operands[1], DFmode)"
+  "*
+{
+  switch (which_alternative)
+    {
+    case 0:
+      /* We normally copy the low-numbered register first.  However, if
+        the first register operand 0 is the same as the second register of
+        operand 1, we must copy in the opposite order.  */
+      if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
+       return \"oril %L0,%L1,0\;oril %0,%1,0\";
+      else
+       return \"oril %0,%1,0\;oril %L0,%L1,0\";
+    case 1:
+      /* If the low-address word is used in the address, we must load it
+        last.  Otherwise, load it first.  Note that we cannot have
+        auto-increment in that case since the address register is known to be
+        dead.  */
+      if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
+                            operands [1], 0))
+       return \"l %L0,%L1\;l %0,%1\";
+      else
+       return \"l%U1 %0,%1\;l %L0,%L1\";
+    case 2:
+      return \"st%U0 %1,%0\;st %L1,%L0\";
+    case 3:
+      return \"#\";
+    case 4:
+      return \"fmr %0,%1\";
+    case 5:
+      return \"lfd%U1%X1 %0,%1\";
+    case 6:
+      return \"stfd%U0%X0 %1,%0\";
+    }
+}"
+  [(set_attr "type" "*,load,*,*,fp,load,*")
+   (set_attr "length" "8,8,8,8,*,*,*")])
 \f
 ;; Next come the multi-word integer load and store and the load and store
 ;; multiple insns.