4 * Copyright (c) 2005 Samuel Tardieu
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.
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.
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
22 static inline void set_t(void)
27 static inline void clr_t(void)
32 static inline void cond_t(int cond)
40 void OPPROTO op_movl_imm_T0(void)
42 T0 = (uint32_t) PARAM1;
46 void OPPROTO op_movl_imm_T1(void)
48 T1 = (uint32_t) PARAM1;
52 void OPPROTO op_cmp_eq_imm_T0(void)
54 cond_t((int32_t) T0 == (int32_t) PARAM1);
58 void OPPROTO op_cmd_eq_T0_T1(void)
64 void OPPROTO op_cmd_hs_T0_T1(void)
66 cond_t((uint32_t) T0 <= (uint32_t) T1);
70 void OPPROTO op_cmd_ge_T0_T1(void)
72 cond_t((int32_t) T0 <= (int32_t) T1);
76 void OPPROTO op_cmd_hi_T0_T1(void)
78 cond_t((uint32_t) T0 < (uint32_t) T1);
82 void OPPROTO op_cmd_gt_T0_T1(void)
84 cond_t((int32_t) T0 < (int32_t) T1);
88 void OPPROTO op_not_T0(void)
94 void OPPROTO op_bf_s(void)
96 env->delayed_pc = PARAM1;
97 if (!(env->sr & SR_T)) {
98 env->flags |= DELAY_SLOT_TRUE;
103 void OPPROTO op_bt_s(void)
105 env->delayed_pc = PARAM1;
106 if (env->sr & SR_T) {
107 env->flags |= DELAY_SLOT_TRUE;
112 void OPPROTO op_store_flags(void)
114 env->flags &= DELAY_SLOT_TRUE;
115 env->flags |= PARAM1;
119 void OPPROTO op_bra(void)
121 env->delayed_pc = PARAM1;
125 void OPPROTO op_braf_T0(void)
127 env->delayed_pc = PARAM1 + T0;
131 void OPPROTO op_bsr(void)
134 env->delayed_pc = PARAM2;
138 void OPPROTO op_bsrf_T0(void)
141 env->delayed_pc = PARAM1 + T0;
145 void OPPROTO op_jsr_T0(void)
148 env->delayed_pc = T0;
152 void OPPROTO op_rts(void)
154 env->delayed_pc = env->pr;
158 void OPPROTO op_addl_imm_T0(void)
164 void OPPROTO op_addl_imm_T1(void)
170 void OPPROTO op_clrmac(void)
172 env->mach = env->macl = 0;
176 void OPPROTO op_clrs(void)
182 void OPPROTO op_clrt(void)
188 void OPPROTO op_sets(void)
194 void OPPROTO op_sett(void)
200 void OPPROTO op_frchg(void)
202 env->fpscr ^= FPSCR_FR;
206 void OPPROTO op_fschg(void)
208 env->fpscr ^= FPSCR_SZ;
212 void OPPROTO op_rte(void)
215 env->delayed_pc = env->spc;
219 void OPPROTO op_swapb_T0(void)
221 T0 = (T0 & 0xffff0000) | ((T0 & 0xff) << 8) | ((T0 >> 8) & 0xff);
225 void OPPROTO op_swapw_T0(void)
227 T0 = ((T0 & 0xffff) << 16) | ((T0 >> 16) & 0xffff);
231 void OPPROTO op_xtrct_T0_T1(void)
233 T1 = ((T0 & 0xffff) << 16) | ((T1 >> 16) & 0xffff);
237 void OPPROTO op_add_T0_T1(void)
243 void OPPROTO op_addc_T0_T1(void)
249 void OPPROTO op_addv_T0_T1(void)
255 void OPPROTO op_cmp_eq_T0_T1(void)
261 void OPPROTO op_cmp_ge_T0_T1(void)
263 cond_t((int32_t) T1 >= (int32_t) T0);
267 void OPPROTO op_cmp_gt_T0_T1(void)
269 cond_t((int32_t) T1 > (int32_t) T0);
273 void OPPROTO op_cmp_hi_T0_T1(void)
275 cond_t((uint32_t) T1 > (uint32_t) T0);
279 void OPPROTO op_cmp_hs_T0_T1(void)
281 cond_t((uint32_t) T1 >= (uint32_t) T0);
285 void OPPROTO op_cmp_str_T0_T1(void)
287 cond_t((T0 & 0x000000ff) == (T1 & 0x000000ff) ||
288 (T0 & 0x0000ff00) == (T1 & 0x0000ff00) ||
289 (T0 & 0x00ff0000) == (T1 & 0x00ff0000) ||
290 (T0 & 0xff000000) == (T1 & 0xff000000));
294 void OPPROTO op_tst_T0_T1(void)
296 cond_t((T1 & T0) == 0);
300 void OPPROTO op_div0s_T0_T1(void)
310 cond_t((T1 ^ T0) & 0x80000000);
314 void OPPROTO op_div0u(void)
316 env->sr &= ~(SR_M | SR_Q | SR_T);
320 void OPPROTO op_div1_T0_T1(void)
326 void OPPROTO op_dmulsl_T0_T1(void)
328 helper_dmulsl_T0_T1();
332 void OPPROTO op_dmulul_T0_T1(void)
334 helper_dmulul_T0_T1();
338 void OPPROTO op_macl_T0_T1(void)
344 void OPPROTO op_macw_T0_T1(void)
350 void OPPROTO op_mull_T0_T1(void)
352 env->macl = (T0 * T1) & 0xffffffff;
356 void OPPROTO op_mulsw_T0_T1(void)
358 env->macl = (int32_t)(int16_t) T0 *(int32_t)(int16_t) T1;
362 void OPPROTO op_muluw_T0_T1(void)
364 env->macl = (uint32_t)(uint16_t) T0 *(uint32_t)(uint16_t) T1;
368 void OPPROTO op_neg_T0(void)
374 void OPPROTO op_negc_T0(void)
380 void OPPROTO op_shad_T0_T1(void)
382 if ((T0 & 0x80000000) == 0)
384 else if ((T0 & 0x1f) == 0)
385 T1 = (T1 & 0x80000000)? 0xffffffff : 0;
387 T1 = ((int32_t) T1) >> ((~T0 & 0x1f) + 1);
391 void OPPROTO op_shld_T0_T1(void)
393 if ((T0 & 0x80000000) == 0)
395 else if ((T0 & 0x1f) == 0)
398 T1 = ((uint32_t) T1) >> ((~T0 & 0x1f) + 1);
402 void OPPROTO op_subc_T0_T1(void)
408 void OPPROTO op_subv_T0_T1(void)
414 void OPPROTO op_trapa(void)
416 env->tra = PARAM1 << 2;
417 env->exception_index = 0x160;
418 do_raise_exception();
422 void OPPROTO op_cmp_pl_T0(void)
424 cond_t((int32_t) T0 > 0);
428 void OPPROTO op_cmp_pz_T0(void)
430 cond_t((int32_t) T0 >= 0);
434 void OPPROTO op_jmp_T0(void)
436 env->delayed_pc = T0;
440 void OPPROTO op_movl_rN_rN(void)
442 env->gregs[PARAM2] = env->gregs[PARAM1];
446 void OPPROTO op_ldcl_rMplus_rN_bank(void)
448 env->gregs[PARAM2] = env->gregs[PARAM1];
449 env->gregs[PARAM1] += 4;
453 void OPPROTO op_ldc_T0_sr(void)
455 env->sr = T0 & 0x700083f3;
459 void OPPROTO op_stc_sr_T0(void)
465 #define LDSTOPS(target,load,store) \
466 void OPPROTO op_##load##_T0_##target (void) \
467 { env ->target = T0; RETURN(); \
469 void OPPROTO op_##store##_##target##_T0 (void) \
470 { T0 = env->target; RETURN(); \
473 LDSTOPS(gbr, ldc, stc)
474 LDSTOPS(vbr, ldc, stc)
475 LDSTOPS(ssr, ldc, stc)
476 LDSTOPS(spc, ldc, stc)
477 LDSTOPS(sgr, ldc, stc)
478 LDSTOPS(dbr, ldc, stc)
479 LDSTOPS(mach, lds, sts)
480 LDSTOPS(macl, lds, sts)
481 LDSTOPS(pr, lds, sts)
482 LDSTOPS(fpul, lds, sts)
484 void OPPROTO op_lds_T0_fpscr(void)
486 env->fpscr = T0 & 0x003fffff;
487 env->fp_status.float_rounding_mode = T0 & 0x01 ?
488 float_round_to_zero : float_round_nearest_even;
493 void OPPROTO op_sts_fpscr_T0(void)
495 T0 = env->fpscr & 0x003fffff;
499 void OPPROTO op_movt_rN(void)
501 env->gregs[PARAM1] = env->sr & SR_T;
505 void OPPROTO op_rotcl_Rn(void)
507 helper_rotcl(&env->gregs[PARAM1]);
511 void OPPROTO op_rotcr_Rn(void)
513 helper_rotcr(&env->gregs[PARAM1]);
517 void OPPROTO op_rotl_Rn(void)
519 cond_t(env->gregs[PARAM1] & 0x80000000);
520 env->gregs[PARAM1] = (env->gregs[PARAM1] << 1) | (env->sr & SR_T);
524 void OPPROTO op_rotr_Rn(void)
526 cond_t(env->gregs[PARAM1] & 1);
527 env->gregs[PARAM1] = (env->gregs[PARAM1] >> 1) |
528 ((env->sr & SR_T) ? 0x80000000 : 0);
532 void OPPROTO op_shal_Rn(void)
534 cond_t(env->gregs[PARAM1] & 0x80000000);
535 env->gregs[PARAM1] <<= 1;
539 void OPPROTO op_shar_Rn(void)
541 cond_t(env->gregs[PARAM1] & 1);
542 *(int32_t *)&env->gregs[PARAM1] >>= 1;
546 void OPPROTO op_shlr_Rn(void)
548 cond_t(env->gregs[PARAM1] & 1);
549 env->gregs[PARAM1] >>= 1;
553 void OPPROTO op_shll2_Rn(void)
555 env->gregs[PARAM1] <<= 2;
559 void OPPROTO op_shll8_Rn(void)
561 env->gregs[PARAM1] <<= 8;
565 void OPPROTO op_shll16_Rn(void)
567 env->gregs[PARAM1] <<= 16;
571 void OPPROTO op_shlr2_Rn(void)
573 env->gregs[PARAM1] >>= 2;
577 void OPPROTO op_shlr8_Rn(void)
579 env->gregs[PARAM1] >>= 8;
583 void OPPROTO op_shlr16_Rn(void)
585 env->gregs[PARAM1] >>= 16;
589 void OPPROTO op_tasb_rN(void)
591 cond_t(*(int8_t *) env->gregs[PARAM1] == 0);
592 *(int8_t *) env->gregs[PARAM1] |= 0x80;
596 void OPPROTO op_movl_T0_rN(void)
598 env->gregs[PARAM1] = T0;
602 void OPPROTO op_movl_T1_rN(void)
604 env->gregs[PARAM1] = T1;
608 void OPPROTO op_movb_rN_T0(void)
610 T0 = (int32_t) (int8_t) (env->gregs[PARAM1] & 0xff);
614 void OPPROTO op_movub_rN_T0(void)
616 T0 = env->gregs[PARAM1] & 0xff;
620 void OPPROTO op_movw_rN_T0(void)
622 T0 = (int32_t) (int16_t) (env->gregs[PARAM1] & 0xffff);
626 void OPPROTO op_movuw_rN_T0(void)
628 T0 = env->gregs[PARAM1] & 0xffff;
632 void OPPROTO op_movl_rN_T0(void)
634 T0 = env->gregs[PARAM1];
638 void OPPROTO op_movb_rN_T1(void)
640 T1 = (int32_t) (int8_t) (env->gregs[PARAM1] & 0xff);
644 void OPPROTO op_movub_rN_T1(void)
646 T1 = env->gregs[PARAM1] & 0xff;
650 void OPPROTO op_movw_rN_T1(void)
652 T1 = (int32_t) (int16_t) (env->gregs[PARAM1] & 0xffff);
656 void OPPROTO op_movuw_rN_T1(void)
658 T1 = env->gregs[PARAM1] & 0xffff;
662 void OPPROTO op_movl_rN_T1(void)
664 T1 = env->gregs[PARAM1];
668 void OPPROTO op_movl_imm_rN(void)
670 env->gregs[PARAM2] = PARAM1;
674 void OPPROTO op_fmov_frN_FT0(void)
676 FT0 = env->fregs[PARAM1];
680 void OPPROTO op_fmov_drN_DT0(void)
684 d.l.upper = *(uint32_t *)&env->fregs[PARAM1];
685 d.l.lower = *(uint32_t *)&env->fregs[PARAM1 + 1];
690 void OPPROTO op_fmov_frN_FT1(void)
692 FT1 = env->fregs[PARAM1];
696 void OPPROTO op_fmov_drN_DT1(void)
700 d.l.upper = *(uint32_t *)&env->fregs[PARAM1];
701 d.l.lower = *(uint32_t *)&env->fregs[PARAM1 + 1];
706 void OPPROTO op_fmov_FT0_frN(void)
708 env->fregs[PARAM1] = FT0;
712 void OPPROTO op_fmov_DT0_drN(void)
717 *(uint32_t *)&env->fregs[PARAM1] = d.l.upper;
718 *(uint32_t *)&env->fregs[PARAM1 + 1] = d.l.lower;
722 void OPPROTO op_fadd_FT(void)
724 FT0 = float32_add(FT0, FT1, &env->fp_status);
728 void OPPROTO op_fadd_DT(void)
730 DT0 = float64_add(DT0, DT1, &env->fp_status);
734 void OPPROTO op_fsub_FT(void)
736 FT0 = float32_sub(FT0, FT1, &env->fp_status);
740 void OPPROTO op_fsub_DT(void)
742 DT0 = float64_sub(DT0, DT1, &env->fp_status);
746 void OPPROTO op_fmul_FT(void)
748 FT0 = float32_mul(FT0, FT1, &env->fp_status);
752 void OPPROTO op_fmul_DT(void)
754 DT0 = float64_mul(DT0, DT1, &env->fp_status);
758 void OPPROTO op_fdiv_FT(void)
760 FT0 = float32_div(FT0, FT1, &env->fp_status);
764 void OPPROTO op_fdiv_DT(void)
766 DT0 = float64_div(DT0, DT1, &env->fp_status);
770 void OPPROTO op_fcmp_eq_FT(void)
772 cond_t(float32_compare(FT0, FT1, &env->fp_status) == 0);
776 void OPPROTO op_fcmp_eq_DT(void)
778 cond_t(float64_compare(DT0, DT1, &env->fp_status) == 0);
782 void OPPROTO op_fcmp_gt_FT(void)
784 cond_t(float32_compare(FT0, FT1, &env->fp_status) == 1);
788 void OPPROTO op_fcmp_gt_DT(void)
790 cond_t(float64_compare(DT0, DT1, &env->fp_status) == 1);
794 void OPPROTO op_float_FT(void)
796 FT0 = int32_to_float32(env->fpul, &env->fp_status);
800 void OPPROTO op_float_DT(void)
802 DT0 = int32_to_float64(env->fpul, &env->fp_status);
806 void OPPROTO op_ftrc_FT(void)
808 env->fpul = float32_to_int32_round_to_zero(FT0, &env->fp_status);
812 void OPPROTO op_ftrc_DT(void)
814 env->fpul = float64_to_int32_round_to_zero(DT0, &env->fp_status);
818 void OPPROTO op_fneg_frN(void)
820 env->fregs[PARAM1] = float32_chs(env->fregs[PARAM1]);
824 void OPPROTO op_fabs_FT(void)
826 FT0 = float32_abs(FT0);
830 void OPPROTO op_fabs_DT(void)
832 DT0 = float64_abs(DT0);
836 void OPPROTO op_fcnvsd_FT_DT(void)
838 DT0 = float32_to_float64(FT0, &env->fp_status);
842 void OPPROTO op_fcnvds_DT_FT(void)
844 FT0 = float64_to_float32(DT0, &env->fp_status);
848 void OPPROTO op_fsqrt_FT(void)
850 FT0 = float32_sqrt(FT0, &env->fp_status);
854 void OPPROTO op_fsqrt_DT(void)
856 DT0 = float64_sqrt(DT0, &env->fp_status);
860 void OPPROTO op_fmov_T0_frN(void)
862 *(uint32_t *)&env->fregs[PARAM1] = T0;
866 void OPPROTO op_dec1_rN(void)
868 env->gregs[PARAM1] -= 1;
872 void OPPROTO op_dec2_rN(void)
874 env->gregs[PARAM1] -= 2;
878 void OPPROTO op_dec4_rN(void)
880 env->gregs[PARAM1] -= 4;
884 void OPPROTO op_dec8_rN(void)
886 env->gregs[PARAM1] -= 8;
890 void OPPROTO op_inc1_rN(void)
892 env->gregs[PARAM1] += 1;
896 void OPPROTO op_inc2_rN(void)
898 env->gregs[PARAM1] += 2;
902 void OPPROTO op_inc4_rN(void)
904 env->gregs[PARAM1] += 4;
908 void OPPROTO op_inc8_rN(void)
910 env->gregs[PARAM1] += 8;
914 void OPPROTO op_add_T0_rN(void)
916 env->gregs[PARAM1] += T0;
920 void OPPROTO op_sub_T0_rN(void)
922 env->gregs[PARAM1] -= T0;
926 void OPPROTO op_and_T0_rN(void)
928 env->gregs[PARAM1] &= T0;
932 void OPPROTO op_or_T0_rN(void)
934 env->gregs[PARAM1] |= T0;
938 void OPPROTO op_xor_T0_rN(void)
940 env->gregs[PARAM1] ^= T0;
944 void OPPROTO op_add_rN_T0(void)
946 T0 += env->gregs[PARAM1];
950 void OPPROTO op_add_rN_T1(void)
952 T1 += env->gregs[PARAM1];
956 void OPPROTO op_add_imm_rN(void)
958 env->gregs[PARAM2] += PARAM1;
962 void OPPROTO op_and_imm_rN(void)
964 env->gregs[PARAM2] &= PARAM1;
968 void OPPROTO op_or_imm_rN(void)
970 env->gregs[PARAM2] |= PARAM1;
974 void OPPROTO op_xor_imm_rN(void)
976 env->gregs[PARAM2] ^= PARAM1;
980 void OPPROTO op_dt_rN(void)
982 cond_t((--env->gregs[PARAM1]) == 0);
986 void OPPROTO op_tst_imm_rN(void)
988 cond_t((env->gregs[PARAM2] & PARAM1) == 0);
992 void OPPROTO op_movl_T0_T1(void)
998 void OPPROTO op_movl_fpul_FT0(void)
1000 FT0 = *(float32 *)&env->fpul;
1004 void OPPROTO op_movl_FT0_fpul(void)
1006 *(float32 *)&env->fpul = FT0;
1010 void OPPROTO op_movl_imm_PC(void)
1016 void OPPROTO op_jT(void)
1019 GOTO_LABEL_PARAM(1);
1023 void OPPROTO op_jdelayed(void)
1025 if (env->flags & DELAY_SLOT_TRUE) {
1026 env->flags &= ~DELAY_SLOT_TRUE;
1027 GOTO_LABEL_PARAM(1);
1032 void OPPROTO op_movl_delayed_pc_PC(void)
1034 env->pc = env->delayed_pc;
1038 void OPPROTO op_addl_GBR_T0(void)
1044 void OPPROTO op_and_imm_T0(void)
1050 void OPPROTO op_or_imm_T0(void)
1056 void OPPROTO op_xor_imm_T0(void)
1062 void OPPROTO op_tst_imm_T0(void)
1064 cond_t((T0 & PARAM1) == 0);
1068 void OPPROTO op_raise_illegal_instruction(void)
1070 env->exception_index = 0x180;
1071 do_raise_exception();
1075 void OPPROTO op_raise_slot_illegal_instruction(void)
1077 env->exception_index = 0x1a0;
1078 do_raise_exception();
1082 void OPPROTO op_debug(void)
1084 env->exception_index = EXCP_DEBUG;
1088 /* Load and store */
1089 #define MEMSUFFIX _raw
1092 #if !defined(CONFIG_USER_ONLY)
1093 #define MEMSUFFIX _user
1097 #define MEMSUFFIX _kernel