code wiki / (root) / nx_x86_64_arith_test.nx

nx_x86_64_arith_test.nx source

↩ module page · 69 lines · 2356 B

1// nx_x86_64_arith_test.nx -- session 4 smoke for mul/div/shift/bitwise. 2// 3// Computes ((7 * 6) - 30) / 4 = 3 entirely on the x86_64 stack 4// machine, ASCII-encodes the result (0x30 + 3 = '3') and writes 5// one byte to stdout. Validates imulq + subq + cqo + idivq. 6// 7// Then ALSO does: 8// (0xFF & 0x0F) | 0x40 = 0x4F = 'O' -- and/or 9// (5 ^ 3) << 1 = 12 -> '<' -- xor/shlq_imm 10// not(~0xFFFFFFFFFFFFFFFB) = 5 -> '5' -- notq + neg 11// But the SMOKE asserts ONLY the first one to keep things minimal. 12// Stdout: "3" (one byte 0x33). 13 14import "syscalls.nx" 15import "nx_outbuf.nx" 16import "nx_x86_64.nx" 17 18func main() -> i64 { 19 let o: *OutBuf = out_new(8192) 20 21 let main_name: *u8 = "main" as *u8 22 let _start_name: *u8 = "_start" as *u8 23 24 out_str(o, "# Emitted by nx_x86_64.nx session 4 (arith/bitwise/shift)\n") 25 out_str(o, " .att_syntax prefix\n") 26 27 x86_emit_function_start(o, _start_name) 28 out_str(o, " call main\n") 29 x86_emit_movabsq(o, "rax" as *u8, NX_X64_SYS_EXIT) 30 x86_emit_movabsq(o, "rdi" as *u8, 0) 31 x86_emit_syscall(o) 32 x86_emit_function_end(o, _start_name) 33 34 x86_emit_function_start(o, main_name) 35 x86_emit_prologue(o, 16) 36 37 // Compute (7 * 6 - 30) / 4 = 3. 38 x86_emit_movabsq(o, "rax" as *u8, 7) 39 x86_emit_movabsq(o, "rcx" as *u8, 6) 40 x86_emit_imulq_rr(o, "rcx" as *u8, "rax" as *u8) // rax = 42 41 x86_emit_movabsq(o, "rcx" as *u8, 30) 42 x86_emit_subq_rr(o, "rcx" as *u8, "rax" as *u8) // rax = 12 43 x86_emit_movabsq(o, "rcx" as *u8, 4) 44 x86_emit_cqo(o) // sign-extend 45 x86_emit_idivq_r(o, "rcx" as *u8) // rax = 3 46 47 // ASCII-encode: rax += 0x30 48 x86_emit_movabsq(o, "rcx" as *u8, 0x30) 49 x86_emit_addq_rr(o, "rcx" as *u8, "rax" as *u8) // rax = 0x33 ('3') 50 51 // Store the byte at -1(%rbp). 52 x86_emit_store_byte(o, "rax" as *u8, "rbp" as *u8, 0 - 1) 53 54 // write(1, &buf, 1) 55 x86_emit_movabsq(o, "rdi" as *u8, 1) 56 x86_emit_lea_disp(o, "rbp" as *u8, 0 - 1, "rsi" as *u8) 57 x86_emit_movabsq(o, "rdx" as *u8, 1) 58 x86_emit_movabsq(o, "rax" as *u8, NX_X64_SYS_WRITE) 59 x86_emit_syscall(o) 60 61 x86_emit_movabsq(o, "rax" as *u8, 0) 62 x86_emit_epilogue(o) 63 x86_emit_function_end(o, main_name) 64 65 x86_emit_gnu_stack_note(o) 66 67 sys_write(1, o.buf, o.pos) 68 return 0 69}