mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
x86jit: Use templates to avoid some void * casts.
Makes it a bit cleaner and potentially safer.
This commit is contained in:
parent
da97a67526
commit
2347498667
14 changed files with 328 additions and 247 deletions
|
@ -59,20 +59,20 @@ void XEmitter::ABI_EmitEpilogue(int maxCallParams)
|
|||
#ifdef _M_IX86 // All32
|
||||
|
||||
// Shared code between Win32 and Unix32
|
||||
void XEmitter::ABI_CallFunction(void *func) {
|
||||
void XEmitter::ABI_CallFunction(const void *func) {
|
||||
ABI_AlignStack(0);
|
||||
CALL(func);
|
||||
ABI_RestoreStack(0);
|
||||
}
|
||||
|
||||
void XEmitter::ABI_CallFunctionC16(void *func, u16 param1) {
|
||||
void XEmitter::ABI_CallFunctionC16(const void *func, u16 param1) {
|
||||
ABI_AlignStack(1 * 2);
|
||||
PUSH(16, Imm16(param1));
|
||||
CALL(func);
|
||||
ABI_RestoreStack(1 * 2);
|
||||
}
|
||||
|
||||
void XEmitter::ABI_CallFunctionCC16(void *func, u32 param1, u16 param2) {
|
||||
void XEmitter::ABI_CallFunctionCC16(const void *func, u32 param1, u16 param2) {
|
||||
ABI_AlignStack(1 * 2 + 1 * 4);
|
||||
PUSH(16, Imm16(param2));
|
||||
PUSH(32, Imm32(param1));
|
||||
|
@ -80,14 +80,14 @@ void XEmitter::ABI_CallFunctionCC16(void *func, u32 param1, u16 param2) {
|
|||
ABI_RestoreStack(1 * 2 + 1 * 4);
|
||||
}
|
||||
|
||||
void XEmitter::ABI_CallFunctionC(void *func, u32 param1) {
|
||||
void XEmitter::ABI_CallFunctionC(const void *func, u32 param1) {
|
||||
ABI_AlignStack(1 * 4);
|
||||
PUSH(32, Imm32(param1));
|
||||
CALL(func);
|
||||
ABI_RestoreStack(1 * 4);
|
||||
}
|
||||
|
||||
void XEmitter::ABI_CallFunctionCC(void *func, u32 param1, u32 param2) {
|
||||
void XEmitter::ABI_CallFunctionCC(const void *func, u32 param1, u32 param2) {
|
||||
ABI_AlignStack(2 * 4);
|
||||
PUSH(32, Imm32(param2));
|
||||
PUSH(32, Imm32(param1));
|
||||
|
@ -95,7 +95,7 @@ void XEmitter::ABI_CallFunctionCC(void *func, u32 param1, u32 param2) {
|
|||
ABI_RestoreStack(2 * 4);
|
||||
}
|
||||
|
||||
void XEmitter::ABI_CallFunctionCCC(void *func, u32 param1, u32 param2, u32 param3) {
|
||||
void XEmitter::ABI_CallFunctionCCC(const void *func, u32 param1, u32 param2, u32 param3) {
|
||||
ABI_AlignStack(3 * 4);
|
||||
PUSH(32, Imm32(param3));
|
||||
PUSH(32, Imm32(param2));
|
||||
|
@ -104,7 +104,7 @@ void XEmitter::ABI_CallFunctionCCC(void *func, u32 param1, u32 param2, u32 param
|
|||
ABI_RestoreStack(3 * 4);
|
||||
}
|
||||
|
||||
void XEmitter::ABI_CallFunctionCCP(void *func, u32 param1, u32 param2, void *param3) {
|
||||
void XEmitter::ABI_CallFunctionCCP(const void *func, u32 param1, u32 param2, void *param3) {
|
||||
ABI_AlignStack(3 * 4);
|
||||
PUSH(32, Imm32((u32)param3));
|
||||
PUSH(32, Imm32(param2));
|
||||
|
@ -113,7 +113,7 @@ void XEmitter::ABI_CallFunctionCCP(void *func, u32 param1, u32 param2, void *par
|
|||
ABI_RestoreStack(3 * 4);
|
||||
}
|
||||
|
||||
void XEmitter::ABI_CallFunctionCCCP(void *func, u32 param1, u32 param2,u32 param3, void *param4) {
|
||||
void XEmitter::ABI_CallFunctionCCCP(const void *func, u32 param1, u32 param2,u32 param3, void *param4) {
|
||||
ABI_AlignStack(4 * 4);
|
||||
PUSH(32, Imm32((u32)param4));
|
||||
PUSH(32, Imm32(param3));
|
||||
|
@ -123,14 +123,14 @@ void XEmitter::ABI_CallFunctionCCCP(void *func, u32 param1, u32 param2,u32 param
|
|||
ABI_RestoreStack(4 * 4);
|
||||
}
|
||||
|
||||
void XEmitter::ABI_CallFunctionP(void *func, void *param1) {
|
||||
void XEmitter::ABI_CallFunctionP(const void *func, void *param1) {
|
||||
ABI_AlignStack(1 * 4);
|
||||
PUSH(32, Imm32((u32)param1));
|
||||
CALL(func);
|
||||
ABI_RestoreStack(1 * 4);
|
||||
}
|
||||
|
||||
void XEmitter::ABI_CallFunctionPPC(void *func, void *param1, void *param2, u32 param3) {
|
||||
void XEmitter::ABI_CallFunctionPPC(const void *func, void *param1, void *param2, u32 param3) {
|
||||
ABI_AlignStack(3 * 4);
|
||||
PUSH(32, Imm32(param3));
|
||||
PUSH(32, Imm32((u32)param2));
|
||||
|
@ -140,7 +140,7 @@ void XEmitter::ABI_CallFunctionPPC(void *func, void *param1, void *param2, u32 p
|
|||
}
|
||||
|
||||
// Pass a register as a parameter.
|
||||
void XEmitter::ABI_CallFunctionR(void *func, X64Reg reg1) {
|
||||
void XEmitter::ABI_CallFunctionR(const void *func, X64Reg reg1) {
|
||||
ABI_AlignStack(1 * 4);
|
||||
PUSH(32, R(reg1));
|
||||
CALL(func);
|
||||
|
@ -148,7 +148,7 @@ void XEmitter::ABI_CallFunctionR(void *func, X64Reg reg1) {
|
|||
}
|
||||
|
||||
// Pass two registers as parameters.
|
||||
void XEmitter::ABI_CallFunctionRR(void *func, Gen::X64Reg reg1, Gen::X64Reg reg2)
|
||||
void XEmitter::ABI_CallFunctionRR(const void *func, Gen::X64Reg reg1, Gen::X64Reg reg2)
|
||||
{
|
||||
ABI_AlignStack(2 * 4);
|
||||
PUSH(32, R(reg2));
|
||||
|
@ -157,7 +157,7 @@ void XEmitter::ABI_CallFunctionRR(void *func, Gen::X64Reg reg1, Gen::X64Reg reg2
|
|||
ABI_RestoreStack(2 * 4);
|
||||
}
|
||||
|
||||
void XEmitter::ABI_CallFunctionAC(void *func, const Gen::OpArg &arg1, u32 param2)
|
||||
void XEmitter::ABI_CallFunctionAC(const void *func, const Gen::OpArg &arg1, u32 param2)
|
||||
{
|
||||
ABI_AlignStack(2 * 4);
|
||||
PUSH(32, Imm32(param2));
|
||||
|
@ -166,7 +166,7 @@ void XEmitter::ABI_CallFunctionAC(void *func, const Gen::OpArg &arg1, u32 param2
|
|||
ABI_RestoreStack(2 * 4);
|
||||
}
|
||||
|
||||
void XEmitter::ABI_CallFunctionACC(void *func, const Gen::OpArg &arg1, u32 param2, u32 param3)
|
||||
void XEmitter::ABI_CallFunctionACC(const void *func, const Gen::OpArg &arg1, u32 param2, u32 param3)
|
||||
{
|
||||
ABI_AlignStack(3 * 4);
|
||||
PUSH(32, Imm32(param3));
|
||||
|
@ -176,7 +176,7 @@ void XEmitter::ABI_CallFunctionACC(void *func, const Gen::OpArg &arg1, u32 param
|
|||
ABI_RestoreStack(3 * 4);
|
||||
}
|
||||
|
||||
void XEmitter::ABI_CallFunctionA(void *func, const Gen::OpArg &arg1)
|
||||
void XEmitter::ABI_CallFunctionA(const void *func, const Gen::OpArg &arg1)
|
||||
{
|
||||
ABI_AlignStack(1 * 4);
|
||||
PUSH(32, arg1);
|
||||
|
@ -184,7 +184,7 @@ void XEmitter::ABI_CallFunctionA(void *func, const Gen::OpArg &arg1)
|
|||
ABI_RestoreStack(1 * 4);
|
||||
}
|
||||
|
||||
void XEmitter::ABI_CallFunctionAA(void *func, const Gen::OpArg &arg1, const Gen::OpArg &arg2)
|
||||
void XEmitter::ABI_CallFunctionAA(const void *func, const Gen::OpArg &arg1, const Gen::OpArg &arg2)
|
||||
{
|
||||
ABI_AlignStack(2 * 4);
|
||||
PUSH(32, arg2);
|
||||
|
@ -247,7 +247,7 @@ void XEmitter::ABI_RestoreStack(unsigned int frameSize) {
|
|||
#else //64bit
|
||||
|
||||
// Common functions
|
||||
void XEmitter::ABI_CallFunction(void *func) {
|
||||
void XEmitter::ABI_CallFunction(const void *func) {
|
||||
u64 distance = u64(func) - (u64(code) + 5);
|
||||
if (distance >= 0x0000000080000000ULL
|
||||
&& distance < 0xFFFFFFFF80000000ULL) {
|
||||
|
@ -259,7 +259,7 @@ void XEmitter::ABI_CallFunction(void *func) {
|
|||
}
|
||||
}
|
||||
|
||||
void XEmitter::ABI_CallFunctionC16(void *func, u16 param1) {
|
||||
void XEmitter::ABI_CallFunctionC16(const void *func, u16 param1) {
|
||||
MOV(32, R(ABI_PARAM1), Imm32((u32)param1));
|
||||
u64 distance = u64(func) - (u64(code) + 5);
|
||||
if (distance >= 0x0000000080000000ULL
|
||||
|
@ -272,7 +272,7 @@ void XEmitter::ABI_CallFunctionC16(void *func, u16 param1) {
|
|||
}
|
||||
}
|
||||
|
||||
void XEmitter::ABI_CallFunctionCC16(void *func, u32 param1, u16 param2) {
|
||||
void XEmitter::ABI_CallFunctionCC16(const void *func, u32 param1, u16 param2) {
|
||||
MOV(32, R(ABI_PARAM1), Imm32(param1));
|
||||
MOV(32, R(ABI_PARAM2), Imm32((u32)param2));
|
||||
u64 distance = u64(func) - (u64(code) + 5);
|
||||
|
@ -286,7 +286,7 @@ void XEmitter::ABI_CallFunctionCC16(void *func, u32 param1, u16 param2) {
|
|||
}
|
||||
}
|
||||
|
||||
void XEmitter::ABI_CallFunctionC(void *func, u32 param1) {
|
||||
void XEmitter::ABI_CallFunctionC(const void *func, u32 param1) {
|
||||
MOV(32, R(ABI_PARAM1), Imm32(param1));
|
||||
u64 distance = u64(func) - (u64(code) + 5);
|
||||
if (distance >= 0x0000000080000000ULL
|
||||
|
@ -299,7 +299,7 @@ void XEmitter::ABI_CallFunctionC(void *func, u32 param1) {
|
|||
}
|
||||
}
|
||||
|
||||
void XEmitter::ABI_CallFunctionCC(void *func, u32 param1, u32 param2) {
|
||||
void XEmitter::ABI_CallFunctionCC(const void *func, u32 param1, u32 param2) {
|
||||
MOV(32, R(ABI_PARAM1), Imm32(param1));
|
||||
MOV(32, R(ABI_PARAM2), Imm32(param2));
|
||||
u64 distance = u64(func) - (u64(code) + 5);
|
||||
|
@ -313,7 +313,7 @@ void XEmitter::ABI_CallFunctionCC(void *func, u32 param1, u32 param2) {
|
|||
}
|
||||
}
|
||||
|
||||
void XEmitter::ABI_CallFunctionCCC(void *func, u32 param1, u32 param2, u32 param3) {
|
||||
void XEmitter::ABI_CallFunctionCCC(const void *func, u32 param1, u32 param2, u32 param3) {
|
||||
MOV(32, R(ABI_PARAM1), Imm32(param1));
|
||||
MOV(32, R(ABI_PARAM2), Imm32(param2));
|
||||
MOV(32, R(ABI_PARAM3), Imm32(param3));
|
||||
|
@ -328,7 +328,7 @@ void XEmitter::ABI_CallFunctionCCC(void *func, u32 param1, u32 param2, u32 param
|
|||
}
|
||||
}
|
||||
|
||||
void XEmitter::ABI_CallFunctionCCP(void *func, u32 param1, u32 param2, void *param3) {
|
||||
void XEmitter::ABI_CallFunctionCCP(const void *func, u32 param1, u32 param2, void *param3) {
|
||||
MOV(32, R(ABI_PARAM1), Imm32(param1));
|
||||
MOV(32, R(ABI_PARAM2), Imm32(param2));
|
||||
MOV(64, R(ABI_PARAM3), Imm64((u64)param3));
|
||||
|
@ -343,7 +343,7 @@ void XEmitter::ABI_CallFunctionCCP(void *func, u32 param1, u32 param2, void *par
|
|||
}
|
||||
}
|
||||
|
||||
void XEmitter::ABI_CallFunctionCCCP(void *func, u32 param1, u32 param2, u32 param3, void *param4) {
|
||||
void XEmitter::ABI_CallFunctionCCCP(const void *func, u32 param1, u32 param2, u32 param3, void *param4) {
|
||||
MOV(32, R(ABI_PARAM1), Imm32(param1));
|
||||
MOV(32, R(ABI_PARAM2), Imm32(param2));
|
||||
MOV(32, R(ABI_PARAM3), Imm32(param3));
|
||||
|
@ -359,7 +359,7 @@ void XEmitter::ABI_CallFunctionCCCP(void *func, u32 param1, u32 param2, u32 para
|
|||
}
|
||||
}
|
||||
|
||||
void XEmitter::ABI_CallFunctionP(void *func, void *param1) {
|
||||
void XEmitter::ABI_CallFunctionP(const void *func, void *param1) {
|
||||
MOV(64, R(ABI_PARAM1), Imm64((u64)param1));
|
||||
u64 distance = u64(func) - (u64(code) + 5);
|
||||
if (distance >= 0x0000000080000000ULL
|
||||
|
@ -372,7 +372,7 @@ void XEmitter::ABI_CallFunctionP(void *func, void *param1) {
|
|||
}
|
||||
}
|
||||
|
||||
void XEmitter::ABI_CallFunctionPPC(void *func, void *param1, void *param2, u32 param3) {
|
||||
void XEmitter::ABI_CallFunctionPPC(const void *func, void *param1, void *param2, u32 param3) {
|
||||
MOV(64, R(ABI_PARAM1), Imm64((u64)param1));
|
||||
MOV(64, R(ABI_PARAM2), Imm64((u64)param2));
|
||||
MOV(32, R(ABI_PARAM3), Imm32(param3));
|
||||
|
@ -388,7 +388,7 @@ void XEmitter::ABI_CallFunctionPPC(void *func, void *param1, void *param2, u32 p
|
|||
}
|
||||
|
||||
// Pass a register as a parameter.
|
||||
void XEmitter::ABI_CallFunctionR(void *func, X64Reg reg1) {
|
||||
void XEmitter::ABI_CallFunctionR(const void *func, X64Reg reg1) {
|
||||
if (reg1 != ABI_PARAM1)
|
||||
MOV(32, R(ABI_PARAM1), R(reg1));
|
||||
u64 distance = u64(func) - (u64(code) + 5);
|
||||
|
@ -403,7 +403,7 @@ void XEmitter::ABI_CallFunctionR(void *func, X64Reg reg1) {
|
|||
}
|
||||
|
||||
// Pass two registers as parameters.
|
||||
void XEmitter::ABI_CallFunctionRR(void *func, X64Reg reg1, X64Reg reg2) {
|
||||
void XEmitter::ABI_CallFunctionRR(const void *func, X64Reg reg1, X64Reg reg2) {
|
||||
if (reg2 != ABI_PARAM1) {
|
||||
if (reg1 != ABI_PARAM1)
|
||||
MOV(64, R(ABI_PARAM1), R(reg1));
|
||||
|
@ -426,7 +426,7 @@ void XEmitter::ABI_CallFunctionRR(void *func, X64Reg reg1, X64Reg reg2) {
|
|||
}
|
||||
}
|
||||
|
||||
void XEmitter::ABI_CallFunctionAC(void *func, const Gen::OpArg &arg1, u32 param2)
|
||||
void XEmitter::ABI_CallFunctionAC(const void *func, const Gen::OpArg &arg1, u32 param2)
|
||||
{
|
||||
if (!arg1.IsSimpleReg(ABI_PARAM1))
|
||||
MOV(32, R(ABI_PARAM1), arg1);
|
||||
|
@ -442,7 +442,7 @@ void XEmitter::ABI_CallFunctionAC(void *func, const Gen::OpArg &arg1, u32 param2
|
|||
}
|
||||
}
|
||||
|
||||
void XEmitter::ABI_CallFunctionACC(void *func, const Gen::OpArg &arg1, u32 param2, u32 param3)
|
||||
void XEmitter::ABI_CallFunctionACC(const void *func, const Gen::OpArg &arg1, u32 param2, u32 param3)
|
||||
{
|
||||
MOV(32, R(ABI_PARAM1), arg1);
|
||||
MOV(32, R(ABI_PARAM2), Imm32(param2));
|
||||
|
@ -458,7 +458,7 @@ void XEmitter::ABI_CallFunctionACC(void *func, const Gen::OpArg &arg1, u32 param
|
|||
}
|
||||
}
|
||||
|
||||
void XEmitter::ABI_CallFunctionA(void *func, const Gen::OpArg &arg1)
|
||||
void XEmitter::ABI_CallFunctionA(const void *func, const Gen::OpArg &arg1)
|
||||
{
|
||||
if (!arg1.IsSimpleReg(ABI_PARAM1))
|
||||
MOV(32, R(ABI_PARAM1), arg1);
|
||||
|
@ -473,7 +473,7 @@ void XEmitter::ABI_CallFunctionA(void *func, const Gen::OpArg &arg1)
|
|||
}
|
||||
}
|
||||
|
||||
void XEmitter::ABI_CallFunctionAA(void *func, const Gen::OpArg &arg1, const Gen::OpArg &arg2)
|
||||
void XEmitter::ABI_CallFunctionAA(const void *func, const Gen::OpArg &arg1, const Gen::OpArg &arg2)
|
||||
{
|
||||
if (!arg1.IsSimpleReg(ABI_PARAM1))
|
||||
MOV(32, R(ABI_PARAM1), arg1);
|
||||
|
|
|
@ -91,12 +91,12 @@ void ThunkManager::Shutdown()
|
|||
FreeCodeSpace();
|
||||
}
|
||||
|
||||
void *ThunkManager::ProtectFunction(void *function, int num_params)
|
||||
const void *ThunkManager::ProtectFunction(const void *function, int num_params)
|
||||
{
|
||||
std::map<void *, const u8 *>::iterator iter;
|
||||
std::map<const void *, const u8 *>::iterator iter;
|
||||
iter = thunks.find(function);
|
||||
if (iter != thunks.end())
|
||||
return (void *)iter->second;
|
||||
return (const void *)iter->second;
|
||||
if (!region)
|
||||
PanicAlert("Trying to protect functions before the emu is started. Bad bad bad.");
|
||||
|
||||
|
@ -108,9 +108,9 @@ void *ThunkManager::ProtectFunction(void *function, int num_params)
|
|||
#else
|
||||
SUB(64, R(ESP), Imm8(0x8));
|
||||
#endif
|
||||
ABI_CallFunction((void*)save_regs);
|
||||
ABI_CallFunction((void*)function);
|
||||
ABI_CallFunction((void*)load_regs);
|
||||
ABI_CallFunction(save_regs);
|
||||
ABI_CallFunction(function);
|
||||
ABI_CallFunction(load_regs);
|
||||
#ifdef _WIN32
|
||||
ADD(64, R(ESP), Imm8(0x28));
|
||||
#else
|
||||
|
@ -118,7 +118,7 @@ void *ThunkManager::ProtectFunction(void *function, int num_params)
|
|||
#endif
|
||||
RET();
|
||||
#else
|
||||
CALL((void*)save_regs);
|
||||
CALL((const void *)save_regs);
|
||||
// Since parameters are in the previous stack frame, not in registers, this takes some
|
||||
// trickery : we simply re-push the parameters. might not be optimal, but that doesn't really
|
||||
// matter.
|
||||
|
@ -135,5 +135,5 @@ void *ThunkManager::ProtectFunction(void *function, int num_params)
|
|||
#endif
|
||||
|
||||
thunks[function] = call_point;
|
||||
return (void *)call_point;
|
||||
return (const void *)call_point;
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ class ThunkManager : public ArmGen::ARMXCodeBlock
|
|||
class ThunkManager : public Gen::XCodeBlock
|
||||
#endif
|
||||
{
|
||||
std::map<void *, const u8 *> thunks;
|
||||
std::map<const void *, const u8 *> thunks;
|
||||
|
||||
const u8 *save_regs;
|
||||
const u8 *load_regs;
|
||||
|
@ -56,7 +56,32 @@ public:
|
|||
~ThunkManager() {
|
||||
Shutdown();
|
||||
}
|
||||
void *ProtectFunction(void *function, int num_params);
|
||||
const void *ProtectFunction(const void *function, int num_params);
|
||||
|
||||
template <typename Tr>
|
||||
const void *ProtectFunction(Tr (*func)()) {
|
||||
return ProtectFunction((const void *)func, 0);
|
||||
}
|
||||
|
||||
template <typename Tr, typename T1>
|
||||
const void *ProtectFunction(Tr (*func)(T1)) {
|
||||
return ProtectFunction((const void *)func, 1);
|
||||
}
|
||||
|
||||
template <typename Tr, typename T1, typename T2>
|
||||
const void *ProtectFunction(Tr (*func)(T1, T2)) {
|
||||
return ProtectFunction((const void *)func, 2);
|
||||
}
|
||||
|
||||
template <typename Tr, typename T1, typename T2, typename T3>
|
||||
const void *ProtectFunction(Tr (*func)(T1, T2, T3)) {
|
||||
return ProtectFunction((const void *)func, 3);
|
||||
}
|
||||
|
||||
template <typename Tr, typename T1, typename T2, typename T3, typename T4>
|
||||
const void *ProtectFunction(Tr (*func)(T1, T2, T3, T4)) {
|
||||
return ProtectFunction((const void *)func, 4);
|
||||
}
|
||||
|
||||
const u8 *GetSaveRegsFunction() const {
|
||||
return save_regs;
|
||||
|
|
|
@ -192,8 +192,10 @@ private:
|
|||
u16 indexReg;
|
||||
};
|
||||
|
||||
inline OpArg M(void *ptr) {return OpArg((u64)ptr, (int)SCALE_RIP);}
|
||||
inline OpArg R(X64Reg value) {return OpArg(0, SCALE_NONE, value);}
|
||||
inline OpArg M(const void *ptr) {return OpArg((u64)ptr, (int)SCALE_RIP);}
|
||||
template <typename T>
|
||||
inline OpArg M(const T *ptr) {return OpArg((u64)(const void *)ptr, (int)SCALE_RIP);}
|
||||
inline OpArg R(X64Reg value) {return OpArg(0, SCALE_NONE, value);}
|
||||
inline OpArg MatR(X64Reg value) {return OpArg(0, SCALE_ATREG, value);}
|
||||
inline OpArg MDisp(X64Reg value, int offset) {
|
||||
return OpArg((u32)offset, SCALE_ATREG, value);
|
||||
|
@ -674,28 +676,42 @@ public:
|
|||
// Utility functions
|
||||
// The difference between this and CALL is that this aligns the stack
|
||||
// where appropriate.
|
||||
void ABI_CallFunction(void *func);
|
||||
void ABI_CallFunction(const void *func);
|
||||
|
||||
void ABI_CallFunctionC16(void *func, u16 param1);
|
||||
void ABI_CallFunctionCC16(void *func, u32 param1, u16 param2);
|
||||
template <typename T>
|
||||
void ABI_CallFunction(T (*func)()) {
|
||||
ABI_CallFunction((const void *)func);
|
||||
}
|
||||
|
||||
void ABI_CallFunction(const u8 *func) {
|
||||
ABI_CallFunction((const void *)func);
|
||||
}
|
||||
|
||||
void ABI_CallFunctionC16(const void *func, u16 param1);
|
||||
void ABI_CallFunctionCC16(const void *func, u32 param1, u16 param2);
|
||||
|
||||
// These only support u32 parameters, but that's enough for a lot of uses.
|
||||
// These will destroy the 1 or 2 first "parameter regs".
|
||||
void ABI_CallFunctionC(void *func, u32 param1);
|
||||
void ABI_CallFunctionCC(void *func, u32 param1, u32 param2);
|
||||
void ABI_CallFunctionCCC(void *func, u32 param1, u32 param2, u32 param3);
|
||||
void ABI_CallFunctionCCP(void *func, u32 param1, u32 param2, void *param3);
|
||||
void ABI_CallFunctionCCCP(void *func, u32 param1, u32 param2, u32 param3, void *param4);
|
||||
void ABI_CallFunctionP(void *func, void *param1);
|
||||
void ABI_CallFunctionPPC(void *func, void *param1, void *param2, u32 param3);
|
||||
void ABI_CallFunctionAC(void *func, const Gen::OpArg &arg1, u32 param2);
|
||||
void ABI_CallFunctionACC(void *func, const Gen::OpArg &arg1, u32 param2, u32 param3);
|
||||
void ABI_CallFunctionA(void *func, const Gen::OpArg &arg1);
|
||||
void ABI_CallFunctionAA(void *func, const Gen::OpArg &arg1, const Gen::OpArg &arg2);
|
||||
void ABI_CallFunctionC(const void *func, u32 param1);
|
||||
void ABI_CallFunctionCC(const void *func, u32 param1, u32 param2);
|
||||
void ABI_CallFunctionCCC(const void *func, u32 param1, u32 param2, u32 param3);
|
||||
void ABI_CallFunctionCCP(const void *func, u32 param1, u32 param2, void *param3);
|
||||
void ABI_CallFunctionCCCP(const void *func, u32 param1, u32 param2, u32 param3, void *param4);
|
||||
void ABI_CallFunctionP(const void *func, void *param1);
|
||||
void ABI_CallFunctionPPC(const void *func, void *param1, void *param2, u32 param3);
|
||||
void ABI_CallFunctionAC(const void *func, const Gen::OpArg &arg1, u32 param2);
|
||||
void ABI_CallFunctionACC(const void *func, const Gen::OpArg &arg1, u32 param2, u32 param3);
|
||||
void ABI_CallFunctionA(const void *func, const Gen::OpArg &arg1);
|
||||
void ABI_CallFunctionAA(const void *func, const Gen::OpArg &arg1, const Gen::OpArg &arg2);
|
||||
|
||||
// Pass a register as a paremeter.
|
||||
void ABI_CallFunctionR(void *func, Gen::X64Reg reg1);
|
||||
void ABI_CallFunctionRR(void *func, Gen::X64Reg reg1, Gen::X64Reg reg2);
|
||||
// Pass a register as a parameter.
|
||||
void ABI_CallFunctionR(const void *func, Gen::X64Reg reg1);
|
||||
void ABI_CallFunctionRR(const void *func, Gen::X64Reg reg1, Gen::X64Reg reg2);
|
||||
|
||||
template <typename Tr, typename T1>
|
||||
void ABI_CallFunctionC(Tr (*func)(T1), u32 param1) {
|
||||
ABI_CallFunctionC((const void *)func, param1);
|
||||
}
|
||||
|
||||
// A function that doesn't have any control over what it will do to regs,
|
||||
// such as the dispatcher, should be surrounded by these.
|
||||
|
|
|
@ -86,7 +86,7 @@ void AsmRoutineManager::Generate(MIPSState *mips, MIPSComp::Jit *jit)
|
|||
// IMPORTANT - We jump on negative, not carry!!!
|
||||
FixupBranch bailCoreState = J_CC(CC_S, true);
|
||||
|
||||
CMP(32, M((void*)&coreState), Imm32(0));
|
||||
CMP(32, M(&coreState), Imm32(0));
|
||||
FixupBranch badCoreState = J_CC(CC_NZ, true);
|
||||
FixupBranch skipToRealDispatch2 = J(); //skip the sync and compare first time
|
||||
|
||||
|
@ -129,13 +129,13 @@ void AsmRoutineManager::Generate(MIPSState *mips, MIPSComp::Jit *jit)
|
|||
SetJumpTarget(notfound);
|
||||
|
||||
//Ok, no block, let's jit
|
||||
ABI_CallFunction((void *)&Jit);
|
||||
ABI_CallFunction(&Jit);
|
||||
JMP(dispatcherNoCheck); // Let's just dispatch again, we'll enter the block since we know it's there.
|
||||
|
||||
SetJumpTarget(bail);
|
||||
SetJumpTarget(bailCoreState);
|
||||
|
||||
CMP(32, M((void*)&coreState), Imm32(0));
|
||||
CMP(32, M(&coreState), Imm32(0));
|
||||
J_CC(CC_Z, outerLoop, true);
|
||||
|
||||
SetJumpTarget(badCoreState);
|
||||
|
|
|
@ -829,22 +829,22 @@ namespace MIPSComp
|
|||
{
|
||||
case 16: // R(rd) = HI; //mfhi
|
||||
gpr.MapReg(rd, false, true);
|
||||
MOV(32, gpr.R(rd), M((void *)&mips_->hi));
|
||||
MOV(32, gpr.R(rd), M(&mips_->hi));
|
||||
break;
|
||||
|
||||
case 17: // HI = R(rs); //mthi
|
||||
gpr.MapReg(rs, true, false);
|
||||
MOV(32, M((void *)&mips_->hi), gpr.R(rs));
|
||||
MOV(32, M(&mips_->hi), gpr.R(rs));
|
||||
break;
|
||||
|
||||
case 18: // R(rd) = LO; break; //mflo
|
||||
gpr.MapReg(rd, false, true);
|
||||
MOV(32, gpr.R(rd), M((void *)&mips_->lo));
|
||||
MOV(32, gpr.R(rd), M(&mips_->lo));
|
||||
break;
|
||||
|
||||
case 19: // LO = R(rs); break; //mtlo
|
||||
gpr.MapReg(rs, true, false);
|
||||
MOV(32, M((void *)&mips_->lo), gpr.R(rs));
|
||||
MOV(32, M(&mips_->lo), gpr.R(rs));
|
||||
break;
|
||||
|
||||
case 24: //mult (the most popular one). lo,hi = signed mul (rs * rt)
|
||||
|
@ -852,8 +852,8 @@ namespace MIPSComp
|
|||
gpr.KillImmediate(rt, true, false);
|
||||
MOV(32, R(EAX), gpr.R(rs));
|
||||
IMUL(32, gpr.R(rt));
|
||||
MOV(32, M((void *)&mips_->hi), R(EDX));
|
||||
MOV(32, M((void *)&mips_->lo), R(EAX));
|
||||
MOV(32, M(&mips_->hi), R(EDX));
|
||||
MOV(32, M(&mips_->lo), R(EAX));
|
||||
gpr.UnlockAllX();
|
||||
break;
|
||||
|
||||
|
@ -863,8 +863,8 @@ namespace MIPSComp
|
|||
gpr.KillImmediate(rt, true, false);
|
||||
MOV(32, R(EAX), gpr.R(rs));
|
||||
MUL(32, gpr.R(rt));
|
||||
MOV(32, M((void *)&mips_->hi), R(EDX));
|
||||
MOV(32, M((void *)&mips_->lo), R(EAX));
|
||||
MOV(32, M(&mips_->hi), R(EDX));
|
||||
MOV(32, M(&mips_->lo), R(EAX));
|
||||
gpr.UnlockAllX();
|
||||
break;
|
||||
|
||||
|
@ -883,7 +883,7 @@ namespace MIPSComp
|
|||
CMP(32, gpr.R(rt), Imm32((u32) -1));
|
||||
FixupBranch notOverflow2 = J_CC(CC_NE);
|
||||
// TODO: Should HI be set to anything?
|
||||
MOV(32, M((void *)&mips_->lo), Imm32(0x80000000));
|
||||
MOV(32, M(&mips_->lo), Imm32(0x80000000));
|
||||
FixupBranch skip2 = J();
|
||||
|
||||
SetJumpTarget(notOverflow);
|
||||
|
@ -892,14 +892,14 @@ namespace MIPSComp
|
|||
MOV(32, R(EAX), gpr.R(rs));
|
||||
CDQ();
|
||||
IDIV(32, gpr.R(rt));
|
||||
MOV(32, M((void *)&mips_->hi), R(EDX));
|
||||
MOV(32, M((void *)&mips_->lo), R(EAX));
|
||||
MOV(32, M(&mips_->hi), R(EDX));
|
||||
MOV(32, M(&mips_->lo), R(EAX));
|
||||
FixupBranch skip = J();
|
||||
|
||||
SetJumpTarget(divZero);
|
||||
// TODO: Is this the right way to handle a divide by zero?
|
||||
MOV(32, M((void *)&mips_->hi), Imm32(0));
|
||||
MOV(32, M((void *)&mips_->lo), Imm32(0));
|
||||
MOV(32, M(&mips_->hi), Imm32(0));
|
||||
MOV(32, M(&mips_->lo), Imm32(0));
|
||||
|
||||
SetJumpTarget(skip);
|
||||
SetJumpTarget(skip2);
|
||||
|
@ -917,14 +917,14 @@ namespace MIPSComp
|
|||
MOV(32, R(EAX), gpr.R(rs));
|
||||
MOV(32, R(EDX), Imm32(0));
|
||||
DIV(32, gpr.R(rt));
|
||||
MOV(32, M((void *)&mips_->hi), R(EDX));
|
||||
MOV(32, M((void *)&mips_->lo), R(EAX));
|
||||
MOV(32, M(&mips_->hi), R(EDX));
|
||||
MOV(32, M(&mips_->lo), R(EAX));
|
||||
FixupBranch skip = J();
|
||||
|
||||
SetJumpTarget(divZero);
|
||||
// TODO: Is this the right way to handle a divide by zero?
|
||||
MOV(32, M((void *)&mips_->hi), Imm32(0));
|
||||
MOV(32, M((void *)&mips_->lo), Imm32(0));
|
||||
MOV(32, M(&mips_->hi), Imm32(0));
|
||||
MOV(32, M(&mips_->lo), Imm32(0));
|
||||
|
||||
SetJumpTarget(skip);
|
||||
gpr.UnlockAllX();
|
||||
|
@ -936,8 +936,8 @@ namespace MIPSComp
|
|||
gpr.KillImmediate(rt, true, false);
|
||||
MOV(32, R(EAX), gpr.R(rs));
|
||||
IMUL(32, gpr.R(rt));
|
||||
ADD(32, M((void *)&mips_->lo), R(EAX));
|
||||
ADC(32, M((void *)&mips_->hi), R(EDX));
|
||||
ADD(32, M(&mips_->lo), R(EAX));
|
||||
ADC(32, M(&mips_->hi), R(EDX));
|
||||
gpr.UnlockAllX();
|
||||
break;
|
||||
|
||||
|
@ -946,8 +946,8 @@ namespace MIPSComp
|
|||
gpr.KillImmediate(rt, true, false);
|
||||
MOV(32, R(EAX), gpr.R(rs));
|
||||
MUL(32, gpr.R(rt));
|
||||
ADD(32, M((void *)&mips_->lo), R(EAX));
|
||||
ADC(32, M((void *)&mips_->hi), R(EDX));
|
||||
ADD(32, M(&mips_->lo), R(EAX));
|
||||
ADC(32, M(&mips_->hi), R(EDX));
|
||||
gpr.UnlockAllX();
|
||||
break;
|
||||
|
||||
|
@ -956,8 +956,8 @@ namespace MIPSComp
|
|||
gpr.KillImmediate(rt, true, false);
|
||||
MOV(32, R(EAX), gpr.R(rs));
|
||||
IMUL(32, gpr.R(rt));
|
||||
SUB(32, M((void *)&mips_->lo), R(EAX));
|
||||
SBB(32, M((void *)&mips_->hi), R(EDX));
|
||||
SUB(32, M(&mips_->lo), R(EAX));
|
||||
SBB(32, M(&mips_->hi), R(EDX));
|
||||
gpr.UnlockAllX();
|
||||
break;
|
||||
|
||||
|
@ -966,8 +966,8 @@ namespace MIPSComp
|
|||
gpr.KillImmediate(rt, true, false);
|
||||
MOV(32, R(EAX), gpr.R(rs));
|
||||
MUL(32, gpr.R(rt));
|
||||
SUB(32, M((void *)&mips_->lo), R(EAX));
|
||||
SBB(32, M((void *)&mips_->hi), R(EDX));
|
||||
SUB(32, M(&mips_->lo), R(EAX));
|
||||
SBB(32, M(&mips_->hi), R(EDX));
|
||||
gpr.UnlockAllX();
|
||||
break;
|
||||
|
||||
|
|
|
@ -110,21 +110,21 @@ static void JitBranchLogMismatch(MIPSOpcode op, u32 pc)
|
|||
void Jit::BranchLog(MIPSOpcode op)
|
||||
{
|
||||
FlushAll();
|
||||
ABI_CallFunctionCC(thunks.ProtectFunction((void *) &JitBranchLog, 2), op.encoding, js.compilerPC);
|
||||
ABI_CallFunctionCC(thunks.ProtectFunction(&JitBranchLog), op.encoding, js.compilerPC);
|
||||
}
|
||||
|
||||
void Jit::BranchLogExit(MIPSOpcode op, u32 dest, bool useEAX)
|
||||
{
|
||||
OpArg destArg = useEAX ? R(EAX) : Imm32(dest);
|
||||
|
||||
CMP(32, M((void *) &intBranchExit), destArg);
|
||||
CMP(32, M(&intBranchExit), destArg);
|
||||
FixupBranch skip = J_CC(CC_E);
|
||||
|
||||
MOV(32, M((void *) &jitBranchExit), destArg);
|
||||
ABI_CallFunctionCC(thunks.ProtectFunction((void *) &JitBranchLogMismatch, 2), op.encoding, js.compilerPC);
|
||||
MOV(32, M(&jitBranchExit), destArg);
|
||||
ABI_CallFunctionCC(thunks.ProtectFunction(&JitBranchLogMismatch), op.encoding, js.compilerPC);
|
||||
// Restore EAX, we probably ruined it.
|
||||
if (useEAX)
|
||||
MOV(32, R(EAX), M((void *) &jitBranchExit));
|
||||
MOV(32, R(EAX), M(&jitBranchExit));
|
||||
|
||||
SetJumpTarget(skip);
|
||||
}
|
||||
|
@ -445,7 +445,7 @@ void Jit::BranchFPFlag(MIPSOpcode op, Gen::CCFlags cc, bool likely)
|
|||
if (!likely && delaySlotIsNice)
|
||||
CompileDelaySlot(DELAYSLOT_NICE);
|
||||
|
||||
TEST(32, M((void *)&(mips_->fpcond)), Imm32(1));
|
||||
TEST(32, M(&(mips_->fpcond)), Imm32(1));
|
||||
|
||||
CompBranchExits(cc, targetAddr, js.compilerPC + 8, delaySlotIsNice, likely, false);
|
||||
}
|
||||
|
@ -492,7 +492,7 @@ void Jit::BranchVFPUFlag(MIPSOpcode op, Gen::CCFlags cc, bool likely)
|
|||
// THE CONDITION
|
||||
int imm3 = (op >> 18) & 7;
|
||||
|
||||
TEST(32, M((void *)&(mips_->vfpuCtrl[VFPU_CTRL_CC])), Imm32(1 << imm3));
|
||||
TEST(32, M(&(mips_->vfpuCtrl[VFPU_CTRL_CC])), Imm32(1 << imm3));
|
||||
|
||||
u32 notTakenTarget = js.compilerPC + (delaySlotIsBranch ? 4 : 8);
|
||||
CompBranchExits(cc, targetAddr, notTakenTarget, delaySlotIsNice, likely, false);
|
||||
|
@ -687,7 +687,7 @@ void Jit::Comp_Syscall(MIPSOpcode op)
|
|||
if (quickFunc)
|
||||
ABI_CallFunctionP(quickFunc, (void *)GetSyscallInfo(op));
|
||||
else
|
||||
ABI_CallFunctionC((void *)&CallSyscall, op.encoding);
|
||||
ABI_CallFunctionC(&CallSyscall, op.encoding);
|
||||
|
||||
WriteSyscallExit();
|
||||
js.compiling = false;
|
||||
|
|
|
@ -111,10 +111,10 @@ void Jit::Comp_FPULS(MIPSOpcode op)
|
|||
OpArg src;
|
||||
if (safe.PrepareRead(src, 4))
|
||||
MOVSS(fpr.RX(ft), src);
|
||||
if (safe.PrepareSlowRead((void *) &Memory::Read_U32))
|
||||
if (safe.PrepareSlowRead(&Memory::Read_U32))
|
||||
{
|
||||
MOV(32, M((void *)&ssLoadStoreTemp), R(EAX));
|
||||
MOVSS(fpr.RX(ft), M((void *)&ssLoadStoreTemp));
|
||||
MOV(32, M(&ssLoadStoreTemp), R(EAX));
|
||||
MOVSS(fpr.RX(ft), M(&ssLoadStoreTemp));
|
||||
}
|
||||
safe.Finish();
|
||||
|
||||
|
@ -134,8 +134,8 @@ void Jit::Comp_FPULS(MIPSOpcode op)
|
|||
MOVSS(dest, fpr.RX(ft));
|
||||
if (safe.PrepareSlowWrite())
|
||||
{
|
||||
MOVSS(M((void *)&ssLoadStoreTemp), fpr.RX(ft));
|
||||
safe.DoSlowWrite((void *) &Memory::Write_U32, M((void *)&ssLoadStoreTemp));
|
||||
MOVSS(M(&ssLoadStoreTemp), fpr.RX(ft));
|
||||
safe.DoSlowWrite(&Memory::Write_U32, M(&ssLoadStoreTemp));
|
||||
}
|
||||
safe.Finish();
|
||||
|
||||
|
@ -160,17 +160,17 @@ void Jit::CompFPComp(int lhs, int rhs, u8 compare, bool allowNaN)
|
|||
{
|
||||
MOVSS(XMM0, fpr.R(lhs));
|
||||
CMPSS(XMM0, fpr.R(rhs), compare);
|
||||
MOVSS(M((void *) ¤tMIPS->fpcond), XMM0);
|
||||
MOVSS(M(¤tMIPS->fpcond), XMM0);
|
||||
|
||||
// This means that NaN also means true, e.g. !<> or !>, etc.
|
||||
if (allowNaN)
|
||||
{
|
||||
MOVSS(XMM0, fpr.R(lhs));
|
||||
CMPUNORDSS(XMM0, fpr.R(rhs));
|
||||
MOVSS(M((void *) &ssCompareTemp), XMM0);
|
||||
MOVSS(M(&ssCompareTemp), XMM0);
|
||||
|
||||
MOV(32, R(EAX), M((void *) &ssCompareTemp));
|
||||
OR(32, M((void *) ¤tMIPS->fpcond), R(EAX));
|
||||
MOV(32, R(EAX), M(&ssCompareTemp));
|
||||
OR(32, M(¤tMIPS->fpcond), R(EAX));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -185,7 +185,7 @@ void Jit::Comp_FPUComp(MIPSOpcode op)
|
|||
{
|
||||
case 0: //f
|
||||
case 8: //sf
|
||||
MOV(32, M((void *) ¤tMIPS->fpcond), Imm32(0));
|
||||
MOV(32, M(¤tMIPS->fpcond), Imm32(0));
|
||||
break;
|
||||
|
||||
case 1: //un
|
||||
|
@ -240,7 +240,7 @@ void Jit::Comp_FPU2op(MIPSOpcode op) {
|
|||
fpr.SpillLock(fd, fs);
|
||||
fpr.MapReg(fd, fd == fs, true);
|
||||
MOVSS(fpr.RX(fd), fpr.R(fs));
|
||||
PAND(fpr.RX(fd), M((void *)ssNoSignMask));
|
||||
PAND(fpr.RX(fd), M(ssNoSignMask));
|
||||
break;
|
||||
|
||||
case 6: //F(fd) = F(fs); break; //mov
|
||||
|
@ -255,7 +255,7 @@ void Jit::Comp_FPU2op(MIPSOpcode op) {
|
|||
fpr.SpillLock(fd, fs);
|
||||
fpr.MapReg(fd, fd == fs, true);
|
||||
MOVSS(fpr.RX(fd), fpr.R(fs));
|
||||
PXOR(fpr.RX(fd), M((void *)ssSignBits2));
|
||||
PXOR(fpr.RX(fd), M(ssSignBits2));
|
||||
break;
|
||||
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
|
||||
namespace MIPSComp
|
||||
{
|
||||
void Jit::CompITypeMemRead(MIPSOpcode op, u32 bits, void (XEmitter::*mov)(int, int, X64Reg, OpArg), void *safeFunc)
|
||||
void Jit::CompITypeMemRead(MIPSOpcode op, u32 bits, void (XEmitter::*mov)(int, int, X64Reg, OpArg), const void *safeFunc)
|
||||
{
|
||||
CONDITIONAL_DISABLE;
|
||||
int offset = _IMM16;
|
||||
|
@ -65,7 +65,7 @@ namespace MIPSComp
|
|||
gpr.UnlockAll();
|
||||
}
|
||||
|
||||
void Jit::CompITypeMemWrite(MIPSOpcode op, u32 bits, void *safeFunc)
|
||||
void Jit::CompITypeMemWrite(MIPSOpcode op, u32 bits, const void *safeFunc)
|
||||
{
|
||||
CONDITIONAL_DISABLE;
|
||||
int offset = _IMM16;
|
||||
|
@ -141,7 +141,7 @@ namespace MIPSComp
|
|||
|
||||
CompITypeMemUnpairedLRInner(op, shiftReg);
|
||||
}
|
||||
if (safe.PrepareSlowRead((void *) &Memory::Read_U32))
|
||||
if (safe.PrepareSlowRead(&Memory::Read_U32))
|
||||
CompITypeMemUnpairedLRInner(op, shiftReg);
|
||||
safe.Finish();
|
||||
}
|
||||
|
@ -154,7 +154,7 @@ namespace MIPSComp
|
|||
if (safe.PrepareWrite(dest, 4))
|
||||
MOV(32, dest, R(EDX));
|
||||
if (safe.PrepareSlowWrite())
|
||||
safe.DoSlowWrite((void *) &Memory::Write_U32, R(EDX));
|
||||
safe.DoSlowWrite(&Memory::Write_U32, R(EDX));
|
||||
safe.Finish();
|
||||
}
|
||||
|
||||
|
@ -269,35 +269,35 @@ namespace MIPSComp
|
|||
switch (o)
|
||||
{
|
||||
case 37: //R(rt) = ReadMem16(addr); break; //lhu
|
||||
CompITypeMemRead(op, 16, &XEmitter::MOVZX, (void *) &Memory::Read_U16);
|
||||
CompITypeMemRead(op, 16, &XEmitter::MOVZX, &Memory::Read_U16);
|
||||
break;
|
||||
|
||||
case 36: //R(rt) = ReadMem8 (addr); break; //lbu
|
||||
CompITypeMemRead(op, 8, &XEmitter::MOVZX, (void *) &Memory::Read_U8);
|
||||
CompITypeMemRead(op, 8, &XEmitter::MOVZX, &Memory::Read_U8);
|
||||
break;
|
||||
|
||||
case 35: //R(rt) = ReadMem32(addr); break; //lw
|
||||
CompITypeMemRead(op, 32, &XEmitter::MOVZX, (void *) &Memory::Read_U32);
|
||||
CompITypeMemRead(op, 32, &XEmitter::MOVZX, &Memory::Read_U32);
|
||||
break;
|
||||
|
||||
case 32: //R(rt) = (u32)(s32)(s8) ReadMem8 (addr); break; //lb
|
||||
CompITypeMemRead(op, 8, &XEmitter::MOVSX, (void *) &Memory::Read_U8);
|
||||
CompITypeMemRead(op, 8, &XEmitter::MOVSX, &Memory::Read_U8);
|
||||
break;
|
||||
|
||||
case 33: //R(rt) = (u32)(s32)(s16)ReadMem16(addr); break; //lh
|
||||
CompITypeMemRead(op, 16, &XEmitter::MOVSX, (void *) &Memory::Read_U16);
|
||||
CompITypeMemRead(op, 16, &XEmitter::MOVSX, &Memory::Read_U16);
|
||||
break;
|
||||
|
||||
case 40: //WriteMem8 (addr, R(rt)); break; //sb
|
||||
CompITypeMemWrite(op, 8, (void *) &Memory::Write_U8);
|
||||
CompITypeMemWrite(op, 8, &Memory::Write_U8);
|
||||
break;
|
||||
|
||||
case 41: //WriteMem16(addr, R(rt)); break; //sh
|
||||
CompITypeMemWrite(op, 16, (void *) &Memory::Write_U16);
|
||||
CompITypeMemWrite(op, 16, &Memory::Write_U16);
|
||||
break;
|
||||
|
||||
case 43: //WriteMem32(addr, R(rt)); break; //sw
|
||||
CompITypeMemWrite(op, 32, (void *) &Memory::Write_U32);
|
||||
CompITypeMemWrite(op, 32, &Memory::Write_U32);
|
||||
break;
|
||||
|
||||
case 34: //lwl
|
||||
|
@ -309,7 +309,7 @@ namespace MIPSComp
|
|||
{
|
||||
EatInstruction(nextOp);
|
||||
// nextOp has the correct address.
|
||||
CompITypeMemRead(nextOp, 32, &XEmitter::MOVZX, (void *) &Memory::Read_U32);
|
||||
CompITypeMemRead(nextOp, 32, &XEmitter::MOVZX, &Memory::Read_U32);
|
||||
}
|
||||
else
|
||||
CompITypeMemUnpairedLR(op, false);
|
||||
|
@ -325,7 +325,7 @@ namespace MIPSComp
|
|||
{
|
||||
EatInstruction(nextOp);
|
||||
// op has the correct address.
|
||||
CompITypeMemRead(op, 32, &XEmitter::MOVZX, (void *) &Memory::Read_U32);
|
||||
CompITypeMemRead(op, 32, &XEmitter::MOVZX, &Memory::Read_U32);
|
||||
}
|
||||
else
|
||||
CompITypeMemUnpairedLR(op, false);
|
||||
|
@ -341,7 +341,7 @@ namespace MIPSComp
|
|||
{
|
||||
EatInstruction(nextOp);
|
||||
// nextOp has the correct address.
|
||||
CompITypeMemWrite(nextOp, 32, (void *) &Memory::Write_U32);
|
||||
CompITypeMemWrite(nextOp, 32, &Memory::Write_U32);
|
||||
}
|
||||
else
|
||||
CompITypeMemUnpairedLR(op, true);
|
||||
|
@ -357,7 +357,7 @@ namespace MIPSComp
|
|||
{
|
||||
EatInstruction(nextOp);
|
||||
// op has the correct address.
|
||||
CompITypeMemWrite(op, 32, (void *) &Memory::Write_U32);
|
||||
CompITypeMemWrite(op, 32, &Memory::Write_U32);
|
||||
}
|
||||
else
|
||||
CompITypeMemUnpairedLR(op, true);
|
||||
|
|
|
@ -27,7 +27,7 @@ int Jit::Replace_fabsf() {
|
|||
fpr.SpillLock(0, 12);
|
||||
fpr.MapReg(0, MAP_DIRTY | MAP_NOINIT);
|
||||
MOVSS(fpr.RX(0), fpr.R(12));
|
||||
ANDPS(fpr.RX(0), M((void *)&ssNoSignMask));
|
||||
ANDPS(fpr.RX(0), M(&ssNoSignMask));
|
||||
fpr.ReleaseSpillLocks();
|
||||
return 4; // Number of instructions in the MIPS function
|
||||
}
|
||||
|
|
|
@ -121,14 +121,14 @@ void Jit::ApplyPrefixST(u8 *vregs, u32 prefix, VectorSize sz) {
|
|||
}
|
||||
MOVSS(fpr.VX(vregs[i]), fpr.V(origV[regnum]));
|
||||
if (abs) {
|
||||
ANDPS(fpr.VX(vregs[i]), M((void *)&noSignMask));
|
||||
ANDPS(fpr.VX(vregs[i]), M(&noSignMask));
|
||||
}
|
||||
} else {
|
||||
MOVSS(fpr.VX(vregs[i]), M((void *)&constantArray[regnum + (abs<<2)]));
|
||||
MOVSS(fpr.VX(vregs[i]), M(&constantArray[regnum + (abs<<2)]));
|
||||
}
|
||||
|
||||
if (negate)
|
||||
XORPS(fpr.VX(vregs[i]), M((void *)&signBitLower));
|
||||
XORPS(fpr.VX(vregs[i]), M(&signBitLower));
|
||||
|
||||
// TODO: This probably means it will swap out soon, inefficiently...
|
||||
fpr.ReleaseSpillLockV(vregs[i]);
|
||||
|
@ -165,14 +165,14 @@ void Jit::ApplyPrefixD(const u8 *vregs, VectorSize sz) {
|
|||
if (sat == 1)
|
||||
{
|
||||
fpr.MapRegV(vregs[i], MAP_DIRTY);
|
||||
MAXSS(fpr.VX(vregs[i]), M((void *)&zero));
|
||||
MINSS(fpr.VX(vregs[i]), M((void *)&one));
|
||||
MAXSS(fpr.VX(vregs[i]), M(&zero));
|
||||
MINSS(fpr.VX(vregs[i]), M(&one));
|
||||
}
|
||||
else if (sat == 3)
|
||||
{
|
||||
fpr.MapRegV(vregs[i], MAP_DIRTY);
|
||||
MAXSS(fpr.VX(vregs[i]), M((void *)&minus_one));
|
||||
MINSS(fpr.VX(vregs[i]), M((void *)&one));
|
||||
MAXSS(fpr.VX(vregs[i]), M(&minus_one));
|
||||
MINSS(fpr.VX(vregs[i]), M(&one));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -224,10 +224,10 @@ void Jit::Comp_SV(MIPSOpcode op) {
|
|||
{
|
||||
MOVSS(fpr.VX(vt), safe.NextFastAddress(0));
|
||||
}
|
||||
if (safe.PrepareSlowRead((void *) &Memory::Read_U32))
|
||||
if (safe.PrepareSlowRead(&Memory::Read_U32))
|
||||
{
|
||||
MOV(32, M((void *)&ssLoadStoreTemp), R(EAX));
|
||||
MOVSS(fpr.VX(vt), M((void *)&ssLoadStoreTemp));
|
||||
MOV(32, M(&ssLoadStoreTemp), R(EAX));
|
||||
MOVSS(fpr.VX(vt), M(&ssLoadStoreTemp));
|
||||
}
|
||||
safe.Finish();
|
||||
|
||||
|
@ -252,8 +252,8 @@ void Jit::Comp_SV(MIPSOpcode op) {
|
|||
}
|
||||
if (safe.PrepareSlowWrite())
|
||||
{
|
||||
MOVSS(M((void *)&ssLoadStoreTemp), fpr.VX(vt));
|
||||
safe.DoSlowWrite((void *) &Memory::Write_U32, M((void *)&ssLoadStoreTemp), 0);
|
||||
MOVSS(M(&ssLoadStoreTemp), fpr.VX(vt));
|
||||
safe.DoSlowWrite(&Memory::Write_U32, M(&ssLoadStoreTemp), 0);
|
||||
}
|
||||
safe.Finish();
|
||||
|
||||
|
@ -361,13 +361,13 @@ void Jit::Comp_SVQ(MIPSOpcode op)
|
|||
for (int i = 0; i < 4; i++)
|
||||
MOVSS(fpr.VX(vregs[i]), safe.NextFastAddress(i * 4));
|
||||
}
|
||||
if (safe.PrepareSlowRead((void *) &Memory::Read_U32))
|
||||
if (safe.PrepareSlowRead(&Memory::Read_U32))
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
safe.NextSlowRead((void *) &Memory::Read_U32, i * 4);
|
||||
MOV(32, M((void *)&ssLoadStoreTemp), R(EAX));
|
||||
MOVSS(fpr.VX(vregs[i]), M((void *)&ssLoadStoreTemp));
|
||||
safe.NextSlowRead(&Memory::Read_U32, i * 4);
|
||||
MOV(32, M(&ssLoadStoreTemp), R(EAX));
|
||||
MOVSS(fpr.VX(vregs[i]), M(&ssLoadStoreTemp));
|
||||
}
|
||||
}
|
||||
safe.Finish();
|
||||
|
@ -398,8 +398,8 @@ void Jit::Comp_SVQ(MIPSOpcode op)
|
|||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
MOVSS(M((void *)&ssLoadStoreTemp), fpr.VX(vregs[i]));
|
||||
safe.DoSlowWrite((void *) &Memory::Write_U32, M((void *)&ssLoadStoreTemp), i * 4);
|
||||
MOVSS(M(&ssLoadStoreTemp), fpr.VX(vregs[i]));
|
||||
safe.DoSlowWrite(&Memory::Write_U32, M(&ssLoadStoreTemp), i * 4);
|
||||
}
|
||||
}
|
||||
safe.Finish();
|
||||
|
@ -424,10 +424,10 @@ void Jit::Comp_VVectorInit(MIPSOpcode op) {
|
|||
switch ((op >> 16) & 0xF)
|
||||
{
|
||||
case 6: // v=zeros; break; //vzero
|
||||
MOVSS(XMM0, M((void *) &zero));
|
||||
MOVSS(XMM0, M(&zero));
|
||||
break;
|
||||
case 7: // v=ones; break; //vone
|
||||
MOVSS(XMM0, M((void *) &one));
|
||||
MOVSS(XMM0, M(&one));
|
||||
break;
|
||||
default:
|
||||
DISABLE;
|
||||
|
@ -455,7 +455,7 @@ void Jit::Comp_VIdt(MIPSOpcode op) {
|
|||
VectorSize sz = GetVecSize(op);
|
||||
int n = GetNumVectorElements(sz);
|
||||
XORPS(XMM0, R(XMM0));
|
||||
MOVSS(XMM1, M((void *) &one));
|
||||
MOVSS(XMM1, M(&one));
|
||||
u8 dregs[4];
|
||||
GetVectorRegsPrefixD(dregs, sz, _VD);
|
||||
fpr.MapRegsV(dregs, sz, MAP_NOINIT | MAP_DIRTY);
|
||||
|
@ -842,11 +842,11 @@ void Jit::Comp_VecDo3(MIPSOpcode op) {
|
|||
break;
|
||||
case 6: // vsge
|
||||
CMPNLTSS(tempxregs[i], fpr.V(tregs[i]));
|
||||
ANDPS(tempxregs[i], M((void *)&oneOneOneOne));
|
||||
ANDPS(tempxregs[i], M(&oneOneOneOne));
|
||||
break;
|
||||
case 7: // vslt
|
||||
CMPLTSS(tempxregs[i], fpr.V(tregs[i]));
|
||||
ANDPS(tempxregs[i], M((void *)&oneOneOneOne));
|
||||
ANDPS(tempxregs[i], M(&oneOneOneOne));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -903,10 +903,10 @@ void Jit::Comp_Vcmp(MIPSOpcode op) {
|
|||
static const int true_bits[4] = {0x31, 0x33, 0x37, 0x3f};
|
||||
|
||||
if (cond == VC_TR) {
|
||||
OR(32, M((void*)¤tMIPS->vfpuCtrl[VFPU_CTRL_CC]), Imm32(true_bits[n-1]));
|
||||
OR(32, M(¤tMIPS->vfpuCtrl[VFPU_CTRL_CC]), Imm32(true_bits[n-1]));
|
||||
return;
|
||||
} else if (cond == VC_FL) {
|
||||
AND(32, M((void*)¤tMIPS->vfpuCtrl[VFPU_CTRL_CC]), Imm32(~true_bits[n-1]));
|
||||
AND(32, M(¤tMIPS->vfpuCtrl[VFPU_CTRL_CC]), Imm32(~true_bits[n-1]));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -928,16 +928,16 @@ void Jit::Comp_Vcmp(MIPSOpcode op) {
|
|||
case VC_ES:
|
||||
comparison = -1; // We will do the compare up here. XMM1 will have the bits.
|
||||
MOVSS(XMM1, fpr.V(sregs[i]));
|
||||
ANDPS(XMM1, M((void *)&fourinfnan));
|
||||
PCMPEQD(XMM1, M((void *)&fourinfnan)); // Integer comparison
|
||||
ANDPS(XMM1, M(&fourinfnan));
|
||||
PCMPEQD(XMM1, M(&fourinfnan)); // Integer comparison
|
||||
break;
|
||||
|
||||
case VC_NS:
|
||||
comparison = -1; // We will do the compare up here. XMM1 will have the bits.
|
||||
MOVSS(XMM1, fpr.V(sregs[i]));
|
||||
ANDPS(XMM1, M((void *)&fourinfnan));
|
||||
PCMPEQD(XMM1, M((void *)&fourinfnan)); // Integer comparison
|
||||
XORPS(XMM1, M((void *)&solidOnes));
|
||||
ANDPS(XMM1, M(&fourinfnan));
|
||||
PCMPEQD(XMM1, M(&fourinfnan)); // Integer comparison
|
||||
XORPS(XMM1, M(&solidOnes));
|
||||
break;
|
||||
|
||||
case VC_EN:
|
||||
|
@ -1011,19 +1011,19 @@ void Jit::Comp_Vcmp(MIPSOpcode op) {
|
|||
CMPSS(XMM1, R(XMM0), comparison);
|
||||
}
|
||||
if (inverse) {
|
||||
XORPS(XMM1, M((void *)&solidOnes));
|
||||
XORPS(XMM1, M(&solidOnes));
|
||||
}
|
||||
}
|
||||
|
||||
MOVSS(M((void *) &ssCompareTemp), XMM1);
|
||||
MOVSS(M(&ssCompareTemp), XMM1);
|
||||
if (i == 0 && n == 1) {
|
||||
MOV(32, R(EAX), M((void *) &ssCompareTemp));
|
||||
MOV(32, R(EAX), M(&ssCompareTemp));
|
||||
AND(32, R(EAX), Imm32(0x31));
|
||||
} else if (i == 0) {
|
||||
MOV(32, R(EAX), M((void *) &ssCompareTemp));
|
||||
MOV(32, R(EAX), M(&ssCompareTemp));
|
||||
AND(32, R(EAX), Imm32(1 << i));
|
||||
} else {
|
||||
MOV(32, R(ECX), M((void *) &ssCompareTemp));
|
||||
MOV(32, R(ECX), M(&ssCompareTemp));
|
||||
AND(32, R(ECX), Imm32(1 << i));
|
||||
OR(32, R(EAX), R(ECX));
|
||||
}
|
||||
|
@ -1092,7 +1092,7 @@ void Jit::Comp_Vi2f(MIPSOpcode op) {
|
|||
}
|
||||
|
||||
if (*mult != 1.0f)
|
||||
MOVSS(XMM1, M((void *)mult));
|
||||
MOVSS(XMM1, M(mult));
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (fpr.V(sregs[i]).IsSimpleReg())
|
||||
MOVD_xmm(R(EAX), fpr.VX(sregs[i]));
|
||||
|
@ -1187,14 +1187,14 @@ void Jit::Comp_Vh2f(MIPSOpcode op) {
|
|||
// OK, 16 bits in each word.
|
||||
// Let's go. Deep magic here.
|
||||
MOVAPS(XMM1, R(XMM0));
|
||||
ANDPS(XMM0, M((void *)mask_nosign)); // xmm0 = expmant
|
||||
ANDPS(XMM0, M(mask_nosign)); // xmm0 = expmant
|
||||
XORPS(XMM1, R(XMM0)); // xmm1 = justsign = expmant ^ xmm0
|
||||
MOVAPS(tempR, R(XMM0));
|
||||
PCMPGTD(tempR, M((void *)was_infnan)); // xmm2 = b_wasinfnan
|
||||
PCMPGTD(tempR, M(was_infnan)); // xmm2 = b_wasinfnan
|
||||
PSLLD(XMM0, 13);
|
||||
MULPS(XMM0, M((void *)magic)); /// xmm0 = scaled
|
||||
MULPS(XMM0, M(magic)); /// xmm0 = scaled
|
||||
PSLLD(XMM1, 16); // xmm1 = sign
|
||||
ANDPS(tempR, M((void *)exp_infnan));
|
||||
ANDPS(tempR, M(exp_infnan));
|
||||
ORPS(XMM1, R(tempR));
|
||||
ORPS(XMM0, R(XMM1));
|
||||
|
||||
|
@ -1340,7 +1340,7 @@ void Jit::Comp_Vf2i(MIPSOpcode op) {
|
|||
}
|
||||
|
||||
if (*mult != 1.0f)
|
||||
MOVSD(XMM1, M((void *)mult));
|
||||
MOVSD(XMM1, M(mult));
|
||||
|
||||
fpr.MapRegsV(tempregs, sz, MAP_DIRTY | MAP_NOINIT);
|
||||
for (int i = 0; i < n; i++) {
|
||||
|
@ -1351,8 +1351,8 @@ void Jit::Comp_Vf2i(MIPSOpcode op) {
|
|||
if (*mult != 1.0f) {
|
||||
MULSD(XMM0, R(XMM1));
|
||||
}
|
||||
MINSD(XMM0, M((void *)&maxIntAsDouble));
|
||||
MAXSD(XMM0, M((void *)&minIntAsDouble));
|
||||
MINSD(XMM0, M(&maxIntAsDouble));
|
||||
MAXSD(XMM0, M(&minIntAsDouble));
|
||||
switch ((op >> 21) & 0x1f) {
|
||||
case 16: /* TODO */ break; //n (round_vfpu_n causes issue #3011 but seems right according to tests...)
|
||||
case 17: CVTTSD2SI(EAX, R(XMM0)); break; //z - truncate
|
||||
|
@ -1388,7 +1388,7 @@ void Jit::Comp_Vcst(MIPSOpcode op) {
|
|||
u8 dregs[4];
|
||||
GetVectorRegsPrefixD(dregs, sz, _VD);
|
||||
|
||||
MOVSS(XMM0, M((void *)&cst_constants[conNum]));
|
||||
MOVSS(XMM0, M(&cst_constants[conNum]));
|
||||
fpr.MapRegsV(dregs, sz, MAP_NOINIT | MAP_DIRTY);
|
||||
for (int i = 0; i < n; i++) {
|
||||
MOVSS(fpr.V(dregs[i]), XMM0);
|
||||
|
@ -1434,8 +1434,8 @@ void Jit::Comp_Vsgn(MIPSOpcode op) {
|
|||
CMPEQSS(XMM0, fpr.V(sregs[i])); // XMM0 = s[i] == 0.0f
|
||||
MOVSS(XMM1, fpr.V(sregs[i]));
|
||||
// Preserve sign bit, replace rest with ones
|
||||
ANDPS(XMM1, M((void *)&signBitLower));
|
||||
ORPS(XMM1, M((void *)&oneOneOneOne));
|
||||
ANDPS(XMM1, M(&signBitLower));
|
||||
ORPS(XMM1, M(&oneOneOneOne));
|
||||
// If really was equal to zero, zap. Note that ANDN negates the destination.
|
||||
ANDNPS(XMM0, R(XMM1));
|
||||
MOVAPS(tempxregs[i], R(XMM0));
|
||||
|
@ -1482,7 +1482,7 @@ void Jit::Comp_Vocp(MIPSOpcode op) {
|
|||
}
|
||||
}
|
||||
|
||||
MOVSS(XMM1, M((void *)&one));
|
||||
MOVSS(XMM1, M(&one));
|
||||
for (int i = 0; i < n; ++i)
|
||||
{
|
||||
MOVSS(XMM0, R(XMM1));
|
||||
|
@ -1550,35 +1550,35 @@ void Jit::Comp_VV2Op(MIPSOpcode op) {
|
|||
case 1: // d[i] = fabsf(s[i]); break; //vabs
|
||||
if (!fpr.V(sregs[i]).IsSimpleReg(tempxregs[i]))
|
||||
MOVSS(tempxregs[i], fpr.V(sregs[i]));
|
||||
ANDPS(tempxregs[i], M((void *)&noSignMask));
|
||||
ANDPS(tempxregs[i], M(&noSignMask));
|
||||
break;
|
||||
case 2: // d[i] = -s[i]; break; //vneg
|
||||
if (!fpr.V(sregs[i]).IsSimpleReg(tempxregs[i]))
|
||||
MOVSS(tempxregs[i], fpr.V(sregs[i]));
|
||||
XORPS(tempxregs[i], M((void *)&signBitLower));
|
||||
XORPS(tempxregs[i], M(&signBitLower));
|
||||
break;
|
||||
case 4: // if (s[i] < 0) d[i] = 0; else {if(s[i] > 1.0f) d[i] = 1.0f; else d[i] = s[i];} break; // vsat0
|
||||
if (!fpr.V(sregs[i]).IsSimpleReg(tempxregs[i]))
|
||||
MOVSS(tempxregs[i], fpr.V(sregs[i]));
|
||||
// TODO: Doesn't handle NaN correctly.
|
||||
MAXSS(tempxregs[i], M((void *)&zero));
|
||||
MINSS(tempxregs[i], M((void *)&one));
|
||||
MAXSS(tempxregs[i], M(&zero));
|
||||
MINSS(tempxregs[i], M(&one));
|
||||
break;
|
||||
case 5: // if (s[i] < -1.0f) d[i] = -1.0f; else {if(s[i] > 1.0f) d[i] = 1.0f; else d[i] = s[i];} break; // vsat1
|
||||
if (!fpr.V(sregs[i]).IsSimpleReg(tempxregs[i]))
|
||||
MOVSS(tempxregs[i], fpr.V(sregs[i]));
|
||||
// TODO: Doesn't handle NaN correctly.
|
||||
MAXSS(tempxregs[i], M((void *)&minus_one));
|
||||
MINSS(tempxregs[i], M((void *)&one));
|
||||
MAXSS(tempxregs[i], M(&minus_one));
|
||||
MINSS(tempxregs[i], M(&one));
|
||||
break;
|
||||
case 16: // d[i] = 1.0f / s[i]; break; //vrcp
|
||||
MOVSS(XMM0, M((void *)&one));
|
||||
MOVSS(XMM0, M(&one));
|
||||
DIVSS(XMM0, fpr.V(sregs[i]));
|
||||
MOVSS(tempxregs[i], R(XMM0));
|
||||
break;
|
||||
case 17: // d[i] = 1.0f / sqrtf(s[i]); break; //vrsq
|
||||
SQRTSS(XMM0, fpr.V(sregs[i]));
|
||||
MOVSS(tempxregs[i], M((void *)&one));
|
||||
MOVSS(tempxregs[i], M(&one));
|
||||
DIVSS(tempxregs[i], R(XMM0));
|
||||
break;
|
||||
case 18: // d[i] = sinf((float)M_PI_2 * s[i]); break; //vsin
|
||||
|
@ -1595,13 +1595,13 @@ void Jit::Comp_VV2Op(MIPSOpcode op) {
|
|||
break;
|
||||
case 22: // d[i] = sqrtf(s[i]); break; //vsqrt
|
||||
SQRTSS(tempxregs[i], fpr.V(sregs[i]));
|
||||
ANDPS(tempxregs[i], M((void *)&noSignMask));
|
||||
ANDPS(tempxregs[i], M(&noSignMask));
|
||||
break;
|
||||
case 23: // d[i] = asinf(s[i] * (float)M_2_PI); break; //vasin
|
||||
DISABLE;
|
||||
break;
|
||||
case 24: // d[i] = -1.0f / s[i]; break; // vnrcp
|
||||
MOVSS(XMM0, M((void *)&minus_one));
|
||||
MOVSS(XMM0, M(&minus_one));
|
||||
DIVSS(XMM0, fpr.V(sregs[i]));
|
||||
MOVSS(tempxregs[i], R(XMM0));
|
||||
break;
|
||||
|
@ -1711,8 +1711,8 @@ void Jit::Comp_VMatrixInit(MIPSOpcode op) {
|
|||
|
||||
switch ((op >> 16) & 0xF) {
|
||||
case 3: // vmidt
|
||||
MOVSS(XMM0, M((void *) &zero));
|
||||
MOVSS(XMM1, M((void *) &one));
|
||||
MOVSS(XMM0, M(&zero));
|
||||
MOVSS(XMM1, M(&one));
|
||||
for (int a = 0; a < n; a++) {
|
||||
for (int b = 0; b < n; b++) {
|
||||
MOVSS(fpr.V(dregs[a * 4 + b]), a == b ? XMM1 : XMM0);
|
||||
|
@ -1720,7 +1720,7 @@ void Jit::Comp_VMatrixInit(MIPSOpcode op) {
|
|||
}
|
||||
break;
|
||||
case 6: // vmzero
|
||||
MOVSS(XMM0, M((void *) &zero));
|
||||
MOVSS(XMM0, M(&zero));
|
||||
for (int a = 0; a < n; a++) {
|
||||
for (int b = 0; b < n; b++) {
|
||||
MOVSS(fpr.V(dregs[a * 4 + b]), XMM0);
|
||||
|
@ -1728,7 +1728,7 @@ void Jit::Comp_VMatrixInit(MIPSOpcode op) {
|
|||
}
|
||||
break;
|
||||
case 7: // vmone
|
||||
MOVSS(XMM0, M((void *) &one));
|
||||
MOVSS(XMM0, M(&one));
|
||||
for (int a = 0; a < n; a++) {
|
||||
for (int b = 0; b < n; b++) {
|
||||
MOVSS(fpr.V(dregs[a * 4 + b]), XMM0);
|
||||
|
@ -2121,10 +2121,10 @@ void Jit::Comp_VRot(MIPSOpcode op) {
|
|||
|
||||
#ifdef _M_X64
|
||||
MOVSS(XMM0, fpr.V(sreg));
|
||||
ABI_CallFunction(negSin ? (void *)&SinCosNegSin : (void *)&SinCos);
|
||||
ABI_CallFunction(negSin ? (const void *)&SinCosNegSin : (const void *)&SinCos);
|
||||
#else
|
||||
// Sigh, passing floats with cdecl isn't pretty, ends up on the stack.
|
||||
ABI_CallFunctionA(negSin ? (void *)&SinCosNegSin : (void *)&SinCos, fpr.V(sreg));
|
||||
ABI_CallFunctionA(negSin ? (const void *)&SinCosNegSin : (const void *)&SinCos, fpr.V(sreg));
|
||||
#endif
|
||||
|
||||
MOVSS(XMM0, M(&sincostemp[0]));
|
||||
|
|
|
@ -184,19 +184,19 @@ void Jit::FlushPrefixV()
|
|||
{
|
||||
if ((js.prefixSFlag & JitState::PREFIX_DIRTY) != 0)
|
||||
{
|
||||
MOV(32, M((void *)&mips_->vfpuCtrl[VFPU_CTRL_SPREFIX]), Imm32(js.prefixS));
|
||||
MOV(32, M(&mips_->vfpuCtrl[VFPU_CTRL_SPREFIX]), Imm32(js.prefixS));
|
||||
js.prefixSFlag = (JitState::PrefixState) (js.prefixSFlag & ~JitState::PREFIX_DIRTY);
|
||||
}
|
||||
|
||||
if ((js.prefixTFlag & JitState::PREFIX_DIRTY) != 0)
|
||||
{
|
||||
MOV(32, M((void *)&mips_->vfpuCtrl[VFPU_CTRL_TPREFIX]), Imm32(js.prefixT));
|
||||
MOV(32, M(&mips_->vfpuCtrl[VFPU_CTRL_TPREFIX]), Imm32(js.prefixT));
|
||||
js.prefixTFlag = (JitState::PrefixState) (js.prefixTFlag & ~JitState::PREFIX_DIRTY);
|
||||
}
|
||||
|
||||
if ((js.prefixDFlag & JitState::PREFIX_DIRTY) != 0)
|
||||
{
|
||||
MOV(32, M((void *)&mips_->vfpuCtrl[VFPU_CTRL_DPREFIX]), Imm32(js.prefixD));
|
||||
MOV(32, M(&mips_->vfpuCtrl[VFPU_CTRL_DPREFIX]), Imm32(js.prefixD));
|
||||
js.prefixDFlag = (JitState::PrefixState) (js.prefixDFlag & ~JitState::PREFIX_DIRTY);
|
||||
}
|
||||
}
|
||||
|
@ -333,7 +333,7 @@ const u8 *Jit::DoJit(u32 em_address, JitBlock *b)
|
|||
// If we're rewinding, CORE_NEXTFRAME should not cause a rewind.
|
||||
// It doesn't really matter either way if we're not rewinding.
|
||||
// CORE_RUNNING is <= CORE_NEXTFRAME.
|
||||
CMP(32, M((void*)&coreState), Imm32(CORE_NEXTFRAME));
|
||||
CMP(32, M(&coreState), Imm32(CORE_NEXTFRAME));
|
||||
FixupBranch skipCheck = J_CC(CC_LE);
|
||||
if (js.afterOp & JitState::AFTER_REWIND_PC_BAD_STATE)
|
||||
MOV(32, M(&mips_->pc), Imm32(js.compilerPC));
|
||||
|
@ -464,7 +464,7 @@ void Jit::Comp_ReplacementFunc(MIPSOpcode op)
|
|||
|
||||
// Standard function call, nothing fancy.
|
||||
// The function returns the number of cycles it took in EAX.
|
||||
ABI_CallFunction((void *)entry->replaceFunc);
|
||||
ABI_CallFunction(entry->replaceFunc);
|
||||
// Alternatively, we could inline it here, instead of calling out, if it's a function
|
||||
// we can emit.
|
||||
|
||||
|
@ -489,9 +489,9 @@ void Jit::Comp_Generic(MIPSOpcode op)
|
|||
{
|
||||
MOV(32, M(&mips_->pc), Imm32(js.compilerPC));
|
||||
if (USE_JIT_MISSMAP)
|
||||
ABI_CallFunctionC((void *)&JitLogMiss, op.encoding);
|
||||
ABI_CallFunctionC(&JitLogMiss, op.encoding);
|
||||
else
|
||||
ABI_CallFunctionC((void *)func, op.encoding);
|
||||
ABI_CallFunctionC(func, op.encoding);
|
||||
}
|
||||
else
|
||||
ERROR_LOG_REPORT(JIT, "Trying to compile instruction %08x that can't be interpreted", op.encoding);
|
||||
|
@ -516,7 +516,7 @@ void Jit::WriteExit(u32 destination, int exit_num)
|
|||
if (js.afterOp & (JitState::AFTER_CORE_STATE | JitState::AFTER_REWIND_PC_BAD_STATE))
|
||||
{
|
||||
// CORE_RUNNING is <= CORE_NEXTFRAME.
|
||||
CMP(32, M((void*)&coreState), Imm32(CORE_NEXTFRAME));
|
||||
CMP(32, M(&coreState), Imm32(CORE_NEXTFRAME));
|
||||
FixupBranch skipCheck = J_CC(CC_LE);
|
||||
MOV(32, M(&mips_->pc), Imm32(js.compilerPC));
|
||||
WriteSyscallExit();
|
||||
|
@ -554,7 +554,7 @@ void Jit::WriteExitDestInReg(X64Reg reg)
|
|||
if (js.afterOp & (JitState::AFTER_CORE_STATE | JitState::AFTER_REWIND_PC_BAD_STATE))
|
||||
{
|
||||
// CORE_RUNNING is <= CORE_NEXTFRAME.
|
||||
CMP(32, M((void*)&coreState), Imm32(CORE_NEXTFRAME));
|
||||
CMP(32, M(&coreState), Imm32(CORE_NEXTFRAME));
|
||||
FixupBranch skipCheck = J_CC(CC_LE);
|
||||
MOV(32, M(&mips_->pc), Imm32(js.compilerPC));
|
||||
WriteSyscallExit();
|
||||
|
@ -580,13 +580,13 @@ void Jit::WriteExitDestInReg(X64Reg reg)
|
|||
SetJumpTarget(tooLow);
|
||||
SetJumpTarget(tooHigh);
|
||||
|
||||
CallProtectedFunction((void *) Memory::GetPointer, R(reg));
|
||||
CallProtectedFunction(Memory::GetPointer, R(reg));
|
||||
CMP(32, R(reg), Imm32(0));
|
||||
FixupBranch skip = J_CC(CC_NE);
|
||||
|
||||
// TODO: "Ignore" this so other threads can continue?
|
||||
if (g_Config.bIgnoreBadMemAccess)
|
||||
CallProtectedFunction((void *) Core_UpdateState, Imm32(CORE_ERROR));
|
||||
CallProtectedFunction(Core_UpdateState, Imm32(CORE_ERROR));
|
||||
|
||||
SUB(32, M(¤tMIPS->downcount), Imm32(0));
|
||||
JMP(asm_.dispatcherCheckCoreState, true);
|
||||
|
@ -612,7 +612,7 @@ bool Jit::CheckJitBreakpoint(u32 addr, int downcountOffset)
|
|||
SAVE_FLAGS;
|
||||
FlushAll();
|
||||
MOV(32, M(&mips_->pc), Imm32(js.compilerPC));
|
||||
ABI_CallFunction((void *)&JitBreakpoint);
|
||||
ABI_CallFunction(&JitBreakpoint);
|
||||
|
||||
// If 0, the conditional breakpoint wasn't taken.
|
||||
CMP(32, R(EAX), Imm32(0));
|
||||
|
@ -809,7 +809,7 @@ bool Jit::JitSafeMem::PrepareSlowWrite()
|
|||
return false;
|
||||
}
|
||||
|
||||
void Jit::JitSafeMem::DoSlowWrite(void *safeFunc, const OpArg src, int suboffset)
|
||||
void Jit::JitSafeMem::DoSlowWrite(const void *safeFunc, const OpArg src, int suboffset)
|
||||
{
|
||||
if (iaddr_ != (u32) -1)
|
||||
jit_->MOV(32, R(EAX), Imm32((iaddr_ + suboffset) & alignMask_));
|
||||
|
@ -824,7 +824,7 @@ void Jit::JitSafeMem::DoSlowWrite(void *safeFunc, const OpArg src, int suboffset
|
|||
needsCheck_ = true;
|
||||
}
|
||||
|
||||
bool Jit::JitSafeMem::PrepareSlowRead(void *safeFunc)
|
||||
bool Jit::JitSafeMem::PrepareSlowRead(const void *safeFunc)
|
||||
{
|
||||
if (!fast_)
|
||||
{
|
||||
|
@ -851,7 +851,7 @@ bool Jit::JitSafeMem::PrepareSlowRead(void *safeFunc)
|
|||
return false;
|
||||
}
|
||||
|
||||
void Jit::JitSafeMem::NextSlowRead(void *safeFunc, int suboffset)
|
||||
void Jit::JitSafeMem::NextSlowRead(const void *safeFunc, int suboffset)
|
||||
{
|
||||
_dbg_assert_msg_(JIT, !fast_, "NextSlowRead() called in fast memory mode?");
|
||||
|
||||
|
@ -916,10 +916,10 @@ void Jit::JitSafeMem::MemCheckImm(ReadType type)
|
|||
return;
|
||||
|
||||
jit_->MOV(32, M(&jit_->mips_->pc), Imm32(jit_->js.compilerPC));
|
||||
jit_->CallProtectedFunction((void *)&JitMemCheck, iaddr_, size_, type == MEM_WRITE ? 1 : 0);
|
||||
jit_->CallProtectedFunction(&JitMemCheck, iaddr_, size_, type == MEM_WRITE ? 1 : 0);
|
||||
|
||||
// CORE_RUNNING is <= CORE_NEXTFRAME.
|
||||
jit_->CMP(32, M((void*)&coreState), Imm32(CORE_NEXTFRAME));
|
||||
jit_->CMP(32, M(&coreState), Imm32(CORE_NEXTFRAME));
|
||||
skipChecks_.push_back(jit_->J_CC(CC_G, true));
|
||||
jit_->js.afterOp |= JitState::AFTER_CORE_STATE | JitState::AFTER_REWIND_PC_BAD_STATE;
|
||||
}
|
||||
|
@ -957,7 +957,7 @@ void Jit::JitSafeMem::MemCheckAsm(ReadType type)
|
|||
jit_->PUSH(xaddr_);
|
||||
jit_->MOV(32, M(&jit_->mips_->pc), Imm32(jit_->js.compilerPC));
|
||||
jit_->ADD(32, R(xaddr_), Imm32(offset_));
|
||||
jit_->CallProtectedFunction((void *)&JitMemCheck, R(xaddr_), size_, type == MEM_WRITE ? 1 : 0);
|
||||
jit_->CallProtectedFunction(&JitMemCheck, R(xaddr_), size_, type == MEM_WRITE ? 1 : 0);
|
||||
for (int i = 0; i < 4; ++i)
|
||||
jit_->POP(xaddr_);
|
||||
|
||||
|
@ -969,38 +969,38 @@ void Jit::JitSafeMem::MemCheckAsm(ReadType type)
|
|||
if (possible)
|
||||
{
|
||||
// CORE_RUNNING is <= CORE_NEXTFRAME.
|
||||
jit_->CMP(32, M((void*)&coreState), Imm32(CORE_NEXTFRAME));
|
||||
jit_->CMP(32, M(&coreState), Imm32(CORE_NEXTFRAME));
|
||||
skipChecks_.push_back(jit_->J_CC(CC_G, true));
|
||||
jit_->js.afterOp |= JitState::AFTER_CORE_STATE | JitState::AFTER_REWIND_PC_BAD_STATE;
|
||||
}
|
||||
}
|
||||
|
||||
void Jit::CallProtectedFunction(void *func, const OpArg &arg1)
|
||||
void Jit::CallProtectedFunction(const void *func, const OpArg &arg1)
|
||||
{
|
||||
// We don't regcache RCX, so the below is safe (and also faster, maybe branch prediction?)
|
||||
ABI_CallFunctionA(thunks.ProtectFunction(func, 1), arg1);
|
||||
}
|
||||
|
||||
void Jit::CallProtectedFunction(void *func, const OpArg &arg1, const OpArg &arg2)
|
||||
void Jit::CallProtectedFunction(const void *func, const OpArg &arg1, const OpArg &arg2)
|
||||
{
|
||||
// We don't regcache RCX/RDX, so the below is safe (and also faster, maybe branch prediction?)
|
||||
ABI_CallFunctionAA(thunks.ProtectFunction(func, 2), arg1, arg2);
|
||||
}
|
||||
|
||||
void Jit::CallProtectedFunction(void *func, const u32 arg1, const u32 arg2, const u32 arg3)
|
||||
void Jit::CallProtectedFunction(const void *func, const u32 arg1, const u32 arg2, const u32 arg3)
|
||||
{
|
||||
// On x64, we need to save R8, which is caller saved.
|
||||
ABI_CallFunction((void *)thunks.GetSaveRegsFunction());
|
||||
ABI_CallFunction(thunks.GetSaveRegsFunction());
|
||||
ABI_CallFunctionCCC(func, arg1, arg2, arg3);
|
||||
ABI_CallFunction((void *)thunks.GetLoadRegsFunction());
|
||||
ABI_CallFunction(thunks.GetLoadRegsFunction());
|
||||
}
|
||||
|
||||
void Jit::CallProtectedFunction(void *func, const OpArg &arg1, const u32 arg2, const u32 arg3)
|
||||
void Jit::CallProtectedFunction(const void *func, const OpArg &arg1, const u32 arg2, const u32 arg3)
|
||||
{
|
||||
// On x64, we need to save R8, which is caller saved.
|
||||
ABI_CallFunction((void *)thunks.GetSaveRegsFunction());
|
||||
ABI_CallFunction(thunks.GetSaveRegsFunction());
|
||||
ABI_CallFunctionACC(func, arg1, arg2, arg3);
|
||||
ABI_CallFunction((void *)thunks.GetLoadRegsFunction());
|
||||
ABI_CallFunction(thunks.GetLoadRegsFunction());
|
||||
}
|
||||
|
||||
void Jit::Comp_DoNothing(MIPSOpcode op) { }
|
||||
|
|
|
@ -202,8 +202,16 @@ private:
|
|||
void CompTriArith(MIPSOpcode op, void (XEmitter::*arith)(int, const OpArg &, const OpArg &), u32 (*doImm)(const u32, const u32));
|
||||
void CompShiftImm(MIPSOpcode op, void (XEmitter::*shift)(int, OpArg, OpArg), u32 (*doImm)(const u32, const u32));
|
||||
void CompShiftVar(MIPSOpcode op, void (XEmitter::*shift)(int, OpArg, OpArg), u32 (*doImm)(const u32, const u32));
|
||||
void CompITypeMemRead(MIPSOpcode op, u32 bits, void (XEmitter::*mov)(int, int, X64Reg, OpArg), void *safeFunc);
|
||||
void CompITypeMemWrite(MIPSOpcode op, u32 bits, void *safeFunc);
|
||||
void CompITypeMemRead(MIPSOpcode op, u32 bits, void (XEmitter::*mov)(int, int, X64Reg, OpArg), const void *safeFunc);
|
||||
template <typename T>
|
||||
void CompITypeMemRead(MIPSOpcode op, u32 bits, void (XEmitter::*mov)(int, int, X64Reg, OpArg), T (*safeFunc)(u32 addr)) {
|
||||
CompITypeMemRead(op, bits, mov, (const void *)safeFunc);
|
||||
}
|
||||
void CompITypeMemWrite(MIPSOpcode op, u32 bits, const void *safeFunc);
|
||||
template <typename T>
|
||||
void CompITypeMemWrite(MIPSOpcode op, u32 bits, void (*safeFunc)(T val, u32 addr)) {
|
||||
CompITypeMemWrite(op, bits, (const void *)safeFunc);
|
||||
}
|
||||
void CompITypeMemUnpairedLR(MIPSOpcode op, bool isStore);
|
||||
void CompITypeMemUnpairedLRInner(MIPSOpcode op, X64Reg shiftReg);
|
||||
void CompBranchExits(CCFlags cc, u32 targetAddr, u32 notTakenAddr, bool delaySlotIsNice, bool likely, bool andLink);
|
||||
|
@ -211,10 +219,30 @@ private:
|
|||
void CompFPTriArith(MIPSOpcode op, void (XEmitter::*arith)(X64Reg reg, OpArg), bool orderMatters);
|
||||
void CompFPComp(int lhs, int rhs, u8 compare, bool allowNaN = false);
|
||||
|
||||
void CallProtectedFunction(void *func, const OpArg &arg1);
|
||||
void CallProtectedFunction(void *func, const OpArg &arg1, const OpArg &arg2);
|
||||
void CallProtectedFunction(void *func, const u32 arg1, const u32 arg2, const u32 arg3);
|
||||
void CallProtectedFunction(void *func, const OpArg &arg1, const u32 arg2, const u32 arg3);
|
||||
void CallProtectedFunction(const void *func, const OpArg &arg1);
|
||||
void CallProtectedFunction(const void *func, const OpArg &arg1, const OpArg &arg2);
|
||||
void CallProtectedFunction(const void *func, const u32 arg1, const u32 arg2, const u32 arg3);
|
||||
void CallProtectedFunction(const void *func, const OpArg &arg1, const u32 arg2, const u32 arg3);
|
||||
|
||||
template <typename Tr, typename T1>
|
||||
void CallProtectedFunction(Tr (*func)(T1), const OpArg &arg1) {
|
||||
CallProtectedFunction((const void *)func, arg1);
|
||||
}
|
||||
|
||||
template <typename Tr, typename T1, typename T2>
|
||||
void CallProtectedFunction(Tr (*func)(T1, T2), const OpArg &arg1, const OpArg &arg2) {
|
||||
CallProtectedFunction((const void *)func, arg1, arg2);
|
||||
}
|
||||
|
||||
template <typename Tr, typename T1, typename T2, typename T3>
|
||||
void CallProtectedFunction(Tr (*func)(T1, T2, T3), const u32 arg1, const u32 arg2, const u32 arg3) {
|
||||
CallProtectedFunction((const void *)func, arg1, arg2, arg3);
|
||||
}
|
||||
|
||||
template <typename Tr, typename T1, typename T2, typename T3>
|
||||
void CallProtectedFunction(Tr (*func)(T1, T2, T3), const OpArg &arg1, const u32 arg2, const u32 arg3) {
|
||||
CallProtectedFunction((const void *)func, arg1, arg2, arg3);
|
||||
}
|
||||
|
||||
bool PredictTakeBranch(u32 targetAddr, bool likely);
|
||||
bool CanContinueBranch() {
|
||||
|
@ -249,12 +277,20 @@ private:
|
|||
// Emit code proceeding a slow write call, returns true if slow write is needed.
|
||||
bool PrepareSlowWrite();
|
||||
// Emit a slow write from src.
|
||||
void DoSlowWrite(void *safeFunc, const OpArg src, int suboffset = 0);
|
||||
void DoSlowWrite(const void *safeFunc, const OpArg src, int suboffset = 0);
|
||||
template <typename T>
|
||||
void DoSlowWrite(void (*safeFunc)(T val, u32 addr), const OpArg src, int suboffset = 0) {
|
||||
DoSlowWrite((const void *)safeFunc, src, suboffset);
|
||||
}
|
||||
|
||||
// Emit code necessary for a memory read, returns true if MOV from src is needed.
|
||||
bool PrepareRead(OpArg &src, int size);
|
||||
// Emit code for a slow read call, and returns true if result is in EAX.
|
||||
bool PrepareSlowRead(void *safeFunc);
|
||||
bool PrepareSlowRead(const void *safeFunc);
|
||||
template <typename T>
|
||||
bool PrepareSlowRead(T (*safeFunc)(u32 addr)) {
|
||||
return PrepareSlowRead((const void *)safeFunc);
|
||||
}
|
||||
|
||||
// Cleans up final code for the memory access.
|
||||
void Finish();
|
||||
|
@ -264,7 +300,11 @@ private:
|
|||
// WARNING: Only works for non-GPR. Do not use for reads into GPR.
|
||||
OpArg NextFastAddress(int suboffset);
|
||||
// WARNING: Only works for non-GPR. Do not use for reads into GPR.
|
||||
void NextSlowRead(void *safeFunc, int suboffset);
|
||||
void NextSlowRead(const void *safeFunc, int suboffset);
|
||||
template <typename T>
|
||||
void NextSlowRead(T (*safeFunc)(u32 addr), int suboffset) {
|
||||
NextSlowRead((const void *)safeFunc, suboffset);
|
||||
}
|
||||
|
||||
private:
|
||||
enum ReadType {
|
||||
|
|
|
@ -177,19 +177,19 @@ JittedVertexDecoder VertexDecoderJitCache::Compile(const VertexDecoder &dec) {
|
|||
int boneCount = 0;
|
||||
if (dec.weighttype && g_Config.bSoftwareSkinning) {
|
||||
for (int i = 0; i < 8; i++) {
|
||||
MOVUPS(XMM0, M((void *)(gstate.boneMatrix + 12 * i)));
|
||||
MOVUPS(XMM1, M((void *)(gstate.boneMatrix + 12 * i + 3)));
|
||||
MOVUPS(XMM2, M((void *)(gstate.boneMatrix + 12 * i + 3 * 2)));
|
||||
MOVUPS(XMM3, M((void *)(gstate.boneMatrix + 12 * i + 3 * 3)));
|
||||
ANDPS(XMM0, M((void *)&threeMasks));
|
||||
ANDPS(XMM1, M((void *)&threeMasks));
|
||||
ANDPS(XMM2, M((void *)&threeMasks));
|
||||
ANDPS(XMM3, M((void *)&threeMasks));
|
||||
ORPS(XMM3, M((void *)&aOne));
|
||||
MOVAPS(M((void *)(bones + 16 * i)), XMM0);
|
||||
MOVAPS(M((void *)(bones + 16 * i + 4)), XMM1);
|
||||
MOVAPS(M((void *)(bones + 16 * i + 8)), XMM2);
|
||||
MOVAPS(M((void *)(bones + 16 * i + 12)), XMM3);
|
||||
MOVUPS(XMM0, M((gstate.boneMatrix + 12 * i)));
|
||||
MOVUPS(XMM1, M((gstate.boneMatrix + 12 * i + 3)));
|
||||
MOVUPS(XMM2, M((gstate.boneMatrix + 12 * i + 3 * 2)));
|
||||
MOVUPS(XMM3, M((gstate.boneMatrix + 12 * i + 3 * 3)));
|
||||
ANDPS(XMM0, M(&threeMasks));
|
||||
ANDPS(XMM1, M(&threeMasks));
|
||||
ANDPS(XMM2, M(&threeMasks));
|
||||
ANDPS(XMM3, M(&threeMasks));
|
||||
ORPS(XMM3, M(&aOne));
|
||||
MOVAPS(M((bones + 16 * i)), XMM0);
|
||||
MOVAPS(M((bones + 16 * i + 4)), XMM1);
|
||||
MOVAPS(M((bones + 16 * i + 8)), XMM2);
|
||||
MOVAPS(M((bones + 16 * i + 12)), XMM3);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -204,9 +204,9 @@ JittedVertexDecoder VertexDecoderJitCache::Compile(const VertexDecoder &dec) {
|
|||
MOVSS(fpScratchReg, MDisp(tempReg1, 4));
|
||||
UNPCKLPS(fpScaleOffsetReg, R(fpScratchReg));
|
||||
if ((dec.VertexType() & GE_VTYPE_TC_MASK) == GE_VTYPE_TC_8BIT) {
|
||||
MULPS(fpScaleOffsetReg, M((void *)&by128));
|
||||
MULPS(fpScaleOffsetReg, M(&by128));
|
||||
} else if ((dec.VertexType() & GE_VTYPE_TC_MASK) == GE_VTYPE_TC_16BIT) {
|
||||
MULPS(fpScaleOffsetReg, M((void *)&by32768));
|
||||
MULPS(fpScaleOffsetReg, M(&by32768));
|
||||
}
|
||||
MOVSS(fpScratchReg, MDisp(tempReg1, 8));
|
||||
MOVSS(fpScratchReg2, MDisp(tempReg1, 12));
|
||||
|
@ -349,7 +349,7 @@ void VertexDecoderJitCache::Jit_WeightsU8Skin() {
|
|||
for (int j = 0; j < dec_->nweights; j++) {
|
||||
MOVZX(32, 8, tempReg1, MDisp(srcReg, dec_->weightoff + j));
|
||||
CVTSI2SS(XMM1, R(tempReg1));
|
||||
MULSS(XMM1, M((void *)&by128));
|
||||
MULSS(XMM1, M(&by128));
|
||||
SHUFPS(XMM1, R(XMM1), _MM_SHUFFLE(0, 0, 0, 0));
|
||||
if (j == 0) {
|
||||
MOVAPS(XMM4, MDisp(tempReg2, 0));
|
||||
|
@ -387,7 +387,7 @@ void VertexDecoderJitCache::Jit_WeightsU16Skin() {
|
|||
for (int j = 0; j < dec_->nweights; j++) {
|
||||
MOVZX(32, 16, tempReg1, MDisp(srcReg, dec_->weightoff + j * 2));
|
||||
CVTSI2SS(XMM1, R(tempReg1));
|
||||
MULSS(XMM1, M((void *)&by32768));
|
||||
MULSS(XMM1, M(&by32768));
|
||||
SHUFPS(XMM1, R(XMM1), _MM_SHUFFLE(0, 0, 0, 0));
|
||||
if (j == 0) {
|
||||
MOVAPS(XMM4, MDisp(tempReg2, 0));
|
||||
|
@ -559,7 +559,7 @@ void VertexDecoderJitCache::Jit_Color4444() {
|
|||
// Alternate approach
|
||||
MOVD_xmm(XMM3, MDisp(srcReg, dec_->coloff));
|
||||
MOVAPS(XMM2, R(XMM3));
|
||||
MOVAPS(XMM1, M((void *)nibbles));
|
||||
MOVAPS(XMM1, M(nibbles));
|
||||
PSLLD(XMM2, 4);
|
||||
PAND(XMM3, R(XMM1));
|
||||
PAND(XMM2, R(XMM1));
|
||||
|
@ -732,7 +732,7 @@ void VertexDecoderJitCache::Jit_NormalS8Skin() {
|
|||
PSLLD(XMM1, 24);
|
||||
PSRAD(XMM1, 24); // Ugly sign extension, can be done faster in SSE4
|
||||
CVTDQ2PS(XMM3, R(XMM1));
|
||||
MULPS(XMM3, M((void *)&by128));
|
||||
MULPS(XMM3, M(&by128));
|
||||
Jit_WriteMatrixMul(dec_->decFmt.nrmoff, false);
|
||||
}
|
||||
|
||||
|
@ -744,7 +744,7 @@ void VertexDecoderJitCache::Jit_NormalS16Skin() {
|
|||
PSLLD(XMM1, 16);
|
||||
PSRAD(XMM1, 16); // Ugly sign extension, can be done faster in SSE4
|
||||
CVTDQ2PS(XMM3, R(XMM1));
|
||||
MULPS(XMM3, M((void *)&by32768));
|
||||
MULPS(XMM3, M(&by32768));
|
||||
Jit_WriteMatrixMul(dec_->decFmt.nrmoff, false);
|
||||
}
|
||||
|
||||
|
@ -807,7 +807,7 @@ void VertexDecoderJitCache::Jit_PosS8Skin() {
|
|||
PSLLD(XMM1, 24);
|
||||
PSRAD(XMM1, 24); // Ugly sign extension, can be done faster in SSE4
|
||||
CVTDQ2PS(XMM3, R(XMM1));
|
||||
MULPS(XMM3, M((void *)&by128));
|
||||
MULPS(XMM3, M(&by128));
|
||||
Jit_WriteMatrixMul(dec_->decFmt.posoff, true);
|
||||
}
|
||||
|
||||
|
@ -818,7 +818,7 @@ void VertexDecoderJitCache::Jit_PosS16Skin() {
|
|||
PSLLD(XMM1, 16);
|
||||
PSRAD(XMM1, 16); // Ugly sign extension, can be done faster in SSE4
|
||||
CVTDQ2PS(XMM3, R(XMM1));
|
||||
MULPS(XMM3, M((void *)&by32768));
|
||||
MULPS(XMM3, M(&by32768));
|
||||
Jit_WriteMatrixMul(dec_->decFmt.posoff, true);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue