Add separate VMX/fpu mxcsr

Add support for constant operands for most fpu instructions
Remove constant folding for most fpu cpde
half float
This commit is contained in:
chss95cs@gmail.com
2022-07-31 08:56:36 -07:00
parent 3185b0ac9c
commit 968f656d96
18 changed files with 687 additions and 611 deletions

View File

@@ -1287,7 +1287,11 @@ void HIRBuilder::SetRoundingMode(Value* value) {
Instr* i = AppendInstr(OPCODE_SET_ROUNDING_MODE_info, 0);
i->set_src1(value);
}
void HIRBuilder::SetNJM(Value* value) {
ASSERT_INTEGER_TYPE(value);
Instr* i = AppendInstr(OPCODE_SET_NJM_info, 0);
i->set_src1(value);
}
Value* HIRBuilder::Max(Value* value1, Value* value2) {
ASSERT_TYPES_EQUAL(value1, value2);
@@ -1632,7 +1636,7 @@ Value* HIRBuilder::Div(Value* value1, Value* value2,
Value* HIRBuilder::MulAdd(Value* value1, Value* value2, Value* value3) {
ASSERT_TYPES_EQUAL(value1, value2);
ASSERT_TYPES_EQUAL(value1, value3);
#if 0
bool c1 = value1->IsConstant();
bool c2 = value2->IsConstant();
if (c1 && c2) {
@@ -1640,7 +1644,7 @@ Value* HIRBuilder::MulAdd(Value* value1, Value* value2, Value* value3) {
dest->Mul(value2);
return Add(dest, value3);
}
#endif
Instr* i = AppendInstr(OPCODE_MUL_ADD_info, 0, AllocValue(value1->type));
i->set_src1(value1);
i->set_src2(value2);
@@ -1651,7 +1655,7 @@ Value* HIRBuilder::MulAdd(Value* value1, Value* value2, Value* value3) {
Value* HIRBuilder::MulSub(Value* value1, Value* value2, Value* value3) {
ASSERT_TYPES_EQUAL(value1, value2);
ASSERT_TYPES_EQUAL(value1, value3);
#if 0
bool c1 = value1->IsConstant();
bool c2 = value2->IsConstant();
if (c1 && c2) {
@@ -1659,7 +1663,7 @@ Value* HIRBuilder::MulSub(Value* value1, Value* value2, Value* value3) {
dest->Mul(value2);
return Sub(dest, value3);
}
#endif
Instr* i = AppendInstr(OPCODE_MUL_SUB_info, 0, AllocValue(value1->type));
i->set_src1(value1);
i->set_src2(value2);

View File

@@ -264,7 +264,7 @@ class HIRBuilder {
Value* new_value);
Value* AtomicAdd(Value* address, Value* value);
Value* AtomicSub(Value* address, Value* value);
void SetNJM(Value* value);
protected:
void DumpValue(StringBuffer* str, Value* value);
void DumpOp(StringBuffer* str, OpcodeSignatureType sig_type, Instr::Op* op);

View File

@@ -284,6 +284,7 @@ enum Opcode {
OPCODE_TO_SINGLE, // i could not find a decent name to assign to this opcode,
// as we already have OPCODE_ROUND. round double to float (
// ppc "single" fpu instruction result rounding behavior )
OPCODE_SET_NJM,
__OPCODE_MAX_VALUE, // Keep at end.
};
@@ -295,6 +296,7 @@ enum OpcodeFlags {
OPCODE_FLAG_IGNORE = (1 << 5),
OPCODE_FLAG_HIDE = (1 << 6),
OPCODE_FLAG_PAIRED_PREV = (1 << 7),
OPCODE_FLAG_DISALLOW_CONSTANT_FOLDING = (1 << 8)
};
enum OpcodeSignatureType {

View File

@@ -151,25 +151,25 @@ DEFINE_OPCODE(
OPCODE_CONVERT,
"convert",
OPCODE_SIG_V_V,
0)
OPCODE_FLAG_DISALLOW_CONSTANT_FOLDING)
DEFINE_OPCODE(
OPCODE_ROUND,
"round",
OPCODE_SIG_V_V,
0)
OPCODE_FLAG_DISALLOW_CONSTANT_FOLDING)
DEFINE_OPCODE(
OPCODE_VECTOR_CONVERT_I2F,
"vector_convert_i2f",
OPCODE_SIG_V_V,
0)
OPCODE_FLAG_DISALLOW_CONSTANT_FOLDING)
DEFINE_OPCODE(
OPCODE_VECTOR_CONVERT_F2I,
"vector_convert_f2i",
OPCODE_SIG_V_V,
0)
OPCODE_FLAG_DISALLOW_CONSTANT_FOLDING)
DEFINE_OPCODE(
OPCODE_LOAD_VECTOR_SHL,
@@ -456,13 +456,13 @@ DEFINE_OPCODE(
OPCODE_MUL_ADD,
"mul_add",
OPCODE_SIG_V_V_V_V,
0)
OPCODE_FLAG_DISALLOW_CONSTANT_FOLDING)
DEFINE_OPCODE(
OPCODE_MUL_SUB,
"mul_sub",
OPCODE_SIG_V_V_V_V,
0)
OPCODE_FLAG_DISALLOW_CONSTANT_FOLDING)
DEFINE_OPCODE(
OPCODE_NEG,
@@ -480,43 +480,43 @@ DEFINE_OPCODE(
OPCODE_SQRT,
"sqrt",
OPCODE_SIG_V_V,
0)
OPCODE_FLAG_DISALLOW_CONSTANT_FOLDING)
DEFINE_OPCODE(
OPCODE_RSQRT,
"rsqrt",
OPCODE_SIG_V_V,
0)
OPCODE_FLAG_DISALLOW_CONSTANT_FOLDING)
DEFINE_OPCODE(
OPCODE_RECIP,
"recip",
OPCODE_SIG_V_V,
0)
OPCODE_FLAG_DISALLOW_CONSTANT_FOLDING)
DEFINE_OPCODE(
OPCODE_POW2,
"pow2",
OPCODE_SIG_V_V,
0)
OPCODE_FLAG_DISALLOW_CONSTANT_FOLDING)
DEFINE_OPCODE(
OPCODE_LOG2,
"log2",
OPCODE_SIG_V_V,
0)
OPCODE_FLAG_DISALLOW_CONSTANT_FOLDING)
DEFINE_OPCODE(
OPCODE_DOT_PRODUCT_3,
"dot_product_3",
OPCODE_SIG_V_V_V,
0)
OPCODE_FLAG_DISALLOW_CONSTANT_FOLDING)
DEFINE_OPCODE(
OPCODE_DOT_PRODUCT_4,
"dot_product_4",
OPCODE_SIG_V_V_V,
0)
OPCODE_FLAG_DISALLOW_CONSTANT_FOLDING)
DEFINE_OPCODE(
OPCODE_AND,
@@ -685,5 +685,11 @@ DEFINE_OPCODE(
OPCODE_TO_SINGLE,
"to_single",
OPCODE_SIG_V_V,
OPCODE_FLAG_DISALLOW_CONSTANT_FOLDING
)
DEFINE_OPCODE(
OPCODE_SET_NJM,
"set_njm",
OPCODE_SIG_X_V,
0
)

View File

@@ -199,7 +199,7 @@ void Value::Truncate(TypeName target_type) {
return;
}
}
//WARNING: this does not handle rounding flags at all!
void Value::Convert(TypeName target_type, RoundMode round_mode) {
switch (type) {
case FLOAT32_TYPE:
@@ -401,7 +401,7 @@ void Value::MulHi(Value* other, bool is_unsigned) {
32);
}
break;
case INT64_TYPE:
case INT64_TYPE: {
#if XE_COMPILER_MSVC
if (is_unsigned) {
constant.i64 = __umulh(constant.i64, other->constant.i64);
@@ -409,17 +409,19 @@ void Value::MulHi(Value* other, bool is_unsigned) {
constant.i64 = __mulh(constant.i64, other->constant.i64);
}
#else
unsigned __int128 product;
if (is_unsigned) {
constant.i64 = static_cast<uint64_t>(
static_cast<unsigned __int128>(constant.i64) *
static_cast<unsigned __int128>(other->constant.i64));
product = static_cast<unsigned __int128>(constant.i64) *
static_cast<unsigned __int128>(other->constant.i64);
} else {
constant.i64 =
static_cast<uint64_t>(static_cast<__int128>(constant.i64) *
static_cast<__int128>(other->constant.i64));
product = static_cast<unsigned __int128>(
static_cast<__int128>(constant.i64) *
static_cast<__int128>(other->constant.i64));
}
constant.i64 = static_cast<int64_t>(product >> 64);
#endif // XE_COMPILER_MSVC
break;
}
default:
assert_unhandled_case(type);
break;
@@ -495,52 +497,6 @@ void Value::Max(Value* other) {
}
}
void Value::MulAdd(Value* dest, Value* value1, Value* value2, Value* value3) {
switch (dest->type) {
case VEC128_TYPE:
for (int i = 0; i < 4; i++) {
dest->constant.v128.f32[i] =
(value1->constant.v128.f32[i] * value2->constant.v128.f32[i]) +
value3->constant.v128.f32[i];
}
break;
case FLOAT32_TYPE:
dest->constant.f32 =
(value1->constant.f32 * value2->constant.f32) + value3->constant.f32;
break;
case FLOAT64_TYPE:
dest->constant.f64 =
(value1->constant.f64 * value2->constant.f64) + value3->constant.f64;
break;
default:
assert_unhandled_case(dest->type);
break;
}
}
void Value::MulSub(Value* dest, Value* value1, Value* value2, Value* value3) {
switch (dest->type) {
case VEC128_TYPE:
for (int i = 0; i < 4; i++) {
dest->constant.v128.f32[i] =
(value1->constant.v128.f32[i] * value2->constant.v128.f32[i]) -
value3->constant.v128.f32[i];
}
break;
case FLOAT32_TYPE:
dest->constant.f32 =
(value1->constant.f32 * value2->constant.f32) - value3->constant.f32;
break;
case FLOAT64_TYPE:
dest->constant.f64 =
(value1->constant.f64 * value2->constant.f64) - value3->constant.f64;
break;
default:
assert_unhandled_case(dest->type);
break;
}
}
void Value::Neg() {
switch (type) {
case INT8_TYPE:
@@ -1643,11 +1599,7 @@ void Value::DenormalFlush() {
constant.v128.u32[i] = current_element;
}
}
void Value::ToSingle() {
assert_true(type == FLOAT64_TYPE);
constant.f64 = static_cast<double>(static_cast<float>(constant.f64));
}
void Value::CountLeadingZeros(const Value* other) {
switch (other->type) {
case INT8_TYPE:

View File

@@ -563,8 +563,7 @@ class Value {
void MulHi(Value* other, bool is_unsigned);
void Div(Value* other, bool is_unsigned);
void Max(Value* other);
static void MulAdd(Value* dest, Value* value1, Value* value2, Value* value3);
static void MulSub(Value* dest, Value* value1, Value* value2, Value* value3);
void Neg();
void Abs();
void Sqrt();
@@ -603,7 +602,6 @@ class Value {
bool saturate);
void ByteSwap();
void DenormalFlush();
void ToSingle();
void CountLeadingZeros(const Value* other);
bool Compare(Opcode opcode, Value* other);
hir::Instr* GetDefSkipAssigns();
@@ -615,7 +613,10 @@ class Value {
// returns true if every single use is as an operand to a single instruction
// (add var2, var1, var1)
bool AllUsesByOneInsn() const;
//the maybe is here because this includes vec128, which is untyped data that can be treated as float or int depending on the context
bool MaybeFloaty() const {
return type == FLOAT32_TYPE || type == FLOAT64_TYPE || type == VEC128_TYPE;
}
private:
static bool CompareInt8(Opcode opcode, Value* a, Value* b);
static bool CompareInt16(Opcode opcode, Value* a, Value* b);