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