harec

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

commit 7b8980d2534d02e53c6a7aa1aa6b8b9cce3e4076
parent e2627649a594d353f51c460bf87129853124b72d
Author: Drew DeVault <sir@cmpwn.com>
Date:   Sun,  4 Jul 2021 12:13:53 -0400

gen: introduce temp_workcopy

This function creates a new temporary which is a working copy of a gen
temporary, so that you can do things like add offsets to it without
altering the original.

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

Diffstat:
Msrc/gen.c | 34++++++++++++++++++----------------
1 file changed, 18 insertions(+), 16 deletions(-)

diff --git a/src/gen.c b/src/gen.c @@ -53,6 +53,18 @@ gen_direct(struct gen_context *ctx, struct gen_temp *temp, assert(qtype->stype != Q__AGGREGATE && qtype->stype != Q__VOID); } +// Emits a qbe copy instruction which makes a working copy of a gen temporary. +static void +temp_workcopy(struct gen_context *ctx, struct qbe_value *qval, + const struct qbe_type *qtype, + const struct gen_temp *temp, const char *fmt) +{ + struct qbe_value qtemp = {0}; + gen_qtemp(ctx, qval, qtype, fmt); + qval_temp(ctx, &qtemp, temp); + pushi(ctx->current, qval, Q_COPY, &qtemp, NULL); +} + // Allocates a temporary of the given type on the stack in the current // function's preamble. static void @@ -209,17 +221,11 @@ gen_copy_string(struct gen_context *ctx, enum qbe_instr load = load_for_type(ctx, voidptr); struct qbe_value dptr = {0}, sptr = {0}, temp = {0}, offset = {0}; - struct qbe_value qdest = {0}, qsrc = {0}; - gen_qtemp(ctx, &dptr, ctx->arch.ptr, "dptr.%d"); - gen_qtemp(ctx, &sptr, ctx->arch.ptr, "sptr.%d"); + temp_workcopy(ctx, &dptr, ctx->arch.ptr, dest, "dptr.%d"); + temp_workcopy(ctx, &sptr, ctx->arch.ptr, src, "sptr.%d"); gen_qtemp(ctx, &temp, ctx->arch.ptr, "temp.%d"); - qval_temp(ctx, &qdest, dest); - qval_temp(ctx, &qsrc, src); constl(&offset, voidptr->size); - pushi(ctx->current, &dptr, Q_COPY, &qdest, NULL); - pushi(ctx->current, &sptr, Q_COPY, &qsrc, NULL); - // Data pushi(ctx->current, &temp, load, &sptr, NULL); pushi(ctx->current, NULL, store, &dptr, &temp, NULL); @@ -463,11 +469,9 @@ gen_expr_const_array(struct gen_context *ctx, assert(!expr->expand); // TODO assert(out); // TODO: Ensure side-effects occur - struct qbe_value base = {0}, ptr = {0}, membsz = {0}; - qval_temp(ctx, &base, out); - gen_qtemp(ctx, &ptr, ctx->arch.ptr, "offset.%d"); + struct qbe_value ptr = {0}, membsz = {0}; + temp_workcopy(ctx, &ptr, ctx->arch.ptr, out, "offset.%d"); constl(&membsz, atype->array.members->size); - pushi(ctx->current, &ptr, Q_COPY, &base, NULL); for (const struct array_constant *ac = expr; ac; ac = ac->next) { struct gen_temp temp = { @@ -508,10 +512,8 @@ gen_expr_const_string(struct gen_context *ctx, } assert(out->indirect); // Invariant - struct qbe_value qout = {0}, temp = {0}; - qval_temp(ctx, &qout, out); - gen_qtemp(ctx, &temp, ctx->arch.ptr, "str.%d"); - pushi(ctx->current, &temp, Q_COPY, &qout, NULL); + struct qbe_value temp = {0}; + temp_workcopy(ctx, &temp, ctx->arch.ptr, out, "str.%d"); struct qbe_value offset = {0}, qlength = {0}; const struct type *voidptr = type_store_lookup_pointer(ctx->store,