code wiki / (root) / nx_smoke_nxc_tilde.nx

nx_smoke_nxc_tilde.nx source

↩ module page · 73 lines · 2850 B

1// nx_smoke_nxc_tilde.nx -- 1:1 proof that the SELF-HOSTED RV64 backend 2// (nx_riscv.nx) lowers `~` (OP_NOT) to `xori rd, rs, -1`. Mirrors 3// nx_smoke_nxc_pipeline.nx but (a) the demo exercises `~` on a non- 4// foldable parameter and (b) it WRITES the emitted RV64 asm to stdout 5// so the gate can grep for the `xori ..., -1` one's-complement and 6// confirm the OP_NOT lowering really fires (not the silent drop that 7// existed before). Then it still assembles, proving nxasm accepts it. 8// 9// exit code: code_len & 0xFF on success (>0), or an error sentinel. 10// license_tier: ORIGINAL 11 12import "nx_syscalls.nx" 13import "nx_types.nx" 14import "nx_lex_kinds.nx" 15import "nx_outbuf.nx" 16import "nx_ir.nx" 17import "nx_tokenizer.nx" 18import "nx_parse.nx" 19import "nx_opt.nx" 20import "nx_regalloc.nx" 21import "nx_riscv.nx" 22import "crt0.nx" 23import "nxasm_v2.nx" 24 25func main() -> i64 { 26 // `~e` on a parameter -> cannot be const-folded -> forces the 27 // backend to actually lower OP_NOT. 28 let demo: *u8 = "func notit(e: i64) -> i64 { return (~e) & 255 } func main() -> i64 { return notit(7) }" 29 30 let toks: *Tok = lex_source(demo, 4096) 31 if toks == (0 as *Tok) { return __syscall(93, 1, 0, 0, 0, 0, 0) } 32 33 let m: *Module = parse_module(toks, 0 as *Module) 34 if m == (0 as *Module) { return __syscall(93, 2, 0, 0, 0, 0, 0) } 35 36 let asm_out: *OutBuf = out_new(131072) 37 emit_crt0_start(asm_out) 38 var fi: i64 = 0 39 while fi < m.n_functions { 40 let fn_base: i64 = m.functions as i64 41 let f: *Function = (fn_base + fi * 176) as *Function 42 opt_run(f) 43 let locs_raw: *u8 = sys_mmap(f.n_values * 24 + 64) 44 let locs: *ValueLoc = locs_raw as *ValueLoc 45 let cs_raw: *u8 = sys_mmap(16) 46 let cs: *i64 = cs_raw as *i64 47 *cs = 0 48 let cs_fpr_raw: *u8 = sys_mmap(16) 49 let cs_fpr: *i64 = cs_fpr_raw as *i64 50 *cs_fpr = 0 51 let sb_raw: *u8 = sys_mmap(16) 52 let sb: *i64 = sb_raw as *i64 53 *sb = 0 54 regalloc_function(f, locs, cs, cs_fpr, sb) 55 let name_addr: i64 = f.name_start 56 let fn_name: *u8 = name_addr as *u8 57 emit_function(f, locs, asm_out, fn_name, 16, 8, *cs, *cs_fpr) 58 fi = fi + 1 59 } 60 61 if asm_out.pos == 0 { return __syscall(93, 100, 0, 0, 0, 0, 0) } 62 63 // 1:1: dump the emitted RV64 asm so the gate can confirm `xori ...,-1`. 64 sys_write(1, asm_out.buf, asm_out.pos) 65 66 let code_buf: *u8 = sys_mmap(65536) 67 let code_len: i64 = assemble(asm_out.buf, asm_out.pos, code_buf, 65536) 68 if code_len == -1 { return __syscall(93, 200, 0, 0, 0, 0, 0) } 69 if code_len == -2 { return __syscall(93, 201, 0, 0, 0, 0, 0) } 70 if code_len == -3 { return __syscall(93, 202, 0, 0, 0, 0, 0) } 71 if code_len == 0 { return __syscall(93, 101, 0, 0, 0, 0, 0) } 72 return __syscall(93, code_len & 0xFF, 0, 0, 0, 0, 0) 73}