nooc

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

commit 0b0ff5596418b4f4fcac145e99ffd419afa81f37
parent 695cc9130a08fa77369eef0ec44c260e36c4ef1b
Author: Nihal Jere <nihal@nihaljere.xyz>
Date:   Wed, 29 Dec 2021 19:39:41 -0600

reference to local variables

required adding lea

Diffstat:
Mmain.c | 5++++-
Atest/pointer_local.pass.nooc | 5+++++
Mx64.c | 14++++++++++++++
Mx64.h | 1+
4 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/main.c b/main.c @@ -451,7 +451,6 @@ genexpr(char *buf, size_t idx, struct place *out) struct expr *ident = &exprs.data[expr->d.uop.expr]; assert(ident->kind == EXPR_IDENT); struct decl *decl = finddecl(ident->d.s); - assert(decl->place.kind == PLACE_ABS); struct place src = { .kind = PLACE_REG, .l.reg = getreg(), .size = 8 }; switch (decl->place.kind) { @@ -459,6 +458,10 @@ genexpr(char *buf, size_t idx, struct place *out) total += mov_r64_imm(buf ? buf + total : NULL, src.l.reg, decl->place.l.addr); total += place_move(buf ? buf + total : NULL, out, &src); break; + case PLACE_FRAME: + total += lea_disp8(buf ? buf + total : NULL, src.l.reg, RBP, -decl->place.l.off); + total += place_move(buf ? buf + total : NULL, out, &src); + break; default: die("genexpr: unhandled place kind for EXPR_UNARY"); } diff --git a/test/pointer_local.pass.nooc b/test/pointer_local.pass.nooc @@ -0,0 +1,5 @@ +let main proc() = proc() { + let c i8 = 65 + syscall(1, 1, $c, 1) + syscall(60, 0) +} diff --git a/x64.c b/x64.c @@ -460,6 +460,20 @@ 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) +{ + assert(src != 4); + if (buf) { + *(buf++) = REX_W; + *(buf++) = 0x8d; + *(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 @@ -50,6 +50,7 @@ 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);