]> Git Repo - qemu.git/blame - target-mips/op.c
Enable 64-bit FPU only for NewABI. Spotted by Vince Weaver.
[qemu.git] / target-mips / op.c
CommitLineData
6af0bf9c
FB
1/*
2 * MIPS emulation micro-operations for qemu.
5fafdf24 3 *
6af0bf9c 4 * Copyright (c) 2004-2005 Jocelyn Mayer
6ea83fed 5 * Copyright (c) 2006 Marius Groeger (FPU operations)
93b12ccc 6 * Copyright (c) 2007 Thiemo Seufer (64-bit FPU support)
6af0bf9c
FB
7 *
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.
12 *
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.
17 *
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
21 */
22
23#include "config.h"
24#include "exec.h"
05f778c8 25#include "host-utils.h"
6af0bf9c 26
1b351e52 27#ifndef CALL_FROM_TB0
5a5012ec 28#define CALL_FROM_TB0(func) func()
1b351e52
FB
29#endif
30#ifndef CALL_FROM_TB1
5a5012ec 31#define CALL_FROM_TB1(func, arg0) func(arg0)
1b351e52
FB
32#endif
33#ifndef CALL_FROM_TB1_CONST16
5a5012ec 34#define CALL_FROM_TB1_CONST16(func, arg0) CALL_FROM_TB1(func, arg0)
1b351e52
FB
35#endif
36#ifndef CALL_FROM_TB2
5a5012ec 37#define CALL_FROM_TB2(func, arg0, arg1) func(arg0, arg1)
1b351e52
FB
38#endif
39#ifndef CALL_FROM_TB2_CONST16
40#define CALL_FROM_TB2_CONST16(func, arg0, arg1) \
5a5012ec 41 CALL_FROM_TB2(func, arg0, arg1)
1b351e52
FB
42#endif
43#ifndef CALL_FROM_TB3
5a5012ec 44#define CALL_FROM_TB3(func, arg0, arg1, arg2) func(arg0, arg1, arg2)
1b351e52
FB
45#endif
46#ifndef CALL_FROM_TB4
47#define CALL_FROM_TB4(func, arg0, arg1, arg2, arg3) \
5a5012ec 48 func(arg0, arg1, arg2, arg3)
1b351e52
FB
49#endif
50
6af0bf9c
FB
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
144
c570fd16 145#define TN
6af0bf9c
FB
146#include "op_template.c"
147#undef TN
148
5a5012ec 149#define FREG 0
6ea83fed 150#include "fop_template.c"
5a5012ec
TS
151#undef FREG
152#define FREG 1
6ea83fed 153#include "fop_template.c"
5a5012ec
TS
154#undef FREG
155#define FREG 2
6ea83fed 156#include "fop_template.c"
5a5012ec
TS
157#undef FREG
158#define FREG 3
6ea83fed 159#include "fop_template.c"
5a5012ec
TS
160#undef FREG
161#define FREG 4
6ea83fed 162#include "fop_template.c"
5a5012ec
TS
163#undef FREG
164#define FREG 5
6ea83fed 165#include "fop_template.c"
5a5012ec
TS
166#undef FREG
167#define FREG 6
6ea83fed 168#include "fop_template.c"
5a5012ec
TS
169#undef FREG
170#define FREG 7
6ea83fed 171#include "fop_template.c"
5a5012ec
TS
172#undef FREG
173#define FREG 8
6ea83fed 174#include "fop_template.c"
5a5012ec
TS
175#undef FREG
176#define FREG 9
6ea83fed 177#include "fop_template.c"
5a5012ec
TS
178#undef FREG
179#define FREG 10
6ea83fed 180#include "fop_template.c"
5a5012ec
TS
181#undef FREG
182#define FREG 11
6ea83fed 183#include "fop_template.c"
5a5012ec
TS
184#undef FREG
185#define FREG 12
6ea83fed 186#include "fop_template.c"
5a5012ec
TS
187#undef FREG
188#define FREG 13
6ea83fed 189#include "fop_template.c"
5a5012ec
TS
190#undef FREG
191#define FREG 14
6ea83fed 192#include "fop_template.c"
5a5012ec
TS
193#undef FREG
194#define FREG 15
6ea83fed 195#include "fop_template.c"
5a5012ec
TS
196#undef FREG
197#define FREG 16
6ea83fed 198#include "fop_template.c"
5a5012ec
TS
199#undef FREG
200#define FREG 17
6ea83fed 201#include "fop_template.c"
5a5012ec
TS
202#undef FREG
203#define FREG 18
6ea83fed 204#include "fop_template.c"
5a5012ec
TS
205#undef FREG
206#define FREG 19
6ea83fed 207#include "fop_template.c"
5a5012ec
TS
208#undef FREG
209#define FREG 20
6ea83fed 210#include "fop_template.c"
5a5012ec
TS
211#undef FREG
212#define FREG 21
6ea83fed 213#include "fop_template.c"
5a5012ec
TS
214#undef FREG
215#define FREG 22
6ea83fed 216#include "fop_template.c"
5a5012ec
TS
217#undef FREG
218#define FREG 23
6ea83fed 219#include "fop_template.c"
5a5012ec
TS
220#undef FREG
221#define FREG 24
6ea83fed 222#include "fop_template.c"
5a5012ec
TS
223#undef FREG
224#define FREG 25
6ea83fed 225#include "fop_template.c"
5a5012ec
TS
226#undef FREG
227#define FREG 26
6ea83fed 228#include "fop_template.c"
5a5012ec
TS
229#undef FREG
230#define FREG 27
6ea83fed 231#include "fop_template.c"
5a5012ec
TS
232#undef FREG
233#define FREG 28
6ea83fed 234#include "fop_template.c"
5a5012ec
TS
235#undef FREG
236#define FREG 29
6ea83fed 237#include "fop_template.c"
5a5012ec
TS
238#undef FREG
239#define FREG 30
6ea83fed 240#include "fop_template.c"
5a5012ec
TS
241#undef FREG
242#define FREG 31
6ea83fed 243#include "fop_template.c"
5a5012ec 244#undef FREG
6ea83fed
FB
245
246#define FTN
247#include "fop_template.c"
248#undef FTN
249
6af0bf9c
FB
250void op_load_HI (void)
251{
d0dc7dc3 252 T0 = env->HI[env->current_tc][PARAM1];
8f6f6026 253 FORCE_RET();
6af0bf9c
FB
254}
255
256void op_store_HI (void)
257{
d0dc7dc3 258 env->HI[env->current_tc][PARAM1] = T0;
8f6f6026 259 FORCE_RET();
6af0bf9c
FB
260}
261
262void op_load_LO (void)
263{
d0dc7dc3 264 T0 = env->LO[env->current_tc][PARAM1];
8f6f6026 265 FORCE_RET();
6af0bf9c
FB
266}
267
268void op_store_LO (void)
269{
d0dc7dc3 270 env->LO[env->current_tc][PARAM1] = T0;
8f6f6026 271 FORCE_RET();
6af0bf9c
FB
272}
273
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
282
623a930e
TS
283#define MEMSUFFIX _super
284#include "op_mem.c"
285#undef MEMSUFFIX
286
6af0bf9c
FB
287#define MEMSUFFIX _kernel
288#include "op_mem.c"
289#undef MEMSUFFIX
290#endif
291
a6763a58
TS
292/* Addresses computation */
293void op_addr_add (void)
294{
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. */
d26bc211 298#if defined(TARGET_MIPS64)
623a930e 299 if (((env->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
a6763a58
TS
300 !(env->CP0_Status & (1 << CP0St_UX)))
301 T0 = (int64_t)(int32_t)(T0 + T1);
302 else
303#endif
304 T0 += T1;
8f6f6026 305 FORCE_RET();
a6763a58
TS
306}
307
6af0bf9c
FB
308/* Arithmetic */
309void op_add (void)
310{
5dc4b744 311 T0 = (int32_t)((int32_t)T0 + (int32_t)T1);
8f6f6026 312 FORCE_RET();
6af0bf9c
FB
313}
314
315void op_addo (void)
316{
317 target_ulong tmp;
318
c570fd16
TS
319 tmp = (int32_t)T0;
320 T0 = (int32_t)T0 + (int32_t)T1;
76e050c2 321 if (((tmp ^ T1 ^ (-1)) & (T0 ^ T1)) >> 31) {
c570fd16 322 /* operands of same sign, result different sign */
1579a72e 323 CALL_FROM_TB1(do_raise_exception, EXCP_OVERFLOW);
6af0bf9c 324 }
5dc4b744 325 T0 = (int32_t)T0;
8f6f6026 326 FORCE_RET();
6af0bf9c
FB
327}
328
329void op_sub (void)
330{
5dc4b744 331 T0 = (int32_t)((int32_t)T0 - (int32_t)T1);
8f6f6026 332 FORCE_RET();
6af0bf9c
FB
333}
334
335void op_subo (void)
336{
337 target_ulong tmp;
338
c570fd16 339 tmp = (int32_t)T0;
6af0bf9c 340 T0 = (int32_t)T0 - (int32_t)T1;
76e050c2 341 if (((tmp ^ T1) & (tmp ^ T0)) >> 31) {
c570fd16 342 /* operands of different sign, first operand and result different sign */
1579a72e 343 CALL_FROM_TB1(do_raise_exception, EXCP_OVERFLOW);
6af0bf9c 344 }
5dc4b744 345 T0 = (int32_t)T0;
8f6f6026 346 FORCE_RET();
6af0bf9c
FB
347}
348
349void op_mul (void)
350{
5dc4b744 351 T0 = (int32_t)((int32_t)T0 * (int32_t)T1);
8f6f6026 352 FORCE_RET();
6af0bf9c
FB
353}
354
80c27194
TS
355#if HOST_LONG_BITS < 64
356void op_div (void)
357{
358 CALL_FROM_TB0(do_div);
8f6f6026 359 FORCE_RET();
80c27194
TS
360}
361#else
6af0bf9c
FB
362void op_div (void)
363{
364 if (T1 != 0) {
d0dc7dc3
TS
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);
6af0bf9c 367 }
8f6f6026 368 FORCE_RET();
6af0bf9c 369}
80c27194 370#endif
6af0bf9c
FB
371
372void op_divu (void)
c570fd16
TS
373{
374 if (T1 != 0) {
d0dc7dc3
TS
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);
c570fd16 377 }
8f6f6026 378 FORCE_RET();
c570fd16
TS
379}
380
d26bc211 381#if defined(TARGET_MIPS64)
c570fd16
TS
382/* Arithmetic */
383void op_dadd (void)
384{
385 T0 += T1;
8f6f6026 386 FORCE_RET();
c570fd16
TS
387}
388
389void op_daddo (void)
390{
391 target_long tmp;
392
393 tmp = T0;
394 T0 += T1;
395 if (((tmp ^ T1 ^ (-1)) & (T0 ^ T1)) >> 63) {
396 /* operands of same sign, result different sign */
1579a72e 397 CALL_FROM_TB1(do_raise_exception, EXCP_OVERFLOW);
c570fd16 398 }
8f6f6026 399 FORCE_RET();
c570fd16
TS
400}
401
402void op_dsub (void)
403{
404 T0 -= T1;
8f6f6026 405 FORCE_RET();
c570fd16
TS
406}
407
408void op_dsubo (void)
409{
410 target_long tmp;
411
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 */
1579a72e 416 CALL_FROM_TB1(do_raise_exception, EXCP_OVERFLOW);
c570fd16 417 }
8f6f6026 418 FORCE_RET();
c570fd16
TS
419}
420
421void op_dmul (void)
422{
423 T0 = (int64_t)T0 * (int64_t)T1;
8f6f6026 424 FORCE_RET();
c570fd16
TS
425}
426
c570fd16
TS
427/* Those might call libgcc functions. */
428void op_ddiv (void)
429{
430 do_ddiv();
8f6f6026 431 FORCE_RET();
c570fd16
TS
432}
433
80c27194 434#if TARGET_LONG_BITS > HOST_LONG_BITS
c570fd16
TS
435void op_ddivu (void)
436{
437 do_ddivu();
8f6f6026 438 FORCE_RET();
c570fd16
TS
439}
440#else
c570fd16 441void op_ddivu (void)
6af0bf9c
FB
442{
443 if (T1 != 0) {
d0dc7dc3
TS
444 env->LO[env->current_tc][0] = T0 / T1;
445 env->HI[env->current_tc][0] = T0 % T1;
6af0bf9c 446 }
8f6f6026 447 FORCE_RET();
6af0bf9c 448}
c570fd16 449#endif
d26bc211 450#endif /* TARGET_MIPS64 */
6af0bf9c
FB
451
452/* Logical */
453void op_and (void)
454{
455 T0 &= T1;
8f6f6026 456 FORCE_RET();
6af0bf9c
FB
457}
458
459void op_nor (void)
460{
461 T0 = ~(T0 | T1);
8f6f6026 462 FORCE_RET();
6af0bf9c
FB
463}
464
465void op_or (void)
466{
467 T0 |= T1;
8f6f6026 468 FORCE_RET();
6af0bf9c
FB
469}
470
471void op_xor (void)
472{
473 T0 ^= T1;
8f6f6026 474 FORCE_RET();
6af0bf9c
FB
475}
476
477void op_sll (void)
478{
5a63bcb2 479 T0 = (int32_t)((uint32_t)T0 << T1);
8f6f6026 480 FORCE_RET();
6af0bf9c
FB
481}
482
483void op_sra (void)
484{
5a63bcb2 485 T0 = (int32_t)((int32_t)T0 >> T1);
8f6f6026 486 FORCE_RET();
6af0bf9c
FB
487}
488
489void op_srl (void)
490{
5a63bcb2 491 T0 = (int32_t)((uint32_t)T0 >> T1);
8f6f6026 492 FORCE_RET();
6af0bf9c
FB
493}
494
7a387fff
TS
495void op_rotr (void)
496{
497 target_ulong tmp;
498
499 if (T1) {
5a63bcb2
TS
500 tmp = (int32_t)((uint32_t)T0 << (0x20 - T1));
501 T0 = (int32_t)((uint32_t)T0 >> T1) | tmp;
502 }
8f6f6026 503 FORCE_RET();
7a387fff
TS
504}
505
6af0bf9c
FB
506void op_sllv (void)
507{
5dc4b744 508 T0 = (int32_t)((uint32_t)T1 << ((uint32_t)T0 & 0x1F));
8f6f6026 509 FORCE_RET();
6af0bf9c
FB
510}
511
512void op_srav (void)
513{
5dc4b744 514 T0 = (int32_t)((int32_t)T1 >> (T0 & 0x1F));
8f6f6026 515 FORCE_RET();
6af0bf9c
FB
516}
517
518void op_srlv (void)
519{
5dc4b744 520 T0 = (int32_t)((uint32_t)T1 >> (T0 & 0x1F));
8f6f6026 521 FORCE_RET();
6af0bf9c
FB
522}
523
7a387fff
TS
524void op_rotrv (void)
525{
526 target_ulong tmp;
527
528 T0 &= 0x1F;
529 if (T0) {
5dc4b744
TS
530 tmp = (int32_t)((uint32_t)T1 << (0x20 - T0));
531 T0 = (int32_t)((uint32_t)T1 >> T0) | tmp;
7a387fff
TS
532 } else
533 T0 = T1;
8f6f6026 534 FORCE_RET();
7a387fff
TS
535}
536
6af0bf9c
FB
537void op_clo (void)
538{
05f778c8 539 T0 = clo32(T0);
8f6f6026 540 FORCE_RET();
6af0bf9c
FB
541}
542
543void op_clz (void)
544{
05f778c8 545 T0 = clz32(T0);
8f6f6026 546 FORCE_RET();
6af0bf9c
FB
547}
548
d26bc211 549#if defined(TARGET_MIPS64)
c570fd16
TS
550
551#if TARGET_LONG_BITS > HOST_LONG_BITS
552/* Those might call libgcc functions. */
553void op_dsll (void)
6af0bf9c 554{
c570fd16 555 CALL_FROM_TB0(do_dsll);
8f6f6026 556 FORCE_RET();
6af0bf9c
FB
557}
558
c570fd16 559void op_dsll32 (void)
6af0bf9c 560{
c570fd16 561 CALL_FROM_TB0(do_dsll32);
8f6f6026 562 FORCE_RET();
6af0bf9c
FB
563}
564
c570fd16 565void op_dsra (void)
6af0bf9c 566{
c570fd16 567 CALL_FROM_TB0(do_dsra);
8f6f6026 568 FORCE_RET();
6af0bf9c
FB
569}
570
c570fd16 571void op_dsra32 (void)
6af0bf9c 572{
c570fd16 573 CALL_FROM_TB0(do_dsra32);
8f6f6026 574 FORCE_RET();
6af0bf9c
FB
575}
576
c570fd16 577void op_dsrl (void)
6af0bf9c 578{
c570fd16 579 CALL_FROM_TB0(do_dsrl);
8f6f6026 580 FORCE_RET();
c570fd16 581}
6af0bf9c 582
c570fd16
TS
583void op_dsrl32 (void)
584{
585 CALL_FROM_TB0(do_dsrl32);
8f6f6026 586 FORCE_RET();
6af0bf9c
FB
587}
588
c570fd16 589void op_drotr (void)
6af0bf9c 590{
c570fd16 591 CALL_FROM_TB0(do_drotr);
8f6f6026 592 FORCE_RET();
c570fd16 593}
6af0bf9c 594
c570fd16
TS
595void op_drotr32 (void)
596{
597 CALL_FROM_TB0(do_drotr32);
8f6f6026 598 FORCE_RET();
6af0bf9c
FB
599}
600
c570fd16 601void op_dsllv (void)
6af0bf9c 602{
c570fd16 603 CALL_FROM_TB0(do_dsllv);
8f6f6026 604 FORCE_RET();
c570fd16 605}
6af0bf9c 606
c570fd16
TS
607void op_dsrav (void)
608{
609 CALL_FROM_TB0(do_dsrav);
8f6f6026 610 FORCE_RET();
6af0bf9c
FB
611}
612
c570fd16 613void op_dsrlv (void)
6af0bf9c 614{
c570fd16 615 CALL_FROM_TB0(do_dsrlv);
8f6f6026 616 FORCE_RET();
c570fd16 617}
6af0bf9c 618
c570fd16
TS
619void op_drotrv (void)
620{
621 CALL_FROM_TB0(do_drotrv);
8f6f6026 622 FORCE_RET();
6af0bf9c 623}
c570fd16 624
05f778c8
TS
625void op_dclo (void)
626{
627 CALL_FROM_TB0(do_dclo);
8f6f6026 628 FORCE_RET();
05f778c8
TS
629}
630
631void op_dclz (void)
632{
633 CALL_FROM_TB0(do_dclz);
8f6f6026 634 FORCE_RET();
05f778c8
TS
635}
636
c570fd16
TS
637#else /* TARGET_LONG_BITS > HOST_LONG_BITS */
638
639void op_dsll (void)
640{
641 T0 = T0 << T1;
8f6f6026 642 FORCE_RET();
c570fd16
TS
643}
644
645void op_dsll32 (void)
646{
647 T0 = T0 << (T1 + 32);
8f6f6026 648 FORCE_RET();
c570fd16
TS
649}
650
651void op_dsra (void)
652{
653 T0 = (int64_t)T0 >> T1;
8f6f6026 654 FORCE_RET();
c570fd16
TS
655}
656
657void op_dsra32 (void)
658{
659 T0 = (int64_t)T0 >> (T1 + 32);
8f6f6026 660 FORCE_RET();
c570fd16
TS
661}
662
663void op_dsrl (void)
664{
665 T0 = T0 >> T1;
8f6f6026 666 FORCE_RET();
c570fd16
TS
667}
668
669void op_dsrl32 (void)
670{
671 T0 = T0 >> (T1 + 32);
8f6f6026 672 FORCE_RET();
c570fd16
TS
673}
674
675void op_drotr (void)
676{
677 target_ulong tmp;
678
679 if (T1) {
c6d6dd7c
TS
680 tmp = T0 << (0x40 - T1);
681 T0 = (T0 >> T1) | tmp;
5a63bcb2 682 }
8f6f6026 683 FORCE_RET();
c570fd16
TS
684}
685
686void op_drotr32 (void)
687{
688 target_ulong tmp;
689
c6d6dd7c
TS
690 tmp = T0 << (0x40 - (32 + T1));
691 T0 = (T0 >> (32 + T1)) | tmp;
8f6f6026 692 FORCE_RET();
c570fd16
TS
693}
694
695void op_dsllv (void)
696{
697 T0 = T1 << (T0 & 0x3F);
8f6f6026 698 FORCE_RET();
c570fd16
TS
699}
700
701void op_dsrav (void)
702{
703 T0 = (int64_t)T1 >> (T0 & 0x3F);
8f6f6026 704 FORCE_RET();
c570fd16
TS
705}
706
707void op_dsrlv (void)
708{
709 T0 = T1 >> (T0 & 0x3F);
8f6f6026 710 FORCE_RET();
c570fd16
TS
711}
712
713void op_drotrv (void)
714{
715 target_ulong tmp;
716
717 T0 &= 0x3F;
718 if (T0) {
c6d6dd7c
TS
719 tmp = T1 << (0x40 - T0);
720 T0 = (T1 >> T0) | tmp;
c570fd16 721 } else
c6d6dd7c 722 T0 = T1;
8f6f6026 723 FORCE_RET();
c570fd16 724}
c570fd16
TS
725
726void op_dclo (void)
727{
05f778c8 728 T0 = clo64(T0);
8f6f6026 729 FORCE_RET();
c570fd16
TS
730}
731
732void op_dclz (void)
733{
05f778c8 734 T0 = clz64(T0);
8f6f6026 735 FORCE_RET();
c570fd16 736}
05f778c8 737#endif /* TARGET_LONG_BITS > HOST_LONG_BITS */
d26bc211 738#endif /* TARGET_MIPS64 */
c570fd16
TS
739
740/* 64 bits arithmetic */
741#if TARGET_LONG_BITS > HOST_LONG_BITS
6af0bf9c
FB
742void op_mult (void)
743{
744 CALL_FROM_TB0(do_mult);
8f6f6026 745 FORCE_RET();
6af0bf9c
FB
746}
747
748void op_multu (void)
749{
750 CALL_FROM_TB0(do_multu);
8f6f6026 751 FORCE_RET();
6af0bf9c
FB
752}
753
754void op_madd (void)
755{
756 CALL_FROM_TB0(do_madd);
8f6f6026 757 FORCE_RET();
6af0bf9c
FB
758}
759
760void op_maddu (void)
761{
762 CALL_FROM_TB0(do_maddu);
8f6f6026 763 FORCE_RET();
6af0bf9c
FB
764}
765
766void op_msub (void)
767{
768 CALL_FROM_TB0(do_msub);
8f6f6026 769 FORCE_RET();
6af0bf9c
FB
770}
771
772void op_msubu (void)
773{
774 CALL_FROM_TB0(do_msubu);
8f6f6026 775 FORCE_RET();
6af0bf9c 776}
c570fd16 777
e9c71dd1
TS
778/* Multiplication variants of the vr54xx. */
779void op_muls (void)
780{
781 CALL_FROM_TB0(do_muls);
782 FORCE_RET();
783}
784
785void op_mulsu (void)
786{
787 CALL_FROM_TB0(do_mulsu);
788 FORCE_RET();
789}
790
791void op_macc (void)
792{
793 CALL_FROM_TB0(do_macc);
794 FORCE_RET();
795}
796
797void op_macchi (void)
798{
799 CALL_FROM_TB0(do_macchi);
800 FORCE_RET();
801}
802
803void op_maccu (void)
804{
805 CALL_FROM_TB0(do_maccu);
806 FORCE_RET();
807}
808void op_macchiu (void)
809{
810 CALL_FROM_TB0(do_macchiu);
811 FORCE_RET();
812}
813
814void op_msac (void)
815{
816 CALL_FROM_TB0(do_msac);
817 FORCE_RET();
818}
819
820void op_msachi (void)
821{
822 CALL_FROM_TB0(do_msachi);
823 FORCE_RET();
824}
825
826void op_msacu (void)
827{
828 CALL_FROM_TB0(do_msacu);
829 FORCE_RET();
830}
831
832void op_msachiu (void)
833{
834 CALL_FROM_TB0(do_msachiu);
835 FORCE_RET();
836}
837
838void op_mulhi (void)
839{
840 CALL_FROM_TB0(do_mulhi);
841 FORCE_RET();
842}
843
844void op_mulhiu (void)
845{
846 CALL_FROM_TB0(do_mulhiu);
847 FORCE_RET();
848}
849
850void op_mulshi (void)
851{
852 CALL_FROM_TB0(do_mulshi);
853 FORCE_RET();
854}
855
856void op_mulshiu (void)
857{
858 CALL_FROM_TB0(do_mulshiu);
859 FORCE_RET();
860}
861
c570fd16
TS
862#else /* TARGET_LONG_BITS > HOST_LONG_BITS */
863
aa343735 864static always_inline uint64_t get_HILO (void)
c570fd16 865{
d0dc7dc3
TS
866 return ((uint64_t)env->HI[env->current_tc][0] << 32) |
867 ((uint64_t)(uint32_t)env->LO[env->current_tc][0]);
c570fd16
TS
868}
869
aa343735 870static always_inline void set_HILO (uint64_t HILO)
c570fd16 871{
d0dc7dc3
TS
872 env->LO[env->current_tc][0] = (int32_t)(HILO & 0xFFFFFFFF);
873 env->HI[env->current_tc][0] = (int32_t)(HILO >> 32);
c570fd16
TS
874}
875
e9c71dd1
TS
876static always_inline void set_HIT0_LO (uint64_t HILO)
877{
d0dc7dc3
TS
878 env->LO[env->current_tc][0] = (int32_t)(HILO & 0xFFFFFFFF);
879 T0 = env->HI[env->current_tc][0] = (int32_t)(HILO >> 32);
e9c71dd1
TS
880}
881
882static always_inline void set_HI_LOT0 (uint64_t HILO)
883{
d0dc7dc3
TS
884 T0 = env->LO[env->current_tc][0] = (int32_t)(HILO & 0xFFFFFFFF);
885 env->HI[env->current_tc][0] = (int32_t)(HILO >> 32);
e9c71dd1
TS
886}
887
c570fd16
TS
888void op_mult (void)
889{
890 set_HILO((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
8f6f6026 891 FORCE_RET();
c570fd16
TS
892}
893
894void op_multu (void)
895{
896 set_HILO((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
8f6f6026 897 FORCE_RET();
c570fd16
TS
898}
899
900void op_madd (void)
901{
902 int64_t tmp;
903
904 tmp = ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
905 set_HILO((int64_t)get_HILO() + tmp);
8f6f6026 906 FORCE_RET();
c570fd16
TS
907}
908
909void op_maddu (void)
910{
911 uint64_t tmp;
912
913 tmp = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
914 set_HILO(get_HILO() + tmp);
8f6f6026 915 FORCE_RET();
c570fd16
TS
916}
917
918void op_msub (void)
919{
920 int64_t tmp;
921
922 tmp = ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
923 set_HILO((int64_t)get_HILO() - tmp);
8f6f6026 924 FORCE_RET();
c570fd16
TS
925}
926
927void op_msubu (void)
928{
929 uint64_t tmp;
930
931 tmp = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
932 set_HILO(get_HILO() - tmp);
8f6f6026 933 FORCE_RET();
c570fd16 934}
e9c71dd1
TS
935
936/* Multiplication variants of the vr54xx. */
937void op_muls (void)
938{
939 set_HI_LOT0(0 - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
940 FORCE_RET();
941}
942
943void op_mulsu (void)
944{
945 set_HI_LOT0(0 - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
946 FORCE_RET();
947}
948
949void op_macc (void)
950{
951 set_HI_LOT0(get_HILO() + ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
952 FORCE_RET();
953}
954
955void op_macchi (void)
956{
957 set_HIT0_LO(get_HILO() + ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
958 FORCE_RET();
959}
960
961void op_maccu (void)
962{
963 set_HI_LOT0(get_HILO() + ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
964 FORCE_RET();
965}
966
967void op_macchiu (void)
968{
969 set_HIT0_LO(get_HILO() + ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
970 FORCE_RET();
971}
972
973void op_msac (void)
974{
975 set_HI_LOT0(get_HILO() - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
976 FORCE_RET();
977}
978
979void op_msachi (void)
980{
981 set_HIT0_LO(get_HILO() - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
982 FORCE_RET();
983}
984
985void op_msacu (void)
986{
987 set_HI_LOT0(get_HILO() - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
988 FORCE_RET();
989}
990
991void op_msachiu (void)
992{
993 set_HIT0_LO(get_HILO() - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
994 FORCE_RET();
995}
996
997void op_mulhi (void)
998{
999 set_HIT0_LO((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
1000 FORCE_RET();
1001}
1002
1003void op_mulhiu (void)
1004{
1005 set_HIT0_LO((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
1006 FORCE_RET();
1007}
1008
1009void op_mulshi (void)
1010{
1011 set_HIT0_LO(0 - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
1012 FORCE_RET();
1013}
1014
1015void op_mulshiu (void)
1016{
1017 set_HIT0_LO(0 - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
1018 FORCE_RET();
1019}
1020
c570fd16
TS
1021#endif /* TARGET_LONG_BITS > HOST_LONG_BITS */
1022
d26bc211 1023#if defined(TARGET_MIPS64)
c570fd16
TS
1024void op_dmult (void)
1025{
d0dc7dc3 1026 CALL_FROM_TB4(muls64, &(env->LO[env->current_tc][0]), &(env->HI[env->current_tc][0]), T0, T1);
8f6f6026 1027 FORCE_RET();
c570fd16
TS
1028}
1029
1030void op_dmultu (void)
1031{
d0dc7dc3 1032 CALL_FROM_TB4(mulu64, &(env->LO[env->current_tc][0]), &(env->HI[env->current_tc][0]), T0, T1);
8f6f6026 1033 FORCE_RET();
c570fd16 1034}
6af0bf9c
FB
1035#endif
1036
1037/* Conditional moves */
1038void op_movn (void)
1039{
1040 if (T1 != 0)
d0dc7dc3 1041 env->gpr[env->current_tc][PARAM1] = T0;
8f6f6026 1042 FORCE_RET();
6af0bf9c
FB
1043}
1044
1045void op_movz (void)
1046{
1047 if (T1 == 0)
d0dc7dc3 1048 env->gpr[env->current_tc][PARAM1] = T0;
8f6f6026 1049 FORCE_RET();
6af0bf9c
FB
1050}
1051
7a387fff
TS
1052void op_movf (void)
1053{
ead9360e 1054 if (!(env->fpu->fcr31 & PARAM1))
5a5012ec 1055 T0 = T1;
8f6f6026 1056 FORCE_RET();
7a387fff
TS
1057}
1058
1059void op_movt (void)
1060{
ead9360e 1061 if (env->fpu->fcr31 & PARAM1)
5a5012ec 1062 T0 = T1;
8f6f6026 1063 FORCE_RET();
7a387fff
TS
1064}
1065
6af0bf9c
FB
1066/* Tests */
1067#define OP_COND(name, cond) \
1068void glue(op_, name) (void) \
1069{ \
1070 if (cond) { \
1071 T0 = 1; \
1072 } else { \
1073 T0 = 0; \
1074 } \
8f6f6026 1075 FORCE_RET(); \
6af0bf9c
FB
1076}
1077
1078OP_COND(eq, T0 == T1);
1079OP_COND(ne, T0 != T1);
f469b9db 1080OP_COND(ge, (target_long)T0 >= (target_long)T1);
6af0bf9c 1081OP_COND(geu, T0 >= T1);
f469b9db 1082OP_COND(lt, (target_long)T0 < (target_long)T1);
6af0bf9c 1083OP_COND(ltu, T0 < T1);
f469b9db
TS
1084OP_COND(gez, (target_long)T0 >= 0);
1085OP_COND(gtz, (target_long)T0 > 0);
1086OP_COND(lez, (target_long)T0 <= 0);
1087OP_COND(ltz, (target_long)T0 < 0);
6af0bf9c 1088
7a387fff 1089/* Branches */
6af0bf9c
FB
1090/* Branch to register */
1091void op_save_breg_target (void)
1092{
39454628 1093 env->btarget = T1;
8f6f6026 1094 FORCE_RET();
6af0bf9c
FB
1095}
1096
1097void op_breg (void)
1098{
39454628 1099 env->PC[env->current_tc] = env->btarget;
8f6f6026 1100 FORCE_RET();
6af0bf9c
FB
1101}
1102
6af0bf9c
FB
1103void op_save_btarget (void)
1104{
1105 env->btarget = PARAM1;
8f6f6026 1106 FORCE_RET();
6af0bf9c
FB
1107}
1108
d26bc211 1109#if defined(TARGET_MIPS64)
9b9e4393
TS
1110void op_save_btarget64 (void)
1111{
1112 env->btarget = ((uint64_t)PARAM1 << 32) | (uint32_t)PARAM2;
8f6f6026 1113 FORCE_RET();
9b9e4393
TS
1114}
1115#endif
1116
6af0bf9c
FB
1117/* Conditional branch */
1118void op_set_bcond (void)
1119{
39454628 1120 env->bcond = T0;
8f6f6026 1121 FORCE_RET();
6af0bf9c
FB
1122}
1123
39454628 1124void op_jnz_bcond (void)
6af0bf9c 1125{
39454628 1126 if (env->bcond)
c53be334 1127 GOTO_LABEL_PARAM(1);
8f6f6026 1128 FORCE_RET();
6af0bf9c
FB
1129}
1130
1131/* CP0 functions */
873eb012 1132void op_mfc0_index (void)
6af0bf9c 1133{
9c2149c8 1134 T0 = env->CP0_Index;
8f6f6026 1135 FORCE_RET();
873eb012
TS
1136}
1137
ead9360e
TS
1138void op_mfc0_mvpcontrol (void)
1139{
1140 T0 = env->mvp->CP0_MVPControl;
8f6f6026 1141 FORCE_RET();
ead9360e
TS
1142}
1143
1144void op_mfc0_mvpconf0 (void)
1145{
1146 T0 = env->mvp->CP0_MVPConf0;
8f6f6026 1147 FORCE_RET();
ead9360e
TS
1148}
1149
1150void op_mfc0_mvpconf1 (void)
1151{
1152 T0 = env->mvp->CP0_MVPConf1;
8f6f6026 1153 FORCE_RET();
ead9360e
TS
1154}
1155
873eb012
TS
1156void op_mfc0_random (void)
1157{
1158 CALL_FROM_TB0(do_mfc0_random);
8f6f6026 1159 FORCE_RET();
873eb012
TS
1160}
1161
ead9360e
TS
1162void op_mfc0_vpecontrol (void)
1163{
1164 T0 = env->CP0_VPEControl;
8f6f6026 1165 FORCE_RET();
ead9360e
TS
1166}
1167
1168void op_mfc0_vpeconf0 (void)
1169{
1170 T0 = env->CP0_VPEConf0;
8f6f6026 1171 FORCE_RET();
ead9360e
TS
1172}
1173
1174void op_mfc0_vpeconf1 (void)
1175{
1176 T0 = env->CP0_VPEConf1;
8f6f6026 1177 FORCE_RET();
ead9360e
TS
1178}
1179
1180void op_mfc0_yqmask (void)
1181{
1182 T0 = env->CP0_YQMask;
8f6f6026 1183 FORCE_RET();
ead9360e
TS
1184}
1185
1186void op_mfc0_vpeschedule (void)
1187{
1188 T0 = env->CP0_VPESchedule;
8f6f6026 1189 FORCE_RET();
ead9360e
TS
1190}
1191
1192void op_mfc0_vpeschefback (void)
1193{
1194 T0 = env->CP0_VPEScheFBack;
8f6f6026 1195 FORCE_RET();
ead9360e
TS
1196}
1197
1198void op_mfc0_vpeopt (void)
1199{
1200 T0 = env->CP0_VPEOpt;
8f6f6026 1201 FORCE_RET();
ead9360e
TS
1202}
1203
873eb012
TS
1204void op_mfc0_entrylo0 (void)
1205{
9c2149c8 1206 T0 = (int32_t)env->CP0_EntryLo0;
8f6f6026 1207 FORCE_RET();
873eb012
TS
1208}
1209
ead9360e
TS
1210void op_mfc0_tcstatus (void)
1211{
1212 T0 = env->CP0_TCStatus[env->current_tc];
8f6f6026 1213 FORCE_RET();
ead9360e
TS
1214}
1215
1216void op_mftc0_tcstatus(void)
1217{
1218 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1219
1220 T0 = env->CP0_TCStatus[other_tc];
8f6f6026 1221 FORCE_RET();
ead9360e
TS
1222}
1223
1224void op_mfc0_tcbind (void)
1225{
1226 T0 = env->CP0_TCBind[env->current_tc];
8f6f6026 1227 FORCE_RET();
ead9360e
TS
1228}
1229
1230void op_mftc0_tcbind(void)
1231{
1232 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1233
1234 T0 = env->CP0_TCBind[other_tc];
8f6f6026 1235 FORCE_RET();
ead9360e
TS
1236}
1237
1238void op_mfc0_tcrestart (void)
1239{
1240 T0 = env->PC[env->current_tc];
8f6f6026 1241 FORCE_RET();
ead9360e
TS
1242}
1243
1244void op_mftc0_tcrestart(void)
1245{
1246 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1247
1248 T0 = env->PC[other_tc];
8f6f6026 1249 FORCE_RET();
ead9360e
TS
1250}
1251
1252void op_mfc0_tchalt (void)
1253{
1254 T0 = env->CP0_TCHalt[env->current_tc];
8f6f6026 1255 FORCE_RET();
ead9360e
TS
1256}
1257
1258void op_mftc0_tchalt(void)
1259{
1260 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1261
1262 T0 = env->CP0_TCHalt[other_tc];
8f6f6026 1263 FORCE_RET();
ead9360e
TS
1264}
1265
1266void op_mfc0_tccontext (void)
1267{
1268 T0 = env->CP0_TCContext[env->current_tc];
8f6f6026 1269 FORCE_RET();
ead9360e
TS
1270}
1271
1272void op_mftc0_tccontext(void)
1273{
1274 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1275
1276 T0 = env->CP0_TCContext[other_tc];
8f6f6026 1277 FORCE_RET();
ead9360e
TS
1278}
1279
1280void op_mfc0_tcschedule (void)
1281{
1282 T0 = env->CP0_TCSchedule[env->current_tc];
8f6f6026 1283 FORCE_RET();
ead9360e
TS
1284}
1285
1286void op_mftc0_tcschedule(void)
1287{
1288 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1289
1290 T0 = env->CP0_TCSchedule[other_tc];
8f6f6026 1291 FORCE_RET();
ead9360e
TS
1292}
1293
1294void op_mfc0_tcschefback (void)
1295{
1296 T0 = env->CP0_TCScheFBack[env->current_tc];
8f6f6026 1297 FORCE_RET();
ead9360e
TS
1298}
1299
1300void op_mftc0_tcschefback(void)
1301{
1302 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1303
1304 T0 = env->CP0_TCScheFBack[other_tc];
8f6f6026 1305 FORCE_RET();
ead9360e
TS
1306}
1307
873eb012
TS
1308void op_mfc0_entrylo1 (void)
1309{
9c2149c8 1310 T0 = (int32_t)env->CP0_EntryLo1;
8f6f6026 1311 FORCE_RET();
873eb012
TS
1312}
1313
1314void op_mfc0_context (void)
1315{
9c2149c8 1316 T0 = (int32_t)env->CP0_Context;
8f6f6026 1317 FORCE_RET();
873eb012
TS
1318}
1319
1320void op_mfc0_pagemask (void)
1321{
9c2149c8 1322 T0 = env->CP0_PageMask;
8f6f6026 1323 FORCE_RET();
873eb012
TS
1324}
1325
7a387fff
TS
1326void op_mfc0_pagegrain (void)
1327{
9c2149c8 1328 T0 = env->CP0_PageGrain;
8f6f6026 1329 FORCE_RET();
7a387fff
TS
1330}
1331
873eb012
TS
1332void op_mfc0_wired (void)
1333{
9c2149c8 1334 T0 = env->CP0_Wired;
8f6f6026 1335 FORCE_RET();
873eb012
TS
1336}
1337
ead9360e
TS
1338void op_mfc0_srsconf0 (void)
1339{
1340 T0 = env->CP0_SRSConf0;
8f6f6026 1341 FORCE_RET();
ead9360e
TS
1342}
1343
1344void op_mfc0_srsconf1 (void)
1345{
1346 T0 = env->CP0_SRSConf1;
8f6f6026 1347 FORCE_RET();
ead9360e
TS
1348}
1349
1350void op_mfc0_srsconf2 (void)
1351{
1352 T0 = env->CP0_SRSConf2;
8f6f6026 1353 FORCE_RET();
ead9360e
TS
1354}
1355
1356void op_mfc0_srsconf3 (void)
1357{
1358 T0 = env->CP0_SRSConf3;
8f6f6026 1359 FORCE_RET();
ead9360e
TS
1360}
1361
1362void op_mfc0_srsconf4 (void)
1363{
1364 T0 = env->CP0_SRSConf4;
8f6f6026 1365 FORCE_RET();
ead9360e
TS
1366}
1367
7a387fff
TS
1368void op_mfc0_hwrena (void)
1369{
9c2149c8 1370 T0 = env->CP0_HWREna;
8f6f6026 1371 FORCE_RET();
7a387fff
TS
1372}
1373
873eb012
TS
1374void op_mfc0_badvaddr (void)
1375{
9c2149c8 1376 T0 = (int32_t)env->CP0_BadVAddr;
8f6f6026 1377 FORCE_RET();
873eb012
TS
1378}
1379
1380void op_mfc0_count (void)
1381{
1382 CALL_FROM_TB0(do_mfc0_count);
8f6f6026 1383 FORCE_RET();
873eb012
TS
1384}
1385
1386void op_mfc0_entryhi (void)
1387{
9c2149c8 1388 T0 = (int32_t)env->CP0_EntryHi;
8f6f6026 1389 FORCE_RET();
873eb012
TS
1390}
1391
ead9360e
TS
1392void op_mftc0_entryhi(void)
1393{
1394 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1395
1396 T0 = (env->CP0_EntryHi & ~0xff) | (env->CP0_TCStatus[other_tc] & 0xff);
8f6f6026 1397 FORCE_RET();
ead9360e
TS
1398}
1399
873eb012
TS
1400void op_mfc0_compare (void)
1401{
9c2149c8 1402 T0 = env->CP0_Compare;
8f6f6026 1403 FORCE_RET();
873eb012
TS
1404}
1405
1406void op_mfc0_status (void)
1407{
9c2149c8 1408 T0 = env->CP0_Status;
8f6f6026 1409 FORCE_RET();
873eb012
TS
1410}
1411
ead9360e
TS
1412void op_mftc0_status(void)
1413{
1414 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1415 uint32_t tcstatus = env->CP0_TCStatus[other_tc];
1416
1417 T0 = env->CP0_Status & ~0xf1000018;
1418 T0 |= tcstatus & (0xf << CP0TCSt_TCU0);
1419 T0 |= (tcstatus & (1 << CP0TCSt_TMX)) >> (CP0TCSt_TMX - CP0St_MX);
623a930e 1420 T0 |= (tcstatus & (0x3 << CP0TCSt_TKSU)) >> (CP0TCSt_TKSU - CP0St_KSU);
8f6f6026 1421 FORCE_RET();
ead9360e
TS
1422}
1423
7a387fff
TS
1424void op_mfc0_intctl (void)
1425{
9c2149c8 1426 T0 = env->CP0_IntCtl;
8f6f6026 1427 FORCE_RET();
7a387fff
TS
1428}
1429
1430void op_mfc0_srsctl (void)
1431{
9c2149c8 1432 T0 = env->CP0_SRSCtl;
8f6f6026 1433 FORCE_RET();
9c2149c8
TS
1434}
1435
1436void op_mfc0_srsmap (void)
1437{
1438 T0 = env->CP0_SRSMap;
8f6f6026 1439 FORCE_RET();
7a387fff
TS
1440}
1441
873eb012
TS
1442void op_mfc0_cause (void)
1443{
9c2149c8 1444 T0 = env->CP0_Cause;
8f6f6026 1445 FORCE_RET();
873eb012
TS
1446}
1447
1448void op_mfc0_epc (void)
1449{
9c2149c8 1450 T0 = (int32_t)env->CP0_EPC;
8f6f6026 1451 FORCE_RET();
873eb012
TS
1452}
1453
1454void op_mfc0_prid (void)
1455{
9c2149c8 1456 T0 = env->CP0_PRid;
8f6f6026 1457 FORCE_RET();
873eb012
TS
1458}
1459
7a387fff
TS
1460void op_mfc0_ebase (void)
1461{
b29a0341 1462 T0 = env->CP0_EBase;
8f6f6026 1463 FORCE_RET();
7a387fff
TS
1464}
1465
873eb012
TS
1466void op_mfc0_config0 (void)
1467{
9c2149c8 1468 T0 = env->CP0_Config0;
8f6f6026 1469 FORCE_RET();
873eb012
TS
1470}
1471
1472void op_mfc0_config1 (void)
1473{
9c2149c8 1474 T0 = env->CP0_Config1;
8f6f6026 1475 FORCE_RET();
873eb012
TS
1476}
1477
7a387fff
TS
1478void op_mfc0_config2 (void)
1479{
9c2149c8 1480 T0 = env->CP0_Config2;
8f6f6026 1481 FORCE_RET();
7a387fff
TS
1482}
1483
1484void op_mfc0_config3 (void)
1485{
9c2149c8 1486 T0 = env->CP0_Config3;
8f6f6026 1487 FORCE_RET();
7a387fff
TS
1488}
1489
e397ee33
TS
1490void op_mfc0_config6 (void)
1491{
1492 T0 = env->CP0_Config6;
8f6f6026 1493 FORCE_RET();
e397ee33
TS
1494}
1495
1496void op_mfc0_config7 (void)
1497{
1498 T0 = env->CP0_Config7;
8f6f6026 1499 FORCE_RET();
e397ee33
TS
1500}
1501
873eb012
TS
1502void op_mfc0_lladdr (void)
1503{
9c2149c8 1504 T0 = (int32_t)env->CP0_LLAddr >> 4;
8f6f6026 1505 FORCE_RET();
873eb012
TS
1506}
1507
fd88b6ab 1508void op_mfc0_watchlo (void)
873eb012 1509{
fd88b6ab 1510 T0 = (int32_t)env->CP0_WatchLo[PARAM1];
8f6f6026 1511 FORCE_RET();
873eb012
TS
1512}
1513
fd88b6ab 1514void op_mfc0_watchhi (void)
873eb012 1515{
fd88b6ab 1516 T0 = env->CP0_WatchHi[PARAM1];
8f6f6026 1517 FORCE_RET();
873eb012
TS
1518}
1519
7a387fff
TS
1520void op_mfc0_xcontext (void)
1521{
9c2149c8 1522 T0 = (int32_t)env->CP0_XContext;
8f6f6026 1523 FORCE_RET();
7a387fff
TS
1524}
1525
1526void op_mfc0_framemask (void)
1527{
1528 T0 = env->CP0_Framemask;
8f6f6026 1529 FORCE_RET();
7a387fff
TS
1530}
1531
873eb012
TS
1532void op_mfc0_debug (void)
1533{
9c2149c8 1534 T0 = env->CP0_Debug;
873eb012
TS
1535 if (env->hflags & MIPS_HFLAG_DM)
1536 T0 |= 1 << CP0DB_DM;
8f6f6026 1537 FORCE_RET();
873eb012
TS
1538}
1539
ead9360e
TS
1540void op_mftc0_debug(void)
1541{
1542 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1543
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)));
8f6f6026 1548 FORCE_RET();
ead9360e
TS
1549}
1550
873eb012
TS
1551void op_mfc0_depc (void)
1552{
9c2149c8 1553 T0 = (int32_t)env->CP0_DEPC;
8f6f6026 1554 FORCE_RET();
873eb012
TS
1555}
1556
7a387fff
TS
1557void op_mfc0_performance0 (void)
1558{
9c2149c8 1559 T0 = env->CP0_Performance0;
8f6f6026 1560 FORCE_RET();
7a387fff
TS
1561}
1562
873eb012
TS
1563void op_mfc0_taglo (void)
1564{
9c2149c8 1565 T0 = env->CP0_TagLo;
8f6f6026 1566 FORCE_RET();
873eb012
TS
1567}
1568
1569void op_mfc0_datalo (void)
1570{
9c2149c8 1571 T0 = env->CP0_DataLo;
8f6f6026 1572 FORCE_RET();
873eb012
TS
1573}
1574
7a387fff
TS
1575void op_mfc0_taghi (void)
1576{
9c2149c8 1577 T0 = env->CP0_TagHi;
8f6f6026 1578 FORCE_RET();
7a387fff
TS
1579}
1580
1581void op_mfc0_datahi (void)
1582{
9c2149c8 1583 T0 = env->CP0_DataHi;
8f6f6026 1584 FORCE_RET();
7a387fff
TS
1585}
1586
873eb012
TS
1587void op_mfc0_errorepc (void)
1588{
9c2149c8 1589 T0 = (int32_t)env->CP0_ErrorEPC;
8f6f6026 1590 FORCE_RET();
873eb012
TS
1591}
1592
1593void op_mfc0_desave (void)
1594{
9c2149c8 1595 T0 = env->CP0_DESAVE;
8f6f6026 1596 FORCE_RET();
6af0bf9c
FB
1597}
1598
8c0fdd85 1599void op_mtc0_index (void)
6af0bf9c 1600{
60445285
TS
1601 int num = 1;
1602 unsigned int tmp = env->tlb->nb_tlb;
1603
1604 do {
1605 tmp >>= 1;
1606 num <<= 1;
1607 } while (tmp);
1608 env->CP0_Index = (env->CP0_Index & 0x80000000) | (T0 & (num - 1));
8f6f6026 1609 FORCE_RET();
ead9360e
TS
1610}
1611
1612void op_mtc0_mvpcontrol (void)
1613{
1614 uint32_t mask = 0;
1615 uint32_t newval;
1616
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);
1623
1624 // TODO: Enable/disable shared TLB, enable/disable VPEs.
1625
1626 env->mvp->CP0_MVPControl = newval;
8f6f6026 1627 FORCE_RET();
ead9360e
TS
1628}
1629
1630void op_mtc0_vpecontrol (void)
1631{
1632 uint32_t mask;
1633 uint32_t newval;
1634
1635 mask = (1 << CP0VPECo_YSI) | (1 << CP0VPECo_GSI) |
1636 (1 << CP0VPECo_TE) | (0xff << CP0VPECo_TargTC);
1637 newval = (env->CP0_VPEControl & ~mask) | (T0 & mask);
1638
1639 /* Yield scheduler intercept not implemented. */
1640 /* Gating storage scheduler intercept not implemented. */
1641
1642 // TODO: Enable/disable TCs.
1643
1644 env->CP0_VPEControl = newval;
8f6f6026 1645 FORCE_RET();
ead9360e
TS
1646}
1647
1648void op_mtc0_vpeconf0 (void)
1649{
1650 uint32_t mask = 0;
1651 uint32_t newval;
1652
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);
1657 }
1658 newval = (env->CP0_VPEConf0 & ~mask) | (T0 & mask);
1659
1660 // TODO: TC exclusive handling due to ERL/EXL.
1661
1662 env->CP0_VPEConf0 = newval;
8f6f6026 1663 FORCE_RET();
ead9360e
TS
1664}
1665
1666void op_mtc0_vpeconf1 (void)
1667{
1668 uint32_t mask = 0;
1669 uint32_t newval;
1670
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);
1675
1676 /* UDI not implemented. */
1677 /* CP2 not implemented. */
1678
1679 // TODO: Handle FPU (CP1) binding.
1680
1681 env->CP0_VPEConf1 = newval;
8f6f6026 1682 FORCE_RET();
ead9360e
TS
1683}
1684
1685void op_mtc0_yqmask (void)
1686{
1687 /* Yield qualifier inputs not implemented. */
1688 env->CP0_YQMask = 0x00000000;
8f6f6026 1689 FORCE_RET();
ead9360e
TS
1690}
1691
1692void op_mtc0_vpeschedule (void)
1693{
1694 env->CP0_VPESchedule = T0;
8f6f6026 1695 FORCE_RET();
ead9360e
TS
1696}
1697
1698void op_mtc0_vpeschefback (void)
1699{
1700 env->CP0_VPEScheFBack = T0;
8f6f6026 1701 FORCE_RET();
ead9360e
TS
1702}
1703
1704void op_mtc0_vpeopt (void)
1705{
1706 env->CP0_VPEOpt = T0 & 0x0000ffff;
8f6f6026 1707 FORCE_RET();
8c0fdd85
TS
1708}
1709
1710void op_mtc0_entrylo0 (void)
1711{
6d35524c 1712 /* Large physaddr (PABITS) not implemented */
7a387fff 1713 /* 1k pages not implemented */
f1b0aa5d 1714 env->CP0_EntryLo0 = T0 & 0x3FFFFFFF;
8f6f6026 1715 FORCE_RET();
8c0fdd85
TS
1716}
1717
ead9360e
TS
1718void op_mtc0_tcstatus (void)
1719{
1720 uint32_t mask = env->CP0_TCStatus_rw_bitmask;
1721 uint32_t newval;
1722
1723 newval = (env->CP0_TCStatus[env->current_tc] & ~mask) | (T0 & mask);
1724
1725 // TODO: Sync with CP0_Status.
1726
1727 env->CP0_TCStatus[env->current_tc] = newval;
8f6f6026 1728 FORCE_RET();
ead9360e
TS
1729}
1730
1731void op_mttc0_tcstatus (void)
1732{
1733 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1734
1735 // TODO: Sync with CP0_Status.
1736
1737 env->CP0_TCStatus[other_tc] = T0;
8f6f6026 1738 FORCE_RET();
ead9360e
TS
1739}
1740
1741void op_mtc0_tcbind (void)
1742{
1743 uint32_t mask = (1 << CP0TCBd_TBE);
1744 uint32_t newval;
1745
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;
8f6f6026 1750 FORCE_RET();
ead9360e
TS
1751}
1752
1753void op_mttc0_tcbind (void)
1754{
1755 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1756 uint32_t mask = (1 << CP0TCBd_TBE);
1757 uint32_t newval;
1758
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;
8f6f6026 1763 FORCE_RET();
ead9360e
TS
1764}
1765
1766void op_mtc0_tcrestart (void)
1767{
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. */
8f6f6026 1772 FORCE_RET();
ead9360e
TS
1773}
1774
1775void op_mttc0_tcrestart (void)
1776{
1777 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1778
1779 env->PC[other_tc] = T0;
1780 env->CP0_TCStatus[other_tc] &= ~(1 << CP0TCSt_TDS);
1781 env->CP0_LLAddr = 0ULL;
1782 /* MIPS16 not implemented. */
8f6f6026 1783 FORCE_RET();
ead9360e
TS
1784}
1785
1786void op_mtc0_tchalt (void)
1787{
1788 env->CP0_TCHalt[env->current_tc] = T0 & 0x1;
1789
1790 // TODO: Halt TC / Restart (if allocated+active) TC.
1791
8f6f6026 1792 FORCE_RET();
ead9360e
TS
1793}
1794
1795void op_mttc0_tchalt (void)
1796{
1797 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1798
1799 // TODO: Halt TC / Restart (if allocated+active) TC.
1800
1801 env->CP0_TCHalt[other_tc] = T0;
8f6f6026 1802 FORCE_RET();
ead9360e
TS
1803}
1804
1805void op_mtc0_tccontext (void)
1806{
1807 env->CP0_TCContext[env->current_tc] = T0;
8f6f6026 1808 FORCE_RET();
ead9360e
TS
1809}
1810
1811void op_mttc0_tccontext (void)
1812{
1813 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1814
1815 env->CP0_TCContext[other_tc] = T0;
8f6f6026 1816 FORCE_RET();
ead9360e
TS
1817}
1818
1819void op_mtc0_tcschedule (void)
1820{
1821 env->CP0_TCSchedule[env->current_tc] = T0;
8f6f6026 1822 FORCE_RET();
ead9360e
TS
1823}
1824
1825void op_mttc0_tcschedule (void)
1826{
1827 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1828
1829 env->CP0_TCSchedule[other_tc] = T0;
8f6f6026 1830 FORCE_RET();
ead9360e
TS
1831}
1832
1833void op_mtc0_tcschefback (void)
1834{
1835 env->CP0_TCScheFBack[env->current_tc] = T0;
8f6f6026 1836 FORCE_RET();
ead9360e
TS
1837}
1838
1839void op_mttc0_tcschefback (void)
1840{
1841 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1842
1843 env->CP0_TCScheFBack[other_tc] = T0;
8f6f6026 1844 FORCE_RET();
ead9360e
TS
1845}
1846
8c0fdd85
TS
1847void op_mtc0_entrylo1 (void)
1848{
6d35524c 1849 /* Large physaddr (PABITS) not implemented */
7a387fff 1850 /* 1k pages not implemented */
f1b0aa5d 1851 env->CP0_EntryLo1 = T0 & 0x3FFFFFFF;
8f6f6026 1852 FORCE_RET();
8c0fdd85
TS
1853}
1854
1855void op_mtc0_context (void)
1856{
534ce69f 1857 env->CP0_Context = (env->CP0_Context & 0x007FFFFF) | (T0 & ~0x007FFFFF);
8f6f6026 1858 FORCE_RET();
8c0fdd85
TS
1859}
1860
1861void op_mtc0_pagemask (void)
1862{
7a387fff 1863 /* 1k pages not implemented */
f2e9ebef 1864 env->CP0_PageMask = T0 & (0x1FFFFFFF & (TARGET_PAGE_MASK << 1));
8f6f6026 1865 FORCE_RET();
7a387fff
TS
1866}
1867
1868void op_mtc0_pagegrain (void)
1869{
1870 /* SmartMIPS not implemented */
6d35524c 1871 /* Large physaddr (PABITS) not implemented */
7a387fff
TS
1872 /* 1k pages not implemented */
1873 env->CP0_PageGrain = 0;
8f6f6026 1874 FORCE_RET();
8c0fdd85
TS
1875}
1876
1877void op_mtc0_wired (void)
1878{
ead9360e 1879 env->CP0_Wired = T0 % env->tlb->nb_tlb;
8f6f6026 1880 FORCE_RET();
ead9360e
TS
1881}
1882
1883void op_mtc0_srsconf0 (void)
1884{
1885 env->CP0_SRSConf0 |= T0 & env->CP0_SRSConf0_rw_bitmask;
8f6f6026 1886 FORCE_RET();
ead9360e
TS
1887}
1888
1889void op_mtc0_srsconf1 (void)
1890{
1891 env->CP0_SRSConf1 |= T0 & env->CP0_SRSConf1_rw_bitmask;
8f6f6026 1892 FORCE_RET();
ead9360e
TS
1893}
1894
1895void op_mtc0_srsconf2 (void)
1896{
1897 env->CP0_SRSConf2 |= T0 & env->CP0_SRSConf2_rw_bitmask;
8f6f6026 1898 FORCE_RET();
ead9360e
TS
1899}
1900
1901void op_mtc0_srsconf3 (void)
1902{
1903 env->CP0_SRSConf3 |= T0 & env->CP0_SRSConf3_rw_bitmask;
8f6f6026 1904 FORCE_RET();
ead9360e
TS
1905}
1906
1907void op_mtc0_srsconf4 (void)
1908{
1909 env->CP0_SRSConf4 |= T0 & env->CP0_SRSConf4_rw_bitmask;
8f6f6026 1910 FORCE_RET();
7a387fff
TS
1911}
1912
1913void op_mtc0_hwrena (void)
1914{
1915 env->CP0_HWREna = T0 & 0x0000000F;
8f6f6026 1916 FORCE_RET();
8c0fdd85
TS
1917}
1918
1919void op_mtc0_count (void)
1920{
1921 CALL_FROM_TB2(cpu_mips_store_count, env, T0);
8f6f6026 1922 FORCE_RET();
8c0fdd85
TS
1923}
1924
1925void op_mtc0_entryhi (void)
1926{
0feef828 1927 target_ulong old, val;
8c0fdd85 1928
7a387fff 1929 /* 1k pages not implemented */
100ce988 1930 val = T0 & ((TARGET_PAGE_MASK << 1) | 0xFF);
d26bc211 1931#if defined(TARGET_MIPS64)
e034e2c3 1932 val &= env->SEGMask;
100ce988 1933#endif
8c0fdd85
TS
1934 old = env->CP0_EntryHi;
1935 env->CP0_EntryHi = val;
ead9360e
TS
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);
1939 }
8c0fdd85
TS
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);
8f6f6026 1943 FORCE_RET();
8c0fdd85
TS
1944}
1945
ead9360e
TS
1946void op_mttc0_entryhi(void)
1947{
1948 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1949
1950 env->CP0_EntryHi = (env->CP0_EntryHi & 0xff) | (T0 & ~0xff);
1951 env->CP0_TCStatus[other_tc] = (env->CP0_TCStatus[other_tc] & ~0xff) | (T0 & 0xff);
8f6f6026 1952 FORCE_RET();
ead9360e
TS
1953}
1954
8c0fdd85
TS
1955void op_mtc0_compare (void)
1956{
1957 CALL_FROM_TB2(cpu_mips_store_compare, env, T0);
8f6f6026 1958 FORCE_RET();
8c0fdd85
TS
1959}
1960
1961void op_mtc0_status (void)
1962{
4de9b249 1963 uint32_t val, old;
ead9360e 1964 uint32_t mask = env->CP0_Status_rw_bitmask;
8c0fdd85 1965
f1b0aa5d 1966 val = T0 & mask;
8c0fdd85 1967 old = env->CP0_Status;
5a5012ec 1968 env->CP0_Status = (env->CP0_Status & ~mask) | val;
08fa4bab 1969 CALL_FROM_TB1(compute_hflags, env);
f41c52f1
TS
1970 if (loglevel & CPU_LOG_EXEC)
1971 CALL_FROM_TB2(do_mtc0_status_debug, old, val);
4de9b249 1972 CALL_FROM_TB1(cpu_mips_update_irq, env);
8f6f6026 1973 FORCE_RET();
8c0fdd85
TS
1974}
1975
ead9360e
TS
1976void op_mttc0_status(void)
1977{
1978 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1979 uint32_t tcstatus = env->CP0_TCStatus[other_tc];
1980
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));
623a930e 1984 tcstatus = (tcstatus & ~(0x3 << CP0TCSt_TKSU)) | ((T0 & (0x3 << CP0St_KSU)) << (CP0TCSt_TKSU - CP0St_KSU));
ead9360e 1985 env->CP0_TCStatus[other_tc] = tcstatus;
8f6f6026 1986 FORCE_RET();
ead9360e
TS
1987}
1988
7a387fff
TS
1989void op_mtc0_intctl (void)
1990{
42532189
TS
1991 /* vectored interrupts not implemented, no performance counters. */
1992 env->CP0_IntCtl = (env->CP0_IntCtl & ~0x000002e0) | (T0 & 0x000002e0);
8f6f6026 1993 FORCE_RET();
7a387fff
TS
1994}
1995
1996void op_mtc0_srsctl (void)
1997{
ead9360e
TS
1998 uint32_t mask = (0xf << CP0SRSCtl_ESS) | (0xf << CP0SRSCtl_PSS);
1999 env->CP0_SRSCtl = (env->CP0_SRSCtl & ~mask) | (T0 & mask);
8f6f6026 2000 FORCE_RET();
7a387fff
TS
2001}
2002
9c2149c8
TS
2003void op_mtc0_srsmap (void)
2004{
ead9360e 2005 env->CP0_SRSMap = T0;
8f6f6026 2006 FORCE_RET();
9c2149c8
TS
2007}
2008
8c0fdd85
TS
2009void op_mtc0_cause (void)
2010{
39d51eb8 2011 uint32_t mask = 0x00C00300;
42532189 2012 uint32_t old = env->CP0_Cause;
39d51eb8 2013
e189e748 2014 if (env->insn_flags & ISA_MIPS32R2)
39d51eb8
TS
2015 mask |= 1 << CP0Ca_DC;
2016
e58c8ba5 2017 env->CP0_Cause = (env->CP0_Cause & ~mask) | (T0 & mask);
8c0fdd85 2018
42532189
TS
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);
2024 }
2025
4de9b249
TS
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);
8c0fdd85 2030 }
8f6f6026 2031 FORCE_RET();
8c0fdd85
TS
2032}
2033
2034void op_mtc0_epc (void)
2035{
f1b0aa5d 2036 env->CP0_EPC = T0;
8f6f6026 2037 FORCE_RET();
8c0fdd85
TS
2038}
2039
7a387fff
TS
2040void op_mtc0_ebase (void)
2041{
2042 /* vectored interrupts not implemented */
2043 /* Multi-CPU not implemented */
b29a0341 2044 env->CP0_EBase = 0x80000000 | (T0 & 0x3FFFF000);
8f6f6026 2045 FORCE_RET();
7a387fff
TS
2046}
2047
8c0fdd85
TS
2048void op_mtc0_config0 (void)
2049{
7bfd934a 2050 env->CP0_Config0 = (env->CP0_Config0 & 0x81FFFFF8) | (T0 & 0x00000007);
8f6f6026 2051 FORCE_RET();
8c0fdd85
TS
2052}
2053
7a387fff
TS
2054void op_mtc0_config2 (void)
2055{
2056 /* tertiary/secondary caches not implemented */
2057 env->CP0_Config2 = (env->CP0_Config2 & 0x8FFF0FFF);
8f6f6026 2058 FORCE_RET();
7a387fff
TS
2059}
2060
fd88b6ab 2061void op_mtc0_watchlo (void)
8c0fdd85 2062{
4e7a4a4e
TS
2063 /* Watch exceptions for instructions, data loads, data stores
2064 not implemented. */
fd88b6ab 2065 env->CP0_WatchLo[PARAM1] = (T0 & ~0x7);
8f6f6026 2066 FORCE_RET();
8c0fdd85
TS
2067}
2068
fd88b6ab 2069void op_mtc0_watchhi (void)
8c0fdd85 2070{
fd88b6ab
TS
2071 env->CP0_WatchHi[PARAM1] = (T0 & 0x40FF0FF8);
2072 env->CP0_WatchHi[PARAM1] &= ~(env->CP0_WatchHi[PARAM1] & T0 & 0x7);
8f6f6026 2073 FORCE_RET();
8c0fdd85
TS
2074}
2075
ead9360e
TS
2076void op_mtc0_xcontext (void)
2077{
2078 target_ulong mask = (1ULL << (env->SEGBITS - 7)) - 1;
2079 env->CP0_XContext = (env->CP0_XContext & mask) | (T0 & ~mask);
8f6f6026 2080 FORCE_RET();
ead9360e
TS
2081}
2082
7a387fff
TS
2083void op_mtc0_framemask (void)
2084{
2085 env->CP0_Framemask = T0; /* XXX */
8f6f6026 2086 FORCE_RET();
7a387fff
TS
2087}
2088
8c0fdd85
TS
2089void op_mtc0_debug (void)
2090{
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;
8f6f6026 2096 FORCE_RET();
8c0fdd85
TS
2097}
2098
ead9360e
TS
2099void op_mttc0_debug(void)
2100{
2101 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2102
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)));
8f6f6026 2107 FORCE_RET();
ead9360e
TS
2108}
2109
8c0fdd85
TS
2110void op_mtc0_depc (void)
2111{
f1b0aa5d 2112 env->CP0_DEPC = T0;
8f6f6026 2113 FORCE_RET();
8c0fdd85
TS
2114}
2115
7a387fff
TS
2116void op_mtc0_performance0 (void)
2117{
1b6fd0bc 2118 env->CP0_Performance0 = T0 & 0x000007ff;
8f6f6026 2119 FORCE_RET();
7a387fff
TS
2120}
2121
8c0fdd85
TS
2122void op_mtc0_taglo (void)
2123{
9c2149c8 2124 env->CP0_TagLo = T0 & 0xFFFFFCF6;
8f6f6026 2125 FORCE_RET();
8c0fdd85
TS
2126}
2127
7a387fff
TS
2128void op_mtc0_datalo (void)
2129{
2130 env->CP0_DataLo = T0; /* XXX */
8f6f6026 2131 FORCE_RET();
7a387fff
TS
2132}
2133
2134void op_mtc0_taghi (void)
2135{
2136 env->CP0_TagHi = T0; /* XXX */
8f6f6026 2137 FORCE_RET();
7a387fff
TS
2138}
2139
2140void op_mtc0_datahi (void)
2141{
2142 env->CP0_DataHi = T0; /* XXX */
8f6f6026 2143 FORCE_RET();
7a387fff
TS
2144}
2145
8c0fdd85
TS
2146void op_mtc0_errorepc (void)
2147{
f1b0aa5d 2148 env->CP0_ErrorEPC = T0;
8f6f6026 2149 FORCE_RET();
8c0fdd85
TS
2150}
2151
2152void op_mtc0_desave (void)
2153{
2154 env->CP0_DESAVE = T0;
8f6f6026 2155 FORCE_RET();
6af0bf9c
FB
2156}
2157
d26bc211 2158#if defined(TARGET_MIPS64)
ead9360e 2159void op_dmfc0_yqmask (void)
f1b0aa5d 2160{
ead9360e 2161 T0 = env->CP0_YQMask;
8f6f6026 2162 FORCE_RET();
ead9360e
TS
2163}
2164
2165void op_dmfc0_vpeschedule (void)
2166{
2167 T0 = env->CP0_VPESchedule;
8f6f6026 2168 FORCE_RET();
ead9360e
TS
2169}
2170
2171void op_dmfc0_vpeschefback (void)
2172{
2173 T0 = env->CP0_VPEScheFBack;
8f6f6026 2174 FORCE_RET();
f1b0aa5d
TS
2175}
2176
9c2149c8
TS
2177void op_dmfc0_entrylo0 (void)
2178{
2179 T0 = env->CP0_EntryLo0;
8f6f6026 2180 FORCE_RET();
9c2149c8
TS
2181}
2182
ead9360e
TS
2183void op_dmfc0_tcrestart (void)
2184{
2185 T0 = env->PC[env->current_tc];
8f6f6026 2186 FORCE_RET();
ead9360e
TS
2187}
2188
2189void op_dmfc0_tchalt (void)
2190{
2191 T0 = env->CP0_TCHalt[env->current_tc];
8f6f6026 2192 FORCE_RET();
ead9360e
TS
2193}
2194
2195void op_dmfc0_tccontext (void)
2196{
2197 T0 = env->CP0_TCContext[env->current_tc];
8f6f6026 2198 FORCE_RET();
ead9360e
TS
2199}
2200
2201void op_dmfc0_tcschedule (void)
2202{
2203 T0 = env->CP0_TCSchedule[env->current_tc];
8f6f6026 2204 FORCE_RET();
ead9360e
TS
2205}
2206
2207void op_dmfc0_tcschefback (void)
2208{
2209 T0 = env->CP0_TCScheFBack[env->current_tc];
8f6f6026 2210 FORCE_RET();
ead9360e
TS
2211}
2212
9c2149c8
TS
2213void op_dmfc0_entrylo1 (void)
2214{
2215 T0 = env->CP0_EntryLo1;
8f6f6026 2216 FORCE_RET();
9c2149c8
TS
2217}
2218
2219void op_dmfc0_context (void)
2220{
2221 T0 = env->CP0_Context;
8f6f6026 2222 FORCE_RET();
9c2149c8
TS
2223}
2224
2225void op_dmfc0_badvaddr (void)
2226{
2227 T0 = env->CP0_BadVAddr;
8f6f6026 2228 FORCE_RET();
9c2149c8
TS
2229}
2230
2231void op_dmfc0_entryhi (void)
2232{
2233 T0 = env->CP0_EntryHi;
8f6f6026 2234 FORCE_RET();
9c2149c8
TS
2235}
2236
2237void op_dmfc0_epc (void)
2238{
2239 T0 = env->CP0_EPC;
8f6f6026 2240 FORCE_RET();
9c2149c8
TS
2241}
2242
9c2149c8
TS
2243void op_dmfc0_lladdr (void)
2244{
2245 T0 = env->CP0_LLAddr >> 4;
8f6f6026 2246 FORCE_RET();
9c2149c8
TS
2247}
2248
fd88b6ab 2249void op_dmfc0_watchlo (void)
9c2149c8 2250{
fd88b6ab 2251 T0 = env->CP0_WatchLo[PARAM1];
8f6f6026 2252 FORCE_RET();
9c2149c8
TS
2253}
2254
2255void op_dmfc0_xcontext (void)
2256{
2257 T0 = env->CP0_XContext;
8f6f6026 2258 FORCE_RET();
9c2149c8
TS
2259}
2260
2261void op_dmfc0_depc (void)
2262{
2263 T0 = env->CP0_DEPC;
8f6f6026 2264 FORCE_RET();
9c2149c8
TS
2265}
2266
2267void op_dmfc0_errorepc (void)
2268{
2269 T0 = env->CP0_ErrorEPC;
8f6f6026 2270 FORCE_RET();
9c2149c8 2271}
d26bc211 2272#endif /* TARGET_MIPS64 */
9c2149c8 2273
ead9360e
TS
2274/* MIPS MT functions */
2275void op_mftgpr(void)
2276{
2277 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2278
5b2808bf 2279 T0 = env->gpr[other_tc][PARAM1];
8f6f6026 2280 FORCE_RET();
ead9360e
TS
2281}
2282
2283void op_mftlo(void)
2284{
2285 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2286
5b2808bf 2287 T0 = env->LO[other_tc][PARAM1];
8f6f6026 2288 FORCE_RET();
ead9360e
TS
2289}
2290
2291void op_mfthi(void)
2292{
2293 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2294
5b2808bf 2295 T0 = env->HI[other_tc][PARAM1];
8f6f6026 2296 FORCE_RET();
ead9360e
TS
2297}
2298
2299void op_mftacx(void)
2300{
2301 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2302
5b2808bf 2303 T0 = env->ACX[other_tc][PARAM1];
8f6f6026 2304 FORCE_RET();
ead9360e
TS
2305}
2306
2307void op_mftdsp(void)
2308{
2309 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2310
2311 T0 = env->DSPControl[other_tc];
8f6f6026 2312 FORCE_RET();
ead9360e
TS
2313}
2314
2315void op_mttgpr(void)
2316{
2317 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2318
5b2808bf 2319 T0 = env->gpr[other_tc][PARAM1];
8f6f6026 2320 FORCE_RET();
ead9360e
TS
2321}
2322
2323void op_mttlo(void)
2324{
2325 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2326
5b2808bf 2327 T0 = env->LO[other_tc][PARAM1];
8f6f6026 2328 FORCE_RET();
ead9360e
TS
2329}
2330
2331void op_mtthi(void)
2332{
2333 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2334
5b2808bf 2335 T0 = env->HI[other_tc][PARAM1];
8f6f6026 2336 FORCE_RET();
ead9360e
TS
2337}
2338
2339void op_mttacx(void)
2340{
2341 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2342
5b2808bf 2343 T0 = env->ACX[other_tc][PARAM1];
8f6f6026 2344 FORCE_RET();
ead9360e
TS
2345}
2346
2347void op_mttdsp(void)
2348{
2349 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2350
2351 T0 = env->DSPControl[other_tc];
8f6f6026 2352 FORCE_RET();
ead9360e
TS
2353}
2354
2355
2356void op_dmt(void)
2357{
2358 // TODO
2359 T0 = 0;
2360 // rt = T0
8f6f6026 2361 FORCE_RET();
ead9360e
TS
2362}
2363
2364void op_emt(void)
2365{
2366 // TODO
2367 T0 = 0;
2368 // rt = T0
8f6f6026 2369 FORCE_RET();
ead9360e
TS
2370}
2371
2372void op_dvpe(void)
2373{
2374 // TODO
2375 T0 = 0;
2376 // rt = T0
8f6f6026 2377 FORCE_RET();
ead9360e
TS
2378}
2379
2380void op_evpe(void)
2381{
2382 // TODO
2383 T0 = 0;
2384 // rt = T0
8f6f6026 2385 FORCE_RET();
ead9360e
TS
2386}
2387
2388void op_fork(void)
2389{
2390 // T0 = rt, T1 = rs
2391 T0 = 0;
2392 // TODO: store to TC register
8f6f6026 2393 FORCE_RET();
ead9360e
TS
2394}
2395
2396void op_yield(void)
2397{
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);
2406 }
2407 }
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
2414 }
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);
2420 }
2421 T0 = env->CP0_YQMask;
8f6f6026 2422 FORCE_RET();
ead9360e
TS
2423}
2424
5a5012ec 2425/* CP1 functions */
6ea83fed
FB
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
2431
5a5012ec
TS
2432void op_cfc1 (void)
2433{
ead9360e 2434 CALL_FROM_TB1(do_cfc1, PARAM1);
5a5012ec 2435 DEBUG_FPU_STATE();
8f6f6026 2436 FORCE_RET();
5a5012ec
TS
2437}
2438
2439void op_ctc1 (void)
2440{
ead9360e 2441 CALL_FROM_TB1(do_ctc1, PARAM1);
6ea83fed 2442 DEBUG_FPU_STATE();
8f6f6026 2443 FORCE_RET();
6ea83fed
FB
2444}
2445
2446void op_mfc1 (void)
2447{
6ad38722 2448 T0 = (int32_t)WT0;
6ea83fed 2449 DEBUG_FPU_STATE();
8f6f6026 2450 FORCE_RET();
6ea83fed
FB
2451}
2452
2453void op_mtc1 (void)
2454{
2455 WT0 = T0;
2456 DEBUG_FPU_STATE();
8f6f6026 2457 FORCE_RET();
6ea83fed
FB
2458}
2459
5a5012ec
TS
2460void op_dmfc1 (void)
2461{
2462 T0 = DT0;
2463 DEBUG_FPU_STATE();
8f6f6026 2464 FORCE_RET();
5a5012ec
TS
2465}
2466
2467void op_dmtc1 (void)
2468{
2469 DT0 = T0;
2470 DEBUG_FPU_STATE();
8f6f6026 2471 FORCE_RET();
5a5012ec
TS
2472}
2473
2474void op_mfhc1 (void)
2475{
6ad38722 2476 T0 = (int32_t)WTH0;
5a5012ec 2477 DEBUG_FPU_STATE();
8f6f6026 2478 FORCE_RET();
5a5012ec
TS
2479}
2480
2481void op_mthc1 (void)
2482{
2483 WTH0 = T0;
2484 DEBUG_FPU_STATE();
8f6f6026 2485 FORCE_RET();
5a5012ec
TS
2486}
2487
6ea83fed
FB
2488/* Float support.
2489 Single precition routines have a "s" suffix, double precision a
5a5012ec
TS
2490 "d" suffix, 32bit integer "w", 64bit integer "l", paired singe "ps",
2491 paired single lowwer "pl", paired single upper "pu". */
6ea83fed
FB
2492
2493#define FLOAT_OP(name, p) void OPPROTO op_float_##name##_##p(void)
2494
dd016883
FB
2495FLOAT_OP(cvtd, s)
2496{
fd4a04eb 2497 CALL_FROM_TB0(do_float_cvtd_s);
dd016883 2498 DEBUG_FPU_STATE();
8f6f6026 2499 FORCE_RET();
dd016883 2500}
6ea83fed
FB
2501FLOAT_OP(cvtd, w)
2502{
fd4a04eb 2503 CALL_FROM_TB0(do_float_cvtd_w);
5a5012ec 2504 DEBUG_FPU_STATE();
8f6f6026 2505 FORCE_RET();
5a5012ec
TS
2506}
2507FLOAT_OP(cvtd, l)
2508{
fd4a04eb 2509 CALL_FROM_TB0(do_float_cvtd_l);
5a5012ec 2510 DEBUG_FPU_STATE();
8f6f6026 2511 FORCE_RET();
5a5012ec
TS
2512}
2513FLOAT_OP(cvtl, d)
2514{
fd4a04eb 2515 CALL_FROM_TB0(do_float_cvtl_d);
5a5012ec 2516 DEBUG_FPU_STATE();
8f6f6026 2517 FORCE_RET();
5a5012ec
TS
2518}
2519FLOAT_OP(cvtl, s)
2520{
fd4a04eb 2521 CALL_FROM_TB0(do_float_cvtl_s);
5a5012ec 2522 DEBUG_FPU_STATE();
8f6f6026 2523 FORCE_RET();
5a5012ec
TS
2524}
2525FLOAT_OP(cvtps, s)
2526{
2527 WT2 = WT0;
2528 WTH2 = WT1;
2529 DEBUG_FPU_STATE();
8f6f6026 2530 FORCE_RET();
5a5012ec
TS
2531}
2532FLOAT_OP(cvtps, pw)
2533{
fd4a04eb 2534 CALL_FROM_TB0(do_float_cvtps_pw);
5a5012ec 2535 DEBUG_FPU_STATE();
8f6f6026 2536 FORCE_RET();
5a5012ec
TS
2537}
2538FLOAT_OP(cvtpw, ps)
2539{
fd4a04eb 2540 CALL_FROM_TB0(do_float_cvtpw_ps);
6ea83fed 2541 DEBUG_FPU_STATE();
8f6f6026 2542 FORCE_RET();
6ea83fed 2543}
dd016883
FB
2544FLOAT_OP(cvts, d)
2545{
fd4a04eb 2546 CALL_FROM_TB0(do_float_cvts_d);
dd016883 2547 DEBUG_FPU_STATE();
8f6f6026 2548 FORCE_RET();
dd016883 2549}
6ea83fed
FB
2550FLOAT_OP(cvts, w)
2551{
fd4a04eb 2552 CALL_FROM_TB0(do_float_cvts_w);
5a5012ec 2553 DEBUG_FPU_STATE();
8f6f6026 2554 FORCE_RET();
5a5012ec
TS
2555}
2556FLOAT_OP(cvts, l)
2557{
fd4a04eb 2558 CALL_FROM_TB0(do_float_cvts_l);
5a5012ec 2559 DEBUG_FPU_STATE();
8f6f6026 2560 FORCE_RET();
5a5012ec
TS
2561}
2562FLOAT_OP(cvts, pl)
2563{
fd4a04eb 2564 CALL_FROM_TB0(do_float_cvts_pl);
5a5012ec 2565 DEBUG_FPU_STATE();
8f6f6026 2566 FORCE_RET();
5a5012ec
TS
2567}
2568FLOAT_OP(cvts, pu)
2569{
fd4a04eb 2570 CALL_FROM_TB0(do_float_cvts_pu);
6ea83fed 2571 DEBUG_FPU_STATE();
8f6f6026 2572 FORCE_RET();
6ea83fed
FB
2573}
2574FLOAT_OP(cvtw, s)
2575{
fd4a04eb 2576 CALL_FROM_TB0(do_float_cvtw_s);
6ea83fed 2577 DEBUG_FPU_STATE();
8f6f6026 2578 FORCE_RET();
6ea83fed
FB
2579}
2580FLOAT_OP(cvtw, d)
2581{
fd4a04eb 2582 CALL_FROM_TB0(do_float_cvtw_d);
5a5012ec 2583 DEBUG_FPU_STATE();
8f6f6026 2584 FORCE_RET();
5a5012ec
TS
2585}
2586
2587FLOAT_OP(pll, ps)
2588{
2589 DT2 = ((uint64_t)WT0 << 32) | WT1;
2590 DEBUG_FPU_STATE();
8f6f6026 2591 FORCE_RET();
5a5012ec
TS
2592}
2593FLOAT_OP(plu, ps)
2594{
2595 DT2 = ((uint64_t)WT0 << 32) | WTH1;
2596 DEBUG_FPU_STATE();
8f6f6026 2597 FORCE_RET();
5a5012ec
TS
2598}
2599FLOAT_OP(pul, ps)
2600{
2601 DT2 = ((uint64_t)WTH0 << 32) | WT1;
2602 DEBUG_FPU_STATE();
8f6f6026 2603 FORCE_RET();
5a5012ec
TS
2604}
2605FLOAT_OP(puu, ps)
2606{
2607 DT2 = ((uint64_t)WTH0 << 32) | WTH1;
6ea83fed 2608 DEBUG_FPU_STATE();
8f6f6026 2609 FORCE_RET();
6ea83fed
FB
2610}
2611
fd4a04eb
TS
2612#define FLOAT_ROUNDOP(op, ttype, stype) \
2613FLOAT_OP(op ## ttype, stype) \
2614{ \
2615 CALL_FROM_TB0(do_float_ ## op ## ttype ## _ ## stype); \
2616 DEBUG_FPU_STATE(); \
8f6f6026 2617 FORCE_RET(); \
6ea83fed
FB
2618}
2619
fd4a04eb
TS
2620FLOAT_ROUNDOP(round, l, d)
2621FLOAT_ROUNDOP(round, l, s)
2622FLOAT_ROUNDOP(round, w, d)
2623FLOAT_ROUNDOP(round, w, s)
6ea83fed 2624
fd4a04eb
TS
2625FLOAT_ROUNDOP(trunc, l, d)
2626FLOAT_ROUNDOP(trunc, l, s)
2627FLOAT_ROUNDOP(trunc, w, d)
2628FLOAT_ROUNDOP(trunc, w, s)
6ea83fed 2629
fd4a04eb
TS
2630FLOAT_ROUNDOP(ceil, l, d)
2631FLOAT_ROUNDOP(ceil, l, s)
2632FLOAT_ROUNDOP(ceil, w, d)
2633FLOAT_ROUNDOP(ceil, w, s)
2634
2635FLOAT_ROUNDOP(floor, l, d)
2636FLOAT_ROUNDOP(floor, l, s)
2637FLOAT_ROUNDOP(floor, w, d)
2638FLOAT_ROUNDOP(floor, w, s)
2639#undef FLOAR_ROUNDOP
6ea83fed 2640
5a5012ec
TS
2641FLOAT_OP(movf, d)
2642{
ead9360e 2643 if (!(env->fpu->fcr31 & PARAM1))
5a5012ec
TS
2644 DT2 = DT0;
2645 DEBUG_FPU_STATE();
8f6f6026 2646 FORCE_RET();
5a5012ec
TS
2647}
2648FLOAT_OP(movf, s)
2649{
ead9360e 2650 if (!(env->fpu->fcr31 & PARAM1))
5a5012ec
TS
2651 WT2 = WT0;
2652 DEBUG_FPU_STATE();
8f6f6026 2653 FORCE_RET();
5a5012ec
TS
2654}
2655FLOAT_OP(movf, ps)
2656{
ead9360e 2657 if (!(env->fpu->fcr31 & PARAM1)) {
5a5012ec
TS
2658 WT2 = WT0;
2659 WTH2 = WTH0;
2660 }
2661 DEBUG_FPU_STATE();
8f6f6026 2662 FORCE_RET();
5a5012ec
TS
2663}
2664FLOAT_OP(movt, d)
2665{
ead9360e 2666 if (env->fpu->fcr31 & PARAM1)
5a5012ec
TS
2667 DT2 = DT0;
2668 DEBUG_FPU_STATE();
8f6f6026 2669 FORCE_RET();
5a5012ec
TS
2670}
2671FLOAT_OP(movt, s)
2672{
ead9360e 2673 if (env->fpu->fcr31 & PARAM1)
5a5012ec
TS
2674 WT2 = WT0;
2675 DEBUG_FPU_STATE();
8f6f6026 2676 FORCE_RET();
5a5012ec
TS
2677}
2678FLOAT_OP(movt, ps)
2679{
ead9360e 2680 if (env->fpu->fcr31 & PARAM1) {
5a5012ec
TS
2681 WT2 = WT0;
2682 WTH2 = WTH0;
2683 }
2684 DEBUG_FPU_STATE();
8f6f6026 2685 FORCE_RET();
5a5012ec
TS
2686}
2687FLOAT_OP(movz, d)
2688{
2689 if (!T0)
2690 DT2 = DT0;
2691 DEBUG_FPU_STATE();
8f6f6026 2692 FORCE_RET();
5a5012ec
TS
2693}
2694FLOAT_OP(movz, s)
2695{
2696 if (!T0)
2697 WT2 = WT0;
2698 DEBUG_FPU_STATE();
8f6f6026 2699 FORCE_RET();
5a5012ec
TS
2700}
2701FLOAT_OP(movz, ps)
2702{
2703 if (!T0) {
2704 WT2 = WT0;
2705 WTH2 = WTH0;
2706 }
2707 DEBUG_FPU_STATE();
8f6f6026 2708 FORCE_RET();
5a5012ec
TS
2709}
2710FLOAT_OP(movn, d)
2711{
2712 if (T0)
2713 DT2 = DT0;
2714 DEBUG_FPU_STATE();
8f6f6026 2715 FORCE_RET();
5a5012ec
TS
2716}
2717FLOAT_OP(movn, s)
2718{
2719 if (T0)
2720 WT2 = WT0;
2721 DEBUG_FPU_STATE();
8f6f6026 2722 FORCE_RET();
5a5012ec
TS
2723}
2724FLOAT_OP(movn, ps)
2725{
2726 if (T0) {
2727 WT2 = WT0;
2728 WTH2 = WTH0;
2729 }
2730 DEBUG_FPU_STATE();
8f6f6026 2731 FORCE_RET();
5a5012ec
TS
2732}
2733
57fa1fb3 2734/* operations calling helpers, for s, d and ps */
8f6f6026 2735#define FLOAT_HOP(name) \
6ea83fed
FB
2736FLOAT_OP(name, d) \
2737{ \
fd4a04eb 2738 CALL_FROM_TB0(do_float_ ## name ## _d); \
6ea83fed 2739 DEBUG_FPU_STATE(); \
8f6f6026 2740 FORCE_RET(); \
6ea83fed
FB
2741} \
2742FLOAT_OP(name, s) \
2743{ \
fd4a04eb 2744 CALL_FROM_TB0(do_float_ ## name ## _s); \
5a5012ec 2745 DEBUG_FPU_STATE(); \
8f6f6026 2746 FORCE_RET(); \
5a5012ec
TS
2747} \
2748FLOAT_OP(name, ps) \
2749{ \
fd4a04eb 2750 CALL_FROM_TB0(do_float_ ## name ## _ps); \
6ea83fed 2751 DEBUG_FPU_STATE(); \
8f6f6026 2752 FORCE_RET(); \
6ea83fed 2753}
57fa1fb3
TS
2754FLOAT_HOP(add)
2755FLOAT_HOP(sub)
2756FLOAT_HOP(mul)
2757FLOAT_HOP(div)
2758FLOAT_HOP(recip2)
2759FLOAT_HOP(rsqrt2)
2760FLOAT_HOP(rsqrt1)
2761FLOAT_HOP(recip1)
2762#undef FLOAT_HOP
2763
2764/* operations calling helpers, for s and d */
2765#define FLOAT_HOP(name) \
2766FLOAT_OP(name, d) \
2767{ \
2768 CALL_FROM_TB0(do_float_ ## name ## _d); \
2769 DEBUG_FPU_STATE(); \
8f6f6026 2770 FORCE_RET(); \
57fa1fb3
TS
2771} \
2772FLOAT_OP(name, s) \
2773{ \
2774 CALL_FROM_TB0(do_float_ ## name ## _s); \
2775 DEBUG_FPU_STATE(); \
8f6f6026 2776 FORCE_RET(); \
57fa1fb3
TS
2777}
2778FLOAT_HOP(rsqrt)
2779FLOAT_HOP(recip)
2780#undef FLOAT_HOP
6ea83fed 2781
57fa1fb3
TS
2782/* operations calling helpers, for ps */
2783#define FLOAT_HOP(name) \
2784FLOAT_OP(name, ps) \
2785{ \
2786 CALL_FROM_TB0(do_float_ ## name ## _ps); \
2787 DEBUG_FPU_STATE(); \
8f6f6026 2788 FORCE_RET(); \
fbcc6828 2789}
57fa1fb3
TS
2790FLOAT_HOP(addr)
2791FLOAT_HOP(mulr)
2792#undef FLOAT_HOP
fbcc6828 2793
5a5012ec
TS
2794/* ternary operations */
2795#define FLOAT_TERNOP(name1, name2) \
2796FLOAT_OP(name1 ## name2, d) \
2797{ \
ead9360e
TS
2798 FDT0 = float64_ ## name1 (FDT0, FDT1, &env->fpu->fp_status); \
2799 FDT2 = float64_ ## name2 (FDT0, FDT2, &env->fpu->fp_status); \
5a5012ec 2800 DEBUG_FPU_STATE(); \
8f6f6026 2801 FORCE_RET(); \
5a5012ec
TS
2802} \
2803FLOAT_OP(name1 ## name2, s) \
2804{ \
ead9360e
TS
2805 FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status); \
2806 FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status); \
5a5012ec 2807 DEBUG_FPU_STATE(); \
8f6f6026 2808 FORCE_RET(); \
5a5012ec
TS
2809} \
2810FLOAT_OP(name1 ## name2, ps) \
2811{ \
ead9360e
TS
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); \
5a5012ec 2816 DEBUG_FPU_STATE(); \
8f6f6026 2817 FORCE_RET(); \
5a5012ec
TS
2818}
2819FLOAT_TERNOP(mul, add)
2820FLOAT_TERNOP(mul, sub)
2821#undef FLOAT_TERNOP
2822
fbcc6828
TS
2823/* negated ternary operations */
2824#define FLOAT_NTERNOP(name1, name2) \
2825FLOAT_OP(n ## name1 ## name2, d) \
2826{ \
ead9360e
TS
2827 FDT0 = float64_ ## name1 (FDT0, FDT1, &env->fpu->fp_status); \
2828 FDT2 = float64_ ## name2 (FDT0, FDT2, &env->fpu->fp_status); \
5747c073 2829 FDT2 = float64_chs(FDT2); \
fbcc6828 2830 DEBUG_FPU_STATE(); \
8f6f6026 2831 FORCE_RET(); \
fbcc6828
TS
2832} \
2833FLOAT_OP(n ## name1 ## name2, s) \
2834{ \
ead9360e
TS
2835 FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status); \
2836 FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status); \
5747c073 2837 FST2 = float32_chs(FST2); \
fbcc6828 2838 DEBUG_FPU_STATE(); \
8f6f6026 2839 FORCE_RET(); \
fbcc6828
TS
2840} \
2841FLOAT_OP(n ## name1 ## name2, ps) \
2842{ \
ead9360e
TS
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); \
5747c073
PB
2847 FST2 = float32_chs(FST2); \
2848 FSTH2 = float32_chs(FSTH2); \
fbcc6828 2849 DEBUG_FPU_STATE(); \
8f6f6026 2850 FORCE_RET(); \
fbcc6828
TS
2851}
2852FLOAT_NTERNOP(mul, add)
2853FLOAT_NTERNOP(mul, sub)
2854#undef FLOAT_NTERNOP
2855
6ea83fed
FB
2856/* unary operations, modifying fp status */
2857#define FLOAT_UNOP(name) \
2858FLOAT_OP(name, d) \
2859{ \
8f6f6026 2860 FDT2 = float64_ ## name(FDT0, &env->fpu->fp_status); \
6ea83fed 2861 DEBUG_FPU_STATE(); \
8f6f6026 2862 FORCE_RET(); \
6ea83fed
FB
2863} \
2864FLOAT_OP(name, s) \
2865{ \
8f6f6026 2866 FST2 = float32_ ## name(FST0, &env->fpu->fp_status); \
6ea83fed 2867 DEBUG_FPU_STATE(); \
8f6f6026 2868 FORCE_RET(); \
6ea83fed
FB
2869}
2870FLOAT_UNOP(sqrt)
2871#undef FLOAT_UNOP
2872
2873/* unary operations, not modifying fp status */
2874#define FLOAT_UNOP(name) \
2875FLOAT_OP(name, d) \
2876{ \
2877 FDT2 = float64_ ## name(FDT0); \
2878 DEBUG_FPU_STATE(); \
8f6f6026 2879 FORCE_RET(); \
6ea83fed
FB
2880} \
2881FLOAT_OP(name, s) \
2882{ \
2883 FST2 = float32_ ## name(FST0); \
2884 DEBUG_FPU_STATE(); \
8f6f6026 2885 FORCE_RET(); \
5a5012ec
TS
2886} \
2887FLOAT_OP(name, ps) \
2888{ \
2889 FST2 = float32_ ## name(FST0); \
2890 FSTH2 = float32_ ## name(FSTH0); \
2891 DEBUG_FPU_STATE(); \
8f6f6026 2892 FORCE_RET(); \
6ea83fed
FB
2893}
2894FLOAT_UNOP(abs)
2895FLOAT_UNOP(chs)
2896#undef FLOAT_UNOP
2897
2898FLOAT_OP(mov, d)
2899{
2900 FDT2 = FDT0;
2901 DEBUG_FPU_STATE();
8f6f6026 2902 FORCE_RET();
6ea83fed
FB
2903}
2904FLOAT_OP(mov, s)
2905{
2906 FST2 = FST0;
2907 DEBUG_FPU_STATE();
8f6f6026 2908 FORCE_RET();
6ea83fed 2909}
5a5012ec
TS
2910FLOAT_OP(mov, ps)
2911{
2912 FST2 = FST0;
2913 FSTH2 = FSTH0;
2914 DEBUG_FPU_STATE();
8f6f6026 2915 FORCE_RET();
5a5012ec
TS
2916}
2917FLOAT_OP(alnv, ps)
2918{
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;
2935 }
2936 DEBUG_FPU_STATE();
8f6f6026 2937 FORCE_RET();
5a5012ec 2938}
6ea83fed
FB
2939
2940#ifdef CONFIG_SOFTFLOAT
2941#define clear_invalid() do { \
ead9360e 2942 int flags = get_float_exception_flags(&env->fpu->fp_status); \
6ea83fed 2943 flags &= ~float_flag_invalid; \
8f6f6026 2944 set_float_exception_flags(flags, &env->fpu->fp_status); \
6ea83fed
FB
2945} while(0)
2946#else
2947#define clear_invalid() do { } while(0)
2948#endif
2949
2950extern void dump_fpu_s(CPUState *env);
2951
fd4a04eb
TS
2952#define CMP_OP(fmt, op) \
2953void OPPROTO op_cmp ## _ ## fmt ## _ ## op(void) \
2954{ \
2955 CALL_FROM_TB1(do_cmp ## _ ## fmt ## _ ## op, PARAM1); \
2956 DEBUG_FPU_STATE(); \
8f6f6026 2957 FORCE_RET(); \
fd4a04eb
TS
2958} \
2959void OPPROTO op_cmpabs ## _ ## fmt ## _ ## op(void) \
2960{ \
2961 CALL_FROM_TB1(do_cmpabs ## _ ## fmt ## _ ## op, PARAM1); \
2962 DEBUG_FPU_STATE(); \
8f6f6026 2963 FORCE_RET(); \
fd4a04eb
TS
2964}
2965#define CMP_OPS(op) \
2966CMP_OP(d, op) \
2967CMP_OP(s, op) \
2968CMP_OP(ps, op)
2969
2970CMP_OPS(f)
2971CMP_OPS(un)
2972CMP_OPS(eq)
2973CMP_OPS(ueq)
2974CMP_OPS(olt)
2975CMP_OPS(ult)
2976CMP_OPS(ole)
2977CMP_OPS(ule)
2978CMP_OPS(sf)
2979CMP_OPS(ngle)
2980CMP_OPS(seq)
2981CMP_OPS(ngl)
2982CMP_OPS(lt)
2983CMP_OPS(nge)
2984CMP_OPS(le)
2985CMP_OPS(ngt)
2986#undef CMP_OPS
2987#undef CMP_OP
6ea83fed
FB
2988
2989void op_bc1f (void)
2990{
ead9360e 2991 T0 = !!(~GET_FP_COND(env->fpu) & (0x1 << PARAM1));
5a5012ec 2992 DEBUG_FPU_STATE();
8f6f6026 2993 FORCE_RET();
5a5012ec 2994}
fd4a04eb 2995void op_bc1any2f (void)
5a5012ec 2996{
ead9360e 2997 T0 = !!(~GET_FP_COND(env->fpu) & (0x3 << PARAM1));
5a5012ec 2998 DEBUG_FPU_STATE();
8f6f6026 2999 FORCE_RET();
5a5012ec 3000}
fd4a04eb 3001void op_bc1any4f (void)
5a5012ec 3002{
ead9360e 3003 T0 = !!(~GET_FP_COND(env->fpu) & (0xf << PARAM1));
6ea83fed 3004 DEBUG_FPU_STATE();
8f6f6026 3005 FORCE_RET();
6ea83fed
FB
3006}
3007
3008void op_bc1t (void)
3009{
ead9360e 3010 T0 = !!(GET_FP_COND(env->fpu) & (0x1 << PARAM1));
5a5012ec 3011 DEBUG_FPU_STATE();
8f6f6026 3012 FORCE_RET();
5a5012ec 3013}
fd4a04eb 3014void op_bc1any2t (void)
5a5012ec 3015{
ead9360e 3016 T0 = !!(GET_FP_COND(env->fpu) & (0x3 << PARAM1));
5a5012ec 3017 DEBUG_FPU_STATE();
8f6f6026 3018 FORCE_RET();
5a5012ec 3019}
fd4a04eb 3020void op_bc1any4t (void)
5a5012ec 3021{
ead9360e 3022 T0 = !!(GET_FP_COND(env->fpu) & (0xf << PARAM1));
6ea83fed 3023 DEBUG_FPU_STATE();
8f6f6026 3024 FORCE_RET();
6ea83fed 3025}
6ea83fed 3026
6af0bf9c
FB
3027void op_tlbwi (void)
3028{
ead9360e 3029 CALL_FROM_TB0(env->tlb->do_tlbwi);
8f6f6026 3030 FORCE_RET();
6af0bf9c
FB
3031}
3032
3033void op_tlbwr (void)
3034{
ead9360e 3035 CALL_FROM_TB0(env->tlb->do_tlbwr);
8f6f6026 3036 FORCE_RET();
6af0bf9c
FB
3037}
3038
3039void op_tlbp (void)
3040{
ead9360e 3041 CALL_FROM_TB0(env->tlb->do_tlbp);
8f6f6026 3042 FORCE_RET();
6af0bf9c
FB
3043}
3044
3045void op_tlbr (void)
3046{
ead9360e 3047 CALL_FROM_TB0(env->tlb->do_tlbr);
8f6f6026 3048 FORCE_RET();
6af0bf9c 3049}
6af0bf9c
FB
3050
3051/* Specials */
6f5b89a0
TS
3052#if defined (CONFIG_USER_ONLY)
3053void op_tls_value (void)
3054{
5a5012ec 3055 T0 = env->tls_value;
6f5b89a0
TS
3056}
3057#endif
3058
6af0bf9c
FB
3059void op_pmon (void)
3060{
3061 CALL_FROM_TB1(do_pmon, PARAM1);
8f6f6026 3062 FORCE_RET();
7a387fff
TS
3063}
3064
3065void op_di (void)
3066{
7a387fff 3067 T0 = env->CP0_Status;
4de9b249
TS
3068 env->CP0_Status = T0 & ~(1 << CP0St_IE);
3069 CALL_FROM_TB1(cpu_mips_update_irq, env);
8f6f6026 3070 FORCE_RET();
7a387fff
TS
3071}
3072
3073void op_ei (void)
3074{
7a387fff 3075 T0 = env->CP0_Status;
4de9b249
TS
3076 env->CP0_Status = T0 | (1 << CP0St_IE);
3077 CALL_FROM_TB1(cpu_mips_update_irq, env);
8f6f6026 3078 FORCE_RET();
6af0bf9c
FB
3079}
3080
3081void op_trap (void)
3082{
3083 if (T0) {
1579a72e 3084 CALL_FROM_TB1(do_raise_exception, EXCP_TRAP);
6af0bf9c 3085 }
8f6f6026 3086 FORCE_RET();
6af0bf9c
FB
3087}
3088
4ad40f36
FB
3089void op_debug (void)
3090{
7a387fff 3091 CALL_FROM_TB1(do_raise_exception, EXCP_DEBUG);
8f6f6026 3092 FORCE_RET();
4ad40f36
FB
3093}
3094
f41c52f1
TS
3095void debug_pre_eret (void);
3096void debug_post_eret (void);
6af0bf9c
FB
3097void op_eret (void)
3098{
f41c52f1
TS
3099 if (loglevel & CPU_LOG_EXEC)
3100 CALL_FROM_TB0(debug_pre_eret);
24c7b0e3 3101 if (env->CP0_Status & (1 << CP0St_ERL)) {
ead9360e 3102 env->PC[env->current_tc] = env->CP0_ErrorEPC;
24c7b0e3 3103 env->CP0_Status &= ~(1 << CP0St_ERL);
51e11d9e 3104 } else {
ead9360e 3105 env->PC[env->current_tc] = env->CP0_EPC;
24c7b0e3 3106 env->CP0_Status &= ~(1 << CP0St_EXL);
51e11d9e 3107 }
08fa4bab 3108 CALL_FROM_TB1(compute_hflags, env);
f41c52f1
TS
3109 if (loglevel & CPU_LOG_EXEC)
3110 CALL_FROM_TB0(debug_post_eret);
6af0bf9c 3111 env->CP0_LLAddr = 1;
8f6f6026 3112 FORCE_RET();
6af0bf9c
FB
3113}
3114
3115void op_deret (void)
3116{
f41c52f1
TS
3117 if (loglevel & CPU_LOG_EXEC)
3118 CALL_FROM_TB0(debug_pre_eret);
ead9360e 3119 env->PC[env->current_tc] = env->CP0_DEPC;
08fa4bab
TS
3120 env->hflags &= MIPS_HFLAG_DM;
3121 CALL_FROM_TB1(compute_hflags, env);
f41c52f1
TS
3122 if (loglevel & CPU_LOG_EXEC)
3123 CALL_FROM_TB0(debug_post_eret);
24c7b0e3 3124 env->CP0_LLAddr = 1;
8f6f6026 3125 FORCE_RET();
7a387fff
TS
3126}
3127
3128void op_rdhwr_cpunum(void)
3129{
387a8fe5
TS
3130 if ((env->hflags & MIPS_HFLAG_CP0) ||
3131 (env->CP0_HWREna & (1 << 0)))
1579a72e 3132 T0 = env->CP0_EBase & 0x3ff;
7a387fff 3133 else
1579a72e 3134 CALL_FROM_TB1(do_raise_exception, EXCP_RI);
8f6f6026 3135 FORCE_RET();
7a387fff
TS
3136}
3137
3138void op_rdhwr_synci_step(void)
3139{
387a8fe5
TS
3140 if ((env->hflags & MIPS_HFLAG_CP0) ||
3141 (env->CP0_HWREna & (1 << 1)))
1579a72e 3142 T0 = env->SYNCI_Step;
7a387fff 3143 else
1579a72e 3144 CALL_FROM_TB1(do_raise_exception, EXCP_RI);
8f6f6026 3145 FORCE_RET();
7a387fff
TS
3146}
3147
3148void op_rdhwr_cc(void)
3149{
387a8fe5
TS
3150 if ((env->hflags & MIPS_HFLAG_CP0) ||
3151 (env->CP0_HWREna & (1 << 2)))
1579a72e 3152 T0 = env->CP0_Count;
7a387fff 3153 else
1579a72e 3154 CALL_FROM_TB1(do_raise_exception, EXCP_RI);
8f6f6026 3155 FORCE_RET();
7a387fff
TS
3156}
3157
3158void op_rdhwr_ccres(void)
3159{
387a8fe5
TS
3160 if ((env->hflags & MIPS_HFLAG_CP0) ||
3161 (env->CP0_HWREna & (1 << 3)))
1579a72e 3162 T0 = env->CCRes;
7a387fff 3163 else
1579a72e 3164 CALL_FROM_TB1(do_raise_exception, EXCP_RI);
8f6f6026 3165 FORCE_RET();
1579a72e
TS
3166}
3167
6af0bf9c
FB
3168void op_save_state (void)
3169{
3170 env->hflags = PARAM1;
8f6f6026 3171 FORCE_RET();
6af0bf9c
FB
3172}
3173
3174void op_save_pc (void)
3175{
ead9360e 3176 env->PC[env->current_tc] = PARAM1;
8f6f6026 3177 FORCE_RET();
6af0bf9c
FB
3178}
3179
d26bc211 3180#if defined(TARGET_MIPS64)
9b9e4393
TS
3181void op_save_pc64 (void)
3182{
ead9360e 3183 env->PC[env->current_tc] = ((uint64_t)PARAM1 << 32) | (uint32_t)PARAM2;
8f6f6026 3184 FORCE_RET();
9b9e4393
TS
3185}
3186#endif
3187
16c00cb2
TS
3188void op_interrupt_restart (void)
3189{
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);
3197 }
8f6f6026 3198 FORCE_RET();
16c00cb2
TS
3199}
3200
6af0bf9c
FB
3201void op_raise_exception (void)
3202{
3203 CALL_FROM_TB1(do_raise_exception, PARAM1);
8f6f6026 3204 FORCE_RET();
6af0bf9c
FB
3205}
3206
3207void op_raise_exception_err (void)
3208{
3209 CALL_FROM_TB2(do_raise_exception_err, PARAM1, PARAM2);
8f6f6026 3210 FORCE_RET();
6af0bf9c
FB
3211}
3212
4ad40f36
FB
3213void op_wait (void)
3214{
3215 env->halted = 1;
3216 CALL_FROM_TB1(do_raise_exception, EXCP_HLT);
8f6f6026 3217 FORCE_RET();
7a387fff
TS
3218}
3219
3220/* Bitfield operations. */
3221void op_ext(void)
3222{
3223 unsigned int pos = PARAM1;
3224 unsigned int size = PARAM2;
3225
c6d6dd7c 3226 T0 = (int32_t)((T1 >> pos) & ((size < 32) ? ((1 << size) - 1) : ~0));
8f6f6026 3227 FORCE_RET();
7a387fff
TS
3228}
3229
3230void op_ins(void)
3231{
3232 unsigned int pos = PARAM1;
3233 unsigned int size = PARAM2;
f757d6ff 3234 target_ulong mask = ((size < 32) ? ((1 << size) - 1) : ~0) << pos;
7a387fff 3235
c6d6dd7c 3236 T0 = (int32_t)((T0 & ~mask) | ((T1 << pos) & mask));
8f6f6026 3237 FORCE_RET();
7a387fff
TS
3238}
3239
3240void op_wsbh(void)
3241{
c6d6dd7c 3242 T0 = (int32_t)(((T1 << 8) & ~0x00FF00FF) | ((T1 >> 8) & 0x00FF00FF));
8f6f6026 3243 FORCE_RET();
7a387fff
TS
3244}
3245
d26bc211 3246#if defined(TARGET_MIPS64)
c570fd16
TS
3247void op_dext(void)
3248{
3249 unsigned int pos = PARAM1;
3250 unsigned int size = PARAM2;
3251
c6d6dd7c 3252 T0 = (T1 >> pos) & ((size < 64) ? ((1ULL << size) - 1) : ~0ULL);
8f6f6026 3253 FORCE_RET();
c570fd16
TS
3254}
3255
3256void op_dins(void)
3257{
3258 unsigned int pos = PARAM1;
3259 unsigned int size = PARAM2;
c6d6dd7c 3260 target_ulong mask = ((size < 64) ? ((1ULL << size) - 1) : ~0ULL) << pos;
c570fd16 3261
171b31e7 3262 T0 = (T0 & ~mask) | ((T1 << pos) & mask);
8f6f6026 3263 FORCE_RET();
c570fd16
TS
3264}
3265
7a387fff
TS
3266void op_dsbh(void)
3267{
3268 T0 = ((T1 << 8) & ~0x00FF00FF00FF00FFULL) | ((T1 >> 8) & 0x00FF00FF00FF00FFULL);
8f6f6026 3269 FORCE_RET();
7a387fff
TS
3270}
3271
3272void op_dshd(void)
3273{
c6d6dd7c
TS
3274 T1 = ((T1 << 16) & ~0x0000FFFF0000FFFFULL) | ((T1 >> 16) & 0x0000FFFF0000FFFFULL);
3275 T0 = (T1 << 32) | (T1 >> 32);
8f6f6026 3276 FORCE_RET();
7a387fff 3277}
c570fd16 3278#endif
7a387fff
TS
3279
3280void op_seb(void)
3281{
3282 T0 = ((T1 & 0xFF) ^ 0x80) - 0x80;
8f6f6026 3283 FORCE_RET();
7a387fff
TS
3284}
3285
3286void op_seh(void)
3287{
3288 T0 = ((T1 & 0xFFFF) ^ 0x8000) - 0x8000;
8f6f6026 3289 FORCE_RET();
4ad40f36 3290}
This page took 0.651834 seconds and 4 git commands to generate.