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