| Index: src/ppc/disasm-ppc.cc
|
| diff --git a/src/ppc/disasm-ppc.cc b/src/ppc/disasm-ppc.cc
|
| index 02ef88bc198c198ade64b02a90a4f82a315548ce..8176bbb78c28984484240e24f0a4f9265f3d7356 100644
|
| --- a/src/ppc/disasm-ppc.cc
|
| +++ b/src/ppc/disasm-ppc.cc
|
| @@ -243,6 +243,14 @@ int Decoder::FormatOption(Instruction* instr, const char* format) {
|
| }
|
| return 1;
|
| }
|
| + case 'c': { // 'cr: condition register of branch instruction
|
| + int code = instr->Bits(20, 18);
|
| + if (code != 7) {
|
| + out_buffer_pos_ +=
|
| + SNPrintF(out_buffer_ + out_buffer_pos_, " cr%d", code);
|
| + }
|
| + return 2;
|
| + }
|
| case 't': { // 'target: target of branch instructions
|
| // target26 or target16
|
| DCHECK(STRING_STARTS_WITH(format, "target"));
|
| @@ -366,7 +374,10 @@ void Decoder::DecodeExt1(Instruction* instr) {
|
| break;
|
| }
|
| case BCLRX: {
|
| - switch (instr->Bits(25, 21) << 21) {
|
| + int bo = instr->Bits(25, 21) << 21;
|
| + int bi = instr->Bits(20, 16);
|
| + CRBit cond = static_cast<CRBit>(bi & (CRWIDTH - 1));
|
| + switch (bo) {
|
| case DCBNZF: {
|
| UnknownFormat(instr, "bclrx-dcbnzf");
|
| break;
|
| @@ -376,7 +387,20 @@ void Decoder::DecodeExt1(Instruction* instr) {
|
| break;
|
| }
|
| case BF: {
|
| - UnknownFormat(instr, "bclrx-bf");
|
| + switch (cond) {
|
| + case CR_EQ:
|
| + Format(instr, "bnelr'l'cr");
|
| + break;
|
| + case CR_GT:
|
| + Format(instr, "blelr'l'cr");
|
| + break;
|
| + case CR_LT:
|
| + Format(instr, "bgelr'l'cr");
|
| + break;
|
| + case CR_SO:
|
| + Format(instr, "bnsolr'l'cr");
|
| + break;
|
| + }
|
| break;
|
| }
|
| case DCBNZT: {
|
| @@ -388,7 +412,20 @@ void Decoder::DecodeExt1(Instruction* instr) {
|
| break;
|
| }
|
| case BT: {
|
| - UnknownFormat(instr, "bclrx-bt");
|
| + switch (cond) {
|
| + case CR_EQ:
|
| + Format(instr, "beqlr'l'cr");
|
| + break;
|
| + case CR_GT:
|
| + Format(instr, "bgtlr'l'cr");
|
| + break;
|
| + case CR_LT:
|
| + Format(instr, "bltlr'l'cr");
|
| + break;
|
| + case CR_SO:
|
| + Format(instr, "bsolr'l'cr");
|
| + break;
|
| + }
|
| break;
|
| }
|
| case DCBNZ: {
|
| @@ -400,11 +437,7 @@ void Decoder::DecodeExt1(Instruction* instr) {
|
| break;
|
| }
|
| case BA: {
|
| - if (instr->Bit(0) == 1) {
|
| - Format(instr, "blrl");
|
| - } else {
|
| - Format(instr, "blr");
|
| - }
|
| + Format(instr, "blr'l");
|
| break;
|
| }
|
| }
|
| @@ -1062,43 +1095,48 @@ int Decoder::InstructionDecode(byte* instr_ptr) {
|
| case BCX: {
|
| int bo = instr->Bits(25, 21) << 21;
|
| int bi = instr->Bits(20, 16);
|
| - switch (bi) {
|
| - case 2:
|
| - case 30:
|
| - if (BT == bo) {
|
| - Format(instr, "beq'l'a 'target16");
|
| - break;
|
| - }
|
| - if (BF == bo) {
|
| - Format(instr, "bne'l'a 'target16");
|
| - break;
|
| + CRBit cond = static_cast<CRBit>(bi & (CRWIDTH - 1));
|
| + switch (bo) {
|
| + case BT: { // Branch if condition true
|
| + switch (cond) {
|
| + case CR_EQ:
|
| + Format(instr, "beq'l'a'cr 'target16");
|
| + break;
|
| + case CR_GT:
|
| + Format(instr, "bgt'l'a'cr 'target16");
|
| + break;
|
| + case CR_LT:
|
| + Format(instr, "blt'l'a'cr 'target16");
|
| + break;
|
| + case CR_SO:
|
| + Format(instr, "bso'l'a'cr 'target16");
|
| + break;
|
| }
|
| - Format(instr, "bc'l'a 'target16");
|
| break;
|
| - case 29:
|
| - if (BT == bo) {
|
| - Format(instr, "bgt'l'a 'target16");
|
| - break;
|
| - }
|
| - if (BF == bo) {
|
| - Format(instr, "ble'l'a 'target16");
|
| - break;
|
| + }
|
| + case BF: { // Branch if condition false
|
| + switch (cond) {
|
| + case CR_EQ:
|
| + Format(instr, "bne'l'a'cr 'target16");
|
| + break;
|
| + case CR_GT:
|
| + Format(instr, "ble'l'a'cr 'target16");
|
| + break;
|
| + case CR_LT:
|
| + Format(instr, "bge'l'a'cr 'target16");
|
| + break;
|
| + case CR_SO:
|
| + Format(instr, "bnso'l'a'cr 'target16");
|
| + break;
|
| }
|
| - Format(instr, "bc'l'a 'target16");
|
| break;
|
| - case 28:
|
| - if (BT == bo) {
|
| - Format(instr, "blt'l'a 'target16");
|
| - break;
|
| - }
|
| - if (BF == bo) {
|
| - Format(instr, "bge'l'a 'target16");
|
| - break;
|
| - }
|
| - Format(instr, "bc'l'a 'target16");
|
| + }
|
| + case DCBNZ: { // Decrement CTR; branch if CTR != 0
|
| + Format(instr, "bdnz'l'a 'target16");
|
| break;
|
| + }
|
| default:
|
| - Format(instr, "bc'l'a 'target16");
|
| + Format(instr, "bc'l'a'cr 'target16");
|
| break;
|
| }
|
| break;
|
|
|