diff options
author | Richard Sandiford <rsandifo@redhat.com> | 2004-01-25 10:16:21 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2004-01-25 10:16:21 +0000 |
commit | bcbc6b7fb8758e95fc602ec909d9b597ff6d93bd (patch) | |
tree | 1d535bdec4a0356739c985f5d98f7596ef9794a4 | |
parent | 0ce78f010d98dc190f21682d4ff56615efd03d23 (diff) | |
download | gcc-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/ChangeLog | 20 | ||||
-rw-r--r-- | gcc/config/mips/mips-protos.h | 2 | ||||
-rw-r--r-- | gcc/config/mips/mips.c | 45 | ||||
-rw-r--r-- | gcc/config/mips/mips.h | 51 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/mips-clobber-at.c | 4 |
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"); } |