nx_x86_64_module_test.nx source
↩ module page · 53 lines · 1656 B
1// nx_x86_64_module_test.nx -- session 7 prove: module-level emission.
2//
3// Hand-builds a Module with two functions:
4//
5// func answer() -> i64 { return 42 }
6// func main() -> i64 { return answer() }
7//
8// Drives x86ctx_emit_module (which emits both functions + globals
9// dump + _start trampoline + GNU-stack note). Expected exit 42.
10
11import "syscalls.nx"
12import "nx_outbuf.nx"
13import "nx_types.nx"
14import "nx_ir.nx"
15import "nx_x86_64.nx"
16import "nx_x86_64_ctx.nx"
17
18func main() -> i64 {
19 let o: *OutBuf = out_new(8192)
20
21 let m: *Module = ir_module_new("module_test" as *u8)
22 let i64_ty: *Type = ir_type_i64()
23
24 // answer() -> 42
25 let f_answer: *Function = ir_function_new(m, "answer" as *u8, 6, i64_ty)
26 let bb_a: *BasicBlock = ir_block_new(f_answer)
27 let c42: i64 = ir_const_i64(f_answer, 42)
28 ir_emit_return(bb_a, c42)
29
30 // main() -> answer()
31 let f_main: *Function = ir_function_new(m, "main" as *u8, 4, i64_ty)
32 let bb_m: *BasicBlock = ir_block_new(f_main)
33 // ir_emit_call needs explicit construction; use ir_emit_call0
34 // if it exists, else hand-build the Instr.
35
36 // Build the call manually using existing alloc_instr + append_instr.
37 let call_i: *Instr = alloc_instr(f_main, OP_CALL, i64_ty)
38 let call_v: i64 = alloc_value(f_main, VK_INSTR, i64_ty)
39 call_i.result = call_v
40 call_i.n_operands = 0
41 call_i.callee = f_answer
42 append_instr(bb_m, call_i)
43
44 ir_emit_return(bb_m, call_v)
45
46 out_str(o, "# Emitted by nx_x86_64_ctx.nx session 7 (module-level)\n")
47 out_str(o, " .att_syntax prefix\n")
48
49 x86ctx_emit_module(m, o)
50
51 sys_write(1, o.buf, o.pos)
52 return 0
53}