diff --git a/src/devices/cpu/mips/mips3.cpp b/src/devices/cpu/mips/mips3.cpp index 86f823bafdc..d2153b7b6e1 100644 --- a/src/devices/cpu/mips/mips3.cpp +++ b/src/devices/cpu/mips/mips3.cpp @@ -28,26 +28,19 @@ #define RTVAL64 (m_core->r[RTREG]) #define RDVAL64 (m_core->r[RDREG]) -#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_t *)&m_core->cpr[1][FSREG])[BYTE_XOR_LE(0)]) -#define FDVALW_FR0 (((uint32_t *)&m_core->cpr[1][FDREG])[BYTE_XOR_LE(0)]) +#define FRVALS_FR0 (((float *)&m_core->cpr[1][FRREG & 0x1E])[BYTE_XOR_LE(FRREG & 1)]) +#define FTVALS_FR0 (((float *)&m_core->cpr[1][FTREG & 0x1E])[BYTE_XOR_LE(FTREG & 1)]) +#define FSVALS_FR0 (((float *)&m_core->cpr[1][FSREG & 0x1E])[BYTE_XOR_LE(FSREG & 1)]) +#define FDVALS_FR0 (((float *)&m_core->cpr[1][FDREG & 0x1E])[BYTE_XOR_LE(FDREG & 1)]) +#define FSVALW_FR0 (((uint32_t *)&m_core->cpr[1][FSREG & 0x1E])[BYTE_XOR_LE(FSREG & 1)]) +#define FDVALW_FR0 (((uint32_t *)&m_core->cpr[1][FDREG & 0x1E])[BYTE_XOR_LE(FDREG & 1)]) -#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 FRVALD_FR0 (*(double *)&m_core->cpr[1][FRREG & 0x1E]) +#define FTVALD_FR0 (*(double *)&m_core->cpr[1][FTREG & 0x1E]) +#define FSVALD_FR0 (*(double *)&m_core->cpr[1][FSREG & 0x1E]) +#define FDVALD_FR0 (*(double *)&m_core->cpr[1][FDREG & 0x1E]) +#define FSVALL_FR0 (*(uint64_t *)&m_core->cpr[1][FSREG & 0x1E]) +#define FDVALL_FR0 (*(uint64_t *)&m_core->cpr[1][FDREG & 0x1E]) #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)]) @@ -1516,35 +1509,34 @@ void mips3_device::handle_cop0(uint32_t op) inline uint32_t mips3_device::get_cop1_reg32(int idx) { - return m_core->cpr[1][idx]; + if (IS_FR0) + return ((uint32_t *)&m_core->cpr[1][idx & 0x1E])[idx & 1]; + else + return m_core->cpr[1][idx]; } inline uint64_t mips3_device::get_cop1_reg64(int idx) { if (IS_FR0) - return (uint64_t(((uint32_t *)&m_core->cpr[1][(idx&0x1E) + 1])[BYTE_XOR_LE(0)])) << 32 - | (uint64_t(((uint32_t *)&m_core->cpr[1][idx&0x1E])[BYTE_XOR_LE(0)])); - else - return m_core->cpr[1][idx]; + idx &= 0x1E; + return m_core->cpr[1][idx]; } inline void mips3_device::set_cop1_reg32(int idx, uint32_t val) { - m_core->cpr[1][idx] = val; + if (IS_FR0) + ((uint32_t *)&m_core->cpr[1][idx & 0x1E])[idx & 1] = val; + else + m_core->cpr[1][idx] = val; } inline void mips3_device::set_cop1_reg64(int idx, uint64_t val) { if (IS_FR0) - { - ((uint32_t *)&m_core->cpr[1][idx&0x1E])[BYTE_XOR_LE(0)] = val & 0xFFFFFFFF; - ((uint32_t *)&m_core->cpr[1][(idx&0x1E) + 1])[BYTE_XOR_LE(0)] = val >> 32; - } - else - { - m_core->cpr[1][idx] = val; - } + idx &= 0x1E; + m_core->cpr[1][idx] = val; } + inline uint64_t mips3_device::get_cop1_creg(int idx) { if (idx == 31) @@ -1609,56 +1601,56 @@ void mips3_device::handle_cop1_fr0(uint32_t op) if (IS_SINGLE(op)) /* ADD.S */ FDVALS_FR0 = FSVALS_FR0 + FTVALS_FR0; else /* ADD.D */ - SFDVALD_FR0(LFSVALD_FR0 + LFTVALD_FR0); + FDVALD_FR0 = FSVALD_FR0 + FTVALD_FR0; break; case 0x01: if (IS_SINGLE(op)) /* SUB.S */ FDVALS_FR0 = FSVALS_FR0 - FTVALS_FR0; else /* SUB.D */ - SFDVALD_FR0(LFSVALD_FR0 - LFTVALD_FR0); + FDVALD_FR0 = FSVALD_FR0 - FTVALD_FR0; break; case 0x02: if (IS_SINGLE(op)) /* MUL.S */ FDVALS_FR0 = FSVALS_FR0 * FTVALS_FR0; else /* MUL.D */ - SFDVALD_FR0(LFSVALD_FR0 * LFTVALD_FR0); + FDVALD_FR0 = FSVALD_FR0 * FTVALD_FR0; break; case 0x03: if (IS_SINGLE(op)) /* DIV.S */ FDVALS_FR0 = FSVALS_FR0 / FTVALS_FR0; else /* DIV.D */ - SFDVALD_FR0(LFSVALD_FR0 / LFTVALD_FR0); + FDVALD_FR0 = FSVALD_FR0 / FTVALD_FR0; break; case 0x04: if (IS_SINGLE(op)) /* SQRT.S */ FDVALS_FR0 = sqrt(FSVALS_FR0); else /* SQRT.D */ - SFDVALD_FR0(sqrt(LFSVALD_FR0)); + FDVALD_FR0 = sqrt(FSVALD_FR0); break; case 0x05: if (IS_SINGLE(op)) /* ABS.S */ FDVALS_FR0 = fabs(FSVALS_FR0); else /* ABS.D */ - SFDVALD_FR0(fabs(LFSVALD_FR0)); + FDVALD_FR0 = fabs(FSVALD_FR0); break; case 0x06: if (IS_SINGLE(op)) /* MOV.S */ FDVALS_FR0 = FSVALS_FR0; else /* MOV.D */ - SFDVALD_FR0(LFSVALD_FR0); + FDVALD_FR0 = FSVALD_FR0; break; case 0x07: if (IS_SINGLE(op)) /* NEG.S */ FDVALS_FR0 = -FSVALS_FR0; else /* NEG.D */ - SFDVALD_FR0(-LFSVALD_FR0); + FDVALD_FR0 = -FSVALD_FR0; break; case 0x08: @@ -1669,16 +1661,16 @@ void mips3_device::handle_cop1_fr0(uint32_t op) temp = ceil(temp - 0.5); else temp = floor(temp + 0.5); - SFDVALL_FR0((int64_t)temp); + FDVALL_FR0 = (int64_t)temp; } else /* ROUND.L.D */ { - double temp = LFSVALD_FR0; + double temp = FSVALD_FR0; if (temp < 0) temp = ceil(temp - 0.5); else temp = floor(temp + 0.5); - SFDVALL_FR0((int64_t)temp); + FDVALL_FR0 = (int64_t)temp; } break; @@ -1690,16 +1682,16 @@ void mips3_device::handle_cop1_fr0(uint32_t op) temp = ceil(temp); else temp = floor(temp); - SFDVALL_FR0((int64_t)temp); + FDVALL_FR0 = (int64_t)temp; } else /* TRUNC.L.D */ { - double temp = LFSVALD_FR0; + double temp = FSVALD_FR0; if (temp < 0) temp = ceil(temp); else temp = floor(temp); - SFDVALL_FR0((int64_t)temp); + FDVALL_FR0 = (int64_t)temp; } break; @@ -1707,16 +1699,16 @@ void mips3_device::handle_cop1_fr0(uint32_t op) if (IS_SINGLE(op)) /* CEIL.L.S */ dtemp = ceil(FSVALS_FR0); else /* CEIL.L.D */ - dtemp = ceil(LFSVALD_FR0); - SFDVALL_FR0((int64_t)dtemp); + dtemp = ceil(FSVALD_FR0); + FDVALL_FR0 = (int64_t)dtemp; break; case 0x0b: if (IS_SINGLE(op)) /* FLOOR.L.S */ dtemp = floor(FSVALS_FR0); else /* FLOOR.L.D */ - dtemp = floor(LFSVALD_FR0); - SFDVALL_FR0((int64_t)dtemp); + dtemp = floor(FSVALD_FR0); + FDVALL_FR0 = (int64_t)dtemp; break; case 0x0c: @@ -1731,7 +1723,7 @@ void mips3_device::handle_cop1_fr0(uint32_t op) } else /* ROUND.W.D */ { - dtemp = LFSVALD_FR0; + dtemp = FSVALD_FR0; if (dtemp < 0) dtemp = ceil(dtemp - 0.5); else @@ -1752,7 +1744,7 @@ void mips3_device::handle_cop1_fr0(uint32_t op) } else /* TRUNC.W.D */ { - dtemp = LFSVALD_FR0; + dtemp = FSVALD_FR0; if (dtemp < 0) dtemp = ceil(dtemp); else @@ -1765,7 +1757,7 @@ void mips3_device::handle_cop1_fr0(uint32_t op) if (IS_SINGLE(op)) /* CEIL.W.S */ dtemp = ceil(FSVALS_FR0); else /* CEIL.W.D */ - dtemp = ceil(LFSVALD_FR0); + dtemp = ceil(FSVALD_FR0); FDVALW_FR0 = (int32_t)dtemp; break; @@ -1773,7 +1765,7 @@ void mips3_device::handle_cop1_fr0(uint32_t op) if (IS_SINGLE(op)) /* FLOOR.W.S */ dtemp = floor(FSVALS_FR0); else /* FLOOR.W.D */ - dtemp = floor(LFSVALD_FR0); + dtemp = floor(FSVALD_FR0); FDVALW_FR0 = (int32_t)dtemp; break; @@ -1783,7 +1775,7 @@ void mips3_device::handle_cop1_fr0(uint32_t op) if (IS_SINGLE(op)) /* MOVT/F.S */ FDVALS_FR0 = FSVALS_FR0; else /* MOVT/F.D */ - SFDVALD_FR0(LFSVALD_FR0); + FDVALD_FR0 = FSVALD_FR0; } break; @@ -1793,7 +1785,7 @@ void mips3_device::handle_cop1_fr0(uint32_t op) if (IS_SINGLE(op)) /* MOVZ.S */ FDVALS_FR0 = FSVALS_FR0; else /* MOVZ.D */ - SFDVALD_FR0(LFSVALD_FR0); + FDVALD_FR0 = FSVALD_FR0; } break; @@ -1803,7 +1795,7 @@ void mips3_device::handle_cop1_fr0(uint32_t op) if (IS_SINGLE(op)) /* MOVN.S */ FDVALS_FR0 = FSVALS_FR0; else /* MOVN.D */ - SFDVALD_FR0(LFSVALD_FR0); + FDVALD_FR0 = FSVALD_FR0; } break; @@ -1811,14 +1803,14 @@ void mips3_device::handle_cop1_fr0(uint32_t op) if (IS_SINGLE(op)) /* RECIP.S */ FDVALS_FR0 = 1.0f / FSVALS_FR0; else /* RECIP.D */ - SFDVALD_FR0(1.0 / LFSVALD_FR0); + FDVALD_FR0 = 1.0 / FSVALD_FR0; break; case 0x16: /* R5000 */ if (IS_SINGLE(op)) /* RSQRT.S */ FDVALS_FR0 = 1.0f / sqrt(FSVALS_FR0); else /* RSQRT.D */ - SFDVALD_FR0(1.0 / sqrt(LFSVALD_FR0)); + FDVALD_FR0 = 1.0 / sqrt(FSVALD_FR0); break; case 0x20: @@ -1827,36 +1819,36 @@ void mips3_device::handle_cop1_fr0(uint32_t op) if (IS_SINGLE(op)) /* CVT.S.W */ FDVALS_FR0 = (int32_t)FSVALW_FR0; else /* CVT.S.L */ - FDVALS_FR0 = (int64_t)LFSVALL_FR0; + FDVALS_FR0 = (int64_t)FSVALL_FR0; } else /* CVT.S.D */ - FDVALS_FR0 = LFSVALD_FR0; + FDVALS_FR0 = FSVALD_FR0; break; case 0x21: if (IS_INTEGRAL(op)) { if (IS_SINGLE(op)) /* CVT.D.W */ - SFDVALD_FR0((int32_t)FSVALW_FR0); + FDVALD_FR0 = (int32_t)FSVALW_FR0; else /* CVT.D.L */ - SFDVALD_FR0((int64_t)LFSVALL_FR0); + FDVALD_FR0 = (int64_t)FSVALL_FR0; } else /* CVT.D.S */ - SFDVALD_FR0(FSVALS_FR0); + FDVALD_FR0 = FSVALS_FR0; break; case 0x24: if (IS_SINGLE(op)) /* CVT.W.S */ FDVALW_FR0 = (int32_t)FSVALS_FR0; else - FDVALW_FR0 = (int32_t)LFSVALD_FR0; + FDVALW_FR0 = (int32_t)FSVALD_FR0; break; case 0x25: if (IS_SINGLE(op)) /* CVT.L.S */ - SFDVALL_FR0((int64_t)FSVALS_FR0); + FDVALL_FR0 = (int64_t)FSVALS_FR0; else /* CVT.L.D */ - SFDVALL_FR0((int64_t)LFSVALD_FR0); + FDVALL_FR0 = (int64_t)FSVALD_FR0; break; case 0x30: @@ -1880,7 +1872,7 @@ void mips3_device::handle_cop1_fr0(uint32_t 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, (LFSVALD_FR0 == LFTVALD_FR0)); + SET_FCC((op >> 8) & 7, (FSVALD_FR0 == FTVALD_FR0)); break; case 0x33: @@ -1888,7 +1880,7 @@ void mips3_device::handle_cop1_fr0(uint32_t 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, (LFSVALD_FR0 == LFTVALD_FR0)); + SET_FCC((op >> 8) & 7, (FSVALD_FR0 == FTVALD_FR0)); break; case 0x34: @@ -1896,7 +1888,7 @@ void mips3_device::handle_cop1_fr0(uint32_t 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, (LFSVALD_FR0 < LFTVALD_FR0)); + SET_FCC((op >> 8) & 7, (FSVALD_FR0 < FTVALD_FR0)); break; case 0x35: @@ -1904,7 +1896,7 @@ void mips3_device::handle_cop1_fr0(uint32_t 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, (LFSVALD_FR0 < LFTVALD_FR0)); + SET_FCC((op >> 8) & 7, (FSVALD_FR0 < FTVALD_FR0)); break; case 0x36: @@ -1912,7 +1904,7 @@ void mips3_device::handle_cop1_fr0(uint32_t 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, (LFSVALD_FR0 <= LFTVALD_FR0)); + SET_FCC((op >> 8) & 7, (FSVALD_FR0 <= FTVALD_FR0)); break; case 0x37: @@ -1920,7 +1912,7 @@ void mips3_device::handle_cop1_fr0(uint32_t 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, (LFSVALD_FR0 <= LFTVALD_FR0)); + SET_FCC((op >> 8) & 7, (FSVALD_FR0 <= FTVALD_FR0)); break; default: @@ -2316,7 +2308,7 @@ void mips3_device::handle_cop1x_fr0(uint32_t op) break; case 0x01: /* LDXC1 */ - if (RDOUBLE(RSVAL32 + RTVAL32, &temp64)) SFDVALL_FR0(temp64); + if (RDOUBLE(RSVAL32 + RTVAL32, &temp64)) FDVALL_FR0 = temp64; break; case 0x08: /* SWXC1 */ @@ -2335,7 +2327,7 @@ void mips3_device::handle_cop1x_fr0(uint32_t op) break; case 0x21: /* MADD.D */ - SFDVALD_FR0(LFSVALD_FR0 * LFTVALD_FR0 + LFRVALD_FR0); + FDVALD_FR0 = FSVALD_FR0 * FTVALD_FR0 + FRVALD_FR0; break; case 0x28: /* MSUB.S */ @@ -2343,7 +2335,7 @@ void mips3_device::handle_cop1x_fr0(uint32_t op) break; case 0x29: /* MSUB.D */ - SFDVALD_FR0(LFSVALD_FR0 * LFTVALD_FR0 - LFRVALD_FR0); + FDVALD_FR0 = FSVALD_FR0 * FTVALD_FR0 - FRVALD_FR0; break; case 0x30: /* NMADD.S */ @@ -2351,7 +2343,7 @@ void mips3_device::handle_cop1x_fr0(uint32_t op) break; case 0x31: /* NMADD.D */ - SFDVALD_FR0(-(LFSVALD_FR0 * LFTVALD_FR0 + LFRVALD_FR0)); + FDVALD_FR0 = -(FSVALD_FR0 * FTVALD_FR0 + FRVALD_FR0); break; case 0x38: /* NMSUB.S */ @@ -2359,7 +2351,7 @@ void mips3_device::handle_cop1x_fr0(uint32_t op) break; case 0x39: /* NMSUB.D */ - SFDVALD_FR0(-(LFSVALD_FR0 * LFTVALD_FR0 - LFRVALD_FR0)); + FDVALD_FR0 = -(FSVALD_FR0 * FTVALD_FR0 - FRVALD_FR0); break; case 0x24: /* MADD.W */ diff --git a/src/devices/cpu/mips/mips3.h b/src/devices/cpu/mips/mips3.h index 6d03dc1e5cc..18cb6557e91 100644 --- a/src/devices/cpu/mips/mips3.h +++ b/src/devices/cpu/mips/mips3.h @@ -557,14 +557,8 @@ private: bool generate_set_cop0_reg(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint8_t reg); bool generate_get_cop0_reg(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint8_t reg); bool generate_cop0(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); - bool generate_cop1_fr0(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); - bool generate_cop1_fr1(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); - void generate_get_cop1_reg64(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, const uint32_t reg, const uml::parameter& param); - void generate_get_cop1_reg64_d2i(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, const uint32_t reg, const uml::parameter& param); - void generate_set_cop1_reg64(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, const uint32_t reg, const uml::parameter& param); - void generate_set_cop1_reg64_i2d(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, const uint32_t reg, const uml::parameter& param); - bool generate_cop1x_fr0(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); - bool generate_cop1x_fr1(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + bool generate_cop1(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + bool generate_cop1x(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void check_cop0_access(drcuml_block *block); void check_cop1_access(drcuml_block *block); diff --git a/src/devices/cpu/mips/mips3drc.cpp b/src/devices/cpu/mips/mips3drc.cpp index 258748b29a6..182c375f9e3 100644 --- a/src/devices/cpu/mips/mips3drc.cpp +++ b/src/devices/cpu/mips/mips3drc.cpp @@ -46,7 +46,7 @@ using namespace uml; #define HI32 R32(REG_HI) #define CPR032(reg) mem(LOPTR(&m_core->cpr[0][reg])) #define CCR032(reg) mem(LOPTR(&m_core->ccr[0][reg])) -#define FPR32_FR0(reg) mem(&((float *)&m_core->cpr[1][reg])[BYTE_XOR_LE(0)]) +#define FPR32(reg) mem((IS_FR0) ? &((float *)&m_core->cpr[1][reg & 0x1E])[BYTE_XOR_LE(reg & 1)] : (float *)&m_core->cpr[1][reg]) #define CCR132(reg) mem(LOPTR(&m_core->ccr[1][reg])) #define CPR232(reg) mem(LOPTR(&m_core->cpr[2][reg])) #define CCR232(reg) mem(LOPTR(&m_core->ccr[2][reg])) @@ -56,26 +56,11 @@ using namespace uml; #define HI64 R64(REG_HI) #define CPR064(reg) mem(&m_core->cpr[0][reg]) #define CCR064(reg) mem(&m_core->ccr[0][reg]) -#define FPR64_FR1(reg) mem((double *)&m_core->cpr[1][reg]) +#define FPR64(reg) mem((IS_FR0) ? (double *)&m_core->cpr[1][reg & 0x1E] : (double *)&m_core->cpr[1][reg]) #define CCR164(reg) mem(&m_core->ccr[1][reg]) #define CPR264(reg) mem(&m_core->cpr[2][reg]) #define CCR264(reg) mem(&m_core->ccr[2][reg]) -#define FRVALS_FR0 mem(&((float *)&m_core->cpr[1][FRREG])[BYTE_XOR_LE(0)]) -#define FTVALS_FR0 mem(&((float *)&m_core->cpr[1][FTREG])[BYTE_XOR_LE(0)]) -#define FSVALS_FR0 mem(&((float *)&m_core->cpr[1][FSREG])[BYTE_XOR_LE(0)]) -#define FDVALS_FR0 mem(&((float *)&m_core->cpr[1][FDREG])[BYTE_XOR_LE(0)]) - -#define FRVALS_FR1 mem(&((float *)&m_core->cpr[1][FRREG])[BYTE_XOR_LE(0)]) -#define FTVALS_FR1 mem(&((float *)&m_core->cpr[1][FTREG])[BYTE_XOR_LE(0)]) -#define FSVALS_FR1 mem(&((float *)&m_core->cpr[1][FSREG])[BYTE_XOR_LE(0)]) -#define FDVALS_FR1 mem(&((float *)&m_core->cpr[1][FDREG])[BYTE_XOR_LE(0)]) - -#define FRVALD_FR1 mem((double *)&m_core->cpr[1][FRREG]) -#define FTVALD_FR1 mem((double *)&m_core->cpr[1][FTREG]) -#define FSVALD_FR1 mem((double *)&m_core->cpr[1][FSREG]) -#define FDVALD_FR1 mem((double *)&m_core->cpr[1][FDREG]) - #define FCCSHIFT(which) fcc_shift[(m_flavor < MIPS3_TYPE_MIPS_IV) ? 0 : ((which) & 7)] #define FCCMASK(which) ((uint32_t)(1 << FCCSHIFT(which))) @@ -1656,7 +1641,7 @@ bool mips3_device::generate_opcode(drcuml_block *block, compiler_state *compiler check_cop1_access(block); UML_ADD(block, I0, R32(RSREG), SIMMVAL); // add i0,,SIMMVAL UML_CALLH(block, *m_read32[m_core->mode >> 1]); // callh read32 - UML_MOV(block, FPR32_FR0(RTREG), I0); // mov ,i0 + UML_MOV(block, FPR32(RTREG), I0); // mov ,i0 if (!in_delay_slot) generate_update_cycles(block, compiler, desc->pc + 4, true); return true; @@ -1665,7 +1650,7 @@ bool mips3_device::generate_opcode(drcuml_block *block, compiler_state *compiler check_cop1_access(block); UML_ADD(block, I0, R32(RSREG), SIMMVAL); // add i0,,SIMMVAL UML_CALLH(block, *m_read64[m_core->mode >> 1]); // callh read64 - generate_set_cop1_reg64_i2d(block, compiler, desc, RTREG, I0); + UML_DMOV(block, FPR64(RTREG), I0); // dmov ,i0 if (!in_delay_slot) generate_update_cycles(block, compiler, desc->pc + 4, true); return true; @@ -1808,7 +1793,7 @@ bool mips3_device::generate_opcode(drcuml_block *block, compiler_state *compiler case 0x39: /* SWC1 - MIPS I */ check_cop1_access(block); UML_ADD(block, I0, R32(RSREG), SIMMVAL); // add i0,,SIMMVAL - UML_MOV(block, I1, FPR32_FR0(RTREG)); // mov i1, + UML_MOV(block, I1, FPR32(RTREG)); // mov i1, UML_CALLH(block, *m_write32[m_core->mode >> 1]); // callh write32 if (!in_delay_slot) generate_update_cycles(block, compiler, desc->pc + 4, true); @@ -1816,8 +1801,8 @@ bool mips3_device::generate_opcode(drcuml_block *block, compiler_state *compiler case 0x3d: /* SDC1 - MIPS III */ check_cop1_access(block); - generate_get_cop1_reg64_d2i(block, compiler, desc, RTREG, I1); UML_ADD(block, I0, R32(RSREG), SIMMVAL); // add i0,,SIMMVAL + UML_DMOV(block, I1, FPR64(RTREG)); // dmov i1, UML_CALLH(block, *m_write64[m_core->mode >> 1]); // callh write64 if (!in_delay_slot) generate_update_cycles(block, compiler, desc->pc + 4, true); @@ -1853,18 +1838,10 @@ bool mips3_device::generate_opcode(drcuml_block *block, compiler_state *compiler return generate_cop0(block, compiler, desc); case 0x11: /* COP1 - MIPS I */ - if ((m_core->mode & 1) == 0) - return generate_cop1_fr0(block, compiler, desc); - else - return generate_cop1_fr1(block, compiler, desc); - return false; + return generate_cop1(block, compiler, desc); case 0x13: /* COP1X - MIPS IV */ - if ((m_core->mode & 1) == 0) - return generate_cop1x_fr0(block, compiler, desc); - else - return generate_cop1x_fr1(block, compiler, desc); - return false; + return generate_cop1x(block, compiler, desc); case 0x12: /* COP2 - MIPS I */ UML_EXH(block, *m_exception[EXCEPTION_INVALIDOP], 0);// exh invalidop,0 @@ -2689,77 +2666,11 @@ void mips3_device::check_cop1_access(drcuml_block *block) } } -void mips3_device::generate_get_cop1_reg64_d2i(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, const uint32_t reg, const uml::parameter& param) -{ - if ((m_core->mode & 1) == 0) - { - UML_ICOPYFS(block, I0, FPR32_FR0((reg & 0x1E) + 1)); - UML_DSHL(block, I0, I0, 32); - UML_ICOPYFS(block, I1, FPR32_FR0(reg & 0x1E)); - UML_DROLINS(block, I0, I1, 0, 0x00000000ffffffffL); - UML_DMOV(block, param, I0); - } - else - { - UML_DMOV(block, param, FPR64_FR1(reg)); - } -} - -void mips3_device::generate_get_cop1_reg64(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, const uint32_t reg, const uml::parameter& param) -{ - if ((m_core->mode & 1) == 0) - { - UML_ICOPYFS(block, I0, FPR32_FR0((reg & 0x1E) + 1)); - UML_DSHL(block, I0, I0, 32); - UML_ICOPYFS(block, I1, FPR32_FR0(reg & 0x1E)); - UML_DROLINS(block, I0, I1, 0, 0x00000000ffffffffL); - UML_FDCOPYI(block, param, I0); - } - else - { - UML_FDMOV(block, param, FPR64_FR1(reg)); - } -} - -void mips3_device::generate_set_cop1_reg64(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, const uint32_t reg, const uml::parameter& param) -{ - if ((m_core->mode & 1) == 0) - { - UML_ICOPYFD(block, I0, param); - UML_FSCOPYI(block, F1, I0); - UML_FSMOV(block, FPR32_FR0(reg & 0x1E), F1); - UML_DSHR(block, I0, I0, 32); - UML_FSCOPYI(block, F1, I0); - UML_FSMOV(block, FPR32_FR0((reg & 0x1E) + 1), F1); - } - else - { - UML_FDMOV(block, FPR64_FR1(reg), param); - } -} - -void mips3_device::generate_set_cop1_reg64_i2d(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, const uint32_t reg, const uml::parameter& param) -{ - if ((m_core->mode & 1) == 0) - { - UML_DMOV(block, I1, param); - UML_FSCOPYI(block, F0, I1); - UML_FSMOV(block, FPR32_FR0(reg & 0x1E), F0); - UML_DSHR(block, I1, I1, 32); - UML_FSCOPYI(block, F0, I1); - UML_FSMOV(block, FPR32_FR0((reg & 0x1E) + 1), F0); - } - else - { - UML_DMOV(block, FPR64_FR1(reg), param); - } -} - /*------------------------------------------------------- - generate_cop1_fr0 - compile COP1 opcodes in FR0 mode + generate_cop1 - compile COP1 opcodes ---------------------------------------------------------*/ -bool mips3_device::generate_cop1_fr0(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +bool mips3_device::generate_cop1(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) { uint32_t op = desc->opptr.l[0]; code_label skip; @@ -2772,15 +2683,14 @@ bool mips3_device::generate_cop1_fr0(drcuml_block *block, compiler_state *compil case 0x00: /* MFC1 - MIPS I */ if (RTREG != 0) { - UML_DSEXT(block, R64(RTREG), FPR32_FR0(RDREG), SIZE_DWORD); // dsext ,fpr[rdreg],dword + UML_DSEXT(block, R64(RTREG), FPR32(RDREG), SIZE_DWORD); // dsext ,fpr[rdreg],dword } return true; case 0x01: /* DMFC1 - MIPS III */ if (RTREG != 0) { - generate_get_cop1_reg64_d2i(block, compiler, desc, RDREG, I0); - UML_DMOV(block, R64(RTREG), I0); + UML_DMOV(block, R64(RTREG), FPR64(RDREG)); // dmov ,fpr[rdreg] } return true; @@ -2790,12 +2700,11 @@ bool mips3_device::generate_cop1_fr0(drcuml_block *block, compiler_state *compil return true; case 0x04: /* MTC1 - MIPS I */ - UML_MOV(block, FPR32_FR0(RDREG), R32(RTREG)); // mov fpr[rdreg], + UML_MOV(block, FPR32(RDREG), R32(RTREG)); // mov fpr[rdreg], return true; case 0x05: /* DMTC1 - MIPS III */ - UML_DMOV(block, I0, R64(RTREG)); - generate_set_cop1_reg64_i2d(block, compiler, desc, RDREG, I0); + UML_DMOV(block, FPR64(RDREG), R64(RTREG)); // dmov fpr[rdreg], return true; case 0x06: /* CTC1 - MIPS I */ @@ -2843,236 +2752,193 @@ bool mips3_device::generate_cop1_fr0(drcuml_block *block, compiler_state *compil case 0x00: if (IS_SINGLE(op)) /* ADD.S - MIPS I */ { - UML_FSADD(block, FDVALS_FR0, FSVALS_FR0, FTVALS_FR0); // fsadd ,, + UML_FSADD(block, FPR32(FDREG), FPR32(FSREG), FPR32(FTREG)); // fsadd ,, } else /* ADD.D - MIPS I */ { - generate_get_cop1_reg64(block, compiler, desc, FSREG, F0); // dmov F0, - generate_get_cop1_reg64(block, compiler, desc, FTREG, F1); // dmov F1, - UML_FDADD(block, F2, F0, F1); // fdadd F2,F0,F1 - generate_set_cop1_reg64(block, compiler, desc, FDREG, F2); // dmov ,F2 + UML_FDADD(block, FPR64(FDREG), FPR64(FSREG), FPR64(FTREG)); // fdadd ,, } return true; case 0x01: if (IS_SINGLE(op)) /* SUB.S - MIPS I */ { - UML_FSSUB(block, FDVALS_FR0, FSVALS_FR0, FTVALS_FR0); // fssub ,, + UML_FSSUB(block, FPR32(FDREG), FPR32(FSREG), FPR32(FTREG)); // fssub ,, } else /* SUB.D - MIPS I */ { - generate_get_cop1_reg64(block, compiler, desc, FSREG, F0); // dmov F0, - generate_get_cop1_reg64(block, compiler, desc, FTREG, F1); // dmov F1, - UML_FDSUB(block, F2, F0, F1); // fdsub F2,F0,F1 - generate_set_cop1_reg64(block, compiler, desc, FDREG, F2); // dmov ,F2 + UML_FDSUB(block, FPR64(FDREG), FPR64(FSREG), FPR64(FTREG)); // fdsub ,, } return true; case 0x02: if (IS_SINGLE(op)) /* MUL.S - MIPS I */ { - UML_FSMUL(block, FDVALS_FR0, FSVALS_FR0, FTVALS_FR0); // fsmul ,, + UML_FSMUL(block, FPR32(FDREG), FPR32(FSREG), FPR32(FTREG)); // fsmul ,, } else /* MUL.D - MIPS I */ { - generate_get_cop1_reg64(block, compiler, desc, FSREG, F0); // dmov F0, - generate_get_cop1_reg64(block, compiler, desc, FTREG, F1); // dmov F1, - UML_FDMUL(block, F2, F0, F1); // fdmul F2,F0,F1 - generate_set_cop1_reg64(block, compiler, desc, FDREG, F2); // dmov ,F2 + UML_FDMUL(block, FPR64(FDREG), FPR64(FSREG), FPR64(FTREG)); // fdmul ,, } return true; case 0x03: if (IS_SINGLE(op)) /* DIV.S - MIPS I */ { - UML_FSDIV(block, FDVALS_FR0, FSVALS_FR0, FTVALS_FR0); // fsdiv ,, + UML_FSDIV(block, FPR32(FDREG), FPR32(FSREG), FPR32(FTREG)); // fsdiv ,, } else /* DIV.D - MIPS I */ { - generate_get_cop1_reg64(block, compiler, desc, FSREG, F0); // dmov F0, - generate_get_cop1_reg64(block, compiler, desc, FTREG, F1); // dmov F1, - UML_FDDIV(block, F2, F0, F1); // fddiv F2,F0,F1 - generate_set_cop1_reg64(block, compiler, desc, FDREG, F2); // dmov ,F2 + UML_FDDIV(block, FPR64(FDREG), FPR64(FSREG), FPR64(FTREG)); // fddiv ,, } return true; case 0x04: if (IS_SINGLE(op)) /* SQRT.S - MIPS II */ { - UML_FSSQRT(block, FDVALS_FR0, FSVALS_FR0); // fssqrt , + UML_FSSQRT(block, FPR32(FDREG), FPR32(FSREG)); // fssqrt , } else /* SQRT.D - MIPS II */ { - generate_get_cop1_reg64(block, compiler, desc, FSREG, F0); // dmov F0, - UML_FDSQRT(block, F0, F0); // fdsqrt F0,F0 - generate_set_cop1_reg64(block, compiler, desc, FDREG, F0); // dmov ,F0 + UML_FDSQRT(block, FPR64(FDREG), FPR64(FSREG)); // fdsqrt , } return true; case 0x05: if (IS_SINGLE(op)) /* ABS.S - MIPS I */ { - UML_FSABS(block, FDVALS_FR0, FSVALS_FR0); // fsabs , + UML_FSABS(block, FPR32(FDREG), FPR32(FSREG)); // fsabs , } else /* ABS.D - MIPS I */ { - generate_get_cop1_reg64(block, compiler, desc, FSREG, F0); // dmov F0, - UML_FDABS(block, F0, F0); // fdabs F0,F0 - generate_set_cop1_reg64(block, compiler, desc, FDREG, F0); // dmov ,F0 + UML_FDABS(block, FPR64(FDREG), FPR64(FSREG)); // fdabs , } return true; case 0x06: if (IS_SINGLE(op)) /* MOV.S - MIPS I */ { - UML_FSMOV(block, FDVALS_FR0, FSVALS_FR0); // fsmov , + UML_FSMOV(block, FPR32(FDREG), FPR32(FSREG)); // fsmov , } else /* MOV.D - MIPS I */ { - generate_get_cop1_reg64(block, compiler, desc, FSREG, F0); // dmov F0, - generate_set_cop1_reg64(block, compiler, desc, FDREG, F0); // dmov ,F0 + UML_FDMOV(block, FPR64(FDREG), FPR64(FSREG)); // fdmov , } return true; case 0x07: if (IS_SINGLE(op)) /* NEG.S - MIPS I */ { - UML_FSNEG(block, FDVALS_FR0, FSVALS_FR0); // fsneg , - UML_CMP(block, FSVALS_FR0, 0); // cmp ,0.0 - UML_MOVc(block, COND_E, FDVALS_FR0, 0x80000000); // mov ,-0.0,e + UML_FSNEG(block, FPR32(FDREG), FPR32(FSREG)); // fsneg , + UML_CMP(block, FPR32(FSREG), 0); // cmp ,0.0 + UML_MOVc(block, COND_E, FPR32(FDREG), 0x80000000); // mov ,-0.0,e } else /* NEG.D - MIPS I */ { - generate_get_cop1_reg64(block, compiler, desc, FSREG, F0); // dmov F0, - UML_FDNEG(block, F1, F0); // fdneg F1,F0 - UML_DCMP(block, F0, 0); // cmp F0,0.0 - UML_DMOVc(block, COND_E, F1, 0x8000000000000000U); // dmov F1,-0.0,e - generate_set_cop1_reg64(block, compiler, desc, FDREG, F1); // dmov ,F1 + UML_FDNEG(block, FPR64(FDREG), FPR64(FSREG)); // fdneg , + UML_DCMP(block, FPR64(FSREG), 0); // cmp ,0.0 + UML_DMOVc(block, COND_E, FPR64(FDREG), 0x8000000000000000U); // dmov ,-0.0,e } return true; case 0x08: if (IS_SINGLE(op)) /* ROUND.L.S - MIPS III */ { - UML_FSTOINT(block, F0, FSVALS_FR0, SIZE_QWORD, ROUND_ROUND);// fstoint f0,,qword,round + UML_FSTOINT(block, FPR64(FDREG), FPR32(FSREG), SIZE_QWORD, ROUND_ROUND);// fstoint ,,qword,round } else /* ROUND.L.D - MIPS III */ { - generate_get_cop1_reg64(block, compiler, desc, FSREG, F0); // dmov f0, - UML_FDTOINT(block, F0, F0, SIZE_QWORD, ROUND_ROUND); // fdtoint f0,f0,qword,round + UML_FDTOINT(block, FPR64(FDREG), FPR64(FSREG), SIZE_QWORD, ROUND_ROUND);// fdtoint ,,qword,round } - UML_ICOPYFD(block, I0, F0); // icopyfd i0,f0 - generate_set_cop1_reg64_i2d(block, compiler, desc, FDREG, I0); // dmov ,f0 return true; case 0x09: if (IS_SINGLE(op)) /* TRUNC.L.S - MIPS III */ { - UML_FSTOINT(block, F0, FSVALS_FR0, SIZE_QWORD, ROUND_TRUNC);// fstoint f0,,qword,trunc + UML_FSTOINT(block, FPR64(FDREG), FPR32(FSREG), SIZE_QWORD, ROUND_TRUNC);// fstoint ,,qword,trunc } else /* TRUNC.L.D - MIPS III */ { - generate_get_cop1_reg64(block, compiler, desc, FSREG, F0); // dmov f0, - UML_FDTOINT(block, F0, F0, SIZE_QWORD, ROUND_TRUNC); // fdtoint f0,f0,qword,trunc + UML_FDTOINT(block, FPR64(FDREG), FPR64(FSREG), SIZE_QWORD, ROUND_TRUNC);// fdtoint ,,qword,trunc } - UML_ICOPYFD(block, I0, F0); // icopyfd i0,f0 - generate_set_cop1_reg64_i2d(block, compiler, desc, FDREG, I0); // dmov ,i0 return true; case 0x0a: if (IS_SINGLE(op)) /* CEIL.L.S - MIPS III */ { - UML_FSTOINT(block, F0, FSVALS_FR0, SIZE_QWORD, ROUND_CEIL);// fstoint f0,,qword,ceil + UML_FSTOINT(block, FPR64(FDREG), FPR32(FSREG), SIZE_QWORD, ROUND_CEIL);// fstoint ,,qword,ceil } else /* CEIL.L.D - MIPS III */ { - generate_get_cop1_reg64(block, compiler, desc, FSREG, F0); // dmov f0, - UML_FDTOINT(block, F0, F0, SIZE_QWORD, ROUND_CEIL); // fdtoint f0,,qword,ceil + UML_FDTOINT(block, FPR64(FDREG), FPR64(FSREG), SIZE_QWORD, ROUND_CEIL);// fdtoint ,,qword,ceil } - UML_ICOPYFD(block, I0, F0); // icopyfd i0,f0 - generate_set_cop1_reg64(block, compiler, desc, FDREG, I0); // dmov ,f0 return true; case 0x0b: if (IS_SINGLE(op)) /* FLOOR.L.S - MIPS III */ { - UML_FSTOINT(block, F0, FSVALS_FR0, SIZE_QWORD, ROUND_FLOOR);// fstoint f0,,qword,floor + UML_FSTOINT(block, FPR64(FDREG), FPR32(FSREG), SIZE_QWORD, ROUND_FLOOR);// fstoint ,,qword,floor } else /* FLOOR.L.D - MIPS III */ { - generate_get_cop1_reg64(block, compiler, desc, FSREG, F0); // dmov f0, - UML_FDTOINT(block, F0, F0, SIZE_QWORD, ROUND_FLOOR); // fdtoint f0,,qword,floor + UML_FDTOINT(block, FPR64(FDREG), FPR64(FSREG), SIZE_QWORD, ROUND_FLOOR);// fdtoint ,,qword,floor } - UML_ICOPYFD(block, I0, F0); // icopyfd i0,f0 - generate_set_cop1_reg64(block, compiler, desc, FDREG, I0); // dmov ,f0 return true; case 0x0c: if (IS_SINGLE(op)) /* ROUND.W.S - MIPS II */ { - UML_FSTOINT(block, FDVALS_FR0, FSVALS_FR0, SIZE_DWORD, ROUND_ROUND);// fstoint ,,dword,round + UML_FSTOINT(block, FPR32(FDREG), FPR32(FSREG), SIZE_DWORD, ROUND_ROUND);// fstoint ,,dword,round } else /* ROUND.W.D - MIPS II */ { - generate_get_cop1_reg64(block, compiler, desc, FSREG, F0); // dmov F0, - UML_FDTOINT(block, FDVALS_FR0, F0, SIZE_DWORD, ROUND_ROUND); // fdtoint ,F0,dword,round + UML_FDTOINT(block, FPR32(FDREG), FPR64(FSREG), SIZE_DWORD, ROUND_ROUND);// fdtoint ,,dword,round } return true; case 0x0d: if (IS_SINGLE(op)) /* TRUNC.W.S - MIPS II */ { - UML_FSTOINT(block, FDVALS_FR0, FSVALS_FR0, SIZE_DWORD, ROUND_TRUNC);// fstoint ,,dword,trunc + UML_FSTOINT(block, FPR32(FDREG), FPR32(FSREG), SIZE_DWORD, ROUND_TRUNC);// fstoint ,,dword,trunc } else /* TRUNC.W.D - MIPS II */ { - generate_get_cop1_reg64(block, compiler, desc, FSREG, F0); // dmov F0, - UML_FDTOINT(block, FDVALS_FR0, F0, SIZE_DWORD, ROUND_TRUNC); // fdtoint ,F0,dword,trunc + UML_FDTOINT(block, FPR32(FDREG), FPR64(FSREG), SIZE_DWORD, ROUND_TRUNC);// fdtoint ,,dword,trunc } return true; case 0x0e: if (IS_SINGLE(op)) /* CEIL.W.S - MIPS II */ { - UML_FSTOINT(block, FDVALS_FR0, FSVALS_FR0, SIZE_DWORD, ROUND_CEIL);// fstoint ,,dword,ceil + UML_FSTOINT(block, FPR32(FDREG), FPR32(FSREG), SIZE_DWORD, ROUND_CEIL);// fstoint ,,dword,ceil } else /* CEIL.W.D - MIPS II */ { - generate_get_cop1_reg64(block, compiler, desc, FSREG, F0); // dmov F0, - UML_FDTOINT(block, FDVALS_FR0, F0, SIZE_DWORD, ROUND_CEIL); // fdtoint ,F0,dword,ceil + UML_FDTOINT(block, FPR32(FDREG), FPR64(FSREG), SIZE_DWORD, ROUND_CEIL);// fdtoint ,,dword,ceil } return true; case 0x0f: if (IS_SINGLE(op)) /* FLOOR.W.S - MIPS II */ { - UML_FSTOINT(block, FDVALS_FR0, FSVALS_FR0, SIZE_DWORD, ROUND_FLOOR);// fstoint ,,dword,floor + UML_FSTOINT(block, FPR32(FDREG), FPR32(FSREG), SIZE_DWORD, ROUND_FLOOR);// fstoint ,,dword,floor } else /* FLOOR.W.D - MIPS II */ { - generate_get_cop1_reg64(block, compiler, desc, FSREG, F0); // dmov F0, - UML_FDTOINT(block, FDVALS_FR0, F0, SIZE_DWORD, ROUND_FLOOR); // fdtoint ,F0,dword,floor + UML_FDTOINT(block, FPR32(FDREG), FPR64(FSREG), SIZE_DWORD, ROUND_FLOOR);// fdtoint ,,dword,floor } return true; case 0x11: - + condition = ((op >> 16) & 1) ? COND_NZ : COND_Z; UML_TEST(block, CCR132(31), FCCMASK(op >> 18)); // test ccr31,fccmask[op] if (IS_SINGLE(op)) /* MOVT/F.S - MIPS IV */ { - condition = ((op >> 16) & 1) ? COND_NZ : COND_Z; - UML_FSMOVc(block, condition, FDVALS_FR0, FSVALS_FR0); // fsmov ,,condition + UML_FSMOVc(block, condition, FPR32(FDREG), FPR32(FSREG)); // fsmov ,,condition } else /* MOVT/F.D - MIPS IV */ { - condition = ((op >> 16) & 1) ? COND_Z : COND_NZ; - generate_get_cop1_reg64(block, compiler, desc, FDREG, F0); // dmov F0, - UML_JMPc(block, condition, skip = compiler->labelnum++); - - generate_get_cop1_reg64(block, compiler, desc, FSREG, F0); // dmov F0, - - UML_LABEL(block, skip); - generate_set_cop1_reg64(block, compiler, desc, FDREG, F0); // dmov ,F0 + UML_FDMOVc(block, condition, FPR64(FDREG), FPR64(FSREG)); // fdmov ,,condition } return true; @@ -3080,15 +2946,11 @@ bool mips3_device::generate_cop1_fr0(drcuml_block *block, compiler_state *compil UML_DCMP(block, R64(RTREG), 0); // dcmp ,0 if (IS_SINGLE(op)) /* MOVZ.S - MIPS IV */ { - UML_FSMOVc(block, COND_Z, FDVALS_FR0, FSVALS_FR0); // fsmov ,,Z + UML_FSMOVc(block, COND_Z, FPR32(FDREG), FPR32(FSREG)); // fsmov ,,Z } else /* MOVZ.D - MIPS IV */ { - generate_get_cop1_reg64(block, compiler, desc, FSREG, F0); // dmov f0, - generate_get_cop1_reg64(block, compiler, desc, FDREG, F1); // dmov f1, - UML_FDMOVc(block, COND_Z, F2, F0); // fdmov f2,,Z - UML_FDMOVc(block, COND_NZ, F2, F1); // fdmov f2,,NZ - generate_set_cop1_reg64(block, compiler, desc, FDREG, F2); // dmov ,f0 + UML_FDMOVc(block, COND_Z, FPR64(FDREG), FPR64(FSREG)); // fdmov ,,Z } return true; @@ -3096,41 +2958,33 @@ bool mips3_device::generate_cop1_fr0(drcuml_block *block, compiler_state *compil UML_DCMP(block, R64(RTREG), 0); // dcmp ,0 if (IS_SINGLE(op)) /* MOVN.S - MIPS IV */ { - UML_FSMOVc(block, COND_NZ, FDVALS_FR0, FSVALS_FR0); // fsmov ,,NZ + UML_FSMOVc(block, COND_NZ, FPR32(FDREG), FPR32(FSREG)); // fsmov ,,NZ } else /* MOVN.D - MIPS IV */ { - generate_get_cop1_reg64(block, compiler, desc, FSREG, F0); // dmov f0, - generate_get_cop1_reg64(block, compiler, desc, FDREG, F1); // dmov f1, - UML_FDMOVc(block, COND_NZ, F2, F0); // fdmov f2,,NZ - UML_FDMOVc(block, COND_Z, F2, F1); // fdmov f2,,Z - generate_set_cop1_reg64(block, compiler, desc, FDREG, F2); // dmov ,f2 + UML_FDMOVc(block, COND_NZ, FPR64(FDREG), FPR64(FSREG)); // fdmov ,,NZ } return true; case 0x15: if (IS_SINGLE(op)) /* RECIP.S - MIPS IV */ { - UML_FSRECIP(block, FDVALS_FR0, FSVALS_FR0); // fsrecip , + UML_FSRECIP(block, FPR32(FDREG), FPR32(FSREG)); // fsrecip , } else /* RECIP.D - MIPS IV */ { - generate_get_cop1_reg64(block, compiler, desc, FSREG, F0); // dmov f0, - UML_FDRECIP(block, F0, F0); // fdrecip f0, - generate_set_cop1_reg64(block, compiler, desc, FDREG, F0); // dmov ,f0 + UML_FDRECIP(block, FPR64(FDREG), FPR64(FSREG)); // fdrecip , } return true; case 0x16: if (IS_SINGLE(op)) /* RSQRT.S - MIPS IV */ { - UML_FSRSQRT(block, FDVALS_FR0, FSVALS_FR0); // fsrsqrt , + UML_FSRSQRT(block, FPR32(FDREG), FPR32(FSREG)); // fsrsqrt , } else /* RSQRT.D - MIPS IV */ { - generate_get_cop1_reg64(block, compiler, desc, FSREG, F0); // dmov f0, - UML_FDRSQRT(block, F0, F0); // fdrsqrt f0, - generate_set_cop1_reg64(block, compiler, desc, FDREG, F0); // dmov ,f0 + UML_FDRSQRT(block, FPR64(FDREG), FPR64(FSREG)); // fdrsqrt , } return true; @@ -3139,18 +2993,16 @@ bool mips3_device::generate_cop1_fr0(drcuml_block *block, compiler_state *compil { if (IS_SINGLE(op)) /* CVT.S.W - MIPS I */ { - UML_FSFRINT(block, FDVALS_FR0, FSVALS_FR0, SIZE_DWORD); // fsfrint ,,dword + UML_FSFRINT(block, FPR32(FDREG), FPR32(FSREG), SIZE_DWORD); // fsfrint ,,dword } else /* CVT.S.L - MIPS I */ { - generate_get_cop1_reg64(block, compiler, desc, FSREG, F0); // dmov f0, - UML_FSFRINT(block, FDVALS_FR0, F0, SIZE_QWORD); // fsfrint ,f0,qword + UML_FSFRINT(block, FPR32(FDREG), FPR64(FSREG), SIZE_QWORD); // fsfrint ,,qword } } else /* CVT.S.D - MIPS I */ { - generate_get_cop1_reg64(block, compiler, desc, FSREG, F0); // dmov f0, - UML_FSFRFLT(block, FDVALS_FR0, F0, SIZE_QWORD); // fsfrflt ,f0,qword + UML_FSFRFLT(block, FPR32(FDREG), FPR64(FSREG), SIZE_QWORD); // fsfrflt ,,qword } return true; @@ -3159,44 +3011,38 @@ bool mips3_device::generate_cop1_fr0(drcuml_block *block, compiler_state *compil { if (IS_SINGLE(op)) /* CVT.D.W - MIPS I */ { - UML_FDFRINT(block, F0, FSVALS_FR0, SIZE_DWORD); // fdfrint f0,,dword + UML_FDFRINT(block, FPR64(FDREG), FPR32(FSREG), SIZE_DWORD); // fdfrint ,,dword } else /* CVT.D.L - MIPS I */ { - generate_get_cop1_reg64(block, compiler, desc, FSREG, F0); // dmov f0, - UML_FDFRINT(block, F0, F0, SIZE_QWORD); // fdfrint f0,f0,qword + UML_FDFRINT(block, FPR64(FDREG), FPR64(FSREG), SIZE_QWORD); // fdfrint ,,qword } } else /* CVT.D.S - MIPS I */ { - UML_FDFRFLT(block, F0, FSVALS_FR0, SIZE_DWORD); // fdfrflt f0,,dword + UML_FDFRFLT(block, FPR64(FDREG), FPR32(FSREG), SIZE_DWORD); // fdfrflt ,,dword } - generate_set_cop1_reg64(block, compiler, desc, FDREG, F0); // dmov ,f0 return true; case 0x24: if (IS_SINGLE(op)) /* CVT.W.S - MIPS I */ { - UML_FSTOINT(block, FDVALS_FR0, FSVALS_FR0, SIZE_DWORD, ROUND_DEFAULT);// fstoint ,,dword,default + UML_FSTOINT(block, FPR32(FDREG), FPR32(FSREG), SIZE_DWORD, ROUND_DEFAULT);// fstoint ,,dword,default } else /* CVT.W.D - MIPS I */ { - generate_get_cop1_reg64(block, compiler, desc, FSREG, F0); // dmov f0, - UML_FDTOINT(block, FDVALS_FR0, F0, SIZE_DWORD, ROUND_DEFAULT);// fdtoint ,f0,dword,default + UML_FDTOINT(block, FPR32(FDREG), FPR64(FSREG), SIZE_DWORD, ROUND_DEFAULT);// fdtoint ,,dword,default } return true; case 0x25: if (IS_SINGLE(op)) /* CVT.L.S - MIPS I */ { - UML_FSTOINT(block, F0, FSVALS_FR0, SIZE_QWORD, ROUND_DEFAULT);// fstoint f0,,qword,default - generate_set_cop1_reg64(block, compiler, desc, FDREG, F0); // dmov ,f0 + UML_FSTOINT(block, FPR64(FDREG), FPR32(FSREG), SIZE_QWORD, ROUND_DEFAULT);// fstoint ,,qword,default } else /* CVT.L.D - MIPS I */ { - generate_get_cop1_reg64(block, compiler, desc, FSREG, F0); // dmov f0, - UML_FDTOINT(block, F0, F0, SIZE_QWORD, ROUND_DEFAULT); // fdtoint ,,qword,default - generate_set_cop1_reg64(block, compiler, desc, FDREG, F0); // dmov ,f0 + UML_FDTOINT(block, FPR64(FDREG), FPR64(FSREG), SIZE_QWORD, ROUND_DEFAULT);// fdtoint ,,qword,default } return true; @@ -3209,13 +3055,11 @@ bool mips3_device::generate_cop1_fr0(drcuml_block *block, compiler_state *compil case 0x39: if (IS_SINGLE(op)) /* C.UN.S - MIPS I */ { - UML_FSCMP(block, FSVALS_FR0, FTVALS_FR0); // fscmp , + UML_FSCMP(block, FPR32(FSREG), FPR32(FTREG)); // fscmp , } else /* C.UN.D - MIPS I */ { - generate_get_cop1_reg64(block, compiler, desc, FSREG, F0); // dmov f0, - generate_get_cop1_reg64(block, compiler, desc, FTREG, F1); // dmov f1, - UML_FDCMP(block, F0, F1); // fdcmp f0,f1 + UML_FDCMP(block, FPR64(FSREG), FPR64(FTREG)); // fdcmp , } UML_SETc(block, COND_U, I0); // set i0,u UML_ROLINS(block, CCR132(31), I0, FCCSHIFT(op >> 8), FCCMASK(op >> 8)); @@ -3226,13 +3070,11 @@ bool mips3_device::generate_cop1_fr0(drcuml_block *block, compiler_state *compil case 0x3a: if (IS_SINGLE(op)) /* C.EQ.S - MIPS I */ { - UML_FSCMP(block, FSVALS_FR0, FTVALS_FR0); // fscmp , + UML_FSCMP(block, FPR32(FSREG), FPR32(FTREG)); // fscmp , } else /* C.EQ.D - MIPS I */ { - generate_get_cop1_reg64(block, compiler, desc, FSREG, F0); // dmov f0, - generate_get_cop1_reg64(block, compiler, desc, FTREG, F1); // dmov f1, - UML_FDCMP(block, F0, F1); // fdcmp f0,f1 + UML_FDCMP(block, FPR64(FSREG), FPR64(FTREG)); // fdcmp , } UML_SETc(block, COND_E, I0); // set i0,e UML_SETc(block, COND_NU, I1); // set i1,nu @@ -3245,13 +3087,11 @@ bool mips3_device::generate_cop1_fr0(drcuml_block *block, compiler_state *compil case 0x3b: if (IS_SINGLE(op)) /* C.UEQ.S - MIPS I */ { - UML_FSCMP(block, FSVALS_FR0, FTVALS_FR0); // fscmp , + UML_FSCMP(block, FPR32(FSREG), FPR32(FTREG)); // fscmp , } else /* C.UEQ.D - MIPS I */ { - generate_get_cop1_reg64(block, compiler, desc, FSREG, F0); // dmov f0, - generate_get_cop1_reg64(block, compiler, desc, FTREG, F1); // dmov f1, - UML_FDCMP(block, F0, F1); // fdcmp f0,f1 + UML_FDCMP(block, FPR64(FSREG), FPR64(FTREG)); // fdcmp , } UML_SETc(block, COND_U, I0); // set i0,u UML_SETc(block, COND_E, I1); // set i1,e @@ -3264,13 +3104,11 @@ bool mips3_device::generate_cop1_fr0(drcuml_block *block, compiler_state *compil case 0x3c: if (IS_SINGLE(op)) /* C.OLT.S - MIPS I */ { - UML_FSCMP(block, FSVALS_FR0, FTVALS_FR0); // fscmp , + UML_FSCMP(block, FPR32(FSREG), FPR32(FTREG)); // fscmp , } else /* C.OLT.D - MIPS I */ { - generate_get_cop1_reg64(block, compiler, desc, FSREG, F0); // dmov f0, - generate_get_cop1_reg64(block, compiler, desc, FTREG, F1); // dmov f1, - UML_FDCMP(block, F0, F1); // fdcmp f0,f1 + UML_FDCMP(block, FPR64(FSREG), FPR64(FTREG)); // fdcmp , } UML_SETc(block, COND_B, I0); // set i0,b UML_SETc(block, COND_NU, I1); // set i1,nu @@ -3283,13 +3121,11 @@ bool mips3_device::generate_cop1_fr0(drcuml_block *block, compiler_state *compil case 0x3d: if (IS_SINGLE(op)) /* C.ULT.S - MIPS I */ { - UML_FSCMP(block, FSVALS_FR0, FTVALS_FR0); // fscmp , + UML_FSCMP(block, FPR32(FSREG), FPR32(FTREG)); // fscmp , } else /* C.ULT.D - MIPS I */ { - generate_get_cop1_reg64(block, compiler, desc, FSREG, F0); // dmov f0, - generate_get_cop1_reg64(block, compiler, desc, FTREG, F1); // dmov f1, - UML_FDCMP(block, F0, F1); // fdcmp f0,f1 + UML_FDCMP(block, FPR64(FSREG), FPR64(FTREG)); // fdcmp , } UML_SETc(block, COND_U, I0); // set i0,u UML_SETc(block, COND_B, I1); // set i1,b @@ -3302,13 +3138,11 @@ bool mips3_device::generate_cop1_fr0(drcuml_block *block, compiler_state *compil case 0x3e: if (IS_SINGLE(op)) /* C.OLE.S - MIPS I */ { - UML_FSCMP(block, FSVALS_FR0, FTVALS_FR0); // fscmp , + UML_FSCMP(block, FPR32(FSREG), FPR32(FTREG)); // fscmp , } else /* C.OLE.D - MIPS I */ { - generate_get_cop1_reg64(block, compiler, desc, FSREG, F0); // dmov f0, - generate_get_cop1_reg64(block, compiler, desc, FTREG, F1); // dmov f1, - UML_FDCMP(block, F0, F1); // fdcmp f0,f1 + UML_FDCMP(block, FPR64(FSREG), FPR64(FTREG)); // fdcmp , } UML_SETc(block, COND_BE, I0); // set i0,be UML_SETc(block, COND_NU, I1); // set i1,nu @@ -3321,13 +3155,11 @@ bool mips3_device::generate_cop1_fr0(drcuml_block *block, compiler_state *compil case 0x3f: if (IS_SINGLE(op)) /* C.ULE.S - MIPS I */ { - UML_FSCMP(block, FSVALS_FR0, FTVALS_FR0); // fscmp , + UML_FSCMP(block, FPR32(FSREG), FPR32(FTREG)); // fscmp , } else /* C.ULE.D - MIPS I */ { - generate_get_cop1_reg64(block, compiler, desc, FSREG, F0); // dmov f0, - generate_get_cop1_reg64(block, compiler, desc, FTREG, F1); // dmov f1, - UML_FDCMP(block, F0, F1); // fdcmp f0,f1 + UML_FDCMP(block, FPR64(FSREG), FPR64(FTREG)); // fdcmp , } UML_SETc(block, COND_U, I0); // set i0,u UML_SETc(block, COND_BE, I1); // set i1,be @@ -3341,393 +3173,15 @@ bool mips3_device::generate_cop1_fr0(drcuml_block *block, compiler_state *compil return false; } -/*------------------------------------------------------- - generate_cop1_fr1 - compile COP1 opcodes in FR1 mode ----------------------------------------------------------*/ - -bool mips3_device::generate_cop1_fr1(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) -{ - uint32_t op = desc->opptr.l[0]; - code_label skip; - condition_t condition; - - check_cop1_access(block); - - switch (RSREG) - { - case 0x00: /* MFC1 - MIPS I */ - if (RTREG != 0) - { - UML_DSEXT(block, R64(RTREG), FPR32_FR0(RDREG), SIZE_DWORD); // dsext ,fpr[rdreg],dword - } - return true; - - case 0x01: /* DMFC1 - MIPS III */ - if (RTREG != 0) - { - generate_get_cop1_reg64_d2i(block, compiler, desc, RDREG, I0); - UML_DMOV(block, R64(RTREG), I0); - } - return true; - - case 0x02: /* CFC1 - MIPS I */ - if (RTREG != 0) - UML_DSEXT(block, R64(RTREG), CCR132(RDREG), SIZE_DWORD); // dsext ,ccr132[rdreg],dword - return true; - - case 0x04: /* MTC1 - MIPS I */ - UML_MOV(block, FPR32_FR0(RDREG), R32(RTREG)); // mov fpr[rdreg], - return true; - - case 0x05: /* DMTC1 - MIPS III */ - UML_DMOV(block, I0, R64(RTREG)); - generate_set_cop1_reg64_i2d(block, compiler, desc, RDREG, I0); - return true; - - case 0x06: /* CTC1 - MIPS I */ - if (RDREG != 31) - { - UML_DSEXT(block, CCR164(RDREG), R32(RTREG), SIZE_DWORD); // dsext ccr1[rdreg],,dword - } - else - { - UML_XOR(block, I0, CCR132(31), R32(RTREG)); // xor i0,ccr1[31], - UML_DSEXT(block, CCR164(31), R32(RTREG), SIZE_DWORD); // dsext ccr1[31],,dword - UML_TEST(block, I0, 3); // test i0,3 - UML_JMPc(block, COND_Z, skip = compiler->labelnum++); // jmp skip,Z - UML_AND(block, I0, CCR132(31), 3); // and i0,ccr1[31],3 - UML_LOAD(block, I0, &m_fpmode[0], I0, SIZE_BYTE, SCALE_x1); // load i0,fpmode,i0,byte - UML_SETFMOD(block, I0); // setfmod i0 - UML_LABEL(block, skip); // skip: - } - return true; - - case 0x08: /* BC */ - switch ((op >> 16) & 3) - { - case 0x00: /* BCzF - MIPS I */ - case 0x02: /* BCzFL - MIPS II */ - UML_TEST(block, CCR132(31), FCCMASK(op >> 18)); // test ccr1[31],fccmask[which] - UML_JMPc(block, COND_NZ, skip = compiler->labelnum++); // jmp skip,NZ - generate_delay_slot_and_branch(block, compiler, desc, 0); // - UML_LABEL(block, skip); // skip: - return true; - - case 0x01: /* BCzT - MIPS I */ - case 0x03: /* BCzTL - MIPS II */ - UML_TEST(block, CCR132(31), FCCMASK(op >> 18)); // test ccr1[31],fccmask[which] - UML_JMPc(block, COND_Z, skip = compiler->labelnum++); // jmp skip,Z - generate_delay_slot_and_branch(block, compiler, desc, 0); // - UML_LABEL(block, skip); // skip: - return true; - } - break; - - default: - switch (op & 0x3f) - { - case 0x00: - if (IS_SINGLE(op)) /* ADD.S - MIPS I */ - UML_FSADD(block, FDVALS_FR1, FSVALS_FR1, FTVALS_FR1); // fsadd ,, - else /* ADD.D - MIPS I */ - UML_FDADD(block, FDVALD_FR1, FSVALD_FR1, FTVALD_FR1); // fdadd ,, - return true; - - case 0x01: - if (IS_SINGLE(op)) /* SUB.S - MIPS I */ - UML_FSSUB(block, FDVALS_FR1, FSVALS_FR1, FTVALS_FR1); // fssub ,, - else /* SUB.D - MIPS I */ - UML_FDSUB(block, FDVALD_FR1, FSVALD_FR1, FTVALD_FR1); // fdsub ,, - return true; - - case 0x02: - if (IS_SINGLE(op)) /* MUL.S - MIPS I */ - UML_FSMUL(block, FDVALS_FR1, FSVALS_FR1, FTVALS_FR1); // fsmul ,, - else /* MUL.D - MIPS I */ - UML_FDMUL(block, FDVALD_FR1, FSVALD_FR1, FTVALD_FR1); // fdmul ,, - return true; - - case 0x03: - if (IS_SINGLE(op)) /* DIV.S - MIPS I */ - UML_FSDIV(block, FDVALS_FR1, FSVALS_FR1, FTVALS_FR1); // fsdiv ,, - else /* DIV.D - MIPS I */ - UML_FDDIV(block, FDVALD_FR1, FSVALD_FR1, FTVALD_FR1); // fddiv ,, - return true; - - case 0x04: - if (IS_SINGLE(op)) /* SQRT.S - MIPS II */ - UML_FSSQRT(block, FDVALS_FR1, FSVALS_FR1); // fssqrt , - else /* SQRT.D - MIPS II */ - UML_FDSQRT(block, FDVALD_FR1, FSVALD_FR1); // fdsqrt , - return true; - - case 0x05: - if (IS_SINGLE(op)) /* ABS.S - MIPS I */ - UML_FSABS(block, FDVALS_FR1, FSVALS_FR1); // fsabs , - else /* ABS.D - MIPS I */ - UML_FDABS(block, FDVALD_FR1, FSVALD_FR1); // fdabs , - return true; - - case 0x06: - if (IS_SINGLE(op)) /* MOV.S - MIPS I */ - UML_FSMOV(block, FDVALS_FR1, FSVALS_FR1); // fsmov , - else /* MOV.D - MIPS I */ - UML_FDMOV(block, FDVALD_FR1, FSVALD_FR1); // fdmov , - return true; - - case 0x07: - if (IS_SINGLE(op)) /* NEG.S - MIPS I */ - { - UML_FSNEG(block, FDVALS_FR1, FSVALS_FR1); // fsneg , - UML_CMP(block, FSVALS_FR1, 0); // cmp ,0.0 - UML_MOVc(block, COND_E, FDVALS_FR1, 0x80000000); // mov ,-0.0,e - } - else /* NEG.D - MIPS I */ - { - UML_FDNEG(block, FDVALD_FR1, FSVALD_FR1); // fdneg , - UML_DCMP(block, FSVALD_FR1, 0); // dcmp ,0.0 - UML_DMOVc(block, COND_E, FDVALD_FR1, 0x8000000000000000L);// mov ,-0.0,e - } - return true; - - case 0x08: - if (IS_SINGLE(op)) /* ROUND.L.S - MIPS III */ - UML_FSTOINT(block, FDVALD_FR1, FSVALS_FR1, SIZE_QWORD, ROUND_ROUND); // fstoint f0,,qword,round - else /* ROUND.L.D - MIPS III */ - UML_FDTOINT(block, FDVALD_FR1, FSVALD_FR1, SIZE_QWORD, ROUND_ROUND); // fdtoint f0,f0,qword,round - return true; - - case 0x09: - if (IS_SINGLE(op)) /* TRUNC.L.S - MIPS III */ - UML_FSTOINT(block, FDVALD_FR1, FSVALS_FR1, SIZE_QWORD, ROUND_TRUNC); // fstoint f0,,qword,trunc - else /* TRUNC.L.D - MIPS III */ - UML_FDTOINT(block, FDVALD_FR1, FSVALD_FR1, SIZE_QWORD, ROUND_TRUNC); // fdtoint f0,f0,qword,trunc - return true; - - case 0x0a: - if (IS_SINGLE(op)) /* CEIL.L.S - MIPS III */ - UML_FSTOINT(block, FDVALD_FR1, FSVALS_FR1, SIZE_QWORD, ROUND_CEIL); // fstoint f0,,qword,ceil - else /* CEIL.L.D - MIPS III */ - UML_FDTOINT(block, FDVALD_FR1, FSVALD_FR1, SIZE_QWORD, ROUND_CEIL); // fdtoint f0,,qword,ceil - return true; - - case 0x0b: - if (IS_SINGLE(op)) /* FLOOR.L.S - MIPS III */ - UML_FSTOINT(block, FDVALD_FR1, FSVALS_FR1, SIZE_QWORD, ROUND_FLOOR); // fstoint f0,,qword,floor - else /* FLOOR.L.D - MIPS III */ - UML_FDTOINT(block, FDVALD_FR1, FSVALD_FR1, SIZE_QWORD, ROUND_FLOOR); // fdtoint f0,,qword,floor - return true; - - case 0x0c: - if (IS_SINGLE(op)) /* ROUND.W.S - MIPS II */ - UML_FSTOINT(block, FDVALS_FR1, FSVALS_FR1, SIZE_DWORD, ROUND_ROUND); // fstoint ,,dword,round - else /* ROUND.W.D - MIPS II */ - UML_FDTOINT(block, FDVALS_FR1, FSVALD_FR1, SIZE_DWORD, ROUND_ROUND); // fdtoint ,F0,dword,round - return true; - - case 0x0d: - if (IS_SINGLE(op)) /* TRUNC.W.S - MIPS II */ - UML_FSTOINT(block, FDVALS_FR1, FSVALS_FR1, SIZE_DWORD, ROUND_TRUNC);// fstoint ,,dword,trunc - else /* TRUNC.W.D - MIPS II */ - UML_FDTOINT(block, FDVALS_FR1, FSVALD_FR1, SIZE_DWORD, ROUND_TRUNC); // fdtoint ,F0,dword,trunc - return true; - - case 0x0e: - if (IS_SINGLE(op)) /* CEIL.W.S - MIPS II */ - UML_FSTOINT(block, FDVALS_FR1, FSVALS_FR1, SIZE_DWORD, ROUND_CEIL);// fstoint ,,dword,ceil - else /* CEIL.W.D - MIPS II */ - UML_FDTOINT(block, FDVALS_FR1, FSVALD_FR1, SIZE_DWORD, ROUND_CEIL); // fdtoint ,F0,dword,ceil - return true; - - case 0x0f: - if (IS_SINGLE(op)) /* FLOOR.W.S - MIPS II */ - UML_FSTOINT(block, FDVALS_FR1, FSVALS_FR1, SIZE_DWORD, ROUND_FLOOR);// fstoint ,,dword,floor - else /* FLOOR.W.D - MIPS II */ - UML_FDTOINT(block, FDVALS_FR1, FSVALD_FR1, SIZE_DWORD, ROUND_FLOOR); // fdtoint ,F0,dword,floor - return true; - - case 0x11: - UML_TEST(block, CCR132(31), FCCMASK(op >> 18)); // test ccr31,fccmask[op] - condition = ((op >> 16) & 1) ? COND_NZ : COND_Z; - if (IS_SINGLE(op)) /* MOVT/F.S - MIPS IV */ - UML_FSMOVc(block, condition, FDVALS_FR1, FSVALS_FR1); // fsmov ,,condition - else /* MOVT/F.D - MIPS IV */ - UML_FDMOVc(block, condition, FDVALD_FR1, FSVALD_FR1); // fdmov ,,condition - return true; - - case 0x12: - UML_DCMP(block, R64(RTREG), 0); // dcmp ,0 - if (IS_SINGLE(op)) /* MOVZ.S - MIPS IV */ - UML_FSMOVc(block, COND_Z, FDVALS_FR1, FSVALS_FR1); // fsmov ,,Z - else /* MOVZ.D - MIPS IV */ - UML_FDMOVc(block, COND_Z, FDVALD_FR1, FSVALD_FR1); // fdmov ,,Z - return true; - - case 0x13: - UML_DCMP(block, R64(RTREG), 0); // dcmp ,0 - if (IS_SINGLE(op)) /* MOVN.S - MIPS IV */ - UML_FSMOVc(block, COND_NZ, FDVALS_FR1, FSVALS_FR1); // fsmov ,,NZ - else /* MOVN.D - MIPS IV */ - UML_FDMOVc(block, COND_NZ, FDVALD_FR1, FSVALD_FR1); // fdmov ,,NZ - return true; - - case 0x15: - if (IS_SINGLE(op)) /* RECIP.S - MIPS IV */ - UML_FSRECIP(block, FDVALS_FR1, FSVALS_FR1); // fsrecip , - else /* RECIP.D - MIPS IV */ - UML_FDRECIP(block, FDVALD_FR1, FSVALD_FR1); // fdrecip , - return true; - - case 0x16: - if (IS_SINGLE(op)) /* RSQRT.S - MIPS IV */ - UML_FSRSQRT(block, FDVALS_FR1, FSVALS_FR1); // fsrsqrt , - else /* RSQRT.D - MIPS IV */ - UML_FDRSQRT(block, FDVALD_FR1, FSVALD_FR1); // fdrsqrt , - return true; - - case 0x20: - if (IS_INTEGRAL(op)) - { - if (IS_SINGLE(op)) /* CVT.S.W - MIPS I */ - UML_FSFRINT(block, FDVALS_FR1, FSVALS_FR1, SIZE_DWORD); // fsfrint ,,dword - else /* CVT.S.L - MIPS I */ - UML_FSFRINT(block, FDVALS_FR1, FSVALD_FR1, SIZE_QWORD); // fsfrint ,,qword - } - else /* CVT.S.D - MIPS I */ - { - UML_FSFRFLT(block, FDVALS_FR1, FSVALD_FR1, SIZE_QWORD); // fsfrflt ,f0,qword - } - return true; - - case 0x21: - if (IS_INTEGRAL(op)) - { - if (IS_SINGLE(op)) /* CVT.D.W - MIPS I */ - UML_FDFRINT(block, FDVALD_FR1, FSVALS_FR1, SIZE_DWORD); // fdfrint ,,dword - else /* CVT.D.L - MIPS I */ - UML_FDFRINT(block, FDVALD_FR1, FSVALD_FR1, SIZE_QWORD); // fdfrint ,,qword - } - else /* CVT.D.S - MIPS I */ - { - UML_FDFRFLT(block, FDVALD_FR1, FSVALS_FR1, SIZE_DWORD); // fdfrflt ,,dword - } - return true; - - case 0x24: - if (IS_SINGLE(op)) /* CVT.W.S - MIPS I */ - UML_FSTOINT(block, FDVALS_FR1, FSVALS_FR1, SIZE_DWORD, ROUND_DEFAULT); // fstoint ,,dword,default - else /* CVT.W.D - MIPS I */ - UML_FDTOINT(block, FDVALS_FR1, FSVALD_FR1, SIZE_DWORD, ROUND_DEFAULT); // fdtoint ,,dword,default - return true; - - case 0x25: - if (IS_SINGLE(op)) /* CVT.L.S - MIPS I */ - UML_FSTOINT(block, FDVALD_FR1, FSVALS_FR1, SIZE_QWORD, ROUND_DEFAULT); // fstoint ,,qword,default - else /* CVT.L.D - MIPS I */ - UML_FDTOINT(block, FDVALD_FR1, FSVALD_FR1, SIZE_QWORD, ROUND_DEFAULT); // fdtoint ,,qword,default - return true; - - case 0x30: - case 0x38: /* C.F.S/D - MIPS I */ - UML_AND(block, CCR132(31), CCR132(31), ~FCCMASK(op >> 8)); // and ccr31,ccr31,~fccmask[op] - return true; - - case 0x31: - case 0x39: - if (IS_SINGLE(op)) /* C.UN.S - MIPS I */ - UML_FSCMP(block, FSVALS_FR1, FTVALS_FR1); // fscmp , - else /* C.UN.D - MIPS I */ - UML_FDCMP(block, FSVALD_FR1, FTVALD_FR1); // fdcmp , - UML_SETc(block, COND_U, I0); // set i0,u - UML_ROLINS(block, CCR132(31), I0, FCCSHIFT(op >> 8), FCCMASK(op >> 8)); // rolins ccr31,i0,fccshift,fcc - return true; - - case 0x32: - case 0x3a: - if (IS_SINGLE(op)) /* C.EQ.S - MIPS I */ - UML_FSCMP(block, FSVALS_FR1, FTVALS_FR1); // fscmp , - else /* C.EQ.D - MIPS I */ - UML_FDCMP(block, FSVALD_FR1, FTVALD_FR1); // fdcmp , - UML_SETc(block, COND_E, I0); // set i0,e - UML_SETc(block, COND_NU, I1); // set i1,nu - UML_AND(block, I0, I0, I1); // and i0,i0,i1 - UML_ROLINS(block, CCR132(31), I0, FCCSHIFT(op >> 8), FCCMASK(op >> 8)); // rolins ccr31,i0,fccshift,fcc - return true; - - case 0x33: - case 0x3b: - if (IS_SINGLE(op)) /* C.UEQ.S - MIPS I */ - UML_FSCMP(block, FSVALS_FR1, FTVALS_FR1); // fscmp , - else /* C.UEQ.D - MIPS I */ - UML_FDCMP(block, FSVALD_FR1, FTVALD_FR1); // fdcmp f0,f1 - UML_SETc(block, COND_U, I0); // set i0,u - UML_SETc(block, COND_E, I1); // set i1,e - UML_OR(block, I0, I0, I1); // or i0,i0,i1 - UML_ROLINS(block, CCR132(31), I0, FCCSHIFT(op >> 8), FCCMASK(op >> 8)); // rolins ccr31,i0,fccshift,fcc - return true; - - case 0x34: - case 0x3c: - if (IS_SINGLE(op)) /* C.OLT.S - MIPS I */ - UML_FSCMP(block, FSVALS_FR1, FTVALS_FR1); // fscmp , - else /* C.OLT.D - MIPS I */ - UML_FDCMP(block, FSVALD_FR1, FTVALD_FR1); // fdcmp f0,f1 - UML_SETc(block, COND_B, I0); // set i0,b - UML_SETc(block, COND_NU, I1); // set i1,nu - UML_AND(block, I0, I0, I1); // and i0,i0,i1 - UML_ROLINS(block, CCR132(31), I0, FCCSHIFT(op >> 8), FCCMASK(op >> 8)); // rolins ccr31,i0,fccshift,fcc - return true; - - case 0x35: - case 0x3d: - if (IS_SINGLE(op)) /* C.ULT.S - MIPS I */ - UML_FSCMP(block, FSVALS_FR1, FTVALS_FR1); // fscmp , - else /* C.ULT.D - MIPS I */ - UML_FDCMP(block, FSVALD_FR1, FTVALD_FR1); // fdcmp f0,f1 - UML_SETc(block, COND_U, I0); // set i0,u - UML_SETc(block, COND_B, I1); // set i1,b - UML_OR(block, I0, I0, I1); // or i0,i0,i1 - UML_ROLINS(block, CCR132(31), I0, FCCSHIFT(op >> 8), FCCMASK(op >> 8)); // rolins ccr31,i0,fccshift,fcc - return true; - - case 0x36: - case 0x3e: - if (IS_SINGLE(op)) /* C.OLE.S - MIPS I */ - UML_FSCMP(block, FSVALS_FR1, FTVALS_FR1); // fscmp , - else /* C.OLE.D - MIPS I */ - UML_FDCMP(block, FSVALD_FR1, FTVALD_FR1); // fdcmp f0,f1 - UML_SETc(block, COND_BE, I0); // set i0,be - UML_SETc(block, COND_NU, I1); // set i1,nu - UML_AND(block, I0, I0, I1); // and i0,i0,i1 - UML_ROLINS(block, CCR132(31), I0, FCCSHIFT(op >> 8), FCCMASK(op >> 8)); // rolins ccr31,i0,fccshift,fcc - return true; - - case 0x37: - case 0x3f: - if (IS_SINGLE(op)) /* C.ULE.S - MIPS I */ - UML_FSCMP(block, FSVALS_FR1, FTVALS_FR1); // fscmp , - else /* C.ULE.D - MIPS I */ - UML_FDCMP(block, FSVALD_FR1, FTVALD_FR1); // fdcmp f0,f1 - UML_SETc(block, COND_U, I0); // set i0,u - UML_SETc(block, COND_BE, I1); // set i1,be - UML_OR(block, I0, I0, I1); // or i0,i0,i1 - UML_ROLINS(block, CCR132(31), I0, FCCSHIFT(op >> 8), FCCMASK(op >> 8)); // rolins ccr31,i0,fccshift,fcc - return true; - } - break; - } - return false; -} - /*************************************************************************** COP1X RECOMPILATION ***************************************************************************/ /*---------------------------------------------------------- - generate_cop1x_fr0 - compile COP1X opcodes in FR0 mode + generate_cop1x - compile COP1X opcodes ----------------------------------------------------------*/ -bool mips3_device::generate_cop1x_fr0(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +bool mips3_device::generate_cop1x(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) { int in_delay_slot = ((desc->flags & OPFLAG_IN_DELAY_SLOT) != 0); uint32_t op = desc->opptr.l[0]; @@ -3739,7 +3193,7 @@ bool mips3_device::generate_cop1x_fr0(drcuml_block *block, compiler_state *compi case 0x00: /* LWXC1 - MIPS IV */ UML_ADD(block, I0, R32(RSREG), R32(RTREG)); // add i0,, UML_CALLH(block, *m_read32[m_core->mode >> 1]); // callh read32 - UML_MOV(block, FDVALS_FR0, I0); // mov ,i0 + UML_MOV(block, FPR32(FDREG), I0); // mov ,i0 if (!in_delay_slot) generate_update_cycles(block, compiler, desc->pc + 4, true); return true; @@ -3747,22 +3201,22 @@ bool mips3_device::generate_cop1x_fr0(drcuml_block *block, compiler_state *compi case 0x01: /* LDXC1 - MIPS IV */ UML_ADD(block, I0, R32(RSREG), R32(RTREG)); // add i0,, UML_CALLH(block, *m_read64[m_core->mode >> 1]); // callh read64 - generate_set_cop1_reg64_i2d(block, compiler, desc, RTREG, I0); + UML_DMOV(block, FPR64(FDREG), I0); // dmov ,i0 if (!in_delay_slot) generate_update_cycles(block, compiler, desc->pc + 4, true); return true; case 0x08: /* SWXC1 - MIPS IV */ UML_ADD(block, I0, R32(RSREG), R32(RTREG)); // add i0,, - UML_MOV(block, I1, FSVALS_FR0); // mov i1, + UML_MOV(block, I1, FPR32(FSREG)); // mov i1, UML_CALLH(block, *m_write32[m_core->mode >> 1]); // callh write32 if (!in_delay_slot) generate_update_cycles(block, compiler, desc->pc + 4, true); return true; case 0x09: /* SDXC1 - MIPS IV */ - generate_get_cop1_reg64_d2i(block, compiler, desc, FSREG, I1); UML_ADD(block, I0, R32(RSREG), R32(RTREG)); // add i0,, + UML_DMOV(block, I1, FPR64(FSREG)); // dmov i1, UML_CALLH(block, *m_write64[m_core->mode >> 1]); // callh write64 if (!in_delay_slot) generate_update_cycles(block, compiler, desc->pc + 4, true); @@ -3772,61 +3226,45 @@ bool mips3_device::generate_cop1x_fr0(drcuml_block *block, compiler_state *compi return true; case 0x20: /* MADD.S - MIPS IV */ - UML_FSMUL(block, F0, FSVALS_FR0, FTVALS_FR0); // fsmul f0,, - UML_FSADD(block, FDVALS_FR0, F0, FRVALS_FR0); // fsadd ,f0, + UML_FSMUL(block, F0, FPR32(FSREG), FPR32(FTREG)); // fsmul f0,, + UML_FSADD(block, FPR32(FDREG), F0, FPR32(FRREG)); // fsadd ,f0, return true; case 0x21: /* MADD.D - MIPS IV */ - generate_get_cop1_reg64(block, compiler, desc, FSREG, F0); - generate_get_cop1_reg64(block, compiler, desc, FTREG, F1); - generate_get_cop1_reg64(block, compiler, desc, FRREG, F2); - UML_FDMUL(block, F3, F0, F1); // fdmul f3,f0,f1 - UML_FDADD(block, F3, F3, F2); // fdadd f3,f3,f2 - generate_set_cop1_reg64(block, compiler, desc, FDREG, F3); // dmov ,f3 + UML_FDMUL(block, F0, FPR64(FSREG), FPR64(FTREG)); // fdmul f0,, + UML_FDADD(block, FPR64(FDREG), F0, FPR64(FRREG)); // fdadd ,f0, return true; case 0x28: /* MSUB.S - MIPS IV */ - UML_FSMUL(block, F0, FSVALS_FR0, FTVALS_FR0); // fsmul f0,, - UML_FSSUB(block, FDVALS_FR0, F0, FRVALS_FR0); // fssub ,f0, + UML_FSMUL(block, F0, FPR32(FSREG), FPR32(FTREG)); // fsmul f0,, + UML_FSSUB(block, FPR32(FDREG), F0, FPR32(FRREG)); // fssub ,f0, return true; case 0x29: /* MSUB.D - MIPS IV */ - generate_get_cop1_reg64(block, compiler, desc, FSREG, F0); - generate_get_cop1_reg64(block, compiler, desc, FTREG, F1); - generate_get_cop1_reg64(block, compiler, desc, FRREG, F2); - UML_FDMUL(block, F3, F0, F1); // fdmul f3,f0,f1 - UML_FDSUB(block, F3, F3, F2); // fdadd f3,f3,f2 - generate_set_cop1_reg64(block, compiler, desc, FDREG, F3); // dmov ,f3 + UML_FDMUL(block, F0, FPR64(FSREG), FPR64(FTREG)); // fdmul f0,, + UML_FDSUB(block, FPR64(FDREG), F0, FPR64(FRREG)); // fdadd ,f0, return true; case 0x30: /* NMADD.S - MIPS IV */ - UML_FSMUL(block, F0, FSVALS_FR0, FTVALS_FR0); // fsmul f0,, - UML_FSADD(block, F0, F0, FRVALS_FR0); // fsadd f0,f0, - UML_FSNEG(block, FDVALS_FR0, F0); // fsneg ,f0 + UML_FSMUL(block, F0, FPR32(FSREG), FPR32(FTREG)); // fsmul f0,, + UML_FSADD(block, F0, F0, FPR32(FRREG)); // fsadd f0,f0, + UML_FSNEG(block, FPR32(FDREG), F0); // fsneg ,f0 return true; case 0x31: /* NMADD.D - MIPS IV */ - generate_get_cop1_reg64(block, compiler, desc, FSREG, F0); - generate_get_cop1_reg64(block, compiler, desc, FTREG, F1); - generate_get_cop1_reg64(block, compiler, desc, FRREG, F2); - UML_FDMUL(block, F3, F0, F1); // fdmul f3,f0,f1 - UML_FDADD(block, F3, F3, F2); // fdadd f3,f3,f2 - UML_FDNEG(block, F3, F3); // fdneg f3,f3 - generate_set_cop1_reg64(block, compiler, desc, FDREG, F3); // dmov ,f3 + UML_FDMUL(block, F0, FPR64(FSREG), FPR64(FTREG)); // fdmul f0,, + UML_FDADD(block, F0, F0, FPR64(FRREG)); // fdadd f0,f0, + UML_FDNEG(block, FPR64(FDREG), F0); // fdneg ,f0 return true; case 0x38: /* NMSUB.S - MIPS IV */ - UML_FSMUL(block, F0, FSVALS_FR0, FTVALS_FR0); // fsmul f0,, - UML_FSSUB(block, FDVALS_FR0, FRVALS_FR0, F0); // fssub ,,f0 + UML_FSMUL(block, F0, FPR32(FSREG), FPR32(FTREG)); // fsmul f0,, + UML_FSSUB(block, FPR32(FDREG), FPR32(FRREG), F0); // fssub ,,f0 return true; case 0x39: /* NMSUB.D - MIPS IV */ - generate_get_cop1_reg64(block, compiler, desc, FSREG, F0); - generate_get_cop1_reg64(block, compiler, desc, FTREG, F1); - generate_get_cop1_reg64(block, compiler, desc, FRREG, F2); - UML_FDMUL(block, F3, F0, F1); // fdmul f4,f0,f1 - UML_FDSUB(block, F3, F2, F0); // fdsub f3,f2,f0 - generate_set_cop1_reg64(block, compiler, desc, FDREG, F3); // dmov ,f3 + UML_FDMUL(block, F0, FPR64(FSREG), FPR64(FTREG)); // fdmul f0,, + UML_FDSUB(block, FPR64(FDREG), FPR64(FRREG), F0); // fdsub ,,f0 return true; default: @@ -3836,104 +3274,6 @@ bool mips3_device::generate_cop1x_fr0(drcuml_block *block, compiler_state *compi return false; } -/*---------------------------------------------------------- - generate_cop1x_fr1 - compile COP1X opcodes in FR1 mode -----------------------------------------------------------*/ - -bool mips3_device::generate_cop1x_fr1(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) -{ - int in_delay_slot = ((desc->flags & OPFLAG_IN_DELAY_SLOT) != 0); - uint32_t op = desc->opptr.l[0]; - - check_cop1_access(block); - - switch (op & 0x3f) - { - case 0x00: /* LWXC1 - MIPS IV */ - UML_ADD(block, I0, R32(RSREG), R32(RTREG)); // add i0,, - UML_CALLH(block, *m_read32[m_core->mode >> 1]); // callh read32 - UML_MOV(block, FDVALS_FR1, I0); // mov ,i0 - if (!in_delay_slot) - generate_update_cycles(block, compiler, desc->pc + 4, true); - return true; - - case 0x01: /* LDXC1 - MIPS IV */ - UML_ADD(block, I0, R32(RSREG), R32(RTREG)); // add i0,, - UML_CALLH(block, *m_read64[m_core->mode >> 1]); // callh read64 - UML_DMOV(block, FDVALD_FR1, I0); // dmov ,i0 - if (!in_delay_slot) - generate_update_cycles(block, compiler, desc->pc + 4, true); - return true; - - case 0x08: /* SWXC1 - MIPS IV */ - UML_ADD(block, I0, R32(RSREG), R32(RTREG)); // add i0,, - UML_MOV(block, I1, FSVALS_FR1); // mov i1, - UML_CALLH(block, *m_write32[m_core->mode >> 1]);// callh write32 - if (!in_delay_slot) - generate_update_cycles(block, compiler, desc->pc + 4, true); - return true; - - case 0x09: /* SDXC1 - MIPS IV */ - generate_get_cop1_reg64_d2i(block, compiler, desc, FSREG, I1); - UML_ADD(block, I0, R32(RSREG), R32(RTREG)); // add i0,, - UML_CALLH(block, *m_write64[m_core->mode >> 1]); // callh write64 - if (!in_delay_slot) - generate_update_cycles(block, compiler, desc->pc + 4, true); - return true; - - case 0x0f: /* PREFX */ - return true; - - case 0x20: /* MADD.S - MIPS IV */ - UML_FSMUL(block, F0, FSVALS_FR1, FTVALS_FR1); // fsmul f0,, - UML_FSADD(block, FDVALS_FR1, F0, FRVALS_FR1); // fsadd ,f0, - return true; - - case 0x21: /* MADD.D - MIPS IV */ - UML_FDMUL(block, F0, FSVALD_FR1, FTVALD_FR1); // fdmul f0,, - UML_FDADD(block, FDVALD_FR1, F0, FRVALD_FR1); // fdadd ,f0, - return true; - - case 0x28: /* MSUB.S - MIPS IV */ - UML_FSMUL(block, F0, FSVALS_FR1, FTVALS_FR1); // fsmul f0,, - UML_FSSUB(block, FDVALS_FR1, F0, FRVALS_FR1); // fssub ,f0, - return true; - - case 0x29: /* MSUB.D - MIPS IV */ - UML_FDMUL(block, F0, FSVALD_FR1, FTVALD_FR1); // fdmul f0,, - UML_FDSUB(block, FDVALD_FR1, F0, FRVALD_FR1); // fdsub ,f0, - return true; - - case 0x30: /* NMADD.S - MIPS IV */ - UML_FSMUL(block, F0, FSVALS_FR1, FTVALS_FR1); // fsmul f0,, - UML_FSADD(block, F0, F0, FRVALS_FR1); // fsadd f0,f0, - UML_FSNEG(block, FDVALS_FR1, F0); // fsneg ,f0 - return true; - - case 0x31: /* NMADD.D - MIPS IV */ - UML_FDMUL(block, F0, FSVALD_FR1, FTVALD_FR1); // fdmul f0,, - UML_FDADD(block, F0, F0, FRVALD_FR1); // fdadd f0,f0, - UML_FDNEG(block, FDVALD_FR1, F0); // fdneg ,f0 - return true; - - case 0x38: /* NMSUB.S - MIPS IV */ - UML_FSMUL(block, F0, FSVALS_FR1, FTVALS_FR1); // fsmul f0,, - UML_FSSUB(block, FDVALS_FR1, FRVALS_FR1, F0); // fssub ,,f0 - return true; - - case 0x39: /* NMSUB.D - MIPS IV */ - UML_FDMUL(block, F0, FSVALD_FR1, FTVALD_FR1); // fdmul f0,, - UML_FDSUB(block, FDVALD_FR1, FRVALD_FR1, F1); // fdsub ,,f0 - return true; - - default: - fprintf(stderr, "cop1x %X\n", op); - break; - } - return false; -} - - /*************************************************************************** CODE LOGGING HELPERS ***************************************************************************/