nxasm_x86_enc.nx
buildroot/runtime/nxasm_x86_enc.nx
about
nxasm_x86_enc.nx -- x86_64 instruction encoder + minimal ELF writer,
written in NishiLang. The x86_64 sibling of asm_enc.nx (RV64).
First brick of the SOVEREIGN x86_64 backend: replaces GNU `as` + `ld`
on the output path. Pure bit-manipulation -- no syscalls, no file
I/O here, so it stays architecture-neutral and the encoder KAT runs
under any lane. Live emit (write the ELF to a fd) is composed in the
test/driver via the syscall layer.
Scope (this iteration): the exact constructs needed to emit a
runnable static ELF -- enough to prove the whole sovereign chain
end-to-end with an exit(N) binary. The full 29-mnemonic AT&T subset
nxc2 emits (movq/movabsq/add/sub/and/or/cmp/test/imul/idiv/cqo/shl/
sar/lea/call/jmp/jcc/setcc/movzbq/...) lands incrementally on this
same REX/ModRM/SIB foundation, each gated by a byte-exact KAT vs the
objdump oracle (Wheeler/benchmark reference only -- NEVER in our
output path).
Encoding model (Intel SDM Vol.2):
REX prefix 0100 WRXB (0x40 base; W=64-bit, B=reg ext bit3)
ModRM mod(2) reg(3) rm(3)
immediates little-endian
genealogy_id: intel_sdm_vol2 + amd_apm + osdev_elf (Wheeler refs)
lineage_id: nishi_sovereign_x86_64_backend_m1
license_tier: ORIGINAL
dependencies 0 imports · 1 importers
imports: none
imported by: nxasm_x86.nx
structs
| none |
consts
| 29 | const X86_RAX: i64 = 0 |
| 30 | const X86_RCX: i64 = 1 |
| 31 | const X86_RDX: i64 = 2 |
| 32 | const X86_RBX: i64 = 3 |
| 33 | const X86_RSP: i64 = 4 |
| 34 | const X86_RBP: i64 = 5 |
| 35 | const X86_RSI: i64 = 6 |
| 36 | const X86_RDI: i64 = 7 |
| 37 | const X86_R8: i64 = 8 |
| 38 | const X86_R9: i64 = 9 |
| 39 | const X86_R10: i64 = 10 |
| 40 | const X86_R11: i64 = 11 |
| 41 | const X86_R12: i64 = 12 |
| 42 | const X86_R13: i64 = 13 |
| 43 | const X86_R14: i64 = 14 |
| 44 | const X86_R15: i64 = 15 |
| 47 | const EM_X86_64: i64 = 62 |
| 48 | const X86_BASE: i64 = 0x400000 // conventional static ET_EXEC base |
| 49 | const X86_HDRLEN: i64 = 120 // 64 (ehdr) + 56 (one phdr) |
| 388 | const X86_OP_ADD: i64 = 0x01 |
| 389 | const X86_OP_SUB: i64 = 0x29 |
| 390 | const X86_OP_AND: i64 = 0x21 |
| 391 | const X86_OP_OR: i64 = 0x09 |
| 392 | const X86_OP_XOR: i64 = 0x31 |
| 393 | const X86_OP_CMP: i64 = 0x39 |
| 394 | const X86_OP_TEST: i64 = 0x85 |
| 396 | const X86_EXT_ADD: i64 = 0 |
| 397 | const X86_EXT_OR: i64 = 1 |
| 398 | const X86_EXT_AND: i64 = 4 |
| 399 | const X86_EXT_SUB: i64 = 5 |
| 400 | const X86_EXT_CMP: i64 = 7 |
| 402 | const X86_EXT_SHL: i64 = 4 |
| 403 | const X86_EXT_SHR: i64 = 5 |
| 404 | const X86_EXT_SAR: i64 = 7 |
| 407 | const X86_CC_O: i64 = 0 |
| 408 | const X86_CC_NO: i64 = 1 |
| 409 | const X86_CC_E: i64 = 4 |
| 410 | const X86_CC_NE: i64 = 5 |
| 411 | const X86_CC_L: i64 = 0xC |
| 412 | const X86_CC_LE: i64 = 0xE |
| 413 | const X86_CC_G: i64 = 0xF |
| 414 | const X86_CC_GE: i64 = 0xD |
| 415 | const X86_CC_S: i64 = 8 // SF=1 (negative) -- the G22 bias-select |
| 416 | const X86_CC_NS: i64 = 9 // SF=0 |
| 1035 | const X86_SHT_ENTS: i64 = 4 // NULL, .text, .debug_line, .shstrtab |
| 1036 | const X86_SHT_ENTSZ: i64 = 64 |
functions
| 52 | func x86_put_u16le(out: *u8, o: i64, v: i64) -> i64 |
| 58 | func x86_put_u32le(out: *u8, o: i64, v: i64) -> i64 |
| 66 | func x86_put_u64le(out: *u8, o: i64, v: i64) -> i64 |
| 80 | func x86_rex_w(reg_field: i64, rm_field: i64) -> i64 |
| 88 | func x86_modrm(mod: i64, reg: i64, rm: i64) -> i64 |
| 97 | func x86_sse_rr(out: *u8, o: i64, pfx: i64, esc: i64, opc: i64, reg: i64, rm: i64) -> i64 |
| 123 | func x86_vex2_rr(out: *u8, o: i64, opc: i64, dst: i64, src1: i64, src2: i64, l: i64, pp: i64) -> i64 |
| 136 | func x86_vex3_rr(out: *u8, o: i64, mmmmm: i64, w: i64, opc: i64, dst: i64, src1: i64, src2: i64, l: i64, pp: i64) -> i64 |
| 150 | func x86_sse_rr_w(out: *u8, o: i64, pfx: i64, esc: i64, opc: i64, reg: i64, rm: i64) -> i64 |
| 173 | func x86_sse_mem(out: *u8, o: i64, pfx: i64, opc: i64, reg: i64, base: i64, disp: i64) -> i64 |
| 192 | func x86_sse_shift_imm(out: *u8, o: i64, opc: i64, ext: i64, xmm: i64, imm8: i64) -> i64 |
| 207 | func x86_sse_rri(out: *u8, o: i64, pfx: i64, opc: i64, reg: i64, rm: i64, imm8: i64) -> i64 |
| 231 | func x86_vex_rrr(out: *u8, o: i64, pp: i64, mmmmm: i64, w: i64, vexL: i64, opc: i64, dst: i64, src1: i64, src2: i64) -> i64 |
| 251 | func x86_vex_rm(out: *u8, o: i64, pp: i64, mmmmm: i64, w: i64, vexL: i64, opc: i64, reg: i64, base: i64, disp: i64) -> i64 |
| 273 | func x86_vex_shift_imm(out: *u8, o: i64, pp: i64, mmmmm: i64, vexL: i64, opc: i64, ext: i64, dst: i64, src: i64, imm8: i64) -> i64 |
| 295 | func x86_vex_rmi(out: *u8, o: i64, pp: i64, mmmmm: i64, w: i64, vexL: i64, opc: i64, dst: i64, src: i64, imm8: i64) -> i64 |
| 317 | func x86_movabs(out: *u8, o: i64, reg: i64, imm: i64) -> i64 |
| 327 | func x86_mov_imm32(out: *u8, o: i64, reg: i64, imm: i64) -> i64 |
| 339 | func x86_mov_reg(out: *u8, o: i64, dst: i64, src: i64) -> i64 |
| 350 | func x86_syscall(out: *u8, o: i64) -> i64 |
| 359 | func x86_rdtsc(out: *u8, o: i64) -> i64 |
| 366 | func x86_ret(out: *u8, o: i64) -> i64 |
| 372 | func x86_push(out: *u8, o: i64, reg: i64) -> i64 |
| 380 | func x86_pop(out: *u8, o: i64, reg: i64) -> i64 |
| 419 | func x86_alu_rr(out: *u8, o: i64, opcode: i64, dst: i64, src: i64) -> i64 |
| 429 | func x86_alu_imm(out: *u8, o: i64, ext: i64, dst: i64, imm: i64) -> i64 |
| 449 | func x86_mem_operand(out: *u8, o: i64, reg_field: i64, base: i64, disp: i64) -> i64 |
| 460 | func x86_mov_load(out: *u8, o: i64, dst: i64, base: i64, disp: i64) -> i64 |
| 468 | func x86_mov_store(out: *u8, o: i64, base: i64, disp: i64, src: i64) -> i64 |
| 478 | func x86_rex_wx(reg_field: i64, index_field: i64, base_field: i64) -> i64 |
| 487 | func x86_scale_log2(scale: i64) -> i64 |
| 498 | func x86_mem_operand_sib(out: *u8, o: i64, reg_field: i64, base: i64, |
| 512 | func x86_mov_load_sib(out: *u8, o: i64, dst: i64, base: i64, index: i64, scale: i64, disp: i64) -> i64 |
| 520 | func x86_mov_store_sib(out: *u8, o: i64, base: i64, index: i64, scale: i64, disp: i64, src: i64) -> i64 |
| 529 | func x86_movl_rex_if(out: *u8, o: i64, reg: i64, rm: i64) -> i64 |
| 537 | func x86_movl_store(out: *u8, o: i64, base: i64, disp: i64, src: i64) -> i64 |
| 542 | func x86_movl_load(out: *u8, o: i64, dst: i64, base: i64, disp: i64) -> i64 |
| 548 | func x86_movl_rr(out: *u8, o: i64, dst: i64, src: i64) -> i64 |
| 556 | func x86_lea(out: *u8, o: i64, dst: i64, base: i64, disp: i64) -> i64 |
| 568 | func x86_lea_sib(out: *u8, o: i64, dst: i64, base: i64, index: i64, scale: i64, disp: i64) -> i64 |
| 577 | func x86_lea_rip(out: *u8, o: i64, dst: i64, disp32: i64) -> i64 |
| 588 | func x86_imul_rr(out: *u8, o: i64, dst: i64, src: i64) -> i64 |
| 598 | func x86_movzbq(out: *u8, o: i64, dst: i64, src: i64) -> i64 |
| 607 | func x86_movzbq_mem(out: *u8, o: i64, dst: i64, base: i64, disp: i64) -> i64 |
| 622 | func x86_movsbq(out: *u8, o: i64, dst: i64, src: i64) -> i64 |
| 631 | func x86_movsbq_mem(out: *u8, o: i64, dst: i64, base: i64, disp: i64) -> i64 |
| 639 | func x86_movswq(out: *u8, o: i64, dst: i64, src: i64) -> i64 |
| 648 | func x86_movswq_mem(out: *u8, o: i64, dst: i64, base: i64, disp: i64) -> i64 |
| 656 | func x86_movzwq(out: *u8, o: i64, dst: i64, src: i64) -> i64 |
| 665 | func x86_movzwq_mem(out: *u8, o: i64, dst: i64, base: i64, disp: i64) -> i64 |
| 673 | func x86_movslq(out: *u8, o: i64, dst: i64, src: i64) -> i64 |
| 681 | func x86_movslq_mem(out: *u8, o: i64, dst: i64, base: i64, disp: i64) -> i64 |
| 689 | func x86_cqo(out: *u8, o: i64) -> i64 |
| 695 | func x86_idiv(out: *u8, o: i64, reg: i64) -> i64 |
| 707 | func x86_mul(out: *u8, o: i64, reg: i64) -> i64 |
| 721 | func x86_crc32_r64(out: *u8, o: i64, dst: i64, src: i64) -> i64 |
| 738 | func x86_pdep_r64(out: *u8, o: i64, dst: i64, src1: i64, src2: i64) -> i64 |
| 747 | func x86_pext_r64(out: *u8, o: i64, dst: i64, src1: i64, src2: i64) -> i64 |
| 759 | func x86_mulx_r64(out: *u8, o: i64, dst_hi: i64, dst_lo: i64, src: i64) -> i64 |
| 771 | func x86_adcx_r64(out: *u8, o: i64, dst: i64, src: i64) -> i64 |
| 781 | func x86_adox_r64(out: *u8, o: i64, dst: i64, src: i64) -> i64 |
| 793 | func x86_shift_imm(out: *u8, o: i64, ext: i64, reg: i64, imm8: i64) -> i64 |
| 803 | func x86_jmp_rel32(out: *u8, o: i64, rel: i64) -> i64 |
| 809 | func x86_call_rel32(out: *u8, o: i64, rel: i64) -> i64 |
| 815 | func x86_jcc_rel32(out: *u8, o: i64, cc: i64, rel: i64) -> i64 |
| 824 | func x86_cmovcc(out: *u8, o: i64, cc: i64, dst: i64, src: i64) -> i64 |
| 834 | func x86_setcc(out: *u8, o: i64, cc: i64, reg: i64) -> i64 |
| 845 | func x86_rot_imm(out: *u8, o: i64, is_ror: i64, reg: i64, imm8: i64) -> i64 |
| 854 | func x86_rot_cl(out: *u8, o: i64, is_ror: i64, reg: i64) -> i64 |
| 862 | func x86_shift_cl(out: *u8, o: i64, ext: i64, reg: i64) -> i64 |
| 870 | func x86_bswap(out: *u8, o: i64, reg: i64) -> i64 |
| 878 | func x86_popcnt(out: *u8, o: i64, dst: i64, src: i64) -> i64 |
| 890 | func x86_cnt32(out: *u8, o: i64, opc: i64, dst: i64, src: i64) -> i64 |
| 904 | func x86_lzcnt32(out: *u8, o: i64, dst: i64, src: i64) -> i64 { return x86_cnt32(out, o, 0xBD, dst, src) } |
| 905 | func x86_tzcnt32(out: *u8, o: i64, dst: i64, src: i64) -> i64 { return x86_cnt32(out, o, 0xBC, dst, src) } |
| 907 | func x86_unary_f7(out: *u8, o: i64, ext: i64, reg: i64) -> i64 |
| 914 | func x86_neg(out: *u8, o: i64, reg: i64) -> i64 { return x86_unary_f7(out, o, 3, reg) } |
| 915 | func x86_not(out: *u8, o: i64, reg: i64) -> i64 { return x86_unary_f7(out, o, 2, reg) } |
| 917 | func x86_incdec(out: *u8, o: i64, ext: i64, reg: i64) -> i64 |
| 925 | func x86_movb_imm(out: *u8, o: i64, base: i64, disp: i64, imm8: i64) -> i64 |
| 936 | func x86_movb_imm_reg(out: *u8, o: i64, reg: i64, imm8: i64) -> i64 |
| 947 | func x86_movb_store(out: *u8, o: i64, base: i64, disp: i64, src: i64) -> i64 |
| 958 | func x86_call_indirect(out: *u8, o: i64, reg: i64) -> i64 |
| 965 | func x86_jmp_indirect(out: *u8, o: i64, reg: i64) -> i64 |
| 979 | func x86_build_elf_at(code: *u8, code_len: i64, entry_off: i64, out: *u8) -> i64 |
| 1041 | func x86_sh_str(out: *u8, off: i64, s: *u8) -> i64 |
| 1048 | func x86_sh_ent(out: *u8, at: i64, name: i64, styp: i64, flags: i64, |
| 1062 | func x86_build_elf_dbg_at(code: *u8, code_len: i64, entry_off: i64, out: *u8, |
| 1112 | func x86_build_elf_dbg3_at(code: *u8, code_len: i64, entry_off: i64, out: *u8, |
| 1171 | func x86_build_elf(code: *u8, code_len: i64, out: *u8) -> i64 |