nooc

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

commit 80f83723f1690bf4f9393f3764c6f1f92c6d479b
parent 1d7177f52d0ab7324ae9476872c8bd745100f0ca
Author: Nihal Jere <nihal@nihaljere.xyz>
Date:   Wed, 15 Dec 2021 20:01:10 -0600

x64: make make function names more consistent, simplify things

Diffstat:
Mmain.c | 10+++++-----
Mx64.c | 119++++++++++++++++++++++++++++++++++++++-----------------------------------------
Mx64.h | 11++---------
3 files changed, 64 insertions(+), 76 deletions(-)

diff --git a/main.c b/main.c @@ -319,11 +319,11 @@ genexpr(char *buf, size_t idx, enum reg reg) if (expr->kind == EXPR_LIT) { switch (expr->class) { case C_INT: - len = mov_r_imm(ptr ? ptr + len : ptr, reg, expr->d.v.v.i); + len = mov_r64_imm(ptr ? ptr + len : ptr, reg, expr->d.v.v.i); break; case C_STR: { int addr = data_push(expr->d.v.v.s.data, expr->d.v.v.s.len); - len = mov_r_imm(ptr ? ptr + len : ptr, reg, addr); + len = mov_r64_imm(ptr ? ptr + len : ptr, reg, addr); break; } default: @@ -388,7 +388,7 @@ gencall(char *buf, size_t addr, struct expr *expr) len += push_r64(buf ? buf + len : NULL, reg); } - len += mov_r_imm(buf ? buf + len : NULL, reg, addr); + len += mov_r64_imm(buf ? buf + len : NULL, reg, addr); len += call(buf ? buf + len : NULL, reg); freereg(reg); @@ -491,7 +491,7 @@ genblock(char *buf, struct block *block, bool toplevel) if (buf) { addr = data_push(expr->d.v.v.s.data, expr->d.v.v.s.len); } - total += mov_r_imm(buf ? buf + total : NULL, reg, addr); + total += mov_r64_imm(buf ? buf + total : NULL, reg, addr); total += decl_fromreg(buf ? buf + total : NULL, decl, reg); break; case C_PROC: @@ -529,7 +529,7 @@ genblock(char *buf, struct block *block, bool toplevel) // FIXME: we assume that any string is a literal, may break if we add binary operands on strings in the future. case C_STR: size_t addr = data_push(expr->d.v.v.s.data, expr->d.v.v.s.len); - total += mov_r_imm(buf ? buf + total : NULL, reg, addr); + total += mov_r64_imm(buf ? buf + total : NULL, reg, addr); total += decl_fromreg(buf ? buf + total : NULL, decl, reg); break; default: diff --git a/x64.c b/x64.c @@ -8,6 +8,20 @@ #include "x64.h" #include "util.h" +enum rex { + REX_B = 0x41, + REX_X = 0x42, + REX_R = 0x44, + REX_W = 0x48, +}; + +enum mod { + MOD_INDIRECT, + MOD_DISP8, + MOD_DISP32, + MOD_DIRECT +}; + char abi_arg[] = {RAX, RDI, RSI, RDX, R10, R8, R9}; unsigned short used_reg; @@ -38,14 +52,12 @@ freereg(enum reg reg) } size_t -add_r_imm(char *buf, enum reg reg, uint64_t imm) +add_r64_imm(char *buf, enum reg dest, uint64_t imm) { - uint8_t mov[] = {0x48, 0x81}; - uint8_t op1 = (MOD_DIRECT << 6) | reg; if (buf) { - memcpy(buf, mov, 2); - buf += 2; - *(buf++) = op1; + *(buf++) = REX_W; + *(buf++) = 0x81;; + *(buf++) = (MOD_DIRECT << 6) | dest; *(buf++) = imm & 0xFF; *(buf++) = (imm >> 8) & 0xFF; *(buf++) = (imm >> 16) & 0xFF; @@ -56,14 +68,12 @@ add_r_imm(char *buf, enum reg reg, uint64_t imm) } size_t -mov_r_imm(char *buf, enum reg reg, uint64_t imm) +mov_r64_imm(char *buf, enum reg dest, uint64_t imm) { - uint8_t mov[] = {0x48, 0xc7}; - uint8_t op1 = (MOD_DIRECT << 6) | reg; if (buf) { - memcpy(buf, mov, 2); - buf += 2; - *(buf++) = op1; + *(buf++) = REX_W; + *(buf++) = 0xc7; + *(buf++) = (MOD_DIRECT << 6) | dest; *(buf++) = imm & 0xFF; *(buf++) = (imm >> 8) & 0xFF; *(buf++) = (imm >> 16) & 0xFF; @@ -74,15 +84,13 @@ mov_r_imm(char *buf, enum reg reg, uint64_t imm) } size_t -mov_r64_m64(char *buf, enum reg reg, uint64_t addr) +mov_r64_m64(char *buf, enum reg dest, uint64_t addr) { - uint8_t mov[] = {0x48, 0x8b}; - uint8_t op1 = (MOD_INDIRECT << 6) | (reg << 3) | 4; uint8_t sib = 0x25; if (buf) { - memcpy(buf, mov, 2); - buf += 2; - *(buf++) = op1; + *(buf++) = REX_W; + *(buf++) = 0x8b; + *(buf++) = (MOD_INDIRECT << 6) | (dest << 3) | 4; *(buf++) = sib; *(buf++) = addr & 0xFF; *(buf++) = (addr >> 8) & 0xFF; @@ -94,15 +102,13 @@ mov_r64_m64(char *buf, enum reg reg, uint64_t addr) } size_t -mov_m64_r64(char *buf, uint64_t addr, enum reg reg) +mov_m64_r64(char *buf, uint64_t addr, enum reg src) { - uint8_t mov[] = {0x48, 0x89}; - uint8_t op1 = (MOD_INDIRECT << 6) | (reg << 3) | 4; uint8_t sib = 0x25; if (buf) { - memcpy(buf, mov, 2); - buf += 2; - *(buf++) = op1; + *(buf++) = REX_W; + *(buf++) = 0x89; + *(buf++) = (MOD_INDIRECT << 6) | (src << 3) | 4; *(buf++) = sib; *(buf++) = addr & 0xFF; *(buf++) = (addr >> 8) & 0xFF; @@ -116,12 +122,10 @@ mov_m64_r64(char *buf, uint64_t addr, enum reg reg) size_t mov_r64_r64(char *buf, enum reg dest, enum reg src) { - uint8_t mov[] = {0x48, 0x89}; - uint8_t op1 = (MOD_DIRECT << 6) | (src << 3) | dest; if (buf) { - memcpy(buf, mov, 2); - buf += 2; - *(buf++) = op1; + *(buf++) = REX_W; + *(buf++) = 0x89; + *(buf++) = (MOD_DIRECT << 6) | (src << 3) | dest; } return 3; @@ -130,11 +134,10 @@ 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) { - uint8_t mov[] = {0x48, 0x89}; assert(src != 4); if (buf) { - memcpy(buf, mov, 2); - buf += 2; + *(buf++) = REX_W; + *(buf++) = 0x89; *(buf++) = (MOD_DISP8 << 6) | (dest << 3) | src; *(buf++) = disp; } @@ -145,11 +148,10 @@ mov_disp8_m64_r64(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) { - uint8_t mov[] = {0x48, 0x8b}; assert(src != 4); if (buf) { - memcpy(buf, mov, 2); - buf += 2; + *(buf++) = REX_W; + *(buf++) = 0x8b; *(buf++) = (MOD_DISP8 << 6) | (dest << 3) | src; *(buf++) = disp; } @@ -158,28 +160,24 @@ mov_disp8_r64_m64(char *buf, enum reg dest, enum reg src, int8_t disp) } size_t -add_r64_r64(char *buf, enum reg reg1, enum reg reg2) +add_r64_r64(char *buf, enum reg dest, enum reg src) { - uint8_t mov[] = {0x48, 0x03}; - uint8_t op = (MOD_DIRECT << 6) | (reg1 << 3) | reg2; if (buf) { - memcpy(buf, mov, 2); - buf += 2; - *(buf++) = op; + *(buf++) = REX_W; + *(buf++) = 0x03; + *(buf++) = (MOD_DIRECT << 6) | (dest << 3) | src; } return 3; } size_t -sub_r64_r64(char *buf, enum reg reg1, enum reg reg2) +sub_r64_r64(char *buf, enum reg dest, enum reg src) { - uint8_t mov[] = {0x48, 0x2B}; - uint8_t op = (MOD_DIRECT << 6) | (reg1 << 3) | reg2; if (buf) { - memcpy(buf, mov, 2); - buf += 2; - *(buf++) = op; + *(buf++) = REX_W; + *(buf++) = 0x2b; + *(buf++) = (MOD_DIRECT << 6) | (dest << 3) | src; } return 3; @@ -188,12 +186,10 @@ sub_r64_r64(char *buf, enum reg reg1, enum reg reg2) size_t sub_r64_imm(char *buf, enum reg dest, int32_t imm) { - uint8_t mov[] = {0x48, 0x81}; - uint8_t op1 = (MOD_DIRECT << 6) | (5 << 3) | dest; if (buf) { - memcpy(buf, mov, 2); - buf += 2; - *(buf++) = op1; + *(buf++) = REX_W; + *(buf++) = 0x81; + *(buf++) = (MOD_DIRECT << 6) | (5 << 3) | dest; *(buf++) = imm & 0xFF; *(buf++) = (imm >> 8) & 0xFF; *(buf++) = (imm >> 16) & 0xFF; @@ -206,12 +202,10 @@ sub_r64_imm(char *buf, enum reg dest, int32_t imm) size_t cmp_r64_r64(char *buf, enum reg reg1, enum reg reg2) { - uint8_t mov[] = {0x48, 0x3B}; - uint8_t op = (MOD_DIRECT << 6) | (reg1 << 3) | reg2; if (buf) { - memcpy(buf, mov, 2); - buf += 2; - *(buf++) = op; + *(buf++) = REX_W; + *(buf++) = 0x3b; + *(buf++) = (MOD_DIRECT << 6) | (reg1 << 3) | reg2; } return 3; @@ -282,9 +276,8 @@ call(char *buf, enum reg reg) size_t ret(char *buf) { - if (buf) { - *(buf++) = 0xC3; - } + if (buf) + *buf = 0xC3; return 1; } @@ -292,13 +285,15 @@ ret(char *buf) size_t push_r64(char *buf, enum reg reg) { if (buf) - *(buf++) = 0x50 + reg; + *buf = 0x50 + reg; + return 1; } size_t pop_r64(char *buf, enum reg reg) { if (buf) - *(buf++) = 0x58 + reg; + *buf = 0x58 + reg; + return 1; } diff --git a/x64.h b/x64.h @@ -17,13 +17,6 @@ enum reg { R15, }; -enum mod { - MOD_INDIRECT, - MOD_DISP8, - MOD_DISP32, - MOD_DIRECT -}; - extern char abi_arg[]; extern unsigned short used_reg; @@ -31,8 +24,8 @@ void clearreg(); enum reg getreg(); void freereg(enum reg reg); -size_t add_r_imm(char *buf, enum reg reg, uint64_t imm); -size_t mov_r_imm(char *buf, enum reg reg, uint64_t imm); +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_m64_r64(char *buf, uint64_t addr, enum reg reg); size_t mov_r64_r64(char *buf, enum reg dest, enum reg src);