Merge pull request #17356 from unknownbrackets/minor-cleanup

Cleanup some more string formats, mostly in debugger
This commit is contained in:
Henrik Rydgård 2023-05-23 08:29:23 +02:00 committed by GitHub
commit 67a35d3476
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
45 changed files with 462 additions and 531 deletions

View File

@ -32,10 +32,10 @@
#if defined(CPU_FEATURES_OS_LINUX) #if defined(CPU_FEATURES_OS_LINUX)
#define USE_CPU_FEATURES 1 #define USE_CPU_FEATURES 1
#endif #endif
#elif PPSSPP_ARCH(ARM64) && defined(__aarch64__) #elif PPSSPP_ARCH(ARM64)
#include "ext/cpu_features/include/cpuinfo_aarch64.h" #include "ext/cpu_features/include/cpuinfo_aarch64.h"
#if defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID) #if defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID) || defined(CPU_FEATURES_OS_WINDOWS)
#define USE_CPU_FEATURES 1 #define USE_CPU_FEATURES 1
#endif #endif
#endif #endif
@ -54,7 +54,7 @@
std::string GetCPUBrandString(); std::string GetCPUBrandString();
#else #else
// No CPUID on ARM, so we'll have to read the registry // No CPUID on ARM, so we'll have to read the registry
#include <windows.h> #include "Common/CommonWindows.h"
std::string GetCPUBrandString() { std::string GetCPUBrandString() {
std::string cpu_string; std::string cpu_string;

View File

@ -1,3 +1,4 @@
#include "Common/StringUtils.h"
#include "expression_parser.h" #include "expression_parser.h"
#include <ctype.h> #include <ctype.h>
#include <cstring> #include <cstring>
@ -14,7 +15,7 @@ typedef enum {
typedef enum { EXCOMM_CONST, EXCOMM_CONST_FLOAT, EXCOMM_REF, EXCOMM_OP } ExpressionCommand; typedef enum { EXCOMM_CONST, EXCOMM_CONST_FLOAT, EXCOMM_REF, EXCOMM_OP } ExpressionCommand;
static char expressionError[512]; static std::string expressionError;
typedef struct { typedef struct {
char Name[4]; char Name[4];
@ -219,7 +220,7 @@ bool isAlphaNum(char c)
bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, PostfixExpression& dest) bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, PostfixExpression& dest)
{ {
expressionError[0] = 0; expressionError.clear();
int infixPos = 0; int infixPos = 0;
int infixLen = (int)strlen(infix); int infixLen = (int)strlen(infix);
@ -253,7 +254,7 @@ bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, Postf
isFloat = true; isFloat = true;
else if (parseNumber(subStr,16,subPos,value) == false) else if (parseNumber(subStr,16,subPos,value) == false)
{ {
snprintf(expressionError, sizeof(expressionError), "Invalid number \"%s\"",subStr); expressionError = StringFromFormat("Invalid number \"%s\"", subStr);
return false; return false;
} }
@ -282,14 +283,14 @@ bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, Postf
continue; continue;
} }
snprintf(expressionError, sizeof(expressionError), "Invalid symbol \"%s\"",subStr); expressionError = StringFromFormat("Invalid symbol \"%s\"", subStr);
return false; return false;
} else { } else {
int len; int len;
ExpressionOpcodeType type = getExpressionOpcode(&infix[infixPos],len,lastOpcode); ExpressionOpcodeType type = getExpressionOpcode(&infix[infixPos],len,lastOpcode);
if (type == EXOP_NONE) if (type == EXOP_NONE)
{ {
snprintf(expressionError, sizeof(expressionError), "Invalid operator at \"%s\"",&infix[infixPos]); expressionError = StringFromFormat("Invalid operator at \"%s\"", &infix[infixPos]);
return false; return false;
} }
@ -304,7 +305,7 @@ bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, Postf
{ {
if (opcodeStack.empty()) if (opcodeStack.empty())
{ {
snprintf(expressionError, sizeof(expressionError), "Closing parenthesis without opening one"); expressionError = "Closing parenthesis without opening one";
return false; return false;
} }
ExpressionOpcodeType t = opcodeStack[opcodeStack.size()-1]; ExpressionOpcodeType t = opcodeStack[opcodeStack.size()-1];
@ -318,7 +319,7 @@ bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, Postf
{ {
if (opcodeStack.empty()) if (opcodeStack.empty())
{ {
snprintf(expressionError, sizeof(expressionError), "Closing bracket without opening one"); expressionError = "Closing bracket without opening one";
return false; return false;
} }
ExpressionOpcodeType t = opcodeStack[opcodeStack.size()-1]; ExpressionOpcodeType t = opcodeStack[opcodeStack.size()-1];
@ -371,7 +372,7 @@ bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, Postf
if (t == EXOP_BRACKETL) // opening bracket without closing one if (t == EXOP_BRACKETL) // opening bracket without closing one
{ {
snprintf(expressionError, sizeof(expressionError), "Parenthesis not closed"); expressionError = "Parenthesis not closed";
return false; return false;
} }
dest.push_back(ExpressionPair(EXCOMM_OP,t)); dest.push_back(ExpressionPair(EXCOMM_OP,t));
@ -430,7 +431,7 @@ bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs,
opcode = exp[num++].second; opcode = exp[num++].second;
if (valueStack.size() < ExpressionOpcodes[opcode].args) if (valueStack.size() < ExpressionOpcodes[opcode].args)
{ {
snprintf(expressionError, sizeof(expressionError), "Not enough arguments"); expressionError = "Not enough arguments";
return false; return false;
} }
for (int l = 0; l < ExpressionOpcodes[opcode].args; l++) for (int l = 0; l < ExpressionOpcodes[opcode].args; l++)
@ -446,12 +447,12 @@ bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs,
case EXOP_MEMSIZE: // must be followed by EXOP_MEM case EXOP_MEMSIZE: // must be followed by EXOP_MEM
if (exp[num++].second != EXOP_MEM) if (exp[num++].second != EXOP_MEM)
{ {
snprintf(expressionError, sizeof(expressionError), "Invalid memsize operator"); expressionError = "Invalid memsize operator";
return false; return false;
} }
uint32_t val; uint32_t val;
if(funcs->getMemoryValue(arg[1],arg[0],val,expressionError, sizeof(expressionError)) == false) if (funcs->getMemoryValue(arg[1], arg[0], val, &expressionError) == false)
{ {
return false; return false;
} }
@ -460,7 +461,7 @@ bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs,
case EXOP_MEM: case EXOP_MEM:
{ {
uint32_t val; uint32_t val;
if (funcs->getMemoryValue(arg[0],4,val,expressionError, sizeof(expressionError)) == false) if (funcs->getMemoryValue(arg[0], 4, val, &expressionError) == false)
{ {
return false; return false;
} }
@ -490,7 +491,7 @@ bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs,
case EXOP_DIV: // a/b case EXOP_DIV: // a/b
if (arg[0] == 0) if (arg[0] == 0)
{ {
snprintf(expressionError, sizeof(expressionError), "Division by zero"); expressionError = "Division by zero";
return false; return false;
} }
if (useFloat) if (useFloat)
@ -501,7 +502,7 @@ bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs,
case EXOP_MOD: // a%b case EXOP_MOD: // a%b
if (arg[0] == 0) if (arg[0] == 0)
{ {
snprintf(expressionError, sizeof(expressionError), "Modulo by zero"); expressionError = "Modulo by zero";
return false; return false;
} }
valueStack.push_back(arg[1]%arg[0]); valueStack.push_back(arg[1]%arg[0]);
@ -574,7 +575,7 @@ bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs,
case EXOP_TERTELSE: // exp ? exp : exp, else muss zuerst kommen! case EXOP_TERTELSE: // exp ? exp : exp, else muss zuerst kommen!
if (exp[num++].second != EXOP_TERTIF) if (exp[num++].second != EXOP_TERTIF)
{ {
snprintf(expressionError, sizeof(expressionError), "Invalid tertiary operator"); expressionError = "Invalid tertiary operator";
return false; return false;
} }
valueStack.push_back(arg[2]?arg[1]:arg[0]); valueStack.push_back(arg[2]?arg[1]:arg[0]);
@ -595,8 +596,9 @@ bool parseExpression(const char *exp, IExpressionFunctions *funcs, uint32_t &des
return parsePostfixExpression(postfix,funcs,dest); return parsePostfixExpression(postfix,funcs,dest);
} }
const char* getExpressionError() const char *getExpressionError()
{ {
if (expressionError[0] == 0) snprintf(expressionError, sizeof(expressionError), "Invalid expression"); if (expressionError.empty())
return expressionError; expressionError = "Invalid expression";
return expressionError.c_str();
} }

View File

@ -2,6 +2,7 @@
#include <cstdint> #include <cstdint>
#include <cstddef> #include <cstddef>
#include <string>
#include <vector> #include <vector>
typedef std::pair<uint32_t, uint32_t> ExpressionPair; typedef std::pair<uint32_t, uint32_t> ExpressionPair;
@ -21,7 +22,7 @@ public:
virtual bool parseSymbol(char* str, uint32_t& symbolValue) = 0; virtual bool parseSymbol(char* str, uint32_t& symbolValue) = 0;
virtual uint32_t getReferenceValue(uint32_t referenceIndex) = 0; virtual uint32_t getReferenceValue(uint32_t referenceIndex) = 0;
virtual ExpressionType getReferenceType(uint32_t referenceIndex) = 0; virtual ExpressionType getReferenceType(uint32_t referenceIndex) = 0;
virtual bool getMemoryValue(uint32_t address, int size, uint32_t& dest, char *error, size_t errorBufSize) = 0; virtual bool getMemoryValue(uint32_t address, int size, uint32_t& dest, std::string *error) = 0;
}; };
bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, PostfixExpression& dest); bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, PostfixExpression& dest);

View File

@ -209,8 +209,8 @@ void CPUInfo::Detect()
RiscV_C = ExtensionSupported(hwcap, 'C'); RiscV_C = ExtensionSupported(hwcap, 'C');
RiscV_V = ExtensionSupported(hwcap, 'V'); RiscV_V = ExtensionSupported(hwcap, 'V');
RiscV_B = ExtensionSupported(hwcap, 'B'); RiscV_B = ExtensionSupported(hwcap, 'B');
// Let's assume for now... // We assume as in RVA20U64 that F means Zicsr is available.
RiscV_Zicsr = RiscV_M && RiscV_A && RiscV_F && RiscV_D; RiscV_Zicsr = RiscV_F;
#ifdef USE_CPU_FEATURES #ifdef USE_CPU_FEATURES
cpu_features::RiscvInfo info = cpu_features::GetRiscvInfo(); cpu_features::RiscvInfo info = cpu_features::GetRiscvInfo();
@ -220,6 +220,7 @@ void CPUInfo::Detect()
RiscV_F = info.features.F; RiscV_F = info.features.F;
RiscV_D = info.features.D; RiscV_D = info.features.D;
RiscV_C = info.features.C; RiscV_C = info.features.C;
RiscV_V = info.features.V;
RiscV_Zicsr = info.features.Zicsr; RiscV_Zicsr = info.features.Zicsr;
truncate_cpy(brand_string, info.uarch); truncate_cpy(brand_string, info.uarch);

View File

@ -812,6 +812,7 @@ static const ConfigSetting debuggerSettings[] = {
ConfigSetting("ShowGpuProfile", &g_Config.bShowGpuProfile, false, CfgFlag::DONT_SAVE), ConfigSetting("ShowGpuProfile", &g_Config.bShowGpuProfile, false, CfgFlag::DONT_SAVE),
ConfigSetting("SkipDeadbeefFilling", &g_Config.bSkipDeadbeefFilling, false, CfgFlag::DEFAULT), ConfigSetting("SkipDeadbeefFilling", &g_Config.bSkipDeadbeefFilling, false, CfgFlag::DEFAULT),
ConfigSetting("FuncHashMap", &g_Config.bFuncHashMap, false, CfgFlag::DEFAULT), ConfigSetting("FuncHashMap", &g_Config.bFuncHashMap, false, CfgFlag::DEFAULT),
ConfigSetting("SkipFuncHashMap", &g_Config.sSkipFuncHashMap, "", CfgFlag::DEFAULT),
ConfigSetting("MemInfoDetailed", &g_Config.bDebugMemInfoDetailed, false, CfgFlag::DEFAULT), ConfigSetting("MemInfoDetailed", &g_Config.bDebugMemInfoDetailed, false, CfgFlag::DEFAULT),
ConfigSetting("DrawFrameGraph", &g_Config.bDrawFrameGraph, false, CfgFlag::DEFAULT), ConfigSetting("DrawFrameGraph", &g_Config.bDrawFrameGraph, false, CfgFlag::DEFAULT),
}; };

View File

@ -489,6 +489,7 @@ public:
// Double edged sword: much easier debugging, but not accurate. // Double edged sword: much easier debugging, but not accurate.
bool bSkipDeadbeefFilling; bool bSkipDeadbeefFilling;
bool bFuncHashMap; bool bFuncHashMap;
std::string sSkipFuncHashMap;
bool bDebugMemInfoDetailed; bool bDebugMemInfoDetailed;
bool bDrawFrameGraph; bool bDrawFrameGraph;

View File

@ -26,7 +26,6 @@ struct MemMap;
class DebugInterface { class DebugInterface {
public: public:
virtual const char *disasm(unsigned int address, unsigned int align) {return "NODEBUGGER";}
virtual int getInstructionSize(int instruction) {return 1;} virtual int getInstructionSize(int instruction) {return 1;}
virtual bool isAlive() {return true;} virtual bool isAlive() {return true;}
@ -55,14 +54,14 @@ public:
virtual u32 GetPC() = 0; virtual u32 GetPC() = 0;
virtual void SetPC(u32 _pc) = 0; virtual void SetPC(u32 _pc) = 0;
virtual u32 GetLR() {return GetPC();} virtual u32 GetLR() {return GetPC();}
virtual void DisAsm(u32 op, u32 pc, int align, char *out, size_t outSize) { virtual void DisAsm(u32 pc, char *out, size_t outSize) {
snprintf(out, outSize, "[%08x] UNKNOWN", op); snprintf(out, outSize, "[%08x] UNKNOWN", pc);
} }
// More stuff for debugger // More stuff for debugger
virtual int GetNumCategories() {return 0;} virtual int GetNumCategories() {return 0;}
virtual int GetNumRegsInCategory(int cat) {return 0;} virtual int GetNumRegsInCategory(int cat) {return 0;}
virtual const char *GetCategoryName(int cat) {return 0;} virtual const char *GetCategoryName(int cat) {return 0;}
virtual const char *GetRegName(int cat, int index) {return 0;} virtual std::string GetRegName(int cat, int index) { return ""; }
virtual void PrintRegValue(int cat, int index, char *out, size_t outSize) { virtual void PrintRegValue(int cat, int index, char *out, size_t outSize) {
snprintf(out, outSize, "%08X", GetGPR32Value(index)); snprintf(out, outSize, "%08X", GetGPR32Value(index));
} }

View File

@ -102,36 +102,33 @@ static HashType computeHash(u32 address, u32 size)
} }
void parseDisasm(const char* disasm, char* opcode, char* arguments, bool insertSymbols) static void parseDisasm(const char *disasm, char *opcode, size_t opcodeSize, char *arguments, size_t argumentsSize, bool insertSymbols) {
{
// copy opcode // copy opcode
while (*disasm != 0 && *disasm != '\t') size_t opcodePos = 0;
{ while (*disasm != 0 && *disasm != '\t' && opcodePos + 1 < opcodeSize) {
*opcode++ = *disasm++; opcode[opcodePos++] = *disasm++;
} }
*opcode = 0; opcode[opcodePos] = 0;
if (*disasm++ == 0) // Otherwise it's a tab, and we skip intentionally.
{ if (*disasm++ == 0) {
*arguments = 0; *arguments = 0;
return; return;
} }
const char* jumpAddress = strstr(disasm,"->$"); const char* jumpAddress = strstr(disasm,"->$");
const char* jumpRegister = strstr(disasm,"->"); const char* jumpRegister = strstr(disasm,"->");
while (*disasm != 0) size_t argumentsPos = 0;
{ while (*disasm != 0 && argumentsPos + 1 < argumentsSize) {
// parse symbol // parse symbol
if (disasm == jumpAddress) if (disasm == jumpAddress) {
{
u32 branchTarget = 0; u32 branchTarget = 0;
sscanf(disasm+3, "%08x", &branchTarget); sscanf(disasm+3, "%08x", &branchTarget);
const std::string addressSymbol = g_symbolMap->GetLabelString(branchTarget); const std::string addressSymbol = g_symbolMap->GetLabelString(branchTarget);
if (!addressSymbol.empty() && insertSymbols) if (!addressSymbol.empty() && insertSymbols) {
{ argumentsPos += snprintf(&arguments[argumentsPos], argumentsSize - argumentsPos, "%s", addressSymbol.c_str());
arguments += sprintf(arguments, "%s", addressSymbol.c_str());
} else { } else {
arguments += sprintf(arguments, "0x%08X", branchTarget); argumentsPos += snprintf(&arguments[argumentsPos], argumentsSize - argumentsPos, "0x%08X", branchTarget);
} }
disasm += 3+8; disasm += 3+8;
@ -141,15 +138,14 @@ void parseDisasm(const char* disasm, char* opcode, char* arguments, bool insertS
if (disasm == jumpRegister) if (disasm == jumpRegister)
disasm += 2; disasm += 2;
if (*disasm == ' ') if (*disasm == ' ') {
{
disasm++; disasm++;
continue; continue;
} }
*arguments++ = *disasm++; arguments[argumentsPos++] = *disasm++;
} }
*arguments = 0; arguments[argumentsPos] = 0;
} }
std::map<u32,DisassemblyEntry*>::iterator findDisassemblyEntry(std::map<u32,DisassemblyEntry*>& entries, u32 address, bool exact) std::map<u32,DisassemblyEntry*>::iterator findDisassemblyEntry(std::map<u32,DisassemblyEntry*>& entries, u32 address, bool exact)
@ -766,8 +762,9 @@ bool DisassemblyOpcode::disassemble(u32 address, DisassemblyLineInfo &dest, bool
cpuDebug = DisassemblyManager::getCpu(); cpuDebug = DisassemblyManager::getCpu();
char opcode[64],arguments[256]; char opcode[64],arguments[256];
const char *dizz = cpuDebug->disasm(address, 4); char dizz[512];
parseDisasm(dizz,opcode,arguments,insertSymbols); cpuDebug->DisAsm(address, dizz, sizeof(dizz));
parseDisasm(dizz, opcode, sizeof(opcode), arguments, sizeof(arguments), insertSymbols);
dest.type = DISTYPE_OPCODE; dest.type = DISTYPE_OPCODE;
dest.name = opcode; dest.name = opcode;
dest.params = arguments; dest.params = arguments;
@ -850,9 +847,9 @@ bool DisassemblyMacro::disassemble(u32 address, DisassemblyLineInfo &dest, bool
addressSymbol = g_symbolMap->GetLabelString(immediate); addressSymbol = g_symbolMap->GetLabelString(immediate);
if (!addressSymbol.empty() && insertSymbols) { if (!addressSymbol.empty() && insertSymbols) {
snprintf(buffer, sizeof(buffer), "%s,%s", cpuDebug->GetRegName(0, rt), addressSymbol.c_str()); snprintf(buffer, sizeof(buffer), "%s,%s", cpuDebug->GetRegName(0, rt).c_str(), addressSymbol.c_str());
} else { } else {
snprintf(buffer, sizeof(buffer), "%s,0x%08X", cpuDebug->GetRegName(0, rt), immediate); snprintf(buffer, sizeof(buffer), "%s,0x%08X", cpuDebug->GetRegName(0, rt).c_str(), immediate);
} }
dest.params = buffer; dest.params = buffer;
@ -865,9 +862,9 @@ bool DisassemblyMacro::disassemble(u32 address, DisassemblyLineInfo &dest, bool
addressSymbol = g_symbolMap->GetLabelString(immediate); addressSymbol = g_symbolMap->GetLabelString(immediate);
if (!addressSymbol.empty() && insertSymbols) { if (!addressSymbol.empty() && insertSymbols) {
snprintf(buffer, sizeof(buffer), "%s,%s", cpuDebug->GetRegName(0, rt), addressSymbol.c_str()); snprintf(buffer, sizeof(buffer), "%s,%s", cpuDebug->GetRegName(0, rt).c_str(), addressSymbol.c_str());
} else { } else {
snprintf(buffer, sizeof(buffer), "%s,0x%08X", cpuDebug->GetRegName(0, rt), immediate); snprintf(buffer, sizeof(buffer), "%s,0x%08X", cpuDebug->GetRegName(0, rt).c_str(), immediate);
} }
dest.params = buffer; dest.params = buffer;

View File

@ -204,7 +204,7 @@ bool ElfReader::LoadRelocations(const Elf32_Rel *rels, int numRelocs) {
default: default:
{ {
char temp[256]; char temp[256];
MIPSDisAsm(MIPSOpcode(op), 0, temp); MIPSDisAsm(MIPSOpcode(op), 0, temp, sizeof(temp));
ERROR_LOG_REPORT(LOADER, "ARGH IT'S AN UNKNOWN RELOCATION!!!!!!!! %08x, type=%d : %s", addr, type, temp); ERROR_LOG_REPORT(LOADER, "ARGH IT'S AN UNKNOWN RELOCATION!!!!!!!! %08x, type=%d : %s", addr, type, temp);
} }
break; break;

View File

@ -142,7 +142,7 @@ namespace MIPSComp
// Prefix may say "z, z, z, z" but if this is a pair, we force to x. // Prefix may say "z, z, z, z" but if this is a pair, we force to x.
// TODO: But some ops seem to use const 0 instead? // TODO: But some ops seem to use const 0 instead?
if (regnum >= n) { if (regnum >= n) {
WARN_LOG(CPU, "JIT: Invalid VFPU swizzle: %08x : %d / %d at PC = %08x (%s)", prefix, regnum, n, GetCompilerPC(), MIPSDisasmAt(GetCompilerPC())); WARN_LOG(CPU, "JIT: Invalid VFPU swizzle: %08x : %d / %d at PC = %08x (%s)", prefix, regnum, n, GetCompilerPC(), MIPSDisasmAt(GetCompilerPC()).c_str());
regnum = 0; regnum = 0;
} }

View File

@ -383,7 +383,7 @@ const u8 *ArmJit::DoJit(u32 em_address, JitBlock *b)
if (logBlocks > 0 && dontLogBlocks == 0) { if (logBlocks > 0 && dontLogBlocks == 0) {
INFO_LOG(JIT, "=============== mips ==============="); INFO_LOG(JIT, "=============== mips ===============");
for (u32 cpc = em_address; cpc != GetCompilerPC() + 4; cpc += 4) { for (u32 cpc = em_address; cpc != GetCompilerPC() + 4; cpc += 4) {
MIPSDisAsm(Memory::Read_Opcode_JIT(cpc), cpc, temp, true); MIPSDisAsm(Memory::Read_Opcode_JIT(cpc), cpc, temp, sizeof(temp), true);
INFO_LOG(JIT, "M: %08x %s", cpc, temp); INFO_LOG(JIT, "M: %08x %s", cpc, temp);
} }
} }

View File

@ -584,11 +584,11 @@ ARMReg ArmRegCacheFPU::R(int mipsReg) {
return (ARMReg)(mr[mipsReg].reg + S0); return (ARMReg)(mr[mipsReg].reg + S0);
} else { } else {
if (mipsReg < 32) { if (mipsReg < 32) {
ERROR_LOG(JIT, "FReg %i not in ARM reg. compilerPC = %08x : %s", mipsReg, js_->compilerPC, MIPSDisasmAt(js_->compilerPC)); ERROR_LOG(JIT, "FReg %i not in ARM reg. compilerPC = %08x : %s", mipsReg, js_->compilerPC, MIPSDisasmAt(js_->compilerPC).c_str());
} else if (mipsReg < 32 + 128) { } else if (mipsReg < 32 + 128) {
ERROR_LOG(JIT, "VReg %i not in ARM reg. compilerPC = %08x : %s", mipsReg - 32, js_->compilerPC, MIPSDisasmAt(js_->compilerPC)); ERROR_LOG(JIT, "VReg %i not in ARM reg. compilerPC = %08x : %s", mipsReg - 32, js_->compilerPC, MIPSDisasmAt(js_->compilerPC).c_str());
} else { } else {
ERROR_LOG(JIT, "Tempreg %i not in ARM reg. compilerPC = %08x : %s", mipsReg - 128 - 32, js_->compilerPC, MIPSDisasmAt(js_->compilerPC)); ERROR_LOG(JIT, "Tempreg %i not in ARM reg. compilerPC = %08x : %s", mipsReg - 128 - 32, js_->compilerPC, MIPSDisasmAt(js_->compilerPC).c_str());
} }
return INVALID_REG; // BAAAD return INVALID_REG; // BAAAD
} }
@ -618,7 +618,7 @@ void ArmRegCacheFPU::QFlush(int quad) {
} }
if (qr[quad].isDirty && !qr[quad].isTemp) { if (qr[quad].isDirty && !qr[quad].isTemp) {
INFO_LOG(JIT, "Flushing Q%i (%s)", quad, GetVectorNotation(qr[quad].mipsVec, qr[quad].sz)); INFO_LOG(JIT, "Flushing Q%i (%s)", quad, GetVectorNotation(qr[quad].mipsVec, qr[quad].sz).c_str());
ARMReg q = QuadAsQ(quad); ARMReg q = QuadAsQ(quad);
// Unlike reads, when writing to the register file we need to be careful to write the correct // Unlike reads, when writing to the register file we need to be careful to write the correct
@ -881,7 +881,7 @@ ARMReg ArmRegCacheFPU::QMapReg(int vreg, VectorSize sz, int flags) {
// We didn't find the extra register, but we got a list of regs to flush. Flush 'em. // We didn't find the extra register, but we got a list of regs to flush. Flush 'em.
// Here we can check for opportunities to do a "transpose-flush" of row vectors, etc. // Here we can check for opportunities to do a "transpose-flush" of row vectors, etc.
if (!quadsToFlush.empty()) { if (!quadsToFlush.empty()) {
INFO_LOG(JIT, "New mapping %s collided with %d quads, flushing them.", GetVectorNotation(vreg, sz), (int)quadsToFlush.size()); INFO_LOG(JIT, "New mapping %s collided with %d quads, flushing them.", GetVectorNotation(vreg, sz).c_str(), (int)quadsToFlush.size());
} }
for (size_t i = 0; i < quadsToFlush.size(); i++) { for (size_t i = 0; i < quadsToFlush.size(); i++) {
QFlush(quadsToFlush[i]); QFlush(quadsToFlush[i]);
@ -973,7 +973,7 @@ ARMReg ArmRegCacheFPU::QMapReg(int vreg, VectorSize sz, int flags) {
qr[quad].isDirty = (flags & MAP_DIRTY) != 0; qr[quad].isDirty = (flags & MAP_DIRTY) != 0;
qr[quad].spillLock = true; qr[quad].spillLock = true;
INFO_LOG(JIT, "Mapped Q%i to vfpu %i (%s), sz=%i, dirty=%i", quad, vreg, GetVectorNotation(vreg, sz), (int)sz, qr[quad].isDirty); INFO_LOG(JIT, "Mapped Q%i to vfpu %i (%s), sz=%i, dirty=%i", quad, vreg, GetVectorNotation(vreg, sz).c_str(), (int)sz, qr[quad].isDirty);
if (sz == V_Single || sz == V_Pair) { if (sz == V_Single || sz == V_Pair) {
return D_0(QuadAsQ(quad)); return D_0(QuadAsQ(quad));
} else { } else {

View File

@ -134,7 +134,7 @@ namespace MIPSComp {
// Prefix may say "z, z, z, z" but if this is a pair, we force to x. // Prefix may say "z, z, z, z" but if this is a pair, we force to x.
// TODO: But some ops seem to use const 0 instead? // TODO: But some ops seem to use const 0 instead?
if (regnum >= n) { if (regnum >= n) {
WARN_LOG(CPU, "JIT: Invalid VFPU swizzle: %08x : %d / %d at PC = %08x (%s)", prefix, regnum, n, GetCompilerPC(), MIPSDisasmAt(GetCompilerPC())); WARN_LOG(CPU, "JIT: Invalid VFPU swizzle: %08x : %d / %d at PC = %08x (%s)", prefix, regnum, n, GetCompilerPC(), MIPSDisasmAt(GetCompilerPC()).c_str());
regnum = 0; regnum = 0;
} }

View File

@ -372,7 +372,7 @@ const u8 *Arm64Jit::DoJit(u32 em_address, JitBlock *b) {
if (logBlocks > 0 && dontLogBlocks == 0) { if (logBlocks > 0 && dontLogBlocks == 0) {
INFO_LOG(JIT, "=============== mips %d ===============", blocks.GetNumBlocks()); INFO_LOG(JIT, "=============== mips %d ===============", blocks.GetNumBlocks());
for (u32 cpc = em_address; cpc != GetCompilerPC() + 4; cpc += 4) { for (u32 cpc = em_address; cpc != GetCompilerPC() + 4; cpc += 4) {
MIPSDisAsm(Memory::Read_Opcode_JIT(cpc), cpc, temp, true); MIPSDisAsm(Memory::Read_Opcode_JIT(cpc), cpc, temp, sizeof(temp), true);
INFO_LOG(JIT, "M: %08x %s", cpc, temp); INFO_LOG(JIT, "M: %08x %s", cpc, temp);
} }
} }

View File

@ -520,11 +520,11 @@ ARM64Reg Arm64RegCacheFPU::R(int mipsReg) {
return (ARM64Reg)(mr[mipsReg].reg + S0); return (ARM64Reg)(mr[mipsReg].reg + S0);
} else { } else {
if (mipsReg < 32) { if (mipsReg < 32) {
ERROR_LOG(JIT, "FReg %i not in ARM reg. compilerPC = %08x : %s", mipsReg, js_->compilerPC, MIPSDisasmAt(js_->compilerPC)); ERROR_LOG(JIT, "FReg %i not in ARM reg. compilerPC = %08x : %s", mipsReg, js_->compilerPC, MIPSDisasmAt(js_->compilerPC).c_str());
} else if (mipsReg < 32 + 128) { } else if (mipsReg < 32 + 128) {
ERROR_LOG(JIT, "VReg %i not in ARM reg. compilerPC = %08x : %s", mipsReg - 32, js_->compilerPC, MIPSDisasmAt(js_->compilerPC)); ERROR_LOG(JIT, "VReg %i not in ARM reg. compilerPC = %08x : %s", mipsReg - 32, js_->compilerPC, MIPSDisasmAt(js_->compilerPC).c_str());
} else { } else {
ERROR_LOG(JIT, "Tempreg %i not in ARM reg. compilerPC = %08x : %s", mipsReg - 128 - 32, js_->compilerPC, MIPSDisasmAt(js_->compilerPC)); ERROR_LOG(JIT, "Tempreg %i not in ARM reg. compilerPC = %08x : %s", mipsReg - 128 - 32, js_->compilerPC, MIPSDisasmAt(js_->compilerPC).c_str());
} }
return INVALID_REG; // BAAAD return INVALID_REG; // BAAAD
} }

View File

@ -283,7 +283,7 @@ void IRFrontend::DoJit(u32 em_address, std::vector<IRInst> &instructions, u32 &m
NOTICE_LOG(JIT, "=============== mips %08x ===============", em_address); NOTICE_LOG(JIT, "=============== mips %08x ===============", em_address);
for (u32 cpc = em_address; cpc != GetCompilerPC(); cpc += 4) { for (u32 cpc = em_address; cpc != GetCompilerPC(); cpc += 4) {
temp2[0] = 0; temp2[0] = 0;
MIPSDisAsm(Memory::Read_Opcode_JIT(cpc), cpc, temp2, true); MIPSDisAsm(Memory::Read_Opcode_JIT(cpc), cpc, temp2, sizeof(temp2), true);
NOTICE_LOG(JIT, "M: %08x %s", cpc, temp2); NOTICE_LOG(JIT, "M: %08x %s", cpc, temp2);
} }
} }

View File

@ -208,7 +208,7 @@ int IRWriter::AddConstantFloat(float value) {
return AddConstant(val); return AddConstant(val);
} }
const char *GetGPRName(int r) { static std::string GetGPRName(int r) {
if (r < 32) { if (r < 32) {
return currentDebugMIPS->GetRegName(0, r); return currentDebugMIPS->GetRegName(0, r);
} }
@ -259,7 +259,7 @@ void DisassembleParam(char *buf, int bufSize, u8 param, char type, u32 constant)
switch (type) { switch (type) {
case 'G': case 'G':
snprintf(buf, bufSize, "%s", GetGPRName(param)); snprintf(buf, bufSize, "%s", GetGPRName(param).c_str());
break; break;
case 'F': case 'F':
if (param >= 32) { if (param >= 32) {

View File

@ -371,7 +371,7 @@ JitBlockDebugInfo IRBlockCache::GetBlockDebugInfo(int blockNum) const {
for (u32 addr = start; addr < start + size; addr += 4) { for (u32 addr = start; addr < start + size; addr += 4) {
char temp[256]; char temp[256];
MIPSDisAsm(Memory::Read_Instruction(addr), addr, temp, true); MIPSDisAsm(Memory::Read_Instruction(addr), addr, temp, sizeof(temp), true);
std::string mipsDis = temp; std::string mipsDis = temp;
debugInfo.origDisasm.push_back(mipsDis); debugInfo.origDisasm.push_back(mipsDis);
} }

View File

@ -688,7 +688,7 @@ JitBlockDebugInfo JitBlockCache::GetBlockDebugInfo(int blockNum) const {
debugInfo.originalAddress = block->originalAddress; debugInfo.originalAddress = block->originalAddress;
for (u32 addr = block->originalAddress; addr <= block->originalAddress + block->originalSize * 4; addr += 4) { for (u32 addr = block->originalAddress; addr <= block->originalAddress + block->originalSize * 4; addr += 4) {
char temp[256]; char temp[256];
MIPSDisAsm(Memory::Read_Instruction(addr), addr, temp, true); MIPSDisAsm(Memory::Read_Instruction(addr), addr, temp, sizeof(temp), true);
std::string mipsDis = temp; std::string mipsDis = temp;
debugInfo.origDisasm.push_back(mipsDis); debugInfo.origDisasm.push_back(mipsDis);
} }

View File

@ -16,6 +16,7 @@
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#include "ppsspp_config.h" #include "ppsspp_config.h"
#include <algorithm>
#include <map> #include <map>
#include <set> #include <set>
#include <unordered_map> #include <unordered_map>
@ -27,6 +28,7 @@
#include "Common/File/FileUtil.h" #include "Common/File/FileUtil.h"
#include "Common/Log.h" #include "Common/Log.h"
#include "Common/StringUtils.h"
#include "Common/TimeUtil.h" #include "Common/TimeUtil.h"
#include "Core/Config.h" #include "Core/Config.h"
#include "Core/MemMap.h" #include "Core/MemMap.h"
@ -940,6 +942,10 @@ skip:
return true; return true;
} }
// Un named stubs, just in case.
if (!strncmp(name, "[UNK:", strlen("[UNK:")))
return true;
// Assume any z_un, not just the address, is a default func. // Assume any z_un, not just the address, is a default func.
return !strncmp(name, "z_un_", strlen("z_un_")) || !strncmp(name, "u_un_", strlen("u_un_")); return !strncmp(name, "z_un_", strlen("z_un_")) || !strncmp(name, "u_un_", strlen("u_un_"));
} }
@ -1189,6 +1195,12 @@ skip:
} }
} }
bool SkipFuncHash(const std::string &name) {
std::vector<std::string> funcs;
SplitString(g_Config.sSkipFuncHashMap, ',', funcs);
return std::find(funcs.begin(), funcs.end(), name) != funcs.end();
}
void RegisterFunction(u32 startAddr, u32 size, const char *name) { void RegisterFunction(u32 startAddr, u32 size, const char *name) {
std::lock_guard<std::recursive_mutex> guard(functions_lock); std::lock_guard<std::recursive_mutex> guard(functions_lock);
@ -1196,7 +1208,7 @@ skip:
for (auto iter = functions.begin(); iter != functions.end(); iter++) { for (auto iter = functions.begin(); iter != functions.end(); iter++) {
if (iter->start == startAddr) { if (iter->start == startAddr) {
// Let's just add it to the hashmap. // Let's just add it to the hashmap.
if (iter->hasHash && size > 16) { if (iter->hasHash && size > 16 && SkipFuncHash(name)) {
HashMapFunc hfun; HashMapFunc hfun;
hfun.hash = iter->hash; hfun.hash = iter->hash;
strncpy(hfun.name, name, 64); strncpy(hfun.name, name, 64);
@ -1278,7 +1290,7 @@ skip:
} }
// Functions with default names aren't very interesting either. // Functions with default names aren't very interesting either.
const std::string name = g_symbolMap->GetLabelString(f.start); const std::string name = g_symbolMap->GetLabelString(f.start);
if (IsDefaultFunction(name)) { if (IsDefaultFunction(name) || SkipFuncHash(name)) {
continue; continue;
} }

View File

@ -22,11 +22,12 @@
#include <strings.h> #include <strings.h>
#endif #endif
#include "Common/StringUtils.h"
#include "Core/Debugger/Breakpoints.h" #include "Core/Debugger/Breakpoints.h"
#include "Core/Debugger/SymbolMap.h" #include "Core/Debugger/SymbolMap.h"
#include "Core/Debugger/DebugInterface.h" #include "Core/Debugger/DebugInterface.h"
#include "Core/MIPS/MIPSDebugInterface.h" #include "Core/MIPS/MIPSDebugInterface.h"
#include "Core/MIPS/MIPSVFPUUtils.h"
#include "Core/HLE/sceKernelThread.h" #include "Core/HLE/sceKernelThread.h"
#include "Core/MemMap.h" #include "Core/MemMap.h"
#include "Core/MIPS/MIPSTables.h" #include "Core/MIPS/MIPSTables.h"
@ -60,12 +61,12 @@ public:
char reg[8]; char reg[8];
snprintf(reg, sizeof(reg), "r%d", i); snprintf(reg, sizeof(reg), "r%d", i);
if (strcasecmp(str, reg) == 0 || strcasecmp(str, cpu->GetRegName(0, i)) == 0) if (strcasecmp(str, reg) == 0 || strcasecmp(str, cpu->GetRegName(0, i).c_str()) == 0)
{ {
referenceIndex = i; referenceIndex = i;
return true; return true;
} }
else if (strcasecmp(str, cpu->GetRegName(1, i)) == 0) else if (strcasecmp(str, cpu->GetRegName(1, i).c_str()) == 0)
{ {
referenceIndex = REF_INDEX_FPU | i; referenceIndex = REF_INDEX_FPU | i;
return true; return true;
@ -81,7 +82,7 @@ public:
for (int i = 0; i < 128; i++) for (int i = 0; i < 128; i++)
{ {
if (strcasecmp(str, cpu->GetRegName(2, i)) == 0) if (strcasecmp(str, cpu->GetRegName(2, i).c_str()) == 0)
{ {
referenceIndex = REF_INDEX_VFPU | i; referenceIndex = REF_INDEX_VFPU | i;
return true; return true;
@ -159,7 +160,7 @@ public:
return EXPR_TYPE_UINT; return EXPR_TYPE_UINT;
} }
bool getMemoryValue(uint32_t address, int size, uint32_t& dest, char* error, size_t errorBufSize) override { bool getMemoryValue(uint32_t address, int size, uint32_t& dest, std::string *error) override {
// We allow, but ignore, bad access. // We allow, but ignore, bad access.
// If we didn't, log/condition statements that reference registers couldn't be configured. // If we didn't, log/condition statements that reference registers couldn't be configured.
uint32_t valid = Memory::ValidSize(address, size); uint32_t valid = Memory::ValidSize(address, size);
@ -179,7 +180,7 @@ public:
return true; return true;
} }
snprintf(error, errorBufSize, "Unexpected memory access size %d", size); *error = StringFromFormat("Unexpected memory access size %d", size);
return false; return false;
} }
@ -189,14 +190,11 @@ private:
const char *MIPSDebugInterface::disasm(unsigned int address, unsigned int align) void MIPSDebugInterface::DisAsm(u32 pc, char *out, size_t outSize) {
{ if (Memory::IsValidAddress(pc))
static char mojs[256]; MIPSDisAsm(Memory::Read_Opcode_JIT(pc), pc, out, outSize);
if (Memory::IsValidAddress(address))
MIPSDisAsm(Memory::Read_Opcode_JIT(address), address, mojs);
else else
strcpy(mojs, "-"); truncate_cpy(out, outSize, "-");
return mojs;
} }
unsigned int MIPSDebugInterface::readMemory(unsigned int address) { unsigned int MIPSDebugInterface::readMemory(unsigned int address) {
@ -264,9 +262,7 @@ const char *MIPSDebugInterface::GetName()
return ("R4"); return ("R4");
} }
// NOT threadsafe. std::string MIPSDebugInterface::GetRegName(int cat, int index) {
const char *MIPSDebugInterface::GetRegName(int cat, int index)
{
static const char *regName[32] = { static const char *regName[32] = {
"zero", "at", "v0", "v1", "zero", "at", "v0", "v1",
"a0", "a1", "a2", "a3", "a0", "a1", "a2", "a3",
@ -277,23 +273,20 @@ const char *MIPSDebugInterface::GetRegName(int cat, int index)
"t8", "t9", "k0", "k1", "t8", "t9", "k0", "k1",
"gp", "sp", "fp", "ra" "gp", "sp", "fp", "ra"
}; };
static const char *fpRegName[32] = {
"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
"f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
"f16", "f16", "f18", "f19", "f20", "f21", "f22", "f23",
"f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
};
// really nasty hack so that this function can be called several times on one line of c++. if (cat == 0 && (unsigned)index < sizeof(regName)) {
static int access = 0;
access++;
access &= 3;
static char temp[4][16];
if (cat == 0) {
return regName[index]; return regName[index];
} else if (cat == 1) { } else if (cat == 1 && (unsigned)index < sizeof(fpRegName)) {
snprintf(temp[access], sizeof(temp[access]), "f%d", index); return fpRegName[index];
return temp[access];
} else if (cat == 2) { } else if (cat == 2) {
snprintf(temp[access], sizeof(temp[access]), "v%03x", index); return GetVectorNotation(index, V_Single);
return temp[access];
} else {
return "???";
} }
return "???";
} }

View File

@ -28,7 +28,6 @@ class MIPSDebugInterface : public DebugInterface
MIPSState *cpu; MIPSState *cpu;
public: public:
MIPSDebugInterface(MIPSState *_cpu) { cpu = _cpu; } MIPSDebugInterface(MIPSState *_cpu) { cpu = _cpu; }
const char *disasm(unsigned int address, unsigned int align) override;
int getInstructionSize(int instruction) override { return 4; } int getInstructionSize(int instruction) override { return 4; }
bool isAlive() override; bool isAlive() override;
bool isBreakpoint(unsigned int address) override; bool isBreakpoint(unsigned int address) override;
@ -51,6 +50,7 @@ public:
u32 GetGPR32Value(int reg) override { return cpu->r[reg]; } u32 GetGPR32Value(int reg) override { return cpu->r[reg]; }
u32 GetPC() override { return cpu->pc; } u32 GetPC() override { return cpu->pc; }
u32 GetLR() override { return cpu->r[MIPS_REG_RA]; } u32 GetLR() override { return cpu->r[MIPS_REG_RA]; }
void DisAsm(u32 pc, char *out, size_t outSize) override;
void SetPC(u32 _pc) override { cpu->pc = _pc; } void SetPC(u32 _pc) override { cpu->pc = _pc; }
const char *GetCategoryName(int cat) override { const char *GetCategoryName(int cat) override {
@ -62,7 +62,7 @@ public:
static int r[3] = { 32, 32, 128 }; static int r[3] = { 32, 32, 128 };
return r[cat]; return r[cat];
} }
const char *GetRegName(int cat, int index) override; std::string GetRegName(int cat, int index) override;
void PrintRegValue(int cat, int index, char *out, size_t outSize) override { void PrintRegValue(int cat, int index, char *out, size_t outSize) override {
switch (cat) { switch (cat) {

View File

@ -16,6 +16,7 @@
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#include <cstring> #include <cstring>
#include "Common/StringUtils.h"
#include "Core/HLE/HLE.h" #include "Core/HLE/HLE.h"
#include "Core/MemMap.h" #include "Core/MemMap.h"
#include "Core/MIPS/MIPS.h" #include "Core/MIPS/MIPS.h"
@ -33,18 +34,14 @@
#define _POS ((op>>6 ) & 0x1F) #define _POS ((op>>6 ) & 0x1F)
#define _SIZE ((op>>11) & 0x1F) #define _SIZE ((op>>11) & 0x1F)
#define RN(i) currentDebugMIPS->GetRegName(0,i) #define RN(i) (currentDebugMIPS->GetRegName(0, i).c_str())
#define FN(i) currentDebugMIPS->GetRegName(1,i) #define FN(i) (currentDebugMIPS->GetRegName(1, i).c_str())
//#define VN(i) currentMIPS->GetRegName(2,i) //#define VN(i) (currentDebugMIPS->GetRegName(2, i).c_str())
u32 disPC;
namespace MIPSDis namespace MIPSDis
{ {
// One shot, not re-entrant. std::string SignedHex(int i) {
const char *SignedHex(int i) char temp[32];
{
static char temp[32];
int offset = 0; int offset = 0;
if (i < 0) if (i < 0)
{ {
@ -53,108 +50,96 @@ namespace MIPSDis
i = -i; i = -i;
} }
sprintf(&temp[offset], "0x%X", i); snprintf(&temp[offset], sizeof(temp) - offset, "0x%X", i);
return temp; return temp;
} }
void Dis_Generic(MIPSOpcode op, char *out) void Dis_Generic(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{ snprintf(out, outSize, "%s\t --- unknown ---", MIPSGetName(op));
sprintf(out, "%s\t --- unknown ---", MIPSGetName(op));
} }
void Dis_Cache(MIPSOpcode op, char *out) void Dis_Cache(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
int imm = SignExtend16ToS32(op & 0xFFFF); int imm = SignExtend16ToS32(op & 0xFFFF);
int rs = _RS; int rs = _RS;
int func = (op >> 16) & 0x1F; int func = (op >> 16) & 0x1F;
sprintf(out, "%s\tfunc=%i, %s(%s)", MIPSGetName(op), func, RN(rs), SignedHex(imm)); snprintf(out, outSize, "%s\tfunc=%i, %s(%s)", MIPSGetName(op), func, RN(rs), SignedHex(imm).c_str());
} }
void Dis_mxc1(MIPSOpcode op, char *out) void Dis_mxc1(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
int fs = _FS; int fs = _FS;
int rt = _RT; int rt = _RT;
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
sprintf(out, "%s\t%s, %s",name,RN(rt),FN(fs)); snprintf(out, outSize, "%s\t%s, %s", name, RN(rt), FN(fs));
} }
void Dis_FPU3op(MIPSOpcode op, char *out) void Dis_FPU3op(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
int ft = _FT; int ft = _FT;
int fs = _FS; int fs = _FS;
int fd = _FD; int fd = _FD;
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
sprintf(out, "%s\t%s, %s, %s",name,FN(fd),FN(fs),FN(ft)); snprintf(out, outSize, "%s\t%s, %s, %s", name, FN(fd), FN(fs), FN(ft));
} }
void Dis_FPU2op(MIPSOpcode op, char *out) void Dis_FPU2op(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
int fs = _FS; int fs = _FS;
int fd = _FD; int fd = _FD;
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
sprintf(out, "%s\t%s, %s",name,FN(fd),FN(fs)); snprintf(out, outSize, "%s\t%s, %s", name, FN(fd), FN(fs));
} }
void Dis_FPULS(MIPSOpcode op, char *out) void Dis_FPULS(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
int offset = SignExtend16ToS32(op & 0xFFFF); int offset = SignExtend16ToS32(op & 0xFFFF);
int ft = _FT; int ft = _FT;
int rs = _RS; int rs = _RS;
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
sprintf(out, "%s\t%s, %s(%s)",name,FN(ft),SignedHex(offset),RN(rs)); snprintf(out, outSize, "%s\t%s, %s(%s)", name, FN(ft), SignedHex(offset).c_str(), RN(rs));
} }
void Dis_FPUComp(MIPSOpcode op, char *out)
{ void Dis_FPUComp(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
int fs = _FS; int fs = _FS;
int ft = _FT; int ft = _FT;
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
sprintf(out, "%s\t%s, %s",name,FN(fs),FN(ft)); snprintf(out, outSize, "%s\t%s, %s", name, FN(fs), FN(ft));
} }
void Dis_FPUBranch(MIPSOpcode op, char *out) void Dis_FPUBranch(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{ u32 off = pc;
u32 off = disPC;
int imm = SignExtend16ToS32(op & 0xFFFF) << 2; int imm = SignExtend16ToS32(op & 0xFFFF) << 2;
off += imm + 4; off += imm + 4;
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
sprintf(out, "%s\t->$%08x",name,off); snprintf(out, outSize, "%s\t->$%08x", name, off);
} }
void Dis_RelBranch(MIPSOpcode op, char *out) void Dis_RelBranch(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{ u32 off = pc;
u32 off = disPC;
int imm = SignExtend16ToS32(op & 0xFFFF) << 2; int imm = SignExtend16ToS32(op & 0xFFFF) << 2;
int rs = _RS; int rs = _RS;
off += imm + 4; off += imm + 4;
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
sprintf(out, "%s\t%s, ->$%08x", name, RN(rs), off); snprintf(out, outSize, "%s\t%s, ->$%08x", name, RN(rs), off);
} }
void Dis_Syscall(MIPSOpcode op, char *out) void Dis_Syscall(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
u32 callno = (op>>6) & 0xFFFFF; //20 bits u32 callno = (op>>6) & 0xFFFFF; //20 bits
int funcnum = callno & 0xFFF; int funcnum = callno & 0xFFF;
int modulenum = (callno & 0xFF000) >> 12; int modulenum = (callno & 0xFF000) >> 12;
sprintf(out, "syscall\t %s",/*PSPHLE::GetModuleName(modulenum),*/GetFuncName(modulenum, funcnum)); snprintf(out, outSize, "syscall\t %s", GetFuncName(modulenum, funcnum));
} }
void Dis_ToHiloTransfer(MIPSOpcode op, char *out) void Dis_ToHiloTransfer(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
int rs = _RS; int rs = _RS;
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
sprintf(out, "%s\t%s",name,RN(rs)); snprintf(out, outSize, "%s\t%s", name, RN(rs));
} }
void Dis_FromHiloTransfer(MIPSOpcode op, char *out) void Dis_FromHiloTransfer(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
int rd = _RD; int rd = _RD;
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
sprintf(out, "%s\t%s",name,RN(rd)); snprintf(out, outSize, "%s\t%s", name, RN(rd));
} }
void Dis_RelBranch2(MIPSOpcode op, char *out) void Dis_RelBranch2(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{ u32 off = pc;
u32 off = disPC;
int imm = SignExtend16ToS32(op & 0xFFFF) << 2; int imm = SignExtend16ToS32(op & 0xFFFF) << 2;
int rt = _RT; int rt = _RT;
int rs = _RS; int rs = _RS;
@ -163,15 +148,14 @@ namespace MIPSDis
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
int o = op>>26; int o = op>>26;
if (o==4 && rs == rt)//beq if (o==4 && rs == rt)//beq
sprintf(out, "b\t->$%08x", off); snprintf(out, outSize, "b\t->$%08x", off);
else if (o==20 && rs == rt)//beql else if (o==20 && rs == rt)//beql
sprintf(out, "bl\t->$%08x", off); snprintf(out, outSize, "bl\t->$%08x", off);
else else
sprintf(out, "%s\t%s, %s, ->$%08x", name, RN(rs), RN(rt), off); snprintf(out, outSize, "%s\t%s, %s, ->$%08x", name, RN(rs), RN(rt), off);
} }
void Dis_IType(MIPSOpcode op, char *out) void Dis_IType(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
u32 uimm = op & 0xFFFF; u32 uimm = op & 0xFFFF;
u32 suimm = SignExtend16ToU32(op); u32 suimm = SignExtend16ToU32(op);
s32 simm = SignExtend16ToS32(op); s32 simm = SignExtend16ToS32(op);
@ -184,127 +168,114 @@ namespace MIPSDis
case 8: //addi case 8: //addi
case 9: //addiu case 9: //addiu
case 10: //slti case 10: //slti
sprintf(out, "%s\t%s, %s, %s",name,RN(rt),RN(rs),SignedHex(simm)); snprintf(out, outSize, "%s\t%s, %s, %s", name, RN(rt), RN(rs), SignedHex(simm).c_str());
break; break;
case 11: //sltiu case 11: //sltiu
sprintf(out, "%s\t%s, %s, 0x%X",name,RN(rt),RN(rs),suimm); snprintf(out, outSize, "%s\t%s, %s, 0x%X", name, RN(rt), RN(rs), suimm);
break; break;
default: default:
sprintf(out, "%s\t%s, %s, 0x%X",name,RN(rt),RN(rs),uimm); snprintf(out, outSize, "%s\t%s, %s, 0x%X", name, RN(rt), RN(rs), uimm);
break; break;
} }
} }
void Dis_ori(MIPSOpcode op, char *out) void Dis_ori(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
u32 uimm = op & 0xFFFF; u32 uimm = op & 0xFFFF;
int rt = _RT; int rt = _RT;
int rs = _RS; int rs = _RS;
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
if (rs == 0) if (rs == 0)
sprintf(out, "li\t%s, 0x%X",RN(rt),uimm); snprintf(out, outSize, "li\t%s, 0x%X", RN(rt), uimm);
else else
sprintf(out, "%s\t%s, %s, 0x%X",name,RN(rt),RN(rs),uimm); snprintf(out, outSize, "%s\t%s, %s, 0x%X", name, RN(rt), RN(rs), uimm);
} }
void Dis_IType1(MIPSOpcode op, char *out) void Dis_IType1(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
u32 uimm = op & 0xFFFF; u32 uimm = op & 0xFFFF;
int rt = _RT; int rt = _RT;
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
sprintf(out, "%s\t%s, 0x%X",name,RN(rt),uimm); snprintf(out, outSize, "%s\t%s, 0x%X", name, RN(rt), uimm);
} }
void Dis_addi(MIPSOpcode op, char *out) void Dis_addi(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
int imm = SignExtend16ToS32(op & 0xFFFF); int imm = SignExtend16ToS32(op & 0xFFFF);
int rt = _RT; int rt = _RT;
int rs = _RS; int rs = _RS;
if (rs == 0) if (rs == 0)
sprintf(out, "li\t%s, %s",RN(rt),SignedHex(imm)); snprintf(out, outSize, "li\t%s, %s", RN(rt), SignedHex(imm).c_str());
else else
Dis_IType(op,out); Dis_IType(op, pc, out, outSize);
} }
void Dis_ITypeMem(MIPSOpcode op, char *out) void Dis_ITypeMem(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
int imm = SignExtend16ToS32(op & 0xFFFF); int imm = SignExtend16ToS32(op & 0xFFFF);
int rt = _RT; int rt = _RT;
int rs = _RS; int rs = _RS;
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
sprintf(out, "%s\t%s, %s(%s)",name,RN(rt),SignedHex(imm),RN(rs)); snprintf(out, outSize, "%s\t%s, %s(%s)", name, RN(rt), SignedHex(imm).c_str(), RN(rs));
} }
void Dis_RType2(MIPSOpcode op, char *out) void Dis_RType2(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
int rs = _RS; int rs = _RS;
int rd = _RD; int rd = _RD;
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
sprintf(out, "%s\t%s, %s",name,RN(rd),RN(rs)); snprintf(out, outSize, "%s\t%s, %s", name, RN(rd), RN(rs));
} }
void Dis_RType3(MIPSOpcode op, char *out) void Dis_RType3(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
int rt = _RT; int rt = _RT;
int rs = _RS; int rs = _RS;
int rd = _RD; int rd = _RD;
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
sprintf(out, "%s\t%s, %s, %s",name,RN(rd),RN(rs),RN(rt)); snprintf(out, outSize, "%s\t%s, %s, %s", name, RN(rd), RN(rs), RN(rt));
} }
void Dis_addu(MIPSOpcode op, char *out) void Dis_addu(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
int rt = _RT; int rt = _RT;
int rs = _RS; int rs = _RS;
int rd = _RD; int rd = _RD;
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
if (rs==0 && rt==0) if (rs==0 && rt==0)
sprintf(out,"li\t%s, 0",RN(rd)); snprintf(out, outSize, "li\t%s, 0", RN(rd));
else if (rs == 0) else if (rs == 0)
sprintf(out,"move\t%s, %s",RN(rd),RN(rt)); snprintf(out, outSize, "move\t%s, %s", RN(rd), RN(rt));
else if (rt == 0) else if (rt == 0)
sprintf(out,"move\t%s, %s",RN(rd),RN(rs)); snprintf(out, outSize, "move\t%s, %s", RN(rd), RN(rs));
else else
sprintf(out, "%s\t%s, %s, %s",name,RN(rd),RN(rs),RN(rt)); snprintf(out, outSize, "%s\t%s, %s, %s", name, RN(rd), RN(rs), RN(rt));
} }
void Dis_ShiftType(MIPSOpcode op, char *out) void Dis_ShiftType(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
int rt = _RT; int rt = _RT;
int rs = _RS; int rs = _RS;
int rd = _RD; int rd = _RD;
int sa = (op>>6) & 0x1F; int sa = (op>>6) & 0x1F;
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
if (((op & 0x3f) == 2) && rs == 1) if (((op & 0x3f) == 2) && rs == 1)
name = "rotr"; name = "rotr";
if (((op & 0x3f) == 6) && sa == 1) if (((op & 0x3f) == 6) && sa == 1)
name = "rotrv"; name = "rotrv";
sprintf(out, "%s\t%s, %s, 0x%X",name,RN(rd),RN(rt),sa); snprintf(out, outSize, "%s\t%s, %s, 0x%X", name, RN(rd), RN(rt), sa);
} }
void Dis_VarShiftType(MIPSOpcode op, char *out) void Dis_VarShiftType(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
int rt = _RT; int rt = _RT;
int rs = _RS; int rs = _RS;
int rd = _RD; int rd = _RD;
int sa = (op>>6) & 0x1F; int sa = (op>>6) & 0x1F;
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
if (((op & 0x3f) == 6) && sa == 1) if (((op & 0x3f) == 6) && sa == 1)
name = "rotrv"; name = "rotrv";
sprintf(out, "%s\t%s, %s, %s",name,RN(rd),RN(rt),RN(rs)); snprintf(out, outSize, "%s\t%s, %s, %s", name, RN(rd), RN(rt), RN(rs));
} }
void Dis_MulDivType(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
void Dis_MulDivType(MIPSOpcode op, char *out)
{
int rt = _RT; int rt = _RT;
int rs = _RS; int rs = _RS;
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
sprintf(out, "%s\t%s, %s",name,RN(rs),RN(rt)); snprintf(out, outSize, "%s\t%s, %s", name, RN(rs), RN(rt));
} }
void Dis_Special3(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
void Dis_Special3(MIPSOpcode op, char *out)
{
int rs = _RS; int rs = _RS;
int Rt = _RT; int Rt = _RT;
int pos = _POS; int pos = _POS;
@ -315,77 +286,67 @@ namespace MIPSDis
case 0x0: //ext case 0x0: //ext
{ {
int size = _SIZE + 1; int size = _SIZE + 1;
sprintf(out,"%s\t%s, %s, 0x%X, 0x%X",name,RN(Rt),RN(rs),pos,size); snprintf(out, outSize, "%s\t%s, %s, 0x%X, 0x%X", name, RN(Rt), RN(rs), pos, size);
} }
break; break;
case 0x4: // ins case 0x4: // ins
{ {
int size = (_SIZE + 1) - pos; int size = (_SIZE + 1) - pos;
sprintf(out,"%s\t%s, %s, 0x%X, 0x%X",name,RN(Rt),RN(rs),pos,size); snprintf(out, outSize, "%s\t%s, %s, 0x%X, 0x%X", name, RN(Rt), RN(rs), pos, size);
} }
break; break;
} }
} }
void Dis_JumpType(MIPSOpcode op, char *out) void Dis_JumpType(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
u32 off = ((op & 0x03FFFFFF) << 2); u32 off = ((op & 0x03FFFFFF) << 2);
u32 addr = (disPC & 0xF0000000) | off; u32 addr = (pc & 0xF0000000) | off;
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
sprintf(out, "%s\t->$%08x",name,addr); snprintf(out, outSize, "%s\t->$%08x", name, addr);
} }
void Dis_JumpRegType(MIPSOpcode op, char *out) void Dis_JumpRegType(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
int rs = _RS; int rs = _RS;
int rd = _RD; int rd = _RD;
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
if ((op & 0x3f) == 9 && rd != MIPS_REG_RA) if ((op & 0x3f) == 9 && rd != MIPS_REG_RA)
sprintf(out, "%s\t%s,->%s", name, RN(rd), RN(rs)); snprintf(out, outSize, "%s\t%s,->%s", name, RN(rd), RN(rs));
else else
sprintf(out, "%s\t->%s", name, RN(rs)); snprintf(out, outSize, "%s\t->%s", name, RN(rs));
} }
void Dis_Allegrex(MIPSOpcode op, char *out) void Dis_Allegrex(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
int rt = _RT; int rt = _RT;
int rd = _RD; int rd = _RD;
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
sprintf(out,"%s\t%s,%s",name,RN(rd),RN(rt)); snprintf(out, outSize, "%s\t%s,%s", name, RN(rd), RN(rt));
} }
void Dis_Allegrex2(MIPSOpcode op, char *out) void Dis_Allegrex2(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
int rt = _RT; int rt = _RT;
int rd = _RD; int rd = _RD;
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
sprintf(out,"%s\t%s,%s",name,RN(rd),RN(rt)); snprintf(out, outSize,"%s\t%s,%s", name, RN(rd), RN(rt));
} }
void Dis_Emuhack(MIPSOpcode op, char *out) void Dis_Emuhack(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{ auto resolved = Memory::Read_Instruction(pc, true);
auto resolved = Memory::Read_Instruction(disPC, true); char disasm[256];
union {
char disasm[256];
char truncated[241];
};
if (MIPS_IS_EMUHACK(resolved)) { if (MIPS_IS_EMUHACK(resolved)) {
strcpy(disasm, "(invalid emuhack)"); truncate_cpy(disasm, sizeof(disasm), "(invalid emuhack)");
} else { } else {
MIPSDisAsm(resolved, disPC, disasm, true); MIPSDisAsm(resolved, pc, disasm, sizeof(disasm), true);
} }
// Truncate in case it was too long, just to avoid warnings.
truncated[240] = '\0';
switch (op.encoding >> 24) { switch (op.encoding >> 24) {
case 0x68: case 0x68:
snprintf(out, 256, "* jitblock: %s", truncated); snprintf(out, outSize, "* jitblock: %s", disasm);
break; break;
case 0x6a: case 0x6a:
snprintf(out, 256, "* replacement: %s", truncated); snprintf(out, outSize, "* replacement: %s", disasm);
break; break;
default: default:
snprintf(out, 256, "* (invalid): %s", truncated); snprintf(out, outSize, "* (invalid): %s", disasm);
break; break;
} }
} }

View File

@ -20,44 +20,42 @@
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
#include "Core/MIPS/MIPS.h" #include "Core/MIPS/MIPS.h"
extern u32 disPC;
namespace MIPSDis namespace MIPSDis
{ {
void Dis_Unknown(MIPSOpcode op, char *out); void Dis_Unknown(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_Unimpl(MIPSOpcode op, char *out); void Dis_Unimpl(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_Syscall(MIPSOpcode op, char *out); void Dis_Syscall(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_mxc1(MIPSOpcode op, char *out); void Dis_mxc1(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_addi(MIPSOpcode op, char *out); void Dis_addi(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_addu(MIPSOpcode op, char *out); void Dis_addu(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_RelBranch2(MIPSOpcode op, char *out); void Dis_RelBranch2(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_RelBranch(MIPSOpcode op, char *out); void Dis_RelBranch(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_Generic(MIPSOpcode op, char *out); void Dis_Generic(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_Cache(MIPSOpcode op, char *out); void Dis_Cache(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_IType(MIPSOpcode op, char *out); void Dis_IType(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_IType1(MIPSOpcode op, char *out); void Dis_IType1(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_ITypeMem(MIPSOpcode op, char *out); void Dis_ITypeMem(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_RType2(MIPSOpcode op, char *out); void Dis_RType2(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_RType3(MIPSOpcode op, char *out); void Dis_RType3(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_MulDivType(MIPSOpcode op, char *out); void Dis_MulDivType(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_ShiftType(MIPSOpcode op, char *out); void Dis_ShiftType(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_VarShiftType(MIPSOpcode op, char *out); void Dis_VarShiftType(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_FPU3op(MIPSOpcode op, char *out); void Dis_FPU3op(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_FPU2op(MIPSOpcode op, char *out); void Dis_FPU2op(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_FPULS(MIPSOpcode op, char *out); void Dis_FPULS(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_FPUComp(MIPSOpcode op, char *out); void Dis_FPUComp(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_FPUBranch(MIPSOpcode op, char *out); void Dis_FPUBranch(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_ori(MIPSOpcode op, char *out); void Dis_ori(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_Special3(MIPSOpcode op, char *out); void Dis_Special3(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_ToHiloTransfer(MIPSOpcode op, char *out); void Dis_ToHiloTransfer(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_FromHiloTransfer(MIPSOpcode op, char *out); void Dis_FromHiloTransfer(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_JumpType(MIPSOpcode op, char *out); void Dis_JumpType(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_JumpRegType(MIPSOpcode op, char *out); void Dis_JumpRegType(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_Allegrex(MIPSOpcode op, char *out); void Dis_Allegrex(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_Allegrex2(MIPSOpcode op, char *out); void Dis_Allegrex2(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_Emuhack(MIPSOpcode op, char *out); void Dis_Emuhack(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
} }

View File

@ -17,6 +17,7 @@
#include <cstring> #include <cstring>
#include "Common/Data/Convert/SmallDataConvert.h" #include "Common/Data/Convert/SmallDataConvert.h"
#include "Common/StringUtils.h"
#include "Core/MIPS/MIPS.h" #include "Core/MIPS/MIPS.h"
#include "Core/MIPS/MIPSDis.h" #include "Core/MIPS/MIPSDis.h"
#include "Core/MIPS/MIPSTables.h" #include "Core/MIPS/MIPSTables.h"
@ -33,9 +34,9 @@
#define _SIZE ((op>>11) & 0x1F) #define _SIZE ((op>>11) & 0x1F)
#define RN(i) currentDebugMIPS->GetRegName(0,i) #define RN(i) (currentDebugMIPS->GetRegName(0, i).c_str())
#define FN(i) currentDebugMIPS->GetRegName(1,i) #define FN(i) (currentDebugMIPS->GetRegName(1, i).c_str())
//#define VN(i) currentDebugMIPS->GetRegName(2,i) //#define VN(i) (currentDebugMIPS->GetRegName(2, i).c_str())
#define S_not(a,b,c) (a<<2)|(b)|(c<<5) #define S_not(a,b,c) (a<<2)|(b)|(c<<5)
@ -47,8 +48,7 @@
#define VertOff 1 #define VertOff 1
#define MtxOff 4 #define MtxOff 4
inline const char *VN(int v, VectorSize size) inline std::string VNStr(int v, VectorSize size) {
{
static const char *vfpuCtrlNames[VFPU_CTRL_MAX] = { static const char *vfpuCtrlNames[VFPU_CTRL_MAX] = {
"SPFX", "SPFX",
"TPFX", "TPFX",
@ -76,11 +76,13 @@ inline const char *VN(int v, VectorSize size)
return GetVectorNotation(v, size); return GetVectorNotation(v, size);
} }
inline const char *MN(int v, MatrixSize size) inline std::string MNStr(int v, MatrixSize size) {
{
return GetMatrixNotation(v, size); return GetMatrixNotation(v, size);
} }
#define VN(v, s) (VNStr(v, s).c_str())
#define MN(v, s) (MNStr(v, s).c_str())
inline const char *VSuff(MIPSOpcode op) inline const char *VSuff(MIPSOpcode op)
{ {
int a = (op>>7)&1; int a = (op>>7)&1;
@ -98,67 +100,62 @@ inline const char *VSuff(MIPSOpcode op)
namespace MIPSDis namespace MIPSDis
{ {
const char *SignedHex(int i); std::string SignedHex(int i);
void Dis_SV(MIPSOpcode op, char *out) void Dis_SV(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
int offset = SignExtend16ToS32(op & 0xFFFC); int offset = SignExtend16ToS32(op & 0xFFFC);
int vt = ((op>>16)&0x1f)|((op&3)<<5); int vt = ((op>>16)&0x1f)|((op&3)<<5);
int rs = (op>>21) & 0x1f; int rs = (op>>21) & 0x1f;
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
sprintf(out, "%s\t%s, %s(%s)", name, VN(vt, V_Single), SignedHex(offset), RN(rs)); snprintf(out, outSize, "%s\t%s, %s(%s)", name, VN(vt, V_Single), SignedHex(offset).c_str(), RN(rs));
} }
void Dis_SVQ(MIPSOpcode op, char *out) void Dis_SVQ(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
int offset = SignExtend16ToS32(op & 0xFFFC); int offset = SignExtend16ToS32(op & 0xFFFC);
int vt = (((op>>16)&0x1f))|((op&1)<<5); int vt = (((op>>16)&0x1f))|((op&1)<<5);
int rs = (op>>21) & 0x1f; int rs = (op>>21) & 0x1f;
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
sprintf(out, "%s\t%s, %s(%s)", name, VN(vt, V_Quad), SignedHex(offset), RN(rs)); size_t outpos = 0;
if (op & 2) outpos += snprintf(out, outSize, "%s\t%s, %s(%s)", name, VN(vt, V_Quad), SignedHex(offset).c_str(), RN(rs));
strcat(out, ", wb"); if ((op & 2) && outpos < outSize)
truncate_cpy(out + outpos, outSize - outpos, ", wb");
} }
void Dis_SVLRQ(MIPSOpcode op, char *out) void Dis_SVLRQ(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
int offset = SignExtend16ToS32(op & 0xFFFC); int offset = SignExtend16ToS32(op & 0xFFFC);
int vt = (((op>>16)&0x1f))|((op&1)<<5); int vt = (((op>>16)&0x1f))|((op&1)<<5);
int rs = (op>>21) & 0x1f; int rs = (op>>21) & 0x1f;
int lr = (op>>1)&1; int lr = (op>>1)&1;
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
sprintf(out, "%s%s.q\t%s, %s(%s)", name, lr ? "r" : "l", VN(vt, V_Quad), SignedHex(offset), RN(rs)); snprintf(out, outSize, "%s%s.q\t%s, %s(%s)", name, lr ? "r" : "l", VN(vt, V_Quad), SignedHex(offset).c_str(), RN(rs));
} }
void Dis_Mftv(MIPSOpcode op, char *out) void Dis_Mftv(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
int vr = op & 0xFF; int vr = op & 0xFF;
int rt = _RT; int rt = _RT;
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
sprintf(out, "%s%s\t%s, %s",name,vr>127?"c":"", RN(rt), VN(vr, V_Single)); snprintf(out, outSize, "%s%s\t%s, %s", name, vr > 127 ? "c" : "", RN(rt), VN(vr, V_Single));
} }
void Dis_Vmfvc(MIPSOpcode op, char *out) void Dis_Vmfvc(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
int vd = _VD; int vd = _VD;
int vr = (op >> 8) & 0x7F; int vr = (op >> 8) & 0x7F;
const char* name = MIPSGetName(op); const char* name = MIPSGetName(op);
sprintf(out, "%s\t%s, %s", name, VN(vd, V_Single), VN(vr + 128, V_Single)); snprintf(out, outSize, "%s\t%s, %s", name, VN(vd, V_Single), VN(vr + 128, V_Single));
} }
void Dis_Vmtvc(MIPSOpcode op, char *out) void Dis_Vmtvc(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
int vr = op & 0x7F; int vr = op & 0x7F;
int vs = _VS; int vs = _VS;
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
sprintf(out, "%s\t%s, %s", name, VN(vs, V_Single), VN(vr + 128, V_Single)); snprintf(out, outSize, "%s\t%s, %s", name, VN(vs, V_Single), VN(vr + 128, V_Single));
} }
void Dis_VPFXST(MIPSOpcode op, char *out) void Dis_VPFXST(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
int data = op & 0xFFFFF; int data = op & 0xFFFFF;
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
sprintf(out, "%s\t[",name); size_t outpos = snprintf(out, outSize, "%s\t[", name);
static const char *regnam[4] = {"X","Y","Z","W"}; static const char *regnam[4] = {"X","Y","Z","W"};
static const char *constan[8] = {"0","1","2","1/2","3","1/3","1/4","1/6"}; static const char *constan[8] = {"0","1","2","1/2","3","1/3","1/4","1/6"};
for (int i=0; i<4; i++) for (int i=0; i<4; i++)
@ -167,68 +164,67 @@ namespace MIPSDis
int abs = (data>>(8+i)) & 1; int abs = (data>>(8+i)) & 1;
int negate = (data>>(16+i)) & 1; int negate = (data>>(16+i)) & 1;
int constants = (data>>(12+i)) & 1; int constants = (data>>(12+i)) & 1;
if (negate) if (negate && outpos < outSize)
strcat(out, "-"); outpos += truncate_cpy(out + outpos, outSize - outpos, "-");
if (abs && !constants) if (abs && !constants && outpos < outSize)
strcat(out, "|"); outpos += truncate_cpy(out + outpos, outSize - outpos, "|");
if (!constants) if (!constants) {
{ if (outpos < outSize)
strcat(out, regnam[regnum]); outpos += truncate_cpy(out + outpos, outSize - outpos, regnam[regnum]);
} } else {
else
{
if (abs) if (abs)
regnum+=4; regnum+=4;
strcat(out, constan[regnum]); if (outpos < outSize)
outpos += truncate_cpy(out + outpos, outSize - outpos, constan[regnum]);
} }
if (abs && !constants) if (abs && !constants && outpos < outSize)
strcat(out, "|"); outpos += truncate_cpy(out + outpos, outSize - outpos, "|");
if (i != 3) if (i != 3 && outpos < outSize)
strcat(out, ","); outpos += truncate_cpy(out + outpos, outSize - outpos, ",");
} }
strcat(out, "]"); if (outpos < outSize)
outpos += truncate_cpy(out + outpos, outSize - outpos, "]");
} }
void Dis_VPFXD(MIPSOpcode op, char *out) void Dis_VPFXD(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
int data = op & 0xFFFFF; int data = op & 0xFFFFF;
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
sprintf(out, "%s\t[", name); size_t outpos = snprintf(out, outSize, "%s\t[", name);
static const char *satNames[4] = {"", "0:1", "X", "-1:1"}; static const char *satNames[4] = {"", "0:1", "X", "-1:1"};
for (int i=0; i<4; i++) for (int i=0; i<4; i++)
{ {
int sat = (data>>i*2)&3; int sat = (data>>i*2)&3;
int mask = (data>>(8+i))&1; int mask = (data>>(8+i))&1;
if (sat) if (sat && outpos < outSize)
strcat(out, satNames[sat]); outpos += truncate_cpy(out + outpos, outSize - outpos, satNames[sat]);
if (mask) if (mask && outpos < outSize)
strcat(out, "M"); outpos += truncate_cpy(out + outpos, outSize - outpos, "M");
if (i < 4 - 1) if (i < 4 - 1 && outpos < outSize)
strcat(out, ","); outpos += truncate_cpy(out + outpos, outSize - outpos, ",");
} }
strcat(out, "]"); if (outpos < outSize)
outpos += truncate_cpy(out + outpos, outSize - outpos, "]");
} }
void Dis_Viim(MIPSOpcode op, char *out) void Dis_Viim(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
int vt = _VT; int vt = _VT;
int imm = SignExtend16ToS32(op & 0xFFFF); int imm = SignExtend16ToS32(op & 0xFFFF);
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
int type = (op >> 23) & 7; int type = (op >> 23) & 7;
if (type == 6) if (type == 6)
sprintf(out, "%s\t%s, %i", name, VN(vt, V_Single), imm); snprintf(out, outSize, "%s\t%s, %i", name, VN(vt, V_Single), imm);
else if (type == 7) else if (type == 7)
sprintf(out, "%s\t%s, %f", name, VN(vt, V_Single), Float16ToFloat32((u16)imm)); snprintf(out, outSize, "%s\t%s, %f", name, VN(vt, V_Single), Float16ToFloat32((u16)imm));
else else
sprintf(out, "%s\tARGH", name); snprintf(out, outSize, "%s\tARGH", name);
} }
void Dis_Vcst(MIPSOpcode op, char *out) void Dis_Vcst(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
int conNum = (op>>16) & 0x1f; int conNum = (op>>16) & 0x1f;
int vd = _VD; int vd = _VD;
VectorSize sz = GetVecSizeSafe(op); VectorSize sz = GetVecSizeSafe(op);
@ -258,68 +254,61 @@ namespace MIPSDis
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
const char *c = constants[conNum]; const char *c = constants[conNum];
if (c==0) c = constants[0]; if (c==0) c = constants[0];
sprintf(out,"%s%s\t%s, %s",name,VSuff(op),VN(vd,sz), c); snprintf(out, outSize, "%s%s\t%s, %s", name, VSuff(op), VN(vd,sz), c);
} }
void Dis_MatrixSet1(MIPSOpcode op, char *out) void Dis_MatrixSet1(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
int vd = _VD; int vd = _VD;
MatrixSize sz = GetMtxSizeSafe(op); MatrixSize sz = GetMtxSizeSafe(op);
sprintf(out, "%s%s\t%s",name,VSuff(op),MN(vd, sz)); snprintf(out, outSize, "%s%s\t%s", name, VSuff(op), MN(vd, sz));
} }
void Dis_MatrixSet2(MIPSOpcode op, char *out) void Dis_MatrixSet2(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
int vd = _VD; int vd = _VD;
int vs = _VS; int vs = _VS;
MatrixSize sz = GetMtxSizeSafe(op); MatrixSize sz = GetMtxSizeSafe(op);
sprintf(out, "%s%s\t%s, %s",name,VSuff(op),MN(vd, sz),MN(vs,sz)); snprintf(out, outSize, "%s%s\t%s, %s", name, VSuff(op), MN(vd, sz), MN(vs,sz));
} }
void Dis_MatrixSet3(MIPSOpcode op, char *out) void Dis_MatrixSet3(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
int vd = _VD; int vd = _VD;
int vs = _VS; int vs = _VS;
int vt = _VT; int vt = _VT;
MatrixSize sz = GetMtxSizeSafe(op); MatrixSize sz = GetMtxSizeSafe(op);
sprintf(out, "%s%s\t%s, %s, %s",name,VSuff(op),MN(vd, sz),MN(vs,sz),MN(vt,sz)); snprintf(out, outSize, "%s%s\t%s, %s, %s", name, VSuff(op), MN(vd, sz), MN(vs,sz), MN(vt,sz));
} }
void Dis_MatrixMult(MIPSOpcode op, char *out) void Dis_MatrixMult(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
int vd = _VD; int vd = _VD;
int vs = _VS; int vs = _VS;
int vt = _VT; int vt = _VT;
MatrixSize sz = GetMtxSizeSafe(op); MatrixSize sz = GetMtxSizeSafe(op);
// TODO: Xpose? // TODO: Xpose?
sprintf(out, "%s%s\t%s, %s, %s",name,VSuff(op),MN(vd, sz),MN(Xpose(vs),sz),MN(vt,sz)); snprintf(out, outSize, "%s%s\t%s, %s, %s", name, VSuff(op), MN(vd, sz), MN(Xpose(vs),sz), MN(vt,sz));
} }
void Dis_Vmscl(MIPSOpcode op, char *out) void Dis_Vmscl(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
int vd = _VD; int vd = _VD;
int vs = _VS; int vs = _VS;
int vt = _VT; int vt = _VT;
MatrixSize sz = GetMtxSizeSafe(op); MatrixSize sz = GetMtxSizeSafe(op);
sprintf(out, "%s%s\t%s, %s, %s", name, VSuff(op), MN(vd, sz), MN(vs, sz), VN(vt, V_Single)); snprintf(out, outSize, "%s%s\t%s, %s, %s", name, VSuff(op), MN(vd, sz), MN(vs, sz), VN(vt, V_Single));
} }
void Dis_VectorDot(MIPSOpcode op, char *out) void Dis_VectorDot(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
int vd = _VD; int vd = _VD;
int vs = _VS; int vs = _VS;
int vt = _VT; int vt = _VT;
VectorSize sz = GetVecSizeSafe(op); VectorSize sz = GetVecSizeSafe(op);
sprintf(out, "%s%s\t%s, %s, %s", name, VSuff(op), VN(vd, V_Single), VN(vs,sz), VN(vt, sz)); snprintf(out, outSize, "%s%s\t%s, %s, %s", name, VSuff(op), VN(vd, V_Single), VN(vs,sz), VN(vt, sz));
} }
void Dis_Vtfm(MIPSOpcode op, char *out) void Dis_Vtfm(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
int vd = _VD; int vd = _VD;
int vs = _VS; int vs = _VS;
int vt = _VT; int vt = _VT;
@ -331,25 +320,23 @@ namespace MIPSDis
if (n == ins) if (n == ins)
{ {
//homogenous //homogenous
sprintf(out, "vhtfm%i%s\t%s, %s, %s", n, VSuff(op), VN(vd, sz), MN(vs, msz), VN(vt, sz)); snprintf(out, outSize, "vhtfm%i%s\t%s, %s, %s", n, VSuff(op), VN(vd, sz), MN(vs, msz), VN(vt, sz));
} }
else if (n == ins+1) else if (n == ins+1)
{ {
sprintf(out, "vtfm%i%s\t%s, %s, %s", n, VSuff(op), VN(vd, sz), MN(vs, msz), VN(vt, sz)); snprintf(out, outSize, "vtfm%i%s\t%s, %s, %s", n, VSuff(op), VN(vd, sz), MN(vs, msz), VN(vt, sz));
} }
else else
{ {
sprintf(out,"BADVTFM"); truncate_cpy(out, outSize, "BADVTFM");
} }
} }
void Dis_Vflush(MIPSOpcode op, char *out) void Dis_Vflush(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{ truncate_cpy(out, outSize, "vflush");
sprintf(out,"vflush");
} }
void Dis_Vcrs(MIPSOpcode op, char *out) void Dis_Vcrs(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
int vt = _VT; int vt = _VT;
int vs = _VS; int vs = _VS;
@ -357,26 +344,24 @@ namespace MIPSDis
VectorSize sz = GetVecSizeSafe(op); VectorSize sz = GetVecSizeSafe(op);
if (sz != V_Triple) if (sz != V_Triple)
{ {
sprintf(out, "vcrs\tERROR"); truncate_cpy(out, outSize, "vcrs\tERROR");
} }
else else
sprintf(out, "%s%s\t%s, %s, %s", name, VSuff(op), VN(vd, sz), VN(vs, sz), VN(vt,sz)); snprintf(out, outSize, "%s%s\t%s, %s, %s", name, VSuff(op), VN(vd, sz), VN(vs, sz), VN(vt,sz));
} }
void Dis_Vcmp(MIPSOpcode op, char *out) void Dis_Vcmp(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
int vt = _VT; int vt = _VT;
int vs = _VS; int vs = _VS;
int cond = op&15; int cond = op&15;
VectorSize sz = GetVecSizeSafe(op); VectorSize sz = GetVecSizeSafe(op);
const char *condNames[16] = {"FL","EQ","LT","LE","TR","NE","GE","GT","EZ","EN","EI","ES","NZ","NN","NI","NS"}; const char *condNames[16] = {"FL","EQ","LT","LE","TR","NE","GE","GT","EZ","EN","EI","ES","NZ","NN","NI","NS"};
sprintf(out, "%s%s\t%s, %s, %s", name, VSuff(op), condNames[cond], VN(vs, sz), VN(vt,sz)); snprintf(out, outSize, "%s%s\t%s, %s, %s", name, VSuff(op), condNames[cond], VN(vs, sz), VN(vt,sz));
} }
void Dis_Vcmov(MIPSOpcode op, char *out) void Dis_Vcmov(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
VectorSize sz = GetVecSizeSafe(op); VectorSize sz = GetVecSizeSafe(op);
int vd = _VD; int vd = _VD;
@ -385,61 +370,55 @@ namespace MIPSDis
int imm3 = (op>>16)&7; int imm3 = (op>>16)&7;
if (tf > 1) if (tf > 1)
{ {
sprintf(out, "%s\tARGH%i", name, tf); snprintf(out, outSize, "%s\tARGH%i", name, tf);
return; return;
} }
if (imm3<6) if (imm3<6)
sprintf(out, "%s%s%s\t%s, %s, CC[%i]", name, tf==0?"t":"f", VSuff(op), VN(vd, sz), VN(vs,sz), imm3); snprintf(out, outSize, "%s%s%s\t%s, %s, CC[%i]", name, tf==0?"t":"f", VSuff(op), VN(vd, sz), VN(vs,sz), imm3);
else if (imm3 == 6) else if (imm3 == 6)
sprintf(out, "%s%s%s\t%s, %s, CC[...]", name, tf==0?"t":"f", VSuff(op), VN(vd, sz), VN(vs,sz)); snprintf(out, outSize, "%s%s%s\t%s, %s, CC[...]", name, tf==0?"t":"f", VSuff(op), VN(vd, sz), VN(vs,sz));
} }
void Dis_Vfad(MIPSOpcode op, char *out) void Dis_Vfad(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
int vd = _VD; int vd = _VD;
int vs = _VS; int vs = _VS;
VectorSize sz = GetVecSizeSafe(op); VectorSize sz = GetVecSizeSafe(op);
sprintf(out, "%s%s\t%s, %s", name, VSuff(op), VN(vd, V_Single), VN(vs,sz)); snprintf(out, outSize, "%s%s\t%s, %s", name, VSuff(op), VN(vd, V_Single), VN(vs,sz));
} }
void Dis_VScl(MIPSOpcode op, char *out) void Dis_VScl(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
int vd = _VD; int vd = _VD;
int vs = _VS; int vs = _VS;
int vt = _VT; int vt = _VT;
VectorSize sz = GetVecSizeSafe(op); VectorSize sz = GetVecSizeSafe(op);
sprintf(out, "%s%s\t%s, %s, %s", name, VSuff(op), VN(vd, sz), VN(vs,sz), VN(vt, V_Single)); snprintf(out, outSize, "%s%s\t%s, %s, %s", name, VSuff(op), VN(vd, sz), VN(vs,sz), VN(vt, V_Single));
} }
void Dis_VectorSet1(MIPSOpcode op, char *out) void Dis_VectorSet1(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
int vd = _VD; int vd = _VD;
VectorSize sz = GetVecSizeSafe(op); VectorSize sz = GetVecSizeSafe(op);
sprintf(out, "%s%s\t%s",name,VSuff(op),VN(vd, sz)); snprintf(out, outSize, "%s%s\t%s", name, VSuff(op), VN(vd, sz));
} }
void Dis_VectorSet2(MIPSOpcode op, char *out) void Dis_VectorSet2(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
int vd = _VD; int vd = _VD;
int vs = _VS; int vs = _VS;
VectorSize sz = GetVecSizeSafe(op); VectorSize sz = GetVecSizeSafe(op);
sprintf(out, "%s%s\t%s, %s",name,VSuff(op),VN(vd, sz),VN(vs, sz)); snprintf(out, outSize, "%s%s\t%s, %s", name, VSuff(op), VN(vd, sz), VN(vs, sz));
} }
void Dis_VectorSet3(MIPSOpcode op, char *out) void Dis_VectorSet3(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
int vd = _VD; int vd = _VD;
int vs = _VS; int vs = _VS;
int vt = _VT; int vt = _VT;
VectorSize sz = GetVecSizeSafe(op); VectorSize sz = GetVecSizeSafe(op);
sprintf(out, "%s%s\t%s, %s, %s", name, VSuff(op), VN(vd, sz), VN(vs,sz), VN(vt, sz)); snprintf(out, outSize, "%s%s\t%s, %s, %s", name, VSuff(op), VN(vd, sz), VN(vs,sz), VN(vt, sz));
} }
void Dis_VRot(MIPSOpcode op, char *out) void Dis_VRot(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
int vd = _VD; int vd = _VD;
int vs = _VS; int vs = _VS;
int imm = (op>>16) & 0x1f; int imm = (op>>16) & 0x1f;
@ -468,11 +447,10 @@ namespace MIPSDis
temp[pos++] = ']'; temp[pos++] = ']';
temp[pos]=0; temp[pos]=0;
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
sprintf(out, "%s%s\t%s, %s, %s",name,VSuff(op),VN(vd, sz),VN(vs, V_Single),temp); snprintf(out, outSize, "%s%s\t%s, %s, %s", name, VSuff(op), VN(vd, sz), VN(vs, V_Single),temp);
} }
void Dis_CrossQuat(MIPSOpcode op, char *out) void Dis_CrossQuat(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
VectorSize sz = GetVecSizeSafe(op); VectorSize sz = GetVecSizeSafe(op);
const char *name; const char *name;
switch (sz) switch (sz)
@ -493,39 +471,35 @@ namespace MIPSDis
int vd = _VD; int vd = _VD;
int vs = _VS; int vs = _VS;
int vt = _VT; int vt = _VT;
sprintf(out, "%s%s\t%s, %s, %s", name, VSuff(op), VN(vd, sz), VN(vs,sz), VN(vt, sz)); snprintf(out, outSize, "%s%s\t%s, %s, %s", name, VSuff(op), VN(vd, sz), VN(vs,sz), VN(vt, sz));
} }
void Dis_Vbfy(MIPSOpcode op, char *out) void Dis_Vbfy(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
VectorSize sz = GetVecSizeSafe(op); VectorSize sz = GetVecSizeSafe(op);
int vd = _VD; int vd = _VD;
int vs = _VS; int vs = _VS;
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
sprintf(out, "%s%s\t%s, %s",name,VSuff(op),VN(vd, sz),VN(vs, sz)); snprintf(out, outSize, "%s%s\t%s, %s", name, VSuff(op), VN(vd, sz), VN(vs, sz));
} }
void Dis_Vf2i(MIPSOpcode op, char *out) void Dis_Vf2i(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
VectorSize sz = GetVecSizeSafe(op); VectorSize sz = GetVecSizeSafe(op);
int vd = _VD; int vd = _VD;
int vs = _VS; int vs = _VS;
int imm = (op>>16)&0x1f; int imm = (op>>16)&0x1f;
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
sprintf(out, "%s%s\t%s, %s, %i",name,VSuff(op),VN(vd, sz),VN(vs, sz),imm); snprintf(out, outSize, "%s%s\t%s, %s, %i", name, VSuff(op), VN(vd, sz), VN(vs, sz), imm);
} }
void Dis_Vs2i(MIPSOpcode op, char *out) void Dis_Vs2i(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
VectorSize sz = GetVecSizeSafe(op); VectorSize sz = GetVecSizeSafe(op);
int vd = _VD; int vd = _VD;
int vs = _VS; int vs = _VS;
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
sprintf(out, "%s%s\t%s, %s",name,VSuff(op),VN(vd, sz),VN(vs, sz)); snprintf(out, outSize, "%s%s\t%s, %s", name, VSuff(op), VN(vd, sz), VN(vs, sz));
} }
void Dis_Vi2x(MIPSOpcode op, char *out) void Dis_Vi2x(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
VectorSize sz = GetVecSizeSafe(op); VectorSize sz = GetVecSizeSafe(op);
VectorSize dsz = GetHalfVectorSizeSafe(sz); VectorSize dsz = GetHalfVectorSizeSafe(sz);
if (((op>>16)&3)==0) if (((op>>16)&3)==0)
@ -534,22 +508,20 @@ namespace MIPSDis
int vd = _VD; int vd = _VD;
int vs = _VS; int vs = _VS;
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
sprintf(out, "%s%s\t%s, %s",name,VSuff(op),VN(vd, dsz),VN(vs, sz)); snprintf(out, outSize, "%s%s\t%s, %s", name, VSuff(op), VN(vd, dsz), VN(vs, sz));
} }
void Dis_Vwbn(MIPSOpcode op, char *out) void Dis_Vwbn(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
VectorSize sz = GetVecSizeSafe(op); VectorSize sz = GetVecSizeSafe(op);
int vd = _VD; int vd = _VD;
int vs = _VS; int vs = _VS;
int imm = (int)((op >> 16) & 0xFF); int imm = (int)((op >> 16) & 0xFF);
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
sprintf(out, "%s%s\t%s, %s, %d", name, VSuff(op), VN(vd, sz), VN(vs, sz), imm); snprintf(out, outSize, "%s%s\t%s, %s, %d", name, VSuff(op), VN(vd, sz), VN(vs, sz), imm);
} }
void Dis_Vf2h(MIPSOpcode op, char *out) void Dis_Vf2h(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
VectorSize sz = GetVecSizeSafe(op); VectorSize sz = GetVecSizeSafe(op);
VectorSize dsz = GetHalfVectorSizeSafe(sz); VectorSize dsz = GetHalfVectorSizeSafe(sz);
if (((op>>16)&3)==0) if (((op>>16)&3)==0)
@ -558,55 +530,50 @@ namespace MIPSDis
int vd = _VD; int vd = _VD;
int vs = _VS; int vs = _VS;
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
sprintf(out, "%s%s\t%s, %s", name, VSuff(op), VN(vd, dsz), VN(vs, sz)); snprintf(out, outSize, "%s%s\t%s, %s", name, VSuff(op), VN(vd, dsz), VN(vs, sz));
} }
void Dis_Vh2f(MIPSOpcode op, char *out) void Dis_Vh2f(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
VectorSize sz = GetVecSizeSafe(op); VectorSize sz = GetVecSizeSafe(op);
VectorSize dsz = GetDoubleVectorSizeSafe(sz); VectorSize dsz = GetDoubleVectorSizeSafe(sz);
int vd = _VD; int vd = _VD;
int vs = _VS; int vs = _VS;
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
sprintf(out, "%s%s\t%s, %s", name, VSuff(op), VN(vd, dsz), VN(vs, sz)); snprintf(out, outSize, "%s%s\t%s, %s", name, VSuff(op), VN(vd, dsz), VN(vs, sz));
} }
void Dis_ColorConv(MIPSOpcode op, char *out) void Dis_ColorConv(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
VectorSize sz = GetVecSizeSafe(op); VectorSize sz = GetVecSizeSafe(op);
VectorSize dsz = GetHalfVectorSizeSafe(sz); VectorSize dsz = GetHalfVectorSizeSafe(sz);
int vd = _VD; int vd = _VD;
int vs = _VS; int vs = _VS;
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
sprintf(out, "%s%s\t%s, %s", name, VSuff(op), VN(vd, dsz), VN(vs, sz)); snprintf(out, outSize, "%s%s\t%s, %s", name, VSuff(op), VN(vd, dsz), VN(vs, sz));
} }
void Dis_Vrnds(MIPSOpcode op, char *out) void Dis_Vrnds(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
int vd = _VD; int vd = _VD;
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
sprintf(out, "%s%s\t%s", name, VSuff(op), VN(vd, V_Single)); snprintf(out, outSize, "%s%s\t%s", name, VSuff(op), VN(vd, V_Single));
} }
void Dis_VrndX(MIPSOpcode op, char *out) void Dis_VrndX(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{
VectorSize sz = GetVecSizeSafe(op); VectorSize sz = GetVecSizeSafe(op);
int vd = _VD; int vd = _VD;
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
sprintf(out, "%s%s\t%s", name, VSuff(op), VN(vd, sz)); snprintf(out, outSize, "%s%s\t%s", name, VSuff(op), VN(vd, sz));
} }
void Dis_VBranch(MIPSOpcode op, char *out) void Dis_VBranch(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
{ u32 off = pc;
u32 off = disPC;
int imm = SignExtend16ToS32(op&0xFFFF) << 2; int imm = SignExtend16ToS32(op&0xFFFF) << 2;
int imm3 = (op>>18)&7; int imm3 = (op>>18)&7;
off += imm + 4; off += imm + 4;
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
sprintf(out, "%s\t->$%08x (CC[%i])",name,off,imm3); snprintf(out, outSize, "%s\t->$%08x (CC[%i])", name, off, imm3);
} }
} }

View File

@ -19,52 +19,50 @@
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
extern u32 disPC;
namespace MIPSDis namespace MIPSDis
{ {
void Dis_Mftv(MIPSOpcode op, char *out); void Dis_Mftv(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_Vmfvc(MIPSOpcode op, char *out); void Dis_Vmfvc(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_Vmtvc(MIPSOpcode op, char *out); void Dis_Vmtvc(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_SV(MIPSOpcode op, char *out); void Dis_SV(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_SVQ(MIPSOpcode op, char *out); void Dis_SVQ(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_SVLRQ(MIPSOpcode op, char *out); void Dis_SVLRQ(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_MatrixSet1(MIPSOpcode op, char *out); void Dis_MatrixSet1(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_MatrixSet2(MIPSOpcode op, char *out); void Dis_MatrixSet2(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_MatrixSet3(MIPSOpcode op, char *out); void Dis_MatrixSet3(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_MatrixMult(MIPSOpcode op, char *out); void Dis_MatrixMult(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_Vmscl(MIPSOpcode op, char *out); void Dis_Vmscl(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_VectorDot(MIPSOpcode op, char *out); void Dis_VectorDot(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_Vfad(MIPSOpcode op, char *out); void Dis_Vfad(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_VectorSet1(MIPSOpcode op, char *out); void Dis_VectorSet1(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_VectorSet2(MIPSOpcode op, char *out); void Dis_VectorSet2(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_VectorSet3(MIPSOpcode op, char *out); void Dis_VectorSet3(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_VRot(MIPSOpcode op, char *out); void Dis_VRot(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_VScl(MIPSOpcode op, char *out); void Dis_VScl(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_VPFXST(MIPSOpcode op, char *out); void Dis_VPFXST(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_VPFXD(MIPSOpcode op, char *out); void Dis_VPFXD(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_Vcrs(MIPSOpcode op, char *out); void Dis_Vcrs(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_Viim(MIPSOpcode op, char *out); void Dis_Viim(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_Vcst(MIPSOpcode op, char *out); void Dis_Vcst(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_CrossQuat(MIPSOpcode op, char *out); void Dis_CrossQuat(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_Vtfm(MIPSOpcode op, char *out); void Dis_Vtfm(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_Vcmp(MIPSOpcode op, char *out); void Dis_Vcmp(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_Vcmov(MIPSOpcode op, char *out); void Dis_Vcmov(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_Vflush(MIPSOpcode op, char *out); void Dis_Vflush(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_Vbfy(MIPSOpcode op, char *out); void Dis_Vbfy(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_Vf2i(MIPSOpcode op, char *out); void Dis_Vf2i(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_Vi2x(MIPSOpcode op, char *out); void Dis_Vi2x(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_Vs2i(MIPSOpcode op, char *out); void Dis_Vs2i(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_Vwbn(MIPSOpcode op, char *out); void Dis_Vwbn(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_Vf2h(MIPSOpcode op, char *out); void Dis_Vf2h(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_Vh2f(MIPSOpcode op, char *out); void Dis_Vh2f(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_Vrnds(MIPSOpcode op, char *out); void Dis_Vrnds(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_VrndX(MIPSOpcode op, char *out); void Dis_VrndX(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_ColorConv(MIPSOpcode op, char *out); void Dis_ColorConv(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_VBranch(MIPSOpcode op, char *out); void Dis_VBranch(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
} }

View File

@ -124,7 +124,7 @@ void ApplyPrefixST(float *r, u32 data, VectorSize size, float invalid = 0.0f) {
if (!constants) { if (!constants) {
if (regnum >= n) { if (regnum >= n) {
// We mostly handle this now, but still worth reporting. // We mostly handle this now, but still worth reporting.
ERROR_LOG_REPORT(CPU, "Invalid VFPU swizzle: %08x: %i / %d at PC = %08x (%s)", data, regnum, n, currentMIPS->pc, MIPSDisasmAt(currentMIPS->pc)); ERROR_LOG_REPORT(CPU, "Invalid VFPU swizzle: %08x: %i / %d at PC = %08x (%s)", data, regnum, n, currentMIPS->pc, MIPSDisasmAt(currentMIPS->pc).c_str());
} }
r[i] = origV[regnum]; r[i] = origV[regnum];
if (abs) if (abs)

View File

@ -918,14 +918,13 @@ void MIPSCompileOp(MIPSOpcode op, MIPSComp::MIPSFrontendInterface *jit) {
} }
} }
void MIPSDisAsm(MIPSOpcode op, u32 pc, char *out, bool tabsToSpaces) { void MIPSDisAsm(MIPSOpcode op, u32 pc, char *out, size_t outSize, bool tabsToSpaces) {
if (op == 0) { if (op == 0) {
strcpy(out, "nop"); truncate_cpy(out, outSize, "nop");
} else { } else {
disPC = pc;
const MIPSInstruction *instr = MIPSGetInstruction(op); const MIPSInstruction *instr = MIPSGetInstruction(op);
if (instr && instr->disasm) { if (instr && instr->disasm) {
instr->disasm(op, out); instr->disasm(op, pc, out, outSize);
if (tabsToSpaces) { if (tabsToSpaces) {
while (*out) { while (*out) {
if (*out == '\t') if (*out == '\t')
@ -934,7 +933,7 @@ void MIPSDisAsm(MIPSOpcode op, u32 pc, char *out, bool tabsToSpaces) {
} }
} }
} else { } else {
strcpy(out, "no instruction :("); truncate_cpy(out, outSize, "no instruction :(");
} }
} }
} }
@ -946,7 +945,7 @@ static inline void Interpret(const MIPSInstruction *instr, MIPSOpcode op) {
ERROR_LOG_REPORT(CPU, "Unknown instruction %08x at %08x", op.encoding, currentMIPS->pc); ERROR_LOG_REPORT(CPU, "Unknown instruction %08x at %08x", op.encoding, currentMIPS->pc);
// Try to disassemble it // Try to disassemble it
char disasm[256]; char disasm[256];
MIPSDisAsm(op, currentMIPS->pc, disasm); MIPSDisAsm(op, currentMIPS->pc, disasm, sizeof(disasm));
_dbg_assert_msg_(0, "%s", disasm); _dbg_assert_msg_(0, "%s", disasm);
currentMIPS->pc += 4; currentMIPS->pc += 4;
} }
@ -1120,8 +1119,8 @@ int MIPSGetMemoryAccessSize(MIPSOpcode op) {
return 0; return 0;
} }
const char *MIPSDisasmAt(u32 compilerPC) { std::string MIPSDisasmAt(u32 compilerPC) {
static char temp[256]; char temp[512];
MIPSDisAsm(Memory::Read_Instruction(compilerPC), 0, temp); MIPSDisAsm(Memory::Read_Instruction(compilerPC), 0, temp, sizeof(temp));
return temp; return temp;
} }

View File

@ -17,6 +17,7 @@
#pragma once #pragma once
#include <string>
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
#include "Core/MIPS/MIPS.h" #include "Core/MIPS/MIPS.h"
@ -115,7 +116,7 @@ struct MIPSInfo {
u64 cycles : 16; u64 cycles : 16;
}; };
typedef void (CDECL *MIPSDisFunc)(MIPSOpcode opcode, char *out); typedef void (CDECL *MIPSDisFunc)(MIPSOpcode opcode, uint32_t pc, char *out, size_t outSize);
typedef void (CDECL *MIPSInterpretFunc)(MIPSOpcode opcode); typedef void (CDECL *MIPSInterpretFunc)(MIPSOpcode opcode);
namespace MIPSComp { namespace MIPSComp {
@ -123,7 +124,7 @@ namespace MIPSComp {
} }
void MIPSCompileOp(MIPSOpcode op, MIPSComp::MIPSFrontendInterface *jit); void MIPSCompileOp(MIPSOpcode op, MIPSComp::MIPSFrontendInterface *jit);
void MIPSDisAsm(MIPSOpcode op, u32 pc, char *out, bool tabsToSpaces = false); void MIPSDisAsm(MIPSOpcode op, u32 pc, char *out, size_t outSize, bool tabsToSpaces = false);
MIPSInfo MIPSGetInfo(MIPSOpcode op); MIPSInfo MIPSGetInfo(MIPSOpcode op);
void MIPSInterpret(MIPSOpcode op); //only for those rare ones void MIPSInterpret(MIPSOpcode op); //only for those rare ones
int MIPSInterpret_RunUntil(u64 globalTicks); int MIPSInterpret_RunUntil(u64 globalTicks);
@ -132,4 +133,4 @@ MIPSInterpretFunc MIPSGetInterpretFunc(MIPSOpcode op);
int MIPSGetInstructionCycleEstimate(MIPSOpcode op); int MIPSGetInstructionCycleEstimate(MIPSOpcode op);
int MIPSGetMemoryAccessSize(MIPSOpcode op); int MIPSGetMemoryAccessSize(MIPSOpcode op);
const char *MIPSGetName(MIPSOpcode op); const char *MIPSGetName(MIPSOpcode op);
const char *MIPSDisasmAt(u32 compilerPC); std::string MIPSDisasmAt(u32 compilerPC);

View File

@ -23,6 +23,7 @@
#include "Common/BitScan.h" #include "Common/BitScan.h"
#include "Common/CommonFuncs.h" #include "Common/CommonFuncs.h"
#include "Common/File/VFS/VFS.h" #include "Common/File/VFS/VFS.h"
#include "Common/StringUtils.h"
#include "Core/Reporting.h" #include "Core/Reporting.h"
#include "Core/MIPS/MIPS.h" #include "Core/MIPS/MIPS.h"
#include "Core/MIPS/MIPSVFPUUtils.h" #include "Core/MIPS/MIPSVFPUUtils.h"
@ -538,11 +539,7 @@ MatrixOverlapType GetMatrixOverlap(int mtx1, int mtx2, MatrixSize msize) {
return OVERLAP_NONE; return OVERLAP_NONE;
} }
const char *GetVectorNotation(int reg, VectorSize size) std::string GetVectorNotation(int reg, VectorSize size) {
{
static char temp[4][16];
static int yo = 0; yo++; yo &= 3;
int mtx = (reg>>2)&7; int mtx = (reg>>2)&7;
int col = reg&3; int col = reg&3;
int row = 0; int row = 0;
@ -557,34 +554,27 @@ const char *GetVectorNotation(int reg, VectorSize size)
} }
if (transpose && c == 'C') c='R'; if (transpose && c == 'C') c='R';
if (transpose) if (transpose)
snprintf(temp[yo], sizeof(temp[yo]), "%c%i%i%i",c,mtx,row,col); return StringFromFormat("%c%i%i%i", c, mtx, row, col);
else return StringFromFormat("%c%i%i%i", c, mtx, col, row);
snprintf(temp[yo], sizeof(temp[yo]), "%c%i%i%i",c,mtx,col,row);
return temp[yo];
} }
const char *GetMatrixNotation(int reg, MatrixSize size) std::string GetMatrixNotation(int reg, MatrixSize size) {
{ int mtx = (reg>>2)&7;
static char temp[4][16]; int col = reg&3;
static int yo=0;yo++;yo&=3; int row = 0;
int mtx = (reg>>2)&7; int transpose = (reg>>5)&1;
int col = reg&3; char c;
int row = 0; switch (size)
int transpose = (reg>>5)&1; {
char c; case M_2x2: c='M'; row=(reg>>5)&2; break;
switch (size) case M_3x3: c='M'; row=(reg>>6)&1; break;
{ case M_4x4: c='M'; row=(reg>>5)&2; break;
case M_2x2: c='M'; row=(reg>>5)&2; break; default: c='?'; break;
case M_3x3: c='M'; row=(reg>>6)&1; break; }
case M_4x4: c='M'; row=(reg>>5)&2; break; if (transpose && c=='M') c='E';
default: c='?'; break; if (transpose)
} return StringFromFormat("%c%i%i%i", c, mtx, row, col);
if (transpose && c=='M') c='E'; return StringFromFormat("%c%i%i%i", c, mtx, col, row);
if (transpose)
snprintf(temp[yo], sizeof(temp[yo]), "%c%i%i%i",c,mtx,row,col);
else
snprintf(temp[yo], sizeof(temp[yo]), "%c%i%i%i",c,mtx,col,row);
return temp[yo];
} }
bool GetVFPUCtrlMask(int reg, u32 *mask) { bool GetVFPUCtrlMask(int reg, u32 *mask) {

View File

@ -16,8 +16,9 @@
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#pragma once #pragma once
#include <cmath>
#include <cmath>
#include <string>
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
#include "Core/MIPS/MIPS.h" #include "Core/MIPS/MIPS.h"
@ -216,8 +217,8 @@ VectorSize MatrixVectorSize(MatrixSize sz);
int GetNumVectorElements(VectorSize sz); int GetNumVectorElements(VectorSize sz);
int GetMatrixSideSafe(MatrixSize sz); int GetMatrixSideSafe(MatrixSize sz);
int GetMatrixSide(MatrixSize sz); int GetMatrixSide(MatrixSize sz);
const char *GetVectorNotation(int reg, VectorSize size); std::string GetVectorNotation(int reg, VectorSize size);
const char *GetMatrixNotation(int reg, MatrixSize size); std::string GetMatrixNotation(int reg, MatrixSize size);
inline bool IsMatrixTransposed(int matrixReg) { inline bool IsMatrixTransposed(int matrixReg) {
return (matrixReg >> 5) & 1; return (matrixReg >> 5) & 1;
} }

View File

@ -107,7 +107,7 @@ static void JitBranchLog(MIPSOpcode op, u32 pc) {
static void JitBranchLogMismatch(MIPSOpcode op, u32 pc) static void JitBranchLogMismatch(MIPSOpcode op, u32 pc)
{ {
char temp[256]; char temp[256];
MIPSDisAsm(op, pc, temp, true); MIPSDisAsm(op, pc, temp, sizeof(temp), true);
ERROR_LOG(JIT, "Bad jump: %s - int:%08x jit:%08x", temp, currentMIPS->intBranchExit, currentMIPS->jitBranchExit); ERROR_LOG(JIT, "Bad jump: %s - int:%08x jit:%08x", temp, currentMIPS->intBranchExit, currentMIPS->jitBranchExit);
Core_EnableStepping(true, "jit.branchdebug", pc); Core_EnableStepping(true, "jit.branchdebug", pc);
} }

View File

@ -17,6 +17,7 @@
#include "Common/Log.h" #include "Common/Log.h"
#include "Common/Math/expression_parser.h" #include "Common/Math/expression_parser.h"
#include "Common/StringUtils.h"
#include "Core/Debugger/SymbolMap.h" #include "Core/Debugger/SymbolMap.h"
#include "GPU/Common/GPUDebugInterface.h" #include "GPU/Common/GPUDebugInterface.h"
#include "GPU/Debugger/Debugger.h" #include "GPU/Debugger/Debugger.h"
@ -516,7 +517,7 @@ public:
bool parseSymbol(char *str, uint32_t &symbolValue) override; bool parseSymbol(char *str, uint32_t &symbolValue) override;
uint32_t getReferenceValue(uint32_t referenceIndex) override; uint32_t getReferenceValue(uint32_t referenceIndex) override;
ExpressionType getReferenceType(uint32_t referenceIndex) override; ExpressionType getReferenceType(uint32_t referenceIndex) override;
bool getMemoryValue(uint32_t address, int size, uint32_t &dest, char *error, size_t errorBufSize) override; bool getMemoryValue(uint32_t address, int size, uint32_t &dest, std::string *error) override;
private: private:
bool parseFieldReference(const char *ref, const char *field, uint32_t &referenceIndex); bool parseFieldReference(const char *ref, const char *field, uint32_t &referenceIndex);
@ -926,7 +927,7 @@ ExpressionType GEExpressionFunctions::getFieldType(GECmdFormat fmt, GECmdField f
return EXPR_TYPE_UINT; return EXPR_TYPE_UINT;
} }
bool GEExpressionFunctions::getMemoryValue(uint32_t address, int size, uint32_t &dest, char *error, size_t errorBufSize) { bool GEExpressionFunctions::getMemoryValue(uint32_t address, int size, uint32_t &dest, std::string *error) {
// We allow, but ignore, bad access. // We allow, but ignore, bad access.
// If we didn't, log/condition statements that reference registers couldn't be configured. // If we didn't, log/condition statements that reference registers couldn't be configured.
uint32_t valid = Memory::ValidSize(address, size); uint32_t valid = Memory::ValidSize(address, size);
@ -946,7 +947,7 @@ bool GEExpressionFunctions::getMemoryValue(uint32_t address, int size, uint32_t
return true; return true;
} }
snprintf(error, errorBufSize, "Unexpected memory access size %d", size); *error = StringFromFormat("Unexpected memory access size %d", size);
return false; return false;
} }

View File

@ -1186,7 +1186,6 @@ int main(int argc, char *argv[]) {
break; break;
} }
#endif #endif
// TODO: Should we even keep the "non-precise" events?
if (event.wheel.y > 0) { if (event.wheel.y > 0) {
key.keyCode = NKCODE_EXT_MOUSEWHEEL_UP; key.keyCode = NKCODE_EXT_MOUSEWHEEL_UP;
mouseWheelMovedUpFrames = 5; mouseWheelMovedUpFrames = 5;

View File

@ -1143,7 +1143,7 @@ void JitCompareScreen::OnRandomBlock(int flag) {
MIPSOpcode opcode = Memory::Read_Instruction(addr); MIPSOpcode opcode = Memory::Read_Instruction(addr);
if (MIPSGetInfo(opcode) & flag) { if (MIPSGetInfo(opcode) & flag) {
char temp[256]; char temp[256];
MIPSDisAsm(opcode, addr, temp); MIPSDisAsm(opcode, addr, temp, sizeof(temp));
// INFO_LOG(HLE, "Stopping at random instruction: %08x %s", addr, temp); // INFO_LOG(HLE, "Stopping at random instruction: %08x %s", addr, temp);
anyWanted = true; anyWanted = true;
break; break;

View File

@ -296,6 +296,7 @@
<ItemGroup> <ItemGroup>
<ClCompile Include="..\..\ext\cpu_features\src\filesystem.c" /> <ClCompile Include="..\..\ext\cpu_features\src\filesystem.c" />
<ClCompile Include="..\..\ext\cpu_features\src\impl_aarch64_linux_or_android.c" /> <ClCompile Include="..\..\ext\cpu_features\src\impl_aarch64_linux_or_android.c" />
<ClCompile Include="..\..\ext\cpu_features\src\impl_aarch64_windows.c" />
<ClCompile Include="..\..\ext\cpu_features\src\impl_arm_linux_or_android.c" /> <ClCompile Include="..\..\ext\cpu_features\src\impl_arm_linux_or_android.c" />
<ClCompile Include="..\..\ext\cpu_features\src\impl_mips_linux_or_android.c" /> <ClCompile Include="..\..\ext\cpu_features\src\impl_mips_linux_or_android.c" />
<ClCompile Include="..\..\ext\cpu_features\src\impl_ppc_linux.c" /> <ClCompile Include="..\..\ext\cpu_features\src\impl_ppc_linux.c" />

View File

@ -110,6 +110,9 @@
<ClCompile Include="..\..\ext\cpu_features\src\impl_aarch64_linux_or_android.c"> <ClCompile Include="..\..\ext\cpu_features\src\impl_aarch64_linux_or_android.c">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\ext\cpu_features\src\impl_aarch64_windows.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\ext\cpu_features\src\impl_arm_linux_or_android.c"> <ClCompile Include="..\..\ext\cpu_features\src\impl_arm_linux_or_android.c">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>

View File

@ -302,7 +302,7 @@ void CtrlDisAsmView::assembleOpcode(u32 address, std::string defaultText)
{ {
for (int reg = 0; reg < debugger->GetNumRegsInCategory(cat); reg++) for (int reg = 0; reg < debugger->GetNumRegsInCategory(cat); reg++)
{ {
if (strcasecmp(debugger->GetRegName(cat,reg),registerName.c_str()) == 0) if (strcasecmp(debugger->GetRegName(cat,reg).c_str(), registerName.c_str()) == 0)
{ {
debugger->SetRegValue(cat,reg,value); debugger->SetRegValue(cat,reg,value);
Reporting::NotifyDebugger(); Reporting::NotifyDebugger();

View File

@ -251,7 +251,7 @@ void CtrlRegisterList::onPaint(WPARAM wParam, LPARAM lParam)
if (i<cpu->GetNumRegsInCategory(category)) if (i<cpu->GetNumRegsInCategory(category))
{ {
char temp[256]; char temp[256];
int temp_len = snprintf(temp, sizeof(temp), "%s", cpu->GetRegName(category, i)); int temp_len = snprintf(temp, sizeof(temp), "%s", cpu->GetRegName(category, i).c_str());
SetTextColor(hdc,0x600000); SetTextColor(hdc,0x600000);
TextOutA(hdc,17,rowY1,temp,temp_len); TextOutA(hdc,17,rowY1,temp,temp_len);
SetTextColor(hdc,0x000000); SetTextColor(hdc,0x000000);

View File

@ -359,6 +359,7 @@
<ItemGroup> <ItemGroup>
<ClCompile Include="cpu_features\src\filesystem.c" /> <ClCompile Include="cpu_features\src\filesystem.c" />
<ClCompile Include="cpu_features\src\impl_aarch64_linux_or_android.c" /> <ClCompile Include="cpu_features\src\impl_aarch64_linux_or_android.c" />
<ClCompile Include="cpu_features\src\impl_aarch64_windows.c" />
<ClCompile Include="cpu_features\src\impl_arm_linux_or_android.c" /> <ClCompile Include="cpu_features\src\impl_arm_linux_or_android.c" />
<ClCompile Include="cpu_features\src\impl_mips_linux_or_android.c" /> <ClCompile Include="cpu_features\src\impl_mips_linux_or_android.c" />
<ClCompile Include="cpu_features\src\impl_ppc_linux.c" /> <ClCompile Include="cpu_features\src\impl_ppc_linux.c" />

View File

@ -111,6 +111,9 @@
<ClCompile Include="cpu_features\src\impl_aarch64_linux_or_android.c"> <ClCompile Include="cpu_features\src\impl_aarch64_linux_or_android.c">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="cpu_features\src\impl_aarch64_windows.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cpu_features\src\impl_arm_linux_or_android.c"> <ClCompile Include="cpu_features\src\impl_arm_linux_or_android.c">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>

View File

@ -207,6 +207,7 @@ endif
SOURCES_C += \ SOURCES_C += \
$(EXTDIR)/cpu_features/src/filesystem.c \ $(EXTDIR)/cpu_features/src/filesystem.c \
$(EXTDIR)/cpu_features/src/impl_aarch64_linux_or_android.c \ $(EXTDIR)/cpu_features/src/impl_aarch64_linux_or_android.c \
$(EXTDIR)/cpu_features/src/impl_aarch64_windows.c \
$(EXTDIR)/cpu_features/src/impl_arm_linux_or_android.c \ $(EXTDIR)/cpu_features/src/impl_arm_linux_or_android.c \
$(EXTDIR)/cpu_features/src/impl_mips_linux_or_android.c \ $(EXTDIR)/cpu_features/src/impl_mips_linux_or_android.c \
$(EXTDIR)/cpu_features/src/impl_ppc_linux.c \ $(EXTDIR)/cpu_features/src/impl_ppc_linux.c \

View File

@ -164,7 +164,7 @@ bool TestJit() {
addr = currentMIPS->pc; addr = currentMIPS->pc;
for (size_t j = 0; j < ARRAY_SIZE(lines); ++j) { for (size_t j = 0; j < ARRAY_SIZE(lines); ++j) {
char line[512]; char line[512];
MIPSDisAsm(Memory::Read_Instruction(addr), addr, line, true); MIPSDisAsm(Memory::Read_Instruction(addr), addr, line, sizeof(line), true);
addr += 4; addr += 4;
printf("%s\n", line); printf("%s\n", line);
} }

View File

@ -243,8 +243,8 @@ bool TestArmEmitter() {
int R001 = GetRowName(0, M_4x4, 1, 0); int R001 = GetRowName(0, M_4x4, 1, 0);
int R002 = GetRowName(0, M_4x4, 2, 0); int R002 = GetRowName(0, M_4x4, 2, 0);
int R003 = GetRowName(0, M_4x4, 3, 0); int R003 = GetRowName(0, M_4x4, 3, 0);
printf("Col 010: %s\n", GetVectorNotation(C010, V_Quad)); printf("Col 010: %s\n", GetVectorNotation(C010, V_Quad).c_str());
printf("Row 003: %s\n", GetVectorNotation(R003, V_Quad)); printf("Row 003: %s\n", GetVectorNotation(R003, V_Quad).c_str());
MIPSAnalyst::AnalysisResults results; MIPSAnalyst::AnalysisResults results;
memset(&results, 0, sizeof(results)); memset(&results, 0, sizeof(results));

View File

@ -431,7 +431,7 @@ bool TestMatrixTranspose() {
} }
void TestGetMatrix(int matrix, MatrixSize sz) { void TestGetMatrix(int matrix, MatrixSize sz) {
INFO_LOG(SYSTEM, "Testing matrix %s", GetMatrixNotation(matrix, sz)); INFO_LOG(SYSTEM, "Testing matrix %s", GetMatrixNotation(matrix, sz).c_str());
u8 fullMatrix[16]; u8 fullMatrix[16];
u8 cols[4]; u8 cols[4];
@ -449,8 +449,8 @@ void TestGetMatrix(int matrix, MatrixSize sz) {
// int rowName = GetRowName(matrix, sz, i, 0); // int rowName = GetRowName(matrix, sz, i, 0);
int colName = cols[i]; int colName = cols[i];
int rowName = rows[i]; int rowName = rows[i];
INFO_LOG(SYSTEM, "Column %i: %s", i, GetVectorNotation(colName, vsz)); INFO_LOG(SYSTEM, "Column %i: %s", i, GetVectorNotation(colName, vsz).c_str());
INFO_LOG(SYSTEM, "Row %i: %s", i, GetVectorNotation(rowName, vsz)); INFO_LOG(SYSTEM, "Row %i: %s", i, GetVectorNotation(rowName, vsz).c_str());
u8 colRegs[4]; u8 colRegs[4];
u8 rowRegs[4]; u8 rowRegs[4];