OSDN Git Service

* builtins.c, c-common.c, c-decl.c, c-format.c, c-format.h,
[pf3gnuchains/gcc-fork.git] / gcc / reload.c
index 46b85f7..66894dc 100644 (file)
@@ -108,14 +108,6 @@ a register with any other reload.  */
 #include "params.h"
 #include "target.h"
 
-#ifndef REGNO_MODE_OK_FOR_BASE_P
-#define REGNO_MODE_OK_FOR_BASE_P(REGNO, MODE) REGNO_OK_FOR_BASE_P (REGNO)
-#endif
-
-#ifndef REG_MODE_OK_FOR_BASE_P
-#define REG_MODE_OK_FOR_BASE_P(REGNO, MODE) REG_OK_FOR_BASE_P (REGNO)
-#endif
-
 /* True if X is a constant that can be forced into the constant pool.  */
 #define CONST_POOL_OK_P(X)                     \
   (CONSTANT_P (X)                              \
@@ -1254,7 +1246,8 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
        mode = outmode;
       if (mode == VOIDmode)
        {
-         error_for_asm (this_insn, "cannot reload integer constant operand in `asm'");
+         error_for_asm (this_insn, "cannot reload integer constant "
+                        "operand in %<asm%>");
          mode = word_mode;
          if (in != 0)
            inmode = word_mode;
@@ -1276,7 +1269,8 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
          }
       if (i == FIRST_PSEUDO_REGISTER)
        {
-         error_for_asm (this_insn, "impossible register constraint in `asm'");
+         error_for_asm (this_insn, "impossible register constraint "
+                        "in %<asm%>");
          class = ALL_REGS;
        }
     }
@@ -3513,7 +3507,7 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
                this_alternative_earlyclobber[i] = 0;
                gcc_assert (this_insn_is_asm);
                error_for_asm (this_insn,
-                               "`&' constraint used with no register class");
+                              "%<&%> constraint used with no register class");
              }
 
            for (j = 0; j < noperands; j++)
@@ -3680,7 +3674,7 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
       /* No alternative works with reloads??  */
       if (insn_code_number >= 0)
        fatal_insn ("unable to generate reloads for:", insn);
-      error_for_asm (insn, "inconsistent operand constraints in an `asm'");
+      error_for_asm (insn, "inconsistent operand constraints in an %<asm%>");
       /* Avoid further trouble with this insn.  */
       PATTERN (insn) = gen_rtx_USE (VOIDmode, const0_rtx);
       n_reloads = 0;
@@ -3784,6 +3778,27 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
          goal_alternative_win[i] = 1;
       }
 
+  /* Likewise any invalid constants appearing as operand of a PLUS
+     that is to be reloaded.  */
+  for (i = 0; i < noperands; i++)
+    if (! goal_alternative_win[i]
+       && GET_CODE (recog_data.operand[i]) == PLUS
+       && CONST_POOL_OK_P (XEXP (recog_data.operand[i], 1))
+       && (PREFERRED_RELOAD_CLASS (XEXP (recog_data.operand[i], 1),
+                                   (enum reg_class) goal_alternative[i])
+            == NO_REGS)
+       && operand_mode[i] != VOIDmode)
+      {
+       rtx tem = force_const_mem (operand_mode[i],
+                                  XEXP (recog_data.operand[i], 1));
+       tem = gen_rtx_PLUS (operand_mode[i],
+                           XEXP (recog_data.operand[i], 0), tem);
+
+       substed_operand[i] = recog_data.operand[i]
+         = find_reloads_toplev (tem, i, address_type[i],
+                                ind_levels, 0, insn, NULL);
+      }
+
   /* Record the values of the earlyclobber operands for the caller.  */
   if (goal_earlyclobber)
     for (i = 0; i < noperands; i++)
@@ -3891,7 +3906,8 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
        else
          {
            gcc_assert (insn_code_number < 0);
-           error_for_asm (insn, "inconsistent operand constraints in an `asm'");
+           error_for_asm (insn, "inconsistent operand constraints "
+                          "in an %<asm%>");
            /* Avoid further trouble with this insn.  */
            PATTERN (insn) = gen_rtx_USE (VOIDmode, const0_rtx);
            n_reloads = 0;
@@ -4937,7 +4953,7 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad,
 #endif
           || operand == stack_pointer_rtx)
          && ! maybe_memory_address_p (mode, ad, 
-                                      &XEXP (XEXP (ad, 0), op_index)))
+                                      &XEXP (XEXP (ad, 0), 1 - op_index)))
        {
          rtx offset_reg;
          rtx addend;
@@ -5224,7 +5240,8 @@ update_auto_inc_notes (rtx insn ATTRIBUTE_UNUSED, int regno ATTRIBUTE_UNUSED,
    is strictly valid.)
 
    CONTEXT = 1 means we are considering regs as index regs,
-   = 0 means we are considering them as base regs.
+   = 0 means we are considering them as base regs, = 2 means we
+   are considering them as base regs for REG + REG.
 
    OPNUM and TYPE specify the purpose of any reloads made.
 
@@ -5247,8 +5264,23 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
                        rtx *loc, int opnum, enum reload_type type,
                        int ind_levels, rtx insn)
 {
+#define REG_OK_FOR_CONTEXT(CONTEXT, REGNO, MODE)               \
+  ((CONTEXT) == 2                                      \
+   ? REGNO_MODE_OK_FOR_REG_BASE_P (REGNO, MODE)                \
+   : (CONTEXT) == 1                                    \
+   ? REGNO_OK_FOR_INDEX_P (REGNO)                      \
+   : REGNO_MODE_OK_FOR_BASE_P (REGNO, MODE))
+
+  enum reg_class context_reg_class;
   RTX_CODE code = GET_CODE (x);
 
+  if (context == 2)
+    context_reg_class = MODE_BASE_REG_REG_CLASS (mode);
+  else if (context == 1)
+    context_reg_class = INDEX_REG_CLASS;
+  else
+    context_reg_class = MODE_BASE_REG_CLASS (mode);
+
   switch (code)
     {
     case PLUS:
@@ -5291,12 +5323,12 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
           register remateralization for expression like &localvar*4.  Reload it.
           It may be possible to combine the displacement on the outer level,
           but it is probably not worthwhile to do so.  */
-       if (context)
+       if (context == 1)
          {
            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 : MODE_BASE_REG_CLASS (mode)),
+                        context_reg_class,
                         GET_MODE (x), VOIDmode, 0, 0, opnum, type);
            return 1;
          }
@@ -5332,22 +5364,22 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
        else if (code0 == REG && code1 == REG)
          {
            if (REG_OK_FOR_INDEX_P (op0)
-               && REG_MODE_OK_FOR_BASE_P (op1, mode))
+               && REG_MODE_OK_FOR_REG_BASE_P (op1, mode))
              return 0;
            else if (REG_OK_FOR_INDEX_P (op1)
-                    && REG_MODE_OK_FOR_BASE_P (op0, mode))
+                    && REG_MODE_OK_FOR_REG_BASE_P (op0, mode))
              return 0;
-           else if (REG_MODE_OK_FOR_BASE_P (op1, mode))
+           else if (REG_MODE_OK_FOR_REG_BASE_P (op1, mode))
              find_reloads_address_1 (mode, orig_op0, 1, &XEXP (x, 0), opnum,
                                      type, ind_levels, insn);
-           else if (REG_MODE_OK_FOR_BASE_P (op0, mode))
+           else if (REG_MODE_OK_FOR_REG_BASE_P (op0, mode))
              find_reloads_address_1 (mode, orig_op1, 1, &XEXP (x, 1), opnum,
                                      type, ind_levels, insn);
            else if (REG_OK_FOR_INDEX_P (op1))
-             find_reloads_address_1 (mode, orig_op0, 0, &XEXP (x, 0), opnum,
+             find_reloads_address_1 (mode, orig_op0, 2, &XEXP (x, 0), opnum,
                                      type, ind_levels, insn);
            else if (REG_OK_FOR_INDEX_P (op0))
-             find_reloads_address_1 (mode, orig_op1, 0, &XEXP (x, 1), opnum,
+             find_reloads_address_1 (mode, orig_op1, 2, &XEXP (x, 1), opnum,
                                      type, ind_levels, insn);
            else
              {
@@ -5511,9 +5543,8 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
 
          if (reg_renumber[regno] >= 0)
            regno = reg_renumber[regno];
-         if ((regno >= FIRST_PSEUDO_REGISTER
-              || !(context ? REGNO_OK_FOR_INDEX_P (regno)
-                   : REGNO_MODE_OK_FOR_BASE_P (regno, mode))))
+         if (regno >= FIRST_PSEUDO_REGISTER
+             || !REG_OK_FOR_CONTEXT (context, regno, mode))
            {
              int reloadnum;
 
@@ -5549,8 +5580,7 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
                  x = XEXP (x, 0);
                  reloadnum
                    = push_reload (x, x, loc, loc,
-                                  (context ? INDEX_REG_CLASS :
-                                   MODE_BASE_REG_CLASS (mode)),
+                                  context_reg_class,
                                   GET_MODE (x), GET_MODE (x), 0, 0,
                                   opnum, RELOAD_OTHER);
                }
@@ -5558,8 +5588,7 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
                {
                  reloadnum
                    = push_reload (x, NULL_RTX, loc, (rtx*) 0,
-                                  (context ? INDEX_REG_CLASS :
-                                   MODE_BASE_REG_CLASS (mode)),
+                                  context_reg_class,
                                   GET_MODE (x), GET_MODE (x), 0, 0,
                                   opnum, type);
                  rld[reloadnum].inc
@@ -5599,8 +5628,7 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
                                opnum, type, ind_levels, insn);
 
          reloadnum = push_reload (x, NULL_RTX, loc, (rtx*) 0,
-                                  (context ? INDEX_REG_CLASS :
-                                   MODE_BASE_REG_CLASS (mode)),
+                                  context_reg_class,
                                   GET_MODE (x), VOIDmode, 0, 0, opnum, type);
          rld[reloadnum].inc
            = find_inc_amount (PATTERN (this_insn), XEXP (x, 0));
@@ -5629,7 +5657,7 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
       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 : MODE_BASE_REG_CLASS (mode)),
+                  context_reg_class,
                   GET_MODE (x), VOIDmode, 0, 0, opnum, type);
       return 1;
 
@@ -5640,8 +5668,7 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
        if (reg_equiv_constant[regno] != 0)
          {
            find_reloads_address_part (reg_equiv_constant[regno], loc,
-                                      (context ? INDEX_REG_CLASS :
-                                       MODE_BASE_REG_CLASS (mode)),
+                                      context_reg_class,
                                       GET_MODE (x), opnum, type, ind_levels);
            return 1;
          }
@@ -5651,8 +5678,7 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
        if (reg_equiv_mem[regno] != 0)
          {
            push_reload (reg_equiv_mem[regno], NULL_RTX, loc, (rtx*) 0,
-                        (context ? INDEX_REG_CLASS :
-                         MODE_BASE_REG_CLASS (mode)),
+                        context_reg_class,
                         GET_MODE (x), VOIDmode, 0, 0, opnum, type);
            return 1;
          }
@@ -5675,12 +5701,11 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
        if (reg_renumber[regno] >= 0)
          regno = reg_renumber[regno];
 
-       if ((regno >= FIRST_PSEUDO_REGISTER
-            || !(context ? REGNO_OK_FOR_INDEX_P (regno)
-                 : REGNO_MODE_OK_FOR_BASE_P (regno, mode))))
+       if (regno >= FIRST_PSEUDO_REGISTER
+           || !REG_OK_FOR_CONTEXT (context, regno, mode))
          {
            push_reload (x, NULL_RTX, loc, (rtx*) 0,
-                        (context ? INDEX_REG_CLASS : MODE_BASE_REG_CLASS (mode)),
+                        context_reg_class,
                         GET_MODE (x), VOIDmode, 0, 0, opnum, type);
            return 1;
          }
@@ -5692,7 +5717,7 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
        if (regno_clobbered_p (regno, this_insn, GET_MODE (x), 0))
          {
            push_reload (x, NULL_RTX, loc, (rtx*) 0,
-                        (context ? INDEX_REG_CLASS : MODE_BASE_REG_CLASS (mode)),
+                        context_reg_class,
                         GET_MODE (x), VOIDmode, 0, 0, opnum, type);
            return 1;
          }
@@ -5709,12 +5734,10 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
            {
              int regno ATTRIBUTE_UNUSED = subreg_regno (x);
 
-             if (! (context ? REGNO_OK_FOR_INDEX_P (regno)
-                    : REGNO_MODE_OK_FOR_BASE_P (regno, mode)))
+             if (! REG_OK_FOR_CONTEXT (context, regno, mode))
                {
                  push_reload (x, NULL_RTX, loc, (rtx*) 0,
-                              (context ? INDEX_REG_CLASS :
-                               MODE_BASE_REG_CLASS (mode)),
+                              context_reg_class,
                               GET_MODE (x), VOIDmode, 0, 0, opnum, type);
                  return 1;
                }
@@ -5723,8 +5746,7 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
             is larger than the class size, then reload the whole SUBREG.  */
          else
            {
-             enum reg_class class = (context ? INDEX_REG_CLASS
-                                     : MODE_BASE_REG_CLASS (mode));
+             enum reg_class class = context_reg_class;
              if ((unsigned) CLASS_MAX_NREGS (class, GET_MODE (SUBREG_REG (x)))
                  > reg_class_size[class])
                {
@@ -5754,6 +5776,7 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
       }
   }
 
+#undef REG_OK_FOR_CONTEXT
   return 0;
 }
 \f