mirror of https://github.com/RPCS3/rpcs3.git
SPU: Implement BISLED
DFCMGT instruction removed, it was wrong to add to begin with ASMJIT: Fix compilation of double compare instructions, move exception to runtime instead of compiletime! Jarves confirmed that he implemented this instruction because of that bug with asmjit only, affected God Of War 3
This commit is contained in:
parent
b307aff9eb
commit
969af86eba
|
@ -1,4 +1,4 @@
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "Emu/Memory/vm.h"
|
#include "Emu/Memory/vm.h"
|
||||||
#include "Emu/System.h"
|
#include "Emu/System.h"
|
||||||
#include "Emu/IdManager.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)
|
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)
|
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)
|
void spu_recompiler::DFCGT(spu_opcode_t op)
|
||||||
{
|
{
|
||||||
fmt::throw_exception("Unexpected instruction" HERE);
|
UNK(op);
|
||||||
}
|
}
|
||||||
|
|
||||||
void spu_recompiler::FA(spu_opcode_t 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)
|
void spu_recompiler::DFCMGT(spu_opcode_t op)
|
||||||
{
|
{
|
||||||
const auto mask = XmmConst(_mm_set1_epi64x(0x7fffffffffffffff));
|
UNK(op);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void spu_recompiler::DFA(spu_opcode_t 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)
|
void spu_recompiler::DFTSV(spu_opcode_t op)
|
||||||
{
|
{
|
||||||
fmt::throw_exception("Unexpected instruction" HERE);
|
UNK(op);
|
||||||
}
|
}
|
||||||
|
|
||||||
void spu_recompiler::FCEQ(spu_opcode_t 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)
|
void spu_recompiler::DFCEQ(spu_opcode_t op)
|
||||||
{
|
{
|
||||||
fmt::throw_exception("Unexpected instruction" HERE);
|
UNK(op);
|
||||||
}
|
}
|
||||||
|
|
||||||
void spu_recompiler::MPY(spu_opcode_t 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)
|
void spu_recompiler::DFCMEQ(spu_opcode_t op)
|
||||||
{
|
{
|
||||||
fmt::throw_exception("Unexpected instruction" HERE);
|
UNK(op);
|
||||||
}
|
}
|
||||||
|
|
||||||
void spu_recompiler::MPYU(spu_opcode_t op)
|
void spu_recompiler::MPYU(spu_opcode_t op)
|
||||||
|
|
|
@ -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)
|
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;
|
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)
|
bool spu_interpreter::DFCMGT(spu_thread& spu, spu_opcode_t op)
|
||||||
{
|
{
|
||||||
const auto mask = _mm_castsi128_pd(_mm_set1_epi64x(0x7fffffffffffffff));
|
fmt::throw_exception("Unexpected Instruction" HERE);
|
||||||
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);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1001,7 +1001,7 @@ const std::vector<u32>& spu_recompiler_base::analyse(const be_t<u32>* ls, u32 en
|
||||||
case spu_itype::DFCEQ:
|
case spu_itype::DFCEQ:
|
||||||
case spu_itype::DFCMEQ:
|
case spu_itype::DFCMEQ:
|
||||||
case spu_itype::DFCGT:
|
case spu_itype::DFCGT:
|
||||||
//case spu_itype::DFCMGT:
|
case spu_itype::DFCMGT:
|
||||||
case spu_itype::DFTSV:
|
case spu_itype::DFTSV:
|
||||||
{
|
{
|
||||||
// Stop before invalid instructions (TODO)
|
// Stop before invalid instructions (TODO)
|
||||||
|
@ -3706,7 +3706,7 @@ public:
|
||||||
case spu_itype::DFCEQ:
|
case spu_itype::DFCEQ:
|
||||||
case spu_itype::DFCMEQ:
|
case spu_itype::DFCMEQ:
|
||||||
case spu_itype::DFCGT:
|
case spu_itype::DFCGT:
|
||||||
//case spu_itype::DFCMGT:
|
case spu_itype::DFCMGT:
|
||||||
case spu_itype::DFTSV:
|
case spu_itype::DFTSV:
|
||||||
case spu_itype::STOP:
|
case spu_itype::STOP:
|
||||||
case spu_itype::STOPD:
|
case spu_itype::STOPD:
|
||||||
|
@ -5854,7 +5854,7 @@ public:
|
||||||
|
|
||||||
void DFCMGT(spu_opcode_t op) //
|
void DFCMGT(spu_opcode_t op) //
|
||||||
{
|
{
|
||||||
set_vr(op.rt, sext<u64[2]>(fcmp<llvm::FCmpInst::FCMP_OGT>(fabs(get_vr<f64[2]>(op.ra)), fabs(get_vr<f64[2]>(op.rb)))));
|
return UNK(op);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DFCMEQ(spu_opcode_t op) //
|
void DFCMEQ(spu_opcode_t op) //
|
||||||
|
@ -6785,7 +6785,13 @@ public:
|
||||||
|
|
||||||
void BISLED(spu_opcode_t op) //
|
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<u32> 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) //
|
void BRZ(spu_opcode_t op) //
|
||||||
|
|
Loading…
Reference in New Issue