14 #include "gu_byteswap.h"
18 #if defined(__SIZEOF_INT128__)
20 typedef int __attribute__((__mode__(__TI__))) int128_t;
21 typedef
unsigned int __attribute__((__mode__(__TI__))) uint128_t;
26 #define GU_SET128(_a, hi64, lo64) _a = (((uint128_t)hi64) << 64) + lo64
27 #define GU_MUL128_INPLACE(_a, _b) _a *= _b
28 #define GU_IMUL128_INPLACE(_a, _b) GU_MUL128_INPLACE(_a, _b)
29 #define GU_EQ128(_a, _b) (_a == _b)
33 #if defined(GU_LITTLE_ENDIAN)
47 struct {uint32_t lo; uint64_t mid; int32_t hi;}__attribute__((packed)) m;
50 gu_int128(int64_t hi, uint64_t lo) : m() { u64[0] = lo; u64[1] = hi; }
57 struct {uint32_t lo; uint64_t mid; uint32_t hi;}__attribute__((packed)) m;
60 gu_uint128(uint64_t hi, uint64_t lo) : m() { u64[0] = lo; u64[1] = hi; }
65 #define GU_SET128(_a, hi64, lo64) _a = gu_uint128(hi64, lo64)
67 #define GU_SET128(_a, hi64, lo64) _a = { .u64 = { lo64, hi64 } }
70 #define GU_MUL128_INPLACE(_a,_b) { \
71 uint64_t m00 = (uint64_t)(_a).u32[0] * (_b).u32[0]; \
72 uint64_t m10 = (uint64_t)(_a).u32[1] * (_b).u32[0]; \
73 uint64_t m20 = (uint64_t)(_a).u32[2] * (_b).u32[0]; \
74 uint64_t m01 = (uint64_t)(_a).u32[0] * (_b).u32[1]; \
75 uint64_t m02 = (uint64_t)(_a).u32[0] * (_b).u32[2]; \
76 uint64_t m11 = (uint64_t)(_a).u32[1] * (_b).u32[1]; \
77 uint32_t m30 = (_a).u32[3] * (_b).u32[0]; \
78 uint32_t m21 = (_a).u32[2] * (_b).u32[1]; \
79 uint32_t m12 = (_a).u32[1] * (_b).u32[2]; \
80 uint32_t m03 = (_a).u32[0] * (_b).u32[3]; \
81 (_a).u64[GU_64LO] = m00; (_a).u64[GU_64HI] = 0; \
82 (_a).m.mid += m10; (_a).m.hi += ((_a).m.mid < m10); \
83 (_a).m.mid += m01; (_a).m.hi += ((_a).m.mid < m01); \
84 (_a).u64[GU_64HI] += m20 + m11 + m02; \
85 (_a).u32[GU_32HI] += m30 + m21 + m12 + m03; \
98 struct {int32_t hi; uint64_t mid; uint32_t lo;}__attribute__((packed)) m;
101 gu_int128(int64_t hi, uint64_t lo) { u64[0] = hi; u64[1] = lo; }
108 struct {uint32_t hi; uint64_t mid; uint32_t lo;}__attribute__((packed)) m;
111 gu_uint128(uint64_t hi, uint64_t lo) { u64[0] = hi; u64[1] = lo; }
116 #define GU_SET128(_a, hi64, lo64) _a = gu_uint128(hi64, lo64)
118 #define GU_SET128(_a, hi64, lo64) _a = { .u64 = { hi64, lo64 } }
121 #define GU_MUL128_INPLACE(_a,_b) { \
122 uint64_t m33 = (uint64_t)_a.u32[3] * _b.u32[3]; \
123 uint64_t m23 = (uint64_t)_a.u32[2] * _b.u32[3]; \
124 uint64_t m13 = (uint64_t)_a.u32[1] * _b.u32[3]; \
125 uint64_t m32 = (uint64_t)_a.u32[3] * _b.u32[2]; \
126 uint64_t m31 = (uint64_t)_a.u32[3] * _b.u32[1]; \
127 uint64_t m22 = (uint64_t)_a.u32[2] * _b.u32[2]; \
128 uint32_t m30 = _a.u32[3] * _b.u32[0]; \
129 uint32_t m21 = _a.u32[2] * _b.u32[1]; \
130 uint32_t m12 = _a.u32[1] * _b.u32[2]; \
131 uint32_t m03 = _a.u32[0] * _b.u32[3]; \
132 _a.u64[GU_64LO] = m00; _a.u64[GU_64HI] = 0; \
133 _a.m.mid += m23; _a.m.hi += (_a.m.mid < m23); \
134 _a.m.mid += m32; _a.m.hi += (_a.m.mid < m32); \
135 _a.u64[GU_64HI] += m13 + m22 + m31; \
136 _a.u32[GU_32HI] += m30 + m21 + m12 + m03; \
141 #define GU_IMUL128_INPLACE(_a, _b) { \
142 uint32_t sign = ((_a).u32[GU_32HI] ^ (_b).u32[GU_32HI]) & 0x80000000UL; \
143 GU_MUL128_INPLACE (_a, _b); \
144 (_a).u32[GU_32HI] |= sign; \
147 #define GU_EQ128(_a, _b) (!memcmp(&_a,&_b,sizeof(_a)))
160 gu_bswap128 (gu_uint128_t*
const arg)
162 uint64_t* x = (uint64_t*)arg;
163 uint64_t tmp = gu_bswap64(x[0]);
164 x[0] = gu_bswap64(x[1]);
172 #ifdef GU_LITTLE_ENDIAN
173 # define gu_le128(x) {}
174 # define gu_be128(x) gu_bswap128(x)
176 # define gu_le128(x) gu_bswap128(x)
177 # define gu_be128(x) {}
180 #define htog128(x) gu_le128(x)
181 #define gtoh128(x) htog128(x)
Definition: gu_int128.h:105
Definition: gu_int128.h:95