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:
M | main.c | | | 10 | +++++----- |
M | x64.c | | | 119 | ++++++++++++++++++++++++++++++++++++++----------------------------------------- |
M | x64.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);