diff --git a/src/devices/cpu/mips/mips3.cpp b/src/devices/cpu/mips/mips3.cpp index 279f9404c50..b3c19faf6fa 100644 --- a/src/devices/cpu/mips/mips3.cpp +++ b/src/devices/cpu/mips/mips3.cpp @@ -31,19 +31,26 @@ #define RTVAL64 (m_core->r[RTREG]) #define RDVAL64 (m_core->r[RDREG]) -#define FRVALS_FR0 (((float *)&m_core->cpr[1][0])[FRREG]) -#define FTVALS_FR0 (((float *)&m_core->cpr[1][0])[FTREG]) -#define FSVALS_FR0 (((float *)&m_core->cpr[1][0])[FSREG]) -#define FDVALS_FR0 (((float *)&m_core->cpr[1][0])[FDREG]) -#define FSVALW_FR0 (((UINT32 *)&m_core->cpr[1][0])[FSREG]) -#define FDVALW_FR0 (((UINT32 *)&m_core->cpr[1][0])[FDREG]) +#define FRVALS_FR0 (((float *)&m_core->cpr[1][FRREG])[BYTE_XOR_LE(0)]) +#define FTVALS_FR0 (((float *)&m_core->cpr[1][FTREG])[BYTE_XOR_LE(0)]) +#define FSVALS_FR0 (((float *)&m_core->cpr[1][FSREG])[BYTE_XOR_LE(0)]) +#define FDVALS_FR0 (((float *)&m_core->cpr[1][FDREG])[BYTE_XOR_LE(0)]) +#define FSVALW_FR0 (((UINT32 *)&m_core->cpr[1][FSREG])[BYTE_XOR_LE(0)]) +#define FDVALW_FR0 (((UINT32 *)&m_core->cpr[1][FDREG])[BYTE_XOR_LE(0)]) -#define FRVALD_FR0 (*(double *)&m_core->cpr[1][FRREG/2]) -#define FTVALD_FR0 (*(double *)&m_core->cpr[1][FTREG/2]) -#define FSVALD_FR0 (*(double *)&m_core->cpr[1][FSREG/2]) -#define FDVALD_FR0 (*(double *)&m_core->cpr[1][FDREG/2]) -#define FSVALL_FR0 (((UINT64 *)&m_core->cpr[1][0])[FSREG/2]) -#define FDVALL_FR0 (((UINT64 *)&m_core->cpr[1][0])[FDREG/2]) +#define LFRVALD_FR0 (u2d(get_cop1_reg64(FRREG))) +#define LFTVALD_FR0 (u2d(get_cop1_reg64(FTREG))) +#define LFSVALD_FR0 (u2d(get_cop1_reg64(FSREG))) +#define LFDVALD_FR0 (u2d(get_cop1_reg64(FDREG))) +#define LFSVALL_FR0 (get_cop1_reg64(FSREG)) +#define LFDVALL_FR0 (get_cop1_reg64(FDREG)) + +#define SFRVALD_FR0(x) (set_cop1_reg64(FRREG,d2u((x)))) +#define SFTVALD_FR0(x) (set_cop1_reg64(FTREG,d2u((x)))) +#define SFSVALD_FR0(x) (set_cop1_reg64(FSREG,d2u((x)))) +#define SFDVALD_FR0(x) (set_cop1_reg64(FDREG,d2u((x)))) +#define SFSVALL_FR0(x) (set_cop1_reg64(FSREG,(x))) +#define SFDVALL_FR0(x) (set_cop1_reg64(FDREG,(x))) #define FRVALS_FR1 (((float *)&m_core->cpr[1][FRREG])[BYTE_XOR_LE(0)]) #define FTVALS_FR1 (((float *)&m_core->cpr[1][FTREG])[BYTE_XOR_LE(0)]) @@ -1513,36 +1520,39 @@ void mips3_device::handle_cop0(UINT32 op) inline UINT32 mips3_device::get_cop1_reg32(int idx) { - if (IS_FR0) - return ((UINT32 *)&m_core->cpr[1][0])[idx]; - else + //if (IS_FR0) + // return ((UINT32 *)&m_core->cpr[1][0])[idx]; + //else return m_core->cpr[1][idx]; } inline UINT64 mips3_device::get_cop1_reg64(int idx) { if (IS_FR0) - return ((UINT64 *)&m_core->cpr[1][0])[idx/2]; + return (UINT64(((UINT32 *)&m_core->cpr[1][(idx&0x1E) + 1])[BYTE_XOR_LE(0)])) << 32 + | (UINT64(((UINT32 *)&m_core->cpr[1][idx&0x1E])[BYTE_XOR_LE(0)])); else return m_core->cpr[1][idx]; } inline void mips3_device::set_cop1_reg32(int idx, UINT32 val) { - if (IS_FR0) - ((UINT32 *)&m_core->cpr[1][0])[idx] = val; - else + //if (IS_FR0) + // ((UINT32 *)&m_core->cpr[1][0])[idx] = val; + //else m_core->cpr[1][idx] = val; } inline void mips3_device::set_cop1_reg64(int idx, UINT64 val) { if (IS_FR0) - ((UINT64 *)&m_core->cpr[1][0])[idx/2] = val; + { + ((UINT32 *)&m_core->cpr[1][idx&0x1E])[BYTE_XOR_LE(0)] = val & 0xFFFFFFFF; + ((UINT32 *)&m_core->cpr[1][(idx&0x1E) + 1])[BYTE_XOR_LE(0)] = val >> 32; + } else m_core->cpr[1][idx] = val; } - inline UINT64 mips3_device::get_cop1_creg(int idx) { if (idx == 31) @@ -1606,56 +1616,56 @@ void mips3_device::handle_cop1_fr0(UINT32 op) if (IS_SINGLE(op)) /* ADD.S */ FDVALS_FR0 = FSVALS_FR0 + FTVALS_FR0; else /* ADD.D */ - FDVALD_FR0 = FSVALD_FR0 + FTVALD_FR0; + SFDVALD_FR0(LFSVALD_FR0 + LFTVALD_FR0); break; case 0x01: if (IS_SINGLE(op)) /* SUB.S */ FDVALS_FR0 = FSVALS_FR0 - FTVALS_FR0; else /* SUB.D */ - FDVALD_FR0 = FSVALD_FR0 - FTVALD_FR0; + SFDVALD_FR0(LFSVALD_FR0 - LFTVALD_FR0); break; case 0x02: if (IS_SINGLE(op)) /* MUL.S */ FDVALS_FR0 = FSVALS_FR0 * FTVALS_FR0; else /* MUL.D */ - FDVALD_FR0 = FSVALD_FR0 * FTVALD_FR0; + SFDVALD_FR0(LFSVALD_FR0 * LFTVALD_FR0); break; case 0x03: if (IS_SINGLE(op)) /* DIV.S */ FDVALS_FR0 = FSVALS_FR0 / FTVALS_FR0; else /* DIV.D */ - FDVALD_FR0 = FSVALD_FR0 / FTVALD_FR0; + SFDVALD_FR0(LFSVALD_FR0 / LFTVALD_FR0); break; case 0x04: if (IS_SINGLE(op)) /* SQRT.S */ FDVALS_FR0 = sqrt(FSVALS_FR0); else /* SQRT.D */ - FDVALD_FR0 = sqrt(FSVALD_FR0); + SFDVALD_FR0(sqrt(LFSVALD_FR0)); break; case 0x05: if (IS_SINGLE(op)) /* ABS.S */ FDVALS_FR0 = fabs(FSVALS_FR0); else /* ABS.D */ - FDVALD_FR0 = fabs(FSVALD_FR0); + SFDVALD_FR0(fabs(LFSVALD_FR0)); break; case 0x06: if (IS_SINGLE(op)) /* MOV.S */ FDVALS_FR0 = FSVALS_FR0; else /* MOV.D */ - FDVALD_FR0 = FSVALD_FR0; + SFDVALD_FR0(LFSVALD_FR0); break; case 0x07: if (IS_SINGLE(op)) /* NEG.S */ FDVALS_FR0 = -FSVALS_FR0; else /* NEG.D */ - FDVALD_FR0 = -FSVALD_FR0; + SFDVALD_FR0(-LFSVALD_FR0); break; case 0x08: @@ -1666,16 +1676,16 @@ void mips3_device::handle_cop1_fr0(UINT32 op) temp = ceil(temp - 0.5); else temp = floor(temp + 0.5); - FDVALL_FR0 = (INT64)temp; + SFDVALL_FR0((INT64)temp); } else /* ROUND.L.D */ { - double temp = FSVALD_FR0; + double temp = LFSVALD_FR0; if (temp < 0) temp = ceil(temp - 0.5); else temp = floor(temp + 0.5); - FDVALL_FR0 = (INT64)temp; + SFDVALL_FR0((INT64)temp); } break; @@ -1687,16 +1697,16 @@ void mips3_device::handle_cop1_fr0(UINT32 op) temp = ceil(temp); else temp = floor(temp); - FDVALL_FR0 = (INT64)temp; + SFDVALL_FR0((INT64)temp); } else /* TRUNC.L.D */ { - double temp = FSVALD_FR0; + double temp = LFSVALD_FR0; if (temp < 0) temp = ceil(temp); else temp = floor(temp); - FDVALL_FR0 = (INT64)temp; + SFDVALL_FR0((INT64)temp); } break; @@ -1704,16 +1714,16 @@ void mips3_device::handle_cop1_fr0(UINT32 op) if (IS_SINGLE(op)) /* CEIL.L.S */ dtemp = ceil(FSVALS_FR0); else /* CEIL.L.D */ - dtemp = ceil(FSVALD_FR0); - FDVALL_FR0 = (INT64)dtemp; + dtemp = ceil(LFSVALD_FR0); + SFDVALL_FR0((INT64)dtemp); break; case 0x0b: if (IS_SINGLE(op)) /* FLOOR.L.S */ dtemp = floor(FSVALS_FR0); else /* FLOOR.L.D */ - dtemp = floor(FSVALD_FR0); - FDVALL_FR0 = (INT64)dtemp; + dtemp = floor(LFSVALD_FR0); + SFDVALL_FR0((INT64)dtemp); break; case 0x0c: @@ -1728,7 +1738,7 @@ void mips3_device::handle_cop1_fr0(UINT32 op) } else /* ROUND.W.D */ { - dtemp = FSVALD_FR0; + dtemp = LFSVALD_FR0; if (dtemp < 0) dtemp = ceil(dtemp - 0.5); else @@ -1749,7 +1759,7 @@ void mips3_device::handle_cop1_fr0(UINT32 op) } else /* TRUNC.W.D */ { - dtemp = FSVALD_FR0; + dtemp = LFSVALD_FR0; if (dtemp < 0) dtemp = ceil(dtemp); else @@ -1762,7 +1772,7 @@ void mips3_device::handle_cop1_fr0(UINT32 op) if (IS_SINGLE(op)) /* CEIL.W.S */ dtemp = ceil(FSVALS_FR0); else /* CEIL.W.D */ - dtemp = ceil(FSVALD_FR0); + dtemp = ceil(LFSVALD_FR0); FDVALW_FR0 = (INT32)dtemp; break; @@ -1770,7 +1780,7 @@ void mips3_device::handle_cop1_fr0(UINT32 op) if (IS_SINGLE(op)) /* FLOOR.W.S */ dtemp = floor(FSVALS_FR0); else /* FLOOR.W.D */ - dtemp = floor(FSVALD_FR0); + dtemp = floor(LFSVALD_FR0); FDVALW_FR0 = (INT32)dtemp; break; @@ -1780,7 +1790,7 @@ void mips3_device::handle_cop1_fr0(UINT32 op) if (IS_SINGLE(op)) /* MOVT/F.S */ FDVALS_FR0 = FSVALS_FR0; else /* MOVT/F.D */ - FDVALD_FR0 = FSVALD_FR0; + SFDVALD_FR0(LFSVALD_FR0); } break; @@ -1790,7 +1800,7 @@ void mips3_device::handle_cop1_fr0(UINT32 op) if (IS_SINGLE(op)) /* MOVZ.S */ FDVALS_FR0 = FSVALS_FR0; else /* MOVZ.D */ - FDVALD_FR0 = FSVALD_FR0; + SFDVALD_FR0(LFSVALD_FR0); } break; @@ -1800,7 +1810,7 @@ void mips3_device::handle_cop1_fr0(UINT32 op) if (IS_SINGLE(op)) /* MOVN.S */ FDVALS_FR0 = FSVALS_FR0; else /* MOVN.D */ - FDVALD_FR0 = FSVALD_FR0; + SFDVALD_FR0(LFSVALD_FR0); } break; @@ -1808,14 +1818,14 @@ void mips3_device::handle_cop1_fr0(UINT32 op) if (IS_SINGLE(op)) /* RECIP.S */ FDVALS_FR0 = 1.0f / FSVALS_FR0; else /* RECIP.D */ - FDVALD_FR0 = 1.0 / FSVALD_FR0; + SFDVALD_FR0(1.0 / LFSVALD_FR0); break; case 0x16: /* R5000 */ if (IS_SINGLE(op)) /* RSQRT.S */ FDVALS_FR0 = 1.0f / sqrt(FSVALS_FR0); else /* RSQRT.D */ - FDVALD_FR0 = 1.0 / sqrt(FSVALD_FR0); + SFDVALD_FR0(1.0 / sqrt(LFSVALD_FR0)); break; case 0x20: @@ -1824,36 +1834,36 @@ void mips3_device::handle_cop1_fr0(UINT32 op) if (IS_SINGLE(op)) /* CVT.S.W */ FDVALS_FR0 = (INT32)FSVALW_FR0; else /* CVT.S.L */ - FDVALS_FR0 = (INT64)FSVALL_FR0; + FDVALS_FR0 = (INT64)LFSVALL_FR0; } else /* CVT.S.D */ - FDVALS_FR0 = FSVALD_FR0; + FDVALS_FR0 = LFSVALD_FR0; break; case 0x21: if (IS_INTEGRAL(op)) { if (IS_SINGLE(op)) /* CVT.D.W */ - FDVALD_FR0 = (INT32)FSVALW_FR0; + SFDVALD_FR0((INT32)FSVALW_FR0); else /* CVT.D.L */ - FDVALD_FR0 = (INT64)FSVALL_FR0; + SFDVALD_FR0((INT64)LFSVALL_FR0); } else /* CVT.D.S */ - FDVALD_FR0 = FSVALS_FR0; + SFDVALD_FR0(FSVALS_FR0); break; case 0x24: if (IS_SINGLE(op)) /* CVT.W.S */ FDVALW_FR0 = (INT32)FSVALS_FR0; else - FDVALW_FR0 = (INT32)FSVALD_FR0; + FDVALW_FR0 = (INT32)LFSVALD_FR0; break; case 0x25: if (IS_SINGLE(op)) /* CVT.L.S */ - FDVALL_FR0 = (INT64)FSVALS_FR0; + SFDVALL_FR0((INT64)FSVALS_FR0); else /* CVT.L.D */ - FDVALL_FR0 = (INT64)FSVALD_FR0; + SFDVALL_FR0((INT64)LFSVALD_FR0); break; case 0x30: @@ -1877,7 +1887,7 @@ void mips3_device::handle_cop1_fr0(UINT32 op) if (IS_SINGLE(op)) /* C.EQ.S */ SET_FCC((op >> 8) & 7, (FSVALS_FR0 == FTVALS_FR0)); else /* C.EQ.D */ - SET_FCC((op >> 8) & 7, (FSVALD_FR0 == FTVALD_FR0)); + SET_FCC((op >> 8) & 7, (LFSVALD_FR0 == LFTVALD_FR0)); break; case 0x33: @@ -1885,7 +1895,7 @@ void mips3_device::handle_cop1_fr0(UINT32 op) if (IS_SINGLE(op)) /* C.UEQ.S */ SET_FCC((op >> 8) & 7, (FSVALS_FR0 == FTVALS_FR0)); else /* C.UEQ.D */ - SET_FCC((op >> 8) & 7, (FSVALD_FR0 == FTVALD_FR0)); + SET_FCC((op >> 8) & 7, (LFSVALD_FR0 == LFTVALD_FR0)); break; case 0x34: @@ -1893,7 +1903,7 @@ void mips3_device::handle_cop1_fr0(UINT32 op) if (IS_SINGLE(op)) /* C.OLT.S */ SET_FCC((op >> 8) & 7, (FSVALS_FR0 < FTVALS_FR0)); else /* C.OLT.D */ - SET_FCC((op >> 8) & 7, (FSVALD_FR0 < FTVALD_FR0)); + SET_FCC((op >> 8) & 7, (LFSVALD_FR0 < LFTVALD_FR0)); break; case 0x35: @@ -1901,7 +1911,7 @@ void mips3_device::handle_cop1_fr0(UINT32 op) if (IS_SINGLE(op)) /* C.ULT.S */ SET_FCC((op >> 8) & 7, (FSVALS_FR0 < FTVALS_FR0)); else /* C.ULT.D */ - SET_FCC((op >> 8) & 7, (FSVALD_FR0 < FTVALD_FR0)); + SET_FCC((op >> 8) & 7, (LFSVALD_FR0 < LFTVALD_FR0)); break; case 0x36: @@ -1909,7 +1919,7 @@ void mips3_device::handle_cop1_fr0(UINT32 op) if (IS_SINGLE(op)) /* C.OLE.S */ SET_FCC((op >> 8) & 7, (FSVALS_FR0 <= FTVALS_FR0)); else /* C.OLE.D */ - SET_FCC((op >> 8) & 7, (FSVALD_FR0 <= FTVALD_FR0)); + SET_FCC((op >> 8) & 7, (LFSVALD_FR0 <= LFTVALD_FR0)); break; case 0x37: @@ -1917,7 +1927,7 @@ void mips3_device::handle_cop1_fr0(UINT32 op) if (IS_SINGLE(op)) /* C.ULE.S */ SET_FCC((op >> 8) & 7, (FSVALS_FR0 <= FTVALS_FR0)); else /* C.ULE.D */ - SET_FCC((op >> 8) & 7, (FSVALD_FR0 <= FTVALD_FR0)); + SET_FCC((op >> 8) & 7, (LFSVALD_FR0 <= LFTVALD_FR0)); break; default: @@ -2311,7 +2321,7 @@ void mips3_device::handle_cop1x_fr0(UINT32 op) break; case 0x01: /* LDXC1 */ - if (RDOUBLE(RSVAL32 + RTVAL32, &temp64)) FDVALL_FR0 = temp64; + if (RDOUBLE(RSVAL32 + RTVAL32, &temp64)) SFDVALL_FR0(temp64); break; case 0x08: /* SWXC1 */ @@ -2330,7 +2340,7 @@ void mips3_device::handle_cop1x_fr0(UINT32 op) break; case 0x21: /* MADD.D */ - FDVALD_FR0 = FSVALD_FR0 * FTVALD_FR0 + FRVALD_FR0; + SFDVALD_FR0(LFSVALD_FR0 * LFTVALD_FR0 + LFRVALD_FR0); break; case 0x28: /* MSUB.S */ @@ -2338,7 +2348,7 @@ void mips3_device::handle_cop1x_fr0(UINT32 op) break; case 0x29: /* MSUB.D */ - FDVALD_FR0 = FSVALD_FR0 * FTVALD_FR0 - FRVALD_FR0; + SFDVALD_FR0(LFSVALD_FR0 * LFTVALD_FR0 - LFRVALD_FR0); break; case 0x30: /* NMADD.S */ @@ -2346,7 +2356,7 @@ void mips3_device::handle_cop1x_fr0(UINT32 op) break; case 0x31: /* NMADD.D */ - FDVALD_FR0 = -(FSVALD_FR0 * FTVALD_FR0 + FRVALD_FR0); + SFDVALD_FR0(-(LFSVALD_FR0 * LFTVALD_FR0 + LFRVALD_FR0)); break; case 0x38: /* NMSUB.S */ @@ -2354,7 +2364,7 @@ void mips3_device::handle_cop1x_fr0(UINT32 op) break; case 0x39: /* NMSUB.D */ - FDVALD_FR0 = -(FSVALD_FR0 * FTVALD_FR0 - FRVALD_FR0); + SFDVALD_FR0(-(LFSVALD_FR0 * LFTVALD_FR0 - LFRVALD_FR0)); break; case 0x24: /* MADD.W */