mirror of
https://github.com/dingusdev/dingusppc.git
synced 2024-12-24 12:30:05 +00:00
ppcdisasm: fix bcctr and bclr instructions.
This commit is contained in:
parent
4ecc48a6cc
commit
1543acc696
@ -36,11 +36,11 @@ const char* bx_mnem[4] = {
|
||||
};
|
||||
|
||||
const char* bclrx_mnem[2] = {
|
||||
"bclr", "bclrl"
|
||||
"blr", "blrl"
|
||||
};
|
||||
|
||||
const char* bcctrx_mnem[2] = {
|
||||
"bcctr", "bcctrl"
|
||||
"bctr", "bctrl"
|
||||
};
|
||||
|
||||
const char* br_cond[8] = { /* simplified branch conditions */
|
||||
@ -376,7 +376,7 @@ void opc_bool_im(PPCDisasmContext* ctx)
|
||||
if (ctx->simplified) {
|
||||
if (index == 0) {
|
||||
if (imm == 0 && !ra && !rs && !imm) { /* unofficial, produced by IDA */
|
||||
ctx->instr_str = "nop";
|
||||
ctx->instr_str = my_sprintf("%-8s", "nop");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -482,12 +482,16 @@ void opc_bcctrx(PPCDisasmContext* ctx)
|
||||
{
|
||||
uint32_t bo, bi, cr;
|
||||
char opcode[10] = "b";
|
||||
char operands[10] = "";
|
||||
char operands[4] = "";
|
||||
|
||||
bo = (ctx->instr_code >> 21) & 0x1F;
|
||||
bi = (ctx->instr_code >> 16) & 0x1F;
|
||||
cr = bi >> 2;
|
||||
|
||||
if (!(bo & 4)) { /* bcctr with BO[2] = 0 is invalid */
|
||||
opc_illegal(ctx);
|
||||
}
|
||||
|
||||
if (!ctx->simplified || ((bo & 0x10) && bi) ||
|
||||
(((bo & 0x14) == 0x14) && (bo & 0xB) && bi)) {
|
||||
generic_bcctrx(ctx, bo, bi);
|
||||
@ -495,7 +499,45 @@ void opc_bcctrx(PPCDisasmContext* ctx)
|
||||
}
|
||||
|
||||
if ((bo & 0x14) == 0x14) {
|
||||
ctx->instr_str = my_sprintf("%-8s0x%08X", bcctrx_mnem[0]);
|
||||
ctx->instr_str = my_sprintf("%-8s", bcctrx_mnem[ctx->instr_code & 1]);
|
||||
return;
|
||||
}
|
||||
|
||||
strcat(opcode, br_cond[((bo >> 1) & 4) | (bi & 3)]);
|
||||
strcat(opcode, "ctr");
|
||||
if (cr) {
|
||||
strcat(operands, "cr0");
|
||||
operands[2] = cr + '0';
|
||||
}
|
||||
|
||||
if (ctx->instr_code & 1) {
|
||||
strcat(opcode, "l"); /* add suffix "l" if the LK bit is set */
|
||||
}
|
||||
if (bo & 1) { /* incorporate prediction bit if set */
|
||||
strcat(opcode, "+");
|
||||
}
|
||||
|
||||
ctx->instr_str = my_sprintf("%-8s%s", opcode, operands);
|
||||
}
|
||||
|
||||
void opc_bclrx(PPCDisasmContext* ctx)
|
||||
{
|
||||
uint32_t bo, bi, cr;
|
||||
char opcode[10] = "b";
|
||||
char operands[12] = "";
|
||||
|
||||
bo = (ctx->instr_code >> 21) & 0x1F;
|
||||
bi = (ctx->instr_code >> 16) & 0x1F;
|
||||
cr = bi >> 2;
|
||||
|
||||
if (!ctx->simplified || ((bo & 0x10) && bi) ||
|
||||
(((bo & 0x14) == 0x14) && (bo & 0xB) && bi)) {
|
||||
generic_bclrx(ctx, bo, bi);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((bo & 0x14) == 0x14) {
|
||||
ctx->instr_str = my_sprintf("%-8s", bclrx_mnem[ctx->instr_code & 1]);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -509,77 +551,26 @@ void opc_bcctrx(PPCDisasmContext* ctx)
|
||||
operands[4] = cr + '0';
|
||||
}
|
||||
strcat(operands, br_cond[4 + (bi & 3)]);
|
||||
strcat(operands, ", ");
|
||||
}
|
||||
}
|
||||
else { /* CTR ignored */
|
||||
strcat(opcode, br_cond[((bo >> 1) & 4) | (bi & 3)]);
|
||||
if (cr) {
|
||||
strcat(operands, "cr0, ");
|
||||
strcat(operands, "cr0");
|
||||
operands[2] = cr + '0';
|
||||
}
|
||||
}
|
||||
|
||||
strcat(opcode, "lr");
|
||||
|
||||
if (ctx->instr_code & 1) {
|
||||
strcat(opcode, "l"); /* add suffix "l" if the LK bit is set */
|
||||
}
|
||||
if (bo & 1) { /* incorporate prediction bit if set */
|
||||
strcat(opcode, (ctx->instr_code & 0x8000) ? "-" : "+");
|
||||
strcat(opcode, "+");
|
||||
}
|
||||
|
||||
ctx->instr_str = my_sprintf("%-8s%s0x%08X", opcode, operands);
|
||||
}
|
||||
|
||||
void opc_bclrx(PPCDisasmContext* ctx)
|
||||
{
|
||||
uint32_t bo, bi, cr;
|
||||
char opcode[10] = "b";
|
||||
char operands[10] = "";
|
||||
|
||||
bo = (ctx->instr_code >> 21) & 0x1F;
|
||||
bi = (ctx->instr_code >> 16) & 0x1F;
|
||||
cr = bi >> 2;
|
||||
|
||||
if (!ctx->simplified || ((bo & 0x10) && bi) ||
|
||||
(((bo & 0x14) == 0x14) && (bo & 0xB) && bi)) {
|
||||
generic_bclrx(ctx, bo, bi);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((bo & 0x14) == 0x14) {
|
||||
ctx->instr_str = my_sprintf("%-8s0x%08X", bclrx_mnem[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(bo & 4)) {
|
||||
strcat(opcode, "d");
|
||||
strcat(opcode, (bo & 2) ? "z" : "nz");
|
||||
if (!(bo & 0x10)) {
|
||||
strcat(opcode, (bo & 8) ? "tlr" : "flr");
|
||||
if (cr) {
|
||||
strcat(operands, "4*cr0+");
|
||||
operands[4] = cr + '0';
|
||||
}
|
||||
strcat(operands, br_cond[4 + (bi & 3)]);
|
||||
strcat(operands, ", ");
|
||||
}
|
||||
}
|
||||
else { /* CTR ignored */
|
||||
strcat(opcode, br_cond[((bo >> 1) & 4) | (bi & 3)]);
|
||||
if (cr) {
|
||||
strcat(operands, "cr0, ");
|
||||
operands[2] = cr + '0';
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx->instr_code & 1) {
|
||||
strcat(opcode, "l"); /* add suffix "l" if the LK bit is set */
|
||||
}
|
||||
if (bo & 1) { /* incorporate prediction bit if set */
|
||||
strcat(opcode, (ctx->instr_code & 0x8000) ? "-" : "+");
|
||||
}
|
||||
|
||||
ctx->instr_str = my_sprintf("%-8s%s0x%08X", opcode, operands);
|
||||
ctx->instr_str = my_sprintf("%-8s%s", opcode, operands);
|
||||
}
|
||||
|
||||
void opc_bx(PPCDisasmContext* ctx)
|
||||
@ -597,7 +588,7 @@ void opc_ori(PPCDisasmContext* ctx)
|
||||
auto imm = ctx->instr_code & 0xFFFF;
|
||||
|
||||
if (!ra && !rs && !imm && ctx->simplified) {
|
||||
ctx->instr_str = "nop";
|
||||
ctx->instr_str = my_sprintf("%-8s", "nop");
|
||||
return;
|
||||
}
|
||||
if (imm == 0 && ctx->simplified) { /* inofficial, produced by IDA */
|
||||
|
@ -7,6 +7,50 @@
|
||||
0xFFF03008,0x48000355,bl,0xFFF0335C
|
||||
0xFFF03000,0x4280035C,b,0xFFF0335C
|
||||
|
||||
# bcctr variants with simplified mnemonics
|
||||
0xFFF03000,0x4E800420,bctr
|
||||
0xFFF03000,0x4E800421,bctrl
|
||||
0xFFF03000,0x4C820420,bnectr
|
||||
0xFFF03000,0x4C820421,bnectrl
|
||||
0xFFF03000,0x4C960420,bnectr,cr5
|
||||
0xFFF03000,0x4C920421,bnectrl,cr4
|
||||
0xFFF03000,0x4D980420,bltctr,cr6
|
||||
0xFFF03000,0x4C9D0420,blectr,cr7
|
||||
0xFFF03000,0x4D820420,beqctr
|
||||
0xFFF03000,0x4D960420,beqctr,cr5
|
||||
0xFFF03000,0x4CA80420,bgectr+,cr2
|
||||
0xFFF03000,0x4C980421,bgectrl,cr6
|
||||
0xFFF03000,0x4D810420,bgtctr
|
||||
0xFFF03000,0x4D850420,bgtctr,cr1
|
||||
0xFFF03000,0x4D8B0421,bsoctrl,cr2
|
||||
0xFFF03000,0x4C830420,bnsctr
|
||||
0xFFF03000,0x4C930420,bnsctr,cr4
|
||||
|
||||
# bclr variants with simplified mnemonics
|
||||
0xFFF03000,0x4E800020,blr
|
||||
0xFFF03000,0x4E800021,blrl
|
||||
0xFFF03000,0x4D800020,bltlr
|
||||
0xFFF03000,0x4D840020,bltlr,cr1
|
||||
0xFFF03000,0x4C810021,blelrl
|
||||
0xFFF03000,0x4C8D0020,blelr,cr3
|
||||
0xFFF03000,0x4DA20020,beqlr+
|
||||
0xFFF03000,0x4DBE0021,beqlrl+,cr7
|
||||
0xFFF03000,0x4CA80020,bgelr+,cr2
|
||||
0xFFF03000,0x4DB90020,bgtlr+,cr6
|
||||
0xFFF03000,0x4C8A0021,bnelrl,cr2
|
||||
0xFFF03000,0x4D930020,bsolr,cr4
|
||||
0xFFF03000,0x4C8F0021,bnslrl,cr3
|
||||
0xFFF03000,0x4E000020,bdnzlr
|
||||
0xFFF03000,0x4E200020,bdnzlr+
|
||||
0xFFF03000,0x4E400020,bdzlr
|
||||
0xFFF03000,0x4E400021,bdzlrl
|
||||
0xFFF03000,0x4E600020,bdzlr+
|
||||
0xFFF03000,0x4C000020,bdnzflr,lt
|
||||
0xFFF03000,0x4C040020,bdnzflr,4*cr1+lt
|
||||
0xFFF03000,0x4C5D0021,bdzflrl,4*cr7+gt
|
||||
0xFFF03000,0x4D020020,bdnztlr,eq
|
||||
0xFFF03000,0x4D530021,bdztlrl,4*cr4+so
|
||||
|
||||
# conditional branches with simplified mnemonics, primary opcode 0x10
|
||||
0xFFF0011C,0x409E2EE4,bne,cr7,0xFFF03000
|
||||
0xFFF00100,0x40A60098,bne+,cr1,0xFFF00198
|
||||
@ -14,6 +58,7 @@
|
||||
0xFFF03004,0x41200054,bdnzt+,lt,0xFFF03058
|
||||
0xFFF03004,0x40000054,bdnzf,lt,0xFFF03058
|
||||
0xFFF03000,0x4106FFF4,bdnzt,4*cr1+eq,0xFFF02FF4
|
||||
0xFFF03000,0x4001558F,bdnzfla,gt,0x0000558C
|
||||
|
||||
# indexed load/store instructions, primary opcode 0x1F
|
||||
0xFFF00100,0x7D49F02E,lwzx,r10,r9,r30
|
||||
|
Can't render this file because it contains an unexpected character in line 4 and column 24.
|
@ -53,8 +53,7 @@ static vector<PPCDisasmContext> read_test_data()
|
||||
|
||||
/* put instruction mnemonic padded with trailing spaces */
|
||||
idisasm << tokens[2];
|
||||
if (tokens.size() > 3) // don't pad operand-less instructions
|
||||
idisasm << setw(8 - tokens[2].length()) << "";
|
||||
idisasm << setw(8 - tokens[2].length()) << "";
|
||||
|
||||
/* now add comma-separated operands */
|
||||
for (i = 3; i < tokens.size(); i++) {
|
||||
|
Loading…
Reference in New Issue
Block a user