aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/rs6000/rs6000.cc6
-rw-r--r--gcc/config/rs6000/rs6000.h2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr110320-1.c22
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr110320-2.c21
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr110320-3.c21
5 files changed, 70 insertions, 2 deletions
diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index 09a5d29..6b9a40f 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -10199,9 +10199,13 @@ rs6000_conditional_register_usage (void)
for (i = 32; i < 64; i++)
fixed_regs[i] = call_used_regs[i] = 1;
+ /* For non PC-relative code, GPR2 is unavailable for register allocation. */
+ if (FIXED_R2 && !rs6000_pcrel_p ())
+ fixed_regs[2] = 1;
+
/* The TOC register is not killed across calls in a way that is
visible to the compiler. */
- if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
+ if (fixed_regs[2] && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2))
call_used_regs[2] = 0;
if (DEFAULT_ABI == ABI_V4 && flag_pic == 2)
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index df44b86..98e046f 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -814,7 +814,7 @@ enum data_align { align_abi, align_opt, align_both };
#define FIXED_REGISTERS \
{/* GPRs */ \
- 0, 1, FIXED_R2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, FIXED_R13, 0, 0, \
+ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, FIXED_R13, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
/* FPRs */ \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
diff --git a/gcc/testsuite/gcc.target/powerpc/pr110320-1.c b/gcc/testsuite/gcc.target/powerpc/pr110320-1.c
new file mode 100644
index 0000000..9d49732
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr110320-1.c
@@ -0,0 +1,22 @@
+/* PR target/110320 */
+/* { dg-require-effective-target powerpc_elfv2 } */
+/* { dg-options "-O2 -mdejagnu-cpu=power10 -ffixed-r0 -ffixed-r11 -ffixed-r12" } */
+
+/* Ensure we use r2 as a normal volatile register for the code below.
+ The test case ensures all of the parameter registers r3 - r10 are used
+ and needed after we compute the expression "x + y" which requires a
+ temporary. The -ffixed-r* options disallow using the other volatile
+ registers r0, r11 and r12. That leaves RA to choose from r2 and the more
+ expensive non-volatile registers for the temporary to be assigned to, and
+ RA will always chooses the cheaper volatile r2 register. */
+
+extern long bar (long, long, long, long, long, long, long, long *);
+
+long
+foo (long r3, long r4, long r5, long r6, long r7, long r8, long r9, long *r10)
+{
+ *r10 = r3 + r4;
+ return bar (r3, r4, r5, r6, r7, r8, r9, r10);
+}
+
+/* { dg-final { scan-assembler {\madd 2,3,4\M} } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/pr110320-2.c b/gcc/testsuite/gcc.target/powerpc/pr110320-2.c
new file mode 100644
index 0000000..9d6aefe
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr110320-2.c
@@ -0,0 +1,21 @@
+/* PR target/110320 */
+/* { dg-require-effective-target powerpc_pcrel } */
+/* { dg-options "-O2 -mdejagnu-cpu=power10 -mno-pcrel -ffixed-r0 -ffixed-r11 -ffixed-r12" } */
+
+/* Ensure we don't use r2 as a normal volatile register for the code below.
+ The test case ensures all of the parameter registers r3 - r10 are used
+ and needed after we compute the expression "x + y" which requires a
+ temporary. The -ffixed-r* options disallow using the other volatile
+ registers r0, r11 and r12. That only leaves RA to choose from the more
+ expensive non-volatile registers for the temporary to be assigned to. */
+
+extern long bar (long, long, long, long, long, long, long, long *);
+
+long
+foo (long r3, long r4, long r5, long r6, long r7, long r8, long r9, long *r10)
+{
+ *r10 = r3 + r4;
+ return bar (r3, r4, r5, r6, r7, r8, r9, r10);
+}
+
+/* { dg-final { scan-assembler-not {\madd 2,3,4\M} } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/pr110320-3.c b/gcc/testsuite/gcc.target/powerpc/pr110320-3.c
new file mode 100644
index 0000000..ffa8c63
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr110320-3.c
@@ -0,0 +1,21 @@
+/* PR target/110320 */
+/* { dg-require-effective-target powerpc_pcrel } */
+/* { dg-options "-O2 -mdejagnu-cpu=power10 -ffixed-r0 -ffixed-r2 -ffixed-r11 -ffixed-r12" } */
+
+/* Ensure we don't use r2 as a normal volatile register for the code below.
+ The test case ensures all of the parameter registers r3 - r10 are used
+ and needed after we compute the expression "x + y" which requires a
+ temporary. The -ffixed-r* options disallow using the other volatile
+ registers r0, r2, r11 and r12. That only leaves RA to choose from the more
+ expensive non-volatile registers for the temporary to be assigned to. */
+
+extern long bar (long, long, long, long, long, long, long, long *);
+
+long
+foo (long r3, long r4, long r5, long r6, long r7, long r8, long r9, long *r10)
+{
+ *r10 = r3 + r4;
+ return bar (r3, r4, r5, r6, r7, r8, r9, r10);
+}
+
+/* { dg-final { scan-assembler-not {\madd 2,3,4\M} } } */