VectorAdd and saturation checks.
This commit is contained in:
@@ -1052,6 +1052,15 @@ Value* HIRBuilder::DidOverflow(Value* value) {
|
||||
return i->dest;
|
||||
}
|
||||
|
||||
Value* HIRBuilder::DidSaturate(Value* value) {
|
||||
Instr* i = AppendInstr(
|
||||
OPCODE_DID_SATURATE_info, 0,
|
||||
AllocValue(INT8_TYPE));
|
||||
i->set_src1(value);
|
||||
i->src2.value = i->src3.value = NULL;
|
||||
return i->dest;
|
||||
}
|
||||
|
||||
Value* HIRBuilder::VectorCompareXX(
|
||||
const OpcodeInfo& opcode, Value* value1, Value* value2,
|
||||
TypeName part_type) {
|
||||
@@ -1140,6 +1149,24 @@ Value* HIRBuilder::AddWithCarry(
|
||||
return i->dest;
|
||||
}
|
||||
|
||||
Value* HIRBuilder::VectorAdd(Value* value1, Value* value2, TypeName part_type,
|
||||
uint32_t arithmetic_flags) {
|
||||
ASSERT_VECTOR_TYPE(value1);
|
||||
ASSERT_VECTOR_TYPE(value2);
|
||||
|
||||
// This is shady.
|
||||
uint32_t flags = part_type | (arithmetic_flags << 8);
|
||||
XEASSERTZERO(flags >> 16);
|
||||
|
||||
Instr* i = AppendInstr(
|
||||
OPCODE_VECTOR_ADD_info, (uint16_t)flags,
|
||||
AllocValue(value1->type));
|
||||
i->set_src1(value1);
|
||||
i->set_src2(value2);
|
||||
i->src3.value = NULL;
|
||||
return i->dest;
|
||||
}
|
||||
|
||||
Value* HIRBuilder::Sub(
|
||||
Value* value1, Value* value2, uint32_t arithmetic_flags) {
|
||||
ASSERT_TYPES_EQUAL(value1, value2);
|
||||
|
||||
@@ -94,10 +94,6 @@ public:
|
||||
Value* Convert(Value* value, TypeName target_type,
|
||||
RoundMode round_mode = ROUND_TO_ZERO);
|
||||
Value* Round(Value* value, RoundMode round_mode);
|
||||
|
||||
// TODO(benvanik): make this cleaner -- not happy with it.
|
||||
// It'd be nice if Convert() supported this, however then we'd need a
|
||||
// VEC128_INT32_TYPE or something.
|
||||
Value* VectorConvertI2F(Value* value, uint32_t arithmetic_flags = 0);
|
||||
Value* VectorConvertF2I(Value* value, uint32_t arithmetic_flags = 0);
|
||||
|
||||
@@ -143,6 +139,7 @@ public:
|
||||
Value* CompareUGE(Value* value1, Value* value2);
|
||||
Value* DidCarry(Value* value);
|
||||
Value* DidOverflow(Value* value);
|
||||
Value* DidSaturate(Value* value);
|
||||
Value* VectorCompareEQ(Value* value1, Value* value2, TypeName part_type);
|
||||
Value* VectorCompareSGT(Value* value1, Value* value2, TypeName part_type);
|
||||
Value* VectorCompareSGE(Value* value1, Value* value2, TypeName part_type);
|
||||
@@ -152,6 +149,8 @@ public:
|
||||
Value* Add(Value* value1, Value* value2, uint32_t arithmetic_flags = 0);
|
||||
Value* AddWithCarry(Value* value1, Value* value2, Value* value3,
|
||||
uint32_t arithmetic_flags = 0);
|
||||
Value* VectorAdd(Value* value1, Value* value2, TypeName part_type,
|
||||
uint32_t arithmetic_flags = 0);
|
||||
Value* Sub(Value* value1, Value* value2,
|
||||
uint32_t arithmetic_flags = 0);
|
||||
Value* Mul(Value* value1, Value* value2, uint32_t arithmetic_flags = 0);
|
||||
|
||||
@@ -130,6 +130,7 @@ enum Opcode {
|
||||
OPCODE_COMPARE_UGE,
|
||||
OPCODE_DID_CARRY,
|
||||
OPCODE_DID_OVERFLOW,
|
||||
OPCODE_DID_SATURATE,
|
||||
OPCODE_VECTOR_COMPARE_EQ,
|
||||
OPCODE_VECTOR_COMPARE_SGT,
|
||||
OPCODE_VECTOR_COMPARE_SGE,
|
||||
@@ -138,6 +139,7 @@ enum Opcode {
|
||||
|
||||
OPCODE_ADD,
|
||||
OPCODE_ADD_CARRY,
|
||||
OPCODE_VECTOR_ADD,
|
||||
OPCODE_SUB,
|
||||
OPCODE_MUL,
|
||||
OPCODE_MUL_HI, // TODO(benvanik): remove this and add INT128 type.
|
||||
|
||||
@@ -292,12 +292,16 @@ DEFINE_OPCODE(
|
||||
"did_carry",
|
||||
OPCODE_SIG_V_V,
|
||||
0);
|
||||
|
||||
DEFINE_OPCODE(
|
||||
OPCODE_DID_OVERFLOW,
|
||||
"did_overflow",
|
||||
OPCODE_SIG_V_V,
|
||||
0);
|
||||
DEFINE_OPCODE(
|
||||
OPCODE_DID_SATURATE,
|
||||
"did_saturate",
|
||||
OPCODE_SIG_V_V,
|
||||
0);
|
||||
|
||||
DEFINE_OPCODE(
|
||||
OPCODE_VECTOR_COMPARE_EQ,
|
||||
@@ -337,6 +341,12 @@ DEFINE_OPCODE(
|
||||
OPCODE_SIG_V_V_V_V,
|
||||
OPCODE_FLAG_COMMUNATIVE);
|
||||
|
||||
DEFINE_OPCODE(
|
||||
OPCODE_VECTOR_ADD,
|
||||
"vector_add",
|
||||
OPCODE_SIG_V_V_V,
|
||||
OPCODE_FLAG_COMMUNATIVE);
|
||||
|
||||
DEFINE_OPCODE(
|
||||
OPCODE_SUB,
|
||||
"sub",
|
||||
|
||||
Reference in New Issue
Block a user