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