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.
175 lines
4.3 KiB
C++
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
|