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:
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);