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_tasb_rN(void)
597 cond_t((env
->gregs
[PARAM1
] & 0xff) == 0);
598 *(int8_t *) &env
->gregs
[PARAM1
] |= 0x80;
602 void OPPROTO
op_movl_T0_rN(void)
604 env
->gregs
[PARAM1
] = T0
;
608 void OPPROTO
op_movl_T1_rN(void)
610 env
->gregs
[PARAM1
] = T1
;
614 void OPPROTO
op_movb_rN_T0(void)
616 T0
= (int32_t) (int8_t) (env
->gregs
[PARAM1
] & 0xff);
620 void OPPROTO
op_movub_rN_T0(void)
622 T0
= env
->gregs
[PARAM1
] & 0xff;
626 void OPPROTO
op_movw_rN_T0(void)
628 T0
= (int32_t) (int16_t) (env
->gregs
[PARAM1
] & 0xffff);
632 void OPPROTO
op_movuw_rN_T0(void)
634 T0
= env
->gregs
[PARAM1
] & 0xffff;
638 void OPPROTO
op_movl_rN_T0(void)
640 T0
= env
->gregs
[PARAM1
];
644 void OPPROTO
op_movb_rN_T1(void)
646 T1
= (int32_t) (int8_t) (env
->gregs
[PARAM1
] & 0xff);
650 void OPPROTO
op_movub_rN_T1(void)
652 T1
= env
->gregs
[PARAM1
] & 0xff;
656 void OPPROTO
op_movw_rN_T1(void)
658 T1
= (int32_t) (int16_t) (env
->gregs
[PARAM1
] & 0xffff);
662 void OPPROTO
op_movuw_rN_T1(void)
664 T1
= env
->gregs
[PARAM1
] & 0xffff;
668 void OPPROTO
op_movl_rN_T1(void)
670 T1
= env
->gregs
[PARAM1
];
674 void OPPROTO
op_movl_imm_rN(void)
676 env
->gregs
[PARAM2
] = PARAM1
;
680 void OPPROTO
op_fmov_frN_FT0(void)
682 FT0
= env
->fregs
[PARAM1
];
686 void OPPROTO
op_fmov_drN_DT0(void)
690 d
.l
.upper
= *(uint32_t *)&env
->fregs
[PARAM1
];
691 d
.l
.lower
= *(uint32_t *)&env
->fregs
[PARAM1
+ 1];
696 void OPPROTO
op_fmov_frN_FT1(void)
698 FT1
= env
->fregs
[PARAM1
];
702 void OPPROTO
op_fmov_drN_DT1(void)
706 d
.l
.upper
= *(uint32_t *)&env
->fregs
[PARAM1
];
707 d
.l
.lower
= *(uint32_t *)&env
->fregs
[PARAM1
+ 1];
712 void OPPROTO
op_fmov_FT0_frN(void)
714 env
->fregs
[PARAM1
] = FT0
;
718 void OPPROTO
op_fmov_DT0_drN(void)
723 *(uint32_t *)&env
->fregs
[PARAM1
] = d
.l
.upper
;
724 *(uint32_t *)&env
->fregs
[PARAM1
+ 1] = d
.l
.lower
;
728 void OPPROTO
op_fadd_FT(void)
730 FT0
= float32_add(FT0
, FT1
, &env
->fp_status
);
734 void OPPROTO
op_fadd_DT(void)
736 DT0
= float64_add(DT0
, DT1
, &env
->fp_status
);
740 void OPPROTO
op_fsub_FT(void)
742 FT0
= float32_sub(FT0
, FT1
, &env
->fp_status
);
746 void OPPROTO
op_fsub_DT(void)
748 DT0
= float64_sub(DT0
, DT1
, &env
->fp_status
);
752 void OPPROTO
op_fmul_FT(void)
754 FT0
= float32_mul(FT0
, FT1
, &env
->fp_status
);
758 void OPPROTO
op_fmul_DT(void)
760 DT0
= float64_mul(DT0
, DT1
, &env
->fp_status
);
764 void OPPROTO
op_fdiv_FT(void)
766 FT0
= float32_div(FT0
, FT1
, &env
->fp_status
);
770 void OPPROTO
op_fdiv_DT(void)
772 DT0
= float64_div(DT0
, DT1
, &env
->fp_status
);
776 void OPPROTO
op_fcmp_eq_FT(void)
778 cond_t(float32_compare(FT0
, FT1
, &env
->fp_status
) == 0);
782 void OPPROTO
op_fcmp_eq_DT(void)
784 cond_t(float64_compare(DT0
, DT1
, &env
->fp_status
) == 0);
788 void OPPROTO
op_fcmp_gt_FT(void)
790 cond_t(float32_compare(FT0
, FT1
, &env
->fp_status
) == 1);
794 void OPPROTO
op_fcmp_gt_DT(void)
796 cond_t(float64_compare(DT0
, DT1
, &env
->fp_status
) == 1);
800 void OPPROTO
op_float_FT(void)
802 FT0
= int32_to_float32(env
->fpul
, &env
->fp_status
);
806 void OPPROTO
op_float_DT(void)
808 DT0
= int32_to_float64(env
->fpul
, &env
->fp_status
);
812 void OPPROTO
op_ftrc_FT(void)
814 env
->fpul
= float32_to_int32_round_to_zero(FT0
, &env
->fp_status
);
818 void OPPROTO
op_ftrc_DT(void)
820 env
->fpul
= float64_to_int32_round_to_zero(DT0
, &env
->fp_status
);
824 void OPPROTO
op_fneg_frN(void)
826 env
->fregs
[PARAM1
] = float32_chs(env
->fregs
[PARAM1
]);
830 void OPPROTO
op_fabs_FT(void)
832 FT0
= float32_abs(FT0
);
836 void OPPROTO
op_fabs_DT(void)
838 DT0
= float64_abs(DT0
);
842 void OPPROTO
op_fcnvsd_FT_DT(void)
844 DT0
= float32_to_float64(FT0
, &env
->fp_status
);
848 void OPPROTO
op_fcnvds_DT_FT(void)
850 FT0
= float64_to_float32(DT0
, &env
->fp_status
);
854 void OPPROTO
op_fsqrt_FT(void)
856 FT0
= float32_sqrt(FT0
, &env
->fp_status
);
860 void OPPROTO
op_fsqrt_DT(void)
862 DT0
= float64_sqrt(DT0
, &env
->fp_status
);
866 void OPPROTO
op_fmov_T0_frN(void)
868 *(uint32_t *)&env
->fregs
[PARAM1
] = T0
;
872 void OPPROTO
op_dec1_rN(void)
874 env
->gregs
[PARAM1
] -= 1;
878 void OPPROTO
op_dec2_rN(void)
880 env
->gregs
[PARAM1
] -= 2;
884 void OPPROTO
op_dec4_rN(void)
886 env
->gregs
[PARAM1
] -= 4;
890 void OPPROTO
op_dec8_rN(void)
892 env
->gregs
[PARAM1
] -= 8;
896 void OPPROTO
op_inc1_rN(void)
898 env
->gregs
[PARAM1
] += 1;
902 void OPPROTO
op_inc2_rN(void)
904 env
->gregs
[PARAM1
] += 2;
908 void OPPROTO
op_inc4_rN(void)
910 env
->gregs
[PARAM1
] += 4;
914 void OPPROTO
op_inc8_rN(void)
916 env
->gregs
[PARAM1
] += 8;
920 void OPPROTO
op_add_T0_rN(void)
922 env
->gregs
[PARAM1
] += T0
;
926 void OPPROTO
op_sub_T0_rN(void)
928 env
->gregs
[PARAM1
] -= T0
;
932 void OPPROTO
op_and_T0_rN(void)
934 env
->gregs
[PARAM1
] &= T0
;
938 void OPPROTO
op_or_T0_rN(void)
940 env
->gregs
[PARAM1
] |= T0
;
944 void OPPROTO
op_xor_T0_rN(void)
946 env
->gregs
[PARAM1
] ^= T0
;
950 void OPPROTO
op_add_rN_T0(void)
952 T0
+= env
->gregs
[PARAM1
];
956 void OPPROTO
op_add_rN_T1(void)
958 T1
+= env
->gregs
[PARAM1
];
962 void OPPROTO
op_add_imm_rN(void)
964 env
->gregs
[PARAM2
] += PARAM1
;
968 void OPPROTO
op_and_imm_rN(void)
970 env
->gregs
[PARAM2
] &= PARAM1
;
974 void OPPROTO
op_or_imm_rN(void)
976 env
->gregs
[PARAM2
] |= PARAM1
;
980 void OPPROTO
op_xor_imm_rN(void)
982 env
->gregs
[PARAM2
] ^= PARAM1
;
986 void OPPROTO
op_dt_rN(void)
988 cond_t((--env
->gregs
[PARAM1
]) == 0);
992 void OPPROTO
op_tst_imm_rN(void)
994 cond_t((env
->gregs
[PARAM2
] & PARAM1
) == 0);
998 void OPPROTO
op_movl_T0_T1(void)
1004 void OPPROTO
op_movl_fpul_FT0(void)
1006 FT0
= *(float32
*)&env
->fpul
;
1010 void OPPROTO
op_movl_FT0_fpul(void)
1012 *(float32
*)&env
->fpul
= FT0
;
1016 void OPPROTO
op_movl_imm_PC(void)
1022 void OPPROTO
op_jT(void)
1025 GOTO_LABEL_PARAM(1);
1029 void OPPROTO
op_jdelayed(void)
1031 if (env
->flags
& DELAY_SLOT_TRUE
) {
1032 env
->flags
&= ~DELAY_SLOT_TRUE
;
1033 GOTO_LABEL_PARAM(1);
1038 void OPPROTO
op_movl_delayed_pc_PC(void)
1040 env
->pc
= env
->delayed_pc
;
1044 void OPPROTO
op_addl_GBR_T0(void)
1050 void OPPROTO
op_and_imm_T0(void)
1056 void OPPROTO
op_or_imm_T0(void)
1062 void OPPROTO
op_xor_imm_T0(void)
1068 void OPPROTO
op_tst_imm_T0(void)
1070 cond_t((T0
& PARAM1
) == 0);
1074 void OPPROTO
op_raise_illegal_instruction(void)
1076 env
->exception_index
= 0x180;
1077 do_raise_exception();
1081 void OPPROTO
op_raise_slot_illegal_instruction(void)
1083 env
->exception_index
= 0x1a0;
1084 do_raise_exception();
1088 void OPPROTO
op_debug(void)
1090 env
->exception_index
= EXCP_DEBUG
;
1094 /* Load and store */
1095 #define MEMSUFFIX _raw
1098 #if !defined(CONFIG_USER_ONLY)
1099 #define MEMSUFFIX _user
1103 #define MEMSUFFIX _kernel