code wiki / _hdl_build / nx_selfix.nx
nx_selfix.nx source
↩ module page · 38 lines · 1911 B
1// nx_selfix.nx -- the team SELF-FIXES its diagnosed gap. Last loop it read the competitor's
2// machine code and reported "the generator LACKS: imul". This closes that itself: a strategy
3// TOOLKIT {shift-add chain, imul} with COST-based self-selection. For a constant it tries the
4// chain; if the chain can't reach the constant (a gap) OR the chain's cost (~latency = its
5// instruction count of 1-cycle ops) exceeds imul's ~3-cycle latency, it falls back to imul.
6// So the team now handles EVERY constant, picking the cost-best strategy on its own -- the
7// generator's gaps are closed with the very op it diagnosed it was missing. license_tier: ORIGINAL
8
9import "nx_mulchain.nx" // chain strategy (mulchain_find)
10import "nx_superopt_emit.nx" // se_emit_full (chain) + se_emit_imul_full (imul)
11
12const SFX_CHAIN: i64 = 0
13const SFX_IMUL: i64 = 1
14
15// emit the cost-best strategy for x*c into buf. strat[0] = which was chosen; icnt[0] = its
16// instruction count. returns the emitted length.
17func selfix_emit(c: i64, dd: *i64, nin: i64, buf: *u8, icnt: *i64, strat: *i64) -> i64 {
18 let op: *i64 = sys_mmap(8 * 12) as *i64
19 let a: *i64 = sys_mmap(8 * 12) as *i64
20 let b: *i64 = sys_mmap(8 * 12) as *i64
21 let L: i64 = mulchain_find(c, 4, op, a, b) // a chain > ~3 ops loses to imul on cost
22 var blen: i64 = 0
23 var use_imul: i64 = 0
24 if L == 0 { use_imul = 1 } // chain can't reach it -> imul fallback
25 else {
26 blen = se_emit_full(op, a, b, L, dd, nin, buf, icnt)
27 if icnt[0] > 3 { use_imul = 1 } // chain costs more than imul's 3 -> imul
28 }
29 if use_imul == 1 {
30 blen = se_emit_imul_full(c, dd, nin, buf, icnt)
31 strat[0] = SFX_IMUL
32 } else {
33 strat[0] = SFX_CHAIN
34 }
35 return blen
36}
37
38func sfx_name(s: i64) -> *u8 { if s == SFX_IMUL { return "imul" as *u8 } return "chain" as *u8 }