]> Git Repo - qemu.git/blob - target-mips/op.c
Switch MIPS movf/movt 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 FREG 0
52 #include "fop_template.c"
53 #undef FREG
54 #define FREG 1
55 #include "fop_template.c"
56 #undef FREG
57 #define FREG 2
58 #include "fop_template.c"
59 #undef FREG
60 #define FREG 3
61 #include "fop_template.c"
62 #undef FREG
63 #define FREG 4
64 #include "fop_template.c"
65 #undef FREG
66 #define FREG 5
67 #include "fop_template.c"
68 #undef FREG
69 #define FREG 6
70 #include "fop_template.c"
71 #undef FREG
72 #define FREG 7
73 #include "fop_template.c"
74 #undef FREG
75 #define FREG 8
76 #include "fop_template.c"
77 #undef FREG
78 #define FREG 9
79 #include "fop_template.c"
80 #undef FREG
81 #define FREG 10
82 #include "fop_template.c"
83 #undef FREG
84 #define FREG 11
85 #include "fop_template.c"
86 #undef FREG
87 #define FREG 12
88 #include "fop_template.c"
89 #undef FREG
90 #define FREG 13
91 #include "fop_template.c"
92 #undef FREG
93 #define FREG 14
94 #include "fop_template.c"
95 #undef FREG
96 #define FREG 15
97 #include "fop_template.c"
98 #undef FREG
99 #define FREG 16
100 #include "fop_template.c"
101 #undef FREG
102 #define FREG 17
103 #include "fop_template.c"
104 #undef FREG
105 #define FREG 18
106 #include "fop_template.c"
107 #undef FREG
108 #define FREG 19
109 #include "fop_template.c"
110 #undef FREG
111 #define FREG 20
112 #include "fop_template.c"
113 #undef FREG
114 #define FREG 21
115 #include "fop_template.c"
116 #undef FREG
117 #define FREG 22
118 #include "fop_template.c"
119 #undef FREG
120 #define FREG 23
121 #include "fop_template.c"
122 #undef FREG
123 #define FREG 24
124 #include "fop_template.c"
125 #undef FREG
126 #define FREG 25
127 #include "fop_template.c"
128 #undef FREG
129 #define FREG 26
130 #include "fop_template.c"
131 #undef FREG
132 #define FREG 27
133 #include "fop_template.c"
134 #undef FREG
135 #define FREG 28
136 #include "fop_template.c"
137 #undef FREG
138 #define FREG 29
139 #include "fop_template.c"
140 #undef FREG
141 #define FREG 30
142 #include "fop_template.c"
143 #undef FREG
144 #define FREG 31
145 #include "fop_template.c"
146 #undef FREG
147
148 /* Load and store */
149 #define MEMSUFFIX _raw
150 #include "op_mem.c"
151 #undef MEMSUFFIX
152 #if !defined(CONFIG_USER_ONLY)
153 #define MEMSUFFIX _user
154 #include "op_mem.c"
155 #undef MEMSUFFIX
156
157 #define MEMSUFFIX _super
158 #include "op_mem.c"
159 #undef MEMSUFFIX
160
161 #define MEMSUFFIX _kernel
162 #include "op_mem.c"
163 #undef MEMSUFFIX
164 #endif
165
166 /* 64 bits arithmetic */
167 #if TARGET_LONG_BITS > HOST_LONG_BITS
168 void op_mult (void)
169 {
170     CALL_FROM_TB0(do_mult);
171     FORCE_RET();
172 }
173
174 void op_multu (void)
175 {
176     CALL_FROM_TB0(do_multu);
177     FORCE_RET();
178 }
179
180 void op_madd (void)
181 {
182     CALL_FROM_TB0(do_madd);
183     FORCE_RET();
184 }
185
186 void op_maddu (void)
187 {
188     CALL_FROM_TB0(do_maddu);
189     FORCE_RET();
190 }
191
192 void op_msub (void)
193 {
194     CALL_FROM_TB0(do_msub);
195     FORCE_RET();
196 }
197
198 void op_msubu (void)
199 {
200     CALL_FROM_TB0(do_msubu);
201     FORCE_RET();
202 }
203
204 /* Multiplication variants of the vr54xx. */
205 void op_muls (void)
206 {
207     CALL_FROM_TB0(do_muls);
208     FORCE_RET();
209 }
210
211 void op_mulsu (void)
212 {
213     CALL_FROM_TB0(do_mulsu);
214     FORCE_RET();
215 }
216
217 void op_macc (void)
218 {
219     CALL_FROM_TB0(do_macc);
220     FORCE_RET();
221 }
222
223 void op_macchi (void)
224 {
225     CALL_FROM_TB0(do_macchi);
226     FORCE_RET();
227 }
228
229 void op_maccu (void)
230 {
231     CALL_FROM_TB0(do_maccu);
232     FORCE_RET();
233 }
234 void op_macchiu (void)
235 {
236     CALL_FROM_TB0(do_macchiu);
237     FORCE_RET();
238 }
239
240 void op_msac (void)
241 {
242     CALL_FROM_TB0(do_msac);
243     FORCE_RET();
244 }
245
246 void op_msachi (void)
247 {
248     CALL_FROM_TB0(do_msachi);
249     FORCE_RET();
250 }
251
252 void op_msacu (void)
253 {
254     CALL_FROM_TB0(do_msacu);
255     FORCE_RET();
256 }
257
258 void op_msachiu (void)
259 {
260     CALL_FROM_TB0(do_msachiu);
261     FORCE_RET();
262 }
263
264 void op_mulhi (void)
265 {
266     CALL_FROM_TB0(do_mulhi);
267     FORCE_RET();
268 }
269
270 void op_mulhiu (void)
271 {
272     CALL_FROM_TB0(do_mulhiu);
273     FORCE_RET();
274 }
275
276 void op_mulshi (void)
277 {
278     CALL_FROM_TB0(do_mulshi);
279     FORCE_RET();
280 }
281
282 void op_mulshiu (void)
283 {
284     CALL_FROM_TB0(do_mulshiu);
285     FORCE_RET();
286 }
287
288 #else /* TARGET_LONG_BITS > HOST_LONG_BITS */
289
290 static always_inline uint64_t get_HILO (void)
291 {
292     return ((uint64_t)env->HI[env->current_tc][0] << 32) |
293             ((uint64_t)(uint32_t)env->LO[env->current_tc][0]);
294 }
295
296 static always_inline void set_HILO (uint64_t HILO)
297 {
298     env->LO[env->current_tc][0] = (int32_t)(HILO & 0xFFFFFFFF);
299     env->HI[env->current_tc][0] = (int32_t)(HILO >> 32);
300 }
301
302 static always_inline void set_HIT0_LO (uint64_t HILO)
303 {
304     env->LO[env->current_tc][0] = (int32_t)(HILO & 0xFFFFFFFF);
305     T0 = env->HI[env->current_tc][0] = (int32_t)(HILO >> 32);
306 }
307
308 static always_inline void set_HI_LOT0 (uint64_t HILO)
309 {
310     T0 = env->LO[env->current_tc][0] = (int32_t)(HILO & 0xFFFFFFFF);
311     env->HI[env->current_tc][0] = (int32_t)(HILO >> 32);
312 }
313
314 void op_mult (void)
315 {
316     set_HILO((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
317     FORCE_RET();
318 }
319
320 void op_multu (void)
321 {
322     set_HILO((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
323     FORCE_RET();
324 }
325
326 void op_madd (void)
327 {
328     int64_t tmp;
329
330     tmp = ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
331     set_HILO((int64_t)get_HILO() + tmp);
332     FORCE_RET();
333 }
334
335 void op_maddu (void)
336 {
337     uint64_t tmp;
338
339     tmp = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
340     set_HILO(get_HILO() + tmp);
341     FORCE_RET();
342 }
343
344 void op_msub (void)
345 {
346     int64_t tmp;
347
348     tmp = ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
349     set_HILO((int64_t)get_HILO() - tmp);
350     FORCE_RET();
351 }
352
353 void op_msubu (void)
354 {
355     uint64_t tmp;
356
357     tmp = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
358     set_HILO(get_HILO() - tmp);
359     FORCE_RET();
360 }
361
362 /* Multiplication variants of the vr54xx. */
363 void op_muls (void)
364 {
365     set_HI_LOT0(0 - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
366     FORCE_RET();
367 }
368
369 void op_mulsu (void)
370 {
371     set_HI_LOT0(0 - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
372     FORCE_RET();
373 }
374
375 void op_macc (void)
376 {
377     set_HI_LOT0(get_HILO() + ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
378     FORCE_RET();
379 }
380
381 void op_macchi (void)
382 {
383     set_HIT0_LO(get_HILO() + ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
384     FORCE_RET();
385 }
386
387 void op_maccu (void)
388 {
389     set_HI_LOT0(get_HILO() + ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
390     FORCE_RET();
391 }
392
393 void op_macchiu (void)
394 {
395     set_HIT0_LO(get_HILO() + ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
396     FORCE_RET();
397 }
398
399 void op_msac (void)
400 {
401     set_HI_LOT0(get_HILO() - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
402     FORCE_RET();
403 }
404
405 void op_msachi (void)
406 {
407     set_HIT0_LO(get_HILO() - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
408     FORCE_RET();
409 }
410
411 void op_msacu (void)
412 {
413     set_HI_LOT0(get_HILO() - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
414     FORCE_RET();
415 }
416
417 void op_msachiu (void)
418 {
419     set_HIT0_LO(get_HILO() - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
420     FORCE_RET();
421 }
422
423 void op_mulhi (void)
424 {
425     set_HIT0_LO((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
426     FORCE_RET();
427 }
428
429 void op_mulhiu (void)
430 {
431     set_HIT0_LO((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
432     FORCE_RET();
433 }
434
435 void op_mulshi (void)
436 {
437     set_HIT0_LO(0 - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
438     FORCE_RET();
439 }
440
441 void op_mulshiu (void)
442 {
443     set_HIT0_LO(0 - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
444     FORCE_RET();
445 }
446
447 #endif /* TARGET_LONG_BITS > HOST_LONG_BITS */
448
449 #if defined(TARGET_MIPS64)
450 void op_dmult (void)
451 {
452     CALL_FROM_TB4(muls64, &(env->LO[env->current_tc][0]), &(env->HI[env->current_tc][0]), T0, T1);
453     FORCE_RET();
454 }
455
456 void op_dmultu (void)
457 {
458     CALL_FROM_TB4(mulu64, &(env->LO[env->current_tc][0]), &(env->HI[env->current_tc][0]), T0, T1);
459     FORCE_RET();
460 }
461 #endif
462
463 /* CP0 functions */
464 void op_mfc0_index (void)
465 {
466     T0 = env->CP0_Index;
467     FORCE_RET();
468 }
469
470 void op_mfc0_mvpcontrol (void)
471 {
472     T0 = env->mvp->CP0_MVPControl;
473     FORCE_RET();
474 }
475
476 void op_mfc0_mvpconf0 (void)
477 {
478     T0 = env->mvp->CP0_MVPConf0;
479     FORCE_RET();
480 }
481
482 void op_mfc0_mvpconf1 (void)
483 {
484     T0 = env->mvp->CP0_MVPConf1;
485     FORCE_RET();
486 }
487
488 void op_mfc0_random (void)
489 {
490     CALL_FROM_TB0(do_mfc0_random);
491     FORCE_RET();
492 }
493
494 void op_mfc0_vpecontrol (void)
495 {
496     T0 = env->CP0_VPEControl;
497     FORCE_RET();
498 }
499
500 void op_mfc0_vpeconf0 (void)
501 {
502     T0 = env->CP0_VPEConf0;
503     FORCE_RET();
504 }
505
506 void op_mfc0_vpeconf1 (void)
507 {
508     T0 = env->CP0_VPEConf1;
509     FORCE_RET();
510 }
511
512 void op_mfc0_yqmask (void)
513 {
514     T0 = env->CP0_YQMask;
515     FORCE_RET();
516 }
517
518 void op_mfc0_vpeschedule (void)
519 {
520     T0 = env->CP0_VPESchedule;
521     FORCE_RET();
522 }
523
524 void op_mfc0_vpeschefback (void)
525 {
526     T0 = env->CP0_VPEScheFBack;
527     FORCE_RET();
528 }
529
530 void op_mfc0_vpeopt (void)
531 {
532     T0 = env->CP0_VPEOpt;
533     FORCE_RET();
534 }
535
536 void op_mfc0_entrylo0 (void)
537 {
538     T0 = (int32_t)env->CP0_EntryLo0;
539     FORCE_RET();
540 }
541
542 void op_mfc0_tcstatus (void)
543 {
544     T0 = env->CP0_TCStatus[env->current_tc];
545     FORCE_RET();
546 }
547
548 void op_mftc0_tcstatus(void)
549 {
550     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
551
552     T0 = env->CP0_TCStatus[other_tc];
553     FORCE_RET();
554 }
555
556 void op_mfc0_tcbind (void)
557 {
558     T0 = env->CP0_TCBind[env->current_tc];
559     FORCE_RET();
560 }
561
562 void op_mftc0_tcbind(void)
563 {
564     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
565
566     T0 = env->CP0_TCBind[other_tc];
567     FORCE_RET();
568 }
569
570 void op_mfc0_tcrestart (void)
571 {
572     T0 = env->PC[env->current_tc];
573     FORCE_RET();
574 }
575
576 void op_mftc0_tcrestart(void)
577 {
578     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
579
580     T0 = env->PC[other_tc];
581     FORCE_RET();
582 }
583
584 void op_mfc0_tchalt (void)
585 {
586     T0 = env->CP0_TCHalt[env->current_tc];
587     FORCE_RET();
588 }
589
590 void op_mftc0_tchalt(void)
591 {
592     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
593
594     T0 = env->CP0_TCHalt[other_tc];
595     FORCE_RET();
596 }
597
598 void op_mfc0_tccontext (void)
599 {
600     T0 = env->CP0_TCContext[env->current_tc];
601     FORCE_RET();
602 }
603
604 void op_mftc0_tccontext(void)
605 {
606     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
607
608     T0 = env->CP0_TCContext[other_tc];
609     FORCE_RET();
610 }
611
612 void op_mfc0_tcschedule (void)
613 {
614     T0 = env->CP0_TCSchedule[env->current_tc];
615     FORCE_RET();
616 }
617
618 void op_mftc0_tcschedule(void)
619 {
620     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
621
622     T0 = env->CP0_TCSchedule[other_tc];
623     FORCE_RET();
624 }
625
626 void op_mfc0_tcschefback (void)
627 {
628     T0 = env->CP0_TCScheFBack[env->current_tc];
629     FORCE_RET();
630 }
631
632 void op_mftc0_tcschefback(void)
633 {
634     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
635
636     T0 = env->CP0_TCScheFBack[other_tc];
637     FORCE_RET();
638 }
639
640 void op_mfc0_entrylo1 (void)
641 {
642     T0 = (int32_t)env->CP0_EntryLo1;
643     FORCE_RET();
644 }
645
646 void op_mfc0_context (void)
647 {
648     T0 = (int32_t)env->CP0_Context;
649     FORCE_RET();
650 }
651
652 void op_mfc0_pagemask (void)
653 {
654     T0 = env->CP0_PageMask;
655     FORCE_RET();
656 }
657
658 void op_mfc0_pagegrain (void)
659 {
660     T0 = env->CP0_PageGrain;
661     FORCE_RET();
662 }
663
664 void op_mfc0_wired (void)
665 {
666     T0 = env->CP0_Wired;
667     FORCE_RET();
668 }
669
670 void op_mfc0_srsconf0 (void)
671 {
672     T0 = env->CP0_SRSConf0;
673     FORCE_RET();
674 }
675
676 void op_mfc0_srsconf1 (void)
677 {
678     T0 = env->CP0_SRSConf1;
679     FORCE_RET();
680 }
681
682 void op_mfc0_srsconf2 (void)
683 {
684     T0 = env->CP0_SRSConf2;
685     FORCE_RET();
686 }
687
688 void op_mfc0_srsconf3 (void)
689 {
690     T0 = env->CP0_SRSConf3;
691     FORCE_RET();
692 }
693
694 void op_mfc0_srsconf4 (void)
695 {
696     T0 = env->CP0_SRSConf4;
697     FORCE_RET();
698 }
699
700 void op_mfc0_hwrena (void)
701 {
702     T0 = env->CP0_HWREna;
703     FORCE_RET();
704 }
705
706 void op_mfc0_badvaddr (void)
707 {
708     T0 = (int32_t)env->CP0_BadVAddr;
709     FORCE_RET();
710 }
711
712 void op_mfc0_count (void)
713 {
714     CALL_FROM_TB0(do_mfc0_count);
715     FORCE_RET();
716 }
717
718 void op_mfc0_entryhi (void)
719 {
720     T0 = (int32_t)env->CP0_EntryHi;
721     FORCE_RET();
722 }
723
724 void op_mftc0_entryhi(void)
725 {
726     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
727
728     T0 = (env->CP0_EntryHi & ~0xff) | (env->CP0_TCStatus[other_tc] & 0xff);
729     FORCE_RET();
730 }
731
732 void op_mfc0_compare (void)
733 {
734     T0 = env->CP0_Compare;
735     FORCE_RET();
736 }
737
738 void op_mfc0_status (void)
739 {
740     T0 = env->CP0_Status;
741     FORCE_RET();
742 }
743
744 void op_mftc0_status(void)
745 {
746     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
747     uint32_t tcstatus = env->CP0_TCStatus[other_tc];
748
749     T0 = env->CP0_Status & ~0xf1000018;
750     T0 |= tcstatus & (0xf << CP0TCSt_TCU0);
751     T0 |= (tcstatus & (1 << CP0TCSt_TMX)) >> (CP0TCSt_TMX - CP0St_MX);
752     T0 |= (tcstatus & (0x3 << CP0TCSt_TKSU)) >> (CP0TCSt_TKSU - CP0St_KSU);
753     FORCE_RET();
754 }
755
756 void op_mfc0_intctl (void)
757 {
758     T0 = env->CP0_IntCtl;
759     FORCE_RET();
760 }
761
762 void op_mfc0_srsctl (void)
763 {
764     T0 = env->CP0_SRSCtl;
765     FORCE_RET();
766 }
767
768 void op_mfc0_srsmap (void)
769 {
770     T0 = env->CP0_SRSMap;
771     FORCE_RET();
772 }
773
774 void op_mfc0_cause (void)
775 {
776     T0 = env->CP0_Cause;
777     FORCE_RET();
778 }
779
780 void op_mfc0_epc (void)
781 {
782     T0 = (int32_t)env->CP0_EPC;
783     FORCE_RET();
784 }
785
786 void op_mfc0_prid (void)
787 {
788     T0 = env->CP0_PRid;
789     FORCE_RET();
790 }
791
792 void op_mfc0_ebase (void)
793 {
794     T0 = env->CP0_EBase;
795     FORCE_RET();
796 }
797
798 void op_mfc0_config0 (void)
799 {
800     T0 = env->CP0_Config0;
801     FORCE_RET();
802 }
803
804 void op_mfc0_config1 (void)
805 {
806     T0 = env->CP0_Config1;
807     FORCE_RET();
808 }
809
810 void op_mfc0_config2 (void)
811 {
812     T0 = env->CP0_Config2;
813     FORCE_RET();
814 }
815
816 void op_mfc0_config3 (void)
817 {
818     T0 = env->CP0_Config3;
819     FORCE_RET();
820 }
821
822 void op_mfc0_config6 (void)
823 {
824     T0 = env->CP0_Config6;
825     FORCE_RET();
826 }
827
828 void op_mfc0_config7 (void)
829 {
830     T0 = env->CP0_Config7;
831     FORCE_RET();
832 }
833
834 void op_mfc0_lladdr (void)
835 {
836     T0 = (int32_t)env->CP0_LLAddr >> 4;
837     FORCE_RET();
838 }
839
840 void op_mfc0_watchlo (void)
841 {
842     T0 = (int32_t)env->CP0_WatchLo[PARAM1];
843     FORCE_RET();
844 }
845
846 void op_mfc0_watchhi (void)
847 {
848     T0 = env->CP0_WatchHi[PARAM1];
849     FORCE_RET();
850 }
851
852 void op_mfc0_xcontext (void)
853 {
854     T0 = (int32_t)env->CP0_XContext;
855     FORCE_RET();
856 }
857
858 void op_mfc0_framemask (void)
859 {
860     T0 = env->CP0_Framemask;
861     FORCE_RET();
862 }
863
864 void op_mfc0_debug (void)
865 {
866     T0 = env->CP0_Debug;
867     if (env->hflags & MIPS_HFLAG_DM)
868         T0 |= 1 << CP0DB_DM;
869     FORCE_RET();
870 }
871
872 void op_mftc0_debug(void)
873 {
874     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
875
876     /* XXX: Might be wrong, check with EJTAG spec. */
877     T0 = (env->CP0_Debug & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) |
878          (env->CP0_Debug_tcstatus[other_tc] &
879           ((1 << CP0DB_SSt) | (1 << CP0DB_Halt)));
880     FORCE_RET();
881 }
882
883 void op_mfc0_depc (void)
884 {
885     T0 = (int32_t)env->CP0_DEPC;
886     FORCE_RET();
887 }
888
889 void op_mfc0_performance0 (void)
890 {
891     T0 = env->CP0_Performance0;
892     FORCE_RET();
893 }
894
895 void op_mfc0_taglo (void)
896 {
897     T0 = env->CP0_TagLo;
898     FORCE_RET();
899 }
900
901 void op_mfc0_datalo (void)
902 {
903     T0 = env->CP0_DataLo;
904     FORCE_RET();
905 }
906
907 void op_mfc0_taghi (void)
908 {
909     T0 = env->CP0_TagHi;
910     FORCE_RET();
911 }
912
913 void op_mfc0_datahi (void)
914 {
915     T0 = env->CP0_DataHi;
916     FORCE_RET();
917 }
918
919 void op_mfc0_errorepc (void)
920 {
921     T0 = (int32_t)env->CP0_ErrorEPC;
922     FORCE_RET();
923 }
924
925 void op_mfc0_desave (void)
926 {
927     T0 = env->CP0_DESAVE;
928     FORCE_RET();
929 }
930
931 void op_mtc0_index (void)
932 {
933     int num = 1;
934     unsigned int tmp = env->tlb->nb_tlb;
935
936     do {
937         tmp >>= 1;
938         num <<= 1;
939     } while (tmp);
940     env->CP0_Index = (env->CP0_Index & 0x80000000) | (T0 & (num - 1));
941     FORCE_RET();
942 }
943
944 void op_mtc0_mvpcontrol (void)
945 {
946     uint32_t mask = 0;
947     uint32_t newval;
948
949     if (env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP))
950         mask |= (1 << CP0MVPCo_CPA) | (1 << CP0MVPCo_VPC) |
951                 (1 << CP0MVPCo_EVP);
952     if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
953         mask |= (1 << CP0MVPCo_STLB);
954     newval = (env->mvp->CP0_MVPControl & ~mask) | (T0 & mask);
955
956     // TODO: Enable/disable shared TLB, enable/disable VPEs.
957
958     env->mvp->CP0_MVPControl = newval;
959     FORCE_RET();
960 }
961
962 void op_mtc0_vpecontrol (void)
963 {
964     uint32_t mask;
965     uint32_t newval;
966
967     mask = (1 << CP0VPECo_YSI) | (1 << CP0VPECo_GSI) |
968            (1 << CP0VPECo_TE) | (0xff << CP0VPECo_TargTC);
969     newval = (env->CP0_VPEControl & ~mask) | (T0 & mask);
970
971     /* Yield scheduler intercept not implemented. */
972     /* Gating storage scheduler intercept not implemented. */
973
974     // TODO: Enable/disable TCs.
975
976     env->CP0_VPEControl = newval;
977     FORCE_RET();
978 }
979
980 void op_mtc0_vpeconf0 (void)
981 {
982     uint32_t mask = 0;
983     uint32_t newval;
984
985     if (env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) {
986         if (env->CP0_VPEConf0 & (1 << CP0VPEC0_VPA))
987             mask |= (0xff << CP0VPEC0_XTC);
988         mask |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
989     }
990     newval = (env->CP0_VPEConf0 & ~mask) | (T0 & mask);
991
992     // TODO: TC exclusive handling due to ERL/EXL.
993
994     env->CP0_VPEConf0 = newval;
995     FORCE_RET();
996 }
997
998 void op_mtc0_vpeconf1 (void)
999 {
1000     uint32_t mask = 0;
1001     uint32_t newval;
1002
1003     if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
1004         mask |= (0xff << CP0VPEC1_NCX) | (0xff << CP0VPEC1_NCP2) |
1005                 (0xff << CP0VPEC1_NCP1);
1006     newval = (env->CP0_VPEConf1 & ~mask) | (T0 & mask);
1007
1008     /* UDI not implemented. */
1009     /* CP2 not implemented. */
1010
1011     // TODO: Handle FPU (CP1) binding.
1012
1013     env->CP0_VPEConf1 = newval;
1014     FORCE_RET();
1015 }
1016
1017 void op_mtc0_yqmask (void)
1018 {
1019     /* Yield qualifier inputs not implemented. */
1020     env->CP0_YQMask = 0x00000000;
1021     FORCE_RET();
1022 }
1023
1024 void op_mtc0_vpeschedule (void)
1025 {
1026     env->CP0_VPESchedule = T0;
1027     FORCE_RET();
1028 }
1029
1030 void op_mtc0_vpeschefback (void)
1031 {
1032     env->CP0_VPEScheFBack = T0;
1033     FORCE_RET();
1034 }
1035
1036 void op_mtc0_vpeopt (void)
1037 {
1038     env->CP0_VPEOpt = T0 & 0x0000ffff;
1039     FORCE_RET();
1040 }
1041
1042 void op_mtc0_entrylo0 (void)
1043 {
1044     /* Large physaddr (PABITS) not implemented */
1045     /* 1k pages not implemented */
1046     env->CP0_EntryLo0 = T0 & 0x3FFFFFFF;
1047     FORCE_RET();
1048 }
1049
1050 void op_mtc0_tcstatus (void)
1051 {
1052     uint32_t mask = env->CP0_TCStatus_rw_bitmask;
1053     uint32_t newval;
1054
1055     newval = (env->CP0_TCStatus[env->current_tc] & ~mask) | (T0 & mask);
1056
1057     // TODO: Sync with CP0_Status.
1058
1059     env->CP0_TCStatus[env->current_tc] = newval;
1060     FORCE_RET();
1061 }
1062
1063 void op_mttc0_tcstatus (void)
1064 {
1065     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1066
1067     // TODO: Sync with CP0_Status.
1068
1069     env->CP0_TCStatus[other_tc] = T0;
1070     FORCE_RET();
1071 }
1072
1073 void op_mtc0_tcbind (void)
1074 {
1075     uint32_t mask = (1 << CP0TCBd_TBE);
1076     uint32_t newval;
1077
1078     if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
1079         mask |= (1 << CP0TCBd_CurVPE);
1080     newval = (env->CP0_TCBind[env->current_tc] & ~mask) | (T0 & mask);
1081     env->CP0_TCBind[env->current_tc] = newval;
1082     FORCE_RET();
1083 }
1084
1085 void op_mttc0_tcbind (void)
1086 {
1087     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1088     uint32_t mask = (1 << CP0TCBd_TBE);
1089     uint32_t newval;
1090
1091     if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
1092         mask |= (1 << CP0TCBd_CurVPE);
1093     newval = (env->CP0_TCBind[other_tc] & ~mask) | (T0 & mask);
1094     env->CP0_TCBind[other_tc] = newval;
1095     FORCE_RET();
1096 }
1097
1098 void op_mtc0_tcrestart (void)
1099 {
1100     env->PC[env->current_tc] = T0;
1101     env->CP0_TCStatus[env->current_tc] &= ~(1 << CP0TCSt_TDS);
1102     env->CP0_LLAddr = 0ULL;
1103     /* MIPS16 not implemented. */
1104     FORCE_RET();
1105 }
1106
1107 void op_mttc0_tcrestart (void)
1108 {
1109     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1110
1111     env->PC[other_tc] = T0;
1112     env->CP0_TCStatus[other_tc] &= ~(1 << CP0TCSt_TDS);
1113     env->CP0_LLAddr = 0ULL;
1114     /* MIPS16 not implemented. */
1115     FORCE_RET();
1116 }
1117
1118 void op_mtc0_tchalt (void)
1119 {
1120     env->CP0_TCHalt[env->current_tc] = T0 & 0x1;
1121
1122     // TODO: Halt TC / Restart (if allocated+active) TC.
1123
1124     FORCE_RET();
1125 }
1126
1127 void op_mttc0_tchalt (void)
1128 {
1129     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1130
1131     // TODO: Halt TC / Restart (if allocated+active) TC.
1132
1133     env->CP0_TCHalt[other_tc] = T0;
1134     FORCE_RET();
1135 }
1136
1137 void op_mtc0_tccontext (void)
1138 {
1139     env->CP0_TCContext[env->current_tc] = T0;
1140     FORCE_RET();
1141 }
1142
1143 void op_mttc0_tccontext (void)
1144 {
1145     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1146
1147     env->CP0_TCContext[other_tc] = T0;
1148     FORCE_RET();
1149 }
1150
1151 void op_mtc0_tcschedule (void)
1152 {
1153     env->CP0_TCSchedule[env->current_tc] = T0;
1154     FORCE_RET();
1155 }
1156
1157 void op_mttc0_tcschedule (void)
1158 {
1159     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1160
1161     env->CP0_TCSchedule[other_tc] = T0;
1162     FORCE_RET();
1163 }
1164
1165 void op_mtc0_tcschefback (void)
1166 {
1167     env->CP0_TCScheFBack[env->current_tc] = T0;
1168     FORCE_RET();
1169 }
1170
1171 void op_mttc0_tcschefback (void)
1172 {
1173     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1174
1175     env->CP0_TCScheFBack[other_tc] = T0;
1176     FORCE_RET();
1177 }
1178
1179 void op_mtc0_entrylo1 (void)
1180 {
1181     /* Large physaddr (PABITS) not implemented */
1182     /* 1k pages not implemented */
1183     env->CP0_EntryLo1 = T0 & 0x3FFFFFFF;
1184     FORCE_RET();
1185 }
1186
1187 void op_mtc0_context (void)
1188 {
1189     env->CP0_Context = (env->CP0_Context & 0x007FFFFF) | (T0 & ~0x007FFFFF);
1190     FORCE_RET();
1191 }
1192
1193 void op_mtc0_pagemask (void)
1194 {
1195     /* 1k pages not implemented */
1196     env->CP0_PageMask = T0 & (0x1FFFFFFF & (TARGET_PAGE_MASK << 1));
1197     FORCE_RET();
1198 }
1199
1200 void op_mtc0_pagegrain (void)
1201 {
1202     /* SmartMIPS not implemented */
1203     /* Large physaddr (PABITS) not implemented */
1204     /* 1k pages not implemented */
1205     env->CP0_PageGrain = 0;
1206     FORCE_RET();
1207 }
1208
1209 void op_mtc0_wired (void)
1210 {
1211     env->CP0_Wired = T0 % env->tlb->nb_tlb;
1212     FORCE_RET();
1213 }
1214
1215 void op_mtc0_srsconf0 (void)
1216 {
1217     env->CP0_SRSConf0 |= T0 & env->CP0_SRSConf0_rw_bitmask;
1218     FORCE_RET();
1219 }
1220
1221 void op_mtc0_srsconf1 (void)
1222 {
1223     env->CP0_SRSConf1 |= T0 & env->CP0_SRSConf1_rw_bitmask;
1224     FORCE_RET();
1225 }
1226
1227 void op_mtc0_srsconf2 (void)
1228 {
1229     env->CP0_SRSConf2 |= T0 & env->CP0_SRSConf2_rw_bitmask;
1230     FORCE_RET();
1231 }
1232
1233 void op_mtc0_srsconf3 (void)
1234 {
1235     env->CP0_SRSConf3 |= T0 & env->CP0_SRSConf3_rw_bitmask;
1236     FORCE_RET();
1237 }
1238
1239 void op_mtc0_srsconf4 (void)
1240 {
1241     env->CP0_SRSConf4 |= T0 & env->CP0_SRSConf4_rw_bitmask;
1242     FORCE_RET();
1243 }
1244
1245 void op_mtc0_hwrena (void)
1246 {
1247     env->CP0_HWREna = T0 & 0x0000000F;
1248     FORCE_RET();
1249 }
1250
1251 void op_mtc0_count (void)
1252 {
1253     CALL_FROM_TB2(cpu_mips_store_count, env, T0);
1254     FORCE_RET();
1255 }
1256
1257 void op_mtc0_entryhi (void)
1258 {
1259     target_ulong old, val;
1260
1261     /* 1k pages not implemented */
1262     val = T0 & ((TARGET_PAGE_MASK << 1) | 0xFF);
1263 #if defined(TARGET_MIPS64)
1264     val &= env->SEGMask;
1265 #endif
1266     old = env->CP0_EntryHi;
1267     env->CP0_EntryHi = val;
1268     if (env->CP0_Config3 & (1 << CP0C3_MT)) {
1269         uint32_t tcst = env->CP0_TCStatus[env->current_tc] & ~0xff;
1270         env->CP0_TCStatus[env->current_tc] = tcst | (val & 0xff);
1271     }
1272     /* If the ASID changes, flush qemu's TLB.  */
1273     if ((old & 0xFF) != (val & 0xFF))
1274         CALL_FROM_TB2(cpu_mips_tlb_flush, env, 1);
1275     FORCE_RET();
1276 }
1277
1278 void op_mttc0_entryhi(void)
1279 {
1280     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1281
1282     env->CP0_EntryHi = (env->CP0_EntryHi & 0xff) | (T0 & ~0xff);
1283     env->CP0_TCStatus[other_tc] = (env->CP0_TCStatus[other_tc] & ~0xff) | (T0 & 0xff);
1284     FORCE_RET();
1285 }
1286
1287 void op_mtc0_compare (void)
1288 {
1289     CALL_FROM_TB2(cpu_mips_store_compare, env, T0);
1290     FORCE_RET();
1291 }
1292
1293 void op_mtc0_status (void)
1294 {
1295     uint32_t val, old;
1296     uint32_t mask = env->CP0_Status_rw_bitmask;
1297
1298     val = T0 & mask;
1299     old = env->CP0_Status;
1300     env->CP0_Status = (env->CP0_Status & ~mask) | val;
1301     CALL_FROM_TB1(compute_hflags, env);
1302     if (loglevel & CPU_LOG_EXEC)
1303         CALL_FROM_TB2(do_mtc0_status_debug, old, val);
1304     CALL_FROM_TB1(cpu_mips_update_irq, env);
1305     FORCE_RET();
1306 }
1307
1308 void op_mttc0_status(void)
1309 {
1310     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1311     uint32_t tcstatus = env->CP0_TCStatus[other_tc];
1312
1313     env->CP0_Status = T0 & ~0xf1000018;
1314     tcstatus = (tcstatus & ~(0xf << CP0TCSt_TCU0)) | (T0 & (0xf << CP0St_CU0));
1315     tcstatus = (tcstatus & ~(1 << CP0TCSt_TMX)) | ((T0 & (1 << CP0St_MX)) << (CP0TCSt_TMX - CP0St_MX));
1316     tcstatus = (tcstatus & ~(0x3 << CP0TCSt_TKSU)) | ((T0 & (0x3 << CP0St_KSU)) << (CP0TCSt_TKSU - CP0St_KSU));
1317     env->CP0_TCStatus[other_tc] = tcstatus;
1318     FORCE_RET();
1319 }
1320
1321 void op_mtc0_intctl (void)
1322 {
1323     /* vectored interrupts not implemented, no performance counters. */
1324     env->CP0_IntCtl = (env->CP0_IntCtl & ~0x000002e0) | (T0 & 0x000002e0);
1325     FORCE_RET();
1326 }
1327
1328 void op_mtc0_srsctl (void)
1329 {
1330     uint32_t mask = (0xf << CP0SRSCtl_ESS) | (0xf << CP0SRSCtl_PSS);
1331     env->CP0_SRSCtl = (env->CP0_SRSCtl & ~mask) | (T0 & mask);
1332     FORCE_RET();
1333 }
1334
1335 void op_mtc0_srsmap (void)
1336 {
1337     env->CP0_SRSMap = T0;
1338     FORCE_RET();
1339 }
1340
1341 void op_mtc0_cause (void)
1342 {
1343     uint32_t mask = 0x00C00300;
1344     uint32_t old = env->CP0_Cause;
1345
1346     if (env->insn_flags & ISA_MIPS32R2)
1347         mask |= 1 << CP0Ca_DC;
1348
1349     env->CP0_Cause = (env->CP0_Cause & ~mask) | (T0 & mask);
1350
1351     if ((old ^ env->CP0_Cause) & (1 << CP0Ca_DC)) {
1352         if (env->CP0_Cause & (1 << CP0Ca_DC))
1353             CALL_FROM_TB1(cpu_mips_stop_count, env);
1354         else
1355             CALL_FROM_TB1(cpu_mips_start_count, env);
1356     }
1357
1358     /* Handle the software interrupt as an hardware one, as they
1359        are very similar */
1360     if (T0 & CP0Ca_IP_mask) {
1361         CALL_FROM_TB1(cpu_mips_update_irq, env);
1362     }
1363     FORCE_RET();
1364 }
1365
1366 void op_mtc0_epc (void)
1367 {
1368     env->CP0_EPC = T0;
1369     FORCE_RET();
1370 }
1371
1372 void op_mtc0_ebase (void)
1373 {
1374     /* vectored interrupts not implemented */
1375     /* Multi-CPU not implemented */
1376     env->CP0_EBase = 0x80000000 | (T0 & 0x3FFFF000);
1377     FORCE_RET();
1378 }
1379
1380 void op_mtc0_config0 (void)
1381 {
1382     env->CP0_Config0 = (env->CP0_Config0 & 0x81FFFFF8) | (T0 & 0x00000007);
1383     FORCE_RET();
1384 }
1385
1386 void op_mtc0_config2 (void)
1387 {
1388     /* tertiary/secondary caches not implemented */
1389     env->CP0_Config2 = (env->CP0_Config2 & 0x8FFF0FFF);
1390     FORCE_RET();
1391 }
1392
1393 void op_mtc0_watchlo (void)
1394 {
1395     /* Watch exceptions for instructions, data loads, data stores
1396        not implemented. */
1397     env->CP0_WatchLo[PARAM1] = (T0 & ~0x7);
1398     FORCE_RET();
1399 }
1400
1401 void op_mtc0_watchhi (void)
1402 {
1403     env->CP0_WatchHi[PARAM1] = (T0 & 0x40FF0FF8);
1404     env->CP0_WatchHi[PARAM1] &= ~(env->CP0_WatchHi[PARAM1] & T0 & 0x7);
1405     FORCE_RET();
1406 }
1407
1408 void op_mtc0_xcontext (void)
1409 {
1410     target_ulong mask = (1ULL << (env->SEGBITS - 7)) - 1;
1411     env->CP0_XContext = (env->CP0_XContext & mask) | (T0 & ~mask);
1412     FORCE_RET();
1413 }
1414
1415 void op_mtc0_framemask (void)
1416 {
1417     env->CP0_Framemask = T0; /* XXX */
1418     FORCE_RET();
1419 }
1420
1421 void op_mtc0_debug (void)
1422 {
1423     env->CP0_Debug = (env->CP0_Debug & 0x8C03FC1F) | (T0 & 0x13300120);
1424     if (T0 & (1 << CP0DB_DM))
1425         env->hflags |= MIPS_HFLAG_DM;
1426     else
1427         env->hflags &= ~MIPS_HFLAG_DM;
1428     FORCE_RET();
1429 }
1430
1431 void op_mttc0_debug(void)
1432 {
1433     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1434
1435     /* XXX: Might be wrong, check with EJTAG spec. */
1436     env->CP0_Debug_tcstatus[other_tc] = T0 & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt));
1437     env->CP0_Debug = (env->CP0_Debug & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) |
1438                      (T0 & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt)));
1439     FORCE_RET();
1440 }
1441
1442 void op_mtc0_depc (void)
1443 {
1444     env->CP0_DEPC = T0;
1445     FORCE_RET();
1446 }
1447
1448 void op_mtc0_performance0 (void)
1449 {
1450     env->CP0_Performance0 = T0 & 0x000007ff;
1451     FORCE_RET();
1452 }
1453
1454 void op_mtc0_taglo (void)
1455 {
1456     env->CP0_TagLo = T0 & 0xFFFFFCF6;
1457     FORCE_RET();
1458 }
1459
1460 void op_mtc0_datalo (void)
1461 {
1462     env->CP0_DataLo = T0; /* XXX */
1463     FORCE_RET();
1464 }
1465
1466 void op_mtc0_taghi (void)
1467 {
1468     env->CP0_TagHi = T0; /* XXX */
1469     FORCE_RET();
1470 }
1471
1472 void op_mtc0_datahi (void)
1473 {
1474     env->CP0_DataHi = T0; /* XXX */
1475     FORCE_RET();
1476 }
1477
1478 void op_mtc0_errorepc (void)
1479 {
1480     env->CP0_ErrorEPC = T0;
1481     FORCE_RET();
1482 }
1483
1484 void op_mtc0_desave (void)
1485 {
1486     env->CP0_DESAVE = T0;
1487     FORCE_RET();
1488 }
1489
1490 #if defined(TARGET_MIPS64)
1491 void op_dmfc0_yqmask (void)
1492 {
1493     T0 = env->CP0_YQMask;
1494     FORCE_RET();
1495 }
1496
1497 void op_dmfc0_vpeschedule (void)
1498 {
1499     T0 = env->CP0_VPESchedule;
1500     FORCE_RET();
1501 }
1502
1503 void op_dmfc0_vpeschefback (void)
1504 {
1505     T0 = env->CP0_VPEScheFBack;
1506     FORCE_RET();
1507 }
1508
1509 void op_dmfc0_entrylo0 (void)
1510 {
1511     T0 = env->CP0_EntryLo0;
1512     FORCE_RET();
1513 }
1514
1515 void op_dmfc0_tcrestart (void)
1516 {
1517     T0 = env->PC[env->current_tc];
1518     FORCE_RET();
1519 }
1520
1521 void op_dmfc0_tchalt (void)
1522 {
1523     T0 = env->CP0_TCHalt[env->current_tc];
1524     FORCE_RET();
1525 }
1526
1527 void op_dmfc0_tccontext (void)
1528 {
1529     T0 = env->CP0_TCContext[env->current_tc];
1530     FORCE_RET();
1531 }
1532
1533 void op_dmfc0_tcschedule (void)
1534 {
1535     T0 = env->CP0_TCSchedule[env->current_tc];
1536     FORCE_RET();
1537 }
1538
1539 void op_dmfc0_tcschefback (void)
1540 {
1541     T0 = env->CP0_TCScheFBack[env->current_tc];
1542     FORCE_RET();
1543 }
1544
1545 void op_dmfc0_entrylo1 (void)
1546 {
1547     T0 = env->CP0_EntryLo1;
1548     FORCE_RET();
1549 }
1550
1551 void op_dmfc0_context (void)
1552 {
1553     T0 = env->CP0_Context;
1554     FORCE_RET();
1555 }
1556
1557 void op_dmfc0_badvaddr (void)
1558 {
1559     T0 = env->CP0_BadVAddr;
1560     FORCE_RET();
1561 }
1562
1563 void op_dmfc0_entryhi (void)
1564 {
1565     T0 = env->CP0_EntryHi;
1566     FORCE_RET();
1567 }
1568
1569 void op_dmfc0_epc (void)
1570 {
1571     T0 = env->CP0_EPC;
1572     FORCE_RET();
1573 }
1574
1575 void op_dmfc0_lladdr (void)
1576 {
1577     T0 = env->CP0_LLAddr >> 4;
1578     FORCE_RET();
1579 }
1580
1581 void op_dmfc0_watchlo (void)
1582 {
1583     T0 = env->CP0_WatchLo[PARAM1];
1584     FORCE_RET();
1585 }
1586
1587 void op_dmfc0_xcontext (void)
1588 {
1589     T0 = env->CP0_XContext;
1590     FORCE_RET();
1591 }
1592
1593 void op_dmfc0_depc (void)
1594 {
1595     T0 = env->CP0_DEPC;
1596     FORCE_RET();
1597 }
1598
1599 void op_dmfc0_errorepc (void)
1600 {
1601     T0 = env->CP0_ErrorEPC;
1602     FORCE_RET();
1603 }
1604 #endif /* TARGET_MIPS64 */
1605
1606 /* MIPS MT functions */
1607 void op_mftgpr(void)
1608 {
1609     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1610
1611     T0 = env->gpr[other_tc][PARAM1];
1612     FORCE_RET();
1613 }
1614
1615 void op_mftlo(void)
1616 {
1617     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1618
1619     T0 = env->LO[other_tc][PARAM1];
1620     FORCE_RET();
1621 }
1622
1623 void op_mfthi(void)
1624 {
1625     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1626
1627     T0 = env->HI[other_tc][PARAM1];
1628     FORCE_RET();
1629 }
1630
1631 void op_mftacx(void)
1632 {
1633     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1634
1635     T0 = env->ACX[other_tc][PARAM1];
1636     FORCE_RET();
1637 }
1638
1639 void op_mftdsp(void)
1640 {
1641     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1642
1643     T0 = env->DSPControl[other_tc];
1644     FORCE_RET();
1645 }
1646
1647 void op_mttgpr(void)
1648 {
1649     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1650
1651     T0 = env->gpr[other_tc][PARAM1];
1652     FORCE_RET();
1653 }
1654
1655 void op_mttlo(void)
1656 {
1657     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1658
1659     T0 = env->LO[other_tc][PARAM1];
1660     FORCE_RET();
1661 }
1662
1663 void op_mtthi(void)
1664 {
1665     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1666
1667     T0 = env->HI[other_tc][PARAM1];
1668     FORCE_RET();
1669 }
1670
1671 void op_mttacx(void)
1672 {
1673     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1674
1675     T0 = env->ACX[other_tc][PARAM1];
1676     FORCE_RET();
1677 }
1678
1679 void op_mttdsp(void)
1680 {
1681     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1682
1683     T0 = env->DSPControl[other_tc];
1684     FORCE_RET();
1685 }
1686
1687
1688 void op_dmt(void)
1689 {
1690     // TODO
1691     T0 = 0;
1692     // rt = T0
1693     FORCE_RET();
1694 }
1695
1696 void op_emt(void)
1697 {
1698     // TODO
1699     T0 = 0;
1700     // rt = T0
1701     FORCE_RET();
1702 }
1703
1704 void op_dvpe(void)
1705 {
1706     // TODO
1707     T0 = 0;
1708     // rt = T0
1709     FORCE_RET();
1710 }
1711
1712 void op_evpe(void)
1713 {
1714     // TODO
1715     T0 = 0;
1716     // rt = T0
1717     FORCE_RET();
1718 }
1719
1720 void op_fork(void)
1721 {
1722     // T0 = rt, T1 = rs
1723     T0 = 0;
1724     // TODO: store to TC register
1725     FORCE_RET();
1726 }
1727
1728 void op_yield(void)
1729 {
1730     if (T0 < 0) {
1731         /* No scheduling policy implemented. */
1732         if (T0 != -2) {
1733             if (env->CP0_VPEControl & (1 << CP0VPECo_YSI) &&
1734                 env->CP0_TCStatus[env->current_tc] & (1 << CP0TCSt_DT)) {
1735                 env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT);
1736                 env->CP0_VPEControl |= 4 << CP0VPECo_EXCPT;
1737                 CALL_FROM_TB1(do_raise_exception, EXCP_THREAD);
1738             }
1739         }
1740     } else if (T0 == 0) {
1741         if (0 /* TODO: TC underflow */) {
1742             env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT);
1743             CALL_FROM_TB1(do_raise_exception, EXCP_THREAD);
1744         } else {
1745             // TODO: Deallocate TC
1746         }
1747     } else if (T0 > 0) {
1748         /* Yield qualifier inputs not implemented. */
1749         env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT);
1750         env->CP0_VPEControl |= 2 << CP0VPECo_EXCPT;
1751         CALL_FROM_TB1(do_raise_exception, EXCP_THREAD);
1752     }
1753     T0 = env->CP0_YQMask;
1754     FORCE_RET();
1755 }
1756
1757 /* CP1 functions */
1758 #if 0
1759 # define DEBUG_FPU_STATE() CALL_FROM_TB1(dump_fpu, env)
1760 #else
1761 # define DEBUG_FPU_STATE() do { } while(0)
1762 #endif
1763
1764 void op_cfc1 (void)
1765 {
1766     CALL_FROM_TB1(do_cfc1, PARAM1);
1767     DEBUG_FPU_STATE();
1768     FORCE_RET();
1769 }
1770
1771 void op_ctc1 (void)
1772 {
1773     CALL_FROM_TB1(do_ctc1, PARAM1);
1774     DEBUG_FPU_STATE();
1775     FORCE_RET();
1776 }
1777
1778 void op_mfc1 (void)
1779 {
1780     T0 = (int32_t)WT0;
1781     DEBUG_FPU_STATE();
1782     FORCE_RET();
1783 }
1784
1785 void op_mtc1 (void)
1786 {
1787     WT0 = T0;
1788     DEBUG_FPU_STATE();
1789     FORCE_RET();
1790 }
1791
1792 void op_dmfc1 (void)
1793 {
1794     T0 = DT0;
1795     DEBUG_FPU_STATE();
1796     FORCE_RET();
1797 }
1798
1799 void op_dmtc1 (void)
1800 {
1801     DT0 = T0;
1802     DEBUG_FPU_STATE();
1803     FORCE_RET();
1804 }
1805
1806 void op_mfhc1 (void)
1807 {
1808     T0 = (int32_t)WTH0;
1809     DEBUG_FPU_STATE();
1810     FORCE_RET();
1811 }
1812
1813 void op_mthc1 (void)
1814 {
1815     WTH0 = T0;
1816     DEBUG_FPU_STATE();
1817     FORCE_RET();
1818 }
1819
1820 /* Float support.
1821    Single precition routines have a "s" suffix, double precision a
1822    "d" suffix, 32bit integer "w", 64bit integer "l", paired singe "ps",
1823    paired single lowwer "pl", paired single upper "pu".  */
1824
1825 #define FLOAT_OP(name, p) void OPPROTO op_float_##name##_##p(void)
1826
1827 FLOAT_OP(cvtd, s)
1828 {
1829     CALL_FROM_TB0(do_float_cvtd_s);
1830     DEBUG_FPU_STATE();
1831     FORCE_RET();
1832 }
1833 FLOAT_OP(cvtd, w)
1834 {
1835     CALL_FROM_TB0(do_float_cvtd_w);
1836     DEBUG_FPU_STATE();
1837     FORCE_RET();
1838 }
1839 FLOAT_OP(cvtd, l)
1840 {
1841     CALL_FROM_TB0(do_float_cvtd_l);
1842     DEBUG_FPU_STATE();
1843     FORCE_RET();
1844 }
1845 FLOAT_OP(cvtl, d)
1846 {
1847     CALL_FROM_TB0(do_float_cvtl_d);
1848     DEBUG_FPU_STATE();
1849     FORCE_RET();
1850 }
1851 FLOAT_OP(cvtl, s)
1852 {
1853     CALL_FROM_TB0(do_float_cvtl_s);
1854     DEBUG_FPU_STATE();
1855     FORCE_RET();
1856 }
1857 FLOAT_OP(cvtps, s)
1858 {
1859     WT2 = WT0;
1860     WTH2 = WT1;
1861     DEBUG_FPU_STATE();
1862     FORCE_RET();
1863 }
1864 FLOAT_OP(cvtps, pw)
1865 {
1866     CALL_FROM_TB0(do_float_cvtps_pw);
1867     DEBUG_FPU_STATE();
1868     FORCE_RET();
1869 }
1870 FLOAT_OP(cvtpw, ps)
1871 {
1872     CALL_FROM_TB0(do_float_cvtpw_ps);
1873     DEBUG_FPU_STATE();
1874     FORCE_RET();
1875 }
1876 FLOAT_OP(cvts, d)
1877 {
1878     CALL_FROM_TB0(do_float_cvts_d);
1879     DEBUG_FPU_STATE();
1880     FORCE_RET();
1881 }
1882 FLOAT_OP(cvts, w)
1883 {
1884     CALL_FROM_TB0(do_float_cvts_w);
1885     DEBUG_FPU_STATE();
1886     FORCE_RET();
1887 }
1888 FLOAT_OP(cvts, l)
1889 {
1890     CALL_FROM_TB0(do_float_cvts_l);
1891     DEBUG_FPU_STATE();
1892     FORCE_RET();
1893 }
1894 FLOAT_OP(cvts, pl)
1895 {
1896     CALL_FROM_TB0(do_float_cvts_pl);
1897     DEBUG_FPU_STATE();
1898     FORCE_RET();
1899 }
1900 FLOAT_OP(cvts, pu)
1901 {
1902     CALL_FROM_TB0(do_float_cvts_pu);
1903     DEBUG_FPU_STATE();
1904     FORCE_RET();
1905 }
1906 FLOAT_OP(cvtw, s)
1907 {
1908     CALL_FROM_TB0(do_float_cvtw_s);
1909     DEBUG_FPU_STATE();
1910     FORCE_RET();
1911 }
1912 FLOAT_OP(cvtw, d)
1913 {
1914     CALL_FROM_TB0(do_float_cvtw_d);
1915     DEBUG_FPU_STATE();
1916     FORCE_RET();
1917 }
1918
1919 FLOAT_OP(pll, ps)
1920 {
1921     DT2 = ((uint64_t)WT0 << 32) | WT1;
1922     DEBUG_FPU_STATE();
1923     FORCE_RET();
1924 }
1925 FLOAT_OP(plu, ps)
1926 {
1927     DT2 = ((uint64_t)WT0 << 32) | WTH1;
1928     DEBUG_FPU_STATE();
1929     FORCE_RET();
1930 }
1931 FLOAT_OP(pul, ps)
1932 {
1933     DT2 = ((uint64_t)WTH0 << 32) | WT1;
1934     DEBUG_FPU_STATE();
1935     FORCE_RET();
1936 }
1937 FLOAT_OP(puu, ps)
1938 {
1939     DT2 = ((uint64_t)WTH0 << 32) | WTH1;
1940     DEBUG_FPU_STATE();
1941     FORCE_RET();
1942 }
1943
1944 #define FLOAT_ROUNDOP(op, ttype, stype)                    \
1945 FLOAT_OP(op ## ttype, stype)                               \
1946 {                                                          \
1947     CALL_FROM_TB0(do_float_ ## op ## ttype ## _ ## stype); \
1948     DEBUG_FPU_STATE();                                     \
1949     FORCE_RET();                                           \
1950 }
1951
1952 FLOAT_ROUNDOP(round, l, d)
1953 FLOAT_ROUNDOP(round, l, s)
1954 FLOAT_ROUNDOP(round, w, d)
1955 FLOAT_ROUNDOP(round, w, s)
1956
1957 FLOAT_ROUNDOP(trunc, l, d)
1958 FLOAT_ROUNDOP(trunc, l, s)
1959 FLOAT_ROUNDOP(trunc, w, d)
1960 FLOAT_ROUNDOP(trunc, w, s)
1961
1962 FLOAT_ROUNDOP(ceil, l, d)
1963 FLOAT_ROUNDOP(ceil, l, s)
1964 FLOAT_ROUNDOP(ceil, w, d)
1965 FLOAT_ROUNDOP(ceil, w, s)
1966
1967 FLOAT_ROUNDOP(floor, l, d)
1968 FLOAT_ROUNDOP(floor, l, s)
1969 FLOAT_ROUNDOP(floor, w, d)
1970 FLOAT_ROUNDOP(floor, w, s)
1971 #undef FLOAR_ROUNDOP
1972
1973 FLOAT_OP(movf, d)
1974 {
1975     if (!(env->fpu->fcr31 & PARAM1))
1976         DT2 = DT0;
1977     DEBUG_FPU_STATE();
1978     FORCE_RET();
1979 }
1980 FLOAT_OP(movf, s)
1981 {
1982     if (!(env->fpu->fcr31 & PARAM1))
1983         WT2 = WT0;
1984     DEBUG_FPU_STATE();
1985     FORCE_RET();
1986 }
1987 FLOAT_OP(movf, ps)
1988 {
1989     if (!(env->fpu->fcr31 & PARAM1)) {
1990         WT2 = WT0;
1991         WTH2 = WTH0;
1992     }
1993     DEBUG_FPU_STATE();
1994     FORCE_RET();
1995 }
1996 FLOAT_OP(movt, d)
1997 {
1998     if (env->fpu->fcr31 & PARAM1)
1999         DT2 = DT0;
2000     DEBUG_FPU_STATE();
2001     FORCE_RET();
2002 }
2003 FLOAT_OP(movt, s)
2004 {
2005     if (env->fpu->fcr31 & PARAM1)
2006         WT2 = WT0;
2007     DEBUG_FPU_STATE();
2008     FORCE_RET();
2009 }
2010 FLOAT_OP(movt, ps)
2011 {
2012     if (env->fpu->fcr31 & PARAM1) {
2013         WT2 = WT0;
2014         WTH2 = WTH0;
2015     }
2016     DEBUG_FPU_STATE();
2017     FORCE_RET();
2018 }
2019 FLOAT_OP(movz, d)
2020 {
2021     if (!T0)
2022         DT2 = DT0;
2023     DEBUG_FPU_STATE();
2024     FORCE_RET();
2025 }
2026 FLOAT_OP(movz, s)
2027 {
2028     if (!T0)
2029         WT2 = WT0;
2030     DEBUG_FPU_STATE();
2031     FORCE_RET();
2032 }
2033 FLOAT_OP(movz, ps)
2034 {
2035     if (!T0) {
2036         WT2 = WT0;
2037         WTH2 = WTH0;
2038     }
2039     DEBUG_FPU_STATE();
2040     FORCE_RET();
2041 }
2042 FLOAT_OP(movn, d)
2043 {
2044     if (T0)
2045         DT2 = DT0;
2046     DEBUG_FPU_STATE();
2047     FORCE_RET();
2048 }
2049 FLOAT_OP(movn, s)
2050 {
2051     if (T0)
2052         WT2 = WT0;
2053     DEBUG_FPU_STATE();
2054     FORCE_RET();
2055 }
2056 FLOAT_OP(movn, ps)
2057 {
2058     if (T0) {
2059         WT2 = WT0;
2060         WTH2 = WTH0;
2061     }
2062     DEBUG_FPU_STATE();
2063     FORCE_RET();
2064 }
2065
2066 /* operations calling helpers, for s, d and ps */
2067 #define FLOAT_HOP(name)   \
2068 FLOAT_OP(name, d)         \
2069 {                         \
2070     CALL_FROM_TB0(do_float_ ## name ## _d);  \
2071     DEBUG_FPU_STATE();    \
2072     FORCE_RET();          \
2073 }                         \
2074 FLOAT_OP(name, s)         \
2075 {                         \
2076     CALL_FROM_TB0(do_float_ ## name ## _s);  \
2077     DEBUG_FPU_STATE();    \
2078     FORCE_RET();          \
2079 }                         \
2080 FLOAT_OP(name, ps)        \
2081 {                         \
2082     CALL_FROM_TB0(do_float_ ## name ## _ps); \
2083     DEBUG_FPU_STATE();    \
2084     FORCE_RET();          \
2085 }
2086 FLOAT_HOP(add)
2087 FLOAT_HOP(sub)
2088 FLOAT_HOP(mul)
2089 FLOAT_HOP(div)
2090 FLOAT_HOP(recip2)
2091 FLOAT_HOP(rsqrt2)
2092 FLOAT_HOP(rsqrt1)
2093 FLOAT_HOP(recip1)
2094 #undef FLOAT_HOP
2095
2096 /* operations calling helpers, for s and d */
2097 #define FLOAT_HOP(name)   \
2098 FLOAT_OP(name, d)         \
2099 {                         \
2100     CALL_FROM_TB0(do_float_ ## name ## _d);  \
2101     DEBUG_FPU_STATE();    \
2102     FORCE_RET();          \
2103 }                         \
2104 FLOAT_OP(name, s)         \
2105 {                         \
2106     CALL_FROM_TB0(do_float_ ## name ## _s);  \
2107     DEBUG_FPU_STATE();    \
2108     FORCE_RET();          \
2109 }
2110 FLOAT_HOP(rsqrt)
2111 FLOAT_HOP(recip)
2112 #undef FLOAT_HOP
2113
2114 /* operations calling helpers, for ps */
2115 #define FLOAT_HOP(name)   \
2116 FLOAT_OP(name, ps)        \
2117 {                         \
2118     CALL_FROM_TB0(do_float_ ## name ## _ps); \
2119     DEBUG_FPU_STATE();    \
2120     FORCE_RET();          \
2121 }
2122 FLOAT_HOP(addr)
2123 FLOAT_HOP(mulr)
2124 #undef FLOAT_HOP
2125
2126 /* ternary operations */
2127 #define FLOAT_TERNOP(name1, name2) \
2128 FLOAT_OP(name1 ## name2, d)        \
2129 {                                  \
2130     FDT0 = float64_ ## name1 (FDT0, FDT1, &env->fpu->fp_status);    \
2131     FDT2 = float64_ ## name2 (FDT0, FDT2, &env->fpu->fp_status);    \
2132     DEBUG_FPU_STATE();             \
2133     FORCE_RET();                   \
2134 }                                  \
2135 FLOAT_OP(name1 ## name2, s)        \
2136 {                                  \
2137     FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status);    \
2138     FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status);    \
2139     DEBUG_FPU_STATE();             \
2140     FORCE_RET();                   \
2141 }                                  \
2142 FLOAT_OP(name1 ## name2, ps)       \
2143 {                                  \
2144     FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status);    \
2145     FSTH0 = float32_ ## name1 (FSTH0, FSTH1, &env->fpu->fp_status); \
2146     FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status);    \
2147     FSTH2 = float32_ ## name2 (FSTH0, FSTH2, &env->fpu->fp_status); \
2148     DEBUG_FPU_STATE();             \
2149     FORCE_RET();                   \
2150 }
2151 FLOAT_TERNOP(mul, add)
2152 FLOAT_TERNOP(mul, sub)
2153 #undef FLOAT_TERNOP
2154
2155 /* negated ternary operations */
2156 #define FLOAT_NTERNOP(name1, name2) \
2157 FLOAT_OP(n ## name1 ## name2, d)    \
2158 {                                   \
2159     FDT0 = float64_ ## name1 (FDT0, FDT1, &env->fpu->fp_status);    \
2160     FDT2 = float64_ ## name2 (FDT0, FDT2, &env->fpu->fp_status);    \
2161     FDT2 = float64_chs(FDT2);       \
2162     DEBUG_FPU_STATE();              \
2163     FORCE_RET();                    \
2164 }                                   \
2165 FLOAT_OP(n ## name1 ## name2, s)    \
2166 {                                   \
2167     FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status);    \
2168     FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status);    \
2169     FST2 = float32_chs(FST2);       \
2170     DEBUG_FPU_STATE();              \
2171     FORCE_RET();                    \
2172 }                                   \
2173 FLOAT_OP(n ## name1 ## name2, ps)   \
2174 {                                   \
2175     FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status);    \
2176     FSTH0 = float32_ ## name1 (FSTH0, FSTH1, &env->fpu->fp_status); \
2177     FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status);    \
2178     FSTH2 = float32_ ## name2 (FSTH0, FSTH2, &env->fpu->fp_status); \
2179     FST2 = float32_chs(FST2);       \
2180     FSTH2 = float32_chs(FSTH2);     \
2181     DEBUG_FPU_STATE();              \
2182     FORCE_RET();                    \
2183 }
2184 FLOAT_NTERNOP(mul, add)
2185 FLOAT_NTERNOP(mul, sub)
2186 #undef FLOAT_NTERNOP
2187
2188 /* unary operations, modifying fp status  */
2189 #define FLOAT_UNOP(name)  \
2190 FLOAT_OP(name, d)         \
2191 {                         \
2192     FDT2 = float64_ ## name(FDT0, &env->fpu->fp_status); \
2193     DEBUG_FPU_STATE();    \
2194     FORCE_RET();          \
2195 }                         \
2196 FLOAT_OP(name, s)         \
2197 {                         \
2198     FST2 = float32_ ## name(FST0, &env->fpu->fp_status); \
2199     DEBUG_FPU_STATE();    \
2200     FORCE_RET();          \
2201 }
2202 FLOAT_UNOP(sqrt)
2203 #undef FLOAT_UNOP
2204
2205 /* unary operations, not modifying fp status  */
2206 #define FLOAT_UNOP(name)  \
2207 FLOAT_OP(name, d)         \
2208 {                         \
2209     FDT2 = float64_ ## name(FDT0);   \
2210     DEBUG_FPU_STATE();    \
2211     FORCE_RET();          \
2212 }                         \
2213 FLOAT_OP(name, s)         \
2214 {                         \
2215     FST2 = float32_ ## name(FST0);   \
2216     DEBUG_FPU_STATE();    \
2217     FORCE_RET();          \
2218 }                         \
2219 FLOAT_OP(name, ps)        \
2220 {                         \
2221     FST2 = float32_ ## name(FST0);   \
2222     FSTH2 = float32_ ## name(FSTH0); \
2223     DEBUG_FPU_STATE();    \
2224     FORCE_RET();          \
2225 }
2226 FLOAT_UNOP(abs)
2227 FLOAT_UNOP(chs)
2228 #undef FLOAT_UNOP
2229
2230 FLOAT_OP(mov, d)
2231 {
2232     FDT2 = FDT0;
2233     DEBUG_FPU_STATE();
2234     FORCE_RET();
2235 }
2236 FLOAT_OP(mov, s)
2237 {
2238     FST2 = FST0;
2239     DEBUG_FPU_STATE();
2240     FORCE_RET();
2241 }
2242 FLOAT_OP(mov, ps)
2243 {
2244     FST2 = FST0;
2245     FSTH2 = FSTH0;
2246     DEBUG_FPU_STATE();
2247     FORCE_RET();
2248 }
2249 FLOAT_OP(alnv, ps)
2250 {
2251     switch (T0 & 0x7) {
2252     case 0:
2253         FST2 = FST0;
2254         FSTH2 = FSTH0;
2255         break;
2256     case 4:
2257 #ifdef TARGET_WORDS_BIGENDIAN
2258         FSTH2 = FST0;
2259         FST2 = FSTH1;
2260 #else
2261         FSTH2 = FST1;
2262         FST2 = FSTH0;
2263 #endif
2264         break;
2265     default: /* unpredictable */
2266         break;
2267     }
2268     DEBUG_FPU_STATE();
2269     FORCE_RET();
2270 }
2271
2272 #ifdef CONFIG_SOFTFLOAT
2273 #define clear_invalid() do {                                \
2274     int flags = get_float_exception_flags(&env->fpu->fp_status); \
2275     flags &= ~float_flag_invalid;                           \
2276     set_float_exception_flags(flags, &env->fpu->fp_status); \
2277 } while(0)
2278 #else
2279 #define clear_invalid() do { } while(0)
2280 #endif
2281
2282 extern void dump_fpu_s(CPUState *env);
2283
2284 #define CMP_OP(fmt, op)                                \
2285 void OPPROTO op_cmp ## _ ## fmt ## _ ## op(void)       \
2286 {                                                      \
2287     CALL_FROM_TB1(do_cmp ## _ ## fmt ## _ ## op, PARAM1); \
2288     DEBUG_FPU_STATE();                                 \
2289     FORCE_RET();                                       \
2290 }                                                      \
2291 void OPPROTO op_cmpabs ## _ ## fmt ## _ ## op(void)    \
2292 {                                                      \
2293     CALL_FROM_TB1(do_cmpabs ## _ ## fmt ## _ ## op, PARAM1); \
2294     DEBUG_FPU_STATE();                                 \
2295     FORCE_RET();                                       \
2296 }
2297 #define CMP_OPS(op)   \
2298 CMP_OP(d, op)         \
2299 CMP_OP(s, op)         \
2300 CMP_OP(ps, op)
2301
2302 CMP_OPS(f)
2303 CMP_OPS(un)
2304 CMP_OPS(eq)
2305 CMP_OPS(ueq)
2306 CMP_OPS(olt)
2307 CMP_OPS(ult)
2308 CMP_OPS(ole)
2309 CMP_OPS(ule)
2310 CMP_OPS(sf)
2311 CMP_OPS(ngle)
2312 CMP_OPS(seq)
2313 CMP_OPS(ngl)
2314 CMP_OPS(lt)
2315 CMP_OPS(nge)
2316 CMP_OPS(le)
2317 CMP_OPS(ngt)
2318 #undef CMP_OPS
2319 #undef CMP_OP
2320
2321 void op_bc1f (void)
2322 {
2323     T0 = !!(~GET_FP_COND(env->fpu) & (0x1 << PARAM1));
2324     DEBUG_FPU_STATE();
2325     FORCE_RET();
2326 }
2327 void op_bc1any2f (void)
2328 {
2329     T0 = !!(~GET_FP_COND(env->fpu) & (0x3 << PARAM1));
2330     DEBUG_FPU_STATE();
2331     FORCE_RET();
2332 }
2333 void op_bc1any4f (void)
2334 {
2335     T0 = !!(~GET_FP_COND(env->fpu) & (0xf << PARAM1));
2336     DEBUG_FPU_STATE();
2337     FORCE_RET();
2338 }
2339
2340 void op_bc1t (void)
2341 {
2342     T0 = !!(GET_FP_COND(env->fpu) & (0x1 << PARAM1));
2343     DEBUG_FPU_STATE();
2344     FORCE_RET();
2345 }
2346 void op_bc1any2t (void)
2347 {
2348     T0 = !!(GET_FP_COND(env->fpu) & (0x3 << PARAM1));
2349     DEBUG_FPU_STATE();
2350     FORCE_RET();
2351 }
2352 void op_bc1any4t (void)
2353 {
2354     T0 = !!(GET_FP_COND(env->fpu) & (0xf << PARAM1));
2355     DEBUG_FPU_STATE();
2356     FORCE_RET();
2357 }
2358
2359 void op_tlbwi (void)
2360 {
2361     CALL_FROM_TB0(env->tlb->do_tlbwi);
2362     FORCE_RET();
2363 }
2364
2365 void op_tlbwr (void)
2366 {
2367     CALL_FROM_TB0(env->tlb->do_tlbwr);
2368     FORCE_RET();
2369 }
2370
2371 void op_tlbp (void)
2372 {
2373     CALL_FROM_TB0(env->tlb->do_tlbp);
2374     FORCE_RET();
2375 }
2376
2377 void op_tlbr (void)
2378 {
2379     CALL_FROM_TB0(env->tlb->do_tlbr);
2380     FORCE_RET();
2381 }
2382
2383 /* Specials */
2384 #if defined (CONFIG_USER_ONLY)
2385 void op_tls_value (void)
2386 {
2387     T0 = env->tls_value;
2388 }
2389 #endif
2390
2391 void op_pmon (void)
2392 {
2393     CALL_FROM_TB1(do_pmon, PARAM1);
2394     FORCE_RET();
2395 }
2396
2397 void op_di (void)
2398 {
2399     T0 = env->CP0_Status;
2400     env->CP0_Status = T0 & ~(1 << CP0St_IE);
2401     CALL_FROM_TB1(cpu_mips_update_irq, env);
2402     FORCE_RET();
2403 }
2404
2405 void op_ei (void)
2406 {
2407     T0 = env->CP0_Status;
2408     env->CP0_Status = T0 | (1 << CP0St_IE);
2409     CALL_FROM_TB1(cpu_mips_update_irq, env);
2410     FORCE_RET();
2411 }
2412
2413 void op_trap (void)
2414 {
2415     if (T0) {
2416         CALL_FROM_TB1(do_raise_exception, EXCP_TRAP);
2417     }
2418     FORCE_RET();
2419 }
2420
2421 void op_debug (void)
2422 {
2423     CALL_FROM_TB1(do_raise_exception, EXCP_DEBUG);
2424     FORCE_RET();
2425 }
2426
2427 void debug_pre_eret (void);
2428 void debug_post_eret (void);
2429 void op_eret (void)
2430 {
2431     if (loglevel & CPU_LOG_EXEC)
2432         CALL_FROM_TB0(debug_pre_eret);
2433     if (env->CP0_Status & (1 << CP0St_ERL)) {
2434         env->PC[env->current_tc] = env->CP0_ErrorEPC;
2435         env->CP0_Status &= ~(1 << CP0St_ERL);
2436     } else {
2437         env->PC[env->current_tc] = env->CP0_EPC;
2438         env->CP0_Status &= ~(1 << CP0St_EXL);
2439     }
2440     CALL_FROM_TB1(compute_hflags, env);
2441     if (loglevel & CPU_LOG_EXEC)
2442         CALL_FROM_TB0(debug_post_eret);
2443     env->CP0_LLAddr = 1;
2444     FORCE_RET();
2445 }
2446
2447 void op_deret (void)
2448 {
2449     if (loglevel & CPU_LOG_EXEC)
2450         CALL_FROM_TB0(debug_pre_eret);
2451     env->PC[env->current_tc] = env->CP0_DEPC;
2452     env->hflags &= MIPS_HFLAG_DM;
2453     CALL_FROM_TB1(compute_hflags, env);
2454     if (loglevel & CPU_LOG_EXEC)
2455         CALL_FROM_TB0(debug_post_eret);
2456     env->CP0_LLAddr = 1;
2457     FORCE_RET();
2458 }
2459
2460 void op_rdhwr_cpunum(void)
2461 {
2462     if ((env->hflags & MIPS_HFLAG_CP0) ||
2463         (env->CP0_HWREna & (1 << 0)))
2464         T0 = env->CP0_EBase & 0x3ff;
2465     else
2466         CALL_FROM_TB1(do_raise_exception, EXCP_RI);
2467     FORCE_RET();
2468 }
2469
2470 void op_rdhwr_synci_step(void)
2471 {
2472     if ((env->hflags & MIPS_HFLAG_CP0) ||
2473         (env->CP0_HWREna & (1 << 1)))
2474         T0 = env->SYNCI_Step;
2475     else
2476         CALL_FROM_TB1(do_raise_exception, EXCP_RI);
2477     FORCE_RET();
2478 }
2479
2480 void op_rdhwr_cc(void)
2481 {
2482     if ((env->hflags & MIPS_HFLAG_CP0) ||
2483         (env->CP0_HWREna & (1 << 2)))
2484         T0 = env->CP0_Count;
2485     else
2486         CALL_FROM_TB1(do_raise_exception, EXCP_RI);
2487     FORCE_RET();
2488 }
2489
2490 void op_rdhwr_ccres(void)
2491 {
2492     if ((env->hflags & MIPS_HFLAG_CP0) ||
2493         (env->CP0_HWREna & (1 << 3)))
2494         T0 = env->CCRes;
2495     else
2496         CALL_FROM_TB1(do_raise_exception, EXCP_RI);
2497     FORCE_RET();
2498 }
2499
2500 void op_save_state (void)
2501 {
2502     env->hflags = PARAM1;
2503     FORCE_RET();
2504 }
2505
2506 void op_wait (void)
2507 {
2508     env->halted = 1;
2509     CALL_FROM_TB1(do_raise_exception, EXCP_HLT);
2510     FORCE_RET();
2511 }
2512
2513 /* Bitfield operations. */
2514 void op_ext(void)
2515 {
2516     unsigned int pos = PARAM1;
2517     unsigned int size = PARAM2;
2518
2519     T0 = (int32_t)((T1 >> pos) & ((size < 32) ? ((1 << size) - 1) : ~0));
2520     FORCE_RET();
2521 }
2522
2523 void op_ins(void)
2524 {
2525     unsigned int pos = PARAM1;
2526     unsigned int size = PARAM2;
2527     target_ulong mask = ((size < 32) ? ((1 << size) - 1) : ~0) << pos;
2528
2529     T0 = (int32_t)((T0 & ~mask) | ((T1 << pos) & mask));
2530     FORCE_RET();
2531 }
2532
2533 void op_wsbh(void)
2534 {
2535     T0 = (int32_t)(((T1 << 8) & ~0x00FF00FF) | ((T1 >> 8) & 0x00FF00FF));
2536     FORCE_RET();
2537 }
2538
2539 #if defined(TARGET_MIPS64)
2540 void op_dext(void)
2541 {
2542     unsigned int pos = PARAM1;
2543     unsigned int size = PARAM2;
2544
2545     T0 = (T1 >> pos) & ((size < 64) ? ((1ULL << size) - 1) : ~0ULL);
2546     FORCE_RET();
2547 }
2548
2549 void op_dins(void)
2550 {
2551     unsigned int pos = PARAM1;
2552     unsigned int size = PARAM2;
2553     target_ulong mask = ((size < 64) ? ((1ULL << size) - 1) : ~0ULL) << pos;
2554
2555     T0 = (T0 & ~mask) | ((T1 << pos) & mask);
2556     FORCE_RET();
2557 }
2558
2559 void op_dsbh(void)
2560 {
2561     T0 = ((T1 << 8) & ~0x00FF00FF00FF00FFULL) | ((T1 >> 8) & 0x00FF00FF00FF00FFULL);
2562     FORCE_RET();
2563 }
2564
2565 void op_dshd(void)
2566 {
2567     T1 = ((T1 << 16) & ~0x0000FFFF0000FFFFULL) | ((T1 >> 16) & 0x0000FFFF0000FFFFULL);
2568     T0 = (T1 << 32) | (T1 >> 32);
2569     FORCE_RET();
2570 }
2571 #endif
This page took 0.165881 seconds and 4 git commands to generate.