1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 *   Mupen64plus - interpreter.def                                         *
3 *   Mupen64Plus homepage: http://code.google.com/p/mupen64plus/           *
4 *   Copyright (C) 2002 Hacktarux                                          *
5 *                                                                         *
6 *   This program is free software; you can redistribute it and/or modify  *
7 *   it under the terms of the GNU General Public License as published by  *
8 *   the Free Software Foundation; either version 2 of the License, or     *
9 *   (at your option) any later version.                                   *
10 *                                                                         *
11 *   This program is distributed in the hope that it will be useful,       *
12 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
13 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
14 *   GNU General Public License for more details.                          *
15 *                                                                         *
16 *   You should have received a copy of the GNU General Public License     *
17 *   along with this program; if not, write to the                         *
18 *   Free Software Foundation, Inc.,                                       *
19 *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.          *
20 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
21
22/* Before #including this file, <stdint.h> and <inttypes.h> must be included,
23 * and the following macros must be defined:
24 *
25 * PCADDR: Program counter (memory address of the current instruction).
26 *
27 * ADD_TO_PC(x): Increment the program counter in 'x' instructions.
28 * This is only used for small changes to PC, so the new program counter
29 * is guaranteed to fall in the current cached interpreter or dynarec block.
30 *
31 * DECLARE_INSTRUCTION(name)
32 * Declares an instruction function which is not a jump.
33 * Followed by a block of code.
34 *
35 * DECLARE_JUMP(name, destination, condition, link, likely, cop1)
36 * name is the name of the jump or branch instruction.
37 * destination is the destination memory address of the jump.
38 * If condition is nonzero, the jump is taken.
39 * link is a pointer to a variable where (PC+8) is written unconditionally.
40 *     To avoid linking, pass &reg[0]
41 * If likely is nonzero, the delay slot is only executed if the jump is taken.
42 * If cop1 is nonzero, a COP1 unusable check will be done.
43 *
44 * CHECK_MEMORY(): A snippet to be run after a store instruction,
45 *                 to check if the store affected executable blocks.
46 *                 The memory address of the store is in the 'address' global.
47 */
48
49#include "../main/device.h"
50#include "fpu.h"
51
52DECLARE_INSTRUCTION(NI)
53{
54   DebugMessage(M64MSG_ERROR, "NI() @ 0x%" PRIX32, PCADDR);
55   DebugMessage(M64MSG_ERROR, "opcode not implemented: %" PRIX32 ":%" PRIX32, PCADDR, *fast_mem_access(PCADDR));
56   stop=1;
57}
58
59DECLARE_INSTRUCTION(RESERVED)
60{
61   DebugMessage(M64MSG_ERROR, "reserved opcode: %" PRIX32 ":%" PRIX32, PCADDR, *fast_mem_access(PCADDR));
62   stop=1;
63}
64
65/* R4300 */
66DECLARE_JUMP(J,   (jinst_index<<2) | ((PCADDR+4) & UINT32_C(0xF0000000)), 1, &reg[0],  0, 0)
67DECLARE_JUMP(JAL, (jinst_index<<2) | ((PCADDR+4) & UINT32_C(0xF0000000)), 1, &reg[31], 0, 0)
68DECLARE_JUMP(BEQ,     PCADDR + (iimmediate+1)*4, irs == irt, &reg[0], 0, 0)
69DECLARE_JUMP(BNE,     PCADDR + (iimmediate+1)*4, irs != irt, &reg[0], 0, 0)
70DECLARE_JUMP(BLEZ,    PCADDR + (iimmediate+1)*4, irs <= 0,   &reg[0], 0, 0)
71DECLARE_JUMP(BGTZ,    PCADDR + (iimmediate+1)*4, irs > 0,    &reg[0], 0, 0)
72
73DECLARE_INSTRUCTION(ADDI)
74{
75   irt = SE32((uint32_t)irs32 + (uint32_t)iimmediate);
76   ADD_TO_PC(1);
77}
78
79DECLARE_INSTRUCTION(ADDIU)
80{
81   irt = SE32((uint32_t)irs32 + (uint32_t)iimmediate);
82   ADD_TO_PC(1);
83}
84
85DECLARE_INSTRUCTION(SLTI)
86{
87   if (irs < iimmediate) irt = 1;
88   else irt = 0;
89   ADD_TO_PC(1);
90}
91
92DECLARE_INSTRUCTION(SLTIU)
93{
94   if ((uint64_t) irs < (uint64_t) ((int64_t) iimmediate))
95     irt = 1;
96   else irt = 0;
97   ADD_TO_PC(1);
98}
99
100DECLARE_INSTRUCTION(ANDI)
101{
102   irt = irs & (uint16_t) iimmediate;
103   ADD_TO_PC(1);
104}
105
106DECLARE_INSTRUCTION(ORI)
107{
108   irt = irs | (uint16_t) iimmediate;
109   ADD_TO_PC(1);
110}
111
112DECLARE_INSTRUCTION(XORI)
113{
114   irt = irs ^ (uint16_t) iimmediate;
115   ADD_TO_PC(1);
116}
117
118DECLARE_INSTRUCTION(LUI)
119{
120   irt = SE32((uint32_t)iimmediate << 16);
121   ADD_TO_PC(1);
122}
123
124DECLARE_JUMP(BEQL,    PCADDR + (iimmediate+1)*4, irs == irt, &reg[0], 1, 0)
125DECLARE_JUMP(BNEL,    PCADDR + (iimmediate+1)*4, irs != irt, &reg[0], 1, 0)
126DECLARE_JUMP(BLEZL,   PCADDR + (iimmediate+1)*4, irs <= 0,   &reg[0], 1, 0)
127DECLARE_JUMP(BGTZL,   PCADDR + (iimmediate+1)*4, irs > 0,    &reg[0], 1, 0)
128
129DECLARE_INSTRUCTION(DADDI)
130{
131   irt = irs + iimmediate;
132   ADD_TO_PC(1);
133}
134
135DECLARE_INSTRUCTION(DADDIU)
136{
137   irt = irs + iimmediate;
138   ADD_TO_PC(1);
139}
140
141/* Assists unaligned memory accessors with making masks to preserve or apply
142 * bits in registers and memory.
143 *
144 * BITS_BELOW_MASK32 and BITS_BELOW_MASK64 make masks where bits 0 to (x - 1)
145 * are set.
146 *
147 * BITS_ABOVE_MASK32 makes masks where bits x to 31 are set.
148 * BITS_ABOVE_MASK64 makes masks where bits x to 63 are set.
149 *
150 * e.g. x = 8
151 * 0000 0000 0000 0000 0000 0000 1111 1111 <- BITS_BELOW_MASK32(8)
152 * 1111 1111 1111 1111 1111 1111 0000 0000 <- BITS_ABOVE_MASK32(8)
153 *
154 * Giving a negative value or one that is >= the bit count of the mask results
155 * in undefined behavior.
156 */
157
158#define BITS_BELOW_MASK32(x) ((UINT32_C(1) << (x)) - 1)
159#define BITS_ABOVE_MASK32(x) (~((UINT32_C(1) << (x)) - 1))
160
161#define BITS_BELOW_MASK64(x) ((UINT64_C(1) << (x)) - 1)
162#define BITS_ABOVE_MASK64(x) (~((UINT64_C(1) << (x)) - 1))
163
164DECLARE_INSTRUCTION(LDL)
165{
166   const uint32_t lsaddr = (uint32_t)irs32 + (uint32_t)iimmediate;
167   int64_t *lsrtp = &irt;
168   uint64_t word = 0;
169   ADD_TO_PC(1);
170   if ((lsaddr & 7) == 0)
171   {
172     address = lsaddr;
173     rdword = (uint64_t*) lsrtp;
174     read_dword_in_memory();
175   }
176   else
177   {
178     address = lsaddr & UINT32_C(0xFFFFFFF8);
179     rdword = &word;
180     read_dword_in_memory();
181     if (address)
182     {
183       /* How many low bits do we want to preserve from the old value? */
184       uint64_t old_mask = BITS_BELOW_MASK64((lsaddr & 7) * 8);
185       /* How many bits up do we want to add the low bits of the new value in? */
186       int new_shift = (lsaddr & 7) * 8;
187       *lsrtp = (*lsrtp & old_mask) | (word << new_shift);
188     }
189   }
190}
191
192DECLARE_INSTRUCTION(LDR)
193{
194   const uint32_t lsaddr = (uint32_t)irs32 + (uint32_t)iimmediate;
195   int64_t *lsrtp = &irt;
196   uint64_t word = 0;
197   ADD_TO_PC(1);
198   address = lsaddr & UINT32_C(0xFFFFFFF8);
199   if ((lsaddr & 7) == 7)
200   {
201     rdword = (uint64_t*) lsrtp;
202     read_dword_in_memory();
203   }
204   else
205   {
206     rdword = &word;
207     read_dword_in_memory();
208     if (address)
209     {
210       /* How many high bits do we want to preserve from the old value? */
211       uint64_t old_mask = BITS_ABOVE_MASK64(((lsaddr & 7) + 1) * 8);
212       /* How many bits down do we want to add the high bits of the new value in? */
213       int new_shift = (7 - (lsaddr & 7)) * 8;
214       *lsrtp = (*lsrtp & old_mask) | (word >> new_shift);
215     }
216   }
217}
218
219DECLARE_INSTRUCTION(LB)
220{
221   const uint32_t lsaddr = (uint32_t)irs32 + (uint32_t)iimmediate;
222   int64_t *lsrtp = &irt;
223   ADD_TO_PC(1);
224   address = lsaddr;
225   rdword = (uint64_t*) lsrtp;
226   read_byte_in_memory();
227   if (address)
228     *lsrtp = SE8(*lsrtp);
229}
230
231DECLARE_INSTRUCTION(LH)
232{
233   const uint32_t lsaddr = (uint32_t)irs32 + (uint32_t)iimmediate;
234   int64_t *lsrtp = &irt;
235   ADD_TO_PC(1);
236   address = lsaddr;
237   rdword = (uint64_t*) lsrtp;
238   read_hword_in_memory();
239   if (address)
240     *lsrtp = SE16(*lsrtp);
241}
242
243DECLARE_INSTRUCTION(LWL)
244{
245   const uint32_t lsaddr = (uint32_t)irs32 + (uint32_t)iimmediate;
246   int64_t *lsrtp = &irt;
247   uint64_t word = 0;
248   ADD_TO_PC(1);
249   if ((lsaddr & 3) == 0)
250   {
251     address = lsaddr;
252     rdword = (uint64_t*) lsrtp;
253     read_word_in_memory();
254     if (address)
255       *lsrtp = SE32(*lsrtp);
256   }
257   else
258   {
259     address = lsaddr & UINT32_C(0xFFFFFFFC);
260     rdword = &word;
261     read_word_in_memory();
262     if (address)
263     {
264       /* How many low bits do we want to preserve from the old value? */
265       uint32_t old_mask = BITS_BELOW_MASK32((lsaddr & 3) * 8);
266       /* How many bits up do we want to add the low bits of the new value in? */
267       int new_shift = (lsaddr & 3) * 8;
268       *lsrtp = SE32(((uint32_t) *lsrtp & old_mask) | ((uint32_t) word << new_shift));
269     }
270   }
271}
272
273DECLARE_INSTRUCTION(LW)
274{
275   const uint32_t lsaddr = (uint32_t)irs32 + (uint32_t)iimmediate;
276   int64_t *lsrtp = &irt;
277   ADD_TO_PC(1);
278   address = lsaddr;
279   rdword = (uint64_t*) lsrtp;
280   read_word_in_memory();
281   if (address)
282     *lsrtp = SE32(*lsrtp);
283}
284
285DECLARE_INSTRUCTION(LBU)
286{
287   const uint32_t lsaddr = (uint32_t)irs32 + (uint32_t)iimmediate;
288   int64_t *lsrtp = &irt;
289   ADD_TO_PC(1);
290   address = lsaddr;
291   rdword = (uint64_t*) lsrtp;
292   read_byte_in_memory();
293}
294
295DECLARE_INSTRUCTION(LHU)
296{
297   const uint32_t lsaddr = (uint32_t)irs32 + (uint32_t)iimmediate;
298   int64_t *lsrtp = &irt;
299   ADD_TO_PC(1);
300   address = lsaddr;
301   rdword = (uint64_t*) lsrtp;
302   read_hword_in_memory();
303}
304
305DECLARE_INSTRUCTION(LWR)
306{
307   const uint32_t lsaddr = (uint32_t)irs32 + (uint32_t)iimmediate;
308   int64_t *lsrtp = &irt;
309   uint64_t word = 0;
310   ADD_TO_PC(1);
311   address = lsaddr & UINT32_C(0xFFFFFFFC);
312   if ((lsaddr & 3) == 3)
313   {
314     rdword = (uint64_t*) lsrtp;
315     read_word_in_memory();
316     if (address)
317       *lsrtp = SE32(*lsrtp);
318   }
319   else
320   {
321     rdword = &word;
322     read_word_in_memory();
323     if (address)
324     {
325       /* How many high bits do we want to preserve from the old value? */
326       uint32_t old_mask = BITS_ABOVE_MASK32(((lsaddr & 3) + 1) * 8);
327       /* How many bits down do we want to add the new value in? */
328       int new_shift = (3 - (lsaddr & 3)) * 8;
329       *lsrtp = SE32(((uint32_t) *lsrtp & old_mask) | ((uint32_t) word >> new_shift));
330     }
331   }
332}
333
334DECLARE_INSTRUCTION(LWU)
335{
336   const uint32_t lsaddr = (uint32_t)irs32 + (uint32_t)iimmediate;
337   int64_t *lsrtp = &irt;
338   ADD_TO_PC(1);
339   address = lsaddr;
340   rdword = (uint64_t*) lsrtp;
341   read_word_in_memory();
342}
343
344DECLARE_INSTRUCTION(SB)
345{
346   const uint32_t lsaddr = (uint32_t)irs32 + (uint32_t)iimmediate;
347   int64_t *lsrtp = &irt;
348   ADD_TO_PC(1);
349   address = lsaddr;
350   cpu_byte = (uint8_t) *lsrtp;
351   write_byte_in_memory();
352   CHECK_MEMORY();
353}
354
355DECLARE_INSTRUCTION(SH)
356{
357   const uint32_t lsaddr = (uint32_t)irs32 + (uint32_t)iimmediate;
358   int64_t *lsrtp = &irt;
359   ADD_TO_PC(1);
360   address = lsaddr;
361   cpu_hword = (uint16_t) *lsrtp;
362   write_hword_in_memory();
363   CHECK_MEMORY();
364}
365
366DECLARE_INSTRUCTION(SWL)
367{
368   const uint32_t lsaddr = (uint32_t)irs32 + (uint32_t)iimmediate;
369   int64_t *lsrtp = &irt;
370   uint64_t old_word = 0;
371   ADD_TO_PC(1);
372   if ((lsaddr & 3) == 0)
373   {
374     address = lsaddr;
375     cpu_word = (uint32_t) *lsrtp;
376     write_word_in_memory();
377     CHECK_MEMORY();
378   }
379   else
380   {
381     address = lsaddr & UINT32_C(0xFFFFFFFC);
382     rdword = &old_word;
383     read_word_in_memory();
384     if (address)
385     {
386       /* How many high bits do we want to preserve from what was in memory
387        * before? */
388       uint32_t old_mask = BITS_ABOVE_MASK32((4 - (lsaddr & 3)) * 8);
389       /* How many bits down do we need to shift the register to store some
390        * of its high bits into the low bits of the memory word? */
391       int new_shift = (lsaddr & 3) * 8;
392       cpu_word = ((uint32_t) old_word & old_mask) | ((uint32_t) *lsrtp >> new_shift);
393       write_word_in_memory();
394       CHECK_MEMORY();
395     }
396   }
397}
398
399DECLARE_INSTRUCTION(SW)
400{
401   const uint32_t lsaddr = (uint32_t)irs32 + (uint32_t)iimmediate;
402   int64_t *lsrtp = &irt;
403   ADD_TO_PC(1);
404   address = lsaddr;
405   cpu_word = (uint32_t) *lsrtp;
406   write_word_in_memory();
407   CHECK_MEMORY();
408}
409
410DECLARE_INSTRUCTION(SDL)
411{
412   const uint32_t lsaddr = (uint32_t)irs32 + (uint32_t)iimmediate;
413   int64_t *lsrtp = &irt;
414   uint64_t old_word = 0;
415   ADD_TO_PC(1);
416   if ((lsaddr & 7) == 0)
417   {
418     address = lsaddr;
419     cpu_dword = *lsrtp;
420     write_dword_in_memory();
421     CHECK_MEMORY();
422   }
423   else
424   {
425     address = lsaddr & UINT32_C(0xFFFFFFF8);
426     rdword = &old_word;
427     read_dword_in_memory();
428     if (address)
429     {
430       /* How many high bits do we want to preserve from what was in memory
431        * before? */
432       uint64_t old_mask = BITS_ABOVE_MASK64((8 - (lsaddr & 7)) * 8);
433       /* How many bits down do we need to shift the register to store some
434        * of its high bits into the low bits of the memory word? */
435       int new_shift = (lsaddr & 7) * 8;
436       cpu_dword = (old_word & old_mask) | ((uint64_t) *lsrtp >> new_shift);
437       write_dword_in_memory();
438       CHECK_MEMORY();
439     }
440   }
441}
442
443DECLARE_INSTRUCTION(SDR)
444{
445   const uint32_t lsaddr = (uint32_t)irs32 + (uint32_t)iimmediate;
446   int64_t *lsrtp = &irt;
447   uint64_t old_word = 0;
448   ADD_TO_PC(1);
449   address = lsaddr & UINT32_C(0xFFFFFFF8);
450   if ((lsaddr & 7) == 7)
451   {
452     cpu_dword = *lsrtp;
453     write_dword_in_memory();
454     CHECK_MEMORY();
455   }
456   else
457   {
458     rdword = &old_word;
459     read_dword_in_memory();
460     if (address)
461     {
462       /* How many low bits do we want to preserve from what was in memory
463        * before? */
464       uint64_t old_mask = BITS_BELOW_MASK64((7 - (lsaddr & 7)) * 8);
465       /* How many bits up do we need to shift the register to store some
466        * of its low bits into the high bits of the memory word? */
467       int new_shift = (7 - (lsaddr & 7)) * 8;
468       cpu_dword = (old_word & old_mask) | (*lsrtp << new_shift);
469       write_dword_in_memory();
470       CHECK_MEMORY();
471     }
472   }
473}
474
475DECLARE_INSTRUCTION(SWR)
476{
477   const uint32_t lsaddr = (uint32_t)irs32 + (uint32_t)iimmediate;
478   int64_t *lsrtp = &irt;
479   uint64_t old_word = 0;
480   ADD_TO_PC(1);
481   address = lsaddr & UINT32_C(0xFFFFFFFC);
482   if ((lsaddr & 3) == 3)
483   {
484     cpu_word = (uint32_t) *lsrtp;
485     write_word_in_memory();
486     CHECK_MEMORY();
487   }
488   else
489   {
490     rdword = &old_word;
491     read_word_in_memory();
492     if (address)
493     {
494       /* How many low bits do we want to preserve from what was in memory
495        * before? */
496       int32_t old_mask = BITS_BELOW_MASK32((3 - (lsaddr & 3)) * 8);
497       /* How many bits up do we need to shift the register to store some
498        * of its low bits into the high bits of the memory word? */
499       int new_shift = (3 - (lsaddr & 3)) * 8;
500       cpu_word = ((uint32_t) old_word & old_mask) | ((uint32_t) *lsrtp << new_shift);
501       write_word_in_memory();
502       CHECK_MEMORY();
503     }
504   }
505}
506
507DECLARE_INSTRUCTION(CACHE)
508{
509   ADD_TO_PC(1);
510}
511
512DECLARE_INSTRUCTION(LL)
513{
514   const uint32_t lsaddr = (uint32_t)irs32 + (uint32_t)iimmediate;
515   int64_t *lsrtp = &irt;
516   ADD_TO_PC(1);
517   address = lsaddr;
518   rdword = (uint64_t*) lsrtp;
519   read_word_in_memory();
520   if (address)
521     {
522    *lsrtp = SE32(*lsrtp);
523    llbit = 1;
524     }
525}
526
527DECLARE_INSTRUCTION(LWC1)
528{
529   const unsigned char lslfft = lfft;
530   const uint32_t lslfaddr = (uint32_t) reg[lfbase] + lfoffset;
531   uint64_t temp;
532   if (check_cop1_unusable()) return;
533   ADD_TO_PC(1);
534   address = lslfaddr;
535   rdword = &temp;
536   read_word_in_memory();
537   if (address)
538     *((uint32_t*) reg_cop1_simple[lslfft]) = (uint32_t) *rdword;
539}
540
541DECLARE_INSTRUCTION(LDC1)
542{
543   const unsigned char lslfft = lfft;
544   const uint32_t lslfaddr = (uint32_t) reg[lfbase] + lfoffset;
545   if (check_cop1_unusable()) return;
546   ADD_TO_PC(1);
547   address = lslfaddr;
548   rdword = (uint64_t*) reg_cop1_double[lslfft];
549   read_dword_in_memory();
550}
551
552DECLARE_INSTRUCTION(LD)
553{
554   const uint32_t lsaddr = (uint32_t)irs32 + (uint32_t)iimmediate;
555   int64_t *lsrtp = &irt;
556   ADD_TO_PC(1);
557   address = lsaddr;
558   rdword = (uint64_t*) lsrtp;
559   read_dword_in_memory();
560}
561
562DECLARE_INSTRUCTION(SC)
563{
564   const uint32_t lsaddr = (uint32_t)irs32 + (uint32_t)iimmediate;
565   int64_t *lsrtp = &irt;
566   ADD_TO_PC(1);
567   if(llbit)
568   {
569      address = lsaddr;
570      cpu_word = (uint32_t) *lsrtp;
571      write_word_in_memory();
572      CHECK_MEMORY();
573      llbit = 0;
574      *lsrtp = 1;
575   }
576   else
577   {
578      *lsrtp = 0;
579   }
580}
581
582DECLARE_INSTRUCTION(SWC1)
583{
584   const unsigned char lslfft = lfft;
585   const uint32_t lslfaddr = (uint32_t) reg[lfbase] + lfoffset;
586   if (check_cop1_unusable()) return;
587   ADD_TO_PC(1);
588   address = lslfaddr;
589   cpu_word = *((uint32_t*) reg_cop1_simple[lslfft]);
590   write_word_in_memory();
591   CHECK_MEMORY();
592}
593
594DECLARE_INSTRUCTION(SDC1)
595{
596   const unsigned char lslfft = lfft;
597   const uint32_t lslfaddr = (uint32_t) reg[lfbase] + lfoffset;
598   if (check_cop1_unusable()) return;
599   ADD_TO_PC(1);
600   address = lslfaddr;
601   cpu_dword = *((uint64_t*) reg_cop1_double[lslfft]);
602   write_dword_in_memory();
603   CHECK_MEMORY();
604}
605
606DECLARE_INSTRUCTION(SD)
607{
608   const uint32_t lsaddr = (uint32_t)irs32 + (uint32_t)iimmediate;
609   int64_t *lsrtp = &irt;
610   ADD_TO_PC(1);
611   address = lsaddr;
612   cpu_dword = *lsrtp;
613   write_dword_in_memory();
614   CHECK_MEMORY();
615}
616
617/* COP0 */
618DECLARE_INSTRUCTION(MFC0)
619{
620   switch(rfs)
621   {
622      case CP0_RANDOM_REG:
623         cp0_update_count();
624         g_cp0_regs[CP0_RANDOM_REG] = (g_cp0_regs[CP0_COUNT_REG]/2 % (32 - g_cp0_regs[CP0_WIRED_REG]))
625            + g_cp0_regs[CP0_WIRED_REG];
626         break;
627      case CP0_COUNT_REG:
628         cp0_update_count();
629         break;
630   }
631
632   rrt = SE32(g_cp0_regs[rfs]);
633   ADD_TO_PC(1);
634}
635
636DECLARE_INSTRUCTION(MTC0)
637{
638  switch(rfs)
639  {
640    case CP0_INDEX_REG:
641      g_cp0_regs[CP0_INDEX_REG] = rrt32 & UINT32_C(0x8000003F);
642      if ((g_cp0_regs[CP0_INDEX_REG] & UINT32_C(0x3F)) > UINT32_C(31))
643      {
644        DebugMessage(M64MSG_ERROR, "MTC0 instruction writing Index register with TLB index > 31");
645        stop=1;
646      }
647      break;
648    case CP0_RANDOM_REG:
649      break;
650    case CP0_ENTRYLO0_REG:
651      g_cp0_regs[CP0_ENTRYLO0_REG] = rrt32 & UINT32_C(0x3FFFFFFF);
652      break;
653    case CP0_ENTRYLO1_REG:
654      g_cp0_regs[CP0_ENTRYLO1_REG] = rrt32 & UINT32_C(0x3FFFFFFF);
655      break;
656    case CP0_CONTEXT_REG:
657      g_cp0_regs[CP0_CONTEXT_REG] = (rrt32 & UINT32_C(0xFF800000))
658                                  | (g_cp0_regs[CP0_CONTEXT_REG] & UINT32_C(0x007FFFF0));
659      break;
660    case CP0_PAGEMASK_REG:
661      g_cp0_regs[CP0_PAGEMASK_REG] = rrt32 & UINT32_C(0x01FFE000);
662      break;
663    case CP0_WIRED_REG:
664      g_cp0_regs[CP0_WIRED_REG] = rrt32;
665      g_cp0_regs[CP0_RANDOM_REG] = UINT32_C(31);
666      break;
667    case CP0_BADVADDR_REG:
668      break;
669    case CP0_COUNT_REG:
670      cp0_update_count();
671      interrupt_unsafe_state = 1;
672      if (next_interrupt <= g_cp0_regs[CP0_COUNT_REG]) gen_interrupt();
673      interrupt_unsafe_state = 0;
674      translate_event_queue(rrt32);
675      g_cp0_regs[CP0_COUNT_REG] = rrt32;
676      break;
677    case CP0_ENTRYHI_REG:
678      g_cp0_regs[CP0_ENTRYHI_REG] = rrt32 & UINT32_C(0xFFFFE0FF);
679      break;
680    case CP0_COMPARE_REG:
681      cp0_update_count();
682      remove_event(COMPARE_INT);
683      add_interrupt_event_count(COMPARE_INT, rrt32);
684      g_cp0_regs[CP0_COMPARE_REG] = rrt32;
685      g_cp0_regs[CP0_CAUSE_REG] &= ~CP0_CAUSE_IP7;
686      break;
687    case CP0_STATUS_REG:
688      if((rrt32 & CP0_STATUS_FR) != (g_cp0_regs[CP0_STATUS_REG] & CP0_STATUS_FR))
689      {
690          shuffle_fpr_data(g_cp0_regs[CP0_STATUS_REG], rrt32);
691          set_fpr_pointers(rrt32);
692      }
693      g_cp0_regs[CP0_STATUS_REG] = rrt32;
694      cp0_update_count();
695      ADD_TO_PC(1);
696      check_interrupt();
697      interrupt_unsafe_state = 1;
698      if (next_interrupt <= g_cp0_regs[CP0_COUNT_REG]) gen_interrupt();
699      interrupt_unsafe_state = 0;
700      ADD_TO_PC(-1);
701      break;
702    case CP0_CAUSE_REG:
703      if (rrt32!=0)
704      {
705         DebugMessage(M64MSG_ERROR, "MTC0 instruction trying to write Cause register with non-0 value");
706         stop = 1;
707      }
708      else g_cp0_regs[CP0_CAUSE_REG] = rrt32;
709      break;
710    case CP0_EPC_REG:
711      g_cp0_regs[CP0_EPC_REG] = rrt32;
712      break;
713    case CP0_PREVID_REG:
714      break;
715    case CP0_CONFIG_REG:
716      g_cp0_regs[CP0_CONFIG_REG] = rrt32;
717      break;
718    case CP0_WATCHLO_REG:
719      g_cp0_regs[CP0_WATCHLO_REG] = rrt32;
720      break;
721    case CP0_WATCHHI_REG:
722      g_cp0_regs[CP0_WATCHHI_REG] = rrt32;
723      break;
724    case CP0_TAGLO_REG:
725      g_cp0_regs[CP0_TAGLO_REG] = rrt32 & UINT32_C(0x0FFFFFC0);
726      break;
727    case CP0_TAGHI_REG:
728      g_cp0_regs[CP0_TAGHI_REG] = 0;
729      break;
730    case CP0_ERROREPC_REG:
731      g_cp0_regs[CP0_ERROREPC_REG] = rrt32;
732      break;
733    default:
734      DebugMessage(M64MSG_ERROR, "Unknown MTC0 write: %d", rfs);
735      stop=1;
736  }
737  ADD_TO_PC(1);
738}
739
740/* COP1 */
741DECLARE_JUMP(BC1F,  PCADDR + (iimmediate+1)*4, (FCR31 & FCR31_CMP_BIT)==0, &reg[0], 0, 1)
742DECLARE_JUMP(BC1T,  PCADDR + (iimmediate+1)*4, (FCR31 & FCR31_CMP_BIT)!=0, &reg[0], 0, 1)
743DECLARE_JUMP(BC1FL, PCADDR + (iimmediate+1)*4, (FCR31 & FCR31_CMP_BIT)==0, &reg[0], 1, 1)
744DECLARE_JUMP(BC1TL, PCADDR + (iimmediate+1)*4, (FCR31 & FCR31_CMP_BIT)!=0, &reg[0], 1, 1)
745
746DECLARE_INSTRUCTION(MFC1)
747{
748   if (check_cop1_unusable()) return;
749   rrt = SE32(*((int32_t*) reg_cop1_simple[rfs]));
750   ADD_TO_PC(1);
751}
752
753DECLARE_INSTRUCTION(DMFC1)
754{
755   if (check_cop1_unusable()) return;
756   rrt = *((int64_t*) reg_cop1_double[rfs]);
757   ADD_TO_PC(1);
758}
759
760DECLARE_INSTRUCTION(CFC1)
761{
762   if (check_cop1_unusable()) return;
763   if (rfs==31)
764   {
765      rrt32 = SE32(FCR31);
766   }
767   if (rfs==0)
768   {
769      rrt32 = SE32(FCR0);
770   }
771   ADD_TO_PC(1);
772}
773
774DECLARE_INSTRUCTION(MTC1)
775{
776   if (check_cop1_unusable()) return;
777   *((int32_t*) reg_cop1_simple[rfs]) = rrt32;
778   ADD_TO_PC(1);
779}
780
781DECLARE_INSTRUCTION(DMTC1)
782{
783   if (check_cop1_unusable()) return;
784   *((int64_t*) reg_cop1_double[rfs]) = rrt;
785   ADD_TO_PC(1);
786}
787
788DECLARE_INSTRUCTION(CTC1)
789{
790   if (check_cop1_unusable()) return;
791   if (rfs==31)
792   {
793      FCR31 = rrt32;
794      update_x86_rounding_mode(rrt32);
795   }
796   //if ((FCR31 >> 7) & 0x1F) printf("FPU Exception enabled : %x\n",
797   //                 (int)((FCR31 >> 7) & 0x1F));
798   ADD_TO_PC(1);
799}
800
801// COP1_D
802DECLARE_INSTRUCTION(ADD_D)
803{
804   if (check_cop1_unusable()) return;
805   add_d(reg_cop1_double[cffs], reg_cop1_double[cfft], reg_cop1_double[cffd]);
806   ADD_TO_PC(1);
807}
808
809DECLARE_INSTRUCTION(SUB_D)
810{
811   if (check_cop1_unusable()) return;
812   sub_d(reg_cop1_double[cffs], reg_cop1_double[cfft], reg_cop1_double[cffd]);
813   ADD_TO_PC(1);
814}
815
816DECLARE_INSTRUCTION(MUL_D)
817{
818   if (check_cop1_unusable()) return;
819   mul_d(reg_cop1_double[cffs], reg_cop1_double[cfft], reg_cop1_double[cffd]);
820   ADD_TO_PC(1);
821}
822
823DECLARE_INSTRUCTION(DIV_D)
824{
825   if (check_cop1_unusable()) return;
826   if((FCR31 & UINT32_C(0x400)) && *reg_cop1_double[cfft] == 0)
827   {
828      //FCR31 |= 0x8020;
829      /*FCR31 |= 0x8000;
830      Cause = 15 << 2;
831      exception_general();*/
832      DebugMessage(M64MSG_ERROR, "DIV_D by 0");
833      //return;
834   }
835   div_d(reg_cop1_double[cffs], reg_cop1_double[cfft], reg_cop1_double[cffd]);
836   ADD_TO_PC(1);
837}
838
839DECLARE_INSTRUCTION(SQRT_D)
840{
841   if (check_cop1_unusable()) return;
842   sqrt_d(reg_cop1_double[cffs], reg_cop1_double[cffd]);
843   ADD_TO_PC(1);
844}
845
846DECLARE_INSTRUCTION(ABS_D)
847{
848   if (check_cop1_unusable()) return;
849   abs_d(reg_cop1_double[cffs], reg_cop1_double[cffd]);
850   ADD_TO_PC(1);
851}
852
853DECLARE_INSTRUCTION(MOV_D)
854{
855   if (check_cop1_unusable()) return;
856   mov_d(reg_cop1_double[cffs], reg_cop1_double[cffd]);
857   ADD_TO_PC(1);
858}
859
860DECLARE_INSTRUCTION(NEG_D)
861{
862   if (check_cop1_unusable()) return;
863   neg_d(reg_cop1_double[cffs], reg_cop1_double[cffd]);
864   ADD_TO_PC(1);
865}
866
867DECLARE_INSTRUCTION(ROUND_L_D)
868{
869   if (check_cop1_unusable()) return;
870   round_l_d(reg_cop1_double[cffs], (int64_t*) reg_cop1_double[cffd]);
871   ADD_TO_PC(1);
872}
873
874DECLARE_INSTRUCTION(TRUNC_L_D)
875{
876   if (check_cop1_unusable()) return;
877   trunc_l_d(reg_cop1_double[cffs], (int64_t*) reg_cop1_double[cffd]);
878   ADD_TO_PC(1);
879}
880
881DECLARE_INSTRUCTION(CEIL_L_D)
882{
883   if (check_cop1_unusable()) return;
884   ceil_l_d(reg_cop1_double[cffs], (int64_t*) reg_cop1_double[cffd]);
885   ADD_TO_PC(1);
886}
887
888DECLARE_INSTRUCTION(FLOOR_L_D)
889{
890   if (check_cop1_unusable()) return;
891   floor_l_d(reg_cop1_double[cffs], (int64_t*) reg_cop1_double[cffd]);
892   ADD_TO_PC(1);
893}
894
895DECLARE_INSTRUCTION(ROUND_W_D)
896{
897   if (check_cop1_unusable()) return;
898   round_w_d(reg_cop1_double[cffs], (int32_t*) reg_cop1_simple[cffd]);
899   ADD_TO_PC(1);
900}
901
902DECLARE_INSTRUCTION(TRUNC_W_D)
903{
904   if (check_cop1_unusable()) return;
905   trunc_w_d(reg_cop1_double[cffs], (int32_t*) reg_cop1_simple[cffd]);
906   ADD_TO_PC(1);
907}
908
909DECLARE_INSTRUCTION(CEIL_W_D)
910{
911   if (check_cop1_unusable()) return;
912   ceil_w_d(reg_cop1_double[cffs], (int32_t*) reg_cop1_simple[cffd]);
913   ADD_TO_PC(1);
914}
915
916DECLARE_INSTRUCTION(FLOOR_W_D)
917{
918   if (check_cop1_unusable()) return;
919   floor_w_d(reg_cop1_double[cffs], (int32_t*) reg_cop1_simple[cffd]);
920   ADD_TO_PC(1);
921}
922
923DECLARE_INSTRUCTION(CVT_S_D)
924{
925   if (check_cop1_unusable()) return;
926   cvt_s_d(reg_cop1_double[cffs], reg_cop1_simple[cffd]);
927   ADD_TO_PC(1);
928}
929
930DECLARE_INSTRUCTION(CVT_W_D)
931{
932   if (check_cop1_unusable()) return;
933   cvt_w_d(reg_cop1_double[cffs], (int32_t*) reg_cop1_simple[cffd]);
934   ADD_TO_PC(1);
935}
936
937DECLARE_INSTRUCTION(CVT_L_D)
938{
939   if (check_cop1_unusable()) return;
940   cvt_l_d(reg_cop1_double[cffs], (int64_t*) reg_cop1_double[cffd]);
941   ADD_TO_PC(1);
942}
943
944DECLARE_INSTRUCTION(C_F_D)
945{
946   if (check_cop1_unusable()) return;
947   c_f_d();
948   ADD_TO_PC(1);
949}
950
951DECLARE_INSTRUCTION(C_UN_D)
952{
953   if (check_cop1_unusable()) return;
954   c_un_d(reg_cop1_double[cffs], reg_cop1_double[cfft]);
955   ADD_TO_PC(1);
956}
957
958DECLARE_INSTRUCTION(C_EQ_D)
959{
960   if (check_cop1_unusable()) return;
961   c_eq_d(reg_cop1_double[cffs], reg_cop1_double[cfft]);
962   ADD_TO_PC(1);
963}
964
965DECLARE_INSTRUCTION(C_UEQ_D)
966{
967   if (check_cop1_unusable()) return;
968   c_ueq_d(reg_cop1_double[cffs], reg_cop1_double[cfft]);
969   ADD_TO_PC(1);
970}
971
972DECLARE_INSTRUCTION(C_OLT_D)
973{
974   if (check_cop1_unusable()) return;
975   c_olt_d(reg_cop1_double[cffs], reg_cop1_double[cfft]);
976   ADD_TO_PC(1);
977}
978
979DECLARE_INSTRUCTION(C_ULT_D)
980{
981   if (check_cop1_unusable()) return;
982   c_ult_d(reg_cop1_double[cffs], reg_cop1_double[cfft]);
983   ADD_TO_PC(1);
984}
985
986DECLARE_INSTRUCTION(C_OLE_D)
987{
988   if (check_cop1_unusable()) return;
989   c_ole_d(reg_cop1_double[cffs], reg_cop1_double[cfft]);
990   ADD_TO_PC(1);
991}
992
993DECLARE_INSTRUCTION(C_ULE_D)
994{
995   if (check_cop1_unusable()) return;
996   c_ule_d(reg_cop1_double[cffs], reg_cop1_double[cfft]);
997   ADD_TO_PC(1);
998}
999
1000DECLARE_INSTRUCTION(C_SF_D)
1001{
1002   if (isnan(*reg_cop1_double[cffs]) || isnan(*reg_cop1_double[cfft]))
1003   {
1004     DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode");
1005     stop=1;
1006   }
1007   c_sf_d(reg_cop1_double[cffs], reg_cop1_double[cfft]);
1008   ADD_TO_PC(1);
1009}
1010
1011DECLARE_INSTRUCTION(C_NGLE_D)
1012{
1013   if (isnan(*reg_cop1_double[cffs]) || isnan(*reg_cop1_double[cfft]))
1014   {
1015     DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode");
1016     stop=1;
1017   }
1018   c_ngle_d(reg_cop1_double[cffs], reg_cop1_double[cfft]);
1019   ADD_TO_PC(1);
1020}
1021
1022DECLARE_INSTRUCTION(C_SEQ_D)
1023{
1024   if (isnan(*reg_cop1_double[cffs]) || isnan(*reg_cop1_double[cfft]))
1025   {
1026     DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode");
1027     stop=1;
1028   }
1029   c_seq_d(reg_cop1_double[cffs], reg_cop1_double[cfft]);
1030   ADD_TO_PC(1);
1031}
1032
1033DECLARE_INSTRUCTION(C_NGL_D)
1034{
1035   if (isnan(*reg_cop1_double[cffs]) || isnan(*reg_cop1_double[cfft]))
1036   {
1037     DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode");
1038     stop=1;
1039   }
1040   c_ngl_d(reg_cop1_double[cffs], reg_cop1_double[cfft]);
1041   ADD_TO_PC(1);
1042}
1043
1044DECLARE_INSTRUCTION(C_LT_D)
1045{
1046   if (check_cop1_unusable()) return;
1047   if (isnan(*reg_cop1_double[cffs]) || isnan(*reg_cop1_double[cfft]))
1048   {
1049     DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode");
1050     stop=1;
1051   }
1052   c_lt_d(reg_cop1_double[cffs], reg_cop1_double[cfft]);
1053   ADD_TO_PC(1);
1054}
1055
1056DECLARE_INSTRUCTION(C_NGE_D)
1057{
1058   if (check_cop1_unusable()) return;
1059   if (isnan(*reg_cop1_double[cffs]) || isnan(*reg_cop1_double[cfft]))
1060   {
1061     DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode");
1062     stop=1;
1063   }
1064   c_nge_d(reg_cop1_double[cffs], reg_cop1_double[cfft]);
1065   ADD_TO_PC(1);
1066}
1067
1068DECLARE_INSTRUCTION(C_LE_D)
1069{
1070   if (check_cop1_unusable()) return;
1071   if (isnan(*reg_cop1_double[cffs]) || isnan(*reg_cop1_double[cfft]))
1072   {
1073     DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode");
1074     stop=1;
1075   }
1076   c_le_d(reg_cop1_double[cffs], reg_cop1_double[cfft]);
1077   ADD_TO_PC(1);
1078}
1079
1080DECLARE_INSTRUCTION(C_NGT_D)
1081{
1082   if (check_cop1_unusable()) return;
1083   if (isnan(*reg_cop1_double[cffs]) || isnan(*reg_cop1_double[cfft]))
1084   {
1085     DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode");
1086     stop=1;
1087   }
1088   c_ngt_d(reg_cop1_double[cffs], reg_cop1_double[cfft]);
1089   ADD_TO_PC(1);
1090}
1091
1092// COP1_L
1093DECLARE_INSTRUCTION(CVT_S_L)
1094{
1095   if (check_cop1_unusable()) return;
1096   cvt_s_l((int64_t*) reg_cop1_double[cffs], reg_cop1_simple[cffd]);
1097   ADD_TO_PC(1);
1098}
1099
1100DECLARE_INSTRUCTION(CVT_D_L)
1101{
1102   if (check_cop1_unusable()) return;
1103   cvt_d_l((int64_t*) reg_cop1_double[cffs], reg_cop1_double[cffd]);
1104   ADD_TO_PC(1);
1105}
1106
1107// COP1_S
1108DECLARE_INSTRUCTION(ADD_S)
1109{
1110   if (check_cop1_unusable()) return;
1111   add_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft], reg_cop1_simple[cffd]);
1112   ADD_TO_PC(1);
1113}
1114
1115DECLARE_INSTRUCTION(SUB_S)
1116{
1117   if (check_cop1_unusable()) return;
1118   sub_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft], reg_cop1_simple[cffd]);
1119   ADD_TO_PC(1);
1120}
1121
1122DECLARE_INSTRUCTION(MUL_S)
1123{
1124   if (check_cop1_unusable()) return;
1125   mul_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft], reg_cop1_simple[cffd]);
1126   ADD_TO_PC(1);
1127}
1128
1129DECLARE_INSTRUCTION(DIV_S)
1130{
1131   if (check_cop1_unusable()) return;
1132   if((FCR31 & UINT32_C(0x400)) && *reg_cop1_simple[cfft] == 0)
1133   {
1134     DebugMessage(M64MSG_ERROR, "DIV_S by 0");
1135   }
1136   div_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft], reg_cop1_simple[cffd]);
1137   ADD_TO_PC(1);
1138}
1139
1140DECLARE_INSTRUCTION(SQRT_S)
1141{
1142   if (check_cop1_unusable()) return;
1143   sqrt_s(reg_cop1_simple[cffs], reg_cop1_simple[cffd]);
1144   ADD_TO_PC(1);
1145}
1146
1147DECLARE_INSTRUCTION(ABS_S)
1148{
1149   if (check_cop1_unusable()) return;
1150   abs_s(reg_cop1_simple[cffs], reg_cop1_simple[cffd]);
1151   ADD_TO_PC(1);
1152}
1153
1154DECLARE_INSTRUCTION(MOV_S)
1155{
1156   if (check_cop1_unusable()) return;
1157   mov_s(reg_cop1_simple[cffs], reg_cop1_simple[cffd]);
1158   ADD_TO_PC(1);
1159}
1160
1161DECLARE_INSTRUCTION(NEG_S)
1162{
1163   if (check_cop1_unusable()) return;
1164   neg_s(reg_cop1_simple[cffs], reg_cop1_simple[cffd]);
1165   ADD_TO_PC(1);
1166}
1167
1168DECLARE_INSTRUCTION(ROUND_L_S)
1169{
1170   if (check_cop1_unusable()) return;
1171   round_l_s(reg_cop1_simple[cffs], (int64_t*) reg_cop1_double[cffd]);
1172   ADD_TO_PC(1);
1173}
1174
1175DECLARE_INSTRUCTION(TRUNC_L_S)
1176{
1177   if (check_cop1_unusable()) return;
1178   trunc_l_s(reg_cop1_simple[cffs], (int64_t*) reg_cop1_double[cffd]);
1179   ADD_TO_PC(1);
1180}
1181
1182DECLARE_INSTRUCTION(CEIL_L_S)
1183{
1184   if (check_cop1_unusable()) return;
1185   ceil_l_s(reg_cop1_simple[cffs], (int64_t*) reg_cop1_double[cffd]);
1186   ADD_TO_PC(1);
1187}
1188
1189DECLARE_INSTRUCTION(FLOOR_L_S)
1190{
1191   if (check_cop1_unusable()) return;
1192   floor_l_s(reg_cop1_simple[cffs], (int64_t*) reg_cop1_double[cffd]);
1193   ADD_TO_PC(1);
1194}
1195
1196DECLARE_INSTRUCTION(ROUND_W_S)
1197{
1198   if (check_cop1_unusable()) return;
1199   round_w_s(reg_cop1_simple[cffs], (int32_t*) reg_cop1_simple[cffd]);
1200   ADD_TO_PC(1);
1201}
1202
1203DECLARE_INSTRUCTION(TRUNC_W_S)
1204{
1205   if (check_cop1_unusable()) return;
1206   trunc_w_s(reg_cop1_simple[cffs], (int32_t*) reg_cop1_simple[cffd]);
1207   ADD_TO_PC(1);
1208}
1209
1210DECLARE_INSTRUCTION(CEIL_W_S)
1211{
1212   if (check_cop1_unusable()) return;
1213   ceil_w_s(reg_cop1_simple[cffs], (int32_t*) reg_cop1_simple[cffd]);
1214   ADD_TO_PC(1);
1215}
1216
1217DECLARE_INSTRUCTION(FLOOR_W_S)
1218{
1219   if (check_cop1_unusable()) return;
1220   floor_w_s(reg_cop1_simple[cffs], (int32_t*) reg_cop1_simple[cffd]);
1221   ADD_TO_PC(1);
1222}
1223
1224DECLARE_INSTRUCTION(CVT_D_S)
1225{
1226   if (check_cop1_unusable()) return;
1227   cvt_d_s(reg_cop1_simple[cffs], reg_cop1_double[cffd]);
1228   ADD_TO_PC(1);
1229}
1230
1231DECLARE_INSTRUCTION(CVT_W_S)
1232{
1233   if (check_cop1_unusable()) return;
1234   cvt_w_s(reg_cop1_simple[cffs], (int32_t*) reg_cop1_simple[cffd]);
1235   ADD_TO_PC(1);
1236}
1237
1238DECLARE_INSTRUCTION(CVT_L_S)
1239{
1240   if (check_cop1_unusable()) return;
1241   cvt_l_s(reg_cop1_simple[cffs], (int64_t*) reg_cop1_double[cffd]);
1242   ADD_TO_PC(1);
1243}
1244
1245DECLARE_INSTRUCTION(C_F_S)
1246{
1247   if (check_cop1_unusable()) return;
1248   c_f_s();
1249   ADD_TO_PC(1);
1250}
1251
1252DECLARE_INSTRUCTION(C_UN_S)
1253{
1254   if (check_cop1_unusable()) return;
1255   c_un_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]);
1256   ADD_TO_PC(1);
1257}
1258
1259DECLARE_INSTRUCTION(C_EQ_S)
1260{
1261   if (check_cop1_unusable()) return;
1262   c_eq_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]);
1263   ADD_TO_PC(1);
1264}
1265
1266DECLARE_INSTRUCTION(C_UEQ_S)
1267{
1268   if (check_cop1_unusable()) return;
1269   c_ueq_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]);
1270   ADD_TO_PC(1);
1271}
1272
1273DECLARE_INSTRUCTION(C_OLT_S)
1274{
1275   if (check_cop1_unusable()) return;
1276   c_olt_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]);
1277   ADD_TO_PC(1);
1278}
1279
1280DECLARE_INSTRUCTION(C_ULT_S)
1281{
1282   if (check_cop1_unusable()) return;
1283   c_ult_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]);
1284   ADD_TO_PC(1);
1285}
1286
1287DECLARE_INSTRUCTION(C_OLE_S)
1288{
1289   if (check_cop1_unusable()) return;
1290   c_ole_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]);
1291   ADD_TO_PC(1);
1292}
1293
1294DECLARE_INSTRUCTION(C_ULE_S)
1295{
1296   if (check_cop1_unusable()) return;
1297   c_ule_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]);
1298   ADD_TO_PC(1);
1299}
1300
1301DECLARE_INSTRUCTION(C_SF_S)
1302{
1303   if (check_cop1_unusable()) return;
1304   if (isnan(*reg_cop1_simple[cffs]) || isnan(*reg_cop1_simple[cfft]))
1305   {
1306     DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode");
1307     stop=1;
1308   }
1309   c_sf_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]);
1310   ADD_TO_PC(1);
1311}
1312
1313DECLARE_INSTRUCTION(C_NGLE_S)
1314{
1315   if (check_cop1_unusable()) return;
1316   if (isnan(*reg_cop1_simple[cffs]) || isnan(*reg_cop1_simple[cfft]))
1317   {
1318     DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode");
1319     stop=1;
1320   }
1321   c_ngle_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]);
1322   ADD_TO_PC(1);
1323}
1324
1325DECLARE_INSTRUCTION(C_SEQ_S)
1326{
1327   if (check_cop1_unusable()) return;
1328   if (isnan(*reg_cop1_simple[cffs]) || isnan(*reg_cop1_simple[cfft]))
1329   {
1330     DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode");
1331     stop=1;
1332   }
1333   c_seq_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]);
1334   ADD_TO_PC(1);
1335}
1336
1337DECLARE_INSTRUCTION(C_NGL_S)
1338{
1339   if (check_cop1_unusable()) return;
1340   if (isnan(*reg_cop1_simple[cffs]) || isnan(*reg_cop1_simple[cfft]))
1341   {
1342     DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode");
1343     stop=1;
1344   }
1345   c_ngl_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]);
1346   ADD_TO_PC(1);
1347}
1348
1349DECLARE_INSTRUCTION(C_LT_S)
1350{
1351   if (check_cop1_unusable()) return;
1352   if (isnan(*reg_cop1_simple[cffs]) || isnan(*reg_cop1_simple[cfft]))
1353   {
1354     DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode");
1355     stop=1;
1356   }
1357   c_lt_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]);
1358   ADD_TO_PC(1);
1359}
1360
1361DECLARE_INSTRUCTION(C_NGE_S)
1362{
1363   if (check_cop1_unusable()) return;
1364   if (isnan(*reg_cop1_simple[cffs]) || isnan(*reg_cop1_simple[cfft]))
1365   {
1366     DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode");
1367     stop=1;
1368   }
1369   c_nge_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]);
1370   ADD_TO_PC(1);
1371}
1372
1373DECLARE_INSTRUCTION(C_LE_S)
1374{
1375   if (check_cop1_unusable()) return;
1376   if (isnan(*reg_cop1_simple[cffs]) || isnan(*reg_cop1_simple[cfft]))
1377   {
1378     DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode");
1379     stop=1;
1380   }
1381   c_le_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]);
1382   ADD_TO_PC(1);
1383}
1384
1385DECLARE_INSTRUCTION(C_NGT_S)
1386{
1387   if (check_cop1_unusable()) return;
1388   if (isnan(*reg_cop1_simple[cffs]) || isnan(*reg_cop1_simple[cfft]))
1389   {
1390     DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode");
1391     stop=1;
1392   }
1393   c_ngt_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]);
1394   ADD_TO_PC(1);
1395}
1396
1397// COP1_W
1398DECLARE_INSTRUCTION(CVT_S_W)
1399{
1400   if (check_cop1_unusable()) return;
1401   cvt_s_w((int32_t*) reg_cop1_simple[cffs], reg_cop1_simple[cffd]);
1402   ADD_TO_PC(1);
1403}
1404
1405DECLARE_INSTRUCTION(CVT_D_W)
1406{
1407   if (check_cop1_unusable()) return;
1408   cvt_d_w((int32_t*) reg_cop1_simple[cffs], reg_cop1_double[cffd]);
1409   ADD_TO_PC(1);
1410}
1411
1412/* regimm */
1413DECLARE_JUMP(BLTZ,    PCADDR + (iimmediate+1)*4, irs < 0,    &reg[0],  0, 0)
1414DECLARE_JUMP(BGEZ,    PCADDR + (iimmediate+1)*4, irs >= 0,   &reg[0],  0, 0)
1415DECLARE_JUMP(BLTZL,   PCADDR + (iimmediate+1)*4, irs < 0,    &reg[0],  1, 0)
1416DECLARE_JUMP(BGEZL,   PCADDR + (iimmediate+1)*4, irs >= 0,   &reg[0],  1, 0)
1417DECLARE_JUMP(BLTZAL,  PCADDR + (iimmediate+1)*4, irs < 0,    &reg[31], 0, 0)
1418DECLARE_JUMP(BGEZAL,  PCADDR + (iimmediate+1)*4, irs >= 0,   &reg[31], 0, 0)
1419DECLARE_JUMP(BLTZALL, PCADDR + (iimmediate+1)*4, irs < 0,    &reg[31], 1, 0)
1420DECLARE_JUMP(BGEZALL, PCADDR + (iimmediate+1)*4, irs >= 0,   &reg[31], 1, 0)
1421
1422/* special */
1423DECLARE_INSTRUCTION(NOP)
1424{
1425   ADD_TO_PC(1);
1426}
1427
1428DECLARE_INSTRUCTION(SLL)
1429{
1430   rrd = SE32((uint32_t) rrt32 << rsa);
1431   ADD_TO_PC(1);
1432}
1433
1434DECLARE_INSTRUCTION(SRL)
1435{
1436   rrd = SE32((uint32_t) rrt32 >> rsa);
1437   ADD_TO_PC(1);
1438}
1439
1440DECLARE_INSTRUCTION(SRA)
1441{
1442   rrd = SE32((int32_t) rrt32 >> rsa);
1443   ADD_TO_PC(1);
1444}
1445
1446DECLARE_INSTRUCTION(SLLV)
1447{
1448   rrd = SE32((uint32_t) rrt32 << (rrs32 & 0x1F));
1449   ADD_TO_PC(1);
1450}
1451
1452DECLARE_INSTRUCTION(SRLV)
1453{
1454   rrd = SE32((uint32_t) rrt32 >> (rrs32 & 0x1F));
1455   ADD_TO_PC(1);
1456}
1457
1458DECLARE_INSTRUCTION(SRAV)
1459{
1460   rrd = SE32((int32_t) rrt32 >> (rrs32 & 0x1F));
1461   ADD_TO_PC(1);
1462}
1463
1464DECLARE_JUMP(JR,   irs32, 1, &reg[0], 0, 0)
1465DECLARE_JUMP(JALR, irs32, 1, &rrd,    0, 0)
1466
1467DECLARE_INSTRUCTION(SYSCALL)
1468{
1469   g_cp0_regs[CP0_CAUSE_REG] = CP0_CAUSE_EXCCODE_SYS;
1470   exception_general();
1471}
1472
1473DECLARE_INSTRUCTION(SYNC)
1474{
1475   ADD_TO_PC(1);
1476}
1477
1478DECLARE_INSTRUCTION(MFHI)
1479{
1480   rrd = hi;
1481   ADD_TO_PC(1);
1482}
1483
1484DECLARE_INSTRUCTION(MTHI)
1485{
1486   hi = rrs;
1487   ADD_TO_PC(1);
1488}
1489
1490DECLARE_INSTRUCTION(MFLO)
1491{
1492   rrd = lo;
1493   ADD_TO_PC(1);
1494}
1495
1496DECLARE_INSTRUCTION(MTLO)
1497{
1498   lo = rrs;
1499   ADD_TO_PC(1);
1500}
1501
1502DECLARE_INSTRUCTION(DSLLV)
1503{
1504   rrd = rrt << (rrs32 & 0x3F);
1505   ADD_TO_PC(1);
1506}
1507
1508DECLARE_INSTRUCTION(DSRLV)
1509{
1510   rrd = (uint64_t) rrt >> (rrs32 & 0x3F);
1511   ADD_TO_PC(1);
1512}
1513
1514DECLARE_INSTRUCTION(DSRAV)
1515{
1516   rrd = (int64_t) rrt >> (rrs32 & 0x3F);
1517   ADD_TO_PC(1);
1518}
1519
1520DECLARE_INSTRUCTION(MULT)
1521{
1522   int64_t temp;
1523   temp = rrs * rrt;
1524   hi = temp >> 32;
1525   lo = SE32(temp);
1526   ADD_TO_PC(1);
1527}
1528
1529DECLARE_INSTRUCTION(MULTU)
1530{
1531   uint64_t temp;
1532   temp = (uint32_t) rrs * (uint64_t) ((uint32_t) rrt);
1533   hi = (int64_t) temp >> 32;
1534   lo = SE32(temp);
1535   ADD_TO_PC(1);
1536}
1537
1538DECLARE_INSTRUCTION(DIV)
1539{
1540   if (rrt32)
1541   {
1542     lo = SE32(rrs32 / rrt32);
1543     hi = SE32(rrs32 % rrt32);
1544   }
1545   else DebugMessage(M64MSG_ERROR, "DIV: divide by 0");
1546   ADD_TO_PC(1);
1547}
1548
1549DECLARE_INSTRUCTION(DIVU)
1550{
1551   if (rrt32)
1552   {
1553     lo = SE32((uint32_t) rrs32 / (uint32_t) rrt32);
1554     hi = SE32((uint32_t) rrs32 % (uint32_t) rrt32);
1555   }
1556   else DebugMessage(M64MSG_ERROR, "DIVU: divide by 0");
1557   ADD_TO_PC(1);
1558}
1559
1560DECLARE_INSTRUCTION(DMULT)
1561{
1562   uint64_t op1, op2, op3, op4;
1563   uint64_t result1, result2, result3, result4;
1564   uint64_t temp1, temp2, temp3, temp4;
1565   int sign = 0;
1566
1567   if (rrs < 0)
1568     {
1569    op2 = -rrs;
1570    sign = 1 - sign;
1571     }
1572   else op2 = rrs;
1573   if (rrt < 0)
1574     {
1575    op4 = -rrt;
1576    sign = 1 - sign;
1577     }
1578   else op4 = rrt;
1579
1580   op1 = op2 & UINT64_C(0xFFFFFFFF);
1581   op2 = (op2 >> 32) & UINT64_C(0xFFFFFFFF);
1582   op3 = op4 & UINT64_C(0xFFFFFFFF);
1583   op4 = (op4 >> 32) & UINT64_C(0xFFFFFFFF);
1584
1585   temp1 = op1 * op3;
1586   temp2 = (temp1 >> 32) + op1 * op4;
1587   temp3 = op2 * op3;
1588   temp4 = (temp3 >> 32) + op2 * op4;
1589
1590   result1 = temp1 & UINT64_C(0xFFFFFFFF);
1591   result2 = temp2 + (temp3 & UINT64_C(0xFFFFFFFF));
1592   result3 = (result2 >> 32) + temp4;
1593   result4 = (result3 >> 32);
1594
1595   lo = result1 | (result2 << 32);
1596   hi = (result3 & UINT64_C(0xFFFFFFFF)) | (result4 << 32);
1597   if (sign)
1598     {
1599    hi = ~hi;
1600    if (!lo) hi++;
1601    else lo = ~lo + 1;
1602     }
1603   ADD_TO_PC(1);
1604}
1605
1606DECLARE_INSTRUCTION(DMULTU)
1607{
1608   uint64_t op1, op2, op3, op4;
1609   uint64_t result1, result2, result3, result4;
1610   uint64_t temp1, temp2, temp3, temp4;
1611
1612   op1 = rrs & UINT64_C(0xFFFFFFFF);
1613   op2 = (rrs >> 32) & UINT64_C(0xFFFFFFFF);
1614   op3 = rrt & UINT64_C(0xFFFFFFFF);
1615   op4 = (rrt >> 32) & UINT64_C(0xFFFFFFFF);
1616
1617   temp1 = op1 * op3;
1618   temp2 = (temp1 >> 32) + op1 * op4;
1619   temp3 = op2 * op3;
1620   temp4 = (temp3 >> 32) + op2 * op4;
1621
1622   result1 = temp1 & UINT64_C(0xFFFFFFFF);
1623   result2 = temp2 + (temp3 & UINT64_C(0xFFFFFFFF));
1624   result3 = (result2 >> 32) + temp4;
1625   result4 = (result3 >> 32);
1626
1627   lo = result1 | (result2 << 32);
1628   hi = (result3 & UINT64_C(0xFFFFFFFF)) | (result4 << 32);
1629
1630   ADD_TO_PC(1);
1631}
1632
1633DECLARE_INSTRUCTION(DDIV)
1634{
1635   if (rrt)
1636   {
1637     lo = rrs / rrt;
1638     hi = rrs % rrt;
1639   }
1640   else DebugMessage(M64MSG_ERROR, "DDIV: divide by 0");
1641   ADD_TO_PC(1);
1642}
1643
1644DECLARE_INSTRUCTION(DDIVU)
1645{
1646   if (rrt)
1647   {
1648     lo = (uint64_t) rrs / (uint64_t) rrt;
1649     hi = (uint64_t) rrs % (uint64_t) rrt;
1650   }
1651   else DebugMessage(M64MSG_ERROR, "DDIVU: divide by 0");
1652   ADD_TO_PC(1);
1653}
1654
1655DECLARE_INSTRUCTION(ADD)
1656{
1657   rrd = SE32(rrs32 + rrt32);
1658   ADD_TO_PC(1);
1659}
1660
1661DECLARE_INSTRUCTION(ADDU)
1662{
1663   rrd = SE32(rrs32 + rrt32);
1664   ADD_TO_PC(1);
1665}
1666
1667DECLARE_INSTRUCTION(SUB)
1668{
1669   rrd = SE32(rrs32 - rrt32);
1670   ADD_TO_PC(1);
1671}
1672
1673DECLARE_INSTRUCTION(SUBU)
1674{
1675   rrd = SE32(rrs32 - rrt32);
1676   ADD_TO_PC(1);
1677}
1678
1679DECLARE_INSTRUCTION(AND)
1680{
1681   rrd = rrs & rrt;
1682   ADD_TO_PC(1);
1683}
1684
1685DECLARE_INSTRUCTION(OR)
1686{
1687   rrd = rrs | rrt;
1688   ADD_TO_PC(1);
1689}
1690
1691DECLARE_INSTRUCTION(XOR)
1692{
1693   rrd = rrs ^ rrt;
1694   ADD_TO_PC(1);
1695}
1696
1697DECLARE_INSTRUCTION(NOR)
1698{
1699   rrd = ~(rrs | rrt);
1700   ADD_TO_PC(1);
1701}
1702
1703DECLARE_INSTRUCTION(SLT)
1704{
1705   if (rrs < rrt) rrd = 1;
1706   else rrd = 0;
1707   ADD_TO_PC(1);
1708}
1709
1710DECLARE_INSTRUCTION(SLTU)
1711{
1712   if ((uint64_t) rrs < (uint64_t) rrt)
1713     rrd = 1;
1714   else rrd = 0;
1715   ADD_TO_PC(1);
1716}
1717
1718DECLARE_INSTRUCTION(DADD)
1719{
1720   rrd = (uint64_t) rrs + (uint64_t) rrt;
1721   ADD_TO_PC(1);
1722}
1723
1724DECLARE_INSTRUCTION(DADDU)
1725{
1726   rrd = (uint64_t) rrs + (uint64_t) rrt;
1727   ADD_TO_PC(1);
1728}
1729
1730DECLARE_INSTRUCTION(DSUB)
1731{
1732   rrd = rrs - rrt;
1733   ADD_TO_PC(1);
1734}
1735
1736DECLARE_INSTRUCTION(DSUBU)
1737{
1738   rrd = rrs - rrt;
1739   ADD_TO_PC(1);
1740}
1741
1742DECLARE_INSTRUCTION(TEQ)
1743{
1744   if (rrs == rrt)
1745   {
1746     DebugMessage(M64MSG_ERROR, "trap exception in TEQ");
1747     stop=1;
1748   }
1749   ADD_TO_PC(1);
1750}
1751
1752DECLARE_INSTRUCTION(DSLL)
1753{
1754   rrd = rrt << rsa;
1755   ADD_TO_PC(1);
1756}
1757
1758DECLARE_INSTRUCTION(DSRL)
1759{
1760   rrd = (uint64_t) rrt >> rsa;
1761   ADD_TO_PC(1);
1762}
1763
1764DECLARE_INSTRUCTION(DSRA)
1765{
1766   rrd = rrt >> rsa;
1767   ADD_TO_PC(1);
1768}
1769
1770DECLARE_INSTRUCTION(DSLL32)
1771{
1772   rrd = rrt << (32 + rsa);
1773   ADD_TO_PC(1);
1774}
1775
1776DECLARE_INSTRUCTION(DSRL32)
1777{
1778   rrd = (uint64_t) rrt >> (32 + rsa);
1779   ADD_TO_PC(1);
1780}
1781
1782DECLARE_INSTRUCTION(DSRA32)
1783{
1784   rrd = (int64_t) rrt >> (32 + rsa);
1785   ADD_TO_PC(1);
1786}
1787
1788/* TLB */
1789#include <encodings/crc32.h>
1790
1791DECLARE_INSTRUCTION(TLBR)
1792{
1793   int index;
1794   index = g_cp0_regs[CP0_INDEX_REG] & UINT32_C(0x1F);
1795   g_cp0_regs[CP0_PAGEMASK_REG] = tlb_e[index].mask << 13;
1796   g_cp0_regs[CP0_ENTRYHI_REG] = ((tlb_e[index].vpn2 << 13) | tlb_e[index].asid);
1797   g_cp0_regs[CP0_ENTRYLO0_REG] = (tlb_e[index].pfn_even << 6) | (tlb_e[index].c_even << 3)
1798     | (tlb_e[index].d_even << 2) | (tlb_e[index].v_even << 1)
1799       | tlb_e[index].g;
1800   g_cp0_regs[CP0_ENTRYLO1_REG] = (tlb_e[index].pfn_odd << 6) | (tlb_e[index].c_odd << 3)
1801     | (tlb_e[index].d_odd << 2) | (tlb_e[index].v_odd << 1)
1802       | tlb_e[index].g;
1803   ADD_TO_PC(1);
1804}
1805
1806static void TLBWrite(unsigned int idx)
1807{
1808   struct r4300_core* r4300 = &g_dev.r4300;
1809   uint32_t pc_addr         = *r4300_pc();
1810
1811 if (pc_addr >= tlb_e[idx].start_even && pc_addr < tlb_e[idx].end_even && tlb_e[idx].v_even)
1812         return;
1813     if (pc_addr >= tlb_e[idx].start_odd && pc_addr < tlb_e[idx].end_odd && tlb_e[idx].v_odd)
1814         return;
1815
1816   if (r4300emu != CORE_PURE_INTERPRETER)
1817   {
1818      unsigned int i;
1819      if (tlb_e[idx].v_even)
1820      {
1821         for (i=tlb_e[idx].start_even>>12; i<=tlb_e[idx].end_even>>12; i++)
1822         {
1823            if(!invalid_code[i] &&(invalid_code[tlb_LUT_r[i]>>12] ||
1824               invalid_code[(tlb_LUT_r[i]>>12)+0x20000]))
1825               invalid_code[i] = 1;
1826            if (!invalid_code[i])
1827            {
1828                /*int j;
1829                md5_state_t state;
1830                md5_byte_t digest[16];
1831                md5_init(&state);
1832                md5_append(&state,
1833                       (const md5_byte_t*)&g_dev.ri.rdram.dram[(tlb_LUT_r[i]&0x7FF000)/4],
1834                       0x1000);
1835                md5_finish(&state, digest);
1836                for (j=0; j<16; j++) blocks[i]->md5[j] = digest[j];*/
1837
1838                blocks[i]->adler32 = encoding_crc32(0, (void*)&g_dev.ri.rdram.dram[(tlb_LUT_r[i]&0x7FF000)/4], 0x1000);
1839
1840                invalid_code[i] = 1;
1841            }
1842            else if (blocks[i])
1843            {
1844               /*int j;
1845                for (j=0; j<16; j++) blocks[i]->md5[j] = 0;*/
1846               blocks[i]->adler32 = 0;
1847            }
1848         }
1849      }
1850      if (tlb_e[idx].v_odd)
1851      {
1852         for (i=tlb_e[idx].start_odd>>12; i<=tlb_e[idx].end_odd>>12; i++)
1853         {
1854            if(!invalid_code[i] &&(invalid_code[tlb_LUT_r[i]>>12] ||
1855               invalid_code[(tlb_LUT_r[i]>>12)+0x20000]))
1856               invalid_code[i] = 1;
1857            if (!invalid_code[i])
1858            {
1859               /*int j;
1860               md5_state_t state;
1861               md5_byte_t digest[16];
1862               md5_init(&state);
1863               md5_append(&state,
1864                      (const md5_byte_t*)&g_dev.ri.rdram.dram[(tlb_LUT_r[i]&0x7FF000)/4],
1865                      0x1000);
1866               md5_finish(&state, digest);
1867               for (j=0; j<16; j++) blocks[i]->md5[j] = digest[j];*/
1868
1869               blocks[i]->adler32 = encoding_crc32(0, (void*)&g_dev.ri.rdram.dram[(tlb_LUT_r[i]&0x7FF000)/4], 0x1000);
1870
1871               invalid_code[i] = 1;
1872            }
1873            else if (blocks[i])
1874            {
1875               /*int j;
1876               for (j=0; j<16; j++) blocks[i]->md5[j] = 0;*/
1877               blocks[i]->adler32 = 0;
1878            }
1879         }
1880      }
1881   }
1882
1883   tlb_unmap(&tlb_e[idx]);
1884
1885   tlb_e[idx].g = (g_cp0_regs[CP0_ENTRYLO0_REG] & g_cp0_regs[CP0_ENTRYLO1_REG] & 1);
1886   tlb_e[idx].pfn_even = (g_cp0_regs[CP0_ENTRYLO0_REG] & UINT32_C(0x3FFFFFC0)) >> 6;
1887   tlb_e[idx].pfn_odd = (g_cp0_regs[CP0_ENTRYLO1_REG] & UINT32_C(0x3FFFFFC0)) >> 6;
1888   tlb_e[idx].c_even = (g_cp0_regs[CP0_ENTRYLO0_REG] & UINT32_C(0x38)) >> 3;
1889   tlb_e[idx].c_odd = (g_cp0_regs[CP0_ENTRYLO1_REG] & UINT32_C(0x38)) >> 3;
1890   tlb_e[idx].d_even = (g_cp0_regs[CP0_ENTRYLO0_REG] & UINT32_C(0x4)) >> 2;
1891   tlb_e[idx].d_odd = (g_cp0_regs[CP0_ENTRYLO1_REG] & UINT32_C(0x4)) >> 2;
1892   tlb_e[idx].v_even = (g_cp0_regs[CP0_ENTRYLO0_REG] & UINT32_C(0x2)) >> 1;
1893   tlb_e[idx].v_odd = (g_cp0_regs[CP0_ENTRYLO1_REG] & UINT32_C(0x2)) >> 1;
1894   tlb_e[idx].asid = (g_cp0_regs[CP0_ENTRYHI_REG] & UINT32_C(0xFF));
1895   tlb_e[idx].vpn2 = (g_cp0_regs[CP0_ENTRYHI_REG] & UINT32_C(0xFFFFE000)) >> 13;
1896   //tlb_e[idx].r = (g_cp0_regs[CP0_ENTRYHI_REG] & 0xC000000000000000LL) >> 62;
1897   tlb_e[idx].mask = (g_cp0_regs[CP0_PAGEMASK_REG] & UINT32_C(0x1FFE000)) >> 13;
1898
1899   tlb_e[idx].start_even = tlb_e[idx].vpn2 << 13;
1900   tlb_e[idx].end_even = tlb_e[idx].start_even+
1901     (tlb_e[idx].mask << 12) + UINT32_C(0xFFF);
1902   tlb_e[idx].phys_even = tlb_e[idx].pfn_even << 12;
1903
1904
1905   tlb_e[idx].start_odd = tlb_e[idx].end_even+1;
1906   tlb_e[idx].end_odd = tlb_e[idx].start_odd+
1907     (tlb_e[idx].mask << 12) + UINT32_C(0xFFF);
1908   tlb_e[idx].phys_odd = tlb_e[idx].pfn_odd << 12;
1909
1910   tlb_map(&tlb_e[idx]);
1911
1912   if (r4300emu != CORE_PURE_INTERPRETER)
1913   {
1914      unsigned int i;
1915      if (tlb_e[idx].v_even)
1916      {
1917         for (i=tlb_e[idx].start_even>>12; i<=tlb_e[idx].end_even>>12; i++)
1918         {
1919            /*if (blocks[i] && (blocks[i]->md5[0] || blocks[i]->md5[1] ||
1920                  blocks[i]->md5[2] || blocks[i]->md5[3]))
1921            {
1922               int j;
1923               int equal = 1;
1924               md5_state_t state;
1925               md5_byte_t digest[16];
1926               md5_init(&state);
1927               md5_append(&state,
1928                  (const md5_byte_t*)&g_dev.ri.rdram.dram[(tlb_LUT_r[i]&0x7FF000)/4],
1929                  0x1000);
1930               md5_finish(&state, digest);
1931               for (j=0; j<16; j++)
1932                 if (digest[j] != blocks[i]->md5[j])
1933                   equal = 0;
1934               if (equal) invalid_code[i] = 0;
1935               }*/
1936               if(blocks[i] && blocks[i]->adler32)
1937               {
1938                  if(blocks[i]->adler32 == encoding_crc32(0,(void*)&g_dev.ri.rdram.dram[(tlb_LUT_r[i]&0x7FF000)/4],0x1000))
1939                     invalid_code[i] = 0;
1940               }
1941         }
1942      }
1943
1944      if (tlb_e[idx].v_odd)
1945      {
1946         for (i=tlb_e[idx].start_odd>>12; i<=tlb_e[idx].end_odd>>12; i++)
1947         {
1948            /*if (blocks[i] && (blocks[i]->md5[0] || blocks[i]->md5[1] ||
1949                  blocks[i]->md5[2] || blocks[i]->md5[3]))
1950              {
1951            int j;
1952            int equal = 1;
1953            md5_state_t state;
1954            md5_byte_t digest[16];
1955            md5_init(&state);
1956            md5_append(&state,
1957                   (const md5_byte_t*)&g_dev.ri.rdram.dram[(tlb_LUT_r[i]&0x7FF000)/4],
1958                   0x1000);
1959            md5_finish(&state, digest);
1960            for (j=0; j<16; j++)
1961              if (digest[j] != blocks[i]->md5[j])
1962                equal = 0;
1963            if (equal) invalid_code[i] = 0;
1964            }*/
1965            if(blocks[i] && blocks[i]->adler32)
1966            {
1967               if(blocks[i]->adler32 == encoding_crc32(0,(void*)&g_dev.ri.rdram.dram[(tlb_LUT_r[i]&0x7FF000)/4],0x1000))
1968                  invalid_code[i] = 0;
1969            }
1970         }
1971      }
1972   }
1973}
1974
1975DECLARE_INSTRUCTION(TLBWI)
1976{
1977   TLBWrite(g_cp0_regs[CP0_INDEX_REG] & UINT32_C(0x3F));
1978   ADD_TO_PC(1);
1979}
1980
1981DECLARE_INSTRUCTION(TLBWR)
1982{
1983   cp0_update_count();
1984   g_cp0_regs[CP0_RANDOM_REG] = (g_cp0_regs[CP0_COUNT_REG]/2 % (32 - g_cp0_regs[CP0_WIRED_REG]))
1985                              + g_cp0_regs[CP0_WIRED_REG];
1986   TLBWrite(g_cp0_regs[CP0_RANDOM_REG]);
1987   ADD_TO_PC(1);
1988}
1989
1990DECLARE_INSTRUCTION(TLBP)
1991{
1992   int i;
1993   g_cp0_regs[CP0_INDEX_REG] |= UINT32_C(0x80000000);
1994   for (i=0; i<32; i++)
1995   {
1996      if (((tlb_e[i].vpn2 & (~tlb_e[i].mask)) ==
1997         (((g_cp0_regs[CP0_ENTRYHI_REG] & UINT32_C(0xFFFFE000)) >> 13) & (~tlb_e[i].mask))) &&
1998        ((tlb_e[i].g) ||
1999         (tlb_e[i].asid == (g_cp0_regs[CP0_ENTRYHI_REG] & UINT32_C(0xFF)))))
2000      {
2001         g_cp0_regs[CP0_INDEX_REG] = i;
2002         break;
2003      }
2004   }
2005   ADD_TO_PC(1);
2006}
2007
2008DECLARE_INSTRUCTION(ERET)
2009{
2010   cp0_update_count();
2011   if (g_cp0_regs[CP0_STATUS_REG] & CP0_STATUS_ERL)
2012   {
2013     DebugMessage(M64MSG_ERROR, "error in ERET");
2014     stop=1;
2015   }
2016   else
2017   {
2018     g_cp0_regs[CP0_STATUS_REG] &= ~CP0_STATUS_EXL;
2019     generic_jump_to(g_cp0_regs[CP0_EPC_REG]);
2020   }
2021   llbit = 0;
2022   check_interrupt();
2023   last_addr = PCADDR;
2024   if (next_interrupt <= g_cp0_regs[CP0_COUNT_REG]) gen_interrupt();
2025}
2026
2027