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_flag(uint32_t flag)
27 static inline void clr_flag(uint32_t flag)
32 static inline void set_t(void)
37 static inline void clr_t(void)
42 static inline void cond_t(int cond)
50 void OPPROTO op_movl_imm_T0(void)
52 T0 = (uint32_t) PARAM1;
56 void OPPROTO op_movl_imm_T1(void)
58 T0 = (uint32_t) PARAM1;
62 void OPPROTO op_movl_imm_T2(void)
64 T0 = (uint32_t) PARAM1;
68 void OPPROTO op_cmp_eq_imm_T0(void)
70 cond_t((int32_t) T0 == (int32_t) PARAM1);
74 void OPPROTO op_cmd_eq_T0_T1(void)
80 void OPPROTO op_cmd_hs_T0_T1(void)
82 cond_t((uint32_t) T0 <= (uint32_t) T1);
86 void OPPROTO op_cmd_ge_T0_T1(void)
88 cond_t((int32_t) T0 <= (int32_t) T1);
92 void OPPROTO op_cmd_hi_T0_T1(void)
94 cond_t((uint32_t) T0 < (uint32_t) T1);
98 void OPPROTO op_cmd_gt_T0_T1(void)
100 cond_t((int32_t) T0 < (int32_t) T1);
104 void OPPROTO op_not_T0(void)
110 void OPPROTO op_bf_s(void)
112 env->delayed_pc = PARAM1;
113 set_flag(DELAY_SLOT_CONDITIONAL | ((~env->sr) & SR_T));
117 void OPPROTO op_bt_s(void)
119 env->delayed_pc = PARAM1;
120 set_flag(DELAY_SLOT_CONDITIONAL | (env->sr & SR_T));
124 void OPPROTO op_bra(void)
126 env->delayed_pc = PARAM1;
127 set_flag(DELAY_SLOT);
131 void OPPROTO op_braf_T0(void)
133 env->delayed_pc = PARAM1 + T0;
134 set_flag(DELAY_SLOT);
138 void OPPROTO op_bsr(void)
141 env->delayed_pc = PARAM2;
142 set_flag(DELAY_SLOT);
146 void OPPROTO op_bsrf_T0(void)
149 env->delayed_pc = PARAM1 + T0;
150 set_flag(DELAY_SLOT);
154 void OPPROTO op_jsr_T0(void)
157 env->delayed_pc = T0;
158 set_flag(DELAY_SLOT);
162 void OPPROTO op_rts(void)
164 env->delayed_pc = env->pr;
165 set_flag(DELAY_SLOT);
169 void OPPROTO op_clr_delay_slot(void)
171 clr_flag(DELAY_SLOT);
175 void OPPROTO op_clr_delay_slot_conditional(void)
177 clr_flag(DELAY_SLOT_CONDITIONAL);
181 void OPPROTO op_exit_tb(void)
187 void OPPROTO op_addl_imm_T0(void)
193 void OPPROTO op_addl_imm_T1(void)
199 void OPPROTO op_clrmac(void)
201 env->mach = env->macl = 0;
205 void OPPROTO op_clrs(void)
211 void OPPROTO op_clrt(void)
217 void OPPROTO op_sets(void)
223 void OPPROTO op_sett(void)
229 void OPPROTO op_frchg(void)
231 env->fpscr ^= FPSCR_FR;
235 void OPPROTO op_fschg(void)
237 env->fpscr ^= FPSCR_SZ;
241 void OPPROTO op_rte(void)
244 env->delayed_pc = env->spc;
245 set_flag(DELAY_SLOT);
249 void OPPROTO op_swapb_T0(void)
251 T0 = (T0 & 0xffff0000) | ((T0 & 0xff) << 8) | ((T0 >> 8) & 0xff);
255 void OPPROTO op_swapw_T0(void)
257 T0 = ((T0 & 0xffff) << 16) | ((T0 >> 16) & 0xffff);
261 void OPPROTO op_xtrct_T0_T1(void)
263 T1 = ((T0 & 0xffff) << 16) | ((T1 >> 16) & 0xffff);
267 void OPPROTO op_addc_T0_T1(void)
273 void OPPROTO op_addv_T0_T1(void)
279 void OPPROTO op_cmp_eq_T0_T1(void)
285 void OPPROTO op_cmp_ge_T0_T1(void)
287 cond_t((int32_t) T1 >= (int32_t) T0);
291 void OPPROTO op_cmp_gt_T0_T1(void)
293 cond_t((int32_t) T1 > (int32_t) T0);
297 void OPPROTO op_cmp_hi_T0_T1(void)
299 cond_t((uint32_t) T1 > (uint32_t) T0);
303 void OPPROTO op_cmp_hs_T0_T1(void)
305 cond_t((uint32_t) T1 >= (uint32_t) T0);
309 void OPPROTO op_cmp_str_T0_T1(void)
311 cond_t((T0 & 0x000000ff) == (T1 & 0x000000ff) ||
312 (T0 & 0x0000ff00) == (T1 & 0x0000ff00) ||
313 (T0 & 0x00ff0000) == (T1 & 0x00ff0000) ||
314 (T0 & 0xff000000) == (T1 & 0xff000000));
318 void OPPROTO op_tst_T0_T1(void)
320 cond_t((T1 & T0) == 0);
324 void OPPROTO op_div0s_T0_T1(void)
334 cond_t((T1 ^ T0) & 0x80000000);
338 void OPPROTO op_div0u(void)
340 env->sr &= ~(SR_M | SR_Q | SR_T);
344 void OPPROTO op_div1_T0_T1(void)
350 void OPPROTO op_dmulsl_T0_T1(void)
352 helper_dmulsl_T0_T1();
356 void OPPROTO op_dmulul_T0_T1(void)
358 helper_dmulul_T0_T1();
362 void OPPROTO op_macl_T0_T1(void)
368 void OPPROTO op_macw_T0_T1(void)
374 void OPPROTO op_mull_T0_T1(void)
376 env->macl = (T0 * T1) & 0xffffffff;
380 void OPPROTO op_mulsw_T0_T1(void)
382 env->macl = (int32_t) T0 *(int32_t) T1;
386 void OPPROTO op_muluw_T0_T1(void)
388 env->macl = (uint32_t) T0 *(uint32_t) T1;
392 void OPPROTO op_neg_T0(void)
398 void OPPROTO op_negc_T0(void)
404 void OPPROTO op_shad_T0_T1(void)
406 if ((T0 & 0x80000000) == 0)
408 else if ((T0 & 0x1f) == 0)
411 T1 = ((int32_t) T1) >> ((~T0 & 0x1f) + 1);
415 void OPPROTO op_shld_T0_T1(void)
417 if ((T0 & 0x80000000) == 0)
419 else if ((T0 & 0x1f) == 0)
422 T1 = ((uint32_t) T1) >> ((~T0 & 0x1f) + 1);
426 void OPPROTO op_subc_T0_T1(void)
432 void OPPROTO op_subv_T0_T1(void)
438 void OPPROTO op_trapa(void)
440 env->tra = PARAM1 * 2;
441 env->exception_index = 0x160;
442 do_raise_exception();
446 void OPPROTO op_cmp_pl_T0(void)
448 cond_t((int32_t) T0 > 0);
452 void OPPROTO op_cmp_pz_T0(void)
454 cond_t((int32_t) T0 >= 0);
458 void OPPROTO op_jmp_T0(void)
460 env->delayed_pc = T0;
461 set_flag(DELAY_SLOT);
465 void OPPROTO op_movl_rN_rN(void)
467 env->gregs[PARAM2] = env->gregs[PARAM1];
471 void OPPROTO op_ldcl_rMplus_rN_bank(void)
473 env->gregs[PARAM2] = env->gregs[PARAM1];
474 env->gregs[PARAM1] += 4;
478 void OPPROTO op_ldc_T0_sr(void)
480 env->sr = T0 & 0x700083f3;
484 void OPPROTO op_stc_sr_T0(void)
490 #define LDSTOPS(target,load,store) \
491 void OPPROTO op_##load##_T0_##target (void) \
492 { env ->target = T0; RETURN(); \
494 void OPPROTO op_##store##_##target##_T0 (void) \
495 { T0 = env->target; RETURN(); \
498 LDSTOPS(gbr, ldc, stc)
499 LDSTOPS(vbr, ldc, stc)
500 LDSTOPS(ssr, ldc, stc)
501 LDSTOPS(spc, ldc, stc)
502 LDSTOPS(sgr, ldc, stc)
503 LDSTOPS(dbr, ldc, stc)
504 LDSTOPS(mach, lds, sts)
505 LDSTOPS(macl, lds, sts)
506 LDSTOPS(pr, lds, sts)
507 LDSTOPS(fpul, lds, sts)
509 void OPPROTO op_lds_T0_fpscr(void)
511 env->fpscr = T0 & 0x003fffff;
512 env->fp_status.float_rounding_mode = T0 & 0x01 ?
513 float_round_to_zero : float_round_nearest_even;
518 void OPPROTO op_sts_fpscr_T0(void)
520 T0 = env->fpscr & 0x003fffff;
524 void OPPROTO op_movt_rN(void)
526 env->gregs[PARAM1] = env->sr & SR_T;
530 void OPPROTO op_rotcl_Rn(void)
532 helper_rotcl(&env->gregs[PARAM1]);
536 void OPPROTO op_rotcr_Rn(void)
538 helper_rotcr(&env->gregs[PARAM1]);
542 void OPPROTO op_rotl_Rn(void)
544 cond_t(env->gregs[PARAM1] & 0x80000000);
545 env->gregs[PARAM1] = (env->gregs[PARAM1] << 1) | (env->sr & SR_T);
549 void OPPROTO op_rotr_Rn(void)
551 cond_t(env->gregs[PARAM1] & 1);
552 env->gregs[PARAM1] = (env->gregs[PARAM1] >> 1) |
553 ((env->sr & SR_T) ? 0x80000000 : 0);
557 void OPPROTO op_shal_Rn(void)
559 cond_t(env->gregs[PARAM1] & 0x80000000);
560 env->gregs[PARAM1] <<= 1;
564 void OPPROTO op_shar_Rn(void)
566 cond_t(env->gregs[PARAM1] & 1);
567 env->gregs[PARAM1] >>= 1;
571 void OPPROTO op_shlr_Rn(void)
573 cond_t(env->gregs[PARAM1] & 1);
574 env->gregs[PARAM1] >>= 1;
578 void OPPROTO op_shll2_Rn(void)
580 env->gregs[PARAM1] <<= 2;
584 void OPPROTO op_shll8_Rn(void)
586 env->gregs[PARAM1] <<= 8;
590 void OPPROTO op_shll16_Rn(void)
592 env->gregs[PARAM1] <<= 16;
596 void OPPROTO op_shlr2_Rn(void)
598 env->gregs[PARAM1] >>= 2;
602 void OPPROTO op_shlr8_Rn(void)
604 env->gregs[PARAM1] >>= 8;
608 void OPPROTO op_shlr16_Rn(void)
610 env->gregs[PARAM1] >>= 16;
614 void OPPROTO op_tasb_rN(void)
616 cond_t(*(int8_t *) env->gregs[PARAM1] == 0);
617 *(int8_t *) env->gregs[PARAM1] |= 0x80;
621 void OPPROTO op_movl_T0_rN(void)
623 env->gregs[PARAM1] = T0;
627 void OPPROTO op_movl_T1_rN(void)
629 env->gregs[PARAM1] = T1;
633 void OPPROTO op_movb_rN_T0(void)
635 T0 = (int32_t) (int8_t) (env->gregs[PARAM1] & 0xff);
639 void OPPROTO op_movub_rN_T0(void)
641 T0 = env->gregs[PARAM1] & 0xff;
645 void OPPROTO op_movw_rN_T0(void)
647 T0 = (int32_t) (int16_t) (env->gregs[PARAM1] & 0xffff);
651 void OPPROTO op_movuw_rN_T0(void)
653 T0 = env->gregs[PARAM1] & 0xffff;
657 void OPPROTO op_movl_rN_T0(void)
659 T0 = env->gregs[PARAM1];
663 void OPPROTO op_movb_rN_T1(void)
665 T1 = (int32_t) (int8_t) (env->gregs[PARAM1] & 0xff);
669 void OPPROTO op_movub_rN_T1(void)
671 T1 = env->gregs[PARAM1] & 0xff;
675 void OPPROTO op_movw_rN_T1(void)
677 T1 = (int32_t) (int16_t) (env->gregs[PARAM1] & 0xffff);
681 void OPPROTO op_movuw_rN_T1(void)
683 T1 = env->gregs[PARAM1] & 0xffff;
687 void OPPROTO op_movl_rN_T1(void)
689 T1 = env->gregs[PARAM1];
693 void OPPROTO op_movl_imm_rN(void)
695 env->gregs[PARAM2] = PARAM1;
699 void OPPROTO op_fmov_frN_FT0(void)
701 FT0 = env->fregs[PARAM1];
705 void OPPROTO op_fmov_drN_DT0(void)
709 d.l.upper = *(uint32_t *)&env->fregs[PARAM1];
710 d.l.lower = *(uint32_t *)&env->fregs[PARAM1 + 1];
715 void OPPROTO op_fmov_frN_FT1(void)
717 FT1 = env->fregs[PARAM1];
721 void OPPROTO op_fmov_drN_DT1(void)
725 d.l.upper = *(uint32_t *)&env->fregs[PARAM1];
726 d.l.lower = *(uint32_t *)&env->fregs[PARAM1 + 1];
731 void OPPROTO op_fmov_FT0_frN(void)
733 env->fregs[PARAM1] = FT0;
737 void OPPROTO op_fmov_DT0_drN(void)
742 *(uint32_t *)&env->fregs[PARAM1] = d.l.upper;
743 *(uint32_t *)&env->fregs[PARAM1 + 1] = d.l.lower;
747 void OPPROTO op_fadd_FT(void)
749 FT0 = float32_add(FT0, FT1, &env->fp_status);
753 void OPPROTO op_fadd_DT(void)
755 DT0 = float64_add(DT0, DT1, &env->fp_status);
759 void OPPROTO op_fsub_FT(void)
761 FT0 = float32_sub(FT0, FT1, &env->fp_status);
765 void OPPROTO op_fsub_DT(void)
767 DT0 = float64_sub(DT0, DT1, &env->fp_status);
771 void OPPROTO op_fmul_FT(void)
773 FT0 = float32_mul(FT0, FT1, &env->fp_status);
777 void OPPROTO op_fmul_DT(void)
779 DT0 = float64_mul(DT0, DT1, &env->fp_status);
783 void OPPROTO op_fdiv_FT(void)
785 FT0 = float32_div(FT0, FT1, &env->fp_status);
789 void OPPROTO op_fdiv_DT(void)
791 DT0 = float64_div(DT0, DT1, &env->fp_status);
795 void OPPROTO op_float_FT(void)
797 FT0 = int32_to_float32(env->fpul, &env->fp_status);
801 void OPPROTO op_float_DT(void)
803 DT0 = int32_to_float64(env->fpul, &env->fp_status);
807 void OPPROTO op_ftrc_FT(void)
809 env->fpul = float32_to_int32_round_to_zero(FT0, &env->fp_status);
813 void OPPROTO op_ftrc_DT(void)
815 env->fpul = float64_to_int32_round_to_zero(DT0, &env->fp_status);
819 void OPPROTO op_fmov_T0_frN(void)
821 *(unsigned int *)&env->fregs[PARAM1] = T0;
825 void OPPROTO op_dec1_rN(void)
827 env->gregs[PARAM1] -= 1;
831 void OPPROTO op_dec2_rN(void)
833 env->gregs[PARAM1] -= 2;
837 void OPPROTO op_dec4_rN(void)
839 env->gregs[PARAM1] -= 4;
843 void OPPROTO op_dec8_rN(void)
845 env->gregs[PARAM1] -= 8;
849 void OPPROTO op_inc1_rN(void)
851 env->gregs[PARAM1] += 1;
855 void OPPROTO op_inc2_rN(void)
857 env->gregs[PARAM1] += 2;
861 void OPPROTO op_inc4_rN(void)
863 env->gregs[PARAM1] += 4;
867 void OPPROTO op_inc8_rN(void)
869 env->gregs[PARAM1] += 8;
873 void OPPROTO op_add_T0_rN(void)
875 env->gregs[PARAM1] += T0;
879 void OPPROTO op_sub_T0_rN(void)
881 env->gregs[PARAM1] -= T0;
885 void OPPROTO op_and_T0_rN(void)
887 env->gregs[PARAM1] &= T0;
891 void OPPROTO op_or_T0_rN(void)
893 env->gregs[PARAM1] |= T0;
897 void OPPROTO op_xor_T0_rN(void)
899 env->gregs[PARAM1] ^= T0;
903 void OPPROTO op_add_rN_T0(void)
905 T0 += env->gregs[PARAM1];
909 void OPPROTO op_add_rN_T1(void)
911 T1 += env->gregs[PARAM1];
915 void OPPROTO op_add_imm_rN(void)
917 env->gregs[PARAM2] += PARAM1;
921 void OPPROTO op_and_imm_rN(void)
923 env->gregs[PARAM2] &= PARAM1;
927 void OPPROTO op_or_imm_rN(void)
929 env->gregs[PARAM2] |= PARAM1;
933 void OPPROTO op_xor_imm_rN(void)
935 env->gregs[PARAM2] ^= PARAM1;
939 void OPPROTO op_dt_rN(void)
941 cond_t((--env->gregs[PARAM1]) == 0);
945 void OPPROTO op_tst_imm_rN(void)
947 cond_t((env->gregs[PARAM2] & PARAM1) == 0);
951 void OPPROTO op_movl_T0_T1(void)
957 void OPPROTO op_movl_fpul_FT0(void)
959 FT0 = *(float32 *)&env->fpul;
963 void OPPROTO op_movl_FT0_fpul(void)
965 *(float32 *)&env->fpul = FT0;
969 void OPPROTO op_goto_tb0(void)
971 GOTO_TB(op_goto_tb0, PARAM1, 0);
975 void OPPROTO op_goto_tb1(void)
977 GOTO_TB(op_goto_tb1, PARAM1, 1);
981 void OPPROTO op_movl_imm_PC(void)
987 void OPPROTO op_jT(void)
994 void OPPROTO op_jdelayed(void)
998 env->flags &= ~(DELAY_SLOT | DELAY_SLOT_CONDITIONAL);
999 if (flags & DELAY_SLOT)
1000 GOTO_LABEL_PARAM(1);
1004 void OPPROTO op_movl_delayed_pc_PC(void)
1006 env->pc = env->delayed_pc;
1010 void OPPROTO op_addl_GBR_T0(void)
1016 void OPPROTO op_and_imm_T0(void)
1022 void OPPROTO op_or_imm_T0(void)
1028 void OPPROTO op_xor_imm_T0(void)
1034 void OPPROTO op_tst_imm_T0(void)
1036 cond_t((T0 & PARAM1) == 0);
1040 void OPPROTO op_raise_illegal_instruction(void)
1042 env->exception_index = 0x180;
1043 do_raise_exception();
1047 void OPPROTO op_raise_slot_illegal_instruction(void)
1049 env->exception_index = 0x1a0;
1050 do_raise_exception();
1054 void OPPROTO op_debug(void)
1056 env->exception_index = EXCP_DEBUG;
1060 /* Load and store */
1061 #define MEMSUFFIX _raw
1064 #if !defined(CONFIG_USER_ONLY)
1065 #define MEMSUFFIX _user
1069 #define MEMSUFFIX _kernel