mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2024-11-14 13:27:45 -07:00
JitArm64_SystemRegisters: Use ScopedARM64Reg
This commit is contained in:
parent
be2b466743
commit
defb2d65a6
@ -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;
|
||||
|
||||
case PowerPC::CR_EQ_BIT: // check bits 31-0 == 0
|
||||
CMP(WC, ARM64Reg::WZR);
|
||||
CSET(out, negate ? CC_NEQ : CC_EQ);
|
||||
break;
|
||||
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_GT_BIT: // check val > 0
|
||||
CMP(XC, ARM64Reg::ZR);
|
||||
CSET(out, negate ? CC_LE : CC_GT);
|
||||
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_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_GT_BIT: // check val > 0
|
||||
CMP(XC, ARM64Reg::ZR);
|
||||
CSET(out, negate ? CC_LE : CC_GT);
|
||||
break;
|
||||
|
||||
default:
|
||||
ASSERT_MSG(DYNA_REC, false, "Invalid CR bit");
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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();
|
||||
{
|
||||
auto WA = gpr.GetScopedReg();
|
||||
|
||||
LDR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(fpscr));
|
||||
LDR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(fpscr));
|
||||
|
||||
AND(WA, WA, LogicalImm(inverted_mask, GPRSize::B32));
|
||||
AND(WA, WA, LogicalImm(inverted_mask, GPRSize::B32));
|
||||
|
||||
if ((mask & (FPSCR_ANY_X | FPSCR_ANY_E)) != 0)
|
||||
UpdateFPExceptionSummary(WA);
|
||||
STR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(fpscr));
|
||||
|
||||
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);
|
||||
auto WA = gpr.GetScopedReg();
|
||||
|
||||
LDR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(fpscr));
|
||||
|
||||
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));
|
||||
}
|
||||
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));
|
||||
|
||||
gpr.Unlock(WA);
|
||||
|
||||
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);
|
||||
auto WB = gpr.GetScopedReg();
|
||||
|
||||
LDR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(fpscr));
|
||||
m_float_emit.FMOV(WB, EncodeRegToSingle(VB));
|
||||
|
||||
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();
|
||||
|
||||
MOVI2R(WC, mask);
|
||||
BIC(WA, WA, WC);
|
||||
AND(WB, WB, WC);
|
||||
}
|
||||
ORR(WA, WA, WB);
|
||||
}
|
||||
else
|
||||
{
|
||||
ARM64Reg WC = gpr.GetReg();
|
||||
|
||||
MOVI2R(WC, mask);
|
||||
BIC(WA, WA, WC);
|
||||
AND(WB, WB, WC);
|
||||
|
||||
gpr.Unlock(WC);
|
||||
}
|
||||
ORR(WA, WA, WB);
|
||||
|
||||
gpr.Unlock(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)
|
||||
|
Loading…
Reference in New Issue
Block a user