nooc

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

commit ec7dafa82296ddd9c75a487dc7c94e5701f1bd12
parent ff44515007b9436695136c7cb97009409b5fe45f
Author: Nihal Jere <nihal@nihaljere.xyz>
Date:   Sun, 26 Dec 2021 16:10:49 -0600

i16

Diffstat:
Mmain.c | 33+++++++++++++++++++++++++++++++++
Mtype.c | 4++++
Mx64.c | 86+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mx64.h | 6++++++
4 files changed, 129 insertions(+), 0 deletions(-)

diff --git a/main.c b/main.c @@ -113,6 +113,9 @@ place_move(char *buf, struct place *dest, struct place *src) case 4: total += mov_mr32_r32(buf ? buf + total : NULL, dest->l.reg, src->l.reg); break; + case 2: + total += mov_mr16_r16(buf ? buf + total : NULL, dest->l.reg, src->l.reg); + break; default: die("place_move: REG -> REGADDR: unhandled size"); } @@ -125,6 +128,9 @@ place_move(char *buf, struct place *dest, struct place *src) case 4: total += mov_disp8_m32_r32(buf ? buf + total : NULL, RBP, -dest->l.off, src->l.reg); break; + case 2: + total += mov_disp8_m16_r16(buf ? buf + total : NULL, RBP, -dest->l.off, src->l.reg); + break; default: die("place_move: REG -> REGADDR: unhandled size"); } @@ -153,6 +159,15 @@ place_move(char *buf, struct place *dest, struct place *src) die("place_move: unhandled dest case for PLACE_REGADDR"); } break; + case 2: + switch (dest->kind) { + case PLACE_REG: + total += mov_r16_mr16(buf ? buf + total : NULL, dest->l.reg, src->l.reg); + break; + default: + die("place_move: unhandled dest case for PLACE_REGADDR"); + } + break; default: die("place_move: REGADDR: src unhandled size"); } @@ -177,6 +192,15 @@ place_move(char *buf, struct place *dest, struct place *src) die("place_move: unhandled dest case for PLACE_FRAME"); } break; + case 2: + switch (dest->kind) { + case PLACE_REG: + total += mov_disp8_r16_m16(buf ? buf + total : NULL, dest->l.reg, RBP, -src->l.off); + break; + default: + die("place_move: unhandled dest case for PLACE_FRAME"); + } + break; default: die("place_move: FRAME: src unhandled size"); } @@ -201,6 +225,15 @@ place_move(char *buf, struct place *dest, struct place *src) die("place_move: unhandled dest case for PLACE_ABS"); } break; + case 2: + switch (dest->kind) { + case PLACE_REG: + total += mov_r16_m16(buf ? buf + total : NULL, dest->l.reg, src->l.addr); + break; + default: + die("place_move: unhandled dest case for PLACE_ABS"); + } + break; default: die("place_move: ABS: src unhandled size"); } diff --git a/type.c b/type.c @@ -52,6 +52,10 @@ inittypes() mapkey(&key, "i32", 3); mapput(typesmap, &key)->n = idx; + type.class = TYPE_INT; + type.size = 2; + idx = type_put(&type); + mapkey(&key, "i16", 3); mapput(typesmap, &key)->n = idx; type.class = TYPE_STR; diff --git a/x64.c b/x64.c @@ -22,6 +22,8 @@ enum mod { MOD_DIRECT }; +#define OP_SIZE_OVERRIDE 0x66 + char abi_arg[] = {RAX, RDI, RSI, RDX, R10, R8, R9}; unsigned short used_reg; @@ -101,6 +103,19 @@ mov_r32_imm(char *buf, enum reg dest, uint32_t imm) } size_t +mov_r16_imm(char *buf, enum reg dest, uint16_t imm) +{ + if (buf) { + *(buf++) = OP_SIZE_OVERRIDE; + *(buf++) = 0xb8; + *(buf++) = imm & 0xFF; + *(buf++) = (imm >> 8) & 0xFF; + } + + return 4; +} + +size_t mov_r64_m64(char *buf, enum reg dest, uint64_t addr) { uint8_t sib = 0x25; @@ -136,6 +151,24 @@ mov_r32_m32(char *buf, enum reg dest, uint32_t addr) } size_t +mov_r16_m16(char *buf, enum reg dest, uint32_t addr) +{ + if (buf) { + *(buf++) = OP_SIZE_OVERRIDE; + if (dest >= 8) *(buf++) = REX_R; + *(buf++) = 0x8b; + *(buf++) = (MOD_INDIRECT << 6) | ((dest & 7) << 3) | 4; + *(buf++) = 0x25; + *(buf++) = addr & 0xFF; + *(buf++) = (addr >> 8) & 0xFF; + *(buf++) = (addr >> 16) & 0xFF; + *(buf++) = (addr >> 24) & 0xFF; + } + + return dest >= 8 ? 9 : 8; +} + +size_t mov_m64_r64(char *buf, uint64_t addr, enum reg src) { if (buf) { @@ -196,6 +229,18 @@ mov_mr32_r32(char *buf, enum reg dest, enum reg src) } size_t +mov_mr16_r16(char *buf, enum reg dest, enum reg src) +{ + if (buf) { + *(buf++) = OP_SIZE_OVERRIDE; + *(buf++) = 0x8B; + *(buf++) = (MOD_INDIRECT << 6) | (src << 3) | dest; + } + + return 3; +} + +size_t mov_r64_mr64(char *buf, enum reg dest, enum reg src) { if (buf) { @@ -219,6 +264,18 @@ mov_r32_mr32(char *buf, enum reg dest, enum reg src) } size_t +mov_r16_mr16(char *buf, enum reg dest, enum reg src) +{ + if (buf) { + *(buf++) = OP_SIZE_OVERRIDE; + *(buf++) = 0x89; + *(buf++) = (MOD_INDIRECT << 6) | (dest << 3) | src; + } + + return 3; +} + +size_t mov_r64_r64(char *buf, enum reg dest, enum reg src) { if (buf) { @@ -270,6 +327,21 @@ mov_disp8_m32_r32(char *buf, enum reg dest, int8_t disp, enum reg src) return 3; } +// FIXME: we don't handle r8-r15 properly in most of these +size_t +mov_disp8_m16_r16(char *buf, enum reg dest, int8_t disp, enum reg src) +{ + assert(src != 4); + if (buf) { + *(buf++) = OP_SIZE_OVERRIDE; + *(buf++) = 0x89; + *(buf++) = (MOD_DISP8 << 6) | (src << 3) | dest; + *(buf++) = disp; + } + + return 4; +} + size_t mov_disp8_r64_m64(char *buf, enum reg dest, enum reg src, int8_t disp) { @@ -298,6 +370,20 @@ 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) +{ + assert(src != 4); + if (buf) { + *(buf++) = OP_SIZE_OVERRIDE; + *(buf++) = 0x8b; + *(buf++) = (MOD_DISP8 << 6) | (dest << 3) | src; + *(buf++) = disp; + } + + return 4; +} + +size_t add_r64_r64(char *buf, enum reg dest, enum reg src) { if (buf) { diff --git a/x64.h b/x64.h @@ -28,17 +28,23 @@ 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_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_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_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_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 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);