[X64] MAX_V128/MIN_V128 Proper NaN handling.
According to console. FFC00000->FFC00000 instead of FFFFFC00 as it was previously. Test case: 415607E8 - "Evil Queen's Castle" level
This commit is contained in:
committed by
Radosław Gliński
parent
51322122a5
commit
7ff152a5a7
@@ -601,11 +601,18 @@ struct MAX_V128 : Sequence<MAX_V128, I<OPCODE_MAX, V128Op, V128Op, V128Op>> {
|
||||
static void Emit(X64Emitter& e, const EmitArgType& i) {
|
||||
e.ChangeMxcsrMode(MXCSRMode::Vmx);
|
||||
// if 0 and -0, return 0! opposite of minfp
|
||||
auto src1 = GetInputRegOrConstant(e, i.src1, e.xmm0);
|
||||
auto src2 = GetInputRegOrConstant(e, i.src2, e.xmm1);
|
||||
const Xmm src1 = GetInputRegOrConstant(e, i.src1, e.xmm0);
|
||||
const Xmm src2 = GetInputRegOrConstant(e, i.src2, e.xmm1);
|
||||
|
||||
e.vmaxps(e.xmm2, src1, src2);
|
||||
e.vmaxps(e.xmm3, src2, src1);
|
||||
e.vorps(i.dest, e.xmm2, e.xmm3);
|
||||
e.vandps(e.xmm2, e.xmm2, e.xmm3);
|
||||
|
||||
e.vcmpunordps(e.xmm3, src1, src1); // mask: vA is NaN
|
||||
e.vblendvps(e.xmm3, src2, src1, e.xmm3);
|
||||
|
||||
e.vcmpunordps(i.dest, src1, src2); // mask: vA or vB is NaN
|
||||
e.vblendvps(i.dest, e.xmm2, e.xmm3, i.dest);
|
||||
}
|
||||
};
|
||||
EMITTER_OPCODE_TABLE(OPCODE_MAX, MAX_F32, MAX_F64, MAX_V128);
|
||||
@@ -660,11 +667,18 @@ struct MIN_F64 : Sequence<MIN_F64, I<OPCODE_MIN, F64Op, F64Op, F64Op>> {
|
||||
struct MIN_V128 : Sequence<MIN_V128, I<OPCODE_MIN, V128Op, V128Op, V128Op>> {
|
||||
static void Emit(X64Emitter& e, const EmitArgType& i) {
|
||||
e.ChangeMxcsrMode(MXCSRMode::Vmx);
|
||||
auto src1 = GetInputRegOrConstant(e, i.src1, e.xmm0);
|
||||
auto src2 = GetInputRegOrConstant(e, i.src2, e.xmm1);
|
||||
const Xmm src1 = GetInputRegOrConstant(e, i.src1, e.xmm0);
|
||||
const Xmm src2 = GetInputRegOrConstant(e, i.src2, e.xmm1);
|
||||
|
||||
e.vminps(e.xmm2, src1, src2);
|
||||
e.vminps(e.xmm3, src2, src1);
|
||||
e.vorps(i.dest, e.xmm2, e.xmm3);
|
||||
e.vorps(e.xmm2, e.xmm2, e.xmm3);
|
||||
|
||||
e.vcmpunordps(e.xmm3, src1, src1); // mask: vA is NaN
|
||||
e.vblendvps(e.xmm3, src2, src1, e.xmm3);
|
||||
|
||||
e.vcmpunordps(i.dest, src1, src2); // mask: vA or vB is NaN
|
||||
e.vblendvps(i.dest, e.xmm2, e.xmm3, i.dest);
|
||||
}
|
||||
};
|
||||
EMITTER_OPCODE_TABLE(OPCODE_MIN, MIN_I8, MIN_I16, MIN_I32, MIN_I64, MIN_F32,
|
||||
|
||||
@@ -5848,3 +5848,20 @@ test_vmaxfp_650_GEN:
|
||||
#_ REGISTER_OUT v2 [FFFFFF80, 0000007F, FFFEFF7F, 00010080]
|
||||
#_ REGISTER_OUT v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF]
|
||||
|
||||
test_vmaxfp_651_GEN:
|
||||
#_ REGISTER_IN v1 [FFC00000, FFC00000, FFC00000, 00000000]
|
||||
#_ REGISTER_IN v2 [00000000, 00000000, 00000000, 00000000]
|
||||
vmaxfp v3, v1, v2
|
||||
blr
|
||||
#_ REGISTER_OUT v1 [FFC00000, FFC00000, FFC00000, 00000000]
|
||||
#_ REGISTER_OUT v2 [00000000, 00000000, 00000000, 00000000]
|
||||
#_ REGISTER_OUT v3 [FFC00000, FFC00000, FFC00000, 00000000]
|
||||
|
||||
test_vmaxfp_652_GEN:
|
||||
#_ REGISTER_IN v1 [7FC00000, 7FC00000, 7FC00000, 00000000]
|
||||
#_ REGISTER_IN v2 [00000000, 00000000, 00000000, 00000000]
|
||||
vmaxfp v3, v1, v2
|
||||
blr
|
||||
#_ REGISTER_OUT v1 [7FC00000, 7FC00000, 7FC00000, 00000000]
|
||||
#_ REGISTER_OUT v2 [00000000, 00000000, 00000000, 00000000]
|
||||
#_ REGISTER_OUT v3 [7FC00000, 7FC00000, 7FC00000, 00000000]
|
||||
|
||||
@@ -5848,3 +5848,20 @@ test_vminfp_650_GEN:
|
||||
#_ REGISTER_OUT v2 [FFFFFF80, 0000007F, FFFEFF7F, 00010080]
|
||||
#_ REGISTER_OUT v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF]
|
||||
|
||||
test_vminfp_651_GEN:
|
||||
#_ REGISTER_IN v1 [FFC00000, FFC00000, FFC00000, 00000000]
|
||||
#_ REGISTER_IN v2 [477FFC00, 477FFC00, 477FFC00, 477FFC00]
|
||||
vminfp v3, v1, v2
|
||||
blr
|
||||
#_ REGISTER_OUT v1 [FFC00000, FFC00000, FFC00000, 00000000]
|
||||
#_ REGISTER_OUT v2 [477FFC00, 477FFC00, 477FFC00, 477FFC00]
|
||||
#_ REGISTER_OUT v3 [FFC00000, FFC00000, FFC00000, 00000000]
|
||||
|
||||
test_vminfp_652_GEN:
|
||||
#_ REGISTER_IN v1 [7FC00000, 7FC00000, 7FC00000, 00000000]
|
||||
#_ REGISTER_IN v2 [477FFC00, 477FFC00, 477FFC00, 477FFC00]
|
||||
vminfp v3, v1, v2
|
||||
blr
|
||||
#_ REGISTER_OUT v1 [7FC00000, 7FC00000, 7FC00000, 00000000]
|
||||
#_ REGISTER_OUT v2 [477FFC00, 477FFC00, 477FFC00, 477FFC00]
|
||||
#_ REGISTER_OUT v3 [7FC00000, 7FC00000, 7FC00000, 00000000]
|
||||
|
||||
Reference in New Issue
Block a user