code wiki / (root) / nx_x86_64_ctx_test.nx

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}