This patch replaces the current REG "i0" format with a dedicated structure,
so that we can make use of the extra 32 bits in the "i" field.

Of the places that iterate on formats and do something for 'i's,
most already handled REGs specially before the format walk and
so don't need to check for 'r'.  Otherwise it's mostly just a case
of adding dummy 'r' cases in order avoid the default gcc_unreachable ()
(in cases where we do the same for 'i').  The main exceptions are the
cselib.c and lra-constraints.c changes.

final.c:leaf_renumber_regs_insn handled REGs specially but then
went on to do a no-op walk of the format.  I just added an early
exit instead of an empty 'r' case.


gcc/
        * rtl.def (REG): Change format to "r".
        * rtl.h (rtunion): Remove rt_reg.
        (reg_info): New structure.
        (rtx_def): Add reg field to main union.
        (X0REGATTR): Delete.
        (REG_CHECK): New macro.
        (SET_REGNO_RAW, rhs_regno, REG_ATTRS): Use it.
        * rtl.c (rtx_format): Document "r".
        (rtx_code_size): Handle REG specially.
        * gengenrtl.c (special_format): Return true for formats
        that include 'r'.
        * gengtype.c (adjust_field_rtx_def): Handle 'r' fields.
        Deal with REG_ATTRS after the field loop.
        * emit-rtl.c (gen_raw_REG): Call rtx_alloc_stat directly.
        * expmed.c (init_expmed): Call gen_raw_REG instead of
        gen_rtx_raw_REG.
        * expr.c (init_expr_target): Likewise.
        * regcprop.c (maybe_mode_change): Likewise.
        * varasm.c (make_decl_rtl): Likewise.
        * final.c (leaf_renumber_regs_insn): Return early after
        handling REGs.
        * genemit.c (gen_exp): Handle 'r' fields.
        * genpeep.c (match_rtx): Likewise.
        * gensupport.c (subst_pattern_match): Likewise.
        (get_alternatives_number, collect_insn_data, alter_predicate_for_insn)
        (alter_constraints, subst_dup): Likewise.
        * read-rtl.c (read_rtx_code): Likewise.
        * print-rtl.c (print_rtx): Likewise.
        * genrecog.c (find_operand, find_matching_operand): Likewise.
        (validate_pattern, match_pattern_2): Likewise.
        (parameter::UINT, rtx_test::REGNO_FIELD): New enum values.
        (rtx_test::regno_field): New function.
        (operator ==, safe_to_hoist_p, transition_parameter_type)
        (parameter_type_string, print_parameter_value)
        (print_nonbool_test, print_test): Handle new enum values.
        * cselib.c (rtx_equal_for_cselib_1): Handle REG specially.
        * lra-constraints.c (operands_match_p): Likewise.

Index: gcc/rtl.def
===================================================================
--- gcc/rtl.def 2015-05-18 07:53:15.014808321 +0100
+++ gcc/rtl.def 2015-05-18 07:53:15.010808427 +0100
@@ -381,7 +381,7 @@ DEF_RTL_EXPR(PC, "pc", "", RTX_OBJ)
    points to a reg_attrs structure.
    This rtx needs to have as many (or more) fields as a MEM, since we
    can change REG rtx's into MEMs during reload.  */
-DEF_RTL_EXPR(REG, "reg", "i0", RTX_OBJ)
+DEF_RTL_EXPR(REG, "reg", "r", RTX_OBJ)
 
 /* A scratch register.  This represents a register used only within a
    single insn.  It will be replaced by a REG during register allocation
Index: gcc/rtl.h
===================================================================
--- gcc/rtl.h   2015-05-18 07:53:15.014808321 +0100
+++ gcc/rtl.h   2015-05-18 07:53:15.014808321 +0100
@@ -201,11 +201,21 @@ struct GTY((for_user)) reg_attrs {
   tree rt_tree;
   basic_block rt_bb;
   mem_attrs *rt_mem;
-  reg_attrs *rt_reg;
   struct constant_descriptor_rtx *rt_constant;
   struct dw_cfi_node *rt_cfi;
 };
 
+/* Describes the properties of a REG.  */
+struct GTY(()) reg_info {
+  /* The value of REGNO.  */
+  unsigned int regno;
+
+  unsigned int unused : 32;
+
+  /* The value of REG_ATTRS.  */
+  reg_attrs *attrs;
+};
+
 /* This structure remembers the position of a SYMBOL_REF within an
    object_block structure.  A SYMBOL_REF only provides this information
    if SYMBOL_REF_HAS_BLOCK_INFO_P is true.  */
@@ -395,6 +405,7 @@ struct GTY((desc("0"), tag("0"),
   union u {
     rtunion fld[1];
     HOST_WIDE_INT hwint[1];
+    struct reg_info reg;
     struct block_symbol block_sym;
     struct real_value rv;
     struct fixed_value fv;
@@ -1070,6 +1081,13 @@ #define XCNMPFV(RTX, C, M) __extension__
                                 __LINE__, __FUNCTION__);               \
    &_rtx->u.fv; })
 
+#define REG_CHECK(RTX) __extension__                                   \
+({ __typeof (RTX) const _rtx = (RTX);                                  \
+   if (GET_CODE (_rtx) != REG)                                         \
+     rtl_check_failed_code1 (_rtx, REG,  __FILE__, __LINE__,           \
+                            __FUNCTION__);                             \
+   &_rtx->u.reg; })
+
 #define BLOCK_SYMBOL_CHECK(RTX) __extension__                          \
 ({ __typeof (RTX) const _symbol = (RTX);                               \
    const unsigned int flags = SYMBOL_REF_FLAGS (_symbol);              \
@@ -1124,6 +1142,7 @@ #define XCMWINT(RTX, N, C, M)         ((RTX)
 #define XCNMWINT(RTX, N, C, M)     ((RTX)->u.hwint[N])
 #define XCNMPRV(RTX, C, M)         (&(RTX)->u.rv)
 #define XCNMPFV(RTX, C, M)         (&(RTX)->u.fv)
+#define REG_CHECK(RTX)             (&(RTX)->u.reg)
 #define BLOCK_SYMBOL_CHECK(RTX)            (&(RTX)->u.block_sym)
 #define HWIVEC_CHECK(RTX,C)        (&(RTX)->u.hwiv)
 
@@ -1248,7 +1267,6 @@ #define X0BBDEF(RTX, N)      (RTL_CHECK1 (
 #define X0ADVFLAGS(RTX, N) (RTL_CHECK1 (RTX, N, '0').rt_addr_diff_vec_flags)
 #define X0CSELIB(RTX, N)   (RTL_CHECK1 (RTX, N, '0').rt_cselib)
 #define X0MEMATTR(RTX, N)  (RTL_CHECKC1 (RTX, N, MEM).rt_mem)
-#define X0REGATTR(RTX, N)  (RTL_CHECKC1 (RTX, N, REG).rt_reg)
 #define X0CONSTANT(RTX, N) (RTL_CHECK1 (RTX, N, '0').rt_constant)
 
 /* Access a '0' field with any type.  */
@@ -1694,7 +1712,7 @@ #define LABEL_REF_LABEL(LABREF) XCEXP (L
    be used on RHS.  Use SET_REGNO to change the value.  */
 #define REGNO(RTX) (rhs_regno(RTX))
 #define SET_REGNO(RTX, N) (df_ref_change_reg_with_loc (RTX, N))
-#define SET_REGNO_RAW(RTX, N) (XCUINT (RTX, 0, REG) = N)
+#define SET_REGNO_RAW(RTX, N) (REG_CHECK (RTX)->regno = N)
 
 /* Return the number of consecutive registers in a REG.  This is always
    1 for pseudo registers and is determined by HARD_REGNO_NREGS for
@@ -1714,7 +1732,7 @@ #define ORIGINAL_REGNO(RTX) \
 static inline unsigned int
 rhs_regno (const_rtx x)
 {
-  return XCUINT (x, 0, REG);
+  return REG_CHECK (x)->regno;
 }
 
 
@@ -2271,7 +2289,7 @@ #define MEM_ATTRS(RTX) X0MEMATTR (RTX, 1
 
 /* The register attribute block.  We provide access macros for each value
    in the block and provide defaults if none specified.  */
-#define REG_ATTRS(RTX) X0REGATTR (RTX, 1)
+#define REG_ATTRS(RTX) (REG_CHECK (RTX)->attrs)
 
 #ifndef GENERATOR_FILE
 /* For a MEM rtx, the alias set.  If 0, this MEM is not in any alias
Index: gcc/rtl.c
===================================================================
--- gcc/rtl.c   2015-05-18 07:53:15.014808321 +0100
+++ gcc/rtl.c   2015-05-18 07:53:15.010808427 +0100
@@ -89,7 +89,8 @@ const char * const rtx_format[NUM_RTX_CO
          prints the uid of the insn.
      "b" is a pointer to a bitmap header.
      "B" is a basic block pointer.
-     "t" is a tree pointer.  */
+     "t" is a tree pointer.
+     "r" a register.  */
 
 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS)   FORMAT ,
 #include "rtl.def"             /* rtl expressions are defined here */
@@ -112,6 +113,8 @@ #define DEF_RTL_EXPR(ENUM, NAME, FORMAT,
   (((ENUM) == CONST_INT || (ENUM) == CONST_DOUBLE                      \
     || (ENUM) == CONST_FIXED || (ENUM) == CONST_WIDE_INT)              \
    ? RTX_HDR_SIZE + (sizeof FORMAT - 1) * sizeof (HOST_WIDE_INT)       \
+   : (ENUM) == REG                                                     \
+   ? RTX_HDR_SIZE + sizeof (reg_info)                                  \
    : RTX_HDR_SIZE + (sizeof FORMAT - 1) * sizeof (rtunion)),
 
 #include "rtl.def"
Index: gcc/gengenrtl.c
===================================================================
--- gcc/gengenrtl.c     2015-05-18 07:53:15.014808321 +0100
+++ gcc/gengenrtl.c     2015-05-18 07:53:15.006808572 +0100
@@ -113,7 +113,8 @@ special_format (const char *fmt)
   return (strchr (fmt, '*') != 0
          || strchr (fmt, 'V') != 0
          || strchr (fmt, 'S') != 0
-         || strchr (fmt, 'n') != 0);
+         || strchr (fmt, 'n') != 0
+         || strchr (fmt, 'r') != 0);
 }
 
 /* Return true if CODE always has VOIDmode.  */
Index: gcc/gengtype.c
===================================================================
--- gcc/gengtype.c      2015-05-18 07:53:15.014808321 +0100
+++ gcc/gengtype.c      2015-05-18 07:53:15.010808427 +0100
@@ -1241,6 +1241,7 @@ adjust_field_rtx_def (type_p t, options_
            case 'i':
            case 'n':
            case 'w':
+           case 'r':
              t = scalar_tp;
              subname = "rt_int";
              break;
@@ -1268,8 +1269,6 @@ adjust_field_rtx_def (type_p t, options_
                t = scalar_tp, subname = "rt_int";
              else if (i == DEBUG_EXPR && aindex == 0)
                t = tree_tp, subname = "rt_tree";
-             else if (i == REG && aindex == 1)
-               t = reg_attrs_tp, subname = "rt_reg";
              else if (i == SYMBOL_REF && aindex == 1)
                t = symbol_union_tp, subname = "";
              else if (i == JUMP_TABLE_DATA && aindex >= 4)
@@ -1344,6 +1343,9 @@ adjust_field_rtx_def (type_p t, options_
                                    "CONSTANT_POOL_ADDRESS_P (&%0)");
        }
 
+      if (i == REG)
+       subfields = create_field (subfields, reg_attrs_tp, "reg.attrs");
+
       if (i == SYMBOL_REF)
        {
          /* Add the "block_sym" field if SYMBOL_REF_HAS_BLOCK_INFO_P
Index: gcc/emit-rtl.c
===================================================================
--- gcc/emit-rtl.c      2015-05-18 07:53:15.014808321 +0100
+++ gcc/emit-rtl.c      2015-05-18 07:53:15.006808572 +0100
@@ -437,7 +437,10 @@ gen_blockage (void)
 rtx
 gen_raw_REG (machine_mode mode, int regno)
 {
-  rtx x = gen_rtx_raw_REG (mode, regno);
+  rtx x = rtx_alloc_stat (REG PASS_MEM_STAT);
+  PUT_MODE (x, mode);
+  SET_REGNO_RAW (x, regno);
+  REG_ATTRS (x) = NULL;
   ORIGINAL_REGNO (x) = regno;
   return x;
 }
Index: gcc/expmed.c
===================================================================
--- gcc/expmed.c        2015-05-18 07:53:15.014808321 +0100
+++ gcc/expmed.c        2015-05-18 07:53:15.006808572 +0100
@@ -260,7 +260,7 @@ init_expmed (void)
     }
 
   /* Avoid using hard regs in ways which may be unsupported.  */
-  all.reg = gen_rtx_raw_REG (mode, LAST_VIRTUAL_REGISTER + 1);
+  all.reg = gen_raw_REG (mode, LAST_VIRTUAL_REGISTER + 1);
   all.plus = gen_rtx_PLUS (mode, all.reg, all.reg);
   all.neg = gen_rtx_NEG (mode, all.reg);
   all.mult = gen_rtx_MULT (mode, all.reg, all.reg);
Index: gcc/expr.c
===================================================================
--- gcc/expr.c  2015-05-18 07:53:15.014808321 +0100
+++ gcc/expr.c  2015-05-18 07:53:15.006808572 +0100
@@ -258,7 +258,7 @@ init_expr_target (void)
          }
     }
 
-  mem = gen_rtx_MEM (VOIDmode, gen_rtx_raw_REG (Pmode, 10000));
+  mem = gen_rtx_MEM (VOIDmode, gen_raw_REG (Pmode, FIRST_PSEUDO_REGISTER));
 
   for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT); mode != VOIDmode;
        mode = GET_MODE_WIDER_MODE (mode))
Index: gcc/regcprop.c
===================================================================
--- gcc/regcprop.c      2015-05-18 07:53:15.014808321 +0100
+++ gcc/regcprop.c      2015-05-18 07:53:15.010808427 +0100
@@ -410,7 +410,7 @@ maybe_mode_change (machine_mode orig_mod
     return NULL_RTX;
 
   if (orig_mode == new_mode)
-    return gen_rtx_raw_REG (new_mode, regno);
+    return gen_raw_REG (new_mode, regno);
   else if (mode_change_ok (orig_mode, new_mode, regno))
     {
       int copy_nregs = hard_regno_nregs[copy_regno][copy_mode];
@@ -426,7 +426,7 @@ maybe_mode_change (machine_mode orig_mod
                + (BYTES_BIG_ENDIAN ? byteoffset : 0));
       regno += subreg_regno_offset (regno, orig_mode, offset, new_mode);
       if (HARD_REGNO_MODE_OK (regno, new_mode))
-       return gen_rtx_raw_REG (new_mode, regno);
+       return gen_raw_REG (new_mode, regno);
     }
   return NULL_RTX;
 }
Index: gcc/varasm.c
===================================================================
--- gcc/varasm.c        2015-05-18 07:53:15.014808321 +0100
+++ gcc/varasm.c        2015-05-18 07:53:15.014808321 +0100
@@ -1429,7 +1429,7 @@ make_decl_rtl (tree decl)
             confused with that register and be eliminated.  This usage is
             somewhat suspect...  */
 
-         SET_DECL_RTL (decl, gen_rtx_raw_REG (mode, reg_number));
+         SET_DECL_RTL (decl, gen_raw_REG (mode, reg_number));
          ORIGINAL_REGNO (DECL_RTL (decl)) = reg_number;
          REG_USERVAR_P (DECL_RTL (decl)) = 1;
 
Index: gcc/final.c
===================================================================
--- gcc/final.c 2015-05-18 07:53:15.014808321 +0100
+++ gcc/final.c 2015-05-18 07:53:15.006808572 +0100
@@ -4438,6 +4438,7 @@ leaf_renumber_regs_insn (rtx in_rtx)
       df_set_regs_ever_live (newreg, true);
       SET_REGNO (in_rtx, newreg);
       in_rtx->used = 1;
+      return;
     }
 
   if (INSN_P (in_rtx))
Index: gcc/genemit.c
===================================================================
--- gcc/genemit.c       2015-05-18 07:53:15.014808321 +0100
+++ gcc/genemit.c       2015-05-18 07:53:15.006808572 +0100
@@ -240,6 +240,10 @@ gen_exp (rtx x, enum rtx_code subroutine
          printf ("%u", XINT (x, i));
          break;
 
+       case 'r':
+         printf ("%u", REGNO (x));
+         break;
+
        case 's':
          printf ("\"%s\"", XSTR (x, i));
          break;
Index: gcc/genpeep.c
===================================================================
--- gcc/genpeep.c       2015-05-18 07:53:15.014808321 +0100
+++ gcc/genpeep.c       2015-05-18 07:53:15.010808427 +0100
@@ -276,6 +276,12 @@ match_rtx (rtx x, struct link *path, int
          printf ("  if (XINT (x, %d) != %d) goto L%d;\n",
                  i, XINT (x, i), fail_label);
        }
+      else if (fmt[i] == 'r')
+       {
+         gcc_assert (i == 0);
+         printf ("  if (REGNO (x) != %d) goto L%d;\n",
+                 REGNO (x), fail_label);
+       }
       else if (fmt[i] == 'w')
        {
          /* Make sure that at run time `x' is the RTX we want to test.  */
Index: gcc/gensupport.c
===================================================================
--- gcc/gensupport.c    2015-05-18 07:53:15.014808321 +0100
+++ gcc/gensupport.c    2015-05-18 07:53:15.010808427 +0100
@@ -880,7 +880,7 @@ subst_pattern_match (rtx x, rtx pt, int
 
       switch (fmt[i])
        {
-       case 'i': case 'w': case 's':
+       case 'i': case 'r': case 'w': case 's':
          continue;
 
        case 'e': case 'u':
@@ -1045,7 +1045,7 @@ get_alternatives_number (rtx pattern, in
                return 0;
          break;
 
-       case 'i': case 'w': case '0': case 's': case 'S': case 'T':
+       case 'i': case 'r': case 'w': case '0': case 's': case 'S': case 'T':
          break;
 
        default:
@@ -1104,7 +1104,7 @@ collect_insn_data (rtx pattern, int *pal
            collect_insn_data (XVECEXP (pattern, i, j), palt, pmax);
          break;
 
-       case 'i': case 'w': case '0': case 's': case 'S': case 'T':
+       case 'i': case 'r': case 'w': case '0': case 's': case 'S': case 'T':
          break;
 
        default:
@@ -1188,7 +1188,7 @@ alter_predicate_for_insn (rtx pattern, i
            }
          break;
 
-       case 'i': case 'w': case '0': case 's':
+       case 'i': case 'r': case 'w': case '0': case 's':
          break;
 
        default:
@@ -1246,7 +1246,7 @@ alter_constraints (rtx pattern, int n_du
            }
          break;
 
-       case 'i': case 'w': case '0': case 's':
+       case 'i': case 'r': case 'w': case '0': case 's':
          break;
 
        default:
@@ -2184,7 +2184,7 @@ subst_dup (rtx pattern, int n_alt, int n
                                                   n_alt, n_subst_alt);
          break;
 
-       case 'i': case 'w': case '0': case 's': case 'S': case 'T':
+       case 'i': case 'r': case 'w': case '0': case 's': case 'S': case 'T':
          break;
 
        default:
Index: gcc/read-rtl.c
===================================================================
--- gcc/read-rtl.c      2015-05-18 07:53:15.014808321 +0100
+++ gcc/read-rtl.c      2015-05-18 07:53:15.010808427 +0100
@@ -1346,6 +1346,13 @@ read_rtx_code (const char *code_name)
                                       name.string);
        break;
 
+      case 'r':
+       read_name (&name);
+       validate_const_int (name.string);
+       SET_REGNO_RAW (return_rtx, atoi (name.string));
+       REG_ATTRS (return_rtx) = NULL;
+       break;
+
       default:
        gcc_unreachable ();
       }
Index: gcc/print-rtl.c
===================================================================
--- gcc/print-rtl.c     2015-05-18 07:53:15.014808321 +0100
+++ gcc/print-rtl.c     2015-05-18 07:53:15.010808427 +0100
@@ -462,55 +462,12 @@ print_rtx (const_rtx in_rtx)
            int value = XINT (in_rtx, i);
            const char *name;
 
-#ifndef GENERATOR_FILE
-           if (REG_P (in_rtx) && (unsigned) value < FIRST_PSEUDO_REGISTER)
-             fprintf (outfile, " %d %s", value, reg_names[value]);
-           else if (REG_P (in_rtx)
-                    && (unsigned) value <= LAST_VIRTUAL_REGISTER)
-             {
-               if (value == VIRTUAL_INCOMING_ARGS_REGNUM)
-                 fprintf (outfile, " %d virtual-incoming-args", value);
-               else if (value == VIRTUAL_STACK_VARS_REGNUM)
-                 fprintf (outfile, " %d virtual-stack-vars", value);
-               else if (value == VIRTUAL_STACK_DYNAMIC_REGNUM)
-                 fprintf (outfile, " %d virtual-stack-dynamic", value);
-               else if (value == VIRTUAL_OUTGOING_ARGS_REGNUM)
-                 fprintf (outfile, " %d virtual-outgoing-args", value);
-               else if (value == VIRTUAL_CFA_REGNUM)
-                 fprintf (outfile, " %d virtual-cfa", value);
-               else if (value == VIRTUAL_PREFERRED_STACK_BOUNDARY_REGNUM)
-                 fprintf (outfile, " %d virtual-preferred-stack-boundary",
-                          value);
-               else
-                 fprintf (outfile, " %d virtual-reg-%d", value,
-                          value-FIRST_VIRTUAL_REGISTER);
-             }
-           else
-#endif
-             if (flag_dump_unnumbered
-                    && (is_insn || NOTE_P (in_rtx)))
+           if (flag_dump_unnumbered
+               && (is_insn || NOTE_P (in_rtx)))
              fputc ('#', outfile);
            else
              fprintf (outfile, " %d", value);
 
-#ifndef GENERATOR_FILE
-           if (REG_P (in_rtx) && REG_ATTRS (in_rtx))
-             {
-               fputs (" [", outfile);
-               if (ORIGINAL_REGNO (in_rtx) != REGNO (in_rtx))
-                 fprintf (outfile, "orig:%i", ORIGINAL_REGNO (in_rtx));
-               if (REG_EXPR (in_rtx))
-                 print_mem_expr (outfile, REG_EXPR (in_rtx));
-
-               if (REG_OFFSET (in_rtx))
-                 fprintf (outfile, "+" HOST_WIDE_INT_PRINT_DEC,
-                          REG_OFFSET (in_rtx));
-               fputs (" ]", outfile);
-             }
-           if (REG_P (in_rtx) && REGNO (in_rtx) != ORIGINAL_REGNO (in_rtx))
-             fprintf (outfile, " [%d]", ORIGINAL_REGNO (in_rtx));
-#endif
-
            if (is_insn && &INSN_CODE (in_rtx) == &XINT (in_rtx, i)
                && XINT (in_rtx, i) >= 0
                && (name = get_insn_name (XINT (in_rtx, i))) != NULL)
@@ -519,6 +476,58 @@ print_rtx (const_rtx in_rtx)
          }
        break;
 
+      case 'r':
+       {
+         unsigned int regno = REGNO (in_rtx);
+#ifndef GENERATOR_FILE
+         if (regno < FIRST_PSEUDO_REGISTER)
+           fprintf (outfile, " %d %s", regno, reg_names[regno]);
+         else if (regno <= LAST_VIRTUAL_REGISTER)
+           {
+             if (regno == VIRTUAL_INCOMING_ARGS_REGNUM)
+               fprintf (outfile, " %d virtual-incoming-args", regno);
+             else if (regno == VIRTUAL_STACK_VARS_REGNUM)
+               fprintf (outfile, " %d virtual-stack-vars", regno);
+             else if (regno == VIRTUAL_STACK_DYNAMIC_REGNUM)
+               fprintf (outfile, " %d virtual-stack-dynamic", regno);
+             else if (regno == VIRTUAL_OUTGOING_ARGS_REGNUM)
+               fprintf (outfile, " %d virtual-outgoing-args", regno);
+             else if (regno == VIRTUAL_CFA_REGNUM)
+               fprintf (outfile, " %d virtual-cfa", regno);
+             else if (regno == VIRTUAL_PREFERRED_STACK_BOUNDARY_REGNUM)
+               fprintf (outfile, " %d virtual-preferred-stack-boundary",
+                        regno);
+             else
+               fprintf (outfile, " %d virtual-reg-%d", regno,
+                        regno-FIRST_VIRTUAL_REGISTER);
+           }
+         else
+#endif
+           if (flag_dump_unnumbered && is_insn)
+             fputc ('#', outfile);
+           else
+             fprintf (outfile, " %d", regno);
+
+#ifndef GENERATOR_FILE
+         if (REG_ATTRS (in_rtx))
+           {
+             fputs (" [", outfile);
+             if (regno != ORIGINAL_REGNO (in_rtx))
+               fprintf (outfile, "orig:%i", ORIGINAL_REGNO (in_rtx));
+             if (REG_EXPR (in_rtx))
+               print_mem_expr (outfile, REG_EXPR (in_rtx));
+
+             if (REG_OFFSET (in_rtx))
+               fprintf (outfile, "+" HOST_WIDE_INT_PRINT_DEC,
+                        REG_OFFSET (in_rtx));
+             fputs (" ]", outfile);
+           }
+         if (regno != ORIGINAL_REGNO (in_rtx))
+           fprintf (outfile, " [%d]", ORIGINAL_REGNO (in_rtx));
+#endif
+         break;
+       }
+
       /* Print NOTE_INSN names rather than integer codes.  */
 
       case 'n':
Index: gcc/genrecog.c
===================================================================
--- gcc/genrecog.c      2015-05-18 07:53:15.014808321 +0100
+++ gcc/genrecog.c      2015-05-18 07:53:15.010808427 +0100
@@ -396,7 +396,7 @@ find_operand (rtx pattern, int n, rtx st
              return r;
          break;
 
-       case 'i': case 'w': case '0': case 's':
+       case 'i': case 'r': case 'w': case '0': case 's':
          break;
 
        default:
@@ -447,7 +447,7 @@ find_matching_operand (rtx pattern, int
              return r;
          break;
 
-       case 'i': case 'w': case '0': case 's':
+       case 'i': case 'r': case 'w': case '0': case 's':
          break;
 
        default:
@@ -747,7 +747,7 @@ validate_pattern (rtx pattern, rtx insn,
            validate_pattern (XVECEXP (pattern, i, j), insn, NULL_RTX, 0);
          break;
 
-       case 'i': case 'w': case '0': case 's':
+       case 'i': case 'r': case 'w': case '0': case 's':
          break;
 
        default:
@@ -967,6 +967,9 @@ struct parameter
     /* An int parameter.  */
     INT,
 
+    /* An unsigned int parameter.  */
+    UINT,
+
     /* A HOST_WIDE_INT parameter.  */
     WIDE_INT
   };
@@ -1063,6 +1066,9 @@ struct rtx_test
     /* Check GET_MODE (X) == LABEL.  */
     MODE,
 
+    /* Check REGNO (X) == LABEL.  */
+    REGNO_FIELD,
+
     /* Check XINT (X, u.opno) == LABEL.  */
     INT_FIELD,
 
@@ -1142,6 +1148,7 @@ struct rtx_test
 
   static rtx_test code (position *);
   static rtx_test mode (position *);
+  static rtx_test regno_field (position *);
   static rtx_test int_field (position *, int);
   static rtx_test wide_int_field (position *, int);
   static rtx_test veclen (position *);
@@ -1180,6 +1187,13 @@ rtx_test::mode (position *pos)
 }
 
 rtx_test
+rtx_test::regno_field (position *pos)
+{
+  rtx_test res (pos, rtx_test::REGNO_FIELD);
+  return res;
+}
+
+rtx_test
 rtx_test::int_field (position *pos, int opno)
 {
   rtx_test res (pos, rtx_test::INT_FIELD);
@@ -1299,6 +1313,7 @@ operator == (const rtx_test &a, const rt
     {
     case rtx_test::CODE:
     case rtx_test::MODE:
+    case rtx_test::REGNO_FIELD:
     case rtx_test::VECLEN:
     case rtx_test::HAVE_NUM_CLOBBERS:
       return true;
@@ -1753,6 +1768,7 @@ safe_to_hoist_p (decision *d, const rtx_
        }
       gcc_unreachable ();
 
+    case rtx_test::REGNO_FIELD:
     case rtx_test::INT_FIELD:
     case rtx_test::WIDE_INT_FIELD:
     case rtx_test::VECLEN:
@@ -1959,6 +1975,9 @@ transition_parameter_type (rtx_test::kin
     case rtx_test::MODE:
       return parameter::MODE;
 
+    case rtx_test::REGNO_FIELD:
+      return parameter::UINT;
+
     case rtx_test::INT_FIELD:
     case rtx_test::VECLEN:
     case rtx_test::PATTERN:
@@ -3970,6 +3989,13 @@ match_pattern_2 (state *s, rtx top_patte
                                      XINT (pattern, i), false);
                    break;
 
+                 case 'r':
+                   /* Make sure that REGNO (X) has the right value.  */
+                   gcc_assert (i == 0);
+                   s = add_decision (s, rtx_test::regno_field (pos),
+                                     REGNO (pattern), false);
+                   break;
+
                  case 'w':
                    /* Make sure that XWINT (X, I) has the right value.  */
                    s = add_decision (s, rtx_test::wide_int_field (pos, i),
@@ -4232,6 +4258,9 @@ parameter_type_string (parameter::type_e
     case parameter::INT:
       return "int";
 
+    case parameter::UINT:
+      return "unsigned int";
+
     case parameter::WIDE_INT:
       return "HOST_WIDE_INT";
     }
@@ -4451,6 +4480,10 @@ print_parameter_value (const parameter &
        printf ("%d", (int) param.value);
        break;
 
+      case parameter::UINT:
+       printf ("%u", (unsigned int) param.value);
+       break;
+
       case parameter::WIDE_INT:
        print_host_wide_int (param.value);
        break;
@@ -4499,6 +4532,12 @@ print_nonbool_test (output_state *os, co
       printf (", %d)", test.u.opno);
       break;
 
+    case rtx_test::REGNO_FIELD:
+      printf ("REGNO (");
+      print_test_rtx (os, test);
+      printf (")");
+      break;
+
     case rtx_test::WIDE_INT_FIELD:
       printf ("XWINT (");
       print_test_rtx (os, test);
@@ -4572,6 +4611,7 @@ print_test (output_state *os, const rtx_
     case rtx_test::CODE:
     case rtx_test::MODE:
     case rtx_test::VECLEN:
+    case rtx_test::REGNO_FIELD:
     case rtx_test::INT_FIELD:
     case rtx_test::WIDE_INT_FIELD:
     case rtx_test::PATTERN:
Index: gcc/cselib.c
===================================================================
--- gcc/cselib.c        2015-05-18 07:53:15.014808321 +0100
+++ gcc/cselib.c        2015-05-18 07:53:15.002808721 +0100
@@ -976,6 +976,9 @@ rtx_equal_for_cselib_1 (rtx x, rtx y, ma
     case LABEL_REF:
       return LABEL_REF_LABEL (x) == LABEL_REF_LABEL (y);
 
+    case REG:
+      return REGNO (x) == REGNO (y);
+
     case MEM:
       /* We have to compare any autoinc operations in the addresses
         using this MEM's mode.  */
Index: gcc/lra-constraints.c
===================================================================
--- gcc/lra-constraints.c       2015-05-18 07:53:15.014808321 +0100
+++ gcc/lra-constraints.c       2015-05-18 07:53:15.010808427 +0100
@@ -749,6 +749,9 @@ operands_match_p (rtx x, rtx y, int y_ha
 
  slow:
 
+  if (code == REG && REG_P (y))
+    return REGNO (x) == REGNO (y);
+
   if (code == REG && GET_CODE (y) == SUBREG && REG_P (SUBREG_REG (y))
       && x == SUBREG_REG (y))
     return true;

Reply via email to