ARMv7 support.
[qemu/mini2440.git] / target-alpha / op.c
blobda93e7cdfb50f2a7bbca14b5b568d54787c33c61
1 /*
2 * Alpha emulation cpu micro-operations for qemu.
4 * Copyright (c) 2007 Jocelyn Mayer
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
21 #define DEBUG_OP
23 #include "config.h"
24 #include "exec.h"
25 #include "host-utils.h"
27 #include "op_helper.h"
29 #define REG 0
30 #include "op_template.h"
32 #define REG 1
33 #include "op_template.h"
35 #define REG 2
36 #include "op_template.h"
38 #define REG 3
39 #include "op_template.h"
41 #define REG 4
42 #include "op_template.h"
44 #define REG 5
45 #include "op_template.h"
47 #define REG 6
48 #include "op_template.h"
50 #define REG 7
51 #include "op_template.h"
53 #define REG 8
54 #include "op_template.h"
56 #define REG 9
57 #include "op_template.h"
59 #define REG 10
60 #include "op_template.h"
62 #define REG 11
63 #include "op_template.h"
65 #define REG 12
66 #include "op_template.h"
68 #define REG 13
69 #include "op_template.h"
71 #define REG 14
72 #include "op_template.h"
74 #define REG 15
75 #include "op_template.h"
77 #define REG 16
78 #include "op_template.h"
80 #define REG 17
81 #include "op_template.h"
83 #define REG 18
84 #include "op_template.h"
86 #define REG 19
87 #include "op_template.h"
89 #define REG 20
90 #include "op_template.h"
92 #define REG 21
93 #include "op_template.h"
95 #define REG 22
96 #include "op_template.h"
98 #define REG 23
99 #include "op_template.h"
101 #define REG 24
102 #include "op_template.h"
104 #define REG 25
105 #include "op_template.h"
107 #define REG 26
108 #include "op_template.h"
110 #define REG 27
111 #include "op_template.h"
113 #define REG 28
114 #include "op_template.h"
116 #define REG 29
117 #include "op_template.h"
119 #define REG 30
120 #include "op_template.h"
122 #define REG 31
123 #include "op_template.h"
125 /* Debug stuff */
126 void OPPROTO op_no_op (void)
128 #if !defined (DEBUG_OP)
129 __asm__ __volatile__("nop" : : : "memory");
130 #endif
131 RETURN();
134 void OPPROTO op_tb_flush (void)
136 helper_tb_flush();
137 RETURN();
140 /* Load and stores */
141 #define MEMSUFFIX _raw
142 #include "op_mem.h"
143 #if !defined(CONFIG_USER_ONLY)
144 #define MEMSUFFIX _kernel
145 #include "op_mem.h"
146 #define MEMSUFFIX _executive
147 #include "op_mem.h"
148 #define MEMSUFFIX _supervisor
149 #include "op_mem.h"
150 #define MEMSUFFIX _user
151 #include "op_mem.h"
152 /* This is used for pal modes */
153 #define MEMSUFFIX _data
154 #include "op_mem.h"
155 #endif
157 /* Special operation for load and store */
158 void OPPROTO op_n7 (void)
160 T0 &= ~(uint64_t)0x7;
161 RETURN();
164 /* Misc */
165 void OPPROTO op_excp (void)
167 helper_excp(PARAM(1), PARAM(2));
168 RETURN();
171 void OPPROTO op_load_amask (void)
173 helper_amask();
174 RETURN();
177 void OPPROTO op_load_pcc (void)
179 helper_load_pcc();
180 RETURN();
183 void OPPROTO op_load_implver (void)
185 helper_load_implver();
186 RETURN();
189 void OPPROTO op_load_fpcr (void)
191 helper_load_fpcr();
192 RETURN();
195 void OPPROTO op_store_fpcr (void)
197 helper_store_fpcr();
198 RETURN();
201 void OPPROTO op_load_irf (void)
203 helper_load_irf();
204 RETURN();
207 void OPPROTO op_set_irf (void)
209 helper_set_irf();
210 RETURN();
213 void OPPROTO op_clear_irf (void)
215 helper_clear_irf();
216 RETURN();
219 void OPPROTO op_exit_tb (void)
221 EXIT_TB();
224 /* Arithmetic */
225 void OPPROTO op_addq (void)
227 T0 += T1;
228 RETURN();
231 void OPPROTO op_addqv (void)
233 helper_addqv();
234 RETURN();
237 void OPPROTO op_addl (void)
239 T0 = (int64_t)((int32_t)(T0 + T1));
240 RETURN();
243 void OPPROTO op_addlv (void)
245 helper_addlv();
246 RETURN();
249 void OPPROTO op_subq (void)
251 T0 -= T1;
252 RETURN();
255 void OPPROTO op_subqv (void)
257 helper_subqv();
258 RETURN();
261 void OPPROTO op_subl (void)
263 T0 = (int64_t)((int32_t)(T0 - T1));
264 RETURN();
267 void OPPROTO op_sublv (void)
269 helper_sublv();
270 RETURN();
273 void OPPROTO op_s4 (void)
275 T0 <<= 2;
276 RETURN();
279 void OPPROTO op_s8 (void)
281 T0 <<= 3;
282 RETURN();
285 void OPPROTO op_mull (void)
287 T0 = (int64_t)((int32_t)T0 * (int32_t)T1);
288 RETURN();
291 void OPPROTO op_mullv (void)
293 helper_mullv();
294 RETURN();
297 void OPPROTO op_mulq (void)
299 T0 = (int64_t)T0 * (int64_t)T1;
300 RETURN();
303 void OPPROTO op_mulqv (void)
305 helper_mulqv();
306 RETURN();
309 void OPPROTO op_umulh (void)
311 uint64_t tl, th;
313 mulu64(&tl, &th, T0, T1);
314 T0 = th;
315 RETURN();
318 /* Logical */
319 void OPPROTO op_and (void)
321 T0 &= T1;
322 RETURN();
325 void OPPROTO op_bic (void)
327 T0 &= ~T1;
328 RETURN();
331 void OPPROTO op_bis (void)
333 T0 |= T1;
334 RETURN();
337 void OPPROTO op_eqv (void)
339 T0 ^= ~T1;
340 RETURN();
343 void OPPROTO op_ornot (void)
345 T0 |= ~T1;
346 RETURN();
349 void OPPROTO op_xor (void)
351 T0 ^= T1;
352 RETURN();
355 void OPPROTO op_sll (void)
357 T0 <<= T1;
358 RETURN();
361 void OPPROTO op_srl (void)
363 T0 >>= T1;
364 RETURN();
367 void OPPROTO op_sra (void)
369 T0 = (int64_t)T0 >> T1;
370 RETURN();
373 void OPPROTO op_sextb (void)
375 T0 = (int64_t)((int8_t)T0);
376 RETURN();
379 void OPPROTO op_sextw (void)
381 T0 = (int64_t)((int16_t)T0);
382 RETURN();
386 void OPPROTO op_ctpop (void)
388 helper_ctpop();
389 RETURN();
392 void OPPROTO op_ctlz (void)
394 helper_ctlz();
395 RETURN();
398 void OPPROTO op_cttz (void)
400 helper_cttz();
401 RETURN();
404 void OPPROTO op_mskbl (void)
406 helper_mskbl();
407 RETURN();
410 void OPPROTO op_extbl (void)
412 helper_extbl();
413 RETURN();
416 void OPPROTO op_insbl (void)
418 helper_insbl();
419 RETURN();
422 void OPPROTO op_mskwl (void)
424 helper_mskwl();
425 RETURN();
428 void OPPROTO op_extwl (void)
430 helper_extwl();
431 RETURN();
434 void OPPROTO op_inswl (void)
436 helper_inswl();
437 RETURN();
440 void OPPROTO op_mskll (void)
442 helper_mskll();
443 RETURN();
446 void OPPROTO op_extll (void)
448 helper_extll();
449 RETURN();
452 void OPPROTO op_insll (void)
454 helper_insll();
455 RETURN();
458 void OPPROTO op_zap (void)
460 helper_zap();
461 RETURN();
464 void OPPROTO op_zapnot (void)
466 helper_zapnot();
467 RETURN();
470 void OPPROTO op_mskql (void)
472 helper_mskql();
473 RETURN();
476 void OPPROTO op_extql (void)
478 helper_extql();
479 RETURN();
482 void OPPROTO op_insql (void)
484 helper_insql();
485 RETURN();
488 void OPPROTO op_mskwh (void)
490 helper_mskwh();
491 RETURN();
494 void OPPROTO op_inswh (void)
496 helper_inswh();
497 RETURN();
500 void OPPROTO op_extwh (void)
502 helper_extwh();
503 RETURN();
506 void OPPROTO op_msklh (void)
508 helper_msklh();
509 RETURN();
512 void OPPROTO op_inslh (void)
514 helper_inslh();
515 RETURN();
518 void OPPROTO op_extlh (void)
520 helper_extlh();
521 RETURN();
524 void OPPROTO op_mskqh (void)
526 helper_mskqh();
527 RETURN();
530 void OPPROTO op_insqh (void)
532 helper_insqh();
533 RETURN();
536 void OPPROTO op_extqh (void)
538 helper_extqh();
539 RETURN();
542 /* Tests */
543 void OPPROTO op_cmpult (void)
545 if (T0 < T1)
546 T0 = 1;
547 else
548 T0 = 0;
549 RETURN();
552 void OPPROTO op_cmpule (void)
554 if (T0 <= T1)
555 T0 = 1;
556 else
557 T0 = 0;
558 RETURN();
561 void OPPROTO op_cmpeq (void)
563 if (T0 == T1)
564 T0 = 1;
565 else
566 T0 = 0;
567 RETURN();
570 void OPPROTO op_cmplt (void)
572 if ((int64_t)T0 < (int64_t)T1)
573 T0 = 1;
574 else
575 T0 = 0;
576 RETURN();
579 void OPPROTO op_cmple (void)
581 if ((int64_t)T0 <= (int64_t)T1)
582 T0 = 1;
583 else
584 T0 = 0;
585 RETURN();
588 void OPPROTO op_cmpbge (void)
590 helper_cmpbge();
591 RETURN();
594 void OPPROTO op_cmpeqz (void)
596 if (T0 == 0)
597 T0 = 1;
598 else
599 T0 = 0;
600 RETURN();
603 void OPPROTO op_cmpnez (void)
605 if (T0 != 0)
606 T0 = 1;
607 else
608 T0 = 0;
609 RETURN();
612 void OPPROTO op_cmpltz (void)
614 if ((int64_t)T0 < 0)
615 T0 = 1;
616 else
617 T0 = 0;
618 RETURN();
621 void OPPROTO op_cmplez (void)
623 if ((int64_t)T0 <= 0)
624 T0 = 1;
625 else
626 T0 = 0;
627 RETURN();
630 void OPPROTO op_cmpgtz (void)
632 if ((int64_t)T0 > 0)
633 T0 = 1;
634 else
635 T0 = 0;
636 RETURN();
639 void OPPROTO op_cmpgez (void)
641 if ((int64_t)T0 >= 0)
642 T0 = 1;
643 else
644 T0 = 0;
645 RETURN();
648 void OPPROTO op_cmplbs (void)
650 T0 &= 1;
651 RETURN();
654 void OPPROTO op_cmplbc (void)
656 T0 = (~T0) & 1;
657 RETURN();
660 /* Branches */
661 void OPPROTO op_branch (void)
663 env->pc = T0 & ~3;
664 RETURN();
667 void OPPROTO op_addq1 (void)
669 T1 += T0;
670 RETURN();
673 #if 0 // Qemu does not know how to do this...
674 void OPPROTO op_bcond (void)
676 if (T0)
677 env->pc = T1 & ~3;
678 else
679 env->pc = PARAM(1);
680 RETURN();
682 #else
683 void OPPROTO op_bcond (void)
685 if (T0)
686 env->pc = T1 & ~3;
687 else
688 env->pc = ((uint64_t)PARAM(1) << 32) | (uint64_t)PARAM(2);
689 RETURN();
691 #endif
693 #if 0 // Qemu does not know how to do this...
694 void OPPROTO op_update_pc (void)
696 env->pc = PARAM(1);
697 RETURN();
699 #else
700 void OPPROTO op_update_pc (void)
702 env->pc = ((uint64_t)PARAM(1) << 32) | (uint64_t)PARAM(2);
703 RETURN();
705 #endif
707 /* Optimization for 32 bits hosts architectures */
708 void OPPROTO op_update_pc32 (void)
710 env->pc = (uint64_t)PARAM(1);
711 RETURN();
714 /* IEEE floating point arithmetic */
715 /* S floating (single) */
716 void OPPROTO op_adds (void)
718 FT0 = float32_add(FT0, FT1, &FP_STATUS);
719 RETURN();
722 void OPPROTO op_subs (void)
724 FT0 = float32_sub(FT0, FT1, &FP_STATUS);
725 RETURN();
728 void OPPROTO op_muls (void)
730 FT0 = float32_mul(FT0, FT1, &FP_STATUS);
731 RETURN();
734 void OPPROTO op_divs (void)
736 FT0 = float32_div(FT0, FT1, &FP_STATUS);
737 RETURN();
740 void OPPROTO op_sqrts (void)
742 helper_sqrts();
743 RETURN();
746 void OPPROTO op_cpys (void)
748 helper_cpys();
749 RETURN();
752 void OPPROTO op_cpysn (void)
754 helper_cpysn();
755 RETURN();
758 void OPPROTO op_cpyse (void)
760 helper_cpyse();
761 RETURN();
764 void OPPROTO op_itofs (void)
766 helper_itofs();
767 RETURN();
770 void OPPROTO op_ftois (void)
772 helper_ftois();
773 RETURN();
776 /* T floating (double) */
777 void OPPROTO op_addt (void)
779 FT0 = float64_add(FT0, FT1, &FP_STATUS);
780 RETURN();
783 void OPPROTO op_subt (void)
785 FT0 = float64_sub(FT0, FT1, &FP_STATUS);
786 RETURN();
789 void OPPROTO op_mult (void)
791 FT0 = float64_mul(FT0, FT1, &FP_STATUS);
792 RETURN();
795 void OPPROTO op_divt (void)
797 FT0 = float64_div(FT0, FT1, &FP_STATUS);
798 RETURN();
801 void OPPROTO op_sqrtt (void)
803 helper_sqrtt();
804 RETURN();
807 void OPPROTO op_cmptun (void)
809 helper_cmptun();
810 RETURN();
813 void OPPROTO op_cmpteq (void)
815 helper_cmpteq();
816 RETURN();
819 void OPPROTO op_cmptle (void)
821 helper_cmptle();
822 RETURN();
825 void OPPROTO op_cmptlt (void)
827 helper_cmptlt();
828 RETURN();
831 void OPPROTO op_itoft (void)
833 helper_itoft();
834 RETURN();
837 void OPPROTO op_ftoit (void)
839 helper_ftoit();
840 RETURN();
843 /* VAX floating point arithmetic */
844 /* F floating */
845 void OPPROTO op_addf (void)
847 helper_addf();
848 RETURN();
851 void OPPROTO op_subf (void)
853 helper_subf();
854 RETURN();
857 void OPPROTO op_mulf (void)
859 helper_mulf();
860 RETURN();
863 void OPPROTO op_divf (void)
865 helper_divf();
866 RETURN();
869 void OPPROTO op_sqrtf (void)
871 helper_sqrtf();
872 RETURN();
875 void OPPROTO op_cmpfeq (void)
877 helper_cmpfeq();
878 RETURN();
881 void OPPROTO op_cmpfne (void)
883 helper_cmpfne();
884 RETURN();
887 void OPPROTO op_cmpflt (void)
889 helper_cmpflt();
890 RETURN();
893 void OPPROTO op_cmpfle (void)
895 helper_cmpfle();
896 RETURN();
899 void OPPROTO op_cmpfgt (void)
901 helper_cmpfgt();
902 RETURN();
905 void OPPROTO op_cmpfge (void)
907 helper_cmpfge();
908 RETURN();
911 void OPPROTO op_itoff (void)
913 helper_itoff();
914 RETURN();
917 /* G floating */
918 void OPPROTO op_addg (void)
920 helper_addg();
921 RETURN();
924 void OPPROTO op_subg (void)
926 helper_subg();
927 RETURN();
930 void OPPROTO op_mulg (void)
932 helper_mulg();
933 RETURN();
936 void OPPROTO op_divg (void)
938 helper_divg();
939 RETURN();
942 void OPPROTO op_sqrtg (void)
944 helper_sqrtg();
945 RETURN();
948 void OPPROTO op_cmpgeq (void)
950 helper_cmpgeq();
951 RETURN();
954 void OPPROTO op_cmpglt (void)
956 helper_cmpglt();
957 RETURN();
960 void OPPROTO op_cmpgle (void)
962 helper_cmpgle();
963 RETURN();
966 /* Floating point format conversion */
967 void OPPROTO op_cvtst (void)
969 FT0 = (float)FT0;
970 RETURN();
973 void OPPROTO op_cvtqs (void)
975 helper_cvtqs();
976 RETURN();
979 void OPPROTO op_cvtts (void)
981 FT0 = (float)FT0;
982 RETURN();
985 void OPPROTO op_cvttq (void)
987 helper_cvttq();
988 RETURN();
991 void OPPROTO op_cvtqt (void)
993 helper_cvtqt();
994 RETURN();
997 void OPPROTO op_cvtqf (void)
999 helper_cvtqf();
1000 RETURN();
1003 void OPPROTO op_cvtgf (void)
1005 helper_cvtgf();
1006 RETURN();
1009 void OPPROTO op_cvtgd (void)
1011 helper_cvtgd();
1012 RETURN();
1015 void OPPROTO op_cvtgq (void)
1017 helper_cvtgq();
1018 RETURN();
1021 void OPPROTO op_cvtqg (void)
1023 helper_cvtqg();
1024 RETURN();
1027 void OPPROTO op_cvtdg (void)
1029 helper_cvtdg();
1030 RETURN();
1033 void OPPROTO op_cvtlq (void)
1035 helper_cvtlq();
1036 RETURN();
1039 void OPPROTO op_cvtql (void)
1041 helper_cvtql();
1042 RETURN();
1045 void OPPROTO op_cvtqlv (void)
1047 helper_cvtqlv();
1048 RETURN();
1051 void OPPROTO op_cvtqlsv (void)
1053 helper_cvtqlsv();
1054 RETURN();
1057 /* PALcode support special instructions */
1058 #if !defined (CONFIG_USER_ONLY)
1059 void OPPROTO op_hw_rei (void)
1061 env->pc = env->ipr[IPR_EXC_ADDR] & ~3;
1062 env->ipr[IPR_EXC_ADDR] = env->ipr[IPR_EXC_ADDR] & 1;
1063 /* XXX: re-enable interrupts and memory mapping */
1064 RETURN();
1067 void OPPROTO op_hw_ret (void)
1069 env->pc = T0 & ~3;
1070 env->ipr[IPR_EXC_ADDR] = T0 & 1;
1071 /* XXX: re-enable interrupts and memory mapping */
1072 RETURN();
1075 void OPPROTO op_mfpr (void)
1077 helper_mfpr(PARAM(1));
1078 RETURN();
1081 void OPPROTO op_mtpr (void)
1083 helper_mtpr(PARAM(1));
1084 RETURN();
1087 void OPPROTO op_set_alt_mode (void)
1089 env->saved_mode = env->ps & 0xC;
1090 env->ps = (env->ps & ~0xC) | (env->ipr[IPR_ALT_MODE] & 0xC);
1091 RETURN();
1094 void OPPROTO op_restore_mode (void)
1096 env->ps = (env->ps & ~0xC) | env->saved_mode;
1097 RETURN();
1100 void OPPROTO op_ld_phys_to_virt (void)
1102 helper_ld_phys_to_virt();
1103 RETURN();
1106 void OPPROTO op_st_phys_to_virt (void)
1108 helper_st_phys_to_virt();
1109 RETURN();
1111 #endif /* !defined (CONFIG_USER_ONLY) */