Value::MulHi and constant propagation for OPCODE_MUL_HI. Could maybe be reworked?

This commit is contained in:
gibbed 2015-05-13 16:13:06 -05:00
parent 9714018fbb
commit bb947c6819
3 changed files with 31 additions and 0 deletions

View File

@ -354,6 +354,13 @@ bool ConstantPropagationPass::Run(HIRBuilder* builder) {
i->Remove(); i->Remove();
} }
break; break;
case OPCODE_MUL_HI:
if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) {
v->set_from(i->src1.value);
v->MulHi(i->src2.value, (i->flags & ARITHMETIC_UNSIGNED) != 0);
i->Remove();
}
break;
case OPCODE_DIV: case OPCODE_DIV:
if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) { if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) {
v->set_from(i->src1.value); v->set_from(i->src1.value);

View File

@ -304,6 +304,29 @@ void Value::Mul(Value* other) {
} }
} }
void Value::MulHi(Value* other, bool is_unsigned) {
assert_true(type == other->type);
switch (type) {
case INT32_TYPE:
if (is_unsigned) {
constant.i32 = (int32_t)(((uint64_t)((uint32_t)constant.i32) * (uint32_t)other->constant.i32) >> 32);
} else {
constant.i32 = (int32_t)(((int64_t)constant.i32 * (int64_t)other->constant.i32) >> 32);
}
break;
case INT64_TYPE:
if (is_unsigned) {
constant.i64 = __umulh(constant.i64, other->constant.i64);
} else {
constant.i64 = __mulh(constant.i64, other->constant.i64);
}
break;
default:
assert_unhandled_case(type);
break;
}
}
void Value::Div(Value* other, bool is_unsigned) { void Value::Div(Value* other, bool is_unsigned) {
assert_true(type == other->type); assert_true(type == other->type);
switch (type) { switch (type) {

View File

@ -385,6 +385,7 @@ class Value {
bool Add(Value* other); bool Add(Value* other);
bool Sub(Value* other); bool Sub(Value* other);
void Mul(Value* other); void Mul(Value* other);
void MulHi(Value* other, bool is_unsigned);
void Div(Value* other, bool is_unsigned); void Div(Value* other, bool is_unsigned);
static void MulAdd(Value* dest, Value* value1, Value* value2, Value* value3); static void MulAdd(Value* dest, Value* value1, Value* value2, Value* value3);
static void MulSub(Value* dest, Value* value1, Value* value2, Value* value3); static void MulSub(Value* dest, Value* value1, Value* value2, Value* value3);