From b28c51271d645709ddaa96a2c35e7f02fcf905e8 Mon Sep 17 00:00:00 2001 From: Ben Vanik <ben.vanik@gmail.com> Date: Sun, 13 Oct 2013 22:53:33 -0700 Subject: [PATCH] A bunch of disasm instructions used by some games. --- src/xenia/cpu/ppc/disasm_altivec.cc | 33 +++++++++++++++++++++++------ src/xenia/cpu/ppc/disasm_fpu.cc | 14 ++++++++---- src/xenia/cpu/ppc/instr.cc | 7 ++++++ src/xenia/cpu/ppc/instr.h | 10 +++++++++ 4 files changed, 54 insertions(+), 10 deletions(-) diff --git a/src/xenia/cpu/ppc/disasm_altivec.cc b/src/xenia/cpu/ppc/disasm_altivec.cc index 1008a32fe..08b23b43c 100644 --- a/src/xenia/cpu/ppc/disasm_altivec.cc +++ b/src/xenia/cpu/ppc/disasm_altivec.cc @@ -1268,7 +1268,10 @@ XEDISASMR(vsl, 0x100001C4, VX )(InstrData& i, InstrDisasm& d) { XEDISASMR(vslb, 0x10000104, VX )(InstrData& i, InstrDisasm& d) { d.Init("vslb", "Vector Shift Left Integer Byte", InstrDisasm::kVMX); - return 1; + d.AddRegOperand(InstrRegister::kVMX, i.VX.VD, InstrRegister::kWrite); + d.AddRegOperand(InstrRegister::kVMX, i.VX.VA, InstrRegister::kRead); + d.AddRegOperand(InstrRegister::kVMX, i.VX.VB, InstrRegister::kRead); + return d.Finish(); } XEDISASMR(vsldoi, 0x1000002C, VXA )(InstrData& i, InstrDisasm& d) { @@ -1324,31 +1327,49 @@ XEDISASMR(vslw128, VX128(6, 208), VX128 )(InstrData& i, InstrDisasm& XEDISASMR(vspltb, 0x1000020C, VX )(InstrData& i, InstrDisasm& d) { d.Init("vspltb", "Vector Splat Byte", InstrDisasm::kVMX); - return 1; + d.AddRegOperand(InstrRegister::kVMX, i.VX.VD, InstrRegister::kWrite); + d.AddRegOperand(InstrRegister::kVMX, i.VX.VB, InstrRegister::kRead); + d.AddUImmOperand(i.VX.VA & 0xF, 1); + return d.Finish(); } XEDISASMR(vsplth, 0x1000024C, VX )(InstrData& i, InstrDisasm& d) { d.Init("vsplth", "Vector Splat Half Word", InstrDisasm::kVMX); - return 1; + d.AddRegOperand(InstrRegister::kVMX, i.VX.VD, InstrRegister::kWrite); + d.AddRegOperand(InstrRegister::kVMX, i.VX.VB, InstrRegister::kRead); + d.AddUImmOperand(i.VX.VA & 0x7, 1); + return d.Finish(); } XEDISASMR(vspltisb, 0x1000030C, VX )(InstrData& i, InstrDisasm& d) { d.Init("vspltisb", "Vector Splat Immediate Signed Byte", InstrDisasm::kVMX); - return 1; + d.AddRegOperand(InstrRegister::kVMX, i.VX.VD, InstrRegister::kWrite); + // 5bit -> 8bit sign extend + uint64_t v = (i.VX.VA & 0x10) ? (i.VX.VA | 0xFFFFFFFFFFFFFFF0) : i.VX.VA; + d.AddSImmOperand(v, 1); + return d.Finish(); } XEDISASMR(vspltish, 0x1000034C, VX )(InstrData& i, InstrDisasm& d) { d.Init("vspltish", "Vector Splat Immediate Signed Half Word", InstrDisasm::kVMX); - return 1; + d.AddRegOperand(InstrRegister::kVMX, i.VX.VD, InstrRegister::kWrite); + // 5bit -> 16bit sign extend + uint64_t v = (i.VX.VA & 0x10) ? (i.VX.VA | 0xFFFFFFFFFFFFFFF0) : i.VX.VA; + d.AddSImmOperand(v, 1); + return d.Finish(); } XEDISASMR(vspltisw, 0x1000038C, VX )(InstrData& i, InstrDisasm& d) { d.Init("vspltisw", "Vector Splat Immediate Signed Word", InstrDisasm::kVMX); - return 1; + d.AddRegOperand(InstrRegister::kVMX, i.VX.VD, InstrRegister::kWrite); + // 5bit -> 32bit sign extend + uint64_t v = (i.VX.VA & 0x10) ? (i.VX.VA | 0xFFFFFFFFFFFFFFF0) : i.VX.VA; + d.AddSImmOperand(v, 1); + return d.Finish(); } XEDISASMR(vspltisw128, VX128_3(6, 1904), VX128_3)(InstrData& i, InstrDisasm& d) { diff --git a/src/xenia/cpu/ppc/disasm_fpu.cc b/src/xenia/cpu/ppc/disasm_fpu.cc index 5c977524c..6b63d8290 100644 --- a/src/xenia/cpu/ppc/disasm_fpu.cc +++ b/src/xenia/cpu/ppc/disasm_fpu.cc @@ -299,8 +299,11 @@ XEDISASMR(mcrfs, 0xFC000080, X )(InstrData& i, InstrDisasm& d) { } XEDISASMR(mffsx, 0xFC00048E, X )(InstrData& i, InstrDisasm& d) { - XEINSTRNOTIMPLEMENTED(); - return 1; + d.Init("mffs", "Move from FPSCR", + InstrDisasm::kFP | (i.X.Rc ? InstrDisasm::kRc : 0)); + d.AddFPSCR(InstrRegister::kRead); + d.AddRegOperand(InstrRegister::kFPR, i.X.RT, InstrRegister::kWrite); + return d.Finish(); } XEDISASMR(mtfsb0x, 0xFC00008C, X )(InstrData& i, InstrDisasm& d) { @@ -314,8 +317,11 @@ XEDISASMR(mtfsb1x, 0xFC00004C, X )(InstrData& i, InstrDisasm& d) { } XEDISASMR(mtfsfx, 0xFC00058E, XFL)(InstrData& i, InstrDisasm& d) { - XEINSTRNOTIMPLEMENTED(); - return 1; + d.Init("mtfsf", "Move to FPSCR Fields", + InstrDisasm::kFP | (i.XFL.Rc ? InstrDisasm::kRc : 0)); + d.AddFPSCR(InstrRegister::kWrite); + d.AddRegOperand(InstrRegister::kFPR, i.XFL.RB, InstrRegister::kRead); + return d.Finish(); } XEDISASMR(mtfsfix, 0xFC00010C, X )(InstrData& i, InstrDisasm& d) { diff --git a/src/xenia/cpu/ppc/instr.cc b/src/xenia/cpu/ppc/instr.cc index c87c07f0c..b53c4bfe9 100644 --- a/src/xenia/cpu/ppc/instr.cc +++ b/src/xenia/cpu/ppc/instr.cc @@ -336,6 +336,13 @@ void InstrDisasm::AddCR(uint32_t bf, InstrRegister::Access access) { special_registers.push_back(i); } +void InstrDisasm::AddFPSCR(InstrRegister::Access access) { + InstrRegister i = { + InstrRegister::kFPSCR, 0, access + }; + special_registers.push_back(i); +} + void InstrDisasm::AddRegOperand( InstrRegister::RegisterSet set, uint32_t ordinal, InstrRegister::Access access, const char* display) { diff --git a/src/xenia/cpu/ppc/instr.h b/src/xenia/cpu/ppc/instr.h index b5ecac3a9..7fa0c5c97 100644 --- a/src/xenia/cpu/ppc/instr.h +++ b/src/xenia/cpu/ppc/instr.h @@ -171,6 +171,15 @@ typedef struct { uint32_t : 6; } XFX; // kXEPPCInstrFormatXFL + struct { + uint32_t Rc : 1; + uint32_t : 10; + uint32_t RB : 5; + uint32_t : 1; + uint32_t FM : 8; + uint32_t : 1; + uint32_t : 6; + } XFL; // kXEPPCInstrFormatXS struct { uint32_t Rc : 1; @@ -478,6 +487,7 @@ public: void AddLR(InstrRegister::Access access); void AddCTR(InstrRegister::Access access); void AddCR(uint32_t bf, InstrRegister::Access access); + void AddFPSCR(InstrRegister::Access access); void AddRegOperand(InstrRegister::RegisterSet set, uint32_t ordinal, InstrRegister::Access access, const char* display = NULL); void AddSImmOperand(uint64_t value, size_t width, const char* display = NULL);