mirror of
https://github.com/FEX-Emu/FEX.git
synced 2024-12-16 02:17:20 +00:00
OpcodeDispatcher: optimize gpr cmpxchg
NZCV stuff. Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
This commit is contained in:
parent
0a6e875329
commit
e8945dfb6d
@ -4288,40 +4288,35 @@ void OpDispatchBuilder::CMPXCHGOp(OpcodeArgs) {
|
||||
Src3Lower = Src3;
|
||||
}
|
||||
|
||||
// If our destination is a GPR then this behaves differently
|
||||
// RAX = RAX == Op1 ? RAX : Op1
|
||||
// AKA if they match then don't touch RAX value
|
||||
// Otherwise set it to the rm operand
|
||||
OrderedNode *CASResult = _Select(FEXCore::IR::COND_EQ,
|
||||
Src1Lower, Src3Lower,
|
||||
Src3Lower, Src1Lower);
|
||||
// Compare RAX with the destination, setting flags accordingly.
|
||||
OrderedNode *Result = _Sub(IR::SizeToOpSize(GPRSize), Src3Lower, Src1Lower);
|
||||
GenerateFlags_SUB(Op, Result, Src3Lower, Src1Lower);
|
||||
CalculateDeferredFlags();
|
||||
|
||||
if (GPRSize == 8 && Size == 4) {
|
||||
// This allows us to only hit the ZEXT case on failure
|
||||
OrderedNode *RAXResult = _NZCVSelect(IR::i64Bit, CondClassType{COND_EQ},
|
||||
Src3, Src1Lower);
|
||||
|
||||
// When the size is 4 we need to make sure not zext the GPR when the comparison fails
|
||||
StoreGPRRegister(X86State::REG_RAX, RAXResult);
|
||||
}
|
||||
else {
|
||||
StoreGPRRegister(X86State::REG_RAX, Src1Lower, Size);
|
||||
}
|
||||
|
||||
// Op1 = RAX == Op1 ? Op2 : Op1
|
||||
// If they match then set the rm operand to the input
|
||||
// else don't set the rm operand
|
||||
OrderedNode *DestResult = _Select(FEXCore::IR::COND_EQ,
|
||||
Src1Lower, Src3Lower,
|
||||
Src2, Src1);
|
||||
OrderedNode *DestResult = _NZCVSelect(IR::i64Bit, CondClassType{COND_EQ},
|
||||
Src2, Src1);
|
||||
|
||||
// Store in to GPR Dest
|
||||
// Have to make sure this is after the result store in RAX for when Dest == RAX
|
||||
if (GPRSize == 8 && Size == 4) {
|
||||
// This allows us to only hit the ZEXT case on failure
|
||||
OrderedNode *RAXResult = _Select(FEXCore::IR::COND_EQ,
|
||||
CASResult, Src3Lower,
|
||||
Src3, Src1Lower);
|
||||
|
||||
// When the size is 4 we need to make sure not zext the GPR when the comparison fails
|
||||
StoreGPRRegister(X86State::REG_RAX, RAXResult);
|
||||
StoreResult_WithOpSize(GPRClass, Op, Op->Dest, DestResult, GPRSize, -1);
|
||||
}
|
||||
else {
|
||||
StoreGPRRegister(X86State::REG_RAX, CASResult, Size);
|
||||
} else {
|
||||
StoreResult(GPRClass, Op, DestResult, -1);
|
||||
}
|
||||
|
||||
OrderedNode *Result = _Sub(IR::SizeToOpSize(GPRSize), Src3Lower, CASResult);
|
||||
GenerateFlags_SUB(Op, Result, Src3Lower, CASResult);
|
||||
}
|
||||
else {
|
||||
HandledLock = Op->Flags & FEXCore::X86Tables::DecodeFlags::FLAG_LOCK;
|
||||
|
Loading…
Reference in New Issue
Block a user