]>
git.proxmox.com Git - mirror_qemu.git/blob - target-sh4/op.c
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;
515 void OPPROTO
op_sts_fpscr_T0(void)
517 T0
= env
->fpscr
& 0x003fffff;
521 void OPPROTO
op_movt_rN(void)
523 env
->gregs
[PARAM1
] = env
->sr
& SR_T
;
527 void OPPROTO
op_rotcl_Rn(void)
529 helper_rotcl(&env
->gregs
[PARAM1
]);
533 void OPPROTO
op_rotcr_Rn(void)
535 helper_rotcr(&env
->gregs
[PARAM1
]);
539 void OPPROTO
op_rotl_Rn(void)
541 cond_t(env
->gregs
[PARAM1
] & 0x80000000);
542 env
->gregs
[PARAM1
] = (env
->gregs
[PARAM1
] << 1) | (env
->sr
& SR_T
);
546 void OPPROTO
op_rotr_Rn(void)
548 cond_t(env
->gregs
[PARAM1
] & 1);
549 env
->gregs
[PARAM1
] = (env
->gregs
[PARAM1
] >> 1) |
550 ((env
->sr
& SR_T
) ? 0x80000000 : 0);
554 void OPPROTO
op_shal_Rn(void)
556 cond_t(env
->gregs
[PARAM1
] & 0x80000000);
557 env
->gregs
[PARAM1
] <<= 1;
561 void OPPROTO
op_shar_Rn(void)
563 cond_t(env
->gregs
[PARAM1
] & 1);
564 *(int32_t *) & env
->gregs
[PARAM1
] >>= 1;
568 void OPPROTO
op_shlr_Rn(void)
570 cond_t(env
->gregs
[PARAM1
] & 1);
571 *(uint32_t *) & env
->gregs
[PARAM1
] >>= 1;
575 void OPPROTO
op_shll2_Rn(void)
577 env
->gregs
[PARAM1
] <<= 2;
581 void OPPROTO
op_shll8_Rn(void)
583 env
->gregs
[PARAM1
] <<= 8;
587 void OPPROTO
op_shll16_Rn(void)
589 env
->gregs
[PARAM1
] <<= 16;
593 void OPPROTO
op_shlr2_Rn(void)
595 *(uint32_t *) & env
->gregs
[PARAM1
] >>= 2;
599 void OPPROTO
op_shlr8_Rn(void)
601 *(uint32_t *) & env
->gregs
[PARAM1
] >>= 8;
605 void OPPROTO
op_shlr16_Rn(void)
607 *(uint32_t *) & env
->gregs
[PARAM1
] >>= 16;
611 void OPPROTO
op_tasb_rN(void)
613 cond_t(*(int8_t *) env
->gregs
[PARAM1
] == 0);
614 *(int8_t *) env
->gregs
[PARAM1
] |= 0x80;
618 void OPPROTO
op_movl_T0_rN(void)
620 env
->gregs
[PARAM1
] = T0
;
624 void OPPROTO
op_movl_T1_rN(void)
626 env
->gregs
[PARAM1
] = T1
;
630 void OPPROTO
op_movb_rN_T0(void)
632 T0
= (int32_t) (int8_t) (env
->gregs
[PARAM1
] & 0xff);
636 void OPPROTO
op_movub_rN_T0(void)
638 T0
= env
->gregs
[PARAM1
] & 0xff;
642 void OPPROTO
op_movw_rN_T0(void)
644 T0
= (int32_t) (int16_t) (env
->gregs
[PARAM1
] & 0xffff);
648 void OPPROTO
op_movuw_rN_T0(void)
650 T0
= env
->gregs
[PARAM1
] & 0xffff;
654 void OPPROTO
op_movl_rN_T0(void)
656 T0
= env
->gregs
[PARAM1
];
660 void OPPROTO
op_movb_rN_T1(void)
662 T1
= (int32_t) (int8_t) (env
->gregs
[PARAM1
] & 0xff);
666 void OPPROTO
op_movub_rN_T1(void)
668 T1
= env
->gregs
[PARAM1
] & 0xff;
672 void OPPROTO
op_movw_rN_T1(void)
674 T1
= (int32_t) (int16_t) (env
->gregs
[PARAM1
] & 0xffff);
678 void OPPROTO
op_movuw_rN_T1(void)
680 T1
= env
->gregs
[PARAM1
] & 0xffff;
684 void OPPROTO
op_movl_rN_T1(void)
686 T1
= env
->gregs
[PARAM1
];
690 void OPPROTO
op_movl_imm_rN(void)
692 env
->gregs
[PARAM2
] = PARAM1
;
696 void OPPROTO
op_fmov_frN_FT0(void)
698 FT0
= *(float32
*)&env
->fregs
[PARAM1
];
702 void OPPROTO
op_fmov_drN_DT0(void)
704 DT0
= *(float64
*)&env
->fregs
[PARAM1
];
708 void OPPROTO
op_fmov_FT0_frN(void)
710 *(float32
*)&env
->fregs
[PARAM1
] = FT0
;
714 void OPPROTO
op_fmov_DT0_drN(void)
716 *(float64
*)&env
->fregs
[PARAM1
] = DT0
;
720 void OPPROTO
op_dec1_rN(void)
722 env
->gregs
[PARAM1
] -= 1;
726 void OPPROTO
op_dec2_rN(void)
728 env
->gregs
[PARAM1
] -= 2;
732 void OPPROTO
op_dec4_rN(void)
734 env
->gregs
[PARAM1
] -= 4;
738 void OPPROTO
op_dec8_rN(void)
740 env
->gregs
[PARAM1
] -= 8;
744 void OPPROTO
op_inc1_rN(void)
746 env
->gregs
[PARAM1
] += 1;
750 void OPPROTO
op_inc2_rN(void)
752 env
->gregs
[PARAM1
] += 2;
756 void OPPROTO
op_inc4_rN(void)
758 env
->gregs
[PARAM1
] += 4;
762 void OPPROTO
op_inc8_rN(void)
764 env
->gregs
[PARAM1
] += 8;
768 void OPPROTO
op_add_T0_rN(void)
770 env
->gregs
[PARAM1
] += T0
;
774 void OPPROTO
op_sub_T0_rN(void)
776 env
->gregs
[PARAM1
] -= T0
;
780 void OPPROTO
op_and_T0_rN(void)
782 env
->gregs
[PARAM1
] &= T0
;
786 void OPPROTO
op_or_T0_rN(void)
788 env
->gregs
[PARAM1
] |= T0
;
792 void OPPROTO
op_xor_T0_rN(void)
794 env
->gregs
[PARAM1
] ^= T0
;
798 void OPPROTO
op_add_rN_T0(void)
800 T0
+= env
->gregs
[PARAM1
];
804 void OPPROTO
op_add_rN_T1(void)
806 T1
+= env
->gregs
[PARAM1
];
810 void OPPROTO
op_add_imm_rN(void)
812 env
->gregs
[PARAM2
] += PARAM1
;
816 void OPPROTO
op_and_imm_rN(void)
818 env
->gregs
[PARAM2
] &= PARAM1
;
822 void OPPROTO
op_or_imm_rN(void)
824 env
->gregs
[PARAM2
] |= PARAM1
;
828 void OPPROTO
op_xor_imm_rN(void)
830 env
->gregs
[PARAM2
] ^= PARAM1
;
834 void OPPROTO
op_dt_rN(void)
836 cond_t((--env
->gregs
[PARAM1
]) == 0);
840 void OPPROTO
op_tst_imm_rN(void)
842 cond_t((env
->gregs
[PARAM2
] & PARAM1
) == 0);
846 void OPPROTO
op_movl_T0_T1(void)
852 void OPPROTO
op_movl_fpul_FT0(void)
854 FT0
= *(float32
*)&env
->fpul
;
858 void OPPROTO
op_movl_FT0_fpul(void)
860 *(float32
*)&env
->fpul
= FT0
;
864 void OPPROTO
op_goto_tb0(void)
866 GOTO_TB(op_goto_tb0
, PARAM1
, 0);
870 void OPPROTO
op_goto_tb1(void)
872 GOTO_TB(op_goto_tb1
, PARAM1
, 1);
876 void OPPROTO
op_movl_imm_PC(void)
882 void OPPROTO
op_jT(void)
889 void OPPROTO
op_jdelayed(void)
893 env
->flags
&= ~(DELAY_SLOT
| DELAY_SLOT_CONDITIONAL
);
894 if (flags
& DELAY_SLOT
)
899 void OPPROTO
op_movl_delayed_pc_PC(void)
901 env
->pc
= env
->delayed_pc
;
905 void OPPROTO
op_addl_GBR_T0(void)
911 void OPPROTO
op_and_imm_T0(void)
917 void OPPROTO
op_or_imm_T0(void)
923 void OPPROTO
op_xor_imm_T0(void)
929 void OPPROTO
op_tst_imm_T0(void)
931 cond_t((T0
& PARAM1
) == 0);
935 void OPPROTO
op_raise_illegal_instruction(void)
937 env
->exception_index
= 0x180;
938 do_raise_exception();
942 void OPPROTO
op_raise_slot_illegal_instruction(void)
944 env
->exception_index
= 0x1a0;
945 do_raise_exception();
949 void OPPROTO
op_debug(void)
951 env
->exception_index
= EXCP_DEBUG
;
956 #define MEMSUFFIX _raw
959 #if !defined(CONFIG_USER_ONLY)
960 #define MEMSUFFIX _user
964 #define MEMSUFFIX _kernel