Rename PowerPC MMUCSR0 and MMUCFG SPRs: those are not BookE specific.
[qemu] / 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) */