===================================================================
@@ -32934,7 +32934,10 @@ rs6000_call_aix (rtx value, rtx func_desc, rtx fla
rtx stack_toc_mem = gen_frame_mem (Pmode,
gen_rtx_PLUS (Pmode, stack_ptr,
stack_toc_offset));
- toc_restore = gen_rtx_SET (VOIDmode, toc_reg, stack_toc_mem);
+ rtx stack_toc_unspec = gen_rtx_UNSPEC (Pmode,
+ gen_rtvec (1, stack_toc_offset),
+ UNSPEC_TOCSLOT);
+ toc_restore = gen_rtx_SET (VOIDmode, toc_reg, stack_toc_unspec);
/* Can we optimize saving the TOC in the prologue or
do we need to do it at every call? */
===================================================================
@@ -138,6 +138,7 @@
UNSPEC_PACK_128BIT
UNSPEC_LSQ
UNSPEC_FUSION_GPR
+ UNSPEC_TOCSLOT
])
;;
@@ -11348,16 +11349,16 @@
;; Call to indirect functions with the AIX abi using a 3 word descriptor.
;; Operand0 is the addresss of the function to call
;; Operand2 is the location in the function descriptor to load r2 from
-;; Operand3 is the stack location to hold the current TOC pointer
+;; Operand3 is the offset of the stack location holding the current TOC pointer
(define_insn "*call_indirect_aix<mode>"
[(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
(match_operand 1 "" "g,g"))
(use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
- (set (reg:P TOC_REGNUM) (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
+ (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
(clobber (reg:P LR_REGNO))]
"DEFAULT_ABI == ABI_AIX"
- "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3"
+ "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3(1)"
[(set_attr "type" "jmpreg")
(set_attr "length" "12")])
@@ -11366,24 +11367,24 @@
(call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
(match_operand 2 "" "g,g")))
(use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
- (set (reg:P TOC_REGNUM) (match_operand:P 4 "memory_operand" "<ptrm>,<ptrm>"))
+ (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
(clobber (reg:P LR_REGNO))]
"DEFAULT_ABI == ABI_AIX"
- "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4"
+ "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4(1)"
[(set_attr "type" "jmpreg")
(set_attr "length" "12")])
;; Call to indirect functions with the ELFv2 ABI.
;; Operand0 is the addresss of the function to call
-;; Operand2 is the stack location to hold the current TOC pointer
+;; Operand2 is the offset of the stack location holding the current TOC pointer
(define_insn "*call_indirect_elfv2<mode>"
[(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
(match_operand 1 "" "g,g"))
- (set (reg:P TOC_REGNUM) (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
+ (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
(clobber (reg:P LR_REGNO))]
"DEFAULT_ABI == ABI_ELFv2"
- "b%T0l\;<ptrload> 2,%2"
+ "b%T0l\;<ptrload> 2,%2(1)"
[(set_attr "type" "jmpreg")
(set_attr "length" "8")])
@@ -11391,10 +11392,10 @@
[(set (match_operand 0 "" "")
(call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
(match_operand 2 "" "g,g")))
- (set (reg:P TOC_REGNUM) (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
+ (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
(clobber (reg:P LR_REGNO))]
"DEFAULT_ABI == ABI_ELFv2"
- "b%T1l\;<ptrload> 2,%3"
+ "b%T1l\;<ptrload> 2,%3(1)"
[(set_attr "type" "jmpreg")
(set_attr "length" "8")])
===================================================================
@@ -0,0 +1,13 @@
+/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler {ld 2,(24|40)\(1\)} } } */
+
+/* From a linux kernel mis-compile of net/core/skbuff.c. */
+register unsigned long current_r1 asm ("r1");
+
+void f (unsigned int n, void (*fun) (unsigned long))
+{
+ while (n--)
+ (*fun) (current_r1 & -0x1000);
+}