trunk/src/emu/cpu/rsp/rspdrc.c
r241690 | r241691 | |
6592 | 6592 | } |
6593 | 6593 | #endif |
6594 | 6594 | |
| 6595 | // VRSQ |
| 6596 | // |
| 6597 | // 31 25 24 20 15 10 5 0 |
| 6598 | // ------------------------------------------------------ |
| 6599 | // | 010010 | 1 | EEEE | SSSSS | ?FFFF | DDDDD | 110100 | |
| 6600 | // ------------------------------------------------------ |
| 6601 | // |
| 6602 | // Calculates reciprocal square-root |
| 6603 | |
| 6604 | inline void rsp_device::ccfunc_rsp_vrsq_scalar() |
| 6605 | { |
| 6606 | int op = m_rsp_state->arg0; |
| 6607 | |
| 6608 | INT32 shifter = 0; |
| 6609 | INT32 rec = (INT16)VREG_S(VS2REG, EL & 7); |
| 6610 | INT32 datainput = (rec < 0) ? (-rec) : (rec); |
| 6611 | |
| 6612 | if (rec < 0) |
| 6613 | { |
| 6614 | if (rec < -32768) |
| 6615 | { |
| 6616 | datainput = ~datainput; |
| 6617 | } |
| 6618 | else |
| 6619 | { |
| 6620 | datainput = -datainput; |
| 6621 | } |
| 6622 | } |
| 6623 | |
| 6624 | if (datainput) |
| 6625 | { |
| 6626 | for (int i = 0; i < 32; i++) |
| 6627 | { |
| 6628 | if (datainput & (1 << ((~i) & 0x1f))) |
| 6629 | { |
| 6630 | shifter = i; |
| 6631 | break; |
| 6632 | } |
| 6633 | } |
| 6634 | } |
| 6635 | else |
| 6636 | { |
| 6637 | shifter = 0; |
| 6638 | } |
| 6639 | |
| 6640 | INT32 address = ((datainput << shifter) & 0x7fc00000) >> 22; |
| 6641 | address = ((address | 0x200) & 0x3fe) | (shifter & 1); |
| 6642 | |
| 6643 | INT32 fetchval = rsp_divtable[address]; |
| 6644 | INT32 temp = (0x40000000 | (fetchval << 14)) >> (((~shifter) & 0x1f) >> 1); |
| 6645 | if (rec < 0) |
| 6646 | { |
| 6647 | temp = ~temp; |
| 6648 | } |
| 6649 | if (!rec) |
| 6650 | { |
| 6651 | temp = 0x7fffffff; |
| 6652 | } |
| 6653 | else if (rec == 0xffff8000) |
| 6654 | { |
| 6655 | temp = 0xffff0000; |
| 6656 | } |
| 6657 | rec = temp; |
| 6658 | |
| 6659 | if (rec < 0) |
| 6660 | { |
| 6661 | if (m_dp_allowed) |
| 6662 | { |
| 6663 | if (rec < -32768) |
| 6664 | { |
| 6665 | datainput = ~datainput; |
| 6666 | } |
| 6667 | else |
| 6668 | { |
| 6669 | datainput = -datainput; |
| 6670 | } |
| 6671 | } |
| 6672 | else |
| 6673 | { |
| 6674 | datainput = -datainput; |
| 6675 | } |
| 6676 | } |
| 6677 | |
| 6678 | if (datainput) |
| 6679 | { |
| 6680 | for (int i = 0; i < 32; i++) |
| 6681 | { |
| 6682 | if (datainput & (1 << ((~i) & 0x1f))) |
| 6683 | { |
| 6684 | shifter = i; |
| 6685 | break; |
| 6686 | } |
| 6687 | } |
| 6688 | } |
| 6689 | else |
| 6690 | { |
| 6691 | shifter = 0; |
| 6692 | } |
| 6693 | |
| 6694 | address = ((datainput << shifter) & 0x7fc00000) >> 22; |
| 6695 | address = ((address | 0x200) & 0x3fe) | (shifter & 1); |
| 6696 | |
| 6697 | fetchval = rsp_divtable[address]; |
| 6698 | temp = (0x40000000 | (fetchval << 14)) >> (((~shifter) & 0x1f) >> 1); |
| 6699 | if (rec < 0) |
| 6700 | { |
| 6701 | temp = ~temp; |
| 6702 | } |
| 6703 | if (!rec) |
| 6704 | { |
| 6705 | temp = 0x7fff; |
| 6706 | } |
| 6707 | else if (rec == 0xffff8000) |
| 6708 | { |
| 6709 | temp = 0x0000; |
| 6710 | } |
| 6711 | rec = temp; |
| 6712 | |
| 6713 | W_VREG_S(VDREG, VS1REG & 7) = (UINT16)rec; |
| 6714 | for (int i = 0; i < 8; i++) |
| 6715 | { |
| 6716 | SET_ACCUM_L(VREG_S(VS2REG, VEC_EL_2(EL, i)), i); |
| 6717 | } |
| 6718 | } |
| 6719 | |
| 6720 | static void cfunc_rsp_vrsq_scalar(void *param) |
| 6721 | { |
| 6722 | ((rsp_device *)param)->ccfunc_rsp_vrsq_scalar(); |
| 6723 | } |
| 6724 | |
6595 | 6725 | #if USE_SIMD |
6596 | 6726 | // VRSQL |
6597 | 6727 | // |
r241690 | r241691 | |
7835 | 7965 | #endif |
7836 | 7966 | return TRUE; |
7837 | 7967 | |
| 7968 | case 0x34: /* VRSQ */ |
| 7969 | UML_MOV(block, mem(&m_rsp_state->arg0), desc->opptr.l[0]); // mov [arg0],desc->opptr.l |
| 7970 | UML_CALLC_block, cfunc_rsp_vrsq_scalar, this); |
| 7971 | return TRUE; |
| 7972 | |
7838 | 7973 | case 0x35: /* VRSQL */ |
7839 | 7974 | UML_MOV(block, mem(&m_rsp_state->arg0), desc->opptr.l[0]); // mov [arg0],desc->opptr.l |
7840 | 7975 | UML_CALLC(block, cfunc_rsp_vrsql_simd, this); |
r241690 | r241691 | |
7857 | 7992 | #endif |
7858 | 7993 | return TRUE; |
7859 | 7994 | |
| 7995 | case 0x37: /* VNOP */ |
| 7996 | case 0x3F: /* VNULL */ |
| 7997 | return TRUE; |
| 7998 | |
7860 | 7999 | default: |
7861 | 8000 | UML_MOV(block, mem(&m_rsp_state->arg0), desc->opptr.l[0]); // mov [arg0],desc->opptr.l |
7862 | 8001 | UML_CALLC(block, cfunc_unimplemented_opcode, this); |
r241690 | r241691 | |
8057 | 8196 | UML_CALLC(block, cfunc_rsp_vmov_scalar, this); |
8058 | 8197 | return TRUE; |
8059 | 8198 | |
| 8199 | case 0x34: /* VRSQ */ |
| 8200 | UML_MOV(block, mem(&m_rsp_state->arg0), desc->opptr.l[0]); // mov [arg0],desc->opptr.l |
| 8201 | UML_CALLC(block, cfunc_rsp_vrsq_scalar, this); |
| 8202 | return TRUE; |
| 8203 | |
8060 | 8204 | case 0x35: /* VRSQL */ |
8061 | 8205 | UML_MOV(block, mem(&m_rsp_state->arg0), desc->opptr.l[0]); // mov [arg0],desc->opptr.l |
8062 | 8206 | UML_CALLC(block, cfunc_rsp_vrsql_scalar, this); |
r241690 | r241691 | |
8067 | 8211 | UML_CALLC(block, cfunc_rsp_vrsqh_scalar, this); |
8068 | 8212 | return TRUE; |
8069 | 8213 | |
| 8214 | case 0x37: /* VNOP */ |
| 8215 | case 0x3F: /* VNULL */ |
| 8216 | return TRUE; |
| 8217 | |
8070 | 8218 | default: |
8071 | 8219 | UML_MOV(block, mem(&m_rsp_state->arg0), desc->opptr.l[0]); // mov [arg0],desc->opptr.l |
8072 | 8220 | UML_CALLC(block, cfunc_unimplemented_opcode, this); |