nx_x86_64_ctx_test.nx source
↩ module page · 50 lines · 1471 B
1// nx_x86_64_ctx_test.nx -- session 6 smoke for IR-driven x86_64 codegen.
2//
3// Hand-builds a tiny Function via the nx_ir APIs:
4//
5// func main() -> i64 {
6// return 42
7// }
8//
9// then drives x86ctx_emit_function on it, prints the asm to stdout.
10// The bash wrapper gcc-links + runs the resulting native binary,
11// expects exit code 42.
12
13import "syscalls.nx"
14import "nx_outbuf.nx"
15import "nx_types.nx"
16import "nx_ir.nx"
17import "nx_x86_64.nx"
18import "nx_x86_64_ctx.nx"
19
20func main() -> i64 {
21 let o: *OutBuf = out_new(8192)
22
23 // Build module + function.
24 let m: *Module = ir_module_new("ctx_test" as *u8)
25 let ret_ty: *Type = ir_type_i64()
26 let f: *Function = ir_function_new(m, "main" as *u8, 4, ret_ty)
27 let bb: *BasicBlock = ir_block_new(f)
28 let c42: i64 = ir_const_i64(f, 42)
29 ir_emit_return(bb, c42)
30
31 out_str(o, "# Emitted by nx_x86_64_ctx.nx session 6 (IR-driven)\n")
32 out_str(o, " .att_syntax prefix\n")
33
34 // _start trampoline that calls main and exits with main's return.
35 out_str(o, " .text\n")
36 out_str(o, " .globl _start\n")
37 out_str(o, "_start:\n")
38 out_str(o, " call main\n")
39 out_str(o, " movq %rax, %rdi\n") // exit code = main's return
40 x86_emit_movabsq(o, "rax" as *u8, NX_X64_SYS_EXIT)
41 x86_emit_syscall(o)
42
43 // Drive the IR-driven emitter on our tiny function.
44 x86ctx_emit_function(f, o)
45
46 x86_emit_gnu_stack_note(o)
47
48 sys_write(1, o.buf, o.pos)
49 return 0
50}