From e3680d1c8f873c827b8cdb00345a8e0f24e5e150 Mon Sep 17 00:00:00 2001 From: mooglyguy Date: Mon, 3 Nov 2014 21:18:39 +0100 Subject: rsp: Add VNOP, VNULL, and VRSQ instructions. [MooglyGuy] --- src/emu/cpu/rsp/rsp.h | 1 + src/emu/cpu/rsp/rspdrc.c | 148 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 149 insertions(+) diff --git a/src/emu/cpu/rsp/rsp.h b/src/emu/cpu/rsp/rsp.h index 7c29e22dfa8..6459b0d8c6d 100644 --- a/src/emu/cpu/rsp/rsp.h +++ b/src/emu/cpu/rsp/rsp.h @@ -325,6 +325,7 @@ public: void ccfunc_mtc2_scalar(); void ccfunc_ctc2_scalar(); #endif + void ccfunc_rsp_vrsq_scalar(); #if USE_SIMD && SIMUL_SIMD void ccfunc_backup_regs(); void ccfunc_restore_regs(); diff --git a/src/emu/cpu/rsp/rspdrc.c b/src/emu/cpu/rsp/rspdrc.c index 6541e4d95df..18e8d301463 100644 --- a/src/emu/cpu/rsp/rspdrc.c +++ b/src/emu/cpu/rsp/rspdrc.c @@ -6592,6 +6592,136 @@ static void cfunc_rsp_vmov_scalar(void *param) } #endif +// VRSQ +// +// 31 25 24 20 15 10 5 0 +// ------------------------------------------------------ +// | 010010 | 1 | EEEE | SSSSS | ?FFFF | DDDDD | 110100 | +// ------------------------------------------------------ +// +// Calculates reciprocal square-root + +inline void rsp_device::ccfunc_rsp_vrsq_scalar() +{ + int op = m_rsp_state->arg0; + + INT32 shifter = 0; + INT32 rec = (INT16)VREG_S(VS2REG, EL & 7); + INT32 datainput = (rec < 0) ? (-rec) : (rec); + + if (rec < 0) + { + if (rec < -32768) + { + datainput = ~datainput; + } + else + { + datainput = -datainput; + } + } + + if (datainput) + { + for (int i = 0; i < 32; i++) + { + if (datainput & (1 << ((~i) & 0x1f))) + { + shifter = i; + break; + } + } + } + else + { + shifter = 0; + } + + INT32 address = ((datainput << shifter) & 0x7fc00000) >> 22; + address = ((address | 0x200) & 0x3fe) | (shifter & 1); + + INT32 fetchval = rsp_divtable[address]; + INT32 temp = (0x40000000 | (fetchval << 14)) >> (((~shifter) & 0x1f) >> 1); + if (rec < 0) + { + temp = ~temp; + } + if (!rec) + { + temp = 0x7fffffff; + } + else if (rec == 0xffff8000) + { + temp = 0xffff0000; + } + rec = temp; + + if (rec < 0) + { + if (m_dp_allowed) + { + if (rec < -32768) + { + datainput = ~datainput; + } + else + { + datainput = -datainput; + } + } + else + { + datainput = -datainput; + } + } + + if (datainput) + { + for (int i = 0; i < 32; i++) + { + if (datainput & (1 << ((~i) & 0x1f))) + { + shifter = i; + break; + } + } + } + else + { + shifter = 0; + } + + address = ((datainput << shifter) & 0x7fc00000) >> 22; + address = ((address | 0x200) & 0x3fe) | (shifter & 1); + + fetchval = rsp_divtable[address]; + temp = (0x40000000 | (fetchval << 14)) >> (((~shifter) & 0x1f) >> 1); + if (rec < 0) + { + temp = ~temp; + } + if (!rec) + { + temp = 0x7fff; + } + else if (rec == 0xffff8000) + { + temp = 0x0000; + } + rec = temp; + + W_VREG_S(VDREG, VS1REG & 7) = (UINT16)rec; + for (int i = 0; i < 8; i++) + { + SET_ACCUM_L(VREG_S(VS2REG, VEC_EL_2(EL, i)), i); + } +} + +static void cfunc_rsp_vrsq_scalar(void *param) +{ + ((rsp_device *)param)->ccfunc_rsp_vrsq_scalar(); +} + #if USE_SIMD // VRSQL // @@ -7835,6 +7965,11 @@ int rsp_device::generate_vector_opcode(drcuml_block *block, compiler_state *comp #endif return TRUE; + case 0x34: /* VRSQ */ + UML_MOV(block, mem(&m_rsp_state->arg0), desc->opptr.l[0]); // mov [arg0],desc->opptr.l + UML_CALLC_block, cfunc_rsp_vrsq_scalar, this); + return TRUE; + case 0x35: /* VRSQL */ UML_MOV(block, mem(&m_rsp_state->arg0), desc->opptr.l[0]); // mov [arg0],desc->opptr.l UML_CALLC(block, cfunc_rsp_vrsql_simd, this); @@ -7857,6 +7992,10 @@ int rsp_device::generate_vector_opcode(drcuml_block *block, compiler_state *comp #endif return TRUE; + case 0x37: /* VNOP */ + case 0x3F: /* VNULL */ + return TRUE; + default: UML_MOV(block, mem(&m_rsp_state->arg0), desc->opptr.l[0]); // mov [arg0],desc->opptr.l UML_CALLC(block, cfunc_unimplemented_opcode, this); @@ -8057,6 +8196,11 @@ int rsp_device::generate_vector_opcode(drcuml_block *block, compiler_state *comp UML_CALLC(block, cfunc_rsp_vmov_scalar, this); return TRUE; + case 0x34: /* VRSQ */ + UML_MOV(block, mem(&m_rsp_state->arg0), desc->opptr.l[0]); // mov [arg0],desc->opptr.l + UML_CALLC(block, cfunc_rsp_vrsq_scalar, this); + return TRUE; + case 0x35: /* VRSQL */ UML_MOV(block, mem(&m_rsp_state->arg0), desc->opptr.l[0]); // mov [arg0],desc->opptr.l UML_CALLC(block, cfunc_rsp_vrsql_scalar, this); @@ -8067,6 +8211,10 @@ int rsp_device::generate_vector_opcode(drcuml_block *block, compiler_state *comp UML_CALLC(block, cfunc_rsp_vrsqh_scalar, this); return TRUE; + case 0x37: /* VNOP */ + case 0x3F: /* VNULL */ + return TRUE; + default: UML_MOV(block, mem(&m_rsp_state->arg0), desc->opptr.l[0]); // mov [arg0],desc->opptr.l UML_CALLC(block, cfunc_unimplemented_opcode, this); -- cgit v1.2.3