harec

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

commit 867863e01b9163167fae3f81fe3bf156e73da075
parent ebf6048bcef837d211d9bdb15a7ae3eda08b45df
Author: Drew DeVault <sir@cmpwn.com>
Date:   Fri, 13 Aug 2021 10:03:44 +0200

gen: implement static insert

Also re-enables 28-insert and fixes the bugs uncovered from that.

Signed-off-by: Drew DeVault <sir@cmpwn.com>

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

diff --git a/src/gen.c b/src/gen.c @@ -1630,13 +1630,30 @@ gen_expr_insert(struct gen_context *ctx, const struct expression *expr) enum qbe_instr store = store_for_type(ctx, &builtin_type_size); pushi(ctx->current, NULL, store, &newlen, &lenptr, NULL); + struct qbe_value membsz = constl(mtype->size); - assert(!expr->append.is_static); // TODO + if (!expr->insert.is_static) { + struct qbe_value rtfunc = mkrtfunc(ctx, "rt.ensure"); + struct qbe_value lval = mklval(ctx, &slice); + pushi(ctx->current, NULL, Q_CALL, &rtfunc, &lval, &membsz, NULL); + } else { + struct qbe_value ptr = mkqtmp(ctx, ctx->arch.ptr, ".%d"); + pushi(ctx->current, &ptr, Q_ADD, &lenptr, &offs, NULL); + struct qbe_value cap = mkqtmp(ctx, ctx->arch.ptr, ".%d"); + pushi(ctx->current, &cap, load, &ptr, NULL); - struct qbe_value rtfunc = mkrtfunc(ctx, "rt.ensure"); - struct qbe_value lval = mklval(ctx, &slice); - struct qbe_value membsz = constl(mtype->size); - pushi(ctx->current, NULL, Q_CALL, &rtfunc, &lval, &membsz, NULL); + struct qbe_statement lvalid, linvalid; + struct qbe_value bvalid = mklabel(ctx, &lvalid, ".%d"); + struct qbe_value binvalid = mklabel(ctx, &linvalid, ".%d"); + struct qbe_value valid = mkqtmp(ctx, &qbe_word, ".%d"); + pushi(ctx->current, &valid, Q_CULEL, &newlen, &cap, NULL); + pushi(ctx->current, NULL, Q_JNZ, &valid, &bvalid, &binvalid, NULL); + push(&ctx->current->body, &linvalid); + + gen_fixed_abort(ctx, expr->loc, ABORT_OOB); + + push(&ctx->current->body, &lvalid); + } struct qbe_value base = mkqtmp(ctx, ctx->arch.ptr, ".%d"); pushi(ctx->current, &base, load, &qslice, NULL); @@ -1647,11 +1664,14 @@ gen_expr_insert(struct gen_context *ctx, const struct expression *expr) struct qbe_value nbyte = mkqtmp(ctx, ctx->arch.sz, ".%d"); struct qbe_value dest = mkqtmp(ctx, ctx->arch.ptr, ".%d"); pushi(ctx->current, &nbyte, Q_ADD, &nadd, &vlen, NULL); + struct qbe_value ncopy = mkqtmp(ctx, ctx->arch.sz, ".%d"); + pushi(ctx->current, &ncopy, Q_SUB, &len, &qindex, NULL); pushi(ctx->current, &nbyte, Q_MUL, &nbyte, &membsz, NULL); + pushi(ctx->current, &ncopy, Q_MUL, &ncopy, &membsz, NULL); pushi(ctx->current, &dest, Q_ADD, &src, &nbyte, NULL); - rtfunc = mkrtfunc(ctx, "rt.memmove"); - pushi(ctx->current, NULL, Q_CALL, &rtfunc, &dest, &src, &nbyte, NULL); + struct qbe_value rtfunc = mkrtfunc(ctx, "rt.memmove"); + pushi(ctx->current, NULL, Q_CALL, &rtfunc, &dest, &src, &ncopy, NULL); struct gen_value gv = { .kind = GV_TEMP, diff --git a/tests/configure b/tests/configure @@ -31,13 +31,13 @@ tests() { 25-promotion \ 26-gen \ 27-rt \ + 28-insert \ 29-unarithm \ 31-postfix \ 32-copy # Disabled tests #22-delete \ - #28-insert \ do cat <<EOF tests/$t: libhart.a tests/$t.ha