OpcodeDispatcher: refactor Comiss helper

AVX128 will use this, it's not SSE-specific.

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
This commit is contained in:
Alyssa Rosenzweig 2024-06-21 14:23:09 -04:00
parent e7bdb8679d
commit 9ecb960f3a
3 changed files with 17 additions and 19 deletions

View File

@ -1551,10 +1551,14 @@ private:
return _AddShift(OpSize::i64Bit, X, _LoadDF(), ShiftType::LSL, Shift);
}
// Set SSE comparison flags based on the result set by Arm FCMP. This converts
// NZCV from the Arm representation to an eXternal representation that's
// totally not a euphemism for x86 or anything, nuh-uh.
void ConvertNZCVToSSE() {
// Compares two floats and sets flags for a COMISS instruction
void Comiss(size_t ElementSize, Ref Src1, Ref Src2, bool InvalidateAF = false) {
// First, set flags according to Arm FCMP.
HandleNZCVWrite();
_FCmp(ElementSize, Src1, Src2);
// Now set COMISS flags by converts NZCV from the Arm representation to an
// eXternal representation that's totally not a euphemism for x86, nuh-uh.
if (CTX->HostFeatures.SupportsFlagM2) {
LOGMAN_THROW_A_FMT(!NZCVDirty, "only expected after fcmp");
@ -1594,6 +1598,13 @@ private:
// Note that we store PF inverted.
SetRFLAG<FEXCore::X86State::RFLAG_PF_RAW_LOC>(_Xor(OpSize::i32Bit, V, _Constant(1)));
}
if (!InvalidateAF) {
// Zero AF. Note that the comparison sets the raw PF to 0/1 above, so
// PF[4] is 0 so the XOR with PF will have no effect, so setting the AF
// byte to zero will indeed zero AF as intended.
SetRFLAG<FEXCore::X86State::RFLAG_AF_RAW_LOC>(_Constant(0));
}
}
// Set x87 comparison flags based on the result set by Arm FCMP. Clobbers

View File

@ -3039,14 +3039,7 @@ void OpDispatchBuilder::UCOMISxOp(OpcodeArgs) {
Ref Src1 = LoadSource_WithOpSize(FPRClass, Op, Op->Dest, GetGuestVectorLength(), Op->Flags);
Ref Src2 = LoadSource_WithOpSize(FPRClass, Op, Op->Src[0], SrcSize, Op->Flags);
HandleNZCVWrite();
_FCmp(ElementSize, Src1, Src2);
ConvertNZCVToSSE();
// Zero AF. Note that the comparison sets the raw PF to 0/1 above, so PF[4] is
// 0 so the XOR with PF will have no effect, so setting the AF byte to zero
// will indeed zero AF as intended.
SetRFLAG<FEXCore::X86State::RFLAG_AF_RAW_LOC>(_Constant(0));
Comiss(ElementSize, Src1, Src2);
}
template void OpDispatchBuilder::UCOMISxOp<4>(OpcodeArgs);

View File

@ -623,13 +623,7 @@ void OpDispatchBuilder::FCOMIF64(OpcodeArgs) {
PossiblySetNZCVBits = ~0;
ConvertNZCVToX87();
} else {
// Invalidate deferred flags early
// OF, SF, AF, PF all undefined
InvalidateDeferredFlags();
_FCmp(8, a, b);
PossiblySetNZCVBits = ~0;
ConvertNZCVToSSE();
Comiss(8, a, b, true /* InvalidateAF */);
}
if constexpr (poptwice) {