Move body of HARD_REGNO_MODE_OK into a function: arm_hard_regno_mode_ok
authorNick Clifton <nickc@redhat.com>
Tue, 22 Jan 2002 17:35:27 +0000 (17:35 +0000)
committerNick Clifton <nickc@gcc.gnu.org>
Tue, 22 Jan 2002 17:35:27 +0000 (17:35 +0000)
From-SVN: r49080

gcc/ChangeLog
gcc/config/arm/arm-protos.h
gcc/config/arm/arm.c
gcc/config/arm/arm.h

index a304260b04a38aaffb488f12007eea2fb115a14f..4659749eddfc9c48215020dbe2599cd1a688efa4 100644 (file)
@@ -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.
index 11accd34b32803c74e9239559ae80e3ae41d37c0..b42da823869aa7eef5d4b2e26b634054c2799fb8 100644 (file)
@@ -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));
index 1490134efde6a5b37b35499422bf6a8f5dff6c60..04f06ae997df902250fa2da9fb0e843b5ea4c06e 100644 (file)
@@ -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;
index 5a7b9b543d344edcec9d72c286af3524f881a855..6f055699f010cd1eaed9df79bac024b3dae937c9 100644 (file)
@@ -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