re PR target/36634 (-msecure-plt combine gives invalid call insn)
authorAlan Modra <amodra@bigpond.net.au>
Fri, 4 Jul 2008 02:32:01 +0000 (02:32 +0000)
committerAlan Modra <amodra@gcc.gnu.org>
Fri, 4 Jul 2008 02:32:01 +0000 (12:02 +0930)
PR target/36634
* config/rs6000/rs6000.md (call, call_value): Don't arrange for
pic_offset_table_rtx to be marked as used here.
(call_nonlocal_sysv, call_value_nonlocal_sysv): Add split for
TARGET_SECURE_PLT to "use" pic_offset_table_rtx.
(call_nonlocal_sysv_secure, call_value_nonlocal_sysv_secure): New insn.
(sibcall_nonlocal_sysv, sibcall_value_nonlocal_sysv): Assert
!TARGET_SECURE_PLT.

From-SVN: r137447

gcc/ChangeLog
gcc/config/rs6000/rs6000.md

index dd3ece4d710050ac3e8cf31c031cd40c439f5ab7..cfdf170e1ec2383e50e5ce10f0704b6564df09e4 100644 (file)
@@ -1,3 +1,14 @@
+2008-07-04  Alan Modra  <amodra@bigpond.net.au>
+
+       PR target/36634
+       * config/rs6000/rs6000.md (call, call_value): Don't arrange for
+       pic_offset_table_rtx to be marked as used here.
+       (call_nonlocal_sysv, call_value_nonlocal_sysv): Add split for
+       TARGET_SECURE_PLT to "use" pic_offset_table_rtx.
+       (call_nonlocal_sysv_secure, call_value_nonlocal_sysv_secure): New insn.
+       (sibcall_nonlocal_sysv, sibcall_value_nonlocal_sysv): Assert
+       !TARGET_SECURE_PLT.
+
 2008-07-03  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
 
        * alloc-pool.c (hash_descriptor, eq_descriptor,
index 5efde36de8d04dcbea61542f42decd45bf29361d..8fe16464285dcd8a357500e3b431402d41c320e5 100644 (file)
 
   operands[0] = XEXP (operands[0], 0);
 
-  if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT
-      && flag_pic
-      && GET_CODE (operands[0]) == SYMBOL_REF
-      && !SYMBOL_REF_LOCAL_P (operands[0]))
-    {
-      rtx call;
-      rtvec tmp;
-
-      tmp = gen_rtvec (3,
-                      gen_rtx_CALL (VOIDmode,
-                                    gen_rtx_MEM (SImode, operands[0]),
-                                    operands[1]),
-                      gen_rtx_USE (VOIDmode, operands[2]),
-                      gen_rtx_CLOBBER (VOIDmode,
-                                       gen_rtx_REG (Pmode, LR_REGNO)));
-      call = emit_call_insn (gen_rtx_PARALLEL (VOIDmode, tmp));
-      use_reg (&CALL_INSN_FUNCTION_USAGE (call), pic_offset_table_rtx);
-      DONE;
-    }
-
   if (GET_CODE (operands[0]) != SYMBOL_REF
       || (DEFAULT_ABI == ABI_AIX && !SYMBOL_REF_FUNCTION_P (operands[0]))
       || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
 
   operands[1] = XEXP (operands[1], 0);
 
-  if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT
-      && flag_pic
-      && GET_CODE (operands[1]) == SYMBOL_REF
-      && !SYMBOL_REF_LOCAL_P (operands[1]))
-    {
-      rtx call;
-      rtvec tmp;
-
-      tmp = gen_rtvec (3,
-                      gen_rtx_SET (VOIDmode,
-                                   operands[0],
-                                   gen_rtx_CALL (VOIDmode,
-                                                 gen_rtx_MEM (SImode,
-                                                              operands[1]),
-                                                 operands[2])),
-                      gen_rtx_USE (VOIDmode, operands[3]),
-                      gen_rtx_CLOBBER (VOIDmode, 
-                                       gen_rtx_REG (Pmode, LR_REGNO)));
-      call = emit_call_insn (gen_rtx_PARALLEL (VOIDmode, tmp));
-      use_reg (&CALL_INSN_FUNCTION_USAGE (call), pic_offset_table_rtx);
-      DONE;
-    }
-
   if (GET_CODE (operands[1]) != SYMBOL_REF
       || (DEFAULT_ABI == ABI_AIX && !SYMBOL_REF_FUNCTION_P (operands[1]))
       || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
    (set_attr "length" "4,4,8,8")])
 
-(define_insn "*call_nonlocal_sysv<mode>"
+(define_insn_and_split "*call_nonlocal_sysv<mode>"
   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
         (match_operand 1 "" "g,g"))
    (use (match_operand:SI 2 "immediate_operand" "O,n"))
 #else
   if (DEFAULT_ABI == ABI_V4 && flag_pic)
     {
-      if (TARGET_SECURE_PLT && flag_pic == 2)
-       /* The magic 32768 offset here and in the other sysv call insns
-          corresponds to the offset of r30 in .got2, as given by LCTOC1.
-          See sysv4.h:toc_section.  */
-       return "bl %z0+32768@plt";
-      else
-       return "bl %z0@plt";
+      gcc_assert (!TARGET_SECURE_PLT);
+      return "bl %z0@plt";
     }
   else
     return "bl %z0";
 #endif
+}
+  "DEFAULT_ABI == ABI_V4
+   && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
+   && (INTVAL (operands[2]) & CALL_LONG) == 0"
+  [(parallel [(call (mem:SI (match_dup 0))
+                   (match_dup 1))
+             (use (match_dup 2))
+             (use (match_dup 3))
+             (clobber (reg:SI LR_REGNO))])]
+{
+  operands[3] = pic_offset_table_rtx;
+}
+  [(set_attr "type" "branch,branch")
+   (set_attr "length" "4,8")])
+
+(define_insn "*call_nonlocal_sysv_secure<mode>"
+  [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
+        (match_operand 1 "" "g,g"))
+   (use (match_operand:SI 2 "immediate_operand" "O,n"))
+   (use (match_operand:SI 3 "register_operand" "r,r"))
+   (clobber (reg:SI LR_REGNO))]
+  "(DEFAULT_ABI == ABI_V4
+    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
+    && (INTVAL (operands[2]) & CALL_LONG) == 0)"
+{
+  if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
+    output_asm_insn ("crxor 6,6,6", operands);
+
+  else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
+    output_asm_insn ("creqv 6,6,6", operands);
+
+  if (flag_pic == 2)
+    /* The magic 32768 offset here and in the other sysv call insns
+       corresponds to the offset of r30 in .got2, as given by LCTOC1.
+       See sysv4.h:toc_section.  */
+    return "bl %z0+32768@plt";
+  else
+    return "bl %z0@plt";
 }
   [(set_attr "type" "branch,branch")
    (set_attr "length" "4,8")])
   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
    (set_attr "length" "4,4,8,8")])
 
-(define_insn "*call_value_nonlocal_sysv<mode>"
+(define_insn_and_split "*call_value_nonlocal_sysv<mode>"
   [(set (match_operand 0 "" "")
        (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
              (match_operand 2 "" "g,g")))
 #else
   if (DEFAULT_ABI == ABI_V4 && flag_pic)
     {
-      if (TARGET_SECURE_PLT && flag_pic == 2)
-       return "bl %z1+32768@plt";
-      else
-       return "bl %z1@plt";
+      gcc_assert (!TARGET_SECURE_PLT);
+      return "bl %z1@plt";
     }
   else
     return "bl %z1";
 #endif
+}
+  "DEFAULT_ABI == ABI_V4
+   && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
+   && (INTVAL (operands[3]) & CALL_LONG) == 0"
+  [(parallel [(set (match_dup 0)
+                  (call (mem:SI (match_dup 1))
+                        (match_dup 2)))
+             (use (match_dup 3))
+             (use (match_dup 4))
+             (clobber (reg:SI LR_REGNO))])]
+{
+  operands[4] = pic_offset_table_rtx;
+}
+  [(set_attr "type" "branch,branch")
+   (set_attr "length" "4,8")])
+
+(define_insn "*call_value_nonlocal_sysv_secure<mode>"
+  [(set (match_operand 0 "" "")
+       (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
+             (match_operand 2 "" "g,g")))
+   (use (match_operand:SI 3 "immediate_operand" "O,n"))
+   (use (match_operand:SI 4 "register_operand" "r,r"))
+   (clobber (reg:SI LR_REGNO))]
+  "(DEFAULT_ABI == ABI_V4
+    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
+    && (INTVAL (operands[3]) & CALL_LONG) == 0)"
+{
+  if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
+    output_asm_insn ("crxor 6,6,6", operands);
+
+  else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
+    output_asm_insn ("creqv 6,6,6", operands);
+
+  if (flag_pic == 2)
+    return "bl %z1+32768@plt";
+  else
+    return "bl %z1@plt";
 }
   [(set_attr "type" "branch,branch")
    (set_attr "length" "4,8")])
 
   if (DEFAULT_ABI == ABI_V4 && flag_pic)
     {
-      if (TARGET_SECURE_PLT && flag_pic == 2)
-       return \"b %z0+32768@plt\";
-      else
-       return \"b %z0@plt\";
+      gcc_assert (!TARGET_SECURE_PLT);
+      return \"b %z0@plt\";
     }
   else
     return \"b %z0\";
 
   if (DEFAULT_ABI == ABI_V4 && flag_pic)
     {
-      if (TARGET_SECURE_PLT && flag_pic == 2)
-       return \"b %z1+32768@plt\";
-      else
-       return \"b %z1@plt\";
+      gcc_assert (!TARGET_SECURE_PLT);
+      return \"b %z1@plt\";
     }
   else
     return \"b %z1\";