summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorSintendo <3380580+Sintendo@users.noreply.github.com>2024-06-23 23:21:07 +0200
committerSintendo <3380580+Sintendo@users.noreply.github.com>2024-10-21 08:33:05 +0200
commitdefb2d65a66f3307eee22065cabec341243321c9 (patch)
tree9cebb50303c92924ff4cc5c78276cbf339fb6eea /Source/Core
parentbe2b4667434d6adc818493d28c182b24370b13a1 (diff)
JitArm64_SystemRegisters: Use ScopedARM64Reg
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/PowerPC/JitArm64/JitArm64_SystemRegisters.cpp339
1 files changed, 152 insertions, 187 deletions
diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_SystemRegisters.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_SystemRegisters.cpp
index 8ffa1b84aa..df4ea4931a 100644
--- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_SystemRegisters.cpp
+++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_SystemRegisters.cpp
@@ -48,17 +48,16 @@ void JitArm64::FixGTBeforeSettingCRFieldBit(Arm64Gen::ARM64Reg reg)
// if the internal representation either has bit 63 set or has all bits set to zero.
// If all bits are zero and we set some bit that's unrelated to GT, we need to set bit 63 so GT
// doesn't accidentally become considered set. Gross but necessary; this can break actual games.
- ARM64Reg WA = gpr.GetReg();
+ auto WA = gpr.GetScopedReg();
ARM64Reg XA = EncodeRegTo64(WA);
ORR(XA, reg, LogicalImm(1ULL << 63, GPRSize::B64));
CMP(reg, ARM64Reg::ZR);
CSEL(reg, reg, XA, CC_NEQ);
- gpr.Unlock(WA);
}
void JitArm64::UpdateFPExceptionSummary(ARM64Reg fpscr)
{
- ARM64Reg WA = gpr.GetReg();
+ auto WA = gpr.GetScopedReg();
// fpscr.VX = (fpscr & FPSCR_VX_ANY) != 0
MOVI2R(WA, FPSCR_VX_ANY);
@@ -71,8 +70,6 @@ void JitArm64::UpdateFPExceptionSummary(ARM64Reg fpscr)
TST(WA, fpscr, ArithOption(fpscr, ShiftType::LSR, 22));
CSET(WA, CCFlags::CC_NEQ);
BFI(fpscr, WA, MathUtil::IntLog2(FPSCR_FEX), 1);
-
- gpr.Unlock(WA);
}
void JitArm64::UpdateRoundingMode()
@@ -135,7 +132,7 @@ void JitArm64::mcrxr(UGeckoInstruction inst)
JITDISABLE(bJITSystemRegistersOff);
gpr.BindCRToRegister(inst.CRFD, false);
- ARM64Reg WA = gpr.GetReg();
+ auto WA = gpr.GetScopedReg();
ARM64Reg XA = EncodeRegTo64(WA);
ARM64Reg XB = gpr.CR(inst.CRFD);
ARM64Reg WB = EncodeRegTo32(XB);
@@ -155,8 +152,6 @@ void JitArm64::mcrxr(UGeckoInstruction inst)
// Clear XER[0-3]
static_assert(PPCSTATE_OFF(xer_ca) + 1 == PPCSTATE_OFF(xer_so_ov));
STRH(IndexType::Unsigned, ARM64Reg::WZR, PPC_REG, PPCSTATE_OFF(xer_ca));
-
- gpr.Unlock(WA);
}
void JitArm64::mfsr(UGeckoInstruction inst)
@@ -186,14 +181,12 @@ void JitArm64::mfsrin(UGeckoInstruction inst)
ARM64Reg RB = gpr.R(b);
ARM64Reg RD = gpr.R(d);
- ARM64Reg index = gpr.GetReg();
+ auto index = gpr.GetScopedReg();
ARM64Reg addr = EncodeRegTo64(RD);
UBFM(index, RB, 28, 31);
ADDI2R(addr, PPC_REG, PPCSTATE_OFF_SR(0), addr);
LDR(RD, addr, ArithOption(EncodeRegTo64(index), true));
-
- gpr.Unlock(index);
}
void JitArm64::mtsrin(UGeckoInstruction inst)
@@ -206,14 +199,12 @@ void JitArm64::mtsrin(UGeckoInstruction inst)
ARM64Reg RB = gpr.R(b);
ARM64Reg RD = gpr.R(d);
- ARM64Reg index = gpr.GetReg();
- ARM64Reg addr = gpr.GetReg();
+ auto index = gpr.GetScopedReg();
+ auto addr = gpr.GetScopedReg();
UBFM(index, RB, 28, 31);
ADDI2R(EncodeRegTo64(addr), PPC_REG, PPCSTATE_OFF_SR(0), EncodeRegTo64(addr));
STR(RD, EncodeRegTo64(addr), ArithOption(EncodeRegTo64(index), true));
-
- gpr.Unlock(index, addr);
}
void JitArm64::twx(UGeckoInstruction inst)
@@ -223,7 +214,7 @@ void JitArm64::twx(UGeckoInstruction inst)
s32 a = inst.RA;
- ARM64Reg WA = gpr.GetReg();
+ auto WA = gpr.GetScopedReg();
if (inst.OPCD == 3) // twi
{
@@ -278,8 +269,6 @@ void JitArm64::twx(UGeckoInstruction inst)
fpr.Flush(FlushMode::All, ARM64Reg::INVALID_REG);
WriteExit(js.compilerPC + 4);
}
-
- gpr.Unlock(WA);
}
void JitArm64::mfspr(UGeckoInstruction inst)
@@ -294,19 +283,19 @@ void JitArm64::mfspr(UGeckoInstruction inst)
case SPR_TL:
case SPR_TU:
{
- ARM64Reg Wg = gpr.GetReg();
+ auto Wg = gpr.GetScopedReg();
ARM64Reg Xg = EncodeRegTo64(Wg);
- ARM64Reg Wresult = gpr.GetReg();
+ auto Wresult = gpr.GetScopedReg();
ARM64Reg Xresult = EncodeRegTo64(Wresult);
- ARM64Reg WA = gpr.GetReg();
- ARM64Reg WB = gpr.GetReg();
+ auto WA = gpr.GetScopedReg();
+ auto WB = gpr.GetScopedReg();
ARM64Reg XA = EncodeRegTo64(WA);
ARM64Reg XB = EncodeRegTo64(WB);
- ARM64Reg VC = fpr.GetReg();
- ARM64Reg VD = fpr.GetReg();
+ auto VC = fpr.GetScopedReg();
+ auto VD = fpr.GetScopedReg();
ARM64Reg SC = EncodeRegToSingle(VC);
ARM64Reg SD = EncodeRegToSingle(VD);
@@ -371,8 +360,6 @@ void JitArm64::mfspr(UGeckoInstruction inst)
else
LSR(EncodeRegTo64(gpr.R(n)), Xresult, 32);
- gpr.Unlock(Wg, Wresult, WA, WB);
- fpr.Unlock(VC, VD);
break;
}
}
@@ -381,22 +368,18 @@ void JitArm64::mfspr(UGeckoInstruction inst)
LSR(EncodeRegTo64(gpr.R(d)), Xresult, 32);
else
MOV(gpr.R(d), Wresult);
-
- gpr.Unlock(Wg, Wresult, WA, WB);
- fpr.Unlock(VC, VD);
}
break;
case SPR_XER:
{
gpr.BindToRegister(d, false);
ARM64Reg RD = gpr.R(d);
- ARM64Reg WA = gpr.GetReg();
+ auto WA = gpr.GetScopedReg();
LDRH(IndexType::Unsigned, RD, PPC_REG, PPCSTATE_OFF(xer_stringctrl));
LDRB(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(xer_ca));
ORR(RD, RD, WA, ArithOption(WA, ShiftType::LSL, XER_CA_SHIFT));
LDRB(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(xer_so_ov));
ORR(RD, RD, WA, ArithOption(WA, ShiftType::LSL, XER_OV_SHIFT));
- gpr.Unlock(WA);
}
break;
case SPR_WPAR:
@@ -462,14 +445,13 @@ void JitArm64::mtspr(UGeckoInstruction inst)
case SPR_XER:
{
ARM64Reg RD = gpr.R(inst.RD);
- ARM64Reg WA = gpr.GetReg();
+ auto WA = gpr.GetScopedReg();
AND(WA, RD, LogicalImm(0xFFFFFF7F, GPRSize::B32));
STRH(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(xer_stringctrl));
UBFM(WA, RD, XER_CA_SHIFT, XER_CA_SHIFT + 1);
STRB(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(xer_ca));
UBFM(WA, RD, XER_OV_SHIFT, 31); // Same as WA = RD >> XER_OV_SHIFT
STRB(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(xer_so_ov));
- gpr.Unlock(WA);
}
break;
default:
@@ -553,114 +535,112 @@ void JitArm64::crXXX(UGeckoInstruction inst)
return;
}
- ARM64Reg WA = gpr.GetReg();
+ auto WA = gpr.GetScopedReg();
ARM64Reg XA = EncodeRegTo64(WA);
- ARM64Reg WB = gpr.GetReg();
- ARM64Reg XB = EncodeRegTo64(WB);
-
- // creqv or crnand or crnor
- bool negateA = inst.SUBOP10 == 289 || inst.SUBOP10 == 225 || inst.SUBOP10 == 33;
- // crandc or crorc or crnand or crnor
- bool negateB =
- inst.SUBOP10 == 129 || inst.SUBOP10 == 417 || inst.SUBOP10 == 225 || inst.SUBOP10 == 33;
-
- // GetCRFieldBit
- for (int i = 0; i < 2; i++)
{
- int field = i ? inst.CRBB >> 2 : inst.CRBA >> 2;
- int bit = i ? 3 - (inst.CRBB & 3) : 3 - (inst.CRBA & 3);
- ARM64Reg out = i ? XB : XA;
- bool negate = i ? negateB : negateA;
+ auto WB = gpr.GetScopedReg();
+ ARM64Reg XB = EncodeRegTo64(WB);
- ARM64Reg XC = gpr.CR(field);
- ARM64Reg WC = EncodeRegTo32(XC);
- switch (bit)
+ // creqv or crnand or crnor
+ bool negateA = inst.SUBOP10 == 289 || inst.SUBOP10 == 225 || inst.SUBOP10 == 33;
+ // crandc or crorc or crnand or crnor
+ bool negateB =
+ inst.SUBOP10 == 129 || inst.SUBOP10 == 417 || inst.SUBOP10 == 225 || inst.SUBOP10 == 33;
+
+ // GetCRFieldBit
+ for (int i = 0; i < 2; i++)
{
- case PowerPC::CR_SO_BIT: // check bit 59 set
- UBFX(out, XC, PowerPC::CR_EMU_SO_BIT, 1);
- if (negate)
- EOR(out, out, LogicalImm(1, GPRSize::B64));
- break;
+ int field = i ? inst.CRBB >> 2 : inst.CRBA >> 2;
+ int bit = i ? 3 - (inst.CRBB & 3) : 3 - (inst.CRBA & 3);
+ ARM64Reg out = i ? XB : XA;
+ bool negate = i ? negateB : negateA;
+
+ ARM64Reg XC = gpr.CR(field);
+ ARM64Reg WC = EncodeRegTo32(XC);
+ switch (bit)
+ {
+ case PowerPC::CR_SO_BIT: // check bit 59 set
+ UBFX(out, XC, PowerPC::CR_EMU_SO_BIT, 1);
+ if (negate)
+ EOR(out, out, LogicalImm(1, GPRSize::B64));
+ break;
- case PowerPC::CR_EQ_BIT: // check bits 31-0 == 0
- CMP(WC, ARM64Reg::WZR);
- CSET(out, negate ? CC_NEQ : CC_EQ);
- break;
+ case PowerPC::CR_EQ_BIT: // check bits 31-0 == 0
+ CMP(WC, ARM64Reg::WZR);
+ CSET(out, negate ? CC_NEQ : CC_EQ);
+ break;
- case PowerPC::CR_GT_BIT: // check val > 0
- CMP(XC, ARM64Reg::ZR);
- CSET(out, negate ? CC_LE : CC_GT);
- break;
+ case PowerPC::CR_GT_BIT: // check val > 0
+ CMP(XC, ARM64Reg::ZR);
+ CSET(out, negate ? CC_LE : CC_GT);
+ break;
- case PowerPC::CR_LT_BIT: // check bit 62 set
- UBFX(out, XC, PowerPC::CR_EMU_LT_BIT, 1);
- if (negate)
- EOR(out, out, LogicalImm(1, GPRSize::B64));
- break;
+ case PowerPC::CR_LT_BIT: // check bit 62 set
+ UBFX(out, XC, PowerPC::CR_EMU_LT_BIT, 1);
+ if (negate)
+ EOR(out, out, LogicalImm(1, GPRSize::B64));
+ break;
- default:
- ASSERT_MSG(DYNA_REC, false, "Invalid CR bit");
+ default:
+ ASSERT_MSG(DYNA_REC, false, "Invalid CR bit");
+ }
}
- }
- // Compute combined bit
- switch (inst.SUBOP10)
- {
- case 33: // crnor: ~(A || B) == (~A && ~B)
- case 129: // crandc: A && ~B
- case 257: // crand: A && B
- AND(XA, XA, XB);
- break;
+ // Compute combined bit
+ switch (inst.SUBOP10)
+ {
+ case 33: // crnor: ~(A || B) == (~A && ~B)
+ case 129: // crandc: A && ~B
+ case 257: // crand: A && B
+ AND(XA, XA, XB);
+ break;
- case 193: // crxor: A ^ B
- case 289: // creqv: ~(A ^ B) = ~A ^ B
- EOR(XA, XA, XB);
- break;
+ case 193: // crxor: A ^ B
+ case 289: // creqv: ~(A ^ B) = ~A ^ B
+ EOR(XA, XA, XB);
+ break;
- case 225: // crnand: ~(A && B) == (~A || ~B)
- case 417: // crorc: A || ~B
- case 449: // cror: A || B
- ORR(XA, XA, XB);
- break;
+ case 225: // crnand: ~(A && B) == (~A || ~B)
+ case 417: // crorc: A || ~B
+ case 449: // cror: A || B
+ ORR(XA, XA, XB);
+ break;
+ }
}
// Store result bit in CRBD
int field = inst.CRBD >> 2;
int bit = 3 - (inst.CRBD & 3);
- gpr.Unlock(WB);
- WB = ARM64Reg::INVALID_REG;
gpr.BindCRToRegister(field, true);
- XB = gpr.CR(field);
+ ARM64Reg CR = gpr.CR(field);
if (bit != PowerPC::CR_GT_BIT)
- FixGTBeforeSettingCRFieldBit(XB);
+ FixGTBeforeSettingCRFieldBit(CR);
switch (bit)
{
case PowerPC::CR_SO_BIT: // set bit 59 to input
- BFI(XB, XA, PowerPC::CR_EMU_SO_BIT, 1);
+ BFI(CR, XA, PowerPC::CR_EMU_SO_BIT, 1);
break;
case PowerPC::CR_EQ_BIT: // clear low 32 bits, set bit 0 to !input
- AND(XB, XB, LogicalImm(0xFFFF'FFFF'0000'0000, GPRSize::B64));
+ AND(CR, CR, LogicalImm(0xFFFF'FFFF'0000'0000, GPRSize::B64));
EOR(XA, XA, LogicalImm(1, GPRSize::B64));
- ORR(XB, XB, XA);
+ ORR(CR, CR, XA);
break;
case PowerPC::CR_GT_BIT: // set bit 63 to !input
EOR(XA, XA, LogicalImm(1, GPRSize::B64));
- BFI(XB, XA, 63, 1);
+ BFI(CR, XA, 63, 1);
break;
case PowerPC::CR_LT_BIT: // set bit 62 to input
- BFI(XB, XA, PowerPC::CR_EMU_LT_BIT, 1);
+ BFI(CR, XA, PowerPC::CR_EMU_LT_BIT, 1);
break;
}
- ORR(XB, XB, LogicalImm(1ULL << 32, GPRSize::B64));
-
- gpr.Unlock(WA);
+ ORR(CR, CR, LogicalImm(1ULL << 32, GPRSize::B64));
}
void JitArm64::mfcr(UGeckoInstruction inst)
@@ -670,8 +650,8 @@ void JitArm64::mfcr(UGeckoInstruction inst)
gpr.BindToRegister(inst.RD, false);
ARM64Reg WA = gpr.R(inst.RD);
- ARM64Reg WB = gpr.GetReg();
- ARM64Reg WC = gpr.GetReg();
+ auto WB = gpr.GetScopedReg();
+ auto WC = gpr.GetScopedReg();
ARM64Reg XA = EncodeRegTo64(WA);
ARM64Reg XB = EncodeRegTo64(WB);
ARM64Reg XC = EncodeRegTo64(WC);
@@ -716,8 +696,6 @@ void JitArm64::mfcr(UGeckoInstruction inst)
else if (!js.op->crInUse[i])
gpr.StoreCRRegisters(BitSet8{i}, WC);
}
-
- gpr.Unlock(WB, WC);
}
void JitArm64::mtcrf(UGeckoInstruction inst)
@@ -729,7 +707,7 @@ void JitArm64::mtcrf(UGeckoInstruction inst)
if (crm != 0)
{
ARM64Reg RS = gpr.R(inst.RS);
- ARM64Reg WB = gpr.GetReg();
+ auto WB = gpr.GetScopedReg();
ARM64Reg XB = EncodeRegTo64(WB);
MOVP2R(XB, PowerPC::ConditionRegister::s_crTable.data());
for (int i = 0; i < 8; ++i)
@@ -753,7 +731,6 @@ void JitArm64::mtcrf(UGeckoInstruction inst)
LDR(CR, XB, ArithOption(CR, true));
}
}
- gpr.Unlock(WB);
}
}
@@ -771,7 +748,7 @@ void JitArm64::mcrfs(UGeckoInstruction inst)
gpr.BindCRToRegister(field, false);
ARM64Reg CR = gpr.CR(field);
- ARM64Reg WA = gpr.GetReg();
+ auto WA = gpr.GetScopedReg();
ARM64Reg WCR = EncodeRegTo32(CR);
ARM64Reg XA = EncodeRegTo64(WA);
@@ -789,8 +766,6 @@ void JitArm64::mcrfs(UGeckoInstruction inst)
MOVP2R(XA, PowerPC::ConditionRegister::s_crTable.data());
LDR(CR, XA, ArithOption(CR, true));
-
- gpr.Unlock(WA);
}
void JitArm64::mffsx(UGeckoInstruction inst)
@@ -799,7 +774,7 @@ void JitArm64::mffsx(UGeckoInstruction inst)
JITDISABLE(bJITSystemRegistersOff);
FALLBACK_IF(inst.Rc);
- ARM64Reg WA = gpr.GetReg();
+ auto WA = gpr.GetScopedReg();
ARM64Reg XA = EncodeRegTo64(WA);
LDR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(fpscr));
@@ -808,8 +783,6 @@ void JitArm64::mffsx(UGeckoInstruction inst)
ORR(XA, XA, LogicalImm(0xFFF8'0000'0000'0000, GPRSize::B64));
m_float_emit.FMOV(EncodeRegToDouble(VD), XA);
-
- gpr.Unlock(WA);
}
void JitArm64::mtfsb0x(UGeckoInstruction inst)
@@ -824,17 +797,17 @@ void JitArm64::mtfsb0x(UGeckoInstruction inst)
if (mask == FPSCR_FEX || mask == FPSCR_VX)
return;
- ARM64Reg WA = gpr.GetReg();
-
- LDR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(fpscr));
+ {
+ auto WA = gpr.GetScopedReg();
- AND(WA, WA, LogicalImm(inverted_mask, GPRSize::B32));
+ LDR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(fpscr));
- if ((mask & (FPSCR_ANY_X | FPSCR_ANY_E)) != 0)
- UpdateFPExceptionSummary(WA);
- STR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(fpscr));
+ AND(WA, WA, LogicalImm(inverted_mask, GPRSize::B32));
- gpr.Unlock(WA);
+ if ((mask & (FPSCR_ANY_X | FPSCR_ANY_E)) != 0)
+ UpdateFPExceptionSummary(WA);
+ STR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(fpscr));
+ }
if (inst.CRBD >= 29)
UpdateRoundingMode();
@@ -852,25 +825,24 @@ void JitArm64::mtfsb1x(UGeckoInstruction inst)
if (mask == FPSCR_FEX || mask == FPSCR_VX)
return;
- ARM64Reg WA = gpr.GetReg();
-
- LDR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(fpscr));
-
- if ((mask & FPSCR_ANY_X) != 0)
{
- ARM64Reg WB = gpr.GetReg();
- TST(WA, LogicalImm(mask, GPRSize::B32));
- ORR(WB, WA, LogicalImm(1 << 31, GPRSize::B32));
- CSEL(WA, WA, WB, CCFlags::CC_NEQ);
- gpr.Unlock(WB);
- }
- ORR(WA, WA, LogicalImm(mask, GPRSize::B32));
+ auto WA = gpr.GetScopedReg();
- if ((mask & (FPSCR_ANY_X | FPSCR_ANY_E)) != 0)
- UpdateFPExceptionSummary(WA);
- STR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(fpscr));
+ LDR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(fpscr));
- gpr.Unlock(WA);
+ if ((mask & FPSCR_ANY_X) != 0)
+ {
+ auto WB = gpr.GetScopedReg();
+ TST(WA, LogicalImm(mask, GPRSize::B32));
+ ORR(WB, WA, LogicalImm(1 << 31, GPRSize::B32));
+ CSEL(WA, WA, WB, CCFlags::CC_NEQ);
+ }
+ ORR(WA, WA, LogicalImm(mask, GPRSize::B32));
+
+ if ((mask & (FPSCR_ANY_X | FPSCR_ANY_E)) != 0)
+ UpdateFPExceptionSummary(WA);
+ STR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(fpscr));
+ }
if (inst.CRBD >= 29)
UpdateRoundingMode();
@@ -887,32 +859,31 @@ void JitArm64::mtfsfix(UGeckoInstruction inst)
u8 shift = 28 - 4 * inst.CRFD;
u32 mask = 0xF << shift;
- ARM64Reg WA = gpr.GetReg();
-
- LDR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(fpscr));
-
- if (imm == 0xF)
- {
- ORR(WA, WA, LogicalImm(mask, GPRSize::B32));
- }
- else if (imm == 0x0)
{
- const u32 inverted_mask = ~mask;
- AND(WA, WA, LogicalImm(inverted_mask, GPRSize::B32));
- }
- else
- {
- ARM64Reg WB = gpr.GetReg();
- MOVZ(WB, imm);
- BFI(WA, WB, shift, 4);
- gpr.Unlock(WB);
- }
+ auto WA = gpr.GetScopedReg();
- if ((mask & (FPSCR_FEX | FPSCR_VX | FPSCR_ANY_X | FPSCR_ANY_E)) != 0)
- UpdateFPExceptionSummary(WA);
- STR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(fpscr));
+ LDR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(fpscr));
- gpr.Unlock(WA);
+ if (imm == 0xF)
+ {
+ ORR(WA, WA, LogicalImm(mask, GPRSize::B32));
+ }
+ else if (imm == 0x0)
+ {
+ const u32 inverted_mask = ~mask;
+ AND(WA, WA, LogicalImm(inverted_mask, GPRSize::B32));
+ }
+ else
+ {
+ auto WB = gpr.GetScopedReg();
+ MOVZ(WB, imm);
+ BFI(WA, WB, shift, 4);
+ }
+
+ if ((mask & (FPSCR_FEX | FPSCR_VX | FPSCR_ANY_X | FPSCR_ANY_E)) != 0)
+ UpdateFPExceptionSummary(WA);
+ STR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(fpscr));
+ }
// Field 7 contains NI and RN.
if (inst.CRFD == 7)
@@ -936,49 +907,43 @@ void JitArm64::mtfsfx(UGeckoInstruction inst)
if (mask == 0xFFFFFFFF)
{
ARM64Reg VB = fpr.R(inst.FB, RegType::LowerPair);
- ARM64Reg WA = gpr.GetReg();
+ auto WA = gpr.GetScopedReg();
m_float_emit.FMOV(WA, EncodeRegToSingle(VB));
UpdateFPExceptionSummary(WA);
STR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(fpscr));
-
- gpr.Unlock(WA);
}
else if (mask != 0)
{
ARM64Reg VB = fpr.R(inst.FB, RegType::LowerPair);
- ARM64Reg WA = gpr.GetReg();
- ARM64Reg WB = gpr.GetReg();
-
- LDR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(fpscr));
- m_float_emit.FMOV(WB, EncodeRegToSingle(VB));
-
- if (LogicalImm imm = LogicalImm(mask, GPRSize::B32))
+ auto WA = gpr.GetScopedReg();
{
- const u32 inverted_mask = ~mask;
- AND(WA, WA, LogicalImm(inverted_mask, GPRSize::B32));
- AND(WB, WB, imm);
- }
- else
- {
- ARM64Reg WC = gpr.GetReg();
+ auto WB = gpr.GetScopedReg();
- MOVI2R(WC, mask);
- BIC(WA, WA, WC);
- AND(WB, WB, WC);
+ LDR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(fpscr));
+ m_float_emit.FMOV(WB, EncodeRegToSingle(VB));
- gpr.Unlock(WC);
- }
- ORR(WA, WA, WB);
+ if (LogicalImm imm = LogicalImm(mask, GPRSize::B32))
+ {
+ const u32 inverted_mask = ~mask;
+ AND(WA, WA, LogicalImm(inverted_mask, GPRSize::B32));
+ AND(WB, WB, imm);
+ }
+ else
+ {
+ auto WC = gpr.GetScopedReg();
- gpr.Unlock(WB);
+ MOVI2R(WC, mask);
+ BIC(WA, WA, WC);
+ AND(WB, WB, WC);
+ }
+ ORR(WA, WA, WB);
+ }
if ((mask & (FPSCR_FEX | FPSCR_VX | FPSCR_ANY_X | FPSCR_ANY_E)) != 0)
UpdateFPExceptionSummary(WA);
STR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(fpscr));
-
- gpr.Unlock(WA);
}
if (inst.FM & 1)