aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2002-01-22 17:35:27 +0000
committerNick Clifton <nickc@gcc.gnu.org>2002-01-22 17:35:27 +0000
commit4b02997f471d575f8367d32ee9c494aecfbc0d29 (patch)
treed5ba45f6205e169b8e856fd187410879ae678135
parentc14a3a45786410dbe33b205bb71f3afa5b4b50b2 (diff)
downloadgcc-4b02997f471d575f8367d32ee9c494aecfbc0d29.zip
gcc-4b02997f471d575f8367d32ee9c494aecfbc0d29.tar.gz
gcc-4b02997f471d575f8367d32ee9c494aecfbc0d29.tar.bz2
Move body of HARD_REGNO_MODE_OK into a function: arm_hard_regno_mode_ok
From-SVN: r49080
-rw-r--r--gcc/ChangeLog16
-rw-r--r--gcc/config/arm/arm-protos.h1
-rw-r--r--gcc/config/arm/arm.c56
-rw-r--r--gcc/config/arm/arm.h25
4 files changed, 62 insertions, 36 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a304260..4659749 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,4 +1,18 @@
-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.
diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
index 11accd3..b42da823 100644
--- a/gcc/config/arm/arm-protos.h
+++ b/gcc/config/arm/arm-protos.h
@@ -43,6 +43,7 @@ extern void arm_encode_call_attribute PARAMS ((tree, int));
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));
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 1490134..04f06ae 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -3358,14 +3358,7 @@ soft_df_operand (op, mode)
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;
@@ -3397,14 +3390,7 @@ nonimmediate_soft_df_operand (op, mode)
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;
@@ -9133,6 +9119,44 @@ arm_final_prescan_insn (insn)
}
}
+/* 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;
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index 5a7b9b5..6f05569 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -847,9 +847,10 @@ extern const char * structure_size_string;
#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; \
@@ -1004,23 +1005,9 @@ extern const char * structure_size_string;
&& 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.
@@ -1092,7 +1079,7 @@ enum reg_class
{ 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
@@ -1909,7 +1896,7 @@ typedef struct
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