From e404a667bf4b0fcef2a4af1b32ef21f5b07367b6 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Mon, 2 Feb 2015 17:46:11 +1030 Subject: [PATCH] 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 --- gcc/ChangeLog | 8 ++++++++ gcc/config/rs6000/rs6000.c | 5 ++++- gcc/config/rs6000/rs6000.md | 21 ++++++++++---------- gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/gcc.target/powerpc/cprophard.c | 13 ++++++++++++ 5 files changed, 40 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/gcc.target/powerpc/cprophard.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3dcb6db8f37..6453686a233 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2015-02-02 Alan Modra + + * 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 PR target/64047 diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 661995cd081..3c853dc046d 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -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? */ diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index a55719039e3..22787e2f70e 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -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" [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l")) (match_operand 1 "" "g,g")) (use (match_operand:P 2 "memory_operand" ",")) - (set (reg:P TOC_REGNUM) (match_operand:P 3 "memory_operand" ",")) + (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" - " 2,%2\;b%T0l\; 2,%3" + " 2,%2\;b%T0l\; 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" ",")) - (set (reg:P TOC_REGNUM) (match_operand:P 4 "memory_operand" ",")) + (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" - " 2,%3\;b%T1l\; 2,%4" + " 2,%3\;b%T1l\; 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" [(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" ",")) + (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\; 2,%2" + "b%T0l\; 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" ",")) + (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\; 2,%3" + "b%T1l\; 2,%3(1)" [(set_attr "type" "jmpreg") (set_attr "length" "8")]) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b15890b0cad..d9c83cf0716 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2015-02-02 Alan Modra + + * gcc.target/powerpc/cprophard.c: New. + 2015-02-01 Andreas Tobler * gfortran.dg/enum_9.f90: Use arm_eabi instead of arm*-*-linux*. diff --git a/gcc/testsuite/gcc.target/powerpc/cprophard.c b/gcc/testsuite/gcc.target/powerpc/cprophard.c new file mode 100644 index 00000000000..f93081f0cb5 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/cprophard.c @@ -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); +} -- 2.30.2