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