[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[RFC PATCH 6/8] int128.h: add bunch of uint128 utility functions (INCOMP
From: |
Alex Bennée |
Subject: |
[RFC PATCH 6/8] int128.h: add bunch of uint128 utility functions (INCOMPLETE) |
Date: |
Tue, 20 Oct 2020 17:37:36 +0100 |
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
- [RFC PATCH 0/8] fpu: experimental conversion of float128_addsub, Alex Bennée, 2020/10/20
- [RFC PATCH 1/8] softfloat: Use mulu64 for mul64To128, Alex Bennée, 2020/10/20
- [RFC PATCH 2/8] softfloat: Use int128.h for some operations, Alex Bennée, 2020/10/20
- [RFC PATCH 3/8] softfloat: Tidy a * b + inf return, Alex Bennée, 2020/10/20
- [RFC PATCH 4/8] softfloat: Add float_cmask and constants, Alex Bennée, 2020/10/20
- [RFC PATCH 7/8] tests/fp: add quad support to the benchmark utility, Alex Bennée, 2020/10/20
- [RFC PATCH 6/8] int128.h: add bunch of uint128 utility functions (INCOMPLETE),
Alex Bennée <=
- [RFC PATCH 8/8] softfloat: implement addsub_floats128 using Uint128 and new style code, Alex Bennée, 2020/10/20
- [RFC PATCH 5/8] softfloat: Inline pick_nan_muladd into its caller, Alex Bennée, 2020/10/20
- Re: [RFC PATCH 0/8] fpu: experimental conversion of float128_addsub, no-reply, 2020/10/20