aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2015-02-02 07:16:11 +0000
committerAlan Modra <amodra@gmail.com>2015-02-02 07:16:11 +0000
commit53941b533fd5c6b693e171f17f0662e659fa9ef8 (patch)
tree67853275467ee73b7fc804fc8ce9712de3281e16
parenta1b2443ef16a29237c8cafef1b738d9279885c47 (diff)
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. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@220344 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/config/rs6000/rs6000.c5
-rw-r--r--gcc/config/rs6000/rs6000.md21
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.target/powerpc/cprophard.c13
5 files changed, 40 insertions, 11 deletions
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 <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
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<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")])
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 <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*.
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);
+}