diff --git a/src/xenia/cpu/ppc/ppc_decode_data.h b/src/xenia/cpu/ppc/ppc_decode_data.h index 60b4de431..61ae57610 100644 --- a/src/xenia/cpu/ppc/ppc_decode_data.h +++ b/src/xenia/cpu/ppc/ppc_decode_data.h @@ -42,7 +42,20 @@ static inline uint64_t XEMASK(uint32_t mstart, uint32_t mstop) { } struct PPCDecodeData { - struct FormatSC {}; + struct FormatSC { + uint32_t LEV() const { return bits_.LEV; } + + private: + uint32_t address_; + union { + uint32_t value_; + struct { + uint32_t : 5; + uint32_t LEV : 7; + uint32_t : 20; + } bits_; + }; + }; struct FormatD { uint32_t RT() const { return bits_.RT; } uint32_t RD() const { return RT(); } diff --git a/src/xenia/cpu/ppc/ppc_instr.h b/src/xenia/cpu/ppc/ppc_instr.h index 2b76392d3..7f2b69bba 100644 --- a/src/xenia/cpu/ppc/ppc_instr.h +++ b/src/xenia/cpu/ppc/ppc_instr.h @@ -49,6 +49,11 @@ struct InstrData { } B; // kXEPPCInstrFormatSC + struct { + uint32_t : 5; + uint32_t LEV : 7; + uint32_t : 20; + } SC; // kXEPPCInstrFormatD struct { uint32_t DS : 16; diff --git a/src/xenia/cpu/ppc/ppc_opcode_disasm_gen.cc b/src/xenia/cpu/ppc/ppc_opcode_disasm_gen.cc index 307b00d13..3bbcaa256 100644 --- a/src/xenia/cpu/ppc/ppc_opcode_disasm_gen.cc +++ b/src/xenia/cpu/ppc/ppc_opcode_disasm_gen.cc @@ -1977,10 +1977,11 @@ void PrintDisasm_rlwnmx(const PPCDecodeData& d, StringBuffer* str) { str->AppendFormat("%d", d.M.ME()); } void PrintDisasm_sc(const PPCDecodeData& d, StringBuffer* str) { - // sc + // sc [LEV] size_t str_start = str->length(); str->Append("sc"); PadStringBuffer(str, str_start, kNamePad); + if (d.SC.LEV()) str->AppendFormat("%d", d.SC.LEV()); } void PrintDisasm_sldx(const PPCDecodeData& d, StringBuffer* str) { // sld[Rc] [RA], [RS], [RB] @@ -5131,7 +5132,7 @@ PPCOpcodeDisasmInfo ppc_opcode_disasm_table[] = { INSTRUCTION(0x50000000, "rlwimix" , kM , kI, kGeneral, "Rotate Left Word Immediate then Mask Insert" , (PPCOpcodeField::kRS,PPCOpcodeField::kSH,PPCOpcodeField::kMB,PPCOpcodeField::kME), (PPCOpcodeField::kRA,PPCOpcodeField::kCRcond), PrintDisasm_rlwimix), INSTRUCTION(0x54000000, "rlwinmx" , kM , kI, kGeneral, "Rotate Left Word Immediate then AND with Mask" , (PPCOpcodeField::kRS,PPCOpcodeField::kSH,PPCOpcodeField::kMB,PPCOpcodeField::kME), (PPCOpcodeField::kRA,PPCOpcodeField::kCRcond), PrintDisasm_rlwinmx), INSTRUCTION(0x5c000000, "rlwnmx" , kM , kI, kGeneral, "Rotate Left Word then AND with Mask" , (PPCOpcodeField::kRS,PPCOpcodeField::kRB,PPCOpcodeField::kMB,PPCOpcodeField::kME), (PPCOpcodeField::kRA,PPCOpcodeField::kCRcond), PrintDisasm_rlwnmx), - INSTRUCTION(0x44000002, "sc" , kSC , kB, kSync , "System Call" , (), (), PrintDisasm_sc), + INSTRUCTION(0x44000002, "sc" , kSC , kB, kSync , "System Call" , (PPCOpcodeField::kLEV), (), PrintDisasm_sc), INSTRUCTION(0x7c000036, "sldx" , kX , kI, kGeneral, "Shift Left Doubleword" , (PPCOpcodeField::kRS,PPCOpcodeField::kRB), (PPCOpcodeField::kRA,PPCOpcodeField::kCRcond), PrintDisasm_sldx), INSTRUCTION(0x7c000030, "slwx" , kX , kI, kGeneral, "Shift Left Word" , (PPCOpcodeField::kRS,PPCOpcodeField::kRB), (PPCOpcodeField::kRA,PPCOpcodeField::kCRcond), PrintDisasm_slwx), INSTRUCTION(0x7c000674, "sradix" , kXS , kI, kGeneral, "Shift Right Algebraic Doubleword Immediate" , (PPCOpcodeField::kRS,PPCOpcodeField::kSH), (PPCOpcodeField::kRA,PPCOpcodeField::kCRcond,PPCOpcodeField::kCA), PrintDisasm_sradix), diff --git a/src/xenia/cpu/ppc/ppc_opcode_info.h b/src/xenia/cpu/ppc/ppc_opcode_info.h index 792a23ef4..f61f1a443 100644 --- a/src/xenia/cpu/ppc/ppc_opcode_info.h +++ b/src/xenia/cpu/ppc/ppc_opcode_info.h @@ -131,6 +131,7 @@ enum class PPCOpcodeField : uint32_t { kME, kMB, kTO, + kLEV, }; struct PPCOpcodeDisasmInfo { diff --git a/tools/ppc-instructions.xml b/tools/ppc-instructions.xml index e8c5e2837..ca45c6abc 100644 --- a/tools/ppc-instructions.xml +++ b/tools/ppc-instructions.xml @@ -1083,7 +1083,8 @@ rlwnm[Rc] [RA], [RS], [RB], [MB], [ME] - sc + + sc [LEV] diff --git a/tools/ppc-table-gen b/tools/ppc-table-gen index 6f8a7f92e..e81194b14 100644 --- a/tools/ppc-table-gen +++ b/tools/ppc-table-gen @@ -270,6 +270,8 @@ def generate_token_append(i, token): return 'str->AppendFormat(d.%s.%s() < 0 ? "-0x%%X" : "0x%%X", std::abs(d.%s.%s()));' % (i.o_form, token, i.o_form, token) elif token == 'ADDR': return 'str->AppendFormat("0x%%X", d.%s.%s());' % (i.o_form, token) + elif token == 'LEV': + return 'if (d.%s.%s()) str->AppendFormat("%%d", d.%s.%s());' % (i.o_form, token, i.o_form, token) return 'str->AppendFormat("(UNHANDLED %s)");' % token