https://gcc.gnu.org/g:ef32bd8c866a1b8a97f627fad44a42f29757c816

commit r16-195-gef32bd8c866a1b8a97f627fad44a42f29757c816
Author: Richard Sandiford <richard.sandif...@arm.com>
Date:   Mon Apr 28 14:40:09 2025 +0100

    simplify-rtx: Split out native_decode_int
    
    native_decode_rtx handles integer modes by building up a wide_int
    and then converting it to an rtx.  This patch splits out the
    wide_int part, so that callers who don't want an rtx can avoid
    creating garbage rtl.
    
    gcc/
            * rtl.h (native_decode_int): Declare.
            * simplify-rtx.cc (native_decode_int): New function, split out 
from...
            (native_decode_rtx): ...here.

Diff:
---
 gcc/rtl.h           |  2 ++
 gcc/simplify-rtx.cc | 38 +++++++++++++++++++++++++-------------
 2 files changed, 27 insertions(+), 13 deletions(-)

diff --git a/gcc/rtl.h b/gcc/rtl.h
index 3b676c468805..cc25aed1f494 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -2443,6 +2443,8 @@ extern void get_full_rtx_cost (rtx, machine_mode, enum 
rtx_code, int,
                               struct full_rtx_costs *);
 extern bool native_encode_rtx (machine_mode, rtx, vec<target_unit> &,
                               unsigned int, unsigned int);
+extern wide_int native_decode_int (const vec<target_unit> &, unsigned int,
+                                  unsigned int, unsigned int);
 extern rtx native_decode_rtx (machine_mode, const vec<target_unit> &,
                              unsigned int);
 extern rtx native_decode_vector_rtx (machine_mode, const vec<target_unit> &,
diff --git a/gcc/simplify-rtx.cc b/gcc/simplify-rtx.cc
index 06b52ca80037..d9aa0493a186 100644
--- a/gcc/simplify-rtx.cc
+++ b/gcc/simplify-rtx.cc
@@ -7713,6 +7713,28 @@ native_decode_vector_rtx (machine_mode mode, const 
vec<target_unit> &bytes,
   return builder.build ();
 }
 
+/* Extract a PRECISION-bit integer from bytes [FIRST_BYTE, FIRST_BYTE + SIZE)
+   of target memory image BYTES.  */
+
+wide_int
+native_decode_int (const vec<target_unit> &bytes, unsigned int first_byte,
+                  unsigned int size, unsigned int precision)
+{
+  /* Pull the bytes msb first, so that we can use simple
+     shift-and-insert wide_int operations.  */
+  wide_int result (wi::zero (precision));
+  for (unsigned int i = 0; i < size; ++i)
+    {
+      unsigned int lsb = (size - i - 1) * BITS_PER_UNIT;
+      /* Always constant because the inputs are.  */
+      unsigned int subbyte
+       = subreg_size_offset_from_lsb (1, size, lsb).to_constant ();
+      result <<= BITS_PER_UNIT;
+      result |= bytes[first_byte + subbyte];
+    }
+  return result;
+}
+
 /* Read an rtx of mode MODE from the target memory image given by BYTES,
    starting at byte FIRST_BYTE.  Each element of BYTES contains BITS_PER_UNIT
    bits and the bytes are in target memory order.  The image has enough
@@ -7738,19 +7760,9 @@ native_decode_rtx (machine_mode mode, const 
vec<target_unit> &bytes,
   if (is_a <scalar_int_mode> (mode, &imode)
       && GET_MODE_PRECISION (imode) <= MAX_BITSIZE_MODE_ANY_INT)
     {
-      /* Pull the bytes msb first, so that we can use simple
-        shift-and-insert wide_int operations.  */
-      unsigned int size = GET_MODE_SIZE (imode);
-      wide_int result (wi::zero (GET_MODE_PRECISION (imode)));
-      for (unsigned int i = 0; i < size; ++i)
-       {
-         unsigned int lsb = (size - i - 1) * BITS_PER_UNIT;
-         /* Always constant because the inputs are.  */
-         unsigned int subbyte
-           = subreg_size_offset_from_lsb (1, size, lsb).to_constant ();
-         result <<= BITS_PER_UNIT;
-         result |= bytes[first_byte + subbyte];
-       }
+      auto result = native_decode_int (bytes, first_byte,
+                                      GET_MODE_SIZE (imode),
+                                      GET_MODE_PRECISION (imode));
       return immed_wide_int_const (result, imode);
     }

Reply via email to