]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
rs6000.md (movdf_hardfloat32): Use worst case insn length attributes for cases 1...
authorDavid Edelsohn <edelsohn@gnu.org>
Mon, 21 Jun 1999 04:18:49 +0000 (04:18 +0000)
committerJeff Law <law@gcc.gnu.org>
Mon, 21 Jun 1999 04:18:49 +0000 (22:18 -0600)
        * rs6000.md (movdf_hardfloat32): Use worst case insn length
        attributes for cases 1 and 2.
        * rs6000.c (find_addr_reg): New function.
        * rs6000.h (find_addr_reg): Declare.
        (offsettable_addr_operand): Delete.
        * rs6000.md (movdf_hardfloat32): Handle non-offsettable loads
        from and stores to GPRs.

From-SVN: r27629

gcc/ChangeLog
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.h
gcc/config/rs6000/rs6000.md

index cc530223d8d9364f7ca34fdbac5a471a4fecc291..1baf016c10f60fafebec26689ebc720d8c5e9c1e 100644 (file)
@@ -1,3 +1,14 @@
+Mon Jun 21 05:17:00 1999  David Edelsohn  <edelsohn@gnu.org>
+
+       * rs6000.md (movdf_hardfloat32): Use worst case insn length
+       attributes for cases 1 and 2.
+
+       * rs6000.c (find_addr_reg): New function.
+       * rs6000.h (find_addr_reg): Declare.
+       (offsettable_addr_operand): Delete.
+       * rs6000.md (movdf_hardfloat32): Handle non-offsettable loads
+       from and stores to GPRs.
+
 Mon Jun 21 04:44:31 1999  Jeffrey A Law  (law@cygnus.com)
 
        * sparc.h (LEGITIMIZE_RELOAD_ADDRESS): Fix paren error introduced
index 433ef20410583426f353f0c3e65681dadfdc12d8..7e6f6090a421c42027f2d61f0272d2c2c17b985c 100644 (file)
@@ -5676,7 +5676,33 @@ rs6000_encode_section_info (decl)
 }
 
 #endif /* USING_SVR4_H */
+
 \f
+/* Return a REG that occurs in ADDR with coefficient 1.
+   ADDR can be effectively incremented by incrementing REG.  */
+
+struct rtx_def *
+find_addr_reg (addr)
+     rtx addr;
+{
+  while (GET_CODE (addr) == PLUS)
+    {
+      if (GET_CODE (XEXP (addr, 0)) == REG)
+       addr = XEXP (addr, 0);
+      else if (GET_CODE (XEXP (addr, 1)) == REG)
+       addr = XEXP (addr, 1);
+      else if (CONSTANT_P (XEXP (addr, 0)))
+       addr = XEXP (addr, 1);
+      else if (CONSTANT_P (XEXP (addr, 1)))
+       addr = XEXP (addr, 0);
+      else
+       abort ();
+    }
+  if (GET_CODE (addr) == REG)
+    return addr;
+  abort ();
+}
+
 void
 rs6000_fatal_bad_address (op)
   rtx op;
index 2f264ea8075aabccb21b31d27dd8540db22748c8..c9634451bf4e13836447eef590466486be639e29 100644 (file)
@@ -3224,13 +3224,13 @@ extern int flag_expensive_optimizations;
 extern int frame_pointer_needed;
 
 /* Declare functions in rs6000.c */
-extern int offsettable_mem_operand ();
 extern void optimization_options ();
 extern void output_options ();
 extern void rs6000_override_options ();
 extern void rs6000_file_start ();
 extern struct rtx_def *rs6000_float_const ();
 extern struct rtx_def *rs6000_got_register ();
+extern struct rtx_def *find_addr_reg();
 extern int direct_return ();
 extern int get_issue_rate ();
 extern int any_operand ();
@@ -3249,7 +3249,7 @@ extern int got_no_const_operand ();
 extern int num_insns_constant ();
 extern int easy_fp_constant ();
 extern int volatile_mem_operand ();
-extern int offsettable_addr_operand ();
+extern int offsettable_mem_operand ();
 extern int mem_or_easy_const_operand ();
 extern int add_operand ();
 extern int non_add_cint_operand ();
index e8338634d82c4f45b79a5d35eed80c6324f8f959..fa6c591871695e9e84770f844bc95ff9aa58a5ea 100644 (file)
 ;; The "??" is a kludge until we can figure out a more reasonable way
 ;; of handling these non-offsettable values.
 (define_insn "*movdf_hardfloat32"
-  [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,o,!r,!r,!r,f,f,m")
-       (match_operand:DF 1 "input_operand" "r,o,r,G,H,F,f,m,f"))]
+  [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,m,!r,!r,!r,f,f,m")
+       (match_operand:DF 1 "input_operand" "r,m,r,G,H,F,f,m,f"))]
   "! TARGET_POWERPC64 && TARGET_HARD_FLOAT
    && (gpc_reg_operand (operands[0], DFmode)
        || gpc_reg_operand (operands[1], DFmode))"
       abort ();
     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.  */
+        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 \"mr %L0,%L1\;mr %0,%1\";
       else
        return \"mr %0,%1\;mr %L0,%L1\";
     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|lwz} %L0,%L1\;{l|lwz} %0,%1\";
+      if (offsettable_memref_p (operands[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|lwz} %L0,%L1\;{l|lwz} %0,%1\";
+         else
+           return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\";
+       }
       else
-       return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\";
+       {
+         rtx addreg;
+
+         if (GET_CODE (XEXP (operands[1], 0)) == PRE_INC
+             || GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
+           abort ();
+
+         addreg = find_addr_reg (XEXP (operands[1], 0));
+         if (refers_to_regno_p (REGNO (operands[0]),
+                                REGNO (operands[0]) + 1,
+                                operands[1], 0))
+           {
+             output_asm_insn (\"{cal|la} %0,4(%0)\", &addreg);
+             output_asm_insn (\"{lx|lwzx} %L0,%1\", operands);
+             output_asm_insn (\"{cal|la} %0,-4(%0)\", &addreg);
+             return \"{lx|lwzx} %0,%1\";
+           }
+         else
+           {
+             output_asm_insn (\"{lx|lwzx} %0,%1\", operands);
+             output_asm_insn (\"{cal|la} %0,4(%0)\", &addreg);
+             output_asm_insn (\"{lx|lwzx} %L0,%1\", operands);
+             output_asm_insn (\"{cal|la} %0,-4(%0)\", &addreg);
+             return \"\";
+           }
+       }
     case 2:
-      return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\";
+      if (offsettable_memref_p (operands[0]))
+       return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\";
+      else
+       {
+         rtx addreg;
+
+         if (GET_CODE (XEXP (operands[1], 0)) == PRE_INC
+             || GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
+           abort ();
+
+         addreg = find_addr_reg (XEXP (operands[0], 0));
+         output_asm_insn (\"{stx|stwx} %1,%0\", operands);
+         output_asm_insn (\"{cal|la} %0,4(%0)\", &addreg);
+         output_asm_insn (\"{stx|stwx} %L1,%0\", operands);
+         output_asm_insn (\"{cal|la} %0,-4(%0)\", &addreg);
+         return \"\";
+       }
     case 3:
     case 4:
     case 5:
     }
 }"
   [(set_attr "type" "*,load,store,*,*,*,fp,fpload,fpstore")
-   (set_attr "length" "8,8,8,8,12,16,*,*,*")])
+   (set_attr "length" "8,16,16,8,12,16,*,*,*")])
 
 (define_insn "*movdf_softfloat32"
   [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m,r,r,r")