harec

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

commit 8d06b9a270acd898b1165554c315a0a525f59658
parent 40ea5a9032b91a52003aaae30f02381d89faa4f4
Author: Drew DeVault <sir@cmpwn.com>
Date:   Sat,  3 Jul 2021 11:30:21 -0400

gen: implement unary address operator

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

Diffstat:
Msrc/gen.c | 45++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 40 insertions(+), 5 deletions(-)

diff --git a/src/gen.c b/src/gen.c @@ -106,6 +106,16 @@ load_temp(struct gen_context *ctx, } } +// Obtains the address of a temporary and changes it to the given pointer type. +static void +temp_address(struct gen_temp *temp, const struct type *type) +{ + assert(type_dealias(type)->storage == STORAGE_POINTER); + assert(temp->indirect); + temp->indirect = false; + temp->type = type; +} + static const struct gen_binding * binding_lookup(struct gen_context *ctx, const struct scope_object *obj) { @@ -382,6 +392,7 @@ gen_expr_const_array(struct gen_context *ctx, const struct gen_temp *out) { 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); @@ -522,10 +533,7 @@ gen_expr_struct(struct gen_context *ctx, const struct expression *expr, const struct gen_temp *out) { - if (!out) { - pushc(ctx->current, "Useless struct expression dropped"); - return; - } + assert(out); // TODO: Ensure side-effects occur struct qbe_value base = {0}, ptr = {0}, offs = {0}; qval_temp(ctx, &base, out); gen_qtemp(ctx, &ptr, ctx->arch.ptr, "offset.%d"); @@ -563,6 +571,31 @@ gen_expr_struct(struct gen_context *ctx, } static void +gen_expr_unarithm(struct gen_context *ctx, + const struct expression *expr, + const struct gen_temp *out) +{ + assert(out); // TODO: Ensure side-effects occur + + struct gen_temp temp; + const struct expression *operand = expr->unarithm.operand; + switch (expr->unarithm.op) { + case UN_ADDRESS: + assert(operand->type == EXPR_ACCESS); + gen_access_address(ctx, &temp, operand); + temp_address(&temp, out->type); + gen_copy(ctx, out, &temp); + break; + case UN_BNOT: + case UN_DEREF: + case UN_LNOT: + case UN_MINUS: + case UN_PLUS: + assert(0); // TODO + } +} + +static void gen_expr(struct gen_context *ctx, const struct expression *expr, const struct gen_temp *out) @@ -616,8 +649,10 @@ gen_expr(struct gen_context *ctx, break; case EXPR_SWITCH: case EXPR_TUPLE: - case EXPR_UNARITHM: assert(0); // TODO + case EXPR_UNARITHM: + gen_expr_unarithm(ctx, expr, out); + break; } }