From 51dba1ce7633369064fcf0b29f9778492ed46643 Mon Sep 17 00:00:00 2001 From: igneum-labs <337424239+igneum-labs@users.noreply.github.com> Date: Tue, 6 Oct 2026 07:58:35 +0000 Subject: [PATCH 1/2] Counter ASIC 3.0 item 8: the latency-shadow knob (LoadClass +shx), its packs and the PC 2 playbook A shadow block of S ALU instructions run R times at the end of every iteration, drawn from the program stream after the 64 base instructions, behind LoadClass::shadow: v2 and v3 draw nothing and emit nothing (the pinned packs are byte-identical, cargo test 54 + 4 + 19 + 7 green). The interpreter, the three kernel dialects (both kernels each), program.h and program.json carry it; the acceptance rule interprets the base program only. Packs for seed igneum-genesis over class mx8 at 4,096 to 180,224 shadow instructions per hash (proto-cuda/packs-ca3-shadow), and the PC 2 bench playbook tools/ca3-shadow/pc2-shadow-bench.ps1 (passes the publisher's three checks). Co-Authored-By: Claude Fable 5.1 --- igneum-census/src/main.rs | 2 +- igneum-pow/src/emit.rs | 100 + igneum-pow/src/generator.rs | 165 +- igneum-pow/src/main.rs | 11 +- igneum-pow/src/verify.rs | 7 + igneum-pow/tests/scratch.rs | 1 + .../packs-ca3-shadow/sh1024x3/kernel.cl | 1306 +++++++++ .../packs-ca3-shadow/sh1024x3/kernel.cu | 1191 ++++++++ .../packs-ca3-shadow/sh1024x3/kernel_bound.cl | 2427 +++++++++++++++++ .../packs-ca3-shadow/sh1024x3/kernel_bound.cu | 1150 ++++++++ .../packs-ca3-shadow/sh1024x3/memhard.h | 109 + .../packs-ca3-shadow/sh1024x3/memhard.metal | 107 + .../packs-ca3-shadow/sh1024x3/program.h | 70 + .../packs-ca3-shadow/sh1024x3/program.json | 1157 ++++++++ .../packs-ca3-shadow/sh1024x3/program.metal | 1136 ++++++++ .../sh1024x3/program_bound.metal | 1138 ++++++++ .../packs-ca3-shadow/sh1024x3/vectors.h | 57 + .../packs-ca3-shadow/sh1024x3/vectors.json | 36 + .../packs-ca3-shadow/sh256x13/kernel.cl | 538 ++++ .../packs-ca3-shadow/sh256x13/kernel.cu | 423 +++ .../packs-ca3-shadow/sh256x13/kernel_bound.cl | 891 ++++++ .../packs-ca3-shadow/sh256x13/kernel_bound.cu | 382 +++ .../packs-ca3-shadow/sh256x13/memhard.h | 109 + .../packs-ca3-shadow/sh256x13/memhard.metal | 107 + .../packs-ca3-shadow/sh256x13/program.h | 70 + .../packs-ca3-shadow/sh256x13/program.json | 389 +++ .../packs-ca3-shadow/sh256x13/program.metal | 368 +++ .../sh256x13/program_bound.metal | 370 +++ .../packs-ca3-shadow/sh256x13/vectors.h | 57 + .../packs-ca3-shadow/sh256x13/vectors.json | 36 + proto-cuda/packs-ca3-shadow/sh256x2/kernel.cl | 538 ++++ proto-cuda/packs-ca3-shadow/sh256x2/kernel.cu | 423 +++ .../packs-ca3-shadow/sh256x2/kernel_bound.cl | 891 ++++++ .../packs-ca3-shadow/sh256x2/kernel_bound.cu | 382 +++ proto-cuda/packs-ca3-shadow/sh256x2/memhard.h | 109 + .../packs-ca3-shadow/sh256x2/memhard.metal | 107 + proto-cuda/packs-ca3-shadow/sh256x2/program.h | 70 + .../packs-ca3-shadow/sh256x2/program.json | 389 +++ .../packs-ca3-shadow/sh256x2/program.metal | 368 +++ .../sh256x2/program_bound.metal | 370 +++ proto-cuda/packs-ca3-shadow/sh256x2/vectors.h | 57 + .../packs-ca3-shadow/sh256x2/vectors.json | 36 + .../packs-ca3-shadow/sh256x27/kernel.cl | 538 ++++ .../packs-ca3-shadow/sh256x27/kernel.cu | 423 +++ .../packs-ca3-shadow/sh256x27/kernel_bound.cl | 891 ++++++ .../packs-ca3-shadow/sh256x27/kernel_bound.cu | 382 +++ .../packs-ca3-shadow/sh256x27/memhard.h | 109 + .../packs-ca3-shadow/sh256x27/memhard.metal | 107 + .../packs-ca3-shadow/sh256x27/program.h | 70 + .../packs-ca3-shadow/sh256x27/program.json | 389 +++ .../packs-ca3-shadow/sh256x27/program.metal | 368 +++ .../sh256x27/program_bound.metal | 370 +++ .../packs-ca3-shadow/sh256x27/vectors.h | 57 + .../packs-ca3-shadow/sh256x27/vectors.json | 36 + .../packs-ca3-shadow/sh256x40/kernel.cl | 538 ++++ .../packs-ca3-shadow/sh256x40/kernel.cu | 423 +++ .../packs-ca3-shadow/sh256x40/kernel_bound.cl | 891 ++++++ .../packs-ca3-shadow/sh256x40/kernel_bound.cu | 382 +++ .../packs-ca3-shadow/sh256x40/memhard.h | 109 + .../packs-ca3-shadow/sh256x40/memhard.metal | 107 + .../packs-ca3-shadow/sh256x40/program.h | 70 + .../packs-ca3-shadow/sh256x40/program.json | 389 +++ .../packs-ca3-shadow/sh256x40/program.metal | 368 +++ .../sh256x40/program_bound.metal | 370 +++ .../packs-ca3-shadow/sh256x40/vectors.h | 57 + .../packs-ca3-shadow/sh256x40/vectors.json | 36 + .../packs-ca3-shadow/sh256x53/kernel.cl | 538 ++++ .../packs-ca3-shadow/sh256x53/kernel.cu | 423 +++ .../packs-ca3-shadow/sh256x53/kernel_bound.cl | 891 ++++++ .../packs-ca3-shadow/sh256x53/kernel_bound.cu | 382 +++ .../packs-ca3-shadow/sh256x53/memhard.h | 109 + .../packs-ca3-shadow/sh256x53/memhard.metal | 107 + .../packs-ca3-shadow/sh256x53/program.h | 70 + .../packs-ca3-shadow/sh256x53/program.json | 389 +++ .../packs-ca3-shadow/sh256x53/program.metal | 368 +++ .../sh256x53/program_bound.metal | 370 +++ .../packs-ca3-shadow/sh256x53/vectors.h | 57 + .../packs-ca3-shadow/sh256x53/vectors.json | 36 + proto-cuda/packs-ca3-shadow/sh256x7/kernel.cl | 538 ++++ proto-cuda/packs-ca3-shadow/sh256x7/kernel.cu | 423 +++ .../packs-ca3-shadow/sh256x7/kernel_bound.cl | 891 ++++++ .../packs-ca3-shadow/sh256x7/kernel_bound.cu | 382 +++ proto-cuda/packs-ca3-shadow/sh256x7/memhard.h | 109 + .../packs-ca3-shadow/sh256x7/memhard.metal | 107 + proto-cuda/packs-ca3-shadow/sh256x7/program.h | 70 + .../packs-ca3-shadow/sh256x7/program.json | 389 +++ .../packs-ca3-shadow/sh256x7/program.metal | 368 +++ .../sh256x7/program_bound.metal | 370 +++ proto-cuda/packs-ca3-shadow/sh256x7/vectors.h | 57 + .../packs-ca3-shadow/sh256x7/vectors.json | 36 + .../packs-ca3-shadow/sh256x88/kernel.cl | 538 ++++ .../packs-ca3-shadow/sh256x88/kernel.cu | 423 +++ .../packs-ca3-shadow/sh256x88/kernel_bound.cl | 891 ++++++ .../packs-ca3-shadow/sh256x88/kernel_bound.cu | 382 +++ .../packs-ca3-shadow/sh256x88/memhard.h | 109 + .../packs-ca3-shadow/sh256x88/memhard.metal | 107 + .../packs-ca3-shadow/sh256x88/program.h | 70 + .../packs-ca3-shadow/sh256x88/program.json | 389 +++ .../packs-ca3-shadow/sh256x88/program.metal | 368 +++ .../sh256x88/program_bound.metal | 370 +++ .../packs-ca3-shadow/sh256x88/vectors.h | 57 + .../packs-ca3-shadow/sh256x88/vectors.json | 36 + proto-cuda/packs-ca3-shadow/sh64x52/kernel.cl | 346 +++ proto-cuda/packs-ca3-shadow/sh64x52/kernel.cu | 231 ++ .../packs-ca3-shadow/sh64x52/kernel_bound.cl | 507 ++++ .../packs-ca3-shadow/sh64x52/kernel_bound.cu | 190 ++ proto-cuda/packs-ca3-shadow/sh64x52/memhard.h | 109 + .../packs-ca3-shadow/sh64x52/memhard.metal | 107 + proto-cuda/packs-ca3-shadow/sh64x52/program.h | 70 + .../packs-ca3-shadow/sh64x52/program.json | 197 ++ .../packs-ca3-shadow/sh64x52/program.metal | 176 ++ .../sh64x52/program_bound.metal | 178 ++ proto-cuda/packs-ca3-shadow/sh64x52/vectors.h | 57 + .../packs-ca3-shadow/sh64x52/vectors.json | 36 + tools/ca3-shadow/pc2-shadow-bench.ps1 | 97 + 115 files changed, 38647 insertions(+), 4 deletions(-) create mode 100644 proto-cuda/packs-ca3-shadow/sh1024x3/kernel.cl create mode 100644 proto-cuda/packs-ca3-shadow/sh1024x3/kernel.cu create mode 100644 proto-cuda/packs-ca3-shadow/sh1024x3/kernel_bound.cl create mode 100644 proto-cuda/packs-ca3-shadow/sh1024x3/kernel_bound.cu create mode 100644 proto-cuda/packs-ca3-shadow/sh1024x3/memhard.h create mode 100644 proto-cuda/packs-ca3-shadow/sh1024x3/memhard.metal create mode 100644 proto-cuda/packs-ca3-shadow/sh1024x3/program.h create mode 100644 proto-cuda/packs-ca3-shadow/sh1024x3/program.json create mode 100644 proto-cuda/packs-ca3-shadow/sh1024x3/program.metal create mode 100644 proto-cuda/packs-ca3-shadow/sh1024x3/program_bound.metal create mode 100644 proto-cuda/packs-ca3-shadow/sh1024x3/vectors.h create mode 100644 proto-cuda/packs-ca3-shadow/sh1024x3/vectors.json create mode 100644 proto-cuda/packs-ca3-shadow/sh256x13/kernel.cl create mode 100644 proto-cuda/packs-ca3-shadow/sh256x13/kernel.cu create mode 100644 proto-cuda/packs-ca3-shadow/sh256x13/kernel_bound.cl create mode 100644 proto-cuda/packs-ca3-shadow/sh256x13/kernel_bound.cu create mode 100644 proto-cuda/packs-ca3-shadow/sh256x13/memhard.h create mode 100644 proto-cuda/packs-ca3-shadow/sh256x13/memhard.metal create mode 100644 proto-cuda/packs-ca3-shadow/sh256x13/program.h create mode 100644 proto-cuda/packs-ca3-shadow/sh256x13/program.json create mode 100644 proto-cuda/packs-ca3-shadow/sh256x13/program.metal create mode 100644 proto-cuda/packs-ca3-shadow/sh256x13/program_bound.metal create mode 100644 proto-cuda/packs-ca3-shadow/sh256x13/vectors.h create mode 100644 proto-cuda/packs-ca3-shadow/sh256x13/vectors.json create mode 100644 proto-cuda/packs-ca3-shadow/sh256x2/kernel.cl create mode 100644 proto-cuda/packs-ca3-shadow/sh256x2/kernel.cu create mode 100644 proto-cuda/packs-ca3-shadow/sh256x2/kernel_bound.cl create mode 100644 proto-cuda/packs-ca3-shadow/sh256x2/kernel_bound.cu create mode 100644 proto-cuda/packs-ca3-shadow/sh256x2/memhard.h create mode 100644 proto-cuda/packs-ca3-shadow/sh256x2/memhard.metal create mode 100644 proto-cuda/packs-ca3-shadow/sh256x2/program.h create mode 100644 proto-cuda/packs-ca3-shadow/sh256x2/program.json create mode 100644 proto-cuda/packs-ca3-shadow/sh256x2/program.metal create mode 100644 proto-cuda/packs-ca3-shadow/sh256x2/program_bound.metal create mode 100644 proto-cuda/packs-ca3-shadow/sh256x2/vectors.h create mode 100644 proto-cuda/packs-ca3-shadow/sh256x2/vectors.json create mode 100644 proto-cuda/packs-ca3-shadow/sh256x27/kernel.cl create mode 100644 proto-cuda/packs-ca3-shadow/sh256x27/kernel.cu create mode 100644 proto-cuda/packs-ca3-shadow/sh256x27/kernel_bound.cl create mode 100644 proto-cuda/packs-ca3-shadow/sh256x27/kernel_bound.cu create mode 100644 proto-cuda/packs-ca3-shadow/sh256x27/memhard.h create mode 100644 proto-cuda/packs-ca3-shadow/sh256x27/memhard.metal create mode 100644 proto-cuda/packs-ca3-shadow/sh256x27/program.h create mode 100644 proto-cuda/packs-ca3-shadow/sh256x27/program.json create mode 100644 proto-cuda/packs-ca3-shadow/sh256x27/program.metal create mode 100644 proto-cuda/packs-ca3-shadow/sh256x27/program_bound.metal create mode 100644 proto-cuda/packs-ca3-shadow/sh256x27/vectors.h create mode 100644 proto-cuda/packs-ca3-shadow/sh256x27/vectors.json create mode 100644 proto-cuda/packs-ca3-shadow/sh256x40/kernel.cl create mode 100644 proto-cuda/packs-ca3-shadow/sh256x40/kernel.cu create mode 100644 proto-cuda/packs-ca3-shadow/sh256x40/kernel_bound.cl create mode 100644 proto-cuda/packs-ca3-shadow/sh256x40/kernel_bound.cu create mode 100644 proto-cuda/packs-ca3-shadow/sh256x40/memhard.h create mode 100644 proto-cuda/packs-ca3-shadow/sh256x40/memhard.metal create mode 100644 proto-cuda/packs-ca3-shadow/sh256x40/program.h create mode 100644 proto-cuda/packs-ca3-shadow/sh256x40/program.json create mode 100644 proto-cuda/packs-ca3-shadow/sh256x40/program.metal create mode 100644 proto-cuda/packs-ca3-shadow/sh256x40/program_bound.metal create mode 100644 proto-cuda/packs-ca3-shadow/sh256x40/vectors.h create mode 100644 proto-cuda/packs-ca3-shadow/sh256x40/vectors.json create mode 100644 proto-cuda/packs-ca3-shadow/sh256x53/kernel.cl create mode 100644 proto-cuda/packs-ca3-shadow/sh256x53/kernel.cu create mode 100644 proto-cuda/packs-ca3-shadow/sh256x53/kernel_bound.cl create mode 100644 proto-cuda/packs-ca3-shadow/sh256x53/kernel_bound.cu create mode 100644 proto-cuda/packs-ca3-shadow/sh256x53/memhard.h create mode 100644 proto-cuda/packs-ca3-shadow/sh256x53/memhard.metal create mode 100644 proto-cuda/packs-ca3-shadow/sh256x53/program.h create mode 100644 proto-cuda/packs-ca3-shadow/sh256x53/program.json create mode 100644 proto-cuda/packs-ca3-shadow/sh256x53/program.metal create mode 100644 proto-cuda/packs-ca3-shadow/sh256x53/program_bound.metal create mode 100644 proto-cuda/packs-ca3-shadow/sh256x53/vectors.h create mode 100644 proto-cuda/packs-ca3-shadow/sh256x53/vectors.json create mode 100644 proto-cuda/packs-ca3-shadow/sh256x7/kernel.cl create mode 100644 proto-cuda/packs-ca3-shadow/sh256x7/kernel.cu create mode 100644 proto-cuda/packs-ca3-shadow/sh256x7/kernel_bound.cl create mode 100644 proto-cuda/packs-ca3-shadow/sh256x7/kernel_bound.cu create mode 100644 proto-cuda/packs-ca3-shadow/sh256x7/memhard.h create mode 100644 proto-cuda/packs-ca3-shadow/sh256x7/memhard.metal create mode 100644 proto-cuda/packs-ca3-shadow/sh256x7/program.h create mode 100644 proto-cuda/packs-ca3-shadow/sh256x7/program.json create mode 100644 proto-cuda/packs-ca3-shadow/sh256x7/program.metal create mode 100644 proto-cuda/packs-ca3-shadow/sh256x7/program_bound.metal create mode 100644 proto-cuda/packs-ca3-shadow/sh256x7/vectors.h create mode 100644 proto-cuda/packs-ca3-shadow/sh256x7/vectors.json create mode 100644 proto-cuda/packs-ca3-shadow/sh256x88/kernel.cl create mode 100644 proto-cuda/packs-ca3-shadow/sh256x88/kernel.cu create mode 100644 proto-cuda/packs-ca3-shadow/sh256x88/kernel_bound.cl create mode 100644 proto-cuda/packs-ca3-shadow/sh256x88/kernel_bound.cu create mode 100644 proto-cuda/packs-ca3-shadow/sh256x88/memhard.h create mode 100644 proto-cuda/packs-ca3-shadow/sh256x88/memhard.metal create mode 100644 proto-cuda/packs-ca3-shadow/sh256x88/program.h create mode 100644 proto-cuda/packs-ca3-shadow/sh256x88/program.json create mode 100644 proto-cuda/packs-ca3-shadow/sh256x88/program.metal create mode 100644 proto-cuda/packs-ca3-shadow/sh256x88/program_bound.metal create mode 100644 proto-cuda/packs-ca3-shadow/sh256x88/vectors.h create mode 100644 proto-cuda/packs-ca3-shadow/sh256x88/vectors.json create mode 100644 proto-cuda/packs-ca3-shadow/sh64x52/kernel.cl create mode 100644 proto-cuda/packs-ca3-shadow/sh64x52/kernel.cu create mode 100644 proto-cuda/packs-ca3-shadow/sh64x52/kernel_bound.cl create mode 100644 proto-cuda/packs-ca3-shadow/sh64x52/kernel_bound.cu create mode 100644 proto-cuda/packs-ca3-shadow/sh64x52/memhard.h create mode 100644 proto-cuda/packs-ca3-shadow/sh64x52/memhard.metal create mode 100644 proto-cuda/packs-ca3-shadow/sh64x52/program.h create mode 100644 proto-cuda/packs-ca3-shadow/sh64x52/program.json create mode 100644 proto-cuda/packs-ca3-shadow/sh64x52/program.metal create mode 100644 proto-cuda/packs-ca3-shadow/sh64x52/program_bound.metal create mode 100644 proto-cuda/packs-ca3-shadow/sh64x52/vectors.h create mode 100644 proto-cuda/packs-ca3-shadow/sh64x52/vectors.json create mode 100644 tools/ca3-shadow/pc2-shadow-bench.ps1 diff --git a/igneum-census/src/main.rs b/igneum-census/src/main.rs index bd7955ef5..171c43009 100644 --- a/igneum-census/src/main.rs +++ b/igneum-census/src/main.rs @@ -183,7 +183,7 @@ fn generate_fixed16(seed_string: &str, seed: [u32; 8], fresh: Fresh) -> Program fresh_reg[dst as usize] = true; instrs.push(Instr { op, dst: dst as u8, src: src as u8, src2: b as u8, imm, imm2, rot, bit: bit as u8, mask, width: 1, win: 0, off: 0 }); } - Program { seed_string: seed_string.to_string(), seed_bytes: seed_string.as_bytes().to_vec(), seed, generator: GENERATOR_VERSION, attempt: 0, class: LoadClass::V2, era_bytes: None, instrs } + Program { seed_string: seed_string.to_string(), seed_bytes: seed_string.as_bytes().to_vec(), seed, generator: GENERATOR_VERSION, attempt: 0, class: LoadClass::V2, era_bytes: None, instrs, shadow: Vec::new() } } // --------------------------------------------------------------------------------------------------------- diff --git a/igneum-pow/src/emit.rs b/igneum-pow/src/emit.rs index 7cb1ceed1..aa36e3fc8 100644 --- a/igneum-pow/src/emit.rs +++ b/igneum-pow/src/emit.rs @@ -308,6 +308,74 @@ fn scratch_header_lines(p: &Program) -> String { /// Hot-table experiment (`docs/plans/hot-table.md`): the `HOT_WORDS` literal of a hot pack's hash kernels (empty /// for every other class, so the pinned packs do not change). +/// One ALU instruction of the latency-shadow block as a statement of the dialect (the same text the program's own +/// instruction lines use for that op; the block holds no load, scratch, hot or wide op). +fn shadow_instr_line(dialect: CoreDialect, ins: &Instr) -> String { + let d = format!("r{}", ins.dst); + let a = format!("r{}", ins.src); + let b = format!("r{}", ins.src2); + match ins.op { + Op::Add => match dialect { + CoreDialect::Metal => format!("{d} = {d} + {a} + select({}, {}, ((sel >> {}u) & 1u) != 0u);", hex(ins.imm), hex(ins.imm2), ins.bit), + _ => format!("{d} = {d} + {a} + ((((sel >> {}u) & 1u) != 0u) ? {} : {});", ins.bit, hex(ins.imm2), hex(ins.imm)), + }, + Op::Sub => format!("{d} = {d} - {a};"), + Op::Mul => format!("{d} = {d} * {a};"), + Op::MulHi => match dialect { + CoreDialect::Metal => format!("{d} = mulhi({d}, {a});"), + CoreDialect::Cuda => format!("{d} = __umulhi({d}, {a});"), + CoreDialect::OpenCl => format!("{d} = mul_hi({d}, {a});"), + }, + Op::Xor => format!("{d} = {d} ^ {a};"), + Op::Or => format!("{d} = {d} | {a};"), + Op::Rotl => format!("{d} = rotl_imm({d}, {}u);", ins.rot), + Op::Rotr => format!("{d} = rotr_var({d}, {a});"), + Op::Mad => format!("{d} = {a} * {b} + {d};"), + Op::Shfl => match dialect { + CoreDialect::Metal => format!("{d} = {d} ^ simd_shuffle_xor({a}, (ushort){});", ins.mask), + CoreDialect::Cuda => format!("{d} = {d} ^ __shfl_xor_sync(0xffffffffu, {a}, {});", ins.mask), + CoreDialect::OpenCl => format!("{{ uint t_; IGNEUM_SHFL_XOR(t_, {a}, {}u); {d} = {d} ^ t_; }}", ins.mask), + }, + Op::Load | Op::WLoad | Op::Scratch | Op::Hot => unreachable!("the shadow block holds ALU instructions only"), + } +} + +/// The latency-shadow block (Counter ASIC 3.0 item 8, `docs/analysis/latency-shadow-2026-10-06.md`) inside the +/// iteration loop, after the program's last instruction: `reps` passes over the block with the iteration's `sel`. +/// Empty for every program without a shadow, so the pinned v2 and v3 packs do not change by a byte. +fn shadow_block(p: &Program, dialect: CoreDialect) -> String { + if !p.has_shadow() { + return String::new(); + } + let reps = p.shadow_reps(); + let mut s = String::with_capacity(64 * p.shadow.len() + 200); + s.push_str(&format!( + " // latency-shadow block (Counter ASIC 3.0 item 8): {} ALU instructions x {reps} passes after instruction 63, no load\n", + p.shadow.len() + )); + let ty = if dialect == CoreDialect::Cuda { "uint32_t" } else { "uint" }; + s.push_str(&format!(" for ({ty} sh = 0u; sh < {reps}u; ++sh) {{\n")); + for (k, ins) in p.shadow.iter().enumerate() { + s.push_str(&format!(" {} // s{k} {}\n", shadow_instr_line(dialect, ins), ins.op.name())); + } + s.push_str(" }\n"); + s +} + +/// The shadow lines of program.h (empty without a shadow). +fn shadow_header_lines(p: &Program) -> String { + let Some(sh) = p.class.shadow else { return String::new() }; + let mut s = String::new(); + s.push_str("// Latency-shadow block (Counter ASIC 3.0 item 8, docs/analysis/latency-shadow-2026-10-06.md): NOT the lottery hash. A block of\n"); + s.push_str("// IGNEUM_SHADOW_INSTRS ALU instructions (the ten non-load families) runs IGNEUM_SHADOW_REPS times at the end of every\n"); + s.push_str("// iteration; the 16 loads, the acceptance rule and the base program are the class's without the shadow.\n"); + s.push_str(&format!("#define IGNEUM_SHADOW_INSTRS {}\n", sh.instrs)); + s.push_str(&format!("#define IGNEUM_SHADOW_REPS {}\n", sh.reps)); + s.push_str(&format!("#define IGNEUM_SHADOW_INSTRS_PER_HASH {}\n", p.shadow_instrs_per_hash())); + s.push_str(&format!("#define IGNEUM_SHADOW_OP_MIX {}\n", jstr(&p.shadow_op_mix()))); + s +} + fn hot_define(p: &Program) -> String { match p.class.hot { Some(h) => format!("// Hot table ({} MiB, {} of the 16 load slots): dst ^= hot[mulhi(src, HOT_WORDS)], docs/plans/hot-table.md. @@ -799,6 +867,7 @@ fn metal_program_impl(p: &Program, dataset_log2: u32, source: LoadSource, bound: }; s.push_str(&format!(" {line} // {k}\n")); } + s.push_str(&shadow_block(p, CoreDialect::Metal)); s.push_str(" }\n"); s.push_str(" uint lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u);\n"); s.push_str(" uint hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u);\n"); @@ -968,6 +1037,7 @@ pub fn cuda_kernel_at(p: &Program, memhard: Option<&MixParams>, dataset_log2: u3 } s.push_str(&format!("\n for (uint32_t it = 0u; it < {ITERATIONS}u; ++it) {{\n uint32_t sel = r0;\n")); s.push_str(&cuda_instr_lines(p, dataset_log2)); + s.push_str(&shadow_block(p, CoreDialect::Cuda)); s.push_str(" }\n"); s.push_str(" uint32_t lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u);\n"); s.push_str(" uint32_t hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u);\n"); @@ -1111,6 +1181,7 @@ pub fn cuda_kernel_bound_at(p: &Program, memhard: Option<&MixParams>, dataset_lo } s.push_str(&format!("\n for (uint32_t it = 0u; it < {ITERATIONS}u; ++it) {{\n uint32_t sel = r0;\n")); s.push_str(&cuda_instr_lines(p, dataset_log2)); + s.push_str(&shadow_block(p, CoreDialect::Cuda)); s.push_str(" }\n"); s.push_str(" uint32_t lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u);\n"); s.push_str(" uint32_t hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u);\n"); @@ -1250,6 +1321,7 @@ pub fn opencl_kernel_bound_at(p: &Program, memhard: Option<&MixParams>, dataset_ } s.push_str(&format!("\n for (uint it = 0u; it < {ITERATIONS}u; ++it) {{\n uint sel = r0;\n")); s.push_str(&opencl_instr_lines(p, dataset_log2)); + s.push_str(&shadow_block(p, CoreDialect::OpenCl)); s.push_str(" }\n"); s.push_str(" uint lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u);\n"); s.push_str(" uint hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u);\n"); @@ -1407,6 +1479,7 @@ pub fn opencl_kernel_at(p: &Program, memhard: Option<&MixParams>, dataset_log2: } s.push_str(&format!("\n for (uint it = 0u; it < {ITERATIONS}u; ++it) {{\n uint sel = r0;\n")); s.push_str(&opencl_instr_lines(p, dataset_log2)); + s.push_str(&shadow_block(p, CoreDialect::OpenCl)); s.push_str(" }\n"); s.push_str(" uint lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u);\n"); s.push_str(" uint hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u);\n"); @@ -1473,6 +1546,7 @@ pub fn program_header(p: &Program, day: &str, ds: &DatasetSource) -> String { s.push_str(&scratch_header_lines(p)); s.push_str(&era_header_lines(p)); s.push_str(&hot_header_lines(p)); + s.push_str(&shadow_header_lines(p)); s.push_str("// 0 = closed-form dataset (ds_elem), 1 = memory-hard cache construction (MEMHARD.md, memhard.h)\n"); s.push_str(&format!("#define IGNEUM_DATASET_MODE {}\n", if memhard.is_some() { 1 } else { 0 })); s.push('\n'); @@ -1824,6 +1898,32 @@ pub fn program_json(p: &Program, day: &str, ds: &DatasetSource) -> String { s.push_str(" \"formula\": \"x = i ^ d0; x *= 0x9E3779B1; x ^= x>>15; x += d1; x *= 0x85EBCA77; x ^= x>>13; x *= 0xC2B2AE3D; x ^= x>>16 (all mod 2^32)\"\n"); } s.push_str(" },\n"); + if let Some(sh) = p.class.shadow { + s.push_str(&format!( + " \"shadow\": {{\"instrs\": {}, \"reps\": {}, \"instrs_per_hash\": {}, \"op_mix\": {{{}}}, \"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\": [\n", + sh.instrs, + sh.reps, + p.shadow_instrs_per_hash(), + p.shadow_histogram().iter().map(|(n, c)| format!("{}: {c}", jstr(n))).collect::>().join(", ") + )); + let n = p.shadow.len(); + for (k, ins) in p.shadow.iter().enumerate() { + s.push_str(&format!( + " {{\"i\": {k}, \"op\": {}, \"dst\": {}, \"src\": {}, \"src2\": {}, \"imm\": {}, \"imm2\": {}, \"rot\": {}, \"bit\": {}, \"mask\": {}}}{}\n", + jstr(ins.op.name()), + ins.dst, + ins.src, + ins.src2, + jhex(ins.imm), + jhex(ins.imm2), + ins.rot, + ins.bit, + ins.mask, + if k + 1 < n { "," } else { "" } + )); + } + s.push_str(" ]},\n"); + } s.push_str(" \"instructions\": [\n"); let n = p.instrs.len(); for (k, ins) in p.instrs.iter().enumerate() { diff --git a/igneum-pow/src/generator.rs b/igneum-pow/src/generator.rs index 5201d950b..1842211bd 100644 --- a/igneum-pow/src/generator.rs +++ b/igneum-pow/src/generator.rs @@ -186,6 +186,9 @@ pub struct Program { /// not read it; the era draw of the integration branch will. pub era_bytes: Option>, pub instrs: Vec, + /// The latency-shadow block (Counter ASIC 3.0 item 8): `class.shadow.instrs` ALU instructions, run + /// `class.shadow.reps` times at the end of every iteration. Empty for every class without a shadow. + pub shadow: Vec, } /// The widths a `load` may read, in words: 4, 16 and 64 bytes. @@ -216,6 +219,9 @@ pub struct LoadClass { /// Hot table (`docs/plans/hot-table.md`, measured 5 October 2026 and not adopted): `Some(HotClass { mb, k, added })` /// turns `k` load slots into reads of an `mb` MiB epoch table. `None` for every other class, class v3 included. pub hot: Option, + /// Latency-shadow program work (Counter ASIC 3.0 item 8, measured 6 October 2026 and not adopted): `Some` adds a + /// block of ALU instructions run `reps` times per iteration. `None` for every other class, class v3 included. + pub shadow: Option, } /// The parameters one era draws from its seed `E_n` (`docs/plans/era-layout.md` section 1.1, the proposed text of @@ -342,6 +348,29 @@ pub struct HotClass { pub added: bool, } +/// Program work in the latency shadow (Counter ASIC 3.0 item 8, 6 October 2026, `docs/analysis/latency-shadow-2026-10-06.md`; +/// NOT the lottery hash, a class v4 candidate's knob): a shadow block of `instrs` ALU instructions (the ten non-load +/// families at the weights of [`NONLOAD_WEIGHTS`], the same nine draws per instruction as the program's, drawn from the +/// program stream AFTER the 64 base instructions, so the base program, its attempt and its acceptance verdict are those +/// of the class without the shadow, draw for draw) executed `reps` times at the end of every iteration, after instruction +/// 63 and before the next iteration samples `sel`. The 16 loads per program, the fresh-source rule and the acceptance +/// rule (which interprets the base program only) are untouched; the shadow adds `8 x instrs x reps` ALU instructions per +/// hash and no load. `None` on every other class: version 2 and class v3 draw nothing and emit nothing. +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub struct ShadowClass { + /// Instructions in the shadow block (1..=4096). + pub instrs: u16, + /// Times the block runs per iteration (1..=1024). + pub reps: u16, +} + +impl ShadowClass { + /// Shadow instructions per hash: `ITERATIONS x instrs x reps`. + pub fn instrs_per_hash(&self) -> usize { + ITERATIONS * self.instrs as usize * self.reps as usize + } +} + /// Scratch geometry (variant 5): 16-byte slots, lane-major, 32 lanes per warp; `scratch_kb` KiB per warp gives /// `scratch_kb x 2` slots per lane (32 KiB: 64 slots, 128 KiB: 256 slots). pub const SCRATCH_SLOT_BYTES: usize = 16; @@ -365,13 +394,13 @@ impl LoadClass { impl LoadClass { /// Generator version 2 as adopted on 4 October 2026: 16 loads of one word. The lottery hash. pub const V2: LoadClass = - LoadClass { mix: [100, 0, 0], load_slots: LOAD_SLOTS as u8, scratch: None, scratch_kb: 0, mixer_mult: 1, growth: false, era: None, hot: None }; + LoadClass { mix: [100, 0, 0], load_slots: LOAD_SLOTS as u8, scratch: None, scratch_kb: 0, mixer_mult: 1, growth: false, era: None, hot: None, shadow: None }; /// The construction decided for program class v3 on 5 October 2026 (Counter ASIC 2.0, `docs/plans/mixer-x4.md`): /// version 2 loads (16 slots of one word, no scratch, no width roll, so the program stream is version 2's), the /// mixer applied 4 times per round, and the cache growth rule. Name "mx4". pub const MX4: LoadClass = - LoadClass { mix: [100, 0, 0], load_slots: LOAD_SLOTS as u8, scratch: None, scratch_kb: 0, mixer_mult: 4, growth: true, era: None, hot: None }; + LoadClass { mix: [100, 0, 0], load_slots: LOAD_SLOTS as u8, scratch: None, scratch_kb: 0, mixer_mult: 4, growth: true, era: None, hot: None, shadow: None }; /// The era class over `base` (`docs/plans/era-layout.md`): the parameters drawn by [`era_draw`]; when `allowed` /// has more than one width the drawn width becomes the class mix (every load that width), otherwise the base @@ -473,6 +502,17 @@ impl LoadClass { } /// This class with the mixer multiplier `m` (1, 2, 4, 8 or 16) and the cache growth rule on or off. + /// The class with a latency-shadow block of `instrs` instructions run `reps` times per iteration ("mx8+sh256x13"). + pub fn with_shadow(self, instrs: u16, reps: u16) -> LoadClass { + assert!((1..=4096).contains(&instrs) && (1..=1024).contains(&reps), "shadow block: 1..=4096 instructions, 1..=1024 reps"); + LoadClass { shadow: Some(ShadowClass { instrs, reps }), ..self } + } + + /// Shadow instructions per hash (0 without a shadow). + pub fn shadow_instrs_per_hash(&self) -> usize { + self.shadow.map(|s| s.instrs_per_hash()).unwrap_or(0) + } + pub fn with_mixer(self, mixer_mult: u8, growth: bool) -> LoadClass { assert!(mixer_mult >= 1 && mixer_mult <= 16 && mixer_mult.is_power_of_two(), "mixer multiplier must be 1, 2, 4, 8 or 16"); LoadClass { mixer_mult, growth, ..self } @@ -499,6 +539,15 @@ impl LoadClass { /// "mx4": the v3 construction; a trailing "m" and "g" set the mixer multiplier and the growth rule on any /// load class, "w16m4g" for example). pub fn parse(s: &str) -> Option { + // "+shx": the latency-shadow block over any class (Counter ASIC 3.0 item 8) + if let Some((base, sh)) = s.rsplit_once("+sh") { + let (instrs, reps) = sh.split_once('x')?; + let (instrs, reps): (u16, u16) = (instrs.parse().ok()?, reps.parse().ok()?); + if !(1..=4096).contains(&instrs) || !(1..=1024).contains(&reps) { + return None; + } + return Some(LoadClass::parse(base)?.with_shadow(instrs, reps)); + } if s == "mx4" { return Some(LoadClass::MX4); } @@ -603,6 +652,10 @@ impl LoadClass { /// An era class is the base name with "-era" appended ("w4-era401998a5", "mx4-era..."). /// A hot class appends "hotk[a]" ("hot64k4", "scr4k32+hot64k4a"; measured and not adopted). pub fn name(&self) -> String { + if let Some(sh) = self.shadow { + // "+shx": the shadow block is a suffix on any class ("mx8+sh256x13") + return format!("{}+sh{}x{}", LoadClass { shadow: None, ..*self }.name(), sh.instrs, sh.reps); + } if let Some(e) = self.era { let base = LoadClass { era: None, ..*self }; let base_name = if base.is_v2() { "w4".to_string() } else { base.name() }; @@ -797,6 +850,31 @@ impl Program { pub fn has_hot(&self) -> bool { self.class.hot.is_some() } + /// Whether the program carries a latency-shadow block (Counter ASIC 3.0 item 8). + pub fn has_shadow(&self) -> bool { + self.class.shadow.is_some() && !self.shadow.is_empty() + } + /// Times the shadow block runs per iteration (0 without one). + pub fn shadow_reps(&self) -> usize { + self.class.shadow.map(|s| s.reps as usize).unwrap_or(0) + } + /// Shadow instructions executed per hash: `ITERATIONS x block x reps` (0 without a shadow). + pub fn shadow_instrs_per_hash(&self) -> usize { + self.shadow.len() * self.shadow_reps() * ITERATIONS + } + /// Op histogram of the shadow block, count descending then name ascending (empty without a shadow). + pub fn shadow_histogram(&self) -> Vec<(&'static str, usize)> { + let mut counts: Vec<(&'static str, usize)> = Vec::new(); + for i in &self.shadow { + let name = i.op.name(); + match counts.iter_mut().find(|(n, _)| *n == name) { + Some(e) => e.1 += 1, + None => counts.push((name, 1)), + } + } + counts.sort_by(|a, b| b.1.cmp(&a.1).then_with(|| a.0.cmp(b.0))); + counts + } /// The hot table's words (0 without one). pub fn hot_words(&self) -> u32 { self.class.hot.map(|h| crate::memhard::hot_words(h.mb as u32)).unwrap_or(0) @@ -834,6 +912,10 @@ impl Program { pub fn op_mix(&self) -> String { self.histogram().iter().map(|(n, c)| format!("{n}={c}")).collect::>().join(" ") } + /// The shadow block's op mix in the same form (empty without a shadow). + pub fn shadow_op_mix(&self) -> String { + self.shadow_histogram().iter().map(|(n, c)| format!("{n}={c}")).collect::>().join(" ") + } /// The program id: FNV-1a 64 over `"igneum-program/" || generator_le32 || seed words as little-endian bytes /// || attempt_le32`. Written into every pack so a version 1 program, or another attempt of the same seed, /// can never be mistaken for this one. @@ -896,6 +978,12 @@ pub fn program_id_class(generator: u32, seed: &[u32; 8], attempt: u32, class: &L b.extend_from_slice(b"era/"); b.extend_from_slice(&e.id_bytes()); } + if let Some(sh) = class.shadow { + // Counter ASIC 3.0 item 8: the shadow block's size and repeat count are part of the construction + b.extend_from_slice(b"shadow/"); + b.extend_from_slice(&sh.instrs.to_le_bytes()); + b.extend_from_slice(&sh.reps.to_le_bytes()); + } if let Some(h) = class.hot { b.extend_from_slice(b"hot/"); b.push(h.mb); @@ -1067,6 +1155,41 @@ pub fn candidate_from_words_class( fresh[dst as usize] = true; instrs.push(Instr { op, dst: dst as u8, src: src as u8, src2: b as u8, imm, imm2, rot, bit: bit as u8, mask, width, win, off }); } + // (3) The latency-shadow block (Counter ASIC 3.0 item 8): drawn after the base program from the same stream, so + // the 64 instructions above are the class's without the shadow, draw for draw. Every slot is an ALU slot: the + // op from the non-load table, the source as on an ALU slot, the same per-instruction draws (the width roll and + // the era windows included when the class takes them, drawn and ignored) so the stream shape is the program's. + let mut shadow = Vec::new(); + if let Some(sh) = class.shadow { + for _ in 0..sh.instrs { + let mut roll = rng.below(75); + let mut op = Op::Add; + for &(o, w) in &NONLOAD_WEIGHTS { + if roll < w { + op = o; + break; + } + roll -= w; + } + let dst = rng.below(8); + let a = rng.below(7); + let src = if a >= dst { a + 1 } else { a }; + let b = rng.below(8); + let imm = rng.next() as u32; + let imm2 = rng.next() as u32; + let rot = 1 + rng.below(31) as u32; + let bit = rng.below(32); + let mask = 1u8 << rng.below(5); + if class.takes_width_roll() { + let _ = rng.below(100); + } + if class.era.is_some() { + let _ = rng.below(3); + let _ = rng.next(); + } + shadow.push(Instr { op, dst: dst as u8, src: src as u8, src2: b as u8, imm, imm2, rot, bit: bit as u8, mask, width: 1, win: 0, off: 0 }); + } + } Program { seed_string: seed_string.to_string(), seed_bytes: seed_bytes.to_vec(), @@ -1076,6 +1199,7 @@ pub fn candidate_from_words_class( class, era_bytes: None, instrs, + shadow, } } @@ -1270,6 +1394,7 @@ pub fn generate_v1_from_words(seed_string: &str, seed: [u32; 8], cfg: &Generator class: LoadClass::V2, era_bytes: None, instrs, + shadow: Vec::new(), } } @@ -1699,4 +1824,40 @@ mod tests { assert_eq!(again.instrs, p.instrs); assert_eq!(again.attempt, p.attempt); } + + #[test] + fn shadow_class_leaves_the_base_program_and_class_v3_untouched() { + // Counter ASIC 3.0 item 8: the shadow is drawn after the 64 base instructions, so the base program, its + // attempt and its acceptance verdict are the class's without the shadow; v2 and v3 draw nothing. + let base = generate_class("igneum-genesis", LoadClass::MX8); + let sh = generate_class("igneum-genesis", LoadClass::MX8.with_shadow(256, 13)); + assert_eq!(sh.instrs, base.instrs); + assert_eq!(sh.attempt, base.attempt); + assert!(base.shadow.is_empty() && !base.has_shadow() && base.shadow_instrs_per_hash() == 0); + assert_eq!(sh.shadow.len(), 256); + assert!(sh.has_shadow()); + assert!(sh.shadow.iter().all(|i| !i.op.is_load() && i.op != Op::WLoad && i.src != i.dst && (1..=31).contains(&i.rot) && i.width == 1)); + assert_eq!(sh.shadow_instrs_per_hash(), ITERATIONS * 256 * 13); + assert_eq!(sh.class.name(), "mx8+sh256x13"); + assert_eq!(LoadClass::parse("mx8+sh256x13"), Some(sh.class)); + assert_eq!(LoadClass::parse("v2+sh64x1"), Some(LoadClass::V2.with_shadow(64, 1))); + assert_eq!(LoadClass::parse("mx8+sh0x1"), None); + assert_eq!(LoadClass::parse("mx8+sh64x0"), None); + assert_ne!(sh.program_id(), base.program_id()); + assert_ne!(sh.program_id(), generate_class("igneum-genesis", LoadClass::MX8.with_shadow(256, 12)).program_id()); + assert_eq!(V3_CLASS.shadow, None); + assert_eq!(LoadClass::V2.shadow, None); + let v2 = generate("igneum-genesis"); + assert!(v2.shadow.is_empty()); + assert_eq!(v2.program_id(), 0xbcc1248b10cc90f2); + // the block changes the hash: the interpreter runs it (closed-form dataset, small, no cache needed) + let ds = crate::verify::DatasetSource::new("2026-10-06", crate::verify::DatasetMode::ClosedForm, 20); + let h0 = crate::verify::hash_warp(&base, 0, &ds); + let h1 = crate::verify::hash_warp(&sh, 0, &ds); + assert_ne!(h0, h1); + // the same seed and class derive the same block + let again = generate_class("igneum-genesis", LoadClass::MX8.with_shadow(256, 13)); + assert_eq!(again.shadow, sh.shadow); + assert_eq!(crate::verify::hash_warp(&again, 0, &ds), h1); + } } diff --git a/igneum-pow/src/main.rs b/igneum-pow/src/main.rs index cf82ab766..9d9053c2d 100644 --- a/igneum-pow/src/main.rs +++ b/igneum-pow/src/main.rs @@ -93,7 +93,7 @@ fn usage() -> ! { \x20 hash-bound --prehash <64 hex> --nonce print the header-bound hash (bind.rs) of one 64-bit nonce\n\ \x20 accept every candidate of the seed (or --epoch-hex) with its acceptance verdict\n\ \x20 show the accepted program, one instruction per line\n\ - \x20 --class C load class: v2 (default), mx4 (class v3: mixer x4, cache growth), w4, w16, w64, w64x4, p4,p16,p64[xN], m[g]\n\ + \x20 --class C load class: v2 (default), mx4 (class v3: mixer x4, cache growth), w4, w16, w64, w64x4, p4,p16,p64[xN], m[g], +shx (latency-shadow block of S ALU instructions x R passes per iteration, Counter ASIC 3.0 item 8)\n\ \x20 --days N days since genesis for the cache growth rule of a class with it (default 0: the 2^26-word cache)\n\ \x20 --program-class v2|v3 the program class of the seam (v3 = generator 3 on V3_CLASS, the chain's own derivation; --era-hex records the era seed)\n\ \x20 --era E era layout over --class: igneum-era-test/ or :<64 hex> (the 32-byte era seed E_n)\n\ @@ -274,6 +274,15 @@ fn bench(a: &Args, mode: DatasetMode) { shape.cache_log2_words, e.program.op_mix() ); + if e.program.has_shadow() { + println!( + "shadow: {} instructions x {} passes per iteration, {} shadow instructions per hash, op mix {}", + e.program.shadow.len(), + e.program.shadow_reps(), + e.program.shadow_instrs_per_hash(), + e.program.shadow_op_mix() + ); + } let bases = [0u32, 4096, 1_000_000]; for &b in &bases { let t = Instant::now(); diff --git a/igneum-pow/src/verify.rs b/igneum-pow/src/verify.rs index 91f9ee31f..4b22630c4 100644 --- a/igneum-pow/src/verify.rs +++ b/igneum-pow/src/verify.rs @@ -380,6 +380,13 @@ pub fn interpret_warp_scratch( } } } + // Latency-shadow block (Counter ASIC 3.0 item 8): the block runs `reps` times after instruction 63 with the + // iteration's `sel`; it is empty on every class without a shadow, so version 2 and class v3 run nothing here. + for _ in 0..program.shadow_reps() { + for ins in &program.shadow { + step(ins, &mut r, &sel, mask, log2, era.as_ref(), layout, ds, &mut idx, &mut val, &mut items_derived); + } + } } let mut hashes = [0u64; LANES]; for lane in 0..LANES { diff --git a/igneum-pow/tests/scratch.rs b/igneum-pow/tests/scratch.rs index acf376d14..0fe68a9be 100644 --- a/igneum-pow/tests/scratch.rs +++ b/igneum-pow/tests/scratch.rs @@ -263,6 +263,7 @@ fn edge(name: &str, c: LoadClass, instrs: Vec) -> Program { class: c, era_bytes: None, instrs, + shadow: Vec::new(), } } diff --git a/proto-cuda/packs-ca3-shadow/sh1024x3/kernel.cl b/proto-cuda/packs-ca3-shadow/sh1024x3/kernel.cl new file mode 100644 index 000000000..8f07f1b0e --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh1024x3/kernel.cl @@ -0,0 +1,1306 @@ +// 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 ^ 0x67a9a7beu; x += 0x9e3779b9u; x = splitmix32(x); r0 = x ^ 0x1a155b25u; } // SEEDW[0], 0x9e3779b9u * 1u, SEEDW[1] + { uint x = nonce ^ 0x1a155b25u; x += 0x3c6ef372u; x = splitmix32(x); r1 = x ^ 0xfddfb732u; } // SEEDW[1], 0x9e3779b9u * 2u, SEEDW[2] + { uint x = nonce ^ 0xfddfb732u; x += 0xdaa66d2bu; x = splitmix32(x); r2 = x ^ 0x4b5af2e8u; } // SEEDW[2], 0x9e3779b9u * 3u, SEEDW[3] + { uint x = nonce ^ 0x4b5af2e8u; x += 0x78dde6e4u; x = splitmix32(x); r3 = x ^ 0xc55caf33u; } // SEEDW[3], 0x9e3779b9u * 4u, SEEDW[4] + { uint x = nonce ^ 0xc55caf33u; x += 0x1715609du; x = splitmix32(x); r4 = x ^ 0xa27c13b7u; } // SEEDW[4], 0x9e3779b9u * 5u, SEEDW[5] + { uint x = nonce ^ 0xa27c13b7u; x += 0xb54cda56u; x = splitmix32(x); r5 = x ^ 0x06628a48u; } // SEEDW[5], 0x9e3779b9u * 6u, SEEDW[6] + { uint x = nonce ^ 0x06628a48u; x += 0x5384540fu; x = splitmix32(x); r6 = x ^ 0x03852469u; } // SEEDW[6], 0x9e3779b9u * 7u, SEEDW[7] + { uint x = nonce ^ 0x03852469u; x += 0xf1bbcdc8u; x = splitmix32(x); r7 = x ^ 0x67a9a7beu; } // SEEDW[7], 0x9e3779b9u * 8u, SEEDW[0] + + for (uint it = 0u; it < 8u; ++it) { + uint sel = r0; + r2 = r3 * r4 + r2; // 0 mad + r2 = r1 * r1 + r2; // 1 mad + r2 = r3 * r2 + r2; // 2 mad + r3 = r3 ^ r5; // 3 xor + r7 = r7 ^ ds[r2 & mask]; // 4 load + r5 = r5 ^ ds[r7 & mask]; // 5 load + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r1 = r1 ^ t_; } // 6 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r7 = r7 ^ t_; } // 7 shfl + r1 = mul_hi(r1, r5); // 8 mulhi + r6 = rotr_var(r6, r3); // 9 rotr + r3 = r3 | r4; // 10 or + r4 = r4 ^ ds[r3 & mask]; // 11 load + r0 = mul_hi(r0, r4); // 12 mulhi + r5 = r5 + r1 + ((((sel >> 30u) & 1u) != 0u) ? 0xd3177981u : 0xc7934706u); // 13 add + r0 = r0 ^ ds[r4 & mask]; // 14 load + r2 = r2 - r4; // 15 sub + r2 = r2 ^ ds[r0 & mask]; // 16 load + r7 = r7 ^ ds[r2 & mask]; // 17 load + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r7 = r7 ^ t_; } // 18 shfl + r5 = r5 * r0; // 19 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // 20 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 16u); r2 = r2 ^ t_; } // 21 shfl + r6 = mul_hi(r6, r2); // 22 mulhi + r6 = r6 ^ ds[r1 & mask]; // 23 load + r5 = r5 * r0; // 24 mul + r5 = rotl_imm(r5, 19u); // 25 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 2u); r7 = r7 ^ t_; } // 26 shfl + r0 = r0 ^ r5; // 27 xor + r0 = r0 ^ r4; // 28 xor + r3 = r3 - r0; // 29 sub + r5 = r5 * r1; // 30 mul + r7 = r7 ^ ds[r2 & mask]; // 31 load + r1 = r1 ^ ds[r0 & mask]; // 32 load + r5 = r5 ^ r6; // 33 xor + r5 = r5 ^ ds[r1 & mask]; // 34 load + r0 = mul_hi(r0, r5); // 35 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r5 = r5 ^ t_; } // 36 shfl + r7 = r7 ^ ds[r0 & mask]; // 37 load + r3 = r3 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0x230c005cu : 0x75ba2fadu); // 38 add + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 4u); r1 = r1 ^ t_; } // 39 shfl + r2 = r2 ^ r5; // 40 xor + r3 = r6 * r3 + r3; // 41 mad + r6 = r6 - r7; // 42 sub + r7 = r7 ^ r0; // 43 xor + r1 = r1 ^ ds[r7 & mask]; // 44 load + r2 = r2 * r3; // 45 mul + r1 = mul_hi(r1, r5); // 46 mulhi + r4 = r4 - r3; // 47 sub + r2 = rotr_var(r2, r6); // 48 rotr + r3 = r3 ^ ds[r5 & mask]; // 49 load + r1 = r1 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x1907970cu : 0x81b8bc2cu); // 50 add + r0 = r0 * r2; // 51 mul + r0 = r0 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x699fd448u : 0x4f92b968u); // 52 add + r1 = r1 + r0 + ((((sel >> 12u) & 1u) != 0u) ? 0x77b1520du : 0x2bb965afu); // 53 add + r7 = rotl_imm(r7, 14u); // 54 rotl + r3 = r3 + r7 + ((((sel >> 1u) & 1u) != 0u) ? 0xa54c55a0u : 0x7b0fe07au); // 55 add + r6 = r6 ^ ds[r7 & mask]; // 56 load + r1 = rotr_var(r1, r5); // 57 rotr + r5 = r5 ^ ds[r4 & mask]; // 58 load + r6 = r6 ^ ds[r2 & mask]; // 59 load + r3 = r5 * r0 + r3; // 60 mad + r5 = r5 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0xad7493e7u : 0xaf9dd72du); // 61 add + r4 = r4 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x1e07c3d9u : 0x89841d87u); // 62 add + r5 = rotl_imm(r5, 19u); // 63 rotl + // latency-shadow block (Counter ASIC 3.0 item 8): 1024 ALU instructions x 3 passes after instruction 63, no load + for (uint sh = 0u; sh < 3u; ++sh) { + r5 = r5 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x8bc12da9u : 0x92199f99u); // s0 add + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x63079e5au : 0x8d72d3adu); // s1 add + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 2u); r6 = r6 ^ t_; } // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + ((((sel >> 31u) & 1u) != 0u) ? 0x5d4c7a60u : 0xb21b4babu); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + ((((sel >> 16u) & 1u) != 0u) ? 0xc88e2942u : 0x2fe0e98bu); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r6 = r6 ^ t_; } // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 4u); r2 = r2 ^ t_; } // s12 shfl + r1 = r1 + r5 + ((((sel >> 25u) & 1u) != 0u) ? 0xbc48c63eu : 0xbdf8f9a5u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r2 = r2 ^ t_; } // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + ((((sel >> 1u) & 1u) != 0u) ? 0x96e8f127u : 0x45c37cecu); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = mul_hi(r6, r0); // s28 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r2 = r2 ^ t_; } // s29 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r1 = r1 ^ t_; } // s30 shfl + r1 = r1 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0xb1cdb2abu : 0x37985632u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // s33 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r0 = r0 ^ t_; } // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x856e0180u : 0x804e777eu); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xe9bd0cc4u : 0x0b06c8a7u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = mul_hi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = mul_hi(r4, r3); // s44 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xcdcb63f6u : 0xee822e17u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r4 = r4 ^ t_; } // s47 shfl + r6 = mul_hi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0xd4758987u : 0x3dfad1b6u); // s56 add + r4 = r4 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x0602d6beu : 0xfca75bc2u); // s57 add + r5 = mul_hi(r5, r6); // s58 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r2 = r2 ^ t_; } // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0x8596687au : 0xd71c02ffu); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 2u); r7 = r7 ^ t_; } // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0x08ac5733u : 0x3c6fe15du); // s72 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r3 = r3 ^ t_; } // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + ((((sel >> 1u) & 1u) != 0u) ? 0xc100b495u : 0x295d5faeu); // s77 add + r3 = mul_hi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + ((((sel >> 15u) & 1u) != 0u) ? 0x5cc59530u : 0x274a9221u); // s81 add + r7 = r7 + r3 + ((((sel >> 5u) & 1u) != 0u) ? 0x141479ecu : 0xc8651f8eu); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r2 = r2 ^ t_; } // s85 shfl + r3 = r3 ^ r2; // s86 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 2u); r5 = r5 ^ t_; } // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x883c0c92u : 0x53f915c2u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + ((((sel >> 31u) & 1u) != 0u) ? 0x3cc5bd20u : 0xe2be00a5u); // s91 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 1u); r7 = r7 ^ t_; } // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + ((((sel >> 17u) & 1u) != 0u) ? 0xbfd646cbu : 0x423fd9c9u); // s101 add + r7 = r7 + r6 + ((((sel >> 11u) & 1u) != 0u) ? 0x19b74a43u : 0x8d3c011du); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + ((((sel >> 15u) & 1u) != 0u) ? 0x7dcb7e18u : 0x8ce14721u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = mul_hi(r2, r0); // s109 mulhi + r1 = mul_hi(r1, r0); // s110 mulhi + r0 = r0 + r2 + ((((sel >> 28u) & 1u) != 0u) ? 0x3c179ad8u : 0x2d9fc6b9u); // s111 add + r2 = mul_hi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + ((((sel >> 22u) & 1u) != 0u) ? 0x47359729u : 0x502138e2u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = mul_hi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 2u); r4 = r4 ^ t_; } // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r7 = r7 ^ t_; } // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x6c57e4e7u : 0x33dff776u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + ((((sel >> 30u) & 1u) != 0u) ? 0xe8212c0cu : 0x5db25b34u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = mul_hi(r0, r5); // s138 mulhi + r2 = r2 + r7 + ((((sel >> 10u) & 1u) != 0u) ? 0xd44ff710u : 0x218d4090u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r3 = r3 ^ t_; } // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + ((((sel >> 29u) & 1u) != 0u) ? 0xb98942fau : 0xf4b1a8deu); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + ((((sel >> 17u) & 1u) != 0u) ? 0x0d48ba42u : 0x2bef10f2u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + ((((sel >> 30u) & 1u) != 0u) ? 0xc98dea9cu : 0xdc5cc080u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0x6c752dcbu : 0x18197438u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + ((((sel >> 3u) & 1u) != 0u) ? 0x8e481727u : 0xf1c46574u); // s163 add + r0 = mul_hi(r0, r4); // s164 mulhi + r2 = r2 + r6 + ((((sel >> 20u) & 1u) != 0u) ? 0x550ab406u : 0xac578137u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + ((((sel >> 14u) & 1u) != 0u) ? 0xaebb5966u : 0xa33e6706u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 8u); r7 = r7 ^ t_; } // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x5bb7550fu : 0xd94d55acu); // s184 add + r3 = r3 | r5; // s185 or + r6 = mul_hi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r7 = r7 ^ t_; } // s188 shfl + r6 = r6 + r5 + ((((sel >> 6u) & 1u) != 0u) ? 0x2a354e2du : 0x89e747feu); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = mul_hi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r4 = r4 ^ t_; } // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + ((((sel >> 7u) & 1u) != 0u) ? 0x10cfdc71u : 0xea03e8e7u); // s197 add + r7 = r7 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x66e148d3u : 0xa7ee0102u); // s198 add + r5 = r5 - r2; // s199 sub + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r5 = r5 ^ t_; } // s200 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 8u); r7 = r7 ^ t_; } // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0x8558b619u : 0x8379a4deu); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = mul_hi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 4u); r2 = r2 ^ t_; } // s209 shfl + r7 = r7 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0xf4049c4cu : 0xaa8cb14eu); // s210 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 16u); r7 = r7 ^ t_; } // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 16u); r3 = r3 ^ t_; } // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = mul_hi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r5 = r5 ^ t_; } // s222 shfl + r5 = mul_hi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0x2a7fecb2u : 0x1d176220u); // s230 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r1 = r1 ^ t_; } // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + ((((sel >> 25u) & 1u) != 0u) ? 0xadce39f3u : 0x17dafb4du); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + ((((sel >> 29u) & 1u) != 0u) ? 0x0e7033b6u : 0xf2f77d26u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + ((((sel >> 31u) & 1u) != 0u) ? 0x7b2ff6b7u : 0xfed2da4eu); // s247 add + r0 = r0 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0xb5fad7b1u : 0x03b2891cu); // s248 add + r5 = mul_hi(r5, r4); // s249 mulhi + r5 = r5 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0xa7e71c2fu : 0x042cd6e3u); // s250 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 1u); r6 = r6 ^ t_; } // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0xb83d78deu : 0x784a302bu); // s254 add + r2 = r2 - r4; // s255 sub + r3 = r3 - r4; // s256 sub + r2 = r2 * r4; // s257 mul + r4 = r0 * r6 + r4; // s258 mad + r5 = r5 | r0; // s259 or + r4 = r4 ^ r6; // s260 xor + r6 = mul_hi(r6, r3); // s261 mulhi + r2 = r2 * r6; // s262 mul + r5 = rotl_imm(r5, 1u); // s263 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 8u); r7 = r7 ^ t_; } // s264 shfl + r3 = r3 * r2; // s265 mul + r2 = r2 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x99a1d1b6u : 0x3dddf1b2u); // s266 add + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 8u); r2 = r2 ^ t_; } // s267 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r0 = r0 ^ t_; } // s268 shfl + r4 = r4 - r2; // s269 sub + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 1u); r0 = r0 ^ t_; } // s270 shfl + r3 = r3 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x40ca287au : 0xcfc62661u); // s271 add + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 16u); r1 = r1 ^ t_; } // s272 shfl + r1 = r3 * r6 + r1; // s273 mad + r7 = r7 + r6 + ((((sel >> 30u) & 1u) != 0u) ? 0xed4b65adu : 0x44caede3u); // s274 add + r5 = r5 ^ r7; // s275 xor + r2 = r2 * r6; // s276 mul + r2 = r2 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0x0f45ae89u : 0x9aae6c12u); // s277 add + r2 = r2 ^ r6; // s278 xor + r1 = r1 - r2; // s279 sub + r5 = r5 ^ r1; // s280 xor + r7 = r7 ^ r1; // s281 xor + r7 = r7 - r1; // s282 sub + r5 = r5 - r7; // s283 sub + r7 = r0 * r6 + r7; // s284 mad + r5 = mul_hi(r5, r4); // s285 mulhi + r3 = r3 - r5; // s286 sub + r5 = r5 - r1; // s287 sub + r1 = r3 * r7 + r1; // s288 mad + r3 = rotl_imm(r3, 9u); // s289 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 8u); r5 = r5 ^ t_; } // s290 shfl + r7 = r7 + r2 + ((((sel >> 1u) & 1u) != 0u) ? 0xe086d3b6u : 0x2307120bu); // s291 add + r4 = r4 ^ r3; // s292 xor + r3 = rotl_imm(r3, 14u); // s293 rotl + r5 = r5 - r4; // s294 sub + r2 = mul_hi(r2, r3); // s295 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r1 = r1 ^ t_; } // s296 shfl + r3 = r6 * r1 + r3; // s297 mad + r4 = r4 ^ r1; // s298 xor + r6 = r6 + r3 + ((((sel >> 24u) & 1u) != 0u) ? 0xadbeb223u : 0x4e3a12e5u); // s299 add + r6 = mul_hi(r6, r5); // s300 mulhi + r7 = rotr_var(r7, r5); // s301 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 16u); r5 = r5 ^ t_; } // s302 shfl + r3 = r3 ^ r4; // s303 xor + r2 = r3 * r1 + r2; // s304 mad + r1 = r1 ^ r7; // s305 xor + r1 = r1 + r0 + ((((sel >> 22u) & 1u) != 0u) ? 0x0d8f1149u : 0x51ab0157u); // s306 add + r2 = r2 + r1 + ((((sel >> 24u) & 1u) != 0u) ? 0x99a96de9u : 0x3b5e8835u); // s307 add + r1 = r5 * r5 + r1; // s308 mad + r2 = r2 * r4; // s309 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 8u); r3 = r3 ^ t_; } // s310 shfl + r0 = r0 ^ r4; // s311 xor + r5 = mul_hi(r5, r2); // s312 mulhi + r7 = r7 + r2 + ((((sel >> 30u) & 1u) != 0u) ? 0x86ddfba7u : 0x81f3297cu); // s313 add + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x38aa230au : 0x838e4a2fu); // s314 add + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 16u); r7 = r7 ^ t_; } // s315 shfl + r7 = r7 - r5; // s316 sub + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r5 = r5 ^ t_; } // s317 shfl + r1 = r1 + r3 + ((((sel >> 11u) & 1u) != 0u) ? 0xa6399179u : 0xebcad805u); // s318 add + r7 = rotl_imm(r7, 21u); // s319 rotl + r7 = r7 ^ r6; // s320 xor + r7 = r7 | r6; // s321 or + r5 = r5 + r3 + ((((sel >> 25u) & 1u) != 0u) ? 0x4de83051u : 0x4c906f73u); // s322 add + r0 = r0 + r4 + ((((sel >> 14u) & 1u) != 0u) ? 0xd3d821c5u : 0x742ec195u); // s323 add + r6 = r6 ^ r2; // s324 xor + r6 = rotl_imm(r6, 1u); // s325 rotl + r4 = rotl_imm(r4, 24u); // s326 rotl + r4 = r4 | r3; // s327 or + r2 = r1 * r3 + r2; // s328 mad + r2 = r2 ^ r7; // s329 xor + r2 = r2 | r3; // s330 or + r7 = r7 - r1; // s331 sub + r3 = r3 + r6 + ((((sel >> 0u) & 1u) != 0u) ? 0xc06f831eu : 0xb86750e9u); // s332 add + r7 = rotl_imm(r7, 25u); // s333 rotl + r3 = r0 * r0 + r3; // s334 mad + r2 = r2 + r5 + ((((sel >> 28u) & 1u) != 0u) ? 0x5225df1du : 0xb57956eeu); // s335 add + r3 = r1 * r6 + r3; // s336 mad + r4 = r2 * r2 + r4; // s337 mad + r7 = r7 * r2; // s338 mul + r1 = r1 * r6; // s339 mul + r4 = r4 + r5 + ((((sel >> 5u) & 1u) != 0u) ? 0xb73822ceu : 0x23f6425fu); // s340 add + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 2u); r5 = r5 ^ t_; } // s341 shfl + r6 = r6 ^ r5; // s342 xor + r0 = rotl_imm(r0, 13u); // s343 rotl + r0 = rotr_var(r0, r3); // s344 rotr + r1 = r1 - r0; // s345 sub + r6 = rotr_var(r6, r1); // s346 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 4u); r6 = r6 ^ t_; } // s347 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 8u); r5 = r5 ^ t_; } // s348 shfl + r5 = r5 ^ r3; // s349 xor + r1 = r4 * r0 + r1; // s350 mad + r3 = rotr_var(r3, r1); // s351 rotr + r1 = rotl_imm(r1, 13u); // s352 rotl + r3 = r3 + r0 + ((((sel >> 26u) & 1u) != 0u) ? 0xfa0c560eu : 0x0dce5917u); // s353 add + r3 = mul_hi(r3, r2); // s354 mulhi + r1 = r2 * r4 + r1; // s355 mad + r0 = r0 ^ r1; // s356 xor + r7 = r7 * r5; // s357 mul + r0 = rotl_imm(r0, 5u); // s358 rotl + r2 = r7 * r7 + r2; // s359 mad + r2 = r2 | r6; // s360 or + r6 = r6 + r1 + ((((sel >> 19u) & 1u) != 0u) ? 0x277e027au : 0x7c83b79au); // s361 add + r0 = r0 * r2; // s362 mul + r3 = r3 * r6; // s363 mul + r2 = rotr_var(r2, r4); // s364 rotr + r5 = r5 + r1 + ((((sel >> 1u) & 1u) != 0u) ? 0x52275ea4u : 0x271f2385u); // s365 add + r1 = r1 * r6; // s366 mul + r0 = r0 + r7 + ((((sel >> 30u) & 1u) != 0u) ? 0x8f8b4093u : 0x4c66800fu); // s367 add + r4 = rotr_var(r4, r0); // s368 rotr + r4 = rotr_var(r4, r0); // s369 rotr + r1 = r0 * r6 + r1; // s370 mad + r0 = r0 - r5; // s371 sub + r7 = r7 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0x9a7dcadcu : 0x7dad1ed5u); // s372 add + r7 = r7 + r3 + ((((sel >> 20u) & 1u) != 0u) ? 0xf808c195u : 0x1ea3d58eu); // s373 add + r1 = r1 * r2; // s374 mul + r3 = r7 * r2 + r3; // s375 mad + r4 = r4 ^ r1; // s376 xor + r1 = r1 | r0; // s377 or + r5 = r5 + r0 + ((((sel >> 26u) & 1u) != 0u) ? 0x427ed5ceu : 0x98b36d10u); // s378 add + r6 = r6 * r0; // s379 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 1u); r7 = r7 ^ t_; } // s380 shfl + r4 = r4 + r0 + ((((sel >> 18u) & 1u) != 0u) ? 0x38f848b9u : 0xb19cab2du); // s381 add + r3 = r5 * r2 + r3; // s382 mad + r0 = r0 | r7; // s383 or + r5 = r5 - r4; // s384 sub + r1 = r1 - r5; // s385 sub + r2 = r2 - r0; // s386 sub + r5 = r5 + r2 + ((((sel >> 17u) & 1u) != 0u) ? 0xffc20cf8u : 0x341056b0u); // s387 add + r1 = rotl_imm(r1, 26u); // s388 rotl + r2 = r2 ^ r5; // s389 xor + r5 = r7 * r0 + r5; // s390 mad + r3 = mul_hi(r3, r2); // s391 mulhi + r5 = r5 + r4 + ((((sel >> 0u) & 1u) != 0u) ? 0xfb939f2bu : 0x78aa571au); // s392 add + r5 = r5 | r2; // s393 or + r1 = mul_hi(r1, r7); // s394 mulhi + r4 = r4 - r2; // s395 sub + r7 = r7 - r1; // s396 sub + r0 = r0 + r1 + ((((sel >> 2u) & 1u) != 0u) ? 0xa9c6c9fbu : 0x31af4767u); // s397 add + r3 = r3 * r1; // s398 mul + r1 = r1 - r7; // s399 sub + r7 = r7 + r6 + ((((sel >> 8u) & 1u) != 0u) ? 0x34f9b056u : 0x266d4c34u); // s400 add + r5 = rotl_imm(r5, 5u); // s401 rotl + r0 = r0 + r4 + ((((sel >> 23u) & 1u) != 0u) ? 0x79822c64u : 0x7241955eu); // s402 add + r2 = r4 * r0 + r2; // s403 mad + r5 = rotl_imm(r5, 29u); // s404 rotl + r3 = r3 - r5; // s405 sub + r2 = r2 + r3 + ((((sel >> 27u) & 1u) != 0u) ? 0xda046091u : 0xf65aca5du); // s406 add + r4 = mul_hi(r4, r7); // s407 mulhi + r2 = r2 + r1 + ((((sel >> 14u) & 1u) != 0u) ? 0x167aba1cu : 0x6a00cefbu); // s408 add + r2 = r6 * r6 + r2; // s409 mad + r6 = rotl_imm(r6, 26u); // s410 rotl + r6 = r6 | r7; // s411 or + r1 = rotl_imm(r1, 20u); // s412 rotl + r7 = r7 * r5; // s413 mul + r6 = r6 - r0; // s414 sub + r6 = mul_hi(r6, r0); // s415 mulhi + r3 = rotl_imm(r3, 5u); // s416 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r1 = r1 ^ t_; } // s417 shfl + r0 = r0 * r4; // s418 mul + r4 = rotr_var(r4, r7); // s419 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r7 = r7 ^ t_; } // s420 shfl + r5 = r3 * r6 + r5; // s421 mad + r3 = r3 ^ r4; // s422 xor + r3 = rotr_var(r3, r7); // s423 rotr + r4 = r4 + r1 + ((((sel >> 26u) & 1u) != 0u) ? 0xbb669c17u : 0xba29da18u); // s424 add + r7 = rotr_var(r7, r5); // s425 rotr + r2 = r2 * r6; // s426 mul + r1 = r1 + r4 + ((((sel >> 16u) & 1u) != 0u) ? 0xc6b45a76u : 0x4f70e34fu); // s427 add + r1 = rotl_imm(r1, 1u); // s428 rotl + r6 = mul_hi(r6, r5); // s429 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xff610984u : 0x3883e0f5u); // s430 add + r4 = r4 | r3; // s431 or + r7 = r7 ^ r5; // s432 xor + r3 = mul_hi(r3, r2); // s433 mulhi + r2 = r2 ^ r6; // s434 xor + r4 = r4 | r3; // s435 or + r0 = r0 + r1 + ((((sel >> 9u) & 1u) != 0u) ? 0xf37057feu : 0xb1b15861u); // s436 add + r7 = r7 + r4 + ((((sel >> 4u) & 1u) != 0u) ? 0x61793eafu : 0x2e9e173fu); // s437 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 1u); r5 = r5 ^ t_; } // s438 shfl + r6 = r0 * r3 + r6; // s439 mad + r5 = r5 ^ r2; // s440 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 16u); r0 = r0 ^ t_; } // s441 shfl + r6 = r6 * r3; // s442 mul + r5 = r5 - r4; // s443 sub + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r2 = r2 ^ t_; } // s444 shfl + r0 = r0 + r5 + ((((sel >> 12u) & 1u) != 0u) ? 0x69def831u : 0x646856aau); // s445 add + r4 = r4 + r6 + ((((sel >> 23u) & 1u) != 0u) ? 0x1f8ecb8bu : 0x58a3f8fcu); // s446 add + r4 = r0 * r2 + r4; // s447 mad + r5 = r5 * r0; // s448 mul + r2 = r2 + r5 + ((((sel >> 11u) & 1u) != 0u) ? 0x7ecb876du : 0x48d3062du); // s449 add + r2 = r5 * r6 + r2; // s450 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r7 = r7 ^ t_; } // s451 shfl + r2 = r2 * r5; // s452 mul + r5 = mul_hi(r5, r4); // s453 mulhi + r1 = r1 ^ r7; // s454 xor + r2 = r2 * r7; // s455 mul + r1 = r1 * r3; // s456 mul + r3 = r6 * r2 + r3; // s457 mad + r7 = r7 - r0; // s458 sub + r2 = r4 * r5 + r2; // s459 mad + r0 = rotl_imm(r0, 2u); // s460 rotl + r4 = r4 ^ r2; // s461 xor + r4 = r4 + r0 + ((((sel >> 18u) & 1u) != 0u) ? 0x7b093757u : 0xb41dd69bu); // s462 add + r6 = r6 + r1 + ((((sel >> 3u) & 1u) != 0u) ? 0x916e1b7eu : 0xb042032eu); // s463 add + r2 = r2 + r6 + ((((sel >> 8u) & 1u) != 0u) ? 0x6d42b978u : 0x4e68a2a0u); // s464 add + r3 = r3 - r2; // s465 sub + r2 = r2 * r5; // s466 mul + r7 = rotl_imm(r7, 28u); // s467 rotl + r0 = r0 - r3; // s468 sub + r7 = mul_hi(r7, r2); // s469 mulhi + r7 = r7 | r6; // s470 or + r7 = rotl_imm(r7, 28u); // s471 rotl + r0 = r0 * r6; // s472 mul + r2 = r2 | r1; // s473 or + r2 = r2 + r4 + ((((sel >> 14u) & 1u) != 0u) ? 0x20c5276bu : 0x13ec3b3eu); // s474 add + r2 = rotr_var(r2, r6); // s475 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 16u); r6 = r6 ^ t_; } // s476 shfl + r2 = rotl_imm(r2, 15u); // s477 rotl + r5 = rotr_var(r5, r4); // s478 rotr + r3 = rotl_imm(r3, 26u); // s479 rotl + r5 = r5 | r6; // s480 or + r3 = rotl_imm(r3, 29u); // s481 rotl + r0 = rotr_var(r0, r7); // s482 rotr + r1 = r1 - r0; // s483 sub + r0 = r2 * r5 + r0; // s484 mad + r6 = r6 ^ r4; // s485 xor + r6 = r6 ^ r0; // s486 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 4u); r3 = r3 ^ t_; } // s487 shfl + r6 = mul_hi(r6, r0); // s488 mulhi + r1 = r1 * r0; // s489 mul + r3 = r3 ^ r6; // s490 xor + r3 = r3 * r6; // s491 mul + r0 = r0 * r3; // s492 mul + r4 = r4 | r3; // s493 or + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 8u); r0 = r0 ^ t_; } // s494 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 16u); r0 = r0 ^ t_; } // s495 shfl + r6 = r5 * r2 + r6; // s496 mad + r5 = r5 * r6; // s497 mul + r3 = r3 ^ r1; // s498 xor + r0 = r0 + r1 + ((((sel >> 20u) & 1u) != 0u) ? 0x19f4c710u : 0x53e99acau); // s499 add + r6 = r5 * r2 + r6; // s500 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r7 = r7 ^ t_; } // s501 shfl + r3 = r3 - r5; // s502 sub + r0 = rotl_imm(r0, 8u); // s503 rotl + r3 = r3 ^ r1; // s504 xor + r7 = r7 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x7a6ac7b5u : 0x0867fe20u); // s505 add + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 2u); r0 = r0 ^ t_; } // s506 shfl + r0 = r0 * r1; // s507 mul + r6 = r6 | r5; // s508 or + r2 = r2 * r7; // s509 mul + r1 = r1 + r5 + ((((sel >> 21u) & 1u) != 0u) ? 0xd77f6a03u : 0xd7fdc3ecu); // s510 add + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 8u); r3 = r3 ^ t_; } // s511 shfl + r6 = r6 + r3 + ((((sel >> 9u) & 1u) != 0u) ? 0x5c22b0b5u : 0x297a096au); // s512 add + r7 = r7 | r0; // s513 or + r7 = r7 + r3 + ((((sel >> 27u) & 1u) != 0u) ? 0x4caafacdu : 0x5de1d1d1u); // s514 add + r1 = mul_hi(r1, r0); // s515 mulhi + r0 = r0 - r6; // s516 sub + r2 = r2 - r1; // s517 sub + r6 = r5 * r7 + r6; // s518 mad + r2 = r2 ^ r7; // s519 xor + r1 = r1 | r5; // s520 or + r0 = r4 * r6 + r0; // s521 mad + r4 = r4 + r6 + ((((sel >> 29u) & 1u) != 0u) ? 0xb1091e80u : 0x2caeeca3u); // s522 add + r7 = r6 * r5 + r7; // s523 mad + r7 = r7 - r2; // s524 sub + r0 = r0 * r7; // s525 mul + r0 = r0 ^ r7; // s526 xor + r1 = mul_hi(r1, r4); // s527 mulhi + r0 = rotr_var(r0, r5); // s528 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 16u); r2 = r2 ^ t_; } // s529 shfl + r2 = mul_hi(r2, r3); // s530 mulhi + r1 = r1 | r4; // s531 or + r6 = r6 + r4 + ((((sel >> 13u) & 1u) != 0u) ? 0xbda312aeu : 0xbe9e1eb0u); // s532 add + r7 = r7 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x1ec16229u : 0xbe5d93a3u); // s533 add + r0 = r6 * r4 + r0; // s534 mad + r0 = r0 + r5 + ((((sel >> 23u) & 1u) != 0u) ? 0x500828bcu : 0x5e23583bu); // s535 add + r6 = r5 * r0 + r6; // s536 mad + r2 = r2 ^ r4; // s537 xor + r6 = r3 * r5 + r6; // s538 mad + r6 = r6 + r4 + ((((sel >> 3u) & 1u) != 0u) ? 0x852321dcu : 0x43c32138u); // s539 add + r2 = r2 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x44e6ae63u : 0xaff69493u); // s540 add + r3 = mul_hi(r3, r5); // s541 mulhi + r1 = r1 + r7 + ((((sel >> 5u) & 1u) != 0u) ? 0x909712feu : 0xc5de29efu); // s542 add + r1 = r3 * r2 + r1; // s543 mad + r1 = r1 + r3 + ((((sel >> 11u) & 1u) != 0u) ? 0xfb7b42b9u : 0x1e20e084u); // s544 add + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 4u); r4 = r4 ^ t_; } // s545 shfl + r6 = r6 + r1 + ((((sel >> 10u) & 1u) != 0u) ? 0x6e036dd4u : 0x9370db38u); // s546 add + r4 = r4 ^ r6; // s547 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r5 = r5 ^ t_; } // s548 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r3 = r3 ^ t_; } // s549 shfl + r1 = rotr_var(r1, r7); // s550 rotr + r0 = r3 * r2 + r0; // s551 mad + r7 = mul_hi(r7, r4); // s552 mulhi + r0 = r0 + r4 + ((((sel >> 13u) & 1u) != 0u) ? 0xd3c9174du : 0xbf2488f6u); // s553 add + r1 = rotl_imm(r1, 1u); // s554 rotl + r7 = rotr_var(r7, r3); // s555 rotr + r7 = rotr_var(r7, r3); // s556 rotr + r6 = r2 * r0 + r6; // s557 mad + r6 = r6 ^ r1; // s558 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r5 = r5 ^ t_; } // s559 shfl + r5 = r5 ^ r3; // s560 xor + r5 = r5 * r1; // s561 mul + r3 = rotl_imm(r3, 31u); // s562 rotl + r6 = rotr_var(r6, r2); // s563 rotr + r7 = r7 | r2; // s564 or + r6 = rotr_var(r6, r0); // s565 rotr + r2 = r2 * r0; // s566 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 2u); r4 = r4 ^ t_; } // s567 shfl + r3 = r3 * r0; // s568 mul + r4 = r4 + r2 + ((((sel >> 9u) & 1u) != 0u) ? 0xa3149efau : 0xd9160c83u); // s569 add + r4 = mul_hi(r4, r2); // s570 mulhi + r3 = r3 + r0 + ((((sel >> 10u) & 1u) != 0u) ? 0x9cab407bu : 0x3bdc971cu); // s571 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 16u); r1 = r1 ^ t_; } // s572 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 4u); r2 = r2 ^ t_; } // s573 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r2 = r2 ^ t_; } // s574 shfl + r0 = r0 ^ r7; // s575 xor + r0 = r0 + r5 + ((((sel >> 27u) & 1u) != 0u) ? 0x747b0838u : 0x17979608u); // s576 add + r0 = r0 ^ r4; // s577 xor + r6 = r6 - r1; // s578 sub + r4 = rotr_var(r4, r2); // s579 rotr + r2 = r2 ^ r3; // s580 xor + r6 = r7 * r2 + r6; // s581 mad + r5 = r5 + r2 + ((((sel >> 7u) & 1u) != 0u) ? 0x02246c0cu : 0x1c10ec5cu); // s582 add + r3 = mul_hi(r3, r6); // s583 mulhi + r2 = r2 ^ r5; // s584 xor + r6 = rotl_imm(r6, 24u); // s585 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 8u); r3 = r3 ^ t_; } // s586 shfl + r1 = r2 * r6 + r1; // s587 mad + r3 = r3 + r7 + ((((sel >> 21u) & 1u) != 0u) ? 0xbea44bd0u : 0x88758873u); // s588 add + r1 = rotl_imm(r1, 30u); // s589 rotl + r7 = r7 * r1; // s590 mul + r3 = r3 + r6 + ((((sel >> 10u) & 1u) != 0u) ? 0x8e0eb890u : 0xf436bb64u); // s591 add + r7 = r6 * r1 + r7; // s592 mad + r0 = r3 * r5 + r0; // s593 mad + r5 = rotr_var(r5, r4); // s594 rotr + r4 = r4 | r0; // s595 or + r6 = r3 * r0 + r6; // s596 mad + r2 = r2 + r1 + ((((sel >> 31u) & 1u) != 0u) ? 0x29b853b3u : 0xb465e47eu); // s597 add + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 16u); r1 = r1 ^ t_; } // s598 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 4u); r4 = r4 ^ t_; } // s599 shfl + r6 = r2 * r0 + r6; // s600 mad + r5 = mul_hi(r5, r0); // s601 mulhi + r6 = r6 * r7; // s602 mul + r4 = r4 | r7; // s603 or + r7 = r7 - r0; // s604 sub + r7 = rotr_var(r7, r4); // s605 rotr + r4 = r0 * r3 + r4; // s606 mad + r4 = mul_hi(r4, r3); // s607 mulhi + r0 = r0 + r1 + ((((sel >> 28u) & 1u) != 0u) ? 0xb7536963u : 0x22ce199du); // s608 add + r2 = r2 - r5; // s609 sub + r2 = r2 ^ r0; // s610 xor + r5 = r5 * r4; // s611 mul + r3 = rotl_imm(r3, 25u); // s612 rotl + r7 = rotl_imm(r7, 13u); // s613 rotl + r4 = r4 * r7; // s614 mul + r5 = r4 * r2 + r5; // s615 mad + r0 = r0 ^ r5; // s616 xor + r7 = r5 * r4 + r7; // s617 mad + r6 = r6 - r4; // s618 sub + r3 = r3 * r4; // s619 mul + r1 = rotl_imm(r1, 24u); // s620 rotl + r1 = r1 ^ r2; // s621 xor + r4 = r4 | r3; // s622 or + r7 = r7 * r2; // s623 mul + r6 = r6 + r1 + ((((sel >> 20u) & 1u) != 0u) ? 0xe37b1e20u : 0x2dbf6ed0u); // s624 add + r4 = r4 ^ r5; // s625 xor + r4 = r6 * r2 + r4; // s626 mad + r1 = r1 ^ r6; // s627 xor + r6 = r6 + r3 + ((((sel >> 12u) & 1u) != 0u) ? 0xf5a2a9f7u : 0x9dc2b9d0u); // s628 add + r7 = r7 - r5; // s629 sub + r1 = mul_hi(r1, r7); // s630 mulhi + r1 = rotr_var(r1, r3); // s631 rotr + r4 = r4 | r6; // s632 or + r2 = r2 + r5 + ((((sel >> 24u) & 1u) != 0u) ? 0x982bfc08u : 0x9c1fba1bu); // s633 add + r6 = r6 * r5; // s634 mul + r7 = r2 * r3 + r7; // s635 mad + r7 = mul_hi(r7, r4); // s636 mulhi + r5 = r5 ^ r0; // s637 xor + r0 = r0 * r1; // s638 mul + r4 = r4 ^ r6; // s639 xor + r6 = r6 - r4; // s640 sub + r6 = mul_hi(r6, r4); // s641 mulhi + r4 = r4 - r0; // s642 sub + r7 = r7 - r5; // s643 sub + r3 = r0 * r7 + r3; // s644 mad + r3 = r3 | r5; // s645 or + r0 = r0 - r4; // s646 sub + r7 = r7 | r5; // s647 or + r7 = rotl_imm(r7, 1u); // s648 rotl + r5 = r5 + r6 + ((((sel >> 31u) & 1u) != 0u) ? 0x6e5d517fu : 0x9f5e0d19u); // s649 add + r1 = r1 | r2; // s650 or + r3 = rotl_imm(r3, 29u); // s651 rotl + r2 = r2 + r4 + ((((sel >> 2u) & 1u) != 0u) ? 0x30faf9c6u : 0xb53f6e74u); // s652 add + r0 = rotl_imm(r0, 21u); // s653 rotl + r1 = r1 ^ r3; // s654 xor + r4 = r7 * r2 + r4; // s655 mad + r4 = r4 - r6; // s656 sub + r4 = r4 * r6; // s657 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r2 = r2 ^ t_; } // s658 shfl + r7 = rotl_imm(r7, 31u); // s659 rotl + r4 = r4 ^ r6; // s660 xor + r1 = r1 - r3; // s661 sub + r3 = r3 * r6; // s662 mul + r5 = r5 * r3; // s663 mul + r7 = r7 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x8941d2e7u : 0x016e0094u); // s664 add + r1 = r1 ^ r2; // s665 xor + r1 = r1 - r0; // s666 sub + r4 = r4 ^ r7; // s667 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 1u); r7 = r7 ^ t_; } // s668 shfl + r1 = rotr_var(r1, r4); // s669 rotr + r2 = r2 + r3 + ((((sel >> 14u) & 1u) != 0u) ? 0x15289435u : 0x9af12ca6u); // s670 add + r2 = rotr_var(r2, r4); // s671 rotr + r4 = r6 * r7 + r4; // s672 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r2 = r2 ^ t_; } // s673 shfl + r6 = r4 * r2 + r6; // s674 mad + r2 = r4 * r6 + r2; // s675 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 16u); r3 = r3 ^ t_; } // s676 shfl + r1 = rotr_var(r1, r0); // s677 rotr + r0 = r0 - r2; // s678 sub + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 16u); r5 = r5 ^ t_; } // s679 shfl + r1 = r1 ^ r0; // s680 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r1 = r1 ^ t_; } // s681 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r0 = r0 ^ t_; } // s682 shfl + r2 = r3 * r3 + r2; // s683 mad + r4 = r4 - r6; // s684 sub + r5 = r5 ^ r3; // s685 xor + r2 = r2 - r5; // s686 sub + r4 = r4 - r5; // s687 sub + r5 = r4 * r7 + r5; // s688 mad + r6 = r6 * r7; // s689 mul + r1 = r1 * r5; // s690 mul + r4 = rotr_var(r4, r3); // s691 rotr + r2 = r2 ^ r4; // s692 xor + r0 = rotl_imm(r0, 2u); // s693 rotl + r5 = r5 + r2 + ((((sel >> 23u) & 1u) != 0u) ? 0x49801084u : 0x4fc762c9u); // s694 add + r0 = r0 + r4 + ((((sel >> 14u) & 1u) != 0u) ? 0x5f403cd5u : 0x626c00f5u); // s695 add + r6 = rotl_imm(r6, 25u); // s696 rotl + r3 = r3 ^ r7; // s697 xor + r0 = r0 * r2; // s698 mul + r5 = rotr_var(r5, r1); // s699 rotr + r3 = r3 ^ r7; // s700 xor + r4 = r4 | r3; // s701 or + r7 = r7 * r3; // s702 mul + r4 = rotl_imm(r4, 24u); // s703 rotl + r5 = r5 + r4 + ((((sel >> 17u) & 1u) != 0u) ? 0xad5e1851u : 0xc08bb414u); // s704 add + r0 = r6 * r5 + r0; // s705 mad + r4 = mul_hi(r4, r1); // s706 mulhi + r4 = rotr_var(r4, r3); // s707 rotr + r3 = rotr_var(r3, r6); // s708 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 16u); r6 = r6 ^ t_; } // s709 shfl + r3 = r2 * r6 + r3; // s710 mad + r1 = r1 * r4; // s711 mul + r3 = r3 + r5 + ((((sel >> 13u) & 1u) != 0u) ? 0x407f7c4du : 0xdc55338fu); // s712 add + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 2u); r6 = r6 ^ t_; } // s713 shfl + r1 = r1 ^ r0; // s714 xor + r7 = r1 * r1 + r7; // s715 mad + r4 = r4 | r0; // s716 or + r6 = r6 * r4; // s717 mul + r0 = r0 - r5; // s718 sub + r1 = r1 ^ r4; // s719 xor + r4 = mul_hi(r4, r6); // s720 mulhi + r1 = r1 + r0 + ((((sel >> 13u) & 1u) != 0u) ? 0xc2093fcau : 0xb2ce569eu); // s721 add + r4 = mul_hi(r4, r2); // s722 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 16u); r6 = r6 ^ t_; } // s723 shfl + r5 = r3 * r0 + r5; // s724 mad + r5 = mul_hi(r5, r0); // s725 mulhi + r2 = rotr_var(r2, r5); // s726 rotr + r5 = r5 + r0 + ((((sel >> 20u) & 1u) != 0u) ? 0x48cdf1c1u : 0x4e8aaad5u); // s727 add + r1 = r1 * r0; // s728 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 1u); r3 = r3 ^ t_; } // s729 shfl + r4 = r4 * r6; // s730 mul + r4 = r4 - r6; // s731 sub + r4 = r4 ^ r2; // s732 xor + r5 = r5 * r6; // s733 mul + r7 = rotr_var(r7, r3); // s734 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 1u); r1 = r1 ^ t_; } // s735 shfl + r1 = mul_hi(r1, r0); // s736 mulhi + r2 = r2 * r6; // s737 mul + r5 = rotl_imm(r5, 27u); // s738 rotl + r2 = mul_hi(r2, r3); // s739 mulhi + r5 = r3 * r5 + r5; // s740 mad + r2 = rotl_imm(r2, 11u); // s741 rotl + r6 = r6 | r2; // s742 or + r2 = r2 ^ r3; // s743 xor + r3 = r3 * r1; // s744 mul + r4 = mul_hi(r4, r2); // s745 mulhi + r5 = r5 ^ r6; // s746 xor + r6 = r6 + r7 + ((((sel >> 11u) & 1u) != 0u) ? 0x0d6b844eu : 0x78fc162du); // s747 add + r1 = rotl_imm(r1, 27u); // s748 rotl + r4 = rotr_var(r4, r1); // s749 rotr + r5 = r5 ^ r7; // s750 xor + r4 = rotr_var(r4, r3); // s751 rotr + r5 = r5 * r2; // s752 mul + r1 = r6 * r7 + r1; // s753 mad + r0 = r0 ^ r1; // s754 xor + r7 = r7 - r1; // s755 sub + r0 = r0 + r4 + ((((sel >> 5u) & 1u) != 0u) ? 0xb74ac71eu : 0x68aab88bu); // s756 add + r7 = r7 + r5 + ((((sel >> 0u) & 1u) != 0u) ? 0xf81f5b66u : 0xba5c123au); // s757 add + r0 = r7 * r2 + r0; // s758 mad + r1 = r1 | r0; // s759 or + r4 = mul_hi(r4, r6); // s760 mulhi + r0 = mul_hi(r0, r7); // s761 mulhi + r3 = rotr_var(r3, r4); // s762 rotr + r3 = rotl_imm(r3, 30u); // s763 rotl + r6 = r6 * r2; // s764 mul + r6 = r6 ^ r4; // s765 xor + r3 = r3 + r4 + ((((sel >> 0u) & 1u) != 0u) ? 0x96dabea6u : 0x6eb1d82au); // s766 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 1u); r0 = r0 ^ t_; } // s767 shfl + r3 = rotl_imm(r3, 8u); // s768 rotl + r7 = r7 * r4; // s769 mul + r6 = r1 * r2 + r6; // s770 mad + r2 = r2 ^ r7; // s771 xor + r6 = r6 * r0; // s772 mul + r2 = r2 - r1; // s773 sub + r1 = r0 * r1 + r1; // s774 mad + r5 = mul_hi(r5, r7); // s775 mulhi + r0 = rotr_var(r0, r4); // s776 rotr + r6 = r6 ^ r0; // s777 xor + r4 = mul_hi(r4, r7); // s778 mulhi + r1 = r3 * r0 + r1; // s779 mad + r6 = r6 + r4 + ((((sel >> 2u) & 1u) != 0u) ? 0x903f3f77u : 0x11d7b79au); // s780 add + r4 = r4 ^ r7; // s781 xor + r1 = r1 + r2 + ((((sel >> 14u) & 1u) != 0u) ? 0x2ca81d8du : 0x1791eaddu); // s782 add + r2 = rotr_var(r2, r1); // s783 rotr + r4 = r4 * r6; // s784 mul + r1 = r1 ^ r6; // s785 xor + r4 = r4 - r0; // s786 sub + r3 = r3 ^ r4; // s787 xor + r4 = r4 * r1; // s788 mul + r4 = r6 * r7 + r4; // s789 mad + r5 = r5 - r0; // s790 sub + r2 = r2 * r0; // s791 mul + r7 = rotl_imm(r7, 12u); // s792 rotl + r2 = r7 * r3 + r2; // s793 mad + r1 = r4 * r4 + r1; // s794 mad + r6 = r6 + r4 + ((((sel >> 15u) & 1u) != 0u) ? 0xf66fad29u : 0xc08797bbu); // s795 add + r1 = r1 - r4; // s796 sub + r5 = r5 * r2; // s797 mul + r5 = r5 ^ r2; // s798 xor + r0 = r0 * r1; // s799 mul + r6 = r6 + r4 + ((((sel >> 13u) & 1u) != 0u) ? 0x2d82a681u : 0x6d4a6371u); // s800 add + r1 = r6 * r1 + r1; // s801 mad + r0 = r0 - r2; // s802 sub + r6 = r6 ^ r2; // s803 xor + r7 = rotl_imm(r7, 24u); // s804 rotl + r6 = r6 ^ r7; // s805 xor + r7 = r7 | r0; // s806 or + r0 = rotl_imm(r0, 5u); // s807 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 2u); r1 = r1 ^ t_; } // s808 shfl + r4 = r1 * r5 + r4; // s809 mad + r0 = r0 + r2 + ((((sel >> 14u) & 1u) != 0u) ? 0x63e62197u : 0x0092eb62u); // s810 add + r5 = r5 - r3; // s811 sub + r2 = r1 * r5 + r2; // s812 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 16u); r6 = r6 ^ t_; } // s813 shfl + r7 = r5 * r1 + r7; // s814 mad + r0 = mul_hi(r0, r7); // s815 mulhi + r2 = r2 | r1; // s816 or + r7 = mul_hi(r7, r3); // s817 mulhi + r2 = r2 ^ r4; // s818 xor + r4 = r4 + r3 + ((((sel >> 0u) & 1u) != 0u) ? 0x27d94f57u : 0xbb69174fu); // s819 add + r5 = r5 + r3 + ((((sel >> 1u) & 1u) != 0u) ? 0x82285691u : 0xda6759f2u); // s820 add + r1 = r1 + r3 + ((((sel >> 31u) & 1u) != 0u) ? 0xe50565d8u : 0x9ad4b47fu); // s821 add + r5 = rotl_imm(r5, 6u); // s822 rotl + r3 = r3 - r0; // s823 sub + r6 = rotl_imm(r6, 12u); // s824 rotl + r4 = r4 | r5; // s825 or + r3 = r3 ^ r2; // s826 xor + r4 = r4 + r0 + ((((sel >> 26u) & 1u) != 0u) ? 0xffcab83au : 0xca1e80fbu); // s827 add + r3 = r3 | r7; // s828 or + r1 = r5 * r7 + r1; // s829 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 16u); r6 = r6 ^ t_; } // s830 shfl + r1 = r1 - r0; // s831 sub + r0 = rotr_var(r0, r2); // s832 rotr + r1 = mul_hi(r1, r0); // s833 mulhi + r6 = mul_hi(r6, r4); // s834 mulhi + r6 = rotl_imm(r6, 2u); // s835 rotl + r4 = r4 | r6; // s836 or + r6 = rotl_imm(r6, 23u); // s837 rotl + r4 = r7 * r4 + r4; // s838 mad + r0 = r0 | r1; // s839 or + r5 = mul_hi(r5, r3); // s840 mulhi + r7 = r4 * r6 + r7; // s841 mad + r1 = r1 + r4 + ((((sel >> 21u) & 1u) != 0u) ? 0x1bc9f95du : 0xcfb90e90u); // s842 add + r1 = r1 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0xf9bd620fu : 0x0b4758b6u); // s843 add + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r2 = r2 ^ t_; } // s844 shfl + r3 = r1 * r7 + r3; // s845 mad + r5 = r5 * r2; // s846 mul + r0 = rotl_imm(r0, 21u); // s847 rotl + r7 = r7 ^ r1; // s848 xor + r3 = r3 + r4 + ((((sel >> 18u) & 1u) != 0u) ? 0x697a4946u : 0x41fdc15au); // s849 add + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 4u); r0 = r0 ^ t_; } // s850 shfl + r1 = rotr_var(r1, r5); // s851 rotr + r5 = r5 | r6; // s852 or + r6 = r6 - r2; // s853 sub + r2 = r2 ^ r6; // s854 xor + r4 = r4 - r6; // s855 sub + r6 = r4 * r6 + r6; // s856 mad + r4 = r4 * r0; // s857 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r2 = r2 ^ t_; } // s858 shfl + r3 = r3 * r4; // s859 mul + r3 = r1 * r7 + r3; // s860 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 2u); r3 = r3 ^ t_; } // s861 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r7 = r7 ^ t_; } // s862 shfl + r0 = r2 * r2 + r0; // s863 mad + r6 = r6 ^ r0; // s864 xor + r6 = r6 + r2 + ((((sel >> 2u) & 1u) != 0u) ? 0x7fedd7f3u : 0x90656f74u); // s865 add + r3 = r3 ^ r2; // s866 xor + r1 = r1 | r4; // s867 or + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 2u); r6 = r6 ^ t_; } // s868 shfl + r1 = mul_hi(r1, r0); // s869 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r3 = r3 ^ t_; } // s870 shfl + r0 = r0 - r3; // s871 sub + r6 = r6 + r1 + ((((sel >> 11u) & 1u) != 0u) ? 0xbe1b480au : 0xa5c0b461u); // s872 add + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r3 = r3 ^ t_; } // s873 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 1u); r5 = r5 ^ t_; } // s874 shfl + r2 = mul_hi(r2, r4); // s875 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 4u); r5 = r5 ^ t_; } // s876 shfl + r5 = rotl_imm(r5, 14u); // s877 rotl + r2 = r2 ^ r7; // s878 xor + r7 = r7 ^ r0; // s879 xor + r0 = r0 * r2; // s880 mul + r4 = r4 * r2; // s881 mul + r7 = r7 * r6; // s882 mul + r4 = mul_hi(r4, r5); // s883 mulhi + r0 = r0 - r4; // s884 sub + r0 = r0 ^ r5; // s885 xor + r6 = r6 * r5; // s886 mul + r1 = r1 + r5 + ((((sel >> 14u) & 1u) != 0u) ? 0x7007f98fu : 0xe806fcecu); // s887 add + r3 = r3 * r1; // s888 mul + r5 = r5 ^ r3; // s889 xor + r6 = r6 | r2; // s890 or + r1 = r1 * r2; // s891 mul + r5 = r5 + r7 + ((((sel >> 3u) & 1u) != 0u) ? 0xf3c87e02u : 0x89a8551eu); // s892 add + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 16u); r2 = r2 ^ t_; } // s893 shfl + r1 = r1 + r3 + ((((sel >> 13u) & 1u) != 0u) ? 0xc315f5deu : 0xba1369dbu); // s894 add + r5 = r0 * r3 + r5; // s895 mad + r5 = rotr_var(r5, r2); // s896 rotr + r1 = r1 ^ r0; // s897 xor + r5 = r5 ^ r1; // s898 xor + r5 = rotr_var(r5, r1); // s899 rotr + r3 = r6 * r6 + r3; // s900 mad + r0 = rotl_imm(r0, 8u); // s901 rotl + r1 = r1 | r0; // s902 or + r1 = r1 + r2 + ((((sel >> 3u) & 1u) != 0u) ? 0x1c355a71u : 0x260e6848u); // s903 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 16u); r7 = r7 ^ t_; } // s904 shfl + r1 = mul_hi(r1, r3); // s905 mulhi + r1 = rotr_var(r1, r4); // s906 rotr + r6 = r6 + r0 + ((((sel >> 8u) & 1u) != 0u) ? 0x0c74a1a8u : 0xa74fd2b1u); // s907 add + r6 = rotr_var(r6, r2); // s908 rotr + r4 = rotl_imm(r4, 12u); // s909 rotl + r5 = r5 + r3 + ((((sel >> 29u) & 1u) != 0u) ? 0xa49b5d73u : 0xe5fb043eu); // s910 add + r3 = r3 ^ r0; // s911 xor + r3 = rotr_var(r3, r4); // s912 rotr + r6 = rotr_var(r6, r0); // s913 rotr + r2 = r2 ^ r5; // s914 xor + r0 = r0 * r7; // s915 mul + r3 = r3 ^ r0; // s916 xor + r5 = r1 * r7 + r5; // s917 mad + r3 = r3 + r4 + ((((sel >> 2u) & 1u) != 0u) ? 0xeb76e56cu : 0x264cb47bu); // s918 add + r3 = mul_hi(r3, r4); // s919 mulhi + r5 = r5 + r6 + ((((sel >> 9u) & 1u) != 0u) ? 0x2aab9631u : 0x418baa72u); // s920 add + r5 = mul_hi(r5, r1); // s921 mulhi + r7 = r7 - r3; // s922 sub + r6 = r6 + r1 + ((((sel >> 2u) & 1u) != 0u) ? 0x98e6b26du : 0x3696a894u); // s923 add + r6 = r3 * r1 + r6; // s924 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r2 = r2 ^ t_; } // s925 shfl + r6 = r6 ^ r1; // s926 xor + r4 = r4 ^ r3; // s927 xor + r0 = r0 + r4 + ((((sel >> 7u) & 1u) != 0u) ? 0x142778eeu : 0x0468c062u); // s928 add + r7 = r7 + r3 + ((((sel >> 29u) & 1u) != 0u) ? 0x4eae212du : 0x0af82291u); // s929 add + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 16u); r4 = r4 ^ t_; } // s930 shfl + r7 = r7 + r2 + ((((sel >> 20u) & 1u) != 0u) ? 0x8d2a8b36u : 0x17de5e29u); // s931 add + r5 = r5 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0xe2d2d7d5u : 0x686794a8u); // s932 add + r0 = mul_hi(r0, r3); // s933 mulhi + r4 = r4 + r0 + ((((sel >> 10u) & 1u) != 0u) ? 0xe3c3c6f9u : 0x66278068u); // s934 add + r6 = rotl_imm(r6, 22u); // s935 rotl + r0 = r0 | r2; // s936 or + r4 = r4 * r3; // s937 mul + r3 = r3 | r6; // s938 or + r7 = rotl_imm(r7, 28u); // s939 rotl + r0 = r0 + r6 + ((((sel >> 20u) & 1u) != 0u) ? 0xc2296063u : 0xc2d02ca6u); // s940 add + r1 = r1 + r5 + ((((sel >> 14u) & 1u) != 0u) ? 0xef1ca415u : 0x0b3c00e0u); // s941 add + r2 = r2 - r6; // s942 sub + r6 = r6 | r3; // s943 or + r0 = rotl_imm(r0, 2u); // s944 rotl + r2 = r2 * r1; // s945 mul + r0 = r0 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0x06a1321au : 0x11224846u); // s946 add + r3 = r3 * r6; // s947 mul + r5 = r5 - r2; // s948 sub + r5 = r5 + r4 + ((((sel >> 5u) & 1u) != 0u) ? 0x5d3e225cu : 0x461c43d4u); // s949 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 16u); r2 = r2 ^ t_; } // s950 shfl + r7 = r0 * r0 + r7; // s951 mad + r6 = rotr_var(r6, r4); // s952 rotr + r1 = r1 + r0 + ((((sel >> 30u) & 1u) != 0u) ? 0xbb84f628u : 0xd5eed39fu); // s953 add + r4 = rotl_imm(r4, 31u); // s954 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 16u); r1 = r1 ^ t_; } // s955 shfl + r2 = r2 - r6; // s956 sub + r4 = r4 ^ r2; // s957 xor + r0 = r0 ^ r2; // s958 xor + r1 = r1 + r0 + ((((sel >> 28u) & 1u) != 0u) ? 0x374c0426u : 0x519d72f7u); // s959 add + r5 = r5 * r4; // s960 mul + r5 = r5 - r7; // s961 sub + r2 = r2 ^ r6; // s962 xor + r4 = r4 ^ r1; // s963 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 16u); r2 = r2 ^ t_; } // s964 shfl + r7 = mul_hi(r7, r3); // s965 mulhi + r4 = rotl_imm(r4, 12u); // s966 rotl + r4 = r4 + r6 + ((((sel >> 26u) & 1u) != 0u) ? 0x03b88592u : 0x151dae18u); // s967 add + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r1 = r1 ^ t_; } // s968 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 8u); r3 = r3 ^ t_; } // s969 shfl + r2 = r2 ^ r7; // s970 xor + r5 = r3 * r4 + r5; // s971 mad + r0 = r0 ^ r3; // s972 xor + r2 = r2 ^ r5; // s973 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 4u); r1 = r1 ^ t_; } // s974 shfl + r5 = r1 * r4 + r5; // s975 mad + r2 = rotl_imm(r2, 19u); // s976 rotl + r1 = r1 - r4; // s977 sub + r5 = rotr_var(r5, r4); // s978 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 16u); r2 = r2 ^ t_; } // s979 shfl + r6 = r6 + r7 + ((((sel >> 28u) & 1u) != 0u) ? 0x1fdee45eu : 0x16220e61u); // s980 add + r4 = rotr_var(r4, r6); // s981 rotr + r6 = mul_hi(r6, r3); // s982 mulhi + r5 = rotl_imm(r5, 17u); // s983 rotl + r2 = r7 * r1 + r2; // s984 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 8u); r4 = r4 ^ t_; } // s985 shfl + r3 = r3 ^ r1; // s986 xor + r4 = r4 + r0 + ((((sel >> 27u) & 1u) != 0u) ? 0x44adc457u : 0x6cd6b697u); // s987 add + r1 = r1 * r5; // s988 mul + r4 = r4 + r2 + ((((sel >> 2u) & 1u) != 0u) ? 0x0a06a223u : 0x1103d2d2u); // s989 add + r4 = r4 * r1; // s990 mul + r4 = r5 * r1 + r4; // s991 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r3 = r3 ^ t_; } // s992 shfl + r1 = r1 - r3; // s993 sub + r4 = r7 * r5 + r4; // s994 mad + r1 = mul_hi(r1, r2); // s995 mulhi + r2 = r1 * r0 + r2; // s996 mad + r3 = rotl_imm(r3, 31u); // s997 rotl + r4 = r4 - r3; // s998 sub + r5 = rotr_var(r5, r3); // s999 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 4u); r4 = r4 ^ t_; } // s1000 shfl + r2 = r2 - r5; // s1001 sub + r3 = r4 * r4 + r3; // s1002 mad + r7 = r5 * r1 + r7; // s1003 mad + r7 = r7 + r4 + ((((sel >> 29u) & 1u) != 0u) ? 0x0044887fu : 0xa9c9d8a9u); // s1004 add + r4 = mul_hi(r4, r0); // s1005 mulhi + r4 = rotl_imm(r4, 21u); // s1006 rotl + r3 = r3 * r1; // s1007 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 2u); r1 = r1 ^ t_; } // s1008 shfl + r0 = mul_hi(r0, r6); // s1009 mulhi + r0 = r0 ^ r3; // s1010 xor + r5 = r5 | r4; // s1011 or + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 4u); r1 = r1 ^ t_; } // s1012 shfl + r2 = r2 + r4 + ((((sel >> 4u) & 1u) != 0u) ? 0x6b70e2c7u : 0xfa1574e3u); // s1013 add + r5 = rotr_var(r5, r7); // s1014 rotr + r0 = rotr_var(r0, r7); // s1015 rotr + r5 = r5 - r7; // s1016 sub + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 16u); r4 = r4 ^ t_; } // s1017 shfl + r6 = mul_hi(r6, r7); // s1018 mulhi + r0 = rotr_var(r0, r1); // s1019 rotr + r2 = r2 ^ r0; // s1020 xor + r4 = r5 * r1 + r4; // s1021 mad + r6 = r6 | r2; // s1022 or + r3 = r3 ^ r0; // s1023 xor + } + } + uint lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((ulong)hi << 32) | (ulong)lo; +} + +#if IGNEUM_EXCHANGE != 0 +// Reports the sub-group size this device uses for a work-group of IGNEUM_GROUP items. host.c runs it only when the +// per-kernel query (clGetKernelSubGroupInfoKHR on igneum_hash) is unavailable; that query is preferred because a +// compiler may pick a different wave width per kernel (RDNA: wave32 or wave64). See WAVEFRONT.md. +IGNEUM_KERNEL_HASH void igneum_probe_subgroup(__global uint* out) { + if (get_local_id(0) == 0u) { out[0] = get_sub_group_size(); out[1] = get_num_sub_groups(); } +} +#endif diff --git a/proto-cuda/packs-ca3-shadow/sh1024x3/kernel.cu b/proto-cuda/packs-ca3-shadow/sh1024x3/kernel.cu new file mode 100644 index 000000000..6f0bbdbfd --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh1024x3/kernel.cu @@ -0,0 +1,1191 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Bit-exact twin of the Metal kernel for the same seed (see proto-cuda/CHECKLIST.md and program.metal). +// Compiled ahead of time by nvcc together with proto-cuda/host.cu. No NVRTC. +#include +#include +#include "program.h" +#include "memhard.h" + +__device__ __forceinline__ uint32_t splitmix32(uint32_t x) { + x ^= x >> 16; x *= 0x7feb352du; + x ^= x >> 15; x *= 0x846ca68bu; + x ^= x >> 16; + return x; +} +// n is a literal in 1..31 at every call site, so both shift amounts are in 1..31. +__device__ __forceinline__ uint32_t rotl_imm(uint32_t x, uint32_t n) { return (x << n) | (x >> (32u - n)); } +// n is masked to 0..31; the second shift amount is masked too, so n == 0 gives x. +__device__ __forceinline__ uint32_t rotr_var(uint32_t x, uint32_t n) { n &= 31u; return (x >> n) | (x << ((32u - n) & 31u)); } +__device__ __forceinline__ uint32_t ds_elem(uint32_t i, uint32_t d0, uint32_t d1) { + uint32_t x = i ^ d0; + x *= 0x9E3779B1u; x ^= x >> 15; + x += d1; + x *= 0x85EBCA77u; x ^= x >> 13; + x *= 0xC2B2AE3Du; x ^= x >> 16; + return x; +} + +// Memory-hard dataset (MEMHARD.md). One thread per cache segment; one thread per 64-byte dataset item. +// The core functions (mh_cache_segment, mh_item) are in memhard.h and are also compiled for the host. +__global__ void igneum_cache_fill(uint32_t* cache, uint32_t nSegments) { + uint32_t seg = blockIdx.x * blockDim.x + threadIdx.x; + if (seg < nSegments) mh_cache_segment(cache, seg); +} +__global__ void igneum_build(uint32_t* ds, const uint32_t* cache, uint32_t nItems) { + uint32_t t = blockIdx.x * blockDim.x + threadIdx.x; + if (t < nItems) { + uint32_t s[16]; + mh_item(cache, t, s); + uint32_t* d = ds + (size_t)t * 16u; + for (uint32_t i = 0u; i < 16u; ++i) d[i] = s[i]; + } +} + +// One hash per thread. blockDim.x is a multiple of 32; lane = threadIdx.x & 31 and every +// __shfl_xor_sync stays inside the lane's own warp, exactly like simd_shuffle_xor inside a +// 32-wide Metal SIMD group. Control flow is uniform, so the full 0xffffffff member mask is valid. +__global__ void igneum_hash(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask) { + uint32_t gid = blockIdx.x * blockDim.x + threadIdx.x; + uint32_t nonce = baseNonce + gid; + uint32_t r0, r1, r2, r3, r4, r5, r6, r7; + { uint32_t x = nonce ^ 0x67a9a7beu; x += 0x9e3779b9u; x = splitmix32(x); r0 = x ^ 0x1a155b25u; } // SEEDW[0], 0x9e3779b9u * 1u, SEEDW[1] + { uint32_t x = nonce ^ 0x1a155b25u; x += 0x3c6ef372u; x = splitmix32(x); r1 = x ^ 0xfddfb732u; } // SEEDW[1], 0x9e3779b9u * 2u, SEEDW[2] + { uint32_t x = nonce ^ 0xfddfb732u; x += 0xdaa66d2bu; x = splitmix32(x); r2 = x ^ 0x4b5af2e8u; } // SEEDW[2], 0x9e3779b9u * 3u, SEEDW[3] + { uint32_t x = nonce ^ 0x4b5af2e8u; x += 0x78dde6e4u; x = splitmix32(x); r3 = x ^ 0xc55caf33u; } // SEEDW[3], 0x9e3779b9u * 4u, SEEDW[4] + { uint32_t x = nonce ^ 0xc55caf33u; x += 0x1715609du; x = splitmix32(x); r4 = x ^ 0xa27c13b7u; } // SEEDW[4], 0x9e3779b9u * 5u, SEEDW[5] + { uint32_t x = nonce ^ 0xa27c13b7u; x += 0xb54cda56u; x = splitmix32(x); r5 = x ^ 0x06628a48u; } // SEEDW[5], 0x9e3779b9u * 6u, SEEDW[6] + { uint32_t x = nonce ^ 0x06628a48u; x += 0x5384540fu; x = splitmix32(x); r6 = x ^ 0x03852469u; } // SEEDW[6], 0x9e3779b9u * 7u, SEEDW[7] + { uint32_t x = nonce ^ 0x03852469u; x += 0xf1bbcdc8u; x = splitmix32(x); r7 = x ^ 0x67a9a7beu; } // SEEDW[7], 0x9e3779b9u * 8u, SEEDW[0] + + for (uint32_t it = 0u; it < 8u; ++it) { + uint32_t sel = r0; + r2 = r3 * r4 + r2; // 0 mad + r2 = r1 * r1 + r2; // 1 mad + r2 = r3 * r2 + r2; // 2 mad + r3 = r3 ^ r5; // 3 xor + r7 = r7 ^ ds[r2 & mask]; // 4 load + r5 = r5 ^ ds[r7 & mask]; // 5 load + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r4, 8); // 6 shfl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r3, 8); // 7 shfl + r1 = __umulhi(r1, r5); // 8 mulhi + r6 = rotr_var(r6, r3); // 9 rotr + r3 = r3 | r4; // 10 or + r4 = r4 ^ ds[r3 & mask]; // 11 load + r0 = __umulhi(r0, r4); // 12 mulhi + r5 = r5 + r1 + ((((sel >> 30u) & 1u) != 0u) ? 0xd3177981u : 0xc7934706u); // 13 add + r0 = r0 ^ ds[r4 & mask]; // 14 load + r2 = r2 - r4; // 15 sub + r2 = r2 ^ ds[r0 & mask]; // 16 load + r7 = r7 ^ ds[r2 & mask]; // 17 load + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r3, 4); // 18 shfl + r5 = r5 * r0; // 19 mul + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // 20 shfl + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 16); // 21 shfl + r6 = __umulhi(r6, r2); // 22 mulhi + r6 = r6 ^ ds[r1 & mask]; // 23 load + r5 = r5 * r0; // 24 mul + r5 = rotl_imm(r5, 19u); // 25 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r6, 2); // 26 shfl + r0 = r0 ^ r5; // 27 xor + r0 = r0 ^ r4; // 28 xor + r3 = r3 - r0; // 29 sub + r5 = r5 * r1; // 30 mul + r7 = r7 ^ ds[r2 & mask]; // 31 load + r1 = r1 ^ ds[r0 & mask]; // 32 load + r5 = r5 ^ r6; // 33 xor + r5 = r5 ^ ds[r1 & mask]; // 34 load + r0 = __umulhi(r0, r5); // 35 mulhi + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // 36 shfl + r7 = r7 ^ ds[r0 & mask]; // 37 load + r3 = r3 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0x230c005cu : 0x75ba2fadu); // 38 add + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r5, 4); // 39 shfl + r2 = r2 ^ r5; // 40 xor + r3 = r6 * r3 + r3; // 41 mad + r6 = r6 - r7; // 42 sub + r7 = r7 ^ r0; // 43 xor + r1 = r1 ^ ds[r7 & mask]; // 44 load + r2 = r2 * r3; // 45 mul + r1 = __umulhi(r1, r5); // 46 mulhi + r4 = r4 - r3; // 47 sub + r2 = rotr_var(r2, r6); // 48 rotr + r3 = r3 ^ ds[r5 & mask]; // 49 load + r1 = r1 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x1907970cu : 0x81b8bc2cu); // 50 add + r0 = r0 * r2; // 51 mul + r0 = r0 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x699fd448u : 0x4f92b968u); // 52 add + r1 = r1 + r0 + ((((sel >> 12u) & 1u) != 0u) ? 0x77b1520du : 0x2bb965afu); // 53 add + r7 = rotl_imm(r7, 14u); // 54 rotl + r3 = r3 + r7 + ((((sel >> 1u) & 1u) != 0u) ? 0xa54c55a0u : 0x7b0fe07au); // 55 add + r6 = r6 ^ ds[r7 & mask]; // 56 load + r1 = rotr_var(r1, r5); // 57 rotr + r5 = r5 ^ ds[r4 & mask]; // 58 load + r6 = r6 ^ ds[r2 & mask]; // 59 load + r3 = r5 * r0 + r3; // 60 mad + r5 = r5 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0xad7493e7u : 0xaf9dd72du); // 61 add + r4 = r4 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x1e07c3d9u : 0x89841d87u); // 62 add + r5 = rotl_imm(r5, 19u); // 63 rotl + // latency-shadow block (Counter ASIC 3.0 item 8): 1024 ALU instructions x 3 passes after instruction 63, no load + for (uint32_t sh = 0u; sh < 3u; ++sh) { + r5 = r5 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x8bc12da9u : 0x92199f99u); // s0 add + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x63079e5au : 0x8d72d3adu); // s1 add + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r3, 2); // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + ((((sel >> 31u) & 1u) != 0u) ? 0x5d4c7a60u : 0xb21b4babu); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + ((((sel >> 16u) & 1u) != 0u) ? 0xc88e2942u : 0x2fe0e98bu); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r1, 4); // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r6, 4); // s12 shfl + r1 = r1 + r5 + ((((sel >> 25u) & 1u) != 0u) ? 0xbc48c63eu : 0xbdf8f9a5u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 8); // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + ((((sel >> 1u) & 1u) != 0u) ? 0x96e8f127u : 0x45c37cecu); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = __umulhi(r6, r0); // s28 mulhi + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // s29 shfl + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r6, 1); // s30 shfl + r1 = r1 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0xb1cdb2abu : 0x37985632u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // s33 shfl + r0 = r0 ^ __shfl_xor_sync(0xffffffffu, r3, 4); // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x856e0180u : 0x804e777eu); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xe9bd0cc4u : 0x0b06c8a7u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = __umulhi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = __umulhi(r4, r3); // s44 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xcdcb63f6u : 0xee822e17u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r3, 8); // s47 shfl + r6 = __umulhi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0xd4758987u : 0x3dfad1b6u); // s56 add + r4 = r4 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x0602d6beu : 0xfca75bc2u); // s57 add + r5 = __umulhi(r5, r6); // s58 mulhi + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0x8596687au : 0xd71c02ffu); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r5, 2); // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0x08ac5733u : 0x3c6fe15du); // s72 add + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r2, 8); // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + ((((sel >> 1u) & 1u) != 0u) ? 0xc100b495u : 0x295d5faeu); // s77 add + r3 = __umulhi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + ((((sel >> 15u) & 1u) != 0u) ? 0x5cc59530u : 0x274a9221u); // s81 add + r7 = r7 + r3 + ((((sel >> 5u) & 1u) != 0u) ? 0x141479ecu : 0xc8651f8eu); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r5, 16); // s85 shfl + r3 = r3 ^ r2; // s86 xor + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r7, 2); // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x883c0c92u : 0x53f915c2u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + ((((sel >> 31u) & 1u) != 0u) ? 0x3cc5bd20u : 0xe2be00a5u); // s91 add + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r2, 1); // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + ((((sel >> 17u) & 1u) != 0u) ? 0xbfd646cbu : 0x423fd9c9u); // s101 add + r7 = r7 + r6 + ((((sel >> 11u) & 1u) != 0u) ? 0x19b74a43u : 0x8d3c011du); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + ((((sel >> 15u) & 1u) != 0u) ? 0x7dcb7e18u : 0x8ce14721u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = __umulhi(r2, r0); // s109 mulhi + r1 = __umulhi(r1, r0); // s110 mulhi + r0 = r0 + r2 + ((((sel >> 28u) & 1u) != 0u) ? 0x3c179ad8u : 0x2d9fc6b9u); // s111 add + r2 = __umulhi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + ((((sel >> 22u) & 1u) != 0u) ? 0x47359729u : 0x502138e2u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = __umulhi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r2, 2); // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x6c57e4e7u : 0x33dff776u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + ((((sel >> 30u) & 1u) != 0u) ? 0xe8212c0cu : 0x5db25b34u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = __umulhi(r0, r5); // s138 mulhi + r2 = r2 + r7 + ((((sel >> 10u) & 1u) != 0u) ? 0xd44ff710u : 0x218d4090u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r6, 1); // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + ((((sel >> 29u) & 1u) != 0u) ? 0xb98942fau : 0xf4b1a8deu); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + ((((sel >> 17u) & 1u) != 0u) ? 0x0d48ba42u : 0x2bef10f2u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + ((((sel >> 30u) & 1u) != 0u) ? 0xc98dea9cu : 0xdc5cc080u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0x6c752dcbu : 0x18197438u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + ((((sel >> 3u) & 1u) != 0u) ? 0x8e481727u : 0xf1c46574u); // s163 add + r0 = __umulhi(r0, r4); // s164 mulhi + r2 = r2 + r6 + ((((sel >> 20u) & 1u) != 0u) ? 0x550ab406u : 0xac578137u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + ((((sel >> 14u) & 1u) != 0u) ? 0xaebb5966u : 0xa33e6706u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r0, 8); // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x5bb7550fu : 0xd94d55acu); // s184 add + r3 = r3 | r5; // s185 or + r6 = __umulhi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s188 shfl + r6 = r6 + r5 + ((((sel >> 6u) & 1u) != 0u) ? 0x2a354e2du : 0x89e747feu); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = __umulhi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r5, 16); // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + ((((sel >> 7u) & 1u) != 0u) ? 0x10cfdc71u : 0xea03e8e7u); // s197 add + r7 = r7 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x66e148d3u : 0xa7ee0102u); // s198 add + r5 = r5 - r2; // s199 sub + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s200 shfl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 8); // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0x8558b619u : 0x8379a4deu); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = __umulhi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r0, 4); // s209 shfl + r7 = r7 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0xf4049c4cu : 0xaa8cb14eu); // s210 add + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 16); // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r2, 16); // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = __umulhi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r2, 8); // s222 shfl + r5 = __umulhi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0x2a7fecb2u : 0x1d176220u); // s230 add + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + ((((sel >> 25u) & 1u) != 0u) ? 0xadce39f3u : 0x17dafb4du); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + ((((sel >> 29u) & 1u) != 0u) ? 0x0e7033b6u : 0xf2f77d26u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + ((((sel >> 31u) & 1u) != 0u) ? 0x7b2ff6b7u : 0xfed2da4eu); // s247 add + r0 = r0 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0xb5fad7b1u : 0x03b2891cu); // s248 add + r5 = __umulhi(r5, r4); // s249 mulhi + r5 = r5 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0xa7e71c2fu : 0x042cd6e3u); // s250 add + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r1, 1); // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0xb83d78deu : 0x784a302bu); // s254 add + r2 = r2 - r4; // s255 sub + r3 = r3 - r4; // s256 sub + r2 = r2 * r4; // s257 mul + r4 = r0 * r6 + r4; // s258 mad + r5 = r5 | r0; // s259 or + r4 = r4 ^ r6; // s260 xor + r6 = __umulhi(r6, r3); // s261 mulhi + r2 = r2 * r6; // s262 mul + r5 = rotl_imm(r5, 1u); // s263 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 8); // s264 shfl + r3 = r3 * r2; // s265 mul + r2 = r2 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x99a1d1b6u : 0x3dddf1b2u); // s266 add + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r0, 8); // s267 shfl + r0 = r0 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s268 shfl + r4 = r4 - r2; // s269 sub + r0 = r0 ^ __shfl_xor_sync(0xffffffffu, r5, 1); // s270 shfl + r3 = r3 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x40ca287au : 0xcfc62661u); // s271 add + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r7, 16); // s272 shfl + r1 = r3 * r6 + r1; // s273 mad + r7 = r7 + r6 + ((((sel >> 30u) & 1u) != 0u) ? 0xed4b65adu : 0x44caede3u); // s274 add + r5 = r5 ^ r7; // s275 xor + r2 = r2 * r6; // s276 mul + r2 = r2 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0x0f45ae89u : 0x9aae6c12u); // s277 add + r2 = r2 ^ r6; // s278 xor + r1 = r1 - r2; // s279 sub + r5 = r5 ^ r1; // s280 xor + r7 = r7 ^ r1; // s281 xor + r7 = r7 - r1; // s282 sub + r5 = r5 - r7; // s283 sub + r7 = r0 * r6 + r7; // s284 mad + r5 = __umulhi(r5, r4); // s285 mulhi + r3 = r3 - r5; // s286 sub + r5 = r5 - r1; // s287 sub + r1 = r3 * r7 + r1; // s288 mad + r3 = rotl_imm(r3, 9u); // s289 rotl + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r6, 8); // s290 shfl + r7 = r7 + r2 + ((((sel >> 1u) & 1u) != 0u) ? 0xe086d3b6u : 0x2307120bu); // s291 add + r4 = r4 ^ r3; // s292 xor + r3 = rotl_imm(r3, 14u); // s293 rotl + r5 = r5 - r4; // s294 sub + r2 = __umulhi(r2, r3); // s295 mulhi + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r3, 4); // s296 shfl + r3 = r6 * r1 + r3; // s297 mad + r4 = r4 ^ r1; // s298 xor + r6 = r6 + r3 + ((((sel >> 24u) & 1u) != 0u) ? 0xadbeb223u : 0x4e3a12e5u); // s299 add + r6 = __umulhi(r6, r5); // s300 mulhi + r7 = rotr_var(r7, r5); // s301 rotr + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r4, 16); // s302 shfl + r3 = r3 ^ r4; // s303 xor + r2 = r3 * r1 + r2; // s304 mad + r1 = r1 ^ r7; // s305 xor + r1 = r1 + r0 + ((((sel >> 22u) & 1u) != 0u) ? 0x0d8f1149u : 0x51ab0157u); // s306 add + r2 = r2 + r1 + ((((sel >> 24u) & 1u) != 0u) ? 0x99a96de9u : 0x3b5e8835u); // s307 add + r1 = r5 * r5 + r1; // s308 mad + r2 = r2 * r4; // s309 mul + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r7, 8); // s310 shfl + r0 = r0 ^ r4; // s311 xor + r5 = __umulhi(r5, r2); // s312 mulhi + r7 = r7 + r2 + ((((sel >> 30u) & 1u) != 0u) ? 0x86ddfba7u : 0x81f3297cu); // s313 add + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x38aa230au : 0x838e4a2fu); // s314 add + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r0, 16); // s315 shfl + r7 = r7 - r5; // s316 sub + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r1, 4); // s317 shfl + r1 = r1 + r3 + ((((sel >> 11u) & 1u) != 0u) ? 0xa6399179u : 0xebcad805u); // s318 add + r7 = rotl_imm(r7, 21u); // s319 rotl + r7 = r7 ^ r6; // s320 xor + r7 = r7 | r6; // s321 or + r5 = r5 + r3 + ((((sel >> 25u) & 1u) != 0u) ? 0x4de83051u : 0x4c906f73u); // s322 add + r0 = r0 + r4 + ((((sel >> 14u) & 1u) != 0u) ? 0xd3d821c5u : 0x742ec195u); // s323 add + r6 = r6 ^ r2; // s324 xor + r6 = rotl_imm(r6, 1u); // s325 rotl + r4 = rotl_imm(r4, 24u); // s326 rotl + r4 = r4 | r3; // s327 or + r2 = r1 * r3 + r2; // s328 mad + r2 = r2 ^ r7; // s329 xor + r2 = r2 | r3; // s330 or + r7 = r7 - r1; // s331 sub + r3 = r3 + r6 + ((((sel >> 0u) & 1u) != 0u) ? 0xc06f831eu : 0xb86750e9u); // s332 add + r7 = rotl_imm(r7, 25u); // s333 rotl + r3 = r0 * r0 + r3; // s334 mad + r2 = r2 + r5 + ((((sel >> 28u) & 1u) != 0u) ? 0x5225df1du : 0xb57956eeu); // s335 add + r3 = r1 * r6 + r3; // s336 mad + r4 = r2 * r2 + r4; // s337 mad + r7 = r7 * r2; // s338 mul + r1 = r1 * r6; // s339 mul + r4 = r4 + r5 + ((((sel >> 5u) & 1u) != 0u) ? 0xb73822ceu : 0x23f6425fu); // s340 add + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r7, 2); // s341 shfl + r6 = r6 ^ r5; // s342 xor + r0 = rotl_imm(r0, 13u); // s343 rotl + r0 = rotr_var(r0, r3); // s344 rotr + r1 = r1 - r0; // s345 sub + r6 = rotr_var(r6, r1); // s346 rotr + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r5, 4); // s347 shfl + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r1, 8); // s348 shfl + r5 = r5 ^ r3; // s349 xor + r1 = r4 * r0 + r1; // s350 mad + r3 = rotr_var(r3, r1); // s351 rotr + r1 = rotl_imm(r1, 13u); // s352 rotl + r3 = r3 + r0 + ((((sel >> 26u) & 1u) != 0u) ? 0xfa0c560eu : 0x0dce5917u); // s353 add + r3 = __umulhi(r3, r2); // s354 mulhi + r1 = r2 * r4 + r1; // s355 mad + r0 = r0 ^ r1; // s356 xor + r7 = r7 * r5; // s357 mul + r0 = rotl_imm(r0, 5u); // s358 rotl + r2 = r7 * r7 + r2; // s359 mad + r2 = r2 | r6; // s360 or + r6 = r6 + r1 + ((((sel >> 19u) & 1u) != 0u) ? 0x277e027au : 0x7c83b79au); // s361 add + r0 = r0 * r2; // s362 mul + r3 = r3 * r6; // s363 mul + r2 = rotr_var(r2, r4); // s364 rotr + r5 = r5 + r1 + ((((sel >> 1u) & 1u) != 0u) ? 0x52275ea4u : 0x271f2385u); // s365 add + r1 = r1 * r6; // s366 mul + r0 = r0 + r7 + ((((sel >> 30u) & 1u) != 0u) ? 0x8f8b4093u : 0x4c66800fu); // s367 add + r4 = rotr_var(r4, r0); // s368 rotr + r4 = rotr_var(r4, r0); // s369 rotr + r1 = r0 * r6 + r1; // s370 mad + r0 = r0 - r5; // s371 sub + r7 = r7 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0x9a7dcadcu : 0x7dad1ed5u); // s372 add + r7 = r7 + r3 + ((((sel >> 20u) & 1u) != 0u) ? 0xf808c195u : 0x1ea3d58eu); // s373 add + r1 = r1 * r2; // s374 mul + r3 = r7 * r2 + r3; // s375 mad + r4 = r4 ^ r1; // s376 xor + r1 = r1 | r0; // s377 or + r5 = r5 + r0 + ((((sel >> 26u) & 1u) != 0u) ? 0x427ed5ceu : 0x98b36d10u); // s378 add + r6 = r6 * r0; // s379 mul + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r3, 1); // s380 shfl + r4 = r4 + r0 + ((((sel >> 18u) & 1u) != 0u) ? 0x38f848b9u : 0xb19cab2du); // s381 add + r3 = r5 * r2 + r3; // s382 mad + r0 = r0 | r7; // s383 or + r5 = r5 - r4; // s384 sub + r1 = r1 - r5; // s385 sub + r2 = r2 - r0; // s386 sub + r5 = r5 + r2 + ((((sel >> 17u) & 1u) != 0u) ? 0xffc20cf8u : 0x341056b0u); // s387 add + r1 = rotl_imm(r1, 26u); // s388 rotl + r2 = r2 ^ r5; // s389 xor + r5 = r7 * r0 + r5; // s390 mad + r3 = __umulhi(r3, r2); // s391 mulhi + r5 = r5 + r4 + ((((sel >> 0u) & 1u) != 0u) ? 0xfb939f2bu : 0x78aa571au); // s392 add + r5 = r5 | r2; // s393 or + r1 = __umulhi(r1, r7); // s394 mulhi + r4 = r4 - r2; // s395 sub + r7 = r7 - r1; // s396 sub + r0 = r0 + r1 + ((((sel >> 2u) & 1u) != 0u) ? 0xa9c6c9fbu : 0x31af4767u); // s397 add + r3 = r3 * r1; // s398 mul + r1 = r1 - r7; // s399 sub + r7 = r7 + r6 + ((((sel >> 8u) & 1u) != 0u) ? 0x34f9b056u : 0x266d4c34u); // s400 add + r5 = rotl_imm(r5, 5u); // s401 rotl + r0 = r0 + r4 + ((((sel >> 23u) & 1u) != 0u) ? 0x79822c64u : 0x7241955eu); // s402 add + r2 = r4 * r0 + r2; // s403 mad + r5 = rotl_imm(r5, 29u); // s404 rotl + r3 = r3 - r5; // s405 sub + r2 = r2 + r3 + ((((sel >> 27u) & 1u) != 0u) ? 0xda046091u : 0xf65aca5du); // s406 add + r4 = __umulhi(r4, r7); // s407 mulhi + r2 = r2 + r1 + ((((sel >> 14u) & 1u) != 0u) ? 0x167aba1cu : 0x6a00cefbu); // s408 add + r2 = r6 * r6 + r2; // s409 mad + r6 = rotl_imm(r6, 26u); // s410 rotl + r6 = r6 | r7; // s411 or + r1 = rotl_imm(r1, 20u); // s412 rotl + r7 = r7 * r5; // s413 mul + r6 = r6 - r0; // s414 sub + r6 = __umulhi(r6, r0); // s415 mulhi + r3 = rotl_imm(r3, 5u); // s416 rotl + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r3, 4); // s417 shfl + r0 = r0 * r4; // s418 mul + r4 = rotr_var(r4, r7); // s419 rotr + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s420 shfl + r5 = r3 * r6 + r5; // s421 mad + r3 = r3 ^ r4; // s422 xor + r3 = rotr_var(r3, r7); // s423 rotr + r4 = r4 + r1 + ((((sel >> 26u) & 1u) != 0u) ? 0xbb669c17u : 0xba29da18u); // s424 add + r7 = rotr_var(r7, r5); // s425 rotr + r2 = r2 * r6; // s426 mul + r1 = r1 + r4 + ((((sel >> 16u) & 1u) != 0u) ? 0xc6b45a76u : 0x4f70e34fu); // s427 add + r1 = rotl_imm(r1, 1u); // s428 rotl + r6 = __umulhi(r6, r5); // s429 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xff610984u : 0x3883e0f5u); // s430 add + r4 = r4 | r3; // s431 or + r7 = r7 ^ r5; // s432 xor + r3 = __umulhi(r3, r2); // s433 mulhi + r2 = r2 ^ r6; // s434 xor + r4 = r4 | r3; // s435 or + r0 = r0 + r1 + ((((sel >> 9u) & 1u) != 0u) ? 0xf37057feu : 0xb1b15861u); // s436 add + r7 = r7 + r4 + ((((sel >> 4u) & 1u) != 0u) ? 0x61793eafu : 0x2e9e173fu); // s437 add + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r1, 1); // s438 shfl + r6 = r0 * r3 + r6; // s439 mad + r5 = r5 ^ r2; // s440 xor + r0 = r0 ^ __shfl_xor_sync(0xffffffffu, r4, 16); // s441 shfl + r6 = r6 * r3; // s442 mul + r5 = r5 - r4; // s443 sub + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r1, 4); // s444 shfl + r0 = r0 + r5 + ((((sel >> 12u) & 1u) != 0u) ? 0x69def831u : 0x646856aau); // s445 add + r4 = r4 + r6 + ((((sel >> 23u) & 1u) != 0u) ? 0x1f8ecb8bu : 0x58a3f8fcu); // s446 add + r4 = r0 * r2 + r4; // s447 mad + r5 = r5 * r0; // s448 mul + r2 = r2 + r5 + ((((sel >> 11u) & 1u) != 0u) ? 0x7ecb876du : 0x48d3062du); // s449 add + r2 = r5 * r6 + r2; // s450 mad + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r3, 4); // s451 shfl + r2 = r2 * r5; // s452 mul + r5 = __umulhi(r5, r4); // s453 mulhi + r1 = r1 ^ r7; // s454 xor + r2 = r2 * r7; // s455 mul + r1 = r1 * r3; // s456 mul + r3 = r6 * r2 + r3; // s457 mad + r7 = r7 - r0; // s458 sub + r2 = r4 * r5 + r2; // s459 mad + r0 = rotl_imm(r0, 2u); // s460 rotl + r4 = r4 ^ r2; // s461 xor + r4 = r4 + r0 + ((((sel >> 18u) & 1u) != 0u) ? 0x7b093757u : 0xb41dd69bu); // s462 add + r6 = r6 + r1 + ((((sel >> 3u) & 1u) != 0u) ? 0x916e1b7eu : 0xb042032eu); // s463 add + r2 = r2 + r6 + ((((sel >> 8u) & 1u) != 0u) ? 0x6d42b978u : 0x4e68a2a0u); // s464 add + r3 = r3 - r2; // s465 sub + r2 = r2 * r5; // s466 mul + r7 = rotl_imm(r7, 28u); // s467 rotl + r0 = r0 - r3; // s468 sub + r7 = __umulhi(r7, r2); // s469 mulhi + r7 = r7 | r6; // s470 or + r7 = rotl_imm(r7, 28u); // s471 rotl + r0 = r0 * r6; // s472 mul + r2 = r2 | r1; // s473 or + r2 = r2 + r4 + ((((sel >> 14u) & 1u) != 0u) ? 0x20c5276bu : 0x13ec3b3eu); // s474 add + r2 = rotr_var(r2, r6); // s475 rotr + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r0, 16); // s476 shfl + r2 = rotl_imm(r2, 15u); // s477 rotl + r5 = rotr_var(r5, r4); // s478 rotr + r3 = rotl_imm(r3, 26u); // s479 rotl + r5 = r5 | r6; // s480 or + r3 = rotl_imm(r3, 29u); // s481 rotl + r0 = rotr_var(r0, r7); // s482 rotr + r1 = r1 - r0; // s483 sub + r0 = r2 * r5 + r0; // s484 mad + r6 = r6 ^ r4; // s485 xor + r6 = r6 ^ r0; // s486 xor + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r7, 4); // s487 shfl + r6 = __umulhi(r6, r0); // s488 mulhi + r1 = r1 * r0; // s489 mul + r3 = r3 ^ r6; // s490 xor + r3 = r3 * r6; // s491 mul + r0 = r0 * r3; // s492 mul + r4 = r4 | r3; // s493 or + r0 = r0 ^ __shfl_xor_sync(0xffffffffu, r5, 8); // s494 shfl + r0 = r0 ^ __shfl_xor_sync(0xffffffffu, r7, 16); // s495 shfl + r6 = r5 * r2 + r6; // s496 mad + r5 = r5 * r6; // s497 mul + r3 = r3 ^ r1; // s498 xor + r0 = r0 + r1 + ((((sel >> 20u) & 1u) != 0u) ? 0x19f4c710u : 0x53e99acau); // s499 add + r6 = r5 * r2 + r6; // s500 mad + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 4); // s501 shfl + r3 = r3 - r5; // s502 sub + r0 = rotl_imm(r0, 8u); // s503 rotl + r3 = r3 ^ r1; // s504 xor + r7 = r7 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x7a6ac7b5u : 0x0867fe20u); // s505 add + r0 = r0 ^ __shfl_xor_sync(0xffffffffu, r7, 2); // s506 shfl + r0 = r0 * r1; // s507 mul + r6 = r6 | r5; // s508 or + r2 = r2 * r7; // s509 mul + r1 = r1 + r5 + ((((sel >> 21u) & 1u) != 0u) ? 0xd77f6a03u : 0xd7fdc3ecu); // s510 add + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r7, 8); // s511 shfl + r6 = r6 + r3 + ((((sel >> 9u) & 1u) != 0u) ? 0x5c22b0b5u : 0x297a096au); // s512 add + r7 = r7 | r0; // s513 or + r7 = r7 + r3 + ((((sel >> 27u) & 1u) != 0u) ? 0x4caafacdu : 0x5de1d1d1u); // s514 add + r1 = __umulhi(r1, r0); // s515 mulhi + r0 = r0 - r6; // s516 sub + r2 = r2 - r1; // s517 sub + r6 = r5 * r7 + r6; // s518 mad + r2 = r2 ^ r7; // s519 xor + r1 = r1 | r5; // s520 or + r0 = r4 * r6 + r0; // s521 mad + r4 = r4 + r6 + ((((sel >> 29u) & 1u) != 0u) ? 0xb1091e80u : 0x2caeeca3u); // s522 add + r7 = r6 * r5 + r7; // s523 mad + r7 = r7 - r2; // s524 sub + r0 = r0 * r7; // s525 mul + r0 = r0 ^ r7; // s526 xor + r1 = __umulhi(r1, r4); // s527 mulhi + r0 = rotr_var(r0, r5); // s528 rotr + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r7, 16); // s529 shfl + r2 = __umulhi(r2, r3); // s530 mulhi + r1 = r1 | r4; // s531 or + r6 = r6 + r4 + ((((sel >> 13u) & 1u) != 0u) ? 0xbda312aeu : 0xbe9e1eb0u); // s532 add + r7 = r7 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x1ec16229u : 0xbe5d93a3u); // s533 add + r0 = r6 * r4 + r0; // s534 mad + r0 = r0 + r5 + ((((sel >> 23u) & 1u) != 0u) ? 0x500828bcu : 0x5e23583bu); // s535 add + r6 = r5 * r0 + r6; // s536 mad + r2 = r2 ^ r4; // s537 xor + r6 = r3 * r5 + r6; // s538 mad + r6 = r6 + r4 + ((((sel >> 3u) & 1u) != 0u) ? 0x852321dcu : 0x43c32138u); // s539 add + r2 = r2 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x44e6ae63u : 0xaff69493u); // s540 add + r3 = __umulhi(r3, r5); // s541 mulhi + r1 = r1 + r7 + ((((sel >> 5u) & 1u) != 0u) ? 0x909712feu : 0xc5de29efu); // s542 add + r1 = r3 * r2 + r1; // s543 mad + r1 = r1 + r3 + ((((sel >> 11u) & 1u) != 0u) ? 0xfb7b42b9u : 0x1e20e084u); // s544 add + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r5, 4); // s545 shfl + r6 = r6 + r1 + ((((sel >> 10u) & 1u) != 0u) ? 0x6e036dd4u : 0x9370db38u); // s546 add + r4 = r4 ^ r6; // s547 xor + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r3, 8); // s548 shfl + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r5, 16); // s549 shfl + r1 = rotr_var(r1, r7); // s550 rotr + r0 = r3 * r2 + r0; // s551 mad + r7 = __umulhi(r7, r4); // s552 mulhi + r0 = r0 + r4 + ((((sel >> 13u) & 1u) != 0u) ? 0xd3c9174du : 0xbf2488f6u); // s553 add + r1 = rotl_imm(r1, 1u); // s554 rotl + r7 = rotr_var(r7, r3); // s555 rotr + r7 = rotr_var(r7, r3); // s556 rotr + r6 = r2 * r0 + r6; // s557 mad + r6 = r6 ^ r1; // s558 xor + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s559 shfl + r5 = r5 ^ r3; // s560 xor + r5 = r5 * r1; // s561 mul + r3 = rotl_imm(r3, 31u); // s562 rotl + r6 = rotr_var(r6, r2); // s563 rotr + r7 = r7 | r2; // s564 or + r6 = rotr_var(r6, r0); // s565 rotr + r2 = r2 * r0; // s566 mul + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r5, 2); // s567 shfl + r3 = r3 * r0; // s568 mul + r4 = r4 + r2 + ((((sel >> 9u) & 1u) != 0u) ? 0xa3149efau : 0xd9160c83u); // s569 add + r4 = __umulhi(r4, r2); // s570 mulhi + r3 = r3 + r0 + ((((sel >> 10u) & 1u) != 0u) ? 0x9cab407bu : 0x3bdc971cu); // s571 add + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r2, 16); // s572 shfl + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r5, 4); // s573 shfl + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r3, 8); // s574 shfl + r0 = r0 ^ r7; // s575 xor + r0 = r0 + r5 + ((((sel >> 27u) & 1u) != 0u) ? 0x747b0838u : 0x17979608u); // s576 add + r0 = r0 ^ r4; // s577 xor + r6 = r6 - r1; // s578 sub + r4 = rotr_var(r4, r2); // s579 rotr + r2 = r2 ^ r3; // s580 xor + r6 = r7 * r2 + r6; // s581 mad + r5 = r5 + r2 + ((((sel >> 7u) & 1u) != 0u) ? 0x02246c0cu : 0x1c10ec5cu); // s582 add + r3 = __umulhi(r3, r6); // s583 mulhi + r2 = r2 ^ r5; // s584 xor + r6 = rotl_imm(r6, 24u); // s585 rotl + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r5, 8); // s586 shfl + r1 = r2 * r6 + r1; // s587 mad + r3 = r3 + r7 + ((((sel >> 21u) & 1u) != 0u) ? 0xbea44bd0u : 0x88758873u); // s588 add + r1 = rotl_imm(r1, 30u); // s589 rotl + r7 = r7 * r1; // s590 mul + r3 = r3 + r6 + ((((sel >> 10u) & 1u) != 0u) ? 0x8e0eb890u : 0xf436bb64u); // s591 add + r7 = r6 * r1 + r7; // s592 mad + r0 = r3 * r5 + r0; // s593 mad + r5 = rotr_var(r5, r4); // s594 rotr + r4 = r4 | r0; // s595 or + r6 = r3 * r0 + r6; // s596 mad + r2 = r2 + r1 + ((((sel >> 31u) & 1u) != 0u) ? 0x29b853b3u : 0xb465e47eu); // s597 add + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r7, 16); // s598 shfl + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r0, 4); // s599 shfl + r6 = r2 * r0 + r6; // s600 mad + r5 = __umulhi(r5, r0); // s601 mulhi + r6 = r6 * r7; // s602 mul + r4 = r4 | r7; // s603 or + r7 = r7 - r0; // s604 sub + r7 = rotr_var(r7, r4); // s605 rotr + r4 = r0 * r3 + r4; // s606 mad + r4 = __umulhi(r4, r3); // s607 mulhi + r0 = r0 + r1 + ((((sel >> 28u) & 1u) != 0u) ? 0xb7536963u : 0x22ce199du); // s608 add + r2 = r2 - r5; // s609 sub + r2 = r2 ^ r0; // s610 xor + r5 = r5 * r4; // s611 mul + r3 = rotl_imm(r3, 25u); // s612 rotl + r7 = rotl_imm(r7, 13u); // s613 rotl + r4 = r4 * r7; // s614 mul + r5 = r4 * r2 + r5; // s615 mad + r0 = r0 ^ r5; // s616 xor + r7 = r5 * r4 + r7; // s617 mad + r6 = r6 - r4; // s618 sub + r3 = r3 * r4; // s619 mul + r1 = rotl_imm(r1, 24u); // s620 rotl + r1 = r1 ^ r2; // s621 xor + r4 = r4 | r3; // s622 or + r7 = r7 * r2; // s623 mul + r6 = r6 + r1 + ((((sel >> 20u) & 1u) != 0u) ? 0xe37b1e20u : 0x2dbf6ed0u); // s624 add + r4 = r4 ^ r5; // s625 xor + r4 = r6 * r2 + r4; // s626 mad + r1 = r1 ^ r6; // s627 xor + r6 = r6 + r3 + ((((sel >> 12u) & 1u) != 0u) ? 0xf5a2a9f7u : 0x9dc2b9d0u); // s628 add + r7 = r7 - r5; // s629 sub + r1 = __umulhi(r1, r7); // s630 mulhi + r1 = rotr_var(r1, r3); // s631 rotr + r4 = r4 | r6; // s632 or + r2 = r2 + r5 + ((((sel >> 24u) & 1u) != 0u) ? 0x982bfc08u : 0x9c1fba1bu); // s633 add + r6 = r6 * r5; // s634 mul + r7 = r2 * r3 + r7; // s635 mad + r7 = __umulhi(r7, r4); // s636 mulhi + r5 = r5 ^ r0; // s637 xor + r0 = r0 * r1; // s638 mul + r4 = r4 ^ r6; // s639 xor + r6 = r6 - r4; // s640 sub + r6 = __umulhi(r6, r4); // s641 mulhi + r4 = r4 - r0; // s642 sub + r7 = r7 - r5; // s643 sub + r3 = r0 * r7 + r3; // s644 mad + r3 = r3 | r5; // s645 or + r0 = r0 - r4; // s646 sub + r7 = r7 | r5; // s647 or + r7 = rotl_imm(r7, 1u); // s648 rotl + r5 = r5 + r6 + ((((sel >> 31u) & 1u) != 0u) ? 0x6e5d517fu : 0x9f5e0d19u); // s649 add + r1 = r1 | r2; // s650 or + r3 = rotl_imm(r3, 29u); // s651 rotl + r2 = r2 + r4 + ((((sel >> 2u) & 1u) != 0u) ? 0x30faf9c6u : 0xb53f6e74u); // s652 add + r0 = rotl_imm(r0, 21u); // s653 rotl + r1 = r1 ^ r3; // s654 xor + r4 = r7 * r2 + r4; // s655 mad + r4 = r4 - r6; // s656 sub + r4 = r4 * r6; // s657 mul + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r1, 4); // s658 shfl + r7 = rotl_imm(r7, 31u); // s659 rotl + r4 = r4 ^ r6; // s660 xor + r1 = r1 - r3; // s661 sub + r3 = r3 * r6; // s662 mul + r5 = r5 * r3; // s663 mul + r7 = r7 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x8941d2e7u : 0x016e0094u); // s664 add + r1 = r1 ^ r2; // s665 xor + r1 = r1 - r0; // s666 sub + r4 = r4 ^ r7; // s667 xor + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r3, 1); // s668 shfl + r1 = rotr_var(r1, r4); // s669 rotr + r2 = r2 + r3 + ((((sel >> 14u) & 1u) != 0u) ? 0x15289435u : 0x9af12ca6u); // s670 add + r2 = rotr_var(r2, r4); // s671 rotr + r4 = r6 * r7 + r4; // s672 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r1, 4); // s673 shfl + r6 = r4 * r2 + r6; // s674 mad + r2 = r4 * r6 + r2; // s675 mad + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r1, 16); // s676 shfl + r1 = rotr_var(r1, r0); // s677 rotr + r0 = r0 - r2; // s678 sub + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r1, 16); // s679 shfl + r1 = r1 ^ r0; // s680 xor + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // s681 shfl + r0 = r0 ^ __shfl_xor_sync(0xffffffffu, r3, 8); // s682 shfl + r2 = r3 * r3 + r2; // s683 mad + r4 = r4 - r6; // s684 sub + r5 = r5 ^ r3; // s685 xor + r2 = r2 - r5; // s686 sub + r4 = r4 - r5; // s687 sub + r5 = r4 * r7 + r5; // s688 mad + r6 = r6 * r7; // s689 mul + r1 = r1 * r5; // s690 mul + r4 = rotr_var(r4, r3); // s691 rotr + r2 = r2 ^ r4; // s692 xor + r0 = rotl_imm(r0, 2u); // s693 rotl + r5 = r5 + r2 + ((((sel >> 23u) & 1u) != 0u) ? 0x49801084u : 0x4fc762c9u); // s694 add + r0 = r0 + r4 + ((((sel >> 14u) & 1u) != 0u) ? 0x5f403cd5u : 0x626c00f5u); // s695 add + r6 = rotl_imm(r6, 25u); // s696 rotl + r3 = r3 ^ r7; // s697 xor + r0 = r0 * r2; // s698 mul + r5 = rotr_var(r5, r1); // s699 rotr + r3 = r3 ^ r7; // s700 xor + r4 = r4 | r3; // s701 or + r7 = r7 * r3; // s702 mul + r4 = rotl_imm(r4, 24u); // s703 rotl + r5 = r5 + r4 + ((((sel >> 17u) & 1u) != 0u) ? 0xad5e1851u : 0xc08bb414u); // s704 add + r0 = r6 * r5 + r0; // s705 mad + r4 = __umulhi(r4, r1); // s706 mulhi + r4 = rotr_var(r4, r3); // s707 rotr + r3 = rotr_var(r3, r6); // s708 rotr + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r7, 16); // s709 shfl + r3 = r2 * r6 + r3; // s710 mad + r1 = r1 * r4; // s711 mul + r3 = r3 + r5 + ((((sel >> 13u) & 1u) != 0u) ? 0x407f7c4du : 0xdc55338fu); // s712 add + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r7, 2); // s713 shfl + r1 = r1 ^ r0; // s714 xor + r7 = r1 * r1 + r7; // s715 mad + r4 = r4 | r0; // s716 or + r6 = r6 * r4; // s717 mul + r0 = r0 - r5; // s718 sub + r1 = r1 ^ r4; // s719 xor + r4 = __umulhi(r4, r6); // s720 mulhi + r1 = r1 + r0 + ((((sel >> 13u) & 1u) != 0u) ? 0xc2093fcau : 0xb2ce569eu); // s721 add + r4 = __umulhi(r4, r2); // s722 mulhi + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r1, 16); // s723 shfl + r5 = r3 * r0 + r5; // s724 mad + r5 = __umulhi(r5, r0); // s725 mulhi + r2 = rotr_var(r2, r5); // s726 rotr + r5 = r5 + r0 + ((((sel >> 20u) & 1u) != 0u) ? 0x48cdf1c1u : 0x4e8aaad5u); // s727 add + r1 = r1 * r0; // s728 mul + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r0, 1); // s729 shfl + r4 = r4 * r6; // s730 mul + r4 = r4 - r6; // s731 sub + r4 = r4 ^ r2; // s732 xor + r5 = r5 * r6; // s733 mul + r7 = rotr_var(r7, r3); // s734 rotr + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r5, 1); // s735 shfl + r1 = __umulhi(r1, r0); // s736 mulhi + r2 = r2 * r6; // s737 mul + r5 = rotl_imm(r5, 27u); // s738 rotl + r2 = __umulhi(r2, r3); // s739 mulhi + r5 = r3 * r5 + r5; // s740 mad + r2 = rotl_imm(r2, 11u); // s741 rotl + r6 = r6 | r2; // s742 or + r2 = r2 ^ r3; // s743 xor + r3 = r3 * r1; // s744 mul + r4 = __umulhi(r4, r2); // s745 mulhi + r5 = r5 ^ r6; // s746 xor + r6 = r6 + r7 + ((((sel >> 11u) & 1u) != 0u) ? 0x0d6b844eu : 0x78fc162du); // s747 add + r1 = rotl_imm(r1, 27u); // s748 rotl + r4 = rotr_var(r4, r1); // s749 rotr + r5 = r5 ^ r7; // s750 xor + r4 = rotr_var(r4, r3); // s751 rotr + r5 = r5 * r2; // s752 mul + r1 = r6 * r7 + r1; // s753 mad + r0 = r0 ^ r1; // s754 xor + r7 = r7 - r1; // s755 sub + r0 = r0 + r4 + ((((sel >> 5u) & 1u) != 0u) ? 0xb74ac71eu : 0x68aab88bu); // s756 add + r7 = r7 + r5 + ((((sel >> 0u) & 1u) != 0u) ? 0xf81f5b66u : 0xba5c123au); // s757 add + r0 = r7 * r2 + r0; // s758 mad + r1 = r1 | r0; // s759 or + r4 = __umulhi(r4, r6); // s760 mulhi + r0 = __umulhi(r0, r7); // s761 mulhi + r3 = rotr_var(r3, r4); // s762 rotr + r3 = rotl_imm(r3, 30u); // s763 rotl + r6 = r6 * r2; // s764 mul + r6 = r6 ^ r4; // s765 xor + r3 = r3 + r4 + ((((sel >> 0u) & 1u) != 0u) ? 0x96dabea6u : 0x6eb1d82au); // s766 add + r0 = r0 ^ __shfl_xor_sync(0xffffffffu, r2, 1); // s767 shfl + r3 = rotl_imm(r3, 8u); // s768 rotl + r7 = r7 * r4; // s769 mul + r6 = r1 * r2 + r6; // s770 mad + r2 = r2 ^ r7; // s771 xor + r6 = r6 * r0; // s772 mul + r2 = r2 - r1; // s773 sub + r1 = r0 * r1 + r1; // s774 mad + r5 = __umulhi(r5, r7); // s775 mulhi + r0 = rotr_var(r0, r4); // s776 rotr + r6 = r6 ^ r0; // s777 xor + r4 = __umulhi(r4, r7); // s778 mulhi + r1 = r3 * r0 + r1; // s779 mad + r6 = r6 + r4 + ((((sel >> 2u) & 1u) != 0u) ? 0x903f3f77u : 0x11d7b79au); // s780 add + r4 = r4 ^ r7; // s781 xor + r1 = r1 + r2 + ((((sel >> 14u) & 1u) != 0u) ? 0x2ca81d8du : 0x1791eaddu); // s782 add + r2 = rotr_var(r2, r1); // s783 rotr + r4 = r4 * r6; // s784 mul + r1 = r1 ^ r6; // s785 xor + r4 = r4 - r0; // s786 sub + r3 = r3 ^ r4; // s787 xor + r4 = r4 * r1; // s788 mul + r4 = r6 * r7 + r4; // s789 mad + r5 = r5 - r0; // s790 sub + r2 = r2 * r0; // s791 mul + r7 = rotl_imm(r7, 12u); // s792 rotl + r2 = r7 * r3 + r2; // s793 mad + r1 = r4 * r4 + r1; // s794 mad + r6 = r6 + r4 + ((((sel >> 15u) & 1u) != 0u) ? 0xf66fad29u : 0xc08797bbu); // s795 add + r1 = r1 - r4; // s796 sub + r5 = r5 * r2; // s797 mul + r5 = r5 ^ r2; // s798 xor + r0 = r0 * r1; // s799 mul + r6 = r6 + r4 + ((((sel >> 13u) & 1u) != 0u) ? 0x2d82a681u : 0x6d4a6371u); // s800 add + r1 = r6 * r1 + r1; // s801 mad + r0 = r0 - r2; // s802 sub + r6 = r6 ^ r2; // s803 xor + r7 = rotl_imm(r7, 24u); // s804 rotl + r6 = r6 ^ r7; // s805 xor + r7 = r7 | r0; // s806 or + r0 = rotl_imm(r0, 5u); // s807 rotl + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r2, 2); // s808 shfl + r4 = r1 * r5 + r4; // s809 mad + r0 = r0 + r2 + ((((sel >> 14u) & 1u) != 0u) ? 0x63e62197u : 0x0092eb62u); // s810 add + r5 = r5 - r3; // s811 sub + r2 = r1 * r5 + r2; // s812 mad + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r0, 16); // s813 shfl + r7 = r5 * r1 + r7; // s814 mad + r0 = __umulhi(r0, r7); // s815 mulhi + r2 = r2 | r1; // s816 or + r7 = __umulhi(r7, r3); // s817 mulhi + r2 = r2 ^ r4; // s818 xor + r4 = r4 + r3 + ((((sel >> 0u) & 1u) != 0u) ? 0x27d94f57u : 0xbb69174fu); // s819 add + r5 = r5 + r3 + ((((sel >> 1u) & 1u) != 0u) ? 0x82285691u : 0xda6759f2u); // s820 add + r1 = r1 + r3 + ((((sel >> 31u) & 1u) != 0u) ? 0xe50565d8u : 0x9ad4b47fu); // s821 add + r5 = rotl_imm(r5, 6u); // s822 rotl + r3 = r3 - r0; // s823 sub + r6 = rotl_imm(r6, 12u); // s824 rotl + r4 = r4 | r5; // s825 or + r3 = r3 ^ r2; // s826 xor + r4 = r4 + r0 + ((((sel >> 26u) & 1u) != 0u) ? 0xffcab83au : 0xca1e80fbu); // s827 add + r3 = r3 | r7; // s828 or + r1 = r5 * r7 + r1; // s829 mad + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r0, 16); // s830 shfl + r1 = r1 - r0; // s831 sub + r0 = rotr_var(r0, r2); // s832 rotr + r1 = __umulhi(r1, r0); // s833 mulhi + r6 = __umulhi(r6, r4); // s834 mulhi + r6 = rotl_imm(r6, 2u); // s835 rotl + r4 = r4 | r6; // s836 or + r6 = rotl_imm(r6, 23u); // s837 rotl + r4 = r7 * r4 + r4; // s838 mad + r0 = r0 | r1; // s839 or + r5 = __umulhi(r5, r3); // s840 mulhi + r7 = r4 * r6 + r7; // s841 mad + r1 = r1 + r4 + ((((sel >> 21u) & 1u) != 0u) ? 0x1bc9f95du : 0xcfb90e90u); // s842 add + r1 = r1 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0xf9bd620fu : 0x0b4758b6u); // s843 add + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r5, 16); // s844 shfl + r3 = r1 * r7 + r3; // s845 mad + r5 = r5 * r2; // s846 mul + r0 = rotl_imm(r0, 21u); // s847 rotl + r7 = r7 ^ r1; // s848 xor + r3 = r3 + r4 + ((((sel >> 18u) & 1u) != 0u) ? 0x697a4946u : 0x41fdc15au); // s849 add + r0 = r0 ^ __shfl_xor_sync(0xffffffffu, r5, 4); // s850 shfl + r1 = rotr_var(r1, r5); // s851 rotr + r5 = r5 | r6; // s852 or + r6 = r6 - r2; // s853 sub + r2 = r2 ^ r6; // s854 xor + r4 = r4 - r6; // s855 sub + r6 = r4 * r6 + r6; // s856 mad + r4 = r4 * r0; // s857 mul + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r1, 4); // s858 shfl + r3 = r3 * r4; // s859 mul + r3 = r1 * r7 + r3; // s860 mad + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r2, 2); // s861 shfl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r4, 8); // s862 shfl + r0 = r2 * r2 + r0; // s863 mad + r6 = r6 ^ r0; // s864 xor + r6 = r6 + r2 + ((((sel >> 2u) & 1u) != 0u) ? 0x7fedd7f3u : 0x90656f74u); // s865 add + r3 = r3 ^ r2; // s866 xor + r1 = r1 | r4; // s867 or + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r7, 2); // s868 shfl + r1 = __umulhi(r1, r0); // s869 mulhi + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r1, 4); // s870 shfl + r0 = r0 - r3; // s871 sub + r6 = r6 + r1 + ((((sel >> 11u) & 1u) != 0u) ? 0xbe1b480au : 0xa5c0b461u); // s872 add + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r6, 1); // s873 shfl + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r0, 1); // s874 shfl + r2 = __umulhi(r2, r4); // s875 mulhi + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r7, 4); // s876 shfl + r5 = rotl_imm(r5, 14u); // s877 rotl + r2 = r2 ^ r7; // s878 xor + r7 = r7 ^ r0; // s879 xor + r0 = r0 * r2; // s880 mul + r4 = r4 * r2; // s881 mul + r7 = r7 * r6; // s882 mul + r4 = __umulhi(r4, r5); // s883 mulhi + r0 = r0 - r4; // s884 sub + r0 = r0 ^ r5; // s885 xor + r6 = r6 * r5; // s886 mul + r1 = r1 + r5 + ((((sel >> 14u) & 1u) != 0u) ? 0x7007f98fu : 0xe806fcecu); // s887 add + r3 = r3 * r1; // s888 mul + r5 = r5 ^ r3; // s889 xor + r6 = r6 | r2; // s890 or + r1 = r1 * r2; // s891 mul + r5 = r5 + r7 + ((((sel >> 3u) & 1u) != 0u) ? 0xf3c87e02u : 0x89a8551eu); // s892 add + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 16); // s893 shfl + r1 = r1 + r3 + ((((sel >> 13u) & 1u) != 0u) ? 0xc315f5deu : 0xba1369dbu); // s894 add + r5 = r0 * r3 + r5; // s895 mad + r5 = rotr_var(r5, r2); // s896 rotr + r1 = r1 ^ r0; // s897 xor + r5 = r5 ^ r1; // s898 xor + r5 = rotr_var(r5, r1); // s899 rotr + r3 = r6 * r6 + r3; // s900 mad + r0 = rotl_imm(r0, 8u); // s901 rotl + r1 = r1 | r0; // s902 or + r1 = r1 + r2 + ((((sel >> 3u) & 1u) != 0u) ? 0x1c355a71u : 0x260e6848u); // s903 add + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r2, 16); // s904 shfl + r1 = __umulhi(r1, r3); // s905 mulhi + r1 = rotr_var(r1, r4); // s906 rotr + r6 = r6 + r0 + ((((sel >> 8u) & 1u) != 0u) ? 0x0c74a1a8u : 0xa74fd2b1u); // s907 add + r6 = rotr_var(r6, r2); // s908 rotr + r4 = rotl_imm(r4, 12u); // s909 rotl + r5 = r5 + r3 + ((((sel >> 29u) & 1u) != 0u) ? 0xa49b5d73u : 0xe5fb043eu); // s910 add + r3 = r3 ^ r0; // s911 xor + r3 = rotr_var(r3, r4); // s912 rotr + r6 = rotr_var(r6, r0); // s913 rotr + r2 = r2 ^ r5; // s914 xor + r0 = r0 * r7; // s915 mul + r3 = r3 ^ r0; // s916 xor + r5 = r1 * r7 + r5; // s917 mad + r3 = r3 + r4 + ((((sel >> 2u) & 1u) != 0u) ? 0xeb76e56cu : 0x264cb47bu); // s918 add + r3 = __umulhi(r3, r4); // s919 mulhi + r5 = r5 + r6 + ((((sel >> 9u) & 1u) != 0u) ? 0x2aab9631u : 0x418baa72u); // s920 add + r5 = __umulhi(r5, r1); // s921 mulhi + r7 = r7 - r3; // s922 sub + r6 = r6 + r1 + ((((sel >> 2u) & 1u) != 0u) ? 0x98e6b26du : 0x3696a894u); // s923 add + r6 = r3 * r1 + r6; // s924 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s925 shfl + r6 = r6 ^ r1; // s926 xor + r4 = r4 ^ r3; // s927 xor + r0 = r0 + r4 + ((((sel >> 7u) & 1u) != 0u) ? 0x142778eeu : 0x0468c062u); // s928 add + r7 = r7 + r3 + ((((sel >> 29u) & 1u) != 0u) ? 0x4eae212du : 0x0af82291u); // s929 add + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r7, 16); // s930 shfl + r7 = r7 + r2 + ((((sel >> 20u) & 1u) != 0u) ? 0x8d2a8b36u : 0x17de5e29u); // s931 add + r5 = r5 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0xe2d2d7d5u : 0x686794a8u); // s932 add + r0 = __umulhi(r0, r3); // s933 mulhi + r4 = r4 + r0 + ((((sel >> 10u) & 1u) != 0u) ? 0xe3c3c6f9u : 0x66278068u); // s934 add + r6 = rotl_imm(r6, 22u); // s935 rotl + r0 = r0 | r2; // s936 or + r4 = r4 * r3; // s937 mul + r3 = r3 | r6; // s938 or + r7 = rotl_imm(r7, 28u); // s939 rotl + r0 = r0 + r6 + ((((sel >> 20u) & 1u) != 0u) ? 0xc2296063u : 0xc2d02ca6u); // s940 add + r1 = r1 + r5 + ((((sel >> 14u) & 1u) != 0u) ? 0xef1ca415u : 0x0b3c00e0u); // s941 add + r2 = r2 - r6; // s942 sub + r6 = r6 | r3; // s943 or + r0 = rotl_imm(r0, 2u); // s944 rotl + r2 = r2 * r1; // s945 mul + r0 = r0 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0x06a1321au : 0x11224846u); // s946 add + r3 = r3 * r6; // s947 mul + r5 = r5 - r2; // s948 sub + r5 = r5 + r4 + ((((sel >> 5u) & 1u) != 0u) ? 0x5d3e225cu : 0x461c43d4u); // s949 add + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r1, 16); // s950 shfl + r7 = r0 * r0 + r7; // s951 mad + r6 = rotr_var(r6, r4); // s952 rotr + r1 = r1 + r0 + ((((sel >> 30u) & 1u) != 0u) ? 0xbb84f628u : 0xd5eed39fu); // s953 add + r4 = rotl_imm(r4, 31u); // s954 rotl + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r2, 16); // s955 shfl + r2 = r2 - r6; // s956 sub + r4 = r4 ^ r2; // s957 xor + r0 = r0 ^ r2; // s958 xor + r1 = r1 + r0 + ((((sel >> 28u) & 1u) != 0u) ? 0x374c0426u : 0x519d72f7u); // s959 add + r5 = r5 * r4; // s960 mul + r5 = r5 - r7; // s961 sub + r2 = r2 ^ r6; // s962 xor + r4 = r4 ^ r1; // s963 xor + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 16); // s964 shfl + r7 = __umulhi(r7, r3); // s965 mulhi + r4 = rotl_imm(r4, 12u); // s966 rotl + r4 = r4 + r6 + ((((sel >> 26u) & 1u) != 0u) ? 0x03b88592u : 0x151dae18u); // s967 add + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r3, 4); // s968 shfl + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r6, 8); // s969 shfl + r2 = r2 ^ r7; // s970 xor + r5 = r3 * r4 + r5; // s971 mad + r0 = r0 ^ r3; // s972 xor + r2 = r2 ^ r5; // s973 xor + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r0, 4); // s974 shfl + r5 = r1 * r4 + r5; // s975 mad + r2 = rotl_imm(r2, 19u); // s976 rotl + r1 = r1 - r4; // s977 sub + r5 = rotr_var(r5, r4); // s978 rotr + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r1, 16); // s979 shfl + r6 = r6 + r7 + ((((sel >> 28u) & 1u) != 0u) ? 0x1fdee45eu : 0x16220e61u); // s980 add + r4 = rotr_var(r4, r6); // s981 rotr + r6 = __umulhi(r6, r3); // s982 mulhi + r5 = rotl_imm(r5, 17u); // s983 rotl + r2 = r7 * r1 + r2; // s984 mad + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r1, 8); // s985 shfl + r3 = r3 ^ r1; // s986 xor + r4 = r4 + r0 + ((((sel >> 27u) & 1u) != 0u) ? 0x44adc457u : 0x6cd6b697u); // s987 add + r1 = r1 * r5; // s988 mul + r4 = r4 + r2 + ((((sel >> 2u) & 1u) != 0u) ? 0x0a06a223u : 0x1103d2d2u); // s989 add + r4 = r4 * r1; // s990 mul + r4 = r5 * r1 + r4; // s991 mad + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r6, 1); // s992 shfl + r1 = r1 - r3; // s993 sub + r4 = r7 * r5 + r4; // s994 mad + r1 = __umulhi(r1, r2); // s995 mulhi + r2 = r1 * r0 + r2; // s996 mad + r3 = rotl_imm(r3, 31u); // s997 rotl + r4 = r4 - r3; // s998 sub + r5 = rotr_var(r5, r3); // s999 rotr + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r0, 4); // s1000 shfl + r2 = r2 - r5; // s1001 sub + r3 = r4 * r4 + r3; // s1002 mad + r7 = r5 * r1 + r7; // s1003 mad + r7 = r7 + r4 + ((((sel >> 29u) & 1u) != 0u) ? 0x0044887fu : 0xa9c9d8a9u); // s1004 add + r4 = __umulhi(r4, r0); // s1005 mulhi + r4 = rotl_imm(r4, 21u); // s1006 rotl + r3 = r3 * r1; // s1007 mul + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r5, 2); // s1008 shfl + r0 = __umulhi(r0, r6); // s1009 mulhi + r0 = r0 ^ r3; // s1010 xor + r5 = r5 | r4; // s1011 or + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r5, 4); // s1012 shfl + r2 = r2 + r4 + ((((sel >> 4u) & 1u) != 0u) ? 0x6b70e2c7u : 0xfa1574e3u); // s1013 add + r5 = rotr_var(r5, r7); // s1014 rotr + r0 = rotr_var(r0, r7); // s1015 rotr + r5 = r5 - r7; // s1016 sub + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r1, 16); // s1017 shfl + r6 = __umulhi(r6, r7); // s1018 mulhi + r0 = rotr_var(r0, r1); // s1019 rotr + r2 = r2 ^ r0; // s1020 xor + r4 = r5 * r1 + r4; // s1021 mad + r6 = r6 | r2; // s1022 or + r3 = r3 ^ r0; // s1023 xor + } + } + uint32_t lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint32_t hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((uint64_t)hi << 32) | (uint64_t)lo; +} + +// Host-side launch wrappers. Declared in program.h, called from host.cu. +cudaError_t igneum_launch_cache_fill(uint32_t* cache, uint32_t nSegments) { + if (nSegments == 0u) return cudaErrorInvalidValue; + uint32_t block = 256u; + uint32_t grid = (nSegments + block - 1u) / block; + igneum_cache_fill<<>>(cache, nSegments); + return cudaGetLastError(); +} + +cudaError_t igneum_launch_build(uint32_t* ds, const uint32_t* cache, uint32_t nItems) { + if (nItems == 0u) return cudaErrorInvalidValue; + uint32_t block = 256u; + uint32_t grid = (nItems + block - 1u) / block; + igneum_build<<>>(ds, cache, nItems); + return cudaGetLastError(); +} + +cudaError_t igneum_launch_hash(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, + uint32_t nonces, uint32_t blockWarps) { + if (blockWarps == 0u || blockWarps > 32u) return cudaErrorInvalidValue; + uint32_t block = 32u * blockWarps; + if (nonces == 0u || (nonces % block) != 0u) return cudaErrorInvalidValue; + igneum_hash<<>>(ds, out, baseNonce, mask); + return cudaGetLastError(); +} + +cudaError_t igneum_hash_info(int* numRegs, int* blocksPerSM, uint32_t blockWarps) { + cudaFuncAttributes attr; + cudaError_t e = cudaFuncGetAttributes(&attr, igneum_hash); + if (e != cudaSuccess) return e; + *numRegs = attr.numRegs; + return cudaOccupancyMaxActiveBlocksPerMultiprocessor(blocksPerSM, igneum_hash, (int)(32u * blockWarps), 0); +} diff --git a/proto-cuda/packs-ca3-shadow/sh1024x3/kernel_bound.cl b/proto-cuda/packs-ca3-shadow/sh1024x3/kernel_bound.cl new file mode 100644 index 000000000..525259b19 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh1024x3/kernel_bound.cl @@ -0,0 +1,2427 @@ +// 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 ^ 0x67a9a7beu; x += 0x9e3779b9u; x = splitmix32(x); r0 = x ^ 0x1a155b25u; } // SEEDW[0], 0x9e3779b9u * 1u, SEEDW[1] + { uint x = nonce ^ 0x1a155b25u; x += 0x3c6ef372u; x = splitmix32(x); r1 = x ^ 0xfddfb732u; } // SEEDW[1], 0x9e3779b9u * 2u, SEEDW[2] + { uint x = nonce ^ 0xfddfb732u; x += 0xdaa66d2bu; x = splitmix32(x); r2 = x ^ 0x4b5af2e8u; } // SEEDW[2], 0x9e3779b9u * 3u, SEEDW[3] + { uint x = nonce ^ 0x4b5af2e8u; x += 0x78dde6e4u; x = splitmix32(x); r3 = x ^ 0xc55caf33u; } // SEEDW[3], 0x9e3779b9u * 4u, SEEDW[4] + { uint x = nonce ^ 0xc55caf33u; x += 0x1715609du; x = splitmix32(x); r4 = x ^ 0xa27c13b7u; } // SEEDW[4], 0x9e3779b9u * 5u, SEEDW[5] + { uint x = nonce ^ 0xa27c13b7u; x += 0xb54cda56u; x = splitmix32(x); r5 = x ^ 0x06628a48u; } // SEEDW[5], 0x9e3779b9u * 6u, SEEDW[6] + { uint x = nonce ^ 0x06628a48u; x += 0x5384540fu; x = splitmix32(x); r6 = x ^ 0x03852469u; } // SEEDW[6], 0x9e3779b9u * 7u, SEEDW[7] + { uint x = nonce ^ 0x03852469u; x += 0xf1bbcdc8u; x = splitmix32(x); r7 = x ^ 0x67a9a7beu; } // SEEDW[7], 0x9e3779b9u * 8u, SEEDW[0] + + for (uint it = 0u; it < 8u; ++it) { + uint sel = r0; + r2 = r3 * r4 + r2; // 0 mad + r2 = r1 * r1 + r2; // 1 mad + r2 = r3 * r2 + r2; // 2 mad + r3 = r3 ^ r5; // 3 xor + r7 = r7 ^ ds[r2 & mask]; // 4 load + r5 = r5 ^ ds[r7 & mask]; // 5 load + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r1 = r1 ^ t_; } // 6 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r7 = r7 ^ t_; } // 7 shfl + r1 = mul_hi(r1, r5); // 8 mulhi + r6 = rotr_var(r6, r3); // 9 rotr + r3 = r3 | r4; // 10 or + r4 = r4 ^ ds[r3 & mask]; // 11 load + r0 = mul_hi(r0, r4); // 12 mulhi + r5 = r5 + r1 + ((((sel >> 30u) & 1u) != 0u) ? 0xd3177981u : 0xc7934706u); // 13 add + r0 = r0 ^ ds[r4 & mask]; // 14 load + r2 = r2 - r4; // 15 sub + r2 = r2 ^ ds[r0 & mask]; // 16 load + r7 = r7 ^ ds[r2 & mask]; // 17 load + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r7 = r7 ^ t_; } // 18 shfl + r5 = r5 * r0; // 19 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // 20 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 16u); r2 = r2 ^ t_; } // 21 shfl + r6 = mul_hi(r6, r2); // 22 mulhi + r6 = r6 ^ ds[r1 & mask]; // 23 load + r5 = r5 * r0; // 24 mul + r5 = rotl_imm(r5, 19u); // 25 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 2u); r7 = r7 ^ t_; } // 26 shfl + r0 = r0 ^ r5; // 27 xor + r0 = r0 ^ r4; // 28 xor + r3 = r3 - r0; // 29 sub + r5 = r5 * r1; // 30 mul + r7 = r7 ^ ds[r2 & mask]; // 31 load + r1 = r1 ^ ds[r0 & mask]; // 32 load + r5 = r5 ^ r6; // 33 xor + r5 = r5 ^ ds[r1 & mask]; // 34 load + r0 = mul_hi(r0, r5); // 35 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r5 = r5 ^ t_; } // 36 shfl + r7 = r7 ^ ds[r0 & mask]; // 37 load + r3 = r3 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0x230c005cu : 0x75ba2fadu); // 38 add + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 4u); r1 = r1 ^ t_; } // 39 shfl + r2 = r2 ^ r5; // 40 xor + r3 = r6 * r3 + r3; // 41 mad + r6 = r6 - r7; // 42 sub + r7 = r7 ^ r0; // 43 xor + r1 = r1 ^ ds[r7 & mask]; // 44 load + r2 = r2 * r3; // 45 mul + r1 = mul_hi(r1, r5); // 46 mulhi + r4 = r4 - r3; // 47 sub + r2 = rotr_var(r2, r6); // 48 rotr + r3 = r3 ^ ds[r5 & mask]; // 49 load + r1 = r1 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x1907970cu : 0x81b8bc2cu); // 50 add + r0 = r0 * r2; // 51 mul + r0 = r0 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x699fd448u : 0x4f92b968u); // 52 add + r1 = r1 + r0 + ((((sel >> 12u) & 1u) != 0u) ? 0x77b1520du : 0x2bb965afu); // 53 add + r7 = rotl_imm(r7, 14u); // 54 rotl + r3 = r3 + r7 + ((((sel >> 1u) & 1u) != 0u) ? 0xa54c55a0u : 0x7b0fe07au); // 55 add + r6 = r6 ^ ds[r7 & mask]; // 56 load + r1 = rotr_var(r1, r5); // 57 rotr + r5 = r5 ^ ds[r4 & mask]; // 58 load + r6 = r6 ^ ds[r2 & mask]; // 59 load + r3 = r5 * r0 + r3; // 60 mad + r5 = r5 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0xad7493e7u : 0xaf9dd72du); // 61 add + r4 = r4 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x1e07c3d9u : 0x89841d87u); // 62 add + r5 = rotl_imm(r5, 19u); // 63 rotl + // latency-shadow block (Counter ASIC 3.0 item 8): 1024 ALU instructions x 3 passes after instruction 63, no load + for (uint sh = 0u; sh < 3u; ++sh) { + r5 = r5 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x8bc12da9u : 0x92199f99u); // s0 add + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x63079e5au : 0x8d72d3adu); // s1 add + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 2u); r6 = r6 ^ t_; } // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + ((((sel >> 31u) & 1u) != 0u) ? 0x5d4c7a60u : 0xb21b4babu); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + ((((sel >> 16u) & 1u) != 0u) ? 0xc88e2942u : 0x2fe0e98bu); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r6 = r6 ^ t_; } // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 4u); r2 = r2 ^ t_; } // s12 shfl + r1 = r1 + r5 + ((((sel >> 25u) & 1u) != 0u) ? 0xbc48c63eu : 0xbdf8f9a5u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r2 = r2 ^ t_; } // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + ((((sel >> 1u) & 1u) != 0u) ? 0x96e8f127u : 0x45c37cecu); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = mul_hi(r6, r0); // s28 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r2 = r2 ^ t_; } // s29 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r1 = r1 ^ t_; } // s30 shfl + r1 = r1 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0xb1cdb2abu : 0x37985632u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // s33 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r0 = r0 ^ t_; } // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x856e0180u : 0x804e777eu); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xe9bd0cc4u : 0x0b06c8a7u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = mul_hi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = mul_hi(r4, r3); // s44 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xcdcb63f6u : 0xee822e17u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r4 = r4 ^ t_; } // s47 shfl + r6 = mul_hi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0xd4758987u : 0x3dfad1b6u); // s56 add + r4 = r4 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x0602d6beu : 0xfca75bc2u); // s57 add + r5 = mul_hi(r5, r6); // s58 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r2 = r2 ^ t_; } // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0x8596687au : 0xd71c02ffu); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 2u); r7 = r7 ^ t_; } // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0x08ac5733u : 0x3c6fe15du); // s72 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r3 = r3 ^ t_; } // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + ((((sel >> 1u) & 1u) != 0u) ? 0xc100b495u : 0x295d5faeu); // s77 add + r3 = mul_hi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + ((((sel >> 15u) & 1u) != 0u) ? 0x5cc59530u : 0x274a9221u); // s81 add + r7 = r7 + r3 + ((((sel >> 5u) & 1u) != 0u) ? 0x141479ecu : 0xc8651f8eu); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r2 = r2 ^ t_; } // s85 shfl + r3 = r3 ^ r2; // s86 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 2u); r5 = r5 ^ t_; } // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x883c0c92u : 0x53f915c2u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + ((((sel >> 31u) & 1u) != 0u) ? 0x3cc5bd20u : 0xe2be00a5u); // s91 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 1u); r7 = r7 ^ t_; } // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + ((((sel >> 17u) & 1u) != 0u) ? 0xbfd646cbu : 0x423fd9c9u); // s101 add + r7 = r7 + r6 + ((((sel >> 11u) & 1u) != 0u) ? 0x19b74a43u : 0x8d3c011du); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + ((((sel >> 15u) & 1u) != 0u) ? 0x7dcb7e18u : 0x8ce14721u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = mul_hi(r2, r0); // s109 mulhi + r1 = mul_hi(r1, r0); // s110 mulhi + r0 = r0 + r2 + ((((sel >> 28u) & 1u) != 0u) ? 0x3c179ad8u : 0x2d9fc6b9u); // s111 add + r2 = mul_hi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + ((((sel >> 22u) & 1u) != 0u) ? 0x47359729u : 0x502138e2u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = mul_hi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 2u); r4 = r4 ^ t_; } // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r7 = r7 ^ t_; } // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x6c57e4e7u : 0x33dff776u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + ((((sel >> 30u) & 1u) != 0u) ? 0xe8212c0cu : 0x5db25b34u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = mul_hi(r0, r5); // s138 mulhi + r2 = r2 + r7 + ((((sel >> 10u) & 1u) != 0u) ? 0xd44ff710u : 0x218d4090u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r3 = r3 ^ t_; } // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + ((((sel >> 29u) & 1u) != 0u) ? 0xb98942fau : 0xf4b1a8deu); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + ((((sel >> 17u) & 1u) != 0u) ? 0x0d48ba42u : 0x2bef10f2u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + ((((sel >> 30u) & 1u) != 0u) ? 0xc98dea9cu : 0xdc5cc080u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0x6c752dcbu : 0x18197438u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + ((((sel >> 3u) & 1u) != 0u) ? 0x8e481727u : 0xf1c46574u); // s163 add + r0 = mul_hi(r0, r4); // s164 mulhi + r2 = r2 + r6 + ((((sel >> 20u) & 1u) != 0u) ? 0x550ab406u : 0xac578137u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + ((((sel >> 14u) & 1u) != 0u) ? 0xaebb5966u : 0xa33e6706u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 8u); r7 = r7 ^ t_; } // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x5bb7550fu : 0xd94d55acu); // s184 add + r3 = r3 | r5; // s185 or + r6 = mul_hi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r7 = r7 ^ t_; } // s188 shfl + r6 = r6 + r5 + ((((sel >> 6u) & 1u) != 0u) ? 0x2a354e2du : 0x89e747feu); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = mul_hi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r4 = r4 ^ t_; } // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + ((((sel >> 7u) & 1u) != 0u) ? 0x10cfdc71u : 0xea03e8e7u); // s197 add + r7 = r7 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x66e148d3u : 0xa7ee0102u); // s198 add + r5 = r5 - r2; // s199 sub + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r5 = r5 ^ t_; } // s200 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 8u); r7 = r7 ^ t_; } // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0x8558b619u : 0x8379a4deu); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = mul_hi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 4u); r2 = r2 ^ t_; } // s209 shfl + r7 = r7 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0xf4049c4cu : 0xaa8cb14eu); // s210 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 16u); r7 = r7 ^ t_; } // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 16u); r3 = r3 ^ t_; } // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = mul_hi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r5 = r5 ^ t_; } // s222 shfl + r5 = mul_hi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0x2a7fecb2u : 0x1d176220u); // s230 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r1 = r1 ^ t_; } // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + ((((sel >> 25u) & 1u) != 0u) ? 0xadce39f3u : 0x17dafb4du); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + ((((sel >> 29u) & 1u) != 0u) ? 0x0e7033b6u : 0xf2f77d26u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + ((((sel >> 31u) & 1u) != 0u) ? 0x7b2ff6b7u : 0xfed2da4eu); // s247 add + r0 = r0 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0xb5fad7b1u : 0x03b2891cu); // s248 add + r5 = mul_hi(r5, r4); // s249 mulhi + r5 = r5 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0xa7e71c2fu : 0x042cd6e3u); // s250 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 1u); r6 = r6 ^ t_; } // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0xb83d78deu : 0x784a302bu); // s254 add + r2 = r2 - r4; // s255 sub + r3 = r3 - r4; // s256 sub + r2 = r2 * r4; // s257 mul + r4 = r0 * r6 + r4; // s258 mad + r5 = r5 | r0; // s259 or + r4 = r4 ^ r6; // s260 xor + r6 = mul_hi(r6, r3); // s261 mulhi + r2 = r2 * r6; // s262 mul + r5 = rotl_imm(r5, 1u); // s263 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 8u); r7 = r7 ^ t_; } // s264 shfl + r3 = r3 * r2; // s265 mul + r2 = r2 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x99a1d1b6u : 0x3dddf1b2u); // s266 add + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 8u); r2 = r2 ^ t_; } // s267 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r0 = r0 ^ t_; } // s268 shfl + r4 = r4 - r2; // s269 sub + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 1u); r0 = r0 ^ t_; } // s270 shfl + r3 = r3 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x40ca287au : 0xcfc62661u); // s271 add + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 16u); r1 = r1 ^ t_; } // s272 shfl + r1 = r3 * r6 + r1; // s273 mad + r7 = r7 + r6 + ((((sel >> 30u) & 1u) != 0u) ? 0xed4b65adu : 0x44caede3u); // s274 add + r5 = r5 ^ r7; // s275 xor + r2 = r2 * r6; // s276 mul + r2 = r2 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0x0f45ae89u : 0x9aae6c12u); // s277 add + r2 = r2 ^ r6; // s278 xor + r1 = r1 - r2; // s279 sub + r5 = r5 ^ r1; // s280 xor + r7 = r7 ^ r1; // s281 xor + r7 = r7 - r1; // s282 sub + r5 = r5 - r7; // s283 sub + r7 = r0 * r6 + r7; // s284 mad + r5 = mul_hi(r5, r4); // s285 mulhi + r3 = r3 - r5; // s286 sub + r5 = r5 - r1; // s287 sub + r1 = r3 * r7 + r1; // s288 mad + r3 = rotl_imm(r3, 9u); // s289 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 8u); r5 = r5 ^ t_; } // s290 shfl + r7 = r7 + r2 + ((((sel >> 1u) & 1u) != 0u) ? 0xe086d3b6u : 0x2307120bu); // s291 add + r4 = r4 ^ r3; // s292 xor + r3 = rotl_imm(r3, 14u); // s293 rotl + r5 = r5 - r4; // s294 sub + r2 = mul_hi(r2, r3); // s295 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r1 = r1 ^ t_; } // s296 shfl + r3 = r6 * r1 + r3; // s297 mad + r4 = r4 ^ r1; // s298 xor + r6 = r6 + r3 + ((((sel >> 24u) & 1u) != 0u) ? 0xadbeb223u : 0x4e3a12e5u); // s299 add + r6 = mul_hi(r6, r5); // s300 mulhi + r7 = rotr_var(r7, r5); // s301 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 16u); r5 = r5 ^ t_; } // s302 shfl + r3 = r3 ^ r4; // s303 xor + r2 = r3 * r1 + r2; // s304 mad + r1 = r1 ^ r7; // s305 xor + r1 = r1 + r0 + ((((sel >> 22u) & 1u) != 0u) ? 0x0d8f1149u : 0x51ab0157u); // s306 add + r2 = r2 + r1 + ((((sel >> 24u) & 1u) != 0u) ? 0x99a96de9u : 0x3b5e8835u); // s307 add + r1 = r5 * r5 + r1; // s308 mad + r2 = r2 * r4; // s309 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 8u); r3 = r3 ^ t_; } // s310 shfl + r0 = r0 ^ r4; // s311 xor + r5 = mul_hi(r5, r2); // s312 mulhi + r7 = r7 + r2 + ((((sel >> 30u) & 1u) != 0u) ? 0x86ddfba7u : 0x81f3297cu); // s313 add + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x38aa230au : 0x838e4a2fu); // s314 add + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 16u); r7 = r7 ^ t_; } // s315 shfl + r7 = r7 - r5; // s316 sub + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r5 = r5 ^ t_; } // s317 shfl + r1 = r1 + r3 + ((((sel >> 11u) & 1u) != 0u) ? 0xa6399179u : 0xebcad805u); // s318 add + r7 = rotl_imm(r7, 21u); // s319 rotl + r7 = r7 ^ r6; // s320 xor + r7 = r7 | r6; // s321 or + r5 = r5 + r3 + ((((sel >> 25u) & 1u) != 0u) ? 0x4de83051u : 0x4c906f73u); // s322 add + r0 = r0 + r4 + ((((sel >> 14u) & 1u) != 0u) ? 0xd3d821c5u : 0x742ec195u); // s323 add + r6 = r6 ^ r2; // s324 xor + r6 = rotl_imm(r6, 1u); // s325 rotl + r4 = rotl_imm(r4, 24u); // s326 rotl + r4 = r4 | r3; // s327 or + r2 = r1 * r3 + r2; // s328 mad + r2 = r2 ^ r7; // s329 xor + r2 = r2 | r3; // s330 or + r7 = r7 - r1; // s331 sub + r3 = r3 + r6 + ((((sel >> 0u) & 1u) != 0u) ? 0xc06f831eu : 0xb86750e9u); // s332 add + r7 = rotl_imm(r7, 25u); // s333 rotl + r3 = r0 * r0 + r3; // s334 mad + r2 = r2 + r5 + ((((sel >> 28u) & 1u) != 0u) ? 0x5225df1du : 0xb57956eeu); // s335 add + r3 = r1 * r6 + r3; // s336 mad + r4 = r2 * r2 + r4; // s337 mad + r7 = r7 * r2; // s338 mul + r1 = r1 * r6; // s339 mul + r4 = r4 + r5 + ((((sel >> 5u) & 1u) != 0u) ? 0xb73822ceu : 0x23f6425fu); // s340 add + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 2u); r5 = r5 ^ t_; } // s341 shfl + r6 = r6 ^ r5; // s342 xor + r0 = rotl_imm(r0, 13u); // s343 rotl + r0 = rotr_var(r0, r3); // s344 rotr + r1 = r1 - r0; // s345 sub + r6 = rotr_var(r6, r1); // s346 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 4u); r6 = r6 ^ t_; } // s347 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 8u); r5 = r5 ^ t_; } // s348 shfl + r5 = r5 ^ r3; // s349 xor + r1 = r4 * r0 + r1; // s350 mad + r3 = rotr_var(r3, r1); // s351 rotr + r1 = rotl_imm(r1, 13u); // s352 rotl + r3 = r3 + r0 + ((((sel >> 26u) & 1u) != 0u) ? 0xfa0c560eu : 0x0dce5917u); // s353 add + r3 = mul_hi(r3, r2); // s354 mulhi + r1 = r2 * r4 + r1; // s355 mad + r0 = r0 ^ r1; // s356 xor + r7 = r7 * r5; // s357 mul + r0 = rotl_imm(r0, 5u); // s358 rotl + r2 = r7 * r7 + r2; // s359 mad + r2 = r2 | r6; // s360 or + r6 = r6 + r1 + ((((sel >> 19u) & 1u) != 0u) ? 0x277e027au : 0x7c83b79au); // s361 add + r0 = r0 * r2; // s362 mul + r3 = r3 * r6; // s363 mul + r2 = rotr_var(r2, r4); // s364 rotr + r5 = r5 + r1 + ((((sel >> 1u) & 1u) != 0u) ? 0x52275ea4u : 0x271f2385u); // s365 add + r1 = r1 * r6; // s366 mul + r0 = r0 + r7 + ((((sel >> 30u) & 1u) != 0u) ? 0x8f8b4093u : 0x4c66800fu); // s367 add + r4 = rotr_var(r4, r0); // s368 rotr + r4 = rotr_var(r4, r0); // s369 rotr + r1 = r0 * r6 + r1; // s370 mad + r0 = r0 - r5; // s371 sub + r7 = r7 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0x9a7dcadcu : 0x7dad1ed5u); // s372 add + r7 = r7 + r3 + ((((sel >> 20u) & 1u) != 0u) ? 0xf808c195u : 0x1ea3d58eu); // s373 add + r1 = r1 * r2; // s374 mul + r3 = r7 * r2 + r3; // s375 mad + r4 = r4 ^ r1; // s376 xor + r1 = r1 | r0; // s377 or + r5 = r5 + r0 + ((((sel >> 26u) & 1u) != 0u) ? 0x427ed5ceu : 0x98b36d10u); // s378 add + r6 = r6 * r0; // s379 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 1u); r7 = r7 ^ t_; } // s380 shfl + r4 = r4 + r0 + ((((sel >> 18u) & 1u) != 0u) ? 0x38f848b9u : 0xb19cab2du); // s381 add + r3 = r5 * r2 + r3; // s382 mad + r0 = r0 | r7; // s383 or + r5 = r5 - r4; // s384 sub + r1 = r1 - r5; // s385 sub + r2 = r2 - r0; // s386 sub + r5 = r5 + r2 + ((((sel >> 17u) & 1u) != 0u) ? 0xffc20cf8u : 0x341056b0u); // s387 add + r1 = rotl_imm(r1, 26u); // s388 rotl + r2 = r2 ^ r5; // s389 xor + r5 = r7 * r0 + r5; // s390 mad + r3 = mul_hi(r3, r2); // s391 mulhi + r5 = r5 + r4 + ((((sel >> 0u) & 1u) != 0u) ? 0xfb939f2bu : 0x78aa571au); // s392 add + r5 = r5 | r2; // s393 or + r1 = mul_hi(r1, r7); // s394 mulhi + r4 = r4 - r2; // s395 sub + r7 = r7 - r1; // s396 sub + r0 = r0 + r1 + ((((sel >> 2u) & 1u) != 0u) ? 0xa9c6c9fbu : 0x31af4767u); // s397 add + r3 = r3 * r1; // s398 mul + r1 = r1 - r7; // s399 sub + r7 = r7 + r6 + ((((sel >> 8u) & 1u) != 0u) ? 0x34f9b056u : 0x266d4c34u); // s400 add + r5 = rotl_imm(r5, 5u); // s401 rotl + r0 = r0 + r4 + ((((sel >> 23u) & 1u) != 0u) ? 0x79822c64u : 0x7241955eu); // s402 add + r2 = r4 * r0 + r2; // s403 mad + r5 = rotl_imm(r5, 29u); // s404 rotl + r3 = r3 - r5; // s405 sub + r2 = r2 + r3 + ((((sel >> 27u) & 1u) != 0u) ? 0xda046091u : 0xf65aca5du); // s406 add + r4 = mul_hi(r4, r7); // s407 mulhi + r2 = r2 + r1 + ((((sel >> 14u) & 1u) != 0u) ? 0x167aba1cu : 0x6a00cefbu); // s408 add + r2 = r6 * r6 + r2; // s409 mad + r6 = rotl_imm(r6, 26u); // s410 rotl + r6 = r6 | r7; // s411 or + r1 = rotl_imm(r1, 20u); // s412 rotl + r7 = r7 * r5; // s413 mul + r6 = r6 - r0; // s414 sub + r6 = mul_hi(r6, r0); // s415 mulhi + r3 = rotl_imm(r3, 5u); // s416 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r1 = r1 ^ t_; } // s417 shfl + r0 = r0 * r4; // s418 mul + r4 = rotr_var(r4, r7); // s419 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r7 = r7 ^ t_; } // s420 shfl + r5 = r3 * r6 + r5; // s421 mad + r3 = r3 ^ r4; // s422 xor + r3 = rotr_var(r3, r7); // s423 rotr + r4 = r4 + r1 + ((((sel >> 26u) & 1u) != 0u) ? 0xbb669c17u : 0xba29da18u); // s424 add + r7 = rotr_var(r7, r5); // s425 rotr + r2 = r2 * r6; // s426 mul + r1 = r1 + r4 + ((((sel >> 16u) & 1u) != 0u) ? 0xc6b45a76u : 0x4f70e34fu); // s427 add + r1 = rotl_imm(r1, 1u); // s428 rotl + r6 = mul_hi(r6, r5); // s429 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xff610984u : 0x3883e0f5u); // s430 add + r4 = r4 | r3; // s431 or + r7 = r7 ^ r5; // s432 xor + r3 = mul_hi(r3, r2); // s433 mulhi + r2 = r2 ^ r6; // s434 xor + r4 = r4 | r3; // s435 or + r0 = r0 + r1 + ((((sel >> 9u) & 1u) != 0u) ? 0xf37057feu : 0xb1b15861u); // s436 add + r7 = r7 + r4 + ((((sel >> 4u) & 1u) != 0u) ? 0x61793eafu : 0x2e9e173fu); // s437 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 1u); r5 = r5 ^ t_; } // s438 shfl + r6 = r0 * r3 + r6; // s439 mad + r5 = r5 ^ r2; // s440 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 16u); r0 = r0 ^ t_; } // s441 shfl + r6 = r6 * r3; // s442 mul + r5 = r5 - r4; // s443 sub + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r2 = r2 ^ t_; } // s444 shfl + r0 = r0 + r5 + ((((sel >> 12u) & 1u) != 0u) ? 0x69def831u : 0x646856aau); // s445 add + r4 = r4 + r6 + ((((sel >> 23u) & 1u) != 0u) ? 0x1f8ecb8bu : 0x58a3f8fcu); // s446 add + r4 = r0 * r2 + r4; // s447 mad + r5 = r5 * r0; // s448 mul + r2 = r2 + r5 + ((((sel >> 11u) & 1u) != 0u) ? 0x7ecb876du : 0x48d3062du); // s449 add + r2 = r5 * r6 + r2; // s450 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r7 = r7 ^ t_; } // s451 shfl + r2 = r2 * r5; // s452 mul + r5 = mul_hi(r5, r4); // s453 mulhi + r1 = r1 ^ r7; // s454 xor + r2 = r2 * r7; // s455 mul + r1 = r1 * r3; // s456 mul + r3 = r6 * r2 + r3; // s457 mad + r7 = r7 - r0; // s458 sub + r2 = r4 * r5 + r2; // s459 mad + r0 = rotl_imm(r0, 2u); // s460 rotl + r4 = r4 ^ r2; // s461 xor + r4 = r4 + r0 + ((((sel >> 18u) & 1u) != 0u) ? 0x7b093757u : 0xb41dd69bu); // s462 add + r6 = r6 + r1 + ((((sel >> 3u) & 1u) != 0u) ? 0x916e1b7eu : 0xb042032eu); // s463 add + r2 = r2 + r6 + ((((sel >> 8u) & 1u) != 0u) ? 0x6d42b978u : 0x4e68a2a0u); // s464 add + r3 = r3 - r2; // s465 sub + r2 = r2 * r5; // s466 mul + r7 = rotl_imm(r7, 28u); // s467 rotl + r0 = r0 - r3; // s468 sub + r7 = mul_hi(r7, r2); // s469 mulhi + r7 = r7 | r6; // s470 or + r7 = rotl_imm(r7, 28u); // s471 rotl + r0 = r0 * r6; // s472 mul + r2 = r2 | r1; // s473 or + r2 = r2 + r4 + ((((sel >> 14u) & 1u) != 0u) ? 0x20c5276bu : 0x13ec3b3eu); // s474 add + r2 = rotr_var(r2, r6); // s475 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 16u); r6 = r6 ^ t_; } // s476 shfl + r2 = rotl_imm(r2, 15u); // s477 rotl + r5 = rotr_var(r5, r4); // s478 rotr + r3 = rotl_imm(r3, 26u); // s479 rotl + r5 = r5 | r6; // s480 or + r3 = rotl_imm(r3, 29u); // s481 rotl + r0 = rotr_var(r0, r7); // s482 rotr + r1 = r1 - r0; // s483 sub + r0 = r2 * r5 + r0; // s484 mad + r6 = r6 ^ r4; // s485 xor + r6 = r6 ^ r0; // s486 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 4u); r3 = r3 ^ t_; } // s487 shfl + r6 = mul_hi(r6, r0); // s488 mulhi + r1 = r1 * r0; // s489 mul + r3 = r3 ^ r6; // s490 xor + r3 = r3 * r6; // s491 mul + r0 = r0 * r3; // s492 mul + r4 = r4 | r3; // s493 or + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 8u); r0 = r0 ^ t_; } // s494 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 16u); r0 = r0 ^ t_; } // s495 shfl + r6 = r5 * r2 + r6; // s496 mad + r5 = r5 * r6; // s497 mul + r3 = r3 ^ r1; // s498 xor + r0 = r0 + r1 + ((((sel >> 20u) & 1u) != 0u) ? 0x19f4c710u : 0x53e99acau); // s499 add + r6 = r5 * r2 + r6; // s500 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r7 = r7 ^ t_; } // s501 shfl + r3 = r3 - r5; // s502 sub + r0 = rotl_imm(r0, 8u); // s503 rotl + r3 = r3 ^ r1; // s504 xor + r7 = r7 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x7a6ac7b5u : 0x0867fe20u); // s505 add + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 2u); r0 = r0 ^ t_; } // s506 shfl + r0 = r0 * r1; // s507 mul + r6 = r6 | r5; // s508 or + r2 = r2 * r7; // s509 mul + r1 = r1 + r5 + ((((sel >> 21u) & 1u) != 0u) ? 0xd77f6a03u : 0xd7fdc3ecu); // s510 add + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 8u); r3 = r3 ^ t_; } // s511 shfl + r6 = r6 + r3 + ((((sel >> 9u) & 1u) != 0u) ? 0x5c22b0b5u : 0x297a096au); // s512 add + r7 = r7 | r0; // s513 or + r7 = r7 + r3 + ((((sel >> 27u) & 1u) != 0u) ? 0x4caafacdu : 0x5de1d1d1u); // s514 add + r1 = mul_hi(r1, r0); // s515 mulhi + r0 = r0 - r6; // s516 sub + r2 = r2 - r1; // s517 sub + r6 = r5 * r7 + r6; // s518 mad + r2 = r2 ^ r7; // s519 xor + r1 = r1 | r5; // s520 or + r0 = r4 * r6 + r0; // s521 mad + r4 = r4 + r6 + ((((sel >> 29u) & 1u) != 0u) ? 0xb1091e80u : 0x2caeeca3u); // s522 add + r7 = r6 * r5 + r7; // s523 mad + r7 = r7 - r2; // s524 sub + r0 = r0 * r7; // s525 mul + r0 = r0 ^ r7; // s526 xor + r1 = mul_hi(r1, r4); // s527 mulhi + r0 = rotr_var(r0, r5); // s528 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 16u); r2 = r2 ^ t_; } // s529 shfl + r2 = mul_hi(r2, r3); // s530 mulhi + r1 = r1 | r4; // s531 or + r6 = r6 + r4 + ((((sel >> 13u) & 1u) != 0u) ? 0xbda312aeu : 0xbe9e1eb0u); // s532 add + r7 = r7 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x1ec16229u : 0xbe5d93a3u); // s533 add + r0 = r6 * r4 + r0; // s534 mad + r0 = r0 + r5 + ((((sel >> 23u) & 1u) != 0u) ? 0x500828bcu : 0x5e23583bu); // s535 add + r6 = r5 * r0 + r6; // s536 mad + r2 = r2 ^ r4; // s537 xor + r6 = r3 * r5 + r6; // s538 mad + r6 = r6 + r4 + ((((sel >> 3u) & 1u) != 0u) ? 0x852321dcu : 0x43c32138u); // s539 add + r2 = r2 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x44e6ae63u : 0xaff69493u); // s540 add + r3 = mul_hi(r3, r5); // s541 mulhi + r1 = r1 + r7 + ((((sel >> 5u) & 1u) != 0u) ? 0x909712feu : 0xc5de29efu); // s542 add + r1 = r3 * r2 + r1; // s543 mad + r1 = r1 + r3 + ((((sel >> 11u) & 1u) != 0u) ? 0xfb7b42b9u : 0x1e20e084u); // s544 add + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 4u); r4 = r4 ^ t_; } // s545 shfl + r6 = r6 + r1 + ((((sel >> 10u) & 1u) != 0u) ? 0x6e036dd4u : 0x9370db38u); // s546 add + r4 = r4 ^ r6; // s547 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r5 = r5 ^ t_; } // s548 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r3 = r3 ^ t_; } // s549 shfl + r1 = rotr_var(r1, r7); // s550 rotr + r0 = r3 * r2 + r0; // s551 mad + r7 = mul_hi(r7, r4); // s552 mulhi + r0 = r0 + r4 + ((((sel >> 13u) & 1u) != 0u) ? 0xd3c9174du : 0xbf2488f6u); // s553 add + r1 = rotl_imm(r1, 1u); // s554 rotl + r7 = rotr_var(r7, r3); // s555 rotr + r7 = rotr_var(r7, r3); // s556 rotr + r6 = r2 * r0 + r6; // s557 mad + r6 = r6 ^ r1; // s558 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r5 = r5 ^ t_; } // s559 shfl + r5 = r5 ^ r3; // s560 xor + r5 = r5 * r1; // s561 mul + r3 = rotl_imm(r3, 31u); // s562 rotl + r6 = rotr_var(r6, r2); // s563 rotr + r7 = r7 | r2; // s564 or + r6 = rotr_var(r6, r0); // s565 rotr + r2 = r2 * r0; // s566 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 2u); r4 = r4 ^ t_; } // s567 shfl + r3 = r3 * r0; // s568 mul + r4 = r4 + r2 + ((((sel >> 9u) & 1u) != 0u) ? 0xa3149efau : 0xd9160c83u); // s569 add + r4 = mul_hi(r4, r2); // s570 mulhi + r3 = r3 + r0 + ((((sel >> 10u) & 1u) != 0u) ? 0x9cab407bu : 0x3bdc971cu); // s571 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 16u); r1 = r1 ^ t_; } // s572 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 4u); r2 = r2 ^ t_; } // s573 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r2 = r2 ^ t_; } // s574 shfl + r0 = r0 ^ r7; // s575 xor + r0 = r0 + r5 + ((((sel >> 27u) & 1u) != 0u) ? 0x747b0838u : 0x17979608u); // s576 add + r0 = r0 ^ r4; // s577 xor + r6 = r6 - r1; // s578 sub + r4 = rotr_var(r4, r2); // s579 rotr + r2 = r2 ^ r3; // s580 xor + r6 = r7 * r2 + r6; // s581 mad + r5 = r5 + r2 + ((((sel >> 7u) & 1u) != 0u) ? 0x02246c0cu : 0x1c10ec5cu); // s582 add + r3 = mul_hi(r3, r6); // s583 mulhi + r2 = r2 ^ r5; // s584 xor + r6 = rotl_imm(r6, 24u); // s585 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 8u); r3 = r3 ^ t_; } // s586 shfl + r1 = r2 * r6 + r1; // s587 mad + r3 = r3 + r7 + ((((sel >> 21u) & 1u) != 0u) ? 0xbea44bd0u : 0x88758873u); // s588 add + r1 = rotl_imm(r1, 30u); // s589 rotl + r7 = r7 * r1; // s590 mul + r3 = r3 + r6 + ((((sel >> 10u) & 1u) != 0u) ? 0x8e0eb890u : 0xf436bb64u); // s591 add + r7 = r6 * r1 + r7; // s592 mad + r0 = r3 * r5 + r0; // s593 mad + r5 = rotr_var(r5, r4); // s594 rotr + r4 = r4 | r0; // s595 or + r6 = r3 * r0 + r6; // s596 mad + r2 = r2 + r1 + ((((sel >> 31u) & 1u) != 0u) ? 0x29b853b3u : 0xb465e47eu); // s597 add + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 16u); r1 = r1 ^ t_; } // s598 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 4u); r4 = r4 ^ t_; } // s599 shfl + r6 = r2 * r0 + r6; // s600 mad + r5 = mul_hi(r5, r0); // s601 mulhi + r6 = r6 * r7; // s602 mul + r4 = r4 | r7; // s603 or + r7 = r7 - r0; // s604 sub + r7 = rotr_var(r7, r4); // s605 rotr + r4 = r0 * r3 + r4; // s606 mad + r4 = mul_hi(r4, r3); // s607 mulhi + r0 = r0 + r1 + ((((sel >> 28u) & 1u) != 0u) ? 0xb7536963u : 0x22ce199du); // s608 add + r2 = r2 - r5; // s609 sub + r2 = r2 ^ r0; // s610 xor + r5 = r5 * r4; // s611 mul + r3 = rotl_imm(r3, 25u); // s612 rotl + r7 = rotl_imm(r7, 13u); // s613 rotl + r4 = r4 * r7; // s614 mul + r5 = r4 * r2 + r5; // s615 mad + r0 = r0 ^ r5; // s616 xor + r7 = r5 * r4 + r7; // s617 mad + r6 = r6 - r4; // s618 sub + r3 = r3 * r4; // s619 mul + r1 = rotl_imm(r1, 24u); // s620 rotl + r1 = r1 ^ r2; // s621 xor + r4 = r4 | r3; // s622 or + r7 = r7 * r2; // s623 mul + r6 = r6 + r1 + ((((sel >> 20u) & 1u) != 0u) ? 0xe37b1e20u : 0x2dbf6ed0u); // s624 add + r4 = r4 ^ r5; // s625 xor + r4 = r6 * r2 + r4; // s626 mad + r1 = r1 ^ r6; // s627 xor + r6 = r6 + r3 + ((((sel >> 12u) & 1u) != 0u) ? 0xf5a2a9f7u : 0x9dc2b9d0u); // s628 add + r7 = r7 - r5; // s629 sub + r1 = mul_hi(r1, r7); // s630 mulhi + r1 = rotr_var(r1, r3); // s631 rotr + r4 = r4 | r6; // s632 or + r2 = r2 + r5 + ((((sel >> 24u) & 1u) != 0u) ? 0x982bfc08u : 0x9c1fba1bu); // s633 add + r6 = r6 * r5; // s634 mul + r7 = r2 * r3 + r7; // s635 mad + r7 = mul_hi(r7, r4); // s636 mulhi + r5 = r5 ^ r0; // s637 xor + r0 = r0 * r1; // s638 mul + r4 = r4 ^ r6; // s639 xor + r6 = r6 - r4; // s640 sub + r6 = mul_hi(r6, r4); // s641 mulhi + r4 = r4 - r0; // s642 sub + r7 = r7 - r5; // s643 sub + r3 = r0 * r7 + r3; // s644 mad + r3 = r3 | r5; // s645 or + r0 = r0 - r4; // s646 sub + r7 = r7 | r5; // s647 or + r7 = rotl_imm(r7, 1u); // s648 rotl + r5 = r5 + r6 + ((((sel >> 31u) & 1u) != 0u) ? 0x6e5d517fu : 0x9f5e0d19u); // s649 add + r1 = r1 | r2; // s650 or + r3 = rotl_imm(r3, 29u); // s651 rotl + r2 = r2 + r4 + ((((sel >> 2u) & 1u) != 0u) ? 0x30faf9c6u : 0xb53f6e74u); // s652 add + r0 = rotl_imm(r0, 21u); // s653 rotl + r1 = r1 ^ r3; // s654 xor + r4 = r7 * r2 + r4; // s655 mad + r4 = r4 - r6; // s656 sub + r4 = r4 * r6; // s657 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r2 = r2 ^ t_; } // s658 shfl + r7 = rotl_imm(r7, 31u); // s659 rotl + r4 = r4 ^ r6; // s660 xor + r1 = r1 - r3; // s661 sub + r3 = r3 * r6; // s662 mul + r5 = r5 * r3; // s663 mul + r7 = r7 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x8941d2e7u : 0x016e0094u); // s664 add + r1 = r1 ^ r2; // s665 xor + r1 = r1 - r0; // s666 sub + r4 = r4 ^ r7; // s667 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 1u); r7 = r7 ^ t_; } // s668 shfl + r1 = rotr_var(r1, r4); // s669 rotr + r2 = r2 + r3 + ((((sel >> 14u) & 1u) != 0u) ? 0x15289435u : 0x9af12ca6u); // s670 add + r2 = rotr_var(r2, r4); // s671 rotr + r4 = r6 * r7 + r4; // s672 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r2 = r2 ^ t_; } // s673 shfl + r6 = r4 * r2 + r6; // s674 mad + r2 = r4 * r6 + r2; // s675 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 16u); r3 = r3 ^ t_; } // s676 shfl + r1 = rotr_var(r1, r0); // s677 rotr + r0 = r0 - r2; // s678 sub + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 16u); r5 = r5 ^ t_; } // s679 shfl + r1 = r1 ^ r0; // s680 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r1 = r1 ^ t_; } // s681 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r0 = r0 ^ t_; } // s682 shfl + r2 = r3 * r3 + r2; // s683 mad + r4 = r4 - r6; // s684 sub + r5 = r5 ^ r3; // s685 xor + r2 = r2 - r5; // s686 sub + r4 = r4 - r5; // s687 sub + r5 = r4 * r7 + r5; // s688 mad + r6 = r6 * r7; // s689 mul + r1 = r1 * r5; // s690 mul + r4 = rotr_var(r4, r3); // s691 rotr + r2 = r2 ^ r4; // s692 xor + r0 = rotl_imm(r0, 2u); // s693 rotl + r5 = r5 + r2 + ((((sel >> 23u) & 1u) != 0u) ? 0x49801084u : 0x4fc762c9u); // s694 add + r0 = r0 + r4 + ((((sel >> 14u) & 1u) != 0u) ? 0x5f403cd5u : 0x626c00f5u); // s695 add + r6 = rotl_imm(r6, 25u); // s696 rotl + r3 = r3 ^ r7; // s697 xor + r0 = r0 * r2; // s698 mul + r5 = rotr_var(r5, r1); // s699 rotr + r3 = r3 ^ r7; // s700 xor + r4 = r4 | r3; // s701 or + r7 = r7 * r3; // s702 mul + r4 = rotl_imm(r4, 24u); // s703 rotl + r5 = r5 + r4 + ((((sel >> 17u) & 1u) != 0u) ? 0xad5e1851u : 0xc08bb414u); // s704 add + r0 = r6 * r5 + r0; // s705 mad + r4 = mul_hi(r4, r1); // s706 mulhi + r4 = rotr_var(r4, r3); // s707 rotr + r3 = rotr_var(r3, r6); // s708 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 16u); r6 = r6 ^ t_; } // s709 shfl + r3 = r2 * r6 + r3; // s710 mad + r1 = r1 * r4; // s711 mul + r3 = r3 + r5 + ((((sel >> 13u) & 1u) != 0u) ? 0x407f7c4du : 0xdc55338fu); // s712 add + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 2u); r6 = r6 ^ t_; } // s713 shfl + r1 = r1 ^ r0; // s714 xor + r7 = r1 * r1 + r7; // s715 mad + r4 = r4 | r0; // s716 or + r6 = r6 * r4; // s717 mul + r0 = r0 - r5; // s718 sub + r1 = r1 ^ r4; // s719 xor + r4 = mul_hi(r4, r6); // s720 mulhi + r1 = r1 + r0 + ((((sel >> 13u) & 1u) != 0u) ? 0xc2093fcau : 0xb2ce569eu); // s721 add + r4 = mul_hi(r4, r2); // s722 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 16u); r6 = r6 ^ t_; } // s723 shfl + r5 = r3 * r0 + r5; // s724 mad + r5 = mul_hi(r5, r0); // s725 mulhi + r2 = rotr_var(r2, r5); // s726 rotr + r5 = r5 + r0 + ((((sel >> 20u) & 1u) != 0u) ? 0x48cdf1c1u : 0x4e8aaad5u); // s727 add + r1 = r1 * r0; // s728 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 1u); r3 = r3 ^ t_; } // s729 shfl + r4 = r4 * r6; // s730 mul + r4 = r4 - r6; // s731 sub + r4 = r4 ^ r2; // s732 xor + r5 = r5 * r6; // s733 mul + r7 = rotr_var(r7, r3); // s734 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 1u); r1 = r1 ^ t_; } // s735 shfl + r1 = mul_hi(r1, r0); // s736 mulhi + r2 = r2 * r6; // s737 mul + r5 = rotl_imm(r5, 27u); // s738 rotl + r2 = mul_hi(r2, r3); // s739 mulhi + r5 = r3 * r5 + r5; // s740 mad + r2 = rotl_imm(r2, 11u); // s741 rotl + r6 = r6 | r2; // s742 or + r2 = r2 ^ r3; // s743 xor + r3 = r3 * r1; // s744 mul + r4 = mul_hi(r4, r2); // s745 mulhi + r5 = r5 ^ r6; // s746 xor + r6 = r6 + r7 + ((((sel >> 11u) & 1u) != 0u) ? 0x0d6b844eu : 0x78fc162du); // s747 add + r1 = rotl_imm(r1, 27u); // s748 rotl + r4 = rotr_var(r4, r1); // s749 rotr + r5 = r5 ^ r7; // s750 xor + r4 = rotr_var(r4, r3); // s751 rotr + r5 = r5 * r2; // s752 mul + r1 = r6 * r7 + r1; // s753 mad + r0 = r0 ^ r1; // s754 xor + r7 = r7 - r1; // s755 sub + r0 = r0 + r4 + ((((sel >> 5u) & 1u) != 0u) ? 0xb74ac71eu : 0x68aab88bu); // s756 add + r7 = r7 + r5 + ((((sel >> 0u) & 1u) != 0u) ? 0xf81f5b66u : 0xba5c123au); // s757 add + r0 = r7 * r2 + r0; // s758 mad + r1 = r1 | r0; // s759 or + r4 = mul_hi(r4, r6); // s760 mulhi + r0 = mul_hi(r0, r7); // s761 mulhi + r3 = rotr_var(r3, r4); // s762 rotr + r3 = rotl_imm(r3, 30u); // s763 rotl + r6 = r6 * r2; // s764 mul + r6 = r6 ^ r4; // s765 xor + r3 = r3 + r4 + ((((sel >> 0u) & 1u) != 0u) ? 0x96dabea6u : 0x6eb1d82au); // s766 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 1u); r0 = r0 ^ t_; } // s767 shfl + r3 = rotl_imm(r3, 8u); // s768 rotl + r7 = r7 * r4; // s769 mul + r6 = r1 * r2 + r6; // s770 mad + r2 = r2 ^ r7; // s771 xor + r6 = r6 * r0; // s772 mul + r2 = r2 - r1; // s773 sub + r1 = r0 * r1 + r1; // s774 mad + r5 = mul_hi(r5, r7); // s775 mulhi + r0 = rotr_var(r0, r4); // s776 rotr + r6 = r6 ^ r0; // s777 xor + r4 = mul_hi(r4, r7); // s778 mulhi + r1 = r3 * r0 + r1; // s779 mad + r6 = r6 + r4 + ((((sel >> 2u) & 1u) != 0u) ? 0x903f3f77u : 0x11d7b79au); // s780 add + r4 = r4 ^ r7; // s781 xor + r1 = r1 + r2 + ((((sel >> 14u) & 1u) != 0u) ? 0x2ca81d8du : 0x1791eaddu); // s782 add + r2 = rotr_var(r2, r1); // s783 rotr + r4 = r4 * r6; // s784 mul + r1 = r1 ^ r6; // s785 xor + r4 = r4 - r0; // s786 sub + r3 = r3 ^ r4; // s787 xor + r4 = r4 * r1; // s788 mul + r4 = r6 * r7 + r4; // s789 mad + r5 = r5 - r0; // s790 sub + r2 = r2 * r0; // s791 mul + r7 = rotl_imm(r7, 12u); // s792 rotl + r2 = r7 * r3 + r2; // s793 mad + r1 = r4 * r4 + r1; // s794 mad + r6 = r6 + r4 + ((((sel >> 15u) & 1u) != 0u) ? 0xf66fad29u : 0xc08797bbu); // s795 add + r1 = r1 - r4; // s796 sub + r5 = r5 * r2; // s797 mul + r5 = r5 ^ r2; // s798 xor + r0 = r0 * r1; // s799 mul + r6 = r6 + r4 + ((((sel >> 13u) & 1u) != 0u) ? 0x2d82a681u : 0x6d4a6371u); // s800 add + r1 = r6 * r1 + r1; // s801 mad + r0 = r0 - r2; // s802 sub + r6 = r6 ^ r2; // s803 xor + r7 = rotl_imm(r7, 24u); // s804 rotl + r6 = r6 ^ r7; // s805 xor + r7 = r7 | r0; // s806 or + r0 = rotl_imm(r0, 5u); // s807 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 2u); r1 = r1 ^ t_; } // s808 shfl + r4 = r1 * r5 + r4; // s809 mad + r0 = r0 + r2 + ((((sel >> 14u) & 1u) != 0u) ? 0x63e62197u : 0x0092eb62u); // s810 add + r5 = r5 - r3; // s811 sub + r2 = r1 * r5 + r2; // s812 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 16u); r6 = r6 ^ t_; } // s813 shfl + r7 = r5 * r1 + r7; // s814 mad + r0 = mul_hi(r0, r7); // s815 mulhi + r2 = r2 | r1; // s816 or + r7 = mul_hi(r7, r3); // s817 mulhi + r2 = r2 ^ r4; // s818 xor + r4 = r4 + r3 + ((((sel >> 0u) & 1u) != 0u) ? 0x27d94f57u : 0xbb69174fu); // s819 add + r5 = r5 + r3 + ((((sel >> 1u) & 1u) != 0u) ? 0x82285691u : 0xda6759f2u); // s820 add + r1 = r1 + r3 + ((((sel >> 31u) & 1u) != 0u) ? 0xe50565d8u : 0x9ad4b47fu); // s821 add + r5 = rotl_imm(r5, 6u); // s822 rotl + r3 = r3 - r0; // s823 sub + r6 = rotl_imm(r6, 12u); // s824 rotl + r4 = r4 | r5; // s825 or + r3 = r3 ^ r2; // s826 xor + r4 = r4 + r0 + ((((sel >> 26u) & 1u) != 0u) ? 0xffcab83au : 0xca1e80fbu); // s827 add + r3 = r3 | r7; // s828 or + r1 = r5 * r7 + r1; // s829 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 16u); r6 = r6 ^ t_; } // s830 shfl + r1 = r1 - r0; // s831 sub + r0 = rotr_var(r0, r2); // s832 rotr + r1 = mul_hi(r1, r0); // s833 mulhi + r6 = mul_hi(r6, r4); // s834 mulhi + r6 = rotl_imm(r6, 2u); // s835 rotl + r4 = r4 | r6; // s836 or + r6 = rotl_imm(r6, 23u); // s837 rotl + r4 = r7 * r4 + r4; // s838 mad + r0 = r0 | r1; // s839 or + r5 = mul_hi(r5, r3); // s840 mulhi + r7 = r4 * r6 + r7; // s841 mad + r1 = r1 + r4 + ((((sel >> 21u) & 1u) != 0u) ? 0x1bc9f95du : 0xcfb90e90u); // s842 add + r1 = r1 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0xf9bd620fu : 0x0b4758b6u); // s843 add + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r2 = r2 ^ t_; } // s844 shfl + r3 = r1 * r7 + r3; // s845 mad + r5 = r5 * r2; // s846 mul + r0 = rotl_imm(r0, 21u); // s847 rotl + r7 = r7 ^ r1; // s848 xor + r3 = r3 + r4 + ((((sel >> 18u) & 1u) != 0u) ? 0x697a4946u : 0x41fdc15au); // s849 add + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 4u); r0 = r0 ^ t_; } // s850 shfl + r1 = rotr_var(r1, r5); // s851 rotr + r5 = r5 | r6; // s852 or + r6 = r6 - r2; // s853 sub + r2 = r2 ^ r6; // s854 xor + r4 = r4 - r6; // s855 sub + r6 = r4 * r6 + r6; // s856 mad + r4 = r4 * r0; // s857 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r2 = r2 ^ t_; } // s858 shfl + r3 = r3 * r4; // s859 mul + r3 = r1 * r7 + r3; // s860 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 2u); r3 = r3 ^ t_; } // s861 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r7 = r7 ^ t_; } // s862 shfl + r0 = r2 * r2 + r0; // s863 mad + r6 = r6 ^ r0; // s864 xor + r6 = r6 + r2 + ((((sel >> 2u) & 1u) != 0u) ? 0x7fedd7f3u : 0x90656f74u); // s865 add + r3 = r3 ^ r2; // s866 xor + r1 = r1 | r4; // s867 or + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 2u); r6 = r6 ^ t_; } // s868 shfl + r1 = mul_hi(r1, r0); // s869 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r3 = r3 ^ t_; } // s870 shfl + r0 = r0 - r3; // s871 sub + r6 = r6 + r1 + ((((sel >> 11u) & 1u) != 0u) ? 0xbe1b480au : 0xa5c0b461u); // s872 add + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r3 = r3 ^ t_; } // s873 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 1u); r5 = r5 ^ t_; } // s874 shfl + r2 = mul_hi(r2, r4); // s875 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 4u); r5 = r5 ^ t_; } // s876 shfl + r5 = rotl_imm(r5, 14u); // s877 rotl + r2 = r2 ^ r7; // s878 xor + r7 = r7 ^ r0; // s879 xor + r0 = r0 * r2; // s880 mul + r4 = r4 * r2; // s881 mul + r7 = r7 * r6; // s882 mul + r4 = mul_hi(r4, r5); // s883 mulhi + r0 = r0 - r4; // s884 sub + r0 = r0 ^ r5; // s885 xor + r6 = r6 * r5; // s886 mul + r1 = r1 + r5 + ((((sel >> 14u) & 1u) != 0u) ? 0x7007f98fu : 0xe806fcecu); // s887 add + r3 = r3 * r1; // s888 mul + r5 = r5 ^ r3; // s889 xor + r6 = r6 | r2; // s890 or + r1 = r1 * r2; // s891 mul + r5 = r5 + r7 + ((((sel >> 3u) & 1u) != 0u) ? 0xf3c87e02u : 0x89a8551eu); // s892 add + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 16u); r2 = r2 ^ t_; } // s893 shfl + r1 = r1 + r3 + ((((sel >> 13u) & 1u) != 0u) ? 0xc315f5deu : 0xba1369dbu); // s894 add + r5 = r0 * r3 + r5; // s895 mad + r5 = rotr_var(r5, r2); // s896 rotr + r1 = r1 ^ r0; // s897 xor + r5 = r5 ^ r1; // s898 xor + r5 = rotr_var(r5, r1); // s899 rotr + r3 = r6 * r6 + r3; // s900 mad + r0 = rotl_imm(r0, 8u); // s901 rotl + r1 = r1 | r0; // s902 or + r1 = r1 + r2 + ((((sel >> 3u) & 1u) != 0u) ? 0x1c355a71u : 0x260e6848u); // s903 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 16u); r7 = r7 ^ t_; } // s904 shfl + r1 = mul_hi(r1, r3); // s905 mulhi + r1 = rotr_var(r1, r4); // s906 rotr + r6 = r6 + r0 + ((((sel >> 8u) & 1u) != 0u) ? 0x0c74a1a8u : 0xa74fd2b1u); // s907 add + r6 = rotr_var(r6, r2); // s908 rotr + r4 = rotl_imm(r4, 12u); // s909 rotl + r5 = r5 + r3 + ((((sel >> 29u) & 1u) != 0u) ? 0xa49b5d73u : 0xe5fb043eu); // s910 add + r3 = r3 ^ r0; // s911 xor + r3 = rotr_var(r3, r4); // s912 rotr + r6 = rotr_var(r6, r0); // s913 rotr + r2 = r2 ^ r5; // s914 xor + r0 = r0 * r7; // s915 mul + r3 = r3 ^ r0; // s916 xor + r5 = r1 * r7 + r5; // s917 mad + r3 = r3 + r4 + ((((sel >> 2u) & 1u) != 0u) ? 0xeb76e56cu : 0x264cb47bu); // s918 add + r3 = mul_hi(r3, r4); // s919 mulhi + r5 = r5 + r6 + ((((sel >> 9u) & 1u) != 0u) ? 0x2aab9631u : 0x418baa72u); // s920 add + r5 = mul_hi(r5, r1); // s921 mulhi + r7 = r7 - r3; // s922 sub + r6 = r6 + r1 + ((((sel >> 2u) & 1u) != 0u) ? 0x98e6b26du : 0x3696a894u); // s923 add + r6 = r3 * r1 + r6; // s924 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r2 = r2 ^ t_; } // s925 shfl + r6 = r6 ^ r1; // s926 xor + r4 = r4 ^ r3; // s927 xor + r0 = r0 + r4 + ((((sel >> 7u) & 1u) != 0u) ? 0x142778eeu : 0x0468c062u); // s928 add + r7 = r7 + r3 + ((((sel >> 29u) & 1u) != 0u) ? 0x4eae212du : 0x0af82291u); // s929 add + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 16u); r4 = r4 ^ t_; } // s930 shfl + r7 = r7 + r2 + ((((sel >> 20u) & 1u) != 0u) ? 0x8d2a8b36u : 0x17de5e29u); // s931 add + r5 = r5 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0xe2d2d7d5u : 0x686794a8u); // s932 add + r0 = mul_hi(r0, r3); // s933 mulhi + r4 = r4 + r0 + ((((sel >> 10u) & 1u) != 0u) ? 0xe3c3c6f9u : 0x66278068u); // s934 add + r6 = rotl_imm(r6, 22u); // s935 rotl + r0 = r0 | r2; // s936 or + r4 = r4 * r3; // s937 mul + r3 = r3 | r6; // s938 or + r7 = rotl_imm(r7, 28u); // s939 rotl + r0 = r0 + r6 + ((((sel >> 20u) & 1u) != 0u) ? 0xc2296063u : 0xc2d02ca6u); // s940 add + r1 = r1 + r5 + ((((sel >> 14u) & 1u) != 0u) ? 0xef1ca415u : 0x0b3c00e0u); // s941 add + r2 = r2 - r6; // s942 sub + r6 = r6 | r3; // s943 or + r0 = rotl_imm(r0, 2u); // s944 rotl + r2 = r2 * r1; // s945 mul + r0 = r0 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0x06a1321au : 0x11224846u); // s946 add + r3 = r3 * r6; // s947 mul + r5 = r5 - r2; // s948 sub + r5 = r5 + r4 + ((((sel >> 5u) & 1u) != 0u) ? 0x5d3e225cu : 0x461c43d4u); // s949 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 16u); r2 = r2 ^ t_; } // s950 shfl + r7 = r0 * r0 + r7; // s951 mad + r6 = rotr_var(r6, r4); // s952 rotr + r1 = r1 + r0 + ((((sel >> 30u) & 1u) != 0u) ? 0xbb84f628u : 0xd5eed39fu); // s953 add + r4 = rotl_imm(r4, 31u); // s954 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 16u); r1 = r1 ^ t_; } // s955 shfl + r2 = r2 - r6; // s956 sub + r4 = r4 ^ r2; // s957 xor + r0 = r0 ^ r2; // s958 xor + r1 = r1 + r0 + ((((sel >> 28u) & 1u) != 0u) ? 0x374c0426u : 0x519d72f7u); // s959 add + r5 = r5 * r4; // s960 mul + r5 = r5 - r7; // s961 sub + r2 = r2 ^ r6; // s962 xor + r4 = r4 ^ r1; // s963 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 16u); r2 = r2 ^ t_; } // s964 shfl + r7 = mul_hi(r7, r3); // s965 mulhi + r4 = rotl_imm(r4, 12u); // s966 rotl + r4 = r4 + r6 + ((((sel >> 26u) & 1u) != 0u) ? 0x03b88592u : 0x151dae18u); // s967 add + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r1 = r1 ^ t_; } // s968 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 8u); r3 = r3 ^ t_; } // s969 shfl + r2 = r2 ^ r7; // s970 xor + r5 = r3 * r4 + r5; // s971 mad + r0 = r0 ^ r3; // s972 xor + r2 = r2 ^ r5; // s973 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 4u); r1 = r1 ^ t_; } // s974 shfl + r5 = r1 * r4 + r5; // s975 mad + r2 = rotl_imm(r2, 19u); // s976 rotl + r1 = r1 - r4; // s977 sub + r5 = rotr_var(r5, r4); // s978 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 16u); r2 = r2 ^ t_; } // s979 shfl + r6 = r6 + r7 + ((((sel >> 28u) & 1u) != 0u) ? 0x1fdee45eu : 0x16220e61u); // s980 add + r4 = rotr_var(r4, r6); // s981 rotr + r6 = mul_hi(r6, r3); // s982 mulhi + r5 = rotl_imm(r5, 17u); // s983 rotl + r2 = r7 * r1 + r2; // s984 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 8u); r4 = r4 ^ t_; } // s985 shfl + r3 = r3 ^ r1; // s986 xor + r4 = r4 + r0 + ((((sel >> 27u) & 1u) != 0u) ? 0x44adc457u : 0x6cd6b697u); // s987 add + r1 = r1 * r5; // s988 mul + r4 = r4 + r2 + ((((sel >> 2u) & 1u) != 0u) ? 0x0a06a223u : 0x1103d2d2u); // s989 add + r4 = r4 * r1; // s990 mul + r4 = r5 * r1 + r4; // s991 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r3 = r3 ^ t_; } // s992 shfl + r1 = r1 - r3; // s993 sub + r4 = r7 * r5 + r4; // s994 mad + r1 = mul_hi(r1, r2); // s995 mulhi + r2 = r1 * r0 + r2; // s996 mad + r3 = rotl_imm(r3, 31u); // s997 rotl + r4 = r4 - r3; // s998 sub + r5 = rotr_var(r5, r3); // s999 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 4u); r4 = r4 ^ t_; } // s1000 shfl + r2 = r2 - r5; // s1001 sub + r3 = r4 * r4 + r3; // s1002 mad + r7 = r5 * r1 + r7; // s1003 mad + r7 = r7 + r4 + ((((sel >> 29u) & 1u) != 0u) ? 0x0044887fu : 0xa9c9d8a9u); // s1004 add + r4 = mul_hi(r4, r0); // s1005 mulhi + r4 = rotl_imm(r4, 21u); // s1006 rotl + r3 = r3 * r1; // s1007 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 2u); r1 = r1 ^ t_; } // s1008 shfl + r0 = mul_hi(r0, r6); // s1009 mulhi + r0 = r0 ^ r3; // s1010 xor + r5 = r5 | r4; // s1011 or + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 4u); r1 = r1 ^ t_; } // s1012 shfl + r2 = r2 + r4 + ((((sel >> 4u) & 1u) != 0u) ? 0x6b70e2c7u : 0xfa1574e3u); // s1013 add + r5 = rotr_var(r5, r7); // s1014 rotr + r0 = rotr_var(r0, r7); // s1015 rotr + r5 = r5 - r7; // s1016 sub + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 16u); r4 = r4 ^ t_; } // s1017 shfl + r6 = mul_hi(r6, r7); // s1018 mulhi + r0 = rotr_var(r0, r1); // s1019 rotr + r2 = r2 ^ r0; // s1020 xor + r4 = r5 * r1 + r4; // s1021 mad + r6 = r6 | r2; // s1022 or + r3 = r3 ^ r0; // s1023 xor + } + } + 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 = r3 * r4 + r2; // 0 mad + r2 = r1 * r1 + r2; // 1 mad + r2 = r3 * r2 + r2; // 2 mad + r3 = r3 ^ r5; // 3 xor + r7 = r7 ^ ds[r2 & mask]; // 4 load + r5 = r5 ^ ds[r7 & mask]; // 5 load + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r1 = r1 ^ t_; } // 6 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r7 = r7 ^ t_; } // 7 shfl + r1 = mul_hi(r1, r5); // 8 mulhi + r6 = rotr_var(r6, r3); // 9 rotr + r3 = r3 | r4; // 10 or + r4 = r4 ^ ds[r3 & mask]; // 11 load + r0 = mul_hi(r0, r4); // 12 mulhi + r5 = r5 + r1 + ((((sel >> 30u) & 1u) != 0u) ? 0xd3177981u : 0xc7934706u); // 13 add + r0 = r0 ^ ds[r4 & mask]; // 14 load + r2 = r2 - r4; // 15 sub + r2 = r2 ^ ds[r0 & mask]; // 16 load + r7 = r7 ^ ds[r2 & mask]; // 17 load + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r7 = r7 ^ t_; } // 18 shfl + r5 = r5 * r0; // 19 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // 20 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 16u); r2 = r2 ^ t_; } // 21 shfl + r6 = mul_hi(r6, r2); // 22 mulhi + r6 = r6 ^ ds[r1 & mask]; // 23 load + r5 = r5 * r0; // 24 mul + r5 = rotl_imm(r5, 19u); // 25 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 2u); r7 = r7 ^ t_; } // 26 shfl + r0 = r0 ^ r5; // 27 xor + r0 = r0 ^ r4; // 28 xor + r3 = r3 - r0; // 29 sub + r5 = r5 * r1; // 30 mul + r7 = r7 ^ ds[r2 & mask]; // 31 load + r1 = r1 ^ ds[r0 & mask]; // 32 load + r5 = r5 ^ r6; // 33 xor + r5 = r5 ^ ds[r1 & mask]; // 34 load + r0 = mul_hi(r0, r5); // 35 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r5 = r5 ^ t_; } // 36 shfl + r7 = r7 ^ ds[r0 & mask]; // 37 load + r3 = r3 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0x230c005cu : 0x75ba2fadu); // 38 add + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 4u); r1 = r1 ^ t_; } // 39 shfl + r2 = r2 ^ r5; // 40 xor + r3 = r6 * r3 + r3; // 41 mad + r6 = r6 - r7; // 42 sub + r7 = r7 ^ r0; // 43 xor + r1 = r1 ^ ds[r7 & mask]; // 44 load + r2 = r2 * r3; // 45 mul + r1 = mul_hi(r1, r5); // 46 mulhi + r4 = r4 - r3; // 47 sub + r2 = rotr_var(r2, r6); // 48 rotr + r3 = r3 ^ ds[r5 & mask]; // 49 load + r1 = r1 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x1907970cu : 0x81b8bc2cu); // 50 add + r0 = r0 * r2; // 51 mul + r0 = r0 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x699fd448u : 0x4f92b968u); // 52 add + r1 = r1 + r0 + ((((sel >> 12u) & 1u) != 0u) ? 0x77b1520du : 0x2bb965afu); // 53 add + r7 = rotl_imm(r7, 14u); // 54 rotl + r3 = r3 + r7 + ((((sel >> 1u) & 1u) != 0u) ? 0xa54c55a0u : 0x7b0fe07au); // 55 add + r6 = r6 ^ ds[r7 & mask]; // 56 load + r1 = rotr_var(r1, r5); // 57 rotr + r5 = r5 ^ ds[r4 & mask]; // 58 load + r6 = r6 ^ ds[r2 & mask]; // 59 load + r3 = r5 * r0 + r3; // 60 mad + r5 = r5 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0xad7493e7u : 0xaf9dd72du); // 61 add + r4 = r4 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x1e07c3d9u : 0x89841d87u); // 62 add + r5 = rotl_imm(r5, 19u); // 63 rotl + // latency-shadow block (Counter ASIC 3.0 item 8): 1024 ALU instructions x 3 passes after instruction 63, no load + for (uint sh = 0u; sh < 3u; ++sh) { + r5 = r5 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x8bc12da9u : 0x92199f99u); // s0 add + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x63079e5au : 0x8d72d3adu); // s1 add + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 2u); r6 = r6 ^ t_; } // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + ((((sel >> 31u) & 1u) != 0u) ? 0x5d4c7a60u : 0xb21b4babu); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + ((((sel >> 16u) & 1u) != 0u) ? 0xc88e2942u : 0x2fe0e98bu); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r6 = r6 ^ t_; } // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 4u); r2 = r2 ^ t_; } // s12 shfl + r1 = r1 + r5 + ((((sel >> 25u) & 1u) != 0u) ? 0xbc48c63eu : 0xbdf8f9a5u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r2 = r2 ^ t_; } // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + ((((sel >> 1u) & 1u) != 0u) ? 0x96e8f127u : 0x45c37cecu); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = mul_hi(r6, r0); // s28 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r2 = r2 ^ t_; } // s29 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r1 = r1 ^ t_; } // s30 shfl + r1 = r1 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0xb1cdb2abu : 0x37985632u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // s33 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r0 = r0 ^ t_; } // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x856e0180u : 0x804e777eu); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xe9bd0cc4u : 0x0b06c8a7u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = mul_hi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = mul_hi(r4, r3); // s44 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xcdcb63f6u : 0xee822e17u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r4 = r4 ^ t_; } // s47 shfl + r6 = mul_hi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0xd4758987u : 0x3dfad1b6u); // s56 add + r4 = r4 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x0602d6beu : 0xfca75bc2u); // s57 add + r5 = mul_hi(r5, r6); // s58 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r2 = r2 ^ t_; } // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0x8596687au : 0xd71c02ffu); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 2u); r7 = r7 ^ t_; } // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0x08ac5733u : 0x3c6fe15du); // s72 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r3 = r3 ^ t_; } // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + ((((sel >> 1u) & 1u) != 0u) ? 0xc100b495u : 0x295d5faeu); // s77 add + r3 = mul_hi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + ((((sel >> 15u) & 1u) != 0u) ? 0x5cc59530u : 0x274a9221u); // s81 add + r7 = r7 + r3 + ((((sel >> 5u) & 1u) != 0u) ? 0x141479ecu : 0xc8651f8eu); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r2 = r2 ^ t_; } // s85 shfl + r3 = r3 ^ r2; // s86 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 2u); r5 = r5 ^ t_; } // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x883c0c92u : 0x53f915c2u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + ((((sel >> 31u) & 1u) != 0u) ? 0x3cc5bd20u : 0xe2be00a5u); // s91 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 1u); r7 = r7 ^ t_; } // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + ((((sel >> 17u) & 1u) != 0u) ? 0xbfd646cbu : 0x423fd9c9u); // s101 add + r7 = r7 + r6 + ((((sel >> 11u) & 1u) != 0u) ? 0x19b74a43u : 0x8d3c011du); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + ((((sel >> 15u) & 1u) != 0u) ? 0x7dcb7e18u : 0x8ce14721u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = mul_hi(r2, r0); // s109 mulhi + r1 = mul_hi(r1, r0); // s110 mulhi + r0 = r0 + r2 + ((((sel >> 28u) & 1u) != 0u) ? 0x3c179ad8u : 0x2d9fc6b9u); // s111 add + r2 = mul_hi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + ((((sel >> 22u) & 1u) != 0u) ? 0x47359729u : 0x502138e2u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = mul_hi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 2u); r4 = r4 ^ t_; } // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r7 = r7 ^ t_; } // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x6c57e4e7u : 0x33dff776u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + ((((sel >> 30u) & 1u) != 0u) ? 0xe8212c0cu : 0x5db25b34u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = mul_hi(r0, r5); // s138 mulhi + r2 = r2 + r7 + ((((sel >> 10u) & 1u) != 0u) ? 0xd44ff710u : 0x218d4090u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r3 = r3 ^ t_; } // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + ((((sel >> 29u) & 1u) != 0u) ? 0xb98942fau : 0xf4b1a8deu); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + ((((sel >> 17u) & 1u) != 0u) ? 0x0d48ba42u : 0x2bef10f2u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + ((((sel >> 30u) & 1u) != 0u) ? 0xc98dea9cu : 0xdc5cc080u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0x6c752dcbu : 0x18197438u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + ((((sel >> 3u) & 1u) != 0u) ? 0x8e481727u : 0xf1c46574u); // s163 add + r0 = mul_hi(r0, r4); // s164 mulhi + r2 = r2 + r6 + ((((sel >> 20u) & 1u) != 0u) ? 0x550ab406u : 0xac578137u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + ((((sel >> 14u) & 1u) != 0u) ? 0xaebb5966u : 0xa33e6706u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 8u); r7 = r7 ^ t_; } // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x5bb7550fu : 0xd94d55acu); // s184 add + r3 = r3 | r5; // s185 or + r6 = mul_hi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r7 = r7 ^ t_; } // s188 shfl + r6 = r6 + r5 + ((((sel >> 6u) & 1u) != 0u) ? 0x2a354e2du : 0x89e747feu); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = mul_hi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r4 = r4 ^ t_; } // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + ((((sel >> 7u) & 1u) != 0u) ? 0x10cfdc71u : 0xea03e8e7u); // s197 add + r7 = r7 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x66e148d3u : 0xa7ee0102u); // s198 add + r5 = r5 - r2; // s199 sub + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r5 = r5 ^ t_; } // s200 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 8u); r7 = r7 ^ t_; } // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0x8558b619u : 0x8379a4deu); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = mul_hi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 4u); r2 = r2 ^ t_; } // s209 shfl + r7 = r7 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0xf4049c4cu : 0xaa8cb14eu); // s210 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 16u); r7 = r7 ^ t_; } // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 16u); r3 = r3 ^ t_; } // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = mul_hi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r5 = r5 ^ t_; } // s222 shfl + r5 = mul_hi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0x2a7fecb2u : 0x1d176220u); // s230 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r1 = r1 ^ t_; } // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + ((((sel >> 25u) & 1u) != 0u) ? 0xadce39f3u : 0x17dafb4du); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + ((((sel >> 29u) & 1u) != 0u) ? 0x0e7033b6u : 0xf2f77d26u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + ((((sel >> 31u) & 1u) != 0u) ? 0x7b2ff6b7u : 0xfed2da4eu); // s247 add + r0 = r0 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0xb5fad7b1u : 0x03b2891cu); // s248 add + r5 = mul_hi(r5, r4); // s249 mulhi + r5 = r5 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0xa7e71c2fu : 0x042cd6e3u); // s250 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 1u); r6 = r6 ^ t_; } // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0xb83d78deu : 0x784a302bu); // s254 add + r2 = r2 - r4; // s255 sub + r3 = r3 - r4; // s256 sub + r2 = r2 * r4; // s257 mul + r4 = r0 * r6 + r4; // s258 mad + r5 = r5 | r0; // s259 or + r4 = r4 ^ r6; // s260 xor + r6 = mul_hi(r6, r3); // s261 mulhi + r2 = r2 * r6; // s262 mul + r5 = rotl_imm(r5, 1u); // s263 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 8u); r7 = r7 ^ t_; } // s264 shfl + r3 = r3 * r2; // s265 mul + r2 = r2 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x99a1d1b6u : 0x3dddf1b2u); // s266 add + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 8u); r2 = r2 ^ t_; } // s267 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r0 = r0 ^ t_; } // s268 shfl + r4 = r4 - r2; // s269 sub + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 1u); r0 = r0 ^ t_; } // s270 shfl + r3 = r3 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x40ca287au : 0xcfc62661u); // s271 add + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 16u); r1 = r1 ^ t_; } // s272 shfl + r1 = r3 * r6 + r1; // s273 mad + r7 = r7 + r6 + ((((sel >> 30u) & 1u) != 0u) ? 0xed4b65adu : 0x44caede3u); // s274 add + r5 = r5 ^ r7; // s275 xor + r2 = r2 * r6; // s276 mul + r2 = r2 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0x0f45ae89u : 0x9aae6c12u); // s277 add + r2 = r2 ^ r6; // s278 xor + r1 = r1 - r2; // s279 sub + r5 = r5 ^ r1; // s280 xor + r7 = r7 ^ r1; // s281 xor + r7 = r7 - r1; // s282 sub + r5 = r5 - r7; // s283 sub + r7 = r0 * r6 + r7; // s284 mad + r5 = mul_hi(r5, r4); // s285 mulhi + r3 = r3 - r5; // s286 sub + r5 = r5 - r1; // s287 sub + r1 = r3 * r7 + r1; // s288 mad + r3 = rotl_imm(r3, 9u); // s289 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 8u); r5 = r5 ^ t_; } // s290 shfl + r7 = r7 + r2 + ((((sel >> 1u) & 1u) != 0u) ? 0xe086d3b6u : 0x2307120bu); // s291 add + r4 = r4 ^ r3; // s292 xor + r3 = rotl_imm(r3, 14u); // s293 rotl + r5 = r5 - r4; // s294 sub + r2 = mul_hi(r2, r3); // s295 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r1 = r1 ^ t_; } // s296 shfl + r3 = r6 * r1 + r3; // s297 mad + r4 = r4 ^ r1; // s298 xor + r6 = r6 + r3 + ((((sel >> 24u) & 1u) != 0u) ? 0xadbeb223u : 0x4e3a12e5u); // s299 add + r6 = mul_hi(r6, r5); // s300 mulhi + r7 = rotr_var(r7, r5); // s301 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 16u); r5 = r5 ^ t_; } // s302 shfl + r3 = r3 ^ r4; // s303 xor + r2 = r3 * r1 + r2; // s304 mad + r1 = r1 ^ r7; // s305 xor + r1 = r1 + r0 + ((((sel >> 22u) & 1u) != 0u) ? 0x0d8f1149u : 0x51ab0157u); // s306 add + r2 = r2 + r1 + ((((sel >> 24u) & 1u) != 0u) ? 0x99a96de9u : 0x3b5e8835u); // s307 add + r1 = r5 * r5 + r1; // s308 mad + r2 = r2 * r4; // s309 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 8u); r3 = r3 ^ t_; } // s310 shfl + r0 = r0 ^ r4; // s311 xor + r5 = mul_hi(r5, r2); // s312 mulhi + r7 = r7 + r2 + ((((sel >> 30u) & 1u) != 0u) ? 0x86ddfba7u : 0x81f3297cu); // s313 add + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x38aa230au : 0x838e4a2fu); // s314 add + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 16u); r7 = r7 ^ t_; } // s315 shfl + r7 = r7 - r5; // s316 sub + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r5 = r5 ^ t_; } // s317 shfl + r1 = r1 + r3 + ((((sel >> 11u) & 1u) != 0u) ? 0xa6399179u : 0xebcad805u); // s318 add + r7 = rotl_imm(r7, 21u); // s319 rotl + r7 = r7 ^ r6; // s320 xor + r7 = r7 | r6; // s321 or + r5 = r5 + r3 + ((((sel >> 25u) & 1u) != 0u) ? 0x4de83051u : 0x4c906f73u); // s322 add + r0 = r0 + r4 + ((((sel >> 14u) & 1u) != 0u) ? 0xd3d821c5u : 0x742ec195u); // s323 add + r6 = r6 ^ r2; // s324 xor + r6 = rotl_imm(r6, 1u); // s325 rotl + r4 = rotl_imm(r4, 24u); // s326 rotl + r4 = r4 | r3; // s327 or + r2 = r1 * r3 + r2; // s328 mad + r2 = r2 ^ r7; // s329 xor + r2 = r2 | r3; // s330 or + r7 = r7 - r1; // s331 sub + r3 = r3 + r6 + ((((sel >> 0u) & 1u) != 0u) ? 0xc06f831eu : 0xb86750e9u); // s332 add + r7 = rotl_imm(r7, 25u); // s333 rotl + r3 = r0 * r0 + r3; // s334 mad + r2 = r2 + r5 + ((((sel >> 28u) & 1u) != 0u) ? 0x5225df1du : 0xb57956eeu); // s335 add + r3 = r1 * r6 + r3; // s336 mad + r4 = r2 * r2 + r4; // s337 mad + r7 = r7 * r2; // s338 mul + r1 = r1 * r6; // s339 mul + r4 = r4 + r5 + ((((sel >> 5u) & 1u) != 0u) ? 0xb73822ceu : 0x23f6425fu); // s340 add + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 2u); r5 = r5 ^ t_; } // s341 shfl + r6 = r6 ^ r5; // s342 xor + r0 = rotl_imm(r0, 13u); // s343 rotl + r0 = rotr_var(r0, r3); // s344 rotr + r1 = r1 - r0; // s345 sub + r6 = rotr_var(r6, r1); // s346 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 4u); r6 = r6 ^ t_; } // s347 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 8u); r5 = r5 ^ t_; } // s348 shfl + r5 = r5 ^ r3; // s349 xor + r1 = r4 * r0 + r1; // s350 mad + r3 = rotr_var(r3, r1); // s351 rotr + r1 = rotl_imm(r1, 13u); // s352 rotl + r3 = r3 + r0 + ((((sel >> 26u) & 1u) != 0u) ? 0xfa0c560eu : 0x0dce5917u); // s353 add + r3 = mul_hi(r3, r2); // s354 mulhi + r1 = r2 * r4 + r1; // s355 mad + r0 = r0 ^ r1; // s356 xor + r7 = r7 * r5; // s357 mul + r0 = rotl_imm(r0, 5u); // s358 rotl + r2 = r7 * r7 + r2; // s359 mad + r2 = r2 | r6; // s360 or + r6 = r6 + r1 + ((((sel >> 19u) & 1u) != 0u) ? 0x277e027au : 0x7c83b79au); // s361 add + r0 = r0 * r2; // s362 mul + r3 = r3 * r6; // s363 mul + r2 = rotr_var(r2, r4); // s364 rotr + r5 = r5 + r1 + ((((sel >> 1u) & 1u) != 0u) ? 0x52275ea4u : 0x271f2385u); // s365 add + r1 = r1 * r6; // s366 mul + r0 = r0 + r7 + ((((sel >> 30u) & 1u) != 0u) ? 0x8f8b4093u : 0x4c66800fu); // s367 add + r4 = rotr_var(r4, r0); // s368 rotr + r4 = rotr_var(r4, r0); // s369 rotr + r1 = r0 * r6 + r1; // s370 mad + r0 = r0 - r5; // s371 sub + r7 = r7 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0x9a7dcadcu : 0x7dad1ed5u); // s372 add + r7 = r7 + r3 + ((((sel >> 20u) & 1u) != 0u) ? 0xf808c195u : 0x1ea3d58eu); // s373 add + r1 = r1 * r2; // s374 mul + r3 = r7 * r2 + r3; // s375 mad + r4 = r4 ^ r1; // s376 xor + r1 = r1 | r0; // s377 or + r5 = r5 + r0 + ((((sel >> 26u) & 1u) != 0u) ? 0x427ed5ceu : 0x98b36d10u); // s378 add + r6 = r6 * r0; // s379 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 1u); r7 = r7 ^ t_; } // s380 shfl + r4 = r4 + r0 + ((((sel >> 18u) & 1u) != 0u) ? 0x38f848b9u : 0xb19cab2du); // s381 add + r3 = r5 * r2 + r3; // s382 mad + r0 = r0 | r7; // s383 or + r5 = r5 - r4; // s384 sub + r1 = r1 - r5; // s385 sub + r2 = r2 - r0; // s386 sub + r5 = r5 + r2 + ((((sel >> 17u) & 1u) != 0u) ? 0xffc20cf8u : 0x341056b0u); // s387 add + r1 = rotl_imm(r1, 26u); // s388 rotl + r2 = r2 ^ r5; // s389 xor + r5 = r7 * r0 + r5; // s390 mad + r3 = mul_hi(r3, r2); // s391 mulhi + r5 = r5 + r4 + ((((sel >> 0u) & 1u) != 0u) ? 0xfb939f2bu : 0x78aa571au); // s392 add + r5 = r5 | r2; // s393 or + r1 = mul_hi(r1, r7); // s394 mulhi + r4 = r4 - r2; // s395 sub + r7 = r7 - r1; // s396 sub + r0 = r0 + r1 + ((((sel >> 2u) & 1u) != 0u) ? 0xa9c6c9fbu : 0x31af4767u); // s397 add + r3 = r3 * r1; // s398 mul + r1 = r1 - r7; // s399 sub + r7 = r7 + r6 + ((((sel >> 8u) & 1u) != 0u) ? 0x34f9b056u : 0x266d4c34u); // s400 add + r5 = rotl_imm(r5, 5u); // s401 rotl + r0 = r0 + r4 + ((((sel >> 23u) & 1u) != 0u) ? 0x79822c64u : 0x7241955eu); // s402 add + r2 = r4 * r0 + r2; // s403 mad + r5 = rotl_imm(r5, 29u); // s404 rotl + r3 = r3 - r5; // s405 sub + r2 = r2 + r3 + ((((sel >> 27u) & 1u) != 0u) ? 0xda046091u : 0xf65aca5du); // s406 add + r4 = mul_hi(r4, r7); // s407 mulhi + r2 = r2 + r1 + ((((sel >> 14u) & 1u) != 0u) ? 0x167aba1cu : 0x6a00cefbu); // s408 add + r2 = r6 * r6 + r2; // s409 mad + r6 = rotl_imm(r6, 26u); // s410 rotl + r6 = r6 | r7; // s411 or + r1 = rotl_imm(r1, 20u); // s412 rotl + r7 = r7 * r5; // s413 mul + r6 = r6 - r0; // s414 sub + r6 = mul_hi(r6, r0); // s415 mulhi + r3 = rotl_imm(r3, 5u); // s416 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r1 = r1 ^ t_; } // s417 shfl + r0 = r0 * r4; // s418 mul + r4 = rotr_var(r4, r7); // s419 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r7 = r7 ^ t_; } // s420 shfl + r5 = r3 * r6 + r5; // s421 mad + r3 = r3 ^ r4; // s422 xor + r3 = rotr_var(r3, r7); // s423 rotr + r4 = r4 + r1 + ((((sel >> 26u) & 1u) != 0u) ? 0xbb669c17u : 0xba29da18u); // s424 add + r7 = rotr_var(r7, r5); // s425 rotr + r2 = r2 * r6; // s426 mul + r1 = r1 + r4 + ((((sel >> 16u) & 1u) != 0u) ? 0xc6b45a76u : 0x4f70e34fu); // s427 add + r1 = rotl_imm(r1, 1u); // s428 rotl + r6 = mul_hi(r6, r5); // s429 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xff610984u : 0x3883e0f5u); // s430 add + r4 = r4 | r3; // s431 or + r7 = r7 ^ r5; // s432 xor + r3 = mul_hi(r3, r2); // s433 mulhi + r2 = r2 ^ r6; // s434 xor + r4 = r4 | r3; // s435 or + r0 = r0 + r1 + ((((sel >> 9u) & 1u) != 0u) ? 0xf37057feu : 0xb1b15861u); // s436 add + r7 = r7 + r4 + ((((sel >> 4u) & 1u) != 0u) ? 0x61793eafu : 0x2e9e173fu); // s437 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 1u); r5 = r5 ^ t_; } // s438 shfl + r6 = r0 * r3 + r6; // s439 mad + r5 = r5 ^ r2; // s440 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 16u); r0 = r0 ^ t_; } // s441 shfl + r6 = r6 * r3; // s442 mul + r5 = r5 - r4; // s443 sub + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r2 = r2 ^ t_; } // s444 shfl + r0 = r0 + r5 + ((((sel >> 12u) & 1u) != 0u) ? 0x69def831u : 0x646856aau); // s445 add + r4 = r4 + r6 + ((((sel >> 23u) & 1u) != 0u) ? 0x1f8ecb8bu : 0x58a3f8fcu); // s446 add + r4 = r0 * r2 + r4; // s447 mad + r5 = r5 * r0; // s448 mul + r2 = r2 + r5 + ((((sel >> 11u) & 1u) != 0u) ? 0x7ecb876du : 0x48d3062du); // s449 add + r2 = r5 * r6 + r2; // s450 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r7 = r7 ^ t_; } // s451 shfl + r2 = r2 * r5; // s452 mul + r5 = mul_hi(r5, r4); // s453 mulhi + r1 = r1 ^ r7; // s454 xor + r2 = r2 * r7; // s455 mul + r1 = r1 * r3; // s456 mul + r3 = r6 * r2 + r3; // s457 mad + r7 = r7 - r0; // s458 sub + r2 = r4 * r5 + r2; // s459 mad + r0 = rotl_imm(r0, 2u); // s460 rotl + r4 = r4 ^ r2; // s461 xor + r4 = r4 + r0 + ((((sel >> 18u) & 1u) != 0u) ? 0x7b093757u : 0xb41dd69bu); // s462 add + r6 = r6 + r1 + ((((sel >> 3u) & 1u) != 0u) ? 0x916e1b7eu : 0xb042032eu); // s463 add + r2 = r2 + r6 + ((((sel >> 8u) & 1u) != 0u) ? 0x6d42b978u : 0x4e68a2a0u); // s464 add + r3 = r3 - r2; // s465 sub + r2 = r2 * r5; // s466 mul + r7 = rotl_imm(r7, 28u); // s467 rotl + r0 = r0 - r3; // s468 sub + r7 = mul_hi(r7, r2); // s469 mulhi + r7 = r7 | r6; // s470 or + r7 = rotl_imm(r7, 28u); // s471 rotl + r0 = r0 * r6; // s472 mul + r2 = r2 | r1; // s473 or + r2 = r2 + r4 + ((((sel >> 14u) & 1u) != 0u) ? 0x20c5276bu : 0x13ec3b3eu); // s474 add + r2 = rotr_var(r2, r6); // s475 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 16u); r6 = r6 ^ t_; } // s476 shfl + r2 = rotl_imm(r2, 15u); // s477 rotl + r5 = rotr_var(r5, r4); // s478 rotr + r3 = rotl_imm(r3, 26u); // s479 rotl + r5 = r5 | r6; // s480 or + r3 = rotl_imm(r3, 29u); // s481 rotl + r0 = rotr_var(r0, r7); // s482 rotr + r1 = r1 - r0; // s483 sub + r0 = r2 * r5 + r0; // s484 mad + r6 = r6 ^ r4; // s485 xor + r6 = r6 ^ r0; // s486 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 4u); r3 = r3 ^ t_; } // s487 shfl + r6 = mul_hi(r6, r0); // s488 mulhi + r1 = r1 * r0; // s489 mul + r3 = r3 ^ r6; // s490 xor + r3 = r3 * r6; // s491 mul + r0 = r0 * r3; // s492 mul + r4 = r4 | r3; // s493 or + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 8u); r0 = r0 ^ t_; } // s494 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 16u); r0 = r0 ^ t_; } // s495 shfl + r6 = r5 * r2 + r6; // s496 mad + r5 = r5 * r6; // s497 mul + r3 = r3 ^ r1; // s498 xor + r0 = r0 + r1 + ((((sel >> 20u) & 1u) != 0u) ? 0x19f4c710u : 0x53e99acau); // s499 add + r6 = r5 * r2 + r6; // s500 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r7 = r7 ^ t_; } // s501 shfl + r3 = r3 - r5; // s502 sub + r0 = rotl_imm(r0, 8u); // s503 rotl + r3 = r3 ^ r1; // s504 xor + r7 = r7 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x7a6ac7b5u : 0x0867fe20u); // s505 add + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 2u); r0 = r0 ^ t_; } // s506 shfl + r0 = r0 * r1; // s507 mul + r6 = r6 | r5; // s508 or + r2 = r2 * r7; // s509 mul + r1 = r1 + r5 + ((((sel >> 21u) & 1u) != 0u) ? 0xd77f6a03u : 0xd7fdc3ecu); // s510 add + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 8u); r3 = r3 ^ t_; } // s511 shfl + r6 = r6 + r3 + ((((sel >> 9u) & 1u) != 0u) ? 0x5c22b0b5u : 0x297a096au); // s512 add + r7 = r7 | r0; // s513 or + r7 = r7 + r3 + ((((sel >> 27u) & 1u) != 0u) ? 0x4caafacdu : 0x5de1d1d1u); // s514 add + r1 = mul_hi(r1, r0); // s515 mulhi + r0 = r0 - r6; // s516 sub + r2 = r2 - r1; // s517 sub + r6 = r5 * r7 + r6; // s518 mad + r2 = r2 ^ r7; // s519 xor + r1 = r1 | r5; // s520 or + r0 = r4 * r6 + r0; // s521 mad + r4 = r4 + r6 + ((((sel >> 29u) & 1u) != 0u) ? 0xb1091e80u : 0x2caeeca3u); // s522 add + r7 = r6 * r5 + r7; // s523 mad + r7 = r7 - r2; // s524 sub + r0 = r0 * r7; // s525 mul + r0 = r0 ^ r7; // s526 xor + r1 = mul_hi(r1, r4); // s527 mulhi + r0 = rotr_var(r0, r5); // s528 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 16u); r2 = r2 ^ t_; } // s529 shfl + r2 = mul_hi(r2, r3); // s530 mulhi + r1 = r1 | r4; // s531 or + r6 = r6 + r4 + ((((sel >> 13u) & 1u) != 0u) ? 0xbda312aeu : 0xbe9e1eb0u); // s532 add + r7 = r7 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x1ec16229u : 0xbe5d93a3u); // s533 add + r0 = r6 * r4 + r0; // s534 mad + r0 = r0 + r5 + ((((sel >> 23u) & 1u) != 0u) ? 0x500828bcu : 0x5e23583bu); // s535 add + r6 = r5 * r0 + r6; // s536 mad + r2 = r2 ^ r4; // s537 xor + r6 = r3 * r5 + r6; // s538 mad + r6 = r6 + r4 + ((((sel >> 3u) & 1u) != 0u) ? 0x852321dcu : 0x43c32138u); // s539 add + r2 = r2 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x44e6ae63u : 0xaff69493u); // s540 add + r3 = mul_hi(r3, r5); // s541 mulhi + r1 = r1 + r7 + ((((sel >> 5u) & 1u) != 0u) ? 0x909712feu : 0xc5de29efu); // s542 add + r1 = r3 * r2 + r1; // s543 mad + r1 = r1 + r3 + ((((sel >> 11u) & 1u) != 0u) ? 0xfb7b42b9u : 0x1e20e084u); // s544 add + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 4u); r4 = r4 ^ t_; } // s545 shfl + r6 = r6 + r1 + ((((sel >> 10u) & 1u) != 0u) ? 0x6e036dd4u : 0x9370db38u); // s546 add + r4 = r4 ^ r6; // s547 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r5 = r5 ^ t_; } // s548 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r3 = r3 ^ t_; } // s549 shfl + r1 = rotr_var(r1, r7); // s550 rotr + r0 = r3 * r2 + r0; // s551 mad + r7 = mul_hi(r7, r4); // s552 mulhi + r0 = r0 + r4 + ((((sel >> 13u) & 1u) != 0u) ? 0xd3c9174du : 0xbf2488f6u); // s553 add + r1 = rotl_imm(r1, 1u); // s554 rotl + r7 = rotr_var(r7, r3); // s555 rotr + r7 = rotr_var(r7, r3); // s556 rotr + r6 = r2 * r0 + r6; // s557 mad + r6 = r6 ^ r1; // s558 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r5 = r5 ^ t_; } // s559 shfl + r5 = r5 ^ r3; // s560 xor + r5 = r5 * r1; // s561 mul + r3 = rotl_imm(r3, 31u); // s562 rotl + r6 = rotr_var(r6, r2); // s563 rotr + r7 = r7 | r2; // s564 or + r6 = rotr_var(r6, r0); // s565 rotr + r2 = r2 * r0; // s566 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 2u); r4 = r4 ^ t_; } // s567 shfl + r3 = r3 * r0; // s568 mul + r4 = r4 + r2 + ((((sel >> 9u) & 1u) != 0u) ? 0xa3149efau : 0xd9160c83u); // s569 add + r4 = mul_hi(r4, r2); // s570 mulhi + r3 = r3 + r0 + ((((sel >> 10u) & 1u) != 0u) ? 0x9cab407bu : 0x3bdc971cu); // s571 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 16u); r1 = r1 ^ t_; } // s572 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 4u); r2 = r2 ^ t_; } // s573 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r2 = r2 ^ t_; } // s574 shfl + r0 = r0 ^ r7; // s575 xor + r0 = r0 + r5 + ((((sel >> 27u) & 1u) != 0u) ? 0x747b0838u : 0x17979608u); // s576 add + r0 = r0 ^ r4; // s577 xor + r6 = r6 - r1; // s578 sub + r4 = rotr_var(r4, r2); // s579 rotr + r2 = r2 ^ r3; // s580 xor + r6 = r7 * r2 + r6; // s581 mad + r5 = r5 + r2 + ((((sel >> 7u) & 1u) != 0u) ? 0x02246c0cu : 0x1c10ec5cu); // s582 add + r3 = mul_hi(r3, r6); // s583 mulhi + r2 = r2 ^ r5; // s584 xor + r6 = rotl_imm(r6, 24u); // s585 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 8u); r3 = r3 ^ t_; } // s586 shfl + r1 = r2 * r6 + r1; // s587 mad + r3 = r3 + r7 + ((((sel >> 21u) & 1u) != 0u) ? 0xbea44bd0u : 0x88758873u); // s588 add + r1 = rotl_imm(r1, 30u); // s589 rotl + r7 = r7 * r1; // s590 mul + r3 = r3 + r6 + ((((sel >> 10u) & 1u) != 0u) ? 0x8e0eb890u : 0xf436bb64u); // s591 add + r7 = r6 * r1 + r7; // s592 mad + r0 = r3 * r5 + r0; // s593 mad + r5 = rotr_var(r5, r4); // s594 rotr + r4 = r4 | r0; // s595 or + r6 = r3 * r0 + r6; // s596 mad + r2 = r2 + r1 + ((((sel >> 31u) & 1u) != 0u) ? 0x29b853b3u : 0xb465e47eu); // s597 add + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 16u); r1 = r1 ^ t_; } // s598 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 4u); r4 = r4 ^ t_; } // s599 shfl + r6 = r2 * r0 + r6; // s600 mad + r5 = mul_hi(r5, r0); // s601 mulhi + r6 = r6 * r7; // s602 mul + r4 = r4 | r7; // s603 or + r7 = r7 - r0; // s604 sub + r7 = rotr_var(r7, r4); // s605 rotr + r4 = r0 * r3 + r4; // s606 mad + r4 = mul_hi(r4, r3); // s607 mulhi + r0 = r0 + r1 + ((((sel >> 28u) & 1u) != 0u) ? 0xb7536963u : 0x22ce199du); // s608 add + r2 = r2 - r5; // s609 sub + r2 = r2 ^ r0; // s610 xor + r5 = r5 * r4; // s611 mul + r3 = rotl_imm(r3, 25u); // s612 rotl + r7 = rotl_imm(r7, 13u); // s613 rotl + r4 = r4 * r7; // s614 mul + r5 = r4 * r2 + r5; // s615 mad + r0 = r0 ^ r5; // s616 xor + r7 = r5 * r4 + r7; // s617 mad + r6 = r6 - r4; // s618 sub + r3 = r3 * r4; // s619 mul + r1 = rotl_imm(r1, 24u); // s620 rotl + r1 = r1 ^ r2; // s621 xor + r4 = r4 | r3; // s622 or + r7 = r7 * r2; // s623 mul + r6 = r6 + r1 + ((((sel >> 20u) & 1u) != 0u) ? 0xe37b1e20u : 0x2dbf6ed0u); // s624 add + r4 = r4 ^ r5; // s625 xor + r4 = r6 * r2 + r4; // s626 mad + r1 = r1 ^ r6; // s627 xor + r6 = r6 + r3 + ((((sel >> 12u) & 1u) != 0u) ? 0xf5a2a9f7u : 0x9dc2b9d0u); // s628 add + r7 = r7 - r5; // s629 sub + r1 = mul_hi(r1, r7); // s630 mulhi + r1 = rotr_var(r1, r3); // s631 rotr + r4 = r4 | r6; // s632 or + r2 = r2 + r5 + ((((sel >> 24u) & 1u) != 0u) ? 0x982bfc08u : 0x9c1fba1bu); // s633 add + r6 = r6 * r5; // s634 mul + r7 = r2 * r3 + r7; // s635 mad + r7 = mul_hi(r7, r4); // s636 mulhi + r5 = r5 ^ r0; // s637 xor + r0 = r0 * r1; // s638 mul + r4 = r4 ^ r6; // s639 xor + r6 = r6 - r4; // s640 sub + r6 = mul_hi(r6, r4); // s641 mulhi + r4 = r4 - r0; // s642 sub + r7 = r7 - r5; // s643 sub + r3 = r0 * r7 + r3; // s644 mad + r3 = r3 | r5; // s645 or + r0 = r0 - r4; // s646 sub + r7 = r7 | r5; // s647 or + r7 = rotl_imm(r7, 1u); // s648 rotl + r5 = r5 + r6 + ((((sel >> 31u) & 1u) != 0u) ? 0x6e5d517fu : 0x9f5e0d19u); // s649 add + r1 = r1 | r2; // s650 or + r3 = rotl_imm(r3, 29u); // s651 rotl + r2 = r2 + r4 + ((((sel >> 2u) & 1u) != 0u) ? 0x30faf9c6u : 0xb53f6e74u); // s652 add + r0 = rotl_imm(r0, 21u); // s653 rotl + r1 = r1 ^ r3; // s654 xor + r4 = r7 * r2 + r4; // s655 mad + r4 = r4 - r6; // s656 sub + r4 = r4 * r6; // s657 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r2 = r2 ^ t_; } // s658 shfl + r7 = rotl_imm(r7, 31u); // s659 rotl + r4 = r4 ^ r6; // s660 xor + r1 = r1 - r3; // s661 sub + r3 = r3 * r6; // s662 mul + r5 = r5 * r3; // s663 mul + r7 = r7 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x8941d2e7u : 0x016e0094u); // s664 add + r1 = r1 ^ r2; // s665 xor + r1 = r1 - r0; // s666 sub + r4 = r4 ^ r7; // s667 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 1u); r7 = r7 ^ t_; } // s668 shfl + r1 = rotr_var(r1, r4); // s669 rotr + r2 = r2 + r3 + ((((sel >> 14u) & 1u) != 0u) ? 0x15289435u : 0x9af12ca6u); // s670 add + r2 = rotr_var(r2, r4); // s671 rotr + r4 = r6 * r7 + r4; // s672 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r2 = r2 ^ t_; } // s673 shfl + r6 = r4 * r2 + r6; // s674 mad + r2 = r4 * r6 + r2; // s675 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 16u); r3 = r3 ^ t_; } // s676 shfl + r1 = rotr_var(r1, r0); // s677 rotr + r0 = r0 - r2; // s678 sub + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 16u); r5 = r5 ^ t_; } // s679 shfl + r1 = r1 ^ r0; // s680 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r1 = r1 ^ t_; } // s681 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r0 = r0 ^ t_; } // s682 shfl + r2 = r3 * r3 + r2; // s683 mad + r4 = r4 - r6; // s684 sub + r5 = r5 ^ r3; // s685 xor + r2 = r2 - r5; // s686 sub + r4 = r4 - r5; // s687 sub + r5 = r4 * r7 + r5; // s688 mad + r6 = r6 * r7; // s689 mul + r1 = r1 * r5; // s690 mul + r4 = rotr_var(r4, r3); // s691 rotr + r2 = r2 ^ r4; // s692 xor + r0 = rotl_imm(r0, 2u); // s693 rotl + r5 = r5 + r2 + ((((sel >> 23u) & 1u) != 0u) ? 0x49801084u : 0x4fc762c9u); // s694 add + r0 = r0 + r4 + ((((sel >> 14u) & 1u) != 0u) ? 0x5f403cd5u : 0x626c00f5u); // s695 add + r6 = rotl_imm(r6, 25u); // s696 rotl + r3 = r3 ^ r7; // s697 xor + r0 = r0 * r2; // s698 mul + r5 = rotr_var(r5, r1); // s699 rotr + r3 = r3 ^ r7; // s700 xor + r4 = r4 | r3; // s701 or + r7 = r7 * r3; // s702 mul + r4 = rotl_imm(r4, 24u); // s703 rotl + r5 = r5 + r4 + ((((sel >> 17u) & 1u) != 0u) ? 0xad5e1851u : 0xc08bb414u); // s704 add + r0 = r6 * r5 + r0; // s705 mad + r4 = mul_hi(r4, r1); // s706 mulhi + r4 = rotr_var(r4, r3); // s707 rotr + r3 = rotr_var(r3, r6); // s708 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 16u); r6 = r6 ^ t_; } // s709 shfl + r3 = r2 * r6 + r3; // s710 mad + r1 = r1 * r4; // s711 mul + r3 = r3 + r5 + ((((sel >> 13u) & 1u) != 0u) ? 0x407f7c4du : 0xdc55338fu); // s712 add + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 2u); r6 = r6 ^ t_; } // s713 shfl + r1 = r1 ^ r0; // s714 xor + r7 = r1 * r1 + r7; // s715 mad + r4 = r4 | r0; // s716 or + r6 = r6 * r4; // s717 mul + r0 = r0 - r5; // s718 sub + r1 = r1 ^ r4; // s719 xor + r4 = mul_hi(r4, r6); // s720 mulhi + r1 = r1 + r0 + ((((sel >> 13u) & 1u) != 0u) ? 0xc2093fcau : 0xb2ce569eu); // s721 add + r4 = mul_hi(r4, r2); // s722 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 16u); r6 = r6 ^ t_; } // s723 shfl + r5 = r3 * r0 + r5; // s724 mad + r5 = mul_hi(r5, r0); // s725 mulhi + r2 = rotr_var(r2, r5); // s726 rotr + r5 = r5 + r0 + ((((sel >> 20u) & 1u) != 0u) ? 0x48cdf1c1u : 0x4e8aaad5u); // s727 add + r1 = r1 * r0; // s728 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 1u); r3 = r3 ^ t_; } // s729 shfl + r4 = r4 * r6; // s730 mul + r4 = r4 - r6; // s731 sub + r4 = r4 ^ r2; // s732 xor + r5 = r5 * r6; // s733 mul + r7 = rotr_var(r7, r3); // s734 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 1u); r1 = r1 ^ t_; } // s735 shfl + r1 = mul_hi(r1, r0); // s736 mulhi + r2 = r2 * r6; // s737 mul + r5 = rotl_imm(r5, 27u); // s738 rotl + r2 = mul_hi(r2, r3); // s739 mulhi + r5 = r3 * r5 + r5; // s740 mad + r2 = rotl_imm(r2, 11u); // s741 rotl + r6 = r6 | r2; // s742 or + r2 = r2 ^ r3; // s743 xor + r3 = r3 * r1; // s744 mul + r4 = mul_hi(r4, r2); // s745 mulhi + r5 = r5 ^ r6; // s746 xor + r6 = r6 + r7 + ((((sel >> 11u) & 1u) != 0u) ? 0x0d6b844eu : 0x78fc162du); // s747 add + r1 = rotl_imm(r1, 27u); // s748 rotl + r4 = rotr_var(r4, r1); // s749 rotr + r5 = r5 ^ r7; // s750 xor + r4 = rotr_var(r4, r3); // s751 rotr + r5 = r5 * r2; // s752 mul + r1 = r6 * r7 + r1; // s753 mad + r0 = r0 ^ r1; // s754 xor + r7 = r7 - r1; // s755 sub + r0 = r0 + r4 + ((((sel >> 5u) & 1u) != 0u) ? 0xb74ac71eu : 0x68aab88bu); // s756 add + r7 = r7 + r5 + ((((sel >> 0u) & 1u) != 0u) ? 0xf81f5b66u : 0xba5c123au); // s757 add + r0 = r7 * r2 + r0; // s758 mad + r1 = r1 | r0; // s759 or + r4 = mul_hi(r4, r6); // s760 mulhi + r0 = mul_hi(r0, r7); // s761 mulhi + r3 = rotr_var(r3, r4); // s762 rotr + r3 = rotl_imm(r3, 30u); // s763 rotl + r6 = r6 * r2; // s764 mul + r6 = r6 ^ r4; // s765 xor + r3 = r3 + r4 + ((((sel >> 0u) & 1u) != 0u) ? 0x96dabea6u : 0x6eb1d82au); // s766 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 1u); r0 = r0 ^ t_; } // s767 shfl + r3 = rotl_imm(r3, 8u); // s768 rotl + r7 = r7 * r4; // s769 mul + r6 = r1 * r2 + r6; // s770 mad + r2 = r2 ^ r7; // s771 xor + r6 = r6 * r0; // s772 mul + r2 = r2 - r1; // s773 sub + r1 = r0 * r1 + r1; // s774 mad + r5 = mul_hi(r5, r7); // s775 mulhi + r0 = rotr_var(r0, r4); // s776 rotr + r6 = r6 ^ r0; // s777 xor + r4 = mul_hi(r4, r7); // s778 mulhi + r1 = r3 * r0 + r1; // s779 mad + r6 = r6 + r4 + ((((sel >> 2u) & 1u) != 0u) ? 0x903f3f77u : 0x11d7b79au); // s780 add + r4 = r4 ^ r7; // s781 xor + r1 = r1 + r2 + ((((sel >> 14u) & 1u) != 0u) ? 0x2ca81d8du : 0x1791eaddu); // s782 add + r2 = rotr_var(r2, r1); // s783 rotr + r4 = r4 * r6; // s784 mul + r1 = r1 ^ r6; // s785 xor + r4 = r4 - r0; // s786 sub + r3 = r3 ^ r4; // s787 xor + r4 = r4 * r1; // s788 mul + r4 = r6 * r7 + r4; // s789 mad + r5 = r5 - r0; // s790 sub + r2 = r2 * r0; // s791 mul + r7 = rotl_imm(r7, 12u); // s792 rotl + r2 = r7 * r3 + r2; // s793 mad + r1 = r4 * r4 + r1; // s794 mad + r6 = r6 + r4 + ((((sel >> 15u) & 1u) != 0u) ? 0xf66fad29u : 0xc08797bbu); // s795 add + r1 = r1 - r4; // s796 sub + r5 = r5 * r2; // s797 mul + r5 = r5 ^ r2; // s798 xor + r0 = r0 * r1; // s799 mul + r6 = r6 + r4 + ((((sel >> 13u) & 1u) != 0u) ? 0x2d82a681u : 0x6d4a6371u); // s800 add + r1 = r6 * r1 + r1; // s801 mad + r0 = r0 - r2; // s802 sub + r6 = r6 ^ r2; // s803 xor + r7 = rotl_imm(r7, 24u); // s804 rotl + r6 = r6 ^ r7; // s805 xor + r7 = r7 | r0; // s806 or + r0 = rotl_imm(r0, 5u); // s807 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 2u); r1 = r1 ^ t_; } // s808 shfl + r4 = r1 * r5 + r4; // s809 mad + r0 = r0 + r2 + ((((sel >> 14u) & 1u) != 0u) ? 0x63e62197u : 0x0092eb62u); // s810 add + r5 = r5 - r3; // s811 sub + r2 = r1 * r5 + r2; // s812 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 16u); r6 = r6 ^ t_; } // s813 shfl + r7 = r5 * r1 + r7; // s814 mad + r0 = mul_hi(r0, r7); // s815 mulhi + r2 = r2 | r1; // s816 or + r7 = mul_hi(r7, r3); // s817 mulhi + r2 = r2 ^ r4; // s818 xor + r4 = r4 + r3 + ((((sel >> 0u) & 1u) != 0u) ? 0x27d94f57u : 0xbb69174fu); // s819 add + r5 = r5 + r3 + ((((sel >> 1u) & 1u) != 0u) ? 0x82285691u : 0xda6759f2u); // s820 add + r1 = r1 + r3 + ((((sel >> 31u) & 1u) != 0u) ? 0xe50565d8u : 0x9ad4b47fu); // s821 add + r5 = rotl_imm(r5, 6u); // s822 rotl + r3 = r3 - r0; // s823 sub + r6 = rotl_imm(r6, 12u); // s824 rotl + r4 = r4 | r5; // s825 or + r3 = r3 ^ r2; // s826 xor + r4 = r4 + r0 + ((((sel >> 26u) & 1u) != 0u) ? 0xffcab83au : 0xca1e80fbu); // s827 add + r3 = r3 | r7; // s828 or + r1 = r5 * r7 + r1; // s829 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 16u); r6 = r6 ^ t_; } // s830 shfl + r1 = r1 - r0; // s831 sub + r0 = rotr_var(r0, r2); // s832 rotr + r1 = mul_hi(r1, r0); // s833 mulhi + r6 = mul_hi(r6, r4); // s834 mulhi + r6 = rotl_imm(r6, 2u); // s835 rotl + r4 = r4 | r6; // s836 or + r6 = rotl_imm(r6, 23u); // s837 rotl + r4 = r7 * r4 + r4; // s838 mad + r0 = r0 | r1; // s839 or + r5 = mul_hi(r5, r3); // s840 mulhi + r7 = r4 * r6 + r7; // s841 mad + r1 = r1 + r4 + ((((sel >> 21u) & 1u) != 0u) ? 0x1bc9f95du : 0xcfb90e90u); // s842 add + r1 = r1 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0xf9bd620fu : 0x0b4758b6u); // s843 add + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r2 = r2 ^ t_; } // s844 shfl + r3 = r1 * r7 + r3; // s845 mad + r5 = r5 * r2; // s846 mul + r0 = rotl_imm(r0, 21u); // s847 rotl + r7 = r7 ^ r1; // s848 xor + r3 = r3 + r4 + ((((sel >> 18u) & 1u) != 0u) ? 0x697a4946u : 0x41fdc15au); // s849 add + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 4u); r0 = r0 ^ t_; } // s850 shfl + r1 = rotr_var(r1, r5); // s851 rotr + r5 = r5 | r6; // s852 or + r6 = r6 - r2; // s853 sub + r2 = r2 ^ r6; // s854 xor + r4 = r4 - r6; // s855 sub + r6 = r4 * r6 + r6; // s856 mad + r4 = r4 * r0; // s857 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r2 = r2 ^ t_; } // s858 shfl + r3 = r3 * r4; // s859 mul + r3 = r1 * r7 + r3; // s860 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 2u); r3 = r3 ^ t_; } // s861 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r7 = r7 ^ t_; } // s862 shfl + r0 = r2 * r2 + r0; // s863 mad + r6 = r6 ^ r0; // s864 xor + r6 = r6 + r2 + ((((sel >> 2u) & 1u) != 0u) ? 0x7fedd7f3u : 0x90656f74u); // s865 add + r3 = r3 ^ r2; // s866 xor + r1 = r1 | r4; // s867 or + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 2u); r6 = r6 ^ t_; } // s868 shfl + r1 = mul_hi(r1, r0); // s869 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r3 = r3 ^ t_; } // s870 shfl + r0 = r0 - r3; // s871 sub + r6 = r6 + r1 + ((((sel >> 11u) & 1u) != 0u) ? 0xbe1b480au : 0xa5c0b461u); // s872 add + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r3 = r3 ^ t_; } // s873 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 1u); r5 = r5 ^ t_; } // s874 shfl + r2 = mul_hi(r2, r4); // s875 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 4u); r5 = r5 ^ t_; } // s876 shfl + r5 = rotl_imm(r5, 14u); // s877 rotl + r2 = r2 ^ r7; // s878 xor + r7 = r7 ^ r0; // s879 xor + r0 = r0 * r2; // s880 mul + r4 = r4 * r2; // s881 mul + r7 = r7 * r6; // s882 mul + r4 = mul_hi(r4, r5); // s883 mulhi + r0 = r0 - r4; // s884 sub + r0 = r0 ^ r5; // s885 xor + r6 = r6 * r5; // s886 mul + r1 = r1 + r5 + ((((sel >> 14u) & 1u) != 0u) ? 0x7007f98fu : 0xe806fcecu); // s887 add + r3 = r3 * r1; // s888 mul + r5 = r5 ^ r3; // s889 xor + r6 = r6 | r2; // s890 or + r1 = r1 * r2; // s891 mul + r5 = r5 + r7 + ((((sel >> 3u) & 1u) != 0u) ? 0xf3c87e02u : 0x89a8551eu); // s892 add + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 16u); r2 = r2 ^ t_; } // s893 shfl + r1 = r1 + r3 + ((((sel >> 13u) & 1u) != 0u) ? 0xc315f5deu : 0xba1369dbu); // s894 add + r5 = r0 * r3 + r5; // s895 mad + r5 = rotr_var(r5, r2); // s896 rotr + r1 = r1 ^ r0; // s897 xor + r5 = r5 ^ r1; // s898 xor + r5 = rotr_var(r5, r1); // s899 rotr + r3 = r6 * r6 + r3; // s900 mad + r0 = rotl_imm(r0, 8u); // s901 rotl + r1 = r1 | r0; // s902 or + r1 = r1 + r2 + ((((sel >> 3u) & 1u) != 0u) ? 0x1c355a71u : 0x260e6848u); // s903 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 16u); r7 = r7 ^ t_; } // s904 shfl + r1 = mul_hi(r1, r3); // s905 mulhi + r1 = rotr_var(r1, r4); // s906 rotr + r6 = r6 + r0 + ((((sel >> 8u) & 1u) != 0u) ? 0x0c74a1a8u : 0xa74fd2b1u); // s907 add + r6 = rotr_var(r6, r2); // s908 rotr + r4 = rotl_imm(r4, 12u); // s909 rotl + r5 = r5 + r3 + ((((sel >> 29u) & 1u) != 0u) ? 0xa49b5d73u : 0xe5fb043eu); // s910 add + r3 = r3 ^ r0; // s911 xor + r3 = rotr_var(r3, r4); // s912 rotr + r6 = rotr_var(r6, r0); // s913 rotr + r2 = r2 ^ r5; // s914 xor + r0 = r0 * r7; // s915 mul + r3 = r3 ^ r0; // s916 xor + r5 = r1 * r7 + r5; // s917 mad + r3 = r3 + r4 + ((((sel >> 2u) & 1u) != 0u) ? 0xeb76e56cu : 0x264cb47bu); // s918 add + r3 = mul_hi(r3, r4); // s919 mulhi + r5 = r5 + r6 + ((((sel >> 9u) & 1u) != 0u) ? 0x2aab9631u : 0x418baa72u); // s920 add + r5 = mul_hi(r5, r1); // s921 mulhi + r7 = r7 - r3; // s922 sub + r6 = r6 + r1 + ((((sel >> 2u) & 1u) != 0u) ? 0x98e6b26du : 0x3696a894u); // s923 add + r6 = r3 * r1 + r6; // s924 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r2 = r2 ^ t_; } // s925 shfl + r6 = r6 ^ r1; // s926 xor + r4 = r4 ^ r3; // s927 xor + r0 = r0 + r4 + ((((sel >> 7u) & 1u) != 0u) ? 0x142778eeu : 0x0468c062u); // s928 add + r7 = r7 + r3 + ((((sel >> 29u) & 1u) != 0u) ? 0x4eae212du : 0x0af82291u); // s929 add + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 16u); r4 = r4 ^ t_; } // s930 shfl + r7 = r7 + r2 + ((((sel >> 20u) & 1u) != 0u) ? 0x8d2a8b36u : 0x17de5e29u); // s931 add + r5 = r5 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0xe2d2d7d5u : 0x686794a8u); // s932 add + r0 = mul_hi(r0, r3); // s933 mulhi + r4 = r4 + r0 + ((((sel >> 10u) & 1u) != 0u) ? 0xe3c3c6f9u : 0x66278068u); // s934 add + r6 = rotl_imm(r6, 22u); // s935 rotl + r0 = r0 | r2; // s936 or + r4 = r4 * r3; // s937 mul + r3 = r3 | r6; // s938 or + r7 = rotl_imm(r7, 28u); // s939 rotl + r0 = r0 + r6 + ((((sel >> 20u) & 1u) != 0u) ? 0xc2296063u : 0xc2d02ca6u); // s940 add + r1 = r1 + r5 + ((((sel >> 14u) & 1u) != 0u) ? 0xef1ca415u : 0x0b3c00e0u); // s941 add + r2 = r2 - r6; // s942 sub + r6 = r6 | r3; // s943 or + r0 = rotl_imm(r0, 2u); // s944 rotl + r2 = r2 * r1; // s945 mul + r0 = r0 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0x06a1321au : 0x11224846u); // s946 add + r3 = r3 * r6; // s947 mul + r5 = r5 - r2; // s948 sub + r5 = r5 + r4 + ((((sel >> 5u) & 1u) != 0u) ? 0x5d3e225cu : 0x461c43d4u); // s949 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 16u); r2 = r2 ^ t_; } // s950 shfl + r7 = r0 * r0 + r7; // s951 mad + r6 = rotr_var(r6, r4); // s952 rotr + r1 = r1 + r0 + ((((sel >> 30u) & 1u) != 0u) ? 0xbb84f628u : 0xd5eed39fu); // s953 add + r4 = rotl_imm(r4, 31u); // s954 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 16u); r1 = r1 ^ t_; } // s955 shfl + r2 = r2 - r6; // s956 sub + r4 = r4 ^ r2; // s957 xor + r0 = r0 ^ r2; // s958 xor + r1 = r1 + r0 + ((((sel >> 28u) & 1u) != 0u) ? 0x374c0426u : 0x519d72f7u); // s959 add + r5 = r5 * r4; // s960 mul + r5 = r5 - r7; // s961 sub + r2 = r2 ^ r6; // s962 xor + r4 = r4 ^ r1; // s963 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 16u); r2 = r2 ^ t_; } // s964 shfl + r7 = mul_hi(r7, r3); // s965 mulhi + r4 = rotl_imm(r4, 12u); // s966 rotl + r4 = r4 + r6 + ((((sel >> 26u) & 1u) != 0u) ? 0x03b88592u : 0x151dae18u); // s967 add + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r1 = r1 ^ t_; } // s968 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 8u); r3 = r3 ^ t_; } // s969 shfl + r2 = r2 ^ r7; // s970 xor + r5 = r3 * r4 + r5; // s971 mad + r0 = r0 ^ r3; // s972 xor + r2 = r2 ^ r5; // s973 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 4u); r1 = r1 ^ t_; } // s974 shfl + r5 = r1 * r4 + r5; // s975 mad + r2 = rotl_imm(r2, 19u); // s976 rotl + r1 = r1 - r4; // s977 sub + r5 = rotr_var(r5, r4); // s978 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 16u); r2 = r2 ^ t_; } // s979 shfl + r6 = r6 + r7 + ((((sel >> 28u) & 1u) != 0u) ? 0x1fdee45eu : 0x16220e61u); // s980 add + r4 = rotr_var(r4, r6); // s981 rotr + r6 = mul_hi(r6, r3); // s982 mulhi + r5 = rotl_imm(r5, 17u); // s983 rotl + r2 = r7 * r1 + r2; // s984 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 8u); r4 = r4 ^ t_; } // s985 shfl + r3 = r3 ^ r1; // s986 xor + r4 = r4 + r0 + ((((sel >> 27u) & 1u) != 0u) ? 0x44adc457u : 0x6cd6b697u); // s987 add + r1 = r1 * r5; // s988 mul + r4 = r4 + r2 + ((((sel >> 2u) & 1u) != 0u) ? 0x0a06a223u : 0x1103d2d2u); // s989 add + r4 = r4 * r1; // s990 mul + r4 = r5 * r1 + r4; // s991 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r3 = r3 ^ t_; } // s992 shfl + r1 = r1 - r3; // s993 sub + r4 = r7 * r5 + r4; // s994 mad + r1 = mul_hi(r1, r2); // s995 mulhi + r2 = r1 * r0 + r2; // s996 mad + r3 = rotl_imm(r3, 31u); // s997 rotl + r4 = r4 - r3; // s998 sub + r5 = rotr_var(r5, r3); // s999 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 4u); r4 = r4 ^ t_; } // s1000 shfl + r2 = r2 - r5; // s1001 sub + r3 = r4 * r4 + r3; // s1002 mad + r7 = r5 * r1 + r7; // s1003 mad + r7 = r7 + r4 + ((((sel >> 29u) & 1u) != 0u) ? 0x0044887fu : 0xa9c9d8a9u); // s1004 add + r4 = mul_hi(r4, r0); // s1005 mulhi + r4 = rotl_imm(r4, 21u); // s1006 rotl + r3 = r3 * r1; // s1007 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 2u); r1 = r1 ^ t_; } // s1008 shfl + r0 = mul_hi(r0, r6); // s1009 mulhi + r0 = r0 ^ r3; // s1010 xor + r5 = r5 | r4; // s1011 or + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 4u); r1 = r1 ^ t_; } // s1012 shfl + r2 = r2 + r4 + ((((sel >> 4u) & 1u) != 0u) ? 0x6b70e2c7u : 0xfa1574e3u); // s1013 add + r5 = rotr_var(r5, r7); // s1014 rotr + r0 = rotr_var(r0, r7); // s1015 rotr + r5 = r5 - r7; // s1016 sub + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 16u); r4 = r4 ^ t_; } // s1017 shfl + r6 = mul_hi(r6, r7); // s1018 mulhi + r0 = rotr_var(r0, r1); // s1019 rotr + r2 = r2 ^ r0; // s1020 xor + r4 = r5 * r1 + r4; // s1021 mad + r6 = r6 | r2; // s1022 or + r3 = r3 ^ r0; // s1023 xor + } + } + uint lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((ulong)hi << 32) | (ulong)lo; +} diff --git a/proto-cuda/packs-ca3-shadow/sh1024x3/kernel_bound.cu b/proto-cuda/packs-ca3-shadow/sh1024x3/kernel_bound.cu new file mode 100644 index 000000000..1f6c9d3d8 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh1024x3/kernel_bound.cu @@ -0,0 +1,1150 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Header-bound twin of igneum_hash in kernel.cu: the init words come from a kernel argument, not SEEDW. +// Host declarations (also in program_bound.h if present): +// struct IgneumInitWords { uint32_t w[8]; }; +// cudaError_t igneum_launch_hash_bound(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, +// IgneumInitWords iw, uint32_t nonces, uint32_t blockWarps); +// cudaError_t igneum_hash_bound_info(int* numRegs, int* blocksPerSM, uint32_t blockWarps); +#include +#include +#include "program.h" + +struct IgneumInitWords { uint32_t w[8]; }; + +__device__ __forceinline__ uint32_t splitmix32(uint32_t x) { + x ^= x >> 16; x *= 0x7feb352du; + x ^= x >> 15; x *= 0x846ca68bu; + x ^= x >> 16; + return x; +} +__device__ __forceinline__ uint32_t rotl_imm(uint32_t x, uint32_t n) { return (x << n) | (x >> (32u - n)); } +__device__ __forceinline__ uint32_t rotr_var(uint32_t x, uint32_t n) { n &= 31u; return (x >> n) | (x << ((32u - n) & 31u)); } + +__global__ void igneum_hash_bound(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, IgneumInitWords iw) { + uint32_t gid = blockIdx.x * blockDim.x + threadIdx.x; + uint32_t nonce = baseNonce + gid; + uint32_t r0, r1, r2, r3, r4, r5, r6, r7; + { uint32_t x = nonce ^ iw.w[0]; x += 0x9e3779b9u * 1u; x = splitmix32(x); r0 = x ^ iw.w[1]; } + { uint32_t x = nonce ^ iw.w[1]; x += 0x9e3779b9u * 2u; x = splitmix32(x); r1 = x ^ iw.w[2]; } + { uint32_t x = nonce ^ iw.w[2]; x += 0x9e3779b9u * 3u; x = splitmix32(x); r2 = x ^ iw.w[3]; } + { uint32_t x = nonce ^ iw.w[3]; x += 0x9e3779b9u * 4u; x = splitmix32(x); r3 = x ^ iw.w[4]; } + { uint32_t x = nonce ^ iw.w[4]; x += 0x9e3779b9u * 5u; x = splitmix32(x); r4 = x ^ iw.w[5]; } + { uint32_t x = nonce ^ iw.w[5]; x += 0x9e3779b9u * 6u; x = splitmix32(x); r5 = x ^ iw.w[6]; } + { uint32_t x = nonce ^ iw.w[6]; x += 0x9e3779b9u * 7u; x = splitmix32(x); r6 = x ^ iw.w[7]; } + { uint32_t x = nonce ^ iw.w[7]; x += 0x9e3779b9u * 8u; x = splitmix32(x); r7 = x ^ iw.w[0]; } + + for (uint32_t it = 0u; it < 8u; ++it) { + uint32_t sel = r0; + r2 = r3 * r4 + r2; // 0 mad + r2 = r1 * r1 + r2; // 1 mad + r2 = r3 * r2 + r2; // 2 mad + r3 = r3 ^ r5; // 3 xor + r7 = r7 ^ ds[r2 & mask]; // 4 load + r5 = r5 ^ ds[r7 & mask]; // 5 load + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r4, 8); // 6 shfl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r3, 8); // 7 shfl + r1 = __umulhi(r1, r5); // 8 mulhi + r6 = rotr_var(r6, r3); // 9 rotr + r3 = r3 | r4; // 10 or + r4 = r4 ^ ds[r3 & mask]; // 11 load + r0 = __umulhi(r0, r4); // 12 mulhi + r5 = r5 + r1 + ((((sel >> 30u) & 1u) != 0u) ? 0xd3177981u : 0xc7934706u); // 13 add + r0 = r0 ^ ds[r4 & mask]; // 14 load + r2 = r2 - r4; // 15 sub + r2 = r2 ^ ds[r0 & mask]; // 16 load + r7 = r7 ^ ds[r2 & mask]; // 17 load + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r3, 4); // 18 shfl + r5 = r5 * r0; // 19 mul + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // 20 shfl + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 16); // 21 shfl + r6 = __umulhi(r6, r2); // 22 mulhi + r6 = r6 ^ ds[r1 & mask]; // 23 load + r5 = r5 * r0; // 24 mul + r5 = rotl_imm(r5, 19u); // 25 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r6, 2); // 26 shfl + r0 = r0 ^ r5; // 27 xor + r0 = r0 ^ r4; // 28 xor + r3 = r3 - r0; // 29 sub + r5 = r5 * r1; // 30 mul + r7 = r7 ^ ds[r2 & mask]; // 31 load + r1 = r1 ^ ds[r0 & mask]; // 32 load + r5 = r5 ^ r6; // 33 xor + r5 = r5 ^ ds[r1 & mask]; // 34 load + r0 = __umulhi(r0, r5); // 35 mulhi + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // 36 shfl + r7 = r7 ^ ds[r0 & mask]; // 37 load + r3 = r3 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0x230c005cu : 0x75ba2fadu); // 38 add + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r5, 4); // 39 shfl + r2 = r2 ^ r5; // 40 xor + r3 = r6 * r3 + r3; // 41 mad + r6 = r6 - r7; // 42 sub + r7 = r7 ^ r0; // 43 xor + r1 = r1 ^ ds[r7 & mask]; // 44 load + r2 = r2 * r3; // 45 mul + r1 = __umulhi(r1, r5); // 46 mulhi + r4 = r4 - r3; // 47 sub + r2 = rotr_var(r2, r6); // 48 rotr + r3 = r3 ^ ds[r5 & mask]; // 49 load + r1 = r1 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x1907970cu : 0x81b8bc2cu); // 50 add + r0 = r0 * r2; // 51 mul + r0 = r0 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x699fd448u : 0x4f92b968u); // 52 add + r1 = r1 + r0 + ((((sel >> 12u) & 1u) != 0u) ? 0x77b1520du : 0x2bb965afu); // 53 add + r7 = rotl_imm(r7, 14u); // 54 rotl + r3 = r3 + r7 + ((((sel >> 1u) & 1u) != 0u) ? 0xa54c55a0u : 0x7b0fe07au); // 55 add + r6 = r6 ^ ds[r7 & mask]; // 56 load + r1 = rotr_var(r1, r5); // 57 rotr + r5 = r5 ^ ds[r4 & mask]; // 58 load + r6 = r6 ^ ds[r2 & mask]; // 59 load + r3 = r5 * r0 + r3; // 60 mad + r5 = r5 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0xad7493e7u : 0xaf9dd72du); // 61 add + r4 = r4 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x1e07c3d9u : 0x89841d87u); // 62 add + r5 = rotl_imm(r5, 19u); // 63 rotl + // latency-shadow block (Counter ASIC 3.0 item 8): 1024 ALU instructions x 3 passes after instruction 63, no load + for (uint32_t sh = 0u; sh < 3u; ++sh) { + r5 = r5 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x8bc12da9u : 0x92199f99u); // s0 add + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x63079e5au : 0x8d72d3adu); // s1 add + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r3, 2); // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + ((((sel >> 31u) & 1u) != 0u) ? 0x5d4c7a60u : 0xb21b4babu); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + ((((sel >> 16u) & 1u) != 0u) ? 0xc88e2942u : 0x2fe0e98bu); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r1, 4); // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r6, 4); // s12 shfl + r1 = r1 + r5 + ((((sel >> 25u) & 1u) != 0u) ? 0xbc48c63eu : 0xbdf8f9a5u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 8); // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + ((((sel >> 1u) & 1u) != 0u) ? 0x96e8f127u : 0x45c37cecu); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = __umulhi(r6, r0); // s28 mulhi + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // s29 shfl + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r6, 1); // s30 shfl + r1 = r1 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0xb1cdb2abu : 0x37985632u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // s33 shfl + r0 = r0 ^ __shfl_xor_sync(0xffffffffu, r3, 4); // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x856e0180u : 0x804e777eu); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xe9bd0cc4u : 0x0b06c8a7u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = __umulhi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = __umulhi(r4, r3); // s44 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xcdcb63f6u : 0xee822e17u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r3, 8); // s47 shfl + r6 = __umulhi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0xd4758987u : 0x3dfad1b6u); // s56 add + r4 = r4 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x0602d6beu : 0xfca75bc2u); // s57 add + r5 = __umulhi(r5, r6); // s58 mulhi + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0x8596687au : 0xd71c02ffu); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r5, 2); // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0x08ac5733u : 0x3c6fe15du); // s72 add + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r2, 8); // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + ((((sel >> 1u) & 1u) != 0u) ? 0xc100b495u : 0x295d5faeu); // s77 add + r3 = __umulhi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + ((((sel >> 15u) & 1u) != 0u) ? 0x5cc59530u : 0x274a9221u); // s81 add + r7 = r7 + r3 + ((((sel >> 5u) & 1u) != 0u) ? 0x141479ecu : 0xc8651f8eu); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r5, 16); // s85 shfl + r3 = r3 ^ r2; // s86 xor + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r7, 2); // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x883c0c92u : 0x53f915c2u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + ((((sel >> 31u) & 1u) != 0u) ? 0x3cc5bd20u : 0xe2be00a5u); // s91 add + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r2, 1); // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + ((((sel >> 17u) & 1u) != 0u) ? 0xbfd646cbu : 0x423fd9c9u); // s101 add + r7 = r7 + r6 + ((((sel >> 11u) & 1u) != 0u) ? 0x19b74a43u : 0x8d3c011du); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + ((((sel >> 15u) & 1u) != 0u) ? 0x7dcb7e18u : 0x8ce14721u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = __umulhi(r2, r0); // s109 mulhi + r1 = __umulhi(r1, r0); // s110 mulhi + r0 = r0 + r2 + ((((sel >> 28u) & 1u) != 0u) ? 0x3c179ad8u : 0x2d9fc6b9u); // s111 add + r2 = __umulhi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + ((((sel >> 22u) & 1u) != 0u) ? 0x47359729u : 0x502138e2u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = __umulhi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r2, 2); // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x6c57e4e7u : 0x33dff776u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + ((((sel >> 30u) & 1u) != 0u) ? 0xe8212c0cu : 0x5db25b34u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = __umulhi(r0, r5); // s138 mulhi + r2 = r2 + r7 + ((((sel >> 10u) & 1u) != 0u) ? 0xd44ff710u : 0x218d4090u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r6, 1); // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + ((((sel >> 29u) & 1u) != 0u) ? 0xb98942fau : 0xf4b1a8deu); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + ((((sel >> 17u) & 1u) != 0u) ? 0x0d48ba42u : 0x2bef10f2u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + ((((sel >> 30u) & 1u) != 0u) ? 0xc98dea9cu : 0xdc5cc080u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0x6c752dcbu : 0x18197438u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + ((((sel >> 3u) & 1u) != 0u) ? 0x8e481727u : 0xf1c46574u); // s163 add + r0 = __umulhi(r0, r4); // s164 mulhi + r2 = r2 + r6 + ((((sel >> 20u) & 1u) != 0u) ? 0x550ab406u : 0xac578137u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + ((((sel >> 14u) & 1u) != 0u) ? 0xaebb5966u : 0xa33e6706u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r0, 8); // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x5bb7550fu : 0xd94d55acu); // s184 add + r3 = r3 | r5; // s185 or + r6 = __umulhi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s188 shfl + r6 = r6 + r5 + ((((sel >> 6u) & 1u) != 0u) ? 0x2a354e2du : 0x89e747feu); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = __umulhi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r5, 16); // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + ((((sel >> 7u) & 1u) != 0u) ? 0x10cfdc71u : 0xea03e8e7u); // s197 add + r7 = r7 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x66e148d3u : 0xa7ee0102u); // s198 add + r5 = r5 - r2; // s199 sub + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s200 shfl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 8); // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0x8558b619u : 0x8379a4deu); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = __umulhi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r0, 4); // s209 shfl + r7 = r7 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0xf4049c4cu : 0xaa8cb14eu); // s210 add + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 16); // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r2, 16); // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = __umulhi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r2, 8); // s222 shfl + r5 = __umulhi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0x2a7fecb2u : 0x1d176220u); // s230 add + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + ((((sel >> 25u) & 1u) != 0u) ? 0xadce39f3u : 0x17dafb4du); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + ((((sel >> 29u) & 1u) != 0u) ? 0x0e7033b6u : 0xf2f77d26u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + ((((sel >> 31u) & 1u) != 0u) ? 0x7b2ff6b7u : 0xfed2da4eu); // s247 add + r0 = r0 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0xb5fad7b1u : 0x03b2891cu); // s248 add + r5 = __umulhi(r5, r4); // s249 mulhi + r5 = r5 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0xa7e71c2fu : 0x042cd6e3u); // s250 add + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r1, 1); // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0xb83d78deu : 0x784a302bu); // s254 add + r2 = r2 - r4; // s255 sub + r3 = r3 - r4; // s256 sub + r2 = r2 * r4; // s257 mul + r4 = r0 * r6 + r4; // s258 mad + r5 = r5 | r0; // s259 or + r4 = r4 ^ r6; // s260 xor + r6 = __umulhi(r6, r3); // s261 mulhi + r2 = r2 * r6; // s262 mul + r5 = rotl_imm(r5, 1u); // s263 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 8); // s264 shfl + r3 = r3 * r2; // s265 mul + r2 = r2 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x99a1d1b6u : 0x3dddf1b2u); // s266 add + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r0, 8); // s267 shfl + r0 = r0 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s268 shfl + r4 = r4 - r2; // s269 sub + r0 = r0 ^ __shfl_xor_sync(0xffffffffu, r5, 1); // s270 shfl + r3 = r3 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x40ca287au : 0xcfc62661u); // s271 add + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r7, 16); // s272 shfl + r1 = r3 * r6 + r1; // s273 mad + r7 = r7 + r6 + ((((sel >> 30u) & 1u) != 0u) ? 0xed4b65adu : 0x44caede3u); // s274 add + r5 = r5 ^ r7; // s275 xor + r2 = r2 * r6; // s276 mul + r2 = r2 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0x0f45ae89u : 0x9aae6c12u); // s277 add + r2 = r2 ^ r6; // s278 xor + r1 = r1 - r2; // s279 sub + r5 = r5 ^ r1; // s280 xor + r7 = r7 ^ r1; // s281 xor + r7 = r7 - r1; // s282 sub + r5 = r5 - r7; // s283 sub + r7 = r0 * r6 + r7; // s284 mad + r5 = __umulhi(r5, r4); // s285 mulhi + r3 = r3 - r5; // s286 sub + r5 = r5 - r1; // s287 sub + r1 = r3 * r7 + r1; // s288 mad + r3 = rotl_imm(r3, 9u); // s289 rotl + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r6, 8); // s290 shfl + r7 = r7 + r2 + ((((sel >> 1u) & 1u) != 0u) ? 0xe086d3b6u : 0x2307120bu); // s291 add + r4 = r4 ^ r3; // s292 xor + r3 = rotl_imm(r3, 14u); // s293 rotl + r5 = r5 - r4; // s294 sub + r2 = __umulhi(r2, r3); // s295 mulhi + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r3, 4); // s296 shfl + r3 = r6 * r1 + r3; // s297 mad + r4 = r4 ^ r1; // s298 xor + r6 = r6 + r3 + ((((sel >> 24u) & 1u) != 0u) ? 0xadbeb223u : 0x4e3a12e5u); // s299 add + r6 = __umulhi(r6, r5); // s300 mulhi + r7 = rotr_var(r7, r5); // s301 rotr + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r4, 16); // s302 shfl + r3 = r3 ^ r4; // s303 xor + r2 = r3 * r1 + r2; // s304 mad + r1 = r1 ^ r7; // s305 xor + r1 = r1 + r0 + ((((sel >> 22u) & 1u) != 0u) ? 0x0d8f1149u : 0x51ab0157u); // s306 add + r2 = r2 + r1 + ((((sel >> 24u) & 1u) != 0u) ? 0x99a96de9u : 0x3b5e8835u); // s307 add + r1 = r5 * r5 + r1; // s308 mad + r2 = r2 * r4; // s309 mul + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r7, 8); // s310 shfl + r0 = r0 ^ r4; // s311 xor + r5 = __umulhi(r5, r2); // s312 mulhi + r7 = r7 + r2 + ((((sel >> 30u) & 1u) != 0u) ? 0x86ddfba7u : 0x81f3297cu); // s313 add + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x38aa230au : 0x838e4a2fu); // s314 add + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r0, 16); // s315 shfl + r7 = r7 - r5; // s316 sub + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r1, 4); // s317 shfl + r1 = r1 + r3 + ((((sel >> 11u) & 1u) != 0u) ? 0xa6399179u : 0xebcad805u); // s318 add + r7 = rotl_imm(r7, 21u); // s319 rotl + r7 = r7 ^ r6; // s320 xor + r7 = r7 | r6; // s321 or + r5 = r5 + r3 + ((((sel >> 25u) & 1u) != 0u) ? 0x4de83051u : 0x4c906f73u); // s322 add + r0 = r0 + r4 + ((((sel >> 14u) & 1u) != 0u) ? 0xd3d821c5u : 0x742ec195u); // s323 add + r6 = r6 ^ r2; // s324 xor + r6 = rotl_imm(r6, 1u); // s325 rotl + r4 = rotl_imm(r4, 24u); // s326 rotl + r4 = r4 | r3; // s327 or + r2 = r1 * r3 + r2; // s328 mad + r2 = r2 ^ r7; // s329 xor + r2 = r2 | r3; // s330 or + r7 = r7 - r1; // s331 sub + r3 = r3 + r6 + ((((sel >> 0u) & 1u) != 0u) ? 0xc06f831eu : 0xb86750e9u); // s332 add + r7 = rotl_imm(r7, 25u); // s333 rotl + r3 = r0 * r0 + r3; // s334 mad + r2 = r2 + r5 + ((((sel >> 28u) & 1u) != 0u) ? 0x5225df1du : 0xb57956eeu); // s335 add + r3 = r1 * r6 + r3; // s336 mad + r4 = r2 * r2 + r4; // s337 mad + r7 = r7 * r2; // s338 mul + r1 = r1 * r6; // s339 mul + r4 = r4 + r5 + ((((sel >> 5u) & 1u) != 0u) ? 0xb73822ceu : 0x23f6425fu); // s340 add + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r7, 2); // s341 shfl + r6 = r6 ^ r5; // s342 xor + r0 = rotl_imm(r0, 13u); // s343 rotl + r0 = rotr_var(r0, r3); // s344 rotr + r1 = r1 - r0; // s345 sub + r6 = rotr_var(r6, r1); // s346 rotr + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r5, 4); // s347 shfl + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r1, 8); // s348 shfl + r5 = r5 ^ r3; // s349 xor + r1 = r4 * r0 + r1; // s350 mad + r3 = rotr_var(r3, r1); // s351 rotr + r1 = rotl_imm(r1, 13u); // s352 rotl + r3 = r3 + r0 + ((((sel >> 26u) & 1u) != 0u) ? 0xfa0c560eu : 0x0dce5917u); // s353 add + r3 = __umulhi(r3, r2); // s354 mulhi + r1 = r2 * r4 + r1; // s355 mad + r0 = r0 ^ r1; // s356 xor + r7 = r7 * r5; // s357 mul + r0 = rotl_imm(r0, 5u); // s358 rotl + r2 = r7 * r7 + r2; // s359 mad + r2 = r2 | r6; // s360 or + r6 = r6 + r1 + ((((sel >> 19u) & 1u) != 0u) ? 0x277e027au : 0x7c83b79au); // s361 add + r0 = r0 * r2; // s362 mul + r3 = r3 * r6; // s363 mul + r2 = rotr_var(r2, r4); // s364 rotr + r5 = r5 + r1 + ((((sel >> 1u) & 1u) != 0u) ? 0x52275ea4u : 0x271f2385u); // s365 add + r1 = r1 * r6; // s366 mul + r0 = r0 + r7 + ((((sel >> 30u) & 1u) != 0u) ? 0x8f8b4093u : 0x4c66800fu); // s367 add + r4 = rotr_var(r4, r0); // s368 rotr + r4 = rotr_var(r4, r0); // s369 rotr + r1 = r0 * r6 + r1; // s370 mad + r0 = r0 - r5; // s371 sub + r7 = r7 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0x9a7dcadcu : 0x7dad1ed5u); // s372 add + r7 = r7 + r3 + ((((sel >> 20u) & 1u) != 0u) ? 0xf808c195u : 0x1ea3d58eu); // s373 add + r1 = r1 * r2; // s374 mul + r3 = r7 * r2 + r3; // s375 mad + r4 = r4 ^ r1; // s376 xor + r1 = r1 | r0; // s377 or + r5 = r5 + r0 + ((((sel >> 26u) & 1u) != 0u) ? 0x427ed5ceu : 0x98b36d10u); // s378 add + r6 = r6 * r0; // s379 mul + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r3, 1); // s380 shfl + r4 = r4 + r0 + ((((sel >> 18u) & 1u) != 0u) ? 0x38f848b9u : 0xb19cab2du); // s381 add + r3 = r5 * r2 + r3; // s382 mad + r0 = r0 | r7; // s383 or + r5 = r5 - r4; // s384 sub + r1 = r1 - r5; // s385 sub + r2 = r2 - r0; // s386 sub + r5 = r5 + r2 + ((((sel >> 17u) & 1u) != 0u) ? 0xffc20cf8u : 0x341056b0u); // s387 add + r1 = rotl_imm(r1, 26u); // s388 rotl + r2 = r2 ^ r5; // s389 xor + r5 = r7 * r0 + r5; // s390 mad + r3 = __umulhi(r3, r2); // s391 mulhi + r5 = r5 + r4 + ((((sel >> 0u) & 1u) != 0u) ? 0xfb939f2bu : 0x78aa571au); // s392 add + r5 = r5 | r2; // s393 or + r1 = __umulhi(r1, r7); // s394 mulhi + r4 = r4 - r2; // s395 sub + r7 = r7 - r1; // s396 sub + r0 = r0 + r1 + ((((sel >> 2u) & 1u) != 0u) ? 0xa9c6c9fbu : 0x31af4767u); // s397 add + r3 = r3 * r1; // s398 mul + r1 = r1 - r7; // s399 sub + r7 = r7 + r6 + ((((sel >> 8u) & 1u) != 0u) ? 0x34f9b056u : 0x266d4c34u); // s400 add + r5 = rotl_imm(r5, 5u); // s401 rotl + r0 = r0 + r4 + ((((sel >> 23u) & 1u) != 0u) ? 0x79822c64u : 0x7241955eu); // s402 add + r2 = r4 * r0 + r2; // s403 mad + r5 = rotl_imm(r5, 29u); // s404 rotl + r3 = r3 - r5; // s405 sub + r2 = r2 + r3 + ((((sel >> 27u) & 1u) != 0u) ? 0xda046091u : 0xf65aca5du); // s406 add + r4 = __umulhi(r4, r7); // s407 mulhi + r2 = r2 + r1 + ((((sel >> 14u) & 1u) != 0u) ? 0x167aba1cu : 0x6a00cefbu); // s408 add + r2 = r6 * r6 + r2; // s409 mad + r6 = rotl_imm(r6, 26u); // s410 rotl + r6 = r6 | r7; // s411 or + r1 = rotl_imm(r1, 20u); // s412 rotl + r7 = r7 * r5; // s413 mul + r6 = r6 - r0; // s414 sub + r6 = __umulhi(r6, r0); // s415 mulhi + r3 = rotl_imm(r3, 5u); // s416 rotl + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r3, 4); // s417 shfl + r0 = r0 * r4; // s418 mul + r4 = rotr_var(r4, r7); // s419 rotr + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s420 shfl + r5 = r3 * r6 + r5; // s421 mad + r3 = r3 ^ r4; // s422 xor + r3 = rotr_var(r3, r7); // s423 rotr + r4 = r4 + r1 + ((((sel >> 26u) & 1u) != 0u) ? 0xbb669c17u : 0xba29da18u); // s424 add + r7 = rotr_var(r7, r5); // s425 rotr + r2 = r2 * r6; // s426 mul + r1 = r1 + r4 + ((((sel >> 16u) & 1u) != 0u) ? 0xc6b45a76u : 0x4f70e34fu); // s427 add + r1 = rotl_imm(r1, 1u); // s428 rotl + r6 = __umulhi(r6, r5); // s429 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xff610984u : 0x3883e0f5u); // s430 add + r4 = r4 | r3; // s431 or + r7 = r7 ^ r5; // s432 xor + r3 = __umulhi(r3, r2); // s433 mulhi + r2 = r2 ^ r6; // s434 xor + r4 = r4 | r3; // s435 or + r0 = r0 + r1 + ((((sel >> 9u) & 1u) != 0u) ? 0xf37057feu : 0xb1b15861u); // s436 add + r7 = r7 + r4 + ((((sel >> 4u) & 1u) != 0u) ? 0x61793eafu : 0x2e9e173fu); // s437 add + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r1, 1); // s438 shfl + r6 = r0 * r3 + r6; // s439 mad + r5 = r5 ^ r2; // s440 xor + r0 = r0 ^ __shfl_xor_sync(0xffffffffu, r4, 16); // s441 shfl + r6 = r6 * r3; // s442 mul + r5 = r5 - r4; // s443 sub + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r1, 4); // s444 shfl + r0 = r0 + r5 + ((((sel >> 12u) & 1u) != 0u) ? 0x69def831u : 0x646856aau); // s445 add + r4 = r4 + r6 + ((((sel >> 23u) & 1u) != 0u) ? 0x1f8ecb8bu : 0x58a3f8fcu); // s446 add + r4 = r0 * r2 + r4; // s447 mad + r5 = r5 * r0; // s448 mul + r2 = r2 + r5 + ((((sel >> 11u) & 1u) != 0u) ? 0x7ecb876du : 0x48d3062du); // s449 add + r2 = r5 * r6 + r2; // s450 mad + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r3, 4); // s451 shfl + r2 = r2 * r5; // s452 mul + r5 = __umulhi(r5, r4); // s453 mulhi + r1 = r1 ^ r7; // s454 xor + r2 = r2 * r7; // s455 mul + r1 = r1 * r3; // s456 mul + r3 = r6 * r2 + r3; // s457 mad + r7 = r7 - r0; // s458 sub + r2 = r4 * r5 + r2; // s459 mad + r0 = rotl_imm(r0, 2u); // s460 rotl + r4 = r4 ^ r2; // s461 xor + r4 = r4 + r0 + ((((sel >> 18u) & 1u) != 0u) ? 0x7b093757u : 0xb41dd69bu); // s462 add + r6 = r6 + r1 + ((((sel >> 3u) & 1u) != 0u) ? 0x916e1b7eu : 0xb042032eu); // s463 add + r2 = r2 + r6 + ((((sel >> 8u) & 1u) != 0u) ? 0x6d42b978u : 0x4e68a2a0u); // s464 add + r3 = r3 - r2; // s465 sub + r2 = r2 * r5; // s466 mul + r7 = rotl_imm(r7, 28u); // s467 rotl + r0 = r0 - r3; // s468 sub + r7 = __umulhi(r7, r2); // s469 mulhi + r7 = r7 | r6; // s470 or + r7 = rotl_imm(r7, 28u); // s471 rotl + r0 = r0 * r6; // s472 mul + r2 = r2 | r1; // s473 or + r2 = r2 + r4 + ((((sel >> 14u) & 1u) != 0u) ? 0x20c5276bu : 0x13ec3b3eu); // s474 add + r2 = rotr_var(r2, r6); // s475 rotr + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r0, 16); // s476 shfl + r2 = rotl_imm(r2, 15u); // s477 rotl + r5 = rotr_var(r5, r4); // s478 rotr + r3 = rotl_imm(r3, 26u); // s479 rotl + r5 = r5 | r6; // s480 or + r3 = rotl_imm(r3, 29u); // s481 rotl + r0 = rotr_var(r0, r7); // s482 rotr + r1 = r1 - r0; // s483 sub + r0 = r2 * r5 + r0; // s484 mad + r6 = r6 ^ r4; // s485 xor + r6 = r6 ^ r0; // s486 xor + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r7, 4); // s487 shfl + r6 = __umulhi(r6, r0); // s488 mulhi + r1 = r1 * r0; // s489 mul + r3 = r3 ^ r6; // s490 xor + r3 = r3 * r6; // s491 mul + r0 = r0 * r3; // s492 mul + r4 = r4 | r3; // s493 or + r0 = r0 ^ __shfl_xor_sync(0xffffffffu, r5, 8); // s494 shfl + r0 = r0 ^ __shfl_xor_sync(0xffffffffu, r7, 16); // s495 shfl + r6 = r5 * r2 + r6; // s496 mad + r5 = r5 * r6; // s497 mul + r3 = r3 ^ r1; // s498 xor + r0 = r0 + r1 + ((((sel >> 20u) & 1u) != 0u) ? 0x19f4c710u : 0x53e99acau); // s499 add + r6 = r5 * r2 + r6; // s500 mad + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 4); // s501 shfl + r3 = r3 - r5; // s502 sub + r0 = rotl_imm(r0, 8u); // s503 rotl + r3 = r3 ^ r1; // s504 xor + r7 = r7 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x7a6ac7b5u : 0x0867fe20u); // s505 add + r0 = r0 ^ __shfl_xor_sync(0xffffffffu, r7, 2); // s506 shfl + r0 = r0 * r1; // s507 mul + r6 = r6 | r5; // s508 or + r2 = r2 * r7; // s509 mul + r1 = r1 + r5 + ((((sel >> 21u) & 1u) != 0u) ? 0xd77f6a03u : 0xd7fdc3ecu); // s510 add + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r7, 8); // s511 shfl + r6 = r6 + r3 + ((((sel >> 9u) & 1u) != 0u) ? 0x5c22b0b5u : 0x297a096au); // s512 add + r7 = r7 | r0; // s513 or + r7 = r7 + r3 + ((((sel >> 27u) & 1u) != 0u) ? 0x4caafacdu : 0x5de1d1d1u); // s514 add + r1 = __umulhi(r1, r0); // s515 mulhi + r0 = r0 - r6; // s516 sub + r2 = r2 - r1; // s517 sub + r6 = r5 * r7 + r6; // s518 mad + r2 = r2 ^ r7; // s519 xor + r1 = r1 | r5; // s520 or + r0 = r4 * r6 + r0; // s521 mad + r4 = r4 + r6 + ((((sel >> 29u) & 1u) != 0u) ? 0xb1091e80u : 0x2caeeca3u); // s522 add + r7 = r6 * r5 + r7; // s523 mad + r7 = r7 - r2; // s524 sub + r0 = r0 * r7; // s525 mul + r0 = r0 ^ r7; // s526 xor + r1 = __umulhi(r1, r4); // s527 mulhi + r0 = rotr_var(r0, r5); // s528 rotr + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r7, 16); // s529 shfl + r2 = __umulhi(r2, r3); // s530 mulhi + r1 = r1 | r4; // s531 or + r6 = r6 + r4 + ((((sel >> 13u) & 1u) != 0u) ? 0xbda312aeu : 0xbe9e1eb0u); // s532 add + r7 = r7 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x1ec16229u : 0xbe5d93a3u); // s533 add + r0 = r6 * r4 + r0; // s534 mad + r0 = r0 + r5 + ((((sel >> 23u) & 1u) != 0u) ? 0x500828bcu : 0x5e23583bu); // s535 add + r6 = r5 * r0 + r6; // s536 mad + r2 = r2 ^ r4; // s537 xor + r6 = r3 * r5 + r6; // s538 mad + r6 = r6 + r4 + ((((sel >> 3u) & 1u) != 0u) ? 0x852321dcu : 0x43c32138u); // s539 add + r2 = r2 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x44e6ae63u : 0xaff69493u); // s540 add + r3 = __umulhi(r3, r5); // s541 mulhi + r1 = r1 + r7 + ((((sel >> 5u) & 1u) != 0u) ? 0x909712feu : 0xc5de29efu); // s542 add + r1 = r3 * r2 + r1; // s543 mad + r1 = r1 + r3 + ((((sel >> 11u) & 1u) != 0u) ? 0xfb7b42b9u : 0x1e20e084u); // s544 add + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r5, 4); // s545 shfl + r6 = r6 + r1 + ((((sel >> 10u) & 1u) != 0u) ? 0x6e036dd4u : 0x9370db38u); // s546 add + r4 = r4 ^ r6; // s547 xor + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r3, 8); // s548 shfl + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r5, 16); // s549 shfl + r1 = rotr_var(r1, r7); // s550 rotr + r0 = r3 * r2 + r0; // s551 mad + r7 = __umulhi(r7, r4); // s552 mulhi + r0 = r0 + r4 + ((((sel >> 13u) & 1u) != 0u) ? 0xd3c9174du : 0xbf2488f6u); // s553 add + r1 = rotl_imm(r1, 1u); // s554 rotl + r7 = rotr_var(r7, r3); // s555 rotr + r7 = rotr_var(r7, r3); // s556 rotr + r6 = r2 * r0 + r6; // s557 mad + r6 = r6 ^ r1; // s558 xor + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s559 shfl + r5 = r5 ^ r3; // s560 xor + r5 = r5 * r1; // s561 mul + r3 = rotl_imm(r3, 31u); // s562 rotl + r6 = rotr_var(r6, r2); // s563 rotr + r7 = r7 | r2; // s564 or + r6 = rotr_var(r6, r0); // s565 rotr + r2 = r2 * r0; // s566 mul + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r5, 2); // s567 shfl + r3 = r3 * r0; // s568 mul + r4 = r4 + r2 + ((((sel >> 9u) & 1u) != 0u) ? 0xa3149efau : 0xd9160c83u); // s569 add + r4 = __umulhi(r4, r2); // s570 mulhi + r3 = r3 + r0 + ((((sel >> 10u) & 1u) != 0u) ? 0x9cab407bu : 0x3bdc971cu); // s571 add + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r2, 16); // s572 shfl + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r5, 4); // s573 shfl + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r3, 8); // s574 shfl + r0 = r0 ^ r7; // s575 xor + r0 = r0 + r5 + ((((sel >> 27u) & 1u) != 0u) ? 0x747b0838u : 0x17979608u); // s576 add + r0 = r0 ^ r4; // s577 xor + r6 = r6 - r1; // s578 sub + r4 = rotr_var(r4, r2); // s579 rotr + r2 = r2 ^ r3; // s580 xor + r6 = r7 * r2 + r6; // s581 mad + r5 = r5 + r2 + ((((sel >> 7u) & 1u) != 0u) ? 0x02246c0cu : 0x1c10ec5cu); // s582 add + r3 = __umulhi(r3, r6); // s583 mulhi + r2 = r2 ^ r5; // s584 xor + r6 = rotl_imm(r6, 24u); // s585 rotl + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r5, 8); // s586 shfl + r1 = r2 * r6 + r1; // s587 mad + r3 = r3 + r7 + ((((sel >> 21u) & 1u) != 0u) ? 0xbea44bd0u : 0x88758873u); // s588 add + r1 = rotl_imm(r1, 30u); // s589 rotl + r7 = r7 * r1; // s590 mul + r3 = r3 + r6 + ((((sel >> 10u) & 1u) != 0u) ? 0x8e0eb890u : 0xf436bb64u); // s591 add + r7 = r6 * r1 + r7; // s592 mad + r0 = r3 * r5 + r0; // s593 mad + r5 = rotr_var(r5, r4); // s594 rotr + r4 = r4 | r0; // s595 or + r6 = r3 * r0 + r6; // s596 mad + r2 = r2 + r1 + ((((sel >> 31u) & 1u) != 0u) ? 0x29b853b3u : 0xb465e47eu); // s597 add + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r7, 16); // s598 shfl + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r0, 4); // s599 shfl + r6 = r2 * r0 + r6; // s600 mad + r5 = __umulhi(r5, r0); // s601 mulhi + r6 = r6 * r7; // s602 mul + r4 = r4 | r7; // s603 or + r7 = r7 - r0; // s604 sub + r7 = rotr_var(r7, r4); // s605 rotr + r4 = r0 * r3 + r4; // s606 mad + r4 = __umulhi(r4, r3); // s607 mulhi + r0 = r0 + r1 + ((((sel >> 28u) & 1u) != 0u) ? 0xb7536963u : 0x22ce199du); // s608 add + r2 = r2 - r5; // s609 sub + r2 = r2 ^ r0; // s610 xor + r5 = r5 * r4; // s611 mul + r3 = rotl_imm(r3, 25u); // s612 rotl + r7 = rotl_imm(r7, 13u); // s613 rotl + r4 = r4 * r7; // s614 mul + r5 = r4 * r2 + r5; // s615 mad + r0 = r0 ^ r5; // s616 xor + r7 = r5 * r4 + r7; // s617 mad + r6 = r6 - r4; // s618 sub + r3 = r3 * r4; // s619 mul + r1 = rotl_imm(r1, 24u); // s620 rotl + r1 = r1 ^ r2; // s621 xor + r4 = r4 | r3; // s622 or + r7 = r7 * r2; // s623 mul + r6 = r6 + r1 + ((((sel >> 20u) & 1u) != 0u) ? 0xe37b1e20u : 0x2dbf6ed0u); // s624 add + r4 = r4 ^ r5; // s625 xor + r4 = r6 * r2 + r4; // s626 mad + r1 = r1 ^ r6; // s627 xor + r6 = r6 + r3 + ((((sel >> 12u) & 1u) != 0u) ? 0xf5a2a9f7u : 0x9dc2b9d0u); // s628 add + r7 = r7 - r5; // s629 sub + r1 = __umulhi(r1, r7); // s630 mulhi + r1 = rotr_var(r1, r3); // s631 rotr + r4 = r4 | r6; // s632 or + r2 = r2 + r5 + ((((sel >> 24u) & 1u) != 0u) ? 0x982bfc08u : 0x9c1fba1bu); // s633 add + r6 = r6 * r5; // s634 mul + r7 = r2 * r3 + r7; // s635 mad + r7 = __umulhi(r7, r4); // s636 mulhi + r5 = r5 ^ r0; // s637 xor + r0 = r0 * r1; // s638 mul + r4 = r4 ^ r6; // s639 xor + r6 = r6 - r4; // s640 sub + r6 = __umulhi(r6, r4); // s641 mulhi + r4 = r4 - r0; // s642 sub + r7 = r7 - r5; // s643 sub + r3 = r0 * r7 + r3; // s644 mad + r3 = r3 | r5; // s645 or + r0 = r0 - r4; // s646 sub + r7 = r7 | r5; // s647 or + r7 = rotl_imm(r7, 1u); // s648 rotl + r5 = r5 + r6 + ((((sel >> 31u) & 1u) != 0u) ? 0x6e5d517fu : 0x9f5e0d19u); // s649 add + r1 = r1 | r2; // s650 or + r3 = rotl_imm(r3, 29u); // s651 rotl + r2 = r2 + r4 + ((((sel >> 2u) & 1u) != 0u) ? 0x30faf9c6u : 0xb53f6e74u); // s652 add + r0 = rotl_imm(r0, 21u); // s653 rotl + r1 = r1 ^ r3; // s654 xor + r4 = r7 * r2 + r4; // s655 mad + r4 = r4 - r6; // s656 sub + r4 = r4 * r6; // s657 mul + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r1, 4); // s658 shfl + r7 = rotl_imm(r7, 31u); // s659 rotl + r4 = r4 ^ r6; // s660 xor + r1 = r1 - r3; // s661 sub + r3 = r3 * r6; // s662 mul + r5 = r5 * r3; // s663 mul + r7 = r7 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x8941d2e7u : 0x016e0094u); // s664 add + r1 = r1 ^ r2; // s665 xor + r1 = r1 - r0; // s666 sub + r4 = r4 ^ r7; // s667 xor + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r3, 1); // s668 shfl + r1 = rotr_var(r1, r4); // s669 rotr + r2 = r2 + r3 + ((((sel >> 14u) & 1u) != 0u) ? 0x15289435u : 0x9af12ca6u); // s670 add + r2 = rotr_var(r2, r4); // s671 rotr + r4 = r6 * r7 + r4; // s672 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r1, 4); // s673 shfl + r6 = r4 * r2 + r6; // s674 mad + r2 = r4 * r6 + r2; // s675 mad + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r1, 16); // s676 shfl + r1 = rotr_var(r1, r0); // s677 rotr + r0 = r0 - r2; // s678 sub + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r1, 16); // s679 shfl + r1 = r1 ^ r0; // s680 xor + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // s681 shfl + r0 = r0 ^ __shfl_xor_sync(0xffffffffu, r3, 8); // s682 shfl + r2 = r3 * r3 + r2; // s683 mad + r4 = r4 - r6; // s684 sub + r5 = r5 ^ r3; // s685 xor + r2 = r2 - r5; // s686 sub + r4 = r4 - r5; // s687 sub + r5 = r4 * r7 + r5; // s688 mad + r6 = r6 * r7; // s689 mul + r1 = r1 * r5; // s690 mul + r4 = rotr_var(r4, r3); // s691 rotr + r2 = r2 ^ r4; // s692 xor + r0 = rotl_imm(r0, 2u); // s693 rotl + r5 = r5 + r2 + ((((sel >> 23u) & 1u) != 0u) ? 0x49801084u : 0x4fc762c9u); // s694 add + r0 = r0 + r4 + ((((sel >> 14u) & 1u) != 0u) ? 0x5f403cd5u : 0x626c00f5u); // s695 add + r6 = rotl_imm(r6, 25u); // s696 rotl + r3 = r3 ^ r7; // s697 xor + r0 = r0 * r2; // s698 mul + r5 = rotr_var(r5, r1); // s699 rotr + r3 = r3 ^ r7; // s700 xor + r4 = r4 | r3; // s701 or + r7 = r7 * r3; // s702 mul + r4 = rotl_imm(r4, 24u); // s703 rotl + r5 = r5 + r4 + ((((sel >> 17u) & 1u) != 0u) ? 0xad5e1851u : 0xc08bb414u); // s704 add + r0 = r6 * r5 + r0; // s705 mad + r4 = __umulhi(r4, r1); // s706 mulhi + r4 = rotr_var(r4, r3); // s707 rotr + r3 = rotr_var(r3, r6); // s708 rotr + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r7, 16); // s709 shfl + r3 = r2 * r6 + r3; // s710 mad + r1 = r1 * r4; // s711 mul + r3 = r3 + r5 + ((((sel >> 13u) & 1u) != 0u) ? 0x407f7c4du : 0xdc55338fu); // s712 add + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r7, 2); // s713 shfl + r1 = r1 ^ r0; // s714 xor + r7 = r1 * r1 + r7; // s715 mad + r4 = r4 | r0; // s716 or + r6 = r6 * r4; // s717 mul + r0 = r0 - r5; // s718 sub + r1 = r1 ^ r4; // s719 xor + r4 = __umulhi(r4, r6); // s720 mulhi + r1 = r1 + r0 + ((((sel >> 13u) & 1u) != 0u) ? 0xc2093fcau : 0xb2ce569eu); // s721 add + r4 = __umulhi(r4, r2); // s722 mulhi + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r1, 16); // s723 shfl + r5 = r3 * r0 + r5; // s724 mad + r5 = __umulhi(r5, r0); // s725 mulhi + r2 = rotr_var(r2, r5); // s726 rotr + r5 = r5 + r0 + ((((sel >> 20u) & 1u) != 0u) ? 0x48cdf1c1u : 0x4e8aaad5u); // s727 add + r1 = r1 * r0; // s728 mul + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r0, 1); // s729 shfl + r4 = r4 * r6; // s730 mul + r4 = r4 - r6; // s731 sub + r4 = r4 ^ r2; // s732 xor + r5 = r5 * r6; // s733 mul + r7 = rotr_var(r7, r3); // s734 rotr + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r5, 1); // s735 shfl + r1 = __umulhi(r1, r0); // s736 mulhi + r2 = r2 * r6; // s737 mul + r5 = rotl_imm(r5, 27u); // s738 rotl + r2 = __umulhi(r2, r3); // s739 mulhi + r5 = r3 * r5 + r5; // s740 mad + r2 = rotl_imm(r2, 11u); // s741 rotl + r6 = r6 | r2; // s742 or + r2 = r2 ^ r3; // s743 xor + r3 = r3 * r1; // s744 mul + r4 = __umulhi(r4, r2); // s745 mulhi + r5 = r5 ^ r6; // s746 xor + r6 = r6 + r7 + ((((sel >> 11u) & 1u) != 0u) ? 0x0d6b844eu : 0x78fc162du); // s747 add + r1 = rotl_imm(r1, 27u); // s748 rotl + r4 = rotr_var(r4, r1); // s749 rotr + r5 = r5 ^ r7; // s750 xor + r4 = rotr_var(r4, r3); // s751 rotr + r5 = r5 * r2; // s752 mul + r1 = r6 * r7 + r1; // s753 mad + r0 = r0 ^ r1; // s754 xor + r7 = r7 - r1; // s755 sub + r0 = r0 + r4 + ((((sel >> 5u) & 1u) != 0u) ? 0xb74ac71eu : 0x68aab88bu); // s756 add + r7 = r7 + r5 + ((((sel >> 0u) & 1u) != 0u) ? 0xf81f5b66u : 0xba5c123au); // s757 add + r0 = r7 * r2 + r0; // s758 mad + r1 = r1 | r0; // s759 or + r4 = __umulhi(r4, r6); // s760 mulhi + r0 = __umulhi(r0, r7); // s761 mulhi + r3 = rotr_var(r3, r4); // s762 rotr + r3 = rotl_imm(r3, 30u); // s763 rotl + r6 = r6 * r2; // s764 mul + r6 = r6 ^ r4; // s765 xor + r3 = r3 + r4 + ((((sel >> 0u) & 1u) != 0u) ? 0x96dabea6u : 0x6eb1d82au); // s766 add + r0 = r0 ^ __shfl_xor_sync(0xffffffffu, r2, 1); // s767 shfl + r3 = rotl_imm(r3, 8u); // s768 rotl + r7 = r7 * r4; // s769 mul + r6 = r1 * r2 + r6; // s770 mad + r2 = r2 ^ r7; // s771 xor + r6 = r6 * r0; // s772 mul + r2 = r2 - r1; // s773 sub + r1 = r0 * r1 + r1; // s774 mad + r5 = __umulhi(r5, r7); // s775 mulhi + r0 = rotr_var(r0, r4); // s776 rotr + r6 = r6 ^ r0; // s777 xor + r4 = __umulhi(r4, r7); // s778 mulhi + r1 = r3 * r0 + r1; // s779 mad + r6 = r6 + r4 + ((((sel >> 2u) & 1u) != 0u) ? 0x903f3f77u : 0x11d7b79au); // s780 add + r4 = r4 ^ r7; // s781 xor + r1 = r1 + r2 + ((((sel >> 14u) & 1u) != 0u) ? 0x2ca81d8du : 0x1791eaddu); // s782 add + r2 = rotr_var(r2, r1); // s783 rotr + r4 = r4 * r6; // s784 mul + r1 = r1 ^ r6; // s785 xor + r4 = r4 - r0; // s786 sub + r3 = r3 ^ r4; // s787 xor + r4 = r4 * r1; // s788 mul + r4 = r6 * r7 + r4; // s789 mad + r5 = r5 - r0; // s790 sub + r2 = r2 * r0; // s791 mul + r7 = rotl_imm(r7, 12u); // s792 rotl + r2 = r7 * r3 + r2; // s793 mad + r1 = r4 * r4 + r1; // s794 mad + r6 = r6 + r4 + ((((sel >> 15u) & 1u) != 0u) ? 0xf66fad29u : 0xc08797bbu); // s795 add + r1 = r1 - r4; // s796 sub + r5 = r5 * r2; // s797 mul + r5 = r5 ^ r2; // s798 xor + r0 = r0 * r1; // s799 mul + r6 = r6 + r4 + ((((sel >> 13u) & 1u) != 0u) ? 0x2d82a681u : 0x6d4a6371u); // s800 add + r1 = r6 * r1 + r1; // s801 mad + r0 = r0 - r2; // s802 sub + r6 = r6 ^ r2; // s803 xor + r7 = rotl_imm(r7, 24u); // s804 rotl + r6 = r6 ^ r7; // s805 xor + r7 = r7 | r0; // s806 or + r0 = rotl_imm(r0, 5u); // s807 rotl + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r2, 2); // s808 shfl + r4 = r1 * r5 + r4; // s809 mad + r0 = r0 + r2 + ((((sel >> 14u) & 1u) != 0u) ? 0x63e62197u : 0x0092eb62u); // s810 add + r5 = r5 - r3; // s811 sub + r2 = r1 * r5 + r2; // s812 mad + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r0, 16); // s813 shfl + r7 = r5 * r1 + r7; // s814 mad + r0 = __umulhi(r0, r7); // s815 mulhi + r2 = r2 | r1; // s816 or + r7 = __umulhi(r7, r3); // s817 mulhi + r2 = r2 ^ r4; // s818 xor + r4 = r4 + r3 + ((((sel >> 0u) & 1u) != 0u) ? 0x27d94f57u : 0xbb69174fu); // s819 add + r5 = r5 + r3 + ((((sel >> 1u) & 1u) != 0u) ? 0x82285691u : 0xda6759f2u); // s820 add + r1 = r1 + r3 + ((((sel >> 31u) & 1u) != 0u) ? 0xe50565d8u : 0x9ad4b47fu); // s821 add + r5 = rotl_imm(r5, 6u); // s822 rotl + r3 = r3 - r0; // s823 sub + r6 = rotl_imm(r6, 12u); // s824 rotl + r4 = r4 | r5; // s825 or + r3 = r3 ^ r2; // s826 xor + r4 = r4 + r0 + ((((sel >> 26u) & 1u) != 0u) ? 0xffcab83au : 0xca1e80fbu); // s827 add + r3 = r3 | r7; // s828 or + r1 = r5 * r7 + r1; // s829 mad + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r0, 16); // s830 shfl + r1 = r1 - r0; // s831 sub + r0 = rotr_var(r0, r2); // s832 rotr + r1 = __umulhi(r1, r0); // s833 mulhi + r6 = __umulhi(r6, r4); // s834 mulhi + r6 = rotl_imm(r6, 2u); // s835 rotl + r4 = r4 | r6; // s836 or + r6 = rotl_imm(r6, 23u); // s837 rotl + r4 = r7 * r4 + r4; // s838 mad + r0 = r0 | r1; // s839 or + r5 = __umulhi(r5, r3); // s840 mulhi + r7 = r4 * r6 + r7; // s841 mad + r1 = r1 + r4 + ((((sel >> 21u) & 1u) != 0u) ? 0x1bc9f95du : 0xcfb90e90u); // s842 add + r1 = r1 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0xf9bd620fu : 0x0b4758b6u); // s843 add + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r5, 16); // s844 shfl + r3 = r1 * r7 + r3; // s845 mad + r5 = r5 * r2; // s846 mul + r0 = rotl_imm(r0, 21u); // s847 rotl + r7 = r7 ^ r1; // s848 xor + r3 = r3 + r4 + ((((sel >> 18u) & 1u) != 0u) ? 0x697a4946u : 0x41fdc15au); // s849 add + r0 = r0 ^ __shfl_xor_sync(0xffffffffu, r5, 4); // s850 shfl + r1 = rotr_var(r1, r5); // s851 rotr + r5 = r5 | r6; // s852 or + r6 = r6 - r2; // s853 sub + r2 = r2 ^ r6; // s854 xor + r4 = r4 - r6; // s855 sub + r6 = r4 * r6 + r6; // s856 mad + r4 = r4 * r0; // s857 mul + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r1, 4); // s858 shfl + r3 = r3 * r4; // s859 mul + r3 = r1 * r7 + r3; // s860 mad + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r2, 2); // s861 shfl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r4, 8); // s862 shfl + r0 = r2 * r2 + r0; // s863 mad + r6 = r6 ^ r0; // s864 xor + r6 = r6 + r2 + ((((sel >> 2u) & 1u) != 0u) ? 0x7fedd7f3u : 0x90656f74u); // s865 add + r3 = r3 ^ r2; // s866 xor + r1 = r1 | r4; // s867 or + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r7, 2); // s868 shfl + r1 = __umulhi(r1, r0); // s869 mulhi + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r1, 4); // s870 shfl + r0 = r0 - r3; // s871 sub + r6 = r6 + r1 + ((((sel >> 11u) & 1u) != 0u) ? 0xbe1b480au : 0xa5c0b461u); // s872 add + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r6, 1); // s873 shfl + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r0, 1); // s874 shfl + r2 = __umulhi(r2, r4); // s875 mulhi + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r7, 4); // s876 shfl + r5 = rotl_imm(r5, 14u); // s877 rotl + r2 = r2 ^ r7; // s878 xor + r7 = r7 ^ r0; // s879 xor + r0 = r0 * r2; // s880 mul + r4 = r4 * r2; // s881 mul + r7 = r7 * r6; // s882 mul + r4 = __umulhi(r4, r5); // s883 mulhi + r0 = r0 - r4; // s884 sub + r0 = r0 ^ r5; // s885 xor + r6 = r6 * r5; // s886 mul + r1 = r1 + r5 + ((((sel >> 14u) & 1u) != 0u) ? 0x7007f98fu : 0xe806fcecu); // s887 add + r3 = r3 * r1; // s888 mul + r5 = r5 ^ r3; // s889 xor + r6 = r6 | r2; // s890 or + r1 = r1 * r2; // s891 mul + r5 = r5 + r7 + ((((sel >> 3u) & 1u) != 0u) ? 0xf3c87e02u : 0x89a8551eu); // s892 add + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 16); // s893 shfl + r1 = r1 + r3 + ((((sel >> 13u) & 1u) != 0u) ? 0xc315f5deu : 0xba1369dbu); // s894 add + r5 = r0 * r3 + r5; // s895 mad + r5 = rotr_var(r5, r2); // s896 rotr + r1 = r1 ^ r0; // s897 xor + r5 = r5 ^ r1; // s898 xor + r5 = rotr_var(r5, r1); // s899 rotr + r3 = r6 * r6 + r3; // s900 mad + r0 = rotl_imm(r0, 8u); // s901 rotl + r1 = r1 | r0; // s902 or + r1 = r1 + r2 + ((((sel >> 3u) & 1u) != 0u) ? 0x1c355a71u : 0x260e6848u); // s903 add + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r2, 16); // s904 shfl + r1 = __umulhi(r1, r3); // s905 mulhi + r1 = rotr_var(r1, r4); // s906 rotr + r6 = r6 + r0 + ((((sel >> 8u) & 1u) != 0u) ? 0x0c74a1a8u : 0xa74fd2b1u); // s907 add + r6 = rotr_var(r6, r2); // s908 rotr + r4 = rotl_imm(r4, 12u); // s909 rotl + r5 = r5 + r3 + ((((sel >> 29u) & 1u) != 0u) ? 0xa49b5d73u : 0xe5fb043eu); // s910 add + r3 = r3 ^ r0; // s911 xor + r3 = rotr_var(r3, r4); // s912 rotr + r6 = rotr_var(r6, r0); // s913 rotr + r2 = r2 ^ r5; // s914 xor + r0 = r0 * r7; // s915 mul + r3 = r3 ^ r0; // s916 xor + r5 = r1 * r7 + r5; // s917 mad + r3 = r3 + r4 + ((((sel >> 2u) & 1u) != 0u) ? 0xeb76e56cu : 0x264cb47bu); // s918 add + r3 = __umulhi(r3, r4); // s919 mulhi + r5 = r5 + r6 + ((((sel >> 9u) & 1u) != 0u) ? 0x2aab9631u : 0x418baa72u); // s920 add + r5 = __umulhi(r5, r1); // s921 mulhi + r7 = r7 - r3; // s922 sub + r6 = r6 + r1 + ((((sel >> 2u) & 1u) != 0u) ? 0x98e6b26du : 0x3696a894u); // s923 add + r6 = r3 * r1 + r6; // s924 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s925 shfl + r6 = r6 ^ r1; // s926 xor + r4 = r4 ^ r3; // s927 xor + r0 = r0 + r4 + ((((sel >> 7u) & 1u) != 0u) ? 0x142778eeu : 0x0468c062u); // s928 add + r7 = r7 + r3 + ((((sel >> 29u) & 1u) != 0u) ? 0x4eae212du : 0x0af82291u); // s929 add + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r7, 16); // s930 shfl + r7 = r7 + r2 + ((((sel >> 20u) & 1u) != 0u) ? 0x8d2a8b36u : 0x17de5e29u); // s931 add + r5 = r5 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0xe2d2d7d5u : 0x686794a8u); // s932 add + r0 = __umulhi(r0, r3); // s933 mulhi + r4 = r4 + r0 + ((((sel >> 10u) & 1u) != 0u) ? 0xe3c3c6f9u : 0x66278068u); // s934 add + r6 = rotl_imm(r6, 22u); // s935 rotl + r0 = r0 | r2; // s936 or + r4 = r4 * r3; // s937 mul + r3 = r3 | r6; // s938 or + r7 = rotl_imm(r7, 28u); // s939 rotl + r0 = r0 + r6 + ((((sel >> 20u) & 1u) != 0u) ? 0xc2296063u : 0xc2d02ca6u); // s940 add + r1 = r1 + r5 + ((((sel >> 14u) & 1u) != 0u) ? 0xef1ca415u : 0x0b3c00e0u); // s941 add + r2 = r2 - r6; // s942 sub + r6 = r6 | r3; // s943 or + r0 = rotl_imm(r0, 2u); // s944 rotl + r2 = r2 * r1; // s945 mul + r0 = r0 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0x06a1321au : 0x11224846u); // s946 add + r3 = r3 * r6; // s947 mul + r5 = r5 - r2; // s948 sub + r5 = r5 + r4 + ((((sel >> 5u) & 1u) != 0u) ? 0x5d3e225cu : 0x461c43d4u); // s949 add + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r1, 16); // s950 shfl + r7 = r0 * r0 + r7; // s951 mad + r6 = rotr_var(r6, r4); // s952 rotr + r1 = r1 + r0 + ((((sel >> 30u) & 1u) != 0u) ? 0xbb84f628u : 0xd5eed39fu); // s953 add + r4 = rotl_imm(r4, 31u); // s954 rotl + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r2, 16); // s955 shfl + r2 = r2 - r6; // s956 sub + r4 = r4 ^ r2; // s957 xor + r0 = r0 ^ r2; // s958 xor + r1 = r1 + r0 + ((((sel >> 28u) & 1u) != 0u) ? 0x374c0426u : 0x519d72f7u); // s959 add + r5 = r5 * r4; // s960 mul + r5 = r5 - r7; // s961 sub + r2 = r2 ^ r6; // s962 xor + r4 = r4 ^ r1; // s963 xor + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 16); // s964 shfl + r7 = __umulhi(r7, r3); // s965 mulhi + r4 = rotl_imm(r4, 12u); // s966 rotl + r4 = r4 + r6 + ((((sel >> 26u) & 1u) != 0u) ? 0x03b88592u : 0x151dae18u); // s967 add + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r3, 4); // s968 shfl + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r6, 8); // s969 shfl + r2 = r2 ^ r7; // s970 xor + r5 = r3 * r4 + r5; // s971 mad + r0 = r0 ^ r3; // s972 xor + r2 = r2 ^ r5; // s973 xor + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r0, 4); // s974 shfl + r5 = r1 * r4 + r5; // s975 mad + r2 = rotl_imm(r2, 19u); // s976 rotl + r1 = r1 - r4; // s977 sub + r5 = rotr_var(r5, r4); // s978 rotr + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r1, 16); // s979 shfl + r6 = r6 + r7 + ((((sel >> 28u) & 1u) != 0u) ? 0x1fdee45eu : 0x16220e61u); // s980 add + r4 = rotr_var(r4, r6); // s981 rotr + r6 = __umulhi(r6, r3); // s982 mulhi + r5 = rotl_imm(r5, 17u); // s983 rotl + r2 = r7 * r1 + r2; // s984 mad + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r1, 8); // s985 shfl + r3 = r3 ^ r1; // s986 xor + r4 = r4 + r0 + ((((sel >> 27u) & 1u) != 0u) ? 0x44adc457u : 0x6cd6b697u); // s987 add + r1 = r1 * r5; // s988 mul + r4 = r4 + r2 + ((((sel >> 2u) & 1u) != 0u) ? 0x0a06a223u : 0x1103d2d2u); // s989 add + r4 = r4 * r1; // s990 mul + r4 = r5 * r1 + r4; // s991 mad + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r6, 1); // s992 shfl + r1 = r1 - r3; // s993 sub + r4 = r7 * r5 + r4; // s994 mad + r1 = __umulhi(r1, r2); // s995 mulhi + r2 = r1 * r0 + r2; // s996 mad + r3 = rotl_imm(r3, 31u); // s997 rotl + r4 = r4 - r3; // s998 sub + r5 = rotr_var(r5, r3); // s999 rotr + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r0, 4); // s1000 shfl + r2 = r2 - r5; // s1001 sub + r3 = r4 * r4 + r3; // s1002 mad + r7 = r5 * r1 + r7; // s1003 mad + r7 = r7 + r4 + ((((sel >> 29u) & 1u) != 0u) ? 0x0044887fu : 0xa9c9d8a9u); // s1004 add + r4 = __umulhi(r4, r0); // s1005 mulhi + r4 = rotl_imm(r4, 21u); // s1006 rotl + r3 = r3 * r1; // s1007 mul + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r5, 2); // s1008 shfl + r0 = __umulhi(r0, r6); // s1009 mulhi + r0 = r0 ^ r3; // s1010 xor + r5 = r5 | r4; // s1011 or + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r5, 4); // s1012 shfl + r2 = r2 + r4 + ((((sel >> 4u) & 1u) != 0u) ? 0x6b70e2c7u : 0xfa1574e3u); // s1013 add + r5 = rotr_var(r5, r7); // s1014 rotr + r0 = rotr_var(r0, r7); // s1015 rotr + r5 = r5 - r7; // s1016 sub + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r1, 16); // s1017 shfl + r6 = __umulhi(r6, r7); // s1018 mulhi + r0 = rotr_var(r0, r1); // s1019 rotr + r2 = r2 ^ r0; // s1020 xor + r4 = r5 * r1 + r4; // s1021 mad + r6 = r6 | r2; // s1022 or + r3 = r3 ^ r0; // s1023 xor + } + } + uint32_t lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint32_t hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((uint64_t)hi << 32) | (uint64_t)lo; +} + +cudaError_t igneum_launch_hash_bound(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, + IgneumInitWords iw, uint32_t nonces, uint32_t blockWarps) { + if (blockWarps == 0u || blockWarps > 32u) return cudaErrorInvalidValue; + uint32_t block = 32u * blockWarps; + if (nonces == 0u || (nonces % block) != 0u) return cudaErrorInvalidValue; + igneum_hash_bound<<>>(ds, out, baseNonce, mask, iw); + return cudaGetLastError(); +} + +cudaError_t igneum_hash_bound_info(int* numRegs, int* blocksPerSM, uint32_t blockWarps) { + cudaFuncAttributes attr; + cudaError_t e = cudaFuncGetAttributes(&attr, igneum_hash_bound); + if (e != cudaSuccess) return e; + *numRegs = attr.numRegs; + return cudaOccupancyMaxActiveBlocksPerMultiprocessor(blocksPerSM, igneum_hash_bound, (int)(32u * blockWarps), 0); +} diff --git a/proto-cuda/packs-ca3-shadow/sh1024x3/memhard.h b/proto-cuda/packs-ca3-shadow/sh1024x3/memhard.h new file mode 100644 index 000000000..f7f34c732 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh1024x3/memhard.h @@ -0,0 +1,109 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Memory-hard dataset core, the same text that the Mac's Metal kernels and CPU verifier were checked against. +// Included by kernel.cu (device), host.cu (host reference) and proto-opencl/host.c (C99 host reference). +// See proto-metal/MEMHARD.md for the construction. kernel.cl carries the same text in OpenCL C. +#pragma once +#ifdef __cplusplus +#include +#else +#include +#endif +#if defined(__CUDACC__) +#define IGNEUM_HD __host__ __device__ __forceinline__ +#elif defined(_MSC_VER) && !defined(__cplusplus) +#define IGNEUM_HD static __inline +#else +#define IGNEUM_HD static inline +#endif +// Memory-hard dataset core (MEMHARD.md). Cache: 2^26 words in 2^16 segments of 64 chained ChaCha12 lines. +// Item: 8 rounds of 8 x seed-parameterised mixer + one 64-byte cache read, then 8 x final mixer (class v3, mixer multiplier 8, +// docs/plans/mixer-x4.md: the round key of application j of round r is 0x9E3779B9 * (r * m + j + 1)). All parameters are literals. +#define MH_CACHE_LINE_MASK 0x003fffffu +#define MH_SEGMENT_LINES 64u +#define MH_QR(a, b, c, d, r1, r2, r3, r4) { a += b; d ^= a; d = mh_rotl(d, r1); c += d; b ^= c; b = mh_rotl(b, r2); a += b; d ^= a; d = mh_rotl(d, r3); c += d; b ^= c; b = mh_rotl(b, r4); } +IGNEUM_HD uint32_t mh_rotl(uint32_t x, uint32_t n) { return (x << n) | (x >> (32u - n)); } // n in 1..31 at every call site + +// y = ChaCha12 core(x) + x +IGNEUM_HD void mh_chacha_block(const uint32_t* x, uint32_t* y) { + for (uint32_t i = 0u; i < 16u; ++i) y[i] = x[i]; + for (uint32_t r = 0u; r < 6u; ++r) { + MH_QR(y[0], y[4], y[8], y[12], 16u, 12u, 8u, 7u) MH_QR(y[1], y[5], y[9], y[13], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[6], y[10], y[14], 16u, 12u, 8u, 7u) MH_QR(y[3], y[7], y[11], y[15], 16u, 12u, 8u, 7u) + MH_QR(y[0], y[5], y[10], y[15], 16u, 12u, 8u, 7u) MH_QR(y[1], y[6], y[11], y[12], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[7], y[8], y[13], 16u, 12u, 8u, 7u) MH_QR(y[3], y[4], y[9], y[14], 16u, 12u, 8u, 7u) + } + for (uint32_t i = 0u; i < 16u; ++i) y[i] += x[i]; +} + +// One cache segment: 64 chained lines written at cache[seg * 1024]. in_j = prev ^ (sigma || K || seg || j || tag), prev_0 = 0. +IGNEUM_HD void mh_cache_segment(uint32_t* cache, uint32_t seg) { + uint32_t prev[16]; uint32_t x[16]; uint32_t y[16]; + for (uint32_t i = 0u; i < 16u; ++i) prev[i] = 0u; + for (uint32_t j = 0u; j < MH_SEGMENT_LINES; ++j) { + x[0] = 0x61707865u ^ prev[0]; x[1] = 0x3320646eu ^ prev[1]; x[2] = 0x79622d32u ^ prev[2]; x[3] = 0x6b206574u ^ prev[3]; + x[4] = 0x3067619fu ^ prev[4]; + x[5] = 0x3c269176u ^ prev[5]; + x[6] = 0x84a03b03u ^ prev[6]; + x[7] = 0xf8c63294u ^ prev[7]; + x[8] = 0xff977c5bu ^ prev[8]; + x[9] = 0xe60def3eu ^ prev[9]; + x[10] = 0x63630141u ^ prev[10]; + x[11] = 0xb8fbcb58u ^ prev[11]; + x[12] = seg ^ prev[12]; x[13] = j ^ prev[13]; x[14] = 0x49676e65u ^ prev[14]; x[15] = 0x756d4d48u ^ prev[15]; + mh_chacha_block(x, y); + uint32_t* line = cache + ((seg * MH_SEGMENT_LINES + j) * 16u); + for (uint32_t i = 0u; i < 16u; ++i) { line[i] = y[i]; prev[i] = y[i]; } + } +} + +// M_r: per word (s ^ (RC + rk)) * MUL, then a column round and a diagonal round with the seed-drawn rotations. +IGNEUM_HD void mh_mixer(uint32_t* s, uint32_t rk) { + s[0] = (s[0] ^ (0xbab68293u + rk)) * 0x42146205u; + s[1] = (s[1] ^ (0xcc162340u + rk)) * 0x52cbe0fbu; + s[2] = (s[2] ^ (0x6ce151ccu + rk)) * 0x7ecf4a03u; + s[3] = (s[3] ^ (0xe62b8997u + rk)) * 0x6728907fu; + s[4] = (s[4] ^ (0xc9c80297u + rk)) * 0xd81d9751u; + s[5] = (s[5] ^ (0xf74a1654u + rk)) * 0x132952c3u; + s[6] = (s[6] ^ (0x3d704af5u + rk)) * 0xf60de277u; + s[7] = (s[7] ^ (0x3cf522b7u + rk)) * 0x05358035u; + s[8] = (s[8] ^ (0x2b9cac04u + rk)) * 0xbaf6499du; + s[9] = (s[9] ^ (0xa880ac10u + rk)) * 0xe4db9667u; + s[10] = (s[10] ^ (0x13e5dd1du + rk)) * 0x3e98f45du; + s[11] = (s[11] ^ (0x6fc3e233u + rk)) * 0xd0004eddu; + s[12] = (s[12] ^ (0x2d83eeacu + rk)) * 0x2691630du; + s[13] = (s[13] ^ (0x9006e8bfu + rk)) * 0x9beb3bcfu; + s[14] = (s[14] ^ (0x2c4b5362u + rk)) * 0xab310379u; + s[15] = (s[15] ^ (0x31b49ee2u + rk)) * 0x99cfb423u; + MH_QR(s[0], s[4], s[8], s[12], 20u, 20u, 19u, 4u) MH_QR(s[1], s[5], s[9], s[13], 20u, 20u, 19u, 4u) + MH_QR(s[2], s[6], s[10], s[14], 20u, 20u, 19u, 4u) MH_QR(s[3], s[7], s[11], s[15], 20u, 20u, 19u, 4u) + MH_QR(s[0], s[5], s[10], s[15], 26u, 3u, 3u, 27u) MH_QR(s[1], s[6], s[11], s[12], 26u, 3u, 3u, 27u) + MH_QR(s[2], s[7], s[8], s[13], 26u, 3u, 3u, 27u) MH_QR(s[3], s[4], s[9], s[14], 26u, 3u, 3u, 27u) +} + +// Item t: 16 words. s = (K, t * MUL[i] + RC[i]); 8 rounds of 8 x mixer + cache line s[0] & mask; 8 x final mixer. +IGNEUM_HD void mh_item(const uint32_t* cache, uint32_t t, uint32_t* s) { + s[0] = 0x3067619fu; + s[1] = 0x3c269176u; + s[2] = 0x84a03b03u; + s[3] = 0xf8c63294u; + s[4] = 0xff977c5bu; + s[5] = 0xe60def3eu; + s[6] = 0x63630141u; + s[7] = 0xb8fbcb58u; + s[8] = t * 0x42146205u + 0xbab68293u; + s[9] = t * 0x52cbe0fbu + 0xcc162340u; + s[10] = t * 0x7ecf4a03u + 0x6ce151ccu; + s[11] = t * 0x6728907fu + 0xe62b8997u; + s[12] = t * 0xd81d9751u + 0xc9c80297u; + s[13] = t * 0x132952c3u + 0xf74a1654u; + s[14] = t * 0xf60de277u + 0x3d704af5u; + s[15] = t * 0x05358035u + 0x3cf522b7u; + for (uint32_t r = 0u; r < 8u; ++r) { + for (uint32_t j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (r * 8u + j + 1u)); + const uint32_t* line = cache + ((s[0] & MH_CACHE_LINE_MASK) * 16u); + for (uint32_t i = 0u; i < 16u; ++i) s[i] ^= line[i]; + } + for (uint32_t j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (64u + j + 1u)); +} +// dataset[w] without the dataset: derive item w >> 4 and take word w & 15. +IGNEUM_HD uint32_t mh_word(const uint32_t* cache, uint32_t w) { uint32_t s[16]; mh_item(cache, w >> 4u, s); return s[w & 15u]; } diff --git a/proto-cuda/packs-ca3-shadow/sh1024x3/memhard.metal b/proto-cuda/packs-ca3-shadow/sh1024x3/memhard.metal new file mode 100644 index 000000000..01b263d6d --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh1024x3/memhard.metal @@ -0,0 +1,107 @@ +#include +using namespace metal; +// Memory-hard dataset core (MEMHARD.md). Cache: 2^26 words in 2^16 segments of 64 chained ChaCha12 lines. +// Item: 8 rounds of 8 x seed-parameterised mixer + one 64-byte cache read, then 8 x final mixer (class v3, mixer multiplier 8, +// docs/plans/mixer-x4.md: the round key of application j of round r is 0x9E3779B9 * (r * m + j + 1)). All parameters are literals. +#define MH_CACHE_LINE_MASK 0x003fffffu +#define MH_SEGMENT_LINES 64u +#define MH_QR(a, b, c, d, r1, r2, r3, r4) { a += b; d ^= a; d = mh_rotl(d, r1); c += d; b ^= c; b = mh_rotl(b, r2); a += b; d ^= a; d = mh_rotl(d, r3); c += d; b ^= c; b = mh_rotl(b, r4); } +inline uint mh_rotl(uint x, uint n) { return (x << n) | (x >> (32u - n)); } // n in 1..31 at every call site + +// y = ChaCha12 core(x) + x +inline void mh_chacha_block(const thread uint* x, thread uint* y) { + for (uint i = 0u; i < 16u; ++i) y[i] = x[i]; + for (uint r = 0u; r < 6u; ++r) { + MH_QR(y[0], y[4], y[8], y[12], 16u, 12u, 8u, 7u) MH_QR(y[1], y[5], y[9], y[13], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[6], y[10], y[14], 16u, 12u, 8u, 7u) MH_QR(y[3], y[7], y[11], y[15], 16u, 12u, 8u, 7u) + MH_QR(y[0], y[5], y[10], y[15], 16u, 12u, 8u, 7u) MH_QR(y[1], y[6], y[11], y[12], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[7], y[8], y[13], 16u, 12u, 8u, 7u) MH_QR(y[3], y[4], y[9], y[14], 16u, 12u, 8u, 7u) + } + for (uint i = 0u; i < 16u; ++i) y[i] += x[i]; +} + +// One cache segment: 64 chained lines written at cache[seg * 1024]. in_j = prev ^ (sigma || K || seg || j || tag), prev_0 = 0. +inline void mh_cache_segment(device uint* cache, uint seg) { + uint prev[16]; uint x[16]; uint y[16]; + for (uint i = 0u; i < 16u; ++i) prev[i] = 0u; + for (uint j = 0u; j < MH_SEGMENT_LINES; ++j) { + x[0] = 0x61707865u ^ prev[0]; x[1] = 0x3320646eu ^ prev[1]; x[2] = 0x79622d32u ^ prev[2]; x[3] = 0x6b206574u ^ prev[3]; + x[4] = 0x3067619fu ^ prev[4]; + x[5] = 0x3c269176u ^ prev[5]; + x[6] = 0x84a03b03u ^ prev[6]; + x[7] = 0xf8c63294u ^ prev[7]; + x[8] = 0xff977c5bu ^ prev[8]; + x[9] = 0xe60def3eu ^ prev[9]; + x[10] = 0x63630141u ^ prev[10]; + x[11] = 0xb8fbcb58u ^ prev[11]; + x[12] = seg ^ prev[12]; x[13] = j ^ prev[13]; x[14] = 0x49676e65u ^ prev[14]; x[15] = 0x756d4d48u ^ prev[15]; + mh_chacha_block(x, y); + device uint* line = cache + ((seg * MH_SEGMENT_LINES + j) * 16u); + for (uint i = 0u; i < 16u; ++i) { line[i] = y[i]; prev[i] = y[i]; } + } +} + +// M_r: per word (s ^ (RC + rk)) * MUL, then a column round and a diagonal round with the seed-drawn rotations. +inline void mh_mixer(thread uint* s, uint rk) { + s[0] = (s[0] ^ (0xbab68293u + rk)) * 0x42146205u; + s[1] = (s[1] ^ (0xcc162340u + rk)) * 0x52cbe0fbu; + s[2] = (s[2] ^ (0x6ce151ccu + rk)) * 0x7ecf4a03u; + s[3] = (s[3] ^ (0xe62b8997u + rk)) * 0x6728907fu; + s[4] = (s[4] ^ (0xc9c80297u + rk)) * 0xd81d9751u; + s[5] = (s[5] ^ (0xf74a1654u + rk)) * 0x132952c3u; + s[6] = (s[6] ^ (0x3d704af5u + rk)) * 0xf60de277u; + s[7] = (s[7] ^ (0x3cf522b7u + rk)) * 0x05358035u; + s[8] = (s[8] ^ (0x2b9cac04u + rk)) * 0xbaf6499du; + s[9] = (s[9] ^ (0xa880ac10u + rk)) * 0xe4db9667u; + s[10] = (s[10] ^ (0x13e5dd1du + rk)) * 0x3e98f45du; + s[11] = (s[11] ^ (0x6fc3e233u + rk)) * 0xd0004eddu; + s[12] = (s[12] ^ (0x2d83eeacu + rk)) * 0x2691630du; + s[13] = (s[13] ^ (0x9006e8bfu + rk)) * 0x9beb3bcfu; + s[14] = (s[14] ^ (0x2c4b5362u + rk)) * 0xab310379u; + s[15] = (s[15] ^ (0x31b49ee2u + rk)) * 0x99cfb423u; + MH_QR(s[0], s[4], s[8], s[12], 20u, 20u, 19u, 4u) MH_QR(s[1], s[5], s[9], s[13], 20u, 20u, 19u, 4u) + MH_QR(s[2], s[6], s[10], s[14], 20u, 20u, 19u, 4u) MH_QR(s[3], s[7], s[11], s[15], 20u, 20u, 19u, 4u) + MH_QR(s[0], s[5], s[10], s[15], 26u, 3u, 3u, 27u) MH_QR(s[1], s[6], s[11], s[12], 26u, 3u, 3u, 27u) + MH_QR(s[2], s[7], s[8], s[13], 26u, 3u, 3u, 27u) MH_QR(s[3], s[4], s[9], s[14], 26u, 3u, 3u, 27u) +} + +// Item t: 16 words. s = (K, t * MUL[i] + RC[i]); 8 rounds of 8 x mixer + cache line s[0] & mask; 8 x final mixer. +inline void mh_item(device const uint* cache, uint t, thread uint* s) { + s[0] = 0x3067619fu; + s[1] = 0x3c269176u; + s[2] = 0x84a03b03u; + s[3] = 0xf8c63294u; + s[4] = 0xff977c5bu; + s[5] = 0xe60def3eu; + s[6] = 0x63630141u; + s[7] = 0xb8fbcb58u; + s[8] = t * 0x42146205u + 0xbab68293u; + s[9] = t * 0x52cbe0fbu + 0xcc162340u; + s[10] = t * 0x7ecf4a03u + 0x6ce151ccu; + s[11] = t * 0x6728907fu + 0xe62b8997u; + s[12] = t * 0xd81d9751u + 0xc9c80297u; + s[13] = t * 0x132952c3u + 0xf74a1654u; + s[14] = t * 0xf60de277u + 0x3d704af5u; + s[15] = t * 0x05358035u + 0x3cf522b7u; + for (uint r = 0u; r < 8u; ++r) { + for (uint j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (r * 8u + j + 1u)); + device const uint* line = cache + ((s[0] & MH_CACHE_LINE_MASK) * 16u); + for (uint i = 0u; i < 16u; ++i) s[i] ^= line[i]; + } + for (uint j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (64u + j + 1u)); +} +// dataset[w] without the dataset: derive item w >> 4 and take word w & 15. +inline uint mh_word(device const uint* cache, uint w) { uint s[16]; mh_item(cache, w >> 4u, s); return s[w & 15u]; } + +// One thread per segment (2^16 threads). +kernel void igneum_cache_fill(device uint* cache [[buffer(0)]], uint gid [[thread_position_in_grid]]) { + mh_cache_segment(cache, gid); +} +// One thread per 64-byte item (dataset words / 16 threads). +kernel void igneum_build(device const uint* cache [[buffer(0)]], device uint* dataset [[buffer(1)]], + uint gid [[thread_position_in_grid]]) { + uint s[16]; + mh_item(cache, gid, s); + device uint* d = dataset + gid * 16u; + for (uint i = 0u; i < 16u; ++i) d[i] = s[i]; +} diff --git a/proto-cuda/packs-ca3-shadow/sh1024x3/program.h b/proto-cuda/packs-ca3-shadow/sh1024x3/program.h new file mode 100644 index 000000000..6722cd82d --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh1024x3/program.h @@ -0,0 +1,70 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Program metadata for host.cu plus the launch wrappers defined in kernel.cu. +// Also included by proto-opencl/host.c (C99), which defines IGNEUM_NO_CUDA first and reads only the macros. +#pragma once +#ifdef __cplusplus +#include +#else +#include +#endif +#ifndef IGNEUM_NO_CUDA +#include +#endif + +#define IGNEUM_SEED_STRING "igneum-genesis" +#define IGNEUM_SEED_BYTES_HEX "69676e65756d2d67656e65736973" +#define IGNEUM_GENERATOR 2 +#define IGNEUM_PROGRAM_ATTEMPT 0 +#define IGNEUM_PROGRAM_ID 0xb42f8c8549967581ull +#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 add=8 shfl=8 xor=6 mad=5 mul=5 mulhi=5 sub=4 rotl=3 rotr=3 or=1" +// 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+sh1024x3" +#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 1024 +#define IGNEUM_SHADOW_REPS 3 +#define IGNEUM_SHADOW_INSTRS_PER_HASH 24576 +#define IGNEUM_SHADOW_OP_MIX "add=170 xor=129 mad=121 shfl=112 mul=104 rotl=93 sub=91 mulhi=74 rotr=72 or=58" +// 0 = closed-form dataset (ds_elem), 1 = memory-hard cache construction (MEMHARD.md, memhard.h) +#define IGNEUM_DATASET_MODE 1 + +#define IGNEUM_SEEDW_INIT { 0x67a9a7beu, 0x1a155b25u, 0xfddfb732u, 0x4b5af2e8u, 0xc55caf33u, 0xa27c13b7u, 0x06628a48u, 0x03852469u } +#define IGNEUM_KEY_INIT { 0x3067619fu, 0x3c269176u, 0x84a03b03u, 0xf8c63294u, 0xff977c5bu, 0xe60def3eu, 0x63630141u, 0xb8fbcb58u } +#define IGNEUM_CACHE_LOG2_WORDS 26 +#define IGNEUM_CACHE_SEGMENT_LOG2_LINES 6 +#define IGNEUM_CACHE_SEGMENTS 65536u +#define IGNEUM_ITEM_ROUNDS 8 +#define IGNEUM_MIXER_MULT 8 // mixer applications per round and after the last read (class v3, docs/plans/mixer-x4.md) +#define IGNEUM_MIX_ROT_INIT { 20u, 20u, 19u, 4u, 26u, 3u, 3u, 27u } +#define IGNEUM_MIX_MUL_INIT { 0x42146205u, 0x52cbe0fbu, 0x7ecf4a03u, 0x6728907fu, 0xd81d9751u, 0x132952c3u, 0xf60de277u, 0x05358035u, 0xbaf6499du, 0xe4db9667u, 0x3e98f45du, 0xd0004eddu, 0x2691630du, 0x9beb3bcfu, 0xab310379u, 0x99cfb423u } +#define IGNEUM_MIX_RC_INIT { 0xbab68293u, 0xcc162340u, 0x6ce151ccu, 0xe62b8997u, 0xc9c80297u, 0xf74a1654u, 0x3d704af5u, 0x3cf522b7u, 0x2b9cac04u, 0xa880ac10u, 0x13e5dd1du, 0x6fc3e233u, 0x2d83eeacu, 0x9006e8bfu, 0x2c4b5362u, 0x31b49ee2u } + +#ifndef IGNEUM_NO_CUDA +// Defined in kernel.cu. All launch on the default stream and return cudaGetLastError(). +cudaError_t igneum_launch_cache_fill(uint32_t* cache, uint32_t nSegments); +cudaError_t igneum_launch_build(uint32_t* ds, const uint32_t* cache, uint32_t nItems); +cudaError_t igneum_launch_hash(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, + uint32_t nonces, uint32_t blockWarps); +cudaError_t igneum_hash_info(int* numRegs, int* blocksPerSM, uint32_t blockWarps); +#endif diff --git a/proto-cuda/packs-ca3-shadow/sh1024x3/program.json b/proto-cuda/packs-ca3-shadow/sh1024x3/program.json new file mode 100644 index 000000000..48e5456a5 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh1024x3/program.json @@ -0,0 +1,1157 @@ +{ + "format": "igneum-program-pack-3", + "generator": 2, + "attempt": 0, + "program_id": "0xb42f8c8549967581", + "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": ["0x67a9a7be", "0x1a155b25", "0xfddfb732", "0x4b5af2e8", "0xc55caf33", "0xa27c13b7", "0x06628a48", "0x03852469"], + "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+sh1024x3", + "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, "add": 8, "shfl": 8, "xor": 6, "mad": 5, "mul": 5, "mulhi": 5, "sub": 4, "rotl": 3, "rotr": 3, "or": 1}, + "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": 1024, "reps": 3, "instrs_per_hash": 24576, "op_mix": {"add": 170, "xor": 129, "mad": 121, "shfl": 112, "mul": 104, "rotl": 93, "sub": 91, "mulhi": 74, "rotr": 72, "or": 58}, "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": "add", "dst": 5, "src": 2, "src2": 1, "imm": "0x92199f99", "imm2": "0x8bc12da9", "rot": 9, "bit": 18, "mask": 4}, + {"i": 1, "op": "add", "dst": 0, "src": 7, "src2": 1, "imm": "0x8d72d3ad", "imm2": "0x63079e5a", "rot": 20, "bit": 26, "mask": 4}, + {"i": 2, "op": "shfl", "dst": 6, "src": 3, "src2": 6, "imm": "0x9beaeddf", "imm2": "0x744ecb00", "rot": 10, "bit": 4, "mask": 2}, + {"i": 3, "op": "sub", "dst": 4, "src": 2, "src2": 0, "imm": "0x2a3ddc67", "imm2": "0x72c80241", "rot": 30, "bit": 1, "mask": 16}, + {"i": 4, "op": "add", "dst": 7, "src": 0, "src2": 5, "imm": "0xb21b4bab", "imm2": "0x5d4c7a60", "rot": 17, "bit": 31, "mask": 4}, + {"i": 5, "op": "rotl", "dst": 0, "src": 6, "src2": 3, "imm": "0xe69d7919", "imm2": "0xa048c61e", "rot": 11, "bit": 1, "mask": 8}, + {"i": 6, "op": "add", "dst": 0, "src": 1, "src2": 3, "imm": "0x2fe0e98b", "imm2": "0xc88e2942", "rot": 5, "bit": 16, "mask": 16}, + {"i": 7, "op": "xor", "dst": 7, "src": 1, "src2": 0, "imm": "0xc16efe98", "imm2": "0x01a638c8", "rot": 8, "bit": 17, "mask": 1}, + {"i": 8, "op": "mad", "dst": 1, "src": 6, "src2": 5, "imm": "0x76ec7b8b", "imm2": "0x25663feb", "rot": 29, "bit": 30, "mask": 2}, + {"i": 9, "op": "shfl", "dst": 6, "src": 1, "src2": 0, "imm": "0x6c8ee3cb", "imm2": "0xea93237e", "rot": 27, "bit": 1, "mask": 4}, + {"i": 10, "op": "mad", "dst": 1, "src": 2, "src2": 2, "imm": "0x6dc4ea18", "imm2": "0x6efde6f5", "rot": 3, "bit": 20, "mask": 2}, + {"i": 11, "op": "mad", "dst": 5, "src": 0, "src2": 3, "imm": "0x023613fc", "imm2": "0x18c51939", "rot": 19, "bit": 31, "mask": 1}, + {"i": 12, "op": "shfl", "dst": 2, "src": 6, "src2": 1, "imm": "0x74aec8d2", "imm2": "0x7f7ad29c", "rot": 7, "bit": 8, "mask": 4}, + {"i": 13, "op": "add", "dst": 1, "src": 5, "src2": 6, "imm": "0xbdf8f9a5", "imm2": "0xbc48c63e", "rot": 6, "bit": 25, "mask": 2}, + {"i": 14, "op": "rotl", "dst": 1, "src": 2, "src2": 6, "imm": "0x7ad8ca8b", "imm2": "0x14c712ad", "rot": 29, "bit": 25, "mask": 8}, + {"i": 15, "op": "sub", "dst": 1, "src": 4, "src2": 5, "imm": "0xd3349f69", "imm2": "0x70aac45a", "rot": 29, "bit": 9, "mask": 16}, + {"i": 16, "op": "or", "dst": 7, "src": 1, "src2": 2, "imm": "0x08168ed1", "imm2": "0x28964037", "rot": 26, "bit": 0, "mask": 2}, + {"i": 17, "op": "shfl", "dst": 2, "src": 4, "src2": 6, "imm": "0x98d85f72", "imm2": "0x3dc87042", "rot": 29, "bit": 22, "mask": 8}, + {"i": 18, "op": "xor", "dst": 7, "src": 4, "src2": 0, "imm": "0x651d4a0e", "imm2": "0x93c198bd", "rot": 26, "bit": 12, "mask": 8}, + {"i": 19, "op": "mul", "dst": 6, "src": 1, "src2": 6, "imm": "0xd38ce89d", "imm2": "0x3dfad388", "rot": 5, "bit": 28, "mask": 8}, + {"i": 20, "op": "mad", "dst": 5, "src": 6, "src2": 0, "imm": "0x59d78b36", "imm2": "0xc4db274e", "rot": 25, "bit": 24, "mask": 1}, + {"i": 21, "op": "sub", "dst": 3, "src": 1, "src2": 7, "imm": "0xf6c6a6c7", "imm2": "0x8536f4e6", "rot": 6, "bit": 12, "mask": 4}, + {"i": 22, "op": "mul", "dst": 6, "src": 0, "src2": 7, "imm": "0x599445b4", "imm2": "0x632f8c32", "rot": 19, "bit": 4, "mask": 8}, + {"i": 23, "op": "add", "dst": 2, "src": 0, "src2": 7, "imm": "0x45c37cec", "imm2": "0x96e8f127", "rot": 15, "bit": 1, "mask": 4}, + {"i": 24, "op": "sub", "dst": 6, "src": 4, "src2": 3, "imm": "0xc1c44491", "imm2": "0x92e3ce57", "rot": 20, "bit": 25, "mask": 4}, + {"i": 25, "op": "mad", "dst": 7, "src": 3, "src2": 4, "imm": "0x89bfb8d3", "imm2": "0x19b5455e", "rot": 22, "bit": 2, "mask": 16}, + {"i": 26, "op": "rotl", "dst": 3, "src": 5, "src2": 7, "imm": "0x2f47ce8d", "imm2": "0x8b458ec5", "rot": 9, "bit": 0, "mask": 4}, + {"i": 27, "op": "sub", "dst": 2, "src": 1, "src2": 2, "imm": "0x9f0dce23", "imm2": "0x3cdca814", "rot": 25, "bit": 1, "mask": 2}, + {"i": 28, "op": "mulhi", "dst": 6, "src": 0, "src2": 3, "imm": "0x61fc9eb8", "imm2": "0x23202e9d", "rot": 30, "bit": 16, "mask": 16}, + {"i": 29, "op": "shfl", "dst": 2, "src": 4, "src2": 3, "imm": "0x339dbd65", "imm2": "0xc175f639", "rot": 15, "bit": 22, "mask": 2}, + {"i": 30, "op": "shfl", "dst": 1, "src": 6, "src2": 1, "imm": "0x5bd14589", "imm2": "0xa68a2bed", "rot": 31, "bit": 31, "mask": 1}, + {"i": 31, "op": "add", "dst": 1, "src": 6, "src2": 1, "imm": "0x37985632", "imm2": "0xb1cdb2ab", "rot": 29, "bit": 1, "mask": 8}, + {"i": 32, "op": "rotr", "dst": 0, "src": 1, "src2": 6, "imm": "0x4b2058f4", "imm2": "0xf06d8ac9", "rot": 9, "bit": 15, "mask": 16}, + {"i": 33, "op": "shfl", "dst": 3, "src": 4, "src2": 4, "imm": "0x2081626c", "imm2": "0x08d1bb87", "rot": 24, "bit": 29, "mask": 2}, + {"i": 34, "op": "shfl", "dst": 0, "src": 3, "src2": 6, "imm": "0xe4fcfe03", "imm2": "0x78a46b13", "rot": 15, "bit": 29, "mask": 4}, + {"i": 35, "op": "mul", "dst": 7, "src": 0, "src2": 4, "imm": "0x33148d30", "imm2": "0x5780a3d6", "rot": 6, "bit": 11, "mask": 2}, + {"i": 36, "op": "add", "dst": 3, "src": 1, "src2": 1, "imm": "0x804e777e", "imm2": "0x856e0180", "rot": 22, "bit": 0, "mask": 16}, + {"i": 37, "op": "xor", "dst": 1, "src": 6, "src2": 0, "imm": "0xc69aa2f6", "imm2": "0xafebe3e8", "rot": 15, "bit": 9, "mask": 16}, + {"i": 38, "op": "mul", "dst": 2, "src": 7, "src2": 4, "imm": "0xeb4c4082", "imm2": "0x3f1e0da7", "rot": 25, "bit": 20, "mask": 16}, + {"i": 39, "op": "add", "dst": 6, "src": 5, "src2": 5, "imm": "0x0b06c8a7", "imm2": "0xe9bd0cc4", "rot": 6, "bit": 2, "mask": 4}, + {"i": 40, "op": "mul", "dst": 5, "src": 7, "src2": 7, "imm": "0x070af1b6", "imm2": "0x6b648e75", "rot": 10, "bit": 6, "mask": 16}, + {"i": 41, "op": "mulhi", "dst": 2, "src": 3, "src2": 2, "imm": "0x389753b2", "imm2": "0x9e657305", "rot": 30, "bit": 2, "mask": 4}, + {"i": 42, "op": "xor", "dst": 2, "src": 0, "src2": 4, "imm": "0x0960e5b9", "imm2": "0xa925a406", "rot": 4, "bit": 6, "mask": 16}, + {"i": 43, "op": "rotl", "dst": 0, "src": 1, "src2": 1, "imm": "0x8eabe09f", "imm2": "0x76ef71e2", "rot": 4, "bit": 19, "mask": 8}, + {"i": 44, "op": "mulhi", "dst": 4, "src": 3, "src2": 7, "imm": "0x6a34768a", "imm2": "0x2e427c64", "rot": 21, "bit": 5, "mask": 4}, + {"i": 45, "op": "add", "dst": 6, "src": 7, "src2": 5, "imm": "0xee822e17", "imm2": "0xcdcb63f6", "rot": 27, "bit": 12, "mask": 16}, + {"i": 46, "op": "mad", "dst": 3, "src": 2, "src2": 0, "imm": "0xc89ead43", "imm2": "0x4d3108b2", "rot": 26, "bit": 17, "mask": 1}, + {"i": 47, "op": "shfl", "dst": 4, "src": 3, "src2": 0, "imm": "0xdd62be9e", "imm2": "0xf243f6f2", "rot": 8, "bit": 4, "mask": 8}, + {"i": 48, "op": "mulhi", "dst": 6, "src": 5, "src2": 0, "imm": "0xd3f7fa72", "imm2": "0x0debc83f", "rot": 25, "bit": 5, "mask": 2}, + {"i": 49, "op": "sub", "dst": 0, "src": 2, "src2": 6, "imm": "0x7afadd15", "imm2": "0xc07fc39c", "rot": 30, "bit": 29, "mask": 8}, + {"i": 50, "op": "sub", "dst": 3, "src": 5, "src2": 3, "imm": "0x179b78ec", "imm2": "0xaeccde37", "rot": 30, "bit": 17, "mask": 1}, + {"i": 51, "op": "rotr", "dst": 1, "src": 4, "src2": 1, "imm": "0xa4bfcea6", "imm2": "0xbf63bb2f", "rot": 2, "bit": 21, "mask": 2}, + {"i": 52, "op": "mad", "dst": 6, "src": 7, "src2": 7, "imm": "0xabf5ed10", "imm2": "0x8a285f51", "rot": 3, "bit": 23, "mask": 2}, + {"i": 53, "op": "xor", "dst": 5, "src": 3, "src2": 5, "imm": "0x88b416eb", "imm2": "0x36271d87", "rot": 19, "bit": 10, "mask": 2}, + {"i": 54, "op": "sub", "dst": 1, "src": 0, "src2": 1, "imm": "0xa3417dd3", "imm2": "0xcd98f620", "rot": 28, "bit": 2, "mask": 1}, + {"i": 55, "op": "sub", "dst": 5, "src": 6, "src2": 2, "imm": "0x45996c6f", "imm2": "0xe3d41087", "rot": 4, "bit": 31, "mask": 1}, + {"i": 56, "op": "add", "dst": 3, "src": 2, "src2": 0, "imm": "0x3dfad1b6", "imm2": "0xd4758987", "rot": 27, "bit": 10, "mask": 2}, + {"i": 57, "op": "add", "dst": 4, "src": 1, "src2": 3, "imm": "0xfca75bc2", "imm2": "0x0602d6be", "rot": 19, "bit": 0, "mask": 16}, + {"i": 58, "op": "mulhi", "dst": 5, "src": 6, "src2": 5, "imm": "0x83250a7b", "imm2": "0x2f93d53b", "rot": 25, "bit": 7, "mask": 2}, + {"i": 59, "op": "shfl", "dst": 2, "src": 1, "src2": 0, "imm": "0x13f4a089", "imm2": "0x145ea125", "rot": 12, "bit": 3, "mask": 2}, + {"i": 60, "op": "rotl", "dst": 2, "src": 5, "src2": 6, "imm": "0xad3170e3", "imm2": "0x15db04d1", "rot": 9, "bit": 13, "mask": 2}, + {"i": 61, "op": "or", "dst": 4, "src": 6, "src2": 2, "imm": "0x4b6305b2", "imm2": "0x6e7b2e9c", "rot": 27, "bit": 16, "mask": 4}, + {"i": 62, "op": "rotr", "dst": 6, "src": 4, "src2": 6, "imm": "0xfcd4b1c9", "imm2": "0xaf5c733b", "rot": 6, "bit": 21, "mask": 16}, + {"i": 63, "op": "mul", "dst": 2, "src": 4, "src2": 6, "imm": "0x95cebb3e", "imm2": "0xbba9cdfc", "rot": 19, "bit": 23, "mask": 1}, + {"i": 64, "op": "xor", "dst": 0, "src": 5, "src2": 7, "imm": "0x5f7579ff", "imm2": "0xb104e01a", "rot": 25, "bit": 12, "mask": 8}, + {"i": 65, "op": "xor", "dst": 2, "src": 7, "src2": 3, "imm": "0x749c7611", "imm2": "0xf17df3bb", "rot": 27, "bit": 26, "mask": 2}, + {"i": 66, "op": "add", "dst": 2, "src": 1, "src2": 6, "imm": "0xd71c02ff", "imm2": "0x8596687a", "rot": 4, "bit": 6, "mask": 2}, + {"i": 67, "op": "rotl", "dst": 1, "src": 3, "src2": 2, "imm": "0xd2864071", "imm2": "0xaa644ef3", "rot": 21, "bit": 5, "mask": 1}, + {"i": 68, "op": "mul", "dst": 3, "src": 2, "src2": 1, "imm": "0xd0689a5f", "imm2": "0xa3a1f063", "rot": 13, "bit": 28, "mask": 2}, + {"i": 69, "op": "shfl", "dst": 7, "src": 5, "src2": 6, "imm": "0xd01476eb", "imm2": "0x76abb5c2", "rot": 7, "bit": 30, "mask": 2}, + {"i": 70, "op": "mul", "dst": 3, "src": 2, "src2": 5, "imm": "0x59a75c10", "imm2": "0x1e1fbb72", "rot": 20, "bit": 16, "mask": 1}, + {"i": 71, "op": "mad", "dst": 0, "src": 2, "src2": 5, "imm": "0x39cca1df", "imm2": "0x22c057ac", "rot": 5, "bit": 23, "mask": 16}, + {"i": 72, "op": "add", "dst": 6, "src": 7, "src2": 3, "imm": "0x3c6fe15d", "imm2": "0x08ac5733", "rot": 14, "bit": 0, "mask": 4}, + {"i": 73, "op": "shfl", "dst": 3, "src": 2, "src2": 6, "imm": "0x2098627d", "imm2": "0xf4fecc81", "rot": 20, "bit": 30, "mask": 8}, + {"i": 74, "op": "mul", "dst": 3, "src": 6, "src2": 5, "imm": "0xf82e9e23", "imm2": "0x3ad62132", "rot": 10, "bit": 14, "mask": 16}, + {"i": 75, "op": "xor", "dst": 6, "src": 7, "src2": 4, "imm": "0x70548a91", "imm2": "0xa9715d2e", "rot": 6, "bit": 24, "mask": 1}, + {"i": 76, "op": "or", "dst": 3, "src": 0, "src2": 7, "imm": "0xa164325f", "imm2": "0xf300838b", "rot": 23, "bit": 23, "mask": 16}, + {"i": 77, "op": "add", "dst": 2, "src": 4, "src2": 6, "imm": "0x295d5fae", "imm2": "0xc100b495", "rot": 7, "bit": 1, "mask": 2}, + {"i": 78, "op": "mulhi", "dst": 3, "src": 7, "src2": 4, "imm": "0xb62cca87", "imm2": "0x2ebde415", "rot": 14, "bit": 7, "mask": 2}, + {"i": 79, "op": "or", "dst": 4, "src": 1, "src2": 7, "imm": "0xfcbc482d", "imm2": "0x8876e6cd", "rot": 29, "bit": 5, "mask": 2}, + {"i": 80, "op": "rotr", "dst": 4, "src": 3, "src2": 0, "imm": "0x6d64013b", "imm2": "0x675f4a8d", "rot": 26, "bit": 18, "mask": 8}, + {"i": 81, "op": "add", "dst": 4, "src": 3, "src2": 3, "imm": "0x274a9221", "imm2": "0x5cc59530", "rot": 15, "bit": 15, "mask": 2}, + {"i": 82, "op": "add", "dst": 7, "src": 3, "src2": 0, "imm": "0xc8651f8e", "imm2": "0x141479ec", "rot": 18, "bit": 5, "mask": 1}, + {"i": 83, "op": "rotr", "dst": 3, "src": 6, "src2": 0, "imm": "0xcc8a7766", "imm2": "0xc2eb5161", "rot": 4, "bit": 29, "mask": 2}, + {"i": 84, "op": "mad", "dst": 2, "src": 4, "src2": 7, "imm": "0xbc507d51", "imm2": "0x0b1196fd", "rot": 9, "bit": 7, "mask": 8}, + {"i": 85, "op": "shfl", "dst": 2, "src": 5, "src2": 5, "imm": "0x5a156c90", "imm2": "0xa6b3fbfa", "rot": 11, "bit": 2, "mask": 16}, + {"i": 86, "op": "xor", "dst": 3, "src": 2, "src2": 1, "imm": "0x8b042658", "imm2": "0xacf37a8f", "rot": 12, "bit": 23, "mask": 16}, + {"i": 87, "op": "shfl", "dst": 5, "src": 7, "src2": 2, "imm": "0x1a214238", "imm2": "0x017fdf5d", "rot": 29, "bit": 14, "mask": 2}, + {"i": 88, "op": "xor", "dst": 0, "src": 4, "src2": 2, "imm": "0xd523e612", "imm2": "0x2158c2ed", "rot": 30, "bit": 14, "mask": 4}, + {"i": 89, "op": "add", "dst": 3, "src": 2, "src2": 7, "imm": "0x53f915c2", "imm2": "0x883c0c92", "rot": 9, "bit": 18, "mask": 8}, + {"i": 90, "op": "rotr", "dst": 7, "src": 5, "src2": 5, "imm": "0xbd633b21", "imm2": "0xcf8c356c", "rot": 25, "bit": 31, "mask": 4}, + {"i": 91, "op": "add", "dst": 3, "src": 1, "src2": 1, "imm": "0xe2be00a5", "imm2": "0x3cc5bd20", "rot": 10, "bit": 31, "mask": 1}, + {"i": 92, "op": "shfl", "dst": 7, "src": 2, "src2": 4, "imm": "0x3d3da600", "imm2": "0x1f22df89", "rot": 4, "bit": 24, "mask": 1}, + {"i": 93, "op": "rotr", "dst": 6, "src": 2, "src2": 7, "imm": "0xb0f57471", "imm2": "0x8f2a7eca", "rot": 16, "bit": 25, "mask": 1}, + {"i": 94, "op": "rotl", "dst": 7, "src": 0, "src2": 4, "imm": "0x00a21815", "imm2": "0xeb4d7218", "rot": 14, "bit": 18, "mask": 16}, + {"i": 95, "op": "mad", "dst": 4, "src": 5, "src2": 5, "imm": "0xc4c3828e", "imm2": "0xfb7bba17", "rot": 16, "bit": 10, "mask": 16}, + {"i": 96, "op": "mad", "dst": 2, "src": 4, "src2": 5, "imm": "0xfc5bbc75", "imm2": "0xfc43468f", "rot": 31, "bit": 20, "mask": 16}, + {"i": 97, "op": "xor", "dst": 1, "src": 0, "src2": 2, "imm": "0x1fe9c249", "imm2": "0x164bb16b", "rot": 15, "bit": 9, "mask": 4}, + {"i": 98, "op": "mul", "dst": 5, "src": 4, "src2": 1, "imm": "0xeda725fa", "imm2": "0x66f7e9a2", "rot": 21, "bit": 6, "mask": 2}, + {"i": 99, "op": "sub", "dst": 2, "src": 0, "src2": 7, "imm": "0x8fb29f7d", "imm2": "0xf530eda1", "rot": 27, "bit": 30, "mask": 4}, + {"i": 100, "op": "rotl", "dst": 7, "src": 2, "src2": 0, "imm": "0x9f4de742", "imm2": "0x9b5ff871", "rot": 30, "bit": 21, "mask": 16}, + {"i": 101, "op": "add", "dst": 5, "src": 6, "src2": 7, "imm": "0x423fd9c9", "imm2": "0xbfd646cb", "rot": 17, "bit": 17, "mask": 2}, + {"i": 102, "op": "add", "dst": 7, "src": 6, "src2": 3, "imm": "0x8d3c011d", "imm2": "0x19b74a43", "rot": 12, "bit": 11, "mask": 4}, + {"i": 103, "op": "rotl", "dst": 5, "src": 6, "src2": 0, "imm": "0xcfc70303", "imm2": "0xf2b3e8ef", "rot": 6, "bit": 24, "mask": 1}, + {"i": 104, "op": "mul", "dst": 0, "src": 4, "src2": 5, "imm": "0x650475eb", "imm2": "0x11dcbd94", "rot": 15, "bit": 10, "mask": 1}, + {"i": 105, "op": "or", "dst": 0, "src": 5, "src2": 3, "imm": "0xaacaa145", "imm2": "0x9139d3fe", "rot": 4, "bit": 18, "mask": 2}, + {"i": 106, "op": "add", "dst": 0, "src": 1, "src2": 7, "imm": "0x8ce14721", "imm2": "0x7dcb7e18", "rot": 24, "bit": 15, "mask": 8}, + {"i": 107, "op": "rotl", "dst": 0, "src": 3, "src2": 3, "imm": "0xb36d6d98", "imm2": "0x2c3390c8", "rot": 15, "bit": 10, "mask": 16}, + {"i": 108, "op": "sub", "dst": 4, "src": 2, "src2": 5, "imm": "0xf6bbdaef", "imm2": "0x9db6f65e", "rot": 25, "bit": 10, "mask": 1}, + {"i": 109, "op": "mulhi", "dst": 2, "src": 0, "src2": 0, "imm": "0xb1721fd6", "imm2": "0xd96d52c9", "rot": 1, "bit": 27, "mask": 8}, + {"i": 110, "op": "mulhi", "dst": 1, "src": 0, "src2": 5, "imm": "0xfb4ca37f", "imm2": "0xb6ec7dbe", "rot": 27, "bit": 12, "mask": 8}, + {"i": 111, "op": "add", "dst": 0, "src": 2, "src2": 0, "imm": "0x2d9fc6b9", "imm2": "0x3c179ad8", "rot": 9, "bit": 28, "mask": 16}, + {"i": 112, "op": "mulhi", "dst": 2, "src": 0, "src2": 6, "imm": "0x71a9f6bd", "imm2": "0xd3417bf5", "rot": 2, "bit": 14, "mask": 8}, + {"i": 113, "op": "sub", "dst": 6, "src": 3, "src2": 5, "imm": "0xa3d19400", "imm2": "0x15df7330", "rot": 5, "bit": 2, "mask": 8}, + {"i": 114, "op": "mad", "dst": 7, "src": 6, "src2": 3, "imm": "0x1400d92e", "imm2": "0xfa4a158e", "rot": 16, "bit": 9, "mask": 1}, + {"i": 115, "op": "rotr", "dst": 5, "src": 1, "src2": 3, "imm": "0xd01684c3", "imm2": "0x6367febb", "rot": 23, "bit": 19, "mask": 2}, + {"i": 116, "op": "rotr", "dst": 6, "src": 4, "src2": 2, "imm": "0x8cd9eb96", "imm2": "0x98f33b24", "rot": 25, "bit": 1, "mask": 2}, + {"i": 117, "op": "add", "dst": 2, "src": 1, "src2": 7, "imm": "0x502138e2", "imm2": "0x47359729", "rot": 5, "bit": 22, "mask": 4}, + {"i": 118, "op": "mad", "dst": 3, "src": 2, "src2": 0, "imm": "0xd94a35c7", "imm2": "0xb83416c3", "rot": 11, "bit": 3, "mask": 4}, + {"i": 119, "op": "mul", "dst": 1, "src": 3, "src2": 6, "imm": "0x09b30cf7", "imm2": "0xef3b98e7", "rot": 17, "bit": 23, "mask": 8}, + {"i": 120, "op": "mad", "dst": 2, "src": 0, "src2": 4, "imm": "0x56416fe0", "imm2": "0x5e1dc8f3", "rot": 17, "bit": 14, "mask": 2}, + {"i": 121, "op": "mul", "dst": 0, "src": 3, "src2": 2, "imm": "0x2892697c", "imm2": "0x9cb3b14e", "rot": 29, "bit": 25, "mask": 2}, + {"i": 122, "op": "mulhi", "dst": 2, "src": 0, "src2": 3, "imm": "0xc33089a1", "imm2": "0xd6c5b530", "rot": 27, "bit": 13, "mask": 8}, + {"i": 123, "op": "mul", "dst": 5, "src": 6, "src2": 4, "imm": "0xdfe04e4a", "imm2": "0x3cc40160", "rot": 3, "bit": 14, "mask": 2}, + {"i": 124, "op": "mad", "dst": 4, "src": 2, "src2": 4, "imm": "0xb33dc1b7", "imm2": "0xab97743a", "rot": 7, "bit": 21, "mask": 4}, + {"i": 125, "op": "shfl", "dst": 4, "src": 2, "src2": 0, "imm": "0xfd469909", "imm2": "0xfc85dc55", "rot": 28, "bit": 24, "mask": 2}, + {"i": 126, "op": "xor", "dst": 2, "src": 0, "src2": 5, "imm": "0xa0094578", "imm2": "0xf1bee474", "rot": 31, "bit": 7, "mask": 2}, + {"i": 127, "op": "rotl", "dst": 1, "src": 7, "src2": 2, "imm": "0xb7ae00a0", "imm2": "0x86cce297", "rot": 7, "bit": 31, "mask": 8}, + {"i": 128, "op": "shfl", "dst": 7, "src": 2, "src2": 7, "imm": "0x019d1940", "imm2": "0x3fe9e7dd", "rot": 14, "bit": 4, "mask": 4}, + {"i": 129, "op": "rotl", "dst": 6, "src": 7, "src2": 7, "imm": "0x40a74cc4", "imm2": "0x09eb4adf", "rot": 17, "bit": 30, "mask": 1}, + {"i": 130, "op": "add", "dst": 2, "src": 5, "src2": 5, "imm": "0x33dff776", "imm2": "0x6c57e4e7", "rot": 27, "bit": 15, "mask": 4}, + {"i": 131, "op": "or", "dst": 0, "src": 3, "src2": 1, "imm": "0xe0c53bb9", "imm2": "0x124404f6", "rot": 4, "bit": 21, "mask": 16}, + {"i": 132, "op": "rotr", "dst": 5, "src": 0, "src2": 1, "imm": "0xe4353fce", "imm2": "0x559d0118", "rot": 2, "bit": 29, "mask": 4}, + {"i": 133, "op": "add", "dst": 2, "src": 3, "src2": 6, "imm": "0x5db25b34", "imm2": "0xe8212c0c", "rot": 21, "bit": 30, "mask": 1}, + {"i": 134, "op": "xor", "dst": 4, "src": 3, "src2": 6, "imm": "0x7366e50e", "imm2": "0x7cc1ffbd", "rot": 19, "bit": 18, "mask": 16}, + {"i": 135, "op": "xor", "dst": 6, "src": 1, "src2": 2, "imm": "0xa36decb7", "imm2": "0x79291734", "rot": 26, "bit": 0, "mask": 8}, + {"i": 136, "op": "sub", "dst": 1, "src": 7, "src2": 0, "imm": "0x225b03e4", "imm2": "0x7183e193", "rot": 16, "bit": 6, "mask": 2}, + {"i": 137, "op": "mad", "dst": 2, "src": 6, "src2": 2, "imm": "0x6f620d51", "imm2": "0x4e814e19", "rot": 6, "bit": 6, "mask": 2}, + {"i": 138, "op": "mulhi", "dst": 0, "src": 5, "src2": 6, "imm": "0x919d6bf3", "imm2": "0xc6240638", "rot": 17, "bit": 11, "mask": 16}, + {"i": 139, "op": "add", "dst": 2, "src": 7, "src2": 7, "imm": "0x218d4090", "imm2": "0xd44ff710", "rot": 1, "bit": 10, "mask": 16}, + {"i": 140, "op": "rotr", "dst": 1, "src": 4, "src2": 4, "imm": "0x4cbfa722", "imm2": "0x114e9564", "rot": 28, "bit": 9, "mask": 16}, + {"i": 141, "op": "shfl", "dst": 3, "src": 6, "src2": 2, "imm": "0xf702c6a1", "imm2": "0xf8f3c5d9", "rot": 7, "bit": 24, "mask": 1}, + {"i": 142, "op": "mad", "dst": 7, "src": 6, "src2": 2, "imm": "0xa2d285be", "imm2": "0x9cc94532", "rot": 15, "bit": 20, "mask": 8}, + {"i": 143, "op": "mul", "dst": 2, "src": 3, "src2": 7, "imm": "0x08b7ed80", "imm2": "0xa8abced4", "rot": 18, "bit": 10, "mask": 4}, + {"i": 144, "op": "add", "dst": 7, "src": 4, "src2": 2, "imm": "0xf4b1a8de", "imm2": "0xb98942fa", "rot": 18, "bit": 29, "mask": 8}, + {"i": 145, "op": "rotl", "dst": 7, "src": 6, "src2": 1, "imm": "0x64b6ba2d", "imm2": "0xf9e86793", "rot": 15, "bit": 24, "mask": 8}, + {"i": 146, "op": "xor", "dst": 7, "src": 5, "src2": 3, "imm": "0x41c42b5f", "imm2": "0x7c7e0e39", "rot": 8, "bit": 23, "mask": 2}, + {"i": 147, "op": "mad", "dst": 4, "src": 7, "src2": 4, "imm": "0x3caa807a", "imm2": "0x553a0cec", "rot": 11, "bit": 22, "mask": 8}, + {"i": 148, "op": "rotr", "dst": 6, "src": 5, "src2": 3, "imm": "0x3cb1289a", "imm2": "0x6b36f78a", "rot": 1, "bit": 9, "mask": 16}, + {"i": 149, "op": "mad", "dst": 1, "src": 2, "src2": 4, "imm": "0x95310ea8", "imm2": "0xc533aa6a", "rot": 16, "bit": 17, "mask": 1}, + {"i": 150, "op": "add", "dst": 1, "src": 7, "src2": 7, "imm": "0x2bef10f2", "imm2": "0x0d48ba42", "rot": 8, "bit": 17, "mask": 4}, + {"i": 151, "op": "xor", "dst": 5, "src": 4, "src2": 7, "imm": "0xda997ab2", "imm2": "0xae31d69e", "rot": 11, "bit": 31, "mask": 2}, + {"i": 152, "op": "add", "dst": 7, "src": 0, "src2": 6, "imm": "0xdc5cc080", "imm2": "0xc98dea9c", "rot": 16, "bit": 30, "mask": 2}, + {"i": 153, "op": "mul", "dst": 4, "src": 6, "src2": 7, "imm": "0xbfbf5f6c", "imm2": "0x61f611bb", "rot": 14, "bit": 22, "mask": 2}, + {"i": 154, "op": "mul", "dst": 0, "src": 2, "src2": 3, "imm": "0xa78008c3", "imm2": "0xbad5eeb1", "rot": 10, "bit": 28, "mask": 8}, + {"i": 155, "op": "xor", "dst": 6, "src": 5, "src2": 4, "imm": "0x1a73b866", "imm2": "0x1f5a62c9", "rot": 9, "bit": 27, "mask": 8}, + {"i": 156, "op": "rotr", "dst": 4, "src": 2, "src2": 0, "imm": "0x9c88500c", "imm2": "0xe25dccf9", "rot": 11, "bit": 2, "mask": 16}, + {"i": 157, "op": "rotl", "dst": 1, "src": 4, "src2": 4, "imm": "0xb05e7669", "imm2": "0x9db704b1", "rot": 11, "bit": 28, "mask": 4}, + {"i": 158, "op": "add", "dst": 5, "src": 0, "src2": 6, "imm": "0x18197438", "imm2": "0x6c752dcb", "rot": 11, "bit": 11, "mask": 2}, + {"i": 159, "op": "mad", "dst": 4, "src": 1, "src2": 5, "imm": "0x4796a65e", "imm2": "0x00e08c7a", "rot": 8, "bit": 19, "mask": 4}, + {"i": 160, "op": "rotl", "dst": 4, "src": 7, "src2": 5, "imm": "0x08a03052", "imm2": "0x0204f0ba", "rot": 26, "bit": 5, "mask": 2}, + {"i": 161, "op": "mad", "dst": 3, "src": 0, "src2": 7, "imm": "0xa0603b0e", "imm2": "0x7eee83d5", "rot": 28, "bit": 22, "mask": 16}, + {"i": 162, "op": "rotr", "dst": 3, "src": 1, "src2": 6, "imm": "0x78a3c69d", "imm2": "0x684693a0", "rot": 21, "bit": 23, "mask": 4}, + {"i": 163, "op": "add", "dst": 4, "src": 0, "src2": 7, "imm": "0xf1c46574", "imm2": "0x8e481727", "rot": 9, "bit": 3, "mask": 4}, + {"i": 164, "op": "mulhi", "dst": 0, "src": 4, "src2": 3, "imm": "0x04644afa", "imm2": "0x64bda2b5", "rot": 26, "bit": 16, "mask": 16}, + {"i": 165, "op": "add", "dst": 2, "src": 6, "src2": 2, "imm": "0xac578137", "imm2": "0x550ab406", "rot": 13, "bit": 20, "mask": 16}, + {"i": 166, "op": "rotl", "dst": 0, "src": 4, "src2": 5, "imm": "0x7f564760", "imm2": "0xb9a8b4f8", "rot": 13, "bit": 29, "mask": 1}, + {"i": 167, "op": "add", "dst": 3, "src": 1, "src2": 0, "imm": "0xa33e6706", "imm2": "0xaebb5966", "rot": 12, "bit": 14, "mask": 16}, + {"i": 168, "op": "or", "dst": 3, "src": 5, "src2": 3, "imm": "0x65b2f3eb", "imm2": "0xb1d00d20", "rot": 12, "bit": 2, "mask": 8}, + {"i": 169, "op": "rotr", "dst": 6, "src": 2, "src2": 3, "imm": "0x7f21faf5", "imm2": "0xbbf0d3f9", "rot": 17, "bit": 13, "mask": 8}, + {"i": 170, "op": "xor", "dst": 4, "src": 6, "src2": 2, "imm": "0x162c7140", "imm2": "0x90d404ad", "rot": 26, "bit": 1, "mask": 4}, + {"i": 171, "op": "sub", "dst": 6, "src": 1, "src2": 7, "imm": "0x6ef9c76e", "imm2": "0xfb7ba272", "rot": 31, "bit": 25, "mask": 1}, + {"i": 172, "op": "rotl", "dst": 7, "src": 5, "src2": 4, "imm": "0xde04eb3b", "imm2": "0xd56caa00", "rot": 22, "bit": 21, "mask": 4}, + {"i": 173, "op": "rotl", "dst": 5, "src": 3, "src2": 5, "imm": "0xa9eac934", "imm2": "0x2c338e51", "rot": 15, "bit": 22, "mask": 2}, + {"i": 174, "op": "shfl", "dst": 7, "src": 0, "src2": 3, "imm": "0x700be4e3", "imm2": "0x4bcfc732", "rot": 19, "bit": 6, "mask": 8}, + {"i": 175, "op": "xor", "dst": 0, "src": 5, "src2": 1, "imm": "0x02ccdba9", "imm2": "0xd0915be0", "rot": 15, "bit": 2, "mask": 16}, + {"i": 176, "op": "rotl", "dst": 7, "src": 4, "src2": 1, "imm": "0x489c8165", "imm2": "0xf24b5a4f", "rot": 6, "bit": 22, "mask": 1}, + {"i": 177, "op": "sub", "dst": 7, "src": 0, "src2": 6, "imm": "0x23ad9693", "imm2": "0x9a8c2f7b", "rot": 24, "bit": 2, "mask": 2}, + {"i": 178, "op": "rotl", "dst": 3, "src": 0, "src2": 6, "imm": "0xafa72a42", "imm2": "0x371d74ee", "rot": 30, "bit": 16, "mask": 1}, + {"i": 179, "op": "mad", "dst": 7, "src": 6, "src2": 1, "imm": "0x18a2a3f3", "imm2": "0xb811b951", "rot": 2, "bit": 9, "mask": 2}, + {"i": 180, "op": "rotl", "dst": 6, "src": 4, "src2": 1, "imm": "0xe6c69c0e", "imm2": "0xfc46a951", "rot": 9, "bit": 31, "mask": 4}, + {"i": 181, "op": "xor", "dst": 2, "src": 4, "src2": 7, "imm": "0xbd1b89e4", "imm2": "0xdf4bce5c", "rot": 15, "bit": 19, "mask": 4}, + {"i": 182, "op": "xor", "dst": 2, "src": 7, "src2": 5, "imm": "0x3dd12aed", "imm2": "0xd0756a69", "rot": 13, "bit": 16, "mask": 4}, + {"i": 183, "op": "xor", "dst": 7, "src": 2, "src2": 3, "imm": "0x77ce69d6", "imm2": "0x2b39bdf2", "rot": 8, "bit": 22, "mask": 16}, + {"i": 184, "op": "add", "dst": 1, "src": 2, "src2": 4, "imm": "0xd94d55ac", "imm2": "0x5bb7550f", "rot": 31, "bit": 21, "mask": 1}, + {"i": 185, "op": "or", "dst": 3, "src": 5, "src2": 6, "imm": "0x7b1ce846", "imm2": "0xcc3b8509", "rot": 28, "bit": 9, "mask": 4}, + {"i": 186, "op": "mulhi", "dst": 6, "src": 3, "src2": 0, "imm": "0xa5e24690", "imm2": "0x2200ba81", "rot": 26, "bit": 10, "mask": 16}, + {"i": 187, "op": "or", "dst": 4, "src": 0, "src2": 3, "imm": "0xf6efe759", "imm2": "0xae1f7118", "rot": 19, "bit": 20, "mask": 4}, + {"i": 188, "op": "shfl", "dst": 7, "src": 1, "src2": 5, "imm": "0xdb318b45", "imm2": "0xcec459c9", "rot": 20, "bit": 11, "mask": 2}, + {"i": 189, "op": "add", "dst": 6, "src": 5, "src2": 1, "imm": "0x89e747fe", "imm2": "0x2a354e2d", "rot": 22, "bit": 6, "mask": 1}, + {"i": 190, "op": "xor", "dst": 1, "src": 4, "src2": 2, "imm": "0xc379e617", "imm2": "0x75e9d63b", "rot": 23, "bit": 3, "mask": 2}, + {"i": 191, "op": "mulhi", "dst": 7, "src": 4, "src2": 3, "imm": "0x5a710287", "imm2": "0x7fe4ead6", "rot": 10, "bit": 25, "mask": 4}, + {"i": 192, "op": "rotl", "dst": 2, "src": 1, "src2": 2, "imm": "0x4d5e59a3", "imm2": "0x1e4fef28", "rot": 26, "bit": 0, "mask": 1}, + {"i": 193, "op": "rotl", "dst": 5, "src": 3, "src2": 7, "imm": "0x7444c47d", "imm2": "0xdad5f8be", "rot": 8, "bit": 30, "mask": 2}, + {"i": 194, "op": "shfl", "dst": 4, "src": 5, "src2": 7, "imm": "0x6a225bbb", "imm2": "0xd6532cd7", "rot": 13, "bit": 17, "mask": 16}, + {"i": 195, "op": "xor", "dst": 4, "src": 5, "src2": 3, "imm": "0x68344b9a", "imm2": "0xcb46a38b", "rot": 1, "bit": 27, "mask": 16}, + {"i": 196, "op": "mul", "dst": 1, "src": 3, "src2": 4, "imm": "0xbebf7359", "imm2": "0x3f0890ba", "rot": 18, "bit": 12, "mask": 4}, + {"i": 197, "op": "add", "dst": 5, "src": 2, "src2": 3, "imm": "0xea03e8e7", "imm2": "0x10cfdc71", "rot": 31, "bit": 7, "mask": 8}, + {"i": 198, "op": "add", "dst": 7, "src": 5, "src2": 1, "imm": "0xa7ee0102", "imm2": "0x66e148d3", "rot": 12, "bit": 15, "mask": 1}, + {"i": 199, "op": "sub", "dst": 5, "src": 2, "src2": 4, "imm": "0xc215584e", "imm2": "0x55fce30f", "rot": 30, "bit": 9, "mask": 2}, + {"i": 200, "op": "shfl", "dst": 5, "src": 1, "src2": 1, "imm": "0x308f8358", "imm2": "0x489f1f93", "rot": 13, "bit": 13, "mask": 2}, + {"i": 201, "op": "shfl", "dst": 7, "src": 1, "src2": 5, "imm": "0x713f1957", "imm2": "0x2239f757", "rot": 15, "bit": 7, "mask": 8}, + {"i": 202, "op": "rotr", "dst": 4, "src": 5, "src2": 1, "imm": "0xb037b6e7", "imm2": "0x49a8b528", "rot": 27, "bit": 13, "mask": 16}, + {"i": 203, "op": "xor", "dst": 7, "src": 5, "src2": 1, "imm": "0x56110241", "imm2": "0xefc8386d", "rot": 22, "bit": 20, "mask": 1}, + {"i": 204, "op": "xor", "dst": 7, "src": 0, "src2": 0, "imm": "0x0827fcc7", "imm2": "0xf4f5dd07", "rot": 13, "bit": 7, "mask": 2}, + {"i": 205, "op": "add", "dst": 6, "src": 2, "src2": 0, "imm": "0x8379a4de", "imm2": "0x8558b619", "rot": 26, "bit": 10, "mask": 1}, + {"i": 206, "op": "rotl", "dst": 4, "src": 3, "src2": 3, "imm": "0x091ceef0", "imm2": "0x69b0f72f", "rot": 13, "bit": 7, "mask": 1}, + {"i": 207, "op": "mulhi", "dst": 1, "src": 3, "src2": 4, "imm": "0x758edac1", "imm2": "0x98dd2f21", "rot": 15, "bit": 9, "mask": 1}, + {"i": 208, "op": "mad", "dst": 1, "src": 4, "src2": 4, "imm": "0x78871a1a", "imm2": "0x5e14e1c8", "rot": 19, "bit": 6, "mask": 2}, + {"i": 209, "op": "shfl", "dst": 2, "src": 0, "src2": 2, "imm": "0xf7e0b9aa", "imm2": "0xaecfd347", "rot": 21, "bit": 9, "mask": 4}, + {"i": 210, "op": "add", "dst": 7, "src": 0, "src2": 7, "imm": "0xaa8cb14e", "imm2": "0xf4049c4c", "rot": 24, "bit": 11, "mask": 8}, + {"i": 211, "op": "shfl", "dst": 7, "src": 1, "src2": 6, "imm": "0xc230d919", "imm2": "0xf76d08fb", "rot": 21, "bit": 13, "mask": 16}, + {"i": 212, "op": "xor", "dst": 1, "src": 0, "src2": 2, "imm": "0x31a5af90", "imm2": "0x7eef58ee", "rot": 9, "bit": 12, "mask": 4}, + {"i": 213, "op": "rotl", "dst": 7, "src": 1, "src2": 6, "imm": "0x0db26138", "imm2": "0x8e3c31f9", "rot": 3, "bit": 26, "mask": 2}, + {"i": 214, "op": "rotr", "dst": 4, "src": 7, "src2": 3, "imm": "0x29558100", "imm2": "0xe4b13ad6", "rot": 29, "bit": 24, "mask": 8}, + {"i": 215, "op": "shfl", "dst": 3, "src": 2, "src2": 6, "imm": "0x1b48c3d0", "imm2": "0x5c674ff6", "rot": 5, "bit": 9, "mask": 16}, + {"i": 216, "op": "or", "dst": 5, "src": 1, "src2": 0, "imm": "0xef768632", "imm2": "0x6de9d10d", "rot": 10, "bit": 4, "mask": 4}, + {"i": 217, "op": "sub", "dst": 1, "src": 2, "src2": 5, "imm": "0x88ca7f5a", "imm2": "0x24718a36", "rot": 18, "bit": 31, "mask": 1}, + {"i": 218, "op": "sub", "dst": 6, "src": 5, "src2": 0, "imm": "0xc4a06728", "imm2": "0xdc2a4fd8", "rot": 9, "bit": 9, "mask": 2}, + {"i": 219, "op": "rotl", "dst": 6, "src": 5, "src2": 7, "imm": "0xb7489e47", "imm2": "0xf13795c5", "rot": 4, "bit": 3, "mask": 8}, + {"i": 220, "op": "mulhi", "dst": 2, "src": 0, "src2": 2, "imm": "0x873cd31b", "imm2": "0x3dfbc55d", "rot": 12, "bit": 23, "mask": 8}, + {"i": 221, "op": "or", "dst": 2, "src": 0, "src2": 3, "imm": "0xdc21f099", "imm2": "0xee06f01e", "rot": 2, "bit": 17, "mask": 8}, + {"i": 222, "op": "shfl", "dst": 5, "src": 2, "src2": 6, "imm": "0x36def499", "imm2": "0xa2849d59", "rot": 23, "bit": 4, "mask": 8}, + {"i": 223, "op": "mulhi", "dst": 5, "src": 6, "src2": 7, "imm": "0xfb95fbca", "imm2": "0xc1aac427", "rot": 14, "bit": 11, "mask": 2}, + {"i": 224, "op": "sub", "dst": 0, "src": 6, "src2": 7, "imm": "0x3d9d29c4", "imm2": "0x34d0dcc0", "rot": 17, "bit": 6, "mask": 4}, + {"i": 225, "op": "rotl", "dst": 7, "src": 0, "src2": 5, "imm": "0x93b01b8e", "imm2": "0xfe1d75ac", "rot": 23, "bit": 15, "mask": 1}, + {"i": 226, "op": "or", "dst": 4, "src": 2, "src2": 4, "imm": "0xfed76e8e", "imm2": "0x1c24ecd8", "rot": 2, "bit": 6, "mask": 16}, + {"i": 227, "op": "mul", "dst": 2, "src": 4, "src2": 1, "imm": "0x5795f5b0", "imm2": "0x0566ea2a", "rot": 6, "bit": 28, "mask": 4}, + {"i": 228, "op": "rotl", "dst": 3, "src": 0, "src2": 2, "imm": "0x8c8486de", "imm2": "0xd066aa8f", "rot": 12, "bit": 20, "mask": 1}, + {"i": 229, "op": "rotr", "dst": 0, "src": 4, "src2": 0, "imm": "0x23a3e882", "imm2": "0xaca23902", "rot": 5, "bit": 22, "mask": 16}, + {"i": 230, "op": "add", "dst": 0, "src": 6, "src2": 4, "imm": "0x1d176220", "imm2": "0x2a7fecb2", "rot": 20, "bit": 16, "mask": 2}, + {"i": 231, "op": "shfl", "dst": 1, "src": 2, "src2": 0, "imm": "0x91172787", "imm2": "0xc5d7af28", "rot": 3, "bit": 24, "mask": 4}, + {"i": 232, "op": "mul", "dst": 2, "src": 1, "src2": 2, "imm": "0x0be68835", "imm2": "0xde692bdb", "rot": 30, "bit": 17, "mask": 1}, + {"i": 233, "op": "mad", "dst": 7, "src": 0, "src2": 1, "imm": "0xf90d2db5", "imm2": "0x96c4c175", "rot": 28, "bit": 7, "mask": 4}, + {"i": 234, "op": "rotl", "dst": 5, "src": 2, "src2": 1, "imm": "0x16379736", "imm2": "0x6973b905", "rot": 22, "bit": 17, "mask": 4}, + {"i": 235, "op": "rotr", "dst": 4, "src": 6, "src2": 2, "imm": "0x84292a13", "imm2": "0x0f897740", "rot": 12, "bit": 6, "mask": 8}, + {"i": 236, "op": "mad", "dst": 0, "src": 5, "src2": 1, "imm": "0xeb7de837", "imm2": "0x64f0c302", "rot": 4, "bit": 19, "mask": 1}, + {"i": 237, "op": "xor", "dst": 6, "src": 4, "src2": 4, "imm": "0x6ab4b683", "imm2": "0x20f17adb", "rot": 1, "bit": 0, "mask": 16}, + {"i": 238, "op": "xor", "dst": 4, "src": 6, "src2": 1, "imm": "0x5836b35c", "imm2": "0x3293cc4a", "rot": 16, "bit": 22, "mask": 16}, + {"i": 239, "op": "rotl", "dst": 6, "src": 1, "src2": 6, "imm": "0x769d8bc0", "imm2": "0xdc86c9cc", "rot": 18, "bit": 27, "mask": 16}, + {"i": 240, "op": "add", "dst": 4, "src": 7, "src2": 1, "imm": "0x17dafb4d", "imm2": "0xadce39f3", "rot": 12, "bit": 25, "mask": 8}, + {"i": 241, "op": "sub", "dst": 0, "src": 7, "src2": 4, "imm": "0xd4690bda", "imm2": "0xdab9b27b", "rot": 30, "bit": 21, "mask": 1}, + {"i": 242, "op": "rotr", "dst": 1, "src": 6, "src2": 2, "imm": "0x670a2d0a", "imm2": "0x0612e33c", "rot": 31, "bit": 25, "mask": 2}, + {"i": 243, "op": "add", "dst": 3, "src": 0, "src2": 2, "imm": "0xf2f77d26", "imm2": "0x0e7033b6", "rot": 27, "bit": 29, "mask": 1}, + {"i": 244, "op": "mad", "dst": 2, "src": 7, "src2": 4, "imm": "0xa9eefc9d", "imm2": "0x16166c85", "rot": 18, "bit": 23, "mask": 16}, + {"i": 245, "op": "mad", "dst": 4, "src": 0, "src2": 6, "imm": "0xb26f6c0f", "imm2": "0x0630e821", "rot": 23, "bit": 30, "mask": 4}, + {"i": 246, "op": "mul", "dst": 5, "src": 7, "src2": 2, "imm": "0x269ce4bf", "imm2": "0x1ce28d32", "rot": 30, "bit": 15, "mask": 16}, + {"i": 247, "op": "add", "dst": 3, "src": 5, "src2": 0, "imm": "0xfed2da4e", "imm2": "0x7b2ff6b7", "rot": 25, "bit": 31, "mask": 2}, + {"i": 248, "op": "add", "dst": 0, "src": 7, "src2": 5, "imm": "0x03b2891c", "imm2": "0xb5fad7b1", "rot": 2, "bit": 0, "mask": 4}, + {"i": 249, "op": "mulhi", "dst": 5, "src": 4, "src2": 6, "imm": "0xa69a1e71", "imm2": "0x15f0c0ea", "rot": 4, "bit": 1, "mask": 4}, + {"i": 250, "op": "add", "dst": 5, "src": 2, "src2": 3, "imm": "0x042cd6e3", "imm2": "0xa7e71c2f", "rot": 24, "bit": 11, "mask": 8}, + {"i": 251, "op": "shfl", "dst": 6, "src": 1, "src2": 2, "imm": "0x89c6b683", "imm2": "0x10bbf661", "rot": 24, "bit": 5, "mask": 1}, + {"i": 252, "op": "xor", "dst": 6, "src": 1, "src2": 3, "imm": "0x265c66d6", "imm2": "0xd4a689ed", "rot": 6, "bit": 14, "mask": 8}, + {"i": 253, "op": "mul", "dst": 2, "src": 5, "src2": 5, "imm": "0x890b8201", "imm2": "0x97c36bf3", "rot": 17, "bit": 22, "mask": 4}, + {"i": 254, "op": "add", "dst": 0, "src": 6, "src2": 0, "imm": "0x784a302b", "imm2": "0xb83d78de", "rot": 27, "bit": 16, "mask": 4}, + {"i": 255, "op": "sub", "dst": 2, "src": 4, "src2": 0, "imm": "0x817adb38", "imm2": "0xf3a3534b", "rot": 7, "bit": 22, "mask": 4}, + {"i": 256, "op": "sub", "dst": 3, "src": 4, "src2": 2, "imm": "0xe0ce945e", "imm2": "0x46b1ef7b", "rot": 19, "bit": 7, "mask": 1}, + {"i": 257, "op": "mul", "dst": 2, "src": 4, "src2": 4, "imm": "0xd2ea408f", "imm2": "0xa3c99bc7", "rot": 31, "bit": 31, "mask": 2}, + {"i": 258, "op": "mad", "dst": 4, "src": 0, "src2": 6, "imm": "0x0d2fed03", "imm2": "0xe4f22c13", "rot": 13, "bit": 1, "mask": 1}, + {"i": 259, "op": "or", "dst": 5, "src": 0, "src2": 7, "imm": "0x2576d6d4", "imm2": "0x9c5b1711", "rot": 10, "bit": 0, "mask": 4}, + {"i": 260, "op": "xor", "dst": 4, "src": 6, "src2": 5, "imm": "0x15f0c87c", "imm2": "0x4688c0cc", "rot": 16, "bit": 10, "mask": 8}, + {"i": 261, "op": "mulhi", "dst": 6, "src": 3, "src2": 5, "imm": "0xb4b90915", "imm2": "0xcc6dcd57", "rot": 18, "bit": 3, "mask": 8}, + {"i": 262, "op": "mul", "dst": 2, "src": 6, "src2": 2, "imm": "0x17fd2215", "imm2": "0xde8a2ca4", "rot": 23, "bit": 1, "mask": 8}, + {"i": 263, "op": "rotl", "dst": 5, "src": 3, "src2": 7, "imm": "0x30d282d7", "imm2": "0x2230b805", "rot": 1, "bit": 30, "mask": 2}, + {"i": 264, "op": "shfl", "dst": 7, "src": 1, "src2": 6, "imm": "0x1efbbbcb", "imm2": "0x9ed4d8c0", "rot": 1, "bit": 27, "mask": 8}, + {"i": 265, "op": "mul", "dst": 3, "src": 2, "src2": 2, "imm": "0xaa201ffc", "imm2": "0xad6fe73d", "rot": 16, "bit": 7, "mask": 2}, + {"i": 266, "op": "add", "dst": 2, "src": 5, "src2": 2, "imm": "0x3dddf1b2", "imm2": "0x99a1d1b6", "rot": 9, "bit": 15, "mask": 2}, + {"i": 267, "op": "shfl", "dst": 2, "src": 0, "src2": 7, "imm": "0x39645ea0", "imm2": "0xf4650f80", "rot": 7, "bit": 7, "mask": 8}, + {"i": 268, "op": "shfl", "dst": 0, "src": 1, "src2": 1, "imm": "0xb95052fd", "imm2": "0x9ee244d5", "rot": 7, "bit": 25, "mask": 2}, + {"i": 269, "op": "sub", "dst": 4, "src": 2, "src2": 7, "imm": "0xa80d4145", "imm2": "0x20c6daa9", "rot": 28, "bit": 8, "mask": 16}, + {"i": 270, "op": "shfl", "dst": 0, "src": 5, "src2": 6, "imm": "0x99118c6e", "imm2": "0xa9bef776", "rot": 1, "bit": 13, "mask": 1}, + {"i": 271, "op": "add", "dst": 3, "src": 2, "src2": 1, "imm": "0xcfc62661", "imm2": "0x40ca287a", "rot": 25, "bit": 21, "mask": 4}, + {"i": 272, "op": "shfl", "dst": 1, "src": 7, "src2": 1, "imm": "0xc85fe17e", "imm2": "0xbec43e83", "rot": 27, "bit": 23, "mask": 16}, + {"i": 273, "op": "mad", "dst": 1, "src": 3, "src2": 6, "imm": "0x9578e92a", "imm2": "0xbc63271f", "rot": 22, "bit": 18, "mask": 16}, + {"i": 274, "op": "add", "dst": 7, "src": 6, "src2": 4, "imm": "0x44caede3", "imm2": "0xed4b65ad", "rot": 25, "bit": 30, "mask": 4}, + {"i": 275, "op": "xor", "dst": 5, "src": 7, "src2": 0, "imm": "0x0ebe2aab", "imm2": "0xf646d31b", "rot": 10, "bit": 14, "mask": 2}, + {"i": 276, "op": "mul", "dst": 2, "src": 6, "src2": 0, "imm": "0xc6ecf917", "imm2": "0xc195e458", "rot": 10, "bit": 5, "mask": 4}, + {"i": 277, "op": "add", "dst": 2, "src": 1, "src2": 6, "imm": "0x9aae6c12", "imm2": "0x0f45ae89", "rot": 10, "bit": 6, "mask": 16}, + {"i": 278, "op": "xor", "dst": 2, "src": 6, "src2": 2, "imm": "0x32edbfe5", "imm2": "0x425604f3", "rot": 27, "bit": 0, "mask": 2}, + {"i": 279, "op": "sub", "dst": 1, "src": 2, "src2": 2, "imm": "0xa14d8329", "imm2": "0x76563fdc", "rot": 11, "bit": 15, "mask": 16}, + {"i": 280, "op": "xor", "dst": 5, "src": 1, "src2": 6, "imm": "0x31f1acee", "imm2": "0x3dd9ff3c", "rot": 29, "bit": 14, "mask": 2}, + {"i": 281, "op": "xor", "dst": 7, "src": 1, "src2": 2, "imm": "0x12c5cc61", "imm2": "0x85c81c12", "rot": 24, "bit": 25, "mask": 1}, + {"i": 282, "op": "sub", "dst": 7, "src": 1, "src2": 7, "imm": "0x25fe3b7a", "imm2": "0xe2aded20", "rot": 17, "bit": 21, "mask": 1}, + {"i": 283, "op": "sub", "dst": 5, "src": 7, "src2": 4, "imm": "0xfc658008", "imm2": "0x02d9e349", "rot": 28, "bit": 13, "mask": 2}, + {"i": 284, "op": "mad", "dst": 7, "src": 0, "src2": 6, "imm": "0xd2435da0", "imm2": "0x8bcecb5c", "rot": 9, "bit": 7, "mask": 1}, + {"i": 285, "op": "mulhi", "dst": 5, "src": 4, "src2": 7, "imm": "0x04018195", "imm2": "0x810e62c1", "rot": 20, "bit": 27, "mask": 2}, + {"i": 286, "op": "sub", "dst": 3, "src": 5, "src2": 6, "imm": "0x7f5964b2", "imm2": "0x5caa64ad", "rot": 3, "bit": 23, "mask": 2}, + {"i": 287, "op": "sub", "dst": 5, "src": 1, "src2": 4, "imm": "0x346b8fe0", "imm2": "0x1374019e", "rot": 6, "bit": 30, "mask": 16}, + {"i": 288, "op": "mad", "dst": 1, "src": 3, "src2": 7, "imm": "0xa16d82d7", "imm2": "0x7c95716a", "rot": 31, "bit": 19, "mask": 2}, + {"i": 289, "op": "rotl", "dst": 3, "src": 5, "src2": 6, "imm": "0x74b1e963", "imm2": "0xe769d2fb", "rot": 9, "bit": 9, "mask": 8}, + {"i": 290, "op": "shfl", "dst": 5, "src": 6, "src2": 1, "imm": "0xcf44c7e0", "imm2": "0x97dd693c", "rot": 11, "bit": 22, "mask": 8}, + {"i": 291, "op": "add", "dst": 7, "src": 2, "src2": 3, "imm": "0x2307120b", "imm2": "0xe086d3b6", "rot": 29, "bit": 1, "mask": 4}, + {"i": 292, "op": "xor", "dst": 4, "src": 3, "src2": 0, "imm": "0xdd7b41db", "imm2": "0x1f7af348", "rot": 15, "bit": 16, "mask": 2}, + {"i": 293, "op": "rotl", "dst": 3, "src": 0, "src2": 6, "imm": "0xf7104409", "imm2": "0x7a289394", "rot": 14, "bit": 3, "mask": 2}, + {"i": 294, "op": "sub", "dst": 5, "src": 4, "src2": 3, "imm": "0xc5763d15", "imm2": "0x5fa7e358", "rot": 2, "bit": 19, "mask": 16}, + {"i": 295, "op": "mulhi", "dst": 2, "src": 3, "src2": 1, "imm": "0x5f13e6f9", "imm2": "0xc3fa6489", "rot": 6, "bit": 9, "mask": 4}, + {"i": 296, "op": "shfl", "dst": 1, "src": 3, "src2": 7, "imm": "0x1188ff3a", "imm2": "0x074aa708", "rot": 27, "bit": 8, "mask": 4}, + {"i": 297, "op": "mad", "dst": 3, "src": 6, "src2": 1, "imm": "0xce9bed04", "imm2": "0x0253b354", "rot": 20, "bit": 23, "mask": 8}, + {"i": 298, "op": "xor", "dst": 4, "src": 1, "src2": 3, "imm": "0x6fb53f58", "imm2": "0x0646f340", "rot": 19, "bit": 1, "mask": 2}, + {"i": 299, "op": "add", "dst": 6, "src": 3, "src2": 0, "imm": "0x4e3a12e5", "imm2": "0xadbeb223", "rot": 14, "bit": 24, "mask": 2}, + {"i": 300, "op": "mulhi", "dst": 6, "src": 5, "src2": 6, "imm": "0x5d60250c", "imm2": "0x47935a9b", "rot": 9, "bit": 12, "mask": 16}, + {"i": 301, "op": "rotr", "dst": 7, "src": 5, "src2": 4, "imm": "0x08d97c7f", "imm2": "0xb4c46177", "rot": 30, "bit": 20, "mask": 2}, + {"i": 302, "op": "shfl", "dst": 5, "src": 4, "src2": 1, "imm": "0x585f2565", "imm2": "0x2d9e7777", "rot": 24, "bit": 10, "mask": 16}, + {"i": 303, "op": "xor", "dst": 3, "src": 4, "src2": 6, "imm": "0xe67277bb", "imm2": "0x319a6450", "rot": 26, "bit": 4, "mask": 4}, + {"i": 304, "op": "mad", "dst": 2, "src": 3, "src2": 1, "imm": "0x72ceeddf", "imm2": "0x1f121773", "rot": 3, "bit": 7, "mask": 1}, + {"i": 305, "op": "xor", "dst": 1, "src": 7, "src2": 0, "imm": "0xc6229ffd", "imm2": "0xe1a6c573", "rot": 21, "bit": 27, "mask": 8}, + {"i": 306, "op": "add", "dst": 1, "src": 0, "src2": 1, "imm": "0x51ab0157", "imm2": "0x0d8f1149", "rot": 19, "bit": 22, "mask": 4}, + {"i": 307, "op": "add", "dst": 2, "src": 1, "src2": 0, "imm": "0x3b5e8835", "imm2": "0x99a96de9", "rot": 14, "bit": 24, "mask": 1}, + {"i": 308, "op": "mad", "dst": 1, "src": 5, "src2": 5, "imm": "0x50f7ced3", "imm2": "0xe5d6aebd", "rot": 10, "bit": 29, "mask": 1}, + {"i": 309, "op": "mul", "dst": 2, "src": 4, "src2": 2, "imm": "0x87903fc4", "imm2": "0xe02c7d63", "rot": 11, "bit": 10, "mask": 16}, + {"i": 310, "op": "shfl", "dst": 3, "src": 7, "src2": 0, "imm": "0xbc6250f4", "imm2": "0x00119753", "rot": 15, "bit": 1, "mask": 8}, + {"i": 311, "op": "xor", "dst": 0, "src": 4, "src2": 1, "imm": "0x5469370e", "imm2": "0x850e5085", "rot": 30, "bit": 17, "mask": 1}, + {"i": 312, "op": "mulhi", "dst": 5, "src": 2, "src2": 4, "imm": "0xc9a9f0aa", "imm2": "0xe1b8b2a2", "rot": 25, "bit": 10, "mask": 16}, + {"i": 313, "op": "add", "dst": 7, "src": 2, "src2": 5, "imm": "0x81f3297c", "imm2": "0x86ddfba7", "rot": 25, "bit": 30, "mask": 4}, + {"i": 314, "op": "add", "dst": 3, "src": 1, "src2": 4, "imm": "0x838e4a2f", "imm2": "0x38aa230a", "rot": 23, "bit": 0, "mask": 8}, + {"i": 315, "op": "shfl", "dst": 7, "src": 0, "src2": 7, "imm": "0x382e2e2b", "imm2": "0x0e8c2364", "rot": 9, "bit": 13, "mask": 16}, + {"i": 316, "op": "sub", "dst": 7, "src": 5, "src2": 0, "imm": "0x114dbd92", "imm2": "0x043e7bb7", "rot": 27, "bit": 5, "mask": 1}, + {"i": 317, "op": "shfl", "dst": 5, "src": 1, "src2": 0, "imm": "0x7499a038", "imm2": "0x46c8223d", "rot": 18, "bit": 9, "mask": 4}, + {"i": 318, "op": "add", "dst": 1, "src": 3, "src2": 3, "imm": "0xebcad805", "imm2": "0xa6399179", "rot": 8, "bit": 11, "mask": 16}, + {"i": 319, "op": "rotl", "dst": 7, "src": 0, "src2": 2, "imm": "0xc7c099aa", "imm2": "0x1cc9fd54", "rot": 21, "bit": 3, "mask": 16}, + {"i": 320, "op": "xor", "dst": 7, "src": 6, "src2": 7, "imm": "0x269254de", "imm2": "0x79f7b26c", "rot": 25, "bit": 3, "mask": 1}, + {"i": 321, "op": "or", "dst": 7, "src": 6, "src2": 5, "imm": "0x8acb7150", "imm2": "0xe4d0562f", "rot": 2, "bit": 23, "mask": 1}, + {"i": 322, "op": "add", "dst": 5, "src": 3, "src2": 1, "imm": "0x4c906f73", "imm2": "0x4de83051", "rot": 31, "bit": 25, "mask": 2}, + {"i": 323, "op": "add", "dst": 0, "src": 4, "src2": 4, "imm": "0x742ec195", "imm2": "0xd3d821c5", "rot": 30, "bit": 14, "mask": 1}, + {"i": 324, "op": "xor", "dst": 6, "src": 2, "src2": 1, "imm": "0x52dcbf95", "imm2": "0x145e5001", "rot": 31, "bit": 27, "mask": 8}, + {"i": 325, "op": "rotl", "dst": 6, "src": 7, "src2": 5, "imm": "0xba6e5639", "imm2": "0x22461fb0", "rot": 1, "bit": 19, "mask": 4}, + {"i": 326, "op": "rotl", "dst": 4, "src": 2, "src2": 3, "imm": "0x693b1238", "imm2": "0xf9a31a2a", "rot": 24, "bit": 28, "mask": 8}, + {"i": 327, "op": "or", "dst": 4, "src": 3, "src2": 3, "imm": "0xc9a52ab2", "imm2": "0x65347c34", "rot": 7, "bit": 17, "mask": 1}, + {"i": 328, "op": "mad", "dst": 2, "src": 1, "src2": 3, "imm": "0x983527d7", "imm2": "0xe8705b7d", "rot": 23, "bit": 10, "mask": 4}, + {"i": 329, "op": "xor", "dst": 2, "src": 7, "src2": 7, "imm": "0xb2c91428", "imm2": "0xd713ec2f", "rot": 16, "bit": 22, "mask": 2}, + {"i": 330, "op": "or", "dst": 2, "src": 3, "src2": 3, "imm": "0x82e7f51e", "imm2": "0xd888464c", "rot": 14, "bit": 12, "mask": 16}, + {"i": 331, "op": "sub", "dst": 7, "src": 1, "src2": 0, "imm": "0x6b30cbc3", "imm2": "0xe490c0ba", "rot": 22, "bit": 25, "mask": 4}, + {"i": 332, "op": "add", "dst": 3, "src": 6, "src2": 7, "imm": "0xb86750e9", "imm2": "0xc06f831e", "rot": 13, "bit": 0, "mask": 1}, + {"i": 333, "op": "rotl", "dst": 7, "src": 5, "src2": 4, "imm": "0xebfc6b23", "imm2": "0x7f122d3f", "rot": 25, "bit": 30, "mask": 16}, + {"i": 334, "op": "mad", "dst": 3, "src": 0, "src2": 0, "imm": "0x26d93415", "imm2": "0x18c6bb67", "rot": 14, "bit": 31, "mask": 4}, + {"i": 335, "op": "add", "dst": 2, "src": 5, "src2": 5, "imm": "0xb57956ee", "imm2": "0x5225df1d", "rot": 1, "bit": 28, "mask": 8}, + {"i": 336, "op": "mad", "dst": 3, "src": 1, "src2": 6, "imm": "0x94961cbe", "imm2": "0x194b0ece", "rot": 18, "bit": 30, "mask": 16}, + {"i": 337, "op": "mad", "dst": 4, "src": 2, "src2": 2, "imm": "0xaf18ea17", "imm2": "0x6697c57a", "rot": 23, "bit": 23, "mask": 1}, + {"i": 338, "op": "mul", "dst": 7, "src": 2, "src2": 3, "imm": "0xb13a5eea", "imm2": "0xd380c60b", "rot": 8, "bit": 2, "mask": 1}, + {"i": 339, "op": "mul", "dst": 1, "src": 6, "src2": 6, "imm": "0x5cb5d0ae", "imm2": "0x5d1154a9", "rot": 26, "bit": 24, "mask": 2}, + {"i": 340, "op": "add", "dst": 4, "src": 5, "src2": 2, "imm": "0x23f6425f", "imm2": "0xb73822ce", "rot": 17, "bit": 5, "mask": 8}, + {"i": 341, "op": "shfl", "dst": 5, "src": 7, "src2": 5, "imm": "0x1cf83f2e", "imm2": "0xfe83f5c7", "rot": 3, "bit": 4, "mask": 2}, + {"i": 342, "op": "xor", "dst": 6, "src": 5, "src2": 5, "imm": "0x9779a4da", "imm2": "0x811f8d46", "rot": 5, "bit": 13, "mask": 2}, + {"i": 343, "op": "rotl", "dst": 0, "src": 5, "src2": 1, "imm": "0xe2670d3b", "imm2": "0x934e289a", "rot": 13, "bit": 1, "mask": 2}, + {"i": 344, "op": "rotr", "dst": 0, "src": 3, "src2": 1, "imm": "0x37ac7f2c", "imm2": "0x1b9b8e86", "rot": 27, "bit": 17, "mask": 8}, + {"i": 345, "op": "sub", "dst": 1, "src": 0, "src2": 1, "imm": "0x13e19779", "imm2": "0xfb4b499a", "rot": 12, "bit": 17, "mask": 16}, + {"i": 346, "op": "rotr", "dst": 6, "src": 1, "src2": 5, "imm": "0x2980da20", "imm2": "0x8c5b5b2a", "rot": 9, "bit": 7, "mask": 1}, + {"i": 347, "op": "shfl", "dst": 6, "src": 5, "src2": 7, "imm": "0x59164252", "imm2": "0xef759b2e", "rot": 29, "bit": 14, "mask": 4}, + {"i": 348, "op": "shfl", "dst": 5, "src": 1, "src2": 4, "imm": "0x3e6c9669", "imm2": "0x3d097f9d", "rot": 17, "bit": 1, "mask": 8}, + {"i": 349, "op": "xor", "dst": 5, "src": 3, "src2": 2, "imm": "0x33eaf5e4", "imm2": "0xb6e426fd", "rot": 3, "bit": 23, "mask": 1}, + {"i": 350, "op": "mad", "dst": 1, "src": 4, "src2": 0, "imm": "0x14117207", "imm2": "0xccca561f", "rot": 26, "bit": 28, "mask": 8}, + {"i": 351, "op": "rotr", "dst": 3, "src": 1, "src2": 2, "imm": "0xa5d142cc", "imm2": "0x782af6db", "rot": 30, "bit": 23, "mask": 2}, + {"i": 352, "op": "rotl", "dst": 1, "src": 4, "src2": 2, "imm": "0xf5702db7", "imm2": "0x4546a982", "rot": 13, "bit": 30, "mask": 16}, + {"i": 353, "op": "add", "dst": 3, "src": 0, "src2": 1, "imm": "0x0dce5917", "imm2": "0xfa0c560e", "rot": 29, "bit": 26, "mask": 16}, + {"i": 354, "op": "mulhi", "dst": 3, "src": 2, "src2": 2, "imm": "0x70705f32", "imm2": "0xf0bb1e75", "rot": 22, "bit": 19, "mask": 2}, + {"i": 355, "op": "mad", "dst": 1, "src": 2, "src2": 4, "imm": "0x084a9636", "imm2": "0x58499400", "rot": 17, "bit": 6, "mask": 8}, + {"i": 356, "op": "xor", "dst": 0, "src": 1, "src2": 1, "imm": "0xcc0b9074", "imm2": "0x2a92c957", "rot": 8, "bit": 11, "mask": 16}, + {"i": 357, "op": "mul", "dst": 7, "src": 5, "src2": 0, "imm": "0x1c89426c", "imm2": "0x512458ef", "rot": 5, "bit": 4, "mask": 16}, + {"i": 358, "op": "rotl", "dst": 0, "src": 3, "src2": 5, "imm": "0x9749818a", "imm2": "0xf45e94ce", "rot": 5, "bit": 8, "mask": 16}, + {"i": 359, "op": "mad", "dst": 2, "src": 7, "src2": 7, "imm": "0x9223a189", "imm2": "0xe1483551", "rot": 28, "bit": 20, "mask": 4}, + {"i": 360, "op": "or", "dst": 2, "src": 6, "src2": 0, "imm": "0x99260432", "imm2": "0x26ebef4f", "rot": 4, "bit": 23, "mask": 8}, + {"i": 361, "op": "add", "dst": 6, "src": 1, "src2": 2, "imm": "0x7c83b79a", "imm2": "0x277e027a", "rot": 2, "bit": 19, "mask": 1}, + {"i": 362, "op": "mul", "dst": 0, "src": 2, "src2": 5, "imm": "0xbd084605", "imm2": "0x6e90e7ea", "rot": 9, "bit": 24, "mask": 2}, + {"i": 363, "op": "mul", "dst": 3, "src": 6, "src2": 5, "imm": "0x59051f01", "imm2": "0xe8281d9a", "rot": 23, "bit": 29, "mask": 4}, + {"i": 364, "op": "rotr", "dst": 2, "src": 4, "src2": 5, "imm": "0x5bdf0bfb", "imm2": "0xbbf28336", "rot": 17, "bit": 16, "mask": 8}, + {"i": 365, "op": "add", "dst": 5, "src": 1, "src2": 1, "imm": "0x271f2385", "imm2": "0x52275ea4", "rot": 15, "bit": 1, "mask": 4}, + {"i": 366, "op": "mul", "dst": 1, "src": 6, "src2": 7, "imm": "0x7c3f97d8", "imm2": "0x26e125b2", "rot": 27, "bit": 1, "mask": 16}, + {"i": 367, "op": "add", "dst": 0, "src": 7, "src2": 7, "imm": "0x4c66800f", "imm2": "0x8f8b4093", "rot": 31, "bit": 30, "mask": 8}, + {"i": 368, "op": "rotr", "dst": 4, "src": 0, "src2": 5, "imm": "0xa2cfa725", "imm2": "0x399a8492", "rot": 26, "bit": 30, "mask": 16}, + {"i": 369, "op": "rotr", "dst": 4, "src": 0, "src2": 2, "imm": "0x33af20e7", "imm2": "0xa5d790da", "rot": 8, "bit": 17, "mask": 16}, + {"i": 370, "op": "mad", "dst": 1, "src": 0, "src2": 6, "imm": "0xa04407dd", "imm2": "0x4a76c510", "rot": 3, "bit": 4, "mask": 1}, + {"i": 371, "op": "sub", "dst": 0, "src": 5, "src2": 5, "imm": "0xdd487a69", "imm2": "0xf2f3bea3", "rot": 16, "bit": 23, "mask": 8}, + {"i": 372, "op": "add", "dst": 7, "src": 2, "src2": 4, "imm": "0x7dad1ed5", "imm2": "0x9a7dcadc", "rot": 9, "bit": 11, "mask": 1}, + {"i": 373, "op": "add", "dst": 7, "src": 3, "src2": 1, "imm": "0x1ea3d58e", "imm2": "0xf808c195", "rot": 23, "bit": 20, "mask": 2}, + {"i": 374, "op": "mul", "dst": 1, "src": 2, "src2": 5, "imm": "0xe3638b23", "imm2": "0xa4451970", "rot": 17, "bit": 18, "mask": 16}, + {"i": 375, "op": "mad", "dst": 3, "src": 7, "src2": 2, "imm": "0x47de145c", "imm2": "0xd3ecaf79", "rot": 4, "bit": 14, "mask": 2}, + {"i": 376, "op": "xor", "dst": 4, "src": 1, "src2": 3, "imm": "0x8f9e1f9c", "imm2": "0xf17569f8", "rot": 14, "bit": 15, "mask": 16}, + {"i": 377, "op": "or", "dst": 1, "src": 0, "src2": 6, "imm": "0xc7782a8e", "imm2": "0xe97b63f5", "rot": 25, "bit": 6, "mask": 4}, + {"i": 378, "op": "add", "dst": 5, "src": 0, "src2": 5, "imm": "0x98b36d10", "imm2": "0x427ed5ce", "rot": 14, "bit": 26, "mask": 1}, + {"i": 379, "op": "mul", "dst": 6, "src": 0, "src2": 6, "imm": "0xc721a62d", "imm2": "0xac48f8b1", "rot": 10, "bit": 29, "mask": 8}, + {"i": 380, "op": "shfl", "dst": 7, "src": 3, "src2": 0, "imm": "0x5669be9a", "imm2": "0xda716313", "rot": 2, "bit": 16, "mask": 1}, + {"i": 381, "op": "add", "dst": 4, "src": 0, "src2": 0, "imm": "0xb19cab2d", "imm2": "0x38f848b9", "rot": 21, "bit": 18, "mask": 1}, + {"i": 382, "op": "mad", "dst": 3, "src": 5, "src2": 2, "imm": "0x109a4f9c", "imm2": "0xc3e783e5", "rot": 4, "bit": 11, "mask": 1}, + {"i": 383, "op": "or", "dst": 0, "src": 7, "src2": 4, "imm": "0x24222532", "imm2": "0xd22601b8", "rot": 12, "bit": 28, "mask": 1}, + {"i": 384, "op": "sub", "dst": 5, "src": 4, "src2": 4, "imm": "0x47edfb73", "imm2": "0x79c5bf97", "rot": 31, "bit": 10, "mask": 8}, + {"i": 385, "op": "sub", "dst": 1, "src": 5, "src2": 7, "imm": "0x5624a08b", "imm2": "0x73983aac", "rot": 15, "bit": 4, "mask": 16}, + {"i": 386, "op": "sub", "dst": 2, "src": 0, "src2": 6, "imm": "0xf26d88b2", "imm2": "0xa457a732", "rot": 26, "bit": 25, "mask": 2}, + {"i": 387, "op": "add", "dst": 5, "src": 2, "src2": 3, "imm": "0x341056b0", "imm2": "0xffc20cf8", "rot": 29, "bit": 17, "mask": 2}, + {"i": 388, "op": "rotl", "dst": 1, "src": 0, "src2": 0, "imm": "0xb6b929b5", "imm2": "0x7b5551e1", "rot": 26, "bit": 12, "mask": 1}, + {"i": 389, "op": "xor", "dst": 2, "src": 5, "src2": 7, "imm": "0x24be9746", "imm2": "0x2727c7c7", "rot": 25, "bit": 22, "mask": 2}, + {"i": 390, "op": "mad", "dst": 5, "src": 7, "src2": 0, "imm": "0x79e4daf7", "imm2": "0xc02263ff", "rot": 19, "bit": 25, "mask": 2}, + {"i": 391, "op": "mulhi", "dst": 3, "src": 2, "src2": 7, "imm": "0x744fd092", "imm2": "0x694ae6d2", "rot": 10, "bit": 24, "mask": 8}, + {"i": 392, "op": "add", "dst": 5, "src": 4, "src2": 6, "imm": "0x78aa571a", "imm2": "0xfb939f2b", "rot": 24, "bit": 0, "mask": 8}, + {"i": 393, "op": "or", "dst": 5, "src": 2, "src2": 3, "imm": "0x71fa0375", "imm2": "0xc25f6314", "rot": 23, "bit": 29, "mask": 1}, + {"i": 394, "op": "mulhi", "dst": 1, "src": 7, "src2": 1, "imm": "0xe1b708c4", "imm2": "0xcbbc3934", "rot": 27, "bit": 10, "mask": 16}, + {"i": 395, "op": "sub", "dst": 4, "src": 2, "src2": 4, "imm": "0xc8aa19ab", "imm2": "0x6e096c30", "rot": 2, "bit": 30, "mask": 16}, + {"i": 396, "op": "sub", "dst": 7, "src": 1, "src2": 4, "imm": "0xe29d1a9d", "imm2": "0xfcaa783e", "rot": 10, "bit": 23, "mask": 8}, + {"i": 397, "op": "add", "dst": 0, "src": 1, "src2": 0, "imm": "0x31af4767", "imm2": "0xa9c6c9fb", "rot": 7, "bit": 2, "mask": 1}, + {"i": 398, "op": "mul", "dst": 3, "src": 1, "src2": 2, "imm": "0x9de6d852", "imm2": "0x2f02513b", "rot": 3, "bit": 12, "mask": 4}, + {"i": 399, "op": "sub", "dst": 1, "src": 7, "src2": 3, "imm": "0x86b918d2", "imm2": "0x6e3ec3e5", "rot": 3, "bit": 9, "mask": 8}, + {"i": 400, "op": "add", "dst": 7, "src": 6, "src2": 2, "imm": "0x266d4c34", "imm2": "0x34f9b056", "rot": 1, "bit": 8, "mask": 2}, + {"i": 401, "op": "rotl", "dst": 5, "src": 6, "src2": 0, "imm": "0x128e82f3", "imm2": "0xc3076761", "rot": 5, "bit": 14, "mask": 1}, + {"i": 402, "op": "add", "dst": 0, "src": 4, "src2": 4, "imm": "0x7241955e", "imm2": "0x79822c64", "rot": 21, "bit": 23, "mask": 2}, + {"i": 403, "op": "mad", "dst": 2, "src": 4, "src2": 0, "imm": "0x2f397fbc", "imm2": "0xdf8f2087", "rot": 22, "bit": 4, "mask": 16}, + {"i": 404, "op": "rotl", "dst": 5, "src": 4, "src2": 4, "imm": "0xd42f308b", "imm2": "0xea85d927", "rot": 29, "bit": 1, "mask": 4}, + {"i": 405, "op": "sub", "dst": 3, "src": 5, "src2": 6, "imm": "0x26507b81", "imm2": "0x7b1e276c", "rot": 24, "bit": 18, "mask": 16}, + {"i": 406, "op": "add", "dst": 2, "src": 3, "src2": 4, "imm": "0xf65aca5d", "imm2": "0xda046091", "rot": 18, "bit": 27, "mask": 16}, + {"i": 407, "op": "mulhi", "dst": 4, "src": 7, "src2": 3, "imm": "0x76bf76f4", "imm2": "0xcec8debd", "rot": 10, "bit": 6, "mask": 4}, + {"i": 408, "op": "add", "dst": 2, "src": 1, "src2": 4, "imm": "0x6a00cefb", "imm2": "0x167aba1c", "rot": 28, "bit": 14, "mask": 2}, + {"i": 409, "op": "mad", "dst": 2, "src": 6, "src2": 6, "imm": "0xdaf8d33d", "imm2": "0xcdb05e40", "rot": 17, "bit": 25, "mask": 8}, + {"i": 410, "op": "rotl", "dst": 6, "src": 0, "src2": 3, "imm": "0xa8a44f36", "imm2": "0x3592e6e8", "rot": 26, "bit": 24, "mask": 1}, + {"i": 411, "op": "or", "dst": 6, "src": 7, "src2": 3, "imm": "0x8eb4a6af", "imm2": "0x41bbd105", "rot": 13, "bit": 18, "mask": 1}, + {"i": 412, "op": "rotl", "dst": 1, "src": 6, "src2": 3, "imm": "0x58c0773d", "imm2": "0x1c9d6657", "rot": 20, "bit": 18, "mask": 1}, + {"i": 413, "op": "mul", "dst": 7, "src": 5, "src2": 7, "imm": "0xd7af150f", "imm2": "0x4fb32fb3", "rot": 1, "bit": 7, "mask": 8}, + {"i": 414, "op": "sub", "dst": 6, "src": 0, "src2": 3, "imm": "0x883e8c36", "imm2": "0x28ad73c6", "rot": 21, "bit": 27, "mask": 8}, + {"i": 415, "op": "mulhi", "dst": 6, "src": 0, "src2": 6, "imm": "0xfdb41fe6", "imm2": "0x728d5b85", "rot": 27, "bit": 22, "mask": 4}, + {"i": 416, "op": "rotl", "dst": 3, "src": 6, "src2": 3, "imm": "0xfe5a3df8", "imm2": "0x0e7f9b9e", "rot": 5, "bit": 0, "mask": 1}, + {"i": 417, "op": "shfl", "dst": 1, "src": 3, "src2": 7, "imm": "0x08d4b4e8", "imm2": "0x196a3353", "rot": 1, "bit": 25, "mask": 4}, + {"i": 418, "op": "mul", "dst": 0, "src": 4, "src2": 6, "imm": "0x3044d4c2", "imm2": "0xf4ab394b", "rot": 31, "bit": 30, "mask": 16}, + {"i": 419, "op": "rotr", "dst": 4, "src": 7, "src2": 1, "imm": "0x3d496070", "imm2": "0x603a15be", "rot": 6, "bit": 18, "mask": 2}, + {"i": 420, "op": "shfl", "dst": 7, "src": 1, "src2": 2, "imm": "0x3ec111f2", "imm2": "0x623a2d8e", "rot": 24, "bit": 0, "mask": 2}, + {"i": 421, "op": "mad", "dst": 5, "src": 3, "src2": 6, "imm": "0xe3f4edb4", "imm2": "0xb855fef3", "rot": 3, "bit": 14, "mask": 1}, + {"i": 422, "op": "xor", "dst": 3, "src": 4, "src2": 6, "imm": "0x70c11ede", "imm2": "0x14a21fcc", "rot": 9, "bit": 31, "mask": 1}, + {"i": 423, "op": "rotr", "dst": 3, "src": 7, "src2": 1, "imm": "0xd3ce5579", "imm2": "0xd4093564", "rot": 10, "bit": 8, "mask": 8}, + {"i": 424, "op": "add", "dst": 4, "src": 1, "src2": 5, "imm": "0xba29da18", "imm2": "0xbb669c17", "rot": 2, "bit": 26, "mask": 16}, + {"i": 425, "op": "rotr", "dst": 7, "src": 5, "src2": 7, "imm": "0xd8c884bc", "imm2": "0xe97a83d3", "rot": 29, "bit": 6, "mask": 8}, + {"i": 426, "op": "mul", "dst": 2, "src": 6, "src2": 7, "imm": "0xa15d3869", "imm2": "0xf533d4c7", "rot": 2, "bit": 9, "mask": 16}, + {"i": 427, "op": "add", "dst": 1, "src": 4, "src2": 6, "imm": "0x4f70e34f", "imm2": "0xc6b45a76", "rot": 4, "bit": 16, "mask": 8}, + {"i": 428, "op": "rotl", "dst": 1, "src": 3, "src2": 7, "imm": "0x953d806a", "imm2": "0x9dad8d45", "rot": 1, "bit": 19, "mask": 4}, + {"i": 429, "op": "mulhi", "dst": 6, "src": 5, "src2": 7, "imm": "0x8bde786b", "imm2": "0xe88755b6", "rot": 23, "bit": 8, "mask": 4}, + {"i": 430, "op": "add", "dst": 6, "src": 7, "src2": 7, "imm": "0x3883e0f5", "imm2": "0xff610984", "rot": 2, "bit": 12, "mask": 1}, + {"i": 431, "op": "or", "dst": 4, "src": 3, "src2": 0, "imm": "0x903158c4", "imm2": "0x490b04a3", "rot": 29, "bit": 31, "mask": 16}, + {"i": 432, "op": "xor", "dst": 7, "src": 5, "src2": 6, "imm": "0x15a9c6b4", "imm2": "0x7fba27c1", "rot": 21, "bit": 27, "mask": 8}, + {"i": 433, "op": "mulhi", "dst": 3, "src": 2, "src2": 1, "imm": "0x6cdeba62", "imm2": "0x268dbc8e", "rot": 21, "bit": 16, "mask": 16}, + {"i": 434, "op": "xor", "dst": 2, "src": 6, "src2": 0, "imm": "0x01e8f4f4", "imm2": "0xe6f6f9b9", "rot": 27, "bit": 18, "mask": 2}, + {"i": 435, "op": "or", "dst": 4, "src": 3, "src2": 3, "imm": "0x12bdbb87", "imm2": "0xd50f83c3", "rot": 20, "bit": 18, "mask": 16}, + {"i": 436, "op": "add", "dst": 0, "src": 1, "src2": 7, "imm": "0xb1b15861", "imm2": "0xf37057fe", "rot": 27, "bit": 9, "mask": 16}, + {"i": 437, "op": "add", "dst": 7, "src": 4, "src2": 1, "imm": "0x2e9e173f", "imm2": "0x61793eaf", "rot": 2, "bit": 4, "mask": 16}, + {"i": 438, "op": "shfl", "dst": 5, "src": 1, "src2": 7, "imm": "0x2e571a62", "imm2": "0x6936fadb", "rot": 27, "bit": 9, "mask": 1}, + {"i": 439, "op": "mad", "dst": 6, "src": 0, "src2": 3, "imm": "0x512e8633", "imm2": "0xb4212462", "rot": 9, "bit": 1, "mask": 8}, + {"i": 440, "op": "xor", "dst": 5, "src": 2, "src2": 6, "imm": "0xdce4dbb6", "imm2": "0xc7e4d408", "rot": 17, "bit": 26, "mask": 8}, + {"i": 441, "op": "shfl", "dst": 0, "src": 4, "src2": 6, "imm": "0x7aa6c0f0", "imm2": "0x3e44e559", "rot": 20, "bit": 30, "mask": 16}, + {"i": 442, "op": "mul", "dst": 6, "src": 3, "src2": 3, "imm": "0xdee751e1", "imm2": "0x5653d024", "rot": 18, "bit": 8, "mask": 16}, + {"i": 443, "op": "sub", "dst": 5, "src": 4, "src2": 0, "imm": "0x5c0fe165", "imm2": "0xd77511f3", "rot": 21, "bit": 17, "mask": 4}, + {"i": 444, "op": "shfl", "dst": 2, "src": 1, "src2": 7, "imm": "0xf03c5c15", "imm2": "0x0c1aa93b", "rot": 19, "bit": 2, "mask": 4}, + {"i": 445, "op": "add", "dst": 0, "src": 5, "src2": 6, "imm": "0x646856aa", "imm2": "0x69def831", "rot": 1, "bit": 12, "mask": 1}, + {"i": 446, "op": "add", "dst": 4, "src": 6, "src2": 3, "imm": "0x58a3f8fc", "imm2": "0x1f8ecb8b", "rot": 5, "bit": 23, "mask": 8}, + {"i": 447, "op": "mad", "dst": 4, "src": 0, "src2": 2, "imm": "0x83bd3431", "imm2": "0xfcc98d58", "rot": 5, "bit": 4, "mask": 2}, + {"i": 448, "op": "mul", "dst": 5, "src": 0, "src2": 0, "imm": "0x3e2fe0c8", "imm2": "0xf7eb98d7", "rot": 4, "bit": 27, "mask": 4}, + {"i": 449, "op": "add", "dst": 2, "src": 5, "src2": 7, "imm": "0x48d3062d", "imm2": "0x7ecb876d", "rot": 12, "bit": 11, "mask": 4}, + {"i": 450, "op": "mad", "dst": 2, "src": 5, "src2": 6, "imm": "0x038504c6", "imm2": "0xec1e05d5", "rot": 1, "bit": 3, "mask": 16}, + {"i": 451, "op": "shfl", "dst": 7, "src": 3, "src2": 2, "imm": "0xd0adce40", "imm2": "0x5b9e3fa4", "rot": 27, "bit": 17, "mask": 4}, + {"i": 452, "op": "mul", "dst": 2, "src": 5, "src2": 2, "imm": "0x7845d0ef", "imm2": "0xae4bf9de", "rot": 30, "bit": 22, "mask": 16}, + {"i": 453, "op": "mulhi", "dst": 5, "src": 4, "src2": 5, "imm": "0x87d5ec4e", "imm2": "0xc3ceaca5", "rot": 3, "bit": 23, "mask": 4}, + {"i": 454, "op": "xor", "dst": 1, "src": 7, "src2": 5, "imm": "0xc8f9c542", "imm2": "0x6c3ae10f", "rot": 3, "bit": 27, "mask": 16}, + {"i": 455, "op": "mul", "dst": 2, "src": 7, "src2": 2, "imm": "0x285c679c", "imm2": "0x937169c4", "rot": 10, "bit": 10, "mask": 2}, + {"i": 456, "op": "mul", "dst": 1, "src": 3, "src2": 2, "imm": "0x3a2c6369", "imm2": "0xd14da825", "rot": 13, "bit": 17, "mask": 2}, + {"i": 457, "op": "mad", "dst": 3, "src": 6, "src2": 2, "imm": "0x96cafbf1", "imm2": "0x813e4998", "rot": 17, "bit": 25, "mask": 1}, + {"i": 458, "op": "sub", "dst": 7, "src": 0, "src2": 7, "imm": "0x0c35e8f0", "imm2": "0x982b0309", "rot": 14, "bit": 9, "mask": 8}, + {"i": 459, "op": "mad", "dst": 2, "src": 4, "src2": 5, "imm": "0xf30c9ad9", "imm2": "0x38eac074", "rot": 7, "bit": 4, "mask": 16}, + {"i": 460, "op": "rotl", "dst": 0, "src": 1, "src2": 1, "imm": "0xfa806b0b", "imm2": "0x8f35f3e8", "rot": 2, "bit": 16, "mask": 1}, + {"i": 461, "op": "xor", "dst": 4, "src": 2, "src2": 2, "imm": "0x7e3004b1", "imm2": "0xd045bae9", "rot": 25, "bit": 29, "mask": 4}, + {"i": 462, "op": "add", "dst": 4, "src": 0, "src2": 7, "imm": "0xb41dd69b", "imm2": "0x7b093757", "rot": 4, "bit": 18, "mask": 2}, + {"i": 463, "op": "add", "dst": 6, "src": 1, "src2": 2, "imm": "0xb042032e", "imm2": "0x916e1b7e", "rot": 20, "bit": 3, "mask": 16}, + {"i": 464, "op": "add", "dst": 2, "src": 6, "src2": 1, "imm": "0x4e68a2a0", "imm2": "0x6d42b978", "rot": 2, "bit": 8, "mask": 16}, + {"i": 465, "op": "sub", "dst": 3, "src": 2, "src2": 5, "imm": "0x6d2c28f7", "imm2": "0xe0e6bde5", "rot": 25, "bit": 26, "mask": 2}, + {"i": 466, "op": "mul", "dst": 2, "src": 5, "src2": 1, "imm": "0x6fdf0e76", "imm2": "0x3835e1d5", "rot": 10, "bit": 13, "mask": 4}, + {"i": 467, "op": "rotl", "dst": 7, "src": 4, "src2": 4, "imm": "0x76e50074", "imm2": "0xc1985d22", "rot": 28, "bit": 28, "mask": 4}, + {"i": 468, "op": "sub", "dst": 0, "src": 3, "src2": 5, "imm": "0xe8ebd254", "imm2": "0x2e36695a", "rot": 20, "bit": 30, "mask": 2}, + {"i": 469, "op": "mulhi", "dst": 7, "src": 2, "src2": 5, "imm": "0x6ac40d81", "imm2": "0x60f2273d", "rot": 20, "bit": 1, "mask": 2}, + {"i": 470, "op": "or", "dst": 7, "src": 6, "src2": 5, "imm": "0x40f8d884", "imm2": "0xcd1733a6", "rot": 3, "bit": 30, "mask": 16}, + {"i": 471, "op": "rotl", "dst": 7, "src": 0, "src2": 5, "imm": "0x2886c4f4", "imm2": "0xc5cbba75", "rot": 28, "bit": 30, "mask": 8}, + {"i": 472, "op": "mul", "dst": 0, "src": 6, "src2": 5, "imm": "0x8fa810c1", "imm2": "0x84895821", "rot": 30, "bit": 18, "mask": 8}, + {"i": 473, "op": "or", "dst": 2, "src": 1, "src2": 3, "imm": "0x497e5829", "imm2": "0x0f1fa2f4", "rot": 14, "bit": 7, "mask": 4}, + {"i": 474, "op": "add", "dst": 2, "src": 4, "src2": 5, "imm": "0x13ec3b3e", "imm2": "0x20c5276b", "rot": 12, "bit": 14, "mask": 1}, + {"i": 475, "op": "rotr", "dst": 2, "src": 6, "src2": 6, "imm": "0x716f6450", "imm2": "0xad824272", "rot": 18, "bit": 10, "mask": 16}, + {"i": 476, "op": "shfl", "dst": 6, "src": 0, "src2": 6, "imm": "0xd142aaeb", "imm2": "0x89499026", "rot": 13, "bit": 11, "mask": 16}, + {"i": 477, "op": "rotl", "dst": 2, "src": 0, "src2": 0, "imm": "0xab4c2d40", "imm2": "0x4f0bebf7", "rot": 15, "bit": 4, "mask": 4}, + {"i": 478, "op": "rotr", "dst": 5, "src": 4, "src2": 7, "imm": "0x816dcb53", "imm2": "0xe2ee112d", "rot": 30, "bit": 23, "mask": 2}, + {"i": 479, "op": "rotl", "dst": 3, "src": 4, "src2": 1, "imm": "0x1b80fc14", "imm2": "0xda59c226", "rot": 26, "bit": 7, "mask": 16}, + {"i": 480, "op": "or", "dst": 5, "src": 6, "src2": 3, "imm": "0x721b4791", "imm2": "0xfe66decd", "rot": 30, "bit": 19, "mask": 8}, + {"i": 481, "op": "rotl", "dst": 3, "src": 6, "src2": 2, "imm": "0xbbebd9b2", "imm2": "0x99be51ce", "rot": 29, "bit": 26, "mask": 2}, + {"i": 482, "op": "rotr", "dst": 0, "src": 7, "src2": 3, "imm": "0x934cf6d0", "imm2": "0x1cf46df7", "rot": 10, "bit": 25, "mask": 2}, + {"i": 483, "op": "sub", "dst": 1, "src": 0, "src2": 6, "imm": "0x367d30ff", "imm2": "0xa000523b", "rot": 10, "bit": 21, "mask": 16}, + {"i": 484, "op": "mad", "dst": 0, "src": 2, "src2": 5, "imm": "0x3bbd1924", "imm2": "0x76913df6", "rot": 30, "bit": 27, "mask": 1}, + {"i": 485, "op": "xor", "dst": 6, "src": 4, "src2": 2, "imm": "0xa3105346", "imm2": "0x9dec8a89", "rot": 5, "bit": 21, "mask": 2}, + {"i": 486, "op": "xor", "dst": 6, "src": 0, "src2": 3, "imm": "0x925ff08a", "imm2": "0xd52afd49", "rot": 29, "bit": 10, "mask": 2}, + {"i": 487, "op": "shfl", "dst": 3, "src": 7, "src2": 6, "imm": "0x428ec5cb", "imm2": "0x32f6d0e6", "rot": 27, "bit": 5, "mask": 4}, + {"i": 488, "op": "mulhi", "dst": 6, "src": 0, "src2": 4, "imm": "0x46773c9a", "imm2": "0xfaeee7d5", "rot": 21, "bit": 22, "mask": 8}, + {"i": 489, "op": "mul", "dst": 1, "src": 0, "src2": 0, "imm": "0x1bbff2c6", "imm2": "0x7fe4669d", "rot": 2, "bit": 8, "mask": 8}, + {"i": 490, "op": "xor", "dst": 3, "src": 6, "src2": 0, "imm": "0xb4033097", "imm2": "0xe74b5e67", "rot": 12, "bit": 26, "mask": 8}, + {"i": 491, "op": "mul", "dst": 3, "src": 6, "src2": 2, "imm": "0xd0d284fc", "imm2": "0xa2365b6a", "rot": 12, "bit": 15, "mask": 1}, + {"i": 492, "op": "mul", "dst": 0, "src": 3, "src2": 2, "imm": "0x0f522efb", "imm2": "0x83d67c65", "rot": 30, "bit": 1, "mask": 16}, + {"i": 493, "op": "or", "dst": 4, "src": 3, "src2": 2, "imm": "0x9b0a6c9c", "imm2": "0xf3a65de4", "rot": 27, "bit": 8, "mask": 4}, + {"i": 494, "op": "shfl", "dst": 0, "src": 5, "src2": 0, "imm": "0x207f17cb", "imm2": "0xdc6d0d71", "rot": 5, "bit": 30, "mask": 8}, + {"i": 495, "op": "shfl", "dst": 0, "src": 7, "src2": 0, "imm": "0x734cd334", "imm2": "0xec33010c", "rot": 22, "bit": 27, "mask": 16}, + {"i": 496, "op": "mad", "dst": 6, "src": 5, "src2": 2, "imm": "0x2feeeb18", "imm2": "0xb90432d6", "rot": 7, "bit": 24, "mask": 1}, + {"i": 497, "op": "mul", "dst": 5, "src": 6, "src2": 2, "imm": "0x17fe96ff", "imm2": "0xb1d6b338", "rot": 4, "bit": 15, "mask": 1}, + {"i": 498, "op": "xor", "dst": 3, "src": 1, "src2": 0, "imm": "0x23f7dbb6", "imm2": "0xbdf5c220", "rot": 21, "bit": 5, "mask": 4}, + {"i": 499, "op": "add", "dst": 0, "src": 1, "src2": 0, "imm": "0x53e99aca", "imm2": "0x19f4c710", "rot": 24, "bit": 20, "mask": 1}, + {"i": 500, "op": "mad", "dst": 6, "src": 5, "src2": 2, "imm": "0x45e40410", "imm2": "0x393faa48", "rot": 9, "bit": 8, "mask": 4}, + {"i": 501, "op": "shfl", "dst": 7, "src": 1, "src2": 4, "imm": "0x606133e9", "imm2": "0xc558e117", "rot": 23, "bit": 24, "mask": 4}, + {"i": 502, "op": "sub", "dst": 3, "src": 5, "src2": 4, "imm": "0xd7c3fe17", "imm2": "0xe45b0e40", "rot": 18, "bit": 0, "mask": 1}, + {"i": 503, "op": "rotl", "dst": 0, "src": 7, "src2": 5, "imm": "0x6b70bc12", "imm2": "0x4389e096", "rot": 8, "bit": 10, "mask": 2}, + {"i": 504, "op": "xor", "dst": 3, "src": 1, "src2": 2, "imm": "0xdbbb52ee", "imm2": "0x72832f97", "rot": 24, "bit": 26, "mask": 1}, + {"i": 505, "op": "add", "dst": 7, "src": 2, "src2": 4, "imm": "0x0867fe20", "imm2": "0x7a6ac7b5", "rot": 2, "bit": 6, "mask": 16}, + {"i": 506, "op": "shfl", "dst": 0, "src": 7, "src2": 2, "imm": "0x65376be1", "imm2": "0x3429185d", "rot": 13, "bit": 2, "mask": 2}, + {"i": 507, "op": "mul", "dst": 0, "src": 1, "src2": 1, "imm": "0xd6a0ba3b", "imm2": "0x86c07924", "rot": 4, "bit": 18, "mask": 1}, + {"i": 508, "op": "or", "dst": 6, "src": 5, "src2": 3, "imm": "0xa6df24ee", "imm2": "0x54cf118c", "rot": 17, "bit": 27, "mask": 1}, + {"i": 509, "op": "mul", "dst": 2, "src": 7, "src2": 6, "imm": "0xc003e06d", "imm2": "0xcb0c9f4d", "rot": 26, "bit": 15, "mask": 4}, + {"i": 510, "op": "add", "dst": 1, "src": 5, "src2": 6, "imm": "0xd7fdc3ec", "imm2": "0xd77f6a03", "rot": 6, "bit": 21, "mask": 1}, + {"i": 511, "op": "shfl", "dst": 3, "src": 7, "src2": 5, "imm": "0xc79b4541", "imm2": "0xaced4b3f", "rot": 7, "bit": 15, "mask": 8}, + {"i": 512, "op": "add", "dst": 6, "src": 3, "src2": 4, "imm": "0x297a096a", "imm2": "0x5c22b0b5", "rot": 10, "bit": 9, "mask": 8}, + {"i": 513, "op": "or", "dst": 7, "src": 0, "src2": 0, "imm": "0xfb7bbd16", "imm2": "0x51a26eb0", "rot": 1, "bit": 10, "mask": 2}, + {"i": 514, "op": "add", "dst": 7, "src": 3, "src2": 7, "imm": "0x5de1d1d1", "imm2": "0x4caafacd", "rot": 29, "bit": 27, "mask": 8}, + {"i": 515, "op": "mulhi", "dst": 1, "src": 0, "src2": 0, "imm": "0x922a5e81", "imm2": "0x80c6c55d", "rot": 25, "bit": 10, "mask": 1}, + {"i": 516, "op": "sub", "dst": 0, "src": 6, "src2": 1, "imm": "0x38387425", "imm2": "0xc6a7f43b", "rot": 14, "bit": 14, "mask": 8}, + {"i": 517, "op": "sub", "dst": 2, "src": 1, "src2": 3, "imm": "0xcc60b1dc", "imm2": "0xd5d6bd52", "rot": 12, "bit": 1, "mask": 16}, + {"i": 518, "op": "mad", "dst": 6, "src": 5, "src2": 7, "imm": "0x1818e2e7", "imm2": "0x378b9ef4", "rot": 22, "bit": 7, "mask": 4}, + {"i": 519, "op": "xor", "dst": 2, "src": 7, "src2": 4, "imm": "0x2bd927b7", "imm2": "0x427a5810", "rot": 19, "bit": 3, "mask": 2}, + {"i": 520, "op": "or", "dst": 1, "src": 5, "src2": 5, "imm": "0xe7b81de1", "imm2": "0xc5f2b3f7", "rot": 28, "bit": 21, "mask": 1}, + {"i": 521, "op": "mad", "dst": 0, "src": 4, "src2": 6, "imm": "0x76a00484", "imm2": "0xcfae93ac", "rot": 14, "bit": 16, "mask": 2}, + {"i": 522, "op": "add", "dst": 4, "src": 6, "src2": 0, "imm": "0x2caeeca3", "imm2": "0xb1091e80", "rot": 11, "bit": 29, "mask": 2}, + {"i": 523, "op": "mad", "dst": 7, "src": 6, "src2": 5, "imm": "0xe1c93303", "imm2": "0x92fca679", "rot": 28, "bit": 7, "mask": 1}, + {"i": 524, "op": "sub", "dst": 7, "src": 2, "src2": 7, "imm": "0xd4e1f467", "imm2": "0x3444a543", "rot": 28, "bit": 5, "mask": 4}, + {"i": 525, "op": "mul", "dst": 0, "src": 7, "src2": 1, "imm": "0x236ff5b2", "imm2": "0x12c4a077", "rot": 30, "bit": 18, "mask": 1}, + {"i": 526, "op": "xor", "dst": 0, "src": 7, "src2": 0, "imm": "0xfb4ab0e2", "imm2": "0x6319cc05", "rot": 6, "bit": 2, "mask": 16}, + {"i": 527, "op": "mulhi", "dst": 1, "src": 4, "src2": 2, "imm": "0x3a840c3c", "imm2": "0x2cf9a54d", "rot": 18, "bit": 26, "mask": 16}, + {"i": 528, "op": "rotr", "dst": 0, "src": 5, "src2": 3, "imm": "0x104a4e3e", "imm2": "0x7c89bf55", "rot": 31, "bit": 27, "mask": 1}, + {"i": 529, "op": "shfl", "dst": 2, "src": 7, "src2": 3, "imm": "0x0d6fe0a1", "imm2": "0x4fc13125", "rot": 19, "bit": 0, "mask": 16}, + {"i": 530, "op": "mulhi", "dst": 2, "src": 3, "src2": 7, "imm": "0xc1fa7155", "imm2": "0xb2e96581", "rot": 20, "bit": 18, "mask": 8}, + {"i": 531, "op": "or", "dst": 1, "src": 4, "src2": 0, "imm": "0xe9dcfcb5", "imm2": "0x4441cdcc", "rot": 2, "bit": 5, "mask": 4}, + {"i": 532, "op": "add", "dst": 6, "src": 4, "src2": 1, "imm": "0xbe9e1eb0", "imm2": "0xbda312ae", "rot": 1, "bit": 13, "mask": 2}, + {"i": 533, "op": "add", "dst": 7, "src": 2, "src2": 1, "imm": "0xbe5d93a3", "imm2": "0x1ec16229", "rot": 15, "bit": 6, "mask": 8}, + {"i": 534, "op": "mad", "dst": 0, "src": 6, "src2": 4, "imm": "0x3aef1a04", "imm2": "0x2a544680", "rot": 26, "bit": 29, "mask": 8}, + {"i": 535, "op": "add", "dst": 0, "src": 5, "src2": 7, "imm": "0x5e23583b", "imm2": "0x500828bc", "rot": 19, "bit": 23, "mask": 2}, + {"i": 536, "op": "mad", "dst": 6, "src": 5, "src2": 0, "imm": "0x731e069b", "imm2": "0xeb0ff2af", "rot": 14, "bit": 30, "mask": 16}, + {"i": 537, "op": "xor", "dst": 2, "src": 4, "src2": 5, "imm": "0xe97b6dfd", "imm2": "0x9ba2df12", "rot": 24, "bit": 24, "mask": 4}, + {"i": 538, "op": "mad", "dst": 6, "src": 3, "src2": 5, "imm": "0x46f47022", "imm2": "0x22517116", "rot": 22, "bit": 22, "mask": 4}, + {"i": 539, "op": "add", "dst": 6, "src": 4, "src2": 0, "imm": "0x43c32138", "imm2": "0x852321dc", "rot": 20, "bit": 3, "mask": 8}, + {"i": 540, "op": "add", "dst": 2, "src": 5, "src2": 1, "imm": "0xaff69493", "imm2": "0x44e6ae63", "rot": 11, "bit": 7, "mask": 2}, + {"i": 541, "op": "mulhi", "dst": 3, "src": 5, "src2": 0, "imm": "0x6c2dab8f", "imm2": "0xc73ea3a3", "rot": 1, "bit": 10, "mask": 2}, + {"i": 542, "op": "add", "dst": 1, "src": 7, "src2": 7, "imm": "0xc5de29ef", "imm2": "0x909712fe", "rot": 16, "bit": 5, "mask": 1}, + {"i": 543, "op": "mad", "dst": 1, "src": 3, "src2": 2, "imm": "0xa94d2524", "imm2": "0xc900e838", "rot": 14, "bit": 7, "mask": 2}, + {"i": 544, "op": "add", "dst": 1, "src": 3, "src2": 1, "imm": "0x1e20e084", "imm2": "0xfb7b42b9", "rot": 16, "bit": 11, "mask": 8}, + {"i": 545, "op": "shfl", "dst": 4, "src": 5, "src2": 1, "imm": "0xde11225f", "imm2": "0x6e67b341", "rot": 20, "bit": 28, "mask": 4}, + {"i": 546, "op": "add", "dst": 6, "src": 1, "src2": 3, "imm": "0x9370db38", "imm2": "0x6e036dd4", "rot": 14, "bit": 10, "mask": 4}, + {"i": 547, "op": "xor", "dst": 4, "src": 6, "src2": 5, "imm": "0xf83030f0", "imm2": "0x4e159cae", "rot": 17, "bit": 21, "mask": 4}, + {"i": 548, "op": "shfl", "dst": 5, "src": 3, "src2": 3, "imm": "0x877cae2d", "imm2": "0x52023f64", "rot": 22, "bit": 23, "mask": 8}, + {"i": 549, "op": "shfl", "dst": 3, "src": 5, "src2": 0, "imm": "0x3b3a0bbf", "imm2": "0x3d4563d9", "rot": 25, "bit": 23, "mask": 16}, + {"i": 550, "op": "rotr", "dst": 1, "src": 7, "src2": 0, "imm": "0x8caea2ed", "imm2": "0x04f96273", "rot": 30, "bit": 10, "mask": 8}, + {"i": 551, "op": "mad", "dst": 0, "src": 3, "src2": 2, "imm": "0xd444cf75", "imm2": "0xe469d995", "rot": 29, "bit": 27, "mask": 16}, + {"i": 552, "op": "mulhi", "dst": 7, "src": 4, "src2": 1, "imm": "0xd17927fe", "imm2": "0x332c3c9b", "rot": 4, "bit": 21, "mask": 16}, + {"i": 553, "op": "add", "dst": 0, "src": 4, "src2": 0, "imm": "0xbf2488f6", "imm2": "0xd3c9174d", "rot": 27, "bit": 13, "mask": 8}, + {"i": 554, "op": "rotl", "dst": 1, "src": 6, "src2": 6, "imm": "0xd1c03267", "imm2": "0x846dbd4f", "rot": 1, "bit": 16, "mask": 4}, + {"i": 555, "op": "rotr", "dst": 7, "src": 3, "src2": 1, "imm": "0x11400256", "imm2": "0x7122901b", "rot": 2, "bit": 22, "mask": 4}, + {"i": 556, "op": "rotr", "dst": 7, "src": 3, "src2": 5, "imm": "0x872805bd", "imm2": "0x98df839d", "rot": 8, "bit": 21, "mask": 4}, + {"i": 557, "op": "mad", "dst": 6, "src": 2, "src2": 0, "imm": "0xf9ccf1e6", "imm2": "0x8a5d9383", "rot": 5, "bit": 1, "mask": 16}, + {"i": 558, "op": "xor", "dst": 6, "src": 1, "src2": 3, "imm": "0xf4b9159d", "imm2": "0x465fe6ad", "rot": 23, "bit": 7, "mask": 4}, + {"i": 559, "op": "shfl", "dst": 5, "src": 1, "src2": 4, "imm": "0x5c3b6669", "imm2": "0x79a72c70", "rot": 2, "bit": 5, "mask": 2}, + {"i": 560, "op": "xor", "dst": 5, "src": 3, "src2": 7, "imm": "0x8bdd39d6", "imm2": "0x7b894927", "rot": 22, "bit": 10, "mask": 8}, + {"i": 561, "op": "mul", "dst": 5, "src": 1, "src2": 3, "imm": "0x31f97a4f", "imm2": "0x45ea59cc", "rot": 5, "bit": 9, "mask": 8}, + {"i": 562, "op": "rotl", "dst": 3, "src": 0, "src2": 3, "imm": "0x41afc563", "imm2": "0x02071ac4", "rot": 31, "bit": 6, "mask": 4}, + {"i": 563, "op": "rotr", "dst": 6, "src": 2, "src2": 7, "imm": "0x71553aea", "imm2": "0x23a2e574", "rot": 8, "bit": 13, "mask": 1}, + {"i": 564, "op": "or", "dst": 7, "src": 2, "src2": 1, "imm": "0x2f9da3c7", "imm2": "0x52bfb0f3", "rot": 27, "bit": 21, "mask": 8}, + {"i": 565, "op": "rotr", "dst": 6, "src": 0, "src2": 1, "imm": "0xd212fdeb", "imm2": "0xcb396389", "rot": 4, "bit": 19, "mask": 2}, + {"i": 566, "op": "mul", "dst": 2, "src": 0, "src2": 0, "imm": "0x49fb5e4e", "imm2": "0xac2fcd9f", "rot": 9, "bit": 3, "mask": 16}, + {"i": 567, "op": "shfl", "dst": 4, "src": 5, "src2": 5, "imm": "0x9bd8ced7", "imm2": "0xfe283d65", "rot": 6, "bit": 18, "mask": 2}, + {"i": 568, "op": "mul", "dst": 3, "src": 0, "src2": 6, "imm": "0x5a360650", "imm2": "0xbcd9e609", "rot": 18, "bit": 25, "mask": 16}, + {"i": 569, "op": "add", "dst": 4, "src": 2, "src2": 6, "imm": "0xd9160c83", "imm2": "0xa3149efa", "rot": 27, "bit": 9, "mask": 16}, + {"i": 570, "op": "mulhi", "dst": 4, "src": 2, "src2": 2, "imm": "0x9f09be0f", "imm2": "0x466e301c", "rot": 13, "bit": 14, "mask": 4}, + {"i": 571, "op": "add", "dst": 3, "src": 0, "src2": 1, "imm": "0x3bdc971c", "imm2": "0x9cab407b", "rot": 19, "bit": 10, "mask": 4}, + {"i": 572, "op": "shfl", "dst": 1, "src": 2, "src2": 5, "imm": "0x4fade3a3", "imm2": "0x8ef34eae", "rot": 28, "bit": 7, "mask": 16}, + {"i": 573, "op": "shfl", "dst": 2, "src": 5, "src2": 6, "imm": "0x0e517d2d", "imm2": "0xba76a591", "rot": 22, "bit": 29, "mask": 4}, + {"i": 574, "op": "shfl", "dst": 2, "src": 3, "src2": 6, "imm": "0x286875b9", "imm2": "0x0bdb47d1", "rot": 21, "bit": 2, "mask": 8}, + {"i": 575, "op": "xor", "dst": 0, "src": 7, "src2": 2, "imm": "0x1500d67e", "imm2": "0x9e79f315", "rot": 21, "bit": 26, "mask": 1}, + {"i": 576, "op": "add", "dst": 0, "src": 5, "src2": 6, "imm": "0x17979608", "imm2": "0x747b0838", "rot": 23, "bit": 27, "mask": 4}, + {"i": 577, "op": "xor", "dst": 0, "src": 4, "src2": 7, "imm": "0x0e6a3840", "imm2": "0xbd07779f", "rot": 4, "bit": 20, "mask": 4}, + {"i": 578, "op": "sub", "dst": 6, "src": 1, "src2": 5, "imm": "0x823f6f0a", "imm2": "0xdddffc63", "rot": 30, "bit": 4, "mask": 4}, + {"i": 579, "op": "rotr", "dst": 4, "src": 2, "src2": 7, "imm": "0x5d9c259c", "imm2": "0x6bc62224", "rot": 13, "bit": 27, "mask": 4}, + {"i": 580, "op": "xor", "dst": 2, "src": 3, "src2": 2, "imm": "0xa5cf94bb", "imm2": "0x29471928", "rot": 15, "bit": 18, "mask": 16}, + {"i": 581, "op": "mad", "dst": 6, "src": 7, "src2": 2, "imm": "0x6332ce35", "imm2": "0xcb2e7fcf", "rot": 18, "bit": 5, "mask": 2}, + {"i": 582, "op": "add", "dst": 5, "src": 2, "src2": 5, "imm": "0x1c10ec5c", "imm2": "0x02246c0c", "rot": 30, "bit": 7, "mask": 4}, + {"i": 583, "op": "mulhi", "dst": 3, "src": 6, "src2": 6, "imm": "0x5b6ab578", "imm2": "0x82443665", "rot": 5, "bit": 23, "mask": 8}, + {"i": 584, "op": "xor", "dst": 2, "src": 5, "src2": 7, "imm": "0x7714ead9", "imm2": "0xf7da87a0", "rot": 5, "bit": 1, "mask": 2}, + {"i": 585, "op": "rotl", "dst": 6, "src": 7, "src2": 2, "imm": "0x59077cfd", "imm2": "0xa5036d68", "rot": 24, "bit": 18, "mask": 1}, + {"i": 586, "op": "shfl", "dst": 3, "src": 5, "src2": 5, "imm": "0xbcf39b30", "imm2": "0x21e737e9", "rot": 10, "bit": 3, "mask": 8}, + {"i": 587, "op": "mad", "dst": 1, "src": 2, "src2": 6, "imm": "0x50a54f69", "imm2": "0x943f418c", "rot": 23, "bit": 30, "mask": 2}, + {"i": 588, "op": "add", "dst": 3, "src": 7, "src2": 6, "imm": "0x88758873", "imm2": "0xbea44bd0", "rot": 10, "bit": 21, "mask": 8}, + {"i": 589, "op": "rotl", "dst": 1, "src": 0, "src2": 4, "imm": "0x11a650a6", "imm2": "0x91e85fc1", "rot": 30, "bit": 9, "mask": 8}, + {"i": 590, "op": "mul", "dst": 7, "src": 1, "src2": 3, "imm": "0xfa67f5cf", "imm2": "0x9c09d91d", "rot": 3, "bit": 15, "mask": 4}, + {"i": 591, "op": "add", "dst": 3, "src": 6, "src2": 5, "imm": "0xf436bb64", "imm2": "0x8e0eb890", "rot": 6, "bit": 10, "mask": 8}, + {"i": 592, "op": "mad", "dst": 7, "src": 6, "src2": 1, "imm": "0x83a0cf83", "imm2": "0x44b9a85b", "rot": 31, "bit": 20, "mask": 1}, + {"i": 593, "op": "mad", "dst": 0, "src": 3, "src2": 5, "imm": "0x73831827", "imm2": "0xf8b28f3f", "rot": 31, "bit": 21, "mask": 1}, + {"i": 594, "op": "rotr", "dst": 5, "src": 4, "src2": 0, "imm": "0x09e97a46", "imm2": "0xc4989d7a", "rot": 31, "bit": 28, "mask": 16}, + {"i": 595, "op": "or", "dst": 4, "src": 0, "src2": 6, "imm": "0xef66d153", "imm2": "0x9daed6c6", "rot": 11, "bit": 15, "mask": 1}, + {"i": 596, "op": "mad", "dst": 6, "src": 3, "src2": 0, "imm": "0x55bea18c", "imm2": "0x08cedefe", "rot": 26, "bit": 27, "mask": 16}, + {"i": 597, "op": "add", "dst": 2, "src": 1, "src2": 2, "imm": "0xb465e47e", "imm2": "0x29b853b3", "rot": 2, "bit": 31, "mask": 1}, + {"i": 598, "op": "shfl", "dst": 1, "src": 7, "src2": 0, "imm": "0x3fcf63c8", "imm2": "0x1d2acdca", "rot": 12, "bit": 27, "mask": 16}, + {"i": 599, "op": "shfl", "dst": 4, "src": 0, "src2": 2, "imm": "0x6fbcc240", "imm2": "0xbd9bb818", "rot": 30, "bit": 19, "mask": 4}, + {"i": 600, "op": "mad", "dst": 6, "src": 2, "src2": 0, "imm": "0x5440cbbf", "imm2": "0x657402f1", "rot": 16, "bit": 7, "mask": 16}, + {"i": 601, "op": "mulhi", "dst": 5, "src": 0, "src2": 2, "imm": "0x8ff1058f", "imm2": "0x9c46832b", "rot": 28, "bit": 15, "mask": 4}, + {"i": 602, "op": "mul", "dst": 6, "src": 7, "src2": 4, "imm": "0x8c02251b", "imm2": "0x45a014c7", "rot": 13, "bit": 30, "mask": 2}, + {"i": 603, "op": "or", "dst": 4, "src": 7, "src2": 1, "imm": "0xb311fbe2", "imm2": "0xafd26cd9", "rot": 9, "bit": 31, "mask": 4}, + {"i": 604, "op": "sub", "dst": 7, "src": 0, "src2": 1, "imm": "0xc050a760", "imm2": "0xffdb9034", "rot": 18, "bit": 11, "mask": 4}, + {"i": 605, "op": "rotr", "dst": 7, "src": 4, "src2": 0, "imm": "0xb8593ab2", "imm2": "0x0daad0c4", "rot": 26, "bit": 28, "mask": 1}, + {"i": 606, "op": "mad", "dst": 4, "src": 0, "src2": 3, "imm": "0x0b542f60", "imm2": "0xa0abc1e9", "rot": 8, "bit": 20, "mask": 4}, + {"i": 607, "op": "mulhi", "dst": 4, "src": 3, "src2": 1, "imm": "0x27d8b89b", "imm2": "0x54951de3", "rot": 30, "bit": 14, "mask": 4}, + {"i": 608, "op": "add", "dst": 0, "src": 1, "src2": 5, "imm": "0x22ce199d", "imm2": "0xb7536963", "rot": 19, "bit": 28, "mask": 1}, + {"i": 609, "op": "sub", "dst": 2, "src": 5, "src2": 0, "imm": "0x60bd3a55", "imm2": "0x1c972c40", "rot": 9, "bit": 21, "mask": 2}, + {"i": 610, "op": "xor", "dst": 2, "src": 0, "src2": 1, "imm": "0x8df2761b", "imm2": "0x5ec9f9cf", "rot": 27, "bit": 14, "mask": 8}, + {"i": 611, "op": "mul", "dst": 5, "src": 4, "src2": 2, "imm": "0x665cb7e1", "imm2": "0x3ee9c4d5", "rot": 6, "bit": 13, "mask": 8}, + {"i": 612, "op": "rotl", "dst": 3, "src": 2, "src2": 4, "imm": "0x039bf24c", "imm2": "0x7014a699", "rot": 25, "bit": 14, "mask": 1}, + {"i": 613, "op": "rotl", "dst": 7, "src": 2, "src2": 0, "imm": "0xf1e7d1df", "imm2": "0xf550b5c3", "rot": 13, "bit": 2, "mask": 4}, + {"i": 614, "op": "mul", "dst": 4, "src": 7, "src2": 5, "imm": "0x56746a9c", "imm2": "0xd4f4d7f4", "rot": 27, "bit": 29, "mask": 16}, + {"i": 615, "op": "mad", "dst": 5, "src": 4, "src2": 2, "imm": "0x50c840dd", "imm2": "0xb8fa3fa0", "rot": 27, "bit": 21, "mask": 2}, + {"i": 616, "op": "xor", "dst": 0, "src": 5, "src2": 2, "imm": "0x66932e94", "imm2": "0xd5078a8b", "rot": 10, "bit": 0, "mask": 16}, + {"i": 617, "op": "mad", "dst": 7, "src": 5, "src2": 4, "imm": "0x0984691a", "imm2": "0x186e2513", "rot": 4, "bit": 13, "mask": 16}, + {"i": 618, "op": "sub", "dst": 6, "src": 4, "src2": 1, "imm": "0x942df8d4", "imm2": "0x4e24129e", "rot": 30, "bit": 7, "mask": 16}, + {"i": 619, "op": "mul", "dst": 3, "src": 4, "src2": 7, "imm": "0xe6b71548", "imm2": "0xfce9dba4", "rot": 1, "bit": 11, "mask": 8}, + {"i": 620, "op": "rotl", "dst": 1, "src": 5, "src2": 7, "imm": "0x8fad392b", "imm2": "0x3048d5e0", "rot": 24, "bit": 27, "mask": 16}, + {"i": 621, "op": "xor", "dst": 1, "src": 2, "src2": 3, "imm": "0x7452ec18", "imm2": "0x1d759604", "rot": 7, "bit": 19, "mask": 8}, + {"i": 622, "op": "or", "dst": 4, "src": 3, "src2": 4, "imm": "0x19b33aca", "imm2": "0x16237c50", "rot": 9, "bit": 29, "mask": 8}, + {"i": 623, "op": "mul", "dst": 7, "src": 2, "src2": 6, "imm": "0x7156d302", "imm2": "0x5e82d5c8", "rot": 21, "bit": 4, "mask": 8}, + {"i": 624, "op": "add", "dst": 6, "src": 1, "src2": 3, "imm": "0x2dbf6ed0", "imm2": "0xe37b1e20", "rot": 3, "bit": 20, "mask": 2}, + {"i": 625, "op": "xor", "dst": 4, "src": 5, "src2": 7, "imm": "0x9adfaf6b", "imm2": "0x0911c6e3", "rot": 1, "bit": 4, "mask": 4}, + {"i": 626, "op": "mad", "dst": 4, "src": 6, "src2": 2, "imm": "0x57c92dce", "imm2": "0x345788ff", "rot": 6, "bit": 8, "mask": 2}, + {"i": 627, "op": "xor", "dst": 1, "src": 6, "src2": 6, "imm": "0xf6749d59", "imm2": "0x466ad924", "rot": 13, "bit": 27, "mask": 1}, + {"i": 628, "op": "add", "dst": 6, "src": 3, "src2": 0, "imm": "0x9dc2b9d0", "imm2": "0xf5a2a9f7", "rot": 2, "bit": 12, "mask": 1}, + {"i": 629, "op": "sub", "dst": 7, "src": 5, "src2": 3, "imm": "0x49d053e2", "imm2": "0x4f3b4bbc", "rot": 6, "bit": 18, "mask": 16}, + {"i": 630, "op": "mulhi", "dst": 1, "src": 7, "src2": 6, "imm": "0x4e16d932", "imm2": "0x05d301c6", "rot": 20, "bit": 11, "mask": 16}, + {"i": 631, "op": "rotr", "dst": 1, "src": 3, "src2": 5, "imm": "0x2fbef1f3", "imm2": "0xaec90af4", "rot": 15, "bit": 11, "mask": 2}, + {"i": 632, "op": "or", "dst": 4, "src": 6, "src2": 6, "imm": "0x6076c434", "imm2": "0x44e87ab6", "rot": 2, "bit": 14, "mask": 1}, + {"i": 633, "op": "add", "dst": 2, "src": 5, "src2": 7, "imm": "0x9c1fba1b", "imm2": "0x982bfc08", "rot": 31, "bit": 24, "mask": 16}, + {"i": 634, "op": "mul", "dst": 6, "src": 5, "src2": 6, "imm": "0xd5ec0fa3", "imm2": "0x5a386421", "rot": 13, "bit": 3, "mask": 1}, + {"i": 635, "op": "mad", "dst": 7, "src": 2, "src2": 3, "imm": "0x9a914ec6", "imm2": "0x7b823439", "rot": 29, "bit": 13, "mask": 16}, + {"i": 636, "op": "mulhi", "dst": 7, "src": 4, "src2": 2, "imm": "0x51c909bb", "imm2": "0x606d962d", "rot": 31, "bit": 19, "mask": 8}, + {"i": 637, "op": "xor", "dst": 5, "src": 0, "src2": 1, "imm": "0x46b5b342", "imm2": "0xffcb803a", "rot": 30, "bit": 30, "mask": 2}, + {"i": 638, "op": "mul", "dst": 0, "src": 1, "src2": 1, "imm": "0x5163a0ce", "imm2": "0xe05f8044", "rot": 9, "bit": 8, "mask": 8}, + {"i": 639, "op": "xor", "dst": 4, "src": 6, "src2": 5, "imm": "0x54d29733", "imm2": "0x2d5950d3", "rot": 3, "bit": 6, "mask": 1}, + {"i": 640, "op": "sub", "dst": 6, "src": 4, "src2": 6, "imm": "0xc5d928e0", "imm2": "0x322de0bd", "rot": 27, "bit": 10, "mask": 4}, + {"i": 641, "op": "mulhi", "dst": 6, "src": 4, "src2": 0, "imm": "0x2b716915", "imm2": "0x8d150d0c", "rot": 29, "bit": 11, "mask": 16}, + {"i": 642, "op": "sub", "dst": 4, "src": 0, "src2": 5, "imm": "0xaf04f7f1", "imm2": "0x6f4fc24a", "rot": 19, "bit": 28, "mask": 1}, + {"i": 643, "op": "sub", "dst": 7, "src": 5, "src2": 6, "imm": "0xed652a97", "imm2": "0xcd337018", "rot": 15, "bit": 21, "mask": 16}, + {"i": 644, "op": "mad", "dst": 3, "src": 0, "src2": 7, "imm": "0x375d923a", "imm2": "0x7d21b100", "rot": 27, "bit": 26, "mask": 2}, + {"i": 645, "op": "or", "dst": 3, "src": 5, "src2": 5, "imm": "0x09c4b18d", "imm2": "0xbffc08e6", "rot": 20, "bit": 12, "mask": 16}, + {"i": 646, "op": "sub", "dst": 0, "src": 4, "src2": 0, "imm": "0x04aee077", "imm2": "0x5254cdd1", "rot": 31, "bit": 27, "mask": 4}, + {"i": 647, "op": "or", "dst": 7, "src": 5, "src2": 4, "imm": "0x9c90dd88", "imm2": "0xc4e0fb3a", "rot": 27, "bit": 29, "mask": 1}, + {"i": 648, "op": "rotl", "dst": 7, "src": 6, "src2": 0, "imm": "0xa3ac817b", "imm2": "0xa06385ae", "rot": 1, "bit": 12, "mask": 4}, + {"i": 649, "op": "add", "dst": 5, "src": 6, "src2": 1, "imm": "0x9f5e0d19", "imm2": "0x6e5d517f", "rot": 17, "bit": 31, "mask": 4}, + {"i": 650, "op": "or", "dst": 1, "src": 2, "src2": 1, "imm": "0x52d36d7d", "imm2": "0x6ed4f46a", "rot": 8, "bit": 16, "mask": 4}, + {"i": 651, "op": "rotl", "dst": 3, "src": 7, "src2": 6, "imm": "0x7af35d35", "imm2": "0xff08d71d", "rot": 29, "bit": 20, "mask": 16}, + {"i": 652, "op": "add", "dst": 2, "src": 4, "src2": 4, "imm": "0xb53f6e74", "imm2": "0x30faf9c6", "rot": 12, "bit": 2, "mask": 16}, + {"i": 653, "op": "rotl", "dst": 0, "src": 3, "src2": 0, "imm": "0x688fef8f", "imm2": "0xc909272c", "rot": 21, "bit": 12, "mask": 4}, + {"i": 654, "op": "xor", "dst": 1, "src": 3, "src2": 0, "imm": "0xfaf5f006", "imm2": "0x29335739", "rot": 16, "bit": 26, "mask": 1}, + {"i": 655, "op": "mad", "dst": 4, "src": 7, "src2": 2, "imm": "0x52aa5838", "imm2": "0x24772222", "rot": 31, "bit": 16, "mask": 2}, + {"i": 656, "op": "sub", "dst": 4, "src": 6, "src2": 0, "imm": "0x5cac1961", "imm2": "0x19df9350", "rot": 22, "bit": 27, "mask": 4}, + {"i": 657, "op": "mul", "dst": 4, "src": 6, "src2": 6, "imm": "0x2fa0c53e", "imm2": "0x05544778", "rot": 3, "bit": 0, "mask": 8}, + {"i": 658, "op": "shfl", "dst": 2, "src": 1, "src2": 6, "imm": "0x100ce1a8", "imm2": "0xeba9c42d", "rot": 9, "bit": 27, "mask": 4}, + {"i": 659, "op": "rotl", "dst": 7, "src": 4, "src2": 4, "imm": "0x80665907", "imm2": "0xc68a72ed", "rot": 31, "bit": 18, "mask": 8}, + {"i": 660, "op": "xor", "dst": 4, "src": 6, "src2": 2, "imm": "0x750d5861", "imm2": "0x4f1f6b61", "rot": 23, "bit": 5, "mask": 16}, + {"i": 661, "op": "sub", "dst": 1, "src": 3, "src2": 0, "imm": "0xb4023070", "imm2": "0x25834ecb", "rot": 11, "bit": 31, "mask": 16}, + {"i": 662, "op": "mul", "dst": 3, "src": 6, "src2": 0, "imm": "0x98d71e0a", "imm2": "0x4b1e4b9b", "rot": 24, "bit": 17, "mask": 4}, + {"i": 663, "op": "mul", "dst": 5, "src": 3, "src2": 4, "imm": "0xb5bdf141", "imm2": "0x46d76719", "rot": 15, "bit": 5, "mask": 16}, + {"i": 664, "op": "add", "dst": 7, "src": 2, "src2": 5, "imm": "0x016e0094", "imm2": "0x8941d2e7", "rot": 26, "bit": 21, "mask": 4}, + {"i": 665, "op": "xor", "dst": 1, "src": 2, "src2": 4, "imm": "0x4cd3f22d", "imm2": "0x68ca0cc2", "rot": 26, "bit": 21, "mask": 4}, + {"i": 666, "op": "sub", "dst": 1, "src": 0, "src2": 5, "imm": "0x4118a9c5", "imm2": "0xb01f4652", "rot": 12, "bit": 16, "mask": 8}, + {"i": 667, "op": "xor", "dst": 4, "src": 7, "src2": 6, "imm": "0xece6b48a", "imm2": "0xcd6148be", "rot": 16, "bit": 1, "mask": 8}, + {"i": 668, "op": "shfl", "dst": 7, "src": 3, "src2": 5, "imm": "0xdd86a52a", "imm2": "0xed55016b", "rot": 14, "bit": 17, "mask": 1}, + {"i": 669, "op": "rotr", "dst": 1, "src": 4, "src2": 2, "imm": "0x7947b08b", "imm2": "0xc644399e", "rot": 23, "bit": 21, "mask": 8}, + {"i": 670, "op": "add", "dst": 2, "src": 3, "src2": 0, "imm": "0x9af12ca6", "imm2": "0x15289435", "rot": 22, "bit": 14, "mask": 8}, + {"i": 671, "op": "rotr", "dst": 2, "src": 4, "src2": 2, "imm": "0xe4b461c7", "imm2": "0x3cc08fa2", "rot": 15, "bit": 9, "mask": 8}, + {"i": 672, "op": "mad", "dst": 4, "src": 6, "src2": 7, "imm": "0x2f0a3958", "imm2": "0x21423192", "rot": 30, "bit": 17, "mask": 4}, + {"i": 673, "op": "shfl", "dst": 2, "src": 1, "src2": 6, "imm": "0x3f3a7a05", "imm2": "0x06b1414f", "rot": 20, "bit": 20, "mask": 4}, + {"i": 674, "op": "mad", "dst": 6, "src": 4, "src2": 2, "imm": "0x01905454", "imm2": "0x3f4d91e7", "rot": 11, "bit": 3, "mask": 1}, + {"i": 675, "op": "mad", "dst": 2, "src": 4, "src2": 6, "imm": "0x06ea623d", "imm2": "0x79d977be", "rot": 24, "bit": 18, "mask": 2}, + {"i": 676, "op": "shfl", "dst": 3, "src": 1, "src2": 6, "imm": "0x12902d97", "imm2": "0x4423a802", "rot": 31, "bit": 15, "mask": 16}, + {"i": 677, "op": "rotr", "dst": 1, "src": 0, "src2": 0, "imm": "0x4652f0a7", "imm2": "0x63bd2f3d", "rot": 18, "bit": 30, "mask": 16}, + {"i": 678, "op": "sub", "dst": 0, "src": 2, "src2": 5, "imm": "0xa1b6480b", "imm2": "0x66bbf7cb", "rot": 23, "bit": 10, "mask": 2}, + {"i": 679, "op": "shfl", "dst": 5, "src": 1, "src2": 6, "imm": "0xa6c92dca", "imm2": "0xbc848744", "rot": 29, "bit": 4, "mask": 16}, + {"i": 680, "op": "xor", "dst": 1, "src": 0, "src2": 0, "imm": "0x9591028e", "imm2": "0x58093970", "rot": 4, "bit": 3, "mask": 8}, + {"i": 681, "op": "shfl", "dst": 1, "src": 2, "src2": 2, "imm": "0x6f0be1de", "imm2": "0x12e663b7", "rot": 19, "bit": 28, "mask": 4}, + {"i": 682, "op": "shfl", "dst": 0, "src": 3, "src2": 4, "imm": "0x9e48d732", "imm2": "0x83b751ce", "rot": 22, "bit": 31, "mask": 8}, + {"i": 683, "op": "mad", "dst": 2, "src": 3, "src2": 3, "imm": "0x9b9cb1f4", "imm2": "0x1658d484", "rot": 4, "bit": 26, "mask": 8}, + {"i": 684, "op": "sub", "dst": 4, "src": 6, "src2": 2, "imm": "0xc1913732", "imm2": "0x75fe1c46", "rot": 30, "bit": 5, "mask": 4}, + {"i": 685, "op": "xor", "dst": 5, "src": 3, "src2": 7, "imm": "0x309a4c48", "imm2": "0x81d6a444", "rot": 29, "bit": 15, "mask": 1}, + {"i": 686, "op": "sub", "dst": 2, "src": 5, "src2": 5, "imm": "0x0fbf5411", "imm2": "0xf5b8875a", "rot": 9, "bit": 1, "mask": 4}, + {"i": 687, "op": "sub", "dst": 4, "src": 5, "src2": 1, "imm": "0x4ecd230a", "imm2": "0xac339e86", "rot": 2, "bit": 23, "mask": 16}, + {"i": 688, "op": "mad", "dst": 5, "src": 4, "src2": 7, "imm": "0x321ec7f8", "imm2": "0xe2087134", "rot": 14, "bit": 27, "mask": 4}, + {"i": 689, "op": "mul", "dst": 6, "src": 7, "src2": 2, "imm": "0x97409084", "imm2": "0x2dded812", "rot": 15, "bit": 1, "mask": 8}, + {"i": 690, "op": "mul", "dst": 1, "src": 5, "src2": 4, "imm": "0x71796f1d", "imm2": "0xd68af3ce", "rot": 8, "bit": 30, "mask": 4}, + {"i": 691, "op": "rotr", "dst": 4, "src": 3, "src2": 0, "imm": "0x990a87a7", "imm2": "0xfa05f126", "rot": 20, "bit": 15, "mask": 16}, + {"i": 692, "op": "xor", "dst": 2, "src": 4, "src2": 7, "imm": "0xb9507bc7", "imm2": "0xcf0d691a", "rot": 29, "bit": 6, "mask": 2}, + {"i": 693, "op": "rotl", "dst": 0, "src": 4, "src2": 0, "imm": "0x8429f629", "imm2": "0xec2dabcd", "rot": 2, "bit": 27, "mask": 2}, + {"i": 694, "op": "add", "dst": 5, "src": 2, "src2": 3, "imm": "0x4fc762c9", "imm2": "0x49801084", "rot": 14, "bit": 23, "mask": 1}, + {"i": 695, "op": "add", "dst": 0, "src": 4, "src2": 3, "imm": "0x626c00f5", "imm2": "0x5f403cd5", "rot": 28, "bit": 14, "mask": 4}, + {"i": 696, "op": "rotl", "dst": 6, "src": 2, "src2": 3, "imm": "0xe64caa6b", "imm2": "0xa8111b9c", "rot": 25, "bit": 2, "mask": 1}, + {"i": 697, "op": "xor", "dst": 3, "src": 7, "src2": 7, "imm": "0x1aa645af", "imm2": "0x216c2572", "rot": 12, "bit": 4, "mask": 2}, + {"i": 698, "op": "mul", "dst": 0, "src": 2, "src2": 4, "imm": "0x10190317", "imm2": "0x07f5bd87", "rot": 20, "bit": 5, "mask": 16}, + {"i": 699, "op": "rotr", "dst": 5, "src": 1, "src2": 5, "imm": "0x330ce2e2", "imm2": "0x4a714552", "rot": 5, "bit": 9, "mask": 2}, + {"i": 700, "op": "xor", "dst": 3, "src": 7, "src2": 3, "imm": "0xb7ac6a97", "imm2": "0x1a847bb7", "rot": 21, "bit": 29, "mask": 4}, + {"i": 701, "op": "or", "dst": 4, "src": 3, "src2": 0, "imm": "0x8c5a3e12", "imm2": "0x94db336f", "rot": 6, "bit": 20, "mask": 8}, + {"i": 702, "op": "mul", "dst": 7, "src": 3, "src2": 3, "imm": "0xe2ac84c7", "imm2": "0x1ef53cc0", "rot": 15, "bit": 17, "mask": 1}, + {"i": 703, "op": "rotl", "dst": 4, "src": 0, "src2": 2, "imm": "0xc653bb55", "imm2": "0x6a41bc44", "rot": 24, "bit": 15, "mask": 2}, + {"i": 704, "op": "add", "dst": 5, "src": 4, "src2": 3, "imm": "0xc08bb414", "imm2": "0xad5e1851", "rot": 17, "bit": 17, "mask": 4}, + {"i": 705, "op": "mad", "dst": 0, "src": 6, "src2": 5, "imm": "0xa0d85d7d", "imm2": "0x5c24ec53", "rot": 22, "bit": 23, "mask": 16}, + {"i": 706, "op": "mulhi", "dst": 4, "src": 1, "src2": 3, "imm": "0x089ef63d", "imm2": "0x825b1346", "rot": 17, "bit": 19, "mask": 2}, + {"i": 707, "op": "rotr", "dst": 4, "src": 3, "src2": 5, "imm": "0xa74afd00", "imm2": "0x402765ac", "rot": 16, "bit": 25, "mask": 4}, + {"i": 708, "op": "rotr", "dst": 3, "src": 6, "src2": 7, "imm": "0x927344a8", "imm2": "0x86226216", "rot": 3, "bit": 16, "mask": 16}, + {"i": 709, "op": "shfl", "dst": 6, "src": 7, "src2": 0, "imm": "0x3f3bf8ac", "imm2": "0x3b7bda0a", "rot": 27, "bit": 1, "mask": 16}, + {"i": 710, "op": "mad", "dst": 3, "src": 2, "src2": 6, "imm": "0xd974f8d2", "imm2": "0xfa936ef1", "rot": 18, "bit": 18, "mask": 2}, + {"i": 711, "op": "mul", "dst": 1, "src": 4, "src2": 0, "imm": "0x111062b6", "imm2": "0x157f4a53", "rot": 14, "bit": 29, "mask": 1}, + {"i": 712, "op": "add", "dst": 3, "src": 5, "src2": 6, "imm": "0xdc55338f", "imm2": "0x407f7c4d", "rot": 12, "bit": 13, "mask": 16}, + {"i": 713, "op": "shfl", "dst": 6, "src": 7, "src2": 1, "imm": "0x95073eef", "imm2": "0x2fb6d6a7", "rot": 2, "bit": 6, "mask": 2}, + {"i": 714, "op": "xor", "dst": 1, "src": 0, "src2": 4, "imm": "0x17ed3778", "imm2": "0x25ea7fd1", "rot": 6, "bit": 21, "mask": 1}, + {"i": 715, "op": "mad", "dst": 7, "src": 1, "src2": 1, "imm": "0x9cd6bfc5", "imm2": "0x06214262", "rot": 11, "bit": 30, "mask": 1}, + {"i": 716, "op": "or", "dst": 4, "src": 0, "src2": 3, "imm": "0x7fbea2fc", "imm2": "0x38894ef8", "rot": 2, "bit": 5, "mask": 2}, + {"i": 717, "op": "mul", "dst": 6, "src": 4, "src2": 2, "imm": "0x9db6712b", "imm2": "0x620de01d", "rot": 16, "bit": 16, "mask": 2}, + {"i": 718, "op": "sub", "dst": 0, "src": 5, "src2": 5, "imm": "0x97919a9a", "imm2": "0xec9f6385", "rot": 18, "bit": 27, "mask": 1}, + {"i": 719, "op": "xor", "dst": 1, "src": 4, "src2": 7, "imm": "0xee3c297d", "imm2": "0x4fefab14", "rot": 16, "bit": 5, "mask": 4}, + {"i": 720, "op": "mulhi", "dst": 4, "src": 6, "src2": 5, "imm": "0xd7003957", "imm2": "0x18e039f0", "rot": 24, "bit": 19, "mask": 1}, + {"i": 721, "op": "add", "dst": 1, "src": 0, "src2": 7, "imm": "0xb2ce569e", "imm2": "0xc2093fca", "rot": 19, "bit": 13, "mask": 16}, + {"i": 722, "op": "mulhi", "dst": 4, "src": 2, "src2": 3, "imm": "0x21a18eec", "imm2": "0xaed097a2", "rot": 24, "bit": 17, "mask": 8}, + {"i": 723, "op": "shfl", "dst": 6, "src": 1, "src2": 6, "imm": "0x48a39bb3", "imm2": "0xb76edf71", "rot": 2, "bit": 27, "mask": 16}, + {"i": 724, "op": "mad", "dst": 5, "src": 3, "src2": 0, "imm": "0xf2c8bc32", "imm2": "0xca791b2c", "rot": 19, "bit": 28, "mask": 2}, + {"i": 725, "op": "mulhi", "dst": 5, "src": 0, "src2": 0, "imm": "0xe08d6f96", "imm2": "0x6e203ce4", "rot": 18, "bit": 0, "mask": 16}, + {"i": 726, "op": "rotr", "dst": 2, "src": 5, "src2": 7, "imm": "0xd326f7ee", "imm2": "0xf21532f9", "rot": 21, "bit": 3, "mask": 4}, + {"i": 727, "op": "add", "dst": 5, "src": 0, "src2": 6, "imm": "0x4e8aaad5", "imm2": "0x48cdf1c1", "rot": 22, "bit": 20, "mask": 16}, + {"i": 728, "op": "mul", "dst": 1, "src": 0, "src2": 6, "imm": "0x82f8289f", "imm2": "0xaf661984", "rot": 11, "bit": 17, "mask": 16}, + {"i": 729, "op": "shfl", "dst": 3, "src": 0, "src2": 4, "imm": "0x46345e75", "imm2": "0xadd3754b", "rot": 26, "bit": 6, "mask": 1}, + {"i": 730, "op": "mul", "dst": 4, "src": 6, "src2": 6, "imm": "0xd1fdd355", "imm2": "0xc58e45d1", "rot": 16, "bit": 4, "mask": 4}, + {"i": 731, "op": "sub", "dst": 4, "src": 6, "src2": 4, "imm": "0x0fd26ae0", "imm2": "0x673e1be6", "rot": 13, "bit": 8, "mask": 2}, + {"i": 732, "op": "xor", "dst": 4, "src": 2, "src2": 1, "imm": "0xc5a1ebeb", "imm2": "0xa44dfb95", "rot": 22, "bit": 26, "mask": 8}, + {"i": 733, "op": "mul", "dst": 5, "src": 6, "src2": 4, "imm": "0x6d00bc06", "imm2": "0x223b7e4e", "rot": 3, "bit": 0, "mask": 8}, + {"i": 734, "op": "rotr", "dst": 7, "src": 3, "src2": 2, "imm": "0xaa9c67c4", "imm2": "0x8c363dd0", "rot": 29, "bit": 25, "mask": 8}, + {"i": 735, "op": "shfl", "dst": 1, "src": 5, "src2": 1, "imm": "0x2f3875ba", "imm2": "0x1a371963", "rot": 22, "bit": 7, "mask": 1}, + {"i": 736, "op": "mulhi", "dst": 1, "src": 0, "src2": 6, "imm": "0xf42e5e71", "imm2": "0x8d323fee", "rot": 13, "bit": 23, "mask": 16}, + {"i": 737, "op": "mul", "dst": 2, "src": 6, "src2": 7, "imm": "0x4b686dd8", "imm2": "0x67b0523f", "rot": 4, "bit": 24, "mask": 4}, + {"i": 738, "op": "rotl", "dst": 5, "src": 3, "src2": 7, "imm": "0x2c53d57a", "imm2": "0x68c1ee91", "rot": 27, "bit": 8, "mask": 1}, + {"i": 739, "op": "mulhi", "dst": 2, "src": 3, "src2": 0, "imm": "0x5a72a768", "imm2": "0x5c479e20", "rot": 18, "bit": 22, "mask": 16}, + {"i": 740, "op": "mad", "dst": 5, "src": 3, "src2": 5, "imm": "0x51bb4f54", "imm2": "0x3e80baf7", "rot": 18, "bit": 7, "mask": 2}, + {"i": 741, "op": "rotl", "dst": 2, "src": 0, "src2": 7, "imm": "0x09cd4969", "imm2": "0x14067eda", "rot": 11, "bit": 29, "mask": 1}, + {"i": 742, "op": "or", "dst": 6, "src": 2, "src2": 3, "imm": "0x638ba9e4", "imm2": "0x53376c12", "rot": 14, "bit": 17, "mask": 2}, + {"i": 743, "op": "xor", "dst": 2, "src": 3, "src2": 6, "imm": "0xc1ea2342", "imm2": "0x301057cb", "rot": 29, "bit": 7, "mask": 1}, + {"i": 744, "op": "mul", "dst": 3, "src": 1, "src2": 2, "imm": "0x0cc57ccc", "imm2": "0xe9026d39", "rot": 27, "bit": 20, "mask": 2}, + {"i": 745, "op": "mulhi", "dst": 4, "src": 2, "src2": 1, "imm": "0x14f82d3a", "imm2": "0x6ccfcc5d", "rot": 17, "bit": 25, "mask": 8}, + {"i": 746, "op": "xor", "dst": 5, "src": 6, "src2": 3, "imm": "0x327a220a", "imm2": "0x2d3bd910", "rot": 20, "bit": 12, "mask": 2}, + {"i": 747, "op": "add", "dst": 6, "src": 7, "src2": 0, "imm": "0x78fc162d", "imm2": "0x0d6b844e", "rot": 24, "bit": 11, "mask": 1}, + {"i": 748, "op": "rotl", "dst": 1, "src": 3, "src2": 6, "imm": "0x058a11f0", "imm2": "0x1a71cf1e", "rot": 27, "bit": 12, "mask": 4}, + {"i": 749, "op": "rotr", "dst": 4, "src": 1, "src2": 2, "imm": "0x5a87939b", "imm2": "0x35760cc4", "rot": 4, "bit": 10, "mask": 1}, + {"i": 750, "op": "xor", "dst": 5, "src": 7, "src2": 6, "imm": "0x919ef5c7", "imm2": "0x9aa514c9", "rot": 12, "bit": 20, "mask": 8}, + {"i": 751, "op": "rotr", "dst": 4, "src": 3, "src2": 1, "imm": "0xd6dd5987", "imm2": "0x6300bb82", "rot": 25, "bit": 27, "mask": 2}, + {"i": 752, "op": "mul", "dst": 5, "src": 2, "src2": 1, "imm": "0xcc5bc338", "imm2": "0xcb485809", "rot": 25, "bit": 31, "mask": 2}, + {"i": 753, "op": "mad", "dst": 1, "src": 6, "src2": 7, "imm": "0xad0ed87f", "imm2": "0xa48a7ad2", "rot": 5, "bit": 25, "mask": 4}, + {"i": 754, "op": "xor", "dst": 0, "src": 1, "src2": 6, "imm": "0xdb944bfd", "imm2": "0x7bcddd30", "rot": 20, "bit": 1, "mask": 2}, + {"i": 755, "op": "sub", "dst": 7, "src": 1, "src2": 0, "imm": "0x7fccd649", "imm2": "0x8967b519", "rot": 15, "bit": 18, "mask": 16}, + {"i": 756, "op": "add", "dst": 0, "src": 4, "src2": 2, "imm": "0x68aab88b", "imm2": "0xb74ac71e", "rot": 22, "bit": 5, "mask": 2}, + {"i": 757, "op": "add", "dst": 7, "src": 5, "src2": 4, "imm": "0xba5c123a", "imm2": "0xf81f5b66", "rot": 27, "bit": 0, "mask": 4}, + {"i": 758, "op": "mad", "dst": 0, "src": 7, "src2": 2, "imm": "0x73762a3f", "imm2": "0x6ea5c1a9", "rot": 25, "bit": 2, "mask": 1}, + {"i": 759, "op": "or", "dst": 1, "src": 0, "src2": 3, "imm": "0x86e2a2f6", "imm2": "0xf0ca2c9d", "rot": 28, "bit": 14, "mask": 16}, + {"i": 760, "op": "mulhi", "dst": 4, "src": 6, "src2": 3, "imm": "0xa5a13558", "imm2": "0x5f59ed18", "rot": 2, "bit": 22, "mask": 2}, + {"i": 761, "op": "mulhi", "dst": 0, "src": 7, "src2": 7, "imm": "0x063f4121", "imm2": "0xd90468ef", "rot": 26, "bit": 9, "mask": 16}, + {"i": 762, "op": "rotr", "dst": 3, "src": 4, "src2": 2, "imm": "0x2bf16789", "imm2": "0xaea617b4", "rot": 5, "bit": 1, "mask": 8}, + {"i": 763, "op": "rotl", "dst": 3, "src": 2, "src2": 4, "imm": "0xcada5385", "imm2": "0x987b9822", "rot": 30, "bit": 28, "mask": 4}, + {"i": 764, "op": "mul", "dst": 6, "src": 2, "src2": 1, "imm": "0xb43f840a", "imm2": "0xbbeca872", "rot": 22, "bit": 31, "mask": 8}, + {"i": 765, "op": "xor", "dst": 6, "src": 4, "src2": 6, "imm": "0x0dcdd279", "imm2": "0x5a37580c", "rot": 2, "bit": 31, "mask": 4}, + {"i": 766, "op": "add", "dst": 3, "src": 4, "src2": 7, "imm": "0x6eb1d82a", "imm2": "0x96dabea6", "rot": 29, "bit": 0, "mask": 1}, + {"i": 767, "op": "shfl", "dst": 0, "src": 2, "src2": 2, "imm": "0x569c62b3", "imm2": "0x67ccfd71", "rot": 23, "bit": 8, "mask": 1}, + {"i": 768, "op": "rotl", "dst": 3, "src": 0, "src2": 2, "imm": "0x07743cf8", "imm2": "0x2f386ddd", "rot": 8, "bit": 0, "mask": 16}, + {"i": 769, "op": "mul", "dst": 7, "src": 4, "src2": 5, "imm": "0x38d7ac15", "imm2": "0xd94cabe7", "rot": 8, "bit": 26, "mask": 8}, + {"i": 770, "op": "mad", "dst": 6, "src": 1, "src2": 2, "imm": "0xdb0b7a5f", "imm2": "0xc94b5196", "rot": 17, "bit": 28, "mask": 8}, + {"i": 771, "op": "xor", "dst": 2, "src": 7, "src2": 5, "imm": "0x9a96db6f", "imm2": "0x1be7adbc", "rot": 13, "bit": 2, "mask": 4}, + {"i": 772, "op": "mul", "dst": 6, "src": 0, "src2": 7, "imm": "0x72de7e2b", "imm2": "0x5a33c8fa", "rot": 25, "bit": 18, "mask": 4}, + {"i": 773, "op": "sub", "dst": 2, "src": 1, "src2": 2, "imm": "0xa38b9d2f", "imm2": "0x8093b709", "rot": 9, "bit": 31, "mask": 2}, + {"i": 774, "op": "mad", "dst": 1, "src": 0, "src2": 1, "imm": "0x27703a78", "imm2": "0xe2fa6549", "rot": 15, "bit": 11, "mask": 8}, + {"i": 775, "op": "mulhi", "dst": 5, "src": 7, "src2": 3, "imm": "0x978c80e6", "imm2": "0x2bcf48c0", "rot": 7, "bit": 4, "mask": 2}, + {"i": 776, "op": "rotr", "dst": 0, "src": 4, "src2": 3, "imm": "0xfe4ca97e", "imm2": "0x20d57bd7", "rot": 21, "bit": 17, "mask": 8}, + {"i": 777, "op": "xor", "dst": 6, "src": 0, "src2": 6, "imm": "0x133bfe0b", "imm2": "0xab42a73d", "rot": 26, "bit": 17, "mask": 8}, + {"i": 778, "op": "mulhi", "dst": 4, "src": 7, "src2": 4, "imm": "0xa45a79ef", "imm2": "0x1d474080", "rot": 28, "bit": 30, "mask": 16}, + {"i": 779, "op": "mad", "dst": 1, "src": 3, "src2": 0, "imm": "0xd7cfaf3e", "imm2": "0x22de04d3", "rot": 3, "bit": 22, "mask": 8}, + {"i": 780, "op": "add", "dst": 6, "src": 4, "src2": 3, "imm": "0x11d7b79a", "imm2": "0x903f3f77", "rot": 16, "bit": 2, "mask": 2}, + {"i": 781, "op": "xor", "dst": 4, "src": 7, "src2": 4, "imm": "0xf54085ad", "imm2": "0x9b70acf5", "rot": 9, "bit": 18, "mask": 16}, + {"i": 782, "op": "add", "dst": 1, "src": 2, "src2": 1, "imm": "0x1791eadd", "imm2": "0x2ca81d8d", "rot": 8, "bit": 14, "mask": 2}, + {"i": 783, "op": "rotr", "dst": 2, "src": 1, "src2": 7, "imm": "0xac869789", "imm2": "0xeeb43dbc", "rot": 31, "bit": 17, "mask": 2}, + {"i": 784, "op": "mul", "dst": 4, "src": 6, "src2": 4, "imm": "0xd035a7ca", "imm2": "0x07452e2d", "rot": 22, "bit": 7, "mask": 4}, + {"i": 785, "op": "xor", "dst": 1, "src": 6, "src2": 3, "imm": "0x46facf23", "imm2": "0x72b382a0", "rot": 17, "bit": 16, "mask": 1}, + {"i": 786, "op": "sub", "dst": 4, "src": 0, "src2": 3, "imm": "0x386a3e78", "imm2": "0x14ec02d5", "rot": 18, "bit": 1, "mask": 2}, + {"i": 787, "op": "xor", "dst": 3, "src": 4, "src2": 6, "imm": "0x3df05ee6", "imm2": "0x6343ef52", "rot": 31, "bit": 12, "mask": 2}, + {"i": 788, "op": "mul", "dst": 4, "src": 1, "src2": 0, "imm": "0x92678acf", "imm2": "0x90af3021", "rot": 27, "bit": 7, "mask": 4}, + {"i": 789, "op": "mad", "dst": 4, "src": 6, "src2": 7, "imm": "0x72266b9a", "imm2": "0xf4ca0ec1", "rot": 30, "bit": 23, "mask": 1}, + {"i": 790, "op": "sub", "dst": 5, "src": 0, "src2": 5, "imm": "0x219f943a", "imm2": "0xc2e29934", "rot": 25, "bit": 5, "mask": 16}, + {"i": 791, "op": "mul", "dst": 2, "src": 0, "src2": 1, "imm": "0x0fbcecac", "imm2": "0xc65a0546", "rot": 6, "bit": 30, "mask": 4}, + {"i": 792, "op": "rotl", "dst": 7, "src": 5, "src2": 7, "imm": "0x227934e2", "imm2": "0x34b10495", "rot": 12, "bit": 26, "mask": 1}, + {"i": 793, "op": "mad", "dst": 2, "src": 7, "src2": 3, "imm": "0x38db49cf", "imm2": "0x7b2340cc", "rot": 23, "bit": 13, "mask": 1}, + {"i": 794, "op": "mad", "dst": 1, "src": 4, "src2": 4, "imm": "0x4e4f8a96", "imm2": "0x56011409", "rot": 21, "bit": 29, "mask": 16}, + {"i": 795, "op": "add", "dst": 6, "src": 4, "src2": 6, "imm": "0xc08797bb", "imm2": "0xf66fad29", "rot": 16, "bit": 15, "mask": 4}, + {"i": 796, "op": "sub", "dst": 1, "src": 4, "src2": 7, "imm": "0xf7e6ae46", "imm2": "0xa82a252b", "rot": 3, "bit": 23, "mask": 2}, + {"i": 797, "op": "mul", "dst": 5, "src": 2, "src2": 1, "imm": "0x26786fc5", "imm2": "0x189061c5", "rot": 9, "bit": 25, "mask": 1}, + {"i": 798, "op": "xor", "dst": 5, "src": 2, "src2": 7, "imm": "0xe8433286", "imm2": "0xed8fa7c2", "rot": 10, "bit": 6, "mask": 2}, + {"i": 799, "op": "mul", "dst": 0, "src": 1, "src2": 1, "imm": "0x08c2bd8a", "imm2": "0x770b1889", "rot": 11, "bit": 27, "mask": 4}, + {"i": 800, "op": "add", "dst": 6, "src": 4, "src2": 5, "imm": "0x6d4a6371", "imm2": "0x2d82a681", "rot": 14, "bit": 13, "mask": 2}, + {"i": 801, "op": "mad", "dst": 1, "src": 6, "src2": 1, "imm": "0x4b9c98c0", "imm2": "0xbfa127a9", "rot": 29, "bit": 29, "mask": 2}, + {"i": 802, "op": "sub", "dst": 0, "src": 2, "src2": 7, "imm": "0x11599b44", "imm2": "0xd29a5300", "rot": 14, "bit": 9, "mask": 16}, + {"i": 803, "op": "xor", "dst": 6, "src": 2, "src2": 4, "imm": "0x4b0bfae2", "imm2": "0xd41479a4", "rot": 4, "bit": 2, "mask": 1}, + {"i": 804, "op": "rotl", "dst": 7, "src": 1, "src2": 3, "imm": "0xae3c9f8b", "imm2": "0x7df429ad", "rot": 24, "bit": 6, "mask": 16}, + {"i": 805, "op": "xor", "dst": 6, "src": 7, "src2": 5, "imm": "0x7b9d93db", "imm2": "0xdac87245", "rot": 26, "bit": 10, "mask": 1}, + {"i": 806, "op": "or", "dst": 7, "src": 0, "src2": 6, "imm": "0xdd4a38c4", "imm2": "0x928f44bc", "rot": 27, "bit": 0, "mask": 16}, + {"i": 807, "op": "rotl", "dst": 0, "src": 5, "src2": 0, "imm": "0x43b30776", "imm2": "0x8aef4c1f", "rot": 5, "bit": 15, "mask": 1}, + {"i": 808, "op": "shfl", "dst": 1, "src": 2, "src2": 7, "imm": "0x58963a0b", "imm2": "0xedd2ffd1", "rot": 9, "bit": 4, "mask": 2}, + {"i": 809, "op": "mad", "dst": 4, "src": 1, "src2": 5, "imm": "0x5f24b47c", "imm2": "0x14a55700", "rot": 24, "bit": 24, "mask": 1}, + {"i": 810, "op": "add", "dst": 0, "src": 2, "src2": 4, "imm": "0x0092eb62", "imm2": "0x63e62197", "rot": 7, "bit": 14, "mask": 8}, + {"i": 811, "op": "sub", "dst": 5, "src": 3, "src2": 2, "imm": "0x83a6d7ee", "imm2": "0x1211bd6c", "rot": 23, "bit": 24, "mask": 16}, + {"i": 812, "op": "mad", "dst": 2, "src": 1, "src2": 5, "imm": "0xda1b1efa", "imm2": "0x9d28dfef", "rot": 12, "bit": 0, "mask": 4}, + {"i": 813, "op": "shfl", "dst": 6, "src": 0, "src2": 1, "imm": "0x51496b62", "imm2": "0xdb8e9b60", "rot": 5, "bit": 0, "mask": 16}, + {"i": 814, "op": "mad", "dst": 7, "src": 5, "src2": 1, "imm": "0xfcfea85b", "imm2": "0xf65ac3f0", "rot": 11, "bit": 20, "mask": 16}, + {"i": 815, "op": "mulhi", "dst": 0, "src": 7, "src2": 4, "imm": "0xd032ed30", "imm2": "0x5b12b17f", "rot": 6, "bit": 21, "mask": 2}, + {"i": 816, "op": "or", "dst": 2, "src": 1, "src2": 5, "imm": "0x8d06c653", "imm2": "0x2927105c", "rot": 2, "bit": 8, "mask": 8}, + {"i": 817, "op": "mulhi", "dst": 7, "src": 3, "src2": 4, "imm": "0xa83c7b19", "imm2": "0x80a32699", "rot": 14, "bit": 28, "mask": 4}, + {"i": 818, "op": "xor", "dst": 2, "src": 4, "src2": 7, "imm": "0x21e0d94d", "imm2": "0xfcdc675a", "rot": 22, "bit": 12, "mask": 1}, + {"i": 819, "op": "add", "dst": 4, "src": 3, "src2": 4, "imm": "0xbb69174f", "imm2": "0x27d94f57", "rot": 6, "bit": 0, "mask": 8}, + {"i": 820, "op": "add", "dst": 5, "src": 3, "src2": 1, "imm": "0xda6759f2", "imm2": "0x82285691", "rot": 21, "bit": 1, "mask": 16}, + {"i": 821, "op": "add", "dst": 1, "src": 3, "src2": 6, "imm": "0x9ad4b47f", "imm2": "0xe50565d8", "rot": 11, "bit": 31, "mask": 1}, + {"i": 822, "op": "rotl", "dst": 5, "src": 2, "src2": 7, "imm": "0x96b9eb01", "imm2": "0x517e9c76", "rot": 6, "bit": 11, "mask": 16}, + {"i": 823, "op": "sub", "dst": 3, "src": 0, "src2": 2, "imm": "0x06b83dd9", "imm2": "0x12831818", "rot": 4, "bit": 8, "mask": 4}, + {"i": 824, "op": "rotl", "dst": 6, "src": 4, "src2": 0, "imm": "0x13faa050", "imm2": "0x55738fd7", "rot": 12, "bit": 25, "mask": 1}, + {"i": 825, "op": "or", "dst": 4, "src": 5, "src2": 2, "imm": "0xf9cde1dd", "imm2": "0xb23e0565", "rot": 15, "bit": 6, "mask": 8}, + {"i": 826, "op": "xor", "dst": 3, "src": 2, "src2": 4, "imm": "0xd611028e", "imm2": "0xa059229f", "rot": 24, "bit": 10, "mask": 8}, + {"i": 827, "op": "add", "dst": 4, "src": 0, "src2": 7, "imm": "0xca1e80fb", "imm2": "0xffcab83a", "rot": 14, "bit": 26, "mask": 8}, + {"i": 828, "op": "or", "dst": 3, "src": 7, "src2": 4, "imm": "0xf9ff98ff", "imm2": "0x0ed3538e", "rot": 22, "bit": 9, "mask": 16}, + {"i": 829, "op": "mad", "dst": 1, "src": 5, "src2": 7, "imm": "0xf2014867", "imm2": "0xf641b223", "rot": 16, "bit": 20, "mask": 8}, + {"i": 830, "op": "shfl", "dst": 6, "src": 0, "src2": 1, "imm": "0x2f5aabc7", "imm2": "0xeb1dd686", "rot": 13, "bit": 11, "mask": 16}, + {"i": 831, "op": "sub", "dst": 1, "src": 0, "src2": 1, "imm": "0x546552ba", "imm2": "0x0d855461", "rot": 15, "bit": 31, "mask": 4}, + {"i": 832, "op": "rotr", "dst": 0, "src": 2, "src2": 2, "imm": "0x1fa3f763", "imm2": "0x04263e5f", "rot": 9, "bit": 18, "mask": 16}, + {"i": 833, "op": "mulhi", "dst": 1, "src": 0, "src2": 6, "imm": "0x3d656eb9", "imm2": "0xf1d34fa4", "rot": 11, "bit": 6, "mask": 8}, + {"i": 834, "op": "mulhi", "dst": 6, "src": 4, "src2": 1, "imm": "0x0b81b084", "imm2": "0xd19afb09", "rot": 21, "bit": 1, "mask": 2}, + {"i": 835, "op": "rotl", "dst": 6, "src": 5, "src2": 0, "imm": "0x041c05b7", "imm2": "0xead1b786", "rot": 2, "bit": 29, "mask": 2}, + {"i": 836, "op": "or", "dst": 4, "src": 6, "src2": 4, "imm": "0xad2af638", "imm2": "0x95f90dcc", "rot": 31, "bit": 13, "mask": 2}, + {"i": 837, "op": "rotl", "dst": 6, "src": 3, "src2": 5, "imm": "0x8eef8e8a", "imm2": "0xb63c32fd", "rot": 23, "bit": 16, "mask": 16}, + {"i": 838, "op": "mad", "dst": 4, "src": 7, "src2": 4, "imm": "0x742a3ab4", "imm2": "0x203cd874", "rot": 22, "bit": 12, "mask": 16}, + {"i": 839, "op": "or", "dst": 0, "src": 1, "src2": 6, "imm": "0xfeed217d", "imm2": "0x32d45142", "rot": 18, "bit": 1, "mask": 1}, + {"i": 840, "op": "mulhi", "dst": 5, "src": 3, "src2": 2, "imm": "0xcaaa2ed4", "imm2": "0x51753b2e", "rot": 8, "bit": 21, "mask": 2}, + {"i": 841, "op": "mad", "dst": 7, "src": 4, "src2": 6, "imm": "0x1cdaec8c", "imm2": "0xb824532a", "rot": 24, "bit": 26, "mask": 2}, + {"i": 842, "op": "add", "dst": 1, "src": 4, "src2": 7, "imm": "0xcfb90e90", "imm2": "0x1bc9f95d", "rot": 7, "bit": 21, "mask": 16}, + {"i": 843, "op": "add", "dst": 1, "src": 2, "src2": 4, "imm": "0x0b4758b6", "imm2": "0xf9bd620f", "rot": 22, "bit": 18, "mask": 2}, + {"i": 844, "op": "shfl", "dst": 2, "src": 5, "src2": 1, "imm": "0xba6c8184", "imm2": "0xf9805e7d", "rot": 12, "bit": 15, "mask": 16}, + {"i": 845, "op": "mad", "dst": 3, "src": 1, "src2": 7, "imm": "0x51f0ae1a", "imm2": "0xf844fedd", "rot": 26, "bit": 16, "mask": 16}, + {"i": 846, "op": "mul", "dst": 5, "src": 2, "src2": 5, "imm": "0xcb1a73f0", "imm2": "0x4a1f23d2", "rot": 8, "bit": 13, "mask": 16}, + {"i": 847, "op": "rotl", "dst": 0, "src": 2, "src2": 2, "imm": "0x4db3dd32", "imm2": "0xfda75c72", "rot": 21, "bit": 7, "mask": 8}, + {"i": 848, "op": "xor", "dst": 7, "src": 1, "src2": 7, "imm": "0x063a34c5", "imm2": "0xba8bdbe2", "rot": 6, "bit": 19, "mask": 2}, + {"i": 849, "op": "add", "dst": 3, "src": 4, "src2": 6, "imm": "0x41fdc15a", "imm2": "0x697a4946", "rot": 17, "bit": 18, "mask": 2}, + {"i": 850, "op": "shfl", "dst": 0, "src": 5, "src2": 6, "imm": "0xa9625a6e", "imm2": "0x605e46ae", "rot": 23, "bit": 31, "mask": 4}, + {"i": 851, "op": "rotr", "dst": 1, "src": 5, "src2": 4, "imm": "0x9834a2c3", "imm2": "0x8e48d96d", "rot": 24, "bit": 26, "mask": 2}, + {"i": 852, "op": "or", "dst": 5, "src": 6, "src2": 5, "imm": "0xd25de27a", "imm2": "0x7160924c", "rot": 8, "bit": 1, "mask": 2}, + {"i": 853, "op": "sub", "dst": 6, "src": 2, "src2": 5, "imm": "0x93410274", "imm2": "0x328dc9c7", "rot": 3, "bit": 27, "mask": 4}, + {"i": 854, "op": "xor", "dst": 2, "src": 6, "src2": 1, "imm": "0x667b541e", "imm2": "0xd72f409a", "rot": 24, "bit": 25, "mask": 1}, + {"i": 855, "op": "sub", "dst": 4, "src": 6, "src2": 4, "imm": "0x6f82ab70", "imm2": "0xc2f2d585", "rot": 8, "bit": 6, "mask": 4}, + {"i": 856, "op": "mad", "dst": 6, "src": 4, "src2": 6, "imm": "0xb117e54f", "imm2": "0x9f607aed", "rot": 5, "bit": 20, "mask": 1}, + {"i": 857, "op": "mul", "dst": 4, "src": 0, "src2": 1, "imm": "0x7d823ff6", "imm2": "0xd8d839b9", "rot": 14, "bit": 22, "mask": 1}, + {"i": 858, "op": "shfl", "dst": 2, "src": 1, "src2": 2, "imm": "0x3b94d7d4", "imm2": "0xec87eec0", "rot": 1, "bit": 16, "mask": 4}, + {"i": 859, "op": "mul", "dst": 3, "src": 4, "src2": 0, "imm": "0x4574c939", "imm2": "0xed266db4", "rot": 23, "bit": 25, "mask": 16}, + {"i": 860, "op": "mad", "dst": 3, "src": 1, "src2": 7, "imm": "0xc56d4af8", "imm2": "0x8d6cbb4f", "rot": 27, "bit": 16, "mask": 4}, + {"i": 861, "op": "shfl", "dst": 3, "src": 2, "src2": 4, "imm": "0x297f7621", "imm2": "0xbe720f68", "rot": 10, "bit": 25, "mask": 2}, + {"i": 862, "op": "shfl", "dst": 7, "src": 4, "src2": 4, "imm": "0x5a6fbd65", "imm2": "0x2f4d3675", "rot": 2, "bit": 20, "mask": 8}, + {"i": 863, "op": "mad", "dst": 0, "src": 2, "src2": 2, "imm": "0x779d6ed7", "imm2": "0xcbb9bf74", "rot": 14, "bit": 23, "mask": 8}, + {"i": 864, "op": "xor", "dst": 6, "src": 0, "src2": 0, "imm": "0xf5e4e963", "imm2": "0x841a5572", "rot": 1, "bit": 16, "mask": 1}, + {"i": 865, "op": "add", "dst": 6, "src": 2, "src2": 5, "imm": "0x90656f74", "imm2": "0x7fedd7f3", "rot": 14, "bit": 2, "mask": 2}, + {"i": 866, "op": "xor", "dst": 3, "src": 2, "src2": 2, "imm": "0x8c4634ed", "imm2": "0x6f378872", "rot": 16, "bit": 10, "mask": 1}, + {"i": 867, "op": "or", "dst": 1, "src": 4, "src2": 5, "imm": "0xb8efb1f2", "imm2": "0x321e55cc", "rot": 1, "bit": 9, "mask": 4}, + {"i": 868, "op": "shfl", "dst": 6, "src": 7, "src2": 7, "imm": "0x1358ef6a", "imm2": "0x572895e4", "rot": 31, "bit": 20, "mask": 2}, + {"i": 869, "op": "mulhi", "dst": 1, "src": 0, "src2": 5, "imm": "0x9f8791c6", "imm2": "0x9c38f8ea", "rot": 4, "bit": 5, "mask": 1}, + {"i": 870, "op": "shfl", "dst": 3, "src": 1, "src2": 0, "imm": "0xc0202ade", "imm2": "0x8a2fe137", "rot": 8, "bit": 20, "mask": 4}, + {"i": 871, "op": "sub", "dst": 0, "src": 3, "src2": 6, "imm": "0xb72e88be", "imm2": "0xaaba7d8b", "rot": 21, "bit": 17, "mask": 1}, + {"i": 872, "op": "add", "dst": 6, "src": 1, "src2": 5, "imm": "0xa5c0b461", "imm2": "0xbe1b480a", "rot": 4, "bit": 11, "mask": 16}, + {"i": 873, "op": "shfl", "dst": 3, "src": 6, "src2": 7, "imm": "0x68200158", "imm2": "0xd41affbe", "rot": 3, "bit": 1, "mask": 1}, + {"i": 874, "op": "shfl", "dst": 5, "src": 0, "src2": 1, "imm": "0x0c18b34d", "imm2": "0x2da7816a", "rot": 31, "bit": 26, "mask": 1}, + {"i": 875, "op": "mulhi", "dst": 2, "src": 4, "src2": 2, "imm": "0x2864ea76", "imm2": "0x90f70b8e", "rot": 8, "bit": 29, "mask": 1}, + {"i": 876, "op": "shfl", "dst": 5, "src": 7, "src2": 2, "imm": "0xec7bd43a", "imm2": "0xc68c28bd", "rot": 22, "bit": 26, "mask": 4}, + {"i": 877, "op": "rotl", "dst": 5, "src": 2, "src2": 7, "imm": "0x6f10ee78", "imm2": "0xd61faedf", "rot": 14, "bit": 19, "mask": 8}, + {"i": 878, "op": "xor", "dst": 2, "src": 7, "src2": 4, "imm": "0x1b3a9d6f", "imm2": "0x3fe164be", "rot": 8, "bit": 7, "mask": 16}, + {"i": 879, "op": "xor", "dst": 7, "src": 0, "src2": 7, "imm": "0xd82487d5", "imm2": "0x044e715c", "rot": 8, "bit": 16, "mask": 16}, + {"i": 880, "op": "mul", "dst": 0, "src": 2, "src2": 2, "imm": "0x435a18d9", "imm2": "0xeea8a6a8", "rot": 15, "bit": 30, "mask": 2}, + {"i": 881, "op": "mul", "dst": 4, "src": 2, "src2": 4, "imm": "0xc59af98e", "imm2": "0x0be62b2d", "rot": 20, "bit": 24, "mask": 2}, + {"i": 882, "op": "mul", "dst": 7, "src": 6, "src2": 6, "imm": "0x2061f407", "imm2": "0x32dd306e", "rot": 23, "bit": 5, "mask": 2}, + {"i": 883, "op": "mulhi", "dst": 4, "src": 5, "src2": 2, "imm": "0x38f7a2a5", "imm2": "0x4fe3d0c1", "rot": 14, "bit": 21, "mask": 1}, + {"i": 884, "op": "sub", "dst": 0, "src": 4, "src2": 7, "imm": "0x105f06d8", "imm2": "0xc72c7ec1", "rot": 24, "bit": 6, "mask": 2}, + {"i": 885, "op": "xor", "dst": 0, "src": 5, "src2": 0, "imm": "0x4f5cb879", "imm2": "0x7a4cfc7e", "rot": 2, "bit": 14, "mask": 4}, + {"i": 886, "op": "mul", "dst": 6, "src": 5, "src2": 0, "imm": "0xda0848f5", "imm2": "0xd4fc2997", "rot": 20, "bit": 2, "mask": 16}, + {"i": 887, "op": "add", "dst": 1, "src": 5, "src2": 5, "imm": "0xe806fcec", "imm2": "0x7007f98f", "rot": 27, "bit": 14, "mask": 4}, + {"i": 888, "op": "mul", "dst": 3, "src": 1, "src2": 2, "imm": "0x036b62a5", "imm2": "0x6af79d9d", "rot": 28, "bit": 25, "mask": 2}, + {"i": 889, "op": "xor", "dst": 5, "src": 3, "src2": 4, "imm": "0xe4dedd5e", "imm2": "0xe45b40df", "rot": 25, "bit": 10, "mask": 2}, + {"i": 890, "op": "or", "dst": 6, "src": 2, "src2": 3, "imm": "0x43edef17", "imm2": "0x6db0771f", "rot": 10, "bit": 8, "mask": 1}, + {"i": 891, "op": "mul", "dst": 1, "src": 2, "src2": 5, "imm": "0x610681d6", "imm2": "0x3528f38a", "rot": 19, "bit": 20, "mask": 1}, + {"i": 892, "op": "add", "dst": 5, "src": 7, "src2": 5, "imm": "0x89a8551e", "imm2": "0xf3c87e02", "rot": 13, "bit": 3, "mask": 1}, + {"i": 893, "op": "shfl", "dst": 2, "src": 4, "src2": 0, "imm": "0x96c02e27", "imm2": "0x0c7d2fa0", "rot": 6, "bit": 13, "mask": 16}, + {"i": 894, "op": "add", "dst": 1, "src": 3, "src2": 3, "imm": "0xba1369db", "imm2": "0xc315f5de", "rot": 5, "bit": 13, "mask": 1}, + {"i": 895, "op": "mad", "dst": 5, "src": 0, "src2": 3, "imm": "0xcbf900b9", "imm2": "0x383dc900", "rot": 25, "bit": 24, "mask": 2}, + {"i": 896, "op": "rotr", "dst": 5, "src": 2, "src2": 0, "imm": "0xd66f2411", "imm2": "0x0925d7da", "rot": 1, "bit": 31, "mask": 2}, + {"i": 897, "op": "xor", "dst": 1, "src": 0, "src2": 7, "imm": "0xacdf2e04", "imm2": "0x8e01fff6", "rot": 17, "bit": 26, "mask": 16}, + {"i": 898, "op": "xor", "dst": 5, "src": 1, "src2": 2, "imm": "0x76946002", "imm2": "0x3cfc0341", "rot": 3, "bit": 19, "mask": 8}, + {"i": 899, "op": "rotr", "dst": 5, "src": 1, "src2": 2, "imm": "0xc69ba2bd", "imm2": "0xcc97af4a", "rot": 24, "bit": 9, "mask": 8}, + {"i": 900, "op": "mad", "dst": 3, "src": 6, "src2": 6, "imm": "0xcaf75eb4", "imm2": "0x9f953d45", "rot": 21, "bit": 25, "mask": 8}, + {"i": 901, "op": "rotl", "dst": 0, "src": 4, "src2": 5, "imm": "0x3be4567f", "imm2": "0xd9eb6d2b", "rot": 8, "bit": 10, "mask": 1}, + {"i": 902, "op": "or", "dst": 1, "src": 0, "src2": 2, "imm": "0x9a115958", "imm2": "0x5a5a64ab", "rot": 30, "bit": 28, "mask": 16}, + {"i": 903, "op": "add", "dst": 1, "src": 2, "src2": 6, "imm": "0x260e6848", "imm2": "0x1c355a71", "rot": 13, "bit": 3, "mask": 4}, + {"i": 904, "op": "shfl", "dst": 7, "src": 2, "src2": 2, "imm": "0xc4c7e9bf", "imm2": "0xc2b59e20", "rot": 22, "bit": 8, "mask": 16}, + {"i": 905, "op": "mulhi", "dst": 1, "src": 3, "src2": 0, "imm": "0xa43d7045", "imm2": "0x0ee05ac3", "rot": 6, "bit": 25, "mask": 1}, + {"i": 906, "op": "rotr", "dst": 1, "src": 4, "src2": 2, "imm": "0x74b4805c", "imm2": "0xc7b17b36", "rot": 9, "bit": 15, "mask": 2}, + {"i": 907, "op": "add", "dst": 6, "src": 0, "src2": 2, "imm": "0xa74fd2b1", "imm2": "0x0c74a1a8", "rot": 11, "bit": 8, "mask": 8}, + {"i": 908, "op": "rotr", "dst": 6, "src": 2, "src2": 0, "imm": "0x1171654d", "imm2": "0x7adb8e13", "rot": 6, "bit": 18, "mask": 16}, + {"i": 909, "op": "rotl", "dst": 4, "src": 2, "src2": 4, "imm": "0xdda8a043", "imm2": "0x4d2b8da0", "rot": 12, "bit": 12, "mask": 4}, + {"i": 910, "op": "add", "dst": 5, "src": 3, "src2": 4, "imm": "0xe5fb043e", "imm2": "0xa49b5d73", "rot": 15, "bit": 29, "mask": 4}, + {"i": 911, "op": "xor", "dst": 3, "src": 0, "src2": 7, "imm": "0x66c112fc", "imm2": "0x1efd4816", "rot": 8, "bit": 0, "mask": 2}, + {"i": 912, "op": "rotr", "dst": 3, "src": 4, "src2": 0, "imm": "0x28252ac9", "imm2": "0xde6ad577", "rot": 10, "bit": 27, "mask": 8}, + {"i": 913, "op": "rotr", "dst": 6, "src": 0, "src2": 2, "imm": "0x5103c579", "imm2": "0x2e439ff9", "rot": 18, "bit": 5, "mask": 2}, + {"i": 914, "op": "xor", "dst": 2, "src": 5, "src2": 6, "imm": "0x2f817b84", "imm2": "0x37974f5b", "rot": 9, "bit": 2, "mask": 2}, + {"i": 915, "op": "mul", "dst": 0, "src": 7, "src2": 5, "imm": "0x792b0c7d", "imm2": "0x29c6fbc3", "rot": 19, "bit": 25, "mask": 16}, + {"i": 916, "op": "xor", "dst": 3, "src": 0, "src2": 5, "imm": "0x240d6897", "imm2": "0xd46e99bb", "rot": 23, "bit": 7, "mask": 2}, + {"i": 917, "op": "mad", "dst": 5, "src": 1, "src2": 7, "imm": "0x04d6fe3f", "imm2": "0x8a444d6b", "rot": 3, "bit": 20, "mask": 8}, + {"i": 918, "op": "add", "dst": 3, "src": 4, "src2": 0, "imm": "0x264cb47b", "imm2": "0xeb76e56c", "rot": 24, "bit": 2, "mask": 2}, + {"i": 919, "op": "mulhi", "dst": 3, "src": 4, "src2": 6, "imm": "0xa5fc0f54", "imm2": "0xd110ef97", "rot": 9, "bit": 24, "mask": 4}, + {"i": 920, "op": "add", "dst": 5, "src": 6, "src2": 7, "imm": "0x418baa72", "imm2": "0x2aab9631", "rot": 27, "bit": 9, "mask": 4}, + {"i": 921, "op": "mulhi", "dst": 5, "src": 1, "src2": 3, "imm": "0x31e4c077", "imm2": "0x96e524f3", "rot": 2, "bit": 22, "mask": 1}, + {"i": 922, "op": "sub", "dst": 7, "src": 3, "src2": 3, "imm": "0x0a7db3b6", "imm2": "0xaf5fdb0e", "rot": 24, "bit": 25, "mask": 4}, + {"i": 923, "op": "add", "dst": 6, "src": 1, "src2": 2, "imm": "0x3696a894", "imm2": "0x98e6b26d", "rot": 10, "bit": 2, "mask": 2}, + {"i": 924, "op": "mad", "dst": 6, "src": 3, "src2": 1, "imm": "0x40b0e710", "imm2": "0x196c0627", "rot": 20, "bit": 3, "mask": 2}, + {"i": 925, "op": "shfl", "dst": 2, "src": 1, "src2": 4, "imm": "0x10f51312", "imm2": "0xde22255a", "rot": 24, "bit": 31, "mask": 2}, + {"i": 926, "op": "xor", "dst": 6, "src": 1, "src2": 2, "imm": "0xd10cf7d3", "imm2": "0x0c8397f4", "rot": 14, "bit": 31, "mask": 2}, + {"i": 927, "op": "xor", "dst": 4, "src": 3, "src2": 2, "imm": "0xbf602cc2", "imm2": "0xffc651a2", "rot": 3, "bit": 10, "mask": 16}, + {"i": 928, "op": "add", "dst": 0, "src": 4, "src2": 3, "imm": "0x0468c062", "imm2": "0x142778ee", "rot": 21, "bit": 7, "mask": 1}, + {"i": 929, "op": "add", "dst": 7, "src": 3, "src2": 7, "imm": "0x0af82291", "imm2": "0x4eae212d", "rot": 12, "bit": 29, "mask": 2}, + {"i": 930, "op": "shfl", "dst": 4, "src": 7, "src2": 7, "imm": "0x85fef0d9", "imm2": "0x98668107", "rot": 29, "bit": 3, "mask": 16}, + {"i": 931, "op": "add", "dst": 7, "src": 2, "src2": 3, "imm": "0x17de5e29", "imm2": "0x8d2a8b36", "rot": 23, "bit": 20, "mask": 16}, + {"i": 932, "op": "add", "dst": 5, "src": 1, "src2": 4, "imm": "0x686794a8", "imm2": "0xe2d2d7d5", "rot": 22, "bit": 6, "mask": 16}, + {"i": 933, "op": "mulhi", "dst": 0, "src": 3, "src2": 2, "imm": "0x57b8be21", "imm2": "0xb9ffd505", "rot": 17, "bit": 16, "mask": 4}, + {"i": 934, "op": "add", "dst": 4, "src": 0, "src2": 7, "imm": "0x66278068", "imm2": "0xe3c3c6f9", "rot": 16, "bit": 10, "mask": 16}, + {"i": 935, "op": "rotl", "dst": 6, "src": 3, "src2": 6, "imm": "0x18d791a8", "imm2": "0x9b7ccf6c", "rot": 22, "bit": 4, "mask": 8}, + {"i": 936, "op": "or", "dst": 0, "src": 2, "src2": 7, "imm": "0x40f7b84a", "imm2": "0x80a024a3", "rot": 16, "bit": 6, "mask": 16}, + {"i": 937, "op": "mul", "dst": 4, "src": 3, "src2": 1, "imm": "0xc5d3b506", "imm2": "0x4180b7d8", "rot": 31, "bit": 25, "mask": 1}, + {"i": 938, "op": "or", "dst": 3, "src": 6, "src2": 2, "imm": "0x44580bba", "imm2": "0xd8a0a08b", "rot": 29, "bit": 14, "mask": 2}, + {"i": 939, "op": "rotl", "dst": 7, "src": 4, "src2": 2, "imm": "0xb13863d4", "imm2": "0x2708314d", "rot": 28, "bit": 23, "mask": 16}, + {"i": 940, "op": "add", "dst": 0, "src": 6, "src2": 2, "imm": "0xc2d02ca6", "imm2": "0xc2296063", "rot": 25, "bit": 20, "mask": 8}, + {"i": 941, "op": "add", "dst": 1, "src": 5, "src2": 2, "imm": "0x0b3c00e0", "imm2": "0xef1ca415", "rot": 5, "bit": 14, "mask": 8}, + {"i": 942, "op": "sub", "dst": 2, "src": 6, "src2": 3, "imm": "0x7c7b17ae", "imm2": "0x4e3d978d", "rot": 25, "bit": 30, "mask": 16}, + {"i": 943, "op": "or", "dst": 6, "src": 3, "src2": 1, "imm": "0x24b8acd4", "imm2": "0x90a2fb3f", "rot": 24, "bit": 15, "mask": 1}, + {"i": 944, "op": "rotl", "dst": 0, "src": 2, "src2": 1, "imm": "0xcacef810", "imm2": "0xce010b8f", "rot": 2, "bit": 3, "mask": 4}, + {"i": 945, "op": "mul", "dst": 2, "src": 1, "src2": 5, "imm": "0x22c1c671", "imm2": "0x05b984f7", "rot": 29, "bit": 9, "mask": 8}, + {"i": 946, "op": "add", "dst": 0, "src": 6, "src2": 0, "imm": "0x11224846", "imm2": "0x06a1321a", "rot": 30, "bit": 1, "mask": 4}, + {"i": 947, "op": "mul", "dst": 3, "src": 6, "src2": 6, "imm": "0xf9fcff47", "imm2": "0x0b24fc3c", "rot": 4, "bit": 22, "mask": 8}, + {"i": 948, "op": "sub", "dst": 5, "src": 2, "src2": 1, "imm": "0xa7d91d3a", "imm2": "0x9ec9dbc5", "rot": 12, "bit": 20, "mask": 16}, + {"i": 949, "op": "add", "dst": 5, "src": 4, "src2": 1, "imm": "0x461c43d4", "imm2": "0x5d3e225c", "rot": 9, "bit": 5, "mask": 1}, + {"i": 950, "op": "shfl", "dst": 2, "src": 1, "src2": 1, "imm": "0x6bda9ce0", "imm2": "0xa453527b", "rot": 15, "bit": 4, "mask": 16}, + {"i": 951, "op": "mad", "dst": 7, "src": 0, "src2": 0, "imm": "0xc3e59bd1", "imm2": "0xedb2982e", "rot": 5, "bit": 19, "mask": 16}, + {"i": 952, "op": "rotr", "dst": 6, "src": 4, "src2": 3, "imm": "0x9fb2bfa7", "imm2": "0x0b3ef145", "rot": 1, "bit": 26, "mask": 1}, + {"i": 953, "op": "add", "dst": 1, "src": 0, "src2": 7, "imm": "0xd5eed39f", "imm2": "0xbb84f628", "rot": 26, "bit": 30, "mask": 8}, + {"i": 954, "op": "rotl", "dst": 4, "src": 0, "src2": 3, "imm": "0x25fb44ad", "imm2": "0x62109a59", "rot": 31, "bit": 8, "mask": 1}, + {"i": 955, "op": "shfl", "dst": 1, "src": 2, "src2": 1, "imm": "0xe428f68f", "imm2": "0xf11a58da", "rot": 12, "bit": 4, "mask": 16}, + {"i": 956, "op": "sub", "dst": 2, "src": 6, "src2": 5, "imm": "0x6dd78ee9", "imm2": "0x4ffd4543", "rot": 20, "bit": 0, "mask": 16}, + {"i": 957, "op": "xor", "dst": 4, "src": 2, "src2": 5, "imm": "0xcee43ef4", "imm2": "0xf35aeb07", "rot": 18, "bit": 1, "mask": 1}, + {"i": 958, "op": "xor", "dst": 0, "src": 2, "src2": 5, "imm": "0x527f596d", "imm2": "0xa6f9b25a", "rot": 4, "bit": 8, "mask": 2}, + {"i": 959, "op": "add", "dst": 1, "src": 0, "src2": 0, "imm": "0x519d72f7", "imm2": "0x374c0426", "rot": 19, "bit": 28, "mask": 8}, + {"i": 960, "op": "mul", "dst": 5, "src": 4, "src2": 0, "imm": "0xe92cddfc", "imm2": "0x6d0833ea", "rot": 31, "bit": 7, "mask": 16}, + {"i": 961, "op": "sub", "dst": 5, "src": 7, "src2": 0, "imm": "0x334be308", "imm2": "0xd439d780", "rot": 6, "bit": 17, "mask": 2}, + {"i": 962, "op": "xor", "dst": 2, "src": 6, "src2": 2, "imm": "0x52012518", "imm2": "0x3183d892", "rot": 28, "bit": 28, "mask": 16}, + {"i": 963, "op": "xor", "dst": 4, "src": 1, "src2": 3, "imm": "0xd4e42ed8", "imm2": "0x94d4b3e2", "rot": 15, "bit": 16, "mask": 16}, + {"i": 964, "op": "shfl", "dst": 2, "src": 4, "src2": 0, "imm": "0x8a6f3322", "imm2": "0xb1a4dd06", "rot": 18, "bit": 1, "mask": 16}, + {"i": 965, "op": "mulhi", "dst": 7, "src": 3, "src2": 2, "imm": "0x186e9862", "imm2": "0x96471db4", "rot": 3, "bit": 13, "mask": 8}, + {"i": 966, "op": "rotl", "dst": 4, "src": 2, "src2": 3, "imm": "0x12ac7c7f", "imm2": "0xc6603066", "rot": 12, "bit": 3, "mask": 1}, + {"i": 967, "op": "add", "dst": 4, "src": 6, "src2": 3, "imm": "0x151dae18", "imm2": "0x03b88592", "rot": 28, "bit": 26, "mask": 8}, + {"i": 968, "op": "shfl", "dst": 1, "src": 3, "src2": 0, "imm": "0xe9c2294a", "imm2": "0x036787dd", "rot": 14, "bit": 27, "mask": 4}, + {"i": 969, "op": "shfl", "dst": 3, "src": 6, "src2": 4, "imm": "0xefa4379b", "imm2": "0x345d5633", "rot": 4, "bit": 21, "mask": 8}, + {"i": 970, "op": "xor", "dst": 2, "src": 7, "src2": 4, "imm": "0xd76b0ad5", "imm2": "0x73d2c3c9", "rot": 29, "bit": 4, "mask": 1}, + {"i": 971, "op": "mad", "dst": 5, "src": 3, "src2": 4, "imm": "0xe4dea7e4", "imm2": "0x66d96cae", "rot": 26, "bit": 30, "mask": 16}, + {"i": 972, "op": "xor", "dst": 0, "src": 3, "src2": 1, "imm": "0xedffd55d", "imm2": "0x48491c3c", "rot": 10, "bit": 6, "mask": 4}, + {"i": 973, "op": "xor", "dst": 2, "src": 5, "src2": 7, "imm": "0x1498b23f", "imm2": "0xc4a4cc25", "rot": 3, "bit": 29, "mask": 8}, + {"i": 974, "op": "shfl", "dst": 1, "src": 0, "src2": 7, "imm": "0x0b763b65", "imm2": "0x06009687", "rot": 23, "bit": 15, "mask": 4}, + {"i": 975, "op": "mad", "dst": 5, "src": 1, "src2": 4, "imm": "0x61513e6e", "imm2": "0xd01e41cd", "rot": 8, "bit": 8, "mask": 2}, + {"i": 976, "op": "rotl", "dst": 2, "src": 7, "src2": 6, "imm": "0xeeba0186", "imm2": "0x5f0c21de", "rot": 19, "bit": 26, "mask": 2}, + {"i": 977, "op": "sub", "dst": 1, "src": 4, "src2": 3, "imm": "0x3cef378c", "imm2": "0xf03c410e", "rot": 19, "bit": 16, "mask": 8}, + {"i": 978, "op": "rotr", "dst": 5, "src": 4, "src2": 2, "imm": "0xa2df2fba", "imm2": "0xd57bb76e", "rot": 26, "bit": 28, "mask": 2}, + {"i": 979, "op": "shfl", "dst": 2, "src": 1, "src2": 5, "imm": "0x711301b6", "imm2": "0xf1dcee6f", "rot": 16, "bit": 20, "mask": 16}, + {"i": 980, "op": "add", "dst": 6, "src": 7, "src2": 7, "imm": "0x16220e61", "imm2": "0x1fdee45e", "rot": 1, "bit": 28, "mask": 2}, + {"i": 981, "op": "rotr", "dst": 4, "src": 6, "src2": 5, "imm": "0x7df06c17", "imm2": "0x153e2a9a", "rot": 20, "bit": 31, "mask": 16}, + {"i": 982, "op": "mulhi", "dst": 6, "src": 3, "src2": 6, "imm": "0xc837247a", "imm2": "0x0fff153e", "rot": 2, "bit": 4, "mask": 16}, + {"i": 983, "op": "rotl", "dst": 5, "src": 4, "src2": 6, "imm": "0xff0911d3", "imm2": "0x307119f0", "rot": 17, "bit": 9, "mask": 16}, + {"i": 984, "op": "mad", "dst": 2, "src": 7, "src2": 1, "imm": "0x000006b7", "imm2": "0x5465c7d9", "rot": 16, "bit": 12, "mask": 16}, + {"i": 985, "op": "shfl", "dst": 4, "src": 1, "src2": 1, "imm": "0x1a35cd4c", "imm2": "0x328c5ea9", "rot": 23, "bit": 11, "mask": 8}, + {"i": 986, "op": "xor", "dst": 3, "src": 1, "src2": 7, "imm": "0x8c909439", "imm2": "0x07659904", "rot": 27, "bit": 26, "mask": 8}, + {"i": 987, "op": "add", "dst": 4, "src": 0, "src2": 0, "imm": "0x6cd6b697", "imm2": "0x44adc457", "rot": 28, "bit": 27, "mask": 8}, + {"i": 988, "op": "mul", "dst": 1, "src": 5, "src2": 2, "imm": "0x301d698f", "imm2": "0xc9ef956f", "rot": 16, "bit": 21, "mask": 4}, + {"i": 989, "op": "add", "dst": 4, "src": 2, "src2": 7, "imm": "0x1103d2d2", "imm2": "0x0a06a223", "rot": 6, "bit": 2, "mask": 2}, + {"i": 990, "op": "mul", "dst": 4, "src": 1, "src2": 7, "imm": "0x36a19dea", "imm2": "0xa430da56", "rot": 17, "bit": 14, "mask": 1}, + {"i": 991, "op": "mad", "dst": 4, "src": 5, "src2": 1, "imm": "0xf71a5298", "imm2": "0x0f7b3ab6", "rot": 16, "bit": 1, "mask": 4}, + {"i": 992, "op": "shfl", "dst": 3, "src": 6, "src2": 7, "imm": "0x88e0fa98", "imm2": "0xcab24e67", "rot": 11, "bit": 1, "mask": 1}, + {"i": 993, "op": "sub", "dst": 1, "src": 3, "src2": 6, "imm": "0x3fe7bcb0", "imm2": "0x26cb7666", "rot": 11, "bit": 23, "mask": 4}, + {"i": 994, "op": "mad", "dst": 4, "src": 7, "src2": 5, "imm": "0x36190da3", "imm2": "0x77223ab4", "rot": 27, "bit": 21, "mask": 16}, + {"i": 995, "op": "mulhi", "dst": 1, "src": 2, "src2": 5, "imm": "0x22516c19", "imm2": "0xfe162249", "rot": 1, "bit": 9, "mask": 16}, + {"i": 996, "op": "mad", "dst": 2, "src": 1, "src2": 0, "imm": "0xf831c64d", "imm2": "0xbf576f4a", "rot": 19, "bit": 21, "mask": 2}, + {"i": 997, "op": "rotl", "dst": 3, "src": 7, "src2": 3, "imm": "0x413c58ed", "imm2": "0x62cc7e93", "rot": 31, "bit": 21, "mask": 1}, + {"i": 998, "op": "sub", "dst": 4, "src": 3, "src2": 2, "imm": "0x8851c0fd", "imm2": "0x08c2dee8", "rot": 9, "bit": 24, "mask": 2}, + {"i": 999, "op": "rotr", "dst": 5, "src": 3, "src2": 4, "imm": "0x90a759c1", "imm2": "0x2ec151f8", "rot": 14, "bit": 26, "mask": 8}, + {"i": 1000, "op": "shfl", "dst": 4, "src": 0, "src2": 0, "imm": "0x6b17577e", "imm2": "0xc08b98a5", "rot": 30, "bit": 1, "mask": 4}, + {"i": 1001, "op": "sub", "dst": 2, "src": 5, "src2": 3, "imm": "0xf41ec916", "imm2": "0x2bc6eef3", "rot": 17, "bit": 12, "mask": 16}, + {"i": 1002, "op": "mad", "dst": 3, "src": 4, "src2": 4, "imm": "0xed540092", "imm2": "0x337ea135", "rot": 28, "bit": 31, "mask": 2}, + {"i": 1003, "op": "mad", "dst": 7, "src": 5, "src2": 1, "imm": "0x28712499", "imm2": "0xfd03d027", "rot": 18, "bit": 23, "mask": 8}, + {"i": 1004, "op": "add", "dst": 7, "src": 4, "src2": 6, "imm": "0xa9c9d8a9", "imm2": "0x0044887f", "rot": 16, "bit": 29, "mask": 1}, + {"i": 1005, "op": "mulhi", "dst": 4, "src": 0, "src2": 0, "imm": "0x6b8395a0", "imm2": "0xaa2511f3", "rot": 8, "bit": 28, "mask": 16}, + {"i": 1006, "op": "rotl", "dst": 4, "src": 5, "src2": 6, "imm": "0xfc4bbe23", "imm2": "0xdf3d0cf7", "rot": 21, "bit": 11, "mask": 8}, + {"i": 1007, "op": "mul", "dst": 3, "src": 1, "src2": 4, "imm": "0x2243fae9", "imm2": "0x721a8001", "rot": 19, "bit": 16, "mask": 1}, + {"i": 1008, "op": "shfl", "dst": 1, "src": 5, "src2": 6, "imm": "0xf6cfc873", "imm2": "0x1613568d", "rot": 30, "bit": 27, "mask": 2}, + {"i": 1009, "op": "mulhi", "dst": 0, "src": 6, "src2": 4, "imm": "0x92273f24", "imm2": "0x507efb37", "rot": 11, "bit": 26, "mask": 8}, + {"i": 1010, "op": "xor", "dst": 0, "src": 3, "src2": 7, "imm": "0x6b940fcd", "imm2": "0xef08aa5e", "rot": 10, "bit": 8, "mask": 16}, + {"i": 1011, "op": "or", "dst": 5, "src": 4, "src2": 0, "imm": "0xeb382e5e", "imm2": "0x6e68ea5e", "rot": 8, "bit": 3, "mask": 4}, + {"i": 1012, "op": "shfl", "dst": 1, "src": 5, "src2": 0, "imm": "0x1ba0f3fc", "imm2": "0x8a5fa410", "rot": 11, "bit": 3, "mask": 4}, + {"i": 1013, "op": "add", "dst": 2, "src": 4, "src2": 7, "imm": "0xfa1574e3", "imm2": "0x6b70e2c7", "rot": 20, "bit": 4, "mask": 8}, + {"i": 1014, "op": "rotr", "dst": 5, "src": 7, "src2": 5, "imm": "0xacb311e7", "imm2": "0x23e38c4f", "rot": 24, "bit": 31, "mask": 1}, + {"i": 1015, "op": "rotr", "dst": 0, "src": 7, "src2": 7, "imm": "0xeb5e3b01", "imm2": "0xa645f53b", "rot": 3, "bit": 26, "mask": 2}, + {"i": 1016, "op": "sub", "dst": 5, "src": 7, "src2": 5, "imm": "0x245b0ff6", "imm2": "0x7cb303f6", "rot": 8, "bit": 0, "mask": 2}, + {"i": 1017, "op": "shfl", "dst": 4, "src": 1, "src2": 2, "imm": "0xfc0f06c8", "imm2": "0x2c2e667d", "rot": 25, "bit": 0, "mask": 16}, + {"i": 1018, "op": "mulhi", "dst": 6, "src": 7, "src2": 5, "imm": "0x06c825c8", "imm2": "0x1a24fdc4", "rot": 23, "bit": 26, "mask": 2}, + {"i": 1019, "op": "rotr", "dst": 0, "src": 1, "src2": 2, "imm": "0x951b3932", "imm2": "0x9c7fd750", "rot": 11, "bit": 22, "mask": 2}, + {"i": 1020, "op": "xor", "dst": 2, "src": 0, "src2": 4, "imm": "0x6ae332da", "imm2": "0x4b6e47fd", "rot": 3, "bit": 31, "mask": 2}, + {"i": 1021, "op": "mad", "dst": 4, "src": 5, "src2": 1, "imm": "0x86a2a11f", "imm2": "0xb391674c", "rot": 15, "bit": 7, "mask": 16}, + {"i": 1022, "op": "or", "dst": 6, "src": 2, "src2": 6, "imm": "0x6b37224b", "imm2": "0x6e0366aa", "rot": 7, "bit": 26, "mask": 4}, + {"i": 1023, "op": "xor", "dst": 3, "src": 0, "src2": 1, "imm": "0xde591d91", "imm2": "0xcff427af", "rot": 14, "bit": 28, "mask": 8} + ]}, + "instructions": [ + {"i": 0, "op": "mad", "dst": 2, "src": 3, "src2": 4, "imm": "0xbf7b174d", "imm2": "0x337b762e", "rot": 17, "bit": 2, "mask": 2, "width": 1}, + {"i": 1, "op": "mad", "dst": 2, "src": 1, "src2": 1, "imm": "0xdd04a5da", "imm2": "0x42da7657", "rot": 15, "bit": 30, "mask": 16, "width": 1}, + {"i": 2, "op": "mad", "dst": 2, "src": 3, "src2": 2, "imm": "0x734003fa", "imm2": "0x5bb67700", "rot": 3, "bit": 20, "mask": 1, "width": 1}, + {"i": 3, "op": "xor", "dst": 3, "src": 5, "src2": 5, "imm": "0xc55a1b1c", "imm2": "0xa19720f3", "rot": 7, "bit": 8, "mask": 1, "width": 1}, + {"i": 4, "op": "load", "dst": 7, "src": 2, "src2": 5, "imm": "0xad572dd7", "imm2": "0x9ceb3ea7", "rot": 18, "bit": 30, "mask": 2, "width": 1}, + {"i": 5, "op": "load", "dst": 5, "src": 7, "src2": 3, "imm": "0x769a53be", "imm2": "0x80f9067e", "rot": 12, "bit": 22, "mask": 1, "width": 1}, + {"i": 6, "op": "shfl", "dst": 1, "src": 4, "src2": 0, "imm": "0xd3613d88", "imm2": "0x262fb219", "rot": 10, "bit": 30, "mask": 8, "width": 1}, + {"i": 7, "op": "shfl", "dst": 7, "src": 3, "src2": 4, "imm": "0xce38e42f", "imm2": "0xb868b818", "rot": 11, "bit": 8, "mask": 8, "width": 1}, + {"i": 8, "op": "mulhi", "dst": 1, "src": 5, "src2": 2, "imm": "0xa5eebca5", "imm2": "0x5703a72b", "rot": 13, "bit": 13, "mask": 16, "width": 1}, + {"i": 9, "op": "rotr", "dst": 6, "src": 3, "src2": 4, "imm": "0x17a5a9c7", "imm2": "0xdcfb93a1", "rot": 20, "bit": 27, "mask": 2, "width": 1}, + {"i": 10, "op": "or", "dst": 3, "src": 4, "src2": 1, "imm": "0xccb7d785", "imm2": "0xc335364c", "rot": 14, "bit": 12, "mask": 4, "width": 1}, + {"i": 11, "op": "load", "dst": 4, "src": 3, "src2": 2, "imm": "0x88cb9af3", "imm2": "0x4e7dc10d", "rot": 24, "bit": 17, "mask": 4, "width": 1}, + {"i": 12, "op": "mulhi", "dst": 0, "src": 4, "src2": 4, "imm": "0x45374321", "imm2": "0x3cd91989", "rot": 11, "bit": 4, "mask": 2, "width": 1}, + {"i": 13, "op": "add", "dst": 5, "src": 1, "src2": 2, "imm": "0xc7934706", "imm2": "0xd3177981", "rot": 16, "bit": 30, "mask": 2, "width": 1}, + {"i": 14, "op": "load", "dst": 0, "src": 4, "src2": 3, "imm": "0xfd7f56bb", "imm2": "0x65e14f52", "rot": 13, "bit": 22, "mask": 2, "width": 1}, + {"i": 15, "op": "sub", "dst": 2, "src": 4, "src2": 4, "imm": "0x35a80b49", "imm2": "0x060f2d13", "rot": 16, "bit": 20, "mask": 16, "width": 1}, + {"i": 16, "op": "load", "dst": 2, "src": 0, "src2": 2, "imm": "0xae0a32c2", "imm2": "0x4c2a4cfe", "rot": 8, "bit": 31, "mask": 16, "width": 1}, + {"i": 17, "op": "load", "dst": 7, "src": 2, "src2": 6, "imm": "0x82a84cc3", "imm2": "0x21a38d68", "rot": 15, "bit": 21, "mask": 2, "width": 1}, + {"i": 18, "op": "shfl", "dst": 7, "src": 3, "src2": 3, "imm": "0xa3818806", "imm2": "0x8f66b5c8", "rot": 14, "bit": 6, "mask": 4, "width": 1}, + {"i": 19, "op": "mul", "dst": 5, "src": 0, "src2": 1, "imm": "0xa00de107", "imm2": "0x77bfcaa5", "rot": 3, "bit": 10, "mask": 2, "width": 1}, + {"i": 20, "op": "shfl", "dst": 3, "src": 4, "src2": 7, "imm": "0x1d2b8cab", "imm2": "0x80b4f9a2", "rot": 14, "bit": 25, "mask": 2, "width": 1}, + {"i": 21, "op": "shfl", "dst": 2, "src": 4, "src2": 5, "imm": "0x3ac915d2", "imm2": "0x5fba7bc2", "rot": 16, "bit": 1, "mask": 16, "width": 1}, + {"i": 22, "op": "mulhi", "dst": 6, "src": 2, "src2": 0, "imm": "0xdc3ec8fd", "imm2": "0x599e2fa3", "rot": 22, "bit": 3, "mask": 2, "width": 1}, + {"i": 23, "op": "load", "dst": 6, "src": 1, "src2": 5, "imm": "0x2a6b16d5", "imm2": "0xd73e396f", "rot": 28, "bit": 29, "mask": 2, "width": 1}, + {"i": 24, "op": "mul", "dst": 5, "src": 0, "src2": 7, "imm": "0x376d0223", "imm2": "0xe1c2169a", "rot": 4, "bit": 16, "mask": 16, "width": 1}, + {"i": 25, "op": "rotl", "dst": 5, "src": 7, "src2": 3, "imm": "0x78ad8c60", "imm2": "0x6f5b77d5", "rot": 19, "bit": 11, "mask": 16, "width": 1}, + {"i": 26, "op": "shfl", "dst": 7, "src": 6, "src2": 5, "imm": "0x93915b9f", "imm2": "0x1e61fb6b", "rot": 28, "bit": 23, "mask": 2, "width": 1}, + {"i": 27, "op": "xor", "dst": 0, "src": 5, "src2": 7, "imm": "0x6378fe15", "imm2": "0x66c78f42", "rot": 12, "bit": 31, "mask": 8, "width": 1}, + {"i": 28, "op": "xor", "dst": 0, "src": 4, "src2": 7, "imm": "0x20a57fda", "imm2": "0x088c848e", "rot": 16, "bit": 13, "mask": 4, "width": 1}, + {"i": 29, "op": "sub", "dst": 3, "src": 0, "src2": 2, "imm": "0x49d95fd5", "imm2": "0x1a5f946a", "rot": 6, "bit": 12, "mask": 1, "width": 1}, + {"i": 30, "op": "mul", "dst": 5, "src": 1, "src2": 7, "imm": "0x0a816217", "imm2": "0x405c4f73", "rot": 13, "bit": 27, "mask": 4, "width": 1}, + {"i": 31, "op": "load", "dst": 7, "src": 2, "src2": 2, "imm": "0x09ed045e", "imm2": "0xd69c4715", "rot": 5, "bit": 9, "mask": 2, "width": 1}, + {"i": 32, "op": "load", "dst": 1, "src": 0, "src2": 6, "imm": "0xeb79ea49", "imm2": "0xcc587f5a", "rot": 6, "bit": 8, "mask": 16, "width": 1}, + {"i": 33, "op": "xor", "dst": 5, "src": 6, "src2": 1, "imm": "0x3027401e", "imm2": "0x5f20c27e", "rot": 18, "bit": 9, "mask": 2, "width": 1}, + {"i": 34, "op": "load", "dst": 5, "src": 1, "src2": 3, "imm": "0x0e1cab07", "imm2": "0x09356c5b", "rot": 19, "bit": 31, "mask": 1, "width": 1}, + {"i": 35, "op": "mulhi", "dst": 0, "src": 5, "src2": 2, "imm": "0x90e31357", "imm2": "0xabd32484", "rot": 26, "bit": 5, "mask": 8, "width": 1}, + {"i": 36, "op": "shfl", "dst": 5, "src": 2, "src2": 5, "imm": "0xee9a955f", "imm2": "0x31b3faed", "rot": 8, "bit": 24, "mask": 4, "width": 1}, + {"i": 37, "op": "load", "dst": 7, "src": 0, "src2": 7, "imm": "0x3ba2f832", "imm2": "0x1160dcd3", "rot": 4, "bit": 29, "mask": 1, "width": 1}, + {"i": 38, "op": "add", "dst": 3, "src": 1, "src2": 7, "imm": "0x75ba2fad", "imm2": "0x230c005c", "rot": 4, "bit": 27, "mask": 1, "width": 1}, + {"i": 39, "op": "shfl", "dst": 1, "src": 5, "src2": 3, "imm": "0xdbf37e75", "imm2": "0xb5ac1969", "rot": 30, "bit": 13, "mask": 4, "width": 1}, + {"i": 40, "op": "xor", "dst": 2, "src": 5, "src2": 5, "imm": "0x47f136c5", "imm2": "0x06ce9153", "rot": 19, "bit": 10, "mask": 2, "width": 1}, + {"i": 41, "op": "mad", "dst": 3, "src": 6, "src2": 3, "imm": "0xce13eff8", "imm2": "0x04cc1d55", "rot": 3, "bit": 1, "mask": 4, "width": 1}, + {"i": 42, "op": "sub", "dst": 6, "src": 7, "src2": 1, "imm": "0x6a65ab71", "imm2": "0x8fbc1bcd", "rot": 4, "bit": 1, "mask": 8, "width": 1}, + {"i": 43, "op": "xor", "dst": 7, "src": 0, "src2": 7, "imm": "0xdaeb4928", "imm2": "0xc0423027", "rot": 24, "bit": 11, "mask": 8, "width": 1}, + {"i": 44, "op": "load", "dst": 1, "src": 7, "src2": 7, "imm": "0x778f01c9", "imm2": "0x28cedcea", "rot": 12, "bit": 4, "mask": 16, "width": 1}, + {"i": 45, "op": "mul", "dst": 2, "src": 3, "src2": 2, "imm": "0xf4264f1b", "imm2": "0x0f627d56", "rot": 5, "bit": 28, "mask": 8, "width": 1}, + {"i": 46, "op": "mulhi", "dst": 1, "src": 5, "src2": 1, "imm": "0xffb2147a", "imm2": "0xccde9b05", "rot": 13, "bit": 9, "mask": 2, "width": 1}, + {"i": 47, "op": "sub", "dst": 4, "src": 3, "src2": 5, "imm": "0x73b36234", "imm2": "0x3f5d5997", "rot": 7, "bit": 18, "mask": 2, "width": 1}, + {"i": 48, "op": "rotr", "dst": 2, "src": 6, "src2": 3, "imm": "0x3a4d9aa9", "imm2": "0x212bec7b", "rot": 4, "bit": 29, "mask": 16, "width": 1}, + {"i": 49, "op": "load", "dst": 3, "src": 5, "src2": 2, "imm": "0x626f11df", "imm2": "0x56cd5bfd", "rot": 7, "bit": 1, "mask": 1, "width": 1}, + {"i": 50, "op": "add", "dst": 1, "src": 5, "src2": 6, "imm": "0x81b8bc2c", "imm2": "0x1907970c", "rot": 28, "bit": 7, "mask": 4, "width": 1}, + {"i": 51, "op": "mul", "dst": 0, "src": 2, "src2": 2, "imm": "0xa8848b30", "imm2": "0xef6ac348", "rot": 9, "bit": 15, "mask": 8, "width": 1}, + {"i": 52, "op": "add", "dst": 0, "src": 2, "src2": 0, "imm": "0x4f92b968", "imm2": "0x699fd448", "rot": 22, "bit": 6, "mask": 4, "width": 1}, + {"i": 53, "op": "add", "dst": 1, "src": 0, "src2": 2, "imm": "0x2bb965af", "imm2": "0x77b1520d", "rot": 2, "bit": 12, "mask": 8, "width": 1}, + {"i": 54, "op": "rotl", "dst": 7, "src": 1, "src2": 0, "imm": "0x553e678b", "imm2": "0x3cc8eae0", "rot": 14, "bit": 20, "mask": 2, "width": 1}, + {"i": 55, "op": "add", "dst": 3, "src": 7, "src2": 2, "imm": "0x7b0fe07a", "imm2": "0xa54c55a0", "rot": 10, "bit": 1, "mask": 1, "width": 1}, + {"i": 56, "op": "load", "dst": 6, "src": 7, "src2": 4, "imm": "0x01eba9aa", "imm2": "0x2758c0f7", "rot": 14, "bit": 15, "mask": 4, "width": 1}, + {"i": 57, "op": "rotr", "dst": 1, "src": 5, "src2": 2, "imm": "0x1f5267b3", "imm2": "0x236f5a27", "rot": 2, "bit": 31, "mask": 16, "width": 1}, + {"i": 58, "op": "load", "dst": 5, "src": 4, "src2": 3, "imm": "0xa9954a9b", "imm2": "0x6a54d4e8", "rot": 11, "bit": 10, "mask": 16, "width": 1}, + {"i": 59, "op": "load", "dst": 6, "src": 2, "src2": 4, "imm": "0x9923ff88", "imm2": "0x9357254e", "rot": 16, "bit": 1, "mask": 16, "width": 1}, + {"i": 60, "op": "mad", "dst": 3, "src": 5, "src2": 0, "imm": "0xc0cc51a6", "imm2": "0x3fd7701b", "rot": 20, "bit": 1, "mask": 4, "width": 1}, + {"i": 61, "op": "add", "dst": 5, "src": 7, "src2": 7, "imm": "0xaf9dd72d", "imm2": "0xad7493e7", "rot": 7, "bit": 31, "mask": 16, "width": 1}, + {"i": 62, "op": "add", "dst": 4, "src": 6, "src2": 2, "imm": "0x89841d87", "imm2": "0x1e07c3d9", "rot": 6, "bit": 27, "mask": 1, "width": 1}, + {"i": 63, "op": "rotl", "dst": 5, "src": 4, "src2": 2, "imm": "0xae210f8d", "imm2": "0x8e499ba4", "rot": 19, "bit": 9, "mask": 1, "width": 1} + ] +} diff --git a/proto-cuda/packs-ca3-shadow/sh1024x3/program.metal b/proto-cuda/packs-ca3-shadow/sh1024x3/program.metal new file mode 100644 index 000000000..369b72183 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh1024x3/program.metal @@ -0,0 +1,1136 @@ +#include +using namespace metal; + +#define MASK 0x0fffffffu +constant uint SEEDW[8] = { 0x67a9a7beu, 0x1a155b25u, 0xfddfb732u, 0x4b5af2e8u, 0xc55caf33u, 0xa27c13b7u, 0x06628a48u, 0x03852469u }; + +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 = r3 * r4 + r2; // 0 + r2 = r1 * r1 + r2; // 1 + r2 = r3 * r2 + r2; // 2 + r3 = r3 ^ r5; // 3 + r7 = r7 ^ dataset[r2 & MASK]; // 4 + r5 = r5 ^ dataset[r7 & MASK]; // 5 + r1 = r1 ^ simd_shuffle_xor(r4, (ushort)8); // 6 + r7 = r7 ^ simd_shuffle_xor(r3, (ushort)8); // 7 + r1 = mulhi(r1, r5); // 8 + r6 = rotr_var(r6, r3); // 9 + r3 = r3 | r4; // 10 + r4 = r4 ^ dataset[r3 & MASK]; // 11 + r0 = mulhi(r0, r4); // 12 + r5 = r5 + r1 + select(0xc7934706u, 0xd3177981u, ((sel >> 30u) & 1u) != 0u); // 13 + r0 = r0 ^ dataset[r4 & MASK]; // 14 + r2 = r2 - r4; // 15 + r2 = r2 ^ dataset[r0 & MASK]; // 16 + r7 = r7 ^ dataset[r2 & MASK]; // 17 + r7 = r7 ^ simd_shuffle_xor(r3, (ushort)4); // 18 + r5 = r5 * r0; // 19 + r3 = r3 ^ simd_shuffle_xor(r4, (ushort)2); // 20 + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)16); // 21 + r6 = mulhi(r6, r2); // 22 + r6 = r6 ^ dataset[r1 & MASK]; // 23 + r5 = r5 * r0; // 24 + r5 = rotl_imm(r5, 19u); // 25 + r7 = r7 ^ simd_shuffle_xor(r6, (ushort)2); // 26 + r0 = r0 ^ r5; // 27 + r0 = r0 ^ r4; // 28 + r3 = r3 - r0; // 29 + r5 = r5 * r1; // 30 + r7 = r7 ^ dataset[r2 & MASK]; // 31 + r1 = r1 ^ dataset[r0 & MASK]; // 32 + r5 = r5 ^ r6; // 33 + r5 = r5 ^ dataset[r1 & MASK]; // 34 + r0 = mulhi(r0, r5); // 35 + r5 = r5 ^ simd_shuffle_xor(r2, (ushort)4); // 36 + r7 = r7 ^ dataset[r0 & MASK]; // 37 + r3 = r3 + r1 + select(0x75ba2fadu, 0x230c005cu, ((sel >> 27u) & 1u) != 0u); // 38 + r1 = r1 ^ simd_shuffle_xor(r5, (ushort)4); // 39 + r2 = r2 ^ r5; // 40 + r3 = r6 * r3 + r3; // 41 + r6 = r6 - r7; // 42 + r7 = r7 ^ r0; // 43 + r1 = r1 ^ dataset[r7 & MASK]; // 44 + r2 = r2 * r3; // 45 + r1 = mulhi(r1, r5); // 46 + r4 = r4 - r3; // 47 + r2 = rotr_var(r2, r6); // 48 + r3 = r3 ^ dataset[r5 & MASK]; // 49 + r1 = r1 + r5 + select(0x81b8bc2cu, 0x1907970cu, ((sel >> 7u) & 1u) != 0u); // 50 + r0 = r0 * r2; // 51 + r0 = r0 + r2 + select(0x4f92b968u, 0x699fd448u, ((sel >> 6u) & 1u) != 0u); // 52 + r1 = r1 + r0 + select(0x2bb965afu, 0x77b1520du, ((sel >> 12u) & 1u) != 0u); // 53 + r7 = rotl_imm(r7, 14u); // 54 + r3 = r3 + r7 + select(0x7b0fe07au, 0xa54c55a0u, ((sel >> 1u) & 1u) != 0u); // 55 + r6 = r6 ^ dataset[r7 & MASK]; // 56 + r1 = rotr_var(r1, r5); // 57 + r5 = r5 ^ dataset[r4 & MASK]; // 58 + r6 = r6 ^ dataset[r2 & MASK]; // 59 + r3 = r5 * r0 + r3; // 60 + r5 = r5 + r7 + select(0xaf9dd72du, 0xad7493e7u, ((sel >> 31u) & 1u) != 0u); // 61 + r4 = r4 + r6 + select(0x89841d87u, 0x1e07c3d9u, ((sel >> 27u) & 1u) != 0u); // 62 + r5 = rotl_imm(r5, 19u); // 63 + // latency-shadow block (Counter ASIC 3.0 item 8): 1024 ALU instructions x 3 passes after instruction 63, no load + for (uint sh = 0u; sh < 3u; ++sh) { + r5 = r5 + r2 + select(0x92199f99u, 0x8bc12da9u, ((sel >> 18u) & 1u) != 0u); // s0 add + r0 = r0 + r7 + select(0x8d72d3adu, 0x63079e5au, ((sel >> 26u) & 1u) != 0u); // s1 add + r6 = r6 ^ simd_shuffle_xor(r3, (ushort)2); // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + select(0xb21b4babu, 0x5d4c7a60u, ((sel >> 31u) & 1u) != 0u); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + select(0x2fe0e98bu, 0xc88e2942u, ((sel >> 16u) & 1u) != 0u); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + r6 = r6 ^ simd_shuffle_xor(r1, (ushort)4); // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + r2 = r2 ^ simd_shuffle_xor(r6, (ushort)4); // s12 shfl + r1 = r1 + r5 + select(0xbdf8f9a5u, 0xbc48c63eu, ((sel >> 25u) & 1u) != 0u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)8); // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + select(0x45c37cecu, 0x96e8f127u, ((sel >> 1u) & 1u) != 0u); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = mulhi(r6, r0); // s28 mulhi + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)2); // s29 shfl + r1 = r1 ^ simd_shuffle_xor(r6, (ushort)1); // s30 shfl + r1 = r1 + r6 + select(0x37985632u, 0xb1cdb2abu, ((sel >> 1u) & 1u) != 0u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + r3 = r3 ^ simd_shuffle_xor(r4, (ushort)2); // s33 shfl + r0 = r0 ^ simd_shuffle_xor(r3, (ushort)4); // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + select(0x804e777eu, 0x856e0180u, ((sel >> 0u) & 1u) != 0u); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + select(0x0b06c8a7u, 0xe9bd0cc4u, ((sel >> 2u) & 1u) != 0u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = mulhi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = mulhi(r4, r3); // s44 mulhi + r6 = r6 + r7 + select(0xee822e17u, 0xcdcb63f6u, ((sel >> 12u) & 1u) != 0u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + r4 = r4 ^ simd_shuffle_xor(r3, (ushort)8); // s47 shfl + r6 = mulhi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + select(0x3dfad1b6u, 0xd4758987u, ((sel >> 10u) & 1u) != 0u); // s56 add + r4 = r4 + r1 + select(0xfca75bc2u, 0x0602d6beu, ((sel >> 0u) & 1u) != 0u); // s57 add + r5 = mulhi(r5, r6); // s58 mulhi + r2 = r2 ^ simd_shuffle_xor(r1, (ushort)2); // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + select(0xd71c02ffu, 0x8596687au, ((sel >> 6u) & 1u) != 0u); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + r7 = r7 ^ simd_shuffle_xor(r5, (ushort)2); // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + select(0x3c6fe15du, 0x08ac5733u, ((sel >> 0u) & 1u) != 0u); // s72 add + r3 = r3 ^ simd_shuffle_xor(r2, (ushort)8); // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + select(0x295d5faeu, 0xc100b495u, ((sel >> 1u) & 1u) != 0u); // s77 add + r3 = mulhi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + select(0x274a9221u, 0x5cc59530u, ((sel >> 15u) & 1u) != 0u); // s81 add + r7 = r7 + r3 + select(0xc8651f8eu, 0x141479ecu, ((sel >> 5u) & 1u) != 0u); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + r2 = r2 ^ simd_shuffle_xor(r5, (ushort)16); // s85 shfl + r3 = r3 ^ r2; // s86 xor + r5 = r5 ^ simd_shuffle_xor(r7, (ushort)2); // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + select(0x53f915c2u, 0x883c0c92u, ((sel >> 18u) & 1u) != 0u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + select(0xe2be00a5u, 0x3cc5bd20u, ((sel >> 31u) & 1u) != 0u); // s91 add + r7 = r7 ^ simd_shuffle_xor(r2, (ushort)1); // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + select(0x423fd9c9u, 0xbfd646cbu, ((sel >> 17u) & 1u) != 0u); // s101 add + r7 = r7 + r6 + select(0x8d3c011du, 0x19b74a43u, ((sel >> 11u) & 1u) != 0u); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + select(0x8ce14721u, 0x7dcb7e18u, ((sel >> 15u) & 1u) != 0u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = mulhi(r2, r0); // s109 mulhi + r1 = mulhi(r1, r0); // s110 mulhi + r0 = r0 + r2 + select(0x2d9fc6b9u, 0x3c179ad8u, ((sel >> 28u) & 1u) != 0u); // s111 add + r2 = mulhi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + select(0x502138e2u, 0x47359729u, ((sel >> 22u) & 1u) != 0u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = mulhi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + r4 = r4 ^ simd_shuffle_xor(r2, (ushort)2); // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + r7 = r7 ^ simd_shuffle_xor(r2, (ushort)4); // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + select(0x33dff776u, 0x6c57e4e7u, ((sel >> 15u) & 1u) != 0u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + select(0x5db25b34u, 0xe8212c0cu, ((sel >> 30u) & 1u) != 0u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = mulhi(r0, r5); // s138 mulhi + r2 = r2 + r7 + select(0x218d4090u, 0xd44ff710u, ((sel >> 10u) & 1u) != 0u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + r3 = r3 ^ simd_shuffle_xor(r6, (ushort)1); // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + select(0xf4b1a8deu, 0xb98942fau, ((sel >> 29u) & 1u) != 0u); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + select(0x2bef10f2u, 0x0d48ba42u, ((sel >> 17u) & 1u) != 0u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + select(0xdc5cc080u, 0xc98dea9cu, ((sel >> 30u) & 1u) != 0u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + select(0x18197438u, 0x6c752dcbu, ((sel >> 11u) & 1u) != 0u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + select(0xf1c46574u, 0x8e481727u, ((sel >> 3u) & 1u) != 0u); // s163 add + r0 = mulhi(r0, r4); // s164 mulhi + r2 = r2 + r6 + select(0xac578137u, 0x550ab406u, ((sel >> 20u) & 1u) != 0u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + select(0xa33e6706u, 0xaebb5966u, ((sel >> 14u) & 1u) != 0u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + r7 = r7 ^ simd_shuffle_xor(r0, (ushort)8); // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + select(0xd94d55acu, 0x5bb7550fu, ((sel >> 21u) & 1u) != 0u); // s184 add + r3 = r3 | r5; // s185 or + r6 = mulhi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)2); // s188 shfl + r6 = r6 + r5 + select(0x89e747feu, 0x2a354e2du, ((sel >> 6u) & 1u) != 0u); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = mulhi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + r4 = r4 ^ simd_shuffle_xor(r5, (ushort)16); // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + select(0xea03e8e7u, 0x10cfdc71u, ((sel >> 7u) & 1u) != 0u); // s197 add + r7 = r7 + r5 + select(0xa7ee0102u, 0x66e148d3u, ((sel >> 15u) & 1u) != 0u); // s198 add + r5 = r5 - r2; // s199 sub + r5 = r5 ^ simd_shuffle_xor(r1, (ushort)2); // s200 shfl + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)8); // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + select(0x8379a4deu, 0x8558b619u, ((sel >> 10u) & 1u) != 0u); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = mulhi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + r2 = r2 ^ simd_shuffle_xor(r0, (ushort)4); // s209 shfl + r7 = r7 + r0 + select(0xaa8cb14eu, 0xf4049c4cu, ((sel >> 11u) & 1u) != 0u); // s210 add + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)16); // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + r3 = r3 ^ simd_shuffle_xor(r2, (ushort)16); // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = mulhi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + r5 = r5 ^ simd_shuffle_xor(r2, (ushort)8); // s222 shfl + r5 = mulhi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + select(0x1d176220u, 0x2a7fecb2u, ((sel >> 16u) & 1u) != 0u); // s230 add + r1 = r1 ^ simd_shuffle_xor(r2, (ushort)4); // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + select(0x17dafb4du, 0xadce39f3u, ((sel >> 25u) & 1u) != 0u); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + select(0xf2f77d26u, 0x0e7033b6u, ((sel >> 29u) & 1u) != 0u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + select(0xfed2da4eu, 0x7b2ff6b7u, ((sel >> 31u) & 1u) != 0u); // s247 add + r0 = r0 + r7 + select(0x03b2891cu, 0xb5fad7b1u, ((sel >> 0u) & 1u) != 0u); // s248 add + r5 = mulhi(r5, r4); // s249 mulhi + r5 = r5 + r2 + select(0x042cd6e3u, 0xa7e71c2fu, ((sel >> 11u) & 1u) != 0u); // s250 add + r6 = r6 ^ simd_shuffle_xor(r1, (ushort)1); // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + select(0x784a302bu, 0xb83d78deu, ((sel >> 16u) & 1u) != 0u); // s254 add + r2 = r2 - r4; // s255 sub + r3 = r3 - r4; // s256 sub + r2 = r2 * r4; // s257 mul + r4 = r0 * r6 + r4; // s258 mad + r5 = r5 | r0; // s259 or + r4 = r4 ^ r6; // s260 xor + r6 = mulhi(r6, r3); // s261 mulhi + r2 = r2 * r6; // s262 mul + r5 = rotl_imm(r5, 1u); // s263 rotl + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)8); // s264 shfl + r3 = r3 * r2; // s265 mul + r2 = r2 + r5 + select(0x3dddf1b2u, 0x99a1d1b6u, ((sel >> 15u) & 1u) != 0u); // s266 add + r2 = r2 ^ simd_shuffle_xor(r0, (ushort)8); // s267 shfl + r0 = r0 ^ simd_shuffle_xor(r1, (ushort)2); // s268 shfl + r4 = r4 - r2; // s269 sub + r0 = r0 ^ simd_shuffle_xor(r5, (ushort)1); // s270 shfl + r3 = r3 + r2 + select(0xcfc62661u, 0x40ca287au, ((sel >> 21u) & 1u) != 0u); // s271 add + r1 = r1 ^ simd_shuffle_xor(r7, (ushort)16); // s272 shfl + r1 = r3 * r6 + r1; // s273 mad + r7 = r7 + r6 + select(0x44caede3u, 0xed4b65adu, ((sel >> 30u) & 1u) != 0u); // s274 add + r5 = r5 ^ r7; // s275 xor + r2 = r2 * r6; // s276 mul + r2 = r2 + r1 + select(0x9aae6c12u, 0x0f45ae89u, ((sel >> 6u) & 1u) != 0u); // s277 add + r2 = r2 ^ r6; // s278 xor + r1 = r1 - r2; // s279 sub + r5 = r5 ^ r1; // s280 xor + r7 = r7 ^ r1; // s281 xor + r7 = r7 - r1; // s282 sub + r5 = r5 - r7; // s283 sub + r7 = r0 * r6 + r7; // s284 mad + r5 = mulhi(r5, r4); // s285 mulhi + r3 = r3 - r5; // s286 sub + r5 = r5 - r1; // s287 sub + r1 = r3 * r7 + r1; // s288 mad + r3 = rotl_imm(r3, 9u); // s289 rotl + r5 = r5 ^ simd_shuffle_xor(r6, (ushort)8); // s290 shfl + r7 = r7 + r2 + select(0x2307120bu, 0xe086d3b6u, ((sel >> 1u) & 1u) != 0u); // s291 add + r4 = r4 ^ r3; // s292 xor + r3 = rotl_imm(r3, 14u); // s293 rotl + r5 = r5 - r4; // s294 sub + r2 = mulhi(r2, r3); // s295 mulhi + r1 = r1 ^ simd_shuffle_xor(r3, (ushort)4); // s296 shfl + r3 = r6 * r1 + r3; // s297 mad + r4 = r4 ^ r1; // s298 xor + r6 = r6 + r3 + select(0x4e3a12e5u, 0xadbeb223u, ((sel >> 24u) & 1u) != 0u); // s299 add + r6 = mulhi(r6, r5); // s300 mulhi + r7 = rotr_var(r7, r5); // s301 rotr + r5 = r5 ^ simd_shuffle_xor(r4, (ushort)16); // s302 shfl + r3 = r3 ^ r4; // s303 xor + r2 = r3 * r1 + r2; // s304 mad + r1 = r1 ^ r7; // s305 xor + r1 = r1 + r0 + select(0x51ab0157u, 0x0d8f1149u, ((sel >> 22u) & 1u) != 0u); // s306 add + r2 = r2 + r1 + select(0x3b5e8835u, 0x99a96de9u, ((sel >> 24u) & 1u) != 0u); // s307 add + r1 = r5 * r5 + r1; // s308 mad + r2 = r2 * r4; // s309 mul + r3 = r3 ^ simd_shuffle_xor(r7, (ushort)8); // s310 shfl + r0 = r0 ^ r4; // s311 xor + r5 = mulhi(r5, r2); // s312 mulhi + r7 = r7 + r2 + select(0x81f3297cu, 0x86ddfba7u, ((sel >> 30u) & 1u) != 0u); // s313 add + r3 = r3 + r1 + select(0x838e4a2fu, 0x38aa230au, ((sel >> 0u) & 1u) != 0u); // s314 add + r7 = r7 ^ simd_shuffle_xor(r0, (ushort)16); // s315 shfl + r7 = r7 - r5; // s316 sub + r5 = r5 ^ simd_shuffle_xor(r1, (ushort)4); // s317 shfl + r1 = r1 + r3 + select(0xebcad805u, 0xa6399179u, ((sel >> 11u) & 1u) != 0u); // s318 add + r7 = rotl_imm(r7, 21u); // s319 rotl + r7 = r7 ^ r6; // s320 xor + r7 = r7 | r6; // s321 or + r5 = r5 + r3 + select(0x4c906f73u, 0x4de83051u, ((sel >> 25u) & 1u) != 0u); // s322 add + r0 = r0 + r4 + select(0x742ec195u, 0xd3d821c5u, ((sel >> 14u) & 1u) != 0u); // s323 add + r6 = r6 ^ r2; // s324 xor + r6 = rotl_imm(r6, 1u); // s325 rotl + r4 = rotl_imm(r4, 24u); // s326 rotl + r4 = r4 | r3; // s327 or + r2 = r1 * r3 + r2; // s328 mad + r2 = r2 ^ r7; // s329 xor + r2 = r2 | r3; // s330 or + r7 = r7 - r1; // s331 sub + r3 = r3 + r6 + select(0xb86750e9u, 0xc06f831eu, ((sel >> 0u) & 1u) != 0u); // s332 add + r7 = rotl_imm(r7, 25u); // s333 rotl + r3 = r0 * r0 + r3; // s334 mad + r2 = r2 + r5 + select(0xb57956eeu, 0x5225df1du, ((sel >> 28u) & 1u) != 0u); // s335 add + r3 = r1 * r6 + r3; // s336 mad + r4 = r2 * r2 + r4; // s337 mad + r7 = r7 * r2; // s338 mul + r1 = r1 * r6; // s339 mul + r4 = r4 + r5 + select(0x23f6425fu, 0xb73822ceu, ((sel >> 5u) & 1u) != 0u); // s340 add + r5 = r5 ^ simd_shuffle_xor(r7, (ushort)2); // s341 shfl + r6 = r6 ^ r5; // s342 xor + r0 = rotl_imm(r0, 13u); // s343 rotl + r0 = rotr_var(r0, r3); // s344 rotr + r1 = r1 - r0; // s345 sub + r6 = rotr_var(r6, r1); // s346 rotr + r6 = r6 ^ simd_shuffle_xor(r5, (ushort)4); // s347 shfl + r5 = r5 ^ simd_shuffle_xor(r1, (ushort)8); // s348 shfl + r5 = r5 ^ r3; // s349 xor + r1 = r4 * r0 + r1; // s350 mad + r3 = rotr_var(r3, r1); // s351 rotr + r1 = rotl_imm(r1, 13u); // s352 rotl + r3 = r3 + r0 + select(0x0dce5917u, 0xfa0c560eu, ((sel >> 26u) & 1u) != 0u); // s353 add + r3 = mulhi(r3, r2); // s354 mulhi + r1 = r2 * r4 + r1; // s355 mad + r0 = r0 ^ r1; // s356 xor + r7 = r7 * r5; // s357 mul + r0 = rotl_imm(r0, 5u); // s358 rotl + r2 = r7 * r7 + r2; // s359 mad + r2 = r2 | r6; // s360 or + r6 = r6 + r1 + select(0x7c83b79au, 0x277e027au, ((sel >> 19u) & 1u) != 0u); // s361 add + r0 = r0 * r2; // s362 mul + r3 = r3 * r6; // s363 mul + r2 = rotr_var(r2, r4); // s364 rotr + r5 = r5 + r1 + select(0x271f2385u, 0x52275ea4u, ((sel >> 1u) & 1u) != 0u); // s365 add + r1 = r1 * r6; // s366 mul + r0 = r0 + r7 + select(0x4c66800fu, 0x8f8b4093u, ((sel >> 30u) & 1u) != 0u); // s367 add + r4 = rotr_var(r4, r0); // s368 rotr + r4 = rotr_var(r4, r0); // s369 rotr + r1 = r0 * r6 + r1; // s370 mad + r0 = r0 - r5; // s371 sub + r7 = r7 + r2 + select(0x7dad1ed5u, 0x9a7dcadcu, ((sel >> 11u) & 1u) != 0u); // s372 add + r7 = r7 + r3 + select(0x1ea3d58eu, 0xf808c195u, ((sel >> 20u) & 1u) != 0u); // s373 add + r1 = r1 * r2; // s374 mul + r3 = r7 * r2 + r3; // s375 mad + r4 = r4 ^ r1; // s376 xor + r1 = r1 | r0; // s377 or + r5 = r5 + r0 + select(0x98b36d10u, 0x427ed5ceu, ((sel >> 26u) & 1u) != 0u); // s378 add + r6 = r6 * r0; // s379 mul + r7 = r7 ^ simd_shuffle_xor(r3, (ushort)1); // s380 shfl + r4 = r4 + r0 + select(0xb19cab2du, 0x38f848b9u, ((sel >> 18u) & 1u) != 0u); // s381 add + r3 = r5 * r2 + r3; // s382 mad + r0 = r0 | r7; // s383 or + r5 = r5 - r4; // s384 sub + r1 = r1 - r5; // s385 sub + r2 = r2 - r0; // s386 sub + r5 = r5 + r2 + select(0x341056b0u, 0xffc20cf8u, ((sel >> 17u) & 1u) != 0u); // s387 add + r1 = rotl_imm(r1, 26u); // s388 rotl + r2 = r2 ^ r5; // s389 xor + r5 = r7 * r0 + r5; // s390 mad + r3 = mulhi(r3, r2); // s391 mulhi + r5 = r5 + r4 + select(0x78aa571au, 0xfb939f2bu, ((sel >> 0u) & 1u) != 0u); // s392 add + r5 = r5 | r2; // s393 or + r1 = mulhi(r1, r7); // s394 mulhi + r4 = r4 - r2; // s395 sub + r7 = r7 - r1; // s396 sub + r0 = r0 + r1 + select(0x31af4767u, 0xa9c6c9fbu, ((sel >> 2u) & 1u) != 0u); // s397 add + r3 = r3 * r1; // s398 mul + r1 = r1 - r7; // s399 sub + r7 = r7 + r6 + select(0x266d4c34u, 0x34f9b056u, ((sel >> 8u) & 1u) != 0u); // s400 add + r5 = rotl_imm(r5, 5u); // s401 rotl + r0 = r0 + r4 + select(0x7241955eu, 0x79822c64u, ((sel >> 23u) & 1u) != 0u); // s402 add + r2 = r4 * r0 + r2; // s403 mad + r5 = rotl_imm(r5, 29u); // s404 rotl + r3 = r3 - r5; // s405 sub + r2 = r2 + r3 + select(0xf65aca5du, 0xda046091u, ((sel >> 27u) & 1u) != 0u); // s406 add + r4 = mulhi(r4, r7); // s407 mulhi + r2 = r2 + r1 + select(0x6a00cefbu, 0x167aba1cu, ((sel >> 14u) & 1u) != 0u); // s408 add + r2 = r6 * r6 + r2; // s409 mad + r6 = rotl_imm(r6, 26u); // s410 rotl + r6 = r6 | r7; // s411 or + r1 = rotl_imm(r1, 20u); // s412 rotl + r7 = r7 * r5; // s413 mul + r6 = r6 - r0; // s414 sub + r6 = mulhi(r6, r0); // s415 mulhi + r3 = rotl_imm(r3, 5u); // s416 rotl + r1 = r1 ^ simd_shuffle_xor(r3, (ushort)4); // s417 shfl + r0 = r0 * r4; // s418 mul + r4 = rotr_var(r4, r7); // s419 rotr + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)2); // s420 shfl + r5 = r3 * r6 + r5; // s421 mad + r3 = r3 ^ r4; // s422 xor + r3 = rotr_var(r3, r7); // s423 rotr + r4 = r4 + r1 + select(0xba29da18u, 0xbb669c17u, ((sel >> 26u) & 1u) != 0u); // s424 add + r7 = rotr_var(r7, r5); // s425 rotr + r2 = r2 * r6; // s426 mul + r1 = r1 + r4 + select(0x4f70e34fu, 0xc6b45a76u, ((sel >> 16u) & 1u) != 0u); // s427 add + r1 = rotl_imm(r1, 1u); // s428 rotl + r6 = mulhi(r6, r5); // s429 mulhi + r6 = r6 + r7 + select(0x3883e0f5u, 0xff610984u, ((sel >> 12u) & 1u) != 0u); // s430 add + r4 = r4 | r3; // s431 or + r7 = r7 ^ r5; // s432 xor + r3 = mulhi(r3, r2); // s433 mulhi + r2 = r2 ^ r6; // s434 xor + r4 = r4 | r3; // s435 or + r0 = r0 + r1 + select(0xb1b15861u, 0xf37057feu, ((sel >> 9u) & 1u) != 0u); // s436 add + r7 = r7 + r4 + select(0x2e9e173fu, 0x61793eafu, ((sel >> 4u) & 1u) != 0u); // s437 add + r5 = r5 ^ simd_shuffle_xor(r1, (ushort)1); // s438 shfl + r6 = r0 * r3 + r6; // s439 mad + r5 = r5 ^ r2; // s440 xor + r0 = r0 ^ simd_shuffle_xor(r4, (ushort)16); // s441 shfl + r6 = r6 * r3; // s442 mul + r5 = r5 - r4; // s443 sub + r2 = r2 ^ simd_shuffle_xor(r1, (ushort)4); // s444 shfl + r0 = r0 + r5 + select(0x646856aau, 0x69def831u, ((sel >> 12u) & 1u) != 0u); // s445 add + r4 = r4 + r6 + select(0x58a3f8fcu, 0x1f8ecb8bu, ((sel >> 23u) & 1u) != 0u); // s446 add + r4 = r0 * r2 + r4; // s447 mad + r5 = r5 * r0; // s448 mul + r2 = r2 + r5 + select(0x48d3062du, 0x7ecb876du, ((sel >> 11u) & 1u) != 0u); // s449 add + r2 = r5 * r6 + r2; // s450 mad + r7 = r7 ^ simd_shuffle_xor(r3, (ushort)4); // s451 shfl + r2 = r2 * r5; // s452 mul + r5 = mulhi(r5, r4); // s453 mulhi + r1 = r1 ^ r7; // s454 xor + r2 = r2 * r7; // s455 mul + r1 = r1 * r3; // s456 mul + r3 = r6 * r2 + r3; // s457 mad + r7 = r7 - r0; // s458 sub + r2 = r4 * r5 + r2; // s459 mad + r0 = rotl_imm(r0, 2u); // s460 rotl + r4 = r4 ^ r2; // s461 xor + r4 = r4 + r0 + select(0xb41dd69bu, 0x7b093757u, ((sel >> 18u) & 1u) != 0u); // s462 add + r6 = r6 + r1 + select(0xb042032eu, 0x916e1b7eu, ((sel >> 3u) & 1u) != 0u); // s463 add + r2 = r2 + r6 + select(0x4e68a2a0u, 0x6d42b978u, ((sel >> 8u) & 1u) != 0u); // s464 add + r3 = r3 - r2; // s465 sub + r2 = r2 * r5; // s466 mul + r7 = rotl_imm(r7, 28u); // s467 rotl + r0 = r0 - r3; // s468 sub + r7 = mulhi(r7, r2); // s469 mulhi + r7 = r7 | r6; // s470 or + r7 = rotl_imm(r7, 28u); // s471 rotl + r0 = r0 * r6; // s472 mul + r2 = r2 | r1; // s473 or + r2 = r2 + r4 + select(0x13ec3b3eu, 0x20c5276bu, ((sel >> 14u) & 1u) != 0u); // s474 add + r2 = rotr_var(r2, r6); // s475 rotr + r6 = r6 ^ simd_shuffle_xor(r0, (ushort)16); // s476 shfl + r2 = rotl_imm(r2, 15u); // s477 rotl + r5 = rotr_var(r5, r4); // s478 rotr + r3 = rotl_imm(r3, 26u); // s479 rotl + r5 = r5 | r6; // s480 or + r3 = rotl_imm(r3, 29u); // s481 rotl + r0 = rotr_var(r0, r7); // s482 rotr + r1 = r1 - r0; // s483 sub + r0 = r2 * r5 + r0; // s484 mad + r6 = r6 ^ r4; // s485 xor + r6 = r6 ^ r0; // s486 xor + r3 = r3 ^ simd_shuffle_xor(r7, (ushort)4); // s487 shfl + r6 = mulhi(r6, r0); // s488 mulhi + r1 = r1 * r0; // s489 mul + r3 = r3 ^ r6; // s490 xor + r3 = r3 * r6; // s491 mul + r0 = r0 * r3; // s492 mul + r4 = r4 | r3; // s493 or + r0 = r0 ^ simd_shuffle_xor(r5, (ushort)8); // s494 shfl + r0 = r0 ^ simd_shuffle_xor(r7, (ushort)16); // s495 shfl + r6 = r5 * r2 + r6; // s496 mad + r5 = r5 * r6; // s497 mul + r3 = r3 ^ r1; // s498 xor + r0 = r0 + r1 + select(0x53e99acau, 0x19f4c710u, ((sel >> 20u) & 1u) != 0u); // s499 add + r6 = r5 * r2 + r6; // s500 mad + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)4); // s501 shfl + r3 = r3 - r5; // s502 sub + r0 = rotl_imm(r0, 8u); // s503 rotl + r3 = r3 ^ r1; // s504 xor + r7 = r7 + r2 + select(0x0867fe20u, 0x7a6ac7b5u, ((sel >> 6u) & 1u) != 0u); // s505 add + r0 = r0 ^ simd_shuffle_xor(r7, (ushort)2); // s506 shfl + r0 = r0 * r1; // s507 mul + r6 = r6 | r5; // s508 or + r2 = r2 * r7; // s509 mul + r1 = r1 + r5 + select(0xd7fdc3ecu, 0xd77f6a03u, ((sel >> 21u) & 1u) != 0u); // s510 add + r3 = r3 ^ simd_shuffle_xor(r7, (ushort)8); // s511 shfl + r6 = r6 + r3 + select(0x297a096au, 0x5c22b0b5u, ((sel >> 9u) & 1u) != 0u); // s512 add + r7 = r7 | r0; // s513 or + r7 = r7 + r3 + select(0x5de1d1d1u, 0x4caafacdu, ((sel >> 27u) & 1u) != 0u); // s514 add + r1 = mulhi(r1, r0); // s515 mulhi + r0 = r0 - r6; // s516 sub + r2 = r2 - r1; // s517 sub + r6 = r5 * r7 + r6; // s518 mad + r2 = r2 ^ r7; // s519 xor + r1 = r1 | r5; // s520 or + r0 = r4 * r6 + r0; // s521 mad + r4 = r4 + r6 + select(0x2caeeca3u, 0xb1091e80u, ((sel >> 29u) & 1u) != 0u); // s522 add + r7 = r6 * r5 + r7; // s523 mad + r7 = r7 - r2; // s524 sub + r0 = r0 * r7; // s525 mul + r0 = r0 ^ r7; // s526 xor + r1 = mulhi(r1, r4); // s527 mulhi + r0 = rotr_var(r0, r5); // s528 rotr + r2 = r2 ^ simd_shuffle_xor(r7, (ushort)16); // s529 shfl + r2 = mulhi(r2, r3); // s530 mulhi + r1 = r1 | r4; // s531 or + r6 = r6 + r4 + select(0xbe9e1eb0u, 0xbda312aeu, ((sel >> 13u) & 1u) != 0u); // s532 add + r7 = r7 + r2 + select(0xbe5d93a3u, 0x1ec16229u, ((sel >> 6u) & 1u) != 0u); // s533 add + r0 = r6 * r4 + r0; // s534 mad + r0 = r0 + r5 + select(0x5e23583bu, 0x500828bcu, ((sel >> 23u) & 1u) != 0u); // s535 add + r6 = r5 * r0 + r6; // s536 mad + r2 = r2 ^ r4; // s537 xor + r6 = r3 * r5 + r6; // s538 mad + r6 = r6 + r4 + select(0x43c32138u, 0x852321dcu, ((sel >> 3u) & 1u) != 0u); // s539 add + r2 = r2 + r5 + select(0xaff69493u, 0x44e6ae63u, ((sel >> 7u) & 1u) != 0u); // s540 add + r3 = mulhi(r3, r5); // s541 mulhi + r1 = r1 + r7 + select(0xc5de29efu, 0x909712feu, ((sel >> 5u) & 1u) != 0u); // s542 add + r1 = r3 * r2 + r1; // s543 mad + r1 = r1 + r3 + select(0x1e20e084u, 0xfb7b42b9u, ((sel >> 11u) & 1u) != 0u); // s544 add + r4 = r4 ^ simd_shuffle_xor(r5, (ushort)4); // s545 shfl + r6 = r6 + r1 + select(0x9370db38u, 0x6e036dd4u, ((sel >> 10u) & 1u) != 0u); // s546 add + r4 = r4 ^ r6; // s547 xor + r5 = r5 ^ simd_shuffle_xor(r3, (ushort)8); // s548 shfl + r3 = r3 ^ simd_shuffle_xor(r5, (ushort)16); // s549 shfl + r1 = rotr_var(r1, r7); // s550 rotr + r0 = r3 * r2 + r0; // s551 mad + r7 = mulhi(r7, r4); // s552 mulhi + r0 = r0 + r4 + select(0xbf2488f6u, 0xd3c9174du, ((sel >> 13u) & 1u) != 0u); // s553 add + r1 = rotl_imm(r1, 1u); // s554 rotl + r7 = rotr_var(r7, r3); // s555 rotr + r7 = rotr_var(r7, r3); // s556 rotr + r6 = r2 * r0 + r6; // s557 mad + r6 = r6 ^ r1; // s558 xor + r5 = r5 ^ simd_shuffle_xor(r1, (ushort)2); // s559 shfl + r5 = r5 ^ r3; // s560 xor + r5 = r5 * r1; // s561 mul + r3 = rotl_imm(r3, 31u); // s562 rotl + r6 = rotr_var(r6, r2); // s563 rotr + r7 = r7 | r2; // s564 or + r6 = rotr_var(r6, r0); // s565 rotr + r2 = r2 * r0; // s566 mul + r4 = r4 ^ simd_shuffle_xor(r5, (ushort)2); // s567 shfl + r3 = r3 * r0; // s568 mul + r4 = r4 + r2 + select(0xd9160c83u, 0xa3149efau, ((sel >> 9u) & 1u) != 0u); // s569 add + r4 = mulhi(r4, r2); // s570 mulhi + r3 = r3 + r0 + select(0x3bdc971cu, 0x9cab407bu, ((sel >> 10u) & 1u) != 0u); // s571 add + r1 = r1 ^ simd_shuffle_xor(r2, (ushort)16); // s572 shfl + r2 = r2 ^ simd_shuffle_xor(r5, (ushort)4); // s573 shfl + r2 = r2 ^ simd_shuffle_xor(r3, (ushort)8); // s574 shfl + r0 = r0 ^ r7; // s575 xor + r0 = r0 + r5 + select(0x17979608u, 0x747b0838u, ((sel >> 27u) & 1u) != 0u); // s576 add + r0 = r0 ^ r4; // s577 xor + r6 = r6 - r1; // s578 sub + r4 = rotr_var(r4, r2); // s579 rotr + r2 = r2 ^ r3; // s580 xor + r6 = r7 * r2 + r6; // s581 mad + r5 = r5 + r2 + select(0x1c10ec5cu, 0x02246c0cu, ((sel >> 7u) & 1u) != 0u); // s582 add + r3 = mulhi(r3, r6); // s583 mulhi + r2 = r2 ^ r5; // s584 xor + r6 = rotl_imm(r6, 24u); // s585 rotl + r3 = r3 ^ simd_shuffle_xor(r5, (ushort)8); // s586 shfl + r1 = r2 * r6 + r1; // s587 mad + r3 = r3 + r7 + select(0x88758873u, 0xbea44bd0u, ((sel >> 21u) & 1u) != 0u); // s588 add + r1 = rotl_imm(r1, 30u); // s589 rotl + r7 = r7 * r1; // s590 mul + r3 = r3 + r6 + select(0xf436bb64u, 0x8e0eb890u, ((sel >> 10u) & 1u) != 0u); // s591 add + r7 = r6 * r1 + r7; // s592 mad + r0 = r3 * r5 + r0; // s593 mad + r5 = rotr_var(r5, r4); // s594 rotr + r4 = r4 | r0; // s595 or + r6 = r3 * r0 + r6; // s596 mad + r2 = r2 + r1 + select(0xb465e47eu, 0x29b853b3u, ((sel >> 31u) & 1u) != 0u); // s597 add + r1 = r1 ^ simd_shuffle_xor(r7, (ushort)16); // s598 shfl + r4 = r4 ^ simd_shuffle_xor(r0, (ushort)4); // s599 shfl + r6 = r2 * r0 + r6; // s600 mad + r5 = mulhi(r5, r0); // s601 mulhi + r6 = r6 * r7; // s602 mul + r4 = r4 | r7; // s603 or + r7 = r7 - r0; // s604 sub + r7 = rotr_var(r7, r4); // s605 rotr + r4 = r0 * r3 + r4; // s606 mad + r4 = mulhi(r4, r3); // s607 mulhi + r0 = r0 + r1 + select(0x22ce199du, 0xb7536963u, ((sel >> 28u) & 1u) != 0u); // s608 add + r2 = r2 - r5; // s609 sub + r2 = r2 ^ r0; // s610 xor + r5 = r5 * r4; // s611 mul + r3 = rotl_imm(r3, 25u); // s612 rotl + r7 = rotl_imm(r7, 13u); // s613 rotl + r4 = r4 * r7; // s614 mul + r5 = r4 * r2 + r5; // s615 mad + r0 = r0 ^ r5; // s616 xor + r7 = r5 * r4 + r7; // s617 mad + r6 = r6 - r4; // s618 sub + r3 = r3 * r4; // s619 mul + r1 = rotl_imm(r1, 24u); // s620 rotl + r1 = r1 ^ r2; // s621 xor + r4 = r4 | r3; // s622 or + r7 = r7 * r2; // s623 mul + r6 = r6 + r1 + select(0x2dbf6ed0u, 0xe37b1e20u, ((sel >> 20u) & 1u) != 0u); // s624 add + r4 = r4 ^ r5; // s625 xor + r4 = r6 * r2 + r4; // s626 mad + r1 = r1 ^ r6; // s627 xor + r6 = r6 + r3 + select(0x9dc2b9d0u, 0xf5a2a9f7u, ((sel >> 12u) & 1u) != 0u); // s628 add + r7 = r7 - r5; // s629 sub + r1 = mulhi(r1, r7); // s630 mulhi + r1 = rotr_var(r1, r3); // s631 rotr + r4 = r4 | r6; // s632 or + r2 = r2 + r5 + select(0x9c1fba1bu, 0x982bfc08u, ((sel >> 24u) & 1u) != 0u); // s633 add + r6 = r6 * r5; // s634 mul + r7 = r2 * r3 + r7; // s635 mad + r7 = mulhi(r7, r4); // s636 mulhi + r5 = r5 ^ r0; // s637 xor + r0 = r0 * r1; // s638 mul + r4 = r4 ^ r6; // s639 xor + r6 = r6 - r4; // s640 sub + r6 = mulhi(r6, r4); // s641 mulhi + r4 = r4 - r0; // s642 sub + r7 = r7 - r5; // s643 sub + r3 = r0 * r7 + r3; // s644 mad + r3 = r3 | r5; // s645 or + r0 = r0 - r4; // s646 sub + r7 = r7 | r5; // s647 or + r7 = rotl_imm(r7, 1u); // s648 rotl + r5 = r5 + r6 + select(0x9f5e0d19u, 0x6e5d517fu, ((sel >> 31u) & 1u) != 0u); // s649 add + r1 = r1 | r2; // s650 or + r3 = rotl_imm(r3, 29u); // s651 rotl + r2 = r2 + r4 + select(0xb53f6e74u, 0x30faf9c6u, ((sel >> 2u) & 1u) != 0u); // s652 add + r0 = rotl_imm(r0, 21u); // s653 rotl + r1 = r1 ^ r3; // s654 xor + r4 = r7 * r2 + r4; // s655 mad + r4 = r4 - r6; // s656 sub + r4 = r4 * r6; // s657 mul + r2 = r2 ^ simd_shuffle_xor(r1, (ushort)4); // s658 shfl + r7 = rotl_imm(r7, 31u); // s659 rotl + r4 = r4 ^ r6; // s660 xor + r1 = r1 - r3; // s661 sub + r3 = r3 * r6; // s662 mul + r5 = r5 * r3; // s663 mul + r7 = r7 + r2 + select(0x016e0094u, 0x8941d2e7u, ((sel >> 21u) & 1u) != 0u); // s664 add + r1 = r1 ^ r2; // s665 xor + r1 = r1 - r0; // s666 sub + r4 = r4 ^ r7; // s667 xor + r7 = r7 ^ simd_shuffle_xor(r3, (ushort)1); // s668 shfl + r1 = rotr_var(r1, r4); // s669 rotr + r2 = r2 + r3 + select(0x9af12ca6u, 0x15289435u, ((sel >> 14u) & 1u) != 0u); // s670 add + r2 = rotr_var(r2, r4); // s671 rotr + r4 = r6 * r7 + r4; // s672 mad + r2 = r2 ^ simd_shuffle_xor(r1, (ushort)4); // s673 shfl + r6 = r4 * r2 + r6; // s674 mad + r2 = r4 * r6 + r2; // s675 mad + r3 = r3 ^ simd_shuffle_xor(r1, (ushort)16); // s676 shfl + r1 = rotr_var(r1, r0); // s677 rotr + r0 = r0 - r2; // s678 sub + r5 = r5 ^ simd_shuffle_xor(r1, (ushort)16); // s679 shfl + r1 = r1 ^ r0; // s680 xor + r1 = r1 ^ simd_shuffle_xor(r2, (ushort)4); // s681 shfl + r0 = r0 ^ simd_shuffle_xor(r3, (ushort)8); // s682 shfl + r2 = r3 * r3 + r2; // s683 mad + r4 = r4 - r6; // s684 sub + r5 = r5 ^ r3; // s685 xor + r2 = r2 - r5; // s686 sub + r4 = r4 - r5; // s687 sub + r5 = r4 * r7 + r5; // s688 mad + r6 = r6 * r7; // s689 mul + r1 = r1 * r5; // s690 mul + r4 = rotr_var(r4, r3); // s691 rotr + r2 = r2 ^ r4; // s692 xor + r0 = rotl_imm(r0, 2u); // s693 rotl + r5 = r5 + r2 + select(0x4fc762c9u, 0x49801084u, ((sel >> 23u) & 1u) != 0u); // s694 add + r0 = r0 + r4 + select(0x626c00f5u, 0x5f403cd5u, ((sel >> 14u) & 1u) != 0u); // s695 add + r6 = rotl_imm(r6, 25u); // s696 rotl + r3 = r3 ^ r7; // s697 xor + r0 = r0 * r2; // s698 mul + r5 = rotr_var(r5, r1); // s699 rotr + r3 = r3 ^ r7; // s700 xor + r4 = r4 | r3; // s701 or + r7 = r7 * r3; // s702 mul + r4 = rotl_imm(r4, 24u); // s703 rotl + r5 = r5 + r4 + select(0xc08bb414u, 0xad5e1851u, ((sel >> 17u) & 1u) != 0u); // s704 add + r0 = r6 * r5 + r0; // s705 mad + r4 = mulhi(r4, r1); // s706 mulhi + r4 = rotr_var(r4, r3); // s707 rotr + r3 = rotr_var(r3, r6); // s708 rotr + r6 = r6 ^ simd_shuffle_xor(r7, (ushort)16); // s709 shfl + r3 = r2 * r6 + r3; // s710 mad + r1 = r1 * r4; // s711 mul + r3 = r3 + r5 + select(0xdc55338fu, 0x407f7c4du, ((sel >> 13u) & 1u) != 0u); // s712 add + r6 = r6 ^ simd_shuffle_xor(r7, (ushort)2); // s713 shfl + r1 = r1 ^ r0; // s714 xor + r7 = r1 * r1 + r7; // s715 mad + r4 = r4 | r0; // s716 or + r6 = r6 * r4; // s717 mul + r0 = r0 - r5; // s718 sub + r1 = r1 ^ r4; // s719 xor + r4 = mulhi(r4, r6); // s720 mulhi + r1 = r1 + r0 + select(0xb2ce569eu, 0xc2093fcau, ((sel >> 13u) & 1u) != 0u); // s721 add + r4 = mulhi(r4, r2); // s722 mulhi + r6 = r6 ^ simd_shuffle_xor(r1, (ushort)16); // s723 shfl + r5 = r3 * r0 + r5; // s724 mad + r5 = mulhi(r5, r0); // s725 mulhi + r2 = rotr_var(r2, r5); // s726 rotr + r5 = r5 + r0 + select(0x4e8aaad5u, 0x48cdf1c1u, ((sel >> 20u) & 1u) != 0u); // s727 add + r1 = r1 * r0; // s728 mul + r3 = r3 ^ simd_shuffle_xor(r0, (ushort)1); // s729 shfl + r4 = r4 * r6; // s730 mul + r4 = r4 - r6; // s731 sub + r4 = r4 ^ r2; // s732 xor + r5 = r5 * r6; // s733 mul + r7 = rotr_var(r7, r3); // s734 rotr + r1 = r1 ^ simd_shuffle_xor(r5, (ushort)1); // s735 shfl + r1 = mulhi(r1, r0); // s736 mulhi + r2 = r2 * r6; // s737 mul + r5 = rotl_imm(r5, 27u); // s738 rotl + r2 = mulhi(r2, r3); // s739 mulhi + r5 = r3 * r5 + r5; // s740 mad + r2 = rotl_imm(r2, 11u); // s741 rotl + r6 = r6 | r2; // s742 or + r2 = r2 ^ r3; // s743 xor + r3 = r3 * r1; // s744 mul + r4 = mulhi(r4, r2); // s745 mulhi + r5 = r5 ^ r6; // s746 xor + r6 = r6 + r7 + select(0x78fc162du, 0x0d6b844eu, ((sel >> 11u) & 1u) != 0u); // s747 add + r1 = rotl_imm(r1, 27u); // s748 rotl + r4 = rotr_var(r4, r1); // s749 rotr + r5 = r5 ^ r7; // s750 xor + r4 = rotr_var(r4, r3); // s751 rotr + r5 = r5 * r2; // s752 mul + r1 = r6 * r7 + r1; // s753 mad + r0 = r0 ^ r1; // s754 xor + r7 = r7 - r1; // s755 sub + r0 = r0 + r4 + select(0x68aab88bu, 0xb74ac71eu, ((sel >> 5u) & 1u) != 0u); // s756 add + r7 = r7 + r5 + select(0xba5c123au, 0xf81f5b66u, ((sel >> 0u) & 1u) != 0u); // s757 add + r0 = r7 * r2 + r0; // s758 mad + r1 = r1 | r0; // s759 or + r4 = mulhi(r4, r6); // s760 mulhi + r0 = mulhi(r0, r7); // s761 mulhi + r3 = rotr_var(r3, r4); // s762 rotr + r3 = rotl_imm(r3, 30u); // s763 rotl + r6 = r6 * r2; // s764 mul + r6 = r6 ^ r4; // s765 xor + r3 = r3 + r4 + select(0x6eb1d82au, 0x96dabea6u, ((sel >> 0u) & 1u) != 0u); // s766 add + r0 = r0 ^ simd_shuffle_xor(r2, (ushort)1); // s767 shfl + r3 = rotl_imm(r3, 8u); // s768 rotl + r7 = r7 * r4; // s769 mul + r6 = r1 * r2 + r6; // s770 mad + r2 = r2 ^ r7; // s771 xor + r6 = r6 * r0; // s772 mul + r2 = r2 - r1; // s773 sub + r1 = r0 * r1 + r1; // s774 mad + r5 = mulhi(r5, r7); // s775 mulhi + r0 = rotr_var(r0, r4); // s776 rotr + r6 = r6 ^ r0; // s777 xor + r4 = mulhi(r4, r7); // s778 mulhi + r1 = r3 * r0 + r1; // s779 mad + r6 = r6 + r4 + select(0x11d7b79au, 0x903f3f77u, ((sel >> 2u) & 1u) != 0u); // s780 add + r4 = r4 ^ r7; // s781 xor + r1 = r1 + r2 + select(0x1791eaddu, 0x2ca81d8du, ((sel >> 14u) & 1u) != 0u); // s782 add + r2 = rotr_var(r2, r1); // s783 rotr + r4 = r4 * r6; // s784 mul + r1 = r1 ^ r6; // s785 xor + r4 = r4 - r0; // s786 sub + r3 = r3 ^ r4; // s787 xor + r4 = r4 * r1; // s788 mul + r4 = r6 * r7 + r4; // s789 mad + r5 = r5 - r0; // s790 sub + r2 = r2 * r0; // s791 mul + r7 = rotl_imm(r7, 12u); // s792 rotl + r2 = r7 * r3 + r2; // s793 mad + r1 = r4 * r4 + r1; // s794 mad + r6 = r6 + r4 + select(0xc08797bbu, 0xf66fad29u, ((sel >> 15u) & 1u) != 0u); // s795 add + r1 = r1 - r4; // s796 sub + r5 = r5 * r2; // s797 mul + r5 = r5 ^ r2; // s798 xor + r0 = r0 * r1; // s799 mul + r6 = r6 + r4 + select(0x6d4a6371u, 0x2d82a681u, ((sel >> 13u) & 1u) != 0u); // s800 add + r1 = r6 * r1 + r1; // s801 mad + r0 = r0 - r2; // s802 sub + r6 = r6 ^ r2; // s803 xor + r7 = rotl_imm(r7, 24u); // s804 rotl + r6 = r6 ^ r7; // s805 xor + r7 = r7 | r0; // s806 or + r0 = rotl_imm(r0, 5u); // s807 rotl + r1 = r1 ^ simd_shuffle_xor(r2, (ushort)2); // s808 shfl + r4 = r1 * r5 + r4; // s809 mad + r0 = r0 + r2 + select(0x0092eb62u, 0x63e62197u, ((sel >> 14u) & 1u) != 0u); // s810 add + r5 = r5 - r3; // s811 sub + r2 = r1 * r5 + r2; // s812 mad + r6 = r6 ^ simd_shuffle_xor(r0, (ushort)16); // s813 shfl + r7 = r5 * r1 + r7; // s814 mad + r0 = mulhi(r0, r7); // s815 mulhi + r2 = r2 | r1; // s816 or + r7 = mulhi(r7, r3); // s817 mulhi + r2 = r2 ^ r4; // s818 xor + r4 = r4 + r3 + select(0xbb69174fu, 0x27d94f57u, ((sel >> 0u) & 1u) != 0u); // s819 add + r5 = r5 + r3 + select(0xda6759f2u, 0x82285691u, ((sel >> 1u) & 1u) != 0u); // s820 add + r1 = r1 + r3 + select(0x9ad4b47fu, 0xe50565d8u, ((sel >> 31u) & 1u) != 0u); // s821 add + r5 = rotl_imm(r5, 6u); // s822 rotl + r3 = r3 - r0; // s823 sub + r6 = rotl_imm(r6, 12u); // s824 rotl + r4 = r4 | r5; // s825 or + r3 = r3 ^ r2; // s826 xor + r4 = r4 + r0 + select(0xca1e80fbu, 0xffcab83au, ((sel >> 26u) & 1u) != 0u); // s827 add + r3 = r3 | r7; // s828 or + r1 = r5 * r7 + r1; // s829 mad + r6 = r6 ^ simd_shuffle_xor(r0, (ushort)16); // s830 shfl + r1 = r1 - r0; // s831 sub + r0 = rotr_var(r0, r2); // s832 rotr + r1 = mulhi(r1, r0); // s833 mulhi + r6 = mulhi(r6, r4); // s834 mulhi + r6 = rotl_imm(r6, 2u); // s835 rotl + r4 = r4 | r6; // s836 or + r6 = rotl_imm(r6, 23u); // s837 rotl + r4 = r7 * r4 + r4; // s838 mad + r0 = r0 | r1; // s839 or + r5 = mulhi(r5, r3); // s840 mulhi + r7 = r4 * r6 + r7; // s841 mad + r1 = r1 + r4 + select(0xcfb90e90u, 0x1bc9f95du, ((sel >> 21u) & 1u) != 0u); // s842 add + r1 = r1 + r2 + select(0x0b4758b6u, 0xf9bd620fu, ((sel >> 18u) & 1u) != 0u); // s843 add + r2 = r2 ^ simd_shuffle_xor(r5, (ushort)16); // s844 shfl + r3 = r1 * r7 + r3; // s845 mad + r5 = r5 * r2; // s846 mul + r0 = rotl_imm(r0, 21u); // s847 rotl + r7 = r7 ^ r1; // s848 xor + r3 = r3 + r4 + select(0x41fdc15au, 0x697a4946u, ((sel >> 18u) & 1u) != 0u); // s849 add + r0 = r0 ^ simd_shuffle_xor(r5, (ushort)4); // s850 shfl + r1 = rotr_var(r1, r5); // s851 rotr + r5 = r5 | r6; // s852 or + r6 = r6 - r2; // s853 sub + r2 = r2 ^ r6; // s854 xor + r4 = r4 - r6; // s855 sub + r6 = r4 * r6 + r6; // s856 mad + r4 = r4 * r0; // s857 mul + r2 = r2 ^ simd_shuffle_xor(r1, (ushort)4); // s858 shfl + r3 = r3 * r4; // s859 mul + r3 = r1 * r7 + r3; // s860 mad + r3 = r3 ^ simd_shuffle_xor(r2, (ushort)2); // s861 shfl + r7 = r7 ^ simd_shuffle_xor(r4, (ushort)8); // s862 shfl + r0 = r2 * r2 + r0; // s863 mad + r6 = r6 ^ r0; // s864 xor + r6 = r6 + r2 + select(0x90656f74u, 0x7fedd7f3u, ((sel >> 2u) & 1u) != 0u); // s865 add + r3 = r3 ^ r2; // s866 xor + r1 = r1 | r4; // s867 or + r6 = r6 ^ simd_shuffle_xor(r7, (ushort)2); // s868 shfl + r1 = mulhi(r1, r0); // s869 mulhi + r3 = r3 ^ simd_shuffle_xor(r1, (ushort)4); // s870 shfl + r0 = r0 - r3; // s871 sub + r6 = r6 + r1 + select(0xa5c0b461u, 0xbe1b480au, ((sel >> 11u) & 1u) != 0u); // s872 add + r3 = r3 ^ simd_shuffle_xor(r6, (ushort)1); // s873 shfl + r5 = r5 ^ simd_shuffle_xor(r0, (ushort)1); // s874 shfl + r2 = mulhi(r2, r4); // s875 mulhi + r5 = r5 ^ simd_shuffle_xor(r7, (ushort)4); // s876 shfl + r5 = rotl_imm(r5, 14u); // s877 rotl + r2 = r2 ^ r7; // s878 xor + r7 = r7 ^ r0; // s879 xor + r0 = r0 * r2; // s880 mul + r4 = r4 * r2; // s881 mul + r7 = r7 * r6; // s882 mul + r4 = mulhi(r4, r5); // s883 mulhi + r0 = r0 - r4; // s884 sub + r0 = r0 ^ r5; // s885 xor + r6 = r6 * r5; // s886 mul + r1 = r1 + r5 + select(0xe806fcecu, 0x7007f98fu, ((sel >> 14u) & 1u) != 0u); // s887 add + r3 = r3 * r1; // s888 mul + r5 = r5 ^ r3; // s889 xor + r6 = r6 | r2; // s890 or + r1 = r1 * r2; // s891 mul + r5 = r5 + r7 + select(0x89a8551eu, 0xf3c87e02u, ((sel >> 3u) & 1u) != 0u); // s892 add + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)16); // s893 shfl + r1 = r1 + r3 + select(0xba1369dbu, 0xc315f5deu, ((sel >> 13u) & 1u) != 0u); // s894 add + r5 = r0 * r3 + r5; // s895 mad + r5 = rotr_var(r5, r2); // s896 rotr + r1 = r1 ^ r0; // s897 xor + r5 = r5 ^ r1; // s898 xor + r5 = rotr_var(r5, r1); // s899 rotr + r3 = r6 * r6 + r3; // s900 mad + r0 = rotl_imm(r0, 8u); // s901 rotl + r1 = r1 | r0; // s902 or + r1 = r1 + r2 + select(0x260e6848u, 0x1c355a71u, ((sel >> 3u) & 1u) != 0u); // s903 add + r7 = r7 ^ simd_shuffle_xor(r2, (ushort)16); // s904 shfl + r1 = mulhi(r1, r3); // s905 mulhi + r1 = rotr_var(r1, r4); // s906 rotr + r6 = r6 + r0 + select(0xa74fd2b1u, 0x0c74a1a8u, ((sel >> 8u) & 1u) != 0u); // s907 add + r6 = rotr_var(r6, r2); // s908 rotr + r4 = rotl_imm(r4, 12u); // s909 rotl + r5 = r5 + r3 + select(0xe5fb043eu, 0xa49b5d73u, ((sel >> 29u) & 1u) != 0u); // s910 add + r3 = r3 ^ r0; // s911 xor + r3 = rotr_var(r3, r4); // s912 rotr + r6 = rotr_var(r6, r0); // s913 rotr + r2 = r2 ^ r5; // s914 xor + r0 = r0 * r7; // s915 mul + r3 = r3 ^ r0; // s916 xor + r5 = r1 * r7 + r5; // s917 mad + r3 = r3 + r4 + select(0x264cb47bu, 0xeb76e56cu, ((sel >> 2u) & 1u) != 0u); // s918 add + r3 = mulhi(r3, r4); // s919 mulhi + r5 = r5 + r6 + select(0x418baa72u, 0x2aab9631u, ((sel >> 9u) & 1u) != 0u); // s920 add + r5 = mulhi(r5, r1); // s921 mulhi + r7 = r7 - r3; // s922 sub + r6 = r6 + r1 + select(0x3696a894u, 0x98e6b26du, ((sel >> 2u) & 1u) != 0u); // s923 add + r6 = r3 * r1 + r6; // s924 mad + r2 = r2 ^ simd_shuffle_xor(r1, (ushort)2); // s925 shfl + r6 = r6 ^ r1; // s926 xor + r4 = r4 ^ r3; // s927 xor + r0 = r0 + r4 + select(0x0468c062u, 0x142778eeu, ((sel >> 7u) & 1u) != 0u); // s928 add + r7 = r7 + r3 + select(0x0af82291u, 0x4eae212du, ((sel >> 29u) & 1u) != 0u); // s929 add + r4 = r4 ^ simd_shuffle_xor(r7, (ushort)16); // s930 shfl + r7 = r7 + r2 + select(0x17de5e29u, 0x8d2a8b36u, ((sel >> 20u) & 1u) != 0u); // s931 add + r5 = r5 + r1 + select(0x686794a8u, 0xe2d2d7d5u, ((sel >> 6u) & 1u) != 0u); // s932 add + r0 = mulhi(r0, r3); // s933 mulhi + r4 = r4 + r0 + select(0x66278068u, 0xe3c3c6f9u, ((sel >> 10u) & 1u) != 0u); // s934 add + r6 = rotl_imm(r6, 22u); // s935 rotl + r0 = r0 | r2; // s936 or + r4 = r4 * r3; // s937 mul + r3 = r3 | r6; // s938 or + r7 = rotl_imm(r7, 28u); // s939 rotl + r0 = r0 + r6 + select(0xc2d02ca6u, 0xc2296063u, ((sel >> 20u) & 1u) != 0u); // s940 add + r1 = r1 + r5 + select(0x0b3c00e0u, 0xef1ca415u, ((sel >> 14u) & 1u) != 0u); // s941 add + r2 = r2 - r6; // s942 sub + r6 = r6 | r3; // s943 or + r0 = rotl_imm(r0, 2u); // s944 rotl + r2 = r2 * r1; // s945 mul + r0 = r0 + r6 + select(0x11224846u, 0x06a1321au, ((sel >> 1u) & 1u) != 0u); // s946 add + r3 = r3 * r6; // s947 mul + r5 = r5 - r2; // s948 sub + r5 = r5 + r4 + select(0x461c43d4u, 0x5d3e225cu, ((sel >> 5u) & 1u) != 0u); // s949 add + r2 = r2 ^ simd_shuffle_xor(r1, (ushort)16); // s950 shfl + r7 = r0 * r0 + r7; // s951 mad + r6 = rotr_var(r6, r4); // s952 rotr + r1 = r1 + r0 + select(0xd5eed39fu, 0xbb84f628u, ((sel >> 30u) & 1u) != 0u); // s953 add + r4 = rotl_imm(r4, 31u); // s954 rotl + r1 = r1 ^ simd_shuffle_xor(r2, (ushort)16); // s955 shfl + r2 = r2 - r6; // s956 sub + r4 = r4 ^ r2; // s957 xor + r0 = r0 ^ r2; // s958 xor + r1 = r1 + r0 + select(0x519d72f7u, 0x374c0426u, ((sel >> 28u) & 1u) != 0u); // s959 add + r5 = r5 * r4; // s960 mul + r5 = r5 - r7; // s961 sub + r2 = r2 ^ r6; // s962 xor + r4 = r4 ^ r1; // s963 xor + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)16); // s964 shfl + r7 = mulhi(r7, r3); // s965 mulhi + r4 = rotl_imm(r4, 12u); // s966 rotl + r4 = r4 + r6 + select(0x151dae18u, 0x03b88592u, ((sel >> 26u) & 1u) != 0u); // s967 add + r1 = r1 ^ simd_shuffle_xor(r3, (ushort)4); // s968 shfl + r3 = r3 ^ simd_shuffle_xor(r6, (ushort)8); // s969 shfl + r2 = r2 ^ r7; // s970 xor + r5 = r3 * r4 + r5; // s971 mad + r0 = r0 ^ r3; // s972 xor + r2 = r2 ^ r5; // s973 xor + r1 = r1 ^ simd_shuffle_xor(r0, (ushort)4); // s974 shfl + r5 = r1 * r4 + r5; // s975 mad + r2 = rotl_imm(r2, 19u); // s976 rotl + r1 = r1 - r4; // s977 sub + r5 = rotr_var(r5, r4); // s978 rotr + r2 = r2 ^ simd_shuffle_xor(r1, (ushort)16); // s979 shfl + r6 = r6 + r7 + select(0x16220e61u, 0x1fdee45eu, ((sel >> 28u) & 1u) != 0u); // s980 add + r4 = rotr_var(r4, r6); // s981 rotr + r6 = mulhi(r6, r3); // s982 mulhi + r5 = rotl_imm(r5, 17u); // s983 rotl + r2 = r7 * r1 + r2; // s984 mad + r4 = r4 ^ simd_shuffle_xor(r1, (ushort)8); // s985 shfl + r3 = r3 ^ r1; // s986 xor + r4 = r4 + r0 + select(0x6cd6b697u, 0x44adc457u, ((sel >> 27u) & 1u) != 0u); // s987 add + r1 = r1 * r5; // s988 mul + r4 = r4 + r2 + select(0x1103d2d2u, 0x0a06a223u, ((sel >> 2u) & 1u) != 0u); // s989 add + r4 = r4 * r1; // s990 mul + r4 = r5 * r1 + r4; // s991 mad + r3 = r3 ^ simd_shuffle_xor(r6, (ushort)1); // s992 shfl + r1 = r1 - r3; // s993 sub + r4 = r7 * r5 + r4; // s994 mad + r1 = mulhi(r1, r2); // s995 mulhi + r2 = r1 * r0 + r2; // s996 mad + r3 = rotl_imm(r3, 31u); // s997 rotl + r4 = r4 - r3; // s998 sub + r5 = rotr_var(r5, r3); // s999 rotr + r4 = r4 ^ simd_shuffle_xor(r0, (ushort)4); // s1000 shfl + r2 = r2 - r5; // s1001 sub + r3 = r4 * r4 + r3; // s1002 mad + r7 = r5 * r1 + r7; // s1003 mad + r7 = r7 + r4 + select(0xa9c9d8a9u, 0x0044887fu, ((sel >> 29u) & 1u) != 0u); // s1004 add + r4 = mulhi(r4, r0); // s1005 mulhi + r4 = rotl_imm(r4, 21u); // s1006 rotl + r3 = r3 * r1; // s1007 mul + r1 = r1 ^ simd_shuffle_xor(r5, (ushort)2); // s1008 shfl + r0 = mulhi(r0, r6); // s1009 mulhi + r0 = r0 ^ r3; // s1010 xor + r5 = r5 | r4; // s1011 or + r1 = r1 ^ simd_shuffle_xor(r5, (ushort)4); // s1012 shfl + r2 = r2 + r4 + select(0xfa1574e3u, 0x6b70e2c7u, ((sel >> 4u) & 1u) != 0u); // s1013 add + r5 = rotr_var(r5, r7); // s1014 rotr + r0 = rotr_var(r0, r7); // s1015 rotr + r5 = r5 - r7; // s1016 sub + r4 = r4 ^ simd_shuffle_xor(r1, (ushort)16); // s1017 shfl + r6 = mulhi(r6, r7); // s1018 mulhi + r0 = rotr_var(r0, r1); // s1019 rotr + r2 = r2 ^ r0; // s1020 xor + r4 = r5 * r1 + r4; // s1021 mad + r6 = r6 | r2; // s1022 or + r3 = r3 ^ r0; // s1023 xor + } + } + uint lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((ulong)hi << 32) | (ulong)lo; +} diff --git a/proto-cuda/packs-ca3-shadow/sh1024x3/program_bound.metal b/proto-cuda/packs-ca3-shadow/sh1024x3/program_bound.metal new file mode 100644 index 000000000..253a2f535 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh1024x3/program_bound.metal @@ -0,0 +1,1138 @@ +#include +using namespace metal; + +#define MASK 0x0fffffffu +constant uint SEEDW[8] = { 0x67a9a7beu, 0x1a155b25u, 0xfddfb732u, 0x4b5af2e8u, 0xc55caf33u, 0xa27c13b7u, 0x06628a48u, 0x03852469u }; + +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 = r3 * r4 + r2; // 0 + r2 = r1 * r1 + r2; // 1 + r2 = r3 * r2 + r2; // 2 + r3 = r3 ^ r5; // 3 + r7 = r7 ^ dataset[r2 & MASK]; // 4 + r5 = r5 ^ dataset[r7 & MASK]; // 5 + r1 = r1 ^ simd_shuffle_xor(r4, (ushort)8); // 6 + r7 = r7 ^ simd_shuffle_xor(r3, (ushort)8); // 7 + r1 = mulhi(r1, r5); // 8 + r6 = rotr_var(r6, r3); // 9 + r3 = r3 | r4; // 10 + r4 = r4 ^ dataset[r3 & MASK]; // 11 + r0 = mulhi(r0, r4); // 12 + r5 = r5 + r1 + select(0xc7934706u, 0xd3177981u, ((sel >> 30u) & 1u) != 0u); // 13 + r0 = r0 ^ dataset[r4 & MASK]; // 14 + r2 = r2 - r4; // 15 + r2 = r2 ^ dataset[r0 & MASK]; // 16 + r7 = r7 ^ dataset[r2 & MASK]; // 17 + r7 = r7 ^ simd_shuffle_xor(r3, (ushort)4); // 18 + r5 = r5 * r0; // 19 + r3 = r3 ^ simd_shuffle_xor(r4, (ushort)2); // 20 + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)16); // 21 + r6 = mulhi(r6, r2); // 22 + r6 = r6 ^ dataset[r1 & MASK]; // 23 + r5 = r5 * r0; // 24 + r5 = rotl_imm(r5, 19u); // 25 + r7 = r7 ^ simd_shuffle_xor(r6, (ushort)2); // 26 + r0 = r0 ^ r5; // 27 + r0 = r0 ^ r4; // 28 + r3 = r3 - r0; // 29 + r5 = r5 * r1; // 30 + r7 = r7 ^ dataset[r2 & MASK]; // 31 + r1 = r1 ^ dataset[r0 & MASK]; // 32 + r5 = r5 ^ r6; // 33 + r5 = r5 ^ dataset[r1 & MASK]; // 34 + r0 = mulhi(r0, r5); // 35 + r5 = r5 ^ simd_shuffle_xor(r2, (ushort)4); // 36 + r7 = r7 ^ dataset[r0 & MASK]; // 37 + r3 = r3 + r1 + select(0x75ba2fadu, 0x230c005cu, ((sel >> 27u) & 1u) != 0u); // 38 + r1 = r1 ^ simd_shuffle_xor(r5, (ushort)4); // 39 + r2 = r2 ^ r5; // 40 + r3 = r6 * r3 + r3; // 41 + r6 = r6 - r7; // 42 + r7 = r7 ^ r0; // 43 + r1 = r1 ^ dataset[r7 & MASK]; // 44 + r2 = r2 * r3; // 45 + r1 = mulhi(r1, r5); // 46 + r4 = r4 - r3; // 47 + r2 = rotr_var(r2, r6); // 48 + r3 = r3 ^ dataset[r5 & MASK]; // 49 + r1 = r1 + r5 + select(0x81b8bc2cu, 0x1907970cu, ((sel >> 7u) & 1u) != 0u); // 50 + r0 = r0 * r2; // 51 + r0 = r0 + r2 + select(0x4f92b968u, 0x699fd448u, ((sel >> 6u) & 1u) != 0u); // 52 + r1 = r1 + r0 + select(0x2bb965afu, 0x77b1520du, ((sel >> 12u) & 1u) != 0u); // 53 + r7 = rotl_imm(r7, 14u); // 54 + r3 = r3 + r7 + select(0x7b0fe07au, 0xa54c55a0u, ((sel >> 1u) & 1u) != 0u); // 55 + r6 = r6 ^ dataset[r7 & MASK]; // 56 + r1 = rotr_var(r1, r5); // 57 + r5 = r5 ^ dataset[r4 & MASK]; // 58 + r6 = r6 ^ dataset[r2 & MASK]; // 59 + r3 = r5 * r0 + r3; // 60 + r5 = r5 + r7 + select(0xaf9dd72du, 0xad7493e7u, ((sel >> 31u) & 1u) != 0u); // 61 + r4 = r4 + r6 + select(0x89841d87u, 0x1e07c3d9u, ((sel >> 27u) & 1u) != 0u); // 62 + r5 = rotl_imm(r5, 19u); // 63 + // latency-shadow block (Counter ASIC 3.0 item 8): 1024 ALU instructions x 3 passes after instruction 63, no load + for (uint sh = 0u; sh < 3u; ++sh) { + r5 = r5 + r2 + select(0x92199f99u, 0x8bc12da9u, ((sel >> 18u) & 1u) != 0u); // s0 add + r0 = r0 + r7 + select(0x8d72d3adu, 0x63079e5au, ((sel >> 26u) & 1u) != 0u); // s1 add + r6 = r6 ^ simd_shuffle_xor(r3, (ushort)2); // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + select(0xb21b4babu, 0x5d4c7a60u, ((sel >> 31u) & 1u) != 0u); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + select(0x2fe0e98bu, 0xc88e2942u, ((sel >> 16u) & 1u) != 0u); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + r6 = r6 ^ simd_shuffle_xor(r1, (ushort)4); // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + r2 = r2 ^ simd_shuffle_xor(r6, (ushort)4); // s12 shfl + r1 = r1 + r5 + select(0xbdf8f9a5u, 0xbc48c63eu, ((sel >> 25u) & 1u) != 0u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)8); // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + select(0x45c37cecu, 0x96e8f127u, ((sel >> 1u) & 1u) != 0u); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = mulhi(r6, r0); // s28 mulhi + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)2); // s29 shfl + r1 = r1 ^ simd_shuffle_xor(r6, (ushort)1); // s30 shfl + r1 = r1 + r6 + select(0x37985632u, 0xb1cdb2abu, ((sel >> 1u) & 1u) != 0u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + r3 = r3 ^ simd_shuffle_xor(r4, (ushort)2); // s33 shfl + r0 = r0 ^ simd_shuffle_xor(r3, (ushort)4); // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + select(0x804e777eu, 0x856e0180u, ((sel >> 0u) & 1u) != 0u); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + select(0x0b06c8a7u, 0xe9bd0cc4u, ((sel >> 2u) & 1u) != 0u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = mulhi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = mulhi(r4, r3); // s44 mulhi + r6 = r6 + r7 + select(0xee822e17u, 0xcdcb63f6u, ((sel >> 12u) & 1u) != 0u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + r4 = r4 ^ simd_shuffle_xor(r3, (ushort)8); // s47 shfl + r6 = mulhi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + select(0x3dfad1b6u, 0xd4758987u, ((sel >> 10u) & 1u) != 0u); // s56 add + r4 = r4 + r1 + select(0xfca75bc2u, 0x0602d6beu, ((sel >> 0u) & 1u) != 0u); // s57 add + r5 = mulhi(r5, r6); // s58 mulhi + r2 = r2 ^ simd_shuffle_xor(r1, (ushort)2); // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + select(0xd71c02ffu, 0x8596687au, ((sel >> 6u) & 1u) != 0u); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + r7 = r7 ^ simd_shuffle_xor(r5, (ushort)2); // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + select(0x3c6fe15du, 0x08ac5733u, ((sel >> 0u) & 1u) != 0u); // s72 add + r3 = r3 ^ simd_shuffle_xor(r2, (ushort)8); // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + select(0x295d5faeu, 0xc100b495u, ((sel >> 1u) & 1u) != 0u); // s77 add + r3 = mulhi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + select(0x274a9221u, 0x5cc59530u, ((sel >> 15u) & 1u) != 0u); // s81 add + r7 = r7 + r3 + select(0xc8651f8eu, 0x141479ecu, ((sel >> 5u) & 1u) != 0u); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + r2 = r2 ^ simd_shuffle_xor(r5, (ushort)16); // s85 shfl + r3 = r3 ^ r2; // s86 xor + r5 = r5 ^ simd_shuffle_xor(r7, (ushort)2); // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + select(0x53f915c2u, 0x883c0c92u, ((sel >> 18u) & 1u) != 0u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + select(0xe2be00a5u, 0x3cc5bd20u, ((sel >> 31u) & 1u) != 0u); // s91 add + r7 = r7 ^ simd_shuffle_xor(r2, (ushort)1); // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + select(0x423fd9c9u, 0xbfd646cbu, ((sel >> 17u) & 1u) != 0u); // s101 add + r7 = r7 + r6 + select(0x8d3c011du, 0x19b74a43u, ((sel >> 11u) & 1u) != 0u); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + select(0x8ce14721u, 0x7dcb7e18u, ((sel >> 15u) & 1u) != 0u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = mulhi(r2, r0); // s109 mulhi + r1 = mulhi(r1, r0); // s110 mulhi + r0 = r0 + r2 + select(0x2d9fc6b9u, 0x3c179ad8u, ((sel >> 28u) & 1u) != 0u); // s111 add + r2 = mulhi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + select(0x502138e2u, 0x47359729u, ((sel >> 22u) & 1u) != 0u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = mulhi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + r4 = r4 ^ simd_shuffle_xor(r2, (ushort)2); // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + r7 = r7 ^ simd_shuffle_xor(r2, (ushort)4); // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + select(0x33dff776u, 0x6c57e4e7u, ((sel >> 15u) & 1u) != 0u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + select(0x5db25b34u, 0xe8212c0cu, ((sel >> 30u) & 1u) != 0u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = mulhi(r0, r5); // s138 mulhi + r2 = r2 + r7 + select(0x218d4090u, 0xd44ff710u, ((sel >> 10u) & 1u) != 0u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + r3 = r3 ^ simd_shuffle_xor(r6, (ushort)1); // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + select(0xf4b1a8deu, 0xb98942fau, ((sel >> 29u) & 1u) != 0u); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + select(0x2bef10f2u, 0x0d48ba42u, ((sel >> 17u) & 1u) != 0u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + select(0xdc5cc080u, 0xc98dea9cu, ((sel >> 30u) & 1u) != 0u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + select(0x18197438u, 0x6c752dcbu, ((sel >> 11u) & 1u) != 0u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + select(0xf1c46574u, 0x8e481727u, ((sel >> 3u) & 1u) != 0u); // s163 add + r0 = mulhi(r0, r4); // s164 mulhi + r2 = r2 + r6 + select(0xac578137u, 0x550ab406u, ((sel >> 20u) & 1u) != 0u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + select(0xa33e6706u, 0xaebb5966u, ((sel >> 14u) & 1u) != 0u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + r7 = r7 ^ simd_shuffle_xor(r0, (ushort)8); // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + select(0xd94d55acu, 0x5bb7550fu, ((sel >> 21u) & 1u) != 0u); // s184 add + r3 = r3 | r5; // s185 or + r6 = mulhi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)2); // s188 shfl + r6 = r6 + r5 + select(0x89e747feu, 0x2a354e2du, ((sel >> 6u) & 1u) != 0u); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = mulhi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + r4 = r4 ^ simd_shuffle_xor(r5, (ushort)16); // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + select(0xea03e8e7u, 0x10cfdc71u, ((sel >> 7u) & 1u) != 0u); // s197 add + r7 = r7 + r5 + select(0xa7ee0102u, 0x66e148d3u, ((sel >> 15u) & 1u) != 0u); // s198 add + r5 = r5 - r2; // s199 sub + r5 = r5 ^ simd_shuffle_xor(r1, (ushort)2); // s200 shfl + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)8); // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + select(0x8379a4deu, 0x8558b619u, ((sel >> 10u) & 1u) != 0u); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = mulhi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + r2 = r2 ^ simd_shuffle_xor(r0, (ushort)4); // s209 shfl + r7 = r7 + r0 + select(0xaa8cb14eu, 0xf4049c4cu, ((sel >> 11u) & 1u) != 0u); // s210 add + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)16); // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + r3 = r3 ^ simd_shuffle_xor(r2, (ushort)16); // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = mulhi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + r5 = r5 ^ simd_shuffle_xor(r2, (ushort)8); // s222 shfl + r5 = mulhi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + select(0x1d176220u, 0x2a7fecb2u, ((sel >> 16u) & 1u) != 0u); // s230 add + r1 = r1 ^ simd_shuffle_xor(r2, (ushort)4); // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + select(0x17dafb4du, 0xadce39f3u, ((sel >> 25u) & 1u) != 0u); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + select(0xf2f77d26u, 0x0e7033b6u, ((sel >> 29u) & 1u) != 0u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + select(0xfed2da4eu, 0x7b2ff6b7u, ((sel >> 31u) & 1u) != 0u); // s247 add + r0 = r0 + r7 + select(0x03b2891cu, 0xb5fad7b1u, ((sel >> 0u) & 1u) != 0u); // s248 add + r5 = mulhi(r5, r4); // s249 mulhi + r5 = r5 + r2 + select(0x042cd6e3u, 0xa7e71c2fu, ((sel >> 11u) & 1u) != 0u); // s250 add + r6 = r6 ^ simd_shuffle_xor(r1, (ushort)1); // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + select(0x784a302bu, 0xb83d78deu, ((sel >> 16u) & 1u) != 0u); // s254 add + r2 = r2 - r4; // s255 sub + r3 = r3 - r4; // s256 sub + r2 = r2 * r4; // s257 mul + r4 = r0 * r6 + r4; // s258 mad + r5 = r5 | r0; // s259 or + r4 = r4 ^ r6; // s260 xor + r6 = mulhi(r6, r3); // s261 mulhi + r2 = r2 * r6; // s262 mul + r5 = rotl_imm(r5, 1u); // s263 rotl + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)8); // s264 shfl + r3 = r3 * r2; // s265 mul + r2 = r2 + r5 + select(0x3dddf1b2u, 0x99a1d1b6u, ((sel >> 15u) & 1u) != 0u); // s266 add + r2 = r2 ^ simd_shuffle_xor(r0, (ushort)8); // s267 shfl + r0 = r0 ^ simd_shuffle_xor(r1, (ushort)2); // s268 shfl + r4 = r4 - r2; // s269 sub + r0 = r0 ^ simd_shuffle_xor(r5, (ushort)1); // s270 shfl + r3 = r3 + r2 + select(0xcfc62661u, 0x40ca287au, ((sel >> 21u) & 1u) != 0u); // s271 add + r1 = r1 ^ simd_shuffle_xor(r7, (ushort)16); // s272 shfl + r1 = r3 * r6 + r1; // s273 mad + r7 = r7 + r6 + select(0x44caede3u, 0xed4b65adu, ((sel >> 30u) & 1u) != 0u); // s274 add + r5 = r5 ^ r7; // s275 xor + r2 = r2 * r6; // s276 mul + r2 = r2 + r1 + select(0x9aae6c12u, 0x0f45ae89u, ((sel >> 6u) & 1u) != 0u); // s277 add + r2 = r2 ^ r6; // s278 xor + r1 = r1 - r2; // s279 sub + r5 = r5 ^ r1; // s280 xor + r7 = r7 ^ r1; // s281 xor + r7 = r7 - r1; // s282 sub + r5 = r5 - r7; // s283 sub + r7 = r0 * r6 + r7; // s284 mad + r5 = mulhi(r5, r4); // s285 mulhi + r3 = r3 - r5; // s286 sub + r5 = r5 - r1; // s287 sub + r1 = r3 * r7 + r1; // s288 mad + r3 = rotl_imm(r3, 9u); // s289 rotl + r5 = r5 ^ simd_shuffle_xor(r6, (ushort)8); // s290 shfl + r7 = r7 + r2 + select(0x2307120bu, 0xe086d3b6u, ((sel >> 1u) & 1u) != 0u); // s291 add + r4 = r4 ^ r3; // s292 xor + r3 = rotl_imm(r3, 14u); // s293 rotl + r5 = r5 - r4; // s294 sub + r2 = mulhi(r2, r3); // s295 mulhi + r1 = r1 ^ simd_shuffle_xor(r3, (ushort)4); // s296 shfl + r3 = r6 * r1 + r3; // s297 mad + r4 = r4 ^ r1; // s298 xor + r6 = r6 + r3 + select(0x4e3a12e5u, 0xadbeb223u, ((sel >> 24u) & 1u) != 0u); // s299 add + r6 = mulhi(r6, r5); // s300 mulhi + r7 = rotr_var(r7, r5); // s301 rotr + r5 = r5 ^ simd_shuffle_xor(r4, (ushort)16); // s302 shfl + r3 = r3 ^ r4; // s303 xor + r2 = r3 * r1 + r2; // s304 mad + r1 = r1 ^ r7; // s305 xor + r1 = r1 + r0 + select(0x51ab0157u, 0x0d8f1149u, ((sel >> 22u) & 1u) != 0u); // s306 add + r2 = r2 + r1 + select(0x3b5e8835u, 0x99a96de9u, ((sel >> 24u) & 1u) != 0u); // s307 add + r1 = r5 * r5 + r1; // s308 mad + r2 = r2 * r4; // s309 mul + r3 = r3 ^ simd_shuffle_xor(r7, (ushort)8); // s310 shfl + r0 = r0 ^ r4; // s311 xor + r5 = mulhi(r5, r2); // s312 mulhi + r7 = r7 + r2 + select(0x81f3297cu, 0x86ddfba7u, ((sel >> 30u) & 1u) != 0u); // s313 add + r3 = r3 + r1 + select(0x838e4a2fu, 0x38aa230au, ((sel >> 0u) & 1u) != 0u); // s314 add + r7 = r7 ^ simd_shuffle_xor(r0, (ushort)16); // s315 shfl + r7 = r7 - r5; // s316 sub + r5 = r5 ^ simd_shuffle_xor(r1, (ushort)4); // s317 shfl + r1 = r1 + r3 + select(0xebcad805u, 0xa6399179u, ((sel >> 11u) & 1u) != 0u); // s318 add + r7 = rotl_imm(r7, 21u); // s319 rotl + r7 = r7 ^ r6; // s320 xor + r7 = r7 | r6; // s321 or + r5 = r5 + r3 + select(0x4c906f73u, 0x4de83051u, ((sel >> 25u) & 1u) != 0u); // s322 add + r0 = r0 + r4 + select(0x742ec195u, 0xd3d821c5u, ((sel >> 14u) & 1u) != 0u); // s323 add + r6 = r6 ^ r2; // s324 xor + r6 = rotl_imm(r6, 1u); // s325 rotl + r4 = rotl_imm(r4, 24u); // s326 rotl + r4 = r4 | r3; // s327 or + r2 = r1 * r3 + r2; // s328 mad + r2 = r2 ^ r7; // s329 xor + r2 = r2 | r3; // s330 or + r7 = r7 - r1; // s331 sub + r3 = r3 + r6 + select(0xb86750e9u, 0xc06f831eu, ((sel >> 0u) & 1u) != 0u); // s332 add + r7 = rotl_imm(r7, 25u); // s333 rotl + r3 = r0 * r0 + r3; // s334 mad + r2 = r2 + r5 + select(0xb57956eeu, 0x5225df1du, ((sel >> 28u) & 1u) != 0u); // s335 add + r3 = r1 * r6 + r3; // s336 mad + r4 = r2 * r2 + r4; // s337 mad + r7 = r7 * r2; // s338 mul + r1 = r1 * r6; // s339 mul + r4 = r4 + r5 + select(0x23f6425fu, 0xb73822ceu, ((sel >> 5u) & 1u) != 0u); // s340 add + r5 = r5 ^ simd_shuffle_xor(r7, (ushort)2); // s341 shfl + r6 = r6 ^ r5; // s342 xor + r0 = rotl_imm(r0, 13u); // s343 rotl + r0 = rotr_var(r0, r3); // s344 rotr + r1 = r1 - r0; // s345 sub + r6 = rotr_var(r6, r1); // s346 rotr + r6 = r6 ^ simd_shuffle_xor(r5, (ushort)4); // s347 shfl + r5 = r5 ^ simd_shuffle_xor(r1, (ushort)8); // s348 shfl + r5 = r5 ^ r3; // s349 xor + r1 = r4 * r0 + r1; // s350 mad + r3 = rotr_var(r3, r1); // s351 rotr + r1 = rotl_imm(r1, 13u); // s352 rotl + r3 = r3 + r0 + select(0x0dce5917u, 0xfa0c560eu, ((sel >> 26u) & 1u) != 0u); // s353 add + r3 = mulhi(r3, r2); // s354 mulhi + r1 = r2 * r4 + r1; // s355 mad + r0 = r0 ^ r1; // s356 xor + r7 = r7 * r5; // s357 mul + r0 = rotl_imm(r0, 5u); // s358 rotl + r2 = r7 * r7 + r2; // s359 mad + r2 = r2 | r6; // s360 or + r6 = r6 + r1 + select(0x7c83b79au, 0x277e027au, ((sel >> 19u) & 1u) != 0u); // s361 add + r0 = r0 * r2; // s362 mul + r3 = r3 * r6; // s363 mul + r2 = rotr_var(r2, r4); // s364 rotr + r5 = r5 + r1 + select(0x271f2385u, 0x52275ea4u, ((sel >> 1u) & 1u) != 0u); // s365 add + r1 = r1 * r6; // s366 mul + r0 = r0 + r7 + select(0x4c66800fu, 0x8f8b4093u, ((sel >> 30u) & 1u) != 0u); // s367 add + r4 = rotr_var(r4, r0); // s368 rotr + r4 = rotr_var(r4, r0); // s369 rotr + r1 = r0 * r6 + r1; // s370 mad + r0 = r0 - r5; // s371 sub + r7 = r7 + r2 + select(0x7dad1ed5u, 0x9a7dcadcu, ((sel >> 11u) & 1u) != 0u); // s372 add + r7 = r7 + r3 + select(0x1ea3d58eu, 0xf808c195u, ((sel >> 20u) & 1u) != 0u); // s373 add + r1 = r1 * r2; // s374 mul + r3 = r7 * r2 + r3; // s375 mad + r4 = r4 ^ r1; // s376 xor + r1 = r1 | r0; // s377 or + r5 = r5 + r0 + select(0x98b36d10u, 0x427ed5ceu, ((sel >> 26u) & 1u) != 0u); // s378 add + r6 = r6 * r0; // s379 mul + r7 = r7 ^ simd_shuffle_xor(r3, (ushort)1); // s380 shfl + r4 = r4 + r0 + select(0xb19cab2du, 0x38f848b9u, ((sel >> 18u) & 1u) != 0u); // s381 add + r3 = r5 * r2 + r3; // s382 mad + r0 = r0 | r7; // s383 or + r5 = r5 - r4; // s384 sub + r1 = r1 - r5; // s385 sub + r2 = r2 - r0; // s386 sub + r5 = r5 + r2 + select(0x341056b0u, 0xffc20cf8u, ((sel >> 17u) & 1u) != 0u); // s387 add + r1 = rotl_imm(r1, 26u); // s388 rotl + r2 = r2 ^ r5; // s389 xor + r5 = r7 * r0 + r5; // s390 mad + r3 = mulhi(r3, r2); // s391 mulhi + r5 = r5 + r4 + select(0x78aa571au, 0xfb939f2bu, ((sel >> 0u) & 1u) != 0u); // s392 add + r5 = r5 | r2; // s393 or + r1 = mulhi(r1, r7); // s394 mulhi + r4 = r4 - r2; // s395 sub + r7 = r7 - r1; // s396 sub + r0 = r0 + r1 + select(0x31af4767u, 0xa9c6c9fbu, ((sel >> 2u) & 1u) != 0u); // s397 add + r3 = r3 * r1; // s398 mul + r1 = r1 - r7; // s399 sub + r7 = r7 + r6 + select(0x266d4c34u, 0x34f9b056u, ((sel >> 8u) & 1u) != 0u); // s400 add + r5 = rotl_imm(r5, 5u); // s401 rotl + r0 = r0 + r4 + select(0x7241955eu, 0x79822c64u, ((sel >> 23u) & 1u) != 0u); // s402 add + r2 = r4 * r0 + r2; // s403 mad + r5 = rotl_imm(r5, 29u); // s404 rotl + r3 = r3 - r5; // s405 sub + r2 = r2 + r3 + select(0xf65aca5du, 0xda046091u, ((sel >> 27u) & 1u) != 0u); // s406 add + r4 = mulhi(r4, r7); // s407 mulhi + r2 = r2 + r1 + select(0x6a00cefbu, 0x167aba1cu, ((sel >> 14u) & 1u) != 0u); // s408 add + r2 = r6 * r6 + r2; // s409 mad + r6 = rotl_imm(r6, 26u); // s410 rotl + r6 = r6 | r7; // s411 or + r1 = rotl_imm(r1, 20u); // s412 rotl + r7 = r7 * r5; // s413 mul + r6 = r6 - r0; // s414 sub + r6 = mulhi(r6, r0); // s415 mulhi + r3 = rotl_imm(r3, 5u); // s416 rotl + r1 = r1 ^ simd_shuffle_xor(r3, (ushort)4); // s417 shfl + r0 = r0 * r4; // s418 mul + r4 = rotr_var(r4, r7); // s419 rotr + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)2); // s420 shfl + r5 = r3 * r6 + r5; // s421 mad + r3 = r3 ^ r4; // s422 xor + r3 = rotr_var(r3, r7); // s423 rotr + r4 = r4 + r1 + select(0xba29da18u, 0xbb669c17u, ((sel >> 26u) & 1u) != 0u); // s424 add + r7 = rotr_var(r7, r5); // s425 rotr + r2 = r2 * r6; // s426 mul + r1 = r1 + r4 + select(0x4f70e34fu, 0xc6b45a76u, ((sel >> 16u) & 1u) != 0u); // s427 add + r1 = rotl_imm(r1, 1u); // s428 rotl + r6 = mulhi(r6, r5); // s429 mulhi + r6 = r6 + r7 + select(0x3883e0f5u, 0xff610984u, ((sel >> 12u) & 1u) != 0u); // s430 add + r4 = r4 | r3; // s431 or + r7 = r7 ^ r5; // s432 xor + r3 = mulhi(r3, r2); // s433 mulhi + r2 = r2 ^ r6; // s434 xor + r4 = r4 | r3; // s435 or + r0 = r0 + r1 + select(0xb1b15861u, 0xf37057feu, ((sel >> 9u) & 1u) != 0u); // s436 add + r7 = r7 + r4 + select(0x2e9e173fu, 0x61793eafu, ((sel >> 4u) & 1u) != 0u); // s437 add + r5 = r5 ^ simd_shuffle_xor(r1, (ushort)1); // s438 shfl + r6 = r0 * r3 + r6; // s439 mad + r5 = r5 ^ r2; // s440 xor + r0 = r0 ^ simd_shuffle_xor(r4, (ushort)16); // s441 shfl + r6 = r6 * r3; // s442 mul + r5 = r5 - r4; // s443 sub + r2 = r2 ^ simd_shuffle_xor(r1, (ushort)4); // s444 shfl + r0 = r0 + r5 + select(0x646856aau, 0x69def831u, ((sel >> 12u) & 1u) != 0u); // s445 add + r4 = r4 + r6 + select(0x58a3f8fcu, 0x1f8ecb8bu, ((sel >> 23u) & 1u) != 0u); // s446 add + r4 = r0 * r2 + r4; // s447 mad + r5 = r5 * r0; // s448 mul + r2 = r2 + r5 + select(0x48d3062du, 0x7ecb876du, ((sel >> 11u) & 1u) != 0u); // s449 add + r2 = r5 * r6 + r2; // s450 mad + r7 = r7 ^ simd_shuffle_xor(r3, (ushort)4); // s451 shfl + r2 = r2 * r5; // s452 mul + r5 = mulhi(r5, r4); // s453 mulhi + r1 = r1 ^ r7; // s454 xor + r2 = r2 * r7; // s455 mul + r1 = r1 * r3; // s456 mul + r3 = r6 * r2 + r3; // s457 mad + r7 = r7 - r0; // s458 sub + r2 = r4 * r5 + r2; // s459 mad + r0 = rotl_imm(r0, 2u); // s460 rotl + r4 = r4 ^ r2; // s461 xor + r4 = r4 + r0 + select(0xb41dd69bu, 0x7b093757u, ((sel >> 18u) & 1u) != 0u); // s462 add + r6 = r6 + r1 + select(0xb042032eu, 0x916e1b7eu, ((sel >> 3u) & 1u) != 0u); // s463 add + r2 = r2 + r6 + select(0x4e68a2a0u, 0x6d42b978u, ((sel >> 8u) & 1u) != 0u); // s464 add + r3 = r3 - r2; // s465 sub + r2 = r2 * r5; // s466 mul + r7 = rotl_imm(r7, 28u); // s467 rotl + r0 = r0 - r3; // s468 sub + r7 = mulhi(r7, r2); // s469 mulhi + r7 = r7 | r6; // s470 or + r7 = rotl_imm(r7, 28u); // s471 rotl + r0 = r0 * r6; // s472 mul + r2 = r2 | r1; // s473 or + r2 = r2 + r4 + select(0x13ec3b3eu, 0x20c5276bu, ((sel >> 14u) & 1u) != 0u); // s474 add + r2 = rotr_var(r2, r6); // s475 rotr + r6 = r6 ^ simd_shuffle_xor(r0, (ushort)16); // s476 shfl + r2 = rotl_imm(r2, 15u); // s477 rotl + r5 = rotr_var(r5, r4); // s478 rotr + r3 = rotl_imm(r3, 26u); // s479 rotl + r5 = r5 | r6; // s480 or + r3 = rotl_imm(r3, 29u); // s481 rotl + r0 = rotr_var(r0, r7); // s482 rotr + r1 = r1 - r0; // s483 sub + r0 = r2 * r5 + r0; // s484 mad + r6 = r6 ^ r4; // s485 xor + r6 = r6 ^ r0; // s486 xor + r3 = r3 ^ simd_shuffle_xor(r7, (ushort)4); // s487 shfl + r6 = mulhi(r6, r0); // s488 mulhi + r1 = r1 * r0; // s489 mul + r3 = r3 ^ r6; // s490 xor + r3 = r3 * r6; // s491 mul + r0 = r0 * r3; // s492 mul + r4 = r4 | r3; // s493 or + r0 = r0 ^ simd_shuffle_xor(r5, (ushort)8); // s494 shfl + r0 = r0 ^ simd_shuffle_xor(r7, (ushort)16); // s495 shfl + r6 = r5 * r2 + r6; // s496 mad + r5 = r5 * r6; // s497 mul + r3 = r3 ^ r1; // s498 xor + r0 = r0 + r1 + select(0x53e99acau, 0x19f4c710u, ((sel >> 20u) & 1u) != 0u); // s499 add + r6 = r5 * r2 + r6; // s500 mad + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)4); // s501 shfl + r3 = r3 - r5; // s502 sub + r0 = rotl_imm(r0, 8u); // s503 rotl + r3 = r3 ^ r1; // s504 xor + r7 = r7 + r2 + select(0x0867fe20u, 0x7a6ac7b5u, ((sel >> 6u) & 1u) != 0u); // s505 add + r0 = r0 ^ simd_shuffle_xor(r7, (ushort)2); // s506 shfl + r0 = r0 * r1; // s507 mul + r6 = r6 | r5; // s508 or + r2 = r2 * r7; // s509 mul + r1 = r1 + r5 + select(0xd7fdc3ecu, 0xd77f6a03u, ((sel >> 21u) & 1u) != 0u); // s510 add + r3 = r3 ^ simd_shuffle_xor(r7, (ushort)8); // s511 shfl + r6 = r6 + r3 + select(0x297a096au, 0x5c22b0b5u, ((sel >> 9u) & 1u) != 0u); // s512 add + r7 = r7 | r0; // s513 or + r7 = r7 + r3 + select(0x5de1d1d1u, 0x4caafacdu, ((sel >> 27u) & 1u) != 0u); // s514 add + r1 = mulhi(r1, r0); // s515 mulhi + r0 = r0 - r6; // s516 sub + r2 = r2 - r1; // s517 sub + r6 = r5 * r7 + r6; // s518 mad + r2 = r2 ^ r7; // s519 xor + r1 = r1 | r5; // s520 or + r0 = r4 * r6 + r0; // s521 mad + r4 = r4 + r6 + select(0x2caeeca3u, 0xb1091e80u, ((sel >> 29u) & 1u) != 0u); // s522 add + r7 = r6 * r5 + r7; // s523 mad + r7 = r7 - r2; // s524 sub + r0 = r0 * r7; // s525 mul + r0 = r0 ^ r7; // s526 xor + r1 = mulhi(r1, r4); // s527 mulhi + r0 = rotr_var(r0, r5); // s528 rotr + r2 = r2 ^ simd_shuffle_xor(r7, (ushort)16); // s529 shfl + r2 = mulhi(r2, r3); // s530 mulhi + r1 = r1 | r4; // s531 or + r6 = r6 + r4 + select(0xbe9e1eb0u, 0xbda312aeu, ((sel >> 13u) & 1u) != 0u); // s532 add + r7 = r7 + r2 + select(0xbe5d93a3u, 0x1ec16229u, ((sel >> 6u) & 1u) != 0u); // s533 add + r0 = r6 * r4 + r0; // s534 mad + r0 = r0 + r5 + select(0x5e23583bu, 0x500828bcu, ((sel >> 23u) & 1u) != 0u); // s535 add + r6 = r5 * r0 + r6; // s536 mad + r2 = r2 ^ r4; // s537 xor + r6 = r3 * r5 + r6; // s538 mad + r6 = r6 + r4 + select(0x43c32138u, 0x852321dcu, ((sel >> 3u) & 1u) != 0u); // s539 add + r2 = r2 + r5 + select(0xaff69493u, 0x44e6ae63u, ((sel >> 7u) & 1u) != 0u); // s540 add + r3 = mulhi(r3, r5); // s541 mulhi + r1 = r1 + r7 + select(0xc5de29efu, 0x909712feu, ((sel >> 5u) & 1u) != 0u); // s542 add + r1 = r3 * r2 + r1; // s543 mad + r1 = r1 + r3 + select(0x1e20e084u, 0xfb7b42b9u, ((sel >> 11u) & 1u) != 0u); // s544 add + r4 = r4 ^ simd_shuffle_xor(r5, (ushort)4); // s545 shfl + r6 = r6 + r1 + select(0x9370db38u, 0x6e036dd4u, ((sel >> 10u) & 1u) != 0u); // s546 add + r4 = r4 ^ r6; // s547 xor + r5 = r5 ^ simd_shuffle_xor(r3, (ushort)8); // s548 shfl + r3 = r3 ^ simd_shuffle_xor(r5, (ushort)16); // s549 shfl + r1 = rotr_var(r1, r7); // s550 rotr + r0 = r3 * r2 + r0; // s551 mad + r7 = mulhi(r7, r4); // s552 mulhi + r0 = r0 + r4 + select(0xbf2488f6u, 0xd3c9174du, ((sel >> 13u) & 1u) != 0u); // s553 add + r1 = rotl_imm(r1, 1u); // s554 rotl + r7 = rotr_var(r7, r3); // s555 rotr + r7 = rotr_var(r7, r3); // s556 rotr + r6 = r2 * r0 + r6; // s557 mad + r6 = r6 ^ r1; // s558 xor + r5 = r5 ^ simd_shuffle_xor(r1, (ushort)2); // s559 shfl + r5 = r5 ^ r3; // s560 xor + r5 = r5 * r1; // s561 mul + r3 = rotl_imm(r3, 31u); // s562 rotl + r6 = rotr_var(r6, r2); // s563 rotr + r7 = r7 | r2; // s564 or + r6 = rotr_var(r6, r0); // s565 rotr + r2 = r2 * r0; // s566 mul + r4 = r4 ^ simd_shuffle_xor(r5, (ushort)2); // s567 shfl + r3 = r3 * r0; // s568 mul + r4 = r4 + r2 + select(0xd9160c83u, 0xa3149efau, ((sel >> 9u) & 1u) != 0u); // s569 add + r4 = mulhi(r4, r2); // s570 mulhi + r3 = r3 + r0 + select(0x3bdc971cu, 0x9cab407bu, ((sel >> 10u) & 1u) != 0u); // s571 add + r1 = r1 ^ simd_shuffle_xor(r2, (ushort)16); // s572 shfl + r2 = r2 ^ simd_shuffle_xor(r5, (ushort)4); // s573 shfl + r2 = r2 ^ simd_shuffle_xor(r3, (ushort)8); // s574 shfl + r0 = r0 ^ r7; // s575 xor + r0 = r0 + r5 + select(0x17979608u, 0x747b0838u, ((sel >> 27u) & 1u) != 0u); // s576 add + r0 = r0 ^ r4; // s577 xor + r6 = r6 - r1; // s578 sub + r4 = rotr_var(r4, r2); // s579 rotr + r2 = r2 ^ r3; // s580 xor + r6 = r7 * r2 + r6; // s581 mad + r5 = r5 + r2 + select(0x1c10ec5cu, 0x02246c0cu, ((sel >> 7u) & 1u) != 0u); // s582 add + r3 = mulhi(r3, r6); // s583 mulhi + r2 = r2 ^ r5; // s584 xor + r6 = rotl_imm(r6, 24u); // s585 rotl + r3 = r3 ^ simd_shuffle_xor(r5, (ushort)8); // s586 shfl + r1 = r2 * r6 + r1; // s587 mad + r3 = r3 + r7 + select(0x88758873u, 0xbea44bd0u, ((sel >> 21u) & 1u) != 0u); // s588 add + r1 = rotl_imm(r1, 30u); // s589 rotl + r7 = r7 * r1; // s590 mul + r3 = r3 + r6 + select(0xf436bb64u, 0x8e0eb890u, ((sel >> 10u) & 1u) != 0u); // s591 add + r7 = r6 * r1 + r7; // s592 mad + r0 = r3 * r5 + r0; // s593 mad + r5 = rotr_var(r5, r4); // s594 rotr + r4 = r4 | r0; // s595 or + r6 = r3 * r0 + r6; // s596 mad + r2 = r2 + r1 + select(0xb465e47eu, 0x29b853b3u, ((sel >> 31u) & 1u) != 0u); // s597 add + r1 = r1 ^ simd_shuffle_xor(r7, (ushort)16); // s598 shfl + r4 = r4 ^ simd_shuffle_xor(r0, (ushort)4); // s599 shfl + r6 = r2 * r0 + r6; // s600 mad + r5 = mulhi(r5, r0); // s601 mulhi + r6 = r6 * r7; // s602 mul + r4 = r4 | r7; // s603 or + r7 = r7 - r0; // s604 sub + r7 = rotr_var(r7, r4); // s605 rotr + r4 = r0 * r3 + r4; // s606 mad + r4 = mulhi(r4, r3); // s607 mulhi + r0 = r0 + r1 + select(0x22ce199du, 0xb7536963u, ((sel >> 28u) & 1u) != 0u); // s608 add + r2 = r2 - r5; // s609 sub + r2 = r2 ^ r0; // s610 xor + r5 = r5 * r4; // s611 mul + r3 = rotl_imm(r3, 25u); // s612 rotl + r7 = rotl_imm(r7, 13u); // s613 rotl + r4 = r4 * r7; // s614 mul + r5 = r4 * r2 + r5; // s615 mad + r0 = r0 ^ r5; // s616 xor + r7 = r5 * r4 + r7; // s617 mad + r6 = r6 - r4; // s618 sub + r3 = r3 * r4; // s619 mul + r1 = rotl_imm(r1, 24u); // s620 rotl + r1 = r1 ^ r2; // s621 xor + r4 = r4 | r3; // s622 or + r7 = r7 * r2; // s623 mul + r6 = r6 + r1 + select(0x2dbf6ed0u, 0xe37b1e20u, ((sel >> 20u) & 1u) != 0u); // s624 add + r4 = r4 ^ r5; // s625 xor + r4 = r6 * r2 + r4; // s626 mad + r1 = r1 ^ r6; // s627 xor + r6 = r6 + r3 + select(0x9dc2b9d0u, 0xf5a2a9f7u, ((sel >> 12u) & 1u) != 0u); // s628 add + r7 = r7 - r5; // s629 sub + r1 = mulhi(r1, r7); // s630 mulhi + r1 = rotr_var(r1, r3); // s631 rotr + r4 = r4 | r6; // s632 or + r2 = r2 + r5 + select(0x9c1fba1bu, 0x982bfc08u, ((sel >> 24u) & 1u) != 0u); // s633 add + r6 = r6 * r5; // s634 mul + r7 = r2 * r3 + r7; // s635 mad + r7 = mulhi(r7, r4); // s636 mulhi + r5 = r5 ^ r0; // s637 xor + r0 = r0 * r1; // s638 mul + r4 = r4 ^ r6; // s639 xor + r6 = r6 - r4; // s640 sub + r6 = mulhi(r6, r4); // s641 mulhi + r4 = r4 - r0; // s642 sub + r7 = r7 - r5; // s643 sub + r3 = r0 * r7 + r3; // s644 mad + r3 = r3 | r5; // s645 or + r0 = r0 - r4; // s646 sub + r7 = r7 | r5; // s647 or + r7 = rotl_imm(r7, 1u); // s648 rotl + r5 = r5 + r6 + select(0x9f5e0d19u, 0x6e5d517fu, ((sel >> 31u) & 1u) != 0u); // s649 add + r1 = r1 | r2; // s650 or + r3 = rotl_imm(r3, 29u); // s651 rotl + r2 = r2 + r4 + select(0xb53f6e74u, 0x30faf9c6u, ((sel >> 2u) & 1u) != 0u); // s652 add + r0 = rotl_imm(r0, 21u); // s653 rotl + r1 = r1 ^ r3; // s654 xor + r4 = r7 * r2 + r4; // s655 mad + r4 = r4 - r6; // s656 sub + r4 = r4 * r6; // s657 mul + r2 = r2 ^ simd_shuffle_xor(r1, (ushort)4); // s658 shfl + r7 = rotl_imm(r7, 31u); // s659 rotl + r4 = r4 ^ r6; // s660 xor + r1 = r1 - r3; // s661 sub + r3 = r3 * r6; // s662 mul + r5 = r5 * r3; // s663 mul + r7 = r7 + r2 + select(0x016e0094u, 0x8941d2e7u, ((sel >> 21u) & 1u) != 0u); // s664 add + r1 = r1 ^ r2; // s665 xor + r1 = r1 - r0; // s666 sub + r4 = r4 ^ r7; // s667 xor + r7 = r7 ^ simd_shuffle_xor(r3, (ushort)1); // s668 shfl + r1 = rotr_var(r1, r4); // s669 rotr + r2 = r2 + r3 + select(0x9af12ca6u, 0x15289435u, ((sel >> 14u) & 1u) != 0u); // s670 add + r2 = rotr_var(r2, r4); // s671 rotr + r4 = r6 * r7 + r4; // s672 mad + r2 = r2 ^ simd_shuffle_xor(r1, (ushort)4); // s673 shfl + r6 = r4 * r2 + r6; // s674 mad + r2 = r4 * r6 + r2; // s675 mad + r3 = r3 ^ simd_shuffle_xor(r1, (ushort)16); // s676 shfl + r1 = rotr_var(r1, r0); // s677 rotr + r0 = r0 - r2; // s678 sub + r5 = r5 ^ simd_shuffle_xor(r1, (ushort)16); // s679 shfl + r1 = r1 ^ r0; // s680 xor + r1 = r1 ^ simd_shuffle_xor(r2, (ushort)4); // s681 shfl + r0 = r0 ^ simd_shuffle_xor(r3, (ushort)8); // s682 shfl + r2 = r3 * r3 + r2; // s683 mad + r4 = r4 - r6; // s684 sub + r5 = r5 ^ r3; // s685 xor + r2 = r2 - r5; // s686 sub + r4 = r4 - r5; // s687 sub + r5 = r4 * r7 + r5; // s688 mad + r6 = r6 * r7; // s689 mul + r1 = r1 * r5; // s690 mul + r4 = rotr_var(r4, r3); // s691 rotr + r2 = r2 ^ r4; // s692 xor + r0 = rotl_imm(r0, 2u); // s693 rotl + r5 = r5 + r2 + select(0x4fc762c9u, 0x49801084u, ((sel >> 23u) & 1u) != 0u); // s694 add + r0 = r0 + r4 + select(0x626c00f5u, 0x5f403cd5u, ((sel >> 14u) & 1u) != 0u); // s695 add + r6 = rotl_imm(r6, 25u); // s696 rotl + r3 = r3 ^ r7; // s697 xor + r0 = r0 * r2; // s698 mul + r5 = rotr_var(r5, r1); // s699 rotr + r3 = r3 ^ r7; // s700 xor + r4 = r4 | r3; // s701 or + r7 = r7 * r3; // s702 mul + r4 = rotl_imm(r4, 24u); // s703 rotl + r5 = r5 + r4 + select(0xc08bb414u, 0xad5e1851u, ((sel >> 17u) & 1u) != 0u); // s704 add + r0 = r6 * r5 + r0; // s705 mad + r4 = mulhi(r4, r1); // s706 mulhi + r4 = rotr_var(r4, r3); // s707 rotr + r3 = rotr_var(r3, r6); // s708 rotr + r6 = r6 ^ simd_shuffle_xor(r7, (ushort)16); // s709 shfl + r3 = r2 * r6 + r3; // s710 mad + r1 = r1 * r4; // s711 mul + r3 = r3 + r5 + select(0xdc55338fu, 0x407f7c4du, ((sel >> 13u) & 1u) != 0u); // s712 add + r6 = r6 ^ simd_shuffle_xor(r7, (ushort)2); // s713 shfl + r1 = r1 ^ r0; // s714 xor + r7 = r1 * r1 + r7; // s715 mad + r4 = r4 | r0; // s716 or + r6 = r6 * r4; // s717 mul + r0 = r0 - r5; // s718 sub + r1 = r1 ^ r4; // s719 xor + r4 = mulhi(r4, r6); // s720 mulhi + r1 = r1 + r0 + select(0xb2ce569eu, 0xc2093fcau, ((sel >> 13u) & 1u) != 0u); // s721 add + r4 = mulhi(r4, r2); // s722 mulhi + r6 = r6 ^ simd_shuffle_xor(r1, (ushort)16); // s723 shfl + r5 = r3 * r0 + r5; // s724 mad + r5 = mulhi(r5, r0); // s725 mulhi + r2 = rotr_var(r2, r5); // s726 rotr + r5 = r5 + r0 + select(0x4e8aaad5u, 0x48cdf1c1u, ((sel >> 20u) & 1u) != 0u); // s727 add + r1 = r1 * r0; // s728 mul + r3 = r3 ^ simd_shuffle_xor(r0, (ushort)1); // s729 shfl + r4 = r4 * r6; // s730 mul + r4 = r4 - r6; // s731 sub + r4 = r4 ^ r2; // s732 xor + r5 = r5 * r6; // s733 mul + r7 = rotr_var(r7, r3); // s734 rotr + r1 = r1 ^ simd_shuffle_xor(r5, (ushort)1); // s735 shfl + r1 = mulhi(r1, r0); // s736 mulhi + r2 = r2 * r6; // s737 mul + r5 = rotl_imm(r5, 27u); // s738 rotl + r2 = mulhi(r2, r3); // s739 mulhi + r5 = r3 * r5 + r5; // s740 mad + r2 = rotl_imm(r2, 11u); // s741 rotl + r6 = r6 | r2; // s742 or + r2 = r2 ^ r3; // s743 xor + r3 = r3 * r1; // s744 mul + r4 = mulhi(r4, r2); // s745 mulhi + r5 = r5 ^ r6; // s746 xor + r6 = r6 + r7 + select(0x78fc162du, 0x0d6b844eu, ((sel >> 11u) & 1u) != 0u); // s747 add + r1 = rotl_imm(r1, 27u); // s748 rotl + r4 = rotr_var(r4, r1); // s749 rotr + r5 = r5 ^ r7; // s750 xor + r4 = rotr_var(r4, r3); // s751 rotr + r5 = r5 * r2; // s752 mul + r1 = r6 * r7 + r1; // s753 mad + r0 = r0 ^ r1; // s754 xor + r7 = r7 - r1; // s755 sub + r0 = r0 + r4 + select(0x68aab88bu, 0xb74ac71eu, ((sel >> 5u) & 1u) != 0u); // s756 add + r7 = r7 + r5 + select(0xba5c123au, 0xf81f5b66u, ((sel >> 0u) & 1u) != 0u); // s757 add + r0 = r7 * r2 + r0; // s758 mad + r1 = r1 | r0; // s759 or + r4 = mulhi(r4, r6); // s760 mulhi + r0 = mulhi(r0, r7); // s761 mulhi + r3 = rotr_var(r3, r4); // s762 rotr + r3 = rotl_imm(r3, 30u); // s763 rotl + r6 = r6 * r2; // s764 mul + r6 = r6 ^ r4; // s765 xor + r3 = r3 + r4 + select(0x6eb1d82au, 0x96dabea6u, ((sel >> 0u) & 1u) != 0u); // s766 add + r0 = r0 ^ simd_shuffle_xor(r2, (ushort)1); // s767 shfl + r3 = rotl_imm(r3, 8u); // s768 rotl + r7 = r7 * r4; // s769 mul + r6 = r1 * r2 + r6; // s770 mad + r2 = r2 ^ r7; // s771 xor + r6 = r6 * r0; // s772 mul + r2 = r2 - r1; // s773 sub + r1 = r0 * r1 + r1; // s774 mad + r5 = mulhi(r5, r7); // s775 mulhi + r0 = rotr_var(r0, r4); // s776 rotr + r6 = r6 ^ r0; // s777 xor + r4 = mulhi(r4, r7); // s778 mulhi + r1 = r3 * r0 + r1; // s779 mad + r6 = r6 + r4 + select(0x11d7b79au, 0x903f3f77u, ((sel >> 2u) & 1u) != 0u); // s780 add + r4 = r4 ^ r7; // s781 xor + r1 = r1 + r2 + select(0x1791eaddu, 0x2ca81d8du, ((sel >> 14u) & 1u) != 0u); // s782 add + r2 = rotr_var(r2, r1); // s783 rotr + r4 = r4 * r6; // s784 mul + r1 = r1 ^ r6; // s785 xor + r4 = r4 - r0; // s786 sub + r3 = r3 ^ r4; // s787 xor + r4 = r4 * r1; // s788 mul + r4 = r6 * r7 + r4; // s789 mad + r5 = r5 - r0; // s790 sub + r2 = r2 * r0; // s791 mul + r7 = rotl_imm(r7, 12u); // s792 rotl + r2 = r7 * r3 + r2; // s793 mad + r1 = r4 * r4 + r1; // s794 mad + r6 = r6 + r4 + select(0xc08797bbu, 0xf66fad29u, ((sel >> 15u) & 1u) != 0u); // s795 add + r1 = r1 - r4; // s796 sub + r5 = r5 * r2; // s797 mul + r5 = r5 ^ r2; // s798 xor + r0 = r0 * r1; // s799 mul + r6 = r6 + r4 + select(0x6d4a6371u, 0x2d82a681u, ((sel >> 13u) & 1u) != 0u); // s800 add + r1 = r6 * r1 + r1; // s801 mad + r0 = r0 - r2; // s802 sub + r6 = r6 ^ r2; // s803 xor + r7 = rotl_imm(r7, 24u); // s804 rotl + r6 = r6 ^ r7; // s805 xor + r7 = r7 | r0; // s806 or + r0 = rotl_imm(r0, 5u); // s807 rotl + r1 = r1 ^ simd_shuffle_xor(r2, (ushort)2); // s808 shfl + r4 = r1 * r5 + r4; // s809 mad + r0 = r0 + r2 + select(0x0092eb62u, 0x63e62197u, ((sel >> 14u) & 1u) != 0u); // s810 add + r5 = r5 - r3; // s811 sub + r2 = r1 * r5 + r2; // s812 mad + r6 = r6 ^ simd_shuffle_xor(r0, (ushort)16); // s813 shfl + r7 = r5 * r1 + r7; // s814 mad + r0 = mulhi(r0, r7); // s815 mulhi + r2 = r2 | r1; // s816 or + r7 = mulhi(r7, r3); // s817 mulhi + r2 = r2 ^ r4; // s818 xor + r4 = r4 + r3 + select(0xbb69174fu, 0x27d94f57u, ((sel >> 0u) & 1u) != 0u); // s819 add + r5 = r5 + r3 + select(0xda6759f2u, 0x82285691u, ((sel >> 1u) & 1u) != 0u); // s820 add + r1 = r1 + r3 + select(0x9ad4b47fu, 0xe50565d8u, ((sel >> 31u) & 1u) != 0u); // s821 add + r5 = rotl_imm(r5, 6u); // s822 rotl + r3 = r3 - r0; // s823 sub + r6 = rotl_imm(r6, 12u); // s824 rotl + r4 = r4 | r5; // s825 or + r3 = r3 ^ r2; // s826 xor + r4 = r4 + r0 + select(0xca1e80fbu, 0xffcab83au, ((sel >> 26u) & 1u) != 0u); // s827 add + r3 = r3 | r7; // s828 or + r1 = r5 * r7 + r1; // s829 mad + r6 = r6 ^ simd_shuffle_xor(r0, (ushort)16); // s830 shfl + r1 = r1 - r0; // s831 sub + r0 = rotr_var(r0, r2); // s832 rotr + r1 = mulhi(r1, r0); // s833 mulhi + r6 = mulhi(r6, r4); // s834 mulhi + r6 = rotl_imm(r6, 2u); // s835 rotl + r4 = r4 | r6; // s836 or + r6 = rotl_imm(r6, 23u); // s837 rotl + r4 = r7 * r4 + r4; // s838 mad + r0 = r0 | r1; // s839 or + r5 = mulhi(r5, r3); // s840 mulhi + r7 = r4 * r6 + r7; // s841 mad + r1 = r1 + r4 + select(0xcfb90e90u, 0x1bc9f95du, ((sel >> 21u) & 1u) != 0u); // s842 add + r1 = r1 + r2 + select(0x0b4758b6u, 0xf9bd620fu, ((sel >> 18u) & 1u) != 0u); // s843 add + r2 = r2 ^ simd_shuffle_xor(r5, (ushort)16); // s844 shfl + r3 = r1 * r7 + r3; // s845 mad + r5 = r5 * r2; // s846 mul + r0 = rotl_imm(r0, 21u); // s847 rotl + r7 = r7 ^ r1; // s848 xor + r3 = r3 + r4 + select(0x41fdc15au, 0x697a4946u, ((sel >> 18u) & 1u) != 0u); // s849 add + r0 = r0 ^ simd_shuffle_xor(r5, (ushort)4); // s850 shfl + r1 = rotr_var(r1, r5); // s851 rotr + r5 = r5 | r6; // s852 or + r6 = r6 - r2; // s853 sub + r2 = r2 ^ r6; // s854 xor + r4 = r4 - r6; // s855 sub + r6 = r4 * r6 + r6; // s856 mad + r4 = r4 * r0; // s857 mul + r2 = r2 ^ simd_shuffle_xor(r1, (ushort)4); // s858 shfl + r3 = r3 * r4; // s859 mul + r3 = r1 * r7 + r3; // s860 mad + r3 = r3 ^ simd_shuffle_xor(r2, (ushort)2); // s861 shfl + r7 = r7 ^ simd_shuffle_xor(r4, (ushort)8); // s862 shfl + r0 = r2 * r2 + r0; // s863 mad + r6 = r6 ^ r0; // s864 xor + r6 = r6 + r2 + select(0x90656f74u, 0x7fedd7f3u, ((sel >> 2u) & 1u) != 0u); // s865 add + r3 = r3 ^ r2; // s866 xor + r1 = r1 | r4; // s867 or + r6 = r6 ^ simd_shuffle_xor(r7, (ushort)2); // s868 shfl + r1 = mulhi(r1, r0); // s869 mulhi + r3 = r3 ^ simd_shuffle_xor(r1, (ushort)4); // s870 shfl + r0 = r0 - r3; // s871 sub + r6 = r6 + r1 + select(0xa5c0b461u, 0xbe1b480au, ((sel >> 11u) & 1u) != 0u); // s872 add + r3 = r3 ^ simd_shuffle_xor(r6, (ushort)1); // s873 shfl + r5 = r5 ^ simd_shuffle_xor(r0, (ushort)1); // s874 shfl + r2 = mulhi(r2, r4); // s875 mulhi + r5 = r5 ^ simd_shuffle_xor(r7, (ushort)4); // s876 shfl + r5 = rotl_imm(r5, 14u); // s877 rotl + r2 = r2 ^ r7; // s878 xor + r7 = r7 ^ r0; // s879 xor + r0 = r0 * r2; // s880 mul + r4 = r4 * r2; // s881 mul + r7 = r7 * r6; // s882 mul + r4 = mulhi(r4, r5); // s883 mulhi + r0 = r0 - r4; // s884 sub + r0 = r0 ^ r5; // s885 xor + r6 = r6 * r5; // s886 mul + r1 = r1 + r5 + select(0xe806fcecu, 0x7007f98fu, ((sel >> 14u) & 1u) != 0u); // s887 add + r3 = r3 * r1; // s888 mul + r5 = r5 ^ r3; // s889 xor + r6 = r6 | r2; // s890 or + r1 = r1 * r2; // s891 mul + r5 = r5 + r7 + select(0x89a8551eu, 0xf3c87e02u, ((sel >> 3u) & 1u) != 0u); // s892 add + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)16); // s893 shfl + r1 = r1 + r3 + select(0xba1369dbu, 0xc315f5deu, ((sel >> 13u) & 1u) != 0u); // s894 add + r5 = r0 * r3 + r5; // s895 mad + r5 = rotr_var(r5, r2); // s896 rotr + r1 = r1 ^ r0; // s897 xor + r5 = r5 ^ r1; // s898 xor + r5 = rotr_var(r5, r1); // s899 rotr + r3 = r6 * r6 + r3; // s900 mad + r0 = rotl_imm(r0, 8u); // s901 rotl + r1 = r1 | r0; // s902 or + r1 = r1 + r2 + select(0x260e6848u, 0x1c355a71u, ((sel >> 3u) & 1u) != 0u); // s903 add + r7 = r7 ^ simd_shuffle_xor(r2, (ushort)16); // s904 shfl + r1 = mulhi(r1, r3); // s905 mulhi + r1 = rotr_var(r1, r4); // s906 rotr + r6 = r6 + r0 + select(0xa74fd2b1u, 0x0c74a1a8u, ((sel >> 8u) & 1u) != 0u); // s907 add + r6 = rotr_var(r6, r2); // s908 rotr + r4 = rotl_imm(r4, 12u); // s909 rotl + r5 = r5 + r3 + select(0xe5fb043eu, 0xa49b5d73u, ((sel >> 29u) & 1u) != 0u); // s910 add + r3 = r3 ^ r0; // s911 xor + r3 = rotr_var(r3, r4); // s912 rotr + r6 = rotr_var(r6, r0); // s913 rotr + r2 = r2 ^ r5; // s914 xor + r0 = r0 * r7; // s915 mul + r3 = r3 ^ r0; // s916 xor + r5 = r1 * r7 + r5; // s917 mad + r3 = r3 + r4 + select(0x264cb47bu, 0xeb76e56cu, ((sel >> 2u) & 1u) != 0u); // s918 add + r3 = mulhi(r3, r4); // s919 mulhi + r5 = r5 + r6 + select(0x418baa72u, 0x2aab9631u, ((sel >> 9u) & 1u) != 0u); // s920 add + r5 = mulhi(r5, r1); // s921 mulhi + r7 = r7 - r3; // s922 sub + r6 = r6 + r1 + select(0x3696a894u, 0x98e6b26du, ((sel >> 2u) & 1u) != 0u); // s923 add + r6 = r3 * r1 + r6; // s924 mad + r2 = r2 ^ simd_shuffle_xor(r1, (ushort)2); // s925 shfl + r6 = r6 ^ r1; // s926 xor + r4 = r4 ^ r3; // s927 xor + r0 = r0 + r4 + select(0x0468c062u, 0x142778eeu, ((sel >> 7u) & 1u) != 0u); // s928 add + r7 = r7 + r3 + select(0x0af82291u, 0x4eae212du, ((sel >> 29u) & 1u) != 0u); // s929 add + r4 = r4 ^ simd_shuffle_xor(r7, (ushort)16); // s930 shfl + r7 = r7 + r2 + select(0x17de5e29u, 0x8d2a8b36u, ((sel >> 20u) & 1u) != 0u); // s931 add + r5 = r5 + r1 + select(0x686794a8u, 0xe2d2d7d5u, ((sel >> 6u) & 1u) != 0u); // s932 add + r0 = mulhi(r0, r3); // s933 mulhi + r4 = r4 + r0 + select(0x66278068u, 0xe3c3c6f9u, ((sel >> 10u) & 1u) != 0u); // s934 add + r6 = rotl_imm(r6, 22u); // s935 rotl + r0 = r0 | r2; // s936 or + r4 = r4 * r3; // s937 mul + r3 = r3 | r6; // s938 or + r7 = rotl_imm(r7, 28u); // s939 rotl + r0 = r0 + r6 + select(0xc2d02ca6u, 0xc2296063u, ((sel >> 20u) & 1u) != 0u); // s940 add + r1 = r1 + r5 + select(0x0b3c00e0u, 0xef1ca415u, ((sel >> 14u) & 1u) != 0u); // s941 add + r2 = r2 - r6; // s942 sub + r6 = r6 | r3; // s943 or + r0 = rotl_imm(r0, 2u); // s944 rotl + r2 = r2 * r1; // s945 mul + r0 = r0 + r6 + select(0x11224846u, 0x06a1321au, ((sel >> 1u) & 1u) != 0u); // s946 add + r3 = r3 * r6; // s947 mul + r5 = r5 - r2; // s948 sub + r5 = r5 + r4 + select(0x461c43d4u, 0x5d3e225cu, ((sel >> 5u) & 1u) != 0u); // s949 add + r2 = r2 ^ simd_shuffle_xor(r1, (ushort)16); // s950 shfl + r7 = r0 * r0 + r7; // s951 mad + r6 = rotr_var(r6, r4); // s952 rotr + r1 = r1 + r0 + select(0xd5eed39fu, 0xbb84f628u, ((sel >> 30u) & 1u) != 0u); // s953 add + r4 = rotl_imm(r4, 31u); // s954 rotl + r1 = r1 ^ simd_shuffle_xor(r2, (ushort)16); // s955 shfl + r2 = r2 - r6; // s956 sub + r4 = r4 ^ r2; // s957 xor + r0 = r0 ^ r2; // s958 xor + r1 = r1 + r0 + select(0x519d72f7u, 0x374c0426u, ((sel >> 28u) & 1u) != 0u); // s959 add + r5 = r5 * r4; // s960 mul + r5 = r5 - r7; // s961 sub + r2 = r2 ^ r6; // s962 xor + r4 = r4 ^ r1; // s963 xor + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)16); // s964 shfl + r7 = mulhi(r7, r3); // s965 mulhi + r4 = rotl_imm(r4, 12u); // s966 rotl + r4 = r4 + r6 + select(0x151dae18u, 0x03b88592u, ((sel >> 26u) & 1u) != 0u); // s967 add + r1 = r1 ^ simd_shuffle_xor(r3, (ushort)4); // s968 shfl + r3 = r3 ^ simd_shuffle_xor(r6, (ushort)8); // s969 shfl + r2 = r2 ^ r7; // s970 xor + r5 = r3 * r4 + r5; // s971 mad + r0 = r0 ^ r3; // s972 xor + r2 = r2 ^ r5; // s973 xor + r1 = r1 ^ simd_shuffle_xor(r0, (ushort)4); // s974 shfl + r5 = r1 * r4 + r5; // s975 mad + r2 = rotl_imm(r2, 19u); // s976 rotl + r1 = r1 - r4; // s977 sub + r5 = rotr_var(r5, r4); // s978 rotr + r2 = r2 ^ simd_shuffle_xor(r1, (ushort)16); // s979 shfl + r6 = r6 + r7 + select(0x16220e61u, 0x1fdee45eu, ((sel >> 28u) & 1u) != 0u); // s980 add + r4 = rotr_var(r4, r6); // s981 rotr + r6 = mulhi(r6, r3); // s982 mulhi + r5 = rotl_imm(r5, 17u); // s983 rotl + r2 = r7 * r1 + r2; // s984 mad + r4 = r4 ^ simd_shuffle_xor(r1, (ushort)8); // s985 shfl + r3 = r3 ^ r1; // s986 xor + r4 = r4 + r0 + select(0x6cd6b697u, 0x44adc457u, ((sel >> 27u) & 1u) != 0u); // s987 add + r1 = r1 * r5; // s988 mul + r4 = r4 + r2 + select(0x1103d2d2u, 0x0a06a223u, ((sel >> 2u) & 1u) != 0u); // s989 add + r4 = r4 * r1; // s990 mul + r4 = r5 * r1 + r4; // s991 mad + r3 = r3 ^ simd_shuffle_xor(r6, (ushort)1); // s992 shfl + r1 = r1 - r3; // s993 sub + r4 = r7 * r5 + r4; // s994 mad + r1 = mulhi(r1, r2); // s995 mulhi + r2 = r1 * r0 + r2; // s996 mad + r3 = rotl_imm(r3, 31u); // s997 rotl + r4 = r4 - r3; // s998 sub + r5 = rotr_var(r5, r3); // s999 rotr + r4 = r4 ^ simd_shuffle_xor(r0, (ushort)4); // s1000 shfl + r2 = r2 - r5; // s1001 sub + r3 = r4 * r4 + r3; // s1002 mad + r7 = r5 * r1 + r7; // s1003 mad + r7 = r7 + r4 + select(0xa9c9d8a9u, 0x0044887fu, ((sel >> 29u) & 1u) != 0u); // s1004 add + r4 = mulhi(r4, r0); // s1005 mulhi + r4 = rotl_imm(r4, 21u); // s1006 rotl + r3 = r3 * r1; // s1007 mul + r1 = r1 ^ simd_shuffle_xor(r5, (ushort)2); // s1008 shfl + r0 = mulhi(r0, r6); // s1009 mulhi + r0 = r0 ^ r3; // s1010 xor + r5 = r5 | r4; // s1011 or + r1 = r1 ^ simd_shuffle_xor(r5, (ushort)4); // s1012 shfl + r2 = r2 + r4 + select(0xfa1574e3u, 0x6b70e2c7u, ((sel >> 4u) & 1u) != 0u); // s1013 add + r5 = rotr_var(r5, r7); // s1014 rotr + r0 = rotr_var(r0, r7); // s1015 rotr + r5 = r5 - r7; // s1016 sub + r4 = r4 ^ simd_shuffle_xor(r1, (ushort)16); // s1017 shfl + r6 = mulhi(r6, r7); // s1018 mulhi + r0 = rotr_var(r0, r1); // s1019 rotr + r2 = r2 ^ r0; // s1020 xor + r4 = r5 * r1 + r4; // s1021 mad + r6 = r6 | r2; // s1022 or + r3 = r3 ^ r0; // s1023 xor + } + } + uint lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((ulong)hi << 32) | (ulong)lo; +} diff --git a/proto-cuda/packs-ca3-shadow/sh1024x3/vectors.h b/proto-cuda/packs-ca3-shadow/sh1024x3/vectors.h new file mode 100644 index 000000000..02862f194 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh1024x3/vectors.h @@ -0,0 +1,57 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Expected outputs: igneum-pow (Rust) CPU interpreter, generator v2, memory-hard dataset +#pragma once +#ifdef __cplusplus +#include +#else +#include +#endif + +#define IGNEUM_VEC_WARPS 3 +static const uint32_t IGNEUM_VEC_BASE[IGNEUM_VEC_WARPS] = { 0u, 4096u, 1000000u }; +static const uint64_t IGNEUM_VEC_OUT[IGNEUM_VEC_WARPS][32] = { + { // base nonce 0 + 0x747f675a3e246779ull, 0x3b7b243899b0630full, 0x09b218fdb330dfe4ull, 0x815881ff26c2ad97ull, 0xcea3325e3467ae16ull, 0xcdb1e7c8315fcf5cull, 0x2a869dbf61a3cc0dull, 0xfb63910ab6c1b391ull, + 0x9a80515f55fd00b0ull, 0x379c4f2c8677cc52ull, 0x855916abf975255dull, 0x02c7e2ec1b7bb721ull, 0xd5d77c714c49d776ull, 0x05a97f93e03bca0aull, 0x2e622e72a5ebe6c4ull, 0x797240828dedbe8full, + 0x3055cd022b2d02dfull, 0xbf5a2bb44435048cull, 0xb34a8a307485687aull, 0xe9e7bcad98410300ull, 0x6550ae6ffd645f8bull, 0x0ebf6803ef855f01ull, 0xba5ee1c0150057a1ull, 0xa941029be202ad09ull, + 0x1ce9748a96ef1e52ull, 0xb94f9bfb9456af54ull, 0x6790d5d0e150fa80ull, 0xbd5acfd4c895f294ull, 0x854ec3ae328a2356ull, 0x42663c674dceb3b7ull, 0xa1ec4b65fc185d23ull, 0xeb2d57676a7403d2ull + }, + { // base nonce 4096 + 0x5e67a3767d022ea9ull, 0xe632ab080c255629ull, 0xd5faa7887d8dd060ull, 0x1be4efe63fee6b31ull, 0x9853b48cd230473cull, 0xb7518eb50febd9fbull, 0x818574269e928cddull, 0x8c8d3235fef8abe3ull, + 0x721cebf4a1abc8b9ull, 0x3401396bf9a05f89ull, 0x73950d7ebcc401abull, 0x5e7d538b6f66a56dull, 0xad8dd338954b0ef4ull, 0xfe44537374e1b230ull, 0x1d2cb8f5d8eb0aaeull, 0xed5e84bdc4323359ull, + 0x3e854f1684be0e03ull, 0x0aaba78e40d9ae05ull, 0x993b011aaca4ed0dull, 0x326daeeb4fb66133ull, 0xdc58784f0070ae86ull, 0x3c5283ea978b04ecull, 0x5e0dfeaae08e60d6ull, 0x6cbb111502716191ull, + 0x4e03aa98da68b701ull, 0xca338b880c4094aaull, 0x440da9a12a281e9dull, 0xaa8d7bc6e2d605c9ull, 0x1bd954a3e2888a07ull, 0x0595e720f5773e7aull, 0x2d881b4257faad0cull, 0xa2408eacf140b697ull + }, + { // base nonce 1000000 + 0x71f0f56dc7c87afbull, 0xdba8a00051ee0c0dull, 0xd77432d0f7c4a528ull, 0xd7e34a1297d6238cull, 0xf380492d6ef03c7full, 0x685e7d06d22aa640ull, 0x6d6278b0933d8900ull, 0xb57c46a08d73078full, + 0xa0122a5ade2bd287ull, 0x021ca9ecc33a14fbull, 0x57fc40164dfda1f0ull, 0xb5574e1a1a27c5f9ull, 0x2e35a9b3eba63d34ull, 0xa1abe6745067d96bull, 0xf3ec38b0932a91f3ull, 0x15cc12195591a0e5ull, + 0x369cea21f9f2c65eull, 0x3a7187650b85b341ull, 0xa7e37b799dca283bull, 0x94e75d165a710881ull, 0x09dd15dc13859257ull, 0x01416f04012b3504ull, 0xcb38317f23258284ull, 0xbd3f1cc73f88926cull, + 0x832f757a700a2b5aull, 0x169ad0ad523a4e71ull, 0x80432f3862428dcdull, 0x4ba8b5b19a4b8e0eull, 0x03472af8bcec773cull, 0x13f795a9ac8cc5bcull, 0x0c8431b4b846d642ull, 0x3c6ec17e1d80e9f6ull + } +}; + +// Dataset self-test: dataset[0..15] and dataset[IGNEUM_MASK] (268435455). +static const uint32_t IGNEUM_DS_HEAD[16] = { + 0xfdad4319u, 0x1a7b68e1u, 0xde6db608u, 0x13d73892u, 0xd17f447au, 0xb2221ccfu, 0x9db004bdu, 0x57d7d367u, + 0xdbc4cf34u, 0x697c009au, 0xc43af1d4u, 0x97f12b2eu, 0x74c37cd0u, 0xc651ea15u, 0x665a6d29u, 0x22330a2du +}; +static const uint32_t IGNEUM_DS_LAST_INDEX = 268435455u; +static const uint32_t IGNEUM_DS_LAST = 0xa83e7aa6u; +// 64 sampled dataset words (index, value) computed on the Mac. +#define IGNEUM_DS_SAMPLES 64 +static const uint32_t IGNEUM_DS_SAMPLE_INDEX[IGNEUM_DS_SAMPLES] = { + 59471966u, 217795994u, 208353206u, 42483309u, 172547758u, 148076330u, 183853158u, 214389424u, 267488061u, 169781097u, 184093494u, 153880993u, 84977930u, 46426879u, 3093825u, 225364072u, 44593546u, 260713159u, 168250303u, 52384140u, 223401610u, 45554030u, 95410555u, 175039924u, 79171087u, 267580473u, 24168642u, 37981670u, 171551130u, 195559979u, 204611762u, 140997658u, 138925853u, 86637313u, 20736778u, 219665210u, 160430336u, 264654675u, 8013395u, 228945585u, 213884386u, 104419827u, 44185464u, 142737231u, 99284897u, 132475900u, 61861762u, 132056166u, 262388043u, 91878046u, 117353561u, 124768597u, 71352993u, 190698941u, 46055428u, 55281366u, 165145231u, 106810753u, 171985651u, 232085256u, 159510492u, 40072060u, 209107596u, 39023794u +}; +static const uint32_t IGNEUM_DS_SAMPLE_VALUE[IGNEUM_DS_SAMPLES] = { + 0x3230bc7bu, 0x7fbfe2c9u, 0xb2690991u, 0x1745c7c5u, 0x0ab0ccafu, 0x1bf87d6bu, 0x160139fdu, 0x719817acu, 0x0155df4bu, 0xbe1e86c3u, 0x680bcd6cu, 0x79c3dc6cu, 0x181e7e5fu, 0x0713a109u, 0xc705dd9fu, 0x3933b7a8u, 0xdd1c0431u, 0x50522b30u, 0xa0020b38u, 0xbff39e96u, 0x21b67e18u, 0x740f8db3u, 0x2baba568u, 0x2c9bef83u, 0x0ad9b671u, 0xc4327869u, 0x7b4fd7d0u, 0x2c29965fu, 0xec56f15fu, 0x61111746u, 0x303a1d6eu, 0xbddcfd1au, 0xf829a355u, 0x6d5df2a9u, 0x01ab8e44u, 0x06d13507u, 0xda8dcfc6u, 0x01a703e1u, 0xafe7d2c1u, 0xc091c3a2u, 0xac1814feu, 0x6e6ff62au, 0x8fdf01bau, 0xdd3f7159u, 0xdfa0d75cu, 0x26684c35u, 0x7f441e63u, 0x88df2570u, 0x8aa4d5ebu, 0xcc816c05u, 0x434df890u, 0xcd392ad6u, 0x1ab4cb63u, 0x595926fau, 0x7cd76b41u, 0x20cb95c4u, 0x13cf823fu, 0xf9daf901u, 0xff9af40au, 0x2c7dfa51u, 0x871206dbu, 0x938c116cu, 0xb64bf199u, 0x5751f874u +}; +// Cache self-test (memory-hard mode): cache[0..15], the last 16 words, and FNV-1a 64 over all 2^26 words. +static const uint32_t IGNEUM_CACHE_HEAD[16] = { + 0x355a86d2u, 0x7957db1cu, 0xd21772afu, 0x6fc1e09bu, 0xd55ce61du, 0x6e6a278bu, 0xd3f543ceu, 0x223d8e82u, + 0x143ab337u, 0x2e9f05bdu, 0x2eb389bfu, 0x0c6e449eu, 0x5cfa4222u, 0xba6560feu, 0x8e3e1aa4u, 0xdbcc1d53u +}; +static const uint32_t IGNEUM_CACHE_LAST[16] = { + 0x41190d91u, 0xbd277957u, 0x22ddbb49u, 0x6986f207u, 0xdf69a4d6u, 0x26401a3au, 0x818230fbu, 0xc417122du, + 0x3597b211u, 0xb553ce55u, 0xcf39cc0du, 0x3b7fc43au, 0x3fd43b00u, 0x67e1c80eu, 0xffa7ea7du, 0xca2960abu +}; +static const uint64_t IGNEUM_CACHE_FNV64 = 0x48c4f5bf24166b2eull; diff --git a/proto-cuda/packs-ca3-shadow/sh1024x3/vectors.json b/proto-cuda/packs-ca3-shadow/sh1024x3/vectors.json new file mode 100644 index 000000000..2140a29b3 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh1024x3/vectors.json @@ -0,0 +1,36 @@ +{ + "seed": "igneum-genesis", + "day": "2026-10-03", + "dataset_mode": "memory-hard", + "dataset_log2_words": 28, + "mask": "0x0fffffff", + "lanes": 32, + "source": "igneum-pow (Rust) CPU interpreter, generator v2, memory-hard dataset", + "warps": [ + {"base_nonce": 0, "expected": [ + "0x747f675a3e246779", "0x3b7b243899b0630f", "0x09b218fdb330dfe4", "0x815881ff26c2ad97", "0xcea3325e3467ae16", "0xcdb1e7c8315fcf5c", "0x2a869dbf61a3cc0d", "0xfb63910ab6c1b391", + "0x9a80515f55fd00b0", "0x379c4f2c8677cc52", "0x855916abf975255d", "0x02c7e2ec1b7bb721", "0xd5d77c714c49d776", "0x05a97f93e03bca0a", "0x2e622e72a5ebe6c4", "0x797240828dedbe8f", + "0x3055cd022b2d02df", "0xbf5a2bb44435048c", "0xb34a8a307485687a", "0xe9e7bcad98410300", "0x6550ae6ffd645f8b", "0x0ebf6803ef855f01", "0xba5ee1c0150057a1", "0xa941029be202ad09", + "0x1ce9748a96ef1e52", "0xb94f9bfb9456af54", "0x6790d5d0e150fa80", "0xbd5acfd4c895f294", "0x854ec3ae328a2356", "0x42663c674dceb3b7", "0xa1ec4b65fc185d23", "0xeb2d57676a7403d2" + ]}, + {"base_nonce": 4096, "expected": [ + "0x5e67a3767d022ea9", "0xe632ab080c255629", "0xd5faa7887d8dd060", "0x1be4efe63fee6b31", "0x9853b48cd230473c", "0xb7518eb50febd9fb", "0x818574269e928cdd", "0x8c8d3235fef8abe3", + "0x721cebf4a1abc8b9", "0x3401396bf9a05f89", "0x73950d7ebcc401ab", "0x5e7d538b6f66a56d", "0xad8dd338954b0ef4", "0xfe44537374e1b230", "0x1d2cb8f5d8eb0aae", "0xed5e84bdc4323359", + "0x3e854f1684be0e03", "0x0aaba78e40d9ae05", "0x993b011aaca4ed0d", "0x326daeeb4fb66133", "0xdc58784f0070ae86", "0x3c5283ea978b04ec", "0x5e0dfeaae08e60d6", "0x6cbb111502716191", + "0x4e03aa98da68b701", "0xca338b880c4094aa", "0x440da9a12a281e9d", "0xaa8d7bc6e2d605c9", "0x1bd954a3e2888a07", "0x0595e720f5773e7a", "0x2d881b4257faad0c", "0xa2408eacf140b697" + ]}, + {"base_nonce": 1000000, "expected": [ + "0x71f0f56dc7c87afb", "0xdba8a00051ee0c0d", "0xd77432d0f7c4a528", "0xd7e34a1297d6238c", "0xf380492d6ef03c7f", "0x685e7d06d22aa640", "0x6d6278b0933d8900", "0xb57c46a08d73078f", + "0xa0122a5ade2bd287", "0x021ca9ecc33a14fb", "0x57fc40164dfda1f0", "0xb5574e1a1a27c5f9", "0x2e35a9b3eba63d34", "0xa1abe6745067d96b", "0xf3ec38b0932a91f3", "0x15cc12195591a0e5", + "0x369cea21f9f2c65e", "0x3a7187650b85b341", "0xa7e37b799dca283b", "0x94e75d165a710881", "0x09dd15dc13859257", "0x01416f04012b3504", "0xcb38317f23258284", "0xbd3f1cc73f88926c", + "0x832f757a700a2b5a", "0x169ad0ad523a4e71", "0x80432f3862428dcd", "0x4ba8b5b19a4b8e0e", "0x03472af8bcec773c", "0x13f795a9ac8cc5bc", "0x0c8431b4b846d642", "0x3c6ec17e1d80e9f6" + ]} + ], + "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" +} diff --git a/proto-cuda/packs-ca3-shadow/sh256x13/kernel.cl b/proto-cuda/packs-ca3-shadow/sh256x13/kernel.cl new file mode 100644 index 000000000..e1be8bee1 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x13/kernel.cl @@ -0,0 +1,538 @@ +// 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 ^ 0x67a9a7beu; x += 0x9e3779b9u; x = splitmix32(x); r0 = x ^ 0x1a155b25u; } // SEEDW[0], 0x9e3779b9u * 1u, SEEDW[1] + { uint x = nonce ^ 0x1a155b25u; x += 0x3c6ef372u; x = splitmix32(x); r1 = x ^ 0xfddfb732u; } // SEEDW[1], 0x9e3779b9u * 2u, SEEDW[2] + { uint x = nonce ^ 0xfddfb732u; x += 0xdaa66d2bu; x = splitmix32(x); r2 = x ^ 0x4b5af2e8u; } // SEEDW[2], 0x9e3779b9u * 3u, SEEDW[3] + { uint x = nonce ^ 0x4b5af2e8u; x += 0x78dde6e4u; x = splitmix32(x); r3 = x ^ 0xc55caf33u; } // SEEDW[3], 0x9e3779b9u * 4u, SEEDW[4] + { uint x = nonce ^ 0xc55caf33u; x += 0x1715609du; x = splitmix32(x); r4 = x ^ 0xa27c13b7u; } // SEEDW[4], 0x9e3779b9u * 5u, SEEDW[5] + { uint x = nonce ^ 0xa27c13b7u; x += 0xb54cda56u; x = splitmix32(x); r5 = x ^ 0x06628a48u; } // SEEDW[5], 0x9e3779b9u * 6u, SEEDW[6] + { uint x = nonce ^ 0x06628a48u; x += 0x5384540fu; x = splitmix32(x); r6 = x ^ 0x03852469u; } // SEEDW[6], 0x9e3779b9u * 7u, SEEDW[7] + { uint x = nonce ^ 0x03852469u; x += 0xf1bbcdc8u; x = splitmix32(x); r7 = x ^ 0x67a9a7beu; } // SEEDW[7], 0x9e3779b9u * 8u, SEEDW[0] + + for (uint it = 0u; it < 8u; ++it) { + uint sel = r0; + r2 = r3 * r4 + r2; // 0 mad + r2 = r1 * r1 + r2; // 1 mad + r2 = r3 * r2 + r2; // 2 mad + r3 = r3 ^ r5; // 3 xor + r7 = r7 ^ ds[r2 & mask]; // 4 load + r5 = r5 ^ ds[r7 & mask]; // 5 load + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r1 = r1 ^ t_; } // 6 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r7 = r7 ^ t_; } // 7 shfl + r1 = mul_hi(r1, r5); // 8 mulhi + r6 = rotr_var(r6, r3); // 9 rotr + r3 = r3 | r4; // 10 or + r4 = r4 ^ ds[r3 & mask]; // 11 load + r0 = mul_hi(r0, r4); // 12 mulhi + r5 = r5 + r1 + ((((sel >> 30u) & 1u) != 0u) ? 0xd3177981u : 0xc7934706u); // 13 add + r0 = r0 ^ ds[r4 & mask]; // 14 load + r2 = r2 - r4; // 15 sub + r2 = r2 ^ ds[r0 & mask]; // 16 load + r7 = r7 ^ ds[r2 & mask]; // 17 load + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r7 = r7 ^ t_; } // 18 shfl + r5 = r5 * r0; // 19 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // 20 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 16u); r2 = r2 ^ t_; } // 21 shfl + r6 = mul_hi(r6, r2); // 22 mulhi + r6 = r6 ^ ds[r1 & mask]; // 23 load + r5 = r5 * r0; // 24 mul + r5 = rotl_imm(r5, 19u); // 25 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 2u); r7 = r7 ^ t_; } // 26 shfl + r0 = r0 ^ r5; // 27 xor + r0 = r0 ^ r4; // 28 xor + r3 = r3 - r0; // 29 sub + r5 = r5 * r1; // 30 mul + r7 = r7 ^ ds[r2 & mask]; // 31 load + r1 = r1 ^ ds[r0 & mask]; // 32 load + r5 = r5 ^ r6; // 33 xor + r5 = r5 ^ ds[r1 & mask]; // 34 load + r0 = mul_hi(r0, r5); // 35 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r5 = r5 ^ t_; } // 36 shfl + r7 = r7 ^ ds[r0 & mask]; // 37 load + r3 = r3 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0x230c005cu : 0x75ba2fadu); // 38 add + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 4u); r1 = r1 ^ t_; } // 39 shfl + r2 = r2 ^ r5; // 40 xor + r3 = r6 * r3 + r3; // 41 mad + r6 = r6 - r7; // 42 sub + r7 = r7 ^ r0; // 43 xor + r1 = r1 ^ ds[r7 & mask]; // 44 load + r2 = r2 * r3; // 45 mul + r1 = mul_hi(r1, r5); // 46 mulhi + r4 = r4 - r3; // 47 sub + r2 = rotr_var(r2, r6); // 48 rotr + r3 = r3 ^ ds[r5 & mask]; // 49 load + r1 = r1 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x1907970cu : 0x81b8bc2cu); // 50 add + r0 = r0 * r2; // 51 mul + r0 = r0 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x699fd448u : 0x4f92b968u); // 52 add + r1 = r1 + r0 + ((((sel >> 12u) & 1u) != 0u) ? 0x77b1520du : 0x2bb965afu); // 53 add + r7 = rotl_imm(r7, 14u); // 54 rotl + r3 = r3 + r7 + ((((sel >> 1u) & 1u) != 0u) ? 0xa54c55a0u : 0x7b0fe07au); // 55 add + r6 = r6 ^ ds[r7 & mask]; // 56 load + r1 = rotr_var(r1, r5); // 57 rotr + r5 = r5 ^ ds[r4 & mask]; // 58 load + r6 = r6 ^ ds[r2 & mask]; // 59 load + r3 = r5 * r0 + r3; // 60 mad + r5 = r5 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0xad7493e7u : 0xaf9dd72du); // 61 add + r4 = r4 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x1e07c3d9u : 0x89841d87u); // 62 add + r5 = rotl_imm(r5, 19u); // 63 rotl + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 13 passes after instruction 63, no load + for (uint sh = 0u; sh < 13u; ++sh) { + r5 = r5 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x8bc12da9u : 0x92199f99u); // s0 add + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x63079e5au : 0x8d72d3adu); // s1 add + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 2u); r6 = r6 ^ t_; } // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + ((((sel >> 31u) & 1u) != 0u) ? 0x5d4c7a60u : 0xb21b4babu); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + ((((sel >> 16u) & 1u) != 0u) ? 0xc88e2942u : 0x2fe0e98bu); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r6 = r6 ^ t_; } // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 4u); r2 = r2 ^ t_; } // s12 shfl + r1 = r1 + r5 + ((((sel >> 25u) & 1u) != 0u) ? 0xbc48c63eu : 0xbdf8f9a5u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r2 = r2 ^ t_; } // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + ((((sel >> 1u) & 1u) != 0u) ? 0x96e8f127u : 0x45c37cecu); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = mul_hi(r6, r0); // s28 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r2 = r2 ^ t_; } // s29 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r1 = r1 ^ t_; } // s30 shfl + r1 = r1 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0xb1cdb2abu : 0x37985632u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // s33 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r0 = r0 ^ t_; } // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x856e0180u : 0x804e777eu); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xe9bd0cc4u : 0x0b06c8a7u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = mul_hi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = mul_hi(r4, r3); // s44 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xcdcb63f6u : 0xee822e17u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r4 = r4 ^ t_; } // s47 shfl + r6 = mul_hi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0xd4758987u : 0x3dfad1b6u); // s56 add + r4 = r4 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x0602d6beu : 0xfca75bc2u); // s57 add + r5 = mul_hi(r5, r6); // s58 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r2 = r2 ^ t_; } // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0x8596687au : 0xd71c02ffu); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 2u); r7 = r7 ^ t_; } // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0x08ac5733u : 0x3c6fe15du); // s72 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r3 = r3 ^ t_; } // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + ((((sel >> 1u) & 1u) != 0u) ? 0xc100b495u : 0x295d5faeu); // s77 add + r3 = mul_hi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + ((((sel >> 15u) & 1u) != 0u) ? 0x5cc59530u : 0x274a9221u); // s81 add + r7 = r7 + r3 + ((((sel >> 5u) & 1u) != 0u) ? 0x141479ecu : 0xc8651f8eu); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r2 = r2 ^ t_; } // s85 shfl + r3 = r3 ^ r2; // s86 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 2u); r5 = r5 ^ t_; } // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x883c0c92u : 0x53f915c2u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + ((((sel >> 31u) & 1u) != 0u) ? 0x3cc5bd20u : 0xe2be00a5u); // s91 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 1u); r7 = r7 ^ t_; } // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + ((((sel >> 17u) & 1u) != 0u) ? 0xbfd646cbu : 0x423fd9c9u); // s101 add + r7 = r7 + r6 + ((((sel >> 11u) & 1u) != 0u) ? 0x19b74a43u : 0x8d3c011du); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + ((((sel >> 15u) & 1u) != 0u) ? 0x7dcb7e18u : 0x8ce14721u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = mul_hi(r2, r0); // s109 mulhi + r1 = mul_hi(r1, r0); // s110 mulhi + r0 = r0 + r2 + ((((sel >> 28u) & 1u) != 0u) ? 0x3c179ad8u : 0x2d9fc6b9u); // s111 add + r2 = mul_hi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + ((((sel >> 22u) & 1u) != 0u) ? 0x47359729u : 0x502138e2u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = mul_hi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 2u); r4 = r4 ^ t_; } // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r7 = r7 ^ t_; } // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x6c57e4e7u : 0x33dff776u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + ((((sel >> 30u) & 1u) != 0u) ? 0xe8212c0cu : 0x5db25b34u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = mul_hi(r0, r5); // s138 mulhi + r2 = r2 + r7 + ((((sel >> 10u) & 1u) != 0u) ? 0xd44ff710u : 0x218d4090u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r3 = r3 ^ t_; } // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + ((((sel >> 29u) & 1u) != 0u) ? 0xb98942fau : 0xf4b1a8deu); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + ((((sel >> 17u) & 1u) != 0u) ? 0x0d48ba42u : 0x2bef10f2u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + ((((sel >> 30u) & 1u) != 0u) ? 0xc98dea9cu : 0xdc5cc080u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0x6c752dcbu : 0x18197438u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + ((((sel >> 3u) & 1u) != 0u) ? 0x8e481727u : 0xf1c46574u); // s163 add + r0 = mul_hi(r0, r4); // s164 mulhi + r2 = r2 + r6 + ((((sel >> 20u) & 1u) != 0u) ? 0x550ab406u : 0xac578137u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + ((((sel >> 14u) & 1u) != 0u) ? 0xaebb5966u : 0xa33e6706u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 8u); r7 = r7 ^ t_; } // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x5bb7550fu : 0xd94d55acu); // s184 add + r3 = r3 | r5; // s185 or + r6 = mul_hi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r7 = r7 ^ t_; } // s188 shfl + r6 = r6 + r5 + ((((sel >> 6u) & 1u) != 0u) ? 0x2a354e2du : 0x89e747feu); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = mul_hi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r4 = r4 ^ t_; } // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + ((((sel >> 7u) & 1u) != 0u) ? 0x10cfdc71u : 0xea03e8e7u); // s197 add + r7 = r7 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x66e148d3u : 0xa7ee0102u); // s198 add + r5 = r5 - r2; // s199 sub + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r5 = r5 ^ t_; } // s200 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 8u); r7 = r7 ^ t_; } // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0x8558b619u : 0x8379a4deu); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = mul_hi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 4u); r2 = r2 ^ t_; } // s209 shfl + r7 = r7 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0xf4049c4cu : 0xaa8cb14eu); // s210 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 16u); r7 = r7 ^ t_; } // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 16u); r3 = r3 ^ t_; } // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = mul_hi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r5 = r5 ^ t_; } // s222 shfl + r5 = mul_hi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0x2a7fecb2u : 0x1d176220u); // s230 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r1 = r1 ^ t_; } // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + ((((sel >> 25u) & 1u) != 0u) ? 0xadce39f3u : 0x17dafb4du); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + ((((sel >> 29u) & 1u) != 0u) ? 0x0e7033b6u : 0xf2f77d26u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + ((((sel >> 31u) & 1u) != 0u) ? 0x7b2ff6b7u : 0xfed2da4eu); // s247 add + r0 = r0 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0xb5fad7b1u : 0x03b2891cu); // s248 add + r5 = mul_hi(r5, r4); // s249 mulhi + r5 = r5 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0xa7e71c2fu : 0x042cd6e3u); // s250 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 1u); r6 = r6 ^ t_; } // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0xb83d78deu : 0x784a302bu); // s254 add + r2 = r2 - r4; // s255 sub + } + } + uint lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((ulong)hi << 32) | (ulong)lo; +} + +#if IGNEUM_EXCHANGE != 0 +// Reports the sub-group size this device uses for a work-group of IGNEUM_GROUP items. host.c runs it only when the +// per-kernel query (clGetKernelSubGroupInfoKHR on igneum_hash) is unavailable; that query is preferred because a +// compiler may pick a different wave width per kernel (RDNA: wave32 or wave64). See WAVEFRONT.md. +IGNEUM_KERNEL_HASH void igneum_probe_subgroup(__global uint* out) { + if (get_local_id(0) == 0u) { out[0] = get_sub_group_size(); out[1] = get_num_sub_groups(); } +} +#endif diff --git a/proto-cuda/packs-ca3-shadow/sh256x13/kernel.cu b/proto-cuda/packs-ca3-shadow/sh256x13/kernel.cu new file mode 100644 index 000000000..b0a692f86 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x13/kernel.cu @@ -0,0 +1,423 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Bit-exact twin of the Metal kernel for the same seed (see proto-cuda/CHECKLIST.md and program.metal). +// Compiled ahead of time by nvcc together with proto-cuda/host.cu. No NVRTC. +#include +#include +#include "program.h" +#include "memhard.h" + +__device__ __forceinline__ uint32_t splitmix32(uint32_t x) { + x ^= x >> 16; x *= 0x7feb352du; + x ^= x >> 15; x *= 0x846ca68bu; + x ^= x >> 16; + return x; +} +// n is a literal in 1..31 at every call site, so both shift amounts are in 1..31. +__device__ __forceinline__ uint32_t rotl_imm(uint32_t x, uint32_t n) { return (x << n) | (x >> (32u - n)); } +// n is masked to 0..31; the second shift amount is masked too, so n == 0 gives x. +__device__ __forceinline__ uint32_t rotr_var(uint32_t x, uint32_t n) { n &= 31u; return (x >> n) | (x << ((32u - n) & 31u)); } +__device__ __forceinline__ uint32_t ds_elem(uint32_t i, uint32_t d0, uint32_t d1) { + uint32_t x = i ^ d0; + x *= 0x9E3779B1u; x ^= x >> 15; + x += d1; + x *= 0x85EBCA77u; x ^= x >> 13; + x *= 0xC2B2AE3Du; x ^= x >> 16; + return x; +} + +// Memory-hard dataset (MEMHARD.md). One thread per cache segment; one thread per 64-byte dataset item. +// The core functions (mh_cache_segment, mh_item) are in memhard.h and are also compiled for the host. +__global__ void igneum_cache_fill(uint32_t* cache, uint32_t nSegments) { + uint32_t seg = blockIdx.x * blockDim.x + threadIdx.x; + if (seg < nSegments) mh_cache_segment(cache, seg); +} +__global__ void igneum_build(uint32_t* ds, const uint32_t* cache, uint32_t nItems) { + uint32_t t = blockIdx.x * blockDim.x + threadIdx.x; + if (t < nItems) { + uint32_t s[16]; + mh_item(cache, t, s); + uint32_t* d = ds + (size_t)t * 16u; + for (uint32_t i = 0u; i < 16u; ++i) d[i] = s[i]; + } +} + +// One hash per thread. blockDim.x is a multiple of 32; lane = threadIdx.x & 31 and every +// __shfl_xor_sync stays inside the lane's own warp, exactly like simd_shuffle_xor inside a +// 32-wide Metal SIMD group. Control flow is uniform, so the full 0xffffffff member mask is valid. +__global__ void igneum_hash(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask) { + uint32_t gid = blockIdx.x * blockDim.x + threadIdx.x; + uint32_t nonce = baseNonce + gid; + uint32_t r0, r1, r2, r3, r4, r5, r6, r7; + { uint32_t x = nonce ^ 0x67a9a7beu; x += 0x9e3779b9u; x = splitmix32(x); r0 = x ^ 0x1a155b25u; } // SEEDW[0], 0x9e3779b9u * 1u, SEEDW[1] + { uint32_t x = nonce ^ 0x1a155b25u; x += 0x3c6ef372u; x = splitmix32(x); r1 = x ^ 0xfddfb732u; } // SEEDW[1], 0x9e3779b9u * 2u, SEEDW[2] + { uint32_t x = nonce ^ 0xfddfb732u; x += 0xdaa66d2bu; x = splitmix32(x); r2 = x ^ 0x4b5af2e8u; } // SEEDW[2], 0x9e3779b9u * 3u, SEEDW[3] + { uint32_t x = nonce ^ 0x4b5af2e8u; x += 0x78dde6e4u; x = splitmix32(x); r3 = x ^ 0xc55caf33u; } // SEEDW[3], 0x9e3779b9u * 4u, SEEDW[4] + { uint32_t x = nonce ^ 0xc55caf33u; x += 0x1715609du; x = splitmix32(x); r4 = x ^ 0xa27c13b7u; } // SEEDW[4], 0x9e3779b9u * 5u, SEEDW[5] + { uint32_t x = nonce ^ 0xa27c13b7u; x += 0xb54cda56u; x = splitmix32(x); r5 = x ^ 0x06628a48u; } // SEEDW[5], 0x9e3779b9u * 6u, SEEDW[6] + { uint32_t x = nonce ^ 0x06628a48u; x += 0x5384540fu; x = splitmix32(x); r6 = x ^ 0x03852469u; } // SEEDW[6], 0x9e3779b9u * 7u, SEEDW[7] + { uint32_t x = nonce ^ 0x03852469u; x += 0xf1bbcdc8u; x = splitmix32(x); r7 = x ^ 0x67a9a7beu; } // SEEDW[7], 0x9e3779b9u * 8u, SEEDW[0] + + for (uint32_t it = 0u; it < 8u; ++it) { + uint32_t sel = r0; + r2 = r3 * r4 + r2; // 0 mad + r2 = r1 * r1 + r2; // 1 mad + r2 = r3 * r2 + r2; // 2 mad + r3 = r3 ^ r5; // 3 xor + r7 = r7 ^ ds[r2 & mask]; // 4 load + r5 = r5 ^ ds[r7 & mask]; // 5 load + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r4, 8); // 6 shfl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r3, 8); // 7 shfl + r1 = __umulhi(r1, r5); // 8 mulhi + r6 = rotr_var(r6, r3); // 9 rotr + r3 = r3 | r4; // 10 or + r4 = r4 ^ ds[r3 & mask]; // 11 load + r0 = __umulhi(r0, r4); // 12 mulhi + r5 = r5 + r1 + ((((sel >> 30u) & 1u) != 0u) ? 0xd3177981u : 0xc7934706u); // 13 add + r0 = r0 ^ ds[r4 & mask]; // 14 load + r2 = r2 - r4; // 15 sub + r2 = r2 ^ ds[r0 & mask]; // 16 load + r7 = r7 ^ ds[r2 & mask]; // 17 load + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r3, 4); // 18 shfl + r5 = r5 * r0; // 19 mul + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // 20 shfl + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 16); // 21 shfl + r6 = __umulhi(r6, r2); // 22 mulhi + r6 = r6 ^ ds[r1 & mask]; // 23 load + r5 = r5 * r0; // 24 mul + r5 = rotl_imm(r5, 19u); // 25 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r6, 2); // 26 shfl + r0 = r0 ^ r5; // 27 xor + r0 = r0 ^ r4; // 28 xor + r3 = r3 - r0; // 29 sub + r5 = r5 * r1; // 30 mul + r7 = r7 ^ ds[r2 & mask]; // 31 load + r1 = r1 ^ ds[r0 & mask]; // 32 load + r5 = r5 ^ r6; // 33 xor + r5 = r5 ^ ds[r1 & mask]; // 34 load + r0 = __umulhi(r0, r5); // 35 mulhi + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // 36 shfl + r7 = r7 ^ ds[r0 & mask]; // 37 load + r3 = r3 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0x230c005cu : 0x75ba2fadu); // 38 add + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r5, 4); // 39 shfl + r2 = r2 ^ r5; // 40 xor + r3 = r6 * r3 + r3; // 41 mad + r6 = r6 - r7; // 42 sub + r7 = r7 ^ r0; // 43 xor + r1 = r1 ^ ds[r7 & mask]; // 44 load + r2 = r2 * r3; // 45 mul + r1 = __umulhi(r1, r5); // 46 mulhi + r4 = r4 - r3; // 47 sub + r2 = rotr_var(r2, r6); // 48 rotr + r3 = r3 ^ ds[r5 & mask]; // 49 load + r1 = r1 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x1907970cu : 0x81b8bc2cu); // 50 add + r0 = r0 * r2; // 51 mul + r0 = r0 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x699fd448u : 0x4f92b968u); // 52 add + r1 = r1 + r0 + ((((sel >> 12u) & 1u) != 0u) ? 0x77b1520du : 0x2bb965afu); // 53 add + r7 = rotl_imm(r7, 14u); // 54 rotl + r3 = r3 + r7 + ((((sel >> 1u) & 1u) != 0u) ? 0xa54c55a0u : 0x7b0fe07au); // 55 add + r6 = r6 ^ ds[r7 & mask]; // 56 load + r1 = rotr_var(r1, r5); // 57 rotr + r5 = r5 ^ ds[r4 & mask]; // 58 load + r6 = r6 ^ ds[r2 & mask]; // 59 load + r3 = r5 * r0 + r3; // 60 mad + r5 = r5 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0xad7493e7u : 0xaf9dd72du); // 61 add + r4 = r4 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x1e07c3d9u : 0x89841d87u); // 62 add + r5 = rotl_imm(r5, 19u); // 63 rotl + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 13 passes after instruction 63, no load + for (uint32_t sh = 0u; sh < 13u; ++sh) { + r5 = r5 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x8bc12da9u : 0x92199f99u); // s0 add + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x63079e5au : 0x8d72d3adu); // s1 add + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r3, 2); // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + ((((sel >> 31u) & 1u) != 0u) ? 0x5d4c7a60u : 0xb21b4babu); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + ((((sel >> 16u) & 1u) != 0u) ? 0xc88e2942u : 0x2fe0e98bu); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r1, 4); // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r6, 4); // s12 shfl + r1 = r1 + r5 + ((((sel >> 25u) & 1u) != 0u) ? 0xbc48c63eu : 0xbdf8f9a5u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 8); // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + ((((sel >> 1u) & 1u) != 0u) ? 0x96e8f127u : 0x45c37cecu); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = __umulhi(r6, r0); // s28 mulhi + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // s29 shfl + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r6, 1); // s30 shfl + r1 = r1 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0xb1cdb2abu : 0x37985632u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // s33 shfl + r0 = r0 ^ __shfl_xor_sync(0xffffffffu, r3, 4); // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x856e0180u : 0x804e777eu); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xe9bd0cc4u : 0x0b06c8a7u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = __umulhi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = __umulhi(r4, r3); // s44 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xcdcb63f6u : 0xee822e17u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r3, 8); // s47 shfl + r6 = __umulhi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0xd4758987u : 0x3dfad1b6u); // s56 add + r4 = r4 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x0602d6beu : 0xfca75bc2u); // s57 add + r5 = __umulhi(r5, r6); // s58 mulhi + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0x8596687au : 0xd71c02ffu); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r5, 2); // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0x08ac5733u : 0x3c6fe15du); // s72 add + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r2, 8); // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + ((((sel >> 1u) & 1u) != 0u) ? 0xc100b495u : 0x295d5faeu); // s77 add + r3 = __umulhi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + ((((sel >> 15u) & 1u) != 0u) ? 0x5cc59530u : 0x274a9221u); // s81 add + r7 = r7 + r3 + ((((sel >> 5u) & 1u) != 0u) ? 0x141479ecu : 0xc8651f8eu); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r5, 16); // s85 shfl + r3 = r3 ^ r2; // s86 xor + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r7, 2); // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x883c0c92u : 0x53f915c2u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + ((((sel >> 31u) & 1u) != 0u) ? 0x3cc5bd20u : 0xe2be00a5u); // s91 add + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r2, 1); // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + ((((sel >> 17u) & 1u) != 0u) ? 0xbfd646cbu : 0x423fd9c9u); // s101 add + r7 = r7 + r6 + ((((sel >> 11u) & 1u) != 0u) ? 0x19b74a43u : 0x8d3c011du); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + ((((sel >> 15u) & 1u) != 0u) ? 0x7dcb7e18u : 0x8ce14721u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = __umulhi(r2, r0); // s109 mulhi + r1 = __umulhi(r1, r0); // s110 mulhi + r0 = r0 + r2 + ((((sel >> 28u) & 1u) != 0u) ? 0x3c179ad8u : 0x2d9fc6b9u); // s111 add + r2 = __umulhi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + ((((sel >> 22u) & 1u) != 0u) ? 0x47359729u : 0x502138e2u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = __umulhi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r2, 2); // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x6c57e4e7u : 0x33dff776u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + ((((sel >> 30u) & 1u) != 0u) ? 0xe8212c0cu : 0x5db25b34u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = __umulhi(r0, r5); // s138 mulhi + r2 = r2 + r7 + ((((sel >> 10u) & 1u) != 0u) ? 0xd44ff710u : 0x218d4090u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r6, 1); // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + ((((sel >> 29u) & 1u) != 0u) ? 0xb98942fau : 0xf4b1a8deu); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + ((((sel >> 17u) & 1u) != 0u) ? 0x0d48ba42u : 0x2bef10f2u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + ((((sel >> 30u) & 1u) != 0u) ? 0xc98dea9cu : 0xdc5cc080u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0x6c752dcbu : 0x18197438u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + ((((sel >> 3u) & 1u) != 0u) ? 0x8e481727u : 0xf1c46574u); // s163 add + r0 = __umulhi(r0, r4); // s164 mulhi + r2 = r2 + r6 + ((((sel >> 20u) & 1u) != 0u) ? 0x550ab406u : 0xac578137u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + ((((sel >> 14u) & 1u) != 0u) ? 0xaebb5966u : 0xa33e6706u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r0, 8); // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x5bb7550fu : 0xd94d55acu); // s184 add + r3 = r3 | r5; // s185 or + r6 = __umulhi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s188 shfl + r6 = r6 + r5 + ((((sel >> 6u) & 1u) != 0u) ? 0x2a354e2du : 0x89e747feu); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = __umulhi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r5, 16); // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + ((((sel >> 7u) & 1u) != 0u) ? 0x10cfdc71u : 0xea03e8e7u); // s197 add + r7 = r7 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x66e148d3u : 0xa7ee0102u); // s198 add + r5 = r5 - r2; // s199 sub + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s200 shfl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 8); // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0x8558b619u : 0x8379a4deu); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = __umulhi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r0, 4); // s209 shfl + r7 = r7 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0xf4049c4cu : 0xaa8cb14eu); // s210 add + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 16); // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r2, 16); // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = __umulhi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r2, 8); // s222 shfl + r5 = __umulhi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0x2a7fecb2u : 0x1d176220u); // s230 add + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + ((((sel >> 25u) & 1u) != 0u) ? 0xadce39f3u : 0x17dafb4du); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + ((((sel >> 29u) & 1u) != 0u) ? 0x0e7033b6u : 0xf2f77d26u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + ((((sel >> 31u) & 1u) != 0u) ? 0x7b2ff6b7u : 0xfed2da4eu); // s247 add + r0 = r0 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0xb5fad7b1u : 0x03b2891cu); // s248 add + r5 = __umulhi(r5, r4); // s249 mulhi + r5 = r5 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0xa7e71c2fu : 0x042cd6e3u); // s250 add + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r1, 1); // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0xb83d78deu : 0x784a302bu); // s254 add + r2 = r2 - r4; // s255 sub + } + } + uint32_t lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint32_t hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((uint64_t)hi << 32) | (uint64_t)lo; +} + +// Host-side launch wrappers. Declared in program.h, called from host.cu. +cudaError_t igneum_launch_cache_fill(uint32_t* cache, uint32_t nSegments) { + if (nSegments == 0u) return cudaErrorInvalidValue; + uint32_t block = 256u; + uint32_t grid = (nSegments + block - 1u) / block; + igneum_cache_fill<<>>(cache, nSegments); + return cudaGetLastError(); +} + +cudaError_t igneum_launch_build(uint32_t* ds, const uint32_t* cache, uint32_t nItems) { + if (nItems == 0u) return cudaErrorInvalidValue; + uint32_t block = 256u; + uint32_t grid = (nItems + block - 1u) / block; + igneum_build<<>>(ds, cache, nItems); + return cudaGetLastError(); +} + +cudaError_t igneum_launch_hash(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, + uint32_t nonces, uint32_t blockWarps) { + if (blockWarps == 0u || blockWarps > 32u) return cudaErrorInvalidValue; + uint32_t block = 32u * blockWarps; + if (nonces == 0u || (nonces % block) != 0u) return cudaErrorInvalidValue; + igneum_hash<<>>(ds, out, baseNonce, mask); + return cudaGetLastError(); +} + +cudaError_t igneum_hash_info(int* numRegs, int* blocksPerSM, uint32_t blockWarps) { + cudaFuncAttributes attr; + cudaError_t e = cudaFuncGetAttributes(&attr, igneum_hash); + if (e != cudaSuccess) return e; + *numRegs = attr.numRegs; + return cudaOccupancyMaxActiveBlocksPerMultiprocessor(blocksPerSM, igneum_hash, (int)(32u * blockWarps), 0); +} diff --git a/proto-cuda/packs-ca3-shadow/sh256x13/kernel_bound.cl b/proto-cuda/packs-ca3-shadow/sh256x13/kernel_bound.cl new file mode 100644 index 000000000..857b927e4 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x13/kernel_bound.cl @@ -0,0 +1,891 @@ +// 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 ^ 0x67a9a7beu; x += 0x9e3779b9u; x = splitmix32(x); r0 = x ^ 0x1a155b25u; } // SEEDW[0], 0x9e3779b9u * 1u, SEEDW[1] + { uint x = nonce ^ 0x1a155b25u; x += 0x3c6ef372u; x = splitmix32(x); r1 = x ^ 0xfddfb732u; } // SEEDW[1], 0x9e3779b9u * 2u, SEEDW[2] + { uint x = nonce ^ 0xfddfb732u; x += 0xdaa66d2bu; x = splitmix32(x); r2 = x ^ 0x4b5af2e8u; } // SEEDW[2], 0x9e3779b9u * 3u, SEEDW[3] + { uint x = nonce ^ 0x4b5af2e8u; x += 0x78dde6e4u; x = splitmix32(x); r3 = x ^ 0xc55caf33u; } // SEEDW[3], 0x9e3779b9u * 4u, SEEDW[4] + { uint x = nonce ^ 0xc55caf33u; x += 0x1715609du; x = splitmix32(x); r4 = x ^ 0xa27c13b7u; } // SEEDW[4], 0x9e3779b9u * 5u, SEEDW[5] + { uint x = nonce ^ 0xa27c13b7u; x += 0xb54cda56u; x = splitmix32(x); r5 = x ^ 0x06628a48u; } // SEEDW[5], 0x9e3779b9u * 6u, SEEDW[6] + { uint x = nonce ^ 0x06628a48u; x += 0x5384540fu; x = splitmix32(x); r6 = x ^ 0x03852469u; } // SEEDW[6], 0x9e3779b9u * 7u, SEEDW[7] + { uint x = nonce ^ 0x03852469u; x += 0xf1bbcdc8u; x = splitmix32(x); r7 = x ^ 0x67a9a7beu; } // SEEDW[7], 0x9e3779b9u * 8u, SEEDW[0] + + for (uint it = 0u; it < 8u; ++it) { + uint sel = r0; + r2 = r3 * r4 + r2; // 0 mad + r2 = r1 * r1 + r2; // 1 mad + r2 = r3 * r2 + r2; // 2 mad + r3 = r3 ^ r5; // 3 xor + r7 = r7 ^ ds[r2 & mask]; // 4 load + r5 = r5 ^ ds[r7 & mask]; // 5 load + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r1 = r1 ^ t_; } // 6 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r7 = r7 ^ t_; } // 7 shfl + r1 = mul_hi(r1, r5); // 8 mulhi + r6 = rotr_var(r6, r3); // 9 rotr + r3 = r3 | r4; // 10 or + r4 = r4 ^ ds[r3 & mask]; // 11 load + r0 = mul_hi(r0, r4); // 12 mulhi + r5 = r5 + r1 + ((((sel >> 30u) & 1u) != 0u) ? 0xd3177981u : 0xc7934706u); // 13 add + r0 = r0 ^ ds[r4 & mask]; // 14 load + r2 = r2 - r4; // 15 sub + r2 = r2 ^ ds[r0 & mask]; // 16 load + r7 = r7 ^ ds[r2 & mask]; // 17 load + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r7 = r7 ^ t_; } // 18 shfl + r5 = r5 * r0; // 19 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // 20 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 16u); r2 = r2 ^ t_; } // 21 shfl + r6 = mul_hi(r6, r2); // 22 mulhi + r6 = r6 ^ ds[r1 & mask]; // 23 load + r5 = r5 * r0; // 24 mul + r5 = rotl_imm(r5, 19u); // 25 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 2u); r7 = r7 ^ t_; } // 26 shfl + r0 = r0 ^ r5; // 27 xor + r0 = r0 ^ r4; // 28 xor + r3 = r3 - r0; // 29 sub + r5 = r5 * r1; // 30 mul + r7 = r7 ^ ds[r2 & mask]; // 31 load + r1 = r1 ^ ds[r0 & mask]; // 32 load + r5 = r5 ^ r6; // 33 xor + r5 = r5 ^ ds[r1 & mask]; // 34 load + r0 = mul_hi(r0, r5); // 35 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r5 = r5 ^ t_; } // 36 shfl + r7 = r7 ^ ds[r0 & mask]; // 37 load + r3 = r3 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0x230c005cu : 0x75ba2fadu); // 38 add + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 4u); r1 = r1 ^ t_; } // 39 shfl + r2 = r2 ^ r5; // 40 xor + r3 = r6 * r3 + r3; // 41 mad + r6 = r6 - r7; // 42 sub + r7 = r7 ^ r0; // 43 xor + r1 = r1 ^ ds[r7 & mask]; // 44 load + r2 = r2 * r3; // 45 mul + r1 = mul_hi(r1, r5); // 46 mulhi + r4 = r4 - r3; // 47 sub + r2 = rotr_var(r2, r6); // 48 rotr + r3 = r3 ^ ds[r5 & mask]; // 49 load + r1 = r1 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x1907970cu : 0x81b8bc2cu); // 50 add + r0 = r0 * r2; // 51 mul + r0 = r0 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x699fd448u : 0x4f92b968u); // 52 add + r1 = r1 + r0 + ((((sel >> 12u) & 1u) != 0u) ? 0x77b1520du : 0x2bb965afu); // 53 add + r7 = rotl_imm(r7, 14u); // 54 rotl + r3 = r3 + r7 + ((((sel >> 1u) & 1u) != 0u) ? 0xa54c55a0u : 0x7b0fe07au); // 55 add + r6 = r6 ^ ds[r7 & mask]; // 56 load + r1 = rotr_var(r1, r5); // 57 rotr + r5 = r5 ^ ds[r4 & mask]; // 58 load + r6 = r6 ^ ds[r2 & mask]; // 59 load + r3 = r5 * r0 + r3; // 60 mad + r5 = r5 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0xad7493e7u : 0xaf9dd72du); // 61 add + r4 = r4 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x1e07c3d9u : 0x89841d87u); // 62 add + r5 = rotl_imm(r5, 19u); // 63 rotl + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 13 passes after instruction 63, no load + for (uint sh = 0u; sh < 13u; ++sh) { + r5 = r5 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x8bc12da9u : 0x92199f99u); // s0 add + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x63079e5au : 0x8d72d3adu); // s1 add + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 2u); r6 = r6 ^ t_; } // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + ((((sel >> 31u) & 1u) != 0u) ? 0x5d4c7a60u : 0xb21b4babu); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + ((((sel >> 16u) & 1u) != 0u) ? 0xc88e2942u : 0x2fe0e98bu); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r6 = r6 ^ t_; } // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 4u); r2 = r2 ^ t_; } // s12 shfl + r1 = r1 + r5 + ((((sel >> 25u) & 1u) != 0u) ? 0xbc48c63eu : 0xbdf8f9a5u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r2 = r2 ^ t_; } // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + ((((sel >> 1u) & 1u) != 0u) ? 0x96e8f127u : 0x45c37cecu); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = mul_hi(r6, r0); // s28 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r2 = r2 ^ t_; } // s29 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r1 = r1 ^ t_; } // s30 shfl + r1 = r1 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0xb1cdb2abu : 0x37985632u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // s33 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r0 = r0 ^ t_; } // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x856e0180u : 0x804e777eu); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xe9bd0cc4u : 0x0b06c8a7u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = mul_hi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = mul_hi(r4, r3); // s44 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xcdcb63f6u : 0xee822e17u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r4 = r4 ^ t_; } // s47 shfl + r6 = mul_hi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0xd4758987u : 0x3dfad1b6u); // s56 add + r4 = r4 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x0602d6beu : 0xfca75bc2u); // s57 add + r5 = mul_hi(r5, r6); // s58 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r2 = r2 ^ t_; } // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0x8596687au : 0xd71c02ffu); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 2u); r7 = r7 ^ t_; } // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0x08ac5733u : 0x3c6fe15du); // s72 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r3 = r3 ^ t_; } // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + ((((sel >> 1u) & 1u) != 0u) ? 0xc100b495u : 0x295d5faeu); // s77 add + r3 = mul_hi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + ((((sel >> 15u) & 1u) != 0u) ? 0x5cc59530u : 0x274a9221u); // s81 add + r7 = r7 + r3 + ((((sel >> 5u) & 1u) != 0u) ? 0x141479ecu : 0xc8651f8eu); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r2 = r2 ^ t_; } // s85 shfl + r3 = r3 ^ r2; // s86 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 2u); r5 = r5 ^ t_; } // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x883c0c92u : 0x53f915c2u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + ((((sel >> 31u) & 1u) != 0u) ? 0x3cc5bd20u : 0xe2be00a5u); // s91 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 1u); r7 = r7 ^ t_; } // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + ((((sel >> 17u) & 1u) != 0u) ? 0xbfd646cbu : 0x423fd9c9u); // s101 add + r7 = r7 + r6 + ((((sel >> 11u) & 1u) != 0u) ? 0x19b74a43u : 0x8d3c011du); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + ((((sel >> 15u) & 1u) != 0u) ? 0x7dcb7e18u : 0x8ce14721u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = mul_hi(r2, r0); // s109 mulhi + r1 = mul_hi(r1, r0); // s110 mulhi + r0 = r0 + r2 + ((((sel >> 28u) & 1u) != 0u) ? 0x3c179ad8u : 0x2d9fc6b9u); // s111 add + r2 = mul_hi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + ((((sel >> 22u) & 1u) != 0u) ? 0x47359729u : 0x502138e2u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = mul_hi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 2u); r4 = r4 ^ t_; } // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r7 = r7 ^ t_; } // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x6c57e4e7u : 0x33dff776u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + ((((sel >> 30u) & 1u) != 0u) ? 0xe8212c0cu : 0x5db25b34u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = mul_hi(r0, r5); // s138 mulhi + r2 = r2 + r7 + ((((sel >> 10u) & 1u) != 0u) ? 0xd44ff710u : 0x218d4090u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r3 = r3 ^ t_; } // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + ((((sel >> 29u) & 1u) != 0u) ? 0xb98942fau : 0xf4b1a8deu); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + ((((sel >> 17u) & 1u) != 0u) ? 0x0d48ba42u : 0x2bef10f2u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + ((((sel >> 30u) & 1u) != 0u) ? 0xc98dea9cu : 0xdc5cc080u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0x6c752dcbu : 0x18197438u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + ((((sel >> 3u) & 1u) != 0u) ? 0x8e481727u : 0xf1c46574u); // s163 add + r0 = mul_hi(r0, r4); // s164 mulhi + r2 = r2 + r6 + ((((sel >> 20u) & 1u) != 0u) ? 0x550ab406u : 0xac578137u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + ((((sel >> 14u) & 1u) != 0u) ? 0xaebb5966u : 0xa33e6706u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 8u); r7 = r7 ^ t_; } // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x5bb7550fu : 0xd94d55acu); // s184 add + r3 = r3 | r5; // s185 or + r6 = mul_hi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r7 = r7 ^ t_; } // s188 shfl + r6 = r6 + r5 + ((((sel >> 6u) & 1u) != 0u) ? 0x2a354e2du : 0x89e747feu); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = mul_hi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r4 = r4 ^ t_; } // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + ((((sel >> 7u) & 1u) != 0u) ? 0x10cfdc71u : 0xea03e8e7u); // s197 add + r7 = r7 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x66e148d3u : 0xa7ee0102u); // s198 add + r5 = r5 - r2; // s199 sub + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r5 = r5 ^ t_; } // s200 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 8u); r7 = r7 ^ t_; } // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0x8558b619u : 0x8379a4deu); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = mul_hi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 4u); r2 = r2 ^ t_; } // s209 shfl + r7 = r7 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0xf4049c4cu : 0xaa8cb14eu); // s210 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 16u); r7 = r7 ^ t_; } // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 16u); r3 = r3 ^ t_; } // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = mul_hi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r5 = r5 ^ t_; } // s222 shfl + r5 = mul_hi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0x2a7fecb2u : 0x1d176220u); // s230 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r1 = r1 ^ t_; } // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + ((((sel >> 25u) & 1u) != 0u) ? 0xadce39f3u : 0x17dafb4du); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + ((((sel >> 29u) & 1u) != 0u) ? 0x0e7033b6u : 0xf2f77d26u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + ((((sel >> 31u) & 1u) != 0u) ? 0x7b2ff6b7u : 0xfed2da4eu); // s247 add + r0 = r0 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0xb5fad7b1u : 0x03b2891cu); // s248 add + r5 = mul_hi(r5, r4); // s249 mulhi + r5 = r5 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0xa7e71c2fu : 0x042cd6e3u); // s250 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 1u); r6 = r6 ^ t_; } // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0xb83d78deu : 0x784a302bu); // s254 add + r2 = r2 - r4; // s255 sub + } + } + 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 = r3 * r4 + r2; // 0 mad + r2 = r1 * r1 + r2; // 1 mad + r2 = r3 * r2 + r2; // 2 mad + r3 = r3 ^ r5; // 3 xor + r7 = r7 ^ ds[r2 & mask]; // 4 load + r5 = r5 ^ ds[r7 & mask]; // 5 load + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r1 = r1 ^ t_; } // 6 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r7 = r7 ^ t_; } // 7 shfl + r1 = mul_hi(r1, r5); // 8 mulhi + r6 = rotr_var(r6, r3); // 9 rotr + r3 = r3 | r4; // 10 or + r4 = r4 ^ ds[r3 & mask]; // 11 load + r0 = mul_hi(r0, r4); // 12 mulhi + r5 = r5 + r1 + ((((sel >> 30u) & 1u) != 0u) ? 0xd3177981u : 0xc7934706u); // 13 add + r0 = r0 ^ ds[r4 & mask]; // 14 load + r2 = r2 - r4; // 15 sub + r2 = r2 ^ ds[r0 & mask]; // 16 load + r7 = r7 ^ ds[r2 & mask]; // 17 load + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r7 = r7 ^ t_; } // 18 shfl + r5 = r5 * r0; // 19 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // 20 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 16u); r2 = r2 ^ t_; } // 21 shfl + r6 = mul_hi(r6, r2); // 22 mulhi + r6 = r6 ^ ds[r1 & mask]; // 23 load + r5 = r5 * r0; // 24 mul + r5 = rotl_imm(r5, 19u); // 25 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 2u); r7 = r7 ^ t_; } // 26 shfl + r0 = r0 ^ r5; // 27 xor + r0 = r0 ^ r4; // 28 xor + r3 = r3 - r0; // 29 sub + r5 = r5 * r1; // 30 mul + r7 = r7 ^ ds[r2 & mask]; // 31 load + r1 = r1 ^ ds[r0 & mask]; // 32 load + r5 = r5 ^ r6; // 33 xor + r5 = r5 ^ ds[r1 & mask]; // 34 load + r0 = mul_hi(r0, r5); // 35 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r5 = r5 ^ t_; } // 36 shfl + r7 = r7 ^ ds[r0 & mask]; // 37 load + r3 = r3 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0x230c005cu : 0x75ba2fadu); // 38 add + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 4u); r1 = r1 ^ t_; } // 39 shfl + r2 = r2 ^ r5; // 40 xor + r3 = r6 * r3 + r3; // 41 mad + r6 = r6 - r7; // 42 sub + r7 = r7 ^ r0; // 43 xor + r1 = r1 ^ ds[r7 & mask]; // 44 load + r2 = r2 * r3; // 45 mul + r1 = mul_hi(r1, r5); // 46 mulhi + r4 = r4 - r3; // 47 sub + r2 = rotr_var(r2, r6); // 48 rotr + r3 = r3 ^ ds[r5 & mask]; // 49 load + r1 = r1 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x1907970cu : 0x81b8bc2cu); // 50 add + r0 = r0 * r2; // 51 mul + r0 = r0 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x699fd448u : 0x4f92b968u); // 52 add + r1 = r1 + r0 + ((((sel >> 12u) & 1u) != 0u) ? 0x77b1520du : 0x2bb965afu); // 53 add + r7 = rotl_imm(r7, 14u); // 54 rotl + r3 = r3 + r7 + ((((sel >> 1u) & 1u) != 0u) ? 0xa54c55a0u : 0x7b0fe07au); // 55 add + r6 = r6 ^ ds[r7 & mask]; // 56 load + r1 = rotr_var(r1, r5); // 57 rotr + r5 = r5 ^ ds[r4 & mask]; // 58 load + r6 = r6 ^ ds[r2 & mask]; // 59 load + r3 = r5 * r0 + r3; // 60 mad + r5 = r5 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0xad7493e7u : 0xaf9dd72du); // 61 add + r4 = r4 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x1e07c3d9u : 0x89841d87u); // 62 add + r5 = rotl_imm(r5, 19u); // 63 rotl + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 13 passes after instruction 63, no load + for (uint sh = 0u; sh < 13u; ++sh) { + r5 = r5 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x8bc12da9u : 0x92199f99u); // s0 add + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x63079e5au : 0x8d72d3adu); // s1 add + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 2u); r6 = r6 ^ t_; } // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + ((((sel >> 31u) & 1u) != 0u) ? 0x5d4c7a60u : 0xb21b4babu); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + ((((sel >> 16u) & 1u) != 0u) ? 0xc88e2942u : 0x2fe0e98bu); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r6 = r6 ^ t_; } // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 4u); r2 = r2 ^ t_; } // s12 shfl + r1 = r1 + r5 + ((((sel >> 25u) & 1u) != 0u) ? 0xbc48c63eu : 0xbdf8f9a5u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r2 = r2 ^ t_; } // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + ((((sel >> 1u) & 1u) != 0u) ? 0x96e8f127u : 0x45c37cecu); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = mul_hi(r6, r0); // s28 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r2 = r2 ^ t_; } // s29 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r1 = r1 ^ t_; } // s30 shfl + r1 = r1 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0xb1cdb2abu : 0x37985632u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // s33 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r0 = r0 ^ t_; } // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x856e0180u : 0x804e777eu); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xe9bd0cc4u : 0x0b06c8a7u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = mul_hi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = mul_hi(r4, r3); // s44 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xcdcb63f6u : 0xee822e17u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r4 = r4 ^ t_; } // s47 shfl + r6 = mul_hi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0xd4758987u : 0x3dfad1b6u); // s56 add + r4 = r4 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x0602d6beu : 0xfca75bc2u); // s57 add + r5 = mul_hi(r5, r6); // s58 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r2 = r2 ^ t_; } // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0x8596687au : 0xd71c02ffu); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 2u); r7 = r7 ^ t_; } // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0x08ac5733u : 0x3c6fe15du); // s72 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r3 = r3 ^ t_; } // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + ((((sel >> 1u) & 1u) != 0u) ? 0xc100b495u : 0x295d5faeu); // s77 add + r3 = mul_hi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + ((((sel >> 15u) & 1u) != 0u) ? 0x5cc59530u : 0x274a9221u); // s81 add + r7 = r7 + r3 + ((((sel >> 5u) & 1u) != 0u) ? 0x141479ecu : 0xc8651f8eu); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r2 = r2 ^ t_; } // s85 shfl + r3 = r3 ^ r2; // s86 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 2u); r5 = r5 ^ t_; } // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x883c0c92u : 0x53f915c2u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + ((((sel >> 31u) & 1u) != 0u) ? 0x3cc5bd20u : 0xe2be00a5u); // s91 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 1u); r7 = r7 ^ t_; } // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + ((((sel >> 17u) & 1u) != 0u) ? 0xbfd646cbu : 0x423fd9c9u); // s101 add + r7 = r7 + r6 + ((((sel >> 11u) & 1u) != 0u) ? 0x19b74a43u : 0x8d3c011du); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + ((((sel >> 15u) & 1u) != 0u) ? 0x7dcb7e18u : 0x8ce14721u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = mul_hi(r2, r0); // s109 mulhi + r1 = mul_hi(r1, r0); // s110 mulhi + r0 = r0 + r2 + ((((sel >> 28u) & 1u) != 0u) ? 0x3c179ad8u : 0x2d9fc6b9u); // s111 add + r2 = mul_hi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + ((((sel >> 22u) & 1u) != 0u) ? 0x47359729u : 0x502138e2u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = mul_hi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 2u); r4 = r4 ^ t_; } // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r7 = r7 ^ t_; } // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x6c57e4e7u : 0x33dff776u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + ((((sel >> 30u) & 1u) != 0u) ? 0xe8212c0cu : 0x5db25b34u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = mul_hi(r0, r5); // s138 mulhi + r2 = r2 + r7 + ((((sel >> 10u) & 1u) != 0u) ? 0xd44ff710u : 0x218d4090u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r3 = r3 ^ t_; } // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + ((((sel >> 29u) & 1u) != 0u) ? 0xb98942fau : 0xf4b1a8deu); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + ((((sel >> 17u) & 1u) != 0u) ? 0x0d48ba42u : 0x2bef10f2u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + ((((sel >> 30u) & 1u) != 0u) ? 0xc98dea9cu : 0xdc5cc080u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0x6c752dcbu : 0x18197438u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + ((((sel >> 3u) & 1u) != 0u) ? 0x8e481727u : 0xf1c46574u); // s163 add + r0 = mul_hi(r0, r4); // s164 mulhi + r2 = r2 + r6 + ((((sel >> 20u) & 1u) != 0u) ? 0x550ab406u : 0xac578137u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + ((((sel >> 14u) & 1u) != 0u) ? 0xaebb5966u : 0xa33e6706u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 8u); r7 = r7 ^ t_; } // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x5bb7550fu : 0xd94d55acu); // s184 add + r3 = r3 | r5; // s185 or + r6 = mul_hi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r7 = r7 ^ t_; } // s188 shfl + r6 = r6 + r5 + ((((sel >> 6u) & 1u) != 0u) ? 0x2a354e2du : 0x89e747feu); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = mul_hi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r4 = r4 ^ t_; } // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + ((((sel >> 7u) & 1u) != 0u) ? 0x10cfdc71u : 0xea03e8e7u); // s197 add + r7 = r7 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x66e148d3u : 0xa7ee0102u); // s198 add + r5 = r5 - r2; // s199 sub + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r5 = r5 ^ t_; } // s200 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 8u); r7 = r7 ^ t_; } // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0x8558b619u : 0x8379a4deu); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = mul_hi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 4u); r2 = r2 ^ t_; } // s209 shfl + r7 = r7 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0xf4049c4cu : 0xaa8cb14eu); // s210 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 16u); r7 = r7 ^ t_; } // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 16u); r3 = r3 ^ t_; } // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = mul_hi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r5 = r5 ^ t_; } // s222 shfl + r5 = mul_hi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0x2a7fecb2u : 0x1d176220u); // s230 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r1 = r1 ^ t_; } // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + ((((sel >> 25u) & 1u) != 0u) ? 0xadce39f3u : 0x17dafb4du); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + ((((sel >> 29u) & 1u) != 0u) ? 0x0e7033b6u : 0xf2f77d26u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + ((((sel >> 31u) & 1u) != 0u) ? 0x7b2ff6b7u : 0xfed2da4eu); // s247 add + r0 = r0 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0xb5fad7b1u : 0x03b2891cu); // s248 add + r5 = mul_hi(r5, r4); // s249 mulhi + r5 = r5 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0xa7e71c2fu : 0x042cd6e3u); // s250 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 1u); r6 = r6 ^ t_; } // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0xb83d78deu : 0x784a302bu); // s254 add + r2 = r2 - r4; // s255 sub + } + } + uint lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((ulong)hi << 32) | (ulong)lo; +} diff --git a/proto-cuda/packs-ca3-shadow/sh256x13/kernel_bound.cu b/proto-cuda/packs-ca3-shadow/sh256x13/kernel_bound.cu new file mode 100644 index 000000000..905e46250 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x13/kernel_bound.cu @@ -0,0 +1,382 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Header-bound twin of igneum_hash in kernel.cu: the init words come from a kernel argument, not SEEDW. +// Host declarations (also in program_bound.h if present): +// struct IgneumInitWords { uint32_t w[8]; }; +// cudaError_t igneum_launch_hash_bound(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, +// IgneumInitWords iw, uint32_t nonces, uint32_t blockWarps); +// cudaError_t igneum_hash_bound_info(int* numRegs, int* blocksPerSM, uint32_t blockWarps); +#include +#include +#include "program.h" + +struct IgneumInitWords { uint32_t w[8]; }; + +__device__ __forceinline__ uint32_t splitmix32(uint32_t x) { + x ^= x >> 16; x *= 0x7feb352du; + x ^= x >> 15; x *= 0x846ca68bu; + x ^= x >> 16; + return x; +} +__device__ __forceinline__ uint32_t rotl_imm(uint32_t x, uint32_t n) { return (x << n) | (x >> (32u - n)); } +__device__ __forceinline__ uint32_t rotr_var(uint32_t x, uint32_t n) { n &= 31u; return (x >> n) | (x << ((32u - n) & 31u)); } + +__global__ void igneum_hash_bound(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, IgneumInitWords iw) { + uint32_t gid = blockIdx.x * blockDim.x + threadIdx.x; + uint32_t nonce = baseNonce + gid; + uint32_t r0, r1, r2, r3, r4, r5, r6, r7; + { uint32_t x = nonce ^ iw.w[0]; x += 0x9e3779b9u * 1u; x = splitmix32(x); r0 = x ^ iw.w[1]; } + { uint32_t x = nonce ^ iw.w[1]; x += 0x9e3779b9u * 2u; x = splitmix32(x); r1 = x ^ iw.w[2]; } + { uint32_t x = nonce ^ iw.w[2]; x += 0x9e3779b9u * 3u; x = splitmix32(x); r2 = x ^ iw.w[3]; } + { uint32_t x = nonce ^ iw.w[3]; x += 0x9e3779b9u * 4u; x = splitmix32(x); r3 = x ^ iw.w[4]; } + { uint32_t x = nonce ^ iw.w[4]; x += 0x9e3779b9u * 5u; x = splitmix32(x); r4 = x ^ iw.w[5]; } + { uint32_t x = nonce ^ iw.w[5]; x += 0x9e3779b9u * 6u; x = splitmix32(x); r5 = x ^ iw.w[6]; } + { uint32_t x = nonce ^ iw.w[6]; x += 0x9e3779b9u * 7u; x = splitmix32(x); r6 = x ^ iw.w[7]; } + { uint32_t x = nonce ^ iw.w[7]; x += 0x9e3779b9u * 8u; x = splitmix32(x); r7 = x ^ iw.w[0]; } + + for (uint32_t it = 0u; it < 8u; ++it) { + uint32_t sel = r0; + r2 = r3 * r4 + r2; // 0 mad + r2 = r1 * r1 + r2; // 1 mad + r2 = r3 * r2 + r2; // 2 mad + r3 = r3 ^ r5; // 3 xor + r7 = r7 ^ ds[r2 & mask]; // 4 load + r5 = r5 ^ ds[r7 & mask]; // 5 load + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r4, 8); // 6 shfl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r3, 8); // 7 shfl + r1 = __umulhi(r1, r5); // 8 mulhi + r6 = rotr_var(r6, r3); // 9 rotr + r3 = r3 | r4; // 10 or + r4 = r4 ^ ds[r3 & mask]; // 11 load + r0 = __umulhi(r0, r4); // 12 mulhi + r5 = r5 + r1 + ((((sel >> 30u) & 1u) != 0u) ? 0xd3177981u : 0xc7934706u); // 13 add + r0 = r0 ^ ds[r4 & mask]; // 14 load + r2 = r2 - r4; // 15 sub + r2 = r2 ^ ds[r0 & mask]; // 16 load + r7 = r7 ^ ds[r2 & mask]; // 17 load + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r3, 4); // 18 shfl + r5 = r5 * r0; // 19 mul + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // 20 shfl + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 16); // 21 shfl + r6 = __umulhi(r6, r2); // 22 mulhi + r6 = r6 ^ ds[r1 & mask]; // 23 load + r5 = r5 * r0; // 24 mul + r5 = rotl_imm(r5, 19u); // 25 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r6, 2); // 26 shfl + r0 = r0 ^ r5; // 27 xor + r0 = r0 ^ r4; // 28 xor + r3 = r3 - r0; // 29 sub + r5 = r5 * r1; // 30 mul + r7 = r7 ^ ds[r2 & mask]; // 31 load + r1 = r1 ^ ds[r0 & mask]; // 32 load + r5 = r5 ^ r6; // 33 xor + r5 = r5 ^ ds[r1 & mask]; // 34 load + r0 = __umulhi(r0, r5); // 35 mulhi + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // 36 shfl + r7 = r7 ^ ds[r0 & mask]; // 37 load + r3 = r3 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0x230c005cu : 0x75ba2fadu); // 38 add + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r5, 4); // 39 shfl + r2 = r2 ^ r5; // 40 xor + r3 = r6 * r3 + r3; // 41 mad + r6 = r6 - r7; // 42 sub + r7 = r7 ^ r0; // 43 xor + r1 = r1 ^ ds[r7 & mask]; // 44 load + r2 = r2 * r3; // 45 mul + r1 = __umulhi(r1, r5); // 46 mulhi + r4 = r4 - r3; // 47 sub + r2 = rotr_var(r2, r6); // 48 rotr + r3 = r3 ^ ds[r5 & mask]; // 49 load + r1 = r1 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x1907970cu : 0x81b8bc2cu); // 50 add + r0 = r0 * r2; // 51 mul + r0 = r0 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x699fd448u : 0x4f92b968u); // 52 add + r1 = r1 + r0 + ((((sel >> 12u) & 1u) != 0u) ? 0x77b1520du : 0x2bb965afu); // 53 add + r7 = rotl_imm(r7, 14u); // 54 rotl + r3 = r3 + r7 + ((((sel >> 1u) & 1u) != 0u) ? 0xa54c55a0u : 0x7b0fe07au); // 55 add + r6 = r6 ^ ds[r7 & mask]; // 56 load + r1 = rotr_var(r1, r5); // 57 rotr + r5 = r5 ^ ds[r4 & mask]; // 58 load + r6 = r6 ^ ds[r2 & mask]; // 59 load + r3 = r5 * r0 + r3; // 60 mad + r5 = r5 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0xad7493e7u : 0xaf9dd72du); // 61 add + r4 = r4 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x1e07c3d9u : 0x89841d87u); // 62 add + r5 = rotl_imm(r5, 19u); // 63 rotl + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 13 passes after instruction 63, no load + for (uint32_t sh = 0u; sh < 13u; ++sh) { + r5 = r5 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x8bc12da9u : 0x92199f99u); // s0 add + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x63079e5au : 0x8d72d3adu); // s1 add + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r3, 2); // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + ((((sel >> 31u) & 1u) != 0u) ? 0x5d4c7a60u : 0xb21b4babu); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + ((((sel >> 16u) & 1u) != 0u) ? 0xc88e2942u : 0x2fe0e98bu); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r1, 4); // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r6, 4); // s12 shfl + r1 = r1 + r5 + ((((sel >> 25u) & 1u) != 0u) ? 0xbc48c63eu : 0xbdf8f9a5u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 8); // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + ((((sel >> 1u) & 1u) != 0u) ? 0x96e8f127u : 0x45c37cecu); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = __umulhi(r6, r0); // s28 mulhi + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // s29 shfl + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r6, 1); // s30 shfl + r1 = r1 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0xb1cdb2abu : 0x37985632u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // s33 shfl + r0 = r0 ^ __shfl_xor_sync(0xffffffffu, r3, 4); // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x856e0180u : 0x804e777eu); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xe9bd0cc4u : 0x0b06c8a7u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = __umulhi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = __umulhi(r4, r3); // s44 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xcdcb63f6u : 0xee822e17u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r3, 8); // s47 shfl + r6 = __umulhi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0xd4758987u : 0x3dfad1b6u); // s56 add + r4 = r4 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x0602d6beu : 0xfca75bc2u); // s57 add + r5 = __umulhi(r5, r6); // s58 mulhi + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0x8596687au : 0xd71c02ffu); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r5, 2); // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0x08ac5733u : 0x3c6fe15du); // s72 add + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r2, 8); // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + ((((sel >> 1u) & 1u) != 0u) ? 0xc100b495u : 0x295d5faeu); // s77 add + r3 = __umulhi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + ((((sel >> 15u) & 1u) != 0u) ? 0x5cc59530u : 0x274a9221u); // s81 add + r7 = r7 + r3 + ((((sel >> 5u) & 1u) != 0u) ? 0x141479ecu : 0xc8651f8eu); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r5, 16); // s85 shfl + r3 = r3 ^ r2; // s86 xor + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r7, 2); // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x883c0c92u : 0x53f915c2u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + ((((sel >> 31u) & 1u) != 0u) ? 0x3cc5bd20u : 0xe2be00a5u); // s91 add + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r2, 1); // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + ((((sel >> 17u) & 1u) != 0u) ? 0xbfd646cbu : 0x423fd9c9u); // s101 add + r7 = r7 + r6 + ((((sel >> 11u) & 1u) != 0u) ? 0x19b74a43u : 0x8d3c011du); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + ((((sel >> 15u) & 1u) != 0u) ? 0x7dcb7e18u : 0x8ce14721u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = __umulhi(r2, r0); // s109 mulhi + r1 = __umulhi(r1, r0); // s110 mulhi + r0 = r0 + r2 + ((((sel >> 28u) & 1u) != 0u) ? 0x3c179ad8u : 0x2d9fc6b9u); // s111 add + r2 = __umulhi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + ((((sel >> 22u) & 1u) != 0u) ? 0x47359729u : 0x502138e2u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = __umulhi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r2, 2); // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x6c57e4e7u : 0x33dff776u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + ((((sel >> 30u) & 1u) != 0u) ? 0xe8212c0cu : 0x5db25b34u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = __umulhi(r0, r5); // s138 mulhi + r2 = r2 + r7 + ((((sel >> 10u) & 1u) != 0u) ? 0xd44ff710u : 0x218d4090u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r6, 1); // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + ((((sel >> 29u) & 1u) != 0u) ? 0xb98942fau : 0xf4b1a8deu); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + ((((sel >> 17u) & 1u) != 0u) ? 0x0d48ba42u : 0x2bef10f2u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + ((((sel >> 30u) & 1u) != 0u) ? 0xc98dea9cu : 0xdc5cc080u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0x6c752dcbu : 0x18197438u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + ((((sel >> 3u) & 1u) != 0u) ? 0x8e481727u : 0xf1c46574u); // s163 add + r0 = __umulhi(r0, r4); // s164 mulhi + r2 = r2 + r6 + ((((sel >> 20u) & 1u) != 0u) ? 0x550ab406u : 0xac578137u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + ((((sel >> 14u) & 1u) != 0u) ? 0xaebb5966u : 0xa33e6706u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r0, 8); // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x5bb7550fu : 0xd94d55acu); // s184 add + r3 = r3 | r5; // s185 or + r6 = __umulhi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s188 shfl + r6 = r6 + r5 + ((((sel >> 6u) & 1u) != 0u) ? 0x2a354e2du : 0x89e747feu); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = __umulhi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r5, 16); // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + ((((sel >> 7u) & 1u) != 0u) ? 0x10cfdc71u : 0xea03e8e7u); // s197 add + r7 = r7 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x66e148d3u : 0xa7ee0102u); // s198 add + r5 = r5 - r2; // s199 sub + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s200 shfl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 8); // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0x8558b619u : 0x8379a4deu); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = __umulhi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r0, 4); // s209 shfl + r7 = r7 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0xf4049c4cu : 0xaa8cb14eu); // s210 add + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 16); // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r2, 16); // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = __umulhi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r2, 8); // s222 shfl + r5 = __umulhi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0x2a7fecb2u : 0x1d176220u); // s230 add + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + ((((sel >> 25u) & 1u) != 0u) ? 0xadce39f3u : 0x17dafb4du); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + ((((sel >> 29u) & 1u) != 0u) ? 0x0e7033b6u : 0xf2f77d26u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + ((((sel >> 31u) & 1u) != 0u) ? 0x7b2ff6b7u : 0xfed2da4eu); // s247 add + r0 = r0 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0xb5fad7b1u : 0x03b2891cu); // s248 add + r5 = __umulhi(r5, r4); // s249 mulhi + r5 = r5 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0xa7e71c2fu : 0x042cd6e3u); // s250 add + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r1, 1); // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0xb83d78deu : 0x784a302bu); // s254 add + r2 = r2 - r4; // s255 sub + } + } + uint32_t lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint32_t hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((uint64_t)hi << 32) | (uint64_t)lo; +} + +cudaError_t igneum_launch_hash_bound(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, + IgneumInitWords iw, uint32_t nonces, uint32_t blockWarps) { + if (blockWarps == 0u || blockWarps > 32u) return cudaErrorInvalidValue; + uint32_t block = 32u * blockWarps; + if (nonces == 0u || (nonces % block) != 0u) return cudaErrorInvalidValue; + igneum_hash_bound<<>>(ds, out, baseNonce, mask, iw); + return cudaGetLastError(); +} + +cudaError_t igneum_hash_bound_info(int* numRegs, int* blocksPerSM, uint32_t blockWarps) { + cudaFuncAttributes attr; + cudaError_t e = cudaFuncGetAttributes(&attr, igneum_hash_bound); + if (e != cudaSuccess) return e; + *numRegs = attr.numRegs; + return cudaOccupancyMaxActiveBlocksPerMultiprocessor(blocksPerSM, igneum_hash_bound, (int)(32u * blockWarps), 0); +} diff --git a/proto-cuda/packs-ca3-shadow/sh256x13/memhard.h b/proto-cuda/packs-ca3-shadow/sh256x13/memhard.h new file mode 100644 index 000000000..f7f34c732 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x13/memhard.h @@ -0,0 +1,109 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Memory-hard dataset core, the same text that the Mac's Metal kernels and CPU verifier were checked against. +// Included by kernel.cu (device), host.cu (host reference) and proto-opencl/host.c (C99 host reference). +// See proto-metal/MEMHARD.md for the construction. kernel.cl carries the same text in OpenCL C. +#pragma once +#ifdef __cplusplus +#include +#else +#include +#endif +#if defined(__CUDACC__) +#define IGNEUM_HD __host__ __device__ __forceinline__ +#elif defined(_MSC_VER) && !defined(__cplusplus) +#define IGNEUM_HD static __inline +#else +#define IGNEUM_HD static inline +#endif +// Memory-hard dataset core (MEMHARD.md). Cache: 2^26 words in 2^16 segments of 64 chained ChaCha12 lines. +// Item: 8 rounds of 8 x seed-parameterised mixer + one 64-byte cache read, then 8 x final mixer (class v3, mixer multiplier 8, +// docs/plans/mixer-x4.md: the round key of application j of round r is 0x9E3779B9 * (r * m + j + 1)). All parameters are literals. +#define MH_CACHE_LINE_MASK 0x003fffffu +#define MH_SEGMENT_LINES 64u +#define MH_QR(a, b, c, d, r1, r2, r3, r4) { a += b; d ^= a; d = mh_rotl(d, r1); c += d; b ^= c; b = mh_rotl(b, r2); a += b; d ^= a; d = mh_rotl(d, r3); c += d; b ^= c; b = mh_rotl(b, r4); } +IGNEUM_HD uint32_t mh_rotl(uint32_t x, uint32_t n) { return (x << n) | (x >> (32u - n)); } // n in 1..31 at every call site + +// y = ChaCha12 core(x) + x +IGNEUM_HD void mh_chacha_block(const uint32_t* x, uint32_t* y) { + for (uint32_t i = 0u; i < 16u; ++i) y[i] = x[i]; + for (uint32_t r = 0u; r < 6u; ++r) { + MH_QR(y[0], y[4], y[8], y[12], 16u, 12u, 8u, 7u) MH_QR(y[1], y[5], y[9], y[13], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[6], y[10], y[14], 16u, 12u, 8u, 7u) MH_QR(y[3], y[7], y[11], y[15], 16u, 12u, 8u, 7u) + MH_QR(y[0], y[5], y[10], y[15], 16u, 12u, 8u, 7u) MH_QR(y[1], y[6], y[11], y[12], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[7], y[8], y[13], 16u, 12u, 8u, 7u) MH_QR(y[3], y[4], y[9], y[14], 16u, 12u, 8u, 7u) + } + for (uint32_t i = 0u; i < 16u; ++i) y[i] += x[i]; +} + +// One cache segment: 64 chained lines written at cache[seg * 1024]. in_j = prev ^ (sigma || K || seg || j || tag), prev_0 = 0. +IGNEUM_HD void mh_cache_segment(uint32_t* cache, uint32_t seg) { + uint32_t prev[16]; uint32_t x[16]; uint32_t y[16]; + for (uint32_t i = 0u; i < 16u; ++i) prev[i] = 0u; + for (uint32_t j = 0u; j < MH_SEGMENT_LINES; ++j) { + x[0] = 0x61707865u ^ prev[0]; x[1] = 0x3320646eu ^ prev[1]; x[2] = 0x79622d32u ^ prev[2]; x[3] = 0x6b206574u ^ prev[3]; + x[4] = 0x3067619fu ^ prev[4]; + x[5] = 0x3c269176u ^ prev[5]; + x[6] = 0x84a03b03u ^ prev[6]; + x[7] = 0xf8c63294u ^ prev[7]; + x[8] = 0xff977c5bu ^ prev[8]; + x[9] = 0xe60def3eu ^ prev[9]; + x[10] = 0x63630141u ^ prev[10]; + x[11] = 0xb8fbcb58u ^ prev[11]; + x[12] = seg ^ prev[12]; x[13] = j ^ prev[13]; x[14] = 0x49676e65u ^ prev[14]; x[15] = 0x756d4d48u ^ prev[15]; + mh_chacha_block(x, y); + uint32_t* line = cache + ((seg * MH_SEGMENT_LINES + j) * 16u); + for (uint32_t i = 0u; i < 16u; ++i) { line[i] = y[i]; prev[i] = y[i]; } + } +} + +// M_r: per word (s ^ (RC + rk)) * MUL, then a column round and a diagonal round with the seed-drawn rotations. +IGNEUM_HD void mh_mixer(uint32_t* s, uint32_t rk) { + s[0] = (s[0] ^ (0xbab68293u + rk)) * 0x42146205u; + s[1] = (s[1] ^ (0xcc162340u + rk)) * 0x52cbe0fbu; + s[2] = (s[2] ^ (0x6ce151ccu + rk)) * 0x7ecf4a03u; + s[3] = (s[3] ^ (0xe62b8997u + rk)) * 0x6728907fu; + s[4] = (s[4] ^ (0xc9c80297u + rk)) * 0xd81d9751u; + s[5] = (s[5] ^ (0xf74a1654u + rk)) * 0x132952c3u; + s[6] = (s[6] ^ (0x3d704af5u + rk)) * 0xf60de277u; + s[7] = (s[7] ^ (0x3cf522b7u + rk)) * 0x05358035u; + s[8] = (s[8] ^ (0x2b9cac04u + rk)) * 0xbaf6499du; + s[9] = (s[9] ^ (0xa880ac10u + rk)) * 0xe4db9667u; + s[10] = (s[10] ^ (0x13e5dd1du + rk)) * 0x3e98f45du; + s[11] = (s[11] ^ (0x6fc3e233u + rk)) * 0xd0004eddu; + s[12] = (s[12] ^ (0x2d83eeacu + rk)) * 0x2691630du; + s[13] = (s[13] ^ (0x9006e8bfu + rk)) * 0x9beb3bcfu; + s[14] = (s[14] ^ (0x2c4b5362u + rk)) * 0xab310379u; + s[15] = (s[15] ^ (0x31b49ee2u + rk)) * 0x99cfb423u; + MH_QR(s[0], s[4], s[8], s[12], 20u, 20u, 19u, 4u) MH_QR(s[1], s[5], s[9], s[13], 20u, 20u, 19u, 4u) + MH_QR(s[2], s[6], s[10], s[14], 20u, 20u, 19u, 4u) MH_QR(s[3], s[7], s[11], s[15], 20u, 20u, 19u, 4u) + MH_QR(s[0], s[5], s[10], s[15], 26u, 3u, 3u, 27u) MH_QR(s[1], s[6], s[11], s[12], 26u, 3u, 3u, 27u) + MH_QR(s[2], s[7], s[8], s[13], 26u, 3u, 3u, 27u) MH_QR(s[3], s[4], s[9], s[14], 26u, 3u, 3u, 27u) +} + +// Item t: 16 words. s = (K, t * MUL[i] + RC[i]); 8 rounds of 8 x mixer + cache line s[0] & mask; 8 x final mixer. +IGNEUM_HD void mh_item(const uint32_t* cache, uint32_t t, uint32_t* s) { + s[0] = 0x3067619fu; + s[1] = 0x3c269176u; + s[2] = 0x84a03b03u; + s[3] = 0xf8c63294u; + s[4] = 0xff977c5bu; + s[5] = 0xe60def3eu; + s[6] = 0x63630141u; + s[7] = 0xb8fbcb58u; + s[8] = t * 0x42146205u + 0xbab68293u; + s[9] = t * 0x52cbe0fbu + 0xcc162340u; + s[10] = t * 0x7ecf4a03u + 0x6ce151ccu; + s[11] = t * 0x6728907fu + 0xe62b8997u; + s[12] = t * 0xd81d9751u + 0xc9c80297u; + s[13] = t * 0x132952c3u + 0xf74a1654u; + s[14] = t * 0xf60de277u + 0x3d704af5u; + s[15] = t * 0x05358035u + 0x3cf522b7u; + for (uint32_t r = 0u; r < 8u; ++r) { + for (uint32_t j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (r * 8u + j + 1u)); + const uint32_t* line = cache + ((s[0] & MH_CACHE_LINE_MASK) * 16u); + for (uint32_t i = 0u; i < 16u; ++i) s[i] ^= line[i]; + } + for (uint32_t j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (64u + j + 1u)); +} +// dataset[w] without the dataset: derive item w >> 4 and take word w & 15. +IGNEUM_HD uint32_t mh_word(const uint32_t* cache, uint32_t w) { uint32_t s[16]; mh_item(cache, w >> 4u, s); return s[w & 15u]; } diff --git a/proto-cuda/packs-ca3-shadow/sh256x13/memhard.metal b/proto-cuda/packs-ca3-shadow/sh256x13/memhard.metal new file mode 100644 index 000000000..01b263d6d --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x13/memhard.metal @@ -0,0 +1,107 @@ +#include +using namespace metal; +// Memory-hard dataset core (MEMHARD.md). Cache: 2^26 words in 2^16 segments of 64 chained ChaCha12 lines. +// Item: 8 rounds of 8 x seed-parameterised mixer + one 64-byte cache read, then 8 x final mixer (class v3, mixer multiplier 8, +// docs/plans/mixer-x4.md: the round key of application j of round r is 0x9E3779B9 * (r * m + j + 1)). All parameters are literals. +#define MH_CACHE_LINE_MASK 0x003fffffu +#define MH_SEGMENT_LINES 64u +#define MH_QR(a, b, c, d, r1, r2, r3, r4) { a += b; d ^= a; d = mh_rotl(d, r1); c += d; b ^= c; b = mh_rotl(b, r2); a += b; d ^= a; d = mh_rotl(d, r3); c += d; b ^= c; b = mh_rotl(b, r4); } +inline uint mh_rotl(uint x, uint n) { return (x << n) | (x >> (32u - n)); } // n in 1..31 at every call site + +// y = ChaCha12 core(x) + x +inline void mh_chacha_block(const thread uint* x, thread uint* y) { + for (uint i = 0u; i < 16u; ++i) y[i] = x[i]; + for (uint r = 0u; r < 6u; ++r) { + MH_QR(y[0], y[4], y[8], y[12], 16u, 12u, 8u, 7u) MH_QR(y[1], y[5], y[9], y[13], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[6], y[10], y[14], 16u, 12u, 8u, 7u) MH_QR(y[3], y[7], y[11], y[15], 16u, 12u, 8u, 7u) + MH_QR(y[0], y[5], y[10], y[15], 16u, 12u, 8u, 7u) MH_QR(y[1], y[6], y[11], y[12], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[7], y[8], y[13], 16u, 12u, 8u, 7u) MH_QR(y[3], y[4], y[9], y[14], 16u, 12u, 8u, 7u) + } + for (uint i = 0u; i < 16u; ++i) y[i] += x[i]; +} + +// One cache segment: 64 chained lines written at cache[seg * 1024]. in_j = prev ^ (sigma || K || seg || j || tag), prev_0 = 0. +inline void mh_cache_segment(device uint* cache, uint seg) { + uint prev[16]; uint x[16]; uint y[16]; + for (uint i = 0u; i < 16u; ++i) prev[i] = 0u; + for (uint j = 0u; j < MH_SEGMENT_LINES; ++j) { + x[0] = 0x61707865u ^ prev[0]; x[1] = 0x3320646eu ^ prev[1]; x[2] = 0x79622d32u ^ prev[2]; x[3] = 0x6b206574u ^ prev[3]; + x[4] = 0x3067619fu ^ prev[4]; + x[5] = 0x3c269176u ^ prev[5]; + x[6] = 0x84a03b03u ^ prev[6]; + x[7] = 0xf8c63294u ^ prev[7]; + x[8] = 0xff977c5bu ^ prev[8]; + x[9] = 0xe60def3eu ^ prev[9]; + x[10] = 0x63630141u ^ prev[10]; + x[11] = 0xb8fbcb58u ^ prev[11]; + x[12] = seg ^ prev[12]; x[13] = j ^ prev[13]; x[14] = 0x49676e65u ^ prev[14]; x[15] = 0x756d4d48u ^ prev[15]; + mh_chacha_block(x, y); + device uint* line = cache + ((seg * MH_SEGMENT_LINES + j) * 16u); + for (uint i = 0u; i < 16u; ++i) { line[i] = y[i]; prev[i] = y[i]; } + } +} + +// M_r: per word (s ^ (RC + rk)) * MUL, then a column round and a diagonal round with the seed-drawn rotations. +inline void mh_mixer(thread uint* s, uint rk) { + s[0] = (s[0] ^ (0xbab68293u + rk)) * 0x42146205u; + s[1] = (s[1] ^ (0xcc162340u + rk)) * 0x52cbe0fbu; + s[2] = (s[2] ^ (0x6ce151ccu + rk)) * 0x7ecf4a03u; + s[3] = (s[3] ^ (0xe62b8997u + rk)) * 0x6728907fu; + s[4] = (s[4] ^ (0xc9c80297u + rk)) * 0xd81d9751u; + s[5] = (s[5] ^ (0xf74a1654u + rk)) * 0x132952c3u; + s[6] = (s[6] ^ (0x3d704af5u + rk)) * 0xf60de277u; + s[7] = (s[7] ^ (0x3cf522b7u + rk)) * 0x05358035u; + s[8] = (s[8] ^ (0x2b9cac04u + rk)) * 0xbaf6499du; + s[9] = (s[9] ^ (0xa880ac10u + rk)) * 0xe4db9667u; + s[10] = (s[10] ^ (0x13e5dd1du + rk)) * 0x3e98f45du; + s[11] = (s[11] ^ (0x6fc3e233u + rk)) * 0xd0004eddu; + s[12] = (s[12] ^ (0x2d83eeacu + rk)) * 0x2691630du; + s[13] = (s[13] ^ (0x9006e8bfu + rk)) * 0x9beb3bcfu; + s[14] = (s[14] ^ (0x2c4b5362u + rk)) * 0xab310379u; + s[15] = (s[15] ^ (0x31b49ee2u + rk)) * 0x99cfb423u; + MH_QR(s[0], s[4], s[8], s[12], 20u, 20u, 19u, 4u) MH_QR(s[1], s[5], s[9], s[13], 20u, 20u, 19u, 4u) + MH_QR(s[2], s[6], s[10], s[14], 20u, 20u, 19u, 4u) MH_QR(s[3], s[7], s[11], s[15], 20u, 20u, 19u, 4u) + MH_QR(s[0], s[5], s[10], s[15], 26u, 3u, 3u, 27u) MH_QR(s[1], s[6], s[11], s[12], 26u, 3u, 3u, 27u) + MH_QR(s[2], s[7], s[8], s[13], 26u, 3u, 3u, 27u) MH_QR(s[3], s[4], s[9], s[14], 26u, 3u, 3u, 27u) +} + +// Item t: 16 words. s = (K, t * MUL[i] + RC[i]); 8 rounds of 8 x mixer + cache line s[0] & mask; 8 x final mixer. +inline void mh_item(device const uint* cache, uint t, thread uint* s) { + s[0] = 0x3067619fu; + s[1] = 0x3c269176u; + s[2] = 0x84a03b03u; + s[3] = 0xf8c63294u; + s[4] = 0xff977c5bu; + s[5] = 0xe60def3eu; + s[6] = 0x63630141u; + s[7] = 0xb8fbcb58u; + s[8] = t * 0x42146205u + 0xbab68293u; + s[9] = t * 0x52cbe0fbu + 0xcc162340u; + s[10] = t * 0x7ecf4a03u + 0x6ce151ccu; + s[11] = t * 0x6728907fu + 0xe62b8997u; + s[12] = t * 0xd81d9751u + 0xc9c80297u; + s[13] = t * 0x132952c3u + 0xf74a1654u; + s[14] = t * 0xf60de277u + 0x3d704af5u; + s[15] = t * 0x05358035u + 0x3cf522b7u; + for (uint r = 0u; r < 8u; ++r) { + for (uint j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (r * 8u + j + 1u)); + device const uint* line = cache + ((s[0] & MH_CACHE_LINE_MASK) * 16u); + for (uint i = 0u; i < 16u; ++i) s[i] ^= line[i]; + } + for (uint j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (64u + j + 1u)); +} +// dataset[w] without the dataset: derive item w >> 4 and take word w & 15. +inline uint mh_word(device const uint* cache, uint w) { uint s[16]; mh_item(cache, w >> 4u, s); return s[w & 15u]; } + +// One thread per segment (2^16 threads). +kernel void igneum_cache_fill(device uint* cache [[buffer(0)]], uint gid [[thread_position_in_grid]]) { + mh_cache_segment(cache, gid); +} +// One thread per 64-byte item (dataset words / 16 threads). +kernel void igneum_build(device const uint* cache [[buffer(0)]], device uint* dataset [[buffer(1)]], + uint gid [[thread_position_in_grid]]) { + uint s[16]; + mh_item(cache, gid, s); + device uint* d = dataset + gid * 16u; + for (uint i = 0u; i < 16u; ++i) d[i] = s[i]; +} diff --git a/proto-cuda/packs-ca3-shadow/sh256x13/program.h b/proto-cuda/packs-ca3-shadow/sh256x13/program.h new file mode 100644 index 000000000..ab3bd0b74 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x13/program.h @@ -0,0 +1,70 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Program metadata for host.cu plus the launch wrappers defined in kernel.cu. +// Also included by proto-opencl/host.c (C99), which defines IGNEUM_NO_CUDA first and reads only the macros. +#pragma once +#ifdef __cplusplus +#include +#else +#include +#endif +#ifndef IGNEUM_NO_CUDA +#include +#endif + +#define IGNEUM_SEED_STRING "igneum-genesis" +#define IGNEUM_SEED_BYTES_HEX "69676e65756d2d67656e65736973" +#define IGNEUM_GENERATOR 2 +#define IGNEUM_PROGRAM_ATTEMPT 0 +#define IGNEUM_PROGRAM_ID 0x9a5be3853b011f6cull +#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 add=8 shfl=8 xor=6 mad=5 mul=5 mulhi=5 sub=4 rotl=3 rotr=3 or=1" +// 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+sh256x13" +#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 13 +#define IGNEUM_SHADOW_INSTRS_PER_HASH 26624 +#define IGNEUM_SHADOW_OP_MIX "add=47 rotl=30 xor=30 shfl=29 mad=27 mul=22 sub=21 rotr=20 mulhi=18 or=12" +// 0 = closed-form dataset (ds_elem), 1 = memory-hard cache construction (MEMHARD.md, memhard.h) +#define IGNEUM_DATASET_MODE 1 + +#define IGNEUM_SEEDW_INIT { 0x67a9a7beu, 0x1a155b25u, 0xfddfb732u, 0x4b5af2e8u, 0xc55caf33u, 0xa27c13b7u, 0x06628a48u, 0x03852469u } +#define IGNEUM_KEY_INIT { 0x3067619fu, 0x3c269176u, 0x84a03b03u, 0xf8c63294u, 0xff977c5bu, 0xe60def3eu, 0x63630141u, 0xb8fbcb58u } +#define IGNEUM_CACHE_LOG2_WORDS 26 +#define IGNEUM_CACHE_SEGMENT_LOG2_LINES 6 +#define IGNEUM_CACHE_SEGMENTS 65536u +#define IGNEUM_ITEM_ROUNDS 8 +#define IGNEUM_MIXER_MULT 8 // mixer applications per round and after the last read (class v3, docs/plans/mixer-x4.md) +#define IGNEUM_MIX_ROT_INIT { 20u, 20u, 19u, 4u, 26u, 3u, 3u, 27u } +#define IGNEUM_MIX_MUL_INIT { 0x42146205u, 0x52cbe0fbu, 0x7ecf4a03u, 0x6728907fu, 0xd81d9751u, 0x132952c3u, 0xf60de277u, 0x05358035u, 0xbaf6499du, 0xe4db9667u, 0x3e98f45du, 0xd0004eddu, 0x2691630du, 0x9beb3bcfu, 0xab310379u, 0x99cfb423u } +#define IGNEUM_MIX_RC_INIT { 0xbab68293u, 0xcc162340u, 0x6ce151ccu, 0xe62b8997u, 0xc9c80297u, 0xf74a1654u, 0x3d704af5u, 0x3cf522b7u, 0x2b9cac04u, 0xa880ac10u, 0x13e5dd1du, 0x6fc3e233u, 0x2d83eeacu, 0x9006e8bfu, 0x2c4b5362u, 0x31b49ee2u } + +#ifndef IGNEUM_NO_CUDA +// Defined in kernel.cu. All launch on the default stream and return cudaGetLastError(). +cudaError_t igneum_launch_cache_fill(uint32_t* cache, uint32_t nSegments); +cudaError_t igneum_launch_build(uint32_t* ds, const uint32_t* cache, uint32_t nItems); +cudaError_t igneum_launch_hash(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, + uint32_t nonces, uint32_t blockWarps); +cudaError_t igneum_hash_info(int* numRegs, int* blocksPerSM, uint32_t blockWarps); +#endif diff --git a/proto-cuda/packs-ca3-shadow/sh256x13/program.json b/proto-cuda/packs-ca3-shadow/sh256x13/program.json new file mode 100644 index 000000000..6042bbe0d --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x13/program.json @@ -0,0 +1,389 @@ +{ + "format": "igneum-program-pack-3", + "generator": 2, + "attempt": 0, + "program_id": "0x9a5be3853b011f6c", + "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": ["0x67a9a7be", "0x1a155b25", "0xfddfb732", "0x4b5af2e8", "0xc55caf33", "0xa27c13b7", "0x06628a48", "0x03852469"], + "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+sh256x13", + "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, "add": 8, "shfl": 8, "xor": 6, "mad": 5, "mul": 5, "mulhi": 5, "sub": 4, "rotl": 3, "rotr": 3, "or": 1}, + "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": 13, "instrs_per_hash": 26624, "op_mix": {"add": 47, "rotl": 30, "xor": 30, "shfl": 29, "mad": 27, "mul": 22, "sub": 21, "rotr": 20, "mulhi": 18, "or": 12}, "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": "add", "dst": 5, "src": 2, "src2": 1, "imm": "0x92199f99", "imm2": "0x8bc12da9", "rot": 9, "bit": 18, "mask": 4}, + {"i": 1, "op": "add", "dst": 0, "src": 7, "src2": 1, "imm": "0x8d72d3ad", "imm2": "0x63079e5a", "rot": 20, "bit": 26, "mask": 4}, + {"i": 2, "op": "shfl", "dst": 6, "src": 3, "src2": 6, "imm": "0x9beaeddf", "imm2": "0x744ecb00", "rot": 10, "bit": 4, "mask": 2}, + {"i": 3, "op": "sub", "dst": 4, "src": 2, "src2": 0, "imm": "0x2a3ddc67", "imm2": "0x72c80241", "rot": 30, "bit": 1, "mask": 16}, + {"i": 4, "op": "add", "dst": 7, "src": 0, "src2": 5, "imm": "0xb21b4bab", "imm2": "0x5d4c7a60", "rot": 17, "bit": 31, "mask": 4}, + {"i": 5, "op": "rotl", "dst": 0, "src": 6, "src2": 3, "imm": "0xe69d7919", "imm2": "0xa048c61e", "rot": 11, "bit": 1, "mask": 8}, + {"i": 6, "op": "add", "dst": 0, "src": 1, "src2": 3, "imm": "0x2fe0e98b", "imm2": "0xc88e2942", "rot": 5, "bit": 16, "mask": 16}, + {"i": 7, "op": "xor", "dst": 7, "src": 1, "src2": 0, "imm": "0xc16efe98", "imm2": "0x01a638c8", "rot": 8, "bit": 17, "mask": 1}, + {"i": 8, "op": "mad", "dst": 1, "src": 6, "src2": 5, "imm": "0x76ec7b8b", "imm2": "0x25663feb", "rot": 29, "bit": 30, "mask": 2}, + {"i": 9, "op": "shfl", "dst": 6, "src": 1, "src2": 0, "imm": "0x6c8ee3cb", "imm2": "0xea93237e", "rot": 27, "bit": 1, "mask": 4}, + {"i": 10, "op": "mad", "dst": 1, "src": 2, "src2": 2, "imm": "0x6dc4ea18", "imm2": "0x6efde6f5", "rot": 3, "bit": 20, "mask": 2}, + {"i": 11, "op": "mad", "dst": 5, "src": 0, "src2": 3, "imm": "0x023613fc", "imm2": "0x18c51939", "rot": 19, "bit": 31, "mask": 1}, + {"i": 12, "op": "shfl", "dst": 2, "src": 6, "src2": 1, "imm": "0x74aec8d2", "imm2": "0x7f7ad29c", "rot": 7, "bit": 8, "mask": 4}, + {"i": 13, "op": "add", "dst": 1, "src": 5, "src2": 6, "imm": "0xbdf8f9a5", "imm2": "0xbc48c63e", "rot": 6, "bit": 25, "mask": 2}, + {"i": 14, "op": "rotl", "dst": 1, "src": 2, "src2": 6, "imm": "0x7ad8ca8b", "imm2": "0x14c712ad", "rot": 29, "bit": 25, "mask": 8}, + {"i": 15, "op": "sub", "dst": 1, "src": 4, "src2": 5, "imm": "0xd3349f69", "imm2": "0x70aac45a", "rot": 29, "bit": 9, "mask": 16}, + {"i": 16, "op": "or", "dst": 7, "src": 1, "src2": 2, "imm": "0x08168ed1", "imm2": "0x28964037", "rot": 26, "bit": 0, "mask": 2}, + {"i": 17, "op": "shfl", "dst": 2, "src": 4, "src2": 6, "imm": "0x98d85f72", "imm2": "0x3dc87042", "rot": 29, "bit": 22, "mask": 8}, + {"i": 18, "op": "xor", "dst": 7, "src": 4, "src2": 0, "imm": "0x651d4a0e", "imm2": "0x93c198bd", "rot": 26, "bit": 12, "mask": 8}, + {"i": 19, "op": "mul", "dst": 6, "src": 1, "src2": 6, "imm": "0xd38ce89d", "imm2": "0x3dfad388", "rot": 5, "bit": 28, "mask": 8}, + {"i": 20, "op": "mad", "dst": 5, "src": 6, "src2": 0, "imm": "0x59d78b36", "imm2": "0xc4db274e", "rot": 25, "bit": 24, "mask": 1}, + {"i": 21, "op": "sub", "dst": 3, "src": 1, "src2": 7, "imm": "0xf6c6a6c7", "imm2": "0x8536f4e6", "rot": 6, "bit": 12, "mask": 4}, + {"i": 22, "op": "mul", "dst": 6, "src": 0, "src2": 7, "imm": "0x599445b4", "imm2": "0x632f8c32", "rot": 19, "bit": 4, "mask": 8}, + {"i": 23, "op": "add", "dst": 2, "src": 0, "src2": 7, "imm": "0x45c37cec", "imm2": "0x96e8f127", "rot": 15, "bit": 1, "mask": 4}, + {"i": 24, "op": "sub", "dst": 6, "src": 4, "src2": 3, "imm": "0xc1c44491", "imm2": "0x92e3ce57", "rot": 20, "bit": 25, "mask": 4}, + {"i": 25, "op": "mad", "dst": 7, "src": 3, "src2": 4, "imm": "0x89bfb8d3", "imm2": "0x19b5455e", "rot": 22, "bit": 2, "mask": 16}, + {"i": 26, "op": "rotl", "dst": 3, "src": 5, "src2": 7, "imm": "0x2f47ce8d", "imm2": "0x8b458ec5", "rot": 9, "bit": 0, "mask": 4}, + {"i": 27, "op": "sub", "dst": 2, "src": 1, "src2": 2, "imm": "0x9f0dce23", "imm2": "0x3cdca814", "rot": 25, "bit": 1, "mask": 2}, + {"i": 28, "op": "mulhi", "dst": 6, "src": 0, "src2": 3, "imm": "0x61fc9eb8", "imm2": "0x23202e9d", "rot": 30, "bit": 16, "mask": 16}, + {"i": 29, "op": "shfl", "dst": 2, "src": 4, "src2": 3, "imm": "0x339dbd65", "imm2": "0xc175f639", "rot": 15, "bit": 22, "mask": 2}, + {"i": 30, "op": "shfl", "dst": 1, "src": 6, "src2": 1, "imm": "0x5bd14589", "imm2": "0xa68a2bed", "rot": 31, "bit": 31, "mask": 1}, + {"i": 31, "op": "add", "dst": 1, "src": 6, "src2": 1, "imm": "0x37985632", "imm2": "0xb1cdb2ab", "rot": 29, "bit": 1, "mask": 8}, + {"i": 32, "op": "rotr", "dst": 0, "src": 1, "src2": 6, "imm": "0x4b2058f4", "imm2": "0xf06d8ac9", "rot": 9, "bit": 15, "mask": 16}, + {"i": 33, "op": "shfl", "dst": 3, "src": 4, "src2": 4, "imm": "0x2081626c", "imm2": "0x08d1bb87", "rot": 24, "bit": 29, "mask": 2}, + {"i": 34, "op": "shfl", "dst": 0, "src": 3, "src2": 6, "imm": "0xe4fcfe03", "imm2": "0x78a46b13", "rot": 15, "bit": 29, "mask": 4}, + {"i": 35, "op": "mul", "dst": 7, "src": 0, "src2": 4, "imm": "0x33148d30", "imm2": "0x5780a3d6", "rot": 6, "bit": 11, "mask": 2}, + {"i": 36, "op": "add", "dst": 3, "src": 1, "src2": 1, "imm": "0x804e777e", "imm2": "0x856e0180", "rot": 22, "bit": 0, "mask": 16}, + {"i": 37, "op": "xor", "dst": 1, "src": 6, "src2": 0, "imm": "0xc69aa2f6", "imm2": "0xafebe3e8", "rot": 15, "bit": 9, "mask": 16}, + {"i": 38, "op": "mul", "dst": 2, "src": 7, "src2": 4, "imm": "0xeb4c4082", "imm2": "0x3f1e0da7", "rot": 25, "bit": 20, "mask": 16}, + {"i": 39, "op": "add", "dst": 6, "src": 5, "src2": 5, "imm": "0x0b06c8a7", "imm2": "0xe9bd0cc4", "rot": 6, "bit": 2, "mask": 4}, + {"i": 40, "op": "mul", "dst": 5, "src": 7, "src2": 7, "imm": "0x070af1b6", "imm2": "0x6b648e75", "rot": 10, "bit": 6, "mask": 16}, + {"i": 41, "op": "mulhi", "dst": 2, "src": 3, "src2": 2, "imm": "0x389753b2", "imm2": "0x9e657305", "rot": 30, "bit": 2, "mask": 4}, + {"i": 42, "op": "xor", "dst": 2, "src": 0, "src2": 4, "imm": "0x0960e5b9", "imm2": "0xa925a406", "rot": 4, "bit": 6, "mask": 16}, + {"i": 43, "op": "rotl", "dst": 0, "src": 1, "src2": 1, "imm": "0x8eabe09f", "imm2": "0x76ef71e2", "rot": 4, "bit": 19, "mask": 8}, + {"i": 44, "op": "mulhi", "dst": 4, "src": 3, "src2": 7, "imm": "0x6a34768a", "imm2": "0x2e427c64", "rot": 21, "bit": 5, "mask": 4}, + {"i": 45, "op": "add", "dst": 6, "src": 7, "src2": 5, "imm": "0xee822e17", "imm2": "0xcdcb63f6", "rot": 27, "bit": 12, "mask": 16}, + {"i": 46, "op": "mad", "dst": 3, "src": 2, "src2": 0, "imm": "0xc89ead43", "imm2": "0x4d3108b2", "rot": 26, "bit": 17, "mask": 1}, + {"i": 47, "op": "shfl", "dst": 4, "src": 3, "src2": 0, "imm": "0xdd62be9e", "imm2": "0xf243f6f2", "rot": 8, "bit": 4, "mask": 8}, + {"i": 48, "op": "mulhi", "dst": 6, "src": 5, "src2": 0, "imm": "0xd3f7fa72", "imm2": "0x0debc83f", "rot": 25, "bit": 5, "mask": 2}, + {"i": 49, "op": "sub", "dst": 0, "src": 2, "src2": 6, "imm": "0x7afadd15", "imm2": "0xc07fc39c", "rot": 30, "bit": 29, "mask": 8}, + {"i": 50, "op": "sub", "dst": 3, "src": 5, "src2": 3, "imm": "0x179b78ec", "imm2": "0xaeccde37", "rot": 30, "bit": 17, "mask": 1}, + {"i": 51, "op": "rotr", "dst": 1, "src": 4, "src2": 1, "imm": "0xa4bfcea6", "imm2": "0xbf63bb2f", "rot": 2, "bit": 21, "mask": 2}, + {"i": 52, "op": "mad", "dst": 6, "src": 7, "src2": 7, "imm": "0xabf5ed10", "imm2": "0x8a285f51", "rot": 3, "bit": 23, "mask": 2}, + {"i": 53, "op": "xor", "dst": 5, "src": 3, "src2": 5, "imm": "0x88b416eb", "imm2": "0x36271d87", "rot": 19, "bit": 10, "mask": 2}, + {"i": 54, "op": "sub", "dst": 1, "src": 0, "src2": 1, "imm": "0xa3417dd3", "imm2": "0xcd98f620", "rot": 28, "bit": 2, "mask": 1}, + {"i": 55, "op": "sub", "dst": 5, "src": 6, "src2": 2, "imm": "0x45996c6f", "imm2": "0xe3d41087", "rot": 4, "bit": 31, "mask": 1}, + {"i": 56, "op": "add", "dst": 3, "src": 2, "src2": 0, "imm": "0x3dfad1b6", "imm2": "0xd4758987", "rot": 27, "bit": 10, "mask": 2}, + {"i": 57, "op": "add", "dst": 4, "src": 1, "src2": 3, "imm": "0xfca75bc2", "imm2": "0x0602d6be", "rot": 19, "bit": 0, "mask": 16}, + {"i": 58, "op": "mulhi", "dst": 5, "src": 6, "src2": 5, "imm": "0x83250a7b", "imm2": "0x2f93d53b", "rot": 25, "bit": 7, "mask": 2}, + {"i": 59, "op": "shfl", "dst": 2, "src": 1, "src2": 0, "imm": "0x13f4a089", "imm2": "0x145ea125", "rot": 12, "bit": 3, "mask": 2}, + {"i": 60, "op": "rotl", "dst": 2, "src": 5, "src2": 6, "imm": "0xad3170e3", "imm2": "0x15db04d1", "rot": 9, "bit": 13, "mask": 2}, + {"i": 61, "op": "or", "dst": 4, "src": 6, "src2": 2, "imm": "0x4b6305b2", "imm2": "0x6e7b2e9c", "rot": 27, "bit": 16, "mask": 4}, + {"i": 62, "op": "rotr", "dst": 6, "src": 4, "src2": 6, "imm": "0xfcd4b1c9", "imm2": "0xaf5c733b", "rot": 6, "bit": 21, "mask": 16}, + {"i": 63, "op": "mul", "dst": 2, "src": 4, "src2": 6, "imm": "0x95cebb3e", "imm2": "0xbba9cdfc", "rot": 19, "bit": 23, "mask": 1}, + {"i": 64, "op": "xor", "dst": 0, "src": 5, "src2": 7, "imm": "0x5f7579ff", "imm2": "0xb104e01a", "rot": 25, "bit": 12, "mask": 8}, + {"i": 65, "op": "xor", "dst": 2, "src": 7, "src2": 3, "imm": "0x749c7611", "imm2": "0xf17df3bb", "rot": 27, "bit": 26, "mask": 2}, + {"i": 66, "op": "add", "dst": 2, "src": 1, "src2": 6, "imm": "0xd71c02ff", "imm2": "0x8596687a", "rot": 4, "bit": 6, "mask": 2}, + {"i": 67, "op": "rotl", "dst": 1, "src": 3, "src2": 2, "imm": "0xd2864071", "imm2": "0xaa644ef3", "rot": 21, "bit": 5, "mask": 1}, + {"i": 68, "op": "mul", "dst": 3, "src": 2, "src2": 1, "imm": "0xd0689a5f", "imm2": "0xa3a1f063", "rot": 13, "bit": 28, "mask": 2}, + {"i": 69, "op": "shfl", "dst": 7, "src": 5, "src2": 6, "imm": "0xd01476eb", "imm2": "0x76abb5c2", "rot": 7, "bit": 30, "mask": 2}, + {"i": 70, "op": "mul", "dst": 3, "src": 2, "src2": 5, "imm": "0x59a75c10", "imm2": "0x1e1fbb72", "rot": 20, "bit": 16, "mask": 1}, + {"i": 71, "op": "mad", "dst": 0, "src": 2, "src2": 5, "imm": "0x39cca1df", "imm2": "0x22c057ac", "rot": 5, "bit": 23, "mask": 16}, + {"i": 72, "op": "add", "dst": 6, "src": 7, "src2": 3, "imm": "0x3c6fe15d", "imm2": "0x08ac5733", "rot": 14, "bit": 0, "mask": 4}, + {"i": 73, "op": "shfl", "dst": 3, "src": 2, "src2": 6, "imm": "0x2098627d", "imm2": "0xf4fecc81", "rot": 20, "bit": 30, "mask": 8}, + {"i": 74, "op": "mul", "dst": 3, "src": 6, "src2": 5, "imm": "0xf82e9e23", "imm2": "0x3ad62132", "rot": 10, "bit": 14, "mask": 16}, + {"i": 75, "op": "xor", "dst": 6, "src": 7, "src2": 4, "imm": "0x70548a91", "imm2": "0xa9715d2e", "rot": 6, "bit": 24, "mask": 1}, + {"i": 76, "op": "or", "dst": 3, "src": 0, "src2": 7, "imm": "0xa164325f", "imm2": "0xf300838b", "rot": 23, "bit": 23, "mask": 16}, + {"i": 77, "op": "add", "dst": 2, "src": 4, "src2": 6, "imm": "0x295d5fae", "imm2": "0xc100b495", "rot": 7, "bit": 1, "mask": 2}, + {"i": 78, "op": "mulhi", "dst": 3, "src": 7, "src2": 4, "imm": "0xb62cca87", "imm2": "0x2ebde415", "rot": 14, "bit": 7, "mask": 2}, + {"i": 79, "op": "or", "dst": 4, "src": 1, "src2": 7, "imm": "0xfcbc482d", "imm2": "0x8876e6cd", "rot": 29, "bit": 5, "mask": 2}, + {"i": 80, "op": "rotr", "dst": 4, "src": 3, "src2": 0, "imm": "0x6d64013b", "imm2": "0x675f4a8d", "rot": 26, "bit": 18, "mask": 8}, + {"i": 81, "op": "add", "dst": 4, "src": 3, "src2": 3, "imm": "0x274a9221", "imm2": "0x5cc59530", "rot": 15, "bit": 15, "mask": 2}, + {"i": 82, "op": "add", "dst": 7, "src": 3, "src2": 0, "imm": "0xc8651f8e", "imm2": "0x141479ec", "rot": 18, "bit": 5, "mask": 1}, + {"i": 83, "op": "rotr", "dst": 3, "src": 6, "src2": 0, "imm": "0xcc8a7766", "imm2": "0xc2eb5161", "rot": 4, "bit": 29, "mask": 2}, + {"i": 84, "op": "mad", "dst": 2, "src": 4, "src2": 7, "imm": "0xbc507d51", "imm2": "0x0b1196fd", "rot": 9, "bit": 7, "mask": 8}, + {"i": 85, "op": "shfl", "dst": 2, "src": 5, "src2": 5, "imm": "0x5a156c90", "imm2": "0xa6b3fbfa", "rot": 11, "bit": 2, "mask": 16}, + {"i": 86, "op": "xor", "dst": 3, "src": 2, "src2": 1, "imm": "0x8b042658", "imm2": "0xacf37a8f", "rot": 12, "bit": 23, "mask": 16}, + {"i": 87, "op": "shfl", "dst": 5, "src": 7, "src2": 2, "imm": "0x1a214238", "imm2": "0x017fdf5d", "rot": 29, "bit": 14, "mask": 2}, + {"i": 88, "op": "xor", "dst": 0, "src": 4, "src2": 2, "imm": "0xd523e612", "imm2": "0x2158c2ed", "rot": 30, "bit": 14, "mask": 4}, + {"i": 89, "op": "add", "dst": 3, "src": 2, "src2": 7, "imm": "0x53f915c2", "imm2": "0x883c0c92", "rot": 9, "bit": 18, "mask": 8}, + {"i": 90, "op": "rotr", "dst": 7, "src": 5, "src2": 5, "imm": "0xbd633b21", "imm2": "0xcf8c356c", "rot": 25, "bit": 31, "mask": 4}, + {"i": 91, "op": "add", "dst": 3, "src": 1, "src2": 1, "imm": "0xe2be00a5", "imm2": "0x3cc5bd20", "rot": 10, "bit": 31, "mask": 1}, + {"i": 92, "op": "shfl", "dst": 7, "src": 2, "src2": 4, "imm": "0x3d3da600", "imm2": "0x1f22df89", "rot": 4, "bit": 24, "mask": 1}, + {"i": 93, "op": "rotr", "dst": 6, "src": 2, "src2": 7, "imm": "0xb0f57471", "imm2": "0x8f2a7eca", "rot": 16, "bit": 25, "mask": 1}, + {"i": 94, "op": "rotl", "dst": 7, "src": 0, "src2": 4, "imm": "0x00a21815", "imm2": "0xeb4d7218", "rot": 14, "bit": 18, "mask": 16}, + {"i": 95, "op": "mad", "dst": 4, "src": 5, "src2": 5, "imm": "0xc4c3828e", "imm2": "0xfb7bba17", "rot": 16, "bit": 10, "mask": 16}, + {"i": 96, "op": "mad", "dst": 2, "src": 4, "src2": 5, "imm": "0xfc5bbc75", "imm2": "0xfc43468f", "rot": 31, "bit": 20, "mask": 16}, + {"i": 97, "op": "xor", "dst": 1, "src": 0, "src2": 2, "imm": "0x1fe9c249", "imm2": "0x164bb16b", "rot": 15, "bit": 9, "mask": 4}, + {"i": 98, "op": "mul", "dst": 5, "src": 4, "src2": 1, "imm": "0xeda725fa", "imm2": "0x66f7e9a2", "rot": 21, "bit": 6, "mask": 2}, + {"i": 99, "op": "sub", "dst": 2, "src": 0, "src2": 7, "imm": "0x8fb29f7d", "imm2": "0xf530eda1", "rot": 27, "bit": 30, "mask": 4}, + {"i": 100, "op": "rotl", "dst": 7, "src": 2, "src2": 0, "imm": "0x9f4de742", "imm2": "0x9b5ff871", "rot": 30, "bit": 21, "mask": 16}, + {"i": 101, "op": "add", "dst": 5, "src": 6, "src2": 7, "imm": "0x423fd9c9", "imm2": "0xbfd646cb", "rot": 17, "bit": 17, "mask": 2}, + {"i": 102, "op": "add", "dst": 7, "src": 6, "src2": 3, "imm": "0x8d3c011d", "imm2": "0x19b74a43", "rot": 12, "bit": 11, "mask": 4}, + {"i": 103, "op": "rotl", "dst": 5, "src": 6, "src2": 0, "imm": "0xcfc70303", "imm2": "0xf2b3e8ef", "rot": 6, "bit": 24, "mask": 1}, + {"i": 104, "op": "mul", "dst": 0, "src": 4, "src2": 5, "imm": "0x650475eb", "imm2": "0x11dcbd94", "rot": 15, "bit": 10, "mask": 1}, + {"i": 105, "op": "or", "dst": 0, "src": 5, "src2": 3, "imm": "0xaacaa145", "imm2": "0x9139d3fe", "rot": 4, "bit": 18, "mask": 2}, + {"i": 106, "op": "add", "dst": 0, "src": 1, "src2": 7, "imm": "0x8ce14721", "imm2": "0x7dcb7e18", "rot": 24, "bit": 15, "mask": 8}, + {"i": 107, "op": "rotl", "dst": 0, "src": 3, "src2": 3, "imm": "0xb36d6d98", "imm2": "0x2c3390c8", "rot": 15, "bit": 10, "mask": 16}, + {"i": 108, "op": "sub", "dst": 4, "src": 2, "src2": 5, "imm": "0xf6bbdaef", "imm2": "0x9db6f65e", "rot": 25, "bit": 10, "mask": 1}, + {"i": 109, "op": "mulhi", "dst": 2, "src": 0, "src2": 0, "imm": "0xb1721fd6", "imm2": "0xd96d52c9", "rot": 1, "bit": 27, "mask": 8}, + {"i": 110, "op": "mulhi", "dst": 1, "src": 0, "src2": 5, "imm": "0xfb4ca37f", "imm2": "0xb6ec7dbe", "rot": 27, "bit": 12, "mask": 8}, + {"i": 111, "op": "add", "dst": 0, "src": 2, "src2": 0, "imm": "0x2d9fc6b9", "imm2": "0x3c179ad8", "rot": 9, "bit": 28, "mask": 16}, + {"i": 112, "op": "mulhi", "dst": 2, "src": 0, "src2": 6, "imm": "0x71a9f6bd", "imm2": "0xd3417bf5", "rot": 2, "bit": 14, "mask": 8}, + {"i": 113, "op": "sub", "dst": 6, "src": 3, "src2": 5, "imm": "0xa3d19400", "imm2": "0x15df7330", "rot": 5, "bit": 2, "mask": 8}, + {"i": 114, "op": "mad", "dst": 7, "src": 6, "src2": 3, "imm": "0x1400d92e", "imm2": "0xfa4a158e", "rot": 16, "bit": 9, "mask": 1}, + {"i": 115, "op": "rotr", "dst": 5, "src": 1, "src2": 3, "imm": "0xd01684c3", "imm2": "0x6367febb", "rot": 23, "bit": 19, "mask": 2}, + {"i": 116, "op": "rotr", "dst": 6, "src": 4, "src2": 2, "imm": "0x8cd9eb96", "imm2": "0x98f33b24", "rot": 25, "bit": 1, "mask": 2}, + {"i": 117, "op": "add", "dst": 2, "src": 1, "src2": 7, "imm": "0x502138e2", "imm2": "0x47359729", "rot": 5, "bit": 22, "mask": 4}, + {"i": 118, "op": "mad", "dst": 3, "src": 2, "src2": 0, "imm": "0xd94a35c7", "imm2": "0xb83416c3", "rot": 11, "bit": 3, "mask": 4}, + {"i": 119, "op": "mul", "dst": 1, "src": 3, "src2": 6, "imm": "0x09b30cf7", "imm2": "0xef3b98e7", "rot": 17, "bit": 23, "mask": 8}, + {"i": 120, "op": "mad", "dst": 2, "src": 0, "src2": 4, "imm": "0x56416fe0", "imm2": "0x5e1dc8f3", "rot": 17, "bit": 14, "mask": 2}, + {"i": 121, "op": "mul", "dst": 0, "src": 3, "src2": 2, "imm": "0x2892697c", "imm2": "0x9cb3b14e", "rot": 29, "bit": 25, "mask": 2}, + {"i": 122, "op": "mulhi", "dst": 2, "src": 0, "src2": 3, "imm": "0xc33089a1", "imm2": "0xd6c5b530", "rot": 27, "bit": 13, "mask": 8}, + {"i": 123, "op": "mul", "dst": 5, "src": 6, "src2": 4, "imm": "0xdfe04e4a", "imm2": "0x3cc40160", "rot": 3, "bit": 14, "mask": 2}, + {"i": 124, "op": "mad", "dst": 4, "src": 2, "src2": 4, "imm": "0xb33dc1b7", "imm2": "0xab97743a", "rot": 7, "bit": 21, "mask": 4}, + {"i": 125, "op": "shfl", "dst": 4, "src": 2, "src2": 0, "imm": "0xfd469909", "imm2": "0xfc85dc55", "rot": 28, "bit": 24, "mask": 2}, + {"i": 126, "op": "xor", "dst": 2, "src": 0, "src2": 5, "imm": "0xa0094578", "imm2": "0xf1bee474", "rot": 31, "bit": 7, "mask": 2}, + {"i": 127, "op": "rotl", "dst": 1, "src": 7, "src2": 2, "imm": "0xb7ae00a0", "imm2": "0x86cce297", "rot": 7, "bit": 31, "mask": 8}, + {"i": 128, "op": "shfl", "dst": 7, "src": 2, "src2": 7, "imm": "0x019d1940", "imm2": "0x3fe9e7dd", "rot": 14, "bit": 4, "mask": 4}, + {"i": 129, "op": "rotl", "dst": 6, "src": 7, "src2": 7, "imm": "0x40a74cc4", "imm2": "0x09eb4adf", "rot": 17, "bit": 30, "mask": 1}, + {"i": 130, "op": "add", "dst": 2, "src": 5, "src2": 5, "imm": "0x33dff776", "imm2": "0x6c57e4e7", "rot": 27, "bit": 15, "mask": 4}, + {"i": 131, "op": "or", "dst": 0, "src": 3, "src2": 1, "imm": "0xe0c53bb9", "imm2": "0x124404f6", "rot": 4, "bit": 21, "mask": 16}, + {"i": 132, "op": "rotr", "dst": 5, "src": 0, "src2": 1, "imm": "0xe4353fce", "imm2": "0x559d0118", "rot": 2, "bit": 29, "mask": 4}, + {"i": 133, "op": "add", "dst": 2, "src": 3, "src2": 6, "imm": "0x5db25b34", "imm2": "0xe8212c0c", "rot": 21, "bit": 30, "mask": 1}, + {"i": 134, "op": "xor", "dst": 4, "src": 3, "src2": 6, "imm": "0x7366e50e", "imm2": "0x7cc1ffbd", "rot": 19, "bit": 18, "mask": 16}, + {"i": 135, "op": "xor", "dst": 6, "src": 1, "src2": 2, "imm": "0xa36decb7", "imm2": "0x79291734", "rot": 26, "bit": 0, "mask": 8}, + {"i": 136, "op": "sub", "dst": 1, "src": 7, "src2": 0, "imm": "0x225b03e4", "imm2": "0x7183e193", "rot": 16, "bit": 6, "mask": 2}, + {"i": 137, "op": "mad", "dst": 2, "src": 6, "src2": 2, "imm": "0x6f620d51", "imm2": "0x4e814e19", "rot": 6, "bit": 6, "mask": 2}, + {"i": 138, "op": "mulhi", "dst": 0, "src": 5, "src2": 6, "imm": "0x919d6bf3", "imm2": "0xc6240638", "rot": 17, "bit": 11, "mask": 16}, + {"i": 139, "op": "add", "dst": 2, "src": 7, "src2": 7, "imm": "0x218d4090", "imm2": "0xd44ff710", "rot": 1, "bit": 10, "mask": 16}, + {"i": 140, "op": "rotr", "dst": 1, "src": 4, "src2": 4, "imm": "0x4cbfa722", "imm2": "0x114e9564", "rot": 28, "bit": 9, "mask": 16}, + {"i": 141, "op": "shfl", "dst": 3, "src": 6, "src2": 2, "imm": "0xf702c6a1", "imm2": "0xf8f3c5d9", "rot": 7, "bit": 24, "mask": 1}, + {"i": 142, "op": "mad", "dst": 7, "src": 6, "src2": 2, "imm": "0xa2d285be", "imm2": "0x9cc94532", "rot": 15, "bit": 20, "mask": 8}, + {"i": 143, "op": "mul", "dst": 2, "src": 3, "src2": 7, "imm": "0x08b7ed80", "imm2": "0xa8abced4", "rot": 18, "bit": 10, "mask": 4}, + {"i": 144, "op": "add", "dst": 7, "src": 4, "src2": 2, "imm": "0xf4b1a8de", "imm2": "0xb98942fa", "rot": 18, "bit": 29, "mask": 8}, + {"i": 145, "op": "rotl", "dst": 7, "src": 6, "src2": 1, "imm": "0x64b6ba2d", "imm2": "0xf9e86793", "rot": 15, "bit": 24, "mask": 8}, + {"i": 146, "op": "xor", "dst": 7, "src": 5, "src2": 3, "imm": "0x41c42b5f", "imm2": "0x7c7e0e39", "rot": 8, "bit": 23, "mask": 2}, + {"i": 147, "op": "mad", "dst": 4, "src": 7, "src2": 4, "imm": "0x3caa807a", "imm2": "0x553a0cec", "rot": 11, "bit": 22, "mask": 8}, + {"i": 148, "op": "rotr", "dst": 6, "src": 5, "src2": 3, "imm": "0x3cb1289a", "imm2": "0x6b36f78a", "rot": 1, "bit": 9, "mask": 16}, + {"i": 149, "op": "mad", "dst": 1, "src": 2, "src2": 4, "imm": "0x95310ea8", "imm2": "0xc533aa6a", "rot": 16, "bit": 17, "mask": 1}, + {"i": 150, "op": "add", "dst": 1, "src": 7, "src2": 7, "imm": "0x2bef10f2", "imm2": "0x0d48ba42", "rot": 8, "bit": 17, "mask": 4}, + {"i": 151, "op": "xor", "dst": 5, "src": 4, "src2": 7, "imm": "0xda997ab2", "imm2": "0xae31d69e", "rot": 11, "bit": 31, "mask": 2}, + {"i": 152, "op": "add", "dst": 7, "src": 0, "src2": 6, "imm": "0xdc5cc080", "imm2": "0xc98dea9c", "rot": 16, "bit": 30, "mask": 2}, + {"i": 153, "op": "mul", "dst": 4, "src": 6, "src2": 7, "imm": "0xbfbf5f6c", "imm2": "0x61f611bb", "rot": 14, "bit": 22, "mask": 2}, + {"i": 154, "op": "mul", "dst": 0, "src": 2, "src2": 3, "imm": "0xa78008c3", "imm2": "0xbad5eeb1", "rot": 10, "bit": 28, "mask": 8}, + {"i": 155, "op": "xor", "dst": 6, "src": 5, "src2": 4, "imm": "0x1a73b866", "imm2": "0x1f5a62c9", "rot": 9, "bit": 27, "mask": 8}, + {"i": 156, "op": "rotr", "dst": 4, "src": 2, "src2": 0, "imm": "0x9c88500c", "imm2": "0xe25dccf9", "rot": 11, "bit": 2, "mask": 16}, + {"i": 157, "op": "rotl", "dst": 1, "src": 4, "src2": 4, "imm": "0xb05e7669", "imm2": "0x9db704b1", "rot": 11, "bit": 28, "mask": 4}, + {"i": 158, "op": "add", "dst": 5, "src": 0, "src2": 6, "imm": "0x18197438", "imm2": "0x6c752dcb", "rot": 11, "bit": 11, "mask": 2}, + {"i": 159, "op": "mad", "dst": 4, "src": 1, "src2": 5, "imm": "0x4796a65e", "imm2": "0x00e08c7a", "rot": 8, "bit": 19, "mask": 4}, + {"i": 160, "op": "rotl", "dst": 4, "src": 7, "src2": 5, "imm": "0x08a03052", "imm2": "0x0204f0ba", "rot": 26, "bit": 5, "mask": 2}, + {"i": 161, "op": "mad", "dst": 3, "src": 0, "src2": 7, "imm": "0xa0603b0e", "imm2": "0x7eee83d5", "rot": 28, "bit": 22, "mask": 16}, + {"i": 162, "op": "rotr", "dst": 3, "src": 1, "src2": 6, "imm": "0x78a3c69d", "imm2": "0x684693a0", "rot": 21, "bit": 23, "mask": 4}, + {"i": 163, "op": "add", "dst": 4, "src": 0, "src2": 7, "imm": "0xf1c46574", "imm2": "0x8e481727", "rot": 9, "bit": 3, "mask": 4}, + {"i": 164, "op": "mulhi", "dst": 0, "src": 4, "src2": 3, "imm": "0x04644afa", "imm2": "0x64bda2b5", "rot": 26, "bit": 16, "mask": 16}, + {"i": 165, "op": "add", "dst": 2, "src": 6, "src2": 2, "imm": "0xac578137", "imm2": "0x550ab406", "rot": 13, "bit": 20, "mask": 16}, + {"i": 166, "op": "rotl", "dst": 0, "src": 4, "src2": 5, "imm": "0x7f564760", "imm2": "0xb9a8b4f8", "rot": 13, "bit": 29, "mask": 1}, + {"i": 167, "op": "add", "dst": 3, "src": 1, "src2": 0, "imm": "0xa33e6706", "imm2": "0xaebb5966", "rot": 12, "bit": 14, "mask": 16}, + {"i": 168, "op": "or", "dst": 3, "src": 5, "src2": 3, "imm": "0x65b2f3eb", "imm2": "0xb1d00d20", "rot": 12, "bit": 2, "mask": 8}, + {"i": 169, "op": "rotr", "dst": 6, "src": 2, "src2": 3, "imm": "0x7f21faf5", "imm2": "0xbbf0d3f9", "rot": 17, "bit": 13, "mask": 8}, + {"i": 170, "op": "xor", "dst": 4, "src": 6, "src2": 2, "imm": "0x162c7140", "imm2": "0x90d404ad", "rot": 26, "bit": 1, "mask": 4}, + {"i": 171, "op": "sub", "dst": 6, "src": 1, "src2": 7, "imm": "0x6ef9c76e", "imm2": "0xfb7ba272", "rot": 31, "bit": 25, "mask": 1}, + {"i": 172, "op": "rotl", "dst": 7, "src": 5, "src2": 4, "imm": "0xde04eb3b", "imm2": "0xd56caa00", "rot": 22, "bit": 21, "mask": 4}, + {"i": 173, "op": "rotl", "dst": 5, "src": 3, "src2": 5, "imm": "0xa9eac934", "imm2": "0x2c338e51", "rot": 15, "bit": 22, "mask": 2}, + {"i": 174, "op": "shfl", "dst": 7, "src": 0, "src2": 3, "imm": "0x700be4e3", "imm2": "0x4bcfc732", "rot": 19, "bit": 6, "mask": 8}, + {"i": 175, "op": "xor", "dst": 0, "src": 5, "src2": 1, "imm": "0x02ccdba9", "imm2": "0xd0915be0", "rot": 15, "bit": 2, "mask": 16}, + {"i": 176, "op": "rotl", "dst": 7, "src": 4, "src2": 1, "imm": "0x489c8165", "imm2": "0xf24b5a4f", "rot": 6, "bit": 22, "mask": 1}, + {"i": 177, "op": "sub", "dst": 7, "src": 0, "src2": 6, "imm": "0x23ad9693", "imm2": "0x9a8c2f7b", "rot": 24, "bit": 2, "mask": 2}, + {"i": 178, "op": "rotl", "dst": 3, "src": 0, "src2": 6, "imm": "0xafa72a42", "imm2": "0x371d74ee", "rot": 30, "bit": 16, "mask": 1}, + {"i": 179, "op": "mad", "dst": 7, "src": 6, "src2": 1, "imm": "0x18a2a3f3", "imm2": "0xb811b951", "rot": 2, "bit": 9, "mask": 2}, + {"i": 180, "op": "rotl", "dst": 6, "src": 4, "src2": 1, "imm": "0xe6c69c0e", "imm2": "0xfc46a951", "rot": 9, "bit": 31, "mask": 4}, + {"i": 181, "op": "xor", "dst": 2, "src": 4, "src2": 7, "imm": "0xbd1b89e4", "imm2": "0xdf4bce5c", "rot": 15, "bit": 19, "mask": 4}, + {"i": 182, "op": "xor", "dst": 2, "src": 7, "src2": 5, "imm": "0x3dd12aed", "imm2": "0xd0756a69", "rot": 13, "bit": 16, "mask": 4}, + {"i": 183, "op": "xor", "dst": 7, "src": 2, "src2": 3, "imm": "0x77ce69d6", "imm2": "0x2b39bdf2", "rot": 8, "bit": 22, "mask": 16}, + {"i": 184, "op": "add", "dst": 1, "src": 2, "src2": 4, "imm": "0xd94d55ac", "imm2": "0x5bb7550f", "rot": 31, "bit": 21, "mask": 1}, + {"i": 185, "op": "or", "dst": 3, "src": 5, "src2": 6, "imm": "0x7b1ce846", "imm2": "0xcc3b8509", "rot": 28, "bit": 9, "mask": 4}, + {"i": 186, "op": "mulhi", "dst": 6, "src": 3, "src2": 0, "imm": "0xa5e24690", "imm2": "0x2200ba81", "rot": 26, "bit": 10, "mask": 16}, + {"i": 187, "op": "or", "dst": 4, "src": 0, "src2": 3, "imm": "0xf6efe759", "imm2": "0xae1f7118", "rot": 19, "bit": 20, "mask": 4}, + {"i": 188, "op": "shfl", "dst": 7, "src": 1, "src2": 5, "imm": "0xdb318b45", "imm2": "0xcec459c9", "rot": 20, "bit": 11, "mask": 2}, + {"i": 189, "op": "add", "dst": 6, "src": 5, "src2": 1, "imm": "0x89e747fe", "imm2": "0x2a354e2d", "rot": 22, "bit": 6, "mask": 1}, + {"i": 190, "op": "xor", "dst": 1, "src": 4, "src2": 2, "imm": "0xc379e617", "imm2": "0x75e9d63b", "rot": 23, "bit": 3, "mask": 2}, + {"i": 191, "op": "mulhi", "dst": 7, "src": 4, "src2": 3, "imm": "0x5a710287", "imm2": "0x7fe4ead6", "rot": 10, "bit": 25, "mask": 4}, + {"i": 192, "op": "rotl", "dst": 2, "src": 1, "src2": 2, "imm": "0x4d5e59a3", "imm2": "0x1e4fef28", "rot": 26, "bit": 0, "mask": 1}, + {"i": 193, "op": "rotl", "dst": 5, "src": 3, "src2": 7, "imm": "0x7444c47d", "imm2": "0xdad5f8be", "rot": 8, "bit": 30, "mask": 2}, + {"i": 194, "op": "shfl", "dst": 4, "src": 5, "src2": 7, "imm": "0x6a225bbb", "imm2": "0xd6532cd7", "rot": 13, "bit": 17, "mask": 16}, + {"i": 195, "op": "xor", "dst": 4, "src": 5, "src2": 3, "imm": "0x68344b9a", "imm2": "0xcb46a38b", "rot": 1, "bit": 27, "mask": 16}, + {"i": 196, "op": "mul", "dst": 1, "src": 3, "src2": 4, "imm": "0xbebf7359", "imm2": "0x3f0890ba", "rot": 18, "bit": 12, "mask": 4}, + {"i": 197, "op": "add", "dst": 5, "src": 2, "src2": 3, "imm": "0xea03e8e7", "imm2": "0x10cfdc71", "rot": 31, "bit": 7, "mask": 8}, + {"i": 198, "op": "add", "dst": 7, "src": 5, "src2": 1, "imm": "0xa7ee0102", "imm2": "0x66e148d3", "rot": 12, "bit": 15, "mask": 1}, + {"i": 199, "op": "sub", "dst": 5, "src": 2, "src2": 4, "imm": "0xc215584e", "imm2": "0x55fce30f", "rot": 30, "bit": 9, "mask": 2}, + {"i": 200, "op": "shfl", "dst": 5, "src": 1, "src2": 1, "imm": "0x308f8358", "imm2": "0x489f1f93", "rot": 13, "bit": 13, "mask": 2}, + {"i": 201, "op": "shfl", "dst": 7, "src": 1, "src2": 5, "imm": "0x713f1957", "imm2": "0x2239f757", "rot": 15, "bit": 7, "mask": 8}, + {"i": 202, "op": "rotr", "dst": 4, "src": 5, "src2": 1, "imm": "0xb037b6e7", "imm2": "0x49a8b528", "rot": 27, "bit": 13, "mask": 16}, + {"i": 203, "op": "xor", "dst": 7, "src": 5, "src2": 1, "imm": "0x56110241", "imm2": "0xefc8386d", "rot": 22, "bit": 20, "mask": 1}, + {"i": 204, "op": "xor", "dst": 7, "src": 0, "src2": 0, "imm": "0x0827fcc7", "imm2": "0xf4f5dd07", "rot": 13, "bit": 7, "mask": 2}, + {"i": 205, "op": "add", "dst": 6, "src": 2, "src2": 0, "imm": "0x8379a4de", "imm2": "0x8558b619", "rot": 26, "bit": 10, "mask": 1}, + {"i": 206, "op": "rotl", "dst": 4, "src": 3, "src2": 3, "imm": "0x091ceef0", "imm2": "0x69b0f72f", "rot": 13, "bit": 7, "mask": 1}, + {"i": 207, "op": "mulhi", "dst": 1, "src": 3, "src2": 4, "imm": "0x758edac1", "imm2": "0x98dd2f21", "rot": 15, "bit": 9, "mask": 1}, + {"i": 208, "op": "mad", "dst": 1, "src": 4, "src2": 4, "imm": "0x78871a1a", "imm2": "0x5e14e1c8", "rot": 19, "bit": 6, "mask": 2}, + {"i": 209, "op": "shfl", "dst": 2, "src": 0, "src2": 2, "imm": "0xf7e0b9aa", "imm2": "0xaecfd347", "rot": 21, "bit": 9, "mask": 4}, + {"i": 210, "op": "add", "dst": 7, "src": 0, "src2": 7, "imm": "0xaa8cb14e", "imm2": "0xf4049c4c", "rot": 24, "bit": 11, "mask": 8}, + {"i": 211, "op": "shfl", "dst": 7, "src": 1, "src2": 6, "imm": "0xc230d919", "imm2": "0xf76d08fb", "rot": 21, "bit": 13, "mask": 16}, + {"i": 212, "op": "xor", "dst": 1, "src": 0, "src2": 2, "imm": "0x31a5af90", "imm2": "0x7eef58ee", "rot": 9, "bit": 12, "mask": 4}, + {"i": 213, "op": "rotl", "dst": 7, "src": 1, "src2": 6, "imm": "0x0db26138", "imm2": "0x8e3c31f9", "rot": 3, "bit": 26, "mask": 2}, + {"i": 214, "op": "rotr", "dst": 4, "src": 7, "src2": 3, "imm": "0x29558100", "imm2": "0xe4b13ad6", "rot": 29, "bit": 24, "mask": 8}, + {"i": 215, "op": "shfl", "dst": 3, "src": 2, "src2": 6, "imm": "0x1b48c3d0", "imm2": "0x5c674ff6", "rot": 5, "bit": 9, "mask": 16}, + {"i": 216, "op": "or", "dst": 5, "src": 1, "src2": 0, "imm": "0xef768632", "imm2": "0x6de9d10d", "rot": 10, "bit": 4, "mask": 4}, + {"i": 217, "op": "sub", "dst": 1, "src": 2, "src2": 5, "imm": "0x88ca7f5a", "imm2": "0x24718a36", "rot": 18, "bit": 31, "mask": 1}, + {"i": 218, "op": "sub", "dst": 6, "src": 5, "src2": 0, "imm": "0xc4a06728", "imm2": "0xdc2a4fd8", "rot": 9, "bit": 9, "mask": 2}, + {"i": 219, "op": "rotl", "dst": 6, "src": 5, "src2": 7, "imm": "0xb7489e47", "imm2": "0xf13795c5", "rot": 4, "bit": 3, "mask": 8}, + {"i": 220, "op": "mulhi", "dst": 2, "src": 0, "src2": 2, "imm": "0x873cd31b", "imm2": "0x3dfbc55d", "rot": 12, "bit": 23, "mask": 8}, + {"i": 221, "op": "or", "dst": 2, "src": 0, "src2": 3, "imm": "0xdc21f099", "imm2": "0xee06f01e", "rot": 2, "bit": 17, "mask": 8}, + {"i": 222, "op": "shfl", "dst": 5, "src": 2, "src2": 6, "imm": "0x36def499", "imm2": "0xa2849d59", "rot": 23, "bit": 4, "mask": 8}, + {"i": 223, "op": "mulhi", "dst": 5, "src": 6, "src2": 7, "imm": "0xfb95fbca", "imm2": "0xc1aac427", "rot": 14, "bit": 11, "mask": 2}, + {"i": 224, "op": "sub", "dst": 0, "src": 6, "src2": 7, "imm": "0x3d9d29c4", "imm2": "0x34d0dcc0", "rot": 17, "bit": 6, "mask": 4}, + {"i": 225, "op": "rotl", "dst": 7, "src": 0, "src2": 5, "imm": "0x93b01b8e", "imm2": "0xfe1d75ac", "rot": 23, "bit": 15, "mask": 1}, + {"i": 226, "op": "or", "dst": 4, "src": 2, "src2": 4, "imm": "0xfed76e8e", "imm2": "0x1c24ecd8", "rot": 2, "bit": 6, "mask": 16}, + {"i": 227, "op": "mul", "dst": 2, "src": 4, "src2": 1, "imm": "0x5795f5b0", "imm2": "0x0566ea2a", "rot": 6, "bit": 28, "mask": 4}, + {"i": 228, "op": "rotl", "dst": 3, "src": 0, "src2": 2, "imm": "0x8c8486de", "imm2": "0xd066aa8f", "rot": 12, "bit": 20, "mask": 1}, + {"i": 229, "op": "rotr", "dst": 0, "src": 4, "src2": 0, "imm": "0x23a3e882", "imm2": "0xaca23902", "rot": 5, "bit": 22, "mask": 16}, + {"i": 230, "op": "add", "dst": 0, "src": 6, "src2": 4, "imm": "0x1d176220", "imm2": "0x2a7fecb2", "rot": 20, "bit": 16, "mask": 2}, + {"i": 231, "op": "shfl", "dst": 1, "src": 2, "src2": 0, "imm": "0x91172787", "imm2": "0xc5d7af28", "rot": 3, "bit": 24, "mask": 4}, + {"i": 232, "op": "mul", "dst": 2, "src": 1, "src2": 2, "imm": "0x0be68835", "imm2": "0xde692bdb", "rot": 30, "bit": 17, "mask": 1}, + {"i": 233, "op": "mad", "dst": 7, "src": 0, "src2": 1, "imm": "0xf90d2db5", "imm2": "0x96c4c175", "rot": 28, "bit": 7, "mask": 4}, + {"i": 234, "op": "rotl", "dst": 5, "src": 2, "src2": 1, "imm": "0x16379736", "imm2": "0x6973b905", "rot": 22, "bit": 17, "mask": 4}, + {"i": 235, "op": "rotr", "dst": 4, "src": 6, "src2": 2, "imm": "0x84292a13", "imm2": "0x0f897740", "rot": 12, "bit": 6, "mask": 8}, + {"i": 236, "op": "mad", "dst": 0, "src": 5, "src2": 1, "imm": "0xeb7de837", "imm2": "0x64f0c302", "rot": 4, "bit": 19, "mask": 1}, + {"i": 237, "op": "xor", "dst": 6, "src": 4, "src2": 4, "imm": "0x6ab4b683", "imm2": "0x20f17adb", "rot": 1, "bit": 0, "mask": 16}, + {"i": 238, "op": "xor", "dst": 4, "src": 6, "src2": 1, "imm": "0x5836b35c", "imm2": "0x3293cc4a", "rot": 16, "bit": 22, "mask": 16}, + {"i": 239, "op": "rotl", "dst": 6, "src": 1, "src2": 6, "imm": "0x769d8bc0", "imm2": "0xdc86c9cc", "rot": 18, "bit": 27, "mask": 16}, + {"i": 240, "op": "add", "dst": 4, "src": 7, "src2": 1, "imm": "0x17dafb4d", "imm2": "0xadce39f3", "rot": 12, "bit": 25, "mask": 8}, + {"i": 241, "op": "sub", "dst": 0, "src": 7, "src2": 4, "imm": "0xd4690bda", "imm2": "0xdab9b27b", "rot": 30, "bit": 21, "mask": 1}, + {"i": 242, "op": "rotr", "dst": 1, "src": 6, "src2": 2, "imm": "0x670a2d0a", "imm2": "0x0612e33c", "rot": 31, "bit": 25, "mask": 2}, + {"i": 243, "op": "add", "dst": 3, "src": 0, "src2": 2, "imm": "0xf2f77d26", "imm2": "0x0e7033b6", "rot": 27, "bit": 29, "mask": 1}, + {"i": 244, "op": "mad", "dst": 2, "src": 7, "src2": 4, "imm": "0xa9eefc9d", "imm2": "0x16166c85", "rot": 18, "bit": 23, "mask": 16}, + {"i": 245, "op": "mad", "dst": 4, "src": 0, "src2": 6, "imm": "0xb26f6c0f", "imm2": "0x0630e821", "rot": 23, "bit": 30, "mask": 4}, + {"i": 246, "op": "mul", "dst": 5, "src": 7, "src2": 2, "imm": "0x269ce4bf", "imm2": "0x1ce28d32", "rot": 30, "bit": 15, "mask": 16}, + {"i": 247, "op": "add", "dst": 3, "src": 5, "src2": 0, "imm": "0xfed2da4e", "imm2": "0x7b2ff6b7", "rot": 25, "bit": 31, "mask": 2}, + {"i": 248, "op": "add", "dst": 0, "src": 7, "src2": 5, "imm": "0x03b2891c", "imm2": "0xb5fad7b1", "rot": 2, "bit": 0, "mask": 4}, + {"i": 249, "op": "mulhi", "dst": 5, "src": 4, "src2": 6, "imm": "0xa69a1e71", "imm2": "0x15f0c0ea", "rot": 4, "bit": 1, "mask": 4}, + {"i": 250, "op": "add", "dst": 5, "src": 2, "src2": 3, "imm": "0x042cd6e3", "imm2": "0xa7e71c2f", "rot": 24, "bit": 11, "mask": 8}, + {"i": 251, "op": "shfl", "dst": 6, "src": 1, "src2": 2, "imm": "0x89c6b683", "imm2": "0x10bbf661", "rot": 24, "bit": 5, "mask": 1}, + {"i": 252, "op": "xor", "dst": 6, "src": 1, "src2": 3, "imm": "0x265c66d6", "imm2": "0xd4a689ed", "rot": 6, "bit": 14, "mask": 8}, + {"i": 253, "op": "mul", "dst": 2, "src": 5, "src2": 5, "imm": "0x890b8201", "imm2": "0x97c36bf3", "rot": 17, "bit": 22, "mask": 4}, + {"i": 254, "op": "add", "dst": 0, "src": 6, "src2": 0, "imm": "0x784a302b", "imm2": "0xb83d78de", "rot": 27, "bit": 16, "mask": 4}, + {"i": 255, "op": "sub", "dst": 2, "src": 4, "src2": 0, "imm": "0x817adb38", "imm2": "0xf3a3534b", "rot": 7, "bit": 22, "mask": 4} + ]}, + "instructions": [ + {"i": 0, "op": "mad", "dst": 2, "src": 3, "src2": 4, "imm": "0xbf7b174d", "imm2": "0x337b762e", "rot": 17, "bit": 2, "mask": 2, "width": 1}, + {"i": 1, "op": "mad", "dst": 2, "src": 1, "src2": 1, "imm": "0xdd04a5da", "imm2": "0x42da7657", "rot": 15, "bit": 30, "mask": 16, "width": 1}, + {"i": 2, "op": "mad", "dst": 2, "src": 3, "src2": 2, "imm": "0x734003fa", "imm2": "0x5bb67700", "rot": 3, "bit": 20, "mask": 1, "width": 1}, + {"i": 3, "op": "xor", "dst": 3, "src": 5, "src2": 5, "imm": "0xc55a1b1c", "imm2": "0xa19720f3", "rot": 7, "bit": 8, "mask": 1, "width": 1}, + {"i": 4, "op": "load", "dst": 7, "src": 2, "src2": 5, "imm": "0xad572dd7", "imm2": "0x9ceb3ea7", "rot": 18, "bit": 30, "mask": 2, "width": 1}, + {"i": 5, "op": "load", "dst": 5, "src": 7, "src2": 3, "imm": "0x769a53be", "imm2": "0x80f9067e", "rot": 12, "bit": 22, "mask": 1, "width": 1}, + {"i": 6, "op": "shfl", "dst": 1, "src": 4, "src2": 0, "imm": "0xd3613d88", "imm2": "0x262fb219", "rot": 10, "bit": 30, "mask": 8, "width": 1}, + {"i": 7, "op": "shfl", "dst": 7, "src": 3, "src2": 4, "imm": "0xce38e42f", "imm2": "0xb868b818", "rot": 11, "bit": 8, "mask": 8, "width": 1}, + {"i": 8, "op": "mulhi", "dst": 1, "src": 5, "src2": 2, "imm": "0xa5eebca5", "imm2": "0x5703a72b", "rot": 13, "bit": 13, "mask": 16, "width": 1}, + {"i": 9, "op": "rotr", "dst": 6, "src": 3, "src2": 4, "imm": "0x17a5a9c7", "imm2": "0xdcfb93a1", "rot": 20, "bit": 27, "mask": 2, "width": 1}, + {"i": 10, "op": "or", "dst": 3, "src": 4, "src2": 1, "imm": "0xccb7d785", "imm2": "0xc335364c", "rot": 14, "bit": 12, "mask": 4, "width": 1}, + {"i": 11, "op": "load", "dst": 4, "src": 3, "src2": 2, "imm": "0x88cb9af3", "imm2": "0x4e7dc10d", "rot": 24, "bit": 17, "mask": 4, "width": 1}, + {"i": 12, "op": "mulhi", "dst": 0, "src": 4, "src2": 4, "imm": "0x45374321", "imm2": "0x3cd91989", "rot": 11, "bit": 4, "mask": 2, "width": 1}, + {"i": 13, "op": "add", "dst": 5, "src": 1, "src2": 2, "imm": "0xc7934706", "imm2": "0xd3177981", "rot": 16, "bit": 30, "mask": 2, "width": 1}, + {"i": 14, "op": "load", "dst": 0, "src": 4, "src2": 3, "imm": "0xfd7f56bb", "imm2": "0x65e14f52", "rot": 13, "bit": 22, "mask": 2, "width": 1}, + {"i": 15, "op": "sub", "dst": 2, "src": 4, "src2": 4, "imm": "0x35a80b49", "imm2": "0x060f2d13", "rot": 16, "bit": 20, "mask": 16, "width": 1}, + {"i": 16, "op": "load", "dst": 2, "src": 0, "src2": 2, "imm": "0xae0a32c2", "imm2": "0x4c2a4cfe", "rot": 8, "bit": 31, "mask": 16, "width": 1}, + {"i": 17, "op": "load", "dst": 7, "src": 2, "src2": 6, "imm": "0x82a84cc3", "imm2": "0x21a38d68", "rot": 15, "bit": 21, "mask": 2, "width": 1}, + {"i": 18, "op": "shfl", "dst": 7, "src": 3, "src2": 3, "imm": "0xa3818806", "imm2": "0x8f66b5c8", "rot": 14, "bit": 6, "mask": 4, "width": 1}, + {"i": 19, "op": "mul", "dst": 5, "src": 0, "src2": 1, "imm": "0xa00de107", "imm2": "0x77bfcaa5", "rot": 3, "bit": 10, "mask": 2, "width": 1}, + {"i": 20, "op": "shfl", "dst": 3, "src": 4, "src2": 7, "imm": "0x1d2b8cab", "imm2": "0x80b4f9a2", "rot": 14, "bit": 25, "mask": 2, "width": 1}, + {"i": 21, "op": "shfl", "dst": 2, "src": 4, "src2": 5, "imm": "0x3ac915d2", "imm2": "0x5fba7bc2", "rot": 16, "bit": 1, "mask": 16, "width": 1}, + {"i": 22, "op": "mulhi", "dst": 6, "src": 2, "src2": 0, "imm": "0xdc3ec8fd", "imm2": "0x599e2fa3", "rot": 22, "bit": 3, "mask": 2, "width": 1}, + {"i": 23, "op": "load", "dst": 6, "src": 1, "src2": 5, "imm": "0x2a6b16d5", "imm2": "0xd73e396f", "rot": 28, "bit": 29, "mask": 2, "width": 1}, + {"i": 24, "op": "mul", "dst": 5, "src": 0, "src2": 7, "imm": "0x376d0223", "imm2": "0xe1c2169a", "rot": 4, "bit": 16, "mask": 16, "width": 1}, + {"i": 25, "op": "rotl", "dst": 5, "src": 7, "src2": 3, "imm": "0x78ad8c60", "imm2": "0x6f5b77d5", "rot": 19, "bit": 11, "mask": 16, "width": 1}, + {"i": 26, "op": "shfl", "dst": 7, "src": 6, "src2": 5, "imm": "0x93915b9f", "imm2": "0x1e61fb6b", "rot": 28, "bit": 23, "mask": 2, "width": 1}, + {"i": 27, "op": "xor", "dst": 0, "src": 5, "src2": 7, "imm": "0x6378fe15", "imm2": "0x66c78f42", "rot": 12, "bit": 31, "mask": 8, "width": 1}, + {"i": 28, "op": "xor", "dst": 0, "src": 4, "src2": 7, "imm": "0x20a57fda", "imm2": "0x088c848e", "rot": 16, "bit": 13, "mask": 4, "width": 1}, + {"i": 29, "op": "sub", "dst": 3, "src": 0, "src2": 2, "imm": "0x49d95fd5", "imm2": "0x1a5f946a", "rot": 6, "bit": 12, "mask": 1, "width": 1}, + {"i": 30, "op": "mul", "dst": 5, "src": 1, "src2": 7, "imm": "0x0a816217", "imm2": "0x405c4f73", "rot": 13, "bit": 27, "mask": 4, "width": 1}, + {"i": 31, "op": "load", "dst": 7, "src": 2, "src2": 2, "imm": "0x09ed045e", "imm2": "0xd69c4715", "rot": 5, "bit": 9, "mask": 2, "width": 1}, + {"i": 32, "op": "load", "dst": 1, "src": 0, "src2": 6, "imm": "0xeb79ea49", "imm2": "0xcc587f5a", "rot": 6, "bit": 8, "mask": 16, "width": 1}, + {"i": 33, "op": "xor", "dst": 5, "src": 6, "src2": 1, "imm": "0x3027401e", "imm2": "0x5f20c27e", "rot": 18, "bit": 9, "mask": 2, "width": 1}, + {"i": 34, "op": "load", "dst": 5, "src": 1, "src2": 3, "imm": "0x0e1cab07", "imm2": "0x09356c5b", "rot": 19, "bit": 31, "mask": 1, "width": 1}, + {"i": 35, "op": "mulhi", "dst": 0, "src": 5, "src2": 2, "imm": "0x90e31357", "imm2": "0xabd32484", "rot": 26, "bit": 5, "mask": 8, "width": 1}, + {"i": 36, "op": "shfl", "dst": 5, "src": 2, "src2": 5, "imm": "0xee9a955f", "imm2": "0x31b3faed", "rot": 8, "bit": 24, "mask": 4, "width": 1}, + {"i": 37, "op": "load", "dst": 7, "src": 0, "src2": 7, "imm": "0x3ba2f832", "imm2": "0x1160dcd3", "rot": 4, "bit": 29, "mask": 1, "width": 1}, + {"i": 38, "op": "add", "dst": 3, "src": 1, "src2": 7, "imm": "0x75ba2fad", "imm2": "0x230c005c", "rot": 4, "bit": 27, "mask": 1, "width": 1}, + {"i": 39, "op": "shfl", "dst": 1, "src": 5, "src2": 3, "imm": "0xdbf37e75", "imm2": "0xb5ac1969", "rot": 30, "bit": 13, "mask": 4, "width": 1}, + {"i": 40, "op": "xor", "dst": 2, "src": 5, "src2": 5, "imm": "0x47f136c5", "imm2": "0x06ce9153", "rot": 19, "bit": 10, "mask": 2, "width": 1}, + {"i": 41, "op": "mad", "dst": 3, "src": 6, "src2": 3, "imm": "0xce13eff8", "imm2": "0x04cc1d55", "rot": 3, "bit": 1, "mask": 4, "width": 1}, + {"i": 42, "op": "sub", "dst": 6, "src": 7, "src2": 1, "imm": "0x6a65ab71", "imm2": "0x8fbc1bcd", "rot": 4, "bit": 1, "mask": 8, "width": 1}, + {"i": 43, "op": "xor", "dst": 7, "src": 0, "src2": 7, "imm": "0xdaeb4928", "imm2": "0xc0423027", "rot": 24, "bit": 11, "mask": 8, "width": 1}, + {"i": 44, "op": "load", "dst": 1, "src": 7, "src2": 7, "imm": "0x778f01c9", "imm2": "0x28cedcea", "rot": 12, "bit": 4, "mask": 16, "width": 1}, + {"i": 45, "op": "mul", "dst": 2, "src": 3, "src2": 2, "imm": "0xf4264f1b", "imm2": "0x0f627d56", "rot": 5, "bit": 28, "mask": 8, "width": 1}, + {"i": 46, "op": "mulhi", "dst": 1, "src": 5, "src2": 1, "imm": "0xffb2147a", "imm2": "0xccde9b05", "rot": 13, "bit": 9, "mask": 2, "width": 1}, + {"i": 47, "op": "sub", "dst": 4, "src": 3, "src2": 5, "imm": "0x73b36234", "imm2": "0x3f5d5997", "rot": 7, "bit": 18, "mask": 2, "width": 1}, + {"i": 48, "op": "rotr", "dst": 2, "src": 6, "src2": 3, "imm": "0x3a4d9aa9", "imm2": "0x212bec7b", "rot": 4, "bit": 29, "mask": 16, "width": 1}, + {"i": 49, "op": "load", "dst": 3, "src": 5, "src2": 2, "imm": "0x626f11df", "imm2": "0x56cd5bfd", "rot": 7, "bit": 1, "mask": 1, "width": 1}, + {"i": 50, "op": "add", "dst": 1, "src": 5, "src2": 6, "imm": "0x81b8bc2c", "imm2": "0x1907970c", "rot": 28, "bit": 7, "mask": 4, "width": 1}, + {"i": 51, "op": "mul", "dst": 0, "src": 2, "src2": 2, "imm": "0xa8848b30", "imm2": "0xef6ac348", "rot": 9, "bit": 15, "mask": 8, "width": 1}, + {"i": 52, "op": "add", "dst": 0, "src": 2, "src2": 0, "imm": "0x4f92b968", "imm2": "0x699fd448", "rot": 22, "bit": 6, "mask": 4, "width": 1}, + {"i": 53, "op": "add", "dst": 1, "src": 0, "src2": 2, "imm": "0x2bb965af", "imm2": "0x77b1520d", "rot": 2, "bit": 12, "mask": 8, "width": 1}, + {"i": 54, "op": "rotl", "dst": 7, "src": 1, "src2": 0, "imm": "0x553e678b", "imm2": "0x3cc8eae0", "rot": 14, "bit": 20, "mask": 2, "width": 1}, + {"i": 55, "op": "add", "dst": 3, "src": 7, "src2": 2, "imm": "0x7b0fe07a", "imm2": "0xa54c55a0", "rot": 10, "bit": 1, "mask": 1, "width": 1}, + {"i": 56, "op": "load", "dst": 6, "src": 7, "src2": 4, "imm": "0x01eba9aa", "imm2": "0x2758c0f7", "rot": 14, "bit": 15, "mask": 4, "width": 1}, + {"i": 57, "op": "rotr", "dst": 1, "src": 5, "src2": 2, "imm": "0x1f5267b3", "imm2": "0x236f5a27", "rot": 2, "bit": 31, "mask": 16, "width": 1}, + {"i": 58, "op": "load", "dst": 5, "src": 4, "src2": 3, "imm": "0xa9954a9b", "imm2": "0x6a54d4e8", "rot": 11, "bit": 10, "mask": 16, "width": 1}, + {"i": 59, "op": "load", "dst": 6, "src": 2, "src2": 4, "imm": "0x9923ff88", "imm2": "0x9357254e", "rot": 16, "bit": 1, "mask": 16, "width": 1}, + {"i": 60, "op": "mad", "dst": 3, "src": 5, "src2": 0, "imm": "0xc0cc51a6", "imm2": "0x3fd7701b", "rot": 20, "bit": 1, "mask": 4, "width": 1}, + {"i": 61, "op": "add", "dst": 5, "src": 7, "src2": 7, "imm": "0xaf9dd72d", "imm2": "0xad7493e7", "rot": 7, "bit": 31, "mask": 16, "width": 1}, + {"i": 62, "op": "add", "dst": 4, "src": 6, "src2": 2, "imm": "0x89841d87", "imm2": "0x1e07c3d9", "rot": 6, "bit": 27, "mask": 1, "width": 1}, + {"i": 63, "op": "rotl", "dst": 5, "src": 4, "src2": 2, "imm": "0xae210f8d", "imm2": "0x8e499ba4", "rot": 19, "bit": 9, "mask": 1, "width": 1} + ] +} diff --git a/proto-cuda/packs-ca3-shadow/sh256x13/program.metal b/proto-cuda/packs-ca3-shadow/sh256x13/program.metal new file mode 100644 index 000000000..6a17edfd7 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x13/program.metal @@ -0,0 +1,368 @@ +#include +using namespace metal; + +#define MASK 0x0fffffffu +constant uint SEEDW[8] = { 0x67a9a7beu, 0x1a155b25u, 0xfddfb732u, 0x4b5af2e8u, 0xc55caf33u, 0xa27c13b7u, 0x06628a48u, 0x03852469u }; + +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 = r3 * r4 + r2; // 0 + r2 = r1 * r1 + r2; // 1 + r2 = r3 * r2 + r2; // 2 + r3 = r3 ^ r5; // 3 + r7 = r7 ^ dataset[r2 & MASK]; // 4 + r5 = r5 ^ dataset[r7 & MASK]; // 5 + r1 = r1 ^ simd_shuffle_xor(r4, (ushort)8); // 6 + r7 = r7 ^ simd_shuffle_xor(r3, (ushort)8); // 7 + r1 = mulhi(r1, r5); // 8 + r6 = rotr_var(r6, r3); // 9 + r3 = r3 | r4; // 10 + r4 = r4 ^ dataset[r3 & MASK]; // 11 + r0 = mulhi(r0, r4); // 12 + r5 = r5 + r1 + select(0xc7934706u, 0xd3177981u, ((sel >> 30u) & 1u) != 0u); // 13 + r0 = r0 ^ dataset[r4 & MASK]; // 14 + r2 = r2 - r4; // 15 + r2 = r2 ^ dataset[r0 & MASK]; // 16 + r7 = r7 ^ dataset[r2 & MASK]; // 17 + r7 = r7 ^ simd_shuffle_xor(r3, (ushort)4); // 18 + r5 = r5 * r0; // 19 + r3 = r3 ^ simd_shuffle_xor(r4, (ushort)2); // 20 + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)16); // 21 + r6 = mulhi(r6, r2); // 22 + r6 = r6 ^ dataset[r1 & MASK]; // 23 + r5 = r5 * r0; // 24 + r5 = rotl_imm(r5, 19u); // 25 + r7 = r7 ^ simd_shuffle_xor(r6, (ushort)2); // 26 + r0 = r0 ^ r5; // 27 + r0 = r0 ^ r4; // 28 + r3 = r3 - r0; // 29 + r5 = r5 * r1; // 30 + r7 = r7 ^ dataset[r2 & MASK]; // 31 + r1 = r1 ^ dataset[r0 & MASK]; // 32 + r5 = r5 ^ r6; // 33 + r5 = r5 ^ dataset[r1 & MASK]; // 34 + r0 = mulhi(r0, r5); // 35 + r5 = r5 ^ simd_shuffle_xor(r2, (ushort)4); // 36 + r7 = r7 ^ dataset[r0 & MASK]; // 37 + r3 = r3 + r1 + select(0x75ba2fadu, 0x230c005cu, ((sel >> 27u) & 1u) != 0u); // 38 + r1 = r1 ^ simd_shuffle_xor(r5, (ushort)4); // 39 + r2 = r2 ^ r5; // 40 + r3 = r6 * r3 + r3; // 41 + r6 = r6 - r7; // 42 + r7 = r7 ^ r0; // 43 + r1 = r1 ^ dataset[r7 & MASK]; // 44 + r2 = r2 * r3; // 45 + r1 = mulhi(r1, r5); // 46 + r4 = r4 - r3; // 47 + r2 = rotr_var(r2, r6); // 48 + r3 = r3 ^ dataset[r5 & MASK]; // 49 + r1 = r1 + r5 + select(0x81b8bc2cu, 0x1907970cu, ((sel >> 7u) & 1u) != 0u); // 50 + r0 = r0 * r2; // 51 + r0 = r0 + r2 + select(0x4f92b968u, 0x699fd448u, ((sel >> 6u) & 1u) != 0u); // 52 + r1 = r1 + r0 + select(0x2bb965afu, 0x77b1520du, ((sel >> 12u) & 1u) != 0u); // 53 + r7 = rotl_imm(r7, 14u); // 54 + r3 = r3 + r7 + select(0x7b0fe07au, 0xa54c55a0u, ((sel >> 1u) & 1u) != 0u); // 55 + r6 = r6 ^ dataset[r7 & MASK]; // 56 + r1 = rotr_var(r1, r5); // 57 + r5 = r5 ^ dataset[r4 & MASK]; // 58 + r6 = r6 ^ dataset[r2 & MASK]; // 59 + r3 = r5 * r0 + r3; // 60 + r5 = r5 + r7 + select(0xaf9dd72du, 0xad7493e7u, ((sel >> 31u) & 1u) != 0u); // 61 + r4 = r4 + r6 + select(0x89841d87u, 0x1e07c3d9u, ((sel >> 27u) & 1u) != 0u); // 62 + r5 = rotl_imm(r5, 19u); // 63 + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 13 passes after instruction 63, no load + for (uint sh = 0u; sh < 13u; ++sh) { + r5 = r5 + r2 + select(0x92199f99u, 0x8bc12da9u, ((sel >> 18u) & 1u) != 0u); // s0 add + r0 = r0 + r7 + select(0x8d72d3adu, 0x63079e5au, ((sel >> 26u) & 1u) != 0u); // s1 add + r6 = r6 ^ simd_shuffle_xor(r3, (ushort)2); // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + select(0xb21b4babu, 0x5d4c7a60u, ((sel >> 31u) & 1u) != 0u); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + select(0x2fe0e98bu, 0xc88e2942u, ((sel >> 16u) & 1u) != 0u); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + r6 = r6 ^ simd_shuffle_xor(r1, (ushort)4); // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + r2 = r2 ^ simd_shuffle_xor(r6, (ushort)4); // s12 shfl + r1 = r1 + r5 + select(0xbdf8f9a5u, 0xbc48c63eu, ((sel >> 25u) & 1u) != 0u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)8); // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + select(0x45c37cecu, 0x96e8f127u, ((sel >> 1u) & 1u) != 0u); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = mulhi(r6, r0); // s28 mulhi + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)2); // s29 shfl + r1 = r1 ^ simd_shuffle_xor(r6, (ushort)1); // s30 shfl + r1 = r1 + r6 + select(0x37985632u, 0xb1cdb2abu, ((sel >> 1u) & 1u) != 0u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + r3 = r3 ^ simd_shuffle_xor(r4, (ushort)2); // s33 shfl + r0 = r0 ^ simd_shuffle_xor(r3, (ushort)4); // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + select(0x804e777eu, 0x856e0180u, ((sel >> 0u) & 1u) != 0u); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + select(0x0b06c8a7u, 0xe9bd0cc4u, ((sel >> 2u) & 1u) != 0u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = mulhi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = mulhi(r4, r3); // s44 mulhi + r6 = r6 + r7 + select(0xee822e17u, 0xcdcb63f6u, ((sel >> 12u) & 1u) != 0u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + r4 = r4 ^ simd_shuffle_xor(r3, (ushort)8); // s47 shfl + r6 = mulhi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + select(0x3dfad1b6u, 0xd4758987u, ((sel >> 10u) & 1u) != 0u); // s56 add + r4 = r4 + r1 + select(0xfca75bc2u, 0x0602d6beu, ((sel >> 0u) & 1u) != 0u); // s57 add + r5 = mulhi(r5, r6); // s58 mulhi + r2 = r2 ^ simd_shuffle_xor(r1, (ushort)2); // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + select(0xd71c02ffu, 0x8596687au, ((sel >> 6u) & 1u) != 0u); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + r7 = r7 ^ simd_shuffle_xor(r5, (ushort)2); // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + select(0x3c6fe15du, 0x08ac5733u, ((sel >> 0u) & 1u) != 0u); // s72 add + r3 = r3 ^ simd_shuffle_xor(r2, (ushort)8); // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + select(0x295d5faeu, 0xc100b495u, ((sel >> 1u) & 1u) != 0u); // s77 add + r3 = mulhi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + select(0x274a9221u, 0x5cc59530u, ((sel >> 15u) & 1u) != 0u); // s81 add + r7 = r7 + r3 + select(0xc8651f8eu, 0x141479ecu, ((sel >> 5u) & 1u) != 0u); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + r2 = r2 ^ simd_shuffle_xor(r5, (ushort)16); // s85 shfl + r3 = r3 ^ r2; // s86 xor + r5 = r5 ^ simd_shuffle_xor(r7, (ushort)2); // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + select(0x53f915c2u, 0x883c0c92u, ((sel >> 18u) & 1u) != 0u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + select(0xe2be00a5u, 0x3cc5bd20u, ((sel >> 31u) & 1u) != 0u); // s91 add + r7 = r7 ^ simd_shuffle_xor(r2, (ushort)1); // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + select(0x423fd9c9u, 0xbfd646cbu, ((sel >> 17u) & 1u) != 0u); // s101 add + r7 = r7 + r6 + select(0x8d3c011du, 0x19b74a43u, ((sel >> 11u) & 1u) != 0u); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + select(0x8ce14721u, 0x7dcb7e18u, ((sel >> 15u) & 1u) != 0u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = mulhi(r2, r0); // s109 mulhi + r1 = mulhi(r1, r0); // s110 mulhi + r0 = r0 + r2 + select(0x2d9fc6b9u, 0x3c179ad8u, ((sel >> 28u) & 1u) != 0u); // s111 add + r2 = mulhi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + select(0x502138e2u, 0x47359729u, ((sel >> 22u) & 1u) != 0u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = mulhi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + r4 = r4 ^ simd_shuffle_xor(r2, (ushort)2); // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + r7 = r7 ^ simd_shuffle_xor(r2, (ushort)4); // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + select(0x33dff776u, 0x6c57e4e7u, ((sel >> 15u) & 1u) != 0u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + select(0x5db25b34u, 0xe8212c0cu, ((sel >> 30u) & 1u) != 0u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = mulhi(r0, r5); // s138 mulhi + r2 = r2 + r7 + select(0x218d4090u, 0xd44ff710u, ((sel >> 10u) & 1u) != 0u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + r3 = r3 ^ simd_shuffle_xor(r6, (ushort)1); // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + select(0xf4b1a8deu, 0xb98942fau, ((sel >> 29u) & 1u) != 0u); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + select(0x2bef10f2u, 0x0d48ba42u, ((sel >> 17u) & 1u) != 0u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + select(0xdc5cc080u, 0xc98dea9cu, ((sel >> 30u) & 1u) != 0u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + select(0x18197438u, 0x6c752dcbu, ((sel >> 11u) & 1u) != 0u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + select(0xf1c46574u, 0x8e481727u, ((sel >> 3u) & 1u) != 0u); // s163 add + r0 = mulhi(r0, r4); // s164 mulhi + r2 = r2 + r6 + select(0xac578137u, 0x550ab406u, ((sel >> 20u) & 1u) != 0u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + select(0xa33e6706u, 0xaebb5966u, ((sel >> 14u) & 1u) != 0u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + r7 = r7 ^ simd_shuffle_xor(r0, (ushort)8); // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + select(0xd94d55acu, 0x5bb7550fu, ((sel >> 21u) & 1u) != 0u); // s184 add + r3 = r3 | r5; // s185 or + r6 = mulhi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)2); // s188 shfl + r6 = r6 + r5 + select(0x89e747feu, 0x2a354e2du, ((sel >> 6u) & 1u) != 0u); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = mulhi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + r4 = r4 ^ simd_shuffle_xor(r5, (ushort)16); // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + select(0xea03e8e7u, 0x10cfdc71u, ((sel >> 7u) & 1u) != 0u); // s197 add + r7 = r7 + r5 + select(0xa7ee0102u, 0x66e148d3u, ((sel >> 15u) & 1u) != 0u); // s198 add + r5 = r5 - r2; // s199 sub + r5 = r5 ^ simd_shuffle_xor(r1, (ushort)2); // s200 shfl + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)8); // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + select(0x8379a4deu, 0x8558b619u, ((sel >> 10u) & 1u) != 0u); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = mulhi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + r2 = r2 ^ simd_shuffle_xor(r0, (ushort)4); // s209 shfl + r7 = r7 + r0 + select(0xaa8cb14eu, 0xf4049c4cu, ((sel >> 11u) & 1u) != 0u); // s210 add + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)16); // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + r3 = r3 ^ simd_shuffle_xor(r2, (ushort)16); // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = mulhi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + r5 = r5 ^ simd_shuffle_xor(r2, (ushort)8); // s222 shfl + r5 = mulhi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + select(0x1d176220u, 0x2a7fecb2u, ((sel >> 16u) & 1u) != 0u); // s230 add + r1 = r1 ^ simd_shuffle_xor(r2, (ushort)4); // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + select(0x17dafb4du, 0xadce39f3u, ((sel >> 25u) & 1u) != 0u); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + select(0xf2f77d26u, 0x0e7033b6u, ((sel >> 29u) & 1u) != 0u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + select(0xfed2da4eu, 0x7b2ff6b7u, ((sel >> 31u) & 1u) != 0u); // s247 add + r0 = r0 + r7 + select(0x03b2891cu, 0xb5fad7b1u, ((sel >> 0u) & 1u) != 0u); // s248 add + r5 = mulhi(r5, r4); // s249 mulhi + r5 = r5 + r2 + select(0x042cd6e3u, 0xa7e71c2fu, ((sel >> 11u) & 1u) != 0u); // s250 add + r6 = r6 ^ simd_shuffle_xor(r1, (ushort)1); // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + select(0x784a302bu, 0xb83d78deu, ((sel >> 16u) & 1u) != 0u); // s254 add + r2 = r2 - r4; // s255 sub + } + } + uint lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((ulong)hi << 32) | (ulong)lo; +} diff --git a/proto-cuda/packs-ca3-shadow/sh256x13/program_bound.metal b/proto-cuda/packs-ca3-shadow/sh256x13/program_bound.metal new file mode 100644 index 000000000..c089f8803 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x13/program_bound.metal @@ -0,0 +1,370 @@ +#include +using namespace metal; + +#define MASK 0x0fffffffu +constant uint SEEDW[8] = { 0x67a9a7beu, 0x1a155b25u, 0xfddfb732u, 0x4b5af2e8u, 0xc55caf33u, 0xa27c13b7u, 0x06628a48u, 0x03852469u }; + +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 = r3 * r4 + r2; // 0 + r2 = r1 * r1 + r2; // 1 + r2 = r3 * r2 + r2; // 2 + r3 = r3 ^ r5; // 3 + r7 = r7 ^ dataset[r2 & MASK]; // 4 + r5 = r5 ^ dataset[r7 & MASK]; // 5 + r1 = r1 ^ simd_shuffle_xor(r4, (ushort)8); // 6 + r7 = r7 ^ simd_shuffle_xor(r3, (ushort)8); // 7 + r1 = mulhi(r1, r5); // 8 + r6 = rotr_var(r6, r3); // 9 + r3 = r3 | r4; // 10 + r4 = r4 ^ dataset[r3 & MASK]; // 11 + r0 = mulhi(r0, r4); // 12 + r5 = r5 + r1 + select(0xc7934706u, 0xd3177981u, ((sel >> 30u) & 1u) != 0u); // 13 + r0 = r0 ^ dataset[r4 & MASK]; // 14 + r2 = r2 - r4; // 15 + r2 = r2 ^ dataset[r0 & MASK]; // 16 + r7 = r7 ^ dataset[r2 & MASK]; // 17 + r7 = r7 ^ simd_shuffle_xor(r3, (ushort)4); // 18 + r5 = r5 * r0; // 19 + r3 = r3 ^ simd_shuffle_xor(r4, (ushort)2); // 20 + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)16); // 21 + r6 = mulhi(r6, r2); // 22 + r6 = r6 ^ dataset[r1 & MASK]; // 23 + r5 = r5 * r0; // 24 + r5 = rotl_imm(r5, 19u); // 25 + r7 = r7 ^ simd_shuffle_xor(r6, (ushort)2); // 26 + r0 = r0 ^ r5; // 27 + r0 = r0 ^ r4; // 28 + r3 = r3 - r0; // 29 + r5 = r5 * r1; // 30 + r7 = r7 ^ dataset[r2 & MASK]; // 31 + r1 = r1 ^ dataset[r0 & MASK]; // 32 + r5 = r5 ^ r6; // 33 + r5 = r5 ^ dataset[r1 & MASK]; // 34 + r0 = mulhi(r0, r5); // 35 + r5 = r5 ^ simd_shuffle_xor(r2, (ushort)4); // 36 + r7 = r7 ^ dataset[r0 & MASK]; // 37 + r3 = r3 + r1 + select(0x75ba2fadu, 0x230c005cu, ((sel >> 27u) & 1u) != 0u); // 38 + r1 = r1 ^ simd_shuffle_xor(r5, (ushort)4); // 39 + r2 = r2 ^ r5; // 40 + r3 = r6 * r3 + r3; // 41 + r6 = r6 - r7; // 42 + r7 = r7 ^ r0; // 43 + r1 = r1 ^ dataset[r7 & MASK]; // 44 + r2 = r2 * r3; // 45 + r1 = mulhi(r1, r5); // 46 + r4 = r4 - r3; // 47 + r2 = rotr_var(r2, r6); // 48 + r3 = r3 ^ dataset[r5 & MASK]; // 49 + r1 = r1 + r5 + select(0x81b8bc2cu, 0x1907970cu, ((sel >> 7u) & 1u) != 0u); // 50 + r0 = r0 * r2; // 51 + r0 = r0 + r2 + select(0x4f92b968u, 0x699fd448u, ((sel >> 6u) & 1u) != 0u); // 52 + r1 = r1 + r0 + select(0x2bb965afu, 0x77b1520du, ((sel >> 12u) & 1u) != 0u); // 53 + r7 = rotl_imm(r7, 14u); // 54 + r3 = r3 + r7 + select(0x7b0fe07au, 0xa54c55a0u, ((sel >> 1u) & 1u) != 0u); // 55 + r6 = r6 ^ dataset[r7 & MASK]; // 56 + r1 = rotr_var(r1, r5); // 57 + r5 = r5 ^ dataset[r4 & MASK]; // 58 + r6 = r6 ^ dataset[r2 & MASK]; // 59 + r3 = r5 * r0 + r3; // 60 + r5 = r5 + r7 + select(0xaf9dd72du, 0xad7493e7u, ((sel >> 31u) & 1u) != 0u); // 61 + r4 = r4 + r6 + select(0x89841d87u, 0x1e07c3d9u, ((sel >> 27u) & 1u) != 0u); // 62 + r5 = rotl_imm(r5, 19u); // 63 + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 13 passes after instruction 63, no load + for (uint sh = 0u; sh < 13u; ++sh) { + r5 = r5 + r2 + select(0x92199f99u, 0x8bc12da9u, ((sel >> 18u) & 1u) != 0u); // s0 add + r0 = r0 + r7 + select(0x8d72d3adu, 0x63079e5au, ((sel >> 26u) & 1u) != 0u); // s1 add + r6 = r6 ^ simd_shuffle_xor(r3, (ushort)2); // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + select(0xb21b4babu, 0x5d4c7a60u, ((sel >> 31u) & 1u) != 0u); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + select(0x2fe0e98bu, 0xc88e2942u, ((sel >> 16u) & 1u) != 0u); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + r6 = r6 ^ simd_shuffle_xor(r1, (ushort)4); // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + r2 = r2 ^ simd_shuffle_xor(r6, (ushort)4); // s12 shfl + r1 = r1 + r5 + select(0xbdf8f9a5u, 0xbc48c63eu, ((sel >> 25u) & 1u) != 0u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)8); // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + select(0x45c37cecu, 0x96e8f127u, ((sel >> 1u) & 1u) != 0u); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = mulhi(r6, r0); // s28 mulhi + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)2); // s29 shfl + r1 = r1 ^ simd_shuffle_xor(r6, (ushort)1); // s30 shfl + r1 = r1 + r6 + select(0x37985632u, 0xb1cdb2abu, ((sel >> 1u) & 1u) != 0u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + r3 = r3 ^ simd_shuffle_xor(r4, (ushort)2); // s33 shfl + r0 = r0 ^ simd_shuffle_xor(r3, (ushort)4); // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + select(0x804e777eu, 0x856e0180u, ((sel >> 0u) & 1u) != 0u); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + select(0x0b06c8a7u, 0xe9bd0cc4u, ((sel >> 2u) & 1u) != 0u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = mulhi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = mulhi(r4, r3); // s44 mulhi + r6 = r6 + r7 + select(0xee822e17u, 0xcdcb63f6u, ((sel >> 12u) & 1u) != 0u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + r4 = r4 ^ simd_shuffle_xor(r3, (ushort)8); // s47 shfl + r6 = mulhi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + select(0x3dfad1b6u, 0xd4758987u, ((sel >> 10u) & 1u) != 0u); // s56 add + r4 = r4 + r1 + select(0xfca75bc2u, 0x0602d6beu, ((sel >> 0u) & 1u) != 0u); // s57 add + r5 = mulhi(r5, r6); // s58 mulhi + r2 = r2 ^ simd_shuffle_xor(r1, (ushort)2); // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + select(0xd71c02ffu, 0x8596687au, ((sel >> 6u) & 1u) != 0u); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + r7 = r7 ^ simd_shuffle_xor(r5, (ushort)2); // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + select(0x3c6fe15du, 0x08ac5733u, ((sel >> 0u) & 1u) != 0u); // s72 add + r3 = r3 ^ simd_shuffle_xor(r2, (ushort)8); // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + select(0x295d5faeu, 0xc100b495u, ((sel >> 1u) & 1u) != 0u); // s77 add + r3 = mulhi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + select(0x274a9221u, 0x5cc59530u, ((sel >> 15u) & 1u) != 0u); // s81 add + r7 = r7 + r3 + select(0xc8651f8eu, 0x141479ecu, ((sel >> 5u) & 1u) != 0u); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + r2 = r2 ^ simd_shuffle_xor(r5, (ushort)16); // s85 shfl + r3 = r3 ^ r2; // s86 xor + r5 = r5 ^ simd_shuffle_xor(r7, (ushort)2); // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + select(0x53f915c2u, 0x883c0c92u, ((sel >> 18u) & 1u) != 0u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + select(0xe2be00a5u, 0x3cc5bd20u, ((sel >> 31u) & 1u) != 0u); // s91 add + r7 = r7 ^ simd_shuffle_xor(r2, (ushort)1); // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + select(0x423fd9c9u, 0xbfd646cbu, ((sel >> 17u) & 1u) != 0u); // s101 add + r7 = r7 + r6 + select(0x8d3c011du, 0x19b74a43u, ((sel >> 11u) & 1u) != 0u); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + select(0x8ce14721u, 0x7dcb7e18u, ((sel >> 15u) & 1u) != 0u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = mulhi(r2, r0); // s109 mulhi + r1 = mulhi(r1, r0); // s110 mulhi + r0 = r0 + r2 + select(0x2d9fc6b9u, 0x3c179ad8u, ((sel >> 28u) & 1u) != 0u); // s111 add + r2 = mulhi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + select(0x502138e2u, 0x47359729u, ((sel >> 22u) & 1u) != 0u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = mulhi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + r4 = r4 ^ simd_shuffle_xor(r2, (ushort)2); // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + r7 = r7 ^ simd_shuffle_xor(r2, (ushort)4); // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + select(0x33dff776u, 0x6c57e4e7u, ((sel >> 15u) & 1u) != 0u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + select(0x5db25b34u, 0xe8212c0cu, ((sel >> 30u) & 1u) != 0u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = mulhi(r0, r5); // s138 mulhi + r2 = r2 + r7 + select(0x218d4090u, 0xd44ff710u, ((sel >> 10u) & 1u) != 0u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + r3 = r3 ^ simd_shuffle_xor(r6, (ushort)1); // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + select(0xf4b1a8deu, 0xb98942fau, ((sel >> 29u) & 1u) != 0u); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + select(0x2bef10f2u, 0x0d48ba42u, ((sel >> 17u) & 1u) != 0u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + select(0xdc5cc080u, 0xc98dea9cu, ((sel >> 30u) & 1u) != 0u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + select(0x18197438u, 0x6c752dcbu, ((sel >> 11u) & 1u) != 0u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + select(0xf1c46574u, 0x8e481727u, ((sel >> 3u) & 1u) != 0u); // s163 add + r0 = mulhi(r0, r4); // s164 mulhi + r2 = r2 + r6 + select(0xac578137u, 0x550ab406u, ((sel >> 20u) & 1u) != 0u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + select(0xa33e6706u, 0xaebb5966u, ((sel >> 14u) & 1u) != 0u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + r7 = r7 ^ simd_shuffle_xor(r0, (ushort)8); // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + select(0xd94d55acu, 0x5bb7550fu, ((sel >> 21u) & 1u) != 0u); // s184 add + r3 = r3 | r5; // s185 or + r6 = mulhi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)2); // s188 shfl + r6 = r6 + r5 + select(0x89e747feu, 0x2a354e2du, ((sel >> 6u) & 1u) != 0u); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = mulhi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + r4 = r4 ^ simd_shuffle_xor(r5, (ushort)16); // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + select(0xea03e8e7u, 0x10cfdc71u, ((sel >> 7u) & 1u) != 0u); // s197 add + r7 = r7 + r5 + select(0xa7ee0102u, 0x66e148d3u, ((sel >> 15u) & 1u) != 0u); // s198 add + r5 = r5 - r2; // s199 sub + r5 = r5 ^ simd_shuffle_xor(r1, (ushort)2); // s200 shfl + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)8); // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + select(0x8379a4deu, 0x8558b619u, ((sel >> 10u) & 1u) != 0u); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = mulhi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + r2 = r2 ^ simd_shuffle_xor(r0, (ushort)4); // s209 shfl + r7 = r7 + r0 + select(0xaa8cb14eu, 0xf4049c4cu, ((sel >> 11u) & 1u) != 0u); // s210 add + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)16); // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + r3 = r3 ^ simd_shuffle_xor(r2, (ushort)16); // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = mulhi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + r5 = r5 ^ simd_shuffle_xor(r2, (ushort)8); // s222 shfl + r5 = mulhi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + select(0x1d176220u, 0x2a7fecb2u, ((sel >> 16u) & 1u) != 0u); // s230 add + r1 = r1 ^ simd_shuffle_xor(r2, (ushort)4); // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + select(0x17dafb4du, 0xadce39f3u, ((sel >> 25u) & 1u) != 0u); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + select(0xf2f77d26u, 0x0e7033b6u, ((sel >> 29u) & 1u) != 0u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + select(0xfed2da4eu, 0x7b2ff6b7u, ((sel >> 31u) & 1u) != 0u); // s247 add + r0 = r0 + r7 + select(0x03b2891cu, 0xb5fad7b1u, ((sel >> 0u) & 1u) != 0u); // s248 add + r5 = mulhi(r5, r4); // s249 mulhi + r5 = r5 + r2 + select(0x042cd6e3u, 0xa7e71c2fu, ((sel >> 11u) & 1u) != 0u); // s250 add + r6 = r6 ^ simd_shuffle_xor(r1, (ushort)1); // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + select(0x784a302bu, 0xb83d78deu, ((sel >> 16u) & 1u) != 0u); // s254 add + r2 = r2 - r4; // s255 sub + } + } + uint lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((ulong)hi << 32) | (ulong)lo; +} diff --git a/proto-cuda/packs-ca3-shadow/sh256x13/vectors.h b/proto-cuda/packs-ca3-shadow/sh256x13/vectors.h new file mode 100644 index 000000000..c1adcfecb --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x13/vectors.h @@ -0,0 +1,57 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Expected outputs: igneum-pow (Rust) CPU interpreter, generator v2, memory-hard dataset +#pragma once +#ifdef __cplusplus +#include +#else +#include +#endif + +#define IGNEUM_VEC_WARPS 3 +static const uint32_t IGNEUM_VEC_BASE[IGNEUM_VEC_WARPS] = { 0u, 4096u, 1000000u }; +static const uint64_t IGNEUM_VEC_OUT[IGNEUM_VEC_WARPS][32] = { + { // base nonce 0 + 0xb359d110ac143375ull, 0x748fb5308223a682ull, 0x2a809644b94a8216ull, 0x18548dad2999d526ull, 0xb793809331b0a189ull, 0x55b034de97b5dcfdull, 0x9506b188c1becd3cull, 0x6f2a3986cb1967b3ull, + 0x376f13355e35e6c4ull, 0x35db684678b0567bull, 0xfec8f41452c07083ull, 0x324ad57e71b201e5ull, 0x1f5def2519b0dff9ull, 0x07e54a4494f2283dull, 0xc698336cb18b866cull, 0xc9808c2475fe8d66ull, + 0x82021978b9d61925ull, 0x0ef2fa3310887ec6ull, 0xdb17534bb857c9ccull, 0x5203cbc6bdb4bbb2ull, 0xb0b2b24438cf1cc0ull, 0xcb1fa6bf5e701935ull, 0x3dca8b3408c4a3f7ull, 0xd7610b168cf2943cull, + 0xcfe566147a489c75ull, 0x6294533ee65da77dull, 0x2e0774f316868b26ull, 0xd2a10f4303777610ull, 0x2e3a4b91c8962246ull, 0x00063a312aa1f50bull, 0x003794aceed11052ull, 0xcc181405cd575561ull + }, + { // base nonce 4096 + 0x382ff31a848c87ceull, 0x9f83773ad5a14bf6ull, 0xb256ecebb8fcf4dcull, 0x000c632632ea0cedull, 0xcaf1f89dc457ab50ull, 0x6a3b9f2156b7b00dull, 0x9b428f619265dcfcull, 0x907f65c3591b88c6ull, + 0x0f225df3fbfb67e2ull, 0x29614e20ca52a926ull, 0x4655beaea3ad2759ull, 0xf995b623fcc6644dull, 0xce65301573c94490ull, 0xc7870bc7e5052ee9ull, 0xf7b89744f3b0b132ull, 0x80351dd1981ed5e3ull, + 0xa878aa51b297dcfcull, 0x001a834e5e050e8eull, 0xca2c133d9937349dull, 0x82d3b88dddc886bfull, 0x7ae69bce58a3da0cull, 0x4561f608a0e10777ull, 0x86a12f3d2bb459c9ull, 0x860f5151394991f8ull, + 0xe55b559c5c954cb8ull, 0x4bcbcdbefcaf412dull, 0x1e74dbd57413e73dull, 0x03d197ea39c77502ull, 0xfdff34586270344aull, 0x7e1ff6220cbc0124ull, 0xba28400b90b409d8ull, 0x592cd3eb57e1d660ull + }, + { // base nonce 1000000 + 0x99769bd9e253e017ull, 0xda7db4183c7fb68bull, 0xff5782631ce7fa14ull, 0x5c6494df049901faull, 0x3d49b9a6b55f9ee6ull, 0xa7f999e4384da8dbull, 0xd1312b67803a0c72ull, 0x85f5d8f8bb33dc9full, + 0x63664a37b11f311aull, 0x28a4b561cf2f7b36ull, 0x7674177403abf2c8ull, 0xf6ef2c094f5cb4afull, 0xbdc4a803a2e91ff4ull, 0x4459a81585f5f6e0ull, 0xb4098eb87a7489feull, 0x60d9b048e1bbefdeull, + 0xd0aec740e4aba722ull, 0x69d9e3e9c99c5391ull, 0x040fe663cbcbfdc2ull, 0x38e3b8eab6a7b6b4ull, 0x8a606e5c69c02b3full, 0xe1dd929d4296cde3ull, 0x2ad80e84d9072b65ull, 0xa1f34ff68012fd66ull, + 0xa2351892f47fbd27ull, 0xd88d059c58979055ull, 0x0c5d59a61c9c5b0bull, 0xd16f446ddd7119c7ull, 0x47aa1f6c4b48d944ull, 0xf6164e14d2937532ull, 0xd344f8977fd2d100ull, 0xf76f271447d7d772ull + } +}; + +// Dataset self-test: dataset[0..15] and dataset[IGNEUM_MASK] (268435455). +static const uint32_t IGNEUM_DS_HEAD[16] = { + 0xfdad4319u, 0x1a7b68e1u, 0xde6db608u, 0x13d73892u, 0xd17f447au, 0xb2221ccfu, 0x9db004bdu, 0x57d7d367u, + 0xdbc4cf34u, 0x697c009au, 0xc43af1d4u, 0x97f12b2eu, 0x74c37cd0u, 0xc651ea15u, 0x665a6d29u, 0x22330a2du +}; +static const uint32_t IGNEUM_DS_LAST_INDEX = 268435455u; +static const uint32_t IGNEUM_DS_LAST = 0xa83e7aa6u; +// 64 sampled dataset words (index, value) computed on the Mac. +#define IGNEUM_DS_SAMPLES 64 +static const uint32_t IGNEUM_DS_SAMPLE_INDEX[IGNEUM_DS_SAMPLES] = { + 59471966u, 217795994u, 208353206u, 42483309u, 172547758u, 148076330u, 183853158u, 214389424u, 267488061u, 169781097u, 184093494u, 153880993u, 84977930u, 46426879u, 3093825u, 225364072u, 44593546u, 260713159u, 168250303u, 52384140u, 223401610u, 45554030u, 95410555u, 175039924u, 79171087u, 267580473u, 24168642u, 37981670u, 171551130u, 195559979u, 204611762u, 140997658u, 138925853u, 86637313u, 20736778u, 219665210u, 160430336u, 264654675u, 8013395u, 228945585u, 213884386u, 104419827u, 44185464u, 142737231u, 99284897u, 132475900u, 61861762u, 132056166u, 262388043u, 91878046u, 117353561u, 124768597u, 71352993u, 190698941u, 46055428u, 55281366u, 165145231u, 106810753u, 171985651u, 232085256u, 159510492u, 40072060u, 209107596u, 39023794u +}; +static const uint32_t IGNEUM_DS_SAMPLE_VALUE[IGNEUM_DS_SAMPLES] = { + 0x3230bc7bu, 0x7fbfe2c9u, 0xb2690991u, 0x1745c7c5u, 0x0ab0ccafu, 0x1bf87d6bu, 0x160139fdu, 0x719817acu, 0x0155df4bu, 0xbe1e86c3u, 0x680bcd6cu, 0x79c3dc6cu, 0x181e7e5fu, 0x0713a109u, 0xc705dd9fu, 0x3933b7a8u, 0xdd1c0431u, 0x50522b30u, 0xa0020b38u, 0xbff39e96u, 0x21b67e18u, 0x740f8db3u, 0x2baba568u, 0x2c9bef83u, 0x0ad9b671u, 0xc4327869u, 0x7b4fd7d0u, 0x2c29965fu, 0xec56f15fu, 0x61111746u, 0x303a1d6eu, 0xbddcfd1au, 0xf829a355u, 0x6d5df2a9u, 0x01ab8e44u, 0x06d13507u, 0xda8dcfc6u, 0x01a703e1u, 0xafe7d2c1u, 0xc091c3a2u, 0xac1814feu, 0x6e6ff62au, 0x8fdf01bau, 0xdd3f7159u, 0xdfa0d75cu, 0x26684c35u, 0x7f441e63u, 0x88df2570u, 0x8aa4d5ebu, 0xcc816c05u, 0x434df890u, 0xcd392ad6u, 0x1ab4cb63u, 0x595926fau, 0x7cd76b41u, 0x20cb95c4u, 0x13cf823fu, 0xf9daf901u, 0xff9af40au, 0x2c7dfa51u, 0x871206dbu, 0x938c116cu, 0xb64bf199u, 0x5751f874u +}; +// Cache self-test (memory-hard mode): cache[0..15], the last 16 words, and FNV-1a 64 over all 2^26 words. +static const uint32_t IGNEUM_CACHE_HEAD[16] = { + 0x355a86d2u, 0x7957db1cu, 0xd21772afu, 0x6fc1e09bu, 0xd55ce61du, 0x6e6a278bu, 0xd3f543ceu, 0x223d8e82u, + 0x143ab337u, 0x2e9f05bdu, 0x2eb389bfu, 0x0c6e449eu, 0x5cfa4222u, 0xba6560feu, 0x8e3e1aa4u, 0xdbcc1d53u +}; +static const uint32_t IGNEUM_CACHE_LAST[16] = { + 0x41190d91u, 0xbd277957u, 0x22ddbb49u, 0x6986f207u, 0xdf69a4d6u, 0x26401a3au, 0x818230fbu, 0xc417122du, + 0x3597b211u, 0xb553ce55u, 0xcf39cc0du, 0x3b7fc43au, 0x3fd43b00u, 0x67e1c80eu, 0xffa7ea7du, 0xca2960abu +}; +static const uint64_t IGNEUM_CACHE_FNV64 = 0x48c4f5bf24166b2eull; diff --git a/proto-cuda/packs-ca3-shadow/sh256x13/vectors.json b/proto-cuda/packs-ca3-shadow/sh256x13/vectors.json new file mode 100644 index 000000000..b3562c1ef --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x13/vectors.json @@ -0,0 +1,36 @@ +{ + "seed": "igneum-genesis", + "day": "2026-10-03", + "dataset_mode": "memory-hard", + "dataset_log2_words": 28, + "mask": "0x0fffffff", + "lanes": 32, + "source": "igneum-pow (Rust) CPU interpreter, generator v2, memory-hard dataset", + "warps": [ + {"base_nonce": 0, "expected": [ + "0xb359d110ac143375", "0x748fb5308223a682", "0x2a809644b94a8216", "0x18548dad2999d526", "0xb793809331b0a189", "0x55b034de97b5dcfd", "0x9506b188c1becd3c", "0x6f2a3986cb1967b3", + "0x376f13355e35e6c4", "0x35db684678b0567b", "0xfec8f41452c07083", "0x324ad57e71b201e5", "0x1f5def2519b0dff9", "0x07e54a4494f2283d", "0xc698336cb18b866c", "0xc9808c2475fe8d66", + "0x82021978b9d61925", "0x0ef2fa3310887ec6", "0xdb17534bb857c9cc", "0x5203cbc6bdb4bbb2", "0xb0b2b24438cf1cc0", "0xcb1fa6bf5e701935", "0x3dca8b3408c4a3f7", "0xd7610b168cf2943c", + "0xcfe566147a489c75", "0x6294533ee65da77d", "0x2e0774f316868b26", "0xd2a10f4303777610", "0x2e3a4b91c8962246", "0x00063a312aa1f50b", "0x003794aceed11052", "0xcc181405cd575561" + ]}, + {"base_nonce": 4096, "expected": [ + "0x382ff31a848c87ce", "0x9f83773ad5a14bf6", "0xb256ecebb8fcf4dc", "0x000c632632ea0ced", "0xcaf1f89dc457ab50", "0x6a3b9f2156b7b00d", "0x9b428f619265dcfc", "0x907f65c3591b88c6", + "0x0f225df3fbfb67e2", "0x29614e20ca52a926", "0x4655beaea3ad2759", "0xf995b623fcc6644d", "0xce65301573c94490", "0xc7870bc7e5052ee9", "0xf7b89744f3b0b132", "0x80351dd1981ed5e3", + "0xa878aa51b297dcfc", "0x001a834e5e050e8e", "0xca2c133d9937349d", "0x82d3b88dddc886bf", "0x7ae69bce58a3da0c", "0x4561f608a0e10777", "0x86a12f3d2bb459c9", "0x860f5151394991f8", + "0xe55b559c5c954cb8", "0x4bcbcdbefcaf412d", "0x1e74dbd57413e73d", "0x03d197ea39c77502", "0xfdff34586270344a", "0x7e1ff6220cbc0124", "0xba28400b90b409d8", "0x592cd3eb57e1d660" + ]}, + {"base_nonce": 1000000, "expected": [ + "0x99769bd9e253e017", "0xda7db4183c7fb68b", "0xff5782631ce7fa14", "0x5c6494df049901fa", "0x3d49b9a6b55f9ee6", "0xa7f999e4384da8db", "0xd1312b67803a0c72", "0x85f5d8f8bb33dc9f", + "0x63664a37b11f311a", "0x28a4b561cf2f7b36", "0x7674177403abf2c8", "0xf6ef2c094f5cb4af", "0xbdc4a803a2e91ff4", "0x4459a81585f5f6e0", "0xb4098eb87a7489fe", "0x60d9b048e1bbefde", + "0xd0aec740e4aba722", "0x69d9e3e9c99c5391", "0x040fe663cbcbfdc2", "0x38e3b8eab6a7b6b4", "0x8a606e5c69c02b3f", "0xe1dd929d4296cde3", "0x2ad80e84d9072b65", "0xa1f34ff68012fd66", + "0xa2351892f47fbd27", "0xd88d059c58979055", "0x0c5d59a61c9c5b0b", "0xd16f446ddd7119c7", "0x47aa1f6c4b48d944", "0xf6164e14d2937532", "0xd344f8977fd2d100", "0xf76f271447d7d772" + ]} + ], + "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" +} diff --git a/proto-cuda/packs-ca3-shadow/sh256x2/kernel.cl b/proto-cuda/packs-ca3-shadow/sh256x2/kernel.cl new file mode 100644 index 000000000..8d5ca53aa --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x2/kernel.cl @@ -0,0 +1,538 @@ +// 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 ^ 0x67a9a7beu; x += 0x9e3779b9u; x = splitmix32(x); r0 = x ^ 0x1a155b25u; } // SEEDW[0], 0x9e3779b9u * 1u, SEEDW[1] + { uint x = nonce ^ 0x1a155b25u; x += 0x3c6ef372u; x = splitmix32(x); r1 = x ^ 0xfddfb732u; } // SEEDW[1], 0x9e3779b9u * 2u, SEEDW[2] + { uint x = nonce ^ 0xfddfb732u; x += 0xdaa66d2bu; x = splitmix32(x); r2 = x ^ 0x4b5af2e8u; } // SEEDW[2], 0x9e3779b9u * 3u, SEEDW[3] + { uint x = nonce ^ 0x4b5af2e8u; x += 0x78dde6e4u; x = splitmix32(x); r3 = x ^ 0xc55caf33u; } // SEEDW[3], 0x9e3779b9u * 4u, SEEDW[4] + { uint x = nonce ^ 0xc55caf33u; x += 0x1715609du; x = splitmix32(x); r4 = x ^ 0xa27c13b7u; } // SEEDW[4], 0x9e3779b9u * 5u, SEEDW[5] + { uint x = nonce ^ 0xa27c13b7u; x += 0xb54cda56u; x = splitmix32(x); r5 = x ^ 0x06628a48u; } // SEEDW[5], 0x9e3779b9u * 6u, SEEDW[6] + { uint x = nonce ^ 0x06628a48u; x += 0x5384540fu; x = splitmix32(x); r6 = x ^ 0x03852469u; } // SEEDW[6], 0x9e3779b9u * 7u, SEEDW[7] + { uint x = nonce ^ 0x03852469u; x += 0xf1bbcdc8u; x = splitmix32(x); r7 = x ^ 0x67a9a7beu; } // SEEDW[7], 0x9e3779b9u * 8u, SEEDW[0] + + for (uint it = 0u; it < 8u; ++it) { + uint sel = r0; + r2 = r3 * r4 + r2; // 0 mad + r2 = r1 * r1 + r2; // 1 mad + r2 = r3 * r2 + r2; // 2 mad + r3 = r3 ^ r5; // 3 xor + r7 = r7 ^ ds[r2 & mask]; // 4 load + r5 = r5 ^ ds[r7 & mask]; // 5 load + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r1 = r1 ^ t_; } // 6 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r7 = r7 ^ t_; } // 7 shfl + r1 = mul_hi(r1, r5); // 8 mulhi + r6 = rotr_var(r6, r3); // 9 rotr + r3 = r3 | r4; // 10 or + r4 = r4 ^ ds[r3 & mask]; // 11 load + r0 = mul_hi(r0, r4); // 12 mulhi + r5 = r5 + r1 + ((((sel >> 30u) & 1u) != 0u) ? 0xd3177981u : 0xc7934706u); // 13 add + r0 = r0 ^ ds[r4 & mask]; // 14 load + r2 = r2 - r4; // 15 sub + r2 = r2 ^ ds[r0 & mask]; // 16 load + r7 = r7 ^ ds[r2 & mask]; // 17 load + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r7 = r7 ^ t_; } // 18 shfl + r5 = r5 * r0; // 19 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // 20 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 16u); r2 = r2 ^ t_; } // 21 shfl + r6 = mul_hi(r6, r2); // 22 mulhi + r6 = r6 ^ ds[r1 & mask]; // 23 load + r5 = r5 * r0; // 24 mul + r5 = rotl_imm(r5, 19u); // 25 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 2u); r7 = r7 ^ t_; } // 26 shfl + r0 = r0 ^ r5; // 27 xor + r0 = r0 ^ r4; // 28 xor + r3 = r3 - r0; // 29 sub + r5 = r5 * r1; // 30 mul + r7 = r7 ^ ds[r2 & mask]; // 31 load + r1 = r1 ^ ds[r0 & mask]; // 32 load + r5 = r5 ^ r6; // 33 xor + r5 = r5 ^ ds[r1 & mask]; // 34 load + r0 = mul_hi(r0, r5); // 35 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r5 = r5 ^ t_; } // 36 shfl + r7 = r7 ^ ds[r0 & mask]; // 37 load + r3 = r3 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0x230c005cu : 0x75ba2fadu); // 38 add + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 4u); r1 = r1 ^ t_; } // 39 shfl + r2 = r2 ^ r5; // 40 xor + r3 = r6 * r3 + r3; // 41 mad + r6 = r6 - r7; // 42 sub + r7 = r7 ^ r0; // 43 xor + r1 = r1 ^ ds[r7 & mask]; // 44 load + r2 = r2 * r3; // 45 mul + r1 = mul_hi(r1, r5); // 46 mulhi + r4 = r4 - r3; // 47 sub + r2 = rotr_var(r2, r6); // 48 rotr + r3 = r3 ^ ds[r5 & mask]; // 49 load + r1 = r1 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x1907970cu : 0x81b8bc2cu); // 50 add + r0 = r0 * r2; // 51 mul + r0 = r0 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x699fd448u : 0x4f92b968u); // 52 add + r1 = r1 + r0 + ((((sel >> 12u) & 1u) != 0u) ? 0x77b1520du : 0x2bb965afu); // 53 add + r7 = rotl_imm(r7, 14u); // 54 rotl + r3 = r3 + r7 + ((((sel >> 1u) & 1u) != 0u) ? 0xa54c55a0u : 0x7b0fe07au); // 55 add + r6 = r6 ^ ds[r7 & mask]; // 56 load + r1 = rotr_var(r1, r5); // 57 rotr + r5 = r5 ^ ds[r4 & mask]; // 58 load + r6 = r6 ^ ds[r2 & mask]; // 59 load + r3 = r5 * r0 + r3; // 60 mad + r5 = r5 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0xad7493e7u : 0xaf9dd72du); // 61 add + r4 = r4 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x1e07c3d9u : 0x89841d87u); // 62 add + r5 = rotl_imm(r5, 19u); // 63 rotl + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 2 passes after instruction 63, no load + for (uint sh = 0u; sh < 2u; ++sh) { + r5 = r5 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x8bc12da9u : 0x92199f99u); // s0 add + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x63079e5au : 0x8d72d3adu); // s1 add + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 2u); r6 = r6 ^ t_; } // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + ((((sel >> 31u) & 1u) != 0u) ? 0x5d4c7a60u : 0xb21b4babu); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + ((((sel >> 16u) & 1u) != 0u) ? 0xc88e2942u : 0x2fe0e98bu); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r6 = r6 ^ t_; } // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 4u); r2 = r2 ^ t_; } // s12 shfl + r1 = r1 + r5 + ((((sel >> 25u) & 1u) != 0u) ? 0xbc48c63eu : 0xbdf8f9a5u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r2 = r2 ^ t_; } // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + ((((sel >> 1u) & 1u) != 0u) ? 0x96e8f127u : 0x45c37cecu); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = mul_hi(r6, r0); // s28 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r2 = r2 ^ t_; } // s29 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r1 = r1 ^ t_; } // s30 shfl + r1 = r1 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0xb1cdb2abu : 0x37985632u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // s33 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r0 = r0 ^ t_; } // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x856e0180u : 0x804e777eu); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xe9bd0cc4u : 0x0b06c8a7u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = mul_hi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = mul_hi(r4, r3); // s44 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xcdcb63f6u : 0xee822e17u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r4 = r4 ^ t_; } // s47 shfl + r6 = mul_hi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0xd4758987u : 0x3dfad1b6u); // s56 add + r4 = r4 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x0602d6beu : 0xfca75bc2u); // s57 add + r5 = mul_hi(r5, r6); // s58 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r2 = r2 ^ t_; } // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0x8596687au : 0xd71c02ffu); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 2u); r7 = r7 ^ t_; } // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0x08ac5733u : 0x3c6fe15du); // s72 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r3 = r3 ^ t_; } // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + ((((sel >> 1u) & 1u) != 0u) ? 0xc100b495u : 0x295d5faeu); // s77 add + r3 = mul_hi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + ((((sel >> 15u) & 1u) != 0u) ? 0x5cc59530u : 0x274a9221u); // s81 add + r7 = r7 + r3 + ((((sel >> 5u) & 1u) != 0u) ? 0x141479ecu : 0xc8651f8eu); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r2 = r2 ^ t_; } // s85 shfl + r3 = r3 ^ r2; // s86 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 2u); r5 = r5 ^ t_; } // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x883c0c92u : 0x53f915c2u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + ((((sel >> 31u) & 1u) != 0u) ? 0x3cc5bd20u : 0xe2be00a5u); // s91 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 1u); r7 = r7 ^ t_; } // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + ((((sel >> 17u) & 1u) != 0u) ? 0xbfd646cbu : 0x423fd9c9u); // s101 add + r7 = r7 + r6 + ((((sel >> 11u) & 1u) != 0u) ? 0x19b74a43u : 0x8d3c011du); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + ((((sel >> 15u) & 1u) != 0u) ? 0x7dcb7e18u : 0x8ce14721u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = mul_hi(r2, r0); // s109 mulhi + r1 = mul_hi(r1, r0); // s110 mulhi + r0 = r0 + r2 + ((((sel >> 28u) & 1u) != 0u) ? 0x3c179ad8u : 0x2d9fc6b9u); // s111 add + r2 = mul_hi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + ((((sel >> 22u) & 1u) != 0u) ? 0x47359729u : 0x502138e2u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = mul_hi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 2u); r4 = r4 ^ t_; } // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r7 = r7 ^ t_; } // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x6c57e4e7u : 0x33dff776u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + ((((sel >> 30u) & 1u) != 0u) ? 0xe8212c0cu : 0x5db25b34u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = mul_hi(r0, r5); // s138 mulhi + r2 = r2 + r7 + ((((sel >> 10u) & 1u) != 0u) ? 0xd44ff710u : 0x218d4090u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r3 = r3 ^ t_; } // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + ((((sel >> 29u) & 1u) != 0u) ? 0xb98942fau : 0xf4b1a8deu); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + ((((sel >> 17u) & 1u) != 0u) ? 0x0d48ba42u : 0x2bef10f2u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + ((((sel >> 30u) & 1u) != 0u) ? 0xc98dea9cu : 0xdc5cc080u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0x6c752dcbu : 0x18197438u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + ((((sel >> 3u) & 1u) != 0u) ? 0x8e481727u : 0xf1c46574u); // s163 add + r0 = mul_hi(r0, r4); // s164 mulhi + r2 = r2 + r6 + ((((sel >> 20u) & 1u) != 0u) ? 0x550ab406u : 0xac578137u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + ((((sel >> 14u) & 1u) != 0u) ? 0xaebb5966u : 0xa33e6706u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 8u); r7 = r7 ^ t_; } // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x5bb7550fu : 0xd94d55acu); // s184 add + r3 = r3 | r5; // s185 or + r6 = mul_hi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r7 = r7 ^ t_; } // s188 shfl + r6 = r6 + r5 + ((((sel >> 6u) & 1u) != 0u) ? 0x2a354e2du : 0x89e747feu); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = mul_hi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r4 = r4 ^ t_; } // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + ((((sel >> 7u) & 1u) != 0u) ? 0x10cfdc71u : 0xea03e8e7u); // s197 add + r7 = r7 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x66e148d3u : 0xa7ee0102u); // s198 add + r5 = r5 - r2; // s199 sub + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r5 = r5 ^ t_; } // s200 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 8u); r7 = r7 ^ t_; } // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0x8558b619u : 0x8379a4deu); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = mul_hi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 4u); r2 = r2 ^ t_; } // s209 shfl + r7 = r7 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0xf4049c4cu : 0xaa8cb14eu); // s210 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 16u); r7 = r7 ^ t_; } // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 16u); r3 = r3 ^ t_; } // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = mul_hi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r5 = r5 ^ t_; } // s222 shfl + r5 = mul_hi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0x2a7fecb2u : 0x1d176220u); // s230 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r1 = r1 ^ t_; } // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + ((((sel >> 25u) & 1u) != 0u) ? 0xadce39f3u : 0x17dafb4du); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + ((((sel >> 29u) & 1u) != 0u) ? 0x0e7033b6u : 0xf2f77d26u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + ((((sel >> 31u) & 1u) != 0u) ? 0x7b2ff6b7u : 0xfed2da4eu); // s247 add + r0 = r0 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0xb5fad7b1u : 0x03b2891cu); // s248 add + r5 = mul_hi(r5, r4); // s249 mulhi + r5 = r5 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0xa7e71c2fu : 0x042cd6e3u); // s250 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 1u); r6 = r6 ^ t_; } // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0xb83d78deu : 0x784a302bu); // s254 add + r2 = r2 - r4; // s255 sub + } + } + uint lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((ulong)hi << 32) | (ulong)lo; +} + +#if IGNEUM_EXCHANGE != 0 +// Reports the sub-group size this device uses for a work-group of IGNEUM_GROUP items. host.c runs it only when the +// per-kernel query (clGetKernelSubGroupInfoKHR on igneum_hash) is unavailable; that query is preferred because a +// compiler may pick a different wave width per kernel (RDNA: wave32 or wave64). See WAVEFRONT.md. +IGNEUM_KERNEL_HASH void igneum_probe_subgroup(__global uint* out) { + if (get_local_id(0) == 0u) { out[0] = get_sub_group_size(); out[1] = get_num_sub_groups(); } +} +#endif diff --git a/proto-cuda/packs-ca3-shadow/sh256x2/kernel.cu b/proto-cuda/packs-ca3-shadow/sh256x2/kernel.cu new file mode 100644 index 000000000..c56c8d003 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x2/kernel.cu @@ -0,0 +1,423 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Bit-exact twin of the Metal kernel for the same seed (see proto-cuda/CHECKLIST.md and program.metal). +// Compiled ahead of time by nvcc together with proto-cuda/host.cu. No NVRTC. +#include +#include +#include "program.h" +#include "memhard.h" + +__device__ __forceinline__ uint32_t splitmix32(uint32_t x) { + x ^= x >> 16; x *= 0x7feb352du; + x ^= x >> 15; x *= 0x846ca68bu; + x ^= x >> 16; + return x; +} +// n is a literal in 1..31 at every call site, so both shift amounts are in 1..31. +__device__ __forceinline__ uint32_t rotl_imm(uint32_t x, uint32_t n) { return (x << n) | (x >> (32u - n)); } +// n is masked to 0..31; the second shift amount is masked too, so n == 0 gives x. +__device__ __forceinline__ uint32_t rotr_var(uint32_t x, uint32_t n) { n &= 31u; return (x >> n) | (x << ((32u - n) & 31u)); } +__device__ __forceinline__ uint32_t ds_elem(uint32_t i, uint32_t d0, uint32_t d1) { + uint32_t x = i ^ d0; + x *= 0x9E3779B1u; x ^= x >> 15; + x += d1; + x *= 0x85EBCA77u; x ^= x >> 13; + x *= 0xC2B2AE3Du; x ^= x >> 16; + return x; +} + +// Memory-hard dataset (MEMHARD.md). One thread per cache segment; one thread per 64-byte dataset item. +// The core functions (mh_cache_segment, mh_item) are in memhard.h and are also compiled for the host. +__global__ void igneum_cache_fill(uint32_t* cache, uint32_t nSegments) { + uint32_t seg = blockIdx.x * blockDim.x + threadIdx.x; + if (seg < nSegments) mh_cache_segment(cache, seg); +} +__global__ void igneum_build(uint32_t* ds, const uint32_t* cache, uint32_t nItems) { + uint32_t t = blockIdx.x * blockDim.x + threadIdx.x; + if (t < nItems) { + uint32_t s[16]; + mh_item(cache, t, s); + uint32_t* d = ds + (size_t)t * 16u; + for (uint32_t i = 0u; i < 16u; ++i) d[i] = s[i]; + } +} + +// One hash per thread. blockDim.x is a multiple of 32; lane = threadIdx.x & 31 and every +// __shfl_xor_sync stays inside the lane's own warp, exactly like simd_shuffle_xor inside a +// 32-wide Metal SIMD group. Control flow is uniform, so the full 0xffffffff member mask is valid. +__global__ void igneum_hash(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask) { + uint32_t gid = blockIdx.x * blockDim.x + threadIdx.x; + uint32_t nonce = baseNonce + gid; + uint32_t r0, r1, r2, r3, r4, r5, r6, r7; + { uint32_t x = nonce ^ 0x67a9a7beu; x += 0x9e3779b9u; x = splitmix32(x); r0 = x ^ 0x1a155b25u; } // SEEDW[0], 0x9e3779b9u * 1u, SEEDW[1] + { uint32_t x = nonce ^ 0x1a155b25u; x += 0x3c6ef372u; x = splitmix32(x); r1 = x ^ 0xfddfb732u; } // SEEDW[1], 0x9e3779b9u * 2u, SEEDW[2] + { uint32_t x = nonce ^ 0xfddfb732u; x += 0xdaa66d2bu; x = splitmix32(x); r2 = x ^ 0x4b5af2e8u; } // SEEDW[2], 0x9e3779b9u * 3u, SEEDW[3] + { uint32_t x = nonce ^ 0x4b5af2e8u; x += 0x78dde6e4u; x = splitmix32(x); r3 = x ^ 0xc55caf33u; } // SEEDW[3], 0x9e3779b9u * 4u, SEEDW[4] + { uint32_t x = nonce ^ 0xc55caf33u; x += 0x1715609du; x = splitmix32(x); r4 = x ^ 0xa27c13b7u; } // SEEDW[4], 0x9e3779b9u * 5u, SEEDW[5] + { uint32_t x = nonce ^ 0xa27c13b7u; x += 0xb54cda56u; x = splitmix32(x); r5 = x ^ 0x06628a48u; } // SEEDW[5], 0x9e3779b9u * 6u, SEEDW[6] + { uint32_t x = nonce ^ 0x06628a48u; x += 0x5384540fu; x = splitmix32(x); r6 = x ^ 0x03852469u; } // SEEDW[6], 0x9e3779b9u * 7u, SEEDW[7] + { uint32_t x = nonce ^ 0x03852469u; x += 0xf1bbcdc8u; x = splitmix32(x); r7 = x ^ 0x67a9a7beu; } // SEEDW[7], 0x9e3779b9u * 8u, SEEDW[0] + + for (uint32_t it = 0u; it < 8u; ++it) { + uint32_t sel = r0; + r2 = r3 * r4 + r2; // 0 mad + r2 = r1 * r1 + r2; // 1 mad + r2 = r3 * r2 + r2; // 2 mad + r3 = r3 ^ r5; // 3 xor + r7 = r7 ^ ds[r2 & mask]; // 4 load + r5 = r5 ^ ds[r7 & mask]; // 5 load + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r4, 8); // 6 shfl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r3, 8); // 7 shfl + r1 = __umulhi(r1, r5); // 8 mulhi + r6 = rotr_var(r6, r3); // 9 rotr + r3 = r3 | r4; // 10 or + r4 = r4 ^ ds[r3 & mask]; // 11 load + r0 = __umulhi(r0, r4); // 12 mulhi + r5 = r5 + r1 + ((((sel >> 30u) & 1u) != 0u) ? 0xd3177981u : 0xc7934706u); // 13 add + r0 = r0 ^ ds[r4 & mask]; // 14 load + r2 = r2 - r4; // 15 sub + r2 = r2 ^ ds[r0 & mask]; // 16 load + r7 = r7 ^ ds[r2 & mask]; // 17 load + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r3, 4); // 18 shfl + r5 = r5 * r0; // 19 mul + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // 20 shfl + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 16); // 21 shfl + r6 = __umulhi(r6, r2); // 22 mulhi + r6 = r6 ^ ds[r1 & mask]; // 23 load + r5 = r5 * r0; // 24 mul + r5 = rotl_imm(r5, 19u); // 25 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r6, 2); // 26 shfl + r0 = r0 ^ r5; // 27 xor + r0 = r0 ^ r4; // 28 xor + r3 = r3 - r0; // 29 sub + r5 = r5 * r1; // 30 mul + r7 = r7 ^ ds[r2 & mask]; // 31 load + r1 = r1 ^ ds[r0 & mask]; // 32 load + r5 = r5 ^ r6; // 33 xor + r5 = r5 ^ ds[r1 & mask]; // 34 load + r0 = __umulhi(r0, r5); // 35 mulhi + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // 36 shfl + r7 = r7 ^ ds[r0 & mask]; // 37 load + r3 = r3 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0x230c005cu : 0x75ba2fadu); // 38 add + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r5, 4); // 39 shfl + r2 = r2 ^ r5; // 40 xor + r3 = r6 * r3 + r3; // 41 mad + r6 = r6 - r7; // 42 sub + r7 = r7 ^ r0; // 43 xor + r1 = r1 ^ ds[r7 & mask]; // 44 load + r2 = r2 * r3; // 45 mul + r1 = __umulhi(r1, r5); // 46 mulhi + r4 = r4 - r3; // 47 sub + r2 = rotr_var(r2, r6); // 48 rotr + r3 = r3 ^ ds[r5 & mask]; // 49 load + r1 = r1 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x1907970cu : 0x81b8bc2cu); // 50 add + r0 = r0 * r2; // 51 mul + r0 = r0 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x699fd448u : 0x4f92b968u); // 52 add + r1 = r1 + r0 + ((((sel >> 12u) & 1u) != 0u) ? 0x77b1520du : 0x2bb965afu); // 53 add + r7 = rotl_imm(r7, 14u); // 54 rotl + r3 = r3 + r7 + ((((sel >> 1u) & 1u) != 0u) ? 0xa54c55a0u : 0x7b0fe07au); // 55 add + r6 = r6 ^ ds[r7 & mask]; // 56 load + r1 = rotr_var(r1, r5); // 57 rotr + r5 = r5 ^ ds[r4 & mask]; // 58 load + r6 = r6 ^ ds[r2 & mask]; // 59 load + r3 = r5 * r0 + r3; // 60 mad + r5 = r5 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0xad7493e7u : 0xaf9dd72du); // 61 add + r4 = r4 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x1e07c3d9u : 0x89841d87u); // 62 add + r5 = rotl_imm(r5, 19u); // 63 rotl + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 2 passes after instruction 63, no load + for (uint32_t sh = 0u; sh < 2u; ++sh) { + r5 = r5 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x8bc12da9u : 0x92199f99u); // s0 add + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x63079e5au : 0x8d72d3adu); // s1 add + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r3, 2); // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + ((((sel >> 31u) & 1u) != 0u) ? 0x5d4c7a60u : 0xb21b4babu); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + ((((sel >> 16u) & 1u) != 0u) ? 0xc88e2942u : 0x2fe0e98bu); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r1, 4); // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r6, 4); // s12 shfl + r1 = r1 + r5 + ((((sel >> 25u) & 1u) != 0u) ? 0xbc48c63eu : 0xbdf8f9a5u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 8); // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + ((((sel >> 1u) & 1u) != 0u) ? 0x96e8f127u : 0x45c37cecu); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = __umulhi(r6, r0); // s28 mulhi + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // s29 shfl + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r6, 1); // s30 shfl + r1 = r1 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0xb1cdb2abu : 0x37985632u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // s33 shfl + r0 = r0 ^ __shfl_xor_sync(0xffffffffu, r3, 4); // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x856e0180u : 0x804e777eu); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xe9bd0cc4u : 0x0b06c8a7u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = __umulhi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = __umulhi(r4, r3); // s44 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xcdcb63f6u : 0xee822e17u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r3, 8); // s47 shfl + r6 = __umulhi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0xd4758987u : 0x3dfad1b6u); // s56 add + r4 = r4 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x0602d6beu : 0xfca75bc2u); // s57 add + r5 = __umulhi(r5, r6); // s58 mulhi + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0x8596687au : 0xd71c02ffu); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r5, 2); // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0x08ac5733u : 0x3c6fe15du); // s72 add + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r2, 8); // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + ((((sel >> 1u) & 1u) != 0u) ? 0xc100b495u : 0x295d5faeu); // s77 add + r3 = __umulhi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + ((((sel >> 15u) & 1u) != 0u) ? 0x5cc59530u : 0x274a9221u); // s81 add + r7 = r7 + r3 + ((((sel >> 5u) & 1u) != 0u) ? 0x141479ecu : 0xc8651f8eu); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r5, 16); // s85 shfl + r3 = r3 ^ r2; // s86 xor + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r7, 2); // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x883c0c92u : 0x53f915c2u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + ((((sel >> 31u) & 1u) != 0u) ? 0x3cc5bd20u : 0xe2be00a5u); // s91 add + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r2, 1); // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + ((((sel >> 17u) & 1u) != 0u) ? 0xbfd646cbu : 0x423fd9c9u); // s101 add + r7 = r7 + r6 + ((((sel >> 11u) & 1u) != 0u) ? 0x19b74a43u : 0x8d3c011du); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + ((((sel >> 15u) & 1u) != 0u) ? 0x7dcb7e18u : 0x8ce14721u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = __umulhi(r2, r0); // s109 mulhi + r1 = __umulhi(r1, r0); // s110 mulhi + r0 = r0 + r2 + ((((sel >> 28u) & 1u) != 0u) ? 0x3c179ad8u : 0x2d9fc6b9u); // s111 add + r2 = __umulhi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + ((((sel >> 22u) & 1u) != 0u) ? 0x47359729u : 0x502138e2u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = __umulhi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r2, 2); // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x6c57e4e7u : 0x33dff776u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + ((((sel >> 30u) & 1u) != 0u) ? 0xe8212c0cu : 0x5db25b34u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = __umulhi(r0, r5); // s138 mulhi + r2 = r2 + r7 + ((((sel >> 10u) & 1u) != 0u) ? 0xd44ff710u : 0x218d4090u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r6, 1); // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + ((((sel >> 29u) & 1u) != 0u) ? 0xb98942fau : 0xf4b1a8deu); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + ((((sel >> 17u) & 1u) != 0u) ? 0x0d48ba42u : 0x2bef10f2u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + ((((sel >> 30u) & 1u) != 0u) ? 0xc98dea9cu : 0xdc5cc080u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0x6c752dcbu : 0x18197438u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + ((((sel >> 3u) & 1u) != 0u) ? 0x8e481727u : 0xf1c46574u); // s163 add + r0 = __umulhi(r0, r4); // s164 mulhi + r2 = r2 + r6 + ((((sel >> 20u) & 1u) != 0u) ? 0x550ab406u : 0xac578137u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + ((((sel >> 14u) & 1u) != 0u) ? 0xaebb5966u : 0xa33e6706u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r0, 8); // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x5bb7550fu : 0xd94d55acu); // s184 add + r3 = r3 | r5; // s185 or + r6 = __umulhi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s188 shfl + r6 = r6 + r5 + ((((sel >> 6u) & 1u) != 0u) ? 0x2a354e2du : 0x89e747feu); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = __umulhi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r5, 16); // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + ((((sel >> 7u) & 1u) != 0u) ? 0x10cfdc71u : 0xea03e8e7u); // s197 add + r7 = r7 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x66e148d3u : 0xa7ee0102u); // s198 add + r5 = r5 - r2; // s199 sub + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s200 shfl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 8); // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0x8558b619u : 0x8379a4deu); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = __umulhi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r0, 4); // s209 shfl + r7 = r7 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0xf4049c4cu : 0xaa8cb14eu); // s210 add + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 16); // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r2, 16); // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = __umulhi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r2, 8); // s222 shfl + r5 = __umulhi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0x2a7fecb2u : 0x1d176220u); // s230 add + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + ((((sel >> 25u) & 1u) != 0u) ? 0xadce39f3u : 0x17dafb4du); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + ((((sel >> 29u) & 1u) != 0u) ? 0x0e7033b6u : 0xf2f77d26u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + ((((sel >> 31u) & 1u) != 0u) ? 0x7b2ff6b7u : 0xfed2da4eu); // s247 add + r0 = r0 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0xb5fad7b1u : 0x03b2891cu); // s248 add + r5 = __umulhi(r5, r4); // s249 mulhi + r5 = r5 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0xa7e71c2fu : 0x042cd6e3u); // s250 add + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r1, 1); // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0xb83d78deu : 0x784a302bu); // s254 add + r2 = r2 - r4; // s255 sub + } + } + uint32_t lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint32_t hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((uint64_t)hi << 32) | (uint64_t)lo; +} + +// Host-side launch wrappers. Declared in program.h, called from host.cu. +cudaError_t igneum_launch_cache_fill(uint32_t* cache, uint32_t nSegments) { + if (nSegments == 0u) return cudaErrorInvalidValue; + uint32_t block = 256u; + uint32_t grid = (nSegments + block - 1u) / block; + igneum_cache_fill<<>>(cache, nSegments); + return cudaGetLastError(); +} + +cudaError_t igneum_launch_build(uint32_t* ds, const uint32_t* cache, uint32_t nItems) { + if (nItems == 0u) return cudaErrorInvalidValue; + uint32_t block = 256u; + uint32_t grid = (nItems + block - 1u) / block; + igneum_build<<>>(ds, cache, nItems); + return cudaGetLastError(); +} + +cudaError_t igneum_launch_hash(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, + uint32_t nonces, uint32_t blockWarps) { + if (blockWarps == 0u || blockWarps > 32u) return cudaErrorInvalidValue; + uint32_t block = 32u * blockWarps; + if (nonces == 0u || (nonces % block) != 0u) return cudaErrorInvalidValue; + igneum_hash<<>>(ds, out, baseNonce, mask); + return cudaGetLastError(); +} + +cudaError_t igneum_hash_info(int* numRegs, int* blocksPerSM, uint32_t blockWarps) { + cudaFuncAttributes attr; + cudaError_t e = cudaFuncGetAttributes(&attr, igneum_hash); + if (e != cudaSuccess) return e; + *numRegs = attr.numRegs; + return cudaOccupancyMaxActiveBlocksPerMultiprocessor(blocksPerSM, igneum_hash, (int)(32u * blockWarps), 0); +} diff --git a/proto-cuda/packs-ca3-shadow/sh256x2/kernel_bound.cl b/proto-cuda/packs-ca3-shadow/sh256x2/kernel_bound.cl new file mode 100644 index 000000000..b98be4e5f --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x2/kernel_bound.cl @@ -0,0 +1,891 @@ +// 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 ^ 0x67a9a7beu; x += 0x9e3779b9u; x = splitmix32(x); r0 = x ^ 0x1a155b25u; } // SEEDW[0], 0x9e3779b9u * 1u, SEEDW[1] + { uint x = nonce ^ 0x1a155b25u; x += 0x3c6ef372u; x = splitmix32(x); r1 = x ^ 0xfddfb732u; } // SEEDW[1], 0x9e3779b9u * 2u, SEEDW[2] + { uint x = nonce ^ 0xfddfb732u; x += 0xdaa66d2bu; x = splitmix32(x); r2 = x ^ 0x4b5af2e8u; } // SEEDW[2], 0x9e3779b9u * 3u, SEEDW[3] + { uint x = nonce ^ 0x4b5af2e8u; x += 0x78dde6e4u; x = splitmix32(x); r3 = x ^ 0xc55caf33u; } // SEEDW[3], 0x9e3779b9u * 4u, SEEDW[4] + { uint x = nonce ^ 0xc55caf33u; x += 0x1715609du; x = splitmix32(x); r4 = x ^ 0xa27c13b7u; } // SEEDW[4], 0x9e3779b9u * 5u, SEEDW[5] + { uint x = nonce ^ 0xa27c13b7u; x += 0xb54cda56u; x = splitmix32(x); r5 = x ^ 0x06628a48u; } // SEEDW[5], 0x9e3779b9u * 6u, SEEDW[6] + { uint x = nonce ^ 0x06628a48u; x += 0x5384540fu; x = splitmix32(x); r6 = x ^ 0x03852469u; } // SEEDW[6], 0x9e3779b9u * 7u, SEEDW[7] + { uint x = nonce ^ 0x03852469u; x += 0xf1bbcdc8u; x = splitmix32(x); r7 = x ^ 0x67a9a7beu; } // SEEDW[7], 0x9e3779b9u * 8u, SEEDW[0] + + for (uint it = 0u; it < 8u; ++it) { + uint sel = r0; + r2 = r3 * r4 + r2; // 0 mad + r2 = r1 * r1 + r2; // 1 mad + r2 = r3 * r2 + r2; // 2 mad + r3 = r3 ^ r5; // 3 xor + r7 = r7 ^ ds[r2 & mask]; // 4 load + r5 = r5 ^ ds[r7 & mask]; // 5 load + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r1 = r1 ^ t_; } // 6 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r7 = r7 ^ t_; } // 7 shfl + r1 = mul_hi(r1, r5); // 8 mulhi + r6 = rotr_var(r6, r3); // 9 rotr + r3 = r3 | r4; // 10 or + r4 = r4 ^ ds[r3 & mask]; // 11 load + r0 = mul_hi(r0, r4); // 12 mulhi + r5 = r5 + r1 + ((((sel >> 30u) & 1u) != 0u) ? 0xd3177981u : 0xc7934706u); // 13 add + r0 = r0 ^ ds[r4 & mask]; // 14 load + r2 = r2 - r4; // 15 sub + r2 = r2 ^ ds[r0 & mask]; // 16 load + r7 = r7 ^ ds[r2 & mask]; // 17 load + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r7 = r7 ^ t_; } // 18 shfl + r5 = r5 * r0; // 19 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // 20 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 16u); r2 = r2 ^ t_; } // 21 shfl + r6 = mul_hi(r6, r2); // 22 mulhi + r6 = r6 ^ ds[r1 & mask]; // 23 load + r5 = r5 * r0; // 24 mul + r5 = rotl_imm(r5, 19u); // 25 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 2u); r7 = r7 ^ t_; } // 26 shfl + r0 = r0 ^ r5; // 27 xor + r0 = r0 ^ r4; // 28 xor + r3 = r3 - r0; // 29 sub + r5 = r5 * r1; // 30 mul + r7 = r7 ^ ds[r2 & mask]; // 31 load + r1 = r1 ^ ds[r0 & mask]; // 32 load + r5 = r5 ^ r6; // 33 xor + r5 = r5 ^ ds[r1 & mask]; // 34 load + r0 = mul_hi(r0, r5); // 35 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r5 = r5 ^ t_; } // 36 shfl + r7 = r7 ^ ds[r0 & mask]; // 37 load + r3 = r3 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0x230c005cu : 0x75ba2fadu); // 38 add + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 4u); r1 = r1 ^ t_; } // 39 shfl + r2 = r2 ^ r5; // 40 xor + r3 = r6 * r3 + r3; // 41 mad + r6 = r6 - r7; // 42 sub + r7 = r7 ^ r0; // 43 xor + r1 = r1 ^ ds[r7 & mask]; // 44 load + r2 = r2 * r3; // 45 mul + r1 = mul_hi(r1, r5); // 46 mulhi + r4 = r4 - r3; // 47 sub + r2 = rotr_var(r2, r6); // 48 rotr + r3 = r3 ^ ds[r5 & mask]; // 49 load + r1 = r1 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x1907970cu : 0x81b8bc2cu); // 50 add + r0 = r0 * r2; // 51 mul + r0 = r0 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x699fd448u : 0x4f92b968u); // 52 add + r1 = r1 + r0 + ((((sel >> 12u) & 1u) != 0u) ? 0x77b1520du : 0x2bb965afu); // 53 add + r7 = rotl_imm(r7, 14u); // 54 rotl + r3 = r3 + r7 + ((((sel >> 1u) & 1u) != 0u) ? 0xa54c55a0u : 0x7b0fe07au); // 55 add + r6 = r6 ^ ds[r7 & mask]; // 56 load + r1 = rotr_var(r1, r5); // 57 rotr + r5 = r5 ^ ds[r4 & mask]; // 58 load + r6 = r6 ^ ds[r2 & mask]; // 59 load + r3 = r5 * r0 + r3; // 60 mad + r5 = r5 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0xad7493e7u : 0xaf9dd72du); // 61 add + r4 = r4 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x1e07c3d9u : 0x89841d87u); // 62 add + r5 = rotl_imm(r5, 19u); // 63 rotl + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 2 passes after instruction 63, no load + for (uint sh = 0u; sh < 2u; ++sh) { + r5 = r5 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x8bc12da9u : 0x92199f99u); // s0 add + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x63079e5au : 0x8d72d3adu); // s1 add + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 2u); r6 = r6 ^ t_; } // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + ((((sel >> 31u) & 1u) != 0u) ? 0x5d4c7a60u : 0xb21b4babu); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + ((((sel >> 16u) & 1u) != 0u) ? 0xc88e2942u : 0x2fe0e98bu); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r6 = r6 ^ t_; } // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 4u); r2 = r2 ^ t_; } // s12 shfl + r1 = r1 + r5 + ((((sel >> 25u) & 1u) != 0u) ? 0xbc48c63eu : 0xbdf8f9a5u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r2 = r2 ^ t_; } // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + ((((sel >> 1u) & 1u) != 0u) ? 0x96e8f127u : 0x45c37cecu); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = mul_hi(r6, r0); // s28 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r2 = r2 ^ t_; } // s29 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r1 = r1 ^ t_; } // s30 shfl + r1 = r1 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0xb1cdb2abu : 0x37985632u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // s33 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r0 = r0 ^ t_; } // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x856e0180u : 0x804e777eu); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xe9bd0cc4u : 0x0b06c8a7u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = mul_hi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = mul_hi(r4, r3); // s44 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xcdcb63f6u : 0xee822e17u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r4 = r4 ^ t_; } // s47 shfl + r6 = mul_hi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0xd4758987u : 0x3dfad1b6u); // s56 add + r4 = r4 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x0602d6beu : 0xfca75bc2u); // s57 add + r5 = mul_hi(r5, r6); // s58 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r2 = r2 ^ t_; } // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0x8596687au : 0xd71c02ffu); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 2u); r7 = r7 ^ t_; } // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0x08ac5733u : 0x3c6fe15du); // s72 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r3 = r3 ^ t_; } // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + ((((sel >> 1u) & 1u) != 0u) ? 0xc100b495u : 0x295d5faeu); // s77 add + r3 = mul_hi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + ((((sel >> 15u) & 1u) != 0u) ? 0x5cc59530u : 0x274a9221u); // s81 add + r7 = r7 + r3 + ((((sel >> 5u) & 1u) != 0u) ? 0x141479ecu : 0xc8651f8eu); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r2 = r2 ^ t_; } // s85 shfl + r3 = r3 ^ r2; // s86 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 2u); r5 = r5 ^ t_; } // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x883c0c92u : 0x53f915c2u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + ((((sel >> 31u) & 1u) != 0u) ? 0x3cc5bd20u : 0xe2be00a5u); // s91 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 1u); r7 = r7 ^ t_; } // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + ((((sel >> 17u) & 1u) != 0u) ? 0xbfd646cbu : 0x423fd9c9u); // s101 add + r7 = r7 + r6 + ((((sel >> 11u) & 1u) != 0u) ? 0x19b74a43u : 0x8d3c011du); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + ((((sel >> 15u) & 1u) != 0u) ? 0x7dcb7e18u : 0x8ce14721u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = mul_hi(r2, r0); // s109 mulhi + r1 = mul_hi(r1, r0); // s110 mulhi + r0 = r0 + r2 + ((((sel >> 28u) & 1u) != 0u) ? 0x3c179ad8u : 0x2d9fc6b9u); // s111 add + r2 = mul_hi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + ((((sel >> 22u) & 1u) != 0u) ? 0x47359729u : 0x502138e2u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = mul_hi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 2u); r4 = r4 ^ t_; } // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r7 = r7 ^ t_; } // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x6c57e4e7u : 0x33dff776u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + ((((sel >> 30u) & 1u) != 0u) ? 0xe8212c0cu : 0x5db25b34u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = mul_hi(r0, r5); // s138 mulhi + r2 = r2 + r7 + ((((sel >> 10u) & 1u) != 0u) ? 0xd44ff710u : 0x218d4090u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r3 = r3 ^ t_; } // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + ((((sel >> 29u) & 1u) != 0u) ? 0xb98942fau : 0xf4b1a8deu); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + ((((sel >> 17u) & 1u) != 0u) ? 0x0d48ba42u : 0x2bef10f2u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + ((((sel >> 30u) & 1u) != 0u) ? 0xc98dea9cu : 0xdc5cc080u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0x6c752dcbu : 0x18197438u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + ((((sel >> 3u) & 1u) != 0u) ? 0x8e481727u : 0xf1c46574u); // s163 add + r0 = mul_hi(r0, r4); // s164 mulhi + r2 = r2 + r6 + ((((sel >> 20u) & 1u) != 0u) ? 0x550ab406u : 0xac578137u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + ((((sel >> 14u) & 1u) != 0u) ? 0xaebb5966u : 0xa33e6706u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 8u); r7 = r7 ^ t_; } // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x5bb7550fu : 0xd94d55acu); // s184 add + r3 = r3 | r5; // s185 or + r6 = mul_hi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r7 = r7 ^ t_; } // s188 shfl + r6 = r6 + r5 + ((((sel >> 6u) & 1u) != 0u) ? 0x2a354e2du : 0x89e747feu); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = mul_hi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r4 = r4 ^ t_; } // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + ((((sel >> 7u) & 1u) != 0u) ? 0x10cfdc71u : 0xea03e8e7u); // s197 add + r7 = r7 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x66e148d3u : 0xa7ee0102u); // s198 add + r5 = r5 - r2; // s199 sub + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r5 = r5 ^ t_; } // s200 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 8u); r7 = r7 ^ t_; } // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0x8558b619u : 0x8379a4deu); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = mul_hi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 4u); r2 = r2 ^ t_; } // s209 shfl + r7 = r7 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0xf4049c4cu : 0xaa8cb14eu); // s210 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 16u); r7 = r7 ^ t_; } // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 16u); r3 = r3 ^ t_; } // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = mul_hi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r5 = r5 ^ t_; } // s222 shfl + r5 = mul_hi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0x2a7fecb2u : 0x1d176220u); // s230 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r1 = r1 ^ t_; } // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + ((((sel >> 25u) & 1u) != 0u) ? 0xadce39f3u : 0x17dafb4du); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + ((((sel >> 29u) & 1u) != 0u) ? 0x0e7033b6u : 0xf2f77d26u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + ((((sel >> 31u) & 1u) != 0u) ? 0x7b2ff6b7u : 0xfed2da4eu); // s247 add + r0 = r0 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0xb5fad7b1u : 0x03b2891cu); // s248 add + r5 = mul_hi(r5, r4); // s249 mulhi + r5 = r5 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0xa7e71c2fu : 0x042cd6e3u); // s250 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 1u); r6 = r6 ^ t_; } // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0xb83d78deu : 0x784a302bu); // s254 add + r2 = r2 - r4; // s255 sub + } + } + 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 = r3 * r4 + r2; // 0 mad + r2 = r1 * r1 + r2; // 1 mad + r2 = r3 * r2 + r2; // 2 mad + r3 = r3 ^ r5; // 3 xor + r7 = r7 ^ ds[r2 & mask]; // 4 load + r5 = r5 ^ ds[r7 & mask]; // 5 load + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r1 = r1 ^ t_; } // 6 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r7 = r7 ^ t_; } // 7 shfl + r1 = mul_hi(r1, r5); // 8 mulhi + r6 = rotr_var(r6, r3); // 9 rotr + r3 = r3 | r4; // 10 or + r4 = r4 ^ ds[r3 & mask]; // 11 load + r0 = mul_hi(r0, r4); // 12 mulhi + r5 = r5 + r1 + ((((sel >> 30u) & 1u) != 0u) ? 0xd3177981u : 0xc7934706u); // 13 add + r0 = r0 ^ ds[r4 & mask]; // 14 load + r2 = r2 - r4; // 15 sub + r2 = r2 ^ ds[r0 & mask]; // 16 load + r7 = r7 ^ ds[r2 & mask]; // 17 load + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r7 = r7 ^ t_; } // 18 shfl + r5 = r5 * r0; // 19 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // 20 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 16u); r2 = r2 ^ t_; } // 21 shfl + r6 = mul_hi(r6, r2); // 22 mulhi + r6 = r6 ^ ds[r1 & mask]; // 23 load + r5 = r5 * r0; // 24 mul + r5 = rotl_imm(r5, 19u); // 25 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 2u); r7 = r7 ^ t_; } // 26 shfl + r0 = r0 ^ r5; // 27 xor + r0 = r0 ^ r4; // 28 xor + r3 = r3 - r0; // 29 sub + r5 = r5 * r1; // 30 mul + r7 = r7 ^ ds[r2 & mask]; // 31 load + r1 = r1 ^ ds[r0 & mask]; // 32 load + r5 = r5 ^ r6; // 33 xor + r5 = r5 ^ ds[r1 & mask]; // 34 load + r0 = mul_hi(r0, r5); // 35 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r5 = r5 ^ t_; } // 36 shfl + r7 = r7 ^ ds[r0 & mask]; // 37 load + r3 = r3 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0x230c005cu : 0x75ba2fadu); // 38 add + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 4u); r1 = r1 ^ t_; } // 39 shfl + r2 = r2 ^ r5; // 40 xor + r3 = r6 * r3 + r3; // 41 mad + r6 = r6 - r7; // 42 sub + r7 = r7 ^ r0; // 43 xor + r1 = r1 ^ ds[r7 & mask]; // 44 load + r2 = r2 * r3; // 45 mul + r1 = mul_hi(r1, r5); // 46 mulhi + r4 = r4 - r3; // 47 sub + r2 = rotr_var(r2, r6); // 48 rotr + r3 = r3 ^ ds[r5 & mask]; // 49 load + r1 = r1 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x1907970cu : 0x81b8bc2cu); // 50 add + r0 = r0 * r2; // 51 mul + r0 = r0 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x699fd448u : 0x4f92b968u); // 52 add + r1 = r1 + r0 + ((((sel >> 12u) & 1u) != 0u) ? 0x77b1520du : 0x2bb965afu); // 53 add + r7 = rotl_imm(r7, 14u); // 54 rotl + r3 = r3 + r7 + ((((sel >> 1u) & 1u) != 0u) ? 0xa54c55a0u : 0x7b0fe07au); // 55 add + r6 = r6 ^ ds[r7 & mask]; // 56 load + r1 = rotr_var(r1, r5); // 57 rotr + r5 = r5 ^ ds[r4 & mask]; // 58 load + r6 = r6 ^ ds[r2 & mask]; // 59 load + r3 = r5 * r0 + r3; // 60 mad + r5 = r5 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0xad7493e7u : 0xaf9dd72du); // 61 add + r4 = r4 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x1e07c3d9u : 0x89841d87u); // 62 add + r5 = rotl_imm(r5, 19u); // 63 rotl + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 2 passes after instruction 63, no load + for (uint sh = 0u; sh < 2u; ++sh) { + r5 = r5 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x8bc12da9u : 0x92199f99u); // s0 add + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x63079e5au : 0x8d72d3adu); // s1 add + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 2u); r6 = r6 ^ t_; } // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + ((((sel >> 31u) & 1u) != 0u) ? 0x5d4c7a60u : 0xb21b4babu); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + ((((sel >> 16u) & 1u) != 0u) ? 0xc88e2942u : 0x2fe0e98bu); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r6 = r6 ^ t_; } // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 4u); r2 = r2 ^ t_; } // s12 shfl + r1 = r1 + r5 + ((((sel >> 25u) & 1u) != 0u) ? 0xbc48c63eu : 0xbdf8f9a5u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r2 = r2 ^ t_; } // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + ((((sel >> 1u) & 1u) != 0u) ? 0x96e8f127u : 0x45c37cecu); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = mul_hi(r6, r0); // s28 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r2 = r2 ^ t_; } // s29 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r1 = r1 ^ t_; } // s30 shfl + r1 = r1 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0xb1cdb2abu : 0x37985632u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // s33 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r0 = r0 ^ t_; } // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x856e0180u : 0x804e777eu); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xe9bd0cc4u : 0x0b06c8a7u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = mul_hi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = mul_hi(r4, r3); // s44 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xcdcb63f6u : 0xee822e17u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r4 = r4 ^ t_; } // s47 shfl + r6 = mul_hi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0xd4758987u : 0x3dfad1b6u); // s56 add + r4 = r4 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x0602d6beu : 0xfca75bc2u); // s57 add + r5 = mul_hi(r5, r6); // s58 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r2 = r2 ^ t_; } // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0x8596687au : 0xd71c02ffu); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 2u); r7 = r7 ^ t_; } // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0x08ac5733u : 0x3c6fe15du); // s72 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r3 = r3 ^ t_; } // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + ((((sel >> 1u) & 1u) != 0u) ? 0xc100b495u : 0x295d5faeu); // s77 add + r3 = mul_hi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + ((((sel >> 15u) & 1u) != 0u) ? 0x5cc59530u : 0x274a9221u); // s81 add + r7 = r7 + r3 + ((((sel >> 5u) & 1u) != 0u) ? 0x141479ecu : 0xc8651f8eu); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r2 = r2 ^ t_; } // s85 shfl + r3 = r3 ^ r2; // s86 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 2u); r5 = r5 ^ t_; } // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x883c0c92u : 0x53f915c2u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + ((((sel >> 31u) & 1u) != 0u) ? 0x3cc5bd20u : 0xe2be00a5u); // s91 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 1u); r7 = r7 ^ t_; } // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + ((((sel >> 17u) & 1u) != 0u) ? 0xbfd646cbu : 0x423fd9c9u); // s101 add + r7 = r7 + r6 + ((((sel >> 11u) & 1u) != 0u) ? 0x19b74a43u : 0x8d3c011du); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + ((((sel >> 15u) & 1u) != 0u) ? 0x7dcb7e18u : 0x8ce14721u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = mul_hi(r2, r0); // s109 mulhi + r1 = mul_hi(r1, r0); // s110 mulhi + r0 = r0 + r2 + ((((sel >> 28u) & 1u) != 0u) ? 0x3c179ad8u : 0x2d9fc6b9u); // s111 add + r2 = mul_hi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + ((((sel >> 22u) & 1u) != 0u) ? 0x47359729u : 0x502138e2u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = mul_hi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 2u); r4 = r4 ^ t_; } // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r7 = r7 ^ t_; } // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x6c57e4e7u : 0x33dff776u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + ((((sel >> 30u) & 1u) != 0u) ? 0xe8212c0cu : 0x5db25b34u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = mul_hi(r0, r5); // s138 mulhi + r2 = r2 + r7 + ((((sel >> 10u) & 1u) != 0u) ? 0xd44ff710u : 0x218d4090u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r3 = r3 ^ t_; } // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + ((((sel >> 29u) & 1u) != 0u) ? 0xb98942fau : 0xf4b1a8deu); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + ((((sel >> 17u) & 1u) != 0u) ? 0x0d48ba42u : 0x2bef10f2u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + ((((sel >> 30u) & 1u) != 0u) ? 0xc98dea9cu : 0xdc5cc080u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0x6c752dcbu : 0x18197438u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + ((((sel >> 3u) & 1u) != 0u) ? 0x8e481727u : 0xf1c46574u); // s163 add + r0 = mul_hi(r0, r4); // s164 mulhi + r2 = r2 + r6 + ((((sel >> 20u) & 1u) != 0u) ? 0x550ab406u : 0xac578137u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + ((((sel >> 14u) & 1u) != 0u) ? 0xaebb5966u : 0xa33e6706u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 8u); r7 = r7 ^ t_; } // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x5bb7550fu : 0xd94d55acu); // s184 add + r3 = r3 | r5; // s185 or + r6 = mul_hi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r7 = r7 ^ t_; } // s188 shfl + r6 = r6 + r5 + ((((sel >> 6u) & 1u) != 0u) ? 0x2a354e2du : 0x89e747feu); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = mul_hi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r4 = r4 ^ t_; } // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + ((((sel >> 7u) & 1u) != 0u) ? 0x10cfdc71u : 0xea03e8e7u); // s197 add + r7 = r7 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x66e148d3u : 0xa7ee0102u); // s198 add + r5 = r5 - r2; // s199 sub + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r5 = r5 ^ t_; } // s200 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 8u); r7 = r7 ^ t_; } // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0x8558b619u : 0x8379a4deu); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = mul_hi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 4u); r2 = r2 ^ t_; } // s209 shfl + r7 = r7 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0xf4049c4cu : 0xaa8cb14eu); // s210 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 16u); r7 = r7 ^ t_; } // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 16u); r3 = r3 ^ t_; } // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = mul_hi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r5 = r5 ^ t_; } // s222 shfl + r5 = mul_hi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0x2a7fecb2u : 0x1d176220u); // s230 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r1 = r1 ^ t_; } // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + ((((sel >> 25u) & 1u) != 0u) ? 0xadce39f3u : 0x17dafb4du); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + ((((sel >> 29u) & 1u) != 0u) ? 0x0e7033b6u : 0xf2f77d26u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + ((((sel >> 31u) & 1u) != 0u) ? 0x7b2ff6b7u : 0xfed2da4eu); // s247 add + r0 = r0 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0xb5fad7b1u : 0x03b2891cu); // s248 add + r5 = mul_hi(r5, r4); // s249 mulhi + r5 = r5 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0xa7e71c2fu : 0x042cd6e3u); // s250 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 1u); r6 = r6 ^ t_; } // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0xb83d78deu : 0x784a302bu); // s254 add + r2 = r2 - r4; // s255 sub + } + } + uint lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((ulong)hi << 32) | (ulong)lo; +} diff --git a/proto-cuda/packs-ca3-shadow/sh256x2/kernel_bound.cu b/proto-cuda/packs-ca3-shadow/sh256x2/kernel_bound.cu new file mode 100644 index 000000000..a21c99632 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x2/kernel_bound.cu @@ -0,0 +1,382 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Header-bound twin of igneum_hash in kernel.cu: the init words come from a kernel argument, not SEEDW. +// Host declarations (also in program_bound.h if present): +// struct IgneumInitWords { uint32_t w[8]; }; +// cudaError_t igneum_launch_hash_bound(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, +// IgneumInitWords iw, uint32_t nonces, uint32_t blockWarps); +// cudaError_t igneum_hash_bound_info(int* numRegs, int* blocksPerSM, uint32_t blockWarps); +#include +#include +#include "program.h" + +struct IgneumInitWords { uint32_t w[8]; }; + +__device__ __forceinline__ uint32_t splitmix32(uint32_t x) { + x ^= x >> 16; x *= 0x7feb352du; + x ^= x >> 15; x *= 0x846ca68bu; + x ^= x >> 16; + return x; +} +__device__ __forceinline__ uint32_t rotl_imm(uint32_t x, uint32_t n) { return (x << n) | (x >> (32u - n)); } +__device__ __forceinline__ uint32_t rotr_var(uint32_t x, uint32_t n) { n &= 31u; return (x >> n) | (x << ((32u - n) & 31u)); } + +__global__ void igneum_hash_bound(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, IgneumInitWords iw) { + uint32_t gid = blockIdx.x * blockDim.x + threadIdx.x; + uint32_t nonce = baseNonce + gid; + uint32_t r0, r1, r2, r3, r4, r5, r6, r7; + { uint32_t x = nonce ^ iw.w[0]; x += 0x9e3779b9u * 1u; x = splitmix32(x); r0 = x ^ iw.w[1]; } + { uint32_t x = nonce ^ iw.w[1]; x += 0x9e3779b9u * 2u; x = splitmix32(x); r1 = x ^ iw.w[2]; } + { uint32_t x = nonce ^ iw.w[2]; x += 0x9e3779b9u * 3u; x = splitmix32(x); r2 = x ^ iw.w[3]; } + { uint32_t x = nonce ^ iw.w[3]; x += 0x9e3779b9u * 4u; x = splitmix32(x); r3 = x ^ iw.w[4]; } + { uint32_t x = nonce ^ iw.w[4]; x += 0x9e3779b9u * 5u; x = splitmix32(x); r4 = x ^ iw.w[5]; } + { uint32_t x = nonce ^ iw.w[5]; x += 0x9e3779b9u * 6u; x = splitmix32(x); r5 = x ^ iw.w[6]; } + { uint32_t x = nonce ^ iw.w[6]; x += 0x9e3779b9u * 7u; x = splitmix32(x); r6 = x ^ iw.w[7]; } + { uint32_t x = nonce ^ iw.w[7]; x += 0x9e3779b9u * 8u; x = splitmix32(x); r7 = x ^ iw.w[0]; } + + for (uint32_t it = 0u; it < 8u; ++it) { + uint32_t sel = r0; + r2 = r3 * r4 + r2; // 0 mad + r2 = r1 * r1 + r2; // 1 mad + r2 = r3 * r2 + r2; // 2 mad + r3 = r3 ^ r5; // 3 xor + r7 = r7 ^ ds[r2 & mask]; // 4 load + r5 = r5 ^ ds[r7 & mask]; // 5 load + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r4, 8); // 6 shfl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r3, 8); // 7 shfl + r1 = __umulhi(r1, r5); // 8 mulhi + r6 = rotr_var(r6, r3); // 9 rotr + r3 = r3 | r4; // 10 or + r4 = r4 ^ ds[r3 & mask]; // 11 load + r0 = __umulhi(r0, r4); // 12 mulhi + r5 = r5 + r1 + ((((sel >> 30u) & 1u) != 0u) ? 0xd3177981u : 0xc7934706u); // 13 add + r0 = r0 ^ ds[r4 & mask]; // 14 load + r2 = r2 - r4; // 15 sub + r2 = r2 ^ ds[r0 & mask]; // 16 load + r7 = r7 ^ ds[r2 & mask]; // 17 load + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r3, 4); // 18 shfl + r5 = r5 * r0; // 19 mul + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // 20 shfl + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 16); // 21 shfl + r6 = __umulhi(r6, r2); // 22 mulhi + r6 = r6 ^ ds[r1 & mask]; // 23 load + r5 = r5 * r0; // 24 mul + r5 = rotl_imm(r5, 19u); // 25 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r6, 2); // 26 shfl + r0 = r0 ^ r5; // 27 xor + r0 = r0 ^ r4; // 28 xor + r3 = r3 - r0; // 29 sub + r5 = r5 * r1; // 30 mul + r7 = r7 ^ ds[r2 & mask]; // 31 load + r1 = r1 ^ ds[r0 & mask]; // 32 load + r5 = r5 ^ r6; // 33 xor + r5 = r5 ^ ds[r1 & mask]; // 34 load + r0 = __umulhi(r0, r5); // 35 mulhi + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // 36 shfl + r7 = r7 ^ ds[r0 & mask]; // 37 load + r3 = r3 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0x230c005cu : 0x75ba2fadu); // 38 add + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r5, 4); // 39 shfl + r2 = r2 ^ r5; // 40 xor + r3 = r6 * r3 + r3; // 41 mad + r6 = r6 - r7; // 42 sub + r7 = r7 ^ r0; // 43 xor + r1 = r1 ^ ds[r7 & mask]; // 44 load + r2 = r2 * r3; // 45 mul + r1 = __umulhi(r1, r5); // 46 mulhi + r4 = r4 - r3; // 47 sub + r2 = rotr_var(r2, r6); // 48 rotr + r3 = r3 ^ ds[r5 & mask]; // 49 load + r1 = r1 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x1907970cu : 0x81b8bc2cu); // 50 add + r0 = r0 * r2; // 51 mul + r0 = r0 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x699fd448u : 0x4f92b968u); // 52 add + r1 = r1 + r0 + ((((sel >> 12u) & 1u) != 0u) ? 0x77b1520du : 0x2bb965afu); // 53 add + r7 = rotl_imm(r7, 14u); // 54 rotl + r3 = r3 + r7 + ((((sel >> 1u) & 1u) != 0u) ? 0xa54c55a0u : 0x7b0fe07au); // 55 add + r6 = r6 ^ ds[r7 & mask]; // 56 load + r1 = rotr_var(r1, r5); // 57 rotr + r5 = r5 ^ ds[r4 & mask]; // 58 load + r6 = r6 ^ ds[r2 & mask]; // 59 load + r3 = r5 * r0 + r3; // 60 mad + r5 = r5 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0xad7493e7u : 0xaf9dd72du); // 61 add + r4 = r4 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x1e07c3d9u : 0x89841d87u); // 62 add + r5 = rotl_imm(r5, 19u); // 63 rotl + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 2 passes after instruction 63, no load + for (uint32_t sh = 0u; sh < 2u; ++sh) { + r5 = r5 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x8bc12da9u : 0x92199f99u); // s0 add + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x63079e5au : 0x8d72d3adu); // s1 add + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r3, 2); // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + ((((sel >> 31u) & 1u) != 0u) ? 0x5d4c7a60u : 0xb21b4babu); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + ((((sel >> 16u) & 1u) != 0u) ? 0xc88e2942u : 0x2fe0e98bu); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r1, 4); // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r6, 4); // s12 shfl + r1 = r1 + r5 + ((((sel >> 25u) & 1u) != 0u) ? 0xbc48c63eu : 0xbdf8f9a5u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 8); // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + ((((sel >> 1u) & 1u) != 0u) ? 0x96e8f127u : 0x45c37cecu); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = __umulhi(r6, r0); // s28 mulhi + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // s29 shfl + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r6, 1); // s30 shfl + r1 = r1 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0xb1cdb2abu : 0x37985632u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // s33 shfl + r0 = r0 ^ __shfl_xor_sync(0xffffffffu, r3, 4); // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x856e0180u : 0x804e777eu); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xe9bd0cc4u : 0x0b06c8a7u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = __umulhi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = __umulhi(r4, r3); // s44 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xcdcb63f6u : 0xee822e17u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r3, 8); // s47 shfl + r6 = __umulhi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0xd4758987u : 0x3dfad1b6u); // s56 add + r4 = r4 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x0602d6beu : 0xfca75bc2u); // s57 add + r5 = __umulhi(r5, r6); // s58 mulhi + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0x8596687au : 0xd71c02ffu); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r5, 2); // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0x08ac5733u : 0x3c6fe15du); // s72 add + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r2, 8); // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + ((((sel >> 1u) & 1u) != 0u) ? 0xc100b495u : 0x295d5faeu); // s77 add + r3 = __umulhi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + ((((sel >> 15u) & 1u) != 0u) ? 0x5cc59530u : 0x274a9221u); // s81 add + r7 = r7 + r3 + ((((sel >> 5u) & 1u) != 0u) ? 0x141479ecu : 0xc8651f8eu); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r5, 16); // s85 shfl + r3 = r3 ^ r2; // s86 xor + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r7, 2); // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x883c0c92u : 0x53f915c2u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + ((((sel >> 31u) & 1u) != 0u) ? 0x3cc5bd20u : 0xe2be00a5u); // s91 add + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r2, 1); // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + ((((sel >> 17u) & 1u) != 0u) ? 0xbfd646cbu : 0x423fd9c9u); // s101 add + r7 = r7 + r6 + ((((sel >> 11u) & 1u) != 0u) ? 0x19b74a43u : 0x8d3c011du); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + ((((sel >> 15u) & 1u) != 0u) ? 0x7dcb7e18u : 0x8ce14721u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = __umulhi(r2, r0); // s109 mulhi + r1 = __umulhi(r1, r0); // s110 mulhi + r0 = r0 + r2 + ((((sel >> 28u) & 1u) != 0u) ? 0x3c179ad8u : 0x2d9fc6b9u); // s111 add + r2 = __umulhi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + ((((sel >> 22u) & 1u) != 0u) ? 0x47359729u : 0x502138e2u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = __umulhi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r2, 2); // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x6c57e4e7u : 0x33dff776u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + ((((sel >> 30u) & 1u) != 0u) ? 0xe8212c0cu : 0x5db25b34u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = __umulhi(r0, r5); // s138 mulhi + r2 = r2 + r7 + ((((sel >> 10u) & 1u) != 0u) ? 0xd44ff710u : 0x218d4090u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r6, 1); // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + ((((sel >> 29u) & 1u) != 0u) ? 0xb98942fau : 0xf4b1a8deu); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + ((((sel >> 17u) & 1u) != 0u) ? 0x0d48ba42u : 0x2bef10f2u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + ((((sel >> 30u) & 1u) != 0u) ? 0xc98dea9cu : 0xdc5cc080u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0x6c752dcbu : 0x18197438u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + ((((sel >> 3u) & 1u) != 0u) ? 0x8e481727u : 0xf1c46574u); // s163 add + r0 = __umulhi(r0, r4); // s164 mulhi + r2 = r2 + r6 + ((((sel >> 20u) & 1u) != 0u) ? 0x550ab406u : 0xac578137u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + ((((sel >> 14u) & 1u) != 0u) ? 0xaebb5966u : 0xa33e6706u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r0, 8); // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x5bb7550fu : 0xd94d55acu); // s184 add + r3 = r3 | r5; // s185 or + r6 = __umulhi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s188 shfl + r6 = r6 + r5 + ((((sel >> 6u) & 1u) != 0u) ? 0x2a354e2du : 0x89e747feu); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = __umulhi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r5, 16); // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + ((((sel >> 7u) & 1u) != 0u) ? 0x10cfdc71u : 0xea03e8e7u); // s197 add + r7 = r7 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x66e148d3u : 0xa7ee0102u); // s198 add + r5 = r5 - r2; // s199 sub + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s200 shfl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 8); // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0x8558b619u : 0x8379a4deu); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = __umulhi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r0, 4); // s209 shfl + r7 = r7 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0xf4049c4cu : 0xaa8cb14eu); // s210 add + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 16); // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r2, 16); // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = __umulhi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r2, 8); // s222 shfl + r5 = __umulhi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0x2a7fecb2u : 0x1d176220u); // s230 add + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + ((((sel >> 25u) & 1u) != 0u) ? 0xadce39f3u : 0x17dafb4du); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + ((((sel >> 29u) & 1u) != 0u) ? 0x0e7033b6u : 0xf2f77d26u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + ((((sel >> 31u) & 1u) != 0u) ? 0x7b2ff6b7u : 0xfed2da4eu); // s247 add + r0 = r0 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0xb5fad7b1u : 0x03b2891cu); // s248 add + r5 = __umulhi(r5, r4); // s249 mulhi + r5 = r5 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0xa7e71c2fu : 0x042cd6e3u); // s250 add + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r1, 1); // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0xb83d78deu : 0x784a302bu); // s254 add + r2 = r2 - r4; // s255 sub + } + } + uint32_t lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint32_t hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((uint64_t)hi << 32) | (uint64_t)lo; +} + +cudaError_t igneum_launch_hash_bound(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, + IgneumInitWords iw, uint32_t nonces, uint32_t blockWarps) { + if (blockWarps == 0u || blockWarps > 32u) return cudaErrorInvalidValue; + uint32_t block = 32u * blockWarps; + if (nonces == 0u || (nonces % block) != 0u) return cudaErrorInvalidValue; + igneum_hash_bound<<>>(ds, out, baseNonce, mask, iw); + return cudaGetLastError(); +} + +cudaError_t igneum_hash_bound_info(int* numRegs, int* blocksPerSM, uint32_t blockWarps) { + cudaFuncAttributes attr; + cudaError_t e = cudaFuncGetAttributes(&attr, igneum_hash_bound); + if (e != cudaSuccess) return e; + *numRegs = attr.numRegs; + return cudaOccupancyMaxActiveBlocksPerMultiprocessor(blocksPerSM, igneum_hash_bound, (int)(32u * blockWarps), 0); +} diff --git a/proto-cuda/packs-ca3-shadow/sh256x2/memhard.h b/proto-cuda/packs-ca3-shadow/sh256x2/memhard.h new file mode 100644 index 000000000..f7f34c732 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x2/memhard.h @@ -0,0 +1,109 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Memory-hard dataset core, the same text that the Mac's Metal kernels and CPU verifier were checked against. +// Included by kernel.cu (device), host.cu (host reference) and proto-opencl/host.c (C99 host reference). +// See proto-metal/MEMHARD.md for the construction. kernel.cl carries the same text in OpenCL C. +#pragma once +#ifdef __cplusplus +#include +#else +#include +#endif +#if defined(__CUDACC__) +#define IGNEUM_HD __host__ __device__ __forceinline__ +#elif defined(_MSC_VER) && !defined(__cplusplus) +#define IGNEUM_HD static __inline +#else +#define IGNEUM_HD static inline +#endif +// Memory-hard dataset core (MEMHARD.md). Cache: 2^26 words in 2^16 segments of 64 chained ChaCha12 lines. +// Item: 8 rounds of 8 x seed-parameterised mixer + one 64-byte cache read, then 8 x final mixer (class v3, mixer multiplier 8, +// docs/plans/mixer-x4.md: the round key of application j of round r is 0x9E3779B9 * (r * m + j + 1)). All parameters are literals. +#define MH_CACHE_LINE_MASK 0x003fffffu +#define MH_SEGMENT_LINES 64u +#define MH_QR(a, b, c, d, r1, r2, r3, r4) { a += b; d ^= a; d = mh_rotl(d, r1); c += d; b ^= c; b = mh_rotl(b, r2); a += b; d ^= a; d = mh_rotl(d, r3); c += d; b ^= c; b = mh_rotl(b, r4); } +IGNEUM_HD uint32_t mh_rotl(uint32_t x, uint32_t n) { return (x << n) | (x >> (32u - n)); } // n in 1..31 at every call site + +// y = ChaCha12 core(x) + x +IGNEUM_HD void mh_chacha_block(const uint32_t* x, uint32_t* y) { + for (uint32_t i = 0u; i < 16u; ++i) y[i] = x[i]; + for (uint32_t r = 0u; r < 6u; ++r) { + MH_QR(y[0], y[4], y[8], y[12], 16u, 12u, 8u, 7u) MH_QR(y[1], y[5], y[9], y[13], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[6], y[10], y[14], 16u, 12u, 8u, 7u) MH_QR(y[3], y[7], y[11], y[15], 16u, 12u, 8u, 7u) + MH_QR(y[0], y[5], y[10], y[15], 16u, 12u, 8u, 7u) MH_QR(y[1], y[6], y[11], y[12], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[7], y[8], y[13], 16u, 12u, 8u, 7u) MH_QR(y[3], y[4], y[9], y[14], 16u, 12u, 8u, 7u) + } + for (uint32_t i = 0u; i < 16u; ++i) y[i] += x[i]; +} + +// One cache segment: 64 chained lines written at cache[seg * 1024]. in_j = prev ^ (sigma || K || seg || j || tag), prev_0 = 0. +IGNEUM_HD void mh_cache_segment(uint32_t* cache, uint32_t seg) { + uint32_t prev[16]; uint32_t x[16]; uint32_t y[16]; + for (uint32_t i = 0u; i < 16u; ++i) prev[i] = 0u; + for (uint32_t j = 0u; j < MH_SEGMENT_LINES; ++j) { + x[0] = 0x61707865u ^ prev[0]; x[1] = 0x3320646eu ^ prev[1]; x[2] = 0x79622d32u ^ prev[2]; x[3] = 0x6b206574u ^ prev[3]; + x[4] = 0x3067619fu ^ prev[4]; + x[5] = 0x3c269176u ^ prev[5]; + x[6] = 0x84a03b03u ^ prev[6]; + x[7] = 0xf8c63294u ^ prev[7]; + x[8] = 0xff977c5bu ^ prev[8]; + x[9] = 0xe60def3eu ^ prev[9]; + x[10] = 0x63630141u ^ prev[10]; + x[11] = 0xb8fbcb58u ^ prev[11]; + x[12] = seg ^ prev[12]; x[13] = j ^ prev[13]; x[14] = 0x49676e65u ^ prev[14]; x[15] = 0x756d4d48u ^ prev[15]; + mh_chacha_block(x, y); + uint32_t* line = cache + ((seg * MH_SEGMENT_LINES + j) * 16u); + for (uint32_t i = 0u; i < 16u; ++i) { line[i] = y[i]; prev[i] = y[i]; } + } +} + +// M_r: per word (s ^ (RC + rk)) * MUL, then a column round and a diagonal round with the seed-drawn rotations. +IGNEUM_HD void mh_mixer(uint32_t* s, uint32_t rk) { + s[0] = (s[0] ^ (0xbab68293u + rk)) * 0x42146205u; + s[1] = (s[1] ^ (0xcc162340u + rk)) * 0x52cbe0fbu; + s[2] = (s[2] ^ (0x6ce151ccu + rk)) * 0x7ecf4a03u; + s[3] = (s[3] ^ (0xe62b8997u + rk)) * 0x6728907fu; + s[4] = (s[4] ^ (0xc9c80297u + rk)) * 0xd81d9751u; + s[5] = (s[5] ^ (0xf74a1654u + rk)) * 0x132952c3u; + s[6] = (s[6] ^ (0x3d704af5u + rk)) * 0xf60de277u; + s[7] = (s[7] ^ (0x3cf522b7u + rk)) * 0x05358035u; + s[8] = (s[8] ^ (0x2b9cac04u + rk)) * 0xbaf6499du; + s[9] = (s[9] ^ (0xa880ac10u + rk)) * 0xe4db9667u; + s[10] = (s[10] ^ (0x13e5dd1du + rk)) * 0x3e98f45du; + s[11] = (s[11] ^ (0x6fc3e233u + rk)) * 0xd0004eddu; + s[12] = (s[12] ^ (0x2d83eeacu + rk)) * 0x2691630du; + s[13] = (s[13] ^ (0x9006e8bfu + rk)) * 0x9beb3bcfu; + s[14] = (s[14] ^ (0x2c4b5362u + rk)) * 0xab310379u; + s[15] = (s[15] ^ (0x31b49ee2u + rk)) * 0x99cfb423u; + MH_QR(s[0], s[4], s[8], s[12], 20u, 20u, 19u, 4u) MH_QR(s[1], s[5], s[9], s[13], 20u, 20u, 19u, 4u) + MH_QR(s[2], s[6], s[10], s[14], 20u, 20u, 19u, 4u) MH_QR(s[3], s[7], s[11], s[15], 20u, 20u, 19u, 4u) + MH_QR(s[0], s[5], s[10], s[15], 26u, 3u, 3u, 27u) MH_QR(s[1], s[6], s[11], s[12], 26u, 3u, 3u, 27u) + MH_QR(s[2], s[7], s[8], s[13], 26u, 3u, 3u, 27u) MH_QR(s[3], s[4], s[9], s[14], 26u, 3u, 3u, 27u) +} + +// Item t: 16 words. s = (K, t * MUL[i] + RC[i]); 8 rounds of 8 x mixer + cache line s[0] & mask; 8 x final mixer. +IGNEUM_HD void mh_item(const uint32_t* cache, uint32_t t, uint32_t* s) { + s[0] = 0x3067619fu; + s[1] = 0x3c269176u; + s[2] = 0x84a03b03u; + s[3] = 0xf8c63294u; + s[4] = 0xff977c5bu; + s[5] = 0xe60def3eu; + s[6] = 0x63630141u; + s[7] = 0xb8fbcb58u; + s[8] = t * 0x42146205u + 0xbab68293u; + s[9] = t * 0x52cbe0fbu + 0xcc162340u; + s[10] = t * 0x7ecf4a03u + 0x6ce151ccu; + s[11] = t * 0x6728907fu + 0xe62b8997u; + s[12] = t * 0xd81d9751u + 0xc9c80297u; + s[13] = t * 0x132952c3u + 0xf74a1654u; + s[14] = t * 0xf60de277u + 0x3d704af5u; + s[15] = t * 0x05358035u + 0x3cf522b7u; + for (uint32_t r = 0u; r < 8u; ++r) { + for (uint32_t j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (r * 8u + j + 1u)); + const uint32_t* line = cache + ((s[0] & MH_CACHE_LINE_MASK) * 16u); + for (uint32_t i = 0u; i < 16u; ++i) s[i] ^= line[i]; + } + for (uint32_t j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (64u + j + 1u)); +} +// dataset[w] without the dataset: derive item w >> 4 and take word w & 15. +IGNEUM_HD uint32_t mh_word(const uint32_t* cache, uint32_t w) { uint32_t s[16]; mh_item(cache, w >> 4u, s); return s[w & 15u]; } diff --git a/proto-cuda/packs-ca3-shadow/sh256x2/memhard.metal b/proto-cuda/packs-ca3-shadow/sh256x2/memhard.metal new file mode 100644 index 000000000..01b263d6d --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x2/memhard.metal @@ -0,0 +1,107 @@ +#include +using namespace metal; +// Memory-hard dataset core (MEMHARD.md). Cache: 2^26 words in 2^16 segments of 64 chained ChaCha12 lines. +// Item: 8 rounds of 8 x seed-parameterised mixer + one 64-byte cache read, then 8 x final mixer (class v3, mixer multiplier 8, +// docs/plans/mixer-x4.md: the round key of application j of round r is 0x9E3779B9 * (r * m + j + 1)). All parameters are literals. +#define MH_CACHE_LINE_MASK 0x003fffffu +#define MH_SEGMENT_LINES 64u +#define MH_QR(a, b, c, d, r1, r2, r3, r4) { a += b; d ^= a; d = mh_rotl(d, r1); c += d; b ^= c; b = mh_rotl(b, r2); a += b; d ^= a; d = mh_rotl(d, r3); c += d; b ^= c; b = mh_rotl(b, r4); } +inline uint mh_rotl(uint x, uint n) { return (x << n) | (x >> (32u - n)); } // n in 1..31 at every call site + +// y = ChaCha12 core(x) + x +inline void mh_chacha_block(const thread uint* x, thread uint* y) { + for (uint i = 0u; i < 16u; ++i) y[i] = x[i]; + for (uint r = 0u; r < 6u; ++r) { + MH_QR(y[0], y[4], y[8], y[12], 16u, 12u, 8u, 7u) MH_QR(y[1], y[5], y[9], y[13], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[6], y[10], y[14], 16u, 12u, 8u, 7u) MH_QR(y[3], y[7], y[11], y[15], 16u, 12u, 8u, 7u) + MH_QR(y[0], y[5], y[10], y[15], 16u, 12u, 8u, 7u) MH_QR(y[1], y[6], y[11], y[12], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[7], y[8], y[13], 16u, 12u, 8u, 7u) MH_QR(y[3], y[4], y[9], y[14], 16u, 12u, 8u, 7u) + } + for (uint i = 0u; i < 16u; ++i) y[i] += x[i]; +} + +// One cache segment: 64 chained lines written at cache[seg * 1024]. in_j = prev ^ (sigma || K || seg || j || tag), prev_0 = 0. +inline void mh_cache_segment(device uint* cache, uint seg) { + uint prev[16]; uint x[16]; uint y[16]; + for (uint i = 0u; i < 16u; ++i) prev[i] = 0u; + for (uint j = 0u; j < MH_SEGMENT_LINES; ++j) { + x[0] = 0x61707865u ^ prev[0]; x[1] = 0x3320646eu ^ prev[1]; x[2] = 0x79622d32u ^ prev[2]; x[3] = 0x6b206574u ^ prev[3]; + x[4] = 0x3067619fu ^ prev[4]; + x[5] = 0x3c269176u ^ prev[5]; + x[6] = 0x84a03b03u ^ prev[6]; + x[7] = 0xf8c63294u ^ prev[7]; + x[8] = 0xff977c5bu ^ prev[8]; + x[9] = 0xe60def3eu ^ prev[9]; + x[10] = 0x63630141u ^ prev[10]; + x[11] = 0xb8fbcb58u ^ prev[11]; + x[12] = seg ^ prev[12]; x[13] = j ^ prev[13]; x[14] = 0x49676e65u ^ prev[14]; x[15] = 0x756d4d48u ^ prev[15]; + mh_chacha_block(x, y); + device uint* line = cache + ((seg * MH_SEGMENT_LINES + j) * 16u); + for (uint i = 0u; i < 16u; ++i) { line[i] = y[i]; prev[i] = y[i]; } + } +} + +// M_r: per word (s ^ (RC + rk)) * MUL, then a column round and a diagonal round with the seed-drawn rotations. +inline void mh_mixer(thread uint* s, uint rk) { + s[0] = (s[0] ^ (0xbab68293u + rk)) * 0x42146205u; + s[1] = (s[1] ^ (0xcc162340u + rk)) * 0x52cbe0fbu; + s[2] = (s[2] ^ (0x6ce151ccu + rk)) * 0x7ecf4a03u; + s[3] = (s[3] ^ (0xe62b8997u + rk)) * 0x6728907fu; + s[4] = (s[4] ^ (0xc9c80297u + rk)) * 0xd81d9751u; + s[5] = (s[5] ^ (0xf74a1654u + rk)) * 0x132952c3u; + s[6] = (s[6] ^ (0x3d704af5u + rk)) * 0xf60de277u; + s[7] = (s[7] ^ (0x3cf522b7u + rk)) * 0x05358035u; + s[8] = (s[8] ^ (0x2b9cac04u + rk)) * 0xbaf6499du; + s[9] = (s[9] ^ (0xa880ac10u + rk)) * 0xe4db9667u; + s[10] = (s[10] ^ (0x13e5dd1du + rk)) * 0x3e98f45du; + s[11] = (s[11] ^ (0x6fc3e233u + rk)) * 0xd0004eddu; + s[12] = (s[12] ^ (0x2d83eeacu + rk)) * 0x2691630du; + s[13] = (s[13] ^ (0x9006e8bfu + rk)) * 0x9beb3bcfu; + s[14] = (s[14] ^ (0x2c4b5362u + rk)) * 0xab310379u; + s[15] = (s[15] ^ (0x31b49ee2u + rk)) * 0x99cfb423u; + MH_QR(s[0], s[4], s[8], s[12], 20u, 20u, 19u, 4u) MH_QR(s[1], s[5], s[9], s[13], 20u, 20u, 19u, 4u) + MH_QR(s[2], s[6], s[10], s[14], 20u, 20u, 19u, 4u) MH_QR(s[3], s[7], s[11], s[15], 20u, 20u, 19u, 4u) + MH_QR(s[0], s[5], s[10], s[15], 26u, 3u, 3u, 27u) MH_QR(s[1], s[6], s[11], s[12], 26u, 3u, 3u, 27u) + MH_QR(s[2], s[7], s[8], s[13], 26u, 3u, 3u, 27u) MH_QR(s[3], s[4], s[9], s[14], 26u, 3u, 3u, 27u) +} + +// Item t: 16 words. s = (K, t * MUL[i] + RC[i]); 8 rounds of 8 x mixer + cache line s[0] & mask; 8 x final mixer. +inline void mh_item(device const uint* cache, uint t, thread uint* s) { + s[0] = 0x3067619fu; + s[1] = 0x3c269176u; + s[2] = 0x84a03b03u; + s[3] = 0xf8c63294u; + s[4] = 0xff977c5bu; + s[5] = 0xe60def3eu; + s[6] = 0x63630141u; + s[7] = 0xb8fbcb58u; + s[8] = t * 0x42146205u + 0xbab68293u; + s[9] = t * 0x52cbe0fbu + 0xcc162340u; + s[10] = t * 0x7ecf4a03u + 0x6ce151ccu; + s[11] = t * 0x6728907fu + 0xe62b8997u; + s[12] = t * 0xd81d9751u + 0xc9c80297u; + s[13] = t * 0x132952c3u + 0xf74a1654u; + s[14] = t * 0xf60de277u + 0x3d704af5u; + s[15] = t * 0x05358035u + 0x3cf522b7u; + for (uint r = 0u; r < 8u; ++r) { + for (uint j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (r * 8u + j + 1u)); + device const uint* line = cache + ((s[0] & MH_CACHE_LINE_MASK) * 16u); + for (uint i = 0u; i < 16u; ++i) s[i] ^= line[i]; + } + for (uint j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (64u + j + 1u)); +} +// dataset[w] without the dataset: derive item w >> 4 and take word w & 15. +inline uint mh_word(device const uint* cache, uint w) { uint s[16]; mh_item(cache, w >> 4u, s); return s[w & 15u]; } + +// One thread per segment (2^16 threads). +kernel void igneum_cache_fill(device uint* cache [[buffer(0)]], uint gid [[thread_position_in_grid]]) { + mh_cache_segment(cache, gid); +} +// One thread per 64-byte item (dataset words / 16 threads). +kernel void igneum_build(device const uint* cache [[buffer(0)]], device uint* dataset [[buffer(1)]], + uint gid [[thread_position_in_grid]]) { + uint s[16]; + mh_item(cache, gid, s); + device uint* d = dataset + gid * 16u; + for (uint i = 0u; i < 16u; ++i) d[i] = s[i]; +} diff --git a/proto-cuda/packs-ca3-shadow/sh256x2/program.h b/proto-cuda/packs-ca3-shadow/sh256x2/program.h new file mode 100644 index 000000000..a0562122b --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x2/program.h @@ -0,0 +1,70 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Program metadata for host.cu plus the launch wrappers defined in kernel.cu. +// Also included by proto-opencl/host.c (C99), which defines IGNEUM_NO_CUDA first and reads only the macros. +#pragma once +#ifdef __cplusplus +#include +#else +#include +#endif +#ifndef IGNEUM_NO_CUDA +#include +#endif + +#define IGNEUM_SEED_STRING "igneum-genesis" +#define IGNEUM_SEED_BYTES_HEX "69676e65756d2d67656e65736973" +#define IGNEUM_GENERATOR 2 +#define IGNEUM_PROGRAM_ATTEMPT 0 +#define IGNEUM_PROGRAM_ID 0x9a3d4d853ae722fbull +#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 add=8 shfl=8 xor=6 mad=5 mul=5 mulhi=5 sub=4 rotl=3 rotr=3 or=1" +// 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+sh256x2" +#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 2 +#define IGNEUM_SHADOW_INSTRS_PER_HASH 4096 +#define IGNEUM_SHADOW_OP_MIX "add=47 rotl=30 xor=30 shfl=29 mad=27 mul=22 sub=21 rotr=20 mulhi=18 or=12" +// 0 = closed-form dataset (ds_elem), 1 = memory-hard cache construction (MEMHARD.md, memhard.h) +#define IGNEUM_DATASET_MODE 1 + +#define IGNEUM_SEEDW_INIT { 0x67a9a7beu, 0x1a155b25u, 0xfddfb732u, 0x4b5af2e8u, 0xc55caf33u, 0xa27c13b7u, 0x06628a48u, 0x03852469u } +#define IGNEUM_KEY_INIT { 0x3067619fu, 0x3c269176u, 0x84a03b03u, 0xf8c63294u, 0xff977c5bu, 0xe60def3eu, 0x63630141u, 0xb8fbcb58u } +#define IGNEUM_CACHE_LOG2_WORDS 26 +#define IGNEUM_CACHE_SEGMENT_LOG2_LINES 6 +#define IGNEUM_CACHE_SEGMENTS 65536u +#define IGNEUM_ITEM_ROUNDS 8 +#define IGNEUM_MIXER_MULT 8 // mixer applications per round and after the last read (class v3, docs/plans/mixer-x4.md) +#define IGNEUM_MIX_ROT_INIT { 20u, 20u, 19u, 4u, 26u, 3u, 3u, 27u } +#define IGNEUM_MIX_MUL_INIT { 0x42146205u, 0x52cbe0fbu, 0x7ecf4a03u, 0x6728907fu, 0xd81d9751u, 0x132952c3u, 0xf60de277u, 0x05358035u, 0xbaf6499du, 0xe4db9667u, 0x3e98f45du, 0xd0004eddu, 0x2691630du, 0x9beb3bcfu, 0xab310379u, 0x99cfb423u } +#define IGNEUM_MIX_RC_INIT { 0xbab68293u, 0xcc162340u, 0x6ce151ccu, 0xe62b8997u, 0xc9c80297u, 0xf74a1654u, 0x3d704af5u, 0x3cf522b7u, 0x2b9cac04u, 0xa880ac10u, 0x13e5dd1du, 0x6fc3e233u, 0x2d83eeacu, 0x9006e8bfu, 0x2c4b5362u, 0x31b49ee2u } + +#ifndef IGNEUM_NO_CUDA +// Defined in kernel.cu. All launch on the default stream and return cudaGetLastError(). +cudaError_t igneum_launch_cache_fill(uint32_t* cache, uint32_t nSegments); +cudaError_t igneum_launch_build(uint32_t* ds, const uint32_t* cache, uint32_t nItems); +cudaError_t igneum_launch_hash(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, + uint32_t nonces, uint32_t blockWarps); +cudaError_t igneum_hash_info(int* numRegs, int* blocksPerSM, uint32_t blockWarps); +#endif diff --git a/proto-cuda/packs-ca3-shadow/sh256x2/program.json b/proto-cuda/packs-ca3-shadow/sh256x2/program.json new file mode 100644 index 000000000..f614ebbe1 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x2/program.json @@ -0,0 +1,389 @@ +{ + "format": "igneum-program-pack-3", + "generator": 2, + "attempt": 0, + "program_id": "0x9a3d4d853ae722fb", + "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": ["0x67a9a7be", "0x1a155b25", "0xfddfb732", "0x4b5af2e8", "0xc55caf33", "0xa27c13b7", "0x06628a48", "0x03852469"], + "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+sh256x2", + "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, "add": 8, "shfl": 8, "xor": 6, "mad": 5, "mul": 5, "mulhi": 5, "sub": 4, "rotl": 3, "rotr": 3, "or": 1}, + "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": 2, "instrs_per_hash": 4096, "op_mix": {"add": 47, "rotl": 30, "xor": 30, "shfl": 29, "mad": 27, "mul": 22, "sub": 21, "rotr": 20, "mulhi": 18, "or": 12}, "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": "add", "dst": 5, "src": 2, "src2": 1, "imm": "0x92199f99", "imm2": "0x8bc12da9", "rot": 9, "bit": 18, "mask": 4}, + {"i": 1, "op": "add", "dst": 0, "src": 7, "src2": 1, "imm": "0x8d72d3ad", "imm2": "0x63079e5a", "rot": 20, "bit": 26, "mask": 4}, + {"i": 2, "op": "shfl", "dst": 6, "src": 3, "src2": 6, "imm": "0x9beaeddf", "imm2": "0x744ecb00", "rot": 10, "bit": 4, "mask": 2}, + {"i": 3, "op": "sub", "dst": 4, "src": 2, "src2": 0, "imm": "0x2a3ddc67", "imm2": "0x72c80241", "rot": 30, "bit": 1, "mask": 16}, + {"i": 4, "op": "add", "dst": 7, "src": 0, "src2": 5, "imm": "0xb21b4bab", "imm2": "0x5d4c7a60", "rot": 17, "bit": 31, "mask": 4}, + {"i": 5, "op": "rotl", "dst": 0, "src": 6, "src2": 3, "imm": "0xe69d7919", "imm2": "0xa048c61e", "rot": 11, "bit": 1, "mask": 8}, + {"i": 6, "op": "add", "dst": 0, "src": 1, "src2": 3, "imm": "0x2fe0e98b", "imm2": "0xc88e2942", "rot": 5, "bit": 16, "mask": 16}, + {"i": 7, "op": "xor", "dst": 7, "src": 1, "src2": 0, "imm": "0xc16efe98", "imm2": "0x01a638c8", "rot": 8, "bit": 17, "mask": 1}, + {"i": 8, "op": "mad", "dst": 1, "src": 6, "src2": 5, "imm": "0x76ec7b8b", "imm2": "0x25663feb", "rot": 29, "bit": 30, "mask": 2}, + {"i": 9, "op": "shfl", "dst": 6, "src": 1, "src2": 0, "imm": "0x6c8ee3cb", "imm2": "0xea93237e", "rot": 27, "bit": 1, "mask": 4}, + {"i": 10, "op": "mad", "dst": 1, "src": 2, "src2": 2, "imm": "0x6dc4ea18", "imm2": "0x6efde6f5", "rot": 3, "bit": 20, "mask": 2}, + {"i": 11, "op": "mad", "dst": 5, "src": 0, "src2": 3, "imm": "0x023613fc", "imm2": "0x18c51939", "rot": 19, "bit": 31, "mask": 1}, + {"i": 12, "op": "shfl", "dst": 2, "src": 6, "src2": 1, "imm": "0x74aec8d2", "imm2": "0x7f7ad29c", "rot": 7, "bit": 8, "mask": 4}, + {"i": 13, "op": "add", "dst": 1, "src": 5, "src2": 6, "imm": "0xbdf8f9a5", "imm2": "0xbc48c63e", "rot": 6, "bit": 25, "mask": 2}, + {"i": 14, "op": "rotl", "dst": 1, "src": 2, "src2": 6, "imm": "0x7ad8ca8b", "imm2": "0x14c712ad", "rot": 29, "bit": 25, "mask": 8}, + {"i": 15, "op": "sub", "dst": 1, "src": 4, "src2": 5, "imm": "0xd3349f69", "imm2": "0x70aac45a", "rot": 29, "bit": 9, "mask": 16}, + {"i": 16, "op": "or", "dst": 7, "src": 1, "src2": 2, "imm": "0x08168ed1", "imm2": "0x28964037", "rot": 26, "bit": 0, "mask": 2}, + {"i": 17, "op": "shfl", "dst": 2, "src": 4, "src2": 6, "imm": "0x98d85f72", "imm2": "0x3dc87042", "rot": 29, "bit": 22, "mask": 8}, + {"i": 18, "op": "xor", "dst": 7, "src": 4, "src2": 0, "imm": "0x651d4a0e", "imm2": "0x93c198bd", "rot": 26, "bit": 12, "mask": 8}, + {"i": 19, "op": "mul", "dst": 6, "src": 1, "src2": 6, "imm": "0xd38ce89d", "imm2": "0x3dfad388", "rot": 5, "bit": 28, "mask": 8}, + {"i": 20, "op": "mad", "dst": 5, "src": 6, "src2": 0, "imm": "0x59d78b36", "imm2": "0xc4db274e", "rot": 25, "bit": 24, "mask": 1}, + {"i": 21, "op": "sub", "dst": 3, "src": 1, "src2": 7, "imm": "0xf6c6a6c7", "imm2": "0x8536f4e6", "rot": 6, "bit": 12, "mask": 4}, + {"i": 22, "op": "mul", "dst": 6, "src": 0, "src2": 7, "imm": "0x599445b4", "imm2": "0x632f8c32", "rot": 19, "bit": 4, "mask": 8}, + {"i": 23, "op": "add", "dst": 2, "src": 0, "src2": 7, "imm": "0x45c37cec", "imm2": "0x96e8f127", "rot": 15, "bit": 1, "mask": 4}, + {"i": 24, "op": "sub", "dst": 6, "src": 4, "src2": 3, "imm": "0xc1c44491", "imm2": "0x92e3ce57", "rot": 20, "bit": 25, "mask": 4}, + {"i": 25, "op": "mad", "dst": 7, "src": 3, "src2": 4, "imm": "0x89bfb8d3", "imm2": "0x19b5455e", "rot": 22, "bit": 2, "mask": 16}, + {"i": 26, "op": "rotl", "dst": 3, "src": 5, "src2": 7, "imm": "0x2f47ce8d", "imm2": "0x8b458ec5", "rot": 9, "bit": 0, "mask": 4}, + {"i": 27, "op": "sub", "dst": 2, "src": 1, "src2": 2, "imm": "0x9f0dce23", "imm2": "0x3cdca814", "rot": 25, "bit": 1, "mask": 2}, + {"i": 28, "op": "mulhi", "dst": 6, "src": 0, "src2": 3, "imm": "0x61fc9eb8", "imm2": "0x23202e9d", "rot": 30, "bit": 16, "mask": 16}, + {"i": 29, "op": "shfl", "dst": 2, "src": 4, "src2": 3, "imm": "0x339dbd65", "imm2": "0xc175f639", "rot": 15, "bit": 22, "mask": 2}, + {"i": 30, "op": "shfl", "dst": 1, "src": 6, "src2": 1, "imm": "0x5bd14589", "imm2": "0xa68a2bed", "rot": 31, "bit": 31, "mask": 1}, + {"i": 31, "op": "add", "dst": 1, "src": 6, "src2": 1, "imm": "0x37985632", "imm2": "0xb1cdb2ab", "rot": 29, "bit": 1, "mask": 8}, + {"i": 32, "op": "rotr", "dst": 0, "src": 1, "src2": 6, "imm": "0x4b2058f4", "imm2": "0xf06d8ac9", "rot": 9, "bit": 15, "mask": 16}, + {"i": 33, "op": "shfl", "dst": 3, "src": 4, "src2": 4, "imm": "0x2081626c", "imm2": "0x08d1bb87", "rot": 24, "bit": 29, "mask": 2}, + {"i": 34, "op": "shfl", "dst": 0, "src": 3, "src2": 6, "imm": "0xe4fcfe03", "imm2": "0x78a46b13", "rot": 15, "bit": 29, "mask": 4}, + {"i": 35, "op": "mul", "dst": 7, "src": 0, "src2": 4, "imm": "0x33148d30", "imm2": "0x5780a3d6", "rot": 6, "bit": 11, "mask": 2}, + {"i": 36, "op": "add", "dst": 3, "src": 1, "src2": 1, "imm": "0x804e777e", "imm2": "0x856e0180", "rot": 22, "bit": 0, "mask": 16}, + {"i": 37, "op": "xor", "dst": 1, "src": 6, "src2": 0, "imm": "0xc69aa2f6", "imm2": "0xafebe3e8", "rot": 15, "bit": 9, "mask": 16}, + {"i": 38, "op": "mul", "dst": 2, "src": 7, "src2": 4, "imm": "0xeb4c4082", "imm2": "0x3f1e0da7", "rot": 25, "bit": 20, "mask": 16}, + {"i": 39, "op": "add", "dst": 6, "src": 5, "src2": 5, "imm": "0x0b06c8a7", "imm2": "0xe9bd0cc4", "rot": 6, "bit": 2, "mask": 4}, + {"i": 40, "op": "mul", "dst": 5, "src": 7, "src2": 7, "imm": "0x070af1b6", "imm2": "0x6b648e75", "rot": 10, "bit": 6, "mask": 16}, + {"i": 41, "op": "mulhi", "dst": 2, "src": 3, "src2": 2, "imm": "0x389753b2", "imm2": "0x9e657305", "rot": 30, "bit": 2, "mask": 4}, + {"i": 42, "op": "xor", "dst": 2, "src": 0, "src2": 4, "imm": "0x0960e5b9", "imm2": "0xa925a406", "rot": 4, "bit": 6, "mask": 16}, + {"i": 43, "op": "rotl", "dst": 0, "src": 1, "src2": 1, "imm": "0x8eabe09f", "imm2": "0x76ef71e2", "rot": 4, "bit": 19, "mask": 8}, + {"i": 44, "op": "mulhi", "dst": 4, "src": 3, "src2": 7, "imm": "0x6a34768a", "imm2": "0x2e427c64", "rot": 21, "bit": 5, "mask": 4}, + {"i": 45, "op": "add", "dst": 6, "src": 7, "src2": 5, "imm": "0xee822e17", "imm2": "0xcdcb63f6", "rot": 27, "bit": 12, "mask": 16}, + {"i": 46, "op": "mad", "dst": 3, "src": 2, "src2": 0, "imm": "0xc89ead43", "imm2": "0x4d3108b2", "rot": 26, "bit": 17, "mask": 1}, + {"i": 47, "op": "shfl", "dst": 4, "src": 3, "src2": 0, "imm": "0xdd62be9e", "imm2": "0xf243f6f2", "rot": 8, "bit": 4, "mask": 8}, + {"i": 48, "op": "mulhi", "dst": 6, "src": 5, "src2": 0, "imm": "0xd3f7fa72", "imm2": "0x0debc83f", "rot": 25, "bit": 5, "mask": 2}, + {"i": 49, "op": "sub", "dst": 0, "src": 2, "src2": 6, "imm": "0x7afadd15", "imm2": "0xc07fc39c", "rot": 30, "bit": 29, "mask": 8}, + {"i": 50, "op": "sub", "dst": 3, "src": 5, "src2": 3, "imm": "0x179b78ec", "imm2": "0xaeccde37", "rot": 30, "bit": 17, "mask": 1}, + {"i": 51, "op": "rotr", "dst": 1, "src": 4, "src2": 1, "imm": "0xa4bfcea6", "imm2": "0xbf63bb2f", "rot": 2, "bit": 21, "mask": 2}, + {"i": 52, "op": "mad", "dst": 6, "src": 7, "src2": 7, "imm": "0xabf5ed10", "imm2": "0x8a285f51", "rot": 3, "bit": 23, "mask": 2}, + {"i": 53, "op": "xor", "dst": 5, "src": 3, "src2": 5, "imm": "0x88b416eb", "imm2": "0x36271d87", "rot": 19, "bit": 10, "mask": 2}, + {"i": 54, "op": "sub", "dst": 1, "src": 0, "src2": 1, "imm": "0xa3417dd3", "imm2": "0xcd98f620", "rot": 28, "bit": 2, "mask": 1}, + {"i": 55, "op": "sub", "dst": 5, "src": 6, "src2": 2, "imm": "0x45996c6f", "imm2": "0xe3d41087", "rot": 4, "bit": 31, "mask": 1}, + {"i": 56, "op": "add", "dst": 3, "src": 2, "src2": 0, "imm": "0x3dfad1b6", "imm2": "0xd4758987", "rot": 27, "bit": 10, "mask": 2}, + {"i": 57, "op": "add", "dst": 4, "src": 1, "src2": 3, "imm": "0xfca75bc2", "imm2": "0x0602d6be", "rot": 19, "bit": 0, "mask": 16}, + {"i": 58, "op": "mulhi", "dst": 5, "src": 6, "src2": 5, "imm": "0x83250a7b", "imm2": "0x2f93d53b", "rot": 25, "bit": 7, "mask": 2}, + {"i": 59, "op": "shfl", "dst": 2, "src": 1, "src2": 0, "imm": "0x13f4a089", "imm2": "0x145ea125", "rot": 12, "bit": 3, "mask": 2}, + {"i": 60, "op": "rotl", "dst": 2, "src": 5, "src2": 6, "imm": "0xad3170e3", "imm2": "0x15db04d1", "rot": 9, "bit": 13, "mask": 2}, + {"i": 61, "op": "or", "dst": 4, "src": 6, "src2": 2, "imm": "0x4b6305b2", "imm2": "0x6e7b2e9c", "rot": 27, "bit": 16, "mask": 4}, + {"i": 62, "op": "rotr", "dst": 6, "src": 4, "src2": 6, "imm": "0xfcd4b1c9", "imm2": "0xaf5c733b", "rot": 6, "bit": 21, "mask": 16}, + {"i": 63, "op": "mul", "dst": 2, "src": 4, "src2": 6, "imm": "0x95cebb3e", "imm2": "0xbba9cdfc", "rot": 19, "bit": 23, "mask": 1}, + {"i": 64, "op": "xor", "dst": 0, "src": 5, "src2": 7, "imm": "0x5f7579ff", "imm2": "0xb104e01a", "rot": 25, "bit": 12, "mask": 8}, + {"i": 65, "op": "xor", "dst": 2, "src": 7, "src2": 3, "imm": "0x749c7611", "imm2": "0xf17df3bb", "rot": 27, "bit": 26, "mask": 2}, + {"i": 66, "op": "add", "dst": 2, "src": 1, "src2": 6, "imm": "0xd71c02ff", "imm2": "0x8596687a", "rot": 4, "bit": 6, "mask": 2}, + {"i": 67, "op": "rotl", "dst": 1, "src": 3, "src2": 2, "imm": "0xd2864071", "imm2": "0xaa644ef3", "rot": 21, "bit": 5, "mask": 1}, + {"i": 68, "op": "mul", "dst": 3, "src": 2, "src2": 1, "imm": "0xd0689a5f", "imm2": "0xa3a1f063", "rot": 13, "bit": 28, "mask": 2}, + {"i": 69, "op": "shfl", "dst": 7, "src": 5, "src2": 6, "imm": "0xd01476eb", "imm2": "0x76abb5c2", "rot": 7, "bit": 30, "mask": 2}, + {"i": 70, "op": "mul", "dst": 3, "src": 2, "src2": 5, "imm": "0x59a75c10", "imm2": "0x1e1fbb72", "rot": 20, "bit": 16, "mask": 1}, + {"i": 71, "op": "mad", "dst": 0, "src": 2, "src2": 5, "imm": "0x39cca1df", "imm2": "0x22c057ac", "rot": 5, "bit": 23, "mask": 16}, + {"i": 72, "op": "add", "dst": 6, "src": 7, "src2": 3, "imm": "0x3c6fe15d", "imm2": "0x08ac5733", "rot": 14, "bit": 0, "mask": 4}, + {"i": 73, "op": "shfl", "dst": 3, "src": 2, "src2": 6, "imm": "0x2098627d", "imm2": "0xf4fecc81", "rot": 20, "bit": 30, "mask": 8}, + {"i": 74, "op": "mul", "dst": 3, "src": 6, "src2": 5, "imm": "0xf82e9e23", "imm2": "0x3ad62132", "rot": 10, "bit": 14, "mask": 16}, + {"i": 75, "op": "xor", "dst": 6, "src": 7, "src2": 4, "imm": "0x70548a91", "imm2": "0xa9715d2e", "rot": 6, "bit": 24, "mask": 1}, + {"i": 76, "op": "or", "dst": 3, "src": 0, "src2": 7, "imm": "0xa164325f", "imm2": "0xf300838b", "rot": 23, "bit": 23, "mask": 16}, + {"i": 77, "op": "add", "dst": 2, "src": 4, "src2": 6, "imm": "0x295d5fae", "imm2": "0xc100b495", "rot": 7, "bit": 1, "mask": 2}, + {"i": 78, "op": "mulhi", "dst": 3, "src": 7, "src2": 4, "imm": "0xb62cca87", "imm2": "0x2ebde415", "rot": 14, "bit": 7, "mask": 2}, + {"i": 79, "op": "or", "dst": 4, "src": 1, "src2": 7, "imm": "0xfcbc482d", "imm2": "0x8876e6cd", "rot": 29, "bit": 5, "mask": 2}, + {"i": 80, "op": "rotr", "dst": 4, "src": 3, "src2": 0, "imm": "0x6d64013b", "imm2": "0x675f4a8d", "rot": 26, "bit": 18, "mask": 8}, + {"i": 81, "op": "add", "dst": 4, "src": 3, "src2": 3, "imm": "0x274a9221", "imm2": "0x5cc59530", "rot": 15, "bit": 15, "mask": 2}, + {"i": 82, "op": "add", "dst": 7, "src": 3, "src2": 0, "imm": "0xc8651f8e", "imm2": "0x141479ec", "rot": 18, "bit": 5, "mask": 1}, + {"i": 83, "op": "rotr", "dst": 3, "src": 6, "src2": 0, "imm": "0xcc8a7766", "imm2": "0xc2eb5161", "rot": 4, "bit": 29, "mask": 2}, + {"i": 84, "op": "mad", "dst": 2, "src": 4, "src2": 7, "imm": "0xbc507d51", "imm2": "0x0b1196fd", "rot": 9, "bit": 7, "mask": 8}, + {"i": 85, "op": "shfl", "dst": 2, "src": 5, "src2": 5, "imm": "0x5a156c90", "imm2": "0xa6b3fbfa", "rot": 11, "bit": 2, "mask": 16}, + {"i": 86, "op": "xor", "dst": 3, "src": 2, "src2": 1, "imm": "0x8b042658", "imm2": "0xacf37a8f", "rot": 12, "bit": 23, "mask": 16}, + {"i": 87, "op": "shfl", "dst": 5, "src": 7, "src2": 2, "imm": "0x1a214238", "imm2": "0x017fdf5d", "rot": 29, "bit": 14, "mask": 2}, + {"i": 88, "op": "xor", "dst": 0, "src": 4, "src2": 2, "imm": "0xd523e612", "imm2": "0x2158c2ed", "rot": 30, "bit": 14, "mask": 4}, + {"i": 89, "op": "add", "dst": 3, "src": 2, "src2": 7, "imm": "0x53f915c2", "imm2": "0x883c0c92", "rot": 9, "bit": 18, "mask": 8}, + {"i": 90, "op": "rotr", "dst": 7, "src": 5, "src2": 5, "imm": "0xbd633b21", "imm2": "0xcf8c356c", "rot": 25, "bit": 31, "mask": 4}, + {"i": 91, "op": "add", "dst": 3, "src": 1, "src2": 1, "imm": "0xe2be00a5", "imm2": "0x3cc5bd20", "rot": 10, "bit": 31, "mask": 1}, + {"i": 92, "op": "shfl", "dst": 7, "src": 2, "src2": 4, "imm": "0x3d3da600", "imm2": "0x1f22df89", "rot": 4, "bit": 24, "mask": 1}, + {"i": 93, "op": "rotr", "dst": 6, "src": 2, "src2": 7, "imm": "0xb0f57471", "imm2": "0x8f2a7eca", "rot": 16, "bit": 25, "mask": 1}, + {"i": 94, "op": "rotl", "dst": 7, "src": 0, "src2": 4, "imm": "0x00a21815", "imm2": "0xeb4d7218", "rot": 14, "bit": 18, "mask": 16}, + {"i": 95, "op": "mad", "dst": 4, "src": 5, "src2": 5, "imm": "0xc4c3828e", "imm2": "0xfb7bba17", "rot": 16, "bit": 10, "mask": 16}, + {"i": 96, "op": "mad", "dst": 2, "src": 4, "src2": 5, "imm": "0xfc5bbc75", "imm2": "0xfc43468f", "rot": 31, "bit": 20, "mask": 16}, + {"i": 97, "op": "xor", "dst": 1, "src": 0, "src2": 2, "imm": "0x1fe9c249", "imm2": "0x164bb16b", "rot": 15, "bit": 9, "mask": 4}, + {"i": 98, "op": "mul", "dst": 5, "src": 4, "src2": 1, "imm": "0xeda725fa", "imm2": "0x66f7e9a2", "rot": 21, "bit": 6, "mask": 2}, + {"i": 99, "op": "sub", "dst": 2, "src": 0, "src2": 7, "imm": "0x8fb29f7d", "imm2": "0xf530eda1", "rot": 27, "bit": 30, "mask": 4}, + {"i": 100, "op": "rotl", "dst": 7, "src": 2, "src2": 0, "imm": "0x9f4de742", "imm2": "0x9b5ff871", "rot": 30, "bit": 21, "mask": 16}, + {"i": 101, "op": "add", "dst": 5, "src": 6, "src2": 7, "imm": "0x423fd9c9", "imm2": "0xbfd646cb", "rot": 17, "bit": 17, "mask": 2}, + {"i": 102, "op": "add", "dst": 7, "src": 6, "src2": 3, "imm": "0x8d3c011d", "imm2": "0x19b74a43", "rot": 12, "bit": 11, "mask": 4}, + {"i": 103, "op": "rotl", "dst": 5, "src": 6, "src2": 0, "imm": "0xcfc70303", "imm2": "0xf2b3e8ef", "rot": 6, "bit": 24, "mask": 1}, + {"i": 104, "op": "mul", "dst": 0, "src": 4, "src2": 5, "imm": "0x650475eb", "imm2": "0x11dcbd94", "rot": 15, "bit": 10, "mask": 1}, + {"i": 105, "op": "or", "dst": 0, "src": 5, "src2": 3, "imm": "0xaacaa145", "imm2": "0x9139d3fe", "rot": 4, "bit": 18, "mask": 2}, + {"i": 106, "op": "add", "dst": 0, "src": 1, "src2": 7, "imm": "0x8ce14721", "imm2": "0x7dcb7e18", "rot": 24, "bit": 15, "mask": 8}, + {"i": 107, "op": "rotl", "dst": 0, "src": 3, "src2": 3, "imm": "0xb36d6d98", "imm2": "0x2c3390c8", "rot": 15, "bit": 10, "mask": 16}, + {"i": 108, "op": "sub", "dst": 4, "src": 2, "src2": 5, "imm": "0xf6bbdaef", "imm2": "0x9db6f65e", "rot": 25, "bit": 10, "mask": 1}, + {"i": 109, "op": "mulhi", "dst": 2, "src": 0, "src2": 0, "imm": "0xb1721fd6", "imm2": "0xd96d52c9", "rot": 1, "bit": 27, "mask": 8}, + {"i": 110, "op": "mulhi", "dst": 1, "src": 0, "src2": 5, "imm": "0xfb4ca37f", "imm2": "0xb6ec7dbe", "rot": 27, "bit": 12, "mask": 8}, + {"i": 111, "op": "add", "dst": 0, "src": 2, "src2": 0, "imm": "0x2d9fc6b9", "imm2": "0x3c179ad8", "rot": 9, "bit": 28, "mask": 16}, + {"i": 112, "op": "mulhi", "dst": 2, "src": 0, "src2": 6, "imm": "0x71a9f6bd", "imm2": "0xd3417bf5", "rot": 2, "bit": 14, "mask": 8}, + {"i": 113, "op": "sub", "dst": 6, "src": 3, "src2": 5, "imm": "0xa3d19400", "imm2": "0x15df7330", "rot": 5, "bit": 2, "mask": 8}, + {"i": 114, "op": "mad", "dst": 7, "src": 6, "src2": 3, "imm": "0x1400d92e", "imm2": "0xfa4a158e", "rot": 16, "bit": 9, "mask": 1}, + {"i": 115, "op": "rotr", "dst": 5, "src": 1, "src2": 3, "imm": "0xd01684c3", "imm2": "0x6367febb", "rot": 23, "bit": 19, "mask": 2}, + {"i": 116, "op": "rotr", "dst": 6, "src": 4, "src2": 2, "imm": "0x8cd9eb96", "imm2": "0x98f33b24", "rot": 25, "bit": 1, "mask": 2}, + {"i": 117, "op": "add", "dst": 2, "src": 1, "src2": 7, "imm": "0x502138e2", "imm2": "0x47359729", "rot": 5, "bit": 22, "mask": 4}, + {"i": 118, "op": "mad", "dst": 3, "src": 2, "src2": 0, "imm": "0xd94a35c7", "imm2": "0xb83416c3", "rot": 11, "bit": 3, "mask": 4}, + {"i": 119, "op": "mul", "dst": 1, "src": 3, "src2": 6, "imm": "0x09b30cf7", "imm2": "0xef3b98e7", "rot": 17, "bit": 23, "mask": 8}, + {"i": 120, "op": "mad", "dst": 2, "src": 0, "src2": 4, "imm": "0x56416fe0", "imm2": "0x5e1dc8f3", "rot": 17, "bit": 14, "mask": 2}, + {"i": 121, "op": "mul", "dst": 0, "src": 3, "src2": 2, "imm": "0x2892697c", "imm2": "0x9cb3b14e", "rot": 29, "bit": 25, "mask": 2}, + {"i": 122, "op": "mulhi", "dst": 2, "src": 0, "src2": 3, "imm": "0xc33089a1", "imm2": "0xd6c5b530", "rot": 27, "bit": 13, "mask": 8}, + {"i": 123, "op": "mul", "dst": 5, "src": 6, "src2": 4, "imm": "0xdfe04e4a", "imm2": "0x3cc40160", "rot": 3, "bit": 14, "mask": 2}, + {"i": 124, "op": "mad", "dst": 4, "src": 2, "src2": 4, "imm": "0xb33dc1b7", "imm2": "0xab97743a", "rot": 7, "bit": 21, "mask": 4}, + {"i": 125, "op": "shfl", "dst": 4, "src": 2, "src2": 0, "imm": "0xfd469909", "imm2": "0xfc85dc55", "rot": 28, "bit": 24, "mask": 2}, + {"i": 126, "op": "xor", "dst": 2, "src": 0, "src2": 5, "imm": "0xa0094578", "imm2": "0xf1bee474", "rot": 31, "bit": 7, "mask": 2}, + {"i": 127, "op": "rotl", "dst": 1, "src": 7, "src2": 2, "imm": "0xb7ae00a0", "imm2": "0x86cce297", "rot": 7, "bit": 31, "mask": 8}, + {"i": 128, "op": "shfl", "dst": 7, "src": 2, "src2": 7, "imm": "0x019d1940", "imm2": "0x3fe9e7dd", "rot": 14, "bit": 4, "mask": 4}, + {"i": 129, "op": "rotl", "dst": 6, "src": 7, "src2": 7, "imm": "0x40a74cc4", "imm2": "0x09eb4adf", "rot": 17, "bit": 30, "mask": 1}, + {"i": 130, "op": "add", "dst": 2, "src": 5, "src2": 5, "imm": "0x33dff776", "imm2": "0x6c57e4e7", "rot": 27, "bit": 15, "mask": 4}, + {"i": 131, "op": "or", "dst": 0, "src": 3, "src2": 1, "imm": "0xe0c53bb9", "imm2": "0x124404f6", "rot": 4, "bit": 21, "mask": 16}, + {"i": 132, "op": "rotr", "dst": 5, "src": 0, "src2": 1, "imm": "0xe4353fce", "imm2": "0x559d0118", "rot": 2, "bit": 29, "mask": 4}, + {"i": 133, "op": "add", "dst": 2, "src": 3, "src2": 6, "imm": "0x5db25b34", "imm2": "0xe8212c0c", "rot": 21, "bit": 30, "mask": 1}, + {"i": 134, "op": "xor", "dst": 4, "src": 3, "src2": 6, "imm": "0x7366e50e", "imm2": "0x7cc1ffbd", "rot": 19, "bit": 18, "mask": 16}, + {"i": 135, "op": "xor", "dst": 6, "src": 1, "src2": 2, "imm": "0xa36decb7", "imm2": "0x79291734", "rot": 26, "bit": 0, "mask": 8}, + {"i": 136, "op": "sub", "dst": 1, "src": 7, "src2": 0, "imm": "0x225b03e4", "imm2": "0x7183e193", "rot": 16, "bit": 6, "mask": 2}, + {"i": 137, "op": "mad", "dst": 2, "src": 6, "src2": 2, "imm": "0x6f620d51", "imm2": "0x4e814e19", "rot": 6, "bit": 6, "mask": 2}, + {"i": 138, "op": "mulhi", "dst": 0, "src": 5, "src2": 6, "imm": "0x919d6bf3", "imm2": "0xc6240638", "rot": 17, "bit": 11, "mask": 16}, + {"i": 139, "op": "add", "dst": 2, "src": 7, "src2": 7, "imm": "0x218d4090", "imm2": "0xd44ff710", "rot": 1, "bit": 10, "mask": 16}, + {"i": 140, "op": "rotr", "dst": 1, "src": 4, "src2": 4, "imm": "0x4cbfa722", "imm2": "0x114e9564", "rot": 28, "bit": 9, "mask": 16}, + {"i": 141, "op": "shfl", "dst": 3, "src": 6, "src2": 2, "imm": "0xf702c6a1", "imm2": "0xf8f3c5d9", "rot": 7, "bit": 24, "mask": 1}, + {"i": 142, "op": "mad", "dst": 7, "src": 6, "src2": 2, "imm": "0xa2d285be", "imm2": "0x9cc94532", "rot": 15, "bit": 20, "mask": 8}, + {"i": 143, "op": "mul", "dst": 2, "src": 3, "src2": 7, "imm": "0x08b7ed80", "imm2": "0xa8abced4", "rot": 18, "bit": 10, "mask": 4}, + {"i": 144, "op": "add", "dst": 7, "src": 4, "src2": 2, "imm": "0xf4b1a8de", "imm2": "0xb98942fa", "rot": 18, "bit": 29, "mask": 8}, + {"i": 145, "op": "rotl", "dst": 7, "src": 6, "src2": 1, "imm": "0x64b6ba2d", "imm2": "0xf9e86793", "rot": 15, "bit": 24, "mask": 8}, + {"i": 146, "op": "xor", "dst": 7, "src": 5, "src2": 3, "imm": "0x41c42b5f", "imm2": "0x7c7e0e39", "rot": 8, "bit": 23, "mask": 2}, + {"i": 147, "op": "mad", "dst": 4, "src": 7, "src2": 4, "imm": "0x3caa807a", "imm2": "0x553a0cec", "rot": 11, "bit": 22, "mask": 8}, + {"i": 148, "op": "rotr", "dst": 6, "src": 5, "src2": 3, "imm": "0x3cb1289a", "imm2": "0x6b36f78a", "rot": 1, "bit": 9, "mask": 16}, + {"i": 149, "op": "mad", "dst": 1, "src": 2, "src2": 4, "imm": "0x95310ea8", "imm2": "0xc533aa6a", "rot": 16, "bit": 17, "mask": 1}, + {"i": 150, "op": "add", "dst": 1, "src": 7, "src2": 7, "imm": "0x2bef10f2", "imm2": "0x0d48ba42", "rot": 8, "bit": 17, "mask": 4}, + {"i": 151, "op": "xor", "dst": 5, "src": 4, "src2": 7, "imm": "0xda997ab2", "imm2": "0xae31d69e", "rot": 11, "bit": 31, "mask": 2}, + {"i": 152, "op": "add", "dst": 7, "src": 0, "src2": 6, "imm": "0xdc5cc080", "imm2": "0xc98dea9c", "rot": 16, "bit": 30, "mask": 2}, + {"i": 153, "op": "mul", "dst": 4, "src": 6, "src2": 7, "imm": "0xbfbf5f6c", "imm2": "0x61f611bb", "rot": 14, "bit": 22, "mask": 2}, + {"i": 154, "op": "mul", "dst": 0, "src": 2, "src2": 3, "imm": "0xa78008c3", "imm2": "0xbad5eeb1", "rot": 10, "bit": 28, "mask": 8}, + {"i": 155, "op": "xor", "dst": 6, "src": 5, "src2": 4, "imm": "0x1a73b866", "imm2": "0x1f5a62c9", "rot": 9, "bit": 27, "mask": 8}, + {"i": 156, "op": "rotr", "dst": 4, "src": 2, "src2": 0, "imm": "0x9c88500c", "imm2": "0xe25dccf9", "rot": 11, "bit": 2, "mask": 16}, + {"i": 157, "op": "rotl", "dst": 1, "src": 4, "src2": 4, "imm": "0xb05e7669", "imm2": "0x9db704b1", "rot": 11, "bit": 28, "mask": 4}, + {"i": 158, "op": "add", "dst": 5, "src": 0, "src2": 6, "imm": "0x18197438", "imm2": "0x6c752dcb", "rot": 11, "bit": 11, "mask": 2}, + {"i": 159, "op": "mad", "dst": 4, "src": 1, "src2": 5, "imm": "0x4796a65e", "imm2": "0x00e08c7a", "rot": 8, "bit": 19, "mask": 4}, + {"i": 160, "op": "rotl", "dst": 4, "src": 7, "src2": 5, "imm": "0x08a03052", "imm2": "0x0204f0ba", "rot": 26, "bit": 5, "mask": 2}, + {"i": 161, "op": "mad", "dst": 3, "src": 0, "src2": 7, "imm": "0xa0603b0e", "imm2": "0x7eee83d5", "rot": 28, "bit": 22, "mask": 16}, + {"i": 162, "op": "rotr", "dst": 3, "src": 1, "src2": 6, "imm": "0x78a3c69d", "imm2": "0x684693a0", "rot": 21, "bit": 23, "mask": 4}, + {"i": 163, "op": "add", "dst": 4, "src": 0, "src2": 7, "imm": "0xf1c46574", "imm2": "0x8e481727", "rot": 9, "bit": 3, "mask": 4}, + {"i": 164, "op": "mulhi", "dst": 0, "src": 4, "src2": 3, "imm": "0x04644afa", "imm2": "0x64bda2b5", "rot": 26, "bit": 16, "mask": 16}, + {"i": 165, "op": "add", "dst": 2, "src": 6, "src2": 2, "imm": "0xac578137", "imm2": "0x550ab406", "rot": 13, "bit": 20, "mask": 16}, + {"i": 166, "op": "rotl", "dst": 0, "src": 4, "src2": 5, "imm": "0x7f564760", "imm2": "0xb9a8b4f8", "rot": 13, "bit": 29, "mask": 1}, + {"i": 167, "op": "add", "dst": 3, "src": 1, "src2": 0, "imm": "0xa33e6706", "imm2": "0xaebb5966", "rot": 12, "bit": 14, "mask": 16}, + {"i": 168, "op": "or", "dst": 3, "src": 5, "src2": 3, "imm": "0x65b2f3eb", "imm2": "0xb1d00d20", "rot": 12, "bit": 2, "mask": 8}, + {"i": 169, "op": "rotr", "dst": 6, "src": 2, "src2": 3, "imm": "0x7f21faf5", "imm2": "0xbbf0d3f9", "rot": 17, "bit": 13, "mask": 8}, + {"i": 170, "op": "xor", "dst": 4, "src": 6, "src2": 2, "imm": "0x162c7140", "imm2": "0x90d404ad", "rot": 26, "bit": 1, "mask": 4}, + {"i": 171, "op": "sub", "dst": 6, "src": 1, "src2": 7, "imm": "0x6ef9c76e", "imm2": "0xfb7ba272", "rot": 31, "bit": 25, "mask": 1}, + {"i": 172, "op": "rotl", "dst": 7, "src": 5, "src2": 4, "imm": "0xde04eb3b", "imm2": "0xd56caa00", "rot": 22, "bit": 21, "mask": 4}, + {"i": 173, "op": "rotl", "dst": 5, "src": 3, "src2": 5, "imm": "0xa9eac934", "imm2": "0x2c338e51", "rot": 15, "bit": 22, "mask": 2}, + {"i": 174, "op": "shfl", "dst": 7, "src": 0, "src2": 3, "imm": "0x700be4e3", "imm2": "0x4bcfc732", "rot": 19, "bit": 6, "mask": 8}, + {"i": 175, "op": "xor", "dst": 0, "src": 5, "src2": 1, "imm": "0x02ccdba9", "imm2": "0xd0915be0", "rot": 15, "bit": 2, "mask": 16}, + {"i": 176, "op": "rotl", "dst": 7, "src": 4, "src2": 1, "imm": "0x489c8165", "imm2": "0xf24b5a4f", "rot": 6, "bit": 22, "mask": 1}, + {"i": 177, "op": "sub", "dst": 7, "src": 0, "src2": 6, "imm": "0x23ad9693", "imm2": "0x9a8c2f7b", "rot": 24, "bit": 2, "mask": 2}, + {"i": 178, "op": "rotl", "dst": 3, "src": 0, "src2": 6, "imm": "0xafa72a42", "imm2": "0x371d74ee", "rot": 30, "bit": 16, "mask": 1}, + {"i": 179, "op": "mad", "dst": 7, "src": 6, "src2": 1, "imm": "0x18a2a3f3", "imm2": "0xb811b951", "rot": 2, "bit": 9, "mask": 2}, + {"i": 180, "op": "rotl", "dst": 6, "src": 4, "src2": 1, "imm": "0xe6c69c0e", "imm2": "0xfc46a951", "rot": 9, "bit": 31, "mask": 4}, + {"i": 181, "op": "xor", "dst": 2, "src": 4, "src2": 7, "imm": "0xbd1b89e4", "imm2": "0xdf4bce5c", "rot": 15, "bit": 19, "mask": 4}, + {"i": 182, "op": "xor", "dst": 2, "src": 7, "src2": 5, "imm": "0x3dd12aed", "imm2": "0xd0756a69", "rot": 13, "bit": 16, "mask": 4}, + {"i": 183, "op": "xor", "dst": 7, "src": 2, "src2": 3, "imm": "0x77ce69d6", "imm2": "0x2b39bdf2", "rot": 8, "bit": 22, "mask": 16}, + {"i": 184, "op": "add", "dst": 1, "src": 2, "src2": 4, "imm": "0xd94d55ac", "imm2": "0x5bb7550f", "rot": 31, "bit": 21, "mask": 1}, + {"i": 185, "op": "or", "dst": 3, "src": 5, "src2": 6, "imm": "0x7b1ce846", "imm2": "0xcc3b8509", "rot": 28, "bit": 9, "mask": 4}, + {"i": 186, "op": "mulhi", "dst": 6, "src": 3, "src2": 0, "imm": "0xa5e24690", "imm2": "0x2200ba81", "rot": 26, "bit": 10, "mask": 16}, + {"i": 187, "op": "or", "dst": 4, "src": 0, "src2": 3, "imm": "0xf6efe759", "imm2": "0xae1f7118", "rot": 19, "bit": 20, "mask": 4}, + {"i": 188, "op": "shfl", "dst": 7, "src": 1, "src2": 5, "imm": "0xdb318b45", "imm2": "0xcec459c9", "rot": 20, "bit": 11, "mask": 2}, + {"i": 189, "op": "add", "dst": 6, "src": 5, "src2": 1, "imm": "0x89e747fe", "imm2": "0x2a354e2d", "rot": 22, "bit": 6, "mask": 1}, + {"i": 190, "op": "xor", "dst": 1, "src": 4, "src2": 2, "imm": "0xc379e617", "imm2": "0x75e9d63b", "rot": 23, "bit": 3, "mask": 2}, + {"i": 191, "op": "mulhi", "dst": 7, "src": 4, "src2": 3, "imm": "0x5a710287", "imm2": "0x7fe4ead6", "rot": 10, "bit": 25, "mask": 4}, + {"i": 192, "op": "rotl", "dst": 2, "src": 1, "src2": 2, "imm": "0x4d5e59a3", "imm2": "0x1e4fef28", "rot": 26, "bit": 0, "mask": 1}, + {"i": 193, "op": "rotl", "dst": 5, "src": 3, "src2": 7, "imm": "0x7444c47d", "imm2": "0xdad5f8be", "rot": 8, "bit": 30, "mask": 2}, + {"i": 194, "op": "shfl", "dst": 4, "src": 5, "src2": 7, "imm": "0x6a225bbb", "imm2": "0xd6532cd7", "rot": 13, "bit": 17, "mask": 16}, + {"i": 195, "op": "xor", "dst": 4, "src": 5, "src2": 3, "imm": "0x68344b9a", "imm2": "0xcb46a38b", "rot": 1, "bit": 27, "mask": 16}, + {"i": 196, "op": "mul", "dst": 1, "src": 3, "src2": 4, "imm": "0xbebf7359", "imm2": "0x3f0890ba", "rot": 18, "bit": 12, "mask": 4}, + {"i": 197, "op": "add", "dst": 5, "src": 2, "src2": 3, "imm": "0xea03e8e7", "imm2": "0x10cfdc71", "rot": 31, "bit": 7, "mask": 8}, + {"i": 198, "op": "add", "dst": 7, "src": 5, "src2": 1, "imm": "0xa7ee0102", "imm2": "0x66e148d3", "rot": 12, "bit": 15, "mask": 1}, + {"i": 199, "op": "sub", "dst": 5, "src": 2, "src2": 4, "imm": "0xc215584e", "imm2": "0x55fce30f", "rot": 30, "bit": 9, "mask": 2}, + {"i": 200, "op": "shfl", "dst": 5, "src": 1, "src2": 1, "imm": "0x308f8358", "imm2": "0x489f1f93", "rot": 13, "bit": 13, "mask": 2}, + {"i": 201, "op": "shfl", "dst": 7, "src": 1, "src2": 5, "imm": "0x713f1957", "imm2": "0x2239f757", "rot": 15, "bit": 7, "mask": 8}, + {"i": 202, "op": "rotr", "dst": 4, "src": 5, "src2": 1, "imm": "0xb037b6e7", "imm2": "0x49a8b528", "rot": 27, "bit": 13, "mask": 16}, + {"i": 203, "op": "xor", "dst": 7, "src": 5, "src2": 1, "imm": "0x56110241", "imm2": "0xefc8386d", "rot": 22, "bit": 20, "mask": 1}, + {"i": 204, "op": "xor", "dst": 7, "src": 0, "src2": 0, "imm": "0x0827fcc7", "imm2": "0xf4f5dd07", "rot": 13, "bit": 7, "mask": 2}, + {"i": 205, "op": "add", "dst": 6, "src": 2, "src2": 0, "imm": "0x8379a4de", "imm2": "0x8558b619", "rot": 26, "bit": 10, "mask": 1}, + {"i": 206, "op": "rotl", "dst": 4, "src": 3, "src2": 3, "imm": "0x091ceef0", "imm2": "0x69b0f72f", "rot": 13, "bit": 7, "mask": 1}, + {"i": 207, "op": "mulhi", "dst": 1, "src": 3, "src2": 4, "imm": "0x758edac1", "imm2": "0x98dd2f21", "rot": 15, "bit": 9, "mask": 1}, + {"i": 208, "op": "mad", "dst": 1, "src": 4, "src2": 4, "imm": "0x78871a1a", "imm2": "0x5e14e1c8", "rot": 19, "bit": 6, "mask": 2}, + {"i": 209, "op": "shfl", "dst": 2, "src": 0, "src2": 2, "imm": "0xf7e0b9aa", "imm2": "0xaecfd347", "rot": 21, "bit": 9, "mask": 4}, + {"i": 210, "op": "add", "dst": 7, "src": 0, "src2": 7, "imm": "0xaa8cb14e", "imm2": "0xf4049c4c", "rot": 24, "bit": 11, "mask": 8}, + {"i": 211, "op": "shfl", "dst": 7, "src": 1, "src2": 6, "imm": "0xc230d919", "imm2": "0xf76d08fb", "rot": 21, "bit": 13, "mask": 16}, + {"i": 212, "op": "xor", "dst": 1, "src": 0, "src2": 2, "imm": "0x31a5af90", "imm2": "0x7eef58ee", "rot": 9, "bit": 12, "mask": 4}, + {"i": 213, "op": "rotl", "dst": 7, "src": 1, "src2": 6, "imm": "0x0db26138", "imm2": "0x8e3c31f9", "rot": 3, "bit": 26, "mask": 2}, + {"i": 214, "op": "rotr", "dst": 4, "src": 7, "src2": 3, "imm": "0x29558100", "imm2": "0xe4b13ad6", "rot": 29, "bit": 24, "mask": 8}, + {"i": 215, "op": "shfl", "dst": 3, "src": 2, "src2": 6, "imm": "0x1b48c3d0", "imm2": "0x5c674ff6", "rot": 5, "bit": 9, "mask": 16}, + {"i": 216, "op": "or", "dst": 5, "src": 1, "src2": 0, "imm": "0xef768632", "imm2": "0x6de9d10d", "rot": 10, "bit": 4, "mask": 4}, + {"i": 217, "op": "sub", "dst": 1, "src": 2, "src2": 5, "imm": "0x88ca7f5a", "imm2": "0x24718a36", "rot": 18, "bit": 31, "mask": 1}, + {"i": 218, "op": "sub", "dst": 6, "src": 5, "src2": 0, "imm": "0xc4a06728", "imm2": "0xdc2a4fd8", "rot": 9, "bit": 9, "mask": 2}, + {"i": 219, "op": "rotl", "dst": 6, "src": 5, "src2": 7, "imm": "0xb7489e47", "imm2": "0xf13795c5", "rot": 4, "bit": 3, "mask": 8}, + {"i": 220, "op": "mulhi", "dst": 2, "src": 0, "src2": 2, "imm": "0x873cd31b", "imm2": "0x3dfbc55d", "rot": 12, "bit": 23, "mask": 8}, + {"i": 221, "op": "or", "dst": 2, "src": 0, "src2": 3, "imm": "0xdc21f099", "imm2": "0xee06f01e", "rot": 2, "bit": 17, "mask": 8}, + {"i": 222, "op": "shfl", "dst": 5, "src": 2, "src2": 6, "imm": "0x36def499", "imm2": "0xa2849d59", "rot": 23, "bit": 4, "mask": 8}, + {"i": 223, "op": "mulhi", "dst": 5, "src": 6, "src2": 7, "imm": "0xfb95fbca", "imm2": "0xc1aac427", "rot": 14, "bit": 11, "mask": 2}, + {"i": 224, "op": "sub", "dst": 0, "src": 6, "src2": 7, "imm": "0x3d9d29c4", "imm2": "0x34d0dcc0", "rot": 17, "bit": 6, "mask": 4}, + {"i": 225, "op": "rotl", "dst": 7, "src": 0, "src2": 5, "imm": "0x93b01b8e", "imm2": "0xfe1d75ac", "rot": 23, "bit": 15, "mask": 1}, + {"i": 226, "op": "or", "dst": 4, "src": 2, "src2": 4, "imm": "0xfed76e8e", "imm2": "0x1c24ecd8", "rot": 2, "bit": 6, "mask": 16}, + {"i": 227, "op": "mul", "dst": 2, "src": 4, "src2": 1, "imm": "0x5795f5b0", "imm2": "0x0566ea2a", "rot": 6, "bit": 28, "mask": 4}, + {"i": 228, "op": "rotl", "dst": 3, "src": 0, "src2": 2, "imm": "0x8c8486de", "imm2": "0xd066aa8f", "rot": 12, "bit": 20, "mask": 1}, + {"i": 229, "op": "rotr", "dst": 0, "src": 4, "src2": 0, "imm": "0x23a3e882", "imm2": "0xaca23902", "rot": 5, "bit": 22, "mask": 16}, + {"i": 230, "op": "add", "dst": 0, "src": 6, "src2": 4, "imm": "0x1d176220", "imm2": "0x2a7fecb2", "rot": 20, "bit": 16, "mask": 2}, + {"i": 231, "op": "shfl", "dst": 1, "src": 2, "src2": 0, "imm": "0x91172787", "imm2": "0xc5d7af28", "rot": 3, "bit": 24, "mask": 4}, + {"i": 232, "op": "mul", "dst": 2, "src": 1, "src2": 2, "imm": "0x0be68835", "imm2": "0xde692bdb", "rot": 30, "bit": 17, "mask": 1}, + {"i": 233, "op": "mad", "dst": 7, "src": 0, "src2": 1, "imm": "0xf90d2db5", "imm2": "0x96c4c175", "rot": 28, "bit": 7, "mask": 4}, + {"i": 234, "op": "rotl", "dst": 5, "src": 2, "src2": 1, "imm": "0x16379736", "imm2": "0x6973b905", "rot": 22, "bit": 17, "mask": 4}, + {"i": 235, "op": "rotr", "dst": 4, "src": 6, "src2": 2, "imm": "0x84292a13", "imm2": "0x0f897740", "rot": 12, "bit": 6, "mask": 8}, + {"i": 236, "op": "mad", "dst": 0, "src": 5, "src2": 1, "imm": "0xeb7de837", "imm2": "0x64f0c302", "rot": 4, "bit": 19, "mask": 1}, + {"i": 237, "op": "xor", "dst": 6, "src": 4, "src2": 4, "imm": "0x6ab4b683", "imm2": "0x20f17adb", "rot": 1, "bit": 0, "mask": 16}, + {"i": 238, "op": "xor", "dst": 4, "src": 6, "src2": 1, "imm": "0x5836b35c", "imm2": "0x3293cc4a", "rot": 16, "bit": 22, "mask": 16}, + {"i": 239, "op": "rotl", "dst": 6, "src": 1, "src2": 6, "imm": "0x769d8bc0", "imm2": "0xdc86c9cc", "rot": 18, "bit": 27, "mask": 16}, + {"i": 240, "op": "add", "dst": 4, "src": 7, "src2": 1, "imm": "0x17dafb4d", "imm2": "0xadce39f3", "rot": 12, "bit": 25, "mask": 8}, + {"i": 241, "op": "sub", "dst": 0, "src": 7, "src2": 4, "imm": "0xd4690bda", "imm2": "0xdab9b27b", "rot": 30, "bit": 21, "mask": 1}, + {"i": 242, "op": "rotr", "dst": 1, "src": 6, "src2": 2, "imm": "0x670a2d0a", "imm2": "0x0612e33c", "rot": 31, "bit": 25, "mask": 2}, + {"i": 243, "op": "add", "dst": 3, "src": 0, "src2": 2, "imm": "0xf2f77d26", "imm2": "0x0e7033b6", "rot": 27, "bit": 29, "mask": 1}, + {"i": 244, "op": "mad", "dst": 2, "src": 7, "src2": 4, "imm": "0xa9eefc9d", "imm2": "0x16166c85", "rot": 18, "bit": 23, "mask": 16}, + {"i": 245, "op": "mad", "dst": 4, "src": 0, "src2": 6, "imm": "0xb26f6c0f", "imm2": "0x0630e821", "rot": 23, "bit": 30, "mask": 4}, + {"i": 246, "op": "mul", "dst": 5, "src": 7, "src2": 2, "imm": "0x269ce4bf", "imm2": "0x1ce28d32", "rot": 30, "bit": 15, "mask": 16}, + {"i": 247, "op": "add", "dst": 3, "src": 5, "src2": 0, "imm": "0xfed2da4e", "imm2": "0x7b2ff6b7", "rot": 25, "bit": 31, "mask": 2}, + {"i": 248, "op": "add", "dst": 0, "src": 7, "src2": 5, "imm": "0x03b2891c", "imm2": "0xb5fad7b1", "rot": 2, "bit": 0, "mask": 4}, + {"i": 249, "op": "mulhi", "dst": 5, "src": 4, "src2": 6, "imm": "0xa69a1e71", "imm2": "0x15f0c0ea", "rot": 4, "bit": 1, "mask": 4}, + {"i": 250, "op": "add", "dst": 5, "src": 2, "src2": 3, "imm": "0x042cd6e3", "imm2": "0xa7e71c2f", "rot": 24, "bit": 11, "mask": 8}, + {"i": 251, "op": "shfl", "dst": 6, "src": 1, "src2": 2, "imm": "0x89c6b683", "imm2": "0x10bbf661", "rot": 24, "bit": 5, "mask": 1}, + {"i": 252, "op": "xor", "dst": 6, "src": 1, "src2": 3, "imm": "0x265c66d6", "imm2": "0xd4a689ed", "rot": 6, "bit": 14, "mask": 8}, + {"i": 253, "op": "mul", "dst": 2, "src": 5, "src2": 5, "imm": "0x890b8201", "imm2": "0x97c36bf3", "rot": 17, "bit": 22, "mask": 4}, + {"i": 254, "op": "add", "dst": 0, "src": 6, "src2": 0, "imm": "0x784a302b", "imm2": "0xb83d78de", "rot": 27, "bit": 16, "mask": 4}, + {"i": 255, "op": "sub", "dst": 2, "src": 4, "src2": 0, "imm": "0x817adb38", "imm2": "0xf3a3534b", "rot": 7, "bit": 22, "mask": 4} + ]}, + "instructions": [ + {"i": 0, "op": "mad", "dst": 2, "src": 3, "src2": 4, "imm": "0xbf7b174d", "imm2": "0x337b762e", "rot": 17, "bit": 2, "mask": 2, "width": 1}, + {"i": 1, "op": "mad", "dst": 2, "src": 1, "src2": 1, "imm": "0xdd04a5da", "imm2": "0x42da7657", "rot": 15, "bit": 30, "mask": 16, "width": 1}, + {"i": 2, "op": "mad", "dst": 2, "src": 3, "src2": 2, "imm": "0x734003fa", "imm2": "0x5bb67700", "rot": 3, "bit": 20, "mask": 1, "width": 1}, + {"i": 3, "op": "xor", "dst": 3, "src": 5, "src2": 5, "imm": "0xc55a1b1c", "imm2": "0xa19720f3", "rot": 7, "bit": 8, "mask": 1, "width": 1}, + {"i": 4, "op": "load", "dst": 7, "src": 2, "src2": 5, "imm": "0xad572dd7", "imm2": "0x9ceb3ea7", "rot": 18, "bit": 30, "mask": 2, "width": 1}, + {"i": 5, "op": "load", "dst": 5, "src": 7, "src2": 3, "imm": "0x769a53be", "imm2": "0x80f9067e", "rot": 12, "bit": 22, "mask": 1, "width": 1}, + {"i": 6, "op": "shfl", "dst": 1, "src": 4, "src2": 0, "imm": "0xd3613d88", "imm2": "0x262fb219", "rot": 10, "bit": 30, "mask": 8, "width": 1}, + {"i": 7, "op": "shfl", "dst": 7, "src": 3, "src2": 4, "imm": "0xce38e42f", "imm2": "0xb868b818", "rot": 11, "bit": 8, "mask": 8, "width": 1}, + {"i": 8, "op": "mulhi", "dst": 1, "src": 5, "src2": 2, "imm": "0xa5eebca5", "imm2": "0x5703a72b", "rot": 13, "bit": 13, "mask": 16, "width": 1}, + {"i": 9, "op": "rotr", "dst": 6, "src": 3, "src2": 4, "imm": "0x17a5a9c7", "imm2": "0xdcfb93a1", "rot": 20, "bit": 27, "mask": 2, "width": 1}, + {"i": 10, "op": "or", "dst": 3, "src": 4, "src2": 1, "imm": "0xccb7d785", "imm2": "0xc335364c", "rot": 14, "bit": 12, "mask": 4, "width": 1}, + {"i": 11, "op": "load", "dst": 4, "src": 3, "src2": 2, "imm": "0x88cb9af3", "imm2": "0x4e7dc10d", "rot": 24, "bit": 17, "mask": 4, "width": 1}, + {"i": 12, "op": "mulhi", "dst": 0, "src": 4, "src2": 4, "imm": "0x45374321", "imm2": "0x3cd91989", "rot": 11, "bit": 4, "mask": 2, "width": 1}, + {"i": 13, "op": "add", "dst": 5, "src": 1, "src2": 2, "imm": "0xc7934706", "imm2": "0xd3177981", "rot": 16, "bit": 30, "mask": 2, "width": 1}, + {"i": 14, "op": "load", "dst": 0, "src": 4, "src2": 3, "imm": "0xfd7f56bb", "imm2": "0x65e14f52", "rot": 13, "bit": 22, "mask": 2, "width": 1}, + {"i": 15, "op": "sub", "dst": 2, "src": 4, "src2": 4, "imm": "0x35a80b49", "imm2": "0x060f2d13", "rot": 16, "bit": 20, "mask": 16, "width": 1}, + {"i": 16, "op": "load", "dst": 2, "src": 0, "src2": 2, "imm": "0xae0a32c2", "imm2": "0x4c2a4cfe", "rot": 8, "bit": 31, "mask": 16, "width": 1}, + {"i": 17, "op": "load", "dst": 7, "src": 2, "src2": 6, "imm": "0x82a84cc3", "imm2": "0x21a38d68", "rot": 15, "bit": 21, "mask": 2, "width": 1}, + {"i": 18, "op": "shfl", "dst": 7, "src": 3, "src2": 3, "imm": "0xa3818806", "imm2": "0x8f66b5c8", "rot": 14, "bit": 6, "mask": 4, "width": 1}, + {"i": 19, "op": "mul", "dst": 5, "src": 0, "src2": 1, "imm": "0xa00de107", "imm2": "0x77bfcaa5", "rot": 3, "bit": 10, "mask": 2, "width": 1}, + {"i": 20, "op": "shfl", "dst": 3, "src": 4, "src2": 7, "imm": "0x1d2b8cab", "imm2": "0x80b4f9a2", "rot": 14, "bit": 25, "mask": 2, "width": 1}, + {"i": 21, "op": "shfl", "dst": 2, "src": 4, "src2": 5, "imm": "0x3ac915d2", "imm2": "0x5fba7bc2", "rot": 16, "bit": 1, "mask": 16, "width": 1}, + {"i": 22, "op": "mulhi", "dst": 6, "src": 2, "src2": 0, "imm": "0xdc3ec8fd", "imm2": "0x599e2fa3", "rot": 22, "bit": 3, "mask": 2, "width": 1}, + {"i": 23, "op": "load", "dst": 6, "src": 1, "src2": 5, "imm": "0x2a6b16d5", "imm2": "0xd73e396f", "rot": 28, "bit": 29, "mask": 2, "width": 1}, + {"i": 24, "op": "mul", "dst": 5, "src": 0, "src2": 7, "imm": "0x376d0223", "imm2": "0xe1c2169a", "rot": 4, "bit": 16, "mask": 16, "width": 1}, + {"i": 25, "op": "rotl", "dst": 5, "src": 7, "src2": 3, "imm": "0x78ad8c60", "imm2": "0x6f5b77d5", "rot": 19, "bit": 11, "mask": 16, "width": 1}, + {"i": 26, "op": "shfl", "dst": 7, "src": 6, "src2": 5, "imm": "0x93915b9f", "imm2": "0x1e61fb6b", "rot": 28, "bit": 23, "mask": 2, "width": 1}, + {"i": 27, "op": "xor", "dst": 0, "src": 5, "src2": 7, "imm": "0x6378fe15", "imm2": "0x66c78f42", "rot": 12, "bit": 31, "mask": 8, "width": 1}, + {"i": 28, "op": "xor", "dst": 0, "src": 4, "src2": 7, "imm": "0x20a57fda", "imm2": "0x088c848e", "rot": 16, "bit": 13, "mask": 4, "width": 1}, + {"i": 29, "op": "sub", "dst": 3, "src": 0, "src2": 2, "imm": "0x49d95fd5", "imm2": "0x1a5f946a", "rot": 6, "bit": 12, "mask": 1, "width": 1}, + {"i": 30, "op": "mul", "dst": 5, "src": 1, "src2": 7, "imm": "0x0a816217", "imm2": "0x405c4f73", "rot": 13, "bit": 27, "mask": 4, "width": 1}, + {"i": 31, "op": "load", "dst": 7, "src": 2, "src2": 2, "imm": "0x09ed045e", "imm2": "0xd69c4715", "rot": 5, "bit": 9, "mask": 2, "width": 1}, + {"i": 32, "op": "load", "dst": 1, "src": 0, "src2": 6, "imm": "0xeb79ea49", "imm2": "0xcc587f5a", "rot": 6, "bit": 8, "mask": 16, "width": 1}, + {"i": 33, "op": "xor", "dst": 5, "src": 6, "src2": 1, "imm": "0x3027401e", "imm2": "0x5f20c27e", "rot": 18, "bit": 9, "mask": 2, "width": 1}, + {"i": 34, "op": "load", "dst": 5, "src": 1, "src2": 3, "imm": "0x0e1cab07", "imm2": "0x09356c5b", "rot": 19, "bit": 31, "mask": 1, "width": 1}, + {"i": 35, "op": "mulhi", "dst": 0, "src": 5, "src2": 2, "imm": "0x90e31357", "imm2": "0xabd32484", "rot": 26, "bit": 5, "mask": 8, "width": 1}, + {"i": 36, "op": "shfl", "dst": 5, "src": 2, "src2": 5, "imm": "0xee9a955f", "imm2": "0x31b3faed", "rot": 8, "bit": 24, "mask": 4, "width": 1}, + {"i": 37, "op": "load", "dst": 7, "src": 0, "src2": 7, "imm": "0x3ba2f832", "imm2": "0x1160dcd3", "rot": 4, "bit": 29, "mask": 1, "width": 1}, + {"i": 38, "op": "add", "dst": 3, "src": 1, "src2": 7, "imm": "0x75ba2fad", "imm2": "0x230c005c", "rot": 4, "bit": 27, "mask": 1, "width": 1}, + {"i": 39, "op": "shfl", "dst": 1, "src": 5, "src2": 3, "imm": "0xdbf37e75", "imm2": "0xb5ac1969", "rot": 30, "bit": 13, "mask": 4, "width": 1}, + {"i": 40, "op": "xor", "dst": 2, "src": 5, "src2": 5, "imm": "0x47f136c5", "imm2": "0x06ce9153", "rot": 19, "bit": 10, "mask": 2, "width": 1}, + {"i": 41, "op": "mad", "dst": 3, "src": 6, "src2": 3, "imm": "0xce13eff8", "imm2": "0x04cc1d55", "rot": 3, "bit": 1, "mask": 4, "width": 1}, + {"i": 42, "op": "sub", "dst": 6, "src": 7, "src2": 1, "imm": "0x6a65ab71", "imm2": "0x8fbc1bcd", "rot": 4, "bit": 1, "mask": 8, "width": 1}, + {"i": 43, "op": "xor", "dst": 7, "src": 0, "src2": 7, "imm": "0xdaeb4928", "imm2": "0xc0423027", "rot": 24, "bit": 11, "mask": 8, "width": 1}, + {"i": 44, "op": "load", "dst": 1, "src": 7, "src2": 7, "imm": "0x778f01c9", "imm2": "0x28cedcea", "rot": 12, "bit": 4, "mask": 16, "width": 1}, + {"i": 45, "op": "mul", "dst": 2, "src": 3, "src2": 2, "imm": "0xf4264f1b", "imm2": "0x0f627d56", "rot": 5, "bit": 28, "mask": 8, "width": 1}, + {"i": 46, "op": "mulhi", "dst": 1, "src": 5, "src2": 1, "imm": "0xffb2147a", "imm2": "0xccde9b05", "rot": 13, "bit": 9, "mask": 2, "width": 1}, + {"i": 47, "op": "sub", "dst": 4, "src": 3, "src2": 5, "imm": "0x73b36234", "imm2": "0x3f5d5997", "rot": 7, "bit": 18, "mask": 2, "width": 1}, + {"i": 48, "op": "rotr", "dst": 2, "src": 6, "src2": 3, "imm": "0x3a4d9aa9", "imm2": "0x212bec7b", "rot": 4, "bit": 29, "mask": 16, "width": 1}, + {"i": 49, "op": "load", "dst": 3, "src": 5, "src2": 2, "imm": "0x626f11df", "imm2": "0x56cd5bfd", "rot": 7, "bit": 1, "mask": 1, "width": 1}, + {"i": 50, "op": "add", "dst": 1, "src": 5, "src2": 6, "imm": "0x81b8bc2c", "imm2": "0x1907970c", "rot": 28, "bit": 7, "mask": 4, "width": 1}, + {"i": 51, "op": "mul", "dst": 0, "src": 2, "src2": 2, "imm": "0xa8848b30", "imm2": "0xef6ac348", "rot": 9, "bit": 15, "mask": 8, "width": 1}, + {"i": 52, "op": "add", "dst": 0, "src": 2, "src2": 0, "imm": "0x4f92b968", "imm2": "0x699fd448", "rot": 22, "bit": 6, "mask": 4, "width": 1}, + {"i": 53, "op": "add", "dst": 1, "src": 0, "src2": 2, "imm": "0x2bb965af", "imm2": "0x77b1520d", "rot": 2, "bit": 12, "mask": 8, "width": 1}, + {"i": 54, "op": "rotl", "dst": 7, "src": 1, "src2": 0, "imm": "0x553e678b", "imm2": "0x3cc8eae0", "rot": 14, "bit": 20, "mask": 2, "width": 1}, + {"i": 55, "op": "add", "dst": 3, "src": 7, "src2": 2, "imm": "0x7b0fe07a", "imm2": "0xa54c55a0", "rot": 10, "bit": 1, "mask": 1, "width": 1}, + {"i": 56, "op": "load", "dst": 6, "src": 7, "src2": 4, "imm": "0x01eba9aa", "imm2": "0x2758c0f7", "rot": 14, "bit": 15, "mask": 4, "width": 1}, + {"i": 57, "op": "rotr", "dst": 1, "src": 5, "src2": 2, "imm": "0x1f5267b3", "imm2": "0x236f5a27", "rot": 2, "bit": 31, "mask": 16, "width": 1}, + {"i": 58, "op": "load", "dst": 5, "src": 4, "src2": 3, "imm": "0xa9954a9b", "imm2": "0x6a54d4e8", "rot": 11, "bit": 10, "mask": 16, "width": 1}, + {"i": 59, "op": "load", "dst": 6, "src": 2, "src2": 4, "imm": "0x9923ff88", "imm2": "0x9357254e", "rot": 16, "bit": 1, "mask": 16, "width": 1}, + {"i": 60, "op": "mad", "dst": 3, "src": 5, "src2": 0, "imm": "0xc0cc51a6", "imm2": "0x3fd7701b", "rot": 20, "bit": 1, "mask": 4, "width": 1}, + {"i": 61, "op": "add", "dst": 5, "src": 7, "src2": 7, "imm": "0xaf9dd72d", "imm2": "0xad7493e7", "rot": 7, "bit": 31, "mask": 16, "width": 1}, + {"i": 62, "op": "add", "dst": 4, "src": 6, "src2": 2, "imm": "0x89841d87", "imm2": "0x1e07c3d9", "rot": 6, "bit": 27, "mask": 1, "width": 1}, + {"i": 63, "op": "rotl", "dst": 5, "src": 4, "src2": 2, "imm": "0xae210f8d", "imm2": "0x8e499ba4", "rot": 19, "bit": 9, "mask": 1, "width": 1} + ] +} diff --git a/proto-cuda/packs-ca3-shadow/sh256x2/program.metal b/proto-cuda/packs-ca3-shadow/sh256x2/program.metal new file mode 100644 index 000000000..654862e09 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x2/program.metal @@ -0,0 +1,368 @@ +#include +using namespace metal; + +#define MASK 0x0fffffffu +constant uint SEEDW[8] = { 0x67a9a7beu, 0x1a155b25u, 0xfddfb732u, 0x4b5af2e8u, 0xc55caf33u, 0xa27c13b7u, 0x06628a48u, 0x03852469u }; + +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 = r3 * r4 + r2; // 0 + r2 = r1 * r1 + r2; // 1 + r2 = r3 * r2 + r2; // 2 + r3 = r3 ^ r5; // 3 + r7 = r7 ^ dataset[r2 & MASK]; // 4 + r5 = r5 ^ dataset[r7 & MASK]; // 5 + r1 = r1 ^ simd_shuffle_xor(r4, (ushort)8); // 6 + r7 = r7 ^ simd_shuffle_xor(r3, (ushort)8); // 7 + r1 = mulhi(r1, r5); // 8 + r6 = rotr_var(r6, r3); // 9 + r3 = r3 | r4; // 10 + r4 = r4 ^ dataset[r3 & MASK]; // 11 + r0 = mulhi(r0, r4); // 12 + r5 = r5 + r1 + select(0xc7934706u, 0xd3177981u, ((sel >> 30u) & 1u) != 0u); // 13 + r0 = r0 ^ dataset[r4 & MASK]; // 14 + r2 = r2 - r4; // 15 + r2 = r2 ^ dataset[r0 & MASK]; // 16 + r7 = r7 ^ dataset[r2 & MASK]; // 17 + r7 = r7 ^ simd_shuffle_xor(r3, (ushort)4); // 18 + r5 = r5 * r0; // 19 + r3 = r3 ^ simd_shuffle_xor(r4, (ushort)2); // 20 + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)16); // 21 + r6 = mulhi(r6, r2); // 22 + r6 = r6 ^ dataset[r1 & MASK]; // 23 + r5 = r5 * r0; // 24 + r5 = rotl_imm(r5, 19u); // 25 + r7 = r7 ^ simd_shuffle_xor(r6, (ushort)2); // 26 + r0 = r0 ^ r5; // 27 + r0 = r0 ^ r4; // 28 + r3 = r3 - r0; // 29 + r5 = r5 * r1; // 30 + r7 = r7 ^ dataset[r2 & MASK]; // 31 + r1 = r1 ^ dataset[r0 & MASK]; // 32 + r5 = r5 ^ r6; // 33 + r5 = r5 ^ dataset[r1 & MASK]; // 34 + r0 = mulhi(r0, r5); // 35 + r5 = r5 ^ simd_shuffle_xor(r2, (ushort)4); // 36 + r7 = r7 ^ dataset[r0 & MASK]; // 37 + r3 = r3 + r1 + select(0x75ba2fadu, 0x230c005cu, ((sel >> 27u) & 1u) != 0u); // 38 + r1 = r1 ^ simd_shuffle_xor(r5, (ushort)4); // 39 + r2 = r2 ^ r5; // 40 + r3 = r6 * r3 + r3; // 41 + r6 = r6 - r7; // 42 + r7 = r7 ^ r0; // 43 + r1 = r1 ^ dataset[r7 & MASK]; // 44 + r2 = r2 * r3; // 45 + r1 = mulhi(r1, r5); // 46 + r4 = r4 - r3; // 47 + r2 = rotr_var(r2, r6); // 48 + r3 = r3 ^ dataset[r5 & MASK]; // 49 + r1 = r1 + r5 + select(0x81b8bc2cu, 0x1907970cu, ((sel >> 7u) & 1u) != 0u); // 50 + r0 = r0 * r2; // 51 + r0 = r0 + r2 + select(0x4f92b968u, 0x699fd448u, ((sel >> 6u) & 1u) != 0u); // 52 + r1 = r1 + r0 + select(0x2bb965afu, 0x77b1520du, ((sel >> 12u) & 1u) != 0u); // 53 + r7 = rotl_imm(r7, 14u); // 54 + r3 = r3 + r7 + select(0x7b0fe07au, 0xa54c55a0u, ((sel >> 1u) & 1u) != 0u); // 55 + r6 = r6 ^ dataset[r7 & MASK]; // 56 + r1 = rotr_var(r1, r5); // 57 + r5 = r5 ^ dataset[r4 & MASK]; // 58 + r6 = r6 ^ dataset[r2 & MASK]; // 59 + r3 = r5 * r0 + r3; // 60 + r5 = r5 + r7 + select(0xaf9dd72du, 0xad7493e7u, ((sel >> 31u) & 1u) != 0u); // 61 + r4 = r4 + r6 + select(0x89841d87u, 0x1e07c3d9u, ((sel >> 27u) & 1u) != 0u); // 62 + r5 = rotl_imm(r5, 19u); // 63 + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 2 passes after instruction 63, no load + for (uint sh = 0u; sh < 2u; ++sh) { + r5 = r5 + r2 + select(0x92199f99u, 0x8bc12da9u, ((sel >> 18u) & 1u) != 0u); // s0 add + r0 = r0 + r7 + select(0x8d72d3adu, 0x63079e5au, ((sel >> 26u) & 1u) != 0u); // s1 add + r6 = r6 ^ simd_shuffle_xor(r3, (ushort)2); // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + select(0xb21b4babu, 0x5d4c7a60u, ((sel >> 31u) & 1u) != 0u); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + select(0x2fe0e98bu, 0xc88e2942u, ((sel >> 16u) & 1u) != 0u); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + r6 = r6 ^ simd_shuffle_xor(r1, (ushort)4); // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + r2 = r2 ^ simd_shuffle_xor(r6, (ushort)4); // s12 shfl + r1 = r1 + r5 + select(0xbdf8f9a5u, 0xbc48c63eu, ((sel >> 25u) & 1u) != 0u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)8); // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + select(0x45c37cecu, 0x96e8f127u, ((sel >> 1u) & 1u) != 0u); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = mulhi(r6, r0); // s28 mulhi + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)2); // s29 shfl + r1 = r1 ^ simd_shuffle_xor(r6, (ushort)1); // s30 shfl + r1 = r1 + r6 + select(0x37985632u, 0xb1cdb2abu, ((sel >> 1u) & 1u) != 0u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + r3 = r3 ^ simd_shuffle_xor(r4, (ushort)2); // s33 shfl + r0 = r0 ^ simd_shuffle_xor(r3, (ushort)4); // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + select(0x804e777eu, 0x856e0180u, ((sel >> 0u) & 1u) != 0u); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + select(0x0b06c8a7u, 0xe9bd0cc4u, ((sel >> 2u) & 1u) != 0u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = mulhi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = mulhi(r4, r3); // s44 mulhi + r6 = r6 + r7 + select(0xee822e17u, 0xcdcb63f6u, ((sel >> 12u) & 1u) != 0u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + r4 = r4 ^ simd_shuffle_xor(r3, (ushort)8); // s47 shfl + r6 = mulhi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + select(0x3dfad1b6u, 0xd4758987u, ((sel >> 10u) & 1u) != 0u); // s56 add + r4 = r4 + r1 + select(0xfca75bc2u, 0x0602d6beu, ((sel >> 0u) & 1u) != 0u); // s57 add + r5 = mulhi(r5, r6); // s58 mulhi + r2 = r2 ^ simd_shuffle_xor(r1, (ushort)2); // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + select(0xd71c02ffu, 0x8596687au, ((sel >> 6u) & 1u) != 0u); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + r7 = r7 ^ simd_shuffle_xor(r5, (ushort)2); // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + select(0x3c6fe15du, 0x08ac5733u, ((sel >> 0u) & 1u) != 0u); // s72 add + r3 = r3 ^ simd_shuffle_xor(r2, (ushort)8); // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + select(0x295d5faeu, 0xc100b495u, ((sel >> 1u) & 1u) != 0u); // s77 add + r3 = mulhi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + select(0x274a9221u, 0x5cc59530u, ((sel >> 15u) & 1u) != 0u); // s81 add + r7 = r7 + r3 + select(0xc8651f8eu, 0x141479ecu, ((sel >> 5u) & 1u) != 0u); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + r2 = r2 ^ simd_shuffle_xor(r5, (ushort)16); // s85 shfl + r3 = r3 ^ r2; // s86 xor + r5 = r5 ^ simd_shuffle_xor(r7, (ushort)2); // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + select(0x53f915c2u, 0x883c0c92u, ((sel >> 18u) & 1u) != 0u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + select(0xe2be00a5u, 0x3cc5bd20u, ((sel >> 31u) & 1u) != 0u); // s91 add + r7 = r7 ^ simd_shuffle_xor(r2, (ushort)1); // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + select(0x423fd9c9u, 0xbfd646cbu, ((sel >> 17u) & 1u) != 0u); // s101 add + r7 = r7 + r6 + select(0x8d3c011du, 0x19b74a43u, ((sel >> 11u) & 1u) != 0u); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + select(0x8ce14721u, 0x7dcb7e18u, ((sel >> 15u) & 1u) != 0u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = mulhi(r2, r0); // s109 mulhi + r1 = mulhi(r1, r0); // s110 mulhi + r0 = r0 + r2 + select(0x2d9fc6b9u, 0x3c179ad8u, ((sel >> 28u) & 1u) != 0u); // s111 add + r2 = mulhi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + select(0x502138e2u, 0x47359729u, ((sel >> 22u) & 1u) != 0u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = mulhi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + r4 = r4 ^ simd_shuffle_xor(r2, (ushort)2); // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + r7 = r7 ^ simd_shuffle_xor(r2, (ushort)4); // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + select(0x33dff776u, 0x6c57e4e7u, ((sel >> 15u) & 1u) != 0u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + select(0x5db25b34u, 0xe8212c0cu, ((sel >> 30u) & 1u) != 0u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = mulhi(r0, r5); // s138 mulhi + r2 = r2 + r7 + select(0x218d4090u, 0xd44ff710u, ((sel >> 10u) & 1u) != 0u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + r3 = r3 ^ simd_shuffle_xor(r6, (ushort)1); // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + select(0xf4b1a8deu, 0xb98942fau, ((sel >> 29u) & 1u) != 0u); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + select(0x2bef10f2u, 0x0d48ba42u, ((sel >> 17u) & 1u) != 0u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + select(0xdc5cc080u, 0xc98dea9cu, ((sel >> 30u) & 1u) != 0u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + select(0x18197438u, 0x6c752dcbu, ((sel >> 11u) & 1u) != 0u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + select(0xf1c46574u, 0x8e481727u, ((sel >> 3u) & 1u) != 0u); // s163 add + r0 = mulhi(r0, r4); // s164 mulhi + r2 = r2 + r6 + select(0xac578137u, 0x550ab406u, ((sel >> 20u) & 1u) != 0u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + select(0xa33e6706u, 0xaebb5966u, ((sel >> 14u) & 1u) != 0u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + r7 = r7 ^ simd_shuffle_xor(r0, (ushort)8); // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + select(0xd94d55acu, 0x5bb7550fu, ((sel >> 21u) & 1u) != 0u); // s184 add + r3 = r3 | r5; // s185 or + r6 = mulhi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)2); // s188 shfl + r6 = r6 + r5 + select(0x89e747feu, 0x2a354e2du, ((sel >> 6u) & 1u) != 0u); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = mulhi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + r4 = r4 ^ simd_shuffle_xor(r5, (ushort)16); // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + select(0xea03e8e7u, 0x10cfdc71u, ((sel >> 7u) & 1u) != 0u); // s197 add + r7 = r7 + r5 + select(0xa7ee0102u, 0x66e148d3u, ((sel >> 15u) & 1u) != 0u); // s198 add + r5 = r5 - r2; // s199 sub + r5 = r5 ^ simd_shuffle_xor(r1, (ushort)2); // s200 shfl + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)8); // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + select(0x8379a4deu, 0x8558b619u, ((sel >> 10u) & 1u) != 0u); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = mulhi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + r2 = r2 ^ simd_shuffle_xor(r0, (ushort)4); // s209 shfl + r7 = r7 + r0 + select(0xaa8cb14eu, 0xf4049c4cu, ((sel >> 11u) & 1u) != 0u); // s210 add + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)16); // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + r3 = r3 ^ simd_shuffle_xor(r2, (ushort)16); // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = mulhi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + r5 = r5 ^ simd_shuffle_xor(r2, (ushort)8); // s222 shfl + r5 = mulhi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + select(0x1d176220u, 0x2a7fecb2u, ((sel >> 16u) & 1u) != 0u); // s230 add + r1 = r1 ^ simd_shuffle_xor(r2, (ushort)4); // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + select(0x17dafb4du, 0xadce39f3u, ((sel >> 25u) & 1u) != 0u); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + select(0xf2f77d26u, 0x0e7033b6u, ((sel >> 29u) & 1u) != 0u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + select(0xfed2da4eu, 0x7b2ff6b7u, ((sel >> 31u) & 1u) != 0u); // s247 add + r0 = r0 + r7 + select(0x03b2891cu, 0xb5fad7b1u, ((sel >> 0u) & 1u) != 0u); // s248 add + r5 = mulhi(r5, r4); // s249 mulhi + r5 = r5 + r2 + select(0x042cd6e3u, 0xa7e71c2fu, ((sel >> 11u) & 1u) != 0u); // s250 add + r6 = r6 ^ simd_shuffle_xor(r1, (ushort)1); // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + select(0x784a302bu, 0xb83d78deu, ((sel >> 16u) & 1u) != 0u); // s254 add + r2 = r2 - r4; // s255 sub + } + } + uint lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((ulong)hi << 32) | (ulong)lo; +} diff --git a/proto-cuda/packs-ca3-shadow/sh256x2/program_bound.metal b/proto-cuda/packs-ca3-shadow/sh256x2/program_bound.metal new file mode 100644 index 000000000..976bdef5c --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x2/program_bound.metal @@ -0,0 +1,370 @@ +#include +using namespace metal; + +#define MASK 0x0fffffffu +constant uint SEEDW[8] = { 0x67a9a7beu, 0x1a155b25u, 0xfddfb732u, 0x4b5af2e8u, 0xc55caf33u, 0xa27c13b7u, 0x06628a48u, 0x03852469u }; + +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 = r3 * r4 + r2; // 0 + r2 = r1 * r1 + r2; // 1 + r2 = r3 * r2 + r2; // 2 + r3 = r3 ^ r5; // 3 + r7 = r7 ^ dataset[r2 & MASK]; // 4 + r5 = r5 ^ dataset[r7 & MASK]; // 5 + r1 = r1 ^ simd_shuffle_xor(r4, (ushort)8); // 6 + r7 = r7 ^ simd_shuffle_xor(r3, (ushort)8); // 7 + r1 = mulhi(r1, r5); // 8 + r6 = rotr_var(r6, r3); // 9 + r3 = r3 | r4; // 10 + r4 = r4 ^ dataset[r3 & MASK]; // 11 + r0 = mulhi(r0, r4); // 12 + r5 = r5 + r1 + select(0xc7934706u, 0xd3177981u, ((sel >> 30u) & 1u) != 0u); // 13 + r0 = r0 ^ dataset[r4 & MASK]; // 14 + r2 = r2 - r4; // 15 + r2 = r2 ^ dataset[r0 & MASK]; // 16 + r7 = r7 ^ dataset[r2 & MASK]; // 17 + r7 = r7 ^ simd_shuffle_xor(r3, (ushort)4); // 18 + r5 = r5 * r0; // 19 + r3 = r3 ^ simd_shuffle_xor(r4, (ushort)2); // 20 + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)16); // 21 + r6 = mulhi(r6, r2); // 22 + r6 = r6 ^ dataset[r1 & MASK]; // 23 + r5 = r5 * r0; // 24 + r5 = rotl_imm(r5, 19u); // 25 + r7 = r7 ^ simd_shuffle_xor(r6, (ushort)2); // 26 + r0 = r0 ^ r5; // 27 + r0 = r0 ^ r4; // 28 + r3 = r3 - r0; // 29 + r5 = r5 * r1; // 30 + r7 = r7 ^ dataset[r2 & MASK]; // 31 + r1 = r1 ^ dataset[r0 & MASK]; // 32 + r5 = r5 ^ r6; // 33 + r5 = r5 ^ dataset[r1 & MASK]; // 34 + r0 = mulhi(r0, r5); // 35 + r5 = r5 ^ simd_shuffle_xor(r2, (ushort)4); // 36 + r7 = r7 ^ dataset[r0 & MASK]; // 37 + r3 = r3 + r1 + select(0x75ba2fadu, 0x230c005cu, ((sel >> 27u) & 1u) != 0u); // 38 + r1 = r1 ^ simd_shuffle_xor(r5, (ushort)4); // 39 + r2 = r2 ^ r5; // 40 + r3 = r6 * r3 + r3; // 41 + r6 = r6 - r7; // 42 + r7 = r7 ^ r0; // 43 + r1 = r1 ^ dataset[r7 & MASK]; // 44 + r2 = r2 * r3; // 45 + r1 = mulhi(r1, r5); // 46 + r4 = r4 - r3; // 47 + r2 = rotr_var(r2, r6); // 48 + r3 = r3 ^ dataset[r5 & MASK]; // 49 + r1 = r1 + r5 + select(0x81b8bc2cu, 0x1907970cu, ((sel >> 7u) & 1u) != 0u); // 50 + r0 = r0 * r2; // 51 + r0 = r0 + r2 + select(0x4f92b968u, 0x699fd448u, ((sel >> 6u) & 1u) != 0u); // 52 + r1 = r1 + r0 + select(0x2bb965afu, 0x77b1520du, ((sel >> 12u) & 1u) != 0u); // 53 + r7 = rotl_imm(r7, 14u); // 54 + r3 = r3 + r7 + select(0x7b0fe07au, 0xa54c55a0u, ((sel >> 1u) & 1u) != 0u); // 55 + r6 = r6 ^ dataset[r7 & MASK]; // 56 + r1 = rotr_var(r1, r5); // 57 + r5 = r5 ^ dataset[r4 & MASK]; // 58 + r6 = r6 ^ dataset[r2 & MASK]; // 59 + r3 = r5 * r0 + r3; // 60 + r5 = r5 + r7 + select(0xaf9dd72du, 0xad7493e7u, ((sel >> 31u) & 1u) != 0u); // 61 + r4 = r4 + r6 + select(0x89841d87u, 0x1e07c3d9u, ((sel >> 27u) & 1u) != 0u); // 62 + r5 = rotl_imm(r5, 19u); // 63 + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 2 passes after instruction 63, no load + for (uint sh = 0u; sh < 2u; ++sh) { + r5 = r5 + r2 + select(0x92199f99u, 0x8bc12da9u, ((sel >> 18u) & 1u) != 0u); // s0 add + r0 = r0 + r7 + select(0x8d72d3adu, 0x63079e5au, ((sel >> 26u) & 1u) != 0u); // s1 add + r6 = r6 ^ simd_shuffle_xor(r3, (ushort)2); // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + select(0xb21b4babu, 0x5d4c7a60u, ((sel >> 31u) & 1u) != 0u); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + select(0x2fe0e98bu, 0xc88e2942u, ((sel >> 16u) & 1u) != 0u); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + r6 = r6 ^ simd_shuffle_xor(r1, (ushort)4); // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + r2 = r2 ^ simd_shuffle_xor(r6, (ushort)4); // s12 shfl + r1 = r1 + r5 + select(0xbdf8f9a5u, 0xbc48c63eu, ((sel >> 25u) & 1u) != 0u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)8); // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + select(0x45c37cecu, 0x96e8f127u, ((sel >> 1u) & 1u) != 0u); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = mulhi(r6, r0); // s28 mulhi + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)2); // s29 shfl + r1 = r1 ^ simd_shuffle_xor(r6, (ushort)1); // s30 shfl + r1 = r1 + r6 + select(0x37985632u, 0xb1cdb2abu, ((sel >> 1u) & 1u) != 0u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + r3 = r3 ^ simd_shuffle_xor(r4, (ushort)2); // s33 shfl + r0 = r0 ^ simd_shuffle_xor(r3, (ushort)4); // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + select(0x804e777eu, 0x856e0180u, ((sel >> 0u) & 1u) != 0u); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + select(0x0b06c8a7u, 0xe9bd0cc4u, ((sel >> 2u) & 1u) != 0u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = mulhi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = mulhi(r4, r3); // s44 mulhi + r6 = r6 + r7 + select(0xee822e17u, 0xcdcb63f6u, ((sel >> 12u) & 1u) != 0u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + r4 = r4 ^ simd_shuffle_xor(r3, (ushort)8); // s47 shfl + r6 = mulhi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + select(0x3dfad1b6u, 0xd4758987u, ((sel >> 10u) & 1u) != 0u); // s56 add + r4 = r4 + r1 + select(0xfca75bc2u, 0x0602d6beu, ((sel >> 0u) & 1u) != 0u); // s57 add + r5 = mulhi(r5, r6); // s58 mulhi + r2 = r2 ^ simd_shuffle_xor(r1, (ushort)2); // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + select(0xd71c02ffu, 0x8596687au, ((sel >> 6u) & 1u) != 0u); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + r7 = r7 ^ simd_shuffle_xor(r5, (ushort)2); // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + select(0x3c6fe15du, 0x08ac5733u, ((sel >> 0u) & 1u) != 0u); // s72 add + r3 = r3 ^ simd_shuffle_xor(r2, (ushort)8); // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + select(0x295d5faeu, 0xc100b495u, ((sel >> 1u) & 1u) != 0u); // s77 add + r3 = mulhi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + select(0x274a9221u, 0x5cc59530u, ((sel >> 15u) & 1u) != 0u); // s81 add + r7 = r7 + r3 + select(0xc8651f8eu, 0x141479ecu, ((sel >> 5u) & 1u) != 0u); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + r2 = r2 ^ simd_shuffle_xor(r5, (ushort)16); // s85 shfl + r3 = r3 ^ r2; // s86 xor + r5 = r5 ^ simd_shuffle_xor(r7, (ushort)2); // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + select(0x53f915c2u, 0x883c0c92u, ((sel >> 18u) & 1u) != 0u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + select(0xe2be00a5u, 0x3cc5bd20u, ((sel >> 31u) & 1u) != 0u); // s91 add + r7 = r7 ^ simd_shuffle_xor(r2, (ushort)1); // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + select(0x423fd9c9u, 0xbfd646cbu, ((sel >> 17u) & 1u) != 0u); // s101 add + r7 = r7 + r6 + select(0x8d3c011du, 0x19b74a43u, ((sel >> 11u) & 1u) != 0u); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + select(0x8ce14721u, 0x7dcb7e18u, ((sel >> 15u) & 1u) != 0u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = mulhi(r2, r0); // s109 mulhi + r1 = mulhi(r1, r0); // s110 mulhi + r0 = r0 + r2 + select(0x2d9fc6b9u, 0x3c179ad8u, ((sel >> 28u) & 1u) != 0u); // s111 add + r2 = mulhi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + select(0x502138e2u, 0x47359729u, ((sel >> 22u) & 1u) != 0u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = mulhi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + r4 = r4 ^ simd_shuffle_xor(r2, (ushort)2); // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + r7 = r7 ^ simd_shuffle_xor(r2, (ushort)4); // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + select(0x33dff776u, 0x6c57e4e7u, ((sel >> 15u) & 1u) != 0u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + select(0x5db25b34u, 0xe8212c0cu, ((sel >> 30u) & 1u) != 0u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = mulhi(r0, r5); // s138 mulhi + r2 = r2 + r7 + select(0x218d4090u, 0xd44ff710u, ((sel >> 10u) & 1u) != 0u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + r3 = r3 ^ simd_shuffle_xor(r6, (ushort)1); // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + select(0xf4b1a8deu, 0xb98942fau, ((sel >> 29u) & 1u) != 0u); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + select(0x2bef10f2u, 0x0d48ba42u, ((sel >> 17u) & 1u) != 0u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + select(0xdc5cc080u, 0xc98dea9cu, ((sel >> 30u) & 1u) != 0u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + select(0x18197438u, 0x6c752dcbu, ((sel >> 11u) & 1u) != 0u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + select(0xf1c46574u, 0x8e481727u, ((sel >> 3u) & 1u) != 0u); // s163 add + r0 = mulhi(r0, r4); // s164 mulhi + r2 = r2 + r6 + select(0xac578137u, 0x550ab406u, ((sel >> 20u) & 1u) != 0u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + select(0xa33e6706u, 0xaebb5966u, ((sel >> 14u) & 1u) != 0u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + r7 = r7 ^ simd_shuffle_xor(r0, (ushort)8); // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + select(0xd94d55acu, 0x5bb7550fu, ((sel >> 21u) & 1u) != 0u); // s184 add + r3 = r3 | r5; // s185 or + r6 = mulhi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)2); // s188 shfl + r6 = r6 + r5 + select(0x89e747feu, 0x2a354e2du, ((sel >> 6u) & 1u) != 0u); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = mulhi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + r4 = r4 ^ simd_shuffle_xor(r5, (ushort)16); // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + select(0xea03e8e7u, 0x10cfdc71u, ((sel >> 7u) & 1u) != 0u); // s197 add + r7 = r7 + r5 + select(0xa7ee0102u, 0x66e148d3u, ((sel >> 15u) & 1u) != 0u); // s198 add + r5 = r5 - r2; // s199 sub + r5 = r5 ^ simd_shuffle_xor(r1, (ushort)2); // s200 shfl + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)8); // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + select(0x8379a4deu, 0x8558b619u, ((sel >> 10u) & 1u) != 0u); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = mulhi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + r2 = r2 ^ simd_shuffle_xor(r0, (ushort)4); // s209 shfl + r7 = r7 + r0 + select(0xaa8cb14eu, 0xf4049c4cu, ((sel >> 11u) & 1u) != 0u); // s210 add + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)16); // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + r3 = r3 ^ simd_shuffle_xor(r2, (ushort)16); // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = mulhi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + r5 = r5 ^ simd_shuffle_xor(r2, (ushort)8); // s222 shfl + r5 = mulhi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + select(0x1d176220u, 0x2a7fecb2u, ((sel >> 16u) & 1u) != 0u); // s230 add + r1 = r1 ^ simd_shuffle_xor(r2, (ushort)4); // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + select(0x17dafb4du, 0xadce39f3u, ((sel >> 25u) & 1u) != 0u); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + select(0xf2f77d26u, 0x0e7033b6u, ((sel >> 29u) & 1u) != 0u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + select(0xfed2da4eu, 0x7b2ff6b7u, ((sel >> 31u) & 1u) != 0u); // s247 add + r0 = r0 + r7 + select(0x03b2891cu, 0xb5fad7b1u, ((sel >> 0u) & 1u) != 0u); // s248 add + r5 = mulhi(r5, r4); // s249 mulhi + r5 = r5 + r2 + select(0x042cd6e3u, 0xa7e71c2fu, ((sel >> 11u) & 1u) != 0u); // s250 add + r6 = r6 ^ simd_shuffle_xor(r1, (ushort)1); // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + select(0x784a302bu, 0xb83d78deu, ((sel >> 16u) & 1u) != 0u); // s254 add + r2 = r2 - r4; // s255 sub + } + } + uint lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((ulong)hi << 32) | (ulong)lo; +} diff --git a/proto-cuda/packs-ca3-shadow/sh256x2/vectors.h b/proto-cuda/packs-ca3-shadow/sh256x2/vectors.h new file mode 100644 index 000000000..aac6ba40e --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x2/vectors.h @@ -0,0 +1,57 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Expected outputs: igneum-pow (Rust) CPU interpreter, generator v2, memory-hard dataset +#pragma once +#ifdef __cplusplus +#include +#else +#include +#endif + +#define IGNEUM_VEC_WARPS 3 +static const uint32_t IGNEUM_VEC_BASE[IGNEUM_VEC_WARPS] = { 0u, 4096u, 1000000u }; +static const uint64_t IGNEUM_VEC_OUT[IGNEUM_VEC_WARPS][32] = { + { // base nonce 0 + 0x04e491e95153d0c0ull, 0x4c42169e1e0b8105ull, 0x0d90a3f13ae112f5ull, 0x7655b613a9d5c4a1ull, 0x175f062319f0c695ull, 0x03353125cf0b0b99ull, 0xf7b735876b46c7c6ull, 0x8237cad948b448ffull, + 0x7e3457c2012f86a1ull, 0xd263e7d83b4bcf46ull, 0x59a40a1e54938c0dull, 0x1b9d1ce89913ead7ull, 0xfb61039aba89f77cull, 0x72e74850db581418ull, 0x3b3ba880375afd7bull, 0xa272b7c295b800d6ull, + 0xe5170a8eb49dc9a4ull, 0x9a09fef0590c4f68ull, 0xe339e58d335c62b1ull, 0xbbe4dcd67ef024e4ull, 0xb58d47107235fc41ull, 0x74fb7ba7185593c2ull, 0xc748f87aa4be1db6ull, 0xd3145c4e1af3852cull, + 0x2dc5b295462aa440ull, 0xd4c1f90dd516b1deull, 0xdf3749272aaa156bull, 0x5b975060e5e9ee08ull, 0x19aa57c02ff889d2ull, 0x86bf447f041aa78bull, 0x51a9bf4b0e40016aull, 0xf4cc02d0f2be1e30ull + }, + { // base nonce 4096 + 0xfa09e795bcf4cc16ull, 0x74a0400fc0d4dd31ull, 0x18aca4406173e8b4ull, 0x3a20caf44908e583ull, 0x6fdfd9cf0198f91aull, 0x96d3c284b0e23363ull, 0x2d0237e263af2f32ull, 0xc44c5d56ddb5492eull, + 0xf862e9bb6fb96d29ull, 0x1679aa2bf73dd7f6ull, 0x123bd29e9e98b2a7ull, 0x7a2bf08712d1f05aull, 0x13eef78a31863d73ull, 0xb2c3d02ef4751a6full, 0x264c88bd8165d431ull, 0x9a1c44a5dd2f4a5dull, + 0xb2d647e692987978ull, 0x8f7fe312b703f739ull, 0x359ea150a66f254cull, 0x7432685b3fa426f6ull, 0x9fbf8c15aff45253ull, 0x30a58e634bd3e321ull, 0x68b90886acfd416cull, 0xe3bcbe6f0477291bull, + 0x33d0e37352364c88ull, 0xa69355a1e959fab7ull, 0x1f4da9c95e497dcfull, 0x66d1a41ad8b76ed9ull, 0x888cfa862362596cull, 0xdf64b72bd1469706ull, 0x29aebe5f9290a5afull, 0x426640cc3a300384ull + }, + { // base nonce 1000000 + 0x3085acf29175f955ull, 0x71fce956fef7c0dcull, 0xd65f7f4f7b5da589ull, 0xf453369353c73bb8ull, 0x28e13e24ae8d9f89ull, 0xd7a3594113498879ull, 0x8f1f8db45dd80ee6ull, 0x847d40b7357ca8ebull, + 0xa199177bc3f7f7a3ull, 0x26e92f6b2077b4d4ull, 0x24f9f1863917dcbcull, 0x1a030d008b777b08ull, 0xebcc0cc9db7c412eull, 0xebb9e3bfa513b0c0ull, 0x5acf6325ac29d53bull, 0xc36c4c199faf1234ull, + 0xacff161df7f202a1ull, 0x2805c39d5bbfb402ull, 0xc3b49f0eda801af6ull, 0x669fa3adaf9cecfeull, 0x9d2b9f502941f5a6ull, 0x18f6d5ad37784f60ull, 0x4cc22b6763f00357ull, 0x9a600deb62c80c0aull, + 0x9ee7ff942eb3d51full, 0x465c74e3f9c48c0eull, 0xa3e54e42f498cfe7ull, 0x3e2ed6c098a6fd94ull, 0x3a3116c0b3eda0b6ull, 0x39b64b349ca5f65eull, 0x4529d689581f15e5ull, 0x4a000068b04c79c2ull + } +}; + +// Dataset self-test: dataset[0..15] and dataset[IGNEUM_MASK] (268435455). +static const uint32_t IGNEUM_DS_HEAD[16] = { + 0xfdad4319u, 0x1a7b68e1u, 0xde6db608u, 0x13d73892u, 0xd17f447au, 0xb2221ccfu, 0x9db004bdu, 0x57d7d367u, + 0xdbc4cf34u, 0x697c009au, 0xc43af1d4u, 0x97f12b2eu, 0x74c37cd0u, 0xc651ea15u, 0x665a6d29u, 0x22330a2du +}; +static const uint32_t IGNEUM_DS_LAST_INDEX = 268435455u; +static const uint32_t IGNEUM_DS_LAST = 0xa83e7aa6u; +// 64 sampled dataset words (index, value) computed on the Mac. +#define IGNEUM_DS_SAMPLES 64 +static const uint32_t IGNEUM_DS_SAMPLE_INDEX[IGNEUM_DS_SAMPLES] = { + 59471966u, 217795994u, 208353206u, 42483309u, 172547758u, 148076330u, 183853158u, 214389424u, 267488061u, 169781097u, 184093494u, 153880993u, 84977930u, 46426879u, 3093825u, 225364072u, 44593546u, 260713159u, 168250303u, 52384140u, 223401610u, 45554030u, 95410555u, 175039924u, 79171087u, 267580473u, 24168642u, 37981670u, 171551130u, 195559979u, 204611762u, 140997658u, 138925853u, 86637313u, 20736778u, 219665210u, 160430336u, 264654675u, 8013395u, 228945585u, 213884386u, 104419827u, 44185464u, 142737231u, 99284897u, 132475900u, 61861762u, 132056166u, 262388043u, 91878046u, 117353561u, 124768597u, 71352993u, 190698941u, 46055428u, 55281366u, 165145231u, 106810753u, 171985651u, 232085256u, 159510492u, 40072060u, 209107596u, 39023794u +}; +static const uint32_t IGNEUM_DS_SAMPLE_VALUE[IGNEUM_DS_SAMPLES] = { + 0x3230bc7bu, 0x7fbfe2c9u, 0xb2690991u, 0x1745c7c5u, 0x0ab0ccafu, 0x1bf87d6bu, 0x160139fdu, 0x719817acu, 0x0155df4bu, 0xbe1e86c3u, 0x680bcd6cu, 0x79c3dc6cu, 0x181e7e5fu, 0x0713a109u, 0xc705dd9fu, 0x3933b7a8u, 0xdd1c0431u, 0x50522b30u, 0xa0020b38u, 0xbff39e96u, 0x21b67e18u, 0x740f8db3u, 0x2baba568u, 0x2c9bef83u, 0x0ad9b671u, 0xc4327869u, 0x7b4fd7d0u, 0x2c29965fu, 0xec56f15fu, 0x61111746u, 0x303a1d6eu, 0xbddcfd1au, 0xf829a355u, 0x6d5df2a9u, 0x01ab8e44u, 0x06d13507u, 0xda8dcfc6u, 0x01a703e1u, 0xafe7d2c1u, 0xc091c3a2u, 0xac1814feu, 0x6e6ff62au, 0x8fdf01bau, 0xdd3f7159u, 0xdfa0d75cu, 0x26684c35u, 0x7f441e63u, 0x88df2570u, 0x8aa4d5ebu, 0xcc816c05u, 0x434df890u, 0xcd392ad6u, 0x1ab4cb63u, 0x595926fau, 0x7cd76b41u, 0x20cb95c4u, 0x13cf823fu, 0xf9daf901u, 0xff9af40au, 0x2c7dfa51u, 0x871206dbu, 0x938c116cu, 0xb64bf199u, 0x5751f874u +}; +// Cache self-test (memory-hard mode): cache[0..15], the last 16 words, and FNV-1a 64 over all 2^26 words. +static const uint32_t IGNEUM_CACHE_HEAD[16] = { + 0x355a86d2u, 0x7957db1cu, 0xd21772afu, 0x6fc1e09bu, 0xd55ce61du, 0x6e6a278bu, 0xd3f543ceu, 0x223d8e82u, + 0x143ab337u, 0x2e9f05bdu, 0x2eb389bfu, 0x0c6e449eu, 0x5cfa4222u, 0xba6560feu, 0x8e3e1aa4u, 0xdbcc1d53u +}; +static const uint32_t IGNEUM_CACHE_LAST[16] = { + 0x41190d91u, 0xbd277957u, 0x22ddbb49u, 0x6986f207u, 0xdf69a4d6u, 0x26401a3au, 0x818230fbu, 0xc417122du, + 0x3597b211u, 0xb553ce55u, 0xcf39cc0du, 0x3b7fc43au, 0x3fd43b00u, 0x67e1c80eu, 0xffa7ea7du, 0xca2960abu +}; +static const uint64_t IGNEUM_CACHE_FNV64 = 0x48c4f5bf24166b2eull; diff --git a/proto-cuda/packs-ca3-shadow/sh256x2/vectors.json b/proto-cuda/packs-ca3-shadow/sh256x2/vectors.json new file mode 100644 index 000000000..e6516b9db --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x2/vectors.json @@ -0,0 +1,36 @@ +{ + "seed": "igneum-genesis", + "day": "2026-10-03", + "dataset_mode": "memory-hard", + "dataset_log2_words": 28, + "mask": "0x0fffffff", + "lanes": 32, + "source": "igneum-pow (Rust) CPU interpreter, generator v2, memory-hard dataset", + "warps": [ + {"base_nonce": 0, "expected": [ + "0x04e491e95153d0c0", "0x4c42169e1e0b8105", "0x0d90a3f13ae112f5", "0x7655b613a9d5c4a1", "0x175f062319f0c695", "0x03353125cf0b0b99", "0xf7b735876b46c7c6", "0x8237cad948b448ff", + "0x7e3457c2012f86a1", "0xd263e7d83b4bcf46", "0x59a40a1e54938c0d", "0x1b9d1ce89913ead7", "0xfb61039aba89f77c", "0x72e74850db581418", "0x3b3ba880375afd7b", "0xa272b7c295b800d6", + "0xe5170a8eb49dc9a4", "0x9a09fef0590c4f68", "0xe339e58d335c62b1", "0xbbe4dcd67ef024e4", "0xb58d47107235fc41", "0x74fb7ba7185593c2", "0xc748f87aa4be1db6", "0xd3145c4e1af3852c", + "0x2dc5b295462aa440", "0xd4c1f90dd516b1de", "0xdf3749272aaa156b", "0x5b975060e5e9ee08", "0x19aa57c02ff889d2", "0x86bf447f041aa78b", "0x51a9bf4b0e40016a", "0xf4cc02d0f2be1e30" + ]}, + {"base_nonce": 4096, "expected": [ + "0xfa09e795bcf4cc16", "0x74a0400fc0d4dd31", "0x18aca4406173e8b4", "0x3a20caf44908e583", "0x6fdfd9cf0198f91a", "0x96d3c284b0e23363", "0x2d0237e263af2f32", "0xc44c5d56ddb5492e", + "0xf862e9bb6fb96d29", "0x1679aa2bf73dd7f6", "0x123bd29e9e98b2a7", "0x7a2bf08712d1f05a", "0x13eef78a31863d73", "0xb2c3d02ef4751a6f", "0x264c88bd8165d431", "0x9a1c44a5dd2f4a5d", + "0xb2d647e692987978", "0x8f7fe312b703f739", "0x359ea150a66f254c", "0x7432685b3fa426f6", "0x9fbf8c15aff45253", "0x30a58e634bd3e321", "0x68b90886acfd416c", "0xe3bcbe6f0477291b", + "0x33d0e37352364c88", "0xa69355a1e959fab7", "0x1f4da9c95e497dcf", "0x66d1a41ad8b76ed9", "0x888cfa862362596c", "0xdf64b72bd1469706", "0x29aebe5f9290a5af", "0x426640cc3a300384" + ]}, + {"base_nonce": 1000000, "expected": [ + "0x3085acf29175f955", "0x71fce956fef7c0dc", "0xd65f7f4f7b5da589", "0xf453369353c73bb8", "0x28e13e24ae8d9f89", "0xd7a3594113498879", "0x8f1f8db45dd80ee6", "0x847d40b7357ca8eb", + "0xa199177bc3f7f7a3", "0x26e92f6b2077b4d4", "0x24f9f1863917dcbc", "0x1a030d008b777b08", "0xebcc0cc9db7c412e", "0xebb9e3bfa513b0c0", "0x5acf6325ac29d53b", "0xc36c4c199faf1234", + "0xacff161df7f202a1", "0x2805c39d5bbfb402", "0xc3b49f0eda801af6", "0x669fa3adaf9cecfe", "0x9d2b9f502941f5a6", "0x18f6d5ad37784f60", "0x4cc22b6763f00357", "0x9a600deb62c80c0a", + "0x9ee7ff942eb3d51f", "0x465c74e3f9c48c0e", "0xa3e54e42f498cfe7", "0x3e2ed6c098a6fd94", "0x3a3116c0b3eda0b6", "0x39b64b349ca5f65e", "0x4529d689581f15e5", "0x4a000068b04c79c2" + ]} + ], + "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" +} diff --git a/proto-cuda/packs-ca3-shadow/sh256x27/kernel.cl b/proto-cuda/packs-ca3-shadow/sh256x27/kernel.cl new file mode 100644 index 000000000..72f7ca4d0 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x27/kernel.cl @@ -0,0 +1,538 @@ +// 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 ^ 0x67a9a7beu; x += 0x9e3779b9u; x = splitmix32(x); r0 = x ^ 0x1a155b25u; } // SEEDW[0], 0x9e3779b9u * 1u, SEEDW[1] + { uint x = nonce ^ 0x1a155b25u; x += 0x3c6ef372u; x = splitmix32(x); r1 = x ^ 0xfddfb732u; } // SEEDW[1], 0x9e3779b9u * 2u, SEEDW[2] + { uint x = nonce ^ 0xfddfb732u; x += 0xdaa66d2bu; x = splitmix32(x); r2 = x ^ 0x4b5af2e8u; } // SEEDW[2], 0x9e3779b9u * 3u, SEEDW[3] + { uint x = nonce ^ 0x4b5af2e8u; x += 0x78dde6e4u; x = splitmix32(x); r3 = x ^ 0xc55caf33u; } // SEEDW[3], 0x9e3779b9u * 4u, SEEDW[4] + { uint x = nonce ^ 0xc55caf33u; x += 0x1715609du; x = splitmix32(x); r4 = x ^ 0xa27c13b7u; } // SEEDW[4], 0x9e3779b9u * 5u, SEEDW[5] + { uint x = nonce ^ 0xa27c13b7u; x += 0xb54cda56u; x = splitmix32(x); r5 = x ^ 0x06628a48u; } // SEEDW[5], 0x9e3779b9u * 6u, SEEDW[6] + { uint x = nonce ^ 0x06628a48u; x += 0x5384540fu; x = splitmix32(x); r6 = x ^ 0x03852469u; } // SEEDW[6], 0x9e3779b9u * 7u, SEEDW[7] + { uint x = nonce ^ 0x03852469u; x += 0xf1bbcdc8u; x = splitmix32(x); r7 = x ^ 0x67a9a7beu; } // SEEDW[7], 0x9e3779b9u * 8u, SEEDW[0] + + for (uint it = 0u; it < 8u; ++it) { + uint sel = r0; + r2 = r3 * r4 + r2; // 0 mad + r2 = r1 * r1 + r2; // 1 mad + r2 = r3 * r2 + r2; // 2 mad + r3 = r3 ^ r5; // 3 xor + r7 = r7 ^ ds[r2 & mask]; // 4 load + r5 = r5 ^ ds[r7 & mask]; // 5 load + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r1 = r1 ^ t_; } // 6 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r7 = r7 ^ t_; } // 7 shfl + r1 = mul_hi(r1, r5); // 8 mulhi + r6 = rotr_var(r6, r3); // 9 rotr + r3 = r3 | r4; // 10 or + r4 = r4 ^ ds[r3 & mask]; // 11 load + r0 = mul_hi(r0, r4); // 12 mulhi + r5 = r5 + r1 + ((((sel >> 30u) & 1u) != 0u) ? 0xd3177981u : 0xc7934706u); // 13 add + r0 = r0 ^ ds[r4 & mask]; // 14 load + r2 = r2 - r4; // 15 sub + r2 = r2 ^ ds[r0 & mask]; // 16 load + r7 = r7 ^ ds[r2 & mask]; // 17 load + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r7 = r7 ^ t_; } // 18 shfl + r5 = r5 * r0; // 19 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // 20 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 16u); r2 = r2 ^ t_; } // 21 shfl + r6 = mul_hi(r6, r2); // 22 mulhi + r6 = r6 ^ ds[r1 & mask]; // 23 load + r5 = r5 * r0; // 24 mul + r5 = rotl_imm(r5, 19u); // 25 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 2u); r7 = r7 ^ t_; } // 26 shfl + r0 = r0 ^ r5; // 27 xor + r0 = r0 ^ r4; // 28 xor + r3 = r3 - r0; // 29 sub + r5 = r5 * r1; // 30 mul + r7 = r7 ^ ds[r2 & mask]; // 31 load + r1 = r1 ^ ds[r0 & mask]; // 32 load + r5 = r5 ^ r6; // 33 xor + r5 = r5 ^ ds[r1 & mask]; // 34 load + r0 = mul_hi(r0, r5); // 35 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r5 = r5 ^ t_; } // 36 shfl + r7 = r7 ^ ds[r0 & mask]; // 37 load + r3 = r3 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0x230c005cu : 0x75ba2fadu); // 38 add + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 4u); r1 = r1 ^ t_; } // 39 shfl + r2 = r2 ^ r5; // 40 xor + r3 = r6 * r3 + r3; // 41 mad + r6 = r6 - r7; // 42 sub + r7 = r7 ^ r0; // 43 xor + r1 = r1 ^ ds[r7 & mask]; // 44 load + r2 = r2 * r3; // 45 mul + r1 = mul_hi(r1, r5); // 46 mulhi + r4 = r4 - r3; // 47 sub + r2 = rotr_var(r2, r6); // 48 rotr + r3 = r3 ^ ds[r5 & mask]; // 49 load + r1 = r1 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x1907970cu : 0x81b8bc2cu); // 50 add + r0 = r0 * r2; // 51 mul + r0 = r0 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x699fd448u : 0x4f92b968u); // 52 add + r1 = r1 + r0 + ((((sel >> 12u) & 1u) != 0u) ? 0x77b1520du : 0x2bb965afu); // 53 add + r7 = rotl_imm(r7, 14u); // 54 rotl + r3 = r3 + r7 + ((((sel >> 1u) & 1u) != 0u) ? 0xa54c55a0u : 0x7b0fe07au); // 55 add + r6 = r6 ^ ds[r7 & mask]; // 56 load + r1 = rotr_var(r1, r5); // 57 rotr + r5 = r5 ^ ds[r4 & mask]; // 58 load + r6 = r6 ^ ds[r2 & mask]; // 59 load + r3 = r5 * r0 + r3; // 60 mad + r5 = r5 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0xad7493e7u : 0xaf9dd72du); // 61 add + r4 = r4 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x1e07c3d9u : 0x89841d87u); // 62 add + r5 = rotl_imm(r5, 19u); // 63 rotl + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 27 passes after instruction 63, no load + for (uint sh = 0u; sh < 27u; ++sh) { + r5 = r5 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x8bc12da9u : 0x92199f99u); // s0 add + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x63079e5au : 0x8d72d3adu); // s1 add + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 2u); r6 = r6 ^ t_; } // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + ((((sel >> 31u) & 1u) != 0u) ? 0x5d4c7a60u : 0xb21b4babu); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + ((((sel >> 16u) & 1u) != 0u) ? 0xc88e2942u : 0x2fe0e98bu); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r6 = r6 ^ t_; } // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 4u); r2 = r2 ^ t_; } // s12 shfl + r1 = r1 + r5 + ((((sel >> 25u) & 1u) != 0u) ? 0xbc48c63eu : 0xbdf8f9a5u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r2 = r2 ^ t_; } // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + ((((sel >> 1u) & 1u) != 0u) ? 0x96e8f127u : 0x45c37cecu); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = mul_hi(r6, r0); // s28 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r2 = r2 ^ t_; } // s29 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r1 = r1 ^ t_; } // s30 shfl + r1 = r1 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0xb1cdb2abu : 0x37985632u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // s33 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r0 = r0 ^ t_; } // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x856e0180u : 0x804e777eu); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xe9bd0cc4u : 0x0b06c8a7u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = mul_hi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = mul_hi(r4, r3); // s44 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xcdcb63f6u : 0xee822e17u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r4 = r4 ^ t_; } // s47 shfl + r6 = mul_hi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0xd4758987u : 0x3dfad1b6u); // s56 add + r4 = r4 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x0602d6beu : 0xfca75bc2u); // s57 add + r5 = mul_hi(r5, r6); // s58 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r2 = r2 ^ t_; } // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0x8596687au : 0xd71c02ffu); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 2u); r7 = r7 ^ t_; } // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0x08ac5733u : 0x3c6fe15du); // s72 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r3 = r3 ^ t_; } // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + ((((sel >> 1u) & 1u) != 0u) ? 0xc100b495u : 0x295d5faeu); // s77 add + r3 = mul_hi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + ((((sel >> 15u) & 1u) != 0u) ? 0x5cc59530u : 0x274a9221u); // s81 add + r7 = r7 + r3 + ((((sel >> 5u) & 1u) != 0u) ? 0x141479ecu : 0xc8651f8eu); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r2 = r2 ^ t_; } // s85 shfl + r3 = r3 ^ r2; // s86 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 2u); r5 = r5 ^ t_; } // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x883c0c92u : 0x53f915c2u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + ((((sel >> 31u) & 1u) != 0u) ? 0x3cc5bd20u : 0xe2be00a5u); // s91 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 1u); r7 = r7 ^ t_; } // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + ((((sel >> 17u) & 1u) != 0u) ? 0xbfd646cbu : 0x423fd9c9u); // s101 add + r7 = r7 + r6 + ((((sel >> 11u) & 1u) != 0u) ? 0x19b74a43u : 0x8d3c011du); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + ((((sel >> 15u) & 1u) != 0u) ? 0x7dcb7e18u : 0x8ce14721u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = mul_hi(r2, r0); // s109 mulhi + r1 = mul_hi(r1, r0); // s110 mulhi + r0 = r0 + r2 + ((((sel >> 28u) & 1u) != 0u) ? 0x3c179ad8u : 0x2d9fc6b9u); // s111 add + r2 = mul_hi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + ((((sel >> 22u) & 1u) != 0u) ? 0x47359729u : 0x502138e2u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = mul_hi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 2u); r4 = r4 ^ t_; } // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r7 = r7 ^ t_; } // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x6c57e4e7u : 0x33dff776u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + ((((sel >> 30u) & 1u) != 0u) ? 0xe8212c0cu : 0x5db25b34u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = mul_hi(r0, r5); // s138 mulhi + r2 = r2 + r7 + ((((sel >> 10u) & 1u) != 0u) ? 0xd44ff710u : 0x218d4090u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r3 = r3 ^ t_; } // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + ((((sel >> 29u) & 1u) != 0u) ? 0xb98942fau : 0xf4b1a8deu); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + ((((sel >> 17u) & 1u) != 0u) ? 0x0d48ba42u : 0x2bef10f2u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + ((((sel >> 30u) & 1u) != 0u) ? 0xc98dea9cu : 0xdc5cc080u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0x6c752dcbu : 0x18197438u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + ((((sel >> 3u) & 1u) != 0u) ? 0x8e481727u : 0xf1c46574u); // s163 add + r0 = mul_hi(r0, r4); // s164 mulhi + r2 = r2 + r6 + ((((sel >> 20u) & 1u) != 0u) ? 0x550ab406u : 0xac578137u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + ((((sel >> 14u) & 1u) != 0u) ? 0xaebb5966u : 0xa33e6706u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 8u); r7 = r7 ^ t_; } // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x5bb7550fu : 0xd94d55acu); // s184 add + r3 = r3 | r5; // s185 or + r6 = mul_hi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r7 = r7 ^ t_; } // s188 shfl + r6 = r6 + r5 + ((((sel >> 6u) & 1u) != 0u) ? 0x2a354e2du : 0x89e747feu); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = mul_hi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r4 = r4 ^ t_; } // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + ((((sel >> 7u) & 1u) != 0u) ? 0x10cfdc71u : 0xea03e8e7u); // s197 add + r7 = r7 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x66e148d3u : 0xa7ee0102u); // s198 add + r5 = r5 - r2; // s199 sub + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r5 = r5 ^ t_; } // s200 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 8u); r7 = r7 ^ t_; } // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0x8558b619u : 0x8379a4deu); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = mul_hi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 4u); r2 = r2 ^ t_; } // s209 shfl + r7 = r7 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0xf4049c4cu : 0xaa8cb14eu); // s210 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 16u); r7 = r7 ^ t_; } // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 16u); r3 = r3 ^ t_; } // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = mul_hi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r5 = r5 ^ t_; } // s222 shfl + r5 = mul_hi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0x2a7fecb2u : 0x1d176220u); // s230 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r1 = r1 ^ t_; } // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + ((((sel >> 25u) & 1u) != 0u) ? 0xadce39f3u : 0x17dafb4du); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + ((((sel >> 29u) & 1u) != 0u) ? 0x0e7033b6u : 0xf2f77d26u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + ((((sel >> 31u) & 1u) != 0u) ? 0x7b2ff6b7u : 0xfed2da4eu); // s247 add + r0 = r0 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0xb5fad7b1u : 0x03b2891cu); // s248 add + r5 = mul_hi(r5, r4); // s249 mulhi + r5 = r5 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0xa7e71c2fu : 0x042cd6e3u); // s250 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 1u); r6 = r6 ^ t_; } // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0xb83d78deu : 0x784a302bu); // s254 add + r2 = r2 - r4; // s255 sub + } + } + uint lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((ulong)hi << 32) | (ulong)lo; +} + +#if IGNEUM_EXCHANGE != 0 +// Reports the sub-group size this device uses for a work-group of IGNEUM_GROUP items. host.c runs it only when the +// per-kernel query (clGetKernelSubGroupInfoKHR on igneum_hash) is unavailable; that query is preferred because a +// compiler may pick a different wave width per kernel (RDNA: wave32 or wave64). See WAVEFRONT.md. +IGNEUM_KERNEL_HASH void igneum_probe_subgroup(__global uint* out) { + if (get_local_id(0) == 0u) { out[0] = get_sub_group_size(); out[1] = get_num_sub_groups(); } +} +#endif diff --git a/proto-cuda/packs-ca3-shadow/sh256x27/kernel.cu b/proto-cuda/packs-ca3-shadow/sh256x27/kernel.cu new file mode 100644 index 000000000..62d29f6ff --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x27/kernel.cu @@ -0,0 +1,423 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Bit-exact twin of the Metal kernel for the same seed (see proto-cuda/CHECKLIST.md and program.metal). +// Compiled ahead of time by nvcc together with proto-cuda/host.cu. No NVRTC. +#include +#include +#include "program.h" +#include "memhard.h" + +__device__ __forceinline__ uint32_t splitmix32(uint32_t x) { + x ^= x >> 16; x *= 0x7feb352du; + x ^= x >> 15; x *= 0x846ca68bu; + x ^= x >> 16; + return x; +} +// n is a literal in 1..31 at every call site, so both shift amounts are in 1..31. +__device__ __forceinline__ uint32_t rotl_imm(uint32_t x, uint32_t n) { return (x << n) | (x >> (32u - n)); } +// n is masked to 0..31; the second shift amount is masked too, so n == 0 gives x. +__device__ __forceinline__ uint32_t rotr_var(uint32_t x, uint32_t n) { n &= 31u; return (x >> n) | (x << ((32u - n) & 31u)); } +__device__ __forceinline__ uint32_t ds_elem(uint32_t i, uint32_t d0, uint32_t d1) { + uint32_t x = i ^ d0; + x *= 0x9E3779B1u; x ^= x >> 15; + x += d1; + x *= 0x85EBCA77u; x ^= x >> 13; + x *= 0xC2B2AE3Du; x ^= x >> 16; + return x; +} + +// Memory-hard dataset (MEMHARD.md). One thread per cache segment; one thread per 64-byte dataset item. +// The core functions (mh_cache_segment, mh_item) are in memhard.h and are also compiled for the host. +__global__ void igneum_cache_fill(uint32_t* cache, uint32_t nSegments) { + uint32_t seg = blockIdx.x * blockDim.x + threadIdx.x; + if (seg < nSegments) mh_cache_segment(cache, seg); +} +__global__ void igneum_build(uint32_t* ds, const uint32_t* cache, uint32_t nItems) { + uint32_t t = blockIdx.x * blockDim.x + threadIdx.x; + if (t < nItems) { + uint32_t s[16]; + mh_item(cache, t, s); + uint32_t* d = ds + (size_t)t * 16u; + for (uint32_t i = 0u; i < 16u; ++i) d[i] = s[i]; + } +} + +// One hash per thread. blockDim.x is a multiple of 32; lane = threadIdx.x & 31 and every +// __shfl_xor_sync stays inside the lane's own warp, exactly like simd_shuffle_xor inside a +// 32-wide Metal SIMD group. Control flow is uniform, so the full 0xffffffff member mask is valid. +__global__ void igneum_hash(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask) { + uint32_t gid = blockIdx.x * blockDim.x + threadIdx.x; + uint32_t nonce = baseNonce + gid; + uint32_t r0, r1, r2, r3, r4, r5, r6, r7; + { uint32_t x = nonce ^ 0x67a9a7beu; x += 0x9e3779b9u; x = splitmix32(x); r0 = x ^ 0x1a155b25u; } // SEEDW[0], 0x9e3779b9u * 1u, SEEDW[1] + { uint32_t x = nonce ^ 0x1a155b25u; x += 0x3c6ef372u; x = splitmix32(x); r1 = x ^ 0xfddfb732u; } // SEEDW[1], 0x9e3779b9u * 2u, SEEDW[2] + { uint32_t x = nonce ^ 0xfddfb732u; x += 0xdaa66d2bu; x = splitmix32(x); r2 = x ^ 0x4b5af2e8u; } // SEEDW[2], 0x9e3779b9u * 3u, SEEDW[3] + { uint32_t x = nonce ^ 0x4b5af2e8u; x += 0x78dde6e4u; x = splitmix32(x); r3 = x ^ 0xc55caf33u; } // SEEDW[3], 0x9e3779b9u * 4u, SEEDW[4] + { uint32_t x = nonce ^ 0xc55caf33u; x += 0x1715609du; x = splitmix32(x); r4 = x ^ 0xa27c13b7u; } // SEEDW[4], 0x9e3779b9u * 5u, SEEDW[5] + { uint32_t x = nonce ^ 0xa27c13b7u; x += 0xb54cda56u; x = splitmix32(x); r5 = x ^ 0x06628a48u; } // SEEDW[5], 0x9e3779b9u * 6u, SEEDW[6] + { uint32_t x = nonce ^ 0x06628a48u; x += 0x5384540fu; x = splitmix32(x); r6 = x ^ 0x03852469u; } // SEEDW[6], 0x9e3779b9u * 7u, SEEDW[7] + { uint32_t x = nonce ^ 0x03852469u; x += 0xf1bbcdc8u; x = splitmix32(x); r7 = x ^ 0x67a9a7beu; } // SEEDW[7], 0x9e3779b9u * 8u, SEEDW[0] + + for (uint32_t it = 0u; it < 8u; ++it) { + uint32_t sel = r0; + r2 = r3 * r4 + r2; // 0 mad + r2 = r1 * r1 + r2; // 1 mad + r2 = r3 * r2 + r2; // 2 mad + r3 = r3 ^ r5; // 3 xor + r7 = r7 ^ ds[r2 & mask]; // 4 load + r5 = r5 ^ ds[r7 & mask]; // 5 load + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r4, 8); // 6 shfl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r3, 8); // 7 shfl + r1 = __umulhi(r1, r5); // 8 mulhi + r6 = rotr_var(r6, r3); // 9 rotr + r3 = r3 | r4; // 10 or + r4 = r4 ^ ds[r3 & mask]; // 11 load + r0 = __umulhi(r0, r4); // 12 mulhi + r5 = r5 + r1 + ((((sel >> 30u) & 1u) != 0u) ? 0xd3177981u : 0xc7934706u); // 13 add + r0 = r0 ^ ds[r4 & mask]; // 14 load + r2 = r2 - r4; // 15 sub + r2 = r2 ^ ds[r0 & mask]; // 16 load + r7 = r7 ^ ds[r2 & mask]; // 17 load + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r3, 4); // 18 shfl + r5 = r5 * r0; // 19 mul + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // 20 shfl + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 16); // 21 shfl + r6 = __umulhi(r6, r2); // 22 mulhi + r6 = r6 ^ ds[r1 & mask]; // 23 load + r5 = r5 * r0; // 24 mul + r5 = rotl_imm(r5, 19u); // 25 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r6, 2); // 26 shfl + r0 = r0 ^ r5; // 27 xor + r0 = r0 ^ r4; // 28 xor + r3 = r3 - r0; // 29 sub + r5 = r5 * r1; // 30 mul + r7 = r7 ^ ds[r2 & mask]; // 31 load + r1 = r1 ^ ds[r0 & mask]; // 32 load + r5 = r5 ^ r6; // 33 xor + r5 = r5 ^ ds[r1 & mask]; // 34 load + r0 = __umulhi(r0, r5); // 35 mulhi + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // 36 shfl + r7 = r7 ^ ds[r0 & mask]; // 37 load + r3 = r3 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0x230c005cu : 0x75ba2fadu); // 38 add + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r5, 4); // 39 shfl + r2 = r2 ^ r5; // 40 xor + r3 = r6 * r3 + r3; // 41 mad + r6 = r6 - r7; // 42 sub + r7 = r7 ^ r0; // 43 xor + r1 = r1 ^ ds[r7 & mask]; // 44 load + r2 = r2 * r3; // 45 mul + r1 = __umulhi(r1, r5); // 46 mulhi + r4 = r4 - r3; // 47 sub + r2 = rotr_var(r2, r6); // 48 rotr + r3 = r3 ^ ds[r5 & mask]; // 49 load + r1 = r1 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x1907970cu : 0x81b8bc2cu); // 50 add + r0 = r0 * r2; // 51 mul + r0 = r0 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x699fd448u : 0x4f92b968u); // 52 add + r1 = r1 + r0 + ((((sel >> 12u) & 1u) != 0u) ? 0x77b1520du : 0x2bb965afu); // 53 add + r7 = rotl_imm(r7, 14u); // 54 rotl + r3 = r3 + r7 + ((((sel >> 1u) & 1u) != 0u) ? 0xa54c55a0u : 0x7b0fe07au); // 55 add + r6 = r6 ^ ds[r7 & mask]; // 56 load + r1 = rotr_var(r1, r5); // 57 rotr + r5 = r5 ^ ds[r4 & mask]; // 58 load + r6 = r6 ^ ds[r2 & mask]; // 59 load + r3 = r5 * r0 + r3; // 60 mad + r5 = r5 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0xad7493e7u : 0xaf9dd72du); // 61 add + r4 = r4 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x1e07c3d9u : 0x89841d87u); // 62 add + r5 = rotl_imm(r5, 19u); // 63 rotl + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 27 passes after instruction 63, no load + for (uint32_t sh = 0u; sh < 27u; ++sh) { + r5 = r5 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x8bc12da9u : 0x92199f99u); // s0 add + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x63079e5au : 0x8d72d3adu); // s1 add + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r3, 2); // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + ((((sel >> 31u) & 1u) != 0u) ? 0x5d4c7a60u : 0xb21b4babu); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + ((((sel >> 16u) & 1u) != 0u) ? 0xc88e2942u : 0x2fe0e98bu); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r1, 4); // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r6, 4); // s12 shfl + r1 = r1 + r5 + ((((sel >> 25u) & 1u) != 0u) ? 0xbc48c63eu : 0xbdf8f9a5u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 8); // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + ((((sel >> 1u) & 1u) != 0u) ? 0x96e8f127u : 0x45c37cecu); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = __umulhi(r6, r0); // s28 mulhi + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // s29 shfl + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r6, 1); // s30 shfl + r1 = r1 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0xb1cdb2abu : 0x37985632u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // s33 shfl + r0 = r0 ^ __shfl_xor_sync(0xffffffffu, r3, 4); // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x856e0180u : 0x804e777eu); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xe9bd0cc4u : 0x0b06c8a7u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = __umulhi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = __umulhi(r4, r3); // s44 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xcdcb63f6u : 0xee822e17u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r3, 8); // s47 shfl + r6 = __umulhi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0xd4758987u : 0x3dfad1b6u); // s56 add + r4 = r4 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x0602d6beu : 0xfca75bc2u); // s57 add + r5 = __umulhi(r5, r6); // s58 mulhi + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0x8596687au : 0xd71c02ffu); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r5, 2); // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0x08ac5733u : 0x3c6fe15du); // s72 add + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r2, 8); // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + ((((sel >> 1u) & 1u) != 0u) ? 0xc100b495u : 0x295d5faeu); // s77 add + r3 = __umulhi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + ((((sel >> 15u) & 1u) != 0u) ? 0x5cc59530u : 0x274a9221u); // s81 add + r7 = r7 + r3 + ((((sel >> 5u) & 1u) != 0u) ? 0x141479ecu : 0xc8651f8eu); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r5, 16); // s85 shfl + r3 = r3 ^ r2; // s86 xor + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r7, 2); // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x883c0c92u : 0x53f915c2u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + ((((sel >> 31u) & 1u) != 0u) ? 0x3cc5bd20u : 0xe2be00a5u); // s91 add + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r2, 1); // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + ((((sel >> 17u) & 1u) != 0u) ? 0xbfd646cbu : 0x423fd9c9u); // s101 add + r7 = r7 + r6 + ((((sel >> 11u) & 1u) != 0u) ? 0x19b74a43u : 0x8d3c011du); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + ((((sel >> 15u) & 1u) != 0u) ? 0x7dcb7e18u : 0x8ce14721u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = __umulhi(r2, r0); // s109 mulhi + r1 = __umulhi(r1, r0); // s110 mulhi + r0 = r0 + r2 + ((((sel >> 28u) & 1u) != 0u) ? 0x3c179ad8u : 0x2d9fc6b9u); // s111 add + r2 = __umulhi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + ((((sel >> 22u) & 1u) != 0u) ? 0x47359729u : 0x502138e2u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = __umulhi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r2, 2); // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x6c57e4e7u : 0x33dff776u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + ((((sel >> 30u) & 1u) != 0u) ? 0xe8212c0cu : 0x5db25b34u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = __umulhi(r0, r5); // s138 mulhi + r2 = r2 + r7 + ((((sel >> 10u) & 1u) != 0u) ? 0xd44ff710u : 0x218d4090u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r6, 1); // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + ((((sel >> 29u) & 1u) != 0u) ? 0xb98942fau : 0xf4b1a8deu); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + ((((sel >> 17u) & 1u) != 0u) ? 0x0d48ba42u : 0x2bef10f2u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + ((((sel >> 30u) & 1u) != 0u) ? 0xc98dea9cu : 0xdc5cc080u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0x6c752dcbu : 0x18197438u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + ((((sel >> 3u) & 1u) != 0u) ? 0x8e481727u : 0xf1c46574u); // s163 add + r0 = __umulhi(r0, r4); // s164 mulhi + r2 = r2 + r6 + ((((sel >> 20u) & 1u) != 0u) ? 0x550ab406u : 0xac578137u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + ((((sel >> 14u) & 1u) != 0u) ? 0xaebb5966u : 0xa33e6706u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r0, 8); // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x5bb7550fu : 0xd94d55acu); // s184 add + r3 = r3 | r5; // s185 or + r6 = __umulhi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s188 shfl + r6 = r6 + r5 + ((((sel >> 6u) & 1u) != 0u) ? 0x2a354e2du : 0x89e747feu); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = __umulhi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r5, 16); // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + ((((sel >> 7u) & 1u) != 0u) ? 0x10cfdc71u : 0xea03e8e7u); // s197 add + r7 = r7 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x66e148d3u : 0xa7ee0102u); // s198 add + r5 = r5 - r2; // s199 sub + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s200 shfl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 8); // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0x8558b619u : 0x8379a4deu); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = __umulhi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r0, 4); // s209 shfl + r7 = r7 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0xf4049c4cu : 0xaa8cb14eu); // s210 add + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 16); // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r2, 16); // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = __umulhi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r2, 8); // s222 shfl + r5 = __umulhi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0x2a7fecb2u : 0x1d176220u); // s230 add + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + ((((sel >> 25u) & 1u) != 0u) ? 0xadce39f3u : 0x17dafb4du); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + ((((sel >> 29u) & 1u) != 0u) ? 0x0e7033b6u : 0xf2f77d26u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + ((((sel >> 31u) & 1u) != 0u) ? 0x7b2ff6b7u : 0xfed2da4eu); // s247 add + r0 = r0 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0xb5fad7b1u : 0x03b2891cu); // s248 add + r5 = __umulhi(r5, r4); // s249 mulhi + r5 = r5 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0xa7e71c2fu : 0x042cd6e3u); // s250 add + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r1, 1); // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0xb83d78deu : 0x784a302bu); // s254 add + r2 = r2 - r4; // s255 sub + } + } + uint32_t lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint32_t hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((uint64_t)hi << 32) | (uint64_t)lo; +} + +// Host-side launch wrappers. Declared in program.h, called from host.cu. +cudaError_t igneum_launch_cache_fill(uint32_t* cache, uint32_t nSegments) { + if (nSegments == 0u) return cudaErrorInvalidValue; + uint32_t block = 256u; + uint32_t grid = (nSegments + block - 1u) / block; + igneum_cache_fill<<>>(cache, nSegments); + return cudaGetLastError(); +} + +cudaError_t igneum_launch_build(uint32_t* ds, const uint32_t* cache, uint32_t nItems) { + if (nItems == 0u) return cudaErrorInvalidValue; + uint32_t block = 256u; + uint32_t grid = (nItems + block - 1u) / block; + igneum_build<<>>(ds, cache, nItems); + return cudaGetLastError(); +} + +cudaError_t igneum_launch_hash(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, + uint32_t nonces, uint32_t blockWarps) { + if (blockWarps == 0u || blockWarps > 32u) return cudaErrorInvalidValue; + uint32_t block = 32u * blockWarps; + if (nonces == 0u || (nonces % block) != 0u) return cudaErrorInvalidValue; + igneum_hash<<>>(ds, out, baseNonce, mask); + return cudaGetLastError(); +} + +cudaError_t igneum_hash_info(int* numRegs, int* blocksPerSM, uint32_t blockWarps) { + cudaFuncAttributes attr; + cudaError_t e = cudaFuncGetAttributes(&attr, igneum_hash); + if (e != cudaSuccess) return e; + *numRegs = attr.numRegs; + return cudaOccupancyMaxActiveBlocksPerMultiprocessor(blocksPerSM, igneum_hash, (int)(32u * blockWarps), 0); +} diff --git a/proto-cuda/packs-ca3-shadow/sh256x27/kernel_bound.cl b/proto-cuda/packs-ca3-shadow/sh256x27/kernel_bound.cl new file mode 100644 index 000000000..02546cd07 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x27/kernel_bound.cl @@ -0,0 +1,891 @@ +// 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 ^ 0x67a9a7beu; x += 0x9e3779b9u; x = splitmix32(x); r0 = x ^ 0x1a155b25u; } // SEEDW[0], 0x9e3779b9u * 1u, SEEDW[1] + { uint x = nonce ^ 0x1a155b25u; x += 0x3c6ef372u; x = splitmix32(x); r1 = x ^ 0xfddfb732u; } // SEEDW[1], 0x9e3779b9u * 2u, SEEDW[2] + { uint x = nonce ^ 0xfddfb732u; x += 0xdaa66d2bu; x = splitmix32(x); r2 = x ^ 0x4b5af2e8u; } // SEEDW[2], 0x9e3779b9u * 3u, SEEDW[3] + { uint x = nonce ^ 0x4b5af2e8u; x += 0x78dde6e4u; x = splitmix32(x); r3 = x ^ 0xc55caf33u; } // SEEDW[3], 0x9e3779b9u * 4u, SEEDW[4] + { uint x = nonce ^ 0xc55caf33u; x += 0x1715609du; x = splitmix32(x); r4 = x ^ 0xa27c13b7u; } // SEEDW[4], 0x9e3779b9u * 5u, SEEDW[5] + { uint x = nonce ^ 0xa27c13b7u; x += 0xb54cda56u; x = splitmix32(x); r5 = x ^ 0x06628a48u; } // SEEDW[5], 0x9e3779b9u * 6u, SEEDW[6] + { uint x = nonce ^ 0x06628a48u; x += 0x5384540fu; x = splitmix32(x); r6 = x ^ 0x03852469u; } // SEEDW[6], 0x9e3779b9u * 7u, SEEDW[7] + { uint x = nonce ^ 0x03852469u; x += 0xf1bbcdc8u; x = splitmix32(x); r7 = x ^ 0x67a9a7beu; } // SEEDW[7], 0x9e3779b9u * 8u, SEEDW[0] + + for (uint it = 0u; it < 8u; ++it) { + uint sel = r0; + r2 = r3 * r4 + r2; // 0 mad + r2 = r1 * r1 + r2; // 1 mad + r2 = r3 * r2 + r2; // 2 mad + r3 = r3 ^ r5; // 3 xor + r7 = r7 ^ ds[r2 & mask]; // 4 load + r5 = r5 ^ ds[r7 & mask]; // 5 load + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r1 = r1 ^ t_; } // 6 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r7 = r7 ^ t_; } // 7 shfl + r1 = mul_hi(r1, r5); // 8 mulhi + r6 = rotr_var(r6, r3); // 9 rotr + r3 = r3 | r4; // 10 or + r4 = r4 ^ ds[r3 & mask]; // 11 load + r0 = mul_hi(r0, r4); // 12 mulhi + r5 = r5 + r1 + ((((sel >> 30u) & 1u) != 0u) ? 0xd3177981u : 0xc7934706u); // 13 add + r0 = r0 ^ ds[r4 & mask]; // 14 load + r2 = r2 - r4; // 15 sub + r2 = r2 ^ ds[r0 & mask]; // 16 load + r7 = r7 ^ ds[r2 & mask]; // 17 load + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r7 = r7 ^ t_; } // 18 shfl + r5 = r5 * r0; // 19 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // 20 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 16u); r2 = r2 ^ t_; } // 21 shfl + r6 = mul_hi(r6, r2); // 22 mulhi + r6 = r6 ^ ds[r1 & mask]; // 23 load + r5 = r5 * r0; // 24 mul + r5 = rotl_imm(r5, 19u); // 25 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 2u); r7 = r7 ^ t_; } // 26 shfl + r0 = r0 ^ r5; // 27 xor + r0 = r0 ^ r4; // 28 xor + r3 = r3 - r0; // 29 sub + r5 = r5 * r1; // 30 mul + r7 = r7 ^ ds[r2 & mask]; // 31 load + r1 = r1 ^ ds[r0 & mask]; // 32 load + r5 = r5 ^ r6; // 33 xor + r5 = r5 ^ ds[r1 & mask]; // 34 load + r0 = mul_hi(r0, r5); // 35 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r5 = r5 ^ t_; } // 36 shfl + r7 = r7 ^ ds[r0 & mask]; // 37 load + r3 = r3 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0x230c005cu : 0x75ba2fadu); // 38 add + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 4u); r1 = r1 ^ t_; } // 39 shfl + r2 = r2 ^ r5; // 40 xor + r3 = r6 * r3 + r3; // 41 mad + r6 = r6 - r7; // 42 sub + r7 = r7 ^ r0; // 43 xor + r1 = r1 ^ ds[r7 & mask]; // 44 load + r2 = r2 * r3; // 45 mul + r1 = mul_hi(r1, r5); // 46 mulhi + r4 = r4 - r3; // 47 sub + r2 = rotr_var(r2, r6); // 48 rotr + r3 = r3 ^ ds[r5 & mask]; // 49 load + r1 = r1 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x1907970cu : 0x81b8bc2cu); // 50 add + r0 = r0 * r2; // 51 mul + r0 = r0 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x699fd448u : 0x4f92b968u); // 52 add + r1 = r1 + r0 + ((((sel >> 12u) & 1u) != 0u) ? 0x77b1520du : 0x2bb965afu); // 53 add + r7 = rotl_imm(r7, 14u); // 54 rotl + r3 = r3 + r7 + ((((sel >> 1u) & 1u) != 0u) ? 0xa54c55a0u : 0x7b0fe07au); // 55 add + r6 = r6 ^ ds[r7 & mask]; // 56 load + r1 = rotr_var(r1, r5); // 57 rotr + r5 = r5 ^ ds[r4 & mask]; // 58 load + r6 = r6 ^ ds[r2 & mask]; // 59 load + r3 = r5 * r0 + r3; // 60 mad + r5 = r5 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0xad7493e7u : 0xaf9dd72du); // 61 add + r4 = r4 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x1e07c3d9u : 0x89841d87u); // 62 add + r5 = rotl_imm(r5, 19u); // 63 rotl + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 27 passes after instruction 63, no load + for (uint sh = 0u; sh < 27u; ++sh) { + r5 = r5 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x8bc12da9u : 0x92199f99u); // s0 add + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x63079e5au : 0x8d72d3adu); // s1 add + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 2u); r6 = r6 ^ t_; } // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + ((((sel >> 31u) & 1u) != 0u) ? 0x5d4c7a60u : 0xb21b4babu); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + ((((sel >> 16u) & 1u) != 0u) ? 0xc88e2942u : 0x2fe0e98bu); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r6 = r6 ^ t_; } // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 4u); r2 = r2 ^ t_; } // s12 shfl + r1 = r1 + r5 + ((((sel >> 25u) & 1u) != 0u) ? 0xbc48c63eu : 0xbdf8f9a5u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r2 = r2 ^ t_; } // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + ((((sel >> 1u) & 1u) != 0u) ? 0x96e8f127u : 0x45c37cecu); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = mul_hi(r6, r0); // s28 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r2 = r2 ^ t_; } // s29 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r1 = r1 ^ t_; } // s30 shfl + r1 = r1 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0xb1cdb2abu : 0x37985632u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // s33 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r0 = r0 ^ t_; } // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x856e0180u : 0x804e777eu); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xe9bd0cc4u : 0x0b06c8a7u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = mul_hi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = mul_hi(r4, r3); // s44 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xcdcb63f6u : 0xee822e17u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r4 = r4 ^ t_; } // s47 shfl + r6 = mul_hi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0xd4758987u : 0x3dfad1b6u); // s56 add + r4 = r4 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x0602d6beu : 0xfca75bc2u); // s57 add + r5 = mul_hi(r5, r6); // s58 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r2 = r2 ^ t_; } // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0x8596687au : 0xd71c02ffu); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 2u); r7 = r7 ^ t_; } // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0x08ac5733u : 0x3c6fe15du); // s72 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r3 = r3 ^ t_; } // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + ((((sel >> 1u) & 1u) != 0u) ? 0xc100b495u : 0x295d5faeu); // s77 add + r3 = mul_hi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + ((((sel >> 15u) & 1u) != 0u) ? 0x5cc59530u : 0x274a9221u); // s81 add + r7 = r7 + r3 + ((((sel >> 5u) & 1u) != 0u) ? 0x141479ecu : 0xc8651f8eu); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r2 = r2 ^ t_; } // s85 shfl + r3 = r3 ^ r2; // s86 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 2u); r5 = r5 ^ t_; } // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x883c0c92u : 0x53f915c2u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + ((((sel >> 31u) & 1u) != 0u) ? 0x3cc5bd20u : 0xe2be00a5u); // s91 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 1u); r7 = r7 ^ t_; } // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + ((((sel >> 17u) & 1u) != 0u) ? 0xbfd646cbu : 0x423fd9c9u); // s101 add + r7 = r7 + r6 + ((((sel >> 11u) & 1u) != 0u) ? 0x19b74a43u : 0x8d3c011du); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + ((((sel >> 15u) & 1u) != 0u) ? 0x7dcb7e18u : 0x8ce14721u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = mul_hi(r2, r0); // s109 mulhi + r1 = mul_hi(r1, r0); // s110 mulhi + r0 = r0 + r2 + ((((sel >> 28u) & 1u) != 0u) ? 0x3c179ad8u : 0x2d9fc6b9u); // s111 add + r2 = mul_hi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + ((((sel >> 22u) & 1u) != 0u) ? 0x47359729u : 0x502138e2u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = mul_hi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 2u); r4 = r4 ^ t_; } // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r7 = r7 ^ t_; } // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x6c57e4e7u : 0x33dff776u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + ((((sel >> 30u) & 1u) != 0u) ? 0xe8212c0cu : 0x5db25b34u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = mul_hi(r0, r5); // s138 mulhi + r2 = r2 + r7 + ((((sel >> 10u) & 1u) != 0u) ? 0xd44ff710u : 0x218d4090u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r3 = r3 ^ t_; } // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + ((((sel >> 29u) & 1u) != 0u) ? 0xb98942fau : 0xf4b1a8deu); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + ((((sel >> 17u) & 1u) != 0u) ? 0x0d48ba42u : 0x2bef10f2u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + ((((sel >> 30u) & 1u) != 0u) ? 0xc98dea9cu : 0xdc5cc080u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0x6c752dcbu : 0x18197438u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + ((((sel >> 3u) & 1u) != 0u) ? 0x8e481727u : 0xf1c46574u); // s163 add + r0 = mul_hi(r0, r4); // s164 mulhi + r2 = r2 + r6 + ((((sel >> 20u) & 1u) != 0u) ? 0x550ab406u : 0xac578137u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + ((((sel >> 14u) & 1u) != 0u) ? 0xaebb5966u : 0xa33e6706u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 8u); r7 = r7 ^ t_; } // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x5bb7550fu : 0xd94d55acu); // s184 add + r3 = r3 | r5; // s185 or + r6 = mul_hi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r7 = r7 ^ t_; } // s188 shfl + r6 = r6 + r5 + ((((sel >> 6u) & 1u) != 0u) ? 0x2a354e2du : 0x89e747feu); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = mul_hi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r4 = r4 ^ t_; } // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + ((((sel >> 7u) & 1u) != 0u) ? 0x10cfdc71u : 0xea03e8e7u); // s197 add + r7 = r7 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x66e148d3u : 0xa7ee0102u); // s198 add + r5 = r5 - r2; // s199 sub + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r5 = r5 ^ t_; } // s200 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 8u); r7 = r7 ^ t_; } // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0x8558b619u : 0x8379a4deu); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = mul_hi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 4u); r2 = r2 ^ t_; } // s209 shfl + r7 = r7 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0xf4049c4cu : 0xaa8cb14eu); // s210 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 16u); r7 = r7 ^ t_; } // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 16u); r3 = r3 ^ t_; } // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = mul_hi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r5 = r5 ^ t_; } // s222 shfl + r5 = mul_hi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0x2a7fecb2u : 0x1d176220u); // s230 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r1 = r1 ^ t_; } // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + ((((sel >> 25u) & 1u) != 0u) ? 0xadce39f3u : 0x17dafb4du); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + ((((sel >> 29u) & 1u) != 0u) ? 0x0e7033b6u : 0xf2f77d26u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + ((((sel >> 31u) & 1u) != 0u) ? 0x7b2ff6b7u : 0xfed2da4eu); // s247 add + r0 = r0 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0xb5fad7b1u : 0x03b2891cu); // s248 add + r5 = mul_hi(r5, r4); // s249 mulhi + r5 = r5 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0xa7e71c2fu : 0x042cd6e3u); // s250 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 1u); r6 = r6 ^ t_; } // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0xb83d78deu : 0x784a302bu); // s254 add + r2 = r2 - r4; // s255 sub + } + } + 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 = r3 * r4 + r2; // 0 mad + r2 = r1 * r1 + r2; // 1 mad + r2 = r3 * r2 + r2; // 2 mad + r3 = r3 ^ r5; // 3 xor + r7 = r7 ^ ds[r2 & mask]; // 4 load + r5 = r5 ^ ds[r7 & mask]; // 5 load + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r1 = r1 ^ t_; } // 6 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r7 = r7 ^ t_; } // 7 shfl + r1 = mul_hi(r1, r5); // 8 mulhi + r6 = rotr_var(r6, r3); // 9 rotr + r3 = r3 | r4; // 10 or + r4 = r4 ^ ds[r3 & mask]; // 11 load + r0 = mul_hi(r0, r4); // 12 mulhi + r5 = r5 + r1 + ((((sel >> 30u) & 1u) != 0u) ? 0xd3177981u : 0xc7934706u); // 13 add + r0 = r0 ^ ds[r4 & mask]; // 14 load + r2 = r2 - r4; // 15 sub + r2 = r2 ^ ds[r0 & mask]; // 16 load + r7 = r7 ^ ds[r2 & mask]; // 17 load + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r7 = r7 ^ t_; } // 18 shfl + r5 = r5 * r0; // 19 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // 20 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 16u); r2 = r2 ^ t_; } // 21 shfl + r6 = mul_hi(r6, r2); // 22 mulhi + r6 = r6 ^ ds[r1 & mask]; // 23 load + r5 = r5 * r0; // 24 mul + r5 = rotl_imm(r5, 19u); // 25 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 2u); r7 = r7 ^ t_; } // 26 shfl + r0 = r0 ^ r5; // 27 xor + r0 = r0 ^ r4; // 28 xor + r3 = r3 - r0; // 29 sub + r5 = r5 * r1; // 30 mul + r7 = r7 ^ ds[r2 & mask]; // 31 load + r1 = r1 ^ ds[r0 & mask]; // 32 load + r5 = r5 ^ r6; // 33 xor + r5 = r5 ^ ds[r1 & mask]; // 34 load + r0 = mul_hi(r0, r5); // 35 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r5 = r5 ^ t_; } // 36 shfl + r7 = r7 ^ ds[r0 & mask]; // 37 load + r3 = r3 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0x230c005cu : 0x75ba2fadu); // 38 add + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 4u); r1 = r1 ^ t_; } // 39 shfl + r2 = r2 ^ r5; // 40 xor + r3 = r6 * r3 + r3; // 41 mad + r6 = r6 - r7; // 42 sub + r7 = r7 ^ r0; // 43 xor + r1 = r1 ^ ds[r7 & mask]; // 44 load + r2 = r2 * r3; // 45 mul + r1 = mul_hi(r1, r5); // 46 mulhi + r4 = r4 - r3; // 47 sub + r2 = rotr_var(r2, r6); // 48 rotr + r3 = r3 ^ ds[r5 & mask]; // 49 load + r1 = r1 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x1907970cu : 0x81b8bc2cu); // 50 add + r0 = r0 * r2; // 51 mul + r0 = r0 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x699fd448u : 0x4f92b968u); // 52 add + r1 = r1 + r0 + ((((sel >> 12u) & 1u) != 0u) ? 0x77b1520du : 0x2bb965afu); // 53 add + r7 = rotl_imm(r7, 14u); // 54 rotl + r3 = r3 + r7 + ((((sel >> 1u) & 1u) != 0u) ? 0xa54c55a0u : 0x7b0fe07au); // 55 add + r6 = r6 ^ ds[r7 & mask]; // 56 load + r1 = rotr_var(r1, r5); // 57 rotr + r5 = r5 ^ ds[r4 & mask]; // 58 load + r6 = r6 ^ ds[r2 & mask]; // 59 load + r3 = r5 * r0 + r3; // 60 mad + r5 = r5 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0xad7493e7u : 0xaf9dd72du); // 61 add + r4 = r4 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x1e07c3d9u : 0x89841d87u); // 62 add + r5 = rotl_imm(r5, 19u); // 63 rotl + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 27 passes after instruction 63, no load + for (uint sh = 0u; sh < 27u; ++sh) { + r5 = r5 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x8bc12da9u : 0x92199f99u); // s0 add + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x63079e5au : 0x8d72d3adu); // s1 add + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 2u); r6 = r6 ^ t_; } // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + ((((sel >> 31u) & 1u) != 0u) ? 0x5d4c7a60u : 0xb21b4babu); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + ((((sel >> 16u) & 1u) != 0u) ? 0xc88e2942u : 0x2fe0e98bu); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r6 = r6 ^ t_; } // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 4u); r2 = r2 ^ t_; } // s12 shfl + r1 = r1 + r5 + ((((sel >> 25u) & 1u) != 0u) ? 0xbc48c63eu : 0xbdf8f9a5u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r2 = r2 ^ t_; } // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + ((((sel >> 1u) & 1u) != 0u) ? 0x96e8f127u : 0x45c37cecu); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = mul_hi(r6, r0); // s28 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r2 = r2 ^ t_; } // s29 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r1 = r1 ^ t_; } // s30 shfl + r1 = r1 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0xb1cdb2abu : 0x37985632u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // s33 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r0 = r0 ^ t_; } // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x856e0180u : 0x804e777eu); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xe9bd0cc4u : 0x0b06c8a7u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = mul_hi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = mul_hi(r4, r3); // s44 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xcdcb63f6u : 0xee822e17u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r4 = r4 ^ t_; } // s47 shfl + r6 = mul_hi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0xd4758987u : 0x3dfad1b6u); // s56 add + r4 = r4 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x0602d6beu : 0xfca75bc2u); // s57 add + r5 = mul_hi(r5, r6); // s58 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r2 = r2 ^ t_; } // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0x8596687au : 0xd71c02ffu); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 2u); r7 = r7 ^ t_; } // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0x08ac5733u : 0x3c6fe15du); // s72 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r3 = r3 ^ t_; } // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + ((((sel >> 1u) & 1u) != 0u) ? 0xc100b495u : 0x295d5faeu); // s77 add + r3 = mul_hi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + ((((sel >> 15u) & 1u) != 0u) ? 0x5cc59530u : 0x274a9221u); // s81 add + r7 = r7 + r3 + ((((sel >> 5u) & 1u) != 0u) ? 0x141479ecu : 0xc8651f8eu); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r2 = r2 ^ t_; } // s85 shfl + r3 = r3 ^ r2; // s86 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 2u); r5 = r5 ^ t_; } // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x883c0c92u : 0x53f915c2u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + ((((sel >> 31u) & 1u) != 0u) ? 0x3cc5bd20u : 0xe2be00a5u); // s91 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 1u); r7 = r7 ^ t_; } // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + ((((sel >> 17u) & 1u) != 0u) ? 0xbfd646cbu : 0x423fd9c9u); // s101 add + r7 = r7 + r6 + ((((sel >> 11u) & 1u) != 0u) ? 0x19b74a43u : 0x8d3c011du); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + ((((sel >> 15u) & 1u) != 0u) ? 0x7dcb7e18u : 0x8ce14721u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = mul_hi(r2, r0); // s109 mulhi + r1 = mul_hi(r1, r0); // s110 mulhi + r0 = r0 + r2 + ((((sel >> 28u) & 1u) != 0u) ? 0x3c179ad8u : 0x2d9fc6b9u); // s111 add + r2 = mul_hi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + ((((sel >> 22u) & 1u) != 0u) ? 0x47359729u : 0x502138e2u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = mul_hi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 2u); r4 = r4 ^ t_; } // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r7 = r7 ^ t_; } // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x6c57e4e7u : 0x33dff776u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + ((((sel >> 30u) & 1u) != 0u) ? 0xe8212c0cu : 0x5db25b34u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = mul_hi(r0, r5); // s138 mulhi + r2 = r2 + r7 + ((((sel >> 10u) & 1u) != 0u) ? 0xd44ff710u : 0x218d4090u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r3 = r3 ^ t_; } // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + ((((sel >> 29u) & 1u) != 0u) ? 0xb98942fau : 0xf4b1a8deu); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + ((((sel >> 17u) & 1u) != 0u) ? 0x0d48ba42u : 0x2bef10f2u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + ((((sel >> 30u) & 1u) != 0u) ? 0xc98dea9cu : 0xdc5cc080u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0x6c752dcbu : 0x18197438u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + ((((sel >> 3u) & 1u) != 0u) ? 0x8e481727u : 0xf1c46574u); // s163 add + r0 = mul_hi(r0, r4); // s164 mulhi + r2 = r2 + r6 + ((((sel >> 20u) & 1u) != 0u) ? 0x550ab406u : 0xac578137u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + ((((sel >> 14u) & 1u) != 0u) ? 0xaebb5966u : 0xa33e6706u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 8u); r7 = r7 ^ t_; } // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x5bb7550fu : 0xd94d55acu); // s184 add + r3 = r3 | r5; // s185 or + r6 = mul_hi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r7 = r7 ^ t_; } // s188 shfl + r6 = r6 + r5 + ((((sel >> 6u) & 1u) != 0u) ? 0x2a354e2du : 0x89e747feu); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = mul_hi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r4 = r4 ^ t_; } // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + ((((sel >> 7u) & 1u) != 0u) ? 0x10cfdc71u : 0xea03e8e7u); // s197 add + r7 = r7 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x66e148d3u : 0xa7ee0102u); // s198 add + r5 = r5 - r2; // s199 sub + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r5 = r5 ^ t_; } // s200 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 8u); r7 = r7 ^ t_; } // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0x8558b619u : 0x8379a4deu); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = mul_hi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 4u); r2 = r2 ^ t_; } // s209 shfl + r7 = r7 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0xf4049c4cu : 0xaa8cb14eu); // s210 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 16u); r7 = r7 ^ t_; } // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 16u); r3 = r3 ^ t_; } // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = mul_hi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r5 = r5 ^ t_; } // s222 shfl + r5 = mul_hi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0x2a7fecb2u : 0x1d176220u); // s230 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r1 = r1 ^ t_; } // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + ((((sel >> 25u) & 1u) != 0u) ? 0xadce39f3u : 0x17dafb4du); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + ((((sel >> 29u) & 1u) != 0u) ? 0x0e7033b6u : 0xf2f77d26u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + ((((sel >> 31u) & 1u) != 0u) ? 0x7b2ff6b7u : 0xfed2da4eu); // s247 add + r0 = r0 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0xb5fad7b1u : 0x03b2891cu); // s248 add + r5 = mul_hi(r5, r4); // s249 mulhi + r5 = r5 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0xa7e71c2fu : 0x042cd6e3u); // s250 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 1u); r6 = r6 ^ t_; } // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0xb83d78deu : 0x784a302bu); // s254 add + r2 = r2 - r4; // s255 sub + } + } + uint lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((ulong)hi << 32) | (ulong)lo; +} diff --git a/proto-cuda/packs-ca3-shadow/sh256x27/kernel_bound.cu b/proto-cuda/packs-ca3-shadow/sh256x27/kernel_bound.cu new file mode 100644 index 000000000..4a823531b --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x27/kernel_bound.cu @@ -0,0 +1,382 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Header-bound twin of igneum_hash in kernel.cu: the init words come from a kernel argument, not SEEDW. +// Host declarations (also in program_bound.h if present): +// struct IgneumInitWords { uint32_t w[8]; }; +// cudaError_t igneum_launch_hash_bound(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, +// IgneumInitWords iw, uint32_t nonces, uint32_t blockWarps); +// cudaError_t igneum_hash_bound_info(int* numRegs, int* blocksPerSM, uint32_t blockWarps); +#include +#include +#include "program.h" + +struct IgneumInitWords { uint32_t w[8]; }; + +__device__ __forceinline__ uint32_t splitmix32(uint32_t x) { + x ^= x >> 16; x *= 0x7feb352du; + x ^= x >> 15; x *= 0x846ca68bu; + x ^= x >> 16; + return x; +} +__device__ __forceinline__ uint32_t rotl_imm(uint32_t x, uint32_t n) { return (x << n) | (x >> (32u - n)); } +__device__ __forceinline__ uint32_t rotr_var(uint32_t x, uint32_t n) { n &= 31u; return (x >> n) | (x << ((32u - n) & 31u)); } + +__global__ void igneum_hash_bound(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, IgneumInitWords iw) { + uint32_t gid = blockIdx.x * blockDim.x + threadIdx.x; + uint32_t nonce = baseNonce + gid; + uint32_t r0, r1, r2, r3, r4, r5, r6, r7; + { uint32_t x = nonce ^ iw.w[0]; x += 0x9e3779b9u * 1u; x = splitmix32(x); r0 = x ^ iw.w[1]; } + { uint32_t x = nonce ^ iw.w[1]; x += 0x9e3779b9u * 2u; x = splitmix32(x); r1 = x ^ iw.w[2]; } + { uint32_t x = nonce ^ iw.w[2]; x += 0x9e3779b9u * 3u; x = splitmix32(x); r2 = x ^ iw.w[3]; } + { uint32_t x = nonce ^ iw.w[3]; x += 0x9e3779b9u * 4u; x = splitmix32(x); r3 = x ^ iw.w[4]; } + { uint32_t x = nonce ^ iw.w[4]; x += 0x9e3779b9u * 5u; x = splitmix32(x); r4 = x ^ iw.w[5]; } + { uint32_t x = nonce ^ iw.w[5]; x += 0x9e3779b9u * 6u; x = splitmix32(x); r5 = x ^ iw.w[6]; } + { uint32_t x = nonce ^ iw.w[6]; x += 0x9e3779b9u * 7u; x = splitmix32(x); r6 = x ^ iw.w[7]; } + { uint32_t x = nonce ^ iw.w[7]; x += 0x9e3779b9u * 8u; x = splitmix32(x); r7 = x ^ iw.w[0]; } + + for (uint32_t it = 0u; it < 8u; ++it) { + uint32_t sel = r0; + r2 = r3 * r4 + r2; // 0 mad + r2 = r1 * r1 + r2; // 1 mad + r2 = r3 * r2 + r2; // 2 mad + r3 = r3 ^ r5; // 3 xor + r7 = r7 ^ ds[r2 & mask]; // 4 load + r5 = r5 ^ ds[r7 & mask]; // 5 load + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r4, 8); // 6 shfl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r3, 8); // 7 shfl + r1 = __umulhi(r1, r5); // 8 mulhi + r6 = rotr_var(r6, r3); // 9 rotr + r3 = r3 | r4; // 10 or + r4 = r4 ^ ds[r3 & mask]; // 11 load + r0 = __umulhi(r0, r4); // 12 mulhi + r5 = r5 + r1 + ((((sel >> 30u) & 1u) != 0u) ? 0xd3177981u : 0xc7934706u); // 13 add + r0 = r0 ^ ds[r4 & mask]; // 14 load + r2 = r2 - r4; // 15 sub + r2 = r2 ^ ds[r0 & mask]; // 16 load + r7 = r7 ^ ds[r2 & mask]; // 17 load + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r3, 4); // 18 shfl + r5 = r5 * r0; // 19 mul + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // 20 shfl + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 16); // 21 shfl + r6 = __umulhi(r6, r2); // 22 mulhi + r6 = r6 ^ ds[r1 & mask]; // 23 load + r5 = r5 * r0; // 24 mul + r5 = rotl_imm(r5, 19u); // 25 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r6, 2); // 26 shfl + r0 = r0 ^ r5; // 27 xor + r0 = r0 ^ r4; // 28 xor + r3 = r3 - r0; // 29 sub + r5 = r5 * r1; // 30 mul + r7 = r7 ^ ds[r2 & mask]; // 31 load + r1 = r1 ^ ds[r0 & mask]; // 32 load + r5 = r5 ^ r6; // 33 xor + r5 = r5 ^ ds[r1 & mask]; // 34 load + r0 = __umulhi(r0, r5); // 35 mulhi + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // 36 shfl + r7 = r7 ^ ds[r0 & mask]; // 37 load + r3 = r3 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0x230c005cu : 0x75ba2fadu); // 38 add + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r5, 4); // 39 shfl + r2 = r2 ^ r5; // 40 xor + r3 = r6 * r3 + r3; // 41 mad + r6 = r6 - r7; // 42 sub + r7 = r7 ^ r0; // 43 xor + r1 = r1 ^ ds[r7 & mask]; // 44 load + r2 = r2 * r3; // 45 mul + r1 = __umulhi(r1, r5); // 46 mulhi + r4 = r4 - r3; // 47 sub + r2 = rotr_var(r2, r6); // 48 rotr + r3 = r3 ^ ds[r5 & mask]; // 49 load + r1 = r1 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x1907970cu : 0x81b8bc2cu); // 50 add + r0 = r0 * r2; // 51 mul + r0 = r0 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x699fd448u : 0x4f92b968u); // 52 add + r1 = r1 + r0 + ((((sel >> 12u) & 1u) != 0u) ? 0x77b1520du : 0x2bb965afu); // 53 add + r7 = rotl_imm(r7, 14u); // 54 rotl + r3 = r3 + r7 + ((((sel >> 1u) & 1u) != 0u) ? 0xa54c55a0u : 0x7b0fe07au); // 55 add + r6 = r6 ^ ds[r7 & mask]; // 56 load + r1 = rotr_var(r1, r5); // 57 rotr + r5 = r5 ^ ds[r4 & mask]; // 58 load + r6 = r6 ^ ds[r2 & mask]; // 59 load + r3 = r5 * r0 + r3; // 60 mad + r5 = r5 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0xad7493e7u : 0xaf9dd72du); // 61 add + r4 = r4 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x1e07c3d9u : 0x89841d87u); // 62 add + r5 = rotl_imm(r5, 19u); // 63 rotl + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 27 passes after instruction 63, no load + for (uint32_t sh = 0u; sh < 27u; ++sh) { + r5 = r5 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x8bc12da9u : 0x92199f99u); // s0 add + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x63079e5au : 0x8d72d3adu); // s1 add + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r3, 2); // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + ((((sel >> 31u) & 1u) != 0u) ? 0x5d4c7a60u : 0xb21b4babu); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + ((((sel >> 16u) & 1u) != 0u) ? 0xc88e2942u : 0x2fe0e98bu); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r1, 4); // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r6, 4); // s12 shfl + r1 = r1 + r5 + ((((sel >> 25u) & 1u) != 0u) ? 0xbc48c63eu : 0xbdf8f9a5u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 8); // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + ((((sel >> 1u) & 1u) != 0u) ? 0x96e8f127u : 0x45c37cecu); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = __umulhi(r6, r0); // s28 mulhi + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // s29 shfl + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r6, 1); // s30 shfl + r1 = r1 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0xb1cdb2abu : 0x37985632u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // s33 shfl + r0 = r0 ^ __shfl_xor_sync(0xffffffffu, r3, 4); // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x856e0180u : 0x804e777eu); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xe9bd0cc4u : 0x0b06c8a7u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = __umulhi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = __umulhi(r4, r3); // s44 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xcdcb63f6u : 0xee822e17u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r3, 8); // s47 shfl + r6 = __umulhi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0xd4758987u : 0x3dfad1b6u); // s56 add + r4 = r4 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x0602d6beu : 0xfca75bc2u); // s57 add + r5 = __umulhi(r5, r6); // s58 mulhi + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0x8596687au : 0xd71c02ffu); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r5, 2); // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0x08ac5733u : 0x3c6fe15du); // s72 add + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r2, 8); // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + ((((sel >> 1u) & 1u) != 0u) ? 0xc100b495u : 0x295d5faeu); // s77 add + r3 = __umulhi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + ((((sel >> 15u) & 1u) != 0u) ? 0x5cc59530u : 0x274a9221u); // s81 add + r7 = r7 + r3 + ((((sel >> 5u) & 1u) != 0u) ? 0x141479ecu : 0xc8651f8eu); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r5, 16); // s85 shfl + r3 = r3 ^ r2; // s86 xor + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r7, 2); // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x883c0c92u : 0x53f915c2u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + ((((sel >> 31u) & 1u) != 0u) ? 0x3cc5bd20u : 0xe2be00a5u); // s91 add + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r2, 1); // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + ((((sel >> 17u) & 1u) != 0u) ? 0xbfd646cbu : 0x423fd9c9u); // s101 add + r7 = r7 + r6 + ((((sel >> 11u) & 1u) != 0u) ? 0x19b74a43u : 0x8d3c011du); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + ((((sel >> 15u) & 1u) != 0u) ? 0x7dcb7e18u : 0x8ce14721u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = __umulhi(r2, r0); // s109 mulhi + r1 = __umulhi(r1, r0); // s110 mulhi + r0 = r0 + r2 + ((((sel >> 28u) & 1u) != 0u) ? 0x3c179ad8u : 0x2d9fc6b9u); // s111 add + r2 = __umulhi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + ((((sel >> 22u) & 1u) != 0u) ? 0x47359729u : 0x502138e2u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = __umulhi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r2, 2); // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x6c57e4e7u : 0x33dff776u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + ((((sel >> 30u) & 1u) != 0u) ? 0xe8212c0cu : 0x5db25b34u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = __umulhi(r0, r5); // s138 mulhi + r2 = r2 + r7 + ((((sel >> 10u) & 1u) != 0u) ? 0xd44ff710u : 0x218d4090u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r6, 1); // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + ((((sel >> 29u) & 1u) != 0u) ? 0xb98942fau : 0xf4b1a8deu); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + ((((sel >> 17u) & 1u) != 0u) ? 0x0d48ba42u : 0x2bef10f2u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + ((((sel >> 30u) & 1u) != 0u) ? 0xc98dea9cu : 0xdc5cc080u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0x6c752dcbu : 0x18197438u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + ((((sel >> 3u) & 1u) != 0u) ? 0x8e481727u : 0xf1c46574u); // s163 add + r0 = __umulhi(r0, r4); // s164 mulhi + r2 = r2 + r6 + ((((sel >> 20u) & 1u) != 0u) ? 0x550ab406u : 0xac578137u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + ((((sel >> 14u) & 1u) != 0u) ? 0xaebb5966u : 0xa33e6706u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r0, 8); // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x5bb7550fu : 0xd94d55acu); // s184 add + r3 = r3 | r5; // s185 or + r6 = __umulhi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s188 shfl + r6 = r6 + r5 + ((((sel >> 6u) & 1u) != 0u) ? 0x2a354e2du : 0x89e747feu); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = __umulhi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r5, 16); // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + ((((sel >> 7u) & 1u) != 0u) ? 0x10cfdc71u : 0xea03e8e7u); // s197 add + r7 = r7 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x66e148d3u : 0xa7ee0102u); // s198 add + r5 = r5 - r2; // s199 sub + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s200 shfl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 8); // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0x8558b619u : 0x8379a4deu); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = __umulhi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r0, 4); // s209 shfl + r7 = r7 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0xf4049c4cu : 0xaa8cb14eu); // s210 add + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 16); // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r2, 16); // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = __umulhi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r2, 8); // s222 shfl + r5 = __umulhi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0x2a7fecb2u : 0x1d176220u); // s230 add + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + ((((sel >> 25u) & 1u) != 0u) ? 0xadce39f3u : 0x17dafb4du); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + ((((sel >> 29u) & 1u) != 0u) ? 0x0e7033b6u : 0xf2f77d26u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + ((((sel >> 31u) & 1u) != 0u) ? 0x7b2ff6b7u : 0xfed2da4eu); // s247 add + r0 = r0 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0xb5fad7b1u : 0x03b2891cu); // s248 add + r5 = __umulhi(r5, r4); // s249 mulhi + r5 = r5 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0xa7e71c2fu : 0x042cd6e3u); // s250 add + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r1, 1); // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0xb83d78deu : 0x784a302bu); // s254 add + r2 = r2 - r4; // s255 sub + } + } + uint32_t lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint32_t hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((uint64_t)hi << 32) | (uint64_t)lo; +} + +cudaError_t igneum_launch_hash_bound(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, + IgneumInitWords iw, uint32_t nonces, uint32_t blockWarps) { + if (blockWarps == 0u || blockWarps > 32u) return cudaErrorInvalidValue; + uint32_t block = 32u * blockWarps; + if (nonces == 0u || (nonces % block) != 0u) return cudaErrorInvalidValue; + igneum_hash_bound<<>>(ds, out, baseNonce, mask, iw); + return cudaGetLastError(); +} + +cudaError_t igneum_hash_bound_info(int* numRegs, int* blocksPerSM, uint32_t blockWarps) { + cudaFuncAttributes attr; + cudaError_t e = cudaFuncGetAttributes(&attr, igneum_hash_bound); + if (e != cudaSuccess) return e; + *numRegs = attr.numRegs; + return cudaOccupancyMaxActiveBlocksPerMultiprocessor(blocksPerSM, igneum_hash_bound, (int)(32u * blockWarps), 0); +} diff --git a/proto-cuda/packs-ca3-shadow/sh256x27/memhard.h b/proto-cuda/packs-ca3-shadow/sh256x27/memhard.h new file mode 100644 index 000000000..f7f34c732 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x27/memhard.h @@ -0,0 +1,109 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Memory-hard dataset core, the same text that the Mac's Metal kernels and CPU verifier were checked against. +// Included by kernel.cu (device), host.cu (host reference) and proto-opencl/host.c (C99 host reference). +// See proto-metal/MEMHARD.md for the construction. kernel.cl carries the same text in OpenCL C. +#pragma once +#ifdef __cplusplus +#include +#else +#include +#endif +#if defined(__CUDACC__) +#define IGNEUM_HD __host__ __device__ __forceinline__ +#elif defined(_MSC_VER) && !defined(__cplusplus) +#define IGNEUM_HD static __inline +#else +#define IGNEUM_HD static inline +#endif +// Memory-hard dataset core (MEMHARD.md). Cache: 2^26 words in 2^16 segments of 64 chained ChaCha12 lines. +// Item: 8 rounds of 8 x seed-parameterised mixer + one 64-byte cache read, then 8 x final mixer (class v3, mixer multiplier 8, +// docs/plans/mixer-x4.md: the round key of application j of round r is 0x9E3779B9 * (r * m + j + 1)). All parameters are literals. +#define MH_CACHE_LINE_MASK 0x003fffffu +#define MH_SEGMENT_LINES 64u +#define MH_QR(a, b, c, d, r1, r2, r3, r4) { a += b; d ^= a; d = mh_rotl(d, r1); c += d; b ^= c; b = mh_rotl(b, r2); a += b; d ^= a; d = mh_rotl(d, r3); c += d; b ^= c; b = mh_rotl(b, r4); } +IGNEUM_HD uint32_t mh_rotl(uint32_t x, uint32_t n) { return (x << n) | (x >> (32u - n)); } // n in 1..31 at every call site + +// y = ChaCha12 core(x) + x +IGNEUM_HD void mh_chacha_block(const uint32_t* x, uint32_t* y) { + for (uint32_t i = 0u; i < 16u; ++i) y[i] = x[i]; + for (uint32_t r = 0u; r < 6u; ++r) { + MH_QR(y[0], y[4], y[8], y[12], 16u, 12u, 8u, 7u) MH_QR(y[1], y[5], y[9], y[13], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[6], y[10], y[14], 16u, 12u, 8u, 7u) MH_QR(y[3], y[7], y[11], y[15], 16u, 12u, 8u, 7u) + MH_QR(y[0], y[5], y[10], y[15], 16u, 12u, 8u, 7u) MH_QR(y[1], y[6], y[11], y[12], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[7], y[8], y[13], 16u, 12u, 8u, 7u) MH_QR(y[3], y[4], y[9], y[14], 16u, 12u, 8u, 7u) + } + for (uint32_t i = 0u; i < 16u; ++i) y[i] += x[i]; +} + +// One cache segment: 64 chained lines written at cache[seg * 1024]. in_j = prev ^ (sigma || K || seg || j || tag), prev_0 = 0. +IGNEUM_HD void mh_cache_segment(uint32_t* cache, uint32_t seg) { + uint32_t prev[16]; uint32_t x[16]; uint32_t y[16]; + for (uint32_t i = 0u; i < 16u; ++i) prev[i] = 0u; + for (uint32_t j = 0u; j < MH_SEGMENT_LINES; ++j) { + x[0] = 0x61707865u ^ prev[0]; x[1] = 0x3320646eu ^ prev[1]; x[2] = 0x79622d32u ^ prev[2]; x[3] = 0x6b206574u ^ prev[3]; + x[4] = 0x3067619fu ^ prev[4]; + x[5] = 0x3c269176u ^ prev[5]; + x[6] = 0x84a03b03u ^ prev[6]; + x[7] = 0xf8c63294u ^ prev[7]; + x[8] = 0xff977c5bu ^ prev[8]; + x[9] = 0xe60def3eu ^ prev[9]; + x[10] = 0x63630141u ^ prev[10]; + x[11] = 0xb8fbcb58u ^ prev[11]; + x[12] = seg ^ prev[12]; x[13] = j ^ prev[13]; x[14] = 0x49676e65u ^ prev[14]; x[15] = 0x756d4d48u ^ prev[15]; + mh_chacha_block(x, y); + uint32_t* line = cache + ((seg * MH_SEGMENT_LINES + j) * 16u); + for (uint32_t i = 0u; i < 16u; ++i) { line[i] = y[i]; prev[i] = y[i]; } + } +} + +// M_r: per word (s ^ (RC + rk)) * MUL, then a column round and a diagonal round with the seed-drawn rotations. +IGNEUM_HD void mh_mixer(uint32_t* s, uint32_t rk) { + s[0] = (s[0] ^ (0xbab68293u + rk)) * 0x42146205u; + s[1] = (s[1] ^ (0xcc162340u + rk)) * 0x52cbe0fbu; + s[2] = (s[2] ^ (0x6ce151ccu + rk)) * 0x7ecf4a03u; + s[3] = (s[3] ^ (0xe62b8997u + rk)) * 0x6728907fu; + s[4] = (s[4] ^ (0xc9c80297u + rk)) * 0xd81d9751u; + s[5] = (s[5] ^ (0xf74a1654u + rk)) * 0x132952c3u; + s[6] = (s[6] ^ (0x3d704af5u + rk)) * 0xf60de277u; + s[7] = (s[7] ^ (0x3cf522b7u + rk)) * 0x05358035u; + s[8] = (s[8] ^ (0x2b9cac04u + rk)) * 0xbaf6499du; + s[9] = (s[9] ^ (0xa880ac10u + rk)) * 0xe4db9667u; + s[10] = (s[10] ^ (0x13e5dd1du + rk)) * 0x3e98f45du; + s[11] = (s[11] ^ (0x6fc3e233u + rk)) * 0xd0004eddu; + s[12] = (s[12] ^ (0x2d83eeacu + rk)) * 0x2691630du; + s[13] = (s[13] ^ (0x9006e8bfu + rk)) * 0x9beb3bcfu; + s[14] = (s[14] ^ (0x2c4b5362u + rk)) * 0xab310379u; + s[15] = (s[15] ^ (0x31b49ee2u + rk)) * 0x99cfb423u; + MH_QR(s[0], s[4], s[8], s[12], 20u, 20u, 19u, 4u) MH_QR(s[1], s[5], s[9], s[13], 20u, 20u, 19u, 4u) + MH_QR(s[2], s[6], s[10], s[14], 20u, 20u, 19u, 4u) MH_QR(s[3], s[7], s[11], s[15], 20u, 20u, 19u, 4u) + MH_QR(s[0], s[5], s[10], s[15], 26u, 3u, 3u, 27u) MH_QR(s[1], s[6], s[11], s[12], 26u, 3u, 3u, 27u) + MH_QR(s[2], s[7], s[8], s[13], 26u, 3u, 3u, 27u) MH_QR(s[3], s[4], s[9], s[14], 26u, 3u, 3u, 27u) +} + +// Item t: 16 words. s = (K, t * MUL[i] + RC[i]); 8 rounds of 8 x mixer + cache line s[0] & mask; 8 x final mixer. +IGNEUM_HD void mh_item(const uint32_t* cache, uint32_t t, uint32_t* s) { + s[0] = 0x3067619fu; + s[1] = 0x3c269176u; + s[2] = 0x84a03b03u; + s[3] = 0xf8c63294u; + s[4] = 0xff977c5bu; + s[5] = 0xe60def3eu; + s[6] = 0x63630141u; + s[7] = 0xb8fbcb58u; + s[8] = t * 0x42146205u + 0xbab68293u; + s[9] = t * 0x52cbe0fbu + 0xcc162340u; + s[10] = t * 0x7ecf4a03u + 0x6ce151ccu; + s[11] = t * 0x6728907fu + 0xe62b8997u; + s[12] = t * 0xd81d9751u + 0xc9c80297u; + s[13] = t * 0x132952c3u + 0xf74a1654u; + s[14] = t * 0xf60de277u + 0x3d704af5u; + s[15] = t * 0x05358035u + 0x3cf522b7u; + for (uint32_t r = 0u; r < 8u; ++r) { + for (uint32_t j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (r * 8u + j + 1u)); + const uint32_t* line = cache + ((s[0] & MH_CACHE_LINE_MASK) * 16u); + for (uint32_t i = 0u; i < 16u; ++i) s[i] ^= line[i]; + } + for (uint32_t j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (64u + j + 1u)); +} +// dataset[w] without the dataset: derive item w >> 4 and take word w & 15. +IGNEUM_HD uint32_t mh_word(const uint32_t* cache, uint32_t w) { uint32_t s[16]; mh_item(cache, w >> 4u, s); return s[w & 15u]; } diff --git a/proto-cuda/packs-ca3-shadow/sh256x27/memhard.metal b/proto-cuda/packs-ca3-shadow/sh256x27/memhard.metal new file mode 100644 index 000000000..01b263d6d --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x27/memhard.metal @@ -0,0 +1,107 @@ +#include +using namespace metal; +// Memory-hard dataset core (MEMHARD.md). Cache: 2^26 words in 2^16 segments of 64 chained ChaCha12 lines. +// Item: 8 rounds of 8 x seed-parameterised mixer + one 64-byte cache read, then 8 x final mixer (class v3, mixer multiplier 8, +// docs/plans/mixer-x4.md: the round key of application j of round r is 0x9E3779B9 * (r * m + j + 1)). All parameters are literals. +#define MH_CACHE_LINE_MASK 0x003fffffu +#define MH_SEGMENT_LINES 64u +#define MH_QR(a, b, c, d, r1, r2, r3, r4) { a += b; d ^= a; d = mh_rotl(d, r1); c += d; b ^= c; b = mh_rotl(b, r2); a += b; d ^= a; d = mh_rotl(d, r3); c += d; b ^= c; b = mh_rotl(b, r4); } +inline uint mh_rotl(uint x, uint n) { return (x << n) | (x >> (32u - n)); } // n in 1..31 at every call site + +// y = ChaCha12 core(x) + x +inline void mh_chacha_block(const thread uint* x, thread uint* y) { + for (uint i = 0u; i < 16u; ++i) y[i] = x[i]; + for (uint r = 0u; r < 6u; ++r) { + MH_QR(y[0], y[4], y[8], y[12], 16u, 12u, 8u, 7u) MH_QR(y[1], y[5], y[9], y[13], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[6], y[10], y[14], 16u, 12u, 8u, 7u) MH_QR(y[3], y[7], y[11], y[15], 16u, 12u, 8u, 7u) + MH_QR(y[0], y[5], y[10], y[15], 16u, 12u, 8u, 7u) MH_QR(y[1], y[6], y[11], y[12], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[7], y[8], y[13], 16u, 12u, 8u, 7u) MH_QR(y[3], y[4], y[9], y[14], 16u, 12u, 8u, 7u) + } + for (uint i = 0u; i < 16u; ++i) y[i] += x[i]; +} + +// One cache segment: 64 chained lines written at cache[seg * 1024]. in_j = prev ^ (sigma || K || seg || j || tag), prev_0 = 0. +inline void mh_cache_segment(device uint* cache, uint seg) { + uint prev[16]; uint x[16]; uint y[16]; + for (uint i = 0u; i < 16u; ++i) prev[i] = 0u; + for (uint j = 0u; j < MH_SEGMENT_LINES; ++j) { + x[0] = 0x61707865u ^ prev[0]; x[1] = 0x3320646eu ^ prev[1]; x[2] = 0x79622d32u ^ prev[2]; x[3] = 0x6b206574u ^ prev[3]; + x[4] = 0x3067619fu ^ prev[4]; + x[5] = 0x3c269176u ^ prev[5]; + x[6] = 0x84a03b03u ^ prev[6]; + x[7] = 0xf8c63294u ^ prev[7]; + x[8] = 0xff977c5bu ^ prev[8]; + x[9] = 0xe60def3eu ^ prev[9]; + x[10] = 0x63630141u ^ prev[10]; + x[11] = 0xb8fbcb58u ^ prev[11]; + x[12] = seg ^ prev[12]; x[13] = j ^ prev[13]; x[14] = 0x49676e65u ^ prev[14]; x[15] = 0x756d4d48u ^ prev[15]; + mh_chacha_block(x, y); + device uint* line = cache + ((seg * MH_SEGMENT_LINES + j) * 16u); + for (uint i = 0u; i < 16u; ++i) { line[i] = y[i]; prev[i] = y[i]; } + } +} + +// M_r: per word (s ^ (RC + rk)) * MUL, then a column round and a diagonal round with the seed-drawn rotations. +inline void mh_mixer(thread uint* s, uint rk) { + s[0] = (s[0] ^ (0xbab68293u + rk)) * 0x42146205u; + s[1] = (s[1] ^ (0xcc162340u + rk)) * 0x52cbe0fbu; + s[2] = (s[2] ^ (0x6ce151ccu + rk)) * 0x7ecf4a03u; + s[3] = (s[3] ^ (0xe62b8997u + rk)) * 0x6728907fu; + s[4] = (s[4] ^ (0xc9c80297u + rk)) * 0xd81d9751u; + s[5] = (s[5] ^ (0xf74a1654u + rk)) * 0x132952c3u; + s[6] = (s[6] ^ (0x3d704af5u + rk)) * 0xf60de277u; + s[7] = (s[7] ^ (0x3cf522b7u + rk)) * 0x05358035u; + s[8] = (s[8] ^ (0x2b9cac04u + rk)) * 0xbaf6499du; + s[9] = (s[9] ^ (0xa880ac10u + rk)) * 0xe4db9667u; + s[10] = (s[10] ^ (0x13e5dd1du + rk)) * 0x3e98f45du; + s[11] = (s[11] ^ (0x6fc3e233u + rk)) * 0xd0004eddu; + s[12] = (s[12] ^ (0x2d83eeacu + rk)) * 0x2691630du; + s[13] = (s[13] ^ (0x9006e8bfu + rk)) * 0x9beb3bcfu; + s[14] = (s[14] ^ (0x2c4b5362u + rk)) * 0xab310379u; + s[15] = (s[15] ^ (0x31b49ee2u + rk)) * 0x99cfb423u; + MH_QR(s[0], s[4], s[8], s[12], 20u, 20u, 19u, 4u) MH_QR(s[1], s[5], s[9], s[13], 20u, 20u, 19u, 4u) + MH_QR(s[2], s[6], s[10], s[14], 20u, 20u, 19u, 4u) MH_QR(s[3], s[7], s[11], s[15], 20u, 20u, 19u, 4u) + MH_QR(s[0], s[5], s[10], s[15], 26u, 3u, 3u, 27u) MH_QR(s[1], s[6], s[11], s[12], 26u, 3u, 3u, 27u) + MH_QR(s[2], s[7], s[8], s[13], 26u, 3u, 3u, 27u) MH_QR(s[3], s[4], s[9], s[14], 26u, 3u, 3u, 27u) +} + +// Item t: 16 words. s = (K, t * MUL[i] + RC[i]); 8 rounds of 8 x mixer + cache line s[0] & mask; 8 x final mixer. +inline void mh_item(device const uint* cache, uint t, thread uint* s) { + s[0] = 0x3067619fu; + s[1] = 0x3c269176u; + s[2] = 0x84a03b03u; + s[3] = 0xf8c63294u; + s[4] = 0xff977c5bu; + s[5] = 0xe60def3eu; + s[6] = 0x63630141u; + s[7] = 0xb8fbcb58u; + s[8] = t * 0x42146205u + 0xbab68293u; + s[9] = t * 0x52cbe0fbu + 0xcc162340u; + s[10] = t * 0x7ecf4a03u + 0x6ce151ccu; + s[11] = t * 0x6728907fu + 0xe62b8997u; + s[12] = t * 0xd81d9751u + 0xc9c80297u; + s[13] = t * 0x132952c3u + 0xf74a1654u; + s[14] = t * 0xf60de277u + 0x3d704af5u; + s[15] = t * 0x05358035u + 0x3cf522b7u; + for (uint r = 0u; r < 8u; ++r) { + for (uint j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (r * 8u + j + 1u)); + device const uint* line = cache + ((s[0] & MH_CACHE_LINE_MASK) * 16u); + for (uint i = 0u; i < 16u; ++i) s[i] ^= line[i]; + } + for (uint j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (64u + j + 1u)); +} +// dataset[w] without the dataset: derive item w >> 4 and take word w & 15. +inline uint mh_word(device const uint* cache, uint w) { uint s[16]; mh_item(cache, w >> 4u, s); return s[w & 15u]; } + +// One thread per segment (2^16 threads). +kernel void igneum_cache_fill(device uint* cache [[buffer(0)]], uint gid [[thread_position_in_grid]]) { + mh_cache_segment(cache, gid); +} +// One thread per 64-byte item (dataset words / 16 threads). +kernel void igneum_build(device const uint* cache [[buffer(0)]], device uint* dataset [[buffer(1)]], + uint gid [[thread_position_in_grid]]) { + uint s[16]; + mh_item(cache, gid, s); + device uint* d = dataset + gid * 16u; + for (uint i = 0u; i < 16u; ++i) d[i] = s[i]; +} diff --git a/proto-cuda/packs-ca3-shadow/sh256x27/program.h b/proto-cuda/packs-ca3-shadow/sh256x27/program.h new file mode 100644 index 000000000..e1c873c47 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x27/program.h @@ -0,0 +1,70 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Program metadata for host.cu plus the launch wrappers defined in kernel.cu. +// Also included by proto-opencl/host.c (C99), which defines IGNEUM_NO_CUDA first and reads only the macros. +#pragma once +#ifdef __cplusplus +#include +#else +#include +#endif +#ifndef IGNEUM_NO_CUDA +#include +#endif + +#define IGNEUM_SEED_STRING "igneum-genesis" +#define IGNEUM_SEED_BYTES_HEX "69676e65756d2d67656e65736973" +#define IGNEUM_GENERATOR 2 +#define IGNEUM_PROGRAM_ATTEMPT 0 +#define IGNEUM_PROGRAM_ID 0x9a8b77853b298baaull +#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 add=8 shfl=8 xor=6 mad=5 mul=5 mulhi=5 sub=4 rotl=3 rotr=3 or=1" +// 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+sh256x27" +#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=47 rotl=30 xor=30 shfl=29 mad=27 mul=22 sub=21 rotr=20 mulhi=18 or=12" +// 0 = closed-form dataset (ds_elem), 1 = memory-hard cache construction (MEMHARD.md, memhard.h) +#define IGNEUM_DATASET_MODE 1 + +#define IGNEUM_SEEDW_INIT { 0x67a9a7beu, 0x1a155b25u, 0xfddfb732u, 0x4b5af2e8u, 0xc55caf33u, 0xa27c13b7u, 0x06628a48u, 0x03852469u } +#define IGNEUM_KEY_INIT { 0x3067619fu, 0x3c269176u, 0x84a03b03u, 0xf8c63294u, 0xff977c5bu, 0xe60def3eu, 0x63630141u, 0xb8fbcb58u } +#define IGNEUM_CACHE_LOG2_WORDS 26 +#define IGNEUM_CACHE_SEGMENT_LOG2_LINES 6 +#define IGNEUM_CACHE_SEGMENTS 65536u +#define IGNEUM_ITEM_ROUNDS 8 +#define IGNEUM_MIXER_MULT 8 // mixer applications per round and after the last read (class v3, docs/plans/mixer-x4.md) +#define IGNEUM_MIX_ROT_INIT { 20u, 20u, 19u, 4u, 26u, 3u, 3u, 27u } +#define IGNEUM_MIX_MUL_INIT { 0x42146205u, 0x52cbe0fbu, 0x7ecf4a03u, 0x6728907fu, 0xd81d9751u, 0x132952c3u, 0xf60de277u, 0x05358035u, 0xbaf6499du, 0xe4db9667u, 0x3e98f45du, 0xd0004eddu, 0x2691630du, 0x9beb3bcfu, 0xab310379u, 0x99cfb423u } +#define IGNEUM_MIX_RC_INIT { 0xbab68293u, 0xcc162340u, 0x6ce151ccu, 0xe62b8997u, 0xc9c80297u, 0xf74a1654u, 0x3d704af5u, 0x3cf522b7u, 0x2b9cac04u, 0xa880ac10u, 0x13e5dd1du, 0x6fc3e233u, 0x2d83eeacu, 0x9006e8bfu, 0x2c4b5362u, 0x31b49ee2u } + +#ifndef IGNEUM_NO_CUDA +// Defined in kernel.cu. All launch on the default stream and return cudaGetLastError(). +cudaError_t igneum_launch_cache_fill(uint32_t* cache, uint32_t nSegments); +cudaError_t igneum_launch_build(uint32_t* ds, const uint32_t* cache, uint32_t nItems); +cudaError_t igneum_launch_hash(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, + uint32_t nonces, uint32_t blockWarps); +cudaError_t igneum_hash_info(int* numRegs, int* blocksPerSM, uint32_t blockWarps); +#endif diff --git a/proto-cuda/packs-ca3-shadow/sh256x27/program.json b/proto-cuda/packs-ca3-shadow/sh256x27/program.json new file mode 100644 index 000000000..8588e0fe9 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x27/program.json @@ -0,0 +1,389 @@ +{ + "format": "igneum-program-pack-3", + "generator": 2, + "attempt": 0, + "program_id": "0x9a8b77853b298baa", + "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": ["0x67a9a7be", "0x1a155b25", "0xfddfb732", "0x4b5af2e8", "0xc55caf33", "0xa27c13b7", "0x06628a48", "0x03852469"], + "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+sh256x27", + "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, "add": 8, "shfl": 8, "xor": 6, "mad": 5, "mul": 5, "mulhi": 5, "sub": 4, "rotl": 3, "rotr": 3, "or": 1}, + "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": 47, "rotl": 30, "xor": 30, "shfl": 29, "mad": 27, "mul": 22, "sub": 21, "rotr": 20, "mulhi": 18, "or": 12}, "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": "add", "dst": 5, "src": 2, "src2": 1, "imm": "0x92199f99", "imm2": "0x8bc12da9", "rot": 9, "bit": 18, "mask": 4}, + {"i": 1, "op": "add", "dst": 0, "src": 7, "src2": 1, "imm": "0x8d72d3ad", "imm2": "0x63079e5a", "rot": 20, "bit": 26, "mask": 4}, + {"i": 2, "op": "shfl", "dst": 6, "src": 3, "src2": 6, "imm": "0x9beaeddf", "imm2": "0x744ecb00", "rot": 10, "bit": 4, "mask": 2}, + {"i": 3, "op": "sub", "dst": 4, "src": 2, "src2": 0, "imm": "0x2a3ddc67", "imm2": "0x72c80241", "rot": 30, "bit": 1, "mask": 16}, + {"i": 4, "op": "add", "dst": 7, "src": 0, "src2": 5, "imm": "0xb21b4bab", "imm2": "0x5d4c7a60", "rot": 17, "bit": 31, "mask": 4}, + {"i": 5, "op": "rotl", "dst": 0, "src": 6, "src2": 3, "imm": "0xe69d7919", "imm2": "0xa048c61e", "rot": 11, "bit": 1, "mask": 8}, + {"i": 6, "op": "add", "dst": 0, "src": 1, "src2": 3, "imm": "0x2fe0e98b", "imm2": "0xc88e2942", "rot": 5, "bit": 16, "mask": 16}, + {"i": 7, "op": "xor", "dst": 7, "src": 1, "src2": 0, "imm": "0xc16efe98", "imm2": "0x01a638c8", "rot": 8, "bit": 17, "mask": 1}, + {"i": 8, "op": "mad", "dst": 1, "src": 6, "src2": 5, "imm": "0x76ec7b8b", "imm2": "0x25663feb", "rot": 29, "bit": 30, "mask": 2}, + {"i": 9, "op": "shfl", "dst": 6, "src": 1, "src2": 0, "imm": "0x6c8ee3cb", "imm2": "0xea93237e", "rot": 27, "bit": 1, "mask": 4}, + {"i": 10, "op": "mad", "dst": 1, "src": 2, "src2": 2, "imm": "0x6dc4ea18", "imm2": "0x6efde6f5", "rot": 3, "bit": 20, "mask": 2}, + {"i": 11, "op": "mad", "dst": 5, "src": 0, "src2": 3, "imm": "0x023613fc", "imm2": "0x18c51939", "rot": 19, "bit": 31, "mask": 1}, + {"i": 12, "op": "shfl", "dst": 2, "src": 6, "src2": 1, "imm": "0x74aec8d2", "imm2": "0x7f7ad29c", "rot": 7, "bit": 8, "mask": 4}, + {"i": 13, "op": "add", "dst": 1, "src": 5, "src2": 6, "imm": "0xbdf8f9a5", "imm2": "0xbc48c63e", "rot": 6, "bit": 25, "mask": 2}, + {"i": 14, "op": "rotl", "dst": 1, "src": 2, "src2": 6, "imm": "0x7ad8ca8b", "imm2": "0x14c712ad", "rot": 29, "bit": 25, "mask": 8}, + {"i": 15, "op": "sub", "dst": 1, "src": 4, "src2": 5, "imm": "0xd3349f69", "imm2": "0x70aac45a", "rot": 29, "bit": 9, "mask": 16}, + {"i": 16, "op": "or", "dst": 7, "src": 1, "src2": 2, "imm": "0x08168ed1", "imm2": "0x28964037", "rot": 26, "bit": 0, "mask": 2}, + {"i": 17, "op": "shfl", "dst": 2, "src": 4, "src2": 6, "imm": "0x98d85f72", "imm2": "0x3dc87042", "rot": 29, "bit": 22, "mask": 8}, + {"i": 18, "op": "xor", "dst": 7, "src": 4, "src2": 0, "imm": "0x651d4a0e", "imm2": "0x93c198bd", "rot": 26, "bit": 12, "mask": 8}, + {"i": 19, "op": "mul", "dst": 6, "src": 1, "src2": 6, "imm": "0xd38ce89d", "imm2": "0x3dfad388", "rot": 5, "bit": 28, "mask": 8}, + {"i": 20, "op": "mad", "dst": 5, "src": 6, "src2": 0, "imm": "0x59d78b36", "imm2": "0xc4db274e", "rot": 25, "bit": 24, "mask": 1}, + {"i": 21, "op": "sub", "dst": 3, "src": 1, "src2": 7, "imm": "0xf6c6a6c7", "imm2": "0x8536f4e6", "rot": 6, "bit": 12, "mask": 4}, + {"i": 22, "op": "mul", "dst": 6, "src": 0, "src2": 7, "imm": "0x599445b4", "imm2": "0x632f8c32", "rot": 19, "bit": 4, "mask": 8}, + {"i": 23, "op": "add", "dst": 2, "src": 0, "src2": 7, "imm": "0x45c37cec", "imm2": "0x96e8f127", "rot": 15, "bit": 1, "mask": 4}, + {"i": 24, "op": "sub", "dst": 6, "src": 4, "src2": 3, "imm": "0xc1c44491", "imm2": "0x92e3ce57", "rot": 20, "bit": 25, "mask": 4}, + {"i": 25, "op": "mad", "dst": 7, "src": 3, "src2": 4, "imm": "0x89bfb8d3", "imm2": "0x19b5455e", "rot": 22, "bit": 2, "mask": 16}, + {"i": 26, "op": "rotl", "dst": 3, "src": 5, "src2": 7, "imm": "0x2f47ce8d", "imm2": "0x8b458ec5", "rot": 9, "bit": 0, "mask": 4}, + {"i": 27, "op": "sub", "dst": 2, "src": 1, "src2": 2, "imm": "0x9f0dce23", "imm2": "0x3cdca814", "rot": 25, "bit": 1, "mask": 2}, + {"i": 28, "op": "mulhi", "dst": 6, "src": 0, "src2": 3, "imm": "0x61fc9eb8", "imm2": "0x23202e9d", "rot": 30, "bit": 16, "mask": 16}, + {"i": 29, "op": "shfl", "dst": 2, "src": 4, "src2": 3, "imm": "0x339dbd65", "imm2": "0xc175f639", "rot": 15, "bit": 22, "mask": 2}, + {"i": 30, "op": "shfl", "dst": 1, "src": 6, "src2": 1, "imm": "0x5bd14589", "imm2": "0xa68a2bed", "rot": 31, "bit": 31, "mask": 1}, + {"i": 31, "op": "add", "dst": 1, "src": 6, "src2": 1, "imm": "0x37985632", "imm2": "0xb1cdb2ab", "rot": 29, "bit": 1, "mask": 8}, + {"i": 32, "op": "rotr", "dst": 0, "src": 1, "src2": 6, "imm": "0x4b2058f4", "imm2": "0xf06d8ac9", "rot": 9, "bit": 15, "mask": 16}, + {"i": 33, "op": "shfl", "dst": 3, "src": 4, "src2": 4, "imm": "0x2081626c", "imm2": "0x08d1bb87", "rot": 24, "bit": 29, "mask": 2}, + {"i": 34, "op": "shfl", "dst": 0, "src": 3, "src2": 6, "imm": "0xe4fcfe03", "imm2": "0x78a46b13", "rot": 15, "bit": 29, "mask": 4}, + {"i": 35, "op": "mul", "dst": 7, "src": 0, "src2": 4, "imm": "0x33148d30", "imm2": "0x5780a3d6", "rot": 6, "bit": 11, "mask": 2}, + {"i": 36, "op": "add", "dst": 3, "src": 1, "src2": 1, "imm": "0x804e777e", "imm2": "0x856e0180", "rot": 22, "bit": 0, "mask": 16}, + {"i": 37, "op": "xor", "dst": 1, "src": 6, "src2": 0, "imm": "0xc69aa2f6", "imm2": "0xafebe3e8", "rot": 15, "bit": 9, "mask": 16}, + {"i": 38, "op": "mul", "dst": 2, "src": 7, "src2": 4, "imm": "0xeb4c4082", "imm2": "0x3f1e0da7", "rot": 25, "bit": 20, "mask": 16}, + {"i": 39, "op": "add", "dst": 6, "src": 5, "src2": 5, "imm": "0x0b06c8a7", "imm2": "0xe9bd0cc4", "rot": 6, "bit": 2, "mask": 4}, + {"i": 40, "op": "mul", "dst": 5, "src": 7, "src2": 7, "imm": "0x070af1b6", "imm2": "0x6b648e75", "rot": 10, "bit": 6, "mask": 16}, + {"i": 41, "op": "mulhi", "dst": 2, "src": 3, "src2": 2, "imm": "0x389753b2", "imm2": "0x9e657305", "rot": 30, "bit": 2, "mask": 4}, + {"i": 42, "op": "xor", "dst": 2, "src": 0, "src2": 4, "imm": "0x0960e5b9", "imm2": "0xa925a406", "rot": 4, "bit": 6, "mask": 16}, + {"i": 43, "op": "rotl", "dst": 0, "src": 1, "src2": 1, "imm": "0x8eabe09f", "imm2": "0x76ef71e2", "rot": 4, "bit": 19, "mask": 8}, + {"i": 44, "op": "mulhi", "dst": 4, "src": 3, "src2": 7, "imm": "0x6a34768a", "imm2": "0x2e427c64", "rot": 21, "bit": 5, "mask": 4}, + {"i": 45, "op": "add", "dst": 6, "src": 7, "src2": 5, "imm": "0xee822e17", "imm2": "0xcdcb63f6", "rot": 27, "bit": 12, "mask": 16}, + {"i": 46, "op": "mad", "dst": 3, "src": 2, "src2": 0, "imm": "0xc89ead43", "imm2": "0x4d3108b2", "rot": 26, "bit": 17, "mask": 1}, + {"i": 47, "op": "shfl", "dst": 4, "src": 3, "src2": 0, "imm": "0xdd62be9e", "imm2": "0xf243f6f2", "rot": 8, "bit": 4, "mask": 8}, + {"i": 48, "op": "mulhi", "dst": 6, "src": 5, "src2": 0, "imm": "0xd3f7fa72", "imm2": "0x0debc83f", "rot": 25, "bit": 5, "mask": 2}, + {"i": 49, "op": "sub", "dst": 0, "src": 2, "src2": 6, "imm": "0x7afadd15", "imm2": "0xc07fc39c", "rot": 30, "bit": 29, "mask": 8}, + {"i": 50, "op": "sub", "dst": 3, "src": 5, "src2": 3, "imm": "0x179b78ec", "imm2": "0xaeccde37", "rot": 30, "bit": 17, "mask": 1}, + {"i": 51, "op": "rotr", "dst": 1, "src": 4, "src2": 1, "imm": "0xa4bfcea6", "imm2": "0xbf63bb2f", "rot": 2, "bit": 21, "mask": 2}, + {"i": 52, "op": "mad", "dst": 6, "src": 7, "src2": 7, "imm": "0xabf5ed10", "imm2": "0x8a285f51", "rot": 3, "bit": 23, "mask": 2}, + {"i": 53, "op": "xor", "dst": 5, "src": 3, "src2": 5, "imm": "0x88b416eb", "imm2": "0x36271d87", "rot": 19, "bit": 10, "mask": 2}, + {"i": 54, "op": "sub", "dst": 1, "src": 0, "src2": 1, "imm": "0xa3417dd3", "imm2": "0xcd98f620", "rot": 28, "bit": 2, "mask": 1}, + {"i": 55, "op": "sub", "dst": 5, "src": 6, "src2": 2, "imm": "0x45996c6f", "imm2": "0xe3d41087", "rot": 4, "bit": 31, "mask": 1}, + {"i": 56, "op": "add", "dst": 3, "src": 2, "src2": 0, "imm": "0x3dfad1b6", "imm2": "0xd4758987", "rot": 27, "bit": 10, "mask": 2}, + {"i": 57, "op": "add", "dst": 4, "src": 1, "src2": 3, "imm": "0xfca75bc2", "imm2": "0x0602d6be", "rot": 19, "bit": 0, "mask": 16}, + {"i": 58, "op": "mulhi", "dst": 5, "src": 6, "src2": 5, "imm": "0x83250a7b", "imm2": "0x2f93d53b", "rot": 25, "bit": 7, "mask": 2}, + {"i": 59, "op": "shfl", "dst": 2, "src": 1, "src2": 0, "imm": "0x13f4a089", "imm2": "0x145ea125", "rot": 12, "bit": 3, "mask": 2}, + {"i": 60, "op": "rotl", "dst": 2, "src": 5, "src2": 6, "imm": "0xad3170e3", "imm2": "0x15db04d1", "rot": 9, "bit": 13, "mask": 2}, + {"i": 61, "op": "or", "dst": 4, "src": 6, "src2": 2, "imm": "0x4b6305b2", "imm2": "0x6e7b2e9c", "rot": 27, "bit": 16, "mask": 4}, + {"i": 62, "op": "rotr", "dst": 6, "src": 4, "src2": 6, "imm": "0xfcd4b1c9", "imm2": "0xaf5c733b", "rot": 6, "bit": 21, "mask": 16}, + {"i": 63, "op": "mul", "dst": 2, "src": 4, "src2": 6, "imm": "0x95cebb3e", "imm2": "0xbba9cdfc", "rot": 19, "bit": 23, "mask": 1}, + {"i": 64, "op": "xor", "dst": 0, "src": 5, "src2": 7, "imm": "0x5f7579ff", "imm2": "0xb104e01a", "rot": 25, "bit": 12, "mask": 8}, + {"i": 65, "op": "xor", "dst": 2, "src": 7, "src2": 3, "imm": "0x749c7611", "imm2": "0xf17df3bb", "rot": 27, "bit": 26, "mask": 2}, + {"i": 66, "op": "add", "dst": 2, "src": 1, "src2": 6, "imm": "0xd71c02ff", "imm2": "0x8596687a", "rot": 4, "bit": 6, "mask": 2}, + {"i": 67, "op": "rotl", "dst": 1, "src": 3, "src2": 2, "imm": "0xd2864071", "imm2": "0xaa644ef3", "rot": 21, "bit": 5, "mask": 1}, + {"i": 68, "op": "mul", "dst": 3, "src": 2, "src2": 1, "imm": "0xd0689a5f", "imm2": "0xa3a1f063", "rot": 13, "bit": 28, "mask": 2}, + {"i": 69, "op": "shfl", "dst": 7, "src": 5, "src2": 6, "imm": "0xd01476eb", "imm2": "0x76abb5c2", "rot": 7, "bit": 30, "mask": 2}, + {"i": 70, "op": "mul", "dst": 3, "src": 2, "src2": 5, "imm": "0x59a75c10", "imm2": "0x1e1fbb72", "rot": 20, "bit": 16, "mask": 1}, + {"i": 71, "op": "mad", "dst": 0, "src": 2, "src2": 5, "imm": "0x39cca1df", "imm2": "0x22c057ac", "rot": 5, "bit": 23, "mask": 16}, + {"i": 72, "op": "add", "dst": 6, "src": 7, "src2": 3, "imm": "0x3c6fe15d", "imm2": "0x08ac5733", "rot": 14, "bit": 0, "mask": 4}, + {"i": 73, "op": "shfl", "dst": 3, "src": 2, "src2": 6, "imm": "0x2098627d", "imm2": "0xf4fecc81", "rot": 20, "bit": 30, "mask": 8}, + {"i": 74, "op": "mul", "dst": 3, "src": 6, "src2": 5, "imm": "0xf82e9e23", "imm2": "0x3ad62132", "rot": 10, "bit": 14, "mask": 16}, + {"i": 75, "op": "xor", "dst": 6, "src": 7, "src2": 4, "imm": "0x70548a91", "imm2": "0xa9715d2e", "rot": 6, "bit": 24, "mask": 1}, + {"i": 76, "op": "or", "dst": 3, "src": 0, "src2": 7, "imm": "0xa164325f", "imm2": "0xf300838b", "rot": 23, "bit": 23, "mask": 16}, + {"i": 77, "op": "add", "dst": 2, "src": 4, "src2": 6, "imm": "0x295d5fae", "imm2": "0xc100b495", "rot": 7, "bit": 1, "mask": 2}, + {"i": 78, "op": "mulhi", "dst": 3, "src": 7, "src2": 4, "imm": "0xb62cca87", "imm2": "0x2ebde415", "rot": 14, "bit": 7, "mask": 2}, + {"i": 79, "op": "or", "dst": 4, "src": 1, "src2": 7, "imm": "0xfcbc482d", "imm2": "0x8876e6cd", "rot": 29, "bit": 5, "mask": 2}, + {"i": 80, "op": "rotr", "dst": 4, "src": 3, "src2": 0, "imm": "0x6d64013b", "imm2": "0x675f4a8d", "rot": 26, "bit": 18, "mask": 8}, + {"i": 81, "op": "add", "dst": 4, "src": 3, "src2": 3, "imm": "0x274a9221", "imm2": "0x5cc59530", "rot": 15, "bit": 15, "mask": 2}, + {"i": 82, "op": "add", "dst": 7, "src": 3, "src2": 0, "imm": "0xc8651f8e", "imm2": "0x141479ec", "rot": 18, "bit": 5, "mask": 1}, + {"i": 83, "op": "rotr", "dst": 3, "src": 6, "src2": 0, "imm": "0xcc8a7766", "imm2": "0xc2eb5161", "rot": 4, "bit": 29, "mask": 2}, + {"i": 84, "op": "mad", "dst": 2, "src": 4, "src2": 7, "imm": "0xbc507d51", "imm2": "0x0b1196fd", "rot": 9, "bit": 7, "mask": 8}, + {"i": 85, "op": "shfl", "dst": 2, "src": 5, "src2": 5, "imm": "0x5a156c90", "imm2": "0xa6b3fbfa", "rot": 11, "bit": 2, "mask": 16}, + {"i": 86, "op": "xor", "dst": 3, "src": 2, "src2": 1, "imm": "0x8b042658", "imm2": "0xacf37a8f", "rot": 12, "bit": 23, "mask": 16}, + {"i": 87, "op": "shfl", "dst": 5, "src": 7, "src2": 2, "imm": "0x1a214238", "imm2": "0x017fdf5d", "rot": 29, "bit": 14, "mask": 2}, + {"i": 88, "op": "xor", "dst": 0, "src": 4, "src2": 2, "imm": "0xd523e612", "imm2": "0x2158c2ed", "rot": 30, "bit": 14, "mask": 4}, + {"i": 89, "op": "add", "dst": 3, "src": 2, "src2": 7, "imm": "0x53f915c2", "imm2": "0x883c0c92", "rot": 9, "bit": 18, "mask": 8}, + {"i": 90, "op": "rotr", "dst": 7, "src": 5, "src2": 5, "imm": "0xbd633b21", "imm2": "0xcf8c356c", "rot": 25, "bit": 31, "mask": 4}, + {"i": 91, "op": "add", "dst": 3, "src": 1, "src2": 1, "imm": "0xe2be00a5", "imm2": "0x3cc5bd20", "rot": 10, "bit": 31, "mask": 1}, + {"i": 92, "op": "shfl", "dst": 7, "src": 2, "src2": 4, "imm": "0x3d3da600", "imm2": "0x1f22df89", "rot": 4, "bit": 24, "mask": 1}, + {"i": 93, "op": "rotr", "dst": 6, "src": 2, "src2": 7, "imm": "0xb0f57471", "imm2": "0x8f2a7eca", "rot": 16, "bit": 25, "mask": 1}, + {"i": 94, "op": "rotl", "dst": 7, "src": 0, "src2": 4, "imm": "0x00a21815", "imm2": "0xeb4d7218", "rot": 14, "bit": 18, "mask": 16}, + {"i": 95, "op": "mad", "dst": 4, "src": 5, "src2": 5, "imm": "0xc4c3828e", "imm2": "0xfb7bba17", "rot": 16, "bit": 10, "mask": 16}, + {"i": 96, "op": "mad", "dst": 2, "src": 4, "src2": 5, "imm": "0xfc5bbc75", "imm2": "0xfc43468f", "rot": 31, "bit": 20, "mask": 16}, + {"i": 97, "op": "xor", "dst": 1, "src": 0, "src2": 2, "imm": "0x1fe9c249", "imm2": "0x164bb16b", "rot": 15, "bit": 9, "mask": 4}, + {"i": 98, "op": "mul", "dst": 5, "src": 4, "src2": 1, "imm": "0xeda725fa", "imm2": "0x66f7e9a2", "rot": 21, "bit": 6, "mask": 2}, + {"i": 99, "op": "sub", "dst": 2, "src": 0, "src2": 7, "imm": "0x8fb29f7d", "imm2": "0xf530eda1", "rot": 27, "bit": 30, "mask": 4}, + {"i": 100, "op": "rotl", "dst": 7, "src": 2, "src2": 0, "imm": "0x9f4de742", "imm2": "0x9b5ff871", "rot": 30, "bit": 21, "mask": 16}, + {"i": 101, "op": "add", "dst": 5, "src": 6, "src2": 7, "imm": "0x423fd9c9", "imm2": "0xbfd646cb", "rot": 17, "bit": 17, "mask": 2}, + {"i": 102, "op": "add", "dst": 7, "src": 6, "src2": 3, "imm": "0x8d3c011d", "imm2": "0x19b74a43", "rot": 12, "bit": 11, "mask": 4}, + {"i": 103, "op": "rotl", "dst": 5, "src": 6, "src2": 0, "imm": "0xcfc70303", "imm2": "0xf2b3e8ef", "rot": 6, "bit": 24, "mask": 1}, + {"i": 104, "op": "mul", "dst": 0, "src": 4, "src2": 5, "imm": "0x650475eb", "imm2": "0x11dcbd94", "rot": 15, "bit": 10, "mask": 1}, + {"i": 105, "op": "or", "dst": 0, "src": 5, "src2": 3, "imm": "0xaacaa145", "imm2": "0x9139d3fe", "rot": 4, "bit": 18, "mask": 2}, + {"i": 106, "op": "add", "dst": 0, "src": 1, "src2": 7, "imm": "0x8ce14721", "imm2": "0x7dcb7e18", "rot": 24, "bit": 15, "mask": 8}, + {"i": 107, "op": "rotl", "dst": 0, "src": 3, "src2": 3, "imm": "0xb36d6d98", "imm2": "0x2c3390c8", "rot": 15, "bit": 10, "mask": 16}, + {"i": 108, "op": "sub", "dst": 4, "src": 2, "src2": 5, "imm": "0xf6bbdaef", "imm2": "0x9db6f65e", "rot": 25, "bit": 10, "mask": 1}, + {"i": 109, "op": "mulhi", "dst": 2, "src": 0, "src2": 0, "imm": "0xb1721fd6", "imm2": "0xd96d52c9", "rot": 1, "bit": 27, "mask": 8}, + {"i": 110, "op": "mulhi", "dst": 1, "src": 0, "src2": 5, "imm": "0xfb4ca37f", "imm2": "0xb6ec7dbe", "rot": 27, "bit": 12, "mask": 8}, + {"i": 111, "op": "add", "dst": 0, "src": 2, "src2": 0, "imm": "0x2d9fc6b9", "imm2": "0x3c179ad8", "rot": 9, "bit": 28, "mask": 16}, + {"i": 112, "op": "mulhi", "dst": 2, "src": 0, "src2": 6, "imm": "0x71a9f6bd", "imm2": "0xd3417bf5", "rot": 2, "bit": 14, "mask": 8}, + {"i": 113, "op": "sub", "dst": 6, "src": 3, "src2": 5, "imm": "0xa3d19400", "imm2": "0x15df7330", "rot": 5, "bit": 2, "mask": 8}, + {"i": 114, "op": "mad", "dst": 7, "src": 6, "src2": 3, "imm": "0x1400d92e", "imm2": "0xfa4a158e", "rot": 16, "bit": 9, "mask": 1}, + {"i": 115, "op": "rotr", "dst": 5, "src": 1, "src2": 3, "imm": "0xd01684c3", "imm2": "0x6367febb", "rot": 23, "bit": 19, "mask": 2}, + {"i": 116, "op": "rotr", "dst": 6, "src": 4, "src2": 2, "imm": "0x8cd9eb96", "imm2": "0x98f33b24", "rot": 25, "bit": 1, "mask": 2}, + {"i": 117, "op": "add", "dst": 2, "src": 1, "src2": 7, "imm": "0x502138e2", "imm2": "0x47359729", "rot": 5, "bit": 22, "mask": 4}, + {"i": 118, "op": "mad", "dst": 3, "src": 2, "src2": 0, "imm": "0xd94a35c7", "imm2": "0xb83416c3", "rot": 11, "bit": 3, "mask": 4}, + {"i": 119, "op": "mul", "dst": 1, "src": 3, "src2": 6, "imm": "0x09b30cf7", "imm2": "0xef3b98e7", "rot": 17, "bit": 23, "mask": 8}, + {"i": 120, "op": "mad", "dst": 2, "src": 0, "src2": 4, "imm": "0x56416fe0", "imm2": "0x5e1dc8f3", "rot": 17, "bit": 14, "mask": 2}, + {"i": 121, "op": "mul", "dst": 0, "src": 3, "src2": 2, "imm": "0x2892697c", "imm2": "0x9cb3b14e", "rot": 29, "bit": 25, "mask": 2}, + {"i": 122, "op": "mulhi", "dst": 2, "src": 0, "src2": 3, "imm": "0xc33089a1", "imm2": "0xd6c5b530", "rot": 27, "bit": 13, "mask": 8}, + {"i": 123, "op": "mul", "dst": 5, "src": 6, "src2": 4, "imm": "0xdfe04e4a", "imm2": "0x3cc40160", "rot": 3, "bit": 14, "mask": 2}, + {"i": 124, "op": "mad", "dst": 4, "src": 2, "src2": 4, "imm": "0xb33dc1b7", "imm2": "0xab97743a", "rot": 7, "bit": 21, "mask": 4}, + {"i": 125, "op": "shfl", "dst": 4, "src": 2, "src2": 0, "imm": "0xfd469909", "imm2": "0xfc85dc55", "rot": 28, "bit": 24, "mask": 2}, + {"i": 126, "op": "xor", "dst": 2, "src": 0, "src2": 5, "imm": "0xa0094578", "imm2": "0xf1bee474", "rot": 31, "bit": 7, "mask": 2}, + {"i": 127, "op": "rotl", "dst": 1, "src": 7, "src2": 2, "imm": "0xb7ae00a0", "imm2": "0x86cce297", "rot": 7, "bit": 31, "mask": 8}, + {"i": 128, "op": "shfl", "dst": 7, "src": 2, "src2": 7, "imm": "0x019d1940", "imm2": "0x3fe9e7dd", "rot": 14, "bit": 4, "mask": 4}, + {"i": 129, "op": "rotl", "dst": 6, "src": 7, "src2": 7, "imm": "0x40a74cc4", "imm2": "0x09eb4adf", "rot": 17, "bit": 30, "mask": 1}, + {"i": 130, "op": "add", "dst": 2, "src": 5, "src2": 5, "imm": "0x33dff776", "imm2": "0x6c57e4e7", "rot": 27, "bit": 15, "mask": 4}, + {"i": 131, "op": "or", "dst": 0, "src": 3, "src2": 1, "imm": "0xe0c53bb9", "imm2": "0x124404f6", "rot": 4, "bit": 21, "mask": 16}, + {"i": 132, "op": "rotr", "dst": 5, "src": 0, "src2": 1, "imm": "0xe4353fce", "imm2": "0x559d0118", "rot": 2, "bit": 29, "mask": 4}, + {"i": 133, "op": "add", "dst": 2, "src": 3, "src2": 6, "imm": "0x5db25b34", "imm2": "0xe8212c0c", "rot": 21, "bit": 30, "mask": 1}, + {"i": 134, "op": "xor", "dst": 4, "src": 3, "src2": 6, "imm": "0x7366e50e", "imm2": "0x7cc1ffbd", "rot": 19, "bit": 18, "mask": 16}, + {"i": 135, "op": "xor", "dst": 6, "src": 1, "src2": 2, "imm": "0xa36decb7", "imm2": "0x79291734", "rot": 26, "bit": 0, "mask": 8}, + {"i": 136, "op": "sub", "dst": 1, "src": 7, "src2": 0, "imm": "0x225b03e4", "imm2": "0x7183e193", "rot": 16, "bit": 6, "mask": 2}, + {"i": 137, "op": "mad", "dst": 2, "src": 6, "src2": 2, "imm": "0x6f620d51", "imm2": "0x4e814e19", "rot": 6, "bit": 6, "mask": 2}, + {"i": 138, "op": "mulhi", "dst": 0, "src": 5, "src2": 6, "imm": "0x919d6bf3", "imm2": "0xc6240638", "rot": 17, "bit": 11, "mask": 16}, + {"i": 139, "op": "add", "dst": 2, "src": 7, "src2": 7, "imm": "0x218d4090", "imm2": "0xd44ff710", "rot": 1, "bit": 10, "mask": 16}, + {"i": 140, "op": "rotr", "dst": 1, "src": 4, "src2": 4, "imm": "0x4cbfa722", "imm2": "0x114e9564", "rot": 28, "bit": 9, "mask": 16}, + {"i": 141, "op": "shfl", "dst": 3, "src": 6, "src2": 2, "imm": "0xf702c6a1", "imm2": "0xf8f3c5d9", "rot": 7, "bit": 24, "mask": 1}, + {"i": 142, "op": "mad", "dst": 7, "src": 6, "src2": 2, "imm": "0xa2d285be", "imm2": "0x9cc94532", "rot": 15, "bit": 20, "mask": 8}, + {"i": 143, "op": "mul", "dst": 2, "src": 3, "src2": 7, "imm": "0x08b7ed80", "imm2": "0xa8abced4", "rot": 18, "bit": 10, "mask": 4}, + {"i": 144, "op": "add", "dst": 7, "src": 4, "src2": 2, "imm": "0xf4b1a8de", "imm2": "0xb98942fa", "rot": 18, "bit": 29, "mask": 8}, + {"i": 145, "op": "rotl", "dst": 7, "src": 6, "src2": 1, "imm": "0x64b6ba2d", "imm2": "0xf9e86793", "rot": 15, "bit": 24, "mask": 8}, + {"i": 146, "op": "xor", "dst": 7, "src": 5, "src2": 3, "imm": "0x41c42b5f", "imm2": "0x7c7e0e39", "rot": 8, "bit": 23, "mask": 2}, + {"i": 147, "op": "mad", "dst": 4, "src": 7, "src2": 4, "imm": "0x3caa807a", "imm2": "0x553a0cec", "rot": 11, "bit": 22, "mask": 8}, + {"i": 148, "op": "rotr", "dst": 6, "src": 5, "src2": 3, "imm": "0x3cb1289a", "imm2": "0x6b36f78a", "rot": 1, "bit": 9, "mask": 16}, + {"i": 149, "op": "mad", "dst": 1, "src": 2, "src2": 4, "imm": "0x95310ea8", "imm2": "0xc533aa6a", "rot": 16, "bit": 17, "mask": 1}, + {"i": 150, "op": "add", "dst": 1, "src": 7, "src2": 7, "imm": "0x2bef10f2", "imm2": "0x0d48ba42", "rot": 8, "bit": 17, "mask": 4}, + {"i": 151, "op": "xor", "dst": 5, "src": 4, "src2": 7, "imm": "0xda997ab2", "imm2": "0xae31d69e", "rot": 11, "bit": 31, "mask": 2}, + {"i": 152, "op": "add", "dst": 7, "src": 0, "src2": 6, "imm": "0xdc5cc080", "imm2": "0xc98dea9c", "rot": 16, "bit": 30, "mask": 2}, + {"i": 153, "op": "mul", "dst": 4, "src": 6, "src2": 7, "imm": "0xbfbf5f6c", "imm2": "0x61f611bb", "rot": 14, "bit": 22, "mask": 2}, + {"i": 154, "op": "mul", "dst": 0, "src": 2, "src2": 3, "imm": "0xa78008c3", "imm2": "0xbad5eeb1", "rot": 10, "bit": 28, "mask": 8}, + {"i": 155, "op": "xor", "dst": 6, "src": 5, "src2": 4, "imm": "0x1a73b866", "imm2": "0x1f5a62c9", "rot": 9, "bit": 27, "mask": 8}, + {"i": 156, "op": "rotr", "dst": 4, "src": 2, "src2": 0, "imm": "0x9c88500c", "imm2": "0xe25dccf9", "rot": 11, "bit": 2, "mask": 16}, + {"i": 157, "op": "rotl", "dst": 1, "src": 4, "src2": 4, "imm": "0xb05e7669", "imm2": "0x9db704b1", "rot": 11, "bit": 28, "mask": 4}, + {"i": 158, "op": "add", "dst": 5, "src": 0, "src2": 6, "imm": "0x18197438", "imm2": "0x6c752dcb", "rot": 11, "bit": 11, "mask": 2}, + {"i": 159, "op": "mad", "dst": 4, "src": 1, "src2": 5, "imm": "0x4796a65e", "imm2": "0x00e08c7a", "rot": 8, "bit": 19, "mask": 4}, + {"i": 160, "op": "rotl", "dst": 4, "src": 7, "src2": 5, "imm": "0x08a03052", "imm2": "0x0204f0ba", "rot": 26, "bit": 5, "mask": 2}, + {"i": 161, "op": "mad", "dst": 3, "src": 0, "src2": 7, "imm": "0xa0603b0e", "imm2": "0x7eee83d5", "rot": 28, "bit": 22, "mask": 16}, + {"i": 162, "op": "rotr", "dst": 3, "src": 1, "src2": 6, "imm": "0x78a3c69d", "imm2": "0x684693a0", "rot": 21, "bit": 23, "mask": 4}, + {"i": 163, "op": "add", "dst": 4, "src": 0, "src2": 7, "imm": "0xf1c46574", "imm2": "0x8e481727", "rot": 9, "bit": 3, "mask": 4}, + {"i": 164, "op": "mulhi", "dst": 0, "src": 4, "src2": 3, "imm": "0x04644afa", "imm2": "0x64bda2b5", "rot": 26, "bit": 16, "mask": 16}, + {"i": 165, "op": "add", "dst": 2, "src": 6, "src2": 2, "imm": "0xac578137", "imm2": "0x550ab406", "rot": 13, "bit": 20, "mask": 16}, + {"i": 166, "op": "rotl", "dst": 0, "src": 4, "src2": 5, "imm": "0x7f564760", "imm2": "0xb9a8b4f8", "rot": 13, "bit": 29, "mask": 1}, + {"i": 167, "op": "add", "dst": 3, "src": 1, "src2": 0, "imm": "0xa33e6706", "imm2": "0xaebb5966", "rot": 12, "bit": 14, "mask": 16}, + {"i": 168, "op": "or", "dst": 3, "src": 5, "src2": 3, "imm": "0x65b2f3eb", "imm2": "0xb1d00d20", "rot": 12, "bit": 2, "mask": 8}, + {"i": 169, "op": "rotr", "dst": 6, "src": 2, "src2": 3, "imm": "0x7f21faf5", "imm2": "0xbbf0d3f9", "rot": 17, "bit": 13, "mask": 8}, + {"i": 170, "op": "xor", "dst": 4, "src": 6, "src2": 2, "imm": "0x162c7140", "imm2": "0x90d404ad", "rot": 26, "bit": 1, "mask": 4}, + {"i": 171, "op": "sub", "dst": 6, "src": 1, "src2": 7, "imm": "0x6ef9c76e", "imm2": "0xfb7ba272", "rot": 31, "bit": 25, "mask": 1}, + {"i": 172, "op": "rotl", "dst": 7, "src": 5, "src2": 4, "imm": "0xde04eb3b", "imm2": "0xd56caa00", "rot": 22, "bit": 21, "mask": 4}, + {"i": 173, "op": "rotl", "dst": 5, "src": 3, "src2": 5, "imm": "0xa9eac934", "imm2": "0x2c338e51", "rot": 15, "bit": 22, "mask": 2}, + {"i": 174, "op": "shfl", "dst": 7, "src": 0, "src2": 3, "imm": "0x700be4e3", "imm2": "0x4bcfc732", "rot": 19, "bit": 6, "mask": 8}, + {"i": 175, "op": "xor", "dst": 0, "src": 5, "src2": 1, "imm": "0x02ccdba9", "imm2": "0xd0915be0", "rot": 15, "bit": 2, "mask": 16}, + {"i": 176, "op": "rotl", "dst": 7, "src": 4, "src2": 1, "imm": "0x489c8165", "imm2": "0xf24b5a4f", "rot": 6, "bit": 22, "mask": 1}, + {"i": 177, "op": "sub", "dst": 7, "src": 0, "src2": 6, "imm": "0x23ad9693", "imm2": "0x9a8c2f7b", "rot": 24, "bit": 2, "mask": 2}, + {"i": 178, "op": "rotl", "dst": 3, "src": 0, "src2": 6, "imm": "0xafa72a42", "imm2": "0x371d74ee", "rot": 30, "bit": 16, "mask": 1}, + {"i": 179, "op": "mad", "dst": 7, "src": 6, "src2": 1, "imm": "0x18a2a3f3", "imm2": "0xb811b951", "rot": 2, "bit": 9, "mask": 2}, + {"i": 180, "op": "rotl", "dst": 6, "src": 4, "src2": 1, "imm": "0xe6c69c0e", "imm2": "0xfc46a951", "rot": 9, "bit": 31, "mask": 4}, + {"i": 181, "op": "xor", "dst": 2, "src": 4, "src2": 7, "imm": "0xbd1b89e4", "imm2": "0xdf4bce5c", "rot": 15, "bit": 19, "mask": 4}, + {"i": 182, "op": "xor", "dst": 2, "src": 7, "src2": 5, "imm": "0x3dd12aed", "imm2": "0xd0756a69", "rot": 13, "bit": 16, "mask": 4}, + {"i": 183, "op": "xor", "dst": 7, "src": 2, "src2": 3, "imm": "0x77ce69d6", "imm2": "0x2b39bdf2", "rot": 8, "bit": 22, "mask": 16}, + {"i": 184, "op": "add", "dst": 1, "src": 2, "src2": 4, "imm": "0xd94d55ac", "imm2": "0x5bb7550f", "rot": 31, "bit": 21, "mask": 1}, + {"i": 185, "op": "or", "dst": 3, "src": 5, "src2": 6, "imm": "0x7b1ce846", "imm2": "0xcc3b8509", "rot": 28, "bit": 9, "mask": 4}, + {"i": 186, "op": "mulhi", "dst": 6, "src": 3, "src2": 0, "imm": "0xa5e24690", "imm2": "0x2200ba81", "rot": 26, "bit": 10, "mask": 16}, + {"i": 187, "op": "or", "dst": 4, "src": 0, "src2": 3, "imm": "0xf6efe759", "imm2": "0xae1f7118", "rot": 19, "bit": 20, "mask": 4}, + {"i": 188, "op": "shfl", "dst": 7, "src": 1, "src2": 5, "imm": "0xdb318b45", "imm2": "0xcec459c9", "rot": 20, "bit": 11, "mask": 2}, + {"i": 189, "op": "add", "dst": 6, "src": 5, "src2": 1, "imm": "0x89e747fe", "imm2": "0x2a354e2d", "rot": 22, "bit": 6, "mask": 1}, + {"i": 190, "op": "xor", "dst": 1, "src": 4, "src2": 2, "imm": "0xc379e617", "imm2": "0x75e9d63b", "rot": 23, "bit": 3, "mask": 2}, + {"i": 191, "op": "mulhi", "dst": 7, "src": 4, "src2": 3, "imm": "0x5a710287", "imm2": "0x7fe4ead6", "rot": 10, "bit": 25, "mask": 4}, + {"i": 192, "op": "rotl", "dst": 2, "src": 1, "src2": 2, "imm": "0x4d5e59a3", "imm2": "0x1e4fef28", "rot": 26, "bit": 0, "mask": 1}, + {"i": 193, "op": "rotl", "dst": 5, "src": 3, "src2": 7, "imm": "0x7444c47d", "imm2": "0xdad5f8be", "rot": 8, "bit": 30, "mask": 2}, + {"i": 194, "op": "shfl", "dst": 4, "src": 5, "src2": 7, "imm": "0x6a225bbb", "imm2": "0xd6532cd7", "rot": 13, "bit": 17, "mask": 16}, + {"i": 195, "op": "xor", "dst": 4, "src": 5, "src2": 3, "imm": "0x68344b9a", "imm2": "0xcb46a38b", "rot": 1, "bit": 27, "mask": 16}, + {"i": 196, "op": "mul", "dst": 1, "src": 3, "src2": 4, "imm": "0xbebf7359", "imm2": "0x3f0890ba", "rot": 18, "bit": 12, "mask": 4}, + {"i": 197, "op": "add", "dst": 5, "src": 2, "src2": 3, "imm": "0xea03e8e7", "imm2": "0x10cfdc71", "rot": 31, "bit": 7, "mask": 8}, + {"i": 198, "op": "add", "dst": 7, "src": 5, "src2": 1, "imm": "0xa7ee0102", "imm2": "0x66e148d3", "rot": 12, "bit": 15, "mask": 1}, + {"i": 199, "op": "sub", "dst": 5, "src": 2, "src2": 4, "imm": "0xc215584e", "imm2": "0x55fce30f", "rot": 30, "bit": 9, "mask": 2}, + {"i": 200, "op": "shfl", "dst": 5, "src": 1, "src2": 1, "imm": "0x308f8358", "imm2": "0x489f1f93", "rot": 13, "bit": 13, "mask": 2}, + {"i": 201, "op": "shfl", "dst": 7, "src": 1, "src2": 5, "imm": "0x713f1957", "imm2": "0x2239f757", "rot": 15, "bit": 7, "mask": 8}, + {"i": 202, "op": "rotr", "dst": 4, "src": 5, "src2": 1, "imm": "0xb037b6e7", "imm2": "0x49a8b528", "rot": 27, "bit": 13, "mask": 16}, + {"i": 203, "op": "xor", "dst": 7, "src": 5, "src2": 1, "imm": "0x56110241", "imm2": "0xefc8386d", "rot": 22, "bit": 20, "mask": 1}, + {"i": 204, "op": "xor", "dst": 7, "src": 0, "src2": 0, "imm": "0x0827fcc7", "imm2": "0xf4f5dd07", "rot": 13, "bit": 7, "mask": 2}, + {"i": 205, "op": "add", "dst": 6, "src": 2, "src2": 0, "imm": "0x8379a4de", "imm2": "0x8558b619", "rot": 26, "bit": 10, "mask": 1}, + {"i": 206, "op": "rotl", "dst": 4, "src": 3, "src2": 3, "imm": "0x091ceef0", "imm2": "0x69b0f72f", "rot": 13, "bit": 7, "mask": 1}, + {"i": 207, "op": "mulhi", "dst": 1, "src": 3, "src2": 4, "imm": "0x758edac1", "imm2": "0x98dd2f21", "rot": 15, "bit": 9, "mask": 1}, + {"i": 208, "op": "mad", "dst": 1, "src": 4, "src2": 4, "imm": "0x78871a1a", "imm2": "0x5e14e1c8", "rot": 19, "bit": 6, "mask": 2}, + {"i": 209, "op": "shfl", "dst": 2, "src": 0, "src2": 2, "imm": "0xf7e0b9aa", "imm2": "0xaecfd347", "rot": 21, "bit": 9, "mask": 4}, + {"i": 210, "op": "add", "dst": 7, "src": 0, "src2": 7, "imm": "0xaa8cb14e", "imm2": "0xf4049c4c", "rot": 24, "bit": 11, "mask": 8}, + {"i": 211, "op": "shfl", "dst": 7, "src": 1, "src2": 6, "imm": "0xc230d919", "imm2": "0xf76d08fb", "rot": 21, "bit": 13, "mask": 16}, + {"i": 212, "op": "xor", "dst": 1, "src": 0, "src2": 2, "imm": "0x31a5af90", "imm2": "0x7eef58ee", "rot": 9, "bit": 12, "mask": 4}, + {"i": 213, "op": "rotl", "dst": 7, "src": 1, "src2": 6, "imm": "0x0db26138", "imm2": "0x8e3c31f9", "rot": 3, "bit": 26, "mask": 2}, + {"i": 214, "op": "rotr", "dst": 4, "src": 7, "src2": 3, "imm": "0x29558100", "imm2": "0xe4b13ad6", "rot": 29, "bit": 24, "mask": 8}, + {"i": 215, "op": "shfl", "dst": 3, "src": 2, "src2": 6, "imm": "0x1b48c3d0", "imm2": "0x5c674ff6", "rot": 5, "bit": 9, "mask": 16}, + {"i": 216, "op": "or", "dst": 5, "src": 1, "src2": 0, "imm": "0xef768632", "imm2": "0x6de9d10d", "rot": 10, "bit": 4, "mask": 4}, + {"i": 217, "op": "sub", "dst": 1, "src": 2, "src2": 5, "imm": "0x88ca7f5a", "imm2": "0x24718a36", "rot": 18, "bit": 31, "mask": 1}, + {"i": 218, "op": "sub", "dst": 6, "src": 5, "src2": 0, "imm": "0xc4a06728", "imm2": "0xdc2a4fd8", "rot": 9, "bit": 9, "mask": 2}, + {"i": 219, "op": "rotl", "dst": 6, "src": 5, "src2": 7, "imm": "0xb7489e47", "imm2": "0xf13795c5", "rot": 4, "bit": 3, "mask": 8}, + {"i": 220, "op": "mulhi", "dst": 2, "src": 0, "src2": 2, "imm": "0x873cd31b", "imm2": "0x3dfbc55d", "rot": 12, "bit": 23, "mask": 8}, + {"i": 221, "op": "or", "dst": 2, "src": 0, "src2": 3, "imm": "0xdc21f099", "imm2": "0xee06f01e", "rot": 2, "bit": 17, "mask": 8}, + {"i": 222, "op": "shfl", "dst": 5, "src": 2, "src2": 6, "imm": "0x36def499", "imm2": "0xa2849d59", "rot": 23, "bit": 4, "mask": 8}, + {"i": 223, "op": "mulhi", "dst": 5, "src": 6, "src2": 7, "imm": "0xfb95fbca", "imm2": "0xc1aac427", "rot": 14, "bit": 11, "mask": 2}, + {"i": 224, "op": "sub", "dst": 0, "src": 6, "src2": 7, "imm": "0x3d9d29c4", "imm2": "0x34d0dcc0", "rot": 17, "bit": 6, "mask": 4}, + {"i": 225, "op": "rotl", "dst": 7, "src": 0, "src2": 5, "imm": "0x93b01b8e", "imm2": "0xfe1d75ac", "rot": 23, "bit": 15, "mask": 1}, + {"i": 226, "op": "or", "dst": 4, "src": 2, "src2": 4, "imm": "0xfed76e8e", "imm2": "0x1c24ecd8", "rot": 2, "bit": 6, "mask": 16}, + {"i": 227, "op": "mul", "dst": 2, "src": 4, "src2": 1, "imm": "0x5795f5b0", "imm2": "0x0566ea2a", "rot": 6, "bit": 28, "mask": 4}, + {"i": 228, "op": "rotl", "dst": 3, "src": 0, "src2": 2, "imm": "0x8c8486de", "imm2": "0xd066aa8f", "rot": 12, "bit": 20, "mask": 1}, + {"i": 229, "op": "rotr", "dst": 0, "src": 4, "src2": 0, "imm": "0x23a3e882", "imm2": "0xaca23902", "rot": 5, "bit": 22, "mask": 16}, + {"i": 230, "op": "add", "dst": 0, "src": 6, "src2": 4, "imm": "0x1d176220", "imm2": "0x2a7fecb2", "rot": 20, "bit": 16, "mask": 2}, + {"i": 231, "op": "shfl", "dst": 1, "src": 2, "src2": 0, "imm": "0x91172787", "imm2": "0xc5d7af28", "rot": 3, "bit": 24, "mask": 4}, + {"i": 232, "op": "mul", "dst": 2, "src": 1, "src2": 2, "imm": "0x0be68835", "imm2": "0xde692bdb", "rot": 30, "bit": 17, "mask": 1}, + {"i": 233, "op": "mad", "dst": 7, "src": 0, "src2": 1, "imm": "0xf90d2db5", "imm2": "0x96c4c175", "rot": 28, "bit": 7, "mask": 4}, + {"i": 234, "op": "rotl", "dst": 5, "src": 2, "src2": 1, "imm": "0x16379736", "imm2": "0x6973b905", "rot": 22, "bit": 17, "mask": 4}, + {"i": 235, "op": "rotr", "dst": 4, "src": 6, "src2": 2, "imm": "0x84292a13", "imm2": "0x0f897740", "rot": 12, "bit": 6, "mask": 8}, + {"i": 236, "op": "mad", "dst": 0, "src": 5, "src2": 1, "imm": "0xeb7de837", "imm2": "0x64f0c302", "rot": 4, "bit": 19, "mask": 1}, + {"i": 237, "op": "xor", "dst": 6, "src": 4, "src2": 4, "imm": "0x6ab4b683", "imm2": "0x20f17adb", "rot": 1, "bit": 0, "mask": 16}, + {"i": 238, "op": "xor", "dst": 4, "src": 6, "src2": 1, "imm": "0x5836b35c", "imm2": "0x3293cc4a", "rot": 16, "bit": 22, "mask": 16}, + {"i": 239, "op": "rotl", "dst": 6, "src": 1, "src2": 6, "imm": "0x769d8bc0", "imm2": "0xdc86c9cc", "rot": 18, "bit": 27, "mask": 16}, + {"i": 240, "op": "add", "dst": 4, "src": 7, "src2": 1, "imm": "0x17dafb4d", "imm2": "0xadce39f3", "rot": 12, "bit": 25, "mask": 8}, + {"i": 241, "op": "sub", "dst": 0, "src": 7, "src2": 4, "imm": "0xd4690bda", "imm2": "0xdab9b27b", "rot": 30, "bit": 21, "mask": 1}, + {"i": 242, "op": "rotr", "dst": 1, "src": 6, "src2": 2, "imm": "0x670a2d0a", "imm2": "0x0612e33c", "rot": 31, "bit": 25, "mask": 2}, + {"i": 243, "op": "add", "dst": 3, "src": 0, "src2": 2, "imm": "0xf2f77d26", "imm2": "0x0e7033b6", "rot": 27, "bit": 29, "mask": 1}, + {"i": 244, "op": "mad", "dst": 2, "src": 7, "src2": 4, "imm": "0xa9eefc9d", "imm2": "0x16166c85", "rot": 18, "bit": 23, "mask": 16}, + {"i": 245, "op": "mad", "dst": 4, "src": 0, "src2": 6, "imm": "0xb26f6c0f", "imm2": "0x0630e821", "rot": 23, "bit": 30, "mask": 4}, + {"i": 246, "op": "mul", "dst": 5, "src": 7, "src2": 2, "imm": "0x269ce4bf", "imm2": "0x1ce28d32", "rot": 30, "bit": 15, "mask": 16}, + {"i": 247, "op": "add", "dst": 3, "src": 5, "src2": 0, "imm": "0xfed2da4e", "imm2": "0x7b2ff6b7", "rot": 25, "bit": 31, "mask": 2}, + {"i": 248, "op": "add", "dst": 0, "src": 7, "src2": 5, "imm": "0x03b2891c", "imm2": "0xb5fad7b1", "rot": 2, "bit": 0, "mask": 4}, + {"i": 249, "op": "mulhi", "dst": 5, "src": 4, "src2": 6, "imm": "0xa69a1e71", "imm2": "0x15f0c0ea", "rot": 4, "bit": 1, "mask": 4}, + {"i": 250, "op": "add", "dst": 5, "src": 2, "src2": 3, "imm": "0x042cd6e3", "imm2": "0xa7e71c2f", "rot": 24, "bit": 11, "mask": 8}, + {"i": 251, "op": "shfl", "dst": 6, "src": 1, "src2": 2, "imm": "0x89c6b683", "imm2": "0x10bbf661", "rot": 24, "bit": 5, "mask": 1}, + {"i": 252, "op": "xor", "dst": 6, "src": 1, "src2": 3, "imm": "0x265c66d6", "imm2": "0xd4a689ed", "rot": 6, "bit": 14, "mask": 8}, + {"i": 253, "op": "mul", "dst": 2, "src": 5, "src2": 5, "imm": "0x890b8201", "imm2": "0x97c36bf3", "rot": 17, "bit": 22, "mask": 4}, + {"i": 254, "op": "add", "dst": 0, "src": 6, "src2": 0, "imm": "0x784a302b", "imm2": "0xb83d78de", "rot": 27, "bit": 16, "mask": 4}, + {"i": 255, "op": "sub", "dst": 2, "src": 4, "src2": 0, "imm": "0x817adb38", "imm2": "0xf3a3534b", "rot": 7, "bit": 22, "mask": 4} + ]}, + "instructions": [ + {"i": 0, "op": "mad", "dst": 2, "src": 3, "src2": 4, "imm": "0xbf7b174d", "imm2": "0x337b762e", "rot": 17, "bit": 2, "mask": 2, "width": 1}, + {"i": 1, "op": "mad", "dst": 2, "src": 1, "src2": 1, "imm": "0xdd04a5da", "imm2": "0x42da7657", "rot": 15, "bit": 30, "mask": 16, "width": 1}, + {"i": 2, "op": "mad", "dst": 2, "src": 3, "src2": 2, "imm": "0x734003fa", "imm2": "0x5bb67700", "rot": 3, "bit": 20, "mask": 1, "width": 1}, + {"i": 3, "op": "xor", "dst": 3, "src": 5, "src2": 5, "imm": "0xc55a1b1c", "imm2": "0xa19720f3", "rot": 7, "bit": 8, "mask": 1, "width": 1}, + {"i": 4, "op": "load", "dst": 7, "src": 2, "src2": 5, "imm": "0xad572dd7", "imm2": "0x9ceb3ea7", "rot": 18, "bit": 30, "mask": 2, "width": 1}, + {"i": 5, "op": "load", "dst": 5, "src": 7, "src2": 3, "imm": "0x769a53be", "imm2": "0x80f9067e", "rot": 12, "bit": 22, "mask": 1, "width": 1}, + {"i": 6, "op": "shfl", "dst": 1, "src": 4, "src2": 0, "imm": "0xd3613d88", "imm2": "0x262fb219", "rot": 10, "bit": 30, "mask": 8, "width": 1}, + {"i": 7, "op": "shfl", "dst": 7, "src": 3, "src2": 4, "imm": "0xce38e42f", "imm2": "0xb868b818", "rot": 11, "bit": 8, "mask": 8, "width": 1}, + {"i": 8, "op": "mulhi", "dst": 1, "src": 5, "src2": 2, "imm": "0xa5eebca5", "imm2": "0x5703a72b", "rot": 13, "bit": 13, "mask": 16, "width": 1}, + {"i": 9, "op": "rotr", "dst": 6, "src": 3, "src2": 4, "imm": "0x17a5a9c7", "imm2": "0xdcfb93a1", "rot": 20, "bit": 27, "mask": 2, "width": 1}, + {"i": 10, "op": "or", "dst": 3, "src": 4, "src2": 1, "imm": "0xccb7d785", "imm2": "0xc335364c", "rot": 14, "bit": 12, "mask": 4, "width": 1}, + {"i": 11, "op": "load", "dst": 4, "src": 3, "src2": 2, "imm": "0x88cb9af3", "imm2": "0x4e7dc10d", "rot": 24, "bit": 17, "mask": 4, "width": 1}, + {"i": 12, "op": "mulhi", "dst": 0, "src": 4, "src2": 4, "imm": "0x45374321", "imm2": "0x3cd91989", "rot": 11, "bit": 4, "mask": 2, "width": 1}, + {"i": 13, "op": "add", "dst": 5, "src": 1, "src2": 2, "imm": "0xc7934706", "imm2": "0xd3177981", "rot": 16, "bit": 30, "mask": 2, "width": 1}, + {"i": 14, "op": "load", "dst": 0, "src": 4, "src2": 3, "imm": "0xfd7f56bb", "imm2": "0x65e14f52", "rot": 13, "bit": 22, "mask": 2, "width": 1}, + {"i": 15, "op": "sub", "dst": 2, "src": 4, "src2": 4, "imm": "0x35a80b49", "imm2": "0x060f2d13", "rot": 16, "bit": 20, "mask": 16, "width": 1}, + {"i": 16, "op": "load", "dst": 2, "src": 0, "src2": 2, "imm": "0xae0a32c2", "imm2": "0x4c2a4cfe", "rot": 8, "bit": 31, "mask": 16, "width": 1}, + {"i": 17, "op": "load", "dst": 7, "src": 2, "src2": 6, "imm": "0x82a84cc3", "imm2": "0x21a38d68", "rot": 15, "bit": 21, "mask": 2, "width": 1}, + {"i": 18, "op": "shfl", "dst": 7, "src": 3, "src2": 3, "imm": "0xa3818806", "imm2": "0x8f66b5c8", "rot": 14, "bit": 6, "mask": 4, "width": 1}, + {"i": 19, "op": "mul", "dst": 5, "src": 0, "src2": 1, "imm": "0xa00de107", "imm2": "0x77bfcaa5", "rot": 3, "bit": 10, "mask": 2, "width": 1}, + {"i": 20, "op": "shfl", "dst": 3, "src": 4, "src2": 7, "imm": "0x1d2b8cab", "imm2": "0x80b4f9a2", "rot": 14, "bit": 25, "mask": 2, "width": 1}, + {"i": 21, "op": "shfl", "dst": 2, "src": 4, "src2": 5, "imm": "0x3ac915d2", "imm2": "0x5fba7bc2", "rot": 16, "bit": 1, "mask": 16, "width": 1}, + {"i": 22, "op": "mulhi", "dst": 6, "src": 2, "src2": 0, "imm": "0xdc3ec8fd", "imm2": "0x599e2fa3", "rot": 22, "bit": 3, "mask": 2, "width": 1}, + {"i": 23, "op": "load", "dst": 6, "src": 1, "src2": 5, "imm": "0x2a6b16d5", "imm2": "0xd73e396f", "rot": 28, "bit": 29, "mask": 2, "width": 1}, + {"i": 24, "op": "mul", "dst": 5, "src": 0, "src2": 7, "imm": "0x376d0223", "imm2": "0xe1c2169a", "rot": 4, "bit": 16, "mask": 16, "width": 1}, + {"i": 25, "op": "rotl", "dst": 5, "src": 7, "src2": 3, "imm": "0x78ad8c60", "imm2": "0x6f5b77d5", "rot": 19, "bit": 11, "mask": 16, "width": 1}, + {"i": 26, "op": "shfl", "dst": 7, "src": 6, "src2": 5, "imm": "0x93915b9f", "imm2": "0x1e61fb6b", "rot": 28, "bit": 23, "mask": 2, "width": 1}, + {"i": 27, "op": "xor", "dst": 0, "src": 5, "src2": 7, "imm": "0x6378fe15", "imm2": "0x66c78f42", "rot": 12, "bit": 31, "mask": 8, "width": 1}, + {"i": 28, "op": "xor", "dst": 0, "src": 4, "src2": 7, "imm": "0x20a57fda", "imm2": "0x088c848e", "rot": 16, "bit": 13, "mask": 4, "width": 1}, + {"i": 29, "op": "sub", "dst": 3, "src": 0, "src2": 2, "imm": "0x49d95fd5", "imm2": "0x1a5f946a", "rot": 6, "bit": 12, "mask": 1, "width": 1}, + {"i": 30, "op": "mul", "dst": 5, "src": 1, "src2": 7, "imm": "0x0a816217", "imm2": "0x405c4f73", "rot": 13, "bit": 27, "mask": 4, "width": 1}, + {"i": 31, "op": "load", "dst": 7, "src": 2, "src2": 2, "imm": "0x09ed045e", "imm2": "0xd69c4715", "rot": 5, "bit": 9, "mask": 2, "width": 1}, + {"i": 32, "op": "load", "dst": 1, "src": 0, "src2": 6, "imm": "0xeb79ea49", "imm2": "0xcc587f5a", "rot": 6, "bit": 8, "mask": 16, "width": 1}, + {"i": 33, "op": "xor", "dst": 5, "src": 6, "src2": 1, "imm": "0x3027401e", "imm2": "0x5f20c27e", "rot": 18, "bit": 9, "mask": 2, "width": 1}, + {"i": 34, "op": "load", "dst": 5, "src": 1, "src2": 3, "imm": "0x0e1cab07", "imm2": "0x09356c5b", "rot": 19, "bit": 31, "mask": 1, "width": 1}, + {"i": 35, "op": "mulhi", "dst": 0, "src": 5, "src2": 2, "imm": "0x90e31357", "imm2": "0xabd32484", "rot": 26, "bit": 5, "mask": 8, "width": 1}, + {"i": 36, "op": "shfl", "dst": 5, "src": 2, "src2": 5, "imm": "0xee9a955f", "imm2": "0x31b3faed", "rot": 8, "bit": 24, "mask": 4, "width": 1}, + {"i": 37, "op": "load", "dst": 7, "src": 0, "src2": 7, "imm": "0x3ba2f832", "imm2": "0x1160dcd3", "rot": 4, "bit": 29, "mask": 1, "width": 1}, + {"i": 38, "op": "add", "dst": 3, "src": 1, "src2": 7, "imm": "0x75ba2fad", "imm2": "0x230c005c", "rot": 4, "bit": 27, "mask": 1, "width": 1}, + {"i": 39, "op": "shfl", "dst": 1, "src": 5, "src2": 3, "imm": "0xdbf37e75", "imm2": "0xb5ac1969", "rot": 30, "bit": 13, "mask": 4, "width": 1}, + {"i": 40, "op": "xor", "dst": 2, "src": 5, "src2": 5, "imm": "0x47f136c5", "imm2": "0x06ce9153", "rot": 19, "bit": 10, "mask": 2, "width": 1}, + {"i": 41, "op": "mad", "dst": 3, "src": 6, "src2": 3, "imm": "0xce13eff8", "imm2": "0x04cc1d55", "rot": 3, "bit": 1, "mask": 4, "width": 1}, + {"i": 42, "op": "sub", "dst": 6, "src": 7, "src2": 1, "imm": "0x6a65ab71", "imm2": "0x8fbc1bcd", "rot": 4, "bit": 1, "mask": 8, "width": 1}, + {"i": 43, "op": "xor", "dst": 7, "src": 0, "src2": 7, "imm": "0xdaeb4928", "imm2": "0xc0423027", "rot": 24, "bit": 11, "mask": 8, "width": 1}, + {"i": 44, "op": "load", "dst": 1, "src": 7, "src2": 7, "imm": "0x778f01c9", "imm2": "0x28cedcea", "rot": 12, "bit": 4, "mask": 16, "width": 1}, + {"i": 45, "op": "mul", "dst": 2, "src": 3, "src2": 2, "imm": "0xf4264f1b", "imm2": "0x0f627d56", "rot": 5, "bit": 28, "mask": 8, "width": 1}, + {"i": 46, "op": "mulhi", "dst": 1, "src": 5, "src2": 1, "imm": "0xffb2147a", "imm2": "0xccde9b05", "rot": 13, "bit": 9, "mask": 2, "width": 1}, + {"i": 47, "op": "sub", "dst": 4, "src": 3, "src2": 5, "imm": "0x73b36234", "imm2": "0x3f5d5997", "rot": 7, "bit": 18, "mask": 2, "width": 1}, + {"i": 48, "op": "rotr", "dst": 2, "src": 6, "src2": 3, "imm": "0x3a4d9aa9", "imm2": "0x212bec7b", "rot": 4, "bit": 29, "mask": 16, "width": 1}, + {"i": 49, "op": "load", "dst": 3, "src": 5, "src2": 2, "imm": "0x626f11df", "imm2": "0x56cd5bfd", "rot": 7, "bit": 1, "mask": 1, "width": 1}, + {"i": 50, "op": "add", "dst": 1, "src": 5, "src2": 6, "imm": "0x81b8bc2c", "imm2": "0x1907970c", "rot": 28, "bit": 7, "mask": 4, "width": 1}, + {"i": 51, "op": "mul", "dst": 0, "src": 2, "src2": 2, "imm": "0xa8848b30", "imm2": "0xef6ac348", "rot": 9, "bit": 15, "mask": 8, "width": 1}, + {"i": 52, "op": "add", "dst": 0, "src": 2, "src2": 0, "imm": "0x4f92b968", "imm2": "0x699fd448", "rot": 22, "bit": 6, "mask": 4, "width": 1}, + {"i": 53, "op": "add", "dst": 1, "src": 0, "src2": 2, "imm": "0x2bb965af", "imm2": "0x77b1520d", "rot": 2, "bit": 12, "mask": 8, "width": 1}, + {"i": 54, "op": "rotl", "dst": 7, "src": 1, "src2": 0, "imm": "0x553e678b", "imm2": "0x3cc8eae0", "rot": 14, "bit": 20, "mask": 2, "width": 1}, + {"i": 55, "op": "add", "dst": 3, "src": 7, "src2": 2, "imm": "0x7b0fe07a", "imm2": "0xa54c55a0", "rot": 10, "bit": 1, "mask": 1, "width": 1}, + {"i": 56, "op": "load", "dst": 6, "src": 7, "src2": 4, "imm": "0x01eba9aa", "imm2": "0x2758c0f7", "rot": 14, "bit": 15, "mask": 4, "width": 1}, + {"i": 57, "op": "rotr", "dst": 1, "src": 5, "src2": 2, "imm": "0x1f5267b3", "imm2": "0x236f5a27", "rot": 2, "bit": 31, "mask": 16, "width": 1}, + {"i": 58, "op": "load", "dst": 5, "src": 4, "src2": 3, "imm": "0xa9954a9b", "imm2": "0x6a54d4e8", "rot": 11, "bit": 10, "mask": 16, "width": 1}, + {"i": 59, "op": "load", "dst": 6, "src": 2, "src2": 4, "imm": "0x9923ff88", "imm2": "0x9357254e", "rot": 16, "bit": 1, "mask": 16, "width": 1}, + {"i": 60, "op": "mad", "dst": 3, "src": 5, "src2": 0, "imm": "0xc0cc51a6", "imm2": "0x3fd7701b", "rot": 20, "bit": 1, "mask": 4, "width": 1}, + {"i": 61, "op": "add", "dst": 5, "src": 7, "src2": 7, "imm": "0xaf9dd72d", "imm2": "0xad7493e7", "rot": 7, "bit": 31, "mask": 16, "width": 1}, + {"i": 62, "op": "add", "dst": 4, "src": 6, "src2": 2, "imm": "0x89841d87", "imm2": "0x1e07c3d9", "rot": 6, "bit": 27, "mask": 1, "width": 1}, + {"i": 63, "op": "rotl", "dst": 5, "src": 4, "src2": 2, "imm": "0xae210f8d", "imm2": "0x8e499ba4", "rot": 19, "bit": 9, "mask": 1, "width": 1} + ] +} diff --git a/proto-cuda/packs-ca3-shadow/sh256x27/program.metal b/proto-cuda/packs-ca3-shadow/sh256x27/program.metal new file mode 100644 index 000000000..2830702a7 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x27/program.metal @@ -0,0 +1,368 @@ +#include +using namespace metal; + +#define MASK 0x0fffffffu +constant uint SEEDW[8] = { 0x67a9a7beu, 0x1a155b25u, 0xfddfb732u, 0x4b5af2e8u, 0xc55caf33u, 0xa27c13b7u, 0x06628a48u, 0x03852469u }; + +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 = r3 * r4 + r2; // 0 + r2 = r1 * r1 + r2; // 1 + r2 = r3 * r2 + r2; // 2 + r3 = r3 ^ r5; // 3 + r7 = r7 ^ dataset[r2 & MASK]; // 4 + r5 = r5 ^ dataset[r7 & MASK]; // 5 + r1 = r1 ^ simd_shuffle_xor(r4, (ushort)8); // 6 + r7 = r7 ^ simd_shuffle_xor(r3, (ushort)8); // 7 + r1 = mulhi(r1, r5); // 8 + r6 = rotr_var(r6, r3); // 9 + r3 = r3 | r4; // 10 + r4 = r4 ^ dataset[r3 & MASK]; // 11 + r0 = mulhi(r0, r4); // 12 + r5 = r5 + r1 + select(0xc7934706u, 0xd3177981u, ((sel >> 30u) & 1u) != 0u); // 13 + r0 = r0 ^ dataset[r4 & MASK]; // 14 + r2 = r2 - r4; // 15 + r2 = r2 ^ dataset[r0 & MASK]; // 16 + r7 = r7 ^ dataset[r2 & MASK]; // 17 + r7 = r7 ^ simd_shuffle_xor(r3, (ushort)4); // 18 + r5 = r5 * r0; // 19 + r3 = r3 ^ simd_shuffle_xor(r4, (ushort)2); // 20 + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)16); // 21 + r6 = mulhi(r6, r2); // 22 + r6 = r6 ^ dataset[r1 & MASK]; // 23 + r5 = r5 * r0; // 24 + r5 = rotl_imm(r5, 19u); // 25 + r7 = r7 ^ simd_shuffle_xor(r6, (ushort)2); // 26 + r0 = r0 ^ r5; // 27 + r0 = r0 ^ r4; // 28 + r3 = r3 - r0; // 29 + r5 = r5 * r1; // 30 + r7 = r7 ^ dataset[r2 & MASK]; // 31 + r1 = r1 ^ dataset[r0 & MASK]; // 32 + r5 = r5 ^ r6; // 33 + r5 = r5 ^ dataset[r1 & MASK]; // 34 + r0 = mulhi(r0, r5); // 35 + r5 = r5 ^ simd_shuffle_xor(r2, (ushort)4); // 36 + r7 = r7 ^ dataset[r0 & MASK]; // 37 + r3 = r3 + r1 + select(0x75ba2fadu, 0x230c005cu, ((sel >> 27u) & 1u) != 0u); // 38 + r1 = r1 ^ simd_shuffle_xor(r5, (ushort)4); // 39 + r2 = r2 ^ r5; // 40 + r3 = r6 * r3 + r3; // 41 + r6 = r6 - r7; // 42 + r7 = r7 ^ r0; // 43 + r1 = r1 ^ dataset[r7 & MASK]; // 44 + r2 = r2 * r3; // 45 + r1 = mulhi(r1, r5); // 46 + r4 = r4 - r3; // 47 + r2 = rotr_var(r2, r6); // 48 + r3 = r3 ^ dataset[r5 & MASK]; // 49 + r1 = r1 + r5 + select(0x81b8bc2cu, 0x1907970cu, ((sel >> 7u) & 1u) != 0u); // 50 + r0 = r0 * r2; // 51 + r0 = r0 + r2 + select(0x4f92b968u, 0x699fd448u, ((sel >> 6u) & 1u) != 0u); // 52 + r1 = r1 + r0 + select(0x2bb965afu, 0x77b1520du, ((sel >> 12u) & 1u) != 0u); // 53 + r7 = rotl_imm(r7, 14u); // 54 + r3 = r3 + r7 + select(0x7b0fe07au, 0xa54c55a0u, ((sel >> 1u) & 1u) != 0u); // 55 + r6 = r6 ^ dataset[r7 & MASK]; // 56 + r1 = rotr_var(r1, r5); // 57 + r5 = r5 ^ dataset[r4 & MASK]; // 58 + r6 = r6 ^ dataset[r2 & MASK]; // 59 + r3 = r5 * r0 + r3; // 60 + r5 = r5 + r7 + select(0xaf9dd72du, 0xad7493e7u, ((sel >> 31u) & 1u) != 0u); // 61 + r4 = r4 + r6 + select(0x89841d87u, 0x1e07c3d9u, ((sel >> 27u) & 1u) != 0u); // 62 + r5 = rotl_imm(r5, 19u); // 63 + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 27 passes after instruction 63, no load + for (uint sh = 0u; sh < 27u; ++sh) { + r5 = r5 + r2 + select(0x92199f99u, 0x8bc12da9u, ((sel >> 18u) & 1u) != 0u); // s0 add + r0 = r0 + r7 + select(0x8d72d3adu, 0x63079e5au, ((sel >> 26u) & 1u) != 0u); // s1 add + r6 = r6 ^ simd_shuffle_xor(r3, (ushort)2); // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + select(0xb21b4babu, 0x5d4c7a60u, ((sel >> 31u) & 1u) != 0u); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + select(0x2fe0e98bu, 0xc88e2942u, ((sel >> 16u) & 1u) != 0u); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + r6 = r6 ^ simd_shuffle_xor(r1, (ushort)4); // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + r2 = r2 ^ simd_shuffle_xor(r6, (ushort)4); // s12 shfl + r1 = r1 + r5 + select(0xbdf8f9a5u, 0xbc48c63eu, ((sel >> 25u) & 1u) != 0u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)8); // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + select(0x45c37cecu, 0x96e8f127u, ((sel >> 1u) & 1u) != 0u); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = mulhi(r6, r0); // s28 mulhi + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)2); // s29 shfl + r1 = r1 ^ simd_shuffle_xor(r6, (ushort)1); // s30 shfl + r1 = r1 + r6 + select(0x37985632u, 0xb1cdb2abu, ((sel >> 1u) & 1u) != 0u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + r3 = r3 ^ simd_shuffle_xor(r4, (ushort)2); // s33 shfl + r0 = r0 ^ simd_shuffle_xor(r3, (ushort)4); // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + select(0x804e777eu, 0x856e0180u, ((sel >> 0u) & 1u) != 0u); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + select(0x0b06c8a7u, 0xe9bd0cc4u, ((sel >> 2u) & 1u) != 0u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = mulhi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = mulhi(r4, r3); // s44 mulhi + r6 = r6 + r7 + select(0xee822e17u, 0xcdcb63f6u, ((sel >> 12u) & 1u) != 0u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + r4 = r4 ^ simd_shuffle_xor(r3, (ushort)8); // s47 shfl + r6 = mulhi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + select(0x3dfad1b6u, 0xd4758987u, ((sel >> 10u) & 1u) != 0u); // s56 add + r4 = r4 + r1 + select(0xfca75bc2u, 0x0602d6beu, ((sel >> 0u) & 1u) != 0u); // s57 add + r5 = mulhi(r5, r6); // s58 mulhi + r2 = r2 ^ simd_shuffle_xor(r1, (ushort)2); // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + select(0xd71c02ffu, 0x8596687au, ((sel >> 6u) & 1u) != 0u); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + r7 = r7 ^ simd_shuffle_xor(r5, (ushort)2); // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + select(0x3c6fe15du, 0x08ac5733u, ((sel >> 0u) & 1u) != 0u); // s72 add + r3 = r3 ^ simd_shuffle_xor(r2, (ushort)8); // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + select(0x295d5faeu, 0xc100b495u, ((sel >> 1u) & 1u) != 0u); // s77 add + r3 = mulhi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + select(0x274a9221u, 0x5cc59530u, ((sel >> 15u) & 1u) != 0u); // s81 add + r7 = r7 + r3 + select(0xc8651f8eu, 0x141479ecu, ((sel >> 5u) & 1u) != 0u); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + r2 = r2 ^ simd_shuffle_xor(r5, (ushort)16); // s85 shfl + r3 = r3 ^ r2; // s86 xor + r5 = r5 ^ simd_shuffle_xor(r7, (ushort)2); // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + select(0x53f915c2u, 0x883c0c92u, ((sel >> 18u) & 1u) != 0u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + select(0xe2be00a5u, 0x3cc5bd20u, ((sel >> 31u) & 1u) != 0u); // s91 add + r7 = r7 ^ simd_shuffle_xor(r2, (ushort)1); // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + select(0x423fd9c9u, 0xbfd646cbu, ((sel >> 17u) & 1u) != 0u); // s101 add + r7 = r7 + r6 + select(0x8d3c011du, 0x19b74a43u, ((sel >> 11u) & 1u) != 0u); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + select(0x8ce14721u, 0x7dcb7e18u, ((sel >> 15u) & 1u) != 0u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = mulhi(r2, r0); // s109 mulhi + r1 = mulhi(r1, r0); // s110 mulhi + r0 = r0 + r2 + select(0x2d9fc6b9u, 0x3c179ad8u, ((sel >> 28u) & 1u) != 0u); // s111 add + r2 = mulhi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + select(0x502138e2u, 0x47359729u, ((sel >> 22u) & 1u) != 0u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = mulhi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + r4 = r4 ^ simd_shuffle_xor(r2, (ushort)2); // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + r7 = r7 ^ simd_shuffle_xor(r2, (ushort)4); // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + select(0x33dff776u, 0x6c57e4e7u, ((sel >> 15u) & 1u) != 0u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + select(0x5db25b34u, 0xe8212c0cu, ((sel >> 30u) & 1u) != 0u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = mulhi(r0, r5); // s138 mulhi + r2 = r2 + r7 + select(0x218d4090u, 0xd44ff710u, ((sel >> 10u) & 1u) != 0u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + r3 = r3 ^ simd_shuffle_xor(r6, (ushort)1); // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + select(0xf4b1a8deu, 0xb98942fau, ((sel >> 29u) & 1u) != 0u); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + select(0x2bef10f2u, 0x0d48ba42u, ((sel >> 17u) & 1u) != 0u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + select(0xdc5cc080u, 0xc98dea9cu, ((sel >> 30u) & 1u) != 0u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + select(0x18197438u, 0x6c752dcbu, ((sel >> 11u) & 1u) != 0u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + select(0xf1c46574u, 0x8e481727u, ((sel >> 3u) & 1u) != 0u); // s163 add + r0 = mulhi(r0, r4); // s164 mulhi + r2 = r2 + r6 + select(0xac578137u, 0x550ab406u, ((sel >> 20u) & 1u) != 0u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + select(0xa33e6706u, 0xaebb5966u, ((sel >> 14u) & 1u) != 0u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + r7 = r7 ^ simd_shuffle_xor(r0, (ushort)8); // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + select(0xd94d55acu, 0x5bb7550fu, ((sel >> 21u) & 1u) != 0u); // s184 add + r3 = r3 | r5; // s185 or + r6 = mulhi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)2); // s188 shfl + r6 = r6 + r5 + select(0x89e747feu, 0x2a354e2du, ((sel >> 6u) & 1u) != 0u); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = mulhi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + r4 = r4 ^ simd_shuffle_xor(r5, (ushort)16); // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + select(0xea03e8e7u, 0x10cfdc71u, ((sel >> 7u) & 1u) != 0u); // s197 add + r7 = r7 + r5 + select(0xa7ee0102u, 0x66e148d3u, ((sel >> 15u) & 1u) != 0u); // s198 add + r5 = r5 - r2; // s199 sub + r5 = r5 ^ simd_shuffle_xor(r1, (ushort)2); // s200 shfl + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)8); // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + select(0x8379a4deu, 0x8558b619u, ((sel >> 10u) & 1u) != 0u); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = mulhi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + r2 = r2 ^ simd_shuffle_xor(r0, (ushort)4); // s209 shfl + r7 = r7 + r0 + select(0xaa8cb14eu, 0xf4049c4cu, ((sel >> 11u) & 1u) != 0u); // s210 add + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)16); // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + r3 = r3 ^ simd_shuffle_xor(r2, (ushort)16); // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = mulhi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + r5 = r5 ^ simd_shuffle_xor(r2, (ushort)8); // s222 shfl + r5 = mulhi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + select(0x1d176220u, 0x2a7fecb2u, ((sel >> 16u) & 1u) != 0u); // s230 add + r1 = r1 ^ simd_shuffle_xor(r2, (ushort)4); // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + select(0x17dafb4du, 0xadce39f3u, ((sel >> 25u) & 1u) != 0u); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + select(0xf2f77d26u, 0x0e7033b6u, ((sel >> 29u) & 1u) != 0u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + select(0xfed2da4eu, 0x7b2ff6b7u, ((sel >> 31u) & 1u) != 0u); // s247 add + r0 = r0 + r7 + select(0x03b2891cu, 0xb5fad7b1u, ((sel >> 0u) & 1u) != 0u); // s248 add + r5 = mulhi(r5, r4); // s249 mulhi + r5 = r5 + r2 + select(0x042cd6e3u, 0xa7e71c2fu, ((sel >> 11u) & 1u) != 0u); // s250 add + r6 = r6 ^ simd_shuffle_xor(r1, (ushort)1); // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + select(0x784a302bu, 0xb83d78deu, ((sel >> 16u) & 1u) != 0u); // s254 add + r2 = r2 - r4; // s255 sub + } + } + uint lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((ulong)hi << 32) | (ulong)lo; +} diff --git a/proto-cuda/packs-ca3-shadow/sh256x27/program_bound.metal b/proto-cuda/packs-ca3-shadow/sh256x27/program_bound.metal new file mode 100644 index 000000000..7a8da2d3e --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x27/program_bound.metal @@ -0,0 +1,370 @@ +#include +using namespace metal; + +#define MASK 0x0fffffffu +constant uint SEEDW[8] = { 0x67a9a7beu, 0x1a155b25u, 0xfddfb732u, 0x4b5af2e8u, 0xc55caf33u, 0xa27c13b7u, 0x06628a48u, 0x03852469u }; + +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 = r3 * r4 + r2; // 0 + r2 = r1 * r1 + r2; // 1 + r2 = r3 * r2 + r2; // 2 + r3 = r3 ^ r5; // 3 + r7 = r7 ^ dataset[r2 & MASK]; // 4 + r5 = r5 ^ dataset[r7 & MASK]; // 5 + r1 = r1 ^ simd_shuffle_xor(r4, (ushort)8); // 6 + r7 = r7 ^ simd_shuffle_xor(r3, (ushort)8); // 7 + r1 = mulhi(r1, r5); // 8 + r6 = rotr_var(r6, r3); // 9 + r3 = r3 | r4; // 10 + r4 = r4 ^ dataset[r3 & MASK]; // 11 + r0 = mulhi(r0, r4); // 12 + r5 = r5 + r1 + select(0xc7934706u, 0xd3177981u, ((sel >> 30u) & 1u) != 0u); // 13 + r0 = r0 ^ dataset[r4 & MASK]; // 14 + r2 = r2 - r4; // 15 + r2 = r2 ^ dataset[r0 & MASK]; // 16 + r7 = r7 ^ dataset[r2 & MASK]; // 17 + r7 = r7 ^ simd_shuffle_xor(r3, (ushort)4); // 18 + r5 = r5 * r0; // 19 + r3 = r3 ^ simd_shuffle_xor(r4, (ushort)2); // 20 + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)16); // 21 + r6 = mulhi(r6, r2); // 22 + r6 = r6 ^ dataset[r1 & MASK]; // 23 + r5 = r5 * r0; // 24 + r5 = rotl_imm(r5, 19u); // 25 + r7 = r7 ^ simd_shuffle_xor(r6, (ushort)2); // 26 + r0 = r0 ^ r5; // 27 + r0 = r0 ^ r4; // 28 + r3 = r3 - r0; // 29 + r5 = r5 * r1; // 30 + r7 = r7 ^ dataset[r2 & MASK]; // 31 + r1 = r1 ^ dataset[r0 & MASK]; // 32 + r5 = r5 ^ r6; // 33 + r5 = r5 ^ dataset[r1 & MASK]; // 34 + r0 = mulhi(r0, r5); // 35 + r5 = r5 ^ simd_shuffle_xor(r2, (ushort)4); // 36 + r7 = r7 ^ dataset[r0 & MASK]; // 37 + r3 = r3 + r1 + select(0x75ba2fadu, 0x230c005cu, ((sel >> 27u) & 1u) != 0u); // 38 + r1 = r1 ^ simd_shuffle_xor(r5, (ushort)4); // 39 + r2 = r2 ^ r5; // 40 + r3 = r6 * r3 + r3; // 41 + r6 = r6 - r7; // 42 + r7 = r7 ^ r0; // 43 + r1 = r1 ^ dataset[r7 & MASK]; // 44 + r2 = r2 * r3; // 45 + r1 = mulhi(r1, r5); // 46 + r4 = r4 - r3; // 47 + r2 = rotr_var(r2, r6); // 48 + r3 = r3 ^ dataset[r5 & MASK]; // 49 + r1 = r1 + r5 + select(0x81b8bc2cu, 0x1907970cu, ((sel >> 7u) & 1u) != 0u); // 50 + r0 = r0 * r2; // 51 + r0 = r0 + r2 + select(0x4f92b968u, 0x699fd448u, ((sel >> 6u) & 1u) != 0u); // 52 + r1 = r1 + r0 + select(0x2bb965afu, 0x77b1520du, ((sel >> 12u) & 1u) != 0u); // 53 + r7 = rotl_imm(r7, 14u); // 54 + r3 = r3 + r7 + select(0x7b0fe07au, 0xa54c55a0u, ((sel >> 1u) & 1u) != 0u); // 55 + r6 = r6 ^ dataset[r7 & MASK]; // 56 + r1 = rotr_var(r1, r5); // 57 + r5 = r5 ^ dataset[r4 & MASK]; // 58 + r6 = r6 ^ dataset[r2 & MASK]; // 59 + r3 = r5 * r0 + r3; // 60 + r5 = r5 + r7 + select(0xaf9dd72du, 0xad7493e7u, ((sel >> 31u) & 1u) != 0u); // 61 + r4 = r4 + r6 + select(0x89841d87u, 0x1e07c3d9u, ((sel >> 27u) & 1u) != 0u); // 62 + r5 = rotl_imm(r5, 19u); // 63 + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 27 passes after instruction 63, no load + for (uint sh = 0u; sh < 27u; ++sh) { + r5 = r5 + r2 + select(0x92199f99u, 0x8bc12da9u, ((sel >> 18u) & 1u) != 0u); // s0 add + r0 = r0 + r7 + select(0x8d72d3adu, 0x63079e5au, ((sel >> 26u) & 1u) != 0u); // s1 add + r6 = r6 ^ simd_shuffle_xor(r3, (ushort)2); // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + select(0xb21b4babu, 0x5d4c7a60u, ((sel >> 31u) & 1u) != 0u); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + select(0x2fe0e98bu, 0xc88e2942u, ((sel >> 16u) & 1u) != 0u); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + r6 = r6 ^ simd_shuffle_xor(r1, (ushort)4); // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + r2 = r2 ^ simd_shuffle_xor(r6, (ushort)4); // s12 shfl + r1 = r1 + r5 + select(0xbdf8f9a5u, 0xbc48c63eu, ((sel >> 25u) & 1u) != 0u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)8); // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + select(0x45c37cecu, 0x96e8f127u, ((sel >> 1u) & 1u) != 0u); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = mulhi(r6, r0); // s28 mulhi + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)2); // s29 shfl + r1 = r1 ^ simd_shuffle_xor(r6, (ushort)1); // s30 shfl + r1 = r1 + r6 + select(0x37985632u, 0xb1cdb2abu, ((sel >> 1u) & 1u) != 0u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + r3 = r3 ^ simd_shuffle_xor(r4, (ushort)2); // s33 shfl + r0 = r0 ^ simd_shuffle_xor(r3, (ushort)4); // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + select(0x804e777eu, 0x856e0180u, ((sel >> 0u) & 1u) != 0u); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + select(0x0b06c8a7u, 0xe9bd0cc4u, ((sel >> 2u) & 1u) != 0u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = mulhi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = mulhi(r4, r3); // s44 mulhi + r6 = r6 + r7 + select(0xee822e17u, 0xcdcb63f6u, ((sel >> 12u) & 1u) != 0u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + r4 = r4 ^ simd_shuffle_xor(r3, (ushort)8); // s47 shfl + r6 = mulhi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + select(0x3dfad1b6u, 0xd4758987u, ((sel >> 10u) & 1u) != 0u); // s56 add + r4 = r4 + r1 + select(0xfca75bc2u, 0x0602d6beu, ((sel >> 0u) & 1u) != 0u); // s57 add + r5 = mulhi(r5, r6); // s58 mulhi + r2 = r2 ^ simd_shuffle_xor(r1, (ushort)2); // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + select(0xd71c02ffu, 0x8596687au, ((sel >> 6u) & 1u) != 0u); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + r7 = r7 ^ simd_shuffle_xor(r5, (ushort)2); // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + select(0x3c6fe15du, 0x08ac5733u, ((sel >> 0u) & 1u) != 0u); // s72 add + r3 = r3 ^ simd_shuffle_xor(r2, (ushort)8); // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + select(0x295d5faeu, 0xc100b495u, ((sel >> 1u) & 1u) != 0u); // s77 add + r3 = mulhi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + select(0x274a9221u, 0x5cc59530u, ((sel >> 15u) & 1u) != 0u); // s81 add + r7 = r7 + r3 + select(0xc8651f8eu, 0x141479ecu, ((sel >> 5u) & 1u) != 0u); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + r2 = r2 ^ simd_shuffle_xor(r5, (ushort)16); // s85 shfl + r3 = r3 ^ r2; // s86 xor + r5 = r5 ^ simd_shuffle_xor(r7, (ushort)2); // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + select(0x53f915c2u, 0x883c0c92u, ((sel >> 18u) & 1u) != 0u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + select(0xe2be00a5u, 0x3cc5bd20u, ((sel >> 31u) & 1u) != 0u); // s91 add + r7 = r7 ^ simd_shuffle_xor(r2, (ushort)1); // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + select(0x423fd9c9u, 0xbfd646cbu, ((sel >> 17u) & 1u) != 0u); // s101 add + r7 = r7 + r6 + select(0x8d3c011du, 0x19b74a43u, ((sel >> 11u) & 1u) != 0u); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + select(0x8ce14721u, 0x7dcb7e18u, ((sel >> 15u) & 1u) != 0u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = mulhi(r2, r0); // s109 mulhi + r1 = mulhi(r1, r0); // s110 mulhi + r0 = r0 + r2 + select(0x2d9fc6b9u, 0x3c179ad8u, ((sel >> 28u) & 1u) != 0u); // s111 add + r2 = mulhi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + select(0x502138e2u, 0x47359729u, ((sel >> 22u) & 1u) != 0u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = mulhi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + r4 = r4 ^ simd_shuffle_xor(r2, (ushort)2); // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + r7 = r7 ^ simd_shuffle_xor(r2, (ushort)4); // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + select(0x33dff776u, 0x6c57e4e7u, ((sel >> 15u) & 1u) != 0u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + select(0x5db25b34u, 0xe8212c0cu, ((sel >> 30u) & 1u) != 0u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = mulhi(r0, r5); // s138 mulhi + r2 = r2 + r7 + select(0x218d4090u, 0xd44ff710u, ((sel >> 10u) & 1u) != 0u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + r3 = r3 ^ simd_shuffle_xor(r6, (ushort)1); // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + select(0xf4b1a8deu, 0xb98942fau, ((sel >> 29u) & 1u) != 0u); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + select(0x2bef10f2u, 0x0d48ba42u, ((sel >> 17u) & 1u) != 0u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + select(0xdc5cc080u, 0xc98dea9cu, ((sel >> 30u) & 1u) != 0u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + select(0x18197438u, 0x6c752dcbu, ((sel >> 11u) & 1u) != 0u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + select(0xf1c46574u, 0x8e481727u, ((sel >> 3u) & 1u) != 0u); // s163 add + r0 = mulhi(r0, r4); // s164 mulhi + r2 = r2 + r6 + select(0xac578137u, 0x550ab406u, ((sel >> 20u) & 1u) != 0u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + select(0xa33e6706u, 0xaebb5966u, ((sel >> 14u) & 1u) != 0u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + r7 = r7 ^ simd_shuffle_xor(r0, (ushort)8); // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + select(0xd94d55acu, 0x5bb7550fu, ((sel >> 21u) & 1u) != 0u); // s184 add + r3 = r3 | r5; // s185 or + r6 = mulhi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)2); // s188 shfl + r6 = r6 + r5 + select(0x89e747feu, 0x2a354e2du, ((sel >> 6u) & 1u) != 0u); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = mulhi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + r4 = r4 ^ simd_shuffle_xor(r5, (ushort)16); // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + select(0xea03e8e7u, 0x10cfdc71u, ((sel >> 7u) & 1u) != 0u); // s197 add + r7 = r7 + r5 + select(0xa7ee0102u, 0x66e148d3u, ((sel >> 15u) & 1u) != 0u); // s198 add + r5 = r5 - r2; // s199 sub + r5 = r5 ^ simd_shuffle_xor(r1, (ushort)2); // s200 shfl + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)8); // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + select(0x8379a4deu, 0x8558b619u, ((sel >> 10u) & 1u) != 0u); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = mulhi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + r2 = r2 ^ simd_shuffle_xor(r0, (ushort)4); // s209 shfl + r7 = r7 + r0 + select(0xaa8cb14eu, 0xf4049c4cu, ((sel >> 11u) & 1u) != 0u); // s210 add + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)16); // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + r3 = r3 ^ simd_shuffle_xor(r2, (ushort)16); // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = mulhi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + r5 = r5 ^ simd_shuffle_xor(r2, (ushort)8); // s222 shfl + r5 = mulhi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + select(0x1d176220u, 0x2a7fecb2u, ((sel >> 16u) & 1u) != 0u); // s230 add + r1 = r1 ^ simd_shuffle_xor(r2, (ushort)4); // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + select(0x17dafb4du, 0xadce39f3u, ((sel >> 25u) & 1u) != 0u); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + select(0xf2f77d26u, 0x0e7033b6u, ((sel >> 29u) & 1u) != 0u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + select(0xfed2da4eu, 0x7b2ff6b7u, ((sel >> 31u) & 1u) != 0u); // s247 add + r0 = r0 + r7 + select(0x03b2891cu, 0xb5fad7b1u, ((sel >> 0u) & 1u) != 0u); // s248 add + r5 = mulhi(r5, r4); // s249 mulhi + r5 = r5 + r2 + select(0x042cd6e3u, 0xa7e71c2fu, ((sel >> 11u) & 1u) != 0u); // s250 add + r6 = r6 ^ simd_shuffle_xor(r1, (ushort)1); // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + select(0x784a302bu, 0xb83d78deu, ((sel >> 16u) & 1u) != 0u); // s254 add + r2 = r2 - r4; // s255 sub + } + } + uint lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((ulong)hi << 32) | (ulong)lo; +} diff --git a/proto-cuda/packs-ca3-shadow/sh256x27/vectors.h b/proto-cuda/packs-ca3-shadow/sh256x27/vectors.h new file mode 100644 index 000000000..17ce44606 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x27/vectors.h @@ -0,0 +1,57 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Expected outputs: igneum-pow (Rust) CPU interpreter, generator v2, memory-hard dataset +#pragma once +#ifdef __cplusplus +#include +#else +#include +#endif + +#define IGNEUM_VEC_WARPS 3 +static const uint32_t IGNEUM_VEC_BASE[IGNEUM_VEC_WARPS] = { 0u, 4096u, 1000000u }; +static const uint64_t IGNEUM_VEC_OUT[IGNEUM_VEC_WARPS][32] = { + { // base nonce 0 + 0x2576769ee4a14c8dull, 0x6408f60b1f606a96ull, 0x8e1825542dbd3636ull, 0xb25c17d8820ae079ull, 0xb6e1a578d06323b2ull, 0x8bea2965eaa47f55ull, 0x3684da53df965532ull, 0x3392668d50a45aadull, + 0x5e78d14aaaadce6eull, 0xcb0a7992844c9192ull, 0xfe4ad7fbc328f9efull, 0x7e64515d7d5941a4ull, 0x425e4eedb7b0ca4bull, 0x4f57a8f93ce317b8ull, 0x081360e3cf765b3aull, 0x1e9e919c50331254ull, + 0x998e7a76718adcbaull, 0xde5600e2b1838d9full, 0x4f85d0539779a267ull, 0x40661123ffbce40cull, 0x95b247ca86ff61dcull, 0xbe2bf61b9fcd1362ull, 0xfd6d6687a07997daull, 0x9935965e43f25045ull, + 0x27fe1552873c0b40ull, 0x972c952c83cf5ea9ull, 0x525b975fb9610333ull, 0x4f81431408d27e2dull, 0x6375d14f804f061full, 0xff6492be48775872ull, 0x81b2e098e1a01f8full, 0xc58ddcb717dd3370ull + }, + { // base nonce 4096 + 0x1ce77a600ec573b4ull, 0xb126a41f83521e45ull, 0x875547a82d6145fcull, 0xd4b04bf258ce4941ull, 0xe24c23e2b2371ad6ull, 0x7687a4beddbbd270ull, 0x63b9346ba234a0beull, 0x2500fb30f5e7eb20ull, + 0x7a185d59a30e3333ull, 0xa3c14cec7e2bcce2ull, 0x5730e39d367c6b21ull, 0x03e10c84ac832a3full, 0xf6dd88e0208019efull, 0xd539425d3bc497fcull, 0x71461f5d0c23f626ull, 0xa4c64db97fb4a425ull, + 0x61f56436538b61f8ull, 0x749b10eccde2f0bcull, 0xbe447d39b5f3aa29ull, 0x0e4ada60a90088b7ull, 0x3eda0e2db0bc9f9eull, 0xf90d81a21a10089cull, 0x7cf50a8f14d2430eull, 0x14601dea6a5d8625ull, + 0x23c448ee2f31a26dull, 0x60e5c3d4b218c0c2ull, 0x46ed8a924ac431fbull, 0xcc77440ffbe5c23dull, 0x9a15a2da9d6ba946ull, 0x37117ce37ca8c606ull, 0x69b85ea283597190ull, 0x03600a05ffba0055ull + }, + { // base nonce 1000000 + 0x6b390e64bbdd91ceull, 0x9b34dd7b05214a6bull, 0x60c14bcda3df2768ull, 0x557f5df495f92ad5ull, 0x5ac883b3090f344bull, 0xdec4058df6f8b088ull, 0x6e3dcb56bbb79ec9ull, 0x6450bb96c6c686bdull, + 0xc2021c81ef714e23ull, 0xcc0b3f77c0cf7bf6ull, 0x03cb474759279b0dull, 0x93cf69a5cd961b9cull, 0x61318f0c14d7e3deull, 0x9df2144c49b171beull, 0xa335ecfaf465e9cdull, 0x4f8661257c1706c3ull, + 0xab374ea37f8e253cull, 0x117242d65e8ebdb4ull, 0x9022069313586cd7ull, 0xe97f096510d6ad03ull, 0xa93d76b12894ffc5ull, 0x7823119022da1590ull, 0xde6f389ece0c83e9ull, 0x84e97ea778e4fb15ull, + 0x23d0802d386a21c8ull, 0xbaacd8512e9bbb31ull, 0x10522970c58234bbull, 0x90f0b64b38eed0b1ull, 0xb250988d2986d15bull, 0xf81e101bb298710full, 0x20e9cca5ade09113ull, 0x91c944d603539c62ull + } +}; + +// Dataset self-test: dataset[0..15] and dataset[IGNEUM_MASK] (268435455). +static const uint32_t IGNEUM_DS_HEAD[16] = { + 0xfdad4319u, 0x1a7b68e1u, 0xde6db608u, 0x13d73892u, 0xd17f447au, 0xb2221ccfu, 0x9db004bdu, 0x57d7d367u, + 0xdbc4cf34u, 0x697c009au, 0xc43af1d4u, 0x97f12b2eu, 0x74c37cd0u, 0xc651ea15u, 0x665a6d29u, 0x22330a2du +}; +static const uint32_t IGNEUM_DS_LAST_INDEX = 268435455u; +static const uint32_t IGNEUM_DS_LAST = 0xa83e7aa6u; +// 64 sampled dataset words (index, value) computed on the Mac. +#define IGNEUM_DS_SAMPLES 64 +static const uint32_t IGNEUM_DS_SAMPLE_INDEX[IGNEUM_DS_SAMPLES] = { + 59471966u, 217795994u, 208353206u, 42483309u, 172547758u, 148076330u, 183853158u, 214389424u, 267488061u, 169781097u, 184093494u, 153880993u, 84977930u, 46426879u, 3093825u, 225364072u, 44593546u, 260713159u, 168250303u, 52384140u, 223401610u, 45554030u, 95410555u, 175039924u, 79171087u, 267580473u, 24168642u, 37981670u, 171551130u, 195559979u, 204611762u, 140997658u, 138925853u, 86637313u, 20736778u, 219665210u, 160430336u, 264654675u, 8013395u, 228945585u, 213884386u, 104419827u, 44185464u, 142737231u, 99284897u, 132475900u, 61861762u, 132056166u, 262388043u, 91878046u, 117353561u, 124768597u, 71352993u, 190698941u, 46055428u, 55281366u, 165145231u, 106810753u, 171985651u, 232085256u, 159510492u, 40072060u, 209107596u, 39023794u +}; +static const uint32_t IGNEUM_DS_SAMPLE_VALUE[IGNEUM_DS_SAMPLES] = { + 0x3230bc7bu, 0x7fbfe2c9u, 0xb2690991u, 0x1745c7c5u, 0x0ab0ccafu, 0x1bf87d6bu, 0x160139fdu, 0x719817acu, 0x0155df4bu, 0xbe1e86c3u, 0x680bcd6cu, 0x79c3dc6cu, 0x181e7e5fu, 0x0713a109u, 0xc705dd9fu, 0x3933b7a8u, 0xdd1c0431u, 0x50522b30u, 0xa0020b38u, 0xbff39e96u, 0x21b67e18u, 0x740f8db3u, 0x2baba568u, 0x2c9bef83u, 0x0ad9b671u, 0xc4327869u, 0x7b4fd7d0u, 0x2c29965fu, 0xec56f15fu, 0x61111746u, 0x303a1d6eu, 0xbddcfd1au, 0xf829a355u, 0x6d5df2a9u, 0x01ab8e44u, 0x06d13507u, 0xda8dcfc6u, 0x01a703e1u, 0xafe7d2c1u, 0xc091c3a2u, 0xac1814feu, 0x6e6ff62au, 0x8fdf01bau, 0xdd3f7159u, 0xdfa0d75cu, 0x26684c35u, 0x7f441e63u, 0x88df2570u, 0x8aa4d5ebu, 0xcc816c05u, 0x434df890u, 0xcd392ad6u, 0x1ab4cb63u, 0x595926fau, 0x7cd76b41u, 0x20cb95c4u, 0x13cf823fu, 0xf9daf901u, 0xff9af40au, 0x2c7dfa51u, 0x871206dbu, 0x938c116cu, 0xb64bf199u, 0x5751f874u +}; +// Cache self-test (memory-hard mode): cache[0..15], the last 16 words, and FNV-1a 64 over all 2^26 words. +static const uint32_t IGNEUM_CACHE_HEAD[16] = { + 0x355a86d2u, 0x7957db1cu, 0xd21772afu, 0x6fc1e09bu, 0xd55ce61du, 0x6e6a278bu, 0xd3f543ceu, 0x223d8e82u, + 0x143ab337u, 0x2e9f05bdu, 0x2eb389bfu, 0x0c6e449eu, 0x5cfa4222u, 0xba6560feu, 0x8e3e1aa4u, 0xdbcc1d53u +}; +static const uint32_t IGNEUM_CACHE_LAST[16] = { + 0x41190d91u, 0xbd277957u, 0x22ddbb49u, 0x6986f207u, 0xdf69a4d6u, 0x26401a3au, 0x818230fbu, 0xc417122du, + 0x3597b211u, 0xb553ce55u, 0xcf39cc0du, 0x3b7fc43au, 0x3fd43b00u, 0x67e1c80eu, 0xffa7ea7du, 0xca2960abu +}; +static const uint64_t IGNEUM_CACHE_FNV64 = 0x48c4f5bf24166b2eull; diff --git a/proto-cuda/packs-ca3-shadow/sh256x27/vectors.json b/proto-cuda/packs-ca3-shadow/sh256x27/vectors.json new file mode 100644 index 000000000..c481669bf --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x27/vectors.json @@ -0,0 +1,36 @@ +{ + "seed": "igneum-genesis", + "day": "2026-10-03", + "dataset_mode": "memory-hard", + "dataset_log2_words": 28, + "mask": "0x0fffffff", + "lanes": 32, + "source": "igneum-pow (Rust) CPU interpreter, generator v2, memory-hard dataset", + "warps": [ + {"base_nonce": 0, "expected": [ + "0x2576769ee4a14c8d", "0x6408f60b1f606a96", "0x8e1825542dbd3636", "0xb25c17d8820ae079", "0xb6e1a578d06323b2", "0x8bea2965eaa47f55", "0x3684da53df965532", "0x3392668d50a45aad", + "0x5e78d14aaaadce6e", "0xcb0a7992844c9192", "0xfe4ad7fbc328f9ef", "0x7e64515d7d5941a4", "0x425e4eedb7b0ca4b", "0x4f57a8f93ce317b8", "0x081360e3cf765b3a", "0x1e9e919c50331254", + "0x998e7a76718adcba", "0xde5600e2b1838d9f", "0x4f85d0539779a267", "0x40661123ffbce40c", "0x95b247ca86ff61dc", "0xbe2bf61b9fcd1362", "0xfd6d6687a07997da", "0x9935965e43f25045", + "0x27fe1552873c0b40", "0x972c952c83cf5ea9", "0x525b975fb9610333", "0x4f81431408d27e2d", "0x6375d14f804f061f", "0xff6492be48775872", "0x81b2e098e1a01f8f", "0xc58ddcb717dd3370" + ]}, + {"base_nonce": 4096, "expected": [ + "0x1ce77a600ec573b4", "0xb126a41f83521e45", "0x875547a82d6145fc", "0xd4b04bf258ce4941", "0xe24c23e2b2371ad6", "0x7687a4beddbbd270", "0x63b9346ba234a0be", "0x2500fb30f5e7eb20", + "0x7a185d59a30e3333", "0xa3c14cec7e2bcce2", "0x5730e39d367c6b21", "0x03e10c84ac832a3f", "0xf6dd88e0208019ef", "0xd539425d3bc497fc", "0x71461f5d0c23f626", "0xa4c64db97fb4a425", + "0x61f56436538b61f8", "0x749b10eccde2f0bc", "0xbe447d39b5f3aa29", "0x0e4ada60a90088b7", "0x3eda0e2db0bc9f9e", "0xf90d81a21a10089c", "0x7cf50a8f14d2430e", "0x14601dea6a5d8625", + "0x23c448ee2f31a26d", "0x60e5c3d4b218c0c2", "0x46ed8a924ac431fb", "0xcc77440ffbe5c23d", "0x9a15a2da9d6ba946", "0x37117ce37ca8c606", "0x69b85ea283597190", "0x03600a05ffba0055" + ]}, + {"base_nonce": 1000000, "expected": [ + "0x6b390e64bbdd91ce", "0x9b34dd7b05214a6b", "0x60c14bcda3df2768", "0x557f5df495f92ad5", "0x5ac883b3090f344b", "0xdec4058df6f8b088", "0x6e3dcb56bbb79ec9", "0x6450bb96c6c686bd", + "0xc2021c81ef714e23", "0xcc0b3f77c0cf7bf6", "0x03cb474759279b0d", "0x93cf69a5cd961b9c", "0x61318f0c14d7e3de", "0x9df2144c49b171be", "0xa335ecfaf465e9cd", "0x4f8661257c1706c3", + "0xab374ea37f8e253c", "0x117242d65e8ebdb4", "0x9022069313586cd7", "0xe97f096510d6ad03", "0xa93d76b12894ffc5", "0x7823119022da1590", "0xde6f389ece0c83e9", "0x84e97ea778e4fb15", + "0x23d0802d386a21c8", "0xbaacd8512e9bbb31", "0x10522970c58234bb", "0x90f0b64b38eed0b1", "0xb250988d2986d15b", "0xf81e101bb298710f", "0x20e9cca5ade09113", "0x91c944d603539c62" + ]} + ], + "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" +} diff --git a/proto-cuda/packs-ca3-shadow/sh256x40/kernel.cl b/proto-cuda/packs-ca3-shadow/sh256x40/kernel.cl new file mode 100644 index 000000000..776a24c7f --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x40/kernel.cl @@ -0,0 +1,538 @@ +// 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 ^ 0x67a9a7beu; x += 0x9e3779b9u; x = splitmix32(x); r0 = x ^ 0x1a155b25u; } // SEEDW[0], 0x9e3779b9u * 1u, SEEDW[1] + { uint x = nonce ^ 0x1a155b25u; x += 0x3c6ef372u; x = splitmix32(x); r1 = x ^ 0xfddfb732u; } // SEEDW[1], 0x9e3779b9u * 2u, SEEDW[2] + { uint x = nonce ^ 0xfddfb732u; x += 0xdaa66d2bu; x = splitmix32(x); r2 = x ^ 0x4b5af2e8u; } // SEEDW[2], 0x9e3779b9u * 3u, SEEDW[3] + { uint x = nonce ^ 0x4b5af2e8u; x += 0x78dde6e4u; x = splitmix32(x); r3 = x ^ 0xc55caf33u; } // SEEDW[3], 0x9e3779b9u * 4u, SEEDW[4] + { uint x = nonce ^ 0xc55caf33u; x += 0x1715609du; x = splitmix32(x); r4 = x ^ 0xa27c13b7u; } // SEEDW[4], 0x9e3779b9u * 5u, SEEDW[5] + { uint x = nonce ^ 0xa27c13b7u; x += 0xb54cda56u; x = splitmix32(x); r5 = x ^ 0x06628a48u; } // SEEDW[5], 0x9e3779b9u * 6u, SEEDW[6] + { uint x = nonce ^ 0x06628a48u; x += 0x5384540fu; x = splitmix32(x); r6 = x ^ 0x03852469u; } // SEEDW[6], 0x9e3779b9u * 7u, SEEDW[7] + { uint x = nonce ^ 0x03852469u; x += 0xf1bbcdc8u; x = splitmix32(x); r7 = x ^ 0x67a9a7beu; } // SEEDW[7], 0x9e3779b9u * 8u, SEEDW[0] + + for (uint it = 0u; it < 8u; ++it) { + uint sel = r0; + r2 = r3 * r4 + r2; // 0 mad + r2 = r1 * r1 + r2; // 1 mad + r2 = r3 * r2 + r2; // 2 mad + r3 = r3 ^ r5; // 3 xor + r7 = r7 ^ ds[r2 & mask]; // 4 load + r5 = r5 ^ ds[r7 & mask]; // 5 load + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r1 = r1 ^ t_; } // 6 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r7 = r7 ^ t_; } // 7 shfl + r1 = mul_hi(r1, r5); // 8 mulhi + r6 = rotr_var(r6, r3); // 9 rotr + r3 = r3 | r4; // 10 or + r4 = r4 ^ ds[r3 & mask]; // 11 load + r0 = mul_hi(r0, r4); // 12 mulhi + r5 = r5 + r1 + ((((sel >> 30u) & 1u) != 0u) ? 0xd3177981u : 0xc7934706u); // 13 add + r0 = r0 ^ ds[r4 & mask]; // 14 load + r2 = r2 - r4; // 15 sub + r2 = r2 ^ ds[r0 & mask]; // 16 load + r7 = r7 ^ ds[r2 & mask]; // 17 load + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r7 = r7 ^ t_; } // 18 shfl + r5 = r5 * r0; // 19 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // 20 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 16u); r2 = r2 ^ t_; } // 21 shfl + r6 = mul_hi(r6, r2); // 22 mulhi + r6 = r6 ^ ds[r1 & mask]; // 23 load + r5 = r5 * r0; // 24 mul + r5 = rotl_imm(r5, 19u); // 25 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 2u); r7 = r7 ^ t_; } // 26 shfl + r0 = r0 ^ r5; // 27 xor + r0 = r0 ^ r4; // 28 xor + r3 = r3 - r0; // 29 sub + r5 = r5 * r1; // 30 mul + r7 = r7 ^ ds[r2 & mask]; // 31 load + r1 = r1 ^ ds[r0 & mask]; // 32 load + r5 = r5 ^ r6; // 33 xor + r5 = r5 ^ ds[r1 & mask]; // 34 load + r0 = mul_hi(r0, r5); // 35 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r5 = r5 ^ t_; } // 36 shfl + r7 = r7 ^ ds[r0 & mask]; // 37 load + r3 = r3 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0x230c005cu : 0x75ba2fadu); // 38 add + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 4u); r1 = r1 ^ t_; } // 39 shfl + r2 = r2 ^ r5; // 40 xor + r3 = r6 * r3 + r3; // 41 mad + r6 = r6 - r7; // 42 sub + r7 = r7 ^ r0; // 43 xor + r1 = r1 ^ ds[r7 & mask]; // 44 load + r2 = r2 * r3; // 45 mul + r1 = mul_hi(r1, r5); // 46 mulhi + r4 = r4 - r3; // 47 sub + r2 = rotr_var(r2, r6); // 48 rotr + r3 = r3 ^ ds[r5 & mask]; // 49 load + r1 = r1 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x1907970cu : 0x81b8bc2cu); // 50 add + r0 = r0 * r2; // 51 mul + r0 = r0 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x699fd448u : 0x4f92b968u); // 52 add + r1 = r1 + r0 + ((((sel >> 12u) & 1u) != 0u) ? 0x77b1520du : 0x2bb965afu); // 53 add + r7 = rotl_imm(r7, 14u); // 54 rotl + r3 = r3 + r7 + ((((sel >> 1u) & 1u) != 0u) ? 0xa54c55a0u : 0x7b0fe07au); // 55 add + r6 = r6 ^ ds[r7 & mask]; // 56 load + r1 = rotr_var(r1, r5); // 57 rotr + r5 = r5 ^ ds[r4 & mask]; // 58 load + r6 = r6 ^ ds[r2 & mask]; // 59 load + r3 = r5 * r0 + r3; // 60 mad + r5 = r5 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0xad7493e7u : 0xaf9dd72du); // 61 add + r4 = r4 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x1e07c3d9u : 0x89841d87u); // 62 add + r5 = rotl_imm(r5, 19u); // 63 rotl + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 40 passes after instruction 63, no load + for (uint sh = 0u; sh < 40u; ++sh) { + r5 = r5 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x8bc12da9u : 0x92199f99u); // s0 add + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x63079e5au : 0x8d72d3adu); // s1 add + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 2u); r6 = r6 ^ t_; } // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + ((((sel >> 31u) & 1u) != 0u) ? 0x5d4c7a60u : 0xb21b4babu); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + ((((sel >> 16u) & 1u) != 0u) ? 0xc88e2942u : 0x2fe0e98bu); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r6 = r6 ^ t_; } // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 4u); r2 = r2 ^ t_; } // s12 shfl + r1 = r1 + r5 + ((((sel >> 25u) & 1u) != 0u) ? 0xbc48c63eu : 0xbdf8f9a5u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r2 = r2 ^ t_; } // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + ((((sel >> 1u) & 1u) != 0u) ? 0x96e8f127u : 0x45c37cecu); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = mul_hi(r6, r0); // s28 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r2 = r2 ^ t_; } // s29 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r1 = r1 ^ t_; } // s30 shfl + r1 = r1 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0xb1cdb2abu : 0x37985632u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // s33 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r0 = r0 ^ t_; } // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x856e0180u : 0x804e777eu); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xe9bd0cc4u : 0x0b06c8a7u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = mul_hi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = mul_hi(r4, r3); // s44 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xcdcb63f6u : 0xee822e17u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r4 = r4 ^ t_; } // s47 shfl + r6 = mul_hi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0xd4758987u : 0x3dfad1b6u); // s56 add + r4 = r4 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x0602d6beu : 0xfca75bc2u); // s57 add + r5 = mul_hi(r5, r6); // s58 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r2 = r2 ^ t_; } // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0x8596687au : 0xd71c02ffu); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 2u); r7 = r7 ^ t_; } // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0x08ac5733u : 0x3c6fe15du); // s72 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r3 = r3 ^ t_; } // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + ((((sel >> 1u) & 1u) != 0u) ? 0xc100b495u : 0x295d5faeu); // s77 add + r3 = mul_hi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + ((((sel >> 15u) & 1u) != 0u) ? 0x5cc59530u : 0x274a9221u); // s81 add + r7 = r7 + r3 + ((((sel >> 5u) & 1u) != 0u) ? 0x141479ecu : 0xc8651f8eu); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r2 = r2 ^ t_; } // s85 shfl + r3 = r3 ^ r2; // s86 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 2u); r5 = r5 ^ t_; } // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x883c0c92u : 0x53f915c2u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + ((((sel >> 31u) & 1u) != 0u) ? 0x3cc5bd20u : 0xe2be00a5u); // s91 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 1u); r7 = r7 ^ t_; } // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + ((((sel >> 17u) & 1u) != 0u) ? 0xbfd646cbu : 0x423fd9c9u); // s101 add + r7 = r7 + r6 + ((((sel >> 11u) & 1u) != 0u) ? 0x19b74a43u : 0x8d3c011du); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + ((((sel >> 15u) & 1u) != 0u) ? 0x7dcb7e18u : 0x8ce14721u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = mul_hi(r2, r0); // s109 mulhi + r1 = mul_hi(r1, r0); // s110 mulhi + r0 = r0 + r2 + ((((sel >> 28u) & 1u) != 0u) ? 0x3c179ad8u : 0x2d9fc6b9u); // s111 add + r2 = mul_hi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + ((((sel >> 22u) & 1u) != 0u) ? 0x47359729u : 0x502138e2u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = mul_hi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 2u); r4 = r4 ^ t_; } // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r7 = r7 ^ t_; } // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x6c57e4e7u : 0x33dff776u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + ((((sel >> 30u) & 1u) != 0u) ? 0xe8212c0cu : 0x5db25b34u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = mul_hi(r0, r5); // s138 mulhi + r2 = r2 + r7 + ((((sel >> 10u) & 1u) != 0u) ? 0xd44ff710u : 0x218d4090u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r3 = r3 ^ t_; } // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + ((((sel >> 29u) & 1u) != 0u) ? 0xb98942fau : 0xf4b1a8deu); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + ((((sel >> 17u) & 1u) != 0u) ? 0x0d48ba42u : 0x2bef10f2u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + ((((sel >> 30u) & 1u) != 0u) ? 0xc98dea9cu : 0xdc5cc080u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0x6c752dcbu : 0x18197438u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + ((((sel >> 3u) & 1u) != 0u) ? 0x8e481727u : 0xf1c46574u); // s163 add + r0 = mul_hi(r0, r4); // s164 mulhi + r2 = r2 + r6 + ((((sel >> 20u) & 1u) != 0u) ? 0x550ab406u : 0xac578137u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + ((((sel >> 14u) & 1u) != 0u) ? 0xaebb5966u : 0xa33e6706u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 8u); r7 = r7 ^ t_; } // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x5bb7550fu : 0xd94d55acu); // s184 add + r3 = r3 | r5; // s185 or + r6 = mul_hi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r7 = r7 ^ t_; } // s188 shfl + r6 = r6 + r5 + ((((sel >> 6u) & 1u) != 0u) ? 0x2a354e2du : 0x89e747feu); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = mul_hi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r4 = r4 ^ t_; } // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + ((((sel >> 7u) & 1u) != 0u) ? 0x10cfdc71u : 0xea03e8e7u); // s197 add + r7 = r7 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x66e148d3u : 0xa7ee0102u); // s198 add + r5 = r5 - r2; // s199 sub + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r5 = r5 ^ t_; } // s200 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 8u); r7 = r7 ^ t_; } // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0x8558b619u : 0x8379a4deu); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = mul_hi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 4u); r2 = r2 ^ t_; } // s209 shfl + r7 = r7 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0xf4049c4cu : 0xaa8cb14eu); // s210 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 16u); r7 = r7 ^ t_; } // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 16u); r3 = r3 ^ t_; } // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = mul_hi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r5 = r5 ^ t_; } // s222 shfl + r5 = mul_hi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0x2a7fecb2u : 0x1d176220u); // s230 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r1 = r1 ^ t_; } // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + ((((sel >> 25u) & 1u) != 0u) ? 0xadce39f3u : 0x17dafb4du); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + ((((sel >> 29u) & 1u) != 0u) ? 0x0e7033b6u : 0xf2f77d26u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + ((((sel >> 31u) & 1u) != 0u) ? 0x7b2ff6b7u : 0xfed2da4eu); // s247 add + r0 = r0 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0xb5fad7b1u : 0x03b2891cu); // s248 add + r5 = mul_hi(r5, r4); // s249 mulhi + r5 = r5 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0xa7e71c2fu : 0x042cd6e3u); // s250 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 1u); r6 = r6 ^ t_; } // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0xb83d78deu : 0x784a302bu); // s254 add + r2 = r2 - r4; // s255 sub + } + } + uint lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((ulong)hi << 32) | (ulong)lo; +} + +#if IGNEUM_EXCHANGE != 0 +// Reports the sub-group size this device uses for a work-group of IGNEUM_GROUP items. host.c runs it only when the +// per-kernel query (clGetKernelSubGroupInfoKHR on igneum_hash) is unavailable; that query is preferred because a +// compiler may pick a different wave width per kernel (RDNA: wave32 or wave64). See WAVEFRONT.md. +IGNEUM_KERNEL_HASH void igneum_probe_subgroup(__global uint* out) { + if (get_local_id(0) == 0u) { out[0] = get_sub_group_size(); out[1] = get_num_sub_groups(); } +} +#endif diff --git a/proto-cuda/packs-ca3-shadow/sh256x40/kernel.cu b/proto-cuda/packs-ca3-shadow/sh256x40/kernel.cu new file mode 100644 index 000000000..41461c8dd --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x40/kernel.cu @@ -0,0 +1,423 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Bit-exact twin of the Metal kernel for the same seed (see proto-cuda/CHECKLIST.md and program.metal). +// Compiled ahead of time by nvcc together with proto-cuda/host.cu. No NVRTC. +#include +#include +#include "program.h" +#include "memhard.h" + +__device__ __forceinline__ uint32_t splitmix32(uint32_t x) { + x ^= x >> 16; x *= 0x7feb352du; + x ^= x >> 15; x *= 0x846ca68bu; + x ^= x >> 16; + return x; +} +// n is a literal in 1..31 at every call site, so both shift amounts are in 1..31. +__device__ __forceinline__ uint32_t rotl_imm(uint32_t x, uint32_t n) { return (x << n) | (x >> (32u - n)); } +// n is masked to 0..31; the second shift amount is masked too, so n == 0 gives x. +__device__ __forceinline__ uint32_t rotr_var(uint32_t x, uint32_t n) { n &= 31u; return (x >> n) | (x << ((32u - n) & 31u)); } +__device__ __forceinline__ uint32_t ds_elem(uint32_t i, uint32_t d0, uint32_t d1) { + uint32_t x = i ^ d0; + x *= 0x9E3779B1u; x ^= x >> 15; + x += d1; + x *= 0x85EBCA77u; x ^= x >> 13; + x *= 0xC2B2AE3Du; x ^= x >> 16; + return x; +} + +// Memory-hard dataset (MEMHARD.md). One thread per cache segment; one thread per 64-byte dataset item. +// The core functions (mh_cache_segment, mh_item) are in memhard.h and are also compiled for the host. +__global__ void igneum_cache_fill(uint32_t* cache, uint32_t nSegments) { + uint32_t seg = blockIdx.x * blockDim.x + threadIdx.x; + if (seg < nSegments) mh_cache_segment(cache, seg); +} +__global__ void igneum_build(uint32_t* ds, const uint32_t* cache, uint32_t nItems) { + uint32_t t = blockIdx.x * blockDim.x + threadIdx.x; + if (t < nItems) { + uint32_t s[16]; + mh_item(cache, t, s); + uint32_t* d = ds + (size_t)t * 16u; + for (uint32_t i = 0u; i < 16u; ++i) d[i] = s[i]; + } +} + +// One hash per thread. blockDim.x is a multiple of 32; lane = threadIdx.x & 31 and every +// __shfl_xor_sync stays inside the lane's own warp, exactly like simd_shuffle_xor inside a +// 32-wide Metal SIMD group. Control flow is uniform, so the full 0xffffffff member mask is valid. +__global__ void igneum_hash(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask) { + uint32_t gid = blockIdx.x * blockDim.x + threadIdx.x; + uint32_t nonce = baseNonce + gid; + uint32_t r0, r1, r2, r3, r4, r5, r6, r7; + { uint32_t x = nonce ^ 0x67a9a7beu; x += 0x9e3779b9u; x = splitmix32(x); r0 = x ^ 0x1a155b25u; } // SEEDW[0], 0x9e3779b9u * 1u, SEEDW[1] + { uint32_t x = nonce ^ 0x1a155b25u; x += 0x3c6ef372u; x = splitmix32(x); r1 = x ^ 0xfddfb732u; } // SEEDW[1], 0x9e3779b9u * 2u, SEEDW[2] + { uint32_t x = nonce ^ 0xfddfb732u; x += 0xdaa66d2bu; x = splitmix32(x); r2 = x ^ 0x4b5af2e8u; } // SEEDW[2], 0x9e3779b9u * 3u, SEEDW[3] + { uint32_t x = nonce ^ 0x4b5af2e8u; x += 0x78dde6e4u; x = splitmix32(x); r3 = x ^ 0xc55caf33u; } // SEEDW[3], 0x9e3779b9u * 4u, SEEDW[4] + { uint32_t x = nonce ^ 0xc55caf33u; x += 0x1715609du; x = splitmix32(x); r4 = x ^ 0xa27c13b7u; } // SEEDW[4], 0x9e3779b9u * 5u, SEEDW[5] + { uint32_t x = nonce ^ 0xa27c13b7u; x += 0xb54cda56u; x = splitmix32(x); r5 = x ^ 0x06628a48u; } // SEEDW[5], 0x9e3779b9u * 6u, SEEDW[6] + { uint32_t x = nonce ^ 0x06628a48u; x += 0x5384540fu; x = splitmix32(x); r6 = x ^ 0x03852469u; } // SEEDW[6], 0x9e3779b9u * 7u, SEEDW[7] + { uint32_t x = nonce ^ 0x03852469u; x += 0xf1bbcdc8u; x = splitmix32(x); r7 = x ^ 0x67a9a7beu; } // SEEDW[7], 0x9e3779b9u * 8u, SEEDW[0] + + for (uint32_t it = 0u; it < 8u; ++it) { + uint32_t sel = r0; + r2 = r3 * r4 + r2; // 0 mad + r2 = r1 * r1 + r2; // 1 mad + r2 = r3 * r2 + r2; // 2 mad + r3 = r3 ^ r5; // 3 xor + r7 = r7 ^ ds[r2 & mask]; // 4 load + r5 = r5 ^ ds[r7 & mask]; // 5 load + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r4, 8); // 6 shfl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r3, 8); // 7 shfl + r1 = __umulhi(r1, r5); // 8 mulhi + r6 = rotr_var(r6, r3); // 9 rotr + r3 = r3 | r4; // 10 or + r4 = r4 ^ ds[r3 & mask]; // 11 load + r0 = __umulhi(r0, r4); // 12 mulhi + r5 = r5 + r1 + ((((sel >> 30u) & 1u) != 0u) ? 0xd3177981u : 0xc7934706u); // 13 add + r0 = r0 ^ ds[r4 & mask]; // 14 load + r2 = r2 - r4; // 15 sub + r2 = r2 ^ ds[r0 & mask]; // 16 load + r7 = r7 ^ ds[r2 & mask]; // 17 load + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r3, 4); // 18 shfl + r5 = r5 * r0; // 19 mul + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // 20 shfl + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 16); // 21 shfl + r6 = __umulhi(r6, r2); // 22 mulhi + r6 = r6 ^ ds[r1 & mask]; // 23 load + r5 = r5 * r0; // 24 mul + r5 = rotl_imm(r5, 19u); // 25 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r6, 2); // 26 shfl + r0 = r0 ^ r5; // 27 xor + r0 = r0 ^ r4; // 28 xor + r3 = r3 - r0; // 29 sub + r5 = r5 * r1; // 30 mul + r7 = r7 ^ ds[r2 & mask]; // 31 load + r1 = r1 ^ ds[r0 & mask]; // 32 load + r5 = r5 ^ r6; // 33 xor + r5 = r5 ^ ds[r1 & mask]; // 34 load + r0 = __umulhi(r0, r5); // 35 mulhi + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // 36 shfl + r7 = r7 ^ ds[r0 & mask]; // 37 load + r3 = r3 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0x230c005cu : 0x75ba2fadu); // 38 add + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r5, 4); // 39 shfl + r2 = r2 ^ r5; // 40 xor + r3 = r6 * r3 + r3; // 41 mad + r6 = r6 - r7; // 42 sub + r7 = r7 ^ r0; // 43 xor + r1 = r1 ^ ds[r7 & mask]; // 44 load + r2 = r2 * r3; // 45 mul + r1 = __umulhi(r1, r5); // 46 mulhi + r4 = r4 - r3; // 47 sub + r2 = rotr_var(r2, r6); // 48 rotr + r3 = r3 ^ ds[r5 & mask]; // 49 load + r1 = r1 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x1907970cu : 0x81b8bc2cu); // 50 add + r0 = r0 * r2; // 51 mul + r0 = r0 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x699fd448u : 0x4f92b968u); // 52 add + r1 = r1 + r0 + ((((sel >> 12u) & 1u) != 0u) ? 0x77b1520du : 0x2bb965afu); // 53 add + r7 = rotl_imm(r7, 14u); // 54 rotl + r3 = r3 + r7 + ((((sel >> 1u) & 1u) != 0u) ? 0xa54c55a0u : 0x7b0fe07au); // 55 add + r6 = r6 ^ ds[r7 & mask]; // 56 load + r1 = rotr_var(r1, r5); // 57 rotr + r5 = r5 ^ ds[r4 & mask]; // 58 load + r6 = r6 ^ ds[r2 & mask]; // 59 load + r3 = r5 * r0 + r3; // 60 mad + r5 = r5 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0xad7493e7u : 0xaf9dd72du); // 61 add + r4 = r4 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x1e07c3d9u : 0x89841d87u); // 62 add + r5 = rotl_imm(r5, 19u); // 63 rotl + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 40 passes after instruction 63, no load + for (uint32_t sh = 0u; sh < 40u; ++sh) { + r5 = r5 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x8bc12da9u : 0x92199f99u); // s0 add + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x63079e5au : 0x8d72d3adu); // s1 add + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r3, 2); // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + ((((sel >> 31u) & 1u) != 0u) ? 0x5d4c7a60u : 0xb21b4babu); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + ((((sel >> 16u) & 1u) != 0u) ? 0xc88e2942u : 0x2fe0e98bu); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r1, 4); // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r6, 4); // s12 shfl + r1 = r1 + r5 + ((((sel >> 25u) & 1u) != 0u) ? 0xbc48c63eu : 0xbdf8f9a5u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 8); // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + ((((sel >> 1u) & 1u) != 0u) ? 0x96e8f127u : 0x45c37cecu); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = __umulhi(r6, r0); // s28 mulhi + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // s29 shfl + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r6, 1); // s30 shfl + r1 = r1 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0xb1cdb2abu : 0x37985632u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // s33 shfl + r0 = r0 ^ __shfl_xor_sync(0xffffffffu, r3, 4); // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x856e0180u : 0x804e777eu); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xe9bd0cc4u : 0x0b06c8a7u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = __umulhi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = __umulhi(r4, r3); // s44 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xcdcb63f6u : 0xee822e17u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r3, 8); // s47 shfl + r6 = __umulhi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0xd4758987u : 0x3dfad1b6u); // s56 add + r4 = r4 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x0602d6beu : 0xfca75bc2u); // s57 add + r5 = __umulhi(r5, r6); // s58 mulhi + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0x8596687au : 0xd71c02ffu); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r5, 2); // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0x08ac5733u : 0x3c6fe15du); // s72 add + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r2, 8); // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + ((((sel >> 1u) & 1u) != 0u) ? 0xc100b495u : 0x295d5faeu); // s77 add + r3 = __umulhi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + ((((sel >> 15u) & 1u) != 0u) ? 0x5cc59530u : 0x274a9221u); // s81 add + r7 = r7 + r3 + ((((sel >> 5u) & 1u) != 0u) ? 0x141479ecu : 0xc8651f8eu); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r5, 16); // s85 shfl + r3 = r3 ^ r2; // s86 xor + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r7, 2); // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x883c0c92u : 0x53f915c2u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + ((((sel >> 31u) & 1u) != 0u) ? 0x3cc5bd20u : 0xe2be00a5u); // s91 add + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r2, 1); // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + ((((sel >> 17u) & 1u) != 0u) ? 0xbfd646cbu : 0x423fd9c9u); // s101 add + r7 = r7 + r6 + ((((sel >> 11u) & 1u) != 0u) ? 0x19b74a43u : 0x8d3c011du); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + ((((sel >> 15u) & 1u) != 0u) ? 0x7dcb7e18u : 0x8ce14721u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = __umulhi(r2, r0); // s109 mulhi + r1 = __umulhi(r1, r0); // s110 mulhi + r0 = r0 + r2 + ((((sel >> 28u) & 1u) != 0u) ? 0x3c179ad8u : 0x2d9fc6b9u); // s111 add + r2 = __umulhi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + ((((sel >> 22u) & 1u) != 0u) ? 0x47359729u : 0x502138e2u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = __umulhi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r2, 2); // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x6c57e4e7u : 0x33dff776u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + ((((sel >> 30u) & 1u) != 0u) ? 0xe8212c0cu : 0x5db25b34u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = __umulhi(r0, r5); // s138 mulhi + r2 = r2 + r7 + ((((sel >> 10u) & 1u) != 0u) ? 0xd44ff710u : 0x218d4090u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r6, 1); // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + ((((sel >> 29u) & 1u) != 0u) ? 0xb98942fau : 0xf4b1a8deu); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + ((((sel >> 17u) & 1u) != 0u) ? 0x0d48ba42u : 0x2bef10f2u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + ((((sel >> 30u) & 1u) != 0u) ? 0xc98dea9cu : 0xdc5cc080u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0x6c752dcbu : 0x18197438u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + ((((sel >> 3u) & 1u) != 0u) ? 0x8e481727u : 0xf1c46574u); // s163 add + r0 = __umulhi(r0, r4); // s164 mulhi + r2 = r2 + r6 + ((((sel >> 20u) & 1u) != 0u) ? 0x550ab406u : 0xac578137u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + ((((sel >> 14u) & 1u) != 0u) ? 0xaebb5966u : 0xa33e6706u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r0, 8); // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x5bb7550fu : 0xd94d55acu); // s184 add + r3 = r3 | r5; // s185 or + r6 = __umulhi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s188 shfl + r6 = r6 + r5 + ((((sel >> 6u) & 1u) != 0u) ? 0x2a354e2du : 0x89e747feu); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = __umulhi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r5, 16); // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + ((((sel >> 7u) & 1u) != 0u) ? 0x10cfdc71u : 0xea03e8e7u); // s197 add + r7 = r7 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x66e148d3u : 0xa7ee0102u); // s198 add + r5 = r5 - r2; // s199 sub + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s200 shfl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 8); // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0x8558b619u : 0x8379a4deu); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = __umulhi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r0, 4); // s209 shfl + r7 = r7 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0xf4049c4cu : 0xaa8cb14eu); // s210 add + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 16); // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r2, 16); // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = __umulhi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r2, 8); // s222 shfl + r5 = __umulhi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0x2a7fecb2u : 0x1d176220u); // s230 add + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + ((((sel >> 25u) & 1u) != 0u) ? 0xadce39f3u : 0x17dafb4du); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + ((((sel >> 29u) & 1u) != 0u) ? 0x0e7033b6u : 0xf2f77d26u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + ((((sel >> 31u) & 1u) != 0u) ? 0x7b2ff6b7u : 0xfed2da4eu); // s247 add + r0 = r0 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0xb5fad7b1u : 0x03b2891cu); // s248 add + r5 = __umulhi(r5, r4); // s249 mulhi + r5 = r5 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0xa7e71c2fu : 0x042cd6e3u); // s250 add + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r1, 1); // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0xb83d78deu : 0x784a302bu); // s254 add + r2 = r2 - r4; // s255 sub + } + } + uint32_t lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint32_t hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((uint64_t)hi << 32) | (uint64_t)lo; +} + +// Host-side launch wrappers. Declared in program.h, called from host.cu. +cudaError_t igneum_launch_cache_fill(uint32_t* cache, uint32_t nSegments) { + if (nSegments == 0u) return cudaErrorInvalidValue; + uint32_t block = 256u; + uint32_t grid = (nSegments + block - 1u) / block; + igneum_cache_fill<<>>(cache, nSegments); + return cudaGetLastError(); +} + +cudaError_t igneum_launch_build(uint32_t* ds, const uint32_t* cache, uint32_t nItems) { + if (nItems == 0u) return cudaErrorInvalidValue; + uint32_t block = 256u; + uint32_t grid = (nItems + block - 1u) / block; + igneum_build<<>>(ds, cache, nItems); + return cudaGetLastError(); +} + +cudaError_t igneum_launch_hash(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, + uint32_t nonces, uint32_t blockWarps) { + if (blockWarps == 0u || blockWarps > 32u) return cudaErrorInvalidValue; + uint32_t block = 32u * blockWarps; + if (nonces == 0u || (nonces % block) != 0u) return cudaErrorInvalidValue; + igneum_hash<<>>(ds, out, baseNonce, mask); + return cudaGetLastError(); +} + +cudaError_t igneum_hash_info(int* numRegs, int* blocksPerSM, uint32_t blockWarps) { + cudaFuncAttributes attr; + cudaError_t e = cudaFuncGetAttributes(&attr, igneum_hash); + if (e != cudaSuccess) return e; + *numRegs = attr.numRegs; + return cudaOccupancyMaxActiveBlocksPerMultiprocessor(blocksPerSM, igneum_hash, (int)(32u * blockWarps), 0); +} diff --git a/proto-cuda/packs-ca3-shadow/sh256x40/kernel_bound.cl b/proto-cuda/packs-ca3-shadow/sh256x40/kernel_bound.cl new file mode 100644 index 000000000..a4c319201 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x40/kernel_bound.cl @@ -0,0 +1,891 @@ +// 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 ^ 0x67a9a7beu; x += 0x9e3779b9u; x = splitmix32(x); r0 = x ^ 0x1a155b25u; } // SEEDW[0], 0x9e3779b9u * 1u, SEEDW[1] + { uint x = nonce ^ 0x1a155b25u; x += 0x3c6ef372u; x = splitmix32(x); r1 = x ^ 0xfddfb732u; } // SEEDW[1], 0x9e3779b9u * 2u, SEEDW[2] + { uint x = nonce ^ 0xfddfb732u; x += 0xdaa66d2bu; x = splitmix32(x); r2 = x ^ 0x4b5af2e8u; } // SEEDW[2], 0x9e3779b9u * 3u, SEEDW[3] + { uint x = nonce ^ 0x4b5af2e8u; x += 0x78dde6e4u; x = splitmix32(x); r3 = x ^ 0xc55caf33u; } // SEEDW[3], 0x9e3779b9u * 4u, SEEDW[4] + { uint x = nonce ^ 0xc55caf33u; x += 0x1715609du; x = splitmix32(x); r4 = x ^ 0xa27c13b7u; } // SEEDW[4], 0x9e3779b9u * 5u, SEEDW[5] + { uint x = nonce ^ 0xa27c13b7u; x += 0xb54cda56u; x = splitmix32(x); r5 = x ^ 0x06628a48u; } // SEEDW[5], 0x9e3779b9u * 6u, SEEDW[6] + { uint x = nonce ^ 0x06628a48u; x += 0x5384540fu; x = splitmix32(x); r6 = x ^ 0x03852469u; } // SEEDW[6], 0x9e3779b9u * 7u, SEEDW[7] + { uint x = nonce ^ 0x03852469u; x += 0xf1bbcdc8u; x = splitmix32(x); r7 = x ^ 0x67a9a7beu; } // SEEDW[7], 0x9e3779b9u * 8u, SEEDW[0] + + for (uint it = 0u; it < 8u; ++it) { + uint sel = r0; + r2 = r3 * r4 + r2; // 0 mad + r2 = r1 * r1 + r2; // 1 mad + r2 = r3 * r2 + r2; // 2 mad + r3 = r3 ^ r5; // 3 xor + r7 = r7 ^ ds[r2 & mask]; // 4 load + r5 = r5 ^ ds[r7 & mask]; // 5 load + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r1 = r1 ^ t_; } // 6 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r7 = r7 ^ t_; } // 7 shfl + r1 = mul_hi(r1, r5); // 8 mulhi + r6 = rotr_var(r6, r3); // 9 rotr + r3 = r3 | r4; // 10 or + r4 = r4 ^ ds[r3 & mask]; // 11 load + r0 = mul_hi(r0, r4); // 12 mulhi + r5 = r5 + r1 + ((((sel >> 30u) & 1u) != 0u) ? 0xd3177981u : 0xc7934706u); // 13 add + r0 = r0 ^ ds[r4 & mask]; // 14 load + r2 = r2 - r4; // 15 sub + r2 = r2 ^ ds[r0 & mask]; // 16 load + r7 = r7 ^ ds[r2 & mask]; // 17 load + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r7 = r7 ^ t_; } // 18 shfl + r5 = r5 * r0; // 19 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // 20 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 16u); r2 = r2 ^ t_; } // 21 shfl + r6 = mul_hi(r6, r2); // 22 mulhi + r6 = r6 ^ ds[r1 & mask]; // 23 load + r5 = r5 * r0; // 24 mul + r5 = rotl_imm(r5, 19u); // 25 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 2u); r7 = r7 ^ t_; } // 26 shfl + r0 = r0 ^ r5; // 27 xor + r0 = r0 ^ r4; // 28 xor + r3 = r3 - r0; // 29 sub + r5 = r5 * r1; // 30 mul + r7 = r7 ^ ds[r2 & mask]; // 31 load + r1 = r1 ^ ds[r0 & mask]; // 32 load + r5 = r5 ^ r6; // 33 xor + r5 = r5 ^ ds[r1 & mask]; // 34 load + r0 = mul_hi(r0, r5); // 35 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r5 = r5 ^ t_; } // 36 shfl + r7 = r7 ^ ds[r0 & mask]; // 37 load + r3 = r3 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0x230c005cu : 0x75ba2fadu); // 38 add + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 4u); r1 = r1 ^ t_; } // 39 shfl + r2 = r2 ^ r5; // 40 xor + r3 = r6 * r3 + r3; // 41 mad + r6 = r6 - r7; // 42 sub + r7 = r7 ^ r0; // 43 xor + r1 = r1 ^ ds[r7 & mask]; // 44 load + r2 = r2 * r3; // 45 mul + r1 = mul_hi(r1, r5); // 46 mulhi + r4 = r4 - r3; // 47 sub + r2 = rotr_var(r2, r6); // 48 rotr + r3 = r3 ^ ds[r5 & mask]; // 49 load + r1 = r1 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x1907970cu : 0x81b8bc2cu); // 50 add + r0 = r0 * r2; // 51 mul + r0 = r0 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x699fd448u : 0x4f92b968u); // 52 add + r1 = r1 + r0 + ((((sel >> 12u) & 1u) != 0u) ? 0x77b1520du : 0x2bb965afu); // 53 add + r7 = rotl_imm(r7, 14u); // 54 rotl + r3 = r3 + r7 + ((((sel >> 1u) & 1u) != 0u) ? 0xa54c55a0u : 0x7b0fe07au); // 55 add + r6 = r6 ^ ds[r7 & mask]; // 56 load + r1 = rotr_var(r1, r5); // 57 rotr + r5 = r5 ^ ds[r4 & mask]; // 58 load + r6 = r6 ^ ds[r2 & mask]; // 59 load + r3 = r5 * r0 + r3; // 60 mad + r5 = r5 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0xad7493e7u : 0xaf9dd72du); // 61 add + r4 = r4 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x1e07c3d9u : 0x89841d87u); // 62 add + r5 = rotl_imm(r5, 19u); // 63 rotl + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 40 passes after instruction 63, no load + for (uint sh = 0u; sh < 40u; ++sh) { + r5 = r5 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x8bc12da9u : 0x92199f99u); // s0 add + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x63079e5au : 0x8d72d3adu); // s1 add + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 2u); r6 = r6 ^ t_; } // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + ((((sel >> 31u) & 1u) != 0u) ? 0x5d4c7a60u : 0xb21b4babu); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + ((((sel >> 16u) & 1u) != 0u) ? 0xc88e2942u : 0x2fe0e98bu); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r6 = r6 ^ t_; } // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 4u); r2 = r2 ^ t_; } // s12 shfl + r1 = r1 + r5 + ((((sel >> 25u) & 1u) != 0u) ? 0xbc48c63eu : 0xbdf8f9a5u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r2 = r2 ^ t_; } // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + ((((sel >> 1u) & 1u) != 0u) ? 0x96e8f127u : 0x45c37cecu); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = mul_hi(r6, r0); // s28 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r2 = r2 ^ t_; } // s29 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r1 = r1 ^ t_; } // s30 shfl + r1 = r1 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0xb1cdb2abu : 0x37985632u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // s33 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r0 = r0 ^ t_; } // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x856e0180u : 0x804e777eu); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xe9bd0cc4u : 0x0b06c8a7u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = mul_hi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = mul_hi(r4, r3); // s44 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xcdcb63f6u : 0xee822e17u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r4 = r4 ^ t_; } // s47 shfl + r6 = mul_hi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0xd4758987u : 0x3dfad1b6u); // s56 add + r4 = r4 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x0602d6beu : 0xfca75bc2u); // s57 add + r5 = mul_hi(r5, r6); // s58 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r2 = r2 ^ t_; } // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0x8596687au : 0xd71c02ffu); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 2u); r7 = r7 ^ t_; } // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0x08ac5733u : 0x3c6fe15du); // s72 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r3 = r3 ^ t_; } // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + ((((sel >> 1u) & 1u) != 0u) ? 0xc100b495u : 0x295d5faeu); // s77 add + r3 = mul_hi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + ((((sel >> 15u) & 1u) != 0u) ? 0x5cc59530u : 0x274a9221u); // s81 add + r7 = r7 + r3 + ((((sel >> 5u) & 1u) != 0u) ? 0x141479ecu : 0xc8651f8eu); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r2 = r2 ^ t_; } // s85 shfl + r3 = r3 ^ r2; // s86 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 2u); r5 = r5 ^ t_; } // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x883c0c92u : 0x53f915c2u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + ((((sel >> 31u) & 1u) != 0u) ? 0x3cc5bd20u : 0xe2be00a5u); // s91 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 1u); r7 = r7 ^ t_; } // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + ((((sel >> 17u) & 1u) != 0u) ? 0xbfd646cbu : 0x423fd9c9u); // s101 add + r7 = r7 + r6 + ((((sel >> 11u) & 1u) != 0u) ? 0x19b74a43u : 0x8d3c011du); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + ((((sel >> 15u) & 1u) != 0u) ? 0x7dcb7e18u : 0x8ce14721u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = mul_hi(r2, r0); // s109 mulhi + r1 = mul_hi(r1, r0); // s110 mulhi + r0 = r0 + r2 + ((((sel >> 28u) & 1u) != 0u) ? 0x3c179ad8u : 0x2d9fc6b9u); // s111 add + r2 = mul_hi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + ((((sel >> 22u) & 1u) != 0u) ? 0x47359729u : 0x502138e2u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = mul_hi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 2u); r4 = r4 ^ t_; } // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r7 = r7 ^ t_; } // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x6c57e4e7u : 0x33dff776u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + ((((sel >> 30u) & 1u) != 0u) ? 0xe8212c0cu : 0x5db25b34u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = mul_hi(r0, r5); // s138 mulhi + r2 = r2 + r7 + ((((sel >> 10u) & 1u) != 0u) ? 0xd44ff710u : 0x218d4090u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r3 = r3 ^ t_; } // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + ((((sel >> 29u) & 1u) != 0u) ? 0xb98942fau : 0xf4b1a8deu); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + ((((sel >> 17u) & 1u) != 0u) ? 0x0d48ba42u : 0x2bef10f2u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + ((((sel >> 30u) & 1u) != 0u) ? 0xc98dea9cu : 0xdc5cc080u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0x6c752dcbu : 0x18197438u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + ((((sel >> 3u) & 1u) != 0u) ? 0x8e481727u : 0xf1c46574u); // s163 add + r0 = mul_hi(r0, r4); // s164 mulhi + r2 = r2 + r6 + ((((sel >> 20u) & 1u) != 0u) ? 0x550ab406u : 0xac578137u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + ((((sel >> 14u) & 1u) != 0u) ? 0xaebb5966u : 0xa33e6706u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 8u); r7 = r7 ^ t_; } // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x5bb7550fu : 0xd94d55acu); // s184 add + r3 = r3 | r5; // s185 or + r6 = mul_hi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r7 = r7 ^ t_; } // s188 shfl + r6 = r6 + r5 + ((((sel >> 6u) & 1u) != 0u) ? 0x2a354e2du : 0x89e747feu); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = mul_hi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r4 = r4 ^ t_; } // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + ((((sel >> 7u) & 1u) != 0u) ? 0x10cfdc71u : 0xea03e8e7u); // s197 add + r7 = r7 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x66e148d3u : 0xa7ee0102u); // s198 add + r5 = r5 - r2; // s199 sub + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r5 = r5 ^ t_; } // s200 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 8u); r7 = r7 ^ t_; } // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0x8558b619u : 0x8379a4deu); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = mul_hi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 4u); r2 = r2 ^ t_; } // s209 shfl + r7 = r7 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0xf4049c4cu : 0xaa8cb14eu); // s210 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 16u); r7 = r7 ^ t_; } // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 16u); r3 = r3 ^ t_; } // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = mul_hi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r5 = r5 ^ t_; } // s222 shfl + r5 = mul_hi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0x2a7fecb2u : 0x1d176220u); // s230 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r1 = r1 ^ t_; } // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + ((((sel >> 25u) & 1u) != 0u) ? 0xadce39f3u : 0x17dafb4du); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + ((((sel >> 29u) & 1u) != 0u) ? 0x0e7033b6u : 0xf2f77d26u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + ((((sel >> 31u) & 1u) != 0u) ? 0x7b2ff6b7u : 0xfed2da4eu); // s247 add + r0 = r0 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0xb5fad7b1u : 0x03b2891cu); // s248 add + r5 = mul_hi(r5, r4); // s249 mulhi + r5 = r5 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0xa7e71c2fu : 0x042cd6e3u); // s250 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 1u); r6 = r6 ^ t_; } // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0xb83d78deu : 0x784a302bu); // s254 add + r2 = r2 - r4; // s255 sub + } + } + 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 = r3 * r4 + r2; // 0 mad + r2 = r1 * r1 + r2; // 1 mad + r2 = r3 * r2 + r2; // 2 mad + r3 = r3 ^ r5; // 3 xor + r7 = r7 ^ ds[r2 & mask]; // 4 load + r5 = r5 ^ ds[r7 & mask]; // 5 load + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r1 = r1 ^ t_; } // 6 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r7 = r7 ^ t_; } // 7 shfl + r1 = mul_hi(r1, r5); // 8 mulhi + r6 = rotr_var(r6, r3); // 9 rotr + r3 = r3 | r4; // 10 or + r4 = r4 ^ ds[r3 & mask]; // 11 load + r0 = mul_hi(r0, r4); // 12 mulhi + r5 = r5 + r1 + ((((sel >> 30u) & 1u) != 0u) ? 0xd3177981u : 0xc7934706u); // 13 add + r0 = r0 ^ ds[r4 & mask]; // 14 load + r2 = r2 - r4; // 15 sub + r2 = r2 ^ ds[r0 & mask]; // 16 load + r7 = r7 ^ ds[r2 & mask]; // 17 load + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r7 = r7 ^ t_; } // 18 shfl + r5 = r5 * r0; // 19 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // 20 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 16u); r2 = r2 ^ t_; } // 21 shfl + r6 = mul_hi(r6, r2); // 22 mulhi + r6 = r6 ^ ds[r1 & mask]; // 23 load + r5 = r5 * r0; // 24 mul + r5 = rotl_imm(r5, 19u); // 25 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 2u); r7 = r7 ^ t_; } // 26 shfl + r0 = r0 ^ r5; // 27 xor + r0 = r0 ^ r4; // 28 xor + r3 = r3 - r0; // 29 sub + r5 = r5 * r1; // 30 mul + r7 = r7 ^ ds[r2 & mask]; // 31 load + r1 = r1 ^ ds[r0 & mask]; // 32 load + r5 = r5 ^ r6; // 33 xor + r5 = r5 ^ ds[r1 & mask]; // 34 load + r0 = mul_hi(r0, r5); // 35 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r5 = r5 ^ t_; } // 36 shfl + r7 = r7 ^ ds[r0 & mask]; // 37 load + r3 = r3 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0x230c005cu : 0x75ba2fadu); // 38 add + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 4u); r1 = r1 ^ t_; } // 39 shfl + r2 = r2 ^ r5; // 40 xor + r3 = r6 * r3 + r3; // 41 mad + r6 = r6 - r7; // 42 sub + r7 = r7 ^ r0; // 43 xor + r1 = r1 ^ ds[r7 & mask]; // 44 load + r2 = r2 * r3; // 45 mul + r1 = mul_hi(r1, r5); // 46 mulhi + r4 = r4 - r3; // 47 sub + r2 = rotr_var(r2, r6); // 48 rotr + r3 = r3 ^ ds[r5 & mask]; // 49 load + r1 = r1 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x1907970cu : 0x81b8bc2cu); // 50 add + r0 = r0 * r2; // 51 mul + r0 = r0 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x699fd448u : 0x4f92b968u); // 52 add + r1 = r1 + r0 + ((((sel >> 12u) & 1u) != 0u) ? 0x77b1520du : 0x2bb965afu); // 53 add + r7 = rotl_imm(r7, 14u); // 54 rotl + r3 = r3 + r7 + ((((sel >> 1u) & 1u) != 0u) ? 0xa54c55a0u : 0x7b0fe07au); // 55 add + r6 = r6 ^ ds[r7 & mask]; // 56 load + r1 = rotr_var(r1, r5); // 57 rotr + r5 = r5 ^ ds[r4 & mask]; // 58 load + r6 = r6 ^ ds[r2 & mask]; // 59 load + r3 = r5 * r0 + r3; // 60 mad + r5 = r5 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0xad7493e7u : 0xaf9dd72du); // 61 add + r4 = r4 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x1e07c3d9u : 0x89841d87u); // 62 add + r5 = rotl_imm(r5, 19u); // 63 rotl + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 40 passes after instruction 63, no load + for (uint sh = 0u; sh < 40u; ++sh) { + r5 = r5 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x8bc12da9u : 0x92199f99u); // s0 add + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x63079e5au : 0x8d72d3adu); // s1 add + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 2u); r6 = r6 ^ t_; } // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + ((((sel >> 31u) & 1u) != 0u) ? 0x5d4c7a60u : 0xb21b4babu); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + ((((sel >> 16u) & 1u) != 0u) ? 0xc88e2942u : 0x2fe0e98bu); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r6 = r6 ^ t_; } // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 4u); r2 = r2 ^ t_; } // s12 shfl + r1 = r1 + r5 + ((((sel >> 25u) & 1u) != 0u) ? 0xbc48c63eu : 0xbdf8f9a5u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r2 = r2 ^ t_; } // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + ((((sel >> 1u) & 1u) != 0u) ? 0x96e8f127u : 0x45c37cecu); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = mul_hi(r6, r0); // s28 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r2 = r2 ^ t_; } // s29 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r1 = r1 ^ t_; } // s30 shfl + r1 = r1 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0xb1cdb2abu : 0x37985632u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // s33 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r0 = r0 ^ t_; } // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x856e0180u : 0x804e777eu); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xe9bd0cc4u : 0x0b06c8a7u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = mul_hi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = mul_hi(r4, r3); // s44 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xcdcb63f6u : 0xee822e17u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r4 = r4 ^ t_; } // s47 shfl + r6 = mul_hi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0xd4758987u : 0x3dfad1b6u); // s56 add + r4 = r4 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x0602d6beu : 0xfca75bc2u); // s57 add + r5 = mul_hi(r5, r6); // s58 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r2 = r2 ^ t_; } // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0x8596687au : 0xd71c02ffu); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 2u); r7 = r7 ^ t_; } // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0x08ac5733u : 0x3c6fe15du); // s72 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r3 = r3 ^ t_; } // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + ((((sel >> 1u) & 1u) != 0u) ? 0xc100b495u : 0x295d5faeu); // s77 add + r3 = mul_hi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + ((((sel >> 15u) & 1u) != 0u) ? 0x5cc59530u : 0x274a9221u); // s81 add + r7 = r7 + r3 + ((((sel >> 5u) & 1u) != 0u) ? 0x141479ecu : 0xc8651f8eu); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r2 = r2 ^ t_; } // s85 shfl + r3 = r3 ^ r2; // s86 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 2u); r5 = r5 ^ t_; } // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x883c0c92u : 0x53f915c2u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + ((((sel >> 31u) & 1u) != 0u) ? 0x3cc5bd20u : 0xe2be00a5u); // s91 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 1u); r7 = r7 ^ t_; } // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + ((((sel >> 17u) & 1u) != 0u) ? 0xbfd646cbu : 0x423fd9c9u); // s101 add + r7 = r7 + r6 + ((((sel >> 11u) & 1u) != 0u) ? 0x19b74a43u : 0x8d3c011du); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + ((((sel >> 15u) & 1u) != 0u) ? 0x7dcb7e18u : 0x8ce14721u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = mul_hi(r2, r0); // s109 mulhi + r1 = mul_hi(r1, r0); // s110 mulhi + r0 = r0 + r2 + ((((sel >> 28u) & 1u) != 0u) ? 0x3c179ad8u : 0x2d9fc6b9u); // s111 add + r2 = mul_hi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + ((((sel >> 22u) & 1u) != 0u) ? 0x47359729u : 0x502138e2u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = mul_hi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 2u); r4 = r4 ^ t_; } // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r7 = r7 ^ t_; } // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x6c57e4e7u : 0x33dff776u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + ((((sel >> 30u) & 1u) != 0u) ? 0xe8212c0cu : 0x5db25b34u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = mul_hi(r0, r5); // s138 mulhi + r2 = r2 + r7 + ((((sel >> 10u) & 1u) != 0u) ? 0xd44ff710u : 0x218d4090u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r3 = r3 ^ t_; } // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + ((((sel >> 29u) & 1u) != 0u) ? 0xb98942fau : 0xf4b1a8deu); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + ((((sel >> 17u) & 1u) != 0u) ? 0x0d48ba42u : 0x2bef10f2u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + ((((sel >> 30u) & 1u) != 0u) ? 0xc98dea9cu : 0xdc5cc080u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0x6c752dcbu : 0x18197438u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + ((((sel >> 3u) & 1u) != 0u) ? 0x8e481727u : 0xf1c46574u); // s163 add + r0 = mul_hi(r0, r4); // s164 mulhi + r2 = r2 + r6 + ((((sel >> 20u) & 1u) != 0u) ? 0x550ab406u : 0xac578137u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + ((((sel >> 14u) & 1u) != 0u) ? 0xaebb5966u : 0xa33e6706u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 8u); r7 = r7 ^ t_; } // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x5bb7550fu : 0xd94d55acu); // s184 add + r3 = r3 | r5; // s185 or + r6 = mul_hi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r7 = r7 ^ t_; } // s188 shfl + r6 = r6 + r5 + ((((sel >> 6u) & 1u) != 0u) ? 0x2a354e2du : 0x89e747feu); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = mul_hi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r4 = r4 ^ t_; } // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + ((((sel >> 7u) & 1u) != 0u) ? 0x10cfdc71u : 0xea03e8e7u); // s197 add + r7 = r7 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x66e148d3u : 0xa7ee0102u); // s198 add + r5 = r5 - r2; // s199 sub + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r5 = r5 ^ t_; } // s200 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 8u); r7 = r7 ^ t_; } // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0x8558b619u : 0x8379a4deu); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = mul_hi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 4u); r2 = r2 ^ t_; } // s209 shfl + r7 = r7 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0xf4049c4cu : 0xaa8cb14eu); // s210 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 16u); r7 = r7 ^ t_; } // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 16u); r3 = r3 ^ t_; } // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = mul_hi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r5 = r5 ^ t_; } // s222 shfl + r5 = mul_hi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0x2a7fecb2u : 0x1d176220u); // s230 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r1 = r1 ^ t_; } // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + ((((sel >> 25u) & 1u) != 0u) ? 0xadce39f3u : 0x17dafb4du); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + ((((sel >> 29u) & 1u) != 0u) ? 0x0e7033b6u : 0xf2f77d26u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + ((((sel >> 31u) & 1u) != 0u) ? 0x7b2ff6b7u : 0xfed2da4eu); // s247 add + r0 = r0 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0xb5fad7b1u : 0x03b2891cu); // s248 add + r5 = mul_hi(r5, r4); // s249 mulhi + r5 = r5 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0xa7e71c2fu : 0x042cd6e3u); // s250 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 1u); r6 = r6 ^ t_; } // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0xb83d78deu : 0x784a302bu); // s254 add + r2 = r2 - r4; // s255 sub + } + } + uint lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((ulong)hi << 32) | (ulong)lo; +} diff --git a/proto-cuda/packs-ca3-shadow/sh256x40/kernel_bound.cu b/proto-cuda/packs-ca3-shadow/sh256x40/kernel_bound.cu new file mode 100644 index 000000000..3d97c4eef --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x40/kernel_bound.cu @@ -0,0 +1,382 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Header-bound twin of igneum_hash in kernel.cu: the init words come from a kernel argument, not SEEDW. +// Host declarations (also in program_bound.h if present): +// struct IgneumInitWords { uint32_t w[8]; }; +// cudaError_t igneum_launch_hash_bound(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, +// IgneumInitWords iw, uint32_t nonces, uint32_t blockWarps); +// cudaError_t igneum_hash_bound_info(int* numRegs, int* blocksPerSM, uint32_t blockWarps); +#include +#include +#include "program.h" + +struct IgneumInitWords { uint32_t w[8]; }; + +__device__ __forceinline__ uint32_t splitmix32(uint32_t x) { + x ^= x >> 16; x *= 0x7feb352du; + x ^= x >> 15; x *= 0x846ca68bu; + x ^= x >> 16; + return x; +} +__device__ __forceinline__ uint32_t rotl_imm(uint32_t x, uint32_t n) { return (x << n) | (x >> (32u - n)); } +__device__ __forceinline__ uint32_t rotr_var(uint32_t x, uint32_t n) { n &= 31u; return (x >> n) | (x << ((32u - n) & 31u)); } + +__global__ void igneum_hash_bound(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, IgneumInitWords iw) { + uint32_t gid = blockIdx.x * blockDim.x + threadIdx.x; + uint32_t nonce = baseNonce + gid; + uint32_t r0, r1, r2, r3, r4, r5, r6, r7; + { uint32_t x = nonce ^ iw.w[0]; x += 0x9e3779b9u * 1u; x = splitmix32(x); r0 = x ^ iw.w[1]; } + { uint32_t x = nonce ^ iw.w[1]; x += 0x9e3779b9u * 2u; x = splitmix32(x); r1 = x ^ iw.w[2]; } + { uint32_t x = nonce ^ iw.w[2]; x += 0x9e3779b9u * 3u; x = splitmix32(x); r2 = x ^ iw.w[3]; } + { uint32_t x = nonce ^ iw.w[3]; x += 0x9e3779b9u * 4u; x = splitmix32(x); r3 = x ^ iw.w[4]; } + { uint32_t x = nonce ^ iw.w[4]; x += 0x9e3779b9u * 5u; x = splitmix32(x); r4 = x ^ iw.w[5]; } + { uint32_t x = nonce ^ iw.w[5]; x += 0x9e3779b9u * 6u; x = splitmix32(x); r5 = x ^ iw.w[6]; } + { uint32_t x = nonce ^ iw.w[6]; x += 0x9e3779b9u * 7u; x = splitmix32(x); r6 = x ^ iw.w[7]; } + { uint32_t x = nonce ^ iw.w[7]; x += 0x9e3779b9u * 8u; x = splitmix32(x); r7 = x ^ iw.w[0]; } + + for (uint32_t it = 0u; it < 8u; ++it) { + uint32_t sel = r0; + r2 = r3 * r4 + r2; // 0 mad + r2 = r1 * r1 + r2; // 1 mad + r2 = r3 * r2 + r2; // 2 mad + r3 = r3 ^ r5; // 3 xor + r7 = r7 ^ ds[r2 & mask]; // 4 load + r5 = r5 ^ ds[r7 & mask]; // 5 load + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r4, 8); // 6 shfl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r3, 8); // 7 shfl + r1 = __umulhi(r1, r5); // 8 mulhi + r6 = rotr_var(r6, r3); // 9 rotr + r3 = r3 | r4; // 10 or + r4 = r4 ^ ds[r3 & mask]; // 11 load + r0 = __umulhi(r0, r4); // 12 mulhi + r5 = r5 + r1 + ((((sel >> 30u) & 1u) != 0u) ? 0xd3177981u : 0xc7934706u); // 13 add + r0 = r0 ^ ds[r4 & mask]; // 14 load + r2 = r2 - r4; // 15 sub + r2 = r2 ^ ds[r0 & mask]; // 16 load + r7 = r7 ^ ds[r2 & mask]; // 17 load + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r3, 4); // 18 shfl + r5 = r5 * r0; // 19 mul + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // 20 shfl + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 16); // 21 shfl + r6 = __umulhi(r6, r2); // 22 mulhi + r6 = r6 ^ ds[r1 & mask]; // 23 load + r5 = r5 * r0; // 24 mul + r5 = rotl_imm(r5, 19u); // 25 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r6, 2); // 26 shfl + r0 = r0 ^ r5; // 27 xor + r0 = r0 ^ r4; // 28 xor + r3 = r3 - r0; // 29 sub + r5 = r5 * r1; // 30 mul + r7 = r7 ^ ds[r2 & mask]; // 31 load + r1 = r1 ^ ds[r0 & mask]; // 32 load + r5 = r5 ^ r6; // 33 xor + r5 = r5 ^ ds[r1 & mask]; // 34 load + r0 = __umulhi(r0, r5); // 35 mulhi + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // 36 shfl + r7 = r7 ^ ds[r0 & mask]; // 37 load + r3 = r3 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0x230c005cu : 0x75ba2fadu); // 38 add + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r5, 4); // 39 shfl + r2 = r2 ^ r5; // 40 xor + r3 = r6 * r3 + r3; // 41 mad + r6 = r6 - r7; // 42 sub + r7 = r7 ^ r0; // 43 xor + r1 = r1 ^ ds[r7 & mask]; // 44 load + r2 = r2 * r3; // 45 mul + r1 = __umulhi(r1, r5); // 46 mulhi + r4 = r4 - r3; // 47 sub + r2 = rotr_var(r2, r6); // 48 rotr + r3 = r3 ^ ds[r5 & mask]; // 49 load + r1 = r1 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x1907970cu : 0x81b8bc2cu); // 50 add + r0 = r0 * r2; // 51 mul + r0 = r0 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x699fd448u : 0x4f92b968u); // 52 add + r1 = r1 + r0 + ((((sel >> 12u) & 1u) != 0u) ? 0x77b1520du : 0x2bb965afu); // 53 add + r7 = rotl_imm(r7, 14u); // 54 rotl + r3 = r3 + r7 + ((((sel >> 1u) & 1u) != 0u) ? 0xa54c55a0u : 0x7b0fe07au); // 55 add + r6 = r6 ^ ds[r7 & mask]; // 56 load + r1 = rotr_var(r1, r5); // 57 rotr + r5 = r5 ^ ds[r4 & mask]; // 58 load + r6 = r6 ^ ds[r2 & mask]; // 59 load + r3 = r5 * r0 + r3; // 60 mad + r5 = r5 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0xad7493e7u : 0xaf9dd72du); // 61 add + r4 = r4 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x1e07c3d9u : 0x89841d87u); // 62 add + r5 = rotl_imm(r5, 19u); // 63 rotl + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 40 passes after instruction 63, no load + for (uint32_t sh = 0u; sh < 40u; ++sh) { + r5 = r5 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x8bc12da9u : 0x92199f99u); // s0 add + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x63079e5au : 0x8d72d3adu); // s1 add + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r3, 2); // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + ((((sel >> 31u) & 1u) != 0u) ? 0x5d4c7a60u : 0xb21b4babu); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + ((((sel >> 16u) & 1u) != 0u) ? 0xc88e2942u : 0x2fe0e98bu); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r1, 4); // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r6, 4); // s12 shfl + r1 = r1 + r5 + ((((sel >> 25u) & 1u) != 0u) ? 0xbc48c63eu : 0xbdf8f9a5u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 8); // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + ((((sel >> 1u) & 1u) != 0u) ? 0x96e8f127u : 0x45c37cecu); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = __umulhi(r6, r0); // s28 mulhi + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // s29 shfl + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r6, 1); // s30 shfl + r1 = r1 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0xb1cdb2abu : 0x37985632u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // s33 shfl + r0 = r0 ^ __shfl_xor_sync(0xffffffffu, r3, 4); // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x856e0180u : 0x804e777eu); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xe9bd0cc4u : 0x0b06c8a7u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = __umulhi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = __umulhi(r4, r3); // s44 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xcdcb63f6u : 0xee822e17u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r3, 8); // s47 shfl + r6 = __umulhi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0xd4758987u : 0x3dfad1b6u); // s56 add + r4 = r4 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x0602d6beu : 0xfca75bc2u); // s57 add + r5 = __umulhi(r5, r6); // s58 mulhi + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0x8596687au : 0xd71c02ffu); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r5, 2); // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0x08ac5733u : 0x3c6fe15du); // s72 add + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r2, 8); // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + ((((sel >> 1u) & 1u) != 0u) ? 0xc100b495u : 0x295d5faeu); // s77 add + r3 = __umulhi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + ((((sel >> 15u) & 1u) != 0u) ? 0x5cc59530u : 0x274a9221u); // s81 add + r7 = r7 + r3 + ((((sel >> 5u) & 1u) != 0u) ? 0x141479ecu : 0xc8651f8eu); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r5, 16); // s85 shfl + r3 = r3 ^ r2; // s86 xor + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r7, 2); // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x883c0c92u : 0x53f915c2u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + ((((sel >> 31u) & 1u) != 0u) ? 0x3cc5bd20u : 0xe2be00a5u); // s91 add + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r2, 1); // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + ((((sel >> 17u) & 1u) != 0u) ? 0xbfd646cbu : 0x423fd9c9u); // s101 add + r7 = r7 + r6 + ((((sel >> 11u) & 1u) != 0u) ? 0x19b74a43u : 0x8d3c011du); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + ((((sel >> 15u) & 1u) != 0u) ? 0x7dcb7e18u : 0x8ce14721u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = __umulhi(r2, r0); // s109 mulhi + r1 = __umulhi(r1, r0); // s110 mulhi + r0 = r0 + r2 + ((((sel >> 28u) & 1u) != 0u) ? 0x3c179ad8u : 0x2d9fc6b9u); // s111 add + r2 = __umulhi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + ((((sel >> 22u) & 1u) != 0u) ? 0x47359729u : 0x502138e2u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = __umulhi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r2, 2); // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x6c57e4e7u : 0x33dff776u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + ((((sel >> 30u) & 1u) != 0u) ? 0xe8212c0cu : 0x5db25b34u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = __umulhi(r0, r5); // s138 mulhi + r2 = r2 + r7 + ((((sel >> 10u) & 1u) != 0u) ? 0xd44ff710u : 0x218d4090u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r6, 1); // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + ((((sel >> 29u) & 1u) != 0u) ? 0xb98942fau : 0xf4b1a8deu); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + ((((sel >> 17u) & 1u) != 0u) ? 0x0d48ba42u : 0x2bef10f2u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + ((((sel >> 30u) & 1u) != 0u) ? 0xc98dea9cu : 0xdc5cc080u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0x6c752dcbu : 0x18197438u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + ((((sel >> 3u) & 1u) != 0u) ? 0x8e481727u : 0xf1c46574u); // s163 add + r0 = __umulhi(r0, r4); // s164 mulhi + r2 = r2 + r6 + ((((sel >> 20u) & 1u) != 0u) ? 0x550ab406u : 0xac578137u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + ((((sel >> 14u) & 1u) != 0u) ? 0xaebb5966u : 0xa33e6706u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r0, 8); // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x5bb7550fu : 0xd94d55acu); // s184 add + r3 = r3 | r5; // s185 or + r6 = __umulhi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s188 shfl + r6 = r6 + r5 + ((((sel >> 6u) & 1u) != 0u) ? 0x2a354e2du : 0x89e747feu); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = __umulhi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r5, 16); // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + ((((sel >> 7u) & 1u) != 0u) ? 0x10cfdc71u : 0xea03e8e7u); // s197 add + r7 = r7 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x66e148d3u : 0xa7ee0102u); // s198 add + r5 = r5 - r2; // s199 sub + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s200 shfl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 8); // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0x8558b619u : 0x8379a4deu); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = __umulhi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r0, 4); // s209 shfl + r7 = r7 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0xf4049c4cu : 0xaa8cb14eu); // s210 add + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 16); // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r2, 16); // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = __umulhi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r2, 8); // s222 shfl + r5 = __umulhi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0x2a7fecb2u : 0x1d176220u); // s230 add + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + ((((sel >> 25u) & 1u) != 0u) ? 0xadce39f3u : 0x17dafb4du); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + ((((sel >> 29u) & 1u) != 0u) ? 0x0e7033b6u : 0xf2f77d26u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + ((((sel >> 31u) & 1u) != 0u) ? 0x7b2ff6b7u : 0xfed2da4eu); // s247 add + r0 = r0 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0xb5fad7b1u : 0x03b2891cu); // s248 add + r5 = __umulhi(r5, r4); // s249 mulhi + r5 = r5 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0xa7e71c2fu : 0x042cd6e3u); // s250 add + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r1, 1); // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0xb83d78deu : 0x784a302bu); // s254 add + r2 = r2 - r4; // s255 sub + } + } + uint32_t lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint32_t hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((uint64_t)hi << 32) | (uint64_t)lo; +} + +cudaError_t igneum_launch_hash_bound(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, + IgneumInitWords iw, uint32_t nonces, uint32_t blockWarps) { + if (blockWarps == 0u || blockWarps > 32u) return cudaErrorInvalidValue; + uint32_t block = 32u * blockWarps; + if (nonces == 0u || (nonces % block) != 0u) return cudaErrorInvalidValue; + igneum_hash_bound<<>>(ds, out, baseNonce, mask, iw); + return cudaGetLastError(); +} + +cudaError_t igneum_hash_bound_info(int* numRegs, int* blocksPerSM, uint32_t blockWarps) { + cudaFuncAttributes attr; + cudaError_t e = cudaFuncGetAttributes(&attr, igneum_hash_bound); + if (e != cudaSuccess) return e; + *numRegs = attr.numRegs; + return cudaOccupancyMaxActiveBlocksPerMultiprocessor(blocksPerSM, igneum_hash_bound, (int)(32u * blockWarps), 0); +} diff --git a/proto-cuda/packs-ca3-shadow/sh256x40/memhard.h b/proto-cuda/packs-ca3-shadow/sh256x40/memhard.h new file mode 100644 index 000000000..f7f34c732 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x40/memhard.h @@ -0,0 +1,109 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Memory-hard dataset core, the same text that the Mac's Metal kernels and CPU verifier were checked against. +// Included by kernel.cu (device), host.cu (host reference) and proto-opencl/host.c (C99 host reference). +// See proto-metal/MEMHARD.md for the construction. kernel.cl carries the same text in OpenCL C. +#pragma once +#ifdef __cplusplus +#include +#else +#include +#endif +#if defined(__CUDACC__) +#define IGNEUM_HD __host__ __device__ __forceinline__ +#elif defined(_MSC_VER) && !defined(__cplusplus) +#define IGNEUM_HD static __inline +#else +#define IGNEUM_HD static inline +#endif +// Memory-hard dataset core (MEMHARD.md). Cache: 2^26 words in 2^16 segments of 64 chained ChaCha12 lines. +// Item: 8 rounds of 8 x seed-parameterised mixer + one 64-byte cache read, then 8 x final mixer (class v3, mixer multiplier 8, +// docs/plans/mixer-x4.md: the round key of application j of round r is 0x9E3779B9 * (r * m + j + 1)). All parameters are literals. +#define MH_CACHE_LINE_MASK 0x003fffffu +#define MH_SEGMENT_LINES 64u +#define MH_QR(a, b, c, d, r1, r2, r3, r4) { a += b; d ^= a; d = mh_rotl(d, r1); c += d; b ^= c; b = mh_rotl(b, r2); a += b; d ^= a; d = mh_rotl(d, r3); c += d; b ^= c; b = mh_rotl(b, r4); } +IGNEUM_HD uint32_t mh_rotl(uint32_t x, uint32_t n) { return (x << n) | (x >> (32u - n)); } // n in 1..31 at every call site + +// y = ChaCha12 core(x) + x +IGNEUM_HD void mh_chacha_block(const uint32_t* x, uint32_t* y) { + for (uint32_t i = 0u; i < 16u; ++i) y[i] = x[i]; + for (uint32_t r = 0u; r < 6u; ++r) { + MH_QR(y[0], y[4], y[8], y[12], 16u, 12u, 8u, 7u) MH_QR(y[1], y[5], y[9], y[13], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[6], y[10], y[14], 16u, 12u, 8u, 7u) MH_QR(y[3], y[7], y[11], y[15], 16u, 12u, 8u, 7u) + MH_QR(y[0], y[5], y[10], y[15], 16u, 12u, 8u, 7u) MH_QR(y[1], y[6], y[11], y[12], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[7], y[8], y[13], 16u, 12u, 8u, 7u) MH_QR(y[3], y[4], y[9], y[14], 16u, 12u, 8u, 7u) + } + for (uint32_t i = 0u; i < 16u; ++i) y[i] += x[i]; +} + +// One cache segment: 64 chained lines written at cache[seg * 1024]. in_j = prev ^ (sigma || K || seg || j || tag), prev_0 = 0. +IGNEUM_HD void mh_cache_segment(uint32_t* cache, uint32_t seg) { + uint32_t prev[16]; uint32_t x[16]; uint32_t y[16]; + for (uint32_t i = 0u; i < 16u; ++i) prev[i] = 0u; + for (uint32_t j = 0u; j < MH_SEGMENT_LINES; ++j) { + x[0] = 0x61707865u ^ prev[0]; x[1] = 0x3320646eu ^ prev[1]; x[2] = 0x79622d32u ^ prev[2]; x[3] = 0x6b206574u ^ prev[3]; + x[4] = 0x3067619fu ^ prev[4]; + x[5] = 0x3c269176u ^ prev[5]; + x[6] = 0x84a03b03u ^ prev[6]; + x[7] = 0xf8c63294u ^ prev[7]; + x[8] = 0xff977c5bu ^ prev[8]; + x[9] = 0xe60def3eu ^ prev[9]; + x[10] = 0x63630141u ^ prev[10]; + x[11] = 0xb8fbcb58u ^ prev[11]; + x[12] = seg ^ prev[12]; x[13] = j ^ prev[13]; x[14] = 0x49676e65u ^ prev[14]; x[15] = 0x756d4d48u ^ prev[15]; + mh_chacha_block(x, y); + uint32_t* line = cache + ((seg * MH_SEGMENT_LINES + j) * 16u); + for (uint32_t i = 0u; i < 16u; ++i) { line[i] = y[i]; prev[i] = y[i]; } + } +} + +// M_r: per word (s ^ (RC + rk)) * MUL, then a column round and a diagonal round with the seed-drawn rotations. +IGNEUM_HD void mh_mixer(uint32_t* s, uint32_t rk) { + s[0] = (s[0] ^ (0xbab68293u + rk)) * 0x42146205u; + s[1] = (s[1] ^ (0xcc162340u + rk)) * 0x52cbe0fbu; + s[2] = (s[2] ^ (0x6ce151ccu + rk)) * 0x7ecf4a03u; + s[3] = (s[3] ^ (0xe62b8997u + rk)) * 0x6728907fu; + s[4] = (s[4] ^ (0xc9c80297u + rk)) * 0xd81d9751u; + s[5] = (s[5] ^ (0xf74a1654u + rk)) * 0x132952c3u; + s[6] = (s[6] ^ (0x3d704af5u + rk)) * 0xf60de277u; + s[7] = (s[7] ^ (0x3cf522b7u + rk)) * 0x05358035u; + s[8] = (s[8] ^ (0x2b9cac04u + rk)) * 0xbaf6499du; + s[9] = (s[9] ^ (0xa880ac10u + rk)) * 0xe4db9667u; + s[10] = (s[10] ^ (0x13e5dd1du + rk)) * 0x3e98f45du; + s[11] = (s[11] ^ (0x6fc3e233u + rk)) * 0xd0004eddu; + s[12] = (s[12] ^ (0x2d83eeacu + rk)) * 0x2691630du; + s[13] = (s[13] ^ (0x9006e8bfu + rk)) * 0x9beb3bcfu; + s[14] = (s[14] ^ (0x2c4b5362u + rk)) * 0xab310379u; + s[15] = (s[15] ^ (0x31b49ee2u + rk)) * 0x99cfb423u; + MH_QR(s[0], s[4], s[8], s[12], 20u, 20u, 19u, 4u) MH_QR(s[1], s[5], s[9], s[13], 20u, 20u, 19u, 4u) + MH_QR(s[2], s[6], s[10], s[14], 20u, 20u, 19u, 4u) MH_QR(s[3], s[7], s[11], s[15], 20u, 20u, 19u, 4u) + MH_QR(s[0], s[5], s[10], s[15], 26u, 3u, 3u, 27u) MH_QR(s[1], s[6], s[11], s[12], 26u, 3u, 3u, 27u) + MH_QR(s[2], s[7], s[8], s[13], 26u, 3u, 3u, 27u) MH_QR(s[3], s[4], s[9], s[14], 26u, 3u, 3u, 27u) +} + +// Item t: 16 words. s = (K, t * MUL[i] + RC[i]); 8 rounds of 8 x mixer + cache line s[0] & mask; 8 x final mixer. +IGNEUM_HD void mh_item(const uint32_t* cache, uint32_t t, uint32_t* s) { + s[0] = 0x3067619fu; + s[1] = 0x3c269176u; + s[2] = 0x84a03b03u; + s[3] = 0xf8c63294u; + s[4] = 0xff977c5bu; + s[5] = 0xe60def3eu; + s[6] = 0x63630141u; + s[7] = 0xb8fbcb58u; + s[8] = t * 0x42146205u + 0xbab68293u; + s[9] = t * 0x52cbe0fbu + 0xcc162340u; + s[10] = t * 0x7ecf4a03u + 0x6ce151ccu; + s[11] = t * 0x6728907fu + 0xe62b8997u; + s[12] = t * 0xd81d9751u + 0xc9c80297u; + s[13] = t * 0x132952c3u + 0xf74a1654u; + s[14] = t * 0xf60de277u + 0x3d704af5u; + s[15] = t * 0x05358035u + 0x3cf522b7u; + for (uint32_t r = 0u; r < 8u; ++r) { + for (uint32_t j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (r * 8u + j + 1u)); + const uint32_t* line = cache + ((s[0] & MH_CACHE_LINE_MASK) * 16u); + for (uint32_t i = 0u; i < 16u; ++i) s[i] ^= line[i]; + } + for (uint32_t j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (64u + j + 1u)); +} +// dataset[w] without the dataset: derive item w >> 4 and take word w & 15. +IGNEUM_HD uint32_t mh_word(const uint32_t* cache, uint32_t w) { uint32_t s[16]; mh_item(cache, w >> 4u, s); return s[w & 15u]; } diff --git a/proto-cuda/packs-ca3-shadow/sh256x40/memhard.metal b/proto-cuda/packs-ca3-shadow/sh256x40/memhard.metal new file mode 100644 index 000000000..01b263d6d --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x40/memhard.metal @@ -0,0 +1,107 @@ +#include +using namespace metal; +// Memory-hard dataset core (MEMHARD.md). Cache: 2^26 words in 2^16 segments of 64 chained ChaCha12 lines. +// Item: 8 rounds of 8 x seed-parameterised mixer + one 64-byte cache read, then 8 x final mixer (class v3, mixer multiplier 8, +// docs/plans/mixer-x4.md: the round key of application j of round r is 0x9E3779B9 * (r * m + j + 1)). All parameters are literals. +#define MH_CACHE_LINE_MASK 0x003fffffu +#define MH_SEGMENT_LINES 64u +#define MH_QR(a, b, c, d, r1, r2, r3, r4) { a += b; d ^= a; d = mh_rotl(d, r1); c += d; b ^= c; b = mh_rotl(b, r2); a += b; d ^= a; d = mh_rotl(d, r3); c += d; b ^= c; b = mh_rotl(b, r4); } +inline uint mh_rotl(uint x, uint n) { return (x << n) | (x >> (32u - n)); } // n in 1..31 at every call site + +// y = ChaCha12 core(x) + x +inline void mh_chacha_block(const thread uint* x, thread uint* y) { + for (uint i = 0u; i < 16u; ++i) y[i] = x[i]; + for (uint r = 0u; r < 6u; ++r) { + MH_QR(y[0], y[4], y[8], y[12], 16u, 12u, 8u, 7u) MH_QR(y[1], y[5], y[9], y[13], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[6], y[10], y[14], 16u, 12u, 8u, 7u) MH_QR(y[3], y[7], y[11], y[15], 16u, 12u, 8u, 7u) + MH_QR(y[0], y[5], y[10], y[15], 16u, 12u, 8u, 7u) MH_QR(y[1], y[6], y[11], y[12], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[7], y[8], y[13], 16u, 12u, 8u, 7u) MH_QR(y[3], y[4], y[9], y[14], 16u, 12u, 8u, 7u) + } + for (uint i = 0u; i < 16u; ++i) y[i] += x[i]; +} + +// One cache segment: 64 chained lines written at cache[seg * 1024]. in_j = prev ^ (sigma || K || seg || j || tag), prev_0 = 0. +inline void mh_cache_segment(device uint* cache, uint seg) { + uint prev[16]; uint x[16]; uint y[16]; + for (uint i = 0u; i < 16u; ++i) prev[i] = 0u; + for (uint j = 0u; j < MH_SEGMENT_LINES; ++j) { + x[0] = 0x61707865u ^ prev[0]; x[1] = 0x3320646eu ^ prev[1]; x[2] = 0x79622d32u ^ prev[2]; x[3] = 0x6b206574u ^ prev[3]; + x[4] = 0x3067619fu ^ prev[4]; + x[5] = 0x3c269176u ^ prev[5]; + x[6] = 0x84a03b03u ^ prev[6]; + x[7] = 0xf8c63294u ^ prev[7]; + x[8] = 0xff977c5bu ^ prev[8]; + x[9] = 0xe60def3eu ^ prev[9]; + x[10] = 0x63630141u ^ prev[10]; + x[11] = 0xb8fbcb58u ^ prev[11]; + x[12] = seg ^ prev[12]; x[13] = j ^ prev[13]; x[14] = 0x49676e65u ^ prev[14]; x[15] = 0x756d4d48u ^ prev[15]; + mh_chacha_block(x, y); + device uint* line = cache + ((seg * MH_SEGMENT_LINES + j) * 16u); + for (uint i = 0u; i < 16u; ++i) { line[i] = y[i]; prev[i] = y[i]; } + } +} + +// M_r: per word (s ^ (RC + rk)) * MUL, then a column round and a diagonal round with the seed-drawn rotations. +inline void mh_mixer(thread uint* s, uint rk) { + s[0] = (s[0] ^ (0xbab68293u + rk)) * 0x42146205u; + s[1] = (s[1] ^ (0xcc162340u + rk)) * 0x52cbe0fbu; + s[2] = (s[2] ^ (0x6ce151ccu + rk)) * 0x7ecf4a03u; + s[3] = (s[3] ^ (0xe62b8997u + rk)) * 0x6728907fu; + s[4] = (s[4] ^ (0xc9c80297u + rk)) * 0xd81d9751u; + s[5] = (s[5] ^ (0xf74a1654u + rk)) * 0x132952c3u; + s[6] = (s[6] ^ (0x3d704af5u + rk)) * 0xf60de277u; + s[7] = (s[7] ^ (0x3cf522b7u + rk)) * 0x05358035u; + s[8] = (s[8] ^ (0x2b9cac04u + rk)) * 0xbaf6499du; + s[9] = (s[9] ^ (0xa880ac10u + rk)) * 0xe4db9667u; + s[10] = (s[10] ^ (0x13e5dd1du + rk)) * 0x3e98f45du; + s[11] = (s[11] ^ (0x6fc3e233u + rk)) * 0xd0004eddu; + s[12] = (s[12] ^ (0x2d83eeacu + rk)) * 0x2691630du; + s[13] = (s[13] ^ (0x9006e8bfu + rk)) * 0x9beb3bcfu; + s[14] = (s[14] ^ (0x2c4b5362u + rk)) * 0xab310379u; + s[15] = (s[15] ^ (0x31b49ee2u + rk)) * 0x99cfb423u; + MH_QR(s[0], s[4], s[8], s[12], 20u, 20u, 19u, 4u) MH_QR(s[1], s[5], s[9], s[13], 20u, 20u, 19u, 4u) + MH_QR(s[2], s[6], s[10], s[14], 20u, 20u, 19u, 4u) MH_QR(s[3], s[7], s[11], s[15], 20u, 20u, 19u, 4u) + MH_QR(s[0], s[5], s[10], s[15], 26u, 3u, 3u, 27u) MH_QR(s[1], s[6], s[11], s[12], 26u, 3u, 3u, 27u) + MH_QR(s[2], s[7], s[8], s[13], 26u, 3u, 3u, 27u) MH_QR(s[3], s[4], s[9], s[14], 26u, 3u, 3u, 27u) +} + +// Item t: 16 words. s = (K, t * MUL[i] + RC[i]); 8 rounds of 8 x mixer + cache line s[0] & mask; 8 x final mixer. +inline void mh_item(device const uint* cache, uint t, thread uint* s) { + s[0] = 0x3067619fu; + s[1] = 0x3c269176u; + s[2] = 0x84a03b03u; + s[3] = 0xf8c63294u; + s[4] = 0xff977c5bu; + s[5] = 0xe60def3eu; + s[6] = 0x63630141u; + s[7] = 0xb8fbcb58u; + s[8] = t * 0x42146205u + 0xbab68293u; + s[9] = t * 0x52cbe0fbu + 0xcc162340u; + s[10] = t * 0x7ecf4a03u + 0x6ce151ccu; + s[11] = t * 0x6728907fu + 0xe62b8997u; + s[12] = t * 0xd81d9751u + 0xc9c80297u; + s[13] = t * 0x132952c3u + 0xf74a1654u; + s[14] = t * 0xf60de277u + 0x3d704af5u; + s[15] = t * 0x05358035u + 0x3cf522b7u; + for (uint r = 0u; r < 8u; ++r) { + for (uint j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (r * 8u + j + 1u)); + device const uint* line = cache + ((s[0] & MH_CACHE_LINE_MASK) * 16u); + for (uint i = 0u; i < 16u; ++i) s[i] ^= line[i]; + } + for (uint j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (64u + j + 1u)); +} +// dataset[w] without the dataset: derive item w >> 4 and take word w & 15. +inline uint mh_word(device const uint* cache, uint w) { uint s[16]; mh_item(cache, w >> 4u, s); return s[w & 15u]; } + +// One thread per segment (2^16 threads). +kernel void igneum_cache_fill(device uint* cache [[buffer(0)]], uint gid [[thread_position_in_grid]]) { + mh_cache_segment(cache, gid); +} +// One thread per 64-byte item (dataset words / 16 threads). +kernel void igneum_build(device const uint* cache [[buffer(0)]], device uint* dataset [[buffer(1)]], + uint gid [[thread_position_in_grid]]) { + uint s[16]; + mh_item(cache, gid, s); + device uint* d = dataset + gid * 16u; + for (uint i = 0u; i < 16u; ++i) d[i] = s[i]; +} diff --git a/proto-cuda/packs-ca3-shadow/sh256x40/program.h b/proto-cuda/packs-ca3-shadow/sh256x40/program.h new file mode 100644 index 000000000..6f06c96e8 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x40/program.h @@ -0,0 +1,70 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Program metadata for host.cu plus the launch wrappers defined in kernel.cu. +// Also included by proto-opencl/host.c (C99), which defines IGNEUM_NO_CUDA first and reads only the macros. +#pragma once +#ifdef __cplusplus +#include +#else +#include +#endif +#ifndef IGNEUM_NO_CUDA +#include +#endif + +#define IGNEUM_SEED_STRING "igneum-genesis" +#define IGNEUM_SEED_BYTES_HEX "69676e65756d2d67656e65736973" +#define IGNEUM_GENERATOR 2 +#define IGNEUM_PROGRAM_ATTEMPT 0 +#define IGNEUM_PROGRAM_ID 0x9abe71853b54db11ull +#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 add=8 shfl=8 xor=6 mad=5 mul=5 mulhi=5 sub=4 rotl=3 rotr=3 or=1" +// 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+sh256x40" +#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 40 +#define IGNEUM_SHADOW_INSTRS_PER_HASH 81920 +#define IGNEUM_SHADOW_OP_MIX "add=47 rotl=30 xor=30 shfl=29 mad=27 mul=22 sub=21 rotr=20 mulhi=18 or=12" +// 0 = closed-form dataset (ds_elem), 1 = memory-hard cache construction (MEMHARD.md, memhard.h) +#define IGNEUM_DATASET_MODE 1 + +#define IGNEUM_SEEDW_INIT { 0x67a9a7beu, 0x1a155b25u, 0xfddfb732u, 0x4b5af2e8u, 0xc55caf33u, 0xa27c13b7u, 0x06628a48u, 0x03852469u } +#define IGNEUM_KEY_INIT { 0x3067619fu, 0x3c269176u, 0x84a03b03u, 0xf8c63294u, 0xff977c5bu, 0xe60def3eu, 0x63630141u, 0xb8fbcb58u } +#define IGNEUM_CACHE_LOG2_WORDS 26 +#define IGNEUM_CACHE_SEGMENT_LOG2_LINES 6 +#define IGNEUM_CACHE_SEGMENTS 65536u +#define IGNEUM_ITEM_ROUNDS 8 +#define IGNEUM_MIXER_MULT 8 // mixer applications per round and after the last read (class v3, docs/plans/mixer-x4.md) +#define IGNEUM_MIX_ROT_INIT { 20u, 20u, 19u, 4u, 26u, 3u, 3u, 27u } +#define IGNEUM_MIX_MUL_INIT { 0x42146205u, 0x52cbe0fbu, 0x7ecf4a03u, 0x6728907fu, 0xd81d9751u, 0x132952c3u, 0xf60de277u, 0x05358035u, 0xbaf6499du, 0xe4db9667u, 0x3e98f45du, 0xd0004eddu, 0x2691630du, 0x9beb3bcfu, 0xab310379u, 0x99cfb423u } +#define IGNEUM_MIX_RC_INIT { 0xbab68293u, 0xcc162340u, 0x6ce151ccu, 0xe62b8997u, 0xc9c80297u, 0xf74a1654u, 0x3d704af5u, 0x3cf522b7u, 0x2b9cac04u, 0xa880ac10u, 0x13e5dd1du, 0x6fc3e233u, 0x2d83eeacu, 0x9006e8bfu, 0x2c4b5362u, 0x31b49ee2u } + +#ifndef IGNEUM_NO_CUDA +// Defined in kernel.cu. All launch on the default stream and return cudaGetLastError(). +cudaError_t igneum_launch_cache_fill(uint32_t* cache, uint32_t nSegments); +cudaError_t igneum_launch_build(uint32_t* ds, const uint32_t* cache, uint32_t nItems); +cudaError_t igneum_launch_hash(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, + uint32_t nonces, uint32_t blockWarps); +cudaError_t igneum_hash_info(int* numRegs, int* blocksPerSM, uint32_t blockWarps); +#endif diff --git a/proto-cuda/packs-ca3-shadow/sh256x40/program.json b/proto-cuda/packs-ca3-shadow/sh256x40/program.json new file mode 100644 index 000000000..91c8f62b2 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x40/program.json @@ -0,0 +1,389 @@ +{ + "format": "igneum-program-pack-3", + "generator": 2, + "attempt": 0, + "program_id": "0x9abe71853b54db11", + "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": ["0x67a9a7be", "0x1a155b25", "0xfddfb732", "0x4b5af2e8", "0xc55caf33", "0xa27c13b7", "0x06628a48", "0x03852469"], + "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+sh256x40", + "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, "add": 8, "shfl": 8, "xor": 6, "mad": 5, "mul": 5, "mulhi": 5, "sub": 4, "rotl": 3, "rotr": 3, "or": 1}, + "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": 40, "instrs_per_hash": 81920, "op_mix": {"add": 47, "rotl": 30, "xor": 30, "shfl": 29, "mad": 27, "mul": 22, "sub": 21, "rotr": 20, "mulhi": 18, "or": 12}, "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": "add", "dst": 5, "src": 2, "src2": 1, "imm": "0x92199f99", "imm2": "0x8bc12da9", "rot": 9, "bit": 18, "mask": 4}, + {"i": 1, "op": "add", "dst": 0, "src": 7, "src2": 1, "imm": "0x8d72d3ad", "imm2": "0x63079e5a", "rot": 20, "bit": 26, "mask": 4}, + {"i": 2, "op": "shfl", "dst": 6, "src": 3, "src2": 6, "imm": "0x9beaeddf", "imm2": "0x744ecb00", "rot": 10, "bit": 4, "mask": 2}, + {"i": 3, "op": "sub", "dst": 4, "src": 2, "src2": 0, "imm": "0x2a3ddc67", "imm2": "0x72c80241", "rot": 30, "bit": 1, "mask": 16}, + {"i": 4, "op": "add", "dst": 7, "src": 0, "src2": 5, "imm": "0xb21b4bab", "imm2": "0x5d4c7a60", "rot": 17, "bit": 31, "mask": 4}, + {"i": 5, "op": "rotl", "dst": 0, "src": 6, "src2": 3, "imm": "0xe69d7919", "imm2": "0xa048c61e", "rot": 11, "bit": 1, "mask": 8}, + {"i": 6, "op": "add", "dst": 0, "src": 1, "src2": 3, "imm": "0x2fe0e98b", "imm2": "0xc88e2942", "rot": 5, "bit": 16, "mask": 16}, + {"i": 7, "op": "xor", "dst": 7, "src": 1, "src2": 0, "imm": "0xc16efe98", "imm2": "0x01a638c8", "rot": 8, "bit": 17, "mask": 1}, + {"i": 8, "op": "mad", "dst": 1, "src": 6, "src2": 5, "imm": "0x76ec7b8b", "imm2": "0x25663feb", "rot": 29, "bit": 30, "mask": 2}, + {"i": 9, "op": "shfl", "dst": 6, "src": 1, "src2": 0, "imm": "0x6c8ee3cb", "imm2": "0xea93237e", "rot": 27, "bit": 1, "mask": 4}, + {"i": 10, "op": "mad", "dst": 1, "src": 2, "src2": 2, "imm": "0x6dc4ea18", "imm2": "0x6efde6f5", "rot": 3, "bit": 20, "mask": 2}, + {"i": 11, "op": "mad", "dst": 5, "src": 0, "src2": 3, "imm": "0x023613fc", "imm2": "0x18c51939", "rot": 19, "bit": 31, "mask": 1}, + {"i": 12, "op": "shfl", "dst": 2, "src": 6, "src2": 1, "imm": "0x74aec8d2", "imm2": "0x7f7ad29c", "rot": 7, "bit": 8, "mask": 4}, + {"i": 13, "op": "add", "dst": 1, "src": 5, "src2": 6, "imm": "0xbdf8f9a5", "imm2": "0xbc48c63e", "rot": 6, "bit": 25, "mask": 2}, + {"i": 14, "op": "rotl", "dst": 1, "src": 2, "src2": 6, "imm": "0x7ad8ca8b", "imm2": "0x14c712ad", "rot": 29, "bit": 25, "mask": 8}, + {"i": 15, "op": "sub", "dst": 1, "src": 4, "src2": 5, "imm": "0xd3349f69", "imm2": "0x70aac45a", "rot": 29, "bit": 9, "mask": 16}, + {"i": 16, "op": "or", "dst": 7, "src": 1, "src2": 2, "imm": "0x08168ed1", "imm2": "0x28964037", "rot": 26, "bit": 0, "mask": 2}, + {"i": 17, "op": "shfl", "dst": 2, "src": 4, "src2": 6, "imm": "0x98d85f72", "imm2": "0x3dc87042", "rot": 29, "bit": 22, "mask": 8}, + {"i": 18, "op": "xor", "dst": 7, "src": 4, "src2": 0, "imm": "0x651d4a0e", "imm2": "0x93c198bd", "rot": 26, "bit": 12, "mask": 8}, + {"i": 19, "op": "mul", "dst": 6, "src": 1, "src2": 6, "imm": "0xd38ce89d", "imm2": "0x3dfad388", "rot": 5, "bit": 28, "mask": 8}, + {"i": 20, "op": "mad", "dst": 5, "src": 6, "src2": 0, "imm": "0x59d78b36", "imm2": "0xc4db274e", "rot": 25, "bit": 24, "mask": 1}, + {"i": 21, "op": "sub", "dst": 3, "src": 1, "src2": 7, "imm": "0xf6c6a6c7", "imm2": "0x8536f4e6", "rot": 6, "bit": 12, "mask": 4}, + {"i": 22, "op": "mul", "dst": 6, "src": 0, "src2": 7, "imm": "0x599445b4", "imm2": "0x632f8c32", "rot": 19, "bit": 4, "mask": 8}, + {"i": 23, "op": "add", "dst": 2, "src": 0, "src2": 7, "imm": "0x45c37cec", "imm2": "0x96e8f127", "rot": 15, "bit": 1, "mask": 4}, + {"i": 24, "op": "sub", "dst": 6, "src": 4, "src2": 3, "imm": "0xc1c44491", "imm2": "0x92e3ce57", "rot": 20, "bit": 25, "mask": 4}, + {"i": 25, "op": "mad", "dst": 7, "src": 3, "src2": 4, "imm": "0x89bfb8d3", "imm2": "0x19b5455e", "rot": 22, "bit": 2, "mask": 16}, + {"i": 26, "op": "rotl", "dst": 3, "src": 5, "src2": 7, "imm": "0x2f47ce8d", "imm2": "0x8b458ec5", "rot": 9, "bit": 0, "mask": 4}, + {"i": 27, "op": "sub", "dst": 2, "src": 1, "src2": 2, "imm": "0x9f0dce23", "imm2": "0x3cdca814", "rot": 25, "bit": 1, "mask": 2}, + {"i": 28, "op": "mulhi", "dst": 6, "src": 0, "src2": 3, "imm": "0x61fc9eb8", "imm2": "0x23202e9d", "rot": 30, "bit": 16, "mask": 16}, + {"i": 29, "op": "shfl", "dst": 2, "src": 4, "src2": 3, "imm": "0x339dbd65", "imm2": "0xc175f639", "rot": 15, "bit": 22, "mask": 2}, + {"i": 30, "op": "shfl", "dst": 1, "src": 6, "src2": 1, "imm": "0x5bd14589", "imm2": "0xa68a2bed", "rot": 31, "bit": 31, "mask": 1}, + {"i": 31, "op": "add", "dst": 1, "src": 6, "src2": 1, "imm": "0x37985632", "imm2": "0xb1cdb2ab", "rot": 29, "bit": 1, "mask": 8}, + {"i": 32, "op": "rotr", "dst": 0, "src": 1, "src2": 6, "imm": "0x4b2058f4", "imm2": "0xf06d8ac9", "rot": 9, "bit": 15, "mask": 16}, + {"i": 33, "op": "shfl", "dst": 3, "src": 4, "src2": 4, "imm": "0x2081626c", "imm2": "0x08d1bb87", "rot": 24, "bit": 29, "mask": 2}, + {"i": 34, "op": "shfl", "dst": 0, "src": 3, "src2": 6, "imm": "0xe4fcfe03", "imm2": "0x78a46b13", "rot": 15, "bit": 29, "mask": 4}, + {"i": 35, "op": "mul", "dst": 7, "src": 0, "src2": 4, "imm": "0x33148d30", "imm2": "0x5780a3d6", "rot": 6, "bit": 11, "mask": 2}, + {"i": 36, "op": "add", "dst": 3, "src": 1, "src2": 1, "imm": "0x804e777e", "imm2": "0x856e0180", "rot": 22, "bit": 0, "mask": 16}, + {"i": 37, "op": "xor", "dst": 1, "src": 6, "src2": 0, "imm": "0xc69aa2f6", "imm2": "0xafebe3e8", "rot": 15, "bit": 9, "mask": 16}, + {"i": 38, "op": "mul", "dst": 2, "src": 7, "src2": 4, "imm": "0xeb4c4082", "imm2": "0x3f1e0da7", "rot": 25, "bit": 20, "mask": 16}, + {"i": 39, "op": "add", "dst": 6, "src": 5, "src2": 5, "imm": "0x0b06c8a7", "imm2": "0xe9bd0cc4", "rot": 6, "bit": 2, "mask": 4}, + {"i": 40, "op": "mul", "dst": 5, "src": 7, "src2": 7, "imm": "0x070af1b6", "imm2": "0x6b648e75", "rot": 10, "bit": 6, "mask": 16}, + {"i": 41, "op": "mulhi", "dst": 2, "src": 3, "src2": 2, "imm": "0x389753b2", "imm2": "0x9e657305", "rot": 30, "bit": 2, "mask": 4}, + {"i": 42, "op": "xor", "dst": 2, "src": 0, "src2": 4, "imm": "0x0960e5b9", "imm2": "0xa925a406", "rot": 4, "bit": 6, "mask": 16}, + {"i": 43, "op": "rotl", "dst": 0, "src": 1, "src2": 1, "imm": "0x8eabe09f", "imm2": "0x76ef71e2", "rot": 4, "bit": 19, "mask": 8}, + {"i": 44, "op": "mulhi", "dst": 4, "src": 3, "src2": 7, "imm": "0x6a34768a", "imm2": "0x2e427c64", "rot": 21, "bit": 5, "mask": 4}, + {"i": 45, "op": "add", "dst": 6, "src": 7, "src2": 5, "imm": "0xee822e17", "imm2": "0xcdcb63f6", "rot": 27, "bit": 12, "mask": 16}, + {"i": 46, "op": "mad", "dst": 3, "src": 2, "src2": 0, "imm": "0xc89ead43", "imm2": "0x4d3108b2", "rot": 26, "bit": 17, "mask": 1}, + {"i": 47, "op": "shfl", "dst": 4, "src": 3, "src2": 0, "imm": "0xdd62be9e", "imm2": "0xf243f6f2", "rot": 8, "bit": 4, "mask": 8}, + {"i": 48, "op": "mulhi", "dst": 6, "src": 5, "src2": 0, "imm": "0xd3f7fa72", "imm2": "0x0debc83f", "rot": 25, "bit": 5, "mask": 2}, + {"i": 49, "op": "sub", "dst": 0, "src": 2, "src2": 6, "imm": "0x7afadd15", "imm2": "0xc07fc39c", "rot": 30, "bit": 29, "mask": 8}, + {"i": 50, "op": "sub", "dst": 3, "src": 5, "src2": 3, "imm": "0x179b78ec", "imm2": "0xaeccde37", "rot": 30, "bit": 17, "mask": 1}, + {"i": 51, "op": "rotr", "dst": 1, "src": 4, "src2": 1, "imm": "0xa4bfcea6", "imm2": "0xbf63bb2f", "rot": 2, "bit": 21, "mask": 2}, + {"i": 52, "op": "mad", "dst": 6, "src": 7, "src2": 7, "imm": "0xabf5ed10", "imm2": "0x8a285f51", "rot": 3, "bit": 23, "mask": 2}, + {"i": 53, "op": "xor", "dst": 5, "src": 3, "src2": 5, "imm": "0x88b416eb", "imm2": "0x36271d87", "rot": 19, "bit": 10, "mask": 2}, + {"i": 54, "op": "sub", "dst": 1, "src": 0, "src2": 1, "imm": "0xa3417dd3", "imm2": "0xcd98f620", "rot": 28, "bit": 2, "mask": 1}, + {"i": 55, "op": "sub", "dst": 5, "src": 6, "src2": 2, "imm": "0x45996c6f", "imm2": "0xe3d41087", "rot": 4, "bit": 31, "mask": 1}, + {"i": 56, "op": "add", "dst": 3, "src": 2, "src2": 0, "imm": "0x3dfad1b6", "imm2": "0xd4758987", "rot": 27, "bit": 10, "mask": 2}, + {"i": 57, "op": "add", "dst": 4, "src": 1, "src2": 3, "imm": "0xfca75bc2", "imm2": "0x0602d6be", "rot": 19, "bit": 0, "mask": 16}, + {"i": 58, "op": "mulhi", "dst": 5, "src": 6, "src2": 5, "imm": "0x83250a7b", "imm2": "0x2f93d53b", "rot": 25, "bit": 7, "mask": 2}, + {"i": 59, "op": "shfl", "dst": 2, "src": 1, "src2": 0, "imm": "0x13f4a089", "imm2": "0x145ea125", "rot": 12, "bit": 3, "mask": 2}, + {"i": 60, "op": "rotl", "dst": 2, "src": 5, "src2": 6, "imm": "0xad3170e3", "imm2": "0x15db04d1", "rot": 9, "bit": 13, "mask": 2}, + {"i": 61, "op": "or", "dst": 4, "src": 6, "src2": 2, "imm": "0x4b6305b2", "imm2": "0x6e7b2e9c", "rot": 27, "bit": 16, "mask": 4}, + {"i": 62, "op": "rotr", "dst": 6, "src": 4, "src2": 6, "imm": "0xfcd4b1c9", "imm2": "0xaf5c733b", "rot": 6, "bit": 21, "mask": 16}, + {"i": 63, "op": "mul", "dst": 2, "src": 4, "src2": 6, "imm": "0x95cebb3e", "imm2": "0xbba9cdfc", "rot": 19, "bit": 23, "mask": 1}, + {"i": 64, "op": "xor", "dst": 0, "src": 5, "src2": 7, "imm": "0x5f7579ff", "imm2": "0xb104e01a", "rot": 25, "bit": 12, "mask": 8}, + {"i": 65, "op": "xor", "dst": 2, "src": 7, "src2": 3, "imm": "0x749c7611", "imm2": "0xf17df3bb", "rot": 27, "bit": 26, "mask": 2}, + {"i": 66, "op": "add", "dst": 2, "src": 1, "src2": 6, "imm": "0xd71c02ff", "imm2": "0x8596687a", "rot": 4, "bit": 6, "mask": 2}, + {"i": 67, "op": "rotl", "dst": 1, "src": 3, "src2": 2, "imm": "0xd2864071", "imm2": "0xaa644ef3", "rot": 21, "bit": 5, "mask": 1}, + {"i": 68, "op": "mul", "dst": 3, "src": 2, "src2": 1, "imm": "0xd0689a5f", "imm2": "0xa3a1f063", "rot": 13, "bit": 28, "mask": 2}, + {"i": 69, "op": "shfl", "dst": 7, "src": 5, "src2": 6, "imm": "0xd01476eb", "imm2": "0x76abb5c2", "rot": 7, "bit": 30, "mask": 2}, + {"i": 70, "op": "mul", "dst": 3, "src": 2, "src2": 5, "imm": "0x59a75c10", "imm2": "0x1e1fbb72", "rot": 20, "bit": 16, "mask": 1}, + {"i": 71, "op": "mad", "dst": 0, "src": 2, "src2": 5, "imm": "0x39cca1df", "imm2": "0x22c057ac", "rot": 5, "bit": 23, "mask": 16}, + {"i": 72, "op": "add", "dst": 6, "src": 7, "src2": 3, "imm": "0x3c6fe15d", "imm2": "0x08ac5733", "rot": 14, "bit": 0, "mask": 4}, + {"i": 73, "op": "shfl", "dst": 3, "src": 2, "src2": 6, "imm": "0x2098627d", "imm2": "0xf4fecc81", "rot": 20, "bit": 30, "mask": 8}, + {"i": 74, "op": "mul", "dst": 3, "src": 6, "src2": 5, "imm": "0xf82e9e23", "imm2": "0x3ad62132", "rot": 10, "bit": 14, "mask": 16}, + {"i": 75, "op": "xor", "dst": 6, "src": 7, "src2": 4, "imm": "0x70548a91", "imm2": "0xa9715d2e", "rot": 6, "bit": 24, "mask": 1}, + {"i": 76, "op": "or", "dst": 3, "src": 0, "src2": 7, "imm": "0xa164325f", "imm2": "0xf300838b", "rot": 23, "bit": 23, "mask": 16}, + {"i": 77, "op": "add", "dst": 2, "src": 4, "src2": 6, "imm": "0x295d5fae", "imm2": "0xc100b495", "rot": 7, "bit": 1, "mask": 2}, + {"i": 78, "op": "mulhi", "dst": 3, "src": 7, "src2": 4, "imm": "0xb62cca87", "imm2": "0x2ebde415", "rot": 14, "bit": 7, "mask": 2}, + {"i": 79, "op": "or", "dst": 4, "src": 1, "src2": 7, "imm": "0xfcbc482d", "imm2": "0x8876e6cd", "rot": 29, "bit": 5, "mask": 2}, + {"i": 80, "op": "rotr", "dst": 4, "src": 3, "src2": 0, "imm": "0x6d64013b", "imm2": "0x675f4a8d", "rot": 26, "bit": 18, "mask": 8}, + {"i": 81, "op": "add", "dst": 4, "src": 3, "src2": 3, "imm": "0x274a9221", "imm2": "0x5cc59530", "rot": 15, "bit": 15, "mask": 2}, + {"i": 82, "op": "add", "dst": 7, "src": 3, "src2": 0, "imm": "0xc8651f8e", "imm2": "0x141479ec", "rot": 18, "bit": 5, "mask": 1}, + {"i": 83, "op": "rotr", "dst": 3, "src": 6, "src2": 0, "imm": "0xcc8a7766", "imm2": "0xc2eb5161", "rot": 4, "bit": 29, "mask": 2}, + {"i": 84, "op": "mad", "dst": 2, "src": 4, "src2": 7, "imm": "0xbc507d51", "imm2": "0x0b1196fd", "rot": 9, "bit": 7, "mask": 8}, + {"i": 85, "op": "shfl", "dst": 2, "src": 5, "src2": 5, "imm": "0x5a156c90", "imm2": "0xa6b3fbfa", "rot": 11, "bit": 2, "mask": 16}, + {"i": 86, "op": "xor", "dst": 3, "src": 2, "src2": 1, "imm": "0x8b042658", "imm2": "0xacf37a8f", "rot": 12, "bit": 23, "mask": 16}, + {"i": 87, "op": "shfl", "dst": 5, "src": 7, "src2": 2, "imm": "0x1a214238", "imm2": "0x017fdf5d", "rot": 29, "bit": 14, "mask": 2}, + {"i": 88, "op": "xor", "dst": 0, "src": 4, "src2": 2, "imm": "0xd523e612", "imm2": "0x2158c2ed", "rot": 30, "bit": 14, "mask": 4}, + {"i": 89, "op": "add", "dst": 3, "src": 2, "src2": 7, "imm": "0x53f915c2", "imm2": "0x883c0c92", "rot": 9, "bit": 18, "mask": 8}, + {"i": 90, "op": "rotr", "dst": 7, "src": 5, "src2": 5, "imm": "0xbd633b21", "imm2": "0xcf8c356c", "rot": 25, "bit": 31, "mask": 4}, + {"i": 91, "op": "add", "dst": 3, "src": 1, "src2": 1, "imm": "0xe2be00a5", "imm2": "0x3cc5bd20", "rot": 10, "bit": 31, "mask": 1}, + {"i": 92, "op": "shfl", "dst": 7, "src": 2, "src2": 4, "imm": "0x3d3da600", "imm2": "0x1f22df89", "rot": 4, "bit": 24, "mask": 1}, + {"i": 93, "op": "rotr", "dst": 6, "src": 2, "src2": 7, "imm": "0xb0f57471", "imm2": "0x8f2a7eca", "rot": 16, "bit": 25, "mask": 1}, + {"i": 94, "op": "rotl", "dst": 7, "src": 0, "src2": 4, "imm": "0x00a21815", "imm2": "0xeb4d7218", "rot": 14, "bit": 18, "mask": 16}, + {"i": 95, "op": "mad", "dst": 4, "src": 5, "src2": 5, "imm": "0xc4c3828e", "imm2": "0xfb7bba17", "rot": 16, "bit": 10, "mask": 16}, + {"i": 96, "op": "mad", "dst": 2, "src": 4, "src2": 5, "imm": "0xfc5bbc75", "imm2": "0xfc43468f", "rot": 31, "bit": 20, "mask": 16}, + {"i": 97, "op": "xor", "dst": 1, "src": 0, "src2": 2, "imm": "0x1fe9c249", "imm2": "0x164bb16b", "rot": 15, "bit": 9, "mask": 4}, + {"i": 98, "op": "mul", "dst": 5, "src": 4, "src2": 1, "imm": "0xeda725fa", "imm2": "0x66f7e9a2", "rot": 21, "bit": 6, "mask": 2}, + {"i": 99, "op": "sub", "dst": 2, "src": 0, "src2": 7, "imm": "0x8fb29f7d", "imm2": "0xf530eda1", "rot": 27, "bit": 30, "mask": 4}, + {"i": 100, "op": "rotl", "dst": 7, "src": 2, "src2": 0, "imm": "0x9f4de742", "imm2": "0x9b5ff871", "rot": 30, "bit": 21, "mask": 16}, + {"i": 101, "op": "add", "dst": 5, "src": 6, "src2": 7, "imm": "0x423fd9c9", "imm2": "0xbfd646cb", "rot": 17, "bit": 17, "mask": 2}, + {"i": 102, "op": "add", "dst": 7, "src": 6, "src2": 3, "imm": "0x8d3c011d", "imm2": "0x19b74a43", "rot": 12, "bit": 11, "mask": 4}, + {"i": 103, "op": "rotl", "dst": 5, "src": 6, "src2": 0, "imm": "0xcfc70303", "imm2": "0xf2b3e8ef", "rot": 6, "bit": 24, "mask": 1}, + {"i": 104, "op": "mul", "dst": 0, "src": 4, "src2": 5, "imm": "0x650475eb", "imm2": "0x11dcbd94", "rot": 15, "bit": 10, "mask": 1}, + {"i": 105, "op": "or", "dst": 0, "src": 5, "src2": 3, "imm": "0xaacaa145", "imm2": "0x9139d3fe", "rot": 4, "bit": 18, "mask": 2}, + {"i": 106, "op": "add", "dst": 0, "src": 1, "src2": 7, "imm": "0x8ce14721", "imm2": "0x7dcb7e18", "rot": 24, "bit": 15, "mask": 8}, + {"i": 107, "op": "rotl", "dst": 0, "src": 3, "src2": 3, "imm": "0xb36d6d98", "imm2": "0x2c3390c8", "rot": 15, "bit": 10, "mask": 16}, + {"i": 108, "op": "sub", "dst": 4, "src": 2, "src2": 5, "imm": "0xf6bbdaef", "imm2": "0x9db6f65e", "rot": 25, "bit": 10, "mask": 1}, + {"i": 109, "op": "mulhi", "dst": 2, "src": 0, "src2": 0, "imm": "0xb1721fd6", "imm2": "0xd96d52c9", "rot": 1, "bit": 27, "mask": 8}, + {"i": 110, "op": "mulhi", "dst": 1, "src": 0, "src2": 5, "imm": "0xfb4ca37f", "imm2": "0xb6ec7dbe", "rot": 27, "bit": 12, "mask": 8}, + {"i": 111, "op": "add", "dst": 0, "src": 2, "src2": 0, "imm": "0x2d9fc6b9", "imm2": "0x3c179ad8", "rot": 9, "bit": 28, "mask": 16}, + {"i": 112, "op": "mulhi", "dst": 2, "src": 0, "src2": 6, "imm": "0x71a9f6bd", "imm2": "0xd3417bf5", "rot": 2, "bit": 14, "mask": 8}, + {"i": 113, "op": "sub", "dst": 6, "src": 3, "src2": 5, "imm": "0xa3d19400", "imm2": "0x15df7330", "rot": 5, "bit": 2, "mask": 8}, + {"i": 114, "op": "mad", "dst": 7, "src": 6, "src2": 3, "imm": "0x1400d92e", "imm2": "0xfa4a158e", "rot": 16, "bit": 9, "mask": 1}, + {"i": 115, "op": "rotr", "dst": 5, "src": 1, "src2": 3, "imm": "0xd01684c3", "imm2": "0x6367febb", "rot": 23, "bit": 19, "mask": 2}, + {"i": 116, "op": "rotr", "dst": 6, "src": 4, "src2": 2, "imm": "0x8cd9eb96", "imm2": "0x98f33b24", "rot": 25, "bit": 1, "mask": 2}, + {"i": 117, "op": "add", "dst": 2, "src": 1, "src2": 7, "imm": "0x502138e2", "imm2": "0x47359729", "rot": 5, "bit": 22, "mask": 4}, + {"i": 118, "op": "mad", "dst": 3, "src": 2, "src2": 0, "imm": "0xd94a35c7", "imm2": "0xb83416c3", "rot": 11, "bit": 3, "mask": 4}, + {"i": 119, "op": "mul", "dst": 1, "src": 3, "src2": 6, "imm": "0x09b30cf7", "imm2": "0xef3b98e7", "rot": 17, "bit": 23, "mask": 8}, + {"i": 120, "op": "mad", "dst": 2, "src": 0, "src2": 4, "imm": "0x56416fe0", "imm2": "0x5e1dc8f3", "rot": 17, "bit": 14, "mask": 2}, + {"i": 121, "op": "mul", "dst": 0, "src": 3, "src2": 2, "imm": "0x2892697c", "imm2": "0x9cb3b14e", "rot": 29, "bit": 25, "mask": 2}, + {"i": 122, "op": "mulhi", "dst": 2, "src": 0, "src2": 3, "imm": "0xc33089a1", "imm2": "0xd6c5b530", "rot": 27, "bit": 13, "mask": 8}, + {"i": 123, "op": "mul", "dst": 5, "src": 6, "src2": 4, "imm": "0xdfe04e4a", "imm2": "0x3cc40160", "rot": 3, "bit": 14, "mask": 2}, + {"i": 124, "op": "mad", "dst": 4, "src": 2, "src2": 4, "imm": "0xb33dc1b7", "imm2": "0xab97743a", "rot": 7, "bit": 21, "mask": 4}, + {"i": 125, "op": "shfl", "dst": 4, "src": 2, "src2": 0, "imm": "0xfd469909", "imm2": "0xfc85dc55", "rot": 28, "bit": 24, "mask": 2}, + {"i": 126, "op": "xor", "dst": 2, "src": 0, "src2": 5, "imm": "0xa0094578", "imm2": "0xf1bee474", "rot": 31, "bit": 7, "mask": 2}, + {"i": 127, "op": "rotl", "dst": 1, "src": 7, "src2": 2, "imm": "0xb7ae00a0", "imm2": "0x86cce297", "rot": 7, "bit": 31, "mask": 8}, + {"i": 128, "op": "shfl", "dst": 7, "src": 2, "src2": 7, "imm": "0x019d1940", "imm2": "0x3fe9e7dd", "rot": 14, "bit": 4, "mask": 4}, + {"i": 129, "op": "rotl", "dst": 6, "src": 7, "src2": 7, "imm": "0x40a74cc4", "imm2": "0x09eb4adf", "rot": 17, "bit": 30, "mask": 1}, + {"i": 130, "op": "add", "dst": 2, "src": 5, "src2": 5, "imm": "0x33dff776", "imm2": "0x6c57e4e7", "rot": 27, "bit": 15, "mask": 4}, + {"i": 131, "op": "or", "dst": 0, "src": 3, "src2": 1, "imm": "0xe0c53bb9", "imm2": "0x124404f6", "rot": 4, "bit": 21, "mask": 16}, + {"i": 132, "op": "rotr", "dst": 5, "src": 0, "src2": 1, "imm": "0xe4353fce", "imm2": "0x559d0118", "rot": 2, "bit": 29, "mask": 4}, + {"i": 133, "op": "add", "dst": 2, "src": 3, "src2": 6, "imm": "0x5db25b34", "imm2": "0xe8212c0c", "rot": 21, "bit": 30, "mask": 1}, + {"i": 134, "op": "xor", "dst": 4, "src": 3, "src2": 6, "imm": "0x7366e50e", "imm2": "0x7cc1ffbd", "rot": 19, "bit": 18, "mask": 16}, + {"i": 135, "op": "xor", "dst": 6, "src": 1, "src2": 2, "imm": "0xa36decb7", "imm2": "0x79291734", "rot": 26, "bit": 0, "mask": 8}, + {"i": 136, "op": "sub", "dst": 1, "src": 7, "src2": 0, "imm": "0x225b03e4", "imm2": "0x7183e193", "rot": 16, "bit": 6, "mask": 2}, + {"i": 137, "op": "mad", "dst": 2, "src": 6, "src2": 2, "imm": "0x6f620d51", "imm2": "0x4e814e19", "rot": 6, "bit": 6, "mask": 2}, + {"i": 138, "op": "mulhi", "dst": 0, "src": 5, "src2": 6, "imm": "0x919d6bf3", "imm2": "0xc6240638", "rot": 17, "bit": 11, "mask": 16}, + {"i": 139, "op": "add", "dst": 2, "src": 7, "src2": 7, "imm": "0x218d4090", "imm2": "0xd44ff710", "rot": 1, "bit": 10, "mask": 16}, + {"i": 140, "op": "rotr", "dst": 1, "src": 4, "src2": 4, "imm": "0x4cbfa722", "imm2": "0x114e9564", "rot": 28, "bit": 9, "mask": 16}, + {"i": 141, "op": "shfl", "dst": 3, "src": 6, "src2": 2, "imm": "0xf702c6a1", "imm2": "0xf8f3c5d9", "rot": 7, "bit": 24, "mask": 1}, + {"i": 142, "op": "mad", "dst": 7, "src": 6, "src2": 2, "imm": "0xa2d285be", "imm2": "0x9cc94532", "rot": 15, "bit": 20, "mask": 8}, + {"i": 143, "op": "mul", "dst": 2, "src": 3, "src2": 7, "imm": "0x08b7ed80", "imm2": "0xa8abced4", "rot": 18, "bit": 10, "mask": 4}, + {"i": 144, "op": "add", "dst": 7, "src": 4, "src2": 2, "imm": "0xf4b1a8de", "imm2": "0xb98942fa", "rot": 18, "bit": 29, "mask": 8}, + {"i": 145, "op": "rotl", "dst": 7, "src": 6, "src2": 1, "imm": "0x64b6ba2d", "imm2": "0xf9e86793", "rot": 15, "bit": 24, "mask": 8}, + {"i": 146, "op": "xor", "dst": 7, "src": 5, "src2": 3, "imm": "0x41c42b5f", "imm2": "0x7c7e0e39", "rot": 8, "bit": 23, "mask": 2}, + {"i": 147, "op": "mad", "dst": 4, "src": 7, "src2": 4, "imm": "0x3caa807a", "imm2": "0x553a0cec", "rot": 11, "bit": 22, "mask": 8}, + {"i": 148, "op": "rotr", "dst": 6, "src": 5, "src2": 3, "imm": "0x3cb1289a", "imm2": "0x6b36f78a", "rot": 1, "bit": 9, "mask": 16}, + {"i": 149, "op": "mad", "dst": 1, "src": 2, "src2": 4, "imm": "0x95310ea8", "imm2": "0xc533aa6a", "rot": 16, "bit": 17, "mask": 1}, + {"i": 150, "op": "add", "dst": 1, "src": 7, "src2": 7, "imm": "0x2bef10f2", "imm2": "0x0d48ba42", "rot": 8, "bit": 17, "mask": 4}, + {"i": 151, "op": "xor", "dst": 5, "src": 4, "src2": 7, "imm": "0xda997ab2", "imm2": "0xae31d69e", "rot": 11, "bit": 31, "mask": 2}, + {"i": 152, "op": "add", "dst": 7, "src": 0, "src2": 6, "imm": "0xdc5cc080", "imm2": "0xc98dea9c", "rot": 16, "bit": 30, "mask": 2}, + {"i": 153, "op": "mul", "dst": 4, "src": 6, "src2": 7, "imm": "0xbfbf5f6c", "imm2": "0x61f611bb", "rot": 14, "bit": 22, "mask": 2}, + {"i": 154, "op": "mul", "dst": 0, "src": 2, "src2": 3, "imm": "0xa78008c3", "imm2": "0xbad5eeb1", "rot": 10, "bit": 28, "mask": 8}, + {"i": 155, "op": "xor", "dst": 6, "src": 5, "src2": 4, "imm": "0x1a73b866", "imm2": "0x1f5a62c9", "rot": 9, "bit": 27, "mask": 8}, + {"i": 156, "op": "rotr", "dst": 4, "src": 2, "src2": 0, "imm": "0x9c88500c", "imm2": "0xe25dccf9", "rot": 11, "bit": 2, "mask": 16}, + {"i": 157, "op": "rotl", "dst": 1, "src": 4, "src2": 4, "imm": "0xb05e7669", "imm2": "0x9db704b1", "rot": 11, "bit": 28, "mask": 4}, + {"i": 158, "op": "add", "dst": 5, "src": 0, "src2": 6, "imm": "0x18197438", "imm2": "0x6c752dcb", "rot": 11, "bit": 11, "mask": 2}, + {"i": 159, "op": "mad", "dst": 4, "src": 1, "src2": 5, "imm": "0x4796a65e", "imm2": "0x00e08c7a", "rot": 8, "bit": 19, "mask": 4}, + {"i": 160, "op": "rotl", "dst": 4, "src": 7, "src2": 5, "imm": "0x08a03052", "imm2": "0x0204f0ba", "rot": 26, "bit": 5, "mask": 2}, + {"i": 161, "op": "mad", "dst": 3, "src": 0, "src2": 7, "imm": "0xa0603b0e", "imm2": "0x7eee83d5", "rot": 28, "bit": 22, "mask": 16}, + {"i": 162, "op": "rotr", "dst": 3, "src": 1, "src2": 6, "imm": "0x78a3c69d", "imm2": "0x684693a0", "rot": 21, "bit": 23, "mask": 4}, + {"i": 163, "op": "add", "dst": 4, "src": 0, "src2": 7, "imm": "0xf1c46574", "imm2": "0x8e481727", "rot": 9, "bit": 3, "mask": 4}, + {"i": 164, "op": "mulhi", "dst": 0, "src": 4, "src2": 3, "imm": "0x04644afa", "imm2": "0x64bda2b5", "rot": 26, "bit": 16, "mask": 16}, + {"i": 165, "op": "add", "dst": 2, "src": 6, "src2": 2, "imm": "0xac578137", "imm2": "0x550ab406", "rot": 13, "bit": 20, "mask": 16}, + {"i": 166, "op": "rotl", "dst": 0, "src": 4, "src2": 5, "imm": "0x7f564760", "imm2": "0xb9a8b4f8", "rot": 13, "bit": 29, "mask": 1}, + {"i": 167, "op": "add", "dst": 3, "src": 1, "src2": 0, "imm": "0xa33e6706", "imm2": "0xaebb5966", "rot": 12, "bit": 14, "mask": 16}, + {"i": 168, "op": "or", "dst": 3, "src": 5, "src2": 3, "imm": "0x65b2f3eb", "imm2": "0xb1d00d20", "rot": 12, "bit": 2, "mask": 8}, + {"i": 169, "op": "rotr", "dst": 6, "src": 2, "src2": 3, "imm": "0x7f21faf5", "imm2": "0xbbf0d3f9", "rot": 17, "bit": 13, "mask": 8}, + {"i": 170, "op": "xor", "dst": 4, "src": 6, "src2": 2, "imm": "0x162c7140", "imm2": "0x90d404ad", "rot": 26, "bit": 1, "mask": 4}, + {"i": 171, "op": "sub", "dst": 6, "src": 1, "src2": 7, "imm": "0x6ef9c76e", "imm2": "0xfb7ba272", "rot": 31, "bit": 25, "mask": 1}, + {"i": 172, "op": "rotl", "dst": 7, "src": 5, "src2": 4, "imm": "0xde04eb3b", "imm2": "0xd56caa00", "rot": 22, "bit": 21, "mask": 4}, + {"i": 173, "op": "rotl", "dst": 5, "src": 3, "src2": 5, "imm": "0xa9eac934", "imm2": "0x2c338e51", "rot": 15, "bit": 22, "mask": 2}, + {"i": 174, "op": "shfl", "dst": 7, "src": 0, "src2": 3, "imm": "0x700be4e3", "imm2": "0x4bcfc732", "rot": 19, "bit": 6, "mask": 8}, + {"i": 175, "op": "xor", "dst": 0, "src": 5, "src2": 1, "imm": "0x02ccdba9", "imm2": "0xd0915be0", "rot": 15, "bit": 2, "mask": 16}, + {"i": 176, "op": "rotl", "dst": 7, "src": 4, "src2": 1, "imm": "0x489c8165", "imm2": "0xf24b5a4f", "rot": 6, "bit": 22, "mask": 1}, + {"i": 177, "op": "sub", "dst": 7, "src": 0, "src2": 6, "imm": "0x23ad9693", "imm2": "0x9a8c2f7b", "rot": 24, "bit": 2, "mask": 2}, + {"i": 178, "op": "rotl", "dst": 3, "src": 0, "src2": 6, "imm": "0xafa72a42", "imm2": "0x371d74ee", "rot": 30, "bit": 16, "mask": 1}, + {"i": 179, "op": "mad", "dst": 7, "src": 6, "src2": 1, "imm": "0x18a2a3f3", "imm2": "0xb811b951", "rot": 2, "bit": 9, "mask": 2}, + {"i": 180, "op": "rotl", "dst": 6, "src": 4, "src2": 1, "imm": "0xe6c69c0e", "imm2": "0xfc46a951", "rot": 9, "bit": 31, "mask": 4}, + {"i": 181, "op": "xor", "dst": 2, "src": 4, "src2": 7, "imm": "0xbd1b89e4", "imm2": "0xdf4bce5c", "rot": 15, "bit": 19, "mask": 4}, + {"i": 182, "op": "xor", "dst": 2, "src": 7, "src2": 5, "imm": "0x3dd12aed", "imm2": "0xd0756a69", "rot": 13, "bit": 16, "mask": 4}, + {"i": 183, "op": "xor", "dst": 7, "src": 2, "src2": 3, "imm": "0x77ce69d6", "imm2": "0x2b39bdf2", "rot": 8, "bit": 22, "mask": 16}, + {"i": 184, "op": "add", "dst": 1, "src": 2, "src2": 4, "imm": "0xd94d55ac", "imm2": "0x5bb7550f", "rot": 31, "bit": 21, "mask": 1}, + {"i": 185, "op": "or", "dst": 3, "src": 5, "src2": 6, "imm": "0x7b1ce846", "imm2": "0xcc3b8509", "rot": 28, "bit": 9, "mask": 4}, + {"i": 186, "op": "mulhi", "dst": 6, "src": 3, "src2": 0, "imm": "0xa5e24690", "imm2": "0x2200ba81", "rot": 26, "bit": 10, "mask": 16}, + {"i": 187, "op": "or", "dst": 4, "src": 0, "src2": 3, "imm": "0xf6efe759", "imm2": "0xae1f7118", "rot": 19, "bit": 20, "mask": 4}, + {"i": 188, "op": "shfl", "dst": 7, "src": 1, "src2": 5, "imm": "0xdb318b45", "imm2": "0xcec459c9", "rot": 20, "bit": 11, "mask": 2}, + {"i": 189, "op": "add", "dst": 6, "src": 5, "src2": 1, "imm": "0x89e747fe", "imm2": "0x2a354e2d", "rot": 22, "bit": 6, "mask": 1}, + {"i": 190, "op": "xor", "dst": 1, "src": 4, "src2": 2, "imm": "0xc379e617", "imm2": "0x75e9d63b", "rot": 23, "bit": 3, "mask": 2}, + {"i": 191, "op": "mulhi", "dst": 7, "src": 4, "src2": 3, "imm": "0x5a710287", "imm2": "0x7fe4ead6", "rot": 10, "bit": 25, "mask": 4}, + {"i": 192, "op": "rotl", "dst": 2, "src": 1, "src2": 2, "imm": "0x4d5e59a3", "imm2": "0x1e4fef28", "rot": 26, "bit": 0, "mask": 1}, + {"i": 193, "op": "rotl", "dst": 5, "src": 3, "src2": 7, "imm": "0x7444c47d", "imm2": "0xdad5f8be", "rot": 8, "bit": 30, "mask": 2}, + {"i": 194, "op": "shfl", "dst": 4, "src": 5, "src2": 7, "imm": "0x6a225bbb", "imm2": "0xd6532cd7", "rot": 13, "bit": 17, "mask": 16}, + {"i": 195, "op": "xor", "dst": 4, "src": 5, "src2": 3, "imm": "0x68344b9a", "imm2": "0xcb46a38b", "rot": 1, "bit": 27, "mask": 16}, + {"i": 196, "op": "mul", "dst": 1, "src": 3, "src2": 4, "imm": "0xbebf7359", "imm2": "0x3f0890ba", "rot": 18, "bit": 12, "mask": 4}, + {"i": 197, "op": "add", "dst": 5, "src": 2, "src2": 3, "imm": "0xea03e8e7", "imm2": "0x10cfdc71", "rot": 31, "bit": 7, "mask": 8}, + {"i": 198, "op": "add", "dst": 7, "src": 5, "src2": 1, "imm": "0xa7ee0102", "imm2": "0x66e148d3", "rot": 12, "bit": 15, "mask": 1}, + {"i": 199, "op": "sub", "dst": 5, "src": 2, "src2": 4, "imm": "0xc215584e", "imm2": "0x55fce30f", "rot": 30, "bit": 9, "mask": 2}, + {"i": 200, "op": "shfl", "dst": 5, "src": 1, "src2": 1, "imm": "0x308f8358", "imm2": "0x489f1f93", "rot": 13, "bit": 13, "mask": 2}, + {"i": 201, "op": "shfl", "dst": 7, "src": 1, "src2": 5, "imm": "0x713f1957", "imm2": "0x2239f757", "rot": 15, "bit": 7, "mask": 8}, + {"i": 202, "op": "rotr", "dst": 4, "src": 5, "src2": 1, "imm": "0xb037b6e7", "imm2": "0x49a8b528", "rot": 27, "bit": 13, "mask": 16}, + {"i": 203, "op": "xor", "dst": 7, "src": 5, "src2": 1, "imm": "0x56110241", "imm2": "0xefc8386d", "rot": 22, "bit": 20, "mask": 1}, + {"i": 204, "op": "xor", "dst": 7, "src": 0, "src2": 0, "imm": "0x0827fcc7", "imm2": "0xf4f5dd07", "rot": 13, "bit": 7, "mask": 2}, + {"i": 205, "op": "add", "dst": 6, "src": 2, "src2": 0, "imm": "0x8379a4de", "imm2": "0x8558b619", "rot": 26, "bit": 10, "mask": 1}, + {"i": 206, "op": "rotl", "dst": 4, "src": 3, "src2": 3, "imm": "0x091ceef0", "imm2": "0x69b0f72f", "rot": 13, "bit": 7, "mask": 1}, + {"i": 207, "op": "mulhi", "dst": 1, "src": 3, "src2": 4, "imm": "0x758edac1", "imm2": "0x98dd2f21", "rot": 15, "bit": 9, "mask": 1}, + {"i": 208, "op": "mad", "dst": 1, "src": 4, "src2": 4, "imm": "0x78871a1a", "imm2": "0x5e14e1c8", "rot": 19, "bit": 6, "mask": 2}, + {"i": 209, "op": "shfl", "dst": 2, "src": 0, "src2": 2, "imm": "0xf7e0b9aa", "imm2": "0xaecfd347", "rot": 21, "bit": 9, "mask": 4}, + {"i": 210, "op": "add", "dst": 7, "src": 0, "src2": 7, "imm": "0xaa8cb14e", "imm2": "0xf4049c4c", "rot": 24, "bit": 11, "mask": 8}, + {"i": 211, "op": "shfl", "dst": 7, "src": 1, "src2": 6, "imm": "0xc230d919", "imm2": "0xf76d08fb", "rot": 21, "bit": 13, "mask": 16}, + {"i": 212, "op": "xor", "dst": 1, "src": 0, "src2": 2, "imm": "0x31a5af90", "imm2": "0x7eef58ee", "rot": 9, "bit": 12, "mask": 4}, + {"i": 213, "op": "rotl", "dst": 7, "src": 1, "src2": 6, "imm": "0x0db26138", "imm2": "0x8e3c31f9", "rot": 3, "bit": 26, "mask": 2}, + {"i": 214, "op": "rotr", "dst": 4, "src": 7, "src2": 3, "imm": "0x29558100", "imm2": "0xe4b13ad6", "rot": 29, "bit": 24, "mask": 8}, + {"i": 215, "op": "shfl", "dst": 3, "src": 2, "src2": 6, "imm": "0x1b48c3d0", "imm2": "0x5c674ff6", "rot": 5, "bit": 9, "mask": 16}, + {"i": 216, "op": "or", "dst": 5, "src": 1, "src2": 0, "imm": "0xef768632", "imm2": "0x6de9d10d", "rot": 10, "bit": 4, "mask": 4}, + {"i": 217, "op": "sub", "dst": 1, "src": 2, "src2": 5, "imm": "0x88ca7f5a", "imm2": "0x24718a36", "rot": 18, "bit": 31, "mask": 1}, + {"i": 218, "op": "sub", "dst": 6, "src": 5, "src2": 0, "imm": "0xc4a06728", "imm2": "0xdc2a4fd8", "rot": 9, "bit": 9, "mask": 2}, + {"i": 219, "op": "rotl", "dst": 6, "src": 5, "src2": 7, "imm": "0xb7489e47", "imm2": "0xf13795c5", "rot": 4, "bit": 3, "mask": 8}, + {"i": 220, "op": "mulhi", "dst": 2, "src": 0, "src2": 2, "imm": "0x873cd31b", "imm2": "0x3dfbc55d", "rot": 12, "bit": 23, "mask": 8}, + {"i": 221, "op": "or", "dst": 2, "src": 0, "src2": 3, "imm": "0xdc21f099", "imm2": "0xee06f01e", "rot": 2, "bit": 17, "mask": 8}, + {"i": 222, "op": "shfl", "dst": 5, "src": 2, "src2": 6, "imm": "0x36def499", "imm2": "0xa2849d59", "rot": 23, "bit": 4, "mask": 8}, + {"i": 223, "op": "mulhi", "dst": 5, "src": 6, "src2": 7, "imm": "0xfb95fbca", "imm2": "0xc1aac427", "rot": 14, "bit": 11, "mask": 2}, + {"i": 224, "op": "sub", "dst": 0, "src": 6, "src2": 7, "imm": "0x3d9d29c4", "imm2": "0x34d0dcc0", "rot": 17, "bit": 6, "mask": 4}, + {"i": 225, "op": "rotl", "dst": 7, "src": 0, "src2": 5, "imm": "0x93b01b8e", "imm2": "0xfe1d75ac", "rot": 23, "bit": 15, "mask": 1}, + {"i": 226, "op": "or", "dst": 4, "src": 2, "src2": 4, "imm": "0xfed76e8e", "imm2": "0x1c24ecd8", "rot": 2, "bit": 6, "mask": 16}, + {"i": 227, "op": "mul", "dst": 2, "src": 4, "src2": 1, "imm": "0x5795f5b0", "imm2": "0x0566ea2a", "rot": 6, "bit": 28, "mask": 4}, + {"i": 228, "op": "rotl", "dst": 3, "src": 0, "src2": 2, "imm": "0x8c8486de", "imm2": "0xd066aa8f", "rot": 12, "bit": 20, "mask": 1}, + {"i": 229, "op": "rotr", "dst": 0, "src": 4, "src2": 0, "imm": "0x23a3e882", "imm2": "0xaca23902", "rot": 5, "bit": 22, "mask": 16}, + {"i": 230, "op": "add", "dst": 0, "src": 6, "src2": 4, "imm": "0x1d176220", "imm2": "0x2a7fecb2", "rot": 20, "bit": 16, "mask": 2}, + {"i": 231, "op": "shfl", "dst": 1, "src": 2, "src2": 0, "imm": "0x91172787", "imm2": "0xc5d7af28", "rot": 3, "bit": 24, "mask": 4}, + {"i": 232, "op": "mul", "dst": 2, "src": 1, "src2": 2, "imm": "0x0be68835", "imm2": "0xde692bdb", "rot": 30, "bit": 17, "mask": 1}, + {"i": 233, "op": "mad", "dst": 7, "src": 0, "src2": 1, "imm": "0xf90d2db5", "imm2": "0x96c4c175", "rot": 28, "bit": 7, "mask": 4}, + {"i": 234, "op": "rotl", "dst": 5, "src": 2, "src2": 1, "imm": "0x16379736", "imm2": "0x6973b905", "rot": 22, "bit": 17, "mask": 4}, + {"i": 235, "op": "rotr", "dst": 4, "src": 6, "src2": 2, "imm": "0x84292a13", "imm2": "0x0f897740", "rot": 12, "bit": 6, "mask": 8}, + {"i": 236, "op": "mad", "dst": 0, "src": 5, "src2": 1, "imm": "0xeb7de837", "imm2": "0x64f0c302", "rot": 4, "bit": 19, "mask": 1}, + {"i": 237, "op": "xor", "dst": 6, "src": 4, "src2": 4, "imm": "0x6ab4b683", "imm2": "0x20f17adb", "rot": 1, "bit": 0, "mask": 16}, + {"i": 238, "op": "xor", "dst": 4, "src": 6, "src2": 1, "imm": "0x5836b35c", "imm2": "0x3293cc4a", "rot": 16, "bit": 22, "mask": 16}, + {"i": 239, "op": "rotl", "dst": 6, "src": 1, "src2": 6, "imm": "0x769d8bc0", "imm2": "0xdc86c9cc", "rot": 18, "bit": 27, "mask": 16}, + {"i": 240, "op": "add", "dst": 4, "src": 7, "src2": 1, "imm": "0x17dafb4d", "imm2": "0xadce39f3", "rot": 12, "bit": 25, "mask": 8}, + {"i": 241, "op": "sub", "dst": 0, "src": 7, "src2": 4, "imm": "0xd4690bda", "imm2": "0xdab9b27b", "rot": 30, "bit": 21, "mask": 1}, + {"i": 242, "op": "rotr", "dst": 1, "src": 6, "src2": 2, "imm": "0x670a2d0a", "imm2": "0x0612e33c", "rot": 31, "bit": 25, "mask": 2}, + {"i": 243, "op": "add", "dst": 3, "src": 0, "src2": 2, "imm": "0xf2f77d26", "imm2": "0x0e7033b6", "rot": 27, "bit": 29, "mask": 1}, + {"i": 244, "op": "mad", "dst": 2, "src": 7, "src2": 4, "imm": "0xa9eefc9d", "imm2": "0x16166c85", "rot": 18, "bit": 23, "mask": 16}, + {"i": 245, "op": "mad", "dst": 4, "src": 0, "src2": 6, "imm": "0xb26f6c0f", "imm2": "0x0630e821", "rot": 23, "bit": 30, "mask": 4}, + {"i": 246, "op": "mul", "dst": 5, "src": 7, "src2": 2, "imm": "0x269ce4bf", "imm2": "0x1ce28d32", "rot": 30, "bit": 15, "mask": 16}, + {"i": 247, "op": "add", "dst": 3, "src": 5, "src2": 0, "imm": "0xfed2da4e", "imm2": "0x7b2ff6b7", "rot": 25, "bit": 31, "mask": 2}, + {"i": 248, "op": "add", "dst": 0, "src": 7, "src2": 5, "imm": "0x03b2891c", "imm2": "0xb5fad7b1", "rot": 2, "bit": 0, "mask": 4}, + {"i": 249, "op": "mulhi", "dst": 5, "src": 4, "src2": 6, "imm": "0xa69a1e71", "imm2": "0x15f0c0ea", "rot": 4, "bit": 1, "mask": 4}, + {"i": 250, "op": "add", "dst": 5, "src": 2, "src2": 3, "imm": "0x042cd6e3", "imm2": "0xa7e71c2f", "rot": 24, "bit": 11, "mask": 8}, + {"i": 251, "op": "shfl", "dst": 6, "src": 1, "src2": 2, "imm": "0x89c6b683", "imm2": "0x10bbf661", "rot": 24, "bit": 5, "mask": 1}, + {"i": 252, "op": "xor", "dst": 6, "src": 1, "src2": 3, "imm": "0x265c66d6", "imm2": "0xd4a689ed", "rot": 6, "bit": 14, "mask": 8}, + {"i": 253, "op": "mul", "dst": 2, "src": 5, "src2": 5, "imm": "0x890b8201", "imm2": "0x97c36bf3", "rot": 17, "bit": 22, "mask": 4}, + {"i": 254, "op": "add", "dst": 0, "src": 6, "src2": 0, "imm": "0x784a302b", "imm2": "0xb83d78de", "rot": 27, "bit": 16, "mask": 4}, + {"i": 255, "op": "sub", "dst": 2, "src": 4, "src2": 0, "imm": "0x817adb38", "imm2": "0xf3a3534b", "rot": 7, "bit": 22, "mask": 4} + ]}, + "instructions": [ + {"i": 0, "op": "mad", "dst": 2, "src": 3, "src2": 4, "imm": "0xbf7b174d", "imm2": "0x337b762e", "rot": 17, "bit": 2, "mask": 2, "width": 1}, + {"i": 1, "op": "mad", "dst": 2, "src": 1, "src2": 1, "imm": "0xdd04a5da", "imm2": "0x42da7657", "rot": 15, "bit": 30, "mask": 16, "width": 1}, + {"i": 2, "op": "mad", "dst": 2, "src": 3, "src2": 2, "imm": "0x734003fa", "imm2": "0x5bb67700", "rot": 3, "bit": 20, "mask": 1, "width": 1}, + {"i": 3, "op": "xor", "dst": 3, "src": 5, "src2": 5, "imm": "0xc55a1b1c", "imm2": "0xa19720f3", "rot": 7, "bit": 8, "mask": 1, "width": 1}, + {"i": 4, "op": "load", "dst": 7, "src": 2, "src2": 5, "imm": "0xad572dd7", "imm2": "0x9ceb3ea7", "rot": 18, "bit": 30, "mask": 2, "width": 1}, + {"i": 5, "op": "load", "dst": 5, "src": 7, "src2": 3, "imm": "0x769a53be", "imm2": "0x80f9067e", "rot": 12, "bit": 22, "mask": 1, "width": 1}, + {"i": 6, "op": "shfl", "dst": 1, "src": 4, "src2": 0, "imm": "0xd3613d88", "imm2": "0x262fb219", "rot": 10, "bit": 30, "mask": 8, "width": 1}, + {"i": 7, "op": "shfl", "dst": 7, "src": 3, "src2": 4, "imm": "0xce38e42f", "imm2": "0xb868b818", "rot": 11, "bit": 8, "mask": 8, "width": 1}, + {"i": 8, "op": "mulhi", "dst": 1, "src": 5, "src2": 2, "imm": "0xa5eebca5", "imm2": "0x5703a72b", "rot": 13, "bit": 13, "mask": 16, "width": 1}, + {"i": 9, "op": "rotr", "dst": 6, "src": 3, "src2": 4, "imm": "0x17a5a9c7", "imm2": "0xdcfb93a1", "rot": 20, "bit": 27, "mask": 2, "width": 1}, + {"i": 10, "op": "or", "dst": 3, "src": 4, "src2": 1, "imm": "0xccb7d785", "imm2": "0xc335364c", "rot": 14, "bit": 12, "mask": 4, "width": 1}, + {"i": 11, "op": "load", "dst": 4, "src": 3, "src2": 2, "imm": "0x88cb9af3", "imm2": "0x4e7dc10d", "rot": 24, "bit": 17, "mask": 4, "width": 1}, + {"i": 12, "op": "mulhi", "dst": 0, "src": 4, "src2": 4, "imm": "0x45374321", "imm2": "0x3cd91989", "rot": 11, "bit": 4, "mask": 2, "width": 1}, + {"i": 13, "op": "add", "dst": 5, "src": 1, "src2": 2, "imm": "0xc7934706", "imm2": "0xd3177981", "rot": 16, "bit": 30, "mask": 2, "width": 1}, + {"i": 14, "op": "load", "dst": 0, "src": 4, "src2": 3, "imm": "0xfd7f56bb", "imm2": "0x65e14f52", "rot": 13, "bit": 22, "mask": 2, "width": 1}, + {"i": 15, "op": "sub", "dst": 2, "src": 4, "src2": 4, "imm": "0x35a80b49", "imm2": "0x060f2d13", "rot": 16, "bit": 20, "mask": 16, "width": 1}, + {"i": 16, "op": "load", "dst": 2, "src": 0, "src2": 2, "imm": "0xae0a32c2", "imm2": "0x4c2a4cfe", "rot": 8, "bit": 31, "mask": 16, "width": 1}, + {"i": 17, "op": "load", "dst": 7, "src": 2, "src2": 6, "imm": "0x82a84cc3", "imm2": "0x21a38d68", "rot": 15, "bit": 21, "mask": 2, "width": 1}, + {"i": 18, "op": "shfl", "dst": 7, "src": 3, "src2": 3, "imm": "0xa3818806", "imm2": "0x8f66b5c8", "rot": 14, "bit": 6, "mask": 4, "width": 1}, + {"i": 19, "op": "mul", "dst": 5, "src": 0, "src2": 1, "imm": "0xa00de107", "imm2": "0x77bfcaa5", "rot": 3, "bit": 10, "mask": 2, "width": 1}, + {"i": 20, "op": "shfl", "dst": 3, "src": 4, "src2": 7, "imm": "0x1d2b8cab", "imm2": "0x80b4f9a2", "rot": 14, "bit": 25, "mask": 2, "width": 1}, + {"i": 21, "op": "shfl", "dst": 2, "src": 4, "src2": 5, "imm": "0x3ac915d2", "imm2": "0x5fba7bc2", "rot": 16, "bit": 1, "mask": 16, "width": 1}, + {"i": 22, "op": "mulhi", "dst": 6, "src": 2, "src2": 0, "imm": "0xdc3ec8fd", "imm2": "0x599e2fa3", "rot": 22, "bit": 3, "mask": 2, "width": 1}, + {"i": 23, "op": "load", "dst": 6, "src": 1, "src2": 5, "imm": "0x2a6b16d5", "imm2": "0xd73e396f", "rot": 28, "bit": 29, "mask": 2, "width": 1}, + {"i": 24, "op": "mul", "dst": 5, "src": 0, "src2": 7, "imm": "0x376d0223", "imm2": "0xe1c2169a", "rot": 4, "bit": 16, "mask": 16, "width": 1}, + {"i": 25, "op": "rotl", "dst": 5, "src": 7, "src2": 3, "imm": "0x78ad8c60", "imm2": "0x6f5b77d5", "rot": 19, "bit": 11, "mask": 16, "width": 1}, + {"i": 26, "op": "shfl", "dst": 7, "src": 6, "src2": 5, "imm": "0x93915b9f", "imm2": "0x1e61fb6b", "rot": 28, "bit": 23, "mask": 2, "width": 1}, + {"i": 27, "op": "xor", "dst": 0, "src": 5, "src2": 7, "imm": "0x6378fe15", "imm2": "0x66c78f42", "rot": 12, "bit": 31, "mask": 8, "width": 1}, + {"i": 28, "op": "xor", "dst": 0, "src": 4, "src2": 7, "imm": "0x20a57fda", "imm2": "0x088c848e", "rot": 16, "bit": 13, "mask": 4, "width": 1}, + {"i": 29, "op": "sub", "dst": 3, "src": 0, "src2": 2, "imm": "0x49d95fd5", "imm2": "0x1a5f946a", "rot": 6, "bit": 12, "mask": 1, "width": 1}, + {"i": 30, "op": "mul", "dst": 5, "src": 1, "src2": 7, "imm": "0x0a816217", "imm2": "0x405c4f73", "rot": 13, "bit": 27, "mask": 4, "width": 1}, + {"i": 31, "op": "load", "dst": 7, "src": 2, "src2": 2, "imm": "0x09ed045e", "imm2": "0xd69c4715", "rot": 5, "bit": 9, "mask": 2, "width": 1}, + {"i": 32, "op": "load", "dst": 1, "src": 0, "src2": 6, "imm": "0xeb79ea49", "imm2": "0xcc587f5a", "rot": 6, "bit": 8, "mask": 16, "width": 1}, + {"i": 33, "op": "xor", "dst": 5, "src": 6, "src2": 1, "imm": "0x3027401e", "imm2": "0x5f20c27e", "rot": 18, "bit": 9, "mask": 2, "width": 1}, + {"i": 34, "op": "load", "dst": 5, "src": 1, "src2": 3, "imm": "0x0e1cab07", "imm2": "0x09356c5b", "rot": 19, "bit": 31, "mask": 1, "width": 1}, + {"i": 35, "op": "mulhi", "dst": 0, "src": 5, "src2": 2, "imm": "0x90e31357", "imm2": "0xabd32484", "rot": 26, "bit": 5, "mask": 8, "width": 1}, + {"i": 36, "op": "shfl", "dst": 5, "src": 2, "src2": 5, "imm": "0xee9a955f", "imm2": "0x31b3faed", "rot": 8, "bit": 24, "mask": 4, "width": 1}, + {"i": 37, "op": "load", "dst": 7, "src": 0, "src2": 7, "imm": "0x3ba2f832", "imm2": "0x1160dcd3", "rot": 4, "bit": 29, "mask": 1, "width": 1}, + {"i": 38, "op": "add", "dst": 3, "src": 1, "src2": 7, "imm": "0x75ba2fad", "imm2": "0x230c005c", "rot": 4, "bit": 27, "mask": 1, "width": 1}, + {"i": 39, "op": "shfl", "dst": 1, "src": 5, "src2": 3, "imm": "0xdbf37e75", "imm2": "0xb5ac1969", "rot": 30, "bit": 13, "mask": 4, "width": 1}, + {"i": 40, "op": "xor", "dst": 2, "src": 5, "src2": 5, "imm": "0x47f136c5", "imm2": "0x06ce9153", "rot": 19, "bit": 10, "mask": 2, "width": 1}, + {"i": 41, "op": "mad", "dst": 3, "src": 6, "src2": 3, "imm": "0xce13eff8", "imm2": "0x04cc1d55", "rot": 3, "bit": 1, "mask": 4, "width": 1}, + {"i": 42, "op": "sub", "dst": 6, "src": 7, "src2": 1, "imm": "0x6a65ab71", "imm2": "0x8fbc1bcd", "rot": 4, "bit": 1, "mask": 8, "width": 1}, + {"i": 43, "op": "xor", "dst": 7, "src": 0, "src2": 7, "imm": "0xdaeb4928", "imm2": "0xc0423027", "rot": 24, "bit": 11, "mask": 8, "width": 1}, + {"i": 44, "op": "load", "dst": 1, "src": 7, "src2": 7, "imm": "0x778f01c9", "imm2": "0x28cedcea", "rot": 12, "bit": 4, "mask": 16, "width": 1}, + {"i": 45, "op": "mul", "dst": 2, "src": 3, "src2": 2, "imm": "0xf4264f1b", "imm2": "0x0f627d56", "rot": 5, "bit": 28, "mask": 8, "width": 1}, + {"i": 46, "op": "mulhi", "dst": 1, "src": 5, "src2": 1, "imm": "0xffb2147a", "imm2": "0xccde9b05", "rot": 13, "bit": 9, "mask": 2, "width": 1}, + {"i": 47, "op": "sub", "dst": 4, "src": 3, "src2": 5, "imm": "0x73b36234", "imm2": "0x3f5d5997", "rot": 7, "bit": 18, "mask": 2, "width": 1}, + {"i": 48, "op": "rotr", "dst": 2, "src": 6, "src2": 3, "imm": "0x3a4d9aa9", "imm2": "0x212bec7b", "rot": 4, "bit": 29, "mask": 16, "width": 1}, + {"i": 49, "op": "load", "dst": 3, "src": 5, "src2": 2, "imm": "0x626f11df", "imm2": "0x56cd5bfd", "rot": 7, "bit": 1, "mask": 1, "width": 1}, + {"i": 50, "op": "add", "dst": 1, "src": 5, "src2": 6, "imm": "0x81b8bc2c", "imm2": "0x1907970c", "rot": 28, "bit": 7, "mask": 4, "width": 1}, + {"i": 51, "op": "mul", "dst": 0, "src": 2, "src2": 2, "imm": "0xa8848b30", "imm2": "0xef6ac348", "rot": 9, "bit": 15, "mask": 8, "width": 1}, + {"i": 52, "op": "add", "dst": 0, "src": 2, "src2": 0, "imm": "0x4f92b968", "imm2": "0x699fd448", "rot": 22, "bit": 6, "mask": 4, "width": 1}, + {"i": 53, "op": "add", "dst": 1, "src": 0, "src2": 2, "imm": "0x2bb965af", "imm2": "0x77b1520d", "rot": 2, "bit": 12, "mask": 8, "width": 1}, + {"i": 54, "op": "rotl", "dst": 7, "src": 1, "src2": 0, "imm": "0x553e678b", "imm2": "0x3cc8eae0", "rot": 14, "bit": 20, "mask": 2, "width": 1}, + {"i": 55, "op": "add", "dst": 3, "src": 7, "src2": 2, "imm": "0x7b0fe07a", "imm2": "0xa54c55a0", "rot": 10, "bit": 1, "mask": 1, "width": 1}, + {"i": 56, "op": "load", "dst": 6, "src": 7, "src2": 4, "imm": "0x01eba9aa", "imm2": "0x2758c0f7", "rot": 14, "bit": 15, "mask": 4, "width": 1}, + {"i": 57, "op": "rotr", "dst": 1, "src": 5, "src2": 2, "imm": "0x1f5267b3", "imm2": "0x236f5a27", "rot": 2, "bit": 31, "mask": 16, "width": 1}, + {"i": 58, "op": "load", "dst": 5, "src": 4, "src2": 3, "imm": "0xa9954a9b", "imm2": "0x6a54d4e8", "rot": 11, "bit": 10, "mask": 16, "width": 1}, + {"i": 59, "op": "load", "dst": 6, "src": 2, "src2": 4, "imm": "0x9923ff88", "imm2": "0x9357254e", "rot": 16, "bit": 1, "mask": 16, "width": 1}, + {"i": 60, "op": "mad", "dst": 3, "src": 5, "src2": 0, "imm": "0xc0cc51a6", "imm2": "0x3fd7701b", "rot": 20, "bit": 1, "mask": 4, "width": 1}, + {"i": 61, "op": "add", "dst": 5, "src": 7, "src2": 7, "imm": "0xaf9dd72d", "imm2": "0xad7493e7", "rot": 7, "bit": 31, "mask": 16, "width": 1}, + {"i": 62, "op": "add", "dst": 4, "src": 6, "src2": 2, "imm": "0x89841d87", "imm2": "0x1e07c3d9", "rot": 6, "bit": 27, "mask": 1, "width": 1}, + {"i": 63, "op": "rotl", "dst": 5, "src": 4, "src2": 2, "imm": "0xae210f8d", "imm2": "0x8e499ba4", "rot": 19, "bit": 9, "mask": 1, "width": 1} + ] +} diff --git a/proto-cuda/packs-ca3-shadow/sh256x40/program.metal b/proto-cuda/packs-ca3-shadow/sh256x40/program.metal new file mode 100644 index 000000000..aef8058fb --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x40/program.metal @@ -0,0 +1,368 @@ +#include +using namespace metal; + +#define MASK 0x0fffffffu +constant uint SEEDW[8] = { 0x67a9a7beu, 0x1a155b25u, 0xfddfb732u, 0x4b5af2e8u, 0xc55caf33u, 0xa27c13b7u, 0x06628a48u, 0x03852469u }; + +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 = r3 * r4 + r2; // 0 + r2 = r1 * r1 + r2; // 1 + r2 = r3 * r2 + r2; // 2 + r3 = r3 ^ r5; // 3 + r7 = r7 ^ dataset[r2 & MASK]; // 4 + r5 = r5 ^ dataset[r7 & MASK]; // 5 + r1 = r1 ^ simd_shuffle_xor(r4, (ushort)8); // 6 + r7 = r7 ^ simd_shuffle_xor(r3, (ushort)8); // 7 + r1 = mulhi(r1, r5); // 8 + r6 = rotr_var(r6, r3); // 9 + r3 = r3 | r4; // 10 + r4 = r4 ^ dataset[r3 & MASK]; // 11 + r0 = mulhi(r0, r4); // 12 + r5 = r5 + r1 + select(0xc7934706u, 0xd3177981u, ((sel >> 30u) & 1u) != 0u); // 13 + r0 = r0 ^ dataset[r4 & MASK]; // 14 + r2 = r2 - r4; // 15 + r2 = r2 ^ dataset[r0 & MASK]; // 16 + r7 = r7 ^ dataset[r2 & MASK]; // 17 + r7 = r7 ^ simd_shuffle_xor(r3, (ushort)4); // 18 + r5 = r5 * r0; // 19 + r3 = r3 ^ simd_shuffle_xor(r4, (ushort)2); // 20 + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)16); // 21 + r6 = mulhi(r6, r2); // 22 + r6 = r6 ^ dataset[r1 & MASK]; // 23 + r5 = r5 * r0; // 24 + r5 = rotl_imm(r5, 19u); // 25 + r7 = r7 ^ simd_shuffle_xor(r6, (ushort)2); // 26 + r0 = r0 ^ r5; // 27 + r0 = r0 ^ r4; // 28 + r3 = r3 - r0; // 29 + r5 = r5 * r1; // 30 + r7 = r7 ^ dataset[r2 & MASK]; // 31 + r1 = r1 ^ dataset[r0 & MASK]; // 32 + r5 = r5 ^ r6; // 33 + r5 = r5 ^ dataset[r1 & MASK]; // 34 + r0 = mulhi(r0, r5); // 35 + r5 = r5 ^ simd_shuffle_xor(r2, (ushort)4); // 36 + r7 = r7 ^ dataset[r0 & MASK]; // 37 + r3 = r3 + r1 + select(0x75ba2fadu, 0x230c005cu, ((sel >> 27u) & 1u) != 0u); // 38 + r1 = r1 ^ simd_shuffle_xor(r5, (ushort)4); // 39 + r2 = r2 ^ r5; // 40 + r3 = r6 * r3 + r3; // 41 + r6 = r6 - r7; // 42 + r7 = r7 ^ r0; // 43 + r1 = r1 ^ dataset[r7 & MASK]; // 44 + r2 = r2 * r3; // 45 + r1 = mulhi(r1, r5); // 46 + r4 = r4 - r3; // 47 + r2 = rotr_var(r2, r6); // 48 + r3 = r3 ^ dataset[r5 & MASK]; // 49 + r1 = r1 + r5 + select(0x81b8bc2cu, 0x1907970cu, ((sel >> 7u) & 1u) != 0u); // 50 + r0 = r0 * r2; // 51 + r0 = r0 + r2 + select(0x4f92b968u, 0x699fd448u, ((sel >> 6u) & 1u) != 0u); // 52 + r1 = r1 + r0 + select(0x2bb965afu, 0x77b1520du, ((sel >> 12u) & 1u) != 0u); // 53 + r7 = rotl_imm(r7, 14u); // 54 + r3 = r3 + r7 + select(0x7b0fe07au, 0xa54c55a0u, ((sel >> 1u) & 1u) != 0u); // 55 + r6 = r6 ^ dataset[r7 & MASK]; // 56 + r1 = rotr_var(r1, r5); // 57 + r5 = r5 ^ dataset[r4 & MASK]; // 58 + r6 = r6 ^ dataset[r2 & MASK]; // 59 + r3 = r5 * r0 + r3; // 60 + r5 = r5 + r7 + select(0xaf9dd72du, 0xad7493e7u, ((sel >> 31u) & 1u) != 0u); // 61 + r4 = r4 + r6 + select(0x89841d87u, 0x1e07c3d9u, ((sel >> 27u) & 1u) != 0u); // 62 + r5 = rotl_imm(r5, 19u); // 63 + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 40 passes after instruction 63, no load + for (uint sh = 0u; sh < 40u; ++sh) { + r5 = r5 + r2 + select(0x92199f99u, 0x8bc12da9u, ((sel >> 18u) & 1u) != 0u); // s0 add + r0 = r0 + r7 + select(0x8d72d3adu, 0x63079e5au, ((sel >> 26u) & 1u) != 0u); // s1 add + r6 = r6 ^ simd_shuffle_xor(r3, (ushort)2); // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + select(0xb21b4babu, 0x5d4c7a60u, ((sel >> 31u) & 1u) != 0u); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + select(0x2fe0e98bu, 0xc88e2942u, ((sel >> 16u) & 1u) != 0u); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + r6 = r6 ^ simd_shuffle_xor(r1, (ushort)4); // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + r2 = r2 ^ simd_shuffle_xor(r6, (ushort)4); // s12 shfl + r1 = r1 + r5 + select(0xbdf8f9a5u, 0xbc48c63eu, ((sel >> 25u) & 1u) != 0u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)8); // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + select(0x45c37cecu, 0x96e8f127u, ((sel >> 1u) & 1u) != 0u); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = mulhi(r6, r0); // s28 mulhi + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)2); // s29 shfl + r1 = r1 ^ simd_shuffle_xor(r6, (ushort)1); // s30 shfl + r1 = r1 + r6 + select(0x37985632u, 0xb1cdb2abu, ((sel >> 1u) & 1u) != 0u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + r3 = r3 ^ simd_shuffle_xor(r4, (ushort)2); // s33 shfl + r0 = r0 ^ simd_shuffle_xor(r3, (ushort)4); // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + select(0x804e777eu, 0x856e0180u, ((sel >> 0u) & 1u) != 0u); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + select(0x0b06c8a7u, 0xe9bd0cc4u, ((sel >> 2u) & 1u) != 0u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = mulhi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = mulhi(r4, r3); // s44 mulhi + r6 = r6 + r7 + select(0xee822e17u, 0xcdcb63f6u, ((sel >> 12u) & 1u) != 0u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + r4 = r4 ^ simd_shuffle_xor(r3, (ushort)8); // s47 shfl + r6 = mulhi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + select(0x3dfad1b6u, 0xd4758987u, ((sel >> 10u) & 1u) != 0u); // s56 add + r4 = r4 + r1 + select(0xfca75bc2u, 0x0602d6beu, ((sel >> 0u) & 1u) != 0u); // s57 add + r5 = mulhi(r5, r6); // s58 mulhi + r2 = r2 ^ simd_shuffle_xor(r1, (ushort)2); // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + select(0xd71c02ffu, 0x8596687au, ((sel >> 6u) & 1u) != 0u); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + r7 = r7 ^ simd_shuffle_xor(r5, (ushort)2); // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + select(0x3c6fe15du, 0x08ac5733u, ((sel >> 0u) & 1u) != 0u); // s72 add + r3 = r3 ^ simd_shuffle_xor(r2, (ushort)8); // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + select(0x295d5faeu, 0xc100b495u, ((sel >> 1u) & 1u) != 0u); // s77 add + r3 = mulhi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + select(0x274a9221u, 0x5cc59530u, ((sel >> 15u) & 1u) != 0u); // s81 add + r7 = r7 + r3 + select(0xc8651f8eu, 0x141479ecu, ((sel >> 5u) & 1u) != 0u); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + r2 = r2 ^ simd_shuffle_xor(r5, (ushort)16); // s85 shfl + r3 = r3 ^ r2; // s86 xor + r5 = r5 ^ simd_shuffle_xor(r7, (ushort)2); // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + select(0x53f915c2u, 0x883c0c92u, ((sel >> 18u) & 1u) != 0u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + select(0xe2be00a5u, 0x3cc5bd20u, ((sel >> 31u) & 1u) != 0u); // s91 add + r7 = r7 ^ simd_shuffle_xor(r2, (ushort)1); // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + select(0x423fd9c9u, 0xbfd646cbu, ((sel >> 17u) & 1u) != 0u); // s101 add + r7 = r7 + r6 + select(0x8d3c011du, 0x19b74a43u, ((sel >> 11u) & 1u) != 0u); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + select(0x8ce14721u, 0x7dcb7e18u, ((sel >> 15u) & 1u) != 0u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = mulhi(r2, r0); // s109 mulhi + r1 = mulhi(r1, r0); // s110 mulhi + r0 = r0 + r2 + select(0x2d9fc6b9u, 0x3c179ad8u, ((sel >> 28u) & 1u) != 0u); // s111 add + r2 = mulhi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + select(0x502138e2u, 0x47359729u, ((sel >> 22u) & 1u) != 0u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = mulhi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + r4 = r4 ^ simd_shuffle_xor(r2, (ushort)2); // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + r7 = r7 ^ simd_shuffle_xor(r2, (ushort)4); // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + select(0x33dff776u, 0x6c57e4e7u, ((sel >> 15u) & 1u) != 0u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + select(0x5db25b34u, 0xe8212c0cu, ((sel >> 30u) & 1u) != 0u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = mulhi(r0, r5); // s138 mulhi + r2 = r2 + r7 + select(0x218d4090u, 0xd44ff710u, ((sel >> 10u) & 1u) != 0u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + r3 = r3 ^ simd_shuffle_xor(r6, (ushort)1); // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + select(0xf4b1a8deu, 0xb98942fau, ((sel >> 29u) & 1u) != 0u); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + select(0x2bef10f2u, 0x0d48ba42u, ((sel >> 17u) & 1u) != 0u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + select(0xdc5cc080u, 0xc98dea9cu, ((sel >> 30u) & 1u) != 0u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + select(0x18197438u, 0x6c752dcbu, ((sel >> 11u) & 1u) != 0u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + select(0xf1c46574u, 0x8e481727u, ((sel >> 3u) & 1u) != 0u); // s163 add + r0 = mulhi(r0, r4); // s164 mulhi + r2 = r2 + r6 + select(0xac578137u, 0x550ab406u, ((sel >> 20u) & 1u) != 0u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + select(0xa33e6706u, 0xaebb5966u, ((sel >> 14u) & 1u) != 0u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + r7 = r7 ^ simd_shuffle_xor(r0, (ushort)8); // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + select(0xd94d55acu, 0x5bb7550fu, ((sel >> 21u) & 1u) != 0u); // s184 add + r3 = r3 | r5; // s185 or + r6 = mulhi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)2); // s188 shfl + r6 = r6 + r5 + select(0x89e747feu, 0x2a354e2du, ((sel >> 6u) & 1u) != 0u); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = mulhi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + r4 = r4 ^ simd_shuffle_xor(r5, (ushort)16); // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + select(0xea03e8e7u, 0x10cfdc71u, ((sel >> 7u) & 1u) != 0u); // s197 add + r7 = r7 + r5 + select(0xa7ee0102u, 0x66e148d3u, ((sel >> 15u) & 1u) != 0u); // s198 add + r5 = r5 - r2; // s199 sub + r5 = r5 ^ simd_shuffle_xor(r1, (ushort)2); // s200 shfl + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)8); // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + select(0x8379a4deu, 0x8558b619u, ((sel >> 10u) & 1u) != 0u); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = mulhi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + r2 = r2 ^ simd_shuffle_xor(r0, (ushort)4); // s209 shfl + r7 = r7 + r0 + select(0xaa8cb14eu, 0xf4049c4cu, ((sel >> 11u) & 1u) != 0u); // s210 add + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)16); // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + r3 = r3 ^ simd_shuffle_xor(r2, (ushort)16); // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = mulhi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + r5 = r5 ^ simd_shuffle_xor(r2, (ushort)8); // s222 shfl + r5 = mulhi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + select(0x1d176220u, 0x2a7fecb2u, ((sel >> 16u) & 1u) != 0u); // s230 add + r1 = r1 ^ simd_shuffle_xor(r2, (ushort)4); // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + select(0x17dafb4du, 0xadce39f3u, ((sel >> 25u) & 1u) != 0u); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + select(0xf2f77d26u, 0x0e7033b6u, ((sel >> 29u) & 1u) != 0u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + select(0xfed2da4eu, 0x7b2ff6b7u, ((sel >> 31u) & 1u) != 0u); // s247 add + r0 = r0 + r7 + select(0x03b2891cu, 0xb5fad7b1u, ((sel >> 0u) & 1u) != 0u); // s248 add + r5 = mulhi(r5, r4); // s249 mulhi + r5 = r5 + r2 + select(0x042cd6e3u, 0xa7e71c2fu, ((sel >> 11u) & 1u) != 0u); // s250 add + r6 = r6 ^ simd_shuffle_xor(r1, (ushort)1); // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + select(0x784a302bu, 0xb83d78deu, ((sel >> 16u) & 1u) != 0u); // s254 add + r2 = r2 - r4; // s255 sub + } + } + uint lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((ulong)hi << 32) | (ulong)lo; +} diff --git a/proto-cuda/packs-ca3-shadow/sh256x40/program_bound.metal b/proto-cuda/packs-ca3-shadow/sh256x40/program_bound.metal new file mode 100644 index 000000000..662225c59 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x40/program_bound.metal @@ -0,0 +1,370 @@ +#include +using namespace metal; + +#define MASK 0x0fffffffu +constant uint SEEDW[8] = { 0x67a9a7beu, 0x1a155b25u, 0xfddfb732u, 0x4b5af2e8u, 0xc55caf33u, 0xa27c13b7u, 0x06628a48u, 0x03852469u }; + +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 = r3 * r4 + r2; // 0 + r2 = r1 * r1 + r2; // 1 + r2 = r3 * r2 + r2; // 2 + r3 = r3 ^ r5; // 3 + r7 = r7 ^ dataset[r2 & MASK]; // 4 + r5 = r5 ^ dataset[r7 & MASK]; // 5 + r1 = r1 ^ simd_shuffle_xor(r4, (ushort)8); // 6 + r7 = r7 ^ simd_shuffle_xor(r3, (ushort)8); // 7 + r1 = mulhi(r1, r5); // 8 + r6 = rotr_var(r6, r3); // 9 + r3 = r3 | r4; // 10 + r4 = r4 ^ dataset[r3 & MASK]; // 11 + r0 = mulhi(r0, r4); // 12 + r5 = r5 + r1 + select(0xc7934706u, 0xd3177981u, ((sel >> 30u) & 1u) != 0u); // 13 + r0 = r0 ^ dataset[r4 & MASK]; // 14 + r2 = r2 - r4; // 15 + r2 = r2 ^ dataset[r0 & MASK]; // 16 + r7 = r7 ^ dataset[r2 & MASK]; // 17 + r7 = r7 ^ simd_shuffle_xor(r3, (ushort)4); // 18 + r5 = r5 * r0; // 19 + r3 = r3 ^ simd_shuffle_xor(r4, (ushort)2); // 20 + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)16); // 21 + r6 = mulhi(r6, r2); // 22 + r6 = r6 ^ dataset[r1 & MASK]; // 23 + r5 = r5 * r0; // 24 + r5 = rotl_imm(r5, 19u); // 25 + r7 = r7 ^ simd_shuffle_xor(r6, (ushort)2); // 26 + r0 = r0 ^ r5; // 27 + r0 = r0 ^ r4; // 28 + r3 = r3 - r0; // 29 + r5 = r5 * r1; // 30 + r7 = r7 ^ dataset[r2 & MASK]; // 31 + r1 = r1 ^ dataset[r0 & MASK]; // 32 + r5 = r5 ^ r6; // 33 + r5 = r5 ^ dataset[r1 & MASK]; // 34 + r0 = mulhi(r0, r5); // 35 + r5 = r5 ^ simd_shuffle_xor(r2, (ushort)4); // 36 + r7 = r7 ^ dataset[r0 & MASK]; // 37 + r3 = r3 + r1 + select(0x75ba2fadu, 0x230c005cu, ((sel >> 27u) & 1u) != 0u); // 38 + r1 = r1 ^ simd_shuffle_xor(r5, (ushort)4); // 39 + r2 = r2 ^ r5; // 40 + r3 = r6 * r3 + r3; // 41 + r6 = r6 - r7; // 42 + r7 = r7 ^ r0; // 43 + r1 = r1 ^ dataset[r7 & MASK]; // 44 + r2 = r2 * r3; // 45 + r1 = mulhi(r1, r5); // 46 + r4 = r4 - r3; // 47 + r2 = rotr_var(r2, r6); // 48 + r3 = r3 ^ dataset[r5 & MASK]; // 49 + r1 = r1 + r5 + select(0x81b8bc2cu, 0x1907970cu, ((sel >> 7u) & 1u) != 0u); // 50 + r0 = r0 * r2; // 51 + r0 = r0 + r2 + select(0x4f92b968u, 0x699fd448u, ((sel >> 6u) & 1u) != 0u); // 52 + r1 = r1 + r0 + select(0x2bb965afu, 0x77b1520du, ((sel >> 12u) & 1u) != 0u); // 53 + r7 = rotl_imm(r7, 14u); // 54 + r3 = r3 + r7 + select(0x7b0fe07au, 0xa54c55a0u, ((sel >> 1u) & 1u) != 0u); // 55 + r6 = r6 ^ dataset[r7 & MASK]; // 56 + r1 = rotr_var(r1, r5); // 57 + r5 = r5 ^ dataset[r4 & MASK]; // 58 + r6 = r6 ^ dataset[r2 & MASK]; // 59 + r3 = r5 * r0 + r3; // 60 + r5 = r5 + r7 + select(0xaf9dd72du, 0xad7493e7u, ((sel >> 31u) & 1u) != 0u); // 61 + r4 = r4 + r6 + select(0x89841d87u, 0x1e07c3d9u, ((sel >> 27u) & 1u) != 0u); // 62 + r5 = rotl_imm(r5, 19u); // 63 + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 40 passes after instruction 63, no load + for (uint sh = 0u; sh < 40u; ++sh) { + r5 = r5 + r2 + select(0x92199f99u, 0x8bc12da9u, ((sel >> 18u) & 1u) != 0u); // s0 add + r0 = r0 + r7 + select(0x8d72d3adu, 0x63079e5au, ((sel >> 26u) & 1u) != 0u); // s1 add + r6 = r6 ^ simd_shuffle_xor(r3, (ushort)2); // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + select(0xb21b4babu, 0x5d4c7a60u, ((sel >> 31u) & 1u) != 0u); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + select(0x2fe0e98bu, 0xc88e2942u, ((sel >> 16u) & 1u) != 0u); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + r6 = r6 ^ simd_shuffle_xor(r1, (ushort)4); // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + r2 = r2 ^ simd_shuffle_xor(r6, (ushort)4); // s12 shfl + r1 = r1 + r5 + select(0xbdf8f9a5u, 0xbc48c63eu, ((sel >> 25u) & 1u) != 0u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)8); // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + select(0x45c37cecu, 0x96e8f127u, ((sel >> 1u) & 1u) != 0u); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = mulhi(r6, r0); // s28 mulhi + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)2); // s29 shfl + r1 = r1 ^ simd_shuffle_xor(r6, (ushort)1); // s30 shfl + r1 = r1 + r6 + select(0x37985632u, 0xb1cdb2abu, ((sel >> 1u) & 1u) != 0u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + r3 = r3 ^ simd_shuffle_xor(r4, (ushort)2); // s33 shfl + r0 = r0 ^ simd_shuffle_xor(r3, (ushort)4); // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + select(0x804e777eu, 0x856e0180u, ((sel >> 0u) & 1u) != 0u); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + select(0x0b06c8a7u, 0xe9bd0cc4u, ((sel >> 2u) & 1u) != 0u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = mulhi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = mulhi(r4, r3); // s44 mulhi + r6 = r6 + r7 + select(0xee822e17u, 0xcdcb63f6u, ((sel >> 12u) & 1u) != 0u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + r4 = r4 ^ simd_shuffle_xor(r3, (ushort)8); // s47 shfl + r6 = mulhi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + select(0x3dfad1b6u, 0xd4758987u, ((sel >> 10u) & 1u) != 0u); // s56 add + r4 = r4 + r1 + select(0xfca75bc2u, 0x0602d6beu, ((sel >> 0u) & 1u) != 0u); // s57 add + r5 = mulhi(r5, r6); // s58 mulhi + r2 = r2 ^ simd_shuffle_xor(r1, (ushort)2); // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + select(0xd71c02ffu, 0x8596687au, ((sel >> 6u) & 1u) != 0u); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + r7 = r7 ^ simd_shuffle_xor(r5, (ushort)2); // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + select(0x3c6fe15du, 0x08ac5733u, ((sel >> 0u) & 1u) != 0u); // s72 add + r3 = r3 ^ simd_shuffle_xor(r2, (ushort)8); // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + select(0x295d5faeu, 0xc100b495u, ((sel >> 1u) & 1u) != 0u); // s77 add + r3 = mulhi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + select(0x274a9221u, 0x5cc59530u, ((sel >> 15u) & 1u) != 0u); // s81 add + r7 = r7 + r3 + select(0xc8651f8eu, 0x141479ecu, ((sel >> 5u) & 1u) != 0u); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + r2 = r2 ^ simd_shuffle_xor(r5, (ushort)16); // s85 shfl + r3 = r3 ^ r2; // s86 xor + r5 = r5 ^ simd_shuffle_xor(r7, (ushort)2); // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + select(0x53f915c2u, 0x883c0c92u, ((sel >> 18u) & 1u) != 0u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + select(0xe2be00a5u, 0x3cc5bd20u, ((sel >> 31u) & 1u) != 0u); // s91 add + r7 = r7 ^ simd_shuffle_xor(r2, (ushort)1); // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + select(0x423fd9c9u, 0xbfd646cbu, ((sel >> 17u) & 1u) != 0u); // s101 add + r7 = r7 + r6 + select(0x8d3c011du, 0x19b74a43u, ((sel >> 11u) & 1u) != 0u); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + select(0x8ce14721u, 0x7dcb7e18u, ((sel >> 15u) & 1u) != 0u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = mulhi(r2, r0); // s109 mulhi + r1 = mulhi(r1, r0); // s110 mulhi + r0 = r0 + r2 + select(0x2d9fc6b9u, 0x3c179ad8u, ((sel >> 28u) & 1u) != 0u); // s111 add + r2 = mulhi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + select(0x502138e2u, 0x47359729u, ((sel >> 22u) & 1u) != 0u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = mulhi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + r4 = r4 ^ simd_shuffle_xor(r2, (ushort)2); // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + r7 = r7 ^ simd_shuffle_xor(r2, (ushort)4); // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + select(0x33dff776u, 0x6c57e4e7u, ((sel >> 15u) & 1u) != 0u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + select(0x5db25b34u, 0xe8212c0cu, ((sel >> 30u) & 1u) != 0u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = mulhi(r0, r5); // s138 mulhi + r2 = r2 + r7 + select(0x218d4090u, 0xd44ff710u, ((sel >> 10u) & 1u) != 0u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + r3 = r3 ^ simd_shuffle_xor(r6, (ushort)1); // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + select(0xf4b1a8deu, 0xb98942fau, ((sel >> 29u) & 1u) != 0u); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + select(0x2bef10f2u, 0x0d48ba42u, ((sel >> 17u) & 1u) != 0u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + select(0xdc5cc080u, 0xc98dea9cu, ((sel >> 30u) & 1u) != 0u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + select(0x18197438u, 0x6c752dcbu, ((sel >> 11u) & 1u) != 0u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + select(0xf1c46574u, 0x8e481727u, ((sel >> 3u) & 1u) != 0u); // s163 add + r0 = mulhi(r0, r4); // s164 mulhi + r2 = r2 + r6 + select(0xac578137u, 0x550ab406u, ((sel >> 20u) & 1u) != 0u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + select(0xa33e6706u, 0xaebb5966u, ((sel >> 14u) & 1u) != 0u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + r7 = r7 ^ simd_shuffle_xor(r0, (ushort)8); // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + select(0xd94d55acu, 0x5bb7550fu, ((sel >> 21u) & 1u) != 0u); // s184 add + r3 = r3 | r5; // s185 or + r6 = mulhi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)2); // s188 shfl + r6 = r6 + r5 + select(0x89e747feu, 0x2a354e2du, ((sel >> 6u) & 1u) != 0u); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = mulhi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + r4 = r4 ^ simd_shuffle_xor(r5, (ushort)16); // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + select(0xea03e8e7u, 0x10cfdc71u, ((sel >> 7u) & 1u) != 0u); // s197 add + r7 = r7 + r5 + select(0xa7ee0102u, 0x66e148d3u, ((sel >> 15u) & 1u) != 0u); // s198 add + r5 = r5 - r2; // s199 sub + r5 = r5 ^ simd_shuffle_xor(r1, (ushort)2); // s200 shfl + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)8); // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + select(0x8379a4deu, 0x8558b619u, ((sel >> 10u) & 1u) != 0u); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = mulhi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + r2 = r2 ^ simd_shuffle_xor(r0, (ushort)4); // s209 shfl + r7 = r7 + r0 + select(0xaa8cb14eu, 0xf4049c4cu, ((sel >> 11u) & 1u) != 0u); // s210 add + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)16); // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + r3 = r3 ^ simd_shuffle_xor(r2, (ushort)16); // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = mulhi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + r5 = r5 ^ simd_shuffle_xor(r2, (ushort)8); // s222 shfl + r5 = mulhi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + select(0x1d176220u, 0x2a7fecb2u, ((sel >> 16u) & 1u) != 0u); // s230 add + r1 = r1 ^ simd_shuffle_xor(r2, (ushort)4); // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + select(0x17dafb4du, 0xadce39f3u, ((sel >> 25u) & 1u) != 0u); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + select(0xf2f77d26u, 0x0e7033b6u, ((sel >> 29u) & 1u) != 0u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + select(0xfed2da4eu, 0x7b2ff6b7u, ((sel >> 31u) & 1u) != 0u); // s247 add + r0 = r0 + r7 + select(0x03b2891cu, 0xb5fad7b1u, ((sel >> 0u) & 1u) != 0u); // s248 add + r5 = mulhi(r5, r4); // s249 mulhi + r5 = r5 + r2 + select(0x042cd6e3u, 0xa7e71c2fu, ((sel >> 11u) & 1u) != 0u); // s250 add + r6 = r6 ^ simd_shuffle_xor(r1, (ushort)1); // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + select(0x784a302bu, 0xb83d78deu, ((sel >> 16u) & 1u) != 0u); // s254 add + r2 = r2 - r4; // s255 sub + } + } + uint lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((ulong)hi << 32) | (ulong)lo; +} diff --git a/proto-cuda/packs-ca3-shadow/sh256x40/vectors.h b/proto-cuda/packs-ca3-shadow/sh256x40/vectors.h new file mode 100644 index 000000000..aa6a964ab --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x40/vectors.h @@ -0,0 +1,57 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Expected outputs: igneum-pow (Rust) CPU interpreter, generator v2, memory-hard dataset +#pragma once +#ifdef __cplusplus +#include +#else +#include +#endif + +#define IGNEUM_VEC_WARPS 3 +static const uint32_t IGNEUM_VEC_BASE[IGNEUM_VEC_WARPS] = { 0u, 4096u, 1000000u }; +static const uint64_t IGNEUM_VEC_OUT[IGNEUM_VEC_WARPS][32] = { + { // base nonce 0 + 0x8b33d5c60f0e3fe5ull, 0xe7edd93c9eae6505ull, 0x99381f4d81c722ceull, 0xd817d5d01693d9a7ull, 0x473d0bad742a6609ull, 0xd75c29c497cab02aull, 0xa0db8f5aaca58cceull, 0xc4de295193e75862ull, + 0x1d2deb87726a3503ull, 0x36ed34ba8370eac0ull, 0x689b5ddaae423450ull, 0x6507132e18ef25b0ull, 0xca4892dafa48ab61ull, 0x26b39a0a8d7583f0ull, 0xbcf46e4d6e4341a5ull, 0xdbe9237704a4b8bcull, + 0x6fb724f6807cac26ull, 0xb48986723b644466ull, 0xa8958ab2c831dbdcull, 0x1095bb8955a0a48eull, 0x6fde063371fad10eull, 0x01420d707cfb6e57ull, 0x9ef8e88c4c35736aull, 0x92607050d08b24e8ull, + 0xab117dfce555499eull, 0xbd480c8ceee753baull, 0x6a9a73bb40b9801aull, 0x4bcf4bc90fc9a717ull, 0xbe2ecde94eba586dull, 0x50e5397b12ec1613ull, 0xa33764874745d040ull, 0x47d202c031c1ca74ull + }, + { // base nonce 4096 + 0x5572ea4a9de11931ull, 0x8ff20445d6db9cbfull, 0x2ac92983c0b49f15ull, 0x53189e447652e67cull, 0xd306b369e7d69af2ull, 0xb6488339eadca189ull, 0x7d0b22bb03c16619ull, 0x8814f4c029865d21ull, + 0x1698acbdfb4243eeull, 0x5b7f512dba18348bull, 0x0a18e4d3b1ac196eull, 0xbfeb9dac4fb12147ull, 0x4125abc3821d7eceull, 0x904a7a143f625da8ull, 0x9c7f2dcf10d2821aull, 0x43a3a87c90e84f15ull, + 0x886f5e9b2071b703ull, 0xeebf6555b0b0aafaull, 0xbc24a7292fc5279full, 0xf318100baa65191eull, 0x6036d6041cb052f5ull, 0xc72a5f8ea8ed07b7ull, 0x094e56f99032053bull, 0x89fd5acef5db38cdull, + 0xcf851955c44686fbull, 0x6c2cc8415a1cf4b5ull, 0x5915cc380747e0f7ull, 0xa5b8bfb7fb74c026ull, 0x5f5d268692d0fe2cull, 0xa92420eca4648fb2ull, 0x1323611e33754623ull, 0x708a051993795984ull + }, + { // base nonce 1000000 + 0x19f68656190c2d72ull, 0x0614eaf9f9786625ull, 0xc89b4c0b29cdf6a5ull, 0xe97552dfa51cd165ull, 0x095c3022193068e8ull, 0x1e8a83a6a1fc8167ull, 0xe684677a507c0dbcull, 0x39cd59b33ec6cc84ull, + 0xfbc7a722d8425a7full, 0x1a981ddc1319f337ull, 0x32ee67aa5212f3dfull, 0x53740c1f0e06f0e7ull, 0x4172139189021dbdull, 0xc99a60f6ea64747eull, 0x90c00b9aa598eafeull, 0xe849b8130b611a18ull, + 0x8f13d1a9611505d8ull, 0x50375ccddca5426eull, 0xe46afc8f034bdd7aull, 0xb3a279c9d73e9db6ull, 0xd81ead7c33d0d6b6ull, 0x164c0027d0291b60ull, 0x0d18d4b1f079f6baull, 0xf3e90f353be8a5deull, + 0xe31e3bf0d3f81e9aull, 0xfc14feadaecb44c8ull, 0x67d396bc37e6b80full, 0xa1cf4ff5cebc1004ull, 0xd3889081b6417effull, 0x74e3a2d09456ad15ull, 0x709460054c25e190ull, 0x14449eee6d3957a3ull + } +}; + +// Dataset self-test: dataset[0..15] and dataset[IGNEUM_MASK] (268435455). +static const uint32_t IGNEUM_DS_HEAD[16] = { + 0xfdad4319u, 0x1a7b68e1u, 0xde6db608u, 0x13d73892u, 0xd17f447au, 0xb2221ccfu, 0x9db004bdu, 0x57d7d367u, + 0xdbc4cf34u, 0x697c009au, 0xc43af1d4u, 0x97f12b2eu, 0x74c37cd0u, 0xc651ea15u, 0x665a6d29u, 0x22330a2du +}; +static const uint32_t IGNEUM_DS_LAST_INDEX = 268435455u; +static const uint32_t IGNEUM_DS_LAST = 0xa83e7aa6u; +// 64 sampled dataset words (index, value) computed on the Mac. +#define IGNEUM_DS_SAMPLES 64 +static const uint32_t IGNEUM_DS_SAMPLE_INDEX[IGNEUM_DS_SAMPLES] = { + 59471966u, 217795994u, 208353206u, 42483309u, 172547758u, 148076330u, 183853158u, 214389424u, 267488061u, 169781097u, 184093494u, 153880993u, 84977930u, 46426879u, 3093825u, 225364072u, 44593546u, 260713159u, 168250303u, 52384140u, 223401610u, 45554030u, 95410555u, 175039924u, 79171087u, 267580473u, 24168642u, 37981670u, 171551130u, 195559979u, 204611762u, 140997658u, 138925853u, 86637313u, 20736778u, 219665210u, 160430336u, 264654675u, 8013395u, 228945585u, 213884386u, 104419827u, 44185464u, 142737231u, 99284897u, 132475900u, 61861762u, 132056166u, 262388043u, 91878046u, 117353561u, 124768597u, 71352993u, 190698941u, 46055428u, 55281366u, 165145231u, 106810753u, 171985651u, 232085256u, 159510492u, 40072060u, 209107596u, 39023794u +}; +static const uint32_t IGNEUM_DS_SAMPLE_VALUE[IGNEUM_DS_SAMPLES] = { + 0x3230bc7bu, 0x7fbfe2c9u, 0xb2690991u, 0x1745c7c5u, 0x0ab0ccafu, 0x1bf87d6bu, 0x160139fdu, 0x719817acu, 0x0155df4bu, 0xbe1e86c3u, 0x680bcd6cu, 0x79c3dc6cu, 0x181e7e5fu, 0x0713a109u, 0xc705dd9fu, 0x3933b7a8u, 0xdd1c0431u, 0x50522b30u, 0xa0020b38u, 0xbff39e96u, 0x21b67e18u, 0x740f8db3u, 0x2baba568u, 0x2c9bef83u, 0x0ad9b671u, 0xc4327869u, 0x7b4fd7d0u, 0x2c29965fu, 0xec56f15fu, 0x61111746u, 0x303a1d6eu, 0xbddcfd1au, 0xf829a355u, 0x6d5df2a9u, 0x01ab8e44u, 0x06d13507u, 0xda8dcfc6u, 0x01a703e1u, 0xafe7d2c1u, 0xc091c3a2u, 0xac1814feu, 0x6e6ff62au, 0x8fdf01bau, 0xdd3f7159u, 0xdfa0d75cu, 0x26684c35u, 0x7f441e63u, 0x88df2570u, 0x8aa4d5ebu, 0xcc816c05u, 0x434df890u, 0xcd392ad6u, 0x1ab4cb63u, 0x595926fau, 0x7cd76b41u, 0x20cb95c4u, 0x13cf823fu, 0xf9daf901u, 0xff9af40au, 0x2c7dfa51u, 0x871206dbu, 0x938c116cu, 0xb64bf199u, 0x5751f874u +}; +// Cache self-test (memory-hard mode): cache[0..15], the last 16 words, and FNV-1a 64 over all 2^26 words. +static const uint32_t IGNEUM_CACHE_HEAD[16] = { + 0x355a86d2u, 0x7957db1cu, 0xd21772afu, 0x6fc1e09bu, 0xd55ce61du, 0x6e6a278bu, 0xd3f543ceu, 0x223d8e82u, + 0x143ab337u, 0x2e9f05bdu, 0x2eb389bfu, 0x0c6e449eu, 0x5cfa4222u, 0xba6560feu, 0x8e3e1aa4u, 0xdbcc1d53u +}; +static const uint32_t IGNEUM_CACHE_LAST[16] = { + 0x41190d91u, 0xbd277957u, 0x22ddbb49u, 0x6986f207u, 0xdf69a4d6u, 0x26401a3au, 0x818230fbu, 0xc417122du, + 0x3597b211u, 0xb553ce55u, 0xcf39cc0du, 0x3b7fc43au, 0x3fd43b00u, 0x67e1c80eu, 0xffa7ea7du, 0xca2960abu +}; +static const uint64_t IGNEUM_CACHE_FNV64 = 0x48c4f5bf24166b2eull; diff --git a/proto-cuda/packs-ca3-shadow/sh256x40/vectors.json b/proto-cuda/packs-ca3-shadow/sh256x40/vectors.json new file mode 100644 index 000000000..8fb6681fb --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x40/vectors.json @@ -0,0 +1,36 @@ +{ + "seed": "igneum-genesis", + "day": "2026-10-03", + "dataset_mode": "memory-hard", + "dataset_log2_words": 28, + "mask": "0x0fffffff", + "lanes": 32, + "source": "igneum-pow (Rust) CPU interpreter, generator v2, memory-hard dataset", + "warps": [ + {"base_nonce": 0, "expected": [ + "0x8b33d5c60f0e3fe5", "0xe7edd93c9eae6505", "0x99381f4d81c722ce", "0xd817d5d01693d9a7", "0x473d0bad742a6609", "0xd75c29c497cab02a", "0xa0db8f5aaca58cce", "0xc4de295193e75862", + "0x1d2deb87726a3503", "0x36ed34ba8370eac0", "0x689b5ddaae423450", "0x6507132e18ef25b0", "0xca4892dafa48ab61", "0x26b39a0a8d7583f0", "0xbcf46e4d6e4341a5", "0xdbe9237704a4b8bc", + "0x6fb724f6807cac26", "0xb48986723b644466", "0xa8958ab2c831dbdc", "0x1095bb8955a0a48e", "0x6fde063371fad10e", "0x01420d707cfb6e57", "0x9ef8e88c4c35736a", "0x92607050d08b24e8", + "0xab117dfce555499e", "0xbd480c8ceee753ba", "0x6a9a73bb40b9801a", "0x4bcf4bc90fc9a717", "0xbe2ecde94eba586d", "0x50e5397b12ec1613", "0xa33764874745d040", "0x47d202c031c1ca74" + ]}, + {"base_nonce": 4096, "expected": [ + "0x5572ea4a9de11931", "0x8ff20445d6db9cbf", "0x2ac92983c0b49f15", "0x53189e447652e67c", "0xd306b369e7d69af2", "0xb6488339eadca189", "0x7d0b22bb03c16619", "0x8814f4c029865d21", + "0x1698acbdfb4243ee", "0x5b7f512dba18348b", "0x0a18e4d3b1ac196e", "0xbfeb9dac4fb12147", "0x4125abc3821d7ece", "0x904a7a143f625da8", "0x9c7f2dcf10d2821a", "0x43a3a87c90e84f15", + "0x886f5e9b2071b703", "0xeebf6555b0b0aafa", "0xbc24a7292fc5279f", "0xf318100baa65191e", "0x6036d6041cb052f5", "0xc72a5f8ea8ed07b7", "0x094e56f99032053b", "0x89fd5acef5db38cd", + "0xcf851955c44686fb", "0x6c2cc8415a1cf4b5", "0x5915cc380747e0f7", "0xa5b8bfb7fb74c026", "0x5f5d268692d0fe2c", "0xa92420eca4648fb2", "0x1323611e33754623", "0x708a051993795984" + ]}, + {"base_nonce": 1000000, "expected": [ + "0x19f68656190c2d72", "0x0614eaf9f9786625", "0xc89b4c0b29cdf6a5", "0xe97552dfa51cd165", "0x095c3022193068e8", "0x1e8a83a6a1fc8167", "0xe684677a507c0dbc", "0x39cd59b33ec6cc84", + "0xfbc7a722d8425a7f", "0x1a981ddc1319f337", "0x32ee67aa5212f3df", "0x53740c1f0e06f0e7", "0x4172139189021dbd", "0xc99a60f6ea64747e", "0x90c00b9aa598eafe", "0xe849b8130b611a18", + "0x8f13d1a9611505d8", "0x50375ccddca5426e", "0xe46afc8f034bdd7a", "0xb3a279c9d73e9db6", "0xd81ead7c33d0d6b6", "0x164c0027d0291b60", "0x0d18d4b1f079f6ba", "0xf3e90f353be8a5de", + "0xe31e3bf0d3f81e9a", "0xfc14feadaecb44c8", "0x67d396bc37e6b80f", "0xa1cf4ff5cebc1004", "0xd3889081b6417eff", "0x74e3a2d09456ad15", "0x709460054c25e190", "0x14449eee6d3957a3" + ]} + ], + "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" +} diff --git a/proto-cuda/packs-ca3-shadow/sh256x53/kernel.cl b/proto-cuda/packs-ca3-shadow/sh256x53/kernel.cl new file mode 100644 index 000000000..cbc5d4b19 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x53/kernel.cl @@ -0,0 +1,538 @@ +// 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 ^ 0x67a9a7beu; x += 0x9e3779b9u; x = splitmix32(x); r0 = x ^ 0x1a155b25u; } // SEEDW[0], 0x9e3779b9u * 1u, SEEDW[1] + { uint x = nonce ^ 0x1a155b25u; x += 0x3c6ef372u; x = splitmix32(x); r1 = x ^ 0xfddfb732u; } // SEEDW[1], 0x9e3779b9u * 2u, SEEDW[2] + { uint x = nonce ^ 0xfddfb732u; x += 0xdaa66d2bu; x = splitmix32(x); r2 = x ^ 0x4b5af2e8u; } // SEEDW[2], 0x9e3779b9u * 3u, SEEDW[3] + { uint x = nonce ^ 0x4b5af2e8u; x += 0x78dde6e4u; x = splitmix32(x); r3 = x ^ 0xc55caf33u; } // SEEDW[3], 0x9e3779b9u * 4u, SEEDW[4] + { uint x = nonce ^ 0xc55caf33u; x += 0x1715609du; x = splitmix32(x); r4 = x ^ 0xa27c13b7u; } // SEEDW[4], 0x9e3779b9u * 5u, SEEDW[5] + { uint x = nonce ^ 0xa27c13b7u; x += 0xb54cda56u; x = splitmix32(x); r5 = x ^ 0x06628a48u; } // SEEDW[5], 0x9e3779b9u * 6u, SEEDW[6] + { uint x = nonce ^ 0x06628a48u; x += 0x5384540fu; x = splitmix32(x); r6 = x ^ 0x03852469u; } // SEEDW[6], 0x9e3779b9u * 7u, SEEDW[7] + { uint x = nonce ^ 0x03852469u; x += 0xf1bbcdc8u; x = splitmix32(x); r7 = x ^ 0x67a9a7beu; } // SEEDW[7], 0x9e3779b9u * 8u, SEEDW[0] + + for (uint it = 0u; it < 8u; ++it) { + uint sel = r0; + r2 = r3 * r4 + r2; // 0 mad + r2 = r1 * r1 + r2; // 1 mad + r2 = r3 * r2 + r2; // 2 mad + r3 = r3 ^ r5; // 3 xor + r7 = r7 ^ ds[r2 & mask]; // 4 load + r5 = r5 ^ ds[r7 & mask]; // 5 load + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r1 = r1 ^ t_; } // 6 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r7 = r7 ^ t_; } // 7 shfl + r1 = mul_hi(r1, r5); // 8 mulhi + r6 = rotr_var(r6, r3); // 9 rotr + r3 = r3 | r4; // 10 or + r4 = r4 ^ ds[r3 & mask]; // 11 load + r0 = mul_hi(r0, r4); // 12 mulhi + r5 = r5 + r1 + ((((sel >> 30u) & 1u) != 0u) ? 0xd3177981u : 0xc7934706u); // 13 add + r0 = r0 ^ ds[r4 & mask]; // 14 load + r2 = r2 - r4; // 15 sub + r2 = r2 ^ ds[r0 & mask]; // 16 load + r7 = r7 ^ ds[r2 & mask]; // 17 load + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r7 = r7 ^ t_; } // 18 shfl + r5 = r5 * r0; // 19 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // 20 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 16u); r2 = r2 ^ t_; } // 21 shfl + r6 = mul_hi(r6, r2); // 22 mulhi + r6 = r6 ^ ds[r1 & mask]; // 23 load + r5 = r5 * r0; // 24 mul + r5 = rotl_imm(r5, 19u); // 25 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 2u); r7 = r7 ^ t_; } // 26 shfl + r0 = r0 ^ r5; // 27 xor + r0 = r0 ^ r4; // 28 xor + r3 = r3 - r0; // 29 sub + r5 = r5 * r1; // 30 mul + r7 = r7 ^ ds[r2 & mask]; // 31 load + r1 = r1 ^ ds[r0 & mask]; // 32 load + r5 = r5 ^ r6; // 33 xor + r5 = r5 ^ ds[r1 & mask]; // 34 load + r0 = mul_hi(r0, r5); // 35 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r5 = r5 ^ t_; } // 36 shfl + r7 = r7 ^ ds[r0 & mask]; // 37 load + r3 = r3 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0x230c005cu : 0x75ba2fadu); // 38 add + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 4u); r1 = r1 ^ t_; } // 39 shfl + r2 = r2 ^ r5; // 40 xor + r3 = r6 * r3 + r3; // 41 mad + r6 = r6 - r7; // 42 sub + r7 = r7 ^ r0; // 43 xor + r1 = r1 ^ ds[r7 & mask]; // 44 load + r2 = r2 * r3; // 45 mul + r1 = mul_hi(r1, r5); // 46 mulhi + r4 = r4 - r3; // 47 sub + r2 = rotr_var(r2, r6); // 48 rotr + r3 = r3 ^ ds[r5 & mask]; // 49 load + r1 = r1 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x1907970cu : 0x81b8bc2cu); // 50 add + r0 = r0 * r2; // 51 mul + r0 = r0 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x699fd448u : 0x4f92b968u); // 52 add + r1 = r1 + r0 + ((((sel >> 12u) & 1u) != 0u) ? 0x77b1520du : 0x2bb965afu); // 53 add + r7 = rotl_imm(r7, 14u); // 54 rotl + r3 = r3 + r7 + ((((sel >> 1u) & 1u) != 0u) ? 0xa54c55a0u : 0x7b0fe07au); // 55 add + r6 = r6 ^ ds[r7 & mask]; // 56 load + r1 = rotr_var(r1, r5); // 57 rotr + r5 = r5 ^ ds[r4 & mask]; // 58 load + r6 = r6 ^ ds[r2 & mask]; // 59 load + r3 = r5 * r0 + r3; // 60 mad + r5 = r5 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0xad7493e7u : 0xaf9dd72du); // 61 add + r4 = r4 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x1e07c3d9u : 0x89841d87u); // 62 add + r5 = rotl_imm(r5, 19u); // 63 rotl + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 53 passes after instruction 63, no load + for (uint sh = 0u; sh < 53u; ++sh) { + r5 = r5 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x8bc12da9u : 0x92199f99u); // s0 add + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x63079e5au : 0x8d72d3adu); // s1 add + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 2u); r6 = r6 ^ t_; } // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + ((((sel >> 31u) & 1u) != 0u) ? 0x5d4c7a60u : 0xb21b4babu); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + ((((sel >> 16u) & 1u) != 0u) ? 0xc88e2942u : 0x2fe0e98bu); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r6 = r6 ^ t_; } // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 4u); r2 = r2 ^ t_; } // s12 shfl + r1 = r1 + r5 + ((((sel >> 25u) & 1u) != 0u) ? 0xbc48c63eu : 0xbdf8f9a5u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r2 = r2 ^ t_; } // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + ((((sel >> 1u) & 1u) != 0u) ? 0x96e8f127u : 0x45c37cecu); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = mul_hi(r6, r0); // s28 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r2 = r2 ^ t_; } // s29 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r1 = r1 ^ t_; } // s30 shfl + r1 = r1 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0xb1cdb2abu : 0x37985632u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // s33 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r0 = r0 ^ t_; } // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x856e0180u : 0x804e777eu); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xe9bd0cc4u : 0x0b06c8a7u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = mul_hi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = mul_hi(r4, r3); // s44 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xcdcb63f6u : 0xee822e17u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r4 = r4 ^ t_; } // s47 shfl + r6 = mul_hi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0xd4758987u : 0x3dfad1b6u); // s56 add + r4 = r4 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x0602d6beu : 0xfca75bc2u); // s57 add + r5 = mul_hi(r5, r6); // s58 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r2 = r2 ^ t_; } // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0x8596687au : 0xd71c02ffu); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 2u); r7 = r7 ^ t_; } // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0x08ac5733u : 0x3c6fe15du); // s72 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r3 = r3 ^ t_; } // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + ((((sel >> 1u) & 1u) != 0u) ? 0xc100b495u : 0x295d5faeu); // s77 add + r3 = mul_hi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + ((((sel >> 15u) & 1u) != 0u) ? 0x5cc59530u : 0x274a9221u); // s81 add + r7 = r7 + r3 + ((((sel >> 5u) & 1u) != 0u) ? 0x141479ecu : 0xc8651f8eu); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r2 = r2 ^ t_; } // s85 shfl + r3 = r3 ^ r2; // s86 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 2u); r5 = r5 ^ t_; } // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x883c0c92u : 0x53f915c2u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + ((((sel >> 31u) & 1u) != 0u) ? 0x3cc5bd20u : 0xe2be00a5u); // s91 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 1u); r7 = r7 ^ t_; } // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + ((((sel >> 17u) & 1u) != 0u) ? 0xbfd646cbu : 0x423fd9c9u); // s101 add + r7 = r7 + r6 + ((((sel >> 11u) & 1u) != 0u) ? 0x19b74a43u : 0x8d3c011du); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + ((((sel >> 15u) & 1u) != 0u) ? 0x7dcb7e18u : 0x8ce14721u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = mul_hi(r2, r0); // s109 mulhi + r1 = mul_hi(r1, r0); // s110 mulhi + r0 = r0 + r2 + ((((sel >> 28u) & 1u) != 0u) ? 0x3c179ad8u : 0x2d9fc6b9u); // s111 add + r2 = mul_hi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + ((((sel >> 22u) & 1u) != 0u) ? 0x47359729u : 0x502138e2u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = mul_hi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 2u); r4 = r4 ^ t_; } // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r7 = r7 ^ t_; } // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x6c57e4e7u : 0x33dff776u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + ((((sel >> 30u) & 1u) != 0u) ? 0xe8212c0cu : 0x5db25b34u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = mul_hi(r0, r5); // s138 mulhi + r2 = r2 + r7 + ((((sel >> 10u) & 1u) != 0u) ? 0xd44ff710u : 0x218d4090u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r3 = r3 ^ t_; } // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + ((((sel >> 29u) & 1u) != 0u) ? 0xb98942fau : 0xf4b1a8deu); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + ((((sel >> 17u) & 1u) != 0u) ? 0x0d48ba42u : 0x2bef10f2u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + ((((sel >> 30u) & 1u) != 0u) ? 0xc98dea9cu : 0xdc5cc080u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0x6c752dcbu : 0x18197438u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + ((((sel >> 3u) & 1u) != 0u) ? 0x8e481727u : 0xf1c46574u); // s163 add + r0 = mul_hi(r0, r4); // s164 mulhi + r2 = r2 + r6 + ((((sel >> 20u) & 1u) != 0u) ? 0x550ab406u : 0xac578137u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + ((((sel >> 14u) & 1u) != 0u) ? 0xaebb5966u : 0xa33e6706u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 8u); r7 = r7 ^ t_; } // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x5bb7550fu : 0xd94d55acu); // s184 add + r3 = r3 | r5; // s185 or + r6 = mul_hi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r7 = r7 ^ t_; } // s188 shfl + r6 = r6 + r5 + ((((sel >> 6u) & 1u) != 0u) ? 0x2a354e2du : 0x89e747feu); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = mul_hi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r4 = r4 ^ t_; } // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + ((((sel >> 7u) & 1u) != 0u) ? 0x10cfdc71u : 0xea03e8e7u); // s197 add + r7 = r7 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x66e148d3u : 0xa7ee0102u); // s198 add + r5 = r5 - r2; // s199 sub + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r5 = r5 ^ t_; } // s200 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 8u); r7 = r7 ^ t_; } // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0x8558b619u : 0x8379a4deu); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = mul_hi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 4u); r2 = r2 ^ t_; } // s209 shfl + r7 = r7 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0xf4049c4cu : 0xaa8cb14eu); // s210 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 16u); r7 = r7 ^ t_; } // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 16u); r3 = r3 ^ t_; } // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = mul_hi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r5 = r5 ^ t_; } // s222 shfl + r5 = mul_hi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0x2a7fecb2u : 0x1d176220u); // s230 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r1 = r1 ^ t_; } // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + ((((sel >> 25u) & 1u) != 0u) ? 0xadce39f3u : 0x17dafb4du); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + ((((sel >> 29u) & 1u) != 0u) ? 0x0e7033b6u : 0xf2f77d26u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + ((((sel >> 31u) & 1u) != 0u) ? 0x7b2ff6b7u : 0xfed2da4eu); // s247 add + r0 = r0 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0xb5fad7b1u : 0x03b2891cu); // s248 add + r5 = mul_hi(r5, r4); // s249 mulhi + r5 = r5 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0xa7e71c2fu : 0x042cd6e3u); // s250 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 1u); r6 = r6 ^ t_; } // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0xb83d78deu : 0x784a302bu); // s254 add + r2 = r2 - r4; // s255 sub + } + } + uint lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((ulong)hi << 32) | (ulong)lo; +} + +#if IGNEUM_EXCHANGE != 0 +// Reports the sub-group size this device uses for a work-group of IGNEUM_GROUP items. host.c runs it only when the +// per-kernel query (clGetKernelSubGroupInfoKHR on igneum_hash) is unavailable; that query is preferred because a +// compiler may pick a different wave width per kernel (RDNA: wave32 or wave64). See WAVEFRONT.md. +IGNEUM_KERNEL_HASH void igneum_probe_subgroup(__global uint* out) { + if (get_local_id(0) == 0u) { out[0] = get_sub_group_size(); out[1] = get_num_sub_groups(); } +} +#endif diff --git a/proto-cuda/packs-ca3-shadow/sh256x53/kernel.cu b/proto-cuda/packs-ca3-shadow/sh256x53/kernel.cu new file mode 100644 index 000000000..722d87900 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x53/kernel.cu @@ -0,0 +1,423 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Bit-exact twin of the Metal kernel for the same seed (see proto-cuda/CHECKLIST.md and program.metal). +// Compiled ahead of time by nvcc together with proto-cuda/host.cu. No NVRTC. +#include +#include +#include "program.h" +#include "memhard.h" + +__device__ __forceinline__ uint32_t splitmix32(uint32_t x) { + x ^= x >> 16; x *= 0x7feb352du; + x ^= x >> 15; x *= 0x846ca68bu; + x ^= x >> 16; + return x; +} +// n is a literal in 1..31 at every call site, so both shift amounts are in 1..31. +__device__ __forceinline__ uint32_t rotl_imm(uint32_t x, uint32_t n) { return (x << n) | (x >> (32u - n)); } +// n is masked to 0..31; the second shift amount is masked too, so n == 0 gives x. +__device__ __forceinline__ uint32_t rotr_var(uint32_t x, uint32_t n) { n &= 31u; return (x >> n) | (x << ((32u - n) & 31u)); } +__device__ __forceinline__ uint32_t ds_elem(uint32_t i, uint32_t d0, uint32_t d1) { + uint32_t x = i ^ d0; + x *= 0x9E3779B1u; x ^= x >> 15; + x += d1; + x *= 0x85EBCA77u; x ^= x >> 13; + x *= 0xC2B2AE3Du; x ^= x >> 16; + return x; +} + +// Memory-hard dataset (MEMHARD.md). One thread per cache segment; one thread per 64-byte dataset item. +// The core functions (mh_cache_segment, mh_item) are in memhard.h and are also compiled for the host. +__global__ void igneum_cache_fill(uint32_t* cache, uint32_t nSegments) { + uint32_t seg = blockIdx.x * blockDim.x + threadIdx.x; + if (seg < nSegments) mh_cache_segment(cache, seg); +} +__global__ void igneum_build(uint32_t* ds, const uint32_t* cache, uint32_t nItems) { + uint32_t t = blockIdx.x * blockDim.x + threadIdx.x; + if (t < nItems) { + uint32_t s[16]; + mh_item(cache, t, s); + uint32_t* d = ds + (size_t)t * 16u; + for (uint32_t i = 0u; i < 16u; ++i) d[i] = s[i]; + } +} + +// One hash per thread. blockDim.x is a multiple of 32; lane = threadIdx.x & 31 and every +// __shfl_xor_sync stays inside the lane's own warp, exactly like simd_shuffle_xor inside a +// 32-wide Metal SIMD group. Control flow is uniform, so the full 0xffffffff member mask is valid. +__global__ void igneum_hash(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask) { + uint32_t gid = blockIdx.x * blockDim.x + threadIdx.x; + uint32_t nonce = baseNonce + gid; + uint32_t r0, r1, r2, r3, r4, r5, r6, r7; + { uint32_t x = nonce ^ 0x67a9a7beu; x += 0x9e3779b9u; x = splitmix32(x); r0 = x ^ 0x1a155b25u; } // SEEDW[0], 0x9e3779b9u * 1u, SEEDW[1] + { uint32_t x = nonce ^ 0x1a155b25u; x += 0x3c6ef372u; x = splitmix32(x); r1 = x ^ 0xfddfb732u; } // SEEDW[1], 0x9e3779b9u * 2u, SEEDW[2] + { uint32_t x = nonce ^ 0xfddfb732u; x += 0xdaa66d2bu; x = splitmix32(x); r2 = x ^ 0x4b5af2e8u; } // SEEDW[2], 0x9e3779b9u * 3u, SEEDW[3] + { uint32_t x = nonce ^ 0x4b5af2e8u; x += 0x78dde6e4u; x = splitmix32(x); r3 = x ^ 0xc55caf33u; } // SEEDW[3], 0x9e3779b9u * 4u, SEEDW[4] + { uint32_t x = nonce ^ 0xc55caf33u; x += 0x1715609du; x = splitmix32(x); r4 = x ^ 0xa27c13b7u; } // SEEDW[4], 0x9e3779b9u * 5u, SEEDW[5] + { uint32_t x = nonce ^ 0xa27c13b7u; x += 0xb54cda56u; x = splitmix32(x); r5 = x ^ 0x06628a48u; } // SEEDW[5], 0x9e3779b9u * 6u, SEEDW[6] + { uint32_t x = nonce ^ 0x06628a48u; x += 0x5384540fu; x = splitmix32(x); r6 = x ^ 0x03852469u; } // SEEDW[6], 0x9e3779b9u * 7u, SEEDW[7] + { uint32_t x = nonce ^ 0x03852469u; x += 0xf1bbcdc8u; x = splitmix32(x); r7 = x ^ 0x67a9a7beu; } // SEEDW[7], 0x9e3779b9u * 8u, SEEDW[0] + + for (uint32_t it = 0u; it < 8u; ++it) { + uint32_t sel = r0; + r2 = r3 * r4 + r2; // 0 mad + r2 = r1 * r1 + r2; // 1 mad + r2 = r3 * r2 + r2; // 2 mad + r3 = r3 ^ r5; // 3 xor + r7 = r7 ^ ds[r2 & mask]; // 4 load + r5 = r5 ^ ds[r7 & mask]; // 5 load + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r4, 8); // 6 shfl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r3, 8); // 7 shfl + r1 = __umulhi(r1, r5); // 8 mulhi + r6 = rotr_var(r6, r3); // 9 rotr + r3 = r3 | r4; // 10 or + r4 = r4 ^ ds[r3 & mask]; // 11 load + r0 = __umulhi(r0, r4); // 12 mulhi + r5 = r5 + r1 + ((((sel >> 30u) & 1u) != 0u) ? 0xd3177981u : 0xc7934706u); // 13 add + r0 = r0 ^ ds[r4 & mask]; // 14 load + r2 = r2 - r4; // 15 sub + r2 = r2 ^ ds[r0 & mask]; // 16 load + r7 = r7 ^ ds[r2 & mask]; // 17 load + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r3, 4); // 18 shfl + r5 = r5 * r0; // 19 mul + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // 20 shfl + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 16); // 21 shfl + r6 = __umulhi(r6, r2); // 22 mulhi + r6 = r6 ^ ds[r1 & mask]; // 23 load + r5 = r5 * r0; // 24 mul + r5 = rotl_imm(r5, 19u); // 25 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r6, 2); // 26 shfl + r0 = r0 ^ r5; // 27 xor + r0 = r0 ^ r4; // 28 xor + r3 = r3 - r0; // 29 sub + r5 = r5 * r1; // 30 mul + r7 = r7 ^ ds[r2 & mask]; // 31 load + r1 = r1 ^ ds[r0 & mask]; // 32 load + r5 = r5 ^ r6; // 33 xor + r5 = r5 ^ ds[r1 & mask]; // 34 load + r0 = __umulhi(r0, r5); // 35 mulhi + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // 36 shfl + r7 = r7 ^ ds[r0 & mask]; // 37 load + r3 = r3 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0x230c005cu : 0x75ba2fadu); // 38 add + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r5, 4); // 39 shfl + r2 = r2 ^ r5; // 40 xor + r3 = r6 * r3 + r3; // 41 mad + r6 = r6 - r7; // 42 sub + r7 = r7 ^ r0; // 43 xor + r1 = r1 ^ ds[r7 & mask]; // 44 load + r2 = r2 * r3; // 45 mul + r1 = __umulhi(r1, r5); // 46 mulhi + r4 = r4 - r3; // 47 sub + r2 = rotr_var(r2, r6); // 48 rotr + r3 = r3 ^ ds[r5 & mask]; // 49 load + r1 = r1 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x1907970cu : 0x81b8bc2cu); // 50 add + r0 = r0 * r2; // 51 mul + r0 = r0 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x699fd448u : 0x4f92b968u); // 52 add + r1 = r1 + r0 + ((((sel >> 12u) & 1u) != 0u) ? 0x77b1520du : 0x2bb965afu); // 53 add + r7 = rotl_imm(r7, 14u); // 54 rotl + r3 = r3 + r7 + ((((sel >> 1u) & 1u) != 0u) ? 0xa54c55a0u : 0x7b0fe07au); // 55 add + r6 = r6 ^ ds[r7 & mask]; // 56 load + r1 = rotr_var(r1, r5); // 57 rotr + r5 = r5 ^ ds[r4 & mask]; // 58 load + r6 = r6 ^ ds[r2 & mask]; // 59 load + r3 = r5 * r0 + r3; // 60 mad + r5 = r5 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0xad7493e7u : 0xaf9dd72du); // 61 add + r4 = r4 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x1e07c3d9u : 0x89841d87u); // 62 add + r5 = rotl_imm(r5, 19u); // 63 rotl + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 53 passes after instruction 63, no load + for (uint32_t sh = 0u; sh < 53u; ++sh) { + r5 = r5 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x8bc12da9u : 0x92199f99u); // s0 add + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x63079e5au : 0x8d72d3adu); // s1 add + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r3, 2); // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + ((((sel >> 31u) & 1u) != 0u) ? 0x5d4c7a60u : 0xb21b4babu); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + ((((sel >> 16u) & 1u) != 0u) ? 0xc88e2942u : 0x2fe0e98bu); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r1, 4); // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r6, 4); // s12 shfl + r1 = r1 + r5 + ((((sel >> 25u) & 1u) != 0u) ? 0xbc48c63eu : 0xbdf8f9a5u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 8); // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + ((((sel >> 1u) & 1u) != 0u) ? 0x96e8f127u : 0x45c37cecu); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = __umulhi(r6, r0); // s28 mulhi + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // s29 shfl + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r6, 1); // s30 shfl + r1 = r1 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0xb1cdb2abu : 0x37985632u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // s33 shfl + r0 = r0 ^ __shfl_xor_sync(0xffffffffu, r3, 4); // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x856e0180u : 0x804e777eu); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xe9bd0cc4u : 0x0b06c8a7u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = __umulhi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = __umulhi(r4, r3); // s44 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xcdcb63f6u : 0xee822e17u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r3, 8); // s47 shfl + r6 = __umulhi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0xd4758987u : 0x3dfad1b6u); // s56 add + r4 = r4 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x0602d6beu : 0xfca75bc2u); // s57 add + r5 = __umulhi(r5, r6); // s58 mulhi + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0x8596687au : 0xd71c02ffu); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r5, 2); // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0x08ac5733u : 0x3c6fe15du); // s72 add + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r2, 8); // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + ((((sel >> 1u) & 1u) != 0u) ? 0xc100b495u : 0x295d5faeu); // s77 add + r3 = __umulhi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + ((((sel >> 15u) & 1u) != 0u) ? 0x5cc59530u : 0x274a9221u); // s81 add + r7 = r7 + r3 + ((((sel >> 5u) & 1u) != 0u) ? 0x141479ecu : 0xc8651f8eu); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r5, 16); // s85 shfl + r3 = r3 ^ r2; // s86 xor + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r7, 2); // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x883c0c92u : 0x53f915c2u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + ((((sel >> 31u) & 1u) != 0u) ? 0x3cc5bd20u : 0xe2be00a5u); // s91 add + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r2, 1); // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + ((((sel >> 17u) & 1u) != 0u) ? 0xbfd646cbu : 0x423fd9c9u); // s101 add + r7 = r7 + r6 + ((((sel >> 11u) & 1u) != 0u) ? 0x19b74a43u : 0x8d3c011du); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + ((((sel >> 15u) & 1u) != 0u) ? 0x7dcb7e18u : 0x8ce14721u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = __umulhi(r2, r0); // s109 mulhi + r1 = __umulhi(r1, r0); // s110 mulhi + r0 = r0 + r2 + ((((sel >> 28u) & 1u) != 0u) ? 0x3c179ad8u : 0x2d9fc6b9u); // s111 add + r2 = __umulhi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + ((((sel >> 22u) & 1u) != 0u) ? 0x47359729u : 0x502138e2u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = __umulhi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r2, 2); // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x6c57e4e7u : 0x33dff776u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + ((((sel >> 30u) & 1u) != 0u) ? 0xe8212c0cu : 0x5db25b34u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = __umulhi(r0, r5); // s138 mulhi + r2 = r2 + r7 + ((((sel >> 10u) & 1u) != 0u) ? 0xd44ff710u : 0x218d4090u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r6, 1); // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + ((((sel >> 29u) & 1u) != 0u) ? 0xb98942fau : 0xf4b1a8deu); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + ((((sel >> 17u) & 1u) != 0u) ? 0x0d48ba42u : 0x2bef10f2u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + ((((sel >> 30u) & 1u) != 0u) ? 0xc98dea9cu : 0xdc5cc080u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0x6c752dcbu : 0x18197438u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + ((((sel >> 3u) & 1u) != 0u) ? 0x8e481727u : 0xf1c46574u); // s163 add + r0 = __umulhi(r0, r4); // s164 mulhi + r2 = r2 + r6 + ((((sel >> 20u) & 1u) != 0u) ? 0x550ab406u : 0xac578137u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + ((((sel >> 14u) & 1u) != 0u) ? 0xaebb5966u : 0xa33e6706u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r0, 8); // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x5bb7550fu : 0xd94d55acu); // s184 add + r3 = r3 | r5; // s185 or + r6 = __umulhi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s188 shfl + r6 = r6 + r5 + ((((sel >> 6u) & 1u) != 0u) ? 0x2a354e2du : 0x89e747feu); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = __umulhi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r5, 16); // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + ((((sel >> 7u) & 1u) != 0u) ? 0x10cfdc71u : 0xea03e8e7u); // s197 add + r7 = r7 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x66e148d3u : 0xa7ee0102u); // s198 add + r5 = r5 - r2; // s199 sub + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s200 shfl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 8); // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0x8558b619u : 0x8379a4deu); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = __umulhi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r0, 4); // s209 shfl + r7 = r7 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0xf4049c4cu : 0xaa8cb14eu); // s210 add + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 16); // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r2, 16); // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = __umulhi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r2, 8); // s222 shfl + r5 = __umulhi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0x2a7fecb2u : 0x1d176220u); // s230 add + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + ((((sel >> 25u) & 1u) != 0u) ? 0xadce39f3u : 0x17dafb4du); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + ((((sel >> 29u) & 1u) != 0u) ? 0x0e7033b6u : 0xf2f77d26u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + ((((sel >> 31u) & 1u) != 0u) ? 0x7b2ff6b7u : 0xfed2da4eu); // s247 add + r0 = r0 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0xb5fad7b1u : 0x03b2891cu); // s248 add + r5 = __umulhi(r5, r4); // s249 mulhi + r5 = r5 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0xa7e71c2fu : 0x042cd6e3u); // s250 add + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r1, 1); // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0xb83d78deu : 0x784a302bu); // s254 add + r2 = r2 - r4; // s255 sub + } + } + uint32_t lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint32_t hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((uint64_t)hi << 32) | (uint64_t)lo; +} + +// Host-side launch wrappers. Declared in program.h, called from host.cu. +cudaError_t igneum_launch_cache_fill(uint32_t* cache, uint32_t nSegments) { + if (nSegments == 0u) return cudaErrorInvalidValue; + uint32_t block = 256u; + uint32_t grid = (nSegments + block - 1u) / block; + igneum_cache_fill<<>>(cache, nSegments); + return cudaGetLastError(); +} + +cudaError_t igneum_launch_build(uint32_t* ds, const uint32_t* cache, uint32_t nItems) { + if (nItems == 0u) return cudaErrorInvalidValue; + uint32_t block = 256u; + uint32_t grid = (nItems + block - 1u) / block; + igneum_build<<>>(ds, cache, nItems); + return cudaGetLastError(); +} + +cudaError_t igneum_launch_hash(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, + uint32_t nonces, uint32_t blockWarps) { + if (blockWarps == 0u || blockWarps > 32u) return cudaErrorInvalidValue; + uint32_t block = 32u * blockWarps; + if (nonces == 0u || (nonces % block) != 0u) return cudaErrorInvalidValue; + igneum_hash<<>>(ds, out, baseNonce, mask); + return cudaGetLastError(); +} + +cudaError_t igneum_hash_info(int* numRegs, int* blocksPerSM, uint32_t blockWarps) { + cudaFuncAttributes attr; + cudaError_t e = cudaFuncGetAttributes(&attr, igneum_hash); + if (e != cudaSuccess) return e; + *numRegs = attr.numRegs; + return cudaOccupancyMaxActiveBlocksPerMultiprocessor(blocksPerSM, igneum_hash, (int)(32u * blockWarps), 0); +} diff --git a/proto-cuda/packs-ca3-shadow/sh256x53/kernel_bound.cl b/proto-cuda/packs-ca3-shadow/sh256x53/kernel_bound.cl new file mode 100644 index 000000000..3dda5afeb --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x53/kernel_bound.cl @@ -0,0 +1,891 @@ +// 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 ^ 0x67a9a7beu; x += 0x9e3779b9u; x = splitmix32(x); r0 = x ^ 0x1a155b25u; } // SEEDW[0], 0x9e3779b9u * 1u, SEEDW[1] + { uint x = nonce ^ 0x1a155b25u; x += 0x3c6ef372u; x = splitmix32(x); r1 = x ^ 0xfddfb732u; } // SEEDW[1], 0x9e3779b9u * 2u, SEEDW[2] + { uint x = nonce ^ 0xfddfb732u; x += 0xdaa66d2bu; x = splitmix32(x); r2 = x ^ 0x4b5af2e8u; } // SEEDW[2], 0x9e3779b9u * 3u, SEEDW[3] + { uint x = nonce ^ 0x4b5af2e8u; x += 0x78dde6e4u; x = splitmix32(x); r3 = x ^ 0xc55caf33u; } // SEEDW[3], 0x9e3779b9u * 4u, SEEDW[4] + { uint x = nonce ^ 0xc55caf33u; x += 0x1715609du; x = splitmix32(x); r4 = x ^ 0xa27c13b7u; } // SEEDW[4], 0x9e3779b9u * 5u, SEEDW[5] + { uint x = nonce ^ 0xa27c13b7u; x += 0xb54cda56u; x = splitmix32(x); r5 = x ^ 0x06628a48u; } // SEEDW[5], 0x9e3779b9u * 6u, SEEDW[6] + { uint x = nonce ^ 0x06628a48u; x += 0x5384540fu; x = splitmix32(x); r6 = x ^ 0x03852469u; } // SEEDW[6], 0x9e3779b9u * 7u, SEEDW[7] + { uint x = nonce ^ 0x03852469u; x += 0xf1bbcdc8u; x = splitmix32(x); r7 = x ^ 0x67a9a7beu; } // SEEDW[7], 0x9e3779b9u * 8u, SEEDW[0] + + for (uint it = 0u; it < 8u; ++it) { + uint sel = r0; + r2 = r3 * r4 + r2; // 0 mad + r2 = r1 * r1 + r2; // 1 mad + r2 = r3 * r2 + r2; // 2 mad + r3 = r3 ^ r5; // 3 xor + r7 = r7 ^ ds[r2 & mask]; // 4 load + r5 = r5 ^ ds[r7 & mask]; // 5 load + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r1 = r1 ^ t_; } // 6 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r7 = r7 ^ t_; } // 7 shfl + r1 = mul_hi(r1, r5); // 8 mulhi + r6 = rotr_var(r6, r3); // 9 rotr + r3 = r3 | r4; // 10 or + r4 = r4 ^ ds[r3 & mask]; // 11 load + r0 = mul_hi(r0, r4); // 12 mulhi + r5 = r5 + r1 + ((((sel >> 30u) & 1u) != 0u) ? 0xd3177981u : 0xc7934706u); // 13 add + r0 = r0 ^ ds[r4 & mask]; // 14 load + r2 = r2 - r4; // 15 sub + r2 = r2 ^ ds[r0 & mask]; // 16 load + r7 = r7 ^ ds[r2 & mask]; // 17 load + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r7 = r7 ^ t_; } // 18 shfl + r5 = r5 * r0; // 19 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // 20 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 16u); r2 = r2 ^ t_; } // 21 shfl + r6 = mul_hi(r6, r2); // 22 mulhi + r6 = r6 ^ ds[r1 & mask]; // 23 load + r5 = r5 * r0; // 24 mul + r5 = rotl_imm(r5, 19u); // 25 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 2u); r7 = r7 ^ t_; } // 26 shfl + r0 = r0 ^ r5; // 27 xor + r0 = r0 ^ r4; // 28 xor + r3 = r3 - r0; // 29 sub + r5 = r5 * r1; // 30 mul + r7 = r7 ^ ds[r2 & mask]; // 31 load + r1 = r1 ^ ds[r0 & mask]; // 32 load + r5 = r5 ^ r6; // 33 xor + r5 = r5 ^ ds[r1 & mask]; // 34 load + r0 = mul_hi(r0, r5); // 35 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r5 = r5 ^ t_; } // 36 shfl + r7 = r7 ^ ds[r0 & mask]; // 37 load + r3 = r3 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0x230c005cu : 0x75ba2fadu); // 38 add + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 4u); r1 = r1 ^ t_; } // 39 shfl + r2 = r2 ^ r5; // 40 xor + r3 = r6 * r3 + r3; // 41 mad + r6 = r6 - r7; // 42 sub + r7 = r7 ^ r0; // 43 xor + r1 = r1 ^ ds[r7 & mask]; // 44 load + r2 = r2 * r3; // 45 mul + r1 = mul_hi(r1, r5); // 46 mulhi + r4 = r4 - r3; // 47 sub + r2 = rotr_var(r2, r6); // 48 rotr + r3 = r3 ^ ds[r5 & mask]; // 49 load + r1 = r1 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x1907970cu : 0x81b8bc2cu); // 50 add + r0 = r0 * r2; // 51 mul + r0 = r0 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x699fd448u : 0x4f92b968u); // 52 add + r1 = r1 + r0 + ((((sel >> 12u) & 1u) != 0u) ? 0x77b1520du : 0x2bb965afu); // 53 add + r7 = rotl_imm(r7, 14u); // 54 rotl + r3 = r3 + r7 + ((((sel >> 1u) & 1u) != 0u) ? 0xa54c55a0u : 0x7b0fe07au); // 55 add + r6 = r6 ^ ds[r7 & mask]; // 56 load + r1 = rotr_var(r1, r5); // 57 rotr + r5 = r5 ^ ds[r4 & mask]; // 58 load + r6 = r6 ^ ds[r2 & mask]; // 59 load + r3 = r5 * r0 + r3; // 60 mad + r5 = r5 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0xad7493e7u : 0xaf9dd72du); // 61 add + r4 = r4 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x1e07c3d9u : 0x89841d87u); // 62 add + r5 = rotl_imm(r5, 19u); // 63 rotl + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 53 passes after instruction 63, no load + for (uint sh = 0u; sh < 53u; ++sh) { + r5 = r5 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x8bc12da9u : 0x92199f99u); // s0 add + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x63079e5au : 0x8d72d3adu); // s1 add + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 2u); r6 = r6 ^ t_; } // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + ((((sel >> 31u) & 1u) != 0u) ? 0x5d4c7a60u : 0xb21b4babu); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + ((((sel >> 16u) & 1u) != 0u) ? 0xc88e2942u : 0x2fe0e98bu); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r6 = r6 ^ t_; } // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 4u); r2 = r2 ^ t_; } // s12 shfl + r1 = r1 + r5 + ((((sel >> 25u) & 1u) != 0u) ? 0xbc48c63eu : 0xbdf8f9a5u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r2 = r2 ^ t_; } // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + ((((sel >> 1u) & 1u) != 0u) ? 0x96e8f127u : 0x45c37cecu); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = mul_hi(r6, r0); // s28 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r2 = r2 ^ t_; } // s29 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r1 = r1 ^ t_; } // s30 shfl + r1 = r1 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0xb1cdb2abu : 0x37985632u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // s33 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r0 = r0 ^ t_; } // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x856e0180u : 0x804e777eu); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xe9bd0cc4u : 0x0b06c8a7u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = mul_hi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = mul_hi(r4, r3); // s44 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xcdcb63f6u : 0xee822e17u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r4 = r4 ^ t_; } // s47 shfl + r6 = mul_hi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0xd4758987u : 0x3dfad1b6u); // s56 add + r4 = r4 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x0602d6beu : 0xfca75bc2u); // s57 add + r5 = mul_hi(r5, r6); // s58 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r2 = r2 ^ t_; } // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0x8596687au : 0xd71c02ffu); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 2u); r7 = r7 ^ t_; } // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0x08ac5733u : 0x3c6fe15du); // s72 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r3 = r3 ^ t_; } // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + ((((sel >> 1u) & 1u) != 0u) ? 0xc100b495u : 0x295d5faeu); // s77 add + r3 = mul_hi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + ((((sel >> 15u) & 1u) != 0u) ? 0x5cc59530u : 0x274a9221u); // s81 add + r7 = r7 + r3 + ((((sel >> 5u) & 1u) != 0u) ? 0x141479ecu : 0xc8651f8eu); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r2 = r2 ^ t_; } // s85 shfl + r3 = r3 ^ r2; // s86 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 2u); r5 = r5 ^ t_; } // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x883c0c92u : 0x53f915c2u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + ((((sel >> 31u) & 1u) != 0u) ? 0x3cc5bd20u : 0xe2be00a5u); // s91 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 1u); r7 = r7 ^ t_; } // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + ((((sel >> 17u) & 1u) != 0u) ? 0xbfd646cbu : 0x423fd9c9u); // s101 add + r7 = r7 + r6 + ((((sel >> 11u) & 1u) != 0u) ? 0x19b74a43u : 0x8d3c011du); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + ((((sel >> 15u) & 1u) != 0u) ? 0x7dcb7e18u : 0x8ce14721u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = mul_hi(r2, r0); // s109 mulhi + r1 = mul_hi(r1, r0); // s110 mulhi + r0 = r0 + r2 + ((((sel >> 28u) & 1u) != 0u) ? 0x3c179ad8u : 0x2d9fc6b9u); // s111 add + r2 = mul_hi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + ((((sel >> 22u) & 1u) != 0u) ? 0x47359729u : 0x502138e2u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = mul_hi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 2u); r4 = r4 ^ t_; } // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r7 = r7 ^ t_; } // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x6c57e4e7u : 0x33dff776u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + ((((sel >> 30u) & 1u) != 0u) ? 0xe8212c0cu : 0x5db25b34u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = mul_hi(r0, r5); // s138 mulhi + r2 = r2 + r7 + ((((sel >> 10u) & 1u) != 0u) ? 0xd44ff710u : 0x218d4090u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r3 = r3 ^ t_; } // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + ((((sel >> 29u) & 1u) != 0u) ? 0xb98942fau : 0xf4b1a8deu); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + ((((sel >> 17u) & 1u) != 0u) ? 0x0d48ba42u : 0x2bef10f2u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + ((((sel >> 30u) & 1u) != 0u) ? 0xc98dea9cu : 0xdc5cc080u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0x6c752dcbu : 0x18197438u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + ((((sel >> 3u) & 1u) != 0u) ? 0x8e481727u : 0xf1c46574u); // s163 add + r0 = mul_hi(r0, r4); // s164 mulhi + r2 = r2 + r6 + ((((sel >> 20u) & 1u) != 0u) ? 0x550ab406u : 0xac578137u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + ((((sel >> 14u) & 1u) != 0u) ? 0xaebb5966u : 0xa33e6706u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 8u); r7 = r7 ^ t_; } // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x5bb7550fu : 0xd94d55acu); // s184 add + r3 = r3 | r5; // s185 or + r6 = mul_hi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r7 = r7 ^ t_; } // s188 shfl + r6 = r6 + r5 + ((((sel >> 6u) & 1u) != 0u) ? 0x2a354e2du : 0x89e747feu); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = mul_hi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r4 = r4 ^ t_; } // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + ((((sel >> 7u) & 1u) != 0u) ? 0x10cfdc71u : 0xea03e8e7u); // s197 add + r7 = r7 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x66e148d3u : 0xa7ee0102u); // s198 add + r5 = r5 - r2; // s199 sub + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r5 = r5 ^ t_; } // s200 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 8u); r7 = r7 ^ t_; } // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0x8558b619u : 0x8379a4deu); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = mul_hi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 4u); r2 = r2 ^ t_; } // s209 shfl + r7 = r7 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0xf4049c4cu : 0xaa8cb14eu); // s210 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 16u); r7 = r7 ^ t_; } // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 16u); r3 = r3 ^ t_; } // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = mul_hi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r5 = r5 ^ t_; } // s222 shfl + r5 = mul_hi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0x2a7fecb2u : 0x1d176220u); // s230 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r1 = r1 ^ t_; } // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + ((((sel >> 25u) & 1u) != 0u) ? 0xadce39f3u : 0x17dafb4du); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + ((((sel >> 29u) & 1u) != 0u) ? 0x0e7033b6u : 0xf2f77d26u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + ((((sel >> 31u) & 1u) != 0u) ? 0x7b2ff6b7u : 0xfed2da4eu); // s247 add + r0 = r0 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0xb5fad7b1u : 0x03b2891cu); // s248 add + r5 = mul_hi(r5, r4); // s249 mulhi + r5 = r5 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0xa7e71c2fu : 0x042cd6e3u); // s250 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 1u); r6 = r6 ^ t_; } // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0xb83d78deu : 0x784a302bu); // s254 add + r2 = r2 - r4; // s255 sub + } + } + 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 = r3 * r4 + r2; // 0 mad + r2 = r1 * r1 + r2; // 1 mad + r2 = r3 * r2 + r2; // 2 mad + r3 = r3 ^ r5; // 3 xor + r7 = r7 ^ ds[r2 & mask]; // 4 load + r5 = r5 ^ ds[r7 & mask]; // 5 load + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r1 = r1 ^ t_; } // 6 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r7 = r7 ^ t_; } // 7 shfl + r1 = mul_hi(r1, r5); // 8 mulhi + r6 = rotr_var(r6, r3); // 9 rotr + r3 = r3 | r4; // 10 or + r4 = r4 ^ ds[r3 & mask]; // 11 load + r0 = mul_hi(r0, r4); // 12 mulhi + r5 = r5 + r1 + ((((sel >> 30u) & 1u) != 0u) ? 0xd3177981u : 0xc7934706u); // 13 add + r0 = r0 ^ ds[r4 & mask]; // 14 load + r2 = r2 - r4; // 15 sub + r2 = r2 ^ ds[r0 & mask]; // 16 load + r7 = r7 ^ ds[r2 & mask]; // 17 load + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r7 = r7 ^ t_; } // 18 shfl + r5 = r5 * r0; // 19 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // 20 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 16u); r2 = r2 ^ t_; } // 21 shfl + r6 = mul_hi(r6, r2); // 22 mulhi + r6 = r6 ^ ds[r1 & mask]; // 23 load + r5 = r5 * r0; // 24 mul + r5 = rotl_imm(r5, 19u); // 25 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 2u); r7 = r7 ^ t_; } // 26 shfl + r0 = r0 ^ r5; // 27 xor + r0 = r0 ^ r4; // 28 xor + r3 = r3 - r0; // 29 sub + r5 = r5 * r1; // 30 mul + r7 = r7 ^ ds[r2 & mask]; // 31 load + r1 = r1 ^ ds[r0 & mask]; // 32 load + r5 = r5 ^ r6; // 33 xor + r5 = r5 ^ ds[r1 & mask]; // 34 load + r0 = mul_hi(r0, r5); // 35 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r5 = r5 ^ t_; } // 36 shfl + r7 = r7 ^ ds[r0 & mask]; // 37 load + r3 = r3 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0x230c005cu : 0x75ba2fadu); // 38 add + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 4u); r1 = r1 ^ t_; } // 39 shfl + r2 = r2 ^ r5; // 40 xor + r3 = r6 * r3 + r3; // 41 mad + r6 = r6 - r7; // 42 sub + r7 = r7 ^ r0; // 43 xor + r1 = r1 ^ ds[r7 & mask]; // 44 load + r2 = r2 * r3; // 45 mul + r1 = mul_hi(r1, r5); // 46 mulhi + r4 = r4 - r3; // 47 sub + r2 = rotr_var(r2, r6); // 48 rotr + r3 = r3 ^ ds[r5 & mask]; // 49 load + r1 = r1 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x1907970cu : 0x81b8bc2cu); // 50 add + r0 = r0 * r2; // 51 mul + r0 = r0 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x699fd448u : 0x4f92b968u); // 52 add + r1 = r1 + r0 + ((((sel >> 12u) & 1u) != 0u) ? 0x77b1520du : 0x2bb965afu); // 53 add + r7 = rotl_imm(r7, 14u); // 54 rotl + r3 = r3 + r7 + ((((sel >> 1u) & 1u) != 0u) ? 0xa54c55a0u : 0x7b0fe07au); // 55 add + r6 = r6 ^ ds[r7 & mask]; // 56 load + r1 = rotr_var(r1, r5); // 57 rotr + r5 = r5 ^ ds[r4 & mask]; // 58 load + r6 = r6 ^ ds[r2 & mask]; // 59 load + r3 = r5 * r0 + r3; // 60 mad + r5 = r5 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0xad7493e7u : 0xaf9dd72du); // 61 add + r4 = r4 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x1e07c3d9u : 0x89841d87u); // 62 add + r5 = rotl_imm(r5, 19u); // 63 rotl + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 53 passes after instruction 63, no load + for (uint sh = 0u; sh < 53u; ++sh) { + r5 = r5 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x8bc12da9u : 0x92199f99u); // s0 add + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x63079e5au : 0x8d72d3adu); // s1 add + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 2u); r6 = r6 ^ t_; } // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + ((((sel >> 31u) & 1u) != 0u) ? 0x5d4c7a60u : 0xb21b4babu); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + ((((sel >> 16u) & 1u) != 0u) ? 0xc88e2942u : 0x2fe0e98bu); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r6 = r6 ^ t_; } // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 4u); r2 = r2 ^ t_; } // s12 shfl + r1 = r1 + r5 + ((((sel >> 25u) & 1u) != 0u) ? 0xbc48c63eu : 0xbdf8f9a5u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r2 = r2 ^ t_; } // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + ((((sel >> 1u) & 1u) != 0u) ? 0x96e8f127u : 0x45c37cecu); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = mul_hi(r6, r0); // s28 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r2 = r2 ^ t_; } // s29 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r1 = r1 ^ t_; } // s30 shfl + r1 = r1 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0xb1cdb2abu : 0x37985632u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // s33 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r0 = r0 ^ t_; } // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x856e0180u : 0x804e777eu); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xe9bd0cc4u : 0x0b06c8a7u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = mul_hi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = mul_hi(r4, r3); // s44 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xcdcb63f6u : 0xee822e17u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r4 = r4 ^ t_; } // s47 shfl + r6 = mul_hi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0xd4758987u : 0x3dfad1b6u); // s56 add + r4 = r4 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x0602d6beu : 0xfca75bc2u); // s57 add + r5 = mul_hi(r5, r6); // s58 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r2 = r2 ^ t_; } // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0x8596687au : 0xd71c02ffu); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 2u); r7 = r7 ^ t_; } // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0x08ac5733u : 0x3c6fe15du); // s72 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r3 = r3 ^ t_; } // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + ((((sel >> 1u) & 1u) != 0u) ? 0xc100b495u : 0x295d5faeu); // s77 add + r3 = mul_hi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + ((((sel >> 15u) & 1u) != 0u) ? 0x5cc59530u : 0x274a9221u); // s81 add + r7 = r7 + r3 + ((((sel >> 5u) & 1u) != 0u) ? 0x141479ecu : 0xc8651f8eu); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r2 = r2 ^ t_; } // s85 shfl + r3 = r3 ^ r2; // s86 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 2u); r5 = r5 ^ t_; } // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x883c0c92u : 0x53f915c2u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + ((((sel >> 31u) & 1u) != 0u) ? 0x3cc5bd20u : 0xe2be00a5u); // s91 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 1u); r7 = r7 ^ t_; } // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + ((((sel >> 17u) & 1u) != 0u) ? 0xbfd646cbu : 0x423fd9c9u); // s101 add + r7 = r7 + r6 + ((((sel >> 11u) & 1u) != 0u) ? 0x19b74a43u : 0x8d3c011du); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + ((((sel >> 15u) & 1u) != 0u) ? 0x7dcb7e18u : 0x8ce14721u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = mul_hi(r2, r0); // s109 mulhi + r1 = mul_hi(r1, r0); // s110 mulhi + r0 = r0 + r2 + ((((sel >> 28u) & 1u) != 0u) ? 0x3c179ad8u : 0x2d9fc6b9u); // s111 add + r2 = mul_hi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + ((((sel >> 22u) & 1u) != 0u) ? 0x47359729u : 0x502138e2u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = mul_hi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 2u); r4 = r4 ^ t_; } // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r7 = r7 ^ t_; } // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x6c57e4e7u : 0x33dff776u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + ((((sel >> 30u) & 1u) != 0u) ? 0xe8212c0cu : 0x5db25b34u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = mul_hi(r0, r5); // s138 mulhi + r2 = r2 + r7 + ((((sel >> 10u) & 1u) != 0u) ? 0xd44ff710u : 0x218d4090u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r3 = r3 ^ t_; } // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + ((((sel >> 29u) & 1u) != 0u) ? 0xb98942fau : 0xf4b1a8deu); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + ((((sel >> 17u) & 1u) != 0u) ? 0x0d48ba42u : 0x2bef10f2u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + ((((sel >> 30u) & 1u) != 0u) ? 0xc98dea9cu : 0xdc5cc080u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0x6c752dcbu : 0x18197438u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + ((((sel >> 3u) & 1u) != 0u) ? 0x8e481727u : 0xf1c46574u); // s163 add + r0 = mul_hi(r0, r4); // s164 mulhi + r2 = r2 + r6 + ((((sel >> 20u) & 1u) != 0u) ? 0x550ab406u : 0xac578137u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + ((((sel >> 14u) & 1u) != 0u) ? 0xaebb5966u : 0xa33e6706u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 8u); r7 = r7 ^ t_; } // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x5bb7550fu : 0xd94d55acu); // s184 add + r3 = r3 | r5; // s185 or + r6 = mul_hi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r7 = r7 ^ t_; } // s188 shfl + r6 = r6 + r5 + ((((sel >> 6u) & 1u) != 0u) ? 0x2a354e2du : 0x89e747feu); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = mul_hi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r4 = r4 ^ t_; } // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + ((((sel >> 7u) & 1u) != 0u) ? 0x10cfdc71u : 0xea03e8e7u); // s197 add + r7 = r7 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x66e148d3u : 0xa7ee0102u); // s198 add + r5 = r5 - r2; // s199 sub + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r5 = r5 ^ t_; } // s200 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 8u); r7 = r7 ^ t_; } // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0x8558b619u : 0x8379a4deu); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = mul_hi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 4u); r2 = r2 ^ t_; } // s209 shfl + r7 = r7 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0xf4049c4cu : 0xaa8cb14eu); // s210 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 16u); r7 = r7 ^ t_; } // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 16u); r3 = r3 ^ t_; } // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = mul_hi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r5 = r5 ^ t_; } // s222 shfl + r5 = mul_hi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0x2a7fecb2u : 0x1d176220u); // s230 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r1 = r1 ^ t_; } // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + ((((sel >> 25u) & 1u) != 0u) ? 0xadce39f3u : 0x17dafb4du); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + ((((sel >> 29u) & 1u) != 0u) ? 0x0e7033b6u : 0xf2f77d26u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + ((((sel >> 31u) & 1u) != 0u) ? 0x7b2ff6b7u : 0xfed2da4eu); // s247 add + r0 = r0 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0xb5fad7b1u : 0x03b2891cu); // s248 add + r5 = mul_hi(r5, r4); // s249 mulhi + r5 = r5 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0xa7e71c2fu : 0x042cd6e3u); // s250 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 1u); r6 = r6 ^ t_; } // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0xb83d78deu : 0x784a302bu); // s254 add + r2 = r2 - r4; // s255 sub + } + } + uint lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((ulong)hi << 32) | (ulong)lo; +} diff --git a/proto-cuda/packs-ca3-shadow/sh256x53/kernel_bound.cu b/proto-cuda/packs-ca3-shadow/sh256x53/kernel_bound.cu new file mode 100644 index 000000000..a9862303b --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x53/kernel_bound.cu @@ -0,0 +1,382 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Header-bound twin of igneum_hash in kernel.cu: the init words come from a kernel argument, not SEEDW. +// Host declarations (also in program_bound.h if present): +// struct IgneumInitWords { uint32_t w[8]; }; +// cudaError_t igneum_launch_hash_bound(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, +// IgneumInitWords iw, uint32_t nonces, uint32_t blockWarps); +// cudaError_t igneum_hash_bound_info(int* numRegs, int* blocksPerSM, uint32_t blockWarps); +#include +#include +#include "program.h" + +struct IgneumInitWords { uint32_t w[8]; }; + +__device__ __forceinline__ uint32_t splitmix32(uint32_t x) { + x ^= x >> 16; x *= 0x7feb352du; + x ^= x >> 15; x *= 0x846ca68bu; + x ^= x >> 16; + return x; +} +__device__ __forceinline__ uint32_t rotl_imm(uint32_t x, uint32_t n) { return (x << n) | (x >> (32u - n)); } +__device__ __forceinline__ uint32_t rotr_var(uint32_t x, uint32_t n) { n &= 31u; return (x >> n) | (x << ((32u - n) & 31u)); } + +__global__ void igneum_hash_bound(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, IgneumInitWords iw) { + uint32_t gid = blockIdx.x * blockDim.x + threadIdx.x; + uint32_t nonce = baseNonce + gid; + uint32_t r0, r1, r2, r3, r4, r5, r6, r7; + { uint32_t x = nonce ^ iw.w[0]; x += 0x9e3779b9u * 1u; x = splitmix32(x); r0 = x ^ iw.w[1]; } + { uint32_t x = nonce ^ iw.w[1]; x += 0x9e3779b9u * 2u; x = splitmix32(x); r1 = x ^ iw.w[2]; } + { uint32_t x = nonce ^ iw.w[2]; x += 0x9e3779b9u * 3u; x = splitmix32(x); r2 = x ^ iw.w[3]; } + { uint32_t x = nonce ^ iw.w[3]; x += 0x9e3779b9u * 4u; x = splitmix32(x); r3 = x ^ iw.w[4]; } + { uint32_t x = nonce ^ iw.w[4]; x += 0x9e3779b9u * 5u; x = splitmix32(x); r4 = x ^ iw.w[5]; } + { uint32_t x = nonce ^ iw.w[5]; x += 0x9e3779b9u * 6u; x = splitmix32(x); r5 = x ^ iw.w[6]; } + { uint32_t x = nonce ^ iw.w[6]; x += 0x9e3779b9u * 7u; x = splitmix32(x); r6 = x ^ iw.w[7]; } + { uint32_t x = nonce ^ iw.w[7]; x += 0x9e3779b9u * 8u; x = splitmix32(x); r7 = x ^ iw.w[0]; } + + for (uint32_t it = 0u; it < 8u; ++it) { + uint32_t sel = r0; + r2 = r3 * r4 + r2; // 0 mad + r2 = r1 * r1 + r2; // 1 mad + r2 = r3 * r2 + r2; // 2 mad + r3 = r3 ^ r5; // 3 xor + r7 = r7 ^ ds[r2 & mask]; // 4 load + r5 = r5 ^ ds[r7 & mask]; // 5 load + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r4, 8); // 6 shfl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r3, 8); // 7 shfl + r1 = __umulhi(r1, r5); // 8 mulhi + r6 = rotr_var(r6, r3); // 9 rotr + r3 = r3 | r4; // 10 or + r4 = r4 ^ ds[r3 & mask]; // 11 load + r0 = __umulhi(r0, r4); // 12 mulhi + r5 = r5 + r1 + ((((sel >> 30u) & 1u) != 0u) ? 0xd3177981u : 0xc7934706u); // 13 add + r0 = r0 ^ ds[r4 & mask]; // 14 load + r2 = r2 - r4; // 15 sub + r2 = r2 ^ ds[r0 & mask]; // 16 load + r7 = r7 ^ ds[r2 & mask]; // 17 load + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r3, 4); // 18 shfl + r5 = r5 * r0; // 19 mul + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // 20 shfl + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 16); // 21 shfl + r6 = __umulhi(r6, r2); // 22 mulhi + r6 = r6 ^ ds[r1 & mask]; // 23 load + r5 = r5 * r0; // 24 mul + r5 = rotl_imm(r5, 19u); // 25 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r6, 2); // 26 shfl + r0 = r0 ^ r5; // 27 xor + r0 = r0 ^ r4; // 28 xor + r3 = r3 - r0; // 29 sub + r5 = r5 * r1; // 30 mul + r7 = r7 ^ ds[r2 & mask]; // 31 load + r1 = r1 ^ ds[r0 & mask]; // 32 load + r5 = r5 ^ r6; // 33 xor + r5 = r5 ^ ds[r1 & mask]; // 34 load + r0 = __umulhi(r0, r5); // 35 mulhi + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // 36 shfl + r7 = r7 ^ ds[r0 & mask]; // 37 load + r3 = r3 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0x230c005cu : 0x75ba2fadu); // 38 add + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r5, 4); // 39 shfl + r2 = r2 ^ r5; // 40 xor + r3 = r6 * r3 + r3; // 41 mad + r6 = r6 - r7; // 42 sub + r7 = r7 ^ r0; // 43 xor + r1 = r1 ^ ds[r7 & mask]; // 44 load + r2 = r2 * r3; // 45 mul + r1 = __umulhi(r1, r5); // 46 mulhi + r4 = r4 - r3; // 47 sub + r2 = rotr_var(r2, r6); // 48 rotr + r3 = r3 ^ ds[r5 & mask]; // 49 load + r1 = r1 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x1907970cu : 0x81b8bc2cu); // 50 add + r0 = r0 * r2; // 51 mul + r0 = r0 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x699fd448u : 0x4f92b968u); // 52 add + r1 = r1 + r0 + ((((sel >> 12u) & 1u) != 0u) ? 0x77b1520du : 0x2bb965afu); // 53 add + r7 = rotl_imm(r7, 14u); // 54 rotl + r3 = r3 + r7 + ((((sel >> 1u) & 1u) != 0u) ? 0xa54c55a0u : 0x7b0fe07au); // 55 add + r6 = r6 ^ ds[r7 & mask]; // 56 load + r1 = rotr_var(r1, r5); // 57 rotr + r5 = r5 ^ ds[r4 & mask]; // 58 load + r6 = r6 ^ ds[r2 & mask]; // 59 load + r3 = r5 * r0 + r3; // 60 mad + r5 = r5 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0xad7493e7u : 0xaf9dd72du); // 61 add + r4 = r4 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x1e07c3d9u : 0x89841d87u); // 62 add + r5 = rotl_imm(r5, 19u); // 63 rotl + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 53 passes after instruction 63, no load + for (uint32_t sh = 0u; sh < 53u; ++sh) { + r5 = r5 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x8bc12da9u : 0x92199f99u); // s0 add + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x63079e5au : 0x8d72d3adu); // s1 add + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r3, 2); // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + ((((sel >> 31u) & 1u) != 0u) ? 0x5d4c7a60u : 0xb21b4babu); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + ((((sel >> 16u) & 1u) != 0u) ? 0xc88e2942u : 0x2fe0e98bu); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r1, 4); // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r6, 4); // s12 shfl + r1 = r1 + r5 + ((((sel >> 25u) & 1u) != 0u) ? 0xbc48c63eu : 0xbdf8f9a5u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 8); // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + ((((sel >> 1u) & 1u) != 0u) ? 0x96e8f127u : 0x45c37cecu); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = __umulhi(r6, r0); // s28 mulhi + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // s29 shfl + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r6, 1); // s30 shfl + r1 = r1 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0xb1cdb2abu : 0x37985632u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // s33 shfl + r0 = r0 ^ __shfl_xor_sync(0xffffffffu, r3, 4); // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x856e0180u : 0x804e777eu); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xe9bd0cc4u : 0x0b06c8a7u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = __umulhi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = __umulhi(r4, r3); // s44 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xcdcb63f6u : 0xee822e17u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r3, 8); // s47 shfl + r6 = __umulhi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0xd4758987u : 0x3dfad1b6u); // s56 add + r4 = r4 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x0602d6beu : 0xfca75bc2u); // s57 add + r5 = __umulhi(r5, r6); // s58 mulhi + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0x8596687au : 0xd71c02ffu); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r5, 2); // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0x08ac5733u : 0x3c6fe15du); // s72 add + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r2, 8); // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + ((((sel >> 1u) & 1u) != 0u) ? 0xc100b495u : 0x295d5faeu); // s77 add + r3 = __umulhi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + ((((sel >> 15u) & 1u) != 0u) ? 0x5cc59530u : 0x274a9221u); // s81 add + r7 = r7 + r3 + ((((sel >> 5u) & 1u) != 0u) ? 0x141479ecu : 0xc8651f8eu); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r5, 16); // s85 shfl + r3 = r3 ^ r2; // s86 xor + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r7, 2); // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x883c0c92u : 0x53f915c2u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + ((((sel >> 31u) & 1u) != 0u) ? 0x3cc5bd20u : 0xe2be00a5u); // s91 add + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r2, 1); // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + ((((sel >> 17u) & 1u) != 0u) ? 0xbfd646cbu : 0x423fd9c9u); // s101 add + r7 = r7 + r6 + ((((sel >> 11u) & 1u) != 0u) ? 0x19b74a43u : 0x8d3c011du); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + ((((sel >> 15u) & 1u) != 0u) ? 0x7dcb7e18u : 0x8ce14721u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = __umulhi(r2, r0); // s109 mulhi + r1 = __umulhi(r1, r0); // s110 mulhi + r0 = r0 + r2 + ((((sel >> 28u) & 1u) != 0u) ? 0x3c179ad8u : 0x2d9fc6b9u); // s111 add + r2 = __umulhi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + ((((sel >> 22u) & 1u) != 0u) ? 0x47359729u : 0x502138e2u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = __umulhi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r2, 2); // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x6c57e4e7u : 0x33dff776u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + ((((sel >> 30u) & 1u) != 0u) ? 0xe8212c0cu : 0x5db25b34u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = __umulhi(r0, r5); // s138 mulhi + r2 = r2 + r7 + ((((sel >> 10u) & 1u) != 0u) ? 0xd44ff710u : 0x218d4090u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r6, 1); // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + ((((sel >> 29u) & 1u) != 0u) ? 0xb98942fau : 0xf4b1a8deu); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + ((((sel >> 17u) & 1u) != 0u) ? 0x0d48ba42u : 0x2bef10f2u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + ((((sel >> 30u) & 1u) != 0u) ? 0xc98dea9cu : 0xdc5cc080u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0x6c752dcbu : 0x18197438u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + ((((sel >> 3u) & 1u) != 0u) ? 0x8e481727u : 0xf1c46574u); // s163 add + r0 = __umulhi(r0, r4); // s164 mulhi + r2 = r2 + r6 + ((((sel >> 20u) & 1u) != 0u) ? 0x550ab406u : 0xac578137u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + ((((sel >> 14u) & 1u) != 0u) ? 0xaebb5966u : 0xa33e6706u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r0, 8); // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x5bb7550fu : 0xd94d55acu); // s184 add + r3 = r3 | r5; // s185 or + r6 = __umulhi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s188 shfl + r6 = r6 + r5 + ((((sel >> 6u) & 1u) != 0u) ? 0x2a354e2du : 0x89e747feu); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = __umulhi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r5, 16); // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + ((((sel >> 7u) & 1u) != 0u) ? 0x10cfdc71u : 0xea03e8e7u); // s197 add + r7 = r7 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x66e148d3u : 0xa7ee0102u); // s198 add + r5 = r5 - r2; // s199 sub + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s200 shfl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 8); // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0x8558b619u : 0x8379a4deu); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = __umulhi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r0, 4); // s209 shfl + r7 = r7 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0xf4049c4cu : 0xaa8cb14eu); // s210 add + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 16); // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r2, 16); // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = __umulhi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r2, 8); // s222 shfl + r5 = __umulhi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0x2a7fecb2u : 0x1d176220u); // s230 add + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + ((((sel >> 25u) & 1u) != 0u) ? 0xadce39f3u : 0x17dafb4du); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + ((((sel >> 29u) & 1u) != 0u) ? 0x0e7033b6u : 0xf2f77d26u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + ((((sel >> 31u) & 1u) != 0u) ? 0x7b2ff6b7u : 0xfed2da4eu); // s247 add + r0 = r0 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0xb5fad7b1u : 0x03b2891cu); // s248 add + r5 = __umulhi(r5, r4); // s249 mulhi + r5 = r5 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0xa7e71c2fu : 0x042cd6e3u); // s250 add + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r1, 1); // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0xb83d78deu : 0x784a302bu); // s254 add + r2 = r2 - r4; // s255 sub + } + } + uint32_t lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint32_t hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((uint64_t)hi << 32) | (uint64_t)lo; +} + +cudaError_t igneum_launch_hash_bound(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, + IgneumInitWords iw, uint32_t nonces, uint32_t blockWarps) { + if (blockWarps == 0u || blockWarps > 32u) return cudaErrorInvalidValue; + uint32_t block = 32u * blockWarps; + if (nonces == 0u || (nonces % block) != 0u) return cudaErrorInvalidValue; + igneum_hash_bound<<>>(ds, out, baseNonce, mask, iw); + return cudaGetLastError(); +} + +cudaError_t igneum_hash_bound_info(int* numRegs, int* blocksPerSM, uint32_t blockWarps) { + cudaFuncAttributes attr; + cudaError_t e = cudaFuncGetAttributes(&attr, igneum_hash_bound); + if (e != cudaSuccess) return e; + *numRegs = attr.numRegs; + return cudaOccupancyMaxActiveBlocksPerMultiprocessor(blocksPerSM, igneum_hash_bound, (int)(32u * blockWarps), 0); +} diff --git a/proto-cuda/packs-ca3-shadow/sh256x53/memhard.h b/proto-cuda/packs-ca3-shadow/sh256x53/memhard.h new file mode 100644 index 000000000..f7f34c732 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x53/memhard.h @@ -0,0 +1,109 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Memory-hard dataset core, the same text that the Mac's Metal kernels and CPU verifier were checked against. +// Included by kernel.cu (device), host.cu (host reference) and proto-opencl/host.c (C99 host reference). +// See proto-metal/MEMHARD.md for the construction. kernel.cl carries the same text in OpenCL C. +#pragma once +#ifdef __cplusplus +#include +#else +#include +#endif +#if defined(__CUDACC__) +#define IGNEUM_HD __host__ __device__ __forceinline__ +#elif defined(_MSC_VER) && !defined(__cplusplus) +#define IGNEUM_HD static __inline +#else +#define IGNEUM_HD static inline +#endif +// Memory-hard dataset core (MEMHARD.md). Cache: 2^26 words in 2^16 segments of 64 chained ChaCha12 lines. +// Item: 8 rounds of 8 x seed-parameterised mixer + one 64-byte cache read, then 8 x final mixer (class v3, mixer multiplier 8, +// docs/plans/mixer-x4.md: the round key of application j of round r is 0x9E3779B9 * (r * m + j + 1)). All parameters are literals. +#define MH_CACHE_LINE_MASK 0x003fffffu +#define MH_SEGMENT_LINES 64u +#define MH_QR(a, b, c, d, r1, r2, r3, r4) { a += b; d ^= a; d = mh_rotl(d, r1); c += d; b ^= c; b = mh_rotl(b, r2); a += b; d ^= a; d = mh_rotl(d, r3); c += d; b ^= c; b = mh_rotl(b, r4); } +IGNEUM_HD uint32_t mh_rotl(uint32_t x, uint32_t n) { return (x << n) | (x >> (32u - n)); } // n in 1..31 at every call site + +// y = ChaCha12 core(x) + x +IGNEUM_HD void mh_chacha_block(const uint32_t* x, uint32_t* y) { + for (uint32_t i = 0u; i < 16u; ++i) y[i] = x[i]; + for (uint32_t r = 0u; r < 6u; ++r) { + MH_QR(y[0], y[4], y[8], y[12], 16u, 12u, 8u, 7u) MH_QR(y[1], y[5], y[9], y[13], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[6], y[10], y[14], 16u, 12u, 8u, 7u) MH_QR(y[3], y[7], y[11], y[15], 16u, 12u, 8u, 7u) + MH_QR(y[0], y[5], y[10], y[15], 16u, 12u, 8u, 7u) MH_QR(y[1], y[6], y[11], y[12], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[7], y[8], y[13], 16u, 12u, 8u, 7u) MH_QR(y[3], y[4], y[9], y[14], 16u, 12u, 8u, 7u) + } + for (uint32_t i = 0u; i < 16u; ++i) y[i] += x[i]; +} + +// One cache segment: 64 chained lines written at cache[seg * 1024]. in_j = prev ^ (sigma || K || seg || j || tag), prev_0 = 0. +IGNEUM_HD void mh_cache_segment(uint32_t* cache, uint32_t seg) { + uint32_t prev[16]; uint32_t x[16]; uint32_t y[16]; + for (uint32_t i = 0u; i < 16u; ++i) prev[i] = 0u; + for (uint32_t j = 0u; j < MH_SEGMENT_LINES; ++j) { + x[0] = 0x61707865u ^ prev[0]; x[1] = 0x3320646eu ^ prev[1]; x[2] = 0x79622d32u ^ prev[2]; x[3] = 0x6b206574u ^ prev[3]; + x[4] = 0x3067619fu ^ prev[4]; + x[5] = 0x3c269176u ^ prev[5]; + x[6] = 0x84a03b03u ^ prev[6]; + x[7] = 0xf8c63294u ^ prev[7]; + x[8] = 0xff977c5bu ^ prev[8]; + x[9] = 0xe60def3eu ^ prev[9]; + x[10] = 0x63630141u ^ prev[10]; + x[11] = 0xb8fbcb58u ^ prev[11]; + x[12] = seg ^ prev[12]; x[13] = j ^ prev[13]; x[14] = 0x49676e65u ^ prev[14]; x[15] = 0x756d4d48u ^ prev[15]; + mh_chacha_block(x, y); + uint32_t* line = cache + ((seg * MH_SEGMENT_LINES + j) * 16u); + for (uint32_t i = 0u; i < 16u; ++i) { line[i] = y[i]; prev[i] = y[i]; } + } +} + +// M_r: per word (s ^ (RC + rk)) * MUL, then a column round and a diagonal round with the seed-drawn rotations. +IGNEUM_HD void mh_mixer(uint32_t* s, uint32_t rk) { + s[0] = (s[0] ^ (0xbab68293u + rk)) * 0x42146205u; + s[1] = (s[1] ^ (0xcc162340u + rk)) * 0x52cbe0fbu; + s[2] = (s[2] ^ (0x6ce151ccu + rk)) * 0x7ecf4a03u; + s[3] = (s[3] ^ (0xe62b8997u + rk)) * 0x6728907fu; + s[4] = (s[4] ^ (0xc9c80297u + rk)) * 0xd81d9751u; + s[5] = (s[5] ^ (0xf74a1654u + rk)) * 0x132952c3u; + s[6] = (s[6] ^ (0x3d704af5u + rk)) * 0xf60de277u; + s[7] = (s[7] ^ (0x3cf522b7u + rk)) * 0x05358035u; + s[8] = (s[8] ^ (0x2b9cac04u + rk)) * 0xbaf6499du; + s[9] = (s[9] ^ (0xa880ac10u + rk)) * 0xe4db9667u; + s[10] = (s[10] ^ (0x13e5dd1du + rk)) * 0x3e98f45du; + s[11] = (s[11] ^ (0x6fc3e233u + rk)) * 0xd0004eddu; + s[12] = (s[12] ^ (0x2d83eeacu + rk)) * 0x2691630du; + s[13] = (s[13] ^ (0x9006e8bfu + rk)) * 0x9beb3bcfu; + s[14] = (s[14] ^ (0x2c4b5362u + rk)) * 0xab310379u; + s[15] = (s[15] ^ (0x31b49ee2u + rk)) * 0x99cfb423u; + MH_QR(s[0], s[4], s[8], s[12], 20u, 20u, 19u, 4u) MH_QR(s[1], s[5], s[9], s[13], 20u, 20u, 19u, 4u) + MH_QR(s[2], s[6], s[10], s[14], 20u, 20u, 19u, 4u) MH_QR(s[3], s[7], s[11], s[15], 20u, 20u, 19u, 4u) + MH_QR(s[0], s[5], s[10], s[15], 26u, 3u, 3u, 27u) MH_QR(s[1], s[6], s[11], s[12], 26u, 3u, 3u, 27u) + MH_QR(s[2], s[7], s[8], s[13], 26u, 3u, 3u, 27u) MH_QR(s[3], s[4], s[9], s[14], 26u, 3u, 3u, 27u) +} + +// Item t: 16 words. s = (K, t * MUL[i] + RC[i]); 8 rounds of 8 x mixer + cache line s[0] & mask; 8 x final mixer. +IGNEUM_HD void mh_item(const uint32_t* cache, uint32_t t, uint32_t* s) { + s[0] = 0x3067619fu; + s[1] = 0x3c269176u; + s[2] = 0x84a03b03u; + s[3] = 0xf8c63294u; + s[4] = 0xff977c5bu; + s[5] = 0xe60def3eu; + s[6] = 0x63630141u; + s[7] = 0xb8fbcb58u; + s[8] = t * 0x42146205u + 0xbab68293u; + s[9] = t * 0x52cbe0fbu + 0xcc162340u; + s[10] = t * 0x7ecf4a03u + 0x6ce151ccu; + s[11] = t * 0x6728907fu + 0xe62b8997u; + s[12] = t * 0xd81d9751u + 0xc9c80297u; + s[13] = t * 0x132952c3u + 0xf74a1654u; + s[14] = t * 0xf60de277u + 0x3d704af5u; + s[15] = t * 0x05358035u + 0x3cf522b7u; + for (uint32_t r = 0u; r < 8u; ++r) { + for (uint32_t j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (r * 8u + j + 1u)); + const uint32_t* line = cache + ((s[0] & MH_CACHE_LINE_MASK) * 16u); + for (uint32_t i = 0u; i < 16u; ++i) s[i] ^= line[i]; + } + for (uint32_t j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (64u + j + 1u)); +} +// dataset[w] without the dataset: derive item w >> 4 and take word w & 15. +IGNEUM_HD uint32_t mh_word(const uint32_t* cache, uint32_t w) { uint32_t s[16]; mh_item(cache, w >> 4u, s); return s[w & 15u]; } diff --git a/proto-cuda/packs-ca3-shadow/sh256x53/memhard.metal b/proto-cuda/packs-ca3-shadow/sh256x53/memhard.metal new file mode 100644 index 000000000..01b263d6d --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x53/memhard.metal @@ -0,0 +1,107 @@ +#include +using namespace metal; +// Memory-hard dataset core (MEMHARD.md). Cache: 2^26 words in 2^16 segments of 64 chained ChaCha12 lines. +// Item: 8 rounds of 8 x seed-parameterised mixer + one 64-byte cache read, then 8 x final mixer (class v3, mixer multiplier 8, +// docs/plans/mixer-x4.md: the round key of application j of round r is 0x9E3779B9 * (r * m + j + 1)). All parameters are literals. +#define MH_CACHE_LINE_MASK 0x003fffffu +#define MH_SEGMENT_LINES 64u +#define MH_QR(a, b, c, d, r1, r2, r3, r4) { a += b; d ^= a; d = mh_rotl(d, r1); c += d; b ^= c; b = mh_rotl(b, r2); a += b; d ^= a; d = mh_rotl(d, r3); c += d; b ^= c; b = mh_rotl(b, r4); } +inline uint mh_rotl(uint x, uint n) { return (x << n) | (x >> (32u - n)); } // n in 1..31 at every call site + +// y = ChaCha12 core(x) + x +inline void mh_chacha_block(const thread uint* x, thread uint* y) { + for (uint i = 0u; i < 16u; ++i) y[i] = x[i]; + for (uint r = 0u; r < 6u; ++r) { + MH_QR(y[0], y[4], y[8], y[12], 16u, 12u, 8u, 7u) MH_QR(y[1], y[5], y[9], y[13], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[6], y[10], y[14], 16u, 12u, 8u, 7u) MH_QR(y[3], y[7], y[11], y[15], 16u, 12u, 8u, 7u) + MH_QR(y[0], y[5], y[10], y[15], 16u, 12u, 8u, 7u) MH_QR(y[1], y[6], y[11], y[12], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[7], y[8], y[13], 16u, 12u, 8u, 7u) MH_QR(y[3], y[4], y[9], y[14], 16u, 12u, 8u, 7u) + } + for (uint i = 0u; i < 16u; ++i) y[i] += x[i]; +} + +// One cache segment: 64 chained lines written at cache[seg * 1024]. in_j = prev ^ (sigma || K || seg || j || tag), prev_0 = 0. +inline void mh_cache_segment(device uint* cache, uint seg) { + uint prev[16]; uint x[16]; uint y[16]; + for (uint i = 0u; i < 16u; ++i) prev[i] = 0u; + for (uint j = 0u; j < MH_SEGMENT_LINES; ++j) { + x[0] = 0x61707865u ^ prev[0]; x[1] = 0x3320646eu ^ prev[1]; x[2] = 0x79622d32u ^ prev[2]; x[3] = 0x6b206574u ^ prev[3]; + x[4] = 0x3067619fu ^ prev[4]; + x[5] = 0x3c269176u ^ prev[5]; + x[6] = 0x84a03b03u ^ prev[6]; + x[7] = 0xf8c63294u ^ prev[7]; + x[8] = 0xff977c5bu ^ prev[8]; + x[9] = 0xe60def3eu ^ prev[9]; + x[10] = 0x63630141u ^ prev[10]; + x[11] = 0xb8fbcb58u ^ prev[11]; + x[12] = seg ^ prev[12]; x[13] = j ^ prev[13]; x[14] = 0x49676e65u ^ prev[14]; x[15] = 0x756d4d48u ^ prev[15]; + mh_chacha_block(x, y); + device uint* line = cache + ((seg * MH_SEGMENT_LINES + j) * 16u); + for (uint i = 0u; i < 16u; ++i) { line[i] = y[i]; prev[i] = y[i]; } + } +} + +// M_r: per word (s ^ (RC + rk)) * MUL, then a column round and a diagonal round with the seed-drawn rotations. +inline void mh_mixer(thread uint* s, uint rk) { + s[0] = (s[0] ^ (0xbab68293u + rk)) * 0x42146205u; + s[1] = (s[1] ^ (0xcc162340u + rk)) * 0x52cbe0fbu; + s[2] = (s[2] ^ (0x6ce151ccu + rk)) * 0x7ecf4a03u; + s[3] = (s[3] ^ (0xe62b8997u + rk)) * 0x6728907fu; + s[4] = (s[4] ^ (0xc9c80297u + rk)) * 0xd81d9751u; + s[5] = (s[5] ^ (0xf74a1654u + rk)) * 0x132952c3u; + s[6] = (s[6] ^ (0x3d704af5u + rk)) * 0xf60de277u; + s[7] = (s[7] ^ (0x3cf522b7u + rk)) * 0x05358035u; + s[8] = (s[8] ^ (0x2b9cac04u + rk)) * 0xbaf6499du; + s[9] = (s[9] ^ (0xa880ac10u + rk)) * 0xe4db9667u; + s[10] = (s[10] ^ (0x13e5dd1du + rk)) * 0x3e98f45du; + s[11] = (s[11] ^ (0x6fc3e233u + rk)) * 0xd0004eddu; + s[12] = (s[12] ^ (0x2d83eeacu + rk)) * 0x2691630du; + s[13] = (s[13] ^ (0x9006e8bfu + rk)) * 0x9beb3bcfu; + s[14] = (s[14] ^ (0x2c4b5362u + rk)) * 0xab310379u; + s[15] = (s[15] ^ (0x31b49ee2u + rk)) * 0x99cfb423u; + MH_QR(s[0], s[4], s[8], s[12], 20u, 20u, 19u, 4u) MH_QR(s[1], s[5], s[9], s[13], 20u, 20u, 19u, 4u) + MH_QR(s[2], s[6], s[10], s[14], 20u, 20u, 19u, 4u) MH_QR(s[3], s[7], s[11], s[15], 20u, 20u, 19u, 4u) + MH_QR(s[0], s[5], s[10], s[15], 26u, 3u, 3u, 27u) MH_QR(s[1], s[6], s[11], s[12], 26u, 3u, 3u, 27u) + MH_QR(s[2], s[7], s[8], s[13], 26u, 3u, 3u, 27u) MH_QR(s[3], s[4], s[9], s[14], 26u, 3u, 3u, 27u) +} + +// Item t: 16 words. s = (K, t * MUL[i] + RC[i]); 8 rounds of 8 x mixer + cache line s[0] & mask; 8 x final mixer. +inline void mh_item(device const uint* cache, uint t, thread uint* s) { + s[0] = 0x3067619fu; + s[1] = 0x3c269176u; + s[2] = 0x84a03b03u; + s[3] = 0xf8c63294u; + s[4] = 0xff977c5bu; + s[5] = 0xe60def3eu; + s[6] = 0x63630141u; + s[7] = 0xb8fbcb58u; + s[8] = t * 0x42146205u + 0xbab68293u; + s[9] = t * 0x52cbe0fbu + 0xcc162340u; + s[10] = t * 0x7ecf4a03u + 0x6ce151ccu; + s[11] = t * 0x6728907fu + 0xe62b8997u; + s[12] = t * 0xd81d9751u + 0xc9c80297u; + s[13] = t * 0x132952c3u + 0xf74a1654u; + s[14] = t * 0xf60de277u + 0x3d704af5u; + s[15] = t * 0x05358035u + 0x3cf522b7u; + for (uint r = 0u; r < 8u; ++r) { + for (uint j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (r * 8u + j + 1u)); + device const uint* line = cache + ((s[0] & MH_CACHE_LINE_MASK) * 16u); + for (uint i = 0u; i < 16u; ++i) s[i] ^= line[i]; + } + for (uint j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (64u + j + 1u)); +} +// dataset[w] without the dataset: derive item w >> 4 and take word w & 15. +inline uint mh_word(device const uint* cache, uint w) { uint s[16]; mh_item(cache, w >> 4u, s); return s[w & 15u]; } + +// One thread per segment (2^16 threads). +kernel void igneum_cache_fill(device uint* cache [[buffer(0)]], uint gid [[thread_position_in_grid]]) { + mh_cache_segment(cache, gid); +} +// One thread per 64-byte item (dataset words / 16 threads). +kernel void igneum_build(device const uint* cache [[buffer(0)]], device uint* dataset [[buffer(1)]], + uint gid [[thread_position_in_grid]]) { + uint s[16]; + mh_item(cache, gid, s); + device uint* d = dataset + gid * 16u; + for (uint i = 0u; i < 16u; ++i) d[i] = s[i]; +} diff --git a/proto-cuda/packs-ca3-shadow/sh256x53/program.h b/proto-cuda/packs-ca3-shadow/sh256x53/program.h new file mode 100644 index 000000000..5e033c0a3 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x53/program.h @@ -0,0 +1,70 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Program metadata for host.cu plus the launch wrappers defined in kernel.cu. +// Also included by proto-opencl/host.c (C99), which defines IGNEUM_NO_CUDA first and reads only the macros. +#pragma once +#ifdef __cplusplus +#include +#else +#include +#endif +#ifndef IGNEUM_NO_CUDA +#include +#endif + +#define IGNEUM_SEED_STRING "igneum-genesis" +#define IGNEUM_SEED_BYTES_HEX "69676e65756d2d67656e65736973" +#define IGNEUM_GENERATOR 2 +#define IGNEUM_PROGRAM_ATTEMPT 0 +#define IGNEUM_PROGRAM_ID 0x9ae3d3853b749dd4ull +#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 add=8 shfl=8 xor=6 mad=5 mul=5 mulhi=5 sub=4 rotl=3 rotr=3 or=1" +// 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+sh256x53" +#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 53 +#define IGNEUM_SHADOW_INSTRS_PER_HASH 108544 +#define IGNEUM_SHADOW_OP_MIX "add=47 rotl=30 xor=30 shfl=29 mad=27 mul=22 sub=21 rotr=20 mulhi=18 or=12" +// 0 = closed-form dataset (ds_elem), 1 = memory-hard cache construction (MEMHARD.md, memhard.h) +#define IGNEUM_DATASET_MODE 1 + +#define IGNEUM_SEEDW_INIT { 0x67a9a7beu, 0x1a155b25u, 0xfddfb732u, 0x4b5af2e8u, 0xc55caf33u, 0xa27c13b7u, 0x06628a48u, 0x03852469u } +#define IGNEUM_KEY_INIT { 0x3067619fu, 0x3c269176u, 0x84a03b03u, 0xf8c63294u, 0xff977c5bu, 0xe60def3eu, 0x63630141u, 0xb8fbcb58u } +#define IGNEUM_CACHE_LOG2_WORDS 26 +#define IGNEUM_CACHE_SEGMENT_LOG2_LINES 6 +#define IGNEUM_CACHE_SEGMENTS 65536u +#define IGNEUM_ITEM_ROUNDS 8 +#define IGNEUM_MIXER_MULT 8 // mixer applications per round and after the last read (class v3, docs/plans/mixer-x4.md) +#define IGNEUM_MIX_ROT_INIT { 20u, 20u, 19u, 4u, 26u, 3u, 3u, 27u } +#define IGNEUM_MIX_MUL_INIT { 0x42146205u, 0x52cbe0fbu, 0x7ecf4a03u, 0x6728907fu, 0xd81d9751u, 0x132952c3u, 0xf60de277u, 0x05358035u, 0xbaf6499du, 0xe4db9667u, 0x3e98f45du, 0xd0004eddu, 0x2691630du, 0x9beb3bcfu, 0xab310379u, 0x99cfb423u } +#define IGNEUM_MIX_RC_INIT { 0xbab68293u, 0xcc162340u, 0x6ce151ccu, 0xe62b8997u, 0xc9c80297u, 0xf74a1654u, 0x3d704af5u, 0x3cf522b7u, 0x2b9cac04u, 0xa880ac10u, 0x13e5dd1du, 0x6fc3e233u, 0x2d83eeacu, 0x9006e8bfu, 0x2c4b5362u, 0x31b49ee2u } + +#ifndef IGNEUM_NO_CUDA +// Defined in kernel.cu. All launch on the default stream and return cudaGetLastError(). +cudaError_t igneum_launch_cache_fill(uint32_t* cache, uint32_t nSegments); +cudaError_t igneum_launch_build(uint32_t* ds, const uint32_t* cache, uint32_t nItems); +cudaError_t igneum_launch_hash(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, + uint32_t nonces, uint32_t blockWarps); +cudaError_t igneum_hash_info(int* numRegs, int* blocksPerSM, uint32_t blockWarps); +#endif diff --git a/proto-cuda/packs-ca3-shadow/sh256x53/program.json b/proto-cuda/packs-ca3-shadow/sh256x53/program.json new file mode 100644 index 000000000..4fb00e833 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x53/program.json @@ -0,0 +1,389 @@ +{ + "format": "igneum-program-pack-3", + "generator": 2, + "attempt": 0, + "program_id": "0x9ae3d3853b749dd4", + "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": ["0x67a9a7be", "0x1a155b25", "0xfddfb732", "0x4b5af2e8", "0xc55caf33", "0xa27c13b7", "0x06628a48", "0x03852469"], + "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+sh256x53", + "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, "add": 8, "shfl": 8, "xor": 6, "mad": 5, "mul": 5, "mulhi": 5, "sub": 4, "rotl": 3, "rotr": 3, "or": 1}, + "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": 53, "instrs_per_hash": 108544, "op_mix": {"add": 47, "rotl": 30, "xor": 30, "shfl": 29, "mad": 27, "mul": 22, "sub": 21, "rotr": 20, "mulhi": 18, "or": 12}, "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": "add", "dst": 5, "src": 2, "src2": 1, "imm": "0x92199f99", "imm2": "0x8bc12da9", "rot": 9, "bit": 18, "mask": 4}, + {"i": 1, "op": "add", "dst": 0, "src": 7, "src2": 1, "imm": "0x8d72d3ad", "imm2": "0x63079e5a", "rot": 20, "bit": 26, "mask": 4}, + {"i": 2, "op": "shfl", "dst": 6, "src": 3, "src2": 6, "imm": "0x9beaeddf", "imm2": "0x744ecb00", "rot": 10, "bit": 4, "mask": 2}, + {"i": 3, "op": "sub", "dst": 4, "src": 2, "src2": 0, "imm": "0x2a3ddc67", "imm2": "0x72c80241", "rot": 30, "bit": 1, "mask": 16}, + {"i": 4, "op": "add", "dst": 7, "src": 0, "src2": 5, "imm": "0xb21b4bab", "imm2": "0x5d4c7a60", "rot": 17, "bit": 31, "mask": 4}, + {"i": 5, "op": "rotl", "dst": 0, "src": 6, "src2": 3, "imm": "0xe69d7919", "imm2": "0xa048c61e", "rot": 11, "bit": 1, "mask": 8}, + {"i": 6, "op": "add", "dst": 0, "src": 1, "src2": 3, "imm": "0x2fe0e98b", "imm2": "0xc88e2942", "rot": 5, "bit": 16, "mask": 16}, + {"i": 7, "op": "xor", "dst": 7, "src": 1, "src2": 0, "imm": "0xc16efe98", "imm2": "0x01a638c8", "rot": 8, "bit": 17, "mask": 1}, + {"i": 8, "op": "mad", "dst": 1, "src": 6, "src2": 5, "imm": "0x76ec7b8b", "imm2": "0x25663feb", "rot": 29, "bit": 30, "mask": 2}, + {"i": 9, "op": "shfl", "dst": 6, "src": 1, "src2": 0, "imm": "0x6c8ee3cb", "imm2": "0xea93237e", "rot": 27, "bit": 1, "mask": 4}, + {"i": 10, "op": "mad", "dst": 1, "src": 2, "src2": 2, "imm": "0x6dc4ea18", "imm2": "0x6efde6f5", "rot": 3, "bit": 20, "mask": 2}, + {"i": 11, "op": "mad", "dst": 5, "src": 0, "src2": 3, "imm": "0x023613fc", "imm2": "0x18c51939", "rot": 19, "bit": 31, "mask": 1}, + {"i": 12, "op": "shfl", "dst": 2, "src": 6, "src2": 1, "imm": "0x74aec8d2", "imm2": "0x7f7ad29c", "rot": 7, "bit": 8, "mask": 4}, + {"i": 13, "op": "add", "dst": 1, "src": 5, "src2": 6, "imm": "0xbdf8f9a5", "imm2": "0xbc48c63e", "rot": 6, "bit": 25, "mask": 2}, + {"i": 14, "op": "rotl", "dst": 1, "src": 2, "src2": 6, "imm": "0x7ad8ca8b", "imm2": "0x14c712ad", "rot": 29, "bit": 25, "mask": 8}, + {"i": 15, "op": "sub", "dst": 1, "src": 4, "src2": 5, "imm": "0xd3349f69", "imm2": "0x70aac45a", "rot": 29, "bit": 9, "mask": 16}, + {"i": 16, "op": "or", "dst": 7, "src": 1, "src2": 2, "imm": "0x08168ed1", "imm2": "0x28964037", "rot": 26, "bit": 0, "mask": 2}, + {"i": 17, "op": "shfl", "dst": 2, "src": 4, "src2": 6, "imm": "0x98d85f72", "imm2": "0x3dc87042", "rot": 29, "bit": 22, "mask": 8}, + {"i": 18, "op": "xor", "dst": 7, "src": 4, "src2": 0, "imm": "0x651d4a0e", "imm2": "0x93c198bd", "rot": 26, "bit": 12, "mask": 8}, + {"i": 19, "op": "mul", "dst": 6, "src": 1, "src2": 6, "imm": "0xd38ce89d", "imm2": "0x3dfad388", "rot": 5, "bit": 28, "mask": 8}, + {"i": 20, "op": "mad", "dst": 5, "src": 6, "src2": 0, "imm": "0x59d78b36", "imm2": "0xc4db274e", "rot": 25, "bit": 24, "mask": 1}, + {"i": 21, "op": "sub", "dst": 3, "src": 1, "src2": 7, "imm": "0xf6c6a6c7", "imm2": "0x8536f4e6", "rot": 6, "bit": 12, "mask": 4}, + {"i": 22, "op": "mul", "dst": 6, "src": 0, "src2": 7, "imm": "0x599445b4", "imm2": "0x632f8c32", "rot": 19, "bit": 4, "mask": 8}, + {"i": 23, "op": "add", "dst": 2, "src": 0, "src2": 7, "imm": "0x45c37cec", "imm2": "0x96e8f127", "rot": 15, "bit": 1, "mask": 4}, + {"i": 24, "op": "sub", "dst": 6, "src": 4, "src2": 3, "imm": "0xc1c44491", "imm2": "0x92e3ce57", "rot": 20, "bit": 25, "mask": 4}, + {"i": 25, "op": "mad", "dst": 7, "src": 3, "src2": 4, "imm": "0x89bfb8d3", "imm2": "0x19b5455e", "rot": 22, "bit": 2, "mask": 16}, + {"i": 26, "op": "rotl", "dst": 3, "src": 5, "src2": 7, "imm": "0x2f47ce8d", "imm2": "0x8b458ec5", "rot": 9, "bit": 0, "mask": 4}, + {"i": 27, "op": "sub", "dst": 2, "src": 1, "src2": 2, "imm": "0x9f0dce23", "imm2": "0x3cdca814", "rot": 25, "bit": 1, "mask": 2}, + {"i": 28, "op": "mulhi", "dst": 6, "src": 0, "src2": 3, "imm": "0x61fc9eb8", "imm2": "0x23202e9d", "rot": 30, "bit": 16, "mask": 16}, + {"i": 29, "op": "shfl", "dst": 2, "src": 4, "src2": 3, "imm": "0x339dbd65", "imm2": "0xc175f639", "rot": 15, "bit": 22, "mask": 2}, + {"i": 30, "op": "shfl", "dst": 1, "src": 6, "src2": 1, "imm": "0x5bd14589", "imm2": "0xa68a2bed", "rot": 31, "bit": 31, "mask": 1}, + {"i": 31, "op": "add", "dst": 1, "src": 6, "src2": 1, "imm": "0x37985632", "imm2": "0xb1cdb2ab", "rot": 29, "bit": 1, "mask": 8}, + {"i": 32, "op": "rotr", "dst": 0, "src": 1, "src2": 6, "imm": "0x4b2058f4", "imm2": "0xf06d8ac9", "rot": 9, "bit": 15, "mask": 16}, + {"i": 33, "op": "shfl", "dst": 3, "src": 4, "src2": 4, "imm": "0x2081626c", "imm2": "0x08d1bb87", "rot": 24, "bit": 29, "mask": 2}, + {"i": 34, "op": "shfl", "dst": 0, "src": 3, "src2": 6, "imm": "0xe4fcfe03", "imm2": "0x78a46b13", "rot": 15, "bit": 29, "mask": 4}, + {"i": 35, "op": "mul", "dst": 7, "src": 0, "src2": 4, "imm": "0x33148d30", "imm2": "0x5780a3d6", "rot": 6, "bit": 11, "mask": 2}, + {"i": 36, "op": "add", "dst": 3, "src": 1, "src2": 1, "imm": "0x804e777e", "imm2": "0x856e0180", "rot": 22, "bit": 0, "mask": 16}, + {"i": 37, "op": "xor", "dst": 1, "src": 6, "src2": 0, "imm": "0xc69aa2f6", "imm2": "0xafebe3e8", "rot": 15, "bit": 9, "mask": 16}, + {"i": 38, "op": "mul", "dst": 2, "src": 7, "src2": 4, "imm": "0xeb4c4082", "imm2": "0x3f1e0da7", "rot": 25, "bit": 20, "mask": 16}, + {"i": 39, "op": "add", "dst": 6, "src": 5, "src2": 5, "imm": "0x0b06c8a7", "imm2": "0xe9bd0cc4", "rot": 6, "bit": 2, "mask": 4}, + {"i": 40, "op": "mul", "dst": 5, "src": 7, "src2": 7, "imm": "0x070af1b6", "imm2": "0x6b648e75", "rot": 10, "bit": 6, "mask": 16}, + {"i": 41, "op": "mulhi", "dst": 2, "src": 3, "src2": 2, "imm": "0x389753b2", "imm2": "0x9e657305", "rot": 30, "bit": 2, "mask": 4}, + {"i": 42, "op": "xor", "dst": 2, "src": 0, "src2": 4, "imm": "0x0960e5b9", "imm2": "0xa925a406", "rot": 4, "bit": 6, "mask": 16}, + {"i": 43, "op": "rotl", "dst": 0, "src": 1, "src2": 1, "imm": "0x8eabe09f", "imm2": "0x76ef71e2", "rot": 4, "bit": 19, "mask": 8}, + {"i": 44, "op": "mulhi", "dst": 4, "src": 3, "src2": 7, "imm": "0x6a34768a", "imm2": "0x2e427c64", "rot": 21, "bit": 5, "mask": 4}, + {"i": 45, "op": "add", "dst": 6, "src": 7, "src2": 5, "imm": "0xee822e17", "imm2": "0xcdcb63f6", "rot": 27, "bit": 12, "mask": 16}, + {"i": 46, "op": "mad", "dst": 3, "src": 2, "src2": 0, "imm": "0xc89ead43", "imm2": "0x4d3108b2", "rot": 26, "bit": 17, "mask": 1}, + {"i": 47, "op": "shfl", "dst": 4, "src": 3, "src2": 0, "imm": "0xdd62be9e", "imm2": "0xf243f6f2", "rot": 8, "bit": 4, "mask": 8}, + {"i": 48, "op": "mulhi", "dst": 6, "src": 5, "src2": 0, "imm": "0xd3f7fa72", "imm2": "0x0debc83f", "rot": 25, "bit": 5, "mask": 2}, + {"i": 49, "op": "sub", "dst": 0, "src": 2, "src2": 6, "imm": "0x7afadd15", "imm2": "0xc07fc39c", "rot": 30, "bit": 29, "mask": 8}, + {"i": 50, "op": "sub", "dst": 3, "src": 5, "src2": 3, "imm": "0x179b78ec", "imm2": "0xaeccde37", "rot": 30, "bit": 17, "mask": 1}, + {"i": 51, "op": "rotr", "dst": 1, "src": 4, "src2": 1, "imm": "0xa4bfcea6", "imm2": "0xbf63bb2f", "rot": 2, "bit": 21, "mask": 2}, + {"i": 52, "op": "mad", "dst": 6, "src": 7, "src2": 7, "imm": "0xabf5ed10", "imm2": "0x8a285f51", "rot": 3, "bit": 23, "mask": 2}, + {"i": 53, "op": "xor", "dst": 5, "src": 3, "src2": 5, "imm": "0x88b416eb", "imm2": "0x36271d87", "rot": 19, "bit": 10, "mask": 2}, + {"i": 54, "op": "sub", "dst": 1, "src": 0, "src2": 1, "imm": "0xa3417dd3", "imm2": "0xcd98f620", "rot": 28, "bit": 2, "mask": 1}, + {"i": 55, "op": "sub", "dst": 5, "src": 6, "src2": 2, "imm": "0x45996c6f", "imm2": "0xe3d41087", "rot": 4, "bit": 31, "mask": 1}, + {"i": 56, "op": "add", "dst": 3, "src": 2, "src2": 0, "imm": "0x3dfad1b6", "imm2": "0xd4758987", "rot": 27, "bit": 10, "mask": 2}, + {"i": 57, "op": "add", "dst": 4, "src": 1, "src2": 3, "imm": "0xfca75bc2", "imm2": "0x0602d6be", "rot": 19, "bit": 0, "mask": 16}, + {"i": 58, "op": "mulhi", "dst": 5, "src": 6, "src2": 5, "imm": "0x83250a7b", "imm2": "0x2f93d53b", "rot": 25, "bit": 7, "mask": 2}, + {"i": 59, "op": "shfl", "dst": 2, "src": 1, "src2": 0, "imm": "0x13f4a089", "imm2": "0x145ea125", "rot": 12, "bit": 3, "mask": 2}, + {"i": 60, "op": "rotl", "dst": 2, "src": 5, "src2": 6, "imm": "0xad3170e3", "imm2": "0x15db04d1", "rot": 9, "bit": 13, "mask": 2}, + {"i": 61, "op": "or", "dst": 4, "src": 6, "src2": 2, "imm": "0x4b6305b2", "imm2": "0x6e7b2e9c", "rot": 27, "bit": 16, "mask": 4}, + {"i": 62, "op": "rotr", "dst": 6, "src": 4, "src2": 6, "imm": "0xfcd4b1c9", "imm2": "0xaf5c733b", "rot": 6, "bit": 21, "mask": 16}, + {"i": 63, "op": "mul", "dst": 2, "src": 4, "src2": 6, "imm": "0x95cebb3e", "imm2": "0xbba9cdfc", "rot": 19, "bit": 23, "mask": 1}, + {"i": 64, "op": "xor", "dst": 0, "src": 5, "src2": 7, "imm": "0x5f7579ff", "imm2": "0xb104e01a", "rot": 25, "bit": 12, "mask": 8}, + {"i": 65, "op": "xor", "dst": 2, "src": 7, "src2": 3, "imm": "0x749c7611", "imm2": "0xf17df3bb", "rot": 27, "bit": 26, "mask": 2}, + {"i": 66, "op": "add", "dst": 2, "src": 1, "src2": 6, "imm": "0xd71c02ff", "imm2": "0x8596687a", "rot": 4, "bit": 6, "mask": 2}, + {"i": 67, "op": "rotl", "dst": 1, "src": 3, "src2": 2, "imm": "0xd2864071", "imm2": "0xaa644ef3", "rot": 21, "bit": 5, "mask": 1}, + {"i": 68, "op": "mul", "dst": 3, "src": 2, "src2": 1, "imm": "0xd0689a5f", "imm2": "0xa3a1f063", "rot": 13, "bit": 28, "mask": 2}, + {"i": 69, "op": "shfl", "dst": 7, "src": 5, "src2": 6, "imm": "0xd01476eb", "imm2": "0x76abb5c2", "rot": 7, "bit": 30, "mask": 2}, + {"i": 70, "op": "mul", "dst": 3, "src": 2, "src2": 5, "imm": "0x59a75c10", "imm2": "0x1e1fbb72", "rot": 20, "bit": 16, "mask": 1}, + {"i": 71, "op": "mad", "dst": 0, "src": 2, "src2": 5, "imm": "0x39cca1df", "imm2": "0x22c057ac", "rot": 5, "bit": 23, "mask": 16}, + {"i": 72, "op": "add", "dst": 6, "src": 7, "src2": 3, "imm": "0x3c6fe15d", "imm2": "0x08ac5733", "rot": 14, "bit": 0, "mask": 4}, + {"i": 73, "op": "shfl", "dst": 3, "src": 2, "src2": 6, "imm": "0x2098627d", "imm2": "0xf4fecc81", "rot": 20, "bit": 30, "mask": 8}, + {"i": 74, "op": "mul", "dst": 3, "src": 6, "src2": 5, "imm": "0xf82e9e23", "imm2": "0x3ad62132", "rot": 10, "bit": 14, "mask": 16}, + {"i": 75, "op": "xor", "dst": 6, "src": 7, "src2": 4, "imm": "0x70548a91", "imm2": "0xa9715d2e", "rot": 6, "bit": 24, "mask": 1}, + {"i": 76, "op": "or", "dst": 3, "src": 0, "src2": 7, "imm": "0xa164325f", "imm2": "0xf300838b", "rot": 23, "bit": 23, "mask": 16}, + {"i": 77, "op": "add", "dst": 2, "src": 4, "src2": 6, "imm": "0x295d5fae", "imm2": "0xc100b495", "rot": 7, "bit": 1, "mask": 2}, + {"i": 78, "op": "mulhi", "dst": 3, "src": 7, "src2": 4, "imm": "0xb62cca87", "imm2": "0x2ebde415", "rot": 14, "bit": 7, "mask": 2}, + {"i": 79, "op": "or", "dst": 4, "src": 1, "src2": 7, "imm": "0xfcbc482d", "imm2": "0x8876e6cd", "rot": 29, "bit": 5, "mask": 2}, + {"i": 80, "op": "rotr", "dst": 4, "src": 3, "src2": 0, "imm": "0x6d64013b", "imm2": "0x675f4a8d", "rot": 26, "bit": 18, "mask": 8}, + {"i": 81, "op": "add", "dst": 4, "src": 3, "src2": 3, "imm": "0x274a9221", "imm2": "0x5cc59530", "rot": 15, "bit": 15, "mask": 2}, + {"i": 82, "op": "add", "dst": 7, "src": 3, "src2": 0, "imm": "0xc8651f8e", "imm2": "0x141479ec", "rot": 18, "bit": 5, "mask": 1}, + {"i": 83, "op": "rotr", "dst": 3, "src": 6, "src2": 0, "imm": "0xcc8a7766", "imm2": "0xc2eb5161", "rot": 4, "bit": 29, "mask": 2}, + {"i": 84, "op": "mad", "dst": 2, "src": 4, "src2": 7, "imm": "0xbc507d51", "imm2": "0x0b1196fd", "rot": 9, "bit": 7, "mask": 8}, + {"i": 85, "op": "shfl", "dst": 2, "src": 5, "src2": 5, "imm": "0x5a156c90", "imm2": "0xa6b3fbfa", "rot": 11, "bit": 2, "mask": 16}, + {"i": 86, "op": "xor", "dst": 3, "src": 2, "src2": 1, "imm": "0x8b042658", "imm2": "0xacf37a8f", "rot": 12, "bit": 23, "mask": 16}, + {"i": 87, "op": "shfl", "dst": 5, "src": 7, "src2": 2, "imm": "0x1a214238", "imm2": "0x017fdf5d", "rot": 29, "bit": 14, "mask": 2}, + {"i": 88, "op": "xor", "dst": 0, "src": 4, "src2": 2, "imm": "0xd523e612", "imm2": "0x2158c2ed", "rot": 30, "bit": 14, "mask": 4}, + {"i": 89, "op": "add", "dst": 3, "src": 2, "src2": 7, "imm": "0x53f915c2", "imm2": "0x883c0c92", "rot": 9, "bit": 18, "mask": 8}, + {"i": 90, "op": "rotr", "dst": 7, "src": 5, "src2": 5, "imm": "0xbd633b21", "imm2": "0xcf8c356c", "rot": 25, "bit": 31, "mask": 4}, + {"i": 91, "op": "add", "dst": 3, "src": 1, "src2": 1, "imm": "0xe2be00a5", "imm2": "0x3cc5bd20", "rot": 10, "bit": 31, "mask": 1}, + {"i": 92, "op": "shfl", "dst": 7, "src": 2, "src2": 4, "imm": "0x3d3da600", "imm2": "0x1f22df89", "rot": 4, "bit": 24, "mask": 1}, + {"i": 93, "op": "rotr", "dst": 6, "src": 2, "src2": 7, "imm": "0xb0f57471", "imm2": "0x8f2a7eca", "rot": 16, "bit": 25, "mask": 1}, + {"i": 94, "op": "rotl", "dst": 7, "src": 0, "src2": 4, "imm": "0x00a21815", "imm2": "0xeb4d7218", "rot": 14, "bit": 18, "mask": 16}, + {"i": 95, "op": "mad", "dst": 4, "src": 5, "src2": 5, "imm": "0xc4c3828e", "imm2": "0xfb7bba17", "rot": 16, "bit": 10, "mask": 16}, + {"i": 96, "op": "mad", "dst": 2, "src": 4, "src2": 5, "imm": "0xfc5bbc75", "imm2": "0xfc43468f", "rot": 31, "bit": 20, "mask": 16}, + {"i": 97, "op": "xor", "dst": 1, "src": 0, "src2": 2, "imm": "0x1fe9c249", "imm2": "0x164bb16b", "rot": 15, "bit": 9, "mask": 4}, + {"i": 98, "op": "mul", "dst": 5, "src": 4, "src2": 1, "imm": "0xeda725fa", "imm2": "0x66f7e9a2", "rot": 21, "bit": 6, "mask": 2}, + {"i": 99, "op": "sub", "dst": 2, "src": 0, "src2": 7, "imm": "0x8fb29f7d", "imm2": "0xf530eda1", "rot": 27, "bit": 30, "mask": 4}, + {"i": 100, "op": "rotl", "dst": 7, "src": 2, "src2": 0, "imm": "0x9f4de742", "imm2": "0x9b5ff871", "rot": 30, "bit": 21, "mask": 16}, + {"i": 101, "op": "add", "dst": 5, "src": 6, "src2": 7, "imm": "0x423fd9c9", "imm2": "0xbfd646cb", "rot": 17, "bit": 17, "mask": 2}, + {"i": 102, "op": "add", "dst": 7, "src": 6, "src2": 3, "imm": "0x8d3c011d", "imm2": "0x19b74a43", "rot": 12, "bit": 11, "mask": 4}, + {"i": 103, "op": "rotl", "dst": 5, "src": 6, "src2": 0, "imm": "0xcfc70303", "imm2": "0xf2b3e8ef", "rot": 6, "bit": 24, "mask": 1}, + {"i": 104, "op": "mul", "dst": 0, "src": 4, "src2": 5, "imm": "0x650475eb", "imm2": "0x11dcbd94", "rot": 15, "bit": 10, "mask": 1}, + {"i": 105, "op": "or", "dst": 0, "src": 5, "src2": 3, "imm": "0xaacaa145", "imm2": "0x9139d3fe", "rot": 4, "bit": 18, "mask": 2}, + {"i": 106, "op": "add", "dst": 0, "src": 1, "src2": 7, "imm": "0x8ce14721", "imm2": "0x7dcb7e18", "rot": 24, "bit": 15, "mask": 8}, + {"i": 107, "op": "rotl", "dst": 0, "src": 3, "src2": 3, "imm": "0xb36d6d98", "imm2": "0x2c3390c8", "rot": 15, "bit": 10, "mask": 16}, + {"i": 108, "op": "sub", "dst": 4, "src": 2, "src2": 5, "imm": "0xf6bbdaef", "imm2": "0x9db6f65e", "rot": 25, "bit": 10, "mask": 1}, + {"i": 109, "op": "mulhi", "dst": 2, "src": 0, "src2": 0, "imm": "0xb1721fd6", "imm2": "0xd96d52c9", "rot": 1, "bit": 27, "mask": 8}, + {"i": 110, "op": "mulhi", "dst": 1, "src": 0, "src2": 5, "imm": "0xfb4ca37f", "imm2": "0xb6ec7dbe", "rot": 27, "bit": 12, "mask": 8}, + {"i": 111, "op": "add", "dst": 0, "src": 2, "src2": 0, "imm": "0x2d9fc6b9", "imm2": "0x3c179ad8", "rot": 9, "bit": 28, "mask": 16}, + {"i": 112, "op": "mulhi", "dst": 2, "src": 0, "src2": 6, "imm": "0x71a9f6bd", "imm2": "0xd3417bf5", "rot": 2, "bit": 14, "mask": 8}, + {"i": 113, "op": "sub", "dst": 6, "src": 3, "src2": 5, "imm": "0xa3d19400", "imm2": "0x15df7330", "rot": 5, "bit": 2, "mask": 8}, + {"i": 114, "op": "mad", "dst": 7, "src": 6, "src2": 3, "imm": "0x1400d92e", "imm2": "0xfa4a158e", "rot": 16, "bit": 9, "mask": 1}, + {"i": 115, "op": "rotr", "dst": 5, "src": 1, "src2": 3, "imm": "0xd01684c3", "imm2": "0x6367febb", "rot": 23, "bit": 19, "mask": 2}, + {"i": 116, "op": "rotr", "dst": 6, "src": 4, "src2": 2, "imm": "0x8cd9eb96", "imm2": "0x98f33b24", "rot": 25, "bit": 1, "mask": 2}, + {"i": 117, "op": "add", "dst": 2, "src": 1, "src2": 7, "imm": "0x502138e2", "imm2": "0x47359729", "rot": 5, "bit": 22, "mask": 4}, + {"i": 118, "op": "mad", "dst": 3, "src": 2, "src2": 0, "imm": "0xd94a35c7", "imm2": "0xb83416c3", "rot": 11, "bit": 3, "mask": 4}, + {"i": 119, "op": "mul", "dst": 1, "src": 3, "src2": 6, "imm": "0x09b30cf7", "imm2": "0xef3b98e7", "rot": 17, "bit": 23, "mask": 8}, + {"i": 120, "op": "mad", "dst": 2, "src": 0, "src2": 4, "imm": "0x56416fe0", "imm2": "0x5e1dc8f3", "rot": 17, "bit": 14, "mask": 2}, + {"i": 121, "op": "mul", "dst": 0, "src": 3, "src2": 2, "imm": "0x2892697c", "imm2": "0x9cb3b14e", "rot": 29, "bit": 25, "mask": 2}, + {"i": 122, "op": "mulhi", "dst": 2, "src": 0, "src2": 3, "imm": "0xc33089a1", "imm2": "0xd6c5b530", "rot": 27, "bit": 13, "mask": 8}, + {"i": 123, "op": "mul", "dst": 5, "src": 6, "src2": 4, "imm": "0xdfe04e4a", "imm2": "0x3cc40160", "rot": 3, "bit": 14, "mask": 2}, + {"i": 124, "op": "mad", "dst": 4, "src": 2, "src2": 4, "imm": "0xb33dc1b7", "imm2": "0xab97743a", "rot": 7, "bit": 21, "mask": 4}, + {"i": 125, "op": "shfl", "dst": 4, "src": 2, "src2": 0, "imm": "0xfd469909", "imm2": "0xfc85dc55", "rot": 28, "bit": 24, "mask": 2}, + {"i": 126, "op": "xor", "dst": 2, "src": 0, "src2": 5, "imm": "0xa0094578", "imm2": "0xf1bee474", "rot": 31, "bit": 7, "mask": 2}, + {"i": 127, "op": "rotl", "dst": 1, "src": 7, "src2": 2, "imm": "0xb7ae00a0", "imm2": "0x86cce297", "rot": 7, "bit": 31, "mask": 8}, + {"i": 128, "op": "shfl", "dst": 7, "src": 2, "src2": 7, "imm": "0x019d1940", "imm2": "0x3fe9e7dd", "rot": 14, "bit": 4, "mask": 4}, + {"i": 129, "op": "rotl", "dst": 6, "src": 7, "src2": 7, "imm": "0x40a74cc4", "imm2": "0x09eb4adf", "rot": 17, "bit": 30, "mask": 1}, + {"i": 130, "op": "add", "dst": 2, "src": 5, "src2": 5, "imm": "0x33dff776", "imm2": "0x6c57e4e7", "rot": 27, "bit": 15, "mask": 4}, + {"i": 131, "op": "or", "dst": 0, "src": 3, "src2": 1, "imm": "0xe0c53bb9", "imm2": "0x124404f6", "rot": 4, "bit": 21, "mask": 16}, + {"i": 132, "op": "rotr", "dst": 5, "src": 0, "src2": 1, "imm": "0xe4353fce", "imm2": "0x559d0118", "rot": 2, "bit": 29, "mask": 4}, + {"i": 133, "op": "add", "dst": 2, "src": 3, "src2": 6, "imm": "0x5db25b34", "imm2": "0xe8212c0c", "rot": 21, "bit": 30, "mask": 1}, + {"i": 134, "op": "xor", "dst": 4, "src": 3, "src2": 6, "imm": "0x7366e50e", "imm2": "0x7cc1ffbd", "rot": 19, "bit": 18, "mask": 16}, + {"i": 135, "op": "xor", "dst": 6, "src": 1, "src2": 2, "imm": "0xa36decb7", "imm2": "0x79291734", "rot": 26, "bit": 0, "mask": 8}, + {"i": 136, "op": "sub", "dst": 1, "src": 7, "src2": 0, "imm": "0x225b03e4", "imm2": "0x7183e193", "rot": 16, "bit": 6, "mask": 2}, + {"i": 137, "op": "mad", "dst": 2, "src": 6, "src2": 2, "imm": "0x6f620d51", "imm2": "0x4e814e19", "rot": 6, "bit": 6, "mask": 2}, + {"i": 138, "op": "mulhi", "dst": 0, "src": 5, "src2": 6, "imm": "0x919d6bf3", "imm2": "0xc6240638", "rot": 17, "bit": 11, "mask": 16}, + {"i": 139, "op": "add", "dst": 2, "src": 7, "src2": 7, "imm": "0x218d4090", "imm2": "0xd44ff710", "rot": 1, "bit": 10, "mask": 16}, + {"i": 140, "op": "rotr", "dst": 1, "src": 4, "src2": 4, "imm": "0x4cbfa722", "imm2": "0x114e9564", "rot": 28, "bit": 9, "mask": 16}, + {"i": 141, "op": "shfl", "dst": 3, "src": 6, "src2": 2, "imm": "0xf702c6a1", "imm2": "0xf8f3c5d9", "rot": 7, "bit": 24, "mask": 1}, + {"i": 142, "op": "mad", "dst": 7, "src": 6, "src2": 2, "imm": "0xa2d285be", "imm2": "0x9cc94532", "rot": 15, "bit": 20, "mask": 8}, + {"i": 143, "op": "mul", "dst": 2, "src": 3, "src2": 7, "imm": "0x08b7ed80", "imm2": "0xa8abced4", "rot": 18, "bit": 10, "mask": 4}, + {"i": 144, "op": "add", "dst": 7, "src": 4, "src2": 2, "imm": "0xf4b1a8de", "imm2": "0xb98942fa", "rot": 18, "bit": 29, "mask": 8}, + {"i": 145, "op": "rotl", "dst": 7, "src": 6, "src2": 1, "imm": "0x64b6ba2d", "imm2": "0xf9e86793", "rot": 15, "bit": 24, "mask": 8}, + {"i": 146, "op": "xor", "dst": 7, "src": 5, "src2": 3, "imm": "0x41c42b5f", "imm2": "0x7c7e0e39", "rot": 8, "bit": 23, "mask": 2}, + {"i": 147, "op": "mad", "dst": 4, "src": 7, "src2": 4, "imm": "0x3caa807a", "imm2": "0x553a0cec", "rot": 11, "bit": 22, "mask": 8}, + {"i": 148, "op": "rotr", "dst": 6, "src": 5, "src2": 3, "imm": "0x3cb1289a", "imm2": "0x6b36f78a", "rot": 1, "bit": 9, "mask": 16}, + {"i": 149, "op": "mad", "dst": 1, "src": 2, "src2": 4, "imm": "0x95310ea8", "imm2": "0xc533aa6a", "rot": 16, "bit": 17, "mask": 1}, + {"i": 150, "op": "add", "dst": 1, "src": 7, "src2": 7, "imm": "0x2bef10f2", "imm2": "0x0d48ba42", "rot": 8, "bit": 17, "mask": 4}, + {"i": 151, "op": "xor", "dst": 5, "src": 4, "src2": 7, "imm": "0xda997ab2", "imm2": "0xae31d69e", "rot": 11, "bit": 31, "mask": 2}, + {"i": 152, "op": "add", "dst": 7, "src": 0, "src2": 6, "imm": "0xdc5cc080", "imm2": "0xc98dea9c", "rot": 16, "bit": 30, "mask": 2}, + {"i": 153, "op": "mul", "dst": 4, "src": 6, "src2": 7, "imm": "0xbfbf5f6c", "imm2": "0x61f611bb", "rot": 14, "bit": 22, "mask": 2}, + {"i": 154, "op": "mul", "dst": 0, "src": 2, "src2": 3, "imm": "0xa78008c3", "imm2": "0xbad5eeb1", "rot": 10, "bit": 28, "mask": 8}, + {"i": 155, "op": "xor", "dst": 6, "src": 5, "src2": 4, "imm": "0x1a73b866", "imm2": "0x1f5a62c9", "rot": 9, "bit": 27, "mask": 8}, + {"i": 156, "op": "rotr", "dst": 4, "src": 2, "src2": 0, "imm": "0x9c88500c", "imm2": "0xe25dccf9", "rot": 11, "bit": 2, "mask": 16}, + {"i": 157, "op": "rotl", "dst": 1, "src": 4, "src2": 4, "imm": "0xb05e7669", "imm2": "0x9db704b1", "rot": 11, "bit": 28, "mask": 4}, + {"i": 158, "op": "add", "dst": 5, "src": 0, "src2": 6, "imm": "0x18197438", "imm2": "0x6c752dcb", "rot": 11, "bit": 11, "mask": 2}, + {"i": 159, "op": "mad", "dst": 4, "src": 1, "src2": 5, "imm": "0x4796a65e", "imm2": "0x00e08c7a", "rot": 8, "bit": 19, "mask": 4}, + {"i": 160, "op": "rotl", "dst": 4, "src": 7, "src2": 5, "imm": "0x08a03052", "imm2": "0x0204f0ba", "rot": 26, "bit": 5, "mask": 2}, + {"i": 161, "op": "mad", "dst": 3, "src": 0, "src2": 7, "imm": "0xa0603b0e", "imm2": "0x7eee83d5", "rot": 28, "bit": 22, "mask": 16}, + {"i": 162, "op": "rotr", "dst": 3, "src": 1, "src2": 6, "imm": "0x78a3c69d", "imm2": "0x684693a0", "rot": 21, "bit": 23, "mask": 4}, + {"i": 163, "op": "add", "dst": 4, "src": 0, "src2": 7, "imm": "0xf1c46574", "imm2": "0x8e481727", "rot": 9, "bit": 3, "mask": 4}, + {"i": 164, "op": "mulhi", "dst": 0, "src": 4, "src2": 3, "imm": "0x04644afa", "imm2": "0x64bda2b5", "rot": 26, "bit": 16, "mask": 16}, + {"i": 165, "op": "add", "dst": 2, "src": 6, "src2": 2, "imm": "0xac578137", "imm2": "0x550ab406", "rot": 13, "bit": 20, "mask": 16}, + {"i": 166, "op": "rotl", "dst": 0, "src": 4, "src2": 5, "imm": "0x7f564760", "imm2": "0xb9a8b4f8", "rot": 13, "bit": 29, "mask": 1}, + {"i": 167, "op": "add", "dst": 3, "src": 1, "src2": 0, "imm": "0xa33e6706", "imm2": "0xaebb5966", "rot": 12, "bit": 14, "mask": 16}, + {"i": 168, "op": "or", "dst": 3, "src": 5, "src2": 3, "imm": "0x65b2f3eb", "imm2": "0xb1d00d20", "rot": 12, "bit": 2, "mask": 8}, + {"i": 169, "op": "rotr", "dst": 6, "src": 2, "src2": 3, "imm": "0x7f21faf5", "imm2": "0xbbf0d3f9", "rot": 17, "bit": 13, "mask": 8}, + {"i": 170, "op": "xor", "dst": 4, "src": 6, "src2": 2, "imm": "0x162c7140", "imm2": "0x90d404ad", "rot": 26, "bit": 1, "mask": 4}, + {"i": 171, "op": "sub", "dst": 6, "src": 1, "src2": 7, "imm": "0x6ef9c76e", "imm2": "0xfb7ba272", "rot": 31, "bit": 25, "mask": 1}, + {"i": 172, "op": "rotl", "dst": 7, "src": 5, "src2": 4, "imm": "0xde04eb3b", "imm2": "0xd56caa00", "rot": 22, "bit": 21, "mask": 4}, + {"i": 173, "op": "rotl", "dst": 5, "src": 3, "src2": 5, "imm": "0xa9eac934", "imm2": "0x2c338e51", "rot": 15, "bit": 22, "mask": 2}, + {"i": 174, "op": "shfl", "dst": 7, "src": 0, "src2": 3, "imm": "0x700be4e3", "imm2": "0x4bcfc732", "rot": 19, "bit": 6, "mask": 8}, + {"i": 175, "op": "xor", "dst": 0, "src": 5, "src2": 1, "imm": "0x02ccdba9", "imm2": "0xd0915be0", "rot": 15, "bit": 2, "mask": 16}, + {"i": 176, "op": "rotl", "dst": 7, "src": 4, "src2": 1, "imm": "0x489c8165", "imm2": "0xf24b5a4f", "rot": 6, "bit": 22, "mask": 1}, + {"i": 177, "op": "sub", "dst": 7, "src": 0, "src2": 6, "imm": "0x23ad9693", "imm2": "0x9a8c2f7b", "rot": 24, "bit": 2, "mask": 2}, + {"i": 178, "op": "rotl", "dst": 3, "src": 0, "src2": 6, "imm": "0xafa72a42", "imm2": "0x371d74ee", "rot": 30, "bit": 16, "mask": 1}, + {"i": 179, "op": "mad", "dst": 7, "src": 6, "src2": 1, "imm": "0x18a2a3f3", "imm2": "0xb811b951", "rot": 2, "bit": 9, "mask": 2}, + {"i": 180, "op": "rotl", "dst": 6, "src": 4, "src2": 1, "imm": "0xe6c69c0e", "imm2": "0xfc46a951", "rot": 9, "bit": 31, "mask": 4}, + {"i": 181, "op": "xor", "dst": 2, "src": 4, "src2": 7, "imm": "0xbd1b89e4", "imm2": "0xdf4bce5c", "rot": 15, "bit": 19, "mask": 4}, + {"i": 182, "op": "xor", "dst": 2, "src": 7, "src2": 5, "imm": "0x3dd12aed", "imm2": "0xd0756a69", "rot": 13, "bit": 16, "mask": 4}, + {"i": 183, "op": "xor", "dst": 7, "src": 2, "src2": 3, "imm": "0x77ce69d6", "imm2": "0x2b39bdf2", "rot": 8, "bit": 22, "mask": 16}, + {"i": 184, "op": "add", "dst": 1, "src": 2, "src2": 4, "imm": "0xd94d55ac", "imm2": "0x5bb7550f", "rot": 31, "bit": 21, "mask": 1}, + {"i": 185, "op": "or", "dst": 3, "src": 5, "src2": 6, "imm": "0x7b1ce846", "imm2": "0xcc3b8509", "rot": 28, "bit": 9, "mask": 4}, + {"i": 186, "op": "mulhi", "dst": 6, "src": 3, "src2": 0, "imm": "0xa5e24690", "imm2": "0x2200ba81", "rot": 26, "bit": 10, "mask": 16}, + {"i": 187, "op": "or", "dst": 4, "src": 0, "src2": 3, "imm": "0xf6efe759", "imm2": "0xae1f7118", "rot": 19, "bit": 20, "mask": 4}, + {"i": 188, "op": "shfl", "dst": 7, "src": 1, "src2": 5, "imm": "0xdb318b45", "imm2": "0xcec459c9", "rot": 20, "bit": 11, "mask": 2}, + {"i": 189, "op": "add", "dst": 6, "src": 5, "src2": 1, "imm": "0x89e747fe", "imm2": "0x2a354e2d", "rot": 22, "bit": 6, "mask": 1}, + {"i": 190, "op": "xor", "dst": 1, "src": 4, "src2": 2, "imm": "0xc379e617", "imm2": "0x75e9d63b", "rot": 23, "bit": 3, "mask": 2}, + {"i": 191, "op": "mulhi", "dst": 7, "src": 4, "src2": 3, "imm": "0x5a710287", "imm2": "0x7fe4ead6", "rot": 10, "bit": 25, "mask": 4}, + {"i": 192, "op": "rotl", "dst": 2, "src": 1, "src2": 2, "imm": "0x4d5e59a3", "imm2": "0x1e4fef28", "rot": 26, "bit": 0, "mask": 1}, + {"i": 193, "op": "rotl", "dst": 5, "src": 3, "src2": 7, "imm": "0x7444c47d", "imm2": "0xdad5f8be", "rot": 8, "bit": 30, "mask": 2}, + {"i": 194, "op": "shfl", "dst": 4, "src": 5, "src2": 7, "imm": "0x6a225bbb", "imm2": "0xd6532cd7", "rot": 13, "bit": 17, "mask": 16}, + {"i": 195, "op": "xor", "dst": 4, "src": 5, "src2": 3, "imm": "0x68344b9a", "imm2": "0xcb46a38b", "rot": 1, "bit": 27, "mask": 16}, + {"i": 196, "op": "mul", "dst": 1, "src": 3, "src2": 4, "imm": "0xbebf7359", "imm2": "0x3f0890ba", "rot": 18, "bit": 12, "mask": 4}, + {"i": 197, "op": "add", "dst": 5, "src": 2, "src2": 3, "imm": "0xea03e8e7", "imm2": "0x10cfdc71", "rot": 31, "bit": 7, "mask": 8}, + {"i": 198, "op": "add", "dst": 7, "src": 5, "src2": 1, "imm": "0xa7ee0102", "imm2": "0x66e148d3", "rot": 12, "bit": 15, "mask": 1}, + {"i": 199, "op": "sub", "dst": 5, "src": 2, "src2": 4, "imm": "0xc215584e", "imm2": "0x55fce30f", "rot": 30, "bit": 9, "mask": 2}, + {"i": 200, "op": "shfl", "dst": 5, "src": 1, "src2": 1, "imm": "0x308f8358", "imm2": "0x489f1f93", "rot": 13, "bit": 13, "mask": 2}, + {"i": 201, "op": "shfl", "dst": 7, "src": 1, "src2": 5, "imm": "0x713f1957", "imm2": "0x2239f757", "rot": 15, "bit": 7, "mask": 8}, + {"i": 202, "op": "rotr", "dst": 4, "src": 5, "src2": 1, "imm": "0xb037b6e7", "imm2": "0x49a8b528", "rot": 27, "bit": 13, "mask": 16}, + {"i": 203, "op": "xor", "dst": 7, "src": 5, "src2": 1, "imm": "0x56110241", "imm2": "0xefc8386d", "rot": 22, "bit": 20, "mask": 1}, + {"i": 204, "op": "xor", "dst": 7, "src": 0, "src2": 0, "imm": "0x0827fcc7", "imm2": "0xf4f5dd07", "rot": 13, "bit": 7, "mask": 2}, + {"i": 205, "op": "add", "dst": 6, "src": 2, "src2": 0, "imm": "0x8379a4de", "imm2": "0x8558b619", "rot": 26, "bit": 10, "mask": 1}, + {"i": 206, "op": "rotl", "dst": 4, "src": 3, "src2": 3, "imm": "0x091ceef0", "imm2": "0x69b0f72f", "rot": 13, "bit": 7, "mask": 1}, + {"i": 207, "op": "mulhi", "dst": 1, "src": 3, "src2": 4, "imm": "0x758edac1", "imm2": "0x98dd2f21", "rot": 15, "bit": 9, "mask": 1}, + {"i": 208, "op": "mad", "dst": 1, "src": 4, "src2": 4, "imm": "0x78871a1a", "imm2": "0x5e14e1c8", "rot": 19, "bit": 6, "mask": 2}, + {"i": 209, "op": "shfl", "dst": 2, "src": 0, "src2": 2, "imm": "0xf7e0b9aa", "imm2": "0xaecfd347", "rot": 21, "bit": 9, "mask": 4}, + {"i": 210, "op": "add", "dst": 7, "src": 0, "src2": 7, "imm": "0xaa8cb14e", "imm2": "0xf4049c4c", "rot": 24, "bit": 11, "mask": 8}, + {"i": 211, "op": "shfl", "dst": 7, "src": 1, "src2": 6, "imm": "0xc230d919", "imm2": "0xf76d08fb", "rot": 21, "bit": 13, "mask": 16}, + {"i": 212, "op": "xor", "dst": 1, "src": 0, "src2": 2, "imm": "0x31a5af90", "imm2": "0x7eef58ee", "rot": 9, "bit": 12, "mask": 4}, + {"i": 213, "op": "rotl", "dst": 7, "src": 1, "src2": 6, "imm": "0x0db26138", "imm2": "0x8e3c31f9", "rot": 3, "bit": 26, "mask": 2}, + {"i": 214, "op": "rotr", "dst": 4, "src": 7, "src2": 3, "imm": "0x29558100", "imm2": "0xe4b13ad6", "rot": 29, "bit": 24, "mask": 8}, + {"i": 215, "op": "shfl", "dst": 3, "src": 2, "src2": 6, "imm": "0x1b48c3d0", "imm2": "0x5c674ff6", "rot": 5, "bit": 9, "mask": 16}, + {"i": 216, "op": "or", "dst": 5, "src": 1, "src2": 0, "imm": "0xef768632", "imm2": "0x6de9d10d", "rot": 10, "bit": 4, "mask": 4}, + {"i": 217, "op": "sub", "dst": 1, "src": 2, "src2": 5, "imm": "0x88ca7f5a", "imm2": "0x24718a36", "rot": 18, "bit": 31, "mask": 1}, + {"i": 218, "op": "sub", "dst": 6, "src": 5, "src2": 0, "imm": "0xc4a06728", "imm2": "0xdc2a4fd8", "rot": 9, "bit": 9, "mask": 2}, + {"i": 219, "op": "rotl", "dst": 6, "src": 5, "src2": 7, "imm": "0xb7489e47", "imm2": "0xf13795c5", "rot": 4, "bit": 3, "mask": 8}, + {"i": 220, "op": "mulhi", "dst": 2, "src": 0, "src2": 2, "imm": "0x873cd31b", "imm2": "0x3dfbc55d", "rot": 12, "bit": 23, "mask": 8}, + {"i": 221, "op": "or", "dst": 2, "src": 0, "src2": 3, "imm": "0xdc21f099", "imm2": "0xee06f01e", "rot": 2, "bit": 17, "mask": 8}, + {"i": 222, "op": "shfl", "dst": 5, "src": 2, "src2": 6, "imm": "0x36def499", "imm2": "0xa2849d59", "rot": 23, "bit": 4, "mask": 8}, + {"i": 223, "op": "mulhi", "dst": 5, "src": 6, "src2": 7, "imm": "0xfb95fbca", "imm2": "0xc1aac427", "rot": 14, "bit": 11, "mask": 2}, + {"i": 224, "op": "sub", "dst": 0, "src": 6, "src2": 7, "imm": "0x3d9d29c4", "imm2": "0x34d0dcc0", "rot": 17, "bit": 6, "mask": 4}, + {"i": 225, "op": "rotl", "dst": 7, "src": 0, "src2": 5, "imm": "0x93b01b8e", "imm2": "0xfe1d75ac", "rot": 23, "bit": 15, "mask": 1}, + {"i": 226, "op": "or", "dst": 4, "src": 2, "src2": 4, "imm": "0xfed76e8e", "imm2": "0x1c24ecd8", "rot": 2, "bit": 6, "mask": 16}, + {"i": 227, "op": "mul", "dst": 2, "src": 4, "src2": 1, "imm": "0x5795f5b0", "imm2": "0x0566ea2a", "rot": 6, "bit": 28, "mask": 4}, + {"i": 228, "op": "rotl", "dst": 3, "src": 0, "src2": 2, "imm": "0x8c8486de", "imm2": "0xd066aa8f", "rot": 12, "bit": 20, "mask": 1}, + {"i": 229, "op": "rotr", "dst": 0, "src": 4, "src2": 0, "imm": "0x23a3e882", "imm2": "0xaca23902", "rot": 5, "bit": 22, "mask": 16}, + {"i": 230, "op": "add", "dst": 0, "src": 6, "src2": 4, "imm": "0x1d176220", "imm2": "0x2a7fecb2", "rot": 20, "bit": 16, "mask": 2}, + {"i": 231, "op": "shfl", "dst": 1, "src": 2, "src2": 0, "imm": "0x91172787", "imm2": "0xc5d7af28", "rot": 3, "bit": 24, "mask": 4}, + {"i": 232, "op": "mul", "dst": 2, "src": 1, "src2": 2, "imm": "0x0be68835", "imm2": "0xde692bdb", "rot": 30, "bit": 17, "mask": 1}, + {"i": 233, "op": "mad", "dst": 7, "src": 0, "src2": 1, "imm": "0xf90d2db5", "imm2": "0x96c4c175", "rot": 28, "bit": 7, "mask": 4}, + {"i": 234, "op": "rotl", "dst": 5, "src": 2, "src2": 1, "imm": "0x16379736", "imm2": "0x6973b905", "rot": 22, "bit": 17, "mask": 4}, + {"i": 235, "op": "rotr", "dst": 4, "src": 6, "src2": 2, "imm": "0x84292a13", "imm2": "0x0f897740", "rot": 12, "bit": 6, "mask": 8}, + {"i": 236, "op": "mad", "dst": 0, "src": 5, "src2": 1, "imm": "0xeb7de837", "imm2": "0x64f0c302", "rot": 4, "bit": 19, "mask": 1}, + {"i": 237, "op": "xor", "dst": 6, "src": 4, "src2": 4, "imm": "0x6ab4b683", "imm2": "0x20f17adb", "rot": 1, "bit": 0, "mask": 16}, + {"i": 238, "op": "xor", "dst": 4, "src": 6, "src2": 1, "imm": "0x5836b35c", "imm2": "0x3293cc4a", "rot": 16, "bit": 22, "mask": 16}, + {"i": 239, "op": "rotl", "dst": 6, "src": 1, "src2": 6, "imm": "0x769d8bc0", "imm2": "0xdc86c9cc", "rot": 18, "bit": 27, "mask": 16}, + {"i": 240, "op": "add", "dst": 4, "src": 7, "src2": 1, "imm": "0x17dafb4d", "imm2": "0xadce39f3", "rot": 12, "bit": 25, "mask": 8}, + {"i": 241, "op": "sub", "dst": 0, "src": 7, "src2": 4, "imm": "0xd4690bda", "imm2": "0xdab9b27b", "rot": 30, "bit": 21, "mask": 1}, + {"i": 242, "op": "rotr", "dst": 1, "src": 6, "src2": 2, "imm": "0x670a2d0a", "imm2": "0x0612e33c", "rot": 31, "bit": 25, "mask": 2}, + {"i": 243, "op": "add", "dst": 3, "src": 0, "src2": 2, "imm": "0xf2f77d26", "imm2": "0x0e7033b6", "rot": 27, "bit": 29, "mask": 1}, + {"i": 244, "op": "mad", "dst": 2, "src": 7, "src2": 4, "imm": "0xa9eefc9d", "imm2": "0x16166c85", "rot": 18, "bit": 23, "mask": 16}, + {"i": 245, "op": "mad", "dst": 4, "src": 0, "src2": 6, "imm": "0xb26f6c0f", "imm2": "0x0630e821", "rot": 23, "bit": 30, "mask": 4}, + {"i": 246, "op": "mul", "dst": 5, "src": 7, "src2": 2, "imm": "0x269ce4bf", "imm2": "0x1ce28d32", "rot": 30, "bit": 15, "mask": 16}, + {"i": 247, "op": "add", "dst": 3, "src": 5, "src2": 0, "imm": "0xfed2da4e", "imm2": "0x7b2ff6b7", "rot": 25, "bit": 31, "mask": 2}, + {"i": 248, "op": "add", "dst": 0, "src": 7, "src2": 5, "imm": "0x03b2891c", "imm2": "0xb5fad7b1", "rot": 2, "bit": 0, "mask": 4}, + {"i": 249, "op": "mulhi", "dst": 5, "src": 4, "src2": 6, "imm": "0xa69a1e71", "imm2": "0x15f0c0ea", "rot": 4, "bit": 1, "mask": 4}, + {"i": 250, "op": "add", "dst": 5, "src": 2, "src2": 3, "imm": "0x042cd6e3", "imm2": "0xa7e71c2f", "rot": 24, "bit": 11, "mask": 8}, + {"i": 251, "op": "shfl", "dst": 6, "src": 1, "src2": 2, "imm": "0x89c6b683", "imm2": "0x10bbf661", "rot": 24, "bit": 5, "mask": 1}, + {"i": 252, "op": "xor", "dst": 6, "src": 1, "src2": 3, "imm": "0x265c66d6", "imm2": "0xd4a689ed", "rot": 6, "bit": 14, "mask": 8}, + {"i": 253, "op": "mul", "dst": 2, "src": 5, "src2": 5, "imm": "0x890b8201", "imm2": "0x97c36bf3", "rot": 17, "bit": 22, "mask": 4}, + {"i": 254, "op": "add", "dst": 0, "src": 6, "src2": 0, "imm": "0x784a302b", "imm2": "0xb83d78de", "rot": 27, "bit": 16, "mask": 4}, + {"i": 255, "op": "sub", "dst": 2, "src": 4, "src2": 0, "imm": "0x817adb38", "imm2": "0xf3a3534b", "rot": 7, "bit": 22, "mask": 4} + ]}, + "instructions": [ + {"i": 0, "op": "mad", "dst": 2, "src": 3, "src2": 4, "imm": "0xbf7b174d", "imm2": "0x337b762e", "rot": 17, "bit": 2, "mask": 2, "width": 1}, + {"i": 1, "op": "mad", "dst": 2, "src": 1, "src2": 1, "imm": "0xdd04a5da", "imm2": "0x42da7657", "rot": 15, "bit": 30, "mask": 16, "width": 1}, + {"i": 2, "op": "mad", "dst": 2, "src": 3, "src2": 2, "imm": "0x734003fa", "imm2": "0x5bb67700", "rot": 3, "bit": 20, "mask": 1, "width": 1}, + {"i": 3, "op": "xor", "dst": 3, "src": 5, "src2": 5, "imm": "0xc55a1b1c", "imm2": "0xa19720f3", "rot": 7, "bit": 8, "mask": 1, "width": 1}, + {"i": 4, "op": "load", "dst": 7, "src": 2, "src2": 5, "imm": "0xad572dd7", "imm2": "0x9ceb3ea7", "rot": 18, "bit": 30, "mask": 2, "width": 1}, + {"i": 5, "op": "load", "dst": 5, "src": 7, "src2": 3, "imm": "0x769a53be", "imm2": "0x80f9067e", "rot": 12, "bit": 22, "mask": 1, "width": 1}, + {"i": 6, "op": "shfl", "dst": 1, "src": 4, "src2": 0, "imm": "0xd3613d88", "imm2": "0x262fb219", "rot": 10, "bit": 30, "mask": 8, "width": 1}, + {"i": 7, "op": "shfl", "dst": 7, "src": 3, "src2": 4, "imm": "0xce38e42f", "imm2": "0xb868b818", "rot": 11, "bit": 8, "mask": 8, "width": 1}, + {"i": 8, "op": "mulhi", "dst": 1, "src": 5, "src2": 2, "imm": "0xa5eebca5", "imm2": "0x5703a72b", "rot": 13, "bit": 13, "mask": 16, "width": 1}, + {"i": 9, "op": "rotr", "dst": 6, "src": 3, "src2": 4, "imm": "0x17a5a9c7", "imm2": "0xdcfb93a1", "rot": 20, "bit": 27, "mask": 2, "width": 1}, + {"i": 10, "op": "or", "dst": 3, "src": 4, "src2": 1, "imm": "0xccb7d785", "imm2": "0xc335364c", "rot": 14, "bit": 12, "mask": 4, "width": 1}, + {"i": 11, "op": "load", "dst": 4, "src": 3, "src2": 2, "imm": "0x88cb9af3", "imm2": "0x4e7dc10d", "rot": 24, "bit": 17, "mask": 4, "width": 1}, + {"i": 12, "op": "mulhi", "dst": 0, "src": 4, "src2": 4, "imm": "0x45374321", "imm2": "0x3cd91989", "rot": 11, "bit": 4, "mask": 2, "width": 1}, + {"i": 13, "op": "add", "dst": 5, "src": 1, "src2": 2, "imm": "0xc7934706", "imm2": "0xd3177981", "rot": 16, "bit": 30, "mask": 2, "width": 1}, + {"i": 14, "op": "load", "dst": 0, "src": 4, "src2": 3, "imm": "0xfd7f56bb", "imm2": "0x65e14f52", "rot": 13, "bit": 22, "mask": 2, "width": 1}, + {"i": 15, "op": "sub", "dst": 2, "src": 4, "src2": 4, "imm": "0x35a80b49", "imm2": "0x060f2d13", "rot": 16, "bit": 20, "mask": 16, "width": 1}, + {"i": 16, "op": "load", "dst": 2, "src": 0, "src2": 2, "imm": "0xae0a32c2", "imm2": "0x4c2a4cfe", "rot": 8, "bit": 31, "mask": 16, "width": 1}, + {"i": 17, "op": "load", "dst": 7, "src": 2, "src2": 6, "imm": "0x82a84cc3", "imm2": "0x21a38d68", "rot": 15, "bit": 21, "mask": 2, "width": 1}, + {"i": 18, "op": "shfl", "dst": 7, "src": 3, "src2": 3, "imm": "0xa3818806", "imm2": "0x8f66b5c8", "rot": 14, "bit": 6, "mask": 4, "width": 1}, + {"i": 19, "op": "mul", "dst": 5, "src": 0, "src2": 1, "imm": "0xa00de107", "imm2": "0x77bfcaa5", "rot": 3, "bit": 10, "mask": 2, "width": 1}, + {"i": 20, "op": "shfl", "dst": 3, "src": 4, "src2": 7, "imm": "0x1d2b8cab", "imm2": "0x80b4f9a2", "rot": 14, "bit": 25, "mask": 2, "width": 1}, + {"i": 21, "op": "shfl", "dst": 2, "src": 4, "src2": 5, "imm": "0x3ac915d2", "imm2": "0x5fba7bc2", "rot": 16, "bit": 1, "mask": 16, "width": 1}, + {"i": 22, "op": "mulhi", "dst": 6, "src": 2, "src2": 0, "imm": "0xdc3ec8fd", "imm2": "0x599e2fa3", "rot": 22, "bit": 3, "mask": 2, "width": 1}, + {"i": 23, "op": "load", "dst": 6, "src": 1, "src2": 5, "imm": "0x2a6b16d5", "imm2": "0xd73e396f", "rot": 28, "bit": 29, "mask": 2, "width": 1}, + {"i": 24, "op": "mul", "dst": 5, "src": 0, "src2": 7, "imm": "0x376d0223", "imm2": "0xe1c2169a", "rot": 4, "bit": 16, "mask": 16, "width": 1}, + {"i": 25, "op": "rotl", "dst": 5, "src": 7, "src2": 3, "imm": "0x78ad8c60", "imm2": "0x6f5b77d5", "rot": 19, "bit": 11, "mask": 16, "width": 1}, + {"i": 26, "op": "shfl", "dst": 7, "src": 6, "src2": 5, "imm": "0x93915b9f", "imm2": "0x1e61fb6b", "rot": 28, "bit": 23, "mask": 2, "width": 1}, + {"i": 27, "op": "xor", "dst": 0, "src": 5, "src2": 7, "imm": "0x6378fe15", "imm2": "0x66c78f42", "rot": 12, "bit": 31, "mask": 8, "width": 1}, + {"i": 28, "op": "xor", "dst": 0, "src": 4, "src2": 7, "imm": "0x20a57fda", "imm2": "0x088c848e", "rot": 16, "bit": 13, "mask": 4, "width": 1}, + {"i": 29, "op": "sub", "dst": 3, "src": 0, "src2": 2, "imm": "0x49d95fd5", "imm2": "0x1a5f946a", "rot": 6, "bit": 12, "mask": 1, "width": 1}, + {"i": 30, "op": "mul", "dst": 5, "src": 1, "src2": 7, "imm": "0x0a816217", "imm2": "0x405c4f73", "rot": 13, "bit": 27, "mask": 4, "width": 1}, + {"i": 31, "op": "load", "dst": 7, "src": 2, "src2": 2, "imm": "0x09ed045e", "imm2": "0xd69c4715", "rot": 5, "bit": 9, "mask": 2, "width": 1}, + {"i": 32, "op": "load", "dst": 1, "src": 0, "src2": 6, "imm": "0xeb79ea49", "imm2": "0xcc587f5a", "rot": 6, "bit": 8, "mask": 16, "width": 1}, + {"i": 33, "op": "xor", "dst": 5, "src": 6, "src2": 1, "imm": "0x3027401e", "imm2": "0x5f20c27e", "rot": 18, "bit": 9, "mask": 2, "width": 1}, + {"i": 34, "op": "load", "dst": 5, "src": 1, "src2": 3, "imm": "0x0e1cab07", "imm2": "0x09356c5b", "rot": 19, "bit": 31, "mask": 1, "width": 1}, + {"i": 35, "op": "mulhi", "dst": 0, "src": 5, "src2": 2, "imm": "0x90e31357", "imm2": "0xabd32484", "rot": 26, "bit": 5, "mask": 8, "width": 1}, + {"i": 36, "op": "shfl", "dst": 5, "src": 2, "src2": 5, "imm": "0xee9a955f", "imm2": "0x31b3faed", "rot": 8, "bit": 24, "mask": 4, "width": 1}, + {"i": 37, "op": "load", "dst": 7, "src": 0, "src2": 7, "imm": "0x3ba2f832", "imm2": "0x1160dcd3", "rot": 4, "bit": 29, "mask": 1, "width": 1}, + {"i": 38, "op": "add", "dst": 3, "src": 1, "src2": 7, "imm": "0x75ba2fad", "imm2": "0x230c005c", "rot": 4, "bit": 27, "mask": 1, "width": 1}, + {"i": 39, "op": "shfl", "dst": 1, "src": 5, "src2": 3, "imm": "0xdbf37e75", "imm2": "0xb5ac1969", "rot": 30, "bit": 13, "mask": 4, "width": 1}, + {"i": 40, "op": "xor", "dst": 2, "src": 5, "src2": 5, "imm": "0x47f136c5", "imm2": "0x06ce9153", "rot": 19, "bit": 10, "mask": 2, "width": 1}, + {"i": 41, "op": "mad", "dst": 3, "src": 6, "src2": 3, "imm": "0xce13eff8", "imm2": "0x04cc1d55", "rot": 3, "bit": 1, "mask": 4, "width": 1}, + {"i": 42, "op": "sub", "dst": 6, "src": 7, "src2": 1, "imm": "0x6a65ab71", "imm2": "0x8fbc1bcd", "rot": 4, "bit": 1, "mask": 8, "width": 1}, + {"i": 43, "op": "xor", "dst": 7, "src": 0, "src2": 7, "imm": "0xdaeb4928", "imm2": "0xc0423027", "rot": 24, "bit": 11, "mask": 8, "width": 1}, + {"i": 44, "op": "load", "dst": 1, "src": 7, "src2": 7, "imm": "0x778f01c9", "imm2": "0x28cedcea", "rot": 12, "bit": 4, "mask": 16, "width": 1}, + {"i": 45, "op": "mul", "dst": 2, "src": 3, "src2": 2, "imm": "0xf4264f1b", "imm2": "0x0f627d56", "rot": 5, "bit": 28, "mask": 8, "width": 1}, + {"i": 46, "op": "mulhi", "dst": 1, "src": 5, "src2": 1, "imm": "0xffb2147a", "imm2": "0xccde9b05", "rot": 13, "bit": 9, "mask": 2, "width": 1}, + {"i": 47, "op": "sub", "dst": 4, "src": 3, "src2": 5, "imm": "0x73b36234", "imm2": "0x3f5d5997", "rot": 7, "bit": 18, "mask": 2, "width": 1}, + {"i": 48, "op": "rotr", "dst": 2, "src": 6, "src2": 3, "imm": "0x3a4d9aa9", "imm2": "0x212bec7b", "rot": 4, "bit": 29, "mask": 16, "width": 1}, + {"i": 49, "op": "load", "dst": 3, "src": 5, "src2": 2, "imm": "0x626f11df", "imm2": "0x56cd5bfd", "rot": 7, "bit": 1, "mask": 1, "width": 1}, + {"i": 50, "op": "add", "dst": 1, "src": 5, "src2": 6, "imm": "0x81b8bc2c", "imm2": "0x1907970c", "rot": 28, "bit": 7, "mask": 4, "width": 1}, + {"i": 51, "op": "mul", "dst": 0, "src": 2, "src2": 2, "imm": "0xa8848b30", "imm2": "0xef6ac348", "rot": 9, "bit": 15, "mask": 8, "width": 1}, + {"i": 52, "op": "add", "dst": 0, "src": 2, "src2": 0, "imm": "0x4f92b968", "imm2": "0x699fd448", "rot": 22, "bit": 6, "mask": 4, "width": 1}, + {"i": 53, "op": "add", "dst": 1, "src": 0, "src2": 2, "imm": "0x2bb965af", "imm2": "0x77b1520d", "rot": 2, "bit": 12, "mask": 8, "width": 1}, + {"i": 54, "op": "rotl", "dst": 7, "src": 1, "src2": 0, "imm": "0x553e678b", "imm2": "0x3cc8eae0", "rot": 14, "bit": 20, "mask": 2, "width": 1}, + {"i": 55, "op": "add", "dst": 3, "src": 7, "src2": 2, "imm": "0x7b0fe07a", "imm2": "0xa54c55a0", "rot": 10, "bit": 1, "mask": 1, "width": 1}, + {"i": 56, "op": "load", "dst": 6, "src": 7, "src2": 4, "imm": "0x01eba9aa", "imm2": "0x2758c0f7", "rot": 14, "bit": 15, "mask": 4, "width": 1}, + {"i": 57, "op": "rotr", "dst": 1, "src": 5, "src2": 2, "imm": "0x1f5267b3", "imm2": "0x236f5a27", "rot": 2, "bit": 31, "mask": 16, "width": 1}, + {"i": 58, "op": "load", "dst": 5, "src": 4, "src2": 3, "imm": "0xa9954a9b", "imm2": "0x6a54d4e8", "rot": 11, "bit": 10, "mask": 16, "width": 1}, + {"i": 59, "op": "load", "dst": 6, "src": 2, "src2": 4, "imm": "0x9923ff88", "imm2": "0x9357254e", "rot": 16, "bit": 1, "mask": 16, "width": 1}, + {"i": 60, "op": "mad", "dst": 3, "src": 5, "src2": 0, "imm": "0xc0cc51a6", "imm2": "0x3fd7701b", "rot": 20, "bit": 1, "mask": 4, "width": 1}, + {"i": 61, "op": "add", "dst": 5, "src": 7, "src2": 7, "imm": "0xaf9dd72d", "imm2": "0xad7493e7", "rot": 7, "bit": 31, "mask": 16, "width": 1}, + {"i": 62, "op": "add", "dst": 4, "src": 6, "src2": 2, "imm": "0x89841d87", "imm2": "0x1e07c3d9", "rot": 6, "bit": 27, "mask": 1, "width": 1}, + {"i": 63, "op": "rotl", "dst": 5, "src": 4, "src2": 2, "imm": "0xae210f8d", "imm2": "0x8e499ba4", "rot": 19, "bit": 9, "mask": 1, "width": 1} + ] +} diff --git a/proto-cuda/packs-ca3-shadow/sh256x53/program.metal b/proto-cuda/packs-ca3-shadow/sh256x53/program.metal new file mode 100644 index 000000000..38e5b41da --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x53/program.metal @@ -0,0 +1,368 @@ +#include +using namespace metal; + +#define MASK 0x0fffffffu +constant uint SEEDW[8] = { 0x67a9a7beu, 0x1a155b25u, 0xfddfb732u, 0x4b5af2e8u, 0xc55caf33u, 0xa27c13b7u, 0x06628a48u, 0x03852469u }; + +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 = r3 * r4 + r2; // 0 + r2 = r1 * r1 + r2; // 1 + r2 = r3 * r2 + r2; // 2 + r3 = r3 ^ r5; // 3 + r7 = r7 ^ dataset[r2 & MASK]; // 4 + r5 = r5 ^ dataset[r7 & MASK]; // 5 + r1 = r1 ^ simd_shuffle_xor(r4, (ushort)8); // 6 + r7 = r7 ^ simd_shuffle_xor(r3, (ushort)8); // 7 + r1 = mulhi(r1, r5); // 8 + r6 = rotr_var(r6, r3); // 9 + r3 = r3 | r4; // 10 + r4 = r4 ^ dataset[r3 & MASK]; // 11 + r0 = mulhi(r0, r4); // 12 + r5 = r5 + r1 + select(0xc7934706u, 0xd3177981u, ((sel >> 30u) & 1u) != 0u); // 13 + r0 = r0 ^ dataset[r4 & MASK]; // 14 + r2 = r2 - r4; // 15 + r2 = r2 ^ dataset[r0 & MASK]; // 16 + r7 = r7 ^ dataset[r2 & MASK]; // 17 + r7 = r7 ^ simd_shuffle_xor(r3, (ushort)4); // 18 + r5 = r5 * r0; // 19 + r3 = r3 ^ simd_shuffle_xor(r4, (ushort)2); // 20 + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)16); // 21 + r6 = mulhi(r6, r2); // 22 + r6 = r6 ^ dataset[r1 & MASK]; // 23 + r5 = r5 * r0; // 24 + r5 = rotl_imm(r5, 19u); // 25 + r7 = r7 ^ simd_shuffle_xor(r6, (ushort)2); // 26 + r0 = r0 ^ r5; // 27 + r0 = r0 ^ r4; // 28 + r3 = r3 - r0; // 29 + r5 = r5 * r1; // 30 + r7 = r7 ^ dataset[r2 & MASK]; // 31 + r1 = r1 ^ dataset[r0 & MASK]; // 32 + r5 = r5 ^ r6; // 33 + r5 = r5 ^ dataset[r1 & MASK]; // 34 + r0 = mulhi(r0, r5); // 35 + r5 = r5 ^ simd_shuffle_xor(r2, (ushort)4); // 36 + r7 = r7 ^ dataset[r0 & MASK]; // 37 + r3 = r3 + r1 + select(0x75ba2fadu, 0x230c005cu, ((sel >> 27u) & 1u) != 0u); // 38 + r1 = r1 ^ simd_shuffle_xor(r5, (ushort)4); // 39 + r2 = r2 ^ r5; // 40 + r3 = r6 * r3 + r3; // 41 + r6 = r6 - r7; // 42 + r7 = r7 ^ r0; // 43 + r1 = r1 ^ dataset[r7 & MASK]; // 44 + r2 = r2 * r3; // 45 + r1 = mulhi(r1, r5); // 46 + r4 = r4 - r3; // 47 + r2 = rotr_var(r2, r6); // 48 + r3 = r3 ^ dataset[r5 & MASK]; // 49 + r1 = r1 + r5 + select(0x81b8bc2cu, 0x1907970cu, ((sel >> 7u) & 1u) != 0u); // 50 + r0 = r0 * r2; // 51 + r0 = r0 + r2 + select(0x4f92b968u, 0x699fd448u, ((sel >> 6u) & 1u) != 0u); // 52 + r1 = r1 + r0 + select(0x2bb965afu, 0x77b1520du, ((sel >> 12u) & 1u) != 0u); // 53 + r7 = rotl_imm(r7, 14u); // 54 + r3 = r3 + r7 + select(0x7b0fe07au, 0xa54c55a0u, ((sel >> 1u) & 1u) != 0u); // 55 + r6 = r6 ^ dataset[r7 & MASK]; // 56 + r1 = rotr_var(r1, r5); // 57 + r5 = r5 ^ dataset[r4 & MASK]; // 58 + r6 = r6 ^ dataset[r2 & MASK]; // 59 + r3 = r5 * r0 + r3; // 60 + r5 = r5 + r7 + select(0xaf9dd72du, 0xad7493e7u, ((sel >> 31u) & 1u) != 0u); // 61 + r4 = r4 + r6 + select(0x89841d87u, 0x1e07c3d9u, ((sel >> 27u) & 1u) != 0u); // 62 + r5 = rotl_imm(r5, 19u); // 63 + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 53 passes after instruction 63, no load + for (uint sh = 0u; sh < 53u; ++sh) { + r5 = r5 + r2 + select(0x92199f99u, 0x8bc12da9u, ((sel >> 18u) & 1u) != 0u); // s0 add + r0 = r0 + r7 + select(0x8d72d3adu, 0x63079e5au, ((sel >> 26u) & 1u) != 0u); // s1 add + r6 = r6 ^ simd_shuffle_xor(r3, (ushort)2); // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + select(0xb21b4babu, 0x5d4c7a60u, ((sel >> 31u) & 1u) != 0u); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + select(0x2fe0e98bu, 0xc88e2942u, ((sel >> 16u) & 1u) != 0u); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + r6 = r6 ^ simd_shuffle_xor(r1, (ushort)4); // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + r2 = r2 ^ simd_shuffle_xor(r6, (ushort)4); // s12 shfl + r1 = r1 + r5 + select(0xbdf8f9a5u, 0xbc48c63eu, ((sel >> 25u) & 1u) != 0u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)8); // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + select(0x45c37cecu, 0x96e8f127u, ((sel >> 1u) & 1u) != 0u); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = mulhi(r6, r0); // s28 mulhi + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)2); // s29 shfl + r1 = r1 ^ simd_shuffle_xor(r6, (ushort)1); // s30 shfl + r1 = r1 + r6 + select(0x37985632u, 0xb1cdb2abu, ((sel >> 1u) & 1u) != 0u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + r3 = r3 ^ simd_shuffle_xor(r4, (ushort)2); // s33 shfl + r0 = r0 ^ simd_shuffle_xor(r3, (ushort)4); // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + select(0x804e777eu, 0x856e0180u, ((sel >> 0u) & 1u) != 0u); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + select(0x0b06c8a7u, 0xe9bd0cc4u, ((sel >> 2u) & 1u) != 0u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = mulhi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = mulhi(r4, r3); // s44 mulhi + r6 = r6 + r7 + select(0xee822e17u, 0xcdcb63f6u, ((sel >> 12u) & 1u) != 0u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + r4 = r4 ^ simd_shuffle_xor(r3, (ushort)8); // s47 shfl + r6 = mulhi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + select(0x3dfad1b6u, 0xd4758987u, ((sel >> 10u) & 1u) != 0u); // s56 add + r4 = r4 + r1 + select(0xfca75bc2u, 0x0602d6beu, ((sel >> 0u) & 1u) != 0u); // s57 add + r5 = mulhi(r5, r6); // s58 mulhi + r2 = r2 ^ simd_shuffle_xor(r1, (ushort)2); // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + select(0xd71c02ffu, 0x8596687au, ((sel >> 6u) & 1u) != 0u); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + r7 = r7 ^ simd_shuffle_xor(r5, (ushort)2); // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + select(0x3c6fe15du, 0x08ac5733u, ((sel >> 0u) & 1u) != 0u); // s72 add + r3 = r3 ^ simd_shuffle_xor(r2, (ushort)8); // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + select(0x295d5faeu, 0xc100b495u, ((sel >> 1u) & 1u) != 0u); // s77 add + r3 = mulhi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + select(0x274a9221u, 0x5cc59530u, ((sel >> 15u) & 1u) != 0u); // s81 add + r7 = r7 + r3 + select(0xc8651f8eu, 0x141479ecu, ((sel >> 5u) & 1u) != 0u); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + r2 = r2 ^ simd_shuffle_xor(r5, (ushort)16); // s85 shfl + r3 = r3 ^ r2; // s86 xor + r5 = r5 ^ simd_shuffle_xor(r7, (ushort)2); // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + select(0x53f915c2u, 0x883c0c92u, ((sel >> 18u) & 1u) != 0u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + select(0xe2be00a5u, 0x3cc5bd20u, ((sel >> 31u) & 1u) != 0u); // s91 add + r7 = r7 ^ simd_shuffle_xor(r2, (ushort)1); // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + select(0x423fd9c9u, 0xbfd646cbu, ((sel >> 17u) & 1u) != 0u); // s101 add + r7 = r7 + r6 + select(0x8d3c011du, 0x19b74a43u, ((sel >> 11u) & 1u) != 0u); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + select(0x8ce14721u, 0x7dcb7e18u, ((sel >> 15u) & 1u) != 0u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = mulhi(r2, r0); // s109 mulhi + r1 = mulhi(r1, r0); // s110 mulhi + r0 = r0 + r2 + select(0x2d9fc6b9u, 0x3c179ad8u, ((sel >> 28u) & 1u) != 0u); // s111 add + r2 = mulhi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + select(0x502138e2u, 0x47359729u, ((sel >> 22u) & 1u) != 0u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = mulhi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + r4 = r4 ^ simd_shuffle_xor(r2, (ushort)2); // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + r7 = r7 ^ simd_shuffle_xor(r2, (ushort)4); // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + select(0x33dff776u, 0x6c57e4e7u, ((sel >> 15u) & 1u) != 0u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + select(0x5db25b34u, 0xe8212c0cu, ((sel >> 30u) & 1u) != 0u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = mulhi(r0, r5); // s138 mulhi + r2 = r2 + r7 + select(0x218d4090u, 0xd44ff710u, ((sel >> 10u) & 1u) != 0u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + r3 = r3 ^ simd_shuffle_xor(r6, (ushort)1); // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + select(0xf4b1a8deu, 0xb98942fau, ((sel >> 29u) & 1u) != 0u); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + select(0x2bef10f2u, 0x0d48ba42u, ((sel >> 17u) & 1u) != 0u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + select(0xdc5cc080u, 0xc98dea9cu, ((sel >> 30u) & 1u) != 0u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + select(0x18197438u, 0x6c752dcbu, ((sel >> 11u) & 1u) != 0u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + select(0xf1c46574u, 0x8e481727u, ((sel >> 3u) & 1u) != 0u); // s163 add + r0 = mulhi(r0, r4); // s164 mulhi + r2 = r2 + r6 + select(0xac578137u, 0x550ab406u, ((sel >> 20u) & 1u) != 0u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + select(0xa33e6706u, 0xaebb5966u, ((sel >> 14u) & 1u) != 0u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + r7 = r7 ^ simd_shuffle_xor(r0, (ushort)8); // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + select(0xd94d55acu, 0x5bb7550fu, ((sel >> 21u) & 1u) != 0u); // s184 add + r3 = r3 | r5; // s185 or + r6 = mulhi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)2); // s188 shfl + r6 = r6 + r5 + select(0x89e747feu, 0x2a354e2du, ((sel >> 6u) & 1u) != 0u); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = mulhi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + r4 = r4 ^ simd_shuffle_xor(r5, (ushort)16); // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + select(0xea03e8e7u, 0x10cfdc71u, ((sel >> 7u) & 1u) != 0u); // s197 add + r7 = r7 + r5 + select(0xa7ee0102u, 0x66e148d3u, ((sel >> 15u) & 1u) != 0u); // s198 add + r5 = r5 - r2; // s199 sub + r5 = r5 ^ simd_shuffle_xor(r1, (ushort)2); // s200 shfl + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)8); // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + select(0x8379a4deu, 0x8558b619u, ((sel >> 10u) & 1u) != 0u); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = mulhi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + r2 = r2 ^ simd_shuffle_xor(r0, (ushort)4); // s209 shfl + r7 = r7 + r0 + select(0xaa8cb14eu, 0xf4049c4cu, ((sel >> 11u) & 1u) != 0u); // s210 add + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)16); // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + r3 = r3 ^ simd_shuffle_xor(r2, (ushort)16); // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = mulhi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + r5 = r5 ^ simd_shuffle_xor(r2, (ushort)8); // s222 shfl + r5 = mulhi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + select(0x1d176220u, 0x2a7fecb2u, ((sel >> 16u) & 1u) != 0u); // s230 add + r1 = r1 ^ simd_shuffle_xor(r2, (ushort)4); // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + select(0x17dafb4du, 0xadce39f3u, ((sel >> 25u) & 1u) != 0u); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + select(0xf2f77d26u, 0x0e7033b6u, ((sel >> 29u) & 1u) != 0u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + select(0xfed2da4eu, 0x7b2ff6b7u, ((sel >> 31u) & 1u) != 0u); // s247 add + r0 = r0 + r7 + select(0x03b2891cu, 0xb5fad7b1u, ((sel >> 0u) & 1u) != 0u); // s248 add + r5 = mulhi(r5, r4); // s249 mulhi + r5 = r5 + r2 + select(0x042cd6e3u, 0xa7e71c2fu, ((sel >> 11u) & 1u) != 0u); // s250 add + r6 = r6 ^ simd_shuffle_xor(r1, (ushort)1); // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + select(0x784a302bu, 0xb83d78deu, ((sel >> 16u) & 1u) != 0u); // s254 add + r2 = r2 - r4; // s255 sub + } + } + uint lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((ulong)hi << 32) | (ulong)lo; +} diff --git a/proto-cuda/packs-ca3-shadow/sh256x53/program_bound.metal b/proto-cuda/packs-ca3-shadow/sh256x53/program_bound.metal new file mode 100644 index 000000000..f26665ab9 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x53/program_bound.metal @@ -0,0 +1,370 @@ +#include +using namespace metal; + +#define MASK 0x0fffffffu +constant uint SEEDW[8] = { 0x67a9a7beu, 0x1a155b25u, 0xfddfb732u, 0x4b5af2e8u, 0xc55caf33u, 0xa27c13b7u, 0x06628a48u, 0x03852469u }; + +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 = r3 * r4 + r2; // 0 + r2 = r1 * r1 + r2; // 1 + r2 = r3 * r2 + r2; // 2 + r3 = r3 ^ r5; // 3 + r7 = r7 ^ dataset[r2 & MASK]; // 4 + r5 = r5 ^ dataset[r7 & MASK]; // 5 + r1 = r1 ^ simd_shuffle_xor(r4, (ushort)8); // 6 + r7 = r7 ^ simd_shuffle_xor(r3, (ushort)8); // 7 + r1 = mulhi(r1, r5); // 8 + r6 = rotr_var(r6, r3); // 9 + r3 = r3 | r4; // 10 + r4 = r4 ^ dataset[r3 & MASK]; // 11 + r0 = mulhi(r0, r4); // 12 + r5 = r5 + r1 + select(0xc7934706u, 0xd3177981u, ((sel >> 30u) & 1u) != 0u); // 13 + r0 = r0 ^ dataset[r4 & MASK]; // 14 + r2 = r2 - r4; // 15 + r2 = r2 ^ dataset[r0 & MASK]; // 16 + r7 = r7 ^ dataset[r2 & MASK]; // 17 + r7 = r7 ^ simd_shuffle_xor(r3, (ushort)4); // 18 + r5 = r5 * r0; // 19 + r3 = r3 ^ simd_shuffle_xor(r4, (ushort)2); // 20 + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)16); // 21 + r6 = mulhi(r6, r2); // 22 + r6 = r6 ^ dataset[r1 & MASK]; // 23 + r5 = r5 * r0; // 24 + r5 = rotl_imm(r5, 19u); // 25 + r7 = r7 ^ simd_shuffle_xor(r6, (ushort)2); // 26 + r0 = r0 ^ r5; // 27 + r0 = r0 ^ r4; // 28 + r3 = r3 - r0; // 29 + r5 = r5 * r1; // 30 + r7 = r7 ^ dataset[r2 & MASK]; // 31 + r1 = r1 ^ dataset[r0 & MASK]; // 32 + r5 = r5 ^ r6; // 33 + r5 = r5 ^ dataset[r1 & MASK]; // 34 + r0 = mulhi(r0, r5); // 35 + r5 = r5 ^ simd_shuffle_xor(r2, (ushort)4); // 36 + r7 = r7 ^ dataset[r0 & MASK]; // 37 + r3 = r3 + r1 + select(0x75ba2fadu, 0x230c005cu, ((sel >> 27u) & 1u) != 0u); // 38 + r1 = r1 ^ simd_shuffle_xor(r5, (ushort)4); // 39 + r2 = r2 ^ r5; // 40 + r3 = r6 * r3 + r3; // 41 + r6 = r6 - r7; // 42 + r7 = r7 ^ r0; // 43 + r1 = r1 ^ dataset[r7 & MASK]; // 44 + r2 = r2 * r3; // 45 + r1 = mulhi(r1, r5); // 46 + r4 = r4 - r3; // 47 + r2 = rotr_var(r2, r6); // 48 + r3 = r3 ^ dataset[r5 & MASK]; // 49 + r1 = r1 + r5 + select(0x81b8bc2cu, 0x1907970cu, ((sel >> 7u) & 1u) != 0u); // 50 + r0 = r0 * r2; // 51 + r0 = r0 + r2 + select(0x4f92b968u, 0x699fd448u, ((sel >> 6u) & 1u) != 0u); // 52 + r1 = r1 + r0 + select(0x2bb965afu, 0x77b1520du, ((sel >> 12u) & 1u) != 0u); // 53 + r7 = rotl_imm(r7, 14u); // 54 + r3 = r3 + r7 + select(0x7b0fe07au, 0xa54c55a0u, ((sel >> 1u) & 1u) != 0u); // 55 + r6 = r6 ^ dataset[r7 & MASK]; // 56 + r1 = rotr_var(r1, r5); // 57 + r5 = r5 ^ dataset[r4 & MASK]; // 58 + r6 = r6 ^ dataset[r2 & MASK]; // 59 + r3 = r5 * r0 + r3; // 60 + r5 = r5 + r7 + select(0xaf9dd72du, 0xad7493e7u, ((sel >> 31u) & 1u) != 0u); // 61 + r4 = r4 + r6 + select(0x89841d87u, 0x1e07c3d9u, ((sel >> 27u) & 1u) != 0u); // 62 + r5 = rotl_imm(r5, 19u); // 63 + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 53 passes after instruction 63, no load + for (uint sh = 0u; sh < 53u; ++sh) { + r5 = r5 + r2 + select(0x92199f99u, 0x8bc12da9u, ((sel >> 18u) & 1u) != 0u); // s0 add + r0 = r0 + r7 + select(0x8d72d3adu, 0x63079e5au, ((sel >> 26u) & 1u) != 0u); // s1 add + r6 = r6 ^ simd_shuffle_xor(r3, (ushort)2); // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + select(0xb21b4babu, 0x5d4c7a60u, ((sel >> 31u) & 1u) != 0u); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + select(0x2fe0e98bu, 0xc88e2942u, ((sel >> 16u) & 1u) != 0u); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + r6 = r6 ^ simd_shuffle_xor(r1, (ushort)4); // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + r2 = r2 ^ simd_shuffle_xor(r6, (ushort)4); // s12 shfl + r1 = r1 + r5 + select(0xbdf8f9a5u, 0xbc48c63eu, ((sel >> 25u) & 1u) != 0u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)8); // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + select(0x45c37cecu, 0x96e8f127u, ((sel >> 1u) & 1u) != 0u); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = mulhi(r6, r0); // s28 mulhi + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)2); // s29 shfl + r1 = r1 ^ simd_shuffle_xor(r6, (ushort)1); // s30 shfl + r1 = r1 + r6 + select(0x37985632u, 0xb1cdb2abu, ((sel >> 1u) & 1u) != 0u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + r3 = r3 ^ simd_shuffle_xor(r4, (ushort)2); // s33 shfl + r0 = r0 ^ simd_shuffle_xor(r3, (ushort)4); // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + select(0x804e777eu, 0x856e0180u, ((sel >> 0u) & 1u) != 0u); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + select(0x0b06c8a7u, 0xe9bd0cc4u, ((sel >> 2u) & 1u) != 0u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = mulhi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = mulhi(r4, r3); // s44 mulhi + r6 = r6 + r7 + select(0xee822e17u, 0xcdcb63f6u, ((sel >> 12u) & 1u) != 0u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + r4 = r4 ^ simd_shuffle_xor(r3, (ushort)8); // s47 shfl + r6 = mulhi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + select(0x3dfad1b6u, 0xd4758987u, ((sel >> 10u) & 1u) != 0u); // s56 add + r4 = r4 + r1 + select(0xfca75bc2u, 0x0602d6beu, ((sel >> 0u) & 1u) != 0u); // s57 add + r5 = mulhi(r5, r6); // s58 mulhi + r2 = r2 ^ simd_shuffle_xor(r1, (ushort)2); // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + select(0xd71c02ffu, 0x8596687au, ((sel >> 6u) & 1u) != 0u); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + r7 = r7 ^ simd_shuffle_xor(r5, (ushort)2); // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + select(0x3c6fe15du, 0x08ac5733u, ((sel >> 0u) & 1u) != 0u); // s72 add + r3 = r3 ^ simd_shuffle_xor(r2, (ushort)8); // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + select(0x295d5faeu, 0xc100b495u, ((sel >> 1u) & 1u) != 0u); // s77 add + r3 = mulhi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + select(0x274a9221u, 0x5cc59530u, ((sel >> 15u) & 1u) != 0u); // s81 add + r7 = r7 + r3 + select(0xc8651f8eu, 0x141479ecu, ((sel >> 5u) & 1u) != 0u); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + r2 = r2 ^ simd_shuffle_xor(r5, (ushort)16); // s85 shfl + r3 = r3 ^ r2; // s86 xor + r5 = r5 ^ simd_shuffle_xor(r7, (ushort)2); // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + select(0x53f915c2u, 0x883c0c92u, ((sel >> 18u) & 1u) != 0u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + select(0xe2be00a5u, 0x3cc5bd20u, ((sel >> 31u) & 1u) != 0u); // s91 add + r7 = r7 ^ simd_shuffle_xor(r2, (ushort)1); // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + select(0x423fd9c9u, 0xbfd646cbu, ((sel >> 17u) & 1u) != 0u); // s101 add + r7 = r7 + r6 + select(0x8d3c011du, 0x19b74a43u, ((sel >> 11u) & 1u) != 0u); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + select(0x8ce14721u, 0x7dcb7e18u, ((sel >> 15u) & 1u) != 0u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = mulhi(r2, r0); // s109 mulhi + r1 = mulhi(r1, r0); // s110 mulhi + r0 = r0 + r2 + select(0x2d9fc6b9u, 0x3c179ad8u, ((sel >> 28u) & 1u) != 0u); // s111 add + r2 = mulhi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + select(0x502138e2u, 0x47359729u, ((sel >> 22u) & 1u) != 0u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = mulhi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + r4 = r4 ^ simd_shuffle_xor(r2, (ushort)2); // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + r7 = r7 ^ simd_shuffle_xor(r2, (ushort)4); // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + select(0x33dff776u, 0x6c57e4e7u, ((sel >> 15u) & 1u) != 0u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + select(0x5db25b34u, 0xe8212c0cu, ((sel >> 30u) & 1u) != 0u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = mulhi(r0, r5); // s138 mulhi + r2 = r2 + r7 + select(0x218d4090u, 0xd44ff710u, ((sel >> 10u) & 1u) != 0u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + r3 = r3 ^ simd_shuffle_xor(r6, (ushort)1); // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + select(0xf4b1a8deu, 0xb98942fau, ((sel >> 29u) & 1u) != 0u); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + select(0x2bef10f2u, 0x0d48ba42u, ((sel >> 17u) & 1u) != 0u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + select(0xdc5cc080u, 0xc98dea9cu, ((sel >> 30u) & 1u) != 0u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + select(0x18197438u, 0x6c752dcbu, ((sel >> 11u) & 1u) != 0u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + select(0xf1c46574u, 0x8e481727u, ((sel >> 3u) & 1u) != 0u); // s163 add + r0 = mulhi(r0, r4); // s164 mulhi + r2 = r2 + r6 + select(0xac578137u, 0x550ab406u, ((sel >> 20u) & 1u) != 0u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + select(0xa33e6706u, 0xaebb5966u, ((sel >> 14u) & 1u) != 0u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + r7 = r7 ^ simd_shuffle_xor(r0, (ushort)8); // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + select(0xd94d55acu, 0x5bb7550fu, ((sel >> 21u) & 1u) != 0u); // s184 add + r3 = r3 | r5; // s185 or + r6 = mulhi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)2); // s188 shfl + r6 = r6 + r5 + select(0x89e747feu, 0x2a354e2du, ((sel >> 6u) & 1u) != 0u); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = mulhi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + r4 = r4 ^ simd_shuffle_xor(r5, (ushort)16); // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + select(0xea03e8e7u, 0x10cfdc71u, ((sel >> 7u) & 1u) != 0u); // s197 add + r7 = r7 + r5 + select(0xa7ee0102u, 0x66e148d3u, ((sel >> 15u) & 1u) != 0u); // s198 add + r5 = r5 - r2; // s199 sub + r5 = r5 ^ simd_shuffle_xor(r1, (ushort)2); // s200 shfl + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)8); // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + select(0x8379a4deu, 0x8558b619u, ((sel >> 10u) & 1u) != 0u); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = mulhi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + r2 = r2 ^ simd_shuffle_xor(r0, (ushort)4); // s209 shfl + r7 = r7 + r0 + select(0xaa8cb14eu, 0xf4049c4cu, ((sel >> 11u) & 1u) != 0u); // s210 add + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)16); // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + r3 = r3 ^ simd_shuffle_xor(r2, (ushort)16); // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = mulhi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + r5 = r5 ^ simd_shuffle_xor(r2, (ushort)8); // s222 shfl + r5 = mulhi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + select(0x1d176220u, 0x2a7fecb2u, ((sel >> 16u) & 1u) != 0u); // s230 add + r1 = r1 ^ simd_shuffle_xor(r2, (ushort)4); // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + select(0x17dafb4du, 0xadce39f3u, ((sel >> 25u) & 1u) != 0u); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + select(0xf2f77d26u, 0x0e7033b6u, ((sel >> 29u) & 1u) != 0u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + select(0xfed2da4eu, 0x7b2ff6b7u, ((sel >> 31u) & 1u) != 0u); // s247 add + r0 = r0 + r7 + select(0x03b2891cu, 0xb5fad7b1u, ((sel >> 0u) & 1u) != 0u); // s248 add + r5 = mulhi(r5, r4); // s249 mulhi + r5 = r5 + r2 + select(0x042cd6e3u, 0xa7e71c2fu, ((sel >> 11u) & 1u) != 0u); // s250 add + r6 = r6 ^ simd_shuffle_xor(r1, (ushort)1); // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + select(0x784a302bu, 0xb83d78deu, ((sel >> 16u) & 1u) != 0u); // s254 add + r2 = r2 - r4; // s255 sub + } + } + uint lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((ulong)hi << 32) | (ulong)lo; +} diff --git a/proto-cuda/packs-ca3-shadow/sh256x53/vectors.h b/proto-cuda/packs-ca3-shadow/sh256x53/vectors.h new file mode 100644 index 000000000..df08f36e3 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x53/vectors.h @@ -0,0 +1,57 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Expected outputs: igneum-pow (Rust) CPU interpreter, generator v2, memory-hard dataset +#pragma once +#ifdef __cplusplus +#include +#else +#include +#endif + +#define IGNEUM_VEC_WARPS 3 +static const uint32_t IGNEUM_VEC_BASE[IGNEUM_VEC_WARPS] = { 0u, 4096u, 1000000u }; +static const uint64_t IGNEUM_VEC_OUT[IGNEUM_VEC_WARPS][32] = { + { // base nonce 0 + 0x9771dab715d71261ull, 0x2f789c8578ad45f7ull, 0xfc9da4810f8196b1ull, 0x508616513c0103d9ull, 0xa4437c880d633e32ull, 0x972fdd14748673e4ull, 0xe58326218e52e816ull, 0x05f1aa766a05de2full, + 0x5a0802a428181a19ull, 0x5a33aa0527816100ull, 0x94e0eabd07b2fa2aull, 0xc7c20dc8566cb721ull, 0x189b9c2a14bba8faull, 0xa28f1353d5ba7b25ull, 0x86ce3df7aad12544ull, 0xdf3bccff4743de4eull, + 0x8d788ef1940c8864ull, 0xaa7671fb6d21e245ull, 0x9165ff575e147e30ull, 0x69e94a6a8b82e4b1ull, 0xcfad1b0dddaee567ull, 0x1d0527a178cf26d4ull, 0xda6c967f7d8e5e63ull, 0xed3f837cb1438585ull, + 0x9bb14627ef025cc2ull, 0x08084c71b63b8874ull, 0x51109206194ff893ull, 0xae4c0bd30a87da1bull, 0x636f54b9276801d6ull, 0x6508c23d1146c64aull, 0x137df6b1c65d335bull, 0x525676cf580b6f11ull + }, + { // base nonce 4096 + 0x1afa4ca3c965c3f5ull, 0x979626393ac908adull, 0x0ec8c4ba1abcd027ull, 0x7e6c26f6c03f15ccull, 0x7def92a296c97be7ull, 0xbeaec262659d72d4ull, 0xf5a7dda50892b2c5ull, 0x6c89bc70a249c825ull, + 0x0c58d024140130d3ull, 0x9a2ab37761c1f47bull, 0x241677b9869dc2f3ull, 0xc7e551770535e858ull, 0xf5b3125d49e65a78ull, 0x674212e38ba61f44ull, 0x8e69f6080a33d03eull, 0xfbed48ca3b12e78cull, + 0xc2dd49a4ad9ca24aull, 0x936d68e8a66b1204ull, 0x59b11d7e652b5c65ull, 0x742732ec4e6bfe6dull, 0xc3996c9b213ee4a5ull, 0x54e68ade1af61d71ull, 0x05117d54c3dfac1full, 0xd9fad59ae411d402ull, + 0x6f3d3c87a70c5350ull, 0xe84ad8082fc0d872ull, 0x50dc66ee26fee450ull, 0x447d4c50908467eeull, 0xde45e7f7fdbeb172ull, 0x0950381288b5a588ull, 0x2a57b3be740708b6ull, 0x4e238e93b5f0101dull + }, + { // base nonce 1000000 + 0x21a07085d7c0bd82ull, 0x16a84b9d075f9acaull, 0xc4db8ee34ce88c5dull, 0xfaa43b3000940f4full, 0xb405ce2db3692d88ull, 0x4cc7c7604a634f08ull, 0xbd4deebb5fd0e1e8ull, 0x7f46c28a6d2f24deull, + 0xe79b310591584a6cull, 0xef3086c61a0b7d50ull, 0x3b5c32e6ec12e734ull, 0x5a95d256113ebd96ull, 0x3ae4561425816798ull, 0x7c5651ebd73d47d5ull, 0x5dd33e0d572cc4a1ull, 0xbeb53b6f4484b746ull, + 0x835212401c6e031dull, 0x45af4100c20b9b22ull, 0x0cc0538f479f2cddull, 0x4c160b9e0eb0ad3cull, 0x04d7a06292ea77b6ull, 0x623d2a40e1bbc924ull, 0x344eddcb7ef1f0ecull, 0x32d8eeb5e34f7935ull, + 0xb96144ba3c229441ull, 0xf03d905f538fefacull, 0x634397d3aa9343d3ull, 0x6dd337c6d3022fc1ull, 0xcae8e601f71a75f8ull, 0x0f24c6af99d12d4cull, 0x573c2b15b7befadeull, 0x39fd0197590efb2aull + } +}; + +// Dataset self-test: dataset[0..15] and dataset[IGNEUM_MASK] (268435455). +static const uint32_t IGNEUM_DS_HEAD[16] = { + 0xfdad4319u, 0x1a7b68e1u, 0xde6db608u, 0x13d73892u, 0xd17f447au, 0xb2221ccfu, 0x9db004bdu, 0x57d7d367u, + 0xdbc4cf34u, 0x697c009au, 0xc43af1d4u, 0x97f12b2eu, 0x74c37cd0u, 0xc651ea15u, 0x665a6d29u, 0x22330a2du +}; +static const uint32_t IGNEUM_DS_LAST_INDEX = 268435455u; +static const uint32_t IGNEUM_DS_LAST = 0xa83e7aa6u; +// 64 sampled dataset words (index, value) computed on the Mac. +#define IGNEUM_DS_SAMPLES 64 +static const uint32_t IGNEUM_DS_SAMPLE_INDEX[IGNEUM_DS_SAMPLES] = { + 59471966u, 217795994u, 208353206u, 42483309u, 172547758u, 148076330u, 183853158u, 214389424u, 267488061u, 169781097u, 184093494u, 153880993u, 84977930u, 46426879u, 3093825u, 225364072u, 44593546u, 260713159u, 168250303u, 52384140u, 223401610u, 45554030u, 95410555u, 175039924u, 79171087u, 267580473u, 24168642u, 37981670u, 171551130u, 195559979u, 204611762u, 140997658u, 138925853u, 86637313u, 20736778u, 219665210u, 160430336u, 264654675u, 8013395u, 228945585u, 213884386u, 104419827u, 44185464u, 142737231u, 99284897u, 132475900u, 61861762u, 132056166u, 262388043u, 91878046u, 117353561u, 124768597u, 71352993u, 190698941u, 46055428u, 55281366u, 165145231u, 106810753u, 171985651u, 232085256u, 159510492u, 40072060u, 209107596u, 39023794u +}; +static const uint32_t IGNEUM_DS_SAMPLE_VALUE[IGNEUM_DS_SAMPLES] = { + 0x3230bc7bu, 0x7fbfe2c9u, 0xb2690991u, 0x1745c7c5u, 0x0ab0ccafu, 0x1bf87d6bu, 0x160139fdu, 0x719817acu, 0x0155df4bu, 0xbe1e86c3u, 0x680bcd6cu, 0x79c3dc6cu, 0x181e7e5fu, 0x0713a109u, 0xc705dd9fu, 0x3933b7a8u, 0xdd1c0431u, 0x50522b30u, 0xa0020b38u, 0xbff39e96u, 0x21b67e18u, 0x740f8db3u, 0x2baba568u, 0x2c9bef83u, 0x0ad9b671u, 0xc4327869u, 0x7b4fd7d0u, 0x2c29965fu, 0xec56f15fu, 0x61111746u, 0x303a1d6eu, 0xbddcfd1au, 0xf829a355u, 0x6d5df2a9u, 0x01ab8e44u, 0x06d13507u, 0xda8dcfc6u, 0x01a703e1u, 0xafe7d2c1u, 0xc091c3a2u, 0xac1814feu, 0x6e6ff62au, 0x8fdf01bau, 0xdd3f7159u, 0xdfa0d75cu, 0x26684c35u, 0x7f441e63u, 0x88df2570u, 0x8aa4d5ebu, 0xcc816c05u, 0x434df890u, 0xcd392ad6u, 0x1ab4cb63u, 0x595926fau, 0x7cd76b41u, 0x20cb95c4u, 0x13cf823fu, 0xf9daf901u, 0xff9af40au, 0x2c7dfa51u, 0x871206dbu, 0x938c116cu, 0xb64bf199u, 0x5751f874u +}; +// Cache self-test (memory-hard mode): cache[0..15], the last 16 words, and FNV-1a 64 over all 2^26 words. +static const uint32_t IGNEUM_CACHE_HEAD[16] = { + 0x355a86d2u, 0x7957db1cu, 0xd21772afu, 0x6fc1e09bu, 0xd55ce61du, 0x6e6a278bu, 0xd3f543ceu, 0x223d8e82u, + 0x143ab337u, 0x2e9f05bdu, 0x2eb389bfu, 0x0c6e449eu, 0x5cfa4222u, 0xba6560feu, 0x8e3e1aa4u, 0xdbcc1d53u +}; +static const uint32_t IGNEUM_CACHE_LAST[16] = { + 0x41190d91u, 0xbd277957u, 0x22ddbb49u, 0x6986f207u, 0xdf69a4d6u, 0x26401a3au, 0x818230fbu, 0xc417122du, + 0x3597b211u, 0xb553ce55u, 0xcf39cc0du, 0x3b7fc43au, 0x3fd43b00u, 0x67e1c80eu, 0xffa7ea7du, 0xca2960abu +}; +static const uint64_t IGNEUM_CACHE_FNV64 = 0x48c4f5bf24166b2eull; diff --git a/proto-cuda/packs-ca3-shadow/sh256x53/vectors.json b/proto-cuda/packs-ca3-shadow/sh256x53/vectors.json new file mode 100644 index 000000000..0023718d7 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x53/vectors.json @@ -0,0 +1,36 @@ +{ + "seed": "igneum-genesis", + "day": "2026-10-03", + "dataset_mode": "memory-hard", + "dataset_log2_words": 28, + "mask": "0x0fffffff", + "lanes": 32, + "source": "igneum-pow (Rust) CPU interpreter, generator v2, memory-hard dataset", + "warps": [ + {"base_nonce": 0, "expected": [ + "0x9771dab715d71261", "0x2f789c8578ad45f7", "0xfc9da4810f8196b1", "0x508616513c0103d9", "0xa4437c880d633e32", "0x972fdd14748673e4", "0xe58326218e52e816", "0x05f1aa766a05de2f", + "0x5a0802a428181a19", "0x5a33aa0527816100", "0x94e0eabd07b2fa2a", "0xc7c20dc8566cb721", "0x189b9c2a14bba8fa", "0xa28f1353d5ba7b25", "0x86ce3df7aad12544", "0xdf3bccff4743de4e", + "0x8d788ef1940c8864", "0xaa7671fb6d21e245", "0x9165ff575e147e30", "0x69e94a6a8b82e4b1", "0xcfad1b0dddaee567", "0x1d0527a178cf26d4", "0xda6c967f7d8e5e63", "0xed3f837cb1438585", + "0x9bb14627ef025cc2", "0x08084c71b63b8874", "0x51109206194ff893", "0xae4c0bd30a87da1b", "0x636f54b9276801d6", "0x6508c23d1146c64a", "0x137df6b1c65d335b", "0x525676cf580b6f11" + ]}, + {"base_nonce": 4096, "expected": [ + "0x1afa4ca3c965c3f5", "0x979626393ac908ad", "0x0ec8c4ba1abcd027", "0x7e6c26f6c03f15cc", "0x7def92a296c97be7", "0xbeaec262659d72d4", "0xf5a7dda50892b2c5", "0x6c89bc70a249c825", + "0x0c58d024140130d3", "0x9a2ab37761c1f47b", "0x241677b9869dc2f3", "0xc7e551770535e858", "0xf5b3125d49e65a78", "0x674212e38ba61f44", "0x8e69f6080a33d03e", "0xfbed48ca3b12e78c", + "0xc2dd49a4ad9ca24a", "0x936d68e8a66b1204", "0x59b11d7e652b5c65", "0x742732ec4e6bfe6d", "0xc3996c9b213ee4a5", "0x54e68ade1af61d71", "0x05117d54c3dfac1f", "0xd9fad59ae411d402", + "0x6f3d3c87a70c5350", "0xe84ad8082fc0d872", "0x50dc66ee26fee450", "0x447d4c50908467ee", "0xde45e7f7fdbeb172", "0x0950381288b5a588", "0x2a57b3be740708b6", "0x4e238e93b5f0101d" + ]}, + {"base_nonce": 1000000, "expected": [ + "0x21a07085d7c0bd82", "0x16a84b9d075f9aca", "0xc4db8ee34ce88c5d", "0xfaa43b3000940f4f", "0xb405ce2db3692d88", "0x4cc7c7604a634f08", "0xbd4deebb5fd0e1e8", "0x7f46c28a6d2f24de", + "0xe79b310591584a6c", "0xef3086c61a0b7d50", "0x3b5c32e6ec12e734", "0x5a95d256113ebd96", "0x3ae4561425816798", "0x7c5651ebd73d47d5", "0x5dd33e0d572cc4a1", "0xbeb53b6f4484b746", + "0x835212401c6e031d", "0x45af4100c20b9b22", "0x0cc0538f479f2cdd", "0x4c160b9e0eb0ad3c", "0x04d7a06292ea77b6", "0x623d2a40e1bbc924", "0x344eddcb7ef1f0ec", "0x32d8eeb5e34f7935", + "0xb96144ba3c229441", "0xf03d905f538fefac", "0x634397d3aa9343d3", "0x6dd337c6d3022fc1", "0xcae8e601f71a75f8", "0x0f24c6af99d12d4c", "0x573c2b15b7befade", "0x39fd0197590efb2a" + ]} + ], + "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" +} diff --git a/proto-cuda/packs-ca3-shadow/sh256x7/kernel.cl b/proto-cuda/packs-ca3-shadow/sh256x7/kernel.cl new file mode 100644 index 000000000..29c0bf356 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x7/kernel.cl @@ -0,0 +1,538 @@ +// 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 ^ 0x67a9a7beu; x += 0x9e3779b9u; x = splitmix32(x); r0 = x ^ 0x1a155b25u; } // SEEDW[0], 0x9e3779b9u * 1u, SEEDW[1] + { uint x = nonce ^ 0x1a155b25u; x += 0x3c6ef372u; x = splitmix32(x); r1 = x ^ 0xfddfb732u; } // SEEDW[1], 0x9e3779b9u * 2u, SEEDW[2] + { uint x = nonce ^ 0xfddfb732u; x += 0xdaa66d2bu; x = splitmix32(x); r2 = x ^ 0x4b5af2e8u; } // SEEDW[2], 0x9e3779b9u * 3u, SEEDW[3] + { uint x = nonce ^ 0x4b5af2e8u; x += 0x78dde6e4u; x = splitmix32(x); r3 = x ^ 0xc55caf33u; } // SEEDW[3], 0x9e3779b9u * 4u, SEEDW[4] + { uint x = nonce ^ 0xc55caf33u; x += 0x1715609du; x = splitmix32(x); r4 = x ^ 0xa27c13b7u; } // SEEDW[4], 0x9e3779b9u * 5u, SEEDW[5] + { uint x = nonce ^ 0xa27c13b7u; x += 0xb54cda56u; x = splitmix32(x); r5 = x ^ 0x06628a48u; } // SEEDW[5], 0x9e3779b9u * 6u, SEEDW[6] + { uint x = nonce ^ 0x06628a48u; x += 0x5384540fu; x = splitmix32(x); r6 = x ^ 0x03852469u; } // SEEDW[6], 0x9e3779b9u * 7u, SEEDW[7] + { uint x = nonce ^ 0x03852469u; x += 0xf1bbcdc8u; x = splitmix32(x); r7 = x ^ 0x67a9a7beu; } // SEEDW[7], 0x9e3779b9u * 8u, SEEDW[0] + + for (uint it = 0u; it < 8u; ++it) { + uint sel = r0; + r2 = r3 * r4 + r2; // 0 mad + r2 = r1 * r1 + r2; // 1 mad + r2 = r3 * r2 + r2; // 2 mad + r3 = r3 ^ r5; // 3 xor + r7 = r7 ^ ds[r2 & mask]; // 4 load + r5 = r5 ^ ds[r7 & mask]; // 5 load + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r1 = r1 ^ t_; } // 6 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r7 = r7 ^ t_; } // 7 shfl + r1 = mul_hi(r1, r5); // 8 mulhi + r6 = rotr_var(r6, r3); // 9 rotr + r3 = r3 | r4; // 10 or + r4 = r4 ^ ds[r3 & mask]; // 11 load + r0 = mul_hi(r0, r4); // 12 mulhi + r5 = r5 + r1 + ((((sel >> 30u) & 1u) != 0u) ? 0xd3177981u : 0xc7934706u); // 13 add + r0 = r0 ^ ds[r4 & mask]; // 14 load + r2 = r2 - r4; // 15 sub + r2 = r2 ^ ds[r0 & mask]; // 16 load + r7 = r7 ^ ds[r2 & mask]; // 17 load + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r7 = r7 ^ t_; } // 18 shfl + r5 = r5 * r0; // 19 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // 20 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 16u); r2 = r2 ^ t_; } // 21 shfl + r6 = mul_hi(r6, r2); // 22 mulhi + r6 = r6 ^ ds[r1 & mask]; // 23 load + r5 = r5 * r0; // 24 mul + r5 = rotl_imm(r5, 19u); // 25 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 2u); r7 = r7 ^ t_; } // 26 shfl + r0 = r0 ^ r5; // 27 xor + r0 = r0 ^ r4; // 28 xor + r3 = r3 - r0; // 29 sub + r5 = r5 * r1; // 30 mul + r7 = r7 ^ ds[r2 & mask]; // 31 load + r1 = r1 ^ ds[r0 & mask]; // 32 load + r5 = r5 ^ r6; // 33 xor + r5 = r5 ^ ds[r1 & mask]; // 34 load + r0 = mul_hi(r0, r5); // 35 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r5 = r5 ^ t_; } // 36 shfl + r7 = r7 ^ ds[r0 & mask]; // 37 load + r3 = r3 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0x230c005cu : 0x75ba2fadu); // 38 add + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 4u); r1 = r1 ^ t_; } // 39 shfl + r2 = r2 ^ r5; // 40 xor + r3 = r6 * r3 + r3; // 41 mad + r6 = r6 - r7; // 42 sub + r7 = r7 ^ r0; // 43 xor + r1 = r1 ^ ds[r7 & mask]; // 44 load + r2 = r2 * r3; // 45 mul + r1 = mul_hi(r1, r5); // 46 mulhi + r4 = r4 - r3; // 47 sub + r2 = rotr_var(r2, r6); // 48 rotr + r3 = r3 ^ ds[r5 & mask]; // 49 load + r1 = r1 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x1907970cu : 0x81b8bc2cu); // 50 add + r0 = r0 * r2; // 51 mul + r0 = r0 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x699fd448u : 0x4f92b968u); // 52 add + r1 = r1 + r0 + ((((sel >> 12u) & 1u) != 0u) ? 0x77b1520du : 0x2bb965afu); // 53 add + r7 = rotl_imm(r7, 14u); // 54 rotl + r3 = r3 + r7 + ((((sel >> 1u) & 1u) != 0u) ? 0xa54c55a0u : 0x7b0fe07au); // 55 add + r6 = r6 ^ ds[r7 & mask]; // 56 load + r1 = rotr_var(r1, r5); // 57 rotr + r5 = r5 ^ ds[r4 & mask]; // 58 load + r6 = r6 ^ ds[r2 & mask]; // 59 load + r3 = r5 * r0 + r3; // 60 mad + r5 = r5 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0xad7493e7u : 0xaf9dd72du); // 61 add + r4 = r4 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x1e07c3d9u : 0x89841d87u); // 62 add + r5 = rotl_imm(r5, 19u); // 63 rotl + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 7 passes after instruction 63, no load + for (uint sh = 0u; sh < 7u; ++sh) { + r5 = r5 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x8bc12da9u : 0x92199f99u); // s0 add + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x63079e5au : 0x8d72d3adu); // s1 add + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 2u); r6 = r6 ^ t_; } // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + ((((sel >> 31u) & 1u) != 0u) ? 0x5d4c7a60u : 0xb21b4babu); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + ((((sel >> 16u) & 1u) != 0u) ? 0xc88e2942u : 0x2fe0e98bu); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r6 = r6 ^ t_; } // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 4u); r2 = r2 ^ t_; } // s12 shfl + r1 = r1 + r5 + ((((sel >> 25u) & 1u) != 0u) ? 0xbc48c63eu : 0xbdf8f9a5u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r2 = r2 ^ t_; } // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + ((((sel >> 1u) & 1u) != 0u) ? 0x96e8f127u : 0x45c37cecu); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = mul_hi(r6, r0); // s28 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r2 = r2 ^ t_; } // s29 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r1 = r1 ^ t_; } // s30 shfl + r1 = r1 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0xb1cdb2abu : 0x37985632u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // s33 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r0 = r0 ^ t_; } // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x856e0180u : 0x804e777eu); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xe9bd0cc4u : 0x0b06c8a7u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = mul_hi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = mul_hi(r4, r3); // s44 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xcdcb63f6u : 0xee822e17u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r4 = r4 ^ t_; } // s47 shfl + r6 = mul_hi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0xd4758987u : 0x3dfad1b6u); // s56 add + r4 = r4 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x0602d6beu : 0xfca75bc2u); // s57 add + r5 = mul_hi(r5, r6); // s58 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r2 = r2 ^ t_; } // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0x8596687au : 0xd71c02ffu); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 2u); r7 = r7 ^ t_; } // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0x08ac5733u : 0x3c6fe15du); // s72 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r3 = r3 ^ t_; } // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + ((((sel >> 1u) & 1u) != 0u) ? 0xc100b495u : 0x295d5faeu); // s77 add + r3 = mul_hi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + ((((sel >> 15u) & 1u) != 0u) ? 0x5cc59530u : 0x274a9221u); // s81 add + r7 = r7 + r3 + ((((sel >> 5u) & 1u) != 0u) ? 0x141479ecu : 0xc8651f8eu); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r2 = r2 ^ t_; } // s85 shfl + r3 = r3 ^ r2; // s86 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 2u); r5 = r5 ^ t_; } // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x883c0c92u : 0x53f915c2u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + ((((sel >> 31u) & 1u) != 0u) ? 0x3cc5bd20u : 0xe2be00a5u); // s91 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 1u); r7 = r7 ^ t_; } // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + ((((sel >> 17u) & 1u) != 0u) ? 0xbfd646cbu : 0x423fd9c9u); // s101 add + r7 = r7 + r6 + ((((sel >> 11u) & 1u) != 0u) ? 0x19b74a43u : 0x8d3c011du); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + ((((sel >> 15u) & 1u) != 0u) ? 0x7dcb7e18u : 0x8ce14721u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = mul_hi(r2, r0); // s109 mulhi + r1 = mul_hi(r1, r0); // s110 mulhi + r0 = r0 + r2 + ((((sel >> 28u) & 1u) != 0u) ? 0x3c179ad8u : 0x2d9fc6b9u); // s111 add + r2 = mul_hi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + ((((sel >> 22u) & 1u) != 0u) ? 0x47359729u : 0x502138e2u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = mul_hi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 2u); r4 = r4 ^ t_; } // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r7 = r7 ^ t_; } // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x6c57e4e7u : 0x33dff776u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + ((((sel >> 30u) & 1u) != 0u) ? 0xe8212c0cu : 0x5db25b34u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = mul_hi(r0, r5); // s138 mulhi + r2 = r2 + r7 + ((((sel >> 10u) & 1u) != 0u) ? 0xd44ff710u : 0x218d4090u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r3 = r3 ^ t_; } // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + ((((sel >> 29u) & 1u) != 0u) ? 0xb98942fau : 0xf4b1a8deu); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + ((((sel >> 17u) & 1u) != 0u) ? 0x0d48ba42u : 0x2bef10f2u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + ((((sel >> 30u) & 1u) != 0u) ? 0xc98dea9cu : 0xdc5cc080u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0x6c752dcbu : 0x18197438u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + ((((sel >> 3u) & 1u) != 0u) ? 0x8e481727u : 0xf1c46574u); // s163 add + r0 = mul_hi(r0, r4); // s164 mulhi + r2 = r2 + r6 + ((((sel >> 20u) & 1u) != 0u) ? 0x550ab406u : 0xac578137u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + ((((sel >> 14u) & 1u) != 0u) ? 0xaebb5966u : 0xa33e6706u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 8u); r7 = r7 ^ t_; } // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x5bb7550fu : 0xd94d55acu); // s184 add + r3 = r3 | r5; // s185 or + r6 = mul_hi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r7 = r7 ^ t_; } // s188 shfl + r6 = r6 + r5 + ((((sel >> 6u) & 1u) != 0u) ? 0x2a354e2du : 0x89e747feu); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = mul_hi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r4 = r4 ^ t_; } // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + ((((sel >> 7u) & 1u) != 0u) ? 0x10cfdc71u : 0xea03e8e7u); // s197 add + r7 = r7 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x66e148d3u : 0xa7ee0102u); // s198 add + r5 = r5 - r2; // s199 sub + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r5 = r5 ^ t_; } // s200 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 8u); r7 = r7 ^ t_; } // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0x8558b619u : 0x8379a4deu); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = mul_hi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 4u); r2 = r2 ^ t_; } // s209 shfl + r7 = r7 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0xf4049c4cu : 0xaa8cb14eu); // s210 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 16u); r7 = r7 ^ t_; } // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 16u); r3 = r3 ^ t_; } // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = mul_hi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r5 = r5 ^ t_; } // s222 shfl + r5 = mul_hi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0x2a7fecb2u : 0x1d176220u); // s230 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r1 = r1 ^ t_; } // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + ((((sel >> 25u) & 1u) != 0u) ? 0xadce39f3u : 0x17dafb4du); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + ((((sel >> 29u) & 1u) != 0u) ? 0x0e7033b6u : 0xf2f77d26u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + ((((sel >> 31u) & 1u) != 0u) ? 0x7b2ff6b7u : 0xfed2da4eu); // s247 add + r0 = r0 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0xb5fad7b1u : 0x03b2891cu); // s248 add + r5 = mul_hi(r5, r4); // s249 mulhi + r5 = r5 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0xa7e71c2fu : 0x042cd6e3u); // s250 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 1u); r6 = r6 ^ t_; } // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0xb83d78deu : 0x784a302bu); // s254 add + r2 = r2 - r4; // s255 sub + } + } + uint lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((ulong)hi << 32) | (ulong)lo; +} + +#if IGNEUM_EXCHANGE != 0 +// Reports the sub-group size this device uses for a work-group of IGNEUM_GROUP items. host.c runs it only when the +// per-kernel query (clGetKernelSubGroupInfoKHR on igneum_hash) is unavailable; that query is preferred because a +// compiler may pick a different wave width per kernel (RDNA: wave32 or wave64). See WAVEFRONT.md. +IGNEUM_KERNEL_HASH void igneum_probe_subgroup(__global uint* out) { + if (get_local_id(0) == 0u) { out[0] = get_sub_group_size(); out[1] = get_num_sub_groups(); } +} +#endif diff --git a/proto-cuda/packs-ca3-shadow/sh256x7/kernel.cu b/proto-cuda/packs-ca3-shadow/sh256x7/kernel.cu new file mode 100644 index 000000000..2da273cfa --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x7/kernel.cu @@ -0,0 +1,423 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Bit-exact twin of the Metal kernel for the same seed (see proto-cuda/CHECKLIST.md and program.metal). +// Compiled ahead of time by nvcc together with proto-cuda/host.cu. No NVRTC. +#include +#include +#include "program.h" +#include "memhard.h" + +__device__ __forceinline__ uint32_t splitmix32(uint32_t x) { + x ^= x >> 16; x *= 0x7feb352du; + x ^= x >> 15; x *= 0x846ca68bu; + x ^= x >> 16; + return x; +} +// n is a literal in 1..31 at every call site, so both shift amounts are in 1..31. +__device__ __forceinline__ uint32_t rotl_imm(uint32_t x, uint32_t n) { return (x << n) | (x >> (32u - n)); } +// n is masked to 0..31; the second shift amount is masked too, so n == 0 gives x. +__device__ __forceinline__ uint32_t rotr_var(uint32_t x, uint32_t n) { n &= 31u; return (x >> n) | (x << ((32u - n) & 31u)); } +__device__ __forceinline__ uint32_t ds_elem(uint32_t i, uint32_t d0, uint32_t d1) { + uint32_t x = i ^ d0; + x *= 0x9E3779B1u; x ^= x >> 15; + x += d1; + x *= 0x85EBCA77u; x ^= x >> 13; + x *= 0xC2B2AE3Du; x ^= x >> 16; + return x; +} + +// Memory-hard dataset (MEMHARD.md). One thread per cache segment; one thread per 64-byte dataset item. +// The core functions (mh_cache_segment, mh_item) are in memhard.h and are also compiled for the host. +__global__ void igneum_cache_fill(uint32_t* cache, uint32_t nSegments) { + uint32_t seg = blockIdx.x * blockDim.x + threadIdx.x; + if (seg < nSegments) mh_cache_segment(cache, seg); +} +__global__ void igneum_build(uint32_t* ds, const uint32_t* cache, uint32_t nItems) { + uint32_t t = blockIdx.x * blockDim.x + threadIdx.x; + if (t < nItems) { + uint32_t s[16]; + mh_item(cache, t, s); + uint32_t* d = ds + (size_t)t * 16u; + for (uint32_t i = 0u; i < 16u; ++i) d[i] = s[i]; + } +} + +// One hash per thread. blockDim.x is a multiple of 32; lane = threadIdx.x & 31 and every +// __shfl_xor_sync stays inside the lane's own warp, exactly like simd_shuffle_xor inside a +// 32-wide Metal SIMD group. Control flow is uniform, so the full 0xffffffff member mask is valid. +__global__ void igneum_hash(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask) { + uint32_t gid = blockIdx.x * blockDim.x + threadIdx.x; + uint32_t nonce = baseNonce + gid; + uint32_t r0, r1, r2, r3, r4, r5, r6, r7; + { uint32_t x = nonce ^ 0x67a9a7beu; x += 0x9e3779b9u; x = splitmix32(x); r0 = x ^ 0x1a155b25u; } // SEEDW[0], 0x9e3779b9u * 1u, SEEDW[1] + { uint32_t x = nonce ^ 0x1a155b25u; x += 0x3c6ef372u; x = splitmix32(x); r1 = x ^ 0xfddfb732u; } // SEEDW[1], 0x9e3779b9u * 2u, SEEDW[2] + { uint32_t x = nonce ^ 0xfddfb732u; x += 0xdaa66d2bu; x = splitmix32(x); r2 = x ^ 0x4b5af2e8u; } // SEEDW[2], 0x9e3779b9u * 3u, SEEDW[3] + { uint32_t x = nonce ^ 0x4b5af2e8u; x += 0x78dde6e4u; x = splitmix32(x); r3 = x ^ 0xc55caf33u; } // SEEDW[3], 0x9e3779b9u * 4u, SEEDW[4] + { uint32_t x = nonce ^ 0xc55caf33u; x += 0x1715609du; x = splitmix32(x); r4 = x ^ 0xa27c13b7u; } // SEEDW[4], 0x9e3779b9u * 5u, SEEDW[5] + { uint32_t x = nonce ^ 0xa27c13b7u; x += 0xb54cda56u; x = splitmix32(x); r5 = x ^ 0x06628a48u; } // SEEDW[5], 0x9e3779b9u * 6u, SEEDW[6] + { uint32_t x = nonce ^ 0x06628a48u; x += 0x5384540fu; x = splitmix32(x); r6 = x ^ 0x03852469u; } // SEEDW[6], 0x9e3779b9u * 7u, SEEDW[7] + { uint32_t x = nonce ^ 0x03852469u; x += 0xf1bbcdc8u; x = splitmix32(x); r7 = x ^ 0x67a9a7beu; } // SEEDW[7], 0x9e3779b9u * 8u, SEEDW[0] + + for (uint32_t it = 0u; it < 8u; ++it) { + uint32_t sel = r0; + r2 = r3 * r4 + r2; // 0 mad + r2 = r1 * r1 + r2; // 1 mad + r2 = r3 * r2 + r2; // 2 mad + r3 = r3 ^ r5; // 3 xor + r7 = r7 ^ ds[r2 & mask]; // 4 load + r5 = r5 ^ ds[r7 & mask]; // 5 load + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r4, 8); // 6 shfl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r3, 8); // 7 shfl + r1 = __umulhi(r1, r5); // 8 mulhi + r6 = rotr_var(r6, r3); // 9 rotr + r3 = r3 | r4; // 10 or + r4 = r4 ^ ds[r3 & mask]; // 11 load + r0 = __umulhi(r0, r4); // 12 mulhi + r5 = r5 + r1 + ((((sel >> 30u) & 1u) != 0u) ? 0xd3177981u : 0xc7934706u); // 13 add + r0 = r0 ^ ds[r4 & mask]; // 14 load + r2 = r2 - r4; // 15 sub + r2 = r2 ^ ds[r0 & mask]; // 16 load + r7 = r7 ^ ds[r2 & mask]; // 17 load + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r3, 4); // 18 shfl + r5 = r5 * r0; // 19 mul + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // 20 shfl + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 16); // 21 shfl + r6 = __umulhi(r6, r2); // 22 mulhi + r6 = r6 ^ ds[r1 & mask]; // 23 load + r5 = r5 * r0; // 24 mul + r5 = rotl_imm(r5, 19u); // 25 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r6, 2); // 26 shfl + r0 = r0 ^ r5; // 27 xor + r0 = r0 ^ r4; // 28 xor + r3 = r3 - r0; // 29 sub + r5 = r5 * r1; // 30 mul + r7 = r7 ^ ds[r2 & mask]; // 31 load + r1 = r1 ^ ds[r0 & mask]; // 32 load + r5 = r5 ^ r6; // 33 xor + r5 = r5 ^ ds[r1 & mask]; // 34 load + r0 = __umulhi(r0, r5); // 35 mulhi + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // 36 shfl + r7 = r7 ^ ds[r0 & mask]; // 37 load + r3 = r3 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0x230c005cu : 0x75ba2fadu); // 38 add + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r5, 4); // 39 shfl + r2 = r2 ^ r5; // 40 xor + r3 = r6 * r3 + r3; // 41 mad + r6 = r6 - r7; // 42 sub + r7 = r7 ^ r0; // 43 xor + r1 = r1 ^ ds[r7 & mask]; // 44 load + r2 = r2 * r3; // 45 mul + r1 = __umulhi(r1, r5); // 46 mulhi + r4 = r4 - r3; // 47 sub + r2 = rotr_var(r2, r6); // 48 rotr + r3 = r3 ^ ds[r5 & mask]; // 49 load + r1 = r1 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x1907970cu : 0x81b8bc2cu); // 50 add + r0 = r0 * r2; // 51 mul + r0 = r0 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x699fd448u : 0x4f92b968u); // 52 add + r1 = r1 + r0 + ((((sel >> 12u) & 1u) != 0u) ? 0x77b1520du : 0x2bb965afu); // 53 add + r7 = rotl_imm(r7, 14u); // 54 rotl + r3 = r3 + r7 + ((((sel >> 1u) & 1u) != 0u) ? 0xa54c55a0u : 0x7b0fe07au); // 55 add + r6 = r6 ^ ds[r7 & mask]; // 56 load + r1 = rotr_var(r1, r5); // 57 rotr + r5 = r5 ^ ds[r4 & mask]; // 58 load + r6 = r6 ^ ds[r2 & mask]; // 59 load + r3 = r5 * r0 + r3; // 60 mad + r5 = r5 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0xad7493e7u : 0xaf9dd72du); // 61 add + r4 = r4 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x1e07c3d9u : 0x89841d87u); // 62 add + r5 = rotl_imm(r5, 19u); // 63 rotl + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 7 passes after instruction 63, no load + for (uint32_t sh = 0u; sh < 7u; ++sh) { + r5 = r5 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x8bc12da9u : 0x92199f99u); // s0 add + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x63079e5au : 0x8d72d3adu); // s1 add + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r3, 2); // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + ((((sel >> 31u) & 1u) != 0u) ? 0x5d4c7a60u : 0xb21b4babu); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + ((((sel >> 16u) & 1u) != 0u) ? 0xc88e2942u : 0x2fe0e98bu); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r1, 4); // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r6, 4); // s12 shfl + r1 = r1 + r5 + ((((sel >> 25u) & 1u) != 0u) ? 0xbc48c63eu : 0xbdf8f9a5u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 8); // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + ((((sel >> 1u) & 1u) != 0u) ? 0x96e8f127u : 0x45c37cecu); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = __umulhi(r6, r0); // s28 mulhi + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // s29 shfl + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r6, 1); // s30 shfl + r1 = r1 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0xb1cdb2abu : 0x37985632u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // s33 shfl + r0 = r0 ^ __shfl_xor_sync(0xffffffffu, r3, 4); // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x856e0180u : 0x804e777eu); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xe9bd0cc4u : 0x0b06c8a7u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = __umulhi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = __umulhi(r4, r3); // s44 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xcdcb63f6u : 0xee822e17u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r3, 8); // s47 shfl + r6 = __umulhi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0xd4758987u : 0x3dfad1b6u); // s56 add + r4 = r4 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x0602d6beu : 0xfca75bc2u); // s57 add + r5 = __umulhi(r5, r6); // s58 mulhi + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0x8596687au : 0xd71c02ffu); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r5, 2); // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0x08ac5733u : 0x3c6fe15du); // s72 add + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r2, 8); // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + ((((sel >> 1u) & 1u) != 0u) ? 0xc100b495u : 0x295d5faeu); // s77 add + r3 = __umulhi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + ((((sel >> 15u) & 1u) != 0u) ? 0x5cc59530u : 0x274a9221u); // s81 add + r7 = r7 + r3 + ((((sel >> 5u) & 1u) != 0u) ? 0x141479ecu : 0xc8651f8eu); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r5, 16); // s85 shfl + r3 = r3 ^ r2; // s86 xor + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r7, 2); // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x883c0c92u : 0x53f915c2u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + ((((sel >> 31u) & 1u) != 0u) ? 0x3cc5bd20u : 0xe2be00a5u); // s91 add + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r2, 1); // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + ((((sel >> 17u) & 1u) != 0u) ? 0xbfd646cbu : 0x423fd9c9u); // s101 add + r7 = r7 + r6 + ((((sel >> 11u) & 1u) != 0u) ? 0x19b74a43u : 0x8d3c011du); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + ((((sel >> 15u) & 1u) != 0u) ? 0x7dcb7e18u : 0x8ce14721u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = __umulhi(r2, r0); // s109 mulhi + r1 = __umulhi(r1, r0); // s110 mulhi + r0 = r0 + r2 + ((((sel >> 28u) & 1u) != 0u) ? 0x3c179ad8u : 0x2d9fc6b9u); // s111 add + r2 = __umulhi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + ((((sel >> 22u) & 1u) != 0u) ? 0x47359729u : 0x502138e2u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = __umulhi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r2, 2); // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x6c57e4e7u : 0x33dff776u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + ((((sel >> 30u) & 1u) != 0u) ? 0xe8212c0cu : 0x5db25b34u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = __umulhi(r0, r5); // s138 mulhi + r2 = r2 + r7 + ((((sel >> 10u) & 1u) != 0u) ? 0xd44ff710u : 0x218d4090u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r6, 1); // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + ((((sel >> 29u) & 1u) != 0u) ? 0xb98942fau : 0xf4b1a8deu); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + ((((sel >> 17u) & 1u) != 0u) ? 0x0d48ba42u : 0x2bef10f2u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + ((((sel >> 30u) & 1u) != 0u) ? 0xc98dea9cu : 0xdc5cc080u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0x6c752dcbu : 0x18197438u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + ((((sel >> 3u) & 1u) != 0u) ? 0x8e481727u : 0xf1c46574u); // s163 add + r0 = __umulhi(r0, r4); // s164 mulhi + r2 = r2 + r6 + ((((sel >> 20u) & 1u) != 0u) ? 0x550ab406u : 0xac578137u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + ((((sel >> 14u) & 1u) != 0u) ? 0xaebb5966u : 0xa33e6706u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r0, 8); // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x5bb7550fu : 0xd94d55acu); // s184 add + r3 = r3 | r5; // s185 or + r6 = __umulhi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s188 shfl + r6 = r6 + r5 + ((((sel >> 6u) & 1u) != 0u) ? 0x2a354e2du : 0x89e747feu); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = __umulhi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r5, 16); // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + ((((sel >> 7u) & 1u) != 0u) ? 0x10cfdc71u : 0xea03e8e7u); // s197 add + r7 = r7 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x66e148d3u : 0xa7ee0102u); // s198 add + r5 = r5 - r2; // s199 sub + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s200 shfl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 8); // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0x8558b619u : 0x8379a4deu); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = __umulhi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r0, 4); // s209 shfl + r7 = r7 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0xf4049c4cu : 0xaa8cb14eu); // s210 add + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 16); // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r2, 16); // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = __umulhi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r2, 8); // s222 shfl + r5 = __umulhi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0x2a7fecb2u : 0x1d176220u); // s230 add + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + ((((sel >> 25u) & 1u) != 0u) ? 0xadce39f3u : 0x17dafb4du); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + ((((sel >> 29u) & 1u) != 0u) ? 0x0e7033b6u : 0xf2f77d26u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + ((((sel >> 31u) & 1u) != 0u) ? 0x7b2ff6b7u : 0xfed2da4eu); // s247 add + r0 = r0 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0xb5fad7b1u : 0x03b2891cu); // s248 add + r5 = __umulhi(r5, r4); // s249 mulhi + r5 = r5 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0xa7e71c2fu : 0x042cd6e3u); // s250 add + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r1, 1); // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0xb83d78deu : 0x784a302bu); // s254 add + r2 = r2 - r4; // s255 sub + } + } + uint32_t lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint32_t hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((uint64_t)hi << 32) | (uint64_t)lo; +} + +// Host-side launch wrappers. Declared in program.h, called from host.cu. +cudaError_t igneum_launch_cache_fill(uint32_t* cache, uint32_t nSegments) { + if (nSegments == 0u) return cudaErrorInvalidValue; + uint32_t block = 256u; + uint32_t grid = (nSegments + block - 1u) / block; + igneum_cache_fill<<>>(cache, nSegments); + return cudaGetLastError(); +} + +cudaError_t igneum_launch_build(uint32_t* ds, const uint32_t* cache, uint32_t nItems) { + if (nItems == 0u) return cudaErrorInvalidValue; + uint32_t block = 256u; + uint32_t grid = (nItems + block - 1u) / block; + igneum_build<<>>(ds, cache, nItems); + return cudaGetLastError(); +} + +cudaError_t igneum_launch_hash(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, + uint32_t nonces, uint32_t blockWarps) { + if (blockWarps == 0u || blockWarps > 32u) return cudaErrorInvalidValue; + uint32_t block = 32u * blockWarps; + if (nonces == 0u || (nonces % block) != 0u) return cudaErrorInvalidValue; + igneum_hash<<>>(ds, out, baseNonce, mask); + return cudaGetLastError(); +} + +cudaError_t igneum_hash_info(int* numRegs, int* blocksPerSM, uint32_t blockWarps) { + cudaFuncAttributes attr; + cudaError_t e = cudaFuncGetAttributes(&attr, igneum_hash); + if (e != cudaSuccess) return e; + *numRegs = attr.numRegs; + return cudaOccupancyMaxActiveBlocksPerMultiprocessor(blocksPerSM, igneum_hash, (int)(32u * blockWarps), 0); +} diff --git a/proto-cuda/packs-ca3-shadow/sh256x7/kernel_bound.cl b/proto-cuda/packs-ca3-shadow/sh256x7/kernel_bound.cl new file mode 100644 index 000000000..90a79d334 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x7/kernel_bound.cl @@ -0,0 +1,891 @@ +// 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 ^ 0x67a9a7beu; x += 0x9e3779b9u; x = splitmix32(x); r0 = x ^ 0x1a155b25u; } // SEEDW[0], 0x9e3779b9u * 1u, SEEDW[1] + { uint x = nonce ^ 0x1a155b25u; x += 0x3c6ef372u; x = splitmix32(x); r1 = x ^ 0xfddfb732u; } // SEEDW[1], 0x9e3779b9u * 2u, SEEDW[2] + { uint x = nonce ^ 0xfddfb732u; x += 0xdaa66d2bu; x = splitmix32(x); r2 = x ^ 0x4b5af2e8u; } // SEEDW[2], 0x9e3779b9u * 3u, SEEDW[3] + { uint x = nonce ^ 0x4b5af2e8u; x += 0x78dde6e4u; x = splitmix32(x); r3 = x ^ 0xc55caf33u; } // SEEDW[3], 0x9e3779b9u * 4u, SEEDW[4] + { uint x = nonce ^ 0xc55caf33u; x += 0x1715609du; x = splitmix32(x); r4 = x ^ 0xa27c13b7u; } // SEEDW[4], 0x9e3779b9u * 5u, SEEDW[5] + { uint x = nonce ^ 0xa27c13b7u; x += 0xb54cda56u; x = splitmix32(x); r5 = x ^ 0x06628a48u; } // SEEDW[5], 0x9e3779b9u * 6u, SEEDW[6] + { uint x = nonce ^ 0x06628a48u; x += 0x5384540fu; x = splitmix32(x); r6 = x ^ 0x03852469u; } // SEEDW[6], 0x9e3779b9u * 7u, SEEDW[7] + { uint x = nonce ^ 0x03852469u; x += 0xf1bbcdc8u; x = splitmix32(x); r7 = x ^ 0x67a9a7beu; } // SEEDW[7], 0x9e3779b9u * 8u, SEEDW[0] + + for (uint it = 0u; it < 8u; ++it) { + uint sel = r0; + r2 = r3 * r4 + r2; // 0 mad + r2 = r1 * r1 + r2; // 1 mad + r2 = r3 * r2 + r2; // 2 mad + r3 = r3 ^ r5; // 3 xor + r7 = r7 ^ ds[r2 & mask]; // 4 load + r5 = r5 ^ ds[r7 & mask]; // 5 load + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r1 = r1 ^ t_; } // 6 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r7 = r7 ^ t_; } // 7 shfl + r1 = mul_hi(r1, r5); // 8 mulhi + r6 = rotr_var(r6, r3); // 9 rotr + r3 = r3 | r4; // 10 or + r4 = r4 ^ ds[r3 & mask]; // 11 load + r0 = mul_hi(r0, r4); // 12 mulhi + r5 = r5 + r1 + ((((sel >> 30u) & 1u) != 0u) ? 0xd3177981u : 0xc7934706u); // 13 add + r0 = r0 ^ ds[r4 & mask]; // 14 load + r2 = r2 - r4; // 15 sub + r2 = r2 ^ ds[r0 & mask]; // 16 load + r7 = r7 ^ ds[r2 & mask]; // 17 load + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r7 = r7 ^ t_; } // 18 shfl + r5 = r5 * r0; // 19 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // 20 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 16u); r2 = r2 ^ t_; } // 21 shfl + r6 = mul_hi(r6, r2); // 22 mulhi + r6 = r6 ^ ds[r1 & mask]; // 23 load + r5 = r5 * r0; // 24 mul + r5 = rotl_imm(r5, 19u); // 25 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 2u); r7 = r7 ^ t_; } // 26 shfl + r0 = r0 ^ r5; // 27 xor + r0 = r0 ^ r4; // 28 xor + r3 = r3 - r0; // 29 sub + r5 = r5 * r1; // 30 mul + r7 = r7 ^ ds[r2 & mask]; // 31 load + r1 = r1 ^ ds[r0 & mask]; // 32 load + r5 = r5 ^ r6; // 33 xor + r5 = r5 ^ ds[r1 & mask]; // 34 load + r0 = mul_hi(r0, r5); // 35 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r5 = r5 ^ t_; } // 36 shfl + r7 = r7 ^ ds[r0 & mask]; // 37 load + r3 = r3 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0x230c005cu : 0x75ba2fadu); // 38 add + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 4u); r1 = r1 ^ t_; } // 39 shfl + r2 = r2 ^ r5; // 40 xor + r3 = r6 * r3 + r3; // 41 mad + r6 = r6 - r7; // 42 sub + r7 = r7 ^ r0; // 43 xor + r1 = r1 ^ ds[r7 & mask]; // 44 load + r2 = r2 * r3; // 45 mul + r1 = mul_hi(r1, r5); // 46 mulhi + r4 = r4 - r3; // 47 sub + r2 = rotr_var(r2, r6); // 48 rotr + r3 = r3 ^ ds[r5 & mask]; // 49 load + r1 = r1 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x1907970cu : 0x81b8bc2cu); // 50 add + r0 = r0 * r2; // 51 mul + r0 = r0 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x699fd448u : 0x4f92b968u); // 52 add + r1 = r1 + r0 + ((((sel >> 12u) & 1u) != 0u) ? 0x77b1520du : 0x2bb965afu); // 53 add + r7 = rotl_imm(r7, 14u); // 54 rotl + r3 = r3 + r7 + ((((sel >> 1u) & 1u) != 0u) ? 0xa54c55a0u : 0x7b0fe07au); // 55 add + r6 = r6 ^ ds[r7 & mask]; // 56 load + r1 = rotr_var(r1, r5); // 57 rotr + r5 = r5 ^ ds[r4 & mask]; // 58 load + r6 = r6 ^ ds[r2 & mask]; // 59 load + r3 = r5 * r0 + r3; // 60 mad + r5 = r5 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0xad7493e7u : 0xaf9dd72du); // 61 add + r4 = r4 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x1e07c3d9u : 0x89841d87u); // 62 add + r5 = rotl_imm(r5, 19u); // 63 rotl + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 7 passes after instruction 63, no load + for (uint sh = 0u; sh < 7u; ++sh) { + r5 = r5 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x8bc12da9u : 0x92199f99u); // s0 add + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x63079e5au : 0x8d72d3adu); // s1 add + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 2u); r6 = r6 ^ t_; } // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + ((((sel >> 31u) & 1u) != 0u) ? 0x5d4c7a60u : 0xb21b4babu); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + ((((sel >> 16u) & 1u) != 0u) ? 0xc88e2942u : 0x2fe0e98bu); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r6 = r6 ^ t_; } // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 4u); r2 = r2 ^ t_; } // s12 shfl + r1 = r1 + r5 + ((((sel >> 25u) & 1u) != 0u) ? 0xbc48c63eu : 0xbdf8f9a5u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r2 = r2 ^ t_; } // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + ((((sel >> 1u) & 1u) != 0u) ? 0x96e8f127u : 0x45c37cecu); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = mul_hi(r6, r0); // s28 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r2 = r2 ^ t_; } // s29 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r1 = r1 ^ t_; } // s30 shfl + r1 = r1 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0xb1cdb2abu : 0x37985632u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // s33 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r0 = r0 ^ t_; } // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x856e0180u : 0x804e777eu); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xe9bd0cc4u : 0x0b06c8a7u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = mul_hi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = mul_hi(r4, r3); // s44 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xcdcb63f6u : 0xee822e17u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r4 = r4 ^ t_; } // s47 shfl + r6 = mul_hi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0xd4758987u : 0x3dfad1b6u); // s56 add + r4 = r4 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x0602d6beu : 0xfca75bc2u); // s57 add + r5 = mul_hi(r5, r6); // s58 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r2 = r2 ^ t_; } // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0x8596687au : 0xd71c02ffu); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 2u); r7 = r7 ^ t_; } // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0x08ac5733u : 0x3c6fe15du); // s72 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r3 = r3 ^ t_; } // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + ((((sel >> 1u) & 1u) != 0u) ? 0xc100b495u : 0x295d5faeu); // s77 add + r3 = mul_hi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + ((((sel >> 15u) & 1u) != 0u) ? 0x5cc59530u : 0x274a9221u); // s81 add + r7 = r7 + r3 + ((((sel >> 5u) & 1u) != 0u) ? 0x141479ecu : 0xc8651f8eu); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r2 = r2 ^ t_; } // s85 shfl + r3 = r3 ^ r2; // s86 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 2u); r5 = r5 ^ t_; } // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x883c0c92u : 0x53f915c2u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + ((((sel >> 31u) & 1u) != 0u) ? 0x3cc5bd20u : 0xe2be00a5u); // s91 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 1u); r7 = r7 ^ t_; } // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + ((((sel >> 17u) & 1u) != 0u) ? 0xbfd646cbu : 0x423fd9c9u); // s101 add + r7 = r7 + r6 + ((((sel >> 11u) & 1u) != 0u) ? 0x19b74a43u : 0x8d3c011du); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + ((((sel >> 15u) & 1u) != 0u) ? 0x7dcb7e18u : 0x8ce14721u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = mul_hi(r2, r0); // s109 mulhi + r1 = mul_hi(r1, r0); // s110 mulhi + r0 = r0 + r2 + ((((sel >> 28u) & 1u) != 0u) ? 0x3c179ad8u : 0x2d9fc6b9u); // s111 add + r2 = mul_hi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + ((((sel >> 22u) & 1u) != 0u) ? 0x47359729u : 0x502138e2u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = mul_hi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 2u); r4 = r4 ^ t_; } // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r7 = r7 ^ t_; } // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x6c57e4e7u : 0x33dff776u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + ((((sel >> 30u) & 1u) != 0u) ? 0xe8212c0cu : 0x5db25b34u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = mul_hi(r0, r5); // s138 mulhi + r2 = r2 + r7 + ((((sel >> 10u) & 1u) != 0u) ? 0xd44ff710u : 0x218d4090u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r3 = r3 ^ t_; } // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + ((((sel >> 29u) & 1u) != 0u) ? 0xb98942fau : 0xf4b1a8deu); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + ((((sel >> 17u) & 1u) != 0u) ? 0x0d48ba42u : 0x2bef10f2u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + ((((sel >> 30u) & 1u) != 0u) ? 0xc98dea9cu : 0xdc5cc080u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0x6c752dcbu : 0x18197438u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + ((((sel >> 3u) & 1u) != 0u) ? 0x8e481727u : 0xf1c46574u); // s163 add + r0 = mul_hi(r0, r4); // s164 mulhi + r2 = r2 + r6 + ((((sel >> 20u) & 1u) != 0u) ? 0x550ab406u : 0xac578137u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + ((((sel >> 14u) & 1u) != 0u) ? 0xaebb5966u : 0xa33e6706u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 8u); r7 = r7 ^ t_; } // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x5bb7550fu : 0xd94d55acu); // s184 add + r3 = r3 | r5; // s185 or + r6 = mul_hi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r7 = r7 ^ t_; } // s188 shfl + r6 = r6 + r5 + ((((sel >> 6u) & 1u) != 0u) ? 0x2a354e2du : 0x89e747feu); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = mul_hi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r4 = r4 ^ t_; } // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + ((((sel >> 7u) & 1u) != 0u) ? 0x10cfdc71u : 0xea03e8e7u); // s197 add + r7 = r7 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x66e148d3u : 0xa7ee0102u); // s198 add + r5 = r5 - r2; // s199 sub + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r5 = r5 ^ t_; } // s200 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 8u); r7 = r7 ^ t_; } // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0x8558b619u : 0x8379a4deu); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = mul_hi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 4u); r2 = r2 ^ t_; } // s209 shfl + r7 = r7 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0xf4049c4cu : 0xaa8cb14eu); // s210 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 16u); r7 = r7 ^ t_; } // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 16u); r3 = r3 ^ t_; } // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = mul_hi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r5 = r5 ^ t_; } // s222 shfl + r5 = mul_hi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0x2a7fecb2u : 0x1d176220u); // s230 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r1 = r1 ^ t_; } // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + ((((sel >> 25u) & 1u) != 0u) ? 0xadce39f3u : 0x17dafb4du); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + ((((sel >> 29u) & 1u) != 0u) ? 0x0e7033b6u : 0xf2f77d26u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + ((((sel >> 31u) & 1u) != 0u) ? 0x7b2ff6b7u : 0xfed2da4eu); // s247 add + r0 = r0 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0xb5fad7b1u : 0x03b2891cu); // s248 add + r5 = mul_hi(r5, r4); // s249 mulhi + r5 = r5 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0xa7e71c2fu : 0x042cd6e3u); // s250 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 1u); r6 = r6 ^ t_; } // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0xb83d78deu : 0x784a302bu); // s254 add + r2 = r2 - r4; // s255 sub + } + } + 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 = r3 * r4 + r2; // 0 mad + r2 = r1 * r1 + r2; // 1 mad + r2 = r3 * r2 + r2; // 2 mad + r3 = r3 ^ r5; // 3 xor + r7 = r7 ^ ds[r2 & mask]; // 4 load + r5 = r5 ^ ds[r7 & mask]; // 5 load + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r1 = r1 ^ t_; } // 6 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r7 = r7 ^ t_; } // 7 shfl + r1 = mul_hi(r1, r5); // 8 mulhi + r6 = rotr_var(r6, r3); // 9 rotr + r3 = r3 | r4; // 10 or + r4 = r4 ^ ds[r3 & mask]; // 11 load + r0 = mul_hi(r0, r4); // 12 mulhi + r5 = r5 + r1 + ((((sel >> 30u) & 1u) != 0u) ? 0xd3177981u : 0xc7934706u); // 13 add + r0 = r0 ^ ds[r4 & mask]; // 14 load + r2 = r2 - r4; // 15 sub + r2 = r2 ^ ds[r0 & mask]; // 16 load + r7 = r7 ^ ds[r2 & mask]; // 17 load + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r7 = r7 ^ t_; } // 18 shfl + r5 = r5 * r0; // 19 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // 20 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 16u); r2 = r2 ^ t_; } // 21 shfl + r6 = mul_hi(r6, r2); // 22 mulhi + r6 = r6 ^ ds[r1 & mask]; // 23 load + r5 = r5 * r0; // 24 mul + r5 = rotl_imm(r5, 19u); // 25 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 2u); r7 = r7 ^ t_; } // 26 shfl + r0 = r0 ^ r5; // 27 xor + r0 = r0 ^ r4; // 28 xor + r3 = r3 - r0; // 29 sub + r5 = r5 * r1; // 30 mul + r7 = r7 ^ ds[r2 & mask]; // 31 load + r1 = r1 ^ ds[r0 & mask]; // 32 load + r5 = r5 ^ r6; // 33 xor + r5 = r5 ^ ds[r1 & mask]; // 34 load + r0 = mul_hi(r0, r5); // 35 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r5 = r5 ^ t_; } // 36 shfl + r7 = r7 ^ ds[r0 & mask]; // 37 load + r3 = r3 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0x230c005cu : 0x75ba2fadu); // 38 add + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 4u); r1 = r1 ^ t_; } // 39 shfl + r2 = r2 ^ r5; // 40 xor + r3 = r6 * r3 + r3; // 41 mad + r6 = r6 - r7; // 42 sub + r7 = r7 ^ r0; // 43 xor + r1 = r1 ^ ds[r7 & mask]; // 44 load + r2 = r2 * r3; // 45 mul + r1 = mul_hi(r1, r5); // 46 mulhi + r4 = r4 - r3; // 47 sub + r2 = rotr_var(r2, r6); // 48 rotr + r3 = r3 ^ ds[r5 & mask]; // 49 load + r1 = r1 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x1907970cu : 0x81b8bc2cu); // 50 add + r0 = r0 * r2; // 51 mul + r0 = r0 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x699fd448u : 0x4f92b968u); // 52 add + r1 = r1 + r0 + ((((sel >> 12u) & 1u) != 0u) ? 0x77b1520du : 0x2bb965afu); // 53 add + r7 = rotl_imm(r7, 14u); // 54 rotl + r3 = r3 + r7 + ((((sel >> 1u) & 1u) != 0u) ? 0xa54c55a0u : 0x7b0fe07au); // 55 add + r6 = r6 ^ ds[r7 & mask]; // 56 load + r1 = rotr_var(r1, r5); // 57 rotr + r5 = r5 ^ ds[r4 & mask]; // 58 load + r6 = r6 ^ ds[r2 & mask]; // 59 load + r3 = r5 * r0 + r3; // 60 mad + r5 = r5 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0xad7493e7u : 0xaf9dd72du); // 61 add + r4 = r4 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x1e07c3d9u : 0x89841d87u); // 62 add + r5 = rotl_imm(r5, 19u); // 63 rotl + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 7 passes after instruction 63, no load + for (uint sh = 0u; sh < 7u; ++sh) { + r5 = r5 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x8bc12da9u : 0x92199f99u); // s0 add + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x63079e5au : 0x8d72d3adu); // s1 add + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 2u); r6 = r6 ^ t_; } // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + ((((sel >> 31u) & 1u) != 0u) ? 0x5d4c7a60u : 0xb21b4babu); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + ((((sel >> 16u) & 1u) != 0u) ? 0xc88e2942u : 0x2fe0e98bu); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r6 = r6 ^ t_; } // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 4u); r2 = r2 ^ t_; } // s12 shfl + r1 = r1 + r5 + ((((sel >> 25u) & 1u) != 0u) ? 0xbc48c63eu : 0xbdf8f9a5u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r2 = r2 ^ t_; } // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + ((((sel >> 1u) & 1u) != 0u) ? 0x96e8f127u : 0x45c37cecu); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = mul_hi(r6, r0); // s28 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r2 = r2 ^ t_; } // s29 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r1 = r1 ^ t_; } // s30 shfl + r1 = r1 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0xb1cdb2abu : 0x37985632u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // s33 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r0 = r0 ^ t_; } // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x856e0180u : 0x804e777eu); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xe9bd0cc4u : 0x0b06c8a7u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = mul_hi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = mul_hi(r4, r3); // s44 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xcdcb63f6u : 0xee822e17u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r4 = r4 ^ t_; } // s47 shfl + r6 = mul_hi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0xd4758987u : 0x3dfad1b6u); // s56 add + r4 = r4 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x0602d6beu : 0xfca75bc2u); // s57 add + r5 = mul_hi(r5, r6); // s58 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r2 = r2 ^ t_; } // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0x8596687au : 0xd71c02ffu); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 2u); r7 = r7 ^ t_; } // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0x08ac5733u : 0x3c6fe15du); // s72 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r3 = r3 ^ t_; } // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + ((((sel >> 1u) & 1u) != 0u) ? 0xc100b495u : 0x295d5faeu); // s77 add + r3 = mul_hi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + ((((sel >> 15u) & 1u) != 0u) ? 0x5cc59530u : 0x274a9221u); // s81 add + r7 = r7 + r3 + ((((sel >> 5u) & 1u) != 0u) ? 0x141479ecu : 0xc8651f8eu); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r2 = r2 ^ t_; } // s85 shfl + r3 = r3 ^ r2; // s86 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 2u); r5 = r5 ^ t_; } // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x883c0c92u : 0x53f915c2u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + ((((sel >> 31u) & 1u) != 0u) ? 0x3cc5bd20u : 0xe2be00a5u); // s91 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 1u); r7 = r7 ^ t_; } // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + ((((sel >> 17u) & 1u) != 0u) ? 0xbfd646cbu : 0x423fd9c9u); // s101 add + r7 = r7 + r6 + ((((sel >> 11u) & 1u) != 0u) ? 0x19b74a43u : 0x8d3c011du); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + ((((sel >> 15u) & 1u) != 0u) ? 0x7dcb7e18u : 0x8ce14721u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = mul_hi(r2, r0); // s109 mulhi + r1 = mul_hi(r1, r0); // s110 mulhi + r0 = r0 + r2 + ((((sel >> 28u) & 1u) != 0u) ? 0x3c179ad8u : 0x2d9fc6b9u); // s111 add + r2 = mul_hi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + ((((sel >> 22u) & 1u) != 0u) ? 0x47359729u : 0x502138e2u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = mul_hi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 2u); r4 = r4 ^ t_; } // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r7 = r7 ^ t_; } // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x6c57e4e7u : 0x33dff776u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + ((((sel >> 30u) & 1u) != 0u) ? 0xe8212c0cu : 0x5db25b34u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = mul_hi(r0, r5); // s138 mulhi + r2 = r2 + r7 + ((((sel >> 10u) & 1u) != 0u) ? 0xd44ff710u : 0x218d4090u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r3 = r3 ^ t_; } // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + ((((sel >> 29u) & 1u) != 0u) ? 0xb98942fau : 0xf4b1a8deu); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + ((((sel >> 17u) & 1u) != 0u) ? 0x0d48ba42u : 0x2bef10f2u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + ((((sel >> 30u) & 1u) != 0u) ? 0xc98dea9cu : 0xdc5cc080u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0x6c752dcbu : 0x18197438u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + ((((sel >> 3u) & 1u) != 0u) ? 0x8e481727u : 0xf1c46574u); // s163 add + r0 = mul_hi(r0, r4); // s164 mulhi + r2 = r2 + r6 + ((((sel >> 20u) & 1u) != 0u) ? 0x550ab406u : 0xac578137u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + ((((sel >> 14u) & 1u) != 0u) ? 0xaebb5966u : 0xa33e6706u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 8u); r7 = r7 ^ t_; } // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x5bb7550fu : 0xd94d55acu); // s184 add + r3 = r3 | r5; // s185 or + r6 = mul_hi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r7 = r7 ^ t_; } // s188 shfl + r6 = r6 + r5 + ((((sel >> 6u) & 1u) != 0u) ? 0x2a354e2du : 0x89e747feu); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = mul_hi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r4 = r4 ^ t_; } // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + ((((sel >> 7u) & 1u) != 0u) ? 0x10cfdc71u : 0xea03e8e7u); // s197 add + r7 = r7 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x66e148d3u : 0xa7ee0102u); // s198 add + r5 = r5 - r2; // s199 sub + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r5 = r5 ^ t_; } // s200 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 8u); r7 = r7 ^ t_; } // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0x8558b619u : 0x8379a4deu); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = mul_hi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 4u); r2 = r2 ^ t_; } // s209 shfl + r7 = r7 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0xf4049c4cu : 0xaa8cb14eu); // s210 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 16u); r7 = r7 ^ t_; } // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 16u); r3 = r3 ^ t_; } // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = mul_hi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r5 = r5 ^ t_; } // s222 shfl + r5 = mul_hi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0x2a7fecb2u : 0x1d176220u); // s230 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r1 = r1 ^ t_; } // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + ((((sel >> 25u) & 1u) != 0u) ? 0xadce39f3u : 0x17dafb4du); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + ((((sel >> 29u) & 1u) != 0u) ? 0x0e7033b6u : 0xf2f77d26u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + ((((sel >> 31u) & 1u) != 0u) ? 0x7b2ff6b7u : 0xfed2da4eu); // s247 add + r0 = r0 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0xb5fad7b1u : 0x03b2891cu); // s248 add + r5 = mul_hi(r5, r4); // s249 mulhi + r5 = r5 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0xa7e71c2fu : 0x042cd6e3u); // s250 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 1u); r6 = r6 ^ t_; } // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0xb83d78deu : 0x784a302bu); // s254 add + r2 = r2 - r4; // s255 sub + } + } + uint lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((ulong)hi << 32) | (ulong)lo; +} diff --git a/proto-cuda/packs-ca3-shadow/sh256x7/kernel_bound.cu b/proto-cuda/packs-ca3-shadow/sh256x7/kernel_bound.cu new file mode 100644 index 000000000..8be9979c6 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x7/kernel_bound.cu @@ -0,0 +1,382 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Header-bound twin of igneum_hash in kernel.cu: the init words come from a kernel argument, not SEEDW. +// Host declarations (also in program_bound.h if present): +// struct IgneumInitWords { uint32_t w[8]; }; +// cudaError_t igneum_launch_hash_bound(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, +// IgneumInitWords iw, uint32_t nonces, uint32_t blockWarps); +// cudaError_t igneum_hash_bound_info(int* numRegs, int* blocksPerSM, uint32_t blockWarps); +#include +#include +#include "program.h" + +struct IgneumInitWords { uint32_t w[8]; }; + +__device__ __forceinline__ uint32_t splitmix32(uint32_t x) { + x ^= x >> 16; x *= 0x7feb352du; + x ^= x >> 15; x *= 0x846ca68bu; + x ^= x >> 16; + return x; +} +__device__ __forceinline__ uint32_t rotl_imm(uint32_t x, uint32_t n) { return (x << n) | (x >> (32u - n)); } +__device__ __forceinline__ uint32_t rotr_var(uint32_t x, uint32_t n) { n &= 31u; return (x >> n) | (x << ((32u - n) & 31u)); } + +__global__ void igneum_hash_bound(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, IgneumInitWords iw) { + uint32_t gid = blockIdx.x * blockDim.x + threadIdx.x; + uint32_t nonce = baseNonce + gid; + uint32_t r0, r1, r2, r3, r4, r5, r6, r7; + { uint32_t x = nonce ^ iw.w[0]; x += 0x9e3779b9u * 1u; x = splitmix32(x); r0 = x ^ iw.w[1]; } + { uint32_t x = nonce ^ iw.w[1]; x += 0x9e3779b9u * 2u; x = splitmix32(x); r1 = x ^ iw.w[2]; } + { uint32_t x = nonce ^ iw.w[2]; x += 0x9e3779b9u * 3u; x = splitmix32(x); r2 = x ^ iw.w[3]; } + { uint32_t x = nonce ^ iw.w[3]; x += 0x9e3779b9u * 4u; x = splitmix32(x); r3 = x ^ iw.w[4]; } + { uint32_t x = nonce ^ iw.w[4]; x += 0x9e3779b9u * 5u; x = splitmix32(x); r4 = x ^ iw.w[5]; } + { uint32_t x = nonce ^ iw.w[5]; x += 0x9e3779b9u * 6u; x = splitmix32(x); r5 = x ^ iw.w[6]; } + { uint32_t x = nonce ^ iw.w[6]; x += 0x9e3779b9u * 7u; x = splitmix32(x); r6 = x ^ iw.w[7]; } + { uint32_t x = nonce ^ iw.w[7]; x += 0x9e3779b9u * 8u; x = splitmix32(x); r7 = x ^ iw.w[0]; } + + for (uint32_t it = 0u; it < 8u; ++it) { + uint32_t sel = r0; + r2 = r3 * r4 + r2; // 0 mad + r2 = r1 * r1 + r2; // 1 mad + r2 = r3 * r2 + r2; // 2 mad + r3 = r3 ^ r5; // 3 xor + r7 = r7 ^ ds[r2 & mask]; // 4 load + r5 = r5 ^ ds[r7 & mask]; // 5 load + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r4, 8); // 6 shfl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r3, 8); // 7 shfl + r1 = __umulhi(r1, r5); // 8 mulhi + r6 = rotr_var(r6, r3); // 9 rotr + r3 = r3 | r4; // 10 or + r4 = r4 ^ ds[r3 & mask]; // 11 load + r0 = __umulhi(r0, r4); // 12 mulhi + r5 = r5 + r1 + ((((sel >> 30u) & 1u) != 0u) ? 0xd3177981u : 0xc7934706u); // 13 add + r0 = r0 ^ ds[r4 & mask]; // 14 load + r2 = r2 - r4; // 15 sub + r2 = r2 ^ ds[r0 & mask]; // 16 load + r7 = r7 ^ ds[r2 & mask]; // 17 load + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r3, 4); // 18 shfl + r5 = r5 * r0; // 19 mul + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // 20 shfl + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 16); // 21 shfl + r6 = __umulhi(r6, r2); // 22 mulhi + r6 = r6 ^ ds[r1 & mask]; // 23 load + r5 = r5 * r0; // 24 mul + r5 = rotl_imm(r5, 19u); // 25 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r6, 2); // 26 shfl + r0 = r0 ^ r5; // 27 xor + r0 = r0 ^ r4; // 28 xor + r3 = r3 - r0; // 29 sub + r5 = r5 * r1; // 30 mul + r7 = r7 ^ ds[r2 & mask]; // 31 load + r1 = r1 ^ ds[r0 & mask]; // 32 load + r5 = r5 ^ r6; // 33 xor + r5 = r5 ^ ds[r1 & mask]; // 34 load + r0 = __umulhi(r0, r5); // 35 mulhi + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // 36 shfl + r7 = r7 ^ ds[r0 & mask]; // 37 load + r3 = r3 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0x230c005cu : 0x75ba2fadu); // 38 add + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r5, 4); // 39 shfl + r2 = r2 ^ r5; // 40 xor + r3 = r6 * r3 + r3; // 41 mad + r6 = r6 - r7; // 42 sub + r7 = r7 ^ r0; // 43 xor + r1 = r1 ^ ds[r7 & mask]; // 44 load + r2 = r2 * r3; // 45 mul + r1 = __umulhi(r1, r5); // 46 mulhi + r4 = r4 - r3; // 47 sub + r2 = rotr_var(r2, r6); // 48 rotr + r3 = r3 ^ ds[r5 & mask]; // 49 load + r1 = r1 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x1907970cu : 0x81b8bc2cu); // 50 add + r0 = r0 * r2; // 51 mul + r0 = r0 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x699fd448u : 0x4f92b968u); // 52 add + r1 = r1 + r0 + ((((sel >> 12u) & 1u) != 0u) ? 0x77b1520du : 0x2bb965afu); // 53 add + r7 = rotl_imm(r7, 14u); // 54 rotl + r3 = r3 + r7 + ((((sel >> 1u) & 1u) != 0u) ? 0xa54c55a0u : 0x7b0fe07au); // 55 add + r6 = r6 ^ ds[r7 & mask]; // 56 load + r1 = rotr_var(r1, r5); // 57 rotr + r5 = r5 ^ ds[r4 & mask]; // 58 load + r6 = r6 ^ ds[r2 & mask]; // 59 load + r3 = r5 * r0 + r3; // 60 mad + r5 = r5 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0xad7493e7u : 0xaf9dd72du); // 61 add + r4 = r4 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x1e07c3d9u : 0x89841d87u); // 62 add + r5 = rotl_imm(r5, 19u); // 63 rotl + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 7 passes after instruction 63, no load + for (uint32_t sh = 0u; sh < 7u; ++sh) { + r5 = r5 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x8bc12da9u : 0x92199f99u); // s0 add + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x63079e5au : 0x8d72d3adu); // s1 add + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r3, 2); // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + ((((sel >> 31u) & 1u) != 0u) ? 0x5d4c7a60u : 0xb21b4babu); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + ((((sel >> 16u) & 1u) != 0u) ? 0xc88e2942u : 0x2fe0e98bu); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r1, 4); // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r6, 4); // s12 shfl + r1 = r1 + r5 + ((((sel >> 25u) & 1u) != 0u) ? 0xbc48c63eu : 0xbdf8f9a5u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 8); // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + ((((sel >> 1u) & 1u) != 0u) ? 0x96e8f127u : 0x45c37cecu); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = __umulhi(r6, r0); // s28 mulhi + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // s29 shfl + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r6, 1); // s30 shfl + r1 = r1 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0xb1cdb2abu : 0x37985632u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // s33 shfl + r0 = r0 ^ __shfl_xor_sync(0xffffffffu, r3, 4); // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x856e0180u : 0x804e777eu); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xe9bd0cc4u : 0x0b06c8a7u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = __umulhi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = __umulhi(r4, r3); // s44 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xcdcb63f6u : 0xee822e17u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r3, 8); // s47 shfl + r6 = __umulhi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0xd4758987u : 0x3dfad1b6u); // s56 add + r4 = r4 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x0602d6beu : 0xfca75bc2u); // s57 add + r5 = __umulhi(r5, r6); // s58 mulhi + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0x8596687au : 0xd71c02ffu); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r5, 2); // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0x08ac5733u : 0x3c6fe15du); // s72 add + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r2, 8); // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + ((((sel >> 1u) & 1u) != 0u) ? 0xc100b495u : 0x295d5faeu); // s77 add + r3 = __umulhi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + ((((sel >> 15u) & 1u) != 0u) ? 0x5cc59530u : 0x274a9221u); // s81 add + r7 = r7 + r3 + ((((sel >> 5u) & 1u) != 0u) ? 0x141479ecu : 0xc8651f8eu); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r5, 16); // s85 shfl + r3 = r3 ^ r2; // s86 xor + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r7, 2); // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x883c0c92u : 0x53f915c2u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + ((((sel >> 31u) & 1u) != 0u) ? 0x3cc5bd20u : 0xe2be00a5u); // s91 add + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r2, 1); // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + ((((sel >> 17u) & 1u) != 0u) ? 0xbfd646cbu : 0x423fd9c9u); // s101 add + r7 = r7 + r6 + ((((sel >> 11u) & 1u) != 0u) ? 0x19b74a43u : 0x8d3c011du); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + ((((sel >> 15u) & 1u) != 0u) ? 0x7dcb7e18u : 0x8ce14721u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = __umulhi(r2, r0); // s109 mulhi + r1 = __umulhi(r1, r0); // s110 mulhi + r0 = r0 + r2 + ((((sel >> 28u) & 1u) != 0u) ? 0x3c179ad8u : 0x2d9fc6b9u); // s111 add + r2 = __umulhi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + ((((sel >> 22u) & 1u) != 0u) ? 0x47359729u : 0x502138e2u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = __umulhi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r2, 2); // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x6c57e4e7u : 0x33dff776u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + ((((sel >> 30u) & 1u) != 0u) ? 0xe8212c0cu : 0x5db25b34u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = __umulhi(r0, r5); // s138 mulhi + r2 = r2 + r7 + ((((sel >> 10u) & 1u) != 0u) ? 0xd44ff710u : 0x218d4090u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r6, 1); // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + ((((sel >> 29u) & 1u) != 0u) ? 0xb98942fau : 0xf4b1a8deu); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + ((((sel >> 17u) & 1u) != 0u) ? 0x0d48ba42u : 0x2bef10f2u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + ((((sel >> 30u) & 1u) != 0u) ? 0xc98dea9cu : 0xdc5cc080u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0x6c752dcbu : 0x18197438u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + ((((sel >> 3u) & 1u) != 0u) ? 0x8e481727u : 0xf1c46574u); // s163 add + r0 = __umulhi(r0, r4); // s164 mulhi + r2 = r2 + r6 + ((((sel >> 20u) & 1u) != 0u) ? 0x550ab406u : 0xac578137u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + ((((sel >> 14u) & 1u) != 0u) ? 0xaebb5966u : 0xa33e6706u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r0, 8); // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x5bb7550fu : 0xd94d55acu); // s184 add + r3 = r3 | r5; // s185 or + r6 = __umulhi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s188 shfl + r6 = r6 + r5 + ((((sel >> 6u) & 1u) != 0u) ? 0x2a354e2du : 0x89e747feu); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = __umulhi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r5, 16); // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + ((((sel >> 7u) & 1u) != 0u) ? 0x10cfdc71u : 0xea03e8e7u); // s197 add + r7 = r7 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x66e148d3u : 0xa7ee0102u); // s198 add + r5 = r5 - r2; // s199 sub + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s200 shfl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 8); // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0x8558b619u : 0x8379a4deu); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = __umulhi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r0, 4); // s209 shfl + r7 = r7 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0xf4049c4cu : 0xaa8cb14eu); // s210 add + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 16); // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r2, 16); // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = __umulhi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r2, 8); // s222 shfl + r5 = __umulhi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0x2a7fecb2u : 0x1d176220u); // s230 add + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + ((((sel >> 25u) & 1u) != 0u) ? 0xadce39f3u : 0x17dafb4du); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + ((((sel >> 29u) & 1u) != 0u) ? 0x0e7033b6u : 0xf2f77d26u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + ((((sel >> 31u) & 1u) != 0u) ? 0x7b2ff6b7u : 0xfed2da4eu); // s247 add + r0 = r0 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0xb5fad7b1u : 0x03b2891cu); // s248 add + r5 = __umulhi(r5, r4); // s249 mulhi + r5 = r5 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0xa7e71c2fu : 0x042cd6e3u); // s250 add + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r1, 1); // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0xb83d78deu : 0x784a302bu); // s254 add + r2 = r2 - r4; // s255 sub + } + } + uint32_t lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint32_t hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((uint64_t)hi << 32) | (uint64_t)lo; +} + +cudaError_t igneum_launch_hash_bound(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, + IgneumInitWords iw, uint32_t nonces, uint32_t blockWarps) { + if (blockWarps == 0u || blockWarps > 32u) return cudaErrorInvalidValue; + uint32_t block = 32u * blockWarps; + if (nonces == 0u || (nonces % block) != 0u) return cudaErrorInvalidValue; + igneum_hash_bound<<>>(ds, out, baseNonce, mask, iw); + return cudaGetLastError(); +} + +cudaError_t igneum_hash_bound_info(int* numRegs, int* blocksPerSM, uint32_t blockWarps) { + cudaFuncAttributes attr; + cudaError_t e = cudaFuncGetAttributes(&attr, igneum_hash_bound); + if (e != cudaSuccess) return e; + *numRegs = attr.numRegs; + return cudaOccupancyMaxActiveBlocksPerMultiprocessor(blocksPerSM, igneum_hash_bound, (int)(32u * blockWarps), 0); +} diff --git a/proto-cuda/packs-ca3-shadow/sh256x7/memhard.h b/proto-cuda/packs-ca3-shadow/sh256x7/memhard.h new file mode 100644 index 000000000..f7f34c732 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x7/memhard.h @@ -0,0 +1,109 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Memory-hard dataset core, the same text that the Mac's Metal kernels and CPU verifier were checked against. +// Included by kernel.cu (device), host.cu (host reference) and proto-opencl/host.c (C99 host reference). +// See proto-metal/MEMHARD.md for the construction. kernel.cl carries the same text in OpenCL C. +#pragma once +#ifdef __cplusplus +#include +#else +#include +#endif +#if defined(__CUDACC__) +#define IGNEUM_HD __host__ __device__ __forceinline__ +#elif defined(_MSC_VER) && !defined(__cplusplus) +#define IGNEUM_HD static __inline +#else +#define IGNEUM_HD static inline +#endif +// Memory-hard dataset core (MEMHARD.md). Cache: 2^26 words in 2^16 segments of 64 chained ChaCha12 lines. +// Item: 8 rounds of 8 x seed-parameterised mixer + one 64-byte cache read, then 8 x final mixer (class v3, mixer multiplier 8, +// docs/plans/mixer-x4.md: the round key of application j of round r is 0x9E3779B9 * (r * m + j + 1)). All parameters are literals. +#define MH_CACHE_LINE_MASK 0x003fffffu +#define MH_SEGMENT_LINES 64u +#define MH_QR(a, b, c, d, r1, r2, r3, r4) { a += b; d ^= a; d = mh_rotl(d, r1); c += d; b ^= c; b = mh_rotl(b, r2); a += b; d ^= a; d = mh_rotl(d, r3); c += d; b ^= c; b = mh_rotl(b, r4); } +IGNEUM_HD uint32_t mh_rotl(uint32_t x, uint32_t n) { return (x << n) | (x >> (32u - n)); } // n in 1..31 at every call site + +// y = ChaCha12 core(x) + x +IGNEUM_HD void mh_chacha_block(const uint32_t* x, uint32_t* y) { + for (uint32_t i = 0u; i < 16u; ++i) y[i] = x[i]; + for (uint32_t r = 0u; r < 6u; ++r) { + MH_QR(y[0], y[4], y[8], y[12], 16u, 12u, 8u, 7u) MH_QR(y[1], y[5], y[9], y[13], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[6], y[10], y[14], 16u, 12u, 8u, 7u) MH_QR(y[3], y[7], y[11], y[15], 16u, 12u, 8u, 7u) + MH_QR(y[0], y[5], y[10], y[15], 16u, 12u, 8u, 7u) MH_QR(y[1], y[6], y[11], y[12], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[7], y[8], y[13], 16u, 12u, 8u, 7u) MH_QR(y[3], y[4], y[9], y[14], 16u, 12u, 8u, 7u) + } + for (uint32_t i = 0u; i < 16u; ++i) y[i] += x[i]; +} + +// One cache segment: 64 chained lines written at cache[seg * 1024]. in_j = prev ^ (sigma || K || seg || j || tag), prev_0 = 0. +IGNEUM_HD void mh_cache_segment(uint32_t* cache, uint32_t seg) { + uint32_t prev[16]; uint32_t x[16]; uint32_t y[16]; + for (uint32_t i = 0u; i < 16u; ++i) prev[i] = 0u; + for (uint32_t j = 0u; j < MH_SEGMENT_LINES; ++j) { + x[0] = 0x61707865u ^ prev[0]; x[1] = 0x3320646eu ^ prev[1]; x[2] = 0x79622d32u ^ prev[2]; x[3] = 0x6b206574u ^ prev[3]; + x[4] = 0x3067619fu ^ prev[4]; + x[5] = 0x3c269176u ^ prev[5]; + x[6] = 0x84a03b03u ^ prev[6]; + x[7] = 0xf8c63294u ^ prev[7]; + x[8] = 0xff977c5bu ^ prev[8]; + x[9] = 0xe60def3eu ^ prev[9]; + x[10] = 0x63630141u ^ prev[10]; + x[11] = 0xb8fbcb58u ^ prev[11]; + x[12] = seg ^ prev[12]; x[13] = j ^ prev[13]; x[14] = 0x49676e65u ^ prev[14]; x[15] = 0x756d4d48u ^ prev[15]; + mh_chacha_block(x, y); + uint32_t* line = cache + ((seg * MH_SEGMENT_LINES + j) * 16u); + for (uint32_t i = 0u; i < 16u; ++i) { line[i] = y[i]; prev[i] = y[i]; } + } +} + +// M_r: per word (s ^ (RC + rk)) * MUL, then a column round and a diagonal round with the seed-drawn rotations. +IGNEUM_HD void mh_mixer(uint32_t* s, uint32_t rk) { + s[0] = (s[0] ^ (0xbab68293u + rk)) * 0x42146205u; + s[1] = (s[1] ^ (0xcc162340u + rk)) * 0x52cbe0fbu; + s[2] = (s[2] ^ (0x6ce151ccu + rk)) * 0x7ecf4a03u; + s[3] = (s[3] ^ (0xe62b8997u + rk)) * 0x6728907fu; + s[4] = (s[4] ^ (0xc9c80297u + rk)) * 0xd81d9751u; + s[5] = (s[5] ^ (0xf74a1654u + rk)) * 0x132952c3u; + s[6] = (s[6] ^ (0x3d704af5u + rk)) * 0xf60de277u; + s[7] = (s[7] ^ (0x3cf522b7u + rk)) * 0x05358035u; + s[8] = (s[8] ^ (0x2b9cac04u + rk)) * 0xbaf6499du; + s[9] = (s[9] ^ (0xa880ac10u + rk)) * 0xe4db9667u; + s[10] = (s[10] ^ (0x13e5dd1du + rk)) * 0x3e98f45du; + s[11] = (s[11] ^ (0x6fc3e233u + rk)) * 0xd0004eddu; + s[12] = (s[12] ^ (0x2d83eeacu + rk)) * 0x2691630du; + s[13] = (s[13] ^ (0x9006e8bfu + rk)) * 0x9beb3bcfu; + s[14] = (s[14] ^ (0x2c4b5362u + rk)) * 0xab310379u; + s[15] = (s[15] ^ (0x31b49ee2u + rk)) * 0x99cfb423u; + MH_QR(s[0], s[4], s[8], s[12], 20u, 20u, 19u, 4u) MH_QR(s[1], s[5], s[9], s[13], 20u, 20u, 19u, 4u) + MH_QR(s[2], s[6], s[10], s[14], 20u, 20u, 19u, 4u) MH_QR(s[3], s[7], s[11], s[15], 20u, 20u, 19u, 4u) + MH_QR(s[0], s[5], s[10], s[15], 26u, 3u, 3u, 27u) MH_QR(s[1], s[6], s[11], s[12], 26u, 3u, 3u, 27u) + MH_QR(s[2], s[7], s[8], s[13], 26u, 3u, 3u, 27u) MH_QR(s[3], s[4], s[9], s[14], 26u, 3u, 3u, 27u) +} + +// Item t: 16 words. s = (K, t * MUL[i] + RC[i]); 8 rounds of 8 x mixer + cache line s[0] & mask; 8 x final mixer. +IGNEUM_HD void mh_item(const uint32_t* cache, uint32_t t, uint32_t* s) { + s[0] = 0x3067619fu; + s[1] = 0x3c269176u; + s[2] = 0x84a03b03u; + s[3] = 0xf8c63294u; + s[4] = 0xff977c5bu; + s[5] = 0xe60def3eu; + s[6] = 0x63630141u; + s[7] = 0xb8fbcb58u; + s[8] = t * 0x42146205u + 0xbab68293u; + s[9] = t * 0x52cbe0fbu + 0xcc162340u; + s[10] = t * 0x7ecf4a03u + 0x6ce151ccu; + s[11] = t * 0x6728907fu + 0xe62b8997u; + s[12] = t * 0xd81d9751u + 0xc9c80297u; + s[13] = t * 0x132952c3u + 0xf74a1654u; + s[14] = t * 0xf60de277u + 0x3d704af5u; + s[15] = t * 0x05358035u + 0x3cf522b7u; + for (uint32_t r = 0u; r < 8u; ++r) { + for (uint32_t j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (r * 8u + j + 1u)); + const uint32_t* line = cache + ((s[0] & MH_CACHE_LINE_MASK) * 16u); + for (uint32_t i = 0u; i < 16u; ++i) s[i] ^= line[i]; + } + for (uint32_t j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (64u + j + 1u)); +} +// dataset[w] without the dataset: derive item w >> 4 and take word w & 15. +IGNEUM_HD uint32_t mh_word(const uint32_t* cache, uint32_t w) { uint32_t s[16]; mh_item(cache, w >> 4u, s); return s[w & 15u]; } diff --git a/proto-cuda/packs-ca3-shadow/sh256x7/memhard.metal b/proto-cuda/packs-ca3-shadow/sh256x7/memhard.metal new file mode 100644 index 000000000..01b263d6d --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x7/memhard.metal @@ -0,0 +1,107 @@ +#include +using namespace metal; +// Memory-hard dataset core (MEMHARD.md). Cache: 2^26 words in 2^16 segments of 64 chained ChaCha12 lines. +// Item: 8 rounds of 8 x seed-parameterised mixer + one 64-byte cache read, then 8 x final mixer (class v3, mixer multiplier 8, +// docs/plans/mixer-x4.md: the round key of application j of round r is 0x9E3779B9 * (r * m + j + 1)). All parameters are literals. +#define MH_CACHE_LINE_MASK 0x003fffffu +#define MH_SEGMENT_LINES 64u +#define MH_QR(a, b, c, d, r1, r2, r3, r4) { a += b; d ^= a; d = mh_rotl(d, r1); c += d; b ^= c; b = mh_rotl(b, r2); a += b; d ^= a; d = mh_rotl(d, r3); c += d; b ^= c; b = mh_rotl(b, r4); } +inline uint mh_rotl(uint x, uint n) { return (x << n) | (x >> (32u - n)); } // n in 1..31 at every call site + +// y = ChaCha12 core(x) + x +inline void mh_chacha_block(const thread uint* x, thread uint* y) { + for (uint i = 0u; i < 16u; ++i) y[i] = x[i]; + for (uint r = 0u; r < 6u; ++r) { + MH_QR(y[0], y[4], y[8], y[12], 16u, 12u, 8u, 7u) MH_QR(y[1], y[5], y[9], y[13], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[6], y[10], y[14], 16u, 12u, 8u, 7u) MH_QR(y[3], y[7], y[11], y[15], 16u, 12u, 8u, 7u) + MH_QR(y[0], y[5], y[10], y[15], 16u, 12u, 8u, 7u) MH_QR(y[1], y[6], y[11], y[12], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[7], y[8], y[13], 16u, 12u, 8u, 7u) MH_QR(y[3], y[4], y[9], y[14], 16u, 12u, 8u, 7u) + } + for (uint i = 0u; i < 16u; ++i) y[i] += x[i]; +} + +// One cache segment: 64 chained lines written at cache[seg * 1024]. in_j = prev ^ (sigma || K || seg || j || tag), prev_0 = 0. +inline void mh_cache_segment(device uint* cache, uint seg) { + uint prev[16]; uint x[16]; uint y[16]; + for (uint i = 0u; i < 16u; ++i) prev[i] = 0u; + for (uint j = 0u; j < MH_SEGMENT_LINES; ++j) { + x[0] = 0x61707865u ^ prev[0]; x[1] = 0x3320646eu ^ prev[1]; x[2] = 0x79622d32u ^ prev[2]; x[3] = 0x6b206574u ^ prev[3]; + x[4] = 0x3067619fu ^ prev[4]; + x[5] = 0x3c269176u ^ prev[5]; + x[6] = 0x84a03b03u ^ prev[6]; + x[7] = 0xf8c63294u ^ prev[7]; + x[8] = 0xff977c5bu ^ prev[8]; + x[9] = 0xe60def3eu ^ prev[9]; + x[10] = 0x63630141u ^ prev[10]; + x[11] = 0xb8fbcb58u ^ prev[11]; + x[12] = seg ^ prev[12]; x[13] = j ^ prev[13]; x[14] = 0x49676e65u ^ prev[14]; x[15] = 0x756d4d48u ^ prev[15]; + mh_chacha_block(x, y); + device uint* line = cache + ((seg * MH_SEGMENT_LINES + j) * 16u); + for (uint i = 0u; i < 16u; ++i) { line[i] = y[i]; prev[i] = y[i]; } + } +} + +// M_r: per word (s ^ (RC + rk)) * MUL, then a column round and a diagonal round with the seed-drawn rotations. +inline void mh_mixer(thread uint* s, uint rk) { + s[0] = (s[0] ^ (0xbab68293u + rk)) * 0x42146205u; + s[1] = (s[1] ^ (0xcc162340u + rk)) * 0x52cbe0fbu; + s[2] = (s[2] ^ (0x6ce151ccu + rk)) * 0x7ecf4a03u; + s[3] = (s[3] ^ (0xe62b8997u + rk)) * 0x6728907fu; + s[4] = (s[4] ^ (0xc9c80297u + rk)) * 0xd81d9751u; + s[5] = (s[5] ^ (0xf74a1654u + rk)) * 0x132952c3u; + s[6] = (s[6] ^ (0x3d704af5u + rk)) * 0xf60de277u; + s[7] = (s[7] ^ (0x3cf522b7u + rk)) * 0x05358035u; + s[8] = (s[8] ^ (0x2b9cac04u + rk)) * 0xbaf6499du; + s[9] = (s[9] ^ (0xa880ac10u + rk)) * 0xe4db9667u; + s[10] = (s[10] ^ (0x13e5dd1du + rk)) * 0x3e98f45du; + s[11] = (s[11] ^ (0x6fc3e233u + rk)) * 0xd0004eddu; + s[12] = (s[12] ^ (0x2d83eeacu + rk)) * 0x2691630du; + s[13] = (s[13] ^ (0x9006e8bfu + rk)) * 0x9beb3bcfu; + s[14] = (s[14] ^ (0x2c4b5362u + rk)) * 0xab310379u; + s[15] = (s[15] ^ (0x31b49ee2u + rk)) * 0x99cfb423u; + MH_QR(s[0], s[4], s[8], s[12], 20u, 20u, 19u, 4u) MH_QR(s[1], s[5], s[9], s[13], 20u, 20u, 19u, 4u) + MH_QR(s[2], s[6], s[10], s[14], 20u, 20u, 19u, 4u) MH_QR(s[3], s[7], s[11], s[15], 20u, 20u, 19u, 4u) + MH_QR(s[0], s[5], s[10], s[15], 26u, 3u, 3u, 27u) MH_QR(s[1], s[6], s[11], s[12], 26u, 3u, 3u, 27u) + MH_QR(s[2], s[7], s[8], s[13], 26u, 3u, 3u, 27u) MH_QR(s[3], s[4], s[9], s[14], 26u, 3u, 3u, 27u) +} + +// Item t: 16 words. s = (K, t * MUL[i] + RC[i]); 8 rounds of 8 x mixer + cache line s[0] & mask; 8 x final mixer. +inline void mh_item(device const uint* cache, uint t, thread uint* s) { + s[0] = 0x3067619fu; + s[1] = 0x3c269176u; + s[2] = 0x84a03b03u; + s[3] = 0xf8c63294u; + s[4] = 0xff977c5bu; + s[5] = 0xe60def3eu; + s[6] = 0x63630141u; + s[7] = 0xb8fbcb58u; + s[8] = t * 0x42146205u + 0xbab68293u; + s[9] = t * 0x52cbe0fbu + 0xcc162340u; + s[10] = t * 0x7ecf4a03u + 0x6ce151ccu; + s[11] = t * 0x6728907fu + 0xe62b8997u; + s[12] = t * 0xd81d9751u + 0xc9c80297u; + s[13] = t * 0x132952c3u + 0xf74a1654u; + s[14] = t * 0xf60de277u + 0x3d704af5u; + s[15] = t * 0x05358035u + 0x3cf522b7u; + for (uint r = 0u; r < 8u; ++r) { + for (uint j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (r * 8u + j + 1u)); + device const uint* line = cache + ((s[0] & MH_CACHE_LINE_MASK) * 16u); + for (uint i = 0u; i < 16u; ++i) s[i] ^= line[i]; + } + for (uint j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (64u + j + 1u)); +} +// dataset[w] without the dataset: derive item w >> 4 and take word w & 15. +inline uint mh_word(device const uint* cache, uint w) { uint s[16]; mh_item(cache, w >> 4u, s); return s[w & 15u]; } + +// One thread per segment (2^16 threads). +kernel void igneum_cache_fill(device uint* cache [[buffer(0)]], uint gid [[thread_position_in_grid]]) { + mh_cache_segment(cache, gid); +} +// One thread per 64-byte item (dataset words / 16 threads). +kernel void igneum_build(device const uint* cache [[buffer(0)]], device uint* dataset [[buffer(1)]], + uint gid [[thread_position_in_grid]]) { + uint s[16]; + mh_item(cache, gid, s); + device uint* d = dataset + gid * 16u; + for (uint i = 0u; i < 16u; ++i) d[i] = s[i]; +} diff --git a/proto-cuda/packs-ca3-shadow/sh256x7/program.h b/proto-cuda/packs-ca3-shadow/sh256x7/program.h new file mode 100644 index 000000000..20110e1ae --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x7/program.h @@ -0,0 +1,70 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Program metadata for host.cu plus the launch wrappers defined in kernel.cu. +// Also included by proto-opencl/host.c (C99), which defines IGNEUM_NO_CUDA first and reads only the macros. +#pragma once +#ifdef __cplusplus +#include +#else +#include +#endif +#ifndef IGNEUM_NO_CUDA +#include +#endif + +#define IGNEUM_SEED_STRING "igneum-genesis" +#define IGNEUM_SEED_BYTES_HEX "69676e65756d2d67656e65736973" +#define IGNEUM_GENERATOR 2 +#define IGNEUM_PROGRAM_ATTEMPT 0 +#define IGNEUM_PROGRAM_ID 0x9a477f853aefcc76ull +#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 add=8 shfl=8 xor=6 mad=5 mul=5 mulhi=5 sub=4 rotl=3 rotr=3 or=1" +// 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+sh256x7" +#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 7 +#define IGNEUM_SHADOW_INSTRS_PER_HASH 14336 +#define IGNEUM_SHADOW_OP_MIX "add=47 rotl=30 xor=30 shfl=29 mad=27 mul=22 sub=21 rotr=20 mulhi=18 or=12" +// 0 = closed-form dataset (ds_elem), 1 = memory-hard cache construction (MEMHARD.md, memhard.h) +#define IGNEUM_DATASET_MODE 1 + +#define IGNEUM_SEEDW_INIT { 0x67a9a7beu, 0x1a155b25u, 0xfddfb732u, 0x4b5af2e8u, 0xc55caf33u, 0xa27c13b7u, 0x06628a48u, 0x03852469u } +#define IGNEUM_KEY_INIT { 0x3067619fu, 0x3c269176u, 0x84a03b03u, 0xf8c63294u, 0xff977c5bu, 0xe60def3eu, 0x63630141u, 0xb8fbcb58u } +#define IGNEUM_CACHE_LOG2_WORDS 26 +#define IGNEUM_CACHE_SEGMENT_LOG2_LINES 6 +#define IGNEUM_CACHE_SEGMENTS 65536u +#define IGNEUM_ITEM_ROUNDS 8 +#define IGNEUM_MIXER_MULT 8 // mixer applications per round and after the last read (class v3, docs/plans/mixer-x4.md) +#define IGNEUM_MIX_ROT_INIT { 20u, 20u, 19u, 4u, 26u, 3u, 3u, 27u } +#define IGNEUM_MIX_MUL_INIT { 0x42146205u, 0x52cbe0fbu, 0x7ecf4a03u, 0x6728907fu, 0xd81d9751u, 0x132952c3u, 0xf60de277u, 0x05358035u, 0xbaf6499du, 0xe4db9667u, 0x3e98f45du, 0xd0004eddu, 0x2691630du, 0x9beb3bcfu, 0xab310379u, 0x99cfb423u } +#define IGNEUM_MIX_RC_INIT { 0xbab68293u, 0xcc162340u, 0x6ce151ccu, 0xe62b8997u, 0xc9c80297u, 0xf74a1654u, 0x3d704af5u, 0x3cf522b7u, 0x2b9cac04u, 0xa880ac10u, 0x13e5dd1du, 0x6fc3e233u, 0x2d83eeacu, 0x9006e8bfu, 0x2c4b5362u, 0x31b49ee2u } + +#ifndef IGNEUM_NO_CUDA +// Defined in kernel.cu. All launch on the default stream and return cudaGetLastError(). +cudaError_t igneum_launch_cache_fill(uint32_t* cache, uint32_t nSegments); +cudaError_t igneum_launch_build(uint32_t* ds, const uint32_t* cache, uint32_t nItems); +cudaError_t igneum_launch_hash(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, + uint32_t nonces, uint32_t blockWarps); +cudaError_t igneum_hash_info(int* numRegs, int* blocksPerSM, uint32_t blockWarps); +#endif diff --git a/proto-cuda/packs-ca3-shadow/sh256x7/program.json b/proto-cuda/packs-ca3-shadow/sh256x7/program.json new file mode 100644 index 000000000..8758bb590 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x7/program.json @@ -0,0 +1,389 @@ +{ + "format": "igneum-program-pack-3", + "generator": 2, + "attempt": 0, + "program_id": "0x9a477f853aefcc76", + "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": ["0x67a9a7be", "0x1a155b25", "0xfddfb732", "0x4b5af2e8", "0xc55caf33", "0xa27c13b7", "0x06628a48", "0x03852469"], + "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+sh256x7", + "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, "add": 8, "shfl": 8, "xor": 6, "mad": 5, "mul": 5, "mulhi": 5, "sub": 4, "rotl": 3, "rotr": 3, "or": 1}, + "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": 7, "instrs_per_hash": 14336, "op_mix": {"add": 47, "rotl": 30, "xor": 30, "shfl": 29, "mad": 27, "mul": 22, "sub": 21, "rotr": 20, "mulhi": 18, "or": 12}, "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": "add", "dst": 5, "src": 2, "src2": 1, "imm": "0x92199f99", "imm2": "0x8bc12da9", "rot": 9, "bit": 18, "mask": 4}, + {"i": 1, "op": "add", "dst": 0, "src": 7, "src2": 1, "imm": "0x8d72d3ad", "imm2": "0x63079e5a", "rot": 20, "bit": 26, "mask": 4}, + {"i": 2, "op": "shfl", "dst": 6, "src": 3, "src2": 6, "imm": "0x9beaeddf", "imm2": "0x744ecb00", "rot": 10, "bit": 4, "mask": 2}, + {"i": 3, "op": "sub", "dst": 4, "src": 2, "src2": 0, "imm": "0x2a3ddc67", "imm2": "0x72c80241", "rot": 30, "bit": 1, "mask": 16}, + {"i": 4, "op": "add", "dst": 7, "src": 0, "src2": 5, "imm": "0xb21b4bab", "imm2": "0x5d4c7a60", "rot": 17, "bit": 31, "mask": 4}, + {"i": 5, "op": "rotl", "dst": 0, "src": 6, "src2": 3, "imm": "0xe69d7919", "imm2": "0xa048c61e", "rot": 11, "bit": 1, "mask": 8}, + {"i": 6, "op": "add", "dst": 0, "src": 1, "src2": 3, "imm": "0x2fe0e98b", "imm2": "0xc88e2942", "rot": 5, "bit": 16, "mask": 16}, + {"i": 7, "op": "xor", "dst": 7, "src": 1, "src2": 0, "imm": "0xc16efe98", "imm2": "0x01a638c8", "rot": 8, "bit": 17, "mask": 1}, + {"i": 8, "op": "mad", "dst": 1, "src": 6, "src2": 5, "imm": "0x76ec7b8b", "imm2": "0x25663feb", "rot": 29, "bit": 30, "mask": 2}, + {"i": 9, "op": "shfl", "dst": 6, "src": 1, "src2": 0, "imm": "0x6c8ee3cb", "imm2": "0xea93237e", "rot": 27, "bit": 1, "mask": 4}, + {"i": 10, "op": "mad", "dst": 1, "src": 2, "src2": 2, "imm": "0x6dc4ea18", "imm2": "0x6efde6f5", "rot": 3, "bit": 20, "mask": 2}, + {"i": 11, "op": "mad", "dst": 5, "src": 0, "src2": 3, "imm": "0x023613fc", "imm2": "0x18c51939", "rot": 19, "bit": 31, "mask": 1}, + {"i": 12, "op": "shfl", "dst": 2, "src": 6, "src2": 1, "imm": "0x74aec8d2", "imm2": "0x7f7ad29c", "rot": 7, "bit": 8, "mask": 4}, + {"i": 13, "op": "add", "dst": 1, "src": 5, "src2": 6, "imm": "0xbdf8f9a5", "imm2": "0xbc48c63e", "rot": 6, "bit": 25, "mask": 2}, + {"i": 14, "op": "rotl", "dst": 1, "src": 2, "src2": 6, "imm": "0x7ad8ca8b", "imm2": "0x14c712ad", "rot": 29, "bit": 25, "mask": 8}, + {"i": 15, "op": "sub", "dst": 1, "src": 4, "src2": 5, "imm": "0xd3349f69", "imm2": "0x70aac45a", "rot": 29, "bit": 9, "mask": 16}, + {"i": 16, "op": "or", "dst": 7, "src": 1, "src2": 2, "imm": "0x08168ed1", "imm2": "0x28964037", "rot": 26, "bit": 0, "mask": 2}, + {"i": 17, "op": "shfl", "dst": 2, "src": 4, "src2": 6, "imm": "0x98d85f72", "imm2": "0x3dc87042", "rot": 29, "bit": 22, "mask": 8}, + {"i": 18, "op": "xor", "dst": 7, "src": 4, "src2": 0, "imm": "0x651d4a0e", "imm2": "0x93c198bd", "rot": 26, "bit": 12, "mask": 8}, + {"i": 19, "op": "mul", "dst": 6, "src": 1, "src2": 6, "imm": "0xd38ce89d", "imm2": "0x3dfad388", "rot": 5, "bit": 28, "mask": 8}, + {"i": 20, "op": "mad", "dst": 5, "src": 6, "src2": 0, "imm": "0x59d78b36", "imm2": "0xc4db274e", "rot": 25, "bit": 24, "mask": 1}, + {"i": 21, "op": "sub", "dst": 3, "src": 1, "src2": 7, "imm": "0xf6c6a6c7", "imm2": "0x8536f4e6", "rot": 6, "bit": 12, "mask": 4}, + {"i": 22, "op": "mul", "dst": 6, "src": 0, "src2": 7, "imm": "0x599445b4", "imm2": "0x632f8c32", "rot": 19, "bit": 4, "mask": 8}, + {"i": 23, "op": "add", "dst": 2, "src": 0, "src2": 7, "imm": "0x45c37cec", "imm2": "0x96e8f127", "rot": 15, "bit": 1, "mask": 4}, + {"i": 24, "op": "sub", "dst": 6, "src": 4, "src2": 3, "imm": "0xc1c44491", "imm2": "0x92e3ce57", "rot": 20, "bit": 25, "mask": 4}, + {"i": 25, "op": "mad", "dst": 7, "src": 3, "src2": 4, "imm": "0x89bfb8d3", "imm2": "0x19b5455e", "rot": 22, "bit": 2, "mask": 16}, + {"i": 26, "op": "rotl", "dst": 3, "src": 5, "src2": 7, "imm": "0x2f47ce8d", "imm2": "0x8b458ec5", "rot": 9, "bit": 0, "mask": 4}, + {"i": 27, "op": "sub", "dst": 2, "src": 1, "src2": 2, "imm": "0x9f0dce23", "imm2": "0x3cdca814", "rot": 25, "bit": 1, "mask": 2}, + {"i": 28, "op": "mulhi", "dst": 6, "src": 0, "src2": 3, "imm": "0x61fc9eb8", "imm2": "0x23202e9d", "rot": 30, "bit": 16, "mask": 16}, + {"i": 29, "op": "shfl", "dst": 2, "src": 4, "src2": 3, "imm": "0x339dbd65", "imm2": "0xc175f639", "rot": 15, "bit": 22, "mask": 2}, + {"i": 30, "op": "shfl", "dst": 1, "src": 6, "src2": 1, "imm": "0x5bd14589", "imm2": "0xa68a2bed", "rot": 31, "bit": 31, "mask": 1}, + {"i": 31, "op": "add", "dst": 1, "src": 6, "src2": 1, "imm": "0x37985632", "imm2": "0xb1cdb2ab", "rot": 29, "bit": 1, "mask": 8}, + {"i": 32, "op": "rotr", "dst": 0, "src": 1, "src2": 6, "imm": "0x4b2058f4", "imm2": "0xf06d8ac9", "rot": 9, "bit": 15, "mask": 16}, + {"i": 33, "op": "shfl", "dst": 3, "src": 4, "src2": 4, "imm": "0x2081626c", "imm2": "0x08d1bb87", "rot": 24, "bit": 29, "mask": 2}, + {"i": 34, "op": "shfl", "dst": 0, "src": 3, "src2": 6, "imm": "0xe4fcfe03", "imm2": "0x78a46b13", "rot": 15, "bit": 29, "mask": 4}, + {"i": 35, "op": "mul", "dst": 7, "src": 0, "src2": 4, "imm": "0x33148d30", "imm2": "0x5780a3d6", "rot": 6, "bit": 11, "mask": 2}, + {"i": 36, "op": "add", "dst": 3, "src": 1, "src2": 1, "imm": "0x804e777e", "imm2": "0x856e0180", "rot": 22, "bit": 0, "mask": 16}, + {"i": 37, "op": "xor", "dst": 1, "src": 6, "src2": 0, "imm": "0xc69aa2f6", "imm2": "0xafebe3e8", "rot": 15, "bit": 9, "mask": 16}, + {"i": 38, "op": "mul", "dst": 2, "src": 7, "src2": 4, "imm": "0xeb4c4082", "imm2": "0x3f1e0da7", "rot": 25, "bit": 20, "mask": 16}, + {"i": 39, "op": "add", "dst": 6, "src": 5, "src2": 5, "imm": "0x0b06c8a7", "imm2": "0xe9bd0cc4", "rot": 6, "bit": 2, "mask": 4}, + {"i": 40, "op": "mul", "dst": 5, "src": 7, "src2": 7, "imm": "0x070af1b6", "imm2": "0x6b648e75", "rot": 10, "bit": 6, "mask": 16}, + {"i": 41, "op": "mulhi", "dst": 2, "src": 3, "src2": 2, "imm": "0x389753b2", "imm2": "0x9e657305", "rot": 30, "bit": 2, "mask": 4}, + {"i": 42, "op": "xor", "dst": 2, "src": 0, "src2": 4, "imm": "0x0960e5b9", "imm2": "0xa925a406", "rot": 4, "bit": 6, "mask": 16}, + {"i": 43, "op": "rotl", "dst": 0, "src": 1, "src2": 1, "imm": "0x8eabe09f", "imm2": "0x76ef71e2", "rot": 4, "bit": 19, "mask": 8}, + {"i": 44, "op": "mulhi", "dst": 4, "src": 3, "src2": 7, "imm": "0x6a34768a", "imm2": "0x2e427c64", "rot": 21, "bit": 5, "mask": 4}, + {"i": 45, "op": "add", "dst": 6, "src": 7, "src2": 5, "imm": "0xee822e17", "imm2": "0xcdcb63f6", "rot": 27, "bit": 12, "mask": 16}, + {"i": 46, "op": "mad", "dst": 3, "src": 2, "src2": 0, "imm": "0xc89ead43", "imm2": "0x4d3108b2", "rot": 26, "bit": 17, "mask": 1}, + {"i": 47, "op": "shfl", "dst": 4, "src": 3, "src2": 0, "imm": "0xdd62be9e", "imm2": "0xf243f6f2", "rot": 8, "bit": 4, "mask": 8}, + {"i": 48, "op": "mulhi", "dst": 6, "src": 5, "src2": 0, "imm": "0xd3f7fa72", "imm2": "0x0debc83f", "rot": 25, "bit": 5, "mask": 2}, + {"i": 49, "op": "sub", "dst": 0, "src": 2, "src2": 6, "imm": "0x7afadd15", "imm2": "0xc07fc39c", "rot": 30, "bit": 29, "mask": 8}, + {"i": 50, "op": "sub", "dst": 3, "src": 5, "src2": 3, "imm": "0x179b78ec", "imm2": "0xaeccde37", "rot": 30, "bit": 17, "mask": 1}, + {"i": 51, "op": "rotr", "dst": 1, "src": 4, "src2": 1, "imm": "0xa4bfcea6", "imm2": "0xbf63bb2f", "rot": 2, "bit": 21, "mask": 2}, + {"i": 52, "op": "mad", "dst": 6, "src": 7, "src2": 7, "imm": "0xabf5ed10", "imm2": "0x8a285f51", "rot": 3, "bit": 23, "mask": 2}, + {"i": 53, "op": "xor", "dst": 5, "src": 3, "src2": 5, "imm": "0x88b416eb", "imm2": "0x36271d87", "rot": 19, "bit": 10, "mask": 2}, + {"i": 54, "op": "sub", "dst": 1, "src": 0, "src2": 1, "imm": "0xa3417dd3", "imm2": "0xcd98f620", "rot": 28, "bit": 2, "mask": 1}, + {"i": 55, "op": "sub", "dst": 5, "src": 6, "src2": 2, "imm": "0x45996c6f", "imm2": "0xe3d41087", "rot": 4, "bit": 31, "mask": 1}, + {"i": 56, "op": "add", "dst": 3, "src": 2, "src2": 0, "imm": "0x3dfad1b6", "imm2": "0xd4758987", "rot": 27, "bit": 10, "mask": 2}, + {"i": 57, "op": "add", "dst": 4, "src": 1, "src2": 3, "imm": "0xfca75bc2", "imm2": "0x0602d6be", "rot": 19, "bit": 0, "mask": 16}, + {"i": 58, "op": "mulhi", "dst": 5, "src": 6, "src2": 5, "imm": "0x83250a7b", "imm2": "0x2f93d53b", "rot": 25, "bit": 7, "mask": 2}, + {"i": 59, "op": "shfl", "dst": 2, "src": 1, "src2": 0, "imm": "0x13f4a089", "imm2": "0x145ea125", "rot": 12, "bit": 3, "mask": 2}, + {"i": 60, "op": "rotl", "dst": 2, "src": 5, "src2": 6, "imm": "0xad3170e3", "imm2": "0x15db04d1", "rot": 9, "bit": 13, "mask": 2}, + {"i": 61, "op": "or", "dst": 4, "src": 6, "src2": 2, "imm": "0x4b6305b2", "imm2": "0x6e7b2e9c", "rot": 27, "bit": 16, "mask": 4}, + {"i": 62, "op": "rotr", "dst": 6, "src": 4, "src2": 6, "imm": "0xfcd4b1c9", "imm2": "0xaf5c733b", "rot": 6, "bit": 21, "mask": 16}, + {"i": 63, "op": "mul", "dst": 2, "src": 4, "src2": 6, "imm": "0x95cebb3e", "imm2": "0xbba9cdfc", "rot": 19, "bit": 23, "mask": 1}, + {"i": 64, "op": "xor", "dst": 0, "src": 5, "src2": 7, "imm": "0x5f7579ff", "imm2": "0xb104e01a", "rot": 25, "bit": 12, "mask": 8}, + {"i": 65, "op": "xor", "dst": 2, "src": 7, "src2": 3, "imm": "0x749c7611", "imm2": "0xf17df3bb", "rot": 27, "bit": 26, "mask": 2}, + {"i": 66, "op": "add", "dst": 2, "src": 1, "src2": 6, "imm": "0xd71c02ff", "imm2": "0x8596687a", "rot": 4, "bit": 6, "mask": 2}, + {"i": 67, "op": "rotl", "dst": 1, "src": 3, "src2": 2, "imm": "0xd2864071", "imm2": "0xaa644ef3", "rot": 21, "bit": 5, "mask": 1}, + {"i": 68, "op": "mul", "dst": 3, "src": 2, "src2": 1, "imm": "0xd0689a5f", "imm2": "0xa3a1f063", "rot": 13, "bit": 28, "mask": 2}, + {"i": 69, "op": "shfl", "dst": 7, "src": 5, "src2": 6, "imm": "0xd01476eb", "imm2": "0x76abb5c2", "rot": 7, "bit": 30, "mask": 2}, + {"i": 70, "op": "mul", "dst": 3, "src": 2, "src2": 5, "imm": "0x59a75c10", "imm2": "0x1e1fbb72", "rot": 20, "bit": 16, "mask": 1}, + {"i": 71, "op": "mad", "dst": 0, "src": 2, "src2": 5, "imm": "0x39cca1df", "imm2": "0x22c057ac", "rot": 5, "bit": 23, "mask": 16}, + {"i": 72, "op": "add", "dst": 6, "src": 7, "src2": 3, "imm": "0x3c6fe15d", "imm2": "0x08ac5733", "rot": 14, "bit": 0, "mask": 4}, + {"i": 73, "op": "shfl", "dst": 3, "src": 2, "src2": 6, "imm": "0x2098627d", "imm2": "0xf4fecc81", "rot": 20, "bit": 30, "mask": 8}, + {"i": 74, "op": "mul", "dst": 3, "src": 6, "src2": 5, "imm": "0xf82e9e23", "imm2": "0x3ad62132", "rot": 10, "bit": 14, "mask": 16}, + {"i": 75, "op": "xor", "dst": 6, "src": 7, "src2": 4, "imm": "0x70548a91", "imm2": "0xa9715d2e", "rot": 6, "bit": 24, "mask": 1}, + {"i": 76, "op": "or", "dst": 3, "src": 0, "src2": 7, "imm": "0xa164325f", "imm2": "0xf300838b", "rot": 23, "bit": 23, "mask": 16}, + {"i": 77, "op": "add", "dst": 2, "src": 4, "src2": 6, "imm": "0x295d5fae", "imm2": "0xc100b495", "rot": 7, "bit": 1, "mask": 2}, + {"i": 78, "op": "mulhi", "dst": 3, "src": 7, "src2": 4, "imm": "0xb62cca87", "imm2": "0x2ebde415", "rot": 14, "bit": 7, "mask": 2}, + {"i": 79, "op": "or", "dst": 4, "src": 1, "src2": 7, "imm": "0xfcbc482d", "imm2": "0x8876e6cd", "rot": 29, "bit": 5, "mask": 2}, + {"i": 80, "op": "rotr", "dst": 4, "src": 3, "src2": 0, "imm": "0x6d64013b", "imm2": "0x675f4a8d", "rot": 26, "bit": 18, "mask": 8}, + {"i": 81, "op": "add", "dst": 4, "src": 3, "src2": 3, "imm": "0x274a9221", "imm2": "0x5cc59530", "rot": 15, "bit": 15, "mask": 2}, + {"i": 82, "op": "add", "dst": 7, "src": 3, "src2": 0, "imm": "0xc8651f8e", "imm2": "0x141479ec", "rot": 18, "bit": 5, "mask": 1}, + {"i": 83, "op": "rotr", "dst": 3, "src": 6, "src2": 0, "imm": "0xcc8a7766", "imm2": "0xc2eb5161", "rot": 4, "bit": 29, "mask": 2}, + {"i": 84, "op": "mad", "dst": 2, "src": 4, "src2": 7, "imm": "0xbc507d51", "imm2": "0x0b1196fd", "rot": 9, "bit": 7, "mask": 8}, + {"i": 85, "op": "shfl", "dst": 2, "src": 5, "src2": 5, "imm": "0x5a156c90", "imm2": "0xa6b3fbfa", "rot": 11, "bit": 2, "mask": 16}, + {"i": 86, "op": "xor", "dst": 3, "src": 2, "src2": 1, "imm": "0x8b042658", "imm2": "0xacf37a8f", "rot": 12, "bit": 23, "mask": 16}, + {"i": 87, "op": "shfl", "dst": 5, "src": 7, "src2": 2, "imm": "0x1a214238", "imm2": "0x017fdf5d", "rot": 29, "bit": 14, "mask": 2}, + {"i": 88, "op": "xor", "dst": 0, "src": 4, "src2": 2, "imm": "0xd523e612", "imm2": "0x2158c2ed", "rot": 30, "bit": 14, "mask": 4}, + {"i": 89, "op": "add", "dst": 3, "src": 2, "src2": 7, "imm": "0x53f915c2", "imm2": "0x883c0c92", "rot": 9, "bit": 18, "mask": 8}, + {"i": 90, "op": "rotr", "dst": 7, "src": 5, "src2": 5, "imm": "0xbd633b21", "imm2": "0xcf8c356c", "rot": 25, "bit": 31, "mask": 4}, + {"i": 91, "op": "add", "dst": 3, "src": 1, "src2": 1, "imm": "0xe2be00a5", "imm2": "0x3cc5bd20", "rot": 10, "bit": 31, "mask": 1}, + {"i": 92, "op": "shfl", "dst": 7, "src": 2, "src2": 4, "imm": "0x3d3da600", "imm2": "0x1f22df89", "rot": 4, "bit": 24, "mask": 1}, + {"i": 93, "op": "rotr", "dst": 6, "src": 2, "src2": 7, "imm": "0xb0f57471", "imm2": "0x8f2a7eca", "rot": 16, "bit": 25, "mask": 1}, + {"i": 94, "op": "rotl", "dst": 7, "src": 0, "src2": 4, "imm": "0x00a21815", "imm2": "0xeb4d7218", "rot": 14, "bit": 18, "mask": 16}, + {"i": 95, "op": "mad", "dst": 4, "src": 5, "src2": 5, "imm": "0xc4c3828e", "imm2": "0xfb7bba17", "rot": 16, "bit": 10, "mask": 16}, + {"i": 96, "op": "mad", "dst": 2, "src": 4, "src2": 5, "imm": "0xfc5bbc75", "imm2": "0xfc43468f", "rot": 31, "bit": 20, "mask": 16}, + {"i": 97, "op": "xor", "dst": 1, "src": 0, "src2": 2, "imm": "0x1fe9c249", "imm2": "0x164bb16b", "rot": 15, "bit": 9, "mask": 4}, + {"i": 98, "op": "mul", "dst": 5, "src": 4, "src2": 1, "imm": "0xeda725fa", "imm2": "0x66f7e9a2", "rot": 21, "bit": 6, "mask": 2}, + {"i": 99, "op": "sub", "dst": 2, "src": 0, "src2": 7, "imm": "0x8fb29f7d", "imm2": "0xf530eda1", "rot": 27, "bit": 30, "mask": 4}, + {"i": 100, "op": "rotl", "dst": 7, "src": 2, "src2": 0, "imm": "0x9f4de742", "imm2": "0x9b5ff871", "rot": 30, "bit": 21, "mask": 16}, + {"i": 101, "op": "add", "dst": 5, "src": 6, "src2": 7, "imm": "0x423fd9c9", "imm2": "0xbfd646cb", "rot": 17, "bit": 17, "mask": 2}, + {"i": 102, "op": "add", "dst": 7, "src": 6, "src2": 3, "imm": "0x8d3c011d", "imm2": "0x19b74a43", "rot": 12, "bit": 11, "mask": 4}, + {"i": 103, "op": "rotl", "dst": 5, "src": 6, "src2": 0, "imm": "0xcfc70303", "imm2": "0xf2b3e8ef", "rot": 6, "bit": 24, "mask": 1}, + {"i": 104, "op": "mul", "dst": 0, "src": 4, "src2": 5, "imm": "0x650475eb", "imm2": "0x11dcbd94", "rot": 15, "bit": 10, "mask": 1}, + {"i": 105, "op": "or", "dst": 0, "src": 5, "src2": 3, "imm": "0xaacaa145", "imm2": "0x9139d3fe", "rot": 4, "bit": 18, "mask": 2}, + {"i": 106, "op": "add", "dst": 0, "src": 1, "src2": 7, "imm": "0x8ce14721", "imm2": "0x7dcb7e18", "rot": 24, "bit": 15, "mask": 8}, + {"i": 107, "op": "rotl", "dst": 0, "src": 3, "src2": 3, "imm": "0xb36d6d98", "imm2": "0x2c3390c8", "rot": 15, "bit": 10, "mask": 16}, + {"i": 108, "op": "sub", "dst": 4, "src": 2, "src2": 5, "imm": "0xf6bbdaef", "imm2": "0x9db6f65e", "rot": 25, "bit": 10, "mask": 1}, + {"i": 109, "op": "mulhi", "dst": 2, "src": 0, "src2": 0, "imm": "0xb1721fd6", "imm2": "0xd96d52c9", "rot": 1, "bit": 27, "mask": 8}, + {"i": 110, "op": "mulhi", "dst": 1, "src": 0, "src2": 5, "imm": "0xfb4ca37f", "imm2": "0xb6ec7dbe", "rot": 27, "bit": 12, "mask": 8}, + {"i": 111, "op": "add", "dst": 0, "src": 2, "src2": 0, "imm": "0x2d9fc6b9", "imm2": "0x3c179ad8", "rot": 9, "bit": 28, "mask": 16}, + {"i": 112, "op": "mulhi", "dst": 2, "src": 0, "src2": 6, "imm": "0x71a9f6bd", "imm2": "0xd3417bf5", "rot": 2, "bit": 14, "mask": 8}, + {"i": 113, "op": "sub", "dst": 6, "src": 3, "src2": 5, "imm": "0xa3d19400", "imm2": "0x15df7330", "rot": 5, "bit": 2, "mask": 8}, + {"i": 114, "op": "mad", "dst": 7, "src": 6, "src2": 3, "imm": "0x1400d92e", "imm2": "0xfa4a158e", "rot": 16, "bit": 9, "mask": 1}, + {"i": 115, "op": "rotr", "dst": 5, "src": 1, "src2": 3, "imm": "0xd01684c3", "imm2": "0x6367febb", "rot": 23, "bit": 19, "mask": 2}, + {"i": 116, "op": "rotr", "dst": 6, "src": 4, "src2": 2, "imm": "0x8cd9eb96", "imm2": "0x98f33b24", "rot": 25, "bit": 1, "mask": 2}, + {"i": 117, "op": "add", "dst": 2, "src": 1, "src2": 7, "imm": "0x502138e2", "imm2": "0x47359729", "rot": 5, "bit": 22, "mask": 4}, + {"i": 118, "op": "mad", "dst": 3, "src": 2, "src2": 0, "imm": "0xd94a35c7", "imm2": "0xb83416c3", "rot": 11, "bit": 3, "mask": 4}, + {"i": 119, "op": "mul", "dst": 1, "src": 3, "src2": 6, "imm": "0x09b30cf7", "imm2": "0xef3b98e7", "rot": 17, "bit": 23, "mask": 8}, + {"i": 120, "op": "mad", "dst": 2, "src": 0, "src2": 4, "imm": "0x56416fe0", "imm2": "0x5e1dc8f3", "rot": 17, "bit": 14, "mask": 2}, + {"i": 121, "op": "mul", "dst": 0, "src": 3, "src2": 2, "imm": "0x2892697c", "imm2": "0x9cb3b14e", "rot": 29, "bit": 25, "mask": 2}, + {"i": 122, "op": "mulhi", "dst": 2, "src": 0, "src2": 3, "imm": "0xc33089a1", "imm2": "0xd6c5b530", "rot": 27, "bit": 13, "mask": 8}, + {"i": 123, "op": "mul", "dst": 5, "src": 6, "src2": 4, "imm": "0xdfe04e4a", "imm2": "0x3cc40160", "rot": 3, "bit": 14, "mask": 2}, + {"i": 124, "op": "mad", "dst": 4, "src": 2, "src2": 4, "imm": "0xb33dc1b7", "imm2": "0xab97743a", "rot": 7, "bit": 21, "mask": 4}, + {"i": 125, "op": "shfl", "dst": 4, "src": 2, "src2": 0, "imm": "0xfd469909", "imm2": "0xfc85dc55", "rot": 28, "bit": 24, "mask": 2}, + {"i": 126, "op": "xor", "dst": 2, "src": 0, "src2": 5, "imm": "0xa0094578", "imm2": "0xf1bee474", "rot": 31, "bit": 7, "mask": 2}, + {"i": 127, "op": "rotl", "dst": 1, "src": 7, "src2": 2, "imm": "0xb7ae00a0", "imm2": "0x86cce297", "rot": 7, "bit": 31, "mask": 8}, + {"i": 128, "op": "shfl", "dst": 7, "src": 2, "src2": 7, "imm": "0x019d1940", "imm2": "0x3fe9e7dd", "rot": 14, "bit": 4, "mask": 4}, + {"i": 129, "op": "rotl", "dst": 6, "src": 7, "src2": 7, "imm": "0x40a74cc4", "imm2": "0x09eb4adf", "rot": 17, "bit": 30, "mask": 1}, + {"i": 130, "op": "add", "dst": 2, "src": 5, "src2": 5, "imm": "0x33dff776", "imm2": "0x6c57e4e7", "rot": 27, "bit": 15, "mask": 4}, + {"i": 131, "op": "or", "dst": 0, "src": 3, "src2": 1, "imm": "0xe0c53bb9", "imm2": "0x124404f6", "rot": 4, "bit": 21, "mask": 16}, + {"i": 132, "op": "rotr", "dst": 5, "src": 0, "src2": 1, "imm": "0xe4353fce", "imm2": "0x559d0118", "rot": 2, "bit": 29, "mask": 4}, + {"i": 133, "op": "add", "dst": 2, "src": 3, "src2": 6, "imm": "0x5db25b34", "imm2": "0xe8212c0c", "rot": 21, "bit": 30, "mask": 1}, + {"i": 134, "op": "xor", "dst": 4, "src": 3, "src2": 6, "imm": "0x7366e50e", "imm2": "0x7cc1ffbd", "rot": 19, "bit": 18, "mask": 16}, + {"i": 135, "op": "xor", "dst": 6, "src": 1, "src2": 2, "imm": "0xa36decb7", "imm2": "0x79291734", "rot": 26, "bit": 0, "mask": 8}, + {"i": 136, "op": "sub", "dst": 1, "src": 7, "src2": 0, "imm": "0x225b03e4", "imm2": "0x7183e193", "rot": 16, "bit": 6, "mask": 2}, + {"i": 137, "op": "mad", "dst": 2, "src": 6, "src2": 2, "imm": "0x6f620d51", "imm2": "0x4e814e19", "rot": 6, "bit": 6, "mask": 2}, + {"i": 138, "op": "mulhi", "dst": 0, "src": 5, "src2": 6, "imm": "0x919d6bf3", "imm2": "0xc6240638", "rot": 17, "bit": 11, "mask": 16}, + {"i": 139, "op": "add", "dst": 2, "src": 7, "src2": 7, "imm": "0x218d4090", "imm2": "0xd44ff710", "rot": 1, "bit": 10, "mask": 16}, + {"i": 140, "op": "rotr", "dst": 1, "src": 4, "src2": 4, "imm": "0x4cbfa722", "imm2": "0x114e9564", "rot": 28, "bit": 9, "mask": 16}, + {"i": 141, "op": "shfl", "dst": 3, "src": 6, "src2": 2, "imm": "0xf702c6a1", "imm2": "0xf8f3c5d9", "rot": 7, "bit": 24, "mask": 1}, + {"i": 142, "op": "mad", "dst": 7, "src": 6, "src2": 2, "imm": "0xa2d285be", "imm2": "0x9cc94532", "rot": 15, "bit": 20, "mask": 8}, + {"i": 143, "op": "mul", "dst": 2, "src": 3, "src2": 7, "imm": "0x08b7ed80", "imm2": "0xa8abced4", "rot": 18, "bit": 10, "mask": 4}, + {"i": 144, "op": "add", "dst": 7, "src": 4, "src2": 2, "imm": "0xf4b1a8de", "imm2": "0xb98942fa", "rot": 18, "bit": 29, "mask": 8}, + {"i": 145, "op": "rotl", "dst": 7, "src": 6, "src2": 1, "imm": "0x64b6ba2d", "imm2": "0xf9e86793", "rot": 15, "bit": 24, "mask": 8}, + {"i": 146, "op": "xor", "dst": 7, "src": 5, "src2": 3, "imm": "0x41c42b5f", "imm2": "0x7c7e0e39", "rot": 8, "bit": 23, "mask": 2}, + {"i": 147, "op": "mad", "dst": 4, "src": 7, "src2": 4, "imm": "0x3caa807a", "imm2": "0x553a0cec", "rot": 11, "bit": 22, "mask": 8}, + {"i": 148, "op": "rotr", "dst": 6, "src": 5, "src2": 3, "imm": "0x3cb1289a", "imm2": "0x6b36f78a", "rot": 1, "bit": 9, "mask": 16}, + {"i": 149, "op": "mad", "dst": 1, "src": 2, "src2": 4, "imm": "0x95310ea8", "imm2": "0xc533aa6a", "rot": 16, "bit": 17, "mask": 1}, + {"i": 150, "op": "add", "dst": 1, "src": 7, "src2": 7, "imm": "0x2bef10f2", "imm2": "0x0d48ba42", "rot": 8, "bit": 17, "mask": 4}, + {"i": 151, "op": "xor", "dst": 5, "src": 4, "src2": 7, "imm": "0xda997ab2", "imm2": "0xae31d69e", "rot": 11, "bit": 31, "mask": 2}, + {"i": 152, "op": "add", "dst": 7, "src": 0, "src2": 6, "imm": "0xdc5cc080", "imm2": "0xc98dea9c", "rot": 16, "bit": 30, "mask": 2}, + {"i": 153, "op": "mul", "dst": 4, "src": 6, "src2": 7, "imm": "0xbfbf5f6c", "imm2": "0x61f611bb", "rot": 14, "bit": 22, "mask": 2}, + {"i": 154, "op": "mul", "dst": 0, "src": 2, "src2": 3, "imm": "0xa78008c3", "imm2": "0xbad5eeb1", "rot": 10, "bit": 28, "mask": 8}, + {"i": 155, "op": "xor", "dst": 6, "src": 5, "src2": 4, "imm": "0x1a73b866", "imm2": "0x1f5a62c9", "rot": 9, "bit": 27, "mask": 8}, + {"i": 156, "op": "rotr", "dst": 4, "src": 2, "src2": 0, "imm": "0x9c88500c", "imm2": "0xe25dccf9", "rot": 11, "bit": 2, "mask": 16}, + {"i": 157, "op": "rotl", "dst": 1, "src": 4, "src2": 4, "imm": "0xb05e7669", "imm2": "0x9db704b1", "rot": 11, "bit": 28, "mask": 4}, + {"i": 158, "op": "add", "dst": 5, "src": 0, "src2": 6, "imm": "0x18197438", "imm2": "0x6c752dcb", "rot": 11, "bit": 11, "mask": 2}, + {"i": 159, "op": "mad", "dst": 4, "src": 1, "src2": 5, "imm": "0x4796a65e", "imm2": "0x00e08c7a", "rot": 8, "bit": 19, "mask": 4}, + {"i": 160, "op": "rotl", "dst": 4, "src": 7, "src2": 5, "imm": "0x08a03052", "imm2": "0x0204f0ba", "rot": 26, "bit": 5, "mask": 2}, + {"i": 161, "op": "mad", "dst": 3, "src": 0, "src2": 7, "imm": "0xa0603b0e", "imm2": "0x7eee83d5", "rot": 28, "bit": 22, "mask": 16}, + {"i": 162, "op": "rotr", "dst": 3, "src": 1, "src2": 6, "imm": "0x78a3c69d", "imm2": "0x684693a0", "rot": 21, "bit": 23, "mask": 4}, + {"i": 163, "op": "add", "dst": 4, "src": 0, "src2": 7, "imm": "0xf1c46574", "imm2": "0x8e481727", "rot": 9, "bit": 3, "mask": 4}, + {"i": 164, "op": "mulhi", "dst": 0, "src": 4, "src2": 3, "imm": "0x04644afa", "imm2": "0x64bda2b5", "rot": 26, "bit": 16, "mask": 16}, + {"i": 165, "op": "add", "dst": 2, "src": 6, "src2": 2, "imm": "0xac578137", "imm2": "0x550ab406", "rot": 13, "bit": 20, "mask": 16}, + {"i": 166, "op": "rotl", "dst": 0, "src": 4, "src2": 5, "imm": "0x7f564760", "imm2": "0xb9a8b4f8", "rot": 13, "bit": 29, "mask": 1}, + {"i": 167, "op": "add", "dst": 3, "src": 1, "src2": 0, "imm": "0xa33e6706", "imm2": "0xaebb5966", "rot": 12, "bit": 14, "mask": 16}, + {"i": 168, "op": "or", "dst": 3, "src": 5, "src2": 3, "imm": "0x65b2f3eb", "imm2": "0xb1d00d20", "rot": 12, "bit": 2, "mask": 8}, + {"i": 169, "op": "rotr", "dst": 6, "src": 2, "src2": 3, "imm": "0x7f21faf5", "imm2": "0xbbf0d3f9", "rot": 17, "bit": 13, "mask": 8}, + {"i": 170, "op": "xor", "dst": 4, "src": 6, "src2": 2, "imm": "0x162c7140", "imm2": "0x90d404ad", "rot": 26, "bit": 1, "mask": 4}, + {"i": 171, "op": "sub", "dst": 6, "src": 1, "src2": 7, "imm": "0x6ef9c76e", "imm2": "0xfb7ba272", "rot": 31, "bit": 25, "mask": 1}, + {"i": 172, "op": "rotl", "dst": 7, "src": 5, "src2": 4, "imm": "0xde04eb3b", "imm2": "0xd56caa00", "rot": 22, "bit": 21, "mask": 4}, + {"i": 173, "op": "rotl", "dst": 5, "src": 3, "src2": 5, "imm": "0xa9eac934", "imm2": "0x2c338e51", "rot": 15, "bit": 22, "mask": 2}, + {"i": 174, "op": "shfl", "dst": 7, "src": 0, "src2": 3, "imm": "0x700be4e3", "imm2": "0x4bcfc732", "rot": 19, "bit": 6, "mask": 8}, + {"i": 175, "op": "xor", "dst": 0, "src": 5, "src2": 1, "imm": "0x02ccdba9", "imm2": "0xd0915be0", "rot": 15, "bit": 2, "mask": 16}, + {"i": 176, "op": "rotl", "dst": 7, "src": 4, "src2": 1, "imm": "0x489c8165", "imm2": "0xf24b5a4f", "rot": 6, "bit": 22, "mask": 1}, + {"i": 177, "op": "sub", "dst": 7, "src": 0, "src2": 6, "imm": "0x23ad9693", "imm2": "0x9a8c2f7b", "rot": 24, "bit": 2, "mask": 2}, + {"i": 178, "op": "rotl", "dst": 3, "src": 0, "src2": 6, "imm": "0xafa72a42", "imm2": "0x371d74ee", "rot": 30, "bit": 16, "mask": 1}, + {"i": 179, "op": "mad", "dst": 7, "src": 6, "src2": 1, "imm": "0x18a2a3f3", "imm2": "0xb811b951", "rot": 2, "bit": 9, "mask": 2}, + {"i": 180, "op": "rotl", "dst": 6, "src": 4, "src2": 1, "imm": "0xe6c69c0e", "imm2": "0xfc46a951", "rot": 9, "bit": 31, "mask": 4}, + {"i": 181, "op": "xor", "dst": 2, "src": 4, "src2": 7, "imm": "0xbd1b89e4", "imm2": "0xdf4bce5c", "rot": 15, "bit": 19, "mask": 4}, + {"i": 182, "op": "xor", "dst": 2, "src": 7, "src2": 5, "imm": "0x3dd12aed", "imm2": "0xd0756a69", "rot": 13, "bit": 16, "mask": 4}, + {"i": 183, "op": "xor", "dst": 7, "src": 2, "src2": 3, "imm": "0x77ce69d6", "imm2": "0x2b39bdf2", "rot": 8, "bit": 22, "mask": 16}, + {"i": 184, "op": "add", "dst": 1, "src": 2, "src2": 4, "imm": "0xd94d55ac", "imm2": "0x5bb7550f", "rot": 31, "bit": 21, "mask": 1}, + {"i": 185, "op": "or", "dst": 3, "src": 5, "src2": 6, "imm": "0x7b1ce846", "imm2": "0xcc3b8509", "rot": 28, "bit": 9, "mask": 4}, + {"i": 186, "op": "mulhi", "dst": 6, "src": 3, "src2": 0, "imm": "0xa5e24690", "imm2": "0x2200ba81", "rot": 26, "bit": 10, "mask": 16}, + {"i": 187, "op": "or", "dst": 4, "src": 0, "src2": 3, "imm": "0xf6efe759", "imm2": "0xae1f7118", "rot": 19, "bit": 20, "mask": 4}, + {"i": 188, "op": "shfl", "dst": 7, "src": 1, "src2": 5, "imm": "0xdb318b45", "imm2": "0xcec459c9", "rot": 20, "bit": 11, "mask": 2}, + {"i": 189, "op": "add", "dst": 6, "src": 5, "src2": 1, "imm": "0x89e747fe", "imm2": "0x2a354e2d", "rot": 22, "bit": 6, "mask": 1}, + {"i": 190, "op": "xor", "dst": 1, "src": 4, "src2": 2, "imm": "0xc379e617", "imm2": "0x75e9d63b", "rot": 23, "bit": 3, "mask": 2}, + {"i": 191, "op": "mulhi", "dst": 7, "src": 4, "src2": 3, "imm": "0x5a710287", "imm2": "0x7fe4ead6", "rot": 10, "bit": 25, "mask": 4}, + {"i": 192, "op": "rotl", "dst": 2, "src": 1, "src2": 2, "imm": "0x4d5e59a3", "imm2": "0x1e4fef28", "rot": 26, "bit": 0, "mask": 1}, + {"i": 193, "op": "rotl", "dst": 5, "src": 3, "src2": 7, "imm": "0x7444c47d", "imm2": "0xdad5f8be", "rot": 8, "bit": 30, "mask": 2}, + {"i": 194, "op": "shfl", "dst": 4, "src": 5, "src2": 7, "imm": "0x6a225bbb", "imm2": "0xd6532cd7", "rot": 13, "bit": 17, "mask": 16}, + {"i": 195, "op": "xor", "dst": 4, "src": 5, "src2": 3, "imm": "0x68344b9a", "imm2": "0xcb46a38b", "rot": 1, "bit": 27, "mask": 16}, + {"i": 196, "op": "mul", "dst": 1, "src": 3, "src2": 4, "imm": "0xbebf7359", "imm2": "0x3f0890ba", "rot": 18, "bit": 12, "mask": 4}, + {"i": 197, "op": "add", "dst": 5, "src": 2, "src2": 3, "imm": "0xea03e8e7", "imm2": "0x10cfdc71", "rot": 31, "bit": 7, "mask": 8}, + {"i": 198, "op": "add", "dst": 7, "src": 5, "src2": 1, "imm": "0xa7ee0102", "imm2": "0x66e148d3", "rot": 12, "bit": 15, "mask": 1}, + {"i": 199, "op": "sub", "dst": 5, "src": 2, "src2": 4, "imm": "0xc215584e", "imm2": "0x55fce30f", "rot": 30, "bit": 9, "mask": 2}, + {"i": 200, "op": "shfl", "dst": 5, "src": 1, "src2": 1, "imm": "0x308f8358", "imm2": "0x489f1f93", "rot": 13, "bit": 13, "mask": 2}, + {"i": 201, "op": "shfl", "dst": 7, "src": 1, "src2": 5, "imm": "0x713f1957", "imm2": "0x2239f757", "rot": 15, "bit": 7, "mask": 8}, + {"i": 202, "op": "rotr", "dst": 4, "src": 5, "src2": 1, "imm": "0xb037b6e7", "imm2": "0x49a8b528", "rot": 27, "bit": 13, "mask": 16}, + {"i": 203, "op": "xor", "dst": 7, "src": 5, "src2": 1, "imm": "0x56110241", "imm2": "0xefc8386d", "rot": 22, "bit": 20, "mask": 1}, + {"i": 204, "op": "xor", "dst": 7, "src": 0, "src2": 0, "imm": "0x0827fcc7", "imm2": "0xf4f5dd07", "rot": 13, "bit": 7, "mask": 2}, + {"i": 205, "op": "add", "dst": 6, "src": 2, "src2": 0, "imm": "0x8379a4de", "imm2": "0x8558b619", "rot": 26, "bit": 10, "mask": 1}, + {"i": 206, "op": "rotl", "dst": 4, "src": 3, "src2": 3, "imm": "0x091ceef0", "imm2": "0x69b0f72f", "rot": 13, "bit": 7, "mask": 1}, + {"i": 207, "op": "mulhi", "dst": 1, "src": 3, "src2": 4, "imm": "0x758edac1", "imm2": "0x98dd2f21", "rot": 15, "bit": 9, "mask": 1}, + {"i": 208, "op": "mad", "dst": 1, "src": 4, "src2": 4, "imm": "0x78871a1a", "imm2": "0x5e14e1c8", "rot": 19, "bit": 6, "mask": 2}, + {"i": 209, "op": "shfl", "dst": 2, "src": 0, "src2": 2, "imm": "0xf7e0b9aa", "imm2": "0xaecfd347", "rot": 21, "bit": 9, "mask": 4}, + {"i": 210, "op": "add", "dst": 7, "src": 0, "src2": 7, "imm": "0xaa8cb14e", "imm2": "0xf4049c4c", "rot": 24, "bit": 11, "mask": 8}, + {"i": 211, "op": "shfl", "dst": 7, "src": 1, "src2": 6, "imm": "0xc230d919", "imm2": "0xf76d08fb", "rot": 21, "bit": 13, "mask": 16}, + {"i": 212, "op": "xor", "dst": 1, "src": 0, "src2": 2, "imm": "0x31a5af90", "imm2": "0x7eef58ee", "rot": 9, "bit": 12, "mask": 4}, + {"i": 213, "op": "rotl", "dst": 7, "src": 1, "src2": 6, "imm": "0x0db26138", "imm2": "0x8e3c31f9", "rot": 3, "bit": 26, "mask": 2}, + {"i": 214, "op": "rotr", "dst": 4, "src": 7, "src2": 3, "imm": "0x29558100", "imm2": "0xe4b13ad6", "rot": 29, "bit": 24, "mask": 8}, + {"i": 215, "op": "shfl", "dst": 3, "src": 2, "src2": 6, "imm": "0x1b48c3d0", "imm2": "0x5c674ff6", "rot": 5, "bit": 9, "mask": 16}, + {"i": 216, "op": "or", "dst": 5, "src": 1, "src2": 0, "imm": "0xef768632", "imm2": "0x6de9d10d", "rot": 10, "bit": 4, "mask": 4}, + {"i": 217, "op": "sub", "dst": 1, "src": 2, "src2": 5, "imm": "0x88ca7f5a", "imm2": "0x24718a36", "rot": 18, "bit": 31, "mask": 1}, + {"i": 218, "op": "sub", "dst": 6, "src": 5, "src2": 0, "imm": "0xc4a06728", "imm2": "0xdc2a4fd8", "rot": 9, "bit": 9, "mask": 2}, + {"i": 219, "op": "rotl", "dst": 6, "src": 5, "src2": 7, "imm": "0xb7489e47", "imm2": "0xf13795c5", "rot": 4, "bit": 3, "mask": 8}, + {"i": 220, "op": "mulhi", "dst": 2, "src": 0, "src2": 2, "imm": "0x873cd31b", "imm2": "0x3dfbc55d", "rot": 12, "bit": 23, "mask": 8}, + {"i": 221, "op": "or", "dst": 2, "src": 0, "src2": 3, "imm": "0xdc21f099", "imm2": "0xee06f01e", "rot": 2, "bit": 17, "mask": 8}, + {"i": 222, "op": "shfl", "dst": 5, "src": 2, "src2": 6, "imm": "0x36def499", "imm2": "0xa2849d59", "rot": 23, "bit": 4, "mask": 8}, + {"i": 223, "op": "mulhi", "dst": 5, "src": 6, "src2": 7, "imm": "0xfb95fbca", "imm2": "0xc1aac427", "rot": 14, "bit": 11, "mask": 2}, + {"i": 224, "op": "sub", "dst": 0, "src": 6, "src2": 7, "imm": "0x3d9d29c4", "imm2": "0x34d0dcc0", "rot": 17, "bit": 6, "mask": 4}, + {"i": 225, "op": "rotl", "dst": 7, "src": 0, "src2": 5, "imm": "0x93b01b8e", "imm2": "0xfe1d75ac", "rot": 23, "bit": 15, "mask": 1}, + {"i": 226, "op": "or", "dst": 4, "src": 2, "src2": 4, "imm": "0xfed76e8e", "imm2": "0x1c24ecd8", "rot": 2, "bit": 6, "mask": 16}, + {"i": 227, "op": "mul", "dst": 2, "src": 4, "src2": 1, "imm": "0x5795f5b0", "imm2": "0x0566ea2a", "rot": 6, "bit": 28, "mask": 4}, + {"i": 228, "op": "rotl", "dst": 3, "src": 0, "src2": 2, "imm": "0x8c8486de", "imm2": "0xd066aa8f", "rot": 12, "bit": 20, "mask": 1}, + {"i": 229, "op": "rotr", "dst": 0, "src": 4, "src2": 0, "imm": "0x23a3e882", "imm2": "0xaca23902", "rot": 5, "bit": 22, "mask": 16}, + {"i": 230, "op": "add", "dst": 0, "src": 6, "src2": 4, "imm": "0x1d176220", "imm2": "0x2a7fecb2", "rot": 20, "bit": 16, "mask": 2}, + {"i": 231, "op": "shfl", "dst": 1, "src": 2, "src2": 0, "imm": "0x91172787", "imm2": "0xc5d7af28", "rot": 3, "bit": 24, "mask": 4}, + {"i": 232, "op": "mul", "dst": 2, "src": 1, "src2": 2, "imm": "0x0be68835", "imm2": "0xde692bdb", "rot": 30, "bit": 17, "mask": 1}, + {"i": 233, "op": "mad", "dst": 7, "src": 0, "src2": 1, "imm": "0xf90d2db5", "imm2": "0x96c4c175", "rot": 28, "bit": 7, "mask": 4}, + {"i": 234, "op": "rotl", "dst": 5, "src": 2, "src2": 1, "imm": "0x16379736", "imm2": "0x6973b905", "rot": 22, "bit": 17, "mask": 4}, + {"i": 235, "op": "rotr", "dst": 4, "src": 6, "src2": 2, "imm": "0x84292a13", "imm2": "0x0f897740", "rot": 12, "bit": 6, "mask": 8}, + {"i": 236, "op": "mad", "dst": 0, "src": 5, "src2": 1, "imm": "0xeb7de837", "imm2": "0x64f0c302", "rot": 4, "bit": 19, "mask": 1}, + {"i": 237, "op": "xor", "dst": 6, "src": 4, "src2": 4, "imm": "0x6ab4b683", "imm2": "0x20f17adb", "rot": 1, "bit": 0, "mask": 16}, + {"i": 238, "op": "xor", "dst": 4, "src": 6, "src2": 1, "imm": "0x5836b35c", "imm2": "0x3293cc4a", "rot": 16, "bit": 22, "mask": 16}, + {"i": 239, "op": "rotl", "dst": 6, "src": 1, "src2": 6, "imm": "0x769d8bc0", "imm2": "0xdc86c9cc", "rot": 18, "bit": 27, "mask": 16}, + {"i": 240, "op": "add", "dst": 4, "src": 7, "src2": 1, "imm": "0x17dafb4d", "imm2": "0xadce39f3", "rot": 12, "bit": 25, "mask": 8}, + {"i": 241, "op": "sub", "dst": 0, "src": 7, "src2": 4, "imm": "0xd4690bda", "imm2": "0xdab9b27b", "rot": 30, "bit": 21, "mask": 1}, + {"i": 242, "op": "rotr", "dst": 1, "src": 6, "src2": 2, "imm": "0x670a2d0a", "imm2": "0x0612e33c", "rot": 31, "bit": 25, "mask": 2}, + {"i": 243, "op": "add", "dst": 3, "src": 0, "src2": 2, "imm": "0xf2f77d26", "imm2": "0x0e7033b6", "rot": 27, "bit": 29, "mask": 1}, + {"i": 244, "op": "mad", "dst": 2, "src": 7, "src2": 4, "imm": "0xa9eefc9d", "imm2": "0x16166c85", "rot": 18, "bit": 23, "mask": 16}, + {"i": 245, "op": "mad", "dst": 4, "src": 0, "src2": 6, "imm": "0xb26f6c0f", "imm2": "0x0630e821", "rot": 23, "bit": 30, "mask": 4}, + {"i": 246, "op": "mul", "dst": 5, "src": 7, "src2": 2, "imm": "0x269ce4bf", "imm2": "0x1ce28d32", "rot": 30, "bit": 15, "mask": 16}, + {"i": 247, "op": "add", "dst": 3, "src": 5, "src2": 0, "imm": "0xfed2da4e", "imm2": "0x7b2ff6b7", "rot": 25, "bit": 31, "mask": 2}, + {"i": 248, "op": "add", "dst": 0, "src": 7, "src2": 5, "imm": "0x03b2891c", "imm2": "0xb5fad7b1", "rot": 2, "bit": 0, "mask": 4}, + {"i": 249, "op": "mulhi", "dst": 5, "src": 4, "src2": 6, "imm": "0xa69a1e71", "imm2": "0x15f0c0ea", "rot": 4, "bit": 1, "mask": 4}, + {"i": 250, "op": "add", "dst": 5, "src": 2, "src2": 3, "imm": "0x042cd6e3", "imm2": "0xa7e71c2f", "rot": 24, "bit": 11, "mask": 8}, + {"i": 251, "op": "shfl", "dst": 6, "src": 1, "src2": 2, "imm": "0x89c6b683", "imm2": "0x10bbf661", "rot": 24, "bit": 5, "mask": 1}, + {"i": 252, "op": "xor", "dst": 6, "src": 1, "src2": 3, "imm": "0x265c66d6", "imm2": "0xd4a689ed", "rot": 6, "bit": 14, "mask": 8}, + {"i": 253, "op": "mul", "dst": 2, "src": 5, "src2": 5, "imm": "0x890b8201", "imm2": "0x97c36bf3", "rot": 17, "bit": 22, "mask": 4}, + {"i": 254, "op": "add", "dst": 0, "src": 6, "src2": 0, "imm": "0x784a302b", "imm2": "0xb83d78de", "rot": 27, "bit": 16, "mask": 4}, + {"i": 255, "op": "sub", "dst": 2, "src": 4, "src2": 0, "imm": "0x817adb38", "imm2": "0xf3a3534b", "rot": 7, "bit": 22, "mask": 4} + ]}, + "instructions": [ + {"i": 0, "op": "mad", "dst": 2, "src": 3, "src2": 4, "imm": "0xbf7b174d", "imm2": "0x337b762e", "rot": 17, "bit": 2, "mask": 2, "width": 1}, + {"i": 1, "op": "mad", "dst": 2, "src": 1, "src2": 1, "imm": "0xdd04a5da", "imm2": "0x42da7657", "rot": 15, "bit": 30, "mask": 16, "width": 1}, + {"i": 2, "op": "mad", "dst": 2, "src": 3, "src2": 2, "imm": "0x734003fa", "imm2": "0x5bb67700", "rot": 3, "bit": 20, "mask": 1, "width": 1}, + {"i": 3, "op": "xor", "dst": 3, "src": 5, "src2": 5, "imm": "0xc55a1b1c", "imm2": "0xa19720f3", "rot": 7, "bit": 8, "mask": 1, "width": 1}, + {"i": 4, "op": "load", "dst": 7, "src": 2, "src2": 5, "imm": "0xad572dd7", "imm2": "0x9ceb3ea7", "rot": 18, "bit": 30, "mask": 2, "width": 1}, + {"i": 5, "op": "load", "dst": 5, "src": 7, "src2": 3, "imm": "0x769a53be", "imm2": "0x80f9067e", "rot": 12, "bit": 22, "mask": 1, "width": 1}, + {"i": 6, "op": "shfl", "dst": 1, "src": 4, "src2": 0, "imm": "0xd3613d88", "imm2": "0x262fb219", "rot": 10, "bit": 30, "mask": 8, "width": 1}, + {"i": 7, "op": "shfl", "dst": 7, "src": 3, "src2": 4, "imm": "0xce38e42f", "imm2": "0xb868b818", "rot": 11, "bit": 8, "mask": 8, "width": 1}, + {"i": 8, "op": "mulhi", "dst": 1, "src": 5, "src2": 2, "imm": "0xa5eebca5", "imm2": "0x5703a72b", "rot": 13, "bit": 13, "mask": 16, "width": 1}, + {"i": 9, "op": "rotr", "dst": 6, "src": 3, "src2": 4, "imm": "0x17a5a9c7", "imm2": "0xdcfb93a1", "rot": 20, "bit": 27, "mask": 2, "width": 1}, + {"i": 10, "op": "or", "dst": 3, "src": 4, "src2": 1, "imm": "0xccb7d785", "imm2": "0xc335364c", "rot": 14, "bit": 12, "mask": 4, "width": 1}, + {"i": 11, "op": "load", "dst": 4, "src": 3, "src2": 2, "imm": "0x88cb9af3", "imm2": "0x4e7dc10d", "rot": 24, "bit": 17, "mask": 4, "width": 1}, + {"i": 12, "op": "mulhi", "dst": 0, "src": 4, "src2": 4, "imm": "0x45374321", "imm2": "0x3cd91989", "rot": 11, "bit": 4, "mask": 2, "width": 1}, + {"i": 13, "op": "add", "dst": 5, "src": 1, "src2": 2, "imm": "0xc7934706", "imm2": "0xd3177981", "rot": 16, "bit": 30, "mask": 2, "width": 1}, + {"i": 14, "op": "load", "dst": 0, "src": 4, "src2": 3, "imm": "0xfd7f56bb", "imm2": "0x65e14f52", "rot": 13, "bit": 22, "mask": 2, "width": 1}, + {"i": 15, "op": "sub", "dst": 2, "src": 4, "src2": 4, "imm": "0x35a80b49", "imm2": "0x060f2d13", "rot": 16, "bit": 20, "mask": 16, "width": 1}, + {"i": 16, "op": "load", "dst": 2, "src": 0, "src2": 2, "imm": "0xae0a32c2", "imm2": "0x4c2a4cfe", "rot": 8, "bit": 31, "mask": 16, "width": 1}, + {"i": 17, "op": "load", "dst": 7, "src": 2, "src2": 6, "imm": "0x82a84cc3", "imm2": "0x21a38d68", "rot": 15, "bit": 21, "mask": 2, "width": 1}, + {"i": 18, "op": "shfl", "dst": 7, "src": 3, "src2": 3, "imm": "0xa3818806", "imm2": "0x8f66b5c8", "rot": 14, "bit": 6, "mask": 4, "width": 1}, + {"i": 19, "op": "mul", "dst": 5, "src": 0, "src2": 1, "imm": "0xa00de107", "imm2": "0x77bfcaa5", "rot": 3, "bit": 10, "mask": 2, "width": 1}, + {"i": 20, "op": "shfl", "dst": 3, "src": 4, "src2": 7, "imm": "0x1d2b8cab", "imm2": "0x80b4f9a2", "rot": 14, "bit": 25, "mask": 2, "width": 1}, + {"i": 21, "op": "shfl", "dst": 2, "src": 4, "src2": 5, "imm": "0x3ac915d2", "imm2": "0x5fba7bc2", "rot": 16, "bit": 1, "mask": 16, "width": 1}, + {"i": 22, "op": "mulhi", "dst": 6, "src": 2, "src2": 0, "imm": "0xdc3ec8fd", "imm2": "0x599e2fa3", "rot": 22, "bit": 3, "mask": 2, "width": 1}, + {"i": 23, "op": "load", "dst": 6, "src": 1, "src2": 5, "imm": "0x2a6b16d5", "imm2": "0xd73e396f", "rot": 28, "bit": 29, "mask": 2, "width": 1}, + {"i": 24, "op": "mul", "dst": 5, "src": 0, "src2": 7, "imm": "0x376d0223", "imm2": "0xe1c2169a", "rot": 4, "bit": 16, "mask": 16, "width": 1}, + {"i": 25, "op": "rotl", "dst": 5, "src": 7, "src2": 3, "imm": "0x78ad8c60", "imm2": "0x6f5b77d5", "rot": 19, "bit": 11, "mask": 16, "width": 1}, + {"i": 26, "op": "shfl", "dst": 7, "src": 6, "src2": 5, "imm": "0x93915b9f", "imm2": "0x1e61fb6b", "rot": 28, "bit": 23, "mask": 2, "width": 1}, + {"i": 27, "op": "xor", "dst": 0, "src": 5, "src2": 7, "imm": "0x6378fe15", "imm2": "0x66c78f42", "rot": 12, "bit": 31, "mask": 8, "width": 1}, + {"i": 28, "op": "xor", "dst": 0, "src": 4, "src2": 7, "imm": "0x20a57fda", "imm2": "0x088c848e", "rot": 16, "bit": 13, "mask": 4, "width": 1}, + {"i": 29, "op": "sub", "dst": 3, "src": 0, "src2": 2, "imm": "0x49d95fd5", "imm2": "0x1a5f946a", "rot": 6, "bit": 12, "mask": 1, "width": 1}, + {"i": 30, "op": "mul", "dst": 5, "src": 1, "src2": 7, "imm": "0x0a816217", "imm2": "0x405c4f73", "rot": 13, "bit": 27, "mask": 4, "width": 1}, + {"i": 31, "op": "load", "dst": 7, "src": 2, "src2": 2, "imm": "0x09ed045e", "imm2": "0xd69c4715", "rot": 5, "bit": 9, "mask": 2, "width": 1}, + {"i": 32, "op": "load", "dst": 1, "src": 0, "src2": 6, "imm": "0xeb79ea49", "imm2": "0xcc587f5a", "rot": 6, "bit": 8, "mask": 16, "width": 1}, + {"i": 33, "op": "xor", "dst": 5, "src": 6, "src2": 1, "imm": "0x3027401e", "imm2": "0x5f20c27e", "rot": 18, "bit": 9, "mask": 2, "width": 1}, + {"i": 34, "op": "load", "dst": 5, "src": 1, "src2": 3, "imm": "0x0e1cab07", "imm2": "0x09356c5b", "rot": 19, "bit": 31, "mask": 1, "width": 1}, + {"i": 35, "op": "mulhi", "dst": 0, "src": 5, "src2": 2, "imm": "0x90e31357", "imm2": "0xabd32484", "rot": 26, "bit": 5, "mask": 8, "width": 1}, + {"i": 36, "op": "shfl", "dst": 5, "src": 2, "src2": 5, "imm": "0xee9a955f", "imm2": "0x31b3faed", "rot": 8, "bit": 24, "mask": 4, "width": 1}, + {"i": 37, "op": "load", "dst": 7, "src": 0, "src2": 7, "imm": "0x3ba2f832", "imm2": "0x1160dcd3", "rot": 4, "bit": 29, "mask": 1, "width": 1}, + {"i": 38, "op": "add", "dst": 3, "src": 1, "src2": 7, "imm": "0x75ba2fad", "imm2": "0x230c005c", "rot": 4, "bit": 27, "mask": 1, "width": 1}, + {"i": 39, "op": "shfl", "dst": 1, "src": 5, "src2": 3, "imm": "0xdbf37e75", "imm2": "0xb5ac1969", "rot": 30, "bit": 13, "mask": 4, "width": 1}, + {"i": 40, "op": "xor", "dst": 2, "src": 5, "src2": 5, "imm": "0x47f136c5", "imm2": "0x06ce9153", "rot": 19, "bit": 10, "mask": 2, "width": 1}, + {"i": 41, "op": "mad", "dst": 3, "src": 6, "src2": 3, "imm": "0xce13eff8", "imm2": "0x04cc1d55", "rot": 3, "bit": 1, "mask": 4, "width": 1}, + {"i": 42, "op": "sub", "dst": 6, "src": 7, "src2": 1, "imm": "0x6a65ab71", "imm2": "0x8fbc1bcd", "rot": 4, "bit": 1, "mask": 8, "width": 1}, + {"i": 43, "op": "xor", "dst": 7, "src": 0, "src2": 7, "imm": "0xdaeb4928", "imm2": "0xc0423027", "rot": 24, "bit": 11, "mask": 8, "width": 1}, + {"i": 44, "op": "load", "dst": 1, "src": 7, "src2": 7, "imm": "0x778f01c9", "imm2": "0x28cedcea", "rot": 12, "bit": 4, "mask": 16, "width": 1}, + {"i": 45, "op": "mul", "dst": 2, "src": 3, "src2": 2, "imm": "0xf4264f1b", "imm2": "0x0f627d56", "rot": 5, "bit": 28, "mask": 8, "width": 1}, + {"i": 46, "op": "mulhi", "dst": 1, "src": 5, "src2": 1, "imm": "0xffb2147a", "imm2": "0xccde9b05", "rot": 13, "bit": 9, "mask": 2, "width": 1}, + {"i": 47, "op": "sub", "dst": 4, "src": 3, "src2": 5, "imm": "0x73b36234", "imm2": "0x3f5d5997", "rot": 7, "bit": 18, "mask": 2, "width": 1}, + {"i": 48, "op": "rotr", "dst": 2, "src": 6, "src2": 3, "imm": "0x3a4d9aa9", "imm2": "0x212bec7b", "rot": 4, "bit": 29, "mask": 16, "width": 1}, + {"i": 49, "op": "load", "dst": 3, "src": 5, "src2": 2, "imm": "0x626f11df", "imm2": "0x56cd5bfd", "rot": 7, "bit": 1, "mask": 1, "width": 1}, + {"i": 50, "op": "add", "dst": 1, "src": 5, "src2": 6, "imm": "0x81b8bc2c", "imm2": "0x1907970c", "rot": 28, "bit": 7, "mask": 4, "width": 1}, + {"i": 51, "op": "mul", "dst": 0, "src": 2, "src2": 2, "imm": "0xa8848b30", "imm2": "0xef6ac348", "rot": 9, "bit": 15, "mask": 8, "width": 1}, + {"i": 52, "op": "add", "dst": 0, "src": 2, "src2": 0, "imm": "0x4f92b968", "imm2": "0x699fd448", "rot": 22, "bit": 6, "mask": 4, "width": 1}, + {"i": 53, "op": "add", "dst": 1, "src": 0, "src2": 2, "imm": "0x2bb965af", "imm2": "0x77b1520d", "rot": 2, "bit": 12, "mask": 8, "width": 1}, + {"i": 54, "op": "rotl", "dst": 7, "src": 1, "src2": 0, "imm": "0x553e678b", "imm2": "0x3cc8eae0", "rot": 14, "bit": 20, "mask": 2, "width": 1}, + {"i": 55, "op": "add", "dst": 3, "src": 7, "src2": 2, "imm": "0x7b0fe07a", "imm2": "0xa54c55a0", "rot": 10, "bit": 1, "mask": 1, "width": 1}, + {"i": 56, "op": "load", "dst": 6, "src": 7, "src2": 4, "imm": "0x01eba9aa", "imm2": "0x2758c0f7", "rot": 14, "bit": 15, "mask": 4, "width": 1}, + {"i": 57, "op": "rotr", "dst": 1, "src": 5, "src2": 2, "imm": "0x1f5267b3", "imm2": "0x236f5a27", "rot": 2, "bit": 31, "mask": 16, "width": 1}, + {"i": 58, "op": "load", "dst": 5, "src": 4, "src2": 3, "imm": "0xa9954a9b", "imm2": "0x6a54d4e8", "rot": 11, "bit": 10, "mask": 16, "width": 1}, + {"i": 59, "op": "load", "dst": 6, "src": 2, "src2": 4, "imm": "0x9923ff88", "imm2": "0x9357254e", "rot": 16, "bit": 1, "mask": 16, "width": 1}, + {"i": 60, "op": "mad", "dst": 3, "src": 5, "src2": 0, "imm": "0xc0cc51a6", "imm2": "0x3fd7701b", "rot": 20, "bit": 1, "mask": 4, "width": 1}, + {"i": 61, "op": "add", "dst": 5, "src": 7, "src2": 7, "imm": "0xaf9dd72d", "imm2": "0xad7493e7", "rot": 7, "bit": 31, "mask": 16, "width": 1}, + {"i": 62, "op": "add", "dst": 4, "src": 6, "src2": 2, "imm": "0x89841d87", "imm2": "0x1e07c3d9", "rot": 6, "bit": 27, "mask": 1, "width": 1}, + {"i": 63, "op": "rotl", "dst": 5, "src": 4, "src2": 2, "imm": "0xae210f8d", "imm2": "0x8e499ba4", "rot": 19, "bit": 9, "mask": 1, "width": 1} + ] +} diff --git a/proto-cuda/packs-ca3-shadow/sh256x7/program.metal b/proto-cuda/packs-ca3-shadow/sh256x7/program.metal new file mode 100644 index 000000000..428804334 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x7/program.metal @@ -0,0 +1,368 @@ +#include +using namespace metal; + +#define MASK 0x0fffffffu +constant uint SEEDW[8] = { 0x67a9a7beu, 0x1a155b25u, 0xfddfb732u, 0x4b5af2e8u, 0xc55caf33u, 0xa27c13b7u, 0x06628a48u, 0x03852469u }; + +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 = r3 * r4 + r2; // 0 + r2 = r1 * r1 + r2; // 1 + r2 = r3 * r2 + r2; // 2 + r3 = r3 ^ r5; // 3 + r7 = r7 ^ dataset[r2 & MASK]; // 4 + r5 = r5 ^ dataset[r7 & MASK]; // 5 + r1 = r1 ^ simd_shuffle_xor(r4, (ushort)8); // 6 + r7 = r7 ^ simd_shuffle_xor(r3, (ushort)8); // 7 + r1 = mulhi(r1, r5); // 8 + r6 = rotr_var(r6, r3); // 9 + r3 = r3 | r4; // 10 + r4 = r4 ^ dataset[r3 & MASK]; // 11 + r0 = mulhi(r0, r4); // 12 + r5 = r5 + r1 + select(0xc7934706u, 0xd3177981u, ((sel >> 30u) & 1u) != 0u); // 13 + r0 = r0 ^ dataset[r4 & MASK]; // 14 + r2 = r2 - r4; // 15 + r2 = r2 ^ dataset[r0 & MASK]; // 16 + r7 = r7 ^ dataset[r2 & MASK]; // 17 + r7 = r7 ^ simd_shuffle_xor(r3, (ushort)4); // 18 + r5 = r5 * r0; // 19 + r3 = r3 ^ simd_shuffle_xor(r4, (ushort)2); // 20 + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)16); // 21 + r6 = mulhi(r6, r2); // 22 + r6 = r6 ^ dataset[r1 & MASK]; // 23 + r5 = r5 * r0; // 24 + r5 = rotl_imm(r5, 19u); // 25 + r7 = r7 ^ simd_shuffle_xor(r6, (ushort)2); // 26 + r0 = r0 ^ r5; // 27 + r0 = r0 ^ r4; // 28 + r3 = r3 - r0; // 29 + r5 = r5 * r1; // 30 + r7 = r7 ^ dataset[r2 & MASK]; // 31 + r1 = r1 ^ dataset[r0 & MASK]; // 32 + r5 = r5 ^ r6; // 33 + r5 = r5 ^ dataset[r1 & MASK]; // 34 + r0 = mulhi(r0, r5); // 35 + r5 = r5 ^ simd_shuffle_xor(r2, (ushort)4); // 36 + r7 = r7 ^ dataset[r0 & MASK]; // 37 + r3 = r3 + r1 + select(0x75ba2fadu, 0x230c005cu, ((sel >> 27u) & 1u) != 0u); // 38 + r1 = r1 ^ simd_shuffle_xor(r5, (ushort)4); // 39 + r2 = r2 ^ r5; // 40 + r3 = r6 * r3 + r3; // 41 + r6 = r6 - r7; // 42 + r7 = r7 ^ r0; // 43 + r1 = r1 ^ dataset[r7 & MASK]; // 44 + r2 = r2 * r3; // 45 + r1 = mulhi(r1, r5); // 46 + r4 = r4 - r3; // 47 + r2 = rotr_var(r2, r6); // 48 + r3 = r3 ^ dataset[r5 & MASK]; // 49 + r1 = r1 + r5 + select(0x81b8bc2cu, 0x1907970cu, ((sel >> 7u) & 1u) != 0u); // 50 + r0 = r0 * r2; // 51 + r0 = r0 + r2 + select(0x4f92b968u, 0x699fd448u, ((sel >> 6u) & 1u) != 0u); // 52 + r1 = r1 + r0 + select(0x2bb965afu, 0x77b1520du, ((sel >> 12u) & 1u) != 0u); // 53 + r7 = rotl_imm(r7, 14u); // 54 + r3 = r3 + r7 + select(0x7b0fe07au, 0xa54c55a0u, ((sel >> 1u) & 1u) != 0u); // 55 + r6 = r6 ^ dataset[r7 & MASK]; // 56 + r1 = rotr_var(r1, r5); // 57 + r5 = r5 ^ dataset[r4 & MASK]; // 58 + r6 = r6 ^ dataset[r2 & MASK]; // 59 + r3 = r5 * r0 + r3; // 60 + r5 = r5 + r7 + select(0xaf9dd72du, 0xad7493e7u, ((sel >> 31u) & 1u) != 0u); // 61 + r4 = r4 + r6 + select(0x89841d87u, 0x1e07c3d9u, ((sel >> 27u) & 1u) != 0u); // 62 + r5 = rotl_imm(r5, 19u); // 63 + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 7 passes after instruction 63, no load + for (uint sh = 0u; sh < 7u; ++sh) { + r5 = r5 + r2 + select(0x92199f99u, 0x8bc12da9u, ((sel >> 18u) & 1u) != 0u); // s0 add + r0 = r0 + r7 + select(0x8d72d3adu, 0x63079e5au, ((sel >> 26u) & 1u) != 0u); // s1 add + r6 = r6 ^ simd_shuffle_xor(r3, (ushort)2); // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + select(0xb21b4babu, 0x5d4c7a60u, ((sel >> 31u) & 1u) != 0u); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + select(0x2fe0e98bu, 0xc88e2942u, ((sel >> 16u) & 1u) != 0u); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + r6 = r6 ^ simd_shuffle_xor(r1, (ushort)4); // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + r2 = r2 ^ simd_shuffle_xor(r6, (ushort)4); // s12 shfl + r1 = r1 + r5 + select(0xbdf8f9a5u, 0xbc48c63eu, ((sel >> 25u) & 1u) != 0u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)8); // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + select(0x45c37cecu, 0x96e8f127u, ((sel >> 1u) & 1u) != 0u); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = mulhi(r6, r0); // s28 mulhi + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)2); // s29 shfl + r1 = r1 ^ simd_shuffle_xor(r6, (ushort)1); // s30 shfl + r1 = r1 + r6 + select(0x37985632u, 0xb1cdb2abu, ((sel >> 1u) & 1u) != 0u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + r3 = r3 ^ simd_shuffle_xor(r4, (ushort)2); // s33 shfl + r0 = r0 ^ simd_shuffle_xor(r3, (ushort)4); // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + select(0x804e777eu, 0x856e0180u, ((sel >> 0u) & 1u) != 0u); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + select(0x0b06c8a7u, 0xe9bd0cc4u, ((sel >> 2u) & 1u) != 0u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = mulhi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = mulhi(r4, r3); // s44 mulhi + r6 = r6 + r7 + select(0xee822e17u, 0xcdcb63f6u, ((sel >> 12u) & 1u) != 0u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + r4 = r4 ^ simd_shuffle_xor(r3, (ushort)8); // s47 shfl + r6 = mulhi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + select(0x3dfad1b6u, 0xd4758987u, ((sel >> 10u) & 1u) != 0u); // s56 add + r4 = r4 + r1 + select(0xfca75bc2u, 0x0602d6beu, ((sel >> 0u) & 1u) != 0u); // s57 add + r5 = mulhi(r5, r6); // s58 mulhi + r2 = r2 ^ simd_shuffle_xor(r1, (ushort)2); // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + select(0xd71c02ffu, 0x8596687au, ((sel >> 6u) & 1u) != 0u); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + r7 = r7 ^ simd_shuffle_xor(r5, (ushort)2); // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + select(0x3c6fe15du, 0x08ac5733u, ((sel >> 0u) & 1u) != 0u); // s72 add + r3 = r3 ^ simd_shuffle_xor(r2, (ushort)8); // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + select(0x295d5faeu, 0xc100b495u, ((sel >> 1u) & 1u) != 0u); // s77 add + r3 = mulhi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + select(0x274a9221u, 0x5cc59530u, ((sel >> 15u) & 1u) != 0u); // s81 add + r7 = r7 + r3 + select(0xc8651f8eu, 0x141479ecu, ((sel >> 5u) & 1u) != 0u); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + r2 = r2 ^ simd_shuffle_xor(r5, (ushort)16); // s85 shfl + r3 = r3 ^ r2; // s86 xor + r5 = r5 ^ simd_shuffle_xor(r7, (ushort)2); // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + select(0x53f915c2u, 0x883c0c92u, ((sel >> 18u) & 1u) != 0u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + select(0xe2be00a5u, 0x3cc5bd20u, ((sel >> 31u) & 1u) != 0u); // s91 add + r7 = r7 ^ simd_shuffle_xor(r2, (ushort)1); // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + select(0x423fd9c9u, 0xbfd646cbu, ((sel >> 17u) & 1u) != 0u); // s101 add + r7 = r7 + r6 + select(0x8d3c011du, 0x19b74a43u, ((sel >> 11u) & 1u) != 0u); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + select(0x8ce14721u, 0x7dcb7e18u, ((sel >> 15u) & 1u) != 0u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = mulhi(r2, r0); // s109 mulhi + r1 = mulhi(r1, r0); // s110 mulhi + r0 = r0 + r2 + select(0x2d9fc6b9u, 0x3c179ad8u, ((sel >> 28u) & 1u) != 0u); // s111 add + r2 = mulhi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + select(0x502138e2u, 0x47359729u, ((sel >> 22u) & 1u) != 0u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = mulhi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + r4 = r4 ^ simd_shuffle_xor(r2, (ushort)2); // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + r7 = r7 ^ simd_shuffle_xor(r2, (ushort)4); // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + select(0x33dff776u, 0x6c57e4e7u, ((sel >> 15u) & 1u) != 0u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + select(0x5db25b34u, 0xe8212c0cu, ((sel >> 30u) & 1u) != 0u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = mulhi(r0, r5); // s138 mulhi + r2 = r2 + r7 + select(0x218d4090u, 0xd44ff710u, ((sel >> 10u) & 1u) != 0u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + r3 = r3 ^ simd_shuffle_xor(r6, (ushort)1); // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + select(0xf4b1a8deu, 0xb98942fau, ((sel >> 29u) & 1u) != 0u); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + select(0x2bef10f2u, 0x0d48ba42u, ((sel >> 17u) & 1u) != 0u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + select(0xdc5cc080u, 0xc98dea9cu, ((sel >> 30u) & 1u) != 0u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + select(0x18197438u, 0x6c752dcbu, ((sel >> 11u) & 1u) != 0u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + select(0xf1c46574u, 0x8e481727u, ((sel >> 3u) & 1u) != 0u); // s163 add + r0 = mulhi(r0, r4); // s164 mulhi + r2 = r2 + r6 + select(0xac578137u, 0x550ab406u, ((sel >> 20u) & 1u) != 0u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + select(0xa33e6706u, 0xaebb5966u, ((sel >> 14u) & 1u) != 0u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + r7 = r7 ^ simd_shuffle_xor(r0, (ushort)8); // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + select(0xd94d55acu, 0x5bb7550fu, ((sel >> 21u) & 1u) != 0u); // s184 add + r3 = r3 | r5; // s185 or + r6 = mulhi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)2); // s188 shfl + r6 = r6 + r5 + select(0x89e747feu, 0x2a354e2du, ((sel >> 6u) & 1u) != 0u); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = mulhi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + r4 = r4 ^ simd_shuffle_xor(r5, (ushort)16); // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + select(0xea03e8e7u, 0x10cfdc71u, ((sel >> 7u) & 1u) != 0u); // s197 add + r7 = r7 + r5 + select(0xa7ee0102u, 0x66e148d3u, ((sel >> 15u) & 1u) != 0u); // s198 add + r5 = r5 - r2; // s199 sub + r5 = r5 ^ simd_shuffle_xor(r1, (ushort)2); // s200 shfl + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)8); // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + select(0x8379a4deu, 0x8558b619u, ((sel >> 10u) & 1u) != 0u); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = mulhi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + r2 = r2 ^ simd_shuffle_xor(r0, (ushort)4); // s209 shfl + r7 = r7 + r0 + select(0xaa8cb14eu, 0xf4049c4cu, ((sel >> 11u) & 1u) != 0u); // s210 add + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)16); // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + r3 = r3 ^ simd_shuffle_xor(r2, (ushort)16); // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = mulhi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + r5 = r5 ^ simd_shuffle_xor(r2, (ushort)8); // s222 shfl + r5 = mulhi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + select(0x1d176220u, 0x2a7fecb2u, ((sel >> 16u) & 1u) != 0u); // s230 add + r1 = r1 ^ simd_shuffle_xor(r2, (ushort)4); // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + select(0x17dafb4du, 0xadce39f3u, ((sel >> 25u) & 1u) != 0u); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + select(0xf2f77d26u, 0x0e7033b6u, ((sel >> 29u) & 1u) != 0u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + select(0xfed2da4eu, 0x7b2ff6b7u, ((sel >> 31u) & 1u) != 0u); // s247 add + r0 = r0 + r7 + select(0x03b2891cu, 0xb5fad7b1u, ((sel >> 0u) & 1u) != 0u); // s248 add + r5 = mulhi(r5, r4); // s249 mulhi + r5 = r5 + r2 + select(0x042cd6e3u, 0xa7e71c2fu, ((sel >> 11u) & 1u) != 0u); // s250 add + r6 = r6 ^ simd_shuffle_xor(r1, (ushort)1); // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + select(0x784a302bu, 0xb83d78deu, ((sel >> 16u) & 1u) != 0u); // s254 add + r2 = r2 - r4; // s255 sub + } + } + uint lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((ulong)hi << 32) | (ulong)lo; +} diff --git a/proto-cuda/packs-ca3-shadow/sh256x7/program_bound.metal b/proto-cuda/packs-ca3-shadow/sh256x7/program_bound.metal new file mode 100644 index 000000000..7665e7144 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x7/program_bound.metal @@ -0,0 +1,370 @@ +#include +using namespace metal; + +#define MASK 0x0fffffffu +constant uint SEEDW[8] = { 0x67a9a7beu, 0x1a155b25u, 0xfddfb732u, 0x4b5af2e8u, 0xc55caf33u, 0xa27c13b7u, 0x06628a48u, 0x03852469u }; + +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 = r3 * r4 + r2; // 0 + r2 = r1 * r1 + r2; // 1 + r2 = r3 * r2 + r2; // 2 + r3 = r3 ^ r5; // 3 + r7 = r7 ^ dataset[r2 & MASK]; // 4 + r5 = r5 ^ dataset[r7 & MASK]; // 5 + r1 = r1 ^ simd_shuffle_xor(r4, (ushort)8); // 6 + r7 = r7 ^ simd_shuffle_xor(r3, (ushort)8); // 7 + r1 = mulhi(r1, r5); // 8 + r6 = rotr_var(r6, r3); // 9 + r3 = r3 | r4; // 10 + r4 = r4 ^ dataset[r3 & MASK]; // 11 + r0 = mulhi(r0, r4); // 12 + r5 = r5 + r1 + select(0xc7934706u, 0xd3177981u, ((sel >> 30u) & 1u) != 0u); // 13 + r0 = r0 ^ dataset[r4 & MASK]; // 14 + r2 = r2 - r4; // 15 + r2 = r2 ^ dataset[r0 & MASK]; // 16 + r7 = r7 ^ dataset[r2 & MASK]; // 17 + r7 = r7 ^ simd_shuffle_xor(r3, (ushort)4); // 18 + r5 = r5 * r0; // 19 + r3 = r3 ^ simd_shuffle_xor(r4, (ushort)2); // 20 + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)16); // 21 + r6 = mulhi(r6, r2); // 22 + r6 = r6 ^ dataset[r1 & MASK]; // 23 + r5 = r5 * r0; // 24 + r5 = rotl_imm(r5, 19u); // 25 + r7 = r7 ^ simd_shuffle_xor(r6, (ushort)2); // 26 + r0 = r0 ^ r5; // 27 + r0 = r0 ^ r4; // 28 + r3 = r3 - r0; // 29 + r5 = r5 * r1; // 30 + r7 = r7 ^ dataset[r2 & MASK]; // 31 + r1 = r1 ^ dataset[r0 & MASK]; // 32 + r5 = r5 ^ r6; // 33 + r5 = r5 ^ dataset[r1 & MASK]; // 34 + r0 = mulhi(r0, r5); // 35 + r5 = r5 ^ simd_shuffle_xor(r2, (ushort)4); // 36 + r7 = r7 ^ dataset[r0 & MASK]; // 37 + r3 = r3 + r1 + select(0x75ba2fadu, 0x230c005cu, ((sel >> 27u) & 1u) != 0u); // 38 + r1 = r1 ^ simd_shuffle_xor(r5, (ushort)4); // 39 + r2 = r2 ^ r5; // 40 + r3 = r6 * r3 + r3; // 41 + r6 = r6 - r7; // 42 + r7 = r7 ^ r0; // 43 + r1 = r1 ^ dataset[r7 & MASK]; // 44 + r2 = r2 * r3; // 45 + r1 = mulhi(r1, r5); // 46 + r4 = r4 - r3; // 47 + r2 = rotr_var(r2, r6); // 48 + r3 = r3 ^ dataset[r5 & MASK]; // 49 + r1 = r1 + r5 + select(0x81b8bc2cu, 0x1907970cu, ((sel >> 7u) & 1u) != 0u); // 50 + r0 = r0 * r2; // 51 + r0 = r0 + r2 + select(0x4f92b968u, 0x699fd448u, ((sel >> 6u) & 1u) != 0u); // 52 + r1 = r1 + r0 + select(0x2bb965afu, 0x77b1520du, ((sel >> 12u) & 1u) != 0u); // 53 + r7 = rotl_imm(r7, 14u); // 54 + r3 = r3 + r7 + select(0x7b0fe07au, 0xa54c55a0u, ((sel >> 1u) & 1u) != 0u); // 55 + r6 = r6 ^ dataset[r7 & MASK]; // 56 + r1 = rotr_var(r1, r5); // 57 + r5 = r5 ^ dataset[r4 & MASK]; // 58 + r6 = r6 ^ dataset[r2 & MASK]; // 59 + r3 = r5 * r0 + r3; // 60 + r5 = r5 + r7 + select(0xaf9dd72du, 0xad7493e7u, ((sel >> 31u) & 1u) != 0u); // 61 + r4 = r4 + r6 + select(0x89841d87u, 0x1e07c3d9u, ((sel >> 27u) & 1u) != 0u); // 62 + r5 = rotl_imm(r5, 19u); // 63 + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 7 passes after instruction 63, no load + for (uint sh = 0u; sh < 7u; ++sh) { + r5 = r5 + r2 + select(0x92199f99u, 0x8bc12da9u, ((sel >> 18u) & 1u) != 0u); // s0 add + r0 = r0 + r7 + select(0x8d72d3adu, 0x63079e5au, ((sel >> 26u) & 1u) != 0u); // s1 add + r6 = r6 ^ simd_shuffle_xor(r3, (ushort)2); // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + select(0xb21b4babu, 0x5d4c7a60u, ((sel >> 31u) & 1u) != 0u); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + select(0x2fe0e98bu, 0xc88e2942u, ((sel >> 16u) & 1u) != 0u); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + r6 = r6 ^ simd_shuffle_xor(r1, (ushort)4); // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + r2 = r2 ^ simd_shuffle_xor(r6, (ushort)4); // s12 shfl + r1 = r1 + r5 + select(0xbdf8f9a5u, 0xbc48c63eu, ((sel >> 25u) & 1u) != 0u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)8); // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + select(0x45c37cecu, 0x96e8f127u, ((sel >> 1u) & 1u) != 0u); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = mulhi(r6, r0); // s28 mulhi + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)2); // s29 shfl + r1 = r1 ^ simd_shuffle_xor(r6, (ushort)1); // s30 shfl + r1 = r1 + r6 + select(0x37985632u, 0xb1cdb2abu, ((sel >> 1u) & 1u) != 0u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + r3 = r3 ^ simd_shuffle_xor(r4, (ushort)2); // s33 shfl + r0 = r0 ^ simd_shuffle_xor(r3, (ushort)4); // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + select(0x804e777eu, 0x856e0180u, ((sel >> 0u) & 1u) != 0u); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + select(0x0b06c8a7u, 0xe9bd0cc4u, ((sel >> 2u) & 1u) != 0u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = mulhi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = mulhi(r4, r3); // s44 mulhi + r6 = r6 + r7 + select(0xee822e17u, 0xcdcb63f6u, ((sel >> 12u) & 1u) != 0u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + r4 = r4 ^ simd_shuffle_xor(r3, (ushort)8); // s47 shfl + r6 = mulhi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + select(0x3dfad1b6u, 0xd4758987u, ((sel >> 10u) & 1u) != 0u); // s56 add + r4 = r4 + r1 + select(0xfca75bc2u, 0x0602d6beu, ((sel >> 0u) & 1u) != 0u); // s57 add + r5 = mulhi(r5, r6); // s58 mulhi + r2 = r2 ^ simd_shuffle_xor(r1, (ushort)2); // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + select(0xd71c02ffu, 0x8596687au, ((sel >> 6u) & 1u) != 0u); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + r7 = r7 ^ simd_shuffle_xor(r5, (ushort)2); // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + select(0x3c6fe15du, 0x08ac5733u, ((sel >> 0u) & 1u) != 0u); // s72 add + r3 = r3 ^ simd_shuffle_xor(r2, (ushort)8); // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + select(0x295d5faeu, 0xc100b495u, ((sel >> 1u) & 1u) != 0u); // s77 add + r3 = mulhi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + select(0x274a9221u, 0x5cc59530u, ((sel >> 15u) & 1u) != 0u); // s81 add + r7 = r7 + r3 + select(0xc8651f8eu, 0x141479ecu, ((sel >> 5u) & 1u) != 0u); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + r2 = r2 ^ simd_shuffle_xor(r5, (ushort)16); // s85 shfl + r3 = r3 ^ r2; // s86 xor + r5 = r5 ^ simd_shuffle_xor(r7, (ushort)2); // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + select(0x53f915c2u, 0x883c0c92u, ((sel >> 18u) & 1u) != 0u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + select(0xe2be00a5u, 0x3cc5bd20u, ((sel >> 31u) & 1u) != 0u); // s91 add + r7 = r7 ^ simd_shuffle_xor(r2, (ushort)1); // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + select(0x423fd9c9u, 0xbfd646cbu, ((sel >> 17u) & 1u) != 0u); // s101 add + r7 = r7 + r6 + select(0x8d3c011du, 0x19b74a43u, ((sel >> 11u) & 1u) != 0u); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + select(0x8ce14721u, 0x7dcb7e18u, ((sel >> 15u) & 1u) != 0u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = mulhi(r2, r0); // s109 mulhi + r1 = mulhi(r1, r0); // s110 mulhi + r0 = r0 + r2 + select(0x2d9fc6b9u, 0x3c179ad8u, ((sel >> 28u) & 1u) != 0u); // s111 add + r2 = mulhi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + select(0x502138e2u, 0x47359729u, ((sel >> 22u) & 1u) != 0u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = mulhi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + r4 = r4 ^ simd_shuffle_xor(r2, (ushort)2); // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + r7 = r7 ^ simd_shuffle_xor(r2, (ushort)4); // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + select(0x33dff776u, 0x6c57e4e7u, ((sel >> 15u) & 1u) != 0u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + select(0x5db25b34u, 0xe8212c0cu, ((sel >> 30u) & 1u) != 0u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = mulhi(r0, r5); // s138 mulhi + r2 = r2 + r7 + select(0x218d4090u, 0xd44ff710u, ((sel >> 10u) & 1u) != 0u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + r3 = r3 ^ simd_shuffle_xor(r6, (ushort)1); // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + select(0xf4b1a8deu, 0xb98942fau, ((sel >> 29u) & 1u) != 0u); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + select(0x2bef10f2u, 0x0d48ba42u, ((sel >> 17u) & 1u) != 0u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + select(0xdc5cc080u, 0xc98dea9cu, ((sel >> 30u) & 1u) != 0u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + select(0x18197438u, 0x6c752dcbu, ((sel >> 11u) & 1u) != 0u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + select(0xf1c46574u, 0x8e481727u, ((sel >> 3u) & 1u) != 0u); // s163 add + r0 = mulhi(r0, r4); // s164 mulhi + r2 = r2 + r6 + select(0xac578137u, 0x550ab406u, ((sel >> 20u) & 1u) != 0u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + select(0xa33e6706u, 0xaebb5966u, ((sel >> 14u) & 1u) != 0u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + r7 = r7 ^ simd_shuffle_xor(r0, (ushort)8); // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + select(0xd94d55acu, 0x5bb7550fu, ((sel >> 21u) & 1u) != 0u); // s184 add + r3 = r3 | r5; // s185 or + r6 = mulhi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)2); // s188 shfl + r6 = r6 + r5 + select(0x89e747feu, 0x2a354e2du, ((sel >> 6u) & 1u) != 0u); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = mulhi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + r4 = r4 ^ simd_shuffle_xor(r5, (ushort)16); // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + select(0xea03e8e7u, 0x10cfdc71u, ((sel >> 7u) & 1u) != 0u); // s197 add + r7 = r7 + r5 + select(0xa7ee0102u, 0x66e148d3u, ((sel >> 15u) & 1u) != 0u); // s198 add + r5 = r5 - r2; // s199 sub + r5 = r5 ^ simd_shuffle_xor(r1, (ushort)2); // s200 shfl + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)8); // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + select(0x8379a4deu, 0x8558b619u, ((sel >> 10u) & 1u) != 0u); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = mulhi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + r2 = r2 ^ simd_shuffle_xor(r0, (ushort)4); // s209 shfl + r7 = r7 + r0 + select(0xaa8cb14eu, 0xf4049c4cu, ((sel >> 11u) & 1u) != 0u); // s210 add + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)16); // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + r3 = r3 ^ simd_shuffle_xor(r2, (ushort)16); // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = mulhi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + r5 = r5 ^ simd_shuffle_xor(r2, (ushort)8); // s222 shfl + r5 = mulhi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + select(0x1d176220u, 0x2a7fecb2u, ((sel >> 16u) & 1u) != 0u); // s230 add + r1 = r1 ^ simd_shuffle_xor(r2, (ushort)4); // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + select(0x17dafb4du, 0xadce39f3u, ((sel >> 25u) & 1u) != 0u); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + select(0xf2f77d26u, 0x0e7033b6u, ((sel >> 29u) & 1u) != 0u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + select(0xfed2da4eu, 0x7b2ff6b7u, ((sel >> 31u) & 1u) != 0u); // s247 add + r0 = r0 + r7 + select(0x03b2891cu, 0xb5fad7b1u, ((sel >> 0u) & 1u) != 0u); // s248 add + r5 = mulhi(r5, r4); // s249 mulhi + r5 = r5 + r2 + select(0x042cd6e3u, 0xa7e71c2fu, ((sel >> 11u) & 1u) != 0u); // s250 add + r6 = r6 ^ simd_shuffle_xor(r1, (ushort)1); // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + select(0x784a302bu, 0xb83d78deu, ((sel >> 16u) & 1u) != 0u); // s254 add + r2 = r2 - r4; // s255 sub + } + } + uint lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((ulong)hi << 32) | (ulong)lo; +} diff --git a/proto-cuda/packs-ca3-shadow/sh256x7/vectors.h b/proto-cuda/packs-ca3-shadow/sh256x7/vectors.h new file mode 100644 index 000000000..90226dedd --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x7/vectors.h @@ -0,0 +1,57 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Expected outputs: igneum-pow (Rust) CPU interpreter, generator v2, memory-hard dataset +#pragma once +#ifdef __cplusplus +#include +#else +#include +#endif + +#define IGNEUM_VEC_WARPS 3 +static const uint32_t IGNEUM_VEC_BASE[IGNEUM_VEC_WARPS] = { 0u, 4096u, 1000000u }; +static const uint64_t IGNEUM_VEC_OUT[IGNEUM_VEC_WARPS][32] = { + { // base nonce 0 + 0xda6688d14887f390ull, 0xa967fb5329ab8301ull, 0xb36d89ddf3f7013aull, 0x8e5916887c019c5bull, 0x0b1b5e0a470dda07ull, 0x9743557891c694a0ull, 0x8b58ec4694a4b51eull, 0xaaa22b2c46199c0dull, + 0xb5e07c83348843f6ull, 0xda3e0641a2fbfa9aull, 0xea345b25e33952a8ull, 0x60b3693e4faa00b0ull, 0x11d7c24c8a92244cull, 0x3ac69fc6a553a1c5ull, 0x3248ecb535caa90eull, 0x5ed2eb6b3cdf16d0ull, + 0xaf92f32b6f8168d2ull, 0x753473cbf8f9d4baull, 0xb5aebafe1e77eb62ull, 0xf14ddaae76168834ull, 0xf4fcd368a46402e2ull, 0x219ab478cf87bd15ull, 0xb7742b0f7031c081ull, 0x17ea8d82545060e5ull, + 0xced8eb883ff74e61ull, 0xeb0ea2bf4b3dd264ull, 0x4c6fa8f5f99206faull, 0x3e6345b3f4e6938cull, 0x3ff0db0f089c87e7ull, 0x3d6f1b5d9f4795abull, 0xb9d7ad3179722417ull, 0xb7c54d6324fb8b3bull + }, + { // base nonce 4096 + 0xe3b44b175fc21b28ull, 0x3cbcac8cf0157f56ull, 0x8ba8bd15c6e4fac5ull, 0xeea33e58ceaff2f9ull, 0x1aa91b8ed208e63dull, 0x2de5d74a2ea58735ull, 0x1441f49981a3d1b0ull, 0x23435140f8545861ull, + 0x5b1d6ad6819e4d55ull, 0x92c7cd25d7f03d99ull, 0x9e52bf6eee3cd384ull, 0x296d5aea3ceed953ull, 0xd8ea21a9e77eaa7full, 0xb1f3ca3d7765a2a1ull, 0xf092c73783629a7bull, 0x2fca1ad4ca6ebeafull, + 0x6502fa6e2782982dull, 0xfddb10daa3a8bee3ull, 0x2e231d6ec341e3faull, 0xa37b7630551c909aull, 0xc38f37d60ea55cbfull, 0x2dca68ba3d90427cull, 0x632441c2905865fbull, 0xe222a7879098bad0ull, + 0x0b9702bfdfd8b4d4ull, 0xf647dd13007d96beull, 0x047245e2c8ed40d4ull, 0x522dd7eb913cf443ull, 0x44c1490f64d1eb99ull, 0xbbb4e274a10aadabull, 0x87f54e49f42ea1b4ull, 0x976c2cdffe1e715dull + }, + { // base nonce 1000000 + 0x8d57cd337f20fb07ull, 0x7ec4cd550630e97dull, 0x19e3be943d762816ull, 0xa82016fc05af1cb4ull, 0xf9df7904600efee9ull, 0xeee8357d45fc5da0ull, 0x7034a05b56de2729ull, 0xa49c0f26c2c6c30aull, + 0x8f6a1f26ad5d3ca8ull, 0x54be93649be7de81ull, 0xd91797784e113edeull, 0x6629319ac39754fbull, 0x03a17cbe16fc0b12ull, 0x1844d087f8df1e4aull, 0x032115e4fee93f48ull, 0x97f1da84a885b38aull, + 0x6a3cbad5a2cfe5baull, 0x6ecebd0bae287f5full, 0xaf2bce191bd441caull, 0x880692461306a21aull, 0xae648081f8f93103ull, 0xf43d9de1f8d4f816ull, 0x93ed1344d9bae877ull, 0xa90b327f4ae55408ull, + 0xa497f12476c412caull, 0x907602bbe1d48d10ull, 0x7252c27e00e43794ull, 0x7382d4e82184f352ull, 0x70db6147f84715e8ull, 0x818f22a7878fbe21ull, 0x70d92097d7a7e469ull, 0xe03d1f285eab54a1ull + } +}; + +// Dataset self-test: dataset[0..15] and dataset[IGNEUM_MASK] (268435455). +static const uint32_t IGNEUM_DS_HEAD[16] = { + 0xfdad4319u, 0x1a7b68e1u, 0xde6db608u, 0x13d73892u, 0xd17f447au, 0xb2221ccfu, 0x9db004bdu, 0x57d7d367u, + 0xdbc4cf34u, 0x697c009au, 0xc43af1d4u, 0x97f12b2eu, 0x74c37cd0u, 0xc651ea15u, 0x665a6d29u, 0x22330a2du +}; +static const uint32_t IGNEUM_DS_LAST_INDEX = 268435455u; +static const uint32_t IGNEUM_DS_LAST = 0xa83e7aa6u; +// 64 sampled dataset words (index, value) computed on the Mac. +#define IGNEUM_DS_SAMPLES 64 +static const uint32_t IGNEUM_DS_SAMPLE_INDEX[IGNEUM_DS_SAMPLES] = { + 59471966u, 217795994u, 208353206u, 42483309u, 172547758u, 148076330u, 183853158u, 214389424u, 267488061u, 169781097u, 184093494u, 153880993u, 84977930u, 46426879u, 3093825u, 225364072u, 44593546u, 260713159u, 168250303u, 52384140u, 223401610u, 45554030u, 95410555u, 175039924u, 79171087u, 267580473u, 24168642u, 37981670u, 171551130u, 195559979u, 204611762u, 140997658u, 138925853u, 86637313u, 20736778u, 219665210u, 160430336u, 264654675u, 8013395u, 228945585u, 213884386u, 104419827u, 44185464u, 142737231u, 99284897u, 132475900u, 61861762u, 132056166u, 262388043u, 91878046u, 117353561u, 124768597u, 71352993u, 190698941u, 46055428u, 55281366u, 165145231u, 106810753u, 171985651u, 232085256u, 159510492u, 40072060u, 209107596u, 39023794u +}; +static const uint32_t IGNEUM_DS_SAMPLE_VALUE[IGNEUM_DS_SAMPLES] = { + 0x3230bc7bu, 0x7fbfe2c9u, 0xb2690991u, 0x1745c7c5u, 0x0ab0ccafu, 0x1bf87d6bu, 0x160139fdu, 0x719817acu, 0x0155df4bu, 0xbe1e86c3u, 0x680bcd6cu, 0x79c3dc6cu, 0x181e7e5fu, 0x0713a109u, 0xc705dd9fu, 0x3933b7a8u, 0xdd1c0431u, 0x50522b30u, 0xa0020b38u, 0xbff39e96u, 0x21b67e18u, 0x740f8db3u, 0x2baba568u, 0x2c9bef83u, 0x0ad9b671u, 0xc4327869u, 0x7b4fd7d0u, 0x2c29965fu, 0xec56f15fu, 0x61111746u, 0x303a1d6eu, 0xbddcfd1au, 0xf829a355u, 0x6d5df2a9u, 0x01ab8e44u, 0x06d13507u, 0xda8dcfc6u, 0x01a703e1u, 0xafe7d2c1u, 0xc091c3a2u, 0xac1814feu, 0x6e6ff62au, 0x8fdf01bau, 0xdd3f7159u, 0xdfa0d75cu, 0x26684c35u, 0x7f441e63u, 0x88df2570u, 0x8aa4d5ebu, 0xcc816c05u, 0x434df890u, 0xcd392ad6u, 0x1ab4cb63u, 0x595926fau, 0x7cd76b41u, 0x20cb95c4u, 0x13cf823fu, 0xf9daf901u, 0xff9af40au, 0x2c7dfa51u, 0x871206dbu, 0x938c116cu, 0xb64bf199u, 0x5751f874u +}; +// Cache self-test (memory-hard mode): cache[0..15], the last 16 words, and FNV-1a 64 over all 2^26 words. +static const uint32_t IGNEUM_CACHE_HEAD[16] = { + 0x355a86d2u, 0x7957db1cu, 0xd21772afu, 0x6fc1e09bu, 0xd55ce61du, 0x6e6a278bu, 0xd3f543ceu, 0x223d8e82u, + 0x143ab337u, 0x2e9f05bdu, 0x2eb389bfu, 0x0c6e449eu, 0x5cfa4222u, 0xba6560feu, 0x8e3e1aa4u, 0xdbcc1d53u +}; +static const uint32_t IGNEUM_CACHE_LAST[16] = { + 0x41190d91u, 0xbd277957u, 0x22ddbb49u, 0x6986f207u, 0xdf69a4d6u, 0x26401a3au, 0x818230fbu, 0xc417122du, + 0x3597b211u, 0xb553ce55u, 0xcf39cc0du, 0x3b7fc43au, 0x3fd43b00u, 0x67e1c80eu, 0xffa7ea7du, 0xca2960abu +}; +static const uint64_t IGNEUM_CACHE_FNV64 = 0x48c4f5bf24166b2eull; diff --git a/proto-cuda/packs-ca3-shadow/sh256x7/vectors.json b/proto-cuda/packs-ca3-shadow/sh256x7/vectors.json new file mode 100644 index 000000000..9eac3ef12 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x7/vectors.json @@ -0,0 +1,36 @@ +{ + "seed": "igneum-genesis", + "day": "2026-10-03", + "dataset_mode": "memory-hard", + "dataset_log2_words": 28, + "mask": "0x0fffffff", + "lanes": 32, + "source": "igneum-pow (Rust) CPU interpreter, generator v2, memory-hard dataset", + "warps": [ + {"base_nonce": 0, "expected": [ + "0xda6688d14887f390", "0xa967fb5329ab8301", "0xb36d89ddf3f7013a", "0x8e5916887c019c5b", "0x0b1b5e0a470dda07", "0x9743557891c694a0", "0x8b58ec4694a4b51e", "0xaaa22b2c46199c0d", + "0xb5e07c83348843f6", "0xda3e0641a2fbfa9a", "0xea345b25e33952a8", "0x60b3693e4faa00b0", "0x11d7c24c8a92244c", "0x3ac69fc6a553a1c5", "0x3248ecb535caa90e", "0x5ed2eb6b3cdf16d0", + "0xaf92f32b6f8168d2", "0x753473cbf8f9d4ba", "0xb5aebafe1e77eb62", "0xf14ddaae76168834", "0xf4fcd368a46402e2", "0x219ab478cf87bd15", "0xb7742b0f7031c081", "0x17ea8d82545060e5", + "0xced8eb883ff74e61", "0xeb0ea2bf4b3dd264", "0x4c6fa8f5f99206fa", "0x3e6345b3f4e6938c", "0x3ff0db0f089c87e7", "0x3d6f1b5d9f4795ab", "0xb9d7ad3179722417", "0xb7c54d6324fb8b3b" + ]}, + {"base_nonce": 4096, "expected": [ + "0xe3b44b175fc21b28", "0x3cbcac8cf0157f56", "0x8ba8bd15c6e4fac5", "0xeea33e58ceaff2f9", "0x1aa91b8ed208e63d", "0x2de5d74a2ea58735", "0x1441f49981a3d1b0", "0x23435140f8545861", + "0x5b1d6ad6819e4d55", "0x92c7cd25d7f03d99", "0x9e52bf6eee3cd384", "0x296d5aea3ceed953", "0xd8ea21a9e77eaa7f", "0xb1f3ca3d7765a2a1", "0xf092c73783629a7b", "0x2fca1ad4ca6ebeaf", + "0x6502fa6e2782982d", "0xfddb10daa3a8bee3", "0x2e231d6ec341e3fa", "0xa37b7630551c909a", "0xc38f37d60ea55cbf", "0x2dca68ba3d90427c", "0x632441c2905865fb", "0xe222a7879098bad0", + "0x0b9702bfdfd8b4d4", "0xf647dd13007d96be", "0x047245e2c8ed40d4", "0x522dd7eb913cf443", "0x44c1490f64d1eb99", "0xbbb4e274a10aadab", "0x87f54e49f42ea1b4", "0x976c2cdffe1e715d" + ]}, + {"base_nonce": 1000000, "expected": [ + "0x8d57cd337f20fb07", "0x7ec4cd550630e97d", "0x19e3be943d762816", "0xa82016fc05af1cb4", "0xf9df7904600efee9", "0xeee8357d45fc5da0", "0x7034a05b56de2729", "0xa49c0f26c2c6c30a", + "0x8f6a1f26ad5d3ca8", "0x54be93649be7de81", "0xd91797784e113ede", "0x6629319ac39754fb", "0x03a17cbe16fc0b12", "0x1844d087f8df1e4a", "0x032115e4fee93f48", "0x97f1da84a885b38a", + "0x6a3cbad5a2cfe5ba", "0x6ecebd0bae287f5f", "0xaf2bce191bd441ca", "0x880692461306a21a", "0xae648081f8f93103", "0xf43d9de1f8d4f816", "0x93ed1344d9bae877", "0xa90b327f4ae55408", + "0xa497f12476c412ca", "0x907602bbe1d48d10", "0x7252c27e00e43794", "0x7382d4e82184f352", "0x70db6147f84715e8", "0x818f22a7878fbe21", "0x70d92097d7a7e469", "0xe03d1f285eab54a1" + ]} + ], + "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" +} diff --git a/proto-cuda/packs-ca3-shadow/sh256x88/kernel.cl b/proto-cuda/packs-ca3-shadow/sh256x88/kernel.cl new file mode 100644 index 000000000..389c69a32 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x88/kernel.cl @@ -0,0 +1,538 @@ +// 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 ^ 0x67a9a7beu; x += 0x9e3779b9u; x = splitmix32(x); r0 = x ^ 0x1a155b25u; } // SEEDW[0], 0x9e3779b9u * 1u, SEEDW[1] + { uint x = nonce ^ 0x1a155b25u; x += 0x3c6ef372u; x = splitmix32(x); r1 = x ^ 0xfddfb732u; } // SEEDW[1], 0x9e3779b9u * 2u, SEEDW[2] + { uint x = nonce ^ 0xfddfb732u; x += 0xdaa66d2bu; x = splitmix32(x); r2 = x ^ 0x4b5af2e8u; } // SEEDW[2], 0x9e3779b9u * 3u, SEEDW[3] + { uint x = nonce ^ 0x4b5af2e8u; x += 0x78dde6e4u; x = splitmix32(x); r3 = x ^ 0xc55caf33u; } // SEEDW[3], 0x9e3779b9u * 4u, SEEDW[4] + { uint x = nonce ^ 0xc55caf33u; x += 0x1715609du; x = splitmix32(x); r4 = x ^ 0xa27c13b7u; } // SEEDW[4], 0x9e3779b9u * 5u, SEEDW[5] + { uint x = nonce ^ 0xa27c13b7u; x += 0xb54cda56u; x = splitmix32(x); r5 = x ^ 0x06628a48u; } // SEEDW[5], 0x9e3779b9u * 6u, SEEDW[6] + { uint x = nonce ^ 0x06628a48u; x += 0x5384540fu; x = splitmix32(x); r6 = x ^ 0x03852469u; } // SEEDW[6], 0x9e3779b9u * 7u, SEEDW[7] + { uint x = nonce ^ 0x03852469u; x += 0xf1bbcdc8u; x = splitmix32(x); r7 = x ^ 0x67a9a7beu; } // SEEDW[7], 0x9e3779b9u * 8u, SEEDW[0] + + for (uint it = 0u; it < 8u; ++it) { + uint sel = r0; + r2 = r3 * r4 + r2; // 0 mad + r2 = r1 * r1 + r2; // 1 mad + r2 = r3 * r2 + r2; // 2 mad + r3 = r3 ^ r5; // 3 xor + r7 = r7 ^ ds[r2 & mask]; // 4 load + r5 = r5 ^ ds[r7 & mask]; // 5 load + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r1 = r1 ^ t_; } // 6 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r7 = r7 ^ t_; } // 7 shfl + r1 = mul_hi(r1, r5); // 8 mulhi + r6 = rotr_var(r6, r3); // 9 rotr + r3 = r3 | r4; // 10 or + r4 = r4 ^ ds[r3 & mask]; // 11 load + r0 = mul_hi(r0, r4); // 12 mulhi + r5 = r5 + r1 + ((((sel >> 30u) & 1u) != 0u) ? 0xd3177981u : 0xc7934706u); // 13 add + r0 = r0 ^ ds[r4 & mask]; // 14 load + r2 = r2 - r4; // 15 sub + r2 = r2 ^ ds[r0 & mask]; // 16 load + r7 = r7 ^ ds[r2 & mask]; // 17 load + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r7 = r7 ^ t_; } // 18 shfl + r5 = r5 * r0; // 19 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // 20 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 16u); r2 = r2 ^ t_; } // 21 shfl + r6 = mul_hi(r6, r2); // 22 mulhi + r6 = r6 ^ ds[r1 & mask]; // 23 load + r5 = r5 * r0; // 24 mul + r5 = rotl_imm(r5, 19u); // 25 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 2u); r7 = r7 ^ t_; } // 26 shfl + r0 = r0 ^ r5; // 27 xor + r0 = r0 ^ r4; // 28 xor + r3 = r3 - r0; // 29 sub + r5 = r5 * r1; // 30 mul + r7 = r7 ^ ds[r2 & mask]; // 31 load + r1 = r1 ^ ds[r0 & mask]; // 32 load + r5 = r5 ^ r6; // 33 xor + r5 = r5 ^ ds[r1 & mask]; // 34 load + r0 = mul_hi(r0, r5); // 35 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r5 = r5 ^ t_; } // 36 shfl + r7 = r7 ^ ds[r0 & mask]; // 37 load + r3 = r3 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0x230c005cu : 0x75ba2fadu); // 38 add + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 4u); r1 = r1 ^ t_; } // 39 shfl + r2 = r2 ^ r5; // 40 xor + r3 = r6 * r3 + r3; // 41 mad + r6 = r6 - r7; // 42 sub + r7 = r7 ^ r0; // 43 xor + r1 = r1 ^ ds[r7 & mask]; // 44 load + r2 = r2 * r3; // 45 mul + r1 = mul_hi(r1, r5); // 46 mulhi + r4 = r4 - r3; // 47 sub + r2 = rotr_var(r2, r6); // 48 rotr + r3 = r3 ^ ds[r5 & mask]; // 49 load + r1 = r1 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x1907970cu : 0x81b8bc2cu); // 50 add + r0 = r0 * r2; // 51 mul + r0 = r0 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x699fd448u : 0x4f92b968u); // 52 add + r1 = r1 + r0 + ((((sel >> 12u) & 1u) != 0u) ? 0x77b1520du : 0x2bb965afu); // 53 add + r7 = rotl_imm(r7, 14u); // 54 rotl + r3 = r3 + r7 + ((((sel >> 1u) & 1u) != 0u) ? 0xa54c55a0u : 0x7b0fe07au); // 55 add + r6 = r6 ^ ds[r7 & mask]; // 56 load + r1 = rotr_var(r1, r5); // 57 rotr + r5 = r5 ^ ds[r4 & mask]; // 58 load + r6 = r6 ^ ds[r2 & mask]; // 59 load + r3 = r5 * r0 + r3; // 60 mad + r5 = r5 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0xad7493e7u : 0xaf9dd72du); // 61 add + r4 = r4 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x1e07c3d9u : 0x89841d87u); // 62 add + r5 = rotl_imm(r5, 19u); // 63 rotl + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 88 passes after instruction 63, no load + for (uint sh = 0u; sh < 88u; ++sh) { + r5 = r5 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x8bc12da9u : 0x92199f99u); // s0 add + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x63079e5au : 0x8d72d3adu); // s1 add + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 2u); r6 = r6 ^ t_; } // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + ((((sel >> 31u) & 1u) != 0u) ? 0x5d4c7a60u : 0xb21b4babu); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + ((((sel >> 16u) & 1u) != 0u) ? 0xc88e2942u : 0x2fe0e98bu); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r6 = r6 ^ t_; } // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 4u); r2 = r2 ^ t_; } // s12 shfl + r1 = r1 + r5 + ((((sel >> 25u) & 1u) != 0u) ? 0xbc48c63eu : 0xbdf8f9a5u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r2 = r2 ^ t_; } // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + ((((sel >> 1u) & 1u) != 0u) ? 0x96e8f127u : 0x45c37cecu); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = mul_hi(r6, r0); // s28 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r2 = r2 ^ t_; } // s29 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r1 = r1 ^ t_; } // s30 shfl + r1 = r1 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0xb1cdb2abu : 0x37985632u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // s33 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r0 = r0 ^ t_; } // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x856e0180u : 0x804e777eu); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xe9bd0cc4u : 0x0b06c8a7u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = mul_hi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = mul_hi(r4, r3); // s44 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xcdcb63f6u : 0xee822e17u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r4 = r4 ^ t_; } // s47 shfl + r6 = mul_hi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0xd4758987u : 0x3dfad1b6u); // s56 add + r4 = r4 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x0602d6beu : 0xfca75bc2u); // s57 add + r5 = mul_hi(r5, r6); // s58 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r2 = r2 ^ t_; } // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0x8596687au : 0xd71c02ffu); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 2u); r7 = r7 ^ t_; } // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0x08ac5733u : 0x3c6fe15du); // s72 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r3 = r3 ^ t_; } // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + ((((sel >> 1u) & 1u) != 0u) ? 0xc100b495u : 0x295d5faeu); // s77 add + r3 = mul_hi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + ((((sel >> 15u) & 1u) != 0u) ? 0x5cc59530u : 0x274a9221u); // s81 add + r7 = r7 + r3 + ((((sel >> 5u) & 1u) != 0u) ? 0x141479ecu : 0xc8651f8eu); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r2 = r2 ^ t_; } // s85 shfl + r3 = r3 ^ r2; // s86 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 2u); r5 = r5 ^ t_; } // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x883c0c92u : 0x53f915c2u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + ((((sel >> 31u) & 1u) != 0u) ? 0x3cc5bd20u : 0xe2be00a5u); // s91 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 1u); r7 = r7 ^ t_; } // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + ((((sel >> 17u) & 1u) != 0u) ? 0xbfd646cbu : 0x423fd9c9u); // s101 add + r7 = r7 + r6 + ((((sel >> 11u) & 1u) != 0u) ? 0x19b74a43u : 0x8d3c011du); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + ((((sel >> 15u) & 1u) != 0u) ? 0x7dcb7e18u : 0x8ce14721u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = mul_hi(r2, r0); // s109 mulhi + r1 = mul_hi(r1, r0); // s110 mulhi + r0 = r0 + r2 + ((((sel >> 28u) & 1u) != 0u) ? 0x3c179ad8u : 0x2d9fc6b9u); // s111 add + r2 = mul_hi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + ((((sel >> 22u) & 1u) != 0u) ? 0x47359729u : 0x502138e2u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = mul_hi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 2u); r4 = r4 ^ t_; } // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r7 = r7 ^ t_; } // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x6c57e4e7u : 0x33dff776u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + ((((sel >> 30u) & 1u) != 0u) ? 0xe8212c0cu : 0x5db25b34u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = mul_hi(r0, r5); // s138 mulhi + r2 = r2 + r7 + ((((sel >> 10u) & 1u) != 0u) ? 0xd44ff710u : 0x218d4090u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r3 = r3 ^ t_; } // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + ((((sel >> 29u) & 1u) != 0u) ? 0xb98942fau : 0xf4b1a8deu); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + ((((sel >> 17u) & 1u) != 0u) ? 0x0d48ba42u : 0x2bef10f2u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + ((((sel >> 30u) & 1u) != 0u) ? 0xc98dea9cu : 0xdc5cc080u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0x6c752dcbu : 0x18197438u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + ((((sel >> 3u) & 1u) != 0u) ? 0x8e481727u : 0xf1c46574u); // s163 add + r0 = mul_hi(r0, r4); // s164 mulhi + r2 = r2 + r6 + ((((sel >> 20u) & 1u) != 0u) ? 0x550ab406u : 0xac578137u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + ((((sel >> 14u) & 1u) != 0u) ? 0xaebb5966u : 0xa33e6706u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 8u); r7 = r7 ^ t_; } // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x5bb7550fu : 0xd94d55acu); // s184 add + r3 = r3 | r5; // s185 or + r6 = mul_hi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r7 = r7 ^ t_; } // s188 shfl + r6 = r6 + r5 + ((((sel >> 6u) & 1u) != 0u) ? 0x2a354e2du : 0x89e747feu); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = mul_hi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r4 = r4 ^ t_; } // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + ((((sel >> 7u) & 1u) != 0u) ? 0x10cfdc71u : 0xea03e8e7u); // s197 add + r7 = r7 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x66e148d3u : 0xa7ee0102u); // s198 add + r5 = r5 - r2; // s199 sub + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r5 = r5 ^ t_; } // s200 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 8u); r7 = r7 ^ t_; } // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0x8558b619u : 0x8379a4deu); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = mul_hi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 4u); r2 = r2 ^ t_; } // s209 shfl + r7 = r7 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0xf4049c4cu : 0xaa8cb14eu); // s210 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 16u); r7 = r7 ^ t_; } // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 16u); r3 = r3 ^ t_; } // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = mul_hi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r5 = r5 ^ t_; } // s222 shfl + r5 = mul_hi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0x2a7fecb2u : 0x1d176220u); // s230 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r1 = r1 ^ t_; } // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + ((((sel >> 25u) & 1u) != 0u) ? 0xadce39f3u : 0x17dafb4du); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + ((((sel >> 29u) & 1u) != 0u) ? 0x0e7033b6u : 0xf2f77d26u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + ((((sel >> 31u) & 1u) != 0u) ? 0x7b2ff6b7u : 0xfed2da4eu); // s247 add + r0 = r0 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0xb5fad7b1u : 0x03b2891cu); // s248 add + r5 = mul_hi(r5, r4); // s249 mulhi + r5 = r5 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0xa7e71c2fu : 0x042cd6e3u); // s250 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 1u); r6 = r6 ^ t_; } // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0xb83d78deu : 0x784a302bu); // s254 add + r2 = r2 - r4; // s255 sub + } + } + uint lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((ulong)hi << 32) | (ulong)lo; +} + +#if IGNEUM_EXCHANGE != 0 +// Reports the sub-group size this device uses for a work-group of IGNEUM_GROUP items. host.c runs it only when the +// per-kernel query (clGetKernelSubGroupInfoKHR on igneum_hash) is unavailable; that query is preferred because a +// compiler may pick a different wave width per kernel (RDNA: wave32 or wave64). See WAVEFRONT.md. +IGNEUM_KERNEL_HASH void igneum_probe_subgroup(__global uint* out) { + if (get_local_id(0) == 0u) { out[0] = get_sub_group_size(); out[1] = get_num_sub_groups(); } +} +#endif diff --git a/proto-cuda/packs-ca3-shadow/sh256x88/kernel.cu b/proto-cuda/packs-ca3-shadow/sh256x88/kernel.cu new file mode 100644 index 000000000..04b229046 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x88/kernel.cu @@ -0,0 +1,423 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Bit-exact twin of the Metal kernel for the same seed (see proto-cuda/CHECKLIST.md and program.metal). +// Compiled ahead of time by nvcc together with proto-cuda/host.cu. No NVRTC. +#include +#include +#include "program.h" +#include "memhard.h" + +__device__ __forceinline__ uint32_t splitmix32(uint32_t x) { + x ^= x >> 16; x *= 0x7feb352du; + x ^= x >> 15; x *= 0x846ca68bu; + x ^= x >> 16; + return x; +} +// n is a literal in 1..31 at every call site, so both shift amounts are in 1..31. +__device__ __forceinline__ uint32_t rotl_imm(uint32_t x, uint32_t n) { return (x << n) | (x >> (32u - n)); } +// n is masked to 0..31; the second shift amount is masked too, so n == 0 gives x. +__device__ __forceinline__ uint32_t rotr_var(uint32_t x, uint32_t n) { n &= 31u; return (x >> n) | (x << ((32u - n) & 31u)); } +__device__ __forceinline__ uint32_t ds_elem(uint32_t i, uint32_t d0, uint32_t d1) { + uint32_t x = i ^ d0; + x *= 0x9E3779B1u; x ^= x >> 15; + x += d1; + x *= 0x85EBCA77u; x ^= x >> 13; + x *= 0xC2B2AE3Du; x ^= x >> 16; + return x; +} + +// Memory-hard dataset (MEMHARD.md). One thread per cache segment; one thread per 64-byte dataset item. +// The core functions (mh_cache_segment, mh_item) are in memhard.h and are also compiled for the host. +__global__ void igneum_cache_fill(uint32_t* cache, uint32_t nSegments) { + uint32_t seg = blockIdx.x * blockDim.x + threadIdx.x; + if (seg < nSegments) mh_cache_segment(cache, seg); +} +__global__ void igneum_build(uint32_t* ds, const uint32_t* cache, uint32_t nItems) { + uint32_t t = blockIdx.x * blockDim.x + threadIdx.x; + if (t < nItems) { + uint32_t s[16]; + mh_item(cache, t, s); + uint32_t* d = ds + (size_t)t * 16u; + for (uint32_t i = 0u; i < 16u; ++i) d[i] = s[i]; + } +} + +// One hash per thread. blockDim.x is a multiple of 32; lane = threadIdx.x & 31 and every +// __shfl_xor_sync stays inside the lane's own warp, exactly like simd_shuffle_xor inside a +// 32-wide Metal SIMD group. Control flow is uniform, so the full 0xffffffff member mask is valid. +__global__ void igneum_hash(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask) { + uint32_t gid = blockIdx.x * blockDim.x + threadIdx.x; + uint32_t nonce = baseNonce + gid; + uint32_t r0, r1, r2, r3, r4, r5, r6, r7; + { uint32_t x = nonce ^ 0x67a9a7beu; x += 0x9e3779b9u; x = splitmix32(x); r0 = x ^ 0x1a155b25u; } // SEEDW[0], 0x9e3779b9u * 1u, SEEDW[1] + { uint32_t x = nonce ^ 0x1a155b25u; x += 0x3c6ef372u; x = splitmix32(x); r1 = x ^ 0xfddfb732u; } // SEEDW[1], 0x9e3779b9u * 2u, SEEDW[2] + { uint32_t x = nonce ^ 0xfddfb732u; x += 0xdaa66d2bu; x = splitmix32(x); r2 = x ^ 0x4b5af2e8u; } // SEEDW[2], 0x9e3779b9u * 3u, SEEDW[3] + { uint32_t x = nonce ^ 0x4b5af2e8u; x += 0x78dde6e4u; x = splitmix32(x); r3 = x ^ 0xc55caf33u; } // SEEDW[3], 0x9e3779b9u * 4u, SEEDW[4] + { uint32_t x = nonce ^ 0xc55caf33u; x += 0x1715609du; x = splitmix32(x); r4 = x ^ 0xa27c13b7u; } // SEEDW[4], 0x9e3779b9u * 5u, SEEDW[5] + { uint32_t x = nonce ^ 0xa27c13b7u; x += 0xb54cda56u; x = splitmix32(x); r5 = x ^ 0x06628a48u; } // SEEDW[5], 0x9e3779b9u * 6u, SEEDW[6] + { uint32_t x = nonce ^ 0x06628a48u; x += 0x5384540fu; x = splitmix32(x); r6 = x ^ 0x03852469u; } // SEEDW[6], 0x9e3779b9u * 7u, SEEDW[7] + { uint32_t x = nonce ^ 0x03852469u; x += 0xf1bbcdc8u; x = splitmix32(x); r7 = x ^ 0x67a9a7beu; } // SEEDW[7], 0x9e3779b9u * 8u, SEEDW[0] + + for (uint32_t it = 0u; it < 8u; ++it) { + uint32_t sel = r0; + r2 = r3 * r4 + r2; // 0 mad + r2 = r1 * r1 + r2; // 1 mad + r2 = r3 * r2 + r2; // 2 mad + r3 = r3 ^ r5; // 3 xor + r7 = r7 ^ ds[r2 & mask]; // 4 load + r5 = r5 ^ ds[r7 & mask]; // 5 load + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r4, 8); // 6 shfl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r3, 8); // 7 shfl + r1 = __umulhi(r1, r5); // 8 mulhi + r6 = rotr_var(r6, r3); // 9 rotr + r3 = r3 | r4; // 10 or + r4 = r4 ^ ds[r3 & mask]; // 11 load + r0 = __umulhi(r0, r4); // 12 mulhi + r5 = r5 + r1 + ((((sel >> 30u) & 1u) != 0u) ? 0xd3177981u : 0xc7934706u); // 13 add + r0 = r0 ^ ds[r4 & mask]; // 14 load + r2 = r2 - r4; // 15 sub + r2 = r2 ^ ds[r0 & mask]; // 16 load + r7 = r7 ^ ds[r2 & mask]; // 17 load + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r3, 4); // 18 shfl + r5 = r5 * r0; // 19 mul + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // 20 shfl + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 16); // 21 shfl + r6 = __umulhi(r6, r2); // 22 mulhi + r6 = r6 ^ ds[r1 & mask]; // 23 load + r5 = r5 * r0; // 24 mul + r5 = rotl_imm(r5, 19u); // 25 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r6, 2); // 26 shfl + r0 = r0 ^ r5; // 27 xor + r0 = r0 ^ r4; // 28 xor + r3 = r3 - r0; // 29 sub + r5 = r5 * r1; // 30 mul + r7 = r7 ^ ds[r2 & mask]; // 31 load + r1 = r1 ^ ds[r0 & mask]; // 32 load + r5 = r5 ^ r6; // 33 xor + r5 = r5 ^ ds[r1 & mask]; // 34 load + r0 = __umulhi(r0, r5); // 35 mulhi + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // 36 shfl + r7 = r7 ^ ds[r0 & mask]; // 37 load + r3 = r3 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0x230c005cu : 0x75ba2fadu); // 38 add + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r5, 4); // 39 shfl + r2 = r2 ^ r5; // 40 xor + r3 = r6 * r3 + r3; // 41 mad + r6 = r6 - r7; // 42 sub + r7 = r7 ^ r0; // 43 xor + r1 = r1 ^ ds[r7 & mask]; // 44 load + r2 = r2 * r3; // 45 mul + r1 = __umulhi(r1, r5); // 46 mulhi + r4 = r4 - r3; // 47 sub + r2 = rotr_var(r2, r6); // 48 rotr + r3 = r3 ^ ds[r5 & mask]; // 49 load + r1 = r1 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x1907970cu : 0x81b8bc2cu); // 50 add + r0 = r0 * r2; // 51 mul + r0 = r0 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x699fd448u : 0x4f92b968u); // 52 add + r1 = r1 + r0 + ((((sel >> 12u) & 1u) != 0u) ? 0x77b1520du : 0x2bb965afu); // 53 add + r7 = rotl_imm(r7, 14u); // 54 rotl + r3 = r3 + r7 + ((((sel >> 1u) & 1u) != 0u) ? 0xa54c55a0u : 0x7b0fe07au); // 55 add + r6 = r6 ^ ds[r7 & mask]; // 56 load + r1 = rotr_var(r1, r5); // 57 rotr + r5 = r5 ^ ds[r4 & mask]; // 58 load + r6 = r6 ^ ds[r2 & mask]; // 59 load + r3 = r5 * r0 + r3; // 60 mad + r5 = r5 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0xad7493e7u : 0xaf9dd72du); // 61 add + r4 = r4 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x1e07c3d9u : 0x89841d87u); // 62 add + r5 = rotl_imm(r5, 19u); // 63 rotl + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 88 passes after instruction 63, no load + for (uint32_t sh = 0u; sh < 88u; ++sh) { + r5 = r5 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x8bc12da9u : 0x92199f99u); // s0 add + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x63079e5au : 0x8d72d3adu); // s1 add + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r3, 2); // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + ((((sel >> 31u) & 1u) != 0u) ? 0x5d4c7a60u : 0xb21b4babu); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + ((((sel >> 16u) & 1u) != 0u) ? 0xc88e2942u : 0x2fe0e98bu); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r1, 4); // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r6, 4); // s12 shfl + r1 = r1 + r5 + ((((sel >> 25u) & 1u) != 0u) ? 0xbc48c63eu : 0xbdf8f9a5u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 8); // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + ((((sel >> 1u) & 1u) != 0u) ? 0x96e8f127u : 0x45c37cecu); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = __umulhi(r6, r0); // s28 mulhi + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // s29 shfl + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r6, 1); // s30 shfl + r1 = r1 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0xb1cdb2abu : 0x37985632u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // s33 shfl + r0 = r0 ^ __shfl_xor_sync(0xffffffffu, r3, 4); // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x856e0180u : 0x804e777eu); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xe9bd0cc4u : 0x0b06c8a7u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = __umulhi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = __umulhi(r4, r3); // s44 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xcdcb63f6u : 0xee822e17u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r3, 8); // s47 shfl + r6 = __umulhi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0xd4758987u : 0x3dfad1b6u); // s56 add + r4 = r4 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x0602d6beu : 0xfca75bc2u); // s57 add + r5 = __umulhi(r5, r6); // s58 mulhi + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0x8596687au : 0xd71c02ffu); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r5, 2); // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0x08ac5733u : 0x3c6fe15du); // s72 add + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r2, 8); // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + ((((sel >> 1u) & 1u) != 0u) ? 0xc100b495u : 0x295d5faeu); // s77 add + r3 = __umulhi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + ((((sel >> 15u) & 1u) != 0u) ? 0x5cc59530u : 0x274a9221u); // s81 add + r7 = r7 + r3 + ((((sel >> 5u) & 1u) != 0u) ? 0x141479ecu : 0xc8651f8eu); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r5, 16); // s85 shfl + r3 = r3 ^ r2; // s86 xor + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r7, 2); // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x883c0c92u : 0x53f915c2u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + ((((sel >> 31u) & 1u) != 0u) ? 0x3cc5bd20u : 0xe2be00a5u); // s91 add + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r2, 1); // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + ((((sel >> 17u) & 1u) != 0u) ? 0xbfd646cbu : 0x423fd9c9u); // s101 add + r7 = r7 + r6 + ((((sel >> 11u) & 1u) != 0u) ? 0x19b74a43u : 0x8d3c011du); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + ((((sel >> 15u) & 1u) != 0u) ? 0x7dcb7e18u : 0x8ce14721u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = __umulhi(r2, r0); // s109 mulhi + r1 = __umulhi(r1, r0); // s110 mulhi + r0 = r0 + r2 + ((((sel >> 28u) & 1u) != 0u) ? 0x3c179ad8u : 0x2d9fc6b9u); // s111 add + r2 = __umulhi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + ((((sel >> 22u) & 1u) != 0u) ? 0x47359729u : 0x502138e2u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = __umulhi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r2, 2); // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x6c57e4e7u : 0x33dff776u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + ((((sel >> 30u) & 1u) != 0u) ? 0xe8212c0cu : 0x5db25b34u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = __umulhi(r0, r5); // s138 mulhi + r2 = r2 + r7 + ((((sel >> 10u) & 1u) != 0u) ? 0xd44ff710u : 0x218d4090u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r6, 1); // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + ((((sel >> 29u) & 1u) != 0u) ? 0xb98942fau : 0xf4b1a8deu); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + ((((sel >> 17u) & 1u) != 0u) ? 0x0d48ba42u : 0x2bef10f2u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + ((((sel >> 30u) & 1u) != 0u) ? 0xc98dea9cu : 0xdc5cc080u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0x6c752dcbu : 0x18197438u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + ((((sel >> 3u) & 1u) != 0u) ? 0x8e481727u : 0xf1c46574u); // s163 add + r0 = __umulhi(r0, r4); // s164 mulhi + r2 = r2 + r6 + ((((sel >> 20u) & 1u) != 0u) ? 0x550ab406u : 0xac578137u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + ((((sel >> 14u) & 1u) != 0u) ? 0xaebb5966u : 0xa33e6706u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r0, 8); // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x5bb7550fu : 0xd94d55acu); // s184 add + r3 = r3 | r5; // s185 or + r6 = __umulhi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s188 shfl + r6 = r6 + r5 + ((((sel >> 6u) & 1u) != 0u) ? 0x2a354e2du : 0x89e747feu); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = __umulhi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r5, 16); // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + ((((sel >> 7u) & 1u) != 0u) ? 0x10cfdc71u : 0xea03e8e7u); // s197 add + r7 = r7 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x66e148d3u : 0xa7ee0102u); // s198 add + r5 = r5 - r2; // s199 sub + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s200 shfl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 8); // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0x8558b619u : 0x8379a4deu); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = __umulhi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r0, 4); // s209 shfl + r7 = r7 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0xf4049c4cu : 0xaa8cb14eu); // s210 add + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 16); // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r2, 16); // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = __umulhi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r2, 8); // s222 shfl + r5 = __umulhi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0x2a7fecb2u : 0x1d176220u); // s230 add + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + ((((sel >> 25u) & 1u) != 0u) ? 0xadce39f3u : 0x17dafb4du); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + ((((sel >> 29u) & 1u) != 0u) ? 0x0e7033b6u : 0xf2f77d26u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + ((((sel >> 31u) & 1u) != 0u) ? 0x7b2ff6b7u : 0xfed2da4eu); // s247 add + r0 = r0 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0xb5fad7b1u : 0x03b2891cu); // s248 add + r5 = __umulhi(r5, r4); // s249 mulhi + r5 = r5 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0xa7e71c2fu : 0x042cd6e3u); // s250 add + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r1, 1); // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0xb83d78deu : 0x784a302bu); // s254 add + r2 = r2 - r4; // s255 sub + } + } + uint32_t lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint32_t hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((uint64_t)hi << 32) | (uint64_t)lo; +} + +// Host-side launch wrappers. Declared in program.h, called from host.cu. +cudaError_t igneum_launch_cache_fill(uint32_t* cache, uint32_t nSegments) { + if (nSegments == 0u) return cudaErrorInvalidValue; + uint32_t block = 256u; + uint32_t grid = (nSegments + block - 1u) / block; + igneum_cache_fill<<>>(cache, nSegments); + return cudaGetLastError(); +} + +cudaError_t igneum_launch_build(uint32_t* ds, const uint32_t* cache, uint32_t nItems) { + if (nItems == 0u) return cudaErrorInvalidValue; + uint32_t block = 256u; + uint32_t grid = (nItems + block - 1u) / block; + igneum_build<<>>(ds, cache, nItems); + return cudaGetLastError(); +} + +cudaError_t igneum_launch_hash(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, + uint32_t nonces, uint32_t blockWarps) { + if (blockWarps == 0u || blockWarps > 32u) return cudaErrorInvalidValue; + uint32_t block = 32u * blockWarps; + if (nonces == 0u || (nonces % block) != 0u) return cudaErrorInvalidValue; + igneum_hash<<>>(ds, out, baseNonce, mask); + return cudaGetLastError(); +} + +cudaError_t igneum_hash_info(int* numRegs, int* blocksPerSM, uint32_t blockWarps) { + cudaFuncAttributes attr; + cudaError_t e = cudaFuncGetAttributes(&attr, igneum_hash); + if (e != cudaSuccess) return e; + *numRegs = attr.numRegs; + return cudaOccupancyMaxActiveBlocksPerMultiprocessor(blocksPerSM, igneum_hash, (int)(32u * blockWarps), 0); +} diff --git a/proto-cuda/packs-ca3-shadow/sh256x88/kernel_bound.cl b/proto-cuda/packs-ca3-shadow/sh256x88/kernel_bound.cl new file mode 100644 index 000000000..34d4fea9d --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x88/kernel_bound.cl @@ -0,0 +1,891 @@ +// 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 ^ 0x67a9a7beu; x += 0x9e3779b9u; x = splitmix32(x); r0 = x ^ 0x1a155b25u; } // SEEDW[0], 0x9e3779b9u * 1u, SEEDW[1] + { uint x = nonce ^ 0x1a155b25u; x += 0x3c6ef372u; x = splitmix32(x); r1 = x ^ 0xfddfb732u; } // SEEDW[1], 0x9e3779b9u * 2u, SEEDW[2] + { uint x = nonce ^ 0xfddfb732u; x += 0xdaa66d2bu; x = splitmix32(x); r2 = x ^ 0x4b5af2e8u; } // SEEDW[2], 0x9e3779b9u * 3u, SEEDW[3] + { uint x = nonce ^ 0x4b5af2e8u; x += 0x78dde6e4u; x = splitmix32(x); r3 = x ^ 0xc55caf33u; } // SEEDW[3], 0x9e3779b9u * 4u, SEEDW[4] + { uint x = nonce ^ 0xc55caf33u; x += 0x1715609du; x = splitmix32(x); r4 = x ^ 0xa27c13b7u; } // SEEDW[4], 0x9e3779b9u * 5u, SEEDW[5] + { uint x = nonce ^ 0xa27c13b7u; x += 0xb54cda56u; x = splitmix32(x); r5 = x ^ 0x06628a48u; } // SEEDW[5], 0x9e3779b9u * 6u, SEEDW[6] + { uint x = nonce ^ 0x06628a48u; x += 0x5384540fu; x = splitmix32(x); r6 = x ^ 0x03852469u; } // SEEDW[6], 0x9e3779b9u * 7u, SEEDW[7] + { uint x = nonce ^ 0x03852469u; x += 0xf1bbcdc8u; x = splitmix32(x); r7 = x ^ 0x67a9a7beu; } // SEEDW[7], 0x9e3779b9u * 8u, SEEDW[0] + + for (uint it = 0u; it < 8u; ++it) { + uint sel = r0; + r2 = r3 * r4 + r2; // 0 mad + r2 = r1 * r1 + r2; // 1 mad + r2 = r3 * r2 + r2; // 2 mad + r3 = r3 ^ r5; // 3 xor + r7 = r7 ^ ds[r2 & mask]; // 4 load + r5 = r5 ^ ds[r7 & mask]; // 5 load + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r1 = r1 ^ t_; } // 6 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r7 = r7 ^ t_; } // 7 shfl + r1 = mul_hi(r1, r5); // 8 mulhi + r6 = rotr_var(r6, r3); // 9 rotr + r3 = r3 | r4; // 10 or + r4 = r4 ^ ds[r3 & mask]; // 11 load + r0 = mul_hi(r0, r4); // 12 mulhi + r5 = r5 + r1 + ((((sel >> 30u) & 1u) != 0u) ? 0xd3177981u : 0xc7934706u); // 13 add + r0 = r0 ^ ds[r4 & mask]; // 14 load + r2 = r2 - r4; // 15 sub + r2 = r2 ^ ds[r0 & mask]; // 16 load + r7 = r7 ^ ds[r2 & mask]; // 17 load + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r7 = r7 ^ t_; } // 18 shfl + r5 = r5 * r0; // 19 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // 20 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 16u); r2 = r2 ^ t_; } // 21 shfl + r6 = mul_hi(r6, r2); // 22 mulhi + r6 = r6 ^ ds[r1 & mask]; // 23 load + r5 = r5 * r0; // 24 mul + r5 = rotl_imm(r5, 19u); // 25 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 2u); r7 = r7 ^ t_; } // 26 shfl + r0 = r0 ^ r5; // 27 xor + r0 = r0 ^ r4; // 28 xor + r3 = r3 - r0; // 29 sub + r5 = r5 * r1; // 30 mul + r7 = r7 ^ ds[r2 & mask]; // 31 load + r1 = r1 ^ ds[r0 & mask]; // 32 load + r5 = r5 ^ r6; // 33 xor + r5 = r5 ^ ds[r1 & mask]; // 34 load + r0 = mul_hi(r0, r5); // 35 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r5 = r5 ^ t_; } // 36 shfl + r7 = r7 ^ ds[r0 & mask]; // 37 load + r3 = r3 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0x230c005cu : 0x75ba2fadu); // 38 add + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 4u); r1 = r1 ^ t_; } // 39 shfl + r2 = r2 ^ r5; // 40 xor + r3 = r6 * r3 + r3; // 41 mad + r6 = r6 - r7; // 42 sub + r7 = r7 ^ r0; // 43 xor + r1 = r1 ^ ds[r7 & mask]; // 44 load + r2 = r2 * r3; // 45 mul + r1 = mul_hi(r1, r5); // 46 mulhi + r4 = r4 - r3; // 47 sub + r2 = rotr_var(r2, r6); // 48 rotr + r3 = r3 ^ ds[r5 & mask]; // 49 load + r1 = r1 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x1907970cu : 0x81b8bc2cu); // 50 add + r0 = r0 * r2; // 51 mul + r0 = r0 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x699fd448u : 0x4f92b968u); // 52 add + r1 = r1 + r0 + ((((sel >> 12u) & 1u) != 0u) ? 0x77b1520du : 0x2bb965afu); // 53 add + r7 = rotl_imm(r7, 14u); // 54 rotl + r3 = r3 + r7 + ((((sel >> 1u) & 1u) != 0u) ? 0xa54c55a0u : 0x7b0fe07au); // 55 add + r6 = r6 ^ ds[r7 & mask]; // 56 load + r1 = rotr_var(r1, r5); // 57 rotr + r5 = r5 ^ ds[r4 & mask]; // 58 load + r6 = r6 ^ ds[r2 & mask]; // 59 load + r3 = r5 * r0 + r3; // 60 mad + r5 = r5 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0xad7493e7u : 0xaf9dd72du); // 61 add + r4 = r4 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x1e07c3d9u : 0x89841d87u); // 62 add + r5 = rotl_imm(r5, 19u); // 63 rotl + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 88 passes after instruction 63, no load + for (uint sh = 0u; sh < 88u; ++sh) { + r5 = r5 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x8bc12da9u : 0x92199f99u); // s0 add + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x63079e5au : 0x8d72d3adu); // s1 add + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 2u); r6 = r6 ^ t_; } // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + ((((sel >> 31u) & 1u) != 0u) ? 0x5d4c7a60u : 0xb21b4babu); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + ((((sel >> 16u) & 1u) != 0u) ? 0xc88e2942u : 0x2fe0e98bu); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r6 = r6 ^ t_; } // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 4u); r2 = r2 ^ t_; } // s12 shfl + r1 = r1 + r5 + ((((sel >> 25u) & 1u) != 0u) ? 0xbc48c63eu : 0xbdf8f9a5u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r2 = r2 ^ t_; } // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + ((((sel >> 1u) & 1u) != 0u) ? 0x96e8f127u : 0x45c37cecu); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = mul_hi(r6, r0); // s28 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r2 = r2 ^ t_; } // s29 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r1 = r1 ^ t_; } // s30 shfl + r1 = r1 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0xb1cdb2abu : 0x37985632u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // s33 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r0 = r0 ^ t_; } // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x856e0180u : 0x804e777eu); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xe9bd0cc4u : 0x0b06c8a7u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = mul_hi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = mul_hi(r4, r3); // s44 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xcdcb63f6u : 0xee822e17u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r4 = r4 ^ t_; } // s47 shfl + r6 = mul_hi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0xd4758987u : 0x3dfad1b6u); // s56 add + r4 = r4 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x0602d6beu : 0xfca75bc2u); // s57 add + r5 = mul_hi(r5, r6); // s58 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r2 = r2 ^ t_; } // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0x8596687au : 0xd71c02ffu); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 2u); r7 = r7 ^ t_; } // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0x08ac5733u : 0x3c6fe15du); // s72 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r3 = r3 ^ t_; } // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + ((((sel >> 1u) & 1u) != 0u) ? 0xc100b495u : 0x295d5faeu); // s77 add + r3 = mul_hi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + ((((sel >> 15u) & 1u) != 0u) ? 0x5cc59530u : 0x274a9221u); // s81 add + r7 = r7 + r3 + ((((sel >> 5u) & 1u) != 0u) ? 0x141479ecu : 0xc8651f8eu); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r2 = r2 ^ t_; } // s85 shfl + r3 = r3 ^ r2; // s86 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 2u); r5 = r5 ^ t_; } // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x883c0c92u : 0x53f915c2u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + ((((sel >> 31u) & 1u) != 0u) ? 0x3cc5bd20u : 0xe2be00a5u); // s91 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 1u); r7 = r7 ^ t_; } // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + ((((sel >> 17u) & 1u) != 0u) ? 0xbfd646cbu : 0x423fd9c9u); // s101 add + r7 = r7 + r6 + ((((sel >> 11u) & 1u) != 0u) ? 0x19b74a43u : 0x8d3c011du); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + ((((sel >> 15u) & 1u) != 0u) ? 0x7dcb7e18u : 0x8ce14721u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = mul_hi(r2, r0); // s109 mulhi + r1 = mul_hi(r1, r0); // s110 mulhi + r0 = r0 + r2 + ((((sel >> 28u) & 1u) != 0u) ? 0x3c179ad8u : 0x2d9fc6b9u); // s111 add + r2 = mul_hi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + ((((sel >> 22u) & 1u) != 0u) ? 0x47359729u : 0x502138e2u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = mul_hi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 2u); r4 = r4 ^ t_; } // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r7 = r7 ^ t_; } // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x6c57e4e7u : 0x33dff776u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + ((((sel >> 30u) & 1u) != 0u) ? 0xe8212c0cu : 0x5db25b34u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = mul_hi(r0, r5); // s138 mulhi + r2 = r2 + r7 + ((((sel >> 10u) & 1u) != 0u) ? 0xd44ff710u : 0x218d4090u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r3 = r3 ^ t_; } // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + ((((sel >> 29u) & 1u) != 0u) ? 0xb98942fau : 0xf4b1a8deu); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + ((((sel >> 17u) & 1u) != 0u) ? 0x0d48ba42u : 0x2bef10f2u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + ((((sel >> 30u) & 1u) != 0u) ? 0xc98dea9cu : 0xdc5cc080u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0x6c752dcbu : 0x18197438u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + ((((sel >> 3u) & 1u) != 0u) ? 0x8e481727u : 0xf1c46574u); // s163 add + r0 = mul_hi(r0, r4); // s164 mulhi + r2 = r2 + r6 + ((((sel >> 20u) & 1u) != 0u) ? 0x550ab406u : 0xac578137u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + ((((sel >> 14u) & 1u) != 0u) ? 0xaebb5966u : 0xa33e6706u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 8u); r7 = r7 ^ t_; } // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x5bb7550fu : 0xd94d55acu); // s184 add + r3 = r3 | r5; // s185 or + r6 = mul_hi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r7 = r7 ^ t_; } // s188 shfl + r6 = r6 + r5 + ((((sel >> 6u) & 1u) != 0u) ? 0x2a354e2du : 0x89e747feu); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = mul_hi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r4 = r4 ^ t_; } // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + ((((sel >> 7u) & 1u) != 0u) ? 0x10cfdc71u : 0xea03e8e7u); // s197 add + r7 = r7 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x66e148d3u : 0xa7ee0102u); // s198 add + r5 = r5 - r2; // s199 sub + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r5 = r5 ^ t_; } // s200 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 8u); r7 = r7 ^ t_; } // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0x8558b619u : 0x8379a4deu); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = mul_hi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 4u); r2 = r2 ^ t_; } // s209 shfl + r7 = r7 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0xf4049c4cu : 0xaa8cb14eu); // s210 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 16u); r7 = r7 ^ t_; } // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 16u); r3 = r3 ^ t_; } // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = mul_hi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r5 = r5 ^ t_; } // s222 shfl + r5 = mul_hi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0x2a7fecb2u : 0x1d176220u); // s230 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r1 = r1 ^ t_; } // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + ((((sel >> 25u) & 1u) != 0u) ? 0xadce39f3u : 0x17dafb4du); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + ((((sel >> 29u) & 1u) != 0u) ? 0x0e7033b6u : 0xf2f77d26u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + ((((sel >> 31u) & 1u) != 0u) ? 0x7b2ff6b7u : 0xfed2da4eu); // s247 add + r0 = r0 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0xb5fad7b1u : 0x03b2891cu); // s248 add + r5 = mul_hi(r5, r4); // s249 mulhi + r5 = r5 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0xa7e71c2fu : 0x042cd6e3u); // s250 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 1u); r6 = r6 ^ t_; } // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0xb83d78deu : 0x784a302bu); // s254 add + r2 = r2 - r4; // s255 sub + } + } + 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 = r3 * r4 + r2; // 0 mad + r2 = r1 * r1 + r2; // 1 mad + r2 = r3 * r2 + r2; // 2 mad + r3 = r3 ^ r5; // 3 xor + r7 = r7 ^ ds[r2 & mask]; // 4 load + r5 = r5 ^ ds[r7 & mask]; // 5 load + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r1 = r1 ^ t_; } // 6 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r7 = r7 ^ t_; } // 7 shfl + r1 = mul_hi(r1, r5); // 8 mulhi + r6 = rotr_var(r6, r3); // 9 rotr + r3 = r3 | r4; // 10 or + r4 = r4 ^ ds[r3 & mask]; // 11 load + r0 = mul_hi(r0, r4); // 12 mulhi + r5 = r5 + r1 + ((((sel >> 30u) & 1u) != 0u) ? 0xd3177981u : 0xc7934706u); // 13 add + r0 = r0 ^ ds[r4 & mask]; // 14 load + r2 = r2 - r4; // 15 sub + r2 = r2 ^ ds[r0 & mask]; // 16 load + r7 = r7 ^ ds[r2 & mask]; // 17 load + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r7 = r7 ^ t_; } // 18 shfl + r5 = r5 * r0; // 19 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // 20 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 16u); r2 = r2 ^ t_; } // 21 shfl + r6 = mul_hi(r6, r2); // 22 mulhi + r6 = r6 ^ ds[r1 & mask]; // 23 load + r5 = r5 * r0; // 24 mul + r5 = rotl_imm(r5, 19u); // 25 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 2u); r7 = r7 ^ t_; } // 26 shfl + r0 = r0 ^ r5; // 27 xor + r0 = r0 ^ r4; // 28 xor + r3 = r3 - r0; // 29 sub + r5 = r5 * r1; // 30 mul + r7 = r7 ^ ds[r2 & mask]; // 31 load + r1 = r1 ^ ds[r0 & mask]; // 32 load + r5 = r5 ^ r6; // 33 xor + r5 = r5 ^ ds[r1 & mask]; // 34 load + r0 = mul_hi(r0, r5); // 35 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r5 = r5 ^ t_; } // 36 shfl + r7 = r7 ^ ds[r0 & mask]; // 37 load + r3 = r3 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0x230c005cu : 0x75ba2fadu); // 38 add + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 4u); r1 = r1 ^ t_; } // 39 shfl + r2 = r2 ^ r5; // 40 xor + r3 = r6 * r3 + r3; // 41 mad + r6 = r6 - r7; // 42 sub + r7 = r7 ^ r0; // 43 xor + r1 = r1 ^ ds[r7 & mask]; // 44 load + r2 = r2 * r3; // 45 mul + r1 = mul_hi(r1, r5); // 46 mulhi + r4 = r4 - r3; // 47 sub + r2 = rotr_var(r2, r6); // 48 rotr + r3 = r3 ^ ds[r5 & mask]; // 49 load + r1 = r1 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x1907970cu : 0x81b8bc2cu); // 50 add + r0 = r0 * r2; // 51 mul + r0 = r0 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x699fd448u : 0x4f92b968u); // 52 add + r1 = r1 + r0 + ((((sel >> 12u) & 1u) != 0u) ? 0x77b1520du : 0x2bb965afu); // 53 add + r7 = rotl_imm(r7, 14u); // 54 rotl + r3 = r3 + r7 + ((((sel >> 1u) & 1u) != 0u) ? 0xa54c55a0u : 0x7b0fe07au); // 55 add + r6 = r6 ^ ds[r7 & mask]; // 56 load + r1 = rotr_var(r1, r5); // 57 rotr + r5 = r5 ^ ds[r4 & mask]; // 58 load + r6 = r6 ^ ds[r2 & mask]; // 59 load + r3 = r5 * r0 + r3; // 60 mad + r5 = r5 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0xad7493e7u : 0xaf9dd72du); // 61 add + r4 = r4 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x1e07c3d9u : 0x89841d87u); // 62 add + r5 = rotl_imm(r5, 19u); // 63 rotl + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 88 passes after instruction 63, no load + for (uint sh = 0u; sh < 88u; ++sh) { + r5 = r5 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x8bc12da9u : 0x92199f99u); // s0 add + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x63079e5au : 0x8d72d3adu); // s1 add + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 2u); r6 = r6 ^ t_; } // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + ((((sel >> 31u) & 1u) != 0u) ? 0x5d4c7a60u : 0xb21b4babu); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + ((((sel >> 16u) & 1u) != 0u) ? 0xc88e2942u : 0x2fe0e98bu); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r6 = r6 ^ t_; } // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 4u); r2 = r2 ^ t_; } // s12 shfl + r1 = r1 + r5 + ((((sel >> 25u) & 1u) != 0u) ? 0xbc48c63eu : 0xbdf8f9a5u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r2 = r2 ^ t_; } // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + ((((sel >> 1u) & 1u) != 0u) ? 0x96e8f127u : 0x45c37cecu); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = mul_hi(r6, r0); // s28 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r2 = r2 ^ t_; } // s29 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r1 = r1 ^ t_; } // s30 shfl + r1 = r1 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0xb1cdb2abu : 0x37985632u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // s33 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r0 = r0 ^ t_; } // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x856e0180u : 0x804e777eu); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xe9bd0cc4u : 0x0b06c8a7u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = mul_hi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = mul_hi(r4, r3); // s44 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xcdcb63f6u : 0xee822e17u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r4 = r4 ^ t_; } // s47 shfl + r6 = mul_hi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0xd4758987u : 0x3dfad1b6u); // s56 add + r4 = r4 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x0602d6beu : 0xfca75bc2u); // s57 add + r5 = mul_hi(r5, r6); // s58 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r2 = r2 ^ t_; } // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0x8596687au : 0xd71c02ffu); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 2u); r7 = r7 ^ t_; } // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0x08ac5733u : 0x3c6fe15du); // s72 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r3 = r3 ^ t_; } // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + ((((sel >> 1u) & 1u) != 0u) ? 0xc100b495u : 0x295d5faeu); // s77 add + r3 = mul_hi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + ((((sel >> 15u) & 1u) != 0u) ? 0x5cc59530u : 0x274a9221u); // s81 add + r7 = r7 + r3 + ((((sel >> 5u) & 1u) != 0u) ? 0x141479ecu : 0xc8651f8eu); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r2 = r2 ^ t_; } // s85 shfl + r3 = r3 ^ r2; // s86 xor + { uint t_; IGNEUM_SHFL_XOR(t_, r7, 2u); r5 = r5 ^ t_; } // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x883c0c92u : 0x53f915c2u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + ((((sel >> 31u) & 1u) != 0u) ? 0x3cc5bd20u : 0xe2be00a5u); // s91 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 1u); r7 = r7 ^ t_; } // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + ((((sel >> 17u) & 1u) != 0u) ? 0xbfd646cbu : 0x423fd9c9u); // s101 add + r7 = r7 + r6 + ((((sel >> 11u) & 1u) != 0u) ? 0x19b74a43u : 0x8d3c011du); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + ((((sel >> 15u) & 1u) != 0u) ? 0x7dcb7e18u : 0x8ce14721u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = mul_hi(r2, r0); // s109 mulhi + r1 = mul_hi(r1, r0); // s110 mulhi + r0 = r0 + r2 + ((((sel >> 28u) & 1u) != 0u) ? 0x3c179ad8u : 0x2d9fc6b9u); // s111 add + r2 = mul_hi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + ((((sel >> 22u) & 1u) != 0u) ? 0x47359729u : 0x502138e2u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = mul_hi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 2u); r4 = r4 ^ t_; } // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r7 = r7 ^ t_; } // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x6c57e4e7u : 0x33dff776u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + ((((sel >> 30u) & 1u) != 0u) ? 0xe8212c0cu : 0x5db25b34u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = mul_hi(r0, r5); // s138 mulhi + r2 = r2 + r7 + ((((sel >> 10u) & 1u) != 0u) ? 0xd44ff710u : 0x218d4090u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r3 = r3 ^ t_; } // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + ((((sel >> 29u) & 1u) != 0u) ? 0xb98942fau : 0xf4b1a8deu); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + ((((sel >> 17u) & 1u) != 0u) ? 0x0d48ba42u : 0x2bef10f2u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + ((((sel >> 30u) & 1u) != 0u) ? 0xc98dea9cu : 0xdc5cc080u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0x6c752dcbu : 0x18197438u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + ((((sel >> 3u) & 1u) != 0u) ? 0x8e481727u : 0xf1c46574u); // s163 add + r0 = mul_hi(r0, r4); // s164 mulhi + r2 = r2 + r6 + ((((sel >> 20u) & 1u) != 0u) ? 0x550ab406u : 0xac578137u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + ((((sel >> 14u) & 1u) != 0u) ? 0xaebb5966u : 0xa33e6706u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 8u); r7 = r7 ^ t_; } // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x5bb7550fu : 0xd94d55acu); // s184 add + r3 = r3 | r5; // s185 or + r6 = mul_hi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r7 = r7 ^ t_; } // s188 shfl + r6 = r6 + r5 + ((((sel >> 6u) & 1u) != 0u) ? 0x2a354e2du : 0x89e747feu); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = mul_hi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 16u); r4 = r4 ^ t_; } // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + ((((sel >> 7u) & 1u) != 0u) ? 0x10cfdc71u : 0xea03e8e7u); // s197 add + r7 = r7 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x66e148d3u : 0xa7ee0102u); // s198 add + r5 = r5 - r2; // s199 sub + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r5 = r5 ^ t_; } // s200 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 8u); r7 = r7 ^ t_; } // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0x8558b619u : 0x8379a4deu); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = mul_hi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r0, 4u); r2 = r2 ^ t_; } // s209 shfl + r7 = r7 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0xf4049c4cu : 0xaa8cb14eu); // s210 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 16u); r7 = r7 ^ t_; } // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 16u); r3 = r3 ^ t_; } // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = mul_hi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 8u); r5 = r5 ^ t_; } // s222 shfl + r5 = mul_hi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0x2a7fecb2u : 0x1d176220u); // s230 add + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r1 = r1 ^ t_; } // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + ((((sel >> 25u) & 1u) != 0u) ? 0xadce39f3u : 0x17dafb4du); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + ((((sel >> 29u) & 1u) != 0u) ? 0x0e7033b6u : 0xf2f77d26u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + ((((sel >> 31u) & 1u) != 0u) ? 0x7b2ff6b7u : 0xfed2da4eu); // s247 add + r0 = r0 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0xb5fad7b1u : 0x03b2891cu); // s248 add + r5 = mul_hi(r5, r4); // s249 mulhi + r5 = r5 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0xa7e71c2fu : 0x042cd6e3u); // s250 add + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 1u); r6 = r6 ^ t_; } // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0xb83d78deu : 0x784a302bu); // s254 add + r2 = r2 - r4; // s255 sub + } + } + uint lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((ulong)hi << 32) | (ulong)lo; +} diff --git a/proto-cuda/packs-ca3-shadow/sh256x88/kernel_bound.cu b/proto-cuda/packs-ca3-shadow/sh256x88/kernel_bound.cu new file mode 100644 index 000000000..00ae080ba --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x88/kernel_bound.cu @@ -0,0 +1,382 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Header-bound twin of igneum_hash in kernel.cu: the init words come from a kernel argument, not SEEDW. +// Host declarations (also in program_bound.h if present): +// struct IgneumInitWords { uint32_t w[8]; }; +// cudaError_t igneum_launch_hash_bound(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, +// IgneumInitWords iw, uint32_t nonces, uint32_t blockWarps); +// cudaError_t igneum_hash_bound_info(int* numRegs, int* blocksPerSM, uint32_t blockWarps); +#include +#include +#include "program.h" + +struct IgneumInitWords { uint32_t w[8]; }; + +__device__ __forceinline__ uint32_t splitmix32(uint32_t x) { + x ^= x >> 16; x *= 0x7feb352du; + x ^= x >> 15; x *= 0x846ca68bu; + x ^= x >> 16; + return x; +} +__device__ __forceinline__ uint32_t rotl_imm(uint32_t x, uint32_t n) { return (x << n) | (x >> (32u - n)); } +__device__ __forceinline__ uint32_t rotr_var(uint32_t x, uint32_t n) { n &= 31u; return (x >> n) | (x << ((32u - n) & 31u)); } + +__global__ void igneum_hash_bound(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, IgneumInitWords iw) { + uint32_t gid = blockIdx.x * blockDim.x + threadIdx.x; + uint32_t nonce = baseNonce + gid; + uint32_t r0, r1, r2, r3, r4, r5, r6, r7; + { uint32_t x = nonce ^ iw.w[0]; x += 0x9e3779b9u * 1u; x = splitmix32(x); r0 = x ^ iw.w[1]; } + { uint32_t x = nonce ^ iw.w[1]; x += 0x9e3779b9u * 2u; x = splitmix32(x); r1 = x ^ iw.w[2]; } + { uint32_t x = nonce ^ iw.w[2]; x += 0x9e3779b9u * 3u; x = splitmix32(x); r2 = x ^ iw.w[3]; } + { uint32_t x = nonce ^ iw.w[3]; x += 0x9e3779b9u * 4u; x = splitmix32(x); r3 = x ^ iw.w[4]; } + { uint32_t x = nonce ^ iw.w[4]; x += 0x9e3779b9u * 5u; x = splitmix32(x); r4 = x ^ iw.w[5]; } + { uint32_t x = nonce ^ iw.w[5]; x += 0x9e3779b9u * 6u; x = splitmix32(x); r5 = x ^ iw.w[6]; } + { uint32_t x = nonce ^ iw.w[6]; x += 0x9e3779b9u * 7u; x = splitmix32(x); r6 = x ^ iw.w[7]; } + { uint32_t x = nonce ^ iw.w[7]; x += 0x9e3779b9u * 8u; x = splitmix32(x); r7 = x ^ iw.w[0]; } + + for (uint32_t it = 0u; it < 8u; ++it) { + uint32_t sel = r0; + r2 = r3 * r4 + r2; // 0 mad + r2 = r1 * r1 + r2; // 1 mad + r2 = r3 * r2 + r2; // 2 mad + r3 = r3 ^ r5; // 3 xor + r7 = r7 ^ ds[r2 & mask]; // 4 load + r5 = r5 ^ ds[r7 & mask]; // 5 load + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r4, 8); // 6 shfl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r3, 8); // 7 shfl + r1 = __umulhi(r1, r5); // 8 mulhi + r6 = rotr_var(r6, r3); // 9 rotr + r3 = r3 | r4; // 10 or + r4 = r4 ^ ds[r3 & mask]; // 11 load + r0 = __umulhi(r0, r4); // 12 mulhi + r5 = r5 + r1 + ((((sel >> 30u) & 1u) != 0u) ? 0xd3177981u : 0xc7934706u); // 13 add + r0 = r0 ^ ds[r4 & mask]; // 14 load + r2 = r2 - r4; // 15 sub + r2 = r2 ^ ds[r0 & mask]; // 16 load + r7 = r7 ^ ds[r2 & mask]; // 17 load + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r3, 4); // 18 shfl + r5 = r5 * r0; // 19 mul + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // 20 shfl + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 16); // 21 shfl + r6 = __umulhi(r6, r2); // 22 mulhi + r6 = r6 ^ ds[r1 & mask]; // 23 load + r5 = r5 * r0; // 24 mul + r5 = rotl_imm(r5, 19u); // 25 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r6, 2); // 26 shfl + r0 = r0 ^ r5; // 27 xor + r0 = r0 ^ r4; // 28 xor + r3 = r3 - r0; // 29 sub + r5 = r5 * r1; // 30 mul + r7 = r7 ^ ds[r2 & mask]; // 31 load + r1 = r1 ^ ds[r0 & mask]; // 32 load + r5 = r5 ^ r6; // 33 xor + r5 = r5 ^ ds[r1 & mask]; // 34 load + r0 = __umulhi(r0, r5); // 35 mulhi + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // 36 shfl + r7 = r7 ^ ds[r0 & mask]; // 37 load + r3 = r3 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0x230c005cu : 0x75ba2fadu); // 38 add + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r5, 4); // 39 shfl + r2 = r2 ^ r5; // 40 xor + r3 = r6 * r3 + r3; // 41 mad + r6 = r6 - r7; // 42 sub + r7 = r7 ^ r0; // 43 xor + r1 = r1 ^ ds[r7 & mask]; // 44 load + r2 = r2 * r3; // 45 mul + r1 = __umulhi(r1, r5); // 46 mulhi + r4 = r4 - r3; // 47 sub + r2 = rotr_var(r2, r6); // 48 rotr + r3 = r3 ^ ds[r5 & mask]; // 49 load + r1 = r1 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x1907970cu : 0x81b8bc2cu); // 50 add + r0 = r0 * r2; // 51 mul + r0 = r0 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x699fd448u : 0x4f92b968u); // 52 add + r1 = r1 + r0 + ((((sel >> 12u) & 1u) != 0u) ? 0x77b1520du : 0x2bb965afu); // 53 add + r7 = rotl_imm(r7, 14u); // 54 rotl + r3 = r3 + r7 + ((((sel >> 1u) & 1u) != 0u) ? 0xa54c55a0u : 0x7b0fe07au); // 55 add + r6 = r6 ^ ds[r7 & mask]; // 56 load + r1 = rotr_var(r1, r5); // 57 rotr + r5 = r5 ^ ds[r4 & mask]; // 58 load + r6 = r6 ^ ds[r2 & mask]; // 59 load + r3 = r5 * r0 + r3; // 60 mad + r5 = r5 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0xad7493e7u : 0xaf9dd72du); // 61 add + r4 = r4 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x1e07c3d9u : 0x89841d87u); // 62 add + r5 = rotl_imm(r5, 19u); // 63 rotl + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 88 passes after instruction 63, no load + for (uint32_t sh = 0u; sh < 88u; ++sh) { + r5 = r5 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x8bc12da9u : 0x92199f99u); // s0 add + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x63079e5au : 0x8d72d3adu); // s1 add + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r3, 2); // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + ((((sel >> 31u) & 1u) != 0u) ? 0x5d4c7a60u : 0xb21b4babu); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + ((((sel >> 16u) & 1u) != 0u) ? 0xc88e2942u : 0x2fe0e98bu); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r1, 4); // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r6, 4); // s12 shfl + r1 = r1 + r5 + ((((sel >> 25u) & 1u) != 0u) ? 0xbc48c63eu : 0xbdf8f9a5u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 8); // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + ((((sel >> 1u) & 1u) != 0u) ? 0x96e8f127u : 0x45c37cecu); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = __umulhi(r6, r0); // s28 mulhi + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // s29 shfl + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r6, 1); // s30 shfl + r1 = r1 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0xb1cdb2abu : 0x37985632u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // s33 shfl + r0 = r0 ^ __shfl_xor_sync(0xffffffffu, r3, 4); // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x856e0180u : 0x804e777eu); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xe9bd0cc4u : 0x0b06c8a7u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = __umulhi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = __umulhi(r4, r3); // s44 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xcdcb63f6u : 0xee822e17u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r3, 8); // s47 shfl + r6 = __umulhi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0xd4758987u : 0x3dfad1b6u); // s56 add + r4 = r4 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x0602d6beu : 0xfca75bc2u); // s57 add + r5 = __umulhi(r5, r6); // s58 mulhi + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + ((((sel >> 6u) & 1u) != 0u) ? 0x8596687au : 0xd71c02ffu); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r5, 2); // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0x08ac5733u : 0x3c6fe15du); // s72 add + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r2, 8); // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + ((((sel >> 1u) & 1u) != 0u) ? 0xc100b495u : 0x295d5faeu); // s77 add + r3 = __umulhi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + ((((sel >> 15u) & 1u) != 0u) ? 0x5cc59530u : 0x274a9221u); // s81 add + r7 = r7 + r3 + ((((sel >> 5u) & 1u) != 0u) ? 0x141479ecu : 0xc8651f8eu); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r5, 16); // s85 shfl + r3 = r3 ^ r2; // s86 xor + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r7, 2); // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x883c0c92u : 0x53f915c2u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + ((((sel >> 31u) & 1u) != 0u) ? 0x3cc5bd20u : 0xe2be00a5u); // s91 add + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r2, 1); // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + ((((sel >> 17u) & 1u) != 0u) ? 0xbfd646cbu : 0x423fd9c9u); // s101 add + r7 = r7 + r6 + ((((sel >> 11u) & 1u) != 0u) ? 0x19b74a43u : 0x8d3c011du); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + ((((sel >> 15u) & 1u) != 0u) ? 0x7dcb7e18u : 0x8ce14721u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = __umulhi(r2, r0); // s109 mulhi + r1 = __umulhi(r1, r0); // s110 mulhi + r0 = r0 + r2 + ((((sel >> 28u) & 1u) != 0u) ? 0x3c179ad8u : 0x2d9fc6b9u); // s111 add + r2 = __umulhi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + ((((sel >> 22u) & 1u) != 0u) ? 0x47359729u : 0x502138e2u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = __umulhi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r2, 2); // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x6c57e4e7u : 0x33dff776u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + ((((sel >> 30u) & 1u) != 0u) ? 0xe8212c0cu : 0x5db25b34u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = __umulhi(r0, r5); // s138 mulhi + r2 = r2 + r7 + ((((sel >> 10u) & 1u) != 0u) ? 0xd44ff710u : 0x218d4090u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r6, 1); // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + ((((sel >> 29u) & 1u) != 0u) ? 0xb98942fau : 0xf4b1a8deu); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + ((((sel >> 17u) & 1u) != 0u) ? 0x0d48ba42u : 0x2bef10f2u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + ((((sel >> 30u) & 1u) != 0u) ? 0xc98dea9cu : 0xdc5cc080u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0x6c752dcbu : 0x18197438u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + ((((sel >> 3u) & 1u) != 0u) ? 0x8e481727u : 0xf1c46574u); // s163 add + r0 = __umulhi(r0, r4); // s164 mulhi + r2 = r2 + r6 + ((((sel >> 20u) & 1u) != 0u) ? 0x550ab406u : 0xac578137u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + ((((sel >> 14u) & 1u) != 0u) ? 0xaebb5966u : 0xa33e6706u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r0, 8); // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + ((((sel >> 21u) & 1u) != 0u) ? 0x5bb7550fu : 0xd94d55acu); // s184 add + r3 = r3 | r5; // s185 or + r6 = __umulhi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s188 shfl + r6 = r6 + r5 + ((((sel >> 6u) & 1u) != 0u) ? 0x2a354e2du : 0x89e747feu); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = __umulhi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r5, 16); // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + ((((sel >> 7u) & 1u) != 0u) ? 0x10cfdc71u : 0xea03e8e7u); // s197 add + r7 = r7 + r5 + ((((sel >> 15u) & 1u) != 0u) ? 0x66e148d3u : 0xa7ee0102u); // s198 add + r5 = r5 - r2; // s199 sub + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s200 shfl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 8); // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0x8558b619u : 0x8379a4deu); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = __umulhi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r0, 4); // s209 shfl + r7 = r7 + r0 + ((((sel >> 11u) & 1u) != 0u) ? 0xf4049c4cu : 0xaa8cb14eu); // s210 add + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r1, 16); // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r2, 16); // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = __umulhi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r2, 8); // s222 shfl + r5 = __umulhi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0x2a7fecb2u : 0x1d176220u); // s230 add + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + ((((sel >> 25u) & 1u) != 0u) ? 0xadce39f3u : 0x17dafb4du); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + ((((sel >> 29u) & 1u) != 0u) ? 0x0e7033b6u : 0xf2f77d26u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + ((((sel >> 31u) & 1u) != 0u) ? 0x7b2ff6b7u : 0xfed2da4eu); // s247 add + r0 = r0 + r7 + ((((sel >> 0u) & 1u) != 0u) ? 0xb5fad7b1u : 0x03b2891cu); // s248 add + r5 = __umulhi(r5, r4); // s249 mulhi + r5 = r5 + r2 + ((((sel >> 11u) & 1u) != 0u) ? 0xa7e71c2fu : 0x042cd6e3u); // s250 add + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r1, 1); // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + ((((sel >> 16u) & 1u) != 0u) ? 0xb83d78deu : 0x784a302bu); // s254 add + r2 = r2 - r4; // s255 sub + } + } + uint32_t lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint32_t hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((uint64_t)hi << 32) | (uint64_t)lo; +} + +cudaError_t igneum_launch_hash_bound(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, + IgneumInitWords iw, uint32_t nonces, uint32_t blockWarps) { + if (blockWarps == 0u || blockWarps > 32u) return cudaErrorInvalidValue; + uint32_t block = 32u * blockWarps; + if (nonces == 0u || (nonces % block) != 0u) return cudaErrorInvalidValue; + igneum_hash_bound<<>>(ds, out, baseNonce, mask, iw); + return cudaGetLastError(); +} + +cudaError_t igneum_hash_bound_info(int* numRegs, int* blocksPerSM, uint32_t blockWarps) { + cudaFuncAttributes attr; + cudaError_t e = cudaFuncGetAttributes(&attr, igneum_hash_bound); + if (e != cudaSuccess) return e; + *numRegs = attr.numRegs; + return cudaOccupancyMaxActiveBlocksPerMultiprocessor(blocksPerSM, igneum_hash_bound, (int)(32u * blockWarps), 0); +} diff --git a/proto-cuda/packs-ca3-shadow/sh256x88/memhard.h b/proto-cuda/packs-ca3-shadow/sh256x88/memhard.h new file mode 100644 index 000000000..f7f34c732 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x88/memhard.h @@ -0,0 +1,109 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Memory-hard dataset core, the same text that the Mac's Metal kernels and CPU verifier were checked against. +// Included by kernel.cu (device), host.cu (host reference) and proto-opencl/host.c (C99 host reference). +// See proto-metal/MEMHARD.md for the construction. kernel.cl carries the same text in OpenCL C. +#pragma once +#ifdef __cplusplus +#include +#else +#include +#endif +#if defined(__CUDACC__) +#define IGNEUM_HD __host__ __device__ __forceinline__ +#elif defined(_MSC_VER) && !defined(__cplusplus) +#define IGNEUM_HD static __inline +#else +#define IGNEUM_HD static inline +#endif +// Memory-hard dataset core (MEMHARD.md). Cache: 2^26 words in 2^16 segments of 64 chained ChaCha12 lines. +// Item: 8 rounds of 8 x seed-parameterised mixer + one 64-byte cache read, then 8 x final mixer (class v3, mixer multiplier 8, +// docs/plans/mixer-x4.md: the round key of application j of round r is 0x9E3779B9 * (r * m + j + 1)). All parameters are literals. +#define MH_CACHE_LINE_MASK 0x003fffffu +#define MH_SEGMENT_LINES 64u +#define MH_QR(a, b, c, d, r1, r2, r3, r4) { a += b; d ^= a; d = mh_rotl(d, r1); c += d; b ^= c; b = mh_rotl(b, r2); a += b; d ^= a; d = mh_rotl(d, r3); c += d; b ^= c; b = mh_rotl(b, r4); } +IGNEUM_HD uint32_t mh_rotl(uint32_t x, uint32_t n) { return (x << n) | (x >> (32u - n)); } // n in 1..31 at every call site + +// y = ChaCha12 core(x) + x +IGNEUM_HD void mh_chacha_block(const uint32_t* x, uint32_t* y) { + for (uint32_t i = 0u; i < 16u; ++i) y[i] = x[i]; + for (uint32_t r = 0u; r < 6u; ++r) { + MH_QR(y[0], y[4], y[8], y[12], 16u, 12u, 8u, 7u) MH_QR(y[1], y[5], y[9], y[13], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[6], y[10], y[14], 16u, 12u, 8u, 7u) MH_QR(y[3], y[7], y[11], y[15], 16u, 12u, 8u, 7u) + MH_QR(y[0], y[5], y[10], y[15], 16u, 12u, 8u, 7u) MH_QR(y[1], y[6], y[11], y[12], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[7], y[8], y[13], 16u, 12u, 8u, 7u) MH_QR(y[3], y[4], y[9], y[14], 16u, 12u, 8u, 7u) + } + for (uint32_t i = 0u; i < 16u; ++i) y[i] += x[i]; +} + +// One cache segment: 64 chained lines written at cache[seg * 1024]. in_j = prev ^ (sigma || K || seg || j || tag), prev_0 = 0. +IGNEUM_HD void mh_cache_segment(uint32_t* cache, uint32_t seg) { + uint32_t prev[16]; uint32_t x[16]; uint32_t y[16]; + for (uint32_t i = 0u; i < 16u; ++i) prev[i] = 0u; + for (uint32_t j = 0u; j < MH_SEGMENT_LINES; ++j) { + x[0] = 0x61707865u ^ prev[0]; x[1] = 0x3320646eu ^ prev[1]; x[2] = 0x79622d32u ^ prev[2]; x[3] = 0x6b206574u ^ prev[3]; + x[4] = 0x3067619fu ^ prev[4]; + x[5] = 0x3c269176u ^ prev[5]; + x[6] = 0x84a03b03u ^ prev[6]; + x[7] = 0xf8c63294u ^ prev[7]; + x[8] = 0xff977c5bu ^ prev[8]; + x[9] = 0xe60def3eu ^ prev[9]; + x[10] = 0x63630141u ^ prev[10]; + x[11] = 0xb8fbcb58u ^ prev[11]; + x[12] = seg ^ prev[12]; x[13] = j ^ prev[13]; x[14] = 0x49676e65u ^ prev[14]; x[15] = 0x756d4d48u ^ prev[15]; + mh_chacha_block(x, y); + uint32_t* line = cache + ((seg * MH_SEGMENT_LINES + j) * 16u); + for (uint32_t i = 0u; i < 16u; ++i) { line[i] = y[i]; prev[i] = y[i]; } + } +} + +// M_r: per word (s ^ (RC + rk)) * MUL, then a column round and a diagonal round with the seed-drawn rotations. +IGNEUM_HD void mh_mixer(uint32_t* s, uint32_t rk) { + s[0] = (s[0] ^ (0xbab68293u + rk)) * 0x42146205u; + s[1] = (s[1] ^ (0xcc162340u + rk)) * 0x52cbe0fbu; + s[2] = (s[2] ^ (0x6ce151ccu + rk)) * 0x7ecf4a03u; + s[3] = (s[3] ^ (0xe62b8997u + rk)) * 0x6728907fu; + s[4] = (s[4] ^ (0xc9c80297u + rk)) * 0xd81d9751u; + s[5] = (s[5] ^ (0xf74a1654u + rk)) * 0x132952c3u; + s[6] = (s[6] ^ (0x3d704af5u + rk)) * 0xf60de277u; + s[7] = (s[7] ^ (0x3cf522b7u + rk)) * 0x05358035u; + s[8] = (s[8] ^ (0x2b9cac04u + rk)) * 0xbaf6499du; + s[9] = (s[9] ^ (0xa880ac10u + rk)) * 0xe4db9667u; + s[10] = (s[10] ^ (0x13e5dd1du + rk)) * 0x3e98f45du; + s[11] = (s[11] ^ (0x6fc3e233u + rk)) * 0xd0004eddu; + s[12] = (s[12] ^ (0x2d83eeacu + rk)) * 0x2691630du; + s[13] = (s[13] ^ (0x9006e8bfu + rk)) * 0x9beb3bcfu; + s[14] = (s[14] ^ (0x2c4b5362u + rk)) * 0xab310379u; + s[15] = (s[15] ^ (0x31b49ee2u + rk)) * 0x99cfb423u; + MH_QR(s[0], s[4], s[8], s[12], 20u, 20u, 19u, 4u) MH_QR(s[1], s[5], s[9], s[13], 20u, 20u, 19u, 4u) + MH_QR(s[2], s[6], s[10], s[14], 20u, 20u, 19u, 4u) MH_QR(s[3], s[7], s[11], s[15], 20u, 20u, 19u, 4u) + MH_QR(s[0], s[5], s[10], s[15], 26u, 3u, 3u, 27u) MH_QR(s[1], s[6], s[11], s[12], 26u, 3u, 3u, 27u) + MH_QR(s[2], s[7], s[8], s[13], 26u, 3u, 3u, 27u) MH_QR(s[3], s[4], s[9], s[14], 26u, 3u, 3u, 27u) +} + +// Item t: 16 words. s = (K, t * MUL[i] + RC[i]); 8 rounds of 8 x mixer + cache line s[0] & mask; 8 x final mixer. +IGNEUM_HD void mh_item(const uint32_t* cache, uint32_t t, uint32_t* s) { + s[0] = 0x3067619fu; + s[1] = 0x3c269176u; + s[2] = 0x84a03b03u; + s[3] = 0xf8c63294u; + s[4] = 0xff977c5bu; + s[5] = 0xe60def3eu; + s[6] = 0x63630141u; + s[7] = 0xb8fbcb58u; + s[8] = t * 0x42146205u + 0xbab68293u; + s[9] = t * 0x52cbe0fbu + 0xcc162340u; + s[10] = t * 0x7ecf4a03u + 0x6ce151ccu; + s[11] = t * 0x6728907fu + 0xe62b8997u; + s[12] = t * 0xd81d9751u + 0xc9c80297u; + s[13] = t * 0x132952c3u + 0xf74a1654u; + s[14] = t * 0xf60de277u + 0x3d704af5u; + s[15] = t * 0x05358035u + 0x3cf522b7u; + for (uint32_t r = 0u; r < 8u; ++r) { + for (uint32_t j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (r * 8u + j + 1u)); + const uint32_t* line = cache + ((s[0] & MH_CACHE_LINE_MASK) * 16u); + for (uint32_t i = 0u; i < 16u; ++i) s[i] ^= line[i]; + } + for (uint32_t j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (64u + j + 1u)); +} +// dataset[w] without the dataset: derive item w >> 4 and take word w & 15. +IGNEUM_HD uint32_t mh_word(const uint32_t* cache, uint32_t w) { uint32_t s[16]; mh_item(cache, w >> 4u, s); return s[w & 15u]; } diff --git a/proto-cuda/packs-ca3-shadow/sh256x88/memhard.metal b/proto-cuda/packs-ca3-shadow/sh256x88/memhard.metal new file mode 100644 index 000000000..01b263d6d --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x88/memhard.metal @@ -0,0 +1,107 @@ +#include +using namespace metal; +// Memory-hard dataset core (MEMHARD.md). Cache: 2^26 words in 2^16 segments of 64 chained ChaCha12 lines. +// Item: 8 rounds of 8 x seed-parameterised mixer + one 64-byte cache read, then 8 x final mixer (class v3, mixer multiplier 8, +// docs/plans/mixer-x4.md: the round key of application j of round r is 0x9E3779B9 * (r * m + j + 1)). All parameters are literals. +#define MH_CACHE_LINE_MASK 0x003fffffu +#define MH_SEGMENT_LINES 64u +#define MH_QR(a, b, c, d, r1, r2, r3, r4) { a += b; d ^= a; d = mh_rotl(d, r1); c += d; b ^= c; b = mh_rotl(b, r2); a += b; d ^= a; d = mh_rotl(d, r3); c += d; b ^= c; b = mh_rotl(b, r4); } +inline uint mh_rotl(uint x, uint n) { return (x << n) | (x >> (32u - n)); } // n in 1..31 at every call site + +// y = ChaCha12 core(x) + x +inline void mh_chacha_block(const thread uint* x, thread uint* y) { + for (uint i = 0u; i < 16u; ++i) y[i] = x[i]; + for (uint r = 0u; r < 6u; ++r) { + MH_QR(y[0], y[4], y[8], y[12], 16u, 12u, 8u, 7u) MH_QR(y[1], y[5], y[9], y[13], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[6], y[10], y[14], 16u, 12u, 8u, 7u) MH_QR(y[3], y[7], y[11], y[15], 16u, 12u, 8u, 7u) + MH_QR(y[0], y[5], y[10], y[15], 16u, 12u, 8u, 7u) MH_QR(y[1], y[6], y[11], y[12], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[7], y[8], y[13], 16u, 12u, 8u, 7u) MH_QR(y[3], y[4], y[9], y[14], 16u, 12u, 8u, 7u) + } + for (uint i = 0u; i < 16u; ++i) y[i] += x[i]; +} + +// One cache segment: 64 chained lines written at cache[seg * 1024]. in_j = prev ^ (sigma || K || seg || j || tag), prev_0 = 0. +inline void mh_cache_segment(device uint* cache, uint seg) { + uint prev[16]; uint x[16]; uint y[16]; + for (uint i = 0u; i < 16u; ++i) prev[i] = 0u; + for (uint j = 0u; j < MH_SEGMENT_LINES; ++j) { + x[0] = 0x61707865u ^ prev[0]; x[1] = 0x3320646eu ^ prev[1]; x[2] = 0x79622d32u ^ prev[2]; x[3] = 0x6b206574u ^ prev[3]; + x[4] = 0x3067619fu ^ prev[4]; + x[5] = 0x3c269176u ^ prev[5]; + x[6] = 0x84a03b03u ^ prev[6]; + x[7] = 0xf8c63294u ^ prev[7]; + x[8] = 0xff977c5bu ^ prev[8]; + x[9] = 0xe60def3eu ^ prev[9]; + x[10] = 0x63630141u ^ prev[10]; + x[11] = 0xb8fbcb58u ^ prev[11]; + x[12] = seg ^ prev[12]; x[13] = j ^ prev[13]; x[14] = 0x49676e65u ^ prev[14]; x[15] = 0x756d4d48u ^ prev[15]; + mh_chacha_block(x, y); + device uint* line = cache + ((seg * MH_SEGMENT_LINES + j) * 16u); + for (uint i = 0u; i < 16u; ++i) { line[i] = y[i]; prev[i] = y[i]; } + } +} + +// M_r: per word (s ^ (RC + rk)) * MUL, then a column round and a diagonal round with the seed-drawn rotations. +inline void mh_mixer(thread uint* s, uint rk) { + s[0] = (s[0] ^ (0xbab68293u + rk)) * 0x42146205u; + s[1] = (s[1] ^ (0xcc162340u + rk)) * 0x52cbe0fbu; + s[2] = (s[2] ^ (0x6ce151ccu + rk)) * 0x7ecf4a03u; + s[3] = (s[3] ^ (0xe62b8997u + rk)) * 0x6728907fu; + s[4] = (s[4] ^ (0xc9c80297u + rk)) * 0xd81d9751u; + s[5] = (s[5] ^ (0xf74a1654u + rk)) * 0x132952c3u; + s[6] = (s[6] ^ (0x3d704af5u + rk)) * 0xf60de277u; + s[7] = (s[7] ^ (0x3cf522b7u + rk)) * 0x05358035u; + s[8] = (s[8] ^ (0x2b9cac04u + rk)) * 0xbaf6499du; + s[9] = (s[9] ^ (0xa880ac10u + rk)) * 0xe4db9667u; + s[10] = (s[10] ^ (0x13e5dd1du + rk)) * 0x3e98f45du; + s[11] = (s[11] ^ (0x6fc3e233u + rk)) * 0xd0004eddu; + s[12] = (s[12] ^ (0x2d83eeacu + rk)) * 0x2691630du; + s[13] = (s[13] ^ (0x9006e8bfu + rk)) * 0x9beb3bcfu; + s[14] = (s[14] ^ (0x2c4b5362u + rk)) * 0xab310379u; + s[15] = (s[15] ^ (0x31b49ee2u + rk)) * 0x99cfb423u; + MH_QR(s[0], s[4], s[8], s[12], 20u, 20u, 19u, 4u) MH_QR(s[1], s[5], s[9], s[13], 20u, 20u, 19u, 4u) + MH_QR(s[2], s[6], s[10], s[14], 20u, 20u, 19u, 4u) MH_QR(s[3], s[7], s[11], s[15], 20u, 20u, 19u, 4u) + MH_QR(s[0], s[5], s[10], s[15], 26u, 3u, 3u, 27u) MH_QR(s[1], s[6], s[11], s[12], 26u, 3u, 3u, 27u) + MH_QR(s[2], s[7], s[8], s[13], 26u, 3u, 3u, 27u) MH_QR(s[3], s[4], s[9], s[14], 26u, 3u, 3u, 27u) +} + +// Item t: 16 words. s = (K, t * MUL[i] + RC[i]); 8 rounds of 8 x mixer + cache line s[0] & mask; 8 x final mixer. +inline void mh_item(device const uint* cache, uint t, thread uint* s) { + s[0] = 0x3067619fu; + s[1] = 0x3c269176u; + s[2] = 0x84a03b03u; + s[3] = 0xf8c63294u; + s[4] = 0xff977c5bu; + s[5] = 0xe60def3eu; + s[6] = 0x63630141u; + s[7] = 0xb8fbcb58u; + s[8] = t * 0x42146205u + 0xbab68293u; + s[9] = t * 0x52cbe0fbu + 0xcc162340u; + s[10] = t * 0x7ecf4a03u + 0x6ce151ccu; + s[11] = t * 0x6728907fu + 0xe62b8997u; + s[12] = t * 0xd81d9751u + 0xc9c80297u; + s[13] = t * 0x132952c3u + 0xf74a1654u; + s[14] = t * 0xf60de277u + 0x3d704af5u; + s[15] = t * 0x05358035u + 0x3cf522b7u; + for (uint r = 0u; r < 8u; ++r) { + for (uint j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (r * 8u + j + 1u)); + device const uint* line = cache + ((s[0] & MH_CACHE_LINE_MASK) * 16u); + for (uint i = 0u; i < 16u; ++i) s[i] ^= line[i]; + } + for (uint j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (64u + j + 1u)); +} +// dataset[w] without the dataset: derive item w >> 4 and take word w & 15. +inline uint mh_word(device const uint* cache, uint w) { uint s[16]; mh_item(cache, w >> 4u, s); return s[w & 15u]; } + +// One thread per segment (2^16 threads). +kernel void igneum_cache_fill(device uint* cache [[buffer(0)]], uint gid [[thread_position_in_grid]]) { + mh_cache_segment(cache, gid); +} +// One thread per 64-byte item (dataset words / 16 threads). +kernel void igneum_build(device const uint* cache [[buffer(0)]], device uint* dataset [[buffer(1)]], + uint gid [[thread_position_in_grid]]) { + uint s[16]; + mh_item(cache, gid, s); + device uint* d = dataset + gid * 16u; + for (uint i = 0u; i < 16u; ++i) d[i] = s[i]; +} diff --git a/proto-cuda/packs-ca3-shadow/sh256x88/program.h b/proto-cuda/packs-ca3-shadow/sh256x88/program.h new file mode 100644 index 000000000..7498b2469 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x88/program.h @@ -0,0 +1,70 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Program metadata for host.cu plus the launch wrappers defined in kernel.cu. +// Also included by proto-opencl/host.c (C99), which defines IGNEUM_NO_CUDA first and reads only the macros. +#pragma once +#ifdef __cplusplus +#include +#else +#include +#endif +#ifndef IGNEUM_NO_CUDA +#include +#endif + +#define IGNEUM_SEED_STRING "igneum-genesis" +#define IGNEUM_SEED_BYTES_HEX "69676e65756d2d67656e65736973" +#define IGNEUM_GENERATOR 2 +#define IGNEUM_PROGRAM_ATTEMPT 0 +#define IGNEUM_PROGRAM_ID 0x9b6191853bdf72c1ull +#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 add=8 shfl=8 xor=6 mad=5 mul=5 mulhi=5 sub=4 rotl=3 rotr=3 or=1" +// 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+sh256x88" +#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 88 +#define IGNEUM_SHADOW_INSTRS_PER_HASH 180224 +#define IGNEUM_SHADOW_OP_MIX "add=47 rotl=30 xor=30 shfl=29 mad=27 mul=22 sub=21 rotr=20 mulhi=18 or=12" +// 0 = closed-form dataset (ds_elem), 1 = memory-hard cache construction (MEMHARD.md, memhard.h) +#define IGNEUM_DATASET_MODE 1 + +#define IGNEUM_SEEDW_INIT { 0x67a9a7beu, 0x1a155b25u, 0xfddfb732u, 0x4b5af2e8u, 0xc55caf33u, 0xa27c13b7u, 0x06628a48u, 0x03852469u } +#define IGNEUM_KEY_INIT { 0x3067619fu, 0x3c269176u, 0x84a03b03u, 0xf8c63294u, 0xff977c5bu, 0xe60def3eu, 0x63630141u, 0xb8fbcb58u } +#define IGNEUM_CACHE_LOG2_WORDS 26 +#define IGNEUM_CACHE_SEGMENT_LOG2_LINES 6 +#define IGNEUM_CACHE_SEGMENTS 65536u +#define IGNEUM_ITEM_ROUNDS 8 +#define IGNEUM_MIXER_MULT 8 // mixer applications per round and after the last read (class v3, docs/plans/mixer-x4.md) +#define IGNEUM_MIX_ROT_INIT { 20u, 20u, 19u, 4u, 26u, 3u, 3u, 27u } +#define IGNEUM_MIX_MUL_INIT { 0x42146205u, 0x52cbe0fbu, 0x7ecf4a03u, 0x6728907fu, 0xd81d9751u, 0x132952c3u, 0xf60de277u, 0x05358035u, 0xbaf6499du, 0xe4db9667u, 0x3e98f45du, 0xd0004eddu, 0x2691630du, 0x9beb3bcfu, 0xab310379u, 0x99cfb423u } +#define IGNEUM_MIX_RC_INIT { 0xbab68293u, 0xcc162340u, 0x6ce151ccu, 0xe62b8997u, 0xc9c80297u, 0xf74a1654u, 0x3d704af5u, 0x3cf522b7u, 0x2b9cac04u, 0xa880ac10u, 0x13e5dd1du, 0x6fc3e233u, 0x2d83eeacu, 0x9006e8bfu, 0x2c4b5362u, 0x31b49ee2u } + +#ifndef IGNEUM_NO_CUDA +// Defined in kernel.cu. All launch on the default stream and return cudaGetLastError(). +cudaError_t igneum_launch_cache_fill(uint32_t* cache, uint32_t nSegments); +cudaError_t igneum_launch_build(uint32_t* ds, const uint32_t* cache, uint32_t nItems); +cudaError_t igneum_launch_hash(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, + uint32_t nonces, uint32_t blockWarps); +cudaError_t igneum_hash_info(int* numRegs, int* blocksPerSM, uint32_t blockWarps); +#endif diff --git a/proto-cuda/packs-ca3-shadow/sh256x88/program.json b/proto-cuda/packs-ca3-shadow/sh256x88/program.json new file mode 100644 index 000000000..a3659596c --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x88/program.json @@ -0,0 +1,389 @@ +{ + "format": "igneum-program-pack-3", + "generator": 2, + "attempt": 0, + "program_id": "0x9b6191853bdf72c1", + "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": ["0x67a9a7be", "0x1a155b25", "0xfddfb732", "0x4b5af2e8", "0xc55caf33", "0xa27c13b7", "0x06628a48", "0x03852469"], + "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+sh256x88", + "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, "add": 8, "shfl": 8, "xor": 6, "mad": 5, "mul": 5, "mulhi": 5, "sub": 4, "rotl": 3, "rotr": 3, "or": 1}, + "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": 88, "instrs_per_hash": 180224, "op_mix": {"add": 47, "rotl": 30, "xor": 30, "shfl": 29, "mad": 27, "mul": 22, "sub": 21, "rotr": 20, "mulhi": 18, "or": 12}, "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": "add", "dst": 5, "src": 2, "src2": 1, "imm": "0x92199f99", "imm2": "0x8bc12da9", "rot": 9, "bit": 18, "mask": 4}, + {"i": 1, "op": "add", "dst": 0, "src": 7, "src2": 1, "imm": "0x8d72d3ad", "imm2": "0x63079e5a", "rot": 20, "bit": 26, "mask": 4}, + {"i": 2, "op": "shfl", "dst": 6, "src": 3, "src2": 6, "imm": "0x9beaeddf", "imm2": "0x744ecb00", "rot": 10, "bit": 4, "mask": 2}, + {"i": 3, "op": "sub", "dst": 4, "src": 2, "src2": 0, "imm": "0x2a3ddc67", "imm2": "0x72c80241", "rot": 30, "bit": 1, "mask": 16}, + {"i": 4, "op": "add", "dst": 7, "src": 0, "src2": 5, "imm": "0xb21b4bab", "imm2": "0x5d4c7a60", "rot": 17, "bit": 31, "mask": 4}, + {"i": 5, "op": "rotl", "dst": 0, "src": 6, "src2": 3, "imm": "0xe69d7919", "imm2": "0xa048c61e", "rot": 11, "bit": 1, "mask": 8}, + {"i": 6, "op": "add", "dst": 0, "src": 1, "src2": 3, "imm": "0x2fe0e98b", "imm2": "0xc88e2942", "rot": 5, "bit": 16, "mask": 16}, + {"i": 7, "op": "xor", "dst": 7, "src": 1, "src2": 0, "imm": "0xc16efe98", "imm2": "0x01a638c8", "rot": 8, "bit": 17, "mask": 1}, + {"i": 8, "op": "mad", "dst": 1, "src": 6, "src2": 5, "imm": "0x76ec7b8b", "imm2": "0x25663feb", "rot": 29, "bit": 30, "mask": 2}, + {"i": 9, "op": "shfl", "dst": 6, "src": 1, "src2": 0, "imm": "0x6c8ee3cb", "imm2": "0xea93237e", "rot": 27, "bit": 1, "mask": 4}, + {"i": 10, "op": "mad", "dst": 1, "src": 2, "src2": 2, "imm": "0x6dc4ea18", "imm2": "0x6efde6f5", "rot": 3, "bit": 20, "mask": 2}, + {"i": 11, "op": "mad", "dst": 5, "src": 0, "src2": 3, "imm": "0x023613fc", "imm2": "0x18c51939", "rot": 19, "bit": 31, "mask": 1}, + {"i": 12, "op": "shfl", "dst": 2, "src": 6, "src2": 1, "imm": "0x74aec8d2", "imm2": "0x7f7ad29c", "rot": 7, "bit": 8, "mask": 4}, + {"i": 13, "op": "add", "dst": 1, "src": 5, "src2": 6, "imm": "0xbdf8f9a5", "imm2": "0xbc48c63e", "rot": 6, "bit": 25, "mask": 2}, + {"i": 14, "op": "rotl", "dst": 1, "src": 2, "src2": 6, "imm": "0x7ad8ca8b", "imm2": "0x14c712ad", "rot": 29, "bit": 25, "mask": 8}, + {"i": 15, "op": "sub", "dst": 1, "src": 4, "src2": 5, "imm": "0xd3349f69", "imm2": "0x70aac45a", "rot": 29, "bit": 9, "mask": 16}, + {"i": 16, "op": "or", "dst": 7, "src": 1, "src2": 2, "imm": "0x08168ed1", "imm2": "0x28964037", "rot": 26, "bit": 0, "mask": 2}, + {"i": 17, "op": "shfl", "dst": 2, "src": 4, "src2": 6, "imm": "0x98d85f72", "imm2": "0x3dc87042", "rot": 29, "bit": 22, "mask": 8}, + {"i": 18, "op": "xor", "dst": 7, "src": 4, "src2": 0, "imm": "0x651d4a0e", "imm2": "0x93c198bd", "rot": 26, "bit": 12, "mask": 8}, + {"i": 19, "op": "mul", "dst": 6, "src": 1, "src2": 6, "imm": "0xd38ce89d", "imm2": "0x3dfad388", "rot": 5, "bit": 28, "mask": 8}, + {"i": 20, "op": "mad", "dst": 5, "src": 6, "src2": 0, "imm": "0x59d78b36", "imm2": "0xc4db274e", "rot": 25, "bit": 24, "mask": 1}, + {"i": 21, "op": "sub", "dst": 3, "src": 1, "src2": 7, "imm": "0xf6c6a6c7", "imm2": "0x8536f4e6", "rot": 6, "bit": 12, "mask": 4}, + {"i": 22, "op": "mul", "dst": 6, "src": 0, "src2": 7, "imm": "0x599445b4", "imm2": "0x632f8c32", "rot": 19, "bit": 4, "mask": 8}, + {"i": 23, "op": "add", "dst": 2, "src": 0, "src2": 7, "imm": "0x45c37cec", "imm2": "0x96e8f127", "rot": 15, "bit": 1, "mask": 4}, + {"i": 24, "op": "sub", "dst": 6, "src": 4, "src2": 3, "imm": "0xc1c44491", "imm2": "0x92e3ce57", "rot": 20, "bit": 25, "mask": 4}, + {"i": 25, "op": "mad", "dst": 7, "src": 3, "src2": 4, "imm": "0x89bfb8d3", "imm2": "0x19b5455e", "rot": 22, "bit": 2, "mask": 16}, + {"i": 26, "op": "rotl", "dst": 3, "src": 5, "src2": 7, "imm": "0x2f47ce8d", "imm2": "0x8b458ec5", "rot": 9, "bit": 0, "mask": 4}, + {"i": 27, "op": "sub", "dst": 2, "src": 1, "src2": 2, "imm": "0x9f0dce23", "imm2": "0x3cdca814", "rot": 25, "bit": 1, "mask": 2}, + {"i": 28, "op": "mulhi", "dst": 6, "src": 0, "src2": 3, "imm": "0x61fc9eb8", "imm2": "0x23202e9d", "rot": 30, "bit": 16, "mask": 16}, + {"i": 29, "op": "shfl", "dst": 2, "src": 4, "src2": 3, "imm": "0x339dbd65", "imm2": "0xc175f639", "rot": 15, "bit": 22, "mask": 2}, + {"i": 30, "op": "shfl", "dst": 1, "src": 6, "src2": 1, "imm": "0x5bd14589", "imm2": "0xa68a2bed", "rot": 31, "bit": 31, "mask": 1}, + {"i": 31, "op": "add", "dst": 1, "src": 6, "src2": 1, "imm": "0x37985632", "imm2": "0xb1cdb2ab", "rot": 29, "bit": 1, "mask": 8}, + {"i": 32, "op": "rotr", "dst": 0, "src": 1, "src2": 6, "imm": "0x4b2058f4", "imm2": "0xf06d8ac9", "rot": 9, "bit": 15, "mask": 16}, + {"i": 33, "op": "shfl", "dst": 3, "src": 4, "src2": 4, "imm": "0x2081626c", "imm2": "0x08d1bb87", "rot": 24, "bit": 29, "mask": 2}, + {"i": 34, "op": "shfl", "dst": 0, "src": 3, "src2": 6, "imm": "0xe4fcfe03", "imm2": "0x78a46b13", "rot": 15, "bit": 29, "mask": 4}, + {"i": 35, "op": "mul", "dst": 7, "src": 0, "src2": 4, "imm": "0x33148d30", "imm2": "0x5780a3d6", "rot": 6, "bit": 11, "mask": 2}, + {"i": 36, "op": "add", "dst": 3, "src": 1, "src2": 1, "imm": "0x804e777e", "imm2": "0x856e0180", "rot": 22, "bit": 0, "mask": 16}, + {"i": 37, "op": "xor", "dst": 1, "src": 6, "src2": 0, "imm": "0xc69aa2f6", "imm2": "0xafebe3e8", "rot": 15, "bit": 9, "mask": 16}, + {"i": 38, "op": "mul", "dst": 2, "src": 7, "src2": 4, "imm": "0xeb4c4082", "imm2": "0x3f1e0da7", "rot": 25, "bit": 20, "mask": 16}, + {"i": 39, "op": "add", "dst": 6, "src": 5, "src2": 5, "imm": "0x0b06c8a7", "imm2": "0xe9bd0cc4", "rot": 6, "bit": 2, "mask": 4}, + {"i": 40, "op": "mul", "dst": 5, "src": 7, "src2": 7, "imm": "0x070af1b6", "imm2": "0x6b648e75", "rot": 10, "bit": 6, "mask": 16}, + {"i": 41, "op": "mulhi", "dst": 2, "src": 3, "src2": 2, "imm": "0x389753b2", "imm2": "0x9e657305", "rot": 30, "bit": 2, "mask": 4}, + {"i": 42, "op": "xor", "dst": 2, "src": 0, "src2": 4, "imm": "0x0960e5b9", "imm2": "0xa925a406", "rot": 4, "bit": 6, "mask": 16}, + {"i": 43, "op": "rotl", "dst": 0, "src": 1, "src2": 1, "imm": "0x8eabe09f", "imm2": "0x76ef71e2", "rot": 4, "bit": 19, "mask": 8}, + {"i": 44, "op": "mulhi", "dst": 4, "src": 3, "src2": 7, "imm": "0x6a34768a", "imm2": "0x2e427c64", "rot": 21, "bit": 5, "mask": 4}, + {"i": 45, "op": "add", "dst": 6, "src": 7, "src2": 5, "imm": "0xee822e17", "imm2": "0xcdcb63f6", "rot": 27, "bit": 12, "mask": 16}, + {"i": 46, "op": "mad", "dst": 3, "src": 2, "src2": 0, "imm": "0xc89ead43", "imm2": "0x4d3108b2", "rot": 26, "bit": 17, "mask": 1}, + {"i": 47, "op": "shfl", "dst": 4, "src": 3, "src2": 0, "imm": "0xdd62be9e", "imm2": "0xf243f6f2", "rot": 8, "bit": 4, "mask": 8}, + {"i": 48, "op": "mulhi", "dst": 6, "src": 5, "src2": 0, "imm": "0xd3f7fa72", "imm2": "0x0debc83f", "rot": 25, "bit": 5, "mask": 2}, + {"i": 49, "op": "sub", "dst": 0, "src": 2, "src2": 6, "imm": "0x7afadd15", "imm2": "0xc07fc39c", "rot": 30, "bit": 29, "mask": 8}, + {"i": 50, "op": "sub", "dst": 3, "src": 5, "src2": 3, "imm": "0x179b78ec", "imm2": "0xaeccde37", "rot": 30, "bit": 17, "mask": 1}, + {"i": 51, "op": "rotr", "dst": 1, "src": 4, "src2": 1, "imm": "0xa4bfcea6", "imm2": "0xbf63bb2f", "rot": 2, "bit": 21, "mask": 2}, + {"i": 52, "op": "mad", "dst": 6, "src": 7, "src2": 7, "imm": "0xabf5ed10", "imm2": "0x8a285f51", "rot": 3, "bit": 23, "mask": 2}, + {"i": 53, "op": "xor", "dst": 5, "src": 3, "src2": 5, "imm": "0x88b416eb", "imm2": "0x36271d87", "rot": 19, "bit": 10, "mask": 2}, + {"i": 54, "op": "sub", "dst": 1, "src": 0, "src2": 1, "imm": "0xa3417dd3", "imm2": "0xcd98f620", "rot": 28, "bit": 2, "mask": 1}, + {"i": 55, "op": "sub", "dst": 5, "src": 6, "src2": 2, "imm": "0x45996c6f", "imm2": "0xe3d41087", "rot": 4, "bit": 31, "mask": 1}, + {"i": 56, "op": "add", "dst": 3, "src": 2, "src2": 0, "imm": "0x3dfad1b6", "imm2": "0xd4758987", "rot": 27, "bit": 10, "mask": 2}, + {"i": 57, "op": "add", "dst": 4, "src": 1, "src2": 3, "imm": "0xfca75bc2", "imm2": "0x0602d6be", "rot": 19, "bit": 0, "mask": 16}, + {"i": 58, "op": "mulhi", "dst": 5, "src": 6, "src2": 5, "imm": "0x83250a7b", "imm2": "0x2f93d53b", "rot": 25, "bit": 7, "mask": 2}, + {"i": 59, "op": "shfl", "dst": 2, "src": 1, "src2": 0, "imm": "0x13f4a089", "imm2": "0x145ea125", "rot": 12, "bit": 3, "mask": 2}, + {"i": 60, "op": "rotl", "dst": 2, "src": 5, "src2": 6, "imm": "0xad3170e3", "imm2": "0x15db04d1", "rot": 9, "bit": 13, "mask": 2}, + {"i": 61, "op": "or", "dst": 4, "src": 6, "src2": 2, "imm": "0x4b6305b2", "imm2": "0x6e7b2e9c", "rot": 27, "bit": 16, "mask": 4}, + {"i": 62, "op": "rotr", "dst": 6, "src": 4, "src2": 6, "imm": "0xfcd4b1c9", "imm2": "0xaf5c733b", "rot": 6, "bit": 21, "mask": 16}, + {"i": 63, "op": "mul", "dst": 2, "src": 4, "src2": 6, "imm": "0x95cebb3e", "imm2": "0xbba9cdfc", "rot": 19, "bit": 23, "mask": 1}, + {"i": 64, "op": "xor", "dst": 0, "src": 5, "src2": 7, "imm": "0x5f7579ff", "imm2": "0xb104e01a", "rot": 25, "bit": 12, "mask": 8}, + {"i": 65, "op": "xor", "dst": 2, "src": 7, "src2": 3, "imm": "0x749c7611", "imm2": "0xf17df3bb", "rot": 27, "bit": 26, "mask": 2}, + {"i": 66, "op": "add", "dst": 2, "src": 1, "src2": 6, "imm": "0xd71c02ff", "imm2": "0x8596687a", "rot": 4, "bit": 6, "mask": 2}, + {"i": 67, "op": "rotl", "dst": 1, "src": 3, "src2": 2, "imm": "0xd2864071", "imm2": "0xaa644ef3", "rot": 21, "bit": 5, "mask": 1}, + {"i": 68, "op": "mul", "dst": 3, "src": 2, "src2": 1, "imm": "0xd0689a5f", "imm2": "0xa3a1f063", "rot": 13, "bit": 28, "mask": 2}, + {"i": 69, "op": "shfl", "dst": 7, "src": 5, "src2": 6, "imm": "0xd01476eb", "imm2": "0x76abb5c2", "rot": 7, "bit": 30, "mask": 2}, + {"i": 70, "op": "mul", "dst": 3, "src": 2, "src2": 5, "imm": "0x59a75c10", "imm2": "0x1e1fbb72", "rot": 20, "bit": 16, "mask": 1}, + {"i": 71, "op": "mad", "dst": 0, "src": 2, "src2": 5, "imm": "0x39cca1df", "imm2": "0x22c057ac", "rot": 5, "bit": 23, "mask": 16}, + {"i": 72, "op": "add", "dst": 6, "src": 7, "src2": 3, "imm": "0x3c6fe15d", "imm2": "0x08ac5733", "rot": 14, "bit": 0, "mask": 4}, + {"i": 73, "op": "shfl", "dst": 3, "src": 2, "src2": 6, "imm": "0x2098627d", "imm2": "0xf4fecc81", "rot": 20, "bit": 30, "mask": 8}, + {"i": 74, "op": "mul", "dst": 3, "src": 6, "src2": 5, "imm": "0xf82e9e23", "imm2": "0x3ad62132", "rot": 10, "bit": 14, "mask": 16}, + {"i": 75, "op": "xor", "dst": 6, "src": 7, "src2": 4, "imm": "0x70548a91", "imm2": "0xa9715d2e", "rot": 6, "bit": 24, "mask": 1}, + {"i": 76, "op": "or", "dst": 3, "src": 0, "src2": 7, "imm": "0xa164325f", "imm2": "0xf300838b", "rot": 23, "bit": 23, "mask": 16}, + {"i": 77, "op": "add", "dst": 2, "src": 4, "src2": 6, "imm": "0x295d5fae", "imm2": "0xc100b495", "rot": 7, "bit": 1, "mask": 2}, + {"i": 78, "op": "mulhi", "dst": 3, "src": 7, "src2": 4, "imm": "0xb62cca87", "imm2": "0x2ebde415", "rot": 14, "bit": 7, "mask": 2}, + {"i": 79, "op": "or", "dst": 4, "src": 1, "src2": 7, "imm": "0xfcbc482d", "imm2": "0x8876e6cd", "rot": 29, "bit": 5, "mask": 2}, + {"i": 80, "op": "rotr", "dst": 4, "src": 3, "src2": 0, "imm": "0x6d64013b", "imm2": "0x675f4a8d", "rot": 26, "bit": 18, "mask": 8}, + {"i": 81, "op": "add", "dst": 4, "src": 3, "src2": 3, "imm": "0x274a9221", "imm2": "0x5cc59530", "rot": 15, "bit": 15, "mask": 2}, + {"i": 82, "op": "add", "dst": 7, "src": 3, "src2": 0, "imm": "0xc8651f8e", "imm2": "0x141479ec", "rot": 18, "bit": 5, "mask": 1}, + {"i": 83, "op": "rotr", "dst": 3, "src": 6, "src2": 0, "imm": "0xcc8a7766", "imm2": "0xc2eb5161", "rot": 4, "bit": 29, "mask": 2}, + {"i": 84, "op": "mad", "dst": 2, "src": 4, "src2": 7, "imm": "0xbc507d51", "imm2": "0x0b1196fd", "rot": 9, "bit": 7, "mask": 8}, + {"i": 85, "op": "shfl", "dst": 2, "src": 5, "src2": 5, "imm": "0x5a156c90", "imm2": "0xa6b3fbfa", "rot": 11, "bit": 2, "mask": 16}, + {"i": 86, "op": "xor", "dst": 3, "src": 2, "src2": 1, "imm": "0x8b042658", "imm2": "0xacf37a8f", "rot": 12, "bit": 23, "mask": 16}, + {"i": 87, "op": "shfl", "dst": 5, "src": 7, "src2": 2, "imm": "0x1a214238", "imm2": "0x017fdf5d", "rot": 29, "bit": 14, "mask": 2}, + {"i": 88, "op": "xor", "dst": 0, "src": 4, "src2": 2, "imm": "0xd523e612", "imm2": "0x2158c2ed", "rot": 30, "bit": 14, "mask": 4}, + {"i": 89, "op": "add", "dst": 3, "src": 2, "src2": 7, "imm": "0x53f915c2", "imm2": "0x883c0c92", "rot": 9, "bit": 18, "mask": 8}, + {"i": 90, "op": "rotr", "dst": 7, "src": 5, "src2": 5, "imm": "0xbd633b21", "imm2": "0xcf8c356c", "rot": 25, "bit": 31, "mask": 4}, + {"i": 91, "op": "add", "dst": 3, "src": 1, "src2": 1, "imm": "0xe2be00a5", "imm2": "0x3cc5bd20", "rot": 10, "bit": 31, "mask": 1}, + {"i": 92, "op": "shfl", "dst": 7, "src": 2, "src2": 4, "imm": "0x3d3da600", "imm2": "0x1f22df89", "rot": 4, "bit": 24, "mask": 1}, + {"i": 93, "op": "rotr", "dst": 6, "src": 2, "src2": 7, "imm": "0xb0f57471", "imm2": "0x8f2a7eca", "rot": 16, "bit": 25, "mask": 1}, + {"i": 94, "op": "rotl", "dst": 7, "src": 0, "src2": 4, "imm": "0x00a21815", "imm2": "0xeb4d7218", "rot": 14, "bit": 18, "mask": 16}, + {"i": 95, "op": "mad", "dst": 4, "src": 5, "src2": 5, "imm": "0xc4c3828e", "imm2": "0xfb7bba17", "rot": 16, "bit": 10, "mask": 16}, + {"i": 96, "op": "mad", "dst": 2, "src": 4, "src2": 5, "imm": "0xfc5bbc75", "imm2": "0xfc43468f", "rot": 31, "bit": 20, "mask": 16}, + {"i": 97, "op": "xor", "dst": 1, "src": 0, "src2": 2, "imm": "0x1fe9c249", "imm2": "0x164bb16b", "rot": 15, "bit": 9, "mask": 4}, + {"i": 98, "op": "mul", "dst": 5, "src": 4, "src2": 1, "imm": "0xeda725fa", "imm2": "0x66f7e9a2", "rot": 21, "bit": 6, "mask": 2}, + {"i": 99, "op": "sub", "dst": 2, "src": 0, "src2": 7, "imm": "0x8fb29f7d", "imm2": "0xf530eda1", "rot": 27, "bit": 30, "mask": 4}, + {"i": 100, "op": "rotl", "dst": 7, "src": 2, "src2": 0, "imm": "0x9f4de742", "imm2": "0x9b5ff871", "rot": 30, "bit": 21, "mask": 16}, + {"i": 101, "op": "add", "dst": 5, "src": 6, "src2": 7, "imm": "0x423fd9c9", "imm2": "0xbfd646cb", "rot": 17, "bit": 17, "mask": 2}, + {"i": 102, "op": "add", "dst": 7, "src": 6, "src2": 3, "imm": "0x8d3c011d", "imm2": "0x19b74a43", "rot": 12, "bit": 11, "mask": 4}, + {"i": 103, "op": "rotl", "dst": 5, "src": 6, "src2": 0, "imm": "0xcfc70303", "imm2": "0xf2b3e8ef", "rot": 6, "bit": 24, "mask": 1}, + {"i": 104, "op": "mul", "dst": 0, "src": 4, "src2": 5, "imm": "0x650475eb", "imm2": "0x11dcbd94", "rot": 15, "bit": 10, "mask": 1}, + {"i": 105, "op": "or", "dst": 0, "src": 5, "src2": 3, "imm": "0xaacaa145", "imm2": "0x9139d3fe", "rot": 4, "bit": 18, "mask": 2}, + {"i": 106, "op": "add", "dst": 0, "src": 1, "src2": 7, "imm": "0x8ce14721", "imm2": "0x7dcb7e18", "rot": 24, "bit": 15, "mask": 8}, + {"i": 107, "op": "rotl", "dst": 0, "src": 3, "src2": 3, "imm": "0xb36d6d98", "imm2": "0x2c3390c8", "rot": 15, "bit": 10, "mask": 16}, + {"i": 108, "op": "sub", "dst": 4, "src": 2, "src2": 5, "imm": "0xf6bbdaef", "imm2": "0x9db6f65e", "rot": 25, "bit": 10, "mask": 1}, + {"i": 109, "op": "mulhi", "dst": 2, "src": 0, "src2": 0, "imm": "0xb1721fd6", "imm2": "0xd96d52c9", "rot": 1, "bit": 27, "mask": 8}, + {"i": 110, "op": "mulhi", "dst": 1, "src": 0, "src2": 5, "imm": "0xfb4ca37f", "imm2": "0xb6ec7dbe", "rot": 27, "bit": 12, "mask": 8}, + {"i": 111, "op": "add", "dst": 0, "src": 2, "src2": 0, "imm": "0x2d9fc6b9", "imm2": "0x3c179ad8", "rot": 9, "bit": 28, "mask": 16}, + {"i": 112, "op": "mulhi", "dst": 2, "src": 0, "src2": 6, "imm": "0x71a9f6bd", "imm2": "0xd3417bf5", "rot": 2, "bit": 14, "mask": 8}, + {"i": 113, "op": "sub", "dst": 6, "src": 3, "src2": 5, "imm": "0xa3d19400", "imm2": "0x15df7330", "rot": 5, "bit": 2, "mask": 8}, + {"i": 114, "op": "mad", "dst": 7, "src": 6, "src2": 3, "imm": "0x1400d92e", "imm2": "0xfa4a158e", "rot": 16, "bit": 9, "mask": 1}, + {"i": 115, "op": "rotr", "dst": 5, "src": 1, "src2": 3, "imm": "0xd01684c3", "imm2": "0x6367febb", "rot": 23, "bit": 19, "mask": 2}, + {"i": 116, "op": "rotr", "dst": 6, "src": 4, "src2": 2, "imm": "0x8cd9eb96", "imm2": "0x98f33b24", "rot": 25, "bit": 1, "mask": 2}, + {"i": 117, "op": "add", "dst": 2, "src": 1, "src2": 7, "imm": "0x502138e2", "imm2": "0x47359729", "rot": 5, "bit": 22, "mask": 4}, + {"i": 118, "op": "mad", "dst": 3, "src": 2, "src2": 0, "imm": "0xd94a35c7", "imm2": "0xb83416c3", "rot": 11, "bit": 3, "mask": 4}, + {"i": 119, "op": "mul", "dst": 1, "src": 3, "src2": 6, "imm": "0x09b30cf7", "imm2": "0xef3b98e7", "rot": 17, "bit": 23, "mask": 8}, + {"i": 120, "op": "mad", "dst": 2, "src": 0, "src2": 4, "imm": "0x56416fe0", "imm2": "0x5e1dc8f3", "rot": 17, "bit": 14, "mask": 2}, + {"i": 121, "op": "mul", "dst": 0, "src": 3, "src2": 2, "imm": "0x2892697c", "imm2": "0x9cb3b14e", "rot": 29, "bit": 25, "mask": 2}, + {"i": 122, "op": "mulhi", "dst": 2, "src": 0, "src2": 3, "imm": "0xc33089a1", "imm2": "0xd6c5b530", "rot": 27, "bit": 13, "mask": 8}, + {"i": 123, "op": "mul", "dst": 5, "src": 6, "src2": 4, "imm": "0xdfe04e4a", "imm2": "0x3cc40160", "rot": 3, "bit": 14, "mask": 2}, + {"i": 124, "op": "mad", "dst": 4, "src": 2, "src2": 4, "imm": "0xb33dc1b7", "imm2": "0xab97743a", "rot": 7, "bit": 21, "mask": 4}, + {"i": 125, "op": "shfl", "dst": 4, "src": 2, "src2": 0, "imm": "0xfd469909", "imm2": "0xfc85dc55", "rot": 28, "bit": 24, "mask": 2}, + {"i": 126, "op": "xor", "dst": 2, "src": 0, "src2": 5, "imm": "0xa0094578", "imm2": "0xf1bee474", "rot": 31, "bit": 7, "mask": 2}, + {"i": 127, "op": "rotl", "dst": 1, "src": 7, "src2": 2, "imm": "0xb7ae00a0", "imm2": "0x86cce297", "rot": 7, "bit": 31, "mask": 8}, + {"i": 128, "op": "shfl", "dst": 7, "src": 2, "src2": 7, "imm": "0x019d1940", "imm2": "0x3fe9e7dd", "rot": 14, "bit": 4, "mask": 4}, + {"i": 129, "op": "rotl", "dst": 6, "src": 7, "src2": 7, "imm": "0x40a74cc4", "imm2": "0x09eb4adf", "rot": 17, "bit": 30, "mask": 1}, + {"i": 130, "op": "add", "dst": 2, "src": 5, "src2": 5, "imm": "0x33dff776", "imm2": "0x6c57e4e7", "rot": 27, "bit": 15, "mask": 4}, + {"i": 131, "op": "or", "dst": 0, "src": 3, "src2": 1, "imm": "0xe0c53bb9", "imm2": "0x124404f6", "rot": 4, "bit": 21, "mask": 16}, + {"i": 132, "op": "rotr", "dst": 5, "src": 0, "src2": 1, "imm": "0xe4353fce", "imm2": "0x559d0118", "rot": 2, "bit": 29, "mask": 4}, + {"i": 133, "op": "add", "dst": 2, "src": 3, "src2": 6, "imm": "0x5db25b34", "imm2": "0xe8212c0c", "rot": 21, "bit": 30, "mask": 1}, + {"i": 134, "op": "xor", "dst": 4, "src": 3, "src2": 6, "imm": "0x7366e50e", "imm2": "0x7cc1ffbd", "rot": 19, "bit": 18, "mask": 16}, + {"i": 135, "op": "xor", "dst": 6, "src": 1, "src2": 2, "imm": "0xa36decb7", "imm2": "0x79291734", "rot": 26, "bit": 0, "mask": 8}, + {"i": 136, "op": "sub", "dst": 1, "src": 7, "src2": 0, "imm": "0x225b03e4", "imm2": "0x7183e193", "rot": 16, "bit": 6, "mask": 2}, + {"i": 137, "op": "mad", "dst": 2, "src": 6, "src2": 2, "imm": "0x6f620d51", "imm2": "0x4e814e19", "rot": 6, "bit": 6, "mask": 2}, + {"i": 138, "op": "mulhi", "dst": 0, "src": 5, "src2": 6, "imm": "0x919d6bf3", "imm2": "0xc6240638", "rot": 17, "bit": 11, "mask": 16}, + {"i": 139, "op": "add", "dst": 2, "src": 7, "src2": 7, "imm": "0x218d4090", "imm2": "0xd44ff710", "rot": 1, "bit": 10, "mask": 16}, + {"i": 140, "op": "rotr", "dst": 1, "src": 4, "src2": 4, "imm": "0x4cbfa722", "imm2": "0x114e9564", "rot": 28, "bit": 9, "mask": 16}, + {"i": 141, "op": "shfl", "dst": 3, "src": 6, "src2": 2, "imm": "0xf702c6a1", "imm2": "0xf8f3c5d9", "rot": 7, "bit": 24, "mask": 1}, + {"i": 142, "op": "mad", "dst": 7, "src": 6, "src2": 2, "imm": "0xa2d285be", "imm2": "0x9cc94532", "rot": 15, "bit": 20, "mask": 8}, + {"i": 143, "op": "mul", "dst": 2, "src": 3, "src2": 7, "imm": "0x08b7ed80", "imm2": "0xa8abced4", "rot": 18, "bit": 10, "mask": 4}, + {"i": 144, "op": "add", "dst": 7, "src": 4, "src2": 2, "imm": "0xf4b1a8de", "imm2": "0xb98942fa", "rot": 18, "bit": 29, "mask": 8}, + {"i": 145, "op": "rotl", "dst": 7, "src": 6, "src2": 1, "imm": "0x64b6ba2d", "imm2": "0xf9e86793", "rot": 15, "bit": 24, "mask": 8}, + {"i": 146, "op": "xor", "dst": 7, "src": 5, "src2": 3, "imm": "0x41c42b5f", "imm2": "0x7c7e0e39", "rot": 8, "bit": 23, "mask": 2}, + {"i": 147, "op": "mad", "dst": 4, "src": 7, "src2": 4, "imm": "0x3caa807a", "imm2": "0x553a0cec", "rot": 11, "bit": 22, "mask": 8}, + {"i": 148, "op": "rotr", "dst": 6, "src": 5, "src2": 3, "imm": "0x3cb1289a", "imm2": "0x6b36f78a", "rot": 1, "bit": 9, "mask": 16}, + {"i": 149, "op": "mad", "dst": 1, "src": 2, "src2": 4, "imm": "0x95310ea8", "imm2": "0xc533aa6a", "rot": 16, "bit": 17, "mask": 1}, + {"i": 150, "op": "add", "dst": 1, "src": 7, "src2": 7, "imm": "0x2bef10f2", "imm2": "0x0d48ba42", "rot": 8, "bit": 17, "mask": 4}, + {"i": 151, "op": "xor", "dst": 5, "src": 4, "src2": 7, "imm": "0xda997ab2", "imm2": "0xae31d69e", "rot": 11, "bit": 31, "mask": 2}, + {"i": 152, "op": "add", "dst": 7, "src": 0, "src2": 6, "imm": "0xdc5cc080", "imm2": "0xc98dea9c", "rot": 16, "bit": 30, "mask": 2}, + {"i": 153, "op": "mul", "dst": 4, "src": 6, "src2": 7, "imm": "0xbfbf5f6c", "imm2": "0x61f611bb", "rot": 14, "bit": 22, "mask": 2}, + {"i": 154, "op": "mul", "dst": 0, "src": 2, "src2": 3, "imm": "0xa78008c3", "imm2": "0xbad5eeb1", "rot": 10, "bit": 28, "mask": 8}, + {"i": 155, "op": "xor", "dst": 6, "src": 5, "src2": 4, "imm": "0x1a73b866", "imm2": "0x1f5a62c9", "rot": 9, "bit": 27, "mask": 8}, + {"i": 156, "op": "rotr", "dst": 4, "src": 2, "src2": 0, "imm": "0x9c88500c", "imm2": "0xe25dccf9", "rot": 11, "bit": 2, "mask": 16}, + {"i": 157, "op": "rotl", "dst": 1, "src": 4, "src2": 4, "imm": "0xb05e7669", "imm2": "0x9db704b1", "rot": 11, "bit": 28, "mask": 4}, + {"i": 158, "op": "add", "dst": 5, "src": 0, "src2": 6, "imm": "0x18197438", "imm2": "0x6c752dcb", "rot": 11, "bit": 11, "mask": 2}, + {"i": 159, "op": "mad", "dst": 4, "src": 1, "src2": 5, "imm": "0x4796a65e", "imm2": "0x00e08c7a", "rot": 8, "bit": 19, "mask": 4}, + {"i": 160, "op": "rotl", "dst": 4, "src": 7, "src2": 5, "imm": "0x08a03052", "imm2": "0x0204f0ba", "rot": 26, "bit": 5, "mask": 2}, + {"i": 161, "op": "mad", "dst": 3, "src": 0, "src2": 7, "imm": "0xa0603b0e", "imm2": "0x7eee83d5", "rot": 28, "bit": 22, "mask": 16}, + {"i": 162, "op": "rotr", "dst": 3, "src": 1, "src2": 6, "imm": "0x78a3c69d", "imm2": "0x684693a0", "rot": 21, "bit": 23, "mask": 4}, + {"i": 163, "op": "add", "dst": 4, "src": 0, "src2": 7, "imm": "0xf1c46574", "imm2": "0x8e481727", "rot": 9, "bit": 3, "mask": 4}, + {"i": 164, "op": "mulhi", "dst": 0, "src": 4, "src2": 3, "imm": "0x04644afa", "imm2": "0x64bda2b5", "rot": 26, "bit": 16, "mask": 16}, + {"i": 165, "op": "add", "dst": 2, "src": 6, "src2": 2, "imm": "0xac578137", "imm2": "0x550ab406", "rot": 13, "bit": 20, "mask": 16}, + {"i": 166, "op": "rotl", "dst": 0, "src": 4, "src2": 5, "imm": "0x7f564760", "imm2": "0xb9a8b4f8", "rot": 13, "bit": 29, "mask": 1}, + {"i": 167, "op": "add", "dst": 3, "src": 1, "src2": 0, "imm": "0xa33e6706", "imm2": "0xaebb5966", "rot": 12, "bit": 14, "mask": 16}, + {"i": 168, "op": "or", "dst": 3, "src": 5, "src2": 3, "imm": "0x65b2f3eb", "imm2": "0xb1d00d20", "rot": 12, "bit": 2, "mask": 8}, + {"i": 169, "op": "rotr", "dst": 6, "src": 2, "src2": 3, "imm": "0x7f21faf5", "imm2": "0xbbf0d3f9", "rot": 17, "bit": 13, "mask": 8}, + {"i": 170, "op": "xor", "dst": 4, "src": 6, "src2": 2, "imm": "0x162c7140", "imm2": "0x90d404ad", "rot": 26, "bit": 1, "mask": 4}, + {"i": 171, "op": "sub", "dst": 6, "src": 1, "src2": 7, "imm": "0x6ef9c76e", "imm2": "0xfb7ba272", "rot": 31, "bit": 25, "mask": 1}, + {"i": 172, "op": "rotl", "dst": 7, "src": 5, "src2": 4, "imm": "0xde04eb3b", "imm2": "0xd56caa00", "rot": 22, "bit": 21, "mask": 4}, + {"i": 173, "op": "rotl", "dst": 5, "src": 3, "src2": 5, "imm": "0xa9eac934", "imm2": "0x2c338e51", "rot": 15, "bit": 22, "mask": 2}, + {"i": 174, "op": "shfl", "dst": 7, "src": 0, "src2": 3, "imm": "0x700be4e3", "imm2": "0x4bcfc732", "rot": 19, "bit": 6, "mask": 8}, + {"i": 175, "op": "xor", "dst": 0, "src": 5, "src2": 1, "imm": "0x02ccdba9", "imm2": "0xd0915be0", "rot": 15, "bit": 2, "mask": 16}, + {"i": 176, "op": "rotl", "dst": 7, "src": 4, "src2": 1, "imm": "0x489c8165", "imm2": "0xf24b5a4f", "rot": 6, "bit": 22, "mask": 1}, + {"i": 177, "op": "sub", "dst": 7, "src": 0, "src2": 6, "imm": "0x23ad9693", "imm2": "0x9a8c2f7b", "rot": 24, "bit": 2, "mask": 2}, + {"i": 178, "op": "rotl", "dst": 3, "src": 0, "src2": 6, "imm": "0xafa72a42", "imm2": "0x371d74ee", "rot": 30, "bit": 16, "mask": 1}, + {"i": 179, "op": "mad", "dst": 7, "src": 6, "src2": 1, "imm": "0x18a2a3f3", "imm2": "0xb811b951", "rot": 2, "bit": 9, "mask": 2}, + {"i": 180, "op": "rotl", "dst": 6, "src": 4, "src2": 1, "imm": "0xe6c69c0e", "imm2": "0xfc46a951", "rot": 9, "bit": 31, "mask": 4}, + {"i": 181, "op": "xor", "dst": 2, "src": 4, "src2": 7, "imm": "0xbd1b89e4", "imm2": "0xdf4bce5c", "rot": 15, "bit": 19, "mask": 4}, + {"i": 182, "op": "xor", "dst": 2, "src": 7, "src2": 5, "imm": "0x3dd12aed", "imm2": "0xd0756a69", "rot": 13, "bit": 16, "mask": 4}, + {"i": 183, "op": "xor", "dst": 7, "src": 2, "src2": 3, "imm": "0x77ce69d6", "imm2": "0x2b39bdf2", "rot": 8, "bit": 22, "mask": 16}, + {"i": 184, "op": "add", "dst": 1, "src": 2, "src2": 4, "imm": "0xd94d55ac", "imm2": "0x5bb7550f", "rot": 31, "bit": 21, "mask": 1}, + {"i": 185, "op": "or", "dst": 3, "src": 5, "src2": 6, "imm": "0x7b1ce846", "imm2": "0xcc3b8509", "rot": 28, "bit": 9, "mask": 4}, + {"i": 186, "op": "mulhi", "dst": 6, "src": 3, "src2": 0, "imm": "0xa5e24690", "imm2": "0x2200ba81", "rot": 26, "bit": 10, "mask": 16}, + {"i": 187, "op": "or", "dst": 4, "src": 0, "src2": 3, "imm": "0xf6efe759", "imm2": "0xae1f7118", "rot": 19, "bit": 20, "mask": 4}, + {"i": 188, "op": "shfl", "dst": 7, "src": 1, "src2": 5, "imm": "0xdb318b45", "imm2": "0xcec459c9", "rot": 20, "bit": 11, "mask": 2}, + {"i": 189, "op": "add", "dst": 6, "src": 5, "src2": 1, "imm": "0x89e747fe", "imm2": "0x2a354e2d", "rot": 22, "bit": 6, "mask": 1}, + {"i": 190, "op": "xor", "dst": 1, "src": 4, "src2": 2, "imm": "0xc379e617", "imm2": "0x75e9d63b", "rot": 23, "bit": 3, "mask": 2}, + {"i": 191, "op": "mulhi", "dst": 7, "src": 4, "src2": 3, "imm": "0x5a710287", "imm2": "0x7fe4ead6", "rot": 10, "bit": 25, "mask": 4}, + {"i": 192, "op": "rotl", "dst": 2, "src": 1, "src2": 2, "imm": "0x4d5e59a3", "imm2": "0x1e4fef28", "rot": 26, "bit": 0, "mask": 1}, + {"i": 193, "op": "rotl", "dst": 5, "src": 3, "src2": 7, "imm": "0x7444c47d", "imm2": "0xdad5f8be", "rot": 8, "bit": 30, "mask": 2}, + {"i": 194, "op": "shfl", "dst": 4, "src": 5, "src2": 7, "imm": "0x6a225bbb", "imm2": "0xd6532cd7", "rot": 13, "bit": 17, "mask": 16}, + {"i": 195, "op": "xor", "dst": 4, "src": 5, "src2": 3, "imm": "0x68344b9a", "imm2": "0xcb46a38b", "rot": 1, "bit": 27, "mask": 16}, + {"i": 196, "op": "mul", "dst": 1, "src": 3, "src2": 4, "imm": "0xbebf7359", "imm2": "0x3f0890ba", "rot": 18, "bit": 12, "mask": 4}, + {"i": 197, "op": "add", "dst": 5, "src": 2, "src2": 3, "imm": "0xea03e8e7", "imm2": "0x10cfdc71", "rot": 31, "bit": 7, "mask": 8}, + {"i": 198, "op": "add", "dst": 7, "src": 5, "src2": 1, "imm": "0xa7ee0102", "imm2": "0x66e148d3", "rot": 12, "bit": 15, "mask": 1}, + {"i": 199, "op": "sub", "dst": 5, "src": 2, "src2": 4, "imm": "0xc215584e", "imm2": "0x55fce30f", "rot": 30, "bit": 9, "mask": 2}, + {"i": 200, "op": "shfl", "dst": 5, "src": 1, "src2": 1, "imm": "0x308f8358", "imm2": "0x489f1f93", "rot": 13, "bit": 13, "mask": 2}, + {"i": 201, "op": "shfl", "dst": 7, "src": 1, "src2": 5, "imm": "0x713f1957", "imm2": "0x2239f757", "rot": 15, "bit": 7, "mask": 8}, + {"i": 202, "op": "rotr", "dst": 4, "src": 5, "src2": 1, "imm": "0xb037b6e7", "imm2": "0x49a8b528", "rot": 27, "bit": 13, "mask": 16}, + {"i": 203, "op": "xor", "dst": 7, "src": 5, "src2": 1, "imm": "0x56110241", "imm2": "0xefc8386d", "rot": 22, "bit": 20, "mask": 1}, + {"i": 204, "op": "xor", "dst": 7, "src": 0, "src2": 0, "imm": "0x0827fcc7", "imm2": "0xf4f5dd07", "rot": 13, "bit": 7, "mask": 2}, + {"i": 205, "op": "add", "dst": 6, "src": 2, "src2": 0, "imm": "0x8379a4de", "imm2": "0x8558b619", "rot": 26, "bit": 10, "mask": 1}, + {"i": 206, "op": "rotl", "dst": 4, "src": 3, "src2": 3, "imm": "0x091ceef0", "imm2": "0x69b0f72f", "rot": 13, "bit": 7, "mask": 1}, + {"i": 207, "op": "mulhi", "dst": 1, "src": 3, "src2": 4, "imm": "0x758edac1", "imm2": "0x98dd2f21", "rot": 15, "bit": 9, "mask": 1}, + {"i": 208, "op": "mad", "dst": 1, "src": 4, "src2": 4, "imm": "0x78871a1a", "imm2": "0x5e14e1c8", "rot": 19, "bit": 6, "mask": 2}, + {"i": 209, "op": "shfl", "dst": 2, "src": 0, "src2": 2, "imm": "0xf7e0b9aa", "imm2": "0xaecfd347", "rot": 21, "bit": 9, "mask": 4}, + {"i": 210, "op": "add", "dst": 7, "src": 0, "src2": 7, "imm": "0xaa8cb14e", "imm2": "0xf4049c4c", "rot": 24, "bit": 11, "mask": 8}, + {"i": 211, "op": "shfl", "dst": 7, "src": 1, "src2": 6, "imm": "0xc230d919", "imm2": "0xf76d08fb", "rot": 21, "bit": 13, "mask": 16}, + {"i": 212, "op": "xor", "dst": 1, "src": 0, "src2": 2, "imm": "0x31a5af90", "imm2": "0x7eef58ee", "rot": 9, "bit": 12, "mask": 4}, + {"i": 213, "op": "rotl", "dst": 7, "src": 1, "src2": 6, "imm": "0x0db26138", "imm2": "0x8e3c31f9", "rot": 3, "bit": 26, "mask": 2}, + {"i": 214, "op": "rotr", "dst": 4, "src": 7, "src2": 3, "imm": "0x29558100", "imm2": "0xe4b13ad6", "rot": 29, "bit": 24, "mask": 8}, + {"i": 215, "op": "shfl", "dst": 3, "src": 2, "src2": 6, "imm": "0x1b48c3d0", "imm2": "0x5c674ff6", "rot": 5, "bit": 9, "mask": 16}, + {"i": 216, "op": "or", "dst": 5, "src": 1, "src2": 0, "imm": "0xef768632", "imm2": "0x6de9d10d", "rot": 10, "bit": 4, "mask": 4}, + {"i": 217, "op": "sub", "dst": 1, "src": 2, "src2": 5, "imm": "0x88ca7f5a", "imm2": "0x24718a36", "rot": 18, "bit": 31, "mask": 1}, + {"i": 218, "op": "sub", "dst": 6, "src": 5, "src2": 0, "imm": "0xc4a06728", "imm2": "0xdc2a4fd8", "rot": 9, "bit": 9, "mask": 2}, + {"i": 219, "op": "rotl", "dst": 6, "src": 5, "src2": 7, "imm": "0xb7489e47", "imm2": "0xf13795c5", "rot": 4, "bit": 3, "mask": 8}, + {"i": 220, "op": "mulhi", "dst": 2, "src": 0, "src2": 2, "imm": "0x873cd31b", "imm2": "0x3dfbc55d", "rot": 12, "bit": 23, "mask": 8}, + {"i": 221, "op": "or", "dst": 2, "src": 0, "src2": 3, "imm": "0xdc21f099", "imm2": "0xee06f01e", "rot": 2, "bit": 17, "mask": 8}, + {"i": 222, "op": "shfl", "dst": 5, "src": 2, "src2": 6, "imm": "0x36def499", "imm2": "0xa2849d59", "rot": 23, "bit": 4, "mask": 8}, + {"i": 223, "op": "mulhi", "dst": 5, "src": 6, "src2": 7, "imm": "0xfb95fbca", "imm2": "0xc1aac427", "rot": 14, "bit": 11, "mask": 2}, + {"i": 224, "op": "sub", "dst": 0, "src": 6, "src2": 7, "imm": "0x3d9d29c4", "imm2": "0x34d0dcc0", "rot": 17, "bit": 6, "mask": 4}, + {"i": 225, "op": "rotl", "dst": 7, "src": 0, "src2": 5, "imm": "0x93b01b8e", "imm2": "0xfe1d75ac", "rot": 23, "bit": 15, "mask": 1}, + {"i": 226, "op": "or", "dst": 4, "src": 2, "src2": 4, "imm": "0xfed76e8e", "imm2": "0x1c24ecd8", "rot": 2, "bit": 6, "mask": 16}, + {"i": 227, "op": "mul", "dst": 2, "src": 4, "src2": 1, "imm": "0x5795f5b0", "imm2": "0x0566ea2a", "rot": 6, "bit": 28, "mask": 4}, + {"i": 228, "op": "rotl", "dst": 3, "src": 0, "src2": 2, "imm": "0x8c8486de", "imm2": "0xd066aa8f", "rot": 12, "bit": 20, "mask": 1}, + {"i": 229, "op": "rotr", "dst": 0, "src": 4, "src2": 0, "imm": "0x23a3e882", "imm2": "0xaca23902", "rot": 5, "bit": 22, "mask": 16}, + {"i": 230, "op": "add", "dst": 0, "src": 6, "src2": 4, "imm": "0x1d176220", "imm2": "0x2a7fecb2", "rot": 20, "bit": 16, "mask": 2}, + {"i": 231, "op": "shfl", "dst": 1, "src": 2, "src2": 0, "imm": "0x91172787", "imm2": "0xc5d7af28", "rot": 3, "bit": 24, "mask": 4}, + {"i": 232, "op": "mul", "dst": 2, "src": 1, "src2": 2, "imm": "0x0be68835", "imm2": "0xde692bdb", "rot": 30, "bit": 17, "mask": 1}, + {"i": 233, "op": "mad", "dst": 7, "src": 0, "src2": 1, "imm": "0xf90d2db5", "imm2": "0x96c4c175", "rot": 28, "bit": 7, "mask": 4}, + {"i": 234, "op": "rotl", "dst": 5, "src": 2, "src2": 1, "imm": "0x16379736", "imm2": "0x6973b905", "rot": 22, "bit": 17, "mask": 4}, + {"i": 235, "op": "rotr", "dst": 4, "src": 6, "src2": 2, "imm": "0x84292a13", "imm2": "0x0f897740", "rot": 12, "bit": 6, "mask": 8}, + {"i": 236, "op": "mad", "dst": 0, "src": 5, "src2": 1, "imm": "0xeb7de837", "imm2": "0x64f0c302", "rot": 4, "bit": 19, "mask": 1}, + {"i": 237, "op": "xor", "dst": 6, "src": 4, "src2": 4, "imm": "0x6ab4b683", "imm2": "0x20f17adb", "rot": 1, "bit": 0, "mask": 16}, + {"i": 238, "op": "xor", "dst": 4, "src": 6, "src2": 1, "imm": "0x5836b35c", "imm2": "0x3293cc4a", "rot": 16, "bit": 22, "mask": 16}, + {"i": 239, "op": "rotl", "dst": 6, "src": 1, "src2": 6, "imm": "0x769d8bc0", "imm2": "0xdc86c9cc", "rot": 18, "bit": 27, "mask": 16}, + {"i": 240, "op": "add", "dst": 4, "src": 7, "src2": 1, "imm": "0x17dafb4d", "imm2": "0xadce39f3", "rot": 12, "bit": 25, "mask": 8}, + {"i": 241, "op": "sub", "dst": 0, "src": 7, "src2": 4, "imm": "0xd4690bda", "imm2": "0xdab9b27b", "rot": 30, "bit": 21, "mask": 1}, + {"i": 242, "op": "rotr", "dst": 1, "src": 6, "src2": 2, "imm": "0x670a2d0a", "imm2": "0x0612e33c", "rot": 31, "bit": 25, "mask": 2}, + {"i": 243, "op": "add", "dst": 3, "src": 0, "src2": 2, "imm": "0xf2f77d26", "imm2": "0x0e7033b6", "rot": 27, "bit": 29, "mask": 1}, + {"i": 244, "op": "mad", "dst": 2, "src": 7, "src2": 4, "imm": "0xa9eefc9d", "imm2": "0x16166c85", "rot": 18, "bit": 23, "mask": 16}, + {"i": 245, "op": "mad", "dst": 4, "src": 0, "src2": 6, "imm": "0xb26f6c0f", "imm2": "0x0630e821", "rot": 23, "bit": 30, "mask": 4}, + {"i": 246, "op": "mul", "dst": 5, "src": 7, "src2": 2, "imm": "0x269ce4bf", "imm2": "0x1ce28d32", "rot": 30, "bit": 15, "mask": 16}, + {"i": 247, "op": "add", "dst": 3, "src": 5, "src2": 0, "imm": "0xfed2da4e", "imm2": "0x7b2ff6b7", "rot": 25, "bit": 31, "mask": 2}, + {"i": 248, "op": "add", "dst": 0, "src": 7, "src2": 5, "imm": "0x03b2891c", "imm2": "0xb5fad7b1", "rot": 2, "bit": 0, "mask": 4}, + {"i": 249, "op": "mulhi", "dst": 5, "src": 4, "src2": 6, "imm": "0xa69a1e71", "imm2": "0x15f0c0ea", "rot": 4, "bit": 1, "mask": 4}, + {"i": 250, "op": "add", "dst": 5, "src": 2, "src2": 3, "imm": "0x042cd6e3", "imm2": "0xa7e71c2f", "rot": 24, "bit": 11, "mask": 8}, + {"i": 251, "op": "shfl", "dst": 6, "src": 1, "src2": 2, "imm": "0x89c6b683", "imm2": "0x10bbf661", "rot": 24, "bit": 5, "mask": 1}, + {"i": 252, "op": "xor", "dst": 6, "src": 1, "src2": 3, "imm": "0x265c66d6", "imm2": "0xd4a689ed", "rot": 6, "bit": 14, "mask": 8}, + {"i": 253, "op": "mul", "dst": 2, "src": 5, "src2": 5, "imm": "0x890b8201", "imm2": "0x97c36bf3", "rot": 17, "bit": 22, "mask": 4}, + {"i": 254, "op": "add", "dst": 0, "src": 6, "src2": 0, "imm": "0x784a302b", "imm2": "0xb83d78de", "rot": 27, "bit": 16, "mask": 4}, + {"i": 255, "op": "sub", "dst": 2, "src": 4, "src2": 0, "imm": "0x817adb38", "imm2": "0xf3a3534b", "rot": 7, "bit": 22, "mask": 4} + ]}, + "instructions": [ + {"i": 0, "op": "mad", "dst": 2, "src": 3, "src2": 4, "imm": "0xbf7b174d", "imm2": "0x337b762e", "rot": 17, "bit": 2, "mask": 2, "width": 1}, + {"i": 1, "op": "mad", "dst": 2, "src": 1, "src2": 1, "imm": "0xdd04a5da", "imm2": "0x42da7657", "rot": 15, "bit": 30, "mask": 16, "width": 1}, + {"i": 2, "op": "mad", "dst": 2, "src": 3, "src2": 2, "imm": "0x734003fa", "imm2": "0x5bb67700", "rot": 3, "bit": 20, "mask": 1, "width": 1}, + {"i": 3, "op": "xor", "dst": 3, "src": 5, "src2": 5, "imm": "0xc55a1b1c", "imm2": "0xa19720f3", "rot": 7, "bit": 8, "mask": 1, "width": 1}, + {"i": 4, "op": "load", "dst": 7, "src": 2, "src2": 5, "imm": "0xad572dd7", "imm2": "0x9ceb3ea7", "rot": 18, "bit": 30, "mask": 2, "width": 1}, + {"i": 5, "op": "load", "dst": 5, "src": 7, "src2": 3, "imm": "0x769a53be", "imm2": "0x80f9067e", "rot": 12, "bit": 22, "mask": 1, "width": 1}, + {"i": 6, "op": "shfl", "dst": 1, "src": 4, "src2": 0, "imm": "0xd3613d88", "imm2": "0x262fb219", "rot": 10, "bit": 30, "mask": 8, "width": 1}, + {"i": 7, "op": "shfl", "dst": 7, "src": 3, "src2": 4, "imm": "0xce38e42f", "imm2": "0xb868b818", "rot": 11, "bit": 8, "mask": 8, "width": 1}, + {"i": 8, "op": "mulhi", "dst": 1, "src": 5, "src2": 2, "imm": "0xa5eebca5", "imm2": "0x5703a72b", "rot": 13, "bit": 13, "mask": 16, "width": 1}, + {"i": 9, "op": "rotr", "dst": 6, "src": 3, "src2": 4, "imm": "0x17a5a9c7", "imm2": "0xdcfb93a1", "rot": 20, "bit": 27, "mask": 2, "width": 1}, + {"i": 10, "op": "or", "dst": 3, "src": 4, "src2": 1, "imm": "0xccb7d785", "imm2": "0xc335364c", "rot": 14, "bit": 12, "mask": 4, "width": 1}, + {"i": 11, "op": "load", "dst": 4, "src": 3, "src2": 2, "imm": "0x88cb9af3", "imm2": "0x4e7dc10d", "rot": 24, "bit": 17, "mask": 4, "width": 1}, + {"i": 12, "op": "mulhi", "dst": 0, "src": 4, "src2": 4, "imm": "0x45374321", "imm2": "0x3cd91989", "rot": 11, "bit": 4, "mask": 2, "width": 1}, + {"i": 13, "op": "add", "dst": 5, "src": 1, "src2": 2, "imm": "0xc7934706", "imm2": "0xd3177981", "rot": 16, "bit": 30, "mask": 2, "width": 1}, + {"i": 14, "op": "load", "dst": 0, "src": 4, "src2": 3, "imm": "0xfd7f56bb", "imm2": "0x65e14f52", "rot": 13, "bit": 22, "mask": 2, "width": 1}, + {"i": 15, "op": "sub", "dst": 2, "src": 4, "src2": 4, "imm": "0x35a80b49", "imm2": "0x060f2d13", "rot": 16, "bit": 20, "mask": 16, "width": 1}, + {"i": 16, "op": "load", "dst": 2, "src": 0, "src2": 2, "imm": "0xae0a32c2", "imm2": "0x4c2a4cfe", "rot": 8, "bit": 31, "mask": 16, "width": 1}, + {"i": 17, "op": "load", "dst": 7, "src": 2, "src2": 6, "imm": "0x82a84cc3", "imm2": "0x21a38d68", "rot": 15, "bit": 21, "mask": 2, "width": 1}, + {"i": 18, "op": "shfl", "dst": 7, "src": 3, "src2": 3, "imm": "0xa3818806", "imm2": "0x8f66b5c8", "rot": 14, "bit": 6, "mask": 4, "width": 1}, + {"i": 19, "op": "mul", "dst": 5, "src": 0, "src2": 1, "imm": "0xa00de107", "imm2": "0x77bfcaa5", "rot": 3, "bit": 10, "mask": 2, "width": 1}, + {"i": 20, "op": "shfl", "dst": 3, "src": 4, "src2": 7, "imm": "0x1d2b8cab", "imm2": "0x80b4f9a2", "rot": 14, "bit": 25, "mask": 2, "width": 1}, + {"i": 21, "op": "shfl", "dst": 2, "src": 4, "src2": 5, "imm": "0x3ac915d2", "imm2": "0x5fba7bc2", "rot": 16, "bit": 1, "mask": 16, "width": 1}, + {"i": 22, "op": "mulhi", "dst": 6, "src": 2, "src2": 0, "imm": "0xdc3ec8fd", "imm2": "0x599e2fa3", "rot": 22, "bit": 3, "mask": 2, "width": 1}, + {"i": 23, "op": "load", "dst": 6, "src": 1, "src2": 5, "imm": "0x2a6b16d5", "imm2": "0xd73e396f", "rot": 28, "bit": 29, "mask": 2, "width": 1}, + {"i": 24, "op": "mul", "dst": 5, "src": 0, "src2": 7, "imm": "0x376d0223", "imm2": "0xe1c2169a", "rot": 4, "bit": 16, "mask": 16, "width": 1}, + {"i": 25, "op": "rotl", "dst": 5, "src": 7, "src2": 3, "imm": "0x78ad8c60", "imm2": "0x6f5b77d5", "rot": 19, "bit": 11, "mask": 16, "width": 1}, + {"i": 26, "op": "shfl", "dst": 7, "src": 6, "src2": 5, "imm": "0x93915b9f", "imm2": "0x1e61fb6b", "rot": 28, "bit": 23, "mask": 2, "width": 1}, + {"i": 27, "op": "xor", "dst": 0, "src": 5, "src2": 7, "imm": "0x6378fe15", "imm2": "0x66c78f42", "rot": 12, "bit": 31, "mask": 8, "width": 1}, + {"i": 28, "op": "xor", "dst": 0, "src": 4, "src2": 7, "imm": "0x20a57fda", "imm2": "0x088c848e", "rot": 16, "bit": 13, "mask": 4, "width": 1}, + {"i": 29, "op": "sub", "dst": 3, "src": 0, "src2": 2, "imm": "0x49d95fd5", "imm2": "0x1a5f946a", "rot": 6, "bit": 12, "mask": 1, "width": 1}, + {"i": 30, "op": "mul", "dst": 5, "src": 1, "src2": 7, "imm": "0x0a816217", "imm2": "0x405c4f73", "rot": 13, "bit": 27, "mask": 4, "width": 1}, + {"i": 31, "op": "load", "dst": 7, "src": 2, "src2": 2, "imm": "0x09ed045e", "imm2": "0xd69c4715", "rot": 5, "bit": 9, "mask": 2, "width": 1}, + {"i": 32, "op": "load", "dst": 1, "src": 0, "src2": 6, "imm": "0xeb79ea49", "imm2": "0xcc587f5a", "rot": 6, "bit": 8, "mask": 16, "width": 1}, + {"i": 33, "op": "xor", "dst": 5, "src": 6, "src2": 1, "imm": "0x3027401e", "imm2": "0x5f20c27e", "rot": 18, "bit": 9, "mask": 2, "width": 1}, + {"i": 34, "op": "load", "dst": 5, "src": 1, "src2": 3, "imm": "0x0e1cab07", "imm2": "0x09356c5b", "rot": 19, "bit": 31, "mask": 1, "width": 1}, + {"i": 35, "op": "mulhi", "dst": 0, "src": 5, "src2": 2, "imm": "0x90e31357", "imm2": "0xabd32484", "rot": 26, "bit": 5, "mask": 8, "width": 1}, + {"i": 36, "op": "shfl", "dst": 5, "src": 2, "src2": 5, "imm": "0xee9a955f", "imm2": "0x31b3faed", "rot": 8, "bit": 24, "mask": 4, "width": 1}, + {"i": 37, "op": "load", "dst": 7, "src": 0, "src2": 7, "imm": "0x3ba2f832", "imm2": "0x1160dcd3", "rot": 4, "bit": 29, "mask": 1, "width": 1}, + {"i": 38, "op": "add", "dst": 3, "src": 1, "src2": 7, "imm": "0x75ba2fad", "imm2": "0x230c005c", "rot": 4, "bit": 27, "mask": 1, "width": 1}, + {"i": 39, "op": "shfl", "dst": 1, "src": 5, "src2": 3, "imm": "0xdbf37e75", "imm2": "0xb5ac1969", "rot": 30, "bit": 13, "mask": 4, "width": 1}, + {"i": 40, "op": "xor", "dst": 2, "src": 5, "src2": 5, "imm": "0x47f136c5", "imm2": "0x06ce9153", "rot": 19, "bit": 10, "mask": 2, "width": 1}, + {"i": 41, "op": "mad", "dst": 3, "src": 6, "src2": 3, "imm": "0xce13eff8", "imm2": "0x04cc1d55", "rot": 3, "bit": 1, "mask": 4, "width": 1}, + {"i": 42, "op": "sub", "dst": 6, "src": 7, "src2": 1, "imm": "0x6a65ab71", "imm2": "0x8fbc1bcd", "rot": 4, "bit": 1, "mask": 8, "width": 1}, + {"i": 43, "op": "xor", "dst": 7, "src": 0, "src2": 7, "imm": "0xdaeb4928", "imm2": "0xc0423027", "rot": 24, "bit": 11, "mask": 8, "width": 1}, + {"i": 44, "op": "load", "dst": 1, "src": 7, "src2": 7, "imm": "0x778f01c9", "imm2": "0x28cedcea", "rot": 12, "bit": 4, "mask": 16, "width": 1}, + {"i": 45, "op": "mul", "dst": 2, "src": 3, "src2": 2, "imm": "0xf4264f1b", "imm2": "0x0f627d56", "rot": 5, "bit": 28, "mask": 8, "width": 1}, + {"i": 46, "op": "mulhi", "dst": 1, "src": 5, "src2": 1, "imm": "0xffb2147a", "imm2": "0xccde9b05", "rot": 13, "bit": 9, "mask": 2, "width": 1}, + {"i": 47, "op": "sub", "dst": 4, "src": 3, "src2": 5, "imm": "0x73b36234", "imm2": "0x3f5d5997", "rot": 7, "bit": 18, "mask": 2, "width": 1}, + {"i": 48, "op": "rotr", "dst": 2, "src": 6, "src2": 3, "imm": "0x3a4d9aa9", "imm2": "0x212bec7b", "rot": 4, "bit": 29, "mask": 16, "width": 1}, + {"i": 49, "op": "load", "dst": 3, "src": 5, "src2": 2, "imm": "0x626f11df", "imm2": "0x56cd5bfd", "rot": 7, "bit": 1, "mask": 1, "width": 1}, + {"i": 50, "op": "add", "dst": 1, "src": 5, "src2": 6, "imm": "0x81b8bc2c", "imm2": "0x1907970c", "rot": 28, "bit": 7, "mask": 4, "width": 1}, + {"i": 51, "op": "mul", "dst": 0, "src": 2, "src2": 2, "imm": "0xa8848b30", "imm2": "0xef6ac348", "rot": 9, "bit": 15, "mask": 8, "width": 1}, + {"i": 52, "op": "add", "dst": 0, "src": 2, "src2": 0, "imm": "0x4f92b968", "imm2": "0x699fd448", "rot": 22, "bit": 6, "mask": 4, "width": 1}, + {"i": 53, "op": "add", "dst": 1, "src": 0, "src2": 2, "imm": "0x2bb965af", "imm2": "0x77b1520d", "rot": 2, "bit": 12, "mask": 8, "width": 1}, + {"i": 54, "op": "rotl", "dst": 7, "src": 1, "src2": 0, "imm": "0x553e678b", "imm2": "0x3cc8eae0", "rot": 14, "bit": 20, "mask": 2, "width": 1}, + {"i": 55, "op": "add", "dst": 3, "src": 7, "src2": 2, "imm": "0x7b0fe07a", "imm2": "0xa54c55a0", "rot": 10, "bit": 1, "mask": 1, "width": 1}, + {"i": 56, "op": "load", "dst": 6, "src": 7, "src2": 4, "imm": "0x01eba9aa", "imm2": "0x2758c0f7", "rot": 14, "bit": 15, "mask": 4, "width": 1}, + {"i": 57, "op": "rotr", "dst": 1, "src": 5, "src2": 2, "imm": "0x1f5267b3", "imm2": "0x236f5a27", "rot": 2, "bit": 31, "mask": 16, "width": 1}, + {"i": 58, "op": "load", "dst": 5, "src": 4, "src2": 3, "imm": "0xa9954a9b", "imm2": "0x6a54d4e8", "rot": 11, "bit": 10, "mask": 16, "width": 1}, + {"i": 59, "op": "load", "dst": 6, "src": 2, "src2": 4, "imm": "0x9923ff88", "imm2": "0x9357254e", "rot": 16, "bit": 1, "mask": 16, "width": 1}, + {"i": 60, "op": "mad", "dst": 3, "src": 5, "src2": 0, "imm": "0xc0cc51a6", "imm2": "0x3fd7701b", "rot": 20, "bit": 1, "mask": 4, "width": 1}, + {"i": 61, "op": "add", "dst": 5, "src": 7, "src2": 7, "imm": "0xaf9dd72d", "imm2": "0xad7493e7", "rot": 7, "bit": 31, "mask": 16, "width": 1}, + {"i": 62, "op": "add", "dst": 4, "src": 6, "src2": 2, "imm": "0x89841d87", "imm2": "0x1e07c3d9", "rot": 6, "bit": 27, "mask": 1, "width": 1}, + {"i": 63, "op": "rotl", "dst": 5, "src": 4, "src2": 2, "imm": "0xae210f8d", "imm2": "0x8e499ba4", "rot": 19, "bit": 9, "mask": 1, "width": 1} + ] +} diff --git a/proto-cuda/packs-ca3-shadow/sh256x88/program.metal b/proto-cuda/packs-ca3-shadow/sh256x88/program.metal new file mode 100644 index 000000000..ad068f3b0 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x88/program.metal @@ -0,0 +1,368 @@ +#include +using namespace metal; + +#define MASK 0x0fffffffu +constant uint SEEDW[8] = { 0x67a9a7beu, 0x1a155b25u, 0xfddfb732u, 0x4b5af2e8u, 0xc55caf33u, 0xa27c13b7u, 0x06628a48u, 0x03852469u }; + +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 = r3 * r4 + r2; // 0 + r2 = r1 * r1 + r2; // 1 + r2 = r3 * r2 + r2; // 2 + r3 = r3 ^ r5; // 3 + r7 = r7 ^ dataset[r2 & MASK]; // 4 + r5 = r5 ^ dataset[r7 & MASK]; // 5 + r1 = r1 ^ simd_shuffle_xor(r4, (ushort)8); // 6 + r7 = r7 ^ simd_shuffle_xor(r3, (ushort)8); // 7 + r1 = mulhi(r1, r5); // 8 + r6 = rotr_var(r6, r3); // 9 + r3 = r3 | r4; // 10 + r4 = r4 ^ dataset[r3 & MASK]; // 11 + r0 = mulhi(r0, r4); // 12 + r5 = r5 + r1 + select(0xc7934706u, 0xd3177981u, ((sel >> 30u) & 1u) != 0u); // 13 + r0 = r0 ^ dataset[r4 & MASK]; // 14 + r2 = r2 - r4; // 15 + r2 = r2 ^ dataset[r0 & MASK]; // 16 + r7 = r7 ^ dataset[r2 & MASK]; // 17 + r7 = r7 ^ simd_shuffle_xor(r3, (ushort)4); // 18 + r5 = r5 * r0; // 19 + r3 = r3 ^ simd_shuffle_xor(r4, (ushort)2); // 20 + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)16); // 21 + r6 = mulhi(r6, r2); // 22 + r6 = r6 ^ dataset[r1 & MASK]; // 23 + r5 = r5 * r0; // 24 + r5 = rotl_imm(r5, 19u); // 25 + r7 = r7 ^ simd_shuffle_xor(r6, (ushort)2); // 26 + r0 = r0 ^ r5; // 27 + r0 = r0 ^ r4; // 28 + r3 = r3 - r0; // 29 + r5 = r5 * r1; // 30 + r7 = r7 ^ dataset[r2 & MASK]; // 31 + r1 = r1 ^ dataset[r0 & MASK]; // 32 + r5 = r5 ^ r6; // 33 + r5 = r5 ^ dataset[r1 & MASK]; // 34 + r0 = mulhi(r0, r5); // 35 + r5 = r5 ^ simd_shuffle_xor(r2, (ushort)4); // 36 + r7 = r7 ^ dataset[r0 & MASK]; // 37 + r3 = r3 + r1 + select(0x75ba2fadu, 0x230c005cu, ((sel >> 27u) & 1u) != 0u); // 38 + r1 = r1 ^ simd_shuffle_xor(r5, (ushort)4); // 39 + r2 = r2 ^ r5; // 40 + r3 = r6 * r3 + r3; // 41 + r6 = r6 - r7; // 42 + r7 = r7 ^ r0; // 43 + r1 = r1 ^ dataset[r7 & MASK]; // 44 + r2 = r2 * r3; // 45 + r1 = mulhi(r1, r5); // 46 + r4 = r4 - r3; // 47 + r2 = rotr_var(r2, r6); // 48 + r3 = r3 ^ dataset[r5 & MASK]; // 49 + r1 = r1 + r5 + select(0x81b8bc2cu, 0x1907970cu, ((sel >> 7u) & 1u) != 0u); // 50 + r0 = r0 * r2; // 51 + r0 = r0 + r2 + select(0x4f92b968u, 0x699fd448u, ((sel >> 6u) & 1u) != 0u); // 52 + r1 = r1 + r0 + select(0x2bb965afu, 0x77b1520du, ((sel >> 12u) & 1u) != 0u); // 53 + r7 = rotl_imm(r7, 14u); // 54 + r3 = r3 + r7 + select(0x7b0fe07au, 0xa54c55a0u, ((sel >> 1u) & 1u) != 0u); // 55 + r6 = r6 ^ dataset[r7 & MASK]; // 56 + r1 = rotr_var(r1, r5); // 57 + r5 = r5 ^ dataset[r4 & MASK]; // 58 + r6 = r6 ^ dataset[r2 & MASK]; // 59 + r3 = r5 * r0 + r3; // 60 + r5 = r5 + r7 + select(0xaf9dd72du, 0xad7493e7u, ((sel >> 31u) & 1u) != 0u); // 61 + r4 = r4 + r6 + select(0x89841d87u, 0x1e07c3d9u, ((sel >> 27u) & 1u) != 0u); // 62 + r5 = rotl_imm(r5, 19u); // 63 + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 88 passes after instruction 63, no load + for (uint sh = 0u; sh < 88u; ++sh) { + r5 = r5 + r2 + select(0x92199f99u, 0x8bc12da9u, ((sel >> 18u) & 1u) != 0u); // s0 add + r0 = r0 + r7 + select(0x8d72d3adu, 0x63079e5au, ((sel >> 26u) & 1u) != 0u); // s1 add + r6 = r6 ^ simd_shuffle_xor(r3, (ushort)2); // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + select(0xb21b4babu, 0x5d4c7a60u, ((sel >> 31u) & 1u) != 0u); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + select(0x2fe0e98bu, 0xc88e2942u, ((sel >> 16u) & 1u) != 0u); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + r6 = r6 ^ simd_shuffle_xor(r1, (ushort)4); // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + r2 = r2 ^ simd_shuffle_xor(r6, (ushort)4); // s12 shfl + r1 = r1 + r5 + select(0xbdf8f9a5u, 0xbc48c63eu, ((sel >> 25u) & 1u) != 0u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)8); // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + select(0x45c37cecu, 0x96e8f127u, ((sel >> 1u) & 1u) != 0u); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = mulhi(r6, r0); // s28 mulhi + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)2); // s29 shfl + r1 = r1 ^ simd_shuffle_xor(r6, (ushort)1); // s30 shfl + r1 = r1 + r6 + select(0x37985632u, 0xb1cdb2abu, ((sel >> 1u) & 1u) != 0u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + r3 = r3 ^ simd_shuffle_xor(r4, (ushort)2); // s33 shfl + r0 = r0 ^ simd_shuffle_xor(r3, (ushort)4); // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + select(0x804e777eu, 0x856e0180u, ((sel >> 0u) & 1u) != 0u); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + select(0x0b06c8a7u, 0xe9bd0cc4u, ((sel >> 2u) & 1u) != 0u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = mulhi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = mulhi(r4, r3); // s44 mulhi + r6 = r6 + r7 + select(0xee822e17u, 0xcdcb63f6u, ((sel >> 12u) & 1u) != 0u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + r4 = r4 ^ simd_shuffle_xor(r3, (ushort)8); // s47 shfl + r6 = mulhi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + select(0x3dfad1b6u, 0xd4758987u, ((sel >> 10u) & 1u) != 0u); // s56 add + r4 = r4 + r1 + select(0xfca75bc2u, 0x0602d6beu, ((sel >> 0u) & 1u) != 0u); // s57 add + r5 = mulhi(r5, r6); // s58 mulhi + r2 = r2 ^ simd_shuffle_xor(r1, (ushort)2); // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + select(0xd71c02ffu, 0x8596687au, ((sel >> 6u) & 1u) != 0u); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + r7 = r7 ^ simd_shuffle_xor(r5, (ushort)2); // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + select(0x3c6fe15du, 0x08ac5733u, ((sel >> 0u) & 1u) != 0u); // s72 add + r3 = r3 ^ simd_shuffle_xor(r2, (ushort)8); // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + select(0x295d5faeu, 0xc100b495u, ((sel >> 1u) & 1u) != 0u); // s77 add + r3 = mulhi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + select(0x274a9221u, 0x5cc59530u, ((sel >> 15u) & 1u) != 0u); // s81 add + r7 = r7 + r3 + select(0xc8651f8eu, 0x141479ecu, ((sel >> 5u) & 1u) != 0u); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + r2 = r2 ^ simd_shuffle_xor(r5, (ushort)16); // s85 shfl + r3 = r3 ^ r2; // s86 xor + r5 = r5 ^ simd_shuffle_xor(r7, (ushort)2); // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + select(0x53f915c2u, 0x883c0c92u, ((sel >> 18u) & 1u) != 0u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + select(0xe2be00a5u, 0x3cc5bd20u, ((sel >> 31u) & 1u) != 0u); // s91 add + r7 = r7 ^ simd_shuffle_xor(r2, (ushort)1); // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + select(0x423fd9c9u, 0xbfd646cbu, ((sel >> 17u) & 1u) != 0u); // s101 add + r7 = r7 + r6 + select(0x8d3c011du, 0x19b74a43u, ((sel >> 11u) & 1u) != 0u); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + select(0x8ce14721u, 0x7dcb7e18u, ((sel >> 15u) & 1u) != 0u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = mulhi(r2, r0); // s109 mulhi + r1 = mulhi(r1, r0); // s110 mulhi + r0 = r0 + r2 + select(0x2d9fc6b9u, 0x3c179ad8u, ((sel >> 28u) & 1u) != 0u); // s111 add + r2 = mulhi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + select(0x502138e2u, 0x47359729u, ((sel >> 22u) & 1u) != 0u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = mulhi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + r4 = r4 ^ simd_shuffle_xor(r2, (ushort)2); // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + r7 = r7 ^ simd_shuffle_xor(r2, (ushort)4); // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + select(0x33dff776u, 0x6c57e4e7u, ((sel >> 15u) & 1u) != 0u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + select(0x5db25b34u, 0xe8212c0cu, ((sel >> 30u) & 1u) != 0u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = mulhi(r0, r5); // s138 mulhi + r2 = r2 + r7 + select(0x218d4090u, 0xd44ff710u, ((sel >> 10u) & 1u) != 0u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + r3 = r3 ^ simd_shuffle_xor(r6, (ushort)1); // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + select(0xf4b1a8deu, 0xb98942fau, ((sel >> 29u) & 1u) != 0u); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + select(0x2bef10f2u, 0x0d48ba42u, ((sel >> 17u) & 1u) != 0u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + select(0xdc5cc080u, 0xc98dea9cu, ((sel >> 30u) & 1u) != 0u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + select(0x18197438u, 0x6c752dcbu, ((sel >> 11u) & 1u) != 0u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + select(0xf1c46574u, 0x8e481727u, ((sel >> 3u) & 1u) != 0u); // s163 add + r0 = mulhi(r0, r4); // s164 mulhi + r2 = r2 + r6 + select(0xac578137u, 0x550ab406u, ((sel >> 20u) & 1u) != 0u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + select(0xa33e6706u, 0xaebb5966u, ((sel >> 14u) & 1u) != 0u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + r7 = r7 ^ simd_shuffle_xor(r0, (ushort)8); // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + select(0xd94d55acu, 0x5bb7550fu, ((sel >> 21u) & 1u) != 0u); // s184 add + r3 = r3 | r5; // s185 or + r6 = mulhi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)2); // s188 shfl + r6 = r6 + r5 + select(0x89e747feu, 0x2a354e2du, ((sel >> 6u) & 1u) != 0u); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = mulhi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + r4 = r4 ^ simd_shuffle_xor(r5, (ushort)16); // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + select(0xea03e8e7u, 0x10cfdc71u, ((sel >> 7u) & 1u) != 0u); // s197 add + r7 = r7 + r5 + select(0xa7ee0102u, 0x66e148d3u, ((sel >> 15u) & 1u) != 0u); // s198 add + r5 = r5 - r2; // s199 sub + r5 = r5 ^ simd_shuffle_xor(r1, (ushort)2); // s200 shfl + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)8); // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + select(0x8379a4deu, 0x8558b619u, ((sel >> 10u) & 1u) != 0u); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = mulhi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + r2 = r2 ^ simd_shuffle_xor(r0, (ushort)4); // s209 shfl + r7 = r7 + r0 + select(0xaa8cb14eu, 0xf4049c4cu, ((sel >> 11u) & 1u) != 0u); // s210 add + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)16); // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + r3 = r3 ^ simd_shuffle_xor(r2, (ushort)16); // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = mulhi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + r5 = r5 ^ simd_shuffle_xor(r2, (ushort)8); // s222 shfl + r5 = mulhi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + select(0x1d176220u, 0x2a7fecb2u, ((sel >> 16u) & 1u) != 0u); // s230 add + r1 = r1 ^ simd_shuffle_xor(r2, (ushort)4); // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + select(0x17dafb4du, 0xadce39f3u, ((sel >> 25u) & 1u) != 0u); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + select(0xf2f77d26u, 0x0e7033b6u, ((sel >> 29u) & 1u) != 0u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + select(0xfed2da4eu, 0x7b2ff6b7u, ((sel >> 31u) & 1u) != 0u); // s247 add + r0 = r0 + r7 + select(0x03b2891cu, 0xb5fad7b1u, ((sel >> 0u) & 1u) != 0u); // s248 add + r5 = mulhi(r5, r4); // s249 mulhi + r5 = r5 + r2 + select(0x042cd6e3u, 0xa7e71c2fu, ((sel >> 11u) & 1u) != 0u); // s250 add + r6 = r6 ^ simd_shuffle_xor(r1, (ushort)1); // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + select(0x784a302bu, 0xb83d78deu, ((sel >> 16u) & 1u) != 0u); // s254 add + r2 = r2 - r4; // s255 sub + } + } + uint lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((ulong)hi << 32) | (ulong)lo; +} diff --git a/proto-cuda/packs-ca3-shadow/sh256x88/program_bound.metal b/proto-cuda/packs-ca3-shadow/sh256x88/program_bound.metal new file mode 100644 index 000000000..9eac74ef2 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x88/program_bound.metal @@ -0,0 +1,370 @@ +#include +using namespace metal; + +#define MASK 0x0fffffffu +constant uint SEEDW[8] = { 0x67a9a7beu, 0x1a155b25u, 0xfddfb732u, 0x4b5af2e8u, 0xc55caf33u, 0xa27c13b7u, 0x06628a48u, 0x03852469u }; + +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 = r3 * r4 + r2; // 0 + r2 = r1 * r1 + r2; // 1 + r2 = r3 * r2 + r2; // 2 + r3 = r3 ^ r5; // 3 + r7 = r7 ^ dataset[r2 & MASK]; // 4 + r5 = r5 ^ dataset[r7 & MASK]; // 5 + r1 = r1 ^ simd_shuffle_xor(r4, (ushort)8); // 6 + r7 = r7 ^ simd_shuffle_xor(r3, (ushort)8); // 7 + r1 = mulhi(r1, r5); // 8 + r6 = rotr_var(r6, r3); // 9 + r3 = r3 | r4; // 10 + r4 = r4 ^ dataset[r3 & MASK]; // 11 + r0 = mulhi(r0, r4); // 12 + r5 = r5 + r1 + select(0xc7934706u, 0xd3177981u, ((sel >> 30u) & 1u) != 0u); // 13 + r0 = r0 ^ dataset[r4 & MASK]; // 14 + r2 = r2 - r4; // 15 + r2 = r2 ^ dataset[r0 & MASK]; // 16 + r7 = r7 ^ dataset[r2 & MASK]; // 17 + r7 = r7 ^ simd_shuffle_xor(r3, (ushort)4); // 18 + r5 = r5 * r0; // 19 + r3 = r3 ^ simd_shuffle_xor(r4, (ushort)2); // 20 + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)16); // 21 + r6 = mulhi(r6, r2); // 22 + r6 = r6 ^ dataset[r1 & MASK]; // 23 + r5 = r5 * r0; // 24 + r5 = rotl_imm(r5, 19u); // 25 + r7 = r7 ^ simd_shuffle_xor(r6, (ushort)2); // 26 + r0 = r0 ^ r5; // 27 + r0 = r0 ^ r4; // 28 + r3 = r3 - r0; // 29 + r5 = r5 * r1; // 30 + r7 = r7 ^ dataset[r2 & MASK]; // 31 + r1 = r1 ^ dataset[r0 & MASK]; // 32 + r5 = r5 ^ r6; // 33 + r5 = r5 ^ dataset[r1 & MASK]; // 34 + r0 = mulhi(r0, r5); // 35 + r5 = r5 ^ simd_shuffle_xor(r2, (ushort)4); // 36 + r7 = r7 ^ dataset[r0 & MASK]; // 37 + r3 = r3 + r1 + select(0x75ba2fadu, 0x230c005cu, ((sel >> 27u) & 1u) != 0u); // 38 + r1 = r1 ^ simd_shuffle_xor(r5, (ushort)4); // 39 + r2 = r2 ^ r5; // 40 + r3 = r6 * r3 + r3; // 41 + r6 = r6 - r7; // 42 + r7 = r7 ^ r0; // 43 + r1 = r1 ^ dataset[r7 & MASK]; // 44 + r2 = r2 * r3; // 45 + r1 = mulhi(r1, r5); // 46 + r4 = r4 - r3; // 47 + r2 = rotr_var(r2, r6); // 48 + r3 = r3 ^ dataset[r5 & MASK]; // 49 + r1 = r1 + r5 + select(0x81b8bc2cu, 0x1907970cu, ((sel >> 7u) & 1u) != 0u); // 50 + r0 = r0 * r2; // 51 + r0 = r0 + r2 + select(0x4f92b968u, 0x699fd448u, ((sel >> 6u) & 1u) != 0u); // 52 + r1 = r1 + r0 + select(0x2bb965afu, 0x77b1520du, ((sel >> 12u) & 1u) != 0u); // 53 + r7 = rotl_imm(r7, 14u); // 54 + r3 = r3 + r7 + select(0x7b0fe07au, 0xa54c55a0u, ((sel >> 1u) & 1u) != 0u); // 55 + r6 = r6 ^ dataset[r7 & MASK]; // 56 + r1 = rotr_var(r1, r5); // 57 + r5 = r5 ^ dataset[r4 & MASK]; // 58 + r6 = r6 ^ dataset[r2 & MASK]; // 59 + r3 = r5 * r0 + r3; // 60 + r5 = r5 + r7 + select(0xaf9dd72du, 0xad7493e7u, ((sel >> 31u) & 1u) != 0u); // 61 + r4 = r4 + r6 + select(0x89841d87u, 0x1e07c3d9u, ((sel >> 27u) & 1u) != 0u); // 62 + r5 = rotl_imm(r5, 19u); // 63 + // latency-shadow block (Counter ASIC 3.0 item 8): 256 ALU instructions x 88 passes after instruction 63, no load + for (uint sh = 0u; sh < 88u; ++sh) { + r5 = r5 + r2 + select(0x92199f99u, 0x8bc12da9u, ((sel >> 18u) & 1u) != 0u); // s0 add + r0 = r0 + r7 + select(0x8d72d3adu, 0x63079e5au, ((sel >> 26u) & 1u) != 0u); // s1 add + r6 = r6 ^ simd_shuffle_xor(r3, (ushort)2); // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + select(0xb21b4babu, 0x5d4c7a60u, ((sel >> 31u) & 1u) != 0u); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + select(0x2fe0e98bu, 0xc88e2942u, ((sel >> 16u) & 1u) != 0u); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + r6 = r6 ^ simd_shuffle_xor(r1, (ushort)4); // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + r2 = r2 ^ simd_shuffle_xor(r6, (ushort)4); // s12 shfl + r1 = r1 + r5 + select(0xbdf8f9a5u, 0xbc48c63eu, ((sel >> 25u) & 1u) != 0u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)8); // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + select(0x45c37cecu, 0x96e8f127u, ((sel >> 1u) & 1u) != 0u); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = mulhi(r6, r0); // s28 mulhi + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)2); // s29 shfl + r1 = r1 ^ simd_shuffle_xor(r6, (ushort)1); // s30 shfl + r1 = r1 + r6 + select(0x37985632u, 0xb1cdb2abu, ((sel >> 1u) & 1u) != 0u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + r3 = r3 ^ simd_shuffle_xor(r4, (ushort)2); // s33 shfl + r0 = r0 ^ simd_shuffle_xor(r3, (ushort)4); // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + select(0x804e777eu, 0x856e0180u, ((sel >> 0u) & 1u) != 0u); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + select(0x0b06c8a7u, 0xe9bd0cc4u, ((sel >> 2u) & 1u) != 0u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = mulhi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = mulhi(r4, r3); // s44 mulhi + r6 = r6 + r7 + select(0xee822e17u, 0xcdcb63f6u, ((sel >> 12u) & 1u) != 0u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + r4 = r4 ^ simd_shuffle_xor(r3, (ushort)8); // s47 shfl + r6 = mulhi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + select(0x3dfad1b6u, 0xd4758987u, ((sel >> 10u) & 1u) != 0u); // s56 add + r4 = r4 + r1 + select(0xfca75bc2u, 0x0602d6beu, ((sel >> 0u) & 1u) != 0u); // s57 add + r5 = mulhi(r5, r6); // s58 mulhi + r2 = r2 ^ simd_shuffle_xor(r1, (ushort)2); // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + r0 = r0 ^ r5; // s64 xor + r2 = r2 ^ r7; // s65 xor + r2 = r2 + r1 + select(0xd71c02ffu, 0x8596687au, ((sel >> 6u) & 1u) != 0u); // s66 add + r1 = rotl_imm(r1, 21u); // s67 rotl + r3 = r3 * r2; // s68 mul + r7 = r7 ^ simd_shuffle_xor(r5, (ushort)2); // s69 shfl + r3 = r3 * r2; // s70 mul + r0 = r2 * r5 + r0; // s71 mad + r6 = r6 + r7 + select(0x3c6fe15du, 0x08ac5733u, ((sel >> 0u) & 1u) != 0u); // s72 add + r3 = r3 ^ simd_shuffle_xor(r2, (ushort)8); // s73 shfl + r3 = r3 * r6; // s74 mul + r6 = r6 ^ r7; // s75 xor + r3 = r3 | r0; // s76 or + r2 = r2 + r4 + select(0x295d5faeu, 0xc100b495u, ((sel >> 1u) & 1u) != 0u); // s77 add + r3 = mulhi(r3, r7); // s78 mulhi + r4 = r4 | r1; // s79 or + r4 = rotr_var(r4, r3); // s80 rotr + r4 = r4 + r3 + select(0x274a9221u, 0x5cc59530u, ((sel >> 15u) & 1u) != 0u); // s81 add + r7 = r7 + r3 + select(0xc8651f8eu, 0x141479ecu, ((sel >> 5u) & 1u) != 0u); // s82 add + r3 = rotr_var(r3, r6); // s83 rotr + r2 = r4 * r7 + r2; // s84 mad + r2 = r2 ^ simd_shuffle_xor(r5, (ushort)16); // s85 shfl + r3 = r3 ^ r2; // s86 xor + r5 = r5 ^ simd_shuffle_xor(r7, (ushort)2); // s87 shfl + r0 = r0 ^ r4; // s88 xor + r3 = r3 + r2 + select(0x53f915c2u, 0x883c0c92u, ((sel >> 18u) & 1u) != 0u); // s89 add + r7 = rotr_var(r7, r5); // s90 rotr + r3 = r3 + r1 + select(0xe2be00a5u, 0x3cc5bd20u, ((sel >> 31u) & 1u) != 0u); // s91 add + r7 = r7 ^ simd_shuffle_xor(r2, (ushort)1); // s92 shfl + r6 = rotr_var(r6, r2); // s93 rotr + r7 = rotl_imm(r7, 14u); // s94 rotl + r4 = r5 * r5 + r4; // s95 mad + r2 = r4 * r5 + r2; // s96 mad + r1 = r1 ^ r0; // s97 xor + r5 = r5 * r4; // s98 mul + r2 = r2 - r0; // s99 sub + r7 = rotl_imm(r7, 30u); // s100 rotl + r5 = r5 + r6 + select(0x423fd9c9u, 0xbfd646cbu, ((sel >> 17u) & 1u) != 0u); // s101 add + r7 = r7 + r6 + select(0x8d3c011du, 0x19b74a43u, ((sel >> 11u) & 1u) != 0u); // s102 add + r5 = rotl_imm(r5, 6u); // s103 rotl + r0 = r0 * r4; // s104 mul + r0 = r0 | r5; // s105 or + r0 = r0 + r1 + select(0x8ce14721u, 0x7dcb7e18u, ((sel >> 15u) & 1u) != 0u); // s106 add + r0 = rotl_imm(r0, 15u); // s107 rotl + r4 = r4 - r2; // s108 sub + r2 = mulhi(r2, r0); // s109 mulhi + r1 = mulhi(r1, r0); // s110 mulhi + r0 = r0 + r2 + select(0x2d9fc6b9u, 0x3c179ad8u, ((sel >> 28u) & 1u) != 0u); // s111 add + r2 = mulhi(r2, r0); // s112 mulhi + r6 = r6 - r3; // s113 sub + r7 = r6 * r3 + r7; // s114 mad + r5 = rotr_var(r5, r1); // s115 rotr + r6 = rotr_var(r6, r4); // s116 rotr + r2 = r2 + r1 + select(0x502138e2u, 0x47359729u, ((sel >> 22u) & 1u) != 0u); // s117 add + r3 = r2 * r0 + r3; // s118 mad + r1 = r1 * r3; // s119 mul + r2 = r0 * r4 + r2; // s120 mad + r0 = r0 * r3; // s121 mul + r2 = mulhi(r2, r0); // s122 mulhi + r5 = r5 * r6; // s123 mul + r4 = r2 * r4 + r4; // s124 mad + r4 = r4 ^ simd_shuffle_xor(r2, (ushort)2); // s125 shfl + r2 = r2 ^ r0; // s126 xor + r1 = rotl_imm(r1, 7u); // s127 rotl + r7 = r7 ^ simd_shuffle_xor(r2, (ushort)4); // s128 shfl + r6 = rotl_imm(r6, 17u); // s129 rotl + r2 = r2 + r5 + select(0x33dff776u, 0x6c57e4e7u, ((sel >> 15u) & 1u) != 0u); // s130 add + r0 = r0 | r3; // s131 or + r5 = rotr_var(r5, r0); // s132 rotr + r2 = r2 + r3 + select(0x5db25b34u, 0xe8212c0cu, ((sel >> 30u) & 1u) != 0u); // s133 add + r4 = r4 ^ r3; // s134 xor + r6 = r6 ^ r1; // s135 xor + r1 = r1 - r7; // s136 sub + r2 = r6 * r2 + r2; // s137 mad + r0 = mulhi(r0, r5); // s138 mulhi + r2 = r2 + r7 + select(0x218d4090u, 0xd44ff710u, ((sel >> 10u) & 1u) != 0u); // s139 add + r1 = rotr_var(r1, r4); // s140 rotr + r3 = r3 ^ simd_shuffle_xor(r6, (ushort)1); // s141 shfl + r7 = r6 * r2 + r7; // s142 mad + r2 = r2 * r3; // s143 mul + r7 = r7 + r4 + select(0xf4b1a8deu, 0xb98942fau, ((sel >> 29u) & 1u) != 0u); // s144 add + r7 = rotl_imm(r7, 15u); // s145 rotl + r7 = r7 ^ r5; // s146 xor + r4 = r7 * r4 + r4; // s147 mad + r6 = rotr_var(r6, r5); // s148 rotr + r1 = r2 * r4 + r1; // s149 mad + r1 = r1 + r7 + select(0x2bef10f2u, 0x0d48ba42u, ((sel >> 17u) & 1u) != 0u); // s150 add + r5 = r5 ^ r4; // s151 xor + r7 = r7 + r0 + select(0xdc5cc080u, 0xc98dea9cu, ((sel >> 30u) & 1u) != 0u); // s152 add + r4 = r4 * r6; // s153 mul + r0 = r0 * r2; // s154 mul + r6 = r6 ^ r5; // s155 xor + r4 = rotr_var(r4, r2); // s156 rotr + r1 = rotl_imm(r1, 11u); // s157 rotl + r5 = r5 + r0 + select(0x18197438u, 0x6c752dcbu, ((sel >> 11u) & 1u) != 0u); // s158 add + r4 = r1 * r5 + r4; // s159 mad + r4 = rotl_imm(r4, 26u); // s160 rotl + r3 = r0 * r7 + r3; // s161 mad + r3 = rotr_var(r3, r1); // s162 rotr + r4 = r4 + r0 + select(0xf1c46574u, 0x8e481727u, ((sel >> 3u) & 1u) != 0u); // s163 add + r0 = mulhi(r0, r4); // s164 mulhi + r2 = r2 + r6 + select(0xac578137u, 0x550ab406u, ((sel >> 20u) & 1u) != 0u); // s165 add + r0 = rotl_imm(r0, 13u); // s166 rotl + r3 = r3 + r1 + select(0xa33e6706u, 0xaebb5966u, ((sel >> 14u) & 1u) != 0u); // s167 add + r3 = r3 | r5; // s168 or + r6 = rotr_var(r6, r2); // s169 rotr + r4 = r4 ^ r6; // s170 xor + r6 = r6 - r1; // s171 sub + r7 = rotl_imm(r7, 22u); // s172 rotl + r5 = rotl_imm(r5, 15u); // s173 rotl + r7 = r7 ^ simd_shuffle_xor(r0, (ushort)8); // s174 shfl + r0 = r0 ^ r5; // s175 xor + r7 = rotl_imm(r7, 6u); // s176 rotl + r7 = r7 - r0; // s177 sub + r3 = rotl_imm(r3, 30u); // s178 rotl + r7 = r6 * r1 + r7; // s179 mad + r6 = rotl_imm(r6, 9u); // s180 rotl + r2 = r2 ^ r4; // s181 xor + r2 = r2 ^ r7; // s182 xor + r7 = r7 ^ r2; // s183 xor + r1 = r1 + r2 + select(0xd94d55acu, 0x5bb7550fu, ((sel >> 21u) & 1u) != 0u); // s184 add + r3 = r3 | r5; // s185 or + r6 = mulhi(r6, r3); // s186 mulhi + r4 = r4 | r0; // s187 or + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)2); // s188 shfl + r6 = r6 + r5 + select(0x89e747feu, 0x2a354e2du, ((sel >> 6u) & 1u) != 0u); // s189 add + r1 = r1 ^ r4; // s190 xor + r7 = mulhi(r7, r4); // s191 mulhi + r2 = rotl_imm(r2, 26u); // s192 rotl + r5 = rotl_imm(r5, 8u); // s193 rotl + r4 = r4 ^ simd_shuffle_xor(r5, (ushort)16); // s194 shfl + r4 = r4 ^ r5; // s195 xor + r1 = r1 * r3; // s196 mul + r5 = r5 + r2 + select(0xea03e8e7u, 0x10cfdc71u, ((sel >> 7u) & 1u) != 0u); // s197 add + r7 = r7 + r5 + select(0xa7ee0102u, 0x66e148d3u, ((sel >> 15u) & 1u) != 0u); // s198 add + r5 = r5 - r2; // s199 sub + r5 = r5 ^ simd_shuffle_xor(r1, (ushort)2); // s200 shfl + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)8); // s201 shfl + r4 = rotr_var(r4, r5); // s202 rotr + r7 = r7 ^ r5; // s203 xor + r7 = r7 ^ r0; // s204 xor + r6 = r6 + r2 + select(0x8379a4deu, 0x8558b619u, ((sel >> 10u) & 1u) != 0u); // s205 add + r4 = rotl_imm(r4, 13u); // s206 rotl + r1 = mulhi(r1, r3); // s207 mulhi + r1 = r4 * r4 + r1; // s208 mad + r2 = r2 ^ simd_shuffle_xor(r0, (ushort)4); // s209 shfl + r7 = r7 + r0 + select(0xaa8cb14eu, 0xf4049c4cu, ((sel >> 11u) & 1u) != 0u); // s210 add + r7 = r7 ^ simd_shuffle_xor(r1, (ushort)16); // s211 shfl + r1 = r1 ^ r0; // s212 xor + r7 = rotl_imm(r7, 3u); // s213 rotl + r4 = rotr_var(r4, r7); // s214 rotr + r3 = r3 ^ simd_shuffle_xor(r2, (ushort)16); // s215 shfl + r5 = r5 | r1; // s216 or + r1 = r1 - r2; // s217 sub + r6 = r6 - r5; // s218 sub + r6 = rotl_imm(r6, 4u); // s219 rotl + r2 = mulhi(r2, r0); // s220 mulhi + r2 = r2 | r0; // s221 or + r5 = r5 ^ simd_shuffle_xor(r2, (ushort)8); // s222 shfl + r5 = mulhi(r5, r6); // s223 mulhi + r0 = r0 - r6; // s224 sub + r7 = rotl_imm(r7, 23u); // s225 rotl + r4 = r4 | r2; // s226 or + r2 = r2 * r4; // s227 mul + r3 = rotl_imm(r3, 12u); // s228 rotl + r0 = rotr_var(r0, r4); // s229 rotr + r0 = r0 + r6 + select(0x1d176220u, 0x2a7fecb2u, ((sel >> 16u) & 1u) != 0u); // s230 add + r1 = r1 ^ simd_shuffle_xor(r2, (ushort)4); // s231 shfl + r2 = r2 * r1; // s232 mul + r7 = r0 * r1 + r7; // s233 mad + r5 = rotl_imm(r5, 22u); // s234 rotl + r4 = rotr_var(r4, r6); // s235 rotr + r0 = r5 * r1 + r0; // s236 mad + r6 = r6 ^ r4; // s237 xor + r4 = r4 ^ r6; // s238 xor + r6 = rotl_imm(r6, 18u); // s239 rotl + r4 = r4 + r7 + select(0x17dafb4du, 0xadce39f3u, ((sel >> 25u) & 1u) != 0u); // s240 add + r0 = r0 - r7; // s241 sub + r1 = rotr_var(r1, r6); // s242 rotr + r3 = r3 + r0 + select(0xf2f77d26u, 0x0e7033b6u, ((sel >> 29u) & 1u) != 0u); // s243 add + r2 = r7 * r4 + r2; // s244 mad + r4 = r0 * r6 + r4; // s245 mad + r5 = r5 * r7; // s246 mul + r3 = r3 + r5 + select(0xfed2da4eu, 0x7b2ff6b7u, ((sel >> 31u) & 1u) != 0u); // s247 add + r0 = r0 + r7 + select(0x03b2891cu, 0xb5fad7b1u, ((sel >> 0u) & 1u) != 0u); // s248 add + r5 = mulhi(r5, r4); // s249 mulhi + r5 = r5 + r2 + select(0x042cd6e3u, 0xa7e71c2fu, ((sel >> 11u) & 1u) != 0u); // s250 add + r6 = r6 ^ simd_shuffle_xor(r1, (ushort)1); // s251 shfl + r6 = r6 ^ r1; // s252 xor + r2 = r2 * r5; // s253 mul + r0 = r0 + r6 + select(0x784a302bu, 0xb83d78deu, ((sel >> 16u) & 1u) != 0u); // s254 add + r2 = r2 - r4; // s255 sub + } + } + uint lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((ulong)hi << 32) | (ulong)lo; +} diff --git a/proto-cuda/packs-ca3-shadow/sh256x88/vectors.h b/proto-cuda/packs-ca3-shadow/sh256x88/vectors.h new file mode 100644 index 000000000..6b2e73d7a --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x88/vectors.h @@ -0,0 +1,57 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Expected outputs: igneum-pow (Rust) CPU interpreter, generator v2, memory-hard dataset +#pragma once +#ifdef __cplusplus +#include +#else +#include +#endif + +#define IGNEUM_VEC_WARPS 3 +static const uint32_t IGNEUM_VEC_BASE[IGNEUM_VEC_WARPS] = { 0u, 4096u, 1000000u }; +static const uint64_t IGNEUM_VEC_OUT[IGNEUM_VEC_WARPS][32] = { + { // base nonce 0 + 0x84beec0429c7ef83ull, 0xf00d1a75c1983cc7ull, 0xa90bcc4907b862d3ull, 0xc4878beb87ecd1f8ull, 0xfc91443ee8482aa9ull, 0xcc6dec63ee8af2d2ull, 0x27bb87776a04a4b8ull, 0x52390b4de0bb62a9ull, + 0xccbe1f94b1b40f4full, 0x64baf9332b181a98ull, 0x397d39dc01b32f0eull, 0xa8f87eb4e8bc75deull, 0x6d941c833a2e5badull, 0xc57e923c71cfadedull, 0x6ebb7f26d71568dcull, 0x0dbdc04d57ad57e1ull, + 0xc29faa2c84db2ed7ull, 0x996c05fc549bbb92ull, 0x2fbd7656e887882dull, 0xacd8bcf4005ee812ull, 0x767be8ac588d2e38ull, 0x47ec828643046423ull, 0x4c01d7965ae941c1ull, 0x57c5c70ffbbb0e65ull, + 0x13b17316cb50fb7bull, 0x76a1f54649a370cfull, 0xad69f76836ba8a7aull, 0x733bd56efa378d81ull, 0x981c426d71f2ed8full, 0x54e1d4cbc0a62512ull, 0x67aff49ed29616c6ull, 0x334b204a4a68c30dull + }, + { // base nonce 4096 + 0x32be0f5b7d992255ull, 0x015d46bc9c3a63e5ull, 0xd484e83305387249ull, 0xbd6caf73759993a4ull, 0xa45046fe4ffea71cull, 0x998be3d8bc3b6b83ull, 0x22733e1011bb3899ull, 0xd43f643f374ec091ull, + 0x58af12ece0d06893ull, 0xc2c70d187309237dull, 0xc63a383d3e949238ull, 0x6021dfa5644f37d6ull, 0x98403c9184ee7f9aull, 0x41918aa77c615242ull, 0x4521bda069686b99ull, 0x063ad2e6be2a91b9ull, + 0xf4e60507ea9cebe7ull, 0x1af1193c38198412ull, 0xe888f6fb01c7122cull, 0x64ba2c1961141fa6ull, 0xc86cd2ac3841a269ull, 0x3488615eda9032dfull, 0xdf7cd491843ee85cull, 0x6661e8614d9e6c8bull, + 0x3cf20cd75714f0c0ull, 0xc494aa0916c00aefull, 0x659a06ca296e221cull, 0x55641c3a74d4078aull, 0xb4c4cde4ab6c19e2ull, 0xeeb96f46b670a71full, 0x2876607f7e2ea1c3ull, 0x2c8dbd443403bc84ull + }, + { // base nonce 1000000 + 0x78541813d6547a59ull, 0x4048c2a56e0aeb32ull, 0xdde4ab04573bd691ull, 0x2efd693c76d79f20ull, 0xf2c68f0fe9a342d3ull, 0x35da60ca90cbe845ull, 0x36798fb3123a26c0ull, 0x0d889aeaaec59a84ull, + 0xe2a0581848e9bc0bull, 0xed7a2887d34e286aull, 0x7f933c3acbcae9d4ull, 0x11be5af68c3a8bd2ull, 0xee163f620d49e2daull, 0xa959ae35321ed248ull, 0xecbbfca1292bdaccull, 0x7ce337105114c1c4ull, + 0xc73aafe51ed8fde3ull, 0x760fdbb27982fcbdull, 0xb9b573c20dc494c2ull, 0x55f9c2d1ef8cc32dull, 0x2af4bfeea1c32c93ull, 0x3fe179c0b56193aeull, 0x92bff7aaec5b772full, 0x80271a03ee19287cull, + 0x4b98c3ac7191efc4ull, 0xe36245f5d990f94bull, 0x2f7c0ed899091a02ull, 0xfbf09b3a6f2fb8dbull, 0x07ff9acffccbf012ull, 0xdcd9727fe482d3e3ull, 0xcae6d467f721bb31ull, 0xfd7fb2e05bbc316full + } +}; + +// Dataset self-test: dataset[0..15] and dataset[IGNEUM_MASK] (268435455). +static const uint32_t IGNEUM_DS_HEAD[16] = { + 0xfdad4319u, 0x1a7b68e1u, 0xde6db608u, 0x13d73892u, 0xd17f447au, 0xb2221ccfu, 0x9db004bdu, 0x57d7d367u, + 0xdbc4cf34u, 0x697c009au, 0xc43af1d4u, 0x97f12b2eu, 0x74c37cd0u, 0xc651ea15u, 0x665a6d29u, 0x22330a2du +}; +static const uint32_t IGNEUM_DS_LAST_INDEX = 268435455u; +static const uint32_t IGNEUM_DS_LAST = 0xa83e7aa6u; +// 64 sampled dataset words (index, value) computed on the Mac. +#define IGNEUM_DS_SAMPLES 64 +static const uint32_t IGNEUM_DS_SAMPLE_INDEX[IGNEUM_DS_SAMPLES] = { + 59471966u, 217795994u, 208353206u, 42483309u, 172547758u, 148076330u, 183853158u, 214389424u, 267488061u, 169781097u, 184093494u, 153880993u, 84977930u, 46426879u, 3093825u, 225364072u, 44593546u, 260713159u, 168250303u, 52384140u, 223401610u, 45554030u, 95410555u, 175039924u, 79171087u, 267580473u, 24168642u, 37981670u, 171551130u, 195559979u, 204611762u, 140997658u, 138925853u, 86637313u, 20736778u, 219665210u, 160430336u, 264654675u, 8013395u, 228945585u, 213884386u, 104419827u, 44185464u, 142737231u, 99284897u, 132475900u, 61861762u, 132056166u, 262388043u, 91878046u, 117353561u, 124768597u, 71352993u, 190698941u, 46055428u, 55281366u, 165145231u, 106810753u, 171985651u, 232085256u, 159510492u, 40072060u, 209107596u, 39023794u +}; +static const uint32_t IGNEUM_DS_SAMPLE_VALUE[IGNEUM_DS_SAMPLES] = { + 0x3230bc7bu, 0x7fbfe2c9u, 0xb2690991u, 0x1745c7c5u, 0x0ab0ccafu, 0x1bf87d6bu, 0x160139fdu, 0x719817acu, 0x0155df4bu, 0xbe1e86c3u, 0x680bcd6cu, 0x79c3dc6cu, 0x181e7e5fu, 0x0713a109u, 0xc705dd9fu, 0x3933b7a8u, 0xdd1c0431u, 0x50522b30u, 0xa0020b38u, 0xbff39e96u, 0x21b67e18u, 0x740f8db3u, 0x2baba568u, 0x2c9bef83u, 0x0ad9b671u, 0xc4327869u, 0x7b4fd7d0u, 0x2c29965fu, 0xec56f15fu, 0x61111746u, 0x303a1d6eu, 0xbddcfd1au, 0xf829a355u, 0x6d5df2a9u, 0x01ab8e44u, 0x06d13507u, 0xda8dcfc6u, 0x01a703e1u, 0xafe7d2c1u, 0xc091c3a2u, 0xac1814feu, 0x6e6ff62au, 0x8fdf01bau, 0xdd3f7159u, 0xdfa0d75cu, 0x26684c35u, 0x7f441e63u, 0x88df2570u, 0x8aa4d5ebu, 0xcc816c05u, 0x434df890u, 0xcd392ad6u, 0x1ab4cb63u, 0x595926fau, 0x7cd76b41u, 0x20cb95c4u, 0x13cf823fu, 0xf9daf901u, 0xff9af40au, 0x2c7dfa51u, 0x871206dbu, 0x938c116cu, 0xb64bf199u, 0x5751f874u +}; +// Cache self-test (memory-hard mode): cache[0..15], the last 16 words, and FNV-1a 64 over all 2^26 words. +static const uint32_t IGNEUM_CACHE_HEAD[16] = { + 0x355a86d2u, 0x7957db1cu, 0xd21772afu, 0x6fc1e09bu, 0xd55ce61du, 0x6e6a278bu, 0xd3f543ceu, 0x223d8e82u, + 0x143ab337u, 0x2e9f05bdu, 0x2eb389bfu, 0x0c6e449eu, 0x5cfa4222u, 0xba6560feu, 0x8e3e1aa4u, 0xdbcc1d53u +}; +static const uint32_t IGNEUM_CACHE_LAST[16] = { + 0x41190d91u, 0xbd277957u, 0x22ddbb49u, 0x6986f207u, 0xdf69a4d6u, 0x26401a3au, 0x818230fbu, 0xc417122du, + 0x3597b211u, 0xb553ce55u, 0xcf39cc0du, 0x3b7fc43au, 0x3fd43b00u, 0x67e1c80eu, 0xffa7ea7du, 0xca2960abu +}; +static const uint64_t IGNEUM_CACHE_FNV64 = 0x48c4f5bf24166b2eull; diff --git a/proto-cuda/packs-ca3-shadow/sh256x88/vectors.json b/proto-cuda/packs-ca3-shadow/sh256x88/vectors.json new file mode 100644 index 000000000..e8fe6391a --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh256x88/vectors.json @@ -0,0 +1,36 @@ +{ + "seed": "igneum-genesis", + "day": "2026-10-03", + "dataset_mode": "memory-hard", + "dataset_log2_words": 28, + "mask": "0x0fffffff", + "lanes": 32, + "source": "igneum-pow (Rust) CPU interpreter, generator v2, memory-hard dataset", + "warps": [ + {"base_nonce": 0, "expected": [ + "0x84beec0429c7ef83", "0xf00d1a75c1983cc7", "0xa90bcc4907b862d3", "0xc4878beb87ecd1f8", "0xfc91443ee8482aa9", "0xcc6dec63ee8af2d2", "0x27bb87776a04a4b8", "0x52390b4de0bb62a9", + "0xccbe1f94b1b40f4f", "0x64baf9332b181a98", "0x397d39dc01b32f0e", "0xa8f87eb4e8bc75de", "0x6d941c833a2e5bad", "0xc57e923c71cfaded", "0x6ebb7f26d71568dc", "0x0dbdc04d57ad57e1", + "0xc29faa2c84db2ed7", "0x996c05fc549bbb92", "0x2fbd7656e887882d", "0xacd8bcf4005ee812", "0x767be8ac588d2e38", "0x47ec828643046423", "0x4c01d7965ae941c1", "0x57c5c70ffbbb0e65", + "0x13b17316cb50fb7b", "0x76a1f54649a370cf", "0xad69f76836ba8a7a", "0x733bd56efa378d81", "0x981c426d71f2ed8f", "0x54e1d4cbc0a62512", "0x67aff49ed29616c6", "0x334b204a4a68c30d" + ]}, + {"base_nonce": 4096, "expected": [ + "0x32be0f5b7d992255", "0x015d46bc9c3a63e5", "0xd484e83305387249", "0xbd6caf73759993a4", "0xa45046fe4ffea71c", "0x998be3d8bc3b6b83", "0x22733e1011bb3899", "0xd43f643f374ec091", + "0x58af12ece0d06893", "0xc2c70d187309237d", "0xc63a383d3e949238", "0x6021dfa5644f37d6", "0x98403c9184ee7f9a", "0x41918aa77c615242", "0x4521bda069686b99", "0x063ad2e6be2a91b9", + "0xf4e60507ea9cebe7", "0x1af1193c38198412", "0xe888f6fb01c7122c", "0x64ba2c1961141fa6", "0xc86cd2ac3841a269", "0x3488615eda9032df", "0xdf7cd491843ee85c", "0x6661e8614d9e6c8b", + "0x3cf20cd75714f0c0", "0xc494aa0916c00aef", "0x659a06ca296e221c", "0x55641c3a74d4078a", "0xb4c4cde4ab6c19e2", "0xeeb96f46b670a71f", "0x2876607f7e2ea1c3", "0x2c8dbd443403bc84" + ]}, + {"base_nonce": 1000000, "expected": [ + "0x78541813d6547a59", "0x4048c2a56e0aeb32", "0xdde4ab04573bd691", "0x2efd693c76d79f20", "0xf2c68f0fe9a342d3", "0x35da60ca90cbe845", "0x36798fb3123a26c0", "0x0d889aeaaec59a84", + "0xe2a0581848e9bc0b", "0xed7a2887d34e286a", "0x7f933c3acbcae9d4", "0x11be5af68c3a8bd2", "0xee163f620d49e2da", "0xa959ae35321ed248", "0xecbbfca1292bdacc", "0x7ce337105114c1c4", + "0xc73aafe51ed8fde3", "0x760fdbb27982fcbd", "0xb9b573c20dc494c2", "0x55f9c2d1ef8cc32d", "0x2af4bfeea1c32c93", "0x3fe179c0b56193ae", "0x92bff7aaec5b772f", "0x80271a03ee19287c", + "0x4b98c3ac7191efc4", "0xe36245f5d990f94b", "0x2f7c0ed899091a02", "0xfbf09b3a6f2fb8db", "0x07ff9acffccbf012", "0xdcd9727fe482d3e3", "0xcae6d467f721bb31", "0xfd7fb2e05bbc316f" + ]} + ], + "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" +} diff --git a/proto-cuda/packs-ca3-shadow/sh64x52/kernel.cl b/proto-cuda/packs-ca3-shadow/sh64x52/kernel.cl new file mode 100644 index 000000000..40b5475e2 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh64x52/kernel.cl @@ -0,0 +1,346 @@ +// 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 ^ 0x67a9a7beu; x += 0x9e3779b9u; x = splitmix32(x); r0 = x ^ 0x1a155b25u; } // SEEDW[0], 0x9e3779b9u * 1u, SEEDW[1] + { uint x = nonce ^ 0x1a155b25u; x += 0x3c6ef372u; x = splitmix32(x); r1 = x ^ 0xfddfb732u; } // SEEDW[1], 0x9e3779b9u * 2u, SEEDW[2] + { uint x = nonce ^ 0xfddfb732u; x += 0xdaa66d2bu; x = splitmix32(x); r2 = x ^ 0x4b5af2e8u; } // SEEDW[2], 0x9e3779b9u * 3u, SEEDW[3] + { uint x = nonce ^ 0x4b5af2e8u; x += 0x78dde6e4u; x = splitmix32(x); r3 = x ^ 0xc55caf33u; } // SEEDW[3], 0x9e3779b9u * 4u, SEEDW[4] + { uint x = nonce ^ 0xc55caf33u; x += 0x1715609du; x = splitmix32(x); r4 = x ^ 0xa27c13b7u; } // SEEDW[4], 0x9e3779b9u * 5u, SEEDW[5] + { uint x = nonce ^ 0xa27c13b7u; x += 0xb54cda56u; x = splitmix32(x); r5 = x ^ 0x06628a48u; } // SEEDW[5], 0x9e3779b9u * 6u, SEEDW[6] + { uint x = nonce ^ 0x06628a48u; x += 0x5384540fu; x = splitmix32(x); r6 = x ^ 0x03852469u; } // SEEDW[6], 0x9e3779b9u * 7u, SEEDW[7] + { uint x = nonce ^ 0x03852469u; x += 0xf1bbcdc8u; x = splitmix32(x); r7 = x ^ 0x67a9a7beu; } // SEEDW[7], 0x9e3779b9u * 8u, SEEDW[0] + + for (uint it = 0u; it < 8u; ++it) { + uint sel = r0; + r2 = r3 * r4 + r2; // 0 mad + r2 = r1 * r1 + r2; // 1 mad + r2 = r3 * r2 + r2; // 2 mad + r3 = r3 ^ r5; // 3 xor + r7 = r7 ^ ds[r2 & mask]; // 4 load + r5 = r5 ^ ds[r7 & mask]; // 5 load + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r1 = r1 ^ t_; } // 6 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r7 = r7 ^ t_; } // 7 shfl + r1 = mul_hi(r1, r5); // 8 mulhi + r6 = rotr_var(r6, r3); // 9 rotr + r3 = r3 | r4; // 10 or + r4 = r4 ^ ds[r3 & mask]; // 11 load + r0 = mul_hi(r0, r4); // 12 mulhi + r5 = r5 + r1 + ((((sel >> 30u) & 1u) != 0u) ? 0xd3177981u : 0xc7934706u); // 13 add + r0 = r0 ^ ds[r4 & mask]; // 14 load + r2 = r2 - r4; // 15 sub + r2 = r2 ^ ds[r0 & mask]; // 16 load + r7 = r7 ^ ds[r2 & mask]; // 17 load + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r7 = r7 ^ t_; } // 18 shfl + r5 = r5 * r0; // 19 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // 20 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 16u); r2 = r2 ^ t_; } // 21 shfl + r6 = mul_hi(r6, r2); // 22 mulhi + r6 = r6 ^ ds[r1 & mask]; // 23 load + r5 = r5 * r0; // 24 mul + r5 = rotl_imm(r5, 19u); // 25 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 2u); r7 = r7 ^ t_; } // 26 shfl + r0 = r0 ^ r5; // 27 xor + r0 = r0 ^ r4; // 28 xor + r3 = r3 - r0; // 29 sub + r5 = r5 * r1; // 30 mul + r7 = r7 ^ ds[r2 & mask]; // 31 load + r1 = r1 ^ ds[r0 & mask]; // 32 load + r5 = r5 ^ r6; // 33 xor + r5 = r5 ^ ds[r1 & mask]; // 34 load + r0 = mul_hi(r0, r5); // 35 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r5 = r5 ^ t_; } // 36 shfl + r7 = r7 ^ ds[r0 & mask]; // 37 load + r3 = r3 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0x230c005cu : 0x75ba2fadu); // 38 add + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 4u); r1 = r1 ^ t_; } // 39 shfl + r2 = r2 ^ r5; // 40 xor + r3 = r6 * r3 + r3; // 41 mad + r6 = r6 - r7; // 42 sub + r7 = r7 ^ r0; // 43 xor + r1 = r1 ^ ds[r7 & mask]; // 44 load + r2 = r2 * r3; // 45 mul + r1 = mul_hi(r1, r5); // 46 mulhi + r4 = r4 - r3; // 47 sub + r2 = rotr_var(r2, r6); // 48 rotr + r3 = r3 ^ ds[r5 & mask]; // 49 load + r1 = r1 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x1907970cu : 0x81b8bc2cu); // 50 add + r0 = r0 * r2; // 51 mul + r0 = r0 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x699fd448u : 0x4f92b968u); // 52 add + r1 = r1 + r0 + ((((sel >> 12u) & 1u) != 0u) ? 0x77b1520du : 0x2bb965afu); // 53 add + r7 = rotl_imm(r7, 14u); // 54 rotl + r3 = r3 + r7 + ((((sel >> 1u) & 1u) != 0u) ? 0xa54c55a0u : 0x7b0fe07au); // 55 add + r6 = r6 ^ ds[r7 & mask]; // 56 load + r1 = rotr_var(r1, r5); // 57 rotr + r5 = r5 ^ ds[r4 & mask]; // 58 load + r6 = r6 ^ ds[r2 & mask]; // 59 load + r3 = r5 * r0 + r3; // 60 mad + r5 = r5 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0xad7493e7u : 0xaf9dd72du); // 61 add + r4 = r4 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x1e07c3d9u : 0x89841d87u); // 62 add + r5 = rotl_imm(r5, 19u); // 63 rotl + // latency-shadow block (Counter ASIC 3.0 item 8): 64 ALU instructions x 52 passes after instruction 63, no load + for (uint sh = 0u; sh < 52u; ++sh) { + r5 = r5 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x8bc12da9u : 0x92199f99u); // s0 add + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x63079e5au : 0x8d72d3adu); // s1 add + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 2u); r6 = r6 ^ t_; } // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + ((((sel >> 31u) & 1u) != 0u) ? 0x5d4c7a60u : 0xb21b4babu); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + ((((sel >> 16u) & 1u) != 0u) ? 0xc88e2942u : 0x2fe0e98bu); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r6 = r6 ^ t_; } // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 4u); r2 = r2 ^ t_; } // s12 shfl + r1 = r1 + r5 + ((((sel >> 25u) & 1u) != 0u) ? 0xbc48c63eu : 0xbdf8f9a5u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r2 = r2 ^ t_; } // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + ((((sel >> 1u) & 1u) != 0u) ? 0x96e8f127u : 0x45c37cecu); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = mul_hi(r6, r0); // s28 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r2 = r2 ^ t_; } // s29 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r1 = r1 ^ t_; } // s30 shfl + r1 = r1 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0xb1cdb2abu : 0x37985632u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // s33 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r0 = r0 ^ t_; } // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x856e0180u : 0x804e777eu); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xe9bd0cc4u : 0x0b06c8a7u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = mul_hi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = mul_hi(r4, r3); // s44 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xcdcb63f6u : 0xee822e17u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r4 = r4 ^ t_; } // s47 shfl + r6 = mul_hi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0xd4758987u : 0x3dfad1b6u); // s56 add + r4 = r4 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x0602d6beu : 0xfca75bc2u); // s57 add + r5 = mul_hi(r5, r6); // s58 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r2 = r2 ^ t_; } // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + } + } + uint lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((ulong)hi << 32) | (ulong)lo; +} + +#if IGNEUM_EXCHANGE != 0 +// Reports the sub-group size this device uses for a work-group of IGNEUM_GROUP items. host.c runs it only when the +// per-kernel query (clGetKernelSubGroupInfoKHR on igneum_hash) is unavailable; that query is preferred because a +// compiler may pick a different wave width per kernel (RDNA: wave32 or wave64). See WAVEFRONT.md. +IGNEUM_KERNEL_HASH void igneum_probe_subgroup(__global uint* out) { + if (get_local_id(0) == 0u) { out[0] = get_sub_group_size(); out[1] = get_num_sub_groups(); } +} +#endif diff --git a/proto-cuda/packs-ca3-shadow/sh64x52/kernel.cu b/proto-cuda/packs-ca3-shadow/sh64x52/kernel.cu new file mode 100644 index 000000000..9ee835a60 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh64x52/kernel.cu @@ -0,0 +1,231 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Bit-exact twin of the Metal kernel for the same seed (see proto-cuda/CHECKLIST.md and program.metal). +// Compiled ahead of time by nvcc together with proto-cuda/host.cu. No NVRTC. +#include +#include +#include "program.h" +#include "memhard.h" + +__device__ __forceinline__ uint32_t splitmix32(uint32_t x) { + x ^= x >> 16; x *= 0x7feb352du; + x ^= x >> 15; x *= 0x846ca68bu; + x ^= x >> 16; + return x; +} +// n is a literal in 1..31 at every call site, so both shift amounts are in 1..31. +__device__ __forceinline__ uint32_t rotl_imm(uint32_t x, uint32_t n) { return (x << n) | (x >> (32u - n)); } +// n is masked to 0..31; the second shift amount is masked too, so n == 0 gives x. +__device__ __forceinline__ uint32_t rotr_var(uint32_t x, uint32_t n) { n &= 31u; return (x >> n) | (x << ((32u - n) & 31u)); } +__device__ __forceinline__ uint32_t ds_elem(uint32_t i, uint32_t d0, uint32_t d1) { + uint32_t x = i ^ d0; + x *= 0x9E3779B1u; x ^= x >> 15; + x += d1; + x *= 0x85EBCA77u; x ^= x >> 13; + x *= 0xC2B2AE3Du; x ^= x >> 16; + return x; +} + +// Memory-hard dataset (MEMHARD.md). One thread per cache segment; one thread per 64-byte dataset item. +// The core functions (mh_cache_segment, mh_item) are in memhard.h and are also compiled for the host. +__global__ void igneum_cache_fill(uint32_t* cache, uint32_t nSegments) { + uint32_t seg = blockIdx.x * blockDim.x + threadIdx.x; + if (seg < nSegments) mh_cache_segment(cache, seg); +} +__global__ void igneum_build(uint32_t* ds, const uint32_t* cache, uint32_t nItems) { + uint32_t t = blockIdx.x * blockDim.x + threadIdx.x; + if (t < nItems) { + uint32_t s[16]; + mh_item(cache, t, s); + uint32_t* d = ds + (size_t)t * 16u; + for (uint32_t i = 0u; i < 16u; ++i) d[i] = s[i]; + } +} + +// One hash per thread. blockDim.x is a multiple of 32; lane = threadIdx.x & 31 and every +// __shfl_xor_sync stays inside the lane's own warp, exactly like simd_shuffle_xor inside a +// 32-wide Metal SIMD group. Control flow is uniform, so the full 0xffffffff member mask is valid. +__global__ void igneum_hash(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask) { + uint32_t gid = blockIdx.x * blockDim.x + threadIdx.x; + uint32_t nonce = baseNonce + gid; + uint32_t r0, r1, r2, r3, r4, r5, r6, r7; + { uint32_t x = nonce ^ 0x67a9a7beu; x += 0x9e3779b9u; x = splitmix32(x); r0 = x ^ 0x1a155b25u; } // SEEDW[0], 0x9e3779b9u * 1u, SEEDW[1] + { uint32_t x = nonce ^ 0x1a155b25u; x += 0x3c6ef372u; x = splitmix32(x); r1 = x ^ 0xfddfb732u; } // SEEDW[1], 0x9e3779b9u * 2u, SEEDW[2] + { uint32_t x = nonce ^ 0xfddfb732u; x += 0xdaa66d2bu; x = splitmix32(x); r2 = x ^ 0x4b5af2e8u; } // SEEDW[2], 0x9e3779b9u * 3u, SEEDW[3] + { uint32_t x = nonce ^ 0x4b5af2e8u; x += 0x78dde6e4u; x = splitmix32(x); r3 = x ^ 0xc55caf33u; } // SEEDW[3], 0x9e3779b9u * 4u, SEEDW[4] + { uint32_t x = nonce ^ 0xc55caf33u; x += 0x1715609du; x = splitmix32(x); r4 = x ^ 0xa27c13b7u; } // SEEDW[4], 0x9e3779b9u * 5u, SEEDW[5] + { uint32_t x = nonce ^ 0xa27c13b7u; x += 0xb54cda56u; x = splitmix32(x); r5 = x ^ 0x06628a48u; } // SEEDW[5], 0x9e3779b9u * 6u, SEEDW[6] + { uint32_t x = nonce ^ 0x06628a48u; x += 0x5384540fu; x = splitmix32(x); r6 = x ^ 0x03852469u; } // SEEDW[6], 0x9e3779b9u * 7u, SEEDW[7] + { uint32_t x = nonce ^ 0x03852469u; x += 0xf1bbcdc8u; x = splitmix32(x); r7 = x ^ 0x67a9a7beu; } // SEEDW[7], 0x9e3779b9u * 8u, SEEDW[0] + + for (uint32_t it = 0u; it < 8u; ++it) { + uint32_t sel = r0; + r2 = r3 * r4 + r2; // 0 mad + r2 = r1 * r1 + r2; // 1 mad + r2 = r3 * r2 + r2; // 2 mad + r3 = r3 ^ r5; // 3 xor + r7 = r7 ^ ds[r2 & mask]; // 4 load + r5 = r5 ^ ds[r7 & mask]; // 5 load + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r4, 8); // 6 shfl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r3, 8); // 7 shfl + r1 = __umulhi(r1, r5); // 8 mulhi + r6 = rotr_var(r6, r3); // 9 rotr + r3 = r3 | r4; // 10 or + r4 = r4 ^ ds[r3 & mask]; // 11 load + r0 = __umulhi(r0, r4); // 12 mulhi + r5 = r5 + r1 + ((((sel >> 30u) & 1u) != 0u) ? 0xd3177981u : 0xc7934706u); // 13 add + r0 = r0 ^ ds[r4 & mask]; // 14 load + r2 = r2 - r4; // 15 sub + r2 = r2 ^ ds[r0 & mask]; // 16 load + r7 = r7 ^ ds[r2 & mask]; // 17 load + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r3, 4); // 18 shfl + r5 = r5 * r0; // 19 mul + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // 20 shfl + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 16); // 21 shfl + r6 = __umulhi(r6, r2); // 22 mulhi + r6 = r6 ^ ds[r1 & mask]; // 23 load + r5 = r5 * r0; // 24 mul + r5 = rotl_imm(r5, 19u); // 25 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r6, 2); // 26 shfl + r0 = r0 ^ r5; // 27 xor + r0 = r0 ^ r4; // 28 xor + r3 = r3 - r0; // 29 sub + r5 = r5 * r1; // 30 mul + r7 = r7 ^ ds[r2 & mask]; // 31 load + r1 = r1 ^ ds[r0 & mask]; // 32 load + r5 = r5 ^ r6; // 33 xor + r5 = r5 ^ ds[r1 & mask]; // 34 load + r0 = __umulhi(r0, r5); // 35 mulhi + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // 36 shfl + r7 = r7 ^ ds[r0 & mask]; // 37 load + r3 = r3 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0x230c005cu : 0x75ba2fadu); // 38 add + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r5, 4); // 39 shfl + r2 = r2 ^ r5; // 40 xor + r3 = r6 * r3 + r3; // 41 mad + r6 = r6 - r7; // 42 sub + r7 = r7 ^ r0; // 43 xor + r1 = r1 ^ ds[r7 & mask]; // 44 load + r2 = r2 * r3; // 45 mul + r1 = __umulhi(r1, r5); // 46 mulhi + r4 = r4 - r3; // 47 sub + r2 = rotr_var(r2, r6); // 48 rotr + r3 = r3 ^ ds[r5 & mask]; // 49 load + r1 = r1 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x1907970cu : 0x81b8bc2cu); // 50 add + r0 = r0 * r2; // 51 mul + r0 = r0 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x699fd448u : 0x4f92b968u); // 52 add + r1 = r1 + r0 + ((((sel >> 12u) & 1u) != 0u) ? 0x77b1520du : 0x2bb965afu); // 53 add + r7 = rotl_imm(r7, 14u); // 54 rotl + r3 = r3 + r7 + ((((sel >> 1u) & 1u) != 0u) ? 0xa54c55a0u : 0x7b0fe07au); // 55 add + r6 = r6 ^ ds[r7 & mask]; // 56 load + r1 = rotr_var(r1, r5); // 57 rotr + r5 = r5 ^ ds[r4 & mask]; // 58 load + r6 = r6 ^ ds[r2 & mask]; // 59 load + r3 = r5 * r0 + r3; // 60 mad + r5 = r5 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0xad7493e7u : 0xaf9dd72du); // 61 add + r4 = r4 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x1e07c3d9u : 0x89841d87u); // 62 add + r5 = rotl_imm(r5, 19u); // 63 rotl + // latency-shadow block (Counter ASIC 3.0 item 8): 64 ALU instructions x 52 passes after instruction 63, no load + for (uint32_t sh = 0u; sh < 52u; ++sh) { + r5 = r5 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x8bc12da9u : 0x92199f99u); // s0 add + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x63079e5au : 0x8d72d3adu); // s1 add + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r3, 2); // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + ((((sel >> 31u) & 1u) != 0u) ? 0x5d4c7a60u : 0xb21b4babu); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + ((((sel >> 16u) & 1u) != 0u) ? 0xc88e2942u : 0x2fe0e98bu); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r1, 4); // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r6, 4); // s12 shfl + r1 = r1 + r5 + ((((sel >> 25u) & 1u) != 0u) ? 0xbc48c63eu : 0xbdf8f9a5u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 8); // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + ((((sel >> 1u) & 1u) != 0u) ? 0x96e8f127u : 0x45c37cecu); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = __umulhi(r6, r0); // s28 mulhi + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // s29 shfl + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r6, 1); // s30 shfl + r1 = r1 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0xb1cdb2abu : 0x37985632u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // s33 shfl + r0 = r0 ^ __shfl_xor_sync(0xffffffffu, r3, 4); // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x856e0180u : 0x804e777eu); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xe9bd0cc4u : 0x0b06c8a7u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = __umulhi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = __umulhi(r4, r3); // s44 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xcdcb63f6u : 0xee822e17u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r3, 8); // s47 shfl + r6 = __umulhi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0xd4758987u : 0x3dfad1b6u); // s56 add + r4 = r4 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x0602d6beu : 0xfca75bc2u); // s57 add + r5 = __umulhi(r5, r6); // s58 mulhi + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + } + } + uint32_t lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint32_t hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((uint64_t)hi << 32) | (uint64_t)lo; +} + +// Host-side launch wrappers. Declared in program.h, called from host.cu. +cudaError_t igneum_launch_cache_fill(uint32_t* cache, uint32_t nSegments) { + if (nSegments == 0u) return cudaErrorInvalidValue; + uint32_t block = 256u; + uint32_t grid = (nSegments + block - 1u) / block; + igneum_cache_fill<<>>(cache, nSegments); + return cudaGetLastError(); +} + +cudaError_t igneum_launch_build(uint32_t* ds, const uint32_t* cache, uint32_t nItems) { + if (nItems == 0u) return cudaErrorInvalidValue; + uint32_t block = 256u; + uint32_t grid = (nItems + block - 1u) / block; + igneum_build<<>>(ds, cache, nItems); + return cudaGetLastError(); +} + +cudaError_t igneum_launch_hash(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, + uint32_t nonces, uint32_t blockWarps) { + if (blockWarps == 0u || blockWarps > 32u) return cudaErrorInvalidValue; + uint32_t block = 32u * blockWarps; + if (nonces == 0u || (nonces % block) != 0u) return cudaErrorInvalidValue; + igneum_hash<<>>(ds, out, baseNonce, mask); + return cudaGetLastError(); +} + +cudaError_t igneum_hash_info(int* numRegs, int* blocksPerSM, uint32_t blockWarps) { + cudaFuncAttributes attr; + cudaError_t e = cudaFuncGetAttributes(&attr, igneum_hash); + if (e != cudaSuccess) return e; + *numRegs = attr.numRegs; + return cudaOccupancyMaxActiveBlocksPerMultiprocessor(blocksPerSM, igneum_hash, (int)(32u * blockWarps), 0); +} diff --git a/proto-cuda/packs-ca3-shadow/sh64x52/kernel_bound.cl b/proto-cuda/packs-ca3-shadow/sh64x52/kernel_bound.cl new file mode 100644 index 000000000..1729c7990 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh64x52/kernel_bound.cl @@ -0,0 +1,507 @@ +// 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 ^ 0x67a9a7beu; x += 0x9e3779b9u; x = splitmix32(x); r0 = x ^ 0x1a155b25u; } // SEEDW[0], 0x9e3779b9u * 1u, SEEDW[1] + { uint x = nonce ^ 0x1a155b25u; x += 0x3c6ef372u; x = splitmix32(x); r1 = x ^ 0xfddfb732u; } // SEEDW[1], 0x9e3779b9u * 2u, SEEDW[2] + { uint x = nonce ^ 0xfddfb732u; x += 0xdaa66d2bu; x = splitmix32(x); r2 = x ^ 0x4b5af2e8u; } // SEEDW[2], 0x9e3779b9u * 3u, SEEDW[3] + { uint x = nonce ^ 0x4b5af2e8u; x += 0x78dde6e4u; x = splitmix32(x); r3 = x ^ 0xc55caf33u; } // SEEDW[3], 0x9e3779b9u * 4u, SEEDW[4] + { uint x = nonce ^ 0xc55caf33u; x += 0x1715609du; x = splitmix32(x); r4 = x ^ 0xa27c13b7u; } // SEEDW[4], 0x9e3779b9u * 5u, SEEDW[5] + { uint x = nonce ^ 0xa27c13b7u; x += 0xb54cda56u; x = splitmix32(x); r5 = x ^ 0x06628a48u; } // SEEDW[5], 0x9e3779b9u * 6u, SEEDW[6] + { uint x = nonce ^ 0x06628a48u; x += 0x5384540fu; x = splitmix32(x); r6 = x ^ 0x03852469u; } // SEEDW[6], 0x9e3779b9u * 7u, SEEDW[7] + { uint x = nonce ^ 0x03852469u; x += 0xf1bbcdc8u; x = splitmix32(x); r7 = x ^ 0x67a9a7beu; } // SEEDW[7], 0x9e3779b9u * 8u, SEEDW[0] + + for (uint it = 0u; it < 8u; ++it) { + uint sel = r0; + r2 = r3 * r4 + r2; // 0 mad + r2 = r1 * r1 + r2; // 1 mad + r2 = r3 * r2 + r2; // 2 mad + r3 = r3 ^ r5; // 3 xor + r7 = r7 ^ ds[r2 & mask]; // 4 load + r5 = r5 ^ ds[r7 & mask]; // 5 load + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r1 = r1 ^ t_; } // 6 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r7 = r7 ^ t_; } // 7 shfl + r1 = mul_hi(r1, r5); // 8 mulhi + r6 = rotr_var(r6, r3); // 9 rotr + r3 = r3 | r4; // 10 or + r4 = r4 ^ ds[r3 & mask]; // 11 load + r0 = mul_hi(r0, r4); // 12 mulhi + r5 = r5 + r1 + ((((sel >> 30u) & 1u) != 0u) ? 0xd3177981u : 0xc7934706u); // 13 add + r0 = r0 ^ ds[r4 & mask]; // 14 load + r2 = r2 - r4; // 15 sub + r2 = r2 ^ ds[r0 & mask]; // 16 load + r7 = r7 ^ ds[r2 & mask]; // 17 load + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r7 = r7 ^ t_; } // 18 shfl + r5 = r5 * r0; // 19 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // 20 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 16u); r2 = r2 ^ t_; } // 21 shfl + r6 = mul_hi(r6, r2); // 22 mulhi + r6 = r6 ^ ds[r1 & mask]; // 23 load + r5 = r5 * r0; // 24 mul + r5 = rotl_imm(r5, 19u); // 25 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 2u); r7 = r7 ^ t_; } // 26 shfl + r0 = r0 ^ r5; // 27 xor + r0 = r0 ^ r4; // 28 xor + r3 = r3 - r0; // 29 sub + r5 = r5 * r1; // 30 mul + r7 = r7 ^ ds[r2 & mask]; // 31 load + r1 = r1 ^ ds[r0 & mask]; // 32 load + r5 = r5 ^ r6; // 33 xor + r5 = r5 ^ ds[r1 & mask]; // 34 load + r0 = mul_hi(r0, r5); // 35 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r5 = r5 ^ t_; } // 36 shfl + r7 = r7 ^ ds[r0 & mask]; // 37 load + r3 = r3 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0x230c005cu : 0x75ba2fadu); // 38 add + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 4u); r1 = r1 ^ t_; } // 39 shfl + r2 = r2 ^ r5; // 40 xor + r3 = r6 * r3 + r3; // 41 mad + r6 = r6 - r7; // 42 sub + r7 = r7 ^ r0; // 43 xor + r1 = r1 ^ ds[r7 & mask]; // 44 load + r2 = r2 * r3; // 45 mul + r1 = mul_hi(r1, r5); // 46 mulhi + r4 = r4 - r3; // 47 sub + r2 = rotr_var(r2, r6); // 48 rotr + r3 = r3 ^ ds[r5 & mask]; // 49 load + r1 = r1 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x1907970cu : 0x81b8bc2cu); // 50 add + r0 = r0 * r2; // 51 mul + r0 = r0 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x699fd448u : 0x4f92b968u); // 52 add + r1 = r1 + r0 + ((((sel >> 12u) & 1u) != 0u) ? 0x77b1520du : 0x2bb965afu); // 53 add + r7 = rotl_imm(r7, 14u); // 54 rotl + r3 = r3 + r7 + ((((sel >> 1u) & 1u) != 0u) ? 0xa54c55a0u : 0x7b0fe07au); // 55 add + r6 = r6 ^ ds[r7 & mask]; // 56 load + r1 = rotr_var(r1, r5); // 57 rotr + r5 = r5 ^ ds[r4 & mask]; // 58 load + r6 = r6 ^ ds[r2 & mask]; // 59 load + r3 = r5 * r0 + r3; // 60 mad + r5 = r5 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0xad7493e7u : 0xaf9dd72du); // 61 add + r4 = r4 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x1e07c3d9u : 0x89841d87u); // 62 add + r5 = rotl_imm(r5, 19u); // 63 rotl + // latency-shadow block (Counter ASIC 3.0 item 8): 64 ALU instructions x 52 passes after instruction 63, no load + for (uint sh = 0u; sh < 52u; ++sh) { + r5 = r5 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x8bc12da9u : 0x92199f99u); // s0 add + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x63079e5au : 0x8d72d3adu); // s1 add + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 2u); r6 = r6 ^ t_; } // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + ((((sel >> 31u) & 1u) != 0u) ? 0x5d4c7a60u : 0xb21b4babu); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + ((((sel >> 16u) & 1u) != 0u) ? 0xc88e2942u : 0x2fe0e98bu); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r6 = r6 ^ t_; } // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 4u); r2 = r2 ^ t_; } // s12 shfl + r1 = r1 + r5 + ((((sel >> 25u) & 1u) != 0u) ? 0xbc48c63eu : 0xbdf8f9a5u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r2 = r2 ^ t_; } // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + ((((sel >> 1u) & 1u) != 0u) ? 0x96e8f127u : 0x45c37cecu); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = mul_hi(r6, r0); // s28 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r2 = r2 ^ t_; } // s29 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r1 = r1 ^ t_; } // s30 shfl + r1 = r1 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0xb1cdb2abu : 0x37985632u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // s33 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r0 = r0 ^ t_; } // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x856e0180u : 0x804e777eu); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xe9bd0cc4u : 0x0b06c8a7u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = mul_hi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = mul_hi(r4, r3); // s44 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xcdcb63f6u : 0xee822e17u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r4 = r4 ^ t_; } // s47 shfl + r6 = mul_hi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0xd4758987u : 0x3dfad1b6u); // s56 add + r4 = r4 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x0602d6beu : 0xfca75bc2u); // s57 add + r5 = mul_hi(r5, r6); // s58 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r2 = r2 ^ t_; } // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + } + } + 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 = r3 * r4 + r2; // 0 mad + r2 = r1 * r1 + r2; // 1 mad + r2 = r3 * r2 + r2; // 2 mad + r3 = r3 ^ r5; // 3 xor + r7 = r7 ^ ds[r2 & mask]; // 4 load + r5 = r5 ^ ds[r7 & mask]; // 5 load + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r1 = r1 ^ t_; } // 6 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r7 = r7 ^ t_; } // 7 shfl + r1 = mul_hi(r1, r5); // 8 mulhi + r6 = rotr_var(r6, r3); // 9 rotr + r3 = r3 | r4; // 10 or + r4 = r4 ^ ds[r3 & mask]; // 11 load + r0 = mul_hi(r0, r4); // 12 mulhi + r5 = r5 + r1 + ((((sel >> 30u) & 1u) != 0u) ? 0xd3177981u : 0xc7934706u); // 13 add + r0 = r0 ^ ds[r4 & mask]; // 14 load + r2 = r2 - r4; // 15 sub + r2 = r2 ^ ds[r0 & mask]; // 16 load + r7 = r7 ^ ds[r2 & mask]; // 17 load + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r7 = r7 ^ t_; } // 18 shfl + r5 = r5 * r0; // 19 mul + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // 20 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 16u); r2 = r2 ^ t_; } // 21 shfl + r6 = mul_hi(r6, r2); // 22 mulhi + r6 = r6 ^ ds[r1 & mask]; // 23 load + r5 = r5 * r0; // 24 mul + r5 = rotl_imm(r5, 19u); // 25 rotl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 2u); r7 = r7 ^ t_; } // 26 shfl + r0 = r0 ^ r5; // 27 xor + r0 = r0 ^ r4; // 28 xor + r3 = r3 - r0; // 29 sub + r5 = r5 * r1; // 30 mul + r7 = r7 ^ ds[r2 & mask]; // 31 load + r1 = r1 ^ ds[r0 & mask]; // 32 load + r5 = r5 ^ r6; // 33 xor + r5 = r5 ^ ds[r1 & mask]; // 34 load + r0 = mul_hi(r0, r5); // 35 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r2, 4u); r5 = r5 ^ t_; } // 36 shfl + r7 = r7 ^ ds[r0 & mask]; // 37 load + r3 = r3 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0x230c005cu : 0x75ba2fadu); // 38 add + { uint t_; IGNEUM_SHFL_XOR(t_, r5, 4u); r1 = r1 ^ t_; } // 39 shfl + r2 = r2 ^ r5; // 40 xor + r3 = r6 * r3 + r3; // 41 mad + r6 = r6 - r7; // 42 sub + r7 = r7 ^ r0; // 43 xor + r1 = r1 ^ ds[r7 & mask]; // 44 load + r2 = r2 * r3; // 45 mul + r1 = mul_hi(r1, r5); // 46 mulhi + r4 = r4 - r3; // 47 sub + r2 = rotr_var(r2, r6); // 48 rotr + r3 = r3 ^ ds[r5 & mask]; // 49 load + r1 = r1 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x1907970cu : 0x81b8bc2cu); // 50 add + r0 = r0 * r2; // 51 mul + r0 = r0 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x699fd448u : 0x4f92b968u); // 52 add + r1 = r1 + r0 + ((((sel >> 12u) & 1u) != 0u) ? 0x77b1520du : 0x2bb965afu); // 53 add + r7 = rotl_imm(r7, 14u); // 54 rotl + r3 = r3 + r7 + ((((sel >> 1u) & 1u) != 0u) ? 0xa54c55a0u : 0x7b0fe07au); // 55 add + r6 = r6 ^ ds[r7 & mask]; // 56 load + r1 = rotr_var(r1, r5); // 57 rotr + r5 = r5 ^ ds[r4 & mask]; // 58 load + r6 = r6 ^ ds[r2 & mask]; // 59 load + r3 = r5 * r0 + r3; // 60 mad + r5 = r5 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0xad7493e7u : 0xaf9dd72du); // 61 add + r4 = r4 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x1e07c3d9u : 0x89841d87u); // 62 add + r5 = rotl_imm(r5, 19u); // 63 rotl + // latency-shadow block (Counter ASIC 3.0 item 8): 64 ALU instructions x 52 passes after instruction 63, no load + for (uint sh = 0u; sh < 52u; ++sh) { + r5 = r5 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x8bc12da9u : 0x92199f99u); // s0 add + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x63079e5au : 0x8d72d3adu); // s1 add + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 2u); r6 = r6 ^ t_; } // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + ((((sel >> 31u) & 1u) != 0u) ? 0x5d4c7a60u : 0xb21b4babu); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + ((((sel >> 16u) & 1u) != 0u) ? 0xc88e2942u : 0x2fe0e98bu); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 4u); r6 = r6 ^ t_; } // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 4u); r2 = r2 ^ t_; } // s12 shfl + r1 = r1 + r5 + ((((sel >> 25u) & 1u) != 0u) ? 0xbc48c63eu : 0xbdf8f9a5u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 8u); r2 = r2 ^ t_; } // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + ((((sel >> 1u) & 1u) != 0u) ? 0x96e8f127u : 0x45c37cecu); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = mul_hi(r6, r0); // s28 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r2 = r2 ^ t_; } // s29 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r6, 1u); r1 = r1 ^ t_; } // s30 shfl + r1 = r1 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0xb1cdb2abu : 0x37985632u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + { uint t_; IGNEUM_SHFL_XOR(t_, r4, 2u); r3 = r3 ^ t_; } // s33 shfl + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 4u); r0 = r0 ^ t_; } // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x856e0180u : 0x804e777eu); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xe9bd0cc4u : 0x0b06c8a7u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = mul_hi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = mul_hi(r4, r3); // s44 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xcdcb63f6u : 0xee822e17u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + { uint t_; IGNEUM_SHFL_XOR(t_, r3, 8u); r4 = r4 ^ t_; } // s47 shfl + r6 = mul_hi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0xd4758987u : 0x3dfad1b6u); // s56 add + r4 = r4 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x0602d6beu : 0xfca75bc2u); // s57 add + r5 = mul_hi(r5, r6); // s58 mulhi + { uint t_; IGNEUM_SHFL_XOR(t_, r1, 2u); r2 = r2 ^ t_; } // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + } + } + uint lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((ulong)hi << 32) | (ulong)lo; +} diff --git a/proto-cuda/packs-ca3-shadow/sh64x52/kernel_bound.cu b/proto-cuda/packs-ca3-shadow/sh64x52/kernel_bound.cu new file mode 100644 index 000000000..f88d73367 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh64x52/kernel_bound.cu @@ -0,0 +1,190 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Header-bound twin of igneum_hash in kernel.cu: the init words come from a kernel argument, not SEEDW. +// Host declarations (also in program_bound.h if present): +// struct IgneumInitWords { uint32_t w[8]; }; +// cudaError_t igneum_launch_hash_bound(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, +// IgneumInitWords iw, uint32_t nonces, uint32_t blockWarps); +// cudaError_t igneum_hash_bound_info(int* numRegs, int* blocksPerSM, uint32_t blockWarps); +#include +#include +#include "program.h" + +struct IgneumInitWords { uint32_t w[8]; }; + +__device__ __forceinline__ uint32_t splitmix32(uint32_t x) { + x ^= x >> 16; x *= 0x7feb352du; + x ^= x >> 15; x *= 0x846ca68bu; + x ^= x >> 16; + return x; +} +__device__ __forceinline__ uint32_t rotl_imm(uint32_t x, uint32_t n) { return (x << n) | (x >> (32u - n)); } +__device__ __forceinline__ uint32_t rotr_var(uint32_t x, uint32_t n) { n &= 31u; return (x >> n) | (x << ((32u - n) & 31u)); } + +__global__ void igneum_hash_bound(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, IgneumInitWords iw) { + uint32_t gid = blockIdx.x * blockDim.x + threadIdx.x; + uint32_t nonce = baseNonce + gid; + uint32_t r0, r1, r2, r3, r4, r5, r6, r7; + { uint32_t x = nonce ^ iw.w[0]; x += 0x9e3779b9u * 1u; x = splitmix32(x); r0 = x ^ iw.w[1]; } + { uint32_t x = nonce ^ iw.w[1]; x += 0x9e3779b9u * 2u; x = splitmix32(x); r1 = x ^ iw.w[2]; } + { uint32_t x = nonce ^ iw.w[2]; x += 0x9e3779b9u * 3u; x = splitmix32(x); r2 = x ^ iw.w[3]; } + { uint32_t x = nonce ^ iw.w[3]; x += 0x9e3779b9u * 4u; x = splitmix32(x); r3 = x ^ iw.w[4]; } + { uint32_t x = nonce ^ iw.w[4]; x += 0x9e3779b9u * 5u; x = splitmix32(x); r4 = x ^ iw.w[5]; } + { uint32_t x = nonce ^ iw.w[5]; x += 0x9e3779b9u * 6u; x = splitmix32(x); r5 = x ^ iw.w[6]; } + { uint32_t x = nonce ^ iw.w[6]; x += 0x9e3779b9u * 7u; x = splitmix32(x); r6 = x ^ iw.w[7]; } + { uint32_t x = nonce ^ iw.w[7]; x += 0x9e3779b9u * 8u; x = splitmix32(x); r7 = x ^ iw.w[0]; } + + for (uint32_t it = 0u; it < 8u; ++it) { + uint32_t sel = r0; + r2 = r3 * r4 + r2; // 0 mad + r2 = r1 * r1 + r2; // 1 mad + r2 = r3 * r2 + r2; // 2 mad + r3 = r3 ^ r5; // 3 xor + r7 = r7 ^ ds[r2 & mask]; // 4 load + r5 = r5 ^ ds[r7 & mask]; // 5 load + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r4, 8); // 6 shfl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r3, 8); // 7 shfl + r1 = __umulhi(r1, r5); // 8 mulhi + r6 = rotr_var(r6, r3); // 9 rotr + r3 = r3 | r4; // 10 or + r4 = r4 ^ ds[r3 & mask]; // 11 load + r0 = __umulhi(r0, r4); // 12 mulhi + r5 = r5 + r1 + ((((sel >> 30u) & 1u) != 0u) ? 0xd3177981u : 0xc7934706u); // 13 add + r0 = r0 ^ ds[r4 & mask]; // 14 load + r2 = r2 - r4; // 15 sub + r2 = r2 ^ ds[r0 & mask]; // 16 load + r7 = r7 ^ ds[r2 & mask]; // 17 load + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r3, 4); // 18 shfl + r5 = r5 * r0; // 19 mul + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // 20 shfl + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 16); // 21 shfl + r6 = __umulhi(r6, r2); // 22 mulhi + r6 = r6 ^ ds[r1 & mask]; // 23 load + r5 = r5 * r0; // 24 mul + r5 = rotl_imm(r5, 19u); // 25 rotl + r7 = r7 ^ __shfl_xor_sync(0xffffffffu, r6, 2); // 26 shfl + r0 = r0 ^ r5; // 27 xor + r0 = r0 ^ r4; // 28 xor + r3 = r3 - r0; // 29 sub + r5 = r5 * r1; // 30 mul + r7 = r7 ^ ds[r2 & mask]; // 31 load + r1 = r1 ^ ds[r0 & mask]; // 32 load + r5 = r5 ^ r6; // 33 xor + r5 = r5 ^ ds[r1 & mask]; // 34 load + r0 = __umulhi(r0, r5); // 35 mulhi + r5 = r5 ^ __shfl_xor_sync(0xffffffffu, r2, 4); // 36 shfl + r7 = r7 ^ ds[r0 & mask]; // 37 load + r3 = r3 + r1 + ((((sel >> 27u) & 1u) != 0u) ? 0x230c005cu : 0x75ba2fadu); // 38 add + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r5, 4); // 39 shfl + r2 = r2 ^ r5; // 40 xor + r3 = r6 * r3 + r3; // 41 mad + r6 = r6 - r7; // 42 sub + r7 = r7 ^ r0; // 43 xor + r1 = r1 ^ ds[r7 & mask]; // 44 load + r2 = r2 * r3; // 45 mul + r1 = __umulhi(r1, r5); // 46 mulhi + r4 = r4 - r3; // 47 sub + r2 = rotr_var(r2, r6); // 48 rotr + r3 = r3 ^ ds[r5 & mask]; // 49 load + r1 = r1 + r5 + ((((sel >> 7u) & 1u) != 0u) ? 0x1907970cu : 0x81b8bc2cu); // 50 add + r0 = r0 * r2; // 51 mul + r0 = r0 + r2 + ((((sel >> 6u) & 1u) != 0u) ? 0x699fd448u : 0x4f92b968u); // 52 add + r1 = r1 + r0 + ((((sel >> 12u) & 1u) != 0u) ? 0x77b1520du : 0x2bb965afu); // 53 add + r7 = rotl_imm(r7, 14u); // 54 rotl + r3 = r3 + r7 + ((((sel >> 1u) & 1u) != 0u) ? 0xa54c55a0u : 0x7b0fe07au); // 55 add + r6 = r6 ^ ds[r7 & mask]; // 56 load + r1 = rotr_var(r1, r5); // 57 rotr + r5 = r5 ^ ds[r4 & mask]; // 58 load + r6 = r6 ^ ds[r2 & mask]; // 59 load + r3 = r5 * r0 + r3; // 60 mad + r5 = r5 + r7 + ((((sel >> 31u) & 1u) != 0u) ? 0xad7493e7u : 0xaf9dd72du); // 61 add + r4 = r4 + r6 + ((((sel >> 27u) & 1u) != 0u) ? 0x1e07c3d9u : 0x89841d87u); // 62 add + r5 = rotl_imm(r5, 19u); // 63 rotl + // latency-shadow block (Counter ASIC 3.0 item 8): 64 ALU instructions x 52 passes after instruction 63, no load + for (uint32_t sh = 0u; sh < 52u; ++sh) { + r5 = r5 + r2 + ((((sel >> 18u) & 1u) != 0u) ? 0x8bc12da9u : 0x92199f99u); // s0 add + r0 = r0 + r7 + ((((sel >> 26u) & 1u) != 0u) ? 0x63079e5au : 0x8d72d3adu); // s1 add + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r3, 2); // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + ((((sel >> 31u) & 1u) != 0u) ? 0x5d4c7a60u : 0xb21b4babu); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + ((((sel >> 16u) & 1u) != 0u) ? 0xc88e2942u : 0x2fe0e98bu); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + r6 = r6 ^ __shfl_xor_sync(0xffffffffu, r1, 4); // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r6, 4); // s12 shfl + r1 = r1 + r5 + ((((sel >> 25u) & 1u) != 0u) ? 0xbc48c63eu : 0xbdf8f9a5u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 8); // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + ((((sel >> 1u) & 1u) != 0u) ? 0x96e8f127u : 0x45c37cecu); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = __umulhi(r6, r0); // s28 mulhi + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // s29 shfl + r1 = r1 ^ __shfl_xor_sync(0xffffffffu, r6, 1); // s30 shfl + r1 = r1 + r6 + ((((sel >> 1u) & 1u) != 0u) ? 0xb1cdb2abu : 0x37985632u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + r3 = r3 ^ __shfl_xor_sync(0xffffffffu, r4, 2); // s33 shfl + r0 = r0 ^ __shfl_xor_sync(0xffffffffu, r3, 4); // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x856e0180u : 0x804e777eu); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + ((((sel >> 2u) & 1u) != 0u) ? 0xe9bd0cc4u : 0x0b06c8a7u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = __umulhi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = __umulhi(r4, r3); // s44 mulhi + r6 = r6 + r7 + ((((sel >> 12u) & 1u) != 0u) ? 0xcdcb63f6u : 0xee822e17u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + r4 = r4 ^ __shfl_xor_sync(0xffffffffu, r3, 8); // s47 shfl + r6 = __umulhi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + ((((sel >> 10u) & 1u) != 0u) ? 0xd4758987u : 0x3dfad1b6u); // s56 add + r4 = r4 + r1 + ((((sel >> 0u) & 1u) != 0u) ? 0x0602d6beu : 0xfca75bc2u); // s57 add + r5 = __umulhi(r5, r6); // s58 mulhi + r2 = r2 ^ __shfl_xor_sync(0xffffffffu, r1, 2); // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + } + } + uint32_t lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint32_t hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((uint64_t)hi << 32) | (uint64_t)lo; +} + +cudaError_t igneum_launch_hash_bound(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, + IgneumInitWords iw, uint32_t nonces, uint32_t blockWarps) { + if (blockWarps == 0u || blockWarps > 32u) return cudaErrorInvalidValue; + uint32_t block = 32u * blockWarps; + if (nonces == 0u || (nonces % block) != 0u) return cudaErrorInvalidValue; + igneum_hash_bound<<>>(ds, out, baseNonce, mask, iw); + return cudaGetLastError(); +} + +cudaError_t igneum_hash_bound_info(int* numRegs, int* blocksPerSM, uint32_t blockWarps) { + cudaFuncAttributes attr; + cudaError_t e = cudaFuncGetAttributes(&attr, igneum_hash_bound); + if (e != cudaSuccess) return e; + *numRegs = attr.numRegs; + return cudaOccupancyMaxActiveBlocksPerMultiprocessor(blocksPerSM, igneum_hash_bound, (int)(32u * blockWarps), 0); +} diff --git a/proto-cuda/packs-ca3-shadow/sh64x52/memhard.h b/proto-cuda/packs-ca3-shadow/sh64x52/memhard.h new file mode 100644 index 000000000..f7f34c732 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh64x52/memhard.h @@ -0,0 +1,109 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Memory-hard dataset core, the same text that the Mac's Metal kernels and CPU verifier were checked against. +// Included by kernel.cu (device), host.cu (host reference) and proto-opencl/host.c (C99 host reference). +// See proto-metal/MEMHARD.md for the construction. kernel.cl carries the same text in OpenCL C. +#pragma once +#ifdef __cplusplus +#include +#else +#include +#endif +#if defined(__CUDACC__) +#define IGNEUM_HD __host__ __device__ __forceinline__ +#elif defined(_MSC_VER) && !defined(__cplusplus) +#define IGNEUM_HD static __inline +#else +#define IGNEUM_HD static inline +#endif +// Memory-hard dataset core (MEMHARD.md). Cache: 2^26 words in 2^16 segments of 64 chained ChaCha12 lines. +// Item: 8 rounds of 8 x seed-parameterised mixer + one 64-byte cache read, then 8 x final mixer (class v3, mixer multiplier 8, +// docs/plans/mixer-x4.md: the round key of application j of round r is 0x9E3779B9 * (r * m + j + 1)). All parameters are literals. +#define MH_CACHE_LINE_MASK 0x003fffffu +#define MH_SEGMENT_LINES 64u +#define MH_QR(a, b, c, d, r1, r2, r3, r4) { a += b; d ^= a; d = mh_rotl(d, r1); c += d; b ^= c; b = mh_rotl(b, r2); a += b; d ^= a; d = mh_rotl(d, r3); c += d; b ^= c; b = mh_rotl(b, r4); } +IGNEUM_HD uint32_t mh_rotl(uint32_t x, uint32_t n) { return (x << n) | (x >> (32u - n)); } // n in 1..31 at every call site + +// y = ChaCha12 core(x) + x +IGNEUM_HD void mh_chacha_block(const uint32_t* x, uint32_t* y) { + for (uint32_t i = 0u; i < 16u; ++i) y[i] = x[i]; + for (uint32_t r = 0u; r < 6u; ++r) { + MH_QR(y[0], y[4], y[8], y[12], 16u, 12u, 8u, 7u) MH_QR(y[1], y[5], y[9], y[13], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[6], y[10], y[14], 16u, 12u, 8u, 7u) MH_QR(y[3], y[7], y[11], y[15], 16u, 12u, 8u, 7u) + MH_QR(y[0], y[5], y[10], y[15], 16u, 12u, 8u, 7u) MH_QR(y[1], y[6], y[11], y[12], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[7], y[8], y[13], 16u, 12u, 8u, 7u) MH_QR(y[3], y[4], y[9], y[14], 16u, 12u, 8u, 7u) + } + for (uint32_t i = 0u; i < 16u; ++i) y[i] += x[i]; +} + +// One cache segment: 64 chained lines written at cache[seg * 1024]. in_j = prev ^ (sigma || K || seg || j || tag), prev_0 = 0. +IGNEUM_HD void mh_cache_segment(uint32_t* cache, uint32_t seg) { + uint32_t prev[16]; uint32_t x[16]; uint32_t y[16]; + for (uint32_t i = 0u; i < 16u; ++i) prev[i] = 0u; + for (uint32_t j = 0u; j < MH_SEGMENT_LINES; ++j) { + x[0] = 0x61707865u ^ prev[0]; x[1] = 0x3320646eu ^ prev[1]; x[2] = 0x79622d32u ^ prev[2]; x[3] = 0x6b206574u ^ prev[3]; + x[4] = 0x3067619fu ^ prev[4]; + x[5] = 0x3c269176u ^ prev[5]; + x[6] = 0x84a03b03u ^ prev[6]; + x[7] = 0xf8c63294u ^ prev[7]; + x[8] = 0xff977c5bu ^ prev[8]; + x[9] = 0xe60def3eu ^ prev[9]; + x[10] = 0x63630141u ^ prev[10]; + x[11] = 0xb8fbcb58u ^ prev[11]; + x[12] = seg ^ prev[12]; x[13] = j ^ prev[13]; x[14] = 0x49676e65u ^ prev[14]; x[15] = 0x756d4d48u ^ prev[15]; + mh_chacha_block(x, y); + uint32_t* line = cache + ((seg * MH_SEGMENT_LINES + j) * 16u); + for (uint32_t i = 0u; i < 16u; ++i) { line[i] = y[i]; prev[i] = y[i]; } + } +} + +// M_r: per word (s ^ (RC + rk)) * MUL, then a column round and a diagonal round with the seed-drawn rotations. +IGNEUM_HD void mh_mixer(uint32_t* s, uint32_t rk) { + s[0] = (s[0] ^ (0xbab68293u + rk)) * 0x42146205u; + s[1] = (s[1] ^ (0xcc162340u + rk)) * 0x52cbe0fbu; + s[2] = (s[2] ^ (0x6ce151ccu + rk)) * 0x7ecf4a03u; + s[3] = (s[3] ^ (0xe62b8997u + rk)) * 0x6728907fu; + s[4] = (s[4] ^ (0xc9c80297u + rk)) * 0xd81d9751u; + s[5] = (s[5] ^ (0xf74a1654u + rk)) * 0x132952c3u; + s[6] = (s[6] ^ (0x3d704af5u + rk)) * 0xf60de277u; + s[7] = (s[7] ^ (0x3cf522b7u + rk)) * 0x05358035u; + s[8] = (s[8] ^ (0x2b9cac04u + rk)) * 0xbaf6499du; + s[9] = (s[9] ^ (0xa880ac10u + rk)) * 0xe4db9667u; + s[10] = (s[10] ^ (0x13e5dd1du + rk)) * 0x3e98f45du; + s[11] = (s[11] ^ (0x6fc3e233u + rk)) * 0xd0004eddu; + s[12] = (s[12] ^ (0x2d83eeacu + rk)) * 0x2691630du; + s[13] = (s[13] ^ (0x9006e8bfu + rk)) * 0x9beb3bcfu; + s[14] = (s[14] ^ (0x2c4b5362u + rk)) * 0xab310379u; + s[15] = (s[15] ^ (0x31b49ee2u + rk)) * 0x99cfb423u; + MH_QR(s[0], s[4], s[8], s[12], 20u, 20u, 19u, 4u) MH_QR(s[1], s[5], s[9], s[13], 20u, 20u, 19u, 4u) + MH_QR(s[2], s[6], s[10], s[14], 20u, 20u, 19u, 4u) MH_QR(s[3], s[7], s[11], s[15], 20u, 20u, 19u, 4u) + MH_QR(s[0], s[5], s[10], s[15], 26u, 3u, 3u, 27u) MH_QR(s[1], s[6], s[11], s[12], 26u, 3u, 3u, 27u) + MH_QR(s[2], s[7], s[8], s[13], 26u, 3u, 3u, 27u) MH_QR(s[3], s[4], s[9], s[14], 26u, 3u, 3u, 27u) +} + +// Item t: 16 words. s = (K, t * MUL[i] + RC[i]); 8 rounds of 8 x mixer + cache line s[0] & mask; 8 x final mixer. +IGNEUM_HD void mh_item(const uint32_t* cache, uint32_t t, uint32_t* s) { + s[0] = 0x3067619fu; + s[1] = 0x3c269176u; + s[2] = 0x84a03b03u; + s[3] = 0xf8c63294u; + s[4] = 0xff977c5bu; + s[5] = 0xe60def3eu; + s[6] = 0x63630141u; + s[7] = 0xb8fbcb58u; + s[8] = t * 0x42146205u + 0xbab68293u; + s[9] = t * 0x52cbe0fbu + 0xcc162340u; + s[10] = t * 0x7ecf4a03u + 0x6ce151ccu; + s[11] = t * 0x6728907fu + 0xe62b8997u; + s[12] = t * 0xd81d9751u + 0xc9c80297u; + s[13] = t * 0x132952c3u + 0xf74a1654u; + s[14] = t * 0xf60de277u + 0x3d704af5u; + s[15] = t * 0x05358035u + 0x3cf522b7u; + for (uint32_t r = 0u; r < 8u; ++r) { + for (uint32_t j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (r * 8u + j + 1u)); + const uint32_t* line = cache + ((s[0] & MH_CACHE_LINE_MASK) * 16u); + for (uint32_t i = 0u; i < 16u; ++i) s[i] ^= line[i]; + } + for (uint32_t j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (64u + j + 1u)); +} +// dataset[w] without the dataset: derive item w >> 4 and take word w & 15. +IGNEUM_HD uint32_t mh_word(const uint32_t* cache, uint32_t w) { uint32_t s[16]; mh_item(cache, w >> 4u, s); return s[w & 15u]; } diff --git a/proto-cuda/packs-ca3-shadow/sh64x52/memhard.metal b/proto-cuda/packs-ca3-shadow/sh64x52/memhard.metal new file mode 100644 index 000000000..01b263d6d --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh64x52/memhard.metal @@ -0,0 +1,107 @@ +#include +using namespace metal; +// Memory-hard dataset core (MEMHARD.md). Cache: 2^26 words in 2^16 segments of 64 chained ChaCha12 lines. +// Item: 8 rounds of 8 x seed-parameterised mixer + one 64-byte cache read, then 8 x final mixer (class v3, mixer multiplier 8, +// docs/plans/mixer-x4.md: the round key of application j of round r is 0x9E3779B9 * (r * m + j + 1)). All parameters are literals. +#define MH_CACHE_LINE_MASK 0x003fffffu +#define MH_SEGMENT_LINES 64u +#define MH_QR(a, b, c, d, r1, r2, r3, r4) { a += b; d ^= a; d = mh_rotl(d, r1); c += d; b ^= c; b = mh_rotl(b, r2); a += b; d ^= a; d = mh_rotl(d, r3); c += d; b ^= c; b = mh_rotl(b, r4); } +inline uint mh_rotl(uint x, uint n) { return (x << n) | (x >> (32u - n)); } // n in 1..31 at every call site + +// y = ChaCha12 core(x) + x +inline void mh_chacha_block(const thread uint* x, thread uint* y) { + for (uint i = 0u; i < 16u; ++i) y[i] = x[i]; + for (uint r = 0u; r < 6u; ++r) { + MH_QR(y[0], y[4], y[8], y[12], 16u, 12u, 8u, 7u) MH_QR(y[1], y[5], y[9], y[13], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[6], y[10], y[14], 16u, 12u, 8u, 7u) MH_QR(y[3], y[7], y[11], y[15], 16u, 12u, 8u, 7u) + MH_QR(y[0], y[5], y[10], y[15], 16u, 12u, 8u, 7u) MH_QR(y[1], y[6], y[11], y[12], 16u, 12u, 8u, 7u) + MH_QR(y[2], y[7], y[8], y[13], 16u, 12u, 8u, 7u) MH_QR(y[3], y[4], y[9], y[14], 16u, 12u, 8u, 7u) + } + for (uint i = 0u; i < 16u; ++i) y[i] += x[i]; +} + +// One cache segment: 64 chained lines written at cache[seg * 1024]. in_j = prev ^ (sigma || K || seg || j || tag), prev_0 = 0. +inline void mh_cache_segment(device uint* cache, uint seg) { + uint prev[16]; uint x[16]; uint y[16]; + for (uint i = 0u; i < 16u; ++i) prev[i] = 0u; + for (uint j = 0u; j < MH_SEGMENT_LINES; ++j) { + x[0] = 0x61707865u ^ prev[0]; x[1] = 0x3320646eu ^ prev[1]; x[2] = 0x79622d32u ^ prev[2]; x[3] = 0x6b206574u ^ prev[3]; + x[4] = 0x3067619fu ^ prev[4]; + x[5] = 0x3c269176u ^ prev[5]; + x[6] = 0x84a03b03u ^ prev[6]; + x[7] = 0xf8c63294u ^ prev[7]; + x[8] = 0xff977c5bu ^ prev[8]; + x[9] = 0xe60def3eu ^ prev[9]; + x[10] = 0x63630141u ^ prev[10]; + x[11] = 0xb8fbcb58u ^ prev[11]; + x[12] = seg ^ prev[12]; x[13] = j ^ prev[13]; x[14] = 0x49676e65u ^ prev[14]; x[15] = 0x756d4d48u ^ prev[15]; + mh_chacha_block(x, y); + device uint* line = cache + ((seg * MH_SEGMENT_LINES + j) * 16u); + for (uint i = 0u; i < 16u; ++i) { line[i] = y[i]; prev[i] = y[i]; } + } +} + +// M_r: per word (s ^ (RC + rk)) * MUL, then a column round and a diagonal round with the seed-drawn rotations. +inline void mh_mixer(thread uint* s, uint rk) { + s[0] = (s[0] ^ (0xbab68293u + rk)) * 0x42146205u; + s[1] = (s[1] ^ (0xcc162340u + rk)) * 0x52cbe0fbu; + s[2] = (s[2] ^ (0x6ce151ccu + rk)) * 0x7ecf4a03u; + s[3] = (s[3] ^ (0xe62b8997u + rk)) * 0x6728907fu; + s[4] = (s[4] ^ (0xc9c80297u + rk)) * 0xd81d9751u; + s[5] = (s[5] ^ (0xf74a1654u + rk)) * 0x132952c3u; + s[6] = (s[6] ^ (0x3d704af5u + rk)) * 0xf60de277u; + s[7] = (s[7] ^ (0x3cf522b7u + rk)) * 0x05358035u; + s[8] = (s[8] ^ (0x2b9cac04u + rk)) * 0xbaf6499du; + s[9] = (s[9] ^ (0xa880ac10u + rk)) * 0xe4db9667u; + s[10] = (s[10] ^ (0x13e5dd1du + rk)) * 0x3e98f45du; + s[11] = (s[11] ^ (0x6fc3e233u + rk)) * 0xd0004eddu; + s[12] = (s[12] ^ (0x2d83eeacu + rk)) * 0x2691630du; + s[13] = (s[13] ^ (0x9006e8bfu + rk)) * 0x9beb3bcfu; + s[14] = (s[14] ^ (0x2c4b5362u + rk)) * 0xab310379u; + s[15] = (s[15] ^ (0x31b49ee2u + rk)) * 0x99cfb423u; + MH_QR(s[0], s[4], s[8], s[12], 20u, 20u, 19u, 4u) MH_QR(s[1], s[5], s[9], s[13], 20u, 20u, 19u, 4u) + MH_QR(s[2], s[6], s[10], s[14], 20u, 20u, 19u, 4u) MH_QR(s[3], s[7], s[11], s[15], 20u, 20u, 19u, 4u) + MH_QR(s[0], s[5], s[10], s[15], 26u, 3u, 3u, 27u) MH_QR(s[1], s[6], s[11], s[12], 26u, 3u, 3u, 27u) + MH_QR(s[2], s[7], s[8], s[13], 26u, 3u, 3u, 27u) MH_QR(s[3], s[4], s[9], s[14], 26u, 3u, 3u, 27u) +} + +// Item t: 16 words. s = (K, t * MUL[i] + RC[i]); 8 rounds of 8 x mixer + cache line s[0] & mask; 8 x final mixer. +inline void mh_item(device const uint* cache, uint t, thread uint* s) { + s[0] = 0x3067619fu; + s[1] = 0x3c269176u; + s[2] = 0x84a03b03u; + s[3] = 0xf8c63294u; + s[4] = 0xff977c5bu; + s[5] = 0xe60def3eu; + s[6] = 0x63630141u; + s[7] = 0xb8fbcb58u; + s[8] = t * 0x42146205u + 0xbab68293u; + s[9] = t * 0x52cbe0fbu + 0xcc162340u; + s[10] = t * 0x7ecf4a03u + 0x6ce151ccu; + s[11] = t * 0x6728907fu + 0xe62b8997u; + s[12] = t * 0xd81d9751u + 0xc9c80297u; + s[13] = t * 0x132952c3u + 0xf74a1654u; + s[14] = t * 0xf60de277u + 0x3d704af5u; + s[15] = t * 0x05358035u + 0x3cf522b7u; + for (uint r = 0u; r < 8u; ++r) { + for (uint j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (r * 8u + j + 1u)); + device const uint* line = cache + ((s[0] & MH_CACHE_LINE_MASK) * 16u); + for (uint i = 0u; i < 16u; ++i) s[i] ^= line[i]; + } + for (uint j = 0u; j < 8u; ++j) mh_mixer(s, 0x9E3779B9u * (64u + j + 1u)); +} +// dataset[w] without the dataset: derive item w >> 4 and take word w & 15. +inline uint mh_word(device const uint* cache, uint w) { uint s[16]; mh_item(cache, w >> 4u, s); return s[w & 15u]; } + +// One thread per segment (2^16 threads). +kernel void igneum_cache_fill(device uint* cache [[buffer(0)]], uint gid [[thread_position_in_grid]]) { + mh_cache_segment(cache, gid); +} +// One thread per 64-byte item (dataset words / 16 threads). +kernel void igneum_build(device const uint* cache [[buffer(0)]], device uint* dataset [[buffer(1)]], + uint gid [[thread_position_in_grid]]) { + uint s[16]; + mh_item(cache, gid, s); + device uint* d = dataset + gid * 16u; + for (uint i = 0u; i < 16u; ++i) d[i] = s[i]; +} diff --git a/proto-cuda/packs-ca3-shadow/sh64x52/program.h b/proto-cuda/packs-ca3-shadow/sh64x52/program.h new file mode 100644 index 000000000..5831b966f --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh64x52/program.h @@ -0,0 +1,70 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Program metadata for host.cu plus the launch wrappers defined in kernel.cu. +// Also included by proto-opencl/host.c (C99), which defines IGNEUM_NO_CUDA first and reads only the macros. +#pragma once +#ifdef __cplusplus +#include +#else +#include +#endif +#ifndef IGNEUM_NO_CUDA +#include +#endif + +#define IGNEUM_SEED_STRING "igneum-genesis" +#define IGNEUM_SEED_BYTES_HEX "69676e65756d2d67656e65736973" +#define IGNEUM_GENERATOR 2 +#define IGNEUM_PROGRAM_ATTEMPT 0 +#define IGNEUM_PROGRAM_ID 0x90cd909ac3e78d4aull +#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 add=8 shfl=8 xor=6 mad=5 mul=5 mulhi=5 sub=4 rotl=3 rotr=3 or=1" +// 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+sh64x52" +#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 64 +#define IGNEUM_SHADOW_REPS 52 +#define IGNEUM_SHADOW_INSTRS_PER_HASH 26624 +#define IGNEUM_SHADOW_OP_MIX "add=12 shfl=10 sub=9 mad=7 mul=6 mulhi=5 rotl=5 xor=5 rotr=3 or=2" +// 0 = closed-form dataset (ds_elem), 1 = memory-hard cache construction (MEMHARD.md, memhard.h) +#define IGNEUM_DATASET_MODE 1 + +#define IGNEUM_SEEDW_INIT { 0x67a9a7beu, 0x1a155b25u, 0xfddfb732u, 0x4b5af2e8u, 0xc55caf33u, 0xa27c13b7u, 0x06628a48u, 0x03852469u } +#define IGNEUM_KEY_INIT { 0x3067619fu, 0x3c269176u, 0x84a03b03u, 0xf8c63294u, 0xff977c5bu, 0xe60def3eu, 0x63630141u, 0xb8fbcb58u } +#define IGNEUM_CACHE_LOG2_WORDS 26 +#define IGNEUM_CACHE_SEGMENT_LOG2_LINES 6 +#define IGNEUM_CACHE_SEGMENTS 65536u +#define IGNEUM_ITEM_ROUNDS 8 +#define IGNEUM_MIXER_MULT 8 // mixer applications per round and after the last read (class v3, docs/plans/mixer-x4.md) +#define IGNEUM_MIX_ROT_INIT { 20u, 20u, 19u, 4u, 26u, 3u, 3u, 27u } +#define IGNEUM_MIX_MUL_INIT { 0x42146205u, 0x52cbe0fbu, 0x7ecf4a03u, 0x6728907fu, 0xd81d9751u, 0x132952c3u, 0xf60de277u, 0x05358035u, 0xbaf6499du, 0xe4db9667u, 0x3e98f45du, 0xd0004eddu, 0x2691630du, 0x9beb3bcfu, 0xab310379u, 0x99cfb423u } +#define IGNEUM_MIX_RC_INIT { 0xbab68293u, 0xcc162340u, 0x6ce151ccu, 0xe62b8997u, 0xc9c80297u, 0xf74a1654u, 0x3d704af5u, 0x3cf522b7u, 0x2b9cac04u, 0xa880ac10u, 0x13e5dd1du, 0x6fc3e233u, 0x2d83eeacu, 0x9006e8bfu, 0x2c4b5362u, 0x31b49ee2u } + +#ifndef IGNEUM_NO_CUDA +// Defined in kernel.cu. All launch on the default stream and return cudaGetLastError(). +cudaError_t igneum_launch_cache_fill(uint32_t* cache, uint32_t nSegments); +cudaError_t igneum_launch_build(uint32_t* ds, const uint32_t* cache, uint32_t nItems); +cudaError_t igneum_launch_hash(const uint32_t* ds, uint64_t* out, uint32_t baseNonce, uint32_t mask, + uint32_t nonces, uint32_t blockWarps); +cudaError_t igneum_hash_info(int* numRegs, int* blocksPerSM, uint32_t blockWarps); +#endif diff --git a/proto-cuda/packs-ca3-shadow/sh64x52/program.json b/proto-cuda/packs-ca3-shadow/sh64x52/program.json new file mode 100644 index 000000000..8cd722d50 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh64x52/program.json @@ -0,0 +1,197 @@ +{ + "format": "igneum-program-pack-3", + "generator": 2, + "attempt": 0, + "program_id": "0x90cd909ac3e78d4a", + "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": ["0x67a9a7be", "0x1a155b25", "0xfddfb732", "0x4b5af2e8", "0xc55caf33", "0xa27c13b7", "0x06628a48", "0x03852469"], + "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+sh64x52", + "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, "add": 8, "shfl": 8, "xor": 6, "mad": 5, "mul": 5, "mulhi": 5, "sub": 4, "rotl": 3, "rotr": 3, "or": 1}, + "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": 64, "reps": 52, "instrs_per_hash": 26624, "op_mix": {"add": 12, "shfl": 10, "sub": 9, "mad": 7, "mul": 6, "mulhi": 5, "rotl": 5, "xor": 5, "rotr": 3, "or": 2}, "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": "add", "dst": 5, "src": 2, "src2": 1, "imm": "0x92199f99", "imm2": "0x8bc12da9", "rot": 9, "bit": 18, "mask": 4}, + {"i": 1, "op": "add", "dst": 0, "src": 7, "src2": 1, "imm": "0x8d72d3ad", "imm2": "0x63079e5a", "rot": 20, "bit": 26, "mask": 4}, + {"i": 2, "op": "shfl", "dst": 6, "src": 3, "src2": 6, "imm": "0x9beaeddf", "imm2": "0x744ecb00", "rot": 10, "bit": 4, "mask": 2}, + {"i": 3, "op": "sub", "dst": 4, "src": 2, "src2": 0, "imm": "0x2a3ddc67", "imm2": "0x72c80241", "rot": 30, "bit": 1, "mask": 16}, + {"i": 4, "op": "add", "dst": 7, "src": 0, "src2": 5, "imm": "0xb21b4bab", "imm2": "0x5d4c7a60", "rot": 17, "bit": 31, "mask": 4}, + {"i": 5, "op": "rotl", "dst": 0, "src": 6, "src2": 3, "imm": "0xe69d7919", "imm2": "0xa048c61e", "rot": 11, "bit": 1, "mask": 8}, + {"i": 6, "op": "add", "dst": 0, "src": 1, "src2": 3, "imm": "0x2fe0e98b", "imm2": "0xc88e2942", "rot": 5, "bit": 16, "mask": 16}, + {"i": 7, "op": "xor", "dst": 7, "src": 1, "src2": 0, "imm": "0xc16efe98", "imm2": "0x01a638c8", "rot": 8, "bit": 17, "mask": 1}, + {"i": 8, "op": "mad", "dst": 1, "src": 6, "src2": 5, "imm": "0x76ec7b8b", "imm2": "0x25663feb", "rot": 29, "bit": 30, "mask": 2}, + {"i": 9, "op": "shfl", "dst": 6, "src": 1, "src2": 0, "imm": "0x6c8ee3cb", "imm2": "0xea93237e", "rot": 27, "bit": 1, "mask": 4}, + {"i": 10, "op": "mad", "dst": 1, "src": 2, "src2": 2, "imm": "0x6dc4ea18", "imm2": "0x6efde6f5", "rot": 3, "bit": 20, "mask": 2}, + {"i": 11, "op": "mad", "dst": 5, "src": 0, "src2": 3, "imm": "0x023613fc", "imm2": "0x18c51939", "rot": 19, "bit": 31, "mask": 1}, + {"i": 12, "op": "shfl", "dst": 2, "src": 6, "src2": 1, "imm": "0x74aec8d2", "imm2": "0x7f7ad29c", "rot": 7, "bit": 8, "mask": 4}, + {"i": 13, "op": "add", "dst": 1, "src": 5, "src2": 6, "imm": "0xbdf8f9a5", "imm2": "0xbc48c63e", "rot": 6, "bit": 25, "mask": 2}, + {"i": 14, "op": "rotl", "dst": 1, "src": 2, "src2": 6, "imm": "0x7ad8ca8b", "imm2": "0x14c712ad", "rot": 29, "bit": 25, "mask": 8}, + {"i": 15, "op": "sub", "dst": 1, "src": 4, "src2": 5, "imm": "0xd3349f69", "imm2": "0x70aac45a", "rot": 29, "bit": 9, "mask": 16}, + {"i": 16, "op": "or", "dst": 7, "src": 1, "src2": 2, "imm": "0x08168ed1", "imm2": "0x28964037", "rot": 26, "bit": 0, "mask": 2}, + {"i": 17, "op": "shfl", "dst": 2, "src": 4, "src2": 6, "imm": "0x98d85f72", "imm2": "0x3dc87042", "rot": 29, "bit": 22, "mask": 8}, + {"i": 18, "op": "xor", "dst": 7, "src": 4, "src2": 0, "imm": "0x651d4a0e", "imm2": "0x93c198bd", "rot": 26, "bit": 12, "mask": 8}, + {"i": 19, "op": "mul", "dst": 6, "src": 1, "src2": 6, "imm": "0xd38ce89d", "imm2": "0x3dfad388", "rot": 5, "bit": 28, "mask": 8}, + {"i": 20, "op": "mad", "dst": 5, "src": 6, "src2": 0, "imm": "0x59d78b36", "imm2": "0xc4db274e", "rot": 25, "bit": 24, "mask": 1}, + {"i": 21, "op": "sub", "dst": 3, "src": 1, "src2": 7, "imm": "0xf6c6a6c7", "imm2": "0x8536f4e6", "rot": 6, "bit": 12, "mask": 4}, + {"i": 22, "op": "mul", "dst": 6, "src": 0, "src2": 7, "imm": "0x599445b4", "imm2": "0x632f8c32", "rot": 19, "bit": 4, "mask": 8}, + {"i": 23, "op": "add", "dst": 2, "src": 0, "src2": 7, "imm": "0x45c37cec", "imm2": "0x96e8f127", "rot": 15, "bit": 1, "mask": 4}, + {"i": 24, "op": "sub", "dst": 6, "src": 4, "src2": 3, "imm": "0xc1c44491", "imm2": "0x92e3ce57", "rot": 20, "bit": 25, "mask": 4}, + {"i": 25, "op": "mad", "dst": 7, "src": 3, "src2": 4, "imm": "0x89bfb8d3", "imm2": "0x19b5455e", "rot": 22, "bit": 2, "mask": 16}, + {"i": 26, "op": "rotl", "dst": 3, "src": 5, "src2": 7, "imm": "0x2f47ce8d", "imm2": "0x8b458ec5", "rot": 9, "bit": 0, "mask": 4}, + {"i": 27, "op": "sub", "dst": 2, "src": 1, "src2": 2, "imm": "0x9f0dce23", "imm2": "0x3cdca814", "rot": 25, "bit": 1, "mask": 2}, + {"i": 28, "op": "mulhi", "dst": 6, "src": 0, "src2": 3, "imm": "0x61fc9eb8", "imm2": "0x23202e9d", "rot": 30, "bit": 16, "mask": 16}, + {"i": 29, "op": "shfl", "dst": 2, "src": 4, "src2": 3, "imm": "0x339dbd65", "imm2": "0xc175f639", "rot": 15, "bit": 22, "mask": 2}, + {"i": 30, "op": "shfl", "dst": 1, "src": 6, "src2": 1, "imm": "0x5bd14589", "imm2": "0xa68a2bed", "rot": 31, "bit": 31, "mask": 1}, + {"i": 31, "op": "add", "dst": 1, "src": 6, "src2": 1, "imm": "0x37985632", "imm2": "0xb1cdb2ab", "rot": 29, "bit": 1, "mask": 8}, + {"i": 32, "op": "rotr", "dst": 0, "src": 1, "src2": 6, "imm": "0x4b2058f4", "imm2": "0xf06d8ac9", "rot": 9, "bit": 15, "mask": 16}, + {"i": 33, "op": "shfl", "dst": 3, "src": 4, "src2": 4, "imm": "0x2081626c", "imm2": "0x08d1bb87", "rot": 24, "bit": 29, "mask": 2}, + {"i": 34, "op": "shfl", "dst": 0, "src": 3, "src2": 6, "imm": "0xe4fcfe03", "imm2": "0x78a46b13", "rot": 15, "bit": 29, "mask": 4}, + {"i": 35, "op": "mul", "dst": 7, "src": 0, "src2": 4, "imm": "0x33148d30", "imm2": "0x5780a3d6", "rot": 6, "bit": 11, "mask": 2}, + {"i": 36, "op": "add", "dst": 3, "src": 1, "src2": 1, "imm": "0x804e777e", "imm2": "0x856e0180", "rot": 22, "bit": 0, "mask": 16}, + {"i": 37, "op": "xor", "dst": 1, "src": 6, "src2": 0, "imm": "0xc69aa2f6", "imm2": "0xafebe3e8", "rot": 15, "bit": 9, "mask": 16}, + {"i": 38, "op": "mul", "dst": 2, "src": 7, "src2": 4, "imm": "0xeb4c4082", "imm2": "0x3f1e0da7", "rot": 25, "bit": 20, "mask": 16}, + {"i": 39, "op": "add", "dst": 6, "src": 5, "src2": 5, "imm": "0x0b06c8a7", "imm2": "0xe9bd0cc4", "rot": 6, "bit": 2, "mask": 4}, + {"i": 40, "op": "mul", "dst": 5, "src": 7, "src2": 7, "imm": "0x070af1b6", "imm2": "0x6b648e75", "rot": 10, "bit": 6, "mask": 16}, + {"i": 41, "op": "mulhi", "dst": 2, "src": 3, "src2": 2, "imm": "0x389753b2", "imm2": "0x9e657305", "rot": 30, "bit": 2, "mask": 4}, + {"i": 42, "op": "xor", "dst": 2, "src": 0, "src2": 4, "imm": "0x0960e5b9", "imm2": "0xa925a406", "rot": 4, "bit": 6, "mask": 16}, + {"i": 43, "op": "rotl", "dst": 0, "src": 1, "src2": 1, "imm": "0x8eabe09f", "imm2": "0x76ef71e2", "rot": 4, "bit": 19, "mask": 8}, + {"i": 44, "op": "mulhi", "dst": 4, "src": 3, "src2": 7, "imm": "0x6a34768a", "imm2": "0x2e427c64", "rot": 21, "bit": 5, "mask": 4}, + {"i": 45, "op": "add", "dst": 6, "src": 7, "src2": 5, "imm": "0xee822e17", "imm2": "0xcdcb63f6", "rot": 27, "bit": 12, "mask": 16}, + {"i": 46, "op": "mad", "dst": 3, "src": 2, "src2": 0, "imm": "0xc89ead43", "imm2": "0x4d3108b2", "rot": 26, "bit": 17, "mask": 1}, + {"i": 47, "op": "shfl", "dst": 4, "src": 3, "src2": 0, "imm": "0xdd62be9e", "imm2": "0xf243f6f2", "rot": 8, "bit": 4, "mask": 8}, + {"i": 48, "op": "mulhi", "dst": 6, "src": 5, "src2": 0, "imm": "0xd3f7fa72", "imm2": "0x0debc83f", "rot": 25, "bit": 5, "mask": 2}, + {"i": 49, "op": "sub", "dst": 0, "src": 2, "src2": 6, "imm": "0x7afadd15", "imm2": "0xc07fc39c", "rot": 30, "bit": 29, "mask": 8}, + {"i": 50, "op": "sub", "dst": 3, "src": 5, "src2": 3, "imm": "0x179b78ec", "imm2": "0xaeccde37", "rot": 30, "bit": 17, "mask": 1}, + {"i": 51, "op": "rotr", "dst": 1, "src": 4, "src2": 1, "imm": "0xa4bfcea6", "imm2": "0xbf63bb2f", "rot": 2, "bit": 21, "mask": 2}, + {"i": 52, "op": "mad", "dst": 6, "src": 7, "src2": 7, "imm": "0xabf5ed10", "imm2": "0x8a285f51", "rot": 3, "bit": 23, "mask": 2}, + {"i": 53, "op": "xor", "dst": 5, "src": 3, "src2": 5, "imm": "0x88b416eb", "imm2": "0x36271d87", "rot": 19, "bit": 10, "mask": 2}, + {"i": 54, "op": "sub", "dst": 1, "src": 0, "src2": 1, "imm": "0xa3417dd3", "imm2": "0xcd98f620", "rot": 28, "bit": 2, "mask": 1}, + {"i": 55, "op": "sub", "dst": 5, "src": 6, "src2": 2, "imm": "0x45996c6f", "imm2": "0xe3d41087", "rot": 4, "bit": 31, "mask": 1}, + {"i": 56, "op": "add", "dst": 3, "src": 2, "src2": 0, "imm": "0x3dfad1b6", "imm2": "0xd4758987", "rot": 27, "bit": 10, "mask": 2}, + {"i": 57, "op": "add", "dst": 4, "src": 1, "src2": 3, "imm": "0xfca75bc2", "imm2": "0x0602d6be", "rot": 19, "bit": 0, "mask": 16}, + {"i": 58, "op": "mulhi", "dst": 5, "src": 6, "src2": 5, "imm": "0x83250a7b", "imm2": "0x2f93d53b", "rot": 25, "bit": 7, "mask": 2}, + {"i": 59, "op": "shfl", "dst": 2, "src": 1, "src2": 0, "imm": "0x13f4a089", "imm2": "0x145ea125", "rot": 12, "bit": 3, "mask": 2}, + {"i": 60, "op": "rotl", "dst": 2, "src": 5, "src2": 6, "imm": "0xad3170e3", "imm2": "0x15db04d1", "rot": 9, "bit": 13, "mask": 2}, + {"i": 61, "op": "or", "dst": 4, "src": 6, "src2": 2, "imm": "0x4b6305b2", "imm2": "0x6e7b2e9c", "rot": 27, "bit": 16, "mask": 4}, + {"i": 62, "op": "rotr", "dst": 6, "src": 4, "src2": 6, "imm": "0xfcd4b1c9", "imm2": "0xaf5c733b", "rot": 6, "bit": 21, "mask": 16}, + {"i": 63, "op": "mul", "dst": 2, "src": 4, "src2": 6, "imm": "0x95cebb3e", "imm2": "0xbba9cdfc", "rot": 19, "bit": 23, "mask": 1} + ]}, + "instructions": [ + {"i": 0, "op": "mad", "dst": 2, "src": 3, "src2": 4, "imm": "0xbf7b174d", "imm2": "0x337b762e", "rot": 17, "bit": 2, "mask": 2, "width": 1}, + {"i": 1, "op": "mad", "dst": 2, "src": 1, "src2": 1, "imm": "0xdd04a5da", "imm2": "0x42da7657", "rot": 15, "bit": 30, "mask": 16, "width": 1}, + {"i": 2, "op": "mad", "dst": 2, "src": 3, "src2": 2, "imm": "0x734003fa", "imm2": "0x5bb67700", "rot": 3, "bit": 20, "mask": 1, "width": 1}, + {"i": 3, "op": "xor", "dst": 3, "src": 5, "src2": 5, "imm": "0xc55a1b1c", "imm2": "0xa19720f3", "rot": 7, "bit": 8, "mask": 1, "width": 1}, + {"i": 4, "op": "load", "dst": 7, "src": 2, "src2": 5, "imm": "0xad572dd7", "imm2": "0x9ceb3ea7", "rot": 18, "bit": 30, "mask": 2, "width": 1}, + {"i": 5, "op": "load", "dst": 5, "src": 7, "src2": 3, "imm": "0x769a53be", "imm2": "0x80f9067e", "rot": 12, "bit": 22, "mask": 1, "width": 1}, + {"i": 6, "op": "shfl", "dst": 1, "src": 4, "src2": 0, "imm": "0xd3613d88", "imm2": "0x262fb219", "rot": 10, "bit": 30, "mask": 8, "width": 1}, + {"i": 7, "op": "shfl", "dst": 7, "src": 3, "src2": 4, "imm": "0xce38e42f", "imm2": "0xb868b818", "rot": 11, "bit": 8, "mask": 8, "width": 1}, + {"i": 8, "op": "mulhi", "dst": 1, "src": 5, "src2": 2, "imm": "0xa5eebca5", "imm2": "0x5703a72b", "rot": 13, "bit": 13, "mask": 16, "width": 1}, + {"i": 9, "op": "rotr", "dst": 6, "src": 3, "src2": 4, "imm": "0x17a5a9c7", "imm2": "0xdcfb93a1", "rot": 20, "bit": 27, "mask": 2, "width": 1}, + {"i": 10, "op": "or", "dst": 3, "src": 4, "src2": 1, "imm": "0xccb7d785", "imm2": "0xc335364c", "rot": 14, "bit": 12, "mask": 4, "width": 1}, + {"i": 11, "op": "load", "dst": 4, "src": 3, "src2": 2, "imm": "0x88cb9af3", "imm2": "0x4e7dc10d", "rot": 24, "bit": 17, "mask": 4, "width": 1}, + {"i": 12, "op": "mulhi", "dst": 0, "src": 4, "src2": 4, "imm": "0x45374321", "imm2": "0x3cd91989", "rot": 11, "bit": 4, "mask": 2, "width": 1}, + {"i": 13, "op": "add", "dst": 5, "src": 1, "src2": 2, "imm": "0xc7934706", "imm2": "0xd3177981", "rot": 16, "bit": 30, "mask": 2, "width": 1}, + {"i": 14, "op": "load", "dst": 0, "src": 4, "src2": 3, "imm": "0xfd7f56bb", "imm2": "0x65e14f52", "rot": 13, "bit": 22, "mask": 2, "width": 1}, + {"i": 15, "op": "sub", "dst": 2, "src": 4, "src2": 4, "imm": "0x35a80b49", "imm2": "0x060f2d13", "rot": 16, "bit": 20, "mask": 16, "width": 1}, + {"i": 16, "op": "load", "dst": 2, "src": 0, "src2": 2, "imm": "0xae0a32c2", "imm2": "0x4c2a4cfe", "rot": 8, "bit": 31, "mask": 16, "width": 1}, + {"i": 17, "op": "load", "dst": 7, "src": 2, "src2": 6, "imm": "0x82a84cc3", "imm2": "0x21a38d68", "rot": 15, "bit": 21, "mask": 2, "width": 1}, + {"i": 18, "op": "shfl", "dst": 7, "src": 3, "src2": 3, "imm": "0xa3818806", "imm2": "0x8f66b5c8", "rot": 14, "bit": 6, "mask": 4, "width": 1}, + {"i": 19, "op": "mul", "dst": 5, "src": 0, "src2": 1, "imm": "0xa00de107", "imm2": "0x77bfcaa5", "rot": 3, "bit": 10, "mask": 2, "width": 1}, + {"i": 20, "op": "shfl", "dst": 3, "src": 4, "src2": 7, "imm": "0x1d2b8cab", "imm2": "0x80b4f9a2", "rot": 14, "bit": 25, "mask": 2, "width": 1}, + {"i": 21, "op": "shfl", "dst": 2, "src": 4, "src2": 5, "imm": "0x3ac915d2", "imm2": "0x5fba7bc2", "rot": 16, "bit": 1, "mask": 16, "width": 1}, + {"i": 22, "op": "mulhi", "dst": 6, "src": 2, "src2": 0, "imm": "0xdc3ec8fd", "imm2": "0x599e2fa3", "rot": 22, "bit": 3, "mask": 2, "width": 1}, + {"i": 23, "op": "load", "dst": 6, "src": 1, "src2": 5, "imm": "0x2a6b16d5", "imm2": "0xd73e396f", "rot": 28, "bit": 29, "mask": 2, "width": 1}, + {"i": 24, "op": "mul", "dst": 5, "src": 0, "src2": 7, "imm": "0x376d0223", "imm2": "0xe1c2169a", "rot": 4, "bit": 16, "mask": 16, "width": 1}, + {"i": 25, "op": "rotl", "dst": 5, "src": 7, "src2": 3, "imm": "0x78ad8c60", "imm2": "0x6f5b77d5", "rot": 19, "bit": 11, "mask": 16, "width": 1}, + {"i": 26, "op": "shfl", "dst": 7, "src": 6, "src2": 5, "imm": "0x93915b9f", "imm2": "0x1e61fb6b", "rot": 28, "bit": 23, "mask": 2, "width": 1}, + {"i": 27, "op": "xor", "dst": 0, "src": 5, "src2": 7, "imm": "0x6378fe15", "imm2": "0x66c78f42", "rot": 12, "bit": 31, "mask": 8, "width": 1}, + {"i": 28, "op": "xor", "dst": 0, "src": 4, "src2": 7, "imm": "0x20a57fda", "imm2": "0x088c848e", "rot": 16, "bit": 13, "mask": 4, "width": 1}, + {"i": 29, "op": "sub", "dst": 3, "src": 0, "src2": 2, "imm": "0x49d95fd5", "imm2": "0x1a5f946a", "rot": 6, "bit": 12, "mask": 1, "width": 1}, + {"i": 30, "op": "mul", "dst": 5, "src": 1, "src2": 7, "imm": "0x0a816217", "imm2": "0x405c4f73", "rot": 13, "bit": 27, "mask": 4, "width": 1}, + {"i": 31, "op": "load", "dst": 7, "src": 2, "src2": 2, "imm": "0x09ed045e", "imm2": "0xd69c4715", "rot": 5, "bit": 9, "mask": 2, "width": 1}, + {"i": 32, "op": "load", "dst": 1, "src": 0, "src2": 6, "imm": "0xeb79ea49", "imm2": "0xcc587f5a", "rot": 6, "bit": 8, "mask": 16, "width": 1}, + {"i": 33, "op": "xor", "dst": 5, "src": 6, "src2": 1, "imm": "0x3027401e", "imm2": "0x5f20c27e", "rot": 18, "bit": 9, "mask": 2, "width": 1}, + {"i": 34, "op": "load", "dst": 5, "src": 1, "src2": 3, "imm": "0x0e1cab07", "imm2": "0x09356c5b", "rot": 19, "bit": 31, "mask": 1, "width": 1}, + {"i": 35, "op": "mulhi", "dst": 0, "src": 5, "src2": 2, "imm": "0x90e31357", "imm2": "0xabd32484", "rot": 26, "bit": 5, "mask": 8, "width": 1}, + {"i": 36, "op": "shfl", "dst": 5, "src": 2, "src2": 5, "imm": "0xee9a955f", "imm2": "0x31b3faed", "rot": 8, "bit": 24, "mask": 4, "width": 1}, + {"i": 37, "op": "load", "dst": 7, "src": 0, "src2": 7, "imm": "0x3ba2f832", "imm2": "0x1160dcd3", "rot": 4, "bit": 29, "mask": 1, "width": 1}, + {"i": 38, "op": "add", "dst": 3, "src": 1, "src2": 7, "imm": "0x75ba2fad", "imm2": "0x230c005c", "rot": 4, "bit": 27, "mask": 1, "width": 1}, + {"i": 39, "op": "shfl", "dst": 1, "src": 5, "src2": 3, "imm": "0xdbf37e75", "imm2": "0xb5ac1969", "rot": 30, "bit": 13, "mask": 4, "width": 1}, + {"i": 40, "op": "xor", "dst": 2, "src": 5, "src2": 5, "imm": "0x47f136c5", "imm2": "0x06ce9153", "rot": 19, "bit": 10, "mask": 2, "width": 1}, + {"i": 41, "op": "mad", "dst": 3, "src": 6, "src2": 3, "imm": "0xce13eff8", "imm2": "0x04cc1d55", "rot": 3, "bit": 1, "mask": 4, "width": 1}, + {"i": 42, "op": "sub", "dst": 6, "src": 7, "src2": 1, "imm": "0x6a65ab71", "imm2": "0x8fbc1bcd", "rot": 4, "bit": 1, "mask": 8, "width": 1}, + {"i": 43, "op": "xor", "dst": 7, "src": 0, "src2": 7, "imm": "0xdaeb4928", "imm2": "0xc0423027", "rot": 24, "bit": 11, "mask": 8, "width": 1}, + {"i": 44, "op": "load", "dst": 1, "src": 7, "src2": 7, "imm": "0x778f01c9", "imm2": "0x28cedcea", "rot": 12, "bit": 4, "mask": 16, "width": 1}, + {"i": 45, "op": "mul", "dst": 2, "src": 3, "src2": 2, "imm": "0xf4264f1b", "imm2": "0x0f627d56", "rot": 5, "bit": 28, "mask": 8, "width": 1}, + {"i": 46, "op": "mulhi", "dst": 1, "src": 5, "src2": 1, "imm": "0xffb2147a", "imm2": "0xccde9b05", "rot": 13, "bit": 9, "mask": 2, "width": 1}, + {"i": 47, "op": "sub", "dst": 4, "src": 3, "src2": 5, "imm": "0x73b36234", "imm2": "0x3f5d5997", "rot": 7, "bit": 18, "mask": 2, "width": 1}, + {"i": 48, "op": "rotr", "dst": 2, "src": 6, "src2": 3, "imm": "0x3a4d9aa9", "imm2": "0x212bec7b", "rot": 4, "bit": 29, "mask": 16, "width": 1}, + {"i": 49, "op": "load", "dst": 3, "src": 5, "src2": 2, "imm": "0x626f11df", "imm2": "0x56cd5bfd", "rot": 7, "bit": 1, "mask": 1, "width": 1}, + {"i": 50, "op": "add", "dst": 1, "src": 5, "src2": 6, "imm": "0x81b8bc2c", "imm2": "0x1907970c", "rot": 28, "bit": 7, "mask": 4, "width": 1}, + {"i": 51, "op": "mul", "dst": 0, "src": 2, "src2": 2, "imm": "0xa8848b30", "imm2": "0xef6ac348", "rot": 9, "bit": 15, "mask": 8, "width": 1}, + {"i": 52, "op": "add", "dst": 0, "src": 2, "src2": 0, "imm": "0x4f92b968", "imm2": "0x699fd448", "rot": 22, "bit": 6, "mask": 4, "width": 1}, + {"i": 53, "op": "add", "dst": 1, "src": 0, "src2": 2, "imm": "0x2bb965af", "imm2": "0x77b1520d", "rot": 2, "bit": 12, "mask": 8, "width": 1}, + {"i": 54, "op": "rotl", "dst": 7, "src": 1, "src2": 0, "imm": "0x553e678b", "imm2": "0x3cc8eae0", "rot": 14, "bit": 20, "mask": 2, "width": 1}, + {"i": 55, "op": "add", "dst": 3, "src": 7, "src2": 2, "imm": "0x7b0fe07a", "imm2": "0xa54c55a0", "rot": 10, "bit": 1, "mask": 1, "width": 1}, + {"i": 56, "op": "load", "dst": 6, "src": 7, "src2": 4, "imm": "0x01eba9aa", "imm2": "0x2758c0f7", "rot": 14, "bit": 15, "mask": 4, "width": 1}, + {"i": 57, "op": "rotr", "dst": 1, "src": 5, "src2": 2, "imm": "0x1f5267b3", "imm2": "0x236f5a27", "rot": 2, "bit": 31, "mask": 16, "width": 1}, + {"i": 58, "op": "load", "dst": 5, "src": 4, "src2": 3, "imm": "0xa9954a9b", "imm2": "0x6a54d4e8", "rot": 11, "bit": 10, "mask": 16, "width": 1}, + {"i": 59, "op": "load", "dst": 6, "src": 2, "src2": 4, "imm": "0x9923ff88", "imm2": "0x9357254e", "rot": 16, "bit": 1, "mask": 16, "width": 1}, + {"i": 60, "op": "mad", "dst": 3, "src": 5, "src2": 0, "imm": "0xc0cc51a6", "imm2": "0x3fd7701b", "rot": 20, "bit": 1, "mask": 4, "width": 1}, + {"i": 61, "op": "add", "dst": 5, "src": 7, "src2": 7, "imm": "0xaf9dd72d", "imm2": "0xad7493e7", "rot": 7, "bit": 31, "mask": 16, "width": 1}, + {"i": 62, "op": "add", "dst": 4, "src": 6, "src2": 2, "imm": "0x89841d87", "imm2": "0x1e07c3d9", "rot": 6, "bit": 27, "mask": 1, "width": 1}, + {"i": 63, "op": "rotl", "dst": 5, "src": 4, "src2": 2, "imm": "0xae210f8d", "imm2": "0x8e499ba4", "rot": 19, "bit": 9, "mask": 1, "width": 1} + ] +} diff --git a/proto-cuda/packs-ca3-shadow/sh64x52/program.metal b/proto-cuda/packs-ca3-shadow/sh64x52/program.metal new file mode 100644 index 000000000..b0864ba67 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh64x52/program.metal @@ -0,0 +1,176 @@ +#include +using namespace metal; + +#define MASK 0x0fffffffu +constant uint SEEDW[8] = { 0x67a9a7beu, 0x1a155b25u, 0xfddfb732u, 0x4b5af2e8u, 0xc55caf33u, 0xa27c13b7u, 0x06628a48u, 0x03852469u }; + +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 = r3 * r4 + r2; // 0 + r2 = r1 * r1 + r2; // 1 + r2 = r3 * r2 + r2; // 2 + r3 = r3 ^ r5; // 3 + r7 = r7 ^ dataset[r2 & MASK]; // 4 + r5 = r5 ^ dataset[r7 & MASK]; // 5 + r1 = r1 ^ simd_shuffle_xor(r4, (ushort)8); // 6 + r7 = r7 ^ simd_shuffle_xor(r3, (ushort)8); // 7 + r1 = mulhi(r1, r5); // 8 + r6 = rotr_var(r6, r3); // 9 + r3 = r3 | r4; // 10 + r4 = r4 ^ dataset[r3 & MASK]; // 11 + r0 = mulhi(r0, r4); // 12 + r5 = r5 + r1 + select(0xc7934706u, 0xd3177981u, ((sel >> 30u) & 1u) != 0u); // 13 + r0 = r0 ^ dataset[r4 & MASK]; // 14 + r2 = r2 - r4; // 15 + r2 = r2 ^ dataset[r0 & MASK]; // 16 + r7 = r7 ^ dataset[r2 & MASK]; // 17 + r7 = r7 ^ simd_shuffle_xor(r3, (ushort)4); // 18 + r5 = r5 * r0; // 19 + r3 = r3 ^ simd_shuffle_xor(r4, (ushort)2); // 20 + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)16); // 21 + r6 = mulhi(r6, r2); // 22 + r6 = r6 ^ dataset[r1 & MASK]; // 23 + r5 = r5 * r0; // 24 + r5 = rotl_imm(r5, 19u); // 25 + r7 = r7 ^ simd_shuffle_xor(r6, (ushort)2); // 26 + r0 = r0 ^ r5; // 27 + r0 = r0 ^ r4; // 28 + r3 = r3 - r0; // 29 + r5 = r5 * r1; // 30 + r7 = r7 ^ dataset[r2 & MASK]; // 31 + r1 = r1 ^ dataset[r0 & MASK]; // 32 + r5 = r5 ^ r6; // 33 + r5 = r5 ^ dataset[r1 & MASK]; // 34 + r0 = mulhi(r0, r5); // 35 + r5 = r5 ^ simd_shuffle_xor(r2, (ushort)4); // 36 + r7 = r7 ^ dataset[r0 & MASK]; // 37 + r3 = r3 + r1 + select(0x75ba2fadu, 0x230c005cu, ((sel >> 27u) & 1u) != 0u); // 38 + r1 = r1 ^ simd_shuffle_xor(r5, (ushort)4); // 39 + r2 = r2 ^ r5; // 40 + r3 = r6 * r3 + r3; // 41 + r6 = r6 - r7; // 42 + r7 = r7 ^ r0; // 43 + r1 = r1 ^ dataset[r7 & MASK]; // 44 + r2 = r2 * r3; // 45 + r1 = mulhi(r1, r5); // 46 + r4 = r4 - r3; // 47 + r2 = rotr_var(r2, r6); // 48 + r3 = r3 ^ dataset[r5 & MASK]; // 49 + r1 = r1 + r5 + select(0x81b8bc2cu, 0x1907970cu, ((sel >> 7u) & 1u) != 0u); // 50 + r0 = r0 * r2; // 51 + r0 = r0 + r2 + select(0x4f92b968u, 0x699fd448u, ((sel >> 6u) & 1u) != 0u); // 52 + r1 = r1 + r0 + select(0x2bb965afu, 0x77b1520du, ((sel >> 12u) & 1u) != 0u); // 53 + r7 = rotl_imm(r7, 14u); // 54 + r3 = r3 + r7 + select(0x7b0fe07au, 0xa54c55a0u, ((sel >> 1u) & 1u) != 0u); // 55 + r6 = r6 ^ dataset[r7 & MASK]; // 56 + r1 = rotr_var(r1, r5); // 57 + r5 = r5 ^ dataset[r4 & MASK]; // 58 + r6 = r6 ^ dataset[r2 & MASK]; // 59 + r3 = r5 * r0 + r3; // 60 + r5 = r5 + r7 + select(0xaf9dd72du, 0xad7493e7u, ((sel >> 31u) & 1u) != 0u); // 61 + r4 = r4 + r6 + select(0x89841d87u, 0x1e07c3d9u, ((sel >> 27u) & 1u) != 0u); // 62 + r5 = rotl_imm(r5, 19u); // 63 + // latency-shadow block (Counter ASIC 3.0 item 8): 64 ALU instructions x 52 passes after instruction 63, no load + for (uint sh = 0u; sh < 52u; ++sh) { + r5 = r5 + r2 + select(0x92199f99u, 0x8bc12da9u, ((sel >> 18u) & 1u) != 0u); // s0 add + r0 = r0 + r7 + select(0x8d72d3adu, 0x63079e5au, ((sel >> 26u) & 1u) != 0u); // s1 add + r6 = r6 ^ simd_shuffle_xor(r3, (ushort)2); // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + select(0xb21b4babu, 0x5d4c7a60u, ((sel >> 31u) & 1u) != 0u); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + select(0x2fe0e98bu, 0xc88e2942u, ((sel >> 16u) & 1u) != 0u); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + r6 = r6 ^ simd_shuffle_xor(r1, (ushort)4); // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + r2 = r2 ^ simd_shuffle_xor(r6, (ushort)4); // s12 shfl + r1 = r1 + r5 + select(0xbdf8f9a5u, 0xbc48c63eu, ((sel >> 25u) & 1u) != 0u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)8); // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + select(0x45c37cecu, 0x96e8f127u, ((sel >> 1u) & 1u) != 0u); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = mulhi(r6, r0); // s28 mulhi + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)2); // s29 shfl + r1 = r1 ^ simd_shuffle_xor(r6, (ushort)1); // s30 shfl + r1 = r1 + r6 + select(0x37985632u, 0xb1cdb2abu, ((sel >> 1u) & 1u) != 0u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + r3 = r3 ^ simd_shuffle_xor(r4, (ushort)2); // s33 shfl + r0 = r0 ^ simd_shuffle_xor(r3, (ushort)4); // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + select(0x804e777eu, 0x856e0180u, ((sel >> 0u) & 1u) != 0u); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + select(0x0b06c8a7u, 0xe9bd0cc4u, ((sel >> 2u) & 1u) != 0u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = mulhi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = mulhi(r4, r3); // s44 mulhi + r6 = r6 + r7 + select(0xee822e17u, 0xcdcb63f6u, ((sel >> 12u) & 1u) != 0u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + r4 = r4 ^ simd_shuffle_xor(r3, (ushort)8); // s47 shfl + r6 = mulhi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + select(0x3dfad1b6u, 0xd4758987u, ((sel >> 10u) & 1u) != 0u); // s56 add + r4 = r4 + r1 + select(0xfca75bc2u, 0x0602d6beu, ((sel >> 0u) & 1u) != 0u); // s57 add + r5 = mulhi(r5, r6); // s58 mulhi + r2 = r2 ^ simd_shuffle_xor(r1, (ushort)2); // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + } + } + uint lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((ulong)hi << 32) | (ulong)lo; +} diff --git a/proto-cuda/packs-ca3-shadow/sh64x52/program_bound.metal b/proto-cuda/packs-ca3-shadow/sh64x52/program_bound.metal new file mode 100644 index 000000000..81de21978 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh64x52/program_bound.metal @@ -0,0 +1,178 @@ +#include +using namespace metal; + +#define MASK 0x0fffffffu +constant uint SEEDW[8] = { 0x67a9a7beu, 0x1a155b25u, 0xfddfb732u, 0x4b5af2e8u, 0xc55caf33u, 0xa27c13b7u, 0x06628a48u, 0x03852469u }; + +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 = r3 * r4 + r2; // 0 + r2 = r1 * r1 + r2; // 1 + r2 = r3 * r2 + r2; // 2 + r3 = r3 ^ r5; // 3 + r7 = r7 ^ dataset[r2 & MASK]; // 4 + r5 = r5 ^ dataset[r7 & MASK]; // 5 + r1 = r1 ^ simd_shuffle_xor(r4, (ushort)8); // 6 + r7 = r7 ^ simd_shuffle_xor(r3, (ushort)8); // 7 + r1 = mulhi(r1, r5); // 8 + r6 = rotr_var(r6, r3); // 9 + r3 = r3 | r4; // 10 + r4 = r4 ^ dataset[r3 & MASK]; // 11 + r0 = mulhi(r0, r4); // 12 + r5 = r5 + r1 + select(0xc7934706u, 0xd3177981u, ((sel >> 30u) & 1u) != 0u); // 13 + r0 = r0 ^ dataset[r4 & MASK]; // 14 + r2 = r2 - r4; // 15 + r2 = r2 ^ dataset[r0 & MASK]; // 16 + r7 = r7 ^ dataset[r2 & MASK]; // 17 + r7 = r7 ^ simd_shuffle_xor(r3, (ushort)4); // 18 + r5 = r5 * r0; // 19 + r3 = r3 ^ simd_shuffle_xor(r4, (ushort)2); // 20 + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)16); // 21 + r6 = mulhi(r6, r2); // 22 + r6 = r6 ^ dataset[r1 & MASK]; // 23 + r5 = r5 * r0; // 24 + r5 = rotl_imm(r5, 19u); // 25 + r7 = r7 ^ simd_shuffle_xor(r6, (ushort)2); // 26 + r0 = r0 ^ r5; // 27 + r0 = r0 ^ r4; // 28 + r3 = r3 - r0; // 29 + r5 = r5 * r1; // 30 + r7 = r7 ^ dataset[r2 & MASK]; // 31 + r1 = r1 ^ dataset[r0 & MASK]; // 32 + r5 = r5 ^ r6; // 33 + r5 = r5 ^ dataset[r1 & MASK]; // 34 + r0 = mulhi(r0, r5); // 35 + r5 = r5 ^ simd_shuffle_xor(r2, (ushort)4); // 36 + r7 = r7 ^ dataset[r0 & MASK]; // 37 + r3 = r3 + r1 + select(0x75ba2fadu, 0x230c005cu, ((sel >> 27u) & 1u) != 0u); // 38 + r1 = r1 ^ simd_shuffle_xor(r5, (ushort)4); // 39 + r2 = r2 ^ r5; // 40 + r3 = r6 * r3 + r3; // 41 + r6 = r6 - r7; // 42 + r7 = r7 ^ r0; // 43 + r1 = r1 ^ dataset[r7 & MASK]; // 44 + r2 = r2 * r3; // 45 + r1 = mulhi(r1, r5); // 46 + r4 = r4 - r3; // 47 + r2 = rotr_var(r2, r6); // 48 + r3 = r3 ^ dataset[r5 & MASK]; // 49 + r1 = r1 + r5 + select(0x81b8bc2cu, 0x1907970cu, ((sel >> 7u) & 1u) != 0u); // 50 + r0 = r0 * r2; // 51 + r0 = r0 + r2 + select(0x4f92b968u, 0x699fd448u, ((sel >> 6u) & 1u) != 0u); // 52 + r1 = r1 + r0 + select(0x2bb965afu, 0x77b1520du, ((sel >> 12u) & 1u) != 0u); // 53 + r7 = rotl_imm(r7, 14u); // 54 + r3 = r3 + r7 + select(0x7b0fe07au, 0xa54c55a0u, ((sel >> 1u) & 1u) != 0u); // 55 + r6 = r6 ^ dataset[r7 & MASK]; // 56 + r1 = rotr_var(r1, r5); // 57 + r5 = r5 ^ dataset[r4 & MASK]; // 58 + r6 = r6 ^ dataset[r2 & MASK]; // 59 + r3 = r5 * r0 + r3; // 60 + r5 = r5 + r7 + select(0xaf9dd72du, 0xad7493e7u, ((sel >> 31u) & 1u) != 0u); // 61 + r4 = r4 + r6 + select(0x89841d87u, 0x1e07c3d9u, ((sel >> 27u) & 1u) != 0u); // 62 + r5 = rotl_imm(r5, 19u); // 63 + // latency-shadow block (Counter ASIC 3.0 item 8): 64 ALU instructions x 52 passes after instruction 63, no load + for (uint sh = 0u; sh < 52u; ++sh) { + r5 = r5 + r2 + select(0x92199f99u, 0x8bc12da9u, ((sel >> 18u) & 1u) != 0u); // s0 add + r0 = r0 + r7 + select(0x8d72d3adu, 0x63079e5au, ((sel >> 26u) & 1u) != 0u); // s1 add + r6 = r6 ^ simd_shuffle_xor(r3, (ushort)2); // s2 shfl + r4 = r4 - r2; // s3 sub + r7 = r7 + r0 + select(0xb21b4babu, 0x5d4c7a60u, ((sel >> 31u) & 1u) != 0u); // s4 add + r0 = rotl_imm(r0, 11u); // s5 rotl + r0 = r0 + r1 + select(0x2fe0e98bu, 0xc88e2942u, ((sel >> 16u) & 1u) != 0u); // s6 add + r7 = r7 ^ r1; // s7 xor + r1 = r6 * r5 + r1; // s8 mad + r6 = r6 ^ simd_shuffle_xor(r1, (ushort)4); // s9 shfl + r1 = r2 * r2 + r1; // s10 mad + r5 = r0 * r3 + r5; // s11 mad + r2 = r2 ^ simd_shuffle_xor(r6, (ushort)4); // s12 shfl + r1 = r1 + r5 + select(0xbdf8f9a5u, 0xbc48c63eu, ((sel >> 25u) & 1u) != 0u); // s13 add + r1 = rotl_imm(r1, 29u); // s14 rotl + r1 = r1 - r4; // s15 sub + r7 = r7 | r1; // s16 or + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)8); // s17 shfl + r7 = r7 ^ r4; // s18 xor + r6 = r6 * r1; // s19 mul + r5 = r6 * r0 + r5; // s20 mad + r3 = r3 - r1; // s21 sub + r6 = r6 * r0; // s22 mul + r2 = r2 + r0 + select(0x45c37cecu, 0x96e8f127u, ((sel >> 1u) & 1u) != 0u); // s23 add + r6 = r6 - r4; // s24 sub + r7 = r3 * r4 + r7; // s25 mad + r3 = rotl_imm(r3, 9u); // s26 rotl + r2 = r2 - r1; // s27 sub + r6 = mulhi(r6, r0); // s28 mulhi + r2 = r2 ^ simd_shuffle_xor(r4, (ushort)2); // s29 shfl + r1 = r1 ^ simd_shuffle_xor(r6, (ushort)1); // s30 shfl + r1 = r1 + r6 + select(0x37985632u, 0xb1cdb2abu, ((sel >> 1u) & 1u) != 0u); // s31 add + r0 = rotr_var(r0, r1); // s32 rotr + r3 = r3 ^ simd_shuffle_xor(r4, (ushort)2); // s33 shfl + r0 = r0 ^ simd_shuffle_xor(r3, (ushort)4); // s34 shfl + r7 = r7 * r0; // s35 mul + r3 = r3 + r1 + select(0x804e777eu, 0x856e0180u, ((sel >> 0u) & 1u) != 0u); // s36 add + r1 = r1 ^ r6; // s37 xor + r2 = r2 * r7; // s38 mul + r6 = r6 + r5 + select(0x0b06c8a7u, 0xe9bd0cc4u, ((sel >> 2u) & 1u) != 0u); // s39 add + r5 = r5 * r7; // s40 mul + r2 = mulhi(r2, r3); // s41 mulhi + r2 = r2 ^ r0; // s42 xor + r0 = rotl_imm(r0, 4u); // s43 rotl + r4 = mulhi(r4, r3); // s44 mulhi + r6 = r6 + r7 + select(0xee822e17u, 0xcdcb63f6u, ((sel >> 12u) & 1u) != 0u); // s45 add + r3 = r2 * r0 + r3; // s46 mad + r4 = r4 ^ simd_shuffle_xor(r3, (ushort)8); // s47 shfl + r6 = mulhi(r6, r5); // s48 mulhi + r0 = r0 - r2; // s49 sub + r3 = r3 - r5; // s50 sub + r1 = rotr_var(r1, r4); // s51 rotr + r6 = r7 * r7 + r6; // s52 mad + r5 = r5 ^ r3; // s53 xor + r1 = r1 - r0; // s54 sub + r5 = r5 - r6; // s55 sub + r3 = r3 + r2 + select(0x3dfad1b6u, 0xd4758987u, ((sel >> 10u) & 1u) != 0u); // s56 add + r4 = r4 + r1 + select(0xfca75bc2u, 0x0602d6beu, ((sel >> 0u) & 1u) != 0u); // s57 add + r5 = mulhi(r5, r6); // s58 mulhi + r2 = r2 ^ simd_shuffle_xor(r1, (ushort)2); // s59 shfl + r2 = rotl_imm(r2, 9u); // s60 rotl + r4 = r4 | r6; // s61 or + r6 = rotr_var(r6, r4); // s62 rotr + r2 = r2 * r4; // s63 mul + } + } + uint lo = r0 ^ rotl_imm(r1, 7u) ^ rotl_imm(r2, 14u) ^ rotl_imm(r3, 21u); + uint hi = r4 ^ rotl_imm(r5, 9u) ^ rotl_imm(r6, 18u) ^ rotl_imm(r7, 27u); + out[gid] = ((ulong)hi << 32) | (ulong)lo; +} diff --git a/proto-cuda/packs-ca3-shadow/sh64x52/vectors.h b/proto-cuda/packs-ca3-shadow/sh64x52/vectors.h new file mode 100644 index 000000000..cb1951505 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh64x52/vectors.h @@ -0,0 +1,57 @@ +// Generated by igneum-pow export (generator v2) for seed "igneum-genesis". Do not edit by hand. +// Expected outputs: igneum-pow (Rust) CPU interpreter, generator v2, memory-hard dataset +#pragma once +#ifdef __cplusplus +#include +#else +#include +#endif + +#define IGNEUM_VEC_WARPS 3 +static const uint32_t IGNEUM_VEC_BASE[IGNEUM_VEC_WARPS] = { 0u, 4096u, 1000000u }; +static const uint64_t IGNEUM_VEC_OUT[IGNEUM_VEC_WARPS][32] = { + { // base nonce 0 + 0xa3b8a9290804d659ull, 0x5f9f66754b18d8ffull, 0xb16216e92da835abull, 0x0b39fe4d61785892ull, 0x41c1dc4365fae001ull, 0x4ac46030d254ef2eull, 0xc150b2eedf1150e8ull, 0x12f58d2b4365bf60ull, + 0x062ff54cc66f4af7ull, 0xeae75a929125710eull, 0xd66526b65b739772ull, 0x0bc71264b95c2476ull, 0xc1f26cc3c388b763ull, 0x0710e93b4113ad1full, 0x0640684a7e9d8d3bull, 0x9d744b9600a4492cull, + 0x5c587b49d6bb21abull, 0xe61fc91882792f37ull, 0x34b9bd30434f7639ull, 0x90d5832360033534ull, 0xcb292d32ba73f298ull, 0xe25a34c284220a27ull, 0xc368afb07b84cb97ull, 0x22677ac18da1c492ull, + 0xc92ec9eb2bfa3cf8ull, 0xf8192cbae1584ea9ull, 0x33832845f56602efull, 0xb4631c3eeb64e4baull, 0xe0cd026f74f13503ull, 0x8b2cdde67aa83342ull, 0x49460f9d8fc8543dull, 0xbe043f283c45c8aaull + }, + { // base nonce 4096 + 0xed7090c919557c31ull, 0xfbb7e7d61439b8f4ull, 0x6b8d89508dd93d99ull, 0x6ef10df441054b27ull, 0xb96ef0c3c6bdda0eull, 0x4488abf6b2d6c8f5ull, 0x435084dc15d7a62dull, 0x338b5465e2c3a9e7ull, + 0xeb7e07e8ea494994ull, 0xcb9a2c8427a70369ull, 0x21906aa4dcdc8944ull, 0xcca2b3f732f284d3ull, 0x2fe6fc14ec6a9070ull, 0xad83e557932d4561ull, 0xef0d3ed86b4b3fd6ull, 0x5eaa24bad3e59a48ull, + 0x361b2a9a72c39ad5ull, 0xde4f4070e3726533ull, 0xf2a31628c3125eb9ull, 0x9c2509ede8c044f6ull, 0xf3a06baf023a54c0ull, 0xbbb4d46f4187a08aull, 0x5ca37f713e263710ull, 0x9e951dbc1b62c5f6ull, + 0xddbaccb99d6b9cdeull, 0x69ae83fd76961da9ull, 0xfc6e0154954e49b0ull, 0x7758bc37239127bcull, 0x6cb3d941e4e44b81ull, 0x6d51736742b5174full, 0x4382a5a2ce0621a3ull, 0x3e6aab017766dc15ull + }, + { // base nonce 1000000 + 0x558d0db79f4d3c83ull, 0xc4eced5e12f7f0fcull, 0xba23763a74a98760ull, 0x420c654eca0293cfull, 0x62ca60aab40cf135ull, 0x08220d2bee4bea8aull, 0x302d6feb6e0a384aull, 0x34825ebd202ccb38ull, + 0xf0b40a99af71c081ull, 0xebdbf2eb6a1c6879ull, 0x0ce4db23e563da32ull, 0x61b6e1797f1dbbf0ull, 0x77d28fa986746824ull, 0xbcd909df67ce5081ull, 0x97106a72a4677f06ull, 0xda3a74c4ecd3aaf3ull, + 0xcd5e5dce743f003cull, 0x2301292d354f657aull, 0xee209fca69a0f756ull, 0x997b5dbc4500f879ull, 0x7721d77fa5d95ebfull, 0xc258e83bfa0aebb3ull, 0xbfb81fe198719694ull, 0x078c8c8cba7bbf51ull, + 0x2cabe008da30cf01ull, 0x4095f0bc4ad3af9eull, 0x2f92a82a74c172dfull, 0x3896dc4196c0da37ull, 0xbb633d25bf177829ull, 0x01dfdee4b011a771ull, 0x96977507954d83fbull, 0x33d4518d25e3ead2ull + } +}; + +// Dataset self-test: dataset[0..15] and dataset[IGNEUM_MASK] (268435455). +static const uint32_t IGNEUM_DS_HEAD[16] = { + 0xfdad4319u, 0x1a7b68e1u, 0xde6db608u, 0x13d73892u, 0xd17f447au, 0xb2221ccfu, 0x9db004bdu, 0x57d7d367u, + 0xdbc4cf34u, 0x697c009au, 0xc43af1d4u, 0x97f12b2eu, 0x74c37cd0u, 0xc651ea15u, 0x665a6d29u, 0x22330a2du +}; +static const uint32_t IGNEUM_DS_LAST_INDEX = 268435455u; +static const uint32_t IGNEUM_DS_LAST = 0xa83e7aa6u; +// 64 sampled dataset words (index, value) computed on the Mac. +#define IGNEUM_DS_SAMPLES 64 +static const uint32_t IGNEUM_DS_SAMPLE_INDEX[IGNEUM_DS_SAMPLES] = { + 59471966u, 217795994u, 208353206u, 42483309u, 172547758u, 148076330u, 183853158u, 214389424u, 267488061u, 169781097u, 184093494u, 153880993u, 84977930u, 46426879u, 3093825u, 225364072u, 44593546u, 260713159u, 168250303u, 52384140u, 223401610u, 45554030u, 95410555u, 175039924u, 79171087u, 267580473u, 24168642u, 37981670u, 171551130u, 195559979u, 204611762u, 140997658u, 138925853u, 86637313u, 20736778u, 219665210u, 160430336u, 264654675u, 8013395u, 228945585u, 213884386u, 104419827u, 44185464u, 142737231u, 99284897u, 132475900u, 61861762u, 132056166u, 262388043u, 91878046u, 117353561u, 124768597u, 71352993u, 190698941u, 46055428u, 55281366u, 165145231u, 106810753u, 171985651u, 232085256u, 159510492u, 40072060u, 209107596u, 39023794u +}; +static const uint32_t IGNEUM_DS_SAMPLE_VALUE[IGNEUM_DS_SAMPLES] = { + 0x3230bc7bu, 0x7fbfe2c9u, 0xb2690991u, 0x1745c7c5u, 0x0ab0ccafu, 0x1bf87d6bu, 0x160139fdu, 0x719817acu, 0x0155df4bu, 0xbe1e86c3u, 0x680bcd6cu, 0x79c3dc6cu, 0x181e7e5fu, 0x0713a109u, 0xc705dd9fu, 0x3933b7a8u, 0xdd1c0431u, 0x50522b30u, 0xa0020b38u, 0xbff39e96u, 0x21b67e18u, 0x740f8db3u, 0x2baba568u, 0x2c9bef83u, 0x0ad9b671u, 0xc4327869u, 0x7b4fd7d0u, 0x2c29965fu, 0xec56f15fu, 0x61111746u, 0x303a1d6eu, 0xbddcfd1au, 0xf829a355u, 0x6d5df2a9u, 0x01ab8e44u, 0x06d13507u, 0xda8dcfc6u, 0x01a703e1u, 0xafe7d2c1u, 0xc091c3a2u, 0xac1814feu, 0x6e6ff62au, 0x8fdf01bau, 0xdd3f7159u, 0xdfa0d75cu, 0x26684c35u, 0x7f441e63u, 0x88df2570u, 0x8aa4d5ebu, 0xcc816c05u, 0x434df890u, 0xcd392ad6u, 0x1ab4cb63u, 0x595926fau, 0x7cd76b41u, 0x20cb95c4u, 0x13cf823fu, 0xf9daf901u, 0xff9af40au, 0x2c7dfa51u, 0x871206dbu, 0x938c116cu, 0xb64bf199u, 0x5751f874u +}; +// Cache self-test (memory-hard mode): cache[0..15], the last 16 words, and FNV-1a 64 over all 2^26 words. +static const uint32_t IGNEUM_CACHE_HEAD[16] = { + 0x355a86d2u, 0x7957db1cu, 0xd21772afu, 0x6fc1e09bu, 0xd55ce61du, 0x6e6a278bu, 0xd3f543ceu, 0x223d8e82u, + 0x143ab337u, 0x2e9f05bdu, 0x2eb389bfu, 0x0c6e449eu, 0x5cfa4222u, 0xba6560feu, 0x8e3e1aa4u, 0xdbcc1d53u +}; +static const uint32_t IGNEUM_CACHE_LAST[16] = { + 0x41190d91u, 0xbd277957u, 0x22ddbb49u, 0x6986f207u, 0xdf69a4d6u, 0x26401a3au, 0x818230fbu, 0xc417122du, + 0x3597b211u, 0xb553ce55u, 0xcf39cc0du, 0x3b7fc43au, 0x3fd43b00u, 0x67e1c80eu, 0xffa7ea7du, 0xca2960abu +}; +static const uint64_t IGNEUM_CACHE_FNV64 = 0x48c4f5bf24166b2eull; diff --git a/proto-cuda/packs-ca3-shadow/sh64x52/vectors.json b/proto-cuda/packs-ca3-shadow/sh64x52/vectors.json new file mode 100644 index 000000000..b06e81e17 --- /dev/null +++ b/proto-cuda/packs-ca3-shadow/sh64x52/vectors.json @@ -0,0 +1,36 @@ +{ + "seed": "igneum-genesis", + "day": "2026-10-03", + "dataset_mode": "memory-hard", + "dataset_log2_words": 28, + "mask": "0x0fffffff", + "lanes": 32, + "source": "igneum-pow (Rust) CPU interpreter, generator v2, memory-hard dataset", + "warps": [ + {"base_nonce": 0, "expected": [ + "0xa3b8a9290804d659", "0x5f9f66754b18d8ff", "0xb16216e92da835ab", "0x0b39fe4d61785892", "0x41c1dc4365fae001", "0x4ac46030d254ef2e", "0xc150b2eedf1150e8", "0x12f58d2b4365bf60", + "0x062ff54cc66f4af7", "0xeae75a929125710e", "0xd66526b65b739772", "0x0bc71264b95c2476", "0xc1f26cc3c388b763", "0x0710e93b4113ad1f", "0x0640684a7e9d8d3b", "0x9d744b9600a4492c", + "0x5c587b49d6bb21ab", "0xe61fc91882792f37", "0x34b9bd30434f7639", "0x90d5832360033534", "0xcb292d32ba73f298", "0xe25a34c284220a27", "0xc368afb07b84cb97", "0x22677ac18da1c492", + "0xc92ec9eb2bfa3cf8", "0xf8192cbae1584ea9", "0x33832845f56602ef", "0xb4631c3eeb64e4ba", "0xe0cd026f74f13503", "0x8b2cdde67aa83342", "0x49460f9d8fc8543d", "0xbe043f283c45c8aa" + ]}, + {"base_nonce": 4096, "expected": [ + "0xed7090c919557c31", "0xfbb7e7d61439b8f4", "0x6b8d89508dd93d99", "0x6ef10df441054b27", "0xb96ef0c3c6bdda0e", "0x4488abf6b2d6c8f5", "0x435084dc15d7a62d", "0x338b5465e2c3a9e7", + "0xeb7e07e8ea494994", "0xcb9a2c8427a70369", "0x21906aa4dcdc8944", "0xcca2b3f732f284d3", "0x2fe6fc14ec6a9070", "0xad83e557932d4561", "0xef0d3ed86b4b3fd6", "0x5eaa24bad3e59a48", + "0x361b2a9a72c39ad5", "0xde4f4070e3726533", "0xf2a31628c3125eb9", "0x9c2509ede8c044f6", "0xf3a06baf023a54c0", "0xbbb4d46f4187a08a", "0x5ca37f713e263710", "0x9e951dbc1b62c5f6", + "0xddbaccb99d6b9cde", "0x69ae83fd76961da9", "0xfc6e0154954e49b0", "0x7758bc37239127bc", "0x6cb3d941e4e44b81", "0x6d51736742b5174f", "0x4382a5a2ce0621a3", "0x3e6aab017766dc15" + ]}, + {"base_nonce": 1000000, "expected": [ + "0x558d0db79f4d3c83", "0xc4eced5e12f7f0fc", "0xba23763a74a98760", "0x420c654eca0293cf", "0x62ca60aab40cf135", "0x08220d2bee4bea8a", "0x302d6feb6e0a384a", "0x34825ebd202ccb38", + "0xf0b40a99af71c081", "0xebdbf2eb6a1c6879", "0x0ce4db23e563da32", "0x61b6e1797f1dbbf0", "0x77d28fa986746824", "0xbcd909df67ce5081", "0x97106a72a4677f06", "0xda3a74c4ecd3aaf3", + "0xcd5e5dce743f003c", "0x2301292d354f657a", "0xee209fca69a0f756", "0x997b5dbc4500f879", "0x7721d77fa5d95ebf", "0xc258e83bfa0aebb3", "0xbfb81fe198719694", "0x078c8c8cba7bbf51", + "0x2cabe008da30cf01", "0x4095f0bc4ad3af9e", "0x2f92a82a74c172df", "0x3896dc4196c0da37", "0xbb633d25bf177829", "0x01dfdee4b011a771", "0x96977507954d83fb", "0x33d4518d25e3ead2" + ]} + ], + "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" +} diff --git a/tools/ca3-shadow/pc2-shadow-bench.ps1 b/tools/ca3-shadow/pc2-shadow-bench.ps1 new file mode 100644 index 000000000..fcc2f27c7 --- /dev/null +++ b/tools/ca3-shadow/pc2-shadow-bench.ps1 @@ -0,0 +1,97 @@ +# Counter ASIC 3.0 item 8 (6 October 2026): program work in the latency shadow on PC 2's RTX 5090 (machine 1ccfe586), +# docs/analysis/latency-shadow-2026-10-06.md. A signed `run` job published with --stop-miners: the app stops its miners +# before this script starts and restarts them when it ends (app/igneum-app/src/jobrun.rs, stop_miners_first); the +# script never quits, restarts or updates the app. It switches the prover off for the run and back on at the end (as +# tools/prover-floor/pc2-floor-measure.ps1 does), confirms the card is empty by nvidia-smi's compute-apps list (never +# api/state, which answers {} on this machine), then runs the INSTALLED igneum-worker-cuda.exe (NVRTC, the pack's own +# kernel text) with --bench on every pack of the fetched kit (fetch job fetch-ca3-shadow-20261006: the class v3 control +# mx8-genesis and the shadow ladder sh256x2 .. sh256x88, sh64x52, sh1024x3) while `nvidia-smi -l 1` samples +# power.draw, utilization.gpu, clocks.sm, clocks.mem and temperature every second into a file. Every number is a RESULT +# line: the worker's own lines (vectors, fingerprint, MH/s), and per pack the mean, min and max power, the mean +# utilisation and clocks over the bench's own window (the timed dispatches), plus every raw sample. No power cap is set +# (the 5 October sweep on this card, counter-asic-2-status.md 22:16, showed the cap never binds above the 400 W floor and +# -pl 200 / 250 are below power.min_limit); nothing elevated. Read back with `node tools/jobs.mjs `. +$ErrorActionPreference = 'Continue' +function Stamp { (Get-Date).ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ssZ') } +$urlFile = if ($env:IGNEUM_APP_DIR) { Join-Path $env:IGNEUM_APP_DIR 'app.url' } else { Join-Path $env:LOCALAPPDATA 'igneum\app\app.url' } +if (-not (Test-Path $urlFile)) { $urlFile = Join-Path $env:LOCALAPPDATA 'igneum\app\app.url' } +$base = $null +if (Test-Path $urlFile) { $base = (Get-Content $urlFile -Raw).Trim().TrimEnd('/') } +function Prove($on) { if (-not $base) { return 'no app.url' }; try { (Invoke-RestMethod -Method Post -Uri "$base/api/prove" -ContentType 'application/json' -Body (@{on=$on} | ConvertTo-Json -Compress) -TimeoutSec 10) | ConvertTo-Json -Compress } catch { "error: $_" } } +function Smi($q) { try { (& nvidia-smi --query-gpu=$q --format=csv,noheader,nounits 2>$null) -join ' | ' } catch { 'nvidia-smi failed' } } +function CudaApps { @(& nvidia-smi --query-compute-apps=pid,process_name,used_memory --format=csv,noheader 2>$null | ForEach-Object { "$_" } | Where-Object { $_ -match 'igneum|sp1|prove' }) } +"RESULT start $(Stamp) prover off for the run: $(Prove $false)" +Start-Sleep -Seconds 20 +$t = 0; $apps = @(CudaApps) +while ($t -lt 120 -and $apps.Count -gt 0) { Start-Sleep -Seconds 10; $t += 10; $apps = @(CudaApps) } +if ($apps.Count -eq 0) { "RESULT card $(Stamp) empty after $t s (no igneum, sp1 or prove compute app on the card)" } else { "RESULT card $(Stamp) UNCONFIRMED after $t s: the numbers below are beside " + ($apps -join '; ') } +"RESULT gpus $(Stamp) $(Smi 'index,name,driver_version,memory.used,clocks.sm,clocks.mem,power.draw,power.limit,power.min_limit,power.max_limit,temperature.gpu')" + +# the kit: the fetch job's folder under the app's jobs folder (tested before use: the wiped-jobs-folder class) +$jobs = Split-Path $env:IGNEUM_JOB_DIR +$kit = Join-Path $jobs 'fetch-ca3-shadow-20261006' +$packs = Join-Path $kit 'packs-ca3-shadow' +if (-not (Test-Path $packs)) { "RESULT error packs missing at $packs (the fetch job fetch-ca3-shadow-20261006 runs first; republish it after any app update)"; "RESULT end $(Stamp) prover back on: $(Prove $true)"; exit 2 } +$inst = @("$env:LOCALAPPDATA\Programs\Igneum Miner", "$env:ProgramFiles\Igneum Miner") | Where-Object { Test-Path (Join-Path $_ 'igneum-worker-cuda.exe') } | Select-Object -First 1 +if (-not $inst) { "RESULT error no installed igneum-worker-cuda.exe"; "RESULT end $(Stamp) prover back on: $(Prove $true)"; exit 2 } +$exe = Join-Path $inst 'igneum-worker-cuda.exe' +"RESULT worker $exe sha256 $((Get-FileHash -Algorithm SHA256 $exe).Hash.ToLower()) bytes $((Get-Item $exe).Length)" +foreach ($f in (Get-ChildItem $packs -Recurse -File | Sort-Object FullName)) { "RESULT kitfile $($f.FullName.Substring($packs.Length + 1).Replace('\', '/')) sha256 $((Get-FileHash -Algorithm SHA256 $f.FullName).Hash.ToLower()) bytes $($f.Length)" } + +# the sampler: nvidia-smi every second into a file for the whole run +$samples = Join-Path $env:IGNEUM_JOB_DIR 'smi-samples.csv' +$smiExe = (Get-Command nvidia-smi -ErrorAction SilentlyContinue).Source +if (-not $smiExe) { $smiExe = Join-Path $env:SystemRoot 'System32\nvidia-smi.exe' } +$sampler = Start-Process -FilePath $smiExe -ArgumentList @('--query-gpu=timestamp,power.draw,utilization.gpu,clocks.sm,clocks.mem,temperature.gpu,memory.used', '--format=csv,noheader,nounits', '-l', '1') -RedirectStandardOutput $samples -NoNewWindow -PassThru +Start-Sleep -Seconds 5 +$windows = @() +$order = @('mx8-genesis', 'sh256x2', 'sh256x7', 'sh256x13', 'sh256x27', 'sh256x53', 'sh256x88', 'sh64x52', 'sh1024x3') +try { + "RESULT idle $(Stamp) 10 s before the first bench: $(Smi 'power.draw,utilization.gpu,clocks.sm,clocks.mem')" + Start-Sleep -Seconds 10 + foreach ($pk in $order) { + $d = Join-Path $packs $pk + if (-not (Test-Path $d)) { "RESULT bench $pk missing"; continue } + foreach ($bw in @(1, 8)) { + if ($bw -eq 8 -and $pk -notin @('mx8-genesis', 'sh256x13', 'sh256x88')) { continue } + $batches = if ($bw -eq 1) { 250 } else { 120 } + $t0 = Get-Date + "RESULT bench $pk bw$bw start $(Stamp)" + & $exe --bench --pack $d --batches $batches --batch-log2 24 --block-warps $bw 2>&1 | ForEach-Object { "RESULT bench $pk bw$bw $_" } + $t1 = Get-Date + "RESULT bench $pk bw$bw end $(Stamp) exit=$LASTEXITCODE wall_s=$([int]($t1 - $t0).TotalSeconds)" + $windows += [pscustomobject]@{ pack = $pk; bw = $bw; t0 = $t0; t1 = $t1 } + Start-Sleep -Seconds 3 + } + } +} finally { + Start-Sleep -Seconds 2 + try { Stop-Process -Id $sampler.Id -Force -ErrorAction SilentlyContinue } catch { } + Start-Sleep -Seconds 1 +} +# per-window power: the samples inside the bench's window after its first 12 s (compile, fills, warm-up) and before its last 2 s +$rows = @() +if (Test-Path $samples) { + foreach ($l in (Get-Content $samples)) { + $p = $l -split ',\s*' + if ($p.Count -lt 7) { continue } + try { $ts = [datetime]::ParseExact($p[0].Trim(), 'yyyy/MM/dd HH:mm:ss.fff', $null) } catch { continue } + $rows += [pscustomobject]@{ ts = $ts; w = [double]$p[1]; util = [double]$p[2]; sm = [double]$p[3]; mem = [double]$p[4]; temp = [double]$p[5]; used = [double]$p[6] } + } +} +"RESULT samples total $($rows.Count) file $samples" +foreach ($win in $windows) { + $in = @($rows | Where-Object { $_.ts -gt $win.t0.AddSeconds(12) -and $_.ts -lt $win.t1.AddSeconds(-2) }) + if ($in.Count -gt 0) { + $w = $in | Measure-Object -Property w -Average -Minimum -Maximum + $u = ($in | Measure-Object -Property util -Average).Average + $s = ($in | Measure-Object -Property sm -Average).Average + $m = ($in | Measure-Object -Property mem -Average).Average + $tp = ($in | Measure-Object -Property temp -Maximum).Maximum + "RESULT power $($win.pack) bw$($win.bw) samples=$($in.Count) watts_mean=$([math]::Round($w.Average, 1)) watts_min=$($w.Minimum) watts_max=$($w.Maximum) util_mean=$([math]::Round($u, 1)) sm_mhz_mean=$([math]::Round($s)) mem_mhz_mean=$([math]::Round($m)) temp_max=$tp window_s=$([int]($win.t1 - $win.t0).TotalSeconds)" + } else { "RESULT power $($win.pack) bw$($win.bw) no samples in window" } +} +foreach ($r in $rows) { "RESULT sample $($r.ts.ToString('HH:mm:ss')) $($r.w) $($r.util) $($r.sm) $($r.mem) $($r.temp) $($r.used)" } +"RESULT gpus_after $(Stamp) $(Smi 'power.draw,power.limit,clocks.sm,clocks.mem,temperature.gpu,memory.used')" +"RESULT end $(Stamp) prover back on: $(Prove $true)" +exit 0 From 4605314315ae77334ffeb30e3526fe40b4d7b49e Mon Sep 17 00:00:00 2001 From: igneum-labs <337424239+igneum-labs@users.noreply.github.com> Date: Tue, 6 Oct 2026 08:08:26 +0000 Subject: [PATCH 2/2] Counter ASIC 3.0 item 8: the Mac rows The M5 Max ladder (Metal, packbench, IOReport GPU and DRAM watts without root): latency-bound to about 100,000 ops per hash, the 5 percent point about 130,000, 11 to 27 W GPU at 100,000 ops, 0.78 to 1.40 microjoules per hash; the verifier's law 2.06 ms + 3.2 us per 1,000 shadow instructions per warp on one core; every pack bit-exact. The analysis file with the knob, the chip side (k = 1, 1.5, 0.3), the gates and the consequences; the bench-log entry; the 5090 rows pending the PC 2 job (the playbook now carries the core-clock rows and the sh256x40 rung). Co-Authored-By: Claude Fable 5.1 --- docs/analysis/latency-shadow-2026-10-06.md | 152 +++++++++++++++++++++ docs/bench-log.md | 27 ++++ tools/ca3-shadow/pc2-shadow-bench.ps1 | 41 +++++- 3 files changed, 214 insertions(+), 6 deletions(-) create mode 100644 docs/analysis/latency-shadow-2026-10-06.md diff --git a/docs/analysis/latency-shadow-2026-10-06.md b/docs/analysis/latency-shadow-2026-10-06.md new file mode 100644 index 000000000..36c2ea5ea --- /dev/null +++ b/docs/analysis/latency-shadow-2026-10-06.md @@ -0,0 +1,152 @@ +# Program work in the latency shadow (Counter ASIC 3.0 item 8, 6 October 2026) + +Branch `ca3-shadow`, worker "shadow", on `ca3-coord` 870363c. The item was opened by item 1's finding (`docs/analysis/chip-model-v3.md` section 5.7): the `f = 1` chip stores the dataset in DRAM and recomputes nothing, so the only lever that moves its per-joule row is program work that the honest card hides behind its 128 dependent reads and a chip must pay for with an ALU core. This file holds the knob, the measurements on the Apple M5 Max and the RTX 5090, the verifier's cost law, the chip side re-evaluated on measured watts, the gates a class v4 candidate would need, and the consequences per tier. Every GPU figure says where it was measured and the load average it was taken at; every chip figure is arithmetic on the cited figures of chip-model-v3.md section 5 and is approximate. Nothing here is live: the knob sits behind a `LoadClass` field that version 2 and class v3 never set, no default changed, and nothing was published to the devnet. + +## 1. What the hash does today, counted from the code + +| Quantity | Value | Source | +|---|---|---| +| Instructions per program | 64, of which 16 are `load` | `igneum-pow/src/generator.rs` `INSTR_COUNT`, `LOAD_SLOTS`; spec 01 section 1.4 | +| Iterations per hash | 8 | `ITERATIONS` | +| Instructions executed per hash | 512: 128 loads, 384 ALU | 64 x 8 | +| ALU op mix of the 48 non-load slots | add 12, xor 10, mul 8, mad 8, shfl 8, rotl 7, sub 6, mulhi 6, rotr 6, or 4 (weights, sum 75) | spec 01 section 1.4.2 | +| Integer ops per instruction, counted from the emitted statements | add 5 (shift, and, select, two adds), rotr 2 (and, funnel shift), shfl 2 (shuffle, xor), the seven others 1; load 2 (mask, xor) | `igneum-pow/src/emit.rs` instruction lines; weighted mean over the non-load weights 137 / 75 = 1.83 ops per ALU instruction | +| Integer ops per hash, this count | about 930: 384 x 1.83 = 703 ALU plus 128 x 2 = 256 for the loads' address mask and fold | arithmetic; the chip model's "512 ops per hash" (section 5.1) counted instructions, not ops | +| Per-hash loop | `for it in 0..8 { sel = r0; 64 instructions in order }`, then the fold | spec 01 section 1.7 | +| RTX 5090 integer budget | 45.2 T op/s (OpenCL event, integer chain) | `docs/benchmarks/repro.md` 2.2 (branch repro-bench) | +| Ops the 5090 could hide before compute binds at 136.1 MH/s | about 332,000 per hash | 45.2 T / 136.1 M | + +Vendor cost per op differs from this count. Item 6's step costs on the M5 Max (`docs/bench-log.md` "6 October 2026, Counter ASIC 3.0 item 6", branch ca3-reserve 192a683): the live `rotr` step 1.13x and the live `shfl` step 0.86x of the add-xor-rotate chain. The "ops" column below is the count above; the measured watts and rates are what the cards do with it. + +## 2. The knob + +`LoadClass::shadow: Option`, class name `+shx` (`mx8+sh256x27`), `igneum-pow/src/generator.rs`. The shadow block is `S` ALU instructions drawn from the program stream AFTER the 64 base instructions (the ten non-load families at the weights of 1.4.2, the same nine draws per instruction as the program's, the source drawn as on an ALU slot, the width roll and the era windows drawn and ignored when the class takes them), executed `R` times at the end of every iteration, after instruction 63 and before the next iteration samples `sel`, with the iteration's `sel`. Per hash it adds `8 x S x R` ALU instructions and no load. + +| Property | How the knob keeps it | +|---|---| +| 16 loads per program, 128 per hash, 4,096 items per unit | the base program is untouched; the block holds no load (`shadow_class_leaves_the_base_program_and_class_v3_untouched`, `generator.rs` tests) | +| The acceptance rule of 1.4.6 | unchanged: it interprets the base program (`accept.rs` reads `p.instrs`), and the block is drawn after the base draws, so the attempt and the verdict are those of the class without the shadow, draw for draw. A class v4 that adopts the block would decide whether rule (c) also runs the block (its cost scales with N: 2,048 evaluations x N ops, about 0.7 s at N = 330,000 on one core, approximate) | +| v2 and v3 byte-identical | the field is `None` on `V2`, `MX4`, `MX8`, `V3_CLASS`; the interpreter, the six kernel bodies, program.h and program.json emit nothing when it is `None`; `cargo test` in igneum-pow: 54 + 4 + 19 + 7 green, the pinned v2 and v3 packs byte for byte (`tests/packs.rs`) | +| Program id | the read-width id with `shadow/ || instrs_le16 || reps_le16` appended, so two block sizes of one seed never share an id | +| The CPU verifier | `verify.rs` runs the block `R` times per iteration after the base instructions with the same `step`; bit-exact against Metal on every pack below | +| Kernel text | one `for (sh = 0; sh < R; ++sh) { S lines }` block inside the iteration loop, the same statements the base instructions use, in Metal, CUDA and OpenCL, both kernels each; program.h carries `IGNEUM_SHADOW_INSTRS`, `IGNEUM_SHADOW_REPS`, `IGNEUM_SHADOW_INSTRS_PER_HASH`, `IGNEUM_SHADOW_OP_MIX` | + +Why a block with a repeat count and not a longer straight line: the block is one site in the kernel text, so a 256-instruction block at 88 passes is 256 lines of code, not 22,528, and the compile-ahead per epoch stays at the v3 figure (Metal compile 85 to 97 ms for a 256-instruction block, 231 ms for 1,024, against 1 ms cached for the control; the 1,024-instruction block also costs the M5 Max 17 percent of its hash rate at the same N, section 3). A repeated random block is RandomX's shape (256 instructions x 2,048 iterations per program), and a chip pays it with a general ALU core either way. + +## 3. The M5 Max rows (Metal, `with-lock.sh measure`, two sessions, 07:51 to 08:03 UTC) + +Harness: `proto-metal/packbench --pack --batches 60 --batch-log2 24 --group 256` (built from this branch; vectors are the Rust interpreter's, the fingerprint FNV-1a 64 over the 2^24 outputs at base 0). Power: the GPU and DRAM energy channels of the IOReport "Energy Model" group, sampled at 2 Hz by a 60-line Swift tool in the scratchpad (`gpupower`: `dlopen("/usr/lib/libIOReport.dylib")`, `IOReportCopyChannelsInGroup("Energy Model")`, the `GPU` and `DRAM` channels in mJ; the `GPU Energy` channel in nJ agrees with `GPU` to 2 percent), no root, the mean over the samples after the first 6 s of each run (compile, fills, warm-up) and before its last second. These are the GPU and the memory, not the package: Ember Tune's Apple row reports 38 W for the whole package at 26.7 MH/s (`docs/plans/ember-tune.md`, branch ember-tune, approximate), so the SoC fabric, the CPU and the rest add about 17 W over the 21 W here. The 5090's watts are whole-card. Idle GPU 0.44 W, idle DRAM 0.64 W. Load averages 3.3 to 6.8 (other agents' builds queued behind the measure lock; the GPU was idle: the Mac mines nothing). The control is the pinned class v3 pack `proto-cuda/packs-ca2-mixer/mx8-genesis`; the shadow packs are `proto-cuda/packs-ca3-shadow/*` over the same seed and class. + +| Pack (class over mx8) | Shadow instrs per hash | Ops per hash (x1.83 + 930) | MH/s (GPU time) | Against the control | GPU W | DRAM W | Microjoules per hash (GPU + DRAM) | Verifier ms per warp, one core, avg of 20 (worst cold) | Bit-exact (3 vectors, 3 in batch, fingerprint) | Load average at start | Compile ms | +|---|---|---|---|---|---|---|---|---|---|---|---| +| mx8-genesis (control, runs 1, 2, 3) | 0 | 930 | 27.07, 27.07, 27.10 | | 11.2, 9.2, 12.3 | 10.2, 10.0, 10.2 | 0.78 (mean 21.0 W) | 2.062 (2.188) | yes, 7c28cfb06c5c65a9 (the 5 October fingerprint) | 4.6, 6.8, 4.2 | 1 (cached) | +| sh256x2 | 4,096 | 8,400 | 26.85 | -0.8% | 15.1 | 10.4 | 0.95 | 2.080 (2.249) | yes, 33e8bbe4c35b2e54 | 4.6 | 85 | +| sh256x7 | 14,336 | 27,200 | 26.74 | -1.3% | 18.0 | 10.6 | 1.07 | 2.112 (2.224) | yes, 6cfb70911007520a | 4.2 | 93 | +| sh256x13 | 26,624 | 49,700 | 26.75 | -1.2% | 20.6 | 10.5 | 1.16 | 2.212 (2.237) | yes, 59ac286fe2a5a9ef | 3.7 | 93 | +| sh64x52 (the same N as sh256x13, a 64-instruction block; runs 1, 2) | 26,624 | 49,700 | 27.72, 27.79 | +2.5% | 19.8, 20.3 | 10.2, 10.3 | 1.09 | 2.137 (2.237) | yes, 9dd010f79d8ca9f4 | 4.4, 4.1 | 59 | +| sh1024x3 (a 1,024-instruction block) | 24,576 | 45,900 | 22.53 | -16.8% | 20.2 | 9.7 | 1.33 | 2.150 (2.274) | yes, a05399c819b79aad | 6.0 | 231 | +| sh256x27 (runs 1, 2) | 55,296 | 102,100 | 26.48, 26.86 | -1.5% (mean 26.67) | 26.9, 26.9 | 10.4, 10.2 | 1.40 | 2.229 (2.276) | yes, 3d2e8245cc084d07 | 3.3, 5.6 | 96 | +| sh256x40 | 81,920 | 150,800 | 25.10 | -7.3% | 26.7 | 10.1 | 1.46 | 2.329 (2.396) | yes, 0844b706302f1c9c | 5.0 | 97 | +| sh256x53 (runs 1, 2) | 108,544 | 199,600 | 24.40, 24.09 | -10.4% (mean 24.25) | 28.8, 28.5 | 9.5, 9.7 | 1.58 | 2.427 (2.461) | yes, 4f824b15cf2b124a | 3.9, 4.6 | 85 | +| sh256x88 | 180,224 | 330,700 | 21.39 | -21.0% | 31.7 | 8.4 | 1.88 | 2.619 (2.771) | yes, 0572522e39a94d8a | 3.8 | 87 | + +Commands: `with-lock.sh measure /mac-shadow-session.sh` and `mac-shadow-session2.sh` (each: `uptime`, `gpupower --interval-ms 500` in the background, `packbench` as above, then `igneum-pow bench --seed igneum-genesis --class --warps 20` for the verifier; logs `mac-shadow-session.log`, `mac-shadow-session2.log` in the scratchpad). The control reads 2.5 percent under the 5 October figure for this pack (27.7 MH/s, `docs/plans/mixer-x4.md` 6.2) on three runs over 12 minutes, so the day's denominator is 27.08 and every row is read against it. + +What the rows say: + +1. The M5 Max stays latency-bound to about 100,000 ops per hash (sh256x27: 1.5 percent under the control, inside the run-to-run spread of 1.4 percent) and stops there: 7.3 percent down at 151,000, 10.4 at 200,000, 21 at 331,000. By the 5 percent rule (`docs/plans/counter-asic-2-public.md`, the 2.0 rule) its ceiling is about 130,000 ops per hash (interpolated between the 102,000 and 151,000 rungs), 70,000 shadow instructions, `sh256x35`. Its counted throughput at the compute-bound end is 21.39 M x 330,700 = 7.1 T ops/s, against the 4.4 T op/s the add-xor-rotate chain of item 6 gives (881 G steps/s x 5): the shadow's op mix issues faster than a dependent chain, as it should. The chip model's "about 290,000" for the M5 Max (section 5.7, from memory) was 2.2x too high; the measured bind point is the row. +2. The block size matters on Apple at the same N: a 64-instruction block (sh64x52) runs 2.5 percent ABOVE the control on both runs, 256 holds, 1,024 costs 17 percent (the kernel's instruction footprint; the 1,024-line block at 3 passes is 3,072 instructions of straight-line code per iteration if the compiler unrolls it). A class v4 would fix the block at 64 to 256 instructions. Why a block can be faster than nothing: the shadow spaces the loads of a warp in time, so fewer reads queue at once (the probe's 522 ns at 256 lanes is a queued latency); it is a 2.5 percent effect on this card and is not claimed for the others. +3. Watts: the GPU rises from 11 W to 27 W at 100,000 ops and to 32 W at 331,000, the DRAM stays at 10 W while the rate holds and falls with it. The marginal energy per counted op on the latency-bound rungs: 22 pJ at 8,400 ops (the first rung wakes the ALUs), 11 at 27,000, 7.8 at 50,000, 6.9 at 100,000; at the compute-bound end 2.9 pJ (31.7 W over 7.1 T op/s). The M5 Max's marginal ALU energy at the useful N is therefore 6 to 8 pJ per counted op, the same class as the 5.5 pJ the model assumed for the 5090 (section 5.7, from (575 - 326) W / 45.2 T op/s). +4. Energy per hash, GPU plus DRAM: 0.78 microjoules at the control, 1.40 at 100,000 ops, 1.88 at 331,000. The M5 Max at the hash is 3.0x better per joule than the 5090's 2.34 microjoules (290 W at 124 MH/s in the app, the 5 October sweep record: `docs/plans/miner-eff.md`, branch miner-eff; 326 W was a peak with the prover on) on these channels, 1.7x on the package figure. + +## 4. The verifier's cost law + +One M5 Max performance core, the Rust interpreter, 20 warps, loads 3.3 to 6.8: ms per warp = 2.06 + 3.2 x 10^-3 x (shadow instructions per hash) / 1,000, the slope fitted on the three largest rungs (3.09, 3.36, 3.26 microseconds per 1,000 shadow instructions per warp). That is 0.1 ns per lane-instruction (the register-major loops vectorise over the 32 lanes) or 1.75 microseconds per 1,000 counted ops per warp. The worst cold unit sits 0.05 to 0.17 ms above the average on every rung. On a 2019-class laptop core the rule of chip-model-v3.md section 3 item 1 (2.5x slower) gives 8.0 microseconds per 1,000 shadow instructions per warp. + +The headroom under the 10 ms gate that the shadow may spend, per pairing (item 2's figures, `docs/plans/counter-asic-3-derivation.md` section 0, bdc07d3, steady / worst cold; the derivation and the shadow are paid by the same verifier on the same unit): + +| Pairing | Headroom, M5 Max core (steady / worst cold) | Shadow instrs per hash that fit on the M5 Max core | Ops per hash | Headroom, 2019-class core (approximate) | Shadow instrs that fit on the 2019-class core | Ops per hash | +|---|---|---|---|---|---|---| +| x8 (class v3) + shadow | 7.9 / 7.8 ms | 2.4 million | 4.5 million | 4.8 / 4.6 ms | 575,000 | 1.05 million | +| dr368 + shadow | 7.3 / 7.1 | 2.2 million | 4.1 million | 3.3 / 2.8 | 350,000 | 640,000 | +| dr736 + shadow | 5.1 / 4.8 | 1.5 million | 2.7 million | none (dr736 alone is 12 ms on that core) | 0 | 0 | + +So the verifier does not bind the shadow at any N on the ladder in any pairing where the derivation itself fits the gate: 330,700 ops per hash costs 0.56 ms on the M5 Max core and about 1.4 ms on the 2019-class core, which is 12 to 30 percent of the headroom. The binding constraint on N is the honest cards' compute (section 3 for the M5 Max, section 5 for the 5090), not the node. The measured rows: x8 + sh256x88 2.62 ms steady, 2.77 worst cold on the M5 Max core, about 6.5 and 6.9 ms on a 2019-class core by the 2.5x rule; dr736 + sh256x88 about 5.5 ms on the M5 Max core (4.9 + 0.56). The 2019-class core itself is unmeasured (O-1.14); the 2.5x rule stands in for it. + +## 5. The RTX 5090 rows (PC 2, 1ccfe586) + +PENDING the PC 2 job `run-ca3-shadow-pc2-20261006` (`tools/ca3-shadow/pc2-shadow-bench.ps1`, published after `/tmp/igneum-devnet/pc2-ca3.clear` under the mkdir lock; the fetch job `fetch-ca3-shadow-20261006` carries the ten packs). The job: `--stop-miners`, the prover off for the run and back on at the end, the card confirmed empty by nvidia-smi's compute-apps list, the installed `igneum-worker-cuda.exe` (NVRTC, the packs' own text) with `--bench --batches 250 --batch-log2 24 --block-warps 1` on every pack, the control first and last, `--block-warps 8` on the control and two rungs, `nvidia-smi -l 1` sampling power.draw, utilization.gpu, clocks.sm, clocks.mem and temperature every second with the per-pack mean over the bench's own window; then the core-clock rows. The rows land here with the closing report. + +Power caps. The brief asked for `nvidia-smi -pl 200, 250` and the default. The 5 October sweep on this card (`docs/plans/counter-asic-2-status.md` "22:16 the 5090 power-limit sweep", relay #224, 22:09 to 22:15Z on PC 2, corrected in `counter-asic-2-rollout.md` 7b) already carries the cap rows at the current program length: + +| Cap | Limit W | Draw W | MH/s (the app's API) | MH/W | SM MHz | +|---|---|---|---|---|---| +| 100% | 575 | 316.2 | 115.42 | 0.365 | 3,051 | +| 80% | 460 | 316.1 | 115.60 | 0.366 | 3,050 | +| 65% | 400 (the floor) | 310.6 | 114.46 | 0.369 | 3,051 | +| 50% | 400 (clamped) | 302.4 | 109.20 | 0.361 | 3,050 | + +Reading: the card draws 302 to 316 W under this program whatever the cap, `power.min_limit` is 400 W, so `-pl 200` and `-pl 250` cannot be set on a 5090 and the cap never binds at the hash. Those rows are re-used, not re-run. The lever that can move the watts is the core clock, and the job carries `nvidia-smi -lgc 0,` at the Ember plan's four caps (2,781 / 2,472 / 2,163 / 1,854 MHz, `docs/plans/ember-tune.md`), about 75 s each, at the control and at sh256x88, with `-rgc` in a finally block; if nvidia-smi refuses the lock the rows are OWED and the job does not try to gain rights. Ember Tune's own 5090 steps did not run (its second engine never mined; re-run pending the project lead); its idle readbacks on PC 1: 90.6 W idle, 2,505 MHz core, 14,001 MHz memory, limit 450 of 575 W. + +The item 1 denominator moves: the 5090 at the hash alone is about 290 W (p95 290, max 295 W at 124 MH/s in the app, the 5 October record on branch miner-eff), not 326 W, so 2.34 microjoules per hash, and the `f = 1` rows of section 5.4 read 5.0x on GDDR7 (was 5.1x), 7.3x on one HBM3 stack (was 7.5x), 8.9x on eight (was 9.2x): a 2 to 3 percent move. The job's own watts at the hash replace this when they land. + +## 6. The chip side, re-evaluated (approximate) + +The `f = 1` chip of chip-model-v3.md section 5.4, at the memory's activate ceiling: GDDR7 (16 devices) 166.4 MH/s at 0.466 microjoules per hash, one HBM3 stack 83.6 MH/s at 0.321, eight stacks 0.262; those are memory, static and controller only. With the shadow the chip adds a core that runs the per-epoch random block at `k` times the GPU's marginal energy per op; the model's 5.5 pJ (section 5.7) is kept as the unit, and the measured marginal figures of section 3 (6 to 8 pJ on the M5 Max at the useful N) say it is the right order. Three columns: `k = 1` (a chip core as good as the GPU's ALU on a random program: RandomX's argument and the project lead's test), `k = 1.5` (1.5x worse), and `k = 0.3` (a wide-SIMD fixed-datapath array at N5: the int32 datapath energy of section 5.1, 0.06 pJ per add and 0.52 per multiply at the op mix's 29 percent multiplies is 0.19 pJ, with a 2x pipeline overhead and about 4x for the register file, operand wires and the shared instruction fetch over a wide SIMD row, approximate; the floor a chip maker would claim). Section 5.7's "k = 1.5" column was computed as the chip being 1.5x BETTER (0.83 at N = 100,000 is 0.466 + 0.55 / 1.5); the column below computes it as written, 1.5x worse. Energy per hash = memory + N x 5.5 pJ x k. + +ALU silicon for the core, at the 5090's 45.2 T op/s (what N = 330,700 at 136.1 MH/s needs): 22,600 32-bit lanes at 2.0 GHz. At N5 an int32 multiply-add lane with its register-file slice is about 0.002 mm^2 (approximate: 3,000 to 6,000 gates at about 0.3 square microns per NAND2-equivalent plus registers), so about 45 mm^2 of datapath, 60 to 100 mm^2 with SIMD control and operand networks, $25 to $40 of silicon at the sram-mirror.md yield model ($20,000 wafer, about $0.36 per mm^2 on a 128 mm^2 die; section 5 of that file); at 28 nm the same lanes are about 8x the area, 360 mm^2 of datapath and 500 mm^2 or more with control, a reticle-class die that a $5M to $30M controller project does not carry. Watts for the core: at `k = 1` 5.5 pJ x 45.2 T = 249 W (the GPU's own marginal power), at `k = 0.3` 75 W, at `k = 1.5` 373 W. So at N = 330,700 the chip is a memory controller plus a GPU-class ALU array at 250 W on an advanced node, which is the brief's test in numbers; at N = 100,000 the array is a third of that (14,000 lanes, about 30 mm^2 at N5, 75 W at `k = 1`). + +Gain per joule against the honest cards, chip energy = memory + N x 5.5 pJ x k, N in counted ops: + +| N ops per hash | Card microjoules: M5 Max (GPU + DRAM) / 5090 | Chip, GDDR7, k = 1 / 1.5 / 0.3 | Gain per joule, GDDR7, against the M5 Max, k = 1 / 1.5 / 0.3 | Against the 5090 (section 5.7's linear watts until the job's rows land) | Chip, one HBM3 stack, k = 1 / 1.5 / 0.3 | Gain, HBM3, against the M5 Max | Against the 5090 (model) | +|---|---|---|---|---|---|---|---| +| 930 (today) | 0.78 / 2.34 (measured, 290 W) | 0.47 | 1.7x | 5.0x | 0.33 | 2.4x | 7.3x | +| 49,700 (sh256x13) | 1.16 / about 2.45 (333 W, model) | 0.74 / 0.88 / 0.55 | 1.6x / 1.3x / 2.1x | 3.3x / 2.8x / 4.5x | 0.59 / 0.73 / 0.40 | 2.0x / 1.6x / 2.9x | 4.2x / 3.4x / 6.1x | +| 102,100 (sh256x27) | 1.40 / about 2.78 (378 W, model) | 1.03 / 1.31 / 0.63 | 1.4x / 1.1x / 2.2x | 2.7x / 2.1x / 4.4x | 0.88 / 1.16 / 0.49 | 1.6x / 1.2x / 2.9x | 3.2x / 2.4x / 5.7x | +| 199,600 (sh256x53; the M5 Max is 10 percent down here) | 1.58 / about 3.40 (462 W, model) | 1.56 / 2.11 / 0.80 | 1.0x / 0.75x / 2.0x | 2.2x / 1.6x / 4.3x | 1.42 / 1.97 / 0.65 | 1.1x / 0.80x / 2.4x | 2.4x / 1.7x / 5.2x | +| 330,700 (sh256x88; the M5 Max is 21 percent down) | 1.88 / about 4.22 (575 W, model) | 2.29 / 3.19 / 1.01 | 0.82x / 0.59x / 1.9x | 1.8x / 1.3x / 4.2x | 2.14 / 3.05 / 0.87 | 0.88x / 0.61x / 2.2x | 2.0x / 1.4x / 4.9x | + +Reading: the lever works exactly as far as `k` is near 1. At N = 100,000 the chip's edge over the M5 Max is 1.4x at `k = 1` and 1.1x at `k = 1.5`, and over the 5090 (model watts) 2.7x and 2.1x; at `k = 0.3` the edge barely moves at any N (2.2x and 4.4x), because a fixed-datapath array runs the block for a third of the card's marginal energy and the memory row stays the same. The number that decides the verdict is therefore `k`: the energy per op of a chip core that executes a per-epoch random integer program with a 32-lane shuffle, divided by a GPU's marginal 5.5 to 7 pJ. Measured on the cards: the M5 Max pays 6.9 pJ per counted op at 100,000 and 2.9 at its compute-bound end; the 5090's figure is the job's. RandomX's argument (and the precedent: no RandomX chip has beaten a CPU per joule) is that a general core cannot reach `k` under about 0.5 on a random program; nothing in this file measures a chip, so the `k = 0.3` column is the attacker's claim and the `k = 1` column ours. + +## 7. The gates a class v4 candidate would need + +The six gates of `docs/plans/counter-asic-2-rollout.md` section 7 plus the verifier on a 2019-class core (O-1.14), with the state today: + +| Gate | State on the shadow class | What closes it | +|---|---|---| +| G1 bit-exact on all three vendors against the Mac reference | Metal GREEN on ten packs (3 of 3 vectors standalone and in batch, cache and dataset PASS, fingerprints above); CUDA PENDING the PC 2 job (the worker's self-test runs the vectors through the bound kernel and prints the 2^24 fingerprint); AMD OWED (PC 1) | the PC 2 closing report; a PC 1 job on the 9070 XT (the OpenCL kernels are emitted) | +| G2 the CPU verifier exact on 1,000 random hashes per card | not run: the evidence is the 96 vectors and the 2^24 fingerprint per pack on Metal | a serve-mode job per card as in 2.0 | +| G3 the generator soundness suite green | `cargo test` 54 + 4 + 19 + 7 green with the new test; the Metal fuzz, edge, stats and determinism runs were NOT run on the shadow class | those four runs at the chosen S and R | +| G4 the fast-time 3-node network across an activation | not run (no node change exists: the class is a `LoadClass` field, and the chain's `V3_CLASS` does not set it) | the node seam for v4 (`program_class_v4_activation_daa`) and the run | +| G5 the PC-built Windows workers and the Mac workers from the same commit | not applicable yet (no worker change: the workers run the packs' own text) | the release step | +| G6 the node change on a fork branch with suites green on PC 2 | not applicable yet | the v4 seam | +| O-1.14 the verifier on a 2019-class core | by the 2.5x rule every rung fits with x8 (6.9 ms worst cold at 330,700 ops); the core itself is unmeasured | one run on such a core | +| Spec text | none written (no PROPOSED entry until the rows are complete); the block would be a class v4 field beside the class v3 ones in 1.4 and 1.7, the acceptance rule's treatment of the block decided (section 2) | the v4 proposal after the 5090 and AMD rows | + +## 8. Consequences per tier + +A longer program costs the card watts and nothing else while the card stays latency-bound; past its bind point it costs hash rate. Income per pound of card is unchanged while the rate holds; income per watt falls by the watts ratio. The numbers are this file's; the 5090's are the model's until the job lands, and the AMD row is the budget's. + +| Tier | At N = 100,000 ops per hash (sh256x27, the candidate) | At N = 200,000 | At N = 331,000 (the 5090's full budget) | What is being done | +|---|---|---|---|---| +| Apple user (M-series laptop or desktop; M5 Max measured) | rate -1.5%, GPU + DRAM 21 to 37 W (+16 W; a laptop on battery feels it), income per watt 0.56x, per pound 0.99x | rate -10%, 38 W; per watt 0.49x, per pound 0.90x | rate -21%, 40 W; per watt 0.41x, per pound 0.79x | the project's N is capped by this card: no more than 130,000 ops (the 5 percent rule), 100,000 recommended | +| NVIDIA, one 24 or 32 GB card (5090 class) | model: rate holds, about 290 to 378 W (+30%); per watt 0.77x, per pound 1.0x | about 462 W; per watt 0.63x | compute-bound at 136 MH/s, 575 W; per watt 0.50x | the PC 2 job measures the rate, the watts and the clock caps; the per-watt loss is the price of the lever and is reported, not hidden | +| NVIDIA, one 8, 12 or 16 GB card | the same shape per card: the ALU budget scales with the SM count, so a 4070-class card (about 30 T op/s, approximate) binds near 200,000 ops at its rate; at 100,000 it holds | a 4060-class card (about 15 T op/s) binds near 100,000 | | no card we own is in this tier; the ladder runs on any CUDA card through the same job | +| AMD, one 16 GB card (RX 9070 XT) | OWED: the budget (about 650,000 ops, approximate, section 5.7) says it holds at 100,000 and at 200,000; its watts at the hash are unmeasured | | | the PC 1 job when the desk is free; the OpenCL kernels are in every pack | +| A rig | per card as above; a rig's bill is watts, so at 100,000 ops a 5090 rig pays about 30 percent more electricity for the same hash (model) | | | the recommended N is the smallest that moves the chip row; the rig pays it only if class v4 is adopted | +| A pool user | nothing changes in shares or payout: the hash rate holds at the recommended N on every card measured | | | | +| A chip | must add a 14,000-lane ALU array at N = 100,000 (about 30 mm^2 at N5, 75 W at `k = 1`) and a 22,600-lane array at 331,000 (60 to 100 mm^2, 250 W); its per-joule edge over the 5090 falls from 5.0x to 2.7x at 100,000 and `k = 1` (model watts), over the M5 Max from 1.7x to 1.4x | | | the `k` question goes to the external cryptanalysis and chip review (item 3): can a core run a random 32-lane program under half a GPU's marginal energy per op | +| The public claim | the honest M5 Max is 1.7x from the `f = 1` GDDR7 chip per joule at N = 0 by these channels, the 5090 5.0x; at N = 100,000 and `k = 1` they read 1.4x and 2.7x (model) | | | nothing on the site changes from this file | + +The N the project should pick, by the 2.0 rule (no card we own loses more than 5 percent): 100,000 ops per hash, `S = 256`, `R = 27` (55,296 shadow instructions per hash), subject to the 5090 row holding within 5 percent in the job and the 9070 XT row when PC 1 is free; the M5 Max's ceiling is 130,000. The block size is 64 to 256 instructions, never 1,024. + +## 9. Unverified and owed + +- The RTX 5090 rows (hash rate, watts, clock caps, the CUDA fingerprints): the PC 2 job, section 5. +- The RX 9070 XT rows: OWED (PC 1 not released today). +- The Mac watts are the IOReport GPU and DRAM channels (no root, the private IOReport library through dlopen), not powermetrics and not the package; Ember Tune's 38 W package figure is approximate and from another session. +- The ops count (1.83 per ALU instruction) is a convention counted from the emitted statements; the vendors' real cost per op differs (item 6's step ratios), which is why the rows carry instructions and watts, not ops alone. +- The chip side is arithmetic: the 5.5 pJ unit, the `k` columns, the lane area and the 28 nm scaling are approximate; no chip was measured, and the `k = 0.3` floor is an estimate of what a fixed-datapath array could claim. +- The acceptance rule does not run the block; whether a class v4 should make it is a design decision with the cost stated in section 2. +- The 2019-class core is unmeasured (O-1.14); the 2.5x rule stands in. +- The Metal fuzz, edge, stats and determinism runs were not made on the shadow class (gate G3 is the crate suite only). diff --git a/docs/bench-log.md b/docs/bench-log.md index 85997dca6..27dddbb38 100644 --- a/docs/bench-log.md +++ b/docs/bench-log.md @@ -1961,3 +1961,30 @@ Ten distinct programs (seed strings `igneum-devnet-v4-epoch0`, `/epoch1` .. `/ep Cache fill 1.95 ms GPU (192.4 ms one core), dataset build 20.8 ms GPU for 1 GiB. The devnet pack three times through `packbench --pack ../proto-cuda/packs/igneum-devnet-v4-epoch0 --batches 1 --batch-log2 20 --group 256` (the pack's two libraries, `memhard.metal` and `program.metal`): compile 79 ms, 1 ms, 1 ms (the system shader cache answers the identical source from the second run); cache fill 0.6 to 0.7 ms GPU, dataset build 20.7 to 20.8 ms GPU. Reading: a fresh program compiles in about 18 ms on this card with the Metal compiler service warm, 79 ms for a pack with its dataset kernels, up to 1.8 s cold (the variant-racing entry's first seed), 0 to 444 ms at the fleet's live boundaries (M11). The hot table fill of layer 5 is 0.07 to 0.22 ms (ca2-cache). So the Mac's per-epoch compile-ahead is under 2 s without the race and about 38 s with it (M11: 34.0 / 34.9 / 37.8 s), and the race is the only item visible against the 600-s window in which the program is known (lead 1,200 s minus the 600-s VDF, fixed at every epoch length). PC cards, cited in the plan: RTX 5090 NVRTC 151 to 180 ms, prepare 0.5 to 1.0 s without the dataset (M11), race one round about 37 s; RX 9070 XT OpenCL compile NOT MEASURED at the current worker (owed: `host.c` times `clBuildProgram` only in the `prepare` path and no `prepared` line from gfx1201 is in any upload); Intel UHD build 3.0 to 6.4 s (M11). Floor by the rule (slowest compile-ahead under 10% of the epoch and inside the window, dataset excluded): 600 DAA s, carried by the race at 6.3% of 600 s; with the race off (M11 found base wins on both the 5090 and the Mac) the slowest measured row is the Intel iGPU at 1.1%. Consequences per tier and the difficulty-settle constraint (24% of a 600-s epoch in settle at the measured 144 s) are in the plan. + +## 6 October 2026, Counter ASIC 3.0 item 8: program work in the latency shadow + +Branch `ca3-shadow`, worker "shadow" (`docs/analysis/latency-shadow-2026-10-06.md` carries the design, the chip side and the consequences; this entry carries the measurements). The knob: `LoadClass::shadow`, class name `+shx`, a block of `S` ALU instructions drawn from the program stream after the 64 base instructions and run `R` times at the end of every iteration (no load; the base program, its attempt and the acceptance verdict are the class's without the shadow; v2 and v3 byte-identical, `cargo test` in igneum-pow 54 + 4 + 19 + 7 green). Packs `proto-cuda/packs-ca3-shadow/*` over `mx8` for seed igneum-genesis; the control is the pinned class v3 pack `packs-ca2-mixer/mx8-genesis`. Ops per hash = shadow instructions x 1.83 (counted from the emitted statements: add 5, rotr 2, shfl 2, the rest 1, weighted over the non-load weights) + 930 (the base program's 384 ALU instructions and 128 loads). + +**Apple M5 Max, Metal** (`proto-metal/packbench --pack --batches 60 --batch-log2 24 --group 256` under `with-lock.sh measure`, two sessions 07:51 to 08:03 UTC, GPU time; power = the IOReport "Energy Model" `GPU` and `DRAM` channels at 2 Hz through a dlopen of libIOReport, no root, the mean over each run after its first 6 s; idle GPU 0.44 W, DRAM 0.64 W; the package is about 17 W more, Ember Tune's 38 W row, approximate; load averages 3.3 to 6.8, the GPU idle: the Mac mines nothing): + +| Pack | Shadow instrs per hash | Ops per hash | MH/s | Against the control | GPU W | DRAM W | Microjoules per hash (GPU + DRAM) | Verifier ms per warp, one core, avg of 20 (worst cold) | Bit-exact, fingerprint 2^24 | Load at start | +|---|---|---|---|---|---|---|---|---|---|---| +| mx8-genesis (control; runs 1, 2, 3) | 0 | 930 | 27.07, 27.07, 27.10 | | 11.2, 9.2, 12.3 | 10.2, 10.0, 10.2 | 0.78 | 2.062 (2.188) | yes, 7c28cfb06c5c65a9 | 4.6, 6.8, 4.2 | +| sh256x2 | 4,096 | 8,400 | 26.85 | -0.8% | 15.1 | 10.4 | 0.95 | 2.080 (2.249) | yes, 33e8bbe4c35b2e54 | 4.6 | +| sh256x7 | 14,336 | 27,200 | 26.74 | -1.3% | 18.0 | 10.6 | 1.07 | 2.112 (2.224) | yes, 6cfb70911007520a | 4.2 | +| sh256x13 | 26,624 | 49,700 | 26.75 | -1.2% | 20.6 | 10.5 | 1.16 | 2.212 (2.237) | yes, 59ac286fe2a5a9ef | 3.7 | +| sh64x52 (64-instruction block; runs 1, 2) | 26,624 | 49,700 | 27.72, 27.79 | +2.5% | 19.8, 20.3 | 10.2, 10.3 | 1.09 | 2.137 (2.237) | yes, 9dd010f79d8ca9f4 | 4.4, 4.1 | +| sh1024x3 (1,024-instruction block) | 24,576 | 45,900 | 22.53 | -16.8% | 20.2 | 9.7 | 1.33 | 2.150 (2.274) | yes, a05399c819b79aad | 6.0 | +| sh256x27 (runs 1, 2) | 55,296 | 102,100 | 26.48, 26.86 | -1.5% | 26.9, 26.9 | 10.4, 10.2 | 1.40 | 2.229 (2.276) | yes, 3d2e8245cc084d07 | 3.3, 5.6 | +| sh256x40 | 81,920 | 150,800 | 25.10 | -7.3% | 26.7 | 10.1 | 1.46 | 2.329 (2.396) | yes, 0844b706302f1c9c | 5.0 | +| sh256x53 (runs 1, 2) | 108,544 | 199,600 | 24.40, 24.09 | -10.4% | 28.8, 28.5 | 9.5, 9.7 | 1.58 | 2.427 (2.461) | yes, 4f824b15cf2b124a | 3.9, 4.6 | +| sh256x88 | 180,224 | 330,700 | 21.39 | -21.0% | 31.7 | 8.4 | 1.88 | 2.619 (2.771) | yes, 0572522e39a94d8a | 3.8 | + +Reading: the M5 Max stays latency-bound to about 100,000 ops per hash and its 5 percent point is about 130,000 (between the 102,100 and 150,800 rungs), 2.2x under the chip model's 290,000 (from memory); the block size matters on Apple (64 instructions +2.5 percent, 256 holds, 1,024 costs 17 percent at the same N: the instruction footprint); the GPU rises from 11 to 27 W at 100,000 ops (marginal 6.9 pJ per counted op; 2.9 pJ at the compute-bound end) and the energy per hash from 0.78 to 1.40 microjoules, GPU plus DRAM. The verifier's law on this core: 2.06 ms + 3.2 microseconds per 1,000 shadow instructions per warp (0.1 ns per lane-instruction), so 330,700 ops cost 0.56 ms here and about 1.4 ms on a 2019-class core by the 2.5x rule: inside every pairing's headroom (x8 7.8 / 4.6 ms, dr368 7.1 / 2.8, dr736 5.1 / none, M5 Max / 2019-class, item 2's figures), so the node never binds the shadow before the cards do. The control is 2.5 percent under the 5 October figure for this pack (27.7, mixer-x4.md 6.2) on three runs; every row is read against today's 27.08. + +**RTX 5090 (PC 2, 1ccfe586), CUDA**: PENDING the PC 2 job `run-ca3-shadow-pc2-20261006` (`tools/ca3-shadow/pc2-shadow-bench.ps1`, after `/tmp/igneum-devnet/pc2-ca3.clear` under the mkdir lock): the same ladder through the installed worker's `--bench` with `nvidia-smi -l 1` sampling, and the core-clock rows at 2,781 / 2,472 / 2,163 / 1,854 MHz (`-lgc`, `-rgc` in a finally; OWED if the lock needs rights the job does not have). The power-cap rows are the 5 October sweep's (counter-asic-2-status.md 22:16: 302 to 316 W at every cap, floor 400 W, so `-pl 200` and `250` cannot be set and the cap never binds at the hash); the card at the hash alone is about 290 W (miner-eff record), 2.34 microjoules per hash at 124 MH/s in the app. + +**RX 9070 XT (PC 1, ae432dc7)**: OWED (PC 1 is the project lead's desk and not released today); the OpenCL kernels are in every pack. + +Consequences per tier (the file's section 8 in short): at the recommended N = 100,000 ops per hash (`sh256x27`) the Apple card loses 1.5 percent of its rate and pays 16 W more (income per watt 0.56x, per pound unchanged), the 5090 by the model holds its rate at about 378 W (per watt 0.77x; the job measures it), the 9070 XT holds by its budget (owed), a rig pays about 30 percent more electricity for the same hash, a pool user sees nothing, and the `f = 1` chip's edge per joule falls from 1.7x to 1.4x against the M5 Max and from 5.0x to 2.7x against the 5090 (model watts) at `k = 1`, where `k` is the chip core's energy per op over the GPU's marginal 5.5 pJ: the number that decides the item. No card we own may lose more than 5 percent (the 2.0 rule): the M5 Max caps N at 130,000. diff --git a/tools/ca3-shadow/pc2-shadow-bench.ps1 b/tools/ca3-shadow/pc2-shadow-bench.ps1 index fcc2f27c7..6fca93bfc 100644 --- a/tools/ca3-shadow/pc2-shadow-bench.ps1 +++ b/tools/ca3-shadow/pc2-shadow-bench.ps1 @@ -5,12 +5,13 @@ # tools/prover-floor/pc2-floor-measure.ps1 does), confirms the card is empty by nvidia-smi's compute-apps list (never # api/state, which answers {} on this machine), then runs the INSTALLED igneum-worker-cuda.exe (NVRTC, the pack's own # kernel text) with --bench on every pack of the fetched kit (fetch job fetch-ca3-shadow-20261006: the class v3 control -# mx8-genesis and the shadow ladder sh256x2 .. sh256x88, sh64x52, sh1024x3) while `nvidia-smi -l 1` samples +# mx8-genesis, run first and last, and the shadow ladder sh256x2 .. sh256x88, sh64x52, sh1024x3) while `nvidia-smi -l 1` samples # power.draw, utilization.gpu, clocks.sm, clocks.mem and temperature every second into a file. Every number is a RESULT # line: the worker's own lines (vectors, fingerprint, MH/s), and per pack the mean, min and max power, the mean # utilisation and clocks over the bench's own window (the timed dispatches), plus every raw sample. No power cap is set # (the 5 October sweep on this card, counter-asic-2-status.md 22:16, showed the cap never binds above the 400 W floor and -# -pl 200 / 250 are below power.min_limit); nothing elevated. Read back with `node tools/jobs.mjs `. +# -pl 200 / 250 are below power.min_limit); the core clock is locked for the clock rows only if nvidia-smi allows it +# unprompted (else OWED); nothing elevated. Read back with `node tools/jobs.mjs `. $ErrorActionPreference = 'Continue' function Stamp { (Get-Date).ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ssZ') } $urlFile = if ($env:IGNEUM_APP_DIR) { Join-Path $env:IGNEUM_APP_DIR 'app.url' } else { Join-Path $env:LOCALAPPDATA 'igneum\app\app.url' } @@ -45,7 +46,7 @@ if (-not $smiExe) { $smiExe = Join-Path $env:SystemRoot 'System32\nvidia-smi.exe $sampler = Start-Process -FilePath $smiExe -ArgumentList @('--query-gpu=timestamp,power.draw,utilization.gpu,clocks.sm,clocks.mem,temperature.gpu,memory.used', '--format=csv,noheader,nounits', '-l', '1') -RedirectStandardOutput $samples -NoNewWindow -PassThru Start-Sleep -Seconds 5 $windows = @() -$order = @('mx8-genesis', 'sh256x2', 'sh256x7', 'sh256x13', 'sh256x27', 'sh256x53', 'sh256x88', 'sh64x52', 'sh1024x3') +$order = @('mx8-genesis', 'sh256x2', 'sh256x7', 'sh256x13', 'sh256x27', 'sh256x40', 'sh256x53', 'sh256x88', 'sh64x52', 'sh1024x3', 'mx8-genesis') try { "RESULT idle $(Stamp) 10 s before the first bench: $(Smi 'power.draw,utilization.gpu,clocks.sm,clocks.mem')" Start-Sleep -Seconds 10 @@ -60,11 +61,39 @@ try { & $exe --bench --pack $d --batches $batches --batch-log2 24 --block-warps $bw 2>&1 | ForEach-Object { "RESULT bench $pk bw$bw $_" } $t1 = Get-Date "RESULT bench $pk bw$bw end $(Stamp) exit=$LASTEXITCODE wall_s=$([int]($t1 - $t0).TotalSeconds)" - $windows += [pscustomobject]@{ pack = $pk; bw = $bw; t0 = $t0; t1 = $t1 } + $windows += [pscustomobject]@{ pack = $pk; bw = "bw$bw"; t0 = $t0; t1 = $t1 } + if ($pk -eq 'mx8-genesis' -and $bw -eq 1 -and $windows.Count -gt 2) { break } + Start-Sleep -Seconds 3 + } + } + # the core-clock rows (coordinator, 6 October 2026 08:0x UTC): the 5 October sweep showed `-pl` cannot bind on this kernel + # (the card draws about 290 to 316 W under a 400 W floor), so the lever that can move the watts is the core clock. Four + # caps of the Ember plan, at the control and at the largest N that fits the verifier gate, about 75 s each. If + # nvidia-smi refuses the lock (it needs administrator rights this job does not have and must not ask for), the rows + # are OWED and nothing else is tried; -rgc runs in the finally block whatever happens. + $clockOk = $true + foreach ($pk in @('mx8-genesis', 'sh256x88')) { + if (-not $clockOk) { break } + $d = Join-Path $packs $pk + if (-not (Test-Path $d)) { continue } + foreach ($mhz in @(2781, 2472, 2163, 1854)) { + $r = (& nvidia-smi -i 0 -lgc 0,$mhz 2>&1 | Out-String).Trim() + "RESULT clock $pk $mhz lgc: $($r -replace "`r?`n", ' | ')" + if ($r -match 'Insufficient|[Pp]ermission|denied|administrator|not supported|Unknown Error|No such') { "RESULT clock OWED: nvidia-smi -lgc refused ($mhz MHz); the rows need rights this job does not have and does not ask for"; $clockOk = $false; break } + Start-Sleep -Seconds 3 + "RESULT clock $pk $mhz readback: $(Smi 'clocks.sm,clocks.max.sm,clocks.mem,power.draw,power.limit')" + $t0 = Get-Date + "RESULT bench $pk clk$mhz start $(Stamp)" + & $exe --bench --pack $d --batches 600 --batch-log2 24 --block-warps 1 2>&1 | ForEach-Object { "RESULT bench $pk clk$mhz $_" } + $t1 = Get-Date + "RESULT bench $pk clk$mhz end $(Stamp) exit=$LASTEXITCODE wall_s=$([int]($t1 - $t0).TotalSeconds)" + $windows += [pscustomobject]@{ pack = $pk; bw = "clk$mhz"; t0 = $t0; t1 = $t1 } Start-Sleep -Seconds 3 } } } finally { + $r = (& nvidia-smi -i 0 -rgc 2>&1 | Out-String).Trim() + "RESULT clock reset rgc: $($r -replace "`r?`n", ' | ') readback: $(Smi 'clocks.sm,clocks.max.sm,power.limit')" Start-Sleep -Seconds 2 try { Stop-Process -Id $sampler.Id -Force -ErrorAction SilentlyContinue } catch { } Start-Sleep -Seconds 1 @@ -88,8 +117,8 @@ foreach ($win in $windows) { $s = ($in | Measure-Object -Property sm -Average).Average $m = ($in | Measure-Object -Property mem -Average).Average $tp = ($in | Measure-Object -Property temp -Maximum).Maximum - "RESULT power $($win.pack) bw$($win.bw) samples=$($in.Count) watts_mean=$([math]::Round($w.Average, 1)) watts_min=$($w.Minimum) watts_max=$($w.Maximum) util_mean=$([math]::Round($u, 1)) sm_mhz_mean=$([math]::Round($s)) mem_mhz_mean=$([math]::Round($m)) temp_max=$tp window_s=$([int]($win.t1 - $win.t0).TotalSeconds)" - } else { "RESULT power $($win.pack) bw$($win.bw) no samples in window" } + "RESULT power $($win.pack) $($win.bw) samples=$($in.Count) watts_mean=$([math]::Round($w.Average, 1)) watts_min=$($w.Minimum) watts_max=$($w.Maximum) util_mean=$([math]::Round($u, 1)) sm_mhz_mean=$([math]::Round($s)) mem_mhz_mean=$([math]::Round($m)) temp_max=$tp window_s=$([int]($win.t1 - $win.t0).TotalSeconds)" + } else { "RESULT power $($win.pack) $($win.bw) no samples in window" } } foreach ($r in $rows) { "RESULT sample $($r.ts.ToString('HH:mm:ss')) $($r.w) $($r.util) $($r.sm) $($r.mem) $($r.temp) $($r.used)" } "RESULT gpus_after $(Stamp) $(Smi 'power.draw,power.limit,clocks.sm,clocks.mem,temperature.gpu,memory.used')"