Constant Propagation for OPCODE_VECTOR_ADD
This commit is contained in:
parent
eb7b80bf7c
commit
0ef16b10e2
|
@ -622,6 +622,16 @@ bool ConstantPropagationPass::Run(HIRBuilder* builder) {
|
||||||
i->Remove();
|
i->Remove();
|
||||||
}
|
}
|
||||||
break;
|
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:
|
case OPCODE_VECTOR_SUB:
|
||||||
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);
|
||||||
|
|
|
@ -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,
|
void Value::VectorSub(Value* other, TypeName type, bool is_unsigned,
|
||||||
bool saturate) {
|
bool saturate) {
|
||||||
assert_true(this->type == VEC128_TYPE && other->type == VEC128_TYPE);
|
assert_true(this->type == VEC128_TYPE && other->type == VEC128_TYPE);
|
||||||
|
|
|
@ -504,6 +504,7 @@ class Value {
|
||||||
void VectorShl(Value* other, TypeName type);
|
void VectorShl(Value* other, TypeName type);
|
||||||
void VectorShr(Value* other, TypeName type);
|
void VectorShr(Value* other, TypeName type);
|
||||||
void VectorRol(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 VectorSub(Value* other, TypeName type, bool is_unsigned, bool saturate);
|
||||||
void ByteSwap();
|
void ByteSwap();
|
||||||
void CountLeadingZeros(const Value* other);
|
void CountLeadingZeros(const Value* other);
|
||||||
|
|
Loading…
Reference in New Issue