Previous 199869 Revisions Next

r36633 Wednesday 25th March, 2015 at 13:28:02 UTC by Ryan Holtz
- mips3: Add integer divide-by-zero handling to MIPS III cores. [MooglyGuy]
[src/emu/cpu/mips]mips3.c mips3.h mips3drc.c

trunk/src/emu/cpu/mips/mips3.c
r245144r245145
24472447   m_core->ccr[2][idx] = val;
24482448}
24492449
2450inline void mips3_device::handle_integer_divide_by_zero(UINT32 op)
2451{
2452   HIVAL64 = (INT32)RSVAL32;
2453   if (m_flavor == MIPS3_TYPE_VR4300)
2454   {
2455      if (RSVAL32 >= 0)
2456      {
2457         LOVAL64 = -1;
2458      }
2459      else
2460      {
2461         LOVAL64 = 1;
2462      }
2463   }
2464   else
2465   {
2466      if (RSVAL32 >= 0)
2467      {
2468      }
2469      else
2470      {
2471      }
2472   }
2473}
2474
24502475inline void mips3_device::handle_cop2(UINT32 op)
24512476{
24522477   if (!(SR & SR_COP2))
r245144r245145
26162641                     LOVAL64 = (INT32)((INT32)RSVAL32 / (INT32)RTVAL32);
26172642                     HIVAL64 = (INT32)((INT32)RSVAL32 % (INT32)RTVAL32);
26182643                  }
2644                  else
2645                  {
2646                     handle_integer_divide_by_zero(op);
2647                  }
26192648                  m_core->icount -= 35;
26202649                  break;
26212650               case 0x1b:  /* DIVU */
r245144r245145
26242653                     LOVAL64 = (INT32)(RSVAL32 / RTVAL32);
26252654                     HIVAL64 = (INT32)(RSVAL32 % RTVAL32);
26262655                  }
2656                  else
2657                  {
2658                     handle_integer_divide_by_zero(op);
2659                  }
26272660                  m_core->icount -= 35;
26282661                  break;
26292662               case 0x1c:  /* DMULT */
trunk/src/emu/cpu/mips/mips3.h
r245144r245145
511511   UINT64 get_cop2_creg(int idx);
512512   void set_cop2_creg(int idx, UINT64 val);
513513   void handle_cop2(UINT32 op);
514   void handle_integer_divide_by_zero(UINT32 op);
514515   void lwl_be(UINT32 op);
515516   void lwr_be(UINT32 op);
516517   void ldl_be(UINT32 op);
r245144r245145
756757#define MIPS3DRC_STRICT_COP2        0x0008          /* validate all COP2 instructions */
757758#define MIPS3DRC_FLUSH_PC           0x0010          /* flush the PC value before each memory access */
758759#define MIPS3DRC_CHECK_OVERFLOWS    0x0020          /* actually check overflows on add/sub instructions */
760#define MIPS3DRC_ACCURATE_DIVZERO   0x0040          /* load correct values into HI/LO on integer divide-by-zero */
759761
760762#define MIPS3DRC_COMPATIBLE_OPTIONS (MIPS3DRC_STRICT_VERIFY | MIPS3DRC_STRICT_COP1 | MIPS3DRC_STRICT_COP0 | MIPS3DRC_STRICT_COP2 | MIPS3DRC_FLUSH_PC)
761763#define MIPS3DRC_FASTEST_OPTIONS    (0)
trunk/src/emu/cpu/mips/mips3drc.c
r245144r245145
20542054         return TRUE;
20552055
20562056      case 0x1a:  /* DIV - MIPS I */
2057         UML_DIVS(block, I0, I1, R32(RSREG), R32(RTREG));                // divs    i0,i1,<rsreg>,<rtreg>
2058         UML_DSEXT(block, LO64, I0, SIZE_DWORD);                                 // dsext   lo,i0,dword
2059         UML_DSEXT(block, HI64, I1, SIZE_DWORD);                                 // dsext   hi,i1,dword
2057      {
2058         if (m_drcoptions & MIPS3DRC_ACCURATE_DIVZERO)
2059         {
2060            code_label divzero, done;
2061
2062            UML_CMP(block, R32(RTREG), 0);                                      // cmp     <rtreg>, 0
2063            UML_JMPc(block, COND_E, divzero = compiler->labelnum++);         // jmp     divzero,E
2064
2065            UML_DIVS(block, I0, I1, R32(RSREG), R32(RTREG));                    // divs    i0,i1,<rsreg>,<rtreg>
2066            UML_DSEXT(block, LO64, I0, SIZE_DWORD);                             // dsext   lo,i0,dword
2067            UML_DSEXT(block, HI64, I1, SIZE_DWORD);                             // dsext   hi,i1,dword
2068            UML_JMP(block, done = compiler->labelnum++);                        // jmp     done
2069
2070            UML_LABEL(block, divzero);                                          // divzero:
2071            if (m_flavor != MIPS3_TYPE_VR4300)
2072            {
2073               UML_MOVc(block, COND_L, I0, 0x00000001);                        // mov     i0,0x00000001,L
2074               UML_MOVc(block, COND_GE, I0, 0xffffffff);                       // mov     i0,0xffffffff,GE
2075            }
2076            else
2077            {
2078               UML_MOVc(block, COND_L, I0, 0x80000001);                        // mov     i0,0x80000001,L
2079               UML_MOVc(block, COND_GE, I0, 0x7fffffff);                       // mov     i0,0x7fffffff,GE
2080            }
2081            UML_DSEXT(block, HI64, R32(RSREG), SIZE_DWORD);                     // dsext   hi,<rsreg>,dword
2082            UML_DSEXT(block, LO64, I0, SIZE_DWORD);                             // dsext   lo,i0,dword
2083
2084            UML_LABEL(block, done);                                             // done:
2085         }
2086         else
2087         {
2088            UML_DIVS(block, I0, I1, R32(RSREG), R32(RTREG));                    // divs    i0,i1,<rsreg>,<rtreg>
2089            UML_DSEXT(block, LO64, I0, SIZE_DWORD);                             // dsext   lo,i0,dword
2090            UML_DSEXT(block, HI64, I1, SIZE_DWORD);                             // dsext   hi,i1,dword
2091         }
20602092         return TRUE;
2093      }
20612094
20622095      case 0x1b:  /* DIVU - MIPS I */
2063         UML_DIVU(block, I0, I1, R32(RSREG), R32(RTREG));                // divu    i0,i1,<rsreg>,<rtreg>
2064         UML_DSEXT(block, LO64, I0, SIZE_DWORD);                                 // dsext   lo,i0,dword
2065         UML_DSEXT(block, HI64, I1, SIZE_DWORD);                                 // dsext   hi,i1,dword
2096         if (m_drcoptions & MIPS3DRC_ACCURATE_DIVZERO)
2097         {
2098            code_label divzero, done;
2099
2100            UML_CMP(block, R32(RTREG), 0);                                      // cmp     <rtreg>, 0
2101            UML_JMPc(block, COND_E, divzero = compiler->labelnum++);         // jmp     divzero,E
2102
2103            UML_DIVU(block, I0, I1, R32(RSREG), R32(RTREG));                    // divu    i0,i1,<rsreg>,<rtreg>
2104            UML_DSEXT(block, LO64, I0, SIZE_DWORD);                             // dsext   lo,i0,dword
2105            UML_DSEXT(block, HI64, I1, SIZE_DWORD);                             // dsext   hi,i1,dword
2106            UML_JMP(block, done = compiler->labelnum++);                        // jmp     done
2107
2108            UML_LABEL(block, divzero);                                          // divzero:
2109            if (m_flavor != MIPS3_TYPE_VR4300)
2110            {
2111               UML_MOVc(block, COND_L, I0, 0x00000001);                        // mov     i0,0x00000001,L
2112               UML_MOVc(block, COND_GE, I0, 0xffffffff);                       // mov     i0,0xffffffff,GE
2113            }
2114            else
2115            {
2116               UML_MOVc(block, COND_L, I0, 0x80000001);                        // mov     i0,0x80000001,L
2117               UML_MOVc(block, COND_GE, I0, 0x7fffffff);                       // mov     i0,0x7fffffff,GE
2118            }
2119            UML_DSEXT(block, HI64, R32(RSREG), SIZE_DWORD);                     // dsext   hi,<rsreg>,dword
2120            UML_DSEXT(block, LO64, I0, SIZE_DWORD);                             // dsext   lo,i0,dword
2121
2122            UML_LABEL(block, done);                                             // done:
2123         }
2124         else
2125         {
2126            UML_DIVU(block, I0, I1, R32(RSREG), R32(RTREG));                    // divu    i0,i1,<rsreg>,<rtreg>
2127            UML_DSEXT(block, LO64, I0, SIZE_DWORD);                             // dsext   lo,i0,dword
2128            UML_DSEXT(block, HI64, I1, SIZE_DWORD);                             // dsext   hi,i1,dword
2129         }
20662130         return TRUE;
20672131
20682132      case 0x1e:  /* DDIV - MIPS III */


Previous 199869 Revisions Next


© 1997-2024 The MAME Team