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