diff --git a/rpcs3/Emu/CPU/CPUThread.cpp b/rpcs3/Emu/CPU/CPUThread.cpp index 1ec31434b2..ec21cc80a1 100644 --- a/rpcs3/Emu/CPU/CPUThread.cpp +++ b/rpcs3/Emu/CPU/CPUThread.cpp @@ -393,7 +393,7 @@ s64 CPUThread::ExecAsCallback(u64 pc, bool wait, u64 a1, u64 a2, u64 a3, u64 a4) { if (Emu.IsStopped()) { - ConLog.Warning("ExecAsCallback() aborted"); + ConLog.Warning("ExecAsCallback(wait=%s) aborted", wxString(wait ? "true" : false).wx_str()); return CELL_EABORT; // doesn't mean anything } Sleep(1); diff --git a/rpcs3/Emu/Cell/PPUDisAsm.h b/rpcs3/Emu/Cell/PPUDisAsm.h index a5cbf1775b..c904350589 100644 --- a/rpcs3/Emu/Cell/PPUDisAsm.h +++ b/rpcs3/Emu/Cell/PPUDisAsm.h @@ -1206,6 +1206,13 @@ private: { DisAsm_R2_INT2_RC("rldimi", ra, rs, sh, mb, rc); } + void RLDC_LR(u32 ra, u32 rs, u32 rb, u32 m_eb, bool is_r, bool rc) + { + if (is_r) + DisAsm_R3_INT2_RC("rldcr", ra, rs, rb, m_eb, 0, rc); + else + DisAsm_R3_INT2_RC("rldcl", ra, rs, rb, m_eb, 0, rc); + } void CMP(u32 crfd, u32 l, u32 ra, u32 rb) { DisAsm_CR1_R2(wxString::Format("cmp%s", wxString(l ? "d" : "w").wx_str()), crfd, ra, rb); diff --git a/rpcs3/Emu/Cell/PPUInstrTable.h b/rpcs3/Emu/Cell/PPUInstrTable.h index e82c02abdb..a65c9224a0 100644 --- a/rpcs3/Emu/Cell/PPUInstrTable.h +++ b/rpcs3/Emu/Cell/PPUInstrTable.h @@ -193,7 +193,7 @@ namespace PPU_instr static CodeField<26, 31> GD_04; //0x3f static CodeField<21, 31> GD_04_0;//0x7ff static CodeField<21, 30> GD_13; //0x3ff - static CodeField<28, 29> GD_1e; //0x3 + static CodeField<27, 29> GD_1e; //0x7 static CodeField<21, 30> GD_1f; //0x3ff static CodeField<30, 31> GD_3a; //0x3 static CodeField<26, 30> GD_3b; //0x1f @@ -441,6 +441,7 @@ namespace PPU_instr bind_instr(g1e_list, RLDICR, RA, RS, sh, me, RC); bind_instr(g1e_list, RLDIC, RA, RS, sh, mb, RC); bind_instr(g1e_list, RLDIMI, RA, RS, sh, mb, RC); + bind_instr(g1e_list, RLDC_LR, RA, RS, RB, mb, AA, RC); /*0x000*/bind_instr(g1f_list, CMP, CRFD, L_10, RA, RB); /*0x004*/bind_instr(g1f_list, TW, TO, RA, RB); diff --git a/rpcs3/Emu/Cell/PPUInterpreter.h b/rpcs3/Emu/Cell/PPUInterpreter.h index ea916d43b1..474cc75f25 100644 --- a/rpcs3/Emu/Cell/PPUInterpreter.h +++ b/rpcs3/Emu/Cell/PPUInterpreter.h @@ -2238,6 +2238,17 @@ private: CPU.GPR[ra] = (CPU.GPR[ra] & ~mask) | (rotl64(CPU.GPR[rs], sh) & mask); if(rc) CPU.UpdateCR0(CPU.GPR[ra]); } + void RLDC_LR(u32 ra, u32 rs, u32 rb, u32 m_eb, bool is_r, bool rc) + { + if (is_r) // rldcr + { + RLDICR(ra, rs, CPU.GPR[rb], m_eb, rc); + } + else // rldcl + { + RLDICL(ra, rs, CPU.GPR[rb], m_eb, rc); + } + } void CMP(u32 crfd, u32 l, u32 ra, u32 rb) { CPU.UpdateCRnS(l, crfd, CPU.GPR[ra], CPU.GPR[rb]); @@ -2766,7 +2777,7 @@ private: } void MULLW(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { - CPU.GPR[rd] = (s64)(s32)((s32)CPU.GPR[ra] * (s32)CPU.GPR[rb]); + CPU.GPR[rd] = (s64)((s64)(s32)CPU.GPR[ra] * (s64)(s32)CPU.GPR[rb]); if(rc) CPU.UpdateCR0(CPU.GPR[rd]); if(oe) UNK("mullwo"); } @@ -2949,7 +2960,7 @@ private: if (RB == 0 || ((u64)RA == (1ULL << 63) && RB == -1)) { if(oe) UNK("divdo"); - CPU.GPR[rd] = (((u64)RA & (1ULL << 63)) && RB == 0) ? -1 : 0; + CPU.GPR[rd] = /*(((u64)RA & (1ULL << 63)) && RB == 0) ? -1 :*/ 0; } else { @@ -2966,11 +2977,11 @@ private: if (RB == 0 || ((u32)RA == (1 << 31) && RB == -1)) { if(oe) UNK("divwo"); - CPU.GPR[rd] = (((u32)RA & (1 << 31)) && RB == 0) ? -1 : 0; + CPU.GPR[rd] = /*(((u32)RA & (1 << 31)) && RB == 0) ? -1 :*/ 0; } else { - CPU.GPR[rd] = (s64)(RA / RB); + CPU.GPR[rd] = (u32)(RA / RB); } if(rc) CPU.UpdateCR0(CPU.GPR[rd]); @@ -3077,18 +3088,34 @@ private: void SRAW(u32 ra, u32 rs, u32 rb, bool rc) { s32 RS = CPU.GPR[rs]; - s32 RB = CPU.GPR[rb]; - CPU.GPR[ra] = RS >> RB; - CPU.XER.CA = (RS < 0) & ((CPU.GPR[ra] << RB) != RS); + u8 shift = CPU.GPR[rb] & 63; + if (shift > 31) + { + CPU.GPR[ra] = 0 - (RS < 0); + CPU.XER.CA = (RS < 0); + } + else + { + CPU.GPR[ra] = RS >> shift; + CPU.XER.CA = (RS < 0) & ((CPU.GPR[ra] << shift) != RS); + } if(rc) CPU.UpdateCR0(CPU.GPR[ra]); } void SRAD(u32 ra, u32 rs, u32 rb, bool rc) { s64 RS = CPU.GPR[rs]; - s64 RB = CPU.GPR[rb]; - CPU.GPR[ra] = RS >> RB; - CPU.XER.CA = (RS < 0) & ((CPU.GPR[ra] << RB) != RS); + u8 shift = CPU.GPR[rb] & 127; + if (shift > 63) + { + CPU.GPR[ra] = 0 - (RS < 0); + CPU.XER.CA = (RS < 0); + } + else + { + CPU.GPR[ra] = RS >> shift; + CPU.XER.CA = (RS < 0) & ((CPU.GPR[ra] << shift) != RS); + } if(rc) CPU.UpdateCR0(CPU.GPR[ra]); } @@ -3162,6 +3189,7 @@ private: void EXTSW(u32 ra, u32 rs, bool rc) { CPU.GPR[ra] = (s64)(s32)CPU.GPR[rs]; + //CPU.XER.CA = ((s64)CPU.GPR[ra] < 0); // ??? if(rc) CPU.UpdateCR0(CPU.GPR[ra]); } /*0x3d6*///ICBI diff --git a/rpcs3/Emu/Cell/PPUOpcodes.h b/rpcs3/Emu/Cell/PPUOpcodes.h index 71a8d3b2f1..2d18686ecf 100644 --- a/rpcs3/Emu/Cell/PPUOpcodes.h +++ b/rpcs3/Emu/Cell/PPUOpcodes.h @@ -250,6 +250,7 @@ namespace PPU_opcodes RLDICR = 0x1, RLDIC = 0x2, RLDIMI = 0x3, + RLDC_LR = 0x4, }; enum G_1fOpcodes //Field 21 - 30 @@ -644,6 +645,7 @@ public: virtual void RLDICR(u32 ra, u32 rs, u32 sh, u32 me, bool rc) = 0; virtual void RLDIC(u32 ra, u32 rs, u32 sh, u32 mb, bool rc) = 0; virtual void RLDIMI(u32 ra, u32 rs, u32 sh, u32 mb, bool rc) = 0; + virtual void RLDC_LR(u32 ra, u32 rs, u32 rb, u32 m_eb, bool is_r, bool rc) = 0; virtual void CMP(u32 crfd, u32 l, u32 ra, u32 rb) = 0; virtual void TW(u32 to, u32 ra, u32 rb) = 0; virtual void LVSL(u32 vd, u32 ra, u32 rb) = 0;