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