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