Skip to content

Commit

Permalink
Merge pull request #8193 from lioncash/disasm
Browse files Browse the repository at this point in the history
Common/GekkoDisassembler: Minor changes
  • Loading branch information
leoetlino committed Jun 29, 2019
2 parents 0c626e6 + 188234b commit a88deda
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 75 deletions.
155 changes: 94 additions & 61 deletions Source/Core/Common/GekkoDisassembler.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -34,12 +34,12 @@


#include "Common/GekkoDisassembler.h" #include "Common/GekkoDisassembler.h"


#include <array>
#include <string> #include <string>


#include <fmt/format.h> #include <fmt/format.h>


#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
#include "Common/StringUtil.h"


namespace Common namespace Common
{ {
Expand Down Expand Up @@ -86,37 +86,68 @@ namespace Common
#define PPCGETIDX2(x) (((x)&PPCIDX2MASK) >> PPCIDX2SH) #define PPCGETIDX2(x) (((x)&PPCIDX2MASK) >> PPCIDX2SH)
#define PPCGETSTRM(x) (((x)&PPCSTRM) >> PPCDSH) #define PPCGETSTRM(x) (((x)&PPCSTRM) >> PPCDSH)


static const char* trap_condition[32] = { constexpr std::array<const char*, 32> trap_condition{
nullptr, "lgt", "llt", nullptr, "eq", "lge", "lle", nullptr, nullptr, "lgt", "llt", nullptr, "eq", "lge", "lle", nullptr,
"gt", nullptr, nullptr, nullptr, "ge", nullptr, nullptr, nullptr, "gt", nullptr, nullptr, nullptr, "ge", nullptr, nullptr, nullptr,
"lt", nullptr, nullptr, nullptr, "le", nullptr, nullptr, nullptr, "lt", nullptr, nullptr, nullptr, "le", nullptr, nullptr, nullptr,
"ne", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}; "ne", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,

};
static const char* cmpname[4] = {"cmpw", "cmpd", "cmplw", "cmpld"};

constexpr std::array<const char*, 4> cmpname{
static const char* ps_cmpname[4] = {"ps_cmpu0", "ps_cmpo0", "ps_cmpu1", "ps_cmpo1"}; "cmpw",

"cmpd",
static const char* b_ext[4] = {"", "l", "a", "la"}; "cmplw",

"cmpld",
static const char* b_condition[8] = {"ge", "le", "ne", "ns", "lt", "gt", "eq", "so"}; };


static const char* b_decr[16] = {"nzf", "zf", nullptr, nullptr, "nzt", "zt", nullptr, nullptr, constexpr std::array<const char*, 4> ps_cmpname{
"nz", "z", nullptr, nullptr, "nz", "z", nullptr, nullptr}; "ps_cmpu0",

"ps_cmpo0",
static const char* regsel[2] = {"", "r"}; "ps_cmpu1",

"ps_cmpo1",
static const char* oesel[2] = {"", "o"}; };


static const char* rcsel[2] = {"", "."}; constexpr std::array<const char*, 4> b_ext{

"",
static const char* ldstnames[24] = {"lwz", "lwzu", "lbz", "lbzu", "stw", "stwu", "stb", "stbu", "l",
"lhz", "lhzu", "lha", "lhau", "sth", "sthu", "lmw", "stmw", "a",
"lfs", "lfsu", "lfd", "lfdu", "stfs", "stfsu", "stfd", "stfdu"}; "la",

};
static const char* regnames[32] = {"r0", "sp", "rtoc", "r3", "r4", "r5", "r6", "r7",
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", constexpr std::array<const char*, 8> b_condition{
"r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", "ge", "le", "ne", "ns", "lt", "gt", "eq", "so",
"r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"}; };

constexpr std::array<const char*, 16> b_decr{
"nzf", "zf", nullptr, nullptr, "nzt", "zt", nullptr, nullptr,
"nz", "z", nullptr, nullptr, "nz", "z", nullptr, nullptr,
};

constexpr std::array<const char*, 2> regsel{
"",
"r",
};

constexpr std::array<const char*, 2> oesel{
"",
"o",
};

constexpr std::array<const char*, 2> rcsel{
"",
".",
};

constexpr std::array<const char*, 24> ldstnames{
"lwz", "lwzu", "lbz", "lbzu", "stw", "stwu", "stb", "stbu", "lhz", "lhzu", "lha", "lhau",
"sth", "sthu", "lmw", "stmw", "lfs", "lfsu", "lfd", "lfdu", "stfs", "stfsu", "stfd", "stfdu",
};

constexpr std::array<const char*, 32> regnames{
"r0", "sp", "rtoc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",
"r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", "r21",
"r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
};


// Initialize static class variables. // Initialize static class variables.
u32* GekkoDisassembler::m_instr = nullptr; u32* GekkoDisassembler::m_instr = nullptr;
Expand Down Expand Up @@ -473,7 +504,7 @@ void GekkoDisassembler::cmpi(u32 in, int uimm)
i = (int)PPCGETCRD(in); i = (int)PPCGETCRD(in);
if (i != 0) if (i != 0)
{ {
m_operands += fmt::format("cr{}, ", '0' + i); m_operands += fmt::format("cr{}, ", i);
} }


m_operands += imm(in, uimm, 2, false); m_operands += imm(in, uimm, 2, false);
Expand All @@ -484,7 +515,7 @@ void GekkoDisassembler::cmpi(u32 in, int uimm)
} }
} }


void GekkoDisassembler::addi(u32 in, const std::string& ext) void GekkoDisassembler::addi(u32 in, std::string_view ext)
{ {
if ((in & 0x08000000) && !PPCGETA(in)) if ((in & 0x08000000) && !PPCGETA(in))
{ {
Expand All @@ -508,7 +539,7 @@ void GekkoDisassembler::addi(u32 in, const std::string& ext)
} }


// Build a branch instr. and return number of chars written to operand. // Build a branch instr. and return number of chars written to operand.
size_t GekkoDisassembler::branch(u32 in, const char* bname, int aform, int bdisp) size_t GekkoDisassembler::branch(u32 in, std::string_view bname, int aform, int bdisp)
{ {
int bo = (int)PPCGETD(in); int bo = (int)PPCGETD(in);
int bi = (int)PPCGETA(in); int bi = (int)PPCGETA(in);
Expand Down Expand Up @@ -608,16 +639,16 @@ void GekkoDisassembler::mcrf(u32 in, char c)
} }
} }


void GekkoDisassembler::crop(u32 in, const char* n1, const char* n2) void GekkoDisassembler::crop(u32 in, std::string_view n1, std::string_view n2)
{ {
int crd = (int)PPCGETD(in); int crd = (int)PPCGETD(in);
int cra = (int)PPCGETA(in); int cra = (int)PPCGETA(in);
int crb = (int)PPCGETB(in); int crb = (int)PPCGETB(in);


if ((in & 1) == 0) if ((in & 1) == 0)
{ {
m_opcode = fmt::format("cr{}", (cra == crb && n2) ? n2 : n1); m_opcode = fmt::format("cr{}", (cra == crb && !n2.empty()) ? n2 : n1);
if (cra == crb && n2) if (cra == crb && !n2.empty())
m_operands = fmt::format("{}, {}", crd, cra); m_operands = fmt::format("{}, {}", crd, cra);
else else
m_operands = fmt::format("{}, {}, {}", crd, cra, crb); m_operands = fmt::format("{}, {}, {}", crd, cra, crb);
Expand All @@ -628,7 +659,7 @@ void GekkoDisassembler::crop(u32 in, const char* n1, const char* n2)
} }
} }


void GekkoDisassembler::nooper(u32 in, const char* name, unsigned char dmode) void GekkoDisassembler::nooper(u32 in, std::string_view name, unsigned char dmode)
{ {
if (in & (PPCDMASK | PPCAMASK | PPCBMASK | 1)) if (in & (PPCDMASK | PPCAMASK | PPCBMASK | 1))
{ {
Expand All @@ -641,7 +672,7 @@ void GekkoDisassembler::nooper(u32 in, const char* name, unsigned char dmode)
} }
} }


void GekkoDisassembler::rlw(u32 in, const char* name, int i) void GekkoDisassembler::rlw(u32 in, std::string_view name, int i)
{ {
int s = (int)PPCGETD(in); int s = (int)PPCGETD(in);
int a = (int)PPCGETA(in); int a = (int)PPCGETA(in);
Expand All @@ -654,13 +685,13 @@ void GekkoDisassembler::rlw(u32 in, const char* name, int i)
bsh, mb, me, HelperRotateMask(bsh, mb, me)); bsh, mb, me, HelperRotateMask(bsh, mb, me));
} }


void GekkoDisassembler::ori(u32 in, const char* name) void GekkoDisassembler::ori(u32 in, std::string_view name)
{ {
m_opcode = name; m_opcode = name;
m_operands = imm(in, 1, 1, true); m_operands = imm(in, 1, 1, true);
} }


void GekkoDisassembler::rld(u32 in, const char* name, int i) void GekkoDisassembler::rld(u32 in, std::string_view name, int i)
{ {
int s = (int)PPCGETD(in); int s = (int)PPCGETD(in);
int a = (int)PPCGETA(in); int a = (int)PPCGETA(in);
Expand All @@ -685,7 +716,7 @@ void GekkoDisassembler::cmp(u32 in)


i = (int)PPCGETCRD(in); i = (int)PPCGETCRD(in);
if (i != 0) if (i != 0)
m_operands += fmt::format("cr{},", static_cast<char>('0' + i)); m_operands += fmt::format("cr{},", i);


m_operands += ra_rb(in); m_operands += ra_rb(in);
} }
Expand Down Expand Up @@ -729,8 +760,8 @@ void GekkoDisassembler::trap(u32 in, unsigned char dmode)
} }


// Standard instruction: xxxx rD,rA,rB // Standard instruction: xxxx rD,rA,rB
void GekkoDisassembler::dab(u32 in, const char* name, int mask, int smode, int chkoe, int chkrc, void GekkoDisassembler::dab(u32 in, std::string_view name, int mask, int smode, int chkoe,
unsigned char dmode) int chkrc, unsigned char dmode)
{ {
if (chkrc >= 0 && ((in & 1) != (unsigned int)chkrc)) if (chkrc >= 0 && ((in & 1) != (unsigned int)chkrc))
{ {
Expand All @@ -751,7 +782,7 @@ void GekkoDisassembler::dab(u32 in, const char* name, int mask, int smode, int c
} }


// Last operand is no register: xxxx rD,rA,NB // Last operand is no register: xxxx rD,rA,NB
void GekkoDisassembler::rrn(u32 in, const char* name, int smode, int chkoe, int chkrc, void GekkoDisassembler::rrn(u32 in, std::string_view name, int smode, int chkoe, int chkrc,
unsigned char dmode) unsigned char dmode)
{ {
if (chkrc >= 0 && ((in & 1) != (unsigned int)chkrc)) if (chkrc >= 0 && ((in & 1) != (unsigned int)chkrc))
Expand Down Expand Up @@ -912,7 +943,7 @@ void GekkoDisassembler::sradi(u32 in)
m_operands = fmt::format("{}, {}, {}", regnames[a], regnames[s], bsh); m_operands = fmt::format("{}, {}, {}", regnames[a], regnames[s], bsh);
} }


void GekkoDisassembler::ldst(u32 in, const char* name, char reg, unsigned char dmode) void GekkoDisassembler::ldst(u32 in, std::string_view name, char reg, unsigned char dmode)
{ {
int s = (int)PPCGETD(in); int s = (int)PPCGETD(in);
int a = (int)PPCGETA(in); int a = (int)PPCGETA(in);
Expand All @@ -937,7 +968,7 @@ void GekkoDisassembler::ldst(u32 in, const char* name, char reg, unsigned char d
} }


// Standard floating point instruction: xxxx fD,fA,fC,fB // Standard floating point instruction: xxxx fD,fA,fC,fB
void GekkoDisassembler::fdabc(u32 in, const char* name, int mask, unsigned char dmode) void GekkoDisassembler::fdabc(u32 in, std::string_view name, int mask, unsigned char dmode)
{ {
int err = 0; int err = 0;


Expand Down Expand Up @@ -974,7 +1005,7 @@ void GekkoDisassembler::fmr(u32 in)
} }


// Indexed float instruction: xxxx fD,rA,rB // Indexed float instruction: xxxx fD,rA,rB
void GekkoDisassembler::fdab(u32 in, const char* name, int mask) void GekkoDisassembler::fdab(u32 in, std::string_view name, int mask)
{ {
m_opcode = name; m_opcode = name;
m_operands = fd_ra_rb(in, mask); m_operands = fd_ra_rb(in, mask);
Expand Down Expand Up @@ -1189,7 +1220,7 @@ void GekkoDisassembler::ps(u32 inst)


int i = (int)PPCGETCRD(inst); int i = (int)PPCGETCRD(inst);
if (i != 0) if (i != 0)
m_operands += fmt::format("cr{}, ", '0' + i); m_operands += fmt::format("cr{}, ", i);
m_operands += fmt::format("p{}, p{}", FA, FB); m_operands += fmt::format("p{}, p{}", FA, FB);
return; return;
} }
Expand Down Expand Up @@ -1359,7 +1390,7 @@ u32* GekkoDisassembler::DoDisassembly(bool big_endian)
break; break;


case 129: case 129:
crop(in, "andc", nullptr); // crandc crop(in, "andc", {}); // crandc
break; break;


case 150: case 150:
Expand All @@ -1371,19 +1402,19 @@ u32* GekkoDisassembler::DoDisassembly(bool big_endian)
break; break;


case 225: case 225:
crop(in, "nand", nullptr); // crnand crop(in, "nand", {}); // crnand
break; break;


case 257: case 257:
crop(in, "and", nullptr); // crand crop(in, "and", {}); // crand
break; break;


case 289: case 289:
crop(in, "eqv", "set"); // creqv crop(in, "eqv", "set"); // creqv
break; break;


case 417: case 417:
crop(in, "orc", nullptr); // crorc crop(in, "orc", {}); // crorc
break; break;


case 449: case 449:
Expand Down Expand Up @@ -2328,28 +2359,30 @@ std::string GekkoDisassembler::Disassemble(u32 opcode, u32 current_instruction_a
return m_opcode.append("\t").append(m_operands); return m_opcode.append("\t").append(m_operands);
} }


static const char* gprnames[] = { constexpr std::array<const char*, 32> gpr_names{
" r0", " r1 (sp)", " r2 (rtoc)", " r3", " r4", " r5", " r6", " r7", " r8", " r9", "r10", " r0", " r1 (sp)", " r2 (rtoc)", " r3", " r4", " r5", " r6", " r7", " r8", " r9", "r10",
"r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", "r21", "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", "r21",
"r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"}; "r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
};


const char* GekkoDisassembler::GetGPRName(u32 index) const char* GekkoDisassembler::GetGPRName(u32 index)
{ {
if (index < 32) if (index < gpr_names.size())
return gprnames[index]; return gpr_names[index];


return nullptr; return nullptr;
} }


static const char* fprnames[] = {" f0", " f1", " f2", " f3", " f4", " f5", " f6", " f7", constexpr std::array<const char*, 32> fpr_names{
" f8", " f9", "f10", "f11", "f12", "f13", "f14", "f15", " f0", " f1", " f2", " f3", " f4", " f5", " f6", " f7", " f8", " f9", "f10",
"f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", "f11", "f12", "f13", "f14", "f15", "f16", "f17", "f18", "f19", "f20", "f21",
"f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31"}; "f22", "f23", "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
};


const char* GekkoDisassembler::GetFPRName(u32 index) const char* GekkoDisassembler::GetFPRName(u32 index)
{ {
if (index < 32) if (index < fpr_names.size())
return fprnames[index]; return fpr_names[index];


return nullptr; return nullptr;
} }
Expand Down
28 changes: 14 additions & 14 deletions Source/Core/Common/GekkoDisassembler.h
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -34,11 +34,10 @@


#pragma once #pragma once


#include <cstdint>
#include <string> #include <string>
#include <string_view>


#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
#include "Common/StringUtil.h"


namespace Common namespace Common
{ {
Expand All @@ -62,30 +61,31 @@ class GekkoDisassembler final


static void trapi(u32 in, unsigned char dmode); static void trapi(u32 in, unsigned char dmode);
static void cmpi(u32 in, int uimm); static void cmpi(u32 in, int uimm);
static void addi(u32 in, const std::string& ext); static void addi(u32 in, std::string_view ext);
static size_t branch(u32 in, const char* bname, int aform, int bdisp); static size_t branch(u32 in, std::string_view bname, int aform, int bdisp);
static void bc(u32 in); static void bc(u32 in);
static void bli(u32 in); static void bli(u32 in);
static void mcrf(u32 in, char c); static void mcrf(u32 in, char c);
static void crop(u32 in, const char* n1, const char* n2); static void crop(u32 in, std::string_view n1, std::string_view n2);
static void nooper(u32 in, const char* name, unsigned char dmode); static void nooper(u32 in, std::string_view name, unsigned char dmode);
static void rlw(u32 in, const char* name, int i); static void rlw(u32 in, std::string_view name, int i);
static void ori(u32 in, const char* name); static void ori(u32 in, std::string_view name);
static void rld(u32 in, const char* name, int i); static void rld(u32 in, std::string_view name, int i);
static void cmp(u32 in); static void cmp(u32 in);
static void trap(u32 in, unsigned char dmode); static void trap(u32 in, unsigned char dmode);
static void dab(u32 in, const char* name, int mask, int smode, int chkoe, int chkrc, static void dab(u32 in, std::string_view name, int mask, int smode, int chkoe, int chkrc,
unsigned char dmode);
static void rrn(u32 in, std::string_view name, int smode, int chkoe, int chkrc,
unsigned char dmode); unsigned char dmode);
static void rrn(u32 in, const char* name, int smode, int chkoe, int chkrc, unsigned char dmode);
static void mtcr(u32 in); static void mtcr(u32 in);
static void msr(u32 in, int smode); static void msr(u32 in, int smode);
static void mspr(u32 in, int smode); static void mspr(u32 in, int smode);
static void mtb(u32 in); static void mtb(u32 in);
static void sradi(u32 in); static void sradi(u32 in);
static void ldst(u32 in, const char* name, char reg, unsigned char dmode); static void ldst(u32 in, std::string_view name, char reg, unsigned char dmode);
static void fdabc(u32 in, const char* name, int mask, unsigned char dmode); static void fdabc(u32 in, std::string_view name, int mask, unsigned char dmode);
static void fmr(u32 in); static void fmr(u32 in);
static void fdab(u32 in, const char* name, int mask); static void fdab(u32 in, std::string_view name, int mask);
static void fcmp(u32 in, char c); static void fcmp(u32 in, char c);
static void mtfsb(u32 in, int n); static void mtfsb(u32 in, int n);
static void ps(u32 inst); static void ps(u32 inst);
Expand Down

0 comments on commit a88deda

Please sign in to comment.