]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR middle-end/8362 (hard reg not substituted for all pseudos on PowerPC)
authorDavid Edelsohn <edelsohn@gnu.org>
Tue, 26 Nov 2002 15:59:58 +0000 (15:59 +0000)
committerDavid Edelsohn <dje@gcc.gnu.org>
Tue, 26 Nov 2002 15:59:58 +0000 (10:59 -0500)
        * config/rs6000/rs6000.c (rs6000_flag_pic): New variable.
        (rs6000_override_options): Save original flag_pic value.
        (rs6000_encode_section_info): More accurate test for "local" symbol.

        PR 8362
        * config/rs6000/rs6000.c (rs6000_outout_load_multiple): New function.
        * config/rs6000/rs6000.md (ldmsi[3-8]): New patterns.

From-SVN: r59520

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

index cbbf7262d44a6a0c17c2f812ffb765474041396c..04122275c2bfe6d2fc4b7619084f01c2ac1945de 100644 (file)
@@ -1,3 +1,13 @@
+2002-11-26  David Edelsohn  <edelsohn@gnu.org>
+
+        * config/rs6000/rs6000.c (rs6000_flag_pic): New variable.
+       (rs6000_override_options): Save original flag_pic value.
+       (rs6000_encode_section_info): More accurate test for "local" symbol.
+
+       PR 8362
+       * config/rs6000/rs6000.c (rs6000_outout_load_multiple): New function.
+       * config/rs6000/rs6000.md (ldmsi[3-8]): New patterns.
+
 2002-11-25  Christian Ehrhardt  <ehrhardt@mathematik.uni-ulm.de>
 
        PR c/8639
index 19aeb07b9e0c26ca65f3142b7e20980857f6e35e..f6024ec1edf8b09e569adee96f3669014488c281 100644 (file)
@@ -77,6 +77,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 
index 2adb119406f70181e25abb2b4a2eef6d310ff25d..23d73f334595b7efcb6571893fe019959c4c7321 100644 (file)
@@ -77,6 +77,9 @@ int rs6000_altivec_abi;
 /* Set to non-zero once AIX common-mode calls have been defined.  */
 static int common_mode_defined;
 
+/* Private copy of original value of flag_pic for ABI_AIX.  */
+static int rs6000_flag_pic;
+
 /* Save information from a "cmpxx" operation until the branch or scc is
    emitted.  */
 rtx rs6000_compare_op0, rs6000_compare_op1;
@@ -484,11 +487,8 @@ rs6000_override_options (default_cpu)
 
   if (flag_pic != 0 && DEFAULT_ABI == ABI_AIX)
     {
+      rs6000_flag_pic = flag_pic;
       flag_pic = 0;
-
-      if (extra_warnings)
-       warning ("-f%s ignored (all code is position independent)",
-                (flag_pic > 1) ? "PIC" : "pic");
     }
 
 #ifdef XCOFF_DEBUGGING_INFO
@@ -5220,6 +5220,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
@@ -10897,8 +10955,12 @@ rs6000_encode_section_info (decl)
   if (TREE_CODE (decl) == FUNCTION_DECL)
     {
       rtx sym_ref = XEXP (DECL_RTL (decl), 0);
-      if ((TREE_ASM_WRITTEN (decl) || ! TREE_PUBLIC (decl))
-          && ! DECL_WEAK (decl))
+      if (!TREE_PUBLIC (decl)
+         || (!DECL_EXTERNAL (decl)
+             && !DECL_ONE_ONLY (decl)
+             && !DECL_WEAK (decl)
+             && !flag_pic
+             && !rs6000_flag_pic))
        SYMBOL_REF_FLAG (sym_ref) = 1;
 
       if (DEFAULT_ABI == ABI_AIX)
index 6e86d734f66348a77623330493cd5731c15c15d3..ec16c1918637b8872a87bc1cefff442b68e1353a 100644 (file)
                     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"))