/*
- * Copyright (C) 2012, 2013
+ * Copyright (C) 2012, 2013, 2014
* Wolfgang Bumiller
* Dale Weiler
*
}
self->reserved_va_count = NULL;
+ self->coverage_func = NULL;
+
self->code = code_init();
return self;
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;
}
(op >= INSTR_NOT_F && op <= INSTR_NOT_FNC) ||
(op >= INSTR_AND && op <= INSTR_BITOR) ||
(op >= INSTR_CALL0 && op <= INSTR_CALL8) ||
- (op >= VINSTR_BITAND_V && op <= VINSTR_CROSS) );
+ (op >= VINSTR_BITAND_V && op <= VINSTR_NEG_V) );
}
static bool ir_function_pass_peephole(ir_function *self)
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;
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)
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;
}
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;
#define IND_BUFSZ 1024
-#ifdef _MSC_VER
-# define strncat(dst, src, sz) strncat_s(dst, sz, src, _TRUNCATE)
-#endif
-
static const char *qc_opname(int op)
{
if (op < 0) return "<INVALID>";
case VINSTR_BITOR_VF: return "BITOR_VF";
case VINSTR_BITXOR_VF: return "BITXOR_VF";
case VINSTR_CROSS: return "CROSS";
+ case VINSTR_NEG_F: return "NEG_F";
+ case VINSTR_NEG_V: return "NEG_V";
default: return "<UNK>";
}
}
return;
}
oprintf("%sfunction %s\n", ind, f->name);
- strncat(ind, "\t", IND_BUFSZ-1);
+ util_strncat(ind, "\t", IND_BUFSZ-1);
if (vec_size(f->locals))
{
oprintf("%s%i locals:\n", ind, (int)vec_size(f->locals));
{
size_t i;
oprintf("%s:%s\n", ind, b->label);
- strncat(ind, "\t", IND_BUFSZ-1);
+ util_strncat(ind, "\t", IND_BUFSZ-1);
if (b->instr && b->instr[0])
oprintf("%s (%i) [entry]\n", ind, (int)(b->instr[0]->eid-1));
return;
}
- strncat(ind, "\t", IND_BUFSZ-1);
+ util_strncat(ind, "\t", IND_BUFSZ-1);
if (in->_ops[0] && (in->_ops[1] || in->_ops[2])) {
ir_value_dump(in->_ops[0], oprintf);