harec

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

commit 67cc0152d27f5b777313d4969f14d5ce296152b3
parent f01835375e63f3279381782d0ac837420423ef62
Author: Drew DeVault <sir@cmpwn.com>
Date:   Wed, 23 Dec 2020 16:04:13 -0500

gen: (mostly) implement unary arithmetic

Diffstat:
Msrc/gen.c | 50++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 50 insertions(+), 0 deletions(-)

diff --git a/src/gen.c b/src/gen.c @@ -296,6 +296,53 @@ gen_expr_return(struct gen_context *ctx, } static void +gen_expr_unarithm(struct gen_context *ctx, + const struct expression *expr, + const struct qbe_value *out) +{ + const struct qbe_type *otype = + qtype_for_type(ctx, expr->unarithm.operand->result, false); + const struct qbe_type *rtype = qtype_for_type(ctx, expr->result, false); + + struct qbe_value operand = {0}, result = {0}; + gen_temp(ctx, &operand, otype, "operand.%d"); + gen_temp(ctx, &result, rtype, "result.%d"); + + gen_expression(ctx, expr->unarithm.operand, &operand); + + struct qbe_value temp = {0}; + switch (expr->unarithm.op) { + case UN_LNOT: + temp.kind = QV_CONST; + temp.type = otype; + temp.lval = 1; + pushi(ctx->current, &result, Q_XOR, &temp, &operand, NULL); + break; + case UN_BNOT: + temp.kind = QV_CONST; + temp.type = otype; + temp.lval = (uint64_t)-1; + pushi(ctx->current, &result, Q_XOR, &temp, &operand, NULL); + break; + case UN_MINUS: + temp.kind = QV_CONST; + temp.type = otype; + temp.lval = 0; + pushi(ctx->current, &result, Q_SUB, &temp, &operand, NULL); + break; + case UN_PLUS: + // no-op + result = operand; + break; + case UN_ADDRESS: + case UN_DEREF: + assert(0); // TODO + } + + gen_store(ctx, out, &result); +} + +static void gen_expression(struct gen_context *ctx, const struct expression *expr, const struct qbe_value *out) @@ -338,7 +385,10 @@ gen_expression(struct gen_context *ctx, case EXPR_SLICE: case EXPR_STRUCT: case EXPR_SWITCH: + assert(0); // TODO case EXPR_UNARITHM: + gen_expr_unarithm(ctx, expr, out); + break; case EXPR_WHILE: assert(0); // TODO }