Statistics
| Branch: | Revision:

root / target-mips / op.c @ 8c99506c

History | View | Annotate | Download (59 kB)

1
/*
2
 *  MIPS emulation micro-operations for qemu.
3
 *
4
 *  Copyright (c) 2004-2005 Jocelyn Mayer
5
 *  Copyright (c) 2006 Marius Groeger (FPU operations)
6
 *  Copyright (c) 2007 Thiemo Seufer (64-bit FPU support)
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"
25
#include "host-utils.h"
26

    
27
#ifndef CALL_FROM_TB0
28
#define CALL_FROM_TB0(func) func()
29
#endif
30
#ifndef CALL_FROM_TB1
31
#define CALL_FROM_TB1(func, arg0) func(arg0)
32
#endif
33
#ifndef CALL_FROM_TB1_CONST16
34
#define CALL_FROM_TB1_CONST16(func, arg0) CALL_FROM_TB1(func, arg0)
35
#endif
36
#ifndef CALL_FROM_TB2
37
#define CALL_FROM_TB2(func, arg0, arg1) func(arg0, arg1)
38
#endif
39
#ifndef CALL_FROM_TB2_CONST16
40
#define CALL_FROM_TB2_CONST16(func, arg0, arg1)     \
41
        CALL_FROM_TB2(func, arg0, arg1)
42
#endif
43
#ifndef CALL_FROM_TB3
44
#define CALL_FROM_TB3(func, arg0, arg1, arg2) func(arg0, arg1, arg2)
45
#endif
46
#ifndef CALL_FROM_TB4
47
#define CALL_FROM_TB4(func, arg0, arg1, arg2, arg3) \
48
        func(arg0, arg1, arg2, arg3)
49
#endif
50

    
51
#define FREG 0
52
#include "fop_template.c"
53
#undef FREG
54
#define FREG 1
55
#include "fop_template.c"
56
#undef FREG
57
#define FREG 2
58
#include "fop_template.c"
59
#undef FREG
60
#define FREG 3
61
#include "fop_template.c"
62
#undef FREG
63
#define FREG 4
64
#include "fop_template.c"
65
#undef FREG
66
#define FREG 5
67
#include "fop_template.c"
68
#undef FREG
69
#define FREG 6
70
#include "fop_template.c"
71
#undef FREG
72
#define FREG 7
73
#include "fop_template.c"
74
#undef FREG
75
#define FREG 8
76
#include "fop_template.c"
77
#undef FREG
78
#define FREG 9
79
#include "fop_template.c"
80
#undef FREG
81
#define FREG 10
82
#include "fop_template.c"
83
#undef FREG
84
#define FREG 11
85
#include "fop_template.c"
86
#undef FREG
87
#define FREG 12
88
#include "fop_template.c"
89
#undef FREG
90
#define FREG 13
91
#include "fop_template.c"
92
#undef FREG
93
#define FREG 14
94
#include "fop_template.c"
95
#undef FREG
96
#define FREG 15
97
#include "fop_template.c"
98
#undef FREG
99
#define FREG 16
100
#include "fop_template.c"
101
#undef FREG
102
#define FREG 17
103
#include "fop_template.c"
104
#undef FREG
105
#define FREG 18
106
#include "fop_template.c"
107
#undef FREG
108
#define FREG 19
109
#include "fop_template.c"
110
#undef FREG
111
#define FREG 20
112
#include "fop_template.c"
113
#undef FREG
114
#define FREG 21
115
#include "fop_template.c"
116
#undef FREG
117
#define FREG 22
118
#include "fop_template.c"
119
#undef FREG
120
#define FREG 23
121
#include "fop_template.c"
122
#undef FREG
123
#define FREG 24
124
#include "fop_template.c"
125
#undef FREG
126
#define FREG 25
127
#include "fop_template.c"
128
#undef FREG
129
#define FREG 26
130
#include "fop_template.c"
131
#undef FREG
132
#define FREG 27
133
#include "fop_template.c"
134
#undef FREG
135
#define FREG 28
136
#include "fop_template.c"
137
#undef FREG
138
#define FREG 29
139
#include "fop_template.c"
140
#undef FREG
141
#define FREG 30
142
#include "fop_template.c"
143
#undef FREG
144
#define FREG 31
145
#include "fop_template.c"
146
#undef FREG
147

    
148
#define FTN
149
#include "fop_template.c"
150
#undef FTN
151

    
152
/* Load and store */
153
#define MEMSUFFIX _raw
154
#include "op_mem.c"
155
#undef MEMSUFFIX
156
#if !defined(CONFIG_USER_ONLY)
157
#define MEMSUFFIX _user
158
#include "op_mem.c"
159
#undef MEMSUFFIX
160

    
161
#define MEMSUFFIX _super
162
#include "op_mem.c"
163
#undef MEMSUFFIX
164

    
165
#define MEMSUFFIX _kernel
166
#include "op_mem.c"
167
#undef MEMSUFFIX
168
#endif
169

    
170
/* Addresses computation */
171
void op_addr_add (void)
172
{
173
/* For compatibility with 32-bit code, data reference in user mode
174
   with Status_UX = 0 should be casted to 32-bit and sign extended.
175
   See the MIPS64 PRA manual, section 4.10. */
176
#if defined(TARGET_MIPS64)
177
    if (((env->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
178
        !(env->CP0_Status & (1 << CP0St_UX)))
179
        T0 = (int64_t)(int32_t)(T0 + T1);
180
    else
181
#endif
182
        T0 += T1;
183
    FORCE_RET();
184
}
185

    
186
/* Arithmetic */
187
void op_add (void)
188
{
189
    T0 = (int32_t)((int32_t)T0 + (int32_t)T1);
190
    FORCE_RET();
191
}
192

    
193
void op_addo (void)
194
{
195
    target_ulong tmp;
196

    
197
    tmp = (int32_t)T0;
198
    T0 = (int32_t)T0 + (int32_t)T1;
199
    if (((tmp ^ T1 ^ (-1)) & (T0 ^ T1)) >> 31) {
200
        /* operands of same sign, result different sign */
201
        CALL_FROM_TB1(do_raise_exception, EXCP_OVERFLOW);
202
    }
203
    T0 = (int32_t)T0;
204
    FORCE_RET();
205
}
206

    
207
void op_sub (void)
208
{
209
    T0 = (int32_t)((int32_t)T0 - (int32_t)T1);
210
    FORCE_RET();
211
}
212

    
213
void op_subo (void)
214
{
215
    target_ulong tmp;
216

    
217
    tmp = (int32_t)T0;
218
    T0 = (int32_t)T0 - (int32_t)T1;
219
    if (((tmp ^ T1) & (tmp ^ T0)) >> 31) {
220
        /* operands of different sign, first operand and result different sign */
221
        CALL_FROM_TB1(do_raise_exception, EXCP_OVERFLOW);
222
    }
223
    T0 = (int32_t)T0;
224
    FORCE_RET();
225
}
226

    
227
void op_mul (void)
228
{
229
    T0 = (int32_t)((int32_t)T0 * (int32_t)T1);
230
    FORCE_RET();
231
}
232

    
233
#if HOST_LONG_BITS < 64
234
void op_div (void)
235
{
236
    CALL_FROM_TB0(do_div);
237
    FORCE_RET();
238
}
239
#else
240
void op_div (void)
241
{
242
    if (T1 != 0) {
243
        env->LO[env->current_tc][0] = (int32_t)((int64_t)(int32_t)T0 / (int32_t)T1);
244
        env->HI[env->current_tc][0] = (int32_t)((int64_t)(int32_t)T0 % (int32_t)T1);
245
    }
246
    FORCE_RET();
247
}
248
#endif
249

    
250
void op_divu (void)
251
{
252
    if (T1 != 0) {
253
        env->LO[env->current_tc][0] = (int32_t)((uint32_t)T0 / (uint32_t)T1);
254
        env->HI[env->current_tc][0] = (int32_t)((uint32_t)T0 % (uint32_t)T1);
255
    }
256
    FORCE_RET();
257
}
258

    
259
#if defined(TARGET_MIPS64)
260
/* Arithmetic */
261
void op_dadd (void)
262
{
263
    T0 += T1;
264
    FORCE_RET();
265
}
266

    
267
void op_daddo (void)
268
{
269
    target_long tmp;
270

    
271
    tmp = T0;
272
    T0 += T1;
273
    if (((tmp ^ T1 ^ (-1)) & (T0 ^ T1)) >> 63) {
274
        /* operands of same sign, result different sign */
275
        CALL_FROM_TB1(do_raise_exception, EXCP_OVERFLOW);
276
    }
277
    FORCE_RET();
278
}
279

    
280
void op_dsub (void)
281
{
282
    T0 -= T1;
283
    FORCE_RET();
284
}
285

    
286
void op_dsubo (void)
287
{
288
    target_long tmp;
289

    
290
    tmp = T0;
291
    T0 = (int64_t)T0 - (int64_t)T1;
292
    if (((tmp ^ T1) & (tmp ^ T0)) >> 63) {
293
        /* operands of different sign, first operand and result different sign */
294
        CALL_FROM_TB1(do_raise_exception, EXCP_OVERFLOW);
295
    }
296
    FORCE_RET();
297
}
298

    
299
void op_dmul (void)
300
{
301
    T0 = (int64_t)T0 * (int64_t)T1;
302
    FORCE_RET();
303
}
304

    
305
/* Those might call libgcc functions.  */
306
void op_ddiv (void)
307
{
308
    do_ddiv();
309
    FORCE_RET();
310
}
311

    
312
#if TARGET_LONG_BITS > HOST_LONG_BITS
313
void op_ddivu (void)
314
{
315
    do_ddivu();
316
    FORCE_RET();
317
}
318
#else
319
void op_ddivu (void)
320
{
321
    if (T1 != 0) {
322
        env->LO[env->current_tc][0] = T0 / T1;
323
        env->HI[env->current_tc][0] = T0 % T1;
324
    }
325
    FORCE_RET();
326
}
327
#endif
328
#endif /* TARGET_MIPS64 */
329

    
330
/* Logical */
331
void op_and (void)
332
{
333
    T0 &= T1;
334
    FORCE_RET();
335
}
336

    
337
void op_nor (void)
338
{
339
    T0 = ~(T0 | T1);
340
    FORCE_RET();
341
}
342

    
343
void op_or (void)
344
{
345
    T0 |= T1;
346
    FORCE_RET();
347
}
348

    
349
void op_xor (void)
350
{
351
    T0 ^= T1;
352
    FORCE_RET();
353
}
354

    
355
void op_sll (void)
356
{
357
    T0 = (int32_t)((uint32_t)T0 << T1);
358
    FORCE_RET();
359
}
360

    
361
void op_sra (void)
362
{
363
    T0 = (int32_t)((int32_t)T0 >> T1);
364
    FORCE_RET();
365
}
366

    
367
void op_srl (void)
368
{
369
    T0 = (int32_t)((uint32_t)T0 >> T1);
370
    FORCE_RET();
371
}
372

    
373
void op_rotr (void)
374
{
375
    target_ulong tmp;
376

    
377
    if (T1) {
378
       tmp = (int32_t)((uint32_t)T0 << (0x20 - T1));
379
       T0 = (int32_t)((uint32_t)T0 >> T1) | tmp;
380
    }
381
    FORCE_RET();
382
}
383

    
384
void op_sllv (void)
385
{
386
    T0 = (int32_t)((uint32_t)T1 << ((uint32_t)T0 & 0x1F));
387
    FORCE_RET();
388
}
389

    
390
void op_srav (void)
391
{
392
    T0 = (int32_t)((int32_t)T1 >> (T0 & 0x1F));
393
    FORCE_RET();
394
}
395

    
396
void op_srlv (void)
397
{
398
    T0 = (int32_t)((uint32_t)T1 >> (T0 & 0x1F));
399
    FORCE_RET();
400
}
401

    
402
void op_rotrv (void)
403
{
404
    target_ulong tmp;
405

    
406
    T0 &= 0x1F;
407
    if (T0) {
408
       tmp = (int32_t)((uint32_t)T1 << (0x20 - T0));
409
       T0 = (int32_t)((uint32_t)T1 >> T0) | tmp;
410
    } else
411
       T0 = T1;
412
    FORCE_RET();
413
}
414

    
415
void op_clo (void)
416
{
417
    T0 = clo32(T0);
418
    FORCE_RET();
419
}
420

    
421
void op_clz (void)
422
{
423
    T0 = clz32(T0);
424
    FORCE_RET();
425
}
426

    
427
#if defined(TARGET_MIPS64)
428

    
429
#if TARGET_LONG_BITS > HOST_LONG_BITS
430
/* Those might call libgcc functions.  */
431
void op_dsll (void)
432
{
433
    CALL_FROM_TB0(do_dsll);
434
    FORCE_RET();
435
}
436

    
437
void op_dsll32 (void)
438
{
439
    CALL_FROM_TB0(do_dsll32);
440
    FORCE_RET();
441
}
442

    
443
void op_dsra (void)
444
{
445
    CALL_FROM_TB0(do_dsra);
446
    FORCE_RET();
447
}
448

    
449
void op_dsra32 (void)
450
{
451
    CALL_FROM_TB0(do_dsra32);
452
    FORCE_RET();
453
}
454

    
455
void op_dsrl (void)
456
{
457
    CALL_FROM_TB0(do_dsrl);
458
    FORCE_RET();
459
}
460

    
461
void op_dsrl32 (void)
462
{
463
    CALL_FROM_TB0(do_dsrl32);
464
    FORCE_RET();
465
}
466

    
467
void op_drotr (void)
468
{
469
    CALL_FROM_TB0(do_drotr);
470
    FORCE_RET();
471
}
472

    
473
void op_drotr32 (void)
474
{
475
    CALL_FROM_TB0(do_drotr32);
476
    FORCE_RET();
477
}
478

    
479
void op_dsllv (void)
480
{
481
    CALL_FROM_TB0(do_dsllv);
482
    FORCE_RET();
483
}
484

    
485
void op_dsrav (void)
486
{
487
    CALL_FROM_TB0(do_dsrav);
488
    FORCE_RET();
489
}
490

    
491
void op_dsrlv (void)
492
{
493
    CALL_FROM_TB0(do_dsrlv);
494
    FORCE_RET();
495
}
496

    
497
void op_drotrv (void)
498
{
499
    CALL_FROM_TB0(do_drotrv);
500
    FORCE_RET();
501
}
502

    
503
void op_dclo (void)
504
{
505
    CALL_FROM_TB0(do_dclo);
506
    FORCE_RET();
507
}
508

    
509
void op_dclz (void)
510
{
511
    CALL_FROM_TB0(do_dclz);
512
    FORCE_RET();
513
}
514

    
515
#else /* TARGET_LONG_BITS > HOST_LONG_BITS */
516

    
517
void op_dsll (void)
518
{
519
    T0 = T0 << T1;
520
    FORCE_RET();
521
}
522

    
523
void op_dsll32 (void)
524
{
525
    T0 = T0 << (T1 + 32);
526
    FORCE_RET();
527
}
528

    
529
void op_dsra (void)
530
{
531
    T0 = (int64_t)T0 >> T1;
532
    FORCE_RET();
533
}
534

    
535
void op_dsra32 (void)
536
{
537
    T0 = (int64_t)T0 >> (T1 + 32);
538
    FORCE_RET();
539
}
540

    
541
void op_dsrl (void)
542
{
543
    T0 = T0 >> T1;
544
    FORCE_RET();
545
}
546

    
547
void op_dsrl32 (void)
548
{
549
    T0 = T0 >> (T1 + 32);
550
    FORCE_RET();
551
}
552

    
553
void op_drotr (void)
554
{
555
    target_ulong tmp;
556

    
557
    if (T1) {
558
        tmp = T0 << (0x40 - T1);
559
        T0 = (T0 >> T1) | tmp;
560
    }
561
    FORCE_RET();
562
}
563

    
564
void op_drotr32 (void)
565
{
566
    target_ulong tmp;
567

    
568
    tmp = T0 << (0x40 - (32 + T1));
569
    T0 = (T0 >> (32 + T1)) | tmp;
570
    FORCE_RET();
571
}
572

    
573
void op_dsllv (void)
574
{
575
    T0 = T1 << (T0 & 0x3F);
576
    FORCE_RET();
577
}
578

    
579
void op_dsrav (void)
580
{
581
    T0 = (int64_t)T1 >> (T0 & 0x3F);
582
    FORCE_RET();
583
}
584

    
585
void op_dsrlv (void)
586
{
587
    T0 = T1 >> (T0 & 0x3F);
588
    FORCE_RET();
589
}
590

    
591
void op_drotrv (void)
592
{
593
    target_ulong tmp;
594

    
595
    T0 &= 0x3F;
596
    if (T0) {
597
        tmp = T1 << (0x40 - T0);
598
        T0 = (T1 >> T0) | tmp;
599
    } else
600
        T0 = T1;
601
    FORCE_RET();
602
}
603

    
604
void op_dclo (void)
605
{
606
    T0 = clo64(T0);
607
    FORCE_RET();
608
}
609

    
610
void op_dclz (void)
611
{
612
    T0 = clz64(T0);
613
    FORCE_RET();
614
}
615
#endif /* TARGET_LONG_BITS > HOST_LONG_BITS */
616
#endif /* TARGET_MIPS64 */
617

    
618
/* 64 bits arithmetic */
619
#if TARGET_LONG_BITS > HOST_LONG_BITS
620
void op_mult (void)
621
{
622
    CALL_FROM_TB0(do_mult);
623
    FORCE_RET();
624
}
625

    
626
void op_multu (void)
627
{
628
    CALL_FROM_TB0(do_multu);
629
    FORCE_RET();
630
}
631

    
632
void op_madd (void)
633
{
634
    CALL_FROM_TB0(do_madd);
635
    FORCE_RET();
636
}
637

    
638
void op_maddu (void)
639
{
640
    CALL_FROM_TB0(do_maddu);
641
    FORCE_RET();
642
}
643

    
644
void op_msub (void)
645
{
646
    CALL_FROM_TB0(do_msub);
647
    FORCE_RET();
648
}
649

    
650
void op_msubu (void)
651
{
652
    CALL_FROM_TB0(do_msubu);
653
    FORCE_RET();
654
}
655

    
656
/* Multiplication variants of the vr54xx. */
657
void op_muls (void)
658
{
659
    CALL_FROM_TB0(do_muls);
660
    FORCE_RET();
661
}
662

    
663
void op_mulsu (void)
664
{
665
    CALL_FROM_TB0(do_mulsu);
666
    FORCE_RET();
667
}
668

    
669
void op_macc (void)
670
{
671
    CALL_FROM_TB0(do_macc);
672
    FORCE_RET();
673
}
674

    
675
void op_macchi (void)
676
{
677
    CALL_FROM_TB0(do_macchi);
678
    FORCE_RET();
679
}
680

    
681
void op_maccu (void)
682
{
683
    CALL_FROM_TB0(do_maccu);
684
    FORCE_RET();
685
}
686
void op_macchiu (void)
687
{
688
    CALL_FROM_TB0(do_macchiu);
689
    FORCE_RET();
690
}
691

    
692
void op_msac (void)
693
{
694
    CALL_FROM_TB0(do_msac);
695
    FORCE_RET();
696
}
697

    
698
void op_msachi (void)
699
{
700
    CALL_FROM_TB0(do_msachi);
701
    FORCE_RET();
702
}
703

    
704
void op_msacu (void)
705
{
706
    CALL_FROM_TB0(do_msacu);
707
    FORCE_RET();
708
}
709

    
710
void op_msachiu (void)
711
{
712
    CALL_FROM_TB0(do_msachiu);
713
    FORCE_RET();
714
}
715

    
716
void op_mulhi (void)
717
{
718
    CALL_FROM_TB0(do_mulhi);
719
    FORCE_RET();
720
}
721

    
722
void op_mulhiu (void)
723
{
724
    CALL_FROM_TB0(do_mulhiu);
725
    FORCE_RET();
726
}
727

    
728
void op_mulshi (void)
729
{
730
    CALL_FROM_TB0(do_mulshi);
731
    FORCE_RET();
732
}
733

    
734
void op_mulshiu (void)
735
{
736
    CALL_FROM_TB0(do_mulshiu);
737
    FORCE_RET();
738
}
739

    
740
#else /* TARGET_LONG_BITS > HOST_LONG_BITS */
741

    
742
static always_inline uint64_t get_HILO (void)
743
{
744
    return ((uint64_t)env->HI[env->current_tc][0] << 32) |
745
            ((uint64_t)(uint32_t)env->LO[env->current_tc][0]);
746
}
747

    
748
static always_inline void set_HILO (uint64_t HILO)
749
{
750
    env->LO[env->current_tc][0] = (int32_t)(HILO & 0xFFFFFFFF);
751
    env->HI[env->current_tc][0] = (int32_t)(HILO >> 32);
752
}
753

    
754
static always_inline void set_HIT0_LO (uint64_t HILO)
755
{
756
    env->LO[env->current_tc][0] = (int32_t)(HILO & 0xFFFFFFFF);
757
    T0 = env->HI[env->current_tc][0] = (int32_t)(HILO >> 32);
758
}
759

    
760
static always_inline void set_HI_LOT0 (uint64_t HILO)
761
{
762
    T0 = env->LO[env->current_tc][0] = (int32_t)(HILO & 0xFFFFFFFF);
763
    env->HI[env->current_tc][0] = (int32_t)(HILO >> 32);
764
}
765

    
766
void op_mult (void)
767
{
768
    set_HILO((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
769
    FORCE_RET();
770
}
771

    
772
void op_multu (void)
773
{
774
    set_HILO((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
775
    FORCE_RET();
776
}
777

    
778
void op_madd (void)
779
{
780
    int64_t tmp;
781

    
782
    tmp = ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
783
    set_HILO((int64_t)get_HILO() + tmp);
784
    FORCE_RET();
785
}
786

    
787
void op_maddu (void)
788
{
789
    uint64_t tmp;
790

    
791
    tmp = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
792
    set_HILO(get_HILO() + tmp);
793
    FORCE_RET();
794
}
795

    
796
void op_msub (void)
797
{
798
    int64_t tmp;
799

    
800
    tmp = ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
801
    set_HILO((int64_t)get_HILO() - tmp);
802
    FORCE_RET();
803
}
804

    
805
void op_msubu (void)
806
{
807
    uint64_t tmp;
808

    
809
    tmp = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
810
    set_HILO(get_HILO() - tmp);
811
    FORCE_RET();
812
}
813

    
814
/* Multiplication variants of the vr54xx. */
815
void op_muls (void)
816
{
817
    set_HI_LOT0(0 - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
818
    FORCE_RET();
819
}
820

    
821
void op_mulsu (void)
822
{
823
    set_HI_LOT0(0 - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
824
    FORCE_RET();
825
}
826

    
827
void op_macc (void)
828
{
829
    set_HI_LOT0(get_HILO() + ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
830
    FORCE_RET();
831
}
832

    
833
void op_macchi (void)
834
{
835
    set_HIT0_LO(get_HILO() + ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
836
    FORCE_RET();
837
}
838

    
839
void op_maccu (void)
840
{
841
    set_HI_LOT0(get_HILO() + ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
842
    FORCE_RET();
843
}
844

    
845
void op_macchiu (void)
846
{
847
    set_HIT0_LO(get_HILO() + ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
848
    FORCE_RET();
849
}
850

    
851
void op_msac (void)
852
{
853
    set_HI_LOT0(get_HILO() - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
854
    FORCE_RET();
855
}
856

    
857
void op_msachi (void)
858
{
859
    set_HIT0_LO(get_HILO() - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
860
    FORCE_RET();
861
}
862

    
863
void op_msacu (void)
864
{
865
    set_HI_LOT0(get_HILO() - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
866
    FORCE_RET();
867
}
868

    
869
void op_msachiu (void)
870
{
871
    set_HIT0_LO(get_HILO() - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
872
    FORCE_RET();
873
}
874

    
875
void op_mulhi (void)
876
{
877
    set_HIT0_LO((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
878
    FORCE_RET();
879
}
880

    
881
void op_mulhiu (void)
882
{
883
    set_HIT0_LO((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
884
    FORCE_RET();
885
}
886

    
887
void op_mulshi (void)
888
{
889
    set_HIT0_LO(0 - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
890
    FORCE_RET();
891
}
892

    
893
void op_mulshiu (void)
894
{
895
    set_HIT0_LO(0 - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
896
    FORCE_RET();
897
}
898

    
899
#endif /* TARGET_LONG_BITS > HOST_LONG_BITS */
900

    
901
#if defined(TARGET_MIPS64)
902
void op_dmult (void)
903
{
904
    CALL_FROM_TB4(muls64, &(env->LO[env->current_tc][0]), &(env->HI[env->current_tc][0]), T0, T1);
905
    FORCE_RET();
906
}
907

    
908
void op_dmultu (void)
909
{
910
    CALL_FROM_TB4(mulu64, &(env->LO[env->current_tc][0]), &(env->HI[env->current_tc][0]), T0, T1);
911
    FORCE_RET();
912
}
913
#endif
914

    
915
/* Conditional moves */
916
void op_movn (void)
917
{
918
    if (T1 != 0)
919
        env->gpr[env->current_tc][PARAM1] = T0;
920
    FORCE_RET();
921
}
922

    
923
void op_movz (void)
924
{
925
    if (T1 == 0)
926
        env->gpr[env->current_tc][PARAM1] = T0;
927
    FORCE_RET();
928
}
929

    
930
void op_movf (void)
931
{
932
    if (!(env->fpu->fcr31 & PARAM1))
933
        T0 = T1;
934
    FORCE_RET();
935
}
936

    
937
void op_movt (void)
938
{
939
    if (env->fpu->fcr31 & PARAM1)
940
        T0 = T1;
941
    FORCE_RET();
942
}
943

    
944
/* Tests */
945
#define OP_COND(name, cond) \
946
void glue(op_, name) (void) \
947
{                           \
948
    if (cond) {             \
949
        T0 = 1;             \
950
    } else {                \
951
        T0 = 0;             \
952
    }                       \
953
    FORCE_RET();            \
954
}
955

    
956
OP_COND(eq, T0 == T1);
957
OP_COND(ne, T0 != T1);
958
OP_COND(ge, (target_long)T0 >= (target_long)T1);
959
OP_COND(geu, T0 >= T1);
960
OP_COND(lt, (target_long)T0 < (target_long)T1);
961
OP_COND(ltu, T0 < T1);
962
OP_COND(gez, (target_long)T0 >= 0);
963
OP_COND(gtz, (target_long)T0 > 0);
964
OP_COND(lez, (target_long)T0 <= 0);
965
OP_COND(ltz, (target_long)T0 < 0);
966

    
967
/* Branches */
968
/* Branch to register */
969
void op_save_breg_target (void)
970
{
971
    env->btarget = T1;
972
    FORCE_RET();
973
}
974

    
975
void op_breg (void)
976
{
977
    env->PC[env->current_tc] = env->btarget;
978
    FORCE_RET();
979
}
980

    
981
void op_save_btarget (void)
982
{
983
    env->btarget = PARAM1;
984
    FORCE_RET();
985
}
986

    
987
#if defined(TARGET_MIPS64)
988
void op_save_btarget64 (void)
989
{
990
    env->btarget = ((uint64_t)PARAM1 << 32) | (uint32_t)PARAM2;
991
    FORCE_RET();
992
}
993
#endif
994

    
995
/* Conditional branch */
996
void op_set_bcond (void)
997
{
998
    env->bcond = T0;
999
    FORCE_RET();
1000
}
1001

    
1002
void op_jnz_bcond (void)
1003
{
1004
    if (env->bcond)
1005
        GOTO_LABEL_PARAM(1);
1006
    FORCE_RET();
1007
}
1008

    
1009
/* CP0 functions */
1010
void op_mfc0_index (void)
1011
{
1012
    T0 = env->CP0_Index;
1013
    FORCE_RET();
1014
}
1015

    
1016
void op_mfc0_mvpcontrol (void)
1017
{
1018
    T0 = env->mvp->CP0_MVPControl;
1019
    FORCE_RET();
1020
}
1021

    
1022
void op_mfc0_mvpconf0 (void)
1023
{
1024
    T0 = env->mvp->CP0_MVPConf0;
1025
    FORCE_RET();
1026
}
1027

    
1028
void op_mfc0_mvpconf1 (void)
1029
{
1030
    T0 = env->mvp->CP0_MVPConf1;
1031
    FORCE_RET();
1032
}
1033

    
1034
void op_mfc0_random (void)
1035
{
1036
    CALL_FROM_TB0(do_mfc0_random);
1037
    FORCE_RET();
1038
}
1039

    
1040
void op_mfc0_vpecontrol (void)
1041
{
1042
    T0 = env->CP0_VPEControl;
1043
    FORCE_RET();
1044
}
1045

    
1046
void op_mfc0_vpeconf0 (void)
1047
{
1048
    T0 = env->CP0_VPEConf0;
1049
    FORCE_RET();
1050
}
1051

    
1052
void op_mfc0_vpeconf1 (void)
1053
{
1054
    T0 = env->CP0_VPEConf1;
1055
    FORCE_RET();
1056
}
1057

    
1058
void op_mfc0_yqmask (void)
1059
{
1060
    T0 = env->CP0_YQMask;
1061
    FORCE_RET();
1062
}
1063

    
1064
void op_mfc0_vpeschedule (void)
1065
{
1066
    T0 = env->CP0_VPESchedule;
1067
    FORCE_RET();
1068
}
1069

    
1070
void op_mfc0_vpeschefback (void)
1071
{
1072
    T0 = env->CP0_VPEScheFBack;
1073
    FORCE_RET();
1074
}
1075

    
1076
void op_mfc0_vpeopt (void)
1077
{
1078
    T0 = env->CP0_VPEOpt;
1079
    FORCE_RET();
1080
}
1081

    
1082
void op_mfc0_entrylo0 (void)
1083
{
1084
    T0 = (int32_t)env->CP0_EntryLo0;
1085
    FORCE_RET();
1086
}
1087

    
1088
void op_mfc0_tcstatus (void)
1089
{
1090
    T0 = env->CP0_TCStatus[env->current_tc];
1091
    FORCE_RET();
1092
}
1093

    
1094
void op_mftc0_tcstatus(void)
1095
{
1096
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1097

    
1098
    T0 = env->CP0_TCStatus[other_tc];
1099
    FORCE_RET();
1100
}
1101

    
1102
void op_mfc0_tcbind (void)
1103
{
1104
    T0 = env->CP0_TCBind[env->current_tc];
1105
    FORCE_RET();
1106
}
1107

    
1108
void op_mftc0_tcbind(void)
1109
{
1110
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1111

    
1112
    T0 = env->CP0_TCBind[other_tc];
1113
    FORCE_RET();
1114
}
1115

    
1116
void op_mfc0_tcrestart (void)
1117
{
1118
    T0 = env->PC[env->current_tc];
1119
    FORCE_RET();
1120
}
1121

    
1122
void op_mftc0_tcrestart(void)
1123
{
1124
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1125

    
1126
    T0 = env->PC[other_tc];
1127
    FORCE_RET();
1128
}
1129

    
1130
void op_mfc0_tchalt (void)
1131
{
1132
    T0 = env->CP0_TCHalt[env->current_tc];
1133
    FORCE_RET();
1134
}
1135

    
1136
void op_mftc0_tchalt(void)
1137
{
1138
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1139

    
1140
    T0 = env->CP0_TCHalt[other_tc];
1141
    FORCE_RET();
1142
}
1143

    
1144
void op_mfc0_tccontext (void)
1145
{
1146
    T0 = env->CP0_TCContext[env->current_tc];
1147
    FORCE_RET();
1148
}
1149

    
1150
void op_mftc0_tccontext(void)
1151
{
1152
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1153

    
1154
    T0 = env->CP0_TCContext[other_tc];
1155
    FORCE_RET();
1156
}
1157

    
1158
void op_mfc0_tcschedule (void)
1159
{
1160
    T0 = env->CP0_TCSchedule[env->current_tc];
1161
    FORCE_RET();
1162
}
1163

    
1164
void op_mftc0_tcschedule(void)
1165
{
1166
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1167

    
1168
    T0 = env->CP0_TCSchedule[other_tc];
1169
    FORCE_RET();
1170
}
1171

    
1172
void op_mfc0_tcschefback (void)
1173
{
1174
    T0 = env->CP0_TCScheFBack[env->current_tc];
1175
    FORCE_RET();
1176
}
1177

    
1178
void op_mftc0_tcschefback(void)
1179
{
1180
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1181

    
1182
    T0 = env->CP0_TCScheFBack[other_tc];
1183
    FORCE_RET();
1184
}
1185

    
1186
void op_mfc0_entrylo1 (void)
1187
{
1188
    T0 = (int32_t)env->CP0_EntryLo1;
1189
    FORCE_RET();
1190
}
1191

    
1192
void op_mfc0_context (void)
1193
{
1194
    T0 = (int32_t)env->CP0_Context;
1195
    FORCE_RET();
1196
}
1197

    
1198
void op_mfc0_pagemask (void)
1199
{
1200
    T0 = env->CP0_PageMask;
1201
    FORCE_RET();
1202
}
1203

    
1204
void op_mfc0_pagegrain (void)
1205
{
1206
    T0 = env->CP0_PageGrain;
1207
    FORCE_RET();
1208
}
1209

    
1210
void op_mfc0_wired (void)
1211
{
1212
    T0 = env->CP0_Wired;
1213
    FORCE_RET();
1214
}
1215

    
1216
void op_mfc0_srsconf0 (void)
1217
{
1218
    T0 = env->CP0_SRSConf0;
1219
    FORCE_RET();
1220
}
1221

    
1222
void op_mfc0_srsconf1 (void)
1223
{
1224
    T0 = env->CP0_SRSConf1;
1225
    FORCE_RET();
1226
}
1227

    
1228
void op_mfc0_srsconf2 (void)
1229
{
1230
    T0 = env->CP0_SRSConf2;
1231
    FORCE_RET();
1232
}
1233

    
1234
void op_mfc0_srsconf3 (void)
1235
{
1236
    T0 = env->CP0_SRSConf3;
1237
    FORCE_RET();
1238
}
1239

    
1240
void op_mfc0_srsconf4 (void)
1241
{
1242
    T0 = env->CP0_SRSConf4;
1243
    FORCE_RET();
1244
}
1245

    
1246
void op_mfc0_hwrena (void)
1247
{
1248
    T0 = env->CP0_HWREna;
1249
    FORCE_RET();
1250
}
1251

    
1252
void op_mfc0_badvaddr (void)
1253
{
1254
    T0 = (int32_t)env->CP0_BadVAddr;
1255
    FORCE_RET();
1256
}
1257

    
1258
void op_mfc0_count (void)
1259
{
1260
    CALL_FROM_TB0(do_mfc0_count);
1261
    FORCE_RET();
1262
}
1263

    
1264
void op_mfc0_entryhi (void)
1265
{
1266
    T0 = (int32_t)env->CP0_EntryHi;
1267
    FORCE_RET();
1268
}
1269

    
1270
void op_mftc0_entryhi(void)
1271
{
1272
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1273

    
1274
    T0 = (env->CP0_EntryHi & ~0xff) | (env->CP0_TCStatus[other_tc] & 0xff);
1275
    FORCE_RET();
1276
}
1277

    
1278
void op_mfc0_compare (void)
1279
{
1280
    T0 = env->CP0_Compare;
1281
    FORCE_RET();
1282
}
1283

    
1284
void op_mfc0_status (void)
1285
{
1286
    T0 = env->CP0_Status;
1287
    FORCE_RET();
1288
}
1289

    
1290
void op_mftc0_status(void)
1291
{
1292
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1293
    uint32_t tcstatus = env->CP0_TCStatus[other_tc];
1294

    
1295
    T0 = env->CP0_Status & ~0xf1000018;
1296
    T0 |= tcstatus & (0xf << CP0TCSt_TCU0);
1297
    T0 |= (tcstatus & (1 << CP0TCSt_TMX)) >> (CP0TCSt_TMX - CP0St_MX);
1298
    T0 |= (tcstatus & (0x3 << CP0TCSt_TKSU)) >> (CP0TCSt_TKSU - CP0St_KSU);
1299
    FORCE_RET();
1300
}
1301

    
1302
void op_mfc0_intctl (void)
1303
{
1304
    T0 = env->CP0_IntCtl;
1305
    FORCE_RET();
1306
}
1307

    
1308
void op_mfc0_srsctl (void)
1309
{
1310
    T0 = env->CP0_SRSCtl;
1311
    FORCE_RET();
1312
}
1313

    
1314
void op_mfc0_srsmap (void)
1315
{
1316
    T0 = env->CP0_SRSMap;
1317
    FORCE_RET();
1318
}
1319

    
1320
void op_mfc0_cause (void)
1321
{
1322
    T0 = env->CP0_Cause;
1323
    FORCE_RET();
1324
}
1325

    
1326
void op_mfc0_epc (void)
1327
{
1328
    T0 = (int32_t)env->CP0_EPC;
1329
    FORCE_RET();
1330
}
1331

    
1332
void op_mfc0_prid (void)
1333
{
1334
    T0 = env->CP0_PRid;
1335
    FORCE_RET();
1336
}
1337

    
1338
void op_mfc0_ebase (void)
1339
{
1340
    T0 = env->CP0_EBase;
1341
    FORCE_RET();
1342
}
1343

    
1344
void op_mfc0_config0 (void)
1345
{
1346
    T0 = env->CP0_Config0;
1347
    FORCE_RET();
1348
}
1349

    
1350
void op_mfc0_config1 (void)
1351
{
1352
    T0 = env->CP0_Config1;
1353
    FORCE_RET();
1354
}
1355

    
1356
void op_mfc0_config2 (void)
1357
{
1358
    T0 = env->CP0_Config2;
1359
    FORCE_RET();
1360
}
1361

    
1362
void op_mfc0_config3 (void)
1363
{
1364
    T0 = env->CP0_Config3;
1365
    FORCE_RET();
1366
}
1367

    
1368
void op_mfc0_config6 (void)
1369
{
1370
    T0 = env->CP0_Config6;
1371
    FORCE_RET();
1372
}
1373

    
1374
void op_mfc0_config7 (void)
1375
{
1376
    T0 = env->CP0_Config7;
1377
    FORCE_RET();
1378
}
1379

    
1380
void op_mfc0_lladdr (void)
1381
{
1382
    T0 = (int32_t)env->CP0_LLAddr >> 4;
1383
    FORCE_RET();
1384
}
1385

    
1386
void op_mfc0_watchlo (void)
1387
{
1388
    T0 = (int32_t)env->CP0_WatchLo[PARAM1];
1389
    FORCE_RET();
1390
}
1391

    
1392
void op_mfc0_watchhi (void)
1393
{
1394
    T0 = env->CP0_WatchHi[PARAM1];
1395
    FORCE_RET();
1396
}
1397

    
1398
void op_mfc0_xcontext (void)
1399
{
1400
    T0 = (int32_t)env->CP0_XContext;
1401
    FORCE_RET();
1402
}
1403

    
1404
void op_mfc0_framemask (void)
1405
{
1406
    T0 = env->CP0_Framemask;
1407
    FORCE_RET();
1408
}
1409

    
1410
void op_mfc0_debug (void)
1411
{
1412
    T0 = env->CP0_Debug;
1413
    if (env->hflags & MIPS_HFLAG_DM)
1414
        T0 |= 1 << CP0DB_DM;
1415
    FORCE_RET();
1416
}
1417

    
1418
void op_mftc0_debug(void)
1419
{
1420
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1421

    
1422
    /* XXX: Might be wrong, check with EJTAG spec. */
1423
    T0 = (env->CP0_Debug & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) |
1424
         (env->CP0_Debug_tcstatus[other_tc] &
1425
          ((1 << CP0DB_SSt) | (1 << CP0DB_Halt)));
1426
    FORCE_RET();
1427
}
1428

    
1429
void op_mfc0_depc (void)
1430
{
1431
    T0 = (int32_t)env->CP0_DEPC;
1432
    FORCE_RET();
1433
}
1434

    
1435
void op_mfc0_performance0 (void)
1436
{
1437
    T0 = env->CP0_Performance0;
1438
    FORCE_RET();
1439
}
1440

    
1441
void op_mfc0_taglo (void)
1442
{
1443
    T0 = env->CP0_TagLo;
1444
    FORCE_RET();
1445
}
1446

    
1447
void op_mfc0_datalo (void)
1448
{
1449
    T0 = env->CP0_DataLo;
1450
    FORCE_RET();
1451
}
1452

    
1453
void op_mfc0_taghi (void)
1454
{
1455
    T0 = env->CP0_TagHi;
1456
    FORCE_RET();
1457
}
1458

    
1459
void op_mfc0_datahi (void)
1460
{
1461
    T0 = env->CP0_DataHi;
1462
    FORCE_RET();
1463
}
1464

    
1465
void op_mfc0_errorepc (void)
1466
{
1467
    T0 = (int32_t)env->CP0_ErrorEPC;
1468
    FORCE_RET();
1469
}
1470

    
1471
void op_mfc0_desave (void)
1472
{
1473
    T0 = env->CP0_DESAVE;
1474
    FORCE_RET();
1475
}
1476

    
1477
void op_mtc0_index (void)
1478
{
1479
    int num = 1;
1480
    unsigned int tmp = env->tlb->nb_tlb;
1481

    
1482
    do {
1483
        tmp >>= 1;
1484
        num <<= 1;
1485
    } while (tmp);
1486
    env->CP0_Index = (env->CP0_Index & 0x80000000) | (T0 & (num - 1));
1487
    FORCE_RET();
1488
}
1489

    
1490
void op_mtc0_mvpcontrol (void)
1491
{
1492
    uint32_t mask = 0;
1493
    uint32_t newval;
1494

    
1495
    if (env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP))
1496
        mask |= (1 << CP0MVPCo_CPA) | (1 << CP0MVPCo_VPC) |
1497
                (1 << CP0MVPCo_EVP);
1498
    if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
1499
        mask |= (1 << CP0MVPCo_STLB);
1500
    newval = (env->mvp->CP0_MVPControl & ~mask) | (T0 & mask);
1501

    
1502
    // TODO: Enable/disable shared TLB, enable/disable VPEs.
1503

    
1504
    env->mvp->CP0_MVPControl = newval;
1505
    FORCE_RET();
1506
}
1507

    
1508
void op_mtc0_vpecontrol (void)
1509
{
1510
    uint32_t mask;
1511
    uint32_t newval;
1512

    
1513
    mask = (1 << CP0VPECo_YSI) | (1 << CP0VPECo_GSI) |
1514
           (1 << CP0VPECo_TE) | (0xff << CP0VPECo_TargTC);
1515
    newval = (env->CP0_VPEControl & ~mask) | (T0 & mask);
1516

    
1517
    /* Yield scheduler intercept not implemented. */
1518
    /* Gating storage scheduler intercept not implemented. */
1519

    
1520
    // TODO: Enable/disable TCs.
1521

    
1522
    env->CP0_VPEControl = newval;
1523
    FORCE_RET();
1524
}
1525

    
1526
void op_mtc0_vpeconf0 (void)
1527
{
1528
    uint32_t mask = 0;
1529
    uint32_t newval;
1530

    
1531
    if (env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) {
1532
        if (env->CP0_VPEConf0 & (1 << CP0VPEC0_VPA))
1533
            mask |= (0xff << CP0VPEC0_XTC);
1534
        mask |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
1535
    }
1536
    newval = (env->CP0_VPEConf0 & ~mask) | (T0 & mask);
1537

    
1538
    // TODO: TC exclusive handling due to ERL/EXL.
1539

    
1540
    env->CP0_VPEConf0 = newval;
1541
    FORCE_RET();
1542
}
1543

    
1544
void op_mtc0_vpeconf1 (void)
1545
{
1546
    uint32_t mask = 0;
1547
    uint32_t newval;
1548

    
1549
    if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
1550
        mask |= (0xff << CP0VPEC1_NCX) | (0xff << CP0VPEC1_NCP2) |
1551
                (0xff << CP0VPEC1_NCP1);
1552
    newval = (env->CP0_VPEConf1 & ~mask) | (T0 & mask);
1553

    
1554
    /* UDI not implemented. */
1555
    /* CP2 not implemented. */
1556

    
1557
    // TODO: Handle FPU (CP1) binding.
1558

    
1559
    env->CP0_VPEConf1 = newval;
1560
    FORCE_RET();
1561
}
1562

    
1563
void op_mtc0_yqmask (void)
1564
{
1565
    /* Yield qualifier inputs not implemented. */
1566
    env->CP0_YQMask = 0x00000000;
1567
    FORCE_RET();
1568
}
1569

    
1570
void op_mtc0_vpeschedule (void)
1571
{
1572
    env->CP0_VPESchedule = T0;
1573
    FORCE_RET();
1574
}
1575

    
1576
void op_mtc0_vpeschefback (void)
1577
{
1578
    env->CP0_VPEScheFBack = T0;
1579
    FORCE_RET();
1580
}
1581

    
1582
void op_mtc0_vpeopt (void)
1583
{
1584
    env->CP0_VPEOpt = T0 & 0x0000ffff;
1585
    FORCE_RET();
1586
}
1587

    
1588
void op_mtc0_entrylo0 (void)
1589
{
1590
    /* Large physaddr (PABITS) not implemented */
1591
    /* 1k pages not implemented */
1592
    env->CP0_EntryLo0 = T0 & 0x3FFFFFFF;
1593
    FORCE_RET();
1594
}
1595

    
1596
void op_mtc0_tcstatus (void)
1597
{
1598
    uint32_t mask = env->CP0_TCStatus_rw_bitmask;
1599
    uint32_t newval;
1600

    
1601
    newval = (env->CP0_TCStatus[env->current_tc] & ~mask) | (T0 & mask);
1602

    
1603
    // TODO: Sync with CP0_Status.
1604

    
1605
    env->CP0_TCStatus[env->current_tc] = newval;
1606
    FORCE_RET();
1607
}
1608

    
1609
void op_mttc0_tcstatus (void)
1610
{
1611
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1612

    
1613
    // TODO: Sync with CP0_Status.
1614

    
1615
    env->CP0_TCStatus[other_tc] = T0;
1616
    FORCE_RET();
1617
}
1618

    
1619
void op_mtc0_tcbind (void)
1620
{
1621
    uint32_t mask = (1 << CP0TCBd_TBE);
1622
    uint32_t newval;
1623

    
1624
    if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
1625
        mask |= (1 << CP0TCBd_CurVPE);
1626
    newval = (env->CP0_TCBind[env->current_tc] & ~mask) | (T0 & mask);
1627
    env->CP0_TCBind[env->current_tc] = newval;
1628
    FORCE_RET();
1629
}
1630

    
1631
void op_mttc0_tcbind (void)
1632
{
1633
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1634
    uint32_t mask = (1 << CP0TCBd_TBE);
1635
    uint32_t newval;
1636

    
1637
    if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
1638
        mask |= (1 << CP0TCBd_CurVPE);
1639
    newval = (env->CP0_TCBind[other_tc] & ~mask) | (T0 & mask);
1640
    env->CP0_TCBind[other_tc] = newval;
1641
    FORCE_RET();
1642
}
1643

    
1644
void op_mtc0_tcrestart (void)
1645
{
1646
    env->PC[env->current_tc] = T0;
1647
    env->CP0_TCStatus[env->current_tc] &= ~(1 << CP0TCSt_TDS);
1648
    env->CP0_LLAddr = 0ULL;
1649
    /* MIPS16 not implemented. */
1650
    FORCE_RET();
1651
}
1652

    
1653
void op_mttc0_tcrestart (void)
1654
{
1655
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1656

    
1657
    env->PC[other_tc] = T0;
1658
    env->CP0_TCStatus[other_tc] &= ~(1 << CP0TCSt_TDS);
1659
    env->CP0_LLAddr = 0ULL;
1660
    /* MIPS16 not implemented. */
1661
    FORCE_RET();
1662
}
1663

    
1664
void op_mtc0_tchalt (void)
1665
{
1666
    env->CP0_TCHalt[env->current_tc] = T0 & 0x1;
1667

    
1668
    // TODO: Halt TC / Restart (if allocated+active) TC.
1669

    
1670
    FORCE_RET();
1671
}
1672

    
1673
void op_mttc0_tchalt (void)
1674
{
1675
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1676

    
1677
    // TODO: Halt TC / Restart (if allocated+active) TC.
1678

    
1679
    env->CP0_TCHalt[other_tc] = T0;
1680
    FORCE_RET();
1681
}
1682

    
1683
void op_mtc0_tccontext (void)
1684
{
1685
    env->CP0_TCContext[env->current_tc] = T0;
1686
    FORCE_RET();
1687
}
1688

    
1689
void op_mttc0_tccontext (void)
1690
{
1691
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1692

    
1693
    env->CP0_TCContext[other_tc] = T0;
1694
    FORCE_RET();
1695
}
1696

    
1697
void op_mtc0_tcschedule (void)
1698
{
1699
    env->CP0_TCSchedule[env->current_tc] = T0;
1700
    FORCE_RET();
1701
}
1702

    
1703
void op_mttc0_tcschedule (void)
1704
{
1705
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1706

    
1707
    env->CP0_TCSchedule[other_tc] = T0;
1708
    FORCE_RET();
1709
}
1710

    
1711
void op_mtc0_tcschefback (void)
1712
{
1713
    env->CP0_TCScheFBack[env->current_tc] = T0;
1714
    FORCE_RET();
1715
}
1716

    
1717
void op_mttc0_tcschefback (void)
1718
{
1719
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1720

    
1721
    env->CP0_TCScheFBack[other_tc] = T0;
1722
    FORCE_RET();
1723
}
1724

    
1725
void op_mtc0_entrylo1 (void)
1726
{
1727
    /* Large physaddr (PABITS) not implemented */
1728
    /* 1k pages not implemented */
1729
    env->CP0_EntryLo1 = T0 & 0x3FFFFFFF;
1730
    FORCE_RET();
1731
}
1732

    
1733
void op_mtc0_context (void)
1734
{
1735
    env->CP0_Context = (env->CP0_Context & 0x007FFFFF) | (T0 & ~0x007FFFFF);
1736
    FORCE_RET();
1737
}
1738

    
1739
void op_mtc0_pagemask (void)
1740
{
1741
    /* 1k pages not implemented */
1742
    env->CP0_PageMask = T0 & (0x1FFFFFFF & (TARGET_PAGE_MASK << 1));
1743
    FORCE_RET();
1744
}
1745

    
1746
void op_mtc0_pagegrain (void)
1747
{
1748
    /* SmartMIPS not implemented */
1749
    /* Large physaddr (PABITS) not implemented */
1750
    /* 1k pages not implemented */
1751
    env->CP0_PageGrain = 0;
1752
    FORCE_RET();
1753
}
1754

    
1755
void op_mtc0_wired (void)
1756
{
1757
    env->CP0_Wired = T0 % env->tlb->nb_tlb;
1758
    FORCE_RET();
1759
}
1760

    
1761
void op_mtc0_srsconf0 (void)
1762
{
1763
    env->CP0_SRSConf0 |= T0 & env->CP0_SRSConf0_rw_bitmask;
1764
    FORCE_RET();
1765
}
1766

    
1767
void op_mtc0_srsconf1 (void)
1768
{
1769
    env->CP0_SRSConf1 |= T0 & env->CP0_SRSConf1_rw_bitmask;
1770
    FORCE_RET();
1771
}
1772

    
1773
void op_mtc0_srsconf2 (void)
1774
{
1775
    env->CP0_SRSConf2 |= T0 & env->CP0_SRSConf2_rw_bitmask;
1776
    FORCE_RET();
1777
}
1778

    
1779
void op_mtc0_srsconf3 (void)
1780
{
1781
    env->CP0_SRSConf3 |= T0 & env->CP0_SRSConf3_rw_bitmask;
1782
    FORCE_RET();
1783
}
1784

    
1785
void op_mtc0_srsconf4 (void)
1786
{
1787
    env->CP0_SRSConf4 |= T0 & env->CP0_SRSConf4_rw_bitmask;
1788
    FORCE_RET();
1789
}
1790

    
1791
void op_mtc0_hwrena (void)
1792
{
1793
    env->CP0_HWREna = T0 & 0x0000000F;
1794
    FORCE_RET();
1795
}
1796

    
1797
void op_mtc0_count (void)
1798
{
1799
    CALL_FROM_TB2(cpu_mips_store_count, env, T0);
1800
    FORCE_RET();
1801
}
1802

    
1803
void op_mtc0_entryhi (void)
1804
{
1805
    target_ulong old, val;
1806

    
1807
    /* 1k pages not implemented */
1808
    val = T0 & ((TARGET_PAGE_MASK << 1) | 0xFF);
1809
#if defined(TARGET_MIPS64)
1810
    val &= env->SEGMask;
1811
#endif
1812
    old = env->CP0_EntryHi;
1813
    env->CP0_EntryHi = val;
1814
    if (env->CP0_Config3 & (1 << CP0C3_MT)) {
1815
        uint32_t tcst = env->CP0_TCStatus[env->current_tc] & ~0xff;
1816
        env->CP0_TCStatus[env->current_tc] = tcst | (val & 0xff);
1817
    }
1818
    /* If the ASID changes, flush qemu's TLB.  */
1819
    if ((old & 0xFF) != (val & 0xFF))
1820
        CALL_FROM_TB2(cpu_mips_tlb_flush, env, 1);
1821
    FORCE_RET();
1822
}
1823

    
1824
void op_mttc0_entryhi(void)
1825
{
1826
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1827

    
1828
    env->CP0_EntryHi = (env->CP0_EntryHi & 0xff) | (T0 & ~0xff);
1829
    env->CP0_TCStatus[other_tc] = (env->CP0_TCStatus[other_tc] & ~0xff) | (T0 & 0xff);
1830
    FORCE_RET();
1831
}
1832

    
1833
void op_mtc0_compare (void)
1834
{
1835
    CALL_FROM_TB2(cpu_mips_store_compare, env, T0);
1836
    FORCE_RET();
1837
}
1838

    
1839
void op_mtc0_status (void)
1840
{
1841
    uint32_t val, old;
1842
    uint32_t mask = env->CP0_Status_rw_bitmask;
1843

    
1844
    val = T0 & mask;
1845
    old = env->CP0_Status;
1846
    env->CP0_Status = (env->CP0_Status & ~mask) | val;
1847
    CALL_FROM_TB1(compute_hflags, env);
1848
    if (loglevel & CPU_LOG_EXEC)
1849
        CALL_FROM_TB2(do_mtc0_status_debug, old, val);
1850
    CALL_FROM_TB1(cpu_mips_update_irq, env);
1851
    FORCE_RET();
1852
}
1853

    
1854
void op_mttc0_status(void)
1855
{
1856
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1857
    uint32_t tcstatus = env->CP0_TCStatus[other_tc];
1858

    
1859
    env->CP0_Status = T0 & ~0xf1000018;
1860
    tcstatus = (tcstatus & ~(0xf << CP0TCSt_TCU0)) | (T0 & (0xf << CP0St_CU0));
1861
    tcstatus = (tcstatus & ~(1 << CP0TCSt_TMX)) | ((T0 & (1 << CP0St_MX)) << (CP0TCSt_TMX - CP0St_MX));
1862
    tcstatus = (tcstatus & ~(0x3 << CP0TCSt_TKSU)) | ((T0 & (0x3 << CP0St_KSU)) << (CP0TCSt_TKSU - CP0St_KSU));
1863
    env->CP0_TCStatus[other_tc] = tcstatus;
1864
    FORCE_RET();
1865
}
1866

    
1867
void op_mtc0_intctl (void)
1868
{
1869
    /* vectored interrupts not implemented, no performance counters. */
1870
    env->CP0_IntCtl = (env->CP0_IntCtl & ~0x000002e0) | (T0 & 0x000002e0);
1871
    FORCE_RET();
1872
}
1873

    
1874
void op_mtc0_srsctl (void)
1875
{
1876
    uint32_t mask = (0xf << CP0SRSCtl_ESS) | (0xf << CP0SRSCtl_PSS);
1877
    env->CP0_SRSCtl = (env->CP0_SRSCtl & ~mask) | (T0 & mask);
1878
    FORCE_RET();
1879
}
1880

    
1881
void op_mtc0_srsmap (void)
1882
{
1883
    env->CP0_SRSMap = T0;
1884
    FORCE_RET();
1885
}
1886

    
1887
void op_mtc0_cause (void)
1888
{
1889
    uint32_t mask = 0x00C00300;
1890
    uint32_t old = env->CP0_Cause;
1891

    
1892
    if (env->insn_flags & ISA_MIPS32R2)
1893
        mask |= 1 << CP0Ca_DC;
1894

    
1895
    env->CP0_Cause = (env->CP0_Cause & ~mask) | (T0 & mask);
1896

    
1897
    if ((old ^ env->CP0_Cause) & (1 << CP0Ca_DC)) {
1898
        if (env->CP0_Cause & (1 << CP0Ca_DC))
1899
            CALL_FROM_TB1(cpu_mips_stop_count, env);
1900
        else
1901
            CALL_FROM_TB1(cpu_mips_start_count, env);
1902
    }
1903

    
1904
    /* Handle the software interrupt as an hardware one, as they
1905
       are very similar */
1906
    if (T0 & CP0Ca_IP_mask) {
1907
        CALL_FROM_TB1(cpu_mips_update_irq, env);
1908
    }
1909
    FORCE_RET();
1910
}
1911

    
1912
void op_mtc0_epc (void)
1913
{
1914
    env->CP0_EPC = T0;
1915
    FORCE_RET();
1916
}
1917

    
1918
void op_mtc0_ebase (void)
1919
{
1920
    /* vectored interrupts not implemented */
1921
    /* Multi-CPU not implemented */
1922
    env->CP0_EBase = 0x80000000 | (T0 & 0x3FFFF000);
1923
    FORCE_RET();
1924
}
1925

    
1926
void op_mtc0_config0 (void)
1927
{
1928
    env->CP0_Config0 = (env->CP0_Config0 & 0x81FFFFF8) | (T0 & 0x00000007);
1929
    FORCE_RET();
1930
}
1931

    
1932
void op_mtc0_config2 (void)
1933
{
1934
    /* tertiary/secondary caches not implemented */
1935
    env->CP0_Config2 = (env->CP0_Config2 & 0x8FFF0FFF);
1936
    FORCE_RET();
1937
}
1938

    
1939
void op_mtc0_watchlo (void)
1940
{
1941
    /* Watch exceptions for instructions, data loads, data stores
1942
       not implemented. */
1943
    env->CP0_WatchLo[PARAM1] = (T0 & ~0x7);
1944
    FORCE_RET();
1945
}
1946

    
1947
void op_mtc0_watchhi (void)
1948
{
1949
    env->CP0_WatchHi[PARAM1] = (T0 & 0x40FF0FF8);
1950
    env->CP0_WatchHi[PARAM1] &= ~(env->CP0_WatchHi[PARAM1] & T0 & 0x7);
1951
    FORCE_RET();
1952
}
1953

    
1954
void op_mtc0_xcontext (void)
1955
{
1956
    target_ulong mask = (1ULL << (env->SEGBITS - 7)) - 1;
1957
    env->CP0_XContext = (env->CP0_XContext & mask) | (T0 & ~mask);
1958
    FORCE_RET();
1959
}
1960

    
1961
void op_mtc0_framemask (void)
1962
{
1963
    env->CP0_Framemask = T0; /* XXX */
1964
    FORCE_RET();
1965
}
1966

    
1967
void op_mtc0_debug (void)
1968
{
1969
    env->CP0_Debug = (env->CP0_Debug & 0x8C03FC1F) | (T0 & 0x13300120);
1970
    if (T0 & (1 << CP0DB_DM))
1971
        env->hflags |= MIPS_HFLAG_DM;
1972
    else
1973
        env->hflags &= ~MIPS_HFLAG_DM;
1974
    FORCE_RET();
1975
}
1976

    
1977
void op_mttc0_debug(void)
1978
{
1979
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1980

    
1981
    /* XXX: Might be wrong, check with EJTAG spec. */
1982
    env->CP0_Debug_tcstatus[other_tc] = T0 & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt));
1983
    env->CP0_Debug = (env->CP0_Debug & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) |
1984
                     (T0 & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt)));
1985
    FORCE_RET();
1986
}
1987

    
1988
void op_mtc0_depc (void)
1989
{
1990
    env->CP0_DEPC = T0;
1991
    FORCE_RET();
1992
}
1993

    
1994
void op_mtc0_performance0 (void)
1995
{
1996
    env->CP0_Performance0 = T0 & 0x000007ff;
1997
    FORCE_RET();
1998
}
1999

    
2000
void op_mtc0_taglo (void)
2001
{
2002
    env->CP0_TagLo = T0 & 0xFFFFFCF6;
2003
    FORCE_RET();
2004
}
2005

    
2006
void op_mtc0_datalo (void)
2007
{
2008
    env->CP0_DataLo = T0; /* XXX */
2009
    FORCE_RET();
2010
}
2011

    
2012
void op_mtc0_taghi (void)
2013
{
2014
    env->CP0_TagHi = T0; /* XXX */
2015
    FORCE_RET();
2016
}
2017

    
2018
void op_mtc0_datahi (void)
2019
{
2020
    env->CP0_DataHi = T0; /* XXX */
2021
    FORCE_RET();
2022
}
2023

    
2024
void op_mtc0_errorepc (void)
2025
{
2026
    env->CP0_ErrorEPC = T0;
2027
    FORCE_RET();
2028
}
2029

    
2030
void op_mtc0_desave (void)
2031
{
2032
    env->CP0_DESAVE = T0;
2033
    FORCE_RET();
2034
}
2035

    
2036
#if defined(TARGET_MIPS64)
2037
void op_dmfc0_yqmask (void)
2038
{
2039
    T0 = env->CP0_YQMask;
2040
    FORCE_RET();
2041
}
2042

    
2043
void op_dmfc0_vpeschedule (void)
2044
{
2045
    T0 = env->CP0_VPESchedule;
2046
    FORCE_RET();
2047
}
2048

    
2049
void op_dmfc0_vpeschefback (void)
2050
{
2051
    T0 = env->CP0_VPEScheFBack;
2052
    FORCE_RET();
2053
}
2054

    
2055
void op_dmfc0_entrylo0 (void)
2056
{
2057
    T0 = env->CP0_EntryLo0;
2058
    FORCE_RET();
2059
}
2060

    
2061
void op_dmfc0_tcrestart (void)
2062
{
2063
    T0 = env->PC[env->current_tc];
2064
    FORCE_RET();
2065
}
2066

    
2067
void op_dmfc0_tchalt (void)
2068
{
2069
    T0 = env->CP0_TCHalt[env->current_tc];
2070
    FORCE_RET();
2071
}
2072

    
2073
void op_dmfc0_tccontext (void)
2074
{
2075
    T0 = env->CP0_TCContext[env->current_tc];
2076
    FORCE_RET();
2077
}
2078

    
2079
void op_dmfc0_tcschedule (void)
2080
{
2081
    T0 = env->CP0_TCSchedule[env->current_tc];
2082
    FORCE_RET();
2083
}
2084

    
2085
void op_dmfc0_tcschefback (void)
2086
{
2087
    T0 = env->CP0_TCScheFBack[env->current_tc];
2088
    FORCE_RET();
2089
}
2090

    
2091
void op_dmfc0_entrylo1 (void)
2092
{
2093
    T0 = env->CP0_EntryLo1;
2094
    FORCE_RET();
2095
}
2096

    
2097
void op_dmfc0_context (void)
2098
{
2099
    T0 = env->CP0_Context;
2100
    FORCE_RET();
2101
}
2102

    
2103
void op_dmfc0_badvaddr (void)
2104
{
2105
    T0 = env->CP0_BadVAddr;
2106
    FORCE_RET();
2107
}
2108

    
2109
void op_dmfc0_entryhi (void)
2110
{
2111
    T0 = env->CP0_EntryHi;
2112
    FORCE_RET();
2113
}
2114

    
2115
void op_dmfc0_epc (void)
2116
{
2117
    T0 = env->CP0_EPC;
2118
    FORCE_RET();
2119
}
2120

    
2121
void op_dmfc0_lladdr (void)
2122
{
2123
    T0 = env->CP0_LLAddr >> 4;
2124
    FORCE_RET();
2125
}
2126

    
2127
void op_dmfc0_watchlo (void)
2128
{
2129
    T0 = env->CP0_WatchLo[PARAM1];
2130
    FORCE_RET();
2131
}
2132

    
2133
void op_dmfc0_xcontext (void)
2134
{
2135
    T0 = env->CP0_XContext;
2136
    FORCE_RET();
2137
}
2138

    
2139
void op_dmfc0_depc (void)
2140
{
2141
    T0 = env->CP0_DEPC;
2142
    FORCE_RET();
2143
}
2144

    
2145
void op_dmfc0_errorepc (void)
2146
{
2147
    T0 = env->CP0_ErrorEPC;
2148
    FORCE_RET();
2149
}
2150
#endif /* TARGET_MIPS64 */
2151

    
2152
/* MIPS MT functions */
2153
void op_mftgpr(void)
2154
{
2155
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2156

    
2157
    T0 = env->gpr[other_tc][PARAM1];
2158
    FORCE_RET();
2159
}
2160

    
2161
void op_mftlo(void)
2162
{
2163
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2164

    
2165
    T0 = env->LO[other_tc][PARAM1];
2166
    FORCE_RET();
2167
}
2168

    
2169
void op_mfthi(void)
2170
{
2171
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2172

    
2173
    T0 = env->HI[other_tc][PARAM1];
2174
    FORCE_RET();
2175
}
2176

    
2177
void op_mftacx(void)
2178
{
2179
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2180

    
2181
    T0 = env->ACX[other_tc][PARAM1];
2182
    FORCE_RET();
2183
}
2184

    
2185
void op_mftdsp(void)
2186
{
2187
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2188

    
2189
    T0 = env->DSPControl[other_tc];
2190
    FORCE_RET();
2191
}
2192

    
2193
void op_mttgpr(void)
2194
{
2195
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2196

    
2197
    T0 = env->gpr[other_tc][PARAM1];
2198
    FORCE_RET();
2199
}
2200

    
2201
void op_mttlo(void)
2202
{
2203
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2204

    
2205
    T0 = env->LO[other_tc][PARAM1];
2206
    FORCE_RET();
2207
}
2208

    
2209
void op_mtthi(void)
2210
{
2211
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2212

    
2213
    T0 = env->HI[other_tc][PARAM1];
2214
    FORCE_RET();
2215
}
2216

    
2217
void op_mttacx(void)
2218
{
2219
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2220

    
2221
    T0 = env->ACX[other_tc][PARAM1];
2222
    FORCE_RET();
2223
}
2224

    
2225
void op_mttdsp(void)
2226
{
2227
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2228

    
2229
    T0 = env->DSPControl[other_tc];
2230
    FORCE_RET();
2231
}
2232

    
2233

    
2234
void op_dmt(void)
2235
{
2236
    // TODO
2237
    T0 = 0;
2238
    // rt = T0
2239
    FORCE_RET();
2240
}
2241

    
2242
void op_emt(void)
2243
{
2244
    // TODO
2245
    T0 = 0;
2246
    // rt = T0
2247
    FORCE_RET();
2248
}
2249

    
2250
void op_dvpe(void)
2251
{
2252
    // TODO
2253
    T0 = 0;
2254
    // rt = T0
2255
    FORCE_RET();
2256
}
2257

    
2258
void op_evpe(void)
2259
{
2260
    // TODO
2261
    T0 = 0;
2262
    // rt = T0
2263
    FORCE_RET();
2264
}
2265

    
2266
void op_fork(void)
2267
{
2268
    // T0 = rt, T1 = rs
2269
    T0 = 0;
2270
    // TODO: store to TC register
2271
    FORCE_RET();
2272
}
2273

    
2274
void op_yield(void)
2275
{
2276
    if (T0 < 0) {
2277
        /* No scheduling policy implemented. */
2278
        if (T0 != -2) {
2279
            if (env->CP0_VPEControl & (1 << CP0VPECo_YSI) &&
2280
                env->CP0_TCStatus[env->current_tc] & (1 << CP0TCSt_DT)) {
2281
                env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT);
2282
                env->CP0_VPEControl |= 4 << CP0VPECo_EXCPT;
2283
                CALL_FROM_TB1(do_raise_exception, EXCP_THREAD);
2284
            }
2285
        }
2286
    } else if (T0 == 0) {
2287
        if (0 /* TODO: TC underflow */) {
2288
            env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT);
2289
            CALL_FROM_TB1(do_raise_exception, EXCP_THREAD);
2290
        } else {
2291
            // TODO: Deallocate TC
2292
        }
2293
    } else if (T0 > 0) {
2294
        /* Yield qualifier inputs not implemented. */
2295
        env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT);
2296
        env->CP0_VPEControl |= 2 << CP0VPECo_EXCPT;
2297
        CALL_FROM_TB1(do_raise_exception, EXCP_THREAD);
2298
    }
2299
    T0 = env->CP0_YQMask;
2300
    FORCE_RET();
2301
}
2302

    
2303
/* CP1 functions */
2304
#if 0
2305
# define DEBUG_FPU_STATE() CALL_FROM_TB1(dump_fpu, env)
2306
#else
2307
# define DEBUG_FPU_STATE() do { } while(0)
2308
#endif
2309

    
2310
void op_cfc1 (void)
2311
{
2312
    CALL_FROM_TB1(do_cfc1, PARAM1);
2313
    DEBUG_FPU_STATE();
2314
    FORCE_RET();
2315
}
2316

    
2317
void op_ctc1 (void)
2318
{
2319
    CALL_FROM_TB1(do_ctc1, PARAM1);
2320
    DEBUG_FPU_STATE();
2321
    FORCE_RET();
2322
}
2323

    
2324
void op_mfc1 (void)
2325
{
2326
    T0 = (int32_t)WT0;
2327
    DEBUG_FPU_STATE();
2328
    FORCE_RET();
2329
}
2330

    
2331
void op_mtc1 (void)
2332
{
2333
    WT0 = T0;
2334
    DEBUG_FPU_STATE();
2335
    FORCE_RET();
2336
}
2337

    
2338
void op_dmfc1 (void)
2339
{
2340
    T0 = DT0;
2341
    DEBUG_FPU_STATE();
2342
    FORCE_RET();
2343
}
2344

    
2345
void op_dmtc1 (void)
2346
{
2347
    DT0 = T0;
2348
    DEBUG_FPU_STATE();
2349
    FORCE_RET();
2350
}
2351

    
2352
void op_mfhc1 (void)
2353
{
2354
    T0 = (int32_t)WTH0;
2355
    DEBUG_FPU_STATE();
2356
    FORCE_RET();
2357
}
2358

    
2359
void op_mthc1 (void)
2360
{
2361
    WTH0 = T0;
2362
    DEBUG_FPU_STATE();
2363
    FORCE_RET();
2364
}
2365

    
2366
/* Float support.
2367
   Single precition routines have a "s" suffix, double precision a
2368
   "d" suffix, 32bit integer "w", 64bit integer "l", paired singe "ps",
2369
   paired single lowwer "pl", paired single upper "pu".  */
2370

    
2371
#define FLOAT_OP(name, p) void OPPROTO op_float_##name##_##p(void)
2372

    
2373
FLOAT_OP(cvtd, s)
2374
{
2375
    CALL_FROM_TB0(do_float_cvtd_s);
2376
    DEBUG_FPU_STATE();
2377
    FORCE_RET();
2378
}
2379
FLOAT_OP(cvtd, w)
2380
{
2381
    CALL_FROM_TB0(do_float_cvtd_w);
2382
    DEBUG_FPU_STATE();
2383
    FORCE_RET();
2384
}
2385
FLOAT_OP(cvtd, l)
2386
{
2387
    CALL_FROM_TB0(do_float_cvtd_l);
2388
    DEBUG_FPU_STATE();
2389
    FORCE_RET();
2390
}
2391
FLOAT_OP(cvtl, d)
2392
{
2393
    CALL_FROM_TB0(do_float_cvtl_d);
2394
    DEBUG_FPU_STATE();
2395
    FORCE_RET();
2396
}
2397
FLOAT_OP(cvtl, s)
2398
{
2399
    CALL_FROM_TB0(do_float_cvtl_s);
2400
    DEBUG_FPU_STATE();
2401
    FORCE_RET();
2402
}
2403
FLOAT_OP(cvtps, s)
2404
{
2405
    WT2 = WT0;
2406
    WTH2 = WT1;
2407
    DEBUG_FPU_STATE();
2408
    FORCE_RET();
2409
}
2410
FLOAT_OP(cvtps, pw)
2411
{
2412
    CALL_FROM_TB0(do_float_cvtps_pw);
2413
    DEBUG_FPU_STATE();
2414
    FORCE_RET();
2415
}
2416
FLOAT_OP(cvtpw, ps)
2417
{
2418
    CALL_FROM_TB0(do_float_cvtpw_ps);
2419
    DEBUG_FPU_STATE();
2420
    FORCE_RET();
2421
}
2422
FLOAT_OP(cvts, d)
2423
{
2424
    CALL_FROM_TB0(do_float_cvts_d);
2425
    DEBUG_FPU_STATE();
2426
    FORCE_RET();
2427
}
2428
FLOAT_OP(cvts, w)
2429
{
2430
    CALL_FROM_TB0(do_float_cvts_w);
2431
    DEBUG_FPU_STATE();
2432
    FORCE_RET();
2433
}
2434
FLOAT_OP(cvts, l)
2435
{
2436
    CALL_FROM_TB0(do_float_cvts_l);
2437
    DEBUG_FPU_STATE();
2438
    FORCE_RET();
2439
}
2440
FLOAT_OP(cvts, pl)
2441
{
2442
    CALL_FROM_TB0(do_float_cvts_pl);
2443
    DEBUG_FPU_STATE();
2444
    FORCE_RET();
2445
}
2446
FLOAT_OP(cvts, pu)
2447
{
2448
    CALL_FROM_TB0(do_float_cvts_pu);
2449
    DEBUG_FPU_STATE();
2450
    FORCE_RET();
2451
}
2452
FLOAT_OP(cvtw, s)
2453
{
2454
    CALL_FROM_TB0(do_float_cvtw_s);
2455
    DEBUG_FPU_STATE();
2456
    FORCE_RET();
2457
}
2458
FLOAT_OP(cvtw, d)
2459
{
2460
    CALL_FROM_TB0(do_float_cvtw_d);
2461
    DEBUG_FPU_STATE();
2462
    FORCE_RET();
2463
}
2464

    
2465
FLOAT_OP(pll, ps)
2466
{
2467
    DT2 = ((uint64_t)WT0 << 32) | WT1;
2468
    DEBUG_FPU_STATE();
2469
    FORCE_RET();
2470
}
2471
FLOAT_OP(plu, ps)
2472
{
2473
    DT2 = ((uint64_t)WT0 << 32) | WTH1;
2474
    DEBUG_FPU_STATE();
2475
    FORCE_RET();
2476
}
2477
FLOAT_OP(pul, ps)
2478
{
2479
    DT2 = ((uint64_t)WTH0 << 32) | WT1;
2480
    DEBUG_FPU_STATE();
2481
    FORCE_RET();
2482
}
2483
FLOAT_OP(puu, ps)
2484
{
2485
    DT2 = ((uint64_t)WTH0 << 32) | WTH1;
2486
    DEBUG_FPU_STATE();
2487
    FORCE_RET();
2488
}
2489

    
2490
#define FLOAT_ROUNDOP(op, ttype, stype)                    \
2491
FLOAT_OP(op ## ttype, stype)                               \
2492
{                                                          \
2493
    CALL_FROM_TB0(do_float_ ## op ## ttype ## _ ## stype); \
2494
    DEBUG_FPU_STATE();                                     \
2495
    FORCE_RET();                                           \
2496
}
2497

    
2498
FLOAT_ROUNDOP(round, l, d)
2499
FLOAT_ROUNDOP(round, l, s)
2500
FLOAT_ROUNDOP(round, w, d)
2501
FLOAT_ROUNDOP(round, w, s)
2502

    
2503
FLOAT_ROUNDOP(trunc, l, d)
2504
FLOAT_ROUNDOP(trunc, l, s)
2505
FLOAT_ROUNDOP(trunc, w, d)
2506
FLOAT_ROUNDOP(trunc, w, s)
2507

    
2508
FLOAT_ROUNDOP(ceil, l, d)
2509
FLOAT_ROUNDOP(ceil, l, s)
2510
FLOAT_ROUNDOP(ceil, w, d)
2511
FLOAT_ROUNDOP(ceil, w, s)
2512

    
2513
FLOAT_ROUNDOP(floor, l, d)
2514
FLOAT_ROUNDOP(floor, l, s)
2515
FLOAT_ROUNDOP(floor, w, d)
2516
FLOAT_ROUNDOP(floor, w, s)
2517
#undef FLOAR_ROUNDOP
2518

    
2519
FLOAT_OP(movf, d)
2520
{
2521
    if (!(env->fpu->fcr31 & PARAM1))
2522
        DT2 = DT0;
2523
    DEBUG_FPU_STATE();
2524
    FORCE_RET();
2525
}
2526
FLOAT_OP(movf, s)
2527
{
2528
    if (!(env->fpu->fcr31 & PARAM1))
2529
        WT2 = WT0;
2530
    DEBUG_FPU_STATE();
2531
    FORCE_RET();
2532
}
2533
FLOAT_OP(movf, ps)
2534
{
2535
    if (!(env->fpu->fcr31 & PARAM1)) {
2536
        WT2 = WT0;
2537
        WTH2 = WTH0;
2538
    }
2539
    DEBUG_FPU_STATE();
2540
    FORCE_RET();
2541
}
2542
FLOAT_OP(movt, d)
2543
{
2544
    if (env->fpu->fcr31 & PARAM1)
2545
        DT2 = DT0;
2546
    DEBUG_FPU_STATE();
2547
    FORCE_RET();
2548
}
2549
FLOAT_OP(movt, s)
2550
{
2551
    if (env->fpu->fcr31 & PARAM1)
2552
        WT2 = WT0;
2553
    DEBUG_FPU_STATE();
2554
    FORCE_RET();
2555
}
2556
FLOAT_OP(movt, ps)
2557
{
2558
    if (env->fpu->fcr31 & PARAM1) {
2559
        WT2 = WT0;
2560
        WTH2 = WTH0;
2561
    }
2562
    DEBUG_FPU_STATE();
2563
    FORCE_RET();
2564
}
2565
FLOAT_OP(movz, d)
2566
{
2567
    if (!T0)
2568
        DT2 = DT0;
2569
    DEBUG_FPU_STATE();
2570
    FORCE_RET();
2571
}
2572
FLOAT_OP(movz, s)
2573
{
2574
    if (!T0)
2575
        WT2 = WT0;
2576
    DEBUG_FPU_STATE();
2577
    FORCE_RET();
2578
}
2579
FLOAT_OP(movz, ps)
2580
{
2581
    if (!T0) {
2582
        WT2 = WT0;
2583
        WTH2 = WTH0;
2584
    }
2585
    DEBUG_FPU_STATE();
2586
    FORCE_RET();
2587
}
2588
FLOAT_OP(movn, d)
2589
{
2590
    if (T0)
2591
        DT2 = DT0;
2592
    DEBUG_FPU_STATE();
2593
    FORCE_RET();
2594
}
2595
FLOAT_OP(movn, s)
2596
{
2597
    if (T0)
2598
        WT2 = WT0;
2599
    DEBUG_FPU_STATE();
2600
    FORCE_RET();
2601
}
2602
FLOAT_OP(movn, ps)
2603
{
2604
    if (T0) {
2605
        WT2 = WT0;
2606
        WTH2 = WTH0;
2607
    }
2608
    DEBUG_FPU_STATE();
2609
    FORCE_RET();
2610
}
2611

    
2612
/* operations calling helpers, for s, d and ps */
2613
#define FLOAT_HOP(name)   \
2614
FLOAT_OP(name, d)         \
2615
{                         \
2616
    CALL_FROM_TB0(do_float_ ## name ## _d);  \
2617
    DEBUG_FPU_STATE();    \
2618
    FORCE_RET();          \
2619
}                         \
2620
FLOAT_OP(name, s)         \
2621
{                         \
2622
    CALL_FROM_TB0(do_float_ ## name ## _s);  \
2623
    DEBUG_FPU_STATE();    \
2624
    FORCE_RET();          \
2625
}                         \
2626
FLOAT_OP(name, ps)        \
2627
{                         \
2628
    CALL_FROM_TB0(do_float_ ## name ## _ps); \
2629
    DEBUG_FPU_STATE();    \
2630
    FORCE_RET();          \
2631
}
2632
FLOAT_HOP(add)
2633
FLOAT_HOP(sub)
2634
FLOAT_HOP(mul)
2635
FLOAT_HOP(div)
2636
FLOAT_HOP(recip2)
2637
FLOAT_HOP(rsqrt2)
2638
FLOAT_HOP(rsqrt1)
2639
FLOAT_HOP(recip1)
2640
#undef FLOAT_HOP
2641

    
2642
/* operations calling helpers, for s and d */
2643
#define FLOAT_HOP(name)   \
2644
FLOAT_OP(name, d)         \
2645
{                         \
2646
    CALL_FROM_TB0(do_float_ ## name ## _d);  \
2647
    DEBUG_FPU_STATE();    \
2648
    FORCE_RET();          \
2649
}                         \
2650
FLOAT_OP(name, s)         \
2651
{                         \
2652
    CALL_FROM_TB0(do_float_ ## name ## _s);  \
2653
    DEBUG_FPU_STATE();    \
2654
    FORCE_RET();          \
2655
}
2656
FLOAT_HOP(rsqrt)
2657
FLOAT_HOP(recip)
2658
#undef FLOAT_HOP
2659

    
2660
/* operations calling helpers, for ps */
2661
#define FLOAT_HOP(name)   \
2662
FLOAT_OP(name, ps)        \
2663
{                         \
2664
    CALL_FROM_TB0(do_float_ ## name ## _ps); \
2665
    DEBUG_FPU_STATE();    \
2666
    FORCE_RET();          \
2667
}
2668
FLOAT_HOP(addr)
2669
FLOAT_HOP(mulr)
2670
#undef FLOAT_HOP
2671

    
2672
/* ternary operations */
2673
#define FLOAT_TERNOP(name1, name2) \
2674
FLOAT_OP(name1 ## name2, d)        \
2675
{                                  \
2676
    FDT0 = float64_ ## name1 (FDT0, FDT1, &env->fpu->fp_status);    \
2677
    FDT2 = float64_ ## name2 (FDT0, FDT2, &env->fpu->fp_status);    \
2678
    DEBUG_FPU_STATE();             \
2679
    FORCE_RET();                   \
2680
}                                  \
2681
FLOAT_OP(name1 ## name2, s)        \
2682
{                                  \
2683
    FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status);    \
2684
    FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status);    \
2685
    DEBUG_FPU_STATE();             \
2686
    FORCE_RET();                   \
2687
}                                  \
2688
FLOAT_OP(name1 ## name2, ps)       \
2689
{                                  \
2690
    FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status);    \
2691
    FSTH0 = float32_ ## name1 (FSTH0, FSTH1, &env->fpu->fp_status); \
2692
    FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status);    \
2693
    FSTH2 = float32_ ## name2 (FSTH0, FSTH2, &env->fpu->fp_status); \
2694
    DEBUG_FPU_STATE();             \
2695
    FORCE_RET();                   \
2696
}
2697
FLOAT_TERNOP(mul, add)
2698
FLOAT_TERNOP(mul, sub)
2699
#undef FLOAT_TERNOP
2700

    
2701
/* negated ternary operations */
2702
#define FLOAT_NTERNOP(name1, name2) \
2703
FLOAT_OP(n ## name1 ## name2, d)    \
2704
{                                   \
2705
    FDT0 = float64_ ## name1 (FDT0, FDT1, &env->fpu->fp_status);    \
2706
    FDT2 = float64_ ## name2 (FDT0, FDT2, &env->fpu->fp_status);    \
2707
    FDT2 = float64_chs(FDT2);       \
2708
    DEBUG_FPU_STATE();              \
2709
    FORCE_RET();                    \
2710
}                                   \
2711
FLOAT_OP(n ## name1 ## name2, s)    \
2712
{                                   \
2713
    FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status);    \
2714
    FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status);    \
2715
    FST2 = float32_chs(FST2);       \
2716
    DEBUG_FPU_STATE();              \
2717
    FORCE_RET();                    \
2718
}                                   \
2719
FLOAT_OP(n ## name1 ## name2, ps)   \
2720
{                                   \
2721
    FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status);    \
2722
    FSTH0 = float32_ ## name1 (FSTH0, FSTH1, &env->fpu->fp_status); \
2723
    FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status);    \
2724
    FSTH2 = float32_ ## name2 (FSTH0, FSTH2, &env->fpu->fp_status); \
2725
    FST2 = float32_chs(FST2);       \
2726
    FSTH2 = float32_chs(FSTH2);     \
2727
    DEBUG_FPU_STATE();              \
2728
    FORCE_RET();                    \
2729
}
2730
FLOAT_NTERNOP(mul, add)
2731
FLOAT_NTERNOP(mul, sub)
2732
#undef FLOAT_NTERNOP
2733

    
2734
/* unary operations, modifying fp status  */
2735
#define FLOAT_UNOP(name)  \
2736
FLOAT_OP(name, d)         \
2737
{                         \
2738
    FDT2 = float64_ ## name(FDT0, &env->fpu->fp_status); \
2739
    DEBUG_FPU_STATE();    \
2740
    FORCE_RET();          \
2741
}                         \
2742
FLOAT_OP(name, s)         \
2743
{                         \
2744
    FST2 = float32_ ## name(FST0, &env->fpu->fp_status); \
2745
    DEBUG_FPU_STATE();    \
2746
    FORCE_RET();          \
2747
}
2748
FLOAT_UNOP(sqrt)
2749
#undef FLOAT_UNOP
2750

    
2751
/* unary operations, not modifying fp status  */
2752
#define FLOAT_UNOP(name)  \
2753
FLOAT_OP(name, d)         \
2754
{                         \
2755
    FDT2 = float64_ ## name(FDT0);   \
2756
    DEBUG_FPU_STATE();    \
2757
    FORCE_RET();          \
2758
}                         \
2759
FLOAT_OP(name, s)         \
2760
{                         \
2761
    FST2 = float32_ ## name(FST0);   \
2762
    DEBUG_FPU_STATE();    \
2763
    FORCE_RET();          \
2764
}                         \
2765
FLOAT_OP(name, ps)        \
2766
{                         \
2767
    FST2 = float32_ ## name(FST0);   \
2768
    FSTH2 = float32_ ## name(FSTH0); \
2769
    DEBUG_FPU_STATE();    \
2770
    FORCE_RET();          \
2771
}
2772
FLOAT_UNOP(abs)
2773
FLOAT_UNOP(chs)
2774
#undef FLOAT_UNOP
2775

    
2776
FLOAT_OP(mov, d)
2777
{
2778
    FDT2 = FDT0;
2779
    DEBUG_FPU_STATE();
2780
    FORCE_RET();
2781
}
2782
FLOAT_OP(mov, s)
2783
{
2784
    FST2 = FST0;
2785
    DEBUG_FPU_STATE();
2786
    FORCE_RET();
2787
}
2788
FLOAT_OP(mov, ps)
2789
{
2790
    FST2 = FST0;
2791
    FSTH2 = FSTH0;
2792
    DEBUG_FPU_STATE();
2793
    FORCE_RET();
2794
}
2795
FLOAT_OP(alnv, ps)
2796
{
2797
    switch (T0 & 0x7) {
2798
    case 0:
2799
        FST2 = FST0;
2800
        FSTH2 = FSTH0;
2801
        break;
2802
    case 4:
2803
#ifdef TARGET_WORDS_BIGENDIAN
2804
        FSTH2 = FST0;
2805
        FST2 = FSTH1;
2806
#else
2807
        FSTH2 = FST1;
2808
        FST2 = FSTH0;
2809
#endif
2810
        break;
2811
    default: /* unpredictable */
2812
        break;
2813
    }
2814
    DEBUG_FPU_STATE();
2815
    FORCE_RET();
2816
}
2817

    
2818
#ifdef CONFIG_SOFTFLOAT
2819
#define clear_invalid() do {                                \
2820
    int flags = get_float_exception_flags(&env->fpu->fp_status); \
2821
    flags &= ~float_flag_invalid;                           \
2822
    set_float_exception_flags(flags, &env->fpu->fp_status); \
2823
} while(0)
2824
#else
2825
#define clear_invalid() do { } while(0)
2826
#endif
2827

    
2828
extern void dump_fpu_s(CPUState *env);
2829

    
2830
#define CMP_OP(fmt, op)                                \
2831
void OPPROTO op_cmp ## _ ## fmt ## _ ## op(void)       \
2832
{                                                      \
2833
    CALL_FROM_TB1(do_cmp ## _ ## fmt ## _ ## op, PARAM1); \
2834
    DEBUG_FPU_STATE();                                 \
2835
    FORCE_RET();                                       \
2836
}                                                      \
2837
void OPPROTO op_cmpabs ## _ ## fmt ## _ ## op(void)    \
2838
{                                                      \
2839
    CALL_FROM_TB1(do_cmpabs ## _ ## fmt ## _ ## op, PARAM1); \
2840
    DEBUG_FPU_STATE();                                 \
2841
    FORCE_RET();                                       \
2842
}
2843
#define CMP_OPS(op)   \
2844
CMP_OP(d, op)         \
2845
CMP_OP(s, op)         \
2846
CMP_OP(ps, op)
2847

    
2848
CMP_OPS(f)
2849
CMP_OPS(un)
2850
CMP_OPS(eq)
2851
CMP_OPS(ueq)
2852
CMP_OPS(olt)
2853
CMP_OPS(ult)
2854
CMP_OPS(ole)
2855
CMP_OPS(ule)
2856
CMP_OPS(sf)
2857
CMP_OPS(ngle)
2858
CMP_OPS(seq)
2859
CMP_OPS(ngl)
2860
CMP_OPS(lt)
2861
CMP_OPS(nge)
2862
CMP_OPS(le)
2863
CMP_OPS(ngt)
2864
#undef CMP_OPS
2865
#undef CMP_OP
2866

    
2867
void op_bc1f (void)
2868
{
2869
    T0 = !!(~GET_FP_COND(env->fpu) & (0x1 << PARAM1));
2870
    DEBUG_FPU_STATE();
2871
    FORCE_RET();
2872
}
2873
void op_bc1any2f (void)
2874
{
2875
    T0 = !!(~GET_FP_COND(env->fpu) & (0x3 << PARAM1));
2876
    DEBUG_FPU_STATE();
2877
    FORCE_RET();
2878
}
2879
void op_bc1any4f (void)
2880
{
2881
    T0 = !!(~GET_FP_COND(env->fpu) & (0xf << PARAM1));
2882
    DEBUG_FPU_STATE();
2883
    FORCE_RET();
2884
}
2885

    
2886
void op_bc1t (void)
2887
{
2888
    T0 = !!(GET_FP_COND(env->fpu) & (0x1 << PARAM1));
2889
    DEBUG_FPU_STATE();
2890
    FORCE_RET();
2891
}
2892
void op_bc1any2t (void)
2893
{
2894
    T0 = !!(GET_FP_COND(env->fpu) & (0x3 << PARAM1));
2895
    DEBUG_FPU_STATE();
2896
    FORCE_RET();
2897
}
2898
void op_bc1any4t (void)
2899
{
2900
    T0 = !!(GET_FP_COND(env->fpu) & (0xf << PARAM1));
2901
    DEBUG_FPU_STATE();
2902
    FORCE_RET();
2903
}
2904

    
2905
void op_tlbwi (void)
2906
{
2907
    CALL_FROM_TB0(env->tlb->do_tlbwi);
2908
    FORCE_RET();
2909
}
2910

    
2911
void op_tlbwr (void)
2912
{
2913
    CALL_FROM_TB0(env->tlb->do_tlbwr);
2914
    FORCE_RET();
2915
}
2916

    
2917
void op_tlbp (void)
2918
{
2919
    CALL_FROM_TB0(env->tlb->do_tlbp);
2920
    FORCE_RET();
2921
}
2922

    
2923
void op_tlbr (void)
2924
{
2925
    CALL_FROM_TB0(env->tlb->do_tlbr);
2926
    FORCE_RET();
2927
}
2928

    
2929
/* Specials */
2930
#if defined (CONFIG_USER_ONLY)
2931
void op_tls_value (void)
2932
{
2933
    T0 = env->tls_value;
2934
}
2935
#endif
2936

    
2937
void op_pmon (void)
2938
{
2939
    CALL_FROM_TB1(do_pmon, PARAM1);
2940
    FORCE_RET();
2941
}
2942

    
2943
void op_di (void)
2944
{
2945
    T0 = env->CP0_Status;
2946
    env->CP0_Status = T0 & ~(1 << CP0St_IE);
2947
    CALL_FROM_TB1(cpu_mips_update_irq, env);
2948
    FORCE_RET();
2949
}
2950

    
2951
void op_ei (void)
2952
{
2953
    T0 = env->CP0_Status;
2954
    env->CP0_Status = T0 | (1 << CP0St_IE);
2955
    CALL_FROM_TB1(cpu_mips_update_irq, env);
2956
    FORCE_RET();
2957
}
2958

    
2959
void op_trap (void)
2960
{
2961
    if (T0) {
2962
        CALL_FROM_TB1(do_raise_exception, EXCP_TRAP);
2963
    }
2964
    FORCE_RET();
2965
}
2966

    
2967
void op_debug (void)
2968
{
2969
    CALL_FROM_TB1(do_raise_exception, EXCP_DEBUG);
2970
    FORCE_RET();
2971
}
2972

    
2973
void debug_pre_eret (void);
2974
void debug_post_eret (void);
2975
void op_eret (void)
2976
{
2977
    if (loglevel & CPU_LOG_EXEC)
2978
        CALL_FROM_TB0(debug_pre_eret);
2979
    if (env->CP0_Status & (1 << CP0St_ERL)) {
2980
        env->PC[env->current_tc] = env->CP0_ErrorEPC;
2981
        env->CP0_Status &= ~(1 << CP0St_ERL);
2982
    } else {
2983
        env->PC[env->current_tc] = env->CP0_EPC;
2984
        env->CP0_Status &= ~(1 << CP0St_EXL);
2985
    }
2986
    CALL_FROM_TB1(compute_hflags, env);
2987
    if (loglevel & CPU_LOG_EXEC)
2988
        CALL_FROM_TB0(debug_post_eret);
2989
    env->CP0_LLAddr = 1;
2990
    FORCE_RET();
2991
}
2992

    
2993
void op_deret (void)
2994
{
2995
    if (loglevel & CPU_LOG_EXEC)
2996
        CALL_FROM_TB0(debug_pre_eret);
2997
    env->PC[env->current_tc] = env->CP0_DEPC;
2998
    env->hflags &= MIPS_HFLAG_DM;
2999
    CALL_FROM_TB1(compute_hflags, env);
3000
    if (loglevel & CPU_LOG_EXEC)
3001
        CALL_FROM_TB0(debug_post_eret);
3002
    env->CP0_LLAddr = 1;
3003
    FORCE_RET();
3004
}
3005

    
3006
void op_rdhwr_cpunum(void)
3007
{
3008
    if ((env->hflags & MIPS_HFLAG_CP0) ||
3009
        (env->CP0_HWREna & (1 << 0)))
3010
        T0 = env->CP0_EBase & 0x3ff;
3011
    else
3012
        CALL_FROM_TB1(do_raise_exception, EXCP_RI);
3013
    FORCE_RET();
3014
}
3015

    
3016
void op_rdhwr_synci_step(void)
3017
{
3018
    if ((env->hflags & MIPS_HFLAG_CP0) ||
3019
        (env->CP0_HWREna & (1 << 1)))
3020
        T0 = env->SYNCI_Step;
3021
    else
3022
        CALL_FROM_TB1(do_raise_exception, EXCP_RI);
3023
    FORCE_RET();
3024
}
3025

    
3026
void op_rdhwr_cc(void)
3027
{
3028
    if ((env->hflags & MIPS_HFLAG_CP0) ||
3029
        (env->CP0_HWREna & (1 << 2)))
3030
        T0 = env->CP0_Count;
3031
    else
3032
        CALL_FROM_TB1(do_raise_exception, EXCP_RI);
3033
    FORCE_RET();
3034
}
3035

    
3036
void op_rdhwr_ccres(void)
3037
{
3038
    if ((env->hflags & MIPS_HFLAG_CP0) ||
3039
        (env->CP0_HWREna & (1 << 3)))
3040
        T0 = env->CCRes;
3041
    else
3042
        CALL_FROM_TB1(do_raise_exception, EXCP_RI);
3043
    FORCE_RET();
3044
}
3045

    
3046
void op_save_state (void)
3047
{
3048
    env->hflags = PARAM1;
3049
    FORCE_RET();
3050
}
3051

    
3052
void op_save_pc (void)
3053
{
3054
    env->PC[env->current_tc] = PARAM1;
3055
    FORCE_RET();
3056
}
3057

    
3058
#if defined(TARGET_MIPS64)
3059
void op_save_pc64 (void)
3060
{
3061
    env->PC[env->current_tc] = ((uint64_t)PARAM1 << 32) | (uint32_t)PARAM2;
3062
    FORCE_RET();
3063
}
3064
#endif
3065

    
3066
void op_interrupt_restart (void)
3067
{
3068
    if (!(env->CP0_Status & (1 << CP0St_EXL)) &&
3069
        !(env->CP0_Status & (1 << CP0St_ERL)) &&
3070
        !(env->hflags & MIPS_HFLAG_DM) &&
3071
        (env->CP0_Status & (1 << CP0St_IE)) &&
3072
        (env->CP0_Status & env->CP0_Cause & CP0Ca_IP_mask)) {
3073
        env->CP0_Cause &= ~(0x1f << CP0Ca_EC);
3074
        CALL_FROM_TB1(do_raise_exception, EXCP_EXT_INTERRUPT);
3075
    }
3076
    FORCE_RET();
3077
}
3078

    
3079
void op_raise_exception (void)
3080
{
3081
    CALL_FROM_TB1(do_raise_exception, PARAM1);
3082
    FORCE_RET();
3083
}
3084

    
3085
void op_raise_exception_err (void)
3086
{
3087
    CALL_FROM_TB2(do_raise_exception_err, PARAM1, PARAM2);
3088
    FORCE_RET();
3089
}
3090

    
3091
void op_wait (void)
3092
{
3093
    env->halted = 1;
3094
    CALL_FROM_TB1(do_raise_exception, EXCP_HLT);
3095
    FORCE_RET();
3096
}
3097

    
3098
/* Bitfield operations. */
3099
void op_ext(void)
3100
{
3101
    unsigned int pos = PARAM1;
3102
    unsigned int size = PARAM2;
3103

    
3104
    T0 = (int32_t)((T1 >> pos) & ((size < 32) ? ((1 << size) - 1) : ~0));
3105
    FORCE_RET();
3106
}
3107

    
3108
void op_ins(void)
3109
{
3110
    unsigned int pos = PARAM1;
3111
    unsigned int size = PARAM2;
3112
    target_ulong mask = ((size < 32) ? ((1 << size) - 1) : ~0) << pos;
3113

    
3114
    T0 = (int32_t)((T0 & ~mask) | ((T1 << pos) & mask));
3115
    FORCE_RET();
3116
}
3117

    
3118
void op_wsbh(void)
3119
{
3120
    T0 = (int32_t)(((T1 << 8) & ~0x00FF00FF) | ((T1 >> 8) & 0x00FF00FF));
3121
    FORCE_RET();
3122
}
3123

    
3124
#if defined(TARGET_MIPS64)
3125
void op_dext(void)
3126
{
3127
    unsigned int pos = PARAM1;
3128
    unsigned int size = PARAM2;
3129

    
3130
    T0 = (T1 >> pos) & ((size < 64) ? ((1ULL << size) - 1) : ~0ULL);
3131
    FORCE_RET();
3132
}
3133

    
3134
void op_dins(void)
3135
{
3136
    unsigned int pos = PARAM1;
3137
    unsigned int size = PARAM2;
3138
    target_ulong mask = ((size < 64) ? ((1ULL << size) - 1) : ~0ULL) << pos;
3139

    
3140
    T0 = (T0 & ~mask) | ((T1 << pos) & mask);
3141
    FORCE_RET();
3142
}
3143

    
3144
void op_dsbh(void)
3145
{
3146
    T0 = ((T1 << 8) & ~0x00FF00FF00FF00FFULL) | ((T1 >> 8) & 0x00FF00FF00FF00FFULL);
3147
    FORCE_RET();
3148
}
3149

    
3150
void op_dshd(void)
3151
{
3152
    T1 = ((T1 << 16) & ~0x0000FFFF0000FFFFULL) | ((T1 >> 16) & 0x0000FFFF0000FFFFULL);
3153
    T0 = (T1 << 32) | (T1 >> 32);
3154
    FORCE_RET();
3155
}
3156
#endif
3157

    
3158
void op_seb(void)
3159
{
3160
    T0 = ((T1 & 0xFF) ^ 0x80) - 0x80;
3161
    FORCE_RET();
3162
}
3163

    
3164
void op_seh(void)
3165
{
3166
    T0 = ((T1 & 0xFFFF) ^ 0x8000) - 0x8000;
3167
    FORCE_RET();
3168
}