diff --git a/rpcs3/Emu/Cell/SPUASMJITRecompiler.cpp b/rpcs3/Emu/Cell/SPUASMJITRecompiler.cpp index d71278e324..21be3d4af0 100644 --- a/rpcs3/Emu/Cell/SPUASMJITRecompiler.cpp +++ b/rpcs3/Emu/Cell/SPUASMJITRecompiler.cpp @@ -1,4 +1,4 @@ -#include "stdafx.h" +#include "stdafx.h" #include "Emu/Memory/vm.h" #include "Emu/System.h" #include "Emu/IdManager.h" @@ -2681,7 +2681,23 @@ void spu_recompiler::IRET(spu_opcode_t op) void spu_recompiler::BISLED(spu_opcode_t op) { - fmt::throw_exception("Unimplemented instruction" HERE); + c->mov(*addr, SPU_OFF_32(gpr, op.ra, &v128::_u32, 3)); + c->and_(*addr, 0x3fffc); + + const XmmLink& vr = XmmAlloc(); + c->movdqa(vr, XmmConst(_mm_set_epi32(spu_branch_target(m_pos + 4), 0, 0, 0))); + c->movdqa(SPU_OFF_128(gpr, op.rt), vr); + + asmjit::Label branch_label = c->newLabel(); + get_events(); + c->jne(branch_label); + + after.emplace_back([=] + { + c->align(asmjit::kAlignCode, 16); + c->bind(branch_label); + branch_indirect(op); + }); } void spu_recompiler::HBR(spu_opcode_t op) @@ -3429,7 +3445,7 @@ void spu_recompiler::FCGT(spu_opcode_t op) void spu_recompiler::DFCGT(spu_opcode_t op) { - fmt::throw_exception("Unexpected instruction" HERE); + UNK(op); } void spu_recompiler::FA(spu_opcode_t op) @@ -3572,14 +3588,7 @@ void spu_recompiler::FCMGT(spu_opcode_t op) void spu_recompiler::DFCMGT(spu_opcode_t op) { - const auto mask = XmmConst(_mm_set1_epi64x(0x7fffffffffffffff)); - const XmmLink& va = XmmGet(op.ra, XmmType::Double); - const XmmLink& vb = XmmGet(op.rb, XmmType::Double); - - c->andpd(va, mask); - c->andpd(vb, mask); - c->cmppd(vb, va, 1); - c->movaps(SPU_OFF_128(gpr, op.rt), vb); + UNK(op); } void spu_recompiler::DFA(spu_opcode_t op) @@ -3798,7 +3807,7 @@ void spu_recompiler::FSCRWR(spu_opcode_t op) void spu_recompiler::DFTSV(spu_opcode_t op) { - fmt::throw_exception("Unexpected instruction" HERE); + UNK(op); } void spu_recompiler::FCEQ(spu_opcode_t op) @@ -3811,7 +3820,7 @@ void spu_recompiler::FCEQ(spu_opcode_t op) void spu_recompiler::DFCEQ(spu_opcode_t op) { - fmt::throw_exception("Unexpected instruction" HERE); + UNK(op); } void spu_recompiler::MPY(spu_opcode_t op) @@ -3876,7 +3885,7 @@ void spu_recompiler::FCMEQ(spu_opcode_t op) void spu_recompiler::DFCMEQ(spu_opcode_t op) { - fmt::throw_exception("Unexpected instruction" HERE); + UNK(op); } void spu_recompiler::MPYU(spu_opcode_t op) diff --git a/rpcs3/Emu/Cell/SPUInterpreter.cpp b/rpcs3/Emu/Cell/SPUInterpreter.cpp index 5518ed864c..c94ccc8852 100644 --- a/rpcs3/Emu/Cell/SPUInterpreter.cpp +++ b/rpcs3/Emu/Cell/SPUInterpreter.cpp @@ -496,7 +496,16 @@ bool spu_interpreter::IRET(spu_thread& spu, spu_opcode_t op) bool spu_interpreter::BISLED(spu_thread& spu, spu_opcode_t op) { - fmt::throw_exception("Unimplemented instruction" HERE); + const u32 target = spu_branch_target(spu.gpr[op.ra]._u32[3]); + spu.gpr[op.rt] = v128::from32r(spu_branch_target(spu.pc + 4)); + + if (spu.get_events()) + { + spu.pc = target; + set_interrupt_status(spu, op); + return false; + } + return true; } @@ -1043,10 +1052,7 @@ bool spu_interpreter_fast::FCMGT(spu_thread& spu, spu_opcode_t op) bool spu_interpreter::DFCMGT(spu_thread& spu, spu_opcode_t op) { - const auto mask = _mm_castsi128_pd(_mm_set1_epi64x(0x7fffffffffffffff)); - const auto ra = _mm_and_pd(spu.gpr[op.ra].vd, mask); - const auto rb = _mm_and_pd(spu.gpr[op.rb].vd, mask); - spu.gpr[op.rt].vd = _mm_cmpgt_pd(ra, rb); + fmt::throw_exception("Unexpected Instruction" HERE); return true; } diff --git a/rpcs3/Emu/Cell/SPURecompiler.cpp b/rpcs3/Emu/Cell/SPURecompiler.cpp index bd4c71f1d4..3bb3ced322 100644 --- a/rpcs3/Emu/Cell/SPURecompiler.cpp +++ b/rpcs3/Emu/Cell/SPURecompiler.cpp @@ -1001,7 +1001,7 @@ const std::vector& spu_recompiler_base::analyse(const be_t* ls, u32 en case spu_itype::DFCEQ: case spu_itype::DFCMEQ: case spu_itype::DFCGT: - //case spu_itype::DFCMGT: + case spu_itype::DFCMGT: case spu_itype::DFTSV: { // Stop before invalid instructions (TODO) @@ -3706,7 +3706,7 @@ public: case spu_itype::DFCEQ: case spu_itype::DFCMEQ: case spu_itype::DFCGT: - //case spu_itype::DFCMGT: + case spu_itype::DFCMGT: case spu_itype::DFTSV: case spu_itype::STOP: case spu_itype::STOPD: @@ -5854,7 +5854,7 @@ public: void DFCMGT(spu_opcode_t op) // { - set_vr(op.rt, sext(fcmp(fabs(get_vr(op.ra)), fabs(get_vr(op.rb))))); + return UNK(op); } void DFCMEQ(spu_opcode_t op) // @@ -6785,7 +6785,13 @@ public: void BISLED(spu_opcode_t op) // { - UNK(op); + if (m_block) m_block->block_end = m_ir->GetInsertBlock(); + const auto addr = eval(extract(get_vr(op.ra), 3) & 0x3fffc); + set_link(op); + value_t res; + res.value = call(&exec_get_events, m_thread); + const auto target = add_block_indirect(op, addr); + m_ir->CreateCondBr(m_ir->CreateICmpNE(res.value, m_ir->getInt32(0)), target, add_block_next()); } void BRZ(spu_opcode_t op) //