Merge remote-tracking branch 'upstream/master' into canary-old-update

This commit is contained in:
illusion98 2020-02-12 04:10:43 -05:00
commit e2eb50f0e4
8 changed files with 43 additions and 11 deletions

View File

@ -42,7 +42,20 @@ static inline uint64_t XEMASK(uint32_t mstart, uint32_t mstop) {
} }
struct PPCDecodeData { 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 { struct FormatD {
uint32_t RT() const { return bits_.RT; } uint32_t RT() const { return bits_.RT; }
uint32_t RD() const { return RT(); } uint32_t RD() const { return RT(); }

View File

@ -423,8 +423,15 @@ int InstrEmit_mcrf(PPCHIRBuilder& f, const InstrData& i) {
// System linkage (A-24) // System linkage (A-24)
int InstrEmit_sc(PPCHIRBuilder& f, const InstrData& i) { int InstrEmit_sc(PPCHIRBuilder& f, const InstrData& i) {
// Game code should only ever use LEV=0.
// LEV=2 is to signify 'call import' from Xenia.
// TODO(gibbed): syscalls!
if (i.SC.LEV == 2) {
f.CallExtern(f.function()); f.CallExtern(f.function());
return 0; return 0;
}
XEINSTRNOTIMPLEMENTED();
return 1;
} }
// Trap (A-25) // Trap (A-25)

View File

@ -49,6 +49,11 @@ struct InstrData {
} B; } B;
// kXEPPCInstrFormatSC // kXEPPCInstrFormatSC
struct {
uint32_t : 5;
uint32_t LEV : 7;
uint32_t : 20;
} SC;
// kXEPPCInstrFormatD // kXEPPCInstrFormatD
struct { struct {
uint32_t DS : 16; uint32_t DS : 16;

View File

@ -1977,10 +1977,11 @@ void PrintDisasm_rlwnmx(const PPCDecodeData& d, StringBuffer* str) {
str->AppendFormat("%d", d.M.ME()); str->AppendFormat("%d", d.M.ME());
} }
void PrintDisasm_sc(const PPCDecodeData& d, StringBuffer* str) { void PrintDisasm_sc(const PPCDecodeData& d, StringBuffer* str) {
// sc // sc [LEV]
size_t str_start = str->length(); size_t str_start = str->length();
str->Append("sc"); str->Append("sc");
PadStringBuffer(str, str_start, kNamePad); PadStringBuffer(str, str_start, kNamePad);
if (d.SC.LEV()) str->AppendFormat("%d", d.SC.LEV());
} }
void PrintDisasm_sldx(const PPCDecodeData& d, StringBuffer* str) { void PrintDisasm_sldx(const PPCDecodeData& d, StringBuffer* str) {
// sld[Rc] [RA], [RS], [RB] // 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(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(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(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(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(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), INSTRUCTION(0x7c000674, "sradix" , kXS , kI, kGeneral, "Shift Right Algebraic Doubleword Immediate" , (PPCOpcodeField::kRS,PPCOpcodeField::kSH), (PPCOpcodeField::kRA,PPCOpcodeField::kCRcond,PPCOpcodeField::kCA), PrintDisasm_sradix),

View File

@ -131,6 +131,7 @@ enum class PPCOpcodeField : uint32_t {
kME, kME,
kMB, kMB,
kTO, kTO,
kLEV,
}; };
struct PPCOpcodeDisasmInfo { struct PPCOpcodeDisasmInfo {

View File

@ -1224,15 +1224,17 @@ bool XexModule::SetupLibraryImports(const char* name,
// bctr // bctr
// Real consoles rewrite this with some code that sets r11. // Real consoles rewrite this with some code that sets r11.
// If we did that we'd still have to put a thunk somewhere and do the // If we did that we'd still have to put a thunk somewhere and do the
// dynamic lookup. Instead, we rewrite it to use syscalls, as they // dynamic lookup. Instead, we rewrite it to use syscalls.
// aren't used on the 360. CPU backends can either take the syscall // We use sc with a LEV operand of 2, which is reserved usage and
// or do something smarter. // should never see actual usage outside of our rewrite.
// sc // CPU backends can either take the special form syscall or do
// something smarter.
// sc 2
// blr // blr
// nop // nop
// nop // nop
uint8_t* p = memory()->TranslateVirtual(record_addr); uint8_t* p = memory()->TranslateVirtual(record_addr);
xe::store_and_swap<uint32_t>(p + 0x0, 0x44000002); xe::store_and_swap<uint32_t>(p + 0x0, 0x44000042);
xe::store_and_swap<uint32_t>(p + 0x4, 0x4E800020); xe::store_and_swap<uint32_t>(p + 0x4, 0x4E800020);
xe::store_and_swap<uint32_t>(p + 0x8, 0x60000000); xe::store_and_swap<uint32_t>(p + 0x8, 0x60000000);
xe::store_and_swap<uint32_t>(p + 0xC, 0x60000000); xe::store_and_swap<uint32_t>(p + 0xC, 0x60000000);

View File

@ -1083,7 +1083,8 @@
<disasm>rlwnm[Rc] [RA], [RS], [RB], [MB], [ME]</disasm> <disasm>rlwnm[Rc] [RA], [RS], [RB], [MB], [ME]</disasm>
</insn> </insn>
<insn mnem="sc" opcode="44000002" form="SC" group="b" desc="System Call" sync="true"> <insn mnem="sc" opcode="44000002" form="SC" group="b" desc="System Call" sync="true">
<disasm>sc</disasm> <in field="LEV" />
<disasm>sc [LEV]</disasm>
</insn> </insn>
<insn mnem="sldx" opcode="7c000036" form="X" group="i" desc="Shift Left Doubleword"> <insn mnem="sldx" opcode="7c000036" form="X" group="i" desc="Shift Left Doubleword">
<in field="RS" /> <in field="RS" />

View File

@ -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) 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': elif token == 'ADDR':
return 'str->AppendFormat("0x%%X", d.%s.%s());' % (i.o_form, token) 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 return 'str->AppendFormat("(UNHANDLED %s)");' % token