summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorFiora <fioraaeterna@gmail.com>2014-11-09 16:21:11 -0800
committerFiora <fioraaeterna@gmail.com>2014-11-09 21:24:30 -0800
commit6603f98d044ccab8889eb3428353911aaa910ee7 (patch)
treeea54e5cb6faa3540ff172b7b02ce7ba3d0664955 /Source
parentc34c231df1e0855c277af5e66a13506f4fb75ed0 (diff)
JIT: add 64-bit write support to FIFO functions
Also fix 64-bit values passed to CallAC and otherwise correct immediate handling in FIFO writes. Fixes 007 Nightfire.
Diffstat (limited to 'Source')
-rw-r--r--Source/Core/Common/x64ABI.cpp8
-rw-r--r--Source/Core/Common/x64Emitter.cpp2
-rw-r--r--Source/Core/Common/x64Emitter.h4
-rw-r--r--Source/Core/Core/PowerPC/Jit64/JitAsm.cpp4
-rw-r--r--Source/Core/Core/PowerPC/JitCommon/JitAsmCommon.h3
-rw-r--r--Source/Core/Core/PowerPC/JitCommon/Jit_Util.cpp35
6 files changed, 34 insertions, 22 deletions
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 &&