]> git.proxmox.com Git - qemu.git/blob - target-ppc/op.c
Implement embedded PowerPC exceptions prefix and vectors registers.
[qemu.git] / target-ppc / op.c
1 /*
2 * PowerPC emulation micro-operations for qemu.
3 *
4 * Copyright (c) 2003-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 "op_helper.h"
26
27 #define REG 0
28 #include "op_template.h"
29
30 #define REG 1
31 #include "op_template.h"
32
33 #define REG 2
34 #include "op_template.h"
35
36 #define REG 3
37 #include "op_template.h"
38
39 #define REG 4
40 #include "op_template.h"
41
42 #define REG 5
43 #include "op_template.h"
44
45 #define REG 6
46 #include "op_template.h"
47
48 #define REG 7
49 #include "op_template.h"
50
51 #define REG 8
52 #include "op_template.h"
53
54 #define REG 9
55 #include "op_template.h"
56
57 #define REG 10
58 #include "op_template.h"
59
60 #define REG 11
61 #include "op_template.h"
62
63 #define REG 12
64 #include "op_template.h"
65
66 #define REG 13
67 #include "op_template.h"
68
69 #define REG 14
70 #include "op_template.h"
71
72 #define REG 15
73 #include "op_template.h"
74
75 #define REG 16
76 #include "op_template.h"
77
78 #define REG 17
79 #include "op_template.h"
80
81 #define REG 18
82 #include "op_template.h"
83
84 #define REG 19
85 #include "op_template.h"
86
87 #define REG 20
88 #include "op_template.h"
89
90 #define REG 21
91 #include "op_template.h"
92
93 #define REG 22
94 #include "op_template.h"
95
96 #define REG 23
97 #include "op_template.h"
98
99 #define REG 24
100 #include "op_template.h"
101
102 #define REG 25
103 #include "op_template.h"
104
105 #define REG 26
106 #include "op_template.h"
107
108 #define REG 27
109 #include "op_template.h"
110
111 #define REG 28
112 #include "op_template.h"
113
114 #define REG 29
115 #include "op_template.h"
116
117 #define REG 30
118 #include "op_template.h"
119
120 #define REG 31
121 #include "op_template.h"
122
123
124 void OPPROTO op_print_mem_EA (void)
125 {
126 do_print_mem_EA(T0);
127 RETURN();
128 }
129
130 /* PowerPC state maintenance operations */
131 /* set_Rc0 */
132 void OPPROTO op_set_Rc0 (void)
133 {
134 env->crf[0] = T0 | xer_so;
135 RETURN();
136 }
137
138 /* Set Rc1 (for floating point arithmetic) */
139 void OPPROTO op_set_Rc1 (void)
140 {
141 env->crf[1] = env->fpscr[7];
142 RETURN();
143 }
144
145 /* Constants load */
146 void OPPROTO op_reset_T0 (void)
147 {
148 T0 = 0;
149 RETURN();
150 }
151
152 void OPPROTO op_set_T0 (void)
153 {
154 T0 = (uint32_t)PARAM1;
155 RETURN();
156 }
157
158 #if defined(TARGET_PPC64)
159 void OPPROTO op_set_T0_64 (void)
160 {
161 T0 = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
162 RETURN();
163 }
164 #endif
165
166 void OPPROTO op_set_T1 (void)
167 {
168 T1 = (uint32_t)PARAM1;
169 RETURN();
170 }
171
172 #if defined(TARGET_PPC64)
173 void OPPROTO op_set_T1_64 (void)
174 {
175 T1 = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
176 RETURN();
177 }
178 #endif
179
180 #if 0 // unused
181 void OPPROTO op_set_T2 (void)
182 {
183 T2 = PARAM1;
184 RETURN();
185 }
186 #endif
187
188 void OPPROTO op_move_T1_T0 (void)
189 {
190 T1 = T0;
191 RETURN();
192 }
193
194 void OPPROTO op_move_T2_T0 (void)
195 {
196 T2 = T0;
197 RETURN();
198 }
199
200 /* Generate exceptions */
201 void OPPROTO op_raise_exception_err (void)
202 {
203 do_raise_exception_err(PARAM1, PARAM2);
204 }
205
206 void OPPROTO op_update_nip (void)
207 {
208 env->nip = (uint32_t)PARAM1;
209 RETURN();
210 }
211
212 #if defined(TARGET_PPC64)
213 void OPPROTO op_update_nip_64 (void)
214 {
215 env->nip = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
216 RETURN();
217 }
218 #endif
219
220 void OPPROTO op_debug (void)
221 {
222 do_raise_exception(EXCP_DEBUG);
223 }
224
225 void OPPROTO op_exit_tb (void)
226 {
227 EXIT_TB();
228 }
229
230 /* Load/store special registers */
231 void OPPROTO op_load_cr (void)
232 {
233 do_load_cr();
234 RETURN();
235 }
236
237 void OPPROTO op_store_cr (void)
238 {
239 do_store_cr(PARAM1);
240 RETURN();
241 }
242
243 void OPPROTO op_load_cro (void)
244 {
245 T0 = env->crf[PARAM1];
246 RETURN();
247 }
248
249 void OPPROTO op_store_cro (void)
250 {
251 env->crf[PARAM1] = T0;
252 RETURN();
253 }
254
255 void OPPROTO op_load_xer_cr (void)
256 {
257 T0 = (xer_so << 3) | (xer_ov << 2) | (xer_ca << 1);
258 RETURN();
259 }
260
261 void OPPROTO op_clear_xer_ov (void)
262 {
263 xer_so = 0;
264 xer_ov = 0;
265 RETURN();
266 }
267
268 void OPPROTO op_clear_xer_ca (void)
269 {
270 xer_ca = 0;
271 RETURN();
272 }
273
274 void OPPROTO op_load_xer_bc (void)
275 {
276 T1 = xer_bc;
277 RETURN();
278 }
279
280 void OPPROTO op_store_xer_bc (void)
281 {
282 xer_bc = T0;
283 RETURN();
284 }
285
286 void OPPROTO op_load_xer (void)
287 {
288 do_load_xer();
289 RETURN();
290 }
291
292 void OPPROTO op_store_xer (void)
293 {
294 do_store_xer();
295 RETURN();
296 }
297
298 #if defined(TARGET_PPC64)
299 void OPPROTO op_store_pri (void)
300 {
301 do_store_pri(PARAM1);
302 RETURN();
303 }
304 #endif
305
306 #if !defined(CONFIG_USER_ONLY)
307 /* Segment registers load and store */
308 void OPPROTO op_load_sr (void)
309 {
310 T0 = env->sr[T1];
311 RETURN();
312 }
313
314 void OPPROTO op_store_sr (void)
315 {
316 do_store_sr(env, T1, T0);
317 RETURN();
318 }
319
320 void OPPROTO op_load_sdr1 (void)
321 {
322 T0 = env->sdr1;
323 RETURN();
324 }
325
326 void OPPROTO op_store_sdr1 (void)
327 {
328 do_store_sdr1(env, T0);
329 RETURN();
330 }
331
332 #if defined (TARGET_PPC64)
333 void OPPROTO op_load_asr (void)
334 {
335 T0 = env->asr;
336 RETURN();
337 }
338
339 void OPPROTO op_store_asr (void)
340 {
341 ppc_store_asr(env, T0);
342 RETURN();
343 }
344 #endif
345
346 void OPPROTO op_load_msr (void)
347 {
348 T0 = do_load_msr(env);
349 RETURN();
350 }
351
352 void OPPROTO op_store_msr (void)
353 {
354 do_store_msr(env, T0);
355 RETURN();
356 }
357
358 void OPPROTO op_update_riee (void)
359 {
360 msr_ri = (T0 >> MSR_RI) & 1;
361 msr_ee = (T0 >> MSR_EE) & 1;
362 RETURN();
363 }
364
365 #if defined (TARGET_PPC64)
366 void OPPROTO op_store_msr_32 (void)
367 {
368 ppc_store_msr_32(env, T0);
369 RETURN();
370 }
371 #endif
372 #endif
373
374 /* SPR */
375 void OPPROTO op_load_spr (void)
376 {
377 T0 = env->spr[PARAM1];
378 RETURN();
379 }
380
381 void OPPROTO op_store_spr (void)
382 {
383 env->spr[PARAM1] = T0;
384 RETURN();
385 }
386
387 void OPPROTO op_load_dump_spr (void)
388 {
389 T0 = ppc_load_dump_spr(PARAM1);
390 RETURN();
391 }
392
393 void OPPROTO op_store_dump_spr (void)
394 {
395 ppc_store_dump_spr(PARAM1, T0);
396 RETURN();
397 }
398
399 void OPPROTO op_mask_spr (void)
400 {
401 env->spr[PARAM1] &= ~T0;
402 RETURN();
403 }
404
405 void OPPROTO op_load_lr (void)
406 {
407 T0 = env->lr;
408 RETURN();
409 }
410
411 void OPPROTO op_store_lr (void)
412 {
413 env->lr = T0;
414 RETURN();
415 }
416
417 void OPPROTO op_load_ctr (void)
418 {
419 T0 = env->ctr;
420 RETURN();
421 }
422
423 void OPPROTO op_store_ctr (void)
424 {
425 env->ctr = T0;
426 RETURN();
427 }
428
429 void OPPROTO op_load_tbl (void)
430 {
431 T0 = cpu_ppc_load_tbl(env);
432 RETURN();
433 }
434
435 void OPPROTO op_load_tbu (void)
436 {
437 T0 = cpu_ppc_load_tbu(env);
438 RETURN();
439 }
440
441 void OPPROTO op_load_atbl (void)
442 {
443 T0 = cpu_ppc_load_atbl(env);
444 RETURN();
445 }
446
447 void OPPROTO op_load_atbu (void)
448 {
449 T0 = cpu_ppc_load_atbu(env);
450 RETURN();
451 }
452
453 #if !defined(CONFIG_USER_ONLY)
454 void OPPROTO op_store_tbl (void)
455 {
456 cpu_ppc_store_tbl(env, T0);
457 RETURN();
458 }
459
460 void OPPROTO op_store_tbu (void)
461 {
462 cpu_ppc_store_tbu(env, T0);
463 RETURN();
464 }
465
466 void OPPROTO op_store_atbl (void)
467 {
468 cpu_ppc_store_atbl(env, T0);
469 RETURN();
470 }
471
472 void OPPROTO op_store_atbu (void)
473 {
474 cpu_ppc_store_atbu(env, T0);
475 RETURN();
476 }
477
478 void OPPROTO op_load_decr (void)
479 {
480 T0 = cpu_ppc_load_decr(env);
481 RETURN();
482 }
483
484 void OPPROTO op_store_decr (void)
485 {
486 cpu_ppc_store_decr(env, T0);
487 RETURN();
488 }
489
490 void OPPROTO op_load_ibat (void)
491 {
492 T0 = env->IBAT[PARAM1][PARAM2];
493 RETURN();
494 }
495
496 void OPPROTO op_store_ibatu (void)
497 {
498 do_store_ibatu(env, PARAM1, T0);
499 RETURN();
500 }
501
502 void OPPROTO op_store_ibatl (void)
503 {
504 #if 1
505 env->IBAT[1][PARAM1] = T0;
506 #else
507 do_store_ibatl(env, PARAM1, T0);
508 #endif
509 RETURN();
510 }
511
512 void OPPROTO op_load_dbat (void)
513 {
514 T0 = env->DBAT[PARAM1][PARAM2];
515 RETURN();
516 }
517
518 void OPPROTO op_store_dbatu (void)
519 {
520 do_store_dbatu(env, PARAM1, T0);
521 RETURN();
522 }
523
524 void OPPROTO op_store_dbatl (void)
525 {
526 #if 1
527 env->DBAT[1][PARAM1] = T0;
528 #else
529 do_store_dbatl(env, PARAM1, T0);
530 #endif
531 RETURN();
532 }
533 #endif /* !defined(CONFIG_USER_ONLY) */
534
535 /* FPSCR */
536 void OPPROTO op_load_fpscr (void)
537 {
538 do_load_fpscr();
539 RETURN();
540 }
541
542 void OPPROTO op_store_fpscr (void)
543 {
544 do_store_fpscr(PARAM1);
545 RETURN();
546 }
547
548 void OPPROTO op_reset_scrfx (void)
549 {
550 env->fpscr[7] &= ~0x8;
551 RETURN();
552 }
553
554 /* crf operations */
555 void OPPROTO op_getbit_T0 (void)
556 {
557 T0 = (T0 >> PARAM1) & 1;
558 RETURN();
559 }
560
561 void OPPROTO op_getbit_T1 (void)
562 {
563 T1 = (T1 >> PARAM1) & 1;
564 RETURN();
565 }
566
567 void OPPROTO op_setcrfbit (void)
568 {
569 T1 = (T1 & PARAM1) | (T0 << PARAM2);
570 RETURN();
571 }
572
573 /* Branch */
574 #define EIP env->nip
575
576 void OPPROTO op_setlr (void)
577 {
578 env->lr = (uint32_t)PARAM1;
579 RETURN();
580 }
581
582 #if defined (TARGET_PPC64)
583 void OPPROTO op_setlr_64 (void)
584 {
585 env->lr = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
586 RETURN();
587 }
588 #endif
589
590 void OPPROTO op_goto_tb0 (void)
591 {
592 GOTO_TB(op_goto_tb0, PARAM1, 0);
593 }
594
595 void OPPROTO op_goto_tb1 (void)
596 {
597 GOTO_TB(op_goto_tb1, PARAM1, 1);
598 }
599
600 void OPPROTO op_b_T1 (void)
601 {
602 env->nip = (uint32_t)(T1 & ~3);
603 RETURN();
604 }
605
606 #if defined (TARGET_PPC64)
607 void OPPROTO op_b_T1_64 (void)
608 {
609 env->nip = (uint64_t)(T1 & ~3);
610 RETURN();
611 }
612 #endif
613
614 void OPPROTO op_jz_T0 (void)
615 {
616 if (!T0)
617 GOTO_LABEL_PARAM(1);
618 RETURN();
619 }
620
621 void OPPROTO op_btest_T1 (void)
622 {
623 if (T0) {
624 env->nip = (uint32_t)(T1 & ~3);
625 } else {
626 env->nip = (uint32_t)PARAM1;
627 }
628 RETURN();
629 }
630
631 #if defined (TARGET_PPC64)
632 void OPPROTO op_btest_T1_64 (void)
633 {
634 if (T0) {
635 env->nip = (uint64_t)(T1 & ~3);
636 } else {
637 env->nip = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
638 }
639 RETURN();
640 }
641 #endif
642
643 void OPPROTO op_movl_T1_ctr (void)
644 {
645 T1 = env->ctr;
646 RETURN();
647 }
648
649 void OPPROTO op_movl_T1_lr (void)
650 {
651 T1 = env->lr;
652 RETURN();
653 }
654
655 /* tests with result in T0 */
656 void OPPROTO op_test_ctr (void)
657 {
658 T0 = (uint32_t)env->ctr;
659 RETURN();
660 }
661
662 #if defined(TARGET_PPC64)
663 void OPPROTO op_test_ctr_64 (void)
664 {
665 T0 = (uint64_t)env->ctr;
666 RETURN();
667 }
668 #endif
669
670 void OPPROTO op_test_ctr_true (void)
671 {
672 T0 = ((uint32_t)env->ctr != 0 && (T0 & PARAM1) != 0);
673 RETURN();
674 }
675
676 #if defined(TARGET_PPC64)
677 void OPPROTO op_test_ctr_true_64 (void)
678 {
679 T0 = ((uint64_t)env->ctr != 0 && (T0 & PARAM1) != 0);
680 RETURN();
681 }
682 #endif
683
684 void OPPROTO op_test_ctr_false (void)
685 {
686 T0 = ((uint32_t)env->ctr != 0 && (T0 & PARAM1) == 0);
687 RETURN();
688 }
689
690 #if defined(TARGET_PPC64)
691 void OPPROTO op_test_ctr_false_64 (void)
692 {
693 T0 = ((uint64_t)env->ctr != 0 && (T0 & PARAM1) == 0);
694 RETURN();
695 }
696 #endif
697
698 void OPPROTO op_test_ctrz (void)
699 {
700 T0 = ((uint32_t)env->ctr == 0);
701 RETURN();
702 }
703
704 #if defined(TARGET_PPC64)
705 void OPPROTO op_test_ctrz_64 (void)
706 {
707 T0 = ((uint64_t)env->ctr == 0);
708 RETURN();
709 }
710 #endif
711
712 void OPPROTO op_test_ctrz_true (void)
713 {
714 T0 = ((uint32_t)env->ctr == 0 && (T0 & PARAM1) != 0);
715 RETURN();
716 }
717
718 #if defined(TARGET_PPC64)
719 void OPPROTO op_test_ctrz_true_64 (void)
720 {
721 T0 = ((uint64_t)env->ctr == 0 && (T0 & PARAM1) != 0);
722 RETURN();
723 }
724 #endif
725
726 void OPPROTO op_test_ctrz_false (void)
727 {
728 T0 = ((uint32_t)env->ctr == 0 && (T0 & PARAM1) == 0);
729 RETURN();
730 }
731
732 #if defined(TARGET_PPC64)
733 void OPPROTO op_test_ctrz_false_64 (void)
734 {
735 T0 = ((uint64_t)env->ctr == 0 && (T0 & PARAM1) == 0);
736 RETURN();
737 }
738 #endif
739
740 void OPPROTO op_test_true (void)
741 {
742 T0 = (T0 & PARAM1);
743 RETURN();
744 }
745
746 void OPPROTO op_test_false (void)
747 {
748 T0 = ((T0 & PARAM1) == 0);
749 RETURN();
750 }
751
752 /* CTR maintenance */
753 void OPPROTO op_dec_ctr (void)
754 {
755 env->ctr--;
756 RETURN();
757 }
758
759 /*** Integer arithmetic ***/
760 /* add */
761 void OPPROTO op_add (void)
762 {
763 T0 += T1;
764 RETURN();
765 }
766
767 void OPPROTO op_check_addo (void)
768 {
769 if (likely(!(((uint32_t)T2 ^ (uint32_t)T1 ^ UINT32_MAX) &
770 ((uint32_t)T2 ^ (uint32_t)T0) & (1UL << 31)))) {
771 xer_ov = 0;
772 } else {
773 xer_ov = 1;
774 xer_so = 1;
775 }
776 RETURN();
777 }
778
779 #if defined(TARGET_PPC64)
780 void OPPROTO op_check_addo_64 (void)
781 {
782 if (likely(!(((uint64_t)T2 ^ (uint64_t)T1 ^ UINT64_MAX) &
783 ((uint64_t)T2 ^ (uint64_t)T0) & (1ULL << 63)))) {
784 xer_ov = 0;
785 } else {
786 xer_ov = 1;
787 xer_so = 1;
788 }
789 RETURN();
790 }
791 #endif
792
793 /* add carrying */
794 void OPPROTO op_check_addc (void)
795 {
796 if (likely((uint32_t)T0 >= (uint32_t)T2)) {
797 xer_ca = 0;
798 } else {
799 xer_ca = 1;
800 }
801 RETURN();
802 }
803
804 #if defined(TARGET_PPC64)
805 void OPPROTO op_check_addc_64 (void)
806 {
807 if (likely((uint64_t)T0 >= (uint64_t)T2)) {
808 xer_ca = 0;
809 } else {
810 xer_ca = 1;
811 }
812 RETURN();
813 }
814 #endif
815
816 /* add extended */
817 void OPPROTO op_adde (void)
818 {
819 do_adde();
820 RETURN();
821 }
822
823 #if defined(TARGET_PPC64)
824 void OPPROTO op_adde_64 (void)
825 {
826 do_adde_64();
827 RETURN();
828 }
829 #endif
830
831 /* add immediate */
832 void OPPROTO op_addi (void)
833 {
834 T0 += (int32_t)PARAM1;
835 RETURN();
836 }
837
838 /* add to minus one extended */
839 void OPPROTO op_add_me (void)
840 {
841 T0 += xer_ca + (-1);
842 if (likely((uint32_t)T1 != 0))
843 xer_ca = 1;
844 RETURN();
845 }
846
847 #if defined(TARGET_PPC64)
848 void OPPROTO op_add_me_64 (void)
849 {
850 T0 += xer_ca + (-1);
851 if (likely((uint64_t)T1 != 0))
852 xer_ca = 1;
853 RETURN();
854 }
855 #endif
856
857 void OPPROTO op_addmeo (void)
858 {
859 do_addmeo();
860 RETURN();
861 }
862
863 void OPPROTO op_addmeo_64 (void)
864 {
865 do_addmeo();
866 RETURN();
867 }
868
869 /* add to zero extended */
870 void OPPROTO op_add_ze (void)
871 {
872 T0 += xer_ca;
873 RETURN();
874 }
875
876 /* divide word */
877 void OPPROTO op_divw (void)
878 {
879 if (unlikely(((int32_t)T0 == INT32_MIN && (int32_t)T1 == -1) ||
880 (int32_t)T1 == 0)) {
881 T0 = (int32_t)((-1) * ((uint32_t)T0 >> 31));
882 } else {
883 T0 = (int32_t)T0 / (int32_t)T1;
884 }
885 RETURN();
886 }
887
888 #if defined(TARGET_PPC64)
889 void OPPROTO op_divd (void)
890 {
891 if (unlikely(((int64_t)T0 == INT64_MIN && (int64_t)T1 == -1) ||
892 (int64_t)T1 == 0)) {
893 T0 = (int64_t)((-1ULL) * ((uint64_t)T0 >> 63));
894 } else {
895 T0 = (int64_t)T0 / (int64_t)T1;
896 }
897 RETURN();
898 }
899 #endif
900
901 void OPPROTO op_divwo (void)
902 {
903 do_divwo();
904 RETURN();
905 }
906
907 #if defined(TARGET_PPC64)
908 void OPPROTO op_divdo (void)
909 {
910 do_divdo();
911 RETURN();
912 }
913 #endif
914
915 /* divide word unsigned */
916 void OPPROTO op_divwu (void)
917 {
918 if (unlikely(T1 == 0)) {
919 T0 = 0;
920 } else {
921 T0 = (uint32_t)T0 / (uint32_t)T1;
922 }
923 RETURN();
924 }
925
926 #if defined(TARGET_PPC64)
927 void OPPROTO op_divdu (void)
928 {
929 if (unlikely(T1 == 0)) {
930 T0 = 0;
931 } else {
932 T0 /= T1;
933 }
934 RETURN();
935 }
936 #endif
937
938 void OPPROTO op_divwuo (void)
939 {
940 do_divwuo();
941 RETURN();
942 }
943
944 #if defined(TARGET_PPC64)
945 void OPPROTO op_divduo (void)
946 {
947 do_divduo();
948 RETURN();
949 }
950 #endif
951
952 /* multiply high word */
953 void OPPROTO op_mulhw (void)
954 {
955 T0 = ((int64_t)((int32_t)T0) * (int64_t)((int32_t)T1)) >> 32;
956 RETURN();
957 }
958
959 #if defined(TARGET_PPC64)
960 void OPPROTO op_mulhd (void)
961 {
962 uint64_t tl, th;
963
964 do_imul64(&tl, &th);
965 T0 = th;
966 RETURN();
967 }
968 #endif
969
970 /* multiply high word unsigned */
971 void OPPROTO op_mulhwu (void)
972 {
973 T0 = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1) >> 32;
974 RETURN();
975 }
976
977 #if defined(TARGET_PPC64)
978 void OPPROTO op_mulhdu (void)
979 {
980 uint64_t tl, th;
981
982 do_mul64(&tl, &th);
983 T0 = th;
984 RETURN();
985 }
986 #endif
987
988 /* multiply low immediate */
989 void OPPROTO op_mulli (void)
990 {
991 T0 = ((int32_t)T0 * (int32_t)PARAM1);
992 RETURN();
993 }
994
995 /* multiply low word */
996 void OPPROTO op_mullw (void)
997 {
998 T0 = (int32_t)(T0 * T1);
999 RETURN();
1000 }
1001
1002 #if defined(TARGET_PPC64)
1003 void OPPROTO op_mulld (void)
1004 {
1005 T0 *= T1;
1006 RETURN();
1007 }
1008 #endif
1009
1010 void OPPROTO op_mullwo (void)
1011 {
1012 do_mullwo();
1013 RETURN();
1014 }
1015
1016 #if defined(TARGET_PPC64)
1017 void OPPROTO op_mulldo (void)
1018 {
1019 do_mulldo();
1020 RETURN();
1021 }
1022 #endif
1023
1024 /* negate */
1025 void OPPROTO op_neg (void)
1026 {
1027 if (likely(T0 != INT32_MIN)) {
1028 T0 = -(int32_t)T0;
1029 }
1030 RETURN();
1031 }
1032
1033 #if defined(TARGET_PPC64)
1034 void OPPROTO op_neg_64 (void)
1035 {
1036 if (likely(T0 != INT64_MIN)) {
1037 T0 = -(int64_t)T0;
1038 }
1039 RETURN();
1040 }
1041 #endif
1042
1043 void OPPROTO op_nego (void)
1044 {
1045 do_nego();
1046 RETURN();
1047 }
1048
1049 #if defined(TARGET_PPC64)
1050 void OPPROTO op_nego_64 (void)
1051 {
1052 do_nego_64();
1053 RETURN();
1054 }
1055 #endif
1056
1057 /* subtract from */
1058 void OPPROTO op_subf (void)
1059 {
1060 T0 = T1 - T0;
1061 RETURN();
1062 }
1063
1064 void OPPROTO op_check_subfo (void)
1065 {
1066 if (likely(!(((uint32_t)(~T2) ^ (uint32_t)T1 ^ UINT32_MAX) &
1067 ((uint32_t)(~T2) ^ (uint32_t)T0) & (1UL << 31)))) {
1068 xer_ov = 0;
1069 } else {
1070 xer_ov = 1;
1071 xer_so = 1;
1072 }
1073 RETURN();
1074 }
1075
1076 #if defined(TARGET_PPC64)
1077 void OPPROTO op_check_subfo_64 (void)
1078 {
1079 if (likely(!(((uint64_t)(~T2) ^ (uint64_t)T1 ^ UINT64_MAX) &
1080 ((uint64_t)(~T2) ^ (uint64_t)T0) & (1ULL << 63)))) {
1081 xer_ov = 0;
1082 } else {
1083 xer_ov = 1;
1084 xer_so = 1;
1085 }
1086 RETURN();
1087 }
1088 #endif
1089
1090 /* subtract from carrying */
1091 void OPPROTO op_check_subfc (void)
1092 {
1093 if (likely((uint32_t)T0 > (uint32_t)T1)) {
1094 xer_ca = 0;
1095 } else {
1096 xer_ca = 1;
1097 }
1098 RETURN();
1099 }
1100
1101 #if defined(TARGET_PPC64)
1102 void OPPROTO op_check_subfc_64 (void)
1103 {
1104 if (likely((uint64_t)T0 > (uint64_t)T1)) {
1105 xer_ca = 0;
1106 } else {
1107 xer_ca = 1;
1108 }
1109 RETURN();
1110 }
1111 #endif
1112
1113 /* subtract from extended */
1114 void OPPROTO op_subfe (void)
1115 {
1116 do_subfe();
1117 RETURN();
1118 }
1119
1120 #if defined(TARGET_PPC64)
1121 void OPPROTO op_subfe_64 (void)
1122 {
1123 do_subfe_64();
1124 RETURN();
1125 }
1126 #endif
1127
1128 /* subtract from immediate carrying */
1129 void OPPROTO op_subfic (void)
1130 {
1131 T0 = (int32_t)PARAM1 + ~T0 + 1;
1132 if ((uint32_t)T0 <= (uint32_t)PARAM1) {
1133 xer_ca = 1;
1134 } else {
1135 xer_ca = 0;
1136 }
1137 RETURN();
1138 }
1139
1140 #if defined(TARGET_PPC64)
1141 void OPPROTO op_subfic_64 (void)
1142 {
1143 T0 = PARAM1 + ~T0 + 1;
1144 if ((uint64_t)T0 <= (uint64_t)PARAM1) {
1145 xer_ca = 1;
1146 } else {
1147 xer_ca = 0;
1148 }
1149 RETURN();
1150 }
1151 #endif
1152
1153 /* subtract from minus one extended */
1154 void OPPROTO op_subfme (void)
1155 {
1156 T0 = ~T0 + xer_ca - 1;
1157 if (likely((uint32_t)T0 != (uint32_t)-1))
1158 xer_ca = 1;
1159 RETURN();
1160 }
1161
1162 #if defined(TARGET_PPC64)
1163 void OPPROTO op_subfme_64 (void)
1164 {
1165 T0 = ~T0 + xer_ca - 1;
1166 if (likely((uint64_t)T0 != (uint64_t)-1))
1167 xer_ca = 1;
1168 RETURN();
1169 }
1170 #endif
1171
1172 void OPPROTO op_subfmeo (void)
1173 {
1174 do_subfmeo();
1175 RETURN();
1176 }
1177
1178 #if defined(TARGET_PPC64)
1179 void OPPROTO op_subfmeo_64 (void)
1180 {
1181 do_subfmeo_64();
1182 RETURN();
1183 }
1184 #endif
1185
1186 /* subtract from zero extended */
1187 void OPPROTO op_subfze (void)
1188 {
1189 T1 = ~T0;
1190 T0 = T1 + xer_ca;
1191 if ((uint32_t)T0 < (uint32_t)T1) {
1192 xer_ca = 1;
1193 } else {
1194 xer_ca = 0;
1195 }
1196 RETURN();
1197 }
1198
1199 #if defined(TARGET_PPC64)
1200 void OPPROTO op_subfze_64 (void)
1201 {
1202 T1 = ~T0;
1203 T0 = T1 + xer_ca;
1204 if ((uint64_t)T0 < (uint64_t)T1) {
1205 xer_ca = 1;
1206 } else {
1207 xer_ca = 0;
1208 }
1209 RETURN();
1210 }
1211 #endif
1212
1213 void OPPROTO op_subfzeo (void)
1214 {
1215 do_subfzeo();
1216 RETURN();
1217 }
1218
1219 #if defined(TARGET_PPC64)
1220 void OPPROTO op_subfzeo_64 (void)
1221 {
1222 do_subfzeo_64();
1223 RETURN();
1224 }
1225 #endif
1226
1227 /*** Integer comparison ***/
1228 /* compare */
1229 void OPPROTO op_cmp (void)
1230 {
1231 if ((int32_t)T0 < (int32_t)T1) {
1232 T0 = 0x08;
1233 } else if ((int32_t)T0 > (int32_t)T1) {
1234 T0 = 0x04;
1235 } else {
1236 T0 = 0x02;
1237 }
1238 T0 |= xer_so;
1239 RETURN();
1240 }
1241
1242 #if defined(TARGET_PPC64)
1243 void OPPROTO op_cmp_64 (void)
1244 {
1245 if ((int64_t)T0 < (int64_t)T1) {
1246 T0 = 0x08;
1247 } else if ((int64_t)T0 > (int64_t)T1) {
1248 T0 = 0x04;
1249 } else {
1250 T0 = 0x02;
1251 }
1252 T0 |= xer_so;
1253 RETURN();
1254 }
1255 #endif
1256
1257 /* compare immediate */
1258 void OPPROTO op_cmpi (void)
1259 {
1260 if ((int32_t)T0 < (int32_t)PARAM1) {
1261 T0 = 0x08;
1262 } else if ((int32_t)T0 > (int32_t)PARAM1) {
1263 T0 = 0x04;
1264 } else {
1265 T0 = 0x02;
1266 }
1267 T0 |= xer_so;
1268 RETURN();
1269 }
1270
1271 #if defined(TARGET_PPC64)
1272 void OPPROTO op_cmpi_64 (void)
1273 {
1274 if ((int64_t)T0 < (int64_t)((int32_t)PARAM1)) {
1275 T0 = 0x08;
1276 } else if ((int64_t)T0 > (int64_t)((int32_t)PARAM1)) {
1277 T0 = 0x04;
1278 } else {
1279 T0 = 0x02;
1280 }
1281 T0 |= xer_so;
1282 RETURN();
1283 }
1284 #endif
1285
1286 /* compare logical */
1287 void OPPROTO op_cmpl (void)
1288 {
1289 if ((uint32_t)T0 < (uint32_t)T1) {
1290 T0 = 0x08;
1291 } else if ((uint32_t)T0 > (uint32_t)T1) {
1292 T0 = 0x04;
1293 } else {
1294 T0 = 0x02;
1295 }
1296 T0 |= xer_so;
1297 RETURN();
1298 }
1299
1300 #if defined(TARGET_PPC64)
1301 void OPPROTO op_cmpl_64 (void)
1302 {
1303 if ((uint64_t)T0 < (uint64_t)T1) {
1304 T0 = 0x08;
1305 } else if ((uint64_t)T0 > (uint64_t)T1) {
1306 T0 = 0x04;
1307 } else {
1308 T0 = 0x02;
1309 }
1310 T0 |= xer_so;
1311 RETURN();
1312 }
1313 #endif
1314
1315 /* compare logical immediate */
1316 void OPPROTO op_cmpli (void)
1317 {
1318 if ((uint32_t)T0 < (uint32_t)PARAM1) {
1319 T0 = 0x08;
1320 } else if ((uint32_t)T0 > (uint32_t)PARAM1) {
1321 T0 = 0x04;
1322 } else {
1323 T0 = 0x02;
1324 }
1325 T0 |= xer_so;
1326 RETURN();
1327 }
1328
1329 #if defined(TARGET_PPC64)
1330 void OPPROTO op_cmpli_64 (void)
1331 {
1332 if ((uint64_t)T0 < (uint64_t)PARAM1) {
1333 T0 = 0x08;
1334 } else if ((uint64_t)T0 > (uint64_t)PARAM1) {
1335 T0 = 0x04;
1336 } else {
1337 T0 = 0x02;
1338 }
1339 T0 |= xer_so;
1340 RETURN();
1341 }
1342 #endif
1343
1344 void OPPROTO op_isel (void)
1345 {
1346 if (T0)
1347 T0 = T1;
1348 else
1349 T0 = T2;
1350 RETURN();
1351 }
1352
1353 void OPPROTO op_popcntb (void)
1354 {
1355 do_popcntb();
1356 RETURN();
1357 }
1358
1359 #if defined(TARGET_PPC64)
1360 void OPPROTO op_popcntb_64 (void)
1361 {
1362 do_popcntb_64();
1363 RETURN();
1364 }
1365 #endif
1366
1367 /*** Integer logical ***/
1368 /* and */
1369 void OPPROTO op_and (void)
1370 {
1371 T0 &= T1;
1372 RETURN();
1373 }
1374
1375 /* andc */
1376 void OPPROTO op_andc (void)
1377 {
1378 T0 &= ~T1;
1379 RETURN();
1380 }
1381
1382 /* andi. */
1383 void OPPROTO op_andi_T0 (void)
1384 {
1385 T0 &= PARAM1;
1386 RETURN();
1387 }
1388
1389 void OPPROTO op_andi_T1 (void)
1390 {
1391 T1 &= PARAM1;
1392 RETURN();
1393 }
1394
1395 #if defined(TARGET_PPC64)
1396 void OPPROTO op_andi_T0_64 (void)
1397 {
1398 T0 &= ((uint64_t)PARAM1 << 32) | PARAM2;
1399 RETURN();
1400 }
1401
1402 void OPPROTO op_andi_T1_64 (void)
1403 {
1404 T1 &= ((uint64_t)PARAM1 << 32) | PARAM2;
1405 RETURN();
1406 }
1407 #endif
1408
1409
1410 /* count leading zero */
1411 void OPPROTO op_cntlzw (void)
1412 {
1413 T0 = _do_cntlzw(T0);
1414 RETURN();
1415 }
1416
1417 #if defined(TARGET_PPC64)
1418 void OPPROTO op_cntlzd (void)
1419 {
1420 T0 = _do_cntlzd(T0);
1421 RETURN();
1422 }
1423 #endif
1424
1425 /* eqv */
1426 void OPPROTO op_eqv (void)
1427 {
1428 T0 = ~(T0 ^ T1);
1429 RETURN();
1430 }
1431
1432 /* extend sign byte */
1433 void OPPROTO op_extsb (void)
1434 {
1435 #if defined (TARGET_PPC64)
1436 T0 = (int64_t)((int8_t)T0);
1437 #else
1438 T0 = (int32_t)((int8_t)T0);
1439 #endif
1440 RETURN();
1441 }
1442
1443 /* extend sign half word */
1444 void OPPROTO op_extsh (void)
1445 {
1446 #if defined (TARGET_PPC64)
1447 T0 = (int64_t)((int16_t)T0);
1448 #else
1449 T0 = (int32_t)((int16_t)T0);
1450 #endif
1451 RETURN();
1452 }
1453
1454 #if defined (TARGET_PPC64)
1455 void OPPROTO op_extsw (void)
1456 {
1457 T0 = (int64_t)((int32_t)T0);
1458 RETURN();
1459 }
1460 #endif
1461
1462 /* nand */
1463 void OPPROTO op_nand (void)
1464 {
1465 T0 = ~(T0 & T1);
1466 RETURN();
1467 }
1468
1469 /* nor */
1470 void OPPROTO op_nor (void)
1471 {
1472 T0 = ~(T0 | T1);
1473 RETURN();
1474 }
1475
1476 /* or */
1477 void OPPROTO op_or (void)
1478 {
1479 T0 |= T1;
1480 RETURN();
1481 }
1482
1483 /* orc */
1484 void OPPROTO op_orc (void)
1485 {
1486 T0 |= ~T1;
1487 RETURN();
1488 }
1489
1490 /* ori */
1491 void OPPROTO op_ori (void)
1492 {
1493 T0 |= PARAM1;
1494 RETURN();
1495 }
1496
1497 /* xor */
1498 void OPPROTO op_xor (void)
1499 {
1500 T0 ^= T1;
1501 RETURN();
1502 }
1503
1504 /* xori */
1505 void OPPROTO op_xori (void)
1506 {
1507 T0 ^= PARAM1;
1508 RETURN();
1509 }
1510
1511 /*** Integer rotate ***/
1512 void OPPROTO op_rotl32_T0_T1 (void)
1513 {
1514 T0 = rotl32(T0, T1 & 0x1F);
1515 RETURN();
1516 }
1517
1518 void OPPROTO op_rotli32_T0 (void)
1519 {
1520 T0 = rotl32(T0, PARAM1);
1521 RETURN();
1522 }
1523
1524 #if defined(TARGET_PPC64)
1525 void OPPROTO op_rotl64_T0_T1 (void)
1526 {
1527 T0 = rotl64(T0, T1 & 0x3F);
1528 RETURN();
1529 }
1530
1531 void OPPROTO op_rotli64_T0 (void)
1532 {
1533 T0 = rotl64(T0, PARAM1);
1534 RETURN();
1535 }
1536 #endif
1537
1538 /*** Integer shift ***/
1539 /* shift left word */
1540 void OPPROTO op_slw (void)
1541 {
1542 if (T1 & 0x20) {
1543 T0 = 0;
1544 } else {
1545 T0 = (uint32_t)(T0 << T1);
1546 }
1547 RETURN();
1548 }
1549
1550 #if defined(TARGET_PPC64)
1551 void OPPROTO op_sld (void)
1552 {
1553 if (T1 & 0x40) {
1554 T0 = 0;
1555 } else {
1556 T0 = T0 << T1;
1557 }
1558 RETURN();
1559 }
1560 #endif
1561
1562 /* shift right algebraic word */
1563 void OPPROTO op_sraw (void)
1564 {
1565 do_sraw();
1566 RETURN();
1567 }
1568
1569 #if defined(TARGET_PPC64)
1570 void OPPROTO op_srad (void)
1571 {
1572 do_srad();
1573 RETURN();
1574 }
1575 #endif
1576
1577 /* shift right algebraic word immediate */
1578 void OPPROTO op_srawi (void)
1579 {
1580 uint32_t mask = (uint32_t)PARAM2;
1581
1582 T0 = (int32_t)T0 >> PARAM1;
1583 if ((int32_t)T1 < 0 && (T1 & mask) != 0) {
1584 xer_ca = 1;
1585 } else {
1586 xer_ca = 0;
1587 }
1588 RETURN();
1589 }
1590
1591 #if defined(TARGET_PPC64)
1592 void OPPROTO op_sradi (void)
1593 {
1594 uint64_t mask = ((uint64_t)PARAM2 << 32) | (uint64_t)PARAM3;
1595
1596 T0 = (int64_t)T0 >> PARAM1;
1597 if ((int64_t)T1 < 0 && ((uint64_t)T1 & mask) != 0) {
1598 xer_ca = 1;
1599 } else {
1600 xer_ca = 0;
1601 }
1602 RETURN();
1603 }
1604 #endif
1605
1606 /* shift right word */
1607 void OPPROTO op_srw (void)
1608 {
1609 if (T1 & 0x20) {
1610 T0 = 0;
1611 } else {
1612 T0 = (uint32_t)T0 >> T1;
1613 }
1614 RETURN();
1615 }
1616
1617 #if defined(TARGET_PPC64)
1618 void OPPROTO op_srd (void)
1619 {
1620 if (T1 & 0x40) {
1621 T0 = 0;
1622 } else {
1623 T0 = (uint64_t)T0 >> T1;
1624 }
1625 RETURN();
1626 }
1627 #endif
1628
1629 void OPPROTO op_sl_T0_T1 (void)
1630 {
1631 T0 = T0 << T1;
1632 RETURN();
1633 }
1634
1635 void OPPROTO op_sli_T0 (void)
1636 {
1637 T0 = T0 << PARAM1;
1638 RETURN();
1639 }
1640
1641 void OPPROTO op_srl_T0_T1 (void)
1642 {
1643 T0 = (uint32_t)T0 >> T1;
1644 RETURN();
1645 }
1646
1647 #if defined(TARGET_PPC64)
1648 void OPPROTO op_srl_T0_T1_64 (void)
1649 {
1650 T0 = (uint32_t)T0 >> T1;
1651 RETURN();
1652 }
1653 #endif
1654
1655 void OPPROTO op_srli_T0 (void)
1656 {
1657 T0 = (uint32_t)T0 >> PARAM1;
1658 RETURN();
1659 }
1660
1661 #if defined(TARGET_PPC64)
1662 void OPPROTO op_srli_T0_64 (void)
1663 {
1664 T0 = (uint64_t)T0 >> PARAM1;
1665 RETURN();
1666 }
1667 #endif
1668
1669 void OPPROTO op_srli_T1 (void)
1670 {
1671 T1 = (uint32_t)T1 >> PARAM1;
1672 RETURN();
1673 }
1674
1675 #if defined(TARGET_PPC64)
1676 void OPPROTO op_srli_T1_64 (void)
1677 {
1678 T1 = (uint64_t)T1 >> PARAM1;
1679 RETURN();
1680 }
1681 #endif
1682
1683 /*** Floating-Point arithmetic ***/
1684 /* fadd - fadd. */
1685 void OPPROTO op_fadd (void)
1686 {
1687 FT0 = float64_add(FT0, FT1, &env->fp_status);
1688 RETURN();
1689 }
1690
1691 /* fsub - fsub. */
1692 void OPPROTO op_fsub (void)
1693 {
1694 FT0 = float64_sub(FT0, FT1, &env->fp_status);
1695 RETURN();
1696 }
1697
1698 /* fmul - fmul. */
1699 void OPPROTO op_fmul (void)
1700 {
1701 FT0 = float64_mul(FT0, FT1, &env->fp_status);
1702 RETURN();
1703 }
1704
1705 /* fdiv - fdiv. */
1706 void OPPROTO op_fdiv (void)
1707 {
1708 FT0 = float64_div(FT0, FT1, &env->fp_status);
1709 RETURN();
1710 }
1711
1712 /* fsqrt - fsqrt. */
1713 void OPPROTO op_fsqrt (void)
1714 {
1715 do_fsqrt();
1716 RETURN();
1717 }
1718
1719 /* fre - fre. */
1720 void OPPROTO op_fre (void)
1721 {
1722 do_fre();
1723 RETURN();
1724 }
1725
1726 /* fres - fres. */
1727 void OPPROTO op_fres (void)
1728 {
1729 do_fres();
1730 RETURN();
1731 }
1732
1733 /* frsqrte - frsqrte. */
1734 void OPPROTO op_frsqrte (void)
1735 {
1736 do_frsqrte();
1737 RETURN();
1738 }
1739
1740 /* fsel - fsel. */
1741 void OPPROTO op_fsel (void)
1742 {
1743 do_fsel();
1744 RETURN();
1745 }
1746
1747 /*** Floating-Point multiply-and-add ***/
1748 /* fmadd - fmadd. */
1749 void OPPROTO op_fmadd (void)
1750 {
1751 #if USE_PRECISE_EMULATION
1752 do_fmadd();
1753 #else
1754 FT0 = float64_mul(FT0, FT1, &env->fp_status);
1755 FT0 = float64_add(FT0, FT2, &env->fp_status);
1756 #endif
1757 RETURN();
1758 }
1759
1760 /* fmsub - fmsub. */
1761 void OPPROTO op_fmsub (void)
1762 {
1763 #if USE_PRECISE_EMULATION
1764 do_fmsub();
1765 #else
1766 FT0 = float64_mul(FT0, FT1, &env->fp_status);
1767 FT0 = float64_sub(FT0, FT2, &env->fp_status);
1768 #endif
1769 RETURN();
1770 }
1771
1772 /* fnmadd - fnmadd. - fnmadds - fnmadds. */
1773 void OPPROTO op_fnmadd (void)
1774 {
1775 do_fnmadd();
1776 RETURN();
1777 }
1778
1779 /* fnmsub - fnmsub. */
1780 void OPPROTO op_fnmsub (void)
1781 {
1782 do_fnmsub();
1783 RETURN();
1784 }
1785
1786 /*** Floating-Point round & convert ***/
1787 /* frsp - frsp. */
1788 void OPPROTO op_frsp (void)
1789 {
1790 FT0 = float64_to_float32(FT0, &env->fp_status);
1791 RETURN();
1792 }
1793
1794 /* fctiw - fctiw. */
1795 void OPPROTO op_fctiw (void)
1796 {
1797 do_fctiw();
1798 RETURN();
1799 }
1800
1801 /* fctiwz - fctiwz. */
1802 void OPPROTO op_fctiwz (void)
1803 {
1804 do_fctiwz();
1805 RETURN();
1806 }
1807
1808 #if defined(TARGET_PPC64)
1809 /* fcfid - fcfid. */
1810 void OPPROTO op_fcfid (void)
1811 {
1812 do_fcfid();
1813 RETURN();
1814 }
1815
1816 /* fctid - fctid. */
1817 void OPPROTO op_fctid (void)
1818 {
1819 do_fctid();
1820 RETURN();
1821 }
1822
1823 /* fctidz - fctidz. */
1824 void OPPROTO op_fctidz (void)
1825 {
1826 do_fctidz();
1827 RETURN();
1828 }
1829 #endif
1830
1831 void OPPROTO op_frin (void)
1832 {
1833 do_frin();
1834 RETURN();
1835 }
1836
1837 void OPPROTO op_friz (void)
1838 {
1839 do_friz();
1840 RETURN();
1841 }
1842
1843 void OPPROTO op_frip (void)
1844 {
1845 do_frip();
1846 RETURN();
1847 }
1848
1849 void OPPROTO op_frim (void)
1850 {
1851 do_frim();
1852 RETURN();
1853 }
1854
1855 /*** Floating-Point compare ***/
1856 /* fcmpu */
1857 void OPPROTO op_fcmpu (void)
1858 {
1859 do_fcmpu();
1860 RETURN();
1861 }
1862
1863 /* fcmpo */
1864 void OPPROTO op_fcmpo (void)
1865 {
1866 do_fcmpo();
1867 RETURN();
1868 }
1869
1870 /*** Floating-point move ***/
1871 /* fabs */
1872 void OPPROTO op_fabs (void)
1873 {
1874 FT0 = float64_abs(FT0);
1875 RETURN();
1876 }
1877
1878 /* fnabs */
1879 void OPPROTO op_fnabs (void)
1880 {
1881 FT0 = float64_abs(FT0);
1882 FT0 = float64_chs(FT0);
1883 RETURN();
1884 }
1885
1886 /* fneg */
1887 void OPPROTO op_fneg (void)
1888 {
1889 FT0 = float64_chs(FT0);
1890 RETURN();
1891 }
1892
1893 /* Load and store */
1894 #define MEMSUFFIX _raw
1895 #include "op_helper.h"
1896 #include "op_mem.h"
1897 #if !defined(CONFIG_USER_ONLY)
1898 #define MEMSUFFIX _user
1899 #include "op_helper.h"
1900 #include "op_mem.h"
1901 #define MEMSUFFIX _kernel
1902 #include "op_helper.h"
1903 #include "op_mem.h"
1904 #endif
1905
1906 /* Special op to check and maybe clear reservation */
1907 void OPPROTO op_check_reservation (void)
1908 {
1909 if ((uint32_t)env->reserve == (uint32_t)(T0 & ~0x00000003))
1910 env->reserve = -1;
1911 RETURN();
1912 }
1913
1914 #if defined(TARGET_PPC64)
1915 void OPPROTO op_check_reservation_64 (void)
1916 {
1917 if ((uint64_t)env->reserve == (uint64_t)(T0 & ~0x00000003))
1918 env->reserve = -1;
1919 RETURN();
1920 }
1921 #endif
1922
1923 void OPPROTO op_wait (void)
1924 {
1925 env->halted = 1;
1926 RETURN();
1927 }
1928
1929 /* Return from interrupt */
1930 #if !defined(CONFIG_USER_ONLY)
1931 void OPPROTO op_rfi (void)
1932 {
1933 do_rfi();
1934 RETURN();
1935 }
1936
1937 #if defined(TARGET_PPC64)
1938 void OPPROTO op_rfid (void)
1939 {
1940 do_rfid();
1941 RETURN();
1942 }
1943 #endif
1944
1945 #if defined(TARGET_PPC64H)
1946 void OPPROTO op_hrfid (void)
1947 {
1948 do_hrfid();
1949 RETURN();
1950 }
1951 #endif
1952
1953 /* Exception vectors */
1954 void OPPROTO op_store_excp_prefix (void)
1955 {
1956 T0 &= env->ivpr_mask;
1957 env->excp_prefix = T0;
1958 RETURN();
1959 }
1960
1961 void OPPROTO op_store_excp_vector (void)
1962 {
1963 T0 &= env->ivor_mask;
1964 env->excp_vectors[PARAM1] = T0;
1965 RETURN();
1966 }
1967 #endif
1968
1969 /* Trap word */
1970 void OPPROTO op_tw (void)
1971 {
1972 do_tw(PARAM1);
1973 RETURN();
1974 }
1975
1976 #if defined(TARGET_PPC64)
1977 void OPPROTO op_td (void)
1978 {
1979 do_td(PARAM1);
1980 RETURN();
1981 }
1982 #endif
1983
1984 #if !defined(CONFIG_USER_ONLY)
1985 /* tlbia */
1986 void OPPROTO op_tlbia (void)
1987 {
1988 do_tlbia();
1989 RETURN();
1990 }
1991
1992 /* tlbie */
1993 void OPPROTO op_tlbie (void)
1994 {
1995 do_tlbie();
1996 RETURN();
1997 }
1998
1999 #if defined(TARGET_PPC64)
2000 void OPPROTO op_tlbie_64 (void)
2001 {
2002 do_tlbie_64();
2003 RETURN();
2004 }
2005 #endif
2006
2007 #if defined(TARGET_PPC64)
2008 void OPPROTO op_slbia (void)
2009 {
2010 do_slbia();
2011 RETURN();
2012 }
2013
2014 void OPPROTO op_slbie (void)
2015 {
2016 do_slbie();
2017 RETURN();
2018 }
2019 #endif
2020 #endif
2021
2022 /* PowerPC 602/603/755 software TLB load instructions */
2023 #if !defined(CONFIG_USER_ONLY)
2024 void OPPROTO op_6xx_tlbld (void)
2025 {
2026 do_load_6xx_tlb(0);
2027 RETURN();
2028 }
2029
2030 void OPPROTO op_6xx_tlbli (void)
2031 {
2032 do_load_6xx_tlb(1);
2033 RETURN();
2034 }
2035 #endif
2036
2037 /* 601 specific */
2038 void OPPROTO op_load_601_rtcl (void)
2039 {
2040 T0 = cpu_ppc601_load_rtcl(env);
2041 RETURN();
2042 }
2043
2044 void OPPROTO op_load_601_rtcu (void)
2045 {
2046 T0 = cpu_ppc601_load_rtcu(env);
2047 RETURN();
2048 }
2049
2050 #if !defined(CONFIG_USER_ONLY)
2051 void OPPROTO op_store_601_rtcl (void)
2052 {
2053 cpu_ppc601_store_rtcl(env, T0);
2054 RETURN();
2055 }
2056
2057 void OPPROTO op_store_601_rtcu (void)
2058 {
2059 cpu_ppc601_store_rtcu(env, T0);
2060 RETURN();
2061 }
2062
2063 void OPPROTO op_load_601_bat (void)
2064 {
2065 T0 = env->IBAT[PARAM1][PARAM2];
2066 RETURN();
2067 }
2068 #endif /* !defined(CONFIG_USER_ONLY) */
2069
2070 /* 601 unified BATs store.
2071 * To avoid using specific MMU code for 601, we store BATs in
2072 * IBAT and DBAT simultaneously, then emulate unified BATs.
2073 */
2074 #if !defined(CONFIG_USER_ONLY)
2075 void OPPROTO op_store_601_batl (void)
2076 {
2077 int nr = PARAM1;
2078
2079 env->IBAT[1][nr] = T0;
2080 env->DBAT[1][nr] = T0;
2081 RETURN();
2082 }
2083
2084 void OPPROTO op_store_601_batu (void)
2085 {
2086 do_store_601_batu(PARAM1);
2087 RETURN();
2088 }
2089 #endif /* !defined(CONFIG_USER_ONLY) */
2090
2091 /* PowerPC 601 specific instructions (POWER bridge) */
2092 /* XXX: those micro-ops need tests ! */
2093 void OPPROTO op_POWER_abs (void)
2094 {
2095 if (T0 == INT32_MIN)
2096 T0 = INT32_MAX;
2097 else if (T0 < 0)
2098 T0 = -T0;
2099 RETURN();
2100 }
2101
2102 void OPPROTO op_POWER_abso (void)
2103 {
2104 do_POWER_abso();
2105 RETURN();
2106 }
2107
2108 void OPPROTO op_POWER_clcs (void)
2109 {
2110 do_POWER_clcs();
2111 RETURN();
2112 }
2113
2114 void OPPROTO op_POWER_div (void)
2115 {
2116 do_POWER_div();
2117 RETURN();
2118 }
2119
2120 void OPPROTO op_POWER_divo (void)
2121 {
2122 do_POWER_divo();
2123 RETURN();
2124 }
2125
2126 void OPPROTO op_POWER_divs (void)
2127 {
2128 do_POWER_divs();
2129 RETURN();
2130 }
2131
2132 void OPPROTO op_POWER_divso (void)
2133 {
2134 do_POWER_divso();
2135 RETURN();
2136 }
2137
2138 void OPPROTO op_POWER_doz (void)
2139 {
2140 if ((int32_t)T1 > (int32_t)T0)
2141 T0 = T1 - T0;
2142 else
2143 T0 = 0;
2144 RETURN();
2145 }
2146
2147 void OPPROTO op_POWER_dozo (void)
2148 {
2149 do_POWER_dozo();
2150 RETURN();
2151 }
2152
2153 void OPPROTO op_load_xer_cmp (void)
2154 {
2155 T2 = xer_cmp;
2156 RETURN();
2157 }
2158
2159 void OPPROTO op_POWER_maskg (void)
2160 {
2161 do_POWER_maskg();
2162 RETURN();
2163 }
2164
2165 void OPPROTO op_POWER_maskir (void)
2166 {
2167 T0 = (T0 & ~T2) | (T1 & T2);
2168 RETURN();
2169 }
2170
2171 void OPPROTO op_POWER_mul (void)
2172 {
2173 uint64_t tmp;
2174
2175 tmp = (uint64_t)T0 * (uint64_t)T1;
2176 env->spr[SPR_MQ] = tmp >> 32;
2177 T0 = tmp;
2178 RETURN();
2179 }
2180
2181 void OPPROTO op_POWER_mulo (void)
2182 {
2183 do_POWER_mulo();
2184 RETURN();
2185 }
2186
2187 void OPPROTO op_POWER_nabs (void)
2188 {
2189 if (T0 > 0)
2190 T0 = -T0;
2191 RETURN();
2192 }
2193
2194 void OPPROTO op_POWER_nabso (void)
2195 {
2196 /* nabs never overflows */
2197 if (T0 > 0)
2198 T0 = -T0;
2199 xer_ov = 0;
2200 RETURN();
2201 }
2202
2203 /* XXX: factorise POWER rotates... */
2204 void OPPROTO op_POWER_rlmi (void)
2205 {
2206 T0 = rotl32(T0, T2) & PARAM1;
2207 T0 |= T1 & PARAM2;
2208 RETURN();
2209 }
2210
2211 void OPPROTO op_POWER_rrib (void)
2212 {
2213 T2 &= 0x1FUL;
2214 T0 = rotl32(T0 & INT32_MIN, T2);
2215 T0 |= T1 & ~rotl32(INT32_MIN, T2);
2216 RETURN();
2217 }
2218
2219 void OPPROTO op_POWER_sle (void)
2220 {
2221 T1 &= 0x1FUL;
2222 env->spr[SPR_MQ] = rotl32(T0, T1);
2223 T0 = T0 << T1;
2224 RETURN();
2225 }
2226
2227 void OPPROTO op_POWER_sleq (void)
2228 {
2229 uint32_t tmp = env->spr[SPR_MQ];
2230
2231 T1 &= 0x1FUL;
2232 env->spr[SPR_MQ] = rotl32(T0, T1);
2233 T0 = T0 << T1;
2234 T0 |= tmp >> (32 - T1);
2235 RETURN();
2236 }
2237
2238 void OPPROTO op_POWER_sllq (void)
2239 {
2240 uint32_t msk = -1;
2241
2242 msk = msk << (T1 & 0x1FUL);
2243 if (T1 & 0x20UL)
2244 msk = ~msk;
2245 T1 &= 0x1FUL;
2246 T0 = (T0 << T1) & msk;
2247 T0 |= env->spr[SPR_MQ] & ~msk;
2248 RETURN();
2249 }
2250
2251 void OPPROTO op_POWER_slq (void)
2252 {
2253 uint32_t msk = -1, tmp;
2254
2255 msk = msk << (T1 & 0x1FUL);
2256 if (T1 & 0x20UL)
2257 msk = ~msk;
2258 T1 &= 0x1FUL;
2259 tmp = rotl32(T0, T1);
2260 T0 = tmp & msk;
2261 env->spr[SPR_MQ] = tmp;
2262 RETURN();
2263 }
2264
2265 void OPPROTO op_POWER_sraq (void)
2266 {
2267 env->spr[SPR_MQ] = rotl32(T0, 32 - (T1 & 0x1FUL));
2268 if (T1 & 0x20UL)
2269 T0 = -1L;
2270 else
2271 T0 = (int32_t)T0 >> T1;
2272 RETURN();
2273 }
2274
2275 void OPPROTO op_POWER_sre (void)
2276 {
2277 T1 &= 0x1FUL;
2278 env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2279 T0 = (int32_t)T0 >> T1;
2280 RETURN();
2281 }
2282
2283 void OPPROTO op_POWER_srea (void)
2284 {
2285 T1 &= 0x1FUL;
2286 env->spr[SPR_MQ] = T0 >> T1;
2287 T0 = (int32_t)T0 >> T1;
2288 RETURN();
2289 }
2290
2291 void OPPROTO op_POWER_sreq (void)
2292 {
2293 uint32_t tmp;
2294 int32_t msk;
2295
2296 T1 &= 0x1FUL;
2297 msk = INT32_MIN >> T1;
2298 tmp = env->spr[SPR_MQ];
2299 env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2300 T0 = T0 >> T1;
2301 T0 |= tmp & msk;
2302 RETURN();
2303 }
2304
2305 void OPPROTO op_POWER_srlq (void)
2306 {
2307 uint32_t tmp;
2308 int32_t msk;
2309
2310 msk = INT32_MIN >> (T1 & 0x1FUL);
2311 if (T1 & 0x20UL)
2312 msk = ~msk;
2313 T1 &= 0x1FUL;
2314 tmp = env->spr[SPR_MQ];
2315 env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2316 T0 = T0 >> T1;
2317 T0 &= msk;
2318 T0 |= tmp & ~msk;
2319 RETURN();
2320 }
2321
2322 void OPPROTO op_POWER_srq (void)
2323 {
2324 T1 &= 0x1FUL;
2325 env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2326 T0 = T0 >> T1;
2327 RETURN();
2328 }
2329
2330 /* POWER instructions not implemented in PowerPC 601 */
2331 #if !defined(CONFIG_USER_ONLY)
2332 void OPPROTO op_POWER_mfsri (void)
2333 {
2334 T1 = T0 >> 28;
2335 T0 = env->sr[T1];
2336 RETURN();
2337 }
2338
2339 void OPPROTO op_POWER_rac (void)
2340 {
2341 do_POWER_rac();
2342 RETURN();
2343 }
2344
2345 void OPPROTO op_POWER_rfsvc (void)
2346 {
2347 do_POWER_rfsvc();
2348 RETURN();
2349 }
2350 #endif
2351
2352 /* PowerPC 602 specific instruction */
2353 #if !defined(CONFIG_USER_ONLY)
2354 void OPPROTO op_602_mfrom (void)
2355 {
2356 do_op_602_mfrom();
2357 RETURN();
2358 }
2359 #endif
2360
2361 /* PowerPC 4xx specific micro-ops */
2362 void OPPROTO op_405_add_T0_T2 (void)
2363 {
2364 T0 = (int32_t)T0 + (int32_t)T2;
2365 RETURN();
2366 }
2367
2368 void OPPROTO op_405_mulchw (void)
2369 {
2370 T0 = ((int16_t)T0) * ((int16_t)(T1 >> 16));
2371 RETURN();
2372 }
2373
2374 void OPPROTO op_405_mulchwu (void)
2375 {
2376 T0 = ((uint16_t)T0) * ((uint16_t)(T1 >> 16));
2377 RETURN();
2378 }
2379
2380 void OPPROTO op_405_mulhhw (void)
2381 {
2382 T0 = ((int16_t)(T0 >> 16)) * ((int16_t)(T1 >> 16));
2383 RETURN();
2384 }
2385
2386 void OPPROTO op_405_mulhhwu (void)
2387 {
2388 T0 = ((uint16_t)(T0 >> 16)) * ((uint16_t)(T1 >> 16));
2389 RETURN();
2390 }
2391
2392 void OPPROTO op_405_mullhw (void)
2393 {
2394 T0 = ((int16_t)T0) * ((int16_t)T1);
2395 RETURN();
2396 }
2397
2398 void OPPROTO op_405_mullhwu (void)
2399 {
2400 T0 = ((uint16_t)T0) * ((uint16_t)T1);
2401 RETURN();
2402 }
2403
2404 void OPPROTO op_405_check_ov (void)
2405 {
2406 do_405_check_ov();
2407 RETURN();
2408 }
2409
2410 void OPPROTO op_405_check_sat (void)
2411 {
2412 do_405_check_sat();
2413 RETURN();
2414 }
2415
2416 void OPPROTO op_405_check_ovu (void)
2417 {
2418 if (likely(T0 >= T2)) {
2419 xer_ov = 0;
2420 } else {
2421 xer_ov = 1;
2422 xer_so = 1;
2423 }
2424 RETURN();
2425 }
2426
2427 void OPPROTO op_405_check_satu (void)
2428 {
2429 if (unlikely(T0 < T2)) {
2430 /* Saturate result */
2431 T0 = -1;
2432 }
2433 RETURN();
2434 }
2435
2436 void OPPROTO op_load_dcr (void)
2437 {
2438 do_load_dcr();
2439 RETURN();
2440 }
2441
2442 void OPPROTO op_store_dcr (void)
2443 {
2444 do_store_dcr();
2445 RETURN();
2446 }
2447
2448 #if !defined(CONFIG_USER_ONLY)
2449 /* Return from critical interrupt :
2450 * same as rfi, except nip & MSR are loaded from SRR2/3 instead of SRR0/1
2451 */
2452 void OPPROTO op_40x_rfci (void)
2453 {
2454 do_40x_rfci();
2455 RETURN();
2456 }
2457
2458 void OPPROTO op_rfci (void)
2459 {
2460 do_rfci();
2461 RETURN();
2462 }
2463
2464 void OPPROTO op_rfdi (void)
2465 {
2466 do_rfdi();
2467 RETURN();
2468 }
2469
2470 void OPPROTO op_rfmci (void)
2471 {
2472 do_rfmci();
2473 RETURN();
2474 }
2475
2476 void OPPROTO op_wrte (void)
2477 {
2478 msr_ee = T0 >> 16;
2479 RETURN();
2480 }
2481
2482 void OPPROTO op_440_tlbre (void)
2483 {
2484 do_440_tlbre(PARAM1);
2485 RETURN();
2486 }
2487
2488 void OPPROTO op_440_tlbsx (void)
2489 {
2490 do_440_tlbsx();
2491 RETURN();
2492 }
2493
2494 void OPPROTO op_440_tlbsx_ (void)
2495 {
2496 do_440_tlbsx_();
2497 RETURN();
2498 }
2499
2500 void OPPROTO op_440_tlbwe (void)
2501 {
2502 do_440_tlbwe(PARAM1);
2503 RETURN();
2504 }
2505
2506 void OPPROTO op_4xx_tlbre_lo (void)
2507 {
2508 do_4xx_tlbre_lo();
2509 RETURN();
2510 }
2511
2512 void OPPROTO op_4xx_tlbre_hi (void)
2513 {
2514 do_4xx_tlbre_hi();
2515 RETURN();
2516 }
2517
2518 void OPPROTO op_4xx_tlbsx (void)
2519 {
2520 do_4xx_tlbsx();
2521 RETURN();
2522 }
2523
2524 void OPPROTO op_4xx_tlbsx_ (void)
2525 {
2526 do_4xx_tlbsx_();
2527 RETURN();
2528 }
2529
2530 void OPPROTO op_4xx_tlbwe_lo (void)
2531 {
2532 do_4xx_tlbwe_lo();
2533 RETURN();
2534 }
2535
2536 void OPPROTO op_4xx_tlbwe_hi (void)
2537 {
2538 do_4xx_tlbwe_hi();
2539 RETURN();
2540 }
2541 #endif
2542
2543 /* SPR micro-ops */
2544 /* 440 specific */
2545 void OPPROTO op_440_dlmzb (void)
2546 {
2547 do_440_dlmzb();
2548 RETURN();
2549 }
2550
2551 void OPPROTO op_440_dlmzb_update_Rc (void)
2552 {
2553 if (T0 == 8)
2554 T0 = 0x2;
2555 else if (T0 < 4)
2556 T0 = 0x4;
2557 else
2558 T0 = 0x8;
2559 RETURN();
2560 }
2561
2562 #if !defined(CONFIG_USER_ONLY)
2563 void OPPROTO op_store_pir (void)
2564 {
2565 env->spr[SPR_PIR] = T0 & 0x0000000FUL;
2566 RETURN();
2567 }
2568
2569 void OPPROTO op_load_403_pb (void)
2570 {
2571 do_load_403_pb(PARAM1);
2572 RETURN();
2573 }
2574
2575 void OPPROTO op_store_403_pb (void)
2576 {
2577 do_store_403_pb(PARAM1);
2578 RETURN();
2579 }
2580
2581 void OPPROTO op_load_40x_pit (void)
2582 {
2583 T0 = load_40x_pit(env);
2584 RETURN();
2585 }
2586
2587 void OPPROTO op_store_40x_pit (void)
2588 {
2589 store_40x_pit(env, T0);
2590 RETURN();
2591 }
2592
2593 void OPPROTO op_store_40x_dbcr0 (void)
2594 {
2595 store_40x_dbcr0(env, T0);
2596 RETURN();
2597 }
2598
2599 void OPPROTO op_store_40x_sler (void)
2600 {
2601 store_40x_sler(env, T0);
2602 RETURN();
2603 }
2604
2605 void OPPROTO op_store_booke_tcr (void)
2606 {
2607 store_booke_tcr(env, T0);
2608 RETURN();
2609 }
2610
2611 void OPPROTO op_store_booke_tsr (void)
2612 {
2613 store_booke_tsr(env, T0);
2614 RETURN();
2615 }
2616 #endif /* !defined(CONFIG_USER_ONLY) */
2617
2618 #if defined(TARGET_PPCEMB)
2619 /* SPE extension */
2620 void OPPROTO op_splatw_T1_64 (void)
2621 {
2622 T1_64 = (T1_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL);
2623 RETURN();
2624 }
2625
2626 void OPPROTO op_splatwi_T0_64 (void)
2627 {
2628 uint64_t tmp = PARAM1;
2629
2630 T0_64 = (tmp << 32) | tmp;
2631 RETURN();
2632 }
2633
2634 void OPPROTO op_splatwi_T1_64 (void)
2635 {
2636 uint64_t tmp = PARAM1;
2637
2638 T1_64 = (tmp << 32) | tmp;
2639 RETURN();
2640 }
2641
2642 void OPPROTO op_extsh_T1_64 (void)
2643 {
2644 T1_64 = (int32_t)((int16_t)T1_64);
2645 RETURN();
2646 }
2647
2648 void OPPROTO op_sli16_T1_64 (void)
2649 {
2650 T1_64 = T1_64 << 16;
2651 RETURN();
2652 }
2653
2654 void OPPROTO op_sli32_T1_64 (void)
2655 {
2656 T1_64 = T1_64 << 32;
2657 RETURN();
2658 }
2659
2660 void OPPROTO op_srli32_T1_64 (void)
2661 {
2662 T1_64 = T1_64 >> 32;
2663 RETURN();
2664 }
2665
2666 void OPPROTO op_evsel (void)
2667 {
2668 do_evsel();
2669 RETURN();
2670 }
2671
2672 void OPPROTO op_evaddw (void)
2673 {
2674 do_evaddw();
2675 RETURN();
2676 }
2677
2678 void OPPROTO op_evsubfw (void)
2679 {
2680 do_evsubfw();
2681 RETURN();
2682 }
2683
2684 void OPPROTO op_evneg (void)
2685 {
2686 do_evneg();
2687 RETURN();
2688 }
2689
2690 void OPPROTO op_evabs (void)
2691 {
2692 do_evabs();
2693 RETURN();
2694 }
2695
2696 void OPPROTO op_evextsh (void)
2697 {
2698 T0_64 = ((uint64_t)((int32_t)(int16_t)(T0_64 >> 32)) << 32) |
2699 (uint64_t)((int32_t)(int16_t)T0_64);
2700 RETURN();
2701 }
2702
2703 void OPPROTO op_evextsb (void)
2704 {
2705 T0_64 = ((uint64_t)((int32_t)(int8_t)(T0_64 >> 32)) << 32) |
2706 (uint64_t)((int32_t)(int8_t)T0_64);
2707 RETURN();
2708 }
2709
2710 void OPPROTO op_evcntlzw (void)
2711 {
2712 do_evcntlzw();
2713 RETURN();
2714 }
2715
2716 void OPPROTO op_evrndw (void)
2717 {
2718 do_evrndw();
2719 RETURN();
2720 }
2721
2722 void OPPROTO op_brinc (void)
2723 {
2724 do_brinc();
2725 RETURN();
2726 }
2727
2728 void OPPROTO op_evcntlsw (void)
2729 {
2730 do_evcntlsw();
2731 RETURN();
2732 }
2733
2734 void OPPROTO op_evand (void)
2735 {
2736 T0_64 &= T1_64;
2737 RETURN();
2738 }
2739
2740 void OPPROTO op_evandc (void)
2741 {
2742 T0_64 &= ~T1_64;
2743 RETURN();
2744 }
2745
2746 void OPPROTO op_evor (void)
2747 {
2748 T0_64 |= T1_64;
2749 RETURN();
2750 }
2751
2752 void OPPROTO op_evxor (void)
2753 {
2754 T0_64 ^= T1_64;
2755 RETURN();
2756 }
2757
2758 void OPPROTO op_eveqv (void)
2759 {
2760 T0_64 = ~(T0_64 ^ T1_64);
2761 RETURN();
2762 }
2763
2764 void OPPROTO op_evnor (void)
2765 {
2766 T0_64 = ~(T0_64 | T1_64);
2767 RETURN();
2768 }
2769
2770 void OPPROTO op_evorc (void)
2771 {
2772 T0_64 |= ~T1_64;
2773 RETURN();
2774 }
2775
2776 void OPPROTO op_evnand (void)
2777 {
2778 T0_64 = ~(T0_64 & T1_64);
2779 RETURN();
2780 }
2781
2782 void OPPROTO op_evsrws (void)
2783 {
2784 do_evsrws();
2785 RETURN();
2786 }
2787
2788 void OPPROTO op_evsrwu (void)
2789 {
2790 do_evsrwu();
2791 RETURN();
2792 }
2793
2794 void OPPROTO op_evslw (void)
2795 {
2796 do_evslw();
2797 RETURN();
2798 }
2799
2800 void OPPROTO op_evrlw (void)
2801 {
2802 do_evrlw();
2803 RETURN();
2804 }
2805
2806 void OPPROTO op_evmergelo (void)
2807 {
2808 T0_64 = (T0_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL);
2809 RETURN();
2810 }
2811
2812 void OPPROTO op_evmergehi (void)
2813 {
2814 T0_64 = (T0_64 & 0xFFFFFFFF00000000ULL) | (T1_64 >> 32);
2815 RETURN();
2816 }
2817
2818 void OPPROTO op_evmergelohi (void)
2819 {
2820 T0_64 = (T0_64 << 32) | (T1_64 >> 32);
2821 RETURN();
2822 }
2823
2824 void OPPROTO op_evmergehilo (void)
2825 {
2826 T0_64 = (T0_64 & 0xFFFFFFFF00000000ULL) | (T1_64 & 0x00000000FFFFFFFFULL);
2827 RETURN();
2828 }
2829
2830 void OPPROTO op_evcmpgts (void)
2831 {
2832 do_evcmpgts();
2833 RETURN();
2834 }
2835
2836 void OPPROTO op_evcmpgtu (void)
2837 {
2838 do_evcmpgtu();
2839 RETURN();
2840 }
2841
2842 void OPPROTO op_evcmplts (void)
2843 {
2844 do_evcmplts();
2845 RETURN();
2846 }
2847
2848 void OPPROTO op_evcmpltu (void)
2849 {
2850 do_evcmpltu();
2851 RETURN();
2852 }
2853
2854 void OPPROTO op_evcmpeq (void)
2855 {
2856 do_evcmpeq();
2857 RETURN();
2858 }
2859
2860 void OPPROTO op_evfssub (void)
2861 {
2862 do_evfssub();
2863 RETURN();
2864 }
2865
2866 void OPPROTO op_evfsadd (void)
2867 {
2868 do_evfsadd();
2869 RETURN();
2870 }
2871
2872 void OPPROTO op_evfsnabs (void)
2873 {
2874 do_evfsnabs();
2875 RETURN();
2876 }
2877
2878 void OPPROTO op_evfsabs (void)
2879 {
2880 do_evfsabs();
2881 RETURN();
2882 }
2883
2884 void OPPROTO op_evfsneg (void)
2885 {
2886 do_evfsneg();
2887 RETURN();
2888 }
2889
2890 void OPPROTO op_evfsdiv (void)
2891 {
2892 do_evfsdiv();
2893 RETURN();
2894 }
2895
2896 void OPPROTO op_evfsmul (void)
2897 {
2898 do_evfsmul();
2899 RETURN();
2900 }
2901
2902 void OPPROTO op_evfscmplt (void)
2903 {
2904 do_evfscmplt();
2905 RETURN();
2906 }
2907
2908 void OPPROTO op_evfscmpgt (void)
2909 {
2910 do_evfscmpgt();
2911 RETURN();
2912 }
2913
2914 void OPPROTO op_evfscmpeq (void)
2915 {
2916 do_evfscmpeq();
2917 RETURN();
2918 }
2919
2920 void OPPROTO op_evfscfsi (void)
2921 {
2922 do_evfscfsi();
2923 RETURN();
2924 }
2925
2926 void OPPROTO op_evfscfui (void)
2927 {
2928 do_evfscfui();
2929 RETURN();
2930 }
2931
2932 void OPPROTO op_evfscfsf (void)
2933 {
2934 do_evfscfsf();
2935 RETURN();
2936 }
2937
2938 void OPPROTO op_evfscfuf (void)
2939 {
2940 do_evfscfuf();
2941 RETURN();
2942 }
2943
2944 void OPPROTO op_evfsctsi (void)
2945 {
2946 do_evfsctsi();
2947 RETURN();
2948 }
2949
2950 void OPPROTO op_evfsctui (void)
2951 {
2952 do_evfsctui();
2953 RETURN();
2954 }
2955
2956 void OPPROTO op_evfsctsf (void)
2957 {
2958 do_evfsctsf();
2959 RETURN();
2960 }
2961
2962 void OPPROTO op_evfsctuf (void)
2963 {
2964 do_evfsctuf();
2965 RETURN();
2966 }
2967
2968 void OPPROTO op_evfsctuiz (void)
2969 {
2970 do_evfsctuiz();
2971 RETURN();
2972 }
2973
2974 void OPPROTO op_evfsctsiz (void)
2975 {
2976 do_evfsctsiz();
2977 RETURN();
2978 }
2979
2980 void OPPROTO op_evfststlt (void)
2981 {
2982 do_evfststlt();
2983 RETURN();
2984 }
2985
2986 void OPPROTO op_evfststgt (void)
2987 {
2988 do_evfststgt();
2989 RETURN();
2990 }
2991
2992 void OPPROTO op_evfststeq (void)
2993 {
2994 do_evfststeq();
2995 RETURN();
2996 }
2997
2998 void OPPROTO op_efssub (void)
2999 {
3000 T0_64 = _do_efssub(T0_64, T1_64);
3001 RETURN();
3002 }
3003
3004 void OPPROTO op_efsadd (void)
3005 {
3006 T0_64 = _do_efsadd(T0_64, T1_64);
3007 RETURN();
3008 }
3009
3010 void OPPROTO op_efsnabs (void)
3011 {
3012 T0_64 = _do_efsnabs(T0_64);
3013 RETURN();
3014 }
3015
3016 void OPPROTO op_efsabs (void)
3017 {
3018 T0_64 = _do_efsabs(T0_64);
3019 RETURN();
3020 }
3021
3022 void OPPROTO op_efsneg (void)
3023 {
3024 T0_64 = _do_efsneg(T0_64);
3025 RETURN();
3026 }
3027
3028 void OPPROTO op_efsdiv (void)
3029 {
3030 T0_64 = _do_efsdiv(T0_64, T1_64);
3031 RETURN();
3032 }
3033
3034 void OPPROTO op_efsmul (void)
3035 {
3036 T0_64 = _do_efsmul(T0_64, T1_64);
3037 RETURN();
3038 }
3039
3040 void OPPROTO op_efscmplt (void)
3041 {
3042 do_efscmplt();
3043 RETURN();
3044 }
3045
3046 void OPPROTO op_efscmpgt (void)
3047 {
3048 do_efscmpgt();
3049 RETURN();
3050 }
3051
3052 void OPPROTO op_efscfd (void)
3053 {
3054 do_efscfd();
3055 RETURN();
3056 }
3057
3058 void OPPROTO op_efscmpeq (void)
3059 {
3060 do_efscmpeq();
3061 RETURN();
3062 }
3063
3064 void OPPROTO op_efscfsi (void)
3065 {
3066 do_efscfsi();
3067 RETURN();
3068 }
3069
3070 void OPPROTO op_efscfui (void)
3071 {
3072 do_efscfui();
3073 RETURN();
3074 }
3075
3076 void OPPROTO op_efscfsf (void)
3077 {
3078 do_efscfsf();
3079 RETURN();
3080 }
3081
3082 void OPPROTO op_efscfuf (void)
3083 {
3084 do_efscfuf();
3085 RETURN();
3086 }
3087
3088 void OPPROTO op_efsctsi (void)
3089 {
3090 do_efsctsi();
3091 RETURN();
3092 }
3093
3094 void OPPROTO op_efsctui (void)
3095 {
3096 do_efsctui();
3097 RETURN();
3098 }
3099
3100 void OPPROTO op_efsctsf (void)
3101 {
3102 do_efsctsf();
3103 RETURN();
3104 }
3105
3106 void OPPROTO op_efsctuf (void)
3107 {
3108 do_efsctuf();
3109 RETURN();
3110 }
3111
3112 void OPPROTO op_efsctsiz (void)
3113 {
3114 do_efsctsiz();
3115 RETURN();
3116 }
3117
3118 void OPPROTO op_efsctuiz (void)
3119 {
3120 do_efsctuiz();
3121 RETURN();
3122 }
3123
3124 void OPPROTO op_efststlt (void)
3125 {
3126 T0 = _do_efststlt(T0_64, T1_64);
3127 RETURN();
3128 }
3129
3130 void OPPROTO op_efststgt (void)
3131 {
3132 T0 = _do_efststgt(T0_64, T1_64);
3133 RETURN();
3134 }
3135
3136 void OPPROTO op_efststeq (void)
3137 {
3138 T0 = _do_efststeq(T0_64, T1_64);
3139 RETURN();
3140 }
3141
3142 void OPPROTO op_efdsub (void)
3143 {
3144 union {
3145 uint64_t u;
3146 float64 f;
3147 } u1, u2;
3148 u1.u = T0_64;
3149 u2.u = T1_64;
3150 u1.f = float64_sub(u1.f, u2.f, &env->spe_status);
3151 T0_64 = u1.u;
3152 RETURN();
3153 }
3154
3155 void OPPROTO op_efdadd (void)
3156 {
3157 union {
3158 uint64_t u;
3159 float64 f;
3160 } u1, u2;
3161 u1.u = T0_64;
3162 u2.u = T1_64;
3163 u1.f = float64_add(u1.f, u2.f, &env->spe_status);
3164 T0_64 = u1.u;
3165 RETURN();
3166 }
3167
3168 void OPPROTO op_efdcfsid (void)
3169 {
3170 do_efdcfsi();
3171 RETURN();
3172 }
3173
3174 void OPPROTO op_efdcfuid (void)
3175 {
3176 do_efdcfui();
3177 RETURN();
3178 }
3179
3180 void OPPROTO op_efdnabs (void)
3181 {
3182 T0_64 |= 0x8000000000000000ULL;
3183 RETURN();
3184 }
3185
3186 void OPPROTO op_efdabs (void)
3187 {
3188 T0_64 &= ~0x8000000000000000ULL;
3189 RETURN();
3190 }
3191
3192 void OPPROTO op_efdneg (void)
3193 {
3194 T0_64 ^= 0x8000000000000000ULL;
3195 RETURN();
3196 }
3197
3198 void OPPROTO op_efddiv (void)
3199 {
3200 union {
3201 uint64_t u;
3202 float64 f;
3203 } u1, u2;
3204 u1.u = T0_64;
3205 u2.u = T1_64;
3206 u1.f = float64_div(u1.f, u2.f, &env->spe_status);
3207 T0_64 = u1.u;
3208 RETURN();
3209 }
3210
3211 void OPPROTO op_efdmul (void)
3212 {
3213 union {
3214 uint64_t u;
3215 float64 f;
3216 } u1, u2;
3217 u1.u = T0_64;
3218 u2.u = T1_64;
3219 u1.f = float64_mul(u1.f, u2.f, &env->spe_status);
3220 T0_64 = u1.u;
3221 RETURN();
3222 }
3223
3224 void OPPROTO op_efdctsidz (void)
3225 {
3226 do_efdctsiz();
3227 RETURN();
3228 }
3229
3230 void OPPROTO op_efdctuidz (void)
3231 {
3232 do_efdctuiz();
3233 RETURN();
3234 }
3235
3236 void OPPROTO op_efdcmplt (void)
3237 {
3238 do_efdcmplt();
3239 RETURN();
3240 }
3241
3242 void OPPROTO op_efdcmpgt (void)
3243 {
3244 do_efdcmpgt();
3245 RETURN();
3246 }
3247
3248 void OPPROTO op_efdcfs (void)
3249 {
3250 do_efdcfs();
3251 RETURN();
3252 }
3253
3254 void OPPROTO op_efdcmpeq (void)
3255 {
3256 do_efdcmpeq();
3257 RETURN();
3258 }
3259
3260 void OPPROTO op_efdcfsi (void)
3261 {
3262 do_efdcfsi();
3263 RETURN();
3264 }
3265
3266 void OPPROTO op_efdcfui (void)
3267 {
3268 do_efdcfui();
3269 RETURN();
3270 }
3271
3272 void OPPROTO op_efdcfsf (void)
3273 {
3274 do_efdcfsf();
3275 RETURN();
3276 }
3277
3278 void OPPROTO op_efdcfuf (void)
3279 {
3280 do_efdcfuf();
3281 RETURN();
3282 }
3283
3284 void OPPROTO op_efdctsi (void)
3285 {
3286 do_efdctsi();
3287 RETURN();
3288 }
3289
3290 void OPPROTO op_efdctui (void)
3291 {
3292 do_efdctui();
3293 RETURN();
3294 }
3295
3296 void OPPROTO op_efdctsf (void)
3297 {
3298 do_efdctsf();
3299 RETURN();
3300 }
3301
3302 void OPPROTO op_efdctuf (void)
3303 {
3304 do_efdctuf();
3305 RETURN();
3306 }
3307
3308 void OPPROTO op_efdctuiz (void)
3309 {
3310 do_efdctuiz();
3311 RETURN();
3312 }
3313
3314 void OPPROTO op_efdctsiz (void)
3315 {
3316 do_efdctsiz();
3317 RETURN();
3318 }
3319
3320 void OPPROTO op_efdtstlt (void)
3321 {
3322 T0 = _do_efdtstlt(T0_64, T1_64);
3323 RETURN();
3324 }
3325
3326 void OPPROTO op_efdtstgt (void)
3327 {
3328 T0 = _do_efdtstgt(T0_64, T1_64);
3329 RETURN();
3330 }
3331
3332 void OPPROTO op_efdtsteq (void)
3333 {
3334 T0 = _do_efdtsteq(T0_64, T1_64);
3335 RETURN();
3336 }
3337 #endif /* defined(TARGET_PPCEMB) */