Merge pull request #1523 from FioraAeterna/fifo64

JIT: add 64-bit write support to FIFO functions and fix immediates
This commit is contained in:
skidau 2014-11-12 12:12:16 +11:00
commit 1095d3fc33
6 changed files with 34 additions and 22 deletions

View File

@ -207,18 +207,18 @@ void XEmitter::MOVTwo(int bits, Gen::X64Reg dst1, Gen::X64Reg src1, Gen::X64Reg
} }
} }
void XEmitter::ABI_CallFunctionAC(const void *func, const Gen::OpArg &arg1, u32 param2) void XEmitter::ABI_CallFunctionAC(int bits, const void *func, const Gen::OpArg &arg1, u32 param2)
{ {
if (!arg1.IsSimpleReg(ABI_PARAM1)) if (!arg1.IsSimpleReg(ABI_PARAM1))
MOV(32, R(ABI_PARAM1), arg1); MOV(bits, R(ABI_PARAM1), arg1);
MOV(32, R(ABI_PARAM2), Imm32(param2)); MOV(32, R(ABI_PARAM2), Imm32(param2));
ABI_CallFunction(func); ABI_CallFunction(func);
} }
void XEmitter::ABI_CallFunctionA(const void *func, const Gen::OpArg &arg1) void XEmitter::ABI_CallFunctionA(int bits, const void *func, const Gen::OpArg &arg1)
{ {
if (!arg1.IsSimpleReg(ABI_PARAM1)) if (!arg1.IsSimpleReg(ABI_PARAM1))
MOV(32, R(ABI_PARAM1), arg1); MOV(bits, R(ABI_PARAM1), arg1);
ABI_CallFunction(func); ABI_CallFunction(func);
} }

View File

@ -1184,7 +1184,7 @@ void OpArg::WriteNormalOp(XEmitter *emit, bool toRM, NormalOp op, const OpArg &o
} }
else else
{ {
_assert_msg_(DYNA_REC, 0, "WriteNormalOp - Unhandled case"); _assert_msg_(DYNA_REC, 0, "WriteNormalOp - Unhandled case %d %d", operand.scale, bits);
} }
_operandReg = (X64Reg)normalops[op].ext; //pass extension in REG of ModRM _operandReg = (X64Reg)normalops[op].ext; //pass extension in REG of ModRM
} }

View File

@ -871,8 +871,8 @@ public:
void ABI_CallFunctionCCCP(const void *func, u32 param1, u32 param2,u32 param3, void *param4); void ABI_CallFunctionCCCP(const void *func, u32 param1, u32 param2,u32 param3, void *param4);
void ABI_CallFunctionPC(const void *func, void *param1, u32 param2); void ABI_CallFunctionPC(const void *func, void *param1, u32 param2);
void ABI_CallFunctionPPC(const void *func, void *param1, void *param2, u32 param3); void ABI_CallFunctionPPC(const void *func, void *param1, void *param2, u32 param3);
void ABI_CallFunctionAC(const void *func, const OpArg &arg1, u32 param2); void ABI_CallFunctionAC(int bits, const void *func, const OpArg &arg1, u32 param2);
void ABI_CallFunctionA(const void *func, const OpArg &arg1); void ABI_CallFunctionA(int bits, const void *func, const OpArg &arg1);
// Pass a register as a parameter. // Pass a register as a parameter.
void ABI_CallFunctionR(const void *func, X64Reg reg1); void ABI_CallFunctionR(const void *func, X64Reg reg1);

View File

@ -130,7 +130,7 @@ void Jit64AsmRoutineManager::Generate()
//Ok, no block, let's jit //Ok, no block, let's jit
ABI_PushRegistersAndAdjustStack({}, 0); ABI_PushRegistersAndAdjustStack({}, 0);
ABI_CallFunctionA((void *)&Jit, PPCSTATE(pc)); ABI_CallFunctionA(32, (void *)&Jit, PPCSTATE(pc));
ABI_PopRegistersAndAdjustStack({}, 0); ABI_PopRegistersAndAdjustStack({}, 0);
// Jit might have cleared the code cache // Jit might have cleared the code cache
@ -186,6 +186,8 @@ void Jit64AsmRoutineManager::GenerateCommon()
GenFifoWrite(16); GenFifoWrite(16);
fifoDirectWrite32 = AlignCode4(); fifoDirectWrite32 = AlignCode4();
GenFifoWrite(32); GenFifoWrite(32);
fifoDirectWrite64 = AlignCode4();
GenFifoWrite(64);
frsqrte = AlignCode4(); frsqrte = AlignCode4();
GenFrsqrte(); GenFrsqrte();
fres = AlignCode4(); fres = AlignCode4();

View File

@ -13,6 +13,7 @@ public:
const u8 *fifoDirectWrite8; const u8 *fifoDirectWrite8;
const u8 *fifoDirectWrite16; const u8 *fifoDirectWrite16;
const u8 *fifoDirectWrite32; const u8 *fifoDirectWrite32;
const u8 *fifoDirectWrite64;
const u8 *enterCode; const u8 *enterCode;
@ -55,8 +56,6 @@ protected:
public: public:
void GenFifoWrite(int size); void GenFifoWrite(int size);
void GenFifoXmm64Write();
void GenFifoFloatWrite();
void GenFrsqrte(); void GenFrsqrte();
void GenFres(); void GenFres();
}; };

View File

@ -464,6 +464,17 @@ u8 *EmuCodeBlock::UnsafeWriteRegToReg(OpArg reg_value, X64Reg reg_addr, int acce
return result; return result;
} }
static OpArg FixImmediate(int accessSize, OpArg arg)
{
if (arg.IsImm())
{
arg = accessSize == 8 ? Imm8((u8)arg.offset) :
accessSize == 16 ? Imm16((u16)arg.offset) :
Imm32((u32)arg.offset);
}
return arg;
}
void EmuCodeBlock::UnsafeWriteGatherPipe(int accessSize) void EmuCodeBlock::UnsafeWriteGatherPipe(int accessSize)
{ {
// No need to protect these, they don't touch any state // No need to protect these, they don't touch any state
@ -479,18 +490,23 @@ void EmuCodeBlock::UnsafeWriteGatherPipe(int accessSize)
case 32: case 32:
CALL((void *)jit->GetAsmRoutines()->fifoDirectWrite32); CALL((void *)jit->GetAsmRoutines()->fifoDirectWrite32);
break; break;
case 64:
CALL((void *)jit->GetAsmRoutines()->fifoDirectWrite64);
break;
} }
jit->js.fifoBytesThisBlock += accessSize >> 3; jit->js.fifoBytesThisBlock += accessSize >> 3;
} }
bool EmuCodeBlock::WriteToConstAddress(int accessSize, OpArg arg, u32 address, BitSet32 registersInUse) bool EmuCodeBlock::WriteToConstAddress(int accessSize, OpArg arg, u32 address, BitSet32 registersInUse)
{ {
arg = FixImmediate(accessSize, arg);
// If we already know the address through constant folding, we can do some // If we already know the address through constant folding, we can do some
// fun tricks... // fun tricks...
if ((address & 0xFFFFF000) == 0xCC008000 && jit->jo.optimizeGatherPipe && accessSize <= 32) if ((address & 0xFFFFF000) == 0xCC008000 && jit->jo.optimizeGatherPipe)
{ {
if (!arg.IsSimpleReg() || arg.GetSimpleReg() != RSCRATCH) if (!arg.IsSimpleReg() || arg.GetSimpleReg() != RSCRATCH)
MOV(32, R(RSCRATCH), arg); MOV(accessSize, R(RSCRATCH), arg);
UnsafeWriteGatherPipe(accessSize); UnsafeWriteGatherPipe(accessSize);
return false; return false;
@ -509,16 +525,16 @@ bool EmuCodeBlock::WriteToConstAddress(int accessSize, OpArg arg, u32 address, B
switch (accessSize) switch (accessSize)
{ {
case 64: case 64:
ABI_CallFunctionAC((void *)&Memory::Write_U64, arg, address); ABI_CallFunctionAC(64, (void *)&Memory::Write_U64, arg, address);
break; break;
case 32: case 32:
ABI_CallFunctionAC((void *)&Memory::Write_U32, arg, address); ABI_CallFunctionAC(32, (void *)&Memory::Write_U32, arg, address);
break; break;
case 16: case 16:
ABI_CallFunctionAC((void *)&Memory::Write_U16, arg, address); ABI_CallFunctionAC(16, (void *)&Memory::Write_U16, arg, address);
break; break;
case 8: case 8:
ABI_CallFunctionAC((void *)&Memory::Write_U8, arg, address); ABI_CallFunctionAC(8, (void *)&Memory::Write_U8, arg, address);
break; break;
} }
ABI_PopRegistersAndAdjustStack(registersInUse, 0); ABI_PopRegistersAndAdjustStack(registersInUse, 0);
@ -529,12 +545,7 @@ bool EmuCodeBlock::WriteToConstAddress(int accessSize, OpArg arg, u32 address, B
void EmuCodeBlock::SafeWriteRegToReg(OpArg reg_value, X64Reg reg_addr, int accessSize, s32 offset, BitSet32 registersInUse, int flags) void EmuCodeBlock::SafeWriteRegToReg(OpArg reg_value, X64Reg reg_addr, int accessSize, s32 offset, BitSet32 registersInUse, int flags)
{ {
// set the correct immediate format // set the correct immediate format
if (reg_value.IsImm()) reg_value = FixImmediate(accessSize, reg_value);
{
reg_value = accessSize == 32 ? Imm32((u32)reg_value.offset) :
accessSize == 16 ? Imm16((u16)reg_value.offset) :
Imm8((u8)reg_value.offset);
}
// TODO: support byte-swapped non-immediate fastmem stores // TODO: support byte-swapped non-immediate fastmem stores
if (!SConfig::GetInstance().m_LocalCoreStartupParameter.bMMU && if (!SConfig::GetInstance().m_LocalCoreStartupParameter.bMMU &&