public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r14-1548] New wi::bitreverse function.
@ 2023-06-05 16:29 Roger Sayle
  0 siblings, 0 replies; only message in thread
From: Roger Sayle @ 2023-06-05 16:29 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:108ff03bac3c440db792fcc61d6247e75b56a572

commit r14-1548-g108ff03bac3c440db792fcc61d6247e75b56a572
Author: Roger Sayle <roger@nextmovesoftware.com>
Date:   Mon Jun 5 17:28:51 2023 +0100

    New wi::bitreverse function.
    
    This patch provides a wide-int implementation of bitreverse, that
    implements both of Richard Sandiford's suggestions from the review at
    https://gcc.gnu.org/pipermail/gcc-patches/2023-May/618215.html of an
    improved API (as a stand-alone function matching the bswap refactoring),
    and an implementation that works with any bit-width precision.
    
    2023-06-05  Roger Sayle  <roger@nextmovesoftware.com>
    
    gcc/ChangeLog
            * wide-int.cc (wi::bitreverse_large): New function implementing
            bit reversal of an integer.
            * wide-int.h (wi::bitreverse): New (template) function prototype.
            (bitreverse_large): Prototype helper function/implementation.
            (wi::bitreverse): New template wrapper around bitreverse_large.

Diff:
---
 gcc/wide-int.cc | 27 +++++++++++++++++++++++++++
 gcc/wide-int.h  | 15 +++++++++++++++
 2 files changed, 42 insertions(+)

diff --git a/gcc/wide-int.cc b/gcc/wide-int.cc
index 1e4c0460b74..24bdce2a656 100644
--- a/gcc/wide-int.cc
+++ b/gcc/wide-int.cc
@@ -766,6 +766,33 @@ wi::bswap_large (HOST_WIDE_INT *val, const HOST_WIDE_INT *xval,
   return canonize (val, len, precision);
 }
 
+/* Bitreverse the integer represented by XVAL and LEN into VAL.  Return
+   the number of blocks in VAL.  Both XVAL and VAL have PRECISION bits.  */
+unsigned int
+wi::bitreverse_large (HOST_WIDE_INT *val, const HOST_WIDE_INT *xval,
+		      unsigned int len, unsigned int precision)
+{
+  unsigned int i, s;
+
+  for (i = 0; i < len; i++)
+    val[i] = 0;
+
+  for (s = 0; s < precision; s++)
+    {
+      unsigned int block = s / HOST_BITS_PER_WIDE_INT;
+      unsigned int offset = s & (HOST_BITS_PER_WIDE_INT - 1);
+      if (((safe_uhwi (xval, len, block) >> offset) & 1) != 0)
+	{
+	  unsigned int d = (precision - 1) - s;
+	  block = d / HOST_BITS_PER_WIDE_INT;
+	  offset = d & (HOST_BITS_PER_WIDE_INT - 1);
+          val[block] |= 1 << offset;
+	}
+    }
+
+  return canonize (val, len, precision);
+}
+
 /* Fill VAL with a mask where the lower WIDTH bits are ones and the bits
    above that up to PREC are zeros.  The result is inverted if NEGATE
    is true.  Return the number of blocks in VAL.  */
diff --git a/gcc/wide-int.h b/gcc/wide-int.h
index e4723adce2c..498d14d188e 100644
--- a/gcc/wide-int.h
+++ b/gcc/wide-int.h
@@ -553,6 +553,7 @@ namespace wi
   UNARY_FUNCTION zext (const T &, unsigned int);
   UNARY_FUNCTION set_bit (const T &, unsigned int);
   UNARY_FUNCTION bswap (const T &);
+  UNARY_FUNCTION bitreverse (const T &);
 
   BINARY_FUNCTION min (const T1 &, const T2 &, signop);
   BINARY_FUNCTION smin (const T1 &, const T2 &);
@@ -1748,6 +1749,8 @@ namespace wi
 			      unsigned int, unsigned int, unsigned int);
   unsigned int bswap_large (HOST_WIDE_INT *, const HOST_WIDE_INT *,
 			    unsigned int, unsigned int);
+  unsigned int bitreverse_large (HOST_WIDE_INT *, const HOST_WIDE_INT *,
+				 unsigned int, unsigned int);
   
   unsigned int lshift_large (HOST_WIDE_INT *, const HOST_WIDE_INT *,
 			     unsigned int, unsigned int, unsigned int);
@@ -2281,6 +2284,18 @@ wi::bswap (const T &x)
   return result;
 }
 
+/* Bitreverse the integer X.  */
+template <typename T>
+inline WI_UNARY_RESULT (T)
+wi::bitreverse (const T &x)
+{
+  WI_UNARY_RESULT_VAR (result, val, T, x);
+  unsigned int precision = get_precision (result);
+  WIDE_INT_REF_FOR (T) xi (x, precision);
+  result.set_len (bitreverse_large (val, xi.val, xi.len, precision));
+  return result;
+}
+
 /* Return the mininum of X and Y, treating them both as having
    signedness SGN.  */
 template <typename T1, typename T2>

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-06-05 16:29 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-06-05 16:29 [gcc r14-1548] New wi::bitreverse function Roger Sayle

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).