harec

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

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:
Minclude/gen.h | 2++
Msrc/gen.c | 18++++++------------
Msrc/genutil.c | 16++++++++++++++++
Atests/902-arithm.ha | 11+++++++++++
Mtests/configure | 3++-
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