Skip to content

Commit

Permalink
OpcodeDispatcher: accelerate cmpxchg with flagm
Browse files Browse the repository at this point in the history
Signed-off-by: Alyssa Rosenzweig <[email protected]>
  • Loading branch information
alyssarosenzweig committed Mar 29, 2024
1 parent 0cf4ee5 commit 3328485
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 10 deletions.
26 changes: 26 additions & 0 deletions FEXCore/Source/Interface/Core/JIT/Arm64/ALUOps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ tags: backend|arm64
$end_info$
*/

#include "FEXCore/IR/IR.h"
#include "Interface/Context/Context.h"
#include "Interface/Core/ArchHelpers/CodeEmitter/Emitter.h"
#include "Interface/Core/ArchHelpers/CodeEmitter/Registers.h"
Expand Down Expand Up @@ -299,6 +300,31 @@ DEF_OP(SubNZCV) {
}
}

DEF_OP(CmpPairZ) {
auto Op = IROp->C<IR::IROp_CmpPairZ>();
const uint8_t OpSize = IROp->Size;

const auto EmitSize = OpSize == IR::i64Bit ? ARMEmitter::Size::i64Bit : ARMEmitter::Size::i32Bit;

// Save NZCV
mrs(TMP1, ARMEmitter::SystemRegister::NZCV);

// Compare, setting Z and clobbering NzCV
const auto Src1 = GetRegPair(Op->Src1.ID());
const auto Src2 = GetRegPair(Op->Src2.ID());
cmp(EmitSize, Src1.first, Src2.first);
ccmp(EmitSize, Src1.second, Src2.second, ARMEmitter::StatusFlags::None, ARMEmitter::Condition::CC_EQ);

// Restore NzCV
if (CTX->HostFeatures.SupportsFlagM) {
rmif(TMP1, 0, 0xb /* NzCV */);
} else {
cset(ARMEmitter::Size::i32Bit, TMP2, ARMEmitter::Condition::CC_EQ);
bfi(ARMEmitter::Size::i32Bit, TMP1, TMP2, 30 /* lsb: Z */, 1);
msr(ARMEmitter::SystemRegister::NZCV, TMP1);
}
}

DEF_OP(CarryInvert) {
LOGMAN_THROW_A_FMT(CTX->HostFeatures.SupportsFlagM, "Unsupported flagm op");
cfinv();
Expand Down
12 changes: 2 additions & 10 deletions FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4258,16 +4258,8 @@ void OpDispatchBuilder::CMPXCHGPairOp(OpcodeArgs) {
OrderedNode *Result_Lower = _ExtractElementPair(IR::SizeToOpSize(Size), CASResult, 0);
OrderedNode *Result_Upper = _ExtractElementPair(IR::SizeToOpSize(Size), CASResult, 1);

// Set ZF if memory result was expected
auto OneConst = _Constant(1);
auto ZeroConst = _Constant(0);

OrderedNode *ZFResult = _Select(FEXCore::IR::COND_EQ,
CASResult, Expected,
OneConst, ZeroConst);

// Set ZF
SetRFLAG<FEXCore::X86State::RFLAG_ZF_RAW_LOC>(ZFResult);
HandleNZCV_RMW();
_CmpPairZ(IR::SizeToOpSize(Size), CASResult, Expected);
CalculateDeferredFlags();

auto UpdateIfNotZF = [this](auto Reg, auto Value) {
Expand Down
5 changes: 5 additions & 0 deletions FEXCore/Source/Interface/IR/IR.json
Original file line number Diff line number Diff line change
Expand Up @@ -1094,6 +1094,11 @@
"Size == FEXCore::IR::OpSize::i32Bit || Size == FEXCore::IR::OpSize::i64Bit"
]
},
"CmpPairZ OpSize:#Size, GPRPair:$Src1, GPRPair:$Src2": {
"Desc": ["Compares register paris and sets Z accordingly, preserving N/Z/V.",
"This accelerates cmpxchg."],
"HasSideEffects": true
},
"SubNZCV OpSize:#Size, GPR:$Src1, GPR:$Src2": {
"Desc": ["Set NZCV for the difference of two GPRs. ",
"Carry flag uses arm64 definition, inverted x86.",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,12 @@ DeadFlagCalculationEliminination::Classify(IROp_Header *IROp)
.CanEliminate = true,
};

case OP_CMPPAIRZ:
return {
.Write = FLAG_Z,
.CanEliminate = true,
};

case OP_CARRYINVERT:
return {
.Read = FLAG_C,
Expand Down

0 comments on commit 3328485

Please sign in to comment.