All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Alex Bennée" <alex.bennee@linaro.org>
To: qemu-devel@nongnu.org
Cc: cota@braap.org, "Alex Bennée" <alex.bennee@linaro.org>
Subject: [RFC PATCH 6/8] int128.h: add bunch of uint128 utility functions (INCOMPLETE)
Date: Tue, 20 Oct 2020 17:37:36 +0100	[thread overview]
Message-ID: <20201020163738.27700-7-alex.bennee@linaro.org> (raw)
In-Reply-To: <20201020163738.27700-1-alex.bennee@linaro.org>

These will be useful for softfloat. I've included the extract/desposit
functions with the main Int128 header and not with cutils as we need
alternate versions for systems that don't have compiler support for
Uint128. Even with compiler support some stuff we need to
hand-hack (like clz128).

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
---
 include/qemu/int128.h | 122 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 122 insertions(+)

diff --git a/include/qemu/int128.h b/include/qemu/int128.h
index 76ea405922..38c8b1ab29 100644
--- a/include/qemu/int128.h
+++ b/include/qemu/int128.h
@@ -3,8 +3,10 @@
 
 #ifdef CONFIG_INT128
 #include "qemu/bswap.h"
+#include "qemu/host-utils.h"
 
 typedef __int128_t Int128;
+typedef __uint128_t Uint128;
 
 static inline Int128 int128_make64(uint64_t a)
 {
@@ -16,6 +18,11 @@ static inline Int128 int128_make128(uint64_t lo, uint64_t hi)
     return (__uint128_t)hi << 64 | lo;
 }
 
+static inline Uint128 uint128_make128(uint64_t lo, uint64_t hi)
+{
+    return (__uint128_t)hi << 64 | lo;
+}
+
 static inline uint64_t int128_get64(Int128 a)
 {
     uint64_t r = a;
@@ -28,16 +35,31 @@ static inline uint64_t int128_getlo(Int128 a)
     return a;
 }
 
+static inline uint64_t uint128_getlo(Uint128 a)
+{
+    return a;
+}
+
 static inline int64_t int128_gethi(Int128 a)
 {
     return a >> 64;
 }
 
+static inline uint64_t uint128_gethi(Uint128 a)
+{
+    return a >> 64;
+}
+
 static inline Int128 int128_zero(void)
 {
     return 0;
 }
 
+static inline Uint128 uint128_zero(void)
+{
+    return 0;
+}
+
 static inline Int128 int128_one(void)
 {
     return 1;
@@ -58,21 +80,51 @@ static inline Int128 int128_and(Int128 a, Int128 b)
     return a & b;
 }
 
+static inline Uint128 uint128_and(Uint128 a, Uint128 b)
+{
+    return a & b;
+}
+
+static inline Int128 int128_or(Int128 a, Int128 b)
+{
+    return a | b;
+}
+
+static inline Uint128 uint128_or(Uint128 a, Uint128 b)
+{
+    return a | b;
+}
+
 static inline Int128 int128_rshift(Int128 a, int n)
 {
     return a >> n;
 }
 
+static inline Uint128 uint128_rshift(Uint128 a, int n)
+{
+    return a >> n;
+}
+
 static inline Int128 int128_lshift(Int128 a, int n)
 {
     return a << n;
 }
 
+static inline Uint128 uint128_lshift(Uint128 a, int n)
+{
+    return a << n;
+}
+
 static inline Int128 int128_add(Int128 a, Int128 b)
 {
     return a + b;
 }
 
+static inline Uint128 uint128_add(Uint128 a, Uint128 b)
+{
+    return a + b;
+}
+
 static inline Int128 int128_neg(Int128 a)
 {
     return -a;
@@ -83,6 +135,11 @@ static inline Int128 int128_sub(Int128 a, Int128 b)
     return a - b;
 }
 
+static inline Uint128 uint128_sub(Uint128 a, Uint128 b)
+{
+    return a - b;
+}
+
 static inline bool int128_nonneg(Int128 a)
 {
     return a >= 0;
@@ -93,6 +150,11 @@ static inline bool int128_eq(Int128 a, Int128 b)
     return a == b;
 }
 
+static inline bool uint128_eq(Uint128 a, Uint128 b)
+{
+    return a == b;
+}
+
 static inline bool int128_ne(Int128 a, Int128 b)
 {
     return a != b;
@@ -148,6 +210,66 @@ static inline Int128 bswap128(Int128 a)
     return int128_make128(bswap64(int128_gethi(a)), bswap64(int128_getlo(a)));
 }
 
+/**
+ * extract128:
+ * @value: the value to extract the bit field from
+ * @start: the lowest bit in the bit field (numbered from 0)
+ * @length: the length of the bit field
+ *
+ * Extract from the 128 bit input @value the bit field specified by the
+ * @start and @length parameters, and return it. The bit field must
+ * lie entirely within the 128 bit word. It is valid to request that
+ * all 128 bits are returned (ie @length 128 and @start 0).
+ *
+ * Returns: the value of the bit field extracted from the input value.
+ */
+static inline Uint128 extract128(Uint128 value, int start, int length)
+{
+    assert(start >= 0 && length > 0 && length <= 128 - start);
+    Uint128 mask = ~(Uint128)0 >> (128 - length);
+    Uint128 shifted = value >> start;
+    return shifted & mask;
+}
+
+/**
+ * deposit128:
+ * @value: initial value to insert bit field into
+ * @start: the lowest bit in the bit field (numbered from 0)
+ * @length: the length of the bit field
+ * @fieldval: the value to insert into the bit field
+ *
+ * Deposit @fieldval into the 128 bit @value at the bit field specified
+ * by the @start and @length parameters, and return the modified
+ * @value. Bits of @value outside the bit field are not modified.
+ * Bits of @fieldval above the least significant @length bits are
+ * ignored. The bit field must lie entirely within the 128 bit word.
+ * It is valid to request that all 128 bits are modified (ie @length
+ * 128 and @start 0).
+ *
+ * Returns: the modified @value.
+ */
+static inline Uint128 deposit128(Uint128 value, int start, int length,
+                                 Uint128 fieldval)
+{
+    assert(start >= 0 && length > 0 && length <= 128 - start);
+    Uint128 mask = (~(Uint128)0 >> (128 - length)) << start;
+    return (value & ~mask) | ((fieldval << start) & mask);
+}
+
+static inline int clz128(Uint128 val)
+{
+    if (val) {
+        uint64_t hi = uint128_gethi(val);
+        if (hi) {
+            return clz64(hi);
+        } else {
+            return 64 + clz64(uint128_getlo(val));
+        }
+    } else {
+        return 128;
+    }
+}
+
 #else /* !CONFIG_INT128 */
 
 typedef struct Int128 Int128;
-- 
2.20.1



  parent reply	other threads:[~2020-10-20 16:40 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-10-20 16:37 [RFC PATCH 0/8] fpu: experimental conversion of float128_addsub Alex Bennée
2020-10-20 16:37 ` [RFC PATCH 1/8] softfloat: Use mulu64 for mul64To128 Alex Bennée
2020-10-20 16:37 ` [RFC PATCH 2/8] softfloat: Use int128.h for some operations Alex Bennée
2020-10-20 16:37 ` [RFC PATCH 3/8] softfloat: Tidy a * b + inf return Alex Bennée
2020-10-20 16:37 ` [RFC PATCH 4/8] softfloat: Add float_cmask and constants Alex Bennée
2020-10-20 16:37 ` [RFC PATCH 5/8] softfloat: Inline pick_nan_muladd into its caller Alex Bennée
2020-10-20 16:37 ` Alex Bennée [this message]
2020-10-20 16:37 ` [RFC PATCH 7/8] tests/fp: add quad support to the benchmark utility Alex Bennée
2020-10-20 16:37 ` [RFC PATCH 8/8] softfloat: implement addsub_floats128 using Uint128 and new style code Alex Bennée
2020-10-20 18:49   ` Richard Henderson
2020-10-20 17:03 ` [RFC PATCH 0/8] fpu: experimental conversion of float128_addsub no-reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201020163738.27700-7-alex.bennee@linaro.org \
    --to=alex.bennee@linaro.org \
    --cc=cota@braap.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.