x86jit: Use templates to avoid some void * casts.

Makes it a bit cleaner and potentially safer.
This commit is contained in:
Unknown W. Brackets 2014-01-18 09:57:13 -08:00
parent da97a67526
commit 2347498667
14 changed files with 328 additions and 247 deletions

View file

@ -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);

View file

@ -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;
}

View file

@ -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;

View file

@ -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.

View file

@ -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);

View file

@ -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;

View file

@ -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;

View file

@ -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 *) &currentMIPS->fpcond), XMM0);
MOVSS(M(&currentMIPS->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 *) &currentMIPS->fpcond), R(EAX));
MOV(32, R(EAX), M(&ssCompareTemp));
OR(32, M(&currentMIPS->fpcond), R(EAX));
}
}
@ -185,7 +185,7 @@ void Jit::Comp_FPUComp(MIPSOpcode op)
{
case 0: //f
case 8: //sf
MOV(32, M((void *) &currentMIPS->fpcond), Imm32(0));
MOV(32, M(&currentMIPS->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;

View file

@ -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);

View file

@ -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
}

View file

@ -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*)&currentMIPS->vfpuCtrl[VFPU_CTRL_CC]), Imm32(true_bits[n-1]));
OR(32, M(&currentMIPS->vfpuCtrl[VFPU_CTRL_CC]), Imm32(true_bits[n-1]));
return;
} else if (cond == VC_FL) {
AND(32, M((void*)&currentMIPS->vfpuCtrl[VFPU_CTRL_CC]), Imm32(~true_bits[n-1]));
AND(32, M(&currentMIPS->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]));

View file

@ -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(&currentMIPS->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) { }

View file

@ -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 {

View file

@ -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);
}