target-alpha: convert some arith3 instructions to TCG
[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_pcc (void)
159 {
160     helper_load_pcc();
161     RETURN();
162 }
163
164 void OPPROTO op_load_implver (void)
165 {
166     helper_load_implver();
167     RETURN();
168 }
169
170 void OPPROTO op_load_fpcr (void)
171 {
172     helper_load_fpcr();
173     RETURN();
174 }
175
176 void OPPROTO op_store_fpcr (void)
177 {
178     helper_store_fpcr();
179     RETURN();
180 }
181
182 void OPPROTO op_load_irf (void)
183 {
184     helper_load_irf();
185     RETURN();
186 }
187
188 void OPPROTO op_set_irf (void)
189 {
190     helper_set_irf();
191     RETURN();
192 }
193
194 void OPPROTO op_clear_irf (void)
195 {
196     helper_clear_irf();
197     RETURN();
198 }
199
200 /* Arithmetic */
201 void OPPROTO op_addqv (void)
202 {
203     helper_addqv();
204     RETURN();
205 }
206
207 void OPPROTO op_addlv (void)
208 {
209     helper_addlv();
210     RETURN();
211 }
212
213 void OPPROTO op_subqv (void)
214 {
215     helper_subqv();
216     RETURN();
217 }
218
219 void OPPROTO op_sublv (void)
220 {
221     helper_sublv();
222     RETURN();
223 }
224
225 void OPPROTO op_mullv (void)
226 {
227     helper_mullv();
228     RETURN();
229 }
230
231 void OPPROTO op_mulqv (void)
232 {
233     helper_mulqv();
234     RETURN();
235 }
236
237 void OPPROTO op_umulh (void)
238 {
239     uint64_t tl, th;
240
241     mulu64(&tl, &th, T0, T1);
242     T0 = th;
243     RETURN();
244 }
245
246 /* Logical */
247 void OPPROTO op_mskbl (void)
248 {
249     helper_mskbl();
250     RETURN();
251 }
252
253 void OPPROTO op_extbl (void)
254 {
255     helper_extbl();
256     RETURN();
257 }
258
259 void OPPROTO op_insbl (void)
260 {
261     helper_insbl();
262     RETURN();
263 }
264
265 void OPPROTO op_mskwl (void)
266 {
267     helper_mskwl();
268     RETURN();
269 }
270
271 void OPPROTO op_extwl (void)
272 {
273     helper_extwl();
274     RETURN();
275 }
276
277 void OPPROTO op_inswl (void)
278 {
279     helper_inswl();
280     RETURN();
281 }
282
283 void OPPROTO op_mskll (void)
284 {
285     helper_mskll();
286     RETURN();
287 }
288
289 void OPPROTO op_extll (void)
290 {
291     helper_extll();
292     RETURN();
293 }
294
295 void OPPROTO op_insll (void)
296 {
297     helper_insll();
298     RETURN();
299 }
300
301 void OPPROTO op_zap (void)
302 {
303     helper_zap();
304     RETURN();
305 }
306
307 void OPPROTO op_zapnot (void)
308 {
309     helper_zapnot();
310     RETURN();
311 }
312
313 void OPPROTO op_mskql (void)
314 {
315     helper_mskql();
316     RETURN();
317 }
318
319 void OPPROTO op_extql (void)
320 {
321     helper_extql();
322     RETURN();
323 }
324
325 void OPPROTO op_insql (void)
326 {
327     helper_insql();
328     RETURN();
329 }
330
331 void OPPROTO op_mskwh (void)
332 {
333     helper_mskwh();
334     RETURN();
335 }
336
337 void OPPROTO op_inswh (void)
338 {
339     helper_inswh();
340     RETURN();
341 }
342
343 void OPPROTO op_extwh (void)
344 {
345     helper_extwh();
346     RETURN();
347 }
348
349 void OPPROTO op_msklh (void)
350 {
351     helper_msklh();
352     RETURN();
353 }
354
355 void OPPROTO op_inslh (void)
356 {
357     helper_inslh();
358     RETURN();
359 }
360
361 void OPPROTO op_extlh (void)
362 {
363     helper_extlh();
364     RETURN();
365 }
366
367 void OPPROTO op_mskqh (void)
368 {
369     helper_mskqh();
370     RETURN();
371 }
372
373 void OPPROTO op_insqh (void)
374 {
375     helper_insqh();
376     RETURN();
377 }
378
379 void OPPROTO op_extqh (void)
380 {
381     helper_extqh();
382     RETURN();
383 }
384
385 /* Tests */
386 void OPPROTO op_cmpult (void)
387 {
388     if (T0 < T1)
389         T0 = 1;
390     else
391         T0 = 0;
392     RETURN();
393 }
394
395 void OPPROTO op_cmpule (void)
396 {
397     if (T0 <= T1)
398         T0 = 1;
399     else
400         T0 = 0;
401     RETURN();
402 }
403
404 void OPPROTO op_cmpeq (void)
405 {
406     if (T0 == T1)
407         T0 = 1;
408     else
409         T0 = 0;
410     RETURN();
411 }
412
413 void OPPROTO op_cmplt (void)
414 {
415     if ((int64_t)T0 < (int64_t)T1)
416         T0 = 1;
417     else
418         T0 = 0;
419     RETURN();
420 }
421
422 void OPPROTO op_cmple (void)
423 {
424     if ((int64_t)T0 <= (int64_t)T1)
425         T0 = 1;
426     else
427         T0 = 0;
428     RETURN();
429 }
430
431 void OPPROTO op_cmpbge (void)
432 {
433     helper_cmpbge();
434     RETURN();
435 }
436
437 void OPPROTO op_cmpeqz (void)
438 {
439     if (T0 == 0)
440         T0 = 1;
441     else
442         T0 = 0;
443     RETURN();
444 }
445
446 void OPPROTO op_cmpnez (void)
447 {
448     if (T0 != 0)
449         T0 = 1;
450     else
451         T0 = 0;
452     RETURN();
453 }
454
455 void OPPROTO op_cmpltz (void)
456 {
457     if ((int64_t)T0 < 0)
458         T0 = 1;
459     else
460         T0 = 0;
461     RETURN();
462 }
463
464 void OPPROTO op_cmplez (void)
465 {
466     if ((int64_t)T0 <= 0)
467         T0 = 1;
468     else
469         T0 = 0;
470     RETURN();
471 }
472
473 void OPPROTO op_cmpgtz (void)
474 {
475     if ((int64_t)T0 > 0)
476         T0 = 1;
477     else
478         T0 = 0;
479     RETURN();
480 }
481
482 void OPPROTO op_cmpgez (void)
483 {
484     if ((int64_t)T0 >= 0)
485         T0 = 1;
486     else
487         T0 = 0;
488     RETURN();
489 }
490
491 void OPPROTO op_cmplbs (void)
492 {
493     T0 &= 1;
494     RETURN();
495 }
496
497 void OPPROTO op_cmplbc (void)
498 {
499     T0 = (~T0) & 1;
500     RETURN();
501 }
502
503 #if 0 // Qemu does not know how to do this...
504 void OPPROTO op_bcond (void)
505 {
506     if (T0)
507         env->pc = T1 & ~3;
508     else
509         env->pc = PARAM(1);
510     RETURN();
511 }
512 #else
513 void OPPROTO op_bcond (void)
514 {
515     if (T0)
516         env->pc = T1 & ~3;
517     else
518         env->pc = ((uint64_t)PARAM(1) << 32) | (uint64_t)PARAM(2);
519     RETURN();
520 }
521 #endif
522
523 /* IEEE floating point arithmetic */
524 /* S floating (single) */
525 void OPPROTO op_adds (void)
526 {
527     FT0 = float32_add(FT0, FT1, &FP_STATUS);
528     RETURN();
529 }
530
531 void OPPROTO op_subs (void)
532 {
533     FT0 = float32_sub(FT0, FT1, &FP_STATUS);
534     RETURN();
535 }
536
537 void OPPROTO op_muls (void)
538 {
539     FT0 = float32_mul(FT0, FT1, &FP_STATUS);
540     RETURN();
541 }
542
543 void OPPROTO op_divs (void)
544 {
545     FT0 = float32_div(FT0, FT1, &FP_STATUS);
546     RETURN();
547 }
548
549 void OPPROTO op_sqrts (void)
550 {
551     helper_sqrts();
552     RETURN();
553 }
554
555 void OPPROTO op_cpys (void)
556 {
557     helper_cpys();
558     RETURN();
559 }
560
561 void OPPROTO op_cpysn (void)
562 {
563     helper_cpysn();
564     RETURN();
565 }
566
567 void OPPROTO op_cpyse (void)
568 {
569     helper_cpyse();
570     RETURN();
571 }
572
573 void OPPROTO op_itofs (void)
574 {
575     helper_itofs();
576     RETURN();
577 }
578
579 void OPPROTO op_ftois (void)
580 {
581     helper_ftois();
582     RETURN();
583 }
584
585 /* T floating (double) */
586 void OPPROTO op_addt (void)
587 {
588     FT0 = float64_add(FT0, FT1, &FP_STATUS);
589     RETURN();
590 }
591
592 void OPPROTO op_subt (void)
593 {
594     FT0 = float64_sub(FT0, FT1, &FP_STATUS);
595     RETURN();
596 }
597
598 void OPPROTO op_mult (void)
599 {
600     FT0 = float64_mul(FT0, FT1, &FP_STATUS);
601     RETURN();
602 }
603
604 void OPPROTO op_divt (void)
605 {
606     FT0 = float64_div(FT0, FT1, &FP_STATUS);
607     RETURN();
608 }
609
610 void OPPROTO op_sqrtt (void)
611 {
612     helper_sqrtt();
613     RETURN();
614 }
615
616 void OPPROTO op_cmptun (void)
617 {
618     helper_cmptun();
619     RETURN();
620 }
621
622 void OPPROTO op_cmpteq (void)
623 {
624     helper_cmpteq();
625     RETURN();
626 }
627
628 void OPPROTO op_cmptle (void)
629 {
630     helper_cmptle();
631     RETURN();
632 }
633
634 void OPPROTO op_cmptlt (void)
635 {
636     helper_cmptlt();
637     RETURN();
638 }
639
640 void OPPROTO op_itoft (void)
641 {
642     helper_itoft();
643     RETURN();
644 }
645
646 void OPPROTO op_ftoit (void)
647 {
648     helper_ftoit();
649     RETURN();
650 }
651
652 /* VAX floating point arithmetic */
653 /* F floating */
654 void OPPROTO op_addf (void)
655 {
656     helper_addf();
657     RETURN();
658 }
659
660 void OPPROTO op_subf (void)
661 {
662     helper_subf();
663     RETURN();
664 }
665
666 void OPPROTO op_mulf (void)
667 {
668     helper_mulf();
669     RETURN();
670 }
671
672 void OPPROTO op_divf (void)
673 {
674     helper_divf();
675     RETURN();
676 }
677
678 void OPPROTO op_sqrtf (void)
679 {
680     helper_sqrtf();
681     RETURN();
682 }
683
684 void OPPROTO op_cmpfeq (void)
685 {
686     helper_cmpfeq();
687     RETURN();
688 }
689
690 void OPPROTO op_cmpfne (void)
691 {
692     helper_cmpfne();
693     RETURN();
694 }
695
696 void OPPROTO op_cmpflt (void)
697 {
698     helper_cmpflt();
699     RETURN();
700 }
701
702 void OPPROTO op_cmpfle (void)
703 {
704     helper_cmpfle();
705     RETURN();
706 }
707
708 void OPPROTO op_cmpfgt (void)
709 {
710     helper_cmpfgt();
711     RETURN();
712 }
713
714 void OPPROTO op_cmpfge (void)
715 {
716     helper_cmpfge();
717     RETURN();
718 }
719
720 void OPPROTO op_itoff (void)
721 {
722     helper_itoff();
723     RETURN();
724 }
725
726 /* G floating */
727 void OPPROTO op_addg (void)
728 {
729     helper_addg();
730     RETURN();
731 }
732
733 void OPPROTO op_subg (void)
734 {
735     helper_subg();
736     RETURN();
737 }
738
739 void OPPROTO op_mulg (void)
740 {
741     helper_mulg();
742     RETURN();
743 }
744
745 void OPPROTO op_divg (void)
746 {
747     helper_divg();
748     RETURN();
749 }
750
751 void OPPROTO op_sqrtg (void)
752 {
753     helper_sqrtg();
754     RETURN();
755 }
756
757 void OPPROTO op_cmpgeq (void)
758 {
759     helper_cmpgeq();
760     RETURN();
761 }
762
763 void OPPROTO op_cmpglt (void)
764 {
765     helper_cmpglt();
766     RETURN();
767 }
768
769 void OPPROTO op_cmpgle (void)
770 {
771     helper_cmpgle();
772     RETURN();
773 }
774
775 /* Floating point format conversion */
776 void OPPROTO op_cvtst (void)
777 {
778     FT0 = (float)FT0;
779     RETURN();
780 }
781
782 void OPPROTO op_cvtqs (void)
783 {
784     helper_cvtqs();
785     RETURN();
786 }
787
788 void OPPROTO op_cvtts (void)
789 {
790     FT0 = (float)FT0;
791     RETURN();
792 }
793
794 void OPPROTO op_cvttq (void)
795 {
796     helper_cvttq();
797     RETURN();
798 }
799
800 void OPPROTO op_cvtqt (void)
801 {
802     helper_cvtqt();
803     RETURN();
804 }
805
806 void OPPROTO op_cvtqf (void)
807 {
808     helper_cvtqf();
809     RETURN();
810 }
811
812 void OPPROTO op_cvtgf (void)
813 {
814     helper_cvtgf();
815     RETURN();
816 }
817
818 void OPPROTO op_cvtgd (void)
819 {
820     helper_cvtgd();
821     RETURN();
822 }
823
824 void OPPROTO op_cvtgq (void)
825 {
826     helper_cvtgq();
827     RETURN();
828 }
829
830 void OPPROTO op_cvtqg (void)
831 {
832     helper_cvtqg();
833     RETURN();
834 }
835
836 void OPPROTO op_cvtdg (void)
837 {
838     helper_cvtdg();
839     RETURN();
840 }
841
842 void OPPROTO op_cvtlq (void)
843 {
844     helper_cvtlq();
845     RETURN();
846 }
847
848 void OPPROTO op_cvtql (void)
849 {
850     helper_cvtql();
851     RETURN();
852 }
853
854 void OPPROTO op_cvtqlv (void)
855 {
856     helper_cvtqlv();
857     RETURN();
858 }
859
860 void OPPROTO op_cvtqlsv (void)
861 {
862     helper_cvtqlsv();
863     RETURN();
864 }
865
866 /* PALcode support special instructions */
867 #if !defined (CONFIG_USER_ONLY)
868 void OPPROTO op_hw_rei (void)
869 {
870     env->pc = env->ipr[IPR_EXC_ADDR] & ~3;
871     env->ipr[IPR_EXC_ADDR] = env->ipr[IPR_EXC_ADDR] & 1;
872     /* XXX: re-enable interrupts and memory mapping */
873     RETURN();
874 }
875
876 void OPPROTO op_hw_ret (void)
877 {
878     env->pc = T0 & ~3;
879     env->ipr[IPR_EXC_ADDR] = T0 & 1;
880     /* XXX: re-enable interrupts and memory mapping */
881     RETURN();
882 }
883
884 void OPPROTO op_mfpr (void)
885 {
886     helper_mfpr(PARAM(1));
887     RETURN();
888 }
889
890 void OPPROTO op_mtpr (void)
891 {
892     helper_mtpr(PARAM(1));
893     RETURN();
894 }
895
896 void OPPROTO op_set_alt_mode (void)
897 {
898     env->saved_mode = env->ps & 0xC;
899     env->ps = (env->ps & ~0xC) | (env->ipr[IPR_ALT_MODE] & 0xC);
900     RETURN();
901 }
902
903 void OPPROTO op_restore_mode (void)
904 {
905     env->ps = (env->ps & ~0xC) | env->saved_mode;
906     RETURN();
907 }
908
909 void OPPROTO op_ld_phys_to_virt (void)
910 {
911     helper_ld_phys_to_virt();
912     RETURN();
913 }
914
915 void OPPROTO op_st_phys_to_virt (void)
916 {
917     helper_st_phys_to_virt();
918     RETURN();
919 }
920 #endif /* !defined (CONFIG_USER_ONLY) */