Constant Propagation for OPCODE_VECTOR_ADD

This commit is contained in:
Dr. Chat 2016-06-12 21:41:02 -05:00
parent eb7b80bf7c
commit 0ef16b10e2
3 changed files with 91 additions and 0 deletions

View File

@ -622,6 +622,16 @@ bool ConstantPropagationPass::Run(HIRBuilder* builder) {
i->Remove();
}
break;
case OPCODE_VECTOR_ADD:
if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) {
v->set_from(i->src1.value);
uint32_t arith_flags = i->flags >> 8;
v->VectorAdd(i->src2.value, hir::TypeName(i->flags & 0xFF),
!!(arith_flags & ARITHMETIC_UNSIGNED),
!!(arith_flags & ARITHMETIC_SATURATE));
i->Remove();
}
break;
case OPCODE_VECTOR_SUB:
if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) {
v->set_from(i->src1.value);

View File

@ -1003,6 +1003,86 @@ void Value::VectorRol(Value* other, TypeName type) {
}
}
void Value::VectorAdd(Value* other, TypeName type, bool is_unsigned,
bool saturate) {
assert_true(this->type == VEC128_TYPE && other->type == VEC128_TYPE);
switch (type) {
case FLOAT32_TYPE:
if (saturate) {
assert_always();
} else {
constant.v128.x += other->constant.v128.x;
constant.v128.y += other->constant.v128.y;
constant.v128.z += other->constant.v128.z;
constant.v128.w += other->constant.v128.w;
}
break;
case FLOAT64_TYPE:
if (saturate) {
assert_always();
} else {
constant.v128.f64[0] += other->constant.v128.f64[0];
constant.v128.f64[1] += other->constant.v128.f64[1];
}
break;
case INT8_TYPE:
if (saturate) {
assert_always();
} else {
for (int i = 0; i < 16; i++) {
if (is_unsigned) {
constant.v128.u8[i] += other->constant.v128.u8[i];
} else {
constant.v128.i8[i] += other->constant.v128.i8[i];
}
}
}
break;
case INT16_TYPE:
if (saturate) {
assert_always();
} else {
for (int i = 0; i < 8; i++) {
if (is_unsigned) {
constant.v128.u16[i] += other->constant.v128.u16[i];
} else {
constant.v128.i16[i] += other->constant.v128.i16[i];
}
}
}
break;
case INT32_TYPE:
if (saturate) {
assert_always();
} else {
for (int i = 0; i < 4; i++) {
if (is_unsigned) {
constant.v128.u32[i] += other->constant.v128.u32[i];
} else {
constant.v128.i32[i] += other->constant.v128.i32[i];
}
}
}
break;
case INT64_TYPE:
if (saturate) {
assert_always();
} else {
if (is_unsigned) {
constant.v128.u64[0] += other->constant.v128.u64[0];
constant.v128.u64[1] += other->constant.v128.u64[1];
} else {
constant.v128.i64[0] += other->constant.v128.i64[0];
constant.v128.i64[1] += other->constant.v128.i64[1];
}
}
break;
default:
assert_unhandled_case(type);
break;
}
}
void Value::VectorSub(Value* other, TypeName type, bool is_unsigned,
bool saturate) {
assert_true(this->type == VEC128_TYPE && other->type == VEC128_TYPE);

View File

@ -504,6 +504,7 @@ class Value {
void VectorShl(Value* other, TypeName type);
void VectorShr(Value* other, TypeName type);
void VectorRol(Value* other, TypeName type);
void VectorAdd(Value* other, TypeName type, bool is_unsigned, bool saturate);
void VectorSub(Value* other, TypeName type, bool is_unsigned, bool saturate);
void ByteSwap();
void CountLeadingZeros(const Value* other);