diff --git a/rpcs3/Emu/Cell/SPURecompiler.cpp b/rpcs3/Emu/Cell/SPURecompiler.cpp index c9b7bc9a0c..0e7b3f0e78 100644 --- a/rpcs3/Emu/Cell/SPURecompiler.cpp +++ b/rpcs3/Emu/Cell/SPURecompiler.cpp @@ -6696,16 +6696,40 @@ public: void ROTQMBYBI(spu_opcode_t op) { + const auto a = get_vr(op.ra); + const auto b = get_vr(op.rb); + + // Data with swapped endian from a load instruction + if (auto [ok, as] = match_expr(a, byteswap(match())); ok) + { + const auto sc = build(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); + const auto sh = sc - (-(splat_scalar(b) >> 3) & 0x1f); + set_vr(op.rt, pshufb(as, sh)); + return; + } + const auto sc = build(112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127); - const auto sh = sc + (-(splat_scalar(get_vr(op.rb)) >> 3) & 0x1f); - set_vr(op.rt, pshufb(get_vr(op.ra), sh)); + const auto sh = sc + (-(splat_scalar(b) >> 3) & 0x1f); + set_vr(op.rt, pshufb(a, sh)); } void SHLQBYBI(spu_opcode_t op) { + const auto a = get_vr(op.ra); + const auto b = get_vr(op.rb); + + // Data with swapped endian from a load instruction + if (auto [ok, as] = match_expr(a, byteswap(match())); ok) + { + const auto sc = build(127, 126, 125, 124, 123, 122, 121, 120, 119, 118, 117, 116, 115, 114, 113, 112); + const auto sh = sc + (splat_scalar(b) >> 3); + set_vr(op.rt, pshufb(as, sh)); + return; + } + const auto sc = build(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); - const auto sh = sc - (splat_scalar(get_vr(op.rb)) >> 3); - set_vr(op.rt, pshufb(get_vr(op.ra), sh)); + const auto sh = sc - (splat_scalar(b) >> 3); + set_vr(op.rt, pshufb(a, sh)); } template @@ -6841,6 +6865,16 @@ public: { const auto a = get_vr(op.ra); const auto b = get_vr(op.rb); + + // Data with swapped endian from a load instruction + if (auto [ok, as] = match_expr(a, byteswap(match())); ok) + { + const auto sc = build(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); + const auto sh = sc - (-splat_scalar(b) & 0x1f); + set_vr(op.rt, pshufb(as, sh)); + return; + } + const auto sc = build(112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127); const auto sh = sc + (-splat_scalar(b) & 0x1f); set_vr(op.rt, pshufb(a, sh)); @@ -6850,6 +6884,16 @@ public: { const auto a = get_vr(op.ra); const auto b = get_vr(op.rb); + + // Data with swapped endian from a load instruction + if (auto [ok, as] = match_expr(a, byteswap(match())); ok) + { + const auto sc = build(127, 126, 125, 124, 123, 122, 121, 120, 119, 118, 117, 116, 115, 114, 113, 112); + const auto sh = sc + (splat_scalar(b) & 0x1f); + set_vr(op.rt, pshufb(as, sh)); + return; + } + const auto sc = build(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); const auto sh = sc - (splat_scalar(b) & 0x1f); set_vr(op.rt, pshufb(a, sh));