From: Alan Modra Date: Mon, 2 Feb 2015 07:16:11 +0000 (+1030) Subject: rs6000.c (rs6000_call_aix): Use unspec rather than mem for toc_restore. X-Git-Tag: upstream/12.2.0~56919 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e404a667bf4b0fcef2a4af1b32ef21f5b07367b6;p=platform%2Fupstream%2Fgcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3dcb6db..6453686 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 661995c..3c853dc 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 a557190..22787e2 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 b15890b..d9c83cf 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 0000000..f93081f --- /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); +}