Use lookup table for PCI class descriptions.
[qemu/mini2440.git] / target-sh4 / op.c
blobdbab658db7dff97c5747f76d842d6106b39d7970
1 /*
2 * SH4 emulation
3 *
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
20 #include "exec.h"
22 static inline void set_flag(uint32_t flag)
24 env->flags |= flag;
27 static inline void clr_flag(uint32_t flag)
29 env->flags &= ~flag;
32 static inline void set_t(void)
34 env->sr |= SR_T;
37 static inline void clr_t(void)
39 env->sr &= ~SR_T;
42 static inline void cond_t(int cond)
44 if (cond)
45 set_t();
46 else
47 clr_t();
50 void OPPROTO op_movl_imm_T0(void)
52 T0 = (uint32_t) PARAM1;
53 RETURN();
56 void OPPROTO op_movl_imm_T1(void)
58 T0 = (uint32_t) PARAM1;
59 RETURN();
62 void OPPROTO op_movl_imm_T2(void)
64 T0 = (uint32_t) PARAM1;
65 RETURN();
68 void OPPROTO op_cmp_eq_imm_T0(void)
70 cond_t((int32_t) T0 == (int32_t) PARAM1);
71 RETURN();
74 void OPPROTO op_cmd_eq_T0_T1(void)
76 cond_t(T0 == T1);
77 RETURN();
80 void OPPROTO op_cmd_hs_T0_T1(void)
82 cond_t((uint32_t) T0 <= (uint32_t) T1);
83 RETURN();
86 void OPPROTO op_cmd_ge_T0_T1(void)
88 cond_t((int32_t) T0 <= (int32_t) T1);
89 RETURN();
92 void OPPROTO op_cmd_hi_T0_T1(void)
94 cond_t((uint32_t) T0 < (uint32_t) T1);
95 RETURN();
98 void OPPROTO op_cmd_gt_T0_T1(void)
100 cond_t((int32_t) T0 < (int32_t) T1);
101 RETURN();
104 void OPPROTO op_not_T0(void)
106 T0 = ~T0;
107 RETURN();
110 void OPPROTO op_bf_s(void)
112 T2 = ~env->sr;
113 env->delayed_pc = PARAM1;
114 set_flag(DELAY_SLOT_CONDITIONAL);
115 RETURN();
118 void OPPROTO op_bt_s(void)
120 T2 = env->sr;
121 env->delayed_pc = PARAM1;
122 set_flag(DELAY_SLOT_CONDITIONAL);
123 RETURN();
126 void OPPROTO op_bra(void)
128 env->delayed_pc = PARAM1;
129 set_flag(DELAY_SLOT);
130 RETURN();
133 void OPPROTO op_braf_T0(void)
135 env->delayed_pc = PARAM1 + T0;
136 set_flag(DELAY_SLOT);
137 RETURN();
140 void OPPROTO op_bsr(void)
142 env->pr = PARAM1;
143 env->delayed_pc = PARAM2;
144 set_flag(DELAY_SLOT);
145 RETURN();
148 void OPPROTO op_bsrf_T0(void)
150 env->pr = PARAM1;
151 env->delayed_pc = PARAM1 + T0;
152 set_flag(DELAY_SLOT);
153 RETURN();
156 void OPPROTO op_jsr_T0(void)
158 env->pr = PARAM1;
159 env->delayed_pc = T0;
160 set_flag(DELAY_SLOT);
161 RETURN();
164 void OPPROTO op_rts(void)
166 env->delayed_pc = env->pr;
167 set_flag(DELAY_SLOT);
168 RETURN();
171 void OPPROTO op_clr_delay_slot(void)
173 clr_flag(DELAY_SLOT);
174 RETURN();
177 void OPPROTO op_clr_delay_slot_conditional(void)
179 clr_flag(DELAY_SLOT_CONDITIONAL);
180 RETURN();
183 void OPPROTO op_exit_tb(void)
185 EXIT_TB();
186 RETURN();
189 void OPPROTO op_addl_imm_T0(void)
191 T0 += PARAM1;
192 RETURN();
195 void OPPROTO op_addl_imm_T1(void)
197 T1 += PARAM1;
198 RETURN();
201 void OPPROTO op_clrmac(void)
203 env->mach = env->macl = 0;
204 RETURN();
207 void OPPROTO op_clrs(void)
209 env->sr &= ~SR_S;
210 RETURN();
213 void OPPROTO op_clrt(void)
215 env->sr &= ~SR_T;
216 RETURN();
219 void OPPROTO op_sets(void)
221 env->sr |= SR_S;
222 RETURN();
225 void OPPROTO op_sett(void)
227 env->sr |= SR_T;
228 RETURN();
231 void OPPROTO op_rte(void)
233 env->sr = env->ssr;
234 env->delayed_pc = env->spc;
235 set_flag(DELAY_SLOT);
236 RETURN();
239 void OPPROTO op_swapb_T0(void)
241 T0 = (T0 & 0xffff0000) | ((T0 & 0xff) << 8) | ((T0 >> 8) & 0xff);
242 RETURN();
245 void OPPROTO op_swapw_T0(void)
247 T0 = ((T0 & 0xffff) << 16) | ((T0 >> 16) & 0xffff);
248 RETURN();
251 void OPPROTO op_xtrct_T0_T1(void)
253 T1 = ((T0 & 0xffff) << 16) | ((T1 >> 16) & 0xffff);
254 RETURN();
257 void OPPROTO op_addc_T0_T1(void)
259 helper_addc_T0_T1();
260 RETURN();
263 void OPPROTO op_addv_T0_T1(void)
265 helper_addv_T0_T1();
266 RETURN();
269 void OPPROTO op_cmp_eq_T0_T1(void)
271 cond_t(T1 == T0);
272 RETURN();
275 void OPPROTO op_cmp_ge_T0_T1(void)
277 cond_t((int32_t) T1 >= (int32_t) T0);
278 RETURN();
281 void OPPROTO op_cmp_gt_T0_T1(void)
283 cond_t((int32_t) T1 > (int32_t) T0);
284 RETURN();
287 void OPPROTO op_cmp_hi_T0_T1(void)
289 cond_t((uint32_t) T1 > (uint32_t) T0);
290 RETURN();
293 void OPPROTO op_cmp_hs_T0_T1(void)
295 cond_t((uint32_t) T1 >= (uint32_t) T0);
296 RETURN();
299 void OPPROTO op_cmp_str_T0_T1(void)
301 cond_t((T0 & 0x000000ff) == (T1 & 0x000000ff) ||
302 (T0 & 0x0000ff00) == (T1 & 0x0000ff00) ||
303 (T0 & 0x00ff0000) == (T1 & 0x00ff0000) ||
304 (T0 & 0xff000000) == (T1 & 0xff000000));
305 RETURN();
308 void OPPROTO op_tst_T0_T1(void)
310 cond_t((T1 & T0) == 0);
311 RETURN();
314 void OPPROTO op_div0s_T0_T1(void)
316 if (T1 & 0x80000000)
317 env->sr |= SR_Q;
318 else
319 env->sr &= ~SR_Q;
320 if (T0 & 0x80000000)
321 env->sr |= SR_M;
322 else
323 env->sr &= ~SR_M;
324 cond_t((T1 ^ T0) & 0x80000000);
325 RETURN();
328 void OPPROTO op_div0u(void)
330 env->sr &= ~(SR_M | SR_Q | SR_T);
331 RETURN();
334 void OPPROTO op_div1_T0_T1(void)
336 helper_div1_T0_T1();
337 RETURN();
340 void OPPROTO op_dmulsl_T0_T1(void)
342 helper_dmulsl_T0_T1();
343 RETURN();
346 void OPPROTO op_dmulul_T0_T1(void)
348 helper_dmulul_T0_T1();
349 RETURN();
352 void OPPROTO op_macl_T0_T1(void)
354 helper_macl_T0_T1();
355 RETURN();
358 void OPPROTO op_macw_T0_T1(void)
360 helper_macw_T0_T1();
361 RETURN();
364 void OPPROTO op_mull_T0_T1(void)
366 env->macl = (T0 * T1) & 0xffffffff;
367 RETURN();
370 void OPPROTO op_mulsw_T0_T1(void)
372 env->macl = (int32_t) T0 *(int32_t) T1;
373 RETURN();
376 void OPPROTO op_muluw_T0_T1(void)
378 env->macl = (uint32_t) T0 *(uint32_t) T1;
379 RETURN();
382 void OPPROTO op_neg_T0(void)
384 T0 = -T0;
385 RETURN();
388 void OPPROTO op_negc_T0(void)
390 helper_negc_T0();
391 RETURN();
394 void OPPROTO op_shad_T0_T1(void)
396 if ((T0 & 0x80000000) == 0)
397 T1 <<= (T0 & 0x1f);
398 else if ((T0 & 0x1f) == 0)
399 T1 = 0;
400 else
401 T1 = ((int32_t) T1) >> ((~T0 & 0x1f) + 1);
402 RETURN();
405 void OPPROTO op_shld_T0_T1(void)
407 if ((T0 & 0x80000000) == 0)
408 T1 <<= (T0 & 0x1f);
409 else if ((T0 & 0x1f) == 0)
410 T1 = 0;
411 else
412 T1 = ((uint32_t) T1) >> ((~T0 & 0x1f) + 1);
413 RETURN();
416 void OPPROTO op_subc_T0_T1(void)
418 helper_subc_T0_T1();
419 RETURN();
422 void OPPROTO op_subv_T0_T1(void)
424 helper_subv_T0_T1();
425 RETURN();
428 void OPPROTO op_trapa(void)
430 env->tra = PARAM1 * 2;
431 env->exception_index = 0x160;
432 do_raise_exception();
433 RETURN();
436 void OPPROTO op_cmp_pl_T0(void)
438 cond_t((int32_t) T0 > 0);
439 RETURN();
442 void OPPROTO op_cmp_pz_T0(void)
444 cond_t((int32_t) T0 >= 0);
445 RETURN();
448 void OPPROTO op_jmp_T0(void)
450 env->delayed_pc = T0;
451 set_flag(DELAY_SLOT);
452 RETURN();
455 void OPPROTO op_movl_rN_rN(void)
457 env->gregs[PARAM2] = env->gregs[PARAM1];
458 RETURN();
461 void OPPROTO op_ldcl_rMplus_rN_bank(void)
463 env->gregs[PARAM2] = env->gregs[PARAM1];
464 env->gregs[PARAM1] += 4;
465 RETURN();
468 #define LDSTOPS(target,load,store) \
469 void OPPROTO op_##load##_T0_##target (void) \
470 { env ->target = T0; RETURN(); \
472 void OPPROTO op_##store##_##target##_T0 (void) \
473 { T0 = env->target; RETURN(); \
476 LDSTOPS(sr, ldc, stc)
477 LDSTOPS(gbr, ldc, stc)
478 LDSTOPS(vbr, ldc, stc)
479 LDSTOPS(ssr, ldc, stc)
480 LDSTOPS(spc, ldc, stc)
481 LDSTOPS(sgr, ldc, stc)
482 LDSTOPS(dbr, ldc, stc)
483 LDSTOPS(mach, lds, sts)
484 LDSTOPS(macl, lds, sts)
485 LDSTOPS(pr, lds, sts)
487 void OPPROTO op_movt_rN(void)
489 env->gregs[PARAM1] = env->sr & SR_T;
490 RETURN();
493 void OPPROTO op_rotcl_Rn(void)
495 helper_rotcl(&env->gregs[PARAM1]);
496 RETURN();
499 void OPPROTO op_rotcr_Rn(void)
501 helper_rotcr(&env->gregs[PARAM1]);
502 RETURN();
505 void OPPROTO op_rotl_Rn(void)
507 cond_t(env->gregs[PARAM1] & 0x80000000);
508 env->gregs[PARAM1] = (env->gregs[PARAM1] << 1) | (env->sr & SR_T);
509 RETURN();
512 void OPPROTO op_rotr_Rn(void)
514 cond_t(env->gregs[PARAM1] & 1);
515 env->gregs[PARAM1] = (env->gregs[PARAM1] >> 1) |
516 ((env->sr & SR_T) ? 0x80000000 : 0);
517 RETURN();
520 void OPPROTO op_shal_Rn(void)
522 cond_t(env->gregs[PARAM1] & 0x80000000);
523 env->gregs[PARAM1] <<= 1;
524 RETURN();
527 void OPPROTO op_shar_Rn(void)
529 cond_t(env->gregs[PARAM1] & 1);
530 *(int32_t *) & env->gregs[PARAM1] >>= 1;
531 RETURN();
534 void OPPROTO op_shlr_Rn(void)
536 cond_t(env->gregs[PARAM1] & 1);
537 *(uint32_t *) & env->gregs[PARAM1] >>= 1;
538 RETURN();
541 void OPPROTO op_shll2_Rn(void)
543 env->gregs[PARAM1] <<= 2;
544 RETURN();
547 void OPPROTO op_shll8_Rn(void)
549 env->gregs[PARAM1] <<= 8;
550 RETURN();
553 void OPPROTO op_shll16_Rn(void)
555 env->gregs[PARAM1] <<= 16;
556 RETURN();
559 void OPPROTO op_shlr2_Rn(void)
561 *(uint32_t *) & env->gregs[PARAM1] >>= 2;
562 RETURN();
565 void OPPROTO op_shlr8_Rn(void)
567 *(uint32_t *) & env->gregs[PARAM1] >>= 8;
568 RETURN();
571 void OPPROTO op_shlr16_Rn(void)
573 *(uint32_t *) & env->gregs[PARAM1] >>= 16;
574 RETURN();
577 void OPPROTO op_tasb_rN(void)
579 cond_t(*(int8_t *) env->gregs[PARAM1] == 0);
580 *(int8_t *) env->gregs[PARAM1] |= 0x80;
581 RETURN();
584 void OPPROTO op_movl_T0_rN(void)
586 env->gregs[PARAM1] = T0;
587 RETURN();
590 void OPPROTO op_movl_T1_rN(void)
592 env->gregs[PARAM1] = T1;
593 RETURN();
596 void OPPROTO op_movb_rN_T0(void)
598 T0 = (int32_t) (int8_t) (env->gregs[PARAM1] & 0xff);
599 RETURN();
602 void OPPROTO op_movub_rN_T0(void)
604 T0 = env->gregs[PARAM1] & 0xff;
605 RETURN();
608 void OPPROTO op_movw_rN_T0(void)
610 T0 = (int32_t) (int16_t) (env->gregs[PARAM1] & 0xffff);
611 RETURN();
614 void OPPROTO op_movuw_rN_T0(void)
616 T0 = env->gregs[PARAM1] & 0xffff;
617 RETURN();
620 void OPPROTO op_movl_rN_T0(void)
622 T0 = env->gregs[PARAM1];
623 RETURN();
626 void OPPROTO op_movb_rN_T1(void)
628 T1 = (int32_t) (int8_t) (env->gregs[PARAM1] & 0xff);
629 RETURN();
632 void OPPROTO op_movub_rN_T1(void)
634 T1 = env->gregs[PARAM1] & 0xff;
635 RETURN();
638 void OPPROTO op_movw_rN_T1(void)
640 T1 = (int32_t) (int16_t) (env->gregs[PARAM1] & 0xffff);
641 RETURN();
644 void OPPROTO op_movuw_rN_T1(void)
646 T1 = env->gregs[PARAM1] & 0xffff;
647 RETURN();
650 void OPPROTO op_movl_rN_T1(void)
652 T1 = env->gregs[PARAM1];
653 RETURN();
656 void OPPROTO op_movl_imm_rN(void)
658 env->gregs[PARAM2] = PARAM1;
659 RETURN();
662 void OPPROTO op_dec1_rN(void)
664 env->gregs[PARAM1] -= 1;
665 RETURN();
668 void OPPROTO op_dec2_rN(void)
670 env->gregs[PARAM1] -= 2;
671 RETURN();
674 void OPPROTO op_dec4_rN(void)
676 env->gregs[PARAM1] -= 4;
677 RETURN();
680 void OPPROTO op_inc1_rN(void)
682 env->gregs[PARAM1] += 1;
683 RETURN();
686 void OPPROTO op_inc2_rN(void)
688 env->gregs[PARAM1] += 2;
689 RETURN();
692 void OPPROTO op_inc4_rN(void)
694 env->gregs[PARAM1] += 4;
695 RETURN();
698 void OPPROTO op_add_T0_rN(void)
700 env->gregs[PARAM1] += T0;
701 RETURN();
704 void OPPROTO op_sub_T0_rN(void)
706 env->gregs[PARAM1] -= T0;
707 RETURN();
710 void OPPROTO op_and_T0_rN(void)
712 env->gregs[PARAM1] &= T0;
713 RETURN();
716 void OPPROTO op_or_T0_rN(void)
718 env->gregs[PARAM1] |= T0;
719 RETURN();
722 void OPPROTO op_xor_T0_rN(void)
724 env->gregs[PARAM1] ^= T0;
725 RETURN();
728 void OPPROTO op_add_rN_T0(void)
730 T0 += env->gregs[PARAM1];
731 RETURN();
734 void OPPROTO op_add_rN_T1(void)
736 T1 += env->gregs[PARAM1];
737 RETURN();
740 void OPPROTO op_add_imm_rN(void)
742 env->gregs[PARAM2] += PARAM1;
743 RETURN();
746 void OPPROTO op_and_imm_rN(void)
748 env->gregs[PARAM2] &= PARAM1;
749 RETURN();
752 void OPPROTO op_or_imm_rN(void)
754 env->gregs[PARAM2] |= PARAM1;
755 RETURN();
758 void OPPROTO op_xor_imm_rN(void)
760 env->gregs[PARAM2] ^= PARAM1;
761 RETURN();
764 void OPPROTO op_dt_rN(void)
766 cond_t((--env->gregs[PARAM1]) == 0);
767 RETURN();
770 void OPPROTO op_tst_imm_rN(void)
772 cond_t((env->gregs[PARAM2] & PARAM1) == 0);
773 RETURN();
776 void OPPROTO op_movl_T0_T1(void)
778 T1 = T0;
779 RETURN();
782 void OPPROTO op_goto_tb0(void)
784 GOTO_TB(op_goto_tb0, PARAM1, 0);
785 RETURN();
788 void OPPROTO op_goto_tb1(void)
790 GOTO_TB(op_goto_tb1, PARAM1, 1);
791 RETURN();
794 void OPPROTO op_movl_imm_PC(void)
796 env->pc = PARAM1;
797 RETURN();
800 void OPPROTO op_jT(void)
802 if (env->sr & SR_T)
803 GOTO_LABEL_PARAM(1);
804 RETURN();
807 void OPPROTO op_jTT2(void)
809 if (T2 & SR_T)
810 GOTO_LABEL_PARAM(1);
811 RETURN();
814 void OPPROTO op_movl_delayed_pc_PC(void)
816 env->pc = env->delayed_pc;
817 RETURN();
820 void OPPROTO op_addl_GBR_T0(void)
822 T0 += env->gbr;
823 RETURN();
826 void OPPROTO op_and_imm_T0(void)
828 T0 &= PARAM1;
829 RETURN();
832 void OPPROTO op_or_imm_T0(void)
834 T0 |= PARAM1;
835 RETURN();
838 void OPPROTO op_xor_imm_T0(void)
840 T0 ^= PARAM1;
841 RETURN();
844 void OPPROTO op_tst_imm_T0(void)
846 cond_t((T0 & PARAM1) == 0);
847 RETURN();
850 void OPPROTO op_raise_illegal_instruction(void)
852 env->exception_index = 0x180;
853 do_raise_exception();
854 RETURN();
857 void OPPROTO op_raise_slot_illegal_instruction(void)
859 env->exception_index = 0x1a0;
860 do_raise_exception();
861 RETURN();
864 void OPPROTO op_debug(void)
866 env->exception_index = EXCP_DEBUG;
867 cpu_loop_exit();
870 /* Load and store */
871 #define MEMSUFFIX _raw
872 #include "op_mem.c"
873 #undef MEMSUFFIX
874 #if !defined(CONFIG_USER_ONLY)
875 #define MEMSUFFIX _user
876 #include "op_mem.c"
877 #undef MEMSUFFIX
879 #define MEMSUFFIX _kernel
880 #include "op_mem.c"
881 #undef MEMSUFFIX
882 #endif