OPCODE_IS_NAN
This commit is contained in:
parent
fb87b7a3c3
commit
18ff97e6b6
|
@ -2909,6 +2909,24 @@ struct IS_FALSE_V128
|
||||||
EMITTER_OPCODE_TABLE(OPCODE_IS_FALSE, IS_FALSE_I8, IS_FALSE_I16, IS_FALSE_I32,
|
EMITTER_OPCODE_TABLE(OPCODE_IS_FALSE, IS_FALSE_I8, IS_FALSE_I16, IS_FALSE_I32,
|
||||||
IS_FALSE_I64, IS_FALSE_F32, IS_FALSE_F64, IS_FALSE_V128);
|
IS_FALSE_I64, IS_FALSE_F32, IS_FALSE_F64, IS_FALSE_V128);
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// OPCODE_IS_NAN
|
||||||
|
// ============================================================================
|
||||||
|
struct IS_NAN_F32 : Sequence<IS_NAN_F32, I<OPCODE_IS_NAN, I8Op, F32Op>> {
|
||||||
|
static void Emit(X64Emitter& e, const EmitArgType& i) {
|
||||||
|
e.vucomiss(i.src1, i.src1);
|
||||||
|
e.setp(i.dest);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct IS_NAN_F64 : Sequence<IS_NAN_F64, I<OPCODE_IS_NAN, I8Op, F64Op>> {
|
||||||
|
static void Emit(X64Emitter& e, const EmitArgType& i) {
|
||||||
|
e.vucomisd(i.src1, i.src1);
|
||||||
|
e.setp(i.dest);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
EMITTER_OPCODE_TABLE(OPCODE_IS_NAN, IS_NAN_F32, IS_NAN_F64);
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// OPCODE_COMPARE_EQ
|
// OPCODE_COMPARE_EQ
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
@ -7566,6 +7584,7 @@ void RegisterSequences() {
|
||||||
Register_OPCODE_SELECT();
|
Register_OPCODE_SELECT();
|
||||||
Register_OPCODE_IS_TRUE();
|
Register_OPCODE_IS_TRUE();
|
||||||
Register_OPCODE_IS_FALSE();
|
Register_OPCODE_IS_FALSE();
|
||||||
|
Register_OPCODE_IS_NAN();
|
||||||
Register_OPCODE_COMPARE_EQ();
|
Register_OPCODE_COMPARE_EQ();
|
||||||
Register_OPCODE_COMPARE_NE();
|
Register_OPCODE_COMPARE_NE();
|
||||||
Register_OPCODE_COMPARE_SLT();
|
Register_OPCODE_COMPARE_SLT();
|
||||||
|
|
|
@ -300,6 +300,20 @@ bool ConstantPropagationPass::Run(HIRBuilder* builder) {
|
||||||
i->Remove();
|
i->Remove();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case OPCODE_IS_NAN:
|
||||||
|
if (i->src1.value->IsConstant()) {
|
||||||
|
if (i->src1.value->type == FLOAT32_TYPE &&
|
||||||
|
isnan(i->src1.value->constant.f32)) {
|
||||||
|
v->set_constant(uint8_t(1));
|
||||||
|
} else if (i->src1.value->type == FLOAT64_TYPE &&
|
||||||
|
isnan(i->src1.value->constant.f64)) {
|
||||||
|
v->set_constant(uint8_t(1));
|
||||||
|
} else {
|
||||||
|
v->set_constant(uint8_t(0));
|
||||||
|
}
|
||||||
|
i->Remove();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
// TODO(benvanik): compares
|
// TODO(benvanik): compares
|
||||||
case OPCODE_COMPARE_EQ:
|
case OPCODE_COMPARE_EQ:
|
||||||
|
|
|
@ -1362,6 +1362,13 @@ Value* HIRBuilder::IsFalse(Value* value) {
|
||||||
return i->dest;
|
return i->dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Value* HIRBuilder::IsNan(Value* value) {
|
||||||
|
Instr* i = AppendInstr(OPCODE_IS_NAN_info, 0, AllocValue(INT8_TYPE));
|
||||||
|
i->set_src1(value);
|
||||||
|
i->src2.value = i->src3.value = NULL;
|
||||||
|
return i->dest;
|
||||||
|
}
|
||||||
|
|
||||||
Value* HIRBuilder::CompareXX(const OpcodeInfo& opcode, Value* value1,
|
Value* HIRBuilder::CompareXX(const OpcodeInfo& opcode, Value* value1,
|
||||||
Value* value2) {
|
Value* value2) {
|
||||||
ASSERT_TYPES_EQUAL(value1, value2);
|
ASSERT_TYPES_EQUAL(value1, value2);
|
||||||
|
|
|
@ -162,6 +162,7 @@ class HIRBuilder {
|
||||||
Value* Select(Value* cond, Value* value1, Value* value2);
|
Value* Select(Value* cond, Value* value1, Value* value2);
|
||||||
Value* IsTrue(Value* value);
|
Value* IsTrue(Value* value);
|
||||||
Value* IsFalse(Value* value);
|
Value* IsFalse(Value* value);
|
||||||
|
Value* IsNan(Value* value);
|
||||||
Value* CompareEQ(Value* value1, Value* value2);
|
Value* CompareEQ(Value* value1, Value* value2);
|
||||||
Value* CompareNE(Value* value1, Value* value2);
|
Value* CompareNE(Value* value1, Value* value2);
|
||||||
Value* CompareSLT(Value* value1, Value* value2);
|
Value* CompareSLT(Value* value1, Value* value2);
|
||||||
|
|
|
@ -164,6 +164,7 @@ enum Opcode {
|
||||||
OPCODE_SELECT,
|
OPCODE_SELECT,
|
||||||
OPCODE_IS_TRUE,
|
OPCODE_IS_TRUE,
|
||||||
OPCODE_IS_FALSE,
|
OPCODE_IS_FALSE,
|
||||||
|
OPCODE_IS_NAN,
|
||||||
OPCODE_COMPARE_EQ,
|
OPCODE_COMPARE_EQ,
|
||||||
OPCODE_COMPARE_NE,
|
OPCODE_COMPARE_NE,
|
||||||
OPCODE_COMPARE_SLT,
|
OPCODE_COMPARE_SLT,
|
||||||
|
|
|
@ -303,6 +303,12 @@ DEFINE_OPCODE(
|
||||||
OPCODE_SIG_V_V,
|
OPCODE_SIG_V_V,
|
||||||
0)
|
0)
|
||||||
|
|
||||||
|
DEFINE_OPCODE(
|
||||||
|
OPCODE_IS_NAN,
|
||||||
|
"is_nan",
|
||||||
|
OPCODE_SIG_V_V,
|
||||||
|
0)
|
||||||
|
|
||||||
DEFINE_OPCODE(
|
DEFINE_OPCODE(
|
||||||
OPCODE_COMPARE_EQ,
|
OPCODE_COMPARE_EQ,
|
||||||
"compare_eq",
|
"compare_eq",
|
||||||
|
|
Loading…
Reference in New Issue