]> Git Repo - qemu.git/blob - target-mips/op.c
Convert some MIPS load/store instructions to TCG.
[qemu.git] / target-mips / op.c
1 /*
2  *  MIPS emulation micro-operations for qemu.
3  *
4  *  Copyright (c) 2004-2005 Jocelyn Mayer
5  *  Copyright (c) 2006 Marius Groeger (FPU operations)
6  *  Copyright (c) 2007 Thiemo Seufer (64-bit FPU support)
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22
23 #include "config.h"
24 #include "exec.h"
25 #include "host-utils.h"
26
27 #ifndef CALL_FROM_TB0
28 #define CALL_FROM_TB0(func) func()
29 #endif
30 #ifndef CALL_FROM_TB1
31 #define CALL_FROM_TB1(func, arg0) func(arg0)
32 #endif
33 #ifndef CALL_FROM_TB1_CONST16
34 #define CALL_FROM_TB1_CONST16(func, arg0) CALL_FROM_TB1(func, arg0)
35 #endif
36 #ifndef CALL_FROM_TB2
37 #define CALL_FROM_TB2(func, arg0, arg1) func(arg0, arg1)
38 #endif
39 #ifndef CALL_FROM_TB2_CONST16
40 #define CALL_FROM_TB2_CONST16(func, arg0, arg1)     \
41         CALL_FROM_TB2(func, arg0, arg1)
42 #endif
43 #ifndef CALL_FROM_TB3
44 #define CALL_FROM_TB3(func, arg0, arg1, arg2) func(arg0, arg1, arg2)
45 #endif
46 #ifndef CALL_FROM_TB4
47 #define CALL_FROM_TB4(func, arg0, arg1, arg2, arg3) \
48         func(arg0, arg1, arg2, arg3)
49 #endif
50
51 #define REG 1
52 #include "op_template.c"
53 #undef REG
54 #define REG 2
55 #include "op_template.c"
56 #undef REG
57 #define REG 3
58 #include "op_template.c"
59 #undef REG
60 #define REG 4
61 #include "op_template.c"
62 #undef REG
63 #define REG 5
64 #include "op_template.c"
65 #undef REG
66 #define REG 6
67 #include "op_template.c"
68 #undef REG
69 #define REG 7
70 #include "op_template.c"
71 #undef REG
72 #define REG 8
73 #include "op_template.c"
74 #undef REG
75 #define REG 9
76 #include "op_template.c"
77 #undef REG
78 #define REG 10
79 #include "op_template.c"
80 #undef REG
81 #define REG 11
82 #include "op_template.c"
83 #undef REG
84 #define REG 12
85 #include "op_template.c"
86 #undef REG
87 #define REG 13
88 #include "op_template.c"
89 #undef REG
90 #define REG 14
91 #include "op_template.c"
92 #undef REG
93 #define REG 15
94 #include "op_template.c"
95 #undef REG
96 #define REG 16
97 #include "op_template.c"
98 #undef REG
99 #define REG 17
100 #include "op_template.c"
101 #undef REG
102 #define REG 18
103 #include "op_template.c"
104 #undef REG
105 #define REG 19
106 #include "op_template.c"
107 #undef REG
108 #define REG 20
109 #include "op_template.c"
110 #undef REG
111 #define REG 21
112 #include "op_template.c"
113 #undef REG
114 #define REG 22
115 #include "op_template.c"
116 #undef REG
117 #define REG 23
118 #include "op_template.c"
119 #undef REG
120 #define REG 24
121 #include "op_template.c"
122 #undef REG
123 #define REG 25
124 #include "op_template.c"
125 #undef REG
126 #define REG 26
127 #include "op_template.c"
128 #undef REG
129 #define REG 27
130 #include "op_template.c"
131 #undef REG
132 #define REG 28
133 #include "op_template.c"
134 #undef REG
135 #define REG 29
136 #include "op_template.c"
137 #undef REG
138 #define REG 30
139 #include "op_template.c"
140 #undef REG
141 #define REG 31
142 #include "op_template.c"
143 #undef REG
144
145 #define TN
146 #include "op_template.c"
147 #undef TN
148
149 #define FREG 0
150 #include "fop_template.c"
151 #undef FREG
152 #define FREG 1
153 #include "fop_template.c"
154 #undef FREG
155 #define FREG 2
156 #include "fop_template.c"
157 #undef FREG
158 #define FREG 3
159 #include "fop_template.c"
160 #undef FREG
161 #define FREG 4
162 #include "fop_template.c"
163 #undef FREG
164 #define FREG 5
165 #include "fop_template.c"
166 #undef FREG
167 #define FREG 6
168 #include "fop_template.c"
169 #undef FREG
170 #define FREG 7
171 #include "fop_template.c"
172 #undef FREG
173 #define FREG 8
174 #include "fop_template.c"
175 #undef FREG
176 #define FREG 9
177 #include "fop_template.c"
178 #undef FREG
179 #define FREG 10
180 #include "fop_template.c"
181 #undef FREG
182 #define FREG 11
183 #include "fop_template.c"
184 #undef FREG
185 #define FREG 12
186 #include "fop_template.c"
187 #undef FREG
188 #define FREG 13
189 #include "fop_template.c"
190 #undef FREG
191 #define FREG 14
192 #include "fop_template.c"
193 #undef FREG
194 #define FREG 15
195 #include "fop_template.c"
196 #undef FREG
197 #define FREG 16
198 #include "fop_template.c"
199 #undef FREG
200 #define FREG 17
201 #include "fop_template.c"
202 #undef FREG
203 #define FREG 18
204 #include "fop_template.c"
205 #undef FREG
206 #define FREG 19
207 #include "fop_template.c"
208 #undef FREG
209 #define FREG 20
210 #include "fop_template.c"
211 #undef FREG
212 #define FREG 21
213 #include "fop_template.c"
214 #undef FREG
215 #define FREG 22
216 #include "fop_template.c"
217 #undef FREG
218 #define FREG 23
219 #include "fop_template.c"
220 #undef FREG
221 #define FREG 24
222 #include "fop_template.c"
223 #undef FREG
224 #define FREG 25
225 #include "fop_template.c"
226 #undef FREG
227 #define FREG 26
228 #include "fop_template.c"
229 #undef FREG
230 #define FREG 27
231 #include "fop_template.c"
232 #undef FREG
233 #define FREG 28
234 #include "fop_template.c"
235 #undef FREG
236 #define FREG 29
237 #include "fop_template.c"
238 #undef FREG
239 #define FREG 30
240 #include "fop_template.c"
241 #undef FREG
242 #define FREG 31
243 #include "fop_template.c"
244 #undef FREG
245
246 #define FTN
247 #include "fop_template.c"
248 #undef FTN
249
250 /* Load and store */
251 #define MEMSUFFIX _raw
252 #include "op_mem.c"
253 #undef MEMSUFFIX
254 #if !defined(CONFIG_USER_ONLY)
255 #define MEMSUFFIX _user
256 #include "op_mem.c"
257 #undef MEMSUFFIX
258
259 #define MEMSUFFIX _super
260 #include "op_mem.c"
261 #undef MEMSUFFIX
262
263 #define MEMSUFFIX _kernel
264 #include "op_mem.c"
265 #undef MEMSUFFIX
266 #endif
267
268 /* Addresses computation */
269 void op_addr_add (void)
270 {
271 /* For compatibility with 32-bit code, data reference in user mode
272    with Status_UX = 0 should be casted to 32-bit and sign extended.
273    See the MIPS64 PRA manual, section 4.10. */
274 #if defined(TARGET_MIPS64)
275     if (((env->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
276         !(env->CP0_Status & (1 << CP0St_UX)))
277         T0 = (int64_t)(int32_t)(T0 + T1);
278     else
279 #endif
280         T0 += T1;
281     FORCE_RET();
282 }
283
284 /* Arithmetic */
285 void op_add (void)
286 {
287     T0 = (int32_t)((int32_t)T0 + (int32_t)T1);
288     FORCE_RET();
289 }
290
291 void op_addo (void)
292 {
293     target_ulong tmp;
294
295     tmp = (int32_t)T0;
296     T0 = (int32_t)T0 + (int32_t)T1;
297     if (((tmp ^ T1 ^ (-1)) & (T0 ^ T1)) >> 31) {
298         /* operands of same sign, result different sign */
299         CALL_FROM_TB1(do_raise_exception, EXCP_OVERFLOW);
300     }
301     T0 = (int32_t)T0;
302     FORCE_RET();
303 }
304
305 void op_sub (void)
306 {
307     T0 = (int32_t)((int32_t)T0 - (int32_t)T1);
308     FORCE_RET();
309 }
310
311 void op_subo (void)
312 {
313     target_ulong tmp;
314
315     tmp = (int32_t)T0;
316     T0 = (int32_t)T0 - (int32_t)T1;
317     if (((tmp ^ T1) & (tmp ^ T0)) >> 31) {
318         /* operands of different sign, first operand and result different sign */
319         CALL_FROM_TB1(do_raise_exception, EXCP_OVERFLOW);
320     }
321     T0 = (int32_t)T0;
322     FORCE_RET();
323 }
324
325 void op_mul (void)
326 {
327     T0 = (int32_t)((int32_t)T0 * (int32_t)T1);
328     FORCE_RET();
329 }
330
331 #if HOST_LONG_BITS < 64
332 void op_div (void)
333 {
334     CALL_FROM_TB0(do_div);
335     FORCE_RET();
336 }
337 #else
338 void op_div (void)
339 {
340     if (T1 != 0) {
341         env->LO[env->current_tc][0] = (int32_t)((int64_t)(int32_t)T0 / (int32_t)T1);
342         env->HI[env->current_tc][0] = (int32_t)((int64_t)(int32_t)T0 % (int32_t)T1);
343     }
344     FORCE_RET();
345 }
346 #endif
347
348 void op_divu (void)
349 {
350     if (T1 != 0) {
351         env->LO[env->current_tc][0] = (int32_t)((uint32_t)T0 / (uint32_t)T1);
352         env->HI[env->current_tc][0] = (int32_t)((uint32_t)T0 % (uint32_t)T1);
353     }
354     FORCE_RET();
355 }
356
357 #if defined(TARGET_MIPS64)
358 /* Arithmetic */
359 void op_dadd (void)
360 {
361     T0 += T1;
362     FORCE_RET();
363 }
364
365 void op_daddo (void)
366 {
367     target_long tmp;
368
369     tmp = T0;
370     T0 += T1;
371     if (((tmp ^ T1 ^ (-1)) & (T0 ^ T1)) >> 63) {
372         /* operands of same sign, result different sign */
373         CALL_FROM_TB1(do_raise_exception, EXCP_OVERFLOW);
374     }
375     FORCE_RET();
376 }
377
378 void op_dsub (void)
379 {
380     T0 -= T1;
381     FORCE_RET();
382 }
383
384 void op_dsubo (void)
385 {
386     target_long tmp;
387
388     tmp = T0;
389     T0 = (int64_t)T0 - (int64_t)T1;
390     if (((tmp ^ T1) & (tmp ^ T0)) >> 63) {
391         /* operands of different sign, first operand and result different sign */
392         CALL_FROM_TB1(do_raise_exception, EXCP_OVERFLOW);
393     }
394     FORCE_RET();
395 }
396
397 void op_dmul (void)
398 {
399     T0 = (int64_t)T0 * (int64_t)T1;
400     FORCE_RET();
401 }
402
403 /* Those might call libgcc functions.  */
404 void op_ddiv (void)
405 {
406     do_ddiv();
407     FORCE_RET();
408 }
409
410 #if TARGET_LONG_BITS > HOST_LONG_BITS
411 void op_ddivu (void)
412 {
413     do_ddivu();
414     FORCE_RET();
415 }
416 #else
417 void op_ddivu (void)
418 {
419     if (T1 != 0) {
420         env->LO[env->current_tc][0] = T0 / T1;
421         env->HI[env->current_tc][0] = T0 % T1;
422     }
423     FORCE_RET();
424 }
425 #endif
426 #endif /* TARGET_MIPS64 */
427
428 /* Logical */
429 void op_and (void)
430 {
431     T0 &= T1;
432     FORCE_RET();
433 }
434
435 void op_nor (void)
436 {
437     T0 = ~(T0 | T1);
438     FORCE_RET();
439 }
440
441 void op_or (void)
442 {
443     T0 |= T1;
444     FORCE_RET();
445 }
446
447 void op_xor (void)
448 {
449     T0 ^= T1;
450     FORCE_RET();
451 }
452
453 void op_sll (void)
454 {
455     T0 = (int32_t)((uint32_t)T0 << T1);
456     FORCE_RET();
457 }
458
459 void op_sra (void)
460 {
461     T0 = (int32_t)((int32_t)T0 >> T1);
462     FORCE_RET();
463 }
464
465 void op_srl (void)
466 {
467     T0 = (int32_t)((uint32_t)T0 >> T1);
468     FORCE_RET();
469 }
470
471 void op_rotr (void)
472 {
473     target_ulong tmp;
474
475     if (T1) {
476        tmp = (int32_t)((uint32_t)T0 << (0x20 - T1));
477        T0 = (int32_t)((uint32_t)T0 >> T1) | tmp;
478     }
479     FORCE_RET();
480 }
481
482 void op_sllv (void)
483 {
484     T0 = (int32_t)((uint32_t)T1 << ((uint32_t)T0 & 0x1F));
485     FORCE_RET();
486 }
487
488 void op_srav (void)
489 {
490     T0 = (int32_t)((int32_t)T1 >> (T0 & 0x1F));
491     FORCE_RET();
492 }
493
494 void op_srlv (void)
495 {
496     T0 = (int32_t)((uint32_t)T1 >> (T0 & 0x1F));
497     FORCE_RET();
498 }
499
500 void op_rotrv (void)
501 {
502     target_ulong tmp;
503
504     T0 &= 0x1F;
505     if (T0) {
506        tmp = (int32_t)((uint32_t)T1 << (0x20 - T0));
507        T0 = (int32_t)((uint32_t)T1 >> T0) | tmp;
508     } else
509        T0 = T1;
510     FORCE_RET();
511 }
512
513 void op_clo (void)
514 {
515     T0 = clo32(T0);
516     FORCE_RET();
517 }
518
519 void op_clz (void)
520 {
521     T0 = clz32(T0);
522     FORCE_RET();
523 }
524
525 #if defined(TARGET_MIPS64)
526
527 #if TARGET_LONG_BITS > HOST_LONG_BITS
528 /* Those might call libgcc functions.  */
529 void op_dsll (void)
530 {
531     CALL_FROM_TB0(do_dsll);
532     FORCE_RET();
533 }
534
535 void op_dsll32 (void)
536 {
537     CALL_FROM_TB0(do_dsll32);
538     FORCE_RET();
539 }
540
541 void op_dsra (void)
542 {
543     CALL_FROM_TB0(do_dsra);
544     FORCE_RET();
545 }
546
547 void op_dsra32 (void)
548 {
549     CALL_FROM_TB0(do_dsra32);
550     FORCE_RET();
551 }
552
553 void op_dsrl (void)
554 {
555     CALL_FROM_TB0(do_dsrl);
556     FORCE_RET();
557 }
558
559 void op_dsrl32 (void)
560 {
561     CALL_FROM_TB0(do_dsrl32);
562     FORCE_RET();
563 }
564
565 void op_drotr (void)
566 {
567     CALL_FROM_TB0(do_drotr);
568     FORCE_RET();
569 }
570
571 void op_drotr32 (void)
572 {
573     CALL_FROM_TB0(do_drotr32);
574     FORCE_RET();
575 }
576
577 void op_dsllv (void)
578 {
579     CALL_FROM_TB0(do_dsllv);
580     FORCE_RET();
581 }
582
583 void op_dsrav (void)
584 {
585     CALL_FROM_TB0(do_dsrav);
586     FORCE_RET();
587 }
588
589 void op_dsrlv (void)
590 {
591     CALL_FROM_TB0(do_dsrlv);
592     FORCE_RET();
593 }
594
595 void op_drotrv (void)
596 {
597     CALL_FROM_TB0(do_drotrv);
598     FORCE_RET();
599 }
600
601 void op_dclo (void)
602 {
603     CALL_FROM_TB0(do_dclo);
604     FORCE_RET();
605 }
606
607 void op_dclz (void)
608 {
609     CALL_FROM_TB0(do_dclz);
610     FORCE_RET();
611 }
612
613 #else /* TARGET_LONG_BITS > HOST_LONG_BITS */
614
615 void op_dsll (void)
616 {
617     T0 = T0 << T1;
618     FORCE_RET();
619 }
620
621 void op_dsll32 (void)
622 {
623     T0 = T0 << (T1 + 32);
624     FORCE_RET();
625 }
626
627 void op_dsra (void)
628 {
629     T0 = (int64_t)T0 >> T1;
630     FORCE_RET();
631 }
632
633 void op_dsra32 (void)
634 {
635     T0 = (int64_t)T0 >> (T1 + 32);
636     FORCE_RET();
637 }
638
639 void op_dsrl (void)
640 {
641     T0 = T0 >> T1;
642     FORCE_RET();
643 }
644
645 void op_dsrl32 (void)
646 {
647     T0 = T0 >> (T1 + 32);
648     FORCE_RET();
649 }
650
651 void op_drotr (void)
652 {
653     target_ulong tmp;
654
655     if (T1) {
656         tmp = T0 << (0x40 - T1);
657         T0 = (T0 >> T1) | tmp;
658     }
659     FORCE_RET();
660 }
661
662 void op_drotr32 (void)
663 {
664     target_ulong tmp;
665
666     tmp = T0 << (0x40 - (32 + T1));
667     T0 = (T0 >> (32 + T1)) | tmp;
668     FORCE_RET();
669 }
670
671 void op_dsllv (void)
672 {
673     T0 = T1 << (T0 & 0x3F);
674     FORCE_RET();
675 }
676
677 void op_dsrav (void)
678 {
679     T0 = (int64_t)T1 >> (T0 & 0x3F);
680     FORCE_RET();
681 }
682
683 void op_dsrlv (void)
684 {
685     T0 = T1 >> (T0 & 0x3F);
686     FORCE_RET();
687 }
688
689 void op_drotrv (void)
690 {
691     target_ulong tmp;
692
693     T0 &= 0x3F;
694     if (T0) {
695         tmp = T1 << (0x40 - T0);
696         T0 = (T1 >> T0) | tmp;
697     } else
698         T0 = T1;
699     FORCE_RET();
700 }
701
702 void op_dclo (void)
703 {
704     T0 = clo64(T0);
705     FORCE_RET();
706 }
707
708 void op_dclz (void)
709 {
710     T0 = clz64(T0);
711     FORCE_RET();
712 }
713 #endif /* TARGET_LONG_BITS > HOST_LONG_BITS */
714 #endif /* TARGET_MIPS64 */
715
716 /* 64 bits arithmetic */
717 #if TARGET_LONG_BITS > HOST_LONG_BITS
718 void op_mult (void)
719 {
720     CALL_FROM_TB0(do_mult);
721     FORCE_RET();
722 }
723
724 void op_multu (void)
725 {
726     CALL_FROM_TB0(do_multu);
727     FORCE_RET();
728 }
729
730 void op_madd (void)
731 {
732     CALL_FROM_TB0(do_madd);
733     FORCE_RET();
734 }
735
736 void op_maddu (void)
737 {
738     CALL_FROM_TB0(do_maddu);
739     FORCE_RET();
740 }
741
742 void op_msub (void)
743 {
744     CALL_FROM_TB0(do_msub);
745     FORCE_RET();
746 }
747
748 void op_msubu (void)
749 {
750     CALL_FROM_TB0(do_msubu);
751     FORCE_RET();
752 }
753
754 /* Multiplication variants of the vr54xx. */
755 void op_muls (void)
756 {
757     CALL_FROM_TB0(do_muls);
758     FORCE_RET();
759 }
760
761 void op_mulsu (void)
762 {
763     CALL_FROM_TB0(do_mulsu);
764     FORCE_RET();
765 }
766
767 void op_macc (void)
768 {
769     CALL_FROM_TB0(do_macc);
770     FORCE_RET();
771 }
772
773 void op_macchi (void)
774 {
775     CALL_FROM_TB0(do_macchi);
776     FORCE_RET();
777 }
778
779 void op_maccu (void)
780 {
781     CALL_FROM_TB0(do_maccu);
782     FORCE_RET();
783 }
784 void op_macchiu (void)
785 {
786     CALL_FROM_TB0(do_macchiu);
787     FORCE_RET();
788 }
789
790 void op_msac (void)
791 {
792     CALL_FROM_TB0(do_msac);
793     FORCE_RET();
794 }
795
796 void op_msachi (void)
797 {
798     CALL_FROM_TB0(do_msachi);
799     FORCE_RET();
800 }
801
802 void op_msacu (void)
803 {
804     CALL_FROM_TB0(do_msacu);
805     FORCE_RET();
806 }
807
808 void op_msachiu (void)
809 {
810     CALL_FROM_TB0(do_msachiu);
811     FORCE_RET();
812 }
813
814 void op_mulhi (void)
815 {
816     CALL_FROM_TB0(do_mulhi);
817     FORCE_RET();
818 }
819
820 void op_mulhiu (void)
821 {
822     CALL_FROM_TB0(do_mulhiu);
823     FORCE_RET();
824 }
825
826 void op_mulshi (void)
827 {
828     CALL_FROM_TB0(do_mulshi);
829     FORCE_RET();
830 }
831
832 void op_mulshiu (void)
833 {
834     CALL_FROM_TB0(do_mulshiu);
835     FORCE_RET();
836 }
837
838 #else /* TARGET_LONG_BITS > HOST_LONG_BITS */
839
840 static always_inline uint64_t get_HILO (void)
841 {
842     return ((uint64_t)env->HI[env->current_tc][0] << 32) |
843             ((uint64_t)(uint32_t)env->LO[env->current_tc][0]);
844 }
845
846 static always_inline void set_HILO (uint64_t HILO)
847 {
848     env->LO[env->current_tc][0] = (int32_t)(HILO & 0xFFFFFFFF);
849     env->HI[env->current_tc][0] = (int32_t)(HILO >> 32);
850 }
851
852 static always_inline void set_HIT0_LO (uint64_t HILO)
853 {
854     env->LO[env->current_tc][0] = (int32_t)(HILO & 0xFFFFFFFF);
855     T0 = env->HI[env->current_tc][0] = (int32_t)(HILO >> 32);
856 }
857
858 static always_inline void set_HI_LOT0 (uint64_t HILO)
859 {
860     T0 = env->LO[env->current_tc][0] = (int32_t)(HILO & 0xFFFFFFFF);
861     env->HI[env->current_tc][0] = (int32_t)(HILO >> 32);
862 }
863
864 void op_mult (void)
865 {
866     set_HILO((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
867     FORCE_RET();
868 }
869
870 void op_multu (void)
871 {
872     set_HILO((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
873     FORCE_RET();
874 }
875
876 void op_madd (void)
877 {
878     int64_t tmp;
879
880     tmp = ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
881     set_HILO((int64_t)get_HILO() + tmp);
882     FORCE_RET();
883 }
884
885 void op_maddu (void)
886 {
887     uint64_t tmp;
888
889     tmp = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
890     set_HILO(get_HILO() + tmp);
891     FORCE_RET();
892 }
893
894 void op_msub (void)
895 {
896     int64_t tmp;
897
898     tmp = ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
899     set_HILO((int64_t)get_HILO() - tmp);
900     FORCE_RET();
901 }
902
903 void op_msubu (void)
904 {
905     uint64_t tmp;
906
907     tmp = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
908     set_HILO(get_HILO() - tmp);
909     FORCE_RET();
910 }
911
912 /* Multiplication variants of the vr54xx. */
913 void op_muls (void)
914 {
915     set_HI_LOT0(0 - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
916     FORCE_RET();
917 }
918
919 void op_mulsu (void)
920 {
921     set_HI_LOT0(0 - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
922     FORCE_RET();
923 }
924
925 void op_macc (void)
926 {
927     set_HI_LOT0(get_HILO() + ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
928     FORCE_RET();
929 }
930
931 void op_macchi (void)
932 {
933     set_HIT0_LO(get_HILO() + ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
934     FORCE_RET();
935 }
936
937 void op_maccu (void)
938 {
939     set_HI_LOT0(get_HILO() + ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
940     FORCE_RET();
941 }
942
943 void op_macchiu (void)
944 {
945     set_HIT0_LO(get_HILO() + ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
946     FORCE_RET();
947 }
948
949 void op_msac (void)
950 {
951     set_HI_LOT0(get_HILO() - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
952     FORCE_RET();
953 }
954
955 void op_msachi (void)
956 {
957     set_HIT0_LO(get_HILO() - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
958     FORCE_RET();
959 }
960
961 void op_msacu (void)
962 {
963     set_HI_LOT0(get_HILO() - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
964     FORCE_RET();
965 }
966
967 void op_msachiu (void)
968 {
969     set_HIT0_LO(get_HILO() - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
970     FORCE_RET();
971 }
972
973 void op_mulhi (void)
974 {
975     set_HIT0_LO((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
976     FORCE_RET();
977 }
978
979 void op_mulhiu (void)
980 {
981     set_HIT0_LO((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
982     FORCE_RET();
983 }
984
985 void op_mulshi (void)
986 {
987     set_HIT0_LO(0 - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
988     FORCE_RET();
989 }
990
991 void op_mulshiu (void)
992 {
993     set_HIT0_LO(0 - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
994     FORCE_RET();
995 }
996
997 #endif /* TARGET_LONG_BITS > HOST_LONG_BITS */
998
999 #if defined(TARGET_MIPS64)
1000 void op_dmult (void)
1001 {
1002     CALL_FROM_TB4(muls64, &(env->LO[env->current_tc][0]), &(env->HI[env->current_tc][0]), T0, T1);
1003     FORCE_RET();
1004 }
1005
1006 void op_dmultu (void)
1007 {
1008     CALL_FROM_TB4(mulu64, &(env->LO[env->current_tc][0]), &(env->HI[env->current_tc][0]), T0, T1);
1009     FORCE_RET();
1010 }
1011 #endif
1012
1013 /* Conditional moves */
1014 void op_movn (void)
1015 {
1016     if (T1 != 0)
1017         env->gpr[env->current_tc][PARAM1] = T0;
1018     FORCE_RET();
1019 }
1020
1021 void op_movz (void)
1022 {
1023     if (T1 == 0)
1024         env->gpr[env->current_tc][PARAM1] = T0;
1025     FORCE_RET();
1026 }
1027
1028 void op_movf (void)
1029 {
1030     if (!(env->fpu->fcr31 & PARAM1))
1031         T0 = T1;
1032     FORCE_RET();
1033 }
1034
1035 void op_movt (void)
1036 {
1037     if (env->fpu->fcr31 & PARAM1)
1038         T0 = T1;
1039     FORCE_RET();
1040 }
1041
1042 /* Tests */
1043 #define OP_COND(name, cond) \
1044 void glue(op_, name) (void) \
1045 {                           \
1046     if (cond) {             \
1047         T0 = 1;             \
1048     } else {                \
1049         T0 = 0;             \
1050     }                       \
1051     FORCE_RET();            \
1052 }
1053
1054 OP_COND(eq, T0 == T1);
1055 OP_COND(ne, T0 != T1);
1056 OP_COND(ge, (target_long)T0 >= (target_long)T1);
1057 OP_COND(geu, T0 >= T1);
1058 OP_COND(lt, (target_long)T0 < (target_long)T1);
1059 OP_COND(ltu, T0 < T1);
1060 OP_COND(gez, (target_long)T0 >= 0);
1061 OP_COND(gtz, (target_long)T0 > 0);
1062 OP_COND(lez, (target_long)T0 <= 0);
1063 OP_COND(ltz, (target_long)T0 < 0);
1064
1065 /* Branches */
1066 /* Branch to register */
1067 void op_save_breg_target (void)
1068 {
1069     env->btarget = T1;
1070     FORCE_RET();
1071 }
1072
1073 void op_breg (void)
1074 {
1075     env->PC[env->current_tc] = env->btarget;
1076     FORCE_RET();
1077 }
1078
1079 void op_save_btarget (void)
1080 {
1081     env->btarget = PARAM1;
1082     FORCE_RET();
1083 }
1084
1085 #if defined(TARGET_MIPS64)
1086 void op_save_btarget64 (void)
1087 {
1088     env->btarget = ((uint64_t)PARAM1 << 32) | (uint32_t)PARAM2;
1089     FORCE_RET();
1090 }
1091 #endif
1092
1093 /* Conditional branch */
1094 void op_set_bcond (void)
1095 {
1096     env->bcond = T0;
1097     FORCE_RET();
1098 }
1099
1100 void op_jnz_bcond (void)
1101 {
1102     if (env->bcond)
1103         GOTO_LABEL_PARAM(1);
1104     FORCE_RET();
1105 }
1106
1107 /* CP0 functions */
1108 void op_mfc0_index (void)
1109 {
1110     T0 = env->CP0_Index;
1111     FORCE_RET();
1112 }
1113
1114 void op_mfc0_mvpcontrol (void)
1115 {
1116     T0 = env->mvp->CP0_MVPControl;
1117     FORCE_RET();
1118 }
1119
1120 void op_mfc0_mvpconf0 (void)
1121 {
1122     T0 = env->mvp->CP0_MVPConf0;
1123     FORCE_RET();
1124 }
1125
1126 void op_mfc0_mvpconf1 (void)
1127 {
1128     T0 = env->mvp->CP0_MVPConf1;
1129     FORCE_RET();
1130 }
1131
1132 void op_mfc0_random (void)
1133 {
1134     CALL_FROM_TB0(do_mfc0_random);
1135     FORCE_RET();
1136 }
1137
1138 void op_mfc0_vpecontrol (void)
1139 {
1140     T0 = env->CP0_VPEControl;
1141     FORCE_RET();
1142 }
1143
1144 void op_mfc0_vpeconf0 (void)
1145 {
1146     T0 = env->CP0_VPEConf0;
1147     FORCE_RET();
1148 }
1149
1150 void op_mfc0_vpeconf1 (void)
1151 {
1152     T0 = env->CP0_VPEConf1;
1153     FORCE_RET();
1154 }
1155
1156 void op_mfc0_yqmask (void)
1157 {
1158     T0 = env->CP0_YQMask;
1159     FORCE_RET();
1160 }
1161
1162 void op_mfc0_vpeschedule (void)
1163 {
1164     T0 = env->CP0_VPESchedule;
1165     FORCE_RET();
1166 }
1167
1168 void op_mfc0_vpeschefback (void)
1169 {
1170     T0 = env->CP0_VPEScheFBack;
1171     FORCE_RET();
1172 }
1173
1174 void op_mfc0_vpeopt (void)
1175 {
1176     T0 = env->CP0_VPEOpt;
1177     FORCE_RET();
1178 }
1179
1180 void op_mfc0_entrylo0 (void)
1181 {
1182     T0 = (int32_t)env->CP0_EntryLo0;
1183     FORCE_RET();
1184 }
1185
1186 void op_mfc0_tcstatus (void)
1187 {
1188     T0 = env->CP0_TCStatus[env->current_tc];
1189     FORCE_RET();
1190 }
1191
1192 void op_mftc0_tcstatus(void)
1193 {
1194     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1195
1196     T0 = env->CP0_TCStatus[other_tc];
1197     FORCE_RET();
1198 }
1199
1200 void op_mfc0_tcbind (void)
1201 {
1202     T0 = env->CP0_TCBind[env->current_tc];
1203     FORCE_RET();
1204 }
1205
1206 void op_mftc0_tcbind(void)
1207 {
1208     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1209
1210     T0 = env->CP0_TCBind[other_tc];
1211     FORCE_RET();
1212 }
1213
1214 void op_mfc0_tcrestart (void)
1215 {
1216     T0 = env->PC[env->current_tc];
1217     FORCE_RET();
1218 }
1219
1220 void op_mftc0_tcrestart(void)
1221 {
1222     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1223
1224     T0 = env->PC[other_tc];
1225     FORCE_RET();
1226 }
1227
1228 void op_mfc0_tchalt (void)
1229 {
1230     T0 = env->CP0_TCHalt[env->current_tc];
1231     FORCE_RET();
1232 }
1233
1234 void op_mftc0_tchalt(void)
1235 {
1236     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1237
1238     T0 = env->CP0_TCHalt[other_tc];
1239     FORCE_RET();
1240 }
1241
1242 void op_mfc0_tccontext (void)
1243 {
1244     T0 = env->CP0_TCContext[env->current_tc];
1245     FORCE_RET();
1246 }
1247
1248 void op_mftc0_tccontext(void)
1249 {
1250     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1251
1252     T0 = env->CP0_TCContext[other_tc];
1253     FORCE_RET();
1254 }
1255
1256 void op_mfc0_tcschedule (void)
1257 {
1258     T0 = env->CP0_TCSchedule[env->current_tc];
1259     FORCE_RET();
1260 }
1261
1262 void op_mftc0_tcschedule(void)
1263 {
1264     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1265
1266     T0 = env->CP0_TCSchedule[other_tc];
1267     FORCE_RET();
1268 }
1269
1270 void op_mfc0_tcschefback (void)
1271 {
1272     T0 = env->CP0_TCScheFBack[env->current_tc];
1273     FORCE_RET();
1274 }
1275
1276 void op_mftc0_tcschefback(void)
1277 {
1278     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1279
1280     T0 = env->CP0_TCScheFBack[other_tc];
1281     FORCE_RET();
1282 }
1283
1284 void op_mfc0_entrylo1 (void)
1285 {
1286     T0 = (int32_t)env->CP0_EntryLo1;
1287     FORCE_RET();
1288 }
1289
1290 void op_mfc0_context (void)
1291 {
1292     T0 = (int32_t)env->CP0_Context;
1293     FORCE_RET();
1294 }
1295
1296 void op_mfc0_pagemask (void)
1297 {
1298     T0 = env->CP0_PageMask;
1299     FORCE_RET();
1300 }
1301
1302 void op_mfc0_pagegrain (void)
1303 {
1304     T0 = env->CP0_PageGrain;
1305     FORCE_RET();
1306 }
1307
1308 void op_mfc0_wired (void)
1309 {
1310     T0 = env->CP0_Wired;
1311     FORCE_RET();
1312 }
1313
1314 void op_mfc0_srsconf0 (void)
1315 {
1316     T0 = env->CP0_SRSConf0;
1317     FORCE_RET();
1318 }
1319
1320 void op_mfc0_srsconf1 (void)
1321 {
1322     T0 = env->CP0_SRSConf1;
1323     FORCE_RET();
1324 }
1325
1326 void op_mfc0_srsconf2 (void)
1327 {
1328     T0 = env->CP0_SRSConf2;
1329     FORCE_RET();
1330 }
1331
1332 void op_mfc0_srsconf3 (void)
1333 {
1334     T0 = env->CP0_SRSConf3;
1335     FORCE_RET();
1336 }
1337
1338 void op_mfc0_srsconf4 (void)
1339 {
1340     T0 = env->CP0_SRSConf4;
1341     FORCE_RET();
1342 }
1343
1344 void op_mfc0_hwrena (void)
1345 {
1346     T0 = env->CP0_HWREna;
1347     FORCE_RET();
1348 }
1349
1350 void op_mfc0_badvaddr (void)
1351 {
1352     T0 = (int32_t)env->CP0_BadVAddr;
1353     FORCE_RET();
1354 }
1355
1356 void op_mfc0_count (void)
1357 {
1358     CALL_FROM_TB0(do_mfc0_count);
1359     FORCE_RET();
1360 }
1361
1362 void op_mfc0_entryhi (void)
1363 {
1364     T0 = (int32_t)env->CP0_EntryHi;
1365     FORCE_RET();
1366 }
1367
1368 void op_mftc0_entryhi(void)
1369 {
1370     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1371
1372     T0 = (env->CP0_EntryHi & ~0xff) | (env->CP0_TCStatus[other_tc] & 0xff);
1373     FORCE_RET();
1374 }
1375
1376 void op_mfc0_compare (void)
1377 {
1378     T0 = env->CP0_Compare;
1379     FORCE_RET();
1380 }
1381
1382 void op_mfc0_status (void)
1383 {
1384     T0 = env->CP0_Status;
1385     FORCE_RET();
1386 }
1387
1388 void op_mftc0_status(void)
1389 {
1390     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1391     uint32_t tcstatus = env->CP0_TCStatus[other_tc];
1392
1393     T0 = env->CP0_Status & ~0xf1000018;
1394     T0 |= tcstatus & (0xf << CP0TCSt_TCU0);
1395     T0 |= (tcstatus & (1 << CP0TCSt_TMX)) >> (CP0TCSt_TMX - CP0St_MX);
1396     T0 |= (tcstatus & (0x3 << CP0TCSt_TKSU)) >> (CP0TCSt_TKSU - CP0St_KSU);
1397     FORCE_RET();
1398 }
1399
1400 void op_mfc0_intctl (void)
1401 {
1402     T0 = env->CP0_IntCtl;
1403     FORCE_RET();
1404 }
1405
1406 void op_mfc0_srsctl (void)
1407 {
1408     T0 = env->CP0_SRSCtl;
1409     FORCE_RET();
1410 }
1411
1412 void op_mfc0_srsmap (void)
1413 {
1414     T0 = env->CP0_SRSMap;
1415     FORCE_RET();
1416 }
1417
1418 void op_mfc0_cause (void)
1419 {
1420     T0 = env->CP0_Cause;
1421     FORCE_RET();
1422 }
1423
1424 void op_mfc0_epc (void)
1425 {
1426     T0 = (int32_t)env->CP0_EPC;
1427     FORCE_RET();
1428 }
1429
1430 void op_mfc0_prid (void)
1431 {
1432     T0 = env->CP0_PRid;
1433     FORCE_RET();
1434 }
1435
1436 void op_mfc0_ebase (void)
1437 {
1438     T0 = env->CP0_EBase;
1439     FORCE_RET();
1440 }
1441
1442 void op_mfc0_config0 (void)
1443 {
1444     T0 = env->CP0_Config0;
1445     FORCE_RET();
1446 }
1447
1448 void op_mfc0_config1 (void)
1449 {
1450     T0 = env->CP0_Config1;
1451     FORCE_RET();
1452 }
1453
1454 void op_mfc0_config2 (void)
1455 {
1456     T0 = env->CP0_Config2;
1457     FORCE_RET();
1458 }
1459
1460 void op_mfc0_config3 (void)
1461 {
1462     T0 = env->CP0_Config3;
1463     FORCE_RET();
1464 }
1465
1466 void op_mfc0_config6 (void)
1467 {
1468     T0 = env->CP0_Config6;
1469     FORCE_RET();
1470 }
1471
1472 void op_mfc0_config7 (void)
1473 {
1474     T0 = env->CP0_Config7;
1475     FORCE_RET();
1476 }
1477
1478 void op_mfc0_lladdr (void)
1479 {
1480     T0 = (int32_t)env->CP0_LLAddr >> 4;
1481     FORCE_RET();
1482 }
1483
1484 void op_mfc0_watchlo (void)
1485 {
1486     T0 = (int32_t)env->CP0_WatchLo[PARAM1];
1487     FORCE_RET();
1488 }
1489
1490 void op_mfc0_watchhi (void)
1491 {
1492     T0 = env->CP0_WatchHi[PARAM1];
1493     FORCE_RET();
1494 }
1495
1496 void op_mfc0_xcontext (void)
1497 {
1498     T0 = (int32_t)env->CP0_XContext;
1499     FORCE_RET();
1500 }
1501
1502 void op_mfc0_framemask (void)
1503 {
1504     T0 = env->CP0_Framemask;
1505     FORCE_RET();
1506 }
1507
1508 void op_mfc0_debug (void)
1509 {
1510     T0 = env->CP0_Debug;
1511     if (env->hflags & MIPS_HFLAG_DM)
1512         T0 |= 1 << CP0DB_DM;
1513     FORCE_RET();
1514 }
1515
1516 void op_mftc0_debug(void)
1517 {
1518     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1519
1520     /* XXX: Might be wrong, check with EJTAG spec. */
1521     T0 = (env->CP0_Debug & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) |
1522          (env->CP0_Debug_tcstatus[other_tc] &
1523           ((1 << CP0DB_SSt) | (1 << CP0DB_Halt)));
1524     FORCE_RET();
1525 }
1526
1527 void op_mfc0_depc (void)
1528 {
1529     T0 = (int32_t)env->CP0_DEPC;
1530     FORCE_RET();
1531 }
1532
1533 void op_mfc0_performance0 (void)
1534 {
1535     T0 = env->CP0_Performance0;
1536     FORCE_RET();
1537 }
1538
1539 void op_mfc0_taglo (void)
1540 {
1541     T0 = env->CP0_TagLo;
1542     FORCE_RET();
1543 }
1544
1545 void op_mfc0_datalo (void)
1546 {
1547     T0 = env->CP0_DataLo;
1548     FORCE_RET();
1549 }
1550
1551 void op_mfc0_taghi (void)
1552 {
1553     T0 = env->CP0_TagHi;
1554     FORCE_RET();
1555 }
1556
1557 void op_mfc0_datahi (void)
1558 {
1559     T0 = env->CP0_DataHi;
1560     FORCE_RET();
1561 }
1562
1563 void op_mfc0_errorepc (void)
1564 {
1565     T0 = (int32_t)env->CP0_ErrorEPC;
1566     FORCE_RET();
1567 }
1568
1569 void op_mfc0_desave (void)
1570 {
1571     T0 = env->CP0_DESAVE;
1572     FORCE_RET();
1573 }
1574
1575 void op_mtc0_index (void)
1576 {
1577     int num = 1;
1578     unsigned int tmp = env->tlb->nb_tlb;
1579
1580     do {
1581         tmp >>= 1;
1582         num <<= 1;
1583     } while (tmp);
1584     env->CP0_Index = (env->CP0_Index & 0x80000000) | (T0 & (num - 1));
1585     FORCE_RET();
1586 }
1587
1588 void op_mtc0_mvpcontrol (void)
1589 {
1590     uint32_t mask = 0;
1591     uint32_t newval;
1592
1593     if (env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP))
1594         mask |= (1 << CP0MVPCo_CPA) | (1 << CP0MVPCo_VPC) |
1595                 (1 << CP0MVPCo_EVP);
1596     if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
1597         mask |= (1 << CP0MVPCo_STLB);
1598     newval = (env->mvp->CP0_MVPControl & ~mask) | (T0 & mask);
1599
1600     // TODO: Enable/disable shared TLB, enable/disable VPEs.
1601
1602     env->mvp->CP0_MVPControl = newval;
1603     FORCE_RET();
1604 }
1605
1606 void op_mtc0_vpecontrol (void)
1607 {
1608     uint32_t mask;
1609     uint32_t newval;
1610
1611     mask = (1 << CP0VPECo_YSI) | (1 << CP0VPECo_GSI) |
1612            (1 << CP0VPECo_TE) | (0xff << CP0VPECo_TargTC);
1613     newval = (env->CP0_VPEControl & ~mask) | (T0 & mask);
1614
1615     /* Yield scheduler intercept not implemented. */
1616     /* Gating storage scheduler intercept not implemented. */
1617
1618     // TODO: Enable/disable TCs.
1619
1620     env->CP0_VPEControl = newval;
1621     FORCE_RET();
1622 }
1623
1624 void op_mtc0_vpeconf0 (void)
1625 {
1626     uint32_t mask = 0;
1627     uint32_t newval;
1628
1629     if (env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) {
1630         if (env->CP0_VPEConf0 & (1 << CP0VPEC0_VPA))
1631             mask |= (0xff << CP0VPEC0_XTC);
1632         mask |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
1633     }
1634     newval = (env->CP0_VPEConf0 & ~mask) | (T0 & mask);
1635
1636     // TODO: TC exclusive handling due to ERL/EXL.
1637
1638     env->CP0_VPEConf0 = newval;
1639     FORCE_RET();
1640 }
1641
1642 void op_mtc0_vpeconf1 (void)
1643 {
1644     uint32_t mask = 0;
1645     uint32_t newval;
1646
1647     if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
1648         mask |= (0xff << CP0VPEC1_NCX) | (0xff << CP0VPEC1_NCP2) |
1649                 (0xff << CP0VPEC1_NCP1);
1650     newval = (env->CP0_VPEConf1 & ~mask) | (T0 & mask);
1651
1652     /* UDI not implemented. */
1653     /* CP2 not implemented. */
1654
1655     // TODO: Handle FPU (CP1) binding.
1656
1657     env->CP0_VPEConf1 = newval;
1658     FORCE_RET();
1659 }
1660
1661 void op_mtc0_yqmask (void)
1662 {
1663     /* Yield qualifier inputs not implemented. */
1664     env->CP0_YQMask = 0x00000000;
1665     FORCE_RET();
1666 }
1667
1668 void op_mtc0_vpeschedule (void)
1669 {
1670     env->CP0_VPESchedule = T0;
1671     FORCE_RET();
1672 }
1673
1674 void op_mtc0_vpeschefback (void)
1675 {
1676     env->CP0_VPEScheFBack = T0;
1677     FORCE_RET();
1678 }
1679
1680 void op_mtc0_vpeopt (void)
1681 {
1682     env->CP0_VPEOpt = T0 & 0x0000ffff;
1683     FORCE_RET();
1684 }
1685
1686 void op_mtc0_entrylo0 (void)
1687 {
1688     /* Large physaddr (PABITS) not implemented */
1689     /* 1k pages not implemented */
1690     env->CP0_EntryLo0 = T0 & 0x3FFFFFFF;
1691     FORCE_RET();
1692 }
1693
1694 void op_mtc0_tcstatus (void)
1695 {
1696     uint32_t mask = env->CP0_TCStatus_rw_bitmask;
1697     uint32_t newval;
1698
1699     newval = (env->CP0_TCStatus[env->current_tc] & ~mask) | (T0 & mask);
1700
1701     // TODO: Sync with CP0_Status.
1702
1703     env->CP0_TCStatus[env->current_tc] = newval;
1704     FORCE_RET();
1705 }
1706
1707 void op_mttc0_tcstatus (void)
1708 {
1709     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1710
1711     // TODO: Sync with CP0_Status.
1712
1713     env->CP0_TCStatus[other_tc] = T0;
1714     FORCE_RET();
1715 }
1716
1717 void op_mtc0_tcbind (void)
1718 {
1719     uint32_t mask = (1 << CP0TCBd_TBE);
1720     uint32_t newval;
1721
1722     if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
1723         mask |= (1 << CP0TCBd_CurVPE);
1724     newval = (env->CP0_TCBind[env->current_tc] & ~mask) | (T0 & mask);
1725     env->CP0_TCBind[env->current_tc] = newval;
1726     FORCE_RET();
1727 }
1728
1729 void op_mttc0_tcbind (void)
1730 {
1731     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1732     uint32_t mask = (1 << CP0TCBd_TBE);
1733     uint32_t newval;
1734
1735     if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
1736         mask |= (1 << CP0TCBd_CurVPE);
1737     newval = (env->CP0_TCBind[other_tc] & ~mask) | (T0 & mask);
1738     env->CP0_TCBind[other_tc] = newval;
1739     FORCE_RET();
1740 }
1741
1742 void op_mtc0_tcrestart (void)
1743 {
1744     env->PC[env->current_tc] = T0;
1745     env->CP0_TCStatus[env->current_tc] &= ~(1 << CP0TCSt_TDS);
1746     env->CP0_LLAddr = 0ULL;
1747     /* MIPS16 not implemented. */
1748     FORCE_RET();
1749 }
1750
1751 void op_mttc0_tcrestart (void)
1752 {
1753     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1754
1755     env->PC[other_tc] = T0;
1756     env->CP0_TCStatus[other_tc] &= ~(1 << CP0TCSt_TDS);
1757     env->CP0_LLAddr = 0ULL;
1758     /* MIPS16 not implemented. */
1759     FORCE_RET();
1760 }
1761
1762 void op_mtc0_tchalt (void)
1763 {
1764     env->CP0_TCHalt[env->current_tc] = T0 & 0x1;
1765
1766     // TODO: Halt TC / Restart (if allocated+active) TC.
1767
1768     FORCE_RET();
1769 }
1770
1771 void op_mttc0_tchalt (void)
1772 {
1773     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1774
1775     // TODO: Halt TC / Restart (if allocated+active) TC.
1776
1777     env->CP0_TCHalt[other_tc] = T0;
1778     FORCE_RET();
1779 }
1780
1781 void op_mtc0_tccontext (void)
1782 {
1783     env->CP0_TCContext[env->current_tc] = T0;
1784     FORCE_RET();
1785 }
1786
1787 void op_mttc0_tccontext (void)
1788 {
1789     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1790
1791     env->CP0_TCContext[other_tc] = T0;
1792     FORCE_RET();
1793 }
1794
1795 void op_mtc0_tcschedule (void)
1796 {
1797     env->CP0_TCSchedule[env->current_tc] = T0;
1798     FORCE_RET();
1799 }
1800
1801 void op_mttc0_tcschedule (void)
1802 {
1803     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1804
1805     env->CP0_TCSchedule[other_tc] = T0;
1806     FORCE_RET();
1807 }
1808
1809 void op_mtc0_tcschefback (void)
1810 {
1811     env->CP0_TCScheFBack[env->current_tc] = T0;
1812     FORCE_RET();
1813 }
1814
1815 void op_mttc0_tcschefback (void)
1816 {
1817     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1818
1819     env->CP0_TCScheFBack[other_tc] = T0;
1820     FORCE_RET();
1821 }
1822
1823 void op_mtc0_entrylo1 (void)
1824 {
1825     /* Large physaddr (PABITS) not implemented */
1826     /* 1k pages not implemented */
1827     env->CP0_EntryLo1 = T0 & 0x3FFFFFFF;
1828     FORCE_RET();
1829 }
1830
1831 void op_mtc0_context (void)
1832 {
1833     env->CP0_Context = (env->CP0_Context & 0x007FFFFF) | (T0 & ~0x007FFFFF);
1834     FORCE_RET();
1835 }
1836
1837 void op_mtc0_pagemask (void)
1838 {
1839     /* 1k pages not implemented */
1840     env->CP0_PageMask = T0 & (0x1FFFFFFF & (TARGET_PAGE_MASK << 1));
1841     FORCE_RET();
1842 }
1843
1844 void op_mtc0_pagegrain (void)
1845 {
1846     /* SmartMIPS not implemented */
1847     /* Large physaddr (PABITS) not implemented */
1848     /* 1k pages not implemented */
1849     env->CP0_PageGrain = 0;
1850     FORCE_RET();
1851 }
1852
1853 void op_mtc0_wired (void)
1854 {
1855     env->CP0_Wired = T0 % env->tlb->nb_tlb;
1856     FORCE_RET();
1857 }
1858
1859 void op_mtc0_srsconf0 (void)
1860 {
1861     env->CP0_SRSConf0 |= T0 & env->CP0_SRSConf0_rw_bitmask;
1862     FORCE_RET();
1863 }
1864
1865 void op_mtc0_srsconf1 (void)
1866 {
1867     env->CP0_SRSConf1 |= T0 & env->CP0_SRSConf1_rw_bitmask;
1868     FORCE_RET();
1869 }
1870
1871 void op_mtc0_srsconf2 (void)
1872 {
1873     env->CP0_SRSConf2 |= T0 & env->CP0_SRSConf2_rw_bitmask;
1874     FORCE_RET();
1875 }
1876
1877 void op_mtc0_srsconf3 (void)
1878 {
1879     env->CP0_SRSConf3 |= T0 & env->CP0_SRSConf3_rw_bitmask;
1880     FORCE_RET();
1881 }
1882
1883 void op_mtc0_srsconf4 (void)
1884 {
1885     env->CP0_SRSConf4 |= T0 & env->CP0_SRSConf4_rw_bitmask;
1886     FORCE_RET();
1887 }
1888
1889 void op_mtc0_hwrena (void)
1890 {
1891     env->CP0_HWREna = T0 & 0x0000000F;
1892     FORCE_RET();
1893 }
1894
1895 void op_mtc0_count (void)
1896 {
1897     CALL_FROM_TB2(cpu_mips_store_count, env, T0);
1898     FORCE_RET();
1899 }
1900
1901 void op_mtc0_entryhi (void)
1902 {
1903     target_ulong old, val;
1904
1905     /* 1k pages not implemented */
1906     val = T0 & ((TARGET_PAGE_MASK << 1) | 0xFF);
1907 #if defined(TARGET_MIPS64)
1908     val &= env->SEGMask;
1909 #endif
1910     old = env->CP0_EntryHi;
1911     env->CP0_EntryHi = val;
1912     if (env->CP0_Config3 & (1 << CP0C3_MT)) {
1913         uint32_t tcst = env->CP0_TCStatus[env->current_tc] & ~0xff;
1914         env->CP0_TCStatus[env->current_tc] = tcst | (val & 0xff);
1915     }
1916     /* If the ASID changes, flush qemu's TLB.  */
1917     if ((old & 0xFF) != (val & 0xFF))
1918         CALL_FROM_TB2(cpu_mips_tlb_flush, env, 1);
1919     FORCE_RET();
1920 }
1921
1922 void op_mttc0_entryhi(void)
1923 {
1924     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1925
1926     env->CP0_EntryHi = (env->CP0_EntryHi & 0xff) | (T0 & ~0xff);
1927     env->CP0_TCStatus[other_tc] = (env->CP0_TCStatus[other_tc] & ~0xff) | (T0 & 0xff);
1928     FORCE_RET();
1929 }
1930
1931 void op_mtc0_compare (void)
1932 {
1933     CALL_FROM_TB2(cpu_mips_store_compare, env, T0);
1934     FORCE_RET();
1935 }
1936
1937 void op_mtc0_status (void)
1938 {
1939     uint32_t val, old;
1940     uint32_t mask = env->CP0_Status_rw_bitmask;
1941
1942     val = T0 & mask;
1943     old = env->CP0_Status;
1944     env->CP0_Status = (env->CP0_Status & ~mask) | val;
1945     CALL_FROM_TB1(compute_hflags, env);
1946     if (loglevel & CPU_LOG_EXEC)
1947         CALL_FROM_TB2(do_mtc0_status_debug, old, val);
1948     CALL_FROM_TB1(cpu_mips_update_irq, env);
1949     FORCE_RET();
1950 }
1951
1952 void op_mttc0_status(void)
1953 {
1954     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1955     uint32_t tcstatus = env->CP0_TCStatus[other_tc];
1956
1957     env->CP0_Status = T0 & ~0xf1000018;
1958     tcstatus = (tcstatus & ~(0xf << CP0TCSt_TCU0)) | (T0 & (0xf << CP0St_CU0));
1959     tcstatus = (tcstatus & ~(1 << CP0TCSt_TMX)) | ((T0 & (1 << CP0St_MX)) << (CP0TCSt_TMX - CP0St_MX));
1960     tcstatus = (tcstatus & ~(0x3 << CP0TCSt_TKSU)) | ((T0 & (0x3 << CP0St_KSU)) << (CP0TCSt_TKSU - CP0St_KSU));
1961     env->CP0_TCStatus[other_tc] = tcstatus;
1962     FORCE_RET();
1963 }
1964
1965 void op_mtc0_intctl (void)
1966 {
1967     /* vectored interrupts not implemented, no performance counters. */
1968     env->CP0_IntCtl = (env->CP0_IntCtl & ~0x000002e0) | (T0 & 0x000002e0);
1969     FORCE_RET();
1970 }
1971
1972 void op_mtc0_srsctl (void)
1973 {
1974     uint32_t mask = (0xf << CP0SRSCtl_ESS) | (0xf << CP0SRSCtl_PSS);
1975     env->CP0_SRSCtl = (env->CP0_SRSCtl & ~mask) | (T0 & mask);
1976     FORCE_RET();
1977 }
1978
1979 void op_mtc0_srsmap (void)
1980 {
1981     env->CP0_SRSMap = T0;
1982     FORCE_RET();
1983 }
1984
1985 void op_mtc0_cause (void)
1986 {
1987     uint32_t mask = 0x00C00300;
1988     uint32_t old = env->CP0_Cause;
1989
1990     if (env->insn_flags & ISA_MIPS32R2)
1991         mask |= 1 << CP0Ca_DC;
1992
1993     env->CP0_Cause = (env->CP0_Cause & ~mask) | (T0 & mask);
1994
1995     if ((old ^ env->CP0_Cause) & (1 << CP0Ca_DC)) {
1996         if (env->CP0_Cause & (1 << CP0Ca_DC))
1997             CALL_FROM_TB1(cpu_mips_stop_count, env);
1998         else
1999             CALL_FROM_TB1(cpu_mips_start_count, env);
2000     }
2001
2002     /* Handle the software interrupt as an hardware one, as they
2003        are very similar */
2004     if (T0 & CP0Ca_IP_mask) {
2005         CALL_FROM_TB1(cpu_mips_update_irq, env);
2006     }
2007     FORCE_RET();
2008 }
2009
2010 void op_mtc0_epc (void)
2011 {
2012     env->CP0_EPC = T0;
2013     FORCE_RET();
2014 }
2015
2016 void op_mtc0_ebase (void)
2017 {
2018     /* vectored interrupts not implemented */
2019     /* Multi-CPU not implemented */
2020     env->CP0_EBase = 0x80000000 | (T0 & 0x3FFFF000);
2021     FORCE_RET();
2022 }
2023
2024 void op_mtc0_config0 (void)
2025 {
2026     env->CP0_Config0 = (env->CP0_Config0 & 0x81FFFFF8) | (T0 & 0x00000007);
2027     FORCE_RET();
2028 }
2029
2030 void op_mtc0_config2 (void)
2031 {
2032     /* tertiary/secondary caches not implemented */
2033     env->CP0_Config2 = (env->CP0_Config2 & 0x8FFF0FFF);
2034     FORCE_RET();
2035 }
2036
2037 void op_mtc0_watchlo (void)
2038 {
2039     /* Watch exceptions for instructions, data loads, data stores
2040        not implemented. */
2041     env->CP0_WatchLo[PARAM1] = (T0 & ~0x7);
2042     FORCE_RET();
2043 }
2044
2045 void op_mtc0_watchhi (void)
2046 {
2047     env->CP0_WatchHi[PARAM1] = (T0 & 0x40FF0FF8);
2048     env->CP0_WatchHi[PARAM1] &= ~(env->CP0_WatchHi[PARAM1] & T0 & 0x7);
2049     FORCE_RET();
2050 }
2051
2052 void op_mtc0_xcontext (void)
2053 {
2054     target_ulong mask = (1ULL << (env->SEGBITS - 7)) - 1;
2055     env->CP0_XContext = (env->CP0_XContext & mask) | (T0 & ~mask);
2056     FORCE_RET();
2057 }
2058
2059 void op_mtc0_framemask (void)
2060 {
2061     env->CP0_Framemask = T0; /* XXX */
2062     FORCE_RET();
2063 }
2064
2065 void op_mtc0_debug (void)
2066 {
2067     env->CP0_Debug = (env->CP0_Debug & 0x8C03FC1F) | (T0 & 0x13300120);
2068     if (T0 & (1 << CP0DB_DM))
2069         env->hflags |= MIPS_HFLAG_DM;
2070     else
2071         env->hflags &= ~MIPS_HFLAG_DM;
2072     FORCE_RET();
2073 }
2074
2075 void op_mttc0_debug(void)
2076 {
2077     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2078
2079     /* XXX: Might be wrong, check with EJTAG spec. */
2080     env->CP0_Debug_tcstatus[other_tc] = T0 & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt));
2081     env->CP0_Debug = (env->CP0_Debug & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) |
2082                      (T0 & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt)));
2083     FORCE_RET();
2084 }
2085
2086 void op_mtc0_depc (void)
2087 {
2088     env->CP0_DEPC = T0;
2089     FORCE_RET();
2090 }
2091
2092 void op_mtc0_performance0 (void)
2093 {
2094     env->CP0_Performance0 = T0 & 0x000007ff;
2095     FORCE_RET();
2096 }
2097
2098 void op_mtc0_taglo (void)
2099 {
2100     env->CP0_TagLo = T0 & 0xFFFFFCF6;
2101     FORCE_RET();
2102 }
2103
2104 void op_mtc0_datalo (void)
2105 {
2106     env->CP0_DataLo = T0; /* XXX */
2107     FORCE_RET();
2108 }
2109
2110 void op_mtc0_taghi (void)
2111 {
2112     env->CP0_TagHi = T0; /* XXX */
2113     FORCE_RET();
2114 }
2115
2116 void op_mtc0_datahi (void)
2117 {
2118     env->CP0_DataHi = T0; /* XXX */
2119     FORCE_RET();
2120 }
2121
2122 void op_mtc0_errorepc (void)
2123 {
2124     env->CP0_ErrorEPC = T0;
2125     FORCE_RET();
2126 }
2127
2128 void op_mtc0_desave (void)
2129 {
2130     env->CP0_DESAVE = T0;
2131     FORCE_RET();
2132 }
2133
2134 #if defined(TARGET_MIPS64)
2135 void op_dmfc0_yqmask (void)
2136 {
2137     T0 = env->CP0_YQMask;
2138     FORCE_RET();
2139 }
2140
2141 void op_dmfc0_vpeschedule (void)
2142 {
2143     T0 = env->CP0_VPESchedule;
2144     FORCE_RET();
2145 }
2146
2147 void op_dmfc0_vpeschefback (void)
2148 {
2149     T0 = env->CP0_VPEScheFBack;
2150     FORCE_RET();
2151 }
2152
2153 void op_dmfc0_entrylo0 (void)
2154 {
2155     T0 = env->CP0_EntryLo0;
2156     FORCE_RET();
2157 }
2158
2159 void op_dmfc0_tcrestart (void)
2160 {
2161     T0 = env->PC[env->current_tc];
2162     FORCE_RET();
2163 }
2164
2165 void op_dmfc0_tchalt (void)
2166 {
2167     T0 = env->CP0_TCHalt[env->current_tc];
2168     FORCE_RET();
2169 }
2170
2171 void op_dmfc0_tccontext (void)
2172 {
2173     T0 = env->CP0_TCContext[env->current_tc];
2174     FORCE_RET();
2175 }
2176
2177 void op_dmfc0_tcschedule (void)
2178 {
2179     T0 = env->CP0_TCSchedule[env->current_tc];
2180     FORCE_RET();
2181 }
2182
2183 void op_dmfc0_tcschefback (void)
2184 {
2185     T0 = env->CP0_TCScheFBack[env->current_tc];
2186     FORCE_RET();
2187 }
2188
2189 void op_dmfc0_entrylo1 (void)
2190 {
2191     T0 = env->CP0_EntryLo1;
2192     FORCE_RET();
2193 }
2194
2195 void op_dmfc0_context (void)
2196 {
2197     T0 = env->CP0_Context;
2198     FORCE_RET();
2199 }
2200
2201 void op_dmfc0_badvaddr (void)
2202 {
2203     T0 = env->CP0_BadVAddr;
2204     FORCE_RET();
2205 }
2206
2207 void op_dmfc0_entryhi (void)
2208 {
2209     T0 = env->CP0_EntryHi;
2210     FORCE_RET();
2211 }
2212
2213 void op_dmfc0_epc (void)
2214 {
2215     T0 = env->CP0_EPC;
2216     FORCE_RET();
2217 }
2218
2219 void op_dmfc0_lladdr (void)
2220 {
2221     T0 = env->CP0_LLAddr >> 4;
2222     FORCE_RET();
2223 }
2224
2225 void op_dmfc0_watchlo (void)
2226 {
2227     T0 = env->CP0_WatchLo[PARAM1];
2228     FORCE_RET();
2229 }
2230
2231 void op_dmfc0_xcontext (void)
2232 {
2233     T0 = env->CP0_XContext;
2234     FORCE_RET();
2235 }
2236
2237 void op_dmfc0_depc (void)
2238 {
2239     T0 = env->CP0_DEPC;
2240     FORCE_RET();
2241 }
2242
2243 void op_dmfc0_errorepc (void)
2244 {
2245     T0 = env->CP0_ErrorEPC;
2246     FORCE_RET();
2247 }
2248 #endif /* TARGET_MIPS64 */
2249
2250 /* MIPS MT functions */
2251 void op_mftgpr(void)
2252 {
2253     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2254
2255     T0 = env->gpr[other_tc][PARAM1];
2256     FORCE_RET();
2257 }
2258
2259 void op_mftlo(void)
2260 {
2261     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2262
2263     T0 = env->LO[other_tc][PARAM1];
2264     FORCE_RET();
2265 }
2266
2267 void op_mfthi(void)
2268 {
2269     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2270
2271     T0 = env->HI[other_tc][PARAM1];
2272     FORCE_RET();
2273 }
2274
2275 void op_mftacx(void)
2276 {
2277     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2278
2279     T0 = env->ACX[other_tc][PARAM1];
2280     FORCE_RET();
2281 }
2282
2283 void op_mftdsp(void)
2284 {
2285     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2286
2287     T0 = env->DSPControl[other_tc];
2288     FORCE_RET();
2289 }
2290
2291 void op_mttgpr(void)
2292 {
2293     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2294
2295     T0 = env->gpr[other_tc][PARAM1];
2296     FORCE_RET();
2297 }
2298
2299 void op_mttlo(void)
2300 {
2301     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2302
2303     T0 = env->LO[other_tc][PARAM1];
2304     FORCE_RET();
2305 }
2306
2307 void op_mtthi(void)
2308 {
2309     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2310
2311     T0 = env->HI[other_tc][PARAM1];
2312     FORCE_RET();
2313 }
2314
2315 void op_mttacx(void)
2316 {
2317     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2318
2319     T0 = env->ACX[other_tc][PARAM1];
2320     FORCE_RET();
2321 }
2322
2323 void op_mttdsp(void)
2324 {
2325     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2326
2327     T0 = env->DSPControl[other_tc];
2328     FORCE_RET();
2329 }
2330
2331
2332 void op_dmt(void)
2333 {
2334     // TODO
2335     T0 = 0;
2336     // rt = T0
2337     FORCE_RET();
2338 }
2339
2340 void op_emt(void)
2341 {
2342     // TODO
2343     T0 = 0;
2344     // rt = T0
2345     FORCE_RET();
2346 }
2347
2348 void op_dvpe(void)
2349 {
2350     // TODO
2351     T0 = 0;
2352     // rt = T0
2353     FORCE_RET();
2354 }
2355
2356 void op_evpe(void)
2357 {
2358     // TODO
2359     T0 = 0;
2360     // rt = T0
2361     FORCE_RET();
2362 }
2363
2364 void op_fork(void)
2365 {
2366     // T0 = rt, T1 = rs
2367     T0 = 0;
2368     // TODO: store to TC register
2369     FORCE_RET();
2370 }
2371
2372 void op_yield(void)
2373 {
2374     if (T0 < 0) {
2375         /* No scheduling policy implemented. */
2376         if (T0 != -2) {
2377             if (env->CP0_VPEControl & (1 << CP0VPECo_YSI) &&
2378                 env->CP0_TCStatus[env->current_tc] & (1 << CP0TCSt_DT)) {
2379                 env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT);
2380                 env->CP0_VPEControl |= 4 << CP0VPECo_EXCPT;
2381                 CALL_FROM_TB1(do_raise_exception, EXCP_THREAD);
2382             }
2383         }
2384     } else if (T0 == 0) {
2385         if (0 /* TODO: TC underflow */) {
2386             env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT);
2387             CALL_FROM_TB1(do_raise_exception, EXCP_THREAD);
2388         } else {
2389             // TODO: Deallocate TC
2390         }
2391     } else if (T0 > 0) {
2392         /* Yield qualifier inputs not implemented. */
2393         env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT);
2394         env->CP0_VPEControl |= 2 << CP0VPECo_EXCPT;
2395         CALL_FROM_TB1(do_raise_exception, EXCP_THREAD);
2396     }
2397     T0 = env->CP0_YQMask;
2398     FORCE_RET();
2399 }
2400
2401 /* CP1 functions */
2402 #if 0
2403 # define DEBUG_FPU_STATE() CALL_FROM_TB1(dump_fpu, env)
2404 #else
2405 # define DEBUG_FPU_STATE() do { } while(0)
2406 #endif
2407
2408 void op_cfc1 (void)
2409 {
2410     CALL_FROM_TB1(do_cfc1, PARAM1);
2411     DEBUG_FPU_STATE();
2412     FORCE_RET();
2413 }
2414
2415 void op_ctc1 (void)
2416 {
2417     CALL_FROM_TB1(do_ctc1, PARAM1);
2418     DEBUG_FPU_STATE();
2419     FORCE_RET();
2420 }
2421
2422 void op_mfc1 (void)
2423 {
2424     T0 = (int32_t)WT0;
2425     DEBUG_FPU_STATE();
2426     FORCE_RET();
2427 }
2428
2429 void op_mtc1 (void)
2430 {
2431     WT0 = T0;
2432     DEBUG_FPU_STATE();
2433     FORCE_RET();
2434 }
2435
2436 void op_dmfc1 (void)
2437 {
2438     T0 = DT0;
2439     DEBUG_FPU_STATE();
2440     FORCE_RET();
2441 }
2442
2443 void op_dmtc1 (void)
2444 {
2445     DT0 = T0;
2446     DEBUG_FPU_STATE();
2447     FORCE_RET();
2448 }
2449
2450 void op_mfhc1 (void)
2451 {
2452     T0 = (int32_t)WTH0;
2453     DEBUG_FPU_STATE();
2454     FORCE_RET();
2455 }
2456
2457 void op_mthc1 (void)
2458 {
2459     WTH0 = T0;
2460     DEBUG_FPU_STATE();
2461     FORCE_RET();
2462 }
2463
2464 /* Float support.
2465    Single precition routines have a "s" suffix, double precision a
2466    "d" suffix, 32bit integer "w", 64bit integer "l", paired singe "ps",
2467    paired single lowwer "pl", paired single upper "pu".  */
2468
2469 #define FLOAT_OP(name, p) void OPPROTO op_float_##name##_##p(void)
2470
2471 FLOAT_OP(cvtd, s)
2472 {
2473     CALL_FROM_TB0(do_float_cvtd_s);
2474     DEBUG_FPU_STATE();
2475     FORCE_RET();
2476 }
2477 FLOAT_OP(cvtd, w)
2478 {
2479     CALL_FROM_TB0(do_float_cvtd_w);
2480     DEBUG_FPU_STATE();
2481     FORCE_RET();
2482 }
2483 FLOAT_OP(cvtd, l)
2484 {
2485     CALL_FROM_TB0(do_float_cvtd_l);
2486     DEBUG_FPU_STATE();
2487     FORCE_RET();
2488 }
2489 FLOAT_OP(cvtl, d)
2490 {
2491     CALL_FROM_TB0(do_float_cvtl_d);
2492     DEBUG_FPU_STATE();
2493     FORCE_RET();
2494 }
2495 FLOAT_OP(cvtl, s)
2496 {
2497     CALL_FROM_TB0(do_float_cvtl_s);
2498     DEBUG_FPU_STATE();
2499     FORCE_RET();
2500 }
2501 FLOAT_OP(cvtps, s)
2502 {
2503     WT2 = WT0;
2504     WTH2 = WT1;
2505     DEBUG_FPU_STATE();
2506     FORCE_RET();
2507 }
2508 FLOAT_OP(cvtps, pw)
2509 {
2510     CALL_FROM_TB0(do_float_cvtps_pw);
2511     DEBUG_FPU_STATE();
2512     FORCE_RET();
2513 }
2514 FLOAT_OP(cvtpw, ps)
2515 {
2516     CALL_FROM_TB0(do_float_cvtpw_ps);
2517     DEBUG_FPU_STATE();
2518     FORCE_RET();
2519 }
2520 FLOAT_OP(cvts, d)
2521 {
2522     CALL_FROM_TB0(do_float_cvts_d);
2523     DEBUG_FPU_STATE();
2524     FORCE_RET();
2525 }
2526 FLOAT_OP(cvts, w)
2527 {
2528     CALL_FROM_TB0(do_float_cvts_w);
2529     DEBUG_FPU_STATE();
2530     FORCE_RET();
2531 }
2532 FLOAT_OP(cvts, l)
2533 {
2534     CALL_FROM_TB0(do_float_cvts_l);
2535     DEBUG_FPU_STATE();
2536     FORCE_RET();
2537 }
2538 FLOAT_OP(cvts, pl)
2539 {
2540     CALL_FROM_TB0(do_float_cvts_pl);
2541     DEBUG_FPU_STATE();
2542     FORCE_RET();
2543 }
2544 FLOAT_OP(cvts, pu)
2545 {
2546     CALL_FROM_TB0(do_float_cvts_pu);
2547     DEBUG_FPU_STATE();
2548     FORCE_RET();
2549 }
2550 FLOAT_OP(cvtw, s)
2551 {
2552     CALL_FROM_TB0(do_float_cvtw_s);
2553     DEBUG_FPU_STATE();
2554     FORCE_RET();
2555 }
2556 FLOAT_OP(cvtw, d)
2557 {
2558     CALL_FROM_TB0(do_float_cvtw_d);
2559     DEBUG_FPU_STATE();
2560     FORCE_RET();
2561 }
2562
2563 FLOAT_OP(pll, ps)
2564 {
2565     DT2 = ((uint64_t)WT0 << 32) | WT1;
2566     DEBUG_FPU_STATE();
2567     FORCE_RET();
2568 }
2569 FLOAT_OP(plu, ps)
2570 {
2571     DT2 = ((uint64_t)WT0 << 32) | WTH1;
2572     DEBUG_FPU_STATE();
2573     FORCE_RET();
2574 }
2575 FLOAT_OP(pul, ps)
2576 {
2577     DT2 = ((uint64_t)WTH0 << 32) | WT1;
2578     DEBUG_FPU_STATE();
2579     FORCE_RET();
2580 }
2581 FLOAT_OP(puu, ps)
2582 {
2583     DT2 = ((uint64_t)WTH0 << 32) | WTH1;
2584     DEBUG_FPU_STATE();
2585     FORCE_RET();
2586 }
2587
2588 #define FLOAT_ROUNDOP(op, ttype, stype)                    \
2589 FLOAT_OP(op ## ttype, stype)                               \
2590 {                                                          \
2591     CALL_FROM_TB0(do_float_ ## op ## ttype ## _ ## stype); \
2592     DEBUG_FPU_STATE();                                     \
2593     FORCE_RET();                                           \
2594 }
2595
2596 FLOAT_ROUNDOP(round, l, d)
2597 FLOAT_ROUNDOP(round, l, s)
2598 FLOAT_ROUNDOP(round, w, d)
2599 FLOAT_ROUNDOP(round, w, s)
2600
2601 FLOAT_ROUNDOP(trunc, l, d)
2602 FLOAT_ROUNDOP(trunc, l, s)
2603 FLOAT_ROUNDOP(trunc, w, d)
2604 FLOAT_ROUNDOP(trunc, w, s)
2605
2606 FLOAT_ROUNDOP(ceil, l, d)
2607 FLOAT_ROUNDOP(ceil, l, s)
2608 FLOAT_ROUNDOP(ceil, w, d)
2609 FLOAT_ROUNDOP(ceil, w, s)
2610
2611 FLOAT_ROUNDOP(floor, l, d)
2612 FLOAT_ROUNDOP(floor, l, s)
2613 FLOAT_ROUNDOP(floor, w, d)
2614 FLOAT_ROUNDOP(floor, w, s)
2615 #undef FLOAR_ROUNDOP
2616
2617 FLOAT_OP(movf, d)
2618 {
2619     if (!(env->fpu->fcr31 & PARAM1))
2620         DT2 = DT0;
2621     DEBUG_FPU_STATE();
2622     FORCE_RET();
2623 }
2624 FLOAT_OP(movf, s)
2625 {
2626     if (!(env->fpu->fcr31 & PARAM1))
2627         WT2 = WT0;
2628     DEBUG_FPU_STATE();
2629     FORCE_RET();
2630 }
2631 FLOAT_OP(movf, ps)
2632 {
2633     if (!(env->fpu->fcr31 & PARAM1)) {
2634         WT2 = WT0;
2635         WTH2 = WTH0;
2636     }
2637     DEBUG_FPU_STATE();
2638     FORCE_RET();
2639 }
2640 FLOAT_OP(movt, d)
2641 {
2642     if (env->fpu->fcr31 & PARAM1)
2643         DT2 = DT0;
2644     DEBUG_FPU_STATE();
2645     FORCE_RET();
2646 }
2647 FLOAT_OP(movt, s)
2648 {
2649     if (env->fpu->fcr31 & PARAM1)
2650         WT2 = WT0;
2651     DEBUG_FPU_STATE();
2652     FORCE_RET();
2653 }
2654 FLOAT_OP(movt, ps)
2655 {
2656     if (env->fpu->fcr31 & PARAM1) {
2657         WT2 = WT0;
2658         WTH2 = WTH0;
2659     }
2660     DEBUG_FPU_STATE();
2661     FORCE_RET();
2662 }
2663 FLOAT_OP(movz, d)
2664 {
2665     if (!T0)
2666         DT2 = DT0;
2667     DEBUG_FPU_STATE();
2668     FORCE_RET();
2669 }
2670 FLOAT_OP(movz, s)
2671 {
2672     if (!T0)
2673         WT2 = WT0;
2674     DEBUG_FPU_STATE();
2675     FORCE_RET();
2676 }
2677 FLOAT_OP(movz, ps)
2678 {
2679     if (!T0) {
2680         WT2 = WT0;
2681         WTH2 = WTH0;
2682     }
2683     DEBUG_FPU_STATE();
2684     FORCE_RET();
2685 }
2686 FLOAT_OP(movn, d)
2687 {
2688     if (T0)
2689         DT2 = DT0;
2690     DEBUG_FPU_STATE();
2691     FORCE_RET();
2692 }
2693 FLOAT_OP(movn, s)
2694 {
2695     if (T0)
2696         WT2 = WT0;
2697     DEBUG_FPU_STATE();
2698     FORCE_RET();
2699 }
2700 FLOAT_OP(movn, ps)
2701 {
2702     if (T0) {
2703         WT2 = WT0;
2704         WTH2 = WTH0;
2705     }
2706     DEBUG_FPU_STATE();
2707     FORCE_RET();
2708 }
2709
2710 /* operations calling helpers, for s, d and ps */
2711 #define FLOAT_HOP(name)   \
2712 FLOAT_OP(name, d)         \
2713 {                         \
2714     CALL_FROM_TB0(do_float_ ## name ## _d);  \
2715     DEBUG_FPU_STATE();    \
2716     FORCE_RET();          \
2717 }                         \
2718 FLOAT_OP(name, s)         \
2719 {                         \
2720     CALL_FROM_TB0(do_float_ ## name ## _s);  \
2721     DEBUG_FPU_STATE();    \
2722     FORCE_RET();          \
2723 }                         \
2724 FLOAT_OP(name, ps)        \
2725 {                         \
2726     CALL_FROM_TB0(do_float_ ## name ## _ps); \
2727     DEBUG_FPU_STATE();    \
2728     FORCE_RET();          \
2729 }
2730 FLOAT_HOP(add)
2731 FLOAT_HOP(sub)
2732 FLOAT_HOP(mul)
2733 FLOAT_HOP(div)
2734 FLOAT_HOP(recip2)
2735 FLOAT_HOP(rsqrt2)
2736 FLOAT_HOP(rsqrt1)
2737 FLOAT_HOP(recip1)
2738 #undef FLOAT_HOP
2739
2740 /* operations calling helpers, for s and d */
2741 #define FLOAT_HOP(name)   \
2742 FLOAT_OP(name, d)         \
2743 {                         \
2744     CALL_FROM_TB0(do_float_ ## name ## _d);  \
2745     DEBUG_FPU_STATE();    \
2746     FORCE_RET();          \
2747 }                         \
2748 FLOAT_OP(name, s)         \
2749 {                         \
2750     CALL_FROM_TB0(do_float_ ## name ## _s);  \
2751     DEBUG_FPU_STATE();    \
2752     FORCE_RET();          \
2753 }
2754 FLOAT_HOP(rsqrt)
2755 FLOAT_HOP(recip)
2756 #undef FLOAT_HOP
2757
2758 /* operations calling helpers, for ps */
2759 #define FLOAT_HOP(name)   \
2760 FLOAT_OP(name, ps)        \
2761 {                         \
2762     CALL_FROM_TB0(do_float_ ## name ## _ps); \
2763     DEBUG_FPU_STATE();    \
2764     FORCE_RET();          \
2765 }
2766 FLOAT_HOP(addr)
2767 FLOAT_HOP(mulr)
2768 #undef FLOAT_HOP
2769
2770 /* ternary operations */
2771 #define FLOAT_TERNOP(name1, name2) \
2772 FLOAT_OP(name1 ## name2, d)        \
2773 {                                  \
2774     FDT0 = float64_ ## name1 (FDT0, FDT1, &env->fpu->fp_status);    \
2775     FDT2 = float64_ ## name2 (FDT0, FDT2, &env->fpu->fp_status);    \
2776     DEBUG_FPU_STATE();             \
2777     FORCE_RET();                   \
2778 }                                  \
2779 FLOAT_OP(name1 ## name2, s)        \
2780 {                                  \
2781     FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status);    \
2782     FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status);    \
2783     DEBUG_FPU_STATE();             \
2784     FORCE_RET();                   \
2785 }                                  \
2786 FLOAT_OP(name1 ## name2, ps)       \
2787 {                                  \
2788     FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status);    \
2789     FSTH0 = float32_ ## name1 (FSTH0, FSTH1, &env->fpu->fp_status); \
2790     FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status);    \
2791     FSTH2 = float32_ ## name2 (FSTH0, FSTH2, &env->fpu->fp_status); \
2792     DEBUG_FPU_STATE();             \
2793     FORCE_RET();                   \
2794 }
2795 FLOAT_TERNOP(mul, add)
2796 FLOAT_TERNOP(mul, sub)
2797 #undef FLOAT_TERNOP
2798
2799 /* negated ternary operations */
2800 #define FLOAT_NTERNOP(name1, name2) \
2801 FLOAT_OP(n ## name1 ## name2, d)    \
2802 {                                   \
2803     FDT0 = float64_ ## name1 (FDT0, FDT1, &env->fpu->fp_status);    \
2804     FDT2 = float64_ ## name2 (FDT0, FDT2, &env->fpu->fp_status);    \
2805     FDT2 = float64_chs(FDT2);       \
2806     DEBUG_FPU_STATE();              \
2807     FORCE_RET();                    \
2808 }                                   \
2809 FLOAT_OP(n ## name1 ## name2, s)    \
2810 {                                   \
2811     FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status);    \
2812     FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status);    \
2813     FST2 = float32_chs(FST2);       \
2814     DEBUG_FPU_STATE();              \
2815     FORCE_RET();                    \
2816 }                                   \
2817 FLOAT_OP(n ## name1 ## name2, ps)   \
2818 {                                   \
2819     FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status);    \
2820     FSTH0 = float32_ ## name1 (FSTH0, FSTH1, &env->fpu->fp_status); \
2821     FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status);    \
2822     FSTH2 = float32_ ## name2 (FSTH0, FSTH2, &env->fpu->fp_status); \
2823     FST2 = float32_chs(FST2);       \
2824     FSTH2 = float32_chs(FSTH2);     \
2825     DEBUG_FPU_STATE();              \
2826     FORCE_RET();                    \
2827 }
2828 FLOAT_NTERNOP(mul, add)
2829 FLOAT_NTERNOP(mul, sub)
2830 #undef FLOAT_NTERNOP
2831
2832 /* unary operations, modifying fp status  */
2833 #define FLOAT_UNOP(name)  \
2834 FLOAT_OP(name, d)         \
2835 {                         \
2836     FDT2 = float64_ ## name(FDT0, &env->fpu->fp_status); \
2837     DEBUG_FPU_STATE();    \
2838     FORCE_RET();          \
2839 }                         \
2840 FLOAT_OP(name, s)         \
2841 {                         \
2842     FST2 = float32_ ## name(FST0, &env->fpu->fp_status); \
2843     DEBUG_FPU_STATE();    \
2844     FORCE_RET();          \
2845 }
2846 FLOAT_UNOP(sqrt)
2847 #undef FLOAT_UNOP
2848
2849 /* unary operations, not modifying fp status  */
2850 #define FLOAT_UNOP(name)  \
2851 FLOAT_OP(name, d)         \
2852 {                         \
2853     FDT2 = float64_ ## name(FDT0);   \
2854     DEBUG_FPU_STATE();    \
2855     FORCE_RET();          \
2856 }                         \
2857 FLOAT_OP(name, s)         \
2858 {                         \
2859     FST2 = float32_ ## name(FST0);   \
2860     DEBUG_FPU_STATE();    \
2861     FORCE_RET();          \
2862 }                         \
2863 FLOAT_OP(name, ps)        \
2864 {                         \
2865     FST2 = float32_ ## name(FST0);   \
2866     FSTH2 = float32_ ## name(FSTH0); \
2867     DEBUG_FPU_STATE();    \
2868     FORCE_RET();          \
2869 }
2870 FLOAT_UNOP(abs)
2871 FLOAT_UNOP(chs)
2872 #undef FLOAT_UNOP
2873
2874 FLOAT_OP(mov, d)
2875 {
2876     FDT2 = FDT0;
2877     DEBUG_FPU_STATE();
2878     FORCE_RET();
2879 }
2880 FLOAT_OP(mov, s)
2881 {
2882     FST2 = FST0;
2883     DEBUG_FPU_STATE();
2884     FORCE_RET();
2885 }
2886 FLOAT_OP(mov, ps)
2887 {
2888     FST2 = FST0;
2889     FSTH2 = FSTH0;
2890     DEBUG_FPU_STATE();
2891     FORCE_RET();
2892 }
2893 FLOAT_OP(alnv, ps)
2894 {
2895     switch (T0 & 0x7) {
2896     case 0:
2897         FST2 = FST0;
2898         FSTH2 = FSTH0;
2899         break;
2900     case 4:
2901 #ifdef TARGET_WORDS_BIGENDIAN
2902         FSTH2 = FST0;
2903         FST2 = FSTH1;
2904 #else
2905         FSTH2 = FST1;
2906         FST2 = FSTH0;
2907 #endif
2908         break;
2909     default: /* unpredictable */
2910         break;
2911     }
2912     DEBUG_FPU_STATE();
2913     FORCE_RET();
2914 }
2915
2916 #ifdef CONFIG_SOFTFLOAT
2917 #define clear_invalid() do {                                \
2918     int flags = get_float_exception_flags(&env->fpu->fp_status); \
2919     flags &= ~float_flag_invalid;                           \
2920     set_float_exception_flags(flags, &env->fpu->fp_status); \
2921 } while(0)
2922 #else
2923 #define clear_invalid() do { } while(0)
2924 #endif
2925
2926 extern void dump_fpu_s(CPUState *env);
2927
2928 #define CMP_OP(fmt, op)                                \
2929 void OPPROTO op_cmp ## _ ## fmt ## _ ## op(void)       \
2930 {                                                      \
2931     CALL_FROM_TB1(do_cmp ## _ ## fmt ## _ ## op, PARAM1); \
2932     DEBUG_FPU_STATE();                                 \
2933     FORCE_RET();                                       \
2934 }                                                      \
2935 void OPPROTO op_cmpabs ## _ ## fmt ## _ ## op(void)    \
2936 {                                                      \
2937     CALL_FROM_TB1(do_cmpabs ## _ ## fmt ## _ ## op, PARAM1); \
2938     DEBUG_FPU_STATE();                                 \
2939     FORCE_RET();                                       \
2940 }
2941 #define CMP_OPS(op)   \
2942 CMP_OP(d, op)         \
2943 CMP_OP(s, op)         \
2944 CMP_OP(ps, op)
2945
2946 CMP_OPS(f)
2947 CMP_OPS(un)
2948 CMP_OPS(eq)
2949 CMP_OPS(ueq)
2950 CMP_OPS(olt)
2951 CMP_OPS(ult)
2952 CMP_OPS(ole)
2953 CMP_OPS(ule)
2954 CMP_OPS(sf)
2955 CMP_OPS(ngle)
2956 CMP_OPS(seq)
2957 CMP_OPS(ngl)
2958 CMP_OPS(lt)
2959 CMP_OPS(nge)
2960 CMP_OPS(le)
2961 CMP_OPS(ngt)
2962 #undef CMP_OPS
2963 #undef CMP_OP
2964
2965 void op_bc1f (void)
2966 {
2967     T0 = !!(~GET_FP_COND(env->fpu) & (0x1 << PARAM1));
2968     DEBUG_FPU_STATE();
2969     FORCE_RET();
2970 }
2971 void op_bc1any2f (void)
2972 {
2973     T0 = !!(~GET_FP_COND(env->fpu) & (0x3 << PARAM1));
2974     DEBUG_FPU_STATE();
2975     FORCE_RET();
2976 }
2977 void op_bc1any4f (void)
2978 {
2979     T0 = !!(~GET_FP_COND(env->fpu) & (0xf << PARAM1));
2980     DEBUG_FPU_STATE();
2981     FORCE_RET();
2982 }
2983
2984 void op_bc1t (void)
2985 {
2986     T0 = !!(GET_FP_COND(env->fpu) & (0x1 << PARAM1));
2987     DEBUG_FPU_STATE();
2988     FORCE_RET();
2989 }
2990 void op_bc1any2t (void)
2991 {
2992     T0 = !!(GET_FP_COND(env->fpu) & (0x3 << PARAM1));
2993     DEBUG_FPU_STATE();
2994     FORCE_RET();
2995 }
2996 void op_bc1any4t (void)
2997 {
2998     T0 = !!(GET_FP_COND(env->fpu) & (0xf << PARAM1));
2999     DEBUG_FPU_STATE();
3000     FORCE_RET();
3001 }
3002
3003 void op_tlbwi (void)
3004 {
3005     CALL_FROM_TB0(env->tlb->do_tlbwi);
3006     FORCE_RET();
3007 }
3008
3009 void op_tlbwr (void)
3010 {
3011     CALL_FROM_TB0(env->tlb->do_tlbwr);
3012     FORCE_RET();
3013 }
3014
3015 void op_tlbp (void)
3016 {
3017     CALL_FROM_TB0(env->tlb->do_tlbp);
3018     FORCE_RET();
3019 }
3020
3021 void op_tlbr (void)
3022 {
3023     CALL_FROM_TB0(env->tlb->do_tlbr);
3024     FORCE_RET();
3025 }
3026
3027 /* Specials */
3028 #if defined (CONFIG_USER_ONLY)
3029 void op_tls_value (void)
3030 {
3031     T0 = env->tls_value;
3032 }
3033 #endif
3034
3035 void op_pmon (void)
3036 {
3037     CALL_FROM_TB1(do_pmon, PARAM1);
3038     FORCE_RET();
3039 }
3040
3041 void op_di (void)
3042 {
3043     T0 = env->CP0_Status;
3044     env->CP0_Status = T0 & ~(1 << CP0St_IE);
3045     CALL_FROM_TB1(cpu_mips_update_irq, env);
3046     FORCE_RET();
3047 }
3048
3049 void op_ei (void)
3050 {
3051     T0 = env->CP0_Status;
3052     env->CP0_Status = T0 | (1 << CP0St_IE);
3053     CALL_FROM_TB1(cpu_mips_update_irq, env);
3054     FORCE_RET();
3055 }
3056
3057 void op_trap (void)
3058 {
3059     if (T0) {
3060         CALL_FROM_TB1(do_raise_exception, EXCP_TRAP);
3061     }
3062     FORCE_RET();
3063 }
3064
3065 void op_debug (void)
3066 {
3067     CALL_FROM_TB1(do_raise_exception, EXCP_DEBUG);
3068     FORCE_RET();
3069 }
3070
3071 void debug_pre_eret (void);
3072 void debug_post_eret (void);
3073 void op_eret (void)
3074 {
3075     if (loglevel & CPU_LOG_EXEC)
3076         CALL_FROM_TB0(debug_pre_eret);
3077     if (env->CP0_Status & (1 << CP0St_ERL)) {
3078         env->PC[env->current_tc] = env->CP0_ErrorEPC;
3079         env->CP0_Status &= ~(1 << CP0St_ERL);
3080     } else {
3081         env->PC[env->current_tc] = env->CP0_EPC;
3082         env->CP0_Status &= ~(1 << CP0St_EXL);
3083     }
3084     CALL_FROM_TB1(compute_hflags, env);
3085     if (loglevel & CPU_LOG_EXEC)
3086         CALL_FROM_TB0(debug_post_eret);
3087     env->CP0_LLAddr = 1;
3088     FORCE_RET();
3089 }
3090
3091 void op_deret (void)
3092 {
3093     if (loglevel & CPU_LOG_EXEC)
3094         CALL_FROM_TB0(debug_pre_eret);
3095     env->PC[env->current_tc] = env->CP0_DEPC;
3096     env->hflags &= MIPS_HFLAG_DM;
3097     CALL_FROM_TB1(compute_hflags, env);
3098     if (loglevel & CPU_LOG_EXEC)
3099         CALL_FROM_TB0(debug_post_eret);
3100     env->CP0_LLAddr = 1;
3101     FORCE_RET();
3102 }
3103
3104 void op_rdhwr_cpunum(void)
3105 {
3106     if ((env->hflags & MIPS_HFLAG_CP0) ||
3107         (env->CP0_HWREna & (1 << 0)))
3108         T0 = env->CP0_EBase & 0x3ff;
3109     else
3110         CALL_FROM_TB1(do_raise_exception, EXCP_RI);
3111     FORCE_RET();
3112 }
3113
3114 void op_rdhwr_synci_step(void)
3115 {
3116     if ((env->hflags & MIPS_HFLAG_CP0) ||
3117         (env->CP0_HWREna & (1 << 1)))
3118         T0 = env->SYNCI_Step;
3119     else
3120         CALL_FROM_TB1(do_raise_exception, EXCP_RI);
3121     FORCE_RET();
3122 }
3123
3124 void op_rdhwr_cc(void)
3125 {
3126     if ((env->hflags & MIPS_HFLAG_CP0) ||
3127         (env->CP0_HWREna & (1 << 2)))
3128         T0 = env->CP0_Count;
3129     else
3130         CALL_FROM_TB1(do_raise_exception, EXCP_RI);
3131     FORCE_RET();
3132 }
3133
3134 void op_rdhwr_ccres(void)
3135 {
3136     if ((env->hflags & MIPS_HFLAG_CP0) ||
3137         (env->CP0_HWREna & (1 << 3)))
3138         T0 = env->CCRes;
3139     else
3140         CALL_FROM_TB1(do_raise_exception, EXCP_RI);
3141     FORCE_RET();
3142 }
3143
3144 void op_save_state (void)
3145 {
3146     env->hflags = PARAM1;
3147     FORCE_RET();
3148 }
3149
3150 void op_save_pc (void)
3151 {
3152     env->PC[env->current_tc] = PARAM1;
3153     FORCE_RET();
3154 }
3155
3156 #if defined(TARGET_MIPS64)
3157 void op_save_pc64 (void)
3158 {
3159     env->PC[env->current_tc] = ((uint64_t)PARAM1 << 32) | (uint32_t)PARAM2;
3160     FORCE_RET();
3161 }
3162 #endif
3163
3164 void op_interrupt_restart (void)
3165 {
3166     if (!(env->CP0_Status & (1 << CP0St_EXL)) &&
3167         !(env->CP0_Status & (1 << CP0St_ERL)) &&
3168         !(env->hflags & MIPS_HFLAG_DM) &&
3169         (env->CP0_Status & (1 << CP0St_IE)) &&
3170         (env->CP0_Status & env->CP0_Cause & CP0Ca_IP_mask)) {
3171         env->CP0_Cause &= ~(0x1f << CP0Ca_EC);
3172         CALL_FROM_TB1(do_raise_exception, EXCP_EXT_INTERRUPT);
3173     }
3174     FORCE_RET();
3175 }
3176
3177 void op_raise_exception (void)
3178 {
3179     CALL_FROM_TB1(do_raise_exception, PARAM1);
3180     FORCE_RET();
3181 }
3182
3183 void op_raise_exception_err (void)
3184 {
3185     CALL_FROM_TB2(do_raise_exception_err, PARAM1, PARAM2);
3186     FORCE_RET();
3187 }
3188
3189 void op_wait (void)
3190 {
3191     env->halted = 1;
3192     CALL_FROM_TB1(do_raise_exception, EXCP_HLT);
3193     FORCE_RET();
3194 }
3195
3196 /* Bitfield operations. */
3197 void op_ext(void)
3198 {
3199     unsigned int pos = PARAM1;
3200     unsigned int size = PARAM2;
3201
3202     T0 = (int32_t)((T1 >> pos) & ((size < 32) ? ((1 << size) - 1) : ~0));
3203     FORCE_RET();
3204 }
3205
3206 void op_ins(void)
3207 {
3208     unsigned int pos = PARAM1;
3209     unsigned int size = PARAM2;
3210     target_ulong mask = ((size < 32) ? ((1 << size) - 1) : ~0) << pos;
3211
3212     T0 = (int32_t)((T0 & ~mask) | ((T1 << pos) & mask));
3213     FORCE_RET();
3214 }
3215
3216 void op_wsbh(void)
3217 {
3218     T0 = (int32_t)(((T1 << 8) & ~0x00FF00FF) | ((T1 >> 8) & 0x00FF00FF));
3219     FORCE_RET();
3220 }
3221
3222 #if defined(TARGET_MIPS64)
3223 void op_dext(void)
3224 {
3225     unsigned int pos = PARAM1;
3226     unsigned int size = PARAM2;
3227
3228     T0 = (T1 >> pos) & ((size < 64) ? ((1ULL << size) - 1) : ~0ULL);
3229     FORCE_RET();
3230 }
3231
3232 void op_dins(void)
3233 {
3234     unsigned int pos = PARAM1;
3235     unsigned int size = PARAM2;
3236     target_ulong mask = ((size < 64) ? ((1ULL << size) - 1) : ~0ULL) << pos;
3237
3238     T0 = (T0 & ~mask) | ((T1 << pos) & mask);
3239     FORCE_RET();
3240 }
3241
3242 void op_dsbh(void)
3243 {
3244     T0 = ((T1 << 8) & ~0x00FF00FF00FF00FFULL) | ((T1 >> 8) & 0x00FF00FF00FF00FFULL);
3245     FORCE_RET();
3246 }
3247
3248 void op_dshd(void)
3249 {
3250     T1 = ((T1 << 16) & ~0x0000FFFF0000FFFFULL) | ((T1 >> 16) & 0x0000FFFF0000FFFFULL);
3251     T0 = (T1 << 32) | (T1 >> 32);
3252     FORCE_RET();
3253 }
3254 #endif
3255
3256 void op_seb(void)
3257 {
3258     T0 = ((T1 & 0xFF) ^ 0x80) - 0x80;
3259     FORCE_RET();
3260 }
3261
3262 void op_seh(void)
3263 {
3264     T0 = ((T1 & 0xFFFF) ^ 0x8000) - 0x8000;
3265     FORCE_RET();
3266 }
This page took 0.204294 seconds and 4 git commands to generate.