From 7aa0e563c3c02b4f30c869d0ce89bc833ca3db56 Mon Sep 17 00:00:00 2001 From: igneum-labs <337424239+igneum-labs@users.noreply.github.com> Date: Wed, 7 Oct 2026 22:29:50 +0000 Subject: [PATCH] Counter ASIC 4.0 research: the fixed per-load pack mx8_shl256x27_v2 (attempt 3, id bd64b207a30413fb; the first export's id 854050a4293f0615 stays as the known-failed record) Co-Authored-By: Claude Fable 5.1 --- .../packs-ca4/mx8_shl256x27_v2/kernel.cl | 583 +++++++++++ .../packs-ca4/mx8_shl256x27_v2/kernel.cu | 468 +++++++++ .../mx8_shl256x27_v2/kernel_bound.cl | 981 ++++++++++++++++++ .../mx8_shl256x27_v2/kernel_bound.cu | 427 ++++++++ .../packs-ca4/mx8_shl256x27_v2/memhard.h | 109 ++ .../packs-ca4/mx8_shl256x27_v2/memhard.metal | 107 ++ .../packs-ca4/mx8_shl256x27_v2/program.h | 72 ++ .../packs-ca4/mx8_shl256x27_v2/program.json | 390 +++++++ .../packs-ca4/mx8_shl256x27_v2/program.metal | 413 ++++++++ .../mx8_shl256x27_v2/program_bound.metal | 415 ++++++++ .../packs-ca4/mx8_shl256x27_v2/vectors.h | 57 + .../packs-ca4/mx8_shl256x27_v2/vectors.json | 36 + 12 files changed, 4058 insertions(+) create mode 100644 proto-cuda/packs-ca4/mx8_shl256x27_v2/kernel.cl create mode 100644 proto-cuda/packs-ca4/mx8_shl256x27_v2/kernel.cu create mode 100644 proto-cuda/packs-ca4/mx8_shl256x27_v2/kernel_bound.cl create mode 100644 proto-cuda/packs-ca4/mx8_shl256x27_v2/kernel_bound.cu create mode 100644 proto-cuda/packs-ca4/mx8_shl256x27_v2/memhard.h create mode 100644 proto-cuda/packs-ca4/mx8_shl256x27_v2/memhard.metal create mode 100644 proto-cuda/packs-ca4/mx8_shl256x27_v2/program.h create mode 100644 proto-cuda/packs-ca4/mx8_shl256x27_v2/program.json create mode 100644 proto-cuda/packs-ca4/mx8_shl256x27_v2/program.metal create mode 100644 proto-cuda/packs-ca4/mx8_shl256x27_v2/program_bound.metal create mode 100644 proto-cuda/packs-ca4/mx8_shl256x27_v2/vectors.h create mode 100644 proto-cuda/packs-ca4/mx8_shl256x27_v2/vectors.json diff --git a/proto-cuda/packs-ca4/mx8_shl256x27_v2/kernel.cl b/proto-cuda/packs-ca4/mx8_shl256x27_v2/kernel.cl new file mode 100644 index 000000000..72dd03640 --- /dev/null +++ b/proto-cuda/packs-ca4/mx8_shl256x27_v2/kernel.cl @@ -0,0 +1,583 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// OpenCL C twin of the Metal kernel for the same seed (see proto-opencl/README.md, WAVEFRONT.md and program.metal). +// Built from source at runtime by proto-opencl/host.c, which passes these defines: +// IGNEUM_GROUP work-group size of igneum_hash, a multiple of 32 (default 32: one work-group = one 32-lane unit) +// IGNEUM_EXCHANGE 0 = local-memory exchange with a barrier (any device, any wave width; the default) +// 1 = sub_group_shuffle_xor (cl_khr_subgroup_shuffle), only with IGNEUM_GROUP 32 and a sub-group size of exactly 32 +// 2 = intel_sub_group_shuffle_xor (cl_intel_subgroups), same condition +// The verification unit is always 32 lanes. A 64-wide hardware wave (AMD GCN/CDNA, RDNA in wave64) runs two units; +// the exchange masks are 1, 2, 4, 8, 16, so every partner lane lies inside the lane's own aligned run of 32. +#ifndef IGNEUM_GROUP +#define IGNEUM_GROUP 32 +#endif +#ifndef IGNEUM_EXCHANGE +#define IGNEUM_EXCHANGE 0 +#endif +#ifdef __OPENCL_VERSION__ +#define IGNEUM_KERNEL_HASH __kernel __attribute__((reqd_work_group_size(IGNEUM_GROUP, 1, 1))) +#define IGNEUM_LOCAL_WORDS(name, n) __local uint name[n] +#if IGNEUM_EXCHANGE == 1 +#ifdef cl_khr_subgroups +#pragma OPENCL EXTENSION cl_khr_subgroups : enable +#endif +#ifdef cl_khr_subgroup_shuffle +#pragma OPENCL EXTENSION cl_khr_subgroup_shuffle : enable +#endif +#elif IGNEUM_EXCHANGE == 2 +#pragma OPENCL EXTENSION cl_intel_subgroups : enable +#endif +#else +// Not an OpenCL compiler: proto-opencl/emu compiles this file as C++ and supplies the built-ins and these two macros. +#include "emu_opencl.h" +#endif + +#if IGNEUM_EXCHANGE == 1 +#define IGNEUM_SHFL_XOR(dst, a, m) dst = sub_group_shuffle_xor((a), (uint)(m)) +#define IGNEUM_BCAST0(dst, a) dst = sub_group_broadcast((a), 0u) +#elif IGNEUM_EXCHANGE == 2 +#define IGNEUM_SHFL_XOR(dst, a, m) dst = intel_sub_group_shuffle_xor((a), (uint)(m)) +#define IGNEUM_BCAST0(dst, a) dst = sub_group_broadcast((a), 0u) +#else +// Local-memory exchange. Two buffers of IGNEUM_GROUP words alternate (xk counts exchanges), so one barrier per +// exchange is enough: a lane can only overwrite buffer b at exchange k+2 after passing barrier k+1, and every lane +// reaches barrier k+1 only after its read of buffer b at exchange k. The partner lid ^ m stays inside the lane's +// aligned run of 32 because m < 32. Control flow is uniform, so every work-item reaches every barrier. +#define IGNEUM_SHFL_XOR(dst, a, m) { xch[(xk & 1u) * IGNEUM_GROUP + lid] = (a); barrier(CLK_LOCAL_MEM_FENCE); dst = xch[(xk & 1u) * IGNEUM_GROUP + (lid ^ (uint)(m))]; xk += 1u; } +#define IGNEUM_BCAST0(dst, a) { xch[(xk & 1u) * IGNEUM_GROUP + lid] = (a); barrier(CLK_LOCAL_MEM_FENCE); dst = xch[(xk & 1u) * IGNEUM_GROUP + (lid & ~31u)]; xk += 1u; } +#endif + +static inline uint splitmix32(uint x) { + x ^= x >> 16; x *= 0x7feb352du; + x ^= x >> 15; x *= 0x846ca68bu; + x ^= x >> 16; + return x; +} +// n is a literal in 1..31 at every call site. OpenCL rotate() rotates left by n modulo 32. +static inline uint rotl_imm(uint x, uint n) { return rotate(x, n); } +// Right rotation by n modulo 32 as a left rotation by (32 - n) modulo 32; n == 0 gives x. +static inline uint rotr_var(uint x, uint n) { return rotate(x, (0u - n) & 31u); } +static inline uint ds_elem(uint i, uint d0, uint d1) { + uint x = i ^ d0; + x *= 0x9E3779B1u; x ^= x >> 15; + x += d1; + x *= 0x85EBCA77u; x ^= x >> 13; + x *= 0xC2B2AE3Du; x ^= x >> 16; + return x; +} + +// Memory-hard dataset core (MEMHARD.md). Cache: 2^26 words in 2^16 segments of 64 chained ChaCha12 lines. +// Item: 8 rounds of 8 x seed-parameterised mixer + one 64-byte cache read, then 8 x final mixer (class v3, mixer multiplier 8, +// docs/plans/mixer-x4.md: the round key of application j of round r is 0x9E3779B9 * (r * m + j + 1)). All parameters are literals. +#define MH_CACHE_LINE_MASK 0x003fffffu +#define MH_SEGMENT_LINES 64u +#define MH_QR(a, b, c, d, r1, r2, r3, r4) { a += b; d ^= a; d = mh_rotl(d, r1); c += d; b ^= c; b = mh_rotl(b, r2); a += b; d ^= a; d = mh_rotl(d, r3); c += d; b ^= c; b = mh_rotl(b, r4); } +static inline uint mh_rotl(uint x, uint n) { return (x << n) | (x >> (32u - n)); } // n in 1..31 at every call site + +// y = ChaCha12 core(x) + x +static inline void mh_chacha_block(const uint* x, uint* y) { + for (uint i = 0u; i < 16u; ++i) y[i] = x[i]; + for (uint r = 0u; r < 6u; ++r) { + MH_QR(y[0], y[4], y[8], y[12], 16u, 12u, 8u, 7u) MH_QR(y[1], y[5], y[9], y[13], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[6], y[10], y[14], 16u, 12u, 8u, 7u) MH_QR(y[3], y[7], y[11], y[15], 16u, 12u, 8u, 7u) + MH_QR(y[0], y[5], y[10], y[15], 16u, 12u, 8u, 7u) MH_QR(y[1], y[6], y[11], y[12], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[7], y[8], y[13], 16u, 12u, 8u, 7u) MH_QR(y[3], y[4], y[9], y[14], 16u, 12u, 8u, 7u) + } + for (uint i = 0u; i < 16u; ++i) y[i] += x[i]; +} + +// One cache segment: 64 chained lines written at cache[seg * 1024]. in_j = prev ^ (sigma || K || seg || j || tag), prev_0 = 0. +static inline void mh_cache_segment(__global uint* cache, uint seg) { + uint prev[16]; uint x[16]; uint y[16]; + for (uint i = 0u; i < 16u; ++i) prev[i] = 0u; + for (uint j = 0u; j < MH_SEGMENT_LINES; ++j) { + x[0] = 0x61707865u ^ prev[0]; x[1] = 0x3320646eu ^ prev[1]; x[2] = 0x79622d32u ^ prev[2]; x[3] = 0x6b206574u ^ prev[3]; + x[4] = 0x3067619fu ^ prev[4]; + x[5] = 0x3c269176u ^ prev[5]; + x[6] = 0x84a03b03u ^ prev[6]; + x[7] = 0xf8c63294u ^ prev[7]; + x[8] = 0xff977c5bu ^ prev[8]; + x[9] = 0xe60def3eu ^ prev[9]; + x[10] = 0x63630141u ^ prev[10]; + x[11] = 0xb8fbcb58u ^ prev[11]; + x[12] = seg ^ prev[12]; x[13] = j ^ prev[13]; x[14] = 0x49676e65u ^ prev[14]; x[15] = 0x756d4d48u ^ prev[15]; + mh_chacha_block(x, y); + __global uint* line = cache + ((seg * MH_SEGMENT_LINES + j) * 16u); + for (uint i = 0u; i < 16u; ++i) { line[i] = y[i]; prev[i] = y[i]; } + } +} + +// M_r: per word (s ^ (RC + rk)) * MUL, then a column round and a diagonal round with the seed-drawn rotations. +static inline void mh_mixer(uint* s, uint rk) { + s[0] = (s[0] ^ (0xbab68293u + rk)) * 0x42146205u; + s[1] = (s[1] ^ (0xcc162340u + rk)) * 0x52cbe0fbu; + s[2] = (s[2] ^ (0x6ce151ccu + rk)) * 0x7ecf4a03u; + s[3] = (s[3] ^ (0xe62b8997u + rk)) * 0x6728907fu; + s[4] = (s[4] ^ (0xc9c80297u + rk)) * 0xd81d9751u; + s[5] = (s[5] ^ (0xf74a1654u + rk)) * 0x132952c3u; + s[6] = (s[6] ^ (0x3d704af5u + rk)) * 0xf60de277u; + s[7] = (s[7] ^ (0x3cf522b7u + rk)) * 0x05358035u; + s[8] = (s[8] ^ (0x2b9cac04u + rk)) * 0xbaf6499du; + s[9] = (s[9] ^ (0xa880ac10u + rk)) * 0xe4db9667u; + s[10] = (s[10] ^ (0x13e5dd1du + rk)) * 0x3e98f45du; + s[11] = (s[11] ^ (0x6fc3e233u + rk)) * 0xd0004eddu; + s[12] = (s[12] ^ (0x2d83eeacu + rk)) * 0x2691630du; + s[13] = (s[13] ^ (0x9006e8bfu + rk)) * 0x9beb3bcfu; + s[14] = (s[14] ^ (0x2c4b5362u + rk)) * 0xab310379u; + s[15] = (s[15] ^ (0x31b49ee2u + rk)) * 0x99cfb423u; + MH_QR(s[0], s[4], s[8], s[12], 20u, 20u, 19u, 4u) MH_QR(s[1], s[5], s[9], s[13], 20u, 20u, 19u, 4u) + MH_QR(s[2], s[6], s[10], s[14], 20u, 20u, 19u, 4u) MH_QR(s[3], s[7], s[11], s[15], 20u, 20u, 19u, 4u) + MH_QR(s[0], s[5], s[10], s[15], 26u, 3u, 3u, 27u) MH_QR(s[1], s[6], s[11], s[12], 26u, 3u, 3u, 27u) + MH_QR(s[2], s[7], s[8], s[13], 26u, 3u, 3u, 27u) MH_QR(s[3], s[4], s[9], s[14], 26u, 3u, 3u, 27u) +} + +// Item t: 16 words. s = (K, t * MUL[i] + RC[i]); 8 rounds of 8 x mixer + cache line s[0] & mask; 8 x final mixer. +static inline void mh_item(__global const uint* cache, uint t, uint* s) { + s[0] = 0x3067619fu; + s[1] = 0x3c269176u; + s[2] = 0x84a03b03u; + s[3] = 0xf8c63294u; + s[4] = 0xff977c5bu; + s[5] = 0xe60def3eu; + s[6] = 0x63630141u; + s[7] = 0xb8fbcb58u; + s[8] = t * 0x42146205u + 0xbab68293u; + s[9] = t * 0x52cbe0fbu + 0xcc162340u; + s[10] = t * 0x7ecf4a03u + 0x6ce151ccu; + s[11] = t * 0x6728907fu + 0xe62b8997u; + s[12] = t * 0xd81d9751u + 0xc9c80297u; + s[13] = t * 0x132952c3u + 0xf74a1654u; + s[14] = t * 0xf60de277u + 0x3d704af5u; + s[15] = t * 0x05358035u + 0x3cf522b7u; + for (uint r = 0u; r < 8u; ++r) { + for (uint j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (r * 8u + j + 1u)); + __global const uint* line = cache + ((s[0] & MH_CACHE_LINE_MASK) * 16u); + for (uint i = 0u; i < 16u; ++i) s[i] ^= line[i]; + } + for (uint j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (64u + j + 1u)); +} +// dataset[w] without the dataset: derive item w >> 4 and take word w & 15. +static inline uint mh_word(__global const uint* cache, uint w) { uint s[16]; mh_item(cache, w >> 4u, s); return s[w & 15u]; } + +// Memory-hard dataset (MEMHARD.md). One work-item per cache segment; one work-item per 64-byte dataset item. +// The same constants as memhard.h in this pack (one emitter, three dialects). +__kernel void igneum_cache_fill(__global uint* cache, uint nSegments) { + uint seg = (uint)get_global_id(0); + if (seg < nSegments) mh_cache_segment(cache, seg); +} +__kernel void igneum_build(__global uint* ds, __global const uint* cache, uint nItems) { + uint t = (uint)get_global_id(0); + if (t < nItems) { + uint s[16]; + mh_item(cache, t, s); + __global uint* d = ds + ((ulong)t * 16u); + for (uint i = 0u; i < 16u; ++i) d[i] = s[i]; + } +} + +// One hash per work-item. IGNEUM_GROUP is a multiple of 32; lane = lid & 31 and every exchange stays inside the +// lane's own aligned run of 32 work-items, exactly like simd_shuffle_xor inside a 32-wide Metal SIMD group and +// __shfl_xor_sync inside a CUDA warp. Control flow is uniform (no branches at all). +IGNEUM_KERNEL_HASH void igneum_hash(__global const uint* ds, __global ulong* out, uint baseNonce, uint mask) { + uint gid = (uint)get_global_id(0); + uint lid = (uint)get_local_id(0); + uint nonce = baseNonce + gid; + uint r0, r1, r2, r3, r4, r5, r6, r7; +#if IGNEUM_EXCHANGE == 0 + IGNEUM_LOCAL_WORDS(xch, 2 * IGNEUM_GROUP); + uint xk = 0u; +#else + (void)lid; +#endif + { uint x = nonce ^ 0xf71aee9fu; x += 0x9e3779b9u; x = splitmix32(x); r0 = x ^ 0xad930c88u; } // SEEDW[0], 0x9e3779b9u * 1u, SEEDW[1] + { uint x = nonce ^ 0xad930c88u; x += 0x3c6ef372u; x = splitmix32(x); r1 = x ^ 0x7f982573u; } // SEEDW[1], 0x9e3779b9u * 2u, SEEDW[2] + { uint x = nonce ^ 0x7f982573u; x += 0xdaa66d2bu; x = splitmix32(x); r2 = x ^ 0xa41f9137u; } // SEEDW[2], 0x9e3779b9u * 3u, SEEDW[3] + { uint x = nonce ^ 0xa41f9137u; x += 0x78dde6e4u; x = splitmix32(x); r3 = x ^ 0x76d803d6u; } // SEEDW[3], 0x9e3779b9u * 4u, SEEDW[4] + { uint x = nonce ^ 0x76d803d6u; x += 0x1715609du; x = splitmix32(x); r4 = x ^ 0x37b4a534u; } // SEEDW[4], 0x9e3779b9u * 5u, SEEDW[5] + { uint x = nonce ^ 0x37b4a534u; x += 0xb54cda56u; x = splitmix32(x); r5 = x ^ 0x4d3fb826u; } // SEEDW[5], 0x9e3779b9u * 6u, SEEDW[6] + { uint x = nonce ^ 0x4d3fb826u; x += 0x5384540fu; x = splitmix32(x); r6 = x ^ 0xff614dcbu; } // SEEDW[6], 0x9e3779b9u * 7u, SEEDW[7] + { uint x = nonce ^ 0xff614dcbu; x += 0xf1bbcdc8u; x = splitmix32(x); r7 = x ^ 0xf71aee9fu; } // SEEDW[7], 0x9e3779b9u * 8u, SEEDW[0] + + for (uint it = 0u; it < 8u; ++it) { + uint sel = r0; + r2 = r2 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0x894e457du : 0xe3e2ed7du); // 0 add + r7 = r4 * r0 + r7; // 1 mad + r3 = r3 - r6; // 2 sub + r5 = rotr_var(r5, r1); // 3 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 1u); r6 = r6 ^ t_; } // 4 shfl + r0 = r0 | r3; // 5 or + r0 = r0 * r1; // 6 mul + r7 = r7 * r6; // 7 mul + r3 = r3 ^ ds[r0 & mask]; // 8 load + // per-load shadow sub-block 0 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 0 + for (uint sh0 = 0u; sh0 < 27u; ++sh0) { + r5 = rotr_var(r5, r4); // s0 rotr + r6 = r6 - r5; // s1 sub + r7 = r7 - r6; // s2 sub + r5 = r5 * r4; // s3 mul + r7 = r7 ^ r6; // s4 xor + r2 = rotl_imm(r2, 23u); // s5 rotl + r7 = r7 ^ r4; // s6 xor + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x3051c491u : 0xdaef8862u); // s7 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r6 = r6 ^ t_; } // s8 shfl + r5 = r5 + r1 + ((((sel >> 26u) & 1u) != 0u) ? 0x5170d0b3u : 0xc20e7045u); // s9 add + r0 = r0 | r3; // s10 or + r5 = mul_hi(r5, r4); // s11 mulhi + r7 = r7 ^ r0; // s12 xor + r5 = r5 - r2; // s13 sub + r0 = r0 + r6 + ((((sel >> 0u) & 1u) != 0u) ? 0x2ead087fu : 0xc86d98a4u); // s14 add + r5 = r5 ^ r7; // s15 xor + } + r4 = r4 + r3 + ((((sel >> 22u) & 1u) != 0u) ? 0xd26d3573u : 0xce9bea84u); // 9 add + r2 = r2 * r4; // 10 mul + r3 = r3 ^ ds[r2 & mask]; // 11 load + // per-load shadow sub-block 1 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 1 + for (uint sh1 = 0u; sh1 < 27u; ++sh1) { + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 8u); r7 = r7 ^ t_; } // s16 shfl + r5 = r5 - r7; // s17 sub + r0 = r0 | r6; // s18 or + r0 = r0 + r5 + ((((sel >> 13u) & 1u) != 0u) ? 0xc47c70a8u : 0x4248b651u); // s19 add + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r4 = r4 ^ t_; } // s20 shfl + r0 = r0 + r4 + ((((sel >> 21u) & 1u) != 0u) ? 0x718c1008u : 0x1e35684fu); // s21 add + r0 = mul_hi(r0, r3); // s22 mulhi + r4 = r4 ^ r2; // s23 xor + r0 = r0 - r2; // s24 sub + r5 = rotl_imm(r5, 13u); // s25 rotl + r7 = r7 - r0; // s26 sub + r2 = r2 ^ r3; // s27 xor + r2 = r3 * r2 + r2; // s28 mad + r2 = r2 ^ r1; // s29 xor + r4 = mul_hi(r4, r0); // s30 mulhi + r6 = r6 ^ r4; // s31 xor + } + r4 = mul_hi(r4, r1); // 12 mulhi + r7 = mul_hi(r7, r3); // 13 mulhi + r3 = r3 + r2 + ((((sel >> 8u) & 1u) != 0u) ? 0xc2828a42u : 0x514f9ff4u); // 14 add + r1 = r3 * r2 + r1; // 15 mad + r2 = rotl_imm(r2, 7u); // 16 rotl + r1 = r1 ^ ds[r2 & mask]; // 17 load + // per-load shadow sub-block 2 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 2 + for (uint sh2 = 0u; sh2 < 27u; ++sh2) { + r4 = r4 ^ r2; // s32 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 1u); r1 = r1 ^ t_; } // s33 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r5 = r5 ^ t_; } // s34 shfl + r4 = r4 - r0; // s35 sub + r6 = r6 - r3; // s36 sub + r2 = r2 | r6; // s37 or + r2 = rotl_imm(r2, 30u); // s38 rotl + r4 = rotr_var(r4, r7); // s39 rotr + r0 = r0 | r7; // s40 or + r2 = rotr_var(r2, r5); // s41 rotr + r1 = r3 * r3 + r1; // s42 mad + r6 = r5 * r5 + r6; // s43 mad + r1 = mul_hi(r1, r0); // s44 mulhi + r1 = r1 * r3; // s45 mul + r0 = r2 * r0 + r0; // s46 mad + r1 = r1 - r5; // s47 sub + } + r3 = r3 * r2; // 18 mul + r6 = rotl_imm(r6, 24u); // 19 rotl + r6 = r6 ^ ds[r3 & mask]; // 20 load + // per-load shadow sub-block 3 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 3 + for (uint sh3 = 0u; sh3 < 27u; ++sh3) { + r4 = r4 ^ r0; // s48 xor + r2 = rotr_var(r2, r0); // s49 rotr + r0 = mul_hi(r0, r5); // s50 mulhi + r7 = r7 | r5; // s51 or + r4 = r0 * r3 + r4; // s52 mad + r0 = rotr_var(r0, r4); // s53 rotr + r6 = r3 * r3 + r6; // s54 mad + r6 = r4 * r2 + r6; // s55 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 2u); r5 = r5 ^ t_; } // s56 shfl + r7 = rotl_imm(r7, 21u); // s57 rotl + r3 = r3 ^ r7; // s58 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 1u); r0 = r0 ^ t_; } // s59 shfl + r5 = r5 ^ r6; // s60 xor + r4 = rotr_var(r4, r7); // s61 rotr + r1 = r1 + r6 + ((((sel >> 10u) & 1u) != 0u) ? 0x31f87d74u : 0xf7ccf1e9u); // s62 add + r5 = r5 + r2 + ((((sel >> 15u) & 1u) != 0u) ? 0x9c2847f4u : 0x2f386099u); // s63 add + } + r1 = r1 ^ ds[r6 & mask]; // 21 load + // per-load shadow sub-block 4 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 4 + for (uint sh4 = 0u; sh4 < 27u; ++sh4) { + r7 = r7 + r0 + ((((sel >> 19u) & 1u) != 0u) ? 0xd3241188u : 0x1b30ce7au); // s64 add + r6 = r6 + r7 + ((((sel >> 13u) & 1u) != 0u) ? 0x9b42c3deu : 0x02dc8349u); // s65 add + r0 = rotl_imm(r0, 16u); // s66 rotl + r2 = rotl_imm(r2, 9u); // s67 rotl + r2 = r5 * r6 + r2; // s68 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 8u); r6 = r6 ^ t_; } // s69 shfl + r2 = r2 ^ r5; // s70 xor + r5 = mul_hi(r5, r1); // s71 mulhi + r6 = rotl_imm(r6, 29u); // s72 rotl + r0 = r0 - r7; // s73 sub + r5 = r2 * r2 + r5; // s74 mad + r0 = rotr_var(r0, r5); // s75 rotr + r7 = r7 + r2 + ((((sel >> 9u) & 1u) != 0u) ? 0x0da1ce17u : 0x05d36679u); // s76 add + r7 = r7 - r2; // s77 sub + r7 = rotr_var(r7, r0); // s78 rotr + r1 = r5 * r5 + r1; // s79 mad + } + r5 = r3 * r3 + r5; // 22 mad + r4 = r4 ^ ds[r7 & mask]; // 23 load + // per-load shadow sub-block 5 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 5 + for (uint sh5 = 0u; sh5 < 27u; ++sh5) { + r3 = rotr_var(r3, r0); // s80 rotr + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xadf5ef88u : 0xf14547bdu); // s81 add + r0 = r0 | r6; // s82 or + r1 = mul_hi(r1, r0); // s83 mulhi + r7 = r6 * r7 + r7; // s84 mad + r5 = rotl_imm(r5, 29u); // s85 rotl + r2 = r2 ^ r6; // s86 xor + r5 = r5 + r4 + ((((sel >> 24u) & 1u) != 0u) ? 0x35ff14aeu : 0xba4947c2u); // s87 add + r3 = r3 + r6 + ((((sel >> 3u) & 1u) != 0u) ? 0xf3900fc1u : 0xf6878beeu); // s88 add + r0 = r0 + r2 + ((((sel >> 12u) & 1u) != 0u) ? 0xf7e8f59fu : 0x926f3607u); // s89 add + r2 = r2 ^ r6; // s90 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 2u); r3 = r3 ^ t_; } // s91 shfl + r6 = r6 - r1; // s92 sub + r5 = r5 + r1 + ((((sel >> 13u) & 1u) != 0u) ? 0x0e376f9cu : 0xdab36c29u); // s93 add + r6 = r1 * r1 + r6; // s94 mad + r3 = r3 ^ r4; // s95 xor + } + r6 = r6 ^ ds[r4 & mask]; // 24 load + // per-load shadow sub-block 6 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 6 + for (uint sh6 = 0u; sh6 < 27u; ++sh6) { + r6 = r5 * r2 + r6; // s96 mad + r7 = r7 + r3 + ((((sel >> 23u) & 1u) != 0u) ? 0x9f917747u : 0x204129e9u); // s97 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 16u); r5 = r5 ^ t_; } // s98 shfl + r2 = r2 * r6; // s99 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r7 = r7 ^ t_; } // s100 shfl + r6 = r6 + r1 + ((((sel >> 10u) & 1u) != 0u) ? 0xe42fe974u : 0xe3b596a0u); // s101 add + r5 = rotl_imm(r5, 3u); // s102 rotl + r5 = r5 ^ r1; // s103 xor + r4 = r4 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0xc3d77ffbu : 0x705c3f94u); // s104 add + r0 = r0 + r6 + ((((sel >> 25u) & 1u) != 0u) ? 0xea02a4cau : 0xbc6fb42bu); // s105 add + r3 = r3 | r5; // s106 or + r0 = r0 - r6; // s107 sub + r0 = rotr_var(r0, r3); // s108 rotr + r5 = r5 + r4 + ((((sel >> 4u) & 1u) != 0u) ? 0x0357e63eu : 0xcb37ea87u); // s109 add + r7 = rotl_imm(r7, 5u); // s110 rotl + r4 = r4 ^ r1; // s111 xor + } + r5 = r5 * r7; // 25 mul + r0 = r0 * r3; // 26 mul + r0 = r0 | r3; // 27 or + r1 = r3 * r4 + r1; // 28 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r0 = r0 ^ t_; } // 29 shfl + r7 = r7 - r3; // 30 sub + r4 = r4 ^ r1; // 31 xor + r4 = r4 | r5; // 32 or + r3 = rotr_var(r3, r5); // 33 rotr + r4 = r4 ^ ds[r5 & mask]; // 34 load + // per-load shadow sub-block 7 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 7 + for (uint sh7 = 0u; sh7 < 27u; ++sh7) { + r6 = r6 ^ r5; // s112 xor + r1 = r1 | r3; // s113 or + r0 = r0 + r5 + ((((sel >> 3u) & 1u) != 0u) ? 0x7f8b8cd2u : 0x9aab0297u); // s114 add + r3 = r3 - r5; // s115 sub + r4 = rotr_var(r4, r2); // s116 rotr + r4 = r4 + r6 + ((((sel >> 6u) & 1u) != 0u) ? 0x59400b57u : 0xc511183fu); // s117 add + r6 = r6 - r1; // s118 sub + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r3 = r3 ^ t_; } // s119 shfl + r6 = r4 * r4 + r6; // s120 mad + r2 = rotl_imm(r2, 8u); // s121 rotl + r5 = r0 * r3 + r5; // s122 mad + r7 = r7 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x27c70dc0u : 0x5200c242u); // s123 add + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 4u); r3 = r3 ^ t_; } // s124 shfl + r0 = r0 + r1 + ((((sel >> 17u) & 1u) != 0u) ? 0xec2f5997u : 0x2d5028ceu); // s125 add + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 16u); r3 = r3 ^ t_; } // s126 shfl + r5 = r5 ^ r0; // s127 xor + } + r0 = r5 * r3 + r0; // 35 mad + r6 = r6 ^ ds[r3 & mask]; // 36 load + // per-load shadow sub-block 8 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 8 + for (uint sh8 = 0u; sh8 < 27u; ++sh8) { + r7 = r7 + r1 + ((((sel >> 10u) & 1u) != 0u) ? 0x09e8ede2u : 0x432f6c0du); // s128 add + r2 = r2 ^ r4; // s129 xor + r0 = r0 * r2; // s130 mul + r4 = r4 | r3; // s131 or + r3 = r3 | r7; // s132 or + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 1u); r7 = r7 ^ t_; } // s133 shfl + r5 = r5 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0xce4fdf8eu : 0xcf5ecc75u); // s134 add + r3 = r2 * r3 + r3; // s135 mad + r1 = rotl_imm(r1, 11u); // s136 rotl + r2 = r2 | r0; // s137 or + r3 = r3 ^ r4; // s138 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 1u); r2 = r2 ^ t_; } // s139 shfl + r2 = rotl_imm(r2, 6u); // s140 rotl + r0 = r0 * r3; // s141 mul + r1 = r1 * r7; // s142 mul + r0 = r0 ^ r1; // s143 xor + } + r5 = r5 * r3; // 37 mul + r5 = r5 ^ r4; // 38 xor + r6 = r6 ^ r0; // 39 xor + r4 = rotr_var(r4, r0); // 40 rotr + r7 = r7 ^ r6; // 41 xor + r1 = r1 ^ ds[r7 & mask]; // 42 load + // per-load shadow sub-block 9 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 9 + for (uint sh9 = 0u; sh9 < 27u; ++sh9) { + r6 = r2 * r0 + r6; // s144 mad + r1 = rotl_imm(r1, 15u); // s145 rotl + r1 = rotl_imm(r1, 30u); // s146 rotl + r6 = r6 ^ r0; // s147 xor + r3 = r3 - r2; // s148 sub + r3 = r3 + r0 + ((((sel >> 5u) & 1u) != 0u) ? 0x11bbdeefu : 0xaa002f15u); // s149 add + r6 = r6 + r5 + ((((sel >> 9u) & 1u) != 0u) ? 0xff9d4b0eu : 0xbe64b2e2u); // s150 add + r1 = r1 * r4; // s151 mul + r5 = rotl_imm(r5, 3u); // s152 rotl + r5 = r5 * r2; // s153 mul + r2 = rotl_imm(r2, 21u); // s154 rotl + r5 = rotl_imm(r5, 18u); // s155 rotl + r1 = r1 ^ r5; // s156 xor + r1 = mul_hi(r1, r6); // s157 mulhi + r4 = r7 * r3 + r4; // s158 mad + r4 = r4 - r7; // s159 sub + } + r2 = r2 - r4; // 43 sub + r6 = mul_hi(r6, r7); // 44 mulhi + r3 = rotl_imm(r3, 13u); // 45 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 16u); r7 = r7 ^ t_; } // 46 shfl + r2 = rotl_imm(r2, 26u); // 47 rotl + r6 = r6 * r2; // 48 mul + r2 = r2 ^ ds[r3 & mask]; // 49 load + // per-load shadow sub-block 10 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 10 + for (uint sh10 = 0u; sh10 < 27u; ++sh10) { + r3 = r3 ^ r2; // s160 xor + r3 = mul_hi(r3, r4); // s161 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 1u); r3 = r3 ^ t_; } // s162 shfl + r0 = r0 - r1; // s163 sub + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 8u); r6 = r6 ^ t_; } // s164 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 2u); r4 = r4 ^ t_; } // s165 shfl + r3 = r3 | r6; // s166 or + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r6 = r6 ^ t_; } // s167 shfl + r2 = r2 ^ r1; // s168 xor + r5 = r5 ^ r1; // s169 xor + r5 = r5 ^ r0; // s170 xor + r3 = r6 * r0 + r3; // s171 mad + r3 = r3 - r0; // s172 sub + r6 = r6 + r0 + ((((sel >> 27u) & 1u) != 0u) ? 0xc72dc2a0u : 0x3b90694bu); // s173 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r7 = r7 ^ t_; } // s174 shfl + r5 = mul_hi(r5, r2); // s175 mulhi + } + r5 = r5 ^ ds[r1 & mask]; // 50 load + // per-load shadow sub-block 11 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 11 + for (uint sh11 = 0u; sh11 < 27u; ++sh11) { + r3 = r3 + r6 + ((((sel >> 5u) & 1u) != 0u) ? 0x4eb75843u : 0x9e65cebdu); // s176 add + r0 = r4 * r1 + r0; // s177 mad + r6 = rotr_var(r6, r7); // s178 rotr + r0 = r0 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0x7001d036u : 0x01e5b250u); // s179 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 16u); r5 = r5 ^ t_; } // s180 shfl + r3 = r3 * r0; // s181 mul + r0 = rotl_imm(r0, 23u); // s182 rotl + r7 = mul_hi(r7, r0); // s183 mulhi + r0 = r0 * r4; // s184 mul + r1 = r1 + r4 + ((((sel >> 19u) & 1u) != 0u) ? 0x91736711u : 0xbef14988u); // s185 add + r7 = r7 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x15e0cdf3u : 0xf5d741beu); // s186 add + r1 = r1 ^ r7; // s187 xor + r1 = r1 + r3 + ((((sel >> 21u) & 1u) != 0u) ? 0x7549bc3eu : 0x32be33c6u); // s188 add + r1 = r0 * r6 + r1; // s189 mad + r0 = rotr_var(r0, r5); // s190 rotr + r4 = r0 * r1 + r4; // s191 mad + } + r0 = rotl_imm(r0, 20u); // 51 rotl + r1 = r1 ^ r2; // 52 xor + r2 = r2 ^ ds[r1 & mask]; // 53 load + // per-load shadow sub-block 12 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 12 + for (uint sh12 = 0u; sh12 < 27u; ++sh12) { + r3 = r6 * r1 + r3; // s192 mad + r6 = rotl_imm(r6, 31u); // s193 rotl + r5 = rotl_imm(r5, 28u); // s194 rotl + r4 = r4 * r3; // s195 mul + r2 = r2 + r3 + ((((sel >> 4u) & 1u) != 0u) ? 0x7c3d6253u : 0x9d7aebbbu); // s196 add + r3 = r3 | r5; // s197 or + r6 = r6 - r0; // s198 sub + r7 = r7 * r4; // s199 mul + r3 = rotr_var(r3, r2); // s200 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 16u); r4 = r4 ^ t_; } // s201 shfl + r7 = r7 ^ r3; // s202 xor + r4 = r4 | r3; // s203 or + r3 = rotr_var(r3, r6); // s204 rotr + r0 = rotr_var(r0, r1); // s205 rotr + r2 = r5 * r2 + r2; // s206 mad + r1 = mul_hi(r1, r5); // s207 mulhi + } + r4 = rotl_imm(r4, 20u); // 54 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r3 = r3 ^ t_; } // 55 shfl + r1 = r1 ^ ds[r0 & mask]; // 56 load + // per-load shadow sub-block 13 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 13 + for (uint sh13 = 0u; sh13 < 27u; ++sh13) { + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 1u); r4 = r4 ^ t_; } // s208 shfl + r7 = r5 * r7 + r7; // s209 mad + r6 = r6 ^ r3; // s210 xor + r3 = r3 ^ r2; // s211 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 16u); r5 = r5 ^ t_; } // s212 shfl + r4 = rotl_imm(r4, 10u); // s213 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 16u); r5 = r5 ^ t_; } // s214 shfl + r3 = r3 | r0; // s215 or + r4 = r4 * r5; // s216 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 16u); r0 = r0 ^ t_; } // s217 shfl + r0 = r0 * r5; // s218 mul + r0 = rotl_imm(r0, 13u); // s219 rotl + r1 = mul_hi(r1, r0); // s220 mulhi + r4 = r4 ^ r1; // s221 xor + r2 = r2 | r3; // s222 or + r0 = r0 ^ r4; // s223 xor + } + r3 = r3 ^ ds[r5 & mask]; // 57 load + // per-load shadow sub-block 14 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 14 + for (uint sh14 = 0u; sh14 < 27u; ++sh14) { + r5 = r6 * r1 + r5; // s224 mad + r4 = r4 ^ r3; // s225 xor + r5 = r5 + r0 + ((((sel >> 3u) & 1u) != 0u) ? 0xe4e51c75u : 0xfe960971u); // s226 add + r3 = mul_hi(r3, r2); // s227 mulhi + r2 = r2 ^ r6; // s228 xor + r1 = mul_hi(r1, r5); // s229 mulhi + r3 = r3 + r4 + ((((sel >> 25u) & 1u) != 0u) ? 0x4d597c08u : 0x48b3ce0au); // s230 add + r2 = rotr_var(r2, r3); // s231 rotr + r2 = r2 - r7; // s232 sub + r6 = r6 | r2; // s233 or + r0 = rotr_var(r0, r3); // s234 rotr + r4 = r4 + r3 + ((((sel >> 13u) & 1u) != 0u) ? 0xc9f1d54cu : 0x2ed8c878u); // s235 add + r0 = r3 * r7 + r0; // s236 mad + r3 = r3 + r5 + ((((sel >> 29u) & 1u) != 0u) ? 0xc572bd00u : 0x22e8b90au); // s237 add + r0 = mul_hi(r0, r4); // s238 mulhi + r6 = r6 * r5; // s239 mul + } + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 2u); r1 = r1 ^ t_; } // 58 shfl + r6 = r6 ^ ds[r4 & mask]; // 59 load + // per-load shadow sub-block 15 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 15 + for (uint sh15 = 0u; sh15 < 27u; ++sh15) { + r5 = r5 + r2 + ((((sel >> 20u) & 1u) != 0u) ? 0xb233f94fu : 0xc6b790e6u); // s240 add + r0 = r0 - r3; // s241 sub + r4 = r4 + r7 + ((((sel >> 4u) & 1u) != 0u) ? 0x534d924bu : 0x0f918d3bu); // s242 add + r5 = rotr_var(r5, r0); // s243 rotr + r1 = rotr_var(r1, r7); // s244 rotr + r2 = r2 | r0; // s245 or + r4 = r4 * r7; // s246 mul + r1 = r2 * r5 + r1; // s247 mad + r2 = r2 * r5; // s248 mul + r4 = r4 ^ r2; // s249 xor + r3 = r3 ^ r1; // s250 xor + r5 = rotr_var(r5, r7); // s251 rotr + r2 = r7 * r7 + r2; // s252 mad + r7 = rotr_var(r7, r3); // s253 rotr + r6 = r6 + r1 + ((((sel >> 21u) & 1u) != 0u) ? 0x86d27169u : 0xb8a27d95u); // s254 add + r6 = r6 | r7; // s255 or + } + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r7 = r7 ^ t_; } // 60 shfl + r5 = rotr_var(r5, r0); // 61 rotr + r0 = r0 + r6 + ((((sel >> 14u) & 1u) != 0u) ? 0xb13a5391u : 0x8c2e5c24u); // 62 add + r2 = r2 + r1 + ((((sel >> 21u) & 1u) != 0u) ? 0xf82fc8b5u : 0xb225b762u); // 63 add + } + uint lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((ulong)hi << 32) | (ulong)lo; +} + +#if IGNEUM_EXCHANGE != 0 +// Reports the sub-group size this device uses for a work-group of IGNEUM_GROUP items. host.c runs it only when the +// per-kernel query (clGetKernelSubGroupInfoKHR on igneum_hash) is unavailable; that query is preferred because a +// compiler may pick a different wave width per kernel (RDNA: wave32 or wave64). See WAVEFRONT.md. +IGNEUM_KERNEL_HASH void igneum_probe_subgroup(__global uint* out) { + if (get_local_id(0) == 0u) { out[0] = get_sub_group_size(); out[1] = get_num_sub_groups(); } +} +#endif diff --git a/proto-cuda/packs-ca4/mx8_shl256x27_v2/kernel.cu b/proto-cuda/packs-ca4/mx8_shl256x27_v2/kernel.cu new file mode 100644 index 000000000..c68c11857 --- /dev/null +++ b/proto-cuda/packs-ca4/mx8_shl256x27_v2/kernel.cu @@ -0,0 +1,468 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Bit-exact twin of the Metal kernel for the same seed (see proto-cuda/CHECKLIST.md and program.metal). +// Compiled ahead of time by nvcc together with proto-cuda/host.cu. No NVRTC. +#include +#include +#include "program.h" +#include "memhard.h" + +__device__ __forceinline__ uint32_t splitmix32(uint32_t x) { + x ^= x >> 16; x *= 0x7feb352du; + x ^= x >> 15; x *= 0x846ca68bu; + x ^= x >> 16; + return x; +} +// n is a literal in 1..31 at every call site, so both shift amounts are in 1..31. +__device__ __forceinline__ uint32_t rotl_imm(uint32_t x, uint32_t n) { return (x << n) | (x >> (32u - n)); } +// n is masked to 0..31; the second shift amount is masked too, so n == 0 gives x. +__device__ __forceinline__ uint32_t rotr_var(uint32_t x, uint32_t n) { n &= 31u; return (x >> n) | (x << ((32u - n) & 31u)); } +__device__ __forceinline__ uint32_t ds_elem(uint32_t i, uint32_t d0, uint32_t d1) { + uint32_t x = i ^ d0; + x *= 0x9E3779B1u; x ^= x >> 15; + x += d1; + x *= 0x85EBCA77u; x ^= x >> 13; + x *= 0xC2B2AE3Du; x ^= x >> 16; + return x; +} + +// Memory-hard dataset (MEMHARD.md). One thread per cache segment; one thread per 64-byte dataset item. +// The core functions (mh_cache_segment, mh_item) are in memhard.h and are also compiled for the host. +__global__ void igneum_cache_fill(uint32_t* cache, uint32_t nSegments) { + uint32_t seg = blockIdx.x * blockDim.x + threadIdx.x; + if (seg < nSegments) mh_cache_segment(cache, seg); +} +__global__ void igneum_build(uint32_t* ds, const uint32_t* cache, uint32_t nItems) { + uint32_t t = blockIdx.x * blockDim.x + threadIdx.x; + if (t < nItems) { + uint32_t s[16]; + mh_item(cache, t, s); + uint32_t* d = ds + (size_t)t * 16u; + for (uint32_t i = 0u; i < 16u; ++i) d[i] = s[i]; + } +} + +// One hash per thread. blockDim.x is a multiple of 32; lane = threadIdx.x & 31 and every +// __shfl_xor_sync stays inside the lane's own warp, exactly like simd_shuffle_xor inside a +// 32-wide Metal SIMD group. Control flow is uniform, so the full 0xffffffff member mask is valid. +__global__ void igneum_hash(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask) { + uint32_t gid = blockIdx.x * blockDim.x + threadIdx.x; + uint32_t nonce = baseNonce + gid; + uint32_t r0, r1, r2, r3, r4, r5, r6, r7; + { uint32_t x = nonce ^ 0xf71aee9fu; x += 0x9e3779b9u; x = splitmix32(x); r0 = x ^ 0xad930c88u; } // SEEDW[0], 0x9e3779b9u * 1u, SEEDW[1] + { uint32_t x = nonce ^ 0xad930c88u; x += 0x3c6ef372u; x = splitmix32(x); r1 = x ^ 0x7f982573u; } // SEEDW[1], 0x9e3779b9u * 2u, SEEDW[2] + { uint32_t x = nonce ^ 0x7f982573u; x += 0xdaa66d2bu; x = splitmix32(x); r2 = x ^ 0xa41f9137u; } // SEEDW[2], 0x9e3779b9u * 3u, SEEDW[3] + { uint32_t x = nonce ^ 0xa41f9137u; x += 0x78dde6e4u; x = splitmix32(x); r3 = x ^ 0x76d803d6u; } // SEEDW[3], 0x9e3779b9u * 4u, SEEDW[4] + { uint32_t x = nonce ^ 0x76d803d6u; x += 0x1715609du; x = splitmix32(x); r4 = x ^ 0x37b4a534u; } // SEEDW[4], 0x9e3779b9u * 5u, SEEDW[5] + { uint32_t x = nonce ^ 0x37b4a534u; x += 0xb54cda56u; x = splitmix32(x); r5 = x ^ 0x4d3fb826u; } // SEEDW[5], 0x9e3779b9u * 6u, SEEDW[6] + { uint32_t x = nonce ^ 0x4d3fb826u; x += 0x5384540fu; x = splitmix32(x); r6 = x ^ 0xff614dcbu; } // SEEDW[6], 0x9e3779b9u * 7u, SEEDW[7] + { uint32_t x = nonce ^ 0xff614dcbu; x += 0xf1bbcdc8u; x = splitmix32(x); r7 = x ^ 0xf71aee9fu; } // SEEDW[7], 0x9e3779b9u * 8u, SEEDW[0] + + for (uint32_t it = 0u; it < 8u; ++it) { + uint32_t sel = r0; + r2 = r2 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0x894e457du : 0xe3e2ed7du); // 0 add + r7 = r4 * r0 + r7; // 1 mad + r3 = r3 - r6; // 2 sub + r5 = rotr_var(r5, r1); // 3 rotr + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r2, 1); // 4 shfl + r0 = r0 | r3; // 5 or + r0 = r0 * r1; // 6 mul + r7 = r7 * r6; // 7 mul + r3 = r3 ^ ds[r0 & mask]; // 8 load + // per-load shadow sub-block 0 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 0 + for (uint32_t sh0 = 0u; sh0 < 27u; ++sh0) { + r5 = rotr_var(r5, r4); // s0 rotr + r6 = r6 - r5; // s1 sub + r7 = r7 - r6; // s2 sub + r5 = r5 * r4; // s3 mul + r7 = r7 ^ r6; // s4 xor + r2 = rotl_imm(r2, 23u); // s5 rotl + r7 = r7 ^ r4; // s6 xor + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x3051c491u : 0xdaef8862u); // s7 add + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r1, 4); // s8 shfl + r5 = r5 + r1 + ((((sel >> 26u) & 1u) != 0u) ? 0x5170d0b3u : 0xc20e7045u); // s9 add + r0 = r0 | r3; // s10 or + r5 = __umulhi(r5, r4); // s11 mulhi + r7 = r7 ^ r0; // s12 xor + r5 = r5 - r2; // s13 sub + r0 = r0 + r6 + ((((sel >> 0u) & 1u) != 0u) ? 0x2ead087fu : 0xc86d98a4u); // s14 add + r5 = r5 ^ r7; // s15 xor + } + r4 = r4 + r3 + ((((sel >> 22u) & 1u) != 0u) ? 0xd26d3573u : 0xce9bea84u); // 9 add + r2 = r2 * r4; // 10 mul + r3 = r3 ^ ds[r2 & mask]; // 11 load + // per-load shadow sub-block 1 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 1 + for (uint32_t sh1 = 0u; sh1 < 27u; ++sh1) { + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r6, 8); // s16 shfl + r5 = r5 - r7; // s17 sub + r0 = r0 | r6; // s18 or + r0 = r0 + r5 + ((((sel >> 13u) & 1u) != 0u) ? 0xc47c70a8u : 0x4248b651u); // s19 add + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r5, 16); // s20 shfl + r0 = r0 + r4 + ((((sel >> 21u) & 1u) != 0u) ? 0x718c1008u : 0x1e35684fu); // s21 add + r0 = __umulhi(r0, r3); // s22 mulhi + r4 = r4 ^ r2; // s23 xor + r0 = r0 - r2; // s24 sub + r5 = rotl_imm(r5, 13u); // s25 rotl + r7 = r7 - r0; // s26 sub + r2 = r2 ^ r3; // s27 xor + r2 = r3 * r2 + r2; // s28 mad + r2 = r2 ^ r1; // s29 xor + r4 = __umulhi(r4, r0); // s30 mulhi + r6 = r6 ^ r4; // s31 xor + } + r4 = __umulhi(r4, r1); // 12 mulhi + r7 = __umulhi(r7, r3); // 13 mulhi + r3 = r3 + r2 + ((((sel >> 8u) & 1u) != 0u) ? 0xc2828a42u : 0x514f9ff4u); // 14 add + r1 = r3 * r2 + r1; // 15 mad + r2 = rotl_imm(r2, 7u); // 16 rotl + r1 = r1 ^ ds[r2 & mask]; // 17 load + // per-load shadow sub-block 2 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 2 + for (uint32_t sh2 = 0u; sh2 < 27u; ++sh2) { + r4 = r4 ^ r2; // s32 xor + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r2, 1); // s33 shfl + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r6, 1); // s34 shfl + r4 = r4 - r0; // s35 sub + r6 = r6 - r3; // s36 sub + r2 = r2 | r6; // s37 or + r2 = rotl_imm(r2, 30u); // s38 rotl + r4 = rotr_var(r4, r7); // s39 rotr + r0 = r0 | r7; // s40 or + r2 = rotr_var(r2, r5); // s41 rotr + r1 = r3 * r3 + r1; // s42 mad + r6 = r5 * r5 + r6; // s43 mad + r1 = __umulhi(r1, r0); // s44 mulhi + r1 = r1 * r3; // s45 mul + r0 = r2 * r0 + r0; // s46 mad + r1 = r1 - r5; // s47 sub + } + r3 = r3 * r2; // 18 mul + r6 = rotl_imm(r6, 24u); // 19 rotl + r6 = r6 ^ ds[r3 & mask]; // 20 load + // per-load shadow sub-block 3 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 3 + for (uint32_t sh3 = 0u; sh3 < 27u; ++sh3) { + r4 = r4 ^ r0; // s48 xor + r2 = rotr_var(r2, r0); // s49 rotr + r0 = __umulhi(r0, r5); // s50 mulhi + r7 = r7 | r5; // s51 or + r4 = r0 * r3 + r4; // s52 mad + r0 = rotr_var(r0, r4); // s53 rotr + r6 = r3 * r3 + r6; // s54 mad + r6 = r4 * r2 + r6; // s55 mad + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r0, 2); // s56 shfl + r7 = rotl_imm(r7, 21u); // s57 rotl + r3 = r3 ^ r7; // s58 xor + r0 = r0 ^ __shfl_xor_sync(0xffffffffu, r4, 1); // s59 shfl + r5 = r5 ^ r6; // s60 xor + r4 = rotr_var(r4, r7); // s61 rotr + r1 = r1 + r6 + ((((sel >> 10u) & 1u) != 0u) ? 0x31f87d74u : 0xf7ccf1e9u); // s62 add + r5 = r5 + r2 + ((((sel >> 15u) & 1u) != 0u) ? 0x9c2847f4u : 0x2f386099u); // s63 add + } + r1 = r1 ^ ds[r6 & mask]; // 21 load + // per-load shadow sub-block 4 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 4 + for (uint32_t sh4 = 0u; sh4 < 27u; ++sh4) { + r7 = r7 + r0 + ((((sel >> 19u) & 1u) != 0u) ? 0xd3241188u : 0x1b30ce7au); // s64 add + r6 = r6 + r7 + ((((sel >> 13u) & 1u) != 0u) ? 0x9b42c3deu : 0x02dc8349u); // s65 add + r0 = rotl_imm(r0, 16u); // s66 rotl + r2 = rotl_imm(r2, 9u); // s67 rotl + r2 = r5 * r6 + r2; // s68 mad + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r1, 8); // s69 shfl + r2 = r2 ^ r5; // s70 xor + r5 = __umulhi(r5, r1); // s71 mulhi + r6 = rotl_imm(r6, 29u); // s72 rotl + r0 = r0 - r7; // s73 sub + r5 = r2 * r2 + r5; // s74 mad + r0 = rotr_var(r0, r5); // s75 rotr + r7 = r7 + r2 + ((((sel >> 9u) & 1u) != 0u) ? 0x0da1ce17u : 0x05d36679u); // s76 add + r7 = r7 - r2; // s77 sub + r7 = rotr_var(r7, r0); // s78 rotr + r1 = r5 * r5 + r1; // s79 mad + } + r5 = r3 * r3 + r5; // 22 mad + r4 = r4 ^ ds[r7 & mask]; // 23 load + // per-load shadow sub-block 5 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 5 + for (uint32_t sh5 = 0u; sh5 < 27u; ++sh5) { + r3 = rotr_var(r3, r0); // s80 rotr + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xadf5ef88u : 0xf14547bdu); // s81 add + r0 = r0 | r6; // s82 or + r1 = __umulhi(r1, r0); // s83 mulhi + r7 = r6 * r7 + r7; // s84 mad + r5 = rotl_imm(r5, 29u); // s85 rotl + r2 = r2 ^ r6; // s86 xor + r5 = r5 + r4 + ((((sel >> 24u) & 1u) != 0u) ? 0x35ff14aeu : 0xba4947c2u); // s87 add + r3 = r3 + r6 + ((((sel >> 3u) & 1u) != 0u) ? 0xf3900fc1u : 0xf6878beeu); // s88 add + r0 = r0 + r2 + ((((sel >> 12u) & 1u) != 0u) ? 0xf7e8f59fu : 0x926f3607u); // s89 add + r2 = r2 ^ r6; // s90 xor + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r2, 2); // s91 shfl + r6 = r6 - r1; // s92 sub + r5 = r5 + r1 + ((((sel >> 13u) & 1u) != 0u) ? 0x0e376f9cu : 0xdab36c29u); // s93 add + r6 = r1 * r1 + r6; // s94 mad + r3 = r3 ^ r4; // s95 xor + } + r6 = r6 ^ ds[r4 & mask]; // 24 load + // per-load shadow sub-block 6 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 6 + for (uint32_t sh6 = 0u; sh6 < 27u; ++sh6) { + r6 = r5 * r2 + r6; // s96 mad + r7 = r7 + r3 + ((((sel >> 23u) & 1u) != 0u) ? 0x9f917747u : 0x204129e9u); // s97 add + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r1, 16); // s98 shfl + r2 = r2 * r6; // s99 mul + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r3, 8); // s100 shfl + r6 = r6 + r1 + ((((sel >> 10u) & 1u) != 0u) ? 0xe42fe974u : 0xe3b596a0u); // s101 add + r5 = rotl_imm(r5, 3u); // s102 rotl + r5 = r5 ^ r1; // s103 xor + r4 = r4 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0xc3d77ffbu : 0x705c3f94u); // s104 add + r0 = r0 + r6 + ((((sel >> 25u) & 1u) != 0u) ? 0xea02a4cau : 0xbc6fb42bu); // s105 add + r3 = r3 | r5; // s106 or + r0 = r0 - r6; // s107 sub + r0 = rotr_var(r0, r3); // s108 rotr + r5 = r5 + r4 + ((((sel >> 4u) & 1u) != 0u) ? 0x0357e63eu : 0xcb37ea87u); // s109 add + r7 = rotl_imm(r7, 5u); // s110 rotl + r4 = r4 ^ r1; // s111 xor + } + r5 = r5 * r7; // 25 mul + r0 = r0 * r3; // 26 mul + r0 = r0 | r3; // 27 or + r1 = r3 * r4 + r1; // 28 mad + r0 = r0 ^ __shfl_xor_sync(0xffffffffu, r2, 8); // 29 shfl + r7 = r7 - r3; // 30 sub + r4 = r4 ^ r1; // 31 xor + r4 = r4 | r5; // 32 or + r3 = rotr_var(r3, r5); // 33 rotr + r4 = r4 ^ ds[r5 & mask]; // 34 load + // per-load shadow sub-block 7 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 7 + for (uint32_t sh7 = 0u; sh7 < 27u; ++sh7) { + r6 = r6 ^ r5; // s112 xor + r1 = r1 | r3; // s113 or + r0 = r0 + r5 + ((((sel >> 3u) & 1u) != 0u) ? 0x7f8b8cd2u : 0x9aab0297u); // s114 add + r3 = r3 - r5; // s115 sub + r4 = rotr_var(r4, r2); // s116 rotr + r4 = r4 + r6 + ((((sel >> 6u) & 1u) != 0u) ? 0x59400b57u : 0xc511183fu); // s117 add + r6 = r6 - r1; // s118 sub + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r1, 4); // s119 shfl + r6 = r4 * r4 + r6; // s120 mad + r2 = rotl_imm(r2, 8u); // s121 rotl + r5 = r0 * r3 + r5; // s122 mad + r7 = r7 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x27c70dc0u : 0x5200c242u); // s123 add + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r5, 4); // s124 shfl + r0 = r0 + r1 + ((((sel >> 17u) & 1u) != 0u) ? 0xec2f5997u : 0x2d5028ceu); // s125 add + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r6, 16); // s126 shfl + r5 = r5 ^ r0; // s127 xor + } + r0 = r5 * r3 + r0; // 35 mad + r6 = r6 ^ ds[r3 & mask]; // 36 load + // per-load shadow sub-block 8 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 8 + for (uint32_t sh8 = 0u; sh8 < 27u; ++sh8) { + r7 = r7 + r1 + ((((sel >> 10u) & 1u) != 0u) ? 0x09e8ede2u : 0x432f6c0du); // s128 add + r2 = r2 ^ r4; // s129 xor + r0 = r0 * r2; // s130 mul + r4 = r4 | r3; // s131 or + r3 = r3 | r7; // s132 or + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r3, 1); // s133 shfl + r5 = r5 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0xce4fdf8eu : 0xcf5ecc75u); // s134 add + r3 = r2 * r3 + r3; // s135 mad + r1 = rotl_imm(r1, 11u); // s136 rotl + r2 = r2 | r0; // s137 or + r3 = r3 ^ r4; // s138 xor + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 1); // s139 shfl + r2 = rotl_imm(r2, 6u); // s140 rotl + r0 = r0 * r3; // s141 mul + r1 = r1 * r7; // s142 mul + r0 = r0 ^ r1; // s143 xor + } + r5 = r5 * r3; // 37 mul + r5 = r5 ^ r4; // 38 xor + r6 = r6 ^ r0; // 39 xor + r4 = rotr_var(r4, r0); // 40 rotr + r7 = r7 ^ r6; // 41 xor + r1 = r1 ^ ds[r7 & mask]; // 42 load + // per-load shadow sub-block 9 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 9 + for (uint32_t sh9 = 0u; sh9 < 27u; ++sh9) { + r6 = r2 * r0 + r6; // s144 mad + r1 = rotl_imm(r1, 15u); // s145 rotl + r1 = rotl_imm(r1, 30u); // s146 rotl + r6 = r6 ^ r0; // s147 xor + r3 = r3 - r2; // s148 sub + r3 = r3 + r0 + ((((sel >> 5u) & 1u) != 0u) ? 0x11bbdeefu : 0xaa002f15u); // s149 add + r6 = r6 + r5 + ((((sel >> 9u) & 1u) != 0u) ? 0xff9d4b0eu : 0xbe64b2e2u); // s150 add + r1 = r1 * r4; // s151 mul + r5 = rotl_imm(r5, 3u); // s152 rotl + r5 = r5 * r2; // s153 mul + r2 = rotl_imm(r2, 21u); // s154 rotl + r5 = rotl_imm(r5, 18u); // s155 rotl + r1 = r1 ^ r5; // s156 xor + r1 = __umulhi(r1, r6); // s157 mulhi + r4 = r7 * r3 + r4; // s158 mad + r4 = r4 - r7; // s159 sub + } + r2 = r2 - r4; // 43 sub + r6 = __umulhi(r6, r7); // 44 mulhi + r3 = rotl_imm(r3, 13u); // 45 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r6, 16); // 46 shfl + r2 = rotl_imm(r2, 26u); // 47 rotl + r6 = r6 * r2; // 48 mul + r2 = r2 ^ ds[r3 & mask]; // 49 load + // per-load shadow sub-block 10 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 10 + for (uint32_t sh10 = 0u; sh10 < 27u; ++sh10) { + r3 = r3 ^ r2; // s160 xor + r3 = __umulhi(r3, r4); // s161 mulhi + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r2, 1); // s162 shfl + r0 = r0 - r1; // s163 sub + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r0, 8); // s164 shfl + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r2, 2); // s165 shfl + r3 = r3 | r6; // s166 or + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r3, 4); // s167 shfl + r2 = r2 ^ r1; // s168 xor + r5 = r5 ^ r1; // s169 xor + r5 = r5 ^ r0; // s170 xor + r3 = r6 * r0 + r3; // s171 mad + r3 = r3 - r0; // s172 sub + r6 = r6 + r0 + ((((sel >> 27u) & 1u) != 0u) ? 0xc72dc2a0u : 0x3b90694bu); // s173 add + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r2, 8); // s174 shfl + r5 = __umulhi(r5, r2); // s175 mulhi + } + r5 = r5 ^ ds[r1 & mask]; // 50 load + // per-load shadow sub-block 11 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 11 + for (uint32_t sh11 = 0u; sh11 < 27u; ++sh11) { + r3 = r3 + r6 + ((((sel >> 5u) & 1u) != 0u) ? 0x4eb75843u : 0x9e65cebdu); // s176 add + r0 = r4 * r1 + r0; // s177 mad + r6 = rotr_var(r6, r7); // s178 rotr + r0 = r0 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0x7001d036u : 0x01e5b250u); // s179 add + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r2, 16); // s180 shfl + r3 = r3 * r0; // s181 mul + r0 = rotl_imm(r0, 23u); // s182 rotl + r7 = __umulhi(r7, r0); // s183 mulhi + r0 = r0 * r4; // s184 mul + r1 = r1 + r4 + ((((sel >> 19u) & 1u) != 0u) ? 0x91736711u : 0xbef14988u); // s185 add + r7 = r7 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x15e0cdf3u : 0xf5d741beu); // s186 add + r1 = r1 ^ r7; // s187 xor + r1 = r1 + r3 + ((((sel >> 21u) & 1u) != 0u) ? 0x7549bc3eu : 0x32be33c6u); // s188 add + r1 = r0 * r6 + r1; // s189 mad + r0 = rotr_var(r0, r5); // s190 rotr + r4 = r0 * r1 + r4; // s191 mad + } + r0 = rotl_imm(r0, 20u); // 51 rotl + r1 = r1 ^ r2; // 52 xor + r2 = r2 ^ ds[r1 & mask]; // 53 load + // per-load shadow sub-block 12 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 12 + for (uint32_t sh12 = 0u; sh12 < 27u; ++sh12) { + r3 = r6 * r1 + r3; // s192 mad + r6 = rotl_imm(r6, 31u); // s193 rotl + r5 = rotl_imm(r5, 28u); // s194 rotl + r4 = r4 * r3; // s195 mul + r2 = r2 + r3 + ((((sel >> 4u) & 1u) != 0u) ? 0x7c3d6253u : 0x9d7aebbbu); // s196 add + r3 = r3 | r5; // s197 or + r6 = r6 - r0; // s198 sub + r7 = r7 * r4; // s199 mul + r3 = rotr_var(r3, r2); // s200 rotr + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r0, 16); // s201 shfl + r7 = r7 ^ r3; // s202 xor + r4 = r4 | r3; // s203 or + r3 = rotr_var(r3, r6); // s204 rotr + r0 = rotr_var(r0, r1); // s205 rotr + r2 = r5 * r2 + r2; // s206 mad + r1 = __umulhi(r1, r5); // s207 mulhi + } + r4 = rotl_imm(r4, 20u); // 54 rotl + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // 55 shfl + r1 = r1 ^ ds[r0 & mask]; // 56 load + // per-load shadow sub-block 13 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 13 + for (uint32_t sh13 = 0u; sh13 < 27u; ++sh13) { + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r3, 1); // s208 shfl + r7 = r5 * r7 + r7; // s209 mad + r6 = r6 ^ r3; // s210 xor + r3 = r3 ^ r2; // s211 xor + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r6, 16); // s212 shfl + r4 = rotl_imm(r4, 10u); // s213 rotl + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r6, 16); // s214 shfl + r3 = r3 | r0; // s215 or + r4 = r4 * r5; // s216 mul + r0 = r0 ^ __shfl_xor_sync(0xffffffffu, r3, 16); // s217 shfl + r0 = r0 * r5; // s218 mul + r0 = rotl_imm(r0, 13u); // s219 rotl + r1 = __umulhi(r1, r0); // s220 mulhi + r4 = r4 ^ r1; // s221 xor + r2 = r2 | r3; // s222 or + r0 = r0 ^ r4; // s223 xor + } + r3 = r3 ^ ds[r5 & mask]; // 57 load + // per-load shadow sub-block 14 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 14 + for (uint32_t sh14 = 0u; sh14 < 27u; ++sh14) { + r5 = r6 * r1 + r5; // s224 mad + r4 = r4 ^ r3; // s225 xor + r5 = r5 + r0 + ((((sel >> 3u) & 1u) != 0u) ? 0xe4e51c75u : 0xfe960971u); // s226 add + r3 = __umulhi(r3, r2); // s227 mulhi + r2 = r2 ^ r6; // s228 xor + r1 = __umulhi(r1, r5); // s229 mulhi + r3 = r3 + r4 + ((((sel >> 25u) & 1u) != 0u) ? 0x4d597c08u : 0x48b3ce0au); // s230 add + r2 = rotr_var(r2, r3); // s231 rotr + r2 = r2 - r7; // s232 sub + r6 = r6 | r2; // s233 or + r0 = rotr_var(r0, r3); // s234 rotr + r4 = r4 + r3 + ((((sel >> 13u) & 1u) != 0u) ? 0xc9f1d54cu : 0x2ed8c878u); // s235 add + r0 = r3 * r7 + r0; // s236 mad + r3 = r3 + r5 + ((((sel >> 29u) & 1u) != 0u) ? 0xc572bd00u : 0x22e8b90au); // s237 add + r0 = __umulhi(r0, r4); // s238 mulhi + r6 = r6 * r5; // s239 mul + } + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r2, 2); // 58 shfl + r6 = r6 ^ ds[r4 & mask]; // 59 load + // per-load shadow sub-block 15 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 15 + for (uint32_t sh15 = 0u; sh15 < 27u; ++sh15) { + r5 = r5 + r2 + ((((sel >> 20u) & 1u) != 0u) ? 0xb233f94fu : 0xc6b790e6u); // s240 add + r0 = r0 - r3; // s241 sub + r4 = r4 + r7 + ((((sel >> 4u) & 1u) != 0u) ? 0x534d924bu : 0x0f918d3bu); // s242 add + r5 = rotr_var(r5, r0); // s243 rotr + r1 = rotr_var(r1, r7); // s244 rotr + r2 = r2 | r0; // s245 or + r4 = r4 * r7; // s246 mul + r1 = r2 * r5 + r1; // s247 mad + r2 = r2 * r5; // s248 mul + r4 = r4 ^ r2; // s249 xor + r3 = r3 ^ r1; // s250 xor + r5 = rotr_var(r5, r7); // s251 rotr + r2 = r7 * r7 + r2; // s252 mad + r7 = rotr_var(r7, r3); // s253 rotr + r6 = r6 + r1 + ((((sel >> 21u) & 1u) != 0u) ? 0x86d27169u : 0xb8a27d95u); // s254 add + r6 = r6 | r7; // s255 or + } + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r3, 4); // 60 shfl + r5 = rotr_var(r5, r0); // 61 rotr + r0 = r0 + r6 + ((((sel >> 14u) & 1u) != 0u) ? 0xb13a5391u : 0x8c2e5c24u); // 62 add + r2 = r2 + r1 + ((((sel >> 21u) & 1u) != 0u) ? 0xf82fc8b5u : 0xb225b762u); // 63 add + } + uint32_t lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint32_t hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((uint64_t)hi << 32) | (uint64_t)lo; +} + +// Host-side launch wrappers. Declared in program.h, called from host.cu. +cudaError_t igneum_launch_cache_fill(uint32_t* cache, uint32_t nSegments) { + if (nSegments == 0u) return cudaErrorInvalidValue; + uint32_t block = 256u; + uint32_t grid = (nSegments + block - 1u) / block; + igneum_cache_fill<<>>(cache, nSegments); + return cudaGetLastError(); +} + +cudaError_t igneum_launch_build(uint32_t* ds, const uint32_t* cache, uint32_t nItems) { + if (nItems == 0u) return cudaErrorInvalidValue; + uint32_t block = 256u; + uint32_t grid = (nItems + block - 1u) / block; + igneum_build<<>>(ds, cache, nItems); + return cudaGetLastError(); +} + +cudaError_t igneum_launch_hash(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, + uint32_t nonces, uint32_t blockWarps) { + if (blockWarps == 0u || blockWarps > 32u) return cudaErrorInvalidValue; + uint32_t block = 32u * blockWarps; + if (nonces == 0u || (nonces % block) != 0u) return cudaErrorInvalidValue; + igneum_hash<<>>(ds, out, baseNonce, mask); + return cudaGetLastError(); +} + +cudaError_t igneum_hash_info(int* numRegs, int* blocksPerSM, uint32_t blockWarps) { + cudaFuncAttributes attr; + cudaError_t e = cudaFuncGetAttributes(&attr, igneum_hash); + if (e != cudaSuccess) return e; + *numRegs = attr.numRegs; + return cudaOccupancyMaxActiveBlocksPerMultiprocessor(blocksPerSM, igneum_hash, (int)(32u * blockWarps), 0); +} diff --git a/proto-cuda/packs-ca4/mx8_shl256x27_v2/kernel_bound.cl b/proto-cuda/packs-ca4/mx8_shl256x27_v2/kernel_bound.cl new file mode 100644 index 000000000..d3808563f --- /dev/null +++ b/proto-cuda/packs-ca4/mx8_shl256x27_v2/kernel_bound.cl @@ -0,0 +1,981 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// OpenCL C twin of the Metal kernel for the same seed (see proto-opencl/README.md, WAVEFRONT.md and program.metal). +// Built from source at runtime by proto-opencl/host.c, which passes these defines: +// IGNEUM_GROUP work-group size of igneum_hash, a multiple of 32 (default 32: one work-group = one 32-lane unit) +// IGNEUM_EXCHANGE 0 = local-memory exchange with a barrier (any device, any wave width; the default) +// 1 = sub_group_shuffle_xor (cl_khr_subgroup_shuffle), only with IGNEUM_GROUP 32 and a sub-group size of exactly 32 +// 2 = intel_sub_group_shuffle_xor (cl_intel_subgroups), same condition +// The verification unit is always 32 lanes. A 64-wide hardware wave (AMD GCN/CDNA, RDNA in wave64) runs two units; +// the exchange masks are 1, 2, 4, 8, 16, so every partner lane lies inside the lane's own aligned run of 32. +#ifndef IGNEUM_GROUP +#define IGNEUM_GROUP 32 +#endif +#ifndef IGNEUM_EXCHANGE +#define IGNEUM_EXCHANGE 0 +#endif +#ifdef __OPENCL_VERSION__ +#define IGNEUM_KERNEL_HASH __kernel __attribute__((reqd_work_group_size(IGNEUM_GROUP, 1, 1))) +#define IGNEUM_LOCAL_WORDS(name, n) __local uint name[n] +#if IGNEUM_EXCHANGE == 1 +#ifdef cl_khr_subgroups +#pragma OPENCL EXTENSION cl_khr_subgroups : enable +#endif +#ifdef cl_khr_subgroup_shuffle +#pragma OPENCL EXTENSION cl_khr_subgroup_shuffle : enable +#endif +#elif IGNEUM_EXCHANGE == 2 +#pragma OPENCL EXTENSION cl_intel_subgroups : enable +#endif +#else +// Not an OpenCL compiler: proto-opencl/emu compiles this file as C++ and supplies the built-ins and these two macros. +#include "emu_opencl.h" +#endif + +#if IGNEUM_EXCHANGE == 1 +#define IGNEUM_SHFL_XOR(dst, a, m) dst = sub_group_shuffle_xor((a), (uint)(m)) +#define IGNEUM_BCAST0(dst, a) dst = sub_group_broadcast((a), 0u) +#elif IGNEUM_EXCHANGE == 2 +#define IGNEUM_SHFL_XOR(dst, a, m) dst = intel_sub_group_shuffle_xor((a), (uint)(m)) +#define IGNEUM_BCAST0(dst, a) dst = sub_group_broadcast((a), 0u) +#else +// Local-memory exchange. Two buffers of IGNEUM_GROUP words alternate (xk counts exchanges), so one barrier per +// exchange is enough: a lane can only overwrite buffer b at exchange k+2 after passing barrier k+1, and every lane +// reaches barrier k+1 only after its read of buffer b at exchange k. The partner lid ^ m stays inside the lane's +// aligned run of 32 because m < 32. Control flow is uniform, so every work-item reaches every barrier. +#define IGNEUM_SHFL_XOR(dst, a, m) { xch[(xk & 1u) * IGNEUM_GROUP + lid] = (a); barrier(CLK_LOCAL_MEM_FENCE); dst = xch[(xk & 1u) * IGNEUM_GROUP + (lid ^ (uint)(m))]; xk += 1u; } +#define IGNEUM_BCAST0(dst, a) { xch[(xk & 1u) * IGNEUM_GROUP + lid] = (a); barrier(CLK_LOCAL_MEM_FENCE); dst = xch[(xk & 1u) * IGNEUM_GROUP + (lid & ~31u)]; xk += 1u; } +#endif + +static inline uint splitmix32(uint x) { + x ^= x >> 16; x *= 0x7feb352du; + x ^= x >> 15; x *= 0x846ca68bu; + x ^= x >> 16; + return x; +} +// n is a literal in 1..31 at every call site. OpenCL rotate() rotates left by n modulo 32. +static inline uint rotl_imm(uint x, uint n) { return rotate(x, n); } +// Right rotation by n modulo 32 as a left rotation by (32 - n) modulo 32; n == 0 gives x. +static inline uint rotr_var(uint x, uint n) { return rotate(x, (0u - n) & 31u); } +static inline uint ds_elem(uint i, uint d0, uint d1) { + uint x = i ^ d0; + x *= 0x9E3779B1u; x ^= x >> 15; + x += d1; + x *= 0x85EBCA77u; x ^= x >> 13; + x *= 0xC2B2AE3Du; x ^= x >> 16; + return x; +} + +// Memory-hard dataset core (MEMHARD.md). Cache: 2^26 words in 2^16 segments of 64 chained ChaCha12 lines. +// Item: 8 rounds of 8 x seed-parameterised mixer + one 64-byte cache read, then 8 x final mixer (class v3, mixer multiplier 8, +// docs/plans/mixer-x4.md: the round key of application j of round r is 0x9E3779B9 * (r * m + j + 1)). All parameters are literals. +#define MH_CACHE_LINE_MASK 0x003fffffu +#define MH_SEGMENT_LINES 64u +#define MH_QR(a, b, c, d, r1, r2, r3, r4) { a += b; d ^= a; d = mh_rotl(d, r1); c += d; b ^= c; b = mh_rotl(b, r2); a += b; d ^= a; d = mh_rotl(d, r3); c += d; b ^= c; b = mh_rotl(b, r4); } +static inline uint mh_rotl(uint x, uint n) { return (x << n) | (x >> (32u - n)); } // n in 1..31 at every call site + +// y = ChaCha12 core(x) + x +static inline void mh_chacha_block(const uint* x, uint* y) { + for (uint i = 0u; i < 16u; ++i) y[i] = x[i]; + for (uint r = 0u; r < 6u; ++r) { + MH_QR(y[0], y[4], y[8], y[12], 16u, 12u, 8u, 7u) MH_QR(y[1], y[5], y[9], y[13], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[6], y[10], y[14], 16u, 12u, 8u, 7u) MH_QR(y[3], y[7], y[11], y[15], 16u, 12u, 8u, 7u) + MH_QR(y[0], y[5], y[10], y[15], 16u, 12u, 8u, 7u) MH_QR(y[1], y[6], y[11], y[12], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[7], y[8], y[13], 16u, 12u, 8u, 7u) MH_QR(y[3], y[4], y[9], y[14], 16u, 12u, 8u, 7u) + } + for (uint i = 0u; i < 16u; ++i) y[i] += x[i]; +} + +// One cache segment: 64 chained lines written at cache[seg * 1024]. in_j = prev ^ (sigma || K || seg || j || tag), prev_0 = 0. +static inline void mh_cache_segment(__global uint* cache, uint seg) { + uint prev[16]; uint x[16]; uint y[16]; + for (uint i = 0u; i < 16u; ++i) prev[i] = 0u; + for (uint j = 0u; j < MH_SEGMENT_LINES; ++j) { + x[0] = 0x61707865u ^ prev[0]; x[1] = 0x3320646eu ^ prev[1]; x[2] = 0x79622d32u ^ prev[2]; x[3] = 0x6b206574u ^ prev[3]; + x[4] = 0x3067619fu ^ prev[4]; + x[5] = 0x3c269176u ^ prev[5]; + x[6] = 0x84a03b03u ^ prev[6]; + x[7] = 0xf8c63294u ^ prev[7]; + x[8] = 0xff977c5bu ^ prev[8]; + x[9] = 0xe60def3eu ^ prev[9]; + x[10] = 0x63630141u ^ prev[10]; + x[11] = 0xb8fbcb58u ^ prev[11]; + x[12] = seg ^ prev[12]; x[13] = j ^ prev[13]; x[14] = 0x49676e65u ^ prev[14]; x[15] = 0x756d4d48u ^ prev[15]; + mh_chacha_block(x, y); + __global uint* line = cache + ((seg * MH_SEGMENT_LINES + j) * 16u); + for (uint i = 0u; i < 16u; ++i) { line[i] = y[i]; prev[i] = y[i]; } + } +} + +// M_r: per word (s ^ (RC + rk)) * MUL, then a column round and a diagonal round with the seed-drawn rotations. +static inline void mh_mixer(uint* s, uint rk) { + s[0] = (s[0] ^ (0xbab68293u + rk)) * 0x42146205u; + s[1] = (s[1] ^ (0xcc162340u + rk)) * 0x52cbe0fbu; + s[2] = (s[2] ^ (0x6ce151ccu + rk)) * 0x7ecf4a03u; + s[3] = (s[3] ^ (0xe62b8997u + rk)) * 0x6728907fu; + s[4] = (s[4] ^ (0xc9c80297u + rk)) * 0xd81d9751u; + s[5] = (s[5] ^ (0xf74a1654u + rk)) * 0x132952c3u; + s[6] = (s[6] ^ (0x3d704af5u + rk)) * 0xf60de277u; + s[7] = (s[7] ^ (0x3cf522b7u + rk)) * 0x05358035u; + s[8] = (s[8] ^ (0x2b9cac04u + rk)) * 0xbaf6499du; + s[9] = (s[9] ^ (0xa880ac10u + rk)) * 0xe4db9667u; + s[10] = (s[10] ^ (0x13e5dd1du + rk)) * 0x3e98f45du; + s[11] = (s[11] ^ (0x6fc3e233u + rk)) * 0xd0004eddu; + s[12] = (s[12] ^ (0x2d83eeacu + rk)) * 0x2691630du; + s[13] = (s[13] ^ (0x9006e8bfu + rk)) * 0x9beb3bcfu; + s[14] = (s[14] ^ (0x2c4b5362u + rk)) * 0xab310379u; + s[15] = (s[15] ^ (0x31b49ee2u + rk)) * 0x99cfb423u; + MH_QR(s[0], s[4], s[8], s[12], 20u, 20u, 19u, 4u) MH_QR(s[1], s[5], s[9], s[13], 20u, 20u, 19u, 4u) + MH_QR(s[2], s[6], s[10], s[14], 20u, 20u, 19u, 4u) MH_QR(s[3], s[7], s[11], s[15], 20u, 20u, 19u, 4u) + MH_QR(s[0], s[5], s[10], s[15], 26u, 3u, 3u, 27u) MH_QR(s[1], s[6], s[11], s[12], 26u, 3u, 3u, 27u) + MH_QR(s[2], s[7], s[8], s[13], 26u, 3u, 3u, 27u) MH_QR(s[3], s[4], s[9], s[14], 26u, 3u, 3u, 27u) +} + +// Item t: 16 words. s = (K, t * MUL[i] + RC[i]); 8 rounds of 8 x mixer + cache line s[0] & mask; 8 x final mixer. +static inline void mh_item(__global const uint* cache, uint t, uint* s) { + s[0] = 0x3067619fu; + s[1] = 0x3c269176u; + s[2] = 0x84a03b03u; + s[3] = 0xf8c63294u; + s[4] = 0xff977c5bu; + s[5] = 0xe60def3eu; + s[6] = 0x63630141u; + s[7] = 0xb8fbcb58u; + s[8] = t * 0x42146205u + 0xbab68293u; + s[9] = t * 0x52cbe0fbu + 0xcc162340u; + s[10] = t * 0x7ecf4a03u + 0x6ce151ccu; + s[11] = t * 0x6728907fu + 0xe62b8997u; + s[12] = t * 0xd81d9751u + 0xc9c80297u; + s[13] = t * 0x132952c3u + 0xf74a1654u; + s[14] = t * 0xf60de277u + 0x3d704af5u; + s[15] = t * 0x05358035u + 0x3cf522b7u; + for (uint r = 0u; r < 8u; ++r) { + for (uint j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (r * 8u + j + 1u)); + __global const uint* line = cache + ((s[0] & MH_CACHE_LINE_MASK) * 16u); + for (uint i = 0u; i < 16u; ++i) s[i] ^= line[i]; + } + for (uint j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (64u + j + 1u)); +} +// dataset[w] without the dataset: derive item w >> 4 and take word w & 15. +static inline uint mh_word(__global const uint* cache, uint w) { uint s[16]; mh_item(cache, w >> 4u, s); return s[w & 15u]; } + +// Memory-hard dataset (MEMHARD.md). One work-item per cache segment; one work-item per 64-byte dataset item. +// The same constants as memhard.h in this pack (one emitter, three dialects). +__kernel void igneum_cache_fill(__global uint* cache, uint nSegments) { + uint seg = (uint)get_global_id(0); + if (seg < nSegments) mh_cache_segment(cache, seg); +} +__kernel void igneum_build(__global uint* ds, __global const uint* cache, uint nItems) { + uint t = (uint)get_global_id(0); + if (t < nItems) { + uint s[16]; + mh_item(cache, t, s); + __global uint* d = ds + ((ulong)t * 16u); + for (uint i = 0u; i < 16u; ++i) d[i] = s[i]; + } +} + +// One hash per work-item. IGNEUM_GROUP is a multiple of 32; lane = lid & 31 and every exchange stays inside the +// lane's own aligned run of 32 work-items, exactly like simd_shuffle_xor inside a 32-wide Metal SIMD group and +// __shfl_xor_sync inside a CUDA warp. Control flow is uniform (no branches at all). +IGNEUM_KERNEL_HASH void igneum_hash(__global const uint* ds, __global ulong* out, uint baseNonce, uint mask) { + uint gid = (uint)get_global_id(0); + uint lid = (uint)get_local_id(0); + uint nonce = baseNonce + gid; + uint r0, r1, r2, r3, r4, r5, r6, r7; +#if IGNEUM_EXCHANGE == 0 + IGNEUM_LOCAL_WORDS(xch, 2 * IGNEUM_GROUP); + uint xk = 0u; +#else + (void)lid; +#endif + { uint x = nonce ^ 0xf71aee9fu; x += 0x9e3779b9u; x = splitmix32(x); r0 = x ^ 0xad930c88u; } // SEEDW[0], 0x9e3779b9u * 1u, SEEDW[1] + { uint x = nonce ^ 0xad930c88u; x += 0x3c6ef372u; x = splitmix32(x); r1 = x ^ 0x7f982573u; } // SEEDW[1], 0x9e3779b9u * 2u, SEEDW[2] + { uint x = nonce ^ 0x7f982573u; x += 0xdaa66d2bu; x = splitmix32(x); r2 = x ^ 0xa41f9137u; } // SEEDW[2], 0x9e3779b9u * 3u, SEEDW[3] + { uint x = nonce ^ 0xa41f9137u; x += 0x78dde6e4u; x = splitmix32(x); r3 = x ^ 0x76d803d6u; } // SEEDW[3], 0x9e3779b9u * 4u, SEEDW[4] + { uint x = nonce ^ 0x76d803d6u; x += 0x1715609du; x = splitmix32(x); r4 = x ^ 0x37b4a534u; } // SEEDW[4], 0x9e3779b9u * 5u, SEEDW[5] + { uint x = nonce ^ 0x37b4a534u; x += 0xb54cda56u; x = splitmix32(x); r5 = x ^ 0x4d3fb826u; } // SEEDW[5], 0x9e3779b9u * 6u, SEEDW[6] + { uint x = nonce ^ 0x4d3fb826u; x += 0x5384540fu; x = splitmix32(x); r6 = x ^ 0xff614dcbu; } // SEEDW[6], 0x9e3779b9u * 7u, SEEDW[7] + { uint x = nonce ^ 0xff614dcbu; x += 0xf1bbcdc8u; x = splitmix32(x); r7 = x ^ 0xf71aee9fu; } // SEEDW[7], 0x9e3779b9u * 8u, SEEDW[0] + + for (uint it = 0u; it < 8u; ++it) { + uint sel = r0; + r2 = r2 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0x894e457du : 0xe3e2ed7du); // 0 add + r7 = r4 * r0 + r7; // 1 mad + r3 = r3 - r6; // 2 sub + r5 = rotr_var(r5, r1); // 3 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 1u); r6 = r6 ^ t_; } // 4 shfl + r0 = r0 | r3; // 5 or + r0 = r0 * r1; // 6 mul + r7 = r7 * r6; // 7 mul + r3 = r3 ^ ds[r0 & mask]; // 8 load + // per-load shadow sub-block 0 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 0 + for (uint sh0 = 0u; sh0 < 27u; ++sh0) { + r5 = rotr_var(r5, r4); // s0 rotr + r6 = r6 - r5; // s1 sub + r7 = r7 - r6; // s2 sub + r5 = r5 * r4; // s3 mul + r7 = r7 ^ r6; // s4 xor + r2 = rotl_imm(r2, 23u); // s5 rotl + r7 = r7 ^ r4; // s6 xor + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x3051c491u : 0xdaef8862u); // s7 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r6 = r6 ^ t_; } // s8 shfl + r5 = r5 + r1 + ((((sel >> 26u) & 1u) != 0u) ? 0x5170d0b3u : 0xc20e7045u); // s9 add + r0 = r0 | r3; // s10 or + r5 = mul_hi(r5, r4); // s11 mulhi + r7 = r7 ^ r0; // s12 xor + r5 = r5 - r2; // s13 sub + r0 = r0 + r6 + ((((sel >> 0u) & 1u) != 0u) ? 0x2ead087fu : 0xc86d98a4u); // s14 add + r5 = r5 ^ r7; // s15 xor + } + r4 = r4 + r3 + ((((sel >> 22u) & 1u) != 0u) ? 0xd26d3573u : 0xce9bea84u); // 9 add + r2 = r2 * r4; // 10 mul + r3 = r3 ^ ds[r2 & mask]; // 11 load + // per-load shadow sub-block 1 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 1 + for (uint sh1 = 0u; sh1 < 27u; ++sh1) { + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 8u); r7 = r7 ^ t_; } // s16 shfl + r5 = r5 - r7; // s17 sub + r0 = r0 | r6; // s18 or + r0 = r0 + r5 + ((((sel >> 13u) & 1u) != 0u) ? 0xc47c70a8u : 0x4248b651u); // s19 add + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r4 = r4 ^ t_; } // s20 shfl + r0 = r0 + r4 + ((((sel >> 21u) & 1u) != 0u) ? 0x718c1008u : 0x1e35684fu); // s21 add + r0 = mul_hi(r0, r3); // s22 mulhi + r4 = r4 ^ r2; // s23 xor + r0 = r0 - r2; // s24 sub + r5 = rotl_imm(r5, 13u); // s25 rotl + r7 = r7 - r0; // s26 sub + r2 = r2 ^ r3; // s27 xor + r2 = r3 * r2 + r2; // s28 mad + r2 = r2 ^ r1; // s29 xor + r4 = mul_hi(r4, r0); // s30 mulhi + r6 = r6 ^ r4; // s31 xor + } + r4 = mul_hi(r4, r1); // 12 mulhi + r7 = mul_hi(r7, r3); // 13 mulhi + r3 = r3 + r2 + ((((sel >> 8u) & 1u) != 0u) ? 0xc2828a42u : 0x514f9ff4u); // 14 add + r1 = r3 * r2 + r1; // 15 mad + r2 = rotl_imm(r2, 7u); // 16 rotl + r1 = r1 ^ ds[r2 & mask]; // 17 load + // per-load shadow sub-block 2 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 2 + for (uint sh2 = 0u; sh2 < 27u; ++sh2) { + r4 = r4 ^ r2; // s32 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 1u); r1 = r1 ^ t_; } // s33 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r5 = r5 ^ t_; } // s34 shfl + r4 = r4 - r0; // s35 sub + r6 = r6 - r3; // s36 sub + r2 = r2 | r6; // s37 or + r2 = rotl_imm(r2, 30u); // s38 rotl + r4 = rotr_var(r4, r7); // s39 rotr + r0 = r0 | r7; // s40 or + r2 = rotr_var(r2, r5); // s41 rotr + r1 = r3 * r3 + r1; // s42 mad + r6 = r5 * r5 + r6; // s43 mad + r1 = mul_hi(r1, r0); // s44 mulhi + r1 = r1 * r3; // s45 mul + r0 = r2 * r0 + r0; // s46 mad + r1 = r1 - r5; // s47 sub + } + r3 = r3 * r2; // 18 mul + r6 = rotl_imm(r6, 24u); // 19 rotl + r6 = r6 ^ ds[r3 & mask]; // 20 load + // per-load shadow sub-block 3 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 3 + for (uint sh3 = 0u; sh3 < 27u; ++sh3) { + r4 = r4 ^ r0; // s48 xor + r2 = rotr_var(r2, r0); // s49 rotr + r0 = mul_hi(r0, r5); // s50 mulhi + r7 = r7 | r5; // s51 or + r4 = r0 * r3 + r4; // s52 mad + r0 = rotr_var(r0, r4); // s53 rotr + r6 = r3 * r3 + r6; // s54 mad + r6 = r4 * r2 + r6; // s55 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 2u); r5 = r5 ^ t_; } // s56 shfl + r7 = rotl_imm(r7, 21u); // s57 rotl + r3 = r3 ^ r7; // s58 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 1u); r0 = r0 ^ t_; } // s59 shfl + r5 = r5 ^ r6; // s60 xor + r4 = rotr_var(r4, r7); // s61 rotr + r1 = r1 + r6 + ((((sel >> 10u) & 1u) != 0u) ? 0x31f87d74u : 0xf7ccf1e9u); // s62 add + r5 = r5 + r2 + ((((sel >> 15u) & 1u) != 0u) ? 0x9c2847f4u : 0x2f386099u); // s63 add + } + r1 = r1 ^ ds[r6 & mask]; // 21 load + // per-load shadow sub-block 4 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 4 + for (uint sh4 = 0u; sh4 < 27u; ++sh4) { + r7 = r7 + r0 + ((((sel >> 19u) & 1u) != 0u) ? 0xd3241188u : 0x1b30ce7au); // s64 add + r6 = r6 + r7 + ((((sel >> 13u) & 1u) != 0u) ? 0x9b42c3deu : 0x02dc8349u); // s65 add + r0 = rotl_imm(r0, 16u); // s66 rotl + r2 = rotl_imm(r2, 9u); // s67 rotl + r2 = r5 * r6 + r2; // s68 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 8u); r6 = r6 ^ t_; } // s69 shfl + r2 = r2 ^ r5; // s70 xor + r5 = mul_hi(r5, r1); // s71 mulhi + r6 = rotl_imm(r6, 29u); // s72 rotl + r0 = r0 - r7; // s73 sub + r5 = r2 * r2 + r5; // s74 mad + r0 = rotr_var(r0, r5); // s75 rotr + r7 = r7 + r2 + ((((sel >> 9u) & 1u) != 0u) ? 0x0da1ce17u : 0x05d36679u); // s76 add + r7 = r7 - r2; // s77 sub + r7 = rotr_var(r7, r0); // s78 rotr + r1 = r5 * r5 + r1; // s79 mad + } + r5 = r3 * r3 + r5; // 22 mad + r4 = r4 ^ ds[r7 & mask]; // 23 load + // per-load shadow sub-block 5 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 5 + for (uint sh5 = 0u; sh5 < 27u; ++sh5) { + r3 = rotr_var(r3, r0); // s80 rotr + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xadf5ef88u : 0xf14547bdu); // s81 add + r0 = r0 | r6; // s82 or + r1 = mul_hi(r1, r0); // s83 mulhi + r7 = r6 * r7 + r7; // s84 mad + r5 = rotl_imm(r5, 29u); // s85 rotl + r2 = r2 ^ r6; // s86 xor + r5 = r5 + r4 + ((((sel >> 24u) & 1u) != 0u) ? 0x35ff14aeu : 0xba4947c2u); // s87 add + r3 = r3 + r6 + ((((sel >> 3u) & 1u) != 0u) ? 0xf3900fc1u : 0xf6878beeu); // s88 add + r0 = r0 + r2 + ((((sel >> 12u) & 1u) != 0u) ? 0xf7e8f59fu : 0x926f3607u); // s89 add + r2 = r2 ^ r6; // s90 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 2u); r3 = r3 ^ t_; } // s91 shfl + r6 = r6 - r1; // s92 sub + r5 = r5 + r1 + ((((sel >> 13u) & 1u) != 0u) ? 0x0e376f9cu : 0xdab36c29u); // s93 add + r6 = r1 * r1 + r6; // s94 mad + r3 = r3 ^ r4; // s95 xor + } + r6 = r6 ^ ds[r4 & mask]; // 24 load + // per-load shadow sub-block 6 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 6 + for (uint sh6 = 0u; sh6 < 27u; ++sh6) { + r6 = r5 * r2 + r6; // s96 mad + r7 = r7 + r3 + ((((sel >> 23u) & 1u) != 0u) ? 0x9f917747u : 0x204129e9u); // s97 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 16u); r5 = r5 ^ t_; } // s98 shfl + r2 = r2 * r6; // s99 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r7 = r7 ^ t_; } // s100 shfl + r6 = r6 + r1 + ((((sel >> 10u) & 1u) != 0u) ? 0xe42fe974u : 0xe3b596a0u); // s101 add + r5 = rotl_imm(r5, 3u); // s102 rotl + r5 = r5 ^ r1; // s103 xor + r4 = r4 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0xc3d77ffbu : 0x705c3f94u); // s104 add + r0 = r0 + r6 + ((((sel >> 25u) & 1u) != 0u) ? 0xea02a4cau : 0xbc6fb42bu); // s105 add + r3 = r3 | r5; // s106 or + r0 = r0 - r6; // s107 sub + r0 = rotr_var(r0, r3); // s108 rotr + r5 = r5 + r4 + ((((sel >> 4u) & 1u) != 0u) ? 0x0357e63eu : 0xcb37ea87u); // s109 add + r7 = rotl_imm(r7, 5u); // s110 rotl + r4 = r4 ^ r1; // s111 xor + } + r5 = r5 * r7; // 25 mul + r0 = r0 * r3; // 26 mul + r0 = r0 | r3; // 27 or + r1 = r3 * r4 + r1; // 28 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r0 = r0 ^ t_; } // 29 shfl + r7 = r7 - r3; // 30 sub + r4 = r4 ^ r1; // 31 xor + r4 = r4 | r5; // 32 or + r3 = rotr_var(r3, r5); // 33 rotr + r4 = r4 ^ ds[r5 & mask]; // 34 load + // per-load shadow sub-block 7 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 7 + for (uint sh7 = 0u; sh7 < 27u; ++sh7) { + r6 = r6 ^ r5; // s112 xor + r1 = r1 | r3; // s113 or + r0 = r0 + r5 + ((((sel >> 3u) & 1u) != 0u) ? 0x7f8b8cd2u : 0x9aab0297u); // s114 add + r3 = r3 - r5; // s115 sub + r4 = rotr_var(r4, r2); // s116 rotr + r4 = r4 + r6 + ((((sel >> 6u) & 1u) != 0u) ? 0x59400b57u : 0xc511183fu); // s117 add + r6 = r6 - r1; // s118 sub + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r3 = r3 ^ t_; } // s119 shfl + r6 = r4 * r4 + r6; // s120 mad + r2 = rotl_imm(r2, 8u); // s121 rotl + r5 = r0 * r3 + r5; // s122 mad + r7 = r7 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x27c70dc0u : 0x5200c242u); // s123 add + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 4u); r3 = r3 ^ t_; } // s124 shfl + r0 = r0 + r1 + ((((sel >> 17u) & 1u) != 0u) ? 0xec2f5997u : 0x2d5028ceu); // s125 add + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 16u); r3 = r3 ^ t_; } // s126 shfl + r5 = r5 ^ r0; // s127 xor + } + r0 = r5 * r3 + r0; // 35 mad + r6 = r6 ^ ds[r3 & mask]; // 36 load + // per-load shadow sub-block 8 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 8 + for (uint sh8 = 0u; sh8 < 27u; ++sh8) { + r7 = r7 + r1 + ((((sel >> 10u) & 1u) != 0u) ? 0x09e8ede2u : 0x432f6c0du); // s128 add + r2 = r2 ^ r4; // s129 xor + r0 = r0 * r2; // s130 mul + r4 = r4 | r3; // s131 or + r3 = r3 | r7; // s132 or + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 1u); r7 = r7 ^ t_; } // s133 shfl + r5 = r5 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0xce4fdf8eu : 0xcf5ecc75u); // s134 add + r3 = r2 * r3 + r3; // s135 mad + r1 = rotl_imm(r1, 11u); // s136 rotl + r2 = r2 | r0; // s137 or + r3 = r3 ^ r4; // s138 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 1u); r2 = r2 ^ t_; } // s139 shfl + r2 = rotl_imm(r2, 6u); // s140 rotl + r0 = r0 * r3; // s141 mul + r1 = r1 * r7; // s142 mul + r0 = r0 ^ r1; // s143 xor + } + r5 = r5 * r3; // 37 mul + r5 = r5 ^ r4; // 38 xor + r6 = r6 ^ r0; // 39 xor + r4 = rotr_var(r4, r0); // 40 rotr + r7 = r7 ^ r6; // 41 xor + r1 = r1 ^ ds[r7 & mask]; // 42 load + // per-load shadow sub-block 9 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 9 + for (uint sh9 = 0u; sh9 < 27u; ++sh9) { + r6 = r2 * r0 + r6; // s144 mad + r1 = rotl_imm(r1, 15u); // s145 rotl + r1 = rotl_imm(r1, 30u); // s146 rotl + r6 = r6 ^ r0; // s147 xor + r3 = r3 - r2; // s148 sub + r3 = r3 + r0 + ((((sel >> 5u) & 1u) != 0u) ? 0x11bbdeefu : 0xaa002f15u); // s149 add + r6 = r6 + r5 + ((((sel >> 9u) & 1u) != 0u) ? 0xff9d4b0eu : 0xbe64b2e2u); // s150 add + r1 = r1 * r4; // s151 mul + r5 = rotl_imm(r5, 3u); // s152 rotl + r5 = r5 * r2; // s153 mul + r2 = rotl_imm(r2, 21u); // s154 rotl + r5 = rotl_imm(r5, 18u); // s155 rotl + r1 = r1 ^ r5; // s156 xor + r1 = mul_hi(r1, r6); // s157 mulhi + r4 = r7 * r3 + r4; // s158 mad + r4 = r4 - r7; // s159 sub + } + r2 = r2 - r4; // 43 sub + r6 = mul_hi(r6, r7); // 44 mulhi + r3 = rotl_imm(r3, 13u); // 45 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 16u); r7 = r7 ^ t_; } // 46 shfl + r2 = rotl_imm(r2, 26u); // 47 rotl + r6 = r6 * r2; // 48 mul + r2 = r2 ^ ds[r3 & mask]; // 49 load + // per-load shadow sub-block 10 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 10 + for (uint sh10 = 0u; sh10 < 27u; ++sh10) { + r3 = r3 ^ r2; // s160 xor + r3 = mul_hi(r3, r4); // s161 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 1u); r3 = r3 ^ t_; } // s162 shfl + r0 = r0 - r1; // s163 sub + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 8u); r6 = r6 ^ t_; } // s164 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 2u); r4 = r4 ^ t_; } // s165 shfl + r3 = r3 | r6; // s166 or + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r6 = r6 ^ t_; } // s167 shfl + r2 = r2 ^ r1; // s168 xor + r5 = r5 ^ r1; // s169 xor + r5 = r5 ^ r0; // s170 xor + r3 = r6 * r0 + r3; // s171 mad + r3 = r3 - r0; // s172 sub + r6 = r6 + r0 + ((((sel >> 27u) & 1u) != 0u) ? 0xc72dc2a0u : 0x3b90694bu); // s173 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r7 = r7 ^ t_; } // s174 shfl + r5 = mul_hi(r5, r2); // s175 mulhi + } + r5 = r5 ^ ds[r1 & mask]; // 50 load + // per-load shadow sub-block 11 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 11 + for (uint sh11 = 0u; sh11 < 27u; ++sh11) { + r3 = r3 + r6 + ((((sel >> 5u) & 1u) != 0u) ? 0x4eb75843u : 0x9e65cebdu); // s176 add + r0 = r4 * r1 + r0; // s177 mad + r6 = rotr_var(r6, r7); // s178 rotr + r0 = r0 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0x7001d036u : 0x01e5b250u); // s179 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 16u); r5 = r5 ^ t_; } // s180 shfl + r3 = r3 * r0; // s181 mul + r0 = rotl_imm(r0, 23u); // s182 rotl + r7 = mul_hi(r7, r0); // s183 mulhi + r0 = r0 * r4; // s184 mul + r1 = r1 + r4 + ((((sel >> 19u) & 1u) != 0u) ? 0x91736711u : 0xbef14988u); // s185 add + r7 = r7 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x15e0cdf3u : 0xf5d741beu); // s186 add + r1 = r1 ^ r7; // s187 xor + r1 = r1 + r3 + ((((sel >> 21u) & 1u) != 0u) ? 0x7549bc3eu : 0x32be33c6u); // s188 add + r1 = r0 * r6 + r1; // s189 mad + r0 = rotr_var(r0, r5); // s190 rotr + r4 = r0 * r1 + r4; // s191 mad + } + r0 = rotl_imm(r0, 20u); // 51 rotl + r1 = r1 ^ r2; // 52 xor + r2 = r2 ^ ds[r1 & mask]; // 53 load + // per-load shadow sub-block 12 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 12 + for (uint sh12 = 0u; sh12 < 27u; ++sh12) { + r3 = r6 * r1 + r3; // s192 mad + r6 = rotl_imm(r6, 31u); // s193 rotl + r5 = rotl_imm(r5, 28u); // s194 rotl + r4 = r4 * r3; // s195 mul + r2 = r2 + r3 + ((((sel >> 4u) & 1u) != 0u) ? 0x7c3d6253u : 0x9d7aebbbu); // s196 add + r3 = r3 | r5; // s197 or + r6 = r6 - r0; // s198 sub + r7 = r7 * r4; // s199 mul + r3 = rotr_var(r3, r2); // s200 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 16u); r4 = r4 ^ t_; } // s201 shfl + r7 = r7 ^ r3; // s202 xor + r4 = r4 | r3; // s203 or + r3 = rotr_var(r3, r6); // s204 rotr + r0 = rotr_var(r0, r1); // s205 rotr + r2 = r5 * r2 + r2; // s206 mad + r1 = mul_hi(r1, r5); // s207 mulhi + } + r4 = rotl_imm(r4, 20u); // 54 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r3 = r3 ^ t_; } // 55 shfl + r1 = r1 ^ ds[r0 & mask]; // 56 load + // per-load shadow sub-block 13 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 13 + for (uint sh13 = 0u; sh13 < 27u; ++sh13) { + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 1u); r4 = r4 ^ t_; } // s208 shfl + r7 = r5 * r7 + r7; // s209 mad + r6 = r6 ^ r3; // s210 xor + r3 = r3 ^ r2; // s211 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 16u); r5 = r5 ^ t_; } // s212 shfl + r4 = rotl_imm(r4, 10u); // s213 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 16u); r5 = r5 ^ t_; } // s214 shfl + r3 = r3 | r0; // s215 or + r4 = r4 * r5; // s216 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 16u); r0 = r0 ^ t_; } // s217 shfl + r0 = r0 * r5; // s218 mul + r0 = rotl_imm(r0, 13u); // s219 rotl + r1 = mul_hi(r1, r0); // s220 mulhi + r4 = r4 ^ r1; // s221 xor + r2 = r2 | r3; // s222 or + r0 = r0 ^ r4; // s223 xor + } + r3 = r3 ^ ds[r5 & mask]; // 57 load + // per-load shadow sub-block 14 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 14 + for (uint sh14 = 0u; sh14 < 27u; ++sh14) { + r5 = r6 * r1 + r5; // s224 mad + r4 = r4 ^ r3; // s225 xor + r5 = r5 + r0 + ((((sel >> 3u) & 1u) != 0u) ? 0xe4e51c75u : 0xfe960971u); // s226 add + r3 = mul_hi(r3, r2); // s227 mulhi + r2 = r2 ^ r6; // s228 xor + r1 = mul_hi(r1, r5); // s229 mulhi + r3 = r3 + r4 + ((((sel >> 25u) & 1u) != 0u) ? 0x4d597c08u : 0x48b3ce0au); // s230 add + r2 = rotr_var(r2, r3); // s231 rotr + r2 = r2 - r7; // s232 sub + r6 = r6 | r2; // s233 or + r0 = rotr_var(r0, r3); // s234 rotr + r4 = r4 + r3 + ((((sel >> 13u) & 1u) != 0u) ? 0xc9f1d54cu : 0x2ed8c878u); // s235 add + r0 = r3 * r7 + r0; // s236 mad + r3 = r3 + r5 + ((((sel >> 29u) & 1u) != 0u) ? 0xc572bd00u : 0x22e8b90au); // s237 add + r0 = mul_hi(r0, r4); // s238 mulhi + r6 = r6 * r5; // s239 mul + } + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 2u); r1 = r1 ^ t_; } // 58 shfl + r6 = r6 ^ ds[r4 & mask]; // 59 load + // per-load shadow sub-block 15 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 15 + for (uint sh15 = 0u; sh15 < 27u; ++sh15) { + r5 = r5 + r2 + ((((sel >> 20u) & 1u) != 0u) ? 0xb233f94fu : 0xc6b790e6u); // s240 add + r0 = r0 - r3; // s241 sub + r4 = r4 + r7 + ((((sel >> 4u) & 1u) != 0u) ? 0x534d924bu : 0x0f918d3bu); // s242 add + r5 = rotr_var(r5, r0); // s243 rotr + r1 = rotr_var(r1, r7); // s244 rotr + r2 = r2 | r0; // s245 or + r4 = r4 * r7; // s246 mul + r1 = r2 * r5 + r1; // s247 mad + r2 = r2 * r5; // s248 mul + r4 = r4 ^ r2; // s249 xor + r3 = r3 ^ r1; // s250 xor + r5 = rotr_var(r5, r7); // s251 rotr + r2 = r7 * r7 + r2; // s252 mad + r7 = rotr_var(r7, r3); // s253 rotr + r6 = r6 + r1 + ((((sel >> 21u) & 1u) != 0u) ? 0x86d27169u : 0xb8a27d95u); // s254 add + r6 = r6 | r7; // s255 or + } + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r7 = r7 ^ t_; } // 60 shfl + r5 = rotr_var(r5, r0); // 61 rotr + r0 = r0 + r6 + ((((sel >> 14u) & 1u) != 0u) ? 0xb13a5391u : 0x8c2e5c24u); // 62 add + r2 = r2 + r1 + ((((sel >> 21u) & 1u) != 0u) ? 0xf82fc8b5u : 0xb225b762u); // 63 add + } + uint lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((ulong)hi << 32) | (ulong)lo; +} + +#if IGNEUM_EXCHANGE != 0 +// Reports the sub-group size this device uses for a work-group of IGNEUM_GROUP items. host.c runs it only when the +// per-kernel query (clGetKernelSubGroupInfoKHR on igneum_hash) is unavailable; that query is preferred because a +// compiler may pick a different wave width per kernel (RDNA: wave32 or wave64). See WAVEFRONT.md. +IGNEUM_KERNEL_HASH void igneum_probe_subgroup(__global uint* out) { + if (get_local_id(0) == 0u) { out[0] = get_sub_group_size(); out[1] = get_num_sub_groups(); } +} +#endif + +// Header-bound variant (bind.rs): the init words come from initw, not SEEDW. Same body as igneum_hash. +IGNEUM_KERNEL_HASH void igneum_hash_bound(__global const uint* ds, __global ulong* out, uint baseNonce, uint mask, __global const uint* initw) { + uint gid = (uint)get_global_id(0); + uint lid = (uint)get_local_id(0); + uint nonce = baseNonce + gid; + uint r0, r1, r2, r3, r4, r5, r6, r7; + uint iw0 = initw[0], iw1 = initw[1], iw2 = initw[2], iw3 = initw[3], iw4 = initw[4], iw5 = initw[5], iw6 = initw[6], iw7 = initw[7]; +#if IGNEUM_EXCHANGE == 0 + IGNEUM_LOCAL_WORDS(xch, 2 * IGNEUM_GROUP); + uint xk = 0u; +#else + (void)lid; +#endif + { uint x = nonce ^ iw0; x += 0x9e3779b9u * 1u; x = splitmix32(x); r0 = x ^ iw1; } + { uint x = nonce ^ iw1; x += 0x9e3779b9u * 2u; x = splitmix32(x); r1 = x ^ iw2; } + { uint x = nonce ^ iw2; x += 0x9e3779b9u * 3u; x = splitmix32(x); r2 = x ^ iw3; } + { uint x = nonce ^ iw3; x += 0x9e3779b9u * 4u; x = splitmix32(x); r3 = x ^ iw4; } + { uint x = nonce ^ iw4; x += 0x9e3779b9u * 5u; x = splitmix32(x); r4 = x ^ iw5; } + { uint x = nonce ^ iw5; x += 0x9e3779b9u * 6u; x = splitmix32(x); r5 = x ^ iw6; } + { uint x = nonce ^ iw6; x += 0x9e3779b9u * 7u; x = splitmix32(x); r6 = x ^ iw7; } + { uint x = nonce ^ iw7; x += 0x9e3779b9u * 8u; x = splitmix32(x); r7 = x ^ iw0; } + + for (uint it = 0u; it < 8u; ++it) { + uint sel = r0; + r2 = r2 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0x894e457du : 0xe3e2ed7du); // 0 add + r7 = r4 * r0 + r7; // 1 mad + r3 = r3 - r6; // 2 sub + r5 = rotr_var(r5, r1); // 3 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 1u); r6 = r6 ^ t_; } // 4 shfl + r0 = r0 | r3; // 5 or + r0 = r0 * r1; // 6 mul + r7 = r7 * r6; // 7 mul + r3 = r3 ^ ds[r0 & mask]; // 8 load + // per-load shadow sub-block 0 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 0 + for (uint sh0 = 0u; sh0 < 27u; ++sh0) { + r5 = rotr_var(r5, r4); // s0 rotr + r6 = r6 - r5; // s1 sub + r7 = r7 - r6; // s2 sub + r5 = r5 * r4; // s3 mul + r7 = r7 ^ r6; // s4 xor + r2 = rotl_imm(r2, 23u); // s5 rotl + r7 = r7 ^ r4; // s6 xor + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x3051c491u : 0xdaef8862u); // s7 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r6 = r6 ^ t_; } // s8 shfl + r5 = r5 + r1 + ((((sel >> 26u) & 1u) != 0u) ? 0x5170d0b3u : 0xc20e7045u); // s9 add + r0 = r0 | r3; // s10 or + r5 = mul_hi(r5, r4); // s11 mulhi + r7 = r7 ^ r0; // s12 xor + r5 = r5 - r2; // s13 sub + r0 = r0 + r6 + ((((sel >> 0u) & 1u) != 0u) ? 0x2ead087fu : 0xc86d98a4u); // s14 add + r5 = r5 ^ r7; // s15 xor + } + r4 = r4 + r3 + ((((sel >> 22u) & 1u) != 0u) ? 0xd26d3573u : 0xce9bea84u); // 9 add + r2 = r2 * r4; // 10 mul + r3 = r3 ^ ds[r2 & mask]; // 11 load + // per-load shadow sub-block 1 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 1 + for (uint sh1 = 0u; sh1 < 27u; ++sh1) { + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 8u); r7 = r7 ^ t_; } // s16 shfl + r5 = r5 - r7; // s17 sub + r0 = r0 | r6; // s18 or + r0 = r0 + r5 + ((((sel >> 13u) & 1u) != 0u) ? 0xc47c70a8u : 0x4248b651u); // s19 add + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r4 = r4 ^ t_; } // s20 shfl + r0 = r0 + r4 + ((((sel >> 21u) & 1u) != 0u) ? 0x718c1008u : 0x1e35684fu); // s21 add + r0 = mul_hi(r0, r3); // s22 mulhi + r4 = r4 ^ r2; // s23 xor + r0 = r0 - r2; // s24 sub + r5 = rotl_imm(r5, 13u); // s25 rotl + r7 = r7 - r0; // s26 sub + r2 = r2 ^ r3; // s27 xor + r2 = r3 * r2 + r2; // s28 mad + r2 = r2 ^ r1; // s29 xor + r4 = mul_hi(r4, r0); // s30 mulhi + r6 = r6 ^ r4; // s31 xor + } + r4 = mul_hi(r4, r1); // 12 mulhi + r7 = mul_hi(r7, r3); // 13 mulhi + r3 = r3 + r2 + ((((sel >> 8u) & 1u) != 0u) ? 0xc2828a42u : 0x514f9ff4u); // 14 add + r1 = r3 * r2 + r1; // 15 mad + r2 = rotl_imm(r2, 7u); // 16 rotl + r1 = r1 ^ ds[r2 & mask]; // 17 load + // per-load shadow sub-block 2 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 2 + for (uint sh2 = 0u; sh2 < 27u; ++sh2) { + r4 = r4 ^ r2; // s32 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 1u); r1 = r1 ^ t_; } // s33 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r5 = r5 ^ t_; } // s34 shfl + r4 = r4 - r0; // s35 sub + r6 = r6 - r3; // s36 sub + r2 = r2 | r6; // s37 or + r2 = rotl_imm(r2, 30u); // s38 rotl + r4 = rotr_var(r4, r7); // s39 rotr + r0 = r0 | r7; // s40 or + r2 = rotr_var(r2, r5); // s41 rotr + r1 = r3 * r3 + r1; // s42 mad + r6 = r5 * r5 + r6; // s43 mad + r1 = mul_hi(r1, r0); // s44 mulhi + r1 = r1 * r3; // s45 mul + r0 = r2 * r0 + r0; // s46 mad + r1 = r1 - r5; // s47 sub + } + r3 = r3 * r2; // 18 mul + r6 = rotl_imm(r6, 24u); // 19 rotl + r6 = r6 ^ ds[r3 & mask]; // 20 load + // per-load shadow sub-block 3 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 3 + for (uint sh3 = 0u; sh3 < 27u; ++sh3) { + r4 = r4 ^ r0; // s48 xor + r2 = rotr_var(r2, r0); // s49 rotr + r0 = mul_hi(r0, r5); // s50 mulhi + r7 = r7 | r5; // s51 or + r4 = r0 * r3 + r4; // s52 mad + r0 = rotr_var(r0, r4); // s53 rotr + r6 = r3 * r3 + r6; // s54 mad + r6 = r4 * r2 + r6; // s55 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 2u); r5 = r5 ^ t_; } // s56 shfl + r7 = rotl_imm(r7, 21u); // s57 rotl + r3 = r3 ^ r7; // s58 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 1u); r0 = r0 ^ t_; } // s59 shfl + r5 = r5 ^ r6; // s60 xor + r4 = rotr_var(r4, r7); // s61 rotr + r1 = r1 + r6 + ((((sel >> 10u) & 1u) != 0u) ? 0x31f87d74u : 0xf7ccf1e9u); // s62 add + r5 = r5 + r2 + ((((sel >> 15u) & 1u) != 0u) ? 0x9c2847f4u : 0x2f386099u); // s63 add + } + r1 = r1 ^ ds[r6 & mask]; // 21 load + // per-load shadow sub-block 4 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 4 + for (uint sh4 = 0u; sh4 < 27u; ++sh4) { + r7 = r7 + r0 + ((((sel >> 19u) & 1u) != 0u) ? 0xd3241188u : 0x1b30ce7au); // s64 add + r6 = r6 + r7 + ((((sel >> 13u) & 1u) != 0u) ? 0x9b42c3deu : 0x02dc8349u); // s65 add + r0 = rotl_imm(r0, 16u); // s66 rotl + r2 = rotl_imm(r2, 9u); // s67 rotl + r2 = r5 * r6 + r2; // s68 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 8u); r6 = r6 ^ t_; } // s69 shfl + r2 = r2 ^ r5; // s70 xor + r5 = mul_hi(r5, r1); // s71 mulhi + r6 = rotl_imm(r6, 29u); // s72 rotl + r0 = r0 - r7; // s73 sub + r5 = r2 * r2 + r5; // s74 mad + r0 = rotr_var(r0, r5); // s75 rotr + r7 = r7 + r2 + ((((sel >> 9u) & 1u) != 0u) ? 0x0da1ce17u : 0x05d36679u); // s76 add + r7 = r7 - r2; // s77 sub + r7 = rotr_var(r7, r0); // s78 rotr + r1 = r5 * r5 + r1; // s79 mad + } + r5 = r3 * r3 + r5; // 22 mad + r4 = r4 ^ ds[r7 & mask]; // 23 load + // per-load shadow sub-block 5 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 5 + for (uint sh5 = 0u; sh5 < 27u; ++sh5) { + r3 = rotr_var(r3, r0); // s80 rotr + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xadf5ef88u : 0xf14547bdu); // s81 add + r0 = r0 | r6; // s82 or + r1 = mul_hi(r1, r0); // s83 mulhi + r7 = r6 * r7 + r7; // s84 mad + r5 = rotl_imm(r5, 29u); // s85 rotl + r2 = r2 ^ r6; // s86 xor + r5 = r5 + r4 + ((((sel >> 24u) & 1u) != 0u) ? 0x35ff14aeu : 0xba4947c2u); // s87 add + r3 = r3 + r6 + ((((sel >> 3u) & 1u) != 0u) ? 0xf3900fc1u : 0xf6878beeu); // s88 add + r0 = r0 + r2 + ((((sel >> 12u) & 1u) != 0u) ? 0xf7e8f59fu : 0x926f3607u); // s89 add + r2 = r2 ^ r6; // s90 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 2u); r3 = r3 ^ t_; } // s91 shfl + r6 = r6 - r1; // s92 sub + r5 = r5 + r1 + ((((sel >> 13u) & 1u) != 0u) ? 0x0e376f9cu : 0xdab36c29u); // s93 add + r6 = r1 * r1 + r6; // s94 mad + r3 = r3 ^ r4; // s95 xor + } + r6 = r6 ^ ds[r4 & mask]; // 24 load + // per-load shadow sub-block 6 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 6 + for (uint sh6 = 0u; sh6 < 27u; ++sh6) { + r6 = r5 * r2 + r6; // s96 mad + r7 = r7 + r3 + ((((sel >> 23u) & 1u) != 0u) ? 0x9f917747u : 0x204129e9u); // s97 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 16u); r5 = r5 ^ t_; } // s98 shfl + r2 = r2 * r6; // s99 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r7 = r7 ^ t_; } // s100 shfl + r6 = r6 + r1 + ((((sel >> 10u) & 1u) != 0u) ? 0xe42fe974u : 0xe3b596a0u); // s101 add + r5 = rotl_imm(r5, 3u); // s102 rotl + r5 = r5 ^ r1; // s103 xor + r4 = r4 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0xc3d77ffbu : 0x705c3f94u); // s104 add + r0 = r0 + r6 + ((((sel >> 25u) & 1u) != 0u) ? 0xea02a4cau : 0xbc6fb42bu); // s105 add + r3 = r3 | r5; // s106 or + r0 = r0 - r6; // s107 sub + r0 = rotr_var(r0, r3); // s108 rotr + r5 = r5 + r4 + ((((sel >> 4u) & 1u) != 0u) ? 0x0357e63eu : 0xcb37ea87u); // s109 add + r7 = rotl_imm(r7, 5u); // s110 rotl + r4 = r4 ^ r1; // s111 xor + } + r5 = r5 * r7; // 25 mul + r0 = r0 * r3; // 26 mul + r0 = r0 | r3; // 27 or + r1 = r3 * r4 + r1; // 28 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r0 = r0 ^ t_; } // 29 shfl + r7 = r7 - r3; // 30 sub + r4 = r4 ^ r1; // 31 xor + r4 = r4 | r5; // 32 or + r3 = rotr_var(r3, r5); // 33 rotr + r4 = r4 ^ ds[r5 & mask]; // 34 load + // per-load shadow sub-block 7 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 7 + for (uint sh7 = 0u; sh7 < 27u; ++sh7) { + r6 = r6 ^ r5; // s112 xor + r1 = r1 | r3; // s113 or + r0 = r0 + r5 + ((((sel >> 3u) & 1u) != 0u) ? 0x7f8b8cd2u : 0x9aab0297u); // s114 add + r3 = r3 - r5; // s115 sub + r4 = rotr_var(r4, r2); // s116 rotr + r4 = r4 + r6 + ((((sel >> 6u) & 1u) != 0u) ? 0x59400b57u : 0xc511183fu); // s117 add + r6 = r6 - r1; // s118 sub + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r3 = r3 ^ t_; } // s119 shfl + r6 = r4 * r4 + r6; // s120 mad + r2 = rotl_imm(r2, 8u); // s121 rotl + r5 = r0 * r3 + r5; // s122 mad + r7 = r7 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x27c70dc0u : 0x5200c242u); // s123 add + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 4u); r3 = r3 ^ t_; } // s124 shfl + r0 = r0 + r1 + ((((sel >> 17u) & 1u) != 0u) ? 0xec2f5997u : 0x2d5028ceu); // s125 add + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 16u); r3 = r3 ^ t_; } // s126 shfl + r5 = r5 ^ r0; // s127 xor + } + r0 = r5 * r3 + r0; // 35 mad + r6 = r6 ^ ds[r3 & mask]; // 36 load + // per-load shadow sub-block 8 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 8 + for (uint sh8 = 0u; sh8 < 27u; ++sh8) { + r7 = r7 + r1 + ((((sel >> 10u) & 1u) != 0u) ? 0x09e8ede2u : 0x432f6c0du); // s128 add + r2 = r2 ^ r4; // s129 xor + r0 = r0 * r2; // s130 mul + r4 = r4 | r3; // s131 or + r3 = r3 | r7; // s132 or + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 1u); r7 = r7 ^ t_; } // s133 shfl + r5 = r5 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0xce4fdf8eu : 0xcf5ecc75u); // s134 add + r3 = r2 * r3 + r3; // s135 mad + r1 = rotl_imm(r1, 11u); // s136 rotl + r2 = r2 | r0; // s137 or + r3 = r3 ^ r4; // s138 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 1u); r2 = r2 ^ t_; } // s139 shfl + r2 = rotl_imm(r2, 6u); // s140 rotl + r0 = r0 * r3; // s141 mul + r1 = r1 * r7; // s142 mul + r0 = r0 ^ r1; // s143 xor + } + r5 = r5 * r3; // 37 mul + r5 = r5 ^ r4; // 38 xor + r6 = r6 ^ r0; // 39 xor + r4 = rotr_var(r4, r0); // 40 rotr + r7 = r7 ^ r6; // 41 xor + r1 = r1 ^ ds[r7 & mask]; // 42 load + // per-load shadow sub-block 9 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 9 + for (uint sh9 = 0u; sh9 < 27u; ++sh9) { + r6 = r2 * r0 + r6; // s144 mad + r1 = rotl_imm(r1, 15u); // s145 rotl + r1 = rotl_imm(r1, 30u); // s146 rotl + r6 = r6 ^ r0; // s147 xor + r3 = r3 - r2; // s148 sub + r3 = r3 + r0 + ((((sel >> 5u) & 1u) != 0u) ? 0x11bbdeefu : 0xaa002f15u); // s149 add + r6 = r6 + r5 + ((((sel >> 9u) & 1u) != 0u) ? 0xff9d4b0eu : 0xbe64b2e2u); // s150 add + r1 = r1 * r4; // s151 mul + r5 = rotl_imm(r5, 3u); // s152 rotl + r5 = r5 * r2; // s153 mul + r2 = rotl_imm(r2, 21u); // s154 rotl + r5 = rotl_imm(r5, 18u); // s155 rotl + r1 = r1 ^ r5; // s156 xor + r1 = mul_hi(r1, r6); // s157 mulhi + r4 = r7 * r3 + r4; // s158 mad + r4 = r4 - r7; // s159 sub + } + r2 = r2 - r4; // 43 sub + r6 = mul_hi(r6, r7); // 44 mulhi + r3 = rotl_imm(r3, 13u); // 45 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 16u); r7 = r7 ^ t_; } // 46 shfl + r2 = rotl_imm(r2, 26u); // 47 rotl + r6 = r6 * r2; // 48 mul + r2 = r2 ^ ds[r3 & mask]; // 49 load + // per-load shadow sub-block 10 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 10 + for (uint sh10 = 0u; sh10 < 27u; ++sh10) { + r3 = r3 ^ r2; // s160 xor + r3 = mul_hi(r3, r4); // s161 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 1u); r3 = r3 ^ t_; } // s162 shfl + r0 = r0 - r1; // s163 sub + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 8u); r6 = r6 ^ t_; } // s164 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 2u); r4 = r4 ^ t_; } // s165 shfl + r3 = r3 | r6; // s166 or + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r6 = r6 ^ t_; } // s167 shfl + r2 = r2 ^ r1; // s168 xor + r5 = r5 ^ r1; // s169 xor + r5 = r5 ^ r0; // s170 xor + r3 = r6 * r0 + r3; // s171 mad + r3 = r3 - r0; // s172 sub + r6 = r6 + r0 + ((((sel >> 27u) & 1u) != 0u) ? 0xc72dc2a0u : 0x3b90694bu); // s173 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r7 = r7 ^ t_; } // s174 shfl + r5 = mul_hi(r5, r2); // s175 mulhi + } + r5 = r5 ^ ds[r1 & mask]; // 50 load + // per-load shadow sub-block 11 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 11 + for (uint sh11 = 0u; sh11 < 27u; ++sh11) { + r3 = r3 + r6 + ((((sel >> 5u) & 1u) != 0u) ? 0x4eb75843u : 0x9e65cebdu); // s176 add + r0 = r4 * r1 + r0; // s177 mad + r6 = rotr_var(r6, r7); // s178 rotr + r0 = r0 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0x7001d036u : 0x01e5b250u); // s179 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 16u); r5 = r5 ^ t_; } // s180 shfl + r3 = r3 * r0; // s181 mul + r0 = rotl_imm(r0, 23u); // s182 rotl + r7 = mul_hi(r7, r0); // s183 mulhi + r0 = r0 * r4; // s184 mul + r1 = r1 + r4 + ((((sel >> 19u) & 1u) != 0u) ? 0x91736711u : 0xbef14988u); // s185 add + r7 = r7 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x15e0cdf3u : 0xf5d741beu); // s186 add + r1 = r1 ^ r7; // s187 xor + r1 = r1 + r3 + ((((sel >> 21u) & 1u) != 0u) ? 0x7549bc3eu : 0x32be33c6u); // s188 add + r1 = r0 * r6 + r1; // s189 mad + r0 = rotr_var(r0, r5); // s190 rotr + r4 = r0 * r1 + r4; // s191 mad + } + r0 = rotl_imm(r0, 20u); // 51 rotl + r1 = r1 ^ r2; // 52 xor + r2 = r2 ^ ds[r1 & mask]; // 53 load + // per-load shadow sub-block 12 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 12 + for (uint sh12 = 0u; sh12 < 27u; ++sh12) { + r3 = r6 * r1 + r3; // s192 mad + r6 = rotl_imm(r6, 31u); // s193 rotl + r5 = rotl_imm(r5, 28u); // s194 rotl + r4 = r4 * r3; // s195 mul + r2 = r2 + r3 + ((((sel >> 4u) & 1u) != 0u) ? 0x7c3d6253u : 0x9d7aebbbu); // s196 add + r3 = r3 | r5; // s197 or + r6 = r6 - r0; // s198 sub + r7 = r7 * r4; // s199 mul + r3 = rotr_var(r3, r2); // s200 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 16u); r4 = r4 ^ t_; } // s201 shfl + r7 = r7 ^ r3; // s202 xor + r4 = r4 | r3; // s203 or + r3 = rotr_var(r3, r6); // s204 rotr + r0 = rotr_var(r0, r1); // s205 rotr + r2 = r5 * r2 + r2; // s206 mad + r1 = mul_hi(r1, r5); // s207 mulhi + } + r4 = rotl_imm(r4, 20u); // 54 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r3 = r3 ^ t_; } // 55 shfl + r1 = r1 ^ ds[r0 & mask]; // 56 load + // per-load shadow sub-block 13 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 13 + for (uint sh13 = 0u; sh13 < 27u; ++sh13) { + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 1u); r4 = r4 ^ t_; } // s208 shfl + r7 = r5 * r7 + r7; // s209 mad + r6 = r6 ^ r3; // s210 xor + r3 = r3 ^ r2; // s211 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 16u); r5 = r5 ^ t_; } // s212 shfl + r4 = rotl_imm(r4, 10u); // s213 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 16u); r5 = r5 ^ t_; } // s214 shfl + r3 = r3 | r0; // s215 or + r4 = r4 * r5; // s216 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 16u); r0 = r0 ^ t_; } // s217 shfl + r0 = r0 * r5; // s218 mul + r0 = rotl_imm(r0, 13u); // s219 rotl + r1 = mul_hi(r1, r0); // s220 mulhi + r4 = r4 ^ r1; // s221 xor + r2 = r2 | r3; // s222 or + r0 = r0 ^ r4; // s223 xor + } + r3 = r3 ^ ds[r5 & mask]; // 57 load + // per-load shadow sub-block 14 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 14 + for (uint sh14 = 0u; sh14 < 27u; ++sh14) { + r5 = r6 * r1 + r5; // s224 mad + r4 = r4 ^ r3; // s225 xor + r5 = r5 + r0 + ((((sel >> 3u) & 1u) != 0u) ? 0xe4e51c75u : 0xfe960971u); // s226 add + r3 = mul_hi(r3, r2); // s227 mulhi + r2 = r2 ^ r6; // s228 xor + r1 = mul_hi(r1, r5); // s229 mulhi + r3 = r3 + r4 + ((((sel >> 25u) & 1u) != 0u) ? 0x4d597c08u : 0x48b3ce0au); // s230 add + r2 = rotr_var(r2, r3); // s231 rotr + r2 = r2 - r7; // s232 sub + r6 = r6 | r2; // s233 or + r0 = rotr_var(r0, r3); // s234 rotr + r4 = r4 + r3 + ((((sel >> 13u) & 1u) != 0u) ? 0xc9f1d54cu : 0x2ed8c878u); // s235 add + r0 = r3 * r7 + r0; // s236 mad + r3 = r3 + r5 + ((((sel >> 29u) & 1u) != 0u) ? 0xc572bd00u : 0x22e8b90au); // s237 add + r0 = mul_hi(r0, r4); // s238 mulhi + r6 = r6 * r5; // s239 mul + } + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 2u); r1 = r1 ^ t_; } // 58 shfl + r6 = r6 ^ ds[r4 & mask]; // 59 load + // per-load shadow sub-block 15 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 15 + for (uint sh15 = 0u; sh15 < 27u; ++sh15) { + r5 = r5 + r2 + ((((sel >> 20u) & 1u) != 0u) ? 0xb233f94fu : 0xc6b790e6u); // s240 add + r0 = r0 - r3; // s241 sub + r4 = r4 + r7 + ((((sel >> 4u) & 1u) != 0u) ? 0x534d924bu : 0x0f918d3bu); // s242 add + r5 = rotr_var(r5, r0); // s243 rotr + r1 = rotr_var(r1, r7); // s244 rotr + r2 = r2 | r0; // s245 or + r4 = r4 * r7; // s246 mul + r1 = r2 * r5 + r1; // s247 mad + r2 = r2 * r5; // s248 mul + r4 = r4 ^ r2; // s249 xor + r3 = r3 ^ r1; // s250 xor + r5 = rotr_var(r5, r7); // s251 rotr + r2 = r7 * r7 + r2; // s252 mad + r7 = rotr_var(r7, r3); // s253 rotr + r6 = r6 + r1 + ((((sel >> 21u) & 1u) != 0u) ? 0x86d27169u : 0xb8a27d95u); // s254 add + r6 = r6 | r7; // s255 or + } + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r7 = r7 ^ t_; } // 60 shfl + r5 = rotr_var(r5, r0); // 61 rotr + r0 = r0 + r6 + ((((sel >> 14u) & 1u) != 0u) ? 0xb13a5391u : 0x8c2e5c24u); // 62 add + r2 = r2 + r1 + ((((sel >> 21u) & 1u) != 0u) ? 0xf82fc8b5u : 0xb225b762u); // 63 add + } + uint lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((ulong)hi << 32) | (ulong)lo; +} diff --git a/proto-cuda/packs-ca4/mx8_shl256x27_v2/kernel_bound.cu b/proto-cuda/packs-ca4/mx8_shl256x27_v2/kernel_bound.cu new file mode 100644 index 000000000..667f26d04 --- /dev/null +++ b/proto-cuda/packs-ca4/mx8_shl256x27_v2/kernel_bound.cu @@ -0,0 +1,427 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Header-bound twin of igneum_hash in kernel.cu: the init words come from a kernel argument, not SEEDW. +// Host declarations (also in program_bound.h if present): +// struct IgneumInitWords { uint32_t w[8]; }; +// cudaError_t igneum_launch_hash_bound(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, +// IgneumInitWords iw, uint32_t nonces, uint32_t blockWarps); +// cudaError_t igneum_hash_bound_info(int* numRegs, int* blocksPerSM, uint32_t blockWarps); +#include +#include +#include "program.h" + +struct IgneumInitWords { uint32_t w[8]; }; + +__device__ __forceinline__ uint32_t splitmix32(uint32_t x) { + x ^= x >> 16; x *= 0x7feb352du; + x ^= x >> 15; x *= 0x846ca68bu; + x ^= x >> 16; + return x; +} +__device__ __forceinline__ uint32_t rotl_imm(uint32_t x, uint32_t n) { return (x << n) | (x >> (32u - n)); } +__device__ __forceinline__ uint32_t rotr_var(uint32_t x, uint32_t n) { n &= 31u; return (x >> n) | (x << ((32u - n) & 31u)); } + +__global__ void igneum_hash_bound(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, IgneumInitWords iw) { + uint32_t gid = blockIdx.x * blockDim.x + threadIdx.x; + uint32_t nonce = baseNonce + gid; + uint32_t r0, r1, r2, r3, r4, r5, r6, r7; + { uint32_t x = nonce ^ iw.w[0]; x += 0x9e3779b9u * 1u; x = splitmix32(x); r0 = x ^ iw.w[1]; } + { uint32_t x = nonce ^ iw.w[1]; x += 0x9e3779b9u * 2u; x = splitmix32(x); r1 = x ^ iw.w[2]; } + { uint32_t x = nonce ^ iw.w[2]; x += 0x9e3779b9u * 3u; x = splitmix32(x); r2 = x ^ iw.w[3]; } + { uint32_t x = nonce ^ iw.w[3]; x += 0x9e3779b9u * 4u; x = splitmix32(x); r3 = x ^ iw.w[4]; } + { uint32_t x = nonce ^ iw.w[4]; x += 0x9e3779b9u * 5u; x = splitmix32(x); r4 = x ^ iw.w[5]; } + { uint32_t x = nonce ^ iw.w[5]; x += 0x9e3779b9u * 6u; x = splitmix32(x); r5 = x ^ iw.w[6]; } + { uint32_t x = nonce ^ iw.w[6]; x += 0x9e3779b9u * 7u; x = splitmix32(x); r6 = x ^ iw.w[7]; } + { uint32_t x = nonce ^ iw.w[7]; x += 0x9e3779b9u * 8u; x = splitmix32(x); r7 = x ^ iw.w[0]; } + + for (uint32_t it = 0u; it < 8u; ++it) { + uint32_t sel = r0; + r2 = r2 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0x894e457du : 0xe3e2ed7du); // 0 add + r7 = r4 * r0 + r7; // 1 mad + r3 = r3 - r6; // 2 sub + r5 = rotr_var(r5, r1); // 3 rotr + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r2, 1); // 4 shfl + r0 = r0 | r3; // 5 or + r0 = r0 * r1; // 6 mul + r7 = r7 * r6; // 7 mul + r3 = r3 ^ ds[r0 & mask]; // 8 load + // per-load shadow sub-block 0 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 0 + for (uint32_t sh0 = 0u; sh0 < 27u; ++sh0) { + r5 = rotr_var(r5, r4); // s0 rotr + r6 = r6 - r5; // s1 sub + r7 = r7 - r6; // s2 sub + r5 = r5 * r4; // s3 mul + r7 = r7 ^ r6; // s4 xor + r2 = rotl_imm(r2, 23u); // s5 rotl + r7 = r7 ^ r4; // s6 xor + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x3051c491u : 0xdaef8862u); // s7 add + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r1, 4); // s8 shfl + r5 = r5 + r1 + ((((sel >> 26u) & 1u) != 0u) ? 0x5170d0b3u : 0xc20e7045u); // s9 add + r0 = r0 | r3; // s10 or + r5 = __umulhi(r5, r4); // s11 mulhi + r7 = r7 ^ r0; // s12 xor + r5 = r5 - r2; // s13 sub + r0 = r0 + r6 + ((((sel >> 0u) & 1u) != 0u) ? 0x2ead087fu : 0xc86d98a4u); // s14 add + r5 = r5 ^ r7; // s15 xor + } + r4 = r4 + r3 + ((((sel >> 22u) & 1u) != 0u) ? 0xd26d3573u : 0xce9bea84u); // 9 add + r2 = r2 * r4; // 10 mul + r3 = r3 ^ ds[r2 & mask]; // 11 load + // per-load shadow sub-block 1 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 1 + for (uint32_t sh1 = 0u; sh1 < 27u; ++sh1) { + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r6, 8); // s16 shfl + r5 = r5 - r7; // s17 sub + r0 = r0 | r6; // s18 or + r0 = r0 + r5 + ((((sel >> 13u) & 1u) != 0u) ? 0xc47c70a8u : 0x4248b651u); // s19 add + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r5, 16); // s20 shfl + r0 = r0 + r4 + ((((sel >> 21u) & 1u) != 0u) ? 0x718c1008u : 0x1e35684fu); // s21 add + r0 = __umulhi(r0, r3); // s22 mulhi + r4 = r4 ^ r2; // s23 xor + r0 = r0 - r2; // s24 sub + r5 = rotl_imm(r5, 13u); // s25 rotl + r7 = r7 - r0; // s26 sub + r2 = r2 ^ r3; // s27 xor + r2 = r3 * r2 + r2; // s28 mad + r2 = r2 ^ r1; // s29 xor + r4 = __umulhi(r4, r0); // s30 mulhi + r6 = r6 ^ r4; // s31 xor + } + r4 = __umulhi(r4, r1); // 12 mulhi + r7 = __umulhi(r7, r3); // 13 mulhi + r3 = r3 + r2 + ((((sel >> 8u) & 1u) != 0u) ? 0xc2828a42u : 0x514f9ff4u); // 14 add + r1 = r3 * r2 + r1; // 15 mad + r2 = rotl_imm(r2, 7u); // 16 rotl + r1 = r1 ^ ds[r2 & mask]; // 17 load + // per-load shadow sub-block 2 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 2 + for (uint32_t sh2 = 0u; sh2 < 27u; ++sh2) { + r4 = r4 ^ r2; // s32 xor + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r2, 1); // s33 shfl + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r6, 1); // s34 shfl + r4 = r4 - r0; // s35 sub + r6 = r6 - r3; // s36 sub + r2 = r2 | r6; // s37 or + r2 = rotl_imm(r2, 30u); // s38 rotl + r4 = rotr_var(r4, r7); // s39 rotr + r0 = r0 | r7; // s40 or + r2 = rotr_var(r2, r5); // s41 rotr + r1 = r3 * r3 + r1; // s42 mad + r6 = r5 * r5 + r6; // s43 mad + r1 = __umulhi(r1, r0); // s44 mulhi + r1 = r1 * r3; // s45 mul + r0 = r2 * r0 + r0; // s46 mad + r1 = r1 - r5; // s47 sub + } + r3 = r3 * r2; // 18 mul + r6 = rotl_imm(r6, 24u); // 19 rotl + r6 = r6 ^ ds[r3 & mask]; // 20 load + // per-load shadow sub-block 3 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 3 + for (uint32_t sh3 = 0u; sh3 < 27u; ++sh3) { + r4 = r4 ^ r0; // s48 xor + r2 = rotr_var(r2, r0); // s49 rotr + r0 = __umulhi(r0, r5); // s50 mulhi + r7 = r7 | r5; // s51 or + r4 = r0 * r3 + r4; // s52 mad + r0 = rotr_var(r0, r4); // s53 rotr + r6 = r3 * r3 + r6; // s54 mad + r6 = r4 * r2 + r6; // s55 mad + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r0, 2); // s56 shfl + r7 = rotl_imm(r7, 21u); // s57 rotl + r3 = r3 ^ r7; // s58 xor + r0 = r0 ^ __shfl_xor_sync(0xffffffffu, r4, 1); // s59 shfl + r5 = r5 ^ r6; // s60 xor + r4 = rotr_var(r4, r7); // s61 rotr + r1 = r1 + r6 + ((((sel >> 10u) & 1u) != 0u) ? 0x31f87d74u : 0xf7ccf1e9u); // s62 add + r5 = r5 + r2 + ((((sel >> 15u) & 1u) != 0u) ? 0x9c2847f4u : 0x2f386099u); // s63 add + } + r1 = r1 ^ ds[r6 & mask]; // 21 load + // per-load shadow sub-block 4 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 4 + for (uint32_t sh4 = 0u; sh4 < 27u; ++sh4) { + r7 = r7 + r0 + ((((sel >> 19u) & 1u) != 0u) ? 0xd3241188u : 0x1b30ce7au); // s64 add + r6 = r6 + r7 + ((((sel >> 13u) & 1u) != 0u) ? 0x9b42c3deu : 0x02dc8349u); // s65 add + r0 = rotl_imm(r0, 16u); // s66 rotl + r2 = rotl_imm(r2, 9u); // s67 rotl + r2 = r5 * r6 + r2; // s68 mad + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r1, 8); // s69 shfl + r2 = r2 ^ r5; // s70 xor + r5 = __umulhi(r5, r1); // s71 mulhi + r6 = rotl_imm(r6, 29u); // s72 rotl + r0 = r0 - r7; // s73 sub + r5 = r2 * r2 + r5; // s74 mad + r0 = rotr_var(r0, r5); // s75 rotr + r7 = r7 + r2 + ((((sel >> 9u) & 1u) != 0u) ? 0x0da1ce17u : 0x05d36679u); // s76 add + r7 = r7 - r2; // s77 sub + r7 = rotr_var(r7, r0); // s78 rotr + r1 = r5 * r5 + r1; // s79 mad + } + r5 = r3 * r3 + r5; // 22 mad + r4 = r4 ^ ds[r7 & mask]; // 23 load + // per-load shadow sub-block 5 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 5 + for (uint32_t sh5 = 0u; sh5 < 27u; ++sh5) { + r3 = rotr_var(r3, r0); // s80 rotr + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xadf5ef88u : 0xf14547bdu); // s81 add + r0 = r0 | r6; // s82 or + r1 = __umulhi(r1, r0); // s83 mulhi + r7 = r6 * r7 + r7; // s84 mad + r5 = rotl_imm(r5, 29u); // s85 rotl + r2 = r2 ^ r6; // s86 xor + r5 = r5 + r4 + ((((sel >> 24u) & 1u) != 0u) ? 0x35ff14aeu : 0xba4947c2u); // s87 add + r3 = r3 + r6 + ((((sel >> 3u) & 1u) != 0u) ? 0xf3900fc1u : 0xf6878beeu); // s88 add + r0 = r0 + r2 + ((((sel >> 12u) & 1u) != 0u) ? 0xf7e8f59fu : 0x926f3607u); // s89 add + r2 = r2 ^ r6; // s90 xor + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r2, 2); // s91 shfl + r6 = r6 - r1; // s92 sub + r5 = r5 + r1 + ((((sel >> 13u) & 1u) != 0u) ? 0x0e376f9cu : 0xdab36c29u); // s93 add + r6 = r1 * r1 + r6; // s94 mad + r3 = r3 ^ r4; // s95 xor + } + r6 = r6 ^ ds[r4 & mask]; // 24 load + // per-load shadow sub-block 6 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 6 + for (uint32_t sh6 = 0u; sh6 < 27u; ++sh6) { + r6 = r5 * r2 + r6; // s96 mad + r7 = r7 + r3 + ((((sel >> 23u) & 1u) != 0u) ? 0x9f917747u : 0x204129e9u); // s97 add + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r1, 16); // s98 shfl + r2 = r2 * r6; // s99 mul + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r3, 8); // s100 shfl + r6 = r6 + r1 + ((((sel >> 10u) & 1u) != 0u) ? 0xe42fe974u : 0xe3b596a0u); // s101 add + r5 = rotl_imm(r5, 3u); // s102 rotl + r5 = r5 ^ r1; // s103 xor + r4 = r4 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0xc3d77ffbu : 0x705c3f94u); // s104 add + r0 = r0 + r6 + ((((sel >> 25u) & 1u) != 0u) ? 0xea02a4cau : 0xbc6fb42bu); // s105 add + r3 = r3 | r5; // s106 or + r0 = r0 - r6; // s107 sub + r0 = rotr_var(r0, r3); // s108 rotr + r5 = r5 + r4 + ((((sel >> 4u) & 1u) != 0u) ? 0x0357e63eu : 0xcb37ea87u); // s109 add + r7 = rotl_imm(r7, 5u); // s110 rotl + r4 = r4 ^ r1; // s111 xor + } + r5 = r5 * r7; // 25 mul + r0 = r0 * r3; // 26 mul + r0 = r0 | r3; // 27 or + r1 = r3 * r4 + r1; // 28 mad + r0 = r0 ^ __shfl_xor_sync(0xffffffffu, r2, 8); // 29 shfl + r7 = r7 - r3; // 30 sub + r4 = r4 ^ r1; // 31 xor + r4 = r4 | r5; // 32 or + r3 = rotr_var(r3, r5); // 33 rotr + r4 = r4 ^ ds[r5 & mask]; // 34 load + // per-load shadow sub-block 7 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 7 + for (uint32_t sh7 = 0u; sh7 < 27u; ++sh7) { + r6 = r6 ^ r5; // s112 xor + r1 = r1 | r3; // s113 or + r0 = r0 + r5 + ((((sel >> 3u) & 1u) != 0u) ? 0x7f8b8cd2u : 0x9aab0297u); // s114 add + r3 = r3 - r5; // s115 sub + r4 = rotr_var(r4, r2); // s116 rotr + r4 = r4 + r6 + ((((sel >> 6u) & 1u) != 0u) ? 0x59400b57u : 0xc511183fu); // s117 add + r6 = r6 - r1; // s118 sub + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r1, 4); // s119 shfl + r6 = r4 * r4 + r6; // s120 mad + r2 = rotl_imm(r2, 8u); // s121 rotl + r5 = r0 * r3 + r5; // s122 mad + r7 = r7 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x27c70dc0u : 0x5200c242u); // s123 add + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r5, 4); // s124 shfl + r0 = r0 + r1 + ((((sel >> 17u) & 1u) != 0u) ? 0xec2f5997u : 0x2d5028ceu); // s125 add + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r6, 16); // s126 shfl + r5 = r5 ^ r0; // s127 xor + } + r0 = r5 * r3 + r0; // 35 mad + r6 = r6 ^ ds[r3 & mask]; // 36 load + // per-load shadow sub-block 8 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 8 + for (uint32_t sh8 = 0u; sh8 < 27u; ++sh8) { + r7 = r7 + r1 + ((((sel >> 10u) & 1u) != 0u) ? 0x09e8ede2u : 0x432f6c0du); // s128 add + r2 = r2 ^ r4; // s129 xor + r0 = r0 * r2; // s130 mul + r4 = r4 | r3; // s131 or + r3 = r3 | r7; // s132 or + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r3, 1); // s133 shfl + r5 = r5 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0xce4fdf8eu : 0xcf5ecc75u); // s134 add + r3 = r2 * r3 + r3; // s135 mad + r1 = rotl_imm(r1, 11u); // s136 rotl + r2 = r2 | r0; // s137 or + r3 = r3 ^ r4; // s138 xor + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 1); // s139 shfl + r2 = rotl_imm(r2, 6u); // s140 rotl + r0 = r0 * r3; // s141 mul + r1 = r1 * r7; // s142 mul + r0 = r0 ^ r1; // s143 xor + } + r5 = r5 * r3; // 37 mul + r5 = r5 ^ r4; // 38 xor + r6 = r6 ^ r0; // 39 xor + r4 = rotr_var(r4, r0); // 40 rotr + r7 = r7 ^ r6; // 41 xor + r1 = r1 ^ ds[r7 & mask]; // 42 load + // per-load shadow sub-block 9 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 9 + for (uint32_t sh9 = 0u; sh9 < 27u; ++sh9) { + r6 = r2 * r0 + r6; // s144 mad + r1 = rotl_imm(r1, 15u); // s145 rotl + r1 = rotl_imm(r1, 30u); // s146 rotl + r6 = r6 ^ r0; // s147 xor + r3 = r3 - r2; // s148 sub + r3 = r3 + r0 + ((((sel >> 5u) & 1u) != 0u) ? 0x11bbdeefu : 0xaa002f15u); // s149 add + r6 = r6 + r5 + ((((sel >> 9u) & 1u) != 0u) ? 0xff9d4b0eu : 0xbe64b2e2u); // s150 add + r1 = r1 * r4; // s151 mul + r5 = rotl_imm(r5, 3u); // s152 rotl + r5 = r5 * r2; // s153 mul + r2 = rotl_imm(r2, 21u); // s154 rotl + r5 = rotl_imm(r5, 18u); // s155 rotl + r1 = r1 ^ r5; // s156 xor + r1 = __umulhi(r1, r6); // s157 mulhi + r4 = r7 * r3 + r4; // s158 mad + r4 = r4 - r7; // s159 sub + } + r2 = r2 - r4; // 43 sub + r6 = __umulhi(r6, r7); // 44 mulhi + r3 = rotl_imm(r3, 13u); // 45 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r6, 16); // 46 shfl + r2 = rotl_imm(r2, 26u); // 47 rotl + r6 = r6 * r2; // 48 mul + r2 = r2 ^ ds[r3 & mask]; // 49 load + // per-load shadow sub-block 10 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 10 + for (uint32_t sh10 = 0u; sh10 < 27u; ++sh10) { + r3 = r3 ^ r2; // s160 xor + r3 = __umulhi(r3, r4); // s161 mulhi + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r2, 1); // s162 shfl + r0 = r0 - r1; // s163 sub + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r0, 8); // s164 shfl + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r2, 2); // s165 shfl + r3 = r3 | r6; // s166 or + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r3, 4); // s167 shfl + r2 = r2 ^ r1; // s168 xor + r5 = r5 ^ r1; // s169 xor + r5 = r5 ^ r0; // s170 xor + r3 = r6 * r0 + r3; // s171 mad + r3 = r3 - r0; // s172 sub + r6 = r6 + r0 + ((((sel >> 27u) & 1u) != 0u) ? 0xc72dc2a0u : 0x3b90694bu); // s173 add + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r2, 8); // s174 shfl + r5 = __umulhi(r5, r2); // s175 mulhi + } + r5 = r5 ^ ds[r1 & mask]; // 50 load + // per-load shadow sub-block 11 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 11 + for (uint32_t sh11 = 0u; sh11 < 27u; ++sh11) { + r3 = r3 + r6 + ((((sel >> 5u) & 1u) != 0u) ? 0x4eb75843u : 0x9e65cebdu); // s176 add + r0 = r4 * r1 + r0; // s177 mad + r6 = rotr_var(r6, r7); // s178 rotr + r0 = r0 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0x7001d036u : 0x01e5b250u); // s179 add + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r2, 16); // s180 shfl + r3 = r3 * r0; // s181 mul + r0 = rotl_imm(r0, 23u); // s182 rotl + r7 = __umulhi(r7, r0); // s183 mulhi + r0 = r0 * r4; // s184 mul + r1 = r1 + r4 + ((((sel >> 19u) & 1u) != 0u) ? 0x91736711u : 0xbef14988u); // s185 add + r7 = r7 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x15e0cdf3u : 0xf5d741beu); // s186 add + r1 = r1 ^ r7; // s187 xor + r1 = r1 + r3 + ((((sel >> 21u) & 1u) != 0u) ? 0x7549bc3eu : 0x32be33c6u); // s188 add + r1 = r0 * r6 + r1; // s189 mad + r0 = rotr_var(r0, r5); // s190 rotr + r4 = r0 * r1 + r4; // s191 mad + } + r0 = rotl_imm(r0, 20u); // 51 rotl + r1 = r1 ^ r2; // 52 xor + r2 = r2 ^ ds[r1 & mask]; // 53 load + // per-load shadow sub-block 12 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 12 + for (uint32_t sh12 = 0u; sh12 < 27u; ++sh12) { + r3 = r6 * r1 + r3; // s192 mad + r6 = rotl_imm(r6, 31u); // s193 rotl + r5 = rotl_imm(r5, 28u); // s194 rotl + r4 = r4 * r3; // s195 mul + r2 = r2 + r3 + ((((sel >> 4u) & 1u) != 0u) ? 0x7c3d6253u : 0x9d7aebbbu); // s196 add + r3 = r3 | r5; // s197 or + r6 = r6 - r0; // s198 sub + r7 = r7 * r4; // s199 mul + r3 = rotr_var(r3, r2); // s200 rotr + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r0, 16); // s201 shfl + r7 = r7 ^ r3; // s202 xor + r4 = r4 | r3; // s203 or + r3 = rotr_var(r3, r6); // s204 rotr + r0 = rotr_var(r0, r1); // s205 rotr + r2 = r5 * r2 + r2; // s206 mad + r1 = __umulhi(r1, r5); // s207 mulhi + } + r4 = rotl_imm(r4, 20u); // 54 rotl + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // 55 shfl + r1 = r1 ^ ds[r0 & mask]; // 56 load + // per-load shadow sub-block 13 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 13 + for (uint32_t sh13 = 0u; sh13 < 27u; ++sh13) { + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r3, 1); // s208 shfl + r7 = r5 * r7 + r7; // s209 mad + r6 = r6 ^ r3; // s210 xor + r3 = r3 ^ r2; // s211 xor + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r6, 16); // s212 shfl + r4 = rotl_imm(r4, 10u); // s213 rotl + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r6, 16); // s214 shfl + r3 = r3 | r0; // s215 or + r4 = r4 * r5; // s216 mul + r0 = r0 ^ __shfl_xor_sync(0xffffffffu, r3, 16); // s217 shfl + r0 = r0 * r5; // s218 mul + r0 = rotl_imm(r0, 13u); // s219 rotl + r1 = __umulhi(r1, r0); // s220 mulhi + r4 = r4 ^ r1; // s221 xor + r2 = r2 | r3; // s222 or + r0 = r0 ^ r4; // s223 xor + } + r3 = r3 ^ ds[r5 & mask]; // 57 load + // per-load shadow sub-block 14 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 14 + for (uint32_t sh14 = 0u; sh14 < 27u; ++sh14) { + r5 = r6 * r1 + r5; // s224 mad + r4 = r4 ^ r3; // s225 xor + r5 = r5 + r0 + ((((sel >> 3u) & 1u) != 0u) ? 0xe4e51c75u : 0xfe960971u); // s226 add + r3 = __umulhi(r3, r2); // s227 mulhi + r2 = r2 ^ r6; // s228 xor + r1 = __umulhi(r1, r5); // s229 mulhi + r3 = r3 + r4 + ((((sel >> 25u) & 1u) != 0u) ? 0x4d597c08u : 0x48b3ce0au); // s230 add + r2 = rotr_var(r2, r3); // s231 rotr + r2 = r2 - r7; // s232 sub + r6 = r6 | r2; // s233 or + r0 = rotr_var(r0, r3); // s234 rotr + r4 = r4 + r3 + ((((sel >> 13u) & 1u) != 0u) ? 0xc9f1d54cu : 0x2ed8c878u); // s235 add + r0 = r3 * r7 + r0; // s236 mad + r3 = r3 + r5 + ((((sel >> 29u) & 1u) != 0u) ? 0xc572bd00u : 0x22e8b90au); // s237 add + r0 = __umulhi(r0, r4); // s238 mulhi + r6 = r6 * r5; // s239 mul + } + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r2, 2); // 58 shfl + r6 = r6 ^ ds[r4 & mask]; // 59 load + // per-load shadow sub-block 15 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 15 + for (uint32_t sh15 = 0u; sh15 < 27u; ++sh15) { + r5 = r5 + r2 + ((((sel >> 20u) & 1u) != 0u) ? 0xb233f94fu : 0xc6b790e6u); // s240 add + r0 = r0 - r3; // s241 sub + r4 = r4 + r7 + ((((sel >> 4u) & 1u) != 0u) ? 0x534d924bu : 0x0f918d3bu); // s242 add + r5 = rotr_var(r5, r0); // s243 rotr + r1 = rotr_var(r1, r7); // s244 rotr + r2 = r2 | r0; // s245 or + r4 = r4 * r7; // s246 mul + r1 = r2 * r5 + r1; // s247 mad + r2 = r2 * r5; // s248 mul + r4 = r4 ^ r2; // s249 xor + r3 = r3 ^ r1; // s250 xor + r5 = rotr_var(r5, r7); // s251 rotr + r2 = r7 * r7 + r2; // s252 mad + r7 = rotr_var(r7, r3); // s253 rotr + r6 = r6 + r1 + ((((sel >> 21u) & 1u) != 0u) ? 0x86d27169u : 0xb8a27d95u); // s254 add + r6 = r6 | r7; // s255 or + } + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r3, 4); // 60 shfl + r5 = rotr_var(r5, r0); // 61 rotr + r0 = r0 + r6 + ((((sel >> 14u) & 1u) != 0u) ? 0xb13a5391u : 0x8c2e5c24u); // 62 add + r2 = r2 + r1 + ((((sel >> 21u) & 1u) != 0u) ? 0xf82fc8b5u : 0xb225b762u); // 63 add + } + uint32_t lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint32_t hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((uint64_t)hi << 32) | (uint64_t)lo; +} + +cudaError_t igneum_launch_hash_bound(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, + IgneumInitWords iw, uint32_t nonces, uint32_t blockWarps) { + if (blockWarps == 0u || blockWarps > 32u) return cudaErrorInvalidValue; + uint32_t block = 32u * blockWarps; + if (nonces == 0u || (nonces % block) != 0u) return cudaErrorInvalidValue; + igneum_hash_bound<<>>(ds, out, baseNonce, mask, iw); + return cudaGetLastError(); +} + +cudaError_t igneum_hash_bound_info(int* numRegs, int* blocksPerSM, uint32_t blockWarps) { + cudaFuncAttributes attr; + cudaError_t e = cudaFuncGetAttributes(&attr, igneum_hash_bound); + if (e != cudaSuccess) return e; + *numRegs = attr.numRegs; + return cudaOccupancyMaxActiveBlocksPerMultiprocessor(blocksPerSM, igneum_hash_bound, (int)(32u * blockWarps), 0); +} diff --git a/proto-cuda/packs-ca4/mx8_shl256x27_v2/memhard.h b/proto-cuda/packs-ca4/mx8_shl256x27_v2/memhard.h new file mode 100644 index 000000000..f7f34c732 --- /dev/null +++ b/proto-cuda/packs-ca4/mx8_shl256x27_v2/memhard.h @@ -0,0 +1,109 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Memory-hard dataset core, the same text that the Mac's Metal kernels and CPU verifier were checked against. +// Included by kernel.cu (device), host.cu (host reference) and proto-opencl/host.c (C99 host reference). +// See proto-metal/MEMHARD.md for the construction. kernel.cl carries the same text in OpenCL C. +#pragma once +#ifdef __cplusplus +#include +#else +#include +#endif +#if defined(__CUDACC__) +#define IGNEUM_HD __host__ __device__ __forceinline__ +#elif defined(_MSC_VER) && !defined(__cplusplus) +#define IGNEUM_HD static __inline +#else +#define IGNEUM_HD static inline +#endif +// Memory-hard dataset core (MEMHARD.md). Cache: 2^26 words in 2^16 segments of 64 chained ChaCha12 lines. +// Item: 8 rounds of 8 x seed-parameterised mixer + one 64-byte cache read, then 8 x final mixer (class v3, mixer multiplier 8, +// docs/plans/mixer-x4.md: the round key of application j of round r is 0x9E3779B9 * (r * m + j + 1)). All parameters are literals. +#define MH_CACHE_LINE_MASK 0x003fffffu +#define MH_SEGMENT_LINES 64u +#define MH_QR(a, b, c, d, r1, r2, r3, r4) { a += b; d ^= a; d = mh_rotl(d, r1); c += d; b ^= c; b = mh_rotl(b, r2); a += b; d ^= a; d = mh_rotl(d, r3); c += d; b ^= c; b = mh_rotl(b, r4); } +IGNEUM_HD uint32_t mh_rotl(uint32_t x, uint32_t n) { return (x << n) | (x >> (32u - n)); } // n in 1..31 at every call site + +// y = ChaCha12 core(x) + x +IGNEUM_HD void mh_chacha_block(const uint32_t* x, uint32_t* y) { + for (uint32_t i = 0u; i < 16u; ++i) y[i] = x[i]; + for (uint32_t r = 0u; r < 6u; ++r) { + MH_QR(y[0], y[4], y[8], y[12], 16u, 12u, 8u, 7u) MH_QR(y[1], y[5], y[9], y[13], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[6], y[10], y[14], 16u, 12u, 8u, 7u) MH_QR(y[3], y[7], y[11], y[15], 16u, 12u, 8u, 7u) + MH_QR(y[0], y[5], y[10], y[15], 16u, 12u, 8u, 7u) MH_QR(y[1], y[6], y[11], y[12], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[7], y[8], y[13], 16u, 12u, 8u, 7u) MH_QR(y[3], y[4], y[9], y[14], 16u, 12u, 8u, 7u) + } + for (uint32_t i = 0u; i < 16u; ++i) y[i] += x[i]; +} + +// One cache segment: 64 chained lines written at cache[seg * 1024]. in_j = prev ^ (sigma || K || seg || j || tag), prev_0 = 0. +IGNEUM_HD void mh_cache_segment(uint32_t* cache, uint32_t seg) { + uint32_t prev[16]; uint32_t x[16]; uint32_t y[16]; + for (uint32_t i = 0u; i < 16u; ++i) prev[i] = 0u; + for (uint32_t j = 0u; j < MH_SEGMENT_LINES; ++j) { + x[0] = 0x61707865u ^ prev[0]; x[1] = 0x3320646eu ^ prev[1]; x[2] = 0x79622d32u ^ prev[2]; x[3] = 0x6b206574u ^ prev[3]; + x[4] = 0x3067619fu ^ prev[4]; + x[5] = 0x3c269176u ^ prev[5]; + x[6] = 0x84a03b03u ^ prev[6]; + x[7] = 0xf8c63294u ^ prev[7]; + x[8] = 0xff977c5bu ^ prev[8]; + x[9] = 0xe60def3eu ^ prev[9]; + x[10] = 0x63630141u ^ prev[10]; + x[11] = 0xb8fbcb58u ^ prev[11]; + x[12] = seg ^ prev[12]; x[13] = j ^ prev[13]; x[14] = 0x49676e65u ^ prev[14]; x[15] = 0x756d4d48u ^ prev[15]; + mh_chacha_block(x, y); + uint32_t* line = cache + ((seg * MH_SEGMENT_LINES + j) * 16u); + for (uint32_t i = 0u; i < 16u; ++i) { line[i] = y[i]; prev[i] = y[i]; } + } +} + +// M_r: per word (s ^ (RC + rk)) * MUL, then a column round and a diagonal round with the seed-drawn rotations. +IGNEUM_HD void mh_mixer(uint32_t* s, uint32_t rk) { + s[0] = (s[0] ^ (0xbab68293u + rk)) * 0x42146205u; + s[1] = (s[1] ^ (0xcc162340u + rk)) * 0x52cbe0fbu; + s[2] = (s[2] ^ (0x6ce151ccu + rk)) * 0x7ecf4a03u; + s[3] = (s[3] ^ (0xe62b8997u + rk)) * 0x6728907fu; + s[4] = (s[4] ^ (0xc9c80297u + rk)) * 0xd81d9751u; + s[5] = (s[5] ^ (0xf74a1654u + rk)) * 0x132952c3u; + s[6] = (s[6] ^ (0x3d704af5u + rk)) * 0xf60de277u; + s[7] = (s[7] ^ (0x3cf522b7u + rk)) * 0x05358035u; + s[8] = (s[8] ^ (0x2b9cac04u + rk)) * 0xbaf6499du; + s[9] = (s[9] ^ (0xa880ac10u + rk)) * 0xe4db9667u; + s[10] = (s[10] ^ (0x13e5dd1du + rk)) * 0x3e98f45du; + s[11] = (s[11] ^ (0x6fc3e233u + rk)) * 0xd0004eddu; + s[12] = (s[12] ^ (0x2d83eeacu + rk)) * 0x2691630du; + s[13] = (s[13] ^ (0x9006e8bfu + rk)) * 0x9beb3bcfu; + s[14] = (s[14] ^ (0x2c4b5362u + rk)) * 0xab310379u; + s[15] = (s[15] ^ (0x31b49ee2u + rk)) * 0x99cfb423u; + MH_QR(s[0], s[4], s[8], s[12], 20u, 20u, 19u, 4u) MH_QR(s[1], s[5], s[9], s[13], 20u, 20u, 19u, 4u) + MH_QR(s[2], s[6], s[10], s[14], 20u, 20u, 19u, 4u) MH_QR(s[3], s[7], s[11], s[15], 20u, 20u, 19u, 4u) + MH_QR(s[0], s[5], s[10], s[15], 26u, 3u, 3u, 27u) MH_QR(s[1], s[6], s[11], s[12], 26u, 3u, 3u, 27u) + MH_QR(s[2], s[7], s[8], s[13], 26u, 3u, 3u, 27u) MH_QR(s[3], s[4], s[9], s[14], 26u, 3u, 3u, 27u) +} + +// Item t: 16 words. s = (K, t * MUL[i] + RC[i]); 8 rounds of 8 x mixer + cache line s[0] & mask; 8 x final mixer. +IGNEUM_HD void mh_item(const uint32_t* cache, uint32_t t, uint32_t* s) { + s[0] = 0x3067619fu; + s[1] = 0x3c269176u; + s[2] = 0x84a03b03u; + s[3] = 0xf8c63294u; + s[4] = 0xff977c5bu; + s[5] = 0xe60def3eu; + s[6] = 0x63630141u; + s[7] = 0xb8fbcb58u; + s[8] = t * 0x42146205u + 0xbab68293u; + s[9] = t * 0x52cbe0fbu + 0xcc162340u; + s[10] = t * 0x7ecf4a03u + 0x6ce151ccu; + s[11] = t * 0x6728907fu + 0xe62b8997u; + s[12] = t * 0xd81d9751u + 0xc9c80297u; + s[13] = t * 0x132952c3u + 0xf74a1654u; + s[14] = t * 0xf60de277u + 0x3d704af5u; + s[15] = t * 0x05358035u + 0x3cf522b7u; + for (uint32_t r = 0u; r < 8u; ++r) { + for (uint32_t j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (r * 8u + j + 1u)); + const uint32_t* line = cache + ((s[0] & MH_CACHE_LINE_MASK) * 16u); + for (uint32_t i = 0u; i < 16u; ++i) s[i] ^= line[i]; + } + for (uint32_t j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (64u + j + 1u)); +} +// dataset[w] without the dataset: derive item w >> 4 and take word w & 15. +IGNEUM_HD uint32_t mh_word(const uint32_t* cache, uint32_t w) { uint32_t s[16]; mh_item(cache, w >> 4u, s); return s[w & 15u]; } diff --git a/proto-cuda/packs-ca4/mx8_shl256x27_v2/memhard.metal b/proto-cuda/packs-ca4/mx8_shl256x27_v2/memhard.metal new file mode 100644 index 000000000..01b263d6d --- /dev/null +++ b/proto-cuda/packs-ca4/mx8_shl256x27_v2/memhard.metal @@ -0,0 +1,107 @@ +#include +using namespace metal; +// Memory-hard dataset core (MEMHARD.md). Cache: 2^26 words in 2^16 segments of 64 chained ChaCha12 lines. +// Item: 8 rounds of 8 x seed-parameterised mixer + one 64-byte cache read, then 8 x final mixer (class v3, mixer multiplier 8, +// docs/plans/mixer-x4.md: the round key of application j of round r is 0x9E3779B9 * (r * m + j + 1)). All parameters are literals. +#define MH_CACHE_LINE_MASK 0x003fffffu +#define MH_SEGMENT_LINES 64u +#define MH_QR(a, b, c, d, r1, r2, r3, r4) { a += b; d ^= a; d = mh_rotl(d, r1); c += d; b ^= c; b = mh_rotl(b, r2); a += b; d ^= a; d = mh_rotl(d, r3); c += d; b ^= c; b = mh_rotl(b, r4); } +inline uint mh_rotl(uint x, uint n) { return (x << n) | (x >> (32u - n)); } // n in 1..31 at every call site + +// y = ChaCha12 core(x) + x +inline void mh_chacha_block(const thread uint* x, thread uint* y) { + for (uint i = 0u; i < 16u; ++i) y[i] = x[i]; + for (uint r = 0u; r < 6u; ++r) { + MH_QR(y[0], y[4], y[8], y[12], 16u, 12u, 8u, 7u) MH_QR(y[1], y[5], y[9], y[13], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[6], y[10], y[14], 16u, 12u, 8u, 7u) MH_QR(y[3], y[7], y[11], y[15], 16u, 12u, 8u, 7u) + MH_QR(y[0], y[5], y[10], y[15], 16u, 12u, 8u, 7u) MH_QR(y[1], y[6], y[11], y[12], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[7], y[8], y[13], 16u, 12u, 8u, 7u) MH_QR(y[3], y[4], y[9], y[14], 16u, 12u, 8u, 7u) + } + for (uint i = 0u; i < 16u; ++i) y[i] += x[i]; +} + +// One cache segment: 64 chained lines written at cache[seg * 1024]. in_j = prev ^ (sigma || K || seg || j || tag), prev_0 = 0. +inline void mh_cache_segment(device uint* cache, uint seg) { + uint prev[16]; uint x[16]; uint y[16]; + for (uint i = 0u; i < 16u; ++i) prev[i] = 0u; + for (uint j = 0u; j < MH_SEGMENT_LINES; ++j) { + x[0] = 0x61707865u ^ prev[0]; x[1] = 0x3320646eu ^ prev[1]; x[2] = 0x79622d32u ^ prev[2]; x[3] = 0x6b206574u ^ prev[3]; + x[4] = 0x3067619fu ^ prev[4]; + x[5] = 0x3c269176u ^ prev[5]; + x[6] = 0x84a03b03u ^ prev[6]; + x[7] = 0xf8c63294u ^ prev[7]; + x[8] = 0xff977c5bu ^ prev[8]; + x[9] = 0xe60def3eu ^ prev[9]; + x[10] = 0x63630141u ^ prev[10]; + x[11] = 0xb8fbcb58u ^ prev[11]; + x[12] = seg ^ prev[12]; x[13] = j ^ prev[13]; x[14] = 0x49676e65u ^ prev[14]; x[15] = 0x756d4d48u ^ prev[15]; + mh_chacha_block(x, y); + device uint* line = cache + ((seg * MH_SEGMENT_LINES + j) * 16u); + for (uint i = 0u; i < 16u; ++i) { line[i] = y[i]; prev[i] = y[i]; } + } +} + +// M_r: per word (s ^ (RC + rk)) * MUL, then a column round and a diagonal round with the seed-drawn rotations. +inline void mh_mixer(thread uint* s, uint rk) { + s[0] = (s[0] ^ (0xbab68293u + rk)) * 0x42146205u; + s[1] = (s[1] ^ (0xcc162340u + rk)) * 0x52cbe0fbu; + s[2] = (s[2] ^ (0x6ce151ccu + rk)) * 0x7ecf4a03u; + s[3] = (s[3] ^ (0xe62b8997u + rk)) * 0x6728907fu; + s[4] = (s[4] ^ (0xc9c80297u + rk)) * 0xd81d9751u; + s[5] = (s[5] ^ (0xf74a1654u + rk)) * 0x132952c3u; + s[6] = (s[6] ^ (0x3d704af5u + rk)) * 0xf60de277u; + s[7] = (s[7] ^ (0x3cf522b7u + rk)) * 0x05358035u; + s[8] = (s[8] ^ (0x2b9cac04u + rk)) * 0xbaf6499du; + s[9] = (s[9] ^ (0xa880ac10u + rk)) * 0xe4db9667u; + s[10] = (s[10] ^ (0x13e5dd1du + rk)) * 0x3e98f45du; + s[11] = (s[11] ^ (0x6fc3e233u + rk)) * 0xd0004eddu; + s[12] = (s[12] ^ (0x2d83eeacu + rk)) * 0x2691630du; + s[13] = (s[13] ^ (0x9006e8bfu + rk)) * 0x9beb3bcfu; + s[14] = (s[14] ^ (0x2c4b5362u + rk)) * 0xab310379u; + s[15] = (s[15] ^ (0x31b49ee2u + rk)) * 0x99cfb423u; + MH_QR(s[0], s[4], s[8], s[12], 20u, 20u, 19u, 4u) MH_QR(s[1], s[5], s[9], s[13], 20u, 20u, 19u, 4u) + MH_QR(s[2], s[6], s[10], s[14], 20u, 20u, 19u, 4u) MH_QR(s[3], s[7], s[11], s[15], 20u, 20u, 19u, 4u) + MH_QR(s[0], s[5], s[10], s[15], 26u, 3u, 3u, 27u) MH_QR(s[1], s[6], s[11], s[12], 26u, 3u, 3u, 27u) + MH_QR(s[2], s[7], s[8], s[13], 26u, 3u, 3u, 27u) MH_QR(s[3], s[4], s[9], s[14], 26u, 3u, 3u, 27u) +} + +// Item t: 16 words. s = (K, t * MUL[i] + RC[i]); 8 rounds of 8 x mixer + cache line s[0] & mask; 8 x final mixer. +inline void mh_item(device const uint* cache, uint t, thread uint* s) { + s[0] = 0x3067619fu; + s[1] = 0x3c269176u; + s[2] = 0x84a03b03u; + s[3] = 0xf8c63294u; + s[4] = 0xff977c5bu; + s[5] = 0xe60def3eu; + s[6] = 0x63630141u; + s[7] = 0xb8fbcb58u; + s[8] = t * 0x42146205u + 0xbab68293u; + s[9] = t * 0x52cbe0fbu + 0xcc162340u; + s[10] = t * 0x7ecf4a03u + 0x6ce151ccu; + s[11] = t * 0x6728907fu + 0xe62b8997u; + s[12] = t * 0xd81d9751u + 0xc9c80297u; + s[13] = t * 0x132952c3u + 0xf74a1654u; + s[14] = t * 0xf60de277u + 0x3d704af5u; + s[15] = t * 0x05358035u + 0x3cf522b7u; + for (uint r = 0u; r < 8u; ++r) { + for (uint j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (r * 8u + j + 1u)); + device const uint* line = cache + ((s[0] & MH_CACHE_LINE_MASK) * 16u); + for (uint i = 0u; i < 16u; ++i) s[i] ^= line[i]; + } + for (uint j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (64u + j + 1u)); +} +// dataset[w] without the dataset: derive item w >> 4 and take word w & 15. +inline uint mh_word(device const uint* cache, uint w) { uint s[16]; mh_item(cache, w >> 4u, s); return s[w & 15u]; } + +// One thread per segment (2^16 threads). +kernel void igneum_cache_fill(device uint* cache [[buffer(0)]], uint gid [[thread_position_in_grid]]) { + mh_cache_segment(cache, gid); +} +// One thread per 64-byte item (dataset words / 16 threads). +kernel void igneum_build(device const uint* cache [[buffer(0)]], device uint* dataset [[buffer(1)]], + uint gid [[thread_position_in_grid]]) { + uint s[16]; + mh_item(cache, gid, s); + device uint* d = dataset + gid * 16u; + for (uint i = 0u; i < 16u; ++i) d[i] = s[i]; +} diff --git a/proto-cuda/packs-ca4/mx8_shl256x27_v2/program.h b/proto-cuda/packs-ca4/mx8_shl256x27_v2/program.h new file mode 100644 index 000000000..801fadcb3 --- /dev/null +++ b/proto-cuda/packs-ca4/mx8_shl256x27_v2/program.h @@ -0,0 +1,72 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Program metadata for host.cu plus the launch wrappers defined in kernel.cu. +// Also included by proto-opencl/host.c (C99), which defines IGNEUM_NO_CUDA first and reads only the macros. +#pragma once +#ifdef __cplusplus +#include +#else +#include +#endif +#ifndef IGNEUM_NO_CUDA +#include +#endif + +#define IGNEUM_SEED_STRING "igneum-genesis" +#define IGNEUM_SEED_BYTES_HEX "69676e65756d2d67656e65736973" +#define IGNEUM_GENERATOR 2 +#define IGNEUM_PROGRAM_ATTEMPT 3 +#define IGNEUM_PROGRAM_ID 0xbd64b207a30413fbull +#define IGNEUM_DAY_STRING "2026-10-03" +#define IGNEUM_DAY_BYTES_HEX "6461792f323032362d31302d3033" +#define IGNEUM_DAY0 0x3067619fu +#define IGNEUM_DAY1 0x3c269176u +#define IGNEUM_DATASET_LOG2 28 +#define IGNEUM_MASK 0x0fffffffu +#define IGNEUM_LANES 32 +#define IGNEUM_ITERATIONS 8 +#define IGNEUM_INSTR_COUNT 64 +#define IGNEUM_LOADS_PER_HASH 128 +#define IGNEUM_WIDE_LOADS_PER_HASH 0 +#define IGNEUM_OP_MIX "load=16 mul=8 rotl=6 shfl=6 add=5 mad=5 xor=5 rotr=4 mulhi=3 or=3 sub=3" +// Class v3 construction (Counter ASIC 2.0, 5 October 2026, docs/plans/mixer-x4.md): version 2 loads; the dataset item +// derivation applies the mixer IGNEUM_MIXER_MULT times per round (memhard.h), and the cache follows the growth rule. +#define IGNEUM_LOAD_CLASS "mx8+shl256x27" +#define IGNEUM_CLASS_MIXER_MULT 8 +#define IGNEUM_CACHE_GROWTH 1 // 1: cache words = 2^(26 + doublings(day)), doublings = floor(log2(1 + day / 1460)) +#define IGNEUM_LOAD_SLOTS 16 +#define IGNEUM_LOAD_MIX { 100, 0, 0 } +#define IGNEUM_LOAD_WIDTH_COUNTS { 16, 0, 0 } // loads of 4, 16, 64 bytes per program +#define IGNEUM_BYTES_PER_HASH 512 +#define IGNEUM_FOLD_ROT 11 +#define IGNEUM_FOLD_MUL 0x9e3779b1u +// Latency-shadow block (Counter ASIC 3.0 item 8, docs/analysis/latency-shadow-2026-10-06.md): NOT the lottery hash. A block of +// IGNEUM_SHADOW_INSTRS ALU instructions (the ten non-load families) runs IGNEUM_SHADOW_REPS times at the end of every +// iteration; the 16 loads, the acceptance rule and the base program are the class's without the shadow. +#define IGNEUM_SHADOW_INSTRS 256 +#define IGNEUM_SHADOW_REPS 27 +#define IGNEUM_SHADOW_INSTRS_PER_HASH 55296 +#define IGNEUM_SHADOW_OP_MIX "add=42 xor=39 mad=29 shfl=27 rotl=23 rotr=22 sub=22 or=19 mul=17 mulhi=16" +// Counter ASIC 4.0 research (experimental): the block is placed per load, sub-block j (instrs / 16) after the j-th load. +#define IGNEUM_SHADOW_PER_LOAD 1 +// 0 = closed-form dataset (ds_elem), 1 = memory-hard cache construction (MEMHARD.md, memhard.h) +#define IGNEUM_DATASET_MODE 1 + +#define IGNEUM_SEEDW_INIT { 0xf71aee9fu, 0xad930c88u, 0x7f982573u, 0xa41f9137u, 0x76d803d6u, 0x37b4a534u, 0x4d3fb826u, 0xff614dcbu } +#define IGNEUM_KEY_INIT { 0x3067619fu, 0x3c269176u, 0x84a03b03u, 0xf8c63294u, 0xff977c5bu, 0xe60def3eu, 0x63630141u, 0xb8fbcb58u } +#define IGNEUM_CACHE_LOG2_WORDS 26 +#define IGNEUM_CACHE_SEGMENT_LOG2_LINES 6 +#define IGNEUM_CACHE_SEGMENTS 65536u +#define IGNEUM_ITEM_ROUNDS 8 +#define IGNEUM_MIXER_MULT 8 // mixer applications per round and after the last read (class v3, docs/plans/mixer-x4.md) +#define IGNEUM_MIX_ROT_INIT { 20u, 20u, 19u, 4u, 26u, 3u, 3u, 27u } +#define IGNEUM_MIX_MUL_INIT { 0x42146205u, 0x52cbe0fbu, 0x7ecf4a03u, 0x6728907fu, 0xd81d9751u, 0x132952c3u, 0xf60de277u, 0x05358035u, 0xbaf6499du, 0xe4db9667u, 0x3e98f45du, 0xd0004eddu, 0x2691630du, 0x9beb3bcfu, 0xab310379u, 0x99cfb423u } +#define IGNEUM_MIX_RC_INIT { 0xbab68293u, 0xcc162340u, 0x6ce151ccu, 0xe62b8997u, 0xc9c80297u, 0xf74a1654u, 0x3d704af5u, 0x3cf522b7u, 0x2b9cac04u, 0xa880ac10u, 0x13e5dd1du, 0x6fc3e233u, 0x2d83eeacu, 0x9006e8bfu, 0x2c4b5362u, 0x31b49ee2u } + +#ifndef IGNEUM_NO_CUDA +// Defined in kernel.cu. All launch on the default stream and return cudaGetLastError(). +cudaError_t igneum_launch_cache_fill(uint32_t* cache, uint32_t nSegments); +cudaError_t igneum_launch_build(uint32_t* ds, const uint32_t* cache, uint32_t nItems); +cudaError_t igneum_launch_hash(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, + uint32_t nonces, uint32_t blockWarps); +cudaError_t igneum_hash_info(int* numRegs, int* blocksPerSM, uint32_t blockWarps); +#endif diff --git a/proto-cuda/packs-ca4/mx8_shl256x27_v2/program.json b/proto-cuda/packs-ca4/mx8_shl256x27_v2/program.json new file mode 100644 index 000000000..1ca99c6ed --- /dev/null +++ b/proto-cuda/packs-ca4/mx8_shl256x27_v2/program.json @@ -0,0 +1,390 @@ +{ + "format": "igneum-program-pack-3", + "generator": 2, + "attempt": 3, + "program_id": "0xbd64b207a30413fb", + "program_id_derivation": "FNV-1a 64 over 'igneum-program/' || generator_le32 || seed_words as little-endian bytes || attempt_le32", + "dataset_mode": "memory-hard", + "seed": "igneum-genesis", + "seed_bytes": "69676e65756d2d67656e65736973", + "seed_words": ["0xf71aee9f", "0xad930c88", "0x7f982573", "0xa41f9137", "0x76d803d6", "0x37b4a534", "0x4d3fb826", "0xff614dcb"], + "seed_derivation": "seed_words = FNV-1a 64 over seed_bytes (attempt 0) or seed_bytes || attempt_le32 (attempt k >= 1), basis ^ (salt * 0x9E3779B97F4A7C15) for salt 0..3, then h ^= h>>33; h *= 0xff51afd7ed558ccd; h ^= h>>33; words[2*salt] = low 32, words[2*salt+1] = high 32", + "generator_rule": "version 2: exactly 16 load slots drawn first from instructions 1..63 (partial Fisher-Yates), the other 48 ops from the ten non-load weights (sum 75); a load's source is drawn from the registers other than dst written by an earlier instruction and not read by a load since; the candidate must pass the acceptance rule of spec 01 section 1.4.6 (static: no cyclically stale load source, every register has an injecting write; dynamic: 64 units on the seed-keyed closed-form dataset with no constant register bit, no lane-constant load site, under 164 saturated final values, every output bit within 136 of 1024, distinct addresses above 245760), else the next attempt of the seed is tried", + "lanes": 32, + "registers": 8, + "iterations": 8, + "instruction_count": 64, + "loads_per_hash": 128, + "load_class": "mx8+shl256x27", + "mixer_mult": 8, + "cache_growth": true, + "mixer": "class v3 (Counter ASIC 2.0, 5 October 2026, docs/plans/mixer-x4.md): every mixer application of the item derivation is 8 applications with round keys (r * 8 + j + 1) * 0x9E3779B9, the 8 dependent cache reads per item unchanged; cache growth rule option C: cache words = 2^(26 + doublings(day)), dataset words = 2^(genesis_log2 + doublings(day)), doublings(day) = floor(log2(1 + day / 1460)) for day = days since genesis", + "load_slots": 16, + "load_mix_percent_4_16_64": [100, 0, 0], + "load_width_counts_4_16_64": [16, 0, 0], + "bytes_per_hash": 512, + "wide_load": "read-width experiment (5 October 2026, docs/plans/read-width.md), NOT the lottery hash: a load of W words (width field, 4 or 16) reads dataset[b .. b + W) with b = (src & mask) & ~(W - 1) and folds every word into dst: x = dst ^ w[0]; for j in 1..W: x = (rotl(x, 11) * 0x9e3779b1) ^ w[j]; dst = x; width 1 is the plain load; the width is drawn per instruction from the class mix with one extra below(100) draw after the nine of version 2, and the program id is FNV-1a 64 over 'igneum-program-rw/' || generator_le32 || seed words || attempt_le32 || mix[3] || load_slots", + "op_mix": {"load": 16, "mul": 8, "rotl": 6, "shfl": 6, "add": 5, "mad": 5, "xor": 5, "rotr": 4, "mulhi": 3, "or": 3, "sub": 3}, + "register_init": "for i in 0..7: x = nonce ^ seed_words[i]; x += 0x9e3779b9 * (i+1) (mod 2^32); x = splitmix32(x); r[i] = x ^ seed_words[(i+1) & 7]", + "splitmix32": "x ^= x>>16; x *= 0x7feb352d; x ^= x>>15; x *= 0x846ca68b; x ^= x>>16", + "iteration": "sel = r0 sampled once at the top of each iteration, then all instructions in order", + "output": "lo = r0 ^ rotl(r1,7) ^ rotl(r2,14) ^ rotl(r3,21); hi = r4 ^ rotl(r5,9) ^ rotl(r6,18) ^ rotl(r7,27); out = (hi << 32) | lo", + "op_semantics": { + "add": "dst = dst + src + (bit `bit` of sel ? imm2 : imm)", + "sub": "dst = dst - src", + "mul": "dst = dst * src (low 32)", + "mulhi": "dst = high 32 bits of dst * src", + "xor": "dst = dst ^ src", + "or": "dst = dst | src", + "rotl": "dst = rotl(dst, rot), rot in 1..31", + "rotr": "dst = rotr(dst, src & 31)", + "mad": "dst = src * src2 + dst", + "shfl": "dst = dst ^ (src of lane (lane ^ mask)), mask in {1,2,4,8,16}, within the 32-lane warp", + "load": "dst = dst ^ dataset[src & dataset.mask]", + "wload": "base = (src of lane 0 & dataset.mask) & ~31; dst = dst ^ dataset[base + lane] (warp-coalesced 128-byte load, lever b, only when --wide-frac > 0)" + }, + "dataset": { + "log2_words": 28, + "bytes": 1073741824, + "mask": "0x0fffffff", + "day": "2026-10-03", + "day_bytes": "6461792f323032362d31302d3033", + "day_words_from": "seed_words_from_bytes(day_bytes)", + "d0": "0x3067619f", + "d1": "0x3c269176", + "mode": "memory-hard", + "spec": "proto-metal/MEMHARD.md", + "key": ["0x3067619f", "0x3c269176", "0x84a03b03", "0xf8c63294", "0xff977c5b", "0xe60def3e", "0x63630141", "0xb8fbcb58"], + "key_derivation": "the 8 words of seed_words_from_bytes(day_bytes); d0, d1 are key[0], key[1]", + "cache": {"log2_words": 26, "bytes": 268435456, "line_words": 16, "segment_lines": 64, "segments": 65536, "block": "ChaCha12 core + feed-forward, rotations 16 12 8 7", "sigma": ["0x61707865", "0x3320646e", "0x79622d32", "0x6b206574"], "tag": ["0x49676e65", "0x756d4d48"], "chain": "in_j = prev_line ^ (sigma[0..3] || key[0..7] || seg || j || tag[0..1]); line_j = block(in_j); prev_0 = 0"}, + "mixer": {"draw": "SplitMix64 seeded with key[0] | key[1] << 32: rot[0..7] = 1 + next() % 31, mul[0..15] = low32(next()) | 1, rc[0..15] = low32(next())", "rot": [20, 20, 19, 4, 26, 3, 3, 27], "mul": ["0x42146205", "0x52cbe0fb", "0x7ecf4a03", "0x6728907f", "0xd81d9751", "0x132952c3", "0xf60de277", "0x05358035", "0xbaf6499d", "0xe4db9667", "0x3e98f45d", "0xd0004edd", "0x2691630d", "0x9beb3bcf", "0xab310379", "0x99cfb423"], "rc": ["0xbab68293", "0xcc162340", "0x6ce151cc", "0xe62b8997", "0xc9c80297", "0xf74a1654", "0x3d704af5", "0x3cf522b7", "0x2b9cac04", "0xa880ac10", "0x13e5dd1d", "0x6fc3e233", "0x2d83eeac", "0x9006e8bf", "0x2c4b5362", "0x31b49ee2"], "round": "for i in 0..15: s[i] = (s[i] ^ (rc[i] + (r+1) * 0x9E3779B9)) * mul[i]; then quarter rounds on columns (0,4,8,12) (1,5,9,13) (2,6,10,14) (3,7,11,15) with rot[0..3] and diagonals (0,5,10,15) (1,6,11,12) (2,7,8,13) (3,4,9,14) with rot[4..7]", "quarter_round": "a += b; d ^= a; d = rotl(d, r1); c += d; b ^= c; b = rotl(b, r2); a += b; d ^= a; d = rotl(d, r3); c += d; b ^= c; b = rotl(b, r4)"}, + "mixer_mult": 8, + "item": "s[0..7] = key; s[8+i] = t * mul[i] + rc[i] for i in 0..7; for r in 0..7: for j in 0..7: s = M(s, rk = (r * 8 + j + 1) * 0x9E3779B9); line = s[0] & 0x003fffff; s[i] ^= cache[line * 16 + i]; then for j in 0..7: s = M(s, rk = (64 + j + 1) * 0x9E3779B9); item(t) = s", + "word": "dataset[w] = item(w >> 4)[w & 15]" + }, + "shadow": {"instrs": 256, "reps": 27, "instrs_per_hash": 55296, "op_mix": {"add": 42, "xor": 39, "mad": 29, "shfl": 27, "rotl": 23, "rotr": 22, "sub": 22, "or": 19, "mul": 17, "mulhi": 16}, "rule": "Counter ASIC 3.0 item 8 (docs/analysis/latency-shadow-2026-10-06.md): after the 64 base instructions the program stream draws instrs more ALU instructions (the non-load table, nine draws each, the source as on an ALU slot); the block runs reps times at the end of every iteration with the iteration's sel; the acceptance rule interprets the base program only", "program_id_suffix": "'shadow/' || instrs_le16 || reps_le16", "instructions": [ + {"i": 0, "op": "rotr", "dst": 5, "src": 4, "src2": 6, "imm": "0x7b829e00", "imm2": "0x3c467e11", "rot": 1, "bit": 5, "mask": 4}, + {"i": 1, "op": "sub", "dst": 6, "src": 5, "src2": 3, "imm": "0xd7d51004", "imm2": "0x0ad2b27c", "rot": 23, "bit": 17, "mask": 4}, + {"i": 2, "op": "sub", "dst": 7, "src": 6, "src2": 3, "imm": "0xc90ee7a1", "imm2": "0xd9ecb052", "rot": 20, "bit": 25, "mask": 8}, + {"i": 3, "op": "mul", "dst": 5, "src": 4, "src2": 7, "imm": "0x420c0864", "imm2": "0x44a36c3c", "rot": 22, "bit": 26, "mask": 16}, + {"i": 4, "op": "xor", "dst": 7, "src": 6, "src2": 2, "imm": "0x23d1dbf3", "imm2": "0x851dcf48", "rot": 27, "bit": 31, "mask": 4}, + {"i": 5, "op": "rotl", "dst": 2, "src": 1, "src2": 5, "imm": "0xbeaf7569", "imm2": "0x358fdb07", "rot": 23, "bit": 2, "mask": 2}, + {"i": 6, "op": "xor", "dst": 7, "src": 4, "src2": 1, "imm": "0x779ddfcd", "imm2": "0xb93ae93c", "rot": 12, "bit": 15, "mask": 2}, + {"i": 7, "op": "add", "dst": 0, "src": 7, "src2": 7, "imm": "0xdaef8862", "imm2": "0x3051c491", "rot": 26, "bit": 26, "mask": 4}, + {"i": 8, "op": "shfl", "dst": 6, "src": 1, "src2": 5, "imm": "0x191b7f7e", "imm2": "0xe9c5693c", "rot": 30, "bit": 7, "mask": 4}, + {"i": 9, "op": "add", "dst": 5, "src": 1, "src2": 2, "imm": "0xc20e7045", "imm2": "0x5170d0b3", "rot": 5, "bit": 26, "mask": 1}, + {"i": 10, "op": "or", "dst": 0, "src": 3, "src2": 2, "imm": "0xa27ed074", "imm2": "0x1f2af192", "rot": 8, "bit": 26, "mask": 1}, + {"i": 11, "op": "mulhi", "dst": 5, "src": 4, "src2": 2, "imm": "0xaadbe6cc", "imm2": "0x24fa9dde", "rot": 13, "bit": 29, "mask": 16}, + {"i": 12, "op": "xor", "dst": 7, "src": 0, "src2": 4, "imm": "0xe787dbb1", "imm2": "0x54c46723", "rot": 1, "bit": 10, "mask": 4}, + {"i": 13, "op": "sub", "dst": 5, "src": 2, "src2": 1, "imm": "0x9d6a004e", "imm2": "0xb5b43329", "rot": 23, "bit": 6, "mask": 1}, + {"i": 14, "op": "add", "dst": 0, "src": 6, "src2": 0, "imm": "0xc86d98a4", "imm2": "0x2ead087f", "rot": 13, "bit": 0, "mask": 1}, + {"i": 15, "op": "xor", "dst": 5, "src": 7, "src2": 1, "imm": "0xa4205ee0", "imm2": "0x4f1d5bba", "rot": 7, "bit": 14, "mask": 16}, + {"i": 16, "op": "shfl", "dst": 7, "src": 6, "src2": 7, "imm": "0x6eb29f0d", "imm2": "0xb7af9e4e", "rot": 2, "bit": 19, "mask": 8}, + {"i": 17, "op": "sub", "dst": 5, "src": 7, "src2": 4, "imm": "0x11aa4853", "imm2": "0x2ce0c575", "rot": 12, "bit": 17, "mask": 16}, + {"i": 18, "op": "or", "dst": 0, "src": 6, "src2": 3, "imm": "0xed5226eb", "imm2": "0xcd376171", "rot": 18, "bit": 9, "mask": 16}, + {"i": 19, "op": "add", "dst": 0, "src": 5, "src2": 7, "imm": "0x4248b651", "imm2": "0xc47c70a8", "rot": 22, "bit": 13, "mask": 2}, + {"i": 20, "op": "shfl", "dst": 4, "src": 5, "src2": 2, "imm": "0xbead1759", "imm2": "0x1b913aee", "rot": 10, "bit": 14, "mask": 16}, + {"i": 21, "op": "add", "dst": 0, "src": 4, "src2": 5, "imm": "0x1e35684f", "imm2": "0x718c1008", "rot": 28, "bit": 21, "mask": 16}, + {"i": 22, "op": "mulhi", "dst": 0, "src": 3, "src2": 0, "imm": "0xe0cc85e3", "imm2": "0x5100e95e", "rot": 25, "bit": 3, "mask": 1}, + {"i": 23, "op": "xor", "dst": 4, "src": 2, "src2": 5, "imm": "0x36be80da", "imm2": "0x597fddd9", "rot": 20, "bit": 11, "mask": 2}, + {"i": 24, "op": "sub", "dst": 0, "src": 2, "src2": 2, "imm": "0x1c0fe722", "imm2": "0x9711da80", "rot": 22, "bit": 5, "mask": 1}, + {"i": 25, "op": "rotl", "dst": 5, "src": 4, "src2": 7, "imm": "0x2e3b3317", "imm2": "0x9e9da27f", "rot": 13, "bit": 21, "mask": 2}, + {"i": 26, "op": "sub", "dst": 7, "src": 0, "src2": 5, "imm": "0x397e8f2f", "imm2": "0x8c3f5941", "rot": 25, "bit": 9, "mask": 16}, + {"i": 27, "op": "xor", "dst": 2, "src": 3, "src2": 2, "imm": "0xa2d897d9", "imm2": "0x5e7a443f", "rot": 29, "bit": 20, "mask": 8}, + {"i": 28, "op": "mad", "dst": 2, "src": 3, "src2": 2, "imm": "0xa61e2ee2", "imm2": "0xe6535252", "rot": 26, "bit": 5, "mask": 1}, + {"i": 29, "op": "xor", "dst": 2, "src": 1, "src2": 1, "imm": "0x1c380f0c", "imm2": "0xf38cddf8", "rot": 17, "bit": 10, "mask": 8}, + {"i": 30, "op": "mulhi", "dst": 4, "src": 0, "src2": 1, "imm": "0x9ab5e6ed", "imm2": "0x9ae01059", "rot": 23, "bit": 5, "mask": 1}, + {"i": 31, "op": "xor", "dst": 6, "src": 4, "src2": 0, "imm": "0x8651f798", "imm2": "0xfcf55e9b", "rot": 1, "bit": 25, "mask": 1}, + {"i": 32, "op": "xor", "dst": 4, "src": 2, "src2": 6, "imm": "0xcb3c03c9", "imm2": "0xcc94a49e", "rot": 5, "bit": 10, "mask": 1}, + {"i": 33, "op": "shfl", "dst": 1, "src": 2, "src2": 3, "imm": "0x23451aa5", "imm2": "0x1ff0cbd2", "rot": 25, "bit": 25, "mask": 1}, + {"i": 34, "op": "shfl", "dst": 5, "src": 6, "src2": 5, "imm": "0x0a169154", "imm2": "0x9baa3264", "rot": 22, "bit": 3, "mask": 1}, + {"i": 35, "op": "sub", "dst": 4, "src": 0, "src2": 2, "imm": "0xa47d5cd6", "imm2": "0x99878331", "rot": 31, "bit": 28, "mask": 2}, + {"i": 36, "op": "sub", "dst": 6, "src": 3, "src2": 6, "imm": "0xab2ad546", "imm2": "0x53e15c19", "rot": 2, "bit": 10, "mask": 16}, + {"i": 37, "op": "or", "dst": 2, "src": 6, "src2": 2, "imm": "0xe123bfae", "imm2": "0xf0cde891", "rot": 16, "bit": 18, "mask": 2}, + {"i": 38, "op": "rotl", "dst": 2, "src": 6, "src2": 7, "imm": "0x3cc04288", "imm2": "0x85c70387", "rot": 30, "bit": 1, "mask": 8}, + {"i": 39, "op": "rotr", "dst": 4, "src": 7, "src2": 1, "imm": "0x80f31d36", "imm2": "0x8c32279d", "rot": 14, "bit": 22, "mask": 16}, + {"i": 40, "op": "or", "dst": 0, "src": 7, "src2": 1, "imm": "0x91a27c69", "imm2": "0xa94ba679", "rot": 16, "bit": 22, "mask": 16}, + {"i": 41, "op": "rotr", "dst": 2, "src": 5, "src2": 5, "imm": "0x5f5ca871", "imm2": "0xa66f6e1e", "rot": 30, "bit": 3, "mask": 8}, + {"i": 42, "op": "mad", "dst": 1, "src": 3, "src2": 3, "imm": "0xf16c6fbe", "imm2": "0xba65dbf1", "rot": 17, "bit": 10, "mask": 4}, + {"i": 43, "op": "mad", "dst": 6, "src": 5, "src2": 5, "imm": "0xee3e3937", "imm2": "0xf2ca16c2", "rot": 18, "bit": 9, "mask": 8}, + {"i": 44, "op": "mulhi", "dst": 1, "src": 0, "src2": 1, "imm": "0xb6ddbd42", "imm2": "0x8c9b9c55", "rot": 19, "bit": 24, "mask": 1}, + {"i": 45, "op": "mul", "dst": 1, "src": 3, "src2": 0, "imm": "0x5bde9611", "imm2": "0xa49dcc94", "rot": 9, "bit": 20, "mask": 16}, + {"i": 46, "op": "mad", "dst": 0, "src": 2, "src2": 0, "imm": "0xed018e02", "imm2": "0xb437c59e", "rot": 10, "bit": 30, "mask": 4}, + {"i": 47, "op": "sub", "dst": 1, "src": 5, "src2": 0, "imm": "0xc977dd30", "imm2": "0xd2194591", "rot": 25, "bit": 13, "mask": 2}, + {"i": 48, "op": "xor", "dst": 4, "src": 0, "src2": 2, "imm": "0x1e586e67", "imm2": "0x0bdc920a", "rot": 14, "bit": 25, "mask": 2}, + {"i": 49, "op": "rotr", "dst": 2, "src": 0, "src2": 4, "imm": "0xced53464", "imm2": "0x2b87e9aa", "rot": 27, "bit": 3, "mask": 16}, + {"i": 50, "op": "mulhi", "dst": 0, "src": 5, "src2": 4, "imm": "0xdfd051ba", "imm2": "0xe95248a6", "rot": 9, "bit": 9, "mask": 2}, + {"i": 51, "op": "or", "dst": 7, "src": 5, "src2": 0, "imm": "0xa2cb118c", "imm2": "0x357931db", "rot": 2, "bit": 12, "mask": 2}, + {"i": 52, "op": "mad", "dst": 4, "src": 0, "src2": 3, "imm": "0x1ea2a1ac", "imm2": "0x8b0c5c54", "rot": 15, "bit": 15, "mask": 16}, + {"i": 53, "op": "rotr", "dst": 0, "src": 4, "src2": 0, "imm": "0xbd1268fe", "imm2": "0x4cab0138", "rot": 9, "bit": 8, "mask": 2}, + {"i": 54, "op": "mad", "dst": 6, "src": 3, "src2": 3, "imm": "0xfd5c9198", "imm2": "0x6942bae5", "rot": 15, "bit": 22, "mask": 16}, + {"i": 55, "op": "mad", "dst": 6, "src": 4, "src2": 2, "imm": "0x4a01c39c", "imm2": "0xca9deebe", "rot": 30, "bit": 25, "mask": 1}, + {"i": 56, "op": "shfl", "dst": 5, "src": 0, "src2": 6, "imm": "0x5a5c8edc", "imm2": "0x36f40134", "rot": 1, "bit": 13, "mask": 2}, + {"i": 57, "op": "rotl", "dst": 7, "src": 3, "src2": 2, "imm": "0x62950b95", "imm2": "0x1bac0994", "rot": 21, "bit": 12, "mask": 4}, + {"i": 58, "op": "xor", "dst": 3, "src": 7, "src2": 0, "imm": "0x4dca8e46", "imm2": "0x79c853b5", "rot": 25, "bit": 11, "mask": 1}, + {"i": 59, "op": "shfl", "dst": 0, "src": 4, "src2": 6, "imm": "0x4c2b533c", "imm2": "0xf4b09101", "rot": 3, "bit": 4, "mask": 1}, + {"i": 60, "op": "xor", "dst": 5, "src": 6, "src2": 1, "imm": "0xc41d4acd", "imm2": "0xc42c4716", "rot": 31, "bit": 21, "mask": 8}, + {"i": 61, "op": "rotr", "dst": 4, "src": 7, "src2": 4, "imm": "0xdafe1dfd", "imm2": "0xa4b90067", "rot": 4, "bit": 0, "mask": 2}, + {"i": 62, "op": "add", "dst": 1, "src": 6, "src2": 2, "imm": "0xf7ccf1e9", "imm2": "0x31f87d74", "rot": 12, "bit": 10, "mask": 2}, + {"i": 63, "op": "add", "dst": 5, "src": 2, "src2": 2, "imm": "0x2f386099", "imm2": "0x9c2847f4", "rot": 10, "bit": 15, "mask": 4}, + {"i": 64, "op": "add", "dst": 7, "src": 0, "src2": 3, "imm": "0x1b30ce7a", "imm2": "0xd3241188", "rot": 14, "bit": 19, "mask": 2}, + {"i": 65, "op": "add", "dst": 6, "src": 7, "src2": 4, "imm": "0x02dc8349", "imm2": "0x9b42c3de", "rot": 18, "bit": 13, "mask": 4}, + {"i": 66, "op": "rotl", "dst": 0, "src": 5, "src2": 6, "imm": "0xd41f93ed", "imm2": "0x2183702d", "rot": 16, "bit": 30, "mask": 16}, + {"i": 67, "op": "rotl", "dst": 2, "src": 6, "src2": 5, "imm": "0xf8423070", "imm2": "0xf48afd52", "rot": 9, "bit": 8, "mask": 2}, + {"i": 68, "op": "mad", "dst": 2, "src": 5, "src2": 6, "imm": "0xb98ae05a", "imm2": "0x97eec6a3", "rot": 18, "bit": 10, "mask": 16}, + {"i": 69, "op": "shfl", "dst": 6, "src": 1, "src2": 0, "imm": "0x176f02ea", "imm2": "0x703e1cab", "rot": 10, "bit": 19, "mask": 8}, + {"i": 70, "op": "xor", "dst": 2, "src": 5, "src2": 7, "imm": "0x14922644", "imm2": "0x1a18b3ed", "rot": 22, "bit": 27, "mask": 1}, + {"i": 71, "op": "mulhi", "dst": 5, "src": 1, "src2": 4, "imm": "0x05d04820", "imm2": "0x60e43e74", "rot": 25, "bit": 31, "mask": 4}, + {"i": 72, "op": "rotl", "dst": 6, "src": 0, "src2": 5, "imm": "0xf04e4109", "imm2": "0xf1ddb551", "rot": 29, "bit": 20, "mask": 1}, + {"i": 73, "op": "sub", "dst": 0, "src": 7, "src2": 7, "imm": "0xe1f20354", "imm2": "0xcd89bdb8", "rot": 2, "bit": 4, "mask": 16}, + {"i": 74, "op": "mad", "dst": 5, "src": 2, "src2": 2, "imm": "0xfb42bfa3", "imm2": "0xe1df26b9", "rot": 21, "bit": 10, "mask": 4}, + {"i": 75, "op": "rotr", "dst": 0, "src": 5, "src2": 6, "imm": "0x67376b2f", "imm2": "0xc02ef691", "rot": 11, "bit": 21, "mask": 1}, + {"i": 76, "op": "add", "dst": 7, "src": 2, "src2": 2, "imm": "0x05d36679", "imm2": "0x0da1ce17", "rot": 7, "bit": 9, "mask": 1}, + {"i": 77, "op": "sub", "dst": 7, "src": 2, "src2": 3, "imm": "0x8841ade4", "imm2": "0x02f2395d", "rot": 15, "bit": 29, "mask": 1}, + {"i": 78, "op": "rotr", "dst": 7, "src": 0, "src2": 2, "imm": "0x10a0bc35", "imm2": "0x71df32ce", "rot": 29, "bit": 6, "mask": 4}, + {"i": 79, "op": "mad", "dst": 1, "src": 5, "src2": 5, "imm": "0x953044fb", "imm2": "0x688d575c", "rot": 18, "bit": 1, "mask": 8}, + {"i": 80, "op": "rotr", "dst": 3, "src": 0, "src2": 3, "imm": "0xd773d95b", "imm2": "0x96c0a95c", "rot": 17, "bit": 20, "mask": 16}, + {"i": 81, "op": "add", "dst": 6, "src": 5, "src2": 4, "imm": "0xf14547bd", "imm2": "0xadf5ef88", "rot": 10, "bit": 2, "mask": 4}, + {"i": 82, "op": "or", "dst": 0, "src": 6, "src2": 3, "imm": "0x2d973325", "imm2": "0x3cdc59f1", "rot": 3, "bit": 20, "mask": 8}, + {"i": 83, "op": "mulhi", "dst": 1, "src": 0, "src2": 6, "imm": "0x850e8c17", "imm2": "0xd83841f9", "rot": 30, "bit": 23, "mask": 16}, + {"i": 84, "op": "mad", "dst": 7, "src": 6, "src2": 7, "imm": "0xbc7fb049", "imm2": "0xed9928df", "rot": 4, "bit": 3, "mask": 4}, + {"i": 85, "op": "rotl", "dst": 5, "src": 0, "src2": 6, "imm": "0xf6305281", "imm2": "0x95a40a03", "rot": 29, "bit": 28, "mask": 2}, + {"i": 86, "op": "xor", "dst": 2, "src": 6, "src2": 0, "imm": "0xd59ffa4f", "imm2": "0x254a4101", "rot": 9, "bit": 28, "mask": 2}, + {"i": 87, "op": "add", "dst": 5, "src": 4, "src2": 2, "imm": "0xba4947c2", "imm2": "0x35ff14ae", "rot": 9, "bit": 24, "mask": 4}, + {"i": 88, "op": "add", "dst": 3, "src": 6, "src2": 4, "imm": "0xf6878bee", "imm2": "0xf3900fc1", "rot": 18, "bit": 3, "mask": 4}, + {"i": 89, "op": "add", "dst": 0, "src": 2, "src2": 5, "imm": "0x926f3607", "imm2": "0xf7e8f59f", "rot": 22, "bit": 12, "mask": 16}, + {"i": 90, "op": "xor", "dst": 2, "src": 6, "src2": 6, "imm": "0x8b009dbb", "imm2": "0x87e4be1e", "rot": 9, "bit": 4, "mask": 8}, + {"i": 91, "op": "shfl", "dst": 3, "src": 2, "src2": 3, "imm": "0x35a452ba", "imm2": "0x1fb223aa", "rot": 15, "bit": 28, "mask": 2}, + {"i": 92, "op": "sub", "dst": 6, "src": 1, "src2": 2, "imm": "0xd26d2497", "imm2": "0x6ace9269", "rot": 20, "bit": 17, "mask": 4}, + {"i": 93, "op": "add", "dst": 5, "src": 1, "src2": 3, "imm": "0xdab36c29", "imm2": "0x0e376f9c", "rot": 27, "bit": 13, "mask": 4}, + {"i": 94, "op": "mad", "dst": 6, "src": 1, "src2": 1, "imm": "0x29e2923e", "imm2": "0x67a97747", "rot": 16, "bit": 30, "mask": 2}, + {"i": 95, "op": "xor", "dst": 3, "src": 4, "src2": 3, "imm": "0x982f8e78", "imm2": "0xdbb7d73f", "rot": 6, "bit": 26, "mask": 8}, + {"i": 96, "op": "mad", "dst": 6, "src": 5, "src2": 2, "imm": "0x760e08de", "imm2": "0x12f3375f", "rot": 27, "bit": 7, "mask": 16}, + {"i": 97, "op": "add", "dst": 7, "src": 3, "src2": 7, "imm": "0x204129e9", "imm2": "0x9f917747", "rot": 26, "bit": 23, "mask": 1}, + {"i": 98, "op": "shfl", "dst": 5, "src": 1, "src2": 5, "imm": "0x0f6aca43", "imm2": "0xdc5cea76", "rot": 29, "bit": 5, "mask": 16}, + {"i": 99, "op": "mul", "dst": 2, "src": 6, "src2": 4, "imm": "0x6abaa10f", "imm2": "0xe0968a9b", "rot": 22, "bit": 27, "mask": 8}, + {"i": 100, "op": "shfl", "dst": 7, "src": 3, "src2": 7, "imm": "0x48d68211", "imm2": "0x9d514118", "rot": 12, "bit": 9, "mask": 8}, + {"i": 101, "op": "add", "dst": 6, "src": 1, "src2": 7, "imm": "0xe3b596a0", "imm2": "0xe42fe974", "rot": 25, "bit": 10, "mask": 2}, + {"i": 102, "op": "rotl", "dst": 5, "src": 1, "src2": 6, "imm": "0xc9afa2dd", "imm2": "0x8441c699", "rot": 3, "bit": 5, "mask": 2}, + {"i": 103, "op": "xor", "dst": 5, "src": 1, "src2": 0, "imm": "0xff93d0c4", "imm2": "0x2b65c415", "rot": 12, "bit": 9, "mask": 16}, + {"i": 104, "op": "add", "dst": 4, "src": 1, "src2": 5, "imm": "0x705c3f94", "imm2": "0xc3d77ffb", "rot": 24, "bit": 27, "mask": 1}, + {"i": 105, "op": "add", "dst": 0, "src": 6, "src2": 0, "imm": "0xbc6fb42b", "imm2": "0xea02a4ca", "rot": 13, "bit": 25, "mask": 4}, + {"i": 106, "op": "or", "dst": 3, "src": 5, "src2": 3, "imm": "0x07559d58", "imm2": "0x5b76e4b5", "rot": 12, "bit": 21, "mask": 1}, + {"i": 107, "op": "sub", "dst": 0, "src": 6, "src2": 7, "imm": "0x70f0b3f2", "imm2": "0xf862cea0", "rot": 20, "bit": 23, "mask": 4}, + {"i": 108, "op": "rotr", "dst": 0, "src": 3, "src2": 1, "imm": "0x93724f38", "imm2": "0x4717fcd8", "rot": 3, "bit": 5, "mask": 8}, + {"i": 109, "op": "add", "dst": 5, "src": 4, "src2": 0, "imm": "0xcb37ea87", "imm2": "0x0357e63e", "rot": 27, "bit": 4, "mask": 2}, + {"i": 110, "op": "rotl", "dst": 7, "src": 3, "src2": 6, "imm": "0x70543783", "imm2": "0x85fcb2f9", "rot": 5, "bit": 13, "mask": 4}, + {"i": 111, "op": "xor", "dst": 4, "src": 1, "src2": 6, "imm": "0x325f187e", "imm2": "0xc4ba0312", "rot": 12, "bit": 14, "mask": 2}, + {"i": 112, "op": "xor", "dst": 6, "src": 5, "src2": 1, "imm": "0xcad70d8a", "imm2": "0x6d6c7bc7", "rot": 5, "bit": 7, "mask": 2}, + {"i": 113, "op": "or", "dst": 1, "src": 3, "src2": 0, "imm": "0x3569dfa0", "imm2": "0xbfab6be2", "rot": 17, "bit": 21, "mask": 8}, + {"i": 114, "op": "add", "dst": 0, "src": 5, "src2": 5, "imm": "0x9aab0297", "imm2": "0x7f8b8cd2", "rot": 21, "bit": 3, "mask": 16}, + {"i": 115, "op": "sub", "dst": 3, "src": 5, "src2": 1, "imm": "0xaaf5f8b5", "imm2": "0xb629e1be", "rot": 24, "bit": 6, "mask": 1}, + {"i": 116, "op": "rotr", "dst": 4, "src": 2, "src2": 6, "imm": "0x7f466189", "imm2": "0xf52bd6af", "rot": 13, "bit": 13, "mask": 16}, + {"i": 117, "op": "add", "dst": 4, "src": 6, "src2": 7, "imm": "0xc511183f", "imm2": "0x59400b57", "rot": 17, "bit": 6, "mask": 8}, + {"i": 118, "op": "sub", "dst": 6, "src": 1, "src2": 4, "imm": "0xf997f264", "imm2": "0x948760fa", "rot": 29, "bit": 3, "mask": 1}, + {"i": 119, "op": "shfl", "dst": 3, "src": 1, "src2": 0, "imm": "0xb9fb8af4", "imm2": "0x735dfe1f", "rot": 24, "bit": 24, "mask": 4}, + {"i": 120, "op": "mad", "dst": 6, "src": 4, "src2": 4, "imm": "0x415a06d6", "imm2": "0xd0160990", "rot": 18, "bit": 11, "mask": 16}, + {"i": 121, "op": "rotl", "dst": 2, "src": 7, "src2": 4, "imm": "0x78dc55da", "imm2": "0x36084523", "rot": 8, "bit": 15, "mask": 16}, + {"i": 122, "op": "mad", "dst": 5, "src": 0, "src2": 3, "imm": "0x951b8e8c", "imm2": "0x3247ab68", "rot": 8, "bit": 25, "mask": 8}, + {"i": 123, "op": "add", "dst": 7, "src": 6, "src2": 7, "imm": "0x5200c242", "imm2": "0x27c70dc0", "rot": 23, "bit": 27, "mask": 4}, + {"i": 124, "op": "shfl", "dst": 3, "src": 5, "src2": 7, "imm": "0x5512f7bd", "imm2": "0x83d356df", "rot": 1, "bit": 25, "mask": 4}, + {"i": 125, "op": "add", "dst": 0, "src": 1, "src2": 3, "imm": "0x2d5028ce", "imm2": "0xec2f5997", "rot": 27, "bit": 17, "mask": 1}, + {"i": 126, "op": "shfl", "dst": 3, "src": 6, "src2": 0, "imm": "0xb2e45b6a", "imm2": "0xee317a17", "rot": 14, "bit": 19, "mask": 16}, + {"i": 127, "op": "xor", "dst": 5, "src": 0, "src2": 3, "imm": "0xe7a12b57", "imm2": "0x4e0dcf60", "rot": 9, "bit": 11, "mask": 4}, + {"i": 128, "op": "add", "dst": 7, "src": 1, "src2": 0, "imm": "0x432f6c0d", "imm2": "0x09e8ede2", "rot": 20, "bit": 10, "mask": 8}, + {"i": 129, "op": "xor", "dst": 2, "src": 4, "src2": 5, "imm": "0x76c67109", "imm2": "0x3f54d25d", "rot": 4, "bit": 12, "mask": 1}, + {"i": 130, "op": "mul", "dst": 0, "src": 2, "src2": 6, "imm": "0x4eca1bc0", "imm2": "0x77c29a67", "rot": 8, "bit": 22, "mask": 4}, + {"i": 131, "op": "or", "dst": 4, "src": 3, "src2": 7, "imm": "0x3195a6fe", "imm2": "0xa1e44e04", "rot": 6, "bit": 13, "mask": 4}, + {"i": 132, "op": "or", "dst": 3, "src": 7, "src2": 0, "imm": "0x059c55ae", "imm2": "0x0a0818b4", "rot": 22, "bit": 8, "mask": 4}, + {"i": 133, "op": "shfl", "dst": 7, "src": 3, "src2": 5, "imm": "0xbd84d73f", "imm2": "0xfcbc80e3", "rot": 8, "bit": 27, "mask": 1}, + {"i": 134, "op": "add", "dst": 5, "src": 2, "src2": 6, "imm": "0xcf5ecc75", "imm2": "0xce4fdf8e", "rot": 31, "bit": 11, "mask": 16}, + {"i": 135, "op": "mad", "dst": 3, "src": 2, "src2": 3, "imm": "0x91f38b1f", "imm2": "0xf12e182b", "rot": 11, "bit": 16, "mask": 2}, + {"i": 136, "op": "rotl", "dst": 1, "src": 2, "src2": 7, "imm": "0x1df61118", "imm2": "0xecebf83b", "rot": 11, "bit": 10, "mask": 8}, + {"i": 137, "op": "or", "dst": 2, "src": 0, "src2": 6, "imm": "0x1b217afb", "imm2": "0x009986f1", "rot": 27, "bit": 17, "mask": 4}, + {"i": 138, "op": "xor", "dst": 3, "src": 4, "src2": 2, "imm": "0xa5b0e8e3", "imm2": "0x8344f4bc", "rot": 25, "bit": 23, "mask": 2}, + {"i": 139, "op": "shfl", "dst": 2, "src": 4, "src2": 1, "imm": "0xe95b436b", "imm2": "0x04f47b79", "rot": 12, "bit": 6, "mask": 1}, + {"i": 140, "op": "rotl", "dst": 2, "src": 6, "src2": 0, "imm": "0x278ba5d4", "imm2": "0x304cc572", "rot": 6, "bit": 31, "mask": 1}, + {"i": 141, "op": "mul", "dst": 0, "src": 3, "src2": 6, "imm": "0xfa5febcc", "imm2": "0x2462f50a", "rot": 25, "bit": 24, "mask": 2}, + {"i": 142, "op": "mul", "dst": 1, "src": 7, "src2": 7, "imm": "0xadab0c26", "imm2": "0x83cefec3", "rot": 3, "bit": 3, "mask": 16}, + {"i": 143, "op": "xor", "dst": 0, "src": 1, "src2": 3, "imm": "0x23cacfae", "imm2": "0x4acf331d", "rot": 13, "bit": 27, "mask": 16}, + {"i": 144, "op": "mad", "dst": 6, "src": 2, "src2": 0, "imm": "0xd3cd907e", "imm2": "0x99806cb9", "rot": 13, "bit": 4, "mask": 4}, + {"i": 145, "op": "rotl", "dst": 1, "src": 4, "src2": 3, "imm": "0xafad23ae", "imm2": "0x919a563b", "rot": 15, "bit": 29, "mask": 2}, + {"i": 146, "op": "rotl", "dst": 1, "src": 4, "src2": 3, "imm": "0x8ff43176", "imm2": "0x20b58068", "rot": 30, "bit": 9, "mask": 4}, + {"i": 147, "op": "xor", "dst": 6, "src": 0, "src2": 1, "imm": "0x7b929413", "imm2": "0x7a7e2fa9", "rot": 7, "bit": 9, "mask": 16}, + {"i": 148, "op": "sub", "dst": 3, "src": 2, "src2": 7, "imm": "0xf2346114", "imm2": "0x74d45ef6", "rot": 17, "bit": 5, "mask": 16}, + {"i": 149, "op": "add", "dst": 3, "src": 0, "src2": 2, "imm": "0xaa002f15", "imm2": "0x11bbdeef", "rot": 22, "bit": 5, "mask": 8}, + {"i": 150, "op": "add", "dst": 6, "src": 5, "src2": 5, "imm": "0xbe64b2e2", "imm2": "0xff9d4b0e", "rot": 14, "bit": 9, "mask": 1}, + {"i": 151, "op": "mul", "dst": 1, "src": 4, "src2": 1, "imm": "0x80ab9255", "imm2": "0x7313b029", "rot": 16, "bit": 5, "mask": 2}, + {"i": 152, "op": "rotl", "dst": 5, "src": 6, "src2": 1, "imm": "0xc5ca5727", "imm2": "0x0153e735", "rot": 3, "bit": 2, "mask": 8}, + {"i": 153, "op": "mul", "dst": 5, "src": 2, "src2": 5, "imm": "0x1598de73", "imm2": "0x99d642dc", "rot": 28, "bit": 30, "mask": 2}, + {"i": 154, "op": "rotl", "dst": 2, "src": 7, "src2": 2, "imm": "0x9f68d6f0", "imm2": "0x29c72445", "rot": 21, "bit": 8, "mask": 1}, + {"i": 155, "op": "rotl", "dst": 5, "src": 0, "src2": 1, "imm": "0xed20980f", "imm2": "0x34b14e75", "rot": 18, "bit": 3, "mask": 2}, + {"i": 156, "op": "xor", "dst": 1, "src": 5, "src2": 2, "imm": "0x5e127c80", "imm2": "0x9d48bd29", "rot": 19, "bit": 14, "mask": 2}, + {"i": 157, "op": "mulhi", "dst": 1, "src": 6, "src2": 5, "imm": "0xd924c751", "imm2": "0x794a134e", "rot": 20, "bit": 31, "mask": 8}, + {"i": 158, "op": "mad", "dst": 4, "src": 7, "src2": 3, "imm": "0x1353b41d", "imm2": "0x34568db3", "rot": 24, "bit": 11, "mask": 16}, + {"i": 159, "op": "sub", "dst": 4, "src": 7, "src2": 7, "imm": "0xfe36ca46", "imm2": "0x915bb25f", "rot": 19, "bit": 10, "mask": 8}, + {"i": 160, "op": "xor", "dst": 3, "src": 2, "src2": 6, "imm": "0xa5a7b77f", "imm2": "0x3101857c", "rot": 3, "bit": 21, "mask": 8}, + {"i": 161, "op": "mulhi", "dst": 3, "src": 4, "src2": 1, "imm": "0x376ee390", "imm2": "0xd6af078e", "rot": 12, "bit": 8, "mask": 4}, + {"i": 162, "op": "shfl", "dst": 3, "src": 2, "src2": 2, "imm": "0x95741acf", "imm2": "0x90ea2feb", "rot": 7, "bit": 15, "mask": 1}, + {"i": 163, "op": "sub", "dst": 0, "src": 1, "src2": 2, "imm": "0x3176da5b", "imm2": "0xd433b4be", "rot": 30, "bit": 31, "mask": 8}, + {"i": 164, "op": "shfl", "dst": 6, "src": 0, "src2": 4, "imm": "0x0502a0cc", "imm2": "0x45dbed17", "rot": 15, "bit": 18, "mask": 8}, + {"i": 165, "op": "shfl", "dst": 4, "src": 2, "src2": 5, "imm": "0x1fbeb1fb", "imm2": "0xc363e4c5", "rot": 3, "bit": 1, "mask": 2}, + {"i": 166, "op": "or", "dst": 3, "src": 6, "src2": 6, "imm": "0x5522496d", "imm2": "0x0e23496d", "rot": 11, "bit": 8, "mask": 2}, + {"i": 167, "op": "shfl", "dst": 6, "src": 3, "src2": 3, "imm": "0xc1f312c5", "imm2": "0x7679c16e", "rot": 7, "bit": 23, "mask": 4}, + {"i": 168, "op": "xor", "dst": 2, "src": 1, "src2": 0, "imm": "0xdfdbdee2", "imm2": "0x054ab2d1", "rot": 17, "bit": 1, "mask": 8}, + {"i": 169, "op": "xor", "dst": 5, "src": 1, "src2": 1, "imm": "0x4913a0ba", "imm2": "0x8681ae62", "rot": 19, "bit": 29, "mask": 16}, + {"i": 170, "op": "xor", "dst": 5, "src": 0, "src2": 7, "imm": "0x11a04a63", "imm2": "0x5d646386", "rot": 12, "bit": 31, "mask": 1}, + {"i": 171, "op": "mad", "dst": 3, "src": 6, "src2": 0, "imm": "0x66b954f7", "imm2": "0x615c24af", "rot": 22, "bit": 17, "mask": 8}, + {"i": 172, "op": "sub", "dst": 3, "src": 0, "src2": 5, "imm": "0x071a3544", "imm2": "0xa1d3128f", "rot": 24, "bit": 4, "mask": 4}, + {"i": 173, "op": "add", "dst": 6, "src": 0, "src2": 1, "imm": "0x3b90694b", "imm2": "0xc72dc2a0", "rot": 24, "bit": 27, "mask": 2}, + {"i": 174, "op": "shfl", "dst": 7, "src": 2, "src2": 7, "imm": "0x50f474e4", "imm2": "0x1138a9f1", "rot": 17, "bit": 16, "mask": 8}, + {"i": 175, "op": "mulhi", "dst": 5, "src": 2, "src2": 4, "imm": "0x09561616", "imm2": "0x8cc5086a", "rot": 26, "bit": 14, "mask": 4}, + {"i": 176, "op": "add", "dst": 3, "src": 6, "src2": 7, "imm": "0x9e65cebd", "imm2": "0x4eb75843", "rot": 29, "bit": 5, "mask": 8}, + {"i": 177, "op": "mad", "dst": 0, "src": 4, "src2": 1, "imm": "0xa95b4929", "imm2": "0x7a61b006", "rot": 16, "bit": 22, "mask": 4}, + {"i": 178, "op": "rotr", "dst": 6, "src": 7, "src2": 5, "imm": "0x9a34a23e", "imm2": "0xb22c37c9", "rot": 1, "bit": 22, "mask": 4}, + {"i": 179, "op": "add", "dst": 0, "src": 7, "src2": 0, "imm": "0x01e5b250", "imm2": "0x7001d036", "rot": 3, "bit": 31, "mask": 4}, + {"i": 180, "op": "shfl", "dst": 5, "src": 2, "src2": 5, "imm": "0xa7f6a337", "imm2": "0xe645a2c2", "rot": 6, "bit": 4, "mask": 16}, + {"i": 181, "op": "mul", "dst": 3, "src": 0, "src2": 4, "imm": "0x0f2b1ce4", "imm2": "0x1046c3c8", "rot": 22, "bit": 28, "mask": 8}, + {"i": 182, "op": "rotl", "dst": 0, "src": 4, "src2": 7, "imm": "0xc7e8ae1c", "imm2": "0x98f9b08e", "rot": 23, "bit": 7, "mask": 1}, + {"i": 183, "op": "mulhi", "dst": 7, "src": 0, "src2": 6, "imm": "0xb64797fa", "imm2": "0x613b63ba", "rot": 17, "bit": 11, "mask": 2}, + {"i": 184, "op": "mul", "dst": 0, "src": 4, "src2": 6, "imm": "0xfcddd784", "imm2": "0x85012b36", "rot": 13, "bit": 19, "mask": 2}, + {"i": 185, "op": "add", "dst": 1, "src": 4, "src2": 1, "imm": "0xbef14988", "imm2": "0x91736711", "rot": 28, "bit": 19, "mask": 2}, + {"i": 186, "op": "add", "dst": 7, "src": 2, "src2": 3, "imm": "0xf5d741be", "imm2": "0x15e0cdf3", "rot": 28, "bit": 6, "mask": 16}, + {"i": 187, "op": "xor", "dst": 1, "src": 7, "src2": 0, "imm": "0xac0a6f4a", "imm2": "0x5fb7de9b", "rot": 13, "bit": 5, "mask": 16}, + {"i": 188, "op": "add", "dst": 1, "src": 3, "src2": 4, "imm": "0x32be33c6", "imm2": "0x7549bc3e", "rot": 10, "bit": 21, "mask": 2}, + {"i": 189, "op": "mad", "dst": 1, "src": 0, "src2": 6, "imm": "0x1c7ce36b", "imm2": "0x31fd592c", "rot": 29, "bit": 3, "mask": 8}, + {"i": 190, "op": "rotr", "dst": 0, "src": 5, "src2": 5, "imm": "0x5d8729d9", "imm2": "0x65b562d0", "rot": 18, "bit": 17, "mask": 8}, + {"i": 191, "op": "mad", "dst": 4, "src": 0, "src2": 1, "imm": "0x8f7c8ec4", "imm2": "0xf2b4257c", "rot": 15, "bit": 14, "mask": 2}, + {"i": 192, "op": "mad", "dst": 3, "src": 6, "src2": 1, "imm": "0xd6bd20bf", "imm2": "0xaf9177ad", "rot": 4, "bit": 8, "mask": 8}, + {"i": 193, "op": "rotl", "dst": 6, "src": 5, "src2": 1, "imm": "0xb3978896", "imm2": "0x240377d5", "rot": 31, "bit": 21, "mask": 16}, + {"i": 194, "op": "rotl", "dst": 5, "src": 1, "src2": 5, "imm": "0x09a5a134", "imm2": "0x0e861d51", "rot": 28, "bit": 31, "mask": 8}, + {"i": 195, "op": "mul", "dst": 4, "src": 3, "src2": 6, "imm": "0x4be7a174", "imm2": "0xd3a7b457", "rot": 3, "bit": 30, "mask": 4}, + {"i": 196, "op": "add", "dst": 2, "src": 3, "src2": 0, "imm": "0x9d7aebbb", "imm2": "0x7c3d6253", "rot": 19, "bit": 4, "mask": 16}, + {"i": 197, "op": "or", "dst": 3, "src": 5, "src2": 1, "imm": "0xc1e98a9d", "imm2": "0x12f8d9c0", "rot": 4, "bit": 29, "mask": 1}, + {"i": 198, "op": "sub", "dst": 6, "src": 0, "src2": 5, "imm": "0x9fabde83", "imm2": "0xc1aa2826", "rot": 13, "bit": 14, "mask": 4}, + {"i": 199, "op": "mul", "dst": 7, "src": 4, "src2": 2, "imm": "0x32653761", "imm2": "0x17d8a6c5", "rot": 23, "bit": 4, "mask": 2}, + {"i": 200, "op": "rotr", "dst": 3, "src": 2, "src2": 2, "imm": "0xd7c4c307", "imm2": "0x9664a047", "rot": 21, "bit": 0, "mask": 16}, + {"i": 201, "op": "shfl", "dst": 4, "src": 0, "src2": 2, "imm": "0x058d2aa6", "imm2": "0xaf120942", "rot": 18, "bit": 27, "mask": 16}, + {"i": 202, "op": "xor", "dst": 7, "src": 3, "src2": 6, "imm": "0x3941fc7c", "imm2": "0x8ae9a794", "rot": 30, "bit": 13, "mask": 4}, + {"i": 203, "op": "or", "dst": 4, "src": 3, "src2": 3, "imm": "0x71058171", "imm2": "0xf05194e4", "rot": 23, "bit": 25, "mask": 4}, + {"i": 204, "op": "rotr", "dst": 3, "src": 6, "src2": 2, "imm": "0xe770de5a", "imm2": "0x00ba5114", "rot": 15, "bit": 0, "mask": 16}, + {"i": 205, "op": "rotr", "dst": 0, "src": 1, "src2": 7, "imm": "0xfa875b85", "imm2": "0x7b600f65", "rot": 17, "bit": 22, "mask": 8}, + {"i": 206, "op": "mad", "dst": 2, "src": 5, "src2": 2, "imm": "0x77c92526", "imm2": "0x0eeae451", "rot": 26, "bit": 31, "mask": 2}, + {"i": 207, "op": "mulhi", "dst": 1, "src": 5, "src2": 2, "imm": "0xe1d887d8", "imm2": "0xb09c96eb", "rot": 16, "bit": 24, "mask": 1}, + {"i": 208, "op": "shfl", "dst": 4, "src": 3, "src2": 7, "imm": "0x5742fb2a", "imm2": "0x8307f5f0", "rot": 2, "bit": 21, "mask": 1}, + {"i": 209, "op": "mad", "dst": 7, "src": 5, "src2": 7, "imm": "0xd3c4a9bd", "imm2": "0xaf46c6f6", "rot": 30, "bit": 27, "mask": 16}, + {"i": 210, "op": "xor", "dst": 6, "src": 3, "src2": 5, "imm": "0x9542f3b3", "imm2": "0xb959da41", "rot": 30, "bit": 9, "mask": 16}, + {"i": 211, "op": "xor", "dst": 3, "src": 2, "src2": 5, "imm": "0x01da033a", "imm2": "0x1e968e2b", "rot": 7, "bit": 22, "mask": 2}, + {"i": 212, "op": "shfl", "dst": 5, "src": 6, "src2": 6, "imm": "0x09f6758f", "imm2": "0x682f117e", "rot": 21, "bit": 30, "mask": 16}, + {"i": 213, "op": "rotl", "dst": 4, "src": 1, "src2": 2, "imm": "0xdb97b8fd", "imm2": "0x17c9d6e5", "rot": 10, "bit": 18, "mask": 8}, + {"i": 214, "op": "shfl", "dst": 5, "src": 6, "src2": 0, "imm": "0x7770463b", "imm2": "0x1b775f29", "rot": 8, "bit": 9, "mask": 16}, + {"i": 215, "op": "or", "dst": 3, "src": 0, "src2": 4, "imm": "0x030be847", "imm2": "0x28ce30d6", "rot": 24, "bit": 13, "mask": 8}, + {"i": 216, "op": "mul", "dst": 4, "src": 5, "src2": 0, "imm": "0xd57210c4", "imm2": "0xf11a023e", "rot": 20, "bit": 28, "mask": 8}, + {"i": 217, "op": "shfl", "dst": 0, "src": 3, "src2": 0, "imm": "0xe8de950c", "imm2": "0x84c408f4", "rot": 13, "bit": 22, "mask": 16}, + {"i": 218, "op": "mul", "dst": 0, "src": 5, "src2": 2, "imm": "0x034cca70", "imm2": "0x0dee748d", "rot": 17, "bit": 6, "mask": 1}, + {"i": 219, "op": "rotl", "dst": 0, "src": 3, "src2": 4, "imm": "0x4581784a", "imm2": "0x98998596", "rot": 13, "bit": 19, "mask": 2}, + {"i": 220, "op": "mulhi", "dst": 1, "src": 0, "src2": 5, "imm": "0x4d564305", "imm2": "0x5e5dac5e", "rot": 28, "bit": 31, "mask": 1}, + {"i": 221, "op": "xor", "dst": 4, "src": 1, "src2": 5, "imm": "0xdbf5ebeb", "imm2": "0xbf5e17eb", "rot": 29, "bit": 31, "mask": 8}, + {"i": 222, "op": "or", "dst": 2, "src": 3, "src2": 5, "imm": "0x15729ed6", "imm2": "0xa983f52f", "rot": 9, "bit": 19, "mask": 4}, + {"i": 223, "op": "xor", "dst": 0, "src": 4, "src2": 1, "imm": "0xffd11221", "imm2": "0xe34d6a6e", "rot": 21, "bit": 31, "mask": 16}, + {"i": 224, "op": "mad", "dst": 5, "src": 6, "src2": 1, "imm": "0x7e34f1f6", "imm2": "0x294c6931", "rot": 17, "bit": 30, "mask": 2}, + {"i": 225, "op": "xor", "dst": 4, "src": 3, "src2": 7, "imm": "0x01e76e71", "imm2": "0xe6632ffd", "rot": 18, "bit": 7, "mask": 8}, + {"i": 226, "op": "add", "dst": 5, "src": 0, "src2": 2, "imm": "0xfe960971", "imm2": "0xe4e51c75", "rot": 16, "bit": 3, "mask": 4}, + {"i": 227, "op": "mulhi", "dst": 3, "src": 2, "src2": 3, "imm": "0x63f4f95a", "imm2": "0x52cfc500", "rot": 4, "bit": 2, "mask": 2}, + {"i": 228, "op": "xor", "dst": 2, "src": 6, "src2": 3, "imm": "0x89e0458f", "imm2": "0x4fc30fcf", "rot": 25, "bit": 19, "mask": 8}, + {"i": 229, "op": "mulhi", "dst": 1, "src": 5, "src2": 5, "imm": "0x58ac55c8", "imm2": "0xdd7ec950", "rot": 27, "bit": 10, "mask": 8}, + {"i": 230, "op": "add", "dst": 3, "src": 4, "src2": 3, "imm": "0x48b3ce0a", "imm2": "0x4d597c08", "rot": 7, "bit": 25, "mask": 2}, + {"i": 231, "op": "rotr", "dst": 2, "src": 3, "src2": 7, "imm": "0xc215de10", "imm2": "0x40b73d08", "rot": 5, "bit": 11, "mask": 8}, + {"i": 232, "op": "sub", "dst": 2, "src": 7, "src2": 4, "imm": "0xca2afec4", "imm2": "0x576725b0", "rot": 12, "bit": 10, "mask": 8}, + {"i": 233, "op": "or", "dst": 6, "src": 2, "src2": 6, "imm": "0x4c44fac9", "imm2": "0x3a2576a0", "rot": 10, "bit": 3, "mask": 2}, + {"i": 234, "op": "rotr", "dst": 0, "src": 3, "src2": 6, "imm": "0xd20b4883", "imm2": "0xf5214ee2", "rot": 3, "bit": 20, "mask": 1}, + {"i": 235, "op": "add", "dst": 4, "src": 3, "src2": 5, "imm": "0x2ed8c878", "imm2": "0xc9f1d54c", "rot": 21, "bit": 13, "mask": 16}, + {"i": 236, "op": "mad", "dst": 0, "src": 3, "src2": 7, "imm": "0x43d96935", "imm2": "0x2c20b192", "rot": 7, "bit": 17, "mask": 4}, + {"i": 237, "op": "add", "dst": 3, "src": 5, "src2": 6, "imm": "0x22e8b90a", "imm2": "0xc572bd00", "rot": 10, "bit": 29, "mask": 2}, + {"i": 238, "op": "mulhi", "dst": 0, "src": 4, "src2": 2, "imm": "0xa2cbbdff", "imm2": "0x042f9ba6", "rot": 1, "bit": 14, "mask": 8}, + {"i": 239, "op": "mul", "dst": 6, "src": 5, "src2": 3, "imm": "0xcc024898", "imm2": "0x7b36c6a9", "rot": 14, "bit": 1, "mask": 2}, + {"i": 240, "op": "add", "dst": 5, "src": 2, "src2": 3, "imm": "0xc6b790e6", "imm2": "0xb233f94f", "rot": 12, "bit": 20, "mask": 16}, + {"i": 241, "op": "sub", "dst": 0, "src": 3, "src2": 0, "imm": "0x8e7ccb1c", "imm2": "0xae1d4c3a", "rot": 19, "bit": 29, "mask": 4}, + {"i": 242, "op": "add", "dst": 4, "src": 7, "src2": 4, "imm": "0x0f918d3b", "imm2": "0x534d924b", "rot": 1, "bit": 4, "mask": 8}, + {"i": 243, "op": "rotr", "dst": 5, "src": 0, "src2": 0, "imm": "0x5515f499", "imm2": "0x3a5a5a09", "rot": 20, "bit": 28, "mask": 8}, + {"i": 244, "op": "rotr", "dst": 1, "src": 7, "src2": 2, "imm": "0x15de3e44", "imm2": "0x2d00a4c8", "rot": 6, "bit": 7, "mask": 1}, + {"i": 245, "op": "or", "dst": 2, "src": 0, "src2": 4, "imm": "0xc1d19687", "imm2": "0xa3f06c6f", "rot": 9, "bit": 19, "mask": 2}, + {"i": 246, "op": "mul", "dst": 4, "src": 7, "src2": 4, "imm": "0x09250afe", "imm2": "0xb09720b1", "rot": 1, "bit": 2, "mask": 8}, + {"i": 247, "op": "mad", "dst": 1, "src": 2, "src2": 5, "imm": "0xb6793fd5", "imm2": "0x32837c74", "rot": 13, "bit": 28, "mask": 1}, + {"i": 248, "op": "mul", "dst": 2, "src": 5, "src2": 0, "imm": "0x1f0bde8f", "imm2": "0x98e78f9b", "rot": 15, "bit": 16, "mask": 8}, + {"i": 249, "op": "xor", "dst": 4, "src": 2, "src2": 6, "imm": "0x3923d007", "imm2": "0x9357d221", "rot": 23, "bit": 24, "mask": 8}, + {"i": 250, "op": "xor", "dst": 3, "src": 1, "src2": 1, "imm": "0xaabf43a0", "imm2": "0xbe559b93", "rot": 21, "bit": 30, "mask": 16}, + {"i": 251, "op": "rotr", "dst": 5, "src": 7, "src2": 0, "imm": "0x4aa1bf2a", "imm2": "0x5b33ea1c", "rot": 24, "bit": 4, "mask": 8}, + {"i": 252, "op": "mad", "dst": 2, "src": 7, "src2": 7, "imm": "0xef234434", "imm2": "0x96d5854d", "rot": 15, "bit": 30, "mask": 2}, + {"i": 253, "op": "rotr", "dst": 7, "src": 3, "src2": 4, "imm": "0x4ea7e652", "imm2": "0x6b77a754", "rot": 16, "bit": 19, "mask": 2}, + {"i": 254, "op": "add", "dst": 6, "src": 1, "src2": 1, "imm": "0xb8a27d95", "imm2": "0x86d27169", "rot": 8, "bit": 21, "mask": 4}, + {"i": 255, "op": "or", "dst": 6, "src": 7, "src2": 1, "imm": "0x2e74a663", "imm2": "0x45dff7ca", "rot": 25, "bit": 2, "mask": 1} + ]}, + "shadow_placement": "per_load", + "instructions": [ + {"i": 0, "op": "add", "dst": 2, "src": 5, "src2": 3, "imm": "0xe3e2ed7d", "imm2": "0x894e457d", "rot": 13, "bit": 2, "mask": 1, "width": 1}, + {"i": 1, "op": "mad", "dst": 7, "src": 4, "src2": 0, "imm": "0x48baccba", "imm2": "0x6e9738d1", "rot": 21, "bit": 30, "mask": 8, "width": 1}, + {"i": 2, "op": "sub", "dst": 3, "src": 6, "src2": 0, "imm": "0x686a83d3", "imm2": "0xeb5efcc2", "rot": 10, "bit": 10, "mask": 16, "width": 1}, + {"i": 3, "op": "rotr", "dst": 5, "src": 1, "src2": 0, "imm": "0xb2c12490", "imm2": "0x7f13e52b", "rot": 25, "bit": 8, "mask": 4, "width": 1}, + {"i": 4, "op": "shfl", "dst": 6, "src": 2, "src2": 6, "imm": "0xc8f420a8", "imm2": "0x608237a0", "rot": 26, "bit": 11, "mask": 1, "width": 1}, + {"i": 5, "op": "or", "dst": 0, "src": 3, "src2": 7, "imm": "0xc7e2251e", "imm2": "0x3e36b8d5", "rot": 30, "bit": 7, "mask": 1, "width": 1}, + {"i": 6, "op": "mul", "dst": 0, "src": 1, "src2": 5, "imm": "0xa5b4da15", "imm2": "0x7cb74643", "rot": 16, "bit": 20, "mask": 2, "width": 1}, + {"i": 7, "op": "mul", "dst": 7, "src": 6, "src2": 4, "imm": "0x013ce090", "imm2": "0xb938a092", "rot": 9, "bit": 29, "mask": 4, "width": 1}, + {"i": 8, "op": "load", "dst": 3, "src": 0, "src2": 6, "imm": "0xf604ccf0", "imm2": "0xf02dffb7", "rot": 26, "bit": 28, "mask": 1, "width": 1}, + {"i": 9, "op": "add", "dst": 4, "src": 3, "src2": 3, "imm": "0xce9bea84", "imm2": "0xd26d3573", "rot": 20, "bit": 22, "mask": 1, "width": 1}, + {"i": 10, "op": "mul", "dst": 2, "src": 4, "src2": 6, "imm": "0x98ac1503", "imm2": "0xb3626dcf", "rot": 22, "bit": 13, "mask": 2, "width": 1}, + {"i": 11, "op": "load", "dst": 3, "src": 2, "src2": 2, "imm": "0xdb84e449", "imm2": "0x538dd18d", "rot": 30, "bit": 5, "mask": 2, "width": 1}, + {"i": 12, "op": "mulhi", "dst": 4, "src": 1, "src2": 7, "imm": "0x7aa83111", "imm2": "0x2a98226a", "rot": 26, "bit": 3, "mask": 1, "width": 1}, + {"i": 13, "op": "mulhi", "dst": 7, "src": 3, "src2": 1, "imm": "0xd2c17bd2", "imm2": "0x2876c049", "rot": 1, "bit": 11, "mask": 16, "width": 1}, + {"i": 14, "op": "add", "dst": 3, "src": 2, "src2": 6, "imm": "0x514f9ff4", "imm2": "0xc2828a42", "rot": 28, "bit": 8, "mask": 4, "width": 1}, + {"i": 15, "op": "mad", "dst": 1, "src": 3, "src2": 2, "imm": "0xf76025ba", "imm2": "0x82d27507", "rot": 31, "bit": 18, "mask": 16, "width": 1}, + {"i": 16, "op": "rotl", "dst": 2, "src": 5, "src2": 0, "imm": "0x7c61ca9c", "imm2": "0x36277625", "rot": 7, "bit": 8, "mask": 8, "width": 1}, + {"i": 17, "op": "load", "dst": 1, "src": 2, "src2": 3, "imm": "0x740a280b", "imm2": "0x383281a7", "rot": 27, "bit": 31, "mask": 16, "width": 1}, + {"i": 18, "op": "mul", "dst": 3, "src": 2, "src2": 6, "imm": "0x064bd0b5", "imm2": "0xd1c0fc47", "rot": 25, "bit": 31, "mask": 16, "width": 1}, + {"i": 19, "op": "rotl", "dst": 6, "src": 7, "src2": 4, "imm": "0xab459e33", "imm2": "0x95f59404", "rot": 24, "bit": 23, "mask": 4, "width": 1}, + {"i": 20, "op": "load", "dst": 6, "src": 3, "src2": 3, "imm": "0x016542dd", "imm2": "0x78d9e35c", "rot": 23, "bit": 4, "mask": 2, "width": 1}, + {"i": 21, "op": "load", "dst": 1, "src": 6, "src2": 4, "imm": "0x3b09488c", "imm2": "0x5dff13e2", "rot": 14, "bit": 29, "mask": 4, "width": 1}, + {"i": 22, "op": "mad", "dst": 5, "src": 3, "src2": 3, "imm": "0x07524f6c", "imm2": "0x1618637f", "rot": 16, "bit": 19, "mask": 1, "width": 1}, + {"i": 23, "op": "load", "dst": 4, "src": 7, "src2": 0, "imm": "0x32a5d5e9", "imm2": "0x375464f7", "rot": 6, "bit": 18, "mask": 4, "width": 1}, + {"i": 24, "op": "load", "dst": 6, "src": 4, "src2": 1, "imm": "0xa0e15b48", "imm2": "0x656763e3", "rot": 3, "bit": 12, "mask": 16, "width": 1}, + {"i": 25, "op": "mul", "dst": 5, "src": 7, "src2": 0, "imm": "0xa79e75f0", "imm2": "0x6a5e8dac", "rot": 13, "bit": 7, "mask": 2, "width": 1}, + {"i": 26, "op": "mul", "dst": 0, "src": 3, "src2": 1, "imm": "0xe3a32543", "imm2": "0x40df802b", "rot": 10, "bit": 19, "mask": 1, "width": 1}, + {"i": 27, "op": "or", "dst": 0, "src": 3, "src2": 7, "imm": "0x58c20b95", "imm2": "0x5bfa6339", "rot": 23, "bit": 17, "mask": 2, "width": 1}, + {"i": 28, "op": "mad", "dst": 1, "src": 3, "src2": 4, "imm": "0xf8cf6f87", "imm2": "0x40bf2b52", "rot": 12, "bit": 22, "mask": 8, "width": 1}, + {"i": 29, "op": "shfl", "dst": 0, "src": 2, "src2": 6, "imm": "0x6f84cf36", "imm2": "0x7936172c", "rot": 2, "bit": 2, "mask": 8, "width": 1}, + {"i": 30, "op": "sub", "dst": 7, "src": 3, "src2": 2, "imm": "0xb77c8c79", "imm2": "0x525a96d8", "rot": 16, "bit": 16, "mask": 8, "width": 1}, + {"i": 31, "op": "xor", "dst": 4, "src": 1, "src2": 4, "imm": "0xad6463e3", "imm2": "0x3874789b", "rot": 27, "bit": 28, "mask": 1, "width": 1}, + {"i": 32, "op": "or", "dst": 4, "src": 5, "src2": 1, "imm": "0x4d700827", "imm2": "0x2dbc3dc4", "rot": 10, "bit": 30, "mask": 16, "width": 1}, + {"i": 33, "op": "rotr", "dst": 3, "src": 5, "src2": 0, "imm": "0x719a64fe", "imm2": "0xb6ba21b7", "rot": 1, "bit": 25, "mask": 1, "width": 1}, + {"i": 34, "op": "load", "dst": 4, "src": 5, "src2": 7, "imm": "0x7af41ac2", "imm2": "0x043993ef", "rot": 1, "bit": 31, "mask": 1, "width": 1}, + {"i": 35, "op": "mad", "dst": 0, "src": 5, "src2": 3, "imm": "0xaa75a56c", "imm2": "0x98eedda3", "rot": 19, "bit": 28, "mask": 16, "width": 1}, + {"i": 36, "op": "load", "dst": 6, "src": 3, "src2": 3, "imm": "0xb30a9fef", "imm2": "0xae0b99d7", "rot": 10, "bit": 26, "mask": 1, "width": 1}, + {"i": 37, "op": "mul", "dst": 5, "src": 3, "src2": 6, "imm": "0x5bda14ce", "imm2": "0x93932ff3", "rot": 2, "bit": 7, "mask": 1, "width": 1}, + {"i": 38, "op": "xor", "dst": 5, "src": 4, "src2": 5, "imm": "0x6087cdca", "imm2": "0x5ade3557", "rot": 7, "bit": 13, "mask": 1, "width": 1}, + {"i": 39, "op": "xor", "dst": 6, "src": 0, "src2": 4, "imm": "0x618cbb10", "imm2": "0x3a79c600", "rot": 1, "bit": 21, "mask": 8, "width": 1}, + {"i": 40, "op": "rotr", "dst": 4, "src": 0, "src2": 5, "imm": "0x206b88d8", "imm2": "0x25c6e9b5", "rot": 25, "bit": 1, "mask": 16, "width": 1}, + {"i": 41, "op": "xor", "dst": 7, "src": 6, "src2": 7, "imm": "0x5e1baea1", "imm2": "0xa6016845", "rot": 30, "bit": 16, "mask": 8, "width": 1}, + {"i": 42, "op": "load", "dst": 1, "src": 7, "src2": 1, "imm": "0xca654c28", "imm2": "0x1d5f5e32", "rot": 29, "bit": 12, "mask": 1, "width": 1}, + {"i": 43, "op": "sub", "dst": 2, "src": 4, "src2": 7, "imm": "0x6abb678b", "imm2": "0x062adc76", "rot": 1, "bit": 20, "mask": 1, "width": 1}, + {"i": 44, "op": "mulhi", "dst": 6, "src": 7, "src2": 0, "imm": "0xfef225a8", "imm2": "0x9fb4c8ef", "rot": 7, "bit": 15, "mask": 4, "width": 1}, + {"i": 45, "op": "rotl", "dst": 3, "src": 1, "src2": 2, "imm": "0xc8dff63b", "imm2": "0xfc726054", "rot": 13, "bit": 22, "mask": 4, "width": 1}, + {"i": 46, "op": "shfl", "dst": 7, "src": 6, "src2": 2, "imm": "0x83bf4499", "imm2": "0xd1f9aaeb", "rot": 13, "bit": 22, "mask": 16, "width": 1}, + {"i": 47, "op": "rotl", "dst": 2, "src": 7, "src2": 6, "imm": "0x592d1583", "imm2": "0x7d216bb4", "rot": 26, "bit": 23, "mask": 8, "width": 1}, + {"i": 48, "op": "mul", "dst": 6, "src": 2, "src2": 5, "imm": "0xa2d3a9c5", "imm2": "0xe46c97c7", "rot": 8, "bit": 4, "mask": 1, "width": 1}, + {"i": 49, "op": "load", "dst": 2, "src": 3, "src2": 5, "imm": "0xc97cc7d0", "imm2": "0x11de360b", "rot": 24, "bit": 4, "mask": 4, "width": 1}, + {"i": 50, "op": "load", "dst": 5, "src": 1, "src2": 5, "imm": "0x51d9e142", "imm2": "0x4949e464", "rot": 6, "bit": 21, "mask": 8, "width": 1}, + {"i": 51, "op": "rotl", "dst": 0, "src": 7, "src2": 5, "imm": "0x47ed408a", "imm2": "0xfbc78474", "rot": 20, "bit": 0, "mask": 1, "width": 1}, + {"i": 52, "op": "xor", "dst": 1, "src": 2, "src2": 0, "imm": "0x548a8b43", "imm2": "0x05fa3627", "rot": 24, "bit": 26, "mask": 2, "width": 1}, + {"i": 53, "op": "load", "dst": 2, "src": 1, "src2": 3, "imm": "0x13137433", "imm2": "0x4da0f56c", "rot": 18, "bit": 10, "mask": 4, "width": 1}, + {"i": 54, "op": "rotl", "dst": 4, "src": 3, "src2": 4, "imm": "0xeb8027b8", "imm2": "0x672311d2", "rot": 20, "bit": 19, "mask": 1, "width": 1}, + {"i": 55, "op": "shfl", "dst": 3, "src": 1, "src2": 7, "imm": "0x273a617a", "imm2": "0x38456825", "rot": 21, "bit": 15, "mask": 2, "width": 1}, + {"i": 56, "op": "load", "dst": 1, "src": 0, "src2": 3, "imm": "0x80aaf238", "imm2": "0xcb72fcc7", "rot": 25, "bit": 21, "mask": 4, "width": 1}, + {"i": 57, "op": "load", "dst": 3, "src": 5, "src2": 5, "imm": "0xc3797c55", "imm2": "0x5ff4d264", "rot": 13, "bit": 10, "mask": 2, "width": 1}, + {"i": 58, "op": "shfl", "dst": 1, "src": 2, "src2": 6, "imm": "0xc24867f2", "imm2": "0x41627f2d", "rot": 24, "bit": 31, "mask": 2, "width": 1}, + {"i": 59, "op": "load", "dst": 6, "src": 4, "src2": 6, "imm": "0x4e68a668", "imm2": "0x47cb76dc", "rot": 6, "bit": 9, "mask": 2, "width": 1}, + {"i": 60, "op": "shfl", "dst": 7, "src": 3, "src2": 3, "imm": "0x1b39c5c8", "imm2": "0x8f3693ee", "rot": 10, "bit": 22, "mask": 4, "width": 1}, + {"i": 61, "op": "rotr", "dst": 5, "src": 0, "src2": 0, "imm": "0x85b99d10", "imm2": "0x253b1522", "rot": 26, "bit": 31, "mask": 4, "width": 1}, + {"i": 62, "op": "add", "dst": 0, "src": 6, "src2": 1, "imm": "0x8c2e5c24", "imm2": "0xb13a5391", "rot": 23, "bit": 14, "mask": 16, "width": 1}, + {"i": 63, "op": "add", "dst": 2, "src": 1, "src2": 7, "imm": "0xb225b762", "imm2": "0xf82fc8b5", "rot": 11, "bit": 21, "mask": 1, "width": 1} + ] +} diff --git a/proto-cuda/packs-ca4/mx8_shl256x27_v2/program.metal b/proto-cuda/packs-ca4/mx8_shl256x27_v2/program.metal new file mode 100644 index 000000000..45e42e15c --- /dev/null +++ b/proto-cuda/packs-ca4/mx8_shl256x27_v2/program.metal @@ -0,0 +1,413 @@ +#include +using namespace metal; + +#define MASK 0x0fffffffu +constant uint SEEDW[8] = { 0xf71aee9fu, 0xad930c88u, 0x7f982573u, 0xa41f9137u, 0x76d803d6u, 0x37b4a534u, 0x4d3fb826u, 0xff614dcbu }; + +inline uint splitmix32(uint x) { + x ^= x >> 16; x *= 0x7feb352du; + x ^= x >> 15; x *= 0x846ca68bu; + x ^= x >> 16; + return x; +} +inline uint rotl_imm(uint x, uint n) { return (x << n) | (x >> (32u - n)); } // n in 1..31 +inline uint rotr_var(uint x, uint n) { n &= 31u; return (x >> n) | (x << ((32u - n) & 31u)); } +inline uint ds_elem(uint i, uint d0, uint d1) { + uint x = i ^ d0; + x *= 0x9E3779B1u; x ^= x >> 15; + x += d1; + x *= 0x85EBCA77u; x ^= x >> 13; + x *= 0xC2B2AE3Du; x ^= x >> 16; + return x; +} + +kernel void igneum_hash(device const uint* dataset [[buffer(0)]], + device ulong* out [[buffer(1)]], + constant uint& baseNonce [[buffer(2)]], + uint gid [[thread_position_in_grid]]) { + uint nonce = baseNonce + gid; + uint r0, r1, r2, r3, r4, r5, r6, r7; + { uint x = nonce ^ SEEDW[0]; x += 0x9e3779b9u * 1u; x = splitmix32(x); r0 = x ^ SEEDW[1]; } + { uint x = nonce ^ SEEDW[1]; x += 0x9e3779b9u * 2u; x = splitmix32(x); r1 = x ^ SEEDW[2]; } + { uint x = nonce ^ SEEDW[2]; x += 0x9e3779b9u * 3u; x = splitmix32(x); r2 = x ^ SEEDW[3]; } + { uint x = nonce ^ SEEDW[3]; x += 0x9e3779b9u * 4u; x = splitmix32(x); r3 = x ^ SEEDW[4]; } + { uint x = nonce ^ SEEDW[4]; x += 0x9e3779b9u * 5u; x = splitmix32(x); r4 = x ^ SEEDW[5]; } + { uint x = nonce ^ SEEDW[5]; x += 0x9e3779b9u * 6u; x = splitmix32(x); r5 = x ^ SEEDW[6]; } + { uint x = nonce ^ SEEDW[6]; x += 0x9e3779b9u * 7u; x = splitmix32(x); r6 = x ^ SEEDW[7]; } + { uint x = nonce ^ SEEDW[7]; x += 0x9e3779b9u * 8u; x = splitmix32(x); r7 = x ^ SEEDW[0]; } + + for (uint it = 0u; it < 8u; ++it) { + uint sel = r0; + r2 = r2 + r5 + select(0xe3e2ed7du, 0x894e457du, ((sel >> 2u) & 1u) != 0u); // 0 + r7 = r4 * r0 + r7; // 1 + r3 = r3 - r6; // 2 + r5 = rotr_var(r5, r1); // 3 + r6 = r6 ^ simd_shuffle_xor(r2, (ushort)1); // 4 + r0 = r0 | r3; // 5 + r0 = r0 * r1; // 6 + r7 = r7 * r6; // 7 + r3 = r3 ^ dataset[r0 & MASK]; // 8 + // per-load shadow sub-block 0 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 0 + for (uint sh0 = 0u; sh0 < 27u; ++sh0) { + r5 = rotr_var(r5, r4); // s0 rotr + r6 = r6 - r5; // s1 sub + r7 = r7 - r6; // s2 sub + r5 = r5 * r4; // s3 mul + r7 = r7 ^ r6; // s4 xor + r2 = rotl_imm(r2, 23u); // s5 rotl + r7 = r7 ^ r4; // s6 xor + r0 = r0 + r7 + select(0xdaef8862u, 0x3051c491u, ((sel >> 26u) & 1u) != 0u); // s7 add + r6 = r6 ^ simd_shuffle_xor(r1, (ushort)4); // s8 shfl + r5 = r5 + r1 + select(0xc20e7045u, 0x5170d0b3u, ((sel >> 26u) & 1u) != 0u); // s9 add + r0 = r0 | r3; // s10 or + r5 = mulhi(r5, r4); // s11 mulhi + r7 = r7 ^ r0; // s12 xor + r5 = r5 - r2; // s13 sub + r0 = r0 + r6 + select(0xc86d98a4u, 0x2ead087fu, ((sel >> 0u) & 1u) != 0u); // s14 add + r5 = r5 ^ r7; // s15 xor + } + r4 = r4 + r3 + select(0xce9bea84u, 0xd26d3573u, ((sel >> 22u) & 1u) != 0u); // 9 + r2 = r2 * r4; // 10 + r3 = r3 ^ dataset[r2 & MASK]; // 11 + // per-load shadow sub-block 1 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 1 + for (uint sh1 = 0u; sh1 < 27u; ++sh1) { + r7 = r7 ^ simd_shuffle_xor(r6, (ushort)8); // s16 shfl + r5 = r5 - r7; // s17 sub + r0 = r0 | r6; // s18 or + r0 = r0 + r5 + select(0x4248b651u, 0xc47c70a8u, ((sel >> 13u) & 1u) != 0u); // s19 add + r4 = r4 ^ simd_shuffle_xor(r5, (ushort)16); // s20 shfl + r0 = r0 + r4 + select(0x1e35684fu, 0x718c1008u, ((sel >> 21u) & 1u) != 0u); // s21 add + r0 = mulhi(r0, r3); // s22 mulhi + r4 = r4 ^ r2; // s23 xor + r0 = r0 - r2; // s24 sub + r5 = rotl_imm(r5, 13u); // s25 rotl + r7 = r7 - r0; // s26 sub + r2 = r2 ^ r3; // s27 xor + r2 = r3 * r2 + r2; // s28 mad + r2 = r2 ^ r1; // s29 xor + r4 = mulhi(r4, r0); // s30 mulhi + r6 = r6 ^ r4; // s31 xor + } + r4 = mulhi(r4, r1); // 12 + r7 = mulhi(r7, r3); // 13 + r3 = r3 + r2 + select(0x514f9ff4u, 0xc2828a42u, ((sel >> 8u) & 1u) != 0u); // 14 + r1 = r3 * r2 + r1; // 15 + r2 = rotl_imm(r2, 7u); // 16 + r1 = r1 ^ dataset[r2 & MASK]; // 17 + // per-load shadow sub-block 2 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 2 + for (uint sh2 = 0u; sh2 < 27u; ++sh2) { + r4 = r4 ^ r2; // s32 xor + r1 = r1 ^ simd_shuffle_xor(r2, (ushort)1); // s33 shfl + r5 = r5 ^ simd_shuffle_xor(r6, (ushort)1); // s34 shfl + r4 = r4 - r0; // s35 sub + r6 = r6 - r3; // s36 sub + r2 = r2 | r6; // s37 or + r2 = rotl_imm(r2, 30u); // s38 rotl + r4 = rotr_var(r4, r7); // s39 rotr + r0 = r0 | r7; // s40 or + r2 = rotr_var(r2, r5); // s41 rotr + r1 = r3 * r3 + r1; // s42 mad + r6 = r5 * r5 + r6; // s43 mad + r1 = mulhi(r1, r0); // s44 mulhi + r1 = r1 * r3; // s45 mul + r0 = r2 * r0 + r0; // s46 mad + r1 = r1 - r5; // s47 sub + } + r3 = r3 * r2; // 18 + r6 = rotl_imm(r6, 24u); // 19 + r6 = r6 ^ dataset[r3 & MASK]; // 20 + // per-load shadow sub-block 3 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 3 + for (uint sh3 = 0u; sh3 < 27u; ++sh3) { + r4 = r4 ^ r0; // s48 xor + r2 = rotr_var(r2, r0); // s49 rotr + r0 = mulhi(r0, r5); // s50 mulhi + r7 = r7 | r5; // s51 or + r4 = r0 * r3 + r4; // s52 mad + r0 = rotr_var(r0, r4); // s53 rotr + r6 = r3 * r3 + r6; // s54 mad + r6 = r4 * r2 + r6; // s55 mad + r5 = r5 ^ simd_shuffle_xor(r0, (ushort)2); // s56 shfl + r7 = rotl_imm(r7, 21u); // s57 rotl + r3 = r3 ^ r7; // s58 xor + r0 = r0 ^ simd_shuffle_xor(r4, (ushort)1); // s59 shfl + r5 = r5 ^ r6; // s60 xor + r4 = rotr_var(r4, r7); // s61 rotr + r1 = r1 + r6 + select(0xf7ccf1e9u, 0x31f87d74u, ((sel >> 10u) & 1u) != 0u); // s62 add + r5 = r5 + r2 + select(0x2f386099u, 0x9c2847f4u, ((sel >> 15u) & 1u) != 0u); // s63 add + } + r1 = r1 ^ dataset[r6 & MASK]; // 21 + // per-load shadow sub-block 4 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 4 + for (uint sh4 = 0u; sh4 < 27u; ++sh4) { + r7 = r7 + r0 + select(0x1b30ce7au, 0xd3241188u, ((sel >> 19u) & 1u) != 0u); // s64 add + r6 = r6 + r7 + select(0x02dc8349u, 0x9b42c3deu, ((sel >> 13u) & 1u) != 0u); // s65 add + r0 = rotl_imm(r0, 16u); // s66 rotl + r2 = rotl_imm(r2, 9u); // s67 rotl + r2 = r5 * r6 + r2; // s68 mad + r6 = r6 ^ simd_shuffle_xor(r1, (ushort)8); // s69 shfl + r2 = r2 ^ r5; // s70 xor + r5 = mulhi(r5, r1); // s71 mulhi + r6 = rotl_imm(r6, 29u); // s72 rotl + r0 = r0 - r7; // s73 sub + r5 = r2 * r2 + r5; // s74 mad + r0 = rotr_var(r0, r5); // s75 rotr + r7 = r7 + r2 + select(0x05d36679u, 0x0da1ce17u, ((sel >> 9u) & 1u) != 0u); // s76 add + r7 = r7 - r2; // s77 sub + r7 = rotr_var(r7, r0); // s78 rotr + r1 = r5 * r5 + r1; // s79 mad + } + r5 = r3 * r3 + r5; // 22 + r4 = r4 ^ dataset[r7 & MASK]; // 23 + // per-load shadow sub-block 5 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 5 + for (uint sh5 = 0u; sh5 < 27u; ++sh5) { + r3 = rotr_var(r3, r0); // s80 rotr + r6 = r6 + r5 + select(0xf14547bdu, 0xadf5ef88u, ((sel >> 2u) & 1u) != 0u); // s81 add + r0 = r0 | r6; // s82 or + r1 = mulhi(r1, r0); // s83 mulhi + r7 = r6 * r7 + r7; // s84 mad + r5 = rotl_imm(r5, 29u); // s85 rotl + r2 = r2 ^ r6; // s86 xor + r5 = r5 + r4 + select(0xba4947c2u, 0x35ff14aeu, ((sel >> 24u) & 1u) != 0u); // s87 add + r3 = r3 + r6 + select(0xf6878beeu, 0xf3900fc1u, ((sel >> 3u) & 1u) != 0u); // s88 add + r0 = r0 + r2 + select(0x926f3607u, 0xf7e8f59fu, ((sel >> 12u) & 1u) != 0u); // s89 add + r2 = r2 ^ r6; // s90 xor + r3 = r3 ^ simd_shuffle_xor(r2, (ushort)2); // s91 shfl + r6 = r6 - r1; // s92 sub + r5 = r5 + r1 + select(0xdab36c29u, 0x0e376f9cu, ((sel >> 13u) & 1u) != 0u); // s93 add + r6 = r1 * r1 + r6; // s94 mad + r3 = r3 ^ r4; // s95 xor + } + r6 = r6 ^ dataset[r4 & MASK]; // 24 + // per-load shadow sub-block 6 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 6 + for (uint sh6 = 0u; sh6 < 27u; ++sh6) { + r6 = r5 * r2 + r6; // s96 mad + r7 = r7 + r3 + select(0x204129e9u, 0x9f917747u, ((sel >> 23u) & 1u) != 0u); // s97 add + r5 = r5 ^ simd_shuffle_xor(r1, (ushort)16); // s98 shfl + r2 = r2 * r6; // s99 mul + r7 = r7 ^ simd_shuffle_xor(r3, (ushort)8); // s100 shfl + r6 = r6 + r1 + select(0xe3b596a0u, 0xe42fe974u, ((sel >> 10u) & 1u) != 0u); // s101 add + r5 = rotl_imm(r5, 3u); // s102 rotl + r5 = r5 ^ r1; // s103 xor + r4 = r4 + r1 + select(0x705c3f94u, 0xc3d77ffbu, ((sel >> 27u) & 1u) != 0u); // s104 add + r0 = r0 + r6 + select(0xbc6fb42bu, 0xea02a4cau, ((sel >> 25u) & 1u) != 0u); // s105 add + r3 = r3 | r5; // s106 or + r0 = r0 - r6; // s107 sub + r0 = rotr_var(r0, r3); // s108 rotr + r5 = r5 + r4 + select(0xcb37ea87u, 0x0357e63eu, ((sel >> 4u) & 1u) != 0u); // s109 add + r7 = rotl_imm(r7, 5u); // s110 rotl + r4 = r4 ^ r1; // s111 xor + } + r5 = r5 * r7; // 25 + r0 = r0 * r3; // 26 + r0 = r0 | r3; // 27 + r1 = r3 * r4 + r1; // 28 + r0 = r0 ^ simd_shuffle_xor(r2, (ushort)8); // 29 + r7 = r7 - r3; // 30 + r4 = r4 ^ r1; // 31 + r4 = r4 | r5; // 32 + r3 = rotr_var(r3, r5); // 33 + r4 = r4 ^ dataset[r5 & MASK]; // 34 + // per-load shadow sub-block 7 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 7 + for (uint sh7 = 0u; sh7 < 27u; ++sh7) { + r6 = r6 ^ r5; // s112 xor + r1 = r1 | r3; // s113 or + r0 = r0 + r5 + select(0x9aab0297u, 0x7f8b8cd2u, ((sel >> 3u) & 1u) != 0u); // s114 add + r3 = r3 - r5; // s115 sub + r4 = rotr_var(r4, r2); // s116 rotr + r4 = r4 + r6 + select(0xc511183fu, 0x59400b57u, ((sel >> 6u) & 1u) != 0u); // s117 add + r6 = r6 - r1; // s118 sub + r3 = r3 ^ simd_shuffle_xor(r1, (ushort)4); // s119 shfl + r6 = r4 * r4 + r6; // s120 mad + r2 = rotl_imm(r2, 8u); // s121 rotl + r5 = r0 * r3 + r5; // s122 mad + r7 = r7 + r6 + select(0x5200c242u, 0x27c70dc0u, ((sel >> 27u) & 1u) != 0u); // s123 add + r3 = r3 ^ simd_shuffle_xor(r5, (ushort)4); // s124 shfl + r0 = r0 + r1 + select(0x2d5028ceu, 0xec2f5997u, ((sel >> 17u) & 1u) != 0u); // s125 add + r3 = r3 ^ simd_shuffle_xor(r6, (ushort)16); // s126 shfl + r5 = r5 ^ r0; // s127 xor + } + r0 = r5 * r3 + r0; // 35 + r6 = r6 ^ dataset[r3 & MASK]; // 36 + // per-load shadow sub-block 8 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 8 + for (uint sh8 = 0u; sh8 < 27u; ++sh8) { + r7 = r7 + r1 + select(0x432f6c0du, 0x09e8ede2u, ((sel >> 10u) & 1u) != 0u); // s128 add + r2 = r2 ^ r4; // s129 xor + r0 = r0 * r2; // s130 mul + r4 = r4 | r3; // s131 or + r3 = r3 | r7; // s132 or + r7 = r7 ^ simd_shuffle_xor(r3, (ushort)1); // s133 shfl + r5 = r5 + r2 + select(0xcf5ecc75u, 0xce4fdf8eu, ((sel >> 11u) & 1u) != 0u); // s134 add + r3 = r2 * r3 + r3; // s135 mad + r1 = rotl_imm(r1, 11u); // s136 rotl + r2 = r2 | r0; // s137 or + r3 = r3 ^ r4; // s138 xor + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)1); // s139 shfl + r2 = rotl_imm(r2, 6u); // s140 rotl + r0 = r0 * r3; // s141 mul + r1 = r1 * r7; // s142 mul + r0 = r0 ^ r1; // s143 xor + } + r5 = r5 * r3; // 37 + r5 = r5 ^ r4; // 38 + r6 = r6 ^ r0; // 39 + r4 = rotr_var(r4, r0); // 40 + r7 = r7 ^ r6; // 41 + r1 = r1 ^ dataset[r7 & MASK]; // 42 + // per-load shadow sub-block 9 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 9 + for (uint sh9 = 0u; sh9 < 27u; ++sh9) { + r6 = r2 * r0 + r6; // s144 mad + r1 = rotl_imm(r1, 15u); // s145 rotl + r1 = rotl_imm(r1, 30u); // s146 rotl + r6 = r6 ^ r0; // s147 xor + r3 = r3 - r2; // s148 sub + r3 = r3 + r0 + select(0xaa002f15u, 0x11bbdeefu, ((sel >> 5u) & 1u) != 0u); // s149 add + r6 = r6 + r5 + select(0xbe64b2e2u, 0xff9d4b0eu, ((sel >> 9u) & 1u) != 0u); // s150 add + r1 = r1 * r4; // s151 mul + r5 = rotl_imm(r5, 3u); // s152 rotl + r5 = r5 * r2; // s153 mul + r2 = rotl_imm(r2, 21u); // s154 rotl + r5 = rotl_imm(r5, 18u); // s155 rotl + r1 = r1 ^ r5; // s156 xor + r1 = mulhi(r1, r6); // s157 mulhi + r4 = r7 * r3 + r4; // s158 mad + r4 = r4 - r7; // s159 sub + } + r2 = r2 - r4; // 43 + r6 = mulhi(r6, r7); // 44 + r3 = rotl_imm(r3, 13u); // 45 + r7 = r7 ^ simd_shuffle_xor(r6, (ushort)16); // 46 + r2 = rotl_imm(r2, 26u); // 47 + r6 = r6 * r2; // 48 + r2 = r2 ^ dataset[r3 & MASK]; // 49 + // per-load shadow sub-block 10 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 10 + for (uint sh10 = 0u; sh10 < 27u; ++sh10) { + r3 = r3 ^ r2; // s160 xor + r3 = mulhi(r3, r4); // s161 mulhi + r3 = r3 ^ simd_shuffle_xor(r2, (ushort)1); // s162 shfl + r0 = r0 - r1; // s163 sub + r6 = r6 ^ simd_shuffle_xor(r0, (ushort)8); // s164 shfl + r4 = r4 ^ simd_shuffle_xor(r2, (ushort)2); // s165 shfl + r3 = r3 | r6; // s166 or + r6 = r6 ^ simd_shuffle_xor(r3, (ushort)4); // s167 shfl + r2 = r2 ^ r1; // s168 xor + r5 = r5 ^ r1; // s169 xor + r5 = r5 ^ r0; // s170 xor + r3 = r6 * r0 + r3; // s171 mad + r3 = r3 - r0; // s172 sub + r6 = r6 + r0 + select(0x3b90694bu, 0xc72dc2a0u, ((sel >> 27u) & 1u) != 0u); // s173 add + r7 = r7 ^ simd_shuffle_xor(r2, (ushort)8); // s174 shfl + r5 = mulhi(r5, r2); // s175 mulhi + } + r5 = r5 ^ dataset[r1 & MASK]; // 50 + // per-load shadow sub-block 11 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 11 + for (uint sh11 = 0u; sh11 < 27u; ++sh11) { + r3 = r3 + r6 + select(0x9e65cebdu, 0x4eb75843u, ((sel >> 5u) & 1u) != 0u); // s176 add + r0 = r4 * r1 + r0; // s177 mad + r6 = rotr_var(r6, r7); // s178 rotr + r0 = r0 + r7 + select(0x01e5b250u, 0x7001d036u, ((sel >> 31u) & 1u) != 0u); // s179 add + r5 = r5 ^ simd_shuffle_xor(r2, (ushort)16); // s180 shfl + r3 = r3 * r0; // s181 mul + r0 = rotl_imm(r0, 23u); // s182 rotl + r7 = mulhi(r7, r0); // s183 mulhi + r0 = r0 * r4; // s184 mul + r1 = r1 + r4 + select(0xbef14988u, 0x91736711u, ((sel >> 19u) & 1u) != 0u); // s185 add + r7 = r7 + r2 + select(0xf5d741beu, 0x15e0cdf3u, ((sel >> 6u) & 1u) != 0u); // s186 add + r1 = r1 ^ r7; // s187 xor + r1 = r1 + r3 + select(0x32be33c6u, 0x7549bc3eu, ((sel >> 21u) & 1u) != 0u); // s188 add + r1 = r0 * r6 + r1; // s189 mad + r0 = rotr_var(r0, r5); // s190 rotr + r4 = r0 * r1 + r4; // s191 mad + } + r0 = rotl_imm(r0, 20u); // 51 + r1 = r1 ^ r2; // 52 + r2 = r2 ^ dataset[r1 & MASK]; // 53 + // per-load shadow sub-block 12 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 12 + for (uint sh12 = 0u; sh12 < 27u; ++sh12) { + r3 = r6 * r1 + r3; // s192 mad + r6 = rotl_imm(r6, 31u); // s193 rotl + r5 = rotl_imm(r5, 28u); // s194 rotl + r4 = r4 * r3; // s195 mul + r2 = r2 + r3 + select(0x9d7aebbbu, 0x7c3d6253u, ((sel >> 4u) & 1u) != 0u); // s196 add + r3 = r3 | r5; // s197 or + r6 = r6 - r0; // s198 sub + r7 = r7 * r4; // s199 mul + r3 = rotr_var(r3, r2); // s200 rotr + r4 = r4 ^ simd_shuffle_xor(r0, (ushort)16); // s201 shfl + r7 = r7 ^ r3; // s202 xor + r4 = r4 | r3; // s203 or + r3 = rotr_var(r3, r6); // s204 rotr + r0 = rotr_var(r0, r1); // s205 rotr + r2 = r5 * r2 + r2; // s206 mad + r1 = mulhi(r1, r5); // s207 mulhi + } + r4 = rotl_imm(r4, 20u); // 54 + r3 = r3 ^ simd_shuffle_xor(r1, (ushort)2); // 55 + r1 = r1 ^ dataset[r0 & MASK]; // 56 + // per-load shadow sub-block 13 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 13 + for (uint sh13 = 0u; sh13 < 27u; ++sh13) { + r4 = r4 ^ simd_shuffle_xor(r3, (ushort)1); // s208 shfl + r7 = r5 * r7 + r7; // s209 mad + r6 = r6 ^ r3; // s210 xor + r3 = r3 ^ r2; // s211 xor + r5 = r5 ^ simd_shuffle_xor(r6, (ushort)16); // s212 shfl + r4 = rotl_imm(r4, 10u); // s213 rotl + r5 = r5 ^ simd_shuffle_xor(r6, (ushort)16); // s214 shfl + r3 = r3 | r0; // s215 or + r4 = r4 * r5; // s216 mul + r0 = r0 ^ simd_shuffle_xor(r3, (ushort)16); // s217 shfl + r0 = r0 * r5; // s218 mul + r0 = rotl_imm(r0, 13u); // s219 rotl + r1 = mulhi(r1, r0); // s220 mulhi + r4 = r4 ^ r1; // s221 xor + r2 = r2 | r3; // s222 or + r0 = r0 ^ r4; // s223 xor + } + r3 = r3 ^ dataset[r5 & MASK]; // 57 + // per-load shadow sub-block 14 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 14 + for (uint sh14 = 0u; sh14 < 27u; ++sh14) { + r5 = r6 * r1 + r5; // s224 mad + r4 = r4 ^ r3; // s225 xor + r5 = r5 + r0 + select(0xfe960971u, 0xe4e51c75u, ((sel >> 3u) & 1u) != 0u); // s226 add + r3 = mulhi(r3, r2); // s227 mulhi + r2 = r2 ^ r6; // s228 xor + r1 = mulhi(r1, r5); // s229 mulhi + r3 = r3 + r4 + select(0x48b3ce0au, 0x4d597c08u, ((sel >> 25u) & 1u) != 0u); // s230 add + r2 = rotr_var(r2, r3); // s231 rotr + r2 = r2 - r7; // s232 sub + r6 = r6 | r2; // s233 or + r0 = rotr_var(r0, r3); // s234 rotr + r4 = r4 + r3 + select(0x2ed8c878u, 0xc9f1d54cu, ((sel >> 13u) & 1u) != 0u); // s235 add + r0 = r3 * r7 + r0; // s236 mad + r3 = r3 + r5 + select(0x22e8b90au, 0xc572bd00u, ((sel >> 29u) & 1u) != 0u); // s237 add + r0 = mulhi(r0, r4); // s238 mulhi + r6 = r6 * r5; // s239 mul + } + r1 = r1 ^ simd_shuffle_xor(r2, (ushort)2); // 58 + r6 = r6 ^ dataset[r4 & MASK]; // 59 + // per-load shadow sub-block 15 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 15 + for (uint sh15 = 0u; sh15 < 27u; ++sh15) { + r5 = r5 + r2 + select(0xc6b790e6u, 0xb233f94fu, ((sel >> 20u) & 1u) != 0u); // s240 add + r0 = r0 - r3; // s241 sub + r4 = r4 + r7 + select(0x0f918d3bu, 0x534d924bu, ((sel >> 4u) & 1u) != 0u); // s242 add + r5 = rotr_var(r5, r0); // s243 rotr + r1 = rotr_var(r1, r7); // s244 rotr + r2 = r2 | r0; // s245 or + r4 = r4 * r7; // s246 mul + r1 = r2 * r5 + r1; // s247 mad + r2 = r2 * r5; // s248 mul + r4 = r4 ^ r2; // s249 xor + r3 = r3 ^ r1; // s250 xor + r5 = rotr_var(r5, r7); // s251 rotr + r2 = r7 * r7 + r2; // s252 mad + r7 = rotr_var(r7, r3); // s253 rotr + r6 = r6 + r1 + select(0xb8a27d95u, 0x86d27169u, ((sel >> 21u) & 1u) != 0u); // s254 add + r6 = r6 | r7; // s255 or + } + r7 = r7 ^ simd_shuffle_xor(r3, (ushort)4); // 60 + r5 = rotr_var(r5, r0); // 61 + r0 = r0 + r6 + select(0x8c2e5c24u, 0xb13a5391u, ((sel >> 14u) & 1u) != 0u); // 62 + r2 = r2 + r1 + select(0xb225b762u, 0xf82fc8b5u, ((sel >> 21u) & 1u) != 0u); // 63 + } + uint lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((ulong)hi << 32) | (ulong)lo; +} diff --git a/proto-cuda/packs-ca4/mx8_shl256x27_v2/program_bound.metal b/proto-cuda/packs-ca4/mx8_shl256x27_v2/program_bound.metal new file mode 100644 index 000000000..8d57d2447 --- /dev/null +++ b/proto-cuda/packs-ca4/mx8_shl256x27_v2/program_bound.metal @@ -0,0 +1,415 @@ +#include +using namespace metal; + +#define MASK 0x0fffffffu +constant uint SEEDW[8] = { 0xf71aee9fu, 0xad930c88u, 0x7f982573u, 0xa41f9137u, 0x76d803d6u, 0x37b4a534u, 0x4d3fb826u, 0xff614dcbu }; + +inline uint splitmix32(uint x) { + x ^= x >> 16; x *= 0x7feb352du; + x ^= x >> 15; x *= 0x846ca68bu; + x ^= x >> 16; + return x; +} +inline uint rotl_imm(uint x, uint n) { return (x << n) | (x >> (32u - n)); } // n in 1..31 +inline uint rotr_var(uint x, uint n) { n &= 31u; return (x >> n) | (x << ((32u - n) & 31u)); } +inline uint ds_elem(uint i, uint d0, uint d1) { + uint x = i ^ d0; + x *= 0x9E3779B1u; x ^= x >> 15; + x += d1; + x *= 0x85EBCA77u; x ^= x >> 13; + x *= 0xC2B2AE3Du; x ^= x >> 16; + return x; +} + +// Header-bound variant: the init words come from buffer 3 (bind.rs), not from SEEDW. +kernel void igneum_hash_bound(device const uint* dataset [[buffer(0)]], + device ulong* out [[buffer(1)]], + constant uint& baseNonce [[buffer(2)]], + constant uint* initw [[buffer(3)]], + uint gid [[thread_position_in_grid]]) { + uint nonce = baseNonce + gid; + uint r0, r1, r2, r3, r4, r5, r6, r7; + { uint x = nonce ^ initw[0]; x += 0x9e3779b9u * 1u; x = splitmix32(x); r0 = x ^ initw[1]; } + { uint x = nonce ^ initw[1]; x += 0x9e3779b9u * 2u; x = splitmix32(x); r1 = x ^ initw[2]; } + { uint x = nonce ^ initw[2]; x += 0x9e3779b9u * 3u; x = splitmix32(x); r2 = x ^ initw[3]; } + { uint x = nonce ^ initw[3]; x += 0x9e3779b9u * 4u; x = splitmix32(x); r3 = x ^ initw[4]; } + { uint x = nonce ^ initw[4]; x += 0x9e3779b9u * 5u; x = splitmix32(x); r4 = x ^ initw[5]; } + { uint x = nonce ^ initw[5]; x += 0x9e3779b9u * 6u; x = splitmix32(x); r5 = x ^ initw[6]; } + { uint x = nonce ^ initw[6]; x += 0x9e3779b9u * 7u; x = splitmix32(x); r6 = x ^ initw[7]; } + { uint x = nonce ^ initw[7]; x += 0x9e3779b9u * 8u; x = splitmix32(x); r7 = x ^ initw[0]; } + + for (uint it = 0u; it < 8u; ++it) { + uint sel = r0; + r2 = r2 + r5 + select(0xe3e2ed7du, 0x894e457du, ((sel >> 2u) & 1u) != 0u); // 0 + r7 = r4 * r0 + r7; // 1 + r3 = r3 - r6; // 2 + r5 = rotr_var(r5, r1); // 3 + r6 = r6 ^ simd_shuffle_xor(r2, (ushort)1); // 4 + r0 = r0 | r3; // 5 + r0 = r0 * r1; // 6 + r7 = r7 * r6; // 7 + r3 = r3 ^ dataset[r0 & MASK]; // 8 + // per-load shadow sub-block 0 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 0 + for (uint sh0 = 0u; sh0 < 27u; ++sh0) { + r5 = rotr_var(r5, r4); // s0 rotr + r6 = r6 - r5; // s1 sub + r7 = r7 - r6; // s2 sub + r5 = r5 * r4; // s3 mul + r7 = r7 ^ r6; // s4 xor + r2 = rotl_imm(r2, 23u); // s5 rotl + r7 = r7 ^ r4; // s6 xor + r0 = r0 + r7 + select(0xdaef8862u, 0x3051c491u, ((sel >> 26u) & 1u) != 0u); // s7 add + r6 = r6 ^ simd_shuffle_xor(r1, (ushort)4); // s8 shfl + r5 = r5 + r1 + select(0xc20e7045u, 0x5170d0b3u, ((sel >> 26u) & 1u) != 0u); // s9 add + r0 = r0 | r3; // s10 or + r5 = mulhi(r5, r4); // s11 mulhi + r7 = r7 ^ r0; // s12 xor + r5 = r5 - r2; // s13 sub + r0 = r0 + r6 + select(0xc86d98a4u, 0x2ead087fu, ((sel >> 0u) & 1u) != 0u); // s14 add + r5 = r5 ^ r7; // s15 xor + } + r4 = r4 + r3 + select(0xce9bea84u, 0xd26d3573u, ((sel >> 22u) & 1u) != 0u); // 9 + r2 = r2 * r4; // 10 + r3 = r3 ^ dataset[r2 & MASK]; // 11 + // per-load shadow sub-block 1 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 1 + for (uint sh1 = 0u; sh1 < 27u; ++sh1) { + r7 = r7 ^ simd_shuffle_xor(r6, (ushort)8); // s16 shfl + r5 = r5 - r7; // s17 sub + r0 = r0 | r6; // s18 or + r0 = r0 + r5 + select(0x4248b651u, 0xc47c70a8u, ((sel >> 13u) & 1u) != 0u); // s19 add + r4 = r4 ^ simd_shuffle_xor(r5, (ushort)16); // s20 shfl + r0 = r0 + r4 + select(0x1e35684fu, 0x718c1008u, ((sel >> 21u) & 1u) != 0u); // s21 add + r0 = mulhi(r0, r3); // s22 mulhi + r4 = r4 ^ r2; // s23 xor + r0 = r0 - r2; // s24 sub + r5 = rotl_imm(r5, 13u); // s25 rotl + r7 = r7 - r0; // s26 sub + r2 = r2 ^ r3; // s27 xor + r2 = r3 * r2 + r2; // s28 mad + r2 = r2 ^ r1; // s29 xor + r4 = mulhi(r4, r0); // s30 mulhi + r6 = r6 ^ r4; // s31 xor + } + r4 = mulhi(r4, r1); // 12 + r7 = mulhi(r7, r3); // 13 + r3 = r3 + r2 + select(0x514f9ff4u, 0xc2828a42u, ((sel >> 8u) & 1u) != 0u); // 14 + r1 = r3 * r2 + r1; // 15 + r2 = rotl_imm(r2, 7u); // 16 + r1 = r1 ^ dataset[r2 & MASK]; // 17 + // per-load shadow sub-block 2 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 2 + for (uint sh2 = 0u; sh2 < 27u; ++sh2) { + r4 = r4 ^ r2; // s32 xor + r1 = r1 ^ simd_shuffle_xor(r2, (ushort)1); // s33 shfl + r5 = r5 ^ simd_shuffle_xor(r6, (ushort)1); // s34 shfl + r4 = r4 - r0; // s35 sub + r6 = r6 - r3; // s36 sub + r2 = r2 | r6; // s37 or + r2 = rotl_imm(r2, 30u); // s38 rotl + r4 = rotr_var(r4, r7); // s39 rotr + r0 = r0 | r7; // s40 or + r2 = rotr_var(r2, r5); // s41 rotr + r1 = r3 * r3 + r1; // s42 mad + r6 = r5 * r5 + r6; // s43 mad + r1 = mulhi(r1, r0); // s44 mulhi + r1 = r1 * r3; // s45 mul + r0 = r2 * r0 + r0; // s46 mad + r1 = r1 - r5; // s47 sub + } + r3 = r3 * r2; // 18 + r6 = rotl_imm(r6, 24u); // 19 + r6 = r6 ^ dataset[r3 & MASK]; // 20 + // per-load shadow sub-block 3 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 3 + for (uint sh3 = 0u; sh3 < 27u; ++sh3) { + r4 = r4 ^ r0; // s48 xor + r2 = rotr_var(r2, r0); // s49 rotr + r0 = mulhi(r0, r5); // s50 mulhi + r7 = r7 | r5; // s51 or + r4 = r0 * r3 + r4; // s52 mad + r0 = rotr_var(r0, r4); // s53 rotr + r6 = r3 * r3 + r6; // s54 mad + r6 = r4 * r2 + r6; // s55 mad + r5 = r5 ^ simd_shuffle_xor(r0, (ushort)2); // s56 shfl + r7 = rotl_imm(r7, 21u); // s57 rotl + r3 = r3 ^ r7; // s58 xor + r0 = r0 ^ simd_shuffle_xor(r4, (ushort)1); // s59 shfl + r5 = r5 ^ r6; // s60 xor + r4 = rotr_var(r4, r7); // s61 rotr + r1 = r1 + r6 + select(0xf7ccf1e9u, 0x31f87d74u, ((sel >> 10u) & 1u) != 0u); // s62 add + r5 = r5 + r2 + select(0x2f386099u, 0x9c2847f4u, ((sel >> 15u) & 1u) != 0u); // s63 add + } + r1 = r1 ^ dataset[r6 & MASK]; // 21 + // per-load shadow sub-block 4 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 4 + for (uint sh4 = 0u; sh4 < 27u; ++sh4) { + r7 = r7 + r0 + select(0x1b30ce7au, 0xd3241188u, ((sel >> 19u) & 1u) != 0u); // s64 add + r6 = r6 + r7 + select(0x02dc8349u, 0x9b42c3deu, ((sel >> 13u) & 1u) != 0u); // s65 add + r0 = rotl_imm(r0, 16u); // s66 rotl + r2 = rotl_imm(r2, 9u); // s67 rotl + r2 = r5 * r6 + r2; // s68 mad + r6 = r6 ^ simd_shuffle_xor(r1, (ushort)8); // s69 shfl + r2 = r2 ^ r5; // s70 xor + r5 = mulhi(r5, r1); // s71 mulhi + r6 = rotl_imm(r6, 29u); // s72 rotl + r0 = r0 - r7; // s73 sub + r5 = r2 * r2 + r5; // s74 mad + r0 = rotr_var(r0, r5); // s75 rotr + r7 = r7 + r2 + select(0x05d36679u, 0x0da1ce17u, ((sel >> 9u) & 1u) != 0u); // s76 add + r7 = r7 - r2; // s77 sub + r7 = rotr_var(r7, r0); // s78 rotr + r1 = r5 * r5 + r1; // s79 mad + } + r5 = r3 * r3 + r5; // 22 + r4 = r4 ^ dataset[r7 & MASK]; // 23 + // per-load shadow sub-block 5 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 5 + for (uint sh5 = 0u; sh5 < 27u; ++sh5) { + r3 = rotr_var(r3, r0); // s80 rotr + r6 = r6 + r5 + select(0xf14547bdu, 0xadf5ef88u, ((sel >> 2u) & 1u) != 0u); // s81 add + r0 = r0 | r6; // s82 or + r1 = mulhi(r1, r0); // s83 mulhi + r7 = r6 * r7 + r7; // s84 mad + r5 = rotl_imm(r5, 29u); // s85 rotl + r2 = r2 ^ r6; // s86 xor + r5 = r5 + r4 + select(0xba4947c2u, 0x35ff14aeu, ((sel >> 24u) & 1u) != 0u); // s87 add + r3 = r3 + r6 + select(0xf6878beeu, 0xf3900fc1u, ((sel >> 3u) & 1u) != 0u); // s88 add + r0 = r0 + r2 + select(0x926f3607u, 0xf7e8f59fu, ((sel >> 12u) & 1u) != 0u); // s89 add + r2 = r2 ^ r6; // s90 xor + r3 = r3 ^ simd_shuffle_xor(r2, (ushort)2); // s91 shfl + r6 = r6 - r1; // s92 sub + r5 = r5 + r1 + select(0xdab36c29u, 0x0e376f9cu, ((sel >> 13u) & 1u) != 0u); // s93 add + r6 = r1 * r1 + r6; // s94 mad + r3 = r3 ^ r4; // s95 xor + } + r6 = r6 ^ dataset[r4 & MASK]; // 24 + // per-load shadow sub-block 6 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 6 + for (uint sh6 = 0u; sh6 < 27u; ++sh6) { + r6 = r5 * r2 + r6; // s96 mad + r7 = r7 + r3 + select(0x204129e9u, 0x9f917747u, ((sel >> 23u) & 1u) != 0u); // s97 add + r5 = r5 ^ simd_shuffle_xor(r1, (ushort)16); // s98 shfl + r2 = r2 * r6; // s99 mul + r7 = r7 ^ simd_shuffle_xor(r3, (ushort)8); // s100 shfl + r6 = r6 + r1 + select(0xe3b596a0u, 0xe42fe974u, ((sel >> 10u) & 1u) != 0u); // s101 add + r5 = rotl_imm(r5, 3u); // s102 rotl + r5 = r5 ^ r1; // s103 xor + r4 = r4 + r1 + select(0x705c3f94u, 0xc3d77ffbu, ((sel >> 27u) & 1u) != 0u); // s104 add + r0 = r0 + r6 + select(0xbc6fb42bu, 0xea02a4cau, ((sel >> 25u) & 1u) != 0u); // s105 add + r3 = r3 | r5; // s106 or + r0 = r0 - r6; // s107 sub + r0 = rotr_var(r0, r3); // s108 rotr + r5 = r5 + r4 + select(0xcb37ea87u, 0x0357e63eu, ((sel >> 4u) & 1u) != 0u); // s109 add + r7 = rotl_imm(r7, 5u); // s110 rotl + r4 = r4 ^ r1; // s111 xor + } + r5 = r5 * r7; // 25 + r0 = r0 * r3; // 26 + r0 = r0 | r3; // 27 + r1 = r3 * r4 + r1; // 28 + r0 = r0 ^ simd_shuffle_xor(r2, (ushort)8); // 29 + r7 = r7 - r3; // 30 + r4 = r4 ^ r1; // 31 + r4 = r4 | r5; // 32 + r3 = rotr_var(r3, r5); // 33 + r4 = r4 ^ dataset[r5 & MASK]; // 34 + // per-load shadow sub-block 7 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 7 + for (uint sh7 = 0u; sh7 < 27u; ++sh7) { + r6 = r6 ^ r5; // s112 xor + r1 = r1 | r3; // s113 or + r0 = r0 + r5 + select(0x9aab0297u, 0x7f8b8cd2u, ((sel >> 3u) & 1u) != 0u); // s114 add + r3 = r3 - r5; // s115 sub + r4 = rotr_var(r4, r2); // s116 rotr + r4 = r4 + r6 + select(0xc511183fu, 0x59400b57u, ((sel >> 6u) & 1u) != 0u); // s117 add + r6 = r6 - r1; // s118 sub + r3 = r3 ^ simd_shuffle_xor(r1, (ushort)4); // s119 shfl + r6 = r4 * r4 + r6; // s120 mad + r2 = rotl_imm(r2, 8u); // s121 rotl + r5 = r0 * r3 + r5; // s122 mad + r7 = r7 + r6 + select(0x5200c242u, 0x27c70dc0u, ((sel >> 27u) & 1u) != 0u); // s123 add + r3 = r3 ^ simd_shuffle_xor(r5, (ushort)4); // s124 shfl + r0 = r0 + r1 + select(0x2d5028ceu, 0xec2f5997u, ((sel >> 17u) & 1u) != 0u); // s125 add + r3 = r3 ^ simd_shuffle_xor(r6, (ushort)16); // s126 shfl + r5 = r5 ^ r0; // s127 xor + } + r0 = r5 * r3 + r0; // 35 + r6 = r6 ^ dataset[r3 & MASK]; // 36 + // per-load shadow sub-block 8 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 8 + for (uint sh8 = 0u; sh8 < 27u; ++sh8) { + r7 = r7 + r1 + select(0x432f6c0du, 0x09e8ede2u, ((sel >> 10u) & 1u) != 0u); // s128 add + r2 = r2 ^ r4; // s129 xor + r0 = r0 * r2; // s130 mul + r4 = r4 | r3; // s131 or + r3 = r3 | r7; // s132 or + r7 = r7 ^ simd_shuffle_xor(r3, (ushort)1); // s133 shfl + r5 = r5 + r2 + select(0xcf5ecc75u, 0xce4fdf8eu, ((sel >> 11u) & 1u) != 0u); // s134 add + r3 = r2 * r3 + r3; // s135 mad + r1 = rotl_imm(r1, 11u); // s136 rotl + r2 = r2 | r0; // s137 or + r3 = r3 ^ r4; // s138 xor + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)1); // s139 shfl + r2 = rotl_imm(r2, 6u); // s140 rotl + r0 = r0 * r3; // s141 mul + r1 = r1 * r7; // s142 mul + r0 = r0 ^ r1; // s143 xor + } + r5 = r5 * r3; // 37 + r5 = r5 ^ r4; // 38 + r6 = r6 ^ r0; // 39 + r4 = rotr_var(r4, r0); // 40 + r7 = r7 ^ r6; // 41 + r1 = r1 ^ dataset[r7 & MASK]; // 42 + // per-load shadow sub-block 9 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 9 + for (uint sh9 = 0u; sh9 < 27u; ++sh9) { + r6 = r2 * r0 + r6; // s144 mad + r1 = rotl_imm(r1, 15u); // s145 rotl + r1 = rotl_imm(r1, 30u); // s146 rotl + r6 = r6 ^ r0; // s147 xor + r3 = r3 - r2; // s148 sub + r3 = r3 + r0 + select(0xaa002f15u, 0x11bbdeefu, ((sel >> 5u) & 1u) != 0u); // s149 add + r6 = r6 + r5 + select(0xbe64b2e2u, 0xff9d4b0eu, ((sel >> 9u) & 1u) != 0u); // s150 add + r1 = r1 * r4; // s151 mul + r5 = rotl_imm(r5, 3u); // s152 rotl + r5 = r5 * r2; // s153 mul + r2 = rotl_imm(r2, 21u); // s154 rotl + r5 = rotl_imm(r5, 18u); // s155 rotl + r1 = r1 ^ r5; // s156 xor + r1 = mulhi(r1, r6); // s157 mulhi + r4 = r7 * r3 + r4; // s158 mad + r4 = r4 - r7; // s159 sub + } + r2 = r2 - r4; // 43 + r6 = mulhi(r6, r7); // 44 + r3 = rotl_imm(r3, 13u); // 45 + r7 = r7 ^ simd_shuffle_xor(r6, (ushort)16); // 46 + r2 = rotl_imm(r2, 26u); // 47 + r6 = r6 * r2; // 48 + r2 = r2 ^ dataset[r3 & MASK]; // 49 + // per-load shadow sub-block 10 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 10 + for (uint sh10 = 0u; sh10 < 27u; ++sh10) { + r3 = r3 ^ r2; // s160 xor + r3 = mulhi(r3, r4); // s161 mulhi + r3 = r3 ^ simd_shuffle_xor(r2, (ushort)1); // s162 shfl + r0 = r0 - r1; // s163 sub + r6 = r6 ^ simd_shuffle_xor(r0, (ushort)8); // s164 shfl + r4 = r4 ^ simd_shuffle_xor(r2, (ushort)2); // s165 shfl + r3 = r3 | r6; // s166 or + r6 = r6 ^ simd_shuffle_xor(r3, (ushort)4); // s167 shfl + r2 = r2 ^ r1; // s168 xor + r5 = r5 ^ r1; // s169 xor + r5 = r5 ^ r0; // s170 xor + r3 = r6 * r0 + r3; // s171 mad + r3 = r3 - r0; // s172 sub + r6 = r6 + r0 + select(0x3b90694bu, 0xc72dc2a0u, ((sel >> 27u) & 1u) != 0u); // s173 add + r7 = r7 ^ simd_shuffle_xor(r2, (ushort)8); // s174 shfl + r5 = mulhi(r5, r2); // s175 mulhi + } + r5 = r5 ^ dataset[r1 & MASK]; // 50 + // per-load shadow sub-block 11 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 11 + for (uint sh11 = 0u; sh11 < 27u; ++sh11) { + r3 = r3 + r6 + select(0x9e65cebdu, 0x4eb75843u, ((sel >> 5u) & 1u) != 0u); // s176 add + r0 = r4 * r1 + r0; // s177 mad + r6 = rotr_var(r6, r7); // s178 rotr + r0 = r0 + r7 + select(0x01e5b250u, 0x7001d036u, ((sel >> 31u) & 1u) != 0u); // s179 add + r5 = r5 ^ simd_shuffle_xor(r2, (ushort)16); // s180 shfl + r3 = r3 * r0; // s181 mul + r0 = rotl_imm(r0, 23u); // s182 rotl + r7 = mulhi(r7, r0); // s183 mulhi + r0 = r0 * r4; // s184 mul + r1 = r1 + r4 + select(0xbef14988u, 0x91736711u, ((sel >> 19u) & 1u) != 0u); // s185 add + r7 = r7 + r2 + select(0xf5d741beu, 0x15e0cdf3u, ((sel >> 6u) & 1u) != 0u); // s186 add + r1 = r1 ^ r7; // s187 xor + r1 = r1 + r3 + select(0x32be33c6u, 0x7549bc3eu, ((sel >> 21u) & 1u) != 0u); // s188 add + r1 = r0 * r6 + r1; // s189 mad + r0 = rotr_var(r0, r5); // s190 rotr + r4 = r0 * r1 + r4; // s191 mad + } + r0 = rotl_imm(r0, 20u); // 51 + r1 = r1 ^ r2; // 52 + r2 = r2 ^ dataset[r1 & MASK]; // 53 + // per-load shadow sub-block 12 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 12 + for (uint sh12 = 0u; sh12 < 27u; ++sh12) { + r3 = r6 * r1 + r3; // s192 mad + r6 = rotl_imm(r6, 31u); // s193 rotl + r5 = rotl_imm(r5, 28u); // s194 rotl + r4 = r4 * r3; // s195 mul + r2 = r2 + r3 + select(0x9d7aebbbu, 0x7c3d6253u, ((sel >> 4u) & 1u) != 0u); // s196 add + r3 = r3 | r5; // s197 or + r6 = r6 - r0; // s198 sub + r7 = r7 * r4; // s199 mul + r3 = rotr_var(r3, r2); // s200 rotr + r4 = r4 ^ simd_shuffle_xor(r0, (ushort)16); // s201 shfl + r7 = r7 ^ r3; // s202 xor + r4 = r4 | r3; // s203 or + r3 = rotr_var(r3, r6); // s204 rotr + r0 = rotr_var(r0, r1); // s205 rotr + r2 = r5 * r2 + r2; // s206 mad + r1 = mulhi(r1, r5); // s207 mulhi + } + r4 = rotl_imm(r4, 20u); // 54 + r3 = r3 ^ simd_shuffle_xor(r1, (ushort)2); // 55 + r1 = r1 ^ dataset[r0 & MASK]; // 56 + // per-load shadow sub-block 13 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 13 + for (uint sh13 = 0u; sh13 < 27u; ++sh13) { + r4 = r4 ^ simd_shuffle_xor(r3, (ushort)1); // s208 shfl + r7 = r5 * r7 + r7; // s209 mad + r6 = r6 ^ r3; // s210 xor + r3 = r3 ^ r2; // s211 xor + r5 = r5 ^ simd_shuffle_xor(r6, (ushort)16); // s212 shfl + r4 = rotl_imm(r4, 10u); // s213 rotl + r5 = r5 ^ simd_shuffle_xor(r6, (ushort)16); // s214 shfl + r3 = r3 | r0; // s215 or + r4 = r4 * r5; // s216 mul + r0 = r0 ^ simd_shuffle_xor(r3, (ushort)16); // s217 shfl + r0 = r0 * r5; // s218 mul + r0 = rotl_imm(r0, 13u); // s219 rotl + r1 = mulhi(r1, r0); // s220 mulhi + r4 = r4 ^ r1; // s221 xor + r2 = r2 | r3; // s222 or + r0 = r0 ^ r4; // s223 xor + } + r3 = r3 ^ dataset[r5 & MASK]; // 57 + // per-load shadow sub-block 14 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 14 + for (uint sh14 = 0u; sh14 < 27u; ++sh14) { + r5 = r6 * r1 + r5; // s224 mad + r4 = r4 ^ r3; // s225 xor + r5 = r5 + r0 + select(0xfe960971u, 0xe4e51c75u, ((sel >> 3u) & 1u) != 0u); // s226 add + r3 = mulhi(r3, r2); // s227 mulhi + r2 = r2 ^ r6; // s228 xor + r1 = mulhi(r1, r5); // s229 mulhi + r3 = r3 + r4 + select(0x48b3ce0au, 0x4d597c08u, ((sel >> 25u) & 1u) != 0u); // s230 add + r2 = rotr_var(r2, r3); // s231 rotr + r2 = r2 - r7; // s232 sub + r6 = r6 | r2; // s233 or + r0 = rotr_var(r0, r3); // s234 rotr + r4 = r4 + r3 + select(0x2ed8c878u, 0xc9f1d54cu, ((sel >> 13u) & 1u) != 0u); // s235 add + r0 = r3 * r7 + r0; // s236 mad + r3 = r3 + r5 + select(0x22e8b90au, 0xc572bd00u, ((sel >> 29u) & 1u) != 0u); // s237 add + r0 = mulhi(r0, r4); // s238 mulhi + r6 = r6 * r5; // s239 mul + } + r1 = r1 ^ simd_shuffle_xor(r2, (ushort)2); // 58 + r6 = r6 ^ dataset[r4 & MASK]; // 59 + // per-load shadow sub-block 15 (Counter ASIC 4.0 research): 16 ALU instructions x 27 passes after load 15 + for (uint sh15 = 0u; sh15 < 27u; ++sh15) { + r5 = r5 + r2 + select(0xc6b790e6u, 0xb233f94fu, ((sel >> 20u) & 1u) != 0u); // s240 add + r0 = r0 - r3; // s241 sub + r4 = r4 + r7 + select(0x0f918d3bu, 0x534d924bu, ((sel >> 4u) & 1u) != 0u); // s242 add + r5 = rotr_var(r5, r0); // s243 rotr + r1 = rotr_var(r1, r7); // s244 rotr + r2 = r2 | r0; // s245 or + r4 = r4 * r7; // s246 mul + r1 = r2 * r5 + r1; // s247 mad + r2 = r2 * r5; // s248 mul + r4 = r4 ^ r2; // s249 xor + r3 = r3 ^ r1; // s250 xor + r5 = rotr_var(r5, r7); // s251 rotr + r2 = r7 * r7 + r2; // s252 mad + r7 = rotr_var(r7, r3); // s253 rotr + r6 = r6 + r1 + select(0xb8a27d95u, 0x86d27169u, ((sel >> 21u) & 1u) != 0u); // s254 add + r6 = r6 | r7; // s255 or + } + r7 = r7 ^ simd_shuffle_xor(r3, (ushort)4); // 60 + r5 = rotr_var(r5, r0); // 61 + r0 = r0 + r6 + select(0x8c2e5c24u, 0xb13a5391u, ((sel >> 14u) & 1u) != 0u); // 62 + r2 = r2 + r1 + select(0xb225b762u, 0xf82fc8b5u, ((sel >> 21u) & 1u) != 0u); // 63 + } + uint lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((ulong)hi << 32) | (ulong)lo; +} diff --git a/proto-cuda/packs-ca4/mx8_shl256x27_v2/vectors.h b/proto-cuda/packs-ca4/mx8_shl256x27_v2/vectors.h new file mode 100644 index 000000000..cd482f7fe --- /dev/null +++ b/proto-cuda/packs-ca4/mx8_shl256x27_v2/vectors.h @@ -0,0 +1,57 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Expected outputs: igneum-pow (Rust) CPU interpreter, generator v2, memory-hard dataset +#pragma once +#ifdef __cplusplus +#include +#else +#include +#endif + +#define IGNEUM_VEC_WARPS 3 +static const uint32_t IGNEUM_VEC_BASE[IGNEUM_VEC_WARPS] = { 0u, 4096u, 1000000u }; +static const uint64_t IGNEUM_VEC_OUT[IGNEUM_VEC_WARPS][32] = { + { // base nonce 0 + 0xefd63997a0441711ull, 0x33de48f246942bbdull, 0x75d11c0462d5d88eull, 0x339027e7a81edd02ull, 0x44ea8055287924c8ull, 0x94695edae512b2fdull, 0x10e849a40976a1f9ull, 0xe359cb57411223cdull, + 0x9f87f6349d272c37ull, 0x9b014e403a50b9d8ull, 0x26fc7cf39d2abb3full, 0x46a8c54601339b19ull, 0x24358a4463be7912ull, 0x9114765e85734923ull, 0x6fe5559c34419006ull, 0x6e0084f9fb52a815ull, + 0xcb00c0ae818d85adull, 0x523ff275ef11bba8ull, 0x18919bc6daeeecc9ull, 0x049eb1764feed566ull, 0xb10204b89ad283fcull, 0xb01bd8c897ec6edaull, 0x37566026b58c0a06ull, 0x52dd03de72a2c1c1ull, + 0xfdb39e45434da769ull, 0x65aa545737c3d5a8ull, 0x1075f64ffd1240fbull, 0x4c025b333a619365ull, 0x370d220ec4a57f28ull, 0x65279249eac9e65bull, 0x733a248e4f1d06b0ull, 0xc8b37f453592452bull + }, + { // base nonce 4096 + 0x918005a6d3fbc63eull, 0xb96b1dd6712afa86ull, 0xd76c1007676d61c2ull, 0x05390f3bd5062f59ull, 0x73aa6903da6f4356ull, 0xc494259068e25752ull, 0xf59c83f92e53c420ull, 0xd218528573a52adeull, + 0x3978767d74c7d605ull, 0xeaab672b16d91b5aull, 0x7c63cb2f17d0e460ull, 0x259ed48b2ecf354cull, 0x39086dbce0897309ull, 0x77a4dd060aaaf1bcull, 0xac407a7c7bea2ebcull, 0xfd818079715aa327ull, + 0x7b9db28bfbac80d0ull, 0xecd209239058699eull, 0x5ed5239644b890f6ull, 0x1671a35df0cdf469ull, 0xbcddda57058609cfull, 0xd8ae74e8f95b1ef1ull, 0x75764d60cfd2ac82ull, 0x79e1e7461d8178bdull, + 0x201bd093799b88e7ull, 0x7ec60d524372883full, 0x79d63de696496167ull, 0x8e449b589811c497ull, 0x52adf459f981f0b8ull, 0x596742f5dd8b43f3ull, 0x86a5fcd2631ae5deull, 0xd22446fc73434c7cull + }, + { // base nonce 1000000 + 0x95de23ae63046a5eull, 0x1d08d2a4b1cb3161ull, 0x6a940c9bef843fd0ull, 0xc5ce48f84aadb294ull, 0xba82215f36795b42ull, 0x8468642d1bf89decull, 0xe898eb1ae43e41a7ull, 0x4406325dcf229715ull, + 0x5bdef83a567bf872ull, 0x7148d685ed7aea55ull, 0xa1ade4af843a6cf6ull, 0xb557e23607845239ull, 0x3e8ed61763fc9602ull, 0x59088c92f20eae50ull, 0xd0ccb1c1189923c9ull, 0x6e43ec976d49b534ull, + 0xa895822ad9282927ull, 0x3eee289557cce518ull, 0x3004d873b41ef15bull, 0xbd029727b3853e96ull, 0x55c208f4320d0c37ull, 0x49fbcab22b92a4baull, 0xddc3fca332df8c3full, 0x288753718fd99e01ull, + 0x31d83163a6fe8b98ull, 0x85bf6f0b5397a63eull, 0x22beb8e9b3aff83dull, 0x9c52af026d8f81ecull, 0xcf4db829220c248dull, 0xf200f1e97bf4fe6cull, 0xf4475fbe74941055ull, 0xdb1af4be8ec353d4ull + } +}; + +// Dataset self-test: dataset[0..15] and dataset[IGNEUM_MASK] (268435455). +static const uint32_t IGNEUM_DS_HEAD[16] = { + 0xfdad4319u, 0x1a7b68e1u, 0xde6db608u, 0x13d73892u, 0xd17f447au, 0xb2221ccfu, 0x9db004bdu, 0x57d7d367u, + 0xdbc4cf34u, 0x697c009au, 0xc43af1d4u, 0x97f12b2eu, 0x74c37cd0u, 0xc651ea15u, 0x665a6d29u, 0x22330a2du +}; +static const uint32_t IGNEUM_DS_LAST_INDEX = 268435455u; +static const uint32_t IGNEUM_DS_LAST = 0xa83e7aa6u; +// 64 sampled dataset words (index, value) computed on the Mac. +#define IGNEUM_DS_SAMPLES 64 +static const uint32_t IGNEUM_DS_SAMPLE_INDEX[IGNEUM_DS_SAMPLES] = { + 59471966u, 217795994u, 208353206u, 42483309u, 172547758u, 148076330u, 183853158u, 214389424u, 267488061u, 169781097u, 184093494u, 153880993u, 84977930u, 46426879u, 3093825u, 225364072u, 44593546u, 260713159u, 168250303u, 52384140u, 223401610u, 45554030u, 95410555u, 175039924u, 79171087u, 267580473u, 24168642u, 37981670u, 171551130u, 195559979u, 204611762u, 140997658u, 138925853u, 86637313u, 20736778u, 219665210u, 160430336u, 264654675u, 8013395u, 228945585u, 213884386u, 104419827u, 44185464u, 142737231u, 99284897u, 132475900u, 61861762u, 132056166u, 262388043u, 91878046u, 117353561u, 124768597u, 71352993u, 190698941u, 46055428u, 55281366u, 165145231u, 106810753u, 171985651u, 232085256u, 159510492u, 40072060u, 209107596u, 39023794u +}; +static const uint32_t IGNEUM_DS_SAMPLE_VALUE[IGNEUM_DS_SAMPLES] = { + 0x3230bc7bu, 0x7fbfe2c9u, 0xb2690991u, 0x1745c7c5u, 0x0ab0ccafu, 0x1bf87d6bu, 0x160139fdu, 0x719817acu, 0x0155df4bu, 0xbe1e86c3u, 0x680bcd6cu, 0x79c3dc6cu, 0x181e7e5fu, 0x0713a109u, 0xc705dd9fu, 0x3933b7a8u, 0xdd1c0431u, 0x50522b30u, 0xa0020b38u, 0xbff39e96u, 0x21b67e18u, 0x740f8db3u, 0x2baba568u, 0x2c9bef83u, 0x0ad9b671u, 0xc4327869u, 0x7b4fd7d0u, 0x2c29965fu, 0xec56f15fu, 0x61111746u, 0x303a1d6eu, 0xbddcfd1au, 0xf829a355u, 0x6d5df2a9u, 0x01ab8e44u, 0x06d13507u, 0xda8dcfc6u, 0x01a703e1u, 0xafe7d2c1u, 0xc091c3a2u, 0xac1814feu, 0x6e6ff62au, 0x8fdf01bau, 0xdd3f7159u, 0xdfa0d75cu, 0x26684c35u, 0x7f441e63u, 0x88df2570u, 0x8aa4d5ebu, 0xcc816c05u, 0x434df890u, 0xcd392ad6u, 0x1ab4cb63u, 0x595926fau, 0x7cd76b41u, 0x20cb95c4u, 0x13cf823fu, 0xf9daf901u, 0xff9af40au, 0x2c7dfa51u, 0x871206dbu, 0x938c116cu, 0xb64bf199u, 0x5751f874u +}; +// Cache self-test (memory-hard mode): cache[0..15], the last 16 words, and FNV-1a 64 over all 2^26 words. +static const uint32_t IGNEUM_CACHE_HEAD[16] = { + 0x355a86d2u, 0x7957db1cu, 0xd21772afu, 0x6fc1e09bu, 0xd55ce61du, 0x6e6a278bu, 0xd3f543ceu, 0x223d8e82u, + 0x143ab337u, 0x2e9f05bdu, 0x2eb389bfu, 0x0c6e449eu, 0x5cfa4222u, 0xba6560feu, 0x8e3e1aa4u, 0xdbcc1d53u +}; +static const uint32_t IGNEUM_CACHE_LAST[16] = { + 0x41190d91u, 0xbd277957u, 0x22ddbb49u, 0x6986f207u, 0xdf69a4d6u, 0x26401a3au, 0x818230fbu, 0xc417122du, + 0x3597b211u, 0xb553ce55u, 0xcf39cc0du, 0x3b7fc43au, 0x3fd43b00u, 0x67e1c80eu, 0xffa7ea7du, 0xca2960abu +}; +static const uint64_t IGNEUM_CACHE_FNV64 = 0x48c4f5bf24166b2eull; diff --git a/proto-cuda/packs-ca4/mx8_shl256x27_v2/vectors.json b/proto-cuda/packs-ca4/mx8_shl256x27_v2/vectors.json new file mode 100644 index 000000000..1d714e8c9 --- /dev/null +++ b/proto-cuda/packs-ca4/mx8_shl256x27_v2/vectors.json @@ -0,0 +1,36 @@ +{ + "seed": "igneum-genesis", + "day": "2026-10-03", + "dataset_mode": "memory-hard", + "dataset_log2_words": 28, + "mask": "0x0fffffff", + "lanes": 32, + "source": "igneum-pow (Rust) CPU interpreter, generator v2, memory-hard dataset", + "warps": [ + {"base_nonce": 0, "expected": [ + "0xefd63997a0441711", "0x33de48f246942bbd", "0x75d11c0462d5d88e", "0x339027e7a81edd02", "0x44ea8055287924c8", "0x94695edae512b2fd", "0x10e849a40976a1f9", "0xe359cb57411223cd", + "0x9f87f6349d272c37", "0x9b014e403a50b9d8", "0x26fc7cf39d2abb3f", "0x46a8c54601339b19", "0x24358a4463be7912", "0x9114765e85734923", "0x6fe5559c34419006", "0x6e0084f9fb52a815", + "0xcb00c0ae818d85ad", "0x523ff275ef11bba8", "0x18919bc6daeeecc9", "0x049eb1764feed566", "0xb10204b89ad283fc", "0xb01bd8c897ec6eda", "0x37566026b58c0a06", "0x52dd03de72a2c1c1", + "0xfdb39e45434da769", "0x65aa545737c3d5a8", "0x1075f64ffd1240fb", "0x4c025b333a619365", "0x370d220ec4a57f28", "0x65279249eac9e65b", "0x733a248e4f1d06b0", "0xc8b37f453592452b" + ]}, + {"base_nonce": 4096, "expected": [ + "0x918005a6d3fbc63e", "0xb96b1dd6712afa86", "0xd76c1007676d61c2", "0x05390f3bd5062f59", "0x73aa6903da6f4356", "0xc494259068e25752", "0xf59c83f92e53c420", "0xd218528573a52ade", + "0x3978767d74c7d605", "0xeaab672b16d91b5a", "0x7c63cb2f17d0e460", "0x259ed48b2ecf354c", "0x39086dbce0897309", "0x77a4dd060aaaf1bc", "0xac407a7c7bea2ebc", "0xfd818079715aa327", + "0x7b9db28bfbac80d0", "0xecd209239058699e", "0x5ed5239644b890f6", "0x1671a35df0cdf469", "0xbcddda57058609cf", "0xd8ae74e8f95b1ef1", "0x75764d60cfd2ac82", "0x79e1e7461d8178bd", + "0x201bd093799b88e7", "0x7ec60d524372883f", "0x79d63de696496167", "0x8e449b589811c497", "0x52adf459f981f0b8", "0x596742f5dd8b43f3", "0x86a5fcd2631ae5de", "0xd22446fc73434c7c" + ]}, + {"base_nonce": 1000000, "expected": [ + "0x95de23ae63046a5e", "0x1d08d2a4b1cb3161", "0x6a940c9bef843fd0", "0xc5ce48f84aadb294", "0xba82215f36795b42", "0x8468642d1bf89dec", "0xe898eb1ae43e41a7", "0x4406325dcf229715", + "0x5bdef83a567bf872", "0x7148d685ed7aea55", "0xa1ade4af843a6cf6", "0xb557e23607845239", "0x3e8ed61763fc9602", "0x59088c92f20eae50", "0xd0ccb1c1189923c9", "0x6e43ec976d49b534", + "0xa895822ad9282927", "0x3eee289557cce518", "0x3004d873b41ef15b", "0xbd029727b3853e96", "0x55c208f4320d0c37", "0x49fbcab22b92a4ba", "0xddc3fca332df8c3f", "0x288753718fd99e01", + "0x31d83163a6fe8b98", "0x85bf6f0b5397a63e", "0x22beb8e9b3aff83d", "0x9c52af026d8f81ec", "0xcf4db829220c248d", "0xf200f1e97bf4fe6c", "0xf4475fbe74941055", "0xdb1af4be8ec353d4" + ]} + ], + "dataset_head": ["0xfdad4319", "0x1a7b68e1", "0xde6db608", "0x13d73892", "0xd17f447a", "0xb2221ccf", "0x9db004bd", "0x57d7d367", "0xdbc4cf34", "0x697c009a", "0xc43af1d4", "0x97f12b2e", "0x74c37cd0", "0xc651ea15", "0x665a6d29", "0x22330a2d"], + "dataset_last_index": 268435455, + "dataset_last": "0xa83e7aa6", + "dataset_samples": [{"index": 59471966, "value": "0x3230bc7b"}, {"index": 217795994, "value": "0x7fbfe2c9"}, {"index": 208353206, "value": "0xb2690991"}, {"index": 42483309, "value": "0x1745c7c5"}, {"index": 172547758, "value": "0x0ab0ccaf"}, {"index": 148076330, "value": "0x1bf87d6b"}, {"index": 183853158, "value": "0x160139fd"}, {"index": 214389424, "value": "0x719817ac"}, {"index": 267488061, "value": "0x0155df4b"}, {"index": 169781097, "value": "0xbe1e86c3"}, {"index": 184093494, "value": "0x680bcd6c"}, {"index": 153880993, "value": "0x79c3dc6c"}, {"index": 84977930, "value": "0x181e7e5f"}, {"index": 46426879, "value": "0x0713a109"}, {"index": 3093825, "value": "0xc705dd9f"}, {"index": 225364072, "value": "0x3933b7a8"}, {"index": 44593546, "value": "0xdd1c0431"}, {"index": 260713159, "value": "0x50522b30"}, {"index": 168250303, "value": "0xa0020b38"}, {"index": 52384140, "value": "0xbff39e96"}, {"index": 223401610, "value": "0x21b67e18"}, {"index": 45554030, "value": "0x740f8db3"}, {"index": 95410555, "value": "0x2baba568"}, {"index": 175039924, "value": "0x2c9bef83"}, {"index": 79171087, "value": "0x0ad9b671"}, {"index": 267580473, "value": "0xc4327869"}, {"index": 24168642, "value": "0x7b4fd7d0"}, {"index": 37981670, "value": "0x2c29965f"}, {"index": 171551130, "value": "0xec56f15f"}, {"index": 195559979, "value": "0x61111746"}, {"index": 204611762, "value": "0x303a1d6e"}, {"index": 140997658, "value": "0xbddcfd1a"}, {"index": 138925853, "value": "0xf829a355"}, {"index": 86637313, "value": "0x6d5df2a9"}, {"index": 20736778, "value": "0x01ab8e44"}, {"index": 219665210, "value": "0x06d13507"}, {"index": 160430336, "value": "0xda8dcfc6"}, {"index": 264654675, "value": "0x01a703e1"}, {"index": 8013395, "value": "0xafe7d2c1"}, {"index": 228945585, "value": "0xc091c3a2"}, {"index": 213884386, "value": "0xac1814fe"}, {"index": 104419827, "value": "0x6e6ff62a"}, {"index": 44185464, "value": "0x8fdf01ba"}, {"index": 142737231, "value": "0xdd3f7159"}, {"index": 99284897, "value": "0xdfa0d75c"}, {"index": 132475900, "value": "0x26684c35"}, {"index": 61861762, "value": "0x7f441e63"}, {"index": 132056166, "value": "0x88df2570"}, {"index": 262388043, "value": "0x8aa4d5eb"}, {"index": 91878046, "value": "0xcc816c05"}, {"index": 117353561, "value": "0x434df890"}, {"index": 124768597, "value": "0xcd392ad6"}, {"index": 71352993, "value": "0x1ab4cb63"}, {"index": 190698941, "value": "0x595926fa"}, {"index": 46055428, "value": "0x7cd76b41"}, {"index": 55281366, "value": "0x20cb95c4"}, {"index": 165145231, "value": "0x13cf823f"}, {"index": 106810753, "value": "0xf9daf901"}, {"index": 171985651, "value": "0xff9af40a"}, {"index": 232085256, "value": "0x2c7dfa51"}, {"index": 159510492, "value": "0x871206db"}, {"index": 40072060, "value": "0x938c116c"}, {"index": 209107596, "value": "0xb64bf199"}, {"index": 39023794, "value": "0x5751f874"}], + "cache_head": ["0x355a86d2", "0x7957db1c", "0xd21772af", "0x6fc1e09b", "0xd55ce61d", "0x6e6a278b", "0xd3f543ce", "0x223d8e82", "0x143ab337", "0x2e9f05bd", "0x2eb389bf", "0x0c6e449e", "0x5cfa4222", "0xba6560fe", "0x8e3e1aa4", "0xdbcc1d53"], + "cache_last_line": ["0x41190d91", "0xbd277957", "0x22ddbb49", "0x6986f207", "0xdf69a4d6", "0x26401a3a", "0x818230fb", "0xc417122d", "0x3597b211", "0xb553ce55", "0xcf39cc0d", "0x3b7fc43a", "0x3fd43b00", "0x67e1c80e", "0xffa7ea7d", "0xca2960ab"], + "cache_fnv1a64": "0x48c4f5bf24166b2e" +}