nooc

nooc programming language compiler
git clone git://git.nihaljere.xyz/nooc
Log | Files | Refs | LICENSE

commit b374c57b127d44eb594a2c2d74b9b4fd7bb9b9d2
parent 185f18ae490552cb8e16e23c6c9f145b55d2f101
Author: Nihal Jere <nihal@nihaljere.xyz>
Date:   Mon, 10 Jan 2022 15:10:39 -0600

x64: remove unused functions and make instruction functions static

Diffstat:
Mx64.c | 486+++++++++++++++++++++++++++++++++++++------------------------------------------
Mx64.h | 44--------------------------------------------
2 files changed, 229 insertions(+), 301 deletions(-)

diff --git a/x64.c b/x64.c @@ -29,223 +29,7 @@ unsigned short used_reg; extern struct toplevel toplevel; -#define NEXT ins++; assert(ins <= end); - static size_t -emitsyscall(char *buf, uint8_t paramcount) -{ - assert(paramcount < 8); - size_t total = 0; - total += push_r64(buf ? buf + total : NULL, RBP); - total += mov_r64_r64(buf ? buf + total : NULL, RBP, RSP); - - for (size_t i = 0; i < paramcount; i++) { - total += push_r64(buf ? buf + total : NULL, abi_arg[i]); - total += mov_disp8_r64_m64(buf ? buf + total : NULL, abi_arg[i], RBP, 8*i + 16); - } - - if (buf) { - *(buf + total++) = 0x0f; - *(buf + total++) = 0x05; - } else { - total += 2; - } - - total += mov_disp8_r64_m64(buf ? buf + total : NULL, RDI, RBP, 8*paramcount + 16); - total += mov_mr64_r64(buf ? buf + total : NULL, RDI, RAX); - - for (size_t i = paramcount - 1; i < paramcount; i--) { - total += pop_r64(buf ? buf + total : NULL, abi_arg[i]); - } - - total += pop_r64(buf ? buf + total : NULL, RBP); - total += ret(buf ? buf + total : NULL); - - return total; -} - -const struct target x64_target = { - .reserved = (1 << RSP) | (1 << RBP), - .emitsyscall = emitsyscall -}; - -size_t -emitblock(char *buf, struct iproc *proc, struct instr *start, struct instr *end, uint64_t end_label) -{ - struct instr *ins = start ? start : proc->data; - end = end ? end : &proc->data[proc->len]; - - uint64_t dest, src, size, count, tmp, label; - int64_t offset; - uint64_t localalloc = 0; - - size_t total = 0; - if (!start) { - total += push_r64(buf ? buf + total : NULL, RBP); - total += mov_r64_r64(buf ? buf + total : NULL, RBP, RSP); - } - - while (ins < end) { - switch (ins->op) { - // FIXME: we don't handle jumps backward yet - case IR_JUMP: - total += jmp(buf ? buf + total : NULL, emitblock(NULL, proc, ins + 1, end, ins->id)); - NEXT; - break; - case IR_RETURN: - total += add_r64_imm(buf ? buf + total : NULL, RSP, localalloc); - total += pop_r64(buf ? buf + total : NULL, RBP); - total += ret(buf ? buf + total : NULL); - NEXT; - break; - case IR_SIZE: - size = ins->id; - NEXT; - - switch (ins->op) { - case IR_STORE: - src = proc->intervals.data[ins->id].reg; - NEXT; - assert(ins->op == IR_EXTRA); - total += mov_mr64_r64(buf ? buf + total : NULL, proc->intervals.data[ins->id].reg, src); - NEXT; - break; - default: - die("x64 emitblock: unhandled size instruction"); - } - break; - case IR_ASSIGN: - tmp = ins->id; - dest = proc->intervals.data[ins->id].reg; - NEXT; - - assert(ins->op == IR_SIZE); - size = ins->id; - NEXT; - - switch (ins->op) { - case IR_CEQ: - total += mov_r64_r64(buf ? buf + total : NULL, dest, proc->intervals.data[ins->id].reg); - NEXT; - total += cmp_r64_r64(buf ? buf + total : NULL, dest, proc->intervals.data[ins->id].reg); - NEXT; - if (ins->op == IR_CONDJUMP) { - label = ins->id; - NEXT; - assert(ins->op == IR_EXTRA); - if (ins->id == tmp) { - total += jne(buf ? buf + total : NULL, emitblock(NULL, proc, ins + 1, end, label)); - } - NEXT; - } - break; - case IR_ADD: - total += mov_r64_r64(buf ? buf + total : NULL, dest, proc->intervals.data[ins->id].reg); - NEXT; - total += add_r64_r64(buf ? buf + total : NULL, dest, proc->intervals.data[ins->id].reg); - NEXT; - break; - case IR_IMM: - total += mov_r64_imm(buf ? buf + total : NULL, dest, ins->id); - NEXT; - break; - case IR_IN: - total += mov_disp8_r64_m64(buf ? buf + total : NULL, dest, RBP, 8*ins->id + 16); - NEXT; - break; - case IR_LOAD: - total += mov_r64_mr64(buf ? buf + total : NULL, dest, proc->intervals.data[ins->id].reg); - NEXT; - break; - case IR_ALLOC: - total += mov_r64_r64(buf ? buf + total : NULL, dest, RSP); - total += sub_r64_imm(buf ? buf + total : NULL, RSP, 8); // FIXME: hardcoding - localalloc += 8; - NEXT; - break; - default: - die("x64 emitblock: unhandled assign instruction"); - } - break; - case IR_CALL: - count = 0; - dest = ins->id; - - for (int i = 0; i < 16; i++) { - total += push_r64(buf ? buf + total : NULL, i); - } - - NEXT; - while (ins->op == IR_CALLARG) { - count++; - total += push_r64(buf ? buf + total : NULL, proc->intervals.data[ins->id].reg); - NEXT; - } - - // we assume call is constant width - this should probably change - offset = -(proc->addr + total - toplevel.code.data[dest].addr + call(NULL, 0)); - total += call(buf ? buf + total : NULL, offset); - // FIXME: this won't work with non-64-bit things - total += add_r64_imm(buf ? buf + total : NULL, RSP, 8*count); - for (int i = 15; i >= 0; i--) { - total += pop_r64(buf ? buf + total : NULL, i); - } - break; - case IR_LABEL: - if (ins->id == end_label) - goto done; - - NEXT; - break; - case IR_STORE: - case IR_IMM: - case IR_ALLOC: - die("x64 emitblock: invalid start of instruction"); - default: - die("x64 emitproc: unknown instruction"); - } - } - -done: - return total; -} - -// FIXME: use array_push -size_t -emitproc(char *buf, struct iproc *proc) -{ - return emitblock(buf, proc, NULL, NULL, 0); -} - -#undef NEXT - -void -clearreg() -{ - used_reg = (1 << RBP) | (1 << RSP); -} - -enum reg -getreg() -{ - for (int i = 0; i < 16; i++) { - if (!(used_reg & (1 << i))) { - used_reg |= (1 << i); - return i; - } - } - - die("out of registers!"); - return 0; // prevents warning -} - -void -freereg(enum reg reg) -{ - used_reg &= ~(1 << reg); -} - -size_t add_r64_imm(char *buf, enum reg dest, uint64_t imm) { if (buf) { @@ -261,7 +45,7 @@ add_r64_imm(char *buf, enum reg dest, uint64_t imm) return 7; } -size_t +static size_t mov_r64_imm(char *buf, enum reg dest, uint64_t imm) { if (buf) { @@ -280,7 +64,7 @@ mov_r64_imm(char *buf, enum reg dest, uint64_t imm) return 10; } -size_t +static size_t mov_r32_imm(char *buf, enum reg dest, uint32_t imm) { if (buf) { @@ -294,7 +78,7 @@ mov_r32_imm(char *buf, enum reg dest, uint32_t imm) return 5; } -size_t +static size_t mov_r16_imm(char *buf, enum reg dest, uint16_t imm) { if (buf) { @@ -307,7 +91,7 @@ mov_r16_imm(char *buf, enum reg dest, uint16_t imm) return 4; } -size_t +static size_t mov_r8_imm(char *buf, enum reg dest, uint8_t imm) { if (buf) { @@ -318,7 +102,7 @@ mov_r8_imm(char *buf, enum reg dest, uint8_t imm) return 2; } -size_t +static size_t mov_r64_m64(char *buf, enum reg dest, uint64_t addr) { uint8_t sib = 0x25; @@ -336,7 +120,7 @@ mov_r64_m64(char *buf, enum reg dest, uint64_t addr) return 8; } -size_t +static size_t mov_r32_m32(char *buf, enum reg dest, uint32_t addr) { if (buf) { @@ -353,7 +137,7 @@ mov_r32_m32(char *buf, enum reg dest, uint32_t addr) return dest >= 8 ? 8 : 7; } -size_t +static size_t mov_r16_m16(char *buf, enum reg dest, uint32_t addr) { if (buf) { @@ -371,7 +155,7 @@ mov_r16_m16(char *buf, enum reg dest, uint32_t addr) return dest >= 8 ? 9 : 8; } -size_t +static size_t mov_r8_m8(char *buf, enum reg dest, uint32_t addr) { if (buf) { @@ -388,7 +172,7 @@ mov_r8_m8(char *buf, enum reg dest, uint32_t addr) return dest >= 8 ? 8 : 7; } -size_t +static size_t mov_m64_r64(char *buf, uint64_t addr, enum reg src) { if (buf) { @@ -407,7 +191,7 @@ mov_m64_r64(char *buf, uint64_t addr, enum reg src) return 10; } -size_t +static size_t mov_m32_r32(char *buf, uint64_t addr, enum reg src) { if (buf) { @@ -425,7 +209,7 @@ mov_m32_r32(char *buf, uint64_t addr, enum reg src) return 9; } -size_t +static size_t mov_mr64_r64(char *buf, enum reg dest, enum reg src) { if (buf) { @@ -437,7 +221,7 @@ mov_mr64_r64(char *buf, enum reg dest, enum reg src) return 3; } -size_t +static size_t mov_mr32_r32(char *buf, enum reg dest, enum reg src) { if (buf) { @@ -448,7 +232,7 @@ mov_mr32_r32(char *buf, enum reg dest, enum reg src) return 2; } -size_t +static size_t mov_mr16_r16(char *buf, enum reg dest, enum reg src) { if (buf) { @@ -460,7 +244,7 @@ mov_mr16_r16(char *buf, enum reg dest, enum reg src) return 3; } -size_t +static size_t mov_mr8_r8(char *buf, enum reg dest, enum reg src) { if (buf) { @@ -471,7 +255,7 @@ mov_mr8_r8(char *buf, enum reg dest, enum reg src) return 2; } -size_t +static size_t mov_r64_mr64(char *buf, enum reg dest, enum reg src) { if (buf) { @@ -483,7 +267,7 @@ mov_r64_mr64(char *buf, enum reg dest, enum reg src) return 3; } -size_t +static size_t mov_r32_mr32(char *buf, enum reg dest, enum reg src) { if (buf) { @@ -494,7 +278,7 @@ mov_r32_mr32(char *buf, enum reg dest, enum reg src) return 2; } -size_t +static size_t mov_r16_mr16(char *buf, enum reg dest, enum reg src) { if (buf) { @@ -506,7 +290,7 @@ mov_r16_mr16(char *buf, enum reg dest, enum reg src) return 3; } -size_t +static size_t mov_r8_mr8(char *buf, enum reg dest, enum reg src) { if (buf) { @@ -517,7 +301,7 @@ mov_r8_mr8(char *buf, enum reg dest, enum reg src) return 2; } -size_t +static size_t mov_r64_r64(char *buf, enum reg dest, enum reg src) { if (buf) { @@ -529,7 +313,7 @@ mov_r64_r64(char *buf, enum reg dest, enum reg src) return 3; } -size_t +static size_t mov_r32_r32(char *buf, enum reg dest, enum reg src) { if (buf) { @@ -541,7 +325,7 @@ mov_r32_r32(char *buf, enum reg dest, enum reg src) return (src >= 8 || dest >= 8) ? 3 : 2; } -size_t +static size_t mov_disp8_m64_r64(char *buf, enum reg dest, int8_t disp, enum reg src) { assert(src != 4); @@ -556,7 +340,7 @@ mov_disp8_m64_r64(char *buf, enum reg dest, int8_t disp, enum reg src) } // FIXME: we don't handle r8-r15 properly in most of these -size_t +static size_t mov_disp8_m32_r32(char *buf, enum reg dest, int8_t disp, enum reg src) { assert(src != 4); @@ -570,7 +354,7 @@ mov_disp8_m32_r32(char *buf, enum reg dest, int8_t disp, enum reg src) } // FIXME: we don't handle r8-r15 properly in most of these -size_t +static size_t mov_disp8_m16_r16(char *buf, enum reg dest, int8_t disp, enum reg src) { assert(src != 4); @@ -585,7 +369,7 @@ mov_disp8_m16_r16(char *buf, enum reg dest, int8_t disp, enum reg src) } // FIXME: we don't handle r8-r15 properly in most of these -size_t +static size_t mov_disp8_m8_r8(char *buf, enum reg dest, int8_t disp, enum reg src) { assert(src != 4); @@ -598,7 +382,7 @@ mov_disp8_m8_r8(char *buf, enum reg dest, int8_t disp, enum reg src) return 3; } -size_t +static size_t mov_disp8_r64_m64(char *buf, enum reg dest, enum reg src, int8_t disp) { assert(src != 4); @@ -612,7 +396,7 @@ mov_disp8_r64_m64(char *buf, enum reg dest, enum reg src, int8_t disp) return 4; } -size_t +static size_t mov_disp8_r32_m32(char *buf, enum reg dest, enum reg src, int8_t disp) { assert(src != 4); @@ -625,7 +409,7 @@ mov_disp8_r32_m32(char *buf, enum reg dest, enum reg src, int8_t disp) return 3; } -size_t +static size_t mov_disp8_r16_m16(char *buf, enum reg dest, enum reg src, int8_t disp) { assert(src != 4); @@ -639,7 +423,7 @@ mov_disp8_r16_m16(char *buf, enum reg dest, enum reg src, int8_t disp) return 4; } -size_t +static size_t mov_disp8_r8_m8(char *buf, enum reg dest, enum reg src, int8_t disp) { assert(src != 4); @@ -652,7 +436,7 @@ mov_disp8_r8_m8(char *buf, enum reg dest, enum reg src, int8_t disp) return 3; } -size_t +static size_t lea_disp8(char *buf, enum reg dest, enum reg src, int8_t disp) { assert(src != 4); @@ -666,7 +450,7 @@ lea_disp8(char *buf, enum reg dest, enum reg src, int8_t disp) return 4; } -size_t +static size_t add_r64_r64(char *buf, enum reg dest, enum reg src) { if (buf) { @@ -678,7 +462,7 @@ add_r64_r64(char *buf, enum reg dest, enum reg src) return 3; } -size_t +static size_t sub_r64_r64(char *buf, enum reg dest, enum reg src) { if (buf) { @@ -690,7 +474,7 @@ sub_r64_r64(char *buf, enum reg dest, enum reg src) return 3; } -size_t +static size_t sub_r64_imm(char *buf, enum reg dest, int32_t imm) { if (buf) { @@ -706,7 +490,7 @@ sub_r64_imm(char *buf, enum reg dest, int32_t imm) return 7; } -size_t +static size_t cmp_r64_r64(char *buf, enum reg reg1, enum reg reg2) { if (buf) { @@ -718,7 +502,7 @@ cmp_r64_r64(char *buf, enum reg reg1, enum reg reg2) return 3; } -size_t +static size_t jng(char *buf, int64_t offset) { if (-256 <= offset && offset <= 255) { @@ -735,7 +519,7 @@ jng(char *buf, int64_t offset) return 0; // prevents warning } -size_t +static size_t jg(char *buf, int64_t offset) { if (-256 <= offset && offset <= 255) { @@ -752,7 +536,7 @@ jg(char *buf, int64_t offset) return 0; // prevents warning } -size_t +static size_t jne(char *buf, int64_t offset) { if (-256 <= offset && offset <= 255) { @@ -769,7 +553,7 @@ jne(char *buf, int64_t offset) return 0; // prevents warning } -size_t +static size_t jmp(char *buf, int64_t offset) { if (-256 <= offset && offset <= 255) { @@ -786,7 +570,7 @@ jmp(char *buf, int64_t offset) return 0; // prevents warning } -size_t +static size_t call(char *buf, int32_t offset) { if (buf) { @@ -800,7 +584,7 @@ call(char *buf, int32_t offset) return 5; } -size_t +static size_t ret(char *buf) { if (buf) @@ -809,7 +593,7 @@ ret(char *buf) return 1; } -size_t +static size_t push_r64(char *buf, enum reg reg) { if (buf) { @@ -822,7 +606,7 @@ push_r64(char *buf, enum reg reg) return reg >= 8 ? 2 : 1; } -size_t +static size_t pop_r64(char *buf, enum reg reg) { if (buf) { @@ -834,3 +618,191 @@ pop_r64(char *buf, enum reg reg) return reg >= 8 ? 2 : 1; } + +#define NEXT ins++; assert(ins <= end); + +static size_t +emitsyscall(char *buf, uint8_t paramcount) +{ + assert(paramcount < 8); + size_t total = 0; + total += push_r64(buf ? buf + total : NULL, RBP); + total += mov_r64_r64(buf ? buf + total : NULL, RBP, RSP); + + for (size_t i = 0; i < paramcount; i++) { + total += push_r64(buf ? buf + total : NULL, abi_arg[i]); + total += mov_disp8_r64_m64(buf ? buf + total : NULL, abi_arg[i], RBP, 8*i + 16); + } + + if (buf) { + *(buf + total++) = 0x0f; + *(buf + total++) = 0x05; + } else { + total += 2; + } + + total += mov_disp8_r64_m64(buf ? buf + total : NULL, RDI, RBP, 8*paramcount + 16); + total += mov_mr64_r64(buf ? buf + total : NULL, RDI, RAX); + + for (size_t i = paramcount - 1; i < paramcount; i--) { + total += pop_r64(buf ? buf + total : NULL, abi_arg[i]); + } + + total += pop_r64(buf ? buf + total : NULL, RBP); + total += ret(buf ? buf + total : NULL); + + return total; +} + +const struct target x64_target = { + .reserved = (1 << RSP) | (1 << RBP), + .emitsyscall = emitsyscall +}; + +size_t +emitblock(char *buf, struct iproc *proc, struct instr *start, struct instr *end, uint64_t end_label) +{ + struct instr *ins = start ? start : proc->data; + end = end ? end : &proc->data[proc->len]; + + uint64_t dest, src, size, count, tmp, label; + int64_t offset; + uint64_t localalloc = 0; + + size_t total = 0; + if (!start) { + total += push_r64(buf ? buf + total : NULL, RBP); + total += mov_r64_r64(buf ? buf + total : NULL, RBP, RSP); + } + + while (ins < end) { + switch (ins->op) { + // FIXME: we don't handle jumps backward yet + case IR_JUMP: + total += jmp(buf ? buf + total : NULL, emitblock(NULL, proc, ins + 1, end, ins->id)); + NEXT; + break; + case IR_RETURN: + total += add_r64_imm(buf ? buf + total : NULL, RSP, localalloc); + total += pop_r64(buf ? buf + total : NULL, RBP); + total += ret(buf ? buf + total : NULL); + NEXT; + break; + case IR_SIZE: + size = ins->id; + NEXT; + + switch (ins->op) { + case IR_STORE: + src = proc->intervals.data[ins->id].reg; + NEXT; + assert(ins->op == IR_EXTRA); + total += mov_mr64_r64(buf ? buf + total : NULL, proc->intervals.data[ins->id].reg, src); + NEXT; + break; + default: + die("x64 emitblock: unhandled size instruction"); + } + break; + case IR_ASSIGN: + tmp = ins->id; + dest = proc->intervals.data[ins->id].reg; + NEXT; + + assert(ins->op == IR_SIZE); + size = ins->id; + NEXT; + + switch (ins->op) { + case IR_CEQ: + total += mov_r64_r64(buf ? buf + total : NULL, dest, proc->intervals.data[ins->id].reg); + NEXT; + total += cmp_r64_r64(buf ? buf + total : NULL, dest, proc->intervals.data[ins->id].reg); + NEXT; + if (ins->op == IR_CONDJUMP) { + label = ins->id; + NEXT; + assert(ins->op == IR_EXTRA); + if (ins->id == tmp) { + total += jne(buf ? buf + total : NULL, emitblock(NULL, proc, ins + 1, end, label)); + } + NEXT; + } + break; + case IR_ADD: + total += mov_r64_r64(buf ? buf + total : NULL, dest, proc->intervals.data[ins->id].reg); + NEXT; + total += add_r64_r64(buf ? buf + total : NULL, dest, proc->intervals.data[ins->id].reg); + NEXT; + break; + case IR_IMM: + total += mov_r64_imm(buf ? buf + total : NULL, dest, ins->id); + NEXT; + break; + case IR_IN: + total += mov_disp8_r64_m64(buf ? buf + total : NULL, dest, RBP, 8*ins->id + 16); + NEXT; + break; + case IR_LOAD: + total += mov_r64_mr64(buf ? buf + total : NULL, dest, proc->intervals.data[ins->id].reg); + NEXT; + break; + case IR_ALLOC: + total += mov_r64_r64(buf ? buf + total : NULL, dest, RSP); + total += sub_r64_imm(buf ? buf + total : NULL, RSP, 8); // FIXME: hardcoding + localalloc += 8; + NEXT; + break; + default: + die("x64 emitblock: unhandled assign instruction"); + } + break; + case IR_CALL: + count = 0; + dest = ins->id; + + for (int i = 0; i < 16; i++) { + total += push_r64(buf ? buf + total : NULL, i); + } + + NEXT; + while (ins->op == IR_CALLARG) { + count++; + total += push_r64(buf ? buf + total : NULL, proc->intervals.data[ins->id].reg); + NEXT; + } + + // we assume call is constant width - this should probably change + offset = -(proc->addr + total - toplevel.code.data[dest].addr + call(NULL, 0)); + total += call(buf ? buf + total : NULL, offset); + // FIXME: this won't work with non-64-bit things + total += add_r64_imm(buf ? buf + total : NULL, RSP, 8*count); + for (int i = 15; i >= 0; i--) { + total += pop_r64(buf ? buf + total : NULL, i); + } + break; + case IR_LABEL: + if (ins->id == end_label) + goto done; + + NEXT; + break; + case IR_STORE: + case IR_IMM: + case IR_ALLOC: + die("x64 emitblock: invalid start of instruction"); + default: + die("x64 emitproc: unknown instruction"); + } + } + +done: + return total; +} + +// FIXME: use array_push +size_t +emitproc(char *buf, struct iproc *proc) +{ + return emitblock(buf, proc, NULL, NULL, 0); +} diff --git a/x64.h b/x64.h @@ -20,48 +20,4 @@ enum reg { extern char abi_arg[]; extern unsigned short used_reg; -void clearreg(); -enum reg getreg(); -void freereg(enum reg reg); - -size_t add_r64_imm(char *buf, enum reg reg, uint64_t imm); -size_t mov_r64_imm(char *buf, enum reg reg, uint64_t imm); -size_t mov_r64_m64(char *buf, enum reg reg, uint64_t addr); -size_t mov_r32_m32(char *buf, enum reg dest, uint32_t addr); -size_t mov_r16_m16(char *buf, enum reg dest, uint32_t addr); -size_t mov_r8_m8(char *buf, enum reg dest, uint32_t addr); -size_t mov_m64_r64(char *buf, uint64_t addr, enum reg reg); -size_t mov_m32_r32(char *buf, uint64_t addr, enum reg src); -size_t mov_m16_r16(char *buf, uint64_t addr, enum reg src); -size_t mov_mr64_r64(char *buf, enum reg dest, enum reg src); -size_t mov_mr32_r32(char *buf, enum reg dest, enum reg src); -size_t mov_mr16_r16(char *buf, enum reg dest, enum reg src); -size_t mov_mr8_r8(char *buf, enum reg dest, enum reg src); -size_t mov_r64_mr64(char *buf, enum reg dest, enum reg src); -size_t mov_r32_mr32(char *buf, enum reg dest, enum reg src); -size_t mov_r16_mr16(char *buf, enum reg dest, enum reg src); -size_t mov_r8_mr8(char *buf, enum reg dest, enum reg src); -size_t mov_r64_r64(char *buf, enum reg dest, enum reg src); -size_t mov_disp8_m64_r64(char *buf, enum reg dest, int8_t disp, enum reg src); -size_t mov_disp8_m32_r32(char *buf, enum reg dest, int8_t disp, enum reg src); -size_t mov_disp8_m16_r16(char *buf, enum reg dest, int8_t disp, enum reg src); -size_t mov_disp8_m8_r8(char *buf, enum reg dest, int8_t disp, enum reg src); -size_t mov_disp8_r64_m64(char *buf, enum reg dest, enum reg src, int8_t disp); -size_t mov_disp8_r32_m32(char *buf, enum reg dest, enum reg src, int8_t disp); -size_t mov_disp8_r16_m16(char *buf, enum reg dest, enum reg src, int8_t disp); -size_t mov_disp8_r8_m8(char *buf, enum reg dest, enum reg src, int8_t disp); -size_t lea_disp8(char *buf, enum reg dest, enum reg src, int8_t disp); -size_t add_r64_r64(char *buf, enum reg reg1, enum reg reg2); -size_t sub_r64_r64(char *buf, enum reg reg1, enum reg reg2); -size_t sub_r64_imm(char *buf, enum reg reg1, int32_t imm); -size_t cmp_r64_r64(char *buf, enum reg reg1, enum reg reg2); -size_t jng(char *buf, int64_t offset); -size_t jg(char *buf, int64_t offset); -size_t jne(char *buf, int64_t offset); -size_t jmp(char *buf, int64_t offset); -size_t call(char *buf, int32_t offset); -size_t ret(char *buf); -size_t push_r64(char *buf, enum reg reg); -size_t pop_r64(char *buf, enum reg reg); - size_t emitproc(char *buf, struct iproc *proc);