Advertisement
Guest User

speed optimize for arm+x86 mame2003-libretro mips3.c

a guest
Feb 22nd, 2023
116
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 75.41 KB | Source Code | 0 0
  1. /*###################################################################################################
  2. **
  3. **
  4. **      mips3.c
  5. **      Core implementation for the portable MIPS III/IV emulator.
  6. **      Written by Aaron Giles
  7. **
  8. **
  9. **      Still not implemented:
  10. **          * MMU (it is logged, however)
  11. **          * DMULT needs to be fixed properly
  12. **
  13. **
  14. **#################################################################################################*/
  15.  
  16. #include <stdio.h>
  17. #include <stddef.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include <math.h>
  21. #include "driver.h"
  22. #include "mamedbg.h"
  23. #include "mips3.h"
  24.  
  25. #define ENABLE_OVERFLOWS 0
  26.  
  27. /*###################################################################################################
  28. **  CONSTANTS
  29. **#################################################################################################*/
  30.  
  31. /* COP0 registers */
  32. #define COP0_Index 0
  33. #define COP0_Random 1
  34. #define COP0_EntryLo 2
  35. #define COP0_EntryLo0 2
  36. #define COP0_EntryLo1 3
  37. #define COP0_Context 4
  38. #define COP0_PageMask 5
  39. #define COP0_Wired 6
  40. #define COP0_BadVAddr 8
  41. #define COP0_Count 9
  42. #define COP0_EntryHi 10
  43. #define COP0_Compare 11
  44. #define COP0_Status 12
  45. #define COP0_Cause 13
  46. #define COP0_EPC 14
  47. #define COP0_PRId 15
  48. #define COP0_XContext 20
  49.  
  50. /* Status register bits */
  51. #define SR_IE 0x00000001
  52. #define SR_EXL 0x00000002
  53. #define SR_ERL 0x00000004
  54. #define SR_KSU_MASK 0x00000018
  55. #define SR_KSU_KERNEL 0x00000000
  56. #define SR_KSU_SUPERVISOR 0x00000008
  57. #define SR_KSU_USER 0x00000010
  58. #define SR_IMSW0 0x00000100
  59. #define SR_IMSW1 0x00000200
  60. #define SR_IMEX0 0x00000400
  61. #define SR_IMEX1 0x00000800
  62. #define SR_IMEX2 0x00001000
  63. #define SR_IMEX3 0x00002000
  64. #define SR_IMEX4 0x00004000
  65. #define SR_IMEX5 0x00008000
  66. #define SR_DE 0x00010000
  67. #define SR_CE 0x00020000
  68. #define SR_CH 0x00040000
  69. #define SR_SR 0x00100000
  70. #define SR_TS 0x00200000
  71. #define SR_BEV 0x00400000
  72. #define SR_RE 0x02000000
  73. #define SR_COP0 0x10000000
  74. #define SR_COP1 0x20000000
  75. #define SR_COP2 0x40000000
  76. #define SR_COP3 0x80000000
  77.  
  78. /* exception types */
  79. #define EXCEPTION_INTERRUPT 0
  80. #define EXCEPTION_TLBMOD 1
  81. #define EXCEPTION_TLBLOAD 2
  82. #define EXCEPTION_TLBSTORE 3
  83. #define EXCEPTION_ADDRLOAD 4
  84. #define EXCEPTION_ADDRSTORE 5
  85. #define EXCEPTION_BUSINST 6
  86. #define EXCEPTION_BUSDATA 7
  87. #define EXCEPTION_SYSCALL 8
  88. #define EXCEPTION_BREAK 9
  89. #define EXCEPTION_INVALIDOP 10
  90. #define EXCEPTION_BADCOP 11
  91. #define EXCEPTION_OVERFLOW 12
  92. #define EXCEPTION_TRAP 13
  93.  
  94. /*###################################################################################################
  95. **  HELPER MACROS
  96. **#################################################################################################*/
  97.  
  98. #define RSREG ((op >> 21) & 31)
  99. #define RTREG ((op >> 16) & 31)
  100. #define RDREG ((op >> 11) & 31)
  101. #define SHIFT ((op >> 6) & 31)
  102.  
  103. #define RSVAL32 ((UINT32)mips3.r[RSREG])
  104. #define RTVAL32 ((UINT32)mips3.r[RTREG])
  105. #define RDVAL32 ((UINT32)mips3.r[RDREG])
  106.  
  107. #define RSVAL64 (mips3.r[RSREG])
  108. #define RTVAL64 (mips3.r[RTREG])
  109. #define RDVAL64 (mips3.r[RDREG])
  110.  
  111. #define FRREG ((op >> 21) & 31)
  112. #define FTREG ((op >> 16) & 31)
  113. #define FSREG ((op >> 11) & 31)
  114. #define FDREG ((op >> 6) & 31)
  115.  
  116. #define FRVALS (((float *)&mips3.cpr[1][FRREG])[BYTE_XOR_LE(0)])
  117. #define FTVALS (((float *)&mips3.cpr[1][FTREG])[BYTE_XOR_LE(0)])
  118. #define FSVALS (((float *)&mips3.cpr[1][FSREG])[BYTE_XOR_LE(0)])
  119. #define FDVALS (((float *)&mips3.cpr[1][FDREG])[BYTE_XOR_LE(0)])
  120.  
  121. #define FRVALD (*(double *)&mips3.cpr[1][FRREG])
  122. #define FTVALD (*(double *)&mips3.cpr[1][FTREG])
  123. #define FSVALD (*(double *)&mips3.cpr[1][FSREG])
  124. #define FDVALD (*(double *)&mips3.cpr[1][FDREG])
  125.  
  126. #define IS_SINGLE(o) (((o) & (1 << 21)) == 0)
  127. #define IS_DOUBLE(o) (((o) & (1 << 21)) != 0)
  128. #define IS_FLOAT(o) (((o) & (1 << 23)) == 0)
  129. #define IS_INTEGRAL(o) (((o) & (1 << 23)) != 0)
  130.  
  131. #define SIMMVAL ((INT16)op)
  132. #define UIMMVAL ((UINT16)op)
  133. #define LIMMVAL (op & 0x03ffffff)
  134.  
  135. #define ADDPC(x) mips3.nextpc = mips3.pc + ((x) << 2)
  136. #define ADDPCL(x, l)                          \
  137.     {                                         \
  138.         mips3.nextpc = mips3.pc + ((x) << 2); \
  139.         mips3.r[l] = mips3.pc + 4;            \
  140.     }
  141. #define ABSPC(x) mips3.nextpc = (mips3.pc & 0xf0000000) | ((x) << 2)
  142. #define ABSPCL(x, l)                                         \
  143.     {                                                        \
  144.         mips3.nextpc = (mips3.pc & 0xf0000000) | ((x) << 2); \
  145.         mips3.r[l] = mips3.pc + 4;                           \
  146.     }
  147. #define SETPC(x) mips3.nextpc = (x)
  148. #define SETPCL(x, l)               \
  149.     {                              \
  150.         mips3.nextpc = (x);        \
  151.         mips3.r[l] = mips3.pc + 4; \
  152.     }
  153.  
  154. #define RBYTE(x) (*mips3.memory.readbyte)(x)
  155. #define RWORD(x) (*mips3.memory.readword)(x)
  156. #define RLONG(x) (*mips3.memory.readlong)(x)
  157. #define RDOUBLE(x) (*mips3.memory.readdouble)(x)
  158.  
  159. #define WBYTE(x, v) (*mips3.memory.writebyte)(x, v)
  160. #define WWORD(x, v) (*mips3.memory.writeword)(x, v)
  161. #define WLONG(x, v) (*mips3.memory.writelong)(x, v)
  162. #define WDOUBLE(x, v) (*mips3.memory.writedouble)(x, v)
  163.  
  164. #define HIVAL (UINT32) mips3.hi
  165. #define LOVAL (UINT32) mips3.lo
  166. #define HIVAL64 mips3.hi
  167. #define LOVAL64 mips3.lo
  168. #define SR mips3.cpr[0][COP0_Status]
  169. #define CAUSE mips3.cpr[0][COP0_Cause]
  170.  
  171. /*###################################################################################################
  172. **  STRUCTURES & TYPEDEFS
  173. **#################################################################################################*/
  174.  
  175. /* memory access function table */
  176. typedef struct
  177. {
  178.     data8_t (*readbyte)(offs_t);
  179.     data16_t (*readword)(offs_t);
  180.     data32_t (*readlong)(offs_t);
  181.     UINT64 (*readdouble)
  182.     (offs_t);
  183.     void (*writebyte)(offs_t, data8_t);
  184.     void (*writeword)(offs_t, data16_t);
  185.     void (*writelong)(offs_t, data32_t);
  186.     void (*writedouble)(offs_t, UINT64);
  187. } memory_handlers;
  188.  
  189. /* MIPS3 Registers */
  190. typedef struct
  191. {
  192.     /* core registers */
  193.     UINT32 pc;
  194.     UINT64 hi;
  195.     UINT64 lo;
  196.     UINT64 r[32];
  197.  
  198.     /* COP registers */
  199.     UINT64 cpr[4][32];
  200.     UINT64 ccr[4][32];
  201.     UINT8 cf[4][8];
  202.  
  203.     /* internal stuff */
  204.     UINT32 ppc;
  205.     UINT32 nextpc;
  206.     int op;
  207.     int interrupt_cycles;
  208.     int (*irq_callback)(int irqline);
  209.     UINT64 count_zero_time;
  210.     void *compare_int_timer;
  211.     UINT8 is_mips4;
  212.  
  213.     /* endian-dependent load/store */
  214.     void (*lwl)(UINT32 op);
  215.     void (*lwr)(UINT32 op);
  216.     void (*swl)(UINT32 op);
  217.     void (*swr)(UINT32 op);
  218.     void (*ldl)(UINT32 op);
  219.     void (*ldr)(UINT32 op);
  220.     void (*sdl)(UINT32 op);
  221.     void (*sdr)(UINT32 op);
  222.  
  223.     /* memory accesses */
  224.     UINT8 bigendian;
  225.     memory_handlers memory;
  226.  
  227.     /* cache memory */
  228.     data32_t *icache;
  229.     data32_t *dcache;
  230.     size_t icache_size;
  231.     size_t dcache_size;
  232. } mips3_regs;
  233.  
  234. /*###################################################################################################
  235. **  PROTOTYPES
  236. **#################################################################################################*/
  237.  
  238. static void lwl_be(UINT32 op);
  239. static void lwr_be(UINT32 op);
  240. static void swl_be(UINT32 op);
  241. static void swr_be(UINT32 op);
  242.  
  243. static void lwl_le(UINT32 op);
  244. static void lwr_le(UINT32 op);
  245. static void swl_le(UINT32 op);
  246. static void swr_le(UINT32 op);
  247.  
  248. static void ldl_be(UINT32 op);
  249. static void ldr_be(UINT32 op);
  250. static void sdl_be(UINT32 op);
  251. static void sdr_be(UINT32 op);
  252.  
  253. static void ldl_le(UINT32 op);
  254. static void ldr_le(UINT32 op);
  255. static void sdl_le(UINT32 op);
  256. static void sdr_le(UINT32 op);
  257.  
  258. static UINT64 readmem32bedw_double(offs_t offset);
  259. static UINT64 readmem32ledw_double(offs_t offset);
  260.  
  261. static void writemem32bedw_double(offs_t offset, UINT64 data);
  262. static void writemem32ledw_double(offs_t offset, UINT64 data);
  263.  
  264. /*###################################################################################################
  265. **  PUBLIC GLOBAL VARIABLES
  266. **#################################################################################################*/
  267.  
  268. int mips3_icount = 50000;
  269.  
  270. /*###################################################################################################
  271. **  PRIVATE GLOBAL VARIABLES
  272. **#################################################################################################*/
  273.  
  274. static mips3_regs mips3;
  275.  
  276. static const memory_handlers be_memory =
  277.     {
  278.         cpu_readmem32bedw, cpu_readmem32bedw_word, cpu_readmem32bedw_dword, readmem32bedw_double,
  279.         cpu_writemem32bedw, cpu_writemem32bedw_word, cpu_writemem32bedw_dword, writemem32bedw_double};
  280.  
  281. static const memory_handlers le_memory =
  282.     {
  283.         cpu_readmem32ledw, cpu_readmem32ledw_word, cpu_readmem32ledw_dword, readmem32ledw_double,
  284.         cpu_writemem32ledw, cpu_writemem32ledw_word, cpu_writemem32ledw_dword, writemem32ledw_double};
  285.  
  286. /*###################################################################################################
  287. **  MEMORY ACCESSORS
  288. **#################################################################################################*/
  289.  
  290. #define ROPCODE(pc) cpu_readop32(pc)
  291.  
  292. /*###################################################################################################
  293. **  EXECEPTION HANDLING
  294. **#################################################################################################*/
  295.  
  296. INLINE void generate_exception(int exception, int backup)
  297. {
  298.     /*
  299.         useful for catching exceptions:
  300.  
  301.         if (exception != 0)
  302.         {
  303.             fprintf(stderr, "Exception: PC=%08X, PPC=%08X\n", mips3.pc, mips3.ppc);
  304.             #ifdef MAME_DEBUG
  305.             {
  306.             extern int debug_key_pressed;
  307.             debug_key_pressed = 1;
  308.             }
  309.             #endif
  310.         }
  311.     */
  312.  
  313.     /* back up if necessary */
  314.     if (backup)
  315.         mips3.pc = mips3.ppc;
  316.  
  317.     /* set the exception PC */
  318.     mips3.cpr[0][COP0_EPC] = mips3.pc;
  319.  
  320.     /* put the cause in the low 8 bits and clear the branch delay flag */
  321.     CAUSE = (CAUSE & ~0x800000ff) | (exception << 2);
  322.  
  323.     /* if we were in a branch delay slot, adjust */
  324.     if (mips3.nextpc != ~0)
  325.     {
  326.         mips3.nextpc = ~0;
  327.         mips3.cpr[0][COP0_EPC] -= 4;
  328.         CAUSE |= 0x80000000;
  329.     }
  330.  
  331.     /* set the exception level */
  332.     SR |= SR_EXL;
  333.  
  334.     /* based on the BEV bit, we either go to ROM or RAM */
  335.     mips3.pc = (SR & SR_BEV) ? 0xbfc00200 : 0x80000000;
  336.  
  337.     /* most exceptions go to offset 0x180, except for TLB stuff */
  338.     if (exception >= EXCEPTION_TLBMOD && exception <= EXCEPTION_TLBSTORE)
  339.         mips3.pc += 0x80;
  340.     else
  341.         mips3.pc += 0x180;
  342.  
  343.     /*
  344.         useful for tracking interrupts
  345.  
  346.         if ((CAUSE & 0x7f) == 0)
  347.             logerror("Took interrupt -- Cause = %08X, PC =  %08X\n", (UINT32)CAUSE, mips3.pc);
  348.     */
  349.  
  350.     /* swap to the new space */
  351.     if (mips3.bigendian)
  352.         change_pc32bedw(mips3.pc);
  353.     else
  354.         change_pc32ledw(mips3.pc);
  355. }
  356.  
  357. INLINE void invalid_instruction(UINT32 op)
  358. {
  359.     generate_exception(EXCEPTION_INVALIDOP, 1);
  360. }
  361.  
  362. /*###################################################################################################
  363. **  IRQ HANDLING
  364. **#################################################################################################*/
  365.  
  366. static void check_irqs(void)
  367. {
  368.     if ((CAUSE & SR & 0xff00) && (SR & SR_IE) && !(SR & SR_EXL) && !(SR & SR_ERL))
  369.         generate_exception(EXCEPTION_INTERRUPT, 0);
  370. }
  371.  
  372. void mips3_set_irq_line(int irqline, int state)
  373. {
  374.     if (state != CLEAR_LINE)
  375.         CAUSE |= 0x400 << irqline;
  376.     else
  377.         CAUSE &= ~(0x400 << irqline);
  378. }
  379.  
  380. void mips3_set_irq_callback(int (*callback)(int irqline))
  381. {
  382.     mips3.irq_callback = callback;
  383. }
  384.  
  385. /*###################################################################################################
  386. **  CONTEXT SWITCHING
  387. **#################################################################################################*/
  388.  
  389. unsigned mips3_get_context(void *dst)
  390. {
  391.     /* copy the context */
  392.     if (dst)
  393.         *(mips3_regs *)dst = mips3;
  394.  
  395.     /* return the context size */
  396.     return sizeof(mips3_regs);
  397. }
  398.  
  399. void mips3_set_context(void *src)
  400. {
  401.     /* copy the context */
  402.     if (src)
  403.         mips3 = *(mips3_regs *)src;
  404.  
  405.     if (mips3.bigendian)
  406.         change_pc32bedw(mips3.pc);
  407.     else
  408.         change_pc32ledw(mips3.pc);
  409. }
  410.  
  411. /*###################################################################################################
  412. **  INITIALIZATION AND SHUTDOWN
  413. **#################################################################################################*/
  414.  
  415. static void compare_int_callback(int cpu)
  416. {
  417.     cpu_set_irq_line(cpu, 5, ASSERT_LINE);
  418. }
  419.  
  420. void mips3_init(void)
  421. {
  422.     mips3.compare_int_timer = timer_alloc(compare_int_callback);
  423. }
  424.  
  425. static void mips3_reset(void *param, int bigendian)
  426. {
  427.     struct mips3_config *config = param;
  428.  
  429.     /* allocate memory */
  430.     mips3.icache = malloc(config->icache);
  431.     mips3.dcache = malloc(config->dcache);
  432.     if (!mips3.icache || !mips3.dcache)
  433.     {
  434.         fprintf(stderr, "error: couldn't allocate cache for mips3!\n");
  435.         exit(1);
  436.     }
  437.  
  438.     /* set up the endianness */
  439.     mips3.bigendian = bigendian;
  440.     if (mips3.bigendian)
  441.     {
  442.         mips3.memory = be_memory;
  443.         mips3.lwl = lwl_be;
  444.         mips3.lwr = lwr_be;
  445.         mips3.swl = swl_be;
  446.         mips3.swr = swr_be;
  447.         mips3.ldl = ldl_be;
  448.         mips3.ldr = ldr_be;
  449.         mips3.sdl = sdl_be;
  450.         mips3.sdr = sdr_be;
  451.     }
  452.     else
  453.     {
  454.         mips3.memory = le_memory;
  455.         mips3.lwl = lwl_le;
  456.         mips3.lwr = lwr_le;
  457.         mips3.swl = swl_le;
  458.         mips3.swr = swr_le;
  459.         mips3.ldl = ldl_le;
  460.         mips3.ldr = ldr_le;
  461.         mips3.sdl = sdl_le;
  462.         mips3.sdr = sdr_le;
  463.     }
  464.  
  465.     /* initialize the rest of the config */
  466.     mips3.icache_size = config->icache;
  467.     mips3.dcache_size = config->dcache;
  468.  
  469.     /* initialize the state */
  470.     mips3.pc = 0xbfc00000;
  471.     mips3.nextpc = ~0;
  472.     mips3.cpr[0][COP0_Status] = SR_BEV | SR_ERL;
  473.     mips3.cpr[0][COP0_Compare] = 0xffffffff;
  474.     mips3.cpr[0][COP0_Count] = 0;
  475.     mips3.count_zero_time = activecpu_gettotalcycles64();
  476.  
  477.     /* adjust for the initial PC */
  478.     if (mips3.bigendian)
  479.         change_pc32bedw(mips3.pc);
  480.     else
  481.         change_pc32ledw(mips3.pc);
  482. }
  483.  
  484. void r4600be_reset(void *param)
  485. {
  486.     mips3_reset(param, 1);
  487.     mips3.cpr[0][COP0_PRId] = 0x2000;
  488.     mips3.is_mips4 = 0;
  489. }
  490.  
  491. void r4600le_reset(void *param)
  492. {
  493.     mips3_reset(param, 0);
  494.     mips3.cpr[0][COP0_PRId] = 0x2000;
  495.     mips3.is_mips4 = 0;
  496. }
  497.  
  498. void r5000be_reset(void *param)
  499. {
  500.     mips3_reset(param, 1);
  501.     mips3.cpr[0][COP0_PRId] = 0x2300;
  502.     mips3.is_mips4 = 1;
  503. }
  504.  
  505. void r5000le_reset(void *param)
  506. {
  507.     mips3_reset(param, 0);
  508.     mips3.cpr[0][COP0_PRId] = 0x2300;
  509.     mips3.is_mips4 = 1;
  510. }
  511.  
  512. void mips3_exit(void)
  513. {
  514.     /* free cache memory */
  515.     if (mips3.icache)
  516.         free(mips3.icache);
  517.     mips3.icache = NULL;
  518.  
  519.     if (mips3.dcache)
  520.         free(mips3.dcache);
  521.     mips3.dcache = NULL;
  522. }
  523.  
  524. /* kludge for DRC support */
  525. void mips3drc_set_options(UINT8 cpunum, UINT32 opts)
  526. {
  527. }
  528.  
  529. /*###################################################################################################
  530. **  COP0 (SYSTEM) EXECUTION HANDLING
  531. **#################################################################################################*/
  532.  
  533. static UINT32 update_cycle_counting(void)
  534. {
  535.     UINT32 count = (activecpu_gettotalcycles64() - mips3.count_zero_time) / 2;
  536.     UINT32 compare = mips3.cpr[0][COP0_Compare];
  537.     UINT32 cyclesleft = compare - count;
  538.     double newtime;
  539.  
  540.     // printf("Update: count=%08X  compare=%08X  delta=%08X  SR=%08X  time=%f\n", count, compare, cyclesleft, (UINT32)SR, TIME_IN_CYCLES(((UINT64)cyclesleft * 2), cpu_getactivecpu()));
  541.  
  542.     /* modify the timer to go off */
  543.     newtime = TIME_IN_CYCLES(((UINT64)cyclesleft * 2), cpu_getactivecpu());
  544.     if (SR & 0x8000)
  545.         timer_adjust(mips3.compare_int_timer, newtime, cpu_getactivecpu(), 0);
  546.     else
  547.         timer_adjust(mips3.compare_int_timer, TIME_NEVER, cpu_getactivecpu(), 0);
  548.     return count;
  549. }
  550.  
  551. INLINE UINT64 get_cop0_reg(int idx)
  552. {
  553.     if (idx == COP0_Count)
  554.     {
  555.         /* it doesn't really take 100 cycles to read this register, but it helps speed */
  556.         /* up loops that hammer on it */
  557.         mips3_icount -= 100;
  558.         return (UINT32)((activecpu_gettotalcycles64() - mips3.count_zero_time) / 2);
  559.     }
  560.     else if (idx == COP0_Cause)
  561.     {
  562.         /* it doesn't really take 100 cycles to read this register, but it helps speed */
  563.         /* up loops that hammer on it */
  564.         mips3_icount -= 100;
  565.     }
  566.     return mips3.cpr[0][idx];
  567. }
  568.  
  569. INLINE void set_cop0_reg(int idx, UINT64 val)
  570. {
  571.     switch (idx)
  572.     {
  573.     case COP0_Cause:
  574.         CAUSE = (CAUSE & 0xfc00) | (val & ~0xfc00);
  575.         /* update interrupts -- software ints can occur this way */
  576.         check_irqs();
  577.         break;
  578.  
  579.     case COP0_Status:
  580.     {
  581.         /* update interrupts and cycle counting */
  582.         UINT32 diff = mips3.cpr[0][idx] ^ val;
  583.         mips3.cpr[0][idx] = val;
  584.         if (diff & 0x8000)
  585.             update_cycle_counting();
  586.         check_irqs();
  587.         break;
  588.     }
  589.  
  590.     case COP0_Count:
  591.         mips3.count_zero_time = activecpu_gettotalcycles64() - ((UINT64)val * 2);
  592.         update_cycle_counting();
  593.         break;
  594.  
  595.     case COP0_Compare:
  596.         CAUSE &= ~0x8000;
  597.         mips3.cpr[0][idx] = val;
  598.         update_cycle_counting();
  599.         break;
  600.  
  601.     case COP0_PRId:
  602.         break;
  603.  
  604.     default:
  605.         mips3.cpr[0][idx] = val;
  606.         break;
  607.     }
  608. }
  609.  
  610. INLINE UINT64 get_cop0_creg(int idx)
  611. {
  612.     return mips3.ccr[0][idx];
  613. }
  614.  
  615. INLINE void set_cop0_creg(int idx, UINT64 val)
  616. {
  617.     mips3.ccr[0][idx] = val;
  618. }
  619.  
  620. INLINE void logonetlbentry(int which)
  621. {
  622.     UINT64 hi = mips3.cpr[0][COP0_EntryHi];
  623.     UINT64 lo = mips3.cpr[0][COP0_EntryLo0 + which];
  624.     UINT32 vpn = (((hi >> 13) & 0x07ffffff) << 1) + which;
  625.     UINT32 asid = hi & 0xff;
  626.     UINT32 r = (hi >> 62) & 3;
  627.     UINT32 pfn = (lo >> 6) & 0x00ffffff;
  628.     UINT32 c = (lo >> 3) & 7;
  629.     UINT32 pagesize = ((mips3.cpr[0][COP0_PageMask] >> 1) | 0xfff) + 1;
  630.     UINT64 vaddr = (UINT64)vpn * (UINT64)pagesize;
  631.     UINT64 paddr = (UINT64)pfn * (UINT64)pagesize;
  632.  
  633.     logerror("pagesize = %08X  vaddr = %08X%08X  paddr = %08X%08X  asid = %02X  r = %X  c = %X  dvg=%c%c%c\n",
  634.              pagesize, (UINT32)(vaddr >> 32), (UINT32)vaddr, (UINT32)(paddr >> 32), (UINT32)paddr,
  635.              asid, r, c, (lo & 4) ? 'd' : '.', (lo & 2) ? 'v' : '.', (lo & 1) ? 'g' : '.');
  636. }
  637.  
  638. static void logtlbentry(void)
  639. {
  640.     logonetlbentry(0);
  641.     logonetlbentry(1);
  642. }
  643.  
  644. INLINE void handle_cop0(UINT32 op)
  645. {
  646.     if ((SR & SR_KSU_MASK) != SR_KSU_KERNEL && !(SR & SR_COP0))
  647.         generate_exception(EXCEPTION_BADCOP, 1);
  648.  
  649.     switch (RSREG)
  650.     {
  651.     case 0x00: /* MFCz */
  652.         if (RTREG)
  653.             RTVAL64 = (INT32)get_cop0_reg(RDREG);
  654.         break;
  655.     case 0x01: /* DMFCz */
  656.         if (RTREG)
  657.             RTVAL64 = get_cop0_reg(RDREG);
  658.         break;
  659.     case 0x02: /* CFCz */
  660.         if (RTREG)
  661.             RTVAL64 = (INT32)get_cop0_creg(RDREG);
  662.         break;
  663.     case 0x04: /* MTCz */
  664.         set_cop0_reg(RDREG, RTVAL32);
  665.         break;
  666.     case 0x05: /* DMTCz */
  667.         set_cop0_reg(RDREG, RTVAL64);
  668.         break;
  669.     case 0x06: /* CTCz */
  670.         set_cop0_creg(RDREG, RTVAL32);
  671.         break;
  672.     case 0x08: /* BC */
  673.         switch (RTREG)
  674.         {
  675.         case 0x00: /* BCzF */
  676.             if (!mips3.cf[0][0])
  677.                 ADDPC(SIMMVAL);
  678.             break;
  679.         case 0x01: /* BCzF */
  680.             if (mips3.cf[0][0])
  681.                 ADDPC(SIMMVAL);
  682.             break;
  683.         case 0x02: /* BCzFL */
  684.             invalid_instruction(op);
  685.             break;
  686.         case 0x03: /* BCzTL */
  687.             invalid_instruction(op);
  688.             break;
  689.         default:
  690.             invalid_instruction(op);
  691.             break;
  692.         }
  693.         break;
  694.     case 0x10:
  695.     case 0x11:
  696.     case 0x12:
  697.     case 0x13:
  698.     case 0x14:
  699.     case 0x15:
  700.     case 0x16:
  701.     case 0x17:
  702.     case 0x18:
  703.     case 0x19:
  704.     case 0x1a:
  705.     case 0x1b:
  706.     case 0x1c:
  707.     case 0x1d:
  708.     case 0x1e:
  709.     case 0x1f: /* COP */
  710.         switch (op & 0x01ffffff)
  711.         {
  712.         case 0x01: /* TLBR */
  713.             break;
  714.         case 0x02: /* TLBWI */
  715.             logtlbentry();
  716.             break;
  717.         case 0x06: /* TLBWR */
  718.             logtlbentry();
  719.             break;
  720.         case 0x08: /* TLBP */
  721.             break;
  722.         case 0x10: /* RFE */
  723.             invalid_instruction(op);
  724.             break;
  725.         case 0x18: /* ERET */
  726.             logerror("ERET\n");
  727.             mips3.pc = mips3.cpr[0][COP0_EPC];
  728.             SR &= ~SR_EXL;
  729.             check_irqs();
  730.             break;
  731.         default:
  732.             invalid_instruction(op);
  733.             break;
  734.         }
  735.         break;
  736.     default:
  737.         invalid_instruction(op);
  738.         break;
  739.     }
  740. }
  741.  
  742. /*###################################################################################################
  743. **  COP1 (FPU) EXECUTION HANDLING
  744. **#################################################################################################*/
  745.  
  746. INLINE UINT64 get_cop1_reg(int idx)
  747. {
  748.     return mips3.cpr[1][idx];
  749. }
  750.  
  751. INLINE void set_cop1_reg(int idx, UINT64 val)
  752. {
  753.     mips3.cpr[1][idx] = val;
  754. }
  755.  
  756. INLINE UINT64 get_cop1_creg(int idx)
  757. {
  758.     return mips3.ccr[1][idx];
  759. }
  760.  
  761. INLINE void set_cop1_creg(int idx, UINT64 val)
  762. {
  763.     mips3.ccr[1][idx] = val;
  764. }
  765.  
  766. INLINE void handle_cop1(UINT32 op)
  767. {
  768.     double dtemp;
  769.  
  770.     /* note: additional condition codes available on R5000 only */
  771.  
  772.     if (!(SR & SR_COP1))
  773.         generate_exception(EXCEPTION_BADCOP, 1);
  774.  
  775.     switch (RSREG)
  776.     {
  777.     case 0x00: /* MFCz */
  778.         if (RTREG)
  779.             RTVAL64 = (INT32)get_cop1_reg(RDREG);
  780.         break;
  781.     case 0x01: /* DMFCz */
  782.         if (RTREG)
  783.             RTVAL64 = get_cop1_reg(RDREG);
  784.         break;
  785.     case 0x02: /* CFCz */
  786.         if (RTREG)
  787.             RTVAL64 = (INT32)get_cop1_creg(RDREG);
  788.         break;
  789.     case 0x04: /* MTCz */
  790.         set_cop1_reg(RDREG, RTVAL32);
  791.         break;
  792.     case 0x05: /* DMTCz */
  793.         set_cop1_reg(RDREG, RTVAL64);
  794.         break;
  795.     case 0x06: /* CTCz */
  796.         set_cop1_creg(RDREG, RTVAL32);
  797.         break;
  798.     case 0x08: /* BC */
  799.         switch ((op >> 16) & 3)
  800.         {
  801.         case 0x00: /* BCzF */
  802.             if (!mips3.cf[1][(op >> 18) & 7])
  803.                 ADDPC(SIMMVAL);
  804.             break;
  805.         case 0x01: /* BCzT */
  806.             if (mips3.cf[1][(op >> 18) & 7])
  807.                 ADDPC(SIMMVAL);
  808.             break;
  809.         case 0x02: /* BCzFL */
  810.             if (!mips3.cf[1][(op >> 18) & 7])
  811.                 ADDPC(SIMMVAL);
  812.             else
  813.                 mips3.pc += 4;
  814.             break;
  815.         case 0x03: /* BCzTL */
  816.             if (mips3.cf[1][(op >> 18) & 7])
  817.                 ADDPC(SIMMVAL);
  818.             else
  819.                 mips3.pc += 4;
  820.             break;
  821.         }
  822.         break;
  823.     default:
  824.         switch (op & 0x3f)
  825.         {
  826.         case 0x00:
  827.             if (IS_SINGLE(op)) /* ADD.S */
  828.                 FDVALS = FSVALS + FTVALS;
  829.             else /* ADD.D */
  830.                 FDVALD = FSVALD + FTVALD;
  831.             break;
  832.  
  833.         case 0x01:
  834.             if (IS_SINGLE(op)) /* SUB.S */
  835.                 FDVALS = FSVALS - FTVALS;
  836.             else /* SUB.D */
  837.                 FDVALD = FSVALD - FTVALD;
  838.             break;
  839.  
  840.         case 0x02:
  841.             if (IS_SINGLE(op)) /* MUL.S */
  842.                 FDVALS = FSVALS * FTVALS;
  843.             else /* MUL.D */
  844.                 FDVALD = FSVALD * FTVALD;
  845.             break;
  846.  
  847.         case 0x03:
  848.             if (IS_SINGLE(op)) /* DIV.S */
  849.                 FDVALS = FSVALS / FTVALS;
  850.             else /* DIV.D */
  851.                 FDVALD = FSVALD / FTVALD;
  852.             break;
  853.  
  854.         case 0x04:
  855.             if (IS_SINGLE(op)) /* SQRT.S */
  856.                 FDVALS = sqrt(FSVALS);
  857.             else /* SQRT.D */
  858.                 FDVALD = sqrt(FSVALD);
  859.             break;
  860.  
  861.         case 0x05:
  862.             if (IS_SINGLE(op)) /* ABS.S */
  863.                 FDVALS = fabs(FSVALS);
  864.             else /* ABS.D */
  865.                 FDVALD = fabs(FSVALD);
  866.             break;
  867.  
  868.         case 0x06:
  869.             if (IS_SINGLE(op)) /* MOV.S */
  870.                 FDVALS = FSVALS;
  871.             else /* MOV.D */
  872.                 FDVALD = FSVALD;
  873.             break;
  874.  
  875.         case 0x07:
  876.             if (IS_SINGLE(op)) /* NEG.S */
  877.                 FDVALS = -FSVALS;
  878.             else /* NEG.D */
  879.                 FDVALD = -FSVALD;
  880.             break;
  881.  
  882.         case 0x08:
  883.             if (IS_SINGLE(op)) /* ROUND.L.S */
  884.             {
  885.                 double temp = FSVALS;
  886.                 if (temp < 0)
  887.                     temp = ceil(temp - 0.5);
  888.                 else
  889.                     temp = floor(temp + 0.5);
  890.                 mips3.cpr[1][FDREG] = (INT64)temp;
  891.             }
  892.             else /* ROUND.L.D */
  893.             {
  894.                 double temp = FSVALD;
  895.                 if (temp < 0)
  896.                     temp = ceil(temp - 0.5);
  897.                 else
  898.                     temp = floor(temp + 0.5);
  899.                 mips3.cpr[1][FDREG] = (INT64)temp;
  900.             }
  901.             break;
  902.  
  903.         case 0x09:
  904.             if (IS_SINGLE(op)) /* TRUNC.L.S */
  905.             {
  906.                 double temp = FSVALS;
  907.                 if (temp < 0)
  908.                     temp = ceil(temp);
  909.                 else
  910.                     temp = floor(temp);
  911.                 mips3.cpr[1][FDREG] = (INT64)temp;
  912.             }
  913.             else /* TRUNC.L.D */
  914.             {
  915.                 double temp = FSVALD;
  916.                 if (temp < 0)
  917.                     temp = ceil(temp);
  918.                 else
  919.                     temp = floor(temp);
  920.                 mips3.cpr[1][FDREG] = (INT64)temp;
  921.             }
  922.             break;
  923.  
  924.         case 0x0a:
  925.             if (IS_SINGLE(op)) /* CEIL.L.S */
  926.                 dtemp = ceil(FSVALS);
  927.             else /* CEIL.L.D */
  928.                 dtemp = ceil(FSVALD);
  929.             mips3.cpr[1][FDREG] = (INT64)dtemp;
  930.             break;
  931.  
  932.         case 0x0b:
  933.             if (IS_SINGLE(op)) /* FLOOR.L.S */
  934.                 dtemp = floor(FSVALS);
  935.             else /* FLOOR.L.D */
  936.                 dtemp = floor(FSVALD);
  937.             mips3.cpr[1][FDREG] = (INT64)dtemp;
  938.             break;
  939.  
  940.         case 0x0c:
  941.             if (IS_SINGLE(op)) /* ROUND.W.S */
  942.             {
  943.                 dtemp = FSVALS;
  944.                 if (dtemp < 0)
  945.                     dtemp = ceil(dtemp - 0.5);
  946.                 else
  947.                     dtemp = floor(dtemp + 0.5);
  948.                 mips3.cpr[1][FDREG] = (INT32)dtemp;
  949.             }
  950.             else /* ROUND.W.D */
  951.             {
  952.                 dtemp = FSVALD;
  953.                 if (dtemp < 0)
  954.                     dtemp = ceil(dtemp - 0.5);
  955.                 else
  956.                     dtemp = floor(dtemp + 0.5);
  957.                 mips3.cpr[1][FDREG] = (INT32)dtemp;
  958.             }
  959.             break;
  960.  
  961.         case 0x0d:
  962.             if (IS_SINGLE(op)) /* TRUNC.W.S */
  963.             {
  964.                 dtemp = FSVALS;
  965.                 if (dtemp < 0)
  966.                     dtemp = ceil(dtemp);
  967.                 else
  968.                     dtemp = floor(dtemp);
  969.                 mips3.cpr[1][FDREG] = (INT32)dtemp;
  970.             }
  971.             else /* TRUNC.W.D */
  972.             {
  973.                 dtemp = FSVALD;
  974.                 if (dtemp < 0)
  975.                     dtemp = ceil(dtemp);
  976.                 else
  977.                     dtemp = floor(dtemp);
  978.                 mips3.cpr[1][FDREG] = (INT32)dtemp;
  979.             }
  980.             break;
  981.  
  982.         case 0x0e:
  983.             if (IS_SINGLE(op)) /* CEIL.W.S */
  984.                 dtemp = ceil(FSVALS);
  985.             else /* CEIL.W.D */
  986.                 dtemp = ceil(FSVALD);
  987.             mips3.cpr[1][FDREG] = (INT32)dtemp;
  988.             break;
  989.  
  990.         case 0x0f:
  991.             if (IS_SINGLE(op)) /* FLOOR.W.S */
  992.                 dtemp = floor(FSVALS);
  993.             else /* FLOOR.W.D */
  994.                 dtemp = floor(FSVALD);
  995.             mips3.cpr[1][FDREG] = (INT32)dtemp;
  996.             break;
  997.  
  998.         case 0x11: /* R5000 */
  999.             if (mips3.cf[1][(op >> 18) & 7] == ((op >> 16) & 1))
  1000.             {
  1001.                 if (IS_SINGLE(op)) /* MOVT/F.S */
  1002.                     FDVALS = FSVALS;
  1003.                 else /* MOVT/F.D */
  1004.                     FDVALD = FSVALD;
  1005.             }
  1006.             break;
  1007.  
  1008.         case 0x12: /* R5000 */
  1009.             if (RTVAL64 == 0)
  1010.             {
  1011.                 if (IS_SINGLE(op)) /* MOVZ.S */
  1012.                     FDVALS = FSVALS;
  1013.                 else /* MOVZ.D */
  1014.                     FDVALD = FSVALD;
  1015.             }
  1016.             break;
  1017.  
  1018.         case 0x13: /* R5000 */
  1019.             if (RTVAL64 != 0)
  1020.             {
  1021.                 if (IS_SINGLE(op)) /* MOVN.S */
  1022.                     FDVALS = FSVALS;
  1023.                 else /* MOVN.D */
  1024.                     FDVALD = FSVALD;
  1025.             }
  1026.             break;
  1027.  
  1028.         case 0x15:             /* R5000 */
  1029.             if (IS_SINGLE(op)) /* RECIP.S */
  1030.                 FDVALS = 1.0 / FSVALS;
  1031.             else /* RECIP.D */
  1032.                 FDVALD = 1.0 / FSVALD;
  1033.             break;
  1034.  
  1035.         case 0x16:             /* R5000 */
  1036.             if (IS_SINGLE(op)) /* RSQRT.S */
  1037.                 FDVALS = 1.0 / sqrt(FSVALS);
  1038.             else /* RSQRT.D */
  1039.                 FDVALD = 1.0 / sqrt(FSVALD);
  1040.             break;
  1041.  
  1042.         case 0x20:
  1043.             if (IS_INTEGRAL(op))
  1044.             {
  1045.                 if (IS_SINGLE(op)) /* CVT.S.W */
  1046.                     FDVALS = (INT32)mips3.cpr[1][FSREG];
  1047.                 else /* CVT.S.L */
  1048.                     FDVALS = (INT64)mips3.cpr[1][FSREG];
  1049.             }
  1050.             else /* CVT.S.D */
  1051.                 FDVALS = FSVALD;
  1052.             break;
  1053.  
  1054.         case 0x21:
  1055.             if (IS_INTEGRAL(op))
  1056.             {
  1057.                 if (IS_SINGLE(op)) /* CVT.D.W */
  1058.                     FDVALD = (INT32)mips3.cpr[1][FSREG];
  1059.                 else /* CVT.D.L */
  1060.                     FDVALD = (INT64)mips3.cpr[1][FSREG];
  1061.             }
  1062.             else /* CVT.D.S */
  1063.                 FDVALD = FSVALS;
  1064.             break;
  1065.  
  1066.         case 0x24:
  1067.             if (IS_SINGLE(op)) /* CVT.W.S */
  1068.                 mips3.cpr[1][FDREG] = (INT32)FSVALS;
  1069.             else
  1070.                 mips3.cpr[1][FDREG] = (INT32)FSVALD;
  1071.             break;
  1072.  
  1073.         case 0x25:
  1074.             if (IS_SINGLE(op)) /* CVT.L.S */
  1075.                 mips3.cpr[1][FDREG] = (INT64)FSVALS;
  1076.             else /* CVT.L.D */
  1077.                 mips3.cpr[1][FDREG] = (INT64)FSVALD;
  1078.             break;
  1079.  
  1080.         case 0x30:
  1081.         case 0x38:
  1082.             if (IS_SINGLE(op)) /* C.F.S */
  1083.                 mips3.cf[1][(op >> 8) & 7] = 0;
  1084.             else /* C.F.D */
  1085.                 mips3.cf[1][(op >> 8) & 7] = 0;
  1086.             break;
  1087.  
  1088.         case 0x31:
  1089.         case 0x39:
  1090.             if (IS_SINGLE(op)) /* C.UN.S */
  1091.                 mips3.cf[1][(op >> 8) & 7] = 0;
  1092.             else /* C.UN.D */
  1093.                 mips3.cf[1][(op >> 8) & 7] = 0;
  1094.             break;
  1095.  
  1096.         case 0x32:
  1097.         case 0x3a:
  1098.             if (IS_SINGLE(op)) /* C.EQ.S */
  1099.                 mips3.cf[1][(op >> 8) & 7] = (FSVALS == FTVALS);
  1100.             else /* C.EQ.D */
  1101.                 mips3.cf[1][(op >> 8) & 7] = (FSVALD == FTVALD);
  1102.             break;
  1103.  
  1104.         case 0x33:
  1105.         case 0x3b:
  1106.             if (IS_SINGLE(op)) /* C.UEQ.S */
  1107.                 mips3.cf[1][(op >> 8) & 7] = (FSVALS == FTVALS);
  1108.             else /* C.UEQ.D */
  1109.                 mips3.cf[1][(op >> 8) & 7] = (FSVALD == FTVALD);
  1110.             break;
  1111.  
  1112.         case 0x34:
  1113.         case 0x3c:
  1114.             if (IS_SINGLE(op)) /* C.OLT.S */
  1115.                 mips3.cf[1][(op >> 8) & 7] = (FSVALS < FTVALS);
  1116.             else /* C.OLT.D */
  1117.                 mips3.cf[1][(op >> 8) & 7] = (FSVALD < FTVALD);
  1118.             break;
  1119.  
  1120.         case 0x35:
  1121.         case 0x3d:
  1122.             if (IS_SINGLE(op)) /* C.ULT.S */
  1123.                 mips3.cf[1][(op >> 8) & 7] = (FSVALS < FTVALS);
  1124.             else /* C.ULT.D */
  1125.                 mips3.cf[1][(op >> 8) & 7] = (FSVALD < FTVALD);
  1126.             break;
  1127.  
  1128.         case 0x36:
  1129.         case 0x3e:
  1130.             if (IS_SINGLE(op)) /* C.OLE.S */
  1131.                 mips3.cf[1][(op >> 8) & 7] = (FSVALS <= FTVALS);
  1132.             else /* C.OLE.D */
  1133.                 mips3.cf[1][(op >> 8) & 7] = (FSVALD <= FTVALD);
  1134.             break;
  1135.  
  1136.         case 0x37:
  1137.         case 0x3f:
  1138.             if (IS_SINGLE(op)) /* C.ULE.S */
  1139.                 mips3.cf[1][(op >> 8) & 7] = (FSVALS <= FTVALS);
  1140.             else /* C.ULE.D */
  1141.                 mips3.cf[1][(op >> 8) & 7] = (FSVALD <= FTVALD);
  1142.             break;
  1143.  
  1144.         default:
  1145.             fprintf(stderr, "cop1 %X\n", op);
  1146.             break;
  1147.         }
  1148.         break;
  1149.     }
  1150. }
  1151.  
  1152. /*###################################################################################################
  1153. **  COP1X (FPU EXTRA) EXECUTION HANDLING
  1154. **#################################################################################################*/
  1155.  
  1156. INLINE void handle_cop1x(UINT32 op)
  1157. {
  1158.     if (!(SR & SR_COP1))
  1159.         generate_exception(EXCEPTION_BADCOP, 1);
  1160.  
  1161.     switch (op & 0x3f)
  1162.     {
  1163.     case 0x00: /* LWXC1 */
  1164.         FDVALS = RLONG(RSVAL32 + RTVAL32);
  1165.         break;
  1166.  
  1167.     case 0x01: /* LDXC1 */
  1168.         FDVALD = RDOUBLE(RSVAL32 + RTVAL32);
  1169.         break;
  1170.  
  1171.     case 0x08: /* SWXC1 */
  1172.         WDOUBLE(RSVAL32 + RTVAL32, FSVALS);
  1173.         break;
  1174.  
  1175.     case 0x09: /* SDXC1 */
  1176.         WDOUBLE(RSVAL32 + RTVAL32, FSVALD);
  1177.         break;
  1178.  
  1179.     case 0x0f: /* PREFX */
  1180.         break;
  1181.  
  1182.     case 0x20: /* MADD.S */
  1183.         FDVALS = FSVALS * FTVALS + FRVALS;
  1184.         break;
  1185.  
  1186.     case 0x21: /* MADD.D */
  1187.         FDVALD = FSVALD * FTVALD + FRVALD;
  1188.         break;
  1189.  
  1190.     case 0x28: /* MSUB.S */
  1191.         FDVALS = FSVALS * FTVALS - FRVALS;
  1192.         break;
  1193.  
  1194.     case 0x29: /* MSUB.D */
  1195.         FDVALD = FSVALD * FTVALD - FRVALD;
  1196.         break;
  1197.  
  1198.     case 0x30: /* NMADD.S */
  1199.         FDVALS = -(FSVALS * FTVALS + FRVALS);
  1200.         break;
  1201.  
  1202.     case 0x31: /* NMADD.D */
  1203.         FDVALD = -(FSVALD * FTVALD + FRVALD);
  1204.         break;
  1205.  
  1206.     case 0x38: /* NMSUB.S */
  1207.         FDVALS = -(FSVALS * FTVALS - FRVALS);
  1208.         break;
  1209.  
  1210.     case 0x39: /* NMSUB.D */
  1211.         FDVALD = -(FSVALD * FTVALD - FRVALD);
  1212.         break;
  1213.  
  1214.     case 0x24: /* MADD.W */
  1215.     case 0x25: /* MADD.L */
  1216.     case 0x2c: /* MSUB.W */
  1217.     case 0x2d: /* MSUB.L */
  1218.     case 0x34: /* NMADD.W */
  1219.     case 0x35: /* NMADD.L */
  1220.     case 0x3c: /* NMSUB.W */
  1221.     case 0x3d: /* NMSUB.L */
  1222.     default:
  1223.         fprintf(stderr, "cop1x %X\n", op);
  1224.         break;
  1225.     }
  1226. }
  1227.  
  1228. /*###################################################################################################
  1229. **  COP2 (CUSTOM) EXECUTION HANDLING
  1230. **#################################################################################################*/
  1231.  
  1232. INLINE UINT64 get_cop2_reg(int idx)
  1233. {
  1234.     return mips3.cpr[2][idx];
  1235. }
  1236.  
  1237. INLINE void set_cop2_reg(int idx, UINT64 val)
  1238. {
  1239.     mips3.cpr[2][idx] = val;
  1240. }
  1241.  
  1242. INLINE UINT64 get_cop2_creg(int idx)
  1243. {
  1244.     return mips3.ccr[2][idx];
  1245. }
  1246.  
  1247. INLINE void set_cop2_creg(int idx, UINT64 val)
  1248. {
  1249.     mips3.ccr[2][idx] = val;
  1250. }
  1251.  
  1252. INLINE void handle_cop2(UINT32 op)
  1253. {
  1254.     if (!(SR & SR_COP2))
  1255.         generate_exception(EXCEPTION_BADCOP, 1);
  1256.  
  1257.     switch (RSREG)
  1258.     {
  1259.     case 0x00: /* MFCz */
  1260.         if (RTREG)
  1261.             RTVAL64 = (INT32)get_cop2_reg(RDREG);
  1262.         break;
  1263.     case 0x01: /* DMFCz */
  1264.         if (RTREG)
  1265.             RTVAL64 = get_cop2_reg(RDREG);
  1266.         break;
  1267.     case 0x02: /* CFCz */
  1268.         if (RTREG)
  1269.             RTVAL64 = (INT32)get_cop2_creg(RDREG);
  1270.         break;
  1271.     case 0x04: /* MTCz */
  1272.         set_cop2_reg(RDREG, RTVAL32);
  1273.         break;
  1274.     case 0x05: /* DMTCz */
  1275.         set_cop2_reg(RDREG, RTVAL64);
  1276.         break;
  1277.     case 0x06: /* CTCz */
  1278.         set_cop2_creg(RDREG, RTVAL32);
  1279.         break;
  1280.     case 0x08: /* BC */
  1281.         switch (RTREG)
  1282.         {
  1283.         case 0x00: /* BCzF */
  1284.             if (!mips3.cf[2])
  1285.                 ADDPC(SIMMVAL);
  1286.             break;
  1287.         case 0x01: /* BCzF */
  1288.             if (mips3.cf[2])
  1289.                 ADDPC(SIMMVAL);
  1290.             break;
  1291.         case 0x02: /* BCzFL */
  1292.             invalid_instruction(op);
  1293.             break;
  1294.         case 0x03: /* BCzTL */
  1295.             invalid_instruction(op);
  1296.             break;
  1297.         default:
  1298.             invalid_instruction(op);
  1299.             break;
  1300.         }
  1301.         break;
  1302.     case 0x10:
  1303.     case 0x11:
  1304.     case 0x12:
  1305.     case 0x13:
  1306.     case 0x14:
  1307.     case 0x15:
  1308.     case 0x16:
  1309.     case 0x17:
  1310.     case 0x18:
  1311.     case 0x19:
  1312.     case 0x1a:
  1313.     case 0x1b:
  1314.     case 0x1c:
  1315.     case 0x1d:
  1316.     case 0x1e:
  1317.     case 0x1f: /* COP */
  1318.         invalid_instruction(op);
  1319.         break;
  1320.     default:
  1321.         invalid_instruction(op);
  1322.         break;
  1323.     }
  1324. }
  1325.  
  1326. /*###################################################################################################
  1327. **  CORE EXECUTION LOOP
  1328. **#################################################################################################*/
  1329.  
  1330. int mips3_execute(int cycles)
  1331. {
  1332.     // printf("mips3_execute (PC=%08X)\n", mips3.pc);
  1333.  
  1334.     /* count cycles and interrupt cycles */
  1335.     mips3_icount = cycles;
  1336.     mips3_icount -= mips3.interrupt_cycles;
  1337.     mips3.interrupt_cycles = 0;
  1338.  
  1339.     if (mips3.bigendian)
  1340.         change_pc32bedw(mips3.pc);
  1341.     else
  1342.         change_pc32bedw(mips3.pc);
  1343.  
  1344.     /* check for IRQs */
  1345.     check_irqs();
  1346.  
  1347.     /* core execution loop */
  1348.     do
  1349.     {
  1350.         UINT32 op;
  1351.         UINT64 temp64;
  1352.         int temp;
  1353.  
  1354.         /* debugging */
  1355.         mips3.ppc = mips3.pc;
  1356.         CALL_MAME_DEBUG;
  1357.  
  1358.         /* instruction fetch */
  1359.         op = ROPCODE(mips3.pc);
  1360.  
  1361.         /* adjust for next PC */
  1362.         if (mips3.nextpc != ~0)
  1363.         {
  1364.             mips3.pc = mips3.nextpc;
  1365.             mips3.nextpc = ~0;
  1366.             if (mips3.bigendian)
  1367.                 change_pc32bedw(mips3.pc);
  1368.             else
  1369.                 change_pc32bedw(mips3.pc);
  1370.         }
  1371.         else
  1372.             mips3.pc += 4;
  1373.  
  1374.         /* parse the instruction */
  1375.         switch (op >> 26)
  1376.         {
  1377.         case 0x00: /* SPECIAL */
  1378.             switch (op & 63)
  1379.             {
  1380.             case 0x00: /* SLL */
  1381.                 if (RDREG)
  1382.                     RDVAL64 = (INT32)(RTVAL32 << SHIFT);
  1383.                 break;
  1384.             case 0x01: /* MOVF - R5000*/
  1385.                 if (RDREG && mips3.cf[1][(op >> 18) & 7] == ((op >> 16) & 1))
  1386.                     RDVAL64 = RSVAL64;
  1387.                 break;
  1388.             case 0x02: /* SRL */
  1389.                 if (RDREG)
  1390.                     RDVAL64 = (INT32)(RTVAL32 >> SHIFT);
  1391.                 break;
  1392.             case 0x03: /* SRA */
  1393.                 if (RDREG)
  1394.                     RDVAL64 = (INT32)RTVAL32 >> SHIFT;
  1395.                 break;
  1396.             case 0x04: /* SLLV */
  1397.                 if (RDREG)
  1398.                     RDVAL64 = (INT32)(RTVAL32 << (RSVAL32 & 31));
  1399.                 break;
  1400.             case 0x06: /* SRLV */
  1401.                 if (RDREG)
  1402.                     RDVAL64 = (INT32)(RTVAL32 >> (RSVAL32 & 31));
  1403.                 break;
  1404.             case 0x07: /* SRAV */
  1405.                 if (RDREG)
  1406.                     RDVAL64 = (INT32)RTVAL32 >> (RSVAL32 & 31);
  1407.                 break;
  1408.             case 0x08: /* JR */
  1409.                 SETPC(RSVAL32);
  1410.                 break;
  1411.             case 0x09: /* JALR */
  1412.                 SETPCL(RSVAL32, RDREG);
  1413.                 break;
  1414.             case 0x0a: /* MOVZ - R5000 */
  1415.                 if (RTVAL64 == 0)
  1416.                 {
  1417.                     if (RDREG)
  1418.                         RDVAL64 = RSVAL64;
  1419.                 }
  1420.                 break;
  1421.             case 0x0b: /* MOVN - R5000 */
  1422.                 if (RTVAL64 != 0)
  1423.                 {
  1424.                     if (RDREG)
  1425.                         RDVAL64 = RSVAL64;
  1426.                 }
  1427.                 break;
  1428.             case 0x0c: /* SYSCALL */
  1429.                 generate_exception(EXCEPTION_SYSCALL, 1);
  1430.                 break;
  1431.             case 0x0d: /* BREAK */
  1432.                 generate_exception(EXCEPTION_BREAK, 1);
  1433.                 break;
  1434.             case 0x0f: /* SYNC */ /* effective no-op */
  1435.                 break;
  1436.             case 0x10: /* MFHI */
  1437.                 if (RDREG)
  1438.                     RDVAL64 = HIVAL64;
  1439.                 break;
  1440.             case 0x11: /* MTHI */
  1441.                 HIVAL64 = RSVAL64;
  1442.                 break;
  1443.             case 0x12: /* MFLO */
  1444.                 if (RDREG)
  1445.                     RDVAL64 = LOVAL64;
  1446.                 break;
  1447.             case 0x13: /* MTLO */
  1448.                 LOVAL64 = RSVAL64;
  1449.                 break;
  1450.             case 0x14: /* DSLLV */
  1451.                 if (RDREG)
  1452.                     RDVAL64 = RTVAL64 << (RSVAL32 & 63);
  1453.                 break;
  1454.             case 0x16: /* DSRLV */
  1455.                 if (RDREG)
  1456.                     RDVAL64 = RTVAL64 >> (RSVAL32 & 63);
  1457.                 break;
  1458.             case 0x17: /* DSRAV */
  1459.                 if (RDREG)
  1460.                     RDVAL64 = (INT64)RTVAL64 >> (RSVAL32 & 63);
  1461.                 break;
  1462.             case 0x18: /* MULT */
  1463.                 temp64 = (INT64)(INT32)RSVAL32 * (INT64)(INT32)RTVAL32;
  1464.                 LOVAL64 = (INT32)temp64;
  1465.                 HIVAL64 = (INT32)(temp64 >> 32);
  1466.                 break;
  1467.             case 0x19: /* MULTU */
  1468.                 temp64 = (UINT64)RSVAL32 * (UINT64)RTVAL32;
  1469.                 LOVAL64 = (INT32)temp64;
  1470.                 HIVAL64 = (INT32)(temp64 >> 32);
  1471.                 break;
  1472.             case 0x1a: /* DIV */
  1473.                 if (RTVAL32)
  1474.                 {
  1475.                     LOVAL64 = (INT32)((INT32)RSVAL32 / (INT32)RTVAL32);
  1476.                     HIVAL64 = (INT32)((INT32)RSVAL32 % (INT32)RTVAL32);
  1477.                 }
  1478.                 break;
  1479.             case 0x1b: /* DIVU */
  1480.                 if (RTVAL32)
  1481.                 {
  1482.                     LOVAL64 = (INT32)(RSVAL32 / RTVAL32);
  1483.                     HIVAL64 = (INT32)(RSVAL32 % RTVAL32);
  1484.                 }
  1485.                 break;
  1486.             case 0x1c: /* DMULT */
  1487.                 temp64 = (INT64)RSVAL64 * (INT64)RTVAL64;
  1488.                 LOVAL64 = temp64;
  1489.                 HIVAL64 = (INT64)temp64 >> 63;
  1490.                 break;
  1491.             case 0x1d: /* DMULTU */
  1492.                 temp64 = (UINT64)RSVAL64 * (UINT64)RTVAL64;
  1493.                 LOVAL64 = temp64;
  1494.                 HIVAL64 = 0;
  1495.                 break;
  1496.             case 0x1e: /* DDIV */
  1497.                 if (RTVAL64)
  1498.                 {
  1499.                     LOVAL64 = (INT64)RSVAL64 / (INT64)RTVAL64;
  1500.                     HIVAL64 = (INT64)RSVAL64 % (INT64)RTVAL64;
  1501.                 }
  1502.                 break;
  1503.             case 0x1f: /* DDIVU */
  1504.                 if (RTVAL64)
  1505.                 {
  1506.                     LOVAL64 = RSVAL64 / RTVAL64;
  1507.                     HIVAL64 = RSVAL64 % RTVAL64;
  1508.                 }
  1509.                 break;
  1510.             case 0x20: /* ADD */
  1511.                 if (ENABLE_OVERFLOWS && RSVAL32 > ~RTVAL32)
  1512.                     generate_exception(EXCEPTION_OVERFLOW, 1);
  1513.                 else
  1514.                     RDVAL64 = (INT32)(RSVAL32 + RTVAL32);
  1515.                 break;
  1516.             case 0x21: /* ADDU */
  1517.                 if (RDREG)
  1518.                     RDVAL64 = (INT32)(RSVAL32 + RTVAL32);
  1519.                 break;
  1520.             case 0x22: /* SUB */
  1521.                 if (ENABLE_OVERFLOWS && RSVAL32 < RTVAL32)
  1522.                     generate_exception(EXCEPTION_OVERFLOW, 1);
  1523.                 else
  1524.                     RDVAL64 = (INT32)(RSVAL32 - RTVAL32);
  1525.                 break;
  1526.             case 0x23: /* SUBU */
  1527.                 if (RDREG)
  1528.                     RDVAL64 = (INT32)(RSVAL32 - RTVAL32);
  1529.                 break;
  1530.             case 0x24: /* AND */
  1531.                 if (RDREG)
  1532.                     RDVAL64 = RSVAL64 & RTVAL64;
  1533.                 break;
  1534.             case 0x25: /* OR */
  1535.                 if (RDREG)
  1536.                     RDVAL64 = RSVAL64 | RTVAL64;
  1537.                 break;
  1538.             case 0x26: /* XOR */
  1539.                 if (RDREG)
  1540.                     RDVAL64 = RSVAL64 ^ RTVAL64;
  1541.                 break;
  1542.             case 0x27: /* NOR */
  1543.                 if (RDREG)
  1544.                     RDVAL64 = ~(RSVAL64 | RTVAL64);
  1545.                 break;
  1546.             case 0x2a: /* SLT */
  1547.                 if (RDREG)
  1548.                     RDVAL64 = (INT64)RSVAL64 < (INT64)RTVAL64;
  1549.                 break;
  1550.             case 0x2b: /* SLTU */
  1551.                 if (RDREG)
  1552.                     RDVAL64 = (UINT64)RSVAL64 < (UINT64)RTVAL64;
  1553.                 break;
  1554.             case 0x2c: /* DADD */
  1555.                 if (ENABLE_OVERFLOWS && RSVAL64 > ~RTVAL64)
  1556.                     generate_exception(EXCEPTION_OVERFLOW, 1);
  1557.                 else
  1558.                     RDVAL64 = RSVAL64 + RTVAL64;
  1559.                 break;
  1560.             case 0x2d: /* DADDU */
  1561.                 if (RDREG)
  1562.                     RDVAL64 = RSVAL64 + RTVAL64;
  1563.                 break;
  1564.             case 0x2e: /* DSUB */
  1565.                 if (ENABLE_OVERFLOWS && RSVAL64 < RTVAL64)
  1566.                     generate_exception(EXCEPTION_OVERFLOW, 1);
  1567.                 else
  1568.                     RDVAL64 = RSVAL64 - RTVAL64;
  1569.                 break;
  1570.             case 0x2f: /* DSUBU */
  1571.                 if (RDREG)
  1572.                     RDVAL64 = RSVAL64 - RTVAL64;
  1573.                 break;
  1574.             case 0x30: /* TGE */
  1575.                 if ((INT64)RSVAL64 >= (INT64)RTVAL64)
  1576.                     generate_exception(EXCEPTION_TRAP, 1);
  1577.                 break;
  1578.             case 0x31: /* TGEU */
  1579.                 if (RSVAL64 >= RTVAL64)
  1580.                     generate_exception(EXCEPTION_TRAP, 1);
  1581.                 break;
  1582.             case 0x32: /* TLT */
  1583.                 if ((INT64)RSVAL64 < (INT64)RTVAL64)
  1584.                     generate_exception(EXCEPTION_TRAP, 1);
  1585.                 break;
  1586.             case 0x33: /* TLTU */
  1587.                 if (RSVAL64 < RTVAL64)
  1588.                     generate_exception(EXCEPTION_TRAP, 1);
  1589.                 break;
  1590.             case 0x34: /* TEQ */
  1591.                 if (RSVAL64 == RTVAL64)
  1592.                     generate_exception(EXCEPTION_TRAP, 1);
  1593.                 break;
  1594.             case 0x36: /* TNE */
  1595.                 if (RSVAL64 != RTVAL64)
  1596.                     generate_exception(EXCEPTION_TRAP, 1);
  1597.                 break;
  1598.             case 0x38: /* DSLL */
  1599.                 if (RDREG)
  1600.                     RDVAL64 = RTVAL64 << SHIFT;
  1601.                 break;
  1602.             case 0x3a: /* DSRL */
  1603.                 if (RDREG)
  1604.                     RDVAL64 = RTVAL64 >> SHIFT;
  1605.                 break;
  1606.             case 0x3b: /* DSRA */
  1607.                 if (RDREG)
  1608.                     RDVAL64 = (INT64)RTVAL64 >> SHIFT;
  1609.                 break;
  1610.             case 0x3c: /* DSLL32 */
  1611.                 if (RDREG)
  1612.                     RDVAL64 = RTVAL64 << (SHIFT + 32);
  1613.                 break;
  1614.             case 0x3e: /* DSRL32 */
  1615.                 if (RDREG)
  1616.                     RDVAL64 = RTVAL64 >> (SHIFT + 32);
  1617.                 break;
  1618.             case 0x3f: /* DSRA32 */
  1619.                 if (RDREG)
  1620.                     RDVAL64 = (INT64)RTVAL64 >> (SHIFT + 32);
  1621.                 break;
  1622.             default: /* ??? */
  1623.                 invalid_instruction(op);
  1624.                 break;
  1625.             }
  1626.             break;
  1627.  
  1628.         case 0x01: /* REGIMM */
  1629.             switch (RTREG)
  1630.             {
  1631.             case 0x00: /* BLTZ */
  1632.                 if ((INT64)RSVAL64 < 0)
  1633.                     ADDPC(SIMMVAL);
  1634.                 break;
  1635.             case 0x01: /* BGEZ */
  1636.                 if ((INT64)RSVAL64 >= 0)
  1637.                     ADDPC(SIMMVAL);
  1638.                 break;
  1639.             case 0x02: /* BLTZL */
  1640.                 if ((INT64)RSVAL64 < 0)
  1641.                     ADDPC(SIMMVAL);
  1642.                 else
  1643.                     mips3.pc += 4;
  1644.                 break;
  1645.             case 0x03: /* BGEZL */
  1646.                 if ((INT64)RSVAL64 >= 0)
  1647.                     ADDPC(SIMMVAL);
  1648.                 else
  1649.                     mips3.pc += 4;
  1650.                 break;
  1651.             case 0x08: /* TGEI */
  1652.                 if ((INT64)RSVAL64 >= SIMMVAL)
  1653.                     generate_exception(EXCEPTION_TRAP, 1);
  1654.                 break;
  1655.             case 0x09: /* TGEIU */
  1656.                 if (RSVAL64 >= SIMMVAL)
  1657.                     generate_exception(EXCEPTION_TRAP, 1);
  1658.                 break;
  1659.             case 0x0a: /* TLTI */
  1660.                 if ((INT64)RSVAL64 < SIMMVAL)
  1661.                     generate_exception(EXCEPTION_TRAP, 1);
  1662.                 break;
  1663.             case 0x0b: /* TLTIU */
  1664.                 if (RSVAL64 >= SIMMVAL)
  1665.                     generate_exception(EXCEPTION_TRAP, 1);
  1666.                 break;
  1667.             case 0x0c: /* TEQI */
  1668.                 if (RSVAL64 == SIMMVAL)
  1669.                     generate_exception(EXCEPTION_TRAP, 1);
  1670.                 break;
  1671.             case 0x0e: /* TNEI */
  1672.                 if (RSVAL64 != SIMMVAL)
  1673.                     generate_exception(EXCEPTION_TRAP, 1);
  1674.                 break;
  1675.             case 0x10: /* BLTZAL */
  1676.                 if ((INT64)RSVAL64 < 0)
  1677.                     ADDPCL(SIMMVAL, 31);
  1678.                 break;
  1679.             case 0x11: /* BGEZAL */
  1680.                 if ((INT64)RSVAL64 >= 0)
  1681.                     ADDPCL(SIMMVAL, 31);
  1682.                 break;
  1683.             case 0x12: /* BLTZALL */
  1684.                 if ((INT64)RSVAL64 < 0)
  1685.                     ADDPCL(SIMMVAL, 31)
  1686.                     else mips3.pc += 4;
  1687.                 break;
  1688.             case 0x13: /* BGEZALL */
  1689.                 if ((INT64)RSVAL64 >= 0)
  1690.                     ADDPCL(SIMMVAL, 31)
  1691.                     else mips3.pc += 4;
  1692.                 break;
  1693.             default: /* ??? */
  1694.                 invalid_instruction(op);
  1695.                 break;
  1696.             }
  1697.             break;
  1698.  
  1699.         case 0x02: /* J */
  1700.             ABSPC(LIMMVAL);
  1701.             break;
  1702.         case 0x03: /* JAL */
  1703.             ABSPCL(LIMMVAL, 31);
  1704.             break;
  1705.         case 0x04: /* BEQ */
  1706.             if (RSVAL64 == RTVAL64)
  1707.                 ADDPC(SIMMVAL);
  1708.             break;
  1709.         case 0x05: /* BNE */
  1710.             if (RSVAL64 != RTVAL64)
  1711.                 ADDPC(SIMMVAL);
  1712.             break;
  1713.         case 0x06: /* BLEZ */
  1714.             if ((INT64)RSVAL64 <= 0)
  1715.                 ADDPC(SIMMVAL);
  1716.             break;
  1717.         case 0x07: /* BGTZ */
  1718.             if ((INT64)RSVAL64 > 0)
  1719.                 ADDPC(SIMMVAL);
  1720.             break;
  1721.         case 0x08: /* ADDI */
  1722.             if (ENABLE_OVERFLOWS && RSVAL32 > ~SIMMVAL)
  1723.                 generate_exception(EXCEPTION_OVERFLOW, 1);
  1724.             else if (RTREG)
  1725.                 RTVAL64 = (INT32)(RSVAL32 + SIMMVAL);
  1726.             break;
  1727.         case 0x09: /* ADDIU */
  1728.             if (RTREG)
  1729.                 RTVAL64 = (INT32)(RSVAL32 + SIMMVAL);
  1730.             break;
  1731.         case 0x0a: /* SLTI */
  1732.             if (RTREG)
  1733.                 RTVAL64 = (INT64)RSVAL64 < (INT64)SIMMVAL;
  1734.             break;
  1735.         case 0x0b: /* SLTIU */
  1736.             if (RTREG)
  1737.                 RTVAL64 = (UINT64)RSVAL64 < (UINT64)SIMMVAL;
  1738.             break;
  1739.         case 0x0c: /* ANDI */
  1740.             if (RTREG)
  1741.                 RTVAL64 = RSVAL64 & UIMMVAL;
  1742.             break;
  1743.         case 0x0d: /* ORI */
  1744.             if (RTREG)
  1745.                 RTVAL64 = RSVAL64 | UIMMVAL;
  1746.             break;
  1747.         case 0x0e: /* XORI */
  1748.             if (RTREG)
  1749.                 RTVAL64 = RSVAL64 ^ UIMMVAL;
  1750.             break;
  1751.         case 0x0f: /* LUI */
  1752.             if (RTREG)
  1753.                 RTVAL64 = (INT32)(UIMMVAL << 16);
  1754.             break;
  1755.         case 0x10: /* COP0 */
  1756.             handle_cop0(op);
  1757.             break;
  1758.         case 0x11: /* COP1 */
  1759.             handle_cop1(op);
  1760.             break;
  1761.         case 0x12: /* COP2 */
  1762.             handle_cop2(op);
  1763.             break;
  1764.         case 0x13: /* COP1X - R5000 */
  1765.             handle_cop1x(op);
  1766.             break;
  1767.         case 0x14: /* BEQL */
  1768.             if (RSVAL64 == RTVAL64)
  1769.                 ADDPC(SIMMVAL);
  1770.             else
  1771.                 mips3.pc += 4;
  1772.             break;
  1773.         case 0x15: /* BNEL */
  1774.             if (RSVAL64 != RTVAL64)
  1775.                 ADDPC(SIMMVAL);
  1776.             else
  1777.                 mips3.pc += 4;
  1778.             break;
  1779.         case 0x16: /* BLEZL */
  1780.             if ((INT64)RSVAL64 <= 0)
  1781.                 ADDPC(SIMMVAL);
  1782.             else
  1783.                 mips3.pc += 4;
  1784.             break;
  1785.         case 0x17: /* BGTZL */
  1786.             if ((INT64)RSVAL64 > 0)
  1787.                 ADDPC(SIMMVAL);
  1788.             else
  1789.                 mips3.pc += 4;
  1790.             break;
  1791.         case 0x18: /* DADDI */
  1792.             if (ENABLE_OVERFLOWS && RSVAL64 > ~SIMMVAL)
  1793.                 generate_exception(EXCEPTION_OVERFLOW, 1);
  1794.             else if (RTREG)
  1795.                 RTVAL64 = RSVAL64 + (INT64)SIMMVAL;
  1796.             break;
  1797.         case 0x19: /* DADDIU */
  1798.             if (RTREG)
  1799.                 RTVAL64 = RSVAL64 + (UINT64)SIMMVAL;
  1800.             break;
  1801.         case 0x1a: /* LDL */
  1802.             (*mips3.ldl)(op);
  1803.             break;
  1804.         case 0x1b: /* LDR */
  1805.             (*mips3.ldr)(op);
  1806.             break;
  1807.         case 0x20: /* LB */
  1808.             temp = RBYTE(SIMMVAL + RSVAL32);
  1809.             if (RTREG)
  1810.                 RTVAL64 = (INT8)temp;
  1811.             break;
  1812.         case 0x21: /* LH */
  1813.             temp = RWORD(SIMMVAL + RSVAL32);
  1814.             if (RTREG)
  1815.                 RTVAL64 = (INT16)temp;
  1816.             break;
  1817.         case 0x22: /* LWL */
  1818.             (*mips3.lwl)(op);
  1819.             break;
  1820.         case 0x23: /* LW */
  1821.             temp = RLONG(SIMMVAL + RSVAL32);
  1822.             if (RTREG)
  1823.                 RTVAL64 = (INT32)temp;
  1824.             break;
  1825.         case 0x24: /* LBU */
  1826.             temp = RBYTE(SIMMVAL + RSVAL32);
  1827.             if (RTREG)
  1828.                 RTVAL64 = (UINT8)temp;
  1829.             break;
  1830.         case 0x25: /* LHU */
  1831.             temp = RWORD(SIMMVAL + RSVAL32);
  1832.             if (RTREG)
  1833.                 RTVAL64 = (UINT16)temp;
  1834.             break;
  1835.         case 0x26: /* LWR */
  1836.             (*mips3.lwr)(op);
  1837.             break;
  1838.         case 0x27: /* LWU */
  1839.             temp = RLONG(SIMMVAL + RSVAL32);
  1840.             if (RTREG)
  1841.                 RTVAL64 = (UINT32)temp;
  1842.             break;
  1843.         case 0x28: /* SB */
  1844.             WBYTE(SIMMVAL + RSVAL32, RTVAL32);
  1845.             break;
  1846.         case 0x29: /* SH */
  1847.             WWORD(SIMMVAL + RSVAL32, RTVAL32);
  1848.             break;
  1849.         case 0x2a: /* SWL */
  1850.             (*mips3.swl)(op);
  1851.             break;
  1852.         case 0x2b: /* SW */
  1853.             WLONG(SIMMVAL + RSVAL32, RTVAL32);
  1854.             break;
  1855.         case 0x2c: /* SDL */
  1856.             (*mips3.sdl)(op);
  1857.             break;
  1858.         case 0x2d: /* SDR */
  1859.             (*mips3.sdr)(op);
  1860.             break;
  1861.         case 0x2e: /* SWR */
  1862.             (*mips3.swr)(op);
  1863.             break;
  1864.         case 0x2f: /* CACHE */ /* effective no-op */
  1865.             break;
  1866.         case 0x30: /* LL */
  1867.             logerror("mips3 Unhandled op: LL\n");
  1868.             break;
  1869.         case 0x31: /* LWC1 */
  1870.             set_cop1_reg(RTREG, RLONG(SIMMVAL + RSVAL32));
  1871.             break;
  1872.         case 0x32: /* LWC2 */
  1873.             set_cop2_reg(RTREG, RLONG(SIMMVAL + RSVAL32));
  1874.             break;
  1875.         case 0x33: /* PREF */ /* effective no-op */
  1876.             break;
  1877.         case 0x34: /* LLD */
  1878.             logerror("mips3 Unhandled op: LLD\n");
  1879.             break;
  1880.         case 0x35: /* LDC1 */
  1881.             set_cop1_reg(RTREG, RDOUBLE(SIMMVAL + RSVAL32));
  1882.             break;
  1883.         case 0x36: /* LDC2 */
  1884.             set_cop2_reg(RTREG, RDOUBLE(SIMMVAL + RSVAL32));
  1885.             break;
  1886.         case 0x37: /* LD */
  1887.             temp64 = RDOUBLE(SIMMVAL + RSVAL32);
  1888.             if (RTREG)
  1889.                 RTVAL64 = temp64;
  1890.             break;
  1891.         case 0x38: /* SC */
  1892.             logerror("mips3 Unhandled op: SC\n");
  1893.             break;
  1894.         case 0x39: /* SWC1 */
  1895.             WLONG(SIMMVAL + RSVAL32, get_cop1_reg(RTREG));
  1896.             break;
  1897.         case 0x3a: /* SWC2 */
  1898.             WLONG(SIMMVAL + RSVAL32, get_cop2_reg(RTREG));
  1899.             break;
  1900.         case 0x3b: /* SWC3 */
  1901.             invalid_instruction(op);
  1902.             break;
  1903.         case 0x3c: /* SCD */
  1904.             logerror("mips3 Unhandled op: SCD\n");
  1905.             break;
  1906.         case 0x3d: /* SDC1 */
  1907.             WDOUBLE(SIMMVAL + RSVAL32, get_cop1_reg(RTREG));
  1908.             break;
  1909.         case 0x3e: /* SDC2 */
  1910.             WDOUBLE(SIMMVAL + RSVAL32, get_cop2_reg(RTREG));
  1911.             break;
  1912.         case 0x3f: /* SD */
  1913.             WDOUBLE(SIMMVAL + RSVAL32, RTVAL64);
  1914.             break;
  1915.         default: /* ??? */
  1916.             invalid_instruction(op);
  1917.             break;
  1918.         }
  1919.         mips3_icount--;
  1920.  
  1921.     } while (mips3_icount > 0 || mips3.nextpc != ~0);
  1922.  
  1923.     // printf("mips3_execute done (PC=%08X)\n", mips3.pc);
  1924.  
  1925.     mips3_icount -= mips3.interrupt_cycles;
  1926.     mips3.interrupt_cycles = 0;
  1927.     return cycles - mips3_icount;
  1928. }
  1929.  
  1930. /*###################################################################################################
  1931. **  REGISTER SNOOP
  1932. **#################################################################################################*/
  1933.  
  1934. unsigned mips3_get_reg(int regnum)
  1935. {
  1936.     switch (regnum)
  1937.     {
  1938.     case REG_PC:
  1939.     case MIPS3_PC:
  1940.         return mips3.pc;
  1941.     case MIPS3_SR:
  1942.         return SR;
  1943.     case MIPS3_EPC:
  1944.         return mips3.cpr[0][COP0_EPC];
  1945.     case MIPS3_CAUSE:
  1946.         return mips3.cpr[0][COP0_Cause];
  1947.     case MIPS3_COUNT:
  1948.         return mips3.cpr[0][COP0_Count];
  1949.     case MIPS3_COMPARE:
  1950.         return mips3.cpr[0][COP0_Compare];
  1951.  
  1952.     case MIPS3_R0:
  1953.         return (UINT32)mips3.r[0];
  1954.     case MIPS3_R1:
  1955.         return (UINT32)mips3.r[1];
  1956.     case MIPS3_R2:
  1957.         return (UINT32)mips3.r[2];
  1958.     case MIPS3_R3:
  1959.         return (UINT32)mips3.r[3];
  1960.     case MIPS3_R4:
  1961.         return (UINT32)mips3.r[4];
  1962.     case MIPS3_R5:
  1963.         return (UINT32)mips3.r[5];
  1964.     case MIPS3_R6:
  1965.         return (UINT32)mips3.r[6];
  1966.     case MIPS3_R7:
  1967.         return (UINT32)mips3.r[7];
  1968.     case MIPS3_R8:
  1969.         return (UINT32)mips3.r[8];
  1970.     case MIPS3_R9:
  1971.         return (UINT32)mips3.r[9];
  1972.     case MIPS3_R10:
  1973.         return (UINT32)mips3.r[10];
  1974.     case MIPS3_R11:
  1975.         return (UINT32)mips3.r[11];
  1976.     case MIPS3_R12:
  1977.         return (UINT32)mips3.r[12];
  1978.     case MIPS3_R13:
  1979.         return (UINT32)mips3.r[13];
  1980.     case MIPS3_R14:
  1981.         return (UINT32)mips3.r[14];
  1982.     case MIPS3_R15:
  1983.         return (UINT32)mips3.r[15];
  1984.     case MIPS3_R16:
  1985.         return (UINT32)mips3.r[16];
  1986.     case MIPS3_R17:
  1987.         return (UINT32)mips3.r[17];
  1988.     case MIPS3_R18:
  1989.         return (UINT32)mips3.r[18];
  1990.     case MIPS3_R19:
  1991.         return (UINT32)mips3.r[19];
  1992.     case MIPS3_R20:
  1993.         return (UINT32)mips3.r[20];
  1994.     case MIPS3_R21:
  1995.         return (UINT32)mips3.r[21];
  1996.     case MIPS3_R22:
  1997.         return (UINT32)mips3.r[22];
  1998.     case MIPS3_R23:
  1999.         return (UINT32)mips3.r[23];
  2000.     case MIPS3_R24:
  2001.         return (UINT32)mips3.r[24];
  2002.     case MIPS3_R25:
  2003.         return (UINT32)mips3.r[25];
  2004.     case MIPS3_R26:
  2005.         return (UINT32)mips3.r[26];
  2006.     case MIPS3_R27:
  2007.         return (UINT32)mips3.r[27];
  2008.     case MIPS3_R28:
  2009.         return (UINT32)mips3.r[28];
  2010.     case MIPS3_R29:
  2011.         return (UINT32)mips3.r[29];
  2012.     case MIPS3_R30:
  2013.         return (UINT32)mips3.r[30];
  2014.     case REG_SP:
  2015.     case MIPS3_R31:
  2016.         return (UINT32)mips3.r[31];
  2017.     case MIPS3_HI:
  2018.         return (UINT32)mips3.hi;
  2019.     case MIPS3_LO:
  2020.         return (UINT32)mips3.lo;
  2021.  
  2022.     case MIPS3_R0LO:
  2023.         return (UINT32)mips3.r[0];
  2024.     case MIPS3_R1LO:
  2025.         return (UINT32)mips3.r[1];
  2026.     case MIPS3_R2LO:
  2027.         return (UINT32)mips3.r[2];
  2028.     case MIPS3_R3LO:
  2029.         return (UINT32)mips3.r[3];
  2030.     case MIPS3_R4LO:
  2031.         return (UINT32)mips3.r[4];
  2032.     case MIPS3_R5LO:
  2033.         return (UINT32)mips3.r[5];
  2034.     case MIPS3_R6LO:
  2035.         return (UINT32)mips3.r[6];
  2036.     case MIPS3_R7LO:
  2037.         return (UINT32)mips3.r[7];
  2038.     case MIPS3_R8LO:
  2039.         return (UINT32)mips3.r[8];
  2040.     case MIPS3_R9LO:
  2041.         return (UINT32)mips3.r[9];
  2042.     case MIPS3_R10LO:
  2043.         return (UINT32)mips3.r[10];
  2044.     case MIPS3_R11LO:
  2045.         return (UINT32)mips3.r[11];
  2046.     case MIPS3_R12LO:
  2047.         return (UINT32)mips3.r[12];
  2048.     case MIPS3_R13LO:
  2049.         return (UINT32)mips3.r[13];
  2050.     case MIPS3_R14LO:
  2051.         return (UINT32)mips3.r[14];
  2052.     case MIPS3_R15LO:
  2053.         return (UINT32)mips3.r[15];
  2054.     case MIPS3_R16LO:
  2055.         return (UINT32)mips3.r[16];
  2056.     case MIPS3_R17LO:
  2057.         return (UINT32)mips3.r[17];
  2058.     case MIPS3_R18LO:
  2059.         return (UINT32)mips3.r[18];
  2060.     case MIPS3_R19LO:
  2061.         return (UINT32)mips3.r[19];
  2062.     case MIPS3_R20LO:
  2063.         return (UINT32)mips3.r[20];
  2064.     case MIPS3_R21LO:
  2065.         return (UINT32)mips3.r[21];
  2066.     case MIPS3_R22LO:
  2067.         return (UINT32)mips3.r[22];
  2068.     case MIPS3_R23LO:
  2069.         return (UINT32)mips3.r[23];
  2070.     case MIPS3_R24LO:
  2071.         return (UINT32)mips3.r[24];
  2072.     case MIPS3_R25LO:
  2073.         return (UINT32)mips3.r[25];
  2074.     case MIPS3_R26LO:
  2075.         return (UINT32)mips3.r[26];
  2076.     case MIPS3_R27LO:
  2077.         return (UINT32)mips3.r[27];
  2078.     case MIPS3_R28LO:
  2079.         return (UINT32)mips3.r[28];
  2080.     case MIPS3_R29LO:
  2081.         return (UINT32)mips3.r[29];
  2082.     case MIPS3_R30LO:
  2083.         return (UINT32)mips3.r[30];
  2084.     case MIPS3_R31LO:
  2085.         return (UINT32)mips3.r[31];
  2086.     case MIPS3_HILO:
  2087.         return (UINT32)mips3.hi;
  2088.     case MIPS3_LOLO:
  2089.         return (UINT32)mips3.lo;
  2090.  
  2091.     case MIPS3_R0HI:
  2092.         return (UINT32)(mips3.r[0] >> 32);
  2093.     case MIPS3_R1HI:
  2094.         return (UINT32)(mips3.r[1] >> 32);
  2095.     case MIPS3_R2HI:
  2096.         return (UINT32)(mips3.r[2] >> 32);
  2097.     case MIPS3_R3HI:
  2098.         return (UINT32)(mips3.r[3] >> 32);
  2099.     case MIPS3_R4HI:
  2100.         return (UINT32)(mips3.r[4] >> 32);
  2101.     case MIPS3_R5HI:
  2102.         return (UINT32)(mips3.r[5] >> 32);
  2103.     case MIPS3_R6HI:
  2104.         return (UINT32)(mips3.r[6] >> 32);
  2105.     case MIPS3_R7HI:
  2106.         return (UINT32)(mips3.r[7] >> 32);
  2107.     case MIPS3_R8HI:
  2108.         return (UINT32)(mips3.r[8] >> 32);
  2109.     case MIPS3_R9HI:
  2110.         return (UINT32)(mips3.r[9] >> 32);
  2111.     case MIPS3_R10HI:
  2112.         return (UINT32)(mips3.r[10] >> 32);
  2113.     case MIPS3_R11HI:
  2114.         return (UINT32)(mips3.r[11] >> 32);
  2115.     case MIPS3_R12HI:
  2116.         return (UINT32)(mips3.r[12] >> 32);
  2117.     case MIPS3_R13HI:
  2118.         return (UINT32)(mips3.r[13] >> 32);
  2119.     case MIPS3_R14HI:
  2120.         return (UINT32)(mips3.r[14] >> 32);
  2121.     case MIPS3_R15HI:
  2122.         return (UINT32)(mips3.r[15] >> 32);
  2123.     case MIPS3_R16HI:
  2124.         return (UINT32)(mips3.r[16] >> 32);
  2125.     case MIPS3_R17HI:
  2126.         return (UINT32)(mips3.r[17] >> 32);
  2127.     case MIPS3_R18HI:
  2128.         return (UINT32)(mips3.r[18] >> 32);
  2129.     case MIPS3_R19HI:
  2130.         return (UINT32)(mips3.r[19] >> 32);
  2131.     case MIPS3_R20HI:
  2132.         return (UINT32)(mips3.r[20] >> 32);
  2133.     case MIPS3_R21HI:
  2134.         return (UINT32)(mips3.r[21] >> 32);
  2135.     case MIPS3_R22HI:
  2136.         return (UINT32)(mips3.r[22] >> 32);
  2137.     case MIPS3_R23HI:
  2138.         return (UINT32)(mips3.r[23] >> 32);
  2139.     case MIPS3_R24HI:
  2140.         return (UINT32)(mips3.r[24] >> 32);
  2141.     case MIPS3_R25HI:
  2142.         return (UINT32)(mips3.r[25] >> 32);
  2143.     case MIPS3_R26HI:
  2144.         return (UINT32)(mips3.r[26] >> 32);
  2145.     case MIPS3_R27HI:
  2146.         return (UINT32)(mips3.r[27] >> 32);
  2147.     case MIPS3_R28HI:
  2148.         return (UINT32)(mips3.r[28] >> 32);
  2149.     case MIPS3_R29HI:
  2150.         return (UINT32)(mips3.r[29] >> 32);
  2151.     case MIPS3_R30HI:
  2152.         return (UINT32)(mips3.r[30] >> 32);
  2153.     case MIPS3_R31HI:
  2154.         return (UINT32)(mips3.r[31] >> 32);
  2155.     case MIPS3_HIHI:
  2156.         return (UINT32)(mips3.hi >> 32);
  2157.     case MIPS3_LOHI:
  2158.         return (UINT32)(mips3.lo >> 32);
  2159.  
  2160.     case REG_PREVIOUSPC:
  2161.         return mips3.ppc;
  2162.  
  2163.     default:
  2164.         if (regnum <= REG_SP_CONTENTS)
  2165.         {
  2166.             //              unsigned offset = REG_SP_CONTENTS - regnum;
  2167.             //              if (offset < PC_STACK_DEPTH)
  2168.             //                  return mips3.pc_stack[offset];
  2169.         }
  2170.     }
  2171.     return 0;
  2172. }
  2173.  
  2174. /*###################################################################################################
  2175. **  REGISTER MODIFY
  2176. **#################################################################################################*/
  2177.  
  2178. void mips3_set_reg(int regnum, unsigned val)
  2179. {
  2180.     switch (regnum)
  2181.     {
  2182.     case REG_PC:
  2183.     case MIPS3_PC:
  2184.         mips3.pc = val;
  2185.         break;
  2186.     case MIPS3_SR:
  2187.         SR = val;
  2188.         break;
  2189.     case MIPS3_EPC:
  2190.         mips3.cpr[0][COP0_EPC] = val;
  2191.         break;
  2192.     case MIPS3_CAUSE:
  2193.         mips3.cpr[0][COP0_Cause] = val;
  2194.         break;
  2195.     case MIPS3_COUNT:
  2196.         mips3.cpr[0][COP0_Count] = val;
  2197.         break;
  2198.     case MIPS3_COMPARE:
  2199.         mips3.cpr[0][COP0_Compare] = val;
  2200.         break;
  2201.  
  2202.     case MIPS3_R0:
  2203.         mips3.r[0] = (INT32)val;
  2204.         break;
  2205.     case MIPS3_R1:
  2206.         mips3.r[1] = (INT32)val;
  2207.         break;
  2208.     case MIPS3_R2:
  2209.         mips3.r[2] = (INT32)val;
  2210.         break;
  2211.     case MIPS3_R3:
  2212.         mips3.r[3] = (INT32)val;
  2213.         break;
  2214.     case MIPS3_R4:
  2215.         mips3.r[4] = (INT32)val;
  2216.         break;
  2217.     case MIPS3_R5:
  2218.         mips3.r[5] = (INT32)val;
  2219.         break;
  2220.     case MIPS3_R6:
  2221.         mips3.r[6] = (INT32)val;
  2222.         break;
  2223.     case MIPS3_R7:
  2224.         mips3.r[7] = (INT32)val;
  2225.         break;
  2226.     case MIPS3_R8:
  2227.         mips3.r[8] = (INT32)val;
  2228.         break;
  2229.     case MIPS3_R9:
  2230.         mips3.r[9] = (INT32)val;
  2231.         break;
  2232.     case MIPS3_R10:
  2233.         mips3.r[10] = (INT32)val;
  2234.         break;
  2235.     case MIPS3_R11:
  2236.         mips3.r[11] = (INT32)val;
  2237.         break;
  2238.     case MIPS3_R12:
  2239.         mips3.r[12] = (INT32)val;
  2240.         break;
  2241.     case MIPS3_R13:
  2242.         mips3.r[13] = (INT32)val;
  2243.         break;
  2244.     case MIPS3_R14:
  2245.         mips3.r[14] = (INT32)val;
  2246.         break;
  2247.     case MIPS3_R15:
  2248.         mips3.r[15] = (INT32)val;
  2249.         break;
  2250.     case MIPS3_R16:
  2251.         mips3.r[16] = (INT32)val;
  2252.         break;
  2253.     case MIPS3_R17:
  2254.         mips3.r[17] = (INT32)val;
  2255.         break;
  2256.     case MIPS3_R18:
  2257.         mips3.r[18] = (INT32)val;
  2258.         break;
  2259.     case MIPS3_R19:
  2260.         mips3.r[19] = (INT32)val;
  2261.         break;
  2262.     case MIPS3_R20:
  2263.         mips3.r[20] = (INT32)val;
  2264.         break;
  2265.     case MIPS3_R21:
  2266.         mips3.r[21] = (INT32)val;
  2267.         break;
  2268.     case MIPS3_R22:
  2269.         mips3.r[22] = (INT32)val;
  2270.         break;
  2271.     case MIPS3_R23:
  2272.         mips3.r[23] = (INT32)val;
  2273.         break;
  2274.     case MIPS3_R24:
  2275.         mips3.r[24] = (INT32)val;
  2276.         break;
  2277.     case MIPS3_R25:
  2278.         mips3.r[25] = (INT32)val;
  2279.         break;
  2280.     case MIPS3_R26:
  2281.         mips3.r[26] = (INT32)val;
  2282.         break;
  2283.     case MIPS3_R27:
  2284.         mips3.r[27] = (INT32)val;
  2285.         break;
  2286.     case MIPS3_R28:
  2287.         mips3.r[28] = (INT32)val;
  2288.         break;
  2289.     case MIPS3_R29:
  2290.         mips3.r[29] = (INT32)val;
  2291.         break;
  2292.     case MIPS3_R30:
  2293.         mips3.r[30] = (INT32)val;
  2294.         break;
  2295.     case REG_SP:
  2296.     case MIPS3_R31:
  2297.         mips3.r[31] = (INT32)val;
  2298.         break;
  2299.     case MIPS3_HI:
  2300.         mips3.hi = (INT32)val;
  2301.         break;
  2302.     case MIPS3_LO:
  2303.         mips3.lo = (INT32)val;
  2304.         break;
  2305.  
  2306.     case MIPS3_R0LO:
  2307.         mips3.r[0] = (mips3.r[0] & ~((UINT64)0xffffffff)) | val;
  2308.         break;
  2309.     case MIPS3_R1LO:
  2310.         mips3.r[1] = (mips3.r[1] & ~((UINT64)0xffffffff)) | val;
  2311.         break;
  2312.     case MIPS3_R2LO:
  2313.         mips3.r[2] = (mips3.r[2] & ~((UINT64)0xffffffff)) | val;
  2314.         break;
  2315.     case MIPS3_R3LO:
  2316.         mips3.r[3] = (mips3.r[3] & ~((UINT64)0xffffffff)) | val;
  2317.         break;
  2318.     case MIPS3_R4LO:
  2319.         mips3.r[4] = (mips3.r[4] & ~((UINT64)0xffffffff)) | val;
  2320.         break;
  2321.     case MIPS3_R5LO:
  2322.         mips3.r[5] = (mips3.r[5] & ~((UINT64)0xffffffff)) | val;
  2323.         break;
  2324.     case MIPS3_R6LO:
  2325.         mips3.r[6] = (mips3.r[6] & ~((UINT64)0xffffffff)) | val;
  2326.         break;
  2327.     case MIPS3_R7LO:
  2328.         mips3.r[7] = (mips3.r[7] & ~((UINT64)0xffffffff)) | val;
  2329.         break;
  2330.     case MIPS3_R8LO:
  2331.         mips3.r[8] = (mips3.r[8] & ~((UINT64)0xffffffff)) | val;
  2332.         break;
  2333.     case MIPS3_R9LO:
  2334.         mips3.r[9] = (mips3.r[9] & ~((UINT64)0xffffffff)) | val;
  2335.         break;
  2336.     case MIPS3_R10LO:
  2337.         mips3.r[10] = (mips3.r[10] & ~((UINT64)0xffffffff)) | val;
  2338.         break;
  2339.     case MIPS3_R11LO:
  2340.         mips3.r[11] = (mips3.r[11] & ~((UINT64)0xffffffff)) | val;
  2341.         break;
  2342.     case MIPS3_R12LO:
  2343.         mips3.r[12] = (mips3.r[12] & ~((UINT64)0xffffffff)) | val;
  2344.         break;
  2345.     case MIPS3_R13LO:
  2346.         mips3.r[13] = (mips3.r[13] & ~((UINT64)0xffffffff)) | val;
  2347.         break;
  2348.     case MIPS3_R14LO:
  2349.         mips3.r[14] = (mips3.r[14] & ~((UINT64)0xffffffff)) | val;
  2350.         break;
  2351.     case MIPS3_R15LO:
  2352.         mips3.r[15] = (mips3.r[15] & ~((UINT64)0xffffffff)) | val;
  2353.         break;
  2354.     case MIPS3_R16LO:
  2355.         mips3.r[16] = (mips3.r[16] & ~((UINT64)0xffffffff)) | val;
  2356.         break;
  2357.     case MIPS3_R17LO:
  2358.         mips3.r[17] = (mips3.r[17] & ~((UINT64)0xffffffff)) | val;
  2359.         break;
  2360.     case MIPS3_R18LO:
  2361.         mips3.r[18] = (mips3.r[18] & ~((UINT64)0xffffffff)) | val;
  2362.         break;
  2363.     case MIPS3_R19LO:
  2364.         mips3.r[19] = (mips3.r[19] & ~((UINT64)0xffffffff)) | val;
  2365.         break;
  2366.     case MIPS3_R20LO:
  2367.         mips3.r[20] = (mips3.r[20] & ~((UINT64)0xffffffff)) | val;
  2368.         break;
  2369.     case MIPS3_R21LO:
  2370.         mips3.r[21] = (mips3.r[21] & ~((UINT64)0xffffffff)) | val;
  2371.         break;
  2372.     case MIPS3_R22LO:
  2373.         mips3.r[22] = (mips3.r[22] & ~((UINT64)0xffffffff)) | val;
  2374.         break;
  2375.     case MIPS3_R23LO:
  2376.         mips3.r[23] = (mips3.r[23] & ~((UINT64)0xffffffff)) | val;
  2377.         break;
  2378.     case MIPS3_R24LO:
  2379.         mips3.r[24] = (mips3.r[24] & ~((UINT64)0xffffffff)) | val;
  2380.         break;
  2381.     case MIPS3_R25LO:
  2382.         mips3.r[25] = (mips3.r[25] & ~((UINT64)0xffffffff)) | val;
  2383.         break;
  2384.     case MIPS3_R26LO:
  2385.         mips3.r[26] = (mips3.r[26] & ~((UINT64)0xffffffff)) | val;
  2386.         break;
  2387.     case MIPS3_R27LO:
  2388.         mips3.r[27] = (mips3.r[27] & ~((UINT64)0xffffffff)) | val;
  2389.         break;
  2390.     case MIPS3_R28LO:
  2391.         mips3.r[28] = (mips3.r[28] & ~((UINT64)0xffffffff)) | val;
  2392.         break;
  2393.     case MIPS3_R29LO:
  2394.         mips3.r[29] = (mips3.r[29] & ~((UINT64)0xffffffff)) | val;
  2395.         break;
  2396.     case MIPS3_R30LO:
  2397.         mips3.r[30] = (mips3.r[30] & ~((UINT64)0xffffffff)) | val;
  2398.         break;
  2399.     case MIPS3_R31LO:
  2400.         mips3.r[31] = (mips3.r[31] & ~((UINT64)0xffffffff)) | val;
  2401.         break;
  2402.     case MIPS3_HILO:
  2403.         mips3.hi = (mips3.hi & ~((UINT64)0xffffffff)) | val;
  2404.         break;
  2405.     case MIPS3_LOLO:
  2406.         mips3.lo = (mips3.lo & ~((UINT64)0xffffffff)) | val;
  2407.         break;
  2408.  
  2409.     case MIPS3_R0HI:
  2410.         mips3.r[0] = (mips3.r[0] & 0xffffffff) | ((UINT64)val << 32);
  2411.         break;
  2412.     case MIPS3_R1HI:
  2413.         mips3.r[1] = (mips3.r[1] & 0xffffffff) | ((UINT64)val << 32);
  2414.         break;
  2415.     case MIPS3_R2HI:
  2416.         mips3.r[2] = (mips3.r[2] & 0xffffffff) | ((UINT64)val << 32);
  2417.         break;
  2418.     case MIPS3_R3HI:
  2419.         mips3.r[3] = (mips3.r[3] & 0xffffffff) | ((UINT64)val << 32);
  2420.         break;
  2421.     case MIPS3_R4HI:
  2422.         mips3.r[4] = (mips3.r[4] & 0xffffffff) | ((UINT64)val << 32);
  2423.         break;
  2424.     case MIPS3_R5HI:
  2425.         mips3.r[5] = (mips3.r[5] & 0xffffffff) | ((UINT64)val << 32);
  2426.         break;
  2427.     case MIPS3_R6HI:
  2428.         mips3.r[6] = (mips3.r[6] & 0xffffffff) | ((UINT64)val << 32);
  2429.         break;
  2430.     case MIPS3_R7HI:
  2431.         mips3.r[7] = (mips3.r[7] & 0xffffffff) | ((UINT64)val << 32);
  2432.         break;
  2433.     case MIPS3_R8HI:
  2434.         mips3.r[8] = (mips3.r[8] & 0xffffffff) | ((UINT64)val << 32);
  2435.         break;
  2436.     case MIPS3_R9HI:
  2437.         mips3.r[9] = (mips3.r[9] & 0xffffffff) | ((UINT64)val << 32);
  2438.         break;
  2439.     case MIPS3_R10HI:
  2440.         mips3.r[10] = (mips3.r[10] & 0xffffffff) | ((UINT64)val << 32);
  2441.         break;
  2442.     case MIPS3_R11HI:
  2443.         mips3.r[11] = (mips3.r[11] & 0xffffffff) | ((UINT64)val << 32);
  2444.         break;
  2445.     case MIPS3_R12HI:
  2446.         mips3.r[12] = (mips3.r[12] & 0xffffffff) | ((UINT64)val << 32);
  2447.         break;
  2448.     case MIPS3_R13HI:
  2449.         mips3.r[13] = (mips3.r[13] & 0xffffffff) | ((UINT64)val << 32);
  2450.         break;
  2451.     case MIPS3_R14HI:
  2452.         mips3.r[14] = (mips3.r[14] & 0xffffffff) | ((UINT64)val << 32);
  2453.         break;
  2454.     case MIPS3_R15HI:
  2455.         mips3.r[15] = (mips3.r[15] & 0xffffffff) | ((UINT64)val << 32);
  2456.         break;
  2457.     case MIPS3_R16HI:
  2458.         mips3.r[16] = (mips3.r[16] & 0xffffffff) | ((UINT64)val << 32);
  2459.         break;
  2460.     case MIPS3_R17HI:
  2461.         mips3.r[17] = (mips3.r[17] & 0xffffffff) | ((UINT64)val << 32);
  2462.         break;
  2463.     case MIPS3_R18HI:
  2464.         mips3.r[18] = (mips3.r[18] & 0xffffffff) | ((UINT64)val << 32);
  2465.         break;
  2466.     case MIPS3_R19HI:
  2467.         mips3.r[19] = (mips3.r[19] & 0xffffffff) | ((UINT64)val << 32);
  2468.         break;
  2469.     case MIPS3_R20HI:
  2470.         mips3.r[20] = (mips3.r[20] & 0xffffffff) | ((UINT64)val << 32);
  2471.         break;
  2472.     case MIPS3_R21HI:
  2473.         mips3.r[21] = (mips3.r[21] & 0xffffffff) | ((UINT64)val << 32);
  2474.         break;
  2475.     case MIPS3_R22HI:
  2476.         mips3.r[22] = (mips3.r[22] & 0xffffffff) | ((UINT64)val << 32);
  2477.         break;
  2478.     case MIPS3_R23HI:
  2479.         mips3.r[23] = (mips3.r[23] & 0xffffffff) | ((UINT64)val << 32);
  2480.         break;
  2481.     case MIPS3_R24HI:
  2482.         mips3.r[24] = (mips3.r[24] & 0xffffffff) | ((UINT64)val << 32);
  2483.         break;
  2484.     case MIPS3_R25HI:
  2485.         mips3.r[25] = (mips3.r[25] & 0xffffffff) | ((UINT64)val << 32);
  2486.         break;
  2487.     case MIPS3_R26HI:
  2488.         mips3.r[26] = (mips3.r[26] & 0xffffffff) | ((UINT64)val << 32);
  2489.         break;
  2490.     case MIPS3_R27HI:
  2491.         mips3.r[27] = (mips3.r[27] & 0xffffffff) | ((UINT64)val << 32);
  2492.         break;
  2493.     case MIPS3_R28HI:
  2494.         mips3.r[28] = (mips3.r[28] & 0xffffffff) | ((UINT64)val << 32);
  2495.         break;
  2496.     case MIPS3_R29HI:
  2497.         mips3.r[29] = (mips3.r[29] & 0xffffffff) | ((UINT64)val << 32);
  2498.         break;
  2499.     case MIPS3_R30HI:
  2500.         mips3.r[30] = (mips3.r[30] & 0xffffffff) | ((UINT64)val << 32);
  2501.         break;
  2502.     case MIPS3_R31HI:
  2503.         mips3.r[31] = (mips3.r[31] & 0xffffffff) | ((UINT64)val << 32);
  2504.         break;
  2505.     case MIPS3_HIHI:
  2506.         mips3.hi = (mips3.hi & 0xffffffff) | ((UINT64)val << 32);
  2507.         break;
  2508.     case MIPS3_LOHI:
  2509.         mips3.lo = (mips3.lo & 0xffffffff) | ((UINT64)val << 32);
  2510.         break;
  2511.  
  2512.     default:
  2513.         if (regnum <= REG_SP_CONTENTS)
  2514.         {
  2515.             //              unsigned offset = REG_SP_CONTENTS - regnum;
  2516.             //              if (offset < PC_STACK_DEPTH)
  2517.             //                  mips3.pc_stack[offset] = val;
  2518.         }
  2519.     }
  2520. }
  2521.  
  2522. /*###################################################################################################
  2523. **  DEBUGGER DEFINITIONS
  2524. **#################################################################################################*/
  2525.  
  2526. static UINT8 mips3_reg_layout[] =
  2527.     {
  2528.         MIPS3_PC, MIPS3_SR, -1,
  2529.         MIPS3_EPC, MIPS3_CAUSE, -1,
  2530.         MIPS3_COUNT, MIPS3_COMPARE, -1,
  2531.         MIPS3_HI, MIPS3_LO, -1,
  2532.         MIPS3_R0, MIPS3_R16, -1,
  2533.         MIPS3_R1, MIPS3_R17, -1,
  2534.         MIPS3_R2, MIPS3_R18, -1,
  2535.         MIPS3_R3, MIPS3_R19, -1,
  2536.         MIPS3_R4, MIPS3_R20, -1,
  2537.         MIPS3_R5, MIPS3_R21, -1,
  2538.         MIPS3_R6, MIPS3_R22, -1,
  2539.         MIPS3_R7, MIPS3_R23, -1,
  2540.         MIPS3_R8, MIPS3_R24, -1,
  2541.         MIPS3_R9, MIPS3_R25, -1,
  2542.         MIPS3_R10, MIPS3_R26, -1,
  2543.         MIPS3_R11, MIPS3_R27, -1,
  2544.         MIPS3_R12, MIPS3_R28, -1,
  2545.         MIPS3_R13, MIPS3_R29, -1,
  2546.         MIPS3_R14, MIPS3_R30, -1,
  2547.         MIPS3_R15, MIPS3_R31, 0};
  2548.  
  2549. static UINT8 mips3_win_layout[] =
  2550.     {
  2551.         0, 0, 45, 20,  /* register window (top rows) */
  2552.         46, 0, 33, 14, /* disassembler window (left colums) */
  2553.         0, 21, 45, 1,  /* memory #1 window (right, upper middle) */
  2554.         46, 15, 33, 7, /* memory #2 window (right, lower middle) */
  2555.         0, 23, 80, 1,  /* command line window (bottom rows) */
  2556. };
  2557.  
  2558. /*###################################################################################################
  2559. **  DEBUGGER STRINGS
  2560. **#################################################################################################*/
  2561.  
  2562. const char *mips3_info(void *context, int regnum)
  2563. {
  2564.     static char buffer[16][47 + 1];
  2565.     static int which = 0;
  2566.     mips3_regs *r = context;
  2567.  
  2568.     which = (which + 1) % 16;
  2569.     buffer[which][0] = '\0';
  2570.  
  2571.     if (!context)
  2572.         r = &mips3;
  2573.  
  2574.     switch (regnum)
  2575.     {
  2576.     case CPU_INFO_REG + MIPS3_PC:
  2577.         sprintf(buffer[which], "PC: %08X", r->pc);
  2578.         break;
  2579.     case CPU_INFO_REG + MIPS3_SR:
  2580.         sprintf(buffer[which], "SR: %08X", (UINT32)r->cpr[0][COP0_Status]);
  2581.         break;
  2582.     case CPU_INFO_REG + MIPS3_EPC:
  2583.         sprintf(buffer[which], "EPC:%08X", (UINT32)r->cpr[0][COP0_EPC]);
  2584.         break;
  2585.     case CPU_INFO_REG + MIPS3_CAUSE:
  2586.         sprintf(buffer[which], "Cause:%08X", (UINT32)r->cpr[0][COP0_Cause]);
  2587.         break;
  2588.     case CPU_INFO_REG + MIPS3_COUNT:
  2589.         sprintf(buffer[which], "Count:%08X", (UINT32)((activecpu_gettotalcycles64() - mips3.count_zero_time) / 2));
  2590.         break;
  2591.     case CPU_INFO_REG + MIPS3_COMPARE:
  2592.         sprintf(buffer[which], "Compare:%08X", (UINT32)r->cpr[0][COP0_Compare]);
  2593.         break;
  2594.  
  2595.     case CPU_INFO_REG + MIPS3_R0:
  2596.         sprintf(buffer[which], "R0: %08X%08X", (UINT32)(r->r[0] >> 32), (UINT32)r->r[0]);
  2597.         break;
  2598.     case CPU_INFO_REG + MIPS3_R1:
  2599.         sprintf(buffer[which], "R1: %08X%08X", (UINT32)(r->r[1] >> 32), (UINT32)r->r[1]);
  2600.         break;
  2601.     case CPU_INFO_REG + MIPS3_R2:
  2602.         sprintf(buffer[which], "R2: %08X%08X", (UINT32)(r->r[2] >> 32), (UINT32)r->r[2]);
  2603.         break;
  2604.     case CPU_INFO_REG + MIPS3_R3:
  2605.         sprintf(buffer[which], "R3: %08X%08X", (UINT32)(r->r[3] >> 32), (UINT32)r->r[3]);
  2606.         break;
  2607.     case CPU_INFO_REG + MIPS3_R4:
  2608.         sprintf(buffer[which], "R4: %08X%08X", (UINT32)(r->r[4] >> 32), (UINT32)r->r[4]);
  2609.         break;
  2610.     case CPU_INFO_REG + MIPS3_R5:
  2611.         sprintf(buffer[which], "R5: %08X%08X", (UINT32)(r->r[5] >> 32), (UINT32)r->r[5]);
  2612.         break;
  2613.     case CPU_INFO_REG + MIPS3_R6:
  2614.         sprintf(buffer[which], "R6: %08X%08X", (UINT32)(r->r[6] >> 32), (UINT32)r->r[6]);
  2615.         break;
  2616.     case CPU_INFO_REG + MIPS3_R7:
  2617.         sprintf(buffer[which], "R7: %08X%08X", (UINT32)(r->r[7] >> 32), (UINT32)r->r[7]);
  2618.         break;
  2619.     case CPU_INFO_REG + MIPS3_R8:
  2620.         sprintf(buffer[which], "R8: %08X%08X", (UINT32)(r->r[8] >> 32), (UINT32)r->r[8]);
  2621.         break;
  2622.     case CPU_INFO_REG + MIPS3_R9:
  2623.         sprintf(buffer[which], "R9: %08X%08X", (UINT32)(r->r[9] >> 32), (UINT32)r->r[9]);
  2624.         break;
  2625.     case CPU_INFO_REG + MIPS3_R10:
  2626.         sprintf(buffer[which], "R10:%08X%08X", (UINT32)(r->r[10] >> 32), (UINT32)r->r[10]);
  2627.         break;
  2628.     case CPU_INFO_REG + MIPS3_R11:
  2629.         sprintf(buffer[which], "R11:%08X%08X", (UINT32)(r->r[11] >> 32), (UINT32)r->r[11]);
  2630.         break;
  2631.     case CPU_INFO_REG + MIPS3_R12:
  2632.         sprintf(buffer[which], "R12:%08X%08X", (UINT32)(r->r[12] >> 32), (UINT32)r->r[12]);
  2633.         break;
  2634.     case CPU_INFO_REG + MIPS3_R13:
  2635.         sprintf(buffer[which], "R13:%08X%08X", (UINT32)(r->r[13] >> 32), (UINT32)r->r[13]);
  2636.         break;
  2637.     case CPU_INFO_REG + MIPS3_R14:
  2638.         sprintf(buffer[which], "R14:%08X%08X", (UINT32)(r->r[14] >> 32), (UINT32)r->r[14]);
  2639.         break;
  2640.     case CPU_INFO_REG + MIPS3_R15:
  2641.         sprintf(buffer[which], "R15:%08X%08X", (UINT32)(r->r[15] >> 32), (UINT32)r->r[15]);
  2642.         break;
  2643.     case CPU_INFO_REG + MIPS3_R16:
  2644.         sprintf(buffer[which], "R16:%08X%08X", (UINT32)(r->r[16] >> 32), (UINT32)r->r[16]);
  2645.         break;
  2646.     case CPU_INFO_REG + MIPS3_R17:
  2647.         sprintf(buffer[which], "R17:%08X%08X", (UINT32)(r->r[17] >> 32), (UINT32)r->r[17]);
  2648.         break;
  2649.     case CPU_INFO_REG + MIPS3_R18:
  2650.         sprintf(buffer[which], "R18:%08X%08X", (UINT32)(r->r[18] >> 32), (UINT32)r->r[18]);
  2651.         break;
  2652.     case CPU_INFO_REG + MIPS3_R19:
  2653.         sprintf(buffer[which], "R19:%08X%08X", (UINT32)(r->r[19] >> 32), (UINT32)r->r[19]);
  2654.         break;
  2655.     case CPU_INFO_REG + MIPS3_R20:
  2656.         sprintf(buffer[which], "R20:%08X%08X", (UINT32)(r->r[20] >> 32), (UINT32)r->r[20]);
  2657.         break;
  2658.     case CPU_INFO_REG + MIPS3_R21:
  2659.         sprintf(buffer[which], "R21:%08X%08X", (UINT32)(r->r[21] >> 32), (UINT32)r->r[21]);
  2660.         break;
  2661.     case CPU_INFO_REG + MIPS3_R22:
  2662.         sprintf(buffer[which], "R22:%08X%08X", (UINT32)(r->r[22] >> 32), (UINT32)r->r[22]);
  2663.         break;
  2664.     case CPU_INFO_REG + MIPS3_R23:
  2665.         sprintf(buffer[which], "R23:%08X%08X", (UINT32)(r->r[23] >> 32), (UINT32)r->r[23]);
  2666.         break;
  2667.     case CPU_INFO_REG + MIPS3_R24:
  2668.         sprintf(buffer[which], "R24:%08X%08X", (UINT32)(r->r[24] >> 32), (UINT32)r->r[24]);
  2669.         break;
  2670.     case CPU_INFO_REG + MIPS3_R25:
  2671.         sprintf(buffer[which], "R25:%08X%08X", (UINT32)(r->r[25] >> 32), (UINT32)r->r[25]);
  2672.         break;
  2673.     case CPU_INFO_REG + MIPS3_R26:
  2674.         sprintf(buffer[which], "R26:%08X%08X", (UINT32)(r->r[26] >> 32), (UINT32)r->r[26]);
  2675.         break;
  2676.     case CPU_INFO_REG + MIPS3_R27:
  2677.         sprintf(buffer[which], "R27:%08X%08X", (UINT32)(r->r[27] >> 32), (UINT32)r->r[27]);
  2678.         break;
  2679.     case CPU_INFO_REG + MIPS3_R28:
  2680.         sprintf(buffer[which], "R28:%08X%08X", (UINT32)(r->r[28] >> 32), (UINT32)r->r[28]);
  2681.         break;
  2682.     case CPU_INFO_REG + MIPS3_R29:
  2683.         sprintf(buffer[which], "R29:%08X%08X", (UINT32)(r->r[29] >> 32), (UINT32)r->r[29]);
  2684.         break;
  2685.     case CPU_INFO_REG + MIPS3_R30:
  2686.         sprintf(buffer[which], "R30:%08X%08X", (UINT32)(r->r[30] >> 32), (UINT32)r->r[30]);
  2687.         break;
  2688.     case CPU_INFO_REG + MIPS3_R31:
  2689.         sprintf(buffer[which], "R31:%08X%08X", (UINT32)(r->r[31] >> 32), (UINT32)r->r[31]);
  2690.         break;
  2691.     case CPU_INFO_REG + MIPS3_HI:
  2692.         sprintf(buffer[which], "HI: %08X%08X", (UINT32)(r->hi >> 32), (UINT32)r->hi);
  2693.         break;
  2694.     case CPU_INFO_REG + MIPS3_LO:
  2695.         sprintf(buffer[which], "LO: %08X%08X", (UINT32)(r->lo >> 32), (UINT32)r->lo);
  2696.         break;
  2697.  
  2698.     case CPU_INFO_NAME:
  2699.         return "MIPS III";
  2700.     case CPU_INFO_FAMILY:
  2701.         return r->bigendian ? "MIPS III (big-endian)" : "MIPS III (little-endian)";
  2702.     case CPU_INFO_VERSION:
  2703.         return "1.0";
  2704.     case CPU_INFO_FILE:
  2705.         return __FILE__;
  2706.     case CPU_INFO_CREDITS:
  2707.         return "Copyright (C) Aaron Giles 2000-2002";
  2708.     case CPU_INFO_REG_LAYOUT:
  2709.         return (const char *)mips3_reg_layout;
  2710.     case CPU_INFO_WIN_LAYOUT:
  2711.         return (const char *)mips3_win_layout;
  2712.     case CPU_INFO_REG + 10000:
  2713.         return "         ";
  2714.     }
  2715.     return buffer[which];
  2716. }
  2717.  
  2718. const char *r4600_info(void *context, int regnum)
  2719. {
  2720.     static char buffer[16][47 + 1];
  2721.     static int which = 0;
  2722.     mips3_regs *r = context;
  2723.  
  2724.     which = (which + 1) % 16;
  2725.     buffer[which][0] = '\0';
  2726.  
  2727.     if (!context)
  2728.         r = &mips3;
  2729.  
  2730.     switch (regnum)
  2731.     {
  2732.     case CPU_INFO_NAME:
  2733.         return "R4600";
  2734.     case CPU_INFO_FAMILY:
  2735.         return r->bigendian ? "MIPS R4600 (big-endian)" : "MIPS R4600 (little-endian)";
  2736.     default:
  2737.         return mips3_info(context, regnum);
  2738.     }
  2739.     return buffer[which];
  2740. }
  2741.  
  2742. const char *r5000_info(void *context, int regnum)
  2743. {
  2744.     static char buffer[16][47 + 1];
  2745.     static int which = 0;
  2746.     mips3_regs *r = context;
  2747.  
  2748.     which = (which + 1) % 16;
  2749.     buffer[which][0] = '\0';
  2750.  
  2751.     if (!context)
  2752.         r = &mips3;
  2753.  
  2754.     switch (regnum)
  2755.     {
  2756.     case CPU_INFO_NAME:
  2757.         return "R5000";
  2758.     case CPU_INFO_FAMILY:
  2759.         return r->bigendian ? "MIPS R5000 (big-endian)" : "MIPS R5000 (little-endian)";
  2760.     default:
  2761.         return mips3_info(context, regnum);
  2762.     }
  2763.     return buffer[which];
  2764. }
  2765.  
  2766. /*###################################################################################################
  2767. **  DISASSEMBLY HOOK
  2768. **#################################################################################################*/
  2769.  
  2770. unsigned mips3_dasm(char *buffer, unsigned pc)
  2771. {
  2772. #ifdef MAME_DEBUG
  2773.     extern unsigned dasmmips3(char *, unsigned);
  2774.     unsigned result;
  2775.     if (mips3.bigendian)
  2776.         change_pc32bedw(pc);
  2777.     else
  2778.         change_pc32ledw(pc);
  2779.     result = dasmmips3(buffer, pc);
  2780.     if (mips3.bigendian)
  2781.         change_pc32bedw(mips3.pc);
  2782.     else
  2783.         change_pc32ledw(mips3.pc);
  2784.     return result;
  2785. #else
  2786.     sprintf(buffer, "$%04X", ROPCODE(pc));
  2787.     return 4;
  2788. #endif
  2789. }
  2790.  
  2791. /*###################################################################################################
  2792. **  DOUBLEWORD READS/WRITES
  2793. **#################################################################################################*/
  2794.  
  2795. static UINT64 readmem32bedw_double(offs_t offset)
  2796. {
  2797.     UINT64 result = (UINT64)cpu_readmem32bedw_dword(offset) << 32;
  2798.     return result | cpu_readmem32bedw_dword(offset + 4);
  2799. }
  2800.  
  2801. static UINT64 readmem32ledw_double(offs_t offset)
  2802. {
  2803.     UINT64 result = cpu_readmem32ledw_dword(offset);
  2804.     return result | ((UINT64)cpu_readmem32ledw_dword(offset + 4) << 32);
  2805. }
  2806.  
  2807. static void writemem32bedw_double(offs_t offset, UINT64 data)
  2808. {
  2809.     cpu_writemem32bedw_dword(offset, data >> 32);
  2810.     cpu_writemem32bedw_dword(offset + 4, data);
  2811. }
  2812.  
  2813. static void writemem32ledw_double(offs_t offset, UINT64 data)
  2814. {
  2815.     cpu_writemem32ledw_dword(offset, data);
  2816.     cpu_writemem32ledw_dword(offset + 4, data >> 32);
  2817. }
  2818.  
  2819. /*###################################################################################################
  2820. **  COMPLEX OPCODE IMPLEMENTATIONS
  2821. **#################################################################################################*/
  2822.  
  2823. static void lwl_be(UINT32 op)
  2824. {
  2825.     offs_t offs = SIMMVAL + RSVAL32;
  2826.     data32_t temp = RLONG(offs & ~3);
  2827.     if (RTREG)
  2828.     {
  2829.         if (!(offs & 3))
  2830.             RTVAL64 = (INT32)temp;
  2831.         else
  2832.         {
  2833.             int shift = 8 * (offs & 3);
  2834.             RTVAL64 = (INT32)((RTVAL32 & (0x00ffffff >> (24 - shift))) | (temp << shift));
  2835.         }
  2836.     }
  2837. }
  2838.  
  2839. static void lwr_be(UINT32 op)
  2840. {
  2841.     offs_t offs = SIMMVAL + RSVAL32;
  2842.     data32_t temp = RLONG(offs & ~3);
  2843.     if (RTREG)
  2844.     {
  2845.         if ((offs & 3) == 3)
  2846.             RTVAL64 = (INT32)temp;
  2847.         else
  2848.         {
  2849.             int shift = 8 * (offs & 3);
  2850.             RTVAL64 = (INT32)((RTVAL32 & (0xffffff00 << shift)) | (temp >> (24 - shift)));
  2851.         }
  2852.     }
  2853. }
  2854.  
  2855. static void ldl_be(UINT32 op)
  2856. {
  2857.     offs_t offs = SIMMVAL + RSVAL32;
  2858.     UINT64 temp = RDOUBLE(offs & ~7);
  2859.     if (RTREG)
  2860.     {
  2861.         if (!(offs & 7))
  2862.             RTVAL64 = temp;
  2863.         else
  2864.         {
  2865.             UINT64 mask = ~((UINT64)0xff << 56);
  2866.             int shift = 8 * (offs & 7);
  2867.             RTVAL64 = (RTVAL64 & (mask >> (56 - shift))) | (temp << shift);
  2868.         }
  2869.     }
  2870. }
  2871.  
  2872. static void ldr_be(UINT32 op)
  2873. {
  2874.     offs_t offs = SIMMVAL + RSVAL32;
  2875.     UINT64 temp = RDOUBLE(offs & ~7);
  2876.     if (RTREG)
  2877.     {
  2878.         if ((offs & 7) == 7)
  2879.             RTVAL64 = temp;
  2880.         else
  2881.         {
  2882.             UINT64 mask = ~((UINT64)0xff);
  2883.             int shift = 8 * (offs & 7);
  2884.             RTVAL64 = (RTVAL64 & (mask << shift)) | (temp >> (56 - shift));
  2885.         }
  2886.     }
  2887. }
  2888.  
  2889. static void swl_be(UINT32 op)
  2890. {
  2891.     offs_t offs = SIMMVAL + RSVAL32;
  2892.     if (!(offs & 3))
  2893.         WLONG(offs, RTVAL32);
  2894.     else
  2895.     {
  2896.         data32_t temp = RLONG(offs & ~3);
  2897.         int shift = 8 * (offs & 3);
  2898. #if defined(__arm__) || defined(__aarch64__)
  2899.         WLONG(offs & ~3, (temp & (0xffffff00 << (24 - shift))) | (RTVAL32 >> shift));
  2900. #else
  2901.         WLONG(offs & ~3, (temp & (0xffffff << shift)) | (RTVAL32 >> shift));
  2902. #endif
  2903.     }
  2904. }
  2905.  
  2906. static void swr_be(UINT32 op)
  2907. {
  2908.     offs_t offs = SIMMVAL + RSVAL32;
  2909.     if ((offs & 3) == 3)
  2910.         WLONG(offs & ~3, RTVAL32);
  2911.     else
  2912.     {
  2913.         data32_t temp = RLONG(offs & ~3);
  2914.         int shift = 8 * (offs & 3);
  2915. #if defined(__arm__) || defined(__aarch64__)
  2916.         WLONG(offs & ~3, (temp & (0x00ffffff >> shift)) | (RTVAL32 << (24 - shift)));
  2917. #else
  2918.         WLONG(offs & ~3, (temp & (0xffffff00 >> shift)) | (RTVAL32 << (24 - shift)));
  2919. #endif
  2920.     }
  2921. }
  2922.  
  2923. static void sdl_be(UINT32 op)
  2924. {
  2925.     offs_t offs = SIMMVAL + RSVAL32;
  2926.     if (!(offs & 7))
  2927.         WDOUBLE(offs, RTVAL64);
  2928.     else
  2929.     {
  2930.         UINT64 temp = RDOUBLE(offs & ~7);
  2931.         UINT64 mask = ~((UINT64)0xff);
  2932.         int shift = 8 * (offs & 7);
  2933. #if defined(__arm__) || defined(__aarch64__)
  2934.         WDOUBLE(offs & ~7, (temp & (mask << (56 - shift))) | (RTVAL64 >> shift));
  2935. #else
  2936.         WDOUBLE(offs & ~7, (temp & (mask >> shift)) | (RTVAL64 << (shift)));
  2937. #endif
  2938.     }
  2939. }
  2940.  
  2941. static void sdr_be(UINT32 op)
  2942. {
  2943.     offs_t offs = SIMMVAL + RSVAL32;
  2944.     if ((offs & 7) == 7)
  2945.         WDOUBLE(offs & ~7, RTVAL64);
  2946.     else
  2947.     {
  2948.         UINT64 temp = RDOUBLE(offs & ~7);
  2949.         UINT64 mask = ~((UINT64)0xff << 56);
  2950.         int shift = 8 * (offs & 7);
  2951. #if defined(__arm__) || defined(__aarch64__)
  2952.         WDOUBLE(offs & ~7, (temp & (mask >> shift)) | (RTVAL64 << (56 - shift)));
  2953. #else
  2954.         WDOUBLE(offs & ~7, (temp & (mask << (56 - shift))) | (RTVAL64 >> (shift)));
  2955. #endif
  2956.     }
  2957. }
  2958.  
  2959. static void lwl_le(UINT32 op)
  2960. {
  2961.     offs_t offs = SIMMVAL + RSVAL32;
  2962.     data32_t temp = RLONG(offs & ~3);
  2963.     if (RTREG)
  2964.     {
  2965.         if ((offs & 3) == 3)
  2966.             RTVAL64 = (INT32)temp;
  2967.         else
  2968.         {
  2969.             int shift = 8 * (offs & 3);
  2970.             RTVAL64 = (INT32)((RTVAL32 & (0x00ffffffU >> shift)) | (temp << (24 - shift)));
  2971.         }
  2972.     }
  2973. }
  2974.  
  2975. static void lwr_le(UINT32 op)
  2976. {
  2977.     offs_t offs = SIMMVAL + RSVAL32;
  2978.     data32_t temp = RLONG(offs & ~3);
  2979.     if (RTREG)
  2980.     {
  2981.         if (!(offs & 3))
  2982.             RTVAL64 = (INT32)temp;
  2983.         else
  2984.         {
  2985.             int shift = 8 * (offs & 3);
  2986.             RTVAL64 = (INT32)((RTVAL32 & (0xffffff00U << (24 - shift))) | (temp >> shift));
  2987.         }
  2988.     }
  2989. }
  2990.  
  2991. static void ldl_le(UINT32 op)
  2992. {
  2993.     offs_t offs = SIMMVAL + RSVAL32;
  2994.     UINT64 temp = RDOUBLE(offs & ~7);
  2995.     if (RTREG)
  2996.     {
  2997.         if ((offs & 7) == 7)
  2998.             RTVAL64 = temp;
  2999.         else
  3000.         {
  3001.             UINT64 mask = ~((UINT64)0xffU << 56);
  3002.             int shift = 8 * (offs & 7);
  3003.             RTVAL64 = (RTVAL64 & (mask >> shift)) | (temp << (56 - shift));
  3004.         }
  3005.     }
  3006. }
  3007.  
  3008. static void ldr_le(UINT32 op)
  3009. {
  3010.     offs_t offs = SIMMVAL + RSVAL32;
  3011.     UINT64 temp = RDOUBLE(offs & ~7);
  3012.     if (RTREG)
  3013.     {
  3014.         if (!(offs & 7))
  3015.             RTVAL64 = temp;
  3016.         else
  3017.         {
  3018.             UINT64 mask = ~((UINT64)0xffU);
  3019.             int shift = 8 * (offs & 7);
  3020.             RTVAL64 = (RTVAL64 & (mask << (56 - shift))) | (temp >> shift);
  3021.         }
  3022.     }
  3023. }
  3024.  
  3025. static void swl_le(UINT32 op)
  3026. {
  3027.     offs_t offs = SIMMVAL + RSVAL32;
  3028.     if ((offs & 3) == 3)
  3029.         WLONG(offs & ~3, RTVAL32);
  3030.     else
  3031.     {
  3032.         data32_t temp = RLONG(offs & ~3);
  3033.         int shift = 8 * (offs & 3);
  3034.         WLONG(offs & ~3, (temp & (0xffffff00U << shift)) | (RTVAL32 >> (24 - shift)));
  3035.     }
  3036. }
  3037.  
  3038. static void swr_le(UINT32 op)
  3039. {
  3040.     offs_t offs = SIMMVAL + RSVAL32;
  3041.     if (!(offs & 3))
  3042.         WLONG(offs, RTVAL32);
  3043.     else
  3044.     {
  3045.         data32_t temp = RLONG(offs & ~3);
  3046.         int shift = 8 * (offs & 3);
  3047.         WLONG(offs & ~3, (temp & (0x00ffffffU >> (24 - shift))) | (RTVAL32 << shift));
  3048.     }
  3049. }
  3050.  
  3051. static void sdl_le(UINT32 op)
  3052. {
  3053.     offs_t offs = SIMMVAL + RSVAL32;
  3054.     if (!(offs & 7))
  3055.     {
  3056.         WDOUBLE(offs, RTVAL64);
  3057.         return;
  3058.     }
  3059.  
  3060.     UINT64 temp = RDOUBLE(offs & ~7);
  3061.     UINT64 mask = ~(UINT64)0xff;
  3062.     int shift = 8 * (offs & 7);
  3063.     WDOUBLE(offs & ~7, (temp & (mask << shift)) | (RTVAL64 >> (56 - shift)));
  3064. }
  3065.  
  3066. static void sdr_le(UINT32 op)
  3067. {
  3068.     offs_t offs = SIMMVAL + RSVAL32;
  3069.     if ((offs & 7) != 7)
  3070.     {
  3071.         UINT64 temp = RDOUBLE(offs & ~7);
  3072.         UINT64 mask = ~(UINT64)0xff << 56;
  3073.         int shift = 8 * (offs & 7);
  3074.         WDOUBLE(offs & ~7, (temp & (mask >> (56 - shift))) | (RTVAL64 << shift));
  3075.     }
  3076.     else
  3077.     {
  3078.         WDOUBLE(offs & ~7, RTVAL64);
  3079.     }
  3080. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement