Files
Xenia-Canary/src/xenia/cpu/ppc/ppc_opcode_disasm.cc
gibbed 5bf0b34445 C++17ification.
C++17ification!

- Filesystem interaction now uses std::filesystem::path.
- Usage of const char*, std::string have been changed to
  std::string_view where appropriate.
- Usage of printf-style functions changed to use fmt.
2020-04-07 16:09:41 -05:00

175 lines
4.3 KiB
C++

/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2015 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include <cstdint>
#include <cstdlib>
#include "xenia/base/assert.h"
#include "xenia/cpu/ppc/ppc_decode_data.h"
#include "xenia/cpu/ppc/ppc_opcode.h"
#include "xenia/cpu/ppc/ppc_opcode_disasm.h"
#include "xenia/cpu/ppc/ppc_opcode_info.h"
namespace xe {
namespace cpu {
namespace ppc {
void PadStringBuffer(StringBuffer* str, size_t base, size_t pad) {
size_t added_len = str->length() - base;
if (added_len < pad) str->AppendBytes(kSpaces, kNamePad - added_len);
}
void PrintDisasm_bcx(const PPCDecodeData& d, StringBuffer* str) {
// [bc][LK][AA][+-] [BO], [BI], [ADDR]
size_t str_start = str->length();
const uint32_t bo = d.B.BO();
const uint32_t bi = d.B.BI();
const uint32_t addr = d.B.ADDR();
const bool bo0 = bo & 0x10;
const bool bo1 = bo & 0x08;
const bool bo2 = bo & 0x04;
const bool bo3 = bo & 0x02;
const bool bo4 = bo & 0x01;
int sign_char = 0; // Default no sign
if (bo0 && !bo1 && !bo2 && bo3 && !bo4) {
str->Append("bdz");
} else if (bo0 && bo1 && !bo2 && bo3 && !bo4) {
str->Append("bdz");
sign_char = -1;
} else if (bo0 && bo1 && !bo2 && bo3 && bo4) {
str->Append("bdz");
sign_char = +1;
} else if (bo0 && !bo1 && !bo2 && !bo3 && !bo4) {
str->Append("bdnz");
} else if (bo0 && bo1 && !bo2 && !bo3 && !bo4) {
str->Append("bdnz");
sign_char = -1;
} else if (bo0 && bo1 && !bo2 && !bo3 && bo4) {
str->Append("bdnz");
sign_char = +1;
} else if (!bo0 && !bo1 && bo2 && !bo3 && !bo4) {
switch (bi % 4) {
case 0x0:
str->Append("bge");
break;
case 0x1:
str->Append("ble");
break;
case 0x2:
str->Append("bne");
break;
}
} else if (!bo0 && !bo1 && bo2 && bo3 && !bo4) {
switch (bi % 4) {
case 0x0:
str->Append("bge");
sign_char = -1;
break;
case 0x1:
str->Append("ble");
sign_char = -1;
break;
case 0x2:
str->Append("bne");
sign_char = -1;
break;
}
} else if (!bo0 && !bo1 && bo2 && bo3 && bo4) {
switch (bi % 4) {
case 0x0:
str->Append("bge");
sign_char = +1;
break;
case 0x1:
str->Append("ble");
sign_char = +1;
break;
case 0x2:
str->Append("bne");
sign_char = +1;
break;
}
} else if (!bo0 && bo1 && bo2 && !bo3 && !bo4) {
switch (bi % 4) {
case 0x0:
str->Append("blt");
break;
case 0x1:
str->Append("bgt");
break;
case 0x2:
str->Append("beq");
break;
}
} else if (!bo0 && bo1 && bo2 && bo3 && !bo4) {
switch (bi % 4) {
case 0x0:
str->Append("blt");
sign_char = -1;
break;
case 0x1:
str->Append("bgt");
sign_char = -1;
break;
case 0x2:
str->Append("beq");
sign_char = -1;
break;
}
} else if (!bo0 && bo1 && bo2 && bo3 && bo4) {
switch (bi % 4) {
case 0x0:
str->Append("blt");
sign_char = +1;
break;
case 0x1:
str->Append("bgt");
sign_char = +1;
break;
case 0x2:
str->Append("beq");
sign_char = +1;
break;
}
}
if (str_start == str->length()) {
// Default
str->Append("bc");
if (d.B.LK()) str->Append('l');
if (d.B.AA()) str->Append('a');
PadStringBuffer(str, str_start, kNamePad);
str->AppendFormat("{}", bo);
str->Append(", ");
str->AppendFormat("{}", bi);
} else {
if (d.B.LK()) str->Append('l');
if (d.B.AA()) str->Append('a');
if (sign_char > 0) {
str->Append('+');
} else if (sign_char < 0) {
str->Append('-');
}
PadStringBuffer(str, str_start, kNamePad);
str->AppendFormat("crf{}", bi / 4);
}
str->Append(", ");
str->AppendFormat("0x{:X}", addr);
}
} // namespace ppc
} // namespace cpu
} // namespace xe