OSDN Git Service

Implement MODE_BASE_REG_CLASS
authornickc <nickc@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 17 Dec 2001 16:46:11 +0000 (16:46 +0000)
committernickc <nickc@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 17 Dec 2001 16:46:11 +0000 (16:46 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@48104 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/caller-save.c
gcc/config/arm/arm.h
gcc/defaults.h
gcc/doc/tm.texi
gcc/recog.c
gcc/regclass.c
gcc/regrename.c
gcc/reload.c
gcc/reload1.c

index 7c89197..1e6e634 100644 (file)
@@ -151,7 +151,9 @@ init_caller_save ()
      that register in every mode we will use to save registers.  */
 
   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-    if (TEST_HARD_REG_BIT (reg_class_contents[(int) BASE_REG_CLASS], i))
+    if (TEST_HARD_REG_BIT
+       (reg_class_contents
+        [(int) MODE_BASE_REG_CLASS (regno_save_mode [i][1])], i))
       break;
 
   if (i == FIRST_PSEUDO_REGISTER)
index 6060275..85fea19 100644 (file)
@@ -256,6 +256,10 @@ Unrecognized value in TARGET_CPU_DEFAULT.
 %{!mthumb-interwork:%{!mno-thumb-interwork:%(cpp_interwork_default)}}  \
 "
 
+#ifndef CPP_PREDEFINES
+#define CPP_PREDEFINES ""
+#endif
+
 #ifndef CC1_SPEC
 #define CC1_SPEC ""
 #endif
@@ -1099,6 +1103,13 @@ enum reg_class
 #define INDEX_REG_CLASS  (TARGET_THUMB ? LO_REGS : GENERAL_REGS)
 #define BASE_REG_CLASS   (TARGET_THUMB ? BASE_REGS : GENERAL_REGS)
 
+/* For the Thumb the high registers cannot be used as base
+   registers when addressing quanitities in QI or HI mode.  */
+#define MODE_BASE_REG_CLASS(MODE)                                      \
+    (TARGET_ARM ? BASE_REGS :                                          \
+     (((MODE) == QImode || (MODE) == HImode || (MODE) == VOIDmode)     \
+     ? LO_REGS : BASE_REGS))
+
 /* When SMALL_REGISTER_CLASSES is nonzero, the compiler allows
    registers explicitly used in the rtl to be used as spill registers
    but prevents the compiler from extending the lifetime of these
index 91962d4..2a7c567 100644 (file)
@@ -450,4 +450,11 @@ You Lose!  You must define PREFERRED_DEBUGGING_TYPE!
 #define FUNCTION_ARG_REG_LITTLE_ENDIAN 0
 #endif
 
+/* Determine the register class for registers suitable to be the base
+   address register in a MEM.  Allow the choice to be dependent upon
+   the mode of the memory access.  */
+#ifndef MODE_BASE_REG_CLASS
+#define MODE_BASE_REG_CLASS(MODE) BASE_REG_CLASS
+#endif
+
 #endif  /* ! GCC_DEFAULTS_H */
index da3b4d5..30c94ee 100644 (file)
@@ -2203,6 +2203,13 @@ A macro whose definition is the name of the class to which a valid
 base register must belong.  A base register is one used in an address
 which is the register value plus a displacement.
 
+@findex MODE_BASE_REG_CLASS
+@item MODE_BASE_REG_CLASS (@var{mode})
+This is a variation of the @code{BASE_REG_CLASS} macro which allows
+the selection of a base register in a mode depenedent manner.  If
+@var{mode} is VOIDmode then it should return the same value as
+@code{BASE_REG_CLASS}.
+
 @findex INDEX_REG_CLASS
 @item INDEX_REG_CLASS
 A macro whose definition is the name of the class to which a valid
index adcd2d4..652038a 100644 (file)
@@ -2244,7 +2244,8 @@ preprocess_constraints ()
 
                case 'p':
                  op_alt[j].is_address = 1;
-                 op_alt[j].class = reg_class_subunion[(int) op_alt[j].class][(int) BASE_REG_CLASS];
+                 op_alt[j].class = reg_class_subunion[(int) op_alt[j].class]
+                   [(int) MODE_BASE_REG_CLASS (VOIDmode)];
                  break;
 
                case 'g': case 'r':
index 9ef8c8c..9bdb2b0 100644 (file)
@@ -1005,10 +1005,10 @@ record_operand_costs (insn, op_costs, reg_pref)
 
       if (GET_CODE (recog_data.operand[i]) == MEM)
        record_address_regs (XEXP (recog_data.operand[i], 0),
-                            BASE_REG_CLASS, frequency * 2);
+                            MODE_BASE_REG_CLASS (modes[i]), frequency * 2);
       else if (constraints[i][0] == 'p')
        record_address_regs (recog_data.operand[i],
-                            BASE_REG_CLASS, frequency * 2);
+                            MODE_BASE_REG_CLASS (modes[i]), frequency * 2);
     }
 
   /* Check for commutative in a separate loop so everything will
@@ -1086,7 +1086,7 @@ scan_one_insn (insn, pass)
                              GENERAL_REGS, 1)
            * frequency);
       record_address_regs (XEXP (SET_SRC (set), 0),
-                          BASE_REG_CLASS, frequency * 2);
+                          MODE_BASE_REG_CLASS (VOIDmode), frequency * 2);
       return insn;
     }
 
@@ -1228,15 +1228,15 @@ regclass (f, nregs, dump)
 
                  if ((0
 #ifdef SECONDARY_RELOAD_CLASS
-                      || (SECONDARY_RELOAD_CLASS (BASE_REG_CLASS, m, r)
+                      || (SECONDARY_RELOAD_CLASS (MODE_BASE_REG_CLASS (VOIDmode), m, r)
                           != NO_REGS)
 #else
 #ifdef SECONDARY_INPUT_RELOAD_CLASS
-                      || (SECONDARY_INPUT_RELOAD_CLASS (BASE_REG_CLASS, m, r)
+                      || (SECONDARY_INPUT_RELOAD_CLASS (MODE_BASE_REG_CLASS (VOIDmode), m, r)
                           != NO_REGS)
 #endif
 #ifdef SECONDARY_OUTPUT_RELOAD_CLASS
-                      || (SECONDARY_OUTPUT_RELOAD_CLASS (BASE_REG_CLASS, m, r)
+                      || (SECONDARY_OUTPUT_RELOAD_CLASS (MODE_BASE_REG_CLASS (VOIDmode), m, r)
                           != NO_REGS)
 #endif
 #endif
@@ -1609,7 +1609,7 @@ record_reg_classes (n_alts, n_ops, ops, modes,
                   address, ie BASE_REG_CLASS.  */
                classes[i]
                  = reg_class_subunion[(int) classes[i]]
-                   [(int) BASE_REG_CLASS];
+                   [(int) MODE_BASE_REG_CLASS (VOIDmode)];
                break;
 
              case 'm':  case 'o':  case 'V':
@@ -2016,7 +2016,7 @@ record_address_regs (x, class, scale)
           as well as in the tests below, that all addresses are in 
           canonical form.  */
 
-       else if (INDEX_REG_CLASS == BASE_REG_CLASS)
+       else if (INDEX_REG_CLASS == MODE_BASE_REG_CLASS (VOIDmode))
          {
            record_address_regs (arg0, class, scale);
            if (! CONSTANT_P (arg1))
@@ -2045,14 +2045,14 @@ record_address_regs (x, class, scale)
                 && (REG_OK_FOR_BASE_P (arg0) || REG_OK_FOR_INDEX_P (arg0)))
          record_address_regs (arg1,
                               REG_OK_FOR_BASE_P (arg0)
-                              ? INDEX_REG_CLASS : BASE_REG_CLASS,
+                              ? INDEX_REG_CLASS : MODE_BASE_REG_CLASS (VOIDmode),
                               scale);
        else if (code0 == REG && code1 == REG
                 && REGNO (arg1) < FIRST_PSEUDO_REGISTER
                 && (REG_OK_FOR_BASE_P (arg1) || REG_OK_FOR_INDEX_P (arg1)))
          record_address_regs (arg0,
                               REG_OK_FOR_BASE_P (arg1)
-                              ? INDEX_REG_CLASS : BASE_REG_CLASS,
+                              ? INDEX_REG_CLASS : MODE_BASE_REG_CLASS (VOIDmode),
                               scale);
 #endif
 
@@ -2063,14 +2063,14 @@ record_address_regs (x, class, scale)
        else if ((code0 == REG && REG_POINTER (arg0))
                 || code1 == MULT)
          {
-           record_address_regs (arg0, BASE_REG_CLASS, scale);
+           record_address_regs (arg0, MODE_BASE_REG_CLASS (VOIDmode), scale);
            record_address_regs (arg1, INDEX_REG_CLASS, scale);
          }
        else if ((code1 == REG && REG_POINTER (arg1))
                 || code0 == MULT)
          {
            record_address_regs (arg0, INDEX_REG_CLASS, scale);
-           record_address_regs (arg1, BASE_REG_CLASS, scale);
+           record_address_regs (arg1, MODE_BASE_REG_CLASS (VOIDmode), scale);
          }
 
        /* Otherwise, count equal chances that each might be a base
@@ -2078,9 +2078,11 @@ record_address_regs (x, class, scale)
 
        else
          {
-           record_address_regs (arg0, BASE_REG_CLASS, scale / 2);
+           record_address_regs (arg0, MODE_BASE_REG_CLASS (VOIDmode),
+                                scale / 2);
            record_address_regs (arg0, INDEX_REG_CLASS, scale / 2);
-           record_address_regs (arg1, BASE_REG_CLASS, scale / 2);
+           record_address_regs (arg1, MODE_BASE_REG_CLASS (VOIDmode),
+                                scale / 2);
            record_address_regs (arg1, INDEX_REG_CLASS, scale / 2);
          }
       }
@@ -2091,7 +2093,8 @@ record_address_regs (x, class, scale)
         if it ends up in the wrong place.  */
     case POST_MODIFY:
     case PRE_MODIFY:
-      record_address_regs (XEXP (x, 0), BASE_REG_CLASS, 2 * scale);
+      record_address_regs (XEXP (x, 0), MODE_BASE_REG_CLASS (VOIDmode),
+                          2 * scale);
       if (REG_P (XEXP (XEXP (x, 1), 1)))
        record_address_regs (XEXP (XEXP (x, 1), 1),
                             INDEX_REG_CLASS, 2 * scale);
index 3236a43..fca249e 100644 (file)
@@ -611,7 +611,7 @@ scan_rtx_address (insn, loc, class, action, mode)
        if (locI)
          scan_rtx_address (insn, locI, INDEX_REG_CLASS, action, mode);
        if (locB)
-         scan_rtx_address (insn, locB, BASE_REG_CLASS, action, mode);
+         scan_rtx_address (insn, locB, MODE_BASE_REG_CLASS (mode), action, mode);
        return;
       }
 
@@ -629,7 +629,8 @@ scan_rtx_address (insn, loc, class, action, mode)
       break;
 
     case MEM:
-      scan_rtx_address (insn, &XEXP (x, 0), BASE_REG_CLASS, action,
+      scan_rtx_address (insn, &XEXP (x, 0),
+                       MODE_BASE_REG_CLASS (GET_MODE (x)), action,
                        GET_MODE (x));
       return;
 
@@ -683,7 +684,8 @@ scan_rtx (insn, loc, class, action, type, earlyclobber)
       return;
 
     case MEM:
-      scan_rtx_address (insn, &XEXP (x, 0), BASE_REG_CLASS, action,
+      scan_rtx_address (insn, &XEXP (x, 0),
+                       MODE_BASE_REG_CLASS (GET_MODE (x)), action,
                        GET_MODE (x));
       return;
 
@@ -1376,8 +1378,9 @@ replace_oldest_value_addr (loc, class, mode, insn, vd)
          changed |= replace_oldest_value_addr (locI, INDEX_REG_CLASS, mode,
                                                insn, vd);
        if (locB)
-         changed |= replace_oldest_value_addr (locB, BASE_REG_CLASS, mode,
-                                               insn, vd);
+         changed |= replace_oldest_value_addr (locB,
+                                               MODE_BASE_REG_CLASS (mode),
+                                               mode, insn, vd);
        return changed;
       }
 
@@ -1422,7 +1425,8 @@ replace_oldest_value_mem (x, insn, vd)
      rtx insn;
      struct value_data *vd;
 {
-  return replace_oldest_value_addr (&XEXP (x, 0), BASE_REG_CLASS,
+  return replace_oldest_value_addr (&XEXP (x, 0),
+                                   MODE_BASE_REG_CLASS (GET_MODE (x)),
                                    GET_MODE (x), insn, vd);
 }
 
index e8adcfa..579cb1b 100644 (file)
@@ -3029,7 +3029,7 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
              case 'p':
                /* All necessary reloads for an address_operand
                   were handled in find_reloads_address.  */
-               this_alternative[i] = (int) BASE_REG_CLASS;
+               this_alternative[i] = (int) MODE_BASE_REG_CLASS (VOIDmode);
                win = 1;
                break;
 
@@ -3686,7 +3686,7 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
            operand_reloadnum[i]
              = push_reload (XEXP (recog_data.operand[i], 0), NULL_RTX,
                             &XEXP (recog_data.operand[i], 0), (rtx*)0,
-                            BASE_REG_CLASS,
+                            MODE_BASE_REG_CLASS (VOIDmode),
                             GET_MODE (XEXP (recog_data.operand[i], 0)),
                             VOIDmode, 0, 0, i, RELOAD_FOR_INPUT);
            rld[operand_reloadnum[i]].inc
@@ -4617,7 +4617,7 @@ find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels, insn)
        return 0;
 
       /* If we do not have one of the cases above, we must do the reload.  */
-      push_reload (ad, NULL_RTX, loc, (rtx*)0, BASE_REG_CLASS,
+      push_reload (ad, NULL_RTX, loc, (rtx*)0, MODE_BASE_REG_CLASS (mode),
                   GET_MODE (ad), VOIDmode, 0, 0, opnum, type);
       return 1;
     }
@@ -4718,7 +4718,7 @@ find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels, insn)
          /* Must use TEM here, not AD, since it is the one that will
             have any subexpressions reloaded, if needed.  */
          push_reload (tem, NULL_RTX, loc, (rtx*)0,
-                      BASE_REG_CLASS, GET_MODE (tem),
+                      MODE_BASE_REG_CLASS (mode), GET_MODE (tem),
                       VOIDmode, 0,
                       0, opnum, type);
          return ! removed_and;
@@ -4764,7 +4764,7 @@ find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels, insn)
          /* If the sum of two regs is not necessarily valid,
             reload the sum into a base reg.
             That will at least work.  */
-         find_reloads_address_part (ad, loc, BASE_REG_CLASS,
+         find_reloads_address_part (ad, loc, MODE_BASE_REG_CLASS (mode),
                                     Pmode, opnum, type, ind_levels);
        }
       return ! removed_and;
@@ -4807,7 +4807,8 @@ find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels, insn)
                                plus_constant (XEXP (XEXP (ad, 0), 0),
                                               INTVAL (XEXP (ad, 1))),
                                XEXP (XEXP (ad, 0), 1));
-      find_reloads_address_part (XEXP (ad, 0), &XEXP (ad, 0), BASE_REG_CLASS,
+      find_reloads_address_part (XEXP (ad, 0), &XEXP (ad, 0),
+                                MODE_BASE_REG_CLASS (mode),
                                 GET_MODE (ad), opnum, type, ind_levels);
       find_reloads_address_1 (mode, XEXP (ad, 1), 1, &XEXP (ad, 1), opnum,
                              type, 0, insn);
@@ -4831,7 +4832,8 @@ find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels, insn)
                                XEXP (XEXP (ad, 0), 0),
                                plus_constant (XEXP (XEXP (ad, 0), 1),
                                               INTVAL (XEXP (ad, 1))));
-      find_reloads_address_part (XEXP (ad, 1), &XEXP (ad, 1), BASE_REG_CLASS,
+      find_reloads_address_part (XEXP (ad, 1), &XEXP (ad, 1),
+                                MODE_BASE_REG_CLASS (mode),
                                 GET_MODE (ad), opnum, type, ind_levels);
       find_reloads_address_1 (mode, XEXP (ad, 0), 1, &XEXP (ad, 0), opnum,
                              type, 0, insn);
@@ -4877,8 +4879,8 @@ find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels, insn)
            loc = &XEXP (*loc, 0);
        }
 
-      find_reloads_address_part (ad, loc, BASE_REG_CLASS, Pmode, opnum, type,
-                                ind_levels);
+      find_reloads_address_part (ad, loc, MODE_BASE_REG_CLASS (mode),
+                                Pmode, opnum, type, ind_levels);
       return ! removed_and;
     }
 
@@ -5303,7 +5305,8 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels, insn)
                    /* Then reload the memory location into a base
                       register.  */
                    reloadnum = push_reload (tem, tem, &XEXP (x, 0),
-                                            &XEXP (op1, 0), BASE_REG_CLASS,
+                                            &XEXP (op1, 0),
+                                            MODE_BASE_REG_CLASS (mode),
                                             GET_MODE (x), GET_MODE (x), 0,
                                             0, opnum, RELOAD_OTHER);
 
@@ -5320,7 +5323,7 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels, insn)
              {
                reloadnum = push_reload (XEXP (op1, 0), XEXP (x, 0),
                                         &XEXP (op1, 0), &XEXP (x, 0),
-                                        BASE_REG_CLASS,
+                                        MODE_BASE_REG_CLASS (mode),
                                         GET_MODE (x), GET_MODE (x), 0, 0,
                                         opnum, RELOAD_OTHER);
 
@@ -5421,7 +5424,8 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels, insn)
                  x = XEXP (x, 0);
                  reloadnum
                    = push_reload (x, x, loc, loc,
-                                  (context ? INDEX_REG_CLASS : BASE_REG_CLASS),
+                                  (context ? INDEX_REG_CLASS :
+                                   MODE_BASE_REG_CLASS (mode)),
                                   GET_MODE (x), GET_MODE (x), 0, 0,
                                   opnum, RELOAD_OTHER);
                }
@@ -5429,7 +5433,8 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels, insn)
                {
                  reloadnum
                    = push_reload (x, NULL_RTX, loc, (rtx*)0,
-                                  (context ? INDEX_REG_CLASS : BASE_REG_CLASS),
+                                  (context ? INDEX_REG_CLASS :
+                                   MODE_BASE_REG_CLASS (mode)),
                                   GET_MODE (x), GET_MODE (x), 0, 0,
                                   opnum, type);
                  rld[reloadnum].inc
@@ -5469,7 +5474,8 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels, insn)
                                opnum, type, ind_levels, insn);
 
          reloadnum = push_reload (x, NULL_RTX, loc, (rtx*)0,
-                                  (context ? INDEX_REG_CLASS : BASE_REG_CLASS),
+                                  (context ? INDEX_REG_CLASS :
+                                   MODE_BASE_REG_CLASS (mode)),
                                   GET_MODE (x), VOIDmode, 0, 0, opnum, type);
          rld[reloadnum].inc
            = find_inc_amount (PATTERN (this_insn), XEXP (x, 0));
@@ -5498,7 +5504,7 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels, insn)
       find_reloads_address (GET_MODE (x), loc, XEXP (x, 0), &XEXP (x, 0),
                            opnum, ADDR_TYPE (type), ind_levels, insn);
       push_reload (*loc, NULL_RTX, loc, (rtx*)0,
-                  (context ? INDEX_REG_CLASS : BASE_REG_CLASS),
+                  (context ? INDEX_REG_CLASS : MODE_BASE_REG_CLASS (mode)),
                   GET_MODE (x), VOIDmode, 0, 0, opnum, type);
       return 1;
 
@@ -5509,7 +5515,8 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels, insn)
        if (reg_equiv_constant[regno] != 0)
          {
            find_reloads_address_part (reg_equiv_constant[regno], loc,
-                                      (context ? INDEX_REG_CLASS : BASE_REG_CLASS),
+                                      (context ? INDEX_REG_CLASS :
+                                       MODE_BASE_REG_CLASS (mode)),
                                       GET_MODE (x), opnum, type, ind_levels);
            return 1;
          }
@@ -5519,7 +5526,8 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels, insn)
        if (reg_equiv_mem[regno] != 0)
          {
            push_reload (reg_equiv_mem[regno], NULL_RTX, loc, (rtx*)0,
-                        (context ? INDEX_REG_CLASS : BASE_REG_CLASS),
+                        (context ? INDEX_REG_CLASS :
+                         MODE_BASE_REG_CLASS (mode)),
                         GET_MODE (x), VOIDmode, 0, 0, opnum, type);
            return 1;
          }
@@ -5547,7 +5555,7 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels, insn)
                  : REGNO_MODE_OK_FOR_BASE_P (regno, mode))))
          {
            push_reload (x, NULL_RTX, loc, (rtx*)0,
-                        (context ? INDEX_REG_CLASS : BASE_REG_CLASS),
+                        (context ? INDEX_REG_CLASS : MODE_BASE_REG_CLASS (mode)),
                         GET_MODE (x), VOIDmode, 0, 0, opnum, type);
            return 1;
          }
@@ -5559,7 +5567,7 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels, insn)
        if (regno_clobbered_p (regno, this_insn, GET_MODE (x), 0))
          {
            push_reload (x, NULL_RTX, loc, (rtx*)0,
-                        (context ? INDEX_REG_CLASS : BASE_REG_CLASS),
+                        (context ? INDEX_REG_CLASS : MODE_BASE_REG_CLASS (mode)),
                         GET_MODE (x), VOIDmode, 0, 0, opnum, type);
            return 1;
          }
@@ -5580,7 +5588,8 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels, insn)
                     : REGNO_MODE_OK_FOR_BASE_P (regno, mode)))
                {
                  push_reload (x, NULL_RTX, loc, (rtx*)0,
-                              (context ? INDEX_REG_CLASS : BASE_REG_CLASS),
+                              (context ? INDEX_REG_CLASS :
+                               MODE_BASE_REG_CLASS (mode)),
                               GET_MODE (x), VOIDmode, 0, 0, opnum, type);
                  return 1;
                }
@@ -5590,7 +5599,7 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels, insn)
          else
            {
              enum reg_class class = (context ? INDEX_REG_CLASS
-                                     : BASE_REG_CLASS);
+                                     : MODE_BASE_REG_CLASS (mode));
              if (CLASS_MAX_NREGS (class, GET_MODE (SUBREG_REG (x)))
                  > reg_class_size[class])
                {
index 58019b0..0f41718 100644 (file)
@@ -1363,7 +1363,8 @@ maybe_fix_stack_asms ()
                  break;
 
                case 'p':
-                 cls = (int) reg_class_subunion[cls][(int) BASE_REG_CLASS];
+                 cls = (int) reg_class_subunion[cls]
+                   [(int) MODE_BASE_REG_CLASS (VOIDmode)];
                  break;
 
                case 'g':