Add missing PowerPC 64 instructions
[qemu/mini2440.git] / target-ppc / op.c
blob8bbbd62d47bbb94888697a1c6559e2c8fda2b100
1 /*
2 * PowerPC emulation micro-operations for qemu.
3 *
4 * Copyright (c) 2003-2007 Jocelyn Mayer
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.
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.
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
21 //#define DEBUG_OP
23 #include "config.h"
24 #include "exec.h"
25 #include "op_helper.h"
27 /* XXX: this is to be suppressed */
28 #define regs (env)
30 #define FT0 (env->ft0)
31 #define FT1 (env->ft1)
32 #define FT2 (env->ft2)
34 /* XXX: this is to be suppressed... */
35 #define PPC_OP(name) void OPPROTO glue(op_, name)(void)
37 #define REG 0
38 #include "op_template.h"
40 #define REG 1
41 #include "op_template.h"
43 #define REG 2
44 #include "op_template.h"
46 #define REG 3
47 #include "op_template.h"
49 #define REG 4
50 #include "op_template.h"
52 #define REG 5
53 #include "op_template.h"
55 #define REG 6
56 #include "op_template.h"
58 #define REG 7
59 #include "op_template.h"
61 #define REG 8
62 #include "op_template.h"
64 #define REG 9
65 #include "op_template.h"
67 #define REG 10
68 #include "op_template.h"
70 #define REG 11
71 #include "op_template.h"
73 #define REG 12
74 #include "op_template.h"
76 #define REG 13
77 #include "op_template.h"
79 #define REG 14
80 #include "op_template.h"
82 #define REG 15
83 #include "op_template.h"
85 #define REG 16
86 #include "op_template.h"
88 #define REG 17
89 #include "op_template.h"
91 #define REG 18
92 #include "op_template.h"
94 #define REG 19
95 #include "op_template.h"
97 #define REG 20
98 #include "op_template.h"
100 #define REG 21
101 #include "op_template.h"
103 #define REG 22
104 #include "op_template.h"
106 #define REG 23
107 #include "op_template.h"
109 #define REG 24
110 #include "op_template.h"
112 #define REG 25
113 #include "op_template.h"
115 #define REG 26
116 #include "op_template.h"
118 #define REG 27
119 #include "op_template.h"
121 #define REG 28
122 #include "op_template.h"
124 #define REG 29
125 #include "op_template.h"
127 #define REG 30
128 #include "op_template.h"
130 #define REG 31
131 #include "op_template.h"
133 /* PowerPC state maintenance operations */
134 /* set_Rc0 */
135 PPC_OP(set_Rc0)
137 env->crf[0] = T0 | xer_ov;
138 RETURN();
141 /* Set Rc1 (for floating point arithmetic) */
142 PPC_OP(set_Rc1)
144 env->crf[1] = regs->fpscr[7];
145 RETURN();
148 /* Constants load */
149 void OPPROTO op_reset_T0 (void)
151 T0 = 0;
152 RETURN();
155 PPC_OP(set_T0)
157 T0 = (uint32_t)PARAM1;
158 RETURN();
161 #if defined(TARGET_PPC64)
162 void OPPROTO op_set_T0_64 (void)
164 T0 = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
165 RETURN();
167 #endif
169 PPC_OP(set_T1)
171 T1 = (uint32_t)PARAM1;
172 RETURN();
175 #if defined(TARGET_PPC64)
176 void OPPROTO op_set_T1_64 (void)
178 T1 = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
179 RETURN();
181 #endif
183 #if 0 // unused
184 PPC_OP(set_T2)
186 T2 = PARAM(1);
187 RETURN();
189 #endif
191 void OPPROTO op_move_T1_T0 (void)
193 T1 = T0;
194 RETURN();
197 void OPPROTO op_move_T2_T0 (void)
199 T2 = T0;
200 RETURN();
203 /* Generate exceptions */
204 PPC_OP(raise_exception_err)
206 do_raise_exception_err(PARAM(1), PARAM(2));
209 PPC_OP(update_nip)
211 env->nip = (uint32_t)PARAM1;
212 RETURN();
215 #if defined(TARGET_PPC64)
216 void OPPROTO op_update_nip_64 (void)
218 env->nip = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
219 RETURN();
221 #endif
223 PPC_OP(debug)
225 do_raise_exception(EXCP_DEBUG);
228 PPC_OP(exit_tb)
230 EXIT_TB();
233 /* Load/store special registers */
234 PPC_OP(load_cr)
236 do_load_cr();
237 RETURN();
240 PPC_OP(store_cr)
242 do_store_cr(PARAM(1));
243 RETURN();
246 void OPPROTO op_load_cro (void)
248 T0 = env->crf[PARAM1];
249 RETURN();
252 void OPPROTO op_store_cro (void)
254 env->crf[PARAM1] = T0;
255 RETURN();
258 PPC_OP(load_xer_cr)
260 T0 = (xer_so << 3) | (xer_ov << 2) | (xer_ca << 1);
261 RETURN();
264 PPC_OP(clear_xer_ov)
266 xer_so = 0;
267 xer_ov = 0;
268 RETURN();
271 PPC_OP(clear_xer_ca)
273 xer_ca = 0;
274 RETURN();
277 PPC_OP(load_xer_bc)
279 T1 = xer_bc;
280 RETURN();
283 void OPPROTO op_store_xer_bc (void)
285 xer_bc = T0;
286 RETURN();
289 PPC_OP(load_xer)
291 do_load_xer();
292 RETURN();
295 PPC_OP(store_xer)
297 do_store_xer();
298 RETURN();
301 #if !defined(CONFIG_USER_ONLY)
302 /* Segment registers load and store */
303 PPC_OP(load_sr)
305 T0 = regs->sr[T1];
306 RETURN();
309 PPC_OP(store_sr)
311 do_store_sr(env, T1, T0);
312 RETURN();
315 PPC_OP(load_sdr1)
317 T0 = regs->sdr1;
318 RETURN();
321 PPC_OP(store_sdr1)
323 do_store_sdr1(env, T0);
324 RETURN();
327 #if defined (TARGET_PPC64)
328 void OPPROTO op_load_asr (void)
330 T0 = env->asr;
331 RETURN();
334 void OPPROTO op_store_asr (void)
336 ppc_store_asr(env, T0);
337 RETURN();
339 #endif
341 PPC_OP(load_msr)
343 T0 = do_load_msr(env);
344 RETURN();
347 PPC_OP(store_msr)
349 do_store_msr(env, T0);
350 RETURN();
353 #if defined (TARGET_PPC64)
354 void OPPROTO op_store_msr_32 (void)
356 ppc_store_msr_32(env, T0);
357 RETURN();
359 #endif
360 #endif
362 /* SPR */
363 PPC_OP(load_spr)
365 T0 = regs->spr[PARAM(1)];
366 RETURN();
369 PPC_OP(store_spr)
371 regs->spr[PARAM(1)] = T0;
372 RETURN();
375 PPC_OP(load_lr)
377 T0 = regs->lr;
378 RETURN();
381 PPC_OP(store_lr)
383 regs->lr = T0;
384 RETURN();
387 PPC_OP(load_ctr)
389 T0 = regs->ctr;
390 RETURN();
393 PPC_OP(store_ctr)
395 regs->ctr = T0;
396 RETURN();
399 PPC_OP(load_tbl)
401 T0 = cpu_ppc_load_tbl(regs);
402 RETURN();
405 PPC_OP(load_tbu)
407 T0 = cpu_ppc_load_tbu(regs);
408 RETURN();
411 #if !defined(CONFIG_USER_ONLY)
412 PPC_OP(store_tbl)
414 cpu_ppc_store_tbl(regs, T0);
415 RETURN();
418 PPC_OP(store_tbu)
420 cpu_ppc_store_tbu(regs, T0);
421 RETURN();
424 PPC_OP(load_decr)
426 T0 = cpu_ppc_load_decr(regs);
427 RETURN();
430 PPC_OP(store_decr)
432 cpu_ppc_store_decr(regs, T0);
433 RETURN();
436 PPC_OP(load_ibat)
438 T0 = regs->IBAT[PARAM(1)][PARAM(2)];
439 RETURN();
442 void OPPROTO op_store_ibatu (void)
444 do_store_ibatu(env, PARAM1, T0);
445 RETURN();
448 void OPPROTO op_store_ibatl (void)
450 #if 1
451 env->IBAT[1][PARAM1] = T0;
452 #else
453 do_store_ibatl(env, PARAM1, T0);
454 #endif
455 RETURN();
458 PPC_OP(load_dbat)
460 T0 = regs->DBAT[PARAM(1)][PARAM(2)];
461 RETURN();
464 void OPPROTO op_store_dbatu (void)
466 do_store_dbatu(env, PARAM1, T0);
467 RETURN();
470 void OPPROTO op_store_dbatl (void)
472 #if 1
473 env->DBAT[1][PARAM1] = T0;
474 #else
475 do_store_dbatl(env, PARAM1, T0);
476 #endif
477 RETURN();
479 #endif /* !defined(CONFIG_USER_ONLY) */
481 /* FPSCR */
482 PPC_OP(load_fpscr)
484 do_load_fpscr();
485 RETURN();
488 PPC_OP(store_fpscr)
490 do_store_fpscr(PARAM1);
491 RETURN();
494 PPC_OP(reset_scrfx)
496 regs->fpscr[7] &= ~0x8;
497 RETURN();
500 /* crf operations */
501 PPC_OP(getbit_T0)
503 T0 = (T0 >> PARAM(1)) & 1;
504 RETURN();
507 PPC_OP(getbit_T1)
509 T1 = (T1 >> PARAM(1)) & 1;
510 RETURN();
513 PPC_OP(setcrfbit)
515 T1 = (T1 & PARAM(1)) | (T0 << PARAM(2));
516 RETURN();
519 /* Branch */
520 #define EIP regs->nip
522 PPC_OP(setlr)
524 regs->lr = (uint32_t)PARAM1;
525 RETURN();
528 #if defined (TARGET_PPC64)
529 void OPPROTO op_setlr_64 (void)
531 regs->lr = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
532 RETURN();
534 #endif
536 PPC_OP(goto_tb0)
538 GOTO_TB(op_goto_tb0, PARAM1, 0);
541 PPC_OP(goto_tb1)
543 GOTO_TB(op_goto_tb1, PARAM1, 1);
546 void OPPROTO op_b_T1 (void)
548 regs->nip = (uint32_t)(T1 & ~3);
549 RETURN();
552 #if defined (TARGET_PPC64)
553 void OPPROTO op_b_T1_64 (void)
555 regs->nip = (uint64_t)(T1 & ~3);
556 RETURN();
558 #endif
560 PPC_OP(jz_T0)
562 if (!T0)
563 GOTO_LABEL_PARAM(1);
564 RETURN();
567 void OPPROTO op_btest_T1 (void)
569 if (T0) {
570 regs->nip = (uint32_t)(T1 & ~3);
571 } else {
572 regs->nip = (uint32_t)PARAM1;
574 RETURN();
577 #if defined (TARGET_PPC64)
578 void OPPROTO op_btest_T1_64 (void)
580 if (T0) {
581 regs->nip = (uint64_t)(T1 & ~3);
582 } else {
583 regs->nip = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
585 RETURN();
587 #endif
589 PPC_OP(movl_T1_ctr)
591 T1 = regs->ctr;
592 RETURN();
595 PPC_OP(movl_T1_lr)
597 T1 = regs->lr;
598 RETURN();
601 /* tests with result in T0 */
602 void OPPROTO op_test_ctr (void)
604 T0 = (uint32_t)regs->ctr;
605 RETURN();
608 #if defined(TARGET_PPC64)
609 void OPPROTO op_test_ctr_64 (void)
611 T0 = (uint64_t)regs->ctr;
612 RETURN();
614 #endif
616 void OPPROTO op_test_ctr_true (void)
618 T0 = ((uint32_t)regs->ctr != 0 && (T0 & PARAM1) != 0);
619 RETURN();
622 #if defined(TARGET_PPC64)
623 void OPPROTO op_test_ctr_true_64 (void)
625 T0 = ((uint64_t)regs->ctr != 0 && (T0 & PARAM1) != 0);
626 RETURN();
628 #endif
630 void OPPROTO op_test_ctr_false (void)
632 T0 = ((uint32_t)regs->ctr != 0 && (T0 & PARAM1) == 0);
633 RETURN();
636 #if defined(TARGET_PPC64)
637 void OPPROTO op_test_ctr_false_64 (void)
639 T0 = ((uint64_t)regs->ctr != 0 && (T0 & PARAM1) == 0);
640 RETURN();
642 #endif
644 void OPPROTO op_test_ctrz (void)
646 T0 = ((uint32_t)regs->ctr == 0);
647 RETURN();
650 #if defined(TARGET_PPC64)
651 void OPPROTO op_test_ctrz_64 (void)
653 T0 = ((uint64_t)regs->ctr == 0);
654 RETURN();
656 #endif
658 void OPPROTO op_test_ctrz_true (void)
660 T0 = ((uint32_t)regs->ctr == 0 && (T0 & PARAM1) != 0);
661 RETURN();
664 #if defined(TARGET_PPC64)
665 void OPPROTO op_test_ctrz_true_64 (void)
667 T0 = ((uint64_t)regs->ctr == 0 && (T0 & PARAM1) != 0);
668 RETURN();
670 #endif
672 void OPPROTO op_test_ctrz_false (void)
674 T0 = ((uint32_t)regs->ctr == 0 && (T0 & PARAM1) == 0);
675 RETURN();
678 #if defined(TARGET_PPC64)
679 void OPPROTO op_test_ctrz_false_64 (void)
681 T0 = ((uint64_t)regs->ctr == 0 && (T0 & PARAM1) == 0);
682 RETURN();
684 #endif
686 PPC_OP(test_true)
688 T0 = (T0 & PARAM(1));
689 RETURN();
692 PPC_OP(test_false)
694 T0 = ((T0 & PARAM(1)) == 0);
695 RETURN();
698 /* CTR maintenance */
699 PPC_OP(dec_ctr)
701 regs->ctr--;
702 RETURN();
705 /*** Integer arithmetic ***/
706 /* add */
707 PPC_OP(add)
709 T0 += T1;
710 RETURN();
713 void OPPROTO op_check_addo (void)
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;
722 RETURN();
725 #if defined(TARGET_PPC64)
726 void OPPROTO op_check_addo_64 (void)
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;
735 RETURN();
737 #endif
739 /* add carrying */
740 void OPPROTO op_check_addc (void)
742 if (likely((uint32_t)T0 >= (uint32_t)T2)) {
743 xer_ca = 0;
744 } else {
745 xer_ca = 1;
747 RETURN();
750 #if defined(TARGET_PPC64)
751 void OPPROTO op_check_addc_64 (void)
753 if (likely((uint64_t)T0 >= (uint64_t)T2)) {
754 xer_ca = 0;
755 } else {
756 xer_ca = 1;
758 RETURN();
760 #endif
762 /* add extended */
763 void OPPROTO op_adde (void)
765 do_adde();
766 RETURN();
769 #if defined(TARGET_PPC64)
770 void OPPROTO op_adde_64 (void)
772 do_adde_64();
773 RETURN();
775 #endif
777 /* add immediate */
778 PPC_OP(addi)
780 T0 += PARAM(1);
781 RETURN();
784 /* add to minus one extended */
785 void OPPROTO op_add_me (void)
787 T0 += xer_ca + (-1);
788 if (likely((uint32_t)T1 != 0))
789 xer_ca = 1;
790 RETURN();
793 #if defined(TARGET_PPC64)
794 void OPPROTO op_add_me_64 (void)
796 T0 += xer_ca + (-1);
797 if (likely((uint64_t)T1 != 0))
798 xer_ca = 1;
799 RETURN();
801 #endif
803 void OPPROTO op_addmeo (void)
805 do_addmeo();
806 RETURN();
809 void OPPROTO op_addmeo_64 (void)
811 do_addmeo();
812 RETURN();
815 /* add to zero extended */
816 void OPPROTO op_add_ze (void)
818 T0 += xer_ca;
819 RETURN();
822 /* divide word */
823 void OPPROTO op_divw (void)
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;
831 RETURN();
834 #if defined(TARGET_PPC64)
835 void OPPROTO op_divd (void)
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;
843 RETURN();
845 #endif
847 void OPPROTO op_divwo (void)
849 do_divwo();
850 RETURN();
853 #if defined(TARGET_PPC64)
854 void OPPROTO op_divdo (void)
856 do_divdo();
857 RETURN();
859 #endif
861 /* divide word unsigned */
862 void OPPROTO op_divwu (void)
864 if (unlikely(T1 == 0)) {
865 T0 = 0;
866 } else {
867 T0 = (uint32_t)T0 / (uint32_t)T1;
869 RETURN();
872 #if defined(TARGET_PPC64)
873 void OPPROTO op_divdu (void)
875 if (unlikely(T1 == 0)) {
876 T0 = 0;
877 } else {
878 T0 /= T1;
880 RETURN();
882 #endif
884 void OPPROTO op_divwuo (void)
886 do_divwuo();
887 RETURN();
890 #if defined(TARGET_PPC64)
891 void OPPROTO op_divduo (void)
893 do_divduo();
894 RETURN();
896 #endif
898 /* multiply high word */
899 void OPPROTO op_mulhw (void)
901 T0 = ((int64_t)((int32_t)T0) * (int64_t)((int32_t)T1)) >> 32;
902 RETURN();
905 #if defined(TARGET_PPC64)
906 void OPPROTO op_mulhd (void)
908 uint64_t tl, th;
910 do_imul64(&tl, &th);
911 T0 = th;
912 RETURN();
914 #endif
916 /* multiply high word unsigned */
917 void OPPROTO op_mulhwu (void)
919 T0 = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1) >> 32;
920 RETURN();
923 #if defined(TARGET_PPC64)
924 void OPPROTO op_mulhdu (void)
926 uint64_t tl, th;
928 do_mul64(&tl, &th);
929 T0 = th;
930 RETURN();
932 #endif
934 /* multiply low immediate */
935 PPC_OP(mulli)
937 T0 = ((int32_t)T0 * (int32_t)PARAM1);
938 RETURN();
941 /* multiply low word */
942 PPC_OP(mullw)
944 T0 = (int32_t)(T0 * T1);
945 RETURN();
948 #if defined(TARGET_PPC64)
949 void OPPROTO op_mulld (void)
951 T0 *= T1;
952 RETURN();
954 #endif
956 void OPPROTO op_mullwo (void)
958 do_mullwo();
959 RETURN();
962 #if defined(TARGET_PPC64)
963 void OPPROTO op_mulldo (void)
965 do_mulldo();
966 RETURN();
968 #endif
970 /* negate */
971 void OPPROTO op_neg (void)
973 if (likely(T0 != INT32_MIN)) {
974 T0 = -(int32_t)T0;
976 RETURN();
979 #if defined(TARGET_PPC64)
980 void OPPROTO op_neg_64 (void)
982 if (likely(T0 != INT64_MIN)) {
983 T0 = -(int64_t)T0;
985 RETURN();
987 #endif
989 void OPPROTO op_nego (void)
991 do_nego();
992 RETURN();
995 #if defined(TARGET_PPC64)
996 void OPPROTO op_nego_64 (void)
998 do_nego_64();
999 RETURN();
1001 #endif
1003 /* substract from */
1004 PPC_OP(subf)
1006 T0 = T1 - T0;
1007 RETURN();
1010 void OPPROTO op_check_subfo (void)
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;
1019 RETURN();
1022 #if defined(TARGET_PPC64)
1023 void OPPROTO op_check_subfo_64 (void)
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;
1032 RETURN();
1034 #endif
1036 /* substract from carrying */
1037 void OPPROTO op_check_subfc (void)
1039 if (likely((uint32_t)T0 > (uint32_t)T1)) {
1040 xer_ca = 0;
1041 } else {
1042 xer_ca = 1;
1044 RETURN();
1047 #if defined(TARGET_PPC64)
1048 void OPPROTO op_check_subfc_64 (void)
1050 if (likely((uint64_t)T0 > (uint64_t)T1)) {
1051 xer_ca = 0;
1052 } else {
1053 xer_ca = 1;
1055 RETURN();
1057 #endif
1059 /* substract from extended */
1060 void OPPROTO op_subfe (void)
1062 do_subfe();
1063 RETURN();
1066 #if defined(TARGET_PPC64)
1067 void OPPROTO op_subfe_64 (void)
1069 do_subfe_64();
1070 RETURN();
1072 #endif
1074 /* substract from immediate carrying */
1075 void OPPROTO op_subfic (void)
1077 T0 = PARAM1 + ~T0 + 1;
1078 if ((uint32_t)T0 <= (uint32_t)PARAM1) {
1079 xer_ca = 1;
1080 } else {
1081 xer_ca = 0;
1083 RETURN();
1086 #if defined(TARGET_PPC64)
1087 void OPPROTO op_subfic_64 (void)
1089 T0 = PARAM1 + ~T0 + 1;
1090 if ((uint64_t)T0 <= (uint64_t)PARAM1) {
1091 xer_ca = 1;
1092 } else {
1093 xer_ca = 0;
1095 RETURN();
1097 #endif
1099 /* substract from minus one extended */
1100 void OPPROTO op_subfme (void)
1102 T0 = ~T0 + xer_ca - 1;
1103 if (likely((uint32_t)T0 != (uint32_t)-1))
1104 xer_ca = 1;
1105 RETURN();
1108 #if defined(TARGET_PPC64)
1109 void OPPROTO op_subfme_64 (void)
1111 T0 = ~T0 + xer_ca - 1;
1112 if (likely((uint64_t)T0 != (uint64_t)-1))
1113 xer_ca = 1;
1114 RETURN();
1116 #endif
1118 void OPPROTO op_subfmeo (void)
1120 do_subfmeo();
1121 RETURN();
1124 #if defined(TARGET_PPC64)
1125 void OPPROTO op_subfmeo_64 (void)
1127 do_subfmeo_64();
1128 RETURN();
1130 #endif
1132 /* substract from zero extended */
1133 void OPPROTO op_subfze (void)
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;
1142 RETURN();
1145 #if defined(TARGET_PPC64)
1146 void OPPROTO op_subfze_64 (void)
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;
1155 RETURN();
1157 #endif
1159 void OPPROTO op_subfzeo (void)
1161 do_subfzeo();
1162 RETURN();
1165 #if defined(TARGET_PPC64)
1166 void OPPROTO op_subfzeo_64 (void)
1168 do_subfzeo_64();
1169 RETURN();
1171 #endif
1173 /*** Integer comparison ***/
1174 /* compare */
1175 void OPPROTO op_cmp (void)
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;
1184 RETURN();
1187 #if defined(TARGET_PPC64)
1188 void OPPROTO op_cmp_64 (void)
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;
1197 RETURN();
1199 #endif
1201 /* compare immediate */
1202 void OPPROTO op_cmpi (void)
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;
1211 RETURN();
1214 #if defined(TARGET_PPC64)
1215 void OPPROTO op_cmpi_64 (void)
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;
1224 RETURN();
1226 #endif
1228 /* compare logical */
1229 void OPPROTO op_cmpl (void)
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;
1238 RETURN();
1241 #if defined(TARGET_PPC64)
1242 void OPPROTO op_cmpl_64 (void)
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;
1251 RETURN();
1253 #endif
1255 /* compare logical immediate */
1256 void OPPROTO op_cmpli (void)
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;
1265 RETURN();
1268 #if defined(TARGET_PPC64)
1269 void OPPROTO op_cmpli_64 (void)
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;
1278 RETURN();
1280 #endif
1282 void OPPROTO op_isel (void)
1284 if (T0)
1285 T0 = T1;
1286 else
1287 T0 = T2;
1288 RETURN();
1291 void OPPROTO op_popcntb (void)
1293 do_popcntb();
1294 RETURN();
1297 #if defined(TARGET_PPC64)
1298 void OPPROTO op_popcntb_64 (void)
1300 do_popcntb_64();
1301 RETURN();
1303 #endif
1305 /*** Integer logical ***/
1306 /* and */
1307 PPC_OP(and)
1309 T0 &= T1;
1310 RETURN();
1313 /* andc */
1314 PPC_OP(andc)
1316 T0 &= ~T1;
1317 RETURN();
1320 /* andi. */
1321 void OPPROTO op_andi_T0 (void)
1323 T0 &= PARAM(1);
1324 RETURN();
1327 void OPPROTO op_andi_T1 (void)
1329 T1 &= PARAM1;
1330 RETURN();
1333 /* count leading zero */
1334 void OPPROTO op_cntlzw (void)
1336 T0 = _do_cntlzw(T0);
1337 RETURN();
1340 #if defined(TARGET_PPC64)
1341 void OPPROTO op_cntlzd (void)
1343 T0 = _do_cntlzd(T0);
1344 RETURN();
1346 #endif
1348 /* eqv */
1349 PPC_OP(eqv)
1351 T0 = ~(T0 ^ T1);
1352 RETURN();
1355 /* extend sign byte */
1356 void OPPROTO op_extsb (void)
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();
1366 /* extend sign half word */
1367 void OPPROTO op_extsh (void)
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();
1377 #if defined (TARGET_PPC64)
1378 void OPPROTO op_extsw (void)
1380 T0 = (int64_t)((int32_t)T0);
1381 RETURN();
1383 #endif
1385 /* nand */
1386 PPC_OP(nand)
1388 T0 = ~(T0 & T1);
1389 RETURN();
1392 /* nor */
1393 PPC_OP(nor)
1395 T0 = ~(T0 | T1);
1396 RETURN();
1399 /* or */
1400 PPC_OP(or)
1402 T0 |= T1;
1403 RETURN();
1406 /* orc */
1407 PPC_OP(orc)
1409 T0 |= ~T1;
1410 RETURN();
1413 /* ori */
1414 PPC_OP(ori)
1416 T0 |= PARAM(1);
1417 RETURN();
1420 /* xor */
1421 PPC_OP(xor)
1423 T0 ^= T1;
1424 RETURN();
1427 /* xori */
1428 PPC_OP(xori)
1430 T0 ^= PARAM(1);
1431 RETURN();
1434 /*** Integer rotate ***/
1435 void OPPROTO op_rotl32_T0_T1 (void)
1437 T0 = rotl32(T0, T1 & 0x1F);
1438 RETURN();
1441 void OPPROTO op_rotli32_T0 (void)
1443 T0 = rotl32(T0, PARAM1);
1444 RETURN();
1447 #if defined(TARGET_PPC64)
1448 void OPPROTO op_rotl64_T0_T1 (void)
1450 T0 = rotl64(T0, T1 & 0x3F);
1451 RETURN();
1454 void OPPROTO op_rotli64_T0 (void)
1456 T0 = rotl64(T0, PARAM1);
1457 RETURN();
1459 #endif
1461 /*** Integer shift ***/
1462 /* shift left word */
1463 void OPPROTO op_slw (void)
1465 if (T1 & 0x20) {
1466 T0 = 0;
1467 } else {
1468 T0 = (uint32_t)(T0 << T1);
1470 RETURN();
1473 #if defined(TARGET_PPC64)
1474 void OPPROTO op_sld (void)
1476 if (T1 & 0x40) {
1477 T0 = 0;
1478 } else {
1479 T0 = T0 << T1;
1481 RETURN();
1483 #endif
1485 /* shift right algebraic word */
1486 void OPPROTO op_sraw (void)
1488 do_sraw();
1489 RETURN();
1492 #if defined(TARGET_PPC64)
1493 void OPPROTO op_srad (void)
1495 do_srad();
1496 RETURN();
1498 #endif
1500 /* shift right algebraic word immediate */
1501 void OPPROTO op_srawi (void)
1503 uint32_t mask = (uint32_t)PARAM2;
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;
1511 RETURN();
1514 #if defined(TARGET_PPC64)
1515 void OPPROTO op_sradi (void)
1517 uint64_t mask = ((uint64_t)PARAM2 << 32) | (uint64_t)PARAM3;
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;
1525 RETURN();
1527 #endif
1529 /* shift right word */
1530 void OPPROTO op_srw (void)
1532 if (T1 & 0x20) {
1533 T0 = 0;
1534 } else {
1535 T0 = (uint32_t)T0 >> T1;
1537 RETURN();
1540 #if defined(TARGET_PPC64)
1541 void OPPROTO op_srd (void)
1543 if (T1 & 0x40) {
1544 T0 = 0;
1545 } else {
1546 T0 = (uint64_t)T0 >> T1;
1548 RETURN();
1550 #endif
1552 void OPPROTO op_sl_T0_T1 (void)
1554 T0 = T0 << T1;
1555 RETURN();
1558 void OPPROTO op_sli_T0 (void)
1560 T0 = T0 << PARAM1;
1561 RETURN();
1564 void OPPROTO op_srl_T0_T1 (void)
1566 T0 = (uint32_t)T0 >> T1;
1567 RETURN();
1570 #if defined(TARGET_PPC64)
1571 void OPPROTO op_srl_T0_T1_64 (void)
1573 T0 = (uint32_t)T0 >> T1;
1574 RETURN();
1576 #endif
1578 void OPPROTO op_srli_T0 (void)
1580 T0 = (uint32_t)T0 >> PARAM1;
1581 RETURN();
1584 #if defined(TARGET_PPC64)
1585 void OPPROTO op_srli_T0_64 (void)
1587 T0 = (uint64_t)T0 >> PARAM1;
1588 RETURN();
1590 #endif
1592 void OPPROTO op_srli_T1 (void)
1594 T1 = (uint32_t)T1 >> PARAM1;
1595 RETURN();
1598 #if defined(TARGET_PPC64)
1599 void OPPROTO op_srli_T1_64 (void)
1601 T1 = (uint64_t)T1 >> PARAM1;
1602 RETURN();
1604 #endif
1606 /*** Floating-Point arithmetic ***/
1607 /* fadd - fadd. */
1608 PPC_OP(fadd)
1610 FT0 = float64_add(FT0, FT1, &env->fp_status);
1611 RETURN();
1614 /* fsub - fsub. */
1615 PPC_OP(fsub)
1617 FT0 = float64_sub(FT0, FT1, &env->fp_status);
1618 RETURN();
1621 /* fmul - fmul. */
1622 PPC_OP(fmul)
1624 FT0 = float64_mul(FT0, FT1, &env->fp_status);
1625 RETURN();
1628 /* fdiv - fdiv. */
1629 PPC_OP(fdiv)
1631 FT0 = float64_div(FT0, FT1, &env->fp_status);
1632 RETURN();
1635 /* fsqrt - fsqrt. */
1636 PPC_OP(fsqrt)
1638 do_fsqrt();
1639 RETURN();
1642 /* fres - fres. */
1643 PPC_OP(fres)
1645 do_fres();
1646 RETURN();
1649 /* frsqrte - frsqrte. */
1650 PPC_OP(frsqrte)
1652 do_frsqrte();
1653 RETURN();
1656 /* fsel - fsel. */
1657 PPC_OP(fsel)
1659 do_fsel();
1660 RETURN();
1663 /*** Floating-Point multiply-and-add ***/
1664 /* fmadd - fmadd. */
1665 PPC_OP(fmadd)
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();
1676 /* fmsub - fmsub. */
1677 PPC_OP(fmsub)
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();
1688 /* fnmadd - fnmadd. - fnmadds - fnmadds. */
1689 PPC_OP(fnmadd)
1691 do_fnmadd();
1692 RETURN();
1695 /* fnmsub - fnmsub. */
1696 PPC_OP(fnmsub)
1698 do_fnmsub();
1699 RETURN();
1702 /*** Floating-Point round & convert ***/
1703 /* frsp - frsp. */
1704 PPC_OP(frsp)
1706 FT0 = float64_to_float32(FT0, &env->fp_status);
1707 RETURN();
1710 /* fctiw - fctiw. */
1711 PPC_OP(fctiw)
1713 do_fctiw();
1714 RETURN();
1717 /* fctiwz - fctiwz. */
1718 PPC_OP(fctiwz)
1720 do_fctiwz();
1721 RETURN();
1724 #if defined(TARGET_PPC64)
1725 /* fcfid - fcfid. */
1726 PPC_OP(fcfid)
1728 do_fcfid();
1729 RETURN();
1732 /* fctid - fctid. */
1733 PPC_OP(fctid)
1735 do_fctid();
1736 RETURN();
1739 /* fctidz - fctidz. */
1740 PPC_OP(fctidz)
1742 do_fctidz();
1743 RETURN();
1745 #endif
1747 /*** Floating-Point compare ***/
1748 /* fcmpu */
1749 PPC_OP(fcmpu)
1751 do_fcmpu();
1752 RETURN();
1755 /* fcmpo */
1756 PPC_OP(fcmpo)
1758 do_fcmpo();
1759 RETURN();
1762 /*** Floating-point move ***/
1763 /* fabs */
1764 PPC_OP(fabs)
1766 FT0 = float64_abs(FT0);
1767 RETURN();
1770 /* fnabs */
1771 PPC_OP(fnabs)
1773 FT0 = float64_abs(FT0);
1774 FT0 = float64_chs(FT0);
1775 RETURN();
1778 /* fneg */
1779 PPC_OP(fneg)
1781 FT0 = float64_chs(FT0);
1782 RETURN();
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
1798 /* Special op to check and maybe clear reservation */
1799 void OPPROTO op_check_reservation (void)
1801 if ((uint32_t)env->reserve == (uint32_t)(T0 & ~0x00000003))
1802 env->reserve = -1;
1803 RETURN();
1806 #if defined(TARGET_PPC64)
1807 void OPPROTO op_check_reservation_64 (void)
1809 if ((uint64_t)env->reserve == (uint64_t)(T0 & ~0x00000003))
1810 env->reserve = -1;
1811 RETURN();
1813 #endif
1815 /* Return from interrupt */
1816 #if !defined(CONFIG_USER_ONLY)
1817 void OPPROTO op_rfi (void)
1819 do_rfi();
1820 RETURN();
1823 #if defined(TARGET_PPC64)
1824 void OPPROTO op_rfi_32 (void)
1826 do_rfi_32();
1827 RETURN();
1830 void OPPROTO op_rfid (void)
1832 do_rfid();
1833 RETURN();
1836 void OPPROTO op_rfid_32 (void)
1838 do_rfid_32();
1839 RETURN();
1841 #endif
1842 #endif
1844 /* Trap word */
1845 void OPPROTO op_tw (void)
1847 do_tw(PARAM1);
1848 RETURN();
1851 #if defined(TARGET_PPC64)
1852 void OPPROTO op_td (void)
1854 do_td(PARAM1);
1855 RETURN();
1857 #endif
1859 #if !defined(CONFIG_USER_ONLY)
1860 /* tlbia */
1861 PPC_OP(tlbia)
1863 do_tlbia();
1864 RETURN();
1867 /* tlbie */
1868 void OPPROTO op_tlbie (void)
1870 do_tlbie();
1871 RETURN();
1874 #if defined(TARGET_PPC64)
1875 void OPPROTO op_tlbie_64 (void)
1877 do_tlbie_64();
1878 RETURN();
1880 #endif
1882 #if defined(TARGET_PPC64)
1883 void OPPROTO op_slbia (void)
1885 do_slbia();
1886 RETURN();
1889 void OPPROTO op_slbie (void)
1891 do_slbie();
1892 RETURN();
1894 #endif
1895 #endif
1897 /* PowerPC 602/603/755 software TLB load instructions */
1898 #if !defined(CONFIG_USER_ONLY)
1899 void OPPROTO op_6xx_tlbld (void)
1901 do_load_6xx_tlb(0);
1902 RETURN();
1905 void OPPROTO op_6xx_tlbli (void)
1907 do_load_6xx_tlb(1);
1908 RETURN();
1910 #endif
1912 /* 601 specific */
1913 void OPPROTO op_load_601_rtcl (void)
1915 T0 = cpu_ppc601_load_rtcl(env);
1916 RETURN();
1919 void OPPROTO op_load_601_rtcu (void)
1921 T0 = cpu_ppc601_load_rtcu(env);
1922 RETURN();
1925 #if !defined(CONFIG_USER_ONLY)
1926 void OPPROTO op_store_601_rtcl (void)
1928 cpu_ppc601_store_rtcl(env, T0);
1929 RETURN();
1932 void OPPROTO op_store_601_rtcu (void)
1934 cpu_ppc601_store_rtcu(env, T0);
1935 RETURN();
1938 void OPPROTO op_load_601_bat (void)
1940 T0 = env->IBAT[PARAM1][PARAM2];
1941 RETURN();
1943 #endif /* !defined(CONFIG_USER_ONLY) */
1945 /* 601 unified BATs store.
1946 * To avoid using specific MMU code for 601, we store BATs in
1947 * IBAT and DBAT simultaneously, then emulate unified BATs.
1949 #if !defined(CONFIG_USER_ONLY)
1950 void OPPROTO op_store_601_batl (void)
1952 int nr = PARAM1;
1954 env->IBAT[1][nr] = T0;
1955 env->DBAT[1][nr] = T0;
1956 RETURN();
1959 void OPPROTO op_store_601_batu (void)
1961 do_store_601_batu(PARAM1);
1962 RETURN();
1964 #endif /* !defined(CONFIG_USER_ONLY) */
1966 /* PowerPC 601 specific instructions (POWER bridge) */
1967 /* XXX: those micro-ops need tests ! */
1968 void OPPROTO op_POWER_abs (void)
1970 if (T0 == INT32_MIN)
1971 T0 = INT32_MAX;
1972 else if (T0 < 0)
1973 T0 = -T0;
1974 RETURN();
1977 void OPPROTO op_POWER_abso (void)
1979 do_POWER_abso();
1980 RETURN();
1983 void OPPROTO op_POWER_clcs (void)
1985 do_POWER_clcs();
1986 RETURN();
1989 void OPPROTO op_POWER_div (void)
1991 do_POWER_div();
1992 RETURN();
1995 void OPPROTO op_POWER_divo (void)
1997 do_POWER_divo();
1998 RETURN();
2001 void OPPROTO op_POWER_divs (void)
2003 do_POWER_divs();
2004 RETURN();
2007 void OPPROTO op_POWER_divso (void)
2009 do_POWER_divso();
2010 RETURN();
2013 void OPPROTO op_POWER_doz (void)
2015 if ((int32_t)T1 > (int32_t)T0)
2016 T0 = T1 - T0;
2017 else
2018 T0 = 0;
2019 RETURN();
2022 void OPPROTO op_POWER_dozo (void)
2024 do_POWER_dozo();
2025 RETURN();
2028 void OPPROTO op_load_xer_cmp (void)
2030 T2 = xer_cmp;
2031 RETURN();
2034 void OPPROTO op_POWER_maskg (void)
2036 do_POWER_maskg();
2037 RETURN();
2040 void OPPROTO op_POWER_maskir (void)
2042 T0 = (T0 & ~T2) | (T1 & T2);
2043 RETURN();
2046 void OPPROTO op_POWER_mul (void)
2048 uint64_t tmp;
2050 tmp = (uint64_t)T0 * (uint64_t)T1;
2051 env->spr[SPR_MQ] = tmp >> 32;
2052 T0 = tmp;
2053 RETURN();
2056 void OPPROTO op_POWER_mulo (void)
2058 do_POWER_mulo();
2059 RETURN();
2062 void OPPROTO op_POWER_nabs (void)
2064 if (T0 > 0)
2065 T0 = -T0;
2066 RETURN();
2069 void OPPROTO op_POWER_nabso (void)
2071 /* nabs never overflows */
2072 if (T0 > 0)
2073 T0 = -T0;
2074 xer_ov = 0;
2075 RETURN();
2078 /* XXX: factorise POWER rotates... */
2079 void OPPROTO op_POWER_rlmi (void)
2081 T0 = rotl32(T0, T2) & PARAM1;
2082 T0 |= T1 & PARAM2;
2083 RETURN();
2086 void OPPROTO op_POWER_rrib (void)
2088 T2 &= 0x1FUL;
2089 T0 = rotl32(T0 & INT32_MIN, T2);
2090 T0 |= T1 & ~rotl32(INT32_MIN, T2);
2091 RETURN();
2094 void OPPROTO op_POWER_sle (void)
2096 T1 &= 0x1FUL;
2097 env->spr[SPR_MQ] = rotl32(T0, T1);
2098 T0 = T0 << T1;
2099 RETURN();
2102 void OPPROTO op_POWER_sleq (void)
2104 uint32_t tmp = env->spr[SPR_MQ];
2106 T1 &= 0x1FUL;
2107 env->spr[SPR_MQ] = rotl32(T0, T1);
2108 T0 = T0 << T1;
2109 T0 |= tmp >> (32 - T1);
2110 RETURN();
2113 void OPPROTO op_POWER_sllq (void)
2115 uint32_t msk = -1;
2117 msk = msk << (T1 & 0x1FUL);
2118 if (T1 & 0x20UL)
2119 msk = ~msk;
2120 T1 &= 0x1FUL;
2121 T0 = (T0 << T1) & msk;
2122 T0 |= env->spr[SPR_MQ] & ~msk;
2123 RETURN();
2126 void OPPROTO op_POWER_slq (void)
2128 uint32_t msk = -1, tmp;
2130 msk = msk << (T1 & 0x1FUL);
2131 if (T1 & 0x20UL)
2132 msk = ~msk;
2133 T1 &= 0x1FUL;
2134 tmp = rotl32(T0, T1);
2135 T0 = tmp & msk;
2136 env->spr[SPR_MQ] = tmp;
2137 RETURN();
2140 void OPPROTO op_POWER_sraq (void)
2142 env->spr[SPR_MQ] = rotl32(T0, 32 - (T1 & 0x1FUL));
2143 if (T1 & 0x20UL)
2144 T0 = -1L;
2145 else
2146 T0 = (int32_t)T0 >> T1;
2147 RETURN();
2150 void OPPROTO op_POWER_sre (void)
2152 T1 &= 0x1FUL;
2153 env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2154 T0 = (int32_t)T0 >> T1;
2155 RETURN();
2158 void OPPROTO op_POWER_srea (void)
2160 T1 &= 0x1FUL;
2161 env->spr[SPR_MQ] = T0 >> T1;
2162 T0 = (int32_t)T0 >> T1;
2163 RETURN();
2166 void OPPROTO op_POWER_sreq (void)
2168 uint32_t tmp;
2169 int32_t msk;
2171 T1 &= 0x1FUL;
2172 msk = INT32_MIN >> T1;
2173 tmp = env->spr[SPR_MQ];
2174 env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2175 T0 = T0 >> T1;
2176 T0 |= tmp & msk;
2177 RETURN();
2180 void OPPROTO op_POWER_srlq (void)
2182 uint32_t tmp;
2183 int32_t msk;
2185 msk = INT32_MIN >> (T1 & 0x1FUL);
2186 if (T1 & 0x20UL)
2187 msk = ~msk;
2188 T1 &= 0x1FUL;
2189 tmp = env->spr[SPR_MQ];
2190 env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2191 T0 = T0 >> T1;
2192 T0 &= msk;
2193 T0 |= tmp & ~msk;
2194 RETURN();
2197 void OPPROTO op_POWER_srq (void)
2199 T1 &= 0x1FUL;
2200 env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2201 T0 = T0 >> T1;
2202 RETURN();
2205 /* POWER instructions not implemented in PowerPC 601 */
2206 #if !defined(CONFIG_USER_ONLY)
2207 void OPPROTO op_POWER_mfsri (void)
2209 T1 = T0 >> 28;
2210 T0 = env->sr[T1];
2211 RETURN();
2214 void OPPROTO op_POWER_rac (void)
2216 do_POWER_rac();
2217 RETURN();
2220 void OPPROTO op_POWER_rfsvc (void)
2222 do_POWER_rfsvc();
2223 RETURN();
2225 #endif
2227 /* PowerPC 602 specific instruction */
2228 #if !defined(CONFIG_USER_ONLY)
2229 void OPPROTO op_602_mfrom (void)
2231 do_op_602_mfrom();
2232 RETURN();
2234 #endif
2236 /* PowerPC 4xx specific micro-ops */
2237 void OPPROTO op_405_add_T0_T2 (void)
2239 T0 = (int32_t)T0 + (int32_t)T2;
2240 RETURN();
2243 void OPPROTO op_405_mulchw (void)
2245 T0 = ((int16_t)T0) * ((int16_t)(T1 >> 16));
2246 RETURN();
2249 void OPPROTO op_405_mulchwu (void)
2251 T0 = ((uint16_t)T0) * ((uint16_t)(T1 >> 16));
2252 RETURN();
2255 void OPPROTO op_405_mulhhw (void)
2257 T0 = ((int16_t)(T0 >> 16)) * ((int16_t)(T1 >> 16));
2258 RETURN();
2261 void OPPROTO op_405_mulhhwu (void)
2263 T0 = ((uint16_t)(T0 >> 16)) * ((uint16_t)(T1 >> 16));
2264 RETURN();
2267 void OPPROTO op_405_mullhw (void)
2269 T0 = ((int16_t)T0) * ((int16_t)T1);
2270 RETURN();
2273 void OPPROTO op_405_mullhwu (void)
2275 T0 = ((uint16_t)T0) * ((uint16_t)T1);
2276 RETURN();
2279 void OPPROTO op_405_check_ov (void)
2281 do_405_check_ov();
2282 RETURN();
2285 void OPPROTO op_405_check_sat (void)
2287 do_405_check_sat();
2288 RETURN();
2291 void OPPROTO op_405_check_ovu (void)
2293 if (likely(T0 >= T2)) {
2294 xer_ov = 0;
2295 } else {
2296 xer_ov = 1;
2297 xer_so = 1;
2299 RETURN();
2302 void OPPROTO op_405_check_satu (void)
2304 if (unlikely(T0 < T2)) {
2305 /* Saturate result */
2306 T0 = -1;
2308 RETURN();
2311 #if !defined(CONFIG_USER_ONLY)
2312 void OPPROTO op_4xx_load_dcr (void)
2314 do_4xx_load_dcr(PARAM1);
2315 RETURN();
2318 void OPPROTO op_4xx_store_dcr (void)
2320 do_4xx_store_dcr(PARAM1);
2321 RETURN();
2324 /* Return from critical interrupt :
2325 * same as rfi, except nip & MSR are loaded from SRR2/3 instead of SRR0/1
2327 void OPPROTO op_4xx_rfci (void)
2329 do_4xx_rfci();
2330 RETURN();
2333 void OPPROTO op_4xx_wrte (void)
2335 msr_ee = T0 >> 16;
2336 RETURN();
2339 void OPPROTO op_4xx_tlbre_lo (void)
2341 do_4xx_tlbre_lo();
2342 RETURN();
2345 void OPPROTO op_4xx_tlbre_hi (void)
2347 do_4xx_tlbre_hi();
2348 RETURN();
2351 void OPPROTO op_4xx_tlbsx (void)
2353 do_4xx_tlbsx();
2354 RETURN();
2357 void OPPROTO op_4xx_tlbsx_ (void)
2359 do_4xx_tlbsx_();
2360 RETURN();
2363 void OPPROTO op_4xx_tlbwe_lo (void)
2365 do_4xx_tlbwe_lo();
2366 RETURN();
2369 void OPPROTO op_4xx_tlbwe_hi (void)
2371 do_4xx_tlbwe_hi();
2372 RETURN();
2374 #endif
2376 /* SPR micro-ops */
2377 /* 440 specific */
2378 void OPPROTO op_440_dlmzb (void)
2380 do_440_dlmzb();
2381 RETURN();
2384 void OPPROTO op_440_dlmzb_update_Rc (void)
2386 if (T0 == 8)
2387 T0 = 0x2;
2388 else if (T0 < 4)
2389 T0 = 0x4;
2390 else
2391 T0 = 0x8;
2392 RETURN();
2395 #if !defined(CONFIG_USER_ONLY)
2396 void OPPROTO op_store_pir (void)
2398 env->spr[SPR_PIR] = T0 & 0x0000000FUL;
2399 RETURN();
2402 void OPPROTO op_load_403_pb (void)
2404 do_load_403_pb(PARAM1);
2405 RETURN();
2408 void OPPROTO op_store_403_pb (void)
2410 do_store_403_pb(PARAM1);
2411 RETURN();
2414 void OPPROTO op_load_40x_pit (void)
2416 T0 = load_40x_pit(env);
2417 RETURN();
2420 void OPPROTO op_store_40x_pit (void)
2422 store_40x_pit(env, T0);
2423 RETURN();
2426 void OPPROTO op_store_booke_tcr (void)
2428 store_booke_tcr(env, T0);
2429 RETURN();
2432 void OPPROTO op_store_booke_tsr (void)
2434 store_booke_tsr(env, T0);
2435 RETURN();
2438 #endif /* !defined(CONFIG_USER_ONLY) */
2440 #if defined(TARGET_PPCSPE)
2441 /* SPE extension */
2442 void OPPROTO op_splatw_T1_64 (void)
2444 T1_64 = (T1_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL);
2445 RETURN();
2448 void OPPROTO op_splatwi_T0_64 (void)
2450 uint64_t tmp = PARAM1;
2452 T0_64 = (tmp << 32) | tmp;
2453 RETURN();
2456 void OPPROTO op_splatwi_T1_64 (void)
2458 uint64_t tmp = PARAM1;
2460 T1_64 = (tmp << 32) | tmp;
2461 RETURN();
2464 void OPPROTO op_extsh_T1_64 (void)
2466 T1_64 = (int32_t)((int16_t)T1_64);
2467 RETURN();
2470 void OPPROTO op_sli16_T1_64 (void)
2472 T1_64 = T1_64 << 16;
2473 RETURN();
2476 void OPPROTO op_sli32_T1_64 (void)
2478 T1_64 = T1_64 << 32;
2479 RETURN();
2482 void OPPROTO op_srli32_T1_64 (void)
2484 T1_64 = T1_64 >> 32;
2485 RETURN();
2488 void OPPROTO op_evsel (void)
2490 do_evsel();
2491 RETURN();
2494 void OPPROTO op_evaddw (void)
2496 do_evaddw();
2497 RETURN();
2500 void OPPROTO op_evsubfw (void)
2502 do_evsubfw();
2503 RETURN();
2506 void OPPROTO op_evneg (void)
2508 do_evneg();
2509 RETURN();
2512 void OPPROTO op_evabs (void)
2514 do_evabs();
2515 RETURN();
2518 void OPPROTO op_evextsh (void)
2520 T0_64 = ((uint64_t)((int32_t)(int16_t)(T0_64 >> 32)) << 32) |
2521 (uint64_t)((int32_t)(int16_t)T0_64);
2522 RETURN();
2525 void OPPROTO op_evextsb (void)
2527 T0_64 = ((uint64_t)((int32_t)(int8_t)(T0_64 >> 32)) << 32) |
2528 (uint64_t)((int32_t)(int8_t)T0_64);
2529 RETURN();
2532 void OPPROTO op_evcntlzw (void)
2534 do_evcntlzw();
2535 RETURN();
2538 void OPPROTO op_evrndw (void)
2540 do_evrndw();
2541 RETURN();
2544 void OPPROTO op_brinc (void)
2546 do_brinc();
2547 RETURN();
2550 void OPPROTO op_evcntlsw (void)
2552 do_evcntlsw();
2553 RETURN();
2556 void OPPROTO op_evand (void)
2558 T0_64 &= T1_64;
2559 RETURN();
2562 void OPPROTO op_evandc (void)
2564 T0_64 &= ~T1_64;
2565 RETURN();
2568 void OPPROTO op_evor (void)
2570 T0_64 |= T1_64;
2571 RETURN();
2574 void OPPROTO op_evxor (void)
2576 T0_64 ^= T1_64;
2577 RETURN();
2580 void OPPROTO op_eveqv (void)
2582 T0_64 = ~(T0_64 ^ T1_64);
2583 RETURN();
2586 void OPPROTO op_evnor (void)
2588 T0_64 = ~(T0_64 | T1_64);
2589 RETURN();
2592 void OPPROTO op_evorc (void)
2594 T0_64 |= ~T1_64;
2595 RETURN();
2598 void OPPROTO op_evnand (void)
2600 T0_64 = ~(T0_64 & T1_64);
2601 RETURN();
2604 void OPPROTO op_evsrws (void)
2606 do_evsrws();
2607 RETURN();
2610 void OPPROTO op_evsrwu (void)
2612 do_evsrwu();
2613 RETURN();
2616 void OPPROTO op_evslw (void)
2618 do_evslw();
2619 RETURN();
2622 void OPPROTO op_evrlw (void)
2624 do_evrlw();
2625 RETURN();
2628 void OPPROTO op_evmergelo (void)
2630 T0_64 = (T0_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL);
2631 RETURN();
2634 void OPPROTO op_evmergehi (void)
2636 T0_64 = (T0_64 & 0xFFFFFFFF00000000ULL) | (T1_64 >> 32);
2637 RETURN();
2640 void OPPROTO op_evmergelohi (void)
2642 T0_64 = (T0_64 << 32) | (T1_64 >> 32);
2643 RETURN();
2646 void OPPROTO op_evmergehilo (void)
2648 T0_64 = (T0_64 & 0xFFFFFFFF00000000ULL) | (T1_64 & 0x00000000FFFFFFFFULL);
2649 RETURN();
2652 void OPPROTO op_evcmpgts (void)
2654 do_evcmpgts();
2655 RETURN();
2658 void OPPROTO op_evcmpgtu (void)
2660 do_evcmpgtu();
2661 RETURN();
2664 void OPPROTO op_evcmplts (void)
2666 do_evcmplts();
2667 RETURN();
2670 void OPPROTO op_evcmpltu (void)
2672 do_evcmpltu();
2673 RETURN();
2676 void OPPROTO op_evcmpeq (void)
2678 do_evcmpeq();
2679 RETURN();
2682 void OPPROTO op_evfssub (void)
2684 do_evfssub();
2685 RETURN();
2688 void OPPROTO op_evfsadd (void)
2690 do_evfsadd();
2691 RETURN();
2694 void OPPROTO op_evfsnabs (void)
2696 do_evfsnabs();
2697 RETURN();
2700 void OPPROTO op_evfsabs (void)
2702 do_evfsabs();
2703 RETURN();
2706 void OPPROTO op_evfsneg (void)
2708 do_evfsneg();
2709 RETURN();
2712 void OPPROTO op_evfsdiv (void)
2714 do_evfsdiv();
2715 RETURN();
2718 void OPPROTO op_evfsmul (void)
2720 do_evfsmul();
2721 RETURN();
2724 void OPPROTO op_evfscmplt (void)
2726 do_evfscmplt();
2727 RETURN();
2730 void OPPROTO op_evfscmpgt (void)
2732 do_evfscmpgt();
2733 RETURN();
2736 void OPPROTO op_evfscmpeq (void)
2738 do_evfscmpeq();
2739 RETURN();
2742 void OPPROTO op_evfscfsi (void)
2744 do_evfscfsi();
2745 RETURN();
2748 void OPPROTO op_evfscfui (void)
2750 do_evfscfui();
2751 RETURN();
2754 void OPPROTO op_evfscfsf (void)
2756 do_evfscfsf();
2757 RETURN();
2760 void OPPROTO op_evfscfuf (void)
2762 do_evfscfuf();
2763 RETURN();
2766 void OPPROTO op_evfsctsi (void)
2768 do_evfsctsi();
2769 RETURN();
2772 void OPPROTO op_evfsctui (void)
2774 do_evfsctui();
2775 RETURN();
2778 void OPPROTO op_evfsctsf (void)
2780 do_evfsctsf();
2781 RETURN();
2784 void OPPROTO op_evfsctuf (void)
2786 do_evfsctuf();
2787 RETURN();
2790 void OPPROTO op_evfsctuiz (void)
2792 do_evfsctuiz();
2793 RETURN();
2796 void OPPROTO op_evfsctsiz (void)
2798 do_evfsctsiz();
2799 RETURN();
2802 void OPPROTO op_evfststlt (void)
2804 do_evfststlt();
2805 RETURN();
2808 void OPPROTO op_evfststgt (void)
2810 do_evfststgt();
2811 RETURN();
2814 void OPPROTO op_evfststeq (void)
2816 do_evfststeq();
2817 RETURN();
2820 void OPPROTO op_efssub (void)
2822 T0_64 = _do_efssub(T0_64, T1_64);
2823 RETURN();
2826 void OPPROTO op_efsadd (void)
2828 T0_64 = _do_efsadd(T0_64, T1_64);
2829 RETURN();
2832 void OPPROTO op_efsnabs (void)
2834 T0_64 = _do_efsnabs(T0_64);
2835 RETURN();
2838 void OPPROTO op_efsabs (void)
2840 T0_64 = _do_efsabs(T0_64);
2841 RETURN();
2844 void OPPROTO op_efsneg (void)
2846 T0_64 = _do_efsneg(T0_64);
2847 RETURN();
2850 void OPPROTO op_efsdiv (void)
2852 T0_64 = _do_efsdiv(T0_64, T1_64);
2853 RETURN();
2856 void OPPROTO op_efsmul (void)
2858 T0_64 = _do_efsmul(T0_64, T1_64);
2859 RETURN();
2862 void OPPROTO op_efscmplt (void)
2864 do_efscmplt();
2865 RETURN();
2868 void OPPROTO op_efscmpgt (void)
2870 do_efscmpgt();
2871 RETURN();
2874 void OPPROTO op_efscfd (void)
2876 do_efscfd();
2877 RETURN();
2880 void OPPROTO op_efscmpeq (void)
2882 do_efscmpeq();
2883 RETURN();
2886 void OPPROTO op_efscfsi (void)
2888 do_efscfsi();
2889 RETURN();
2892 void OPPROTO op_efscfui (void)
2894 do_efscfui();
2895 RETURN();
2898 void OPPROTO op_efscfsf (void)
2900 do_efscfsf();
2901 RETURN();
2904 void OPPROTO op_efscfuf (void)
2906 do_efscfuf();
2907 RETURN();
2910 void OPPROTO op_efsctsi (void)
2912 do_efsctsi();
2913 RETURN();
2916 void OPPROTO op_efsctui (void)
2918 do_efsctui();
2919 RETURN();
2922 void OPPROTO op_efsctsf (void)
2924 do_efsctsf();
2925 RETURN();
2928 void OPPROTO op_efsctuf (void)
2930 do_efsctuf();
2931 RETURN();
2934 void OPPROTO op_efsctsiz (void)
2936 do_efsctsiz();
2937 RETURN();
2940 void OPPROTO op_efsctuiz (void)
2942 do_efsctuiz();
2943 RETURN();
2946 void OPPROTO op_efststlt (void)
2948 T0 = _do_efststlt(T0_64, T1_64);
2949 RETURN();
2952 void OPPROTO op_efststgt (void)
2954 T0 = _do_efststgt(T0_64, T1_64);
2955 RETURN();
2958 void OPPROTO op_efststeq (void)
2960 T0 = _do_efststeq(T0_64, T1_64);
2961 RETURN();
2964 void OPPROTO op_efdsub (void)
2966 union {
2967 uint64_t u;
2968 float64 f;
2969 } u1, u2;
2970 u1.u = T0_64;
2971 u2.u = T1_64;
2972 u1.f = float64_sub(u1.f, u2.f, &env->spe_status);
2973 T0_64 = u1.u;
2974 RETURN();
2977 void OPPROTO op_efdadd (void)
2979 union {
2980 uint64_t u;
2981 float64 f;
2982 } u1, u2;
2983 u1.u = T0_64;
2984 u2.u = T1_64;
2985 u1.f = float64_add(u1.f, u2.f, &env->spe_status);
2986 T0_64 = u1.u;
2987 RETURN();
2990 void OPPROTO op_efdcfsid (void)
2992 do_efdcfsi();
2993 RETURN();
2996 void OPPROTO op_efdcfuid (void)
2998 do_efdcfui();
2999 RETURN();
3002 void OPPROTO op_efdnabs (void)
3004 T0_64 |= 0x8000000000000000ULL;
3005 RETURN();
3008 void OPPROTO op_efdabs (void)
3010 T0_64 &= ~0x8000000000000000ULL;
3011 RETURN();
3014 void OPPROTO op_efdneg (void)
3016 T0_64 ^= 0x8000000000000000ULL;
3017 RETURN();
3020 void OPPROTO op_efddiv (void)
3022 union {
3023 uint64_t u;
3024 float64 f;
3025 } u1, u2;
3026 u1.u = T0_64;
3027 u2.u = T1_64;
3028 u1.f = float64_div(u1.f, u2.f, &env->spe_status);
3029 T0_64 = u1.u;
3030 RETURN();
3033 void OPPROTO op_efdmul (void)
3035 union {
3036 uint64_t u;
3037 float64 f;
3038 } u1, u2;
3039 u1.u = T0_64;
3040 u2.u = T1_64;
3041 u1.f = float64_mul(u1.f, u2.f, &env->spe_status);
3042 T0_64 = u1.u;
3043 RETURN();
3046 void OPPROTO op_efdctsidz (void)
3048 do_efdctsiz();
3049 RETURN();
3052 void OPPROTO op_efdctuidz (void)
3054 do_efdctuiz();
3055 RETURN();
3058 void OPPROTO op_efdcmplt (void)
3060 do_efdcmplt();
3061 RETURN();
3064 void OPPROTO op_efdcmpgt (void)
3066 do_efdcmpgt();
3067 RETURN();
3070 void OPPROTO op_efdcfs (void)
3072 do_efdcfs();
3073 RETURN();
3076 void OPPROTO op_efdcmpeq (void)
3078 do_efdcmpeq();
3079 RETURN();
3082 void OPPROTO op_efdcfsi (void)
3084 do_efdcfsi();
3085 RETURN();
3088 void OPPROTO op_efdcfui (void)
3090 do_efdcfui();
3091 RETURN();
3094 void OPPROTO op_efdcfsf (void)
3096 do_efdcfsf();
3097 RETURN();
3100 void OPPROTO op_efdcfuf (void)
3102 do_efdcfuf();
3103 RETURN();
3106 void OPPROTO op_efdctsi (void)
3108 do_efdctsi();
3109 RETURN();
3112 void OPPROTO op_efdctui (void)
3114 do_efdctui();
3115 RETURN();
3118 void OPPROTO op_efdctsf (void)
3120 do_efdctsf();
3121 RETURN();
3124 void OPPROTO op_efdctuf (void)
3126 do_efdctuf();
3127 RETURN();
3130 void OPPROTO op_efdctuiz (void)
3132 do_efdctuiz();
3133 RETURN();
3136 void OPPROTO op_efdctsiz (void)
3138 do_efdctsiz();
3139 RETURN();
3142 void OPPROTO op_efdtstlt (void)
3144 T0 = _do_efdtstlt(T0_64, T1_64);
3145 RETURN();
3148 void OPPROTO op_efdtstgt (void)
3150 T0 = _do_efdtstgt(T0_64, T1_64);
3151 RETURN();
3154 void OPPROTO op_efdtsteq (void)
3156 T0 = _do_efdtsteq(T0_64, T1_64);
3157 RETURN();
3159 #endif /* defined(TARGET_PPCSPE) */