Minor optimization, sketch on an lvl.q jit implementation

This commit is contained in:
Henrik Rydgard 2013-08-11 15:31:54 +02:00
parent 9109882c04
commit fecd9d5f78
5 changed files with 124 additions and 44 deletions

View File

@ -592,12 +592,22 @@ namespace MIPSComp
fpr.ReleaseSpillLocksAndDiscardTemps();
}
void Jit::Comp_Vhoriz(u32 op) {
DISABLE;
switch ((op >> 16) & 31) {
case 6: // vfad
break;
case 7: // vavg
break;
}
}
void Jit::Comp_VHdp(u32 op) {
// Similar to vdot
DISABLE;
}
void Jit::Comp_VecDo3(u32 op) {
CONDITIONAL_DISABLE;
@ -1535,10 +1545,6 @@ namespace MIPSComp
fpr.ReleaseSpillLocksAndDiscardTemps();
}
void Jit::Comp_Vhoriz(u32 op) {
DISABLE;
}
static float sincostemp[2];
void SinCos(float angle) {

View File

@ -215,31 +215,29 @@ namespace MIPSInt
switch (op >> 26)
{
case 53: //lvl.q/lvr.q
if (addr & 0x3)
{
_dbg_assert_msg_(CPU, 0, "Misaligned lvX.q");
}
if ((op&2) == 0)
{
// It's an LVL
float d[4];
ReadVector(d, V_Quad, vt);
int offset = (addr >> 2) & 3;
for (int i = 0; i < offset + 1; i++)
if (addr & 0x3)
{
d[3 - i] = Memory::Read_Float(addr - i * 4);
_dbg_assert_msg_(CPU, 0, "Misaligned lvX.q");
}
WriteVector(d, V_Quad, vt);
}
else
{
// It's an LVR
float d[4];
ReadVector(d, V_Quad, vt);
int offset = (addr >> 2) & 3;
for (int i = 0; i < (3 - offset) + 1; i++)
if ((op & 2) == 0)
{
d[i] = Memory::Read_Float(addr + 4 * i);
// It's an LVL
for (int i = 0; i < offset + 1; i++)
{
d[3 - i] = Memory::Read_Float(addr - 4 * i);
}
}
else
{
// It's an LVR
for (int i = 0; i < (3 - offset) + 1; i++)
{
d[i] = Memory::Read_Float(addr + 4 * i);
}
}
WriteVector(d, V_Quad, vt);
}
@ -254,33 +252,32 @@ namespace MIPSInt
break;
case 61: // svl.q/svr.q
if (addr & 0x3)
{
_dbg_assert_msg_(CPU, 0, "Misaligned svX.q");
}
if ((op&2) == 0)
{
// It's an SVL
if (addr & 0x3)
{
_dbg_assert_msg_(CPU, 0, "Misaligned svX.q");
}
float d[4];
ReadVector(d, V_Quad, vt);
int offset = (addr >> 2) & 3;
for (int i = 0; i < offset + 1; i++)
if ((op&2) == 0)
{
Memory::Write_Float(d[3 - i], addr - i * 4);
// It's an SVL
for (int i = 0; i < offset + 1; i++)
{
Memory::Write_Float(d[3 - i], addr - i * 4);
}
}
}
else
{
// It's an SVR
float d[4];
ReadVector(d, V_Quad, vt);
int offset = (addr >> 2) & 3;
for (int i = 0; i < (3 - offset) + 1; i++)
else
{
Memory::Write_Float(d[i], addr + 4 * i);
// It's an SVR
for (int i = 0; i < (3 - offset) + 1; i++)
{
Memory::Write_Float(d[i], addr + 4 * i);
}
}
break;
}
break;
case 62: //sv.q
if (addr & 0xF)

View File

@ -162,7 +162,7 @@ const MIPSInstruction tableImmediate[64] = //xxxxxx .....
{VFPU6},
INSTR("sv", &Jit::Comp_SVQ, Dis_SVLRQ, Int_SVQ, IS_VFPU|VFPU_NO_PREFIX), //copU
INSTR("sv.q", &Jit::Comp_SVQ, Dis_SVQ, Int_SVQ, IS_VFPU|VFPU_NO_PREFIX),
INSTR("vflush", &Jit::Comp_Generic, Dis_Vflush, Int_Vflush, IS_VFPU|VFPU_NO_PREFIX),
INSTR("vflush", &Jit::Comp_DoNothing, Dis_Vflush, Int_Vflush, IS_VFPU|VFPU_NO_PREFIX),
};
const MIPSInstruction tableSpecial[64] = /// 000000 ...... ...... .......... xxxxxx

View File

@ -272,6 +272,73 @@ void Jit::Comp_SVQ(u32 op)
switch (op >> 26)
{
case 53: //lvl.q/lvr.q
{
if (!g_Config.bFastMemory) {
DISABLE;
}
DISABLE;
gpr.BindToRegister(rs, true, true);
gpr.FlushLockX(ECX);
u8 vregs[4];
GetVectorRegs(vregs, V_Quad, vt);
MOV(32, R(EAX), gpr.R(rs));
ADD(32, R(EAX), Imm32(imm));
#ifdef _M_IX86
AND(32, R(EAX), Imm32(Memory::MEMVIEW32_MASK));
#endif
MOV(32, R(ECX), R(EAX));
SHR(32, R(EAX), Imm8(2));
AND(32, R(EAX), Imm32(0x3));
CMP(32, R(EAX), Imm32(0));
FixupBranch next = J_CC(CC_NE);
fpr.MapRegsV(vregs, V_Quad, MAP_DIRTY);
// Offset = 0
MOVSS(fpr.RX(vregs[3]), MRegSum(RBX, RAX));
FixupBranch skip0 = J();
SetJumpTarget(next);
CMP(32, R(EAX), Imm32(1));
next = J_CC(CC_NE);
// Offset = 1
MOVSS(fpr.RX(vregs[3]), MComplex(RBX, RAX, 1, 4));
MOVSS(fpr.RX(vregs[2]), MComplex(RBX, RAX, 1, 0));
FixupBranch skip1 = J();
SetJumpTarget(next);
CMP(32, R(EAX), Imm32(2));
next = J_CC(CC_NE);
// Offset = 2
MOVSS(fpr.RX(vregs[3]), MComplex(RBX, RAX, 1, 8));
MOVSS(fpr.RX(vregs[2]), MComplex(RBX, RAX, 1, 4));
MOVSS(fpr.RX(vregs[1]), MComplex(RBX, RAX, 1, 0));
FixupBranch skip2 = J();
SetJumpTarget(next);
CMP(32, R(EAX), Imm32(3));
next = J_CC(CC_NE);
// Offset = 3
MOVSS(fpr.RX(vregs[3]), MComplex(RBX, RAX, 1, 12));
MOVSS(fpr.RX(vregs[2]), MComplex(RBX, RAX, 1, 8));
MOVSS(fpr.RX(vregs[1]), MComplex(RBX, RAX, 1, 4));
MOVSS(fpr.RX(vregs[0]), MComplex(RBX, RAX, 1, 0));
SetJumpTarget(next);
SetJumpTarget(skip0);
SetJumpTarget(skip1);
SetJumpTarget(skip2);
gpr.UnlockAll();
fpr.ReleaseSpillLocks();
}
break;
case 54: //lv.q
{
gpr.BindToRegister(rs, true, true);
@ -337,6 +404,8 @@ void Jit::Comp_SVQ(u32 op)
}
break;
default:
DISABLE;
break;

View File

@ -222,12 +222,20 @@ void Memset(const u32 _Address, const u8 _Data, const u32 _iLength);
inline void Memcpy(const u32 to_address, const void *from_data, const u32 len)
{
memcpy(GetPointer(to_address), from_data, len);
u8 *to = GetPointer(to_address);
if (to) {
memcpy(to, from_data, len);
}
// if not, GetPointer will log.
}
inline void Memcpy(void *to_data, const u32 from_address, const u32 len)
{
memcpy(to_data, GetPointer(from_address), len);
const u8 *from = GetPointer(from_address);
if (from) {
memcpy(to_data, from, len);
}
// if not, GetPointer will log.
}
inline void MemcpyUnchecked(void *to_data, const u32 from_address, const u32 len)