diff --git a/igneum-census/src/main.rs b/igneum-census/src/main.rs index bd7955ef..171c4300 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 7cb1ceed..aa36e3fc 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 5201d950..1842211b 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 cf82ab76..9d9053c2 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 91f9ee31..4b22630c 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 acf376d1..0fe68a9b 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 00000000..8f07f1b0 --- /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 00000000..6f0bbdbf --- /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 00000000..525259b1 --- /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 00000000..1f6c9d3d --- /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 00000000..f7f34c73 --- /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 00000000..01b263d6 --- /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 00000000..6722cd82 --- /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 00000000..48e5456a --- /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 00000000..369b7218 --- /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 00000000..253a2f53 --- /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 00000000..02862f19 --- /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 00000000..2140a29b --- /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 00000000..e1be8bee --- /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 00000000..b0a692f8 --- /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 00000000..857b927e --- /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 00000000..905e4625 --- /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 00000000..f7f34c73 --- /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 00000000..01b263d6 --- /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 00000000..ab3bd0b7 --- /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 00000000..6042bbe0 --- /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 00000000..6a17edfd --- /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 00000000..c089f880 --- /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 00000000..c1adcfec --- /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 00000000..b3562c1e --- /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 00000000..8d5ca53a --- /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 00000000..c56c8d00 --- /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 00000000..b98be4e5 --- /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 00000000..a21c9963 --- /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 00000000..f7f34c73 --- /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 00000000..01b263d6 --- /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 00000000..a0562122 --- /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 00000000..f614ebbe --- /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 00000000..654862e0 --- /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 00000000..976bdef5 --- /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 00000000..aac6ba40 --- /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 00000000..e6516b9d --- /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 00000000..72f7ca4d --- /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 00000000..62d29f6f --- /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 00000000..02546cd0 --- /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 00000000..4a823531 --- /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 00000000..f7f34c73 --- /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 00000000..01b263d6 --- /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 00000000..e1c873c4 --- /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 00000000..8588e0fe --- /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 00000000..2830702a --- /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 00000000..7a8da2d3 --- /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 00000000..17ce4460 --- /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 00000000..c481669b --- /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 00000000..776a24c7 --- /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 00000000..41461c8d --- /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 00000000..a4c31920 --- /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 00000000..3d97c4ee --- /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 00000000..f7f34c73 --- /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 00000000..01b263d6 --- /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 00000000..6f06c96e --- /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 00000000..91c8f62b --- /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 00000000..aef8058f --- /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 00000000..662225c5 --- /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 00000000..aa6a964a --- /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 00000000..8fb6681f --- /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 00000000..cbc5d4b1 --- /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 00000000..722d8790 --- /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 00000000..3dda5afe --- /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 00000000..a9862303 --- /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 00000000..f7f34c73 --- /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 00000000..01b263d6 --- /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 00000000..5e033c0a --- /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 00000000..4fb00e83 --- /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 00000000..38e5b41d --- /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 00000000..f26665ab --- /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 00000000..df08f36e --- /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 00000000..0023718d --- /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 00000000..29c0bf35 --- /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 00000000..2da273cf --- /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 00000000..90a79d33 --- /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 00000000..8be9979c --- /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 00000000..f7f34c73 --- /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 00000000..01b263d6 --- /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 00000000..20110e1a --- /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 00000000..8758bb59 --- /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 00000000..42880433 --- /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 00000000..7665e714 --- /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 00000000..90226ded --- /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 00000000..9eac3ef1 --- /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 00000000..389c69a3 --- /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 00000000..04b22904 --- /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 00000000..34d4fea9 --- /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 00000000..00ae080b --- /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 00000000..f7f34c73 --- /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 00000000..01b263d6 --- /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 00000000..7498b246 --- /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 00000000..a3659596 --- /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 00000000..ad068f3b --- /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 00000000..9eac74ef --- /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 00000000..6b2e73d7 --- /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 00000000..e8fe6391 --- /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 00000000..40b5475e --- /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 00000000..9ee835a6 --- /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 00000000..1729c799 --- /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 00000000..f88d7336 --- /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 00000000..f7f34c73 --- /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 00000000..01b263d6 --- /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 00000000..5831b966 --- /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 00000000..8cd722d5 --- /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 00000000..b0864ba6 --- /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 00000000..81de2197 --- /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 00000000..cb195150 --- /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 00000000..b06e81e1 --- /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 00000000..fcc2f27c --- /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