commit 3da844c1c2cf0854756599b0eddea076d272a9f7
parent 770ed9ded1cc982eeeee7fd86146e2fe75f36afb
Author: Drew DeVault <sir@cmpwn.com>
Date: Wed, 14 Jul 2021 16:41:43 +0200
gen: fix binarithm with direct output
Signed-off-by: Drew DeVault <sir@cmpwn.com>
Diffstat:
5 files changed, 37 insertions(+), 13 deletions(-)
diff --git a/include/gen.h b/include/gen.h
@@ -72,6 +72,8 @@ void alloc_temp(struct gen_context *ctx, struct gen_temp *temp,
const struct type *type, const char *fmt);
void load_temp(struct gen_context *ctx, struct qbe_value *out,
const struct gen_temp *temp);
+void store_temp(struct gen_context *ctx,const struct gen_temp *temp,
+ struct qbe_value *value);
void temp_address(struct gen_temp *temp, const struct type *type);
void temp_deref(struct gen_temp *temp);
const struct gen_binding *binding_lookup(struct gen_context *ctx,
diff --git a/src/gen.c b/src/gen.c
@@ -156,16 +156,9 @@ gen_copy(struct gen_context *ctx,
}
// Copy between types which have a native qbe representation
- struct qbe_value value = {0}, dtemp = {0};
+ struct qbe_value value = {0};
load_temp(ctx, &value, src);
- qval_temp(ctx, &dtemp, dest);
-
- if (dest->indirect) {
- enum qbe_instr instr = store_for_type(ctx, dtype);
- pushi(ctx->current, NULL, instr, &value, &dtemp, NULL);
- } else {
- pushi(ctx->current, &dtemp, Q_COPY, &value, NULL);
- }
+ store_temp(ctx, dest, &value);
}
static void gen_expr(struct gen_context *ctx,
@@ -376,9 +369,10 @@ gen_expr_binarithm(struct gen_context *ctx,
enum qbe_instr instr = binarithm_for_op(
ctx, expr->binarithm.op, lvexpr->result);
- struct qbe_value qout;
- qval_temp(ctx, &qout, out);
- pushi(ctx->current, &qout, instr, &lvalue, &rvalue, NULL);
+ struct qbe_value result;
+ gen_qtemp(ctx, &result, lvalue.type, "result.%d");
+ pushi(ctx->current, &result, instr, &lvalue, &rvalue, NULL);
+ store_temp(ctx, out, &result);
}
static void
diff --git a/src/genutil.c b/src/genutil.c
@@ -115,6 +115,22 @@ load_temp(struct gen_context *ctx,
}
}
+void
+store_temp(struct gen_context *ctx,
+ const struct gen_temp *temp,
+ struct qbe_value *value)
+{
+ struct qbe_value out;
+ qval_temp(ctx, &out, temp);
+
+ if (temp->indirect) {
+ enum qbe_instr instr = store_for_type(ctx, temp->type);
+ pushi(ctx->current, NULL, instr, value, &out, NULL);
+ } else {
+ pushi(ctx->current, &out, Q_COPY, value, NULL);
+ }
+}
+
// Obtains the address of a temporary and changes it to the given pointer type.
void
temp_address(struct gen_temp *temp, const struct type *type)
diff --git a/tests/902-arithm.ha b/tests/902-arithm.ha
@@ -0,0 +1,11 @@
+export fn main() int = {
+ // Direct
+ let x: int = 10;
+ x = 2 + 2;
+ assert(x == 4);
+
+ // Indirect
+ let x = [1, 2, 3];
+ assert(x[1 + 1] == 3);
+ return 0;
+};
diff --git a/tests/configure b/tests/configure
@@ -5,7 +5,8 @@ tests() {
# Temporary test suite
for t in \
900-basics \
- 901-primitives
+ 901-primitives \
+ 902-arithm
do
cat <<EOF
tests/$t: tests/$t.ha