21b8287de6bff0e6107472f12a6ed95339048d3e
[qemu] / target-sh4 / op.c
1 /*
2  *  SH4 emulation
3  *
4  *  Copyright (c) 2005 Samuel Tardieu
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20 #include "exec.h"
21
22 static inline void set_t(void)
23 {
24     env->sr |= SR_T;
25 }
26
27 static inline void clr_t(void)
28 {
29     env->sr &= ~SR_T;
30 }
31
32 static inline void cond_t(int cond)
33 {
34     if (cond)
35         set_t();
36     else
37         clr_t();
38 }
39
40 void OPPROTO op_movl_imm_T0(void)
41 {
42     T0 = (uint32_t) PARAM1;
43     RETURN();
44 }
45
46 void OPPROTO op_movl_imm_T1(void)
47 {
48     T1 = (uint32_t) PARAM1;
49     RETURN();
50 }
51
52 void OPPROTO op_cmp_eq_imm_T0(void)
53 {
54     cond_t((int32_t) T0 == (int32_t) PARAM1);
55     RETURN();
56 }
57
58 void OPPROTO op_not_T0(void)
59 {
60     T0 = ~T0;
61     RETURN();
62 }
63
64 void OPPROTO op_bf_s(void)
65 {
66     env->delayed_pc = PARAM1;
67     if (!(env->sr & SR_T)) {
68         env->flags |= DELAY_SLOT_TRUE;
69     }
70     RETURN();
71 }
72
73 void OPPROTO op_bt_s(void)
74 {
75     env->delayed_pc = PARAM1;
76     if (env->sr & SR_T) {
77         env->flags |= DELAY_SLOT_TRUE;
78     }
79     RETURN();
80 }
81
82 void OPPROTO op_store_flags(void)
83 {
84     env->flags &= DELAY_SLOT_TRUE;
85     env->flags |= PARAM1;
86     RETURN();
87 }
88
89 void OPPROTO op_bra(void)
90 {
91     env->delayed_pc = PARAM1;
92     RETURN();
93 }
94
95 void OPPROTO op_braf_T0(void)
96 {
97     env->delayed_pc = PARAM1 + T0;
98     RETURN();
99 }
100
101 void OPPROTO op_bsr(void)
102 {
103     env->pr = PARAM1;
104     env->delayed_pc = PARAM2;
105     RETURN();
106 }
107
108 void OPPROTO op_bsrf_T0(void)
109 {
110     env->pr = PARAM1;
111     env->delayed_pc = PARAM1 + T0;
112     RETURN();
113 }
114
115 void OPPROTO op_jsr_T0(void)
116 {
117     env->pr = PARAM1;
118     env->delayed_pc = T0;
119     RETURN();
120 }
121
122 void OPPROTO op_rts(void)
123 {
124     env->delayed_pc = env->pr;
125     RETURN();
126 }
127
128 void OPPROTO op_addl_imm_T0(void)
129 {
130     T0 += PARAM1;
131     RETURN();
132 }
133
134 void OPPROTO op_addl_imm_T1(void)
135 {
136     T1 += PARAM1;
137     RETURN();
138 }
139
140 void OPPROTO op_clrmac(void)
141 {
142     env->mach = env->macl = 0;
143     RETURN();
144 }
145
146 void OPPROTO op_clrs(void)
147 {
148     env->sr &= ~SR_S;
149     RETURN();
150 }
151
152 void OPPROTO op_clrt(void)
153 {
154     env->sr &= ~SR_T;
155     RETURN();
156 }
157
158 void OPPROTO op_ldtlb(void)
159 {
160     helper_ldtlb();
161     RETURN();
162 }
163
164 void OPPROTO op_sets(void)
165 {
166     env->sr |= SR_S;
167     RETURN();
168 }
169
170 void OPPROTO op_sett(void)
171 {
172     env->sr |= SR_T;
173     RETURN();
174 }
175
176 void OPPROTO op_frchg(void)
177 {
178     env->fpscr ^= FPSCR_FR;
179     RETURN();
180 }
181
182 void OPPROTO op_fschg(void)
183 {
184     env->fpscr ^= FPSCR_SZ;
185     RETURN();
186 }
187
188 void OPPROTO op_rte(void)
189 {
190     env->sr = env->ssr;
191     env->delayed_pc = env->spc;
192     RETURN();
193 }
194
195 void OPPROTO op_swapb_T0(void)
196 {
197     T0 = (T0 & 0xffff0000) | ((T0 & 0xff) << 8) | ((T0 >> 8) & 0xff);
198     RETURN();
199 }
200
201 void OPPROTO op_swapw_T0(void)
202 {
203     T0 = ((T0 & 0xffff) << 16) | ((T0 >> 16) & 0xffff);
204     RETURN();
205 }
206
207 void OPPROTO op_xtrct_T0_T1(void)
208 {
209     T1 = ((T0 & 0xffff) << 16) | ((T1 >> 16) & 0xffff);
210     RETURN();
211 }
212
213 void OPPROTO op_add_T0_T1(void)
214 {
215     T1 += T0;
216     RETURN();
217 }
218
219 void OPPROTO op_addc_T0_T1(void)
220 {
221     helper_addc_T0_T1();
222     RETURN();
223 }
224
225 void OPPROTO op_addv_T0_T1(void)
226 {
227     helper_addv_T0_T1();
228     RETURN();
229 }
230
231 void OPPROTO op_cmp_eq_T0_T1(void)
232 {
233     cond_t(T1 == T0);
234     RETURN();
235 }
236
237 void OPPROTO op_cmp_ge_T0_T1(void)
238 {
239     cond_t((int32_t) T1 >= (int32_t) T0);
240     RETURN();
241 }
242
243 void OPPROTO op_cmp_gt_T0_T1(void)
244 {
245     cond_t((int32_t) T1 > (int32_t) T0);
246     RETURN();
247 }
248
249 void OPPROTO op_cmp_hi_T0_T1(void)
250 {
251     cond_t((uint32_t) T1 > (uint32_t) T0);
252     RETURN();
253 }
254
255 void OPPROTO op_cmp_hs_T0_T1(void)
256 {
257     cond_t((uint32_t) T1 >= (uint32_t) T0);
258     RETURN();
259 }
260
261 void OPPROTO op_cmp_str_T0_T1(void)
262 {
263     cond_t((T0 & 0x000000ff) == (T1 & 0x000000ff) ||
264            (T0 & 0x0000ff00) == (T1 & 0x0000ff00) ||
265            (T0 & 0x00ff0000) == (T1 & 0x00ff0000) ||
266            (T0 & 0xff000000) == (T1 & 0xff000000));
267     RETURN();
268 }
269
270 void OPPROTO op_tst_T0_T1(void)
271 {
272     cond_t((T1 & T0) == 0);
273     RETURN();
274 }
275
276 void OPPROTO op_div0s_T0_T1(void)
277 {
278     if (T1 & 0x80000000)
279         env->sr |= SR_Q;
280     else
281         env->sr &= ~SR_Q;
282     if (T0 & 0x80000000)
283         env->sr |= SR_M;
284     else
285         env->sr &= ~SR_M;
286     cond_t((T1 ^ T0) & 0x80000000);
287     RETURN();
288 }
289
290 void OPPROTO op_div0u(void)
291 {
292     env->sr &= ~(SR_M | SR_Q | SR_T);
293     RETURN();
294 }
295
296 void OPPROTO op_div1_T0_T1(void)
297 {
298     helper_div1_T0_T1();
299     RETURN();
300 }
301
302 void OPPROTO op_dmulsl_T0_T1(void)
303 {
304     helper_dmulsl_T0_T1();
305     RETURN();
306 }
307
308 void OPPROTO op_dmulul_T0_T1(void)
309 {
310     helper_dmulul_T0_T1();
311     RETURN();
312 }
313
314 void OPPROTO op_macl_T0_T1(void)
315 {
316     helper_macl_T0_T1();
317     RETURN();
318 }
319
320 void OPPROTO op_macw_T0_T1(void)
321 {
322     helper_macw_T0_T1();
323     RETURN();
324 }
325
326 void OPPROTO op_mull_T0_T1(void)
327 {
328     env->macl = (T0 * T1) & 0xffffffff;
329     RETURN();
330 }
331
332 void OPPROTO op_mulsw_T0_T1(void)
333 {
334     env->macl = (int32_t)(int16_t) T0 *(int32_t)(int16_t) T1;
335     RETURN();
336 }
337
338 void OPPROTO op_muluw_T0_T1(void)
339 {
340     env->macl = (uint32_t)(uint16_t) T0 *(uint32_t)(uint16_t) T1;
341     RETURN();
342 }
343
344 void OPPROTO op_neg_T0(void)
345 {
346     T0 = -T0;
347     RETURN();
348 }
349
350 void OPPROTO op_negc_T0(void)
351 {
352     helper_negc_T0();
353     RETURN();
354 }
355
356 void OPPROTO op_shad_T0_T1(void)
357 {
358     if ((T0 & 0x80000000) == 0)
359         T1 <<= (T0 & 0x1f);
360     else if ((T0 & 0x1f) == 0)
361         T1 = (T1 & 0x80000000)? 0xffffffff : 0;
362     else
363         T1 = ((int32_t) T1) >> ((~T0 & 0x1f) + 1);
364     RETURN();
365 }
366
367 void OPPROTO op_shld_T0_T1(void)
368 {
369     if ((T0 & 0x80000000) == 0)
370         T1 <<= (T0 & 0x1f);
371     else if ((T0 & 0x1f) == 0)
372         T1 = 0;
373     else
374         T1 = ((uint32_t) T1) >> ((~T0 & 0x1f) + 1);
375     RETURN();
376 }
377
378 void OPPROTO op_subc_T0_T1(void)
379 {
380     helper_subc_T0_T1();
381     RETURN();
382 }
383
384 void OPPROTO op_subv_T0_T1(void)
385 {
386     helper_subv_T0_T1();
387     RETURN();
388 }
389
390 void OPPROTO op_trapa(void)
391 {
392     env->tra = PARAM1 << 2;
393     env->exception_index = 0x160;
394     do_raise_exception();
395     RETURN();
396 }
397
398 void OPPROTO op_cmp_pl_T0(void)
399 {
400     cond_t((int32_t) T0 > 0);
401     RETURN();
402 }
403
404 void OPPROTO op_cmp_pz_T0(void)
405 {
406     cond_t((int32_t) T0 >= 0);
407     RETURN();
408 }
409
410 void OPPROTO op_jmp_T0(void)
411 {
412     env->delayed_pc = T0;
413     RETURN();
414 }
415
416 void OPPROTO op_movl_rN_rN(void)
417 {
418     env->gregs[PARAM2] = env->gregs[PARAM1];
419     RETURN();
420 }
421
422 void OPPROTO op_ldcl_rMplus_rN_bank(void)
423 {
424     env->gregs[PARAM2] = env->gregs[PARAM1];
425     env->gregs[PARAM1] += 4;
426     RETURN();
427 }
428
429 void OPPROTO op_ldc_T0_sr(void)
430 {
431     env->sr = T0 & 0x700083f3;
432     RETURN();
433 }
434
435 void OPPROTO op_stc_sr_T0(void)
436 {
437     T0 = env->sr;
438     RETURN();
439 }
440
441 #define LDSTOPS(target,load,store) \
442 void OPPROTO op_##load##_T0_##target (void) \
443 { env ->target = T0;   RETURN(); \
444 } \
445 void OPPROTO op_##store##_##target##_T0 (void) \
446 { T0 = env->target;   RETURN(); \
447 } \
448
449     LDSTOPS(gbr, ldc, stc)
450     LDSTOPS(vbr, ldc, stc)
451     LDSTOPS(ssr, ldc, stc)
452     LDSTOPS(spc, ldc, stc)
453     LDSTOPS(sgr, ldc, stc)
454     LDSTOPS(dbr, ldc, stc)
455     LDSTOPS(mach, lds, sts)
456     LDSTOPS(macl, lds, sts)
457     LDSTOPS(pr, lds, sts)
458     LDSTOPS(fpul, lds, sts)
459
460 void OPPROTO op_lds_T0_fpscr(void)
461 {
462     env->fpscr = T0 & 0x003fffff;
463     env->fp_status.float_rounding_mode = T0 & 0x01 ?
464       float_round_to_zero : float_round_nearest_even;
465
466     RETURN();
467 }
468
469 void OPPROTO op_sts_fpscr_T0(void)
470 {
471     T0 = env->fpscr & 0x003fffff;
472     RETURN();
473 }
474
475 void OPPROTO op_movt_rN(void)
476 {
477     env->gregs[PARAM1] = env->sr & SR_T;
478     RETURN();
479 }
480
481 void OPPROTO op_rotcl_Rn(void)
482 {
483     helper_rotcl(&env->gregs[PARAM1]);
484     RETURN();
485 }
486
487 void OPPROTO op_rotcr_Rn(void)
488 {
489     helper_rotcr(&env->gregs[PARAM1]);
490     RETURN();
491 }
492
493 void OPPROTO op_rotl_Rn(void)
494 {
495     cond_t(env->gregs[PARAM1] & 0x80000000);
496     env->gregs[PARAM1] = (env->gregs[PARAM1] << 1) | (env->sr & SR_T);
497     RETURN();
498 }
499
500 void OPPROTO op_rotr_Rn(void)
501 {
502     cond_t(env->gregs[PARAM1] & 1);
503     env->gregs[PARAM1] = (env->gregs[PARAM1] >> 1) |
504         ((env->sr & SR_T) ? 0x80000000 : 0);
505     RETURN();
506 }
507
508 void OPPROTO op_shal_Rn(void)
509 {
510     cond_t(env->gregs[PARAM1] & 0x80000000);
511     env->gregs[PARAM1] <<= 1;
512     RETURN();
513 }
514
515 void OPPROTO op_shar_Rn(void)
516 {
517     cond_t(env->gregs[PARAM1] & 1);
518     *(int32_t *)&env->gregs[PARAM1] >>= 1;
519     RETURN();
520 }
521
522 void OPPROTO op_shlr_Rn(void)
523 {
524     cond_t(env->gregs[PARAM1] & 1);
525     env->gregs[PARAM1] >>= 1;
526     RETURN();
527 }
528
529 void OPPROTO op_shll2_Rn(void)
530 {
531     env->gregs[PARAM1] <<= 2;
532     RETURN();
533 }
534
535 void OPPROTO op_shll8_Rn(void)
536 {
537     env->gregs[PARAM1] <<= 8;
538     RETURN();
539 }
540
541 void OPPROTO op_shll16_Rn(void)
542 {
543     env->gregs[PARAM1] <<= 16;
544     RETURN();
545 }
546
547 void OPPROTO op_shlr2_Rn(void)
548 {
549     env->gregs[PARAM1] >>= 2;
550     RETURN();
551 }
552
553 void OPPROTO op_shlr8_Rn(void)
554 {
555     env->gregs[PARAM1] >>= 8;
556     RETURN();
557 }
558
559 void OPPROTO op_shlr16_Rn(void)
560 {
561     env->gregs[PARAM1] >>= 16;
562     RETURN();
563 }
564
565 void OPPROTO op_movl_T0_rN(void)
566 {
567     env->gregs[PARAM1] = T0;
568     RETURN();
569 }
570
571 void OPPROTO op_movl_T1_rN(void)
572 {
573     env->gregs[PARAM1] = T1;
574     RETURN();
575 }
576
577 void OPPROTO op_movb_rN_T0(void)
578 {
579     T0 = (int32_t) (int8_t) (env->gregs[PARAM1] & 0xff);
580     RETURN();
581 }
582
583 void OPPROTO op_movub_rN_T0(void)
584 {
585     T0 = env->gregs[PARAM1] & 0xff;
586     RETURN();
587 }
588
589 void OPPROTO op_movw_rN_T0(void)
590 {
591     T0 = (int32_t) (int16_t) (env->gregs[PARAM1] & 0xffff);
592     RETURN();
593 }
594
595 void OPPROTO op_movuw_rN_T0(void)
596 {
597     T0 = env->gregs[PARAM1] & 0xffff;
598     RETURN();
599 }
600
601 void OPPROTO op_movl_rN_T0(void)
602 {
603     T0 = env->gregs[PARAM1];
604     RETURN();
605 }
606
607 void OPPROTO op_movb_rN_T1(void)
608 {
609     T1 = (int32_t) (int8_t) (env->gregs[PARAM1] & 0xff);
610     RETURN();
611 }
612
613 void OPPROTO op_movub_rN_T1(void)
614 {
615     T1 = env->gregs[PARAM1] & 0xff;
616     RETURN();
617 }
618
619 void OPPROTO op_movw_rN_T1(void)
620 {
621     T1 = (int32_t) (int16_t) (env->gregs[PARAM1] & 0xffff);
622     RETURN();
623 }
624
625 void OPPROTO op_movuw_rN_T1(void)
626 {
627     T1 = env->gregs[PARAM1] & 0xffff;
628     RETURN();
629 }
630
631 void OPPROTO op_movl_rN_T1(void)
632 {
633     T1 = env->gregs[PARAM1];
634     RETURN();
635 }
636
637 void OPPROTO op_movl_imm_rN(void)
638 {
639     env->gregs[PARAM2] = PARAM1;
640     RETURN();
641 }
642
643 void OPPROTO op_fmov_frN_FT0(void)
644 {
645     FT0 = env->fregs[PARAM1];
646     RETURN();
647 }
648
649 void OPPROTO op_fmov_drN_DT0(void)
650 {
651     CPU_DoubleU d;
652
653     d.l.upper = *(uint32_t *)&env->fregs[PARAM1];
654     d.l.lower = *(uint32_t *)&env->fregs[PARAM1 + 1];
655     DT0 = d.d;
656     RETURN();
657 }
658
659 void OPPROTO op_fmov_frN_FT1(void)
660 {
661     FT1 = env->fregs[PARAM1];
662     RETURN();
663 }
664
665 void OPPROTO op_fmov_drN_DT1(void)
666 {
667     CPU_DoubleU d;
668
669     d.l.upper = *(uint32_t *)&env->fregs[PARAM1];
670     d.l.lower = *(uint32_t *)&env->fregs[PARAM1 + 1];
671     DT1 = d.d;
672     RETURN();
673 }
674
675 void OPPROTO op_fmov_FT0_frN(void)
676 {
677     env->fregs[PARAM1] = FT0;
678     RETURN();
679 }
680
681 void OPPROTO op_fmov_DT0_drN(void)
682 {
683     CPU_DoubleU d;
684
685     d.d = DT0;
686     *(uint32_t *)&env->fregs[PARAM1] = d.l.upper;
687     *(uint32_t *)&env->fregs[PARAM1 + 1] = d.l.lower;
688     RETURN();
689 }
690
691 void OPPROTO op_fadd_FT(void)
692 {
693     FT0 = float32_add(FT0, FT1, &env->fp_status);
694     RETURN();
695 }
696
697 void OPPROTO op_fadd_DT(void)
698 {
699     DT0 = float64_add(DT0, DT1, &env->fp_status);
700     RETURN();
701 }
702
703 void OPPROTO op_fsub_FT(void)
704 {
705     FT0 = float32_sub(FT0, FT1, &env->fp_status);
706     RETURN();
707 }
708
709 void OPPROTO op_fsub_DT(void)
710 {
711     DT0 = float64_sub(DT0, DT1, &env->fp_status);
712     RETURN();
713 }
714
715 void OPPROTO op_fmul_FT(void)
716 {
717     FT0 = float32_mul(FT0, FT1, &env->fp_status);
718     RETURN();
719 }
720
721 void OPPROTO op_fmul_DT(void)
722 {
723     DT0 = float64_mul(DT0, DT1, &env->fp_status);
724     RETURN();
725 }
726
727 void OPPROTO op_fdiv_FT(void)
728 {
729     FT0 = float32_div(FT0, FT1, &env->fp_status);
730     RETURN();
731 }
732
733 void OPPROTO op_fdiv_DT(void)
734 {
735     DT0 = float64_div(DT0, DT1, &env->fp_status);
736     RETURN();
737 }
738
739 void OPPROTO op_fcmp_eq_FT(void)
740 {
741     cond_t(float32_compare(FT0, FT1, &env->fp_status) == 0);
742     RETURN();
743 }
744
745 void OPPROTO op_fcmp_eq_DT(void)
746 {
747     cond_t(float64_compare(DT0, DT1, &env->fp_status) == 0);
748     RETURN();
749 }
750
751 void OPPROTO op_fcmp_gt_FT(void)
752 {
753     cond_t(float32_compare(FT0, FT1, &env->fp_status) == 1);
754     RETURN();
755 }
756
757 void OPPROTO op_fcmp_gt_DT(void)
758 {
759     cond_t(float64_compare(DT0, DT1, &env->fp_status) == 1);
760     RETURN();
761 }
762
763 void OPPROTO op_float_FT(void)
764 {
765     FT0 = int32_to_float32(env->fpul, &env->fp_status);
766     RETURN();
767 }
768
769 void OPPROTO op_float_DT(void)
770 {
771     DT0 = int32_to_float64(env->fpul, &env->fp_status);
772     RETURN();
773 }
774
775 void OPPROTO op_ftrc_FT(void)
776 {
777     env->fpul = float32_to_int32_round_to_zero(FT0, &env->fp_status);
778     RETURN();
779 }
780
781 void OPPROTO op_ftrc_DT(void)
782 {
783     env->fpul = float64_to_int32_round_to_zero(DT0, &env->fp_status);
784     RETURN();
785 }
786
787 void OPPROTO op_fneg_frN(void)
788 {
789     env->fregs[PARAM1] = float32_chs(env->fregs[PARAM1]);
790     RETURN();
791 }
792
793 void OPPROTO op_fabs_FT(void)
794 {
795     FT0 = float32_abs(FT0);
796     RETURN();
797 }
798
799 void OPPROTO op_fabs_DT(void)
800 {
801     DT0 = float64_abs(DT0);
802     RETURN();
803 }
804
805 void OPPROTO op_fcnvsd_FT_DT(void)
806 {
807     DT0 = float32_to_float64(FT0, &env->fp_status);
808     RETURN();
809 }
810
811 void OPPROTO op_fcnvds_DT_FT(void)
812 {
813     FT0 = float64_to_float32(DT0, &env->fp_status);
814     RETURN();
815 }
816
817 void OPPROTO op_fsqrt_FT(void)
818 {
819     FT0 = float32_sqrt(FT0, &env->fp_status);
820     RETURN();
821 }
822
823 void OPPROTO op_fsqrt_DT(void)
824 {
825     DT0 = float64_sqrt(DT0, &env->fp_status);
826     RETURN();
827 }
828
829 void OPPROTO op_fmov_T0_frN(void)
830 {
831     *(uint32_t *)&env->fregs[PARAM1] = T0;
832     RETURN();
833 }
834
835 void OPPROTO op_dec1_rN(void)
836 {
837     env->gregs[PARAM1] -= 1;
838     RETURN();
839 }
840
841 void OPPROTO op_dec2_rN(void)
842 {
843     env->gregs[PARAM1] -= 2;
844     RETURN();
845 }
846
847 void OPPROTO op_dec4_rN(void)
848 {
849     env->gregs[PARAM1] -= 4;
850     RETURN();
851 }
852
853 void OPPROTO op_dec8_rN(void)
854 {
855     env->gregs[PARAM1] -= 8;
856     RETURN();
857 }
858
859 void OPPROTO op_inc1_rN(void)
860 {
861     env->gregs[PARAM1] += 1;
862     RETURN();
863 }
864
865 void OPPROTO op_inc2_rN(void)
866 {
867     env->gregs[PARAM1] += 2;
868     RETURN();
869 }
870
871 void OPPROTO op_inc4_rN(void)
872 {
873     env->gregs[PARAM1] += 4;
874     RETURN();
875 }
876
877 void OPPROTO op_inc8_rN(void)
878 {
879     env->gregs[PARAM1] += 8;
880     RETURN();
881 }
882
883 void OPPROTO op_add_T0_rN(void)
884 {
885     env->gregs[PARAM1] += T0;
886     RETURN();
887 }
888
889 void OPPROTO op_sub_T0_rN(void)
890 {
891     env->gregs[PARAM1] -= T0;
892     RETURN();
893 }
894
895 void OPPROTO op_and_T0_rN(void)
896 {
897     env->gregs[PARAM1] &= T0;
898     RETURN();
899 }
900
901 void OPPROTO op_or_T0_rN(void)
902 {
903     env->gregs[PARAM1] |= T0;
904     RETURN();
905 }
906
907 void OPPROTO op_xor_T0_rN(void)
908 {
909     env->gregs[PARAM1] ^= T0;
910     RETURN();
911 }
912
913 void OPPROTO op_add_rN_T0(void)
914 {
915     T0 += env->gregs[PARAM1];
916     RETURN();
917 }
918
919 void OPPROTO op_add_rN_T1(void)
920 {
921     T1 += env->gregs[PARAM1];
922     RETURN();
923 }
924
925 void OPPROTO op_add_imm_rN(void)
926 {
927     env->gregs[PARAM2] += PARAM1;
928     RETURN();
929 }
930
931 void OPPROTO op_and_imm_rN(void)
932 {
933     env->gregs[PARAM2] &= PARAM1;
934     RETURN();
935 }
936
937 void OPPROTO op_or_imm_rN(void)
938 {
939     env->gregs[PARAM2] |= PARAM1;
940     RETURN();
941 }
942
943 void OPPROTO op_xor_imm_rN(void)
944 {
945     env->gregs[PARAM2] ^= PARAM1;
946     RETURN();
947 }
948
949 void OPPROTO op_dt_rN(void)
950 {
951     cond_t((--env->gregs[PARAM1]) == 0);
952     RETURN();
953 }
954
955 void OPPROTO op_tst_imm_rN(void)
956 {
957     cond_t((env->gregs[PARAM2] & PARAM1) == 0);
958     RETURN();
959 }
960
961 void OPPROTO op_movl_T0_T1(void)
962 {
963     T1 = T0;
964     RETURN();
965 }
966
967 void OPPROTO op_movl_fpul_FT0(void)
968 {
969     FT0 = *(float32 *)&env->fpul;
970     RETURN();
971 }
972
973 void OPPROTO op_movl_FT0_fpul(void)
974 {
975     *(float32 *)&env->fpul = FT0;
976     RETURN();
977 }
978
979 void OPPROTO op_movl_imm_PC(void)
980 {
981     env->pc = PARAM1;
982     RETURN();
983 }
984
985 void OPPROTO op_jT(void)
986 {
987     if (env->sr & SR_T)
988         GOTO_LABEL_PARAM(1);
989     RETURN();
990 }
991
992 void OPPROTO op_jdelayed(void)
993 {
994     if (env->flags & DELAY_SLOT_TRUE) {
995         env->flags &= ~DELAY_SLOT_TRUE;
996         GOTO_LABEL_PARAM(1);
997     }
998     RETURN();
999 }
1000
1001 void OPPROTO op_movl_delayed_pc_PC(void)
1002 {
1003     env->pc = env->delayed_pc;
1004     RETURN();
1005 }
1006
1007 void OPPROTO op_addl_GBR_T0(void)
1008 {
1009     T0 += env->gbr;
1010     RETURN();
1011 }
1012
1013 void OPPROTO op_and_imm_T0(void)
1014 {
1015     T0 &= PARAM1;
1016     RETURN();
1017 }
1018
1019 void OPPROTO op_or_imm_T0(void)
1020 {
1021     T0 |= PARAM1;
1022     RETURN();
1023 }
1024
1025 void OPPROTO op_xor_imm_T0(void)
1026 {
1027     T0 ^= PARAM1;
1028     RETURN();
1029 }
1030
1031 void OPPROTO op_tst_imm_T0(void)
1032 {
1033     cond_t((T0 & PARAM1) == 0);
1034     RETURN();
1035 }
1036
1037 void OPPROTO op_raise_illegal_instruction(void)
1038 {
1039     env->exception_index = 0x180;
1040     do_raise_exception();
1041     RETURN();
1042 }
1043
1044 void OPPROTO op_raise_slot_illegal_instruction(void)
1045 {
1046     env->exception_index = 0x1a0;
1047     do_raise_exception();
1048     RETURN();
1049 }
1050
1051 void OPPROTO op_debug(void)
1052 {
1053     env->exception_index = EXCP_DEBUG;
1054     cpu_loop_exit();
1055 }
1056
1057 void OPPROTO op_sleep(void)
1058 {
1059     env->halted = 1;
1060     env->exception_index = EXCP_HLT;
1061     cpu_loop_exit();
1062 }
1063
1064 /* Load and store */
1065 #define MEMSUFFIX _raw
1066 #include "op_mem.c"
1067 #undef MEMSUFFIX
1068 #if !defined(CONFIG_USER_ONLY)
1069 #define MEMSUFFIX _user
1070 #include "op_mem.c"
1071 #undef MEMSUFFIX
1072
1073 #define MEMSUFFIX _kernel
1074 #include "op_mem.c"
1075 #undef MEMSUFFIX
1076 #endif