"$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",
"$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",
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,
/* 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);
}
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));
}
- 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
/* 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. */
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)
\f
/* 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.
#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