Value::MulHi and constant propagation for OPCODE_MUL_HI. Could maybe be reworked?
This commit is contained in:
parent
9714018fbb
commit
bb947c6819
|
@ -354,6 +354,13 @@ bool ConstantPropagationPass::Run(HIRBuilder* builder) {
|
|||
i->Remove();
|
||||
}
|
||||
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:
|
||||
if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) {
|
||||
v->set_from(i->src1.value);
|
||||
|
|
|
@ -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) {
|
||||
assert_true(type == other->type);
|
||||
switch (type) {
|
||||
|
|
|
@ -385,6 +385,7 @@ class Value {
|
|||
bool Add(Value* other);
|
||||
bool Sub(Value* other);
|
||||
void Mul(Value* other);
|
||||
void MulHi(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 MulSub(Value* dest, Value* value1, Value* value2, Value* value3);
|
||||
|
|
Loading…
Reference in New Issue