X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;ds=sidebyside;f=ir.c;h=ef782f91e5548c512e17b3054b4e4438cbe7e525;hb=1a8bb31d2a122010e99e47ce238a99f1cd922379;hp=9967d7d8dbd91649a62c55b69772a91fa3c6e2de;hpb=92c0d6157c3d6b24ffff811a989572e2ae6d92f9;p=xonotic%2Fgmqcc.git diff --git a/ir.c b/ir.c index 9967d7d..ef782f9 100644 --- a/ir.c +++ b/ir.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012, 2013 + * Copyright (C) 2012, 2013, 2014 * Wolfgang Bumiller * Dale Weiler * @@ -355,6 +355,8 @@ ir_builder* ir_builder_new(const char *modulename) } self->reserved_va_count = NULL; + self->coverage_func = NULL; + self->code = code_init(); return self; @@ -602,6 +604,10 @@ ir_block* ir_function_create_block(lex_ctx_t ctx, ir_function *self, const char ir_block* bn = ir_block_new(self, label); bn->context = ctx; vec_push(self->blocks, bn); + + if ((self->flags & IR_FLAG_BLOCK_COVERAGE) && self->owner->coverage_func) + (void)ir_block_create_call(bn, ctx, NULL, self->owner->coverage_func, false); + return bn; } @@ -1531,6 +1537,26 @@ bool ir_block_create_store_op(ir_block *self, lex_ctx_t ctx, int op, ir_value *t return true; } +bool ir_block_create_state_op(ir_block *self, lex_ctx_t ctx, ir_value *frame, ir_value *think) +{ + ir_instr *in; + if (!ir_check_unreachable(self)) + return false; + + in = ir_instr_new(ctx, self, INSTR_STATE); + if (!in) + return false; + + if (!ir_instr_op(in, 0, frame, false) || + !ir_instr_op(in, 1, think, false)) + { + ir_instr_delete(in); + return false; + } + vec_push(self->instr, in); + return true; +} + static bool ir_block_create_store(ir_block *self, lex_ctx_t ctx, ir_value *target, ir_value *what) { int op = 0; @@ -1583,7 +1609,9 @@ bool ir_block_create_return(ir_block *self, lex_ctx_t ctx, ir_value *v) ir_instr *in; if (!ir_check_unreachable(self)) return false; + self->final = true; + self->is_return = true; in = ir_instr_new(ctx, self, INSTR_RETURN); if (!in) @@ -1890,7 +1918,7 @@ ir_value* ir_block_create_unary(ir_block *self, lex_ctx_t ctx, case VINSTR_NEG_F: return ir_block_create_general_instr(self, ctx, label, INSTR_SUB_F, NULL, operand, ot); case VINSTR_NEG_V: - return ir_block_create_general_instr(self, ctx, label, INSTR_SUB_V, NULL, operand, ot); + return ir_block_create_general_instr(self, ctx, label, INSTR_SUB_V, NULL, operand, TYPE_VECTOR); default: ot = operand->vtype; @@ -3159,8 +3187,14 @@ static bool gen_blocks_recursive(code_t *code, ir_function *func, ir_block *bloc } if (instr->opcode == INSTR_STATE) { - irerror(block->context, "TODO: state instruction"); - return false; + stmt.opcode = instr->opcode; + if (instr->_ops[0]) + stmt.o1.u1 = ir_value_code_addr(instr->_ops[0]); + if (instr->_ops[1]) + stmt.o2.u1 = ir_value_code_addr(instr->_ops[1]); + stmt.o3.u1 = 0; + code_push_statement(code, &stmt, instr->context); + continue; } stmt.opcode = instr->opcode;