-2002-01-22 Nick Clifton <nickc@cambridge.redhat.com>
+2002-01-22 Nick Clifton <nickc@redhat.com>
+
+ * config/arm/arm.h (CONDITIONAL_REGISTER_USAGE): Move 'regno'
+ variable declaration to outer scope in order to simplify
+ future extensions.
+ (HARD_REGNO_MODE_OK): Replace macro body with a with a call to
+ arm_hard_regno_mode_ok.
+ * config/arm/arm-protos.h: Add a prototype for
+ arm_hard_regno_mode_ok.
+ * config/arm/arm.c (soft_df_operand): Remove now redundant
+ check for DImode values using IP_REGNUM.
+ (nonimmediate_soft_df_operand): Remove now redundant check for
+ DImode values using IP_REGNUM.
+ (arm_hard_regno_mode_ok): New function. New check: make sure
+ that DImode values are not stored in IP_REGNUM.
* config/arm/arm.c (arm_expand_prologue): Replace REG_MAYBE_DEAD
note with a USE.
extern int arm_function_ok_for_sibcall PARAMS ((tree));
#endif
#ifdef RTX_CODE
+extern int arm_hard_regno_mode_ok PARAMS ((unsigned int, enum machine_mode));
extern int const_ok_for_arm PARAMS ((HOST_WIDE_INT));
extern int arm_split_constant PARAMS ((RTX_CODE, enum machine_mode,
HOST_WIDE_INT, rtx, rtx, int));
enum machine_mode mode;
{
if (s_register_operand (op, mode))
- {
- if (GET_CODE (op) == SUBREG)
- op = SUBREG_REG (op);
-
- /* The IP register must not be used, since its higher
- numbered counterpart is 13 - the stack pointer. */
- return REGNO (op) != IP_REGNUM;
- }
+ return TRUE;
if (mode != VOIDmode && GET_MODE (op) != mode)
return FALSE;
enum machine_mode mode;
{
if (s_register_operand (op, mode))
- {
- if (GET_CODE (op) == SUBREG)
- op = SUBREG_REG (op);
-
- /* The IP register must not be used, since its higher
- numbered counterpart is 13 - the stack pointer. */
- return REGNO (op) != IP_REGNUM;
- }
+ return TRUE;
if (mode != VOIDmode && GET_MODE (op) != mode)
return FALSE;
}
}
+/* Returns true if REGNO is a valid register
+ for holding a quantity of tyoe MODE. */
+
+int
+arm_hard_regno_mode_ok (regno, mode)
+ unsigned int regno;
+ enum machine_mode mode;
+{
+ if (GET_MODE_CLASS (mode) == MODE_CC)
+ return regno == CC_REGNUM;
+
+ if (TARGET_THUMB)
+ /* For the Thumb we only allow values bigger than SImode in
+ registers 0 - 6, so that there is always a second low
+ register available to hold the upper part of the value.
+ We probably we ought to ensure that the register is the
+ start of an even numbered register pair. */
+ return (NUM_REGS (mode) < 2) || (regno < LAST_LO_REGNUM);
+
+ if (regno <= LAST_ARM_REGNUM)
+ /* If the register is a general purpose ARM register we allow
+ it only if it not a special register (SP, LR, PC) and only
+ if there will be enough (non-special) registers to hold the
+ entire value. */
+ return regno < (SP_REGNUM - (unsigned) NUM_REGS (mode));
+
+ if ( regno == FRAME_POINTER_REGNUM
+ || regno == ARG_POINTER_REGNUM)
+ /* We only allow integers in the fake hard registers. */
+ return GET_MODE_CLASS (mode) == MODE_INT;
+
+ /* The only registers left are the FPU registers
+ which we only allow to hold FP values. */
+ return GET_MODE_CLASS (mode) == MODE_FLOAT
+ && regno >= FIRST_ARM_FP_REGNUM
+ && regno <= LAST_ARM_FP_REGNUM;
+}
+
int
arm_regno_class (regno)
int regno;
#define CONDITIONAL_REGISTER_USAGE \
{ \
+ int regno; \
+ \
if (TARGET_SOFT_FLOAT || TARGET_THUMB) \
{ \
- int regno; \
for (regno = FIRST_ARM_FP_REGNUM; \
regno <= LAST_ARM_FP_REGNUM; ++regno) \
fixed_regs[regno] = call_used_regs[regno] = 1; \
&& REGNO != ARG_POINTER_REGNUM) \
? 1 : NUM_REGS (MODE))
-/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
- This is TRUE for ARM regs since they can hold anything, and TRUE for FPU
- regs holding FP.
- For the Thumb we only allow values bigger than SImode in registers 0 - 6,
- so that there is always a second lo register available to hold the upper
- part of the value. Probably we ought to ensure that the register is the
- start of an even numbered register pair. */
+/* Return true if REGNO is suitable for holding a quantity of type MODE. */
#define HARD_REGNO_MODE_OK(REGNO, MODE) \
- (TARGET_ARM ? \
- ((GET_MODE_CLASS (MODE) == MODE_CC) ? (REGNO == CC_REGNUM) : \
- ( REGNO <= LAST_ARM_REGNUM \
- || REGNO == FRAME_POINTER_REGNUM \
- || REGNO == ARG_POINTER_REGNUM \
- || GET_MODE_CLASS (MODE) == MODE_FLOAT)) \
- : \
- ((GET_MODE_CLASS (MODE) == MODE_CC) ? (REGNO == CC_REGNUM) : \
- (NUM_REGS (MODE) < 2 || REGNO < LAST_LO_REGNUM)))
+ arm_hard_regno_mode_ok ((REGNO), (MODE))
/* Value is 1 if it is a good idea to tie two pseudo registers
when one has mode MODE1 and one has mode MODE2.
{ 0x200FFFF }, /* GENERAL_REGS */ \
{ 0x2FFFFFF } /* ALL_REGS */ \
}
-
+
/* The same information, inverted:
Return the class number of the smallest class containing
reg number REGNO. This could be a conditional expression
arm_encode_call_attribute (decl, LONG_CALL_FLAG_CHAR); \
else if (! TREE_PUBLIC (decl)) \
arm_encode_call_attribute (decl, SHORT_CALL_FLAG_CHAR); \
- } \
+ }
/* Symbols in the text segment can be accessed without indirecting via the
constant pool; it may take an extra binary operation, but this is still