Merge pull request #1523 from FioraAeterna/fifo64
JIT: add 64-bit write support to FIFO functions and fix immediates
This commit is contained in:
commit
1095d3fc33
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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();
|
||||||
};
|
};
|
||||||
|
|
|
@ -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 &&
|
||||||
|
|
Loading…
Reference in New Issue