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