OSDN Git Service

* config/rs6000/rs6000.c (rs6000_outout_load_multiple): New function.
authordje <dje@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 16 Nov 2002 18:01:51 +0000 (18:01 +0000)
committerdje <dje@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 16 Nov 2002 18:01:51 +0000 (18:01 +0000)
        * config/rs6000/rs6000.md (movti_string): Remove output modifier
        when scratch register never needed.
        (ldmsi[3-8]): New patterns.

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

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

index 2a80b55..f023800 100644 (file)
@@ -1,3 +1,10 @@
+2002-11-16  David Edelsohn  <edelsohn@gnu.org>
+
+       * config/rs6000/rs6000.c (rs6000_outout_load_multiple): New function.
+       * config/rs6000/rs6000.md (movti_string): Remove output modifier
+       when scratch register never needed.
+       (ldmsi[3-8]): New patterns.
+
 2002-11-16  Kazu Hirata  <kazu@cs.umass.edu>
 
        * hard-reg-set.h: Follow spelling conventions.
index 53d8192..a7ec02b 100644 (file)
@@ -84,6 +84,7 @@ extern int constant_pool_expr_p PARAMS ((rtx));
 extern int toc_relative_expr_p PARAMS ((rtx));
 extern int expand_block_move PARAMS ((rtx[]));
 extern int load_multiple_operation PARAMS ((rtx, enum machine_mode));
+extern const char * rs6000_output_load_multiple PARAMS ((rtx[]));
 extern int store_multiple_operation PARAMS ((rtx, enum machine_mode));
 extern int branch_comparison_operator PARAMS ((rtx, enum machine_mode));
 extern int branch_positive_comparison_operator 
@@ -186,7 +187,7 @@ extern void rs6000_emit_load_toc_table PARAMS ((int));
 extern void rs6000_aix_emit_builtin_unwind_init PARAMS ((void));
 extern void rs6000_emit_epilogue PARAMS ((int));
 extern void debug_stack_info PARAMS ((rs6000_stack_t *));
-extern const char *output_isel PARAMS ((rtx *));
+extern const char * output_isel PARAMS ((rtx *));
 extern int vrsave_operation PARAMS ((rtx, enum machine_mode));
 extern int rs6000_register_move_cost PARAMS ((enum machine_mode,
                                              enum reg_class, enum reg_class));
index 4dd911e..5dd2e12 100644 (file)
@@ -6390,6 +6390,64 @@ store_multiple_operation (op, mode)
   return 1;
 }
 
+/* Return a string to perform a load_multiple operation.
+   operands[0] is the vector.
+   operands[1] is the source address.
+   operands[2] is the first destination register.  */
+
+const char *
+rs6000_output_load_multiple (operands)
+     rtx operands[2];
+{
+  /* We have to handle the case where the pseudo used to contain the address
+     is assigned to one of the output registers.  */
+  int i, j;
+  int words = XVECLEN (operands[0], 0);
+  rtx xop[10];
+
+  if (XVECLEN (operands[0], 0) == 1)
+    return "{l|lwz} %2,0(%1)";
+
+  for (i = 0; i < words; i++)
+    if (refers_to_regno_p (REGNO (operands[2]) + i,
+                          REGNO (operands[2]) + i + 1, operands[1], 0))
+      {
+       if (i == words-1)
+         {
+           xop[0] = GEN_INT (4 * (words-1));
+           xop[1] = operands[1];
+           xop[2] = operands[2];
+           output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
+           return "";
+         }
+       else if (i == 0)
+         {
+           xop[0] = GEN_INT (4 * (words-1));
+           xop[1] = operands[1];
+           xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
+           output_asm_insn ("{cal %1,4(%1)|addi %1,%1,4}\n\t{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,-4(%1)", xop);
+           return "";
+         }
+       else
+         {
+           for (j = 0; j < words; j++)
+             if (j != i)
+               {
+                 xop[0] = GEN_INT (j * 4);
+                 xop[1] = operands[1];
+                 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
+                 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
+               }
+           xop[0] = GEN_INT (i * 4);
+           xop[1] = operands[1];
+           output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
+           return "";
+         }
+      }
+
+  return "{lsi|lswi} %2,%1,%N0";
+}
+
 /* Return 1 for a parallel vrsave operation.  */
 
 int
index f221c17..853dab2 100644 (file)
 (define_insn "*movti_string"
   [(set (match_operand:TI 0 "reg_or_mem_operand" "=Q,m,????r,????r,????r")
        (match_operand:TI 1 "reg_or_mem_operand" "r,r,r,Q,m"))
-   (clobber (match_scratch:SI 2 "=X,X,X,X,X"))]
+   (clobber (match_scratch:SI 2 "X,X,X,X,X"))]
   "TARGET_STRING && ! TARGET_POWER && ! TARGET_POWERPC64
    && (gpc_reg_operand (operands[0], TImode) || gpc_reg_operand (operands[1], TImode))"
   "*
                     adjust_address (op1, SImode, i * 4));
 }")
 
-(define_insn ""
+(define_insn "*ldmsi8"
   [(match_parallel 0 "load_multiple_operation"
-                  [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
-                        (mem:SI (match_operand:SI 2 "gpc_reg_operand" "b")))])]
-  "TARGET_STRING"
+    [(set (match_operand:SI 2 "gpc_reg_operand" "")
+          (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
+     (set (match_operand:SI 3 "gpc_reg_operand" "")
+          (mem:SI (plus:SI (match_dup 1) (const_int 4))))
+     (set (match_operand:SI 4 "gpc_reg_operand" "")
+          (mem:SI (plus:SI (match_dup 1) (const_int 8))))
+     (set (match_operand:SI 5 "gpc_reg_operand" "")
+          (mem:SI (plus:SI (match_dup 1) (const_int 12))))
+     (set (match_operand:SI 6 "gpc_reg_operand" "")
+          (mem:SI (plus:SI (match_dup 1) (const_int 16))))
+     (set (match_operand:SI 7 "gpc_reg_operand" "")
+          (mem:SI (plus:SI (match_dup 1) (const_int 20))))
+     (set (match_operand:SI 8 "gpc_reg_operand" "")
+          (mem:SI (plus:SI (match_dup 1) (const_int 24))))
+     (set (match_operand:SI 9 "gpc_reg_operand" "")
+          (mem:SI (plus:SI (match_dup 1) (const_int 28))))])]
+  "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
   "*
-{
-  /* We have to handle the case where the pseudo used to contain the address
-     is assigned to one of the output registers.  */
-  int i, j;
-  int words = XVECLEN (operands[0], 0);
-  rtx xop[10];
+{ return rs6000_output_load_multiple (operands); }"
+  [(set_attr "type" "load")
+   (set_attr "length" "32")])
 
-  if (XVECLEN (operands[0], 0) == 1)
-    return \"{l|lwz} %1,0(%2)\";
+(define_insn "*ldmsi7"
+  [(match_parallel 0 "load_multiple_operation"
+    [(set (match_operand:SI 2 "gpc_reg_operand" "")
+          (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
+     (set (match_operand:SI 3 "gpc_reg_operand" "")
+          (mem:SI (plus:SI (match_dup 1) (const_int 4))))
+     (set (match_operand:SI 4 "gpc_reg_operand" "")
+          (mem:SI (plus:SI (match_dup 1) (const_int 8))))
+     (set (match_operand:SI 5 "gpc_reg_operand" "")
+          (mem:SI (plus:SI (match_dup 1) (const_int 12))))
+     (set (match_operand:SI 6 "gpc_reg_operand" "")
+          (mem:SI (plus:SI (match_dup 1) (const_int 16))))
+     (set (match_operand:SI 7 "gpc_reg_operand" "")
+          (mem:SI (plus:SI (match_dup 1) (const_int 20))))
+     (set (match_operand:SI 8 "gpc_reg_operand" "")
+          (mem:SI (plus:SI (match_dup 1) (const_int 24))))])]
+  "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
+  "*
+{ return rs6000_output_load_multiple (operands); }"
+  [(set_attr "type" "load")
+   (set_attr "length" "32")])
 
-  for (i = 0; i < words; i++)
-    if (refers_to_regno_p (REGNO (operands[1]) + i,
-                          REGNO (operands[1]) + i + 1, operands[2], 0))
-      {
-       if (i == words-1)
-         {
-           xop[0] = operands[1];
-           xop[1] = operands[2];
-           xop[2] = GEN_INT (4 * (words-1));
-           output_asm_insn (\"{lsi|lswi} %0,%1,%2\;{l|lwz} %1,%2(%1)\", xop);
-           return \"\";
-         }
-       else if (i == 0)
-         {
-           xop[0] = operands[1];
-           xop[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
-           xop[2] = GEN_INT (4 * (words-1));
-           output_asm_insn (\"{cal %0,4(%0)|addi %0,%0,4}\;{lsi|lswi} %1,%0,%2\;{l|lwz} %0,-4(%0)\", xop);
-           return \"\";
-         }
-       else
-         {
-           for (j = 0; j < words; j++)
-             if (j != i)
-               {
-                 xop[0] = gen_rtx_REG (SImode, REGNO (operands[1]) + j);
-                 xop[1] = operands[2];
-                 xop[2] = GEN_INT (j * 4);
-                 output_asm_insn (\"{l|lwz} %0,%2(%1)\", xop);
-               }
-           xop[0] = operands[2];
-           xop[1] = GEN_INT (i * 4);
-           output_asm_insn (\"{l|lwz} %0,%1(%0)\", xop);
-           return \"\";
-         }
-      }
+(define_insn "*ldmsi6"
+  [(match_parallel 0 "load_multiple_operation"
+    [(set (match_operand:SI 2 "gpc_reg_operand" "")
+          (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
+     (set (match_operand:SI 3 "gpc_reg_operand" "")
+          (mem:SI (plus:SI (match_dup 1) (const_int 4))))
+     (set (match_operand:SI 4 "gpc_reg_operand" "")
+          (mem:SI (plus:SI (match_dup 1) (const_int 8))))
+     (set (match_operand:SI 5 "gpc_reg_operand" "")
+          (mem:SI (plus:SI (match_dup 1) (const_int 12))))
+     (set (match_operand:SI 6 "gpc_reg_operand" "")
+          (mem:SI (plus:SI (match_dup 1) (const_int 16))))
+     (set (match_operand:SI 7 "gpc_reg_operand" "")
+          (mem:SI (plus:SI (match_dup 1) (const_int 20))))])]
+  "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
+  "*
+{ return rs6000_output_load_multiple (operands); }"
+  [(set_attr "type" "load")
+   (set_attr "length" "32")])
 
-  return \"{lsi|lswi} %1,%2,%N0\";
-}"
+(define_insn "*ldmsi5"
+  [(match_parallel 0 "load_multiple_operation"
+    [(set (match_operand:SI 2 "gpc_reg_operand" "")
+          (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
+     (set (match_operand:SI 3 "gpc_reg_operand" "")
+          (mem:SI (plus:SI (match_dup 1) (const_int 4))))
+     (set (match_operand:SI 4 "gpc_reg_operand" "")
+          (mem:SI (plus:SI (match_dup 1) (const_int 8))))
+     (set (match_operand:SI 5 "gpc_reg_operand" "")
+          (mem:SI (plus:SI (match_dup 1) (const_int 12))))
+     (set (match_operand:SI 6 "gpc_reg_operand" "")
+          (mem:SI (plus:SI (match_dup 1) (const_int 16))))])]
+  "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
+  "*
+{ return rs6000_output_load_multiple (operands); }"
+  [(set_attr "type" "load")
+   (set_attr "length" "32")])
+
+(define_insn "*ldmsi4"
+  [(match_parallel 0 "load_multiple_operation"
+    [(set (match_operand:SI 2 "gpc_reg_operand" "")
+          (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
+     (set (match_operand:SI 3 "gpc_reg_operand" "")
+          (mem:SI (plus:SI (match_dup 1) (const_int 4))))
+     (set (match_operand:SI 4 "gpc_reg_operand" "")
+          (mem:SI (plus:SI (match_dup 1) (const_int 8))))
+     (set (match_operand:SI 5 "gpc_reg_operand" "")
+          (mem:SI (plus:SI (match_dup 1) (const_int 12))))])]
+  "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
+  "*
+{ return rs6000_output_load_multiple (operands); }"
+  [(set_attr "type" "load")
+   (set_attr "length" "32")])
+
+(define_insn "*ldmsi3"
+  [(match_parallel 0 "load_multiple_operation"
+    [(set (match_operand:SI 2 "gpc_reg_operand" "")
+          (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
+     (set (match_operand:SI 3 "gpc_reg_operand" "")
+          (mem:SI (plus:SI (match_dup 1) (const_int 4))))
+     (set (match_operand:SI 4 "gpc_reg_operand" "")
+          (mem:SI (plus:SI (match_dup 1) (const_int 8))))])]
+  "TARGET_STRING && XVECLEN (operands[0], 0) == 3"
+  "*
+{ return rs6000_output_load_multiple (operands); }"
   [(set_attr "type" "load")
    (set_attr "length" "32")])
 
-\f
 (define_expand "store_multiple"
   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
                          (match_operand:SI 1 "" ""))
                     gen_rtx_REG (SImode, regno + i));
 }")
 
-(define_insn ""
+(define_insn "*store_multiple_power"
   [(match_parallel 0 "store_multiple_operation"
                   [(set (match_operand:SI 1 "indirect_operand" "=Q")
                         (match_operand:SI 2 "gpc_reg_operand" "r"))
   "{stsi|stswi} %2,%P1,%O0"
   [(set_attr "type" "store")])
 
-(define_insn ""
+(define_insn "*store_multiple_string"
   [(match_parallel 0 "store_multiple_operation"
                   [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
                         (match_operand:SI 2 "gpc_reg_operand" "r"))