(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)
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 INSTR_NOT_V:
case INSTR_NOT_S:
case INSTR_NOT_ENT:
- case INSTR_NOT_FNC:
-#if 0
- case INSTR_NOT_I:
-#endif
+ case INSTR_NOT_FNC: /*
+ case INSTR_NOT_I: */
ot = TYPE_FLOAT;
break;
- /* QC doesn't have other unary operations. We expect extensions to fill
- * the above list, otherwise we assume out-type = in-type, eg for an
- * unary minus
+
+ /*
+ * Negation for virtual instructions is emulated with 0-value. Thankfully
+ * the operand for 0 already exists so we just source it from here.
*/
+ 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, TYPE_VECTOR);
+
default:
ot = operand->vtype;
break;
continue;
}
}
-
code_push_statement(code, &stmt, instr->context);
}
return true;
#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);