Factor out the VGA vram mapping updating routine
[qemu-kvm/fedora.git] / target-mips / op.c
blobcece7f1f23ac4f75d3886d0f058aab92e4e1f797
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_dup_T0 (void)
252 T2 = T0;
253 FORCE_RET();
256 void op_load_HI (void)
258 T0 = env->HI[PARAM1][env->current_tc];
259 FORCE_RET();
262 void op_store_HI (void)
264 env->HI[PARAM1][env->current_tc] = T0;
265 FORCE_RET();
268 void op_load_LO (void)
270 T0 = env->LO[PARAM1][env->current_tc];
271 FORCE_RET();
274 void op_store_LO (void)
276 env->LO[PARAM1][env->current_tc] = T0;
277 FORCE_RET();
280 /* Load and store */
281 #define MEMSUFFIX _raw
282 #include "op_mem.c"
283 #undef MEMSUFFIX
284 #if !defined(CONFIG_USER_ONLY)
285 #define MEMSUFFIX _user
286 #include "op_mem.c"
287 #undef MEMSUFFIX
289 #define MEMSUFFIX _super
290 #include "op_mem.c"
291 #undef MEMSUFFIX
293 #define MEMSUFFIX _kernel
294 #include "op_mem.c"
295 #undef MEMSUFFIX
296 #endif
298 /* Addresses computation */
299 void op_addr_add (void)
301 /* For compatibility with 32-bit code, data reference in user mode
302 with Status_UX = 0 should be casted to 32-bit and sign extended.
303 See the MIPS64 PRA manual, section 4.10. */
304 #if defined(TARGET_MIPS64)
305 if (((env->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
306 !(env->CP0_Status & (1 << CP0St_UX)))
307 T0 = (int64_t)(int32_t)(T0 + T1);
308 else
309 #endif
310 T0 += T1;
311 FORCE_RET();
314 /* Arithmetic */
315 void op_add (void)
317 T0 = (int32_t)((int32_t)T0 + (int32_t)T1);
318 FORCE_RET();
321 void op_addo (void)
323 target_ulong tmp;
325 tmp = (int32_t)T0;
326 T0 = (int32_t)T0 + (int32_t)T1;
327 if (((tmp ^ T1 ^ (-1)) & (T0 ^ T1)) >> 31) {
328 /* operands of same sign, result different sign */
329 CALL_FROM_TB1(do_raise_exception, EXCP_OVERFLOW);
331 T0 = (int32_t)T0;
332 FORCE_RET();
335 void op_sub (void)
337 T0 = (int32_t)((int32_t)T0 - (int32_t)T1);
338 FORCE_RET();
341 void op_subo (void)
343 target_ulong tmp;
345 tmp = (int32_t)T0;
346 T0 = (int32_t)T0 - (int32_t)T1;
347 if (((tmp ^ T1) & (tmp ^ T0)) >> 31) {
348 /* operands of different sign, first operand and result different sign */
349 CALL_FROM_TB1(do_raise_exception, EXCP_OVERFLOW);
351 T0 = (int32_t)T0;
352 FORCE_RET();
355 void op_mul (void)
357 T0 = (int32_t)((int32_t)T0 * (int32_t)T1);
358 FORCE_RET();
361 #if HOST_LONG_BITS < 64
362 void op_div (void)
364 CALL_FROM_TB0(do_div);
365 FORCE_RET();
367 #else
368 void op_div (void)
370 if (T1 != 0) {
371 env->LO[0][env->current_tc] = (int32_t)((int64_t)(int32_t)T0 / (int32_t)T1);
372 env->HI[0][env->current_tc] = (int32_t)((int64_t)(int32_t)T0 % (int32_t)T1);
374 FORCE_RET();
376 #endif
378 void op_divu (void)
380 if (T1 != 0) {
381 env->LO[0][env->current_tc] = (int32_t)((uint32_t)T0 / (uint32_t)T1);
382 env->HI[0][env->current_tc] = (int32_t)((uint32_t)T0 % (uint32_t)T1);
384 FORCE_RET();
387 #if defined(TARGET_MIPS64)
388 /* Arithmetic */
389 void op_dadd (void)
391 T0 += T1;
392 FORCE_RET();
395 void op_daddo (void)
397 target_long tmp;
399 tmp = T0;
400 T0 += T1;
401 if (((tmp ^ T1 ^ (-1)) & (T0 ^ T1)) >> 63) {
402 /* operands of same sign, result different sign */
403 CALL_FROM_TB1(do_raise_exception, EXCP_OVERFLOW);
405 FORCE_RET();
408 void op_dsub (void)
410 T0 -= T1;
411 FORCE_RET();
414 void op_dsubo (void)
416 target_long tmp;
418 tmp = T0;
419 T0 = (int64_t)T0 - (int64_t)T1;
420 if (((tmp ^ T1) & (tmp ^ T0)) >> 63) {
421 /* operands of different sign, first operand and result different sign */
422 CALL_FROM_TB1(do_raise_exception, EXCP_OVERFLOW);
424 FORCE_RET();
427 void op_dmul (void)
429 T0 = (int64_t)T0 * (int64_t)T1;
430 FORCE_RET();
433 /* Those might call libgcc functions. */
434 void op_ddiv (void)
436 do_ddiv();
437 FORCE_RET();
440 #if TARGET_LONG_BITS > HOST_LONG_BITS
441 void op_ddivu (void)
443 do_ddivu();
444 FORCE_RET();
446 #else
447 void op_ddivu (void)
449 if (T1 != 0) {
450 env->LO[0][env->current_tc] = T0 / T1;
451 env->HI[0][env->current_tc] = T0 % T1;
453 FORCE_RET();
455 #endif
456 #endif /* TARGET_MIPS64 */
458 /* Logical */
459 void op_and (void)
461 T0 &= T1;
462 FORCE_RET();
465 void op_nor (void)
467 T0 = ~(T0 | T1);
468 FORCE_RET();
471 void op_or (void)
473 T0 |= T1;
474 FORCE_RET();
477 void op_xor (void)
479 T0 ^= T1;
480 FORCE_RET();
483 void op_sll (void)
485 T0 = (int32_t)((uint32_t)T0 << T1);
486 FORCE_RET();
489 void op_sra (void)
491 T0 = (int32_t)((int32_t)T0 >> T1);
492 FORCE_RET();
495 void op_srl (void)
497 T0 = (int32_t)((uint32_t)T0 >> T1);
498 FORCE_RET();
501 void op_rotr (void)
503 target_ulong tmp;
505 if (T1) {
506 tmp = (int32_t)((uint32_t)T0 << (0x20 - T1));
507 T0 = (int32_t)((uint32_t)T0 >> T1) | tmp;
509 FORCE_RET();
512 void op_sllv (void)
514 T0 = (int32_t)((uint32_t)T1 << ((uint32_t)T0 & 0x1F));
515 FORCE_RET();
518 void op_srav (void)
520 T0 = (int32_t)((int32_t)T1 >> (T0 & 0x1F));
521 FORCE_RET();
524 void op_srlv (void)
526 T0 = (int32_t)((uint32_t)T1 >> (T0 & 0x1F));
527 FORCE_RET();
530 void op_rotrv (void)
532 target_ulong tmp;
534 T0 &= 0x1F;
535 if (T0) {
536 tmp = (int32_t)((uint32_t)T1 << (0x20 - T0));
537 T0 = (int32_t)((uint32_t)T1 >> T0) | tmp;
538 } else
539 T0 = T1;
540 FORCE_RET();
543 void op_clo (void)
545 T0 = clo32(T0);
546 FORCE_RET();
549 void op_clz (void)
551 T0 = clz32(T0);
552 FORCE_RET();
555 #if defined(TARGET_MIPS64)
557 #if TARGET_LONG_BITS > HOST_LONG_BITS
558 /* Those might call libgcc functions. */
559 void op_dsll (void)
561 CALL_FROM_TB0(do_dsll);
562 FORCE_RET();
565 void op_dsll32 (void)
567 CALL_FROM_TB0(do_dsll32);
568 FORCE_RET();
571 void op_dsra (void)
573 CALL_FROM_TB0(do_dsra);
574 FORCE_RET();
577 void op_dsra32 (void)
579 CALL_FROM_TB0(do_dsra32);
580 FORCE_RET();
583 void op_dsrl (void)
585 CALL_FROM_TB0(do_dsrl);
586 FORCE_RET();
589 void op_dsrl32 (void)
591 CALL_FROM_TB0(do_dsrl32);
592 FORCE_RET();
595 void op_drotr (void)
597 CALL_FROM_TB0(do_drotr);
598 FORCE_RET();
601 void op_drotr32 (void)
603 CALL_FROM_TB0(do_drotr32);
604 FORCE_RET();
607 void op_dsllv (void)
609 CALL_FROM_TB0(do_dsllv);
610 FORCE_RET();
613 void op_dsrav (void)
615 CALL_FROM_TB0(do_dsrav);
616 FORCE_RET();
619 void op_dsrlv (void)
621 CALL_FROM_TB0(do_dsrlv);
622 FORCE_RET();
625 void op_drotrv (void)
627 CALL_FROM_TB0(do_drotrv);
628 FORCE_RET();
631 void op_dclo (void)
633 CALL_FROM_TB0(do_dclo);
634 FORCE_RET();
637 void op_dclz (void)
639 CALL_FROM_TB0(do_dclz);
640 FORCE_RET();
643 #else /* TARGET_LONG_BITS > HOST_LONG_BITS */
645 void op_dsll (void)
647 T0 = T0 << T1;
648 FORCE_RET();
651 void op_dsll32 (void)
653 T0 = T0 << (T1 + 32);
654 FORCE_RET();
657 void op_dsra (void)
659 T0 = (int64_t)T0 >> T1;
660 FORCE_RET();
663 void op_dsra32 (void)
665 T0 = (int64_t)T0 >> (T1 + 32);
666 FORCE_RET();
669 void op_dsrl (void)
671 T0 = T0 >> T1;
672 FORCE_RET();
675 void op_dsrl32 (void)
677 T0 = T0 >> (T1 + 32);
678 FORCE_RET();
681 void op_drotr (void)
683 target_ulong tmp;
685 if (T1) {
686 tmp = T0 << (0x40 - T1);
687 T0 = (T0 >> T1) | tmp;
689 FORCE_RET();
692 void op_drotr32 (void)
694 target_ulong tmp;
696 tmp = T0 << (0x40 - (32 + T1));
697 T0 = (T0 >> (32 + T1)) | tmp;
698 FORCE_RET();
701 void op_dsllv (void)
703 T0 = T1 << (T0 & 0x3F);
704 FORCE_RET();
707 void op_dsrav (void)
709 T0 = (int64_t)T1 >> (T0 & 0x3F);
710 FORCE_RET();
713 void op_dsrlv (void)
715 T0 = T1 >> (T0 & 0x3F);
716 FORCE_RET();
719 void op_drotrv (void)
721 target_ulong tmp;
723 T0 &= 0x3F;
724 if (T0) {
725 tmp = T1 << (0x40 - T0);
726 T0 = (T1 >> T0) | tmp;
727 } else
728 T0 = T1;
729 FORCE_RET();
732 void op_dclo (void)
734 T0 = clo64(T0);
735 FORCE_RET();
738 void op_dclz (void)
740 T0 = clz64(T0);
741 FORCE_RET();
743 #endif /* TARGET_LONG_BITS > HOST_LONG_BITS */
744 #endif /* TARGET_MIPS64 */
746 /* 64 bits arithmetic */
747 #if TARGET_LONG_BITS > HOST_LONG_BITS
748 void op_mult (void)
750 CALL_FROM_TB0(do_mult);
751 FORCE_RET();
754 void op_multu (void)
756 CALL_FROM_TB0(do_multu);
757 FORCE_RET();
760 void op_madd (void)
762 CALL_FROM_TB0(do_madd);
763 FORCE_RET();
766 void op_maddu (void)
768 CALL_FROM_TB0(do_maddu);
769 FORCE_RET();
772 void op_msub (void)
774 CALL_FROM_TB0(do_msub);
775 FORCE_RET();
778 void op_msubu (void)
780 CALL_FROM_TB0(do_msubu);
781 FORCE_RET();
784 /* Multiplication variants of the vr54xx. */
785 void op_muls (void)
787 CALL_FROM_TB0(do_muls);
788 FORCE_RET();
791 void op_mulsu (void)
793 CALL_FROM_TB0(do_mulsu);
794 FORCE_RET();
797 void op_macc (void)
799 CALL_FROM_TB0(do_macc);
800 FORCE_RET();
803 void op_macchi (void)
805 CALL_FROM_TB0(do_macchi);
806 FORCE_RET();
809 void op_maccu (void)
811 CALL_FROM_TB0(do_maccu);
812 FORCE_RET();
814 void op_macchiu (void)
816 CALL_FROM_TB0(do_macchiu);
817 FORCE_RET();
820 void op_msac (void)
822 CALL_FROM_TB0(do_msac);
823 FORCE_RET();
826 void op_msachi (void)
828 CALL_FROM_TB0(do_msachi);
829 FORCE_RET();
832 void op_msacu (void)
834 CALL_FROM_TB0(do_msacu);
835 FORCE_RET();
838 void op_msachiu (void)
840 CALL_FROM_TB0(do_msachiu);
841 FORCE_RET();
844 void op_mulhi (void)
846 CALL_FROM_TB0(do_mulhi);
847 FORCE_RET();
850 void op_mulhiu (void)
852 CALL_FROM_TB0(do_mulhiu);
853 FORCE_RET();
856 void op_mulshi (void)
858 CALL_FROM_TB0(do_mulshi);
859 FORCE_RET();
862 void op_mulshiu (void)
864 CALL_FROM_TB0(do_mulshiu);
865 FORCE_RET();
868 #else /* TARGET_LONG_BITS > HOST_LONG_BITS */
870 static always_inline uint64_t get_HILO (void)
872 return ((uint64_t)env->HI[0][env->current_tc] << 32) |
873 ((uint64_t)(uint32_t)env->LO[0][env->current_tc]);
876 static always_inline void set_HILO (uint64_t HILO)
878 env->LO[0][env->current_tc] = (int32_t)(HILO & 0xFFFFFFFF);
879 env->HI[0][env->current_tc] = (int32_t)(HILO >> 32);
882 static always_inline void set_HIT0_LO (uint64_t HILO)
884 env->LO[0][env->current_tc] = (int32_t)(HILO & 0xFFFFFFFF);
885 T0 = env->HI[0][env->current_tc] = (int32_t)(HILO >> 32);
888 static always_inline void set_HI_LOT0 (uint64_t HILO)
890 T0 = env->LO[0][env->current_tc] = (int32_t)(HILO & 0xFFFFFFFF);
891 env->HI[0][env->current_tc] = (int32_t)(HILO >> 32);
894 void op_mult (void)
896 set_HILO((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
897 FORCE_RET();
900 void op_multu (void)
902 set_HILO((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
903 FORCE_RET();
906 void op_madd (void)
908 int64_t tmp;
910 tmp = ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
911 set_HILO((int64_t)get_HILO() + tmp);
912 FORCE_RET();
915 void op_maddu (void)
917 uint64_t tmp;
919 tmp = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
920 set_HILO(get_HILO() + tmp);
921 FORCE_RET();
924 void op_msub (void)
926 int64_t tmp;
928 tmp = ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
929 set_HILO((int64_t)get_HILO() - tmp);
930 FORCE_RET();
933 void op_msubu (void)
935 uint64_t tmp;
937 tmp = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
938 set_HILO(get_HILO() - tmp);
939 FORCE_RET();
942 /* Multiplication variants of the vr54xx. */
943 void op_muls (void)
945 set_HI_LOT0(0 - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
946 FORCE_RET();
949 void op_mulsu (void)
951 set_HI_LOT0(0 - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
952 FORCE_RET();
955 void op_macc (void)
957 set_HI_LOT0(get_HILO() + ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
958 FORCE_RET();
961 void op_macchi (void)
963 set_HIT0_LO(get_HILO() + ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
964 FORCE_RET();
967 void op_maccu (void)
969 set_HI_LOT0(get_HILO() + ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
970 FORCE_RET();
973 void op_macchiu (void)
975 set_HIT0_LO(get_HILO() + ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
976 FORCE_RET();
979 void op_msac (void)
981 set_HI_LOT0(get_HILO() - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
982 FORCE_RET();
985 void op_msachi (void)
987 set_HIT0_LO(get_HILO() - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
988 FORCE_RET();
991 void op_msacu (void)
993 set_HI_LOT0(get_HILO() - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
994 FORCE_RET();
997 void op_msachiu (void)
999 set_HIT0_LO(get_HILO() - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
1000 FORCE_RET();
1003 void op_mulhi (void)
1005 set_HIT0_LO((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
1006 FORCE_RET();
1009 void op_mulhiu (void)
1011 set_HIT0_LO((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
1012 FORCE_RET();
1015 void op_mulshi (void)
1017 set_HIT0_LO(0 - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
1018 FORCE_RET();
1021 void op_mulshiu (void)
1023 set_HIT0_LO(0 - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
1024 FORCE_RET();
1027 #endif /* TARGET_LONG_BITS > HOST_LONG_BITS */
1029 #if defined(TARGET_MIPS64)
1030 void op_dmult (void)
1032 CALL_FROM_TB4(muls64, &(env->LO[0][env->current_tc]), &(env->HI[0][env->current_tc]), T0, T1);
1033 FORCE_RET();
1036 void op_dmultu (void)
1038 CALL_FROM_TB4(mulu64, &(env->LO[0][env->current_tc]), &(env->HI[0][env->current_tc]), T0, T1);
1039 FORCE_RET();
1041 #endif
1043 /* Conditional moves */
1044 void op_movn (void)
1046 if (T1 != 0)
1047 env->gpr[PARAM1][env->current_tc] = T0;
1048 FORCE_RET();
1051 void op_movz (void)
1053 if (T1 == 0)
1054 env->gpr[PARAM1][env->current_tc] = T0;
1055 FORCE_RET();
1058 void op_movf (void)
1060 if (!(env->fpu->fcr31 & PARAM1))
1061 T0 = T1;
1062 FORCE_RET();
1065 void op_movt (void)
1067 if (env->fpu->fcr31 & PARAM1)
1068 T0 = T1;
1069 FORCE_RET();
1072 /* Tests */
1073 #define OP_COND(name, cond) \
1074 void glue(op_, name) (void) \
1076 if (cond) { \
1077 T0 = 1; \
1078 } else { \
1079 T0 = 0; \
1081 FORCE_RET(); \
1084 OP_COND(eq, T0 == T1);
1085 OP_COND(ne, T0 != T1);
1086 OP_COND(ge, (target_long)T0 >= (target_long)T1);
1087 OP_COND(geu, T0 >= T1);
1088 OP_COND(lt, (target_long)T0 < (target_long)T1);
1089 OP_COND(ltu, T0 < T1);
1090 OP_COND(gez, (target_long)T0 >= 0);
1091 OP_COND(gtz, (target_long)T0 > 0);
1092 OP_COND(lez, (target_long)T0 <= 0);
1093 OP_COND(ltz, (target_long)T0 < 0);
1095 /* Branches */
1096 /* Branch to register */
1097 void op_save_breg_target (void)
1099 env->btarget = T2;
1100 FORCE_RET();
1103 void op_restore_breg_target (void)
1105 T2 = env->btarget;
1106 FORCE_RET();
1109 void op_breg (void)
1111 env->PC[env->current_tc] = T2;
1112 FORCE_RET();
1115 void op_save_btarget (void)
1117 env->btarget = PARAM1;
1118 FORCE_RET();
1121 #if defined(TARGET_MIPS64)
1122 void op_save_btarget64 (void)
1124 env->btarget = ((uint64_t)PARAM1 << 32) | (uint32_t)PARAM2;
1125 FORCE_RET();
1127 #endif
1129 /* Conditional branch */
1130 void op_set_bcond (void)
1132 T2 = T0;
1133 FORCE_RET();
1136 void op_save_bcond (void)
1138 env->bcond = T2;
1139 FORCE_RET();
1142 void op_restore_bcond (void)
1144 T2 = env->bcond;
1145 FORCE_RET();
1148 void op_jnz_T2 (void)
1150 if (T2)
1151 GOTO_LABEL_PARAM(1);
1152 FORCE_RET();
1155 /* CP0 functions */
1156 void op_mfc0_index (void)
1158 T0 = env->CP0_Index;
1159 FORCE_RET();
1162 void op_mfc0_mvpcontrol (void)
1164 T0 = env->mvp->CP0_MVPControl;
1165 FORCE_RET();
1168 void op_mfc0_mvpconf0 (void)
1170 T0 = env->mvp->CP0_MVPConf0;
1171 FORCE_RET();
1174 void op_mfc0_mvpconf1 (void)
1176 T0 = env->mvp->CP0_MVPConf1;
1177 FORCE_RET();
1180 void op_mfc0_random (void)
1182 CALL_FROM_TB0(do_mfc0_random);
1183 FORCE_RET();
1186 void op_mfc0_vpecontrol (void)
1188 T0 = env->CP0_VPEControl;
1189 FORCE_RET();
1192 void op_mfc0_vpeconf0 (void)
1194 T0 = env->CP0_VPEConf0;
1195 FORCE_RET();
1198 void op_mfc0_vpeconf1 (void)
1200 T0 = env->CP0_VPEConf1;
1201 FORCE_RET();
1204 void op_mfc0_yqmask (void)
1206 T0 = env->CP0_YQMask;
1207 FORCE_RET();
1210 void op_mfc0_vpeschedule (void)
1212 T0 = env->CP0_VPESchedule;
1213 FORCE_RET();
1216 void op_mfc0_vpeschefback (void)
1218 T0 = env->CP0_VPEScheFBack;
1219 FORCE_RET();
1222 void op_mfc0_vpeopt (void)
1224 T0 = env->CP0_VPEOpt;
1225 FORCE_RET();
1228 void op_mfc0_entrylo0 (void)
1230 T0 = (int32_t)env->CP0_EntryLo0;
1231 FORCE_RET();
1234 void op_mfc0_tcstatus (void)
1236 T0 = env->CP0_TCStatus[env->current_tc];
1237 FORCE_RET();
1240 void op_mftc0_tcstatus(void)
1242 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1244 T0 = env->CP0_TCStatus[other_tc];
1245 FORCE_RET();
1248 void op_mfc0_tcbind (void)
1250 T0 = env->CP0_TCBind[env->current_tc];
1251 FORCE_RET();
1254 void op_mftc0_tcbind(void)
1256 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1258 T0 = env->CP0_TCBind[other_tc];
1259 FORCE_RET();
1262 void op_mfc0_tcrestart (void)
1264 T0 = env->PC[env->current_tc];
1265 FORCE_RET();
1268 void op_mftc0_tcrestart(void)
1270 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1272 T0 = env->PC[other_tc];
1273 FORCE_RET();
1276 void op_mfc0_tchalt (void)
1278 T0 = env->CP0_TCHalt[env->current_tc];
1279 FORCE_RET();
1282 void op_mftc0_tchalt(void)
1284 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1286 T0 = env->CP0_TCHalt[other_tc];
1287 FORCE_RET();
1290 void op_mfc0_tccontext (void)
1292 T0 = env->CP0_TCContext[env->current_tc];
1293 FORCE_RET();
1296 void op_mftc0_tccontext(void)
1298 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1300 T0 = env->CP0_TCContext[other_tc];
1301 FORCE_RET();
1304 void op_mfc0_tcschedule (void)
1306 T0 = env->CP0_TCSchedule[env->current_tc];
1307 FORCE_RET();
1310 void op_mftc0_tcschedule(void)
1312 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1314 T0 = env->CP0_TCSchedule[other_tc];
1315 FORCE_RET();
1318 void op_mfc0_tcschefback (void)
1320 T0 = env->CP0_TCScheFBack[env->current_tc];
1321 FORCE_RET();
1324 void op_mftc0_tcschefback(void)
1326 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1328 T0 = env->CP0_TCScheFBack[other_tc];
1329 FORCE_RET();
1332 void op_mfc0_entrylo1 (void)
1334 T0 = (int32_t)env->CP0_EntryLo1;
1335 FORCE_RET();
1338 void op_mfc0_context (void)
1340 T0 = (int32_t)env->CP0_Context;
1341 FORCE_RET();
1344 void op_mfc0_pagemask (void)
1346 T0 = env->CP0_PageMask;
1347 FORCE_RET();
1350 void op_mfc0_pagegrain (void)
1352 T0 = env->CP0_PageGrain;
1353 FORCE_RET();
1356 void op_mfc0_wired (void)
1358 T0 = env->CP0_Wired;
1359 FORCE_RET();
1362 void op_mfc0_srsconf0 (void)
1364 T0 = env->CP0_SRSConf0;
1365 FORCE_RET();
1368 void op_mfc0_srsconf1 (void)
1370 T0 = env->CP0_SRSConf1;
1371 FORCE_RET();
1374 void op_mfc0_srsconf2 (void)
1376 T0 = env->CP0_SRSConf2;
1377 FORCE_RET();
1380 void op_mfc0_srsconf3 (void)
1382 T0 = env->CP0_SRSConf3;
1383 FORCE_RET();
1386 void op_mfc0_srsconf4 (void)
1388 T0 = env->CP0_SRSConf4;
1389 FORCE_RET();
1392 void op_mfc0_hwrena (void)
1394 T0 = env->CP0_HWREna;
1395 FORCE_RET();
1398 void op_mfc0_badvaddr (void)
1400 T0 = (int32_t)env->CP0_BadVAddr;
1401 FORCE_RET();
1404 void op_mfc0_count (void)
1406 CALL_FROM_TB0(do_mfc0_count);
1407 FORCE_RET();
1410 void op_mfc0_entryhi (void)
1412 T0 = (int32_t)env->CP0_EntryHi;
1413 FORCE_RET();
1416 void op_mftc0_entryhi(void)
1418 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1420 T0 = (env->CP0_EntryHi & ~0xff) | (env->CP0_TCStatus[other_tc] & 0xff);
1421 FORCE_RET();
1424 void op_mfc0_compare (void)
1426 T0 = env->CP0_Compare;
1427 FORCE_RET();
1430 void op_mfc0_status (void)
1432 T0 = env->CP0_Status;
1433 FORCE_RET();
1436 void op_mftc0_status(void)
1438 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1439 uint32_t tcstatus = env->CP0_TCStatus[other_tc];
1441 T0 = env->CP0_Status & ~0xf1000018;
1442 T0 |= tcstatus & (0xf << CP0TCSt_TCU0);
1443 T0 |= (tcstatus & (1 << CP0TCSt_TMX)) >> (CP0TCSt_TMX - CP0St_MX);
1444 T0 |= (tcstatus & (0x3 << CP0TCSt_TKSU)) >> (CP0TCSt_TKSU - CP0St_KSU);
1445 FORCE_RET();
1448 void op_mfc0_intctl (void)
1450 T0 = env->CP0_IntCtl;
1451 FORCE_RET();
1454 void op_mfc0_srsctl (void)
1456 T0 = env->CP0_SRSCtl;
1457 FORCE_RET();
1460 void op_mfc0_srsmap (void)
1462 T0 = env->CP0_SRSMap;
1463 FORCE_RET();
1466 void op_mfc0_cause (void)
1468 T0 = env->CP0_Cause;
1469 FORCE_RET();
1472 void op_mfc0_epc (void)
1474 T0 = (int32_t)env->CP0_EPC;
1475 FORCE_RET();
1478 void op_mfc0_prid (void)
1480 T0 = env->CP0_PRid;
1481 FORCE_RET();
1484 void op_mfc0_ebase (void)
1486 T0 = env->CP0_EBase;
1487 FORCE_RET();
1490 void op_mfc0_config0 (void)
1492 T0 = env->CP0_Config0;
1493 FORCE_RET();
1496 void op_mfc0_config1 (void)
1498 T0 = env->CP0_Config1;
1499 FORCE_RET();
1502 void op_mfc0_config2 (void)
1504 T0 = env->CP0_Config2;
1505 FORCE_RET();
1508 void op_mfc0_config3 (void)
1510 T0 = env->CP0_Config3;
1511 FORCE_RET();
1514 void op_mfc0_config6 (void)
1516 T0 = env->CP0_Config6;
1517 FORCE_RET();
1520 void op_mfc0_config7 (void)
1522 T0 = env->CP0_Config7;
1523 FORCE_RET();
1526 void op_mfc0_lladdr (void)
1528 T0 = (int32_t)env->CP0_LLAddr >> 4;
1529 FORCE_RET();
1532 void op_mfc0_watchlo (void)
1534 T0 = (int32_t)env->CP0_WatchLo[PARAM1];
1535 FORCE_RET();
1538 void op_mfc0_watchhi (void)
1540 T0 = env->CP0_WatchHi[PARAM1];
1541 FORCE_RET();
1544 void op_mfc0_xcontext (void)
1546 T0 = (int32_t)env->CP0_XContext;
1547 FORCE_RET();
1550 void op_mfc0_framemask (void)
1552 T0 = env->CP0_Framemask;
1553 FORCE_RET();
1556 void op_mfc0_debug (void)
1558 T0 = env->CP0_Debug;
1559 if (env->hflags & MIPS_HFLAG_DM)
1560 T0 |= 1 << CP0DB_DM;
1561 FORCE_RET();
1564 void op_mftc0_debug(void)
1566 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1568 /* XXX: Might be wrong, check with EJTAG spec. */
1569 T0 = (env->CP0_Debug & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) |
1570 (env->CP0_Debug_tcstatus[other_tc] &
1571 ((1 << CP0DB_SSt) | (1 << CP0DB_Halt)));
1572 FORCE_RET();
1575 void op_mfc0_depc (void)
1577 T0 = (int32_t)env->CP0_DEPC;
1578 FORCE_RET();
1581 void op_mfc0_performance0 (void)
1583 T0 = env->CP0_Performance0;
1584 FORCE_RET();
1587 void op_mfc0_taglo (void)
1589 T0 = env->CP0_TagLo;
1590 FORCE_RET();
1593 void op_mfc0_datalo (void)
1595 T0 = env->CP0_DataLo;
1596 FORCE_RET();
1599 void op_mfc0_taghi (void)
1601 T0 = env->CP0_TagHi;
1602 FORCE_RET();
1605 void op_mfc0_datahi (void)
1607 T0 = env->CP0_DataHi;
1608 FORCE_RET();
1611 void op_mfc0_errorepc (void)
1613 T0 = (int32_t)env->CP0_ErrorEPC;
1614 FORCE_RET();
1617 void op_mfc0_desave (void)
1619 T0 = env->CP0_DESAVE;
1620 FORCE_RET();
1623 void op_mtc0_index (void)
1625 int num = 1;
1626 unsigned int tmp = env->tlb->nb_tlb;
1628 do {
1629 tmp >>= 1;
1630 num <<= 1;
1631 } while (tmp);
1632 env->CP0_Index = (env->CP0_Index & 0x80000000) | (T0 & (num - 1));
1633 FORCE_RET();
1636 void op_mtc0_mvpcontrol (void)
1638 uint32_t mask = 0;
1639 uint32_t newval;
1641 if (env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP))
1642 mask |= (1 << CP0MVPCo_CPA) | (1 << CP0MVPCo_VPC) |
1643 (1 << CP0MVPCo_EVP);
1644 if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
1645 mask |= (1 << CP0MVPCo_STLB);
1646 newval = (env->mvp->CP0_MVPControl & ~mask) | (T0 & mask);
1648 // TODO: Enable/disable shared TLB, enable/disable VPEs.
1650 env->mvp->CP0_MVPControl = newval;
1651 FORCE_RET();
1654 void op_mtc0_vpecontrol (void)
1656 uint32_t mask;
1657 uint32_t newval;
1659 mask = (1 << CP0VPECo_YSI) | (1 << CP0VPECo_GSI) |
1660 (1 << CP0VPECo_TE) | (0xff << CP0VPECo_TargTC);
1661 newval = (env->CP0_VPEControl & ~mask) | (T0 & mask);
1663 /* Yield scheduler intercept not implemented. */
1664 /* Gating storage scheduler intercept not implemented. */
1666 // TODO: Enable/disable TCs.
1668 env->CP0_VPEControl = newval;
1669 FORCE_RET();
1672 void op_mtc0_vpeconf0 (void)
1674 uint32_t mask = 0;
1675 uint32_t newval;
1677 if (env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) {
1678 if (env->CP0_VPEConf0 & (1 << CP0VPEC0_VPA))
1679 mask |= (0xff << CP0VPEC0_XTC);
1680 mask |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
1682 newval = (env->CP0_VPEConf0 & ~mask) | (T0 & mask);
1684 // TODO: TC exclusive handling due to ERL/EXL.
1686 env->CP0_VPEConf0 = newval;
1687 FORCE_RET();
1690 void op_mtc0_vpeconf1 (void)
1692 uint32_t mask = 0;
1693 uint32_t newval;
1695 if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
1696 mask |= (0xff << CP0VPEC1_NCX) | (0xff << CP0VPEC1_NCP2) |
1697 (0xff << CP0VPEC1_NCP1);
1698 newval = (env->CP0_VPEConf1 & ~mask) | (T0 & mask);
1700 /* UDI not implemented. */
1701 /* CP2 not implemented. */
1703 // TODO: Handle FPU (CP1) binding.
1705 env->CP0_VPEConf1 = newval;
1706 FORCE_RET();
1709 void op_mtc0_yqmask (void)
1711 /* Yield qualifier inputs not implemented. */
1712 env->CP0_YQMask = 0x00000000;
1713 FORCE_RET();
1716 void op_mtc0_vpeschedule (void)
1718 env->CP0_VPESchedule = T0;
1719 FORCE_RET();
1722 void op_mtc0_vpeschefback (void)
1724 env->CP0_VPEScheFBack = T0;
1725 FORCE_RET();
1728 void op_mtc0_vpeopt (void)
1730 env->CP0_VPEOpt = T0 & 0x0000ffff;
1731 FORCE_RET();
1734 void op_mtc0_entrylo0 (void)
1736 /* Large physaddr (PABITS) not implemented */
1737 /* 1k pages not implemented */
1738 env->CP0_EntryLo0 = T0 & 0x3FFFFFFF;
1739 FORCE_RET();
1742 void op_mtc0_tcstatus (void)
1744 uint32_t mask = env->CP0_TCStatus_rw_bitmask;
1745 uint32_t newval;
1747 newval = (env->CP0_TCStatus[env->current_tc] & ~mask) | (T0 & mask);
1749 // TODO: Sync with CP0_Status.
1751 env->CP0_TCStatus[env->current_tc] = newval;
1752 FORCE_RET();
1755 void op_mttc0_tcstatus (void)
1757 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1759 // TODO: Sync with CP0_Status.
1761 env->CP0_TCStatus[other_tc] = T0;
1762 FORCE_RET();
1765 void op_mtc0_tcbind (void)
1767 uint32_t mask = (1 << CP0TCBd_TBE);
1768 uint32_t newval;
1770 if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
1771 mask |= (1 << CP0TCBd_CurVPE);
1772 newval = (env->CP0_TCBind[env->current_tc] & ~mask) | (T0 & mask);
1773 env->CP0_TCBind[env->current_tc] = newval;
1774 FORCE_RET();
1777 void op_mttc0_tcbind (void)
1779 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1780 uint32_t mask = (1 << CP0TCBd_TBE);
1781 uint32_t newval;
1783 if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
1784 mask |= (1 << CP0TCBd_CurVPE);
1785 newval = (env->CP0_TCBind[other_tc] & ~mask) | (T0 & mask);
1786 env->CP0_TCBind[other_tc] = newval;
1787 FORCE_RET();
1790 void op_mtc0_tcrestart (void)
1792 env->PC[env->current_tc] = T0;
1793 env->CP0_TCStatus[env->current_tc] &= ~(1 << CP0TCSt_TDS);
1794 env->CP0_LLAddr = 0ULL;
1795 /* MIPS16 not implemented. */
1796 FORCE_RET();
1799 void op_mttc0_tcrestart (void)
1801 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1803 env->PC[other_tc] = T0;
1804 env->CP0_TCStatus[other_tc] &= ~(1 << CP0TCSt_TDS);
1805 env->CP0_LLAddr = 0ULL;
1806 /* MIPS16 not implemented. */
1807 FORCE_RET();
1810 void op_mtc0_tchalt (void)
1812 env->CP0_TCHalt[env->current_tc] = T0 & 0x1;
1814 // TODO: Halt TC / Restart (if allocated+active) TC.
1816 FORCE_RET();
1819 void op_mttc0_tchalt (void)
1821 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1823 // TODO: Halt TC / Restart (if allocated+active) TC.
1825 env->CP0_TCHalt[other_tc] = T0;
1826 FORCE_RET();
1829 void op_mtc0_tccontext (void)
1831 env->CP0_TCContext[env->current_tc] = T0;
1832 FORCE_RET();
1835 void op_mttc0_tccontext (void)
1837 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1839 env->CP0_TCContext[other_tc] = T0;
1840 FORCE_RET();
1843 void op_mtc0_tcschedule (void)
1845 env->CP0_TCSchedule[env->current_tc] = T0;
1846 FORCE_RET();
1849 void op_mttc0_tcschedule (void)
1851 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1853 env->CP0_TCSchedule[other_tc] = T0;
1854 FORCE_RET();
1857 void op_mtc0_tcschefback (void)
1859 env->CP0_TCScheFBack[env->current_tc] = T0;
1860 FORCE_RET();
1863 void op_mttc0_tcschefback (void)
1865 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1867 env->CP0_TCScheFBack[other_tc] = T0;
1868 FORCE_RET();
1871 void op_mtc0_entrylo1 (void)
1873 /* Large physaddr (PABITS) not implemented */
1874 /* 1k pages not implemented */
1875 env->CP0_EntryLo1 = T0 & 0x3FFFFFFF;
1876 FORCE_RET();
1879 void op_mtc0_context (void)
1881 env->CP0_Context = (env->CP0_Context & 0x007FFFFF) | (T0 & ~0x007FFFFF);
1882 FORCE_RET();
1885 void op_mtc0_pagemask (void)
1887 /* 1k pages not implemented */
1888 env->CP0_PageMask = T0 & (0x1FFFFFFF & (TARGET_PAGE_MASK << 1));
1889 FORCE_RET();
1892 void op_mtc0_pagegrain (void)
1894 /* SmartMIPS not implemented */
1895 /* Large physaddr (PABITS) not implemented */
1896 /* 1k pages not implemented */
1897 env->CP0_PageGrain = 0;
1898 FORCE_RET();
1901 void op_mtc0_wired (void)
1903 env->CP0_Wired = T0 % env->tlb->nb_tlb;
1904 FORCE_RET();
1907 void op_mtc0_srsconf0 (void)
1909 env->CP0_SRSConf0 |= T0 & env->CP0_SRSConf0_rw_bitmask;
1910 FORCE_RET();
1913 void op_mtc0_srsconf1 (void)
1915 env->CP0_SRSConf1 |= T0 & env->CP0_SRSConf1_rw_bitmask;
1916 FORCE_RET();
1919 void op_mtc0_srsconf2 (void)
1921 env->CP0_SRSConf2 |= T0 & env->CP0_SRSConf2_rw_bitmask;
1922 FORCE_RET();
1925 void op_mtc0_srsconf3 (void)
1927 env->CP0_SRSConf3 |= T0 & env->CP0_SRSConf3_rw_bitmask;
1928 FORCE_RET();
1931 void op_mtc0_srsconf4 (void)
1933 env->CP0_SRSConf4 |= T0 & env->CP0_SRSConf4_rw_bitmask;
1934 FORCE_RET();
1937 void op_mtc0_hwrena (void)
1939 env->CP0_HWREna = T0 & 0x0000000F;
1940 FORCE_RET();
1943 void op_mtc0_count (void)
1945 CALL_FROM_TB2(cpu_mips_store_count, env, T0);
1946 FORCE_RET();
1949 void op_mtc0_entryhi (void)
1951 target_ulong old, val;
1953 /* 1k pages not implemented */
1954 val = T0 & ((TARGET_PAGE_MASK << 1) | 0xFF);
1955 #if defined(TARGET_MIPS64)
1956 val &= env->SEGMask;
1957 #endif
1958 old = env->CP0_EntryHi;
1959 env->CP0_EntryHi = val;
1960 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
1961 uint32_t tcst = env->CP0_TCStatus[env->current_tc] & ~0xff;
1962 env->CP0_TCStatus[env->current_tc] = tcst | (val & 0xff);
1964 /* If the ASID changes, flush qemu's TLB. */
1965 if ((old & 0xFF) != (val & 0xFF))
1966 CALL_FROM_TB2(cpu_mips_tlb_flush, env, 1);
1967 FORCE_RET();
1970 void op_mttc0_entryhi(void)
1972 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1974 env->CP0_EntryHi = (env->CP0_EntryHi & 0xff) | (T0 & ~0xff);
1975 env->CP0_TCStatus[other_tc] = (env->CP0_TCStatus[other_tc] & ~0xff) | (T0 & 0xff);
1976 FORCE_RET();
1979 void op_mtc0_compare (void)
1981 CALL_FROM_TB2(cpu_mips_store_compare, env, T0);
1982 FORCE_RET();
1985 void op_mtc0_status (void)
1987 uint32_t val, old;
1988 uint32_t mask = env->CP0_Status_rw_bitmask;
1990 val = T0 & mask;
1991 old = env->CP0_Status;
1992 env->CP0_Status = (env->CP0_Status & ~mask) | val;
1993 CALL_FROM_TB1(compute_hflags, env);
1994 if (loglevel & CPU_LOG_EXEC)
1995 CALL_FROM_TB2(do_mtc0_status_debug, old, val);
1996 CALL_FROM_TB1(cpu_mips_update_irq, env);
1997 FORCE_RET();
2000 void op_mttc0_status(void)
2002 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2003 uint32_t tcstatus = env->CP0_TCStatus[other_tc];
2005 env->CP0_Status = T0 & ~0xf1000018;
2006 tcstatus = (tcstatus & ~(0xf << CP0TCSt_TCU0)) | (T0 & (0xf << CP0St_CU0));
2007 tcstatus = (tcstatus & ~(1 << CP0TCSt_TMX)) | ((T0 & (1 << CP0St_MX)) << (CP0TCSt_TMX - CP0St_MX));
2008 tcstatus = (tcstatus & ~(0x3 << CP0TCSt_TKSU)) | ((T0 & (0x3 << CP0St_KSU)) << (CP0TCSt_TKSU - CP0St_KSU));
2009 env->CP0_TCStatus[other_tc] = tcstatus;
2010 FORCE_RET();
2013 void op_mtc0_intctl (void)
2015 /* vectored interrupts not implemented, no performance counters. */
2016 env->CP0_IntCtl = (env->CP0_IntCtl & ~0x000002e0) | (T0 & 0x000002e0);
2017 FORCE_RET();
2020 void op_mtc0_srsctl (void)
2022 uint32_t mask = (0xf << CP0SRSCtl_ESS) | (0xf << CP0SRSCtl_PSS);
2023 env->CP0_SRSCtl = (env->CP0_SRSCtl & ~mask) | (T0 & mask);
2024 FORCE_RET();
2027 void op_mtc0_srsmap (void)
2029 env->CP0_SRSMap = T0;
2030 FORCE_RET();
2033 void op_mtc0_cause (void)
2035 uint32_t mask = 0x00C00300;
2036 uint32_t old = env->CP0_Cause;
2038 if (env->insn_flags & ISA_MIPS32R2)
2039 mask |= 1 << CP0Ca_DC;
2041 env->CP0_Cause = (env->CP0_Cause & ~mask) | (T0 & mask);
2043 if ((old ^ env->CP0_Cause) & (1 << CP0Ca_DC)) {
2044 if (env->CP0_Cause & (1 << CP0Ca_DC))
2045 CALL_FROM_TB1(cpu_mips_stop_count, env);
2046 else
2047 CALL_FROM_TB1(cpu_mips_start_count, env);
2050 /* Handle the software interrupt as an hardware one, as they
2051 are very similar */
2052 if (T0 & CP0Ca_IP_mask) {
2053 CALL_FROM_TB1(cpu_mips_update_irq, env);
2055 FORCE_RET();
2058 void op_mtc0_epc (void)
2060 env->CP0_EPC = T0;
2061 FORCE_RET();
2064 void op_mtc0_ebase (void)
2066 /* vectored interrupts not implemented */
2067 /* Multi-CPU not implemented */
2068 env->CP0_EBase = 0x80000000 | (T0 & 0x3FFFF000);
2069 FORCE_RET();
2072 void op_mtc0_config0 (void)
2074 env->CP0_Config0 = (env->CP0_Config0 & 0x81FFFFF8) | (T0 & 0x00000007);
2075 FORCE_RET();
2078 void op_mtc0_config2 (void)
2080 /* tertiary/secondary caches not implemented */
2081 env->CP0_Config2 = (env->CP0_Config2 & 0x8FFF0FFF);
2082 FORCE_RET();
2085 void op_mtc0_watchlo (void)
2087 /* Watch exceptions for instructions, data loads, data stores
2088 not implemented. */
2089 env->CP0_WatchLo[PARAM1] = (T0 & ~0x7);
2090 FORCE_RET();
2093 void op_mtc0_watchhi (void)
2095 env->CP0_WatchHi[PARAM1] = (T0 & 0x40FF0FF8);
2096 env->CP0_WatchHi[PARAM1] &= ~(env->CP0_WatchHi[PARAM1] & T0 & 0x7);
2097 FORCE_RET();
2100 void op_mtc0_xcontext (void)
2102 target_ulong mask = (1ULL << (env->SEGBITS - 7)) - 1;
2103 env->CP0_XContext = (env->CP0_XContext & mask) | (T0 & ~mask);
2104 FORCE_RET();
2107 void op_mtc0_framemask (void)
2109 env->CP0_Framemask = T0; /* XXX */
2110 FORCE_RET();
2113 void op_mtc0_debug (void)
2115 env->CP0_Debug = (env->CP0_Debug & 0x8C03FC1F) | (T0 & 0x13300120);
2116 if (T0 & (1 << CP0DB_DM))
2117 env->hflags |= MIPS_HFLAG_DM;
2118 else
2119 env->hflags &= ~MIPS_HFLAG_DM;
2120 FORCE_RET();
2123 void op_mttc0_debug(void)
2125 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2127 /* XXX: Might be wrong, check with EJTAG spec. */
2128 env->CP0_Debug_tcstatus[other_tc] = T0 & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt));
2129 env->CP0_Debug = (env->CP0_Debug & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) |
2130 (T0 & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt)));
2131 FORCE_RET();
2134 void op_mtc0_depc (void)
2136 env->CP0_DEPC = T0;
2137 FORCE_RET();
2140 void op_mtc0_performance0 (void)
2142 env->CP0_Performance0 = T0 & 0x000007ff;
2143 FORCE_RET();
2146 void op_mtc0_taglo (void)
2148 env->CP0_TagLo = T0 & 0xFFFFFCF6;
2149 FORCE_RET();
2152 void op_mtc0_datalo (void)
2154 env->CP0_DataLo = T0; /* XXX */
2155 FORCE_RET();
2158 void op_mtc0_taghi (void)
2160 env->CP0_TagHi = T0; /* XXX */
2161 FORCE_RET();
2164 void op_mtc0_datahi (void)
2166 env->CP0_DataHi = T0; /* XXX */
2167 FORCE_RET();
2170 void op_mtc0_errorepc (void)
2172 env->CP0_ErrorEPC = T0;
2173 FORCE_RET();
2176 void op_mtc0_desave (void)
2178 env->CP0_DESAVE = T0;
2179 FORCE_RET();
2182 #if defined(TARGET_MIPS64)
2183 void op_dmfc0_yqmask (void)
2185 T0 = env->CP0_YQMask;
2186 FORCE_RET();
2189 void op_dmfc0_vpeschedule (void)
2191 T0 = env->CP0_VPESchedule;
2192 FORCE_RET();
2195 void op_dmfc0_vpeschefback (void)
2197 T0 = env->CP0_VPEScheFBack;
2198 FORCE_RET();
2201 void op_dmfc0_entrylo0 (void)
2203 T0 = env->CP0_EntryLo0;
2204 FORCE_RET();
2207 void op_dmfc0_tcrestart (void)
2209 T0 = env->PC[env->current_tc];
2210 FORCE_RET();
2213 void op_dmfc0_tchalt (void)
2215 T0 = env->CP0_TCHalt[env->current_tc];
2216 FORCE_RET();
2219 void op_dmfc0_tccontext (void)
2221 T0 = env->CP0_TCContext[env->current_tc];
2222 FORCE_RET();
2225 void op_dmfc0_tcschedule (void)
2227 T0 = env->CP0_TCSchedule[env->current_tc];
2228 FORCE_RET();
2231 void op_dmfc0_tcschefback (void)
2233 T0 = env->CP0_TCScheFBack[env->current_tc];
2234 FORCE_RET();
2237 void op_dmfc0_entrylo1 (void)
2239 T0 = env->CP0_EntryLo1;
2240 FORCE_RET();
2243 void op_dmfc0_context (void)
2245 T0 = env->CP0_Context;
2246 FORCE_RET();
2249 void op_dmfc0_badvaddr (void)
2251 T0 = env->CP0_BadVAddr;
2252 FORCE_RET();
2255 void op_dmfc0_entryhi (void)
2257 T0 = env->CP0_EntryHi;
2258 FORCE_RET();
2261 void op_dmfc0_epc (void)
2263 T0 = env->CP0_EPC;
2264 FORCE_RET();
2267 void op_dmfc0_lladdr (void)
2269 T0 = env->CP0_LLAddr >> 4;
2270 FORCE_RET();
2273 void op_dmfc0_watchlo (void)
2275 T0 = env->CP0_WatchLo[PARAM1];
2276 FORCE_RET();
2279 void op_dmfc0_xcontext (void)
2281 T0 = env->CP0_XContext;
2282 FORCE_RET();
2285 void op_dmfc0_depc (void)
2287 T0 = env->CP0_DEPC;
2288 FORCE_RET();
2291 void op_dmfc0_errorepc (void)
2293 T0 = env->CP0_ErrorEPC;
2294 FORCE_RET();
2296 #endif /* TARGET_MIPS64 */
2298 /* MIPS MT functions */
2299 void op_mftgpr(void)
2301 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2303 T0 = env->gpr[PARAM1][other_tc];
2304 FORCE_RET();
2307 void op_mftlo(void)
2309 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2311 T0 = env->LO[PARAM1][other_tc];
2312 FORCE_RET();
2315 void op_mfthi(void)
2317 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2319 T0 = env->HI[PARAM1][other_tc];
2320 FORCE_RET();
2323 void op_mftacx(void)
2325 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2327 T0 = env->ACX[PARAM1][other_tc];
2328 FORCE_RET();
2331 void op_mftdsp(void)
2333 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2335 T0 = env->DSPControl[other_tc];
2336 FORCE_RET();
2339 void op_mttgpr(void)
2341 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2343 T0 = env->gpr[PARAM1][other_tc];
2344 FORCE_RET();
2347 void op_mttlo(void)
2349 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2351 T0 = env->LO[PARAM1][other_tc];
2352 FORCE_RET();
2355 void op_mtthi(void)
2357 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2359 T0 = env->HI[PARAM1][other_tc];
2360 FORCE_RET();
2363 void op_mttacx(void)
2365 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2367 T0 = env->ACX[PARAM1][other_tc];
2368 FORCE_RET();
2371 void op_mttdsp(void)
2373 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2375 T0 = env->DSPControl[other_tc];
2376 FORCE_RET();
2380 void op_dmt(void)
2382 // TODO
2383 T0 = 0;
2384 // rt = T0
2385 FORCE_RET();
2388 void op_emt(void)
2390 // TODO
2391 T0 = 0;
2392 // rt = T0
2393 FORCE_RET();
2396 void op_dvpe(void)
2398 // TODO
2399 T0 = 0;
2400 // rt = T0
2401 FORCE_RET();
2404 void op_evpe(void)
2406 // TODO
2407 T0 = 0;
2408 // rt = T0
2409 FORCE_RET();
2412 void op_fork(void)
2414 // T0 = rt, T1 = rs
2415 T0 = 0;
2416 // TODO: store to TC register
2417 FORCE_RET();
2420 void op_yield(void)
2422 if (T0 < 0) {
2423 /* No scheduling policy implemented. */
2424 if (T0 != -2) {
2425 if (env->CP0_VPEControl & (1 << CP0VPECo_YSI) &&
2426 env->CP0_TCStatus[env->current_tc] & (1 << CP0TCSt_DT)) {
2427 env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT);
2428 env->CP0_VPEControl |= 4 << CP0VPECo_EXCPT;
2429 CALL_FROM_TB1(do_raise_exception, EXCP_THREAD);
2432 } else if (T0 == 0) {
2433 if (0 /* TODO: TC underflow */) {
2434 env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT);
2435 CALL_FROM_TB1(do_raise_exception, EXCP_THREAD);
2436 } else {
2437 // TODO: Deallocate TC
2439 } else if (T0 > 0) {
2440 /* Yield qualifier inputs not implemented. */
2441 env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT);
2442 env->CP0_VPEControl |= 2 << CP0VPECo_EXCPT;
2443 CALL_FROM_TB1(do_raise_exception, EXCP_THREAD);
2445 T0 = env->CP0_YQMask;
2446 FORCE_RET();
2449 /* CP1 functions */
2450 #if 0
2451 # define DEBUG_FPU_STATE() CALL_FROM_TB1(dump_fpu, env)
2452 #else
2453 # define DEBUG_FPU_STATE() do { } while(0)
2454 #endif
2456 void op_cfc1 (void)
2458 CALL_FROM_TB1(do_cfc1, PARAM1);
2459 DEBUG_FPU_STATE();
2460 FORCE_RET();
2463 void op_ctc1 (void)
2465 CALL_FROM_TB1(do_ctc1, PARAM1);
2466 DEBUG_FPU_STATE();
2467 FORCE_RET();
2470 void op_mfc1 (void)
2472 T0 = (int32_t)WT0;
2473 DEBUG_FPU_STATE();
2474 FORCE_RET();
2477 void op_mtc1 (void)
2479 WT0 = T0;
2480 DEBUG_FPU_STATE();
2481 FORCE_RET();
2484 void op_dmfc1 (void)
2486 T0 = DT0;
2487 DEBUG_FPU_STATE();
2488 FORCE_RET();
2491 void op_dmtc1 (void)
2493 DT0 = T0;
2494 DEBUG_FPU_STATE();
2495 FORCE_RET();
2498 void op_mfhc1 (void)
2500 T0 = (int32_t)WTH0;
2501 DEBUG_FPU_STATE();
2502 FORCE_RET();
2505 void op_mthc1 (void)
2507 WTH0 = T0;
2508 DEBUG_FPU_STATE();
2509 FORCE_RET();
2512 /* Float support.
2513 Single precition routines have a "s" suffix, double precision a
2514 "d" suffix, 32bit integer "w", 64bit integer "l", paired singe "ps",
2515 paired single lowwer "pl", paired single upper "pu". */
2517 #define FLOAT_OP(name, p) void OPPROTO op_float_##name##_##p(void)
2519 FLOAT_OP(cvtd, s)
2521 CALL_FROM_TB0(do_float_cvtd_s);
2522 DEBUG_FPU_STATE();
2523 FORCE_RET();
2525 FLOAT_OP(cvtd, w)
2527 CALL_FROM_TB0(do_float_cvtd_w);
2528 DEBUG_FPU_STATE();
2529 FORCE_RET();
2531 FLOAT_OP(cvtd, l)
2533 CALL_FROM_TB0(do_float_cvtd_l);
2534 DEBUG_FPU_STATE();
2535 FORCE_RET();
2537 FLOAT_OP(cvtl, d)
2539 CALL_FROM_TB0(do_float_cvtl_d);
2540 DEBUG_FPU_STATE();
2541 FORCE_RET();
2543 FLOAT_OP(cvtl, s)
2545 CALL_FROM_TB0(do_float_cvtl_s);
2546 DEBUG_FPU_STATE();
2547 FORCE_RET();
2549 FLOAT_OP(cvtps, s)
2551 WT2 = WT0;
2552 WTH2 = WT1;
2553 DEBUG_FPU_STATE();
2554 FORCE_RET();
2556 FLOAT_OP(cvtps, pw)
2558 CALL_FROM_TB0(do_float_cvtps_pw);
2559 DEBUG_FPU_STATE();
2560 FORCE_RET();
2562 FLOAT_OP(cvtpw, ps)
2564 CALL_FROM_TB0(do_float_cvtpw_ps);
2565 DEBUG_FPU_STATE();
2566 FORCE_RET();
2568 FLOAT_OP(cvts, d)
2570 CALL_FROM_TB0(do_float_cvts_d);
2571 DEBUG_FPU_STATE();
2572 FORCE_RET();
2574 FLOAT_OP(cvts, w)
2576 CALL_FROM_TB0(do_float_cvts_w);
2577 DEBUG_FPU_STATE();
2578 FORCE_RET();
2580 FLOAT_OP(cvts, l)
2582 CALL_FROM_TB0(do_float_cvts_l);
2583 DEBUG_FPU_STATE();
2584 FORCE_RET();
2586 FLOAT_OP(cvts, pl)
2588 CALL_FROM_TB0(do_float_cvts_pl);
2589 DEBUG_FPU_STATE();
2590 FORCE_RET();
2592 FLOAT_OP(cvts, pu)
2594 CALL_FROM_TB0(do_float_cvts_pu);
2595 DEBUG_FPU_STATE();
2596 FORCE_RET();
2598 FLOAT_OP(cvtw, s)
2600 CALL_FROM_TB0(do_float_cvtw_s);
2601 DEBUG_FPU_STATE();
2602 FORCE_RET();
2604 FLOAT_OP(cvtw, d)
2606 CALL_FROM_TB0(do_float_cvtw_d);
2607 DEBUG_FPU_STATE();
2608 FORCE_RET();
2611 FLOAT_OP(pll, ps)
2613 DT2 = ((uint64_t)WT0 << 32) | WT1;
2614 DEBUG_FPU_STATE();
2615 FORCE_RET();
2617 FLOAT_OP(plu, ps)
2619 DT2 = ((uint64_t)WT0 << 32) | WTH1;
2620 DEBUG_FPU_STATE();
2621 FORCE_RET();
2623 FLOAT_OP(pul, ps)
2625 DT2 = ((uint64_t)WTH0 << 32) | WT1;
2626 DEBUG_FPU_STATE();
2627 FORCE_RET();
2629 FLOAT_OP(puu, ps)
2631 DT2 = ((uint64_t)WTH0 << 32) | WTH1;
2632 DEBUG_FPU_STATE();
2633 FORCE_RET();
2636 #define FLOAT_ROUNDOP(op, ttype, stype) \
2637 FLOAT_OP(op ## ttype, stype) \
2639 CALL_FROM_TB0(do_float_ ## op ## ttype ## _ ## stype); \
2640 DEBUG_FPU_STATE(); \
2641 FORCE_RET(); \
2644 FLOAT_ROUNDOP(round, l, d)
2645 FLOAT_ROUNDOP(round, l, s)
2646 FLOAT_ROUNDOP(round, w, d)
2647 FLOAT_ROUNDOP(round, w, s)
2649 FLOAT_ROUNDOP(trunc, l, d)
2650 FLOAT_ROUNDOP(trunc, l, s)
2651 FLOAT_ROUNDOP(trunc, w, d)
2652 FLOAT_ROUNDOP(trunc, w, s)
2654 FLOAT_ROUNDOP(ceil, l, d)
2655 FLOAT_ROUNDOP(ceil, l, s)
2656 FLOAT_ROUNDOP(ceil, w, d)
2657 FLOAT_ROUNDOP(ceil, w, s)
2659 FLOAT_ROUNDOP(floor, l, d)
2660 FLOAT_ROUNDOP(floor, l, s)
2661 FLOAT_ROUNDOP(floor, w, d)
2662 FLOAT_ROUNDOP(floor, w, s)
2663 #undef FLOAR_ROUNDOP
2665 FLOAT_OP(movf, d)
2667 if (!(env->fpu->fcr31 & PARAM1))
2668 DT2 = DT0;
2669 DEBUG_FPU_STATE();
2670 FORCE_RET();
2672 FLOAT_OP(movf, s)
2674 if (!(env->fpu->fcr31 & PARAM1))
2675 WT2 = WT0;
2676 DEBUG_FPU_STATE();
2677 FORCE_RET();
2679 FLOAT_OP(movf, ps)
2681 if (!(env->fpu->fcr31 & PARAM1)) {
2682 WT2 = WT0;
2683 WTH2 = WTH0;
2685 DEBUG_FPU_STATE();
2686 FORCE_RET();
2688 FLOAT_OP(movt, d)
2690 if (env->fpu->fcr31 & PARAM1)
2691 DT2 = DT0;
2692 DEBUG_FPU_STATE();
2693 FORCE_RET();
2695 FLOAT_OP(movt, s)
2697 if (env->fpu->fcr31 & PARAM1)
2698 WT2 = WT0;
2699 DEBUG_FPU_STATE();
2700 FORCE_RET();
2702 FLOAT_OP(movt, ps)
2704 if (env->fpu->fcr31 & PARAM1) {
2705 WT2 = WT0;
2706 WTH2 = WTH0;
2708 DEBUG_FPU_STATE();
2709 FORCE_RET();
2711 FLOAT_OP(movz, d)
2713 if (!T0)
2714 DT2 = DT0;
2715 DEBUG_FPU_STATE();
2716 FORCE_RET();
2718 FLOAT_OP(movz, s)
2720 if (!T0)
2721 WT2 = WT0;
2722 DEBUG_FPU_STATE();
2723 FORCE_RET();
2725 FLOAT_OP(movz, ps)
2727 if (!T0) {
2728 WT2 = WT0;
2729 WTH2 = WTH0;
2731 DEBUG_FPU_STATE();
2732 FORCE_RET();
2734 FLOAT_OP(movn, d)
2736 if (T0)
2737 DT2 = DT0;
2738 DEBUG_FPU_STATE();
2739 FORCE_RET();
2741 FLOAT_OP(movn, s)
2743 if (T0)
2744 WT2 = WT0;
2745 DEBUG_FPU_STATE();
2746 FORCE_RET();
2748 FLOAT_OP(movn, ps)
2750 if (T0) {
2751 WT2 = WT0;
2752 WTH2 = WTH0;
2754 DEBUG_FPU_STATE();
2755 FORCE_RET();
2758 /* operations calling helpers, for s, d and ps */
2759 #define FLOAT_HOP(name) \
2760 FLOAT_OP(name, d) \
2762 CALL_FROM_TB0(do_float_ ## name ## _d); \
2763 DEBUG_FPU_STATE(); \
2764 FORCE_RET(); \
2766 FLOAT_OP(name, s) \
2768 CALL_FROM_TB0(do_float_ ## name ## _s); \
2769 DEBUG_FPU_STATE(); \
2770 FORCE_RET(); \
2772 FLOAT_OP(name, ps) \
2774 CALL_FROM_TB0(do_float_ ## name ## _ps); \
2775 DEBUG_FPU_STATE(); \
2776 FORCE_RET(); \
2778 FLOAT_HOP(add)
2779 FLOAT_HOP(sub)
2780 FLOAT_HOP(mul)
2781 FLOAT_HOP(div)
2782 FLOAT_HOP(recip2)
2783 FLOAT_HOP(rsqrt2)
2784 FLOAT_HOP(rsqrt1)
2785 FLOAT_HOP(recip1)
2786 #undef FLOAT_HOP
2788 /* operations calling helpers, for s and d */
2789 #define FLOAT_HOP(name) \
2790 FLOAT_OP(name, d) \
2792 CALL_FROM_TB0(do_float_ ## name ## _d); \
2793 DEBUG_FPU_STATE(); \
2794 FORCE_RET(); \
2796 FLOAT_OP(name, s) \
2798 CALL_FROM_TB0(do_float_ ## name ## _s); \
2799 DEBUG_FPU_STATE(); \
2800 FORCE_RET(); \
2802 FLOAT_HOP(rsqrt)
2803 FLOAT_HOP(recip)
2804 #undef FLOAT_HOP
2806 /* operations calling helpers, for ps */
2807 #define FLOAT_HOP(name) \
2808 FLOAT_OP(name, ps) \
2810 CALL_FROM_TB0(do_float_ ## name ## _ps); \
2811 DEBUG_FPU_STATE(); \
2812 FORCE_RET(); \
2814 FLOAT_HOP(addr)
2815 FLOAT_HOP(mulr)
2816 #undef FLOAT_HOP
2818 /* ternary operations */
2819 #define FLOAT_TERNOP(name1, name2) \
2820 FLOAT_OP(name1 ## name2, d) \
2822 FDT0 = float64_ ## name1 (FDT0, FDT1, &env->fpu->fp_status); \
2823 FDT2 = float64_ ## name2 (FDT0, FDT2, &env->fpu->fp_status); \
2824 DEBUG_FPU_STATE(); \
2825 FORCE_RET(); \
2827 FLOAT_OP(name1 ## name2, s) \
2829 FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status); \
2830 FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status); \
2831 DEBUG_FPU_STATE(); \
2832 FORCE_RET(); \
2834 FLOAT_OP(name1 ## name2, ps) \
2836 FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status); \
2837 FSTH0 = float32_ ## name1 (FSTH0, FSTH1, &env->fpu->fp_status); \
2838 FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status); \
2839 FSTH2 = float32_ ## name2 (FSTH0, FSTH2, &env->fpu->fp_status); \
2840 DEBUG_FPU_STATE(); \
2841 FORCE_RET(); \
2843 FLOAT_TERNOP(mul, add)
2844 FLOAT_TERNOP(mul, sub)
2845 #undef FLOAT_TERNOP
2847 /* negated ternary operations */
2848 #define FLOAT_NTERNOP(name1, name2) \
2849 FLOAT_OP(n ## name1 ## name2, d) \
2851 FDT0 = float64_ ## name1 (FDT0, FDT1, &env->fpu->fp_status); \
2852 FDT2 = float64_ ## name2 (FDT0, FDT2, &env->fpu->fp_status); \
2853 FDT2 = float64_chs(FDT2); \
2854 DEBUG_FPU_STATE(); \
2855 FORCE_RET(); \
2857 FLOAT_OP(n ## name1 ## name2, s) \
2859 FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status); \
2860 FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status); \
2861 FST2 = float32_chs(FST2); \
2862 DEBUG_FPU_STATE(); \
2863 FORCE_RET(); \
2865 FLOAT_OP(n ## name1 ## name2, ps) \
2867 FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status); \
2868 FSTH0 = float32_ ## name1 (FSTH0, FSTH1, &env->fpu->fp_status); \
2869 FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status); \
2870 FSTH2 = float32_ ## name2 (FSTH0, FSTH2, &env->fpu->fp_status); \
2871 FST2 = float32_chs(FST2); \
2872 FSTH2 = float32_chs(FSTH2); \
2873 DEBUG_FPU_STATE(); \
2874 FORCE_RET(); \
2876 FLOAT_NTERNOP(mul, add)
2877 FLOAT_NTERNOP(mul, sub)
2878 #undef FLOAT_NTERNOP
2880 /* unary operations, modifying fp status */
2881 #define FLOAT_UNOP(name) \
2882 FLOAT_OP(name, d) \
2884 FDT2 = float64_ ## name(FDT0, &env->fpu->fp_status); \
2885 DEBUG_FPU_STATE(); \
2886 FORCE_RET(); \
2888 FLOAT_OP(name, s) \
2890 FST2 = float32_ ## name(FST0, &env->fpu->fp_status); \
2891 DEBUG_FPU_STATE(); \
2892 FORCE_RET(); \
2894 FLOAT_UNOP(sqrt)
2895 #undef FLOAT_UNOP
2897 /* unary operations, not modifying fp status */
2898 #define FLOAT_UNOP(name) \
2899 FLOAT_OP(name, d) \
2901 FDT2 = float64_ ## name(FDT0); \
2902 DEBUG_FPU_STATE(); \
2903 FORCE_RET(); \
2905 FLOAT_OP(name, s) \
2907 FST2 = float32_ ## name(FST0); \
2908 DEBUG_FPU_STATE(); \
2909 FORCE_RET(); \
2911 FLOAT_OP(name, ps) \
2913 FST2 = float32_ ## name(FST0); \
2914 FSTH2 = float32_ ## name(FSTH0); \
2915 DEBUG_FPU_STATE(); \
2916 FORCE_RET(); \
2918 FLOAT_UNOP(abs)
2919 FLOAT_UNOP(chs)
2920 #undef FLOAT_UNOP
2922 FLOAT_OP(mov, d)
2924 FDT2 = FDT0;
2925 DEBUG_FPU_STATE();
2926 FORCE_RET();
2928 FLOAT_OP(mov, s)
2930 FST2 = FST0;
2931 DEBUG_FPU_STATE();
2932 FORCE_RET();
2934 FLOAT_OP(mov, ps)
2936 FST2 = FST0;
2937 FSTH2 = FSTH0;
2938 DEBUG_FPU_STATE();
2939 FORCE_RET();
2941 FLOAT_OP(alnv, ps)
2943 switch (T0 & 0x7) {
2944 case 0:
2945 FST2 = FST0;
2946 FSTH2 = FSTH0;
2947 break;
2948 case 4:
2949 #ifdef TARGET_WORDS_BIGENDIAN
2950 FSTH2 = FST0;
2951 FST2 = FSTH1;
2952 #else
2953 FSTH2 = FST1;
2954 FST2 = FSTH0;
2955 #endif
2956 break;
2957 default: /* unpredictable */
2958 break;
2960 DEBUG_FPU_STATE();
2961 FORCE_RET();
2964 #ifdef CONFIG_SOFTFLOAT
2965 #define clear_invalid() do { \
2966 int flags = get_float_exception_flags(&env->fpu->fp_status); \
2967 flags &= ~float_flag_invalid; \
2968 set_float_exception_flags(flags, &env->fpu->fp_status); \
2969 } while(0)
2970 #else
2971 #define clear_invalid() do { } while(0)
2972 #endif
2974 extern void dump_fpu_s(CPUState *env);
2976 #define CMP_OP(fmt, op) \
2977 void OPPROTO op_cmp ## _ ## fmt ## _ ## op(void) \
2979 CALL_FROM_TB1(do_cmp ## _ ## fmt ## _ ## op, PARAM1); \
2980 DEBUG_FPU_STATE(); \
2981 FORCE_RET(); \
2983 void OPPROTO op_cmpabs ## _ ## fmt ## _ ## op(void) \
2985 CALL_FROM_TB1(do_cmpabs ## _ ## fmt ## _ ## op, PARAM1); \
2986 DEBUG_FPU_STATE(); \
2987 FORCE_RET(); \
2989 #define CMP_OPS(op) \
2990 CMP_OP(d, op) \
2991 CMP_OP(s, op) \
2992 CMP_OP(ps, op)
2994 CMP_OPS(f)
2995 CMP_OPS(un)
2996 CMP_OPS(eq)
2997 CMP_OPS(ueq)
2998 CMP_OPS(olt)
2999 CMP_OPS(ult)
3000 CMP_OPS(ole)
3001 CMP_OPS(ule)
3002 CMP_OPS(sf)
3003 CMP_OPS(ngle)
3004 CMP_OPS(seq)
3005 CMP_OPS(ngl)
3006 CMP_OPS(lt)
3007 CMP_OPS(nge)
3008 CMP_OPS(le)
3009 CMP_OPS(ngt)
3010 #undef CMP_OPS
3011 #undef CMP_OP
3013 void op_bc1f (void)
3015 T0 = !!(~GET_FP_COND(env->fpu) & (0x1 << PARAM1));
3016 DEBUG_FPU_STATE();
3017 FORCE_RET();
3019 void op_bc1any2f (void)
3021 T0 = !!(~GET_FP_COND(env->fpu) & (0x3 << PARAM1));
3022 DEBUG_FPU_STATE();
3023 FORCE_RET();
3025 void op_bc1any4f (void)
3027 T0 = !!(~GET_FP_COND(env->fpu) & (0xf << PARAM1));
3028 DEBUG_FPU_STATE();
3029 FORCE_RET();
3032 void op_bc1t (void)
3034 T0 = !!(GET_FP_COND(env->fpu) & (0x1 << PARAM1));
3035 DEBUG_FPU_STATE();
3036 FORCE_RET();
3038 void op_bc1any2t (void)
3040 T0 = !!(GET_FP_COND(env->fpu) & (0x3 << PARAM1));
3041 DEBUG_FPU_STATE();
3042 FORCE_RET();
3044 void op_bc1any4t (void)
3046 T0 = !!(GET_FP_COND(env->fpu) & (0xf << PARAM1));
3047 DEBUG_FPU_STATE();
3048 FORCE_RET();
3051 void op_tlbwi (void)
3053 CALL_FROM_TB0(env->tlb->do_tlbwi);
3054 FORCE_RET();
3057 void op_tlbwr (void)
3059 CALL_FROM_TB0(env->tlb->do_tlbwr);
3060 FORCE_RET();
3063 void op_tlbp (void)
3065 CALL_FROM_TB0(env->tlb->do_tlbp);
3066 FORCE_RET();
3069 void op_tlbr (void)
3071 CALL_FROM_TB0(env->tlb->do_tlbr);
3072 FORCE_RET();
3075 /* Specials */
3076 #if defined (CONFIG_USER_ONLY)
3077 void op_tls_value (void)
3079 T0 = env->tls_value;
3081 #endif
3083 void op_pmon (void)
3085 CALL_FROM_TB1(do_pmon, PARAM1);
3086 FORCE_RET();
3089 void op_di (void)
3091 T0 = env->CP0_Status;
3092 env->CP0_Status = T0 & ~(1 << CP0St_IE);
3093 CALL_FROM_TB1(cpu_mips_update_irq, env);
3094 FORCE_RET();
3097 void op_ei (void)
3099 T0 = env->CP0_Status;
3100 env->CP0_Status = T0 | (1 << CP0St_IE);
3101 CALL_FROM_TB1(cpu_mips_update_irq, env);
3102 FORCE_RET();
3105 void op_trap (void)
3107 if (T0) {
3108 CALL_FROM_TB1(do_raise_exception, EXCP_TRAP);
3110 FORCE_RET();
3113 void op_debug (void)
3115 CALL_FROM_TB1(do_raise_exception, EXCP_DEBUG);
3116 FORCE_RET();
3119 void op_set_lladdr (void)
3121 env->CP0_LLAddr = T2;
3122 FORCE_RET();
3125 void debug_pre_eret (void);
3126 void debug_post_eret (void);
3127 void op_eret (void)
3129 if (loglevel & CPU_LOG_EXEC)
3130 CALL_FROM_TB0(debug_pre_eret);
3131 if (env->CP0_Status & (1 << CP0St_ERL)) {
3132 env->PC[env->current_tc] = env->CP0_ErrorEPC;
3133 env->CP0_Status &= ~(1 << CP0St_ERL);
3134 } else {
3135 env->PC[env->current_tc] = env->CP0_EPC;
3136 env->CP0_Status &= ~(1 << CP0St_EXL);
3138 CALL_FROM_TB1(compute_hflags, env);
3139 if (loglevel & CPU_LOG_EXEC)
3140 CALL_FROM_TB0(debug_post_eret);
3141 env->CP0_LLAddr = 1;
3142 FORCE_RET();
3145 void op_deret (void)
3147 if (loglevel & CPU_LOG_EXEC)
3148 CALL_FROM_TB0(debug_pre_eret);
3149 env->PC[env->current_tc] = env->CP0_DEPC;
3150 env->hflags &= MIPS_HFLAG_DM;
3151 CALL_FROM_TB1(compute_hflags, env);
3152 if (loglevel & CPU_LOG_EXEC)
3153 CALL_FROM_TB0(debug_post_eret);
3154 env->CP0_LLAddr = 1;
3155 FORCE_RET();
3158 void op_rdhwr_cpunum(void)
3160 if ((env->hflags & MIPS_HFLAG_CP0) ||
3161 (env->CP0_HWREna & (1 << 0)))
3162 T0 = env->CP0_EBase & 0x3ff;
3163 else
3164 CALL_FROM_TB1(do_raise_exception, EXCP_RI);
3165 FORCE_RET();
3168 void op_rdhwr_synci_step(void)
3170 if ((env->hflags & MIPS_HFLAG_CP0) ||
3171 (env->CP0_HWREna & (1 << 1)))
3172 T0 = env->SYNCI_Step;
3173 else
3174 CALL_FROM_TB1(do_raise_exception, EXCP_RI);
3175 FORCE_RET();
3178 void op_rdhwr_cc(void)
3180 if ((env->hflags & MIPS_HFLAG_CP0) ||
3181 (env->CP0_HWREna & (1 << 2)))
3182 T0 = env->CP0_Count;
3183 else
3184 CALL_FROM_TB1(do_raise_exception, EXCP_RI);
3185 FORCE_RET();
3188 void op_rdhwr_ccres(void)
3190 if ((env->hflags & MIPS_HFLAG_CP0) ||
3191 (env->CP0_HWREna & (1 << 3)))
3192 T0 = env->CCRes;
3193 else
3194 CALL_FROM_TB1(do_raise_exception, EXCP_RI);
3195 FORCE_RET();
3198 void op_save_state (void)
3200 env->hflags = PARAM1;
3201 FORCE_RET();
3204 void op_save_pc (void)
3206 env->PC[env->current_tc] = PARAM1;
3207 FORCE_RET();
3210 #if defined(TARGET_MIPS64)
3211 void op_save_pc64 (void)
3213 env->PC[env->current_tc] = ((uint64_t)PARAM1 << 32) | (uint32_t)PARAM2;
3214 FORCE_RET();
3216 #endif
3218 void op_interrupt_restart (void)
3220 if (!(env->CP0_Status & (1 << CP0St_EXL)) &&
3221 !(env->CP0_Status & (1 << CP0St_ERL)) &&
3222 !(env->hflags & MIPS_HFLAG_DM) &&
3223 (env->CP0_Status & (1 << CP0St_IE)) &&
3224 (env->CP0_Status & env->CP0_Cause & CP0Ca_IP_mask)) {
3225 env->CP0_Cause &= ~(0x1f << CP0Ca_EC);
3226 CALL_FROM_TB1(do_raise_exception, EXCP_EXT_INTERRUPT);
3228 FORCE_RET();
3231 void op_raise_exception (void)
3233 CALL_FROM_TB1(do_raise_exception, PARAM1);
3234 FORCE_RET();
3237 void op_raise_exception_err (void)
3239 CALL_FROM_TB2(do_raise_exception_err, PARAM1, PARAM2);
3240 FORCE_RET();
3243 void op_wait (void)
3245 env->halted = 1;
3246 CALL_FROM_TB1(do_raise_exception, EXCP_HLT);
3247 FORCE_RET();
3250 /* Bitfield operations. */
3251 void op_ext(void)
3253 unsigned int pos = PARAM1;
3254 unsigned int size = PARAM2;
3256 T0 = (int32_t)((T1 >> pos) & ((size < 32) ? ((1 << size) - 1) : ~0));
3257 FORCE_RET();
3260 void op_ins(void)
3262 unsigned int pos = PARAM1;
3263 unsigned int size = PARAM2;
3264 target_ulong mask = ((size < 32) ? ((1 << size) - 1) : ~0) << pos;
3266 T0 = (int32_t)((T0 & ~mask) | ((T1 << pos) & mask));
3267 FORCE_RET();
3270 void op_wsbh(void)
3272 T0 = (int32_t)(((T1 << 8) & ~0x00FF00FF) | ((T1 >> 8) & 0x00FF00FF));
3273 FORCE_RET();
3276 #if defined(TARGET_MIPS64)
3277 void op_dext(void)
3279 unsigned int pos = PARAM1;
3280 unsigned int size = PARAM2;
3282 T0 = (T1 >> pos) & ((size < 64) ? ((1ULL << size) - 1) : ~0ULL);
3283 FORCE_RET();
3286 void op_dins(void)
3288 unsigned int pos = PARAM1;
3289 unsigned int size = PARAM2;
3290 target_ulong mask = ((size < 64) ? ((1ULL << size) - 1) : ~0ULL) << pos;
3292 T0 = (T0 & ~mask) | ((T1 << pos) & mask);
3293 FORCE_RET();
3296 void op_dsbh(void)
3298 T0 = ((T1 << 8) & ~0x00FF00FF00FF00FFULL) | ((T1 >> 8) & 0x00FF00FF00FF00FFULL);
3299 FORCE_RET();
3302 void op_dshd(void)
3304 T1 = ((T1 << 16) & ~0x0000FFFF0000FFFFULL) | ((T1 >> 16) & 0x0000FFFF0000FFFFULL);
3305 T0 = (T1 << 32) | (T1 >> 32);
3306 FORCE_RET();
3308 #endif
3310 void op_seb(void)
3312 T0 = ((T1 & 0xFF) ^ 0x80) - 0x80;
3313 FORCE_RET();
3316 void op_seh(void)
3318 T0 = ((T1 & 0xFFFF) ^ 0x8000) - 0x8000;
3319 FORCE_RET();