OSDN Git Service

* simplify_rtx.c (simplify_subreg): Keep subregs on return values,
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 4 Jun 2001 14:52:14 +0000 (14:52 +0000)
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 4 Jun 2001 14:52:14 +0000 (14:52 +0000)
check CLASS_CANNOT_CHANGE_MODE before avoiding subreg on hard reg,
in case register wasn't OK previously, accept it now; allow
subregs of frame pointer if reload completed and frame pointer
is not needed.

* combine.c (sombine_simplify_rtx): Fix comment;
use subreg_lowpart_offset instead of subreg_lowpart_p
(gen_lowpart_for_combine): Use subreg_lowpart_offset.
* rtl.h (subreg_lowpart_parts_p): Kill.
(subreg_lowpart_offset, subreg_highpart_offset): Declare.
* simplify-rtx.c (simplify_subreg): Use subreg_lowpart_offset.
* emit-rtl.c (gen_lowpart_SUBREG): Use subreg_lowpart_offset;
(gen_lowpart_common): Likewise.
(subreg_lowpart_p): Likewise.
(subreg_lowpart_parts_p): Kill.
(subreg_lowpart_offset, subreg_highpart_offset): New function.

* emit-rtl.c (gen_lowpart_common): Use simplify_gen_subreg
to simplify SUBREG and REG.
(gen_highpart): Use simplify_gen_subreg for all simplifications.

* emit-rtl.c (gen_realpart, gen_imagpart): Do not handle
CONCAT specially.

* rtlanal.c (replace_regs):  Use simplify_gen_subreg

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@42850 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/combine.c
gcc/emit-rtl.c
gcc/rtl.h
gcc/rtlanal.c
gcc/simplify-rtx.c

index b688945..d387b24 100644 (file)
@@ -1,3 +1,32 @@
+Mon Jun  4 16:50:33 CEST 2001  Jan Hubicka  <jh@suse.cz>
+
+       * simplify_rtx.c (simplify_subreg): Keep subregs on return values,
+       check CLASS_CANNOT_CHANGE_MODE before avoiding subreg on hard reg,
+       in case register wasn't OK previously, accept it now; allow
+       subregs of frame pointer if reload completed and frame pointer
+       is not needed.
+
+       * combine.c (sombine_simplify_rtx): Fix comment;
+       use subreg_lowpart_offset instead of subreg_lowpart_p
+       (gen_lowpart_for_combine): Use subreg_lowpart_offset.
+       * rtl.h (subreg_lowpart_parts_p): Kill.
+       (subreg_lowpart_offset, subreg_highpart_offset): Declare.
+       * simplify-rtx.c (simplify_subreg): Use subreg_lowpart_offset.
+       * emit-rtl.c (gen_lowpart_SUBREG): Use subreg_lowpart_offset;
+       (gen_lowpart_common): Likewise.
+       (subreg_lowpart_p): Likewise.
+       (subreg_lowpart_parts_p): Kill.
+       (subreg_lowpart_offset, subreg_highpart_offset): New function.
+
+       * emit-rtl.c (gen_lowpart_common): Use simplify_gen_subreg
+       to simplify SUBREG and REG.
+       (gen_highpart): Use simplify_gen_subreg for all simplifications.
+
+       * emit-rtl.c (gen_realpart, gen_imagpart): Do not handle
+       CONCAT specially.
+
+       * rtlanal.c (replace_regs):  Use simplify_gen_subreg
+
 Mon Jun  4 09:21:19 2001  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>
 
        * tree.def (ARRAY_RANGE_REF): New code.
index bfa97b0..e34ab2f 100644 (file)
@@ -3715,7 +3715,7 @@ combine_simplify_rtx (x, op0_mode, last, in_dest)
 
   /* If CODE is an associative operation not otherwise handled, see if we
      can associate some operands.  This can win if they are constants or
-     if they are logically related (i.e. (a & b) & a.  */
+     if they are logically related (i.e. (a & b) & a).  */
   if ((code == PLUS || code == MINUS
        || code == MULT || code == AND || code == IOR || code == XOR
        || code == DIV || code == UDIV
@@ -3774,7 +3774,7 @@ combine_simplify_rtx (x, op0_mode, last, in_dest)
 
       /* simplify_subreg can't use gen_lowpart_for_combine.  */
       if (CONSTANT_P (SUBREG_REG (x))
-         && subreg_lowpart_parts_p (mode, op0_mode, SUBREG_BYTE (x)))
+         && subreg_lowpart_offset (mode, op0_mode) == SUBREG_BYTE (x))
        return gen_lowpart_for_combine (mode, SUBREG_REG (x));
 
       {
@@ -9765,18 +9765,13 @@ gen_lowpart_for_combine (mode, x)
   else
     {
       int offset = 0;
+      rtx res;
 
-      if ((WORDS_BIG_ENDIAN || BYTES_BIG_ENDIAN)
-         && GET_MODE_SIZE (GET_MODE (x)) > GET_MODE_SIZE (mode))
-       {
-         int difference = (GET_MODE_SIZE (GET_MODE (x))
-                           - GET_MODE_SIZE (mode));
-         if (WORDS_BIG_ENDIAN)
-           offset += (difference / UNITS_PER_WORD) * UNITS_PER_WORD;
-         if (BYTES_BIG_ENDIAN)
-           offset += difference % UNITS_PER_WORD;
-       }
-      return gen_rtx_SUBREG (mode, x, offset);
+      offset = subreg_lowpart_offset (mode, GET_MODE (x));
+      res = simplify_gen_subreg (mode, x, GET_MODE (x), offset);
+      if (res)
+       return res;
+      return gen_rtx_CLOBBER (GET_MODE (x), const0_rtx);
     }
 }
 \f
index 7a98f20..6c72a99 100644 (file)
@@ -381,22 +381,12 @@ gen_lowpart_SUBREG (mode, reg)
      rtx reg;
 {
   enum machine_mode inmode;
-  int offset;
 
   inmode = GET_MODE (reg);
   if (inmode == VOIDmode)
     inmode = mode;
-  offset = 0;
-  if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (inmode)
-      && (WORDS_BIG_ENDIAN || BYTES_BIG_ENDIAN))
-    {
-      offset = GET_MODE_SIZE (inmode) - GET_MODE_SIZE (mode);
-      if (! BYTES_BIG_ENDIAN)
-       offset = (offset / UNITS_PER_WORD) * UNITS_PER_WORD;
-      else if (! WORDS_BIG_ENDIAN)
-       offset %= UNITS_PER_WORD;
-    }
-  return gen_rtx_SUBREG (mode, reg, offset);
+  return gen_rtx_SUBREG (mode, reg,
+                        subreg_lowpart_offset (mode, inmode));
 }
 \f
 /* rtx gen_rtx (code, mode, [element1, ..., elementn])
@@ -761,16 +751,7 @@ gen_lowpart_common (mode, x)
          > ((xsize + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)))
     return 0;
 
-  if ((WORDS_BIG_ENDIAN || BYTES_BIG_ENDIAN)
-      && xsize > msize)
-    {
-      int difference = xsize - msize;
-
-      if (WORDS_BIG_ENDIAN)
-       offset += (difference / UNITS_PER_WORD) * UNITS_PER_WORD;
-      if (BYTES_BIG_ENDIAN)
-       offset += difference % UNITS_PER_WORD;
-    }
+  offset = subreg_lowpart_offset (mode, GET_MODE (x));
 
   if ((GET_CODE (x) == ZERO_EXTEND || GET_CODE (x) == SIGN_EXTEND)
       && (GET_MODE_CLASS (mode) == MODE_INT
@@ -791,61 +772,8 @@ gen_lowpart_common (mode, x)
       else if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (x)))
        return gen_rtx_fmt_e (GET_CODE (x), mode, XEXP (x, 0));
     }
-  else if (GET_CODE (x) == SUBREG
-          && (GET_MODE_SIZE (mode) <= UNITS_PER_WORD
-              || GET_MODE_SIZE (mode) == GET_MODE_UNIT_SIZE (GET_MODE (x))))
-    {
-      int final_offset;
-
-      if (GET_MODE (SUBREG_REG (x)) == mode && subreg_lowpart_p (x))
-       return SUBREG_REG (x);
-
-      /* When working with SUBREGs the rule is that the byte
-        offset must be a multiple of the SUBREG's mode.  */
-      final_offset = SUBREG_BYTE (x) + offset;
-      final_offset = (final_offset / GET_MODE_SIZE (mode));
-      final_offset = (final_offset * GET_MODE_SIZE (mode));
-      return gen_rtx_SUBREG (mode, SUBREG_REG (x), final_offset);   
-    }
-  else if (GET_CODE (x) == REG)
-    {
-      /* Hard registers are done specially in certain cases.  */  
-      if (REGNO (x) < FIRST_PSEUDO_REGISTER)
-        {
-         int final_regno = REGNO (x) +
-                           subreg_regno_offset (REGNO (x), GET_MODE (x), 
-                                                offset, mode);
-
-         /* If the final regno is not valid for MODE, punt.  */
-         /* ??? We do allow it if the current REG is not valid for
-            ??? it's mode.  It is a kludge to work around how float/complex
-            ??? arguments are passed on 32-bit Sparc and should be fixed.  */
-         if (! HARD_REGNO_MODE_OK (final_regno, mode)
-             && HARD_REGNO_MODE_OK (REGNO (x), GET_MODE (x)))
-           return 0;
-
-              /* integrate.c can't handle parts of a return value register. */
-         if ((! REG_FUNCTION_VALUE_P (x)
-                  || ! rtx_equal_function_value_matters)
-#ifdef CLASS_CANNOT_CHANGE_MODE
-              && ! (CLASS_CANNOT_CHANGE_MODE_P (mode, GET_MODE (x))
-                    && GET_MODE_CLASS (GET_MODE (x)) != MODE_COMPLEX_INT
-                    && GET_MODE_CLASS (GET_MODE (x)) != MODE_COMPLEX_FLOAT
-                    && (TEST_HARD_REG_BIT
-                        (reg_class_contents[(int) CLASS_CANNOT_CHANGE_MODE],
-                         REGNO (x))))
-#endif
-              /* We want to keep the stack, frame, and arg pointers
-                 special.  */
-              && x != frame_pointer_rtx
-#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
-              && x != arg_pointer_rtx
-#endif
-              && x != stack_pointer_rtx)
-           return gen_rtx_REG (mode, final_regno);
-         }
-      return gen_rtx_SUBREG (mode, x, offset);
-    }
+  else if (GET_CODE (x) == SUBREG || GET_CODE (x) == REG || GET_CODE (x) == CONCAT)
+    return simplify_gen_subreg (mode, x, GET_MODE (x), offset);
   /* If X is a CONST_INT or a CONST_DOUBLE, extract the appropriate bits
      from the low-order part of the constant.  */
   else if ((GET_MODE_CLASS (mode) == MODE_INT
@@ -1088,12 +1016,10 @@ gen_realpart (mode, x)
      enum machine_mode mode;
      register rtx x;
 {
-  if (GET_CODE (x) == CONCAT && GET_MODE (XEXP (x, 0)) == mode)
-    return XEXP (x, 0);
-  else if (WORDS_BIG_ENDIAN
-          && GET_MODE_BITSIZE (mode) < BITS_PER_WORD
-          && REG_P (x)
-          && REGNO (x) < FIRST_PSEUDO_REGISTER)
+  if (WORDS_BIG_ENDIAN
+      && GET_MODE_BITSIZE (mode) < BITS_PER_WORD
+      && REG_P (x)
+      && REGNO (x) < FIRST_PSEUDO_REGISTER)
     internal_error
       ("Can't access real part of complex value in hard register");
   else if (WORDS_BIG_ENDIAN)
@@ -1110,9 +1036,7 @@ gen_imagpart (mode, x)
      enum machine_mode mode;
      register rtx x;
 {
-  if (GET_CODE (x) == CONCAT && GET_MODE (XEXP (x, 0)) == mode)
-    return XEXP (x, 1);
-  else if (WORDS_BIG_ENDIAN)
+  if (WORDS_BIG_ENDIAN)
     return gen_lowpart (mode, x);
   else if (! WORDS_BIG_ENDIAN
           && GET_MODE_BITSIZE (mode) < BITS_PER_WORD
@@ -1195,109 +1119,62 @@ gen_highpart (mode, x)
      register rtx x;
 {
   unsigned int msize = GET_MODE_SIZE (mode);
-  unsigned int xsize = GET_MODE_SIZE (GET_MODE (x));
+  rtx result;
 
   /* This case loses if X is a subreg.  To catch bugs early,
      complain if an invalid MODE is used even in other cases.  */
   if (msize > UNITS_PER_WORD
       && msize != GET_MODE_UNIT_SIZE (GET_MODE (x)))
     abort ();
-  if (GET_CODE (x) == CONST_DOUBLE
-#if !(TARGET_FLOAT_FORMAT != HOST_FLOAT_FORMAT || defined (REAL_IS_NOT_DOUBLE))
-      && GET_MODE_CLASS (GET_MODE (x)) != MODE_FLOAT
-#endif
-      )
-    return GEN_INT (CONST_DOUBLE_HIGH (x) & GET_MODE_MASK (mode));
-  else if (GET_CODE (x) == CONST_INT)
-    {
-      if (HOST_BITS_PER_WIDE_INT <= BITS_PER_WORD)
-       return const0_rtx;
-      return GEN_INT (INTVAL (x) >> (HOST_BITS_PER_WIDE_INT - BITS_PER_WORD));
-    }
-  else if (GET_CODE (x) == MEM)
-    {
-      register int offset = 0;
 
-      if (! WORDS_BIG_ENDIAN)
-       offset = (MAX (xsize, UNITS_PER_WORD)
-                 - MAX (msize, UNITS_PER_WORD));
+  result = simplify_gen_subreg (mode, x, GET_MODE (x),
+                               subreg_highpart_offset (mode, GET_MODE (x)));
+  if (!result)
+    abort ();
+  return result;
+}
+/* Return offset in bytes to get OUTERMODE low part
+   of the value in mode INNERMODE stored in memory in target format.  */
 
-      if (! BYTES_BIG_ENDIAN
-         && msize < UNITS_PER_WORD)
-       offset -= (msize - MIN (UNITS_PER_WORD, xsize));
+unsigned int
+subreg_lowpart_offset (outermode, innermode)
+     enum machine_mode outermode, innermode;
+{
+  unsigned int offset = 0;
+  int difference = (GET_MODE_SIZE (innermode) - GET_MODE_SIZE (outermode));
 
-      return change_address (x, mode, plus_constant (XEXP (x, 0), offset));
-    }
-  else if (GET_CODE (x) == SUBREG)
+  if (difference > 0)
     {
-      /* The only time this should occur is when we are looking at a
-        multi-word item with a SUBREG whose mode is the same as that of the
-        item.  It isn't clear what we would do if it wasn't.  */
-      if (SUBREG_BYTE (x) != 0)
-       abort ();
-      return gen_highpart (mode, SUBREG_REG (x));
+      if (WORDS_BIG_ENDIAN)
+       offset += (difference / UNITS_PER_WORD) * UNITS_PER_WORD;
+      if (BYTES_BIG_ENDIAN)
+       offset += difference % UNITS_PER_WORD;
     }
-  else if (GET_CODE (x) == REG)
-    {
-      int offset = 0;
-
-      if (GET_MODE_SIZE (GET_MODE (x)) < GET_MODE_SIZE (mode))
-       abort ();
-
-      if ((! WORDS_BIG_ENDIAN || ! BYTES_BIG_ENDIAN)
-         && xsize > msize)
-       {
-         int difference = xsize - msize;
 
-         if (! WORDS_BIG_ENDIAN)
-           offset += (difference / UNITS_PER_WORD) * UNITS_PER_WORD;
-         if (! BYTES_BIG_ENDIAN)
-           offset += difference % UNITS_PER_WORD;
-       }
-      if (REGNO (x) < FIRST_PSEUDO_REGISTER)
-       {
-         int final_regno = REGNO (x) +
-           subreg_regno_offset (REGNO (x), GET_MODE (x), offset, mode);
-
-         /* integrate.c can't handle parts of a return value register.
-            ??? Then integrate.c should be fixed!
-            ??? What about CLASS_CANNOT_CHANGE_SIZE?  */
-         if ((! REG_FUNCTION_VALUE_P (x)
-              || ! rtx_equal_function_value_matters)
-         /* We want to keep the stack, frame, and arg pointers special.  */
-             && x != frame_pointer_rtx
-#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM 
-             && x != arg_pointer_rtx
-#endif
-             && x != stack_pointer_rtx)
-           return gen_rtx_REG (mode, final_regno);
-       }
-      /* Just generate a normal SUBREG.  */
-      return gen_rtx_SUBREG (mode, x, offset); 
-    }
-  else
-    abort ();
+  return offset;
 }
-/* Return 1 iff (SUBREG:outermode (OP:innermode) byte)
-   refers to the least significant part of its containing reg.  */
 
-int
-subreg_lowpart_parts_p (outermode, innermode, byte)
+/* Return offset in bytes to get OUTERMODE high part
+   of the value in mode INNERMODE stored in memory in target format.  */
+unsigned int
+subreg_highpart_offset (outermode, innermode)
      enum machine_mode outermode, innermode;
-     unsigned int byte;
 {
   unsigned int offset = 0;
   int difference = (GET_MODE_SIZE (innermode) - GET_MODE_SIZE (outermode));
 
+  if (GET_MODE_SIZE (innermode) < GET_MODE_SIZE (outermode))
+     abort ();
+
   if (difference > 0)
     {
-      if (WORDS_BIG_ENDIAN)
+      if (WORDS_BIG_ENDIAN)
        offset += (difference / UNITS_PER_WORD) * UNITS_PER_WORD;
-      if (BYTES_BIG_ENDIAN)
+      if (BYTES_BIG_ENDIAN)
        offset += difference % UNITS_PER_WORD;
     }
 
-  return byte == offset;
+  return offset;
 }
 
 /* Return 1 iff X, assumed to be a SUBREG,
@@ -1313,8 +1190,8 @@ subreg_lowpart_p (x)
   else if (GET_MODE (SUBREG_REG (x)) == VOIDmode)
     return 0;
 
-  return subreg_lowpart_parts_p (GET_MODE (x), GET_MODE (SUBREG_REG (x)),
-                                SUBREG_BYTE (x));
+  return (subreg_lowpart_offset (GET_MODE (x), GET_MODE (SUBREG_REG (x)))
+         == SUBREG_BYTE (x));
 }
 \f
 
index 648aa13..1cc0d73 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1198,9 +1198,10 @@ extern rtx constant_subword              PARAMS ((rtx, int,
 extern rtx operand_subword_force       PARAMS ((rtx, unsigned int,
                                                 enum machine_mode));
 extern int subreg_lowpart_p            PARAMS ((rtx));
-extern int subreg_lowpart_parts_p      PARAMS ((enum machine_mode,
-                                                enum machine_mode,
-                                                unsigned int));
+extern unsigned int subreg_lowpart_offset PARAMS ((enum machine_mode,
+                                                  enum machine_mode));
+extern unsigned int subreg_highpart_offset PARAMS ((enum machine_mode,
+                                                   enum machine_mode));
 extern rtx make_safe_from              PARAMS ((rtx, rtx));
 extern rtx convert_memory_address      PARAMS ((enum machine_mode, rtx));
 extern rtx get_insns                   PARAMS ((void));
index af0f81f..0f0f6cd 100644 (file)
@@ -2258,40 +2258,9 @@ replace_regs (x, reg_map, nregs, replace_dest)
          && GET_CODE (reg_map[REGNO (SUBREG_REG (x))]) == SUBREG)
        {
          rtx map_val = reg_map[REGNO (SUBREG_REG (x))];
-         rtx map_inner = SUBREG_REG (map_val);
-
-         if (GET_MODE (x) == GET_MODE (map_inner))
-           return map_inner;
-         else
-           {
-             int final_offset = SUBREG_BYTE (x) + SUBREG_BYTE (map_val);
-
-             /* When working with REG SUBREGs the rule is that the byte
-                offset must be a multiple of the SUBREG's mode.  */
-             final_offset = (final_offset / GET_MODE_SIZE (GET_MODE (x)));
-             final_offset = (final_offset * GET_MODE_SIZE (GET_MODE (x)));
-
-             /* We cannot call gen_rtx here since we may be linked with
-                genattrtab.c.  */
-             /* Let's try clobbering the incoming SUBREG and see
-                if this is really safe.  */
-             SUBREG_REG (x) = map_inner;
-             SUBREG_BYTE (x) = final_offset;
-             return x;
-#if 0
-             rtx new = rtx_alloc (SUBREG);
-             int final_offset = SUBREG_BYTE (x) + SUBREG_BYTE (map_val);
-
-             /* When working with REG SUBREGs the rule is that the byte
-                offset must be a multiple of the SUBREG's mode.  */
-             final_offset = (final_offset / GET_MODE_SIZE (GET_MODE (x)));
-             final_offset = (final_offset * GET_MODE_SIZE (GET_MODE (x)));
-
-             PUT_MODE (new, GET_MODE (x));
-             SUBREG_REG (new) = map_inner;
-             SUBREG_BYTE (new) = final_offset;
-#endif
-           }
+         return simplify_gen_subreg (GET_MODE (x), map_val,
+                                     GET_MODE (SUBREG_REG (x)), 
+                                     SUBREG_BYTE (x));
        }
       break;
 
index 621bd90..aef9b55 100644 (file)
@@ -2215,7 +2215,7 @@ simplify_subreg (outermode, op, innermode, byte)
         Later it we should move all simplification code here and rewrite
         GEN_LOWPART_IF_POSSIBLE, GEN_HIGHPART, OPERAND_SUBWORD and friends
         using SIMPLIFY_SUBREG.  */
-      if (subreg_lowpart_parts_p (outermode, innermode, byte))
+      if (subreg_lowpart_offset (outermode, innermode) == byte)
        {
          rtx new = gen_lowpart_if_possible (outermode, op);
          if (new)
@@ -2347,11 +2347,23 @@ simplify_subreg (outermode, op, innermode, byte)
      frame, or argument pointer, leave this as a SUBREG.  */
 
   if (REG_P (op)
+      && (! REG_FUNCTION_VALUE_P (op)
+         || ! rtx_equal_function_value_matters)
+#ifdef CLASS_CANNOT_CHANGE_MODE
+      && ! (CLASS_CANNOT_CHANGE_MODE_P (outermode, innermode)
+           && GET_MODE_CLASS (innermode) != MODE_COMPLEX_INT
+           && GET_MODE_CLASS (innermode) != MODE_COMPLEX_FLOAT
+           && (TEST_HARD_REG_BIT
+               (reg_class_contents[(int) CLASS_CANNOT_CHANGE_MODE],
+                REGNO (op))))
+#endif
       && REGNO (op) < FIRST_PSEUDO_REGISTER
-      && REGNO (op) != FRAME_POINTER_REGNUM
+      && ((reload_completed && !frame_pointer_needed)
+         || (REGNO (op) != FRAME_POINTER_REGNUM
 #if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
-      && REGNO (op) != HARD_FRAME_POINTER_REGNUM
+             && REGNO (op) != HARD_FRAME_POINTER_REGNUM
 #endif
+            ))
 #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
       && REGNO (op) != ARG_POINTER_REGNUM
 #endif
@@ -2360,7 +2372,11 @@ simplify_subreg (outermode, op, innermode, byte)
       int final_regno = subreg_hard_regno (gen_rtx_SUBREG (outermode, op, byte),
                                           0);
 
-      if (HARD_REGNO_MODE_OK (final_regno, outermode))
+      /* ??? We do allow it if the current REG is not valid for
+        its mode.  This is a kludge to work around how float/complex
+        arguments are passed on 32-bit Sparc and should be fixed.  */
+      if (HARD_REGNO_MODE_OK (final_regno, outermode)
+         || ! HARD_REGNO_MODE_OK (REGNO (op), innermode))
        return gen_rtx_REG (outermode, final_regno);
     }