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 T0
= (uint32_t) PARAM1
;
52 void OPPROTO
op_movl_imm_T2(void)
54 T0
= (uint32_t) PARAM1
;
58 void OPPROTO
op_cmp_eq_imm_T0(void)
60 cond_t((int32_t) T0
== (int32_t) PARAM1
);
64 void OPPROTO
op_cmd_eq_T0_T1(void)
70 void OPPROTO
op_cmd_hs_T0_T1(void)
72 cond_t((uint32_t) T0
<= (uint32_t) T1
);
76 void OPPROTO
op_cmd_ge_T0_T1(void)
78 cond_t((int32_t) T0
<= (int32_t) T1
);
82 void OPPROTO
op_cmd_hi_T0_T1(void)
84 cond_t((uint32_t) T0
< (uint32_t) T1
);
88 void OPPROTO
op_cmd_gt_T0_T1(void)
90 cond_t((int32_t) T0
< (int32_t) T1
);
94 void OPPROTO
op_not_T0(void)
100 void OPPROTO
op_bf_s(void)
102 env
->delayed_pc
= PARAM1
;
103 if (!(env
->sr
& SR_T
)) {
104 env
->flags
|= DELAY_SLOT_TRUE
;
109 void OPPROTO
op_bt_s(void)
111 env
->delayed_pc
= PARAM1
;
112 if (env
->sr
& SR_T
) {
113 env
->flags
|= DELAY_SLOT_TRUE
;
118 void OPPROTO
op_store_flags(void)
120 env
->flags
&= DELAY_SLOT_TRUE
;
121 env
->flags
|= PARAM1
;
125 void OPPROTO
op_bra(void)
127 env
->delayed_pc
= PARAM1
;
131 void OPPROTO
op_braf_T0(void)
133 env
->delayed_pc
= PARAM1
+ T0
;
137 void OPPROTO
op_bsr(void)
140 env
->delayed_pc
= PARAM2
;
144 void OPPROTO
op_bsrf_T0(void)
147 env
->delayed_pc
= PARAM1
+ T0
;
151 void OPPROTO
op_jsr_T0(void)
154 env
->delayed_pc
= T0
;
158 void OPPROTO
op_rts(void)
160 env
->delayed_pc
= env
->pr
;
164 void OPPROTO
op_addl_imm_T0(void)
170 void OPPROTO
op_addl_imm_T1(void)
176 void OPPROTO
op_clrmac(void)
178 env
->mach
= env
->macl
= 0;
182 void OPPROTO
op_clrs(void)
188 void OPPROTO
op_clrt(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_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) T0
*(int32_t) T1
;
362 void OPPROTO
op_muluw_T0_T1(void)
364 env
->macl
= (uint32_t) T0
*(uint32_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)
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 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_float_FT(void)
772 FT0
= int32_to_float32(env
->fpul
, &env
->fp_status
);
776 void OPPROTO
op_float_DT(void)
778 DT0
= int32_to_float64(env
->fpul
, &env
->fp_status
);
782 void OPPROTO
op_ftrc_FT(void)
784 env
->fpul
= float32_to_int32_round_to_zero(FT0
, &env
->fp_status
);
788 void OPPROTO
op_ftrc_DT(void)
790 env
->fpul
= float64_to_int32_round_to_zero(DT0
, &env
->fp_status
);
794 void OPPROTO
op_fmov_T0_frN(void)
796 *(unsigned int *)&env
->fregs
[PARAM1
] = T0
;
800 void OPPROTO
op_dec1_rN(void)
802 env
->gregs
[PARAM1
] -= 1;
806 void OPPROTO
op_dec2_rN(void)
808 env
->gregs
[PARAM1
] -= 2;
812 void OPPROTO
op_dec4_rN(void)
814 env
->gregs
[PARAM1
] -= 4;
818 void OPPROTO
op_dec8_rN(void)
820 env
->gregs
[PARAM1
] -= 8;
824 void OPPROTO
op_inc1_rN(void)
826 env
->gregs
[PARAM1
] += 1;
830 void OPPROTO
op_inc2_rN(void)
832 env
->gregs
[PARAM1
] += 2;
836 void OPPROTO
op_inc4_rN(void)
838 env
->gregs
[PARAM1
] += 4;
842 void OPPROTO
op_inc8_rN(void)
844 env
->gregs
[PARAM1
] += 8;
848 void OPPROTO
op_add_T0_rN(void)
850 env
->gregs
[PARAM1
] += T0
;
854 void OPPROTO
op_sub_T0_rN(void)
856 env
->gregs
[PARAM1
] -= T0
;
860 void OPPROTO
op_and_T0_rN(void)
862 env
->gregs
[PARAM1
] &= T0
;
866 void OPPROTO
op_or_T0_rN(void)
868 env
->gregs
[PARAM1
] |= T0
;
872 void OPPROTO
op_xor_T0_rN(void)
874 env
->gregs
[PARAM1
] ^= T0
;
878 void OPPROTO
op_add_rN_T0(void)
880 T0
+= env
->gregs
[PARAM1
];
884 void OPPROTO
op_add_rN_T1(void)
886 T1
+= env
->gregs
[PARAM1
];
890 void OPPROTO
op_add_imm_rN(void)
892 env
->gregs
[PARAM2
] += PARAM1
;
896 void OPPROTO
op_and_imm_rN(void)
898 env
->gregs
[PARAM2
] &= PARAM1
;
902 void OPPROTO
op_or_imm_rN(void)
904 env
->gregs
[PARAM2
] |= PARAM1
;
908 void OPPROTO
op_xor_imm_rN(void)
910 env
->gregs
[PARAM2
] ^= PARAM1
;
914 void OPPROTO
op_dt_rN(void)
916 cond_t((--env
->gregs
[PARAM1
]) == 0);
920 void OPPROTO
op_tst_imm_rN(void)
922 cond_t((env
->gregs
[PARAM2
] & PARAM1
) == 0);
926 void OPPROTO
op_movl_T0_T1(void)
932 void OPPROTO
op_movl_fpul_FT0(void)
934 FT0
= *(float32
*)&env
->fpul
;
938 void OPPROTO
op_movl_FT0_fpul(void)
940 *(float32
*)&env
->fpul
= FT0
;
944 void OPPROTO
op_movl_imm_PC(void)
950 void OPPROTO
op_jT(void)
957 void OPPROTO
op_jdelayed(void)
959 if (env
->flags
& DELAY_SLOT_TRUE
) {
960 env
->flags
&= ~DELAY_SLOT_TRUE
;
966 void OPPROTO
op_movl_delayed_pc_PC(void)
968 env
->pc
= env
->delayed_pc
;
972 void OPPROTO
op_addl_GBR_T0(void)
978 void OPPROTO
op_and_imm_T0(void)
984 void OPPROTO
op_or_imm_T0(void)
990 void OPPROTO
op_xor_imm_T0(void)
996 void OPPROTO
op_tst_imm_T0(void)
998 cond_t((T0
& PARAM1
) == 0);
1002 void OPPROTO
op_raise_illegal_instruction(void)
1004 env
->exception_index
= 0x180;
1005 do_raise_exception();
1009 void OPPROTO
op_raise_slot_illegal_instruction(void)
1011 env
->exception_index
= 0x1a0;
1012 do_raise_exception();
1016 void OPPROTO
op_debug(void)
1018 env
->exception_index
= EXCP_DEBUG
;
1022 /* Load and store */
1023 #define MEMSUFFIX _raw
1026 #if !defined(CONFIG_USER_ONLY)
1027 #define MEMSUFFIX _user
1031 #define MEMSUFFIX _kernel