Merging in odd commits

This commit is contained in:
Maxim Poliakovski 2020-01-22 12:28:42 +01:00 committed by dingusdev
parent b16427e810
commit 99559c1e0c
3 changed files with 236 additions and 287 deletions

View File

@ -7,7 +7,7 @@ using namespace std;
template< typename... Args >
std::string my_sprintf(const char* format, Args... args)
{
int length = std::snprintf( nullptr, 0, format, args... );
int length = std::snprintf(nullptr, 0, format, args...);
if (length <= 0)
return {}; /* empty string in C++11 */
@ -19,205 +19,124 @@ std::string my_sprintf(const char* format, Args... args)
return str;
}
const char *bx_mnem[4] = {
const char* arith_im_mnem[9] = {
"mulli", "subfic", "", "", "", "addic", "addic.", "addi", "addis"
};
const char* bx_mnem[4] = {
"b", "bl", "ba", "bla"
};
const char *br_cond[8] = { /* simplified branch conditions */
const char* br_cond[8] = { /* simplified branch conditions */
"ge", "le", "ne", "ns", "lt", "gt", "eq", "so"
};
const char *opc_idx_ldst[24] = { /* indexed load/store opcodes */
const char* opc_idx_ldst[24] = { /* indexed load/store opcodes */
"lwzx", "lwzux", "lbzx", "lbzux", "stwx", "stwux", "stbx", "stbux", "lhzx",
"lhzux", "lhax", "lhaux", "sthx", "sthux", "", "", "lfsx", "lfsux", "lfdx",
"lfdux", "stfsx", "stfsux", "stfdx", "stfdux"
};
const char *opc_logic[16] = { /* indexed load/store opcodes */
const char* opc_logic[16] = { /* indexed load/store opcodes */
"and", "andc", "", "nor", "", "", "", "", "eqv", "xor", "", "", "orc", "or",
"nand", ""
};
const char *opc_subs[16] = { /* subtracts & friends */
const char* opc_subs[16] = { /* subtracts & friends */
"subfc", "subf", "", "neg", "subfe", "", "subfze", "subfme", "doz", "", "",
"abs", "", "", "", "nabs"
};
const char *opc_adds[9] = { /* additions */
const char* opc_adds[9] = { /* additions */
"addc", "", "", "", "adde", "", "addze", "addme", "add"
};
const char *opc_muldivs[16] = { /* multiply and division instructions */
const char* opc_muldivs[16] = { /* multiply and division instructions */
"mulhwu", "", "mulhw", "mul", "", "", "", "mullw", "", "", "div", "divs",
"", "", "divwu", "divw"
};
const char* opc_int_ldst[16] = { /* integer load and store instructions */
"lwz", "lwzu", "lbz", "lbzu", "stw", "stwu", "stb", "stbu", "lhz", "lhzu",
"lha", "lhau", "sth", "sthu", "lmw", "stmw"
};
/** various formatting helpers. */
void fmt_oneop(string& buf, const char* opc, int src)
{
buf = my_sprintf("%-8sr%d", opc, src);
}
void fmt_twoop(string& buf, const char *opc, int dst, int src)
void fmt_twoop(string& buf, const char* opc, int dst, int src)
{
buf = my_sprintf("%-8sr%d, r%d", opc, dst, src);
}
void fmt_twoop_imm(string& buf, const char *opc, int dst, int imm)
void fmt_twoop_simm(string& buf, const char* opc, int dst, int imm)
{
buf = my_sprintf("%-8sr%d, 0x%04X", opc, dst, imm);
buf = my_sprintf("%-8sr%d, %s0x%X", opc, dst, (imm < 0) ? "-" : "", abs(imm));
}
void fmt_twoop_spr(string& buf, const char* opc, int dst, int src)
{
buf = my_sprintf("%-8sr%d, spr%d", opc, dst, src);
}
void fmt_threeop(string& buf, const char *opc, int dst, int src1, int src2)
void fmt_threeop(string& buf, const char* opc, int dst, int src1, int src2)
{
buf = my_sprintf("%-8sr%d, r%d, r%d", opc, dst, src1, src2);
}
void fmt_threeop_imm(string& buf, const char* opc, int dst, int src1, int imm)
void fmt_threeop_uimm(string& buf, const char* opc, int dst, int src1, int imm)
{
buf = my_sprintf("%-8sr%d, r%d, 0x%04X", opc, dst, src1, imm);
}
void fmt_fourop(string& buf, const char* opc, int dst, int src1, int src2, int src3)
void fmt_threeop_simm(string& buf, const char* opc, int dst, int src1, int imm)
{
buf = my_sprintf("%-8sr%d, r%d, r%d, r%d", opc, dst, src1, src2, src3);
buf = my_sprintf("%-8sr%d, r%d, %s0x%X", opc, dst, src1,
(imm < 0) ? "-" : "", abs(imm));
}
void opc_illegal(PPCDisasmContext *ctx)
void opc_illegal(PPCDisasmContext* ctx)
{
ctx->instr_str = my_sprintf("%-8s0x%08X", "dc.l", ctx->instr_code);
}
void opc_twi(PPCDisasmContext *ctx)
void opc_twi(PPCDisasmContext* ctx)
{
//return "DEADBEEF";
}
void opc_group4(PPCDisasmContext *ctx)
void opc_group4(PPCDisasmContext* ctx)
{
printf("Altivec group 4 not supported yet\n");
}
void opc_mulli(PPCDisasmContext *ctx)
void opc_ar_im(PPCDisasmContext* ctx)
{
auto ra = (ctx->instr_code >> 16) & 0x1F;
auto rd = (ctx->instr_code >> 21) & 0x1F;
auto imm = ctx->instr_code & 0xFFFF;
int32_t imm = SIGNEXT(ctx->instr_code & 0xFFFF, 15);
fmt_threeop_imm(ctx->instr_str, "mulli", rd, ra, imm);
}
void opc_subfic(PPCDisasmContext *ctx)
{
auto ra = (ctx->instr_code >> 16) & 0x1F;
auto rd = (ctx->instr_code >> 21) & 0x1F;
auto imm = ctx->instr_code & 0xFFFF;
fmt_threeop_imm(ctx->instr_str, "subfic", rd, ra, imm);
}
void power_dozi(PPCDisasmContext *ctx)
{
auto ra = (ctx->instr_code >> 16) & 0x1F;
auto rd = (ctx->instr_code >> 21) & 0x1F;
auto imm = ctx->instr_code & 0xFFFF;
fmt_threeop_imm(ctx->instr_str, "dozi", rd, ra, imm);
}
void opc_cmpli(PPCDisasmContext *ctx)
{
auto ra = (ctx->instr_code >> 16) & 0x1F;
auto crfd = (ctx->instr_code >> 23) & 0x07;
auto imm = ctx->instr_code & 0xFFFF;
if (ctx->instr_code & 0x200000) {
opc_illegal(ctx);
if ((ctx->instr_code >> 26) == 0xE && !ra && ctx->simplified) {
fmt_twoop_simm(ctx->instr_str, "li", rd, imm);
}
else {
fmt_threeop_imm(ctx->instr_str, "cmpli", crfd, ra, imm);
fmt_threeop_simm(ctx->instr_str, arith_im_mnem[(ctx->instr_code >> 26) - 7],
rd, ra, imm);
}
}
void opc_cmpi(PPCDisasmContext *ctx)
void power_dozi(PPCDisasmContext* ctx)
{
auto crfd = (ctx->instr_code >> 23) & 0x07;
auto ra = (ctx->instr_code >> 16) & 0x1F;
auto imm = ctx->instr_code & 0xFFFF;
if (ctx->instr_code & 0x200000) {
opc_illegal(ctx);
}
else {
fmt_threeop_imm(ctx->instr_str, "cmpi", crfd, ra, imm);
}
//return "DEADBEEF";
}
void opc_addic(PPCDisasmContext *ctx)
void opc_cmpli(PPCDisasmContext* ctx)
{
auto ra = (ctx->instr_code >> 16) & 0x1F;
auto rd = (ctx->instr_code >> 21) & 0x1F;
auto imm = ctx->instr_code & 0xFFFF;
fmt_threeop_imm(ctx->instr_str, "addic", rd, ra, imm);
//return "DEADBEEF";
}
void opc_addicdot(PPCDisasmContext *ctx)
void opc_cmpi(PPCDisasmContext* ctx)
{
auto ra = (ctx->instr_code >> 16) & 0x1F;
auto rd = (ctx->instr_code >> 21) & 0x1F;
auto imm = ctx->instr_code & 0xFFFF;
fmt_threeop_imm(ctx->instr_str, "addic.", rd, ra, imm);
//return "DEADBEEF";
}
void opc_addi(PPCDisasmContext *ctx)
void generic_bcx(PPCDisasmContext* ctx, uint32_t bo, uint32_t bi, uint32_t dst)
{
auto ra = (ctx->instr_code >> 16) & 0x1F;
auto rd = (ctx->instr_code >> 21) & 0x1F;
auto imm = ctx->instr_code & 0xFFFF;
if (ra == 0 && ctx->simplified)
fmt_twoop_imm(ctx->instr_str, "li", rd, imm);
else
fmt_threeop_imm(ctx->instr_str, "addi", rd, ra, imm);
}
void opc_addis(PPCDisasmContext* ctx)
{
auto ra = (ctx->instr_code >> 16) & 0x1F;
auto rd = (ctx->instr_code >> 21) & 0x1F;
auto imm = ctx->instr_code & 0xFFFF;
if (ra == 0 && ctx->simplified)
fmt_twoop_imm(ctx->instr_str, "lis", rd, imm);
else
fmt_threeop_imm(ctx->instr_str, "addis", rd, ra, imm);
}
void opc_lwz(PPCDisasmContext* ctx)
{
auto ra = (ctx->instr_code >> 16) & 0x1F;
auto rd = (ctx->instr_code >> 21) & 0x1F;
auto offset = ctx->instr_code & 0xFFFF;
if (ra == 0) {
fmt_twoop_imm(ctx->instr_str, "lzw", rd, offset);
}
else {
fmt_threeop_imm(ctx->instr_str, "lzw", rd, ra, offset);
}
}
void generic_bcx(PPCDisasmContext *ctx, uint32_t bo, uint32_t bi, uint32_t dst)
{
char opcode[10] = "bc";
char opcode[10] = "bc";
if (ctx->instr_code & 1) {
strcat(opcode, "l"); /* add suffix "l" if the LK bit is set */
@ -228,17 +147,17 @@ void generic_bcx(PPCDisasmContext *ctx, uint32_t bo, uint32_t bi, uint32_t dst)
ctx->instr_str = my_sprintf("%-8s%d, %d, 0x%08X", opcode, bo, bi, dst);
}
void opc_bcx(PPCDisasmContext *ctx)
void opc_bcx(PPCDisasmContext* ctx)
{
uint32_t bo, bi, dst, cr;
char opcode[10] = "b";
char opcode[10] = "b";
char operands[10] = "";
bo = (ctx->instr_code >> 21) & 0x1F;
bi = (ctx->instr_code >> 16) & 0x1F;
cr = bi >> 2;
bo = (ctx->instr_code >> 21) & 0x1F;
bi = (ctx->instr_code >> 16) & 0x1F;
cr = bi >> 2;
dst = ((ctx->instr_code & 2) ? 0 : ctx->instr_addr) +
SIGNEXT(ctx->instr_code & 0xFFFC, 15);
SIGNEXT(ctx->instr_code & 0xFFFC, 15);
if (!ctx->simplified || ((bo & 0x10) && bi) ||
(((bo & 0x14) == 0x14) && (bo & 0xB) && bi)) {
@ -261,11 +180,13 @@ void opc_bcx(PPCDisasmContext *ctx)
operands[4] = cr + '0';
}
strcat(operands, br_cond[4 + (bi & 3)]);
strcat(operands, ", ");
}
} else { /* CTR ignored */
}
else { /* CTR ignored */
strcat(opcode, br_cond[((bo >> 1) & 4) | (bi & 3)]);
if (cr) {
strcat(operands, "cr0");
strcat(operands, "cr0, ");
operands[2] = cr + '0';
}
}
@ -280,21 +201,21 @@ void opc_bcx(PPCDisasmContext *ctx)
strcat(opcode, (ctx->instr_code & 0x8000) ? "-" : "+");
}
ctx->instr_str = my_sprintf("%-8s%s, 0x%08X", opcode, operands, dst);
ctx->instr_str = my_sprintf("%-8s%s0x%08X", opcode, operands, dst);
}
void opc_bx(PPCDisasmContext *ctx)
void opc_bx(PPCDisasmContext* ctx)
{
uint32_t dst = ((ctx->instr_code & 2) ? 0 : ctx->instr_addr)
+ SIGNEXT(ctx->instr_code & 0x3FFFFFC, 25);
+ SIGNEXT(ctx->instr_code & 0x3FFFFFC, 25);
ctx->instr_str = my_sprintf("%-8s0x%08X", bx_mnem[ctx->instr_code & 3], dst);
}
void opc_ori(PPCDisasmContext *ctx)
void opc_ori(PPCDisasmContext* ctx)
{
auto ra = (ctx->instr_code >> 16) & 0x1F;
auto rs = (ctx->instr_code >> 21) & 0x1F;
auto ra = (ctx->instr_code >> 16) & 0x1F;
auto rs = (ctx->instr_code >> 21) & 0x1F;
auto imm = ctx->instr_code & 0xFFFF;
if (!ra && !rs && !imm && ctx->simplified) {
@ -305,19 +226,10 @@ void opc_ori(PPCDisasmContext *ctx)
fmt_twoop(ctx->instr_str, "mr", ra, rs);
return;
}
fmt_threeop_imm(ctx->instr_str, "ori", ra, rs, imm);
fmt_threeop_uimm(ctx->instr_str, "ori", ra, rs, imm);
}
void opc_oris(PPCDisasmContext* ctx)
{
auto ra = (ctx->instr_code >> 16) & 0x1F;
auto rs = (ctx->instr_code >> 21) & 0x1F;
auto imm = ctx->instr_code & 0xFFFF;
fmt_threeop_imm(ctx->instr_str, "oris", ra, rs, imm);
}
void opc_group31(PPCDisasmContext *ctx)
void opc_group31(PPCDisasmContext* ctx)
{
char opcode[10] = "";
@ -326,145 +238,163 @@ void opc_group31(PPCDisasmContext *ctx)
auto rs = (ctx->instr_code >> 21) & 0x1F;
int ext_opc = (ctx->instr_code >> 1) & 0x3FF; /* extract extended opcode */
int index = ext_opc >> 5;
bool rc_set = ctx->instr_code & 1;
int index = ext_opc >> 5;
bool rc_set = ctx->instr_code & 1;
switch(ext_opc & 0x1F) {
case 8: /* subtracts & friends */
index &= 0xF; /* strip OE bit */
if (!strlen(opc_subs[index])) {
opc_illegal(ctx);
} else {
strcpy(opcode, opc_subs[index]);
if (ext_opc & 0x200) /* check OE bit */
strcat(opcode, "o");
if (rc_set)
strcat(opcode, ".");
if (index == 3 || index == 6 || index == 7 || index == 11 ||
index == 15) { /* ugly check for two-operands instructions */
if (rb != 0)
opc_illegal(ctx);
else
fmt_twoop(ctx->instr_str, opcode, rs, ra);
} else
fmt_threeop(ctx->instr_str, opcode, rs, ra, rb);
}
return;
case 10: /* additions */
index &= 0xF; /* strip OE bit */
if (index > 8 || !strlen(opc_adds[index])) {
opc_illegal(ctx);
} else {
strcpy(opcode, opc_adds[index]);
if (ext_opc & 0x200) /* check OE bit */
strcat(opcode, "o");
if (rc_set)
strcat(opcode, ".");
if (index == 6 || index == 7) {
if (rb != 0)
opc_illegal(ctx);
else
fmt_twoop(ctx->instr_str, opcode, rs, ra);
} else
fmt_threeop(ctx->instr_str, opcode, rs, ra, rb);
}
return;
case 11: /* integer multiplications and divisions */
index &= 0xF; /* strip OE bit */
if (!strlen(opc_muldivs[index])) {
opc_illegal(ctx);
} else {
strcpy(opcode, opc_muldivs[index]);
if (ext_opc & 0x200) /* check OE bit */
strcat(opcode, "o");
if (rc_set)
strcat(opcode, ".");
if ((!index || index == 2) && (ext_opc & 0x200))
switch (ext_opc & 0x1F) {
case 8: /* subtracts & friends */
index &= 0xF; /* strip OE bit */
if (!strlen(opc_subs[index])) {
opc_illegal(ctx);
}
else {
strcpy(opcode, opc_subs[index]);
if (ext_opc & 0x200) /* check OE bit */
strcat(opcode, "o");
if (rc_set)
strcat(opcode, ".");
if (index == 3 || index == 6 || index == 7 || index == 11 ||
index == 15) { /* ugly check for two-operands instructions */
if (rb != 0)
opc_illegal(ctx);
else
fmt_threeop(ctx->instr_str, opcode, rs, ra, rb);
fmt_twoop(ctx->instr_str, opcode, rs, ra);
}
return;
case 0x1C: /* logical instructions */
if (index == 13 && rs == rb && ctx->simplified) {
fmt_twoop(ctx->instr_str, rc_set ? "mr." : "mr", ra, rs);
} else {
strcpy(opcode, opc_logic[index]);
if (!strlen(opcode)) {
opc_illegal(ctx);
} else {
if (rc_set)
strcat(opcode, ".");
fmt_threeop(ctx->instr_str, opcode, ra, rs, rb);
}
}
return;
case 0x17: /* indexed load/store instructions */
if (index > 23 || rc_set || strlen(opc_idx_ldst[index]) == 0) {
opc_illegal(ctx);
return;
}
if (index < 16)
fmt_threeop(ctx->instr_str, opc_idx_ldst[index], rs, ra, rb);
else
ctx->instr_str = my_sprintf("%-8sfp%d, r%d, r%d",
opc_idx_ldst[index], rs, ra, rb);
fmt_threeop(ctx->instr_str, opcode, rs, ra, rb);
}
return;
case 10: /* additions */
index &= 0xF; /* strip OE bit */
if (index > 8 || !strlen(opc_adds[index])) {
opc_illegal(ctx);
}
else {
strcpy(opcode, opc_adds[index]);
if (ext_opc & 0x200) /* check OE bit */
strcat(opcode, "o");
if (rc_set)
strcat(opcode, ".");
if (index == 6 || index == 7) {
if (rb != 0)
opc_illegal(ctx);
else
fmt_twoop(ctx->instr_str, opcode, rs, ra);
}
else
fmt_threeop(ctx->instr_str, opcode, rs, ra, rb);
}
return;
case 11: /* integer multiplications and divisions */
index &= 0xF; /* strip OE bit */
if (!strlen(opc_muldivs[index])) {
opc_illegal(ctx);
}
else {
strcpy(opcode, opc_muldivs[index]);
if (ext_opc & 0x200) /* check OE bit */
strcat(opcode, "o");
if (rc_set)
strcat(opcode, ".");
if ((!index || index == 2) && (ext_opc & 0x200))
opc_illegal(ctx);
else
fmt_threeop(ctx->instr_str, opcode, rs, ra, rb);
}
return;
case 0x1C: /* logical instructions */
if (index == 13 && rs == rb && ctx->simplified) {
fmt_twoop(ctx->instr_str, rc_set ? "mr." : "mr", ra, rs);
}
else {
strcpy(opcode, opc_logic[index]);
if (!strlen(opcode)) {
opc_illegal(ctx);
}
else {
if (rc_set)
strcat(opcode, ".");
fmt_threeop(ctx->instr_str, opcode, ra, rs, rb);
}
}
return;
case 0x17: /* indexed load/store instructions */
if (index > 23 || rc_set || strlen(opc_idx_ldst[index]) == 0) {
opc_illegal(ctx);
return;
}
if (index < 16)
fmt_threeop(ctx->instr_str, opc_idx_ldst[index], rs, ra, rb);
else
ctx->instr_str = my_sprintf("%-8sfp%d, r%d, r%d",
opc_idx_ldst[index], rs, ra, rb);
return;
break;
}
auto ref_spr = (((ctx->instr_code >> 11) & 31) << 5) | ((ctx->instr_code >> 16) & 31);
switch(ext_opc) {
case 4:
if (rc_set)
opc_illegal(ctx);
else
ctx->instr_str = my_sprintf("%-8s%d, r%d, r%d", "tw", rs, ra, rb);
break;
case 19: /* mfcr */
fmt_oneop(ctx->instr_str, "mfcr", rs);
break;
case 144: /* mtcrf */
if (ctx->instr_code & 0x100801)
opc_illegal(ctx);
else {
ctx->instr_str = my_sprintf("%-8s0x%02X, r%d", "mtcrf",
(ctx->instr_code >> 12) & 0xFF, rs);
}
break;
case 146: /* mtmsr */
fmt_oneop(ctx->instr_str, "mtmsr", rs);
break;
case 339: /* mfspr */
fmt_twoop_spr(ctx->instr_str, "mfspr", rs, ref_spr);
break;
case 467: /* mtspr */
fmt_twoop_spr(ctx->instr_str, "mtspr", ref_spr, rs);
break;
default:
switch (ext_opc) {
case 4:
if (rc_set)
opc_illegal(ctx);
else
ctx->instr_str = my_sprintf("%-8s%d, r%d, r%d", "tw", rs, ra, rb);
break;
case 144: /* mtcrf */
if (ctx->instr_code & 0x100801)
opc_illegal(ctx);
else {
ctx->instr_str = my_sprintf("%-8s0x%02X, r%d", "mtcrf",
(ctx->instr_code >> 12) & 0xFF, rs);
}
break;
default:
opc_illegal(ctx);
}
}
void opc_intldst(PPCDisasmContext* ctx)
{
int32_t opcode = (ctx->instr_code >> 26) - 32;
int32_t ra = (ctx->instr_code >> 16) & 0x1F;
int32_t rd = (ctx->instr_code >> 21) & 0x1F;
int32_t imm = SIGNEXT(ctx->instr_code & 0xFFFF, 15);
/* ra = 0 is forbidden for loads and stores with update */
/* ra = rd is forbidden for loads with update */
if (((opcode < 14) && (opcode & 5) == 1 && ra == rd) || ((opcode & 1) && !ra))
{
opc_illegal(ctx);
return;
}
if (ra) {
ctx->instr_str = my_sprintf("%-8sr%d, %s0x%X(r%d)", opc_int_ldst[opcode],
rd, ((imm < 0) ? "-" : ""), abs(imm), ra);
}
else {
ctx->instr_str = my_sprintf("%-8sr%d, %s0x%X", opc_int_ldst[opcode],
rd, ((imm < 0) ? "-" : ""), abs(imm));
}
}
/** main dispatch table. */
static std::function<void(PPCDisasmContext*)> OpcodeDispatchTable[64] = {
opc_illegal, opc_illegal, opc_illegal, opc_twi,
opc_group4, opc_illegal, opc_illegal, opc_mulli,
opc_subfic, power_dozi, opc_cmpli, opc_cmpi,
opc_addic, opc_addicdot, opc_addi, opc_addis,
opc_group4, opc_illegal, opc_illegal, opc_ar_im,
opc_ar_im, power_dozi, opc_cmpli, opc_cmpi,
opc_ar_im, opc_ar_im, opc_ar_im, opc_ar_im,
opc_bcx, opc_illegal, opc_bx, opc_illegal,
opc_illegal, opc_illegal, opc_illegal, opc_illegal,
opc_ori, opc_oris, opc_illegal, opc_illegal,
opc_ori, opc_illegal, opc_illegal, opc_illegal,
opc_illegal, opc_illegal, opc_illegal, opc_group31,
opc_lwz, opc_illegal, opc_illegal, opc_illegal,
opc_illegal, opc_illegal, opc_illegal, opc_illegal,
opc_illegal, opc_illegal, opc_illegal, opc_illegal,
opc_illegal, opc_illegal, opc_illegal, opc_illegal,
opc_intldst, opc_intldst, opc_intldst, opc_intldst,
opc_intldst, opc_intldst, opc_intldst, opc_intldst,
opc_intldst, opc_intldst, opc_intldst, opc_intldst,
opc_intldst, opc_intldst, opc_intldst, opc_intldst,
opc_illegal, opc_illegal, opc_illegal, opc_illegal,
opc_illegal, opc_illegal, opc_illegal, opc_illegal,
opc_illegal, opc_illegal, opc_illegal, opc_illegal,
@ -491,11 +421,11 @@ static std::function<void(PPCDisasmContext*)> OpcodeDispatchTable[64] = {
*/
};
string disassemble_single(PPCDisasmContext *ctx)
string disassemble_single(PPCDisasmContext* ctx)
{
OpcodeDispatchTable[ctx->instr_code >> 26](ctx);
ctx->instr_addr += 4;
return ctx->instr_str;
}
}

View File

@ -5,7 +5,7 @@
#include <string>
typedef struct PPCDisasmContext {
uint32_t instr_addr = 0;
uint32_t instr_addr;
uint32_t instr_code;
std::string instr_str;
bool simplified; /* true if we should output simplified mnemonics */

View File

@ -25,6 +25,7 @@ void show_help()
cout << " until X -- execute until address X is reached" << endl;
cout << " regs -- dump content of the GRPs" << endl;
cout << " set R=X -- assign value X to register R" << endl;
cout << " memdump -- dump content of the system memory to memdump.bin" << endl;
#ifdef PROFILER
cout << " profiler -- show stats related to the processor" << endl;
#endif
@ -38,12 +39,20 @@ void dump_regs()
for (uint32_t i = 0; i < 32; i++)
cout << "GPR " << dec << i << " : " << hex << ppc_state.ppc_gpr[i] << endl;
cout << "PC: " << hex << ppc_state.ppc_pc << endl;
cout << "LR: " << hex << ppc_state.ppc_spr[SPR::LR] << endl;
cout << "CR: " << hex << ppc_state.ppc_cr << endl;
cout << "CTR: " << hex << ppc_state.ppc_spr[SPR::CTR] << endl;
cout << "XER: " << hex << ppc_state.ppc_spr[SPR::XER] << endl;
cout << "MSR: " << hex << ppc_state.ppc_msr << endl;
cout << "PC: " << hex << ppc_state.ppc_pc << endl;
cout << "LR: " << hex << ppc_state.ppc_spr[8] << endl;
cout << "CR: " << hex << ppc_state.ppc_cr << endl;
cout << "CTR: " << hex << ppc_state.ppc_spr[9] << endl;
cout << "XER: " << hex << ppc_state.ppc_spr[1] << endl;
cout << "MSR: " << hex << ppc_state.ppc_msr << endl;
}
void dump_mem_file()
{
std::ofstream memdumpfile;
memdumpfile.open("memdump.bin", std::ofstream::out | std::ofstream::binary);
memdumpfile.write((char*)&machine_sysram_mem, sizeof(char) * 67108864);
memdumpfile.close();
}
void disasm()
@ -85,9 +94,13 @@ void enter_debugger()
}
if (cmd == "help") {
show_help();
} else if (cmd == "quit") {
}
else if (cmd == "quit") {
break;
}
else if (cmd == "memdump") {
dump_mem_file();
}
#ifdef PROFILER
else if (cmd == "profiler") {
cout << "Number of Supervisor Instructions Executed:" << supervisor_inst_num << endl;
@ -97,28 +110,34 @@ void enter_debugger()
#endif
else if (cmd == "regs") {
dump_regs();
} else if (cmd == "set") {
}
else if (cmd == "set") {
ss >> expr_str;
reg_expr = expr_str.substr(0, expr_str.find("="));
if (reg_expr == "pc") {
addr_str = expr_str.substr(expr_str.find("=") + 1);
addr = stoul(addr_str, NULL, 0);
addr = stol(addr_str, NULL, 0);
ppc_state.ppc_pc = addr;
} else {
}
else {
cout << "Unknown register " << reg_expr << endl;
}
} else if (cmd == "step") {
}
else if (cmd == "step") {
ppc_exec_single();
} else if (cmd == "until") {
}
else if (cmd == "until") {
ss >> addr_str;
addr = stoul(addr_str, NULL, 16);
addr = stol(addr_str, NULL, 16);
ppc_exec_until(addr);
} else if (cmd == "disas") {
}
else if (cmd == "disas") {
disasm();
} else {
}
else {
cout << "Unknown command: " << cmd << endl;
continue;
}
last_cmd = cmd;
}
}
}