JitArm64: Implement indexed paired loadstore instructions
After writing 23b81ef
without realizing that we hadn't actually
implemented the indexed paired loadstore instructions yet,
I am now implementing them.
This commit is contained in:
parent
d162015112
commit
b24b79e373
|
@ -159,8 +159,8 @@ public:
|
||||||
void ps_cmpXX(UGeckoInstruction inst);
|
void ps_cmpXX(UGeckoInstruction inst);
|
||||||
|
|
||||||
// Loadstore paired
|
// Loadstore paired
|
||||||
void psq_l(UGeckoInstruction inst);
|
void psq_lXX(UGeckoInstruction inst);
|
||||||
void psq_st(UGeckoInstruction inst);
|
void psq_stXX(UGeckoInstruction inst);
|
||||||
|
|
||||||
void ConvertDoubleToSingleLower(size_t guest_reg, Arm64Gen::ARM64Reg dest_reg,
|
void ConvertDoubleToSingleLower(size_t guest_reg, Arm64Gen::ARM64Reg dest_reg,
|
||||||
Arm64Gen::ARM64Reg src_reg);
|
Arm64Gen::ARM64Reg src_reg);
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
using namespace Arm64Gen;
|
using namespace Arm64Gen;
|
||||||
|
|
||||||
void JitArm64::psq_l(UGeckoInstruction inst)
|
void JitArm64::psq_lXX(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
INSTRUCTION_START
|
INSTRUCTION_START
|
||||||
JITDISABLE(bJITLoadStorePairedOff);
|
JITDISABLE(bJITLoadStorePairedOff);
|
||||||
|
@ -39,7 +39,6 @@ void JitArm64::psq_l(UGeckoInstruction inst)
|
||||||
gpr.Lock(ARM64Reg::W0, ARM64Reg::W1, ARM64Reg::W2, ARM64Reg::W30);
|
gpr.Lock(ARM64Reg::W0, ARM64Reg::W1, ARM64Reg::W2, ARM64Reg::W30);
|
||||||
fpr.Lock(ARM64Reg::Q0, ARM64Reg::Q1);
|
fpr.Lock(ARM64Reg::Q0, ARM64Reg::Q1);
|
||||||
|
|
||||||
const ARM64Reg arm_addr = gpr.R(inst.RA);
|
|
||||||
constexpr ARM64Reg scale_reg = ARM64Reg::W0;
|
constexpr ARM64Reg scale_reg = ARM64Reg::W0;
|
||||||
constexpr ARM64Reg addr_reg = ARM64Reg::W1;
|
constexpr ARM64Reg addr_reg = ARM64Reg::W1;
|
||||||
constexpr ARM64Reg type_reg = ARM64Reg::W2;
|
constexpr ARM64Reg type_reg = ARM64Reg::W2;
|
||||||
|
@ -47,20 +46,25 @@ void JitArm64::psq_l(UGeckoInstruction inst)
|
||||||
|
|
||||||
if (inst.RA || update) // Always uses the register on update
|
if (inst.RA || update) // Always uses the register on update
|
||||||
{
|
{
|
||||||
if (offset >= 0)
|
if (indexed)
|
||||||
ADD(addr_reg, arm_addr, offset);
|
ADD(addr_reg, gpr.R(inst.RA), gpr.R(inst.RB));
|
||||||
|
else if (offset >= 0)
|
||||||
|
ADD(addr_reg, gpr.R(inst.RA), offset);
|
||||||
else
|
else
|
||||||
SUB(addr_reg, arm_addr, std::abs(offset));
|
SUB(addr_reg, gpr.R(inst.RA), std::abs(offset));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (indexed)
|
||||||
|
MOV(addr_reg, gpr.R(inst.RB));
|
||||||
|
else
|
||||||
MOVI2R(addr_reg, (u32)offset);
|
MOVI2R(addr_reg, (u32)offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (update)
|
if (update)
|
||||||
{
|
{
|
||||||
gpr.BindToRegister(inst.RA, true);
|
gpr.BindToRegister(inst.RA, false);
|
||||||
MOV(arm_addr, addr_reg);
|
MOV(gpr.R(inst.RA), addr_reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (js.assumeNoPairedQuantize)
|
if (js.assumeNoPairedQuantize)
|
||||||
|
@ -101,7 +105,7 @@ void JitArm64::psq_l(UGeckoInstruction inst)
|
||||||
fpr.Unlock(ARM64Reg::Q0, ARM64Reg::Q1);
|
fpr.Unlock(ARM64Reg::Q0, ARM64Reg::Q1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitArm64::psq_st(UGeckoInstruction inst)
|
void JitArm64::psq_stXX(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
INSTRUCTION_START
|
INSTRUCTION_START
|
||||||
JITDISABLE(bJITLoadStorePairedOff);
|
JITDISABLE(bJITLoadStorePairedOff);
|
||||||
|
@ -158,8 +162,6 @@ void JitArm64::psq_st(UGeckoInstruction inst)
|
||||||
|
|
||||||
gpr.Lock(ARM64Reg::W0, ARM64Reg::W1, ARM64Reg::W2, ARM64Reg::W30);
|
gpr.Lock(ARM64Reg::W0, ARM64Reg::W1, ARM64Reg::W2, ARM64Reg::W30);
|
||||||
|
|
||||||
const ARM64Reg arm_addr = gpr.R(inst.RA);
|
|
||||||
|
|
||||||
constexpr ARM64Reg scale_reg = ARM64Reg::W0;
|
constexpr ARM64Reg scale_reg = ARM64Reg::W0;
|
||||||
constexpr ARM64Reg addr_reg = ARM64Reg::W1;
|
constexpr ARM64Reg addr_reg = ARM64Reg::W1;
|
||||||
constexpr ARM64Reg type_reg = ARM64Reg::W2;
|
constexpr ARM64Reg type_reg = ARM64Reg::W2;
|
||||||
|
@ -173,20 +175,25 @@ void JitArm64::psq_st(UGeckoInstruction inst)
|
||||||
|
|
||||||
if (inst.RA || update) // Always uses the register on update
|
if (inst.RA || update) // Always uses the register on update
|
||||||
{
|
{
|
||||||
if (offset >= 0)
|
if (indexed)
|
||||||
|
ADD(addr_reg, gpr.R(inst.RA), gpr.R(inst.RB));
|
||||||
|
else if (offset >= 0)
|
||||||
ADD(addr_reg, gpr.R(inst.RA), offset);
|
ADD(addr_reg, gpr.R(inst.RA), offset);
|
||||||
else
|
else
|
||||||
SUB(addr_reg, gpr.R(inst.RA), std::abs(offset));
|
SUB(addr_reg, gpr.R(inst.RA), std::abs(offset));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (indexed)
|
||||||
|
MOV(addr_reg, gpr.R(inst.RB));
|
||||||
|
else
|
||||||
MOVI2R(addr_reg, (u32)offset);
|
MOVI2R(addr_reg, (u32)offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (update)
|
if (update)
|
||||||
{
|
{
|
||||||
gpr.BindToRegister(inst.RA, true);
|
gpr.BindToRegister(inst.RA, false);
|
||||||
MOV(arm_addr, addr_reg);
|
MOV(gpr.R(inst.RA), addr_reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (js.assumeNoPairedQuantize)
|
if (js.assumeNoPairedQuantize)
|
||||||
|
|
|
@ -78,12 +78,12 @@ constexpr std::array<GekkoOPTemplate, 54> primarytable{{
|
||||||
{54, &JitArm64::stfXX}, // stfd
|
{54, &JitArm64::stfXX}, // stfd
|
||||||
{55, &JitArm64::stfXX}, // stfdu
|
{55, &JitArm64::stfXX}, // stfdu
|
||||||
|
|
||||||
{56, &JitArm64::psq_l}, // psq_l
|
{56, &JitArm64::psq_lXX}, // psq_l
|
||||||
{57, &JitArm64::psq_l}, // psq_lu
|
{57, &JitArm64::psq_lXX}, // psq_lu
|
||||||
{60, &JitArm64::psq_st}, // psq_st
|
{60, &JitArm64::psq_stXX}, // psq_st
|
||||||
{61, &JitArm64::psq_st}, // psq_stu
|
{61, &JitArm64::psq_stXX}, // psq_stu
|
||||||
|
|
||||||
// missing: 0, 1, 2, 5, 6, 9, 22, 30, 62, 58
|
// missing: 0, 1, 2, 5, 6, 9, 22, 30, 58, 62
|
||||||
}};
|
}};
|
||||||
|
|
||||||
constexpr std::array<GekkoOPTemplate, 13> table4{{
|
constexpr std::array<GekkoOPTemplate, 13> table4{{
|
||||||
|
@ -125,10 +125,10 @@ constexpr std::array<GekkoOPTemplate, 17> table4_2{{
|
||||||
}};
|
}};
|
||||||
|
|
||||||
constexpr std::array<GekkoOPTemplate, 4> table4_3{{
|
constexpr std::array<GekkoOPTemplate, 4> table4_3{{
|
||||||
{6, &JitArm64::FallBackToInterpreter}, // psq_lx
|
{6, &JitArm64::psq_lXX}, // psq_lx
|
||||||
{7, &JitArm64::FallBackToInterpreter}, // psq_stx
|
{7, &JitArm64::psq_stXX}, // psq_stx
|
||||||
{38, &JitArm64::FallBackToInterpreter}, // psq_lux
|
{38, &JitArm64::psq_lXX}, // psq_lux
|
||||||
{39, &JitArm64::FallBackToInterpreter}, // psq_stux
|
{39, &JitArm64::psq_stXX}, // psq_stux
|
||||||
}};
|
}};
|
||||||
|
|
||||||
constexpr std::array<GekkoOPTemplate, 13> table19{{
|
constexpr std::array<GekkoOPTemplate, 13> table19{{
|
||||||
|
|
Loading…
Reference in New Issue