diff --git a/rpcs3/Emu/Cell/PPUInterpreter.cpp b/rpcs3/Emu/Cell/PPUInterpreter.cpp index 53e18db82b..f5d06ed57a 100644 --- a/rpcs3/Emu/Cell/PPUInterpreter.cpp +++ b/rpcs3/Emu/Cell/PPUInterpreter.cpp @@ -5204,7 +5204,9 @@ auto LVRX() static const auto exec = [](ppu_thread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.gpr[op.ra] + ppu.gpr[op.rb] : ppu.gpr[op.rb]; - const u128 data = ppu_feed_data(ppu, addr & -16); + + // Read from instruction address if offset is 0, this prevents accessing potentially bad memory from addr (because no actual memory is dereferenced) + const u128 data = ppu_feed_data(ppu, ((addr & 15) == 0 ? ppu.cia : addr) & -16); ppu.vr[op.vd] = data >> ((~addr & 15) * 8) >> 8; }; diff --git a/rpcs3/Emu/Cell/PPUTranslator.cpp b/rpcs3/Emu/Cell/PPUTranslator.cpp index e591a5fada..8b3ac0b402 100644 --- a/rpcs3/Emu/Cell/PPUTranslator.cpp +++ b/rpcs3/Emu/Cell/PPUTranslator.cpp @@ -3310,8 +3310,11 @@ void PPUTranslator::SRD(ppu_opcode_t op) void PPUTranslator::LVRX(ppu_opcode_t op) { const auto addr = op.ra ? m_ir->CreateAdd(GetGpr(op.ra), GetGpr(op.rb)) : GetGpr(op.rb); - const auto data = ReadMemory(m_ir->CreateAnd(addr, ~0xfull), GetType(), m_is_be, 16); - set_vr(op.vd, pshufb(value(data), build(255, 254, 253, 252, 251, 250, 249, 248, 247, 246, 245, 244, 243, 242, 241, 240) + vsplat(trunc(value(addr) & 0xf)))); + const auto offset = eval(trunc(value(addr) & 0xf)); + + // Read from instruction address if offset is 0, this prevents accessing potentially bad memory from addr (because no actual memory is dereferenced) + const auto data = ReadMemory(m_ir->CreateAnd(m_ir->CreateSelect(m_ir->CreateIsNull(offset.value), m_reloc ? m_seg0 : GetAddr(0), addr), ~0xfull), GetType(), m_is_be, 16); + set_vr(op.vd, pshufb(value(data), build(255, 254, 253, 252, 251, 250, 249, 248, 247, 246, 245, 244, 243, 242, 241, 240) + vsplat(offset))); } void PPUTranslator::LSWI(ppu_opcode_t op)