405a05257f458fe76b4d96f31e746b96b42f1542
[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 #if 0 // Qemu does not know how to do this...
438 void OPPROTO op_bcond (void)
439 {
440     if (T0)
441         env->pc = T1 & ~3;
442     else
443         env->pc = PARAM(1);
444     RETURN();
445 }
446 #else
447 void OPPROTO op_bcond (void)
448 {
449     if (T0)
450         env->pc = T1 & ~3;
451     else
452         env->pc = ((uint64_t)PARAM(1) << 32) | (uint64_t)PARAM(2);
453     RETURN();
454 }
455 #endif
456
457 /* IEEE floating point arithmetic */
458 /* S floating (single) */
459 void OPPROTO op_adds (void)
460 {
461     FT0 = float32_add(FT0, FT1, &FP_STATUS);
462     RETURN();
463 }
464
465 void OPPROTO op_subs (void)
466 {
467     FT0 = float32_sub(FT0, FT1, &FP_STATUS);
468     RETURN();
469 }
470
471 void OPPROTO op_muls (void)
472 {
473     FT0 = float32_mul(FT0, FT1, &FP_STATUS);
474     RETURN();
475 }
476
477 void OPPROTO op_divs (void)
478 {
479     FT0 = float32_div(FT0, FT1, &FP_STATUS);
480     RETURN();
481 }
482
483 void OPPROTO op_sqrts (void)
484 {
485     helper_sqrts();
486     RETURN();
487 }
488
489 void OPPROTO op_cpys (void)
490 {
491     helper_cpys();
492     RETURN();
493 }
494
495 void OPPROTO op_cpysn (void)
496 {
497     helper_cpysn();
498     RETURN();
499 }
500
501 void OPPROTO op_cpyse (void)
502 {
503     helper_cpyse();
504     RETURN();
505 }
506
507 void OPPROTO op_itofs (void)
508 {
509     helper_itofs();
510     RETURN();
511 }
512
513 void OPPROTO op_ftois (void)
514 {
515     helper_ftois();
516     RETURN();
517 }
518
519 /* T floating (double) */
520 void OPPROTO op_addt (void)
521 {
522     FT0 = float64_add(FT0, FT1, &FP_STATUS);
523     RETURN();
524 }
525
526 void OPPROTO op_subt (void)
527 {
528     FT0 = float64_sub(FT0, FT1, &FP_STATUS);
529     RETURN();
530 }
531
532 void OPPROTO op_mult (void)
533 {
534     FT0 = float64_mul(FT0, FT1, &FP_STATUS);
535     RETURN();
536 }
537
538 void OPPROTO op_divt (void)
539 {
540     FT0 = float64_div(FT0, FT1, &FP_STATUS);
541     RETURN();
542 }
543
544 void OPPROTO op_sqrtt (void)
545 {
546     helper_sqrtt();
547     RETURN();
548 }
549
550 void OPPROTO op_cmptun (void)
551 {
552     helper_cmptun();
553     RETURN();
554 }
555
556 void OPPROTO op_cmpteq (void)
557 {
558     helper_cmpteq();
559     RETURN();
560 }
561
562 void OPPROTO op_cmptle (void)
563 {
564     helper_cmptle();
565     RETURN();
566 }
567
568 void OPPROTO op_cmptlt (void)
569 {
570     helper_cmptlt();
571     RETURN();
572 }
573
574 void OPPROTO op_itoft (void)
575 {
576     helper_itoft();
577     RETURN();
578 }
579
580 void OPPROTO op_ftoit (void)
581 {
582     helper_ftoit();
583     RETURN();
584 }
585
586 /* VAX floating point arithmetic */
587 /* F floating */
588 void OPPROTO op_addf (void)
589 {
590     helper_addf();
591     RETURN();
592 }
593
594 void OPPROTO op_subf (void)
595 {
596     helper_subf();
597     RETURN();
598 }
599
600 void OPPROTO op_mulf (void)
601 {
602     helper_mulf();
603     RETURN();
604 }
605
606 void OPPROTO op_divf (void)
607 {
608     helper_divf();
609     RETURN();
610 }
611
612 void OPPROTO op_sqrtf (void)
613 {
614     helper_sqrtf();
615     RETURN();
616 }
617
618 void OPPROTO op_cmpfeq (void)
619 {
620     helper_cmpfeq();
621     RETURN();
622 }
623
624 void OPPROTO op_cmpfne (void)
625 {
626     helper_cmpfne();
627     RETURN();
628 }
629
630 void OPPROTO op_cmpflt (void)
631 {
632     helper_cmpflt();
633     RETURN();
634 }
635
636 void OPPROTO op_cmpfle (void)
637 {
638     helper_cmpfle();
639     RETURN();
640 }
641
642 void OPPROTO op_cmpfgt (void)
643 {
644     helper_cmpfgt();
645     RETURN();
646 }
647
648 void OPPROTO op_cmpfge (void)
649 {
650     helper_cmpfge();
651     RETURN();
652 }
653
654 void OPPROTO op_itoff (void)
655 {
656     helper_itoff();
657     RETURN();
658 }
659
660 /* G floating */
661 void OPPROTO op_addg (void)
662 {
663     helper_addg();
664     RETURN();
665 }
666
667 void OPPROTO op_subg (void)
668 {
669     helper_subg();
670     RETURN();
671 }
672
673 void OPPROTO op_mulg (void)
674 {
675     helper_mulg();
676     RETURN();
677 }
678
679 void OPPROTO op_divg (void)
680 {
681     helper_divg();
682     RETURN();
683 }
684
685 void OPPROTO op_sqrtg (void)
686 {
687     helper_sqrtg();
688     RETURN();
689 }
690
691 void OPPROTO op_cmpgeq (void)
692 {
693     helper_cmpgeq();
694     RETURN();
695 }
696
697 void OPPROTO op_cmpglt (void)
698 {
699     helper_cmpglt();
700     RETURN();
701 }
702
703 void OPPROTO op_cmpgle (void)
704 {
705     helper_cmpgle();
706     RETURN();
707 }
708
709 /* Floating point format conversion */
710 void OPPROTO op_cvtst (void)
711 {
712     FT0 = (float)FT0;
713     RETURN();
714 }
715
716 void OPPROTO op_cvtqs (void)
717 {
718     helper_cvtqs();
719     RETURN();
720 }
721
722 void OPPROTO op_cvtts (void)
723 {
724     FT0 = (float)FT0;
725     RETURN();
726 }
727
728 void OPPROTO op_cvttq (void)
729 {
730     helper_cvttq();
731     RETURN();
732 }
733
734 void OPPROTO op_cvtqt (void)
735 {
736     helper_cvtqt();
737     RETURN();
738 }
739
740 void OPPROTO op_cvtqf (void)
741 {
742     helper_cvtqf();
743     RETURN();
744 }
745
746 void OPPROTO op_cvtgf (void)
747 {
748     helper_cvtgf();
749     RETURN();
750 }
751
752 void OPPROTO op_cvtgd (void)
753 {
754     helper_cvtgd();
755     RETURN();
756 }
757
758 void OPPROTO op_cvtgq (void)
759 {
760     helper_cvtgq();
761     RETURN();
762 }
763
764 void OPPROTO op_cvtqg (void)
765 {
766     helper_cvtqg();
767     RETURN();
768 }
769
770 void OPPROTO op_cvtdg (void)
771 {
772     helper_cvtdg();
773     RETURN();
774 }
775
776 void OPPROTO op_cvtlq (void)
777 {
778     helper_cvtlq();
779     RETURN();
780 }
781
782 void OPPROTO op_cvtql (void)
783 {
784     helper_cvtql();
785     RETURN();
786 }
787
788 void OPPROTO op_cvtqlv (void)
789 {
790     helper_cvtqlv();
791     RETURN();
792 }
793
794 void OPPROTO op_cvtqlsv (void)
795 {
796     helper_cvtqlsv();
797     RETURN();
798 }
799
800 /* PALcode support special instructions */
801 #if !defined (CONFIG_USER_ONLY)
802 void OPPROTO op_hw_rei (void)
803 {
804     env->pc = env->ipr[IPR_EXC_ADDR] & ~3;
805     env->ipr[IPR_EXC_ADDR] = env->ipr[IPR_EXC_ADDR] & 1;
806     /* XXX: re-enable interrupts and memory mapping */
807     RETURN();
808 }
809
810 void OPPROTO op_hw_ret (void)
811 {
812     env->pc = T0 & ~3;
813     env->ipr[IPR_EXC_ADDR] = T0 & 1;
814     /* XXX: re-enable interrupts and memory mapping */
815     RETURN();
816 }
817
818 void OPPROTO op_mfpr (void)
819 {
820     helper_mfpr(PARAM(1));
821     RETURN();
822 }
823
824 void OPPROTO op_mtpr (void)
825 {
826     helper_mtpr(PARAM(1));
827     RETURN();
828 }
829
830 void OPPROTO op_set_alt_mode (void)
831 {
832     env->saved_mode = env->ps & 0xC;
833     env->ps = (env->ps & ~0xC) | (env->ipr[IPR_ALT_MODE] & 0xC);
834     RETURN();
835 }
836
837 void OPPROTO op_restore_mode (void)
838 {
839     env->ps = (env->ps & ~0xC) | env->saved_mode;
840     RETURN();
841 }
842
843 void OPPROTO op_ld_phys_to_virt (void)
844 {
845     helper_ld_phys_to_virt();
846     RETURN();
847 }
848
849 void OPPROTO op_st_phys_to_virt (void)
850 {
851     helper_st_phys_to_virt();
852     RETURN();
853 }
854 #endif /* !defined (CONFIG_USER_ONLY) */