More TCG updates for CRIS
[qemu/qemu-JZ.git] / target-mips / op.c
blob00b779967eaafc00680df0800f5979f87017d124
1 /*
2 * MIPS emulation micro-operations for qemu.
4 * Copyright (c) 2004-2005 Jocelyn Mayer
5 * Copyright (c) 2006 Marius Groeger (FPU operations)
6 * Copyright (c) 2007 Thiemo Seufer (64-bit FPU support)
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include "config.h"
24 #include "exec.h"
25 #include "host-utils.h"
27 #ifndef CALL_FROM_TB0
28 #define CALL_FROM_TB0(func) func()
29 #endif
30 #ifndef CALL_FROM_TB1
31 #define CALL_FROM_TB1(func, arg0) func(arg0)
32 #endif
33 #ifndef CALL_FROM_TB1_CONST16
34 #define CALL_FROM_TB1_CONST16(func, arg0) CALL_FROM_TB1(func, arg0)
35 #endif
36 #ifndef CALL_FROM_TB2
37 #define CALL_FROM_TB2(func, arg0, arg1) func(arg0, arg1)
38 #endif
39 #ifndef CALL_FROM_TB2_CONST16
40 #define CALL_FROM_TB2_CONST16(func, arg0, arg1) \
41 CALL_FROM_TB2(func, arg0, arg1)
42 #endif
43 #ifndef CALL_FROM_TB3
44 #define CALL_FROM_TB3(func, arg0, arg1, arg2) func(arg0, arg1, arg2)
45 #endif
46 #ifndef CALL_FROM_TB4
47 #define CALL_FROM_TB4(func, arg0, arg1, arg2, arg3) \
48 func(arg0, arg1, arg2, arg3)
49 #endif
51 #define REG 1
52 #include "op_template.c"
53 #undef REG
54 #define REG 2
55 #include "op_template.c"
56 #undef REG
57 #define REG 3
58 #include "op_template.c"
59 #undef REG
60 #define REG 4
61 #include "op_template.c"
62 #undef REG
63 #define REG 5
64 #include "op_template.c"
65 #undef REG
66 #define REG 6
67 #include "op_template.c"
68 #undef REG
69 #define REG 7
70 #include "op_template.c"
71 #undef REG
72 #define REG 8
73 #include "op_template.c"
74 #undef REG
75 #define REG 9
76 #include "op_template.c"
77 #undef REG
78 #define REG 10
79 #include "op_template.c"
80 #undef REG
81 #define REG 11
82 #include "op_template.c"
83 #undef REG
84 #define REG 12
85 #include "op_template.c"
86 #undef REG
87 #define REG 13
88 #include "op_template.c"
89 #undef REG
90 #define REG 14
91 #include "op_template.c"
92 #undef REG
93 #define REG 15
94 #include "op_template.c"
95 #undef REG
96 #define REG 16
97 #include "op_template.c"
98 #undef REG
99 #define REG 17
100 #include "op_template.c"
101 #undef REG
102 #define REG 18
103 #include "op_template.c"
104 #undef REG
105 #define REG 19
106 #include "op_template.c"
107 #undef REG
108 #define REG 20
109 #include "op_template.c"
110 #undef REG
111 #define REG 21
112 #include "op_template.c"
113 #undef REG
114 #define REG 22
115 #include "op_template.c"
116 #undef REG
117 #define REG 23
118 #include "op_template.c"
119 #undef REG
120 #define REG 24
121 #include "op_template.c"
122 #undef REG
123 #define REG 25
124 #include "op_template.c"
125 #undef REG
126 #define REG 26
127 #include "op_template.c"
128 #undef REG
129 #define REG 27
130 #include "op_template.c"
131 #undef REG
132 #define REG 28
133 #include "op_template.c"
134 #undef REG
135 #define REG 29
136 #include "op_template.c"
137 #undef REG
138 #define REG 30
139 #include "op_template.c"
140 #undef REG
141 #define REG 31
142 #include "op_template.c"
143 #undef REG
145 #define TN
146 #include "op_template.c"
147 #undef TN
149 #define FREG 0
150 #include "fop_template.c"
151 #undef FREG
152 #define FREG 1
153 #include "fop_template.c"
154 #undef FREG
155 #define FREG 2
156 #include "fop_template.c"
157 #undef FREG
158 #define FREG 3
159 #include "fop_template.c"
160 #undef FREG
161 #define FREG 4
162 #include "fop_template.c"
163 #undef FREG
164 #define FREG 5
165 #include "fop_template.c"
166 #undef FREG
167 #define FREG 6
168 #include "fop_template.c"
169 #undef FREG
170 #define FREG 7
171 #include "fop_template.c"
172 #undef FREG
173 #define FREG 8
174 #include "fop_template.c"
175 #undef FREG
176 #define FREG 9
177 #include "fop_template.c"
178 #undef FREG
179 #define FREG 10
180 #include "fop_template.c"
181 #undef FREG
182 #define FREG 11
183 #include "fop_template.c"
184 #undef FREG
185 #define FREG 12
186 #include "fop_template.c"
187 #undef FREG
188 #define FREG 13
189 #include "fop_template.c"
190 #undef FREG
191 #define FREG 14
192 #include "fop_template.c"
193 #undef FREG
194 #define FREG 15
195 #include "fop_template.c"
196 #undef FREG
197 #define FREG 16
198 #include "fop_template.c"
199 #undef FREG
200 #define FREG 17
201 #include "fop_template.c"
202 #undef FREG
203 #define FREG 18
204 #include "fop_template.c"
205 #undef FREG
206 #define FREG 19
207 #include "fop_template.c"
208 #undef FREG
209 #define FREG 20
210 #include "fop_template.c"
211 #undef FREG
212 #define FREG 21
213 #include "fop_template.c"
214 #undef FREG
215 #define FREG 22
216 #include "fop_template.c"
217 #undef FREG
218 #define FREG 23
219 #include "fop_template.c"
220 #undef FREG
221 #define FREG 24
222 #include "fop_template.c"
223 #undef FREG
224 #define FREG 25
225 #include "fop_template.c"
226 #undef FREG
227 #define FREG 26
228 #include "fop_template.c"
229 #undef FREG
230 #define FREG 27
231 #include "fop_template.c"
232 #undef FREG
233 #define FREG 28
234 #include "fop_template.c"
235 #undef FREG
236 #define FREG 29
237 #include "fop_template.c"
238 #undef FREG
239 #define FREG 30
240 #include "fop_template.c"
241 #undef FREG
242 #define FREG 31
243 #include "fop_template.c"
244 #undef FREG
246 #define FTN
247 #include "fop_template.c"
248 #undef FTN
250 void op_load_HI (void)
252 T0 = env->HI[env->current_tc][PARAM1];
253 FORCE_RET();
256 void op_store_HI (void)
258 env->HI[env->current_tc][PARAM1] = T0;
259 FORCE_RET();
262 void op_load_LO (void)
264 T0 = env->LO[env->current_tc][PARAM1];
265 FORCE_RET();
268 void op_store_LO (void)
270 env->LO[env->current_tc][PARAM1] = T0;
271 FORCE_RET();
274 /* Load and store */
275 #define MEMSUFFIX _raw
276 #include "op_mem.c"
277 #undef MEMSUFFIX
278 #if !defined(CONFIG_USER_ONLY)
279 #define MEMSUFFIX _user
280 #include "op_mem.c"
281 #undef MEMSUFFIX
283 #define MEMSUFFIX _super
284 #include "op_mem.c"
285 #undef MEMSUFFIX
287 #define MEMSUFFIX _kernel
288 #include "op_mem.c"
289 #undef MEMSUFFIX
290 #endif
292 /* Addresses computation */
293 void op_addr_add (void)
295 /* For compatibility with 32-bit code, data reference in user mode
296 with Status_UX = 0 should be casted to 32-bit and sign extended.
297 See the MIPS64 PRA manual, section 4.10. */
298 #if defined(TARGET_MIPS64)
299 if (((env->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
300 !(env->CP0_Status & (1 << CP0St_UX)))
301 T0 = (int64_t)(int32_t)(T0 + T1);
302 else
303 #endif
304 T0 += T1;
305 FORCE_RET();
308 /* Arithmetic */
309 void op_add (void)
311 T0 = (int32_t)((int32_t)T0 + (int32_t)T1);
312 FORCE_RET();
315 void op_addo (void)
317 target_ulong tmp;
319 tmp = (int32_t)T0;
320 T0 = (int32_t)T0 + (int32_t)T1;
321 if (((tmp ^ T1 ^ (-1)) & (T0 ^ T1)) >> 31) {
322 /* operands of same sign, result different sign */
323 CALL_FROM_TB1(do_raise_exception, EXCP_OVERFLOW);
325 T0 = (int32_t)T0;
326 FORCE_RET();
329 void op_sub (void)
331 T0 = (int32_t)((int32_t)T0 - (int32_t)T1);
332 FORCE_RET();
335 void op_subo (void)
337 target_ulong tmp;
339 tmp = (int32_t)T0;
340 T0 = (int32_t)T0 - (int32_t)T1;
341 if (((tmp ^ T1) & (tmp ^ T0)) >> 31) {
342 /* operands of different sign, first operand and result different sign */
343 CALL_FROM_TB1(do_raise_exception, EXCP_OVERFLOW);
345 T0 = (int32_t)T0;
346 FORCE_RET();
349 void op_mul (void)
351 T0 = (int32_t)((int32_t)T0 * (int32_t)T1);
352 FORCE_RET();
355 #if HOST_LONG_BITS < 64
356 void op_div (void)
358 CALL_FROM_TB0(do_div);
359 FORCE_RET();
361 #else
362 void op_div (void)
364 if (T1 != 0) {
365 env->LO[env->current_tc][0] = (int32_t)((int64_t)(int32_t)T0 / (int32_t)T1);
366 env->HI[env->current_tc][0] = (int32_t)((int64_t)(int32_t)T0 % (int32_t)T1);
368 FORCE_RET();
370 #endif
372 void op_divu (void)
374 if (T1 != 0) {
375 env->LO[env->current_tc][0] = (int32_t)((uint32_t)T0 / (uint32_t)T1);
376 env->HI[env->current_tc][0] = (int32_t)((uint32_t)T0 % (uint32_t)T1);
378 FORCE_RET();
381 #if defined(TARGET_MIPS64)
382 /* Arithmetic */
383 void op_dadd (void)
385 T0 += T1;
386 FORCE_RET();
389 void op_daddo (void)
391 target_long tmp;
393 tmp = T0;
394 T0 += T1;
395 if (((tmp ^ T1 ^ (-1)) & (T0 ^ T1)) >> 63) {
396 /* operands of same sign, result different sign */
397 CALL_FROM_TB1(do_raise_exception, EXCP_OVERFLOW);
399 FORCE_RET();
402 void op_dsub (void)
404 T0 -= T1;
405 FORCE_RET();
408 void op_dsubo (void)
410 target_long tmp;
412 tmp = T0;
413 T0 = (int64_t)T0 - (int64_t)T1;
414 if (((tmp ^ T1) & (tmp ^ T0)) >> 63) {
415 /* operands of different sign, first operand and result different sign */
416 CALL_FROM_TB1(do_raise_exception, EXCP_OVERFLOW);
418 FORCE_RET();
421 void op_dmul (void)
423 T0 = (int64_t)T0 * (int64_t)T1;
424 FORCE_RET();
427 /* Those might call libgcc functions. */
428 void op_ddiv (void)
430 do_ddiv();
431 FORCE_RET();
434 #if TARGET_LONG_BITS > HOST_LONG_BITS
435 void op_ddivu (void)
437 do_ddivu();
438 FORCE_RET();
440 #else
441 void op_ddivu (void)
443 if (T1 != 0) {
444 env->LO[env->current_tc][0] = T0 / T1;
445 env->HI[env->current_tc][0] = T0 % T1;
447 FORCE_RET();
449 #endif
450 #endif /* TARGET_MIPS64 */
452 /* Logical */
453 void op_and (void)
455 T0 &= T1;
456 FORCE_RET();
459 void op_nor (void)
461 T0 = ~(T0 | T1);
462 FORCE_RET();
465 void op_or (void)
467 T0 |= T1;
468 FORCE_RET();
471 void op_xor (void)
473 T0 ^= T1;
474 FORCE_RET();
477 void op_sll (void)
479 T0 = (int32_t)((uint32_t)T0 << T1);
480 FORCE_RET();
483 void op_sra (void)
485 T0 = (int32_t)((int32_t)T0 >> T1);
486 FORCE_RET();
489 void op_srl (void)
491 T0 = (int32_t)((uint32_t)T0 >> T1);
492 FORCE_RET();
495 void op_rotr (void)
497 target_ulong tmp;
499 if (T1) {
500 tmp = (int32_t)((uint32_t)T0 << (0x20 - T1));
501 T0 = (int32_t)((uint32_t)T0 >> T1) | tmp;
503 FORCE_RET();
506 void op_sllv (void)
508 T0 = (int32_t)((uint32_t)T1 << ((uint32_t)T0 & 0x1F));
509 FORCE_RET();
512 void op_srav (void)
514 T0 = (int32_t)((int32_t)T1 >> (T0 & 0x1F));
515 FORCE_RET();
518 void op_srlv (void)
520 T0 = (int32_t)((uint32_t)T1 >> (T0 & 0x1F));
521 FORCE_RET();
524 void op_rotrv (void)
526 target_ulong tmp;
528 T0 &= 0x1F;
529 if (T0) {
530 tmp = (int32_t)((uint32_t)T1 << (0x20 - T0));
531 T0 = (int32_t)((uint32_t)T1 >> T0) | tmp;
532 } else
533 T0 = T1;
534 FORCE_RET();
537 void op_clo (void)
539 T0 = clo32(T0);
540 FORCE_RET();
543 void op_clz (void)
545 T0 = clz32(T0);
546 FORCE_RET();
549 #if defined(TARGET_MIPS64)
551 #if TARGET_LONG_BITS > HOST_LONG_BITS
552 /* Those might call libgcc functions. */
553 void op_dsll (void)
555 CALL_FROM_TB0(do_dsll);
556 FORCE_RET();
559 void op_dsll32 (void)
561 CALL_FROM_TB0(do_dsll32);
562 FORCE_RET();
565 void op_dsra (void)
567 CALL_FROM_TB0(do_dsra);
568 FORCE_RET();
571 void op_dsra32 (void)
573 CALL_FROM_TB0(do_dsra32);
574 FORCE_RET();
577 void op_dsrl (void)
579 CALL_FROM_TB0(do_dsrl);
580 FORCE_RET();
583 void op_dsrl32 (void)
585 CALL_FROM_TB0(do_dsrl32);
586 FORCE_RET();
589 void op_drotr (void)
591 CALL_FROM_TB0(do_drotr);
592 FORCE_RET();
595 void op_drotr32 (void)
597 CALL_FROM_TB0(do_drotr32);
598 FORCE_RET();
601 void op_dsllv (void)
603 CALL_FROM_TB0(do_dsllv);
604 FORCE_RET();
607 void op_dsrav (void)
609 CALL_FROM_TB0(do_dsrav);
610 FORCE_RET();
613 void op_dsrlv (void)
615 CALL_FROM_TB0(do_dsrlv);
616 FORCE_RET();
619 void op_drotrv (void)
621 CALL_FROM_TB0(do_drotrv);
622 FORCE_RET();
625 void op_dclo (void)
627 CALL_FROM_TB0(do_dclo);
628 FORCE_RET();
631 void op_dclz (void)
633 CALL_FROM_TB0(do_dclz);
634 FORCE_RET();
637 #else /* TARGET_LONG_BITS > HOST_LONG_BITS */
639 void op_dsll (void)
641 T0 = T0 << T1;
642 FORCE_RET();
645 void op_dsll32 (void)
647 T0 = T0 << (T1 + 32);
648 FORCE_RET();
651 void op_dsra (void)
653 T0 = (int64_t)T0 >> T1;
654 FORCE_RET();
657 void op_dsra32 (void)
659 T0 = (int64_t)T0 >> (T1 + 32);
660 FORCE_RET();
663 void op_dsrl (void)
665 T0 = T0 >> T1;
666 FORCE_RET();
669 void op_dsrl32 (void)
671 T0 = T0 >> (T1 + 32);
672 FORCE_RET();
675 void op_drotr (void)
677 target_ulong tmp;
679 if (T1) {
680 tmp = T0 << (0x40 - T1);
681 T0 = (T0 >> T1) | tmp;
683 FORCE_RET();
686 void op_drotr32 (void)
688 target_ulong tmp;
690 tmp = T0 << (0x40 - (32 + T1));
691 T0 = (T0 >> (32 + T1)) | tmp;
692 FORCE_RET();
695 void op_dsllv (void)
697 T0 = T1 << (T0 & 0x3F);
698 FORCE_RET();
701 void op_dsrav (void)
703 T0 = (int64_t)T1 >> (T0 & 0x3F);
704 FORCE_RET();
707 void op_dsrlv (void)
709 T0 = T1 >> (T0 & 0x3F);
710 FORCE_RET();
713 void op_drotrv (void)
715 target_ulong tmp;
717 T0 &= 0x3F;
718 if (T0) {
719 tmp = T1 << (0x40 - T0);
720 T0 = (T1 >> T0) | tmp;
721 } else
722 T0 = T1;
723 FORCE_RET();
726 void op_dclo (void)
728 T0 = clo64(T0);
729 FORCE_RET();
732 void op_dclz (void)
734 T0 = clz64(T0);
735 FORCE_RET();
737 #endif /* TARGET_LONG_BITS > HOST_LONG_BITS */
738 #endif /* TARGET_MIPS64 */
740 /* 64 bits arithmetic */
741 #if TARGET_LONG_BITS > HOST_LONG_BITS
742 void op_mult (void)
744 CALL_FROM_TB0(do_mult);
745 FORCE_RET();
748 void op_multu (void)
750 CALL_FROM_TB0(do_multu);
751 FORCE_RET();
754 void op_madd (void)
756 CALL_FROM_TB0(do_madd);
757 FORCE_RET();
760 void op_maddu (void)
762 CALL_FROM_TB0(do_maddu);
763 FORCE_RET();
766 void op_msub (void)
768 CALL_FROM_TB0(do_msub);
769 FORCE_RET();
772 void op_msubu (void)
774 CALL_FROM_TB0(do_msubu);
775 FORCE_RET();
778 /* Multiplication variants of the vr54xx. */
779 void op_muls (void)
781 CALL_FROM_TB0(do_muls);
782 FORCE_RET();
785 void op_mulsu (void)
787 CALL_FROM_TB0(do_mulsu);
788 FORCE_RET();
791 void op_macc (void)
793 CALL_FROM_TB0(do_macc);
794 FORCE_RET();
797 void op_macchi (void)
799 CALL_FROM_TB0(do_macchi);
800 FORCE_RET();
803 void op_maccu (void)
805 CALL_FROM_TB0(do_maccu);
806 FORCE_RET();
808 void op_macchiu (void)
810 CALL_FROM_TB0(do_macchiu);
811 FORCE_RET();
814 void op_msac (void)
816 CALL_FROM_TB0(do_msac);
817 FORCE_RET();
820 void op_msachi (void)
822 CALL_FROM_TB0(do_msachi);
823 FORCE_RET();
826 void op_msacu (void)
828 CALL_FROM_TB0(do_msacu);
829 FORCE_RET();
832 void op_msachiu (void)
834 CALL_FROM_TB0(do_msachiu);
835 FORCE_RET();
838 void op_mulhi (void)
840 CALL_FROM_TB0(do_mulhi);
841 FORCE_RET();
844 void op_mulhiu (void)
846 CALL_FROM_TB0(do_mulhiu);
847 FORCE_RET();
850 void op_mulshi (void)
852 CALL_FROM_TB0(do_mulshi);
853 FORCE_RET();
856 void op_mulshiu (void)
858 CALL_FROM_TB0(do_mulshiu);
859 FORCE_RET();
862 #else /* TARGET_LONG_BITS > HOST_LONG_BITS */
864 static always_inline uint64_t get_HILO (void)
866 return ((uint64_t)env->HI[env->current_tc][0] << 32) |
867 ((uint64_t)(uint32_t)env->LO[env->current_tc][0]);
870 static always_inline void set_HILO (uint64_t HILO)
872 env->LO[env->current_tc][0] = (int32_t)(HILO & 0xFFFFFFFF);
873 env->HI[env->current_tc][0] = (int32_t)(HILO >> 32);
876 static always_inline void set_HIT0_LO (uint64_t HILO)
878 env->LO[env->current_tc][0] = (int32_t)(HILO & 0xFFFFFFFF);
879 T0 = env->HI[env->current_tc][0] = (int32_t)(HILO >> 32);
882 static always_inline void set_HI_LOT0 (uint64_t HILO)
884 T0 = env->LO[env->current_tc][0] = (int32_t)(HILO & 0xFFFFFFFF);
885 env->HI[env->current_tc][0] = (int32_t)(HILO >> 32);
888 void op_mult (void)
890 set_HILO((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
891 FORCE_RET();
894 void op_multu (void)
896 set_HILO((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
897 FORCE_RET();
900 void op_madd (void)
902 int64_t tmp;
904 tmp = ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
905 set_HILO((int64_t)get_HILO() + tmp);
906 FORCE_RET();
909 void op_maddu (void)
911 uint64_t tmp;
913 tmp = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
914 set_HILO(get_HILO() + tmp);
915 FORCE_RET();
918 void op_msub (void)
920 int64_t tmp;
922 tmp = ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
923 set_HILO((int64_t)get_HILO() - tmp);
924 FORCE_RET();
927 void op_msubu (void)
929 uint64_t tmp;
931 tmp = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
932 set_HILO(get_HILO() - tmp);
933 FORCE_RET();
936 /* Multiplication variants of the vr54xx. */
937 void op_muls (void)
939 set_HI_LOT0(0 - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
940 FORCE_RET();
943 void op_mulsu (void)
945 set_HI_LOT0(0 - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
946 FORCE_RET();
949 void op_macc (void)
951 set_HI_LOT0(get_HILO() + ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
952 FORCE_RET();
955 void op_macchi (void)
957 set_HIT0_LO(get_HILO() + ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
958 FORCE_RET();
961 void op_maccu (void)
963 set_HI_LOT0(get_HILO() + ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
964 FORCE_RET();
967 void op_macchiu (void)
969 set_HIT0_LO(get_HILO() + ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
970 FORCE_RET();
973 void op_msac (void)
975 set_HI_LOT0(get_HILO() - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
976 FORCE_RET();
979 void op_msachi (void)
981 set_HIT0_LO(get_HILO() - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
982 FORCE_RET();
985 void op_msacu (void)
987 set_HI_LOT0(get_HILO() - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
988 FORCE_RET();
991 void op_msachiu (void)
993 set_HIT0_LO(get_HILO() - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
994 FORCE_RET();
997 void op_mulhi (void)
999 set_HIT0_LO((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
1000 FORCE_RET();
1003 void op_mulhiu (void)
1005 set_HIT0_LO((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
1006 FORCE_RET();
1009 void op_mulshi (void)
1011 set_HIT0_LO(0 - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
1012 FORCE_RET();
1015 void op_mulshiu (void)
1017 set_HIT0_LO(0 - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
1018 FORCE_RET();
1021 #endif /* TARGET_LONG_BITS > HOST_LONG_BITS */
1023 #if defined(TARGET_MIPS64)
1024 void op_dmult (void)
1026 CALL_FROM_TB4(muls64, &(env->LO[env->current_tc][0]), &(env->HI[env->current_tc][0]), T0, T1);
1027 FORCE_RET();
1030 void op_dmultu (void)
1032 CALL_FROM_TB4(mulu64, &(env->LO[env->current_tc][0]), &(env->HI[env->current_tc][0]), T0, T1);
1033 FORCE_RET();
1035 #endif
1037 /* Conditional moves */
1038 void op_movn (void)
1040 if (T1 != 0)
1041 env->gpr[env->current_tc][PARAM1] = T0;
1042 FORCE_RET();
1045 void op_movz (void)
1047 if (T1 == 0)
1048 env->gpr[env->current_tc][PARAM1] = T0;
1049 FORCE_RET();
1052 void op_movf (void)
1054 if (!(env->fpu->fcr31 & PARAM1))
1055 T0 = T1;
1056 FORCE_RET();
1059 void op_movt (void)
1061 if (env->fpu->fcr31 & PARAM1)
1062 T0 = T1;
1063 FORCE_RET();
1066 /* Tests */
1067 #define OP_COND(name, cond) \
1068 void glue(op_, name) (void) \
1070 if (cond) { \
1071 T0 = 1; \
1072 } else { \
1073 T0 = 0; \
1075 FORCE_RET(); \
1078 OP_COND(eq, T0 == T1);
1079 OP_COND(ne, T0 != T1);
1080 OP_COND(ge, (target_long)T0 >= (target_long)T1);
1081 OP_COND(geu, T0 >= T1);
1082 OP_COND(lt, (target_long)T0 < (target_long)T1);
1083 OP_COND(ltu, T0 < T1);
1084 OP_COND(gez, (target_long)T0 >= 0);
1085 OP_COND(gtz, (target_long)T0 > 0);
1086 OP_COND(lez, (target_long)T0 <= 0);
1087 OP_COND(ltz, (target_long)T0 < 0);
1089 /* Branches */
1090 /* Branch to register */
1091 void op_save_breg_target (void)
1093 env->btarget = T1;
1094 FORCE_RET();
1097 void op_breg (void)
1099 env->PC[env->current_tc] = env->btarget;
1100 FORCE_RET();
1103 void op_save_btarget (void)
1105 env->btarget = PARAM1;
1106 FORCE_RET();
1109 #if defined(TARGET_MIPS64)
1110 void op_save_btarget64 (void)
1112 env->btarget = ((uint64_t)PARAM1 << 32) | (uint32_t)PARAM2;
1113 FORCE_RET();
1115 #endif
1117 /* Conditional branch */
1118 void op_set_bcond (void)
1120 env->bcond = T0;
1121 FORCE_RET();
1124 void op_jnz_bcond (void)
1126 if (env->bcond)
1127 GOTO_LABEL_PARAM(1);
1128 FORCE_RET();
1131 /* CP0 functions */
1132 void op_mfc0_index (void)
1134 T0 = env->CP0_Index;
1135 FORCE_RET();
1138 void op_mfc0_mvpcontrol (void)
1140 T0 = env->mvp->CP0_MVPControl;
1141 FORCE_RET();
1144 void op_mfc0_mvpconf0 (void)
1146 T0 = env->mvp->CP0_MVPConf0;
1147 FORCE_RET();
1150 void op_mfc0_mvpconf1 (void)
1152 T0 = env->mvp->CP0_MVPConf1;
1153 FORCE_RET();
1156 void op_mfc0_random (void)
1158 CALL_FROM_TB0(do_mfc0_random);
1159 FORCE_RET();
1162 void op_mfc0_vpecontrol (void)
1164 T0 = env->CP0_VPEControl;
1165 FORCE_RET();
1168 void op_mfc0_vpeconf0 (void)
1170 T0 = env->CP0_VPEConf0;
1171 FORCE_RET();
1174 void op_mfc0_vpeconf1 (void)
1176 T0 = env->CP0_VPEConf1;
1177 FORCE_RET();
1180 void op_mfc0_yqmask (void)
1182 T0 = env->CP0_YQMask;
1183 FORCE_RET();
1186 void op_mfc0_vpeschedule (void)
1188 T0 = env->CP0_VPESchedule;
1189 FORCE_RET();
1192 void op_mfc0_vpeschefback (void)
1194 T0 = env->CP0_VPEScheFBack;
1195 FORCE_RET();
1198 void op_mfc0_vpeopt (void)
1200 T0 = env->CP0_VPEOpt;
1201 FORCE_RET();
1204 void op_mfc0_entrylo0 (void)
1206 T0 = (int32_t)env->CP0_EntryLo0;
1207 FORCE_RET();
1210 void op_mfc0_tcstatus (void)
1212 T0 = env->CP0_TCStatus[env->current_tc];
1213 FORCE_RET();
1216 void op_mftc0_tcstatus(void)
1218 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1220 T0 = env->CP0_TCStatus[other_tc];
1221 FORCE_RET();
1224 void op_mfc0_tcbind (void)
1226 T0 = env->CP0_TCBind[env->current_tc];
1227 FORCE_RET();
1230 void op_mftc0_tcbind(void)
1232 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1234 T0 = env->CP0_TCBind[other_tc];
1235 FORCE_RET();
1238 void op_mfc0_tcrestart (void)
1240 T0 = env->PC[env->current_tc];
1241 FORCE_RET();
1244 void op_mftc0_tcrestart(void)
1246 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1248 T0 = env->PC[other_tc];
1249 FORCE_RET();
1252 void op_mfc0_tchalt (void)
1254 T0 = env->CP0_TCHalt[env->current_tc];
1255 FORCE_RET();
1258 void op_mftc0_tchalt(void)
1260 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1262 T0 = env->CP0_TCHalt[other_tc];
1263 FORCE_RET();
1266 void op_mfc0_tccontext (void)
1268 T0 = env->CP0_TCContext[env->current_tc];
1269 FORCE_RET();
1272 void op_mftc0_tccontext(void)
1274 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1276 T0 = env->CP0_TCContext[other_tc];
1277 FORCE_RET();
1280 void op_mfc0_tcschedule (void)
1282 T0 = env->CP0_TCSchedule[env->current_tc];
1283 FORCE_RET();
1286 void op_mftc0_tcschedule(void)
1288 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1290 T0 = env->CP0_TCSchedule[other_tc];
1291 FORCE_RET();
1294 void op_mfc0_tcschefback (void)
1296 T0 = env->CP0_TCScheFBack[env->current_tc];
1297 FORCE_RET();
1300 void op_mftc0_tcschefback(void)
1302 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1304 T0 = env->CP0_TCScheFBack[other_tc];
1305 FORCE_RET();
1308 void op_mfc0_entrylo1 (void)
1310 T0 = (int32_t)env->CP0_EntryLo1;
1311 FORCE_RET();
1314 void op_mfc0_context (void)
1316 T0 = (int32_t)env->CP0_Context;
1317 FORCE_RET();
1320 void op_mfc0_pagemask (void)
1322 T0 = env->CP0_PageMask;
1323 FORCE_RET();
1326 void op_mfc0_pagegrain (void)
1328 T0 = env->CP0_PageGrain;
1329 FORCE_RET();
1332 void op_mfc0_wired (void)
1334 T0 = env->CP0_Wired;
1335 FORCE_RET();
1338 void op_mfc0_srsconf0 (void)
1340 T0 = env->CP0_SRSConf0;
1341 FORCE_RET();
1344 void op_mfc0_srsconf1 (void)
1346 T0 = env->CP0_SRSConf1;
1347 FORCE_RET();
1350 void op_mfc0_srsconf2 (void)
1352 T0 = env->CP0_SRSConf2;
1353 FORCE_RET();
1356 void op_mfc0_srsconf3 (void)
1358 T0 = env->CP0_SRSConf3;
1359 FORCE_RET();
1362 void op_mfc0_srsconf4 (void)
1364 T0 = env->CP0_SRSConf4;
1365 FORCE_RET();
1368 void op_mfc0_hwrena (void)
1370 T0 = env->CP0_HWREna;
1371 FORCE_RET();
1374 void op_mfc0_badvaddr (void)
1376 T0 = (int32_t)env->CP0_BadVAddr;
1377 FORCE_RET();
1380 void op_mfc0_count (void)
1382 CALL_FROM_TB0(do_mfc0_count);
1383 FORCE_RET();
1386 void op_mfc0_entryhi (void)
1388 T0 = (int32_t)env->CP0_EntryHi;
1389 FORCE_RET();
1392 void op_mftc0_entryhi(void)
1394 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1396 T0 = (env->CP0_EntryHi & ~0xff) | (env->CP0_TCStatus[other_tc] & 0xff);
1397 FORCE_RET();
1400 void op_mfc0_compare (void)
1402 T0 = env->CP0_Compare;
1403 FORCE_RET();
1406 void op_mfc0_status (void)
1408 T0 = env->CP0_Status;
1409 FORCE_RET();
1412 void op_mftc0_status(void)
1414 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1415 uint32_t tcstatus = env->CP0_TCStatus[other_tc];
1417 T0 = env->CP0_Status & ~0xf1000018;
1418 T0 |= tcstatus & (0xf << CP0TCSt_TCU0);
1419 T0 |= (tcstatus & (1 << CP0TCSt_TMX)) >> (CP0TCSt_TMX - CP0St_MX);
1420 T0 |= (tcstatus & (0x3 << CP0TCSt_TKSU)) >> (CP0TCSt_TKSU - CP0St_KSU);
1421 FORCE_RET();
1424 void op_mfc0_intctl (void)
1426 T0 = env->CP0_IntCtl;
1427 FORCE_RET();
1430 void op_mfc0_srsctl (void)
1432 T0 = env->CP0_SRSCtl;
1433 FORCE_RET();
1436 void op_mfc0_srsmap (void)
1438 T0 = env->CP0_SRSMap;
1439 FORCE_RET();
1442 void op_mfc0_cause (void)
1444 T0 = env->CP0_Cause;
1445 FORCE_RET();
1448 void op_mfc0_epc (void)
1450 T0 = (int32_t)env->CP0_EPC;
1451 FORCE_RET();
1454 void op_mfc0_prid (void)
1456 T0 = env->CP0_PRid;
1457 FORCE_RET();
1460 void op_mfc0_ebase (void)
1462 T0 = env->CP0_EBase;
1463 FORCE_RET();
1466 void op_mfc0_config0 (void)
1468 T0 = env->CP0_Config0;
1469 FORCE_RET();
1472 void op_mfc0_config1 (void)
1474 T0 = env->CP0_Config1;
1475 FORCE_RET();
1478 void op_mfc0_config2 (void)
1480 T0 = env->CP0_Config2;
1481 FORCE_RET();
1484 void op_mfc0_config3 (void)
1486 T0 = env->CP0_Config3;
1487 FORCE_RET();
1490 void op_mfc0_config6 (void)
1492 T0 = env->CP0_Config6;
1493 FORCE_RET();
1496 void op_mfc0_config7 (void)
1498 T0 = env->CP0_Config7;
1499 FORCE_RET();
1502 void op_mfc0_lladdr (void)
1504 T0 = (int32_t)env->CP0_LLAddr >> 4;
1505 FORCE_RET();
1508 void op_mfc0_watchlo (void)
1510 T0 = (int32_t)env->CP0_WatchLo[PARAM1];
1511 FORCE_RET();
1514 void op_mfc0_watchhi (void)
1516 T0 = env->CP0_WatchHi[PARAM1];
1517 FORCE_RET();
1520 void op_mfc0_xcontext (void)
1522 T0 = (int32_t)env->CP0_XContext;
1523 FORCE_RET();
1526 void op_mfc0_framemask (void)
1528 T0 = env->CP0_Framemask;
1529 FORCE_RET();
1532 void op_mfc0_debug (void)
1534 T0 = env->CP0_Debug;
1535 if (env->hflags & MIPS_HFLAG_DM)
1536 T0 |= 1 << CP0DB_DM;
1537 FORCE_RET();
1540 void op_mftc0_debug(void)
1542 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1544 /* XXX: Might be wrong, check with EJTAG spec. */
1545 T0 = (env->CP0_Debug & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) |
1546 (env->CP0_Debug_tcstatus[other_tc] &
1547 ((1 << CP0DB_SSt) | (1 << CP0DB_Halt)));
1548 FORCE_RET();
1551 void op_mfc0_depc (void)
1553 T0 = (int32_t)env->CP0_DEPC;
1554 FORCE_RET();
1557 void op_mfc0_performance0 (void)
1559 T0 = env->CP0_Performance0;
1560 FORCE_RET();
1563 void op_mfc0_taglo (void)
1565 T0 = env->CP0_TagLo;
1566 FORCE_RET();
1569 void op_mfc0_datalo (void)
1571 T0 = env->CP0_DataLo;
1572 FORCE_RET();
1575 void op_mfc0_taghi (void)
1577 T0 = env->CP0_TagHi;
1578 FORCE_RET();
1581 void op_mfc0_datahi (void)
1583 T0 = env->CP0_DataHi;
1584 FORCE_RET();
1587 void op_mfc0_errorepc (void)
1589 T0 = (int32_t)env->CP0_ErrorEPC;
1590 FORCE_RET();
1593 void op_mfc0_desave (void)
1595 T0 = env->CP0_DESAVE;
1596 FORCE_RET();
1599 void op_mtc0_index (void)
1601 int num = 1;
1602 unsigned int tmp = env->tlb->nb_tlb;
1604 do {
1605 tmp >>= 1;
1606 num <<= 1;
1607 } while (tmp);
1608 env->CP0_Index = (env->CP0_Index & 0x80000000) | (T0 & (num - 1));
1609 FORCE_RET();
1612 void op_mtc0_mvpcontrol (void)
1614 uint32_t mask = 0;
1615 uint32_t newval;
1617 if (env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP))
1618 mask |= (1 << CP0MVPCo_CPA) | (1 << CP0MVPCo_VPC) |
1619 (1 << CP0MVPCo_EVP);
1620 if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
1621 mask |= (1 << CP0MVPCo_STLB);
1622 newval = (env->mvp->CP0_MVPControl & ~mask) | (T0 & mask);
1624 // TODO: Enable/disable shared TLB, enable/disable VPEs.
1626 env->mvp->CP0_MVPControl = newval;
1627 FORCE_RET();
1630 void op_mtc0_vpecontrol (void)
1632 uint32_t mask;
1633 uint32_t newval;
1635 mask = (1 << CP0VPECo_YSI) | (1 << CP0VPECo_GSI) |
1636 (1 << CP0VPECo_TE) | (0xff << CP0VPECo_TargTC);
1637 newval = (env->CP0_VPEControl & ~mask) | (T0 & mask);
1639 /* Yield scheduler intercept not implemented. */
1640 /* Gating storage scheduler intercept not implemented. */
1642 // TODO: Enable/disable TCs.
1644 env->CP0_VPEControl = newval;
1645 FORCE_RET();
1648 void op_mtc0_vpeconf0 (void)
1650 uint32_t mask = 0;
1651 uint32_t newval;
1653 if (env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) {
1654 if (env->CP0_VPEConf0 & (1 << CP0VPEC0_VPA))
1655 mask |= (0xff << CP0VPEC0_XTC);
1656 mask |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
1658 newval = (env->CP0_VPEConf0 & ~mask) | (T0 & mask);
1660 // TODO: TC exclusive handling due to ERL/EXL.
1662 env->CP0_VPEConf0 = newval;
1663 FORCE_RET();
1666 void op_mtc0_vpeconf1 (void)
1668 uint32_t mask = 0;
1669 uint32_t newval;
1671 if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
1672 mask |= (0xff << CP0VPEC1_NCX) | (0xff << CP0VPEC1_NCP2) |
1673 (0xff << CP0VPEC1_NCP1);
1674 newval = (env->CP0_VPEConf1 & ~mask) | (T0 & mask);
1676 /* UDI not implemented. */
1677 /* CP2 not implemented. */
1679 // TODO: Handle FPU (CP1) binding.
1681 env->CP0_VPEConf1 = newval;
1682 FORCE_RET();
1685 void op_mtc0_yqmask (void)
1687 /* Yield qualifier inputs not implemented. */
1688 env->CP0_YQMask = 0x00000000;
1689 FORCE_RET();
1692 void op_mtc0_vpeschedule (void)
1694 env->CP0_VPESchedule = T0;
1695 FORCE_RET();
1698 void op_mtc0_vpeschefback (void)
1700 env->CP0_VPEScheFBack = T0;
1701 FORCE_RET();
1704 void op_mtc0_vpeopt (void)
1706 env->CP0_VPEOpt = T0 & 0x0000ffff;
1707 FORCE_RET();
1710 void op_mtc0_entrylo0 (void)
1712 /* Large physaddr (PABITS) not implemented */
1713 /* 1k pages not implemented */
1714 env->CP0_EntryLo0 = T0 & 0x3FFFFFFF;
1715 FORCE_RET();
1718 void op_mtc0_tcstatus (void)
1720 uint32_t mask = env->CP0_TCStatus_rw_bitmask;
1721 uint32_t newval;
1723 newval = (env->CP0_TCStatus[env->current_tc] & ~mask) | (T0 & mask);
1725 // TODO: Sync with CP0_Status.
1727 env->CP0_TCStatus[env->current_tc] = newval;
1728 FORCE_RET();
1731 void op_mttc0_tcstatus (void)
1733 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1735 // TODO: Sync with CP0_Status.
1737 env->CP0_TCStatus[other_tc] = T0;
1738 FORCE_RET();
1741 void op_mtc0_tcbind (void)
1743 uint32_t mask = (1 << CP0TCBd_TBE);
1744 uint32_t newval;
1746 if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
1747 mask |= (1 << CP0TCBd_CurVPE);
1748 newval = (env->CP0_TCBind[env->current_tc] & ~mask) | (T0 & mask);
1749 env->CP0_TCBind[env->current_tc] = newval;
1750 FORCE_RET();
1753 void op_mttc0_tcbind (void)
1755 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1756 uint32_t mask = (1 << CP0TCBd_TBE);
1757 uint32_t newval;
1759 if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
1760 mask |= (1 << CP0TCBd_CurVPE);
1761 newval = (env->CP0_TCBind[other_tc] & ~mask) | (T0 & mask);
1762 env->CP0_TCBind[other_tc] = newval;
1763 FORCE_RET();
1766 void op_mtc0_tcrestart (void)
1768 env->PC[env->current_tc] = T0;
1769 env->CP0_TCStatus[env->current_tc] &= ~(1 << CP0TCSt_TDS);
1770 env->CP0_LLAddr = 0ULL;
1771 /* MIPS16 not implemented. */
1772 FORCE_RET();
1775 void op_mttc0_tcrestart (void)
1777 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1779 env->PC[other_tc] = T0;
1780 env->CP0_TCStatus[other_tc] &= ~(1 << CP0TCSt_TDS);
1781 env->CP0_LLAddr = 0ULL;
1782 /* MIPS16 not implemented. */
1783 FORCE_RET();
1786 void op_mtc0_tchalt (void)
1788 env->CP0_TCHalt[env->current_tc] = T0 & 0x1;
1790 // TODO: Halt TC / Restart (if allocated+active) TC.
1792 FORCE_RET();
1795 void op_mttc0_tchalt (void)
1797 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1799 // TODO: Halt TC / Restart (if allocated+active) TC.
1801 env->CP0_TCHalt[other_tc] = T0;
1802 FORCE_RET();
1805 void op_mtc0_tccontext (void)
1807 env->CP0_TCContext[env->current_tc] = T0;
1808 FORCE_RET();
1811 void op_mttc0_tccontext (void)
1813 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1815 env->CP0_TCContext[other_tc] = T0;
1816 FORCE_RET();
1819 void op_mtc0_tcschedule (void)
1821 env->CP0_TCSchedule[env->current_tc] = T0;
1822 FORCE_RET();
1825 void op_mttc0_tcschedule (void)
1827 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1829 env->CP0_TCSchedule[other_tc] = T0;
1830 FORCE_RET();
1833 void op_mtc0_tcschefback (void)
1835 env->CP0_TCScheFBack[env->current_tc] = T0;
1836 FORCE_RET();
1839 void op_mttc0_tcschefback (void)
1841 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1843 env->CP0_TCScheFBack[other_tc] = T0;
1844 FORCE_RET();
1847 void op_mtc0_entrylo1 (void)
1849 /* Large physaddr (PABITS) not implemented */
1850 /* 1k pages not implemented */
1851 env->CP0_EntryLo1 = T0 & 0x3FFFFFFF;
1852 FORCE_RET();
1855 void op_mtc0_context (void)
1857 env->CP0_Context = (env->CP0_Context & 0x007FFFFF) | (T0 & ~0x007FFFFF);
1858 FORCE_RET();
1861 void op_mtc0_pagemask (void)
1863 /* 1k pages not implemented */
1864 env->CP0_PageMask = T0 & (0x1FFFFFFF & (TARGET_PAGE_MASK << 1));
1865 FORCE_RET();
1868 void op_mtc0_pagegrain (void)
1870 /* SmartMIPS not implemented */
1871 /* Large physaddr (PABITS) not implemented */
1872 /* 1k pages not implemented */
1873 env->CP0_PageGrain = 0;
1874 FORCE_RET();
1877 void op_mtc0_wired (void)
1879 env->CP0_Wired = T0 % env->tlb->nb_tlb;
1880 FORCE_RET();
1883 void op_mtc0_srsconf0 (void)
1885 env->CP0_SRSConf0 |= T0 & env->CP0_SRSConf0_rw_bitmask;
1886 FORCE_RET();
1889 void op_mtc0_srsconf1 (void)
1891 env->CP0_SRSConf1 |= T0 & env->CP0_SRSConf1_rw_bitmask;
1892 FORCE_RET();
1895 void op_mtc0_srsconf2 (void)
1897 env->CP0_SRSConf2 |= T0 & env->CP0_SRSConf2_rw_bitmask;
1898 FORCE_RET();
1901 void op_mtc0_srsconf3 (void)
1903 env->CP0_SRSConf3 |= T0 & env->CP0_SRSConf3_rw_bitmask;
1904 FORCE_RET();
1907 void op_mtc0_srsconf4 (void)
1909 env->CP0_SRSConf4 |= T0 & env->CP0_SRSConf4_rw_bitmask;
1910 FORCE_RET();
1913 void op_mtc0_hwrena (void)
1915 env->CP0_HWREna = T0 & 0x0000000F;
1916 FORCE_RET();
1919 void op_mtc0_count (void)
1921 CALL_FROM_TB2(cpu_mips_store_count, env, T0);
1922 FORCE_RET();
1925 void op_mtc0_entryhi (void)
1927 target_ulong old, val;
1929 /* 1k pages not implemented */
1930 val = T0 & ((TARGET_PAGE_MASK << 1) | 0xFF);
1931 #if defined(TARGET_MIPS64)
1932 val &= env->SEGMask;
1933 #endif
1934 old = env->CP0_EntryHi;
1935 env->CP0_EntryHi = val;
1936 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
1937 uint32_t tcst = env->CP0_TCStatus[env->current_tc] & ~0xff;
1938 env->CP0_TCStatus[env->current_tc] = tcst | (val & 0xff);
1940 /* If the ASID changes, flush qemu's TLB. */
1941 if ((old & 0xFF) != (val & 0xFF))
1942 CALL_FROM_TB2(cpu_mips_tlb_flush, env, 1);
1943 FORCE_RET();
1946 void op_mttc0_entryhi(void)
1948 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1950 env->CP0_EntryHi = (env->CP0_EntryHi & 0xff) | (T0 & ~0xff);
1951 env->CP0_TCStatus[other_tc] = (env->CP0_TCStatus[other_tc] & ~0xff) | (T0 & 0xff);
1952 FORCE_RET();
1955 void op_mtc0_compare (void)
1957 CALL_FROM_TB2(cpu_mips_store_compare, env, T0);
1958 FORCE_RET();
1961 void op_mtc0_status (void)
1963 uint32_t val, old;
1964 uint32_t mask = env->CP0_Status_rw_bitmask;
1966 val = T0 & mask;
1967 old = env->CP0_Status;
1968 env->CP0_Status = (env->CP0_Status & ~mask) | val;
1969 CALL_FROM_TB1(compute_hflags, env);
1970 if (loglevel & CPU_LOG_EXEC)
1971 CALL_FROM_TB2(do_mtc0_status_debug, old, val);
1972 CALL_FROM_TB1(cpu_mips_update_irq, env);
1973 FORCE_RET();
1976 void op_mttc0_status(void)
1978 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1979 uint32_t tcstatus = env->CP0_TCStatus[other_tc];
1981 env->CP0_Status = T0 & ~0xf1000018;
1982 tcstatus = (tcstatus & ~(0xf << CP0TCSt_TCU0)) | (T0 & (0xf << CP0St_CU0));
1983 tcstatus = (tcstatus & ~(1 << CP0TCSt_TMX)) | ((T0 & (1 << CP0St_MX)) << (CP0TCSt_TMX - CP0St_MX));
1984 tcstatus = (tcstatus & ~(0x3 << CP0TCSt_TKSU)) | ((T0 & (0x3 << CP0St_KSU)) << (CP0TCSt_TKSU - CP0St_KSU));
1985 env->CP0_TCStatus[other_tc] = tcstatus;
1986 FORCE_RET();
1989 void op_mtc0_intctl (void)
1991 /* vectored interrupts not implemented, no performance counters. */
1992 env->CP0_IntCtl = (env->CP0_IntCtl & ~0x000002e0) | (T0 & 0x000002e0);
1993 FORCE_RET();
1996 void op_mtc0_srsctl (void)
1998 uint32_t mask = (0xf << CP0SRSCtl_ESS) | (0xf << CP0SRSCtl_PSS);
1999 env->CP0_SRSCtl = (env->CP0_SRSCtl & ~mask) | (T0 & mask);
2000 FORCE_RET();
2003 void op_mtc0_srsmap (void)
2005 env->CP0_SRSMap = T0;
2006 FORCE_RET();
2009 void op_mtc0_cause (void)
2011 uint32_t mask = 0x00C00300;
2012 uint32_t old = env->CP0_Cause;
2014 if (env->insn_flags & ISA_MIPS32R2)
2015 mask |= 1 << CP0Ca_DC;
2017 env->CP0_Cause = (env->CP0_Cause & ~mask) | (T0 & mask);
2019 if ((old ^ env->CP0_Cause) & (1 << CP0Ca_DC)) {
2020 if (env->CP0_Cause & (1 << CP0Ca_DC))
2021 CALL_FROM_TB1(cpu_mips_stop_count, env);
2022 else
2023 CALL_FROM_TB1(cpu_mips_start_count, env);
2026 /* Handle the software interrupt as an hardware one, as they
2027 are very similar */
2028 if (T0 & CP0Ca_IP_mask) {
2029 CALL_FROM_TB1(cpu_mips_update_irq, env);
2031 FORCE_RET();
2034 void op_mtc0_epc (void)
2036 env->CP0_EPC = T0;
2037 FORCE_RET();
2040 void op_mtc0_ebase (void)
2042 /* vectored interrupts not implemented */
2043 /* Multi-CPU not implemented */
2044 env->CP0_EBase = 0x80000000 | (T0 & 0x3FFFF000);
2045 FORCE_RET();
2048 void op_mtc0_config0 (void)
2050 env->CP0_Config0 = (env->CP0_Config0 & 0x81FFFFF8) | (T0 & 0x00000007);
2051 FORCE_RET();
2054 void op_mtc0_config2 (void)
2056 /* tertiary/secondary caches not implemented */
2057 env->CP0_Config2 = (env->CP0_Config2 & 0x8FFF0FFF);
2058 FORCE_RET();
2061 void op_mtc0_watchlo (void)
2063 /* Watch exceptions for instructions, data loads, data stores
2064 not implemented. */
2065 env->CP0_WatchLo[PARAM1] = (T0 & ~0x7);
2066 FORCE_RET();
2069 void op_mtc0_watchhi (void)
2071 env->CP0_WatchHi[PARAM1] = (T0 & 0x40FF0FF8);
2072 env->CP0_WatchHi[PARAM1] &= ~(env->CP0_WatchHi[PARAM1] & T0 & 0x7);
2073 FORCE_RET();
2076 void op_mtc0_xcontext (void)
2078 target_ulong mask = (1ULL << (env->SEGBITS - 7)) - 1;
2079 env->CP0_XContext = (env->CP0_XContext & mask) | (T0 & ~mask);
2080 FORCE_RET();
2083 void op_mtc0_framemask (void)
2085 env->CP0_Framemask = T0; /* XXX */
2086 FORCE_RET();
2089 void op_mtc0_debug (void)
2091 env->CP0_Debug = (env->CP0_Debug & 0x8C03FC1F) | (T0 & 0x13300120);
2092 if (T0 & (1 << CP0DB_DM))
2093 env->hflags |= MIPS_HFLAG_DM;
2094 else
2095 env->hflags &= ~MIPS_HFLAG_DM;
2096 FORCE_RET();
2099 void op_mttc0_debug(void)
2101 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2103 /* XXX: Might be wrong, check with EJTAG spec. */
2104 env->CP0_Debug_tcstatus[other_tc] = T0 & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt));
2105 env->CP0_Debug = (env->CP0_Debug & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) |
2106 (T0 & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt)));
2107 FORCE_RET();
2110 void op_mtc0_depc (void)
2112 env->CP0_DEPC = T0;
2113 FORCE_RET();
2116 void op_mtc0_performance0 (void)
2118 env->CP0_Performance0 = T0 & 0x000007ff;
2119 FORCE_RET();
2122 void op_mtc0_taglo (void)
2124 env->CP0_TagLo = T0 & 0xFFFFFCF6;
2125 FORCE_RET();
2128 void op_mtc0_datalo (void)
2130 env->CP0_DataLo = T0; /* XXX */
2131 FORCE_RET();
2134 void op_mtc0_taghi (void)
2136 env->CP0_TagHi = T0; /* XXX */
2137 FORCE_RET();
2140 void op_mtc0_datahi (void)
2142 env->CP0_DataHi = T0; /* XXX */
2143 FORCE_RET();
2146 void op_mtc0_errorepc (void)
2148 env->CP0_ErrorEPC = T0;
2149 FORCE_RET();
2152 void op_mtc0_desave (void)
2154 env->CP0_DESAVE = T0;
2155 FORCE_RET();
2158 #if defined(TARGET_MIPS64)
2159 void op_dmfc0_yqmask (void)
2161 T0 = env->CP0_YQMask;
2162 FORCE_RET();
2165 void op_dmfc0_vpeschedule (void)
2167 T0 = env->CP0_VPESchedule;
2168 FORCE_RET();
2171 void op_dmfc0_vpeschefback (void)
2173 T0 = env->CP0_VPEScheFBack;
2174 FORCE_RET();
2177 void op_dmfc0_entrylo0 (void)
2179 T0 = env->CP0_EntryLo0;
2180 FORCE_RET();
2183 void op_dmfc0_tcrestart (void)
2185 T0 = env->PC[env->current_tc];
2186 FORCE_RET();
2189 void op_dmfc0_tchalt (void)
2191 T0 = env->CP0_TCHalt[env->current_tc];
2192 FORCE_RET();
2195 void op_dmfc0_tccontext (void)
2197 T0 = env->CP0_TCContext[env->current_tc];
2198 FORCE_RET();
2201 void op_dmfc0_tcschedule (void)
2203 T0 = env->CP0_TCSchedule[env->current_tc];
2204 FORCE_RET();
2207 void op_dmfc0_tcschefback (void)
2209 T0 = env->CP0_TCScheFBack[env->current_tc];
2210 FORCE_RET();
2213 void op_dmfc0_entrylo1 (void)
2215 T0 = env->CP0_EntryLo1;
2216 FORCE_RET();
2219 void op_dmfc0_context (void)
2221 T0 = env->CP0_Context;
2222 FORCE_RET();
2225 void op_dmfc0_badvaddr (void)
2227 T0 = env->CP0_BadVAddr;
2228 FORCE_RET();
2231 void op_dmfc0_entryhi (void)
2233 T0 = env->CP0_EntryHi;
2234 FORCE_RET();
2237 void op_dmfc0_epc (void)
2239 T0 = env->CP0_EPC;
2240 FORCE_RET();
2243 void op_dmfc0_lladdr (void)
2245 T0 = env->CP0_LLAddr >> 4;
2246 FORCE_RET();
2249 void op_dmfc0_watchlo (void)
2251 T0 = env->CP0_WatchLo[PARAM1];
2252 FORCE_RET();
2255 void op_dmfc0_xcontext (void)
2257 T0 = env->CP0_XContext;
2258 FORCE_RET();
2261 void op_dmfc0_depc (void)
2263 T0 = env->CP0_DEPC;
2264 FORCE_RET();
2267 void op_dmfc0_errorepc (void)
2269 T0 = env->CP0_ErrorEPC;
2270 FORCE_RET();
2272 #endif /* TARGET_MIPS64 */
2274 /* MIPS MT functions */
2275 void op_mftgpr(void)
2277 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2279 T0 = env->gpr[other_tc][PARAM1];
2280 FORCE_RET();
2283 void op_mftlo(void)
2285 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2287 T0 = env->LO[other_tc][PARAM1];
2288 FORCE_RET();
2291 void op_mfthi(void)
2293 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2295 T0 = env->HI[other_tc][PARAM1];
2296 FORCE_RET();
2299 void op_mftacx(void)
2301 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2303 T0 = env->ACX[other_tc][PARAM1];
2304 FORCE_RET();
2307 void op_mftdsp(void)
2309 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2311 T0 = env->DSPControl[other_tc];
2312 FORCE_RET();
2315 void op_mttgpr(void)
2317 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2319 T0 = env->gpr[other_tc][PARAM1];
2320 FORCE_RET();
2323 void op_mttlo(void)
2325 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2327 T0 = env->LO[other_tc][PARAM1];
2328 FORCE_RET();
2331 void op_mtthi(void)
2333 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2335 T0 = env->HI[other_tc][PARAM1];
2336 FORCE_RET();
2339 void op_mttacx(void)
2341 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2343 T0 = env->ACX[other_tc][PARAM1];
2344 FORCE_RET();
2347 void op_mttdsp(void)
2349 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2351 T0 = env->DSPControl[other_tc];
2352 FORCE_RET();
2356 void op_dmt(void)
2358 // TODO
2359 T0 = 0;
2360 // rt = T0
2361 FORCE_RET();
2364 void op_emt(void)
2366 // TODO
2367 T0 = 0;
2368 // rt = T0
2369 FORCE_RET();
2372 void op_dvpe(void)
2374 // TODO
2375 T0 = 0;
2376 // rt = T0
2377 FORCE_RET();
2380 void op_evpe(void)
2382 // TODO
2383 T0 = 0;
2384 // rt = T0
2385 FORCE_RET();
2388 void op_fork(void)
2390 // T0 = rt, T1 = rs
2391 T0 = 0;
2392 // TODO: store to TC register
2393 FORCE_RET();
2396 void op_yield(void)
2398 if (T0 < 0) {
2399 /* No scheduling policy implemented. */
2400 if (T0 != -2) {
2401 if (env->CP0_VPEControl & (1 << CP0VPECo_YSI) &&
2402 env->CP0_TCStatus[env->current_tc] & (1 << CP0TCSt_DT)) {
2403 env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT);
2404 env->CP0_VPEControl |= 4 << CP0VPECo_EXCPT;
2405 CALL_FROM_TB1(do_raise_exception, EXCP_THREAD);
2408 } else if (T0 == 0) {
2409 if (0 /* TODO: TC underflow */) {
2410 env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT);
2411 CALL_FROM_TB1(do_raise_exception, EXCP_THREAD);
2412 } else {
2413 // TODO: Deallocate TC
2415 } else if (T0 > 0) {
2416 /* Yield qualifier inputs not implemented. */
2417 env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT);
2418 env->CP0_VPEControl |= 2 << CP0VPECo_EXCPT;
2419 CALL_FROM_TB1(do_raise_exception, EXCP_THREAD);
2421 T0 = env->CP0_YQMask;
2422 FORCE_RET();
2425 /* CP1 functions */
2426 #if 0
2427 # define DEBUG_FPU_STATE() CALL_FROM_TB1(dump_fpu, env)
2428 #else
2429 # define DEBUG_FPU_STATE() do { } while(0)
2430 #endif
2432 void op_cfc1 (void)
2434 CALL_FROM_TB1(do_cfc1, PARAM1);
2435 DEBUG_FPU_STATE();
2436 FORCE_RET();
2439 void op_ctc1 (void)
2441 CALL_FROM_TB1(do_ctc1, PARAM1);
2442 DEBUG_FPU_STATE();
2443 FORCE_RET();
2446 void op_mfc1 (void)
2448 T0 = (int32_t)WT0;
2449 DEBUG_FPU_STATE();
2450 FORCE_RET();
2453 void op_mtc1 (void)
2455 WT0 = T0;
2456 DEBUG_FPU_STATE();
2457 FORCE_RET();
2460 void op_dmfc1 (void)
2462 T0 = DT0;
2463 DEBUG_FPU_STATE();
2464 FORCE_RET();
2467 void op_dmtc1 (void)
2469 DT0 = T0;
2470 DEBUG_FPU_STATE();
2471 FORCE_RET();
2474 void op_mfhc1 (void)
2476 T0 = (int32_t)WTH0;
2477 DEBUG_FPU_STATE();
2478 FORCE_RET();
2481 void op_mthc1 (void)
2483 WTH0 = T0;
2484 DEBUG_FPU_STATE();
2485 FORCE_RET();
2488 /* Float support.
2489 Single precition routines have a "s" suffix, double precision a
2490 "d" suffix, 32bit integer "w", 64bit integer "l", paired singe "ps",
2491 paired single lowwer "pl", paired single upper "pu". */
2493 #define FLOAT_OP(name, p) void OPPROTO op_float_##name##_##p(void)
2495 FLOAT_OP(cvtd, s)
2497 CALL_FROM_TB0(do_float_cvtd_s);
2498 DEBUG_FPU_STATE();
2499 FORCE_RET();
2501 FLOAT_OP(cvtd, w)
2503 CALL_FROM_TB0(do_float_cvtd_w);
2504 DEBUG_FPU_STATE();
2505 FORCE_RET();
2507 FLOAT_OP(cvtd, l)
2509 CALL_FROM_TB0(do_float_cvtd_l);
2510 DEBUG_FPU_STATE();
2511 FORCE_RET();
2513 FLOAT_OP(cvtl, d)
2515 CALL_FROM_TB0(do_float_cvtl_d);
2516 DEBUG_FPU_STATE();
2517 FORCE_RET();
2519 FLOAT_OP(cvtl, s)
2521 CALL_FROM_TB0(do_float_cvtl_s);
2522 DEBUG_FPU_STATE();
2523 FORCE_RET();
2525 FLOAT_OP(cvtps, s)
2527 WT2 = WT0;
2528 WTH2 = WT1;
2529 DEBUG_FPU_STATE();
2530 FORCE_RET();
2532 FLOAT_OP(cvtps, pw)
2534 CALL_FROM_TB0(do_float_cvtps_pw);
2535 DEBUG_FPU_STATE();
2536 FORCE_RET();
2538 FLOAT_OP(cvtpw, ps)
2540 CALL_FROM_TB0(do_float_cvtpw_ps);
2541 DEBUG_FPU_STATE();
2542 FORCE_RET();
2544 FLOAT_OP(cvts, d)
2546 CALL_FROM_TB0(do_float_cvts_d);
2547 DEBUG_FPU_STATE();
2548 FORCE_RET();
2550 FLOAT_OP(cvts, w)
2552 CALL_FROM_TB0(do_float_cvts_w);
2553 DEBUG_FPU_STATE();
2554 FORCE_RET();
2556 FLOAT_OP(cvts, l)
2558 CALL_FROM_TB0(do_float_cvts_l);
2559 DEBUG_FPU_STATE();
2560 FORCE_RET();
2562 FLOAT_OP(cvts, pl)
2564 CALL_FROM_TB0(do_float_cvts_pl);
2565 DEBUG_FPU_STATE();
2566 FORCE_RET();
2568 FLOAT_OP(cvts, pu)
2570 CALL_FROM_TB0(do_float_cvts_pu);
2571 DEBUG_FPU_STATE();
2572 FORCE_RET();
2574 FLOAT_OP(cvtw, s)
2576 CALL_FROM_TB0(do_float_cvtw_s);
2577 DEBUG_FPU_STATE();
2578 FORCE_RET();
2580 FLOAT_OP(cvtw, d)
2582 CALL_FROM_TB0(do_float_cvtw_d);
2583 DEBUG_FPU_STATE();
2584 FORCE_RET();
2587 FLOAT_OP(pll, ps)
2589 DT2 = ((uint64_t)WT0 << 32) | WT1;
2590 DEBUG_FPU_STATE();
2591 FORCE_RET();
2593 FLOAT_OP(plu, ps)
2595 DT2 = ((uint64_t)WT0 << 32) | WTH1;
2596 DEBUG_FPU_STATE();
2597 FORCE_RET();
2599 FLOAT_OP(pul, ps)
2601 DT2 = ((uint64_t)WTH0 << 32) | WT1;
2602 DEBUG_FPU_STATE();
2603 FORCE_RET();
2605 FLOAT_OP(puu, ps)
2607 DT2 = ((uint64_t)WTH0 << 32) | WTH1;
2608 DEBUG_FPU_STATE();
2609 FORCE_RET();
2612 #define FLOAT_ROUNDOP(op, ttype, stype) \
2613 FLOAT_OP(op ## ttype, stype) \
2615 CALL_FROM_TB0(do_float_ ## op ## ttype ## _ ## stype); \
2616 DEBUG_FPU_STATE(); \
2617 FORCE_RET(); \
2620 FLOAT_ROUNDOP(round, l, d)
2621 FLOAT_ROUNDOP(round, l, s)
2622 FLOAT_ROUNDOP(round, w, d)
2623 FLOAT_ROUNDOP(round, w, s)
2625 FLOAT_ROUNDOP(trunc, l, d)
2626 FLOAT_ROUNDOP(trunc, l, s)
2627 FLOAT_ROUNDOP(trunc, w, d)
2628 FLOAT_ROUNDOP(trunc, w, s)
2630 FLOAT_ROUNDOP(ceil, l, d)
2631 FLOAT_ROUNDOP(ceil, l, s)
2632 FLOAT_ROUNDOP(ceil, w, d)
2633 FLOAT_ROUNDOP(ceil, w, s)
2635 FLOAT_ROUNDOP(floor, l, d)
2636 FLOAT_ROUNDOP(floor, l, s)
2637 FLOAT_ROUNDOP(floor, w, d)
2638 FLOAT_ROUNDOP(floor, w, s)
2639 #undef FLOAR_ROUNDOP
2641 FLOAT_OP(movf, d)
2643 if (!(env->fpu->fcr31 & PARAM1))
2644 DT2 = DT0;
2645 DEBUG_FPU_STATE();
2646 FORCE_RET();
2648 FLOAT_OP(movf, s)
2650 if (!(env->fpu->fcr31 & PARAM1))
2651 WT2 = WT0;
2652 DEBUG_FPU_STATE();
2653 FORCE_RET();
2655 FLOAT_OP(movf, ps)
2657 if (!(env->fpu->fcr31 & PARAM1)) {
2658 WT2 = WT0;
2659 WTH2 = WTH0;
2661 DEBUG_FPU_STATE();
2662 FORCE_RET();
2664 FLOAT_OP(movt, d)
2666 if (env->fpu->fcr31 & PARAM1)
2667 DT2 = DT0;
2668 DEBUG_FPU_STATE();
2669 FORCE_RET();
2671 FLOAT_OP(movt, s)
2673 if (env->fpu->fcr31 & PARAM1)
2674 WT2 = WT0;
2675 DEBUG_FPU_STATE();
2676 FORCE_RET();
2678 FLOAT_OP(movt, ps)
2680 if (env->fpu->fcr31 & PARAM1) {
2681 WT2 = WT0;
2682 WTH2 = WTH0;
2684 DEBUG_FPU_STATE();
2685 FORCE_RET();
2687 FLOAT_OP(movz, d)
2689 if (!T0)
2690 DT2 = DT0;
2691 DEBUG_FPU_STATE();
2692 FORCE_RET();
2694 FLOAT_OP(movz, s)
2696 if (!T0)
2697 WT2 = WT0;
2698 DEBUG_FPU_STATE();
2699 FORCE_RET();
2701 FLOAT_OP(movz, ps)
2703 if (!T0) {
2704 WT2 = WT0;
2705 WTH2 = WTH0;
2707 DEBUG_FPU_STATE();
2708 FORCE_RET();
2710 FLOAT_OP(movn, d)
2712 if (T0)
2713 DT2 = DT0;
2714 DEBUG_FPU_STATE();
2715 FORCE_RET();
2717 FLOAT_OP(movn, s)
2719 if (T0)
2720 WT2 = WT0;
2721 DEBUG_FPU_STATE();
2722 FORCE_RET();
2724 FLOAT_OP(movn, ps)
2726 if (T0) {
2727 WT2 = WT0;
2728 WTH2 = WTH0;
2730 DEBUG_FPU_STATE();
2731 FORCE_RET();
2734 /* operations calling helpers, for s, d and ps */
2735 #define FLOAT_HOP(name) \
2736 FLOAT_OP(name, d) \
2738 CALL_FROM_TB0(do_float_ ## name ## _d); \
2739 DEBUG_FPU_STATE(); \
2740 FORCE_RET(); \
2742 FLOAT_OP(name, s) \
2744 CALL_FROM_TB0(do_float_ ## name ## _s); \
2745 DEBUG_FPU_STATE(); \
2746 FORCE_RET(); \
2748 FLOAT_OP(name, ps) \
2750 CALL_FROM_TB0(do_float_ ## name ## _ps); \
2751 DEBUG_FPU_STATE(); \
2752 FORCE_RET(); \
2754 FLOAT_HOP(add)
2755 FLOAT_HOP(sub)
2756 FLOAT_HOP(mul)
2757 FLOAT_HOP(div)
2758 FLOAT_HOP(recip2)
2759 FLOAT_HOP(rsqrt2)
2760 FLOAT_HOP(rsqrt1)
2761 FLOAT_HOP(recip1)
2762 #undef FLOAT_HOP
2764 /* operations calling helpers, for s and d */
2765 #define FLOAT_HOP(name) \
2766 FLOAT_OP(name, d) \
2768 CALL_FROM_TB0(do_float_ ## name ## _d); \
2769 DEBUG_FPU_STATE(); \
2770 FORCE_RET(); \
2772 FLOAT_OP(name, s) \
2774 CALL_FROM_TB0(do_float_ ## name ## _s); \
2775 DEBUG_FPU_STATE(); \
2776 FORCE_RET(); \
2778 FLOAT_HOP(rsqrt)
2779 FLOAT_HOP(recip)
2780 #undef FLOAT_HOP
2782 /* operations calling helpers, for ps */
2783 #define FLOAT_HOP(name) \
2784 FLOAT_OP(name, ps) \
2786 CALL_FROM_TB0(do_float_ ## name ## _ps); \
2787 DEBUG_FPU_STATE(); \
2788 FORCE_RET(); \
2790 FLOAT_HOP(addr)
2791 FLOAT_HOP(mulr)
2792 #undef FLOAT_HOP
2794 /* ternary operations */
2795 #define FLOAT_TERNOP(name1, name2) \
2796 FLOAT_OP(name1 ## name2, d) \
2798 FDT0 = float64_ ## name1 (FDT0, FDT1, &env->fpu->fp_status); \
2799 FDT2 = float64_ ## name2 (FDT0, FDT2, &env->fpu->fp_status); \
2800 DEBUG_FPU_STATE(); \
2801 FORCE_RET(); \
2803 FLOAT_OP(name1 ## name2, s) \
2805 FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status); \
2806 FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status); \
2807 DEBUG_FPU_STATE(); \
2808 FORCE_RET(); \
2810 FLOAT_OP(name1 ## name2, ps) \
2812 FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status); \
2813 FSTH0 = float32_ ## name1 (FSTH0, FSTH1, &env->fpu->fp_status); \
2814 FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status); \
2815 FSTH2 = float32_ ## name2 (FSTH0, FSTH2, &env->fpu->fp_status); \
2816 DEBUG_FPU_STATE(); \
2817 FORCE_RET(); \
2819 FLOAT_TERNOP(mul, add)
2820 FLOAT_TERNOP(mul, sub)
2821 #undef FLOAT_TERNOP
2823 /* negated ternary operations */
2824 #define FLOAT_NTERNOP(name1, name2) \
2825 FLOAT_OP(n ## name1 ## name2, d) \
2827 FDT0 = float64_ ## name1 (FDT0, FDT1, &env->fpu->fp_status); \
2828 FDT2 = float64_ ## name2 (FDT0, FDT2, &env->fpu->fp_status); \
2829 FDT2 = float64_chs(FDT2); \
2830 DEBUG_FPU_STATE(); \
2831 FORCE_RET(); \
2833 FLOAT_OP(n ## name1 ## name2, s) \
2835 FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status); \
2836 FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status); \
2837 FST2 = float32_chs(FST2); \
2838 DEBUG_FPU_STATE(); \
2839 FORCE_RET(); \
2841 FLOAT_OP(n ## name1 ## name2, ps) \
2843 FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status); \
2844 FSTH0 = float32_ ## name1 (FSTH0, FSTH1, &env->fpu->fp_status); \
2845 FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status); \
2846 FSTH2 = float32_ ## name2 (FSTH0, FSTH2, &env->fpu->fp_status); \
2847 FST2 = float32_chs(FST2); \
2848 FSTH2 = float32_chs(FSTH2); \
2849 DEBUG_FPU_STATE(); \
2850 FORCE_RET(); \
2852 FLOAT_NTERNOP(mul, add)
2853 FLOAT_NTERNOP(mul, sub)
2854 #undef FLOAT_NTERNOP
2856 /* unary operations, modifying fp status */
2857 #define FLOAT_UNOP(name) \
2858 FLOAT_OP(name, d) \
2860 FDT2 = float64_ ## name(FDT0, &env->fpu->fp_status); \
2861 DEBUG_FPU_STATE(); \
2862 FORCE_RET(); \
2864 FLOAT_OP(name, s) \
2866 FST2 = float32_ ## name(FST0, &env->fpu->fp_status); \
2867 DEBUG_FPU_STATE(); \
2868 FORCE_RET(); \
2870 FLOAT_UNOP(sqrt)
2871 #undef FLOAT_UNOP
2873 /* unary operations, not modifying fp status */
2874 #define FLOAT_UNOP(name) \
2875 FLOAT_OP(name, d) \
2877 FDT2 = float64_ ## name(FDT0); \
2878 DEBUG_FPU_STATE(); \
2879 FORCE_RET(); \
2881 FLOAT_OP(name, s) \
2883 FST2 = float32_ ## name(FST0); \
2884 DEBUG_FPU_STATE(); \
2885 FORCE_RET(); \
2887 FLOAT_OP(name, ps) \
2889 FST2 = float32_ ## name(FST0); \
2890 FSTH2 = float32_ ## name(FSTH0); \
2891 DEBUG_FPU_STATE(); \
2892 FORCE_RET(); \
2894 FLOAT_UNOP(abs)
2895 FLOAT_UNOP(chs)
2896 #undef FLOAT_UNOP
2898 FLOAT_OP(mov, d)
2900 FDT2 = FDT0;
2901 DEBUG_FPU_STATE();
2902 FORCE_RET();
2904 FLOAT_OP(mov, s)
2906 FST2 = FST0;
2907 DEBUG_FPU_STATE();
2908 FORCE_RET();
2910 FLOAT_OP(mov, ps)
2912 FST2 = FST0;
2913 FSTH2 = FSTH0;
2914 DEBUG_FPU_STATE();
2915 FORCE_RET();
2917 FLOAT_OP(alnv, ps)
2919 switch (T0 & 0x7) {
2920 case 0:
2921 FST2 = FST0;
2922 FSTH2 = FSTH0;
2923 break;
2924 case 4:
2925 #ifdef TARGET_WORDS_BIGENDIAN
2926 FSTH2 = FST0;
2927 FST2 = FSTH1;
2928 #else
2929 FSTH2 = FST1;
2930 FST2 = FSTH0;
2931 #endif
2932 break;
2933 default: /* unpredictable */
2934 break;
2936 DEBUG_FPU_STATE();
2937 FORCE_RET();
2940 #ifdef CONFIG_SOFTFLOAT
2941 #define clear_invalid() do { \
2942 int flags = get_float_exception_flags(&env->fpu->fp_status); \
2943 flags &= ~float_flag_invalid; \
2944 set_float_exception_flags(flags, &env->fpu->fp_status); \
2945 } while(0)
2946 #else
2947 #define clear_invalid() do { } while(0)
2948 #endif
2950 extern void dump_fpu_s(CPUState *env);
2952 #define CMP_OP(fmt, op) \
2953 void OPPROTO op_cmp ## _ ## fmt ## _ ## op(void) \
2955 CALL_FROM_TB1(do_cmp ## _ ## fmt ## _ ## op, PARAM1); \
2956 DEBUG_FPU_STATE(); \
2957 FORCE_RET(); \
2959 void OPPROTO op_cmpabs ## _ ## fmt ## _ ## op(void) \
2961 CALL_FROM_TB1(do_cmpabs ## _ ## fmt ## _ ## op, PARAM1); \
2962 DEBUG_FPU_STATE(); \
2963 FORCE_RET(); \
2965 #define CMP_OPS(op) \
2966 CMP_OP(d, op) \
2967 CMP_OP(s, op) \
2968 CMP_OP(ps, op)
2970 CMP_OPS(f)
2971 CMP_OPS(un)
2972 CMP_OPS(eq)
2973 CMP_OPS(ueq)
2974 CMP_OPS(olt)
2975 CMP_OPS(ult)
2976 CMP_OPS(ole)
2977 CMP_OPS(ule)
2978 CMP_OPS(sf)
2979 CMP_OPS(ngle)
2980 CMP_OPS(seq)
2981 CMP_OPS(ngl)
2982 CMP_OPS(lt)
2983 CMP_OPS(nge)
2984 CMP_OPS(le)
2985 CMP_OPS(ngt)
2986 #undef CMP_OPS
2987 #undef CMP_OP
2989 void op_bc1f (void)
2991 T0 = !!(~GET_FP_COND(env->fpu) & (0x1 << PARAM1));
2992 DEBUG_FPU_STATE();
2993 FORCE_RET();
2995 void op_bc1any2f (void)
2997 T0 = !!(~GET_FP_COND(env->fpu) & (0x3 << PARAM1));
2998 DEBUG_FPU_STATE();
2999 FORCE_RET();
3001 void op_bc1any4f (void)
3003 T0 = !!(~GET_FP_COND(env->fpu) & (0xf << PARAM1));
3004 DEBUG_FPU_STATE();
3005 FORCE_RET();
3008 void op_bc1t (void)
3010 T0 = !!(GET_FP_COND(env->fpu) & (0x1 << PARAM1));
3011 DEBUG_FPU_STATE();
3012 FORCE_RET();
3014 void op_bc1any2t (void)
3016 T0 = !!(GET_FP_COND(env->fpu) & (0x3 << PARAM1));
3017 DEBUG_FPU_STATE();
3018 FORCE_RET();
3020 void op_bc1any4t (void)
3022 T0 = !!(GET_FP_COND(env->fpu) & (0xf << PARAM1));
3023 DEBUG_FPU_STATE();
3024 FORCE_RET();
3027 void op_tlbwi (void)
3029 CALL_FROM_TB0(env->tlb->do_tlbwi);
3030 FORCE_RET();
3033 void op_tlbwr (void)
3035 CALL_FROM_TB0(env->tlb->do_tlbwr);
3036 FORCE_RET();
3039 void op_tlbp (void)
3041 CALL_FROM_TB0(env->tlb->do_tlbp);
3042 FORCE_RET();
3045 void op_tlbr (void)
3047 CALL_FROM_TB0(env->tlb->do_tlbr);
3048 FORCE_RET();
3051 /* Specials */
3052 #if defined (CONFIG_USER_ONLY)
3053 void op_tls_value (void)
3055 T0 = env->tls_value;
3057 #endif
3059 void op_pmon (void)
3061 CALL_FROM_TB1(do_pmon, PARAM1);
3062 FORCE_RET();
3065 void op_di (void)
3067 T0 = env->CP0_Status;
3068 env->CP0_Status = T0 & ~(1 << CP0St_IE);
3069 CALL_FROM_TB1(cpu_mips_update_irq, env);
3070 FORCE_RET();
3073 void op_ei (void)
3075 T0 = env->CP0_Status;
3076 env->CP0_Status = T0 | (1 << CP0St_IE);
3077 CALL_FROM_TB1(cpu_mips_update_irq, env);
3078 FORCE_RET();
3081 void op_trap (void)
3083 if (T0) {
3084 CALL_FROM_TB1(do_raise_exception, EXCP_TRAP);
3086 FORCE_RET();
3089 void op_debug (void)
3091 CALL_FROM_TB1(do_raise_exception, EXCP_DEBUG);
3092 FORCE_RET();
3095 void debug_pre_eret (void);
3096 void debug_post_eret (void);
3097 void op_eret (void)
3099 if (loglevel & CPU_LOG_EXEC)
3100 CALL_FROM_TB0(debug_pre_eret);
3101 if (env->CP0_Status & (1 << CP0St_ERL)) {
3102 env->PC[env->current_tc] = env->CP0_ErrorEPC;
3103 env->CP0_Status &= ~(1 << CP0St_ERL);
3104 } else {
3105 env->PC[env->current_tc] = env->CP0_EPC;
3106 env->CP0_Status &= ~(1 << CP0St_EXL);
3108 CALL_FROM_TB1(compute_hflags, env);
3109 if (loglevel & CPU_LOG_EXEC)
3110 CALL_FROM_TB0(debug_post_eret);
3111 env->CP0_LLAddr = 1;
3112 FORCE_RET();
3115 void op_deret (void)
3117 if (loglevel & CPU_LOG_EXEC)
3118 CALL_FROM_TB0(debug_pre_eret);
3119 env->PC[env->current_tc] = env->CP0_DEPC;
3120 env->hflags &= MIPS_HFLAG_DM;
3121 CALL_FROM_TB1(compute_hflags, env);
3122 if (loglevel & CPU_LOG_EXEC)
3123 CALL_FROM_TB0(debug_post_eret);
3124 env->CP0_LLAddr = 1;
3125 FORCE_RET();
3128 void op_rdhwr_cpunum(void)
3130 if ((env->hflags & MIPS_HFLAG_CP0) ||
3131 (env->CP0_HWREna & (1 << 0)))
3132 T0 = env->CP0_EBase & 0x3ff;
3133 else
3134 CALL_FROM_TB1(do_raise_exception, EXCP_RI);
3135 FORCE_RET();
3138 void op_rdhwr_synci_step(void)
3140 if ((env->hflags & MIPS_HFLAG_CP0) ||
3141 (env->CP0_HWREna & (1 << 1)))
3142 T0 = env->SYNCI_Step;
3143 else
3144 CALL_FROM_TB1(do_raise_exception, EXCP_RI);
3145 FORCE_RET();
3148 void op_rdhwr_cc(void)
3150 if ((env->hflags & MIPS_HFLAG_CP0) ||
3151 (env->CP0_HWREna & (1 << 2)))
3152 T0 = env->CP0_Count;
3153 else
3154 CALL_FROM_TB1(do_raise_exception, EXCP_RI);
3155 FORCE_RET();
3158 void op_rdhwr_ccres(void)
3160 if ((env->hflags & MIPS_HFLAG_CP0) ||
3161 (env->CP0_HWREna & (1 << 3)))
3162 T0 = env->CCRes;
3163 else
3164 CALL_FROM_TB1(do_raise_exception, EXCP_RI);
3165 FORCE_RET();
3168 void op_save_state (void)
3170 env->hflags = PARAM1;
3171 FORCE_RET();
3174 void op_save_pc (void)
3176 env->PC[env->current_tc] = PARAM1;
3177 FORCE_RET();
3180 #if defined(TARGET_MIPS64)
3181 void op_save_pc64 (void)
3183 env->PC[env->current_tc] = ((uint64_t)PARAM1 << 32) | (uint32_t)PARAM2;
3184 FORCE_RET();
3186 #endif
3188 void op_interrupt_restart (void)
3190 if (!(env->CP0_Status & (1 << CP0St_EXL)) &&
3191 !(env->CP0_Status & (1 << CP0St_ERL)) &&
3192 !(env->hflags & MIPS_HFLAG_DM) &&
3193 (env->CP0_Status & (1 << CP0St_IE)) &&
3194 (env->CP0_Status & env->CP0_Cause & CP0Ca_IP_mask)) {
3195 env->CP0_Cause &= ~(0x1f << CP0Ca_EC);
3196 CALL_FROM_TB1(do_raise_exception, EXCP_EXT_INTERRUPT);
3198 FORCE_RET();
3201 void op_raise_exception (void)
3203 CALL_FROM_TB1(do_raise_exception, PARAM1);
3204 FORCE_RET();
3207 void op_raise_exception_err (void)
3209 CALL_FROM_TB2(do_raise_exception_err, PARAM1, PARAM2);
3210 FORCE_RET();
3213 void op_wait (void)
3215 env->halted = 1;
3216 CALL_FROM_TB1(do_raise_exception, EXCP_HLT);
3217 FORCE_RET();
3220 /* Bitfield operations. */
3221 void op_ext(void)
3223 unsigned int pos = PARAM1;
3224 unsigned int size = PARAM2;
3226 T0 = (int32_t)((T1 >> pos) & ((size < 32) ? ((1 << size) - 1) : ~0));
3227 FORCE_RET();
3230 void op_ins(void)
3232 unsigned int pos = PARAM1;
3233 unsigned int size = PARAM2;
3234 target_ulong mask = ((size < 32) ? ((1 << size) - 1) : ~0) << pos;
3236 T0 = (int32_t)((T0 & ~mask) | ((T1 << pos) & mask));
3237 FORCE_RET();
3240 void op_wsbh(void)
3242 T0 = (int32_t)(((T1 << 8) & ~0x00FF00FF) | ((T1 >> 8) & 0x00FF00FF));
3243 FORCE_RET();
3246 #if defined(TARGET_MIPS64)
3247 void op_dext(void)
3249 unsigned int pos = PARAM1;
3250 unsigned int size = PARAM2;
3252 T0 = (T1 >> pos) & ((size < 64) ? ((1ULL << size) - 1) : ~0ULL);
3253 FORCE_RET();
3256 void op_dins(void)
3258 unsigned int pos = PARAM1;
3259 unsigned int size = PARAM2;
3260 target_ulong mask = ((size < 64) ? ((1ULL << size) - 1) : ~0ULL) << pos;
3262 T0 = (T0 & ~mask) | ((T1 << pos) & mask);
3263 FORCE_RET();
3266 void op_dsbh(void)
3268 T0 = ((T1 << 8) & ~0x00FF00FF00FF00FFULL) | ((T1 >> 8) & 0x00FF00FF00FF00FFULL);
3269 FORCE_RET();
3272 void op_dshd(void)
3274 T1 = ((T1 << 16) & ~0x0000FFFF0000FFFFULL) | ((T1 >> 16) & 0x0000FFFF0000FFFFULL);
3275 T0 = (T1 << 32) | (T1 >> 32);
3276 FORCE_RET();
3278 #endif
3280 void op_seb(void)
3282 T0 = ((T1 & 0xFF) ^ 0x80) - 0x80;
3283 FORCE_RET();
3286 void op_seh(void)
3288 T0 = ((T1 & 0xFFFF) ^ 0x8000) - 0x8000;
3289 FORCE_RET();