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:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
)
|
||||
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user