From fcedfddf00b3f994e4f4e40332ac7fc192c63244 Mon Sep 17 00:00:00 2001 From: polwex Date: Sun, 5 Oct 2025 21:56:51 +0700 Subject: claude is gud --- vere/pkg/c3/defs.h | 283 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 283 insertions(+) create mode 100644 vere/pkg/c3/defs.h (limited to 'vere/pkg/c3/defs.h') diff --git a/vere/pkg/c3/defs.h b/vere/pkg/c3/defs.h new file mode 100644 index 0000000..5adc05d --- /dev/null +++ b/vere/pkg/c3/defs.h @@ -0,0 +1,283 @@ +/// @file + +#ifndef C3_DEFS_H +#define C3_DEFS_H + +#include "portable.h" +#include "types.h" +#include + +#include + + /** Loobeans - inverse booleans to match nock. + **/ +# define c3y 0 +# define c3n 1 + +# define _(x) (c3y == (x)) +# define __(x) ((x) ? c3y : c3n) +# define c3a(x, y) __(_(x) && _(y)) +# define c3o(x, y) __(_(x) || _(y)) + + + /** Random useful C macros. + **/ + /* Dessert. Debug assert. If a debugger is attached, it will break in and + execution can be allowed to proceed without aborting the process. + Otherwise, the unhandled SIGTRAP will dump core. + */ +#ifdef C3DBG + #if defined(__i386__) || defined(__x86_64__) + #define c3_dessert(x) do { if(!(x)) __asm__ volatile("int $3"); } while (0) + #elif defined(__thumb__) + #define c3_dessert(x) do { if(!(x)) __asm__ volatile(".inst 0xde01"); } while (0) + #elif defined(__aarch64__) + #define c3_dessert(x) do { if(!(x)) __asm__ volatile(".inst 0xd4200000"); } while (0) + #elif defined(__arm__) + #define c3_dessert(x) do { if(!(x)) __asm__ volatile(".inst 0xe7f001f0"); } while (0) + #else + STATIC_ASSERT(0, "debugger break instruction unimplemented"); + #endif +#else + #define c3_dessert(x) ((void)(0)) +#endif + + /* Stub. + */ +# define c3_stub u3_assert(!"stub") + + /* Size in words. + */ +# define c3_wiseof(x) (((sizeof (x)) + 3) >> 2) + + /* Bit counting. + */ +#if (32 == (CHAR_BIT * __SIZEOF_INT__)) +# define c3_lz_w __builtin_clz +# define c3_tz_w __builtin_ctz +# define c3_pc_w __builtin_popcount +#elif (32 == (CHAR_BIT * __SIZEOF_LONG__)) +# define c3_lz_w __builtin_clzl +# define c3_tz_w __builtin_ctzl +# define c3_pc_w __builtin_popcountl +#else +# error "port me" +#endif + +#if (64 == (CHAR_BIT * __SIZEOF_LONG__)) +# define c3_lz_d __builtin_clzl +# define c3_tz_d __builtin_ctzl +# define c3_pc_d __builtin_popcountl +#elif (64 == (CHAR_BIT * __SIZEOF_LONG_LONG__)) +# define c3_lz_d __builtin_clzll +# define c3_tz_d __builtin_ctzll +# define c3_pc_d __builtin_popcountll +#else +# error "port me" +#endif + +# define c3_bits_word(w) ((w) ? (32 - c3_lz_w(w)) : 0) +# define c3_bits_dabl(d) ((d) ? (64 - c3_lz_d(d)) : 0) + + /* Min and max. + */ +# define c3_max(x, y) ( ((x) > (y)) ? (x) : (y) ) +# define c3_min(x, y) ( ((x) < (y)) ? (x) : (y) ) + + +//! Round up/down (respectively). +//! +//! @param[in] x Integer to round. +//! @param[in] n Multiple to round to. Must be power of 2. +//! +//! @return `x` rounded to the nearest multiple of `n`. +# define c3_rop(x, n) (((x) + ((n) - 1)) & (~((n) - 1))) +# define c3_rod(x, n) ((x) & ~((n) - 1)) + + /* Rotate. + */ +# define c3_rotw(r, x) ( ((x) << (r)) | ((x) >> (32 - (r))) ) + + /* Fill 16 words (64 bytes) with high-quality entropy. + */ + void + c3_rand(c3_w* rad_w); + + /* Short integers. + */ +# define c3_s1(a) ( (a) ) +# define c3_s2(a, b) ( ((b) << 8) | c3_s1(a) ) +# define c3_s3(a, b, c) ( ((c) << 16) | c3_s2(a, b) ) +# define c3_s4(a, b, c, d) ( ((d) << 24) | c3_s3(a, b, c) ) + +# define c3_s5(a, b, c, d, e) \ + ( ((uint64_t)c3_s1(e) << 32ULL) | c3_s4(a, b, c, d) ) +# define c3_s6(a, b, c, d, e, f) \ + ( ((uint64_t)c3_s2(e, f) << 32ULL) | c3_s4(a, b, c, d) ) +# define c3_s7(a, b, c, d, e, f, g) \ + ( ((uint64_t)c3_s3(e, f, g) << 32ULL) | c3_s4(a, b, c, d) ) +# define c3_s8(a, b, c, d, e, f, g, h) \ + ( ((uint64_t)c3_s4(e, f, g, h) << 32ULL) | c3_s4(a, b, c, d) ) + + /* Byte-order twiddling. + */ +# define c3_flip32(w) \ + ( (((w) >> 24) & 0xff) \ + | (((w) >> 16) & 0xff) << 8 \ + | (((w) >> 8) & 0xff) << 16 \ + | ( (w) & 0xff) << 24 ) + + inline c3_s + c3_sift_short(c3_y buf_y[2]) + { + return ((c3_s)buf_y[1] << 8 | (c3_s)buf_y[0]); + } + + inline c3_w + c3_sift_word(c3_y buf_y[4]) + { + return ((c3_w)buf_y[3] << 24 | (c3_w)buf_y[2] << 16 | (c3_w)buf_y[1] << 8 | (c3_w)buf_y[0]); + } + + inline c3_d + c3_sift_chub(c3_y byt_y[8]) + { + return (c3_d)byt_y[0] + | (c3_d)byt_y[1] << 8 + | (c3_d)byt_y[2] << 16 + | (c3_d)byt_y[3] << 24 + | (c3_d)byt_y[4] << 32 + | (c3_d)byt_y[5] << 40 + | (c3_d)byt_y[6] << 48 + | (c3_d)byt_y[7] << 56; + } + + inline void + c3_etch_short(c3_y buf_y[2], c3_s sot_s) + { + buf_y[0] = sot_s & 0xff; + buf_y[1] = (sot_s >> 8) & 0xff; + } + + inline void + c3_etch_word(c3_y buf_y[4], c3_w wod_w) + { + buf_y[0] = wod_w & 0xff; + buf_y[1] = (wod_w >> 8) & 0xff; + buf_y[2] = (wod_w >> 16) & 0xff; + buf_y[3] = (wod_w >> 24) & 0xff; + } + + inline void + c3_etch_chub(c3_y byt_y[8], c3_d num_d) + { + byt_y[0] = num_d & 0xff; + byt_y[1] = (num_d >> 8) & 0xff; + byt_y[2] = (num_d >> 16) & 0xff; + byt_y[3] = (num_d >> 24) & 0xff; + byt_y[4] = (num_d >> 32) & 0xff; + byt_y[5] = (num_d >> 40) & 0xff; + byt_y[6] = (num_d >> 48) & 0xff; + byt_y[7] = (num_d >> 56) & 0xff; + } + + /* Asserting allocators. + */ +# define c3_free(s) free(s) +# define c3_malloc(s) ({ \ + void* rut = malloc(s); \ + if ( 0 == rut ) { \ + fprintf(stderr, "c3_malloc(%" PRIu64 ") failed\r\n", \ + (c3_d)s); \ + u3_assert(!"memory lost"); \ + } \ + rut;}) +# define c3_calloc(s) ({ \ + void* rut = calloc(1,s); \ + if ( 0 == rut ) { \ + fprintf(stderr, "c3_calloc(%" PRIu64 ") failed\r\n", \ + (c3_d)s); \ + u3_assert(!"memory lost"); \ + } \ + rut;}) +# define c3_realloc(a, b) ({ \ + void* rut = realloc(a, b); \ + if ( 0 == rut ) { \ + fprintf(stderr, "c3_realloc(%" PRIu64 ") failed\r\n", \ + (c3_d)b); \ + u3_assert(!"memory lost"); \ + } \ + rut;}) + + /* Asserting unix fs wrappers. + ** + ** these all crash the process if passed a non-canonical + ** path (i.e., one containing '.', '..', or the empty path + ** component), so make sure you don't pass them one. if you + ** find yourself fighting with them, then please delete them + ** and do a sed search-and-replace to remove the `c3_` from + ** their call sites; their goal is to decrease maintenance + ** burden, not increase it. + */ + // defined in vere/io/unix.c. + c3_t u3_unix_cane(const c3_c* pax_c); +# define c3_open(a, ...) ({ \ + open(a, __VA_ARGS__);}) +# define c3_opendir(a) ({ \ + opendir(a);}) +# define c3_mkdir(a, b) ({ \ + mkdir(a, b);}) +# define c3_rmdir(a) ({ \ + rmdir(a);}) +# define c3_link(a, b) ({ \ + link(a, b);}) +# define c3_unlink(a) ({ \ + unlink(a);}) +# define c3_fopen(a, b) ({ \ + fopen(a, b);}) +# define c3_remove(a) ({ \ + remove(a);}) +# define c3_rename(a, b) ({ \ + rename(a, b);}) + +/* c3_align( + x - the address/quantity to align, + al - the alignment, + hilo - [C3_ALGHI, C3_ALGLO] high or low align + ) + + hi or lo align x to al + + unless effective type of x is c3_w or c3_d, assumes x is a pointer. +*/ +#define c3_align(x, al, hilo) \ + _Generic((x), \ + c3_w : c3_align_w, \ + c3_d : c3_align_d, \ + default : c3_align_p) \ + (x, al, hilo) +typedef enum { C3_ALGHI=1, C3_ALGLO=0 } align_dir; +inline c3_w +c3_align_w(c3_w x, c3_w al, align_dir hilo) { + c3_dessert(hilo <= C3_ALGHI && hilo >= C3_ALGLO); + x += hilo * (al - 1); + x &= ~(al - 1); + return x; +} +inline c3_d +c3_align_d(c3_d x, c3_d al, align_dir hilo) { + c3_dessert(hilo <= C3_ALGHI && hilo >= C3_ALGLO); + x += hilo * (al - 1); + x &= ~(al - 1); + return x; +} +inline void* +c3_align_p(void const * p, size_t al, align_dir hilo) { + uintptr_t x = (uintptr_t)p; + c3_dessert(hilo <= C3_ALGHI && hilo >= C3_ALGLO); + x += hilo * (al - 1); + x &= ~(al - 1); + return (void*)x; +} + +#endif /* ifndef C3_DEFS_H */ -- cgit v1.2.3