mirror of
https://github.com/libretro/ppsspp.git
synced 2024-11-28 10:51:06 +00:00
Improve typesafety in the x86 regalloc.
This commit is contained in:
parent
3156b95d3f
commit
97aa1a631e
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -44,5 +44,4 @@
|
||||
|
||||
namespace MIPSComp {
|
||||
extern Jit *jit;
|
||||
extern const float cst_constants[32];
|
||||
}
|
||||
|
@ -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),
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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_;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user