File nov465381.diff of Package gcc41
This patch changes the method used to mark the GOT register used
for -msecure-plt calls. Instead of doing so at rtl expansion time,
I've implemented a splitter to add a "use" of the GOT register.
Since the split happen after combine, this cures the problem of
combine creating PLT calls that lack any use of the GOT register.
I've also added some assertions in the sibcall insns. These can't
possibly work with -msecure-plt as there is no way to ensure the
GOT register is valid.
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 these
are not used when TARGET_SECURE_PLT.
Index: gcc/config/rs6000/rs6000.md
===================================================================
--- gcc/config/rs6000/rs6000.md.orig 2007-01-15 11:11:08.000000000 +0100
+++ gcc/config/rs6000/rs6000.md 2009-11-20 13:42:37.000000000 +0100
@@ -9849,25 +9849,6 @@
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_SCRATCH (SImode)));
- 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))
@@ -9919,28 +9900,6 @@
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_SCRATCH (SImode)));
- 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))
@@ -10196,7 +10155,7 @@
[(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
(set_attr "length" "4,4,8,8")])
-(define_insn "*call_nonlocal_sysv"
+(define_insn_and_split "*call_nonlocal_sysv"
[(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "s,s"))
(match_operand 1 "" "g,g"))
(use (match_operand:SI 2 "immediate_operand" "O,n"))
@@ -10216,18 +10175,52 @@
#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 (match_dup 4))])]
+{
+ operands[4] = operands[3];
+ operands[3] = pic_offset_table_rtx;
+}
+ [(set_attr "type" "branch,branch")
+ (set_attr "length" "4,8")])
+
+(define_insn "*call_nonlocal_sysv_secure"
+ [(call (mem:SI (match_operand:SI 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 (match_scratch:SI 4 "=l,l"))]
+ "(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")])
@@ -10251,7 +10244,7 @@
[(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
(set_attr "length" "4,4,8,8")])
-(define_insn "*call_value_nonlocal_sysv"
+(define_insn_and_split "*call_value_nonlocal_sysv"
[(set (match_operand 0 "" "")
(call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "s,s"))
(match_operand 2 "" "g,g")))
@@ -10272,15 +10265,51 @@
#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 (match_dup 5))])]
+{
+ operands[5] = operands[4];
+ operands[4] = pic_offset_table_rtx;
+}
+ [(set_attr "type" "branch,branch")
+ (set_attr "length" "4,8")])
+
+(define_insn "*call_value_nonlocal_sysv_secure"
+ [(set (match_operand 0 "" "")
+ (call (mem:SI (match_operand:SI 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 (match_scratch:SI 5 "=l,l"))]
+ "(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")])
@@ -10495,10 +10524,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\";
@@ -10549,10 +10576,8 @@
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\";