Clear the upper 32 bits of addr_reg in TARGET_LONG_BITS == 32 case
[qemu/mini2440.git] / target-alpha / op.c
blob957c6516059cf888bcc2e62ba83b0203e4bccf94
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 /* Arithmetic */
220 void OPPROTO op_addq (void)
222 T0 += T1;
223 RETURN();
226 void OPPROTO op_addqv (void)
228 helper_addqv();
229 RETURN();
232 void OPPROTO op_addl (void)
234 T0 = (int64_t)((int32_t)(T0 + T1));
235 RETURN();
238 void OPPROTO op_addlv (void)
240 helper_addlv();
241 RETURN();
244 void OPPROTO op_subq (void)
246 T0 -= T1;
247 RETURN();
250 void OPPROTO op_subqv (void)
252 helper_subqv();
253 RETURN();
256 void OPPROTO op_subl (void)
258 T0 = (int64_t)((int32_t)(T0 - T1));
259 RETURN();
262 void OPPROTO op_sublv (void)
264 helper_sublv();
265 RETURN();
268 void OPPROTO op_s4 (void)
270 T0 <<= 2;
271 RETURN();
274 void OPPROTO op_s8 (void)
276 T0 <<= 3;
277 RETURN();
280 void OPPROTO op_mull (void)
282 T0 = (int64_t)((int32_t)T0 * (int32_t)T1);
283 RETURN();
286 void OPPROTO op_mullv (void)
288 helper_mullv();
289 RETURN();
292 void OPPROTO op_mulq (void)
294 T0 = (int64_t)T0 * (int64_t)T1;
295 RETURN();
298 void OPPROTO op_mulqv (void)
300 helper_mulqv();
301 RETURN();
304 void OPPROTO op_umulh (void)
306 uint64_t tl, th;
308 mulu64(&tl, &th, T0, T1);
309 T0 = th;
310 RETURN();
313 /* Logical */
314 void OPPROTO op_and (void)
316 T0 &= T1;
317 RETURN();
320 void OPPROTO op_bic (void)
322 T0 &= ~T1;
323 RETURN();
326 void OPPROTO op_bis (void)
328 T0 |= T1;
329 RETURN();
332 void OPPROTO op_eqv (void)
334 T0 ^= ~T1;
335 RETURN();
338 void OPPROTO op_ornot (void)
340 T0 |= ~T1;
341 RETURN();
344 void OPPROTO op_xor (void)
346 T0 ^= T1;
347 RETURN();
350 void OPPROTO op_sll (void)
352 T0 <<= T1;
353 RETURN();
356 void OPPROTO op_srl (void)
358 T0 >>= T1;
359 RETURN();
362 void OPPROTO op_sra (void)
364 T0 = (int64_t)T0 >> T1;
365 RETURN();
368 void OPPROTO op_sextb (void)
370 T0 = (int64_t)((int8_t)T0);
371 RETURN();
374 void OPPROTO op_sextw (void)
376 T0 = (int64_t)((int16_t)T0);
377 RETURN();
381 void OPPROTO op_ctpop (void)
383 helper_ctpop();
384 RETURN();
387 void OPPROTO op_ctlz (void)
389 helper_ctlz();
390 RETURN();
393 void OPPROTO op_cttz (void)
395 helper_cttz();
396 RETURN();
399 void OPPROTO op_mskbl (void)
401 helper_mskbl();
402 RETURN();
405 void OPPROTO op_extbl (void)
407 helper_extbl();
408 RETURN();
411 void OPPROTO op_insbl (void)
413 helper_insbl();
414 RETURN();
417 void OPPROTO op_mskwl (void)
419 helper_mskwl();
420 RETURN();
423 void OPPROTO op_extwl (void)
425 helper_extwl();
426 RETURN();
429 void OPPROTO op_inswl (void)
431 helper_inswl();
432 RETURN();
435 void OPPROTO op_mskll (void)
437 helper_mskll();
438 RETURN();
441 void OPPROTO op_extll (void)
443 helper_extll();
444 RETURN();
447 void OPPROTO op_insll (void)
449 helper_insll();
450 RETURN();
453 void OPPROTO op_zap (void)
455 helper_zap();
456 RETURN();
459 void OPPROTO op_zapnot (void)
461 helper_zapnot();
462 RETURN();
465 void OPPROTO op_mskql (void)
467 helper_mskql();
468 RETURN();
471 void OPPROTO op_extql (void)
473 helper_extql();
474 RETURN();
477 void OPPROTO op_insql (void)
479 helper_insql();
480 RETURN();
483 void OPPROTO op_mskwh (void)
485 helper_mskwh();
486 RETURN();
489 void OPPROTO op_inswh (void)
491 helper_inswh();
492 RETURN();
495 void OPPROTO op_extwh (void)
497 helper_extwh();
498 RETURN();
501 void OPPROTO op_msklh (void)
503 helper_msklh();
504 RETURN();
507 void OPPROTO op_inslh (void)
509 helper_inslh();
510 RETURN();
513 void OPPROTO op_extlh (void)
515 helper_extlh();
516 RETURN();
519 void OPPROTO op_mskqh (void)
521 helper_mskqh();
522 RETURN();
525 void OPPROTO op_insqh (void)
527 helper_insqh();
528 RETURN();
531 void OPPROTO op_extqh (void)
533 helper_extqh();
534 RETURN();
537 /* Tests */
538 void OPPROTO op_cmpult (void)
540 if (T0 < T1)
541 T0 = 1;
542 else
543 T0 = 0;
544 RETURN();
547 void OPPROTO op_cmpule (void)
549 if (T0 <= T1)
550 T0 = 1;
551 else
552 T0 = 0;
553 RETURN();
556 void OPPROTO op_cmpeq (void)
558 if (T0 == T1)
559 T0 = 1;
560 else
561 T0 = 0;
562 RETURN();
565 void OPPROTO op_cmplt (void)
567 if ((int64_t)T0 < (int64_t)T1)
568 T0 = 1;
569 else
570 T0 = 0;
571 RETURN();
574 void OPPROTO op_cmple (void)
576 if ((int64_t)T0 <= (int64_t)T1)
577 T0 = 1;
578 else
579 T0 = 0;
580 RETURN();
583 void OPPROTO op_cmpbge (void)
585 helper_cmpbge();
586 RETURN();
589 void OPPROTO op_cmpeqz (void)
591 if (T0 == 0)
592 T0 = 1;
593 else
594 T0 = 0;
595 RETURN();
598 void OPPROTO op_cmpnez (void)
600 if (T0 != 0)
601 T0 = 1;
602 else
603 T0 = 0;
604 RETURN();
607 void OPPROTO op_cmpltz (void)
609 if ((int64_t)T0 < 0)
610 T0 = 1;
611 else
612 T0 = 0;
613 RETURN();
616 void OPPROTO op_cmplez (void)
618 if ((int64_t)T0 <= 0)
619 T0 = 1;
620 else
621 T0 = 0;
622 RETURN();
625 void OPPROTO op_cmpgtz (void)
627 if ((int64_t)T0 > 0)
628 T0 = 1;
629 else
630 T0 = 0;
631 RETURN();
634 void OPPROTO op_cmpgez (void)
636 if ((int64_t)T0 >= 0)
637 T0 = 1;
638 else
639 T0 = 0;
640 RETURN();
643 void OPPROTO op_cmplbs (void)
645 T0 &= 1;
646 RETURN();
649 void OPPROTO op_cmplbc (void)
651 T0 = (~T0) & 1;
652 RETURN();
655 /* Branches */
656 void OPPROTO op_branch (void)
658 env->pc = T0 & ~3;
659 RETURN();
662 void OPPROTO op_addq1 (void)
664 T1 += T0;
665 RETURN();
668 #if 0 // Qemu does not know how to do this...
669 void OPPROTO op_bcond (void)
671 if (T0)
672 env->pc = T1 & ~3;
673 else
674 env->pc = PARAM(1);
675 RETURN();
677 #else
678 void OPPROTO op_bcond (void)
680 if (T0)
681 env->pc = T1 & ~3;
682 else
683 env->pc = ((uint64_t)PARAM(1) << 32) | (uint64_t)PARAM(2);
684 RETURN();
686 #endif
688 #if 0 // Qemu does not know how to do this...
689 void OPPROTO op_update_pc (void)
691 env->pc = PARAM(1);
692 RETURN();
694 #else
695 void OPPROTO op_update_pc (void)
697 env->pc = ((uint64_t)PARAM(1) << 32) | (uint64_t)PARAM(2);
698 RETURN();
700 #endif
702 /* Optimization for 32 bits hosts architectures */
703 void OPPROTO op_update_pc32 (void)
705 env->pc = (uint64_t)PARAM(1);
706 RETURN();
709 /* IEEE floating point arithmetic */
710 /* S floating (single) */
711 void OPPROTO op_adds (void)
713 FT0 = float32_add(FT0, FT1, &FP_STATUS);
714 RETURN();
717 void OPPROTO op_subs (void)
719 FT0 = float32_sub(FT0, FT1, &FP_STATUS);
720 RETURN();
723 void OPPROTO op_muls (void)
725 FT0 = float32_mul(FT0, FT1, &FP_STATUS);
726 RETURN();
729 void OPPROTO op_divs (void)
731 FT0 = float32_div(FT0, FT1, &FP_STATUS);
732 RETURN();
735 void OPPROTO op_sqrts (void)
737 helper_sqrts();
738 RETURN();
741 void OPPROTO op_cpys (void)
743 helper_cpys();
744 RETURN();
747 void OPPROTO op_cpysn (void)
749 helper_cpysn();
750 RETURN();
753 void OPPROTO op_cpyse (void)
755 helper_cpyse();
756 RETURN();
759 void OPPROTO op_itofs (void)
761 helper_itofs();
762 RETURN();
765 void OPPROTO op_ftois (void)
767 helper_ftois();
768 RETURN();
771 /* T floating (double) */
772 void OPPROTO op_addt (void)
774 FT0 = float64_add(FT0, FT1, &FP_STATUS);
775 RETURN();
778 void OPPROTO op_subt (void)
780 FT0 = float64_sub(FT0, FT1, &FP_STATUS);
781 RETURN();
784 void OPPROTO op_mult (void)
786 FT0 = float64_mul(FT0, FT1, &FP_STATUS);
787 RETURN();
790 void OPPROTO op_divt (void)
792 FT0 = float64_div(FT0, FT1, &FP_STATUS);
793 RETURN();
796 void OPPROTO op_sqrtt (void)
798 helper_sqrtt();
799 RETURN();
802 void OPPROTO op_cmptun (void)
804 helper_cmptun();
805 RETURN();
808 void OPPROTO op_cmpteq (void)
810 helper_cmpteq();
811 RETURN();
814 void OPPROTO op_cmptle (void)
816 helper_cmptle();
817 RETURN();
820 void OPPROTO op_cmptlt (void)
822 helper_cmptlt();
823 RETURN();
826 void OPPROTO op_itoft (void)
828 helper_itoft();
829 RETURN();
832 void OPPROTO op_ftoit (void)
834 helper_ftoit();
835 RETURN();
838 /* VAX floating point arithmetic */
839 /* F floating */
840 void OPPROTO op_addf (void)
842 helper_addf();
843 RETURN();
846 void OPPROTO op_subf (void)
848 helper_subf();
849 RETURN();
852 void OPPROTO op_mulf (void)
854 helper_mulf();
855 RETURN();
858 void OPPROTO op_divf (void)
860 helper_divf();
861 RETURN();
864 void OPPROTO op_sqrtf (void)
866 helper_sqrtf();
867 RETURN();
870 void OPPROTO op_cmpfeq (void)
872 helper_cmpfeq();
873 RETURN();
876 void OPPROTO op_cmpfne (void)
878 helper_cmpfne();
879 RETURN();
882 void OPPROTO op_cmpflt (void)
884 helper_cmpflt();
885 RETURN();
888 void OPPROTO op_cmpfle (void)
890 helper_cmpfle();
891 RETURN();
894 void OPPROTO op_cmpfgt (void)
896 helper_cmpfgt();
897 RETURN();
900 void OPPROTO op_cmpfge (void)
902 helper_cmpfge();
903 RETURN();
906 void OPPROTO op_itoff (void)
908 helper_itoff();
909 RETURN();
912 /* G floating */
913 void OPPROTO op_addg (void)
915 helper_addg();
916 RETURN();
919 void OPPROTO op_subg (void)
921 helper_subg();
922 RETURN();
925 void OPPROTO op_mulg (void)
927 helper_mulg();
928 RETURN();
931 void OPPROTO op_divg (void)
933 helper_divg();
934 RETURN();
937 void OPPROTO op_sqrtg (void)
939 helper_sqrtg();
940 RETURN();
943 void OPPROTO op_cmpgeq (void)
945 helper_cmpgeq();
946 RETURN();
949 void OPPROTO op_cmpglt (void)
951 helper_cmpglt();
952 RETURN();
955 void OPPROTO op_cmpgle (void)
957 helper_cmpgle();
958 RETURN();
961 /* Floating point format conversion */
962 void OPPROTO op_cvtst (void)
964 FT0 = (float)FT0;
965 RETURN();
968 void OPPROTO op_cvtqs (void)
970 helper_cvtqs();
971 RETURN();
974 void OPPROTO op_cvtts (void)
976 FT0 = (float)FT0;
977 RETURN();
980 void OPPROTO op_cvttq (void)
982 helper_cvttq();
983 RETURN();
986 void OPPROTO op_cvtqt (void)
988 helper_cvtqt();
989 RETURN();
992 void OPPROTO op_cvtqf (void)
994 helper_cvtqf();
995 RETURN();
998 void OPPROTO op_cvtgf (void)
1000 helper_cvtgf();
1001 RETURN();
1004 void OPPROTO op_cvtgd (void)
1006 helper_cvtgd();
1007 RETURN();
1010 void OPPROTO op_cvtgq (void)
1012 helper_cvtgq();
1013 RETURN();
1016 void OPPROTO op_cvtqg (void)
1018 helper_cvtqg();
1019 RETURN();
1022 void OPPROTO op_cvtdg (void)
1024 helper_cvtdg();
1025 RETURN();
1028 void OPPROTO op_cvtlq (void)
1030 helper_cvtlq();
1031 RETURN();
1034 void OPPROTO op_cvtql (void)
1036 helper_cvtql();
1037 RETURN();
1040 void OPPROTO op_cvtqlv (void)
1042 helper_cvtqlv();
1043 RETURN();
1046 void OPPROTO op_cvtqlsv (void)
1048 helper_cvtqlsv();
1049 RETURN();
1052 /* PALcode support special instructions */
1053 #if !defined (CONFIG_USER_ONLY)
1054 void OPPROTO op_hw_rei (void)
1056 env->pc = env->ipr[IPR_EXC_ADDR] & ~3;
1057 env->ipr[IPR_EXC_ADDR] = env->ipr[IPR_EXC_ADDR] & 1;
1058 /* XXX: re-enable interrupts and memory mapping */
1059 RETURN();
1062 void OPPROTO op_hw_ret (void)
1064 env->pc = T0 & ~3;
1065 env->ipr[IPR_EXC_ADDR] = T0 & 1;
1066 /* XXX: re-enable interrupts and memory mapping */
1067 RETURN();
1070 void OPPROTO op_mfpr (void)
1072 helper_mfpr(PARAM(1));
1073 RETURN();
1076 void OPPROTO op_mtpr (void)
1078 helper_mtpr(PARAM(1));
1079 RETURN();
1082 void OPPROTO op_set_alt_mode (void)
1084 env->saved_mode = env->ps & 0xC;
1085 env->ps = (env->ps & ~0xC) | (env->ipr[IPR_ALT_MODE] & 0xC);
1086 RETURN();
1089 void OPPROTO op_restore_mode (void)
1091 env->ps = (env->ps & ~0xC) | env->saved_mode;
1092 RETURN();
1095 void OPPROTO op_ld_phys_to_virt (void)
1097 helper_ld_phys_to_virt();
1098 RETURN();
1101 void OPPROTO op_st_phys_to_virt (void)
1103 helper_st_phys_to_virt();
1104 RETURN();
1106 #endif /* !defined (CONFIG_USER_ONLY) */