diff --git a/Source/Core/Common/x64ABI.cpp b/Source/Core/Common/x64ABI.cpp index 2815ab8495..44818ceb67 100644 --- a/Source/Core/Common/x64ABI.cpp +++ b/Source/Core/Common/x64ABI.cpp @@ -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)) - MOV(32, R(ABI_PARAM1), arg1); + MOV(bits, R(ABI_PARAM1), arg1); MOV(32, R(ABI_PARAM2), Imm32(param2)); 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)) - MOV(32, R(ABI_PARAM1), arg1); + MOV(bits, R(ABI_PARAM1), arg1); ABI_CallFunction(func); } diff --git a/Source/Core/Common/x64Emitter.cpp b/Source/Core/Common/x64Emitter.cpp index 3716d922aa..cbdae83c91 100644 --- a/Source/Core/Common/x64Emitter.cpp +++ b/Source/Core/Common/x64Emitter.cpp @@ -1184,7 +1184,7 @@ void OpArg::WriteNormalOp(XEmitter *emit, bool toRM, NormalOp op, const OpArg &o } 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 } diff --git a/Source/Core/Common/x64Emitter.h b/Source/Core/Common/x64Emitter.h index 7f98497456..9df47e10eb 100644 --- a/Source/Core/Common/x64Emitter.h +++ b/Source/Core/Common/x64Emitter.h @@ -871,8 +871,8 @@ public: 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_CallFunctionPPC(const void *func, void *param1, void *param2, u32 param3); - void ABI_CallFunctionAC(const void *func, const OpArg &arg1, u32 param2); - void ABI_CallFunctionA(const void *func, const OpArg &arg1); + void ABI_CallFunctionAC(int bits, const void *func, const OpArg &arg1, u32 param2); + void ABI_CallFunctionA(int bits, const void *func, const OpArg &arg1); // Pass a register as a parameter. void ABI_CallFunctionR(const void *func, X64Reg reg1); diff --git a/Source/Core/Core/PowerPC/Jit64/JitAsm.cpp b/Source/Core/Core/PowerPC/Jit64/JitAsm.cpp index ae1d149e56..38c1d52ab8 100644 --- a/Source/Core/Core/PowerPC/Jit64/JitAsm.cpp +++ b/Source/Core/Core/PowerPC/Jit64/JitAsm.cpp @@ -130,7 +130,7 @@ void Jit64AsmRoutineManager::Generate() //Ok, no block, let's jit ABI_PushRegistersAndAdjustStack({}, 0); - ABI_CallFunctionA((void *)&Jit, PPCSTATE(pc)); + ABI_CallFunctionA(32, (void *)&Jit, PPCSTATE(pc)); ABI_PopRegistersAndAdjustStack({}, 0); // Jit might have cleared the code cache @@ -186,6 +186,8 @@ void Jit64AsmRoutineManager::GenerateCommon() GenFifoWrite(16); fifoDirectWrite32 = AlignCode4(); GenFifoWrite(32); + fifoDirectWrite64 = AlignCode4(); + GenFifoWrite(64); frsqrte = AlignCode4(); GenFrsqrte(); fres = AlignCode4(); diff --git a/Source/Core/Core/PowerPC/JitCommon/JitAsmCommon.h b/Source/Core/Core/PowerPC/JitCommon/JitAsmCommon.h index f38df7f266..847d318230 100644 --- a/Source/Core/Core/PowerPC/JitCommon/JitAsmCommon.h +++ b/Source/Core/Core/PowerPC/JitCommon/JitAsmCommon.h @@ -13,6 +13,7 @@ public: const u8 *fifoDirectWrite8; const u8 *fifoDirectWrite16; const u8 *fifoDirectWrite32; + const u8 *fifoDirectWrite64; const u8 *enterCode; @@ -55,8 +56,6 @@ protected: public: void GenFifoWrite(int size); - void GenFifoXmm64Write(); - void GenFifoFloatWrite(); void GenFrsqrte(); void GenFres(); }; diff --git a/Source/Core/Core/PowerPC/JitCommon/Jit_Util.cpp b/Source/Core/Core/PowerPC/JitCommon/Jit_Util.cpp index 6066e334d2..fe6d6b2f2c 100644 --- a/Source/Core/Core/PowerPC/JitCommon/Jit_Util.cpp +++ b/Source/Core/Core/PowerPC/JitCommon/Jit_Util.cpp @@ -464,6 +464,17 @@ u8 *EmuCodeBlock::UnsafeWriteRegToReg(OpArg reg_value, X64Reg reg_addr, int acce 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) { // No need to protect these, they don't touch any state @@ -479,18 +490,23 @@ void EmuCodeBlock::UnsafeWriteGatherPipe(int accessSize) case 32: CALL((void *)jit->GetAsmRoutines()->fifoDirectWrite32); break; + case 64: + CALL((void *)jit->GetAsmRoutines()->fifoDirectWrite64); + break; } jit->js.fifoBytesThisBlock += accessSize >> 3; } 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 // fun tricks... - if ((address & 0xFFFFF000) == 0xCC008000 && jit->jo.optimizeGatherPipe && accessSize <= 32) + if ((address & 0xFFFFF000) == 0xCC008000 && jit->jo.optimizeGatherPipe) { if (!arg.IsSimpleReg() || arg.GetSimpleReg() != RSCRATCH) - MOV(32, R(RSCRATCH), arg); + MOV(accessSize, R(RSCRATCH), arg); UnsafeWriteGatherPipe(accessSize); return false; @@ -509,16 +525,16 @@ bool EmuCodeBlock::WriteToConstAddress(int accessSize, OpArg arg, u32 address, B switch (accessSize) { case 64: - ABI_CallFunctionAC((void *)&Memory::Write_U64, arg, address); + ABI_CallFunctionAC(64, (void *)&Memory::Write_U64, arg, address); break; case 32: - ABI_CallFunctionAC((void *)&Memory::Write_U32, arg, address); + ABI_CallFunctionAC(32, (void *)&Memory::Write_U32, arg, address); break; case 16: - ABI_CallFunctionAC((void *)&Memory::Write_U16, arg, address); + ABI_CallFunctionAC(16, (void *)&Memory::Write_U16, arg, address); break; case 8: - ABI_CallFunctionAC((void *)&Memory::Write_U8, arg, address); + ABI_CallFunctionAC(8, (void *)&Memory::Write_U8, arg, address); break; } 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) { // set the correct immediate format - if (reg_value.IsImm()) - { - reg_value = accessSize == 32 ? Imm32((u32)reg_value.offset) : - accessSize == 16 ? Imm16((u16)reg_value.offset) : - Imm8((u8)reg_value.offset); - } + reg_value = FixImmediate(accessSize, reg_value); // TODO: support byte-swapped non-immediate fastmem stores if (!SConfig::GetInstance().m_LocalCoreStartupParameter.bMMU &&