summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog45
-rw-r--r--gcc/config/arc/arc.h12
-rw-r--r--gcc/config/arm/arm.c20
-rw-r--r--gcc/config/arm/arm.h2
-rw-r--r--gcc/config/cris/cris.h2
-rw-r--r--gcc/config/i386/i386.c4
-rw-r--r--gcc/config/i386/i386.h12
-rw-r--r--gcc/config/m68k/m68k.h72
-rw-r--r--gcc/config/s390/s390.h2
-rw-r--r--gcc/config/sparc/sparc.h4
-rw-r--r--gcc/testsuite/gcc.dg/20020312-2.c139
11 files changed, 238 insertions, 76 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 761ecb34c8f..85b0f026e2e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,7 +1,24 @@
+2002-03-12 Richard Henderson <rth@redhat.com>
+
+ * config/arc/arc.h, config/cris/cris.h, config/i386/i386.h,
+ config/m68k/m68k.h, config/s390/s390.h, config/sparc/sparc.h
+ (PIC_OFFSET_TABLE_REGNUM): Conditionalize on flag_pic.
+
+ * config/arm/arm.h config/i386/i386.h, config/m68k/m68k.h,
+ config/sparc/sparc.h (CONDITIONAL_REGISTER_USAGE): Set
+ PIC_OFFSET_TABLE_REGNUM based on INVALID_REGNUM not flag_pic.
+
+ * config/arc/arc.h (CONDITIONAL_REGISTER_USAGE): New.
+ * config/arm/arm.c (arm_pic_register): Init to INVALID_REGNUM.
+ (arm_override_options): Set arm_pic_register if TARGET_APCS_STACK
+ also. Don't set it if not flag_pic.
+ * config/i386/i386.c (ix86_save_reg): Trust PIC_OFFSET_TABLE_REGNUM
+ to be INVALID_REGNUM when not used.
+
2002-03-13 Aldy Hernandez <aldyh@redhat.com>
- * expmed.c (store_bit_field): Reset alias set for memory.
- (extract_bit_field): Same.
+ * expmed.c (store_bit_field): Reset alias set for memory.
+ (extract_bit_field): Same.
2002-03-12 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
@@ -372,12 +389,12 @@ Sat Mar 9 07:20:01 2002 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
2002-03-08 Aldy Hernandez <aldyh@redhat.com>
- * config/rs6000/rs6000.c (rs6000_va_arg): Fix alignment for
- vectors.
+ * config/rs6000/rs6000.c (rs6000_va_arg): Fix alignment for
+ vectors.
2002-03-08 Aldy Hernandez <aldyh@redhat.com>
- * config/rs6000/sysv4.h (BIGGEST_ALIGNMENT): Change for altivec.
+ * config/rs6000/sysv4.h (BIGGEST_ALIGNMENT): Change for altivec.
Fri Mar 8 21:27:49 CET 2002 Jan Hubicka <jh@suse.cz>
@@ -521,11 +538,11 @@ Thu Mar 7 16:33:54 CET 2002 Jan Hubicka <jh@suse.cz>
2002-03-07 Aldy Hernandez <aldyh@redhat.com>
- * doc/invoke.texi: Add documentation for -mabi=no-altivec.
+ * doc/invoke.texi: Add documentation for -mabi=no-altivec.
- * config/rs6000/rs6000.c (rs6000_parse_abi_options): Add
- -mabi=no-altivec
- (alt_reg_names): Remove % for vrsave.
+ * config/rs6000/rs6000.c (rs6000_parse_abi_options): Add
+ -mabi=no-altivec
+ (alt_reg_names): Remove % for vrsave.
2002-03-06 Richard Henderson <rth@redhat.com>
@@ -537,7 +554,7 @@ Thu Mar 7 16:33:54 CET 2002 Jan Hubicka <jh@suse.cz>
2002-03-06 Ulrich Weigand <uweigand@de.ibm.com>
- * reload1.c (reload): Unshare all rtl after reload is done.
+ * reload1.c (reload): Unshare all rtl after reload is done.
* simplify-rtx.c (simplify_plus_minus): Do not abort,
but simply fail if the expression is too complex to simplify.
@@ -662,7 +679,7 @@ Tue Mar 5 18:31:27 CET 2002 Jan Hubicka <jh@suse.cz>
2002-03-05 Richard Henderson <rth@redhat.com>
- * rs6000.h (TOTAL_ALTIVEC_REGS): Fix off-by-one error.
+ * rs6000.h (TOTAL_ALTIVEC_REGS): Fix off-by-one error.
2002-03-04 Geoffrey Keating <geoffk@redhat.com>
@@ -709,10 +726,10 @@ Mon Mar 4 15:33:54 CET 2002 Jan Hubicka <jh@suse.cz>
2002-03-03 Aldy Hernandez <aldyh@redhat.com>
- * config.gcc (powerpc-*-eabialtivec*): Use t-ppcendian.
- (powerpc-*-eabisimaltivec*): Same.
+ * config.gcc (powerpc-*-eabialtivec*): Use t-ppcendian.
+ (powerpc-*-eabisimaltivec*): Same.
- * config/rs6000/t-ppcendian: New.
+ * config/rs6000/t-ppcendian: New.
2002-03-04 Herman A.J. ten Brugge <Haj.Ten.Brugge@net.HCC.nl>
diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h
index 4ba19f1eaf6..651d81ec92d 100644
--- a/gcc/config/arc/arc.h
+++ b/gcc/config/arc/arc.h
@@ -355,6 +355,16 @@ if (GET_MODE_CLASS (MODE) == MODE_INT \
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, \
27, 28, 29, 30 }
+/* Macro to conditionally modify fixed_regs/call_used_regs. */
+#define CONDITIONAL_REGISTER_USAGE \
+do { \
+ if (PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM) \
+ { \
+ fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
+ call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
+ } \
+} while (0)
+
/* Return number of consecutive hard regs needed starting at reg REGNO
to hold something of mode MODE.
This is ordinarily the length in words of a value of mode MODE
@@ -1152,7 +1162,7 @@ do { \
pointer and frame pointer registers. If this macro is not defined, it
is up to the machine-dependent files to allocate such a register (if
necessary). */
-#define PIC_OFFSET_TABLE_REGNUM 26
+#define PIC_OFFSET_TABLE_REGNUM (flag_pic ? 26 : INVALID_REGNUM)
/* Define this macro if the register defined by PIC_OFFSET_TABLE_REGNUM is
clobbered by calls. Do not define this macro if PIC_OFFSET_TABLE_REGNUM
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 4a0e8519ef6..8e859570218 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -268,7 +268,7 @@ enum machine_mode output_memory_reference_mode;
/* The register number to be used for the PIC offset register. */
const char * arm_pic_register_string = NULL;
-int arm_pic_register = 9;
+int arm_pic_register = INVALID_REGNUM;
/* Set to 1 when a return insn is output, this means that the epilogue
is not needed. */
@@ -651,8 +651,8 @@ arm_override_options ()
/* If stack checking is disabled, we can use r10 as the PIC register,
which keeps r9 available. */
- if (flag_pic && !TARGET_APCS_STACK)
- arm_pic_register = 10;
+ if (flag_pic)
+ arm_pic_register = TARGET_APCS_STACK ? 9 : 10;
if (TARGET_APCS_FLOAT)
warning ("passing floating point arguments in fp regs not yet supported");
@@ -713,18 +713,16 @@ arm_override_options ()
if (arm_pic_register_string != NULL)
{
- int pic_register;
-
+ int pic_register = decode_reg_name (arm_pic_register_string);
+
if (!flag_pic)
warning ("-mpic-register= is useless without -fpic");
- pic_register = decode_reg_name (arm_pic_register_string);
-
/* Prevent the user from choosing an obviously stupid PIC register. */
- if (pic_register < 0 || call_used_regs[pic_register]
- || pic_register == HARD_FRAME_POINTER_REGNUM
- || pic_register == STACK_POINTER_REGNUM
- || pic_register >= PC_REGNUM)
+ else if (pic_register < 0 || call_used_regs[pic_register]
+ || pic_register == HARD_FRAME_POINTER_REGNUM
+ || pic_register == STACK_POINTER_REGNUM
+ || pic_register >= PC_REGNUM)
error ("unable to use '%s' for PIC register", arm_pic_register_string);
else
arm_pic_register = pic_register;
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index c180e267b38..240595e58f5 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -838,7 +838,7 @@ extern const char * structure_size_string;
regno <= LAST_ARM_FP_REGNUM; ++regno) \
fixed_regs[regno] = call_used_regs[regno] = 1; \
} \
- if (flag_pic) \
+ if (PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM) \
{ \
fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
diff --git a/gcc/config/cris/cris.h b/gcc/config/cris/cris.h
index 235777db85e..21065a9f462 100644
--- a/gcc/config/cris/cris.h
+++ b/gcc/config/cris/cris.h
@@ -1468,7 +1468,7 @@ call_ ## FUNC (void) \
/* Node: PIC */
-#define PIC_OFFSET_TABLE_REGNUM 0
+#define PIC_OFFSET_TABLE_REGNUM (flag_pic ? 0 : INVALID_REGNUM)
#define LEGITIMATE_PIC_OPERAND_P(X) cris_legitimate_pic_operand (X)
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 56fdf9076c8..2d0649944d6 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -3880,9 +3880,7 @@ ix86_save_reg (regno, maybe_eh_return)
int regno;
int maybe_eh_return;
{
- if (flag_pic
- && ! TARGET_64BIT
- && regno == PIC_OFFSET_TABLE_REGNUM
+ if (regno == PIC_OFFSET_TABLE_REGNUM
&& (current_function_uses_pic_offset_table
|| current_function_uses_const_pool
|| current_function_calls_eh_return))
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 50e8dd5f6cf..94359133c92 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -937,7 +937,7 @@ do { \
call_used_regs[i] = (call_used_regs[i] \
& (TARGET_64BIT ? 2 : 1)) != 0; \
} \
- if (flag_pic && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM) \
+ if (PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM) \
{ \
fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
@@ -1113,11 +1113,11 @@ do { \
#define STATIC_CHAIN_REGNUM (TARGET_64BIT ? FIRST_REX_INT_REG + 10 - 8 : 2)
/* Register to hold the addressing base for position independent
- code access to data items.
- We don't use PIC pointer for 64bit mode. Define the regnum to
- dummy value to prevent gcc from pessimizing code dealing with EBX.
- */
-#define PIC_OFFSET_TABLE_REGNUM (TARGET_64BIT ? INVALID_REGNUM : 3)
+ code access to data items. We don't use PIC pointer for 64bit
+ mode. Define the regnum to dummy value to prevent gcc from
+ pessimizing code dealing with EBX. */
+#define PIC_OFFSET_TABLE_REGNUM \
+ (TARGET_64BIT || !flag_pic ? INVALID_REGNUM : 3)
/* Register in which address to store a structure value
arrives in the function. On the 386, the prologue
diff --git a/gcc/config/m68k/m68k.h b/gcc/config/m68k/m68k.h
index 9a20494aa38..55f5fd14e04 100644
--- a/gcc/config/m68k/m68k.h
+++ b/gcc/config/m68k/m68k.h
@@ -387,7 +387,7 @@ extern int target_flags;
#endif
/* This defines the register which is used to hold the offset table for PIC. */
-#define PIC_OFFSET_TABLE_REGNUM 13
+#define PIC_OFFSET_TABLE_REGNUM (flag_pic ? 13 : INVALID_REGNUM)
#ifndef SUPPORT_SUN_FPA
@@ -469,43 +469,43 @@ extern int target_flags;
#ifdef SUPPORT_SUN_FPA
-#define CONDITIONAL_REGISTER_USAGE \
-{ \
- int i; \
- HARD_REG_SET x; \
- if (! TARGET_FPA) \
- { \
- COPY_HARD_REG_SET (x, reg_class_contents[(int)FPA_REGS]); \
- for (i = 0; i < FIRST_PSEUDO_REGISTER; i++ ) \
- if (TEST_HARD_REG_BIT (x, i)) \
- fixed_regs[i] = call_used_regs[i] = 1; \
- } \
- if (! TARGET_68881) \
- { \
- COPY_HARD_REG_SET (x, reg_class_contents[(int)FP_REGS]); \
- for (i = 0; i < FIRST_PSEUDO_REGISTER; i++ ) \
- if (TEST_HARD_REG_BIT (x, i)) \
- fixed_regs[i] = call_used_regs[i] = 1; \
- } \
- if (flag_pic) \
- fixed_regs[PIC_OFFSET_TABLE_REGNUM] \
- = call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1;\
+#define CONDITIONAL_REGISTER_USAGE \
+{ \
+ int i; \
+ HARD_REG_SET x; \
+ if (! TARGET_FPA) \
+ { \
+ COPY_HARD_REG_SET (x, reg_class_contents[(int)FPA_REGS]); \
+ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++ ) \
+ if (TEST_HARD_REG_BIT (x, i)) \
+ fixed_regs[i] = call_used_regs[i] = 1; \
+ } \
+ if (! TARGET_68881) \
+ { \
+ COPY_HARD_REG_SET (x, reg_class_contents[(int)FP_REGS]); \
+ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++ ) \
+ if (TEST_HARD_REG_BIT (x, i)) \
+ fixed_regs[i] = call_used_regs[i] = 1; \
+ } \
+ if (PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM) \
+ fixed_regs[PIC_OFFSET_TABLE_REGNUM] \
+ = call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
}
#else
-#define CONDITIONAL_REGISTER_USAGE \
-{ \
- int i; \
- HARD_REG_SET x; \
- if (! TARGET_68881) \
- { \
- COPY_HARD_REG_SET (x, reg_class_contents[(int)FP_REGS]); \
- for (i = 0; i < FIRST_PSEUDO_REGISTER; i++ ) \
- if (TEST_HARD_REG_BIT (x, i)) \
- fixed_regs[i] = call_used_regs[i] = 1; \
- } \
- if (flag_pic) \
- fixed_regs[PIC_OFFSET_TABLE_REGNUM] \
- = call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1;\
+#define CONDITIONAL_REGISTER_USAGE \
+{ \
+ int i; \
+ HARD_REG_SET x; \
+ if (! TARGET_68881) \
+ { \
+ COPY_HARD_REG_SET (x, reg_class_contents[(int)FP_REGS]); \
+ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++ ) \
+ if (TEST_HARD_REG_BIT (x, i)) \
+ fixed_regs[i] = call_used_regs[i] = 1; \
+ } \
+ if (PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM) \
+ fixed_regs[PIC_OFFSET_TABLE_REGNUM] \
+ = call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
}
#endif /* defined SUPPORT_SUN_FPA */
diff --git a/gcc/config/s390/s390.h b/gcc/config/s390/s390.h
index 8ab287b2df7..93b355caf65 100644
--- a/gcc/config/s390/s390.h
+++ b/gcc/config/s390/s390.h
@@ -249,7 +249,7 @@ if (INTEGRAL_MODE_P (MODE) && \
GPR 14: Return registers holds the return address
GPR 15: Stack pointer */
-#define PIC_OFFSET_TABLE_REGNUM 12
+#define PIC_OFFSET_TABLE_REGNUM (flag_pic ? 12 : INVALID_REGNUM)
#define BASE_REGISTER 13
#define RETURN_REGNUM 14
#define STACK_POINTER_REGNUM 15
diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h
index aeb107880c4..92c8ace9e13 100644
--- a/gcc/config/sparc/sparc.h
+++ b/gcc/config/sparc/sparc.h
@@ -984,7 +984,7 @@ if (TARGET_ARCH64 \
#define CONDITIONAL_REGISTER_USAGE \
do \
{ \
- if (flag_pic) \
+ if (PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM) \
{ \
fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
@@ -1159,7 +1159,7 @@ extern int sparc_mode_class[];
/* Register which holds offset table for position-independent
data references. */
-#define PIC_OFFSET_TABLE_REGNUM 23
+#define PIC_OFFSET_TABLE_REGNUM (flag_pic ? 23 : INVALID_REGNUM)
/* Pick a default value we can notice from override_options:
!v9: Default is on.
diff --git a/gcc/testsuite/gcc.dg/20020312-2.c b/gcc/testsuite/gcc.dg/20020312-2.c
new file mode 100644
index 00000000000..889e152be34
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/20020312-2.c
@@ -0,0 +1,139 @@
+/* PR 5878.
+
+ We ICEd in verify_local_live_at_start because we incorrectly forced
+ the PIC register live between BAR and BAZ. We did this because the
+ definition of PIC_OFFSET_TABLE_REGNUM was incorrectly not INVALID_REGNUM
+ when !flag_pic for most targets. */
+
+/* { dg-do run } */
+/* { dg-options "-O -fno-pic" } */
+
+#if #cpu(a29k)
+/* No pic register. */
+#elif defined(__alpha__)
+/* PIC register is $29, but is used even without -fpic. */
+#elif defined(__arc__)
+# define PIC_REG "26"
+#elif defined(__arm__)
+# define PIC_REG "9"
+#elif defined(AVR)
+/* No pic register. */
+#elif defined(__clipper__)
+/* No pic register. */
+#elif defined(__convex__)
+/* No pic register. */
+#elif defined(__cris__)
+# define PIC_REG "0"
+#elif defined(__D30V__)
+/* No pic register. */
+#elif defined(__dsp1600__)
+/* No pic register. */
+#elif defined(__elxsi__)
+/* No pic register. */
+#elif defined(__fr30__)
+/* No pic register. */
+#elif defined(__H8300__) || defined(__H8300H__) || defined(__H8300S__)
+/* No pic register. */
+#elif #cpu(i370)
+/* No pic register. */
+#elif defined(__i386__)
+# define PIC_REG "ebx"
+#elif defined(__i860__)
+/* No pic register. */
+#elif defined(__i960__)
+/* No pic register. */
+#elif defined(__ia64__)
+/* PIC register is r1, but is used even without -fpic. */
+#elif defined(__M32R__)
+/* No pic register. */
+#elif defined(__m68k__)
+# define PIC_REG "a5"
+#elif defined(__m88k__)
+# define PIC_REG "25"
+#elif defined(__mc68hc1x__)
+/* No pic register. */
+#elif defined(__mcore__)
+/* No pic register. */
+#elif defined(__mips__)
+/* PIC register is $28, but is used even without -fpic. */
+#elif defined(__mn10200__)
+/* No pic register. */
+#elif defined(__mn10300__)
+/* No pic register. */
+#elif #cpu(ns32k)
+/* No pic register. */
+#elif defined(__parisc__)
+/* PIC register is %r27 or %r19, but is used even without -fpic. */
+#elif defined(__pdp11__)
+/* No pic register. */
+#elif defined(__pj__)
+/* No pic register. */
+#elif defined(__powerpc__)
+# ifdef __darwin__
+# define PIC_REG "31"
+# else
+# define PIC_REG "30"
+# endif
+#elif defined(__ibm032__) /* aka romp */
+/* No pic register. */
+#elif defined(__s390__)
+# define PIC_REG "12"
+#elif defined(__sparc__)
+# define PIC_REG "l7"
+#elif defined(__v850)
+/* No pic register. */
+#elif defined(__vax__)
+/* No pic register. */
+#elif defined(__we32000__)
+/* No pic register. */
+#elif defined(__xstormy16__)
+/* No pic register. */
+#elif defined(__XTENSA__)
+/* No pic register. */
+#else
+# error "Modify the test for your target."
+#endif
+
+#ifdef PIC_REG
+register void *reg __asm__(PIC_REG);
+#else
+/* We really need a global register variable set to the PIC register
+ to expose the bug. Oh well, let the test case not fail. */
+static void *reg;
+#endif
+
+void * __attribute__((noinline))
+dummy (void *x)
+{
+ return x;
+}
+
+void
+f (void)
+{
+ goto *dummy (&&bar);
+ for (;;)
+ {
+ foo:
+ reg = (void *) 1;
+ if (!reg)
+ goto baz;
+ reg = &&foo;
+ }
+
+ bar:
+ baz:
+ reg = 0;
+}
+
+int
+main()
+{
+ void *old_reg = reg;
+ reg = (void *) 1;
+ f ();
+ if (reg)
+ abort ();
+ reg = old_reg;
+ return 0;
+}