rs6000.c (rs6000_call_aix): Use unspec rather than mem for toc_restore.

gcc/
	* config/rs6000/rs6000.c (rs6000_call_aix): Use unspec rather
	than mem for toc_restore.
	* config/rs6000/rs6000.md (UNSPEC_TOCSLOT): Define.
	(call_indirect_aix, call_value_indirect_aix): Adjust to suit.
	(call_indirect_elfv2, call_value_indirect_elfv2): Likewise.
gcc/testsuite/
	* gcc.target/powerpc/cprophard.c: New.

From-SVN: r220344
This commit is contained in:
Alan Modra 2015-02-02 17:46:11 +10:30 committed by Alan Modra
parent 02d3e45e7a
commit e404a667bf
5 changed files with 40 additions and 11 deletions

View File

@ -1,3 +1,11 @@
2015-02-02 Alan Modra <amodra@gmail.com>
* config/rs6000/rs6000.c (rs6000_call_aix): Use unspec rather
than mem for toc_restore.
* config/rs6000/rs6000.md (UNSPEC_TOCSLOT): Define.
(call_indirect_aix, call_value_indirect_aix): Adjust to suit.
(call_indirect_elfv2, call_value_indirect_elfv2): Likewise.
2015-02-01 David Edelsohn <dje.gcc@gmail.com>
PR target/64047

View File

@ -32951,7 +32951,10 @@ rs6000_call_aix (rtx value, rtx func_desc, rtx flag, rtx cookie)
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? */

View File

@ -69,6 +69,7 @@
UNSPEC_PROBE_STACK ; probe stack memory reference
UNSPEC_TOCPTR ; address of a word pointing to the TOC
UNSPEC_TOC ; address of the TOC (more-or-less)
UNSPEC_TOCSLOT ; offset from r1 of toc pointer save slot
UNSPEC_MOVSI_GOT
UNSPEC_MV_CR_OV ; move_from_CR_ov_bit
UNSPEC_FCTIWZ
@ -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")])

View File

@ -1,3 +1,7 @@
2015-02-02 Alan Modra <amodra@gmail.com>
* gcc.target/powerpc/cprophard.c: New.
2015-02-01 Andreas Tobler <andreast@gcc.gnu.org>
* gfortran.dg/enum_9.f90: Use arm_eabi instead of arm*-*-linux*.

View File

@ -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);
}