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