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