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_not_T0(void)
64 void OPPROTO op_bf_s(void)
66 env->delayed_pc = PARAM1;
67 if (!(env->sr & SR_T)) {
68 env->flags |= DELAY_SLOT_TRUE;
73 void OPPROTO op_bt_s(void)
75 env->delayed_pc = PARAM1;
77 env->flags |= DELAY_SLOT_TRUE;
82 void OPPROTO op_store_flags(void)
84 env->flags &= DELAY_SLOT_TRUE;
89 void OPPROTO op_bra(void)
91 env->delayed_pc = PARAM1;
95 void OPPROTO op_braf_T0(void)
97 env->delayed_pc = PARAM1 + T0;
101 void OPPROTO op_bsr(void)
104 env->delayed_pc = PARAM2;
108 void OPPROTO op_bsrf_T0(void)
111 env->delayed_pc = PARAM1 + T0;
115 void OPPROTO op_jsr_T0(void)
118 env->delayed_pc = T0;
122 void OPPROTO op_rts(void)
124 env->delayed_pc = env->pr;
128 void OPPROTO op_addl_imm_T0(void)
134 void OPPROTO op_addl_imm_T1(void)
140 void OPPROTO op_clrmac(void)
142 env->mach = env->macl = 0;
146 void OPPROTO op_clrs(void)
152 void OPPROTO op_clrt(void)
158 void OPPROTO op_ldtlb(void)
164 void OPPROTO op_sets(void)
170 void OPPROTO op_sett(void)
176 void OPPROTO op_frchg(void)
178 env->fpscr ^= FPSCR_FR;
182 void OPPROTO op_fschg(void)
184 env->fpscr ^= FPSCR_SZ;
188 void OPPROTO op_rte(void)
191 env->delayed_pc = env->spc;
195 void OPPROTO op_swapb_T0(void)
197 T0 = (T0 & 0xffff0000) | ((T0 & 0xff) << 8) | ((T0 >> 8) & 0xff);
201 void OPPROTO op_swapw_T0(void)
203 T0 = ((T0 & 0xffff) << 16) | ((T0 >> 16) & 0xffff);
207 void OPPROTO op_xtrct_T0_T1(void)
209 T1 = ((T0 & 0xffff) << 16) | ((T1 >> 16) & 0xffff);
213 void OPPROTO op_add_T0_T1(void)
219 void OPPROTO op_addc_T0_T1(void)
225 void OPPROTO op_addv_T0_T1(void)
231 void OPPROTO op_cmp_eq_T0_T1(void)
237 void OPPROTO op_cmp_ge_T0_T1(void)
239 cond_t((int32_t) T1 >= (int32_t) T0);
243 void OPPROTO op_cmp_gt_T0_T1(void)
245 cond_t((int32_t) T1 > (int32_t) T0);
249 void OPPROTO op_cmp_hi_T0_T1(void)
251 cond_t((uint32_t) T1 > (uint32_t) T0);
255 void OPPROTO op_cmp_hs_T0_T1(void)
257 cond_t((uint32_t) T1 >= (uint32_t) T0);
261 void OPPROTO op_cmp_str_T0_T1(void)
263 cond_t((T0 & 0x000000ff) == (T1 & 0x000000ff) ||
264 (T0 & 0x0000ff00) == (T1 & 0x0000ff00) ||
265 (T0 & 0x00ff0000) == (T1 & 0x00ff0000) ||
266 (T0 & 0xff000000) == (T1 & 0xff000000));
270 void OPPROTO op_tst_T0_T1(void)
272 cond_t((T1 & T0) == 0);
276 void OPPROTO op_div0s_T0_T1(void)
286 cond_t((T1 ^ T0) & 0x80000000);
290 void OPPROTO op_div0u(void)
292 env->sr &= ~(SR_M | SR_Q | SR_T);
296 void OPPROTO op_div1_T0_T1(void)
302 void OPPROTO op_dmulsl_T0_T1(void)
304 helper_dmulsl_T0_T1();
308 void OPPROTO op_dmulul_T0_T1(void)
310 helper_dmulul_T0_T1();
314 void OPPROTO op_macl_T0_T1(void)
320 void OPPROTO op_macw_T0_T1(void)
326 void OPPROTO op_mull_T0_T1(void)
328 env->macl = (T0 * T1) & 0xffffffff;
332 void OPPROTO op_mulsw_T0_T1(void)
334 env->macl = (int32_t)(int16_t) T0 *(int32_t)(int16_t) T1;
338 void OPPROTO op_muluw_T0_T1(void)
340 env->macl = (uint32_t)(uint16_t) T0 *(uint32_t)(uint16_t) T1;
344 void OPPROTO op_neg_T0(void)
350 void OPPROTO op_negc_T0(void)
356 void OPPROTO op_shad_T0_T1(void)
358 if ((T0 & 0x80000000) == 0)
360 else if ((T0 & 0x1f) == 0)
361 T1 = (T1 & 0x80000000)? 0xffffffff : 0;
363 T1 = ((int32_t) T1) >> ((~T0 & 0x1f) + 1);
367 void OPPROTO op_shld_T0_T1(void)
369 if ((T0 & 0x80000000) == 0)
371 else if ((T0 & 0x1f) == 0)
374 T1 = ((uint32_t) T1) >> ((~T0 & 0x1f) + 1);
378 void OPPROTO op_subc_T0_T1(void)
384 void OPPROTO op_subv_T0_T1(void)
390 void OPPROTO op_trapa(void)
392 env->tra = PARAM1 << 2;
393 env->exception_index = 0x160;
394 do_raise_exception();
398 void OPPROTO op_cmp_pl_T0(void)
400 cond_t((int32_t) T0 > 0);
404 void OPPROTO op_cmp_pz_T0(void)
406 cond_t((int32_t) T0 >= 0);
410 void OPPROTO op_jmp_T0(void)
412 env->delayed_pc = T0;
416 void OPPROTO op_movl_rN_rN(void)
418 env->gregs[PARAM2] = env->gregs[PARAM1];
422 void OPPROTO op_ldcl_rMplus_rN_bank(void)
424 env->gregs[PARAM2] = env->gregs[PARAM1];
425 env->gregs[PARAM1] += 4;
429 void OPPROTO op_ldc_T0_sr(void)
431 env->sr = T0 & 0x700083f3;
435 void OPPROTO op_stc_sr_T0(void)
441 #define LDSTOPS(target,load,store) \
442 void OPPROTO op_##load##_T0_##target (void) \
443 { env ->target = T0; RETURN(); \
445 void OPPROTO op_##store##_##target##_T0 (void) \
446 { T0 = env->target; RETURN(); \
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)
460 void OPPROTO op_lds_T0_fpscr(void)
462 env->fpscr = T0 & 0x003fffff;
463 env->fp_status.float_rounding_mode = T0 & 0x01 ?
464 float_round_to_zero : float_round_nearest_even;
469 void OPPROTO op_sts_fpscr_T0(void)
471 T0 = env->fpscr & 0x003fffff;
475 void OPPROTO op_movt_rN(void)
477 env->gregs[PARAM1] = env->sr & SR_T;
481 void OPPROTO op_rotcl_Rn(void)
483 helper_rotcl(&env->gregs[PARAM1]);
487 void OPPROTO op_rotcr_Rn(void)
489 helper_rotcr(&env->gregs[PARAM1]);
493 void OPPROTO op_rotl_Rn(void)
495 cond_t(env->gregs[PARAM1] & 0x80000000);
496 env->gregs[PARAM1] = (env->gregs[PARAM1] << 1) | (env->sr & SR_T);
500 void OPPROTO op_rotr_Rn(void)
502 cond_t(env->gregs[PARAM1] & 1);
503 env->gregs[PARAM1] = (env->gregs[PARAM1] >> 1) |
504 ((env->sr & SR_T) ? 0x80000000 : 0);
508 void OPPROTO op_shal_Rn(void)
510 cond_t(env->gregs[PARAM1] & 0x80000000);
511 env->gregs[PARAM1] <<= 1;
515 void OPPROTO op_shar_Rn(void)
517 cond_t(env->gregs[PARAM1] & 1);
518 *(int32_t *)&env->gregs[PARAM1] >>= 1;
522 void OPPROTO op_shlr_Rn(void)
524 cond_t(env->gregs[PARAM1] & 1);
525 env->gregs[PARAM1] >>= 1;
529 void OPPROTO op_shll2_Rn(void)
531 env->gregs[PARAM1] <<= 2;
535 void OPPROTO op_shll8_Rn(void)
537 env->gregs[PARAM1] <<= 8;
541 void OPPROTO op_shll16_Rn(void)
543 env->gregs[PARAM1] <<= 16;
547 void OPPROTO op_shlr2_Rn(void)
549 env->gregs[PARAM1] >>= 2;
553 void OPPROTO op_shlr8_Rn(void)
555 env->gregs[PARAM1] >>= 8;
559 void OPPROTO op_shlr16_Rn(void)
561 env->gregs[PARAM1] >>= 16;
565 void OPPROTO op_movl_T0_rN(void)
567 env->gregs[PARAM1] = T0;
571 void OPPROTO op_movl_T1_rN(void)
573 env->gregs[PARAM1] = T1;
577 void OPPROTO op_movb_rN_T0(void)
579 T0 = (int32_t) (int8_t) (env->gregs[PARAM1] & 0xff);
583 void OPPROTO op_movub_rN_T0(void)
585 T0 = env->gregs[PARAM1] & 0xff;
589 void OPPROTO op_movw_rN_T0(void)
591 T0 = (int32_t) (int16_t) (env->gregs[PARAM1] & 0xffff);
595 void OPPROTO op_movuw_rN_T0(void)
597 T0 = env->gregs[PARAM1] & 0xffff;
601 void OPPROTO op_movl_rN_T0(void)
603 T0 = env->gregs[PARAM1];
607 void OPPROTO op_movb_rN_T1(void)
609 T1 = (int32_t) (int8_t) (env->gregs[PARAM1] & 0xff);
613 void OPPROTO op_movub_rN_T1(void)
615 T1 = env->gregs[PARAM1] & 0xff;
619 void OPPROTO op_movw_rN_T1(void)
621 T1 = (int32_t) (int16_t) (env->gregs[PARAM1] & 0xffff);
625 void OPPROTO op_movuw_rN_T1(void)
627 T1 = env->gregs[PARAM1] & 0xffff;
631 void OPPROTO op_movl_rN_T1(void)
633 T1 = env->gregs[PARAM1];
637 void OPPROTO op_movl_imm_rN(void)
639 env->gregs[PARAM2] = PARAM1;
643 void OPPROTO op_fmov_frN_FT0(void)
645 FT0 = env->fregs[PARAM1];
649 void OPPROTO op_fmov_drN_DT0(void)
653 d.l.upper = *(uint32_t *)&env->fregs[PARAM1];
654 d.l.lower = *(uint32_t *)&env->fregs[PARAM1 + 1];
659 void OPPROTO op_fmov_frN_FT1(void)
661 FT1 = env->fregs[PARAM1];
665 void OPPROTO op_fmov_drN_DT1(void)
669 d.l.upper = *(uint32_t *)&env->fregs[PARAM1];
670 d.l.lower = *(uint32_t *)&env->fregs[PARAM1 + 1];
675 void OPPROTO op_fmov_FT0_frN(void)
677 env->fregs[PARAM1] = FT0;
681 void OPPROTO op_fmov_DT0_drN(void)
686 *(uint32_t *)&env->fregs[PARAM1] = d.l.upper;
687 *(uint32_t *)&env->fregs[PARAM1 + 1] = d.l.lower;
691 void OPPROTO op_fadd_FT(void)
693 FT0 = float32_add(FT0, FT1, &env->fp_status);
697 void OPPROTO op_fadd_DT(void)
699 DT0 = float64_add(DT0, DT1, &env->fp_status);
703 void OPPROTO op_fsub_FT(void)
705 FT0 = float32_sub(FT0, FT1, &env->fp_status);
709 void OPPROTO op_fsub_DT(void)
711 DT0 = float64_sub(DT0, DT1, &env->fp_status);
715 void OPPROTO op_fmul_FT(void)
717 FT0 = float32_mul(FT0, FT1, &env->fp_status);
721 void OPPROTO op_fmul_DT(void)
723 DT0 = float64_mul(DT0, DT1, &env->fp_status);
727 void OPPROTO op_fdiv_FT(void)
729 FT0 = float32_div(FT0, FT1, &env->fp_status);
733 void OPPROTO op_fdiv_DT(void)
735 DT0 = float64_div(DT0, DT1, &env->fp_status);
739 void OPPROTO op_fcmp_eq_FT(void)
741 cond_t(float32_compare(FT0, FT1, &env->fp_status) == 0);
745 void OPPROTO op_fcmp_eq_DT(void)
747 cond_t(float64_compare(DT0, DT1, &env->fp_status) == 0);
751 void OPPROTO op_fcmp_gt_FT(void)
753 cond_t(float32_compare(FT0, FT1, &env->fp_status) == 1);
757 void OPPROTO op_fcmp_gt_DT(void)
759 cond_t(float64_compare(DT0, DT1, &env->fp_status) == 1);
763 void OPPROTO op_float_FT(void)
765 FT0 = int32_to_float32(env->fpul, &env->fp_status);
769 void OPPROTO op_float_DT(void)
771 DT0 = int32_to_float64(env->fpul, &env->fp_status);
775 void OPPROTO op_ftrc_FT(void)
777 env->fpul = float32_to_int32_round_to_zero(FT0, &env->fp_status);
781 void OPPROTO op_ftrc_DT(void)
783 env->fpul = float64_to_int32_round_to_zero(DT0, &env->fp_status);
787 void OPPROTO op_fneg_frN(void)
789 env->fregs[PARAM1] = float32_chs(env->fregs[PARAM1]);
793 void OPPROTO op_fabs_FT(void)
795 FT0 = float32_abs(FT0);
799 void OPPROTO op_fabs_DT(void)
801 DT0 = float64_abs(DT0);
805 void OPPROTO op_fcnvsd_FT_DT(void)
807 DT0 = float32_to_float64(FT0, &env->fp_status);
811 void OPPROTO op_fcnvds_DT_FT(void)
813 FT0 = float64_to_float32(DT0, &env->fp_status);
817 void OPPROTO op_fsqrt_FT(void)
819 FT0 = float32_sqrt(FT0, &env->fp_status);
823 void OPPROTO op_fsqrt_DT(void)
825 DT0 = float64_sqrt(DT0, &env->fp_status);
829 void OPPROTO op_fmov_T0_frN(void)
831 *(uint32_t *)&env->fregs[PARAM1] = T0;
835 void OPPROTO op_dec1_rN(void)
837 env->gregs[PARAM1] -= 1;
841 void OPPROTO op_dec2_rN(void)
843 env->gregs[PARAM1] -= 2;
847 void OPPROTO op_dec4_rN(void)
849 env->gregs[PARAM1] -= 4;
853 void OPPROTO op_dec8_rN(void)
855 env->gregs[PARAM1] -= 8;
859 void OPPROTO op_inc1_rN(void)
861 env->gregs[PARAM1] += 1;
865 void OPPROTO op_inc2_rN(void)
867 env->gregs[PARAM1] += 2;
871 void OPPROTO op_inc4_rN(void)
873 env->gregs[PARAM1] += 4;
877 void OPPROTO op_inc8_rN(void)
879 env->gregs[PARAM1] += 8;
883 void OPPROTO op_add_T0_rN(void)
885 env->gregs[PARAM1] += T0;
889 void OPPROTO op_sub_T0_rN(void)
891 env->gregs[PARAM1] -= T0;
895 void OPPROTO op_and_T0_rN(void)
897 env->gregs[PARAM1] &= T0;
901 void OPPROTO op_or_T0_rN(void)
903 env->gregs[PARAM1] |= T0;
907 void OPPROTO op_xor_T0_rN(void)
909 env->gregs[PARAM1] ^= T0;
913 void OPPROTO op_add_rN_T0(void)
915 T0 += env->gregs[PARAM1];
919 void OPPROTO op_add_rN_T1(void)
921 T1 += env->gregs[PARAM1];
925 void OPPROTO op_add_imm_rN(void)
927 env->gregs[PARAM2] += PARAM1;
931 void OPPROTO op_and_imm_rN(void)
933 env->gregs[PARAM2] &= PARAM1;
937 void OPPROTO op_or_imm_rN(void)
939 env->gregs[PARAM2] |= PARAM1;
943 void OPPROTO op_xor_imm_rN(void)
945 env->gregs[PARAM2] ^= PARAM1;
949 void OPPROTO op_dt_rN(void)
951 cond_t((--env->gregs[PARAM1]) == 0);
955 void OPPROTO op_tst_imm_rN(void)
957 cond_t((env->gregs[PARAM2] & PARAM1) == 0);
961 void OPPROTO op_movl_T0_T1(void)
967 void OPPROTO op_movl_fpul_FT0(void)
969 FT0 = *(float32 *)&env->fpul;
973 void OPPROTO op_movl_FT0_fpul(void)
975 *(float32 *)&env->fpul = FT0;
979 void OPPROTO op_movl_imm_PC(void)
985 void OPPROTO op_jT(void)
992 void OPPROTO op_jdelayed(void)
994 if (env->flags & DELAY_SLOT_TRUE) {
995 env->flags &= ~DELAY_SLOT_TRUE;
1001 void OPPROTO op_movl_delayed_pc_PC(void)
1003 env->pc = env->delayed_pc;
1007 void OPPROTO op_addl_GBR_T0(void)
1013 void OPPROTO op_and_imm_T0(void)
1019 void OPPROTO op_or_imm_T0(void)
1025 void OPPROTO op_xor_imm_T0(void)
1031 void OPPROTO op_tst_imm_T0(void)
1033 cond_t((T0 & PARAM1) == 0);
1037 void OPPROTO op_raise_illegal_instruction(void)
1039 env->exception_index = 0x180;
1040 do_raise_exception();
1044 void OPPROTO op_raise_slot_illegal_instruction(void)
1046 env->exception_index = 0x1a0;
1047 do_raise_exception();
1051 void OPPROTO op_debug(void)
1053 env->exception_index = EXCP_DEBUG;
1057 void OPPROTO op_sleep(void)
1060 env->exception_index = EXCP_HLT;
1064 /* Load and store */
1065 #define MEMSUFFIX _raw
1068 #if !defined(CONFIG_USER_ONLY)
1069 #define MEMSUFFIX _user
1073 #define MEMSUFFIX _kernel