harec

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

commit b1751497f2da4c902d9457c7de034c03d65fdc57
parent 73d32ab237ae360fe25ad74a56344b6a7855832c
Author: Eyal Sawady <ecs@d2evs.net>
Date:   Tue, 10 Aug 2021 06:21:07 +0000

gen: implement && and ||

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

diff --git a/src/gen.c b/src/gen.c @@ -529,7 +529,24 @@ gen_expr_assign(struct gen_context *ctx, const struct expression *expr) if (expr->assign.op == BIN_LEQUAL) { gen_expr_at(ctx, value, obj); } else if (expr->assign.op == BIN_LAND || expr->assign.op == BIN_LOR) { - assert(0); // TODO + struct qbe_statement lrval, lshort; + struct qbe_value brval = mklabel(ctx, &lrval, ".%d"); + struct qbe_value bshort = mklabel(ctx, &lshort, ".%d"); + struct gen_value load = gen_load(ctx, obj); + struct qbe_value qload = mkqval(ctx, &load); + if (expr->binarithm.op == BIN_LAND) { + pushi(ctx->current, NULL, Q_JNZ, &qload, &brval, + &bshort, NULL); + } else { + pushi(ctx->current, NULL, Q_JNZ, &qload, &bshort, + &brval, NULL); + } + push(&ctx->current->body, &lrval); + gen_expr_at(ctx, value, obj); + if (!expr->binarithm.rvalue->terminates) { + pushi(ctx->current, NULL, Q_JMP, &bshort, NULL); + } + push(&ctx->current->body, &lshort); } else { struct gen_value lvalue = gen_load(ctx, obj); struct gen_value rvalue = gen_expr(ctx, value); @@ -549,12 +566,38 @@ gen_expr_binarithm(struct gen_context *ctx, const struct expression *expr) { const struct type *ltype = type_dealias(expr->binarithm.lvalue->result); const struct type *rtype = type_dealias(expr->binarithm.rvalue->result); + struct gen_value result = mktemp(ctx, expr->result, ".%d"); + struct qbe_value qresult = mkqval(ctx, &result); + + if (expr->binarithm.op == BIN_LAND || expr->binarithm.op == BIN_LOR) { + struct qbe_statement lrval, lshort; + struct qbe_value brval = mklabel(ctx, &lrval, ".%d"); + struct qbe_value bshort = mklabel(ctx, &lshort, ".%d"); + struct gen_value lval = gen_expr(ctx, expr->binarithm.lvalue); + struct qbe_value qlval = mkqval(ctx, &lval); + pushi(ctx->current, &qresult, Q_COPY, &qlval, NULL); + if (expr->binarithm.op == BIN_LAND) { + pushi(ctx->current, NULL, Q_JNZ, &qresult, &brval, + &bshort, NULL); + } else { + pushi(ctx->current, NULL, Q_JNZ, &qresult, &bshort, + &brval, NULL); + } + push(&ctx->current->body, &lrval); + struct gen_value rval = gen_expr(ctx, expr->binarithm.rvalue); + struct qbe_value qrval = mkqval(ctx, &rval); + pushi(ctx->current, &qresult, Q_COPY, &qrval, NULL); + if (!expr->binarithm.rvalue->terminates) { + pushi(ctx->current, NULL, Q_JMP, &bshort, NULL); + } + push(&ctx->current->body, &lshort); + return result; + } + struct gen_value lvalue = gen_expr(ctx, expr->binarithm.lvalue); struct gen_value rvalue = gen_expr(ctx, expr->binarithm.rvalue); - struct gen_value result = mktemp(ctx, expr->result, ".%d"); struct qbe_value qlval = mkqval(ctx, &lvalue); struct qbe_value qrval = mkqval(ctx, &rvalue); - struct qbe_value qresult = mkqval(ctx, &result); assert((ltype->storage == STORAGE_STRING) == (rtype->storage == STORAGE_STRING)); if (ltype->storage == STORAGE_STRING) { @@ -569,7 +612,6 @@ gen_expr_binarithm(struct gen_context *ctx, const struct expression *expr) } return result; } - enum qbe_instr instr = binarithm_for_op(ctx, expr->binarithm.op, expr->binarithm.lvalue->result); pushi(ctx->current, &qresult, instr, &qlval, &qrval, NULL);