Fix typo in comment, by Andreas Faerber.
[qemu/dscho.git] / target-ppc / op.c
blob546f12a86420c1f3c84f25315c17c12aa0840c73
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"
134 void OPPROTO op_print_mem_EA (void)
136 do_print_mem_EA(T0);
137 RETURN();
140 /* PowerPC state maintenance operations */
141 /* set_Rc0 */
142 PPC_OP(set_Rc0)
144 env->crf[0] = T0 | xer_ov;
145 RETURN();
148 /* Set Rc1 (for floating point arithmetic) */
149 PPC_OP(set_Rc1)
151 env->crf[1] = regs->fpscr[7];
152 RETURN();
155 /* Constants load */
156 void OPPROTO op_reset_T0 (void)
158 T0 = 0;
159 RETURN();
162 PPC_OP(set_T0)
164 T0 = (uint32_t)PARAM1;
165 RETURN();
168 #if defined(TARGET_PPC64)
169 void OPPROTO op_set_T0_64 (void)
171 T0 = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
172 RETURN();
174 #endif
176 PPC_OP(set_T1)
178 T1 = (uint32_t)PARAM1;
179 RETURN();
182 #if defined(TARGET_PPC64)
183 void OPPROTO op_set_T1_64 (void)
185 T1 = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
186 RETURN();
188 #endif
190 #if 0 // unused
191 PPC_OP(set_T2)
193 T2 = PARAM(1);
194 RETURN();
196 #endif
198 void OPPROTO op_move_T1_T0 (void)
200 T1 = T0;
201 RETURN();
204 void OPPROTO op_move_T2_T0 (void)
206 T2 = T0;
207 RETURN();
210 /* Generate exceptions */
211 PPC_OP(raise_exception_err)
213 do_raise_exception_err(PARAM(1), PARAM(2));
216 PPC_OP(update_nip)
218 env->nip = (uint32_t)PARAM1;
219 RETURN();
222 #if defined(TARGET_PPC64)
223 void OPPROTO op_update_nip_64 (void)
225 env->nip = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
226 RETURN();
228 #endif
230 PPC_OP(debug)
232 do_raise_exception(EXCP_DEBUG);
235 PPC_OP(exit_tb)
237 EXIT_TB();
240 /* Load/store special registers */
241 PPC_OP(load_cr)
243 do_load_cr();
244 RETURN();
247 PPC_OP(store_cr)
249 do_store_cr(PARAM(1));
250 RETURN();
253 void OPPROTO op_load_cro (void)
255 T0 = env->crf[PARAM1];
256 RETURN();
259 void OPPROTO op_store_cro (void)
261 env->crf[PARAM1] = T0;
262 RETURN();
265 PPC_OP(load_xer_cr)
267 T0 = (xer_so << 3) | (xer_ov << 2) | (xer_ca << 1);
268 RETURN();
271 PPC_OP(clear_xer_ov)
273 xer_so = 0;
274 xer_ov = 0;
275 RETURN();
278 PPC_OP(clear_xer_ca)
280 xer_ca = 0;
281 RETURN();
284 PPC_OP(load_xer_bc)
286 T1 = xer_bc;
287 RETURN();
290 void OPPROTO op_store_xer_bc (void)
292 xer_bc = T0;
293 RETURN();
296 PPC_OP(load_xer)
298 do_load_xer();
299 RETURN();
302 PPC_OP(store_xer)
304 do_store_xer();
305 RETURN();
308 #if !defined(CONFIG_USER_ONLY)
309 /* Segment registers load and store */
310 PPC_OP(load_sr)
312 T0 = regs->sr[T1];
313 RETURN();
316 PPC_OP(store_sr)
318 do_store_sr(env, T1, T0);
319 RETURN();
322 PPC_OP(load_sdr1)
324 T0 = regs->sdr1;
325 RETURN();
328 PPC_OP(store_sdr1)
330 do_store_sdr1(env, T0);
331 RETURN();
334 #if defined (TARGET_PPC64)
335 void OPPROTO op_load_asr (void)
337 T0 = env->asr;
338 RETURN();
341 void OPPROTO op_store_asr (void)
343 ppc_store_asr(env, T0);
344 RETURN();
346 #endif
348 PPC_OP(load_msr)
350 T0 = do_load_msr(env);
351 RETURN();
354 PPC_OP(store_msr)
356 do_store_msr(env, T0);
357 RETURN();
360 #if defined (TARGET_PPC64)
361 void OPPROTO op_store_msr_32 (void)
363 ppc_store_msr_32(env, T0);
364 RETURN();
366 #endif
367 #endif
369 /* SPR */
370 void OPPROTO op_load_spr (void)
372 T0 = env->spr[PARAM1];
373 RETURN();
376 void OPPROTO op_store_spr (void)
378 env->spr[PARAM1] = T0;
379 RETURN();
382 void OPPROTO op_load_dump_spr (void)
384 T0 = ppc_load_dump_spr(PARAM1);
385 RETURN();
388 void OPPROTO op_store_dump_spr (void)
390 ppc_store_dump_spr(PARAM1, T0);
391 RETURN();
394 void OPPROTO op_mask_spr (void)
396 env->spr[PARAM1] &= ~T0;
397 RETURN();
400 PPC_OP(load_lr)
402 T0 = regs->lr;
403 RETURN();
406 PPC_OP(store_lr)
408 regs->lr = T0;
409 RETURN();
412 PPC_OP(load_ctr)
414 T0 = regs->ctr;
415 RETURN();
418 PPC_OP(store_ctr)
420 regs->ctr = T0;
421 RETURN();
424 PPC_OP(load_tbl)
426 T0 = cpu_ppc_load_tbl(regs);
427 RETURN();
430 PPC_OP(load_tbu)
432 T0 = cpu_ppc_load_tbu(regs);
433 RETURN();
436 #if !defined(CONFIG_USER_ONLY)
437 PPC_OP(store_tbl)
439 cpu_ppc_store_tbl(regs, T0);
440 RETURN();
443 PPC_OP(store_tbu)
445 cpu_ppc_store_tbu(regs, T0);
446 RETURN();
449 PPC_OP(load_decr)
451 T0 = cpu_ppc_load_decr(regs);
452 RETURN();
455 PPC_OP(store_decr)
457 cpu_ppc_store_decr(regs, T0);
458 RETURN();
461 PPC_OP(load_ibat)
463 T0 = regs->IBAT[PARAM(1)][PARAM(2)];
464 RETURN();
467 void OPPROTO op_store_ibatu (void)
469 do_store_ibatu(env, PARAM1, T0);
470 RETURN();
473 void OPPROTO op_store_ibatl (void)
475 #if 1
476 env->IBAT[1][PARAM1] = T0;
477 #else
478 do_store_ibatl(env, PARAM1, T0);
479 #endif
480 RETURN();
483 PPC_OP(load_dbat)
485 T0 = regs->DBAT[PARAM(1)][PARAM(2)];
486 RETURN();
489 void OPPROTO op_store_dbatu (void)
491 do_store_dbatu(env, PARAM1, T0);
492 RETURN();
495 void OPPROTO op_store_dbatl (void)
497 #if 1
498 env->DBAT[1][PARAM1] = T0;
499 #else
500 do_store_dbatl(env, PARAM1, T0);
501 #endif
502 RETURN();
504 #endif /* !defined(CONFIG_USER_ONLY) */
506 /* FPSCR */
507 PPC_OP(load_fpscr)
509 do_load_fpscr();
510 RETURN();
513 PPC_OP(store_fpscr)
515 do_store_fpscr(PARAM1);
516 RETURN();
519 PPC_OP(reset_scrfx)
521 regs->fpscr[7] &= ~0x8;
522 RETURN();
525 /* crf operations */
526 PPC_OP(getbit_T0)
528 T0 = (T0 >> PARAM(1)) & 1;
529 RETURN();
532 PPC_OP(getbit_T1)
534 T1 = (T1 >> PARAM(1)) & 1;
535 RETURN();
538 PPC_OP(setcrfbit)
540 T1 = (T1 & PARAM(1)) | (T0 << PARAM(2));
541 RETURN();
544 /* Branch */
545 #define EIP regs->nip
547 PPC_OP(setlr)
549 regs->lr = (uint32_t)PARAM1;
550 RETURN();
553 #if defined (TARGET_PPC64)
554 void OPPROTO op_setlr_64 (void)
556 regs->lr = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
557 RETURN();
559 #endif
561 PPC_OP(goto_tb0)
563 GOTO_TB(op_goto_tb0, PARAM1, 0);
566 PPC_OP(goto_tb1)
568 GOTO_TB(op_goto_tb1, PARAM1, 1);
571 void OPPROTO op_b_T1 (void)
573 regs->nip = (uint32_t)(T1 & ~3);
574 RETURN();
577 #if defined (TARGET_PPC64)
578 void OPPROTO op_b_T1_64 (void)
580 regs->nip = (uint64_t)(T1 & ~3);
581 RETURN();
583 #endif
585 PPC_OP(jz_T0)
587 if (!T0)
588 GOTO_LABEL_PARAM(1);
589 RETURN();
592 void OPPROTO op_btest_T1 (void)
594 if (T0) {
595 regs->nip = (uint32_t)(T1 & ~3);
596 } else {
597 regs->nip = (uint32_t)PARAM1;
599 RETURN();
602 #if defined (TARGET_PPC64)
603 void OPPROTO op_btest_T1_64 (void)
605 if (T0) {
606 regs->nip = (uint64_t)(T1 & ~3);
607 } else {
608 regs->nip = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
610 RETURN();
612 #endif
614 PPC_OP(movl_T1_ctr)
616 T1 = regs->ctr;
617 RETURN();
620 PPC_OP(movl_T1_lr)
622 T1 = regs->lr;
623 RETURN();
626 /* tests with result in T0 */
627 void OPPROTO op_test_ctr (void)
629 T0 = (uint32_t)regs->ctr;
630 RETURN();
633 #if defined(TARGET_PPC64)
634 void OPPROTO op_test_ctr_64 (void)
636 T0 = (uint64_t)regs->ctr;
637 RETURN();
639 #endif
641 void OPPROTO op_test_ctr_true (void)
643 T0 = ((uint32_t)regs->ctr != 0 && (T0 & PARAM1) != 0);
644 RETURN();
647 #if defined(TARGET_PPC64)
648 void OPPROTO op_test_ctr_true_64 (void)
650 T0 = ((uint64_t)regs->ctr != 0 && (T0 & PARAM1) != 0);
651 RETURN();
653 #endif
655 void OPPROTO op_test_ctr_false (void)
657 T0 = ((uint32_t)regs->ctr != 0 && (T0 & PARAM1) == 0);
658 RETURN();
661 #if defined(TARGET_PPC64)
662 void OPPROTO op_test_ctr_false_64 (void)
664 T0 = ((uint64_t)regs->ctr != 0 && (T0 & PARAM1) == 0);
665 RETURN();
667 #endif
669 void OPPROTO op_test_ctrz (void)
671 T0 = ((uint32_t)regs->ctr == 0);
672 RETURN();
675 #if defined(TARGET_PPC64)
676 void OPPROTO op_test_ctrz_64 (void)
678 T0 = ((uint64_t)regs->ctr == 0);
679 RETURN();
681 #endif
683 void OPPROTO op_test_ctrz_true (void)
685 T0 = ((uint32_t)regs->ctr == 0 && (T0 & PARAM1) != 0);
686 RETURN();
689 #if defined(TARGET_PPC64)
690 void OPPROTO op_test_ctrz_true_64 (void)
692 T0 = ((uint64_t)regs->ctr == 0 && (T0 & PARAM1) != 0);
693 RETURN();
695 #endif
697 void OPPROTO op_test_ctrz_false (void)
699 T0 = ((uint32_t)regs->ctr == 0 && (T0 & PARAM1) == 0);
700 RETURN();
703 #if defined(TARGET_PPC64)
704 void OPPROTO op_test_ctrz_false_64 (void)
706 T0 = ((uint64_t)regs->ctr == 0 && (T0 & PARAM1) == 0);
707 RETURN();
709 #endif
711 PPC_OP(test_true)
713 T0 = (T0 & PARAM(1));
714 RETURN();
717 PPC_OP(test_false)
719 T0 = ((T0 & PARAM(1)) == 0);
720 RETURN();
723 /* CTR maintenance */
724 PPC_OP(dec_ctr)
726 regs->ctr--;
727 RETURN();
730 /*** Integer arithmetic ***/
731 /* add */
732 PPC_OP(add)
734 T0 += T1;
735 RETURN();
738 void OPPROTO op_check_addo (void)
740 if (likely(!(((uint32_t)T2 ^ (uint32_t)T1 ^ UINT32_MAX) &
741 ((uint32_t)T2 ^ (uint32_t)T0) & (1UL << 31)))) {
742 xer_ov = 0;
743 } else {
744 xer_so = 1;
745 xer_ov = 1;
747 RETURN();
750 #if defined(TARGET_PPC64)
751 void OPPROTO op_check_addo_64 (void)
753 if (likely(!(((uint64_t)T2 ^ (uint64_t)T1 ^ UINT64_MAX) &
754 ((uint64_t)T2 ^ (uint64_t)T0) & (1ULL << 63)))) {
755 xer_ov = 0;
756 } else {
757 xer_so = 1;
758 xer_ov = 1;
760 RETURN();
762 #endif
764 /* add carrying */
765 void OPPROTO op_check_addc (void)
767 if (likely((uint32_t)T0 >= (uint32_t)T2)) {
768 xer_ca = 0;
769 } else {
770 xer_ca = 1;
772 RETURN();
775 #if defined(TARGET_PPC64)
776 void OPPROTO op_check_addc_64 (void)
778 if (likely((uint64_t)T0 >= (uint64_t)T2)) {
779 xer_ca = 0;
780 } else {
781 xer_ca = 1;
783 RETURN();
785 #endif
787 /* add extended */
788 void OPPROTO op_adde (void)
790 do_adde();
791 RETURN();
794 #if defined(TARGET_PPC64)
795 void OPPROTO op_adde_64 (void)
797 do_adde_64();
798 RETURN();
800 #endif
802 /* add immediate */
803 PPC_OP(addi)
805 T0 += (int32_t)PARAM(1);
806 RETURN();
809 /* add to minus one extended */
810 void OPPROTO op_add_me (void)
812 T0 += xer_ca + (-1);
813 if (likely((uint32_t)T1 != 0))
814 xer_ca = 1;
815 RETURN();
818 #if defined(TARGET_PPC64)
819 void OPPROTO op_add_me_64 (void)
821 T0 += xer_ca + (-1);
822 if (likely((uint64_t)T1 != 0))
823 xer_ca = 1;
824 RETURN();
826 #endif
828 void OPPROTO op_addmeo (void)
830 do_addmeo();
831 RETURN();
834 void OPPROTO op_addmeo_64 (void)
836 do_addmeo();
837 RETURN();
840 /* add to zero extended */
841 void OPPROTO op_add_ze (void)
843 T0 += xer_ca;
844 RETURN();
847 /* divide word */
848 void OPPROTO op_divw (void)
850 if (unlikely(((int32_t)T0 == INT32_MIN && (int32_t)T1 == -1) ||
851 (int32_t)T1 == 0)) {
852 T0 = (int32_t)((-1) * ((uint32_t)T0 >> 31));
853 } else {
854 T0 = (int32_t)T0 / (int32_t)T1;
856 RETURN();
859 #if defined(TARGET_PPC64)
860 void OPPROTO op_divd (void)
862 if (unlikely(((int64_t)T0 == INT64_MIN && (int64_t)T1 == -1) ||
863 (int64_t)T1 == 0)) {
864 T0 = (int64_t)((-1ULL) * ((uint64_t)T0 >> 63));
865 } else {
866 T0 = (int64_t)T0 / (int64_t)T1;
868 RETURN();
870 #endif
872 void OPPROTO op_divwo (void)
874 do_divwo();
875 RETURN();
878 #if defined(TARGET_PPC64)
879 void OPPROTO op_divdo (void)
881 do_divdo();
882 RETURN();
884 #endif
886 /* divide word unsigned */
887 void OPPROTO op_divwu (void)
889 if (unlikely(T1 == 0)) {
890 T0 = 0;
891 } else {
892 T0 = (uint32_t)T0 / (uint32_t)T1;
894 RETURN();
897 #if defined(TARGET_PPC64)
898 void OPPROTO op_divdu (void)
900 if (unlikely(T1 == 0)) {
901 T0 = 0;
902 } else {
903 T0 /= T1;
905 RETURN();
907 #endif
909 void OPPROTO op_divwuo (void)
911 do_divwuo();
912 RETURN();
915 #if defined(TARGET_PPC64)
916 void OPPROTO op_divduo (void)
918 do_divduo();
919 RETURN();
921 #endif
923 /* multiply high word */
924 void OPPROTO op_mulhw (void)
926 T0 = ((int64_t)((int32_t)T0) * (int64_t)((int32_t)T1)) >> 32;
927 RETURN();
930 #if defined(TARGET_PPC64)
931 void OPPROTO op_mulhd (void)
933 uint64_t tl, th;
935 do_imul64(&tl, &th);
936 T0 = th;
937 RETURN();
939 #endif
941 /* multiply high word unsigned */
942 void OPPROTO op_mulhwu (void)
944 T0 = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1) >> 32;
945 RETURN();
948 #if defined(TARGET_PPC64)
949 void OPPROTO op_mulhdu (void)
951 uint64_t tl, th;
953 do_mul64(&tl, &th);
954 T0 = th;
955 RETURN();
957 #endif
959 /* multiply low immediate */
960 PPC_OP(mulli)
962 T0 = ((int32_t)T0 * (int32_t)PARAM1);
963 RETURN();
966 /* multiply low word */
967 PPC_OP(mullw)
969 T0 = (int32_t)(T0 * T1);
970 RETURN();
973 #if defined(TARGET_PPC64)
974 void OPPROTO op_mulld (void)
976 T0 *= T1;
977 RETURN();
979 #endif
981 void OPPROTO op_mullwo (void)
983 do_mullwo();
984 RETURN();
987 #if defined(TARGET_PPC64)
988 void OPPROTO op_mulldo (void)
990 do_mulldo();
991 RETURN();
993 #endif
995 /* negate */
996 void OPPROTO op_neg (void)
998 if (likely(T0 != INT32_MIN)) {
999 T0 = -(int32_t)T0;
1001 RETURN();
1004 #if defined(TARGET_PPC64)
1005 void OPPROTO op_neg_64 (void)
1007 if (likely(T0 != INT64_MIN)) {
1008 T0 = -(int64_t)T0;
1010 RETURN();
1012 #endif
1014 void OPPROTO op_nego (void)
1016 do_nego();
1017 RETURN();
1020 #if defined(TARGET_PPC64)
1021 void OPPROTO op_nego_64 (void)
1023 do_nego_64();
1024 RETURN();
1026 #endif
1028 /* subtract from */
1029 PPC_OP(subf)
1031 T0 = T1 - T0;
1032 RETURN();
1035 void OPPROTO op_check_subfo (void)
1037 if (likely(!(((uint32_t)(~T2) ^ (uint32_t)T1 ^ UINT32_MAX) &
1038 ((uint32_t)(~T2) ^ (uint32_t)T0) & (1UL << 31)))) {
1039 xer_ov = 0;
1040 } else {
1041 xer_so = 1;
1042 xer_ov = 1;
1044 RETURN();
1047 #if defined(TARGET_PPC64)
1048 void OPPROTO op_check_subfo_64 (void)
1050 if (likely(!(((uint64_t)(~T2) ^ (uint64_t)T1 ^ UINT64_MAX) &
1051 ((uint64_t)(~T2) ^ (uint64_t)T0) & (1ULL << 63)))) {
1052 xer_ov = 0;
1053 } else {
1054 xer_so = 1;
1055 xer_ov = 1;
1057 RETURN();
1059 #endif
1061 /* subtract from carrying */
1062 void OPPROTO op_check_subfc (void)
1064 if (likely((uint32_t)T0 > (uint32_t)T1)) {
1065 xer_ca = 0;
1066 } else {
1067 xer_ca = 1;
1069 RETURN();
1072 #if defined(TARGET_PPC64)
1073 void OPPROTO op_check_subfc_64 (void)
1075 if (likely((uint64_t)T0 > (uint64_t)T1)) {
1076 xer_ca = 0;
1077 } else {
1078 xer_ca = 1;
1080 RETURN();
1082 #endif
1084 /* subtract from extended */
1085 void OPPROTO op_subfe (void)
1087 do_subfe();
1088 RETURN();
1091 #if defined(TARGET_PPC64)
1092 void OPPROTO op_subfe_64 (void)
1094 do_subfe_64();
1095 RETURN();
1097 #endif
1099 /* subtract from immediate carrying */
1100 void OPPROTO op_subfic (void)
1102 T0 = (int32_t)PARAM1 + ~T0 + 1;
1103 if ((uint32_t)T0 <= (uint32_t)PARAM1) {
1104 xer_ca = 1;
1105 } else {
1106 xer_ca = 0;
1108 RETURN();
1111 #if defined(TARGET_PPC64)
1112 void OPPROTO op_subfic_64 (void)
1114 T0 = PARAM1 + ~T0 + 1;
1115 if ((uint64_t)T0 <= (uint64_t)PARAM1) {
1116 xer_ca = 1;
1117 } else {
1118 xer_ca = 0;
1120 RETURN();
1122 #endif
1124 /* subtract from minus one extended */
1125 void OPPROTO op_subfme (void)
1127 T0 = ~T0 + xer_ca - 1;
1128 if (likely((uint32_t)T0 != (uint32_t)-1))
1129 xer_ca = 1;
1130 RETURN();
1133 #if defined(TARGET_PPC64)
1134 void OPPROTO op_subfme_64 (void)
1136 T0 = ~T0 + xer_ca - 1;
1137 if (likely((uint64_t)T0 != (uint64_t)-1))
1138 xer_ca = 1;
1139 RETURN();
1141 #endif
1143 void OPPROTO op_subfmeo (void)
1145 do_subfmeo();
1146 RETURN();
1149 #if defined(TARGET_PPC64)
1150 void OPPROTO op_subfmeo_64 (void)
1152 do_subfmeo_64();
1153 RETURN();
1155 #endif
1157 /* subtract from zero extended */
1158 void OPPROTO op_subfze (void)
1160 T1 = ~T0;
1161 T0 = T1 + xer_ca;
1162 if ((uint32_t)T0 < (uint32_t)T1) {
1163 xer_ca = 1;
1164 } else {
1165 xer_ca = 0;
1167 RETURN();
1170 #if defined(TARGET_PPC64)
1171 void OPPROTO op_subfze_64 (void)
1173 T1 = ~T0;
1174 T0 = T1 + xer_ca;
1175 if ((uint64_t)T0 < (uint64_t)T1) {
1176 xer_ca = 1;
1177 } else {
1178 xer_ca = 0;
1180 RETURN();
1182 #endif
1184 void OPPROTO op_subfzeo (void)
1186 do_subfzeo();
1187 RETURN();
1190 #if defined(TARGET_PPC64)
1191 void OPPROTO op_subfzeo_64 (void)
1193 do_subfzeo_64();
1194 RETURN();
1196 #endif
1198 /*** Integer comparison ***/
1199 /* compare */
1200 void OPPROTO op_cmp (void)
1202 if ((int32_t)T0 < (int32_t)T1) {
1203 T0 = 0x08;
1204 } else if ((int32_t)T0 > (int32_t)T1) {
1205 T0 = 0x04;
1206 } else {
1207 T0 = 0x02;
1209 RETURN();
1212 #if defined(TARGET_PPC64)
1213 void OPPROTO op_cmp_64 (void)
1215 if ((int64_t)T0 < (int64_t)T1) {
1216 T0 = 0x08;
1217 } else if ((int64_t)T0 > (int64_t)T1) {
1218 T0 = 0x04;
1219 } else {
1220 T0 = 0x02;
1222 RETURN();
1224 #endif
1226 /* compare immediate */
1227 void OPPROTO op_cmpi (void)
1229 if ((int32_t)T0 < (int32_t)PARAM1) {
1230 T0 = 0x08;
1231 } else if ((int32_t)T0 > (int32_t)PARAM1) {
1232 T0 = 0x04;
1233 } else {
1234 T0 = 0x02;
1236 RETURN();
1239 #if defined(TARGET_PPC64)
1240 void OPPROTO op_cmpi_64 (void)
1242 if ((int64_t)T0 < (int64_t)((int32_t)PARAM1)) {
1243 T0 = 0x08;
1244 } else if ((int64_t)T0 > (int64_t)((int32_t)PARAM1)) {
1245 T0 = 0x04;
1246 } else {
1247 T0 = 0x02;
1249 RETURN();
1251 #endif
1253 /* compare logical */
1254 void OPPROTO op_cmpl (void)
1256 if ((uint32_t)T0 < (uint32_t)T1) {
1257 T0 = 0x08;
1258 } else if ((uint32_t)T0 > (uint32_t)T1) {
1259 T0 = 0x04;
1260 } else {
1261 T0 = 0x02;
1263 RETURN();
1266 #if defined(TARGET_PPC64)
1267 void OPPROTO op_cmpl_64 (void)
1269 if ((uint64_t)T0 < (uint64_t)T1) {
1270 T0 = 0x08;
1271 } else if ((uint64_t)T0 > (uint64_t)T1) {
1272 T0 = 0x04;
1273 } else {
1274 T0 = 0x02;
1276 RETURN();
1278 #endif
1280 /* compare logical immediate */
1281 void OPPROTO op_cmpli (void)
1283 if ((uint32_t)T0 < (uint32_t)PARAM1) {
1284 T0 = 0x08;
1285 } else if ((uint32_t)T0 > (uint32_t)PARAM1) {
1286 T0 = 0x04;
1287 } else {
1288 T0 = 0x02;
1290 RETURN();
1293 #if defined(TARGET_PPC64)
1294 void OPPROTO op_cmpli_64 (void)
1296 if ((uint64_t)T0 < (uint64_t)PARAM1) {
1297 T0 = 0x08;
1298 } else if ((uint64_t)T0 > (uint64_t)PARAM1) {
1299 T0 = 0x04;
1300 } else {
1301 T0 = 0x02;
1303 RETURN();
1305 #endif
1307 void OPPROTO op_isel (void)
1309 if (T0)
1310 T0 = T1;
1311 else
1312 T0 = T2;
1313 RETURN();
1316 void OPPROTO op_popcntb (void)
1318 do_popcntb();
1319 RETURN();
1322 #if defined(TARGET_PPC64)
1323 void OPPROTO op_popcntb_64 (void)
1325 do_popcntb_64();
1326 RETURN();
1328 #endif
1330 /*** Integer logical ***/
1331 /* and */
1332 PPC_OP(and)
1334 T0 &= T1;
1335 RETURN();
1338 /* andc */
1339 PPC_OP(andc)
1341 T0 &= ~T1;
1342 RETURN();
1345 /* andi. */
1346 void OPPROTO op_andi_T0 (void)
1348 T0 &= PARAM(1);
1349 RETURN();
1352 void OPPROTO op_andi_T1 (void)
1354 T1 &= PARAM1;
1355 RETURN();
1358 /* count leading zero */
1359 void OPPROTO op_cntlzw (void)
1361 T0 = _do_cntlzw(T0);
1362 RETURN();
1365 #if defined(TARGET_PPC64)
1366 void OPPROTO op_cntlzd (void)
1368 T0 = _do_cntlzd(T0);
1369 RETURN();
1371 #endif
1373 /* eqv */
1374 PPC_OP(eqv)
1376 T0 = ~(T0 ^ T1);
1377 RETURN();
1380 /* extend sign byte */
1381 void OPPROTO op_extsb (void)
1383 #if defined (TARGET_PPC64)
1384 T0 = (int64_t)((int8_t)T0);
1385 #else
1386 T0 = (int32_t)((int8_t)T0);
1387 #endif
1388 RETURN();
1391 /* extend sign half word */
1392 void OPPROTO op_extsh (void)
1394 #if defined (TARGET_PPC64)
1395 T0 = (int64_t)((int16_t)T0);
1396 #else
1397 T0 = (int32_t)((int16_t)T0);
1398 #endif
1399 RETURN();
1402 #if defined (TARGET_PPC64)
1403 void OPPROTO op_extsw (void)
1405 T0 = (int64_t)((int32_t)T0);
1406 RETURN();
1408 #endif
1410 /* nand */
1411 PPC_OP(nand)
1413 T0 = ~(T0 & T1);
1414 RETURN();
1417 /* nor */
1418 PPC_OP(nor)
1420 T0 = ~(T0 | T1);
1421 RETURN();
1424 /* or */
1425 PPC_OP(or)
1427 T0 |= T1;
1428 RETURN();
1431 /* orc */
1432 PPC_OP(orc)
1434 T0 |= ~T1;
1435 RETURN();
1438 /* ori */
1439 PPC_OP(ori)
1441 T0 |= PARAM(1);
1442 RETURN();
1445 /* xor */
1446 PPC_OP(xor)
1448 T0 ^= T1;
1449 RETURN();
1452 /* xori */
1453 PPC_OP(xori)
1455 T0 ^= PARAM(1);
1456 RETURN();
1459 /*** Integer rotate ***/
1460 void OPPROTO op_rotl32_T0_T1 (void)
1462 T0 = rotl32(T0, T1 & 0x1F);
1463 RETURN();
1466 void OPPROTO op_rotli32_T0 (void)
1468 T0 = rotl32(T0, PARAM1);
1469 RETURN();
1472 #if defined(TARGET_PPC64)
1473 void OPPROTO op_rotl64_T0_T1 (void)
1475 T0 = rotl64(T0, T1 & 0x3F);
1476 RETURN();
1479 void OPPROTO op_rotli64_T0 (void)
1481 T0 = rotl64(T0, PARAM1);
1482 RETURN();
1484 #endif
1486 /*** Integer shift ***/
1487 /* shift left word */
1488 void OPPROTO op_slw (void)
1490 if (T1 & 0x20) {
1491 T0 = 0;
1492 } else {
1493 T0 = (uint32_t)(T0 << T1);
1495 RETURN();
1498 #if defined(TARGET_PPC64)
1499 void OPPROTO op_sld (void)
1501 if (T1 & 0x40) {
1502 T0 = 0;
1503 } else {
1504 T0 = T0 << T1;
1506 RETURN();
1508 #endif
1510 /* shift right algebraic word */
1511 void OPPROTO op_sraw (void)
1513 do_sraw();
1514 RETURN();
1517 #if defined(TARGET_PPC64)
1518 void OPPROTO op_srad (void)
1520 do_srad();
1521 RETURN();
1523 #endif
1525 /* shift right algebraic word immediate */
1526 void OPPROTO op_srawi (void)
1528 uint32_t mask = (uint32_t)PARAM2;
1530 T0 = (int32_t)T0 >> PARAM1;
1531 if ((int32_t)T1 < 0 && (T1 & mask) != 0) {
1532 xer_ca = 1;
1533 } else {
1534 xer_ca = 0;
1536 RETURN();
1539 #if defined(TARGET_PPC64)
1540 void OPPROTO op_sradi (void)
1542 uint64_t mask = ((uint64_t)PARAM2 << 32) | (uint64_t)PARAM3;
1544 T0 = (int64_t)T0 >> PARAM1;
1545 if ((int64_t)T1 < 0 && ((uint64_t)T1 & mask) != 0) {
1546 xer_ca = 1;
1547 } else {
1548 xer_ca = 0;
1550 RETURN();
1552 #endif
1554 /* shift right word */
1555 void OPPROTO op_srw (void)
1557 if (T1 & 0x20) {
1558 T0 = 0;
1559 } else {
1560 T0 = (uint32_t)T0 >> T1;
1562 RETURN();
1565 #if defined(TARGET_PPC64)
1566 void OPPROTO op_srd (void)
1568 if (T1 & 0x40) {
1569 T0 = 0;
1570 } else {
1571 T0 = (uint64_t)T0 >> T1;
1573 RETURN();
1575 #endif
1577 void OPPROTO op_sl_T0_T1 (void)
1579 T0 = T0 << T1;
1580 RETURN();
1583 void OPPROTO op_sli_T0 (void)
1585 T0 = T0 << PARAM1;
1586 RETURN();
1589 void OPPROTO op_srl_T0_T1 (void)
1591 T0 = (uint32_t)T0 >> T1;
1592 RETURN();
1595 #if defined(TARGET_PPC64)
1596 void OPPROTO op_srl_T0_T1_64 (void)
1598 T0 = (uint32_t)T0 >> T1;
1599 RETURN();
1601 #endif
1603 void OPPROTO op_srli_T0 (void)
1605 T0 = (uint32_t)T0 >> PARAM1;
1606 RETURN();
1609 #if defined(TARGET_PPC64)
1610 void OPPROTO op_srli_T0_64 (void)
1612 T0 = (uint64_t)T0 >> PARAM1;
1613 RETURN();
1615 #endif
1617 void OPPROTO op_srli_T1 (void)
1619 T1 = (uint32_t)T1 >> PARAM1;
1620 RETURN();
1623 #if defined(TARGET_PPC64)
1624 void OPPROTO op_srli_T1_64 (void)
1626 T1 = (uint64_t)T1 >> PARAM1;
1627 RETURN();
1629 #endif
1631 /*** Floating-Point arithmetic ***/
1632 /* fadd - fadd. */
1633 PPC_OP(fadd)
1635 FT0 = float64_add(FT0, FT1, &env->fp_status);
1636 RETURN();
1639 /* fsub - fsub. */
1640 PPC_OP(fsub)
1642 FT0 = float64_sub(FT0, FT1, &env->fp_status);
1643 RETURN();
1646 /* fmul - fmul. */
1647 PPC_OP(fmul)
1649 FT0 = float64_mul(FT0, FT1, &env->fp_status);
1650 RETURN();
1653 /* fdiv - fdiv. */
1654 PPC_OP(fdiv)
1656 FT0 = float64_div(FT0, FT1, &env->fp_status);
1657 RETURN();
1660 /* fsqrt - fsqrt. */
1661 PPC_OP(fsqrt)
1663 do_fsqrt();
1664 RETURN();
1667 /* fres - fres. */
1668 PPC_OP(fres)
1670 do_fres();
1671 RETURN();
1674 /* frsqrte - frsqrte. */
1675 PPC_OP(frsqrte)
1677 do_frsqrte();
1678 RETURN();
1681 /* fsel - fsel. */
1682 PPC_OP(fsel)
1684 do_fsel();
1685 RETURN();
1688 /*** Floating-Point multiply-and-add ***/
1689 /* fmadd - fmadd. */
1690 PPC_OP(fmadd)
1692 #if USE_PRECISE_EMULATION
1693 do_fmadd();
1694 #else
1695 FT0 = float64_mul(FT0, FT1, &env->fp_status);
1696 FT0 = float64_add(FT0, FT2, &env->fp_status);
1697 #endif
1698 RETURN();
1701 /* fmsub - fmsub. */
1702 PPC_OP(fmsub)
1704 #if USE_PRECISE_EMULATION
1705 do_fmsub();
1706 #else
1707 FT0 = float64_mul(FT0, FT1, &env->fp_status);
1708 FT0 = float64_sub(FT0, FT2, &env->fp_status);
1709 #endif
1710 RETURN();
1713 /* fnmadd - fnmadd. - fnmadds - fnmadds. */
1714 PPC_OP(fnmadd)
1716 do_fnmadd();
1717 RETURN();
1720 /* fnmsub - fnmsub. */
1721 PPC_OP(fnmsub)
1723 do_fnmsub();
1724 RETURN();
1727 /*** Floating-Point round & convert ***/
1728 /* frsp - frsp. */
1729 PPC_OP(frsp)
1731 FT0 = float64_to_float32(FT0, &env->fp_status);
1732 RETURN();
1735 /* fctiw - fctiw. */
1736 PPC_OP(fctiw)
1738 do_fctiw();
1739 RETURN();
1742 /* fctiwz - fctiwz. */
1743 PPC_OP(fctiwz)
1745 do_fctiwz();
1746 RETURN();
1749 #if defined(TARGET_PPC64)
1750 /* fcfid - fcfid. */
1751 PPC_OP(fcfid)
1753 do_fcfid();
1754 RETURN();
1757 /* fctid - fctid. */
1758 PPC_OP(fctid)
1760 do_fctid();
1761 RETURN();
1764 /* fctidz - fctidz. */
1765 PPC_OP(fctidz)
1767 do_fctidz();
1768 RETURN();
1770 #endif
1772 /*** Floating-Point compare ***/
1773 /* fcmpu */
1774 PPC_OP(fcmpu)
1776 do_fcmpu();
1777 RETURN();
1780 /* fcmpo */
1781 PPC_OP(fcmpo)
1783 do_fcmpo();
1784 RETURN();
1787 /*** Floating-point move ***/
1788 /* fabs */
1789 PPC_OP(fabs)
1791 FT0 = float64_abs(FT0);
1792 RETURN();
1795 /* fnabs */
1796 PPC_OP(fnabs)
1798 FT0 = float64_abs(FT0);
1799 FT0 = float64_chs(FT0);
1800 RETURN();
1803 /* fneg */
1804 PPC_OP(fneg)
1806 FT0 = float64_chs(FT0);
1807 RETURN();
1810 /* Load and store */
1811 #define MEMSUFFIX _raw
1812 #include "op_helper.h"
1813 #include "op_mem.h"
1814 #if !defined(CONFIG_USER_ONLY)
1815 #define MEMSUFFIX _user
1816 #include "op_helper.h"
1817 #include "op_mem.h"
1818 #define MEMSUFFIX _kernel
1819 #include "op_helper.h"
1820 #include "op_mem.h"
1821 #endif
1823 /* Special op to check and maybe clear reservation */
1824 void OPPROTO op_check_reservation (void)
1826 if ((uint32_t)env->reserve == (uint32_t)(T0 & ~0x00000003))
1827 env->reserve = -1;
1828 RETURN();
1831 #if defined(TARGET_PPC64)
1832 void OPPROTO op_check_reservation_64 (void)
1834 if ((uint64_t)env->reserve == (uint64_t)(T0 & ~0x00000003))
1835 env->reserve = -1;
1836 RETURN();
1838 #endif
1840 /* Return from interrupt */
1841 #if !defined(CONFIG_USER_ONLY)
1842 void OPPROTO op_rfi (void)
1844 do_rfi();
1845 RETURN();
1848 #if defined(TARGET_PPC64)
1849 void OPPROTO op_rfid (void)
1851 do_rfid();
1852 RETURN();
1854 #endif
1855 #endif
1857 /* Trap word */
1858 void OPPROTO op_tw (void)
1860 do_tw(PARAM1);
1861 RETURN();
1864 #if defined(TARGET_PPC64)
1865 void OPPROTO op_td (void)
1867 do_td(PARAM1);
1868 RETURN();
1870 #endif
1872 #if !defined(CONFIG_USER_ONLY)
1873 /* tlbia */
1874 PPC_OP(tlbia)
1876 do_tlbia();
1877 RETURN();
1880 /* tlbie */
1881 void OPPROTO op_tlbie (void)
1883 do_tlbie();
1884 RETURN();
1887 #if defined(TARGET_PPC64)
1888 void OPPROTO op_tlbie_64 (void)
1890 do_tlbie_64();
1891 RETURN();
1893 #endif
1895 #if defined(TARGET_PPC64)
1896 void OPPROTO op_slbia (void)
1898 do_slbia();
1899 RETURN();
1902 void OPPROTO op_slbie (void)
1904 do_slbie();
1905 RETURN();
1907 #endif
1908 #endif
1910 /* PowerPC 602/603/755 software TLB load instructions */
1911 #if !defined(CONFIG_USER_ONLY)
1912 void OPPROTO op_6xx_tlbld (void)
1914 do_load_6xx_tlb(0);
1915 RETURN();
1918 void OPPROTO op_6xx_tlbli (void)
1920 do_load_6xx_tlb(1);
1921 RETURN();
1923 #endif
1925 /* 601 specific */
1926 void OPPROTO op_load_601_rtcl (void)
1928 T0 = cpu_ppc601_load_rtcl(env);
1929 RETURN();
1932 void OPPROTO op_load_601_rtcu (void)
1934 T0 = cpu_ppc601_load_rtcu(env);
1935 RETURN();
1938 #if !defined(CONFIG_USER_ONLY)
1939 void OPPROTO op_store_601_rtcl (void)
1941 cpu_ppc601_store_rtcl(env, T0);
1942 RETURN();
1945 void OPPROTO op_store_601_rtcu (void)
1947 cpu_ppc601_store_rtcu(env, T0);
1948 RETURN();
1951 void OPPROTO op_load_601_bat (void)
1953 T0 = env->IBAT[PARAM1][PARAM2];
1954 RETURN();
1956 #endif /* !defined(CONFIG_USER_ONLY) */
1958 /* 601 unified BATs store.
1959 * To avoid using specific MMU code for 601, we store BATs in
1960 * IBAT and DBAT simultaneously, then emulate unified BATs.
1962 #if !defined(CONFIG_USER_ONLY)
1963 void OPPROTO op_store_601_batl (void)
1965 int nr = PARAM1;
1967 env->IBAT[1][nr] = T0;
1968 env->DBAT[1][nr] = T0;
1969 RETURN();
1972 void OPPROTO op_store_601_batu (void)
1974 do_store_601_batu(PARAM1);
1975 RETURN();
1977 #endif /* !defined(CONFIG_USER_ONLY) */
1979 /* PowerPC 601 specific instructions (POWER bridge) */
1980 /* XXX: those micro-ops need tests ! */
1981 void OPPROTO op_POWER_abs (void)
1983 if (T0 == INT32_MIN)
1984 T0 = INT32_MAX;
1985 else if (T0 < 0)
1986 T0 = -T0;
1987 RETURN();
1990 void OPPROTO op_POWER_abso (void)
1992 do_POWER_abso();
1993 RETURN();
1996 void OPPROTO op_POWER_clcs (void)
1998 do_POWER_clcs();
1999 RETURN();
2002 void OPPROTO op_POWER_div (void)
2004 do_POWER_div();
2005 RETURN();
2008 void OPPROTO op_POWER_divo (void)
2010 do_POWER_divo();
2011 RETURN();
2014 void OPPROTO op_POWER_divs (void)
2016 do_POWER_divs();
2017 RETURN();
2020 void OPPROTO op_POWER_divso (void)
2022 do_POWER_divso();
2023 RETURN();
2026 void OPPROTO op_POWER_doz (void)
2028 if ((int32_t)T1 > (int32_t)T0)
2029 T0 = T1 - T0;
2030 else
2031 T0 = 0;
2032 RETURN();
2035 void OPPROTO op_POWER_dozo (void)
2037 do_POWER_dozo();
2038 RETURN();
2041 void OPPROTO op_load_xer_cmp (void)
2043 T2 = xer_cmp;
2044 RETURN();
2047 void OPPROTO op_POWER_maskg (void)
2049 do_POWER_maskg();
2050 RETURN();
2053 void OPPROTO op_POWER_maskir (void)
2055 T0 = (T0 & ~T2) | (T1 & T2);
2056 RETURN();
2059 void OPPROTO op_POWER_mul (void)
2061 uint64_t tmp;
2063 tmp = (uint64_t)T0 * (uint64_t)T1;
2064 env->spr[SPR_MQ] = tmp >> 32;
2065 T0 = tmp;
2066 RETURN();
2069 void OPPROTO op_POWER_mulo (void)
2071 do_POWER_mulo();
2072 RETURN();
2075 void OPPROTO op_POWER_nabs (void)
2077 if (T0 > 0)
2078 T0 = -T0;
2079 RETURN();
2082 void OPPROTO op_POWER_nabso (void)
2084 /* nabs never overflows */
2085 if (T0 > 0)
2086 T0 = -T0;
2087 xer_ov = 0;
2088 RETURN();
2091 /* XXX: factorise POWER rotates... */
2092 void OPPROTO op_POWER_rlmi (void)
2094 T0 = rotl32(T0, T2) & PARAM1;
2095 T0 |= T1 & PARAM2;
2096 RETURN();
2099 void OPPROTO op_POWER_rrib (void)
2101 T2 &= 0x1FUL;
2102 T0 = rotl32(T0 & INT32_MIN, T2);
2103 T0 |= T1 & ~rotl32(INT32_MIN, T2);
2104 RETURN();
2107 void OPPROTO op_POWER_sle (void)
2109 T1 &= 0x1FUL;
2110 env->spr[SPR_MQ] = rotl32(T0, T1);
2111 T0 = T0 << T1;
2112 RETURN();
2115 void OPPROTO op_POWER_sleq (void)
2117 uint32_t tmp = env->spr[SPR_MQ];
2119 T1 &= 0x1FUL;
2120 env->spr[SPR_MQ] = rotl32(T0, T1);
2121 T0 = T0 << T1;
2122 T0 |= tmp >> (32 - T1);
2123 RETURN();
2126 void OPPROTO op_POWER_sllq (void)
2128 uint32_t msk = -1;
2130 msk = msk << (T1 & 0x1FUL);
2131 if (T1 & 0x20UL)
2132 msk = ~msk;
2133 T1 &= 0x1FUL;
2134 T0 = (T0 << T1) & msk;
2135 T0 |= env->spr[SPR_MQ] & ~msk;
2136 RETURN();
2139 void OPPROTO op_POWER_slq (void)
2141 uint32_t msk = -1, tmp;
2143 msk = msk << (T1 & 0x1FUL);
2144 if (T1 & 0x20UL)
2145 msk = ~msk;
2146 T1 &= 0x1FUL;
2147 tmp = rotl32(T0, T1);
2148 T0 = tmp & msk;
2149 env->spr[SPR_MQ] = tmp;
2150 RETURN();
2153 void OPPROTO op_POWER_sraq (void)
2155 env->spr[SPR_MQ] = rotl32(T0, 32 - (T1 & 0x1FUL));
2156 if (T1 & 0x20UL)
2157 T0 = -1L;
2158 else
2159 T0 = (int32_t)T0 >> T1;
2160 RETURN();
2163 void OPPROTO op_POWER_sre (void)
2165 T1 &= 0x1FUL;
2166 env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2167 T0 = (int32_t)T0 >> T1;
2168 RETURN();
2171 void OPPROTO op_POWER_srea (void)
2173 T1 &= 0x1FUL;
2174 env->spr[SPR_MQ] = T0 >> T1;
2175 T0 = (int32_t)T0 >> T1;
2176 RETURN();
2179 void OPPROTO op_POWER_sreq (void)
2181 uint32_t tmp;
2182 int32_t msk;
2184 T1 &= 0x1FUL;
2185 msk = INT32_MIN >> T1;
2186 tmp = env->spr[SPR_MQ];
2187 env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2188 T0 = T0 >> T1;
2189 T0 |= tmp & msk;
2190 RETURN();
2193 void OPPROTO op_POWER_srlq (void)
2195 uint32_t tmp;
2196 int32_t msk;
2198 msk = INT32_MIN >> (T1 & 0x1FUL);
2199 if (T1 & 0x20UL)
2200 msk = ~msk;
2201 T1 &= 0x1FUL;
2202 tmp = env->spr[SPR_MQ];
2203 env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2204 T0 = T0 >> T1;
2205 T0 &= msk;
2206 T0 |= tmp & ~msk;
2207 RETURN();
2210 void OPPROTO op_POWER_srq (void)
2212 T1 &= 0x1FUL;
2213 env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2214 T0 = T0 >> T1;
2215 RETURN();
2218 /* POWER instructions not implemented in PowerPC 601 */
2219 #if !defined(CONFIG_USER_ONLY)
2220 void OPPROTO op_POWER_mfsri (void)
2222 T1 = T0 >> 28;
2223 T0 = env->sr[T1];
2224 RETURN();
2227 void OPPROTO op_POWER_rac (void)
2229 do_POWER_rac();
2230 RETURN();
2233 void OPPROTO op_POWER_rfsvc (void)
2235 do_POWER_rfsvc();
2236 RETURN();
2238 #endif
2240 /* PowerPC 602 specific instruction */
2241 #if !defined(CONFIG_USER_ONLY)
2242 void OPPROTO op_602_mfrom (void)
2244 do_op_602_mfrom();
2245 RETURN();
2247 #endif
2249 /* PowerPC 4xx specific micro-ops */
2250 void OPPROTO op_405_add_T0_T2 (void)
2252 T0 = (int32_t)T0 + (int32_t)T2;
2253 RETURN();
2256 void OPPROTO op_405_mulchw (void)
2258 T0 = ((int16_t)T0) * ((int16_t)(T1 >> 16));
2259 RETURN();
2262 void OPPROTO op_405_mulchwu (void)
2264 T0 = ((uint16_t)T0) * ((uint16_t)(T1 >> 16));
2265 RETURN();
2268 void OPPROTO op_405_mulhhw (void)
2270 T0 = ((int16_t)(T0 >> 16)) * ((int16_t)(T1 >> 16));
2271 RETURN();
2274 void OPPROTO op_405_mulhhwu (void)
2276 T0 = ((uint16_t)(T0 >> 16)) * ((uint16_t)(T1 >> 16));
2277 RETURN();
2280 void OPPROTO op_405_mullhw (void)
2282 T0 = ((int16_t)T0) * ((int16_t)T1);
2283 RETURN();
2286 void OPPROTO op_405_mullhwu (void)
2288 T0 = ((uint16_t)T0) * ((uint16_t)T1);
2289 RETURN();
2292 void OPPROTO op_405_check_ov (void)
2294 do_405_check_ov();
2295 RETURN();
2298 void OPPROTO op_405_check_sat (void)
2300 do_405_check_sat();
2301 RETURN();
2304 void OPPROTO op_405_check_ovu (void)
2306 if (likely(T0 >= T2)) {
2307 xer_ov = 0;
2308 } else {
2309 xer_ov = 1;
2310 xer_so = 1;
2312 RETURN();
2315 void OPPROTO op_405_check_satu (void)
2317 if (unlikely(T0 < T2)) {
2318 /* Saturate result */
2319 T0 = -1;
2321 RETURN();
2324 #if !defined(CONFIG_USER_ONLY)
2325 void OPPROTO op_load_dcr (void)
2327 do_load_dcr();
2328 RETURN();
2331 void OPPROTO op_store_dcr (void)
2333 do_store_dcr();
2334 RETURN();
2337 /* Return from critical interrupt :
2338 * same as rfi, except nip & MSR are loaded from SRR2/3 instead of SRR0/1
2340 void OPPROTO op_40x_rfci (void)
2342 do_40x_rfci();
2343 RETURN();
2346 void OPPROTO op_rfci (void)
2348 do_rfci();
2349 RETURN();
2352 void OPPROTO op_rfdi (void)
2354 do_rfdi();
2355 RETURN();
2358 void OPPROTO op_rfmci (void)
2360 do_rfmci();
2361 RETURN();
2364 void OPPROTO op_wrte (void)
2366 msr_ee = T0 >> 16;
2367 RETURN();
2370 void OPPROTO op_4xx_tlbre_lo (void)
2372 do_4xx_tlbre_lo();
2373 RETURN();
2376 void OPPROTO op_4xx_tlbre_hi (void)
2378 do_4xx_tlbre_hi();
2379 RETURN();
2382 void OPPROTO op_4xx_tlbsx (void)
2384 do_4xx_tlbsx();
2385 RETURN();
2388 void OPPROTO op_4xx_tlbsx_ (void)
2390 do_4xx_tlbsx_();
2391 RETURN();
2394 void OPPROTO op_4xx_tlbwe_lo (void)
2396 do_4xx_tlbwe_lo();
2397 RETURN();
2400 void OPPROTO op_4xx_tlbwe_hi (void)
2402 do_4xx_tlbwe_hi();
2403 RETURN();
2405 #endif
2407 /* SPR micro-ops */
2408 /* 440 specific */
2409 void OPPROTO op_440_dlmzb (void)
2411 do_440_dlmzb();
2412 RETURN();
2415 void OPPROTO op_440_dlmzb_update_Rc (void)
2417 if (T0 == 8)
2418 T0 = 0x2;
2419 else if (T0 < 4)
2420 T0 = 0x4;
2421 else
2422 T0 = 0x8;
2423 RETURN();
2426 #if !defined(CONFIG_USER_ONLY)
2427 void OPPROTO op_store_pir (void)
2429 env->spr[SPR_PIR] = T0 & 0x0000000FUL;
2430 RETURN();
2433 void OPPROTO op_load_403_pb (void)
2435 do_load_403_pb(PARAM1);
2436 RETURN();
2439 void OPPROTO op_store_403_pb (void)
2441 do_store_403_pb(PARAM1);
2442 RETURN();
2445 void OPPROTO op_load_40x_pit (void)
2447 T0 = load_40x_pit(env);
2448 RETURN();
2451 void OPPROTO op_store_40x_pit (void)
2453 store_40x_pit(env, T0);
2454 RETURN();
2457 void OPPROTO op_store_40x_dbcr0 (void)
2459 store_40x_dbcr0(env, T0);
2462 void OPPROTO op_store_40x_sler (void)
2464 store_40x_sler(env, T0);
2465 RETURN();
2468 void OPPROTO op_store_booke_tcr (void)
2470 store_booke_tcr(env, T0);
2471 RETURN();
2474 void OPPROTO op_store_booke_tsr (void)
2476 store_booke_tsr(env, T0);
2477 RETURN();
2480 #endif /* !defined(CONFIG_USER_ONLY) */
2482 #if defined(TARGET_PPCEMB)
2483 /* SPE extension */
2484 void OPPROTO op_splatw_T1_64 (void)
2486 T1_64 = (T1_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL);
2487 RETURN();
2490 void OPPROTO op_splatwi_T0_64 (void)
2492 uint64_t tmp = PARAM1;
2494 T0_64 = (tmp << 32) | tmp;
2495 RETURN();
2498 void OPPROTO op_splatwi_T1_64 (void)
2500 uint64_t tmp = PARAM1;
2502 T1_64 = (tmp << 32) | tmp;
2503 RETURN();
2506 void OPPROTO op_extsh_T1_64 (void)
2508 T1_64 = (int32_t)((int16_t)T1_64);
2509 RETURN();
2512 void OPPROTO op_sli16_T1_64 (void)
2514 T1_64 = T1_64 << 16;
2515 RETURN();
2518 void OPPROTO op_sli32_T1_64 (void)
2520 T1_64 = T1_64 << 32;
2521 RETURN();
2524 void OPPROTO op_srli32_T1_64 (void)
2526 T1_64 = T1_64 >> 32;
2527 RETURN();
2530 void OPPROTO op_evsel (void)
2532 do_evsel();
2533 RETURN();
2536 void OPPROTO op_evaddw (void)
2538 do_evaddw();
2539 RETURN();
2542 void OPPROTO op_evsubfw (void)
2544 do_evsubfw();
2545 RETURN();
2548 void OPPROTO op_evneg (void)
2550 do_evneg();
2551 RETURN();
2554 void OPPROTO op_evabs (void)
2556 do_evabs();
2557 RETURN();
2560 void OPPROTO op_evextsh (void)
2562 T0_64 = ((uint64_t)((int32_t)(int16_t)(T0_64 >> 32)) << 32) |
2563 (uint64_t)((int32_t)(int16_t)T0_64);
2564 RETURN();
2567 void OPPROTO op_evextsb (void)
2569 T0_64 = ((uint64_t)((int32_t)(int8_t)(T0_64 >> 32)) << 32) |
2570 (uint64_t)((int32_t)(int8_t)T0_64);
2571 RETURN();
2574 void OPPROTO op_evcntlzw (void)
2576 do_evcntlzw();
2577 RETURN();
2580 void OPPROTO op_evrndw (void)
2582 do_evrndw();
2583 RETURN();
2586 void OPPROTO op_brinc (void)
2588 do_brinc();
2589 RETURN();
2592 void OPPROTO op_evcntlsw (void)
2594 do_evcntlsw();
2595 RETURN();
2598 void OPPROTO op_evand (void)
2600 T0_64 &= T1_64;
2601 RETURN();
2604 void OPPROTO op_evandc (void)
2606 T0_64 &= ~T1_64;
2607 RETURN();
2610 void OPPROTO op_evor (void)
2612 T0_64 |= T1_64;
2613 RETURN();
2616 void OPPROTO op_evxor (void)
2618 T0_64 ^= T1_64;
2619 RETURN();
2622 void OPPROTO op_eveqv (void)
2624 T0_64 = ~(T0_64 ^ T1_64);
2625 RETURN();
2628 void OPPROTO op_evnor (void)
2630 T0_64 = ~(T0_64 | T1_64);
2631 RETURN();
2634 void OPPROTO op_evorc (void)
2636 T0_64 |= ~T1_64;
2637 RETURN();
2640 void OPPROTO op_evnand (void)
2642 T0_64 = ~(T0_64 & T1_64);
2643 RETURN();
2646 void OPPROTO op_evsrws (void)
2648 do_evsrws();
2649 RETURN();
2652 void OPPROTO op_evsrwu (void)
2654 do_evsrwu();
2655 RETURN();
2658 void OPPROTO op_evslw (void)
2660 do_evslw();
2661 RETURN();
2664 void OPPROTO op_evrlw (void)
2666 do_evrlw();
2667 RETURN();
2670 void OPPROTO op_evmergelo (void)
2672 T0_64 = (T0_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL);
2673 RETURN();
2676 void OPPROTO op_evmergehi (void)
2678 T0_64 = (T0_64 & 0xFFFFFFFF00000000ULL) | (T1_64 >> 32);
2679 RETURN();
2682 void OPPROTO op_evmergelohi (void)
2684 T0_64 = (T0_64 << 32) | (T1_64 >> 32);
2685 RETURN();
2688 void OPPROTO op_evmergehilo (void)
2690 T0_64 = (T0_64 & 0xFFFFFFFF00000000ULL) | (T1_64 & 0x00000000FFFFFFFFULL);
2691 RETURN();
2694 void OPPROTO op_evcmpgts (void)
2696 do_evcmpgts();
2697 RETURN();
2700 void OPPROTO op_evcmpgtu (void)
2702 do_evcmpgtu();
2703 RETURN();
2706 void OPPROTO op_evcmplts (void)
2708 do_evcmplts();
2709 RETURN();
2712 void OPPROTO op_evcmpltu (void)
2714 do_evcmpltu();
2715 RETURN();
2718 void OPPROTO op_evcmpeq (void)
2720 do_evcmpeq();
2721 RETURN();
2724 void OPPROTO op_evfssub (void)
2726 do_evfssub();
2727 RETURN();
2730 void OPPROTO op_evfsadd (void)
2732 do_evfsadd();
2733 RETURN();
2736 void OPPROTO op_evfsnabs (void)
2738 do_evfsnabs();
2739 RETURN();
2742 void OPPROTO op_evfsabs (void)
2744 do_evfsabs();
2745 RETURN();
2748 void OPPROTO op_evfsneg (void)
2750 do_evfsneg();
2751 RETURN();
2754 void OPPROTO op_evfsdiv (void)
2756 do_evfsdiv();
2757 RETURN();
2760 void OPPROTO op_evfsmul (void)
2762 do_evfsmul();
2763 RETURN();
2766 void OPPROTO op_evfscmplt (void)
2768 do_evfscmplt();
2769 RETURN();
2772 void OPPROTO op_evfscmpgt (void)
2774 do_evfscmpgt();
2775 RETURN();
2778 void OPPROTO op_evfscmpeq (void)
2780 do_evfscmpeq();
2781 RETURN();
2784 void OPPROTO op_evfscfsi (void)
2786 do_evfscfsi();
2787 RETURN();
2790 void OPPROTO op_evfscfui (void)
2792 do_evfscfui();
2793 RETURN();
2796 void OPPROTO op_evfscfsf (void)
2798 do_evfscfsf();
2799 RETURN();
2802 void OPPROTO op_evfscfuf (void)
2804 do_evfscfuf();
2805 RETURN();
2808 void OPPROTO op_evfsctsi (void)
2810 do_evfsctsi();
2811 RETURN();
2814 void OPPROTO op_evfsctui (void)
2816 do_evfsctui();
2817 RETURN();
2820 void OPPROTO op_evfsctsf (void)
2822 do_evfsctsf();
2823 RETURN();
2826 void OPPROTO op_evfsctuf (void)
2828 do_evfsctuf();
2829 RETURN();
2832 void OPPROTO op_evfsctuiz (void)
2834 do_evfsctuiz();
2835 RETURN();
2838 void OPPROTO op_evfsctsiz (void)
2840 do_evfsctsiz();
2841 RETURN();
2844 void OPPROTO op_evfststlt (void)
2846 do_evfststlt();
2847 RETURN();
2850 void OPPROTO op_evfststgt (void)
2852 do_evfststgt();
2853 RETURN();
2856 void OPPROTO op_evfststeq (void)
2858 do_evfststeq();
2859 RETURN();
2862 void OPPROTO op_efssub (void)
2864 T0_64 = _do_efssub(T0_64, T1_64);
2865 RETURN();
2868 void OPPROTO op_efsadd (void)
2870 T0_64 = _do_efsadd(T0_64, T1_64);
2871 RETURN();
2874 void OPPROTO op_efsnabs (void)
2876 T0_64 = _do_efsnabs(T0_64);
2877 RETURN();
2880 void OPPROTO op_efsabs (void)
2882 T0_64 = _do_efsabs(T0_64);
2883 RETURN();
2886 void OPPROTO op_efsneg (void)
2888 T0_64 = _do_efsneg(T0_64);
2889 RETURN();
2892 void OPPROTO op_efsdiv (void)
2894 T0_64 = _do_efsdiv(T0_64, T1_64);
2895 RETURN();
2898 void OPPROTO op_efsmul (void)
2900 T0_64 = _do_efsmul(T0_64, T1_64);
2901 RETURN();
2904 void OPPROTO op_efscmplt (void)
2906 do_efscmplt();
2907 RETURN();
2910 void OPPROTO op_efscmpgt (void)
2912 do_efscmpgt();
2913 RETURN();
2916 void OPPROTO op_efscfd (void)
2918 do_efscfd();
2919 RETURN();
2922 void OPPROTO op_efscmpeq (void)
2924 do_efscmpeq();
2925 RETURN();
2928 void OPPROTO op_efscfsi (void)
2930 do_efscfsi();
2931 RETURN();
2934 void OPPROTO op_efscfui (void)
2936 do_efscfui();
2937 RETURN();
2940 void OPPROTO op_efscfsf (void)
2942 do_efscfsf();
2943 RETURN();
2946 void OPPROTO op_efscfuf (void)
2948 do_efscfuf();
2949 RETURN();
2952 void OPPROTO op_efsctsi (void)
2954 do_efsctsi();
2955 RETURN();
2958 void OPPROTO op_efsctui (void)
2960 do_efsctui();
2961 RETURN();
2964 void OPPROTO op_efsctsf (void)
2966 do_efsctsf();
2967 RETURN();
2970 void OPPROTO op_efsctuf (void)
2972 do_efsctuf();
2973 RETURN();
2976 void OPPROTO op_efsctsiz (void)
2978 do_efsctsiz();
2979 RETURN();
2982 void OPPROTO op_efsctuiz (void)
2984 do_efsctuiz();
2985 RETURN();
2988 void OPPROTO op_efststlt (void)
2990 T0 = _do_efststlt(T0_64, T1_64);
2991 RETURN();
2994 void OPPROTO op_efststgt (void)
2996 T0 = _do_efststgt(T0_64, T1_64);
2997 RETURN();
3000 void OPPROTO op_efststeq (void)
3002 T0 = _do_efststeq(T0_64, T1_64);
3003 RETURN();
3006 void OPPROTO op_efdsub (void)
3008 union {
3009 uint64_t u;
3010 float64 f;
3011 } u1, u2;
3012 u1.u = T0_64;
3013 u2.u = T1_64;
3014 u1.f = float64_sub(u1.f, u2.f, &env->spe_status);
3015 T0_64 = u1.u;
3016 RETURN();
3019 void OPPROTO op_efdadd (void)
3021 union {
3022 uint64_t u;
3023 float64 f;
3024 } u1, u2;
3025 u1.u = T0_64;
3026 u2.u = T1_64;
3027 u1.f = float64_add(u1.f, u2.f, &env->spe_status);
3028 T0_64 = u1.u;
3029 RETURN();
3032 void OPPROTO op_efdcfsid (void)
3034 do_efdcfsi();
3035 RETURN();
3038 void OPPROTO op_efdcfuid (void)
3040 do_efdcfui();
3041 RETURN();
3044 void OPPROTO op_efdnabs (void)
3046 T0_64 |= 0x8000000000000000ULL;
3047 RETURN();
3050 void OPPROTO op_efdabs (void)
3052 T0_64 &= ~0x8000000000000000ULL;
3053 RETURN();
3056 void OPPROTO op_efdneg (void)
3058 T0_64 ^= 0x8000000000000000ULL;
3059 RETURN();
3062 void OPPROTO op_efddiv (void)
3064 union {
3065 uint64_t u;
3066 float64 f;
3067 } u1, u2;
3068 u1.u = T0_64;
3069 u2.u = T1_64;
3070 u1.f = float64_div(u1.f, u2.f, &env->spe_status);
3071 T0_64 = u1.u;
3072 RETURN();
3075 void OPPROTO op_efdmul (void)
3077 union {
3078 uint64_t u;
3079 float64 f;
3080 } u1, u2;
3081 u1.u = T0_64;
3082 u2.u = T1_64;
3083 u1.f = float64_mul(u1.f, u2.f, &env->spe_status);
3084 T0_64 = u1.u;
3085 RETURN();
3088 void OPPROTO op_efdctsidz (void)
3090 do_efdctsiz();
3091 RETURN();
3094 void OPPROTO op_efdctuidz (void)
3096 do_efdctuiz();
3097 RETURN();
3100 void OPPROTO op_efdcmplt (void)
3102 do_efdcmplt();
3103 RETURN();
3106 void OPPROTO op_efdcmpgt (void)
3108 do_efdcmpgt();
3109 RETURN();
3112 void OPPROTO op_efdcfs (void)
3114 do_efdcfs();
3115 RETURN();
3118 void OPPROTO op_efdcmpeq (void)
3120 do_efdcmpeq();
3121 RETURN();
3124 void OPPROTO op_efdcfsi (void)
3126 do_efdcfsi();
3127 RETURN();
3130 void OPPROTO op_efdcfui (void)
3132 do_efdcfui();
3133 RETURN();
3136 void OPPROTO op_efdcfsf (void)
3138 do_efdcfsf();
3139 RETURN();
3142 void OPPROTO op_efdcfuf (void)
3144 do_efdcfuf();
3145 RETURN();
3148 void OPPROTO op_efdctsi (void)
3150 do_efdctsi();
3151 RETURN();
3154 void OPPROTO op_efdctui (void)
3156 do_efdctui();
3157 RETURN();
3160 void OPPROTO op_efdctsf (void)
3162 do_efdctsf();
3163 RETURN();
3166 void OPPROTO op_efdctuf (void)
3168 do_efdctuf();
3169 RETURN();
3172 void OPPROTO op_efdctuiz (void)
3174 do_efdctuiz();
3175 RETURN();
3178 void OPPROTO op_efdctsiz (void)
3180 do_efdctsiz();
3181 RETURN();
3184 void OPPROTO op_efdtstlt (void)
3186 T0 = _do_efdtstlt(T0_64, T1_64);
3187 RETURN();
3190 void OPPROTO op_efdtstgt (void)
3192 T0 = _do_efdtstgt(T0_64, T1_64);
3193 RETURN();
3196 void OPPROTO op_efdtsteq (void)
3198 T0 = _do_efdtsteq(T0_64, T1_64);
3199 RETURN();
3201 #endif /* defined(TARGET_PPCEMB) */