harec

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

commit bdbd60bf9e257ecb6a6aa45d65460e846f17cd81
parent 54be90686905f02100e97fedae9657b1661e012e
Author: Eyal Sawady <ecs@d2evs.net>
Date:   Tue, 10 Aug 2021 10:37:19 +0000

gen: implement slice assignment

Also enable 08-slices

Signed-off-by: Eyal Sawady <ecs@d2evs.net>

Diffstat:
Msrc/gen.c | 44+++++++++++++++++++++++++++++++++++++++++++-
Mtests/configure | 2+-
2 files changed, 44 insertions(+), 2 deletions(-)

diff --git a/src/gen.c b/src/gen.c @@ -580,12 +580,54 @@ gen_expr_assert(struct gen_context *ctx, const struct expression *expr) } static struct gen_value +gen_expr_assign_slice(struct gen_context *ctx, const struct expression *expr) +{ + struct gen_value obj = gen_expr(ctx, expr->assign.object); + struct gen_value val = gen_expr(ctx, expr->assign.value); + struct qbe_value qobj = mkqval(ctx, &obj); + struct qbe_value qval = mkqval(ctx, &val); + struct qbe_value step = constl(ctx->arch.ptr->size); + + struct qbe_value ptr = mkqtmp(ctx, ctx->arch.ptr, ".%d"); + struct qbe_value olen = mkqtmp(ctx, ctx->arch.ptr, ".%d"); + struct qbe_value vlen = mkqtmp(ctx, ctx->arch.ptr, ".%d"); + + pushi(ctx->current, &ptr, Q_ADD, &qobj, &step, NULL); + pushi(ctx->current, &olen, Q_LOADL, &ptr, NULL); + pushi(ctx->current, &ptr, Q_ADD, &qval, &step, NULL); + pushi(ctx->current, &vlen, Q_LOADL, &ptr, NULL); + + struct qbe_statement linvalid, lvalid; + struct qbe_value binvalid = mklabel(ctx, &linvalid, ".%d"); + struct qbe_value bvalid = mklabel(ctx, &lvalid, ".%d"); + struct qbe_value tmp = mkqtmp(ctx, &qbe_long, ".%d"); + pushi(ctx->current, &tmp, Q_CUGEL, &olen, &vlen, NULL); + pushi(ctx->current, NULL, Q_JNZ, &tmp, &bvalid, &binvalid, NULL); + push(&ctx->current->body, &linvalid); + gen_fixed_abort(ctx, expr->loc, ABORT_OOB); + push(&ctx->current->body, &lvalid); + + struct qbe_value rtmemcpy = mkrtfunc(ctx, "rt.memcpy"); + struct qbe_value optr = mkqtmp(ctx, ctx->arch.ptr, ".%d"); + struct qbe_value vptr = mkqtmp(ctx, ctx->arch.ptr, ".%d"); + pushi(ctx->current, &optr, Q_LOADL, &qobj, NULL); + pushi(ctx->current, &vptr, Q_LOADL, &qval, NULL); + tmp = constl(expr->assign.object->result->array.members->size); + pushi(ctx->current, &olen, Q_MUL, &olen, &tmp, NULL); + pushi(ctx->current, NULL, Q_CALL, &rtmemcpy, &optr, &vptr, &olen, NULL); + + return gv_void; +} + +static struct gen_value gen_expr_assign(struct gen_context *ctx, const struct expression *expr) { struct expression *object = expr->assign.object; struct expression *value = expr->assign.value; + if (object->type == EXPR_SLICE) { + return gen_expr_assign_slice(ctx, expr); + } assert(object->type == EXPR_ACCESS || expr->assign.indirect); // Invariant - assert(object->type != EXPR_SLICE); // TODO struct gen_value obj; if (expr->assign.indirect) { diff --git a/tests/configure b/tests/configure @@ -47,6 +47,7 @@ EOF 05-implicit-casts \ 06-structs \ 07-aliases \ + 08-slices \ 09-funcs \ 10-binarithms \ 11-globals \ @@ -62,7 +63,6 @@ EOF 29-unarithm # Disabled tests - #08-slices \ #12-loops \ #16-defer \ #18-match \