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 <noreply@anthropic.com>
This commit is contained in:
igneum-labs 2026-10-07 22:29:50 +00:00
parent afea95ccdf
commit 7aa0e563c3
12 changed files with 4058 additions and 0 deletions

View file

@ -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

View file

@ -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 <cuda_runtime.h>
#include <cstdint>
#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<<<grid, block>>>(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<<<grid, block>>>(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<<<nonces / block, block>>>(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);
}

View file

@ -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;
}

View file

@ -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 <cuda_runtime.h>
#include <cstdint>
#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<<<nonces / block, block>>>(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);
}

View file

@ -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 <cstdint>
#else
#include <stdint.h>
#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]; }

View file

@ -0,0 +1,107 @@
#include <metal_stdlib>
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];
}

View file

@ -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 <cstdint>
#else
#include <stdint.h>
#endif
#ifndef IGNEUM_NO_CUDA
#include <cuda_runtime.h>
#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

View file

@ -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}
]
}

View file

@ -0,0 +1,413 @@
#include <metal_stdlib>
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;
}

View file

@ -0,0 +1,415 @@
#include <metal_stdlib>
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;
}

View file

@ -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 <cstdint>
#else
#include <stdint.h>
#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;

View file

@ -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"
}