aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Sandiford <rsandifo@redhat.com>2004-01-25 10:16:21 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2004-01-25 10:16:21 +0000
commitbcbc6b7fb8758e95fc602ec909d9b597ff6d93bd (patch)
tree1d535bdec4a0356739c985f5d98f7596ef9794a4
parent0ce78f010d98dc190f21682d4ff56615efd03d23 (diff)
downloadgcc-bcbc6b7fb8758e95fc602ec909d9b597ff6d93bd.zip
gcc-bcbc6b7fb8758e95fc602ec909d9b597ff6d93bd.tar.gz
gcc-bcbc6b7fb8758e95fc602ec909d9b597ff6d93bd.tar.bz2
mips-protos.h (mips_reg_mode_ok_for_base_p): Delete.
* config/mips/mips-protos.h (mips_reg_mode_ok_for_base_p): Delete. (mips_regno_mode_ok_for_base_p): Declare. * config/mips/mips.h (ARG_POINTER_REGNUM): Renumber to 77. (FRAME_POINTER_REGNUM): Renumber to 78. (FIRST_PSEUDO_REGISTER): Update comment accordingly. (BASE_REG_P, GP_REG_OR_PSEUDO_STRICT_P): Delete. (GP_REG_OR_PSEUDO_NONSTRICT_P): Delete. (REGNO_MODE_OK_FOR_BASE_P): Use mips_regno_mode_ok_for_base_p. (REG_MODE_OK_FOR_BASE_P): Likewise. * config/mips/mips.c (mips_reg_names, mips_sw_reg_names): Change entry for 77 to "$arg" and entry for 78 to "$frame". (mips_regno_to_class): Map 77 and 78 to ALL_REGS. (mips_reg_mode_ok_for_base_p): Remove. (mips_regno_mode_ok_for_base_p): New function, derived from old BASE_REG_P macro. Don't enforce the mips16 stack pointer restrictions unless we're being strict. (mips_valid_base_register_p): Use mips_regno_mode_ok_for_base_p. testsuite/ * gcc.dg/torture/mips-clobber-at.c: New test. From-SVN: r76547
-rw-r--r--gcc/ChangeLog20
-rw-r--r--gcc/config/mips/mips-protos.h2
-rw-r--r--gcc/config/mips/mips.c45
-rw-r--r--gcc/config/mips/mips.h51
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/torture/mips-clobber-at.c4
6 files changed, 80 insertions, 46 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0fcc6d9..d6138b2 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,23 @@
+2004-01-25 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips-protos.h (mips_reg_mode_ok_for_base_p): Delete.
+ (mips_regno_mode_ok_for_base_p): Declare.
+ * config/mips/mips.h (ARG_POINTER_REGNUM): Renumber to 77.
+ (FRAME_POINTER_REGNUM): Renumber to 78.
+ (FIRST_PSEUDO_REGISTER): Update comment accordingly.
+ (BASE_REG_P, GP_REG_OR_PSEUDO_STRICT_P): Delete.
+ (GP_REG_OR_PSEUDO_NONSTRICT_P): Delete.
+ (REGNO_MODE_OK_FOR_BASE_P): Use mips_regno_mode_ok_for_base_p.
+ (REG_MODE_OK_FOR_BASE_P): Likewise.
+ * config/mips/mips.c (mips_reg_names, mips_sw_reg_names): Change
+ entry for 77 to "$arg" and entry for 78 to "$frame".
+ (mips_regno_to_class): Map 77 and 78 to ALL_REGS.
+ (mips_reg_mode_ok_for_base_p): Remove.
+ (mips_regno_mode_ok_for_base_p): New function, derived from old
+ BASE_REG_P macro. Don't enforce the mips16 stack pointer
+ restrictions unless we're being strict.
+ (mips_valid_base_register_p): Use mips_regno_mode_ok_for_base_p.
+
2004-01-24 Kazu Hirata <kazu@cs.umass.edu>
* c-common.h: Fix comment typos.
diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h
index 6bf635c..dfc1467 100644
--- a/gcc/config/mips/mips-protos.h
+++ b/gcc/config/mips/mips-protos.h
@@ -26,7 +26,7 @@ Boston, MA 02111-1307, USA. */
#ifndef GCC_MIPS_PROTOS_H
#define GCC_MIPS_PROTOS_H
-extern int mips_reg_mode_ok_for_base_p (rtx, enum machine_mode, int);
+extern int mips_regno_mode_ok_for_base_p (int, enum machine_mode, int);
extern int mips_address_insns (rtx, enum machine_mode);
extern int mips_const_insns (rtx);
extern int mips_fetch_insns (rtx);
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index c348f58..d7bec70 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -572,7 +572,7 @@ char mips_reg_names[][8] =
"$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
"$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
"hi", "lo", "", "$fcc0","$fcc1","$fcc2","$fcc3","$fcc4",
- "$fcc5","$fcc6","$fcc7","", "", "", "", "$fakec",
+ "$fcc5","$fcc6","$fcc7","", "", "$arg", "$frame", "$fakec",
"$c0r0", "$c0r1", "$c0r2", "$c0r3", "$c0r4", "$c0r5", "$c0r6", "$c0r7",
"$c0r8", "$c0r9", "$c0r10","$c0r11","$c0r12","$c0r13","$c0r14","$c0r15",
"$c0r16","$c0r17","$c0r18","$c0r19","$c0r20","$c0r21","$c0r22","$c0r23",
@@ -601,7 +601,7 @@ char mips_sw_reg_names[][8] =
"$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
"$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
"hi", "lo", "", "$fcc0","$fcc1","$fcc2","$fcc3","$fcc4",
- "$fcc5","$fcc6","$fcc7","$rap", "", "", "", "$fakec",
+ "$fcc5","$fcc6","$fcc7","$rap", "", "$arg", "$frame", "$fakec",
"$c0r0", "$c0r1", "$c0r2", "$c0r3", "$c0r4", "$c0r5", "$c0r6", "$c0r7",
"$c0r8", "$c0r9", "$c0r10","$c0r11","$c0r12","$c0r13","$c0r14","$c0r15",
"$c0r16","$c0r17","$c0r18","$c0r19","$c0r20","$c0r21","$c0r22","$c0r23",
@@ -638,7 +638,7 @@ const enum reg_class mips_regno_to_class[] =
HI_REG, LO_REG, NO_REGS, ST_REGS,
ST_REGS, ST_REGS, ST_REGS, ST_REGS,
ST_REGS, ST_REGS, ST_REGS, NO_REGS,
- NO_REGS, NO_REGS, NO_REGS, NO_REGS,
+ NO_REGS, ALL_REGS, ALL_REGS, NO_REGS,
COP0_REGS, COP0_REGS, COP0_REGS, COP0_REGS,
COP0_REGS, COP0_REGS, COP0_REGS, COP0_REGS,
COP0_REGS, COP0_REGS, COP0_REGS, COP0_REGS,
@@ -953,11 +953,40 @@ mips_symbolic_constant_p (rtx x, enum mips_symbol_type *symbol_type)
/* This function is used to implement REG_MODE_OK_FOR_BASE_P. */
int
-mips_reg_mode_ok_for_base_p (rtx reg, enum machine_mode mode, int strict)
+mips_regno_mode_ok_for_base_p (int regno, enum machine_mode mode, int strict)
{
- return (strict
- ? REGNO_MODE_OK_FOR_BASE_P (REGNO (reg), mode)
- : GP_REG_OR_PSEUDO_NONSTRICT_P (REGNO (reg), mode));
+ if (regno >= FIRST_PSEUDO_REGISTER)
+ {
+ if (!strict)
+ return true;
+ regno = reg_renumber[regno];
+ }
+
+ /* These fake registers will be eliminated to either the stack or
+ hard frame pointer, both of which are usually valid base registers.
+ Reload deals with the cases where the eliminated form isn't valid. */
+ if (regno == ARG_POINTER_REGNUM || regno == FRAME_POINTER_REGNUM)
+ return true;
+
+ /* In mips16 mode, the stack pointer can only address word and doubleword
+ values, nothing smaller. There are two problems here:
+
+ (a) Instantiating virtual registers can introduce new uses of the
+ stack pointer. If these virtual registers are valid addresses,
+ the stack pointer should be too.
+
+ (b) Most uses of the stack pointer are not made explicit until
+ FRAME_POINTER_REGNUM and ARG_POINTER_REGNUM have been eliminated.
+ We don't know until that stage whether we'll be eliminating to the
+ stack pointer (which needs the restriction) or the hard frame
+ pointer (which doesn't).
+
+ All in all, it seems more consitent to only enforce this restriction
+ during and after reload. */
+ if (TARGET_MIPS16 && regno == STACK_POINTER_REGNUM)
+ return !strict || GET_MODE_SIZE (mode) == 4 || GET_MODE_SIZE (mode) == 8;
+
+ return TARGET_MIPS16 ? M16_REG_P (regno) : GP_REG_P (regno);
}
@@ -971,7 +1000,7 @@ mips_valid_base_register_p (rtx x, enum machine_mode mode, int strict)
x = SUBREG_REG (x);
return (GET_CODE (x) == REG
- && mips_reg_mode_ok_for_base_p (x, mode, strict));
+ && mips_regno_mode_ok_for_base_p (REGNO (x), mode, strict));
}
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index 049933a..74b8c54 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -1474,8 +1474,11 @@ extern const struct mips_cpu_info *mips_tune_info;
- 8 condition code registers
- 2 accumulator registers (hi and lo)
- 32 registers each for coprocessors 0, 2 and 3
- - FAKE_CALL_REGNO (see the comment above load_callsi for details)
- - 5 dummy entries that were used at various times in the past. */
+ - 3 fake registers:
+ - ARG_POINTER_REGNUM
+ - FRAME_POINTER_REGNUM
+ - FAKE_CALL_REGNO (see the comment above load_callsi for details)
+ - 3 dummy entries that were used at various times in the past. */
#define FIRST_PSEUDO_REGISTER 176
@@ -1661,11 +1664,10 @@ extern char mips_hard_regno_mode_ok[][FIRST_PSEUDO_REGISTER];
/* Register to use for pushing function arguments. */
#define STACK_POINTER_REGNUM (GP_REG_FIRST + 29)
-/* Base register for access to local variables of the function. We
- pretend that the frame pointer is $1, and then eliminate it to
- HARD_FRAME_POINTER_REGNUM. We can get away with this because $1 is
- a fixed register, and will not be used for anything else. */
-#define FRAME_POINTER_REGNUM (GP_REG_FIRST + 1)
+/* These two registers don't really exist: they get eliminated to either
+ the stack or hard frame pointer. */
+#define ARG_POINTER_REGNUM 77
+#define FRAME_POINTER_REGNUM 78
/* $30 is not available on the mips16, so we use $17 as the frame
pointer. */
@@ -1678,9 +1680,6 @@ extern char mips_hard_regno_mode_ok[][FIRST_PSEUDO_REGISTER];
This is computed in `reload', in reload1.c. */
#define FRAME_POINTER_REQUIRED (current_function_calls_alloca)
-/* Base register for access to arguments of the function. */
-#define ARG_POINTER_REGNUM GP_REG_FIRST
-
/* Register in which static-chain is passed to a function. */
#define STATIC_CHAIN_REGNUM (GP_REG_FIRST + 2)
@@ -2510,31 +2509,9 @@ typedef struct mips_args {
/* Addressing modes, and classification of registers for them. */
-/* These assume that REGNO is a hard or pseudo reg number.
- They give nonzero only if REGNO is a hard reg of the suitable class
- or a pseudo reg currently allocated to a suitable hard reg.
- These definitions are NOT overridden anywhere. */
-
-#define BASE_REG_P(regno, mode) \
- (TARGET_MIPS16 \
- ? (M16_REG_P (regno) \
- || (regno) == FRAME_POINTER_REGNUM \
- || (regno) == ARG_POINTER_REGNUM \
- || ((regno) == STACK_POINTER_REGNUM \
- && (GET_MODE_SIZE (mode) == 4 \
- || GET_MODE_SIZE (mode) == 8))) \
- : GP_REG_P (regno))
-
-#define GP_REG_OR_PSEUDO_STRICT_P(regno, mode) \
- BASE_REG_P((regno < FIRST_PSEUDO_REGISTER) ? (int) regno : reg_renumber[regno], \
- (mode))
-
-#define GP_REG_OR_PSEUDO_NONSTRICT_P(regno, mode) \
- (((regno) >= FIRST_PSEUDO_REGISTER) || (BASE_REG_P ((regno), (mode))))
-
-#define REGNO_OK_FOR_INDEX_P(regno) 0
-#define REGNO_MODE_OK_FOR_BASE_P(regno, mode) \
- GP_REG_OR_PSEUDO_STRICT_P ((regno), (mode))
+#define REGNO_OK_FOR_INDEX_P(REGNO) 0
+#define REGNO_MODE_OK_FOR_BASE_P(REGNO, MODE) \
+ mips_regno_mode_ok_for_base_p (REGNO, MODE, 1)
/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
and check its validity for a certain class.
@@ -2549,10 +2526,10 @@ typedef struct mips_args {
#ifndef REG_OK_STRICT
#define REG_MODE_OK_FOR_BASE_P(X, MODE) \
- mips_reg_mode_ok_for_base_p (X, MODE, 0)
+ mips_regno_mode_ok_for_base_p (REGNO (X), MODE, 0)
#else
#define REG_MODE_OK_FOR_BASE_P(X, MODE) \
- mips_reg_mode_ok_for_base_p (X, MODE, 1)
+ mips_regno_mode_ok_for_base_p (REGNO (X), MODE, 1)
#endif
#define REG_OK_FOR_INDEX_P(X) 0
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index dd33a2e..c7935a4 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2004-01-25 Richard Sandiford <rsandifo@redhat.com>
+
+ * gcc.dg/torture/mips-clobber-at.c: New test.
+
2004-01-24 Ian Lance Taylor <ian@wasabisystems.com>
* gcc.dg/20040124-1.c: New test.
diff --git a/gcc/testsuite/gcc.dg/torture/mips-clobber-at.c b/gcc/testsuite/gcc.dg/torture/mips-clobber-at.c
new file mode 100644
index 0000000..7f93698
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/mips-clobber-at.c
@@ -0,0 +1,4 @@
+/* "$1" used to be mapped to the internal frame pointer. */
+/* { dg-do compile { target mips*-*-* } } */
+/* { dg-options "" } */
+int foo () { asm volatile ("#" ::: "$1"); }