ppsspp/Core/MIPS/MIPSDis.cpp
Sacha 41f5abab31 PPSSPP ported to Blackberry10
Now builds on Playbook and Dev Alpha
Make emulator more compatible with other OS (case sensitivity, defines, includes)
Uses Android's code paths and backend
2012-11-05 23:09:49 +10:00

333 lines
7.9 KiB
C++

// Copyright (c) 2012- PPSSPP Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0 or later versions.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#include "../HLE/HLE.h"
#include "MIPS.h"
#include "MIPSDis.h"
#include "MIPSTables.h"
#include "MIPSDebugInterface.h"
#if defined(ANDROID) || defined(BLACKBERRY)
#include "ARM/Jit.h"
#else
#include "x86/Jit.h"
#endif
#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 RN(i) currentDebugMIPS->GetRegName(0,i)
#define FN(i) currentDebugMIPS->GetRegName(1,i)
//#define VN(i) currentMIPS->GetRegName(2,i)
u32 disPC;
namespace MIPSDis
{
void Dis_Generic(u32 op, char *out)
{
sprintf(out, "%s\t --- unknown ---", MIPSGetName(op));
}
void Dis_mxc1(u32 op, char *out)
{
int fs = (op>>11) & 0x1F;
int rt = (op>>16) & 0x1F;
const char *name = MIPSGetName(op);
sprintf(out, "%s\t%s, %s",name,RN(rt),FN(fs));
}
void Dis_FPU3op(u32 op, char *out)
{
int ft = (op>>16) & 0x1F;
int fs = (op>>11) & 0x1F;
int fd = (op>>6) & 0x1F;
const char *name = MIPSGetName(op);
sprintf(out, "%s\t%s, %s, %s",name,FN(fd),FN(fs),FN(ft));
}
void Dis_FPU2op(u32 op, char *out)
{
int fs = (op>>11) & 0x1F;
int fd = (op>>6) & 0x1F;
const char *name = MIPSGetName(op);
sprintf(out, "%s\t%s, %s",name,FN(fd),FN(fs));
}
void Dis_FPULS(u32 op, char *out)
{
int offset = (signed short)(op&0xFFFF);
int ft = ((op>>16)&0x1f);
int rs = (op>>21) & 0x1f;
const char *name = MIPSGetName(op);
sprintf(out, "%s\t%s, %d(%s)",name,FN(ft),offset,RN(rs));
}
void Dis_FPUComp(u32 op, char *out)
{
int fs = ((op>>11)&0x1f);
int ft = ((op>>16)&0x1f);
const char *name = MIPSGetName(op);
sprintf(out, "%s\t%s, %s",name,FN(fs),RN(ft));
}
void Dis_FPUBranch(u32 op, char *out)
{
u32 off = disPC;
int imm = (signed short)(op&0xFFFF)<<2;
off += imm + 4;
const char *name = MIPSGetName(op);
sprintf(out, "%s\t->$%08x",name,off);
}
void Dis_RelBranch(u32 op, char *out)
{
u32 off = disPC;
int imm = (signed short)(op&0xFFFF)<<2;
int rs = (op>>21) & 0x1F;
off += imm + 4;
const char *name = MIPSGetName(op);
sprintf(out, "%s\t%s, ->$%08x",name,RN(rs),off);
}
void Dis_Syscall(u32 op, char *out)
{
u32 callno = (op>>6) & 0xFFFFF; //20 bits
int funcnum = callno & 0xFFF;
int modulenum = (callno & 0xFF000) >> 12;
sprintf(out, "syscall\t %s",/*PSPHLE::GetModuleName(modulenum),*/GetFuncName(modulenum, funcnum));
}
void Dis_ToHiloTransfer(u32 op, char *out)
{
int rs = (op>>21) & 0x1F;
const char *name = MIPSGetName(op);
sprintf(out, "%s\t%s",name,RN(rs));
}
void Dis_FromHiloTransfer(u32 op, char *out)
{
int rd = (op>>11) & 0x1F;
const char *name = MIPSGetName(op);
sprintf(out, "%s\t%s",name,RN(rd));
}
void Dis_RelBranch2(u32 op, char *out)
{
u32 off = disPC;
int imm = (signed short)(op&0xFFFF)<<2;
int rt = (op>>16) & 0x1F;
int rs = (op>>21) & 0x1F;
off += imm + 4;
const char *name = MIPSGetName(op);
int o = op>>26;
if (o==4 && rs == rt)//beq
sprintf(out,"b\t->$%08x",off);
else if (o==4 && rs == rt)//beq
sprintf(out,"bl\t->$%08x",off);
else
sprintf(out, "%s\t%s, %s, ->$%08x",name,RN(rt),RN(rs),off);
}
void Dis_IType(u32 op, char *out)
{
int imm = (signed short)(op&0xFFFF);
int rt = (op>>16) & 0x1F;
int rs = (op>>21) & 0x1F;
const char *name = MIPSGetName(op);
sprintf(out, "%s\t%s, %s, %i",name,RN(rt),RN(rs),imm);
}
void Dis_ori(u32 op, char *out)
{
int imm = (signed short)(op&0xFFFF);
int rt = (op>>16) & 0x1F;
int rs = (op>>21) & 0x1F;
const char *name = MIPSGetName(op);
if (rs == 0)
sprintf(out, "li\t%s, %i",RN(rt),imm);
else
sprintf(out, "%s\t%s, %s, %i",name,RN(rt),RN(rs),imm);
}
void Dis_IType1(u32 op, char *out)
{
int imm = (signed short)(op&0xFFFF);
int rt = (op>>16) & 0x1F;
const char *name = MIPSGetName(op);
sprintf(out, "%s\t%s, %i",name,RN(rt),imm);
}
void Dis_addi(u32 op, char *out)
{
int imm = (signed short)(op&0xFFFF);
int rt = (op>>16) & 0x1F;
int rs = (op>>21) & 0x1F;
if (rs == 0)
sprintf(out, "li\t%s, %i",RN(rt),imm);
else
Dis_IType(op,out);
}
void Dis_ITypeMem(u32 op, char *out)
{
int imm = (signed short)(op&0xFFFF);
int rt = (op>>16) & 0x1F;
int rs = (op>>21) & 0x1F;
const char *name = MIPSGetName(op);
sprintf(out, "%s\t%s, %i(%s)",name,RN(rt),imm,RN(rs));
}
void Dis_RType2(u32 op, char *out)
{
int rs = (op>>21) & 0x1F;
int rd = (op>>11) & 0x1F;
const char *name = MIPSGetName(op);
sprintf(out, "%s\t%s, %s",name,RN(rd),RN(rs));
}
void Dis_RType3(u32 op, char *out)
{
int rt = (op>>16) & 0x1F;
int rs = (op>>21) & 0x1F;
int rd = (op>>11) & 0x1F;
const char *name = MIPSGetName(op);
sprintf(out, "%s\t%s, %s, %s",name,RN(rd),RN(rs),RN(rt));
}
void Dis_addu(u32 op, char *out)
{
int rt = (op>>16) & 0x1F;
int rs = (op>>21) & 0x1F;
int rd = (op>>11) & 0x1F;
const char *name = MIPSGetName(op);
if (rs==0 && rt==0)
sprintf(out,"li\t%s, 0",RN(rd));
else if (rs == 0)
sprintf(out,"mov\t%s, %s",RN(rd),RN(rt));
else if (rt == 0)
sprintf(out,"mov\t%s, %s",RN(rd),RN(rs));
else
sprintf(out, "%s\t%s, %s, %s",name,RN(rd),RN(rs),RN(rt));
}
void Dis_ShiftType(u32 op, char *out)
{
int rt = (op>>16) & 0x1F;
int rs = (op>>21) & 0x1F;
int rd = (op>>11) & 0x1F;
int sa = (op>>6) & 0x1F;
const char *name = MIPSGetName(op);
if (((op & 0x3f) == 2) && rs == 1)
name = "rotr";
if (((op & 0x3f) == 6) && sa == 1)
name = "rotrv";
sprintf(out, "%s\t%s, %s, %d",name,RN(rd),RN(rt),sa);
}
void Dis_VarShiftType(u32 op, char *out)
{
int rt = (op>>16) & 0x1F;
int rs = (op>>21) & 0x1F;
int rd = (op>>11) & 0x1F;
const char *name = MIPSGetName(op);
sprintf(out, "%s\t%s, %s, %s",name,RN(rd),RN(rt),RN(rs));
}
void Dis_MulDivType(u32 op, char *out)
{
int rt = (op>>16) & 0x1F;
int rs = (op>>21) & 0x1F;
const char *name = MIPSGetName(op);
sprintf(out, "%s\t%s, %s",name,RN(rs),RN(rt));
}
void Dis_Special3(u32 op, char *out)
{
int rs = _RS;
int Rt = _RT;
int pos = _POS;
const char *name = MIPSGetName(op);
switch (op & 0x3f)
{
case 0x0: //ext
{
int size = _SIZE + 1;
sprintf(out,"%s\t%s, %s, %i, %i",name,RN(Rt),RN(rs),pos,size);
}
break;
case 0x4: // ins
{
int size = (_SIZE + 1) - pos;
sprintf(out,"%s\t%s, %s, %i, %i",name,RN(Rt),RN(rs),pos,size);
}
break;
}
}
void Dis_JumpType(u32 op, char *out)
{
u32 off = ((op & 0x3FFFFFF) << 2);
u32 addr = (disPC & 0xF0000000) | off;
const char *name = MIPSGetName(op);
sprintf(out, "%s\t->$%08x",name,addr);
}
void Dis_JumpRegType(u32 op, char *out)
{
int rs = (op>>21)&0x1f;
const char *name = MIPSGetName(op);
sprintf(out, "%s\t->%s",name,RN(rs));
}
void Dis_Allegrex(u32 op, char *out)
{
int rt = (op>>16) & 0x1F;
int rd = (op>>11) & 0x1F;
const char *name = MIPSGetName(op);
sprintf(out,"%s\t%s,%s",name,RN(rd),RN(rt));
}
void Dis_Allegrex2(u32 op, char *out)
{
int rt = (op>>16) & 0x1F;
int rd = (op>>11) & 0x1F;
const char *name = MIPSGetName(op);
sprintf(out,"%s\t%s,%s",name,RN(rd),RN(rt));
}
void Dis_Emuhack(u32 op, char *out)
{
//const char *name = MIPSGetName(op);
//sprintf(out,"%s\t-",name);
out[0]='*';
// MIPSDisAsm(MIPSComp::GetOriginalOp(op), currentDebugMIPS->GetPC(), out+1);
}
}