mirror of
https://github.com/FEX-Emu/FEX.git
synced 2025-02-23 16:23:10 +00:00
OpcodeDispatcher: optimize LOOP invert
need to reorder since the select clobbers nzcv. before/after diff on the loopne unit test: > 4308: [INFO] cset w20, ne 40c41 < 4308: [INFO] mrs x20, nzcv --- > 4308: [INFO] mrs x21, nzcv 42,49c43,48 < 4308: [INFO] cset x21, ne < 4308: [INFO] ubfx w22, w20, #30, #1 < 4308: [INFO] eor x22, x22, #0x1 < 4308: [INFO] and x21, x21, x22 < 4308: [INFO] msr nzcv, x20 < 4308: [INFO] cbnz x21, #+0x8 (addr 0xfffed66f8094) < 4308: [INFO] b #+0x1c (addr 0xfffed66f80ac) < 4308: [INFO] ldr x0, pc+8 (addr 0xfffed66f809c) --- > 4308: [INFO] cset x22, ne > 4308: [INFO] and x20, x22, x20 > 4308: [INFO] msr nzcv, x21 > 4308: [INFO] cbnz x20, #+0x8 (addr 0xfffec94e8090) > 4308: [INFO] b #+0x1c (addr 0xfffec94e80a8) > 4308: [INFO] ldr x0, pc+8 (addr 0xfffec94e8098) Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
This commit is contained in:
parent
0d70c6a0d0
commit
ec14a65e23
@ -1092,6 +1092,12 @@ void OpDispatchBuilder::LoopOp(OpcodeArgs) {
|
||||
bool CheckZF = Op->OP != 0xE2;
|
||||
bool ZFTrue = Op->OP == 0xE1;
|
||||
|
||||
// If LOOPE then jumps to target if RCX != 0 && ZF == 1
|
||||
// If LOOPNE then jumps to target if RCX != 0 && ZF == 0
|
||||
OrderedNode *AndCondWith = nullptr;
|
||||
if (CheckZF)
|
||||
AndCondWith = GetRFLAG(FEXCore::X86State::RFLAG_ZF_RAW_LOC, !ZFTrue);
|
||||
|
||||
BlockSetRIP = true;
|
||||
auto ZeroConst = _Constant(0);
|
||||
IRPair<IROp_Header> SrcCond;
|
||||
@ -1112,15 +1118,8 @@ void OpDispatchBuilder::LoopOp(OpcodeArgs) {
|
||||
SrcCond = _Select(FEXCore::IR::COND_NEQ,
|
||||
CondReg, ZeroConst, TakeBranch, DoNotTakeBranch);
|
||||
|
||||
// If LOOPE then jumps to target if RCX != 0 && ZF == 1
|
||||
// If LOOPNE then jumps to target if RCX != 0 && ZF == 0
|
||||
if (CheckZF) {
|
||||
OrderedNode *ZF = GetRFLAG(FEXCore::X86State::RFLAG_ZF_RAW_LOC);
|
||||
if (!ZFTrue) {
|
||||
ZF = _Xor(OpSize::i64Bit, ZF, _Constant(1));
|
||||
}
|
||||
SrcCond = _And(OpSize::i64Bit, SrcCond, ZF);
|
||||
}
|
||||
if (AndCondWith)
|
||||
SrcCond = _And(OpSize::i64Bit, SrcCond, AndCondWith);
|
||||
|
||||
CalculateDeferredFlags();
|
||||
auto TrueBlock = JumpTargets.find(Target);
|
||||
|
Loading…
x
Reference in New Issue
Block a user