From 413dd3eb84aa8b8232b47aa99a3f1ab9aa86d28c Mon Sep 17 00:00:00 2001 From: Owen Rummage Date: Sat, 18 Jul 2026 21:04:37 -0500 Subject: [PATCH] prelim PPC64be/PPC32be ASM testing, to be refined later --- Makefile | 17 +- README.md | 4 +- src/kernels/fossbench-powerpc.c | 261 --- src/kernels/fossbench-ppc32-ext.S | 74 - src/kernels/fossbench-ppc32be.S | 2729 +++++++++++++++++++++++++++++ src/kernels/fossbench-ppc64be.S | 2017 +++++++++++++++++++++ 6 files changed, 4756 insertions(+), 346 deletions(-) delete mode 100644 src/kernels/fossbench-powerpc.c delete mode 100644 src/kernels/fossbench-ppc32-ext.S create mode 100644 src/kernels/fossbench-ppc32be.S create mode 100644 src/kernels/fossbench-ppc64be.S diff --git a/Makefile b/Makefile index 570b16d..317f852 100644 --- a/Makefile +++ b/Makefile @@ -14,9 +14,8 @@ DRIVER := src/main.c src/app/benchmark.c ASM_ARM64 := src/kernels/fossbench-arm64.S ASM_AMD64 := src/kernels/fossbench-amd64.S ASM_I386 := src/kernels/fossbench-i386.S -SRC_PPC32 := src/kernels/fossbench-powerpc.c -ASM_PPC32 := src/kernels/fossbench-ppc32-ext.S -SRC_PPC64 := src/kernels/fossbench-powerpc.c +ASM_PPC32 := src/kernels/fossbench-ppc32be.S +ASM_PPC64 := src/kernels/fossbench-ppc64be.S # Figure out the host CPU. HOST_ARCH := $(shell uname -m) @@ -31,10 +30,10 @@ else ifneq (,$(filter i386 i486 i586 i686 x86,$(HOST_ARCH))) HOST_KERNEL := $(ASM_I386) else ifneq (,$(filter ppc powerpc ppc32 powerpc32,$(HOST_ARCH))) HOST_ARCHNAME := ppc32be - HOST_KERNEL := $(SRC_PPC32) $(ASM_PPC32) + HOST_KERNEL := $(ASM_PPC32) else ifneq (,$(filter ppc64 powerpc64,$(HOST_ARCH))) HOST_ARCHNAME := ppc64be - HOST_KERNEL := $(SRC_PPC64) + HOST_KERNEL := $(ASM_PPC64) else HOST_ARCHNAME := $(HOST_ARCH) $(error unsupported host architecture '$(HOST_ARCH)') @@ -130,12 +129,12 @@ $(DIST)/fossbench-linux-i386: $(DRIVER) $(ASM_I386) | $(DIST) $(CC_I386) -m32 -march=pentium4 -fno-pie -no-pie $(CFLAGS) $(TLS_CFLAGS) $(PTHREAD) $(LDFLAGS) -o $@ $(DRIVER) $(ASM_I386) $(LDLIBS) @echo "built $@" -$(DIST)/fossbench-linux-ppc32be: $(DRIVER) $(SRC_PPC32) $(ASM_PPC32) | $(DIST) - $(CC_PPC32BE) $(CFLAGS) $(TLS_CFLAGS) $(PTHREAD) $(LDFLAGS) -o $@ $(DRIVER) $(SRC_PPC32) $(ASM_PPC32) $(LDLIBS) +$(DIST)/fossbench-linux-ppc32be: $(DRIVER) $(ASM_PPC32) | $(DIST) + $(CC_PPC32BE) $(CFLAGS) $(TLS_CFLAGS) $(PTHREAD) $(LDFLAGS) -o $@ $(DRIVER) $(ASM_PPC32) $(LDLIBS) @echo "built $@" -$(DIST)/fossbench-linux-ppc64be: $(DRIVER) $(SRC_PPC64) | $(DIST) - $(CC_PPC64BE) -mcpu=970 -maltivec $(CFLAGS) $(TLS_CFLAGS) $(PTHREAD) $(LDFLAGS) -o $@ $(DRIVER) $(SRC_PPC64) $(LDLIBS) +$(DIST)/fossbench-linux-ppc64be: $(DRIVER) $(ASM_PPC64) | $(DIST) + $(CC_PPC64BE) -mcpu=970 -maltivec $(CFLAGS) $(TLS_CFLAGS) $(PTHREAD) $(LDFLAGS) -o $@ $(DRIVER) $(ASM_PPC64) $(LDLIBS) @echo "built $@" $(DIST)/fossbench-macos-arm64: $(DRIVER) $(ASM_ARM64) | $(DIST) diff --git a/README.md b/README.md index 9f7c626..c3c8bb3 100644 --- a/README.md +++ b/README.md @@ -153,7 +153,7 @@ src/app/upload.c API payload and network transport src/kernels/fossbench-arm64.S ARM64 kernels src/kernels/fossbench-amd64.S x86-64 kernels src/kernels/fossbench-i386.S i386 kernels -src/kernels/fossbench-powerpc.c PowerPC kernels -src/kernels/fossbench-ppc32-ext.S optional PPC32 extended kernels +src/kernels/fossbench-ppc32be.S 32-bit big-endian PowerPC kernels +src/kernels/fossbench-ppc64be.S 64-bit big-endian PowerPC kernels src/test_kernels.c kernel correctness suite ``` diff --git a/src/kernels/fossbench-powerpc.c b/src/kernels/fossbench-powerpc.c deleted file mode 100644 index e5f2c12..0000000 --- a/src/kernels/fossbench-powerpc.c +++ /dev/null @@ -1,261 +0,0 @@ -/* PowerPC kernel code. */ -#include -#include -#include -#include -#include - -#if defined(__linux__) -#include -#endif - -static uint32_t rotl32(uint32_t x, unsigned n) -{ - return (x << n) | (x >> (32 - n)); -} - -uint64_t fb_int_math(uint64_t iters) -{ - uint64_t a = 0x9e3779b97f4a7c15ULL, b = 0xbf58476d1ce4e5b9ULL; - uint64_t c = 0x94d049bb133111ebULL, d = 0x2545f4914f6cdd1dULL; - uint64_t i; - if (!iters) return 0; - for (i = 0; i < iters; i++) { - a = a * 0xdeadbeefU + b; b = b * 0xdeadbeefU + c; - c = c * 0xdeadbeefU + d; d = d * 0xdeadbeefU + a; - a ^= c >> 29; b ^= d << 17; c ^= (a >> 31) | (a << 33); - d ^= b >> 7; a += c / 0xdeadbeefU; b += d / 0xdeadbeefU; - } - return a ^ b ^ c ^ d; -} - -uint64_t fb_fp_math(uint64_t iters) -{ - double a = 1.5, b = 2.5, c = 3.5, d = .5, out; - uint64_t bits, i; - if (!iters) return 0; - for (i = 0; i < iters; i++) { - a = fmin(a * 1.0625 + .0009765625, 2.0); - b = fmin(b * 1.0625 + .0009765625, 2.0); - c = fmin(c * 1.0625 + .0009765625, 2.0) + sqrt(a); - d = fmax(fabs(fmin(d * 1.0625 + .0009765625, 2.0) + sqrt(b)), 1.0); - a += 1.0 / (c + 1.0); b += 1.0 / (d + 1.0); - } - out = a + b + c + d; - memcpy(&bits, &out, sizeof bits); - return bits; -} - -uint64_t fb_primes(uint64_t limit, uint8_t *sieve) -{ - uint64_t i, j, count = 0; - if (limit < 2) return 0; - memset(sieve, 0, (size_t)limit); - sieve[0] = sieve[1] = 1; - for (i = 2; i <= (limit - 1) / i; i++) - if (!sieve[i]) for (j = i * i; j < limit; j += i) sieve[j] = 1; - for (i = 2; i < limit; i++) count += !sieve[i]; - return count; -} - -#if !defined(__powerpc64__) -static uint64_t fb_simd_scalar(uint64_t iters, void *memory) -{ - uint32_t *v = (uint32_t *)memory; - uint32_t a[8]; uint64_t i; unsigned j; uint32_t sum = 0; - if (!iters) return 0; - memcpy(a, v, sizeof a); - for (i = 0; i < iters; i++) - for (j = 0; j < 8; j++) a[j] = rotl32(a[j] + a[(j + 1) & 7] * (j + 3), (j + 5) & 31); - for (j = 0; j < 8; j++) sum ^= a[j]; - memcpy(v, a, sizeof a); - return sum; -} -#endif - -#if defined(__powerpc64__) -/* The iMac G5 has AltiVec. */ -typedef uint32_t fb_vec_u32 __attribute__((vector_size(16))); - -uint64_t fb_simd(uint64_t iters, void *memory) -{ - fb_vec_u32 a, b; - uint32_t *v = (uint32_t *)memory; - uint32_t sum = 0; - uint64_t i; - unsigned j; - - if (!iters) - return 0; - memcpy(&a, v, sizeof a); - memcpy(&b, v + 4, sizeof b); - for (i = 0; i < iters; i++) { - a = a + b; - b = b ^ a; - a = a + b; - b = b ^ a; - } - memcpy(v, &a, sizeof a); - memcpy(v + 4, &b, sizeof b); - for (j = 0; j < 8; j++) - sum ^= v[j]; - return sum; -} -#else -/* The optional PowerPC code is in the assembly file. */ -extern void fb_simd_ps_kernel(uint64_t iters, void *memory); -extern void fb_simd_vsx_kernel(uint64_t iters, void *memory); -extern void fb_simd_altivec_kernel(uint64_t iters, void *memory); - -typedef void (*fb_simd_kernel)(uint64_t, void *); - -static int device_is_nintendo(void) -{ -#if defined(__linux__) - static const char prefix[] = "nintendo,"; - static const char *const paths[] = { - "/proc/device-tree/compatible", - "/sys/firmware/devicetree/base/compatible" - }; - char compatible[sizeof prefix - 1]; - unsigned i; - - for (i = 0; i < sizeof paths / sizeof paths[0]; i++) { - FILE *fp = fopen(paths[i], "rb"); - int match; - if (fp == NULL) - continue; - match = fread(compatible, 1, sizeof compatible, fp) == sizeof compatible && - memcmp(compatible, prefix, sizeof compatible) == 0; - fclose(fp); - return match; - } - return 0; -#else - return 0; -#endif -} - -static fb_simd_kernel detect_simd_kernel(void) -{ - /* Linux tells us which PowerPC features are available. */ -#if defined(__linux__) && defined(AT_HWCAP) - const unsigned long hwcap = getauxval(AT_HWCAP); - const unsigned long has_altivec = 0x10000000UL; - const unsigned long has_vsx = 0x00000080UL; - - if (device_is_nintendo()) - return fb_simd_ps_kernel; - if (hwcap & has_vsx) - return fb_simd_vsx_kernel; - if (hwcap & has_altivec) - return fb_simd_altivec_kernel; -#else - if (device_is_nintendo()) - return fb_simd_ps_kernel; -#endif - return NULL; -} - -uint64_t fb_simd(uint64_t iters, void *memory) -{ - static fb_simd_kernel kernel; - static int detected; - fb_simd_kernel selected; - uint32_t *v = (uint32_t *)memory; - uint32_t sum = 0; - unsigned j; - - if (!iters) - return 0; - if (!__atomic_load_n(&detected, __ATOMIC_ACQUIRE)) { - fb_simd_kernel found = detect_simd_kernel(); - __atomic_store_n(&kernel, found, __ATOMIC_RELAXED); - __atomic_store_n(&detected, 1, __ATOMIC_RELEASE); - } - selected = __atomic_load_n(&kernel, __ATOMIC_RELAXED); - if (selected == NULL) - return fb_simd_scalar(iters, memory); - - selected(iters, memory); - for (j = 0; j < 8; j++) - sum ^= v[j]; - return sum; -} -#endif - -static uint32_t load32_native(const uint8_t *p) -{ - uint32_t v; memcpy(&v, p, sizeof v); return v; -} - -uint64_t fb_compress(const uint8_t *src, uint64_t len, uint32_t *ht) -{ - uint64_t ip = 0, anchor = 0, out = 0, ref, ml, lit; - memset(ht, 0, (size_t)(1U << 16) * sizeof *ht); - if (len < 16) return len + 1; - while (ip < len - 12) { - uint32_t seq = load32_native(src + ip); - uint32_t h = (uint32_t)(seq * 2654435761U) >> 16; - ref = ht[h]; ht[h] = (uint32_t)ip; - if (ref >= ip || ip - ref >= 65536 || load32_native(src + ref) != seq) { ip++; continue; } - for (ml = 4; ip + ml < len && src[ip + ml] == src[ref + ml]; ml++) {} - lit = ip - anchor; out += lit + 3 + (lit >= 15) + (ml >= 19); - ip += ml; anchor = ip; - } - return out + (len - anchor) + 1; -} - -static uint32_t load32le(const uint8_t *p) -{ - return (uint32_t)p[0] | (uint32_t)p[1] << 8 | (uint32_t)p[2] << 16 | (uint32_t)p[3] << 24; -} -static void store32le(uint8_t *p, uint32_t v) -{ - p[0] = (uint8_t)v; p[1] = (uint8_t)(v >> 8); p[2] = (uint8_t)(v >> 16); p[3] = (uint8_t)(v >> 24); -} -#define QR(a,b,c,d) do { a+=b; d=rotl32(d^a,16); c+=d; b=rotl32(b^c,12); a+=b; d=rotl32(d^a,8); c+=d; b=rotl32(b^c,7); } while (0) -uint64_t fb_chacha20(uint8_t *buf, uint64_t len, const uint8_t key[32], uint64_t passes) -{ - static const uint32_t sigma[4] = {0x61707865,0x3320646e,0x79622d32,0x6b206574}; - uint32_t base[16], x[16], counter = 0, checksum = 0; uint64_t pass, off; int i, r; - len &= ~(uint64_t)63; if (!len || !passes) return 0; - memcpy(base, sigma, 16); for (i=0;i<8;i++) base[4+i]=load32le(key+4*i); - base[13]=base[14]=base[15]=0; - for (pass=0;pass=end)return; if(c+1a[c])c++; if(a[root]>=a[c])return; t=a[root];a[root]=a[c];a[c]=t;root=c; } } -uint64_t fb_sort(uint32_t *a, uint64_t n) -{ - uint64_t i,end,sum=0; uint32_t t; if(n<2)return n?a[0]:0; - for (i = n / 2; i; i--) - sift(a, i - 1, n); - for (end = n - 1; end; end--) { - t = a[0]; a[0] = a[end]; a[end] = t; - sift(a, 0, end); - } - for(i=0;i>7)|(sum<<57);sum^=a[i];sum+=a[i];} return sum; -} - -uint64_t fb_chase(void **ptrs, uint64_t steps) -{ - void **p=ptrs; uint64_t i; if(!steps)return 0; for(i=0;i