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_ldtlb(void)
194 void OPPROTO op_sets(void)
200 void OPPROTO op_sett(void)
206 void OPPROTO op_frchg(void)
208 env->fpscr ^= FPSCR_FR;
212 void OPPROTO op_fschg(void)
214 env->fpscr ^= FPSCR_SZ;
218 void OPPROTO op_rte(void)
221 env->delayed_pc = env->spc;
225 void OPPROTO op_swapb_T0(void)
227 T0 = (T0 & 0xffff0000) | ((T0 & 0xff) << 8) | ((T0 >> 8) & 0xff);
231 void OPPROTO op_swapw_T0(void)
233 T0 = ((T0 & 0xffff) << 16) | ((T0 >> 16) & 0xffff);
237 void OPPROTO op_xtrct_T0_T1(void)
239 T1 = ((T0 & 0xffff) << 16) | ((T1 >> 16) & 0xffff);
243 void OPPROTO op_add_T0_T1(void)
249 void OPPROTO op_addc_T0_T1(void)
255 void OPPROTO op_addv_T0_T1(void)
261 void OPPROTO op_cmp_eq_T0_T1(void)
267 void OPPROTO op_cmp_ge_T0_T1(void)
269 cond_t((int32_t) T1 >= (int32_t) T0);
273 void OPPROTO op_cmp_gt_T0_T1(void)
275 cond_t((int32_t) T1 > (int32_t) T0);
279 void OPPROTO op_cmp_hi_T0_T1(void)
281 cond_t((uint32_t) T1 > (uint32_t) T0);
285 void OPPROTO op_cmp_hs_T0_T1(void)
287 cond_t((uint32_t) T1 >= (uint32_t) T0);
291 void OPPROTO op_cmp_str_T0_T1(void)
293 cond_t((T0 & 0x000000ff) == (T1 & 0x000000ff) ||
294 (T0 & 0x0000ff00) == (T1 & 0x0000ff00) ||
295 (T0 & 0x00ff0000) == (T1 & 0x00ff0000) ||
296 (T0 & 0xff000000) == (T1 & 0xff000000));
300 void OPPROTO op_tst_T0_T1(void)
302 cond_t((T1 & T0) == 0);
306 void OPPROTO op_div0s_T0_T1(void)
316 cond_t((T1 ^ T0) & 0x80000000);
320 void OPPROTO op_div0u(void)
322 env->sr &= ~(SR_M | SR_Q | SR_T);
326 void OPPROTO op_div1_T0_T1(void)
332 void OPPROTO op_dmulsl_T0_T1(void)
334 helper_dmulsl_T0_T1();
338 void OPPROTO op_dmulul_T0_T1(void)
340 helper_dmulul_T0_T1();
344 void OPPROTO op_macl_T0_T1(void)
350 void OPPROTO op_macw_T0_T1(void)
356 void OPPROTO op_mull_T0_T1(void)
358 env->macl = (T0 * T1) & 0xffffffff;
362 void OPPROTO op_mulsw_T0_T1(void)
364 env->macl = (int32_t)(int16_t) T0 *(int32_t)(int16_t) T1;
368 void OPPROTO op_muluw_T0_T1(void)
370 env->macl = (uint32_t)(uint16_t) T0 *(uint32_t)(uint16_t) T1;
374 void OPPROTO op_neg_T0(void)
380 void OPPROTO op_negc_T0(void)
386 void OPPROTO op_shad_T0_T1(void)
388 if ((T0 & 0x80000000) == 0)
390 else if ((T0 & 0x1f) == 0)
391 T1 = (T1 & 0x80000000)? 0xffffffff : 0;
393 T1 = ((int32_t) T1) >> ((~T0 & 0x1f) + 1);
397 void OPPROTO op_shld_T0_T1(void)
399 if ((T0 & 0x80000000) == 0)
401 else if ((T0 & 0x1f) == 0)
404 T1 = ((uint32_t) T1) >> ((~T0 & 0x1f) + 1);
408 void OPPROTO op_subc_T0_T1(void)
414 void OPPROTO op_subv_T0_T1(void)
420 void OPPROTO op_trapa(void)
422 env->tra = PARAM1 << 2;
423 env->exception_index = 0x160;
424 do_raise_exception();
428 void OPPROTO op_cmp_pl_T0(void)
430 cond_t((int32_t) T0 > 0);
434 void OPPROTO op_cmp_pz_T0(void)
436 cond_t((int32_t) T0 >= 0);
440 void OPPROTO op_jmp_T0(void)
442 env->delayed_pc = T0;
446 void OPPROTO op_movl_rN_rN(void)
448 env->gregs[PARAM2] = env->gregs[PARAM1];
452 void OPPROTO op_ldcl_rMplus_rN_bank(void)
454 env->gregs[PARAM2] = env->gregs[PARAM1];
455 env->gregs[PARAM1] += 4;
459 void OPPROTO op_ldc_T0_sr(void)
461 env->sr = T0 & 0x700083f3;
465 void OPPROTO op_stc_sr_T0(void)
471 #define LDSTOPS(target,load,store) \
472 void OPPROTO op_##load##_T0_##target (void) \
473 { env ->target = T0; RETURN(); \
475 void OPPROTO op_##store##_##target##_T0 (void) \
476 { T0 = env->target; RETURN(); \
479 LDSTOPS(gbr, ldc, stc)
480 LDSTOPS(vbr, ldc, stc)
481 LDSTOPS(ssr, ldc, stc)
482 LDSTOPS(spc, ldc, stc)
483 LDSTOPS(sgr, ldc, stc)
484 LDSTOPS(dbr, ldc, stc)
485 LDSTOPS(mach, lds, sts)
486 LDSTOPS(macl, lds, sts)
487 LDSTOPS(pr, lds, sts)
488 LDSTOPS(fpul, lds, sts)
490 void OPPROTO op_lds_T0_fpscr(void)
492 env->fpscr = T0 & 0x003fffff;
493 env->fp_status.float_rounding_mode = T0 & 0x01 ?
494 float_round_to_zero : float_round_nearest_even;
499 void OPPROTO op_sts_fpscr_T0(void)
501 T0 = env->fpscr & 0x003fffff;
505 void OPPROTO op_movt_rN(void)
507 env->gregs[PARAM1] = env->sr & SR_T;
511 void OPPROTO op_rotcl_Rn(void)
513 helper_rotcl(&env->gregs[PARAM1]);
517 void OPPROTO op_rotcr_Rn(void)
519 helper_rotcr(&env->gregs[PARAM1]);
523 void OPPROTO op_rotl_Rn(void)
525 cond_t(env->gregs[PARAM1] & 0x80000000);
526 env->gregs[PARAM1] = (env->gregs[PARAM1] << 1) | (env->sr & SR_T);
530 void OPPROTO op_rotr_Rn(void)
532 cond_t(env->gregs[PARAM1] & 1);
533 env->gregs[PARAM1] = (env->gregs[PARAM1] >> 1) |
534 ((env->sr & SR_T) ? 0x80000000 : 0);
538 void OPPROTO op_shal_Rn(void)
540 cond_t(env->gregs[PARAM1] & 0x80000000);
541 env->gregs[PARAM1] <<= 1;
545 void OPPROTO op_shar_Rn(void)
547 cond_t(env->gregs[PARAM1] & 1);
548 *(int32_t *)&env->gregs[PARAM1] >>= 1;
552 void OPPROTO op_shlr_Rn(void)
554 cond_t(env->gregs[PARAM1] & 1);
555 env->gregs[PARAM1] >>= 1;
559 void OPPROTO op_shll2_Rn(void)
561 env->gregs[PARAM1] <<= 2;
565 void OPPROTO op_shll8_Rn(void)
567 env->gregs[PARAM1] <<= 8;
571 void OPPROTO op_shll16_Rn(void)
573 env->gregs[PARAM1] <<= 16;
577 void OPPROTO op_shlr2_Rn(void)
579 env->gregs[PARAM1] >>= 2;
583 void OPPROTO op_shlr8_Rn(void)
585 env->gregs[PARAM1] >>= 8;
589 void OPPROTO op_shlr16_Rn(void)
591 env->gregs[PARAM1] >>= 16;
595 void OPPROTO op_movl_T0_rN(void)
597 env->gregs[PARAM1] = T0;
601 void OPPROTO op_movl_T1_rN(void)
603 env->gregs[PARAM1] = T1;
607 void OPPROTO op_movb_rN_T0(void)
609 T0 = (int32_t) (int8_t) (env->gregs[PARAM1] & 0xff);
613 void OPPROTO op_movub_rN_T0(void)
615 T0 = env->gregs[PARAM1] & 0xff;
619 void OPPROTO op_movw_rN_T0(void)
621 T0 = (int32_t) (int16_t) (env->gregs[PARAM1] & 0xffff);
625 void OPPROTO op_movuw_rN_T0(void)
627 T0 = env->gregs[PARAM1] & 0xffff;
631 void OPPROTO op_movl_rN_T0(void)
633 T0 = env->gregs[PARAM1];
637 void OPPROTO op_movb_rN_T1(void)
639 T1 = (int32_t) (int8_t) (env->gregs[PARAM1] & 0xff);
643 void OPPROTO op_movub_rN_T1(void)
645 T1 = env->gregs[PARAM1] & 0xff;
649 void OPPROTO op_movw_rN_T1(void)
651 T1 = (int32_t) (int16_t) (env->gregs[PARAM1] & 0xffff);
655 void OPPROTO op_movuw_rN_T1(void)
657 T1 = env->gregs[PARAM1] & 0xffff;
661 void OPPROTO op_movl_rN_T1(void)
663 T1 = env->gregs[PARAM1];
667 void OPPROTO op_movl_imm_rN(void)
669 env->gregs[PARAM2] = PARAM1;
673 void OPPROTO op_fmov_frN_FT0(void)
675 FT0 = env->fregs[PARAM1];
679 void OPPROTO op_fmov_drN_DT0(void)
683 d.l.upper = *(uint32_t *)&env->fregs[PARAM1];
684 d.l.lower = *(uint32_t *)&env->fregs[PARAM1 + 1];
689 void OPPROTO op_fmov_frN_FT1(void)
691 FT1 = env->fregs[PARAM1];
695 void OPPROTO op_fmov_drN_DT1(void)
699 d.l.upper = *(uint32_t *)&env->fregs[PARAM1];
700 d.l.lower = *(uint32_t *)&env->fregs[PARAM1 + 1];
705 void OPPROTO op_fmov_FT0_frN(void)
707 env->fregs[PARAM1] = FT0;
711 void OPPROTO op_fmov_DT0_drN(void)
716 *(uint32_t *)&env->fregs[PARAM1] = d.l.upper;
717 *(uint32_t *)&env->fregs[PARAM1 + 1] = d.l.lower;
721 void OPPROTO op_fadd_FT(void)
723 FT0 = float32_add(FT0, FT1, &env->fp_status);
727 void OPPROTO op_fadd_DT(void)
729 DT0 = float64_add(DT0, DT1, &env->fp_status);
733 void OPPROTO op_fsub_FT(void)
735 FT0 = float32_sub(FT0, FT1, &env->fp_status);
739 void OPPROTO op_fsub_DT(void)
741 DT0 = float64_sub(DT0, DT1, &env->fp_status);
745 void OPPROTO op_fmul_FT(void)
747 FT0 = float32_mul(FT0, FT1, &env->fp_status);
751 void OPPROTO op_fmul_DT(void)
753 DT0 = float64_mul(DT0, DT1, &env->fp_status);
757 void OPPROTO op_fdiv_FT(void)
759 FT0 = float32_div(FT0, FT1, &env->fp_status);
763 void OPPROTO op_fdiv_DT(void)
765 DT0 = float64_div(DT0, DT1, &env->fp_status);
769 void OPPROTO op_fcmp_eq_FT(void)
771 cond_t(float32_compare(FT0, FT1, &env->fp_status) == 0);
775 void OPPROTO op_fcmp_eq_DT(void)
777 cond_t(float64_compare(DT0, DT1, &env->fp_status) == 0);
781 void OPPROTO op_fcmp_gt_FT(void)
783 cond_t(float32_compare(FT0, FT1, &env->fp_status) == 1);
787 void OPPROTO op_fcmp_gt_DT(void)
789 cond_t(float64_compare(DT0, DT1, &env->fp_status) == 1);
793 void OPPROTO op_float_FT(void)
795 FT0 = int32_to_float32(env->fpul, &env->fp_status);
799 void OPPROTO op_float_DT(void)
801 DT0 = int32_to_float64(env->fpul, &env->fp_status);
805 void OPPROTO op_ftrc_FT(void)
807 env->fpul = float32_to_int32_round_to_zero(FT0, &env->fp_status);
811 void OPPROTO op_ftrc_DT(void)
813 env->fpul = float64_to_int32_round_to_zero(DT0, &env->fp_status);
817 void OPPROTO op_fneg_frN(void)
819 env->fregs[PARAM1] = float32_chs(env->fregs[PARAM1]);
823 void OPPROTO op_fabs_FT(void)
825 FT0 = float32_abs(FT0);
829 void OPPROTO op_fabs_DT(void)
831 DT0 = float64_abs(DT0);
835 void OPPROTO op_fcnvsd_FT_DT(void)
837 DT0 = float32_to_float64(FT0, &env->fp_status);
841 void OPPROTO op_fcnvds_DT_FT(void)
843 FT0 = float64_to_float32(DT0, &env->fp_status);
847 void OPPROTO op_fsqrt_FT(void)
849 FT0 = float32_sqrt(FT0, &env->fp_status);
853 void OPPROTO op_fsqrt_DT(void)
855 DT0 = float64_sqrt(DT0, &env->fp_status);
859 void OPPROTO op_fmov_T0_frN(void)
861 *(uint32_t *)&env->fregs[PARAM1] = T0;
865 void OPPROTO op_dec1_rN(void)
867 env->gregs[PARAM1] -= 1;
871 void OPPROTO op_dec2_rN(void)
873 env->gregs[PARAM1] -= 2;
877 void OPPROTO op_dec4_rN(void)
879 env->gregs[PARAM1] -= 4;
883 void OPPROTO op_dec8_rN(void)
885 env->gregs[PARAM1] -= 8;
889 void OPPROTO op_inc1_rN(void)
891 env->gregs[PARAM1] += 1;
895 void OPPROTO op_inc2_rN(void)
897 env->gregs[PARAM1] += 2;
901 void OPPROTO op_inc4_rN(void)
903 env->gregs[PARAM1] += 4;
907 void OPPROTO op_inc8_rN(void)
909 env->gregs[PARAM1] += 8;
913 void OPPROTO op_add_T0_rN(void)
915 env->gregs[PARAM1] += T0;
919 void OPPROTO op_sub_T0_rN(void)
921 env->gregs[PARAM1] -= T0;
925 void OPPROTO op_and_T0_rN(void)
927 env->gregs[PARAM1] &= T0;
931 void OPPROTO op_or_T0_rN(void)
933 env->gregs[PARAM1] |= T0;
937 void OPPROTO op_xor_T0_rN(void)
939 env->gregs[PARAM1] ^= T0;
943 void OPPROTO op_add_rN_T0(void)
945 T0 += env->gregs[PARAM1];
949 void OPPROTO op_add_rN_T1(void)
951 T1 += env->gregs[PARAM1];
955 void OPPROTO op_add_imm_rN(void)
957 env->gregs[PARAM2] += PARAM1;
961 void OPPROTO op_and_imm_rN(void)
963 env->gregs[PARAM2] &= PARAM1;
967 void OPPROTO op_or_imm_rN(void)
969 env->gregs[PARAM2] |= PARAM1;
973 void OPPROTO op_xor_imm_rN(void)
975 env->gregs[PARAM2] ^= PARAM1;
979 void OPPROTO op_dt_rN(void)
981 cond_t((--env->gregs[PARAM1]) == 0);
985 void OPPROTO op_tst_imm_rN(void)
987 cond_t((env->gregs[PARAM2] & PARAM1) == 0);
991 void OPPROTO op_movl_T0_T1(void)
997 void OPPROTO op_movl_fpul_FT0(void)
999 FT0 = *(float32 *)&env->fpul;
1003 void OPPROTO op_movl_FT0_fpul(void)
1005 *(float32 *)&env->fpul = FT0;
1009 void OPPROTO op_movl_imm_PC(void)
1015 void OPPROTO op_jT(void)
1018 GOTO_LABEL_PARAM(1);
1022 void OPPROTO op_jdelayed(void)
1024 if (env->flags & DELAY_SLOT_TRUE) {
1025 env->flags &= ~DELAY_SLOT_TRUE;
1026 GOTO_LABEL_PARAM(1);
1031 void OPPROTO op_movl_delayed_pc_PC(void)
1033 env->pc = env->delayed_pc;
1037 void OPPROTO op_addl_GBR_T0(void)
1043 void OPPROTO op_and_imm_T0(void)
1049 void OPPROTO op_or_imm_T0(void)
1055 void OPPROTO op_xor_imm_T0(void)
1061 void OPPROTO op_tst_imm_T0(void)
1063 cond_t((T0 & PARAM1) == 0);
1067 void OPPROTO op_raise_illegal_instruction(void)
1069 env->exception_index = 0x180;
1070 do_raise_exception();
1074 void OPPROTO op_raise_slot_illegal_instruction(void)
1076 env->exception_index = 0x1a0;
1077 do_raise_exception();
1081 void OPPROTO op_debug(void)
1083 env->exception_index = EXCP_DEBUG;
1087 void OPPROTO op_sleep(void)
1090 env->exception_index = EXCP_HLT;
1094 /* Load and store */
1095 #define MEMSUFFIX _raw
1098 #if !defined(CONFIG_USER_ONLY)
1099 #define MEMSUFFIX _user
1103 #define MEMSUFFIX _kernel