]> git.proxmox.com Git - qemu.git/blob - target-alpha/op.c
find -type f | xargs sed -i 's/[\t ]$//g' # on most files
[qemu.git] / target-alpha / op.c
1 /*
2 * Alpha emulation cpu micro-operations for qemu.
3 *
4 * Copyright (c) 2007 Jocelyn Mayer
5 *
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.
10 *
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.
15 *
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
19 */
20
21 #define DEBUG_OP
22
23 #include "config.h"
24 #include "exec.h"
25
26 #include "op_helper.h"
27
28 #define REG 0
29 #include "op_template.h"
30
31 #define REG 1
32 #include "op_template.h"
33
34 #define REG 2
35 #include "op_template.h"
36
37 #define REG 3
38 #include "op_template.h"
39
40 #define REG 4
41 #include "op_template.h"
42
43 #define REG 5
44 #include "op_template.h"
45
46 #define REG 6
47 #include "op_template.h"
48
49 #define REG 7
50 #include "op_template.h"
51
52 #define REG 8
53 #include "op_template.h"
54
55 #define REG 9
56 #include "op_template.h"
57
58 #define REG 10
59 #include "op_template.h"
60
61 #define REG 11
62 #include "op_template.h"
63
64 #define REG 12
65 #include "op_template.h"
66
67 #define REG 13
68 #include "op_template.h"
69
70 #define REG 14
71 #include "op_template.h"
72
73 #define REG 15
74 #include "op_template.h"
75
76 #define REG 16
77 #include "op_template.h"
78
79 #define REG 17
80 #include "op_template.h"
81
82 #define REG 18
83 #include "op_template.h"
84
85 #define REG 19
86 #include "op_template.h"
87
88 #define REG 20
89 #include "op_template.h"
90
91 #define REG 21
92 #include "op_template.h"
93
94 #define REG 22
95 #include "op_template.h"
96
97 #define REG 23
98 #include "op_template.h"
99
100 #define REG 24
101 #include "op_template.h"
102
103 #define REG 25
104 #include "op_template.h"
105
106 #define REG 26
107 #include "op_template.h"
108
109 #define REG 27
110 #include "op_template.h"
111
112 #define REG 28
113 #include "op_template.h"
114
115 #define REG 29
116 #include "op_template.h"
117
118 #define REG 30
119 #include "op_template.h"
120
121 #define REG 31
122 #include "op_template.h"
123
124 /* Debug stuff */
125 void OPPROTO op_no_op (void)
126 {
127 #if !defined (DEBUG_OP)
128 __asm__ __volatile__("nop" : : : "memory");
129 #endif
130 RETURN();
131 }
132
133 void OPPROTO op_tb_flush (void)
134 {
135 helper_tb_flush();
136 RETURN();
137 }
138
139 /* Load and stores */
140 #define MEMSUFFIX _raw
141 #include "op_mem.h"
142 #if !defined(CONFIG_USER_ONLY)
143 #define MEMSUFFIX _user
144 #include "op_mem.h"
145 #define MEMSUFFIX _kernel
146 #include "op_mem.h"
147 /* Those are used for supervisor, executive and pal modes */
148 #define MEMSUFFIX _data
149 #include "op_mem.h"
150 #endif
151
152 /* Special operation for load and store */
153 void OPPROTO op_n7 (void)
154 {
155 T0 &= ~(uint64_t)0x7;
156 RETURN();
157 }
158
159 /* Misc */
160 void OPPROTO op_excp (void)
161 {
162 helper_excp(PARAM(1), PARAM(2));
163 RETURN();
164 }
165
166 void OPPROTO op_load_amask (void)
167 {
168 helper_amask();
169 RETURN();
170 }
171
172 void OPPROTO op_load_pcc (void)
173 {
174 helper_load_pcc();
175 RETURN();
176 }
177
178 void OPPROTO op_load_implver (void)
179 {
180 helper_load_implver();
181 RETURN();
182 }
183
184 void OPPROTO op_load_fpcr (void)
185 {
186 helper_load_fpcr();
187 RETURN();
188 }
189
190 void OPPROTO op_store_fpcr (void)
191 {
192 helper_store_fpcr();
193 RETURN();
194 }
195
196 void OPPROTO op_load_irf (void)
197 {
198 helper_load_irf();
199 RETURN();
200 }
201
202 void OPPROTO op_set_irf (void)
203 {
204 helper_set_irf();
205 RETURN();
206 }
207
208 void OPPROTO op_clear_irf (void)
209 {
210 helper_clear_irf();
211 RETURN();
212 }
213
214 void OPPROTO op_exit_tb (void)
215 {
216 EXIT_TB();
217 }
218
219 /* Arithmetic */
220 void OPPROTO op_addq (void)
221 {
222 T0 += T1;
223 RETURN();
224 }
225
226 void OPPROTO op_addqv (void)
227 {
228 helper_addqv();
229 RETURN();
230 }
231
232 void OPPROTO op_addl (void)
233 {
234 T0 = (int64_t)((int32_t)(T0 + T1));
235 RETURN();
236 }
237
238 void OPPROTO op_addlv (void)
239 {
240 helper_addlv();
241 RETURN();
242 }
243
244 void OPPROTO op_subq (void)
245 {
246 T0 -= T1;
247 RETURN();
248 }
249
250 void OPPROTO op_subqv (void)
251 {
252 helper_subqv();
253 RETURN();
254 }
255
256 void OPPROTO op_subl (void)
257 {
258 T0 = (int64_t)((int32_t)(T0 - T1));
259 RETURN();
260 }
261
262 void OPPROTO op_sublv (void)
263 {
264 helper_sublv();
265 RETURN();
266 }
267
268 void OPPROTO op_s4 (void)
269 {
270 T0 <<= 2;
271 RETURN();
272 }
273
274 void OPPROTO op_s8 (void)
275 {
276 T0 <<= 3;
277 RETURN();
278 }
279
280 void OPPROTO op_mull (void)
281 {
282 T0 = (int64_t)((int32_t)T0 * (int32_t)T1);
283 RETURN();
284 }
285
286 void OPPROTO op_mullv (void)
287 {
288 helper_mullv();
289 RETURN();
290 }
291
292 void OPPROTO op_mulq (void)
293 {
294 T0 *= T1;
295 RETURN();
296 }
297
298 void OPPROTO op_mulqv (void)
299 {
300 helper_mulqv();
301 RETURN();
302 }
303
304 void OPPROTO op_umulh (void)
305 {
306 helper_umulh();
307 RETURN();
308 }
309
310 /* Logical */
311 void OPPROTO op_and (void)
312 {
313 T0 &= T1;
314 RETURN();
315 }
316
317 void OPPROTO op_bic (void)
318 {
319 T0 &= ~T1;
320 RETURN();
321 }
322
323 void OPPROTO op_bis (void)
324 {
325 T0 |= T1;
326 RETURN();
327 }
328
329 void OPPROTO op_eqv (void)
330 {
331 T0 ^= ~T1;
332 RETURN();
333 }
334
335 void OPPROTO op_ornot (void)
336 {
337 T0 |= ~T1;
338 RETURN();
339 }
340
341 void OPPROTO op_xor (void)
342 {
343 T0 ^= T1;
344 RETURN();
345 }
346
347 void OPPROTO op_sll (void)
348 {
349 T0 <<= T1;
350 RETURN();
351 }
352
353 void OPPROTO op_srl (void)
354 {
355 T0 >>= T1;
356 RETURN();
357 }
358
359 void OPPROTO op_sra (void)
360 {
361 T0 = (int64_t)T0 >> T1;
362 RETURN();
363 }
364
365 void OPPROTO op_sextb (void)
366 {
367 T0 = (int64_t)((int8_t)T0);
368 RETURN();
369 }
370
371 void OPPROTO op_sextw (void)
372 {
373 T0 = (int64_t)((int16_t)T0);
374 RETURN();
375
376 }
377
378 void OPPROTO op_ctpop (void)
379 {
380 helper_ctpop();
381 RETURN();
382 }
383
384 void OPPROTO op_ctlz (void)
385 {
386 helper_ctlz();
387 RETURN();
388 }
389
390 void OPPROTO op_cttz (void)
391 {
392 helper_cttz();
393 RETURN();
394 }
395
396 void OPPROTO op_mskbl (void)
397 {
398 helper_mskbl();
399 RETURN();
400 }
401
402 void OPPROTO op_extbl (void)
403 {
404 helper_extbl();
405 RETURN();
406 }
407
408 void OPPROTO op_insbl (void)
409 {
410 helper_insbl();
411 RETURN();
412 }
413
414 void OPPROTO op_mskwl (void)
415 {
416 helper_mskwl();
417 RETURN();
418 }
419
420 void OPPROTO op_extwl (void)
421 {
422 helper_extwl();
423 RETURN();
424 }
425
426 void OPPROTO op_inswl (void)
427 {
428 helper_inswl();
429 RETURN();
430 }
431
432 void OPPROTO op_mskll (void)
433 {
434 helper_mskll();
435 RETURN();
436 }
437
438 void OPPROTO op_extll (void)
439 {
440 helper_extll();
441 RETURN();
442 }
443
444 void OPPROTO op_insll (void)
445 {
446 helper_insll();
447 RETURN();
448 }
449
450 void OPPROTO op_zap (void)
451 {
452 helper_zap();
453 RETURN();
454 }
455
456 void OPPROTO op_zapnot (void)
457 {
458 helper_zapnot();
459 RETURN();
460 }
461
462 void OPPROTO op_mskql (void)
463 {
464 helper_mskql();
465 RETURN();
466 }
467
468 void OPPROTO op_extql (void)
469 {
470 helper_extql();
471 RETURN();
472 }
473
474 void OPPROTO op_insql (void)
475 {
476 helper_insql();
477 RETURN();
478 }
479
480 void OPPROTO op_mskwh (void)
481 {
482 helper_mskwh();
483 RETURN();
484 }
485
486 void OPPROTO op_inswh (void)
487 {
488 helper_inswh();
489 RETURN();
490 }
491
492 void OPPROTO op_extwh (void)
493 {
494 helper_extwh();
495 RETURN();
496 }
497
498 void OPPROTO op_msklh (void)
499 {
500 helper_msklh();
501 RETURN();
502 }
503
504 void OPPROTO op_inslh (void)
505 {
506 helper_inslh();
507 RETURN();
508 }
509
510 void OPPROTO op_extlh (void)
511 {
512 helper_extlh();
513 RETURN();
514 }
515
516 void OPPROTO op_mskqh (void)
517 {
518 helper_mskqh();
519 RETURN();
520 }
521
522 void OPPROTO op_insqh (void)
523 {
524 helper_insqh();
525 RETURN();
526 }
527
528 void OPPROTO op_extqh (void)
529 {
530 helper_extqh();
531 RETURN();
532 }
533
534 /* Tests */
535 void OPPROTO op_cmpult (void)
536 {
537 if (T0 < T1)
538 T0 = 1;
539 else
540 T0 = 0;
541 RETURN();
542 }
543
544 void OPPROTO op_cmpule (void)
545 {
546 if (T0 <= T1)
547 T0 = 1;
548 else
549 T0 = 0;
550 RETURN();
551 }
552
553 void OPPROTO op_cmpeq (void)
554 {
555 if (T0 == T1)
556 T0 = 1;
557 else
558 T0 = 0;
559 RETURN();
560 }
561
562 void OPPROTO op_cmplt (void)
563 {
564 if ((int64_t)T0 < (int64_t)T1)
565 T0 = 1;
566 else
567 T0 = 0;
568 RETURN();
569 }
570
571 void OPPROTO op_cmple (void)
572 {
573 if ((int64_t)T0 <= (int64_t)T1)
574 T0 = 1;
575 else
576 T0 = 0;
577 RETURN();
578 }
579
580 void OPPROTO op_cmpbge (void)
581 {
582 helper_cmpbge();
583 RETURN();
584 }
585
586 void OPPROTO op_cmpeqz (void)
587 {
588 if (T0 == 0)
589 T0 = 1;
590 else
591 T0 = 0;
592 RETURN();
593 }
594
595 void OPPROTO op_cmpnez (void)
596 {
597 if (T0 != 0)
598 T0 = 1;
599 else
600 T0 = 0;
601 RETURN();
602 }
603
604 void OPPROTO op_cmpltz (void)
605 {
606 if ((int64_t)T0 < 0)
607 T0 = 1;
608 else
609 T0 = 0;
610 RETURN();
611 }
612
613 void OPPROTO op_cmplez (void)
614 {
615 if ((int64_t)T0 <= 0)
616 T0 = 1;
617 else
618 T0 = 0;
619 RETURN();
620 }
621
622 void OPPROTO op_cmpgtz (void)
623 {
624 if ((int64_t)T0 > 0)
625 T0 = 1;
626 else
627 T0 = 0;
628 RETURN();
629 }
630
631 void OPPROTO op_cmpgez (void)
632 {
633 if ((int64_t)T0 >= 0)
634 T0 = 1;
635 else
636 T0 = 0;
637 RETURN();
638 }
639
640 void OPPROTO op_cmplbs (void)
641 {
642 T0 &= 1;
643 RETURN();
644 }
645
646 void OPPROTO op_cmplbc (void)
647 {
648 T0 = (~T0) & 1;
649 RETURN();
650 }
651
652 /* Branches */
653 void OPPROTO op_branch (void)
654 {
655 env->pc = T0 & ~3;
656 RETURN();
657 }
658
659 void OPPROTO op_addq1 (void)
660 {
661 T1 += T0;
662 RETURN();
663 }
664
665 #if 0 // Qemu does not know how to do this...
666 void OPPROTO op_bcond (void)
667 {
668 if (T0)
669 env->pc = T1 & ~3;
670 else
671 env->pc = PARAM(1);
672 RETURN();
673 }
674 #else
675 void OPPROTO op_bcond (void)
676 {
677 if (T0)
678 env->pc = T1 & ~3;
679 else
680 env->pc = ((uint64_t)PARAM(1) << 32) | (uint64_t)PARAM(2);
681 RETURN();
682 }
683 #endif
684
685 #if 0 // Qemu does not know how to do this...
686 void OPPROTO op_update_pc (void)
687 {
688 env->pc = PARAM(1);
689 RETURN();
690 }
691 #else
692 void OPPROTO op_update_pc (void)
693 {
694 env->pc = ((uint64_t)PARAM(1) << 32) | (uint64_t)PARAM(2);
695 RETURN();
696 }
697 #endif
698
699 /* Optimization for 32 bits hosts architectures */
700 void OPPROTO op_update_pc32 (void)
701 {
702 env->pc = (uint64_t)PARAM(1);
703 RETURN();
704 }
705
706 /* IEEE floating point arithmetic */
707 /* S floating (single) */
708 void OPPROTO op_adds (void)
709 {
710 FT0 = float32_add(FT0, FT1, &FP_STATUS);
711 RETURN();
712 }
713
714 void OPPROTO op_subs (void)
715 {
716 FT0 = float32_sub(FT0, FT1, &FP_STATUS);
717 RETURN();
718 }
719
720 void OPPROTO op_muls (void)
721 {
722 FT0 = float32_mul(FT0, FT1, &FP_STATUS);
723 RETURN();
724 }
725
726 void OPPROTO op_divs (void)
727 {
728 FT0 = float32_div(FT0, FT1, &FP_STATUS);
729 RETURN();
730 }
731
732 void OPPROTO op_sqrts (void)
733 {
734 helper_sqrts();
735 RETURN();
736 }
737
738 void OPPROTO op_cpys (void)
739 {
740 helper_cpys();
741 RETURN();
742 }
743
744 void OPPROTO op_cpysn (void)
745 {
746 helper_cpysn();
747 RETURN();
748 }
749
750 void OPPROTO op_cpyse (void)
751 {
752 helper_cpyse();
753 RETURN();
754 }
755
756 void OPPROTO op_itofs (void)
757 {
758 helper_itofs();
759 RETURN();
760 }
761
762 void OPPROTO op_ftois (void)
763 {
764 helper_ftois();
765 RETURN();
766 }
767
768 /* T floating (double) */
769 void OPPROTO op_addt (void)
770 {
771 FT0 = float64_add(FT0, FT1, &FP_STATUS);
772 RETURN();
773 }
774
775 void OPPROTO op_subt (void)
776 {
777 FT0 = float64_sub(FT0, FT1, &FP_STATUS);
778 RETURN();
779 }
780
781 void OPPROTO op_mult (void)
782 {
783 FT0 = float64_mul(FT0, FT1, &FP_STATUS);
784 RETURN();
785 }
786
787 void OPPROTO op_divt (void)
788 {
789 FT0 = float64_div(FT0, FT1, &FP_STATUS);
790 RETURN();
791 }
792
793 void OPPROTO op_sqrtt (void)
794 {
795 helper_sqrtt();
796 RETURN();
797 }
798
799 void OPPROTO op_cmptun (void)
800 {
801 helper_cmptun();
802 RETURN();
803 }
804
805 void OPPROTO op_cmpteq (void)
806 {
807 helper_cmpteq();
808 RETURN();
809 }
810
811 void OPPROTO op_cmptle (void)
812 {
813 helper_cmptle();
814 RETURN();
815 }
816
817 void OPPROTO op_cmptlt (void)
818 {
819 helper_cmptlt();
820 RETURN();
821 }
822
823 void OPPROTO op_itoft (void)
824 {
825 helper_itoft();
826 RETURN();
827 }
828
829 void OPPROTO op_ftoit (void)
830 {
831 helper_ftoit();
832 RETURN();
833 }
834
835 /* VAX floating point arithmetic */
836 /* F floating */
837 void OPPROTO op_addf (void)
838 {
839 helper_addf();
840 RETURN();
841 }
842
843 void OPPROTO op_subf (void)
844 {
845 helper_subf();
846 RETURN();
847 }
848
849 void OPPROTO op_mulf (void)
850 {
851 helper_mulf();
852 RETURN();
853 }
854
855 void OPPROTO op_divf (void)
856 {
857 helper_divf();
858 RETURN();
859 }
860
861 void OPPROTO op_sqrtf (void)
862 {
863 helper_sqrtf();
864 RETURN();
865 }
866
867 void OPPROTO op_cmpfeq (void)
868 {
869 helper_cmpfeq();
870 RETURN();
871 }
872
873 void OPPROTO op_cmpfne (void)
874 {
875 helper_cmpfne();
876 RETURN();
877 }
878
879 void OPPROTO op_cmpflt (void)
880 {
881 helper_cmpflt();
882 RETURN();
883 }
884
885 void OPPROTO op_cmpfle (void)
886 {
887 helper_cmpfle();
888 RETURN();
889 }
890
891 void OPPROTO op_cmpfgt (void)
892 {
893 helper_cmpfgt();
894 RETURN();
895 }
896
897 void OPPROTO op_cmpfge (void)
898 {
899 helper_cmpfge();
900 RETURN();
901 }
902
903 void OPPROTO op_itoff (void)
904 {
905 helper_itoff();
906 RETURN();
907 }
908
909 /* G floating */
910 void OPPROTO op_addg (void)
911 {
912 helper_addg();
913 RETURN();
914 }
915
916 void OPPROTO op_subg (void)
917 {
918 helper_subg();
919 RETURN();
920 }
921
922 void OPPROTO op_mulg (void)
923 {
924 helper_mulg();
925 RETURN();
926 }
927
928 void OPPROTO op_divg (void)
929 {
930 helper_divg();
931 RETURN();
932 }
933
934 void OPPROTO op_sqrtg (void)
935 {
936 helper_sqrtg();
937 RETURN();
938 }
939
940 void OPPROTO op_cmpgeq (void)
941 {
942 helper_cmpgeq();
943 RETURN();
944 }
945
946 void OPPROTO op_cmpglt (void)
947 {
948 helper_cmpglt();
949 RETURN();
950 }
951
952 void OPPROTO op_cmpgle (void)
953 {
954 helper_cmpgle();
955 RETURN();
956 }
957
958 /* Floating point format conversion */
959 void OPPROTO op_cvtst (void)
960 {
961 FT0 = (float)FT0;
962 RETURN();
963 }
964
965 void OPPROTO op_cvtqs (void)
966 {
967 helper_cvtqs();
968 RETURN();
969 }
970
971 void OPPROTO op_cvtts (void)
972 {
973 FT0 = (float)FT0;
974 RETURN();
975 }
976
977 void OPPROTO op_cvttq (void)
978 {
979 helper_cvttq();
980 RETURN();
981 }
982
983 void OPPROTO op_cvtqt (void)
984 {
985 helper_cvtqt();
986 RETURN();
987 }
988
989 void OPPROTO op_cvtqf (void)
990 {
991 helper_cvtqf();
992 RETURN();
993 }
994
995 void OPPROTO op_cvtgf (void)
996 {
997 helper_cvtgf();
998 RETURN();
999 }
1000
1001 void OPPROTO op_cvtgd (void)
1002 {
1003 helper_cvtgd();
1004 RETURN();
1005 }
1006
1007 void OPPROTO op_cvtgq (void)
1008 {
1009 helper_cvtgq();
1010 RETURN();
1011 }
1012
1013 void OPPROTO op_cvtqg (void)
1014 {
1015 helper_cvtqg();
1016 RETURN();
1017 }
1018
1019 void OPPROTO op_cvtdg (void)
1020 {
1021 helper_cvtdg();
1022 RETURN();
1023 }
1024
1025 void OPPROTO op_cvtlq (void)
1026 {
1027 helper_cvtlq();
1028 RETURN();
1029 }
1030
1031 void OPPROTO op_cvtql (void)
1032 {
1033 helper_cvtql();
1034 RETURN();
1035 }
1036
1037 void OPPROTO op_cvtqlv (void)
1038 {
1039 helper_cvtqlv();
1040 RETURN();
1041 }
1042
1043 void OPPROTO op_cvtqlsv (void)
1044 {
1045 helper_cvtqlsv();
1046 RETURN();
1047 }
1048
1049 /* PALcode support special instructions */
1050 #if !defined (CONFIG_USER_ONLY)
1051 void OPPROTO op_hw_rei (void)
1052 {
1053 env->pc = env->ipr[IPR_EXC_ADDR] & ~3;
1054 env->ipr[IPR_EXC_ADDR] = env->ipr[IPR_EXC_ADDR] & 1;
1055 /* XXX: re-enable interrupts and memory mapping */
1056 RETURN();
1057 }
1058
1059 void OPPROTO op_hw_ret (void)
1060 {
1061 env->pc = T0 & ~3;
1062 env->ipr[IPR_EXC_ADDR] = T0 & 1;
1063 /* XXX: re-enable interrupts and memory mapping */
1064 RETURN();
1065 }
1066
1067 void OPPROTO op_mfpr (void)
1068 {
1069 helper_mfpr(PARAM(1));
1070 RETURN();
1071 }
1072
1073 void OPPROTO op_mtpr (void)
1074 {
1075 helper_mtpr(PARAM(1));
1076 RETURN();
1077 }
1078
1079 void OPPROTO op_set_alt_mode (void)
1080 {
1081 env->saved_mode = env->ps & 0xC;
1082 env->ps = (env->ps & ~0xC) | (env->ipr[IPR_ALT_MODE] & 0xC);
1083 RETURN();
1084 }
1085
1086 void OPPROTO op_restore_mode (void)
1087 {
1088 env->ps = (env->ps & ~0xC) | env->saved_mode;
1089 RETURN();
1090 }
1091
1092 void OPPROTO op_ld_phys_to_virt (void)
1093 {
1094 helper_ld_phys_to_virt();
1095 RETURN();
1096 }
1097
1098 void OPPROTO op_st_phys_to_virt (void)
1099 {
1100 helper_st_phys_to_virt();
1101 RETURN();
1102 }
1103 #endif /* !defined (CONFIG_USER_ONLY) */