aboutsummaryrefslogtreecommitdiff
path: root/src/ARMJIT_A64/ARMJIT_Branch.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ARMJIT_A64/ARMJIT_Branch.cpp')
-rw-r--r--src/ARMJIT_A64/ARMJIT_Branch.cpp99
1 files changed, 34 insertions, 65 deletions
diff --git a/src/ARMJIT_A64/ARMJIT_Branch.cpp b/src/ARMJIT_A64/ARMJIT_Branch.cpp
index 542f0b7..f130938 100644
--- a/src/ARMJIT_A64/ARMJIT_Branch.cpp
+++ b/src/ARMJIT_A64/ARMJIT_Branch.cpp
@@ -143,7 +143,7 @@ void Compiler::Comp_JumpTo(u32 addr, bool forceNonConstantCycles)
if ((Thumb || CurInstr.Cond() >= 0xE) && !forceNonConstantCycles)
ConstantCycles += cycles;
else
- ADD(RCycles, RCycles, cycles);
+ SUB(RCycles, RCycles, cycles);
}
@@ -152,23 +152,19 @@ void* Compiler::Gen_JumpTo9(int kind)
AlignCode16();
void* res = GetRXPtr();
- MOVI2R(W2, kCodeCacheTiming);
- // W1 - code cycles non branch
- // W2 - branch code cycles
LSR(W1, W0, 12);
- LSL(W1, W1, 2);
ADDI2R(W1, W1, offsetof(ARMv5, MemTimings), W2);
LDRB(W1, RCPU, W1);
- LDR(INDEX_UNSIGNED, W3, RCPU, offsetof(ARMv5, ITCMSize));
+ LDR(INDEX_UNSIGNED, W2, RCPU, offsetof(ARMv5, ITCMSize));
STR(INDEX_UNSIGNED, W1, RCPU, offsetof(ARMv5, RegionCodeCycles));
- CMP(W0, W3);
- FixupBranch outsideITCM = B(CC_LO);
- MOVI2R(W1, 1);
- MOVI2R(W2, 1);
- SetJumpTarget(outsideITCM);
+ CMP(W1, 0xFF);
+ MOVI2R(W3, kCodeCacheTiming);
+ CSEL(W1, W3, W1, CC_EQ);
+ CMP(W0, W2);
+ CSINC(W1, W1, WZR, CC_HS);
FixupBranch switchToThumb;
if (kind == 0)
@@ -176,40 +172,36 @@ void* Compiler::Gen_JumpTo9(int kind)
if (kind == 0 || kind == 1)
{
- ANDI2R(W0, W0, ~3);
-
+ // ARM
if (kind == 0)
ANDI2R(RCPSR, RCPSR, ~0x20);
- ADD(W3, W0, 4);
- STR(INDEX_UNSIGNED, W3, RCPU, offsetof(ARM, R[15]));
-
- ADD(W1, W1, W2);
- ADD(RCycles, RCycles, W1);
+ ANDI2R(W0, W0, ~3);
+ ADD(W0, W0, 4);
+ STR(INDEX_UNSIGNED, W0, RCPU, offsetof(ARMv5, R[15]));
+ ADD(W1, W1, W1);
+ SUB(RCycles, RCycles, W1);
RET();
}
+
if (kind == 0 || kind == 2)
{
+ // Thumb
if (kind == 0)
{
SetJumpTarget(switchToThumb);
-
ORRI2R(RCPSR, RCPSR, 0x20);
}
ANDI2R(W0, W0, ~1);
+ ADD(W0, W0, 2);
+ STR(INDEX_UNSIGNED, W0, RCPU, offsetof(ARMv5, R[15]));
- ADD(W3, W0, 2);
- STR(INDEX_UNSIGNED, W3, RCPU, offsetof(ARM, R[15]));
-
- FixupBranch halfwordLoc = TBZ(W0, 1);
- ADD(W1, W1, W2);
- ADD(RCycles, RCycles, W1);
- RET();
-
- SetJumpTarget(halfwordLoc);
- ADD(RCycles, RCycles, W2);
+ ADD(W2, W1, W1);
+ TSTI2R(W0, 0x2);
+ CSEL(W1, W1, W2, CC_EQ);
+ SUB(RCycles, RCycles, W1);
RET();
}
@@ -237,7 +229,7 @@ void* Compiler::Gen_JumpTo7(int kind)
UBFX(W2, W3, 0, 8);
UBFX(W3, W3, 8, 8);
ADD(W2, W3, W2);
- ADD(RCycles, RCycles, W2);
+ SUB(RCycles, RCycles, W2);
ANDI2R(W0, W0, ~3);
@@ -261,7 +253,7 @@ void* Compiler::Gen_JumpTo7(int kind)
UBFX(W2, W3, 16, 8);
UBFX(W3, W3, 24, 8);
ADD(W2, W3, W2);
- ADD(RCycles, RCycles, W2);
+ SUB(RCycles, RCycles, W2);
ANDI2R(W0, W0, ~1);
@@ -287,22 +279,11 @@ void Compiler::Comp_JumpTo(Arm64Gen::ARM64Reg addr, bool switchThumb, bool resto
}
else
{
- BitSet16 hiRegsLoaded(RegCache.DirtyRegs & 0xFF00);
- bool previouslyDirty = CPSRDirty;
+
+ bool cpsrDirty = CPSRDirty;
SaveCPSR();
-
- if (restoreCPSR)
- {
- if (Thumb || CurInstr.Cond() >= 0xE)
- RegCache.Flush();
- else
- {
- // the ugly way...
- // we only save them, to load and save them again
- for (int reg : hiRegsLoaded)
- SaveReg(reg, RegCache.Mapping[reg]);
- }
- }
+ SaveCycles();
+ PushRegs(restoreCPSR);
if (switchThumb)
MOV(W1, addr);
@@ -319,16 +300,12 @@ void Compiler::Comp_JumpTo(Arm64Gen::ARM64Reg addr, bool switchThumb, bool resto
QuickCallFunction(X3, jumpToTrampoline<ARMv5>);
else
QuickCallFunction(X3, jumpToTrampoline<ARMv4>);
-
- if (!Thumb && restoreCPSR && CurInstr.Cond() < 0xE)
- {
- for (int reg : hiRegsLoaded)
- LoadReg(reg, RegCache.Mapping[reg]);
- }
- if (previouslyDirty)
- LoadCPSR();
- CPSRDirty = previouslyDirty;
+ PopRegs(restoreCPSR);
+ LoadCycles();
+ LoadCPSR();
+ if (CurInstr.Cond() < 0xE)
+ CPSRDirty = cpsrDirty;
}
}
@@ -368,21 +345,13 @@ void Compiler::T_Comp_BCOND()
s32 offset = (s32)(CurInstr.Instr << 24) >> 23;
Comp_JumpTo(R15 + offset + 1, true);
- Comp_BranchSpecialBehaviour();
+ Comp_BranchSpecialBehaviour(true);
FixupBranch skipFailed = B();
SetJumpTarget(skipExecute);
Comp_AddCycles_C(true);
- if (CurInstr.BranchFlags & branch_FollowCondTaken)
- {
- SaveCPSR(false);
- RegCache.PrepareExit();
-
- ADD(W0, RCycles, ConstantCycles);
- ABI_PopRegisters(SavedRegs);
- RET();
- }
+ Comp_BranchSpecialBehaviour(false);
SetJumpTarget(skipFailed);
}