From 2a93940bff0d86a69e0018924a1d2e33c2cebb4d Mon Sep 17 00:00:00 2001 From: jacob Date: Mon, 24 Feb 2025 08:50:37 -0600 Subject: [PATCH] remove u128 --- src/common.h | 81 ++++------------------------------------------------ src/rng.c | 22 ++++---------- src/rng.h | 2 -- src/sprite.c | 17 ++++++----- src/uid.c | 13 +++++---- src/user.c | 8 +++--- src/util.h | 2 ++ 7 files changed, 32 insertions(+), 113 deletions(-) diff --git a/src/common.h b/src/common.h index a6d45bfe..889ce865 100644 --- a/src/common.h +++ b/src/common.h @@ -370,70 +370,6 @@ GLOBAL const f64 *_f64_nan = (f64 *)&_f64_nan_u64; #define PI ((f32)3.14159265358979323846) #define TAU ((f32)6.28318530717958647693) -/* ========================== * - * Big int - * ========================== */ - -#if COMPILER_CLANG - -#define U128(hi64, lo64) (((u128)(hi64) << 64) | (lo64)) -#define U128_HI(a) ((u64)((a) >> 64)) -#define U128_LO(a) ((u64)(a)) - -typedef __uint128_t u128; - -INLINE b32 u128_eq(u128 a, u128 b) { return a == b; } -INLINE b32 u128_lt(u128 a, u128 b) { return a < b; } -INLINE b32 u128_gt(u128 a, u128 b) { return a > b; } -INLINE u128 u128_xor_u8(u128 a, u8 b) { return a ^ b; } -INLINE u128 u128_mul(u128 a, u128 b) { return a * b; } - -#elif COMPILER_MSVC - -#if LANGUAGE_CPP -# define U128(hi64, lo64) { .hi = (hi64), .lo = (lo64) } -#else -# define U128(hi64, lo64) ((u128) { .hi = (hi64), .lo = (lo64) }) -#endif -#define U128_HI(a) ((a).hi) -#define U128_LO(a) ((a).lo) - -typedef struct { u64 lo; u64 hi; } u128; - -INLINE b32 u128_eq(u128 a, u128 b) { return a.hi == b.hi && a.lo == b.lo; } -INLINE b32 u128_lt(u128 a, u128 b) { return ((((a.hi > b.hi) - (a.hi < b.hi)) << 1) + ((a.lo > b.lo) - (a.lo < b.lo))) < 0; } -INLINE b32 u128_gt(u128 a, u128 b) { return ((((a.hi > b.hi) - (a.hi < b.hi)) << 1) + ((a.lo > b.lo) - (a.lo < b.lo))) > 0; } -INLINE u128 u128_xor_u8(u128 a, u8 b) { return U128(a.hi, a.lo ^ b); } - -/* https://www.codeproject.com/Tips/784635/UInt-Bit-Operations */ - -/* TODO: Use msvc intrinsics & ensure results are identical to clang */ - -INLINE u128 u128_mul(u128 a, u128 b) -{ - u64 a1 = (a.lo & 0xffffffff); - u64 b1 = (b.lo & 0xffffffff); - u64 t = (a1 * b1); - u64 w3 = (t & 0xffffffff); - u64 k = (t >> 32); - - a.lo >>= 32; - t = (a.lo * b1) + k; - k = (t & 0xffffffff); - u64 w1 = (t >> 32); - - b.lo >>= 32; - t = (a1 * b.lo) + k; - k = (t >> 32); - - u128 res = U128((a.lo * b.lo) + w1 + k, (t << 32) + w3); - res.hi += (a.hi * b.lo) + (a.lo * b.hi); - - return res; -} - -#endif - /* ========================== * * Atomics * ========================== */ @@ -487,18 +423,13 @@ struct string32 { u32 *text; }; -#define UID(hi, lo) (struct uid) { .v = U128((hi), (lo)) } +#define UID(hi64, lo64) ((struct uid) { .hi = (hi64), .lo = (lo64) }) struct uid { - union { - u128 v; - struct { - u64 lo; - u64 hi; - }; - }; + u64 hi; + u64 lo; }; -INLINE b32 uid_eq(struct uid a, struct uid b) { return u128_eq(a.v, b.v); } -INLINE b32 uid_is_zero(struct uid uid) { return u128_eq(uid.v, U128(0, 0)); } +INLINE b32 uid_eq(struct uid a, struct uid b) { return a.hi == b.hi && a.lo == b.lo; } +INLINE b32 uid_is_zero(struct uid v) { return v.hi == 0 && v.lo == 0; } struct image_rgba { u32 width; @@ -536,7 +467,7 @@ struct host_channel_id { * ========================== */ struct sprite_tag { - u128 hash; + u64 hash; struct string path; }; diff --git a/src/rng.c b/src/rng.c index 0fcce607..12cc321e 100644 --- a/src/rng.c +++ b/src/rng.c @@ -5,7 +5,7 @@ GLOBAL struct { struct arena arena; - u128 *noise; + u64 *noise; u64 noise_count; } G = ZI, DEBUG_ALIAS(G, G_rng); @@ -25,7 +25,7 @@ INTERNAL void gen_random_file(struct string path, u32 count) } struct sys_file f = sys_file_open_append(path); for (u32 i = 0; i < count; ++i) { - u128 rand = rng_rand_u128(); + u64 rand = rng_rand_u64(); sys_file_write(f, STRING_FROM_STRUCT(&rand)); } sys_file_close(f); @@ -43,8 +43,8 @@ struct rng_startup_receipt rng_startup(struct resource_startup_receipt *resource if (resource_exists(noise_path)) { struct resource r = resource_open(noise_path); G.noise_count = r.data.len / sizeof(*G.noise); - G.arena = arena_alloc(sizeof(u128) * G.noise_count); - G.noise = arena_push_array(&G.arena, u128, G.noise_count); + G.arena = arena_alloc(sizeof(u64) * G.noise_count); + G.noise = arena_push_array(&G.arena, u64, G.noise_count); MEMCPY(G.noise, r.data.text, r.data.len); resource_close(r); } else { @@ -71,13 +71,6 @@ u64 rng_rand_u64(void) return v; } -u128 rng_rand_u128(void) -{ - u128 v = 0; - sys_rand(STRING_FROM_STRUCT(&v)); - return v; -} - f32 rng_rand_f32(f32 range_start, f32 range_end) { return ((f32)rng_rand_u32() / (f32)U32_MAX) * (range_end - range_start) + range_start; @@ -99,15 +92,10 @@ f64 rng_rand_f64(f64 range_start, f64 range_end) u32 rng_noise_u32(u64 seed) { - return (u32)U128_LO(G.noise[seed % G.noise_count]); + return (u32)G.noise[seed % G.noise_count]; } u64 rng_noise_u64(u64 seed) -{ - return U128_LO(G.noise[seed % G.noise_count]); -} - -u128 rng_noise_u128(u64 seed) { return G.noise[seed % G.noise_count]; } diff --git a/src/rng.h b/src/rng.h index 6bfc84f0..7a2abfc7 100644 --- a/src/rng.h +++ b/src/rng.h @@ -10,14 +10,12 @@ struct rng_startup_receipt rng_startup(struct resource_startup_receipt *resource /* Rand */ u32 rng_rand_u32(void); u64 rng_rand_u64(void); -u128 rng_rand_u128(void); f32 rng_rand_f32(f32 range_start, f32 range_end); f64 rng_rand_f64(f64 range_start, f64 range_end); /* Noise */ u32 rng_noise_u32(u64 seed); u64 rng_noise_u64(u64 seed); -u128 rng_noise_u128(u64 seed); f32 rng_noise_f32(u64 seed, f32 range_start, f32 range_end); f32 rng_noise_f64(u64 seed, f64 range_start, f64 range_end); diff --git a/src/sprite.c b/src/sprite.c index 970a8bed..de6c3440 100644 --- a/src/sprite.c +++ b/src/sprite.c @@ -67,7 +67,7 @@ struct cache_node_refcount { CT_ASSERT(sizeof(struct cache_node_refcount) == 8); /* Must fit into 64 bit atomic */ struct cache_node_hash { - u128 v; + u64 v; }; struct cache_node { @@ -286,25 +286,24 @@ INTERNAL APP_EXIT_CALLBACK_FUNC_DEF(sprite_shutdown) struct sprite_tag sprite_tag_from_path(struct string path) { struct sprite_tag res = ZI; - res.hash = HASH_FNV128_BASIS; - res.hash = hash_fnv128(res.hash, path); + res.hash = hash_fnv64(HASH_FNV64_BASIS, path); res.path = path; return res; } b32 sprite_tag_is_nil(struct sprite_tag tag) { - return u128_eq(tag.hash, U128(0, 0)); + return tag.hash == 0; } b32 sprite_tag_eq(struct sprite_tag t1, struct sprite_tag t2) { - return u128_eq(t1.hash, t2.hash); + return t1.hash == t2.hash; } -INTERNAL struct cache_node_hash cache_node_hash_from_tag_hash(u128 tag_hash, enum cache_node_kind kind) +INTERNAL struct cache_node_hash cache_node_hash_from_tag_hash(u64 tag_hash, enum cache_node_kind kind) { - return (struct cache_node_hash) { .v = hash_fnv128(tag_hash, STRING(1, (u8 *)&kind)) }; + return (struct cache_node_hash) { .v = hash_fnv64(tag_hash, STRING(1, (u8 *)&kind)) }; } /* ========================== * @@ -784,7 +783,7 @@ INTERNAL struct cache_node *node_lookup_touch(struct sprite_scope *scope, struct struct cache_node **nonmatching_next = NULL; struct cache_node_hash hash = cache_node_hash_from_tag_hash(tag.hash, kind); - u64 cache_bucket_index = U128_LO(hash.v) % CACHE_BUCKETS_COUNT; + u64 cache_bucket_index = hash.v % CACHE_BUCKETS_COUNT; struct cache_bucket *bucket = &G.cache.buckets[cache_bucket_index]; /* Lookup */ @@ -794,7 +793,7 @@ INTERNAL struct cache_node *node_lookup_touch(struct sprite_scope *scope, struct nonmatching_next = &bucket->first; n = *nonmatching_next; while (n) { - if (u128_eq(n->hash.v, hash.v)) { + if (n->hash.v == hash.v) { scope_ensure_reference(scope, n, cache_bucket_index); break; } else { diff --git a/src/uid.c b/src/uid.c index 3573ecea..db82f763 100644 --- a/src/uid.c +++ b/src/uid.c @@ -5,16 +5,17 @@ /* Returns a uid generated from the system's random number generator */ struct uid uid_rand(void) { - u128 v = 0; - sys_rand(STRING_FROM_STRUCT(&v)); - return (struct uid) { .v = v }; + struct uid res = ZI; + sys_rand(STRING_FROM_STRUCT(&res)); + return res; } -/* Returns the deterministic outcome of two uids formed into a new uid */ +/* Commutatively combines 2 uids into a new uid */ struct uid uid_combine(struct uid a, struct uid b) { struct uid res; - res.v = hash_fnv128(HASH_FNV128_BASIS, STRING_FROM_STRUCT(&a)); - res.v = hash_fnv128(res.v, STRING_FROM_STRUCT(&b)); + /* Add bits of a+b to an arbitrary random constant (to prevent (a=0 + b=0) from returning a uid=0) */ + res.hi = 0x958d53b0e2fd8e3f + a.hi + b.hi; + res.lo = 0x7038ffd46e0868c7 + a.lo + b.lo; return res; } diff --git a/src/user.c b/src/user.c index f537ac08..f3ec6049 100644 --- a/src/user.c +++ b/src/user.c @@ -353,7 +353,7 @@ INTERNAL struct string get_ent_debug_text(struct arena *arena, struct sim_ent *e /* TODO: String fmt function */ struct uid uid = ent->uid; res.len += string_copy(arena, LIT(" [")).len; - res.len += string_from_uint(arena, (U128_HI(uid.v) >> 36) & 0xFFFFFFF, 16, 7).len; + res.len += string_from_uint(arena, (uid.hi >> 36) & 0xFFFFFFF, 16, 7).len; res.len += string_copy(arena, LIT("]\n")).len; { @@ -437,9 +437,9 @@ INTERNAL SORT_COMPARE_FUNC_DEF(ent_draw_order_cmp, arg_a, arg_b, udata) } if (res == 0) { /* Sort by sprite */ - u128 a_cmp = a->sprite.hash; - u128 b_cmp = b->sprite.hash; - res = u128_lt(a_cmp, b_cmp) - u128_gt(a_cmp, b_cmp); + u64 a_cmp = a->sprite.hash; + u64 b_cmp = b->sprite.hash; + res = (a_cmp < b_cmp) - (a_cmp > b_cmp); } if (res == 0) { /* Sort by activation */ diff --git a/src/util.h b/src/util.h index 217f0068..c7dfd839 100644 --- a/src/util.h +++ b/src/util.h @@ -32,6 +32,7 @@ INLINE u64 hash_fnv64(u64 seed, struct string s) return hash; } +#if 0 #define HASH_FNV128_BASIS U128(0x6C62272E07BB0142, 0x62B821756295C58D) INLINE u128 hash_fnv128(u128 seed, struct string s) { @@ -44,6 +45,7 @@ INLINE u128 hash_fnv128(u128 seed, struct string s) } return hash; } +#endif /* ========================== * * Merge sort