]> Git Repo - qemu.git/blob - target-mips/op.c
Fix mov[tf].ps handling for MIPS, by Richard Sandiford.
[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_mvpcontrol (void)
465 {
466     T0 = env->mvp->CP0_MVPControl;
467     FORCE_RET();
468 }
469
470 void op_mfc0_mvpconf0 (void)
471 {
472     T0 = env->mvp->CP0_MVPConf0;
473     FORCE_RET();
474 }
475
476 void op_mfc0_mvpconf1 (void)
477 {
478     T0 = env->mvp->CP0_MVPConf1;
479     FORCE_RET();
480 }
481
482 void op_mfc0_random (void)
483 {
484     CALL_FROM_TB0(do_mfc0_random);
485     FORCE_RET();
486 }
487
488 void op_mfc0_tcstatus (void)
489 {
490     T0 = env->CP0_TCStatus[env->current_tc];
491     FORCE_RET();
492 }
493
494 void op_mftc0_tcstatus(void)
495 {
496     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
497
498     T0 = env->CP0_TCStatus[other_tc];
499     FORCE_RET();
500 }
501
502 void op_mfc0_tcbind (void)
503 {
504     T0 = env->CP0_TCBind[env->current_tc];
505     FORCE_RET();
506 }
507
508 void op_mftc0_tcbind(void)
509 {
510     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
511
512     T0 = env->CP0_TCBind[other_tc];
513     FORCE_RET();
514 }
515
516 void op_mfc0_tcrestart (void)
517 {
518     T0 = env->PC[env->current_tc];
519     FORCE_RET();
520 }
521
522 void op_mftc0_tcrestart(void)
523 {
524     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
525
526     T0 = env->PC[other_tc];
527     FORCE_RET();
528 }
529
530 void op_mfc0_tchalt (void)
531 {
532     T0 = env->CP0_TCHalt[env->current_tc];
533     FORCE_RET();
534 }
535
536 void op_mftc0_tchalt(void)
537 {
538     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
539
540     T0 = env->CP0_TCHalt[other_tc];
541     FORCE_RET();
542 }
543
544 void op_mfc0_tccontext (void)
545 {
546     T0 = env->CP0_TCContext[env->current_tc];
547     FORCE_RET();
548 }
549
550 void op_mftc0_tccontext(void)
551 {
552     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
553
554     T0 = env->CP0_TCContext[other_tc];
555     FORCE_RET();
556 }
557
558 void op_mfc0_tcschedule (void)
559 {
560     T0 = env->CP0_TCSchedule[env->current_tc];
561     FORCE_RET();
562 }
563
564 void op_mftc0_tcschedule(void)
565 {
566     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
567
568     T0 = env->CP0_TCSchedule[other_tc];
569     FORCE_RET();
570 }
571
572 void op_mfc0_tcschefback (void)
573 {
574     T0 = env->CP0_TCScheFBack[env->current_tc];
575     FORCE_RET();
576 }
577
578 void op_mftc0_tcschefback(void)
579 {
580     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
581
582     T0 = env->CP0_TCScheFBack[other_tc];
583     FORCE_RET();
584 }
585
586 void op_mfc0_count (void)
587 {
588     CALL_FROM_TB0(do_mfc0_count);
589     FORCE_RET();
590 }
591
592 void op_mftc0_entryhi(void)
593 {
594     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
595
596     T0 = (env->CP0_EntryHi & ~0xff) | (env->CP0_TCStatus[other_tc] & 0xff);
597     FORCE_RET();
598 }
599
600 void op_mftc0_status(void)
601 {
602     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
603     uint32_t tcstatus = env->CP0_TCStatus[other_tc];
604
605     T0 = env->CP0_Status & ~0xf1000018;
606     T0 |= tcstatus & (0xf << CP0TCSt_TCU0);
607     T0 |= (tcstatus & (1 << CP0TCSt_TMX)) >> (CP0TCSt_TMX - CP0St_MX);
608     T0 |= (tcstatus & (0x3 << CP0TCSt_TKSU)) >> (CP0TCSt_TKSU - CP0St_KSU);
609     FORCE_RET();
610 }
611
612 void op_mfc0_lladdr (void)
613 {
614     T0 = (int32_t)env->CP0_LLAddr >> 4;
615     FORCE_RET();
616 }
617
618 void op_mfc0_watchlo (void)
619 {
620     T0 = (int32_t)env->CP0_WatchLo[PARAM1];
621     FORCE_RET();
622 }
623
624 void op_mfc0_watchhi (void)
625 {
626     T0 = env->CP0_WatchHi[PARAM1];
627     FORCE_RET();
628 }
629
630 void op_mfc0_debug (void)
631 {
632     T0 = env->CP0_Debug;
633     if (env->hflags & MIPS_HFLAG_DM)
634         T0 |= 1 << CP0DB_DM;
635     FORCE_RET();
636 }
637
638 void op_mftc0_debug(void)
639 {
640     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
641
642     /* XXX: Might be wrong, check with EJTAG spec. */
643     T0 = (env->CP0_Debug & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) |
644          (env->CP0_Debug_tcstatus[other_tc] &
645           ((1 << CP0DB_SSt) | (1 << CP0DB_Halt)));
646     FORCE_RET();
647 }
648
649 void op_mtc0_index (void)
650 {
651     int num = 1;
652     unsigned int tmp = env->tlb->nb_tlb;
653
654     do {
655         tmp >>= 1;
656         num <<= 1;
657     } while (tmp);
658     env->CP0_Index = (env->CP0_Index & 0x80000000) | (T0 & (num - 1));
659     FORCE_RET();
660 }
661
662 void op_mtc0_mvpcontrol (void)
663 {
664     uint32_t mask = 0;
665     uint32_t newval;
666
667     if (env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP))
668         mask |= (1 << CP0MVPCo_CPA) | (1 << CP0MVPCo_VPC) |
669                 (1 << CP0MVPCo_EVP);
670     if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
671         mask |= (1 << CP0MVPCo_STLB);
672     newval = (env->mvp->CP0_MVPControl & ~mask) | (T0 & mask);
673
674     // TODO: Enable/disable shared TLB, enable/disable VPEs.
675
676     env->mvp->CP0_MVPControl = newval;
677     FORCE_RET();
678 }
679
680 void op_mtc0_vpecontrol (void)
681 {
682     uint32_t mask;
683     uint32_t newval;
684
685     mask = (1 << CP0VPECo_YSI) | (1 << CP0VPECo_GSI) |
686            (1 << CP0VPECo_TE) | (0xff << CP0VPECo_TargTC);
687     newval = (env->CP0_VPEControl & ~mask) | (T0 & mask);
688
689     /* Yield scheduler intercept not implemented. */
690     /* Gating storage scheduler intercept not implemented. */
691
692     // TODO: Enable/disable TCs.
693
694     env->CP0_VPEControl = newval;
695     FORCE_RET();
696 }
697
698 void op_mtc0_vpeconf0 (void)
699 {
700     uint32_t mask = 0;
701     uint32_t newval;
702
703     if (env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) {
704         if (env->CP0_VPEConf0 & (1 << CP0VPEC0_VPA))
705             mask |= (0xff << CP0VPEC0_XTC);
706         mask |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
707     }
708     newval = (env->CP0_VPEConf0 & ~mask) | (T0 & mask);
709
710     // TODO: TC exclusive handling due to ERL/EXL.
711
712     env->CP0_VPEConf0 = newval;
713     FORCE_RET();
714 }
715
716 void op_mtc0_vpeconf1 (void)
717 {
718     uint32_t mask = 0;
719     uint32_t newval;
720
721     if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
722         mask |= (0xff << CP0VPEC1_NCX) | (0xff << CP0VPEC1_NCP2) |
723                 (0xff << CP0VPEC1_NCP1);
724     newval = (env->CP0_VPEConf1 & ~mask) | (T0 & mask);
725
726     /* UDI not implemented. */
727     /* CP2 not implemented. */
728
729     // TODO: Handle FPU (CP1) binding.
730
731     env->CP0_VPEConf1 = newval;
732     FORCE_RET();
733 }
734
735 void op_mtc0_yqmask (void)
736 {
737     /* Yield qualifier inputs not implemented. */
738     env->CP0_YQMask = 0x00000000;
739     FORCE_RET();
740 }
741
742 void op_mtc0_vpeschedule (void)
743 {
744     env->CP0_VPESchedule = T0;
745     FORCE_RET();
746 }
747
748 void op_mtc0_vpeschefback (void)
749 {
750     env->CP0_VPEScheFBack = T0;
751     FORCE_RET();
752 }
753
754 void op_mtc0_vpeopt (void)
755 {
756     env->CP0_VPEOpt = T0 & 0x0000ffff;
757     FORCE_RET();
758 }
759
760 void op_mtc0_entrylo0 (void)
761 {
762     /* Large physaddr (PABITS) not implemented */
763     /* 1k pages not implemented */
764     env->CP0_EntryLo0 = T0 & 0x3FFFFFFF;
765     FORCE_RET();
766 }
767
768 void op_mtc0_tcstatus (void)
769 {
770     uint32_t mask = env->CP0_TCStatus_rw_bitmask;
771     uint32_t newval;
772
773     newval = (env->CP0_TCStatus[env->current_tc] & ~mask) | (T0 & mask);
774
775     // TODO: Sync with CP0_Status.
776
777     env->CP0_TCStatus[env->current_tc] = newval;
778     FORCE_RET();
779 }
780
781 void op_mttc0_tcstatus (void)
782 {
783     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
784
785     // TODO: Sync with CP0_Status.
786
787     env->CP0_TCStatus[other_tc] = T0;
788     FORCE_RET();
789 }
790
791 void op_mtc0_tcbind (void)
792 {
793     uint32_t mask = (1 << CP0TCBd_TBE);
794     uint32_t newval;
795
796     if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
797         mask |= (1 << CP0TCBd_CurVPE);
798     newval = (env->CP0_TCBind[env->current_tc] & ~mask) | (T0 & mask);
799     env->CP0_TCBind[env->current_tc] = newval;
800     FORCE_RET();
801 }
802
803 void op_mttc0_tcbind (void)
804 {
805     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
806     uint32_t mask = (1 << CP0TCBd_TBE);
807     uint32_t newval;
808
809     if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
810         mask |= (1 << CP0TCBd_CurVPE);
811     newval = (env->CP0_TCBind[other_tc] & ~mask) | (T0 & mask);
812     env->CP0_TCBind[other_tc] = newval;
813     FORCE_RET();
814 }
815
816 void op_mtc0_tcrestart (void)
817 {
818     env->PC[env->current_tc] = T0;
819     env->CP0_TCStatus[env->current_tc] &= ~(1 << CP0TCSt_TDS);
820     env->CP0_LLAddr = 0ULL;
821     /* MIPS16 not implemented. */
822     FORCE_RET();
823 }
824
825 void op_mttc0_tcrestart (void)
826 {
827     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
828
829     env->PC[other_tc] = T0;
830     env->CP0_TCStatus[other_tc] &= ~(1 << CP0TCSt_TDS);
831     env->CP0_LLAddr = 0ULL;
832     /* MIPS16 not implemented. */
833     FORCE_RET();
834 }
835
836 void op_mtc0_tchalt (void)
837 {
838     env->CP0_TCHalt[env->current_tc] = T0 & 0x1;
839
840     // TODO: Halt TC / Restart (if allocated+active) TC.
841
842     FORCE_RET();
843 }
844
845 void op_mttc0_tchalt (void)
846 {
847     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
848
849     // TODO: Halt TC / Restart (if allocated+active) TC.
850
851     env->CP0_TCHalt[other_tc] = T0;
852     FORCE_RET();
853 }
854
855 void op_mtc0_tccontext (void)
856 {
857     env->CP0_TCContext[env->current_tc] = T0;
858     FORCE_RET();
859 }
860
861 void op_mttc0_tccontext (void)
862 {
863     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
864
865     env->CP0_TCContext[other_tc] = T0;
866     FORCE_RET();
867 }
868
869 void op_mtc0_tcschedule (void)
870 {
871     env->CP0_TCSchedule[env->current_tc] = T0;
872     FORCE_RET();
873 }
874
875 void op_mttc0_tcschedule (void)
876 {
877     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
878
879     env->CP0_TCSchedule[other_tc] = T0;
880     FORCE_RET();
881 }
882
883 void op_mtc0_tcschefback (void)
884 {
885     env->CP0_TCScheFBack[env->current_tc] = T0;
886     FORCE_RET();
887 }
888
889 void op_mttc0_tcschefback (void)
890 {
891     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
892
893     env->CP0_TCScheFBack[other_tc] = T0;
894     FORCE_RET();
895 }
896
897 void op_mtc0_entrylo1 (void)
898 {
899     /* Large physaddr (PABITS) not implemented */
900     /* 1k pages not implemented */
901     env->CP0_EntryLo1 = T0 & 0x3FFFFFFF;
902     FORCE_RET();
903 }
904
905 void op_mtc0_context (void)
906 {
907     env->CP0_Context = (env->CP0_Context & 0x007FFFFF) | (T0 & ~0x007FFFFF);
908     FORCE_RET();
909 }
910
911 void op_mtc0_pagemask (void)
912 {
913     /* 1k pages not implemented */
914     env->CP0_PageMask = T0 & (0x1FFFFFFF & (TARGET_PAGE_MASK << 1));
915     FORCE_RET();
916 }
917
918 void op_mtc0_pagegrain (void)
919 {
920     /* SmartMIPS not implemented */
921     /* Large physaddr (PABITS) not implemented */
922     /* 1k pages not implemented */
923     env->CP0_PageGrain = 0;
924     FORCE_RET();
925 }
926
927 void op_mtc0_wired (void)
928 {
929     env->CP0_Wired = T0 % env->tlb->nb_tlb;
930     FORCE_RET();
931 }
932
933 void op_mtc0_srsconf0 (void)
934 {
935     env->CP0_SRSConf0 |= T0 & env->CP0_SRSConf0_rw_bitmask;
936     FORCE_RET();
937 }
938
939 void op_mtc0_srsconf1 (void)
940 {
941     env->CP0_SRSConf1 |= T0 & env->CP0_SRSConf1_rw_bitmask;
942     FORCE_RET();
943 }
944
945 void op_mtc0_srsconf2 (void)
946 {
947     env->CP0_SRSConf2 |= T0 & env->CP0_SRSConf2_rw_bitmask;
948     FORCE_RET();
949 }
950
951 void op_mtc0_srsconf3 (void)
952 {
953     env->CP0_SRSConf3 |= T0 & env->CP0_SRSConf3_rw_bitmask;
954     FORCE_RET();
955 }
956
957 void op_mtc0_srsconf4 (void)
958 {
959     env->CP0_SRSConf4 |= T0 & env->CP0_SRSConf4_rw_bitmask;
960     FORCE_RET();
961 }
962
963 void op_mtc0_hwrena (void)
964 {
965     env->CP0_HWREna = T0 & 0x0000000F;
966     FORCE_RET();
967 }
968
969 void op_mtc0_count (void)
970 {
971     CALL_FROM_TB2(cpu_mips_store_count, env, T0);
972     FORCE_RET();
973 }
974
975 void op_mtc0_entryhi (void)
976 {
977     target_ulong old, val;
978
979     /* 1k pages not implemented */
980     val = T0 & ((TARGET_PAGE_MASK << 1) | 0xFF);
981 #if defined(TARGET_MIPS64)
982     val &= env->SEGMask;
983 #endif
984     old = env->CP0_EntryHi;
985     env->CP0_EntryHi = val;
986     if (env->CP0_Config3 & (1 << CP0C3_MT)) {
987         uint32_t tcst = env->CP0_TCStatus[env->current_tc] & ~0xff;
988         env->CP0_TCStatus[env->current_tc] = tcst | (val & 0xff);
989     }
990     /* If the ASID changes, flush qemu's TLB.  */
991     if ((old & 0xFF) != (val & 0xFF))
992         CALL_FROM_TB2(cpu_mips_tlb_flush, env, 1);
993     FORCE_RET();
994 }
995
996 void op_mttc0_entryhi(void)
997 {
998     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
999
1000     env->CP0_EntryHi = (env->CP0_EntryHi & 0xff) | (T0 & ~0xff);
1001     env->CP0_TCStatus[other_tc] = (env->CP0_TCStatus[other_tc] & ~0xff) | (T0 & 0xff);
1002     FORCE_RET();
1003 }
1004
1005 void op_mtc0_compare (void)
1006 {
1007     CALL_FROM_TB2(cpu_mips_store_compare, env, T0);
1008     FORCE_RET();
1009 }
1010
1011 void op_mtc0_status (void)
1012 {
1013     uint32_t val, old;
1014     uint32_t mask = env->CP0_Status_rw_bitmask;
1015
1016     val = T0 & mask;
1017     old = env->CP0_Status;
1018     env->CP0_Status = (env->CP0_Status & ~mask) | val;
1019     CALL_FROM_TB1(compute_hflags, env);
1020     if (loglevel & CPU_LOG_EXEC)
1021         CALL_FROM_TB2(do_mtc0_status_debug, old, val);
1022     CALL_FROM_TB1(cpu_mips_update_irq, env);
1023     FORCE_RET();
1024 }
1025
1026 void op_mttc0_status(void)
1027 {
1028     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1029     uint32_t tcstatus = env->CP0_TCStatus[other_tc];
1030
1031     env->CP0_Status = T0 & ~0xf1000018;
1032     tcstatus = (tcstatus & ~(0xf << CP0TCSt_TCU0)) | (T0 & (0xf << CP0St_CU0));
1033     tcstatus = (tcstatus & ~(1 << CP0TCSt_TMX)) | ((T0 & (1 << CP0St_MX)) << (CP0TCSt_TMX - CP0St_MX));
1034     tcstatus = (tcstatus & ~(0x3 << CP0TCSt_TKSU)) | ((T0 & (0x3 << CP0St_KSU)) << (CP0TCSt_TKSU - CP0St_KSU));
1035     env->CP0_TCStatus[other_tc] = tcstatus;
1036     FORCE_RET();
1037 }
1038
1039 void op_mtc0_intctl (void)
1040 {
1041     /* vectored interrupts not implemented, no performance counters. */
1042     env->CP0_IntCtl = (env->CP0_IntCtl & ~0x000002e0) | (T0 & 0x000002e0);
1043     FORCE_RET();
1044 }
1045
1046 void op_mtc0_srsctl (void)
1047 {
1048     uint32_t mask = (0xf << CP0SRSCtl_ESS) | (0xf << CP0SRSCtl_PSS);
1049     env->CP0_SRSCtl = (env->CP0_SRSCtl & ~mask) | (T0 & mask);
1050     FORCE_RET();
1051 }
1052
1053 void op_mtc0_srsmap (void)
1054 {
1055     env->CP0_SRSMap = T0;
1056     FORCE_RET();
1057 }
1058
1059 void op_mtc0_cause (void)
1060 {
1061     uint32_t mask = 0x00C00300;
1062     uint32_t old = env->CP0_Cause;
1063
1064     if (env->insn_flags & ISA_MIPS32R2)
1065         mask |= 1 << CP0Ca_DC;
1066
1067     env->CP0_Cause = (env->CP0_Cause & ~mask) | (T0 & mask);
1068
1069     if ((old ^ env->CP0_Cause) & (1 << CP0Ca_DC)) {
1070         if (env->CP0_Cause & (1 << CP0Ca_DC))
1071             CALL_FROM_TB1(cpu_mips_stop_count, env);
1072         else
1073             CALL_FROM_TB1(cpu_mips_start_count, env);
1074     }
1075
1076     /* Handle the software interrupt as an hardware one, as they
1077        are very similar */
1078     if (T0 & CP0Ca_IP_mask) {
1079         CALL_FROM_TB1(cpu_mips_update_irq, env);
1080     }
1081     FORCE_RET();
1082 }
1083
1084 void op_mtc0_epc (void)
1085 {
1086     env->CP0_EPC = T0;
1087     FORCE_RET();
1088 }
1089
1090 void op_mtc0_ebase (void)
1091 {
1092     /* vectored interrupts not implemented */
1093     /* Multi-CPU not implemented */
1094     env->CP0_EBase = 0x80000000 | (T0 & 0x3FFFF000);
1095     FORCE_RET();
1096 }
1097
1098 void op_mtc0_config0 (void)
1099 {
1100     env->CP0_Config0 = (env->CP0_Config0 & 0x81FFFFF8) | (T0 & 0x00000007);
1101     FORCE_RET();
1102 }
1103
1104 void op_mtc0_config2 (void)
1105 {
1106     /* tertiary/secondary caches not implemented */
1107     env->CP0_Config2 = (env->CP0_Config2 & 0x8FFF0FFF);
1108     FORCE_RET();
1109 }
1110
1111 void op_mtc0_watchlo (void)
1112 {
1113     /* Watch exceptions for instructions, data loads, data stores
1114        not implemented. */
1115     env->CP0_WatchLo[PARAM1] = (T0 & ~0x7);
1116     FORCE_RET();
1117 }
1118
1119 void op_mtc0_watchhi (void)
1120 {
1121     env->CP0_WatchHi[PARAM1] = (T0 & 0x40FF0FF8);
1122     env->CP0_WatchHi[PARAM1] &= ~(env->CP0_WatchHi[PARAM1] & T0 & 0x7);
1123     FORCE_RET();
1124 }
1125
1126 void op_mtc0_xcontext (void)
1127 {
1128     target_ulong mask = (1ULL << (env->SEGBITS - 7)) - 1;
1129     env->CP0_XContext = (env->CP0_XContext & mask) | (T0 & ~mask);
1130     FORCE_RET();
1131 }
1132
1133 void op_mtc0_framemask (void)
1134 {
1135     env->CP0_Framemask = T0; /* XXX */
1136     FORCE_RET();
1137 }
1138
1139 void op_mtc0_debug (void)
1140 {
1141     env->CP0_Debug = (env->CP0_Debug & 0x8C03FC1F) | (T0 & 0x13300120);
1142     if (T0 & (1 << CP0DB_DM))
1143         env->hflags |= MIPS_HFLAG_DM;
1144     else
1145         env->hflags &= ~MIPS_HFLAG_DM;
1146     FORCE_RET();
1147 }
1148
1149 void op_mttc0_debug(void)
1150 {
1151     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1152
1153     /* XXX: Might be wrong, check with EJTAG spec. */
1154     env->CP0_Debug_tcstatus[other_tc] = T0 & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt));
1155     env->CP0_Debug = (env->CP0_Debug & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) |
1156                      (T0 & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt)));
1157     FORCE_RET();
1158 }
1159
1160 void op_mtc0_depc (void)
1161 {
1162     env->CP0_DEPC = T0;
1163     FORCE_RET();
1164 }
1165
1166 void op_mtc0_performance0 (void)
1167 {
1168     env->CP0_Performance0 = T0 & 0x000007ff;
1169     FORCE_RET();
1170 }
1171
1172 void op_mtc0_taglo (void)
1173 {
1174     env->CP0_TagLo = T0 & 0xFFFFFCF6;
1175     FORCE_RET();
1176 }
1177
1178 void op_mtc0_datalo (void)
1179 {
1180     env->CP0_DataLo = T0; /* XXX */
1181     FORCE_RET();
1182 }
1183
1184 void op_mtc0_taghi (void)
1185 {
1186     env->CP0_TagHi = T0; /* XXX */
1187     FORCE_RET();
1188 }
1189
1190 void op_mtc0_datahi (void)
1191 {
1192     env->CP0_DataHi = T0; /* XXX */
1193     FORCE_RET();
1194 }
1195
1196 void op_mtc0_errorepc (void)
1197 {
1198     env->CP0_ErrorEPC = T0;
1199     FORCE_RET();
1200 }
1201
1202 void op_mtc0_desave (void)
1203 {
1204     env->CP0_DESAVE = T0;
1205     FORCE_RET();
1206 }
1207
1208 #if defined(TARGET_MIPS64)
1209 void op_dmfc0_tcrestart (void)
1210 {
1211     T0 = env->PC[env->current_tc];
1212     FORCE_RET();
1213 }
1214
1215 void op_dmfc0_tchalt (void)
1216 {
1217     T0 = env->CP0_TCHalt[env->current_tc];
1218     FORCE_RET();
1219 }
1220
1221 void op_dmfc0_tccontext (void)
1222 {
1223     T0 = env->CP0_TCContext[env->current_tc];
1224     FORCE_RET();
1225 }
1226
1227 void op_dmfc0_tcschedule (void)
1228 {
1229     T0 = env->CP0_TCSchedule[env->current_tc];
1230     FORCE_RET();
1231 }
1232
1233 void op_dmfc0_tcschefback (void)
1234 {
1235     T0 = env->CP0_TCScheFBack[env->current_tc];
1236     FORCE_RET();
1237 }
1238
1239 void op_dmfc0_lladdr (void)
1240 {
1241     T0 = env->CP0_LLAddr >> 4;
1242     FORCE_RET();
1243 }
1244
1245 void op_dmfc0_watchlo (void)
1246 {
1247     T0 = env->CP0_WatchLo[PARAM1];
1248     FORCE_RET();
1249 }
1250 #endif /* TARGET_MIPS64 */
1251
1252 /* MIPS MT functions */
1253 void op_mftgpr(void)
1254 {
1255     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1256
1257     T0 = env->gpr[other_tc][PARAM1];
1258     FORCE_RET();
1259 }
1260
1261 void op_mftlo(void)
1262 {
1263     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1264
1265     T0 = env->LO[other_tc][PARAM1];
1266     FORCE_RET();
1267 }
1268
1269 void op_mfthi(void)
1270 {
1271     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1272
1273     T0 = env->HI[other_tc][PARAM1];
1274     FORCE_RET();
1275 }
1276
1277 void op_mftacx(void)
1278 {
1279     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1280
1281     T0 = env->ACX[other_tc][PARAM1];
1282     FORCE_RET();
1283 }
1284
1285 void op_mftdsp(void)
1286 {
1287     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1288
1289     T0 = env->DSPControl[other_tc];
1290     FORCE_RET();
1291 }
1292
1293 void op_mttgpr(void)
1294 {
1295     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1296
1297     T0 = env->gpr[other_tc][PARAM1];
1298     FORCE_RET();
1299 }
1300
1301 void op_mttlo(void)
1302 {
1303     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1304
1305     T0 = env->LO[other_tc][PARAM1];
1306     FORCE_RET();
1307 }
1308
1309 void op_mtthi(void)
1310 {
1311     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1312
1313     T0 = env->HI[other_tc][PARAM1];
1314     FORCE_RET();
1315 }
1316
1317 void op_mttacx(void)
1318 {
1319     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1320
1321     T0 = env->ACX[other_tc][PARAM1];
1322     FORCE_RET();
1323 }
1324
1325 void op_mttdsp(void)
1326 {
1327     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1328
1329     T0 = env->DSPControl[other_tc];
1330     FORCE_RET();
1331 }
1332
1333
1334 void op_dmt(void)
1335 {
1336     // TODO
1337     T0 = 0;
1338     // rt = T0
1339     FORCE_RET();
1340 }
1341
1342 void op_emt(void)
1343 {
1344     // TODO
1345     T0 = 0;
1346     // rt = T0
1347     FORCE_RET();
1348 }
1349
1350 void op_dvpe(void)
1351 {
1352     // TODO
1353     T0 = 0;
1354     // rt = T0
1355     FORCE_RET();
1356 }
1357
1358 void op_evpe(void)
1359 {
1360     // TODO
1361     T0 = 0;
1362     // rt = T0
1363     FORCE_RET();
1364 }
1365
1366 void op_fork(void)
1367 {
1368     // T0 = rt, T1 = rs
1369     T0 = 0;
1370     // TODO: store to TC register
1371     FORCE_RET();
1372 }
1373
1374 void op_yield(void)
1375 {
1376     if (T0 < 0) {
1377         /* No scheduling policy implemented. */
1378         if (T0 != -2) {
1379             if (env->CP0_VPEControl & (1 << CP0VPECo_YSI) &&
1380                 env->CP0_TCStatus[env->current_tc] & (1 << CP0TCSt_DT)) {
1381                 env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT);
1382                 env->CP0_VPEControl |= 4 << CP0VPECo_EXCPT;
1383                 CALL_FROM_TB1(do_raise_exception, EXCP_THREAD);
1384             }
1385         }
1386     } else if (T0 == 0) {
1387         if (0 /* TODO: TC underflow */) {
1388             env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT);
1389             CALL_FROM_TB1(do_raise_exception, EXCP_THREAD);
1390         } else {
1391             // TODO: Deallocate TC
1392         }
1393     } else if (T0 > 0) {
1394         /* Yield qualifier inputs not implemented. */
1395         env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT);
1396         env->CP0_VPEControl |= 2 << CP0VPECo_EXCPT;
1397         CALL_FROM_TB1(do_raise_exception, EXCP_THREAD);
1398     }
1399     T0 = env->CP0_YQMask;
1400     FORCE_RET();
1401 }
1402
1403 /* CP1 functions */
1404 #if 0
1405 # define DEBUG_FPU_STATE() CALL_FROM_TB1(dump_fpu, env)
1406 #else
1407 # define DEBUG_FPU_STATE() do { } while(0)
1408 #endif
1409
1410 void op_cfc1 (void)
1411 {
1412     CALL_FROM_TB1(do_cfc1, PARAM1);
1413     DEBUG_FPU_STATE();
1414     FORCE_RET();
1415 }
1416
1417 void op_ctc1 (void)
1418 {
1419     CALL_FROM_TB1(do_ctc1, PARAM1);
1420     DEBUG_FPU_STATE();
1421     FORCE_RET();
1422 }
1423
1424 void op_mfc1 (void)
1425 {
1426     T0 = (int32_t)WT0;
1427     DEBUG_FPU_STATE();
1428     FORCE_RET();
1429 }
1430
1431 void op_mtc1 (void)
1432 {
1433     WT0 = T0;
1434     DEBUG_FPU_STATE();
1435     FORCE_RET();
1436 }
1437
1438 void op_dmfc1 (void)
1439 {
1440     T0 = DT0;
1441     DEBUG_FPU_STATE();
1442     FORCE_RET();
1443 }
1444
1445 void op_dmtc1 (void)
1446 {
1447     DT0 = T0;
1448     DEBUG_FPU_STATE();
1449     FORCE_RET();
1450 }
1451
1452 void op_mfhc1 (void)
1453 {
1454     T0 = (int32_t)WTH0;
1455     DEBUG_FPU_STATE();
1456     FORCE_RET();
1457 }
1458
1459 void op_mthc1 (void)
1460 {
1461     WTH0 = T0;
1462     DEBUG_FPU_STATE();
1463     FORCE_RET();
1464 }
1465
1466 /* Float support.
1467    Single precition routines have a "s" suffix, double precision a
1468    "d" suffix, 32bit integer "w", 64bit integer "l", paired singe "ps",
1469    paired single lowwer "pl", paired single upper "pu".  */
1470
1471 #define FLOAT_OP(name, p) void OPPROTO op_float_##name##_##p(void)
1472
1473 FLOAT_OP(cvtd, s)
1474 {
1475     CALL_FROM_TB0(do_float_cvtd_s);
1476     DEBUG_FPU_STATE();
1477     FORCE_RET();
1478 }
1479 FLOAT_OP(cvtd, w)
1480 {
1481     CALL_FROM_TB0(do_float_cvtd_w);
1482     DEBUG_FPU_STATE();
1483     FORCE_RET();
1484 }
1485 FLOAT_OP(cvtd, l)
1486 {
1487     CALL_FROM_TB0(do_float_cvtd_l);
1488     DEBUG_FPU_STATE();
1489     FORCE_RET();
1490 }
1491 FLOAT_OP(cvtl, d)
1492 {
1493     CALL_FROM_TB0(do_float_cvtl_d);
1494     DEBUG_FPU_STATE();
1495     FORCE_RET();
1496 }
1497 FLOAT_OP(cvtl, s)
1498 {
1499     CALL_FROM_TB0(do_float_cvtl_s);
1500     DEBUG_FPU_STATE();
1501     FORCE_RET();
1502 }
1503 FLOAT_OP(cvtps, s)
1504 {
1505     WT2 = WT0;
1506     WTH2 = WT1;
1507     DEBUG_FPU_STATE();
1508     FORCE_RET();
1509 }
1510 FLOAT_OP(cvtps, pw)
1511 {
1512     CALL_FROM_TB0(do_float_cvtps_pw);
1513     DEBUG_FPU_STATE();
1514     FORCE_RET();
1515 }
1516 FLOAT_OP(cvtpw, ps)
1517 {
1518     CALL_FROM_TB0(do_float_cvtpw_ps);
1519     DEBUG_FPU_STATE();
1520     FORCE_RET();
1521 }
1522 FLOAT_OP(cvts, d)
1523 {
1524     CALL_FROM_TB0(do_float_cvts_d);
1525     DEBUG_FPU_STATE();
1526     FORCE_RET();
1527 }
1528 FLOAT_OP(cvts, w)
1529 {
1530     CALL_FROM_TB0(do_float_cvts_w);
1531     DEBUG_FPU_STATE();
1532     FORCE_RET();
1533 }
1534 FLOAT_OP(cvts, l)
1535 {
1536     CALL_FROM_TB0(do_float_cvts_l);
1537     DEBUG_FPU_STATE();
1538     FORCE_RET();
1539 }
1540 FLOAT_OP(cvts, pl)
1541 {
1542     CALL_FROM_TB0(do_float_cvts_pl);
1543     DEBUG_FPU_STATE();
1544     FORCE_RET();
1545 }
1546 FLOAT_OP(cvts, pu)
1547 {
1548     CALL_FROM_TB0(do_float_cvts_pu);
1549     DEBUG_FPU_STATE();
1550     FORCE_RET();
1551 }
1552 FLOAT_OP(cvtw, s)
1553 {
1554     CALL_FROM_TB0(do_float_cvtw_s);
1555     DEBUG_FPU_STATE();
1556     FORCE_RET();
1557 }
1558 FLOAT_OP(cvtw, d)
1559 {
1560     CALL_FROM_TB0(do_float_cvtw_d);
1561     DEBUG_FPU_STATE();
1562     FORCE_RET();
1563 }
1564
1565 FLOAT_OP(pll, ps)
1566 {
1567     DT2 = ((uint64_t)WT0 << 32) | WT1;
1568     DEBUG_FPU_STATE();
1569     FORCE_RET();
1570 }
1571 FLOAT_OP(plu, ps)
1572 {
1573     DT2 = ((uint64_t)WT0 << 32) | WTH1;
1574     DEBUG_FPU_STATE();
1575     FORCE_RET();
1576 }
1577 FLOAT_OP(pul, ps)
1578 {
1579     DT2 = ((uint64_t)WTH0 << 32) | WT1;
1580     DEBUG_FPU_STATE();
1581     FORCE_RET();
1582 }
1583 FLOAT_OP(puu, ps)
1584 {
1585     DT2 = ((uint64_t)WTH0 << 32) | WTH1;
1586     DEBUG_FPU_STATE();
1587     FORCE_RET();
1588 }
1589
1590 #define FLOAT_ROUNDOP(op, ttype, stype)                    \
1591 FLOAT_OP(op ## ttype, stype)                               \
1592 {                                                          \
1593     CALL_FROM_TB0(do_float_ ## op ## ttype ## _ ## stype); \
1594     DEBUG_FPU_STATE();                                     \
1595     FORCE_RET();                                           \
1596 }
1597
1598 FLOAT_ROUNDOP(round, l, d)
1599 FLOAT_ROUNDOP(round, l, s)
1600 FLOAT_ROUNDOP(round, w, d)
1601 FLOAT_ROUNDOP(round, w, s)
1602
1603 FLOAT_ROUNDOP(trunc, l, d)
1604 FLOAT_ROUNDOP(trunc, l, s)
1605 FLOAT_ROUNDOP(trunc, w, d)
1606 FLOAT_ROUNDOP(trunc, w, s)
1607
1608 FLOAT_ROUNDOP(ceil, l, d)
1609 FLOAT_ROUNDOP(ceil, l, s)
1610 FLOAT_ROUNDOP(ceil, w, d)
1611 FLOAT_ROUNDOP(ceil, w, s)
1612
1613 FLOAT_ROUNDOP(floor, l, d)
1614 FLOAT_ROUNDOP(floor, l, s)
1615 FLOAT_ROUNDOP(floor, w, d)
1616 FLOAT_ROUNDOP(floor, w, s)
1617 #undef FLOAR_ROUNDOP
1618
1619 FLOAT_OP(movf, d)
1620 {
1621     if (!(env->fpu->fcr31 & PARAM1))
1622         DT2 = DT0;
1623     DEBUG_FPU_STATE();
1624     FORCE_RET();
1625 }
1626 FLOAT_OP(movf, s)
1627 {
1628     if (!(env->fpu->fcr31 & PARAM1))
1629         WT2 = WT0;
1630     DEBUG_FPU_STATE();
1631     FORCE_RET();
1632 }
1633 FLOAT_OP(movf, ps)
1634 {
1635     unsigned int mask = GET_FP_COND (env->fpu) >> PARAM1;
1636     if (!(mask & 1))
1637         WT2 = WT0;
1638     if (!(mask & 2))
1639         WTH2 = WTH0;
1640     DEBUG_FPU_STATE();
1641     FORCE_RET();
1642 }
1643 FLOAT_OP(movt, d)
1644 {
1645     if (env->fpu->fcr31 & PARAM1)
1646         DT2 = DT0;
1647     DEBUG_FPU_STATE();
1648     FORCE_RET();
1649 }
1650 FLOAT_OP(movt, s)
1651 {
1652     if (env->fpu->fcr31 & PARAM1)
1653         WT2 = WT0;
1654     DEBUG_FPU_STATE();
1655     FORCE_RET();
1656 }
1657 FLOAT_OP(movt, ps)
1658 {
1659     unsigned int mask = GET_FP_COND (env->fpu) >> PARAM1;
1660     if (mask & 1)
1661         WT2 = WT0;
1662     if (mask & 2)
1663         WTH2 = WTH0;
1664     DEBUG_FPU_STATE();
1665     FORCE_RET();
1666 }
1667 FLOAT_OP(movz, d)
1668 {
1669     if (!T0)
1670         DT2 = DT0;
1671     DEBUG_FPU_STATE();
1672     FORCE_RET();
1673 }
1674 FLOAT_OP(movz, s)
1675 {
1676     if (!T0)
1677         WT2 = WT0;
1678     DEBUG_FPU_STATE();
1679     FORCE_RET();
1680 }
1681 FLOAT_OP(movz, ps)
1682 {
1683     if (!T0) {
1684         WT2 = WT0;
1685         WTH2 = WTH0;
1686     }
1687     DEBUG_FPU_STATE();
1688     FORCE_RET();
1689 }
1690 FLOAT_OP(movn, d)
1691 {
1692     if (T0)
1693         DT2 = DT0;
1694     DEBUG_FPU_STATE();
1695     FORCE_RET();
1696 }
1697 FLOAT_OP(movn, s)
1698 {
1699     if (T0)
1700         WT2 = WT0;
1701     DEBUG_FPU_STATE();
1702     FORCE_RET();
1703 }
1704 FLOAT_OP(movn, ps)
1705 {
1706     if (T0) {
1707         WT2 = WT0;
1708         WTH2 = WTH0;
1709     }
1710     DEBUG_FPU_STATE();
1711     FORCE_RET();
1712 }
1713
1714 /* operations calling helpers, for s, d and ps */
1715 #define FLOAT_HOP(name)   \
1716 FLOAT_OP(name, d)         \
1717 {                         \
1718     CALL_FROM_TB0(do_float_ ## name ## _d);  \
1719     DEBUG_FPU_STATE();    \
1720     FORCE_RET();          \
1721 }                         \
1722 FLOAT_OP(name, s)         \
1723 {                         \
1724     CALL_FROM_TB0(do_float_ ## name ## _s);  \
1725     DEBUG_FPU_STATE();    \
1726     FORCE_RET();          \
1727 }                         \
1728 FLOAT_OP(name, ps)        \
1729 {                         \
1730     CALL_FROM_TB0(do_float_ ## name ## _ps); \
1731     DEBUG_FPU_STATE();    \
1732     FORCE_RET();          \
1733 }
1734 FLOAT_HOP(add)
1735 FLOAT_HOP(sub)
1736 FLOAT_HOP(mul)
1737 FLOAT_HOP(div)
1738 FLOAT_HOP(recip2)
1739 FLOAT_HOP(rsqrt2)
1740 FLOAT_HOP(rsqrt1)
1741 FLOAT_HOP(recip1)
1742 #undef FLOAT_HOP
1743
1744 /* operations calling helpers, for s and d */
1745 #define FLOAT_HOP(name)   \
1746 FLOAT_OP(name, d)         \
1747 {                         \
1748     CALL_FROM_TB0(do_float_ ## name ## _d);  \
1749     DEBUG_FPU_STATE();    \
1750     FORCE_RET();          \
1751 }                         \
1752 FLOAT_OP(name, s)         \
1753 {                         \
1754     CALL_FROM_TB0(do_float_ ## name ## _s);  \
1755     DEBUG_FPU_STATE();    \
1756     FORCE_RET();          \
1757 }
1758 FLOAT_HOP(rsqrt)
1759 FLOAT_HOP(recip)
1760 #undef FLOAT_HOP
1761
1762 /* operations calling helpers, for ps */
1763 #define FLOAT_HOP(name)   \
1764 FLOAT_OP(name, ps)        \
1765 {                         \
1766     CALL_FROM_TB0(do_float_ ## name ## _ps); \
1767     DEBUG_FPU_STATE();    \
1768     FORCE_RET();          \
1769 }
1770 FLOAT_HOP(addr)
1771 FLOAT_HOP(mulr)
1772 #undef FLOAT_HOP
1773
1774 /* ternary operations */
1775 #define FLOAT_TERNOP(name1, name2) \
1776 FLOAT_OP(name1 ## name2, d)        \
1777 {                                  \
1778     FDT0 = float64_ ## name1 (FDT0, FDT1, &env->fpu->fp_status);    \
1779     FDT2 = float64_ ## name2 (FDT0, FDT2, &env->fpu->fp_status);    \
1780     DEBUG_FPU_STATE();             \
1781     FORCE_RET();                   \
1782 }                                  \
1783 FLOAT_OP(name1 ## name2, s)        \
1784 {                                  \
1785     FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status);    \
1786     FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status);    \
1787     DEBUG_FPU_STATE();             \
1788     FORCE_RET();                   \
1789 }                                  \
1790 FLOAT_OP(name1 ## name2, ps)       \
1791 {                                  \
1792     FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status);    \
1793     FSTH0 = float32_ ## name1 (FSTH0, FSTH1, &env->fpu->fp_status); \
1794     FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status);    \
1795     FSTH2 = float32_ ## name2 (FSTH0, FSTH2, &env->fpu->fp_status); \
1796     DEBUG_FPU_STATE();             \
1797     FORCE_RET();                   \
1798 }
1799 FLOAT_TERNOP(mul, add)
1800 FLOAT_TERNOP(mul, sub)
1801 #undef FLOAT_TERNOP
1802
1803 /* negated ternary operations */
1804 #define FLOAT_NTERNOP(name1, name2) \
1805 FLOAT_OP(n ## name1 ## name2, d)    \
1806 {                                   \
1807     FDT0 = float64_ ## name1 (FDT0, FDT1, &env->fpu->fp_status);    \
1808     FDT2 = float64_ ## name2 (FDT0, FDT2, &env->fpu->fp_status);    \
1809     FDT2 = float64_chs(FDT2);       \
1810     DEBUG_FPU_STATE();              \
1811     FORCE_RET();                    \
1812 }                                   \
1813 FLOAT_OP(n ## name1 ## name2, s)    \
1814 {                                   \
1815     FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status);    \
1816     FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status);    \
1817     FST2 = float32_chs(FST2);       \
1818     DEBUG_FPU_STATE();              \
1819     FORCE_RET();                    \
1820 }                                   \
1821 FLOAT_OP(n ## name1 ## name2, ps)   \
1822 {                                   \
1823     FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status);    \
1824     FSTH0 = float32_ ## name1 (FSTH0, FSTH1, &env->fpu->fp_status); \
1825     FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status);    \
1826     FSTH2 = float32_ ## name2 (FSTH0, FSTH2, &env->fpu->fp_status); \
1827     FST2 = float32_chs(FST2);       \
1828     FSTH2 = float32_chs(FSTH2);     \
1829     DEBUG_FPU_STATE();              \
1830     FORCE_RET();                    \
1831 }
1832 FLOAT_NTERNOP(mul, add)
1833 FLOAT_NTERNOP(mul, sub)
1834 #undef FLOAT_NTERNOP
1835
1836 /* unary operations, modifying fp status  */
1837 #define FLOAT_UNOP(name)  \
1838 FLOAT_OP(name, d)         \
1839 {                         \
1840     FDT2 = float64_ ## name(FDT0, &env->fpu->fp_status); \
1841     DEBUG_FPU_STATE();    \
1842     FORCE_RET();          \
1843 }                         \
1844 FLOAT_OP(name, s)         \
1845 {                         \
1846     FST2 = float32_ ## name(FST0, &env->fpu->fp_status); \
1847     DEBUG_FPU_STATE();    \
1848     FORCE_RET();          \
1849 }
1850 FLOAT_UNOP(sqrt)
1851 #undef FLOAT_UNOP
1852
1853 /* unary operations, not modifying fp status  */
1854 #define FLOAT_UNOP(name)  \
1855 FLOAT_OP(name, d)         \
1856 {                         \
1857     FDT2 = float64_ ## name(FDT0);   \
1858     DEBUG_FPU_STATE();    \
1859     FORCE_RET();          \
1860 }                         \
1861 FLOAT_OP(name, s)         \
1862 {                         \
1863     FST2 = float32_ ## name(FST0);   \
1864     DEBUG_FPU_STATE();    \
1865     FORCE_RET();          \
1866 }                         \
1867 FLOAT_OP(name, ps)        \
1868 {                         \
1869     FST2 = float32_ ## name(FST0);   \
1870     FSTH2 = float32_ ## name(FSTH0); \
1871     DEBUG_FPU_STATE();    \
1872     FORCE_RET();          \
1873 }
1874 FLOAT_UNOP(abs)
1875 FLOAT_UNOP(chs)
1876 #undef FLOAT_UNOP
1877
1878 FLOAT_OP(mov, d)
1879 {
1880     FDT2 = FDT0;
1881     DEBUG_FPU_STATE();
1882     FORCE_RET();
1883 }
1884 FLOAT_OP(mov, s)
1885 {
1886     FST2 = FST0;
1887     DEBUG_FPU_STATE();
1888     FORCE_RET();
1889 }
1890 FLOAT_OP(mov, ps)
1891 {
1892     FST2 = FST0;
1893     FSTH2 = FSTH0;
1894     DEBUG_FPU_STATE();
1895     FORCE_RET();
1896 }
1897 FLOAT_OP(alnv, ps)
1898 {
1899     switch (T0 & 0x7) {
1900     case 0:
1901         FST2 = FST0;
1902         FSTH2 = FSTH0;
1903         break;
1904     case 4:
1905 #ifdef TARGET_WORDS_BIGENDIAN
1906         FSTH2 = FST0;
1907         FST2 = FSTH1;
1908 #else
1909         FSTH2 = FST1;
1910         FST2 = FSTH0;
1911 #endif
1912         break;
1913     default: /* unpredictable */
1914         break;
1915     }
1916     DEBUG_FPU_STATE();
1917     FORCE_RET();
1918 }
1919
1920 #ifdef CONFIG_SOFTFLOAT
1921 #define clear_invalid() do {                                \
1922     int flags = get_float_exception_flags(&env->fpu->fp_status); \
1923     flags &= ~float_flag_invalid;                           \
1924     set_float_exception_flags(flags, &env->fpu->fp_status); \
1925 } while(0)
1926 #else
1927 #define clear_invalid() do { } while(0)
1928 #endif
1929
1930 extern void dump_fpu_s(CPUState *env);
1931
1932 #define CMP_OP(fmt, op)                                \
1933 void OPPROTO op_cmp ## _ ## fmt ## _ ## op(void)       \
1934 {                                                      \
1935     CALL_FROM_TB1(do_cmp ## _ ## fmt ## _ ## op, PARAM1); \
1936     DEBUG_FPU_STATE();                                 \
1937     FORCE_RET();                                       \
1938 }                                                      \
1939 void OPPROTO op_cmpabs ## _ ## fmt ## _ ## op(void)    \
1940 {                                                      \
1941     CALL_FROM_TB1(do_cmpabs ## _ ## fmt ## _ ## op, PARAM1); \
1942     DEBUG_FPU_STATE();                                 \
1943     FORCE_RET();                                       \
1944 }
1945 #define CMP_OPS(op)   \
1946 CMP_OP(d, op)         \
1947 CMP_OP(s, op)         \
1948 CMP_OP(ps, op)
1949
1950 CMP_OPS(f)
1951 CMP_OPS(un)
1952 CMP_OPS(eq)
1953 CMP_OPS(ueq)
1954 CMP_OPS(olt)
1955 CMP_OPS(ult)
1956 CMP_OPS(ole)
1957 CMP_OPS(ule)
1958 CMP_OPS(sf)
1959 CMP_OPS(ngle)
1960 CMP_OPS(seq)
1961 CMP_OPS(ngl)
1962 CMP_OPS(lt)
1963 CMP_OPS(nge)
1964 CMP_OPS(le)
1965 CMP_OPS(ngt)
1966 #undef CMP_OPS
1967 #undef CMP_OP
1968
1969 void op_bc1f (void)
1970 {
1971     T0 = !!(~GET_FP_COND(env->fpu) & (0x1 << PARAM1));
1972     DEBUG_FPU_STATE();
1973     FORCE_RET();
1974 }
1975 void op_bc1any2f (void)
1976 {
1977     T0 = !!(~GET_FP_COND(env->fpu) & (0x3 << PARAM1));
1978     DEBUG_FPU_STATE();
1979     FORCE_RET();
1980 }
1981 void op_bc1any4f (void)
1982 {
1983     T0 = !!(~GET_FP_COND(env->fpu) & (0xf << PARAM1));
1984     DEBUG_FPU_STATE();
1985     FORCE_RET();
1986 }
1987
1988 void op_bc1t (void)
1989 {
1990     T0 = !!(GET_FP_COND(env->fpu) & (0x1 << PARAM1));
1991     DEBUG_FPU_STATE();
1992     FORCE_RET();
1993 }
1994 void op_bc1any2t (void)
1995 {
1996     T0 = !!(GET_FP_COND(env->fpu) & (0x3 << PARAM1));
1997     DEBUG_FPU_STATE();
1998     FORCE_RET();
1999 }
2000 void op_bc1any4t (void)
2001 {
2002     T0 = !!(GET_FP_COND(env->fpu) & (0xf << PARAM1));
2003     DEBUG_FPU_STATE();
2004     FORCE_RET();
2005 }
2006
2007 void op_tlbwi (void)
2008 {
2009     CALL_FROM_TB0(env->tlb->do_tlbwi);
2010     FORCE_RET();
2011 }
2012
2013 void op_tlbwr (void)
2014 {
2015     CALL_FROM_TB0(env->tlb->do_tlbwr);
2016     FORCE_RET();
2017 }
2018
2019 void op_tlbp (void)
2020 {
2021     CALL_FROM_TB0(env->tlb->do_tlbp);
2022     FORCE_RET();
2023 }
2024
2025 void op_tlbr (void)
2026 {
2027     CALL_FROM_TB0(env->tlb->do_tlbr);
2028     FORCE_RET();
2029 }
2030
2031 /* Specials */
2032 #if defined (CONFIG_USER_ONLY)
2033 void op_tls_value (void)
2034 {
2035     T0 = env->tls_value;
2036 }
2037 #endif
2038
2039 void op_pmon (void)
2040 {
2041     CALL_FROM_TB1(do_pmon, PARAM1);
2042     FORCE_RET();
2043 }
2044
2045 void op_di (void)
2046 {
2047     T0 = env->CP0_Status;
2048     env->CP0_Status = T0 & ~(1 << CP0St_IE);
2049     CALL_FROM_TB1(cpu_mips_update_irq, env);
2050     FORCE_RET();
2051 }
2052
2053 void op_ei (void)
2054 {
2055     T0 = env->CP0_Status;
2056     env->CP0_Status = T0 | (1 << CP0St_IE);
2057     CALL_FROM_TB1(cpu_mips_update_irq, env);
2058     FORCE_RET();
2059 }
2060
2061 void op_trap (void)
2062 {
2063     if (T0) {
2064         CALL_FROM_TB1(do_raise_exception, EXCP_TRAP);
2065     }
2066     FORCE_RET();
2067 }
2068
2069 void op_debug (void)
2070 {
2071     CALL_FROM_TB1(do_raise_exception, EXCP_DEBUG);
2072     FORCE_RET();
2073 }
2074
2075 void debug_pre_eret (void);
2076 void debug_post_eret (void);
2077 void op_eret (void)
2078 {
2079     if (loglevel & CPU_LOG_EXEC)
2080         CALL_FROM_TB0(debug_pre_eret);
2081     if (env->CP0_Status & (1 << CP0St_ERL)) {
2082         env->PC[env->current_tc] = env->CP0_ErrorEPC;
2083         env->CP0_Status &= ~(1 << CP0St_ERL);
2084     } else {
2085         env->PC[env->current_tc] = env->CP0_EPC;
2086         env->CP0_Status &= ~(1 << CP0St_EXL);
2087     }
2088     CALL_FROM_TB1(compute_hflags, env);
2089     if (loglevel & CPU_LOG_EXEC)
2090         CALL_FROM_TB0(debug_post_eret);
2091     env->CP0_LLAddr = 1;
2092     FORCE_RET();
2093 }
2094
2095 void op_deret (void)
2096 {
2097     if (loglevel & CPU_LOG_EXEC)
2098         CALL_FROM_TB0(debug_pre_eret);
2099     env->PC[env->current_tc] = env->CP0_DEPC;
2100     env->hflags &= MIPS_HFLAG_DM;
2101     CALL_FROM_TB1(compute_hflags, env);
2102     if (loglevel & CPU_LOG_EXEC)
2103         CALL_FROM_TB0(debug_post_eret);
2104     env->CP0_LLAddr = 1;
2105     FORCE_RET();
2106 }
2107
2108 void op_rdhwr_cpunum(void)
2109 {
2110     if ((env->hflags & MIPS_HFLAG_CP0) ||
2111         (env->CP0_HWREna & (1 << 0)))
2112         T0 = env->CP0_EBase & 0x3ff;
2113     else
2114         CALL_FROM_TB1(do_raise_exception, EXCP_RI);
2115     FORCE_RET();
2116 }
2117
2118 void op_rdhwr_synci_step(void)
2119 {
2120     if ((env->hflags & MIPS_HFLAG_CP0) ||
2121         (env->CP0_HWREna & (1 << 1)))
2122         T0 = env->SYNCI_Step;
2123     else
2124         CALL_FROM_TB1(do_raise_exception, EXCP_RI);
2125     FORCE_RET();
2126 }
2127
2128 void op_rdhwr_cc(void)
2129 {
2130     if ((env->hflags & MIPS_HFLAG_CP0) ||
2131         (env->CP0_HWREna & (1 << 2)))
2132         T0 = env->CP0_Count;
2133     else
2134         CALL_FROM_TB1(do_raise_exception, EXCP_RI);
2135     FORCE_RET();
2136 }
2137
2138 void op_rdhwr_ccres(void)
2139 {
2140     if ((env->hflags & MIPS_HFLAG_CP0) ||
2141         (env->CP0_HWREna & (1 << 3)))
2142         T0 = env->CCRes;
2143     else
2144         CALL_FROM_TB1(do_raise_exception, EXCP_RI);
2145     FORCE_RET();
2146 }
2147
2148 void op_save_state (void)
2149 {
2150     env->hflags = PARAM1;
2151     FORCE_RET();
2152 }
2153
2154 void op_wait (void)
2155 {
2156     env->halted = 1;
2157     CALL_FROM_TB1(do_raise_exception, EXCP_HLT);
2158     FORCE_RET();
2159 }
2160
2161 /* Bitfield operations. */
2162 void op_ext(void)
2163 {
2164     unsigned int pos = PARAM1;
2165     unsigned int size = PARAM2;
2166
2167     T0 = (int32_t)((T1 >> pos) & ((size < 32) ? ((1 << size) - 1) : ~0));
2168     FORCE_RET();
2169 }
2170
2171 void op_ins(void)
2172 {
2173     unsigned int pos = PARAM1;
2174     unsigned int size = PARAM2;
2175     target_ulong mask = ((size < 32) ? ((1 << size) - 1) : ~0) << pos;
2176
2177     T0 = (int32_t)((T0 & ~mask) | ((T1 << pos) & mask));
2178     FORCE_RET();
2179 }
2180
2181 void op_wsbh(void)
2182 {
2183     T0 = (int32_t)(((T1 << 8) & ~0x00FF00FF) | ((T1 >> 8) & 0x00FF00FF));
2184     FORCE_RET();
2185 }
2186
2187 #if defined(TARGET_MIPS64)
2188 void op_dext(void)
2189 {
2190     unsigned int pos = PARAM1;
2191     unsigned int size = PARAM2;
2192
2193     T0 = (T1 >> pos) & ((size < 64) ? ((1ULL << size) - 1) : ~0ULL);
2194     FORCE_RET();
2195 }
2196
2197 void op_dins(void)
2198 {
2199     unsigned int pos = PARAM1;
2200     unsigned int size = PARAM2;
2201     target_ulong mask = ((size < 64) ? ((1ULL << size) - 1) : ~0ULL) << pos;
2202
2203     T0 = (T0 & ~mask) | ((T1 << pos) & mask);
2204     FORCE_RET();
2205 }
2206
2207 void op_dsbh(void)
2208 {
2209     T0 = ((T1 << 8) & ~0x00FF00FF00FF00FFULL) | ((T1 >> 8) & 0x00FF00FF00FF00FFULL);
2210     FORCE_RET();
2211 }
2212
2213 void op_dshd(void)
2214 {
2215     T1 = ((T1 << 16) & ~0x0000FFFF0000FFFFULL) | ((T1 >> 16) & 0x0000FFFF0000FFFFULL);
2216     T0 = (T1 << 32) | (T1 >> 32);
2217     FORCE_RET();
2218 }
2219 #endif
This page took 0.136573 seconds and 4 git commands to generate.