Improve typesafety in the x86 regalloc.

This commit is contained in:
Unknown W. Brackets 2013-08-24 19:31:12 -07:00
parent 3156b95d3f
commit 97aa1a631e
20 changed files with 318 additions and 280 deletions

View File

@ -15,19 +15,24 @@
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#include "ArmJit.h"
#include "Core/MIPS/MIPS.h"
#include "Core/MIPS/MIPSCodeUtils.h"
#include "Core/MIPS/ARM/ArmJit.h"
#include "Common/CPUDetect.h"
using namespace MIPSAnalyst;
#define _RS ((op>>21) & 0x1F)
#define _RT ((op>>16) & 0x1F)
#define _RD ((op>>11) & 0x1F)
#define _FS ((op>>11) & 0x1F)
#define _FT ((op>>16) & 0x1F)
#define _FD ((op>>6 ) & 0x1F)
#define _SA ((op>>6 ) & 0x1F)
#define _POS ((op>>6 ) & 0x1F)
#define _SIZE ((op>>11 ) & 0x1F)
#define _RS MIPS_GET_RS(op)
#define _RT MIPS_GET_RT(op)
#define _RD MIPS_GET_RD(op)
#define _FS MIPS_GET_FS(op)
#define _FT MIPS_GET_FT(op)
#define _FD MIPS_GET_FD(op)
#define _SA MIPS_GET_SA(op)
#define _POS ((op>> 6) & 0x1F)
#define _SIZE ((op>>11) & 0x1F)
#define _IMM16 (signed short)(op & 0xFFFF)
#define _IMM26 (op & 0x03FFFFFF)
// All functions should have CONDITIONAL_DISABLE, so we can narrow things down to a file quickly.
// Currently known non working ones should have DISABLE.
@ -68,8 +73,8 @@ namespace MIPSComp
u32 uimm = op & 0xFFFF;
u32 suimm = (u32)(s32)simm;
int rt = _RT;
int rs = _RS;
MIPSGPReg rt = _RT;
MIPSGPReg rs = _RS;
// noop, won't write to ZERO.
if (rt == 0)
@ -130,7 +135,7 @@ namespace MIPSComp
void Jit::Comp_RType2(MIPSOpcode op)
{
CONDITIONAL_DISABLE;
int rs = _RS;
MIPSGPReg rs = _RS;
int rd = _RD;
// Don't change $zr.
@ -183,8 +188,8 @@ namespace MIPSComp
void Jit::Comp_RType3(MIPSOpcode op)
{
CONDITIONAL_DISABLE;
int rt = _RT;
int rs = _RS;
MIPSGPReg rt = _RT;
MIPSGPReg rs = _RS;
int rd = _RD;
// noop, won't write to ZERO.
@ -328,7 +333,7 @@ namespace MIPSComp
void Jit::CompShiftImm(MIPSOpcode op, ArmGen::ShiftType shiftType)
{
int rd = _RD;
int rt = _RT;
MIPSGPReg rt = _RT;
int sa = _SA;
gpr.MapDirtyIn(rd, rt);
@ -338,8 +343,8 @@ namespace MIPSComp
void Jit::CompShiftVar(MIPSOpcode op, ArmGen::ShiftType shiftType)
{
int rd = _RD;
int rt = _RT;
int rs = _RS;
MIPSGPReg rt = _RT;
MIPSGPReg rs = _RS;
if (gpr.IsImm(rs))
{
int sa = gpr.GetImm(rs) & 0x1F;
@ -355,7 +360,7 @@ namespace MIPSComp
void Jit::Comp_ShiftType(MIPSOpcode op)
{
CONDITIONAL_DISABLE;
int rs = _RS;
MIPSGPReg rs = _RS;
int rd = _RD;
int fd = _FD;
@ -383,8 +388,8 @@ namespace MIPSComp
{
CONDITIONAL_DISABLE;
int rs = _RS;
int rt = _RT;
MIPSGPReg rs = _RS;
MIPSGPReg rt = _RT;
int pos = _POS;
int size = _SIZE + 1;
@ -450,7 +455,7 @@ namespace MIPSComp
void Jit::Comp_Allegrex(MIPSOpcode op)
{
CONDITIONAL_DISABLE;
int rt = _RT;
MIPSGPReg rt = _RT;
int rd = _RD;
// Don't change $zr.
if (rd == 0)
@ -508,7 +513,7 @@ namespace MIPSComp
void Jit::Comp_Allegrex2(MIPSOpcode op)
{
CONDITIONAL_DISABLE;
int rt = _RT;
MIPSGPReg rt = _RT;
int rd = _RD;
// Don't change $zr.
if (rd == 0)
@ -541,8 +546,8 @@ namespace MIPSComp
void Jit::Comp_MulDivType(MIPSOpcode op)
{
CONDITIONAL_DISABLE;
int rt = _RT;
int rs = _RS;
MIPSGPReg rt = _RT;
MIPSGPReg rs = _RS;
int rd = _RD;
switch (op & 63)

View File

@ -31,15 +31,16 @@
#include "Common/ArmEmitter.h"
#define _RS ((op>>21) & 0x1F)
#define _RT ((op>>16) & 0x1F)
#define _RD ((op>>11) & 0x1F)
#define _FS ((op>>11) & 0x1F)
#define _FT ((op>>16) & 0x1F)
#define _FD ((op>>6 ) & 0x1F)
#define _POS ((op>>6 ) & 0x1F)
#define _SIZE ((op>>11 ) & 0x1F)
#define _IMM16 (signed short)(op&0xFFFF)
#define _RS MIPS_GET_RS(op)
#define _RT MIPS_GET_RT(op)
#define _RD MIPS_GET_RD(op)
#define _FS MIPS_GET_FS(op)
#define _FT MIPS_GET_FT(op)
#define _FD MIPS_GET_FD(op)
#define _SA MIPS_GET_SA(op)
#define _POS ((op>> 6) & 0x1F)
#define _SIZE ((op>>11) & 0x1F)
#define _IMM16 (signed short)(op & 0xFFFF)
#define _IMM26 (op & 0x03FFFFFF)
#define LOOPOPTIMIZATION 0
@ -60,8 +61,8 @@ void Jit::BranchRSRTComp(MIPSOpcode op, ArmGen::CCFlags cc, bool likely)
return;
}
int offset = _IMM16 << 2;
int rt = _RT;
int rs = _RS;
MIPSGPReg rt = _RT;
MIPSGPReg rs = _RS;
u32 targetAddr = js.compilerPC + offset + 4;
MIPSOpcode delaySlotOp = Memory::Read_Instruction(js.compilerPC+4);
@ -120,7 +121,7 @@ void Jit::BranchRSZeroComp(MIPSOpcode op, ArmGen::CCFlags cc, bool andLink, bool
return;
}
int offset = _IMM16 << 2;
int rs = _RS;
MIPSGPReg rs = _RS;
u32 targetAddr = js.compilerPC + offset + 4;
MIPSOpcode delaySlotOp = Memory::Read_Instruction(js.compilerPC + 4);
@ -370,7 +371,7 @@ void Jit::Comp_JumpReg(MIPSOpcode op)
ERROR_LOG_REPORT(JIT, "Branch in JumpReg delay slot at %08x in block starting at %08x", js.compilerPC, js.blockStart);
return;
}
int rs = _RS;
MIPSGPReg rs = _RS;
MIPSOpcode delaySlotOp = Memory::Read_Instruction(js.compilerPC + 4);
bool delaySlotIsNice = IsDelaySlotNiceReg(op, delaySlotOp, rs);

View File

@ -14,21 +14,26 @@
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#include "Core/Config.h"
#include "Core/MIPS/MIPS.h"
#include "Core/MIPS/MIPSCodeUtils.h"
#include "Core/MIPS/MIPSTables.h"
#include "ArmJit.h"
#include "ArmRegCache.h"
#include "Core/MIPS/ARM/ArmJit.h"
#include "Core/MIPS/ARM/ArmRegCache.h"
#define _RS ((op>>21) & 0x1F)
#define _RT ((op>>16) & 0x1F)
#define _RD ((op>>11) & 0x1F)
#define _FS ((op>>11) & 0x1F)
#define _FT ((op>>16) & 0x1F)
#define _FD ((op>>6 ) & 0x1F)
#define _POS ((op>>6 ) & 0x1F)
#define _RS MIPS_GET_RS(op)
#define _RT MIPS_GET_RT(op)
#define _RD MIPS_GET_RD(op)
#define _FS MIPS_GET_FS(op)
#define _FT MIPS_GET_FT(op)
#define _FD MIPS_GET_FD(op)
#define _SA MIPS_GET_SA(op)
#define _POS ((op>> 6) & 0x1F)
#define _SIZE ((op>>11) & 0x1F)
#define _IMM16 (signed short)(op & 0xFFFF)
#define _IMM26 (op & 0x03FFFFFF)
// All functions should have CONDITIONAL_DISABLE, so we can narrow things down to a file quickly.
// Currently known non working ones should have DISABLE.
@ -84,7 +89,7 @@ void Jit::Comp_FPULS(MIPSOpcode op)
s32 offset = (s16)(op & 0xFFFF);
int ft = _FT;
int rs = _RS;
MIPSGPReg rs = _RS;
// u32 addr = R(rs) + offset;
// logBlocks = 1;
bool doCheck = false;
@ -312,7 +317,7 @@ void Jit::Comp_mxc1(MIPSOpcode op)
CONDITIONAL_DISABLE;
int fs = _FS;
int rt = _RT;
MIPSGPReg rt = _RT;
switch ((op >> 21) & 0x1f)
{

View File

@ -37,20 +37,25 @@
// (pointer or data), we could avoid many BIC instructions.
#include "../../MemMap.h"
#include "../MIPSAnalyst.h"
#include "../../Config.h"
#include "ArmJit.h"
#include "ArmRegCache.h"
#include "Core/MemMap.h"
#include "Core/Config.h"
#include "Core/MIPS/MIPS.h"
#include "Core/MIPS/MIPSAnalyst.h"
#include "Core/MIPS/MIPSCodeUtils.h"
#include "Core/MIPS/ARM/ArmJit.h"
#include "Core/MIPS/ARM/ArmRegCache.h"
#define _RS ((op>>21) & 0x1F)
#define _RT ((op>>16) & 0x1F)
#define _RD ((op>>11) & 0x1F)
#define _FS ((op>>11) & 0x1F)
#define _FT ((op>>16) & 0x1F)
#define _FD ((op>>6 ) & 0x1F)
#define _POS ((op>>6 ) & 0x1F)
#define _SIZE ((op>>11 ) & 0x1F)
#define _RS MIPS_GET_RS(op)
#define _RT MIPS_GET_RT(op)
#define _RD MIPS_GET_RD(op)
#define _FS MIPS_GET_FS(op)
#define _FT MIPS_GET_FT(op)
#define _FD MIPS_GET_FD(op)
#define _SA MIPS_GET_SA(op)
#define _POS ((op>> 6) & 0x1F)
#define _SIZE ((op>>11) & 0x1F)
#define _IMM16 (signed short)(op & 0xFFFF)
#define _IMM26 (op & 0x03FFFFFF)
// All functions should have CONDITIONAL_DISABLE, so we can narrow things down to a file quickly.
// Currently known non working ones should have DISABLE.
@ -126,10 +131,10 @@ namespace MIPSComp
CONDITIONAL_DISABLE;
int offset = (signed short)(op&0xFFFF);
bool load = false;
int rt = _RT;
int rs = _RS;
MIPSGPReg rt = _RT;
MIPSGPReg rs = _RS;
int o = op>>26;
if (((op >> 29) & 1) == 0 && rt == 0) {
if (((op >> 29) & 1) == 0 && rt == MIPS_REG_ZERO) {
// Don't load anything into $zr
return;
}

View File

@ -21,12 +21,13 @@
#include "Core/MemMap.h"
#include "Core/MIPS/MIPS.h"
#include "Core/MIPS/MIPSAnalyst.h"
#include "Core/MIPS/MIPSCodeUtils.h"
#include "Common/CPUDetect.h"
#include "Core/Config.h"
#include "Core/Reporting.h"
#include "ArmJit.h"
#include "ArmRegCache.h"
#include "Core/MIPS/ARM/ArmJit.h"
#include "Core/MIPS/ARM/ArmRegCache.h"
const bool disablePrefixes = false;
@ -38,14 +39,17 @@ const bool disablePrefixes = false;
#define CONDITIONAL_DISABLE ;
#define DISABLE { fpr.ReleaseSpillLocksAndDiscardTemps(); Comp_Generic(op); return; }
#define _RS ((op>>21) & 0x1F)
#define _RT ((op>>16) & 0x1F)
#define _RD ((op>>11) & 0x1F)
#define _FS ((op>>11) & 0x1F)
#define _FT ((op>>16) & 0x1F)
#define _FD ((op>>6 ) & 0x1F)
#define _POS ((op>>6 ) & 0x1F)
#define _SIZE ((op>>11 ) & 0x1F)
#define _RS MIPS_GET_RS(op)
#define _RT MIPS_GET_RT(op)
#define _RD MIPS_GET_RD(op)
#define _FS MIPS_GET_FS(op)
#define _FT MIPS_GET_FT(op)
#define _FD MIPS_GET_FD(op)
#define _SA MIPS_GET_SA(op)
#define _POS ((op>> 6) & 0x1F)
#define _SIZE ((op>>11) & 0x1F)
#define _IMM16 (signed short)(op & 0xFFFF)
#define _IMM26 (op & 0x03FFFFFF)
namespace MIPSComp
{
@ -236,7 +240,7 @@ namespace MIPSComp
s32 imm = (signed short)(op&0xFFFC);
int vt = ((op >> 16) & 0x1f) | ((op & 3) << 5);
int rs = _RS;
MIPSGPReg rs = _RS;
bool doCheck = false;
switch (op >> 26)
@ -327,7 +331,7 @@ namespace MIPSComp
int imm = (signed short)(op&0xFFFC);
int vt = (((op >> 16) & 0x1f)) | ((op&1) << 5);
int rs = _RS;
MIPSGPReg rs = _RS;
bool doCheck = false;
switch (op >> 26)
@ -968,7 +972,7 @@ namespace MIPSComp
CONDITIONAL_DISABLE;
int imm = op & 0xFF;
int rt = _RT;
MIPSGPReg rt = _RT;
switch ((op >> 21) & 0x1f)
{
case 3: //mfv / mfvc

View File

@ -44,5 +44,4 @@
namespace MIPSComp {
extern Jit *jit;
extern const float cst_constants[32];
}

View File

@ -60,7 +60,7 @@ MIPSDebugInterface *currentDebugMIPS = &debugr4k;
#define M_SQRT1_2 0.707106781186547524401f
#endif
extern const float cst_constants[32] = {
const float cst_constants[32] = {
0,
std::numeric_limits<float>::max(), // all these are verified on real PSP
sqrtf(2.0f),

View File

@ -24,7 +24,7 @@
typedef Memory::Opcode MIPSOpcode;
enum
enum MIPSGPReg
{
MIPS_REG_ZERO=0,
MIPS_REG_COMPILER_SCRATCH=1,
@ -56,6 +56,7 @@ enum
// ID for mipscall "callback" is stored here - from JPCSP
MIPS_REG_CALL_ID=MIPS_REG_S0,
MIPS_REG_INVALID=-1,
};
enum

View File

@ -31,7 +31,7 @@ using namespace std;
namespace MIPSAnalyst
{
// Only can ever output a single reg.
int GetOutGPReg(MIPSOpcode op) {
MIPSGPReg GetOutGPReg(MIPSOpcode op) {
MIPSInfo opinfo = MIPSGetInfo(op);
if ((opinfo & IS_VFPU) == 0) {
if (opinfo & OUT_RT) {
@ -44,10 +44,10 @@ namespace MIPSAnalyst
return MIPS_REG_RA;
}
}
return -1;
return MIPS_REG_INVALID;
}
bool ReadsFromGPReg(MIPSOpcode op, u32 reg) {
bool ReadsFromGPReg(MIPSOpcode op, MIPSGPReg reg) {
MIPSInfo info = MIPSGetInfo(op);
if ((info & IS_VFPU) == 0) {
if ((info & IN_RS) != 0 && MIPS_GET_RS(op) == reg) {
@ -60,12 +60,12 @@ namespace MIPSAnalyst
return false;
}
bool IsDelaySlotNiceReg(MIPSOpcode branchOp, MIPSOpcode op, int reg1, int reg2) {
bool IsDelaySlotNiceReg(MIPSOpcode branchOp, MIPSOpcode op, MIPSGPReg reg1, MIPSGPReg reg2) {
// $0 is never an out reg, it's always 0.
if (reg1 != 0 && GetOutGPReg(op) == reg1) {
if (reg1 != MIPS_REG_ZERO && GetOutGPReg(op) == reg1) {
return false;
}
if (reg2 != 0 && GetOutGPReg(op) == reg2) {
if (reg2 != MIPS_REG_ZERO && GetOutGPReg(op) == reg2) {
return false;
}
@ -104,8 +104,8 @@ namespace MIPSAnalyst
MIPSOpcode op = Memory::Read_Instruction(addr);
MIPSInfo info = MIPSGetInfo(op);
int rs = MIPS_GET_RS(op);
int rt = MIPS_GET_RT(op);
MIPSGPReg rs = MIPS_GET_RS(op);
MIPSGPReg rt = MIPS_GET_RT(op);
if (info & IN_RS) {
if ((info & IN_RS_ADDR) == IN_RS_ADDR) {
@ -119,8 +119,8 @@ namespace MIPSAnalyst
results.r[rt].MarkRead(addr);
}
int outReg = GetOutGPReg(op);
if (outReg != -1) {
MIPSGPReg outReg = GetOutGPReg(op);
if (outReg != MIPS_REG_INVALID) {
results.r[outReg].MarkWrite(addr);
}
@ -184,7 +184,7 @@ namespace MIPSAnalyst
}
bool IsRegisterUsed(u32 reg, u32 addr)
bool IsRegisterUsed(MIPSGPReg reg, u32 addr)
{
while (true)
{
@ -400,9 +400,9 @@ namespace MIPSAnalyst
LOG(CPU,"Precompiled %i straight leaf functions",count);*/
}
std::vector<int> GetInputRegs(MIPSOpcode op)
std::vector<MIPSGPReg> GetInputRegs(MIPSOpcode op)
{
std::vector<int> vec;
std::vector<MIPSGPReg> vec;
MIPSInfo info = MIPSGetInfo(op);
if ((info & IS_VFPU) == 0)
{
@ -411,9 +411,9 @@ namespace MIPSAnalyst
}
return vec;
}
std::vector<int> GetOutputRegs(MIPSOpcode op)
std::vector<MIPSGPReg> GetOutputRegs(MIPSOpcode op)
{
std::vector<int> vec;
std::vector<MIPSGPReg> vec;
MIPSInfo info = MIPSGetInfo(op);
if ((info & IS_VFPU) == 0)
{
@ -453,7 +453,7 @@ namespace MIPSAnalyst
if (opInfo & IN_RS) // to register
{
info.isBranchToRegister = true;
info.branchRegisterNum = MIPS_GET_RS(op);
info.branchRegisterNum = (int)MIPS_GET_RS(op);
info.branchTarget = cpu->GetRegValue(0,info.branchRegisterNum);
} else { // to immediate
info.branchTarget = GetJumpTarget(address);
@ -465,7 +465,7 @@ namespace MIPSAnalyst
{
info.isConditional = true;
u32 rt = cpu->GetRegValue(0,MIPS_GET_RT(op));
u32 rt = cpu->GetRegValue(0, (int)MIPS_GET_RT(op));
switch (opInfo & CONDTYPE_MASK)
{
case CONDTYPE_EQ:
@ -489,8 +489,8 @@ namespace MIPSAnalyst
info.isLinkedBranch = true;
}
u32 rt = cpu->GetRegValue(0,MIPS_GET_RT(op));
u32 rs = cpu->GetRegValue(0,MIPS_GET_RS(op));
u32 rt = cpu->GetRegValue(0, (int)MIPS_GET_RT(op));
u32 rs = cpu->GetRegValue(0, (int)MIPS_GET_RS(op));
switch (opInfo & CONDTYPE_MASK)
{
case CONDTYPE_EQ:
@ -544,7 +544,7 @@ namespace MIPSAnalyst
info.dataSize = 16;
}
u32 rs = cpu->GetRegValue(0,MIPS_GET_RS(op));
u32 rs = cpu->GetRegValue(0, (int)MIPS_GET_RS(op));
s16 imm16 = op & 0xFFFF;
info.dataAddress = rs + imm16;
}

View File

@ -79,12 +79,12 @@ namespace MIPSAnalyst
void ScanForFunctions(u32 startAddr, u32 endAddr);
void CompileLeafs();
std::vector<int> GetInputRegs(MIPSOpcode op);
std::vector<int> GetOutputRegs(MIPSOpcode op);
std::vector<MIPSGPReg> GetInputRegs(MIPSOpcode op);
std::vector<MIPSGPReg> GetOutputRegs(MIPSOpcode op);
int GetOutGPReg(MIPSOpcode op);
bool ReadsFromGPReg(MIPSOpcode op, u32 reg);
bool IsDelaySlotNiceReg(MIPSOpcode branchOp, MIPSOpcode op, int reg1, int reg2 = 0);
MIPSGPReg GetOutGPReg(MIPSOpcode op);
bool ReadsFromGPReg(MIPSOpcode op, MIPSGPReg reg);
bool IsDelaySlotNiceReg(MIPSOpcode branchOp, MIPSOpcode op, MIPSGPReg reg1, MIPSGPReg reg2 = MIPS_REG_ZERO);
bool IsDelaySlotNiceVFPU(MIPSOpcode branchOp, MIPSOpcode op);
bool IsDelaySlotNiceFPU(MIPSOpcode branchOp, MIPSOpcode op);
bool IsSyscall(MIPSOpcode op);

View File

@ -38,11 +38,11 @@
#define MIPS_GET_OP(op) ((op>>26) & 0x3F)
#define MIPS_GET_FUNC(op) (op & 0x3F)
#define MIPS_GET_SA(op) (op>>6 & 0x1F)
#define MIPS_GET_SA(op) ((op>>6) & 0x1F)
#define MIPS_GET_RS(op) ((op>>21) & 0x1F)
#define MIPS_GET_RT(op) ((op>>16) & 0x1F)
#define MIPS_GET_RD(op) ((op>>11) & 0x1F)
#define MIPS_GET_RS(op) MIPSGPReg((op>>21) & 0x1F)
#define MIPS_GET_RT(op) MIPSGPReg((op>>16) & 0x1F)
#define MIPS_GET_RD(op) MIPSGPReg((op>>11) & 0x1F)
#define MIPS_GET_FS(op) ((op>>11) & 0x1F)
#define MIPS_GET_FT(op) ((op>>16) & 0x1F)

View File

@ -15,20 +15,24 @@
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#include "Jit.h"
#include "RegCache.h"
#include "Core/MIPS/MIPSCodeUtils.h"
#include "Core/MIPS/x86/Jit.h"
#include "Core/MIPS/x86/RegCache.h"
#include <algorithm>
using namespace MIPSAnalyst;
#define _RS ((op>>21) & 0x1F)
#define _RT ((op>>16) & 0x1F)
#define _RD ((op>>11) & 0x1F)
#define _FS ((op>>11) & 0x1F)
#define _FT ((op>>16) & 0x1F)
#define _FD ((op>>6 ) & 0x1F)
#define _SA ((op>>6 ) & 0x1F)
#define _POS ((op>>6 ) & 0x1F)
#define _SIZE ((op>>11 ) & 0x1F)
#define _RS MIPS_GET_RS(op)
#define _RT MIPS_GET_RT(op)
#define _RD MIPS_GET_RD(op)
#define _FS MIPS_GET_FS(op)
#define _FT MIPS_GET_FT(op)
#define _FD MIPS_GET_FD(op)
#define _SA MIPS_GET_SA(op)
#define _POS ((op>> 6) & 0x1F)
#define _SIZE ((op>>11) & 0x1F)
#define _IMM16 (signed short)(op & 0xFFFF)
#define _IMM26 (op & 0x03FFFFFF)
// All functions should have CONDITIONAL_DISABLE, so we can narrow things down to a file quickly.
// Currently known non working ones should have DISABLE.
@ -42,8 +46,8 @@ namespace MIPSComp
void Jit::CompImmLogic(MIPSOpcode op, void (XEmitter::*arith)(int, const OpArg &, const OpArg &))
{
u32 uimm = (u16)(op & 0xFFFF);
int rt = _RT;
int rs = _RS;
MIPSGPReg rt = _RT;
MIPSGPReg rs = _RS;
gpr.Lock(rt, rs);
gpr.BindToRegister(rt, rt == rs, true);
if (rt != rs)
@ -55,15 +59,15 @@ namespace MIPSComp
void Jit::Comp_IType(MIPSOpcode op)
{
CONDITIONAL_DISABLE;
s32 simm = (s32)(s16)(op & 0xFFFF); // sign extension
s32 simm = (s32)_IMM16; // sign extension
u32 uimm = op & 0xFFFF;
u32 suimm = (u32)(s32)simm;
int rt = _RT;
int rs = _RS;
MIPSGPReg rt = _RT;
MIPSGPReg rs = _RS;
// noop, won't write to ZERO.
if (rt == 0)
if (rt == MIPS_REG_ZERO)
return;
switch (op >> 26)
@ -162,11 +166,11 @@ namespace MIPSComp
void Jit::Comp_RType2(MIPSOpcode op)
{
CONDITIONAL_DISABLE;
int rs = _RS;
int rd = _RD;
MIPSGPReg rs = _RS;
MIPSGPReg rd = _RD;
// Don't change $zr.
if (rd == 0)
if (rd == MIPS_REG_ZERO)
return;
switch (op & 63)
@ -268,9 +272,9 @@ namespace MIPSComp
//rd = rs X rt
void Jit::CompTriArith(MIPSOpcode op, void (XEmitter::*arith)(int, const OpArg &, const OpArg &), u32 (*doImm)(const u32, const u32))
{
int rt = _RT;
int rs = _RS;
int rd = _RD;
MIPSGPReg rt = _RT;
MIPSGPReg rs = _RS;
MIPSGPReg rd = _RD;
// Yes, this happens. Let's make it fast.
if (doImm && gpr.IsImmediate(rs) && gpr.IsImmediate(rt))
@ -281,19 +285,19 @@ namespace MIPSComp
// Act like zero was used if the operand is equivalent. This happens.
if (gpr.IsImmediate(rs) && gpr.GetImmediate32(rs) == 0)
rs = 0;
rs = MIPS_REG_ZERO;
if (gpr.IsImmediate(rt) && gpr.GetImmediate32(rt) == 0)
rt = 0;
rt = MIPS_REG_ZERO;
gpr.Lock(rt, rs, rd);
// Optimize out operations against 0... and is the only one that isn't a MOV.
if (rt == 0 || (rs == 0 && doImm != &RType3_ImmSub))
if (rt == MIPS_REG_ZERO || (rs == MIPS_REG_ZERO && doImm != &RType3_ImmSub))
{
if (doImm == &RType3_ImmAnd)
gpr.SetImmediate32(rd, 0);
else
{
int rsource = rt == 0 ? rs : rt;
MIPSGPReg rsource = rt == MIPS_REG_ZERO ? rs : rt;
if (rsource != rd)
{
gpr.BindToRegister(rd, false, true);
@ -327,12 +331,12 @@ namespace MIPSComp
{
CONDITIONAL_DISABLE
int rt = _RT;
int rs = _RS;
int rd = _RD;
MIPSGPReg rt = _RT;
MIPSGPReg rs = _RS;
MIPSGPReg rd = _RD;
// noop, won't write to ZERO.
if (rd == 0)
if (rd == MIPS_REG_ZERO)
return;
switch (op & 63)
@ -451,7 +455,7 @@ namespace MIPSComp
gpr.SetImmediate32(rd, std::max((s32)gpr.GetImmediate32(rs), (s32)gpr.GetImmediate32(rt)));
else
{
int rsrc = rd == rt ? rs : rt;
MIPSGPReg rsrc = rd == rt ? rs : rt;
gpr.Lock(rd, rs, rt);
gpr.KillImmediate(rsrc, true, false);
gpr.BindToRegister(rd, rd == rs || rd == rt, true);
@ -468,7 +472,7 @@ namespace MIPSComp
gpr.SetImmediate32(rd, std::min((s32)gpr.GetImmediate32(rs), (s32)gpr.GetImmediate32(rt)));
else
{
int rsrc = rd == rt ? rs : rt;
MIPSGPReg rsrc = rd == rt ? rs : rt;
gpr.Lock(rd, rs, rt);
gpr.KillImmediate(rsrc, true, false);
gpr.BindToRegister(rd, rd == rs || rd == rt, true);
@ -509,8 +513,8 @@ namespace MIPSComp
void Jit::CompShiftImm(MIPSOpcode op, void (XEmitter::*shift)(int, OpArg, OpArg), u32 (*doImm)(const u32, const u32))
{
int rd = _RD;
int rt = _RT;
MIPSGPReg rd = _RD;
MIPSGPReg rt = _RT;
int sa = _SA;
if (doImm && gpr.IsImmediate(rt))
@ -530,9 +534,9 @@ namespace MIPSComp
// "over-shifts" work the same as on x86 - only bottom 5 bits are used to get the shift value
void Jit::CompShiftVar(MIPSOpcode op, void (XEmitter::*shift)(int, OpArg, OpArg), u32 (*doImm)(const u32, const u32))
{
int rd = _RD;
int rt = _RT;
int rs = _RS;
MIPSGPReg rd = _RD;
MIPSGPReg rt = _RT;
MIPSGPReg rs = _RS;
if (doImm && gpr.IsImmediate(rs) && gpr.IsImmediate(rt))
{
@ -566,12 +570,12 @@ namespace MIPSComp
void Jit::Comp_ShiftType(MIPSOpcode op)
{
CONDITIONAL_DISABLE;
int rs = _RS;
int rd = _RD;
int fd = _FD;
int rs = (op>>21) & 0x1F;
MIPSGPReg rd = _RD;
int fd = (op>>6) & 0x1F;
// noop, won't write to ZERO.
if (rd == 0)
if (rd == MIPS_REG_ZERO)
return;
// WARNING : ROTR
@ -594,15 +598,15 @@ namespace MIPSComp
void Jit::Comp_Special3(MIPSOpcode op)
{
CONDITIONAL_DISABLE;
int rs = _RS;
int rt = _RT;
MIPSGPReg rs = _RS;
MIPSGPReg rt = _RT;
int pos = _POS;
int size = _SIZE + 1;
u32 mask = 0xFFFFFFFFUL >> (32 - size);
// Don't change $zr.
if (rt == 0)
if (rt == MIPS_REG_ZERO)
return;
switch (op & 0x3f)
@ -662,10 +666,10 @@ namespace MIPSComp
void Jit::Comp_Allegrex(MIPSOpcode op)
{
CONDITIONAL_DISABLE
int rt = _RT;
int rd = _RD;
MIPSGPReg rt = _RT;
MIPSGPReg rd = _RD;
// Don't change $zr.
if (rd == 0)
if (rd == MIPS_REG_ZERO)
return;
switch ((op >> 6) & 31)
@ -772,10 +776,10 @@ namespace MIPSComp
void Jit::Comp_Allegrex2(MIPSOpcode op)
{
CONDITIONAL_DISABLE
int rt = _RT;
int rd = _RD;
MIPSGPReg rt = _RT;
MIPSGPReg rd = _RD;
// Don't change $zr.
if (rd == 0)
if (rd == MIPS_REG_ZERO)
return;
DISABLE;
@ -802,9 +806,9 @@ namespace MIPSComp
void Jit::Comp_MulDivType(MIPSOpcode op)
{
CONDITIONAL_DISABLE;
int rt = _RT;
int rs = _RS;
int rd = _RD;
MIPSGPReg rt = _RT;
MIPSGPReg rs = _RS;
MIPSGPReg rd = _RD;
switch (op & 63)
{

View File

@ -30,15 +30,16 @@
#include "Core/MIPS/x86/RegCache.h"
#include "Core/MIPS/JitCommon/JitBlockCache.h"
#define _RS ((op>>21) & 0x1F)
#define _RT ((op>>16) & 0x1F)
#define _RD ((op>>11) & 0x1F)
#define _FS ((op>>11) & 0x1F)
#define _FT ((op>>16) & 0x1F)
#define _FD ((op>>6 ) & 0x1F)
#define _POS ((op>>6 ) & 0x1F)
#define _SIZE ((op>>11 ) & 0x1F)
#define _IMM16 (signed short)(op&0xFFFF)
#define _RS MIPS_GET_RS(op)
#define _RT MIPS_GET_RT(op)
#define _RD MIPS_GET_RD(op)
#define _FS MIPS_GET_FS(op)
#define _FT MIPS_GET_FT(op)
#define _FD MIPS_GET_FD(op)
#define _SA MIPS_GET_SA(op)
#define _POS ((op>> 6) & 0x1F)
#define _SIZE ((op>>11) & 0x1F)
#define _IMM16 (signed short)(op & 0xFFFF)
#define _IMM26 (op & 0x03FFFFFF)
#define LOOPOPTIMIZATION 0
@ -136,8 +137,8 @@ void Jit::BranchRSRTComp(MIPSOpcode op, Gen::CCFlags cc, bool likely)
return;
}
int offset = _IMM16 << 2;
int rt = _RT;
int rs = _RS;
MIPSGPReg rt = _RT;
MIPSGPReg rs = _RS;
u32 targetAddr = js.compilerPC + offset + 4;
MIPSOpcode delaySlotOp = Memory::Read_Instruction(js.compilerPC+4);
@ -186,7 +187,7 @@ void Jit::BranchRSRTComp(MIPSOpcode op, Gen::CCFlags cc, bool likely)
else
{
gpr.BindToRegister(rs, true, false);
CMP(32, gpr.R(rs), rt == 0 ? Imm32(0) : gpr.R(rt));
CMP(32, gpr.R(rs), rt == MIPS_REG_ZERO ? Imm32(0) : gpr.R(rt));
}
Gen::FixupBranch ptr;
@ -236,7 +237,7 @@ void Jit::BranchRSZeroComp(MIPSOpcode op, Gen::CCFlags cc, bool andLink, bool li
return;
}
int offset = _IMM16 << 2;
int rs = _RS;
MIPSGPReg rs = _RS;
u32 targetAddr = js.compilerPC + offset + 4;
MIPSOpcode delaySlotOp = Memory::Read_Instruction(js.compilerPC + 4);
@ -573,7 +574,7 @@ void Jit::Comp_JumpReg(MIPSOpcode op)
ERROR_LOG_REPORT(JIT, "Branch in JumpReg delay slot at %08x in block starting at %08x", js.compilerPC, js.blockStart);
return;
}
int rs = _RS;
MIPSGPReg rs = _RS;
MIPSOpcode delaySlotOp = Memory::Read_Instruction(js.compilerPC + 4);
bool delaySlotIsNice = IsDelaySlotNiceReg(op, delaySlotOp, rs);

View File

@ -15,21 +15,24 @@
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#include "../MIPS.h"
#include "../../Config.h"
#include "Core/Config.h"
#include "Common/Common.h"
#include "Jit.h"
#include "RegCache.h"
#include "Core/MIPS/MIPS.h"
#include "Core/MIPS/MIPSCodeUtils.h"
#include "Core/MIPS/x86/Jit.h"
#include "Core/MIPS/x86/RegCache.h"
#define _RS ((op>>21) & 0x1F)
#define _RT ((op>>16) & 0x1F)
#define _RD ((op>>11) & 0x1F)
#define _FS ((op>>11) & 0x1F)
#define _FT ((op>>16) & 0x1F)
#define _FD ((op>>6 ) & 0x1F)
#define _POS ((op>>6 ) & 0x1F)
#define _SIZE ((op>>11 ) & 0x1F)
#define _RS MIPS_GET_RS(op)
#define _RT MIPS_GET_RT(op)
#define _RD MIPS_GET_RD(op)
#define _FS MIPS_GET_FS(op)
#define _FT MIPS_GET_FT(op)
#define _FD MIPS_GET_FD(op)
#define _SA MIPS_GET_SA(op)
#define _POS ((op>> 6) & 0x1F)
#define _SIZE ((op>>11) & 0x1F)
#define _IMM16 (signed short)(op & 0xFFFF)
#define _IMM26 (op & 0x03FFFFFF)
// All functions should have CONDITIONAL_DISABLE, so we can narrow things down to a file quickly.
// Currently known non working ones should have DISABLE.
@ -92,9 +95,9 @@ static u32 MEMORY_ALIGNED16(ssLoadStoreTemp);
void Jit::Comp_FPULS(MIPSOpcode op)
{
CONDITIONAL_DISABLE;
s32 offset = (s16)(op&0xFFFF);
s32 offset = _IMM16;
int ft = _FT;
int rs = _RS;
MIPSGPReg rs = _RS;
switch(op >> 26)
{
@ -295,12 +298,12 @@ void Jit::Comp_mxc1(MIPSOpcode op)
CONDITIONAL_DISABLE;
int fs = _FS;
int rt = _RT;
MIPSGPReg rt = _RT;
switch((op >> 21) & 0x1f)
{
case 0: // R(rt) = FI(fs); break; //mfc1
if (rt != 0)
if (rt != MIPS_REG_ZERO)
{
// Cross move! slightly tricky
fpr.StoreFromRegister(fs);

View File

@ -15,22 +15,25 @@
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#include "../../MemMap.h"
#include "../MIPSAnalyst.h"
#include "../../Config.h"
#include "Jit.h"
#include "RegCache.h"
#include "Core/MemMap.h"
#include "Core/MIPS/MIPSAnalyst.h"
#include "Core/Config.h"
#include "Core/MIPS/MIPSCodeUtils.h"
#include "Core/MIPS/x86/Jit.h"
#include "Core/MIPS/x86/RegCache.h"
#define _RS ((op>>21) & 0x1F)
#define _RT ((op>>16) & 0x1F)
#define _RD ((op>>11) & 0x1F)
#define _FS ((op>>11) & 0x1F)
#define _FT ((op>>16) & 0x1F)
#define _FD ((op>>6 ) & 0x1F)
#define _POS ((op>>6 ) & 0x1F)
#define _SIZE ((op>>11 ) & 0x1F)
#define _RS MIPS_GET_RS(op)
#define _RT MIPS_GET_RT(op)
#define _RD MIPS_GET_RD(op)
#define _FS MIPS_GET_FS(op)
#define _FT MIPS_GET_FT(op)
#define _FD MIPS_GET_FD(op)
#define _SA MIPS_GET_SA(op)
#define _POS ((op>> 6) & 0x1F)
#define _SIZE ((op>>11) & 0x1F)
#define _IMM16 (signed short)(op & 0xFFFF)
#define _IMM26 (op & 0x03FFFFFF)
// All functions should have CONDITIONAL_DISABLE, so we can narrow things down to a file quickly.
// Currently known non working ones should have DISABLE.
@ -44,9 +47,9 @@ namespace MIPSComp
void Jit::CompITypeMemRead(MIPSOpcode op, u32 bits, void (XEmitter::*mov)(int, int, X64Reg, OpArg), void *safeFunc)
{
CONDITIONAL_DISABLE;
int offset = (signed short)(op&0xFFFF);
int rt = _RT;
int rs = _RS;
int offset = _IMM16;
MIPSGPReg rt = _RT;
MIPSGPReg rs = _RS;
gpr.Lock(rt, rs);
gpr.BindToRegister(rt, rt == rs, true);
@ -65,9 +68,9 @@ namespace MIPSComp
void Jit::CompITypeMemWrite(MIPSOpcode op, u32 bits, void *safeFunc)
{
CONDITIONAL_DISABLE;
int offset = (signed short)(op&0xFFFF);
int rt = _RT;
int rs = _RS;
int offset = _IMM16;
MIPSGPReg rt = _RT;
MIPSGPReg rs = _RS;
gpr.Lock(rt, rs);
gpr.BindToRegister(rt, true, false);
@ -106,9 +109,9 @@ namespace MIPSComp
{
CONDITIONAL_DISABLE;
int o = op>>26;
int offset = (signed short)(op&0xFFFF);
int rt = _RT;
int rs = _RS;
int offset = _IMM16;
MIPSGPReg rt = _RT;
MIPSGPReg rs = _RS;
X64Reg shiftReg = ECX;
gpr.FlushLockX(ECX, EDX);
@ -163,7 +166,7 @@ namespace MIPSComp
{
CONDITIONAL_DISABLE;
int o = op>>26;
int rt = _RT;
MIPSGPReg rt = _RT;
// Make sure we have the shift for the target in ECX.
if (shiftReg != ECX)
@ -254,11 +257,11 @@ namespace MIPSComp
void Jit::Comp_ITypeMem(MIPSOpcode op)
{
CONDITIONAL_DISABLE;
int offset = (signed short)(op&0xFFFF);
int rt = _RT;
int rs = _RS;
int offset = _IMM16;
MIPSGPReg rt = _RT;
MIPSGPReg rs = _RS;
int o = op>>26;
if (((op >> 29) & 1) == 0 && rt == 0) {
if (((op >> 29) & 1) == 0 && rt == MIPS_REG_ZERO) {
// Don't load anything into $zr
return;
}

View File

@ -24,10 +24,10 @@
#include "Core/Config.h"
#include "Core/Reporting.h"
#include "Core/MIPS/MIPSAnalyst.h"
#include "Core/MIPS/MIPSCodeUtils.h"
#include "Core/MIPS/MIPSVFPUUtils.h"
#include "Jit.h"
#include "RegCache.h"
#include "Core/MIPS/x86/Jit.h"
#include "Core/MIPS/x86/RegCache.h"
// All functions should have CONDITIONAL_DISABLE, so we can narrow things down to a file quickly.
@ -38,14 +38,17 @@
#define DISABLE { fpr.ReleaseSpillLocks(); Comp_Generic(op); return; }
#define _RS ((op>>21) & 0x1F)
#define _RT ((op>>16) & 0x1F)
#define _RD ((op>>11) & 0x1F)
#define _FS ((op>>11) & 0x1F)
#define _FT ((op>>16) & 0x1F)
#define _FD ((op>>6 ) & 0x1F)
#define _POS ((op>>6 ) & 0x1F)
#define _SIZE ((op>>11 ) & 0x1F)
#define _RS MIPS_GET_RS(op)
#define _RT MIPS_GET_RT(op)
#define _RD MIPS_GET_RD(op)
#define _FS MIPS_GET_FS(op)
#define _FT MIPS_GET_FT(op)
#define _FD MIPS_GET_FD(op)
#define _SA MIPS_GET_SA(op)
#define _POS ((op>> 6) & 0x1F)
#define _SIZE ((op>>11) & 0x1F)
#define _IMM16 (signed short)(op & 0xFFFF)
#define _IMM26 (op & 0x03FFFFFF)
using namespace Gen;
@ -203,7 +206,7 @@ void Jit::Comp_SV(MIPSOpcode op) {
s32 imm = (signed short)(op&0xFFFC);
int vt = ((op >> 16) & 0x1f) | ((op & 3) << 5);
int rs = _RS;
MIPSGPReg rs = _RS;
switch (op >> 26)
{
@ -268,7 +271,7 @@ void Jit::Comp_SVQ(MIPSOpcode op)
int imm = (signed short)(op&0xFFFC);
int vt = (((op >> 16) & 0x1f)) | ((op&1) << 5);
int rs = _RS;
MIPSGPReg rs = _RS;
switch (op >> 26)
{
@ -1317,12 +1320,12 @@ void Jit::Comp_Mftv(MIPSOpcode op) {
CONDITIONAL_DISABLE;
int imm = op & 0xFF;
int rt = _RT;
MIPSGPReg rt = _RT;
switch ((op >> 21) & 0x1f)
{
case 3: //mfv / mfvc
// rt = 0, imm = 255 appears to be used as a CPU interlock by some games.
if (rt != 0) {
if (rt != MIPS_REG_ZERO) {
if (imm < 128) { //R(rt) = VI(imm);
fpr.StoreFromRegisterV(imm);
gpr.BindToRegister(rt, false, true);

View File

@ -503,7 +503,7 @@ bool Jit::CheckJitBreakpoint(u32 addr, int downcountOffset)
return false;
}
Jit::JitSafeMem::JitSafeMem(Jit *jit, int raddr, s32 offset, u32 alignMask)
Jit::JitSafeMem::JitSafeMem(Jit *jit, MIPSGPReg raddr, s32 offset, u32 alignMask)
: jit_(jit), raddr_(raddr), offset_(offset), needsCheck_(false), needsSkip_(false), alignMask_(alignMask)
{
// This makes it more instructions, so let's play it safe and say we need a far jump.

View File

@ -339,7 +339,7 @@ private:
class JitSafeMem
{
public:
JitSafeMem(Jit *jit, int raddr, s32 offset, u32 alignMask = 0xFFFFFFFF);
JitSafeMem(Jit *jit, MIPSGPReg raddr, s32 offset, u32 alignMask = 0xFFFFFFFF);
// Emit code necessary for a memory write, returns true if MOV to dest is needed.
bool PrepareWrite(OpArg &dest, int size);
@ -377,7 +377,7 @@ private:
bool ImmValid();
Jit *jit_;
int raddr_;
MIPSGPReg raddr_;
s32 offset_;
int size_;
bool needsCheck_;

View File

@ -57,11 +57,12 @@ void GPRRegCache::Start(MIPSState *mips, MIPSAnalyst::AnalysisResults &stats) {
xregs[i].allocLocked = false;
}
for (int i = 0; i < NUM_MIPS_GPRS; i++) {
regs[i].location = GetDefaultLocation(i);
const MIPSGPReg r = MIPSGPReg(i);
regs[i].location = GetDefaultLocation(r);
regs[i].away = false;
regs[i].locked = false;
}
// todo: sort to find the most popular regs
/*
int maxPreload = 2;
@ -81,11 +82,11 @@ void GPRRegCache::Start(MIPSState *mips, MIPSAnalyst::AnalysisResults &stats) {
// these are MIPS reg indices
void GPRRegCache::Lock(int p1, int p2, int p3, int p4) {
void GPRRegCache::Lock(MIPSGPReg p1, MIPSGPReg p2, MIPSGPReg p3, MIPSGPReg p4) {
regs[p1].locked = true;
if (p2 != 0xFF) regs[p2].locked = true;
if (p3 != 0xFF) regs[p3].locked = true;
if (p4 != 0xFF) regs[p4].locked = true;
if (p2 != MIPS_REG_INVALID) regs[p2].locked = true;
if (p3 != MIPS_REG_INVALID) regs[p3].locked = true;
if (p4 != MIPS_REG_INVALID) regs[p4].locked = true;
}
// these are x64 reg indices
@ -129,7 +130,7 @@ X64Reg GPRRegCache::GetFreeXReg()
X64Reg xr = (X64Reg)aOrder[i];
if (xregs[xr].allocLocked)
continue;
int preg = xregs[xr].mipsReg;
MIPSGPReg preg = xregs[xr].mipsReg;
if (!regs[preg].locked)
{
StoreFromRegister(preg);
@ -151,12 +152,13 @@ void GPRRegCache::FlushR(X64Reg reg)
int GPRRegCache::SanityCheck() const {
for (int i = 0; i < NUM_MIPS_GPRS; i++) {
const MIPSGPReg r = MIPSGPReg(i);
if (regs[i].away) {
if (regs[i].location.IsSimpleReg()) {
Gen::X64Reg simple = regs[i].location.GetSimpleReg();
if (xregs[simple].allocLocked)
return 1;
if (xregs[simple].mipsReg != i)
if (xregs[simple].mipsReg != r)
return 2;
}
else if (regs[i].location.IsImm())
@ -166,21 +168,21 @@ int GPRRegCache::SanityCheck() const {
return 0;
}
void GPRRegCache::DiscardRegContentsIfCached(int preg) {
void GPRRegCache::DiscardRegContentsIfCached(MIPSGPReg preg) {
if (regs[preg].away && regs[preg].location.IsSimpleReg()) {
X64Reg xr = regs[preg].location.GetSimpleReg();
xregs[xr].free = true;
xregs[xr].dirty = false;
xregs[xr].mipsReg = -1;
xregs[xr].mipsReg = MIPS_REG_INVALID;
regs[preg].away = false;
regs[preg].location = GetDefaultLocation(preg);
}
}
void GPRRegCache::SetImmediate32(int preg, u32 immValue) {
void GPRRegCache::SetImmediate32(MIPSGPReg preg, u32 immValue) {
// ZERO is always zero. Let's just make sure.
if (preg == 0)
if (preg == MIPS_REG_ZERO)
immValue = 0;
DiscardRegContentsIfCached(preg);
@ -188,17 +190,17 @@ void GPRRegCache::SetImmediate32(int preg, u32 immValue) {
regs[preg].location = Imm32(immValue);
}
bool GPRRegCache::IsImmediate(int preg) const {
bool GPRRegCache::IsImmediate(MIPSGPReg preg) const {
// Always say yes for ZERO, even if it's in a temp reg.
if (preg == 0)
if (preg == MIPS_REG_ZERO)
return true;
return regs[preg].location.IsImm();
}
u32 GPRRegCache::GetImmediate32(int preg) const {
u32 GPRRegCache::GetImmediate32(MIPSGPReg preg) const {
_dbg_assert_msg_(JIT, IsImmediate(preg), "Reg %d must be an immediate.", preg);
// Always 0 for ZERO.
if (preg == 0)
if (preg == MIPS_REG_ZERO)
return 0;
return regs[preg].location.GetImmValue();
}
@ -209,12 +211,12 @@ const int *GPRRegCache::GetAllocationOrder(int &count) {
}
OpArg GPRRegCache::GetDefaultLocation(int reg) const {
OpArg GPRRegCache::GetDefaultLocation(MIPSGPReg reg) const {
return M(&mips->r[reg]);
}
void GPRRegCache::KillImmediate(int preg, bool doLoad, bool makeDirty) {
void GPRRegCache::KillImmediate(MIPSGPReg preg, bool doLoad, bool makeDirty) {
if (regs[preg].away) {
if (regs[preg].location.IsImm())
BindToRegister(preg, doLoad, makeDirty);
@ -223,7 +225,7 @@ void GPRRegCache::KillImmediate(int preg, bool doLoad, bool makeDirty) {
}
}
void GPRRegCache::BindToRegister(int i, bool doLoad, bool makeDirty) {
void GPRRegCache::BindToRegister(MIPSGPReg i, bool doLoad, bool makeDirty) {
if (!regs[i].away && regs[i].location.IsImm())
PanicAlert("Bad immediate");
@ -237,13 +239,13 @@ void GPRRegCache::BindToRegister(int i, bool doLoad, bool makeDirty) {
OpArg newloc = ::Gen::R(xr);
if (doLoad) {
// Force ZERO to be 0.
if (i == 0)
if (i == MIPS_REG_ZERO)
emit->MOV(32, newloc, Imm32(0));
else
emit->MOV(32, newloc, regs[i].location);
}
for (int j = 0; j < 32; j++) {
if (i != j && regs[j].location.IsSimpleReg() && regs[j].location.GetSimpleReg() == xr) {
if (i != MIPSGPReg(j) && regs[j].location.IsSimpleReg() && regs[j].location.GetSimpleReg() == xr) {
ERROR_LOG(JIT, "BindToRegister: Strange condition");
Crash();
}
@ -260,13 +262,13 @@ void GPRRegCache::BindToRegister(int i, bool doLoad, bool makeDirty) {
}
}
void GPRRegCache::StoreFromRegister(int i) {
void GPRRegCache::StoreFromRegister(MIPSGPReg i) {
if (regs[i].away) {
bool doStore;
if (regs[i].location.IsSimpleReg()) {
X64Reg xr = RX(i);
xregs[xr].free = true;
xregs[xr].mipsReg = -1;
xregs[xr].mipsReg = MIPS_REG_INVALID;
doStore = xregs[xr].dirty;
xregs[xr].dirty = false;
} else {
@ -275,7 +277,7 @@ void GPRRegCache::StoreFromRegister(int i) {
}
OpArg newLoc = GetDefaultLocation(i);
// But never store to ZERO.
if (doStore && i != 0)
if (doStore && i != MIPS_REG_ZERO)
emit->MOV(32, newLoc, regs[i].location);
regs[i].location = newLoc;
regs[i].away = false;
@ -288,17 +290,18 @@ void GPRRegCache::Flush() {
PanicAlert("Someone forgot to unlock X64 reg %i.", i);
}
for (int i = 0; i < NUM_MIPS_GPRS; i++) {
const MIPSGPReg r = MIPSGPReg(i);
if (regs[i].locked) {
PanicAlert("Somebody forgot to unlock MIPS reg %i.", i);
}
if (regs[i].away) {
if (regs[i].location.IsSimpleReg()) {
X64Reg xr = RX(i);
StoreFromRegister(i);
X64Reg xr = RX(r);
StoreFromRegister(r);
xregs[xr].dirty = false;
}
else if (regs[i].location.IsImm()) {
StoreFromRegister(i);
StoreFromRegister(r);
} else {
_assert_msg_(DYNA_REC,0,"Jit64 - Flush unhandled case, reg %i PC: %08x", i, mips->pc);
}

View File

@ -18,6 +18,7 @@
#pragma once
#include "Common/x64Emitter.h"
#include "Core/MIPS/MIPS.h"
#include "Core/MIPS/MIPSAnalyst.h"
using namespace Gen;
@ -38,7 +39,7 @@ struct MIPSCachedReg {
};
struct X64CachedReg {
int mipsReg;
MIPSGPReg mipsReg;
bool dirty;
bool free;
bool allocLocked;
@ -56,7 +57,7 @@ public:
~GPRRegCache() {}
void Start(MIPSState *mips, MIPSAnalyst::AnalysisResults &stats);
void DiscardRegContentsIfCached(int preg);
void DiscardRegContentsIfCached(MIPSGPReg preg);
void SetEmitter(XEmitter *emitter) {emit = emitter;}
void FlushR(X64Reg reg);
@ -71,30 +72,30 @@ public:
void Flush();
void FlushBeforeCall();
int SanityCheck() const;
void KillImmediate(int preg, bool doLoad, bool makeDirty);
void KillImmediate(MIPSGPReg preg, bool doLoad, bool makeDirty);
void BindToRegister(int preg, bool doLoad = true, bool makeDirty = true);
void StoreFromRegister(int preg);
void BindToRegister(MIPSGPReg preg, bool doLoad = true, bool makeDirty = true);
void StoreFromRegister(MIPSGPReg preg);
const OpArg &R(int preg) const {return regs[preg].location;}
X64Reg RX(int preg) const
const OpArg &R(MIPSGPReg preg) const {return regs[preg].location;}
X64Reg RX(MIPSGPReg preg) const
{
if (regs[preg].away && regs[preg].location.IsSimpleReg())
return regs[preg].location.GetSimpleReg();
PanicAlert("Not so simple - %i", preg);
return (X64Reg)-1;
}
OpArg GetDefaultLocation(int reg) const;
OpArg GetDefaultLocation(MIPSGPReg reg) const;
// Register locking.
void Lock(int p1, int p2=0xff, int p3=0xff, int p4=0xff);
void Lock(MIPSGPReg p1, MIPSGPReg p2 = MIPS_REG_INVALID, MIPSGPReg p3 = MIPS_REG_INVALID, MIPSGPReg p4 = MIPS_REG_INVALID);
void LockX(int x1, int x2=0xff, int x3=0xff, int x4=0xff);
void UnlockAll();
void UnlockAllX();
void SetImmediate32(int preg, u32 immValue);
bool IsImmediate(int preg) const;
u32 GetImmediate32(int preg) const;
void SetImmediate32(MIPSGPReg preg, u32 immValue);
bool IsImmediate(MIPSGPReg preg) const;
u32 GetImmediate32(MIPSGPReg preg) const;
void GetState(GPRRegCacheState &state) const;
void RestoreState(const GPRRegCacheState state);