harec

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

commit ebf6048bcef837d211d9bdb15a7ae3eda08b45df
parent 6498602e151d782f2845d91f26bd9954abb9b399
Author: Drew DeVault <sir@cmpwn.com>
Date:   Fri, 13 Aug 2021 09:26:44 +0200

gen: implement variadic insert

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

Diffstat:
Msrc/gen.c | 23+++++++++++++++++++++--
1 file changed, 21 insertions(+), 2 deletions(-)

diff --git a/src/gen.c b/src/gen.c @@ -1613,7 +1613,20 @@ gen_expr_insert(struct gen_context *ctx, const struct expression *expr) struct qbe_value newlen = mkqtmp(ctx, ctx->arch.sz, ".%d"); pushi(ctx->current, &newlen, Q_ADD, &len, &nadd, NULL); - assert(!expr->insert.variadic); // TODO + struct gen_value vobj; + struct qbe_value vlen = constl(0), vdata; + if (expr->insert.variadic) { + vobj = gen_expr(ctx, expr->insert.variadic); + struct qbe_value lval = mklval(ctx, &vobj); + vdata = mkqtmp(ctx, ctx->arch.ptr, ".%d"); + pushi(ctx->current, &vdata, load, &lval, NULL); + + struct qbe_value vptr = mkqtmp(ctx, ctx->arch.ptr, ".%d"); + vlen = mkqtmp(ctx, ctx->arch.sz, ".%d"); + pushi(ctx->current, &vptr, Q_ADD, &lval, &offs, NULL); + pushi(ctx->current, &vlen, load, &vptr, NULL); + pushi(ctx->current, &newlen, Q_ADD, &newlen, &vlen, NULL); + } enum qbe_instr store = store_for_type(ctx, &builtin_type_size); pushi(ctx->current, NULL, store, &newlen, &lenptr, NULL); @@ -1633,7 +1646,8 @@ gen_expr_insert(struct gen_context *ctx, const struct expression *expr) pushi(ctx->current, &src, Q_ADD, &base, &src, NULL); 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_MUL, &nadd, &membsz, NULL); + pushi(ctx->current, &nbyte, Q_ADD, &nadd, &vlen, NULL); + pushi(ctx->current, &nbyte, Q_MUL, &nbyte, &membsz, NULL); pushi(ctx->current, &dest, Q_ADD, &src, &nbyte, NULL); rtfunc = mkrtfunc(ctx, "rt.memmove"); @@ -1649,6 +1663,11 @@ gen_expr_insert(struct gen_context *ctx, const struct expression *expr) gen_expr_at(ctx, value->expr, gv); pushi(ctx->current, &src, Q_ADD, &src, &membsz, NULL); } + if (expr->insert.variadic) { + rtfunc = mkrtfunc(ctx, "rt.memcpy"); + pushi(ctx->current, &nbyte, Q_MUL, &vlen, &membsz, NULL); + pushi(ctx->current, NULL, Q_CALL, &rtfunc, &src, &vdata, &nbyte, NULL); + } return gv_void; }