Statistics
| Branch: | Revision:

root / target-mips / op.c @ aaa9128a

History | View | Annotate | Download (60.6 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 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

    
145
#define TN
146
#include "op_template.c"
147
#undef TN
148

    
149
#define FREG 0
150
#include "fop_template.c"
151
#undef FREG
152
#define FREG 1
153
#include "fop_template.c"
154
#undef FREG
155
#define FREG 2
156
#include "fop_template.c"
157
#undef FREG
158
#define FREG 3
159
#include "fop_template.c"
160
#undef FREG
161
#define FREG 4
162
#include "fop_template.c"
163
#undef FREG
164
#define FREG 5
165
#include "fop_template.c"
166
#undef FREG
167
#define FREG 6
168
#include "fop_template.c"
169
#undef FREG
170
#define FREG 7
171
#include "fop_template.c"
172
#undef FREG
173
#define FREG 8
174
#include "fop_template.c"
175
#undef FREG
176
#define FREG 9
177
#include "fop_template.c"
178
#undef FREG
179
#define FREG 10
180
#include "fop_template.c"
181
#undef FREG
182
#define FREG 11
183
#include "fop_template.c"
184
#undef FREG
185
#define FREG 12
186
#include "fop_template.c"
187
#undef FREG
188
#define FREG 13
189
#include "fop_template.c"
190
#undef FREG
191
#define FREG 14
192
#include "fop_template.c"
193
#undef FREG
194
#define FREG 15
195
#include "fop_template.c"
196
#undef FREG
197
#define FREG 16
198
#include "fop_template.c"
199
#undef FREG
200
#define FREG 17
201
#include "fop_template.c"
202
#undef FREG
203
#define FREG 18
204
#include "fop_template.c"
205
#undef FREG
206
#define FREG 19
207
#include "fop_template.c"
208
#undef FREG
209
#define FREG 20
210
#include "fop_template.c"
211
#undef FREG
212
#define FREG 21
213
#include "fop_template.c"
214
#undef FREG
215
#define FREG 22
216
#include "fop_template.c"
217
#undef FREG
218
#define FREG 23
219
#include "fop_template.c"
220
#undef FREG
221
#define FREG 24
222
#include "fop_template.c"
223
#undef FREG
224
#define FREG 25
225
#include "fop_template.c"
226
#undef FREG
227
#define FREG 26
228
#include "fop_template.c"
229
#undef FREG
230
#define FREG 27
231
#include "fop_template.c"
232
#undef FREG
233
#define FREG 28
234
#include "fop_template.c"
235
#undef FREG
236
#define FREG 29
237
#include "fop_template.c"
238
#undef FREG
239
#define FREG 30
240
#include "fop_template.c"
241
#undef FREG
242
#define FREG 31
243
#include "fop_template.c"
244
#undef FREG
245

    
246
#define FTN
247
#include "fop_template.c"
248
#undef FTN
249

    
250
/* Load and store */
251
#define MEMSUFFIX _raw
252
#include "op_mem.c"
253
#undef MEMSUFFIX
254
#if !defined(CONFIG_USER_ONLY)
255
#define MEMSUFFIX _user
256
#include "op_mem.c"
257
#undef MEMSUFFIX
258

    
259
#define MEMSUFFIX _super
260
#include "op_mem.c"
261
#undef MEMSUFFIX
262

    
263
#define MEMSUFFIX _kernel
264
#include "op_mem.c"
265
#undef MEMSUFFIX
266
#endif
267

    
268
/* Addresses computation */
269
void op_addr_add (void)
270
{
271
/* For compatibility with 32-bit code, data reference in user mode
272
   with Status_UX = 0 should be casted to 32-bit and sign extended.
273
   See the MIPS64 PRA manual, section 4.10. */
274
#if defined(TARGET_MIPS64)
275
    if (((env->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
276
        !(env->CP0_Status & (1 << CP0St_UX)))
277
        T0 = (int64_t)(int32_t)(T0 + T1);
278
    else
279
#endif
280
        T0 += T1;
281
    FORCE_RET();
282
}
283

    
284
/* Arithmetic */
285
void op_add (void)
286
{
287
    T0 = (int32_t)((int32_t)T0 + (int32_t)T1);
288
    FORCE_RET();
289
}
290

    
291
void op_addo (void)
292
{
293
    target_ulong tmp;
294

    
295
    tmp = (int32_t)T0;
296
    T0 = (int32_t)T0 + (int32_t)T1;
297
    if (((tmp ^ T1 ^ (-1)) & (T0 ^ T1)) >> 31) {
298
        /* operands of same sign, result different sign */
299
        CALL_FROM_TB1(do_raise_exception, EXCP_OVERFLOW);
300
    }
301
    T0 = (int32_t)T0;
302
    FORCE_RET();
303
}
304

    
305
void op_sub (void)
306
{
307
    T0 = (int32_t)((int32_t)T0 - (int32_t)T1);
308
    FORCE_RET();
309
}
310

    
311
void op_subo (void)
312
{
313
    target_ulong tmp;
314

    
315
    tmp = (int32_t)T0;
316
    T0 = (int32_t)T0 - (int32_t)T1;
317
    if (((tmp ^ T1) & (tmp ^ T0)) >> 31) {
318
        /* operands of different sign, first operand and result different sign */
319
        CALL_FROM_TB1(do_raise_exception, EXCP_OVERFLOW);
320
    }
321
    T0 = (int32_t)T0;
322
    FORCE_RET();
323
}
324

    
325
void op_mul (void)
326
{
327
    T0 = (int32_t)((int32_t)T0 * (int32_t)T1);
328
    FORCE_RET();
329
}
330

    
331
#if HOST_LONG_BITS < 64
332
void op_div (void)
333
{
334
    CALL_FROM_TB0(do_div);
335
    FORCE_RET();
336
}
337
#else
338
void op_div (void)
339
{
340
    if (T1 != 0) {
341
        env->LO[env->current_tc][0] = (int32_t)((int64_t)(int32_t)T0 / (int32_t)T1);
342
        env->HI[env->current_tc][0] = (int32_t)((int64_t)(int32_t)T0 % (int32_t)T1);
343
    }
344
    FORCE_RET();
345
}
346
#endif
347

    
348
void op_divu (void)
349
{
350
    if (T1 != 0) {
351
        env->LO[env->current_tc][0] = (int32_t)((uint32_t)T0 / (uint32_t)T1);
352
        env->HI[env->current_tc][0] = (int32_t)((uint32_t)T0 % (uint32_t)T1);
353
    }
354
    FORCE_RET();
355
}
356

    
357
#if defined(TARGET_MIPS64)
358
/* Arithmetic */
359
void op_dadd (void)
360
{
361
    T0 += T1;
362
    FORCE_RET();
363
}
364

    
365
void op_daddo (void)
366
{
367
    target_long tmp;
368

    
369
    tmp = T0;
370
    T0 += T1;
371
    if (((tmp ^ T1 ^ (-1)) & (T0 ^ T1)) >> 63) {
372
        /* operands of same sign, result different sign */
373
        CALL_FROM_TB1(do_raise_exception, EXCP_OVERFLOW);
374
    }
375
    FORCE_RET();
376
}
377

    
378
void op_dsub (void)
379
{
380
    T0 -= T1;
381
    FORCE_RET();
382
}
383

    
384
void op_dsubo (void)
385
{
386
    target_long tmp;
387

    
388
    tmp = T0;
389
    T0 = (int64_t)T0 - (int64_t)T1;
390
    if (((tmp ^ T1) & (tmp ^ T0)) >> 63) {
391
        /* operands of different sign, first operand and result different sign */
392
        CALL_FROM_TB1(do_raise_exception, EXCP_OVERFLOW);
393
    }
394
    FORCE_RET();
395
}
396

    
397
void op_dmul (void)
398
{
399
    T0 = (int64_t)T0 * (int64_t)T1;
400
    FORCE_RET();
401
}
402

    
403
/* Those might call libgcc functions.  */
404
void op_ddiv (void)
405
{
406
    do_ddiv();
407
    FORCE_RET();
408
}
409

    
410
#if TARGET_LONG_BITS > HOST_LONG_BITS
411
void op_ddivu (void)
412
{
413
    do_ddivu();
414
    FORCE_RET();
415
}
416
#else
417
void op_ddivu (void)
418
{
419
    if (T1 != 0) {
420
        env->LO[env->current_tc][0] = T0 / T1;
421
        env->HI[env->current_tc][0] = T0 % T1;
422
    }
423
    FORCE_RET();
424
}
425
#endif
426
#endif /* TARGET_MIPS64 */
427

    
428
/* Logical */
429
void op_and (void)
430
{
431
    T0 &= T1;
432
    FORCE_RET();
433
}
434

    
435
void op_nor (void)
436
{
437
    T0 = ~(T0 | T1);
438
    FORCE_RET();
439
}
440

    
441
void op_or (void)
442
{
443
    T0 |= T1;
444
    FORCE_RET();
445
}
446

    
447
void op_xor (void)
448
{
449
    T0 ^= T1;
450
    FORCE_RET();
451
}
452

    
453
void op_sll (void)
454
{
455
    T0 = (int32_t)((uint32_t)T0 << T1);
456
    FORCE_RET();
457
}
458

    
459
void op_sra (void)
460
{
461
    T0 = (int32_t)((int32_t)T0 >> T1);
462
    FORCE_RET();
463
}
464

    
465
void op_srl (void)
466
{
467
    T0 = (int32_t)((uint32_t)T0 >> T1);
468
    FORCE_RET();
469
}
470

    
471
void op_rotr (void)
472
{
473
    target_ulong tmp;
474

    
475
    if (T1) {
476
       tmp = (int32_t)((uint32_t)T0 << (0x20 - T1));
477
       T0 = (int32_t)((uint32_t)T0 >> T1) | tmp;
478
    }
479
    FORCE_RET();
480
}
481

    
482
void op_sllv (void)
483
{
484
    T0 = (int32_t)((uint32_t)T1 << ((uint32_t)T0 & 0x1F));
485
    FORCE_RET();
486
}
487

    
488
void op_srav (void)
489
{
490
    T0 = (int32_t)((int32_t)T1 >> (T0 & 0x1F));
491
    FORCE_RET();
492
}
493

    
494
void op_srlv (void)
495
{
496
    T0 = (int32_t)((uint32_t)T1 >> (T0 & 0x1F));
497
    FORCE_RET();
498
}
499

    
500
void op_rotrv (void)
501
{
502
    target_ulong tmp;
503

    
504
    T0 &= 0x1F;
505
    if (T0) {
506
       tmp = (int32_t)((uint32_t)T1 << (0x20 - T0));
507
       T0 = (int32_t)((uint32_t)T1 >> T0) | tmp;
508
    } else
509
       T0 = T1;
510
    FORCE_RET();
511
}
512

    
513
void op_clo (void)
514
{
515
    T0 = clo32(T0);
516
    FORCE_RET();
517
}
518

    
519
void op_clz (void)
520
{
521
    T0 = clz32(T0);
522
    FORCE_RET();
523
}
524

    
525
#if defined(TARGET_MIPS64)
526

    
527
#if TARGET_LONG_BITS > HOST_LONG_BITS
528
/* Those might call libgcc functions.  */
529
void op_dsll (void)
530
{
531
    CALL_FROM_TB0(do_dsll);
532
    FORCE_RET();
533
}
534

    
535
void op_dsll32 (void)
536
{
537
    CALL_FROM_TB0(do_dsll32);
538
    FORCE_RET();
539
}
540

    
541
void op_dsra (void)
542
{
543
    CALL_FROM_TB0(do_dsra);
544
    FORCE_RET();
545
}
546

    
547
void op_dsra32 (void)
548
{
549
    CALL_FROM_TB0(do_dsra32);
550
    FORCE_RET();
551
}
552

    
553
void op_dsrl (void)
554
{
555
    CALL_FROM_TB0(do_dsrl);
556
    FORCE_RET();
557
}
558

    
559
void op_dsrl32 (void)
560
{
561
    CALL_FROM_TB0(do_dsrl32);
562
    FORCE_RET();
563
}
564

    
565
void op_drotr (void)
566
{
567
    CALL_FROM_TB0(do_drotr);
568
    FORCE_RET();
569
}
570

    
571
void op_drotr32 (void)
572
{
573
    CALL_FROM_TB0(do_drotr32);
574
    FORCE_RET();
575
}
576

    
577
void op_dsllv (void)
578
{
579
    CALL_FROM_TB0(do_dsllv);
580
    FORCE_RET();
581
}
582

    
583
void op_dsrav (void)
584
{
585
    CALL_FROM_TB0(do_dsrav);
586
    FORCE_RET();
587
}
588

    
589
void op_dsrlv (void)
590
{
591
    CALL_FROM_TB0(do_dsrlv);
592
    FORCE_RET();
593
}
594

    
595
void op_drotrv (void)
596
{
597
    CALL_FROM_TB0(do_drotrv);
598
    FORCE_RET();
599
}
600

    
601
void op_dclo (void)
602
{
603
    CALL_FROM_TB0(do_dclo);
604
    FORCE_RET();
605
}
606

    
607
void op_dclz (void)
608
{
609
    CALL_FROM_TB0(do_dclz);
610
    FORCE_RET();
611
}
612

    
613
#else /* TARGET_LONG_BITS > HOST_LONG_BITS */
614

    
615
void op_dsll (void)
616
{
617
    T0 = T0 << T1;
618
    FORCE_RET();
619
}
620

    
621
void op_dsll32 (void)
622
{
623
    T0 = T0 << (T1 + 32);
624
    FORCE_RET();
625
}
626

    
627
void op_dsra (void)
628
{
629
    T0 = (int64_t)T0 >> T1;
630
    FORCE_RET();
631
}
632

    
633
void op_dsra32 (void)
634
{
635
    T0 = (int64_t)T0 >> (T1 + 32);
636
    FORCE_RET();
637
}
638

    
639
void op_dsrl (void)
640
{
641
    T0 = T0 >> T1;
642
    FORCE_RET();
643
}
644

    
645
void op_dsrl32 (void)
646
{
647
    T0 = T0 >> (T1 + 32);
648
    FORCE_RET();
649
}
650

    
651
void op_drotr (void)
652
{
653
    target_ulong tmp;
654

    
655
    if (T1) {
656
        tmp = T0 << (0x40 - T1);
657
        T0 = (T0 >> T1) | tmp;
658
    }
659
    FORCE_RET();
660
}
661

    
662
void op_drotr32 (void)
663
{
664
    target_ulong tmp;
665

    
666
    tmp = T0 << (0x40 - (32 + T1));
667
    T0 = (T0 >> (32 + T1)) | tmp;
668
    FORCE_RET();
669
}
670

    
671
void op_dsllv (void)
672
{
673
    T0 = T1 << (T0 & 0x3F);
674
    FORCE_RET();
675
}
676

    
677
void op_dsrav (void)
678
{
679
    T0 = (int64_t)T1 >> (T0 & 0x3F);
680
    FORCE_RET();
681
}
682

    
683
void op_dsrlv (void)
684
{
685
    T0 = T1 >> (T0 & 0x3F);
686
    FORCE_RET();
687
}
688

    
689
void op_drotrv (void)
690
{
691
    target_ulong tmp;
692

    
693
    T0 &= 0x3F;
694
    if (T0) {
695
        tmp = T1 << (0x40 - T0);
696
        T0 = (T1 >> T0) | tmp;
697
    } else
698
        T0 = T1;
699
    FORCE_RET();
700
}
701

    
702
void op_dclo (void)
703
{
704
    T0 = clo64(T0);
705
    FORCE_RET();
706
}
707

    
708
void op_dclz (void)
709
{
710
    T0 = clz64(T0);
711
    FORCE_RET();
712
}
713
#endif /* TARGET_LONG_BITS > HOST_LONG_BITS */
714
#endif /* TARGET_MIPS64 */
715

    
716
/* 64 bits arithmetic */
717
#if TARGET_LONG_BITS > HOST_LONG_BITS
718
void op_mult (void)
719
{
720
    CALL_FROM_TB0(do_mult);
721
    FORCE_RET();
722
}
723

    
724
void op_multu (void)
725
{
726
    CALL_FROM_TB0(do_multu);
727
    FORCE_RET();
728
}
729

    
730
void op_madd (void)
731
{
732
    CALL_FROM_TB0(do_madd);
733
    FORCE_RET();
734
}
735

    
736
void op_maddu (void)
737
{
738
    CALL_FROM_TB0(do_maddu);
739
    FORCE_RET();
740
}
741

    
742
void op_msub (void)
743
{
744
    CALL_FROM_TB0(do_msub);
745
    FORCE_RET();
746
}
747

    
748
void op_msubu (void)
749
{
750
    CALL_FROM_TB0(do_msubu);
751
    FORCE_RET();
752
}
753

    
754
/* Multiplication variants of the vr54xx. */
755
void op_muls (void)
756
{
757
    CALL_FROM_TB0(do_muls);
758
    FORCE_RET();
759
}
760

    
761
void op_mulsu (void)
762
{
763
    CALL_FROM_TB0(do_mulsu);
764
    FORCE_RET();
765
}
766

    
767
void op_macc (void)
768
{
769
    CALL_FROM_TB0(do_macc);
770
    FORCE_RET();
771
}
772

    
773
void op_macchi (void)
774
{
775
    CALL_FROM_TB0(do_macchi);
776
    FORCE_RET();
777
}
778

    
779
void op_maccu (void)
780
{
781
    CALL_FROM_TB0(do_maccu);
782
    FORCE_RET();
783
}
784
void op_macchiu (void)
785
{
786
    CALL_FROM_TB0(do_macchiu);
787
    FORCE_RET();
788
}
789

    
790
void op_msac (void)
791
{
792
    CALL_FROM_TB0(do_msac);
793
    FORCE_RET();
794
}
795

    
796
void op_msachi (void)
797
{
798
    CALL_FROM_TB0(do_msachi);
799
    FORCE_RET();
800
}
801

    
802
void op_msacu (void)
803
{
804
    CALL_FROM_TB0(do_msacu);
805
    FORCE_RET();
806
}
807

    
808
void op_msachiu (void)
809
{
810
    CALL_FROM_TB0(do_msachiu);
811
    FORCE_RET();
812
}
813

    
814
void op_mulhi (void)
815
{
816
    CALL_FROM_TB0(do_mulhi);
817
    FORCE_RET();
818
}
819

    
820
void op_mulhiu (void)
821
{
822
    CALL_FROM_TB0(do_mulhiu);
823
    FORCE_RET();
824
}
825

    
826
void op_mulshi (void)
827
{
828
    CALL_FROM_TB0(do_mulshi);
829
    FORCE_RET();
830
}
831

    
832
void op_mulshiu (void)
833
{
834
    CALL_FROM_TB0(do_mulshiu);
835
    FORCE_RET();
836
}
837

    
838
#else /* TARGET_LONG_BITS > HOST_LONG_BITS */
839

    
840
static always_inline uint64_t get_HILO (void)
841
{
842
    return ((uint64_t)env->HI[env->current_tc][0] << 32) |
843
            ((uint64_t)(uint32_t)env->LO[env->current_tc][0]);
844
}
845

    
846
static always_inline void set_HILO (uint64_t HILO)
847
{
848
    env->LO[env->current_tc][0] = (int32_t)(HILO & 0xFFFFFFFF);
849
    env->HI[env->current_tc][0] = (int32_t)(HILO >> 32);
850
}
851

    
852
static always_inline void set_HIT0_LO (uint64_t HILO)
853
{
854
    env->LO[env->current_tc][0] = (int32_t)(HILO & 0xFFFFFFFF);
855
    T0 = env->HI[env->current_tc][0] = (int32_t)(HILO >> 32);
856
}
857

    
858
static always_inline void set_HI_LOT0 (uint64_t HILO)
859
{
860
    T0 = env->LO[env->current_tc][0] = (int32_t)(HILO & 0xFFFFFFFF);
861
    env->HI[env->current_tc][0] = (int32_t)(HILO >> 32);
862
}
863

    
864
void op_mult (void)
865
{
866
    set_HILO((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
867
    FORCE_RET();
868
}
869

    
870
void op_multu (void)
871
{
872
    set_HILO((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
873
    FORCE_RET();
874
}
875

    
876
void op_madd (void)
877
{
878
    int64_t tmp;
879

    
880
    tmp = ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
881
    set_HILO((int64_t)get_HILO() + tmp);
882
    FORCE_RET();
883
}
884

    
885
void op_maddu (void)
886
{
887
    uint64_t tmp;
888

    
889
    tmp = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
890
    set_HILO(get_HILO() + tmp);
891
    FORCE_RET();
892
}
893

    
894
void op_msub (void)
895
{
896
    int64_t tmp;
897

    
898
    tmp = ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
899
    set_HILO((int64_t)get_HILO() - tmp);
900
    FORCE_RET();
901
}
902

    
903
void op_msubu (void)
904
{
905
    uint64_t tmp;
906

    
907
    tmp = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
908
    set_HILO(get_HILO() - tmp);
909
    FORCE_RET();
910
}
911

    
912
/* Multiplication variants of the vr54xx. */
913
void op_muls (void)
914
{
915
    set_HI_LOT0(0 - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
916
    FORCE_RET();
917
}
918

    
919
void op_mulsu (void)
920
{
921
    set_HI_LOT0(0 - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
922
    FORCE_RET();
923
}
924

    
925
void op_macc (void)
926
{
927
    set_HI_LOT0(get_HILO() + ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
928
    FORCE_RET();
929
}
930

    
931
void op_macchi (void)
932
{
933
    set_HIT0_LO(get_HILO() + ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
934
    FORCE_RET();
935
}
936

    
937
void op_maccu (void)
938
{
939
    set_HI_LOT0(get_HILO() + ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
940
    FORCE_RET();
941
}
942

    
943
void op_macchiu (void)
944
{
945
    set_HIT0_LO(get_HILO() + ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
946
    FORCE_RET();
947
}
948

    
949
void op_msac (void)
950
{
951
    set_HI_LOT0(get_HILO() - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
952
    FORCE_RET();
953
}
954

    
955
void op_msachi (void)
956
{
957
    set_HIT0_LO(get_HILO() - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
958
    FORCE_RET();
959
}
960

    
961
void op_msacu (void)
962
{
963
    set_HI_LOT0(get_HILO() - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
964
    FORCE_RET();
965
}
966

    
967
void op_msachiu (void)
968
{
969
    set_HIT0_LO(get_HILO() - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
970
    FORCE_RET();
971
}
972

    
973
void op_mulhi (void)
974
{
975
    set_HIT0_LO((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
976
    FORCE_RET();
977
}
978

    
979
void op_mulhiu (void)
980
{
981
    set_HIT0_LO((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
982
    FORCE_RET();
983
}
984

    
985
void op_mulshi (void)
986
{
987
    set_HIT0_LO(0 - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
988
    FORCE_RET();
989
}
990

    
991
void op_mulshiu (void)
992
{
993
    set_HIT0_LO(0 - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
994
    FORCE_RET();
995
}
996

    
997
#endif /* TARGET_LONG_BITS > HOST_LONG_BITS */
998

    
999
#if defined(TARGET_MIPS64)
1000
void op_dmult (void)
1001
{
1002
    CALL_FROM_TB4(muls64, &(env->LO[env->current_tc][0]), &(env->HI[env->current_tc][0]), T0, T1);
1003
    FORCE_RET();
1004
}
1005

    
1006
void op_dmultu (void)
1007
{
1008
    CALL_FROM_TB4(mulu64, &(env->LO[env->current_tc][0]), &(env->HI[env->current_tc][0]), T0, T1);
1009
    FORCE_RET();
1010
}
1011
#endif
1012

    
1013
/* Conditional moves */
1014
void op_movn (void)
1015
{
1016
    if (T1 != 0)
1017
        env->gpr[env->current_tc][PARAM1] = T0;
1018
    FORCE_RET();
1019
}
1020

    
1021
void op_movz (void)
1022
{
1023
    if (T1 == 0)
1024
        env->gpr[env->current_tc][PARAM1] = T0;
1025
    FORCE_RET();
1026
}
1027

    
1028
void op_movf (void)
1029
{
1030
    if (!(env->fpu->fcr31 & PARAM1))
1031
        T0 = T1;
1032
    FORCE_RET();
1033
}
1034

    
1035
void op_movt (void)
1036
{
1037
    if (env->fpu->fcr31 & PARAM1)
1038
        T0 = T1;
1039
    FORCE_RET();
1040
}
1041

    
1042
/* Tests */
1043
#define OP_COND(name, cond) \
1044
void glue(op_, name) (void) \
1045
{                           \
1046
    if (cond) {             \
1047
        T0 = 1;             \
1048
    } else {                \
1049
        T0 = 0;             \
1050
    }                       \
1051
    FORCE_RET();            \
1052
}
1053

    
1054
OP_COND(eq, T0 == T1);
1055
OP_COND(ne, T0 != T1);
1056
OP_COND(ge, (target_long)T0 >= (target_long)T1);
1057
OP_COND(geu, T0 >= T1);
1058
OP_COND(lt, (target_long)T0 < (target_long)T1);
1059
OP_COND(ltu, T0 < T1);
1060
OP_COND(gez, (target_long)T0 >= 0);
1061
OP_COND(gtz, (target_long)T0 > 0);
1062
OP_COND(lez, (target_long)T0 <= 0);
1063
OP_COND(ltz, (target_long)T0 < 0);
1064

    
1065
/* Branches */
1066
/* Branch to register */
1067
void op_save_breg_target (void)
1068
{
1069
    env->btarget = T1;
1070
    FORCE_RET();
1071
}
1072

    
1073
void op_breg (void)
1074
{
1075
    env->PC[env->current_tc] = env->btarget;
1076
    FORCE_RET();
1077
}
1078

    
1079
void op_save_btarget (void)
1080
{
1081
    env->btarget = PARAM1;
1082
    FORCE_RET();
1083
}
1084

    
1085
#if defined(TARGET_MIPS64)
1086
void op_save_btarget64 (void)
1087
{
1088
    env->btarget = ((uint64_t)PARAM1 << 32) | (uint32_t)PARAM2;
1089
    FORCE_RET();
1090
}
1091
#endif
1092

    
1093
/* Conditional branch */
1094
void op_set_bcond (void)
1095
{
1096
    env->bcond = T0;
1097
    FORCE_RET();
1098
}
1099

    
1100
void op_jnz_bcond (void)
1101
{
1102
    if (env->bcond)
1103
        GOTO_LABEL_PARAM(1);
1104
    FORCE_RET();
1105
}
1106

    
1107
/* CP0 functions */
1108
void op_mfc0_index (void)
1109
{
1110
    T0 = env->CP0_Index;
1111
    FORCE_RET();
1112
}
1113

    
1114
void op_mfc0_mvpcontrol (void)
1115
{
1116
    T0 = env->mvp->CP0_MVPControl;
1117
    FORCE_RET();
1118
}
1119

    
1120
void op_mfc0_mvpconf0 (void)
1121
{
1122
    T0 = env->mvp->CP0_MVPConf0;
1123
    FORCE_RET();
1124
}
1125

    
1126
void op_mfc0_mvpconf1 (void)
1127
{
1128
    T0 = env->mvp->CP0_MVPConf1;
1129
    FORCE_RET();
1130
}
1131

    
1132
void op_mfc0_random (void)
1133
{
1134
    CALL_FROM_TB0(do_mfc0_random);
1135
    FORCE_RET();
1136
}
1137

    
1138
void op_mfc0_vpecontrol (void)
1139
{
1140
    T0 = env->CP0_VPEControl;
1141
    FORCE_RET();
1142
}
1143

    
1144
void op_mfc0_vpeconf0 (void)
1145
{
1146
    T0 = env->CP0_VPEConf0;
1147
    FORCE_RET();
1148
}
1149

    
1150
void op_mfc0_vpeconf1 (void)
1151
{
1152
    T0 = env->CP0_VPEConf1;
1153
    FORCE_RET();
1154
}
1155

    
1156
void op_mfc0_yqmask (void)
1157
{
1158
    T0 = env->CP0_YQMask;
1159
    FORCE_RET();
1160
}
1161

    
1162
void op_mfc0_vpeschedule (void)
1163
{
1164
    T0 = env->CP0_VPESchedule;
1165
    FORCE_RET();
1166
}
1167

    
1168
void op_mfc0_vpeschefback (void)
1169
{
1170
    T0 = env->CP0_VPEScheFBack;
1171
    FORCE_RET();
1172
}
1173

    
1174
void op_mfc0_vpeopt (void)
1175
{
1176
    T0 = env->CP0_VPEOpt;
1177
    FORCE_RET();
1178
}
1179

    
1180
void op_mfc0_entrylo0 (void)
1181
{
1182
    T0 = (int32_t)env->CP0_EntryLo0;
1183
    FORCE_RET();
1184
}
1185

    
1186
void op_mfc0_tcstatus (void)
1187
{
1188
    T0 = env->CP0_TCStatus[env->current_tc];
1189
    FORCE_RET();
1190
}
1191

    
1192
void op_mftc0_tcstatus(void)
1193
{
1194
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1195

    
1196
    T0 = env->CP0_TCStatus[other_tc];
1197
    FORCE_RET();
1198
}
1199

    
1200
void op_mfc0_tcbind (void)
1201
{
1202
    T0 = env->CP0_TCBind[env->current_tc];
1203
    FORCE_RET();
1204
}
1205

    
1206
void op_mftc0_tcbind(void)
1207
{
1208
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1209

    
1210
    T0 = env->CP0_TCBind[other_tc];
1211
    FORCE_RET();
1212
}
1213

    
1214
void op_mfc0_tcrestart (void)
1215
{
1216
    T0 = env->PC[env->current_tc];
1217
    FORCE_RET();
1218
}
1219

    
1220
void op_mftc0_tcrestart(void)
1221
{
1222
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1223

    
1224
    T0 = env->PC[other_tc];
1225
    FORCE_RET();
1226
}
1227

    
1228
void op_mfc0_tchalt (void)
1229
{
1230
    T0 = env->CP0_TCHalt[env->current_tc];
1231
    FORCE_RET();
1232
}
1233

    
1234
void op_mftc0_tchalt(void)
1235
{
1236
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1237

    
1238
    T0 = env->CP0_TCHalt[other_tc];
1239
    FORCE_RET();
1240
}
1241

    
1242
void op_mfc0_tccontext (void)
1243
{
1244
    T0 = env->CP0_TCContext[env->current_tc];
1245
    FORCE_RET();
1246
}
1247

    
1248
void op_mftc0_tccontext(void)
1249
{
1250
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1251

    
1252
    T0 = env->CP0_TCContext[other_tc];
1253
    FORCE_RET();
1254
}
1255

    
1256
void op_mfc0_tcschedule (void)
1257
{
1258
    T0 = env->CP0_TCSchedule[env->current_tc];
1259
    FORCE_RET();
1260
}
1261

    
1262
void op_mftc0_tcschedule(void)
1263
{
1264
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1265

    
1266
    T0 = env->CP0_TCSchedule[other_tc];
1267
    FORCE_RET();
1268
}
1269

    
1270
void op_mfc0_tcschefback (void)
1271
{
1272
    T0 = env->CP0_TCScheFBack[env->current_tc];
1273
    FORCE_RET();
1274
}
1275

    
1276
void op_mftc0_tcschefback(void)
1277
{
1278
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1279

    
1280
    T0 = env->CP0_TCScheFBack[other_tc];
1281
    FORCE_RET();
1282
}
1283

    
1284
void op_mfc0_entrylo1 (void)
1285
{
1286
    T0 = (int32_t)env->CP0_EntryLo1;
1287
    FORCE_RET();
1288
}
1289

    
1290
void op_mfc0_context (void)
1291
{
1292
    T0 = (int32_t)env->CP0_Context;
1293
    FORCE_RET();
1294
}
1295

    
1296
void op_mfc0_pagemask (void)
1297
{
1298
    T0 = env->CP0_PageMask;
1299
    FORCE_RET();
1300
}
1301

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

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

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

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

    
1326
void op_mfc0_srsconf2 (void)
1327
{
1328
    T0 = env->CP0_SRSConf2;
1329
    FORCE_RET();
1330
}
1331

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

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

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

    
1350
void op_mfc0_badvaddr (void)
1351
{
1352
    T0 = (int32_t)env->CP0_BadVAddr;
1353
    FORCE_RET();
1354
}
1355

    
1356
void op_mfc0_count (void)
1357
{
1358
    CALL_FROM_TB0(do_mfc0_count);
1359
    FORCE_RET();
1360
}
1361

    
1362
void op_mfc0_entryhi (void)
1363
{
1364
    T0 = (int32_t)env->CP0_EntryHi;
1365
    FORCE_RET();
1366
}
1367

    
1368
void op_mftc0_entryhi(void)
1369
{
1370
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1371

    
1372
    T0 = (env->CP0_EntryHi & ~0xff) | (env->CP0_TCStatus[other_tc] & 0xff);
1373
    FORCE_RET();
1374
}
1375

    
1376
void op_mfc0_compare (void)
1377
{
1378
    T0 = env->CP0_Compare;
1379
    FORCE_RET();
1380
}
1381

    
1382
void op_mfc0_status (void)
1383
{
1384
    T0 = env->CP0_Status;
1385
    FORCE_RET();
1386
}
1387

    
1388
void op_mftc0_status(void)
1389
{
1390
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1391
    uint32_t tcstatus = env->CP0_TCStatus[other_tc];
1392

    
1393
    T0 = env->CP0_Status & ~0xf1000018;
1394
    T0 |= tcstatus & (0xf << CP0TCSt_TCU0);
1395
    T0 |= (tcstatus & (1 << CP0TCSt_TMX)) >> (CP0TCSt_TMX - CP0St_MX);
1396
    T0 |= (tcstatus & (0x3 << CP0TCSt_TKSU)) >> (CP0TCSt_TKSU - CP0St_KSU);
1397
    FORCE_RET();
1398
}
1399

    
1400
void op_mfc0_intctl (void)
1401
{
1402
    T0 = env->CP0_IntCtl;
1403
    FORCE_RET();
1404
}
1405

    
1406
void op_mfc0_srsctl (void)
1407
{
1408
    T0 = env->CP0_SRSCtl;
1409
    FORCE_RET();
1410
}
1411

    
1412
void op_mfc0_srsmap (void)
1413
{
1414
    T0 = env->CP0_SRSMap;
1415
    FORCE_RET();
1416
}
1417

    
1418
void op_mfc0_cause (void)
1419
{
1420
    T0 = env->CP0_Cause;
1421
    FORCE_RET();
1422
}
1423

    
1424
void op_mfc0_epc (void)
1425
{
1426
    T0 = (int32_t)env->CP0_EPC;
1427
    FORCE_RET();
1428
}
1429

    
1430
void op_mfc0_prid (void)
1431
{
1432
    T0 = env->CP0_PRid;
1433
    FORCE_RET();
1434
}
1435

    
1436
void op_mfc0_ebase (void)
1437
{
1438
    T0 = env->CP0_EBase;
1439
    FORCE_RET();
1440
}
1441

    
1442
void op_mfc0_config0 (void)
1443
{
1444
    T0 = env->CP0_Config0;
1445
    FORCE_RET();
1446
}
1447

    
1448
void op_mfc0_config1 (void)
1449
{
1450
    T0 = env->CP0_Config1;
1451
    FORCE_RET();
1452
}
1453

    
1454
void op_mfc0_config2 (void)
1455
{
1456
    T0 = env->CP0_Config2;
1457
    FORCE_RET();
1458
}
1459

    
1460
void op_mfc0_config3 (void)
1461
{
1462
    T0 = env->CP0_Config3;
1463
    FORCE_RET();
1464
}
1465

    
1466
void op_mfc0_config6 (void)
1467
{
1468
    T0 = env->CP0_Config6;
1469
    FORCE_RET();
1470
}
1471

    
1472
void op_mfc0_config7 (void)
1473
{
1474
    T0 = env->CP0_Config7;
1475
    FORCE_RET();
1476
}
1477

    
1478
void op_mfc0_lladdr (void)
1479
{
1480
    T0 = (int32_t)env->CP0_LLAddr >> 4;
1481
    FORCE_RET();
1482
}
1483

    
1484
void op_mfc0_watchlo (void)
1485
{
1486
    T0 = (int32_t)env->CP0_WatchLo[PARAM1];
1487
    FORCE_RET();
1488
}
1489

    
1490
void op_mfc0_watchhi (void)
1491
{
1492
    T0 = env->CP0_WatchHi[PARAM1];
1493
    FORCE_RET();
1494
}
1495

    
1496
void op_mfc0_xcontext (void)
1497
{
1498
    T0 = (int32_t)env->CP0_XContext;
1499
    FORCE_RET();
1500
}
1501

    
1502
void op_mfc0_framemask (void)
1503
{
1504
    T0 = env->CP0_Framemask;
1505
    FORCE_RET();
1506
}
1507

    
1508
void op_mfc0_debug (void)
1509
{
1510
    T0 = env->CP0_Debug;
1511
    if (env->hflags & MIPS_HFLAG_DM)
1512
        T0 |= 1 << CP0DB_DM;
1513
    FORCE_RET();
1514
}
1515

    
1516
void op_mftc0_debug(void)
1517
{
1518
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1519

    
1520
    /* XXX: Might be wrong, check with EJTAG spec. */
1521
    T0 = (env->CP0_Debug & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) |
1522
         (env->CP0_Debug_tcstatus[other_tc] &
1523
          ((1 << CP0DB_SSt) | (1 << CP0DB_Halt)));
1524
    FORCE_RET();
1525
}
1526

    
1527
void op_mfc0_depc (void)
1528
{
1529
    T0 = (int32_t)env->CP0_DEPC;
1530
    FORCE_RET();
1531
}
1532

    
1533
void op_mfc0_performance0 (void)
1534
{
1535
    T0 = env->CP0_Performance0;
1536
    FORCE_RET();
1537
}
1538

    
1539
void op_mfc0_taglo (void)
1540
{
1541
    T0 = env->CP0_TagLo;
1542
    FORCE_RET();
1543
}
1544

    
1545
void op_mfc0_datalo (void)
1546
{
1547
    T0 = env->CP0_DataLo;
1548
    FORCE_RET();
1549
}
1550

    
1551
void op_mfc0_taghi (void)
1552
{
1553
    T0 = env->CP0_TagHi;
1554
    FORCE_RET();
1555
}
1556

    
1557
void op_mfc0_datahi (void)
1558
{
1559
    T0 = env->CP0_DataHi;
1560
    FORCE_RET();
1561
}
1562

    
1563
void op_mfc0_errorepc (void)
1564
{
1565
    T0 = (int32_t)env->CP0_ErrorEPC;
1566
    FORCE_RET();
1567
}
1568

    
1569
void op_mfc0_desave (void)
1570
{
1571
    T0 = env->CP0_DESAVE;
1572
    FORCE_RET();
1573
}
1574

    
1575
void op_mtc0_index (void)
1576
{
1577
    int num = 1;
1578
    unsigned int tmp = env->tlb->nb_tlb;
1579

    
1580
    do {
1581
        tmp >>= 1;
1582
        num <<= 1;
1583
    } while (tmp);
1584
    env->CP0_Index = (env->CP0_Index & 0x80000000) | (T0 & (num - 1));
1585
    FORCE_RET();
1586
}
1587

    
1588
void op_mtc0_mvpcontrol (void)
1589
{
1590
    uint32_t mask = 0;
1591
    uint32_t newval;
1592

    
1593
    if (env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP))
1594
        mask |= (1 << CP0MVPCo_CPA) | (1 << CP0MVPCo_VPC) |
1595
                (1 << CP0MVPCo_EVP);
1596
    if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
1597
        mask |= (1 << CP0MVPCo_STLB);
1598
    newval = (env->mvp->CP0_MVPControl & ~mask) | (T0 & mask);
1599

    
1600
    // TODO: Enable/disable shared TLB, enable/disable VPEs.
1601

    
1602
    env->mvp->CP0_MVPControl = newval;
1603
    FORCE_RET();
1604
}
1605

    
1606
void op_mtc0_vpecontrol (void)
1607
{
1608
    uint32_t mask;
1609
    uint32_t newval;
1610

    
1611
    mask = (1 << CP0VPECo_YSI) | (1 << CP0VPECo_GSI) |
1612
           (1 << CP0VPECo_TE) | (0xff << CP0VPECo_TargTC);
1613
    newval = (env->CP0_VPEControl & ~mask) | (T0 & mask);
1614

    
1615
    /* Yield scheduler intercept not implemented. */
1616
    /* Gating storage scheduler intercept not implemented. */
1617

    
1618
    // TODO: Enable/disable TCs.
1619

    
1620
    env->CP0_VPEControl = newval;
1621
    FORCE_RET();
1622
}
1623

    
1624
void op_mtc0_vpeconf0 (void)
1625
{
1626
    uint32_t mask = 0;
1627
    uint32_t newval;
1628

    
1629
    if (env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) {
1630
        if (env->CP0_VPEConf0 & (1 << CP0VPEC0_VPA))
1631
            mask |= (0xff << CP0VPEC0_XTC);
1632
        mask |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
1633
    }
1634
    newval = (env->CP0_VPEConf0 & ~mask) | (T0 & mask);
1635

    
1636
    // TODO: TC exclusive handling due to ERL/EXL.
1637

    
1638
    env->CP0_VPEConf0 = newval;
1639
    FORCE_RET();
1640
}
1641

    
1642
void op_mtc0_vpeconf1 (void)
1643
{
1644
    uint32_t mask = 0;
1645
    uint32_t newval;
1646

    
1647
    if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
1648
        mask |= (0xff << CP0VPEC1_NCX) | (0xff << CP0VPEC1_NCP2) |
1649
                (0xff << CP0VPEC1_NCP1);
1650
    newval = (env->CP0_VPEConf1 & ~mask) | (T0 & mask);
1651

    
1652
    /* UDI not implemented. */
1653
    /* CP2 not implemented. */
1654

    
1655
    // TODO: Handle FPU (CP1) binding.
1656

    
1657
    env->CP0_VPEConf1 = newval;
1658
    FORCE_RET();
1659
}
1660

    
1661
void op_mtc0_yqmask (void)
1662
{
1663
    /* Yield qualifier inputs not implemented. */
1664
    env->CP0_YQMask = 0x00000000;
1665
    FORCE_RET();
1666
}
1667

    
1668
void op_mtc0_vpeschedule (void)
1669
{
1670
    env->CP0_VPESchedule = T0;
1671
    FORCE_RET();
1672
}
1673

    
1674
void op_mtc0_vpeschefback (void)
1675
{
1676
    env->CP0_VPEScheFBack = T0;
1677
    FORCE_RET();
1678
}
1679

    
1680
void op_mtc0_vpeopt (void)
1681
{
1682
    env->CP0_VPEOpt = T0 & 0x0000ffff;
1683
    FORCE_RET();
1684
}
1685

    
1686
void op_mtc0_entrylo0 (void)
1687
{
1688
    /* Large physaddr (PABITS) not implemented */
1689
    /* 1k pages not implemented */
1690
    env->CP0_EntryLo0 = T0 & 0x3FFFFFFF;
1691
    FORCE_RET();
1692
}
1693

    
1694
void op_mtc0_tcstatus (void)
1695
{
1696
    uint32_t mask = env->CP0_TCStatus_rw_bitmask;
1697
    uint32_t newval;
1698

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

    
1701
    // TODO: Sync with CP0_Status.
1702

    
1703
    env->CP0_TCStatus[env->current_tc] = newval;
1704
    FORCE_RET();
1705
}
1706

    
1707
void op_mttc0_tcstatus (void)
1708
{
1709
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1710

    
1711
    // TODO: Sync with CP0_Status.
1712

    
1713
    env->CP0_TCStatus[other_tc] = T0;
1714
    FORCE_RET();
1715
}
1716

    
1717
void op_mtc0_tcbind (void)
1718
{
1719
    uint32_t mask = (1 << CP0TCBd_TBE);
1720
    uint32_t newval;
1721

    
1722
    if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
1723
        mask |= (1 << CP0TCBd_CurVPE);
1724
    newval = (env->CP0_TCBind[env->current_tc] & ~mask) | (T0 & mask);
1725
    env->CP0_TCBind[env->current_tc] = newval;
1726
    FORCE_RET();
1727
}
1728

    
1729
void op_mttc0_tcbind (void)
1730
{
1731
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1732
    uint32_t mask = (1 << CP0TCBd_TBE);
1733
    uint32_t newval;
1734

    
1735
    if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
1736
        mask |= (1 << CP0TCBd_CurVPE);
1737
    newval = (env->CP0_TCBind[other_tc] & ~mask) | (T0 & mask);
1738
    env->CP0_TCBind[other_tc] = newval;
1739
    FORCE_RET();
1740
}
1741

    
1742
void op_mtc0_tcrestart (void)
1743
{
1744
    env->PC[env->current_tc] = T0;
1745
    env->CP0_TCStatus[env->current_tc] &= ~(1 << CP0TCSt_TDS);
1746
    env->CP0_LLAddr = 0ULL;
1747
    /* MIPS16 not implemented. */
1748
    FORCE_RET();
1749
}
1750

    
1751
void op_mttc0_tcrestart (void)
1752
{
1753
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1754

    
1755
    env->PC[other_tc] = T0;
1756
    env->CP0_TCStatus[other_tc] &= ~(1 << CP0TCSt_TDS);
1757
    env->CP0_LLAddr = 0ULL;
1758
    /* MIPS16 not implemented. */
1759
    FORCE_RET();
1760
}
1761

    
1762
void op_mtc0_tchalt (void)
1763
{
1764
    env->CP0_TCHalt[env->current_tc] = T0 & 0x1;
1765

    
1766
    // TODO: Halt TC / Restart (if allocated+active) TC.
1767

    
1768
    FORCE_RET();
1769
}
1770

    
1771
void op_mttc0_tchalt (void)
1772
{
1773
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1774

    
1775
    // TODO: Halt TC / Restart (if allocated+active) TC.
1776

    
1777
    env->CP0_TCHalt[other_tc] = T0;
1778
    FORCE_RET();
1779
}
1780

    
1781
void op_mtc0_tccontext (void)
1782
{
1783
    env->CP0_TCContext[env->current_tc] = T0;
1784
    FORCE_RET();
1785
}
1786

    
1787
void op_mttc0_tccontext (void)
1788
{
1789
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1790

    
1791
    env->CP0_TCContext[other_tc] = T0;
1792
    FORCE_RET();
1793
}
1794

    
1795
void op_mtc0_tcschedule (void)
1796
{
1797
    env->CP0_TCSchedule[env->current_tc] = T0;
1798
    FORCE_RET();
1799
}
1800

    
1801
void op_mttc0_tcschedule (void)
1802
{
1803
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1804

    
1805
    env->CP0_TCSchedule[other_tc] = T0;
1806
    FORCE_RET();
1807
}
1808

    
1809
void op_mtc0_tcschefback (void)
1810
{
1811
    env->CP0_TCScheFBack[env->current_tc] = T0;
1812
    FORCE_RET();
1813
}
1814

    
1815
void op_mttc0_tcschefback (void)
1816
{
1817
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1818

    
1819
    env->CP0_TCScheFBack[other_tc] = T0;
1820
    FORCE_RET();
1821
}
1822

    
1823
void op_mtc0_entrylo1 (void)
1824
{
1825
    /* Large physaddr (PABITS) not implemented */
1826
    /* 1k pages not implemented */
1827
    env->CP0_EntryLo1 = T0 & 0x3FFFFFFF;
1828
    FORCE_RET();
1829
}
1830

    
1831
void op_mtc0_context (void)
1832
{
1833
    env->CP0_Context = (env->CP0_Context & 0x007FFFFF) | (T0 & ~0x007FFFFF);
1834
    FORCE_RET();
1835
}
1836

    
1837
void op_mtc0_pagemask (void)
1838
{
1839
    /* 1k pages not implemented */
1840
    env->CP0_PageMask = T0 & (0x1FFFFFFF & (TARGET_PAGE_MASK << 1));
1841
    FORCE_RET();
1842
}
1843

    
1844
void op_mtc0_pagegrain (void)
1845
{
1846
    /* SmartMIPS not implemented */
1847
    /* Large physaddr (PABITS) not implemented */
1848
    /* 1k pages not implemented */
1849
    env->CP0_PageGrain = 0;
1850
    FORCE_RET();
1851
}
1852

    
1853
void op_mtc0_wired (void)
1854
{
1855
    env->CP0_Wired = T0 % env->tlb->nb_tlb;
1856
    FORCE_RET();
1857
}
1858

    
1859
void op_mtc0_srsconf0 (void)
1860
{
1861
    env->CP0_SRSConf0 |= T0 & env->CP0_SRSConf0_rw_bitmask;
1862
    FORCE_RET();
1863
}
1864

    
1865
void op_mtc0_srsconf1 (void)
1866
{
1867
    env->CP0_SRSConf1 |= T0 & env->CP0_SRSConf1_rw_bitmask;
1868
    FORCE_RET();
1869
}
1870

    
1871
void op_mtc0_srsconf2 (void)
1872
{
1873
    env->CP0_SRSConf2 |= T0 & env->CP0_SRSConf2_rw_bitmask;
1874
    FORCE_RET();
1875
}
1876

    
1877
void op_mtc0_srsconf3 (void)
1878
{
1879
    env->CP0_SRSConf3 |= T0 & env->CP0_SRSConf3_rw_bitmask;
1880
    FORCE_RET();
1881
}
1882

    
1883
void op_mtc0_srsconf4 (void)
1884
{
1885
    env->CP0_SRSConf4 |= T0 & env->CP0_SRSConf4_rw_bitmask;
1886
    FORCE_RET();
1887
}
1888

    
1889
void op_mtc0_hwrena (void)
1890
{
1891
    env->CP0_HWREna = T0 & 0x0000000F;
1892
    FORCE_RET();
1893
}
1894

    
1895
void op_mtc0_count (void)
1896
{
1897
    CALL_FROM_TB2(cpu_mips_store_count, env, T0);
1898
    FORCE_RET();
1899
}
1900

    
1901
void op_mtc0_entryhi (void)
1902
{
1903
    target_ulong old, val;
1904

    
1905
    /* 1k pages not implemented */
1906
    val = T0 & ((TARGET_PAGE_MASK << 1) | 0xFF);
1907
#if defined(TARGET_MIPS64)
1908
    val &= env->SEGMask;
1909
#endif
1910
    old = env->CP0_EntryHi;
1911
    env->CP0_EntryHi = val;
1912
    if (env->CP0_Config3 & (1 << CP0C3_MT)) {
1913
        uint32_t tcst = env->CP0_TCStatus[env->current_tc] & ~0xff;
1914
        env->CP0_TCStatus[env->current_tc] = tcst | (val & 0xff);
1915
    }
1916
    /* If the ASID changes, flush qemu's TLB.  */
1917
    if ((old & 0xFF) != (val & 0xFF))
1918
        CALL_FROM_TB2(cpu_mips_tlb_flush, env, 1);
1919
    FORCE_RET();
1920
}
1921

    
1922
void op_mttc0_entryhi(void)
1923
{
1924
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1925

    
1926
    env->CP0_EntryHi = (env->CP0_EntryHi & 0xff) | (T0 & ~0xff);
1927
    env->CP0_TCStatus[other_tc] = (env->CP0_TCStatus[other_tc] & ~0xff) | (T0 & 0xff);
1928
    FORCE_RET();
1929
}
1930

    
1931
void op_mtc0_compare (void)
1932
{
1933
    CALL_FROM_TB2(cpu_mips_store_compare, env, T0);
1934
    FORCE_RET();
1935
}
1936

    
1937
void op_mtc0_status (void)
1938
{
1939
    uint32_t val, old;
1940
    uint32_t mask = env->CP0_Status_rw_bitmask;
1941

    
1942
    val = T0 & mask;
1943
    old = env->CP0_Status;
1944
    env->CP0_Status = (env->CP0_Status & ~mask) | val;
1945
    CALL_FROM_TB1(compute_hflags, env);
1946
    if (loglevel & CPU_LOG_EXEC)
1947
        CALL_FROM_TB2(do_mtc0_status_debug, old, val);
1948
    CALL_FROM_TB1(cpu_mips_update_irq, env);
1949
    FORCE_RET();
1950
}
1951

    
1952
void op_mttc0_status(void)
1953
{
1954
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1955
    uint32_t tcstatus = env->CP0_TCStatus[other_tc];
1956

    
1957
    env->CP0_Status = T0 & ~0xf1000018;
1958
    tcstatus = (tcstatus & ~(0xf << CP0TCSt_TCU0)) | (T0 & (0xf << CP0St_CU0));
1959
    tcstatus = (tcstatus & ~(1 << CP0TCSt_TMX)) | ((T0 & (1 << CP0St_MX)) << (CP0TCSt_TMX - CP0St_MX));
1960
    tcstatus = (tcstatus & ~(0x3 << CP0TCSt_TKSU)) | ((T0 & (0x3 << CP0St_KSU)) << (CP0TCSt_TKSU - CP0St_KSU));
1961
    env->CP0_TCStatus[other_tc] = tcstatus;
1962
    FORCE_RET();
1963
}
1964

    
1965
void op_mtc0_intctl (void)
1966
{
1967
    /* vectored interrupts not implemented, no performance counters. */
1968
    env->CP0_IntCtl = (env->CP0_IntCtl & ~0x000002e0) | (T0 & 0x000002e0);
1969
    FORCE_RET();
1970
}
1971

    
1972
void op_mtc0_srsctl (void)
1973
{
1974
    uint32_t mask = (0xf << CP0SRSCtl_ESS) | (0xf << CP0SRSCtl_PSS);
1975
    env->CP0_SRSCtl = (env->CP0_SRSCtl & ~mask) | (T0 & mask);
1976
    FORCE_RET();
1977
}
1978

    
1979
void op_mtc0_srsmap (void)
1980
{
1981
    env->CP0_SRSMap = T0;
1982
    FORCE_RET();
1983
}
1984

    
1985
void op_mtc0_cause (void)
1986
{
1987
    uint32_t mask = 0x00C00300;
1988
    uint32_t old = env->CP0_Cause;
1989

    
1990
    if (env->insn_flags & ISA_MIPS32R2)
1991
        mask |= 1 << CP0Ca_DC;
1992

    
1993
    env->CP0_Cause = (env->CP0_Cause & ~mask) | (T0 & mask);
1994

    
1995
    if ((old ^ env->CP0_Cause) & (1 << CP0Ca_DC)) {
1996
        if (env->CP0_Cause & (1 << CP0Ca_DC))
1997
            CALL_FROM_TB1(cpu_mips_stop_count, env);
1998
        else
1999
            CALL_FROM_TB1(cpu_mips_start_count, env);
2000
    }
2001

    
2002
    /* Handle the software interrupt as an hardware one, as they
2003
       are very similar */
2004
    if (T0 & CP0Ca_IP_mask) {
2005
        CALL_FROM_TB1(cpu_mips_update_irq, env);
2006
    }
2007
    FORCE_RET();
2008
}
2009

    
2010
void op_mtc0_epc (void)
2011
{
2012
    env->CP0_EPC = T0;
2013
    FORCE_RET();
2014
}
2015

    
2016
void op_mtc0_ebase (void)
2017
{
2018
    /* vectored interrupts not implemented */
2019
    /* Multi-CPU not implemented */
2020
    env->CP0_EBase = 0x80000000 | (T0 & 0x3FFFF000);
2021
    FORCE_RET();
2022
}
2023

    
2024
void op_mtc0_config0 (void)
2025
{
2026
    env->CP0_Config0 = (env->CP0_Config0 & 0x81FFFFF8) | (T0 & 0x00000007);
2027
    FORCE_RET();
2028
}
2029

    
2030
void op_mtc0_config2 (void)
2031
{
2032
    /* tertiary/secondary caches not implemented */
2033
    env->CP0_Config2 = (env->CP0_Config2 & 0x8FFF0FFF);
2034
    FORCE_RET();
2035
}
2036

    
2037
void op_mtc0_watchlo (void)
2038
{
2039
    /* Watch exceptions for instructions, data loads, data stores
2040
       not implemented. */
2041
    env->CP0_WatchLo[PARAM1] = (T0 & ~0x7);
2042
    FORCE_RET();
2043
}
2044

    
2045
void op_mtc0_watchhi (void)
2046
{
2047
    env->CP0_WatchHi[PARAM1] = (T0 & 0x40FF0FF8);
2048
    env->CP0_WatchHi[PARAM1] &= ~(env->CP0_WatchHi[PARAM1] & T0 & 0x7);
2049
    FORCE_RET();
2050
}
2051

    
2052
void op_mtc0_xcontext (void)
2053
{
2054
    target_ulong mask = (1ULL << (env->SEGBITS - 7)) - 1;
2055
    env->CP0_XContext = (env->CP0_XContext & mask) | (T0 & ~mask);
2056
    FORCE_RET();
2057
}
2058

    
2059
void op_mtc0_framemask (void)
2060
{
2061
    env->CP0_Framemask = T0; /* XXX */
2062
    FORCE_RET();
2063
}
2064

    
2065
void op_mtc0_debug (void)
2066
{
2067
    env->CP0_Debug = (env->CP0_Debug & 0x8C03FC1F) | (T0 & 0x13300120);
2068
    if (T0 & (1 << CP0DB_DM))
2069
        env->hflags |= MIPS_HFLAG_DM;
2070
    else
2071
        env->hflags &= ~MIPS_HFLAG_DM;
2072
    FORCE_RET();
2073
}
2074

    
2075
void op_mttc0_debug(void)
2076
{
2077
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2078

    
2079
    /* XXX: Might be wrong, check with EJTAG spec. */
2080
    env->CP0_Debug_tcstatus[other_tc] = T0 & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt));
2081
    env->CP0_Debug = (env->CP0_Debug & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) |
2082
                     (T0 & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt)));
2083
    FORCE_RET();
2084
}
2085

    
2086
void op_mtc0_depc (void)
2087
{
2088
    env->CP0_DEPC = T0;
2089
    FORCE_RET();
2090
}
2091

    
2092
void op_mtc0_performance0 (void)
2093
{
2094
    env->CP0_Performance0 = T0 & 0x000007ff;
2095
    FORCE_RET();
2096
}
2097

    
2098
void op_mtc0_taglo (void)
2099
{
2100
    env->CP0_TagLo = T0 & 0xFFFFFCF6;
2101
    FORCE_RET();
2102
}
2103

    
2104
void op_mtc0_datalo (void)
2105
{
2106
    env->CP0_DataLo = T0; /* XXX */
2107
    FORCE_RET();
2108
}
2109

    
2110
void op_mtc0_taghi (void)
2111
{
2112
    env->CP0_TagHi = T0; /* XXX */
2113
    FORCE_RET();
2114
}
2115

    
2116
void op_mtc0_datahi (void)
2117
{
2118
    env->CP0_DataHi = T0; /* XXX */
2119
    FORCE_RET();
2120
}
2121

    
2122
void op_mtc0_errorepc (void)
2123
{
2124
    env->CP0_ErrorEPC = T0;
2125
    FORCE_RET();
2126
}
2127

    
2128
void op_mtc0_desave (void)
2129
{
2130
    env->CP0_DESAVE = T0;
2131
    FORCE_RET();
2132
}
2133

    
2134
#if defined(TARGET_MIPS64)
2135
void op_dmfc0_yqmask (void)
2136
{
2137
    T0 = env->CP0_YQMask;
2138
    FORCE_RET();
2139
}
2140

    
2141
void op_dmfc0_vpeschedule (void)
2142
{
2143
    T0 = env->CP0_VPESchedule;
2144
    FORCE_RET();
2145
}
2146

    
2147
void op_dmfc0_vpeschefback (void)
2148
{
2149
    T0 = env->CP0_VPEScheFBack;
2150
    FORCE_RET();
2151
}
2152

    
2153
void op_dmfc0_entrylo0 (void)
2154
{
2155
    T0 = env->CP0_EntryLo0;
2156
    FORCE_RET();
2157
}
2158

    
2159
void op_dmfc0_tcrestart (void)
2160
{
2161
    T0 = env->PC[env->current_tc];
2162
    FORCE_RET();
2163
}
2164

    
2165
void op_dmfc0_tchalt (void)
2166
{
2167
    T0 = env->CP0_TCHalt[env->current_tc];
2168
    FORCE_RET();
2169
}
2170

    
2171
void op_dmfc0_tccontext (void)
2172
{
2173
    T0 = env->CP0_TCContext[env->current_tc];
2174
    FORCE_RET();
2175
}
2176

    
2177
void op_dmfc0_tcschedule (void)
2178
{
2179
    T0 = env->CP0_TCSchedule[env->current_tc];
2180
    FORCE_RET();
2181
}
2182

    
2183
void op_dmfc0_tcschefback (void)
2184
{
2185
    T0 = env->CP0_TCScheFBack[env->current_tc];
2186
    FORCE_RET();
2187
}
2188

    
2189
void op_dmfc0_entrylo1 (void)
2190
{
2191
    T0 = env->CP0_EntryLo1;
2192
    FORCE_RET();
2193
}
2194

    
2195
void op_dmfc0_context (void)
2196
{
2197
    T0 = env->CP0_Context;
2198
    FORCE_RET();
2199
}
2200

    
2201
void op_dmfc0_badvaddr (void)
2202
{
2203
    T0 = env->CP0_BadVAddr;
2204
    FORCE_RET();
2205
}
2206

    
2207
void op_dmfc0_entryhi (void)
2208
{
2209
    T0 = env->CP0_EntryHi;
2210
    FORCE_RET();
2211
}
2212

    
2213
void op_dmfc0_epc (void)
2214
{
2215
    T0 = env->CP0_EPC;
2216
    FORCE_RET();
2217
}
2218

    
2219
void op_dmfc0_lladdr (void)
2220
{
2221
    T0 = env->CP0_LLAddr >> 4;
2222
    FORCE_RET();
2223
}
2224

    
2225
void op_dmfc0_watchlo (void)
2226
{
2227
    T0 = env->CP0_WatchLo[PARAM1];
2228
    FORCE_RET();
2229
}
2230

    
2231
void op_dmfc0_xcontext (void)
2232
{
2233
    T0 = env->CP0_XContext;
2234
    FORCE_RET();
2235
}
2236

    
2237
void op_dmfc0_depc (void)
2238
{
2239
    T0 = env->CP0_DEPC;
2240
    FORCE_RET();
2241
}
2242

    
2243
void op_dmfc0_errorepc (void)
2244
{
2245
    T0 = env->CP0_ErrorEPC;
2246
    FORCE_RET();
2247
}
2248
#endif /* TARGET_MIPS64 */
2249

    
2250
/* MIPS MT functions */
2251
void op_mftgpr(void)
2252
{
2253
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2254

    
2255
    T0 = env->gpr[other_tc][PARAM1];
2256
    FORCE_RET();
2257
}
2258

    
2259
void op_mftlo(void)
2260
{
2261
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2262

    
2263
    T0 = env->LO[other_tc][PARAM1];
2264
    FORCE_RET();
2265
}
2266

    
2267
void op_mfthi(void)
2268
{
2269
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2270

    
2271
    T0 = env->HI[other_tc][PARAM1];
2272
    FORCE_RET();
2273
}
2274

    
2275
void op_mftacx(void)
2276
{
2277
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2278

    
2279
    T0 = env->ACX[other_tc][PARAM1];
2280
    FORCE_RET();
2281
}
2282

    
2283
void op_mftdsp(void)
2284
{
2285
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2286

    
2287
    T0 = env->DSPControl[other_tc];
2288
    FORCE_RET();
2289
}
2290

    
2291
void op_mttgpr(void)
2292
{
2293
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2294

    
2295
    T0 = env->gpr[other_tc][PARAM1];
2296
    FORCE_RET();
2297
}
2298

    
2299
void op_mttlo(void)
2300
{
2301
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2302

    
2303
    T0 = env->LO[other_tc][PARAM1];
2304
    FORCE_RET();
2305
}
2306

    
2307
void op_mtthi(void)
2308
{
2309
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2310

    
2311
    T0 = env->HI[other_tc][PARAM1];
2312
    FORCE_RET();
2313
}
2314

    
2315
void op_mttacx(void)
2316
{
2317
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2318

    
2319
    T0 = env->ACX[other_tc][PARAM1];
2320
    FORCE_RET();
2321
}
2322

    
2323
void op_mttdsp(void)
2324
{
2325
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
2326

    
2327
    T0 = env->DSPControl[other_tc];
2328
    FORCE_RET();
2329
}
2330

    
2331

    
2332
void op_dmt(void)
2333
{
2334
    // TODO
2335
    T0 = 0;
2336
    // rt = T0
2337
    FORCE_RET();
2338
}
2339

    
2340
void op_emt(void)
2341
{
2342
    // TODO
2343
    T0 = 0;
2344
    // rt = T0
2345
    FORCE_RET();
2346
}
2347

    
2348
void op_dvpe(void)
2349
{
2350
    // TODO
2351
    T0 = 0;
2352
    // rt = T0
2353
    FORCE_RET();
2354
}
2355

    
2356
void op_evpe(void)
2357
{
2358
    // TODO
2359
    T0 = 0;
2360
    // rt = T0
2361
    FORCE_RET();
2362
}
2363

    
2364
void op_fork(void)
2365
{
2366
    // T0 = rt, T1 = rs
2367
    T0 = 0;
2368
    // TODO: store to TC register
2369
    FORCE_RET();
2370
}
2371

    
2372
void op_yield(void)
2373
{
2374
    if (T0 < 0) {
2375
        /* No scheduling policy implemented. */
2376
        if (T0 != -2) {
2377
            if (env->CP0_VPEControl & (1 << CP0VPECo_YSI) &&
2378
                env->CP0_TCStatus[env->current_tc] & (1 << CP0TCSt_DT)) {
2379
                env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT);
2380
                env->CP0_VPEControl |= 4 << CP0VPECo_EXCPT;
2381
                CALL_FROM_TB1(do_raise_exception, EXCP_THREAD);
2382
            }
2383
        }
2384
    } else if (T0 == 0) {
2385
        if (0 /* TODO: TC underflow */) {
2386
            env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT);
2387
            CALL_FROM_TB1(do_raise_exception, EXCP_THREAD);
2388
        } else {
2389
            // TODO: Deallocate TC
2390
        }
2391
    } else if (T0 > 0) {
2392
        /* Yield qualifier inputs not implemented. */
2393
        env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT);
2394
        env->CP0_VPEControl |= 2 << CP0VPECo_EXCPT;
2395
        CALL_FROM_TB1(do_raise_exception, EXCP_THREAD);
2396
    }
2397
    T0 = env->CP0_YQMask;
2398
    FORCE_RET();
2399
}
2400

    
2401
/* CP1 functions */
2402
#if 0
2403
# define DEBUG_FPU_STATE() CALL_FROM_TB1(dump_fpu, env)
2404
#else
2405
# define DEBUG_FPU_STATE() do { } while(0)
2406
#endif
2407

    
2408
void op_cfc1 (void)
2409
{
2410
    CALL_FROM_TB1(do_cfc1, PARAM1);
2411
    DEBUG_FPU_STATE();
2412
    FORCE_RET();
2413
}
2414

    
2415
void op_ctc1 (void)
2416
{
2417
    CALL_FROM_TB1(do_ctc1, PARAM1);
2418
    DEBUG_FPU_STATE();
2419
    FORCE_RET();
2420
}
2421

    
2422
void op_mfc1 (void)
2423
{
2424
    T0 = (int32_t)WT0;
2425
    DEBUG_FPU_STATE();
2426
    FORCE_RET();
2427
}
2428

    
2429
void op_mtc1 (void)
2430
{
2431
    WT0 = T0;
2432
    DEBUG_FPU_STATE();
2433
    FORCE_RET();
2434
}
2435

    
2436
void op_dmfc1 (void)
2437
{
2438
    T0 = DT0;
2439
    DEBUG_FPU_STATE();
2440
    FORCE_RET();
2441
}
2442

    
2443
void op_dmtc1 (void)
2444
{
2445
    DT0 = T0;
2446
    DEBUG_FPU_STATE();
2447
    FORCE_RET();
2448
}
2449

    
2450
void op_mfhc1 (void)
2451
{
2452
    T0 = (int32_t)WTH0;
2453
    DEBUG_FPU_STATE();
2454
    FORCE_RET();
2455
}
2456

    
2457
void op_mthc1 (void)
2458
{
2459
    WTH0 = T0;
2460
    DEBUG_FPU_STATE();
2461
    FORCE_RET();
2462
}
2463

    
2464
/* Float support.
2465
   Single precition routines have a "s" suffix, double precision a
2466
   "d" suffix, 32bit integer "w", 64bit integer "l", paired singe "ps",
2467
   paired single lowwer "pl", paired single upper "pu".  */
2468

    
2469
#define FLOAT_OP(name, p) void OPPROTO op_float_##name##_##p(void)
2470

    
2471
FLOAT_OP(cvtd, s)
2472
{
2473
    CALL_FROM_TB0(do_float_cvtd_s);
2474
    DEBUG_FPU_STATE();
2475
    FORCE_RET();
2476
}
2477
FLOAT_OP(cvtd, w)
2478
{
2479
    CALL_FROM_TB0(do_float_cvtd_w);
2480
    DEBUG_FPU_STATE();
2481
    FORCE_RET();
2482
}
2483
FLOAT_OP(cvtd, l)
2484
{
2485
    CALL_FROM_TB0(do_float_cvtd_l);
2486
    DEBUG_FPU_STATE();
2487
    FORCE_RET();
2488
}
2489
FLOAT_OP(cvtl, d)
2490
{
2491
    CALL_FROM_TB0(do_float_cvtl_d);
2492
    DEBUG_FPU_STATE();
2493
    FORCE_RET();
2494
}
2495
FLOAT_OP(cvtl, s)
2496
{
2497
    CALL_FROM_TB0(do_float_cvtl_s);
2498
    DEBUG_FPU_STATE();
2499
    FORCE_RET();
2500
}
2501
FLOAT_OP(cvtps, s)
2502
{
2503
    WT2 = WT0;
2504
    WTH2 = WT1;
2505
    DEBUG_FPU_STATE();
2506
    FORCE_RET();
2507
}
2508
FLOAT_OP(cvtps, pw)
2509
{
2510
    CALL_FROM_TB0(do_float_cvtps_pw);
2511
    DEBUG_FPU_STATE();
2512
    FORCE_RET();
2513
}
2514
FLOAT_OP(cvtpw, ps)
2515
{
2516
    CALL_FROM_TB0(do_float_cvtpw_ps);
2517
    DEBUG_FPU_STATE();
2518
    FORCE_RET();
2519
}
2520
FLOAT_OP(cvts, d)
2521
{
2522
    CALL_FROM_TB0(do_float_cvts_d);
2523
    DEBUG_FPU_STATE();
2524
    FORCE_RET();
2525
}
2526
FLOAT_OP(cvts, w)
2527
{
2528
    CALL_FROM_TB0(do_float_cvts_w);
2529
    DEBUG_FPU_STATE();
2530
    FORCE_RET();
2531
}
2532
FLOAT_OP(cvts, l)
2533
{
2534
    CALL_FROM_TB0(do_float_cvts_l);
2535
    DEBUG_FPU_STATE();
2536
    FORCE_RET();
2537
}
2538
FLOAT_OP(cvts, pl)
2539
{
2540
    CALL_FROM_TB0(do_float_cvts_pl);
2541
    DEBUG_FPU_STATE();
2542
    FORCE_RET();
2543
}
2544
FLOAT_OP(cvts, pu)
2545
{
2546
    CALL_FROM_TB0(do_float_cvts_pu);
2547
    DEBUG_FPU_STATE();
2548
    FORCE_RET();
2549
}
2550
FLOAT_OP(cvtw, s)
2551
{
2552
    CALL_FROM_TB0(do_float_cvtw_s);
2553
    DEBUG_FPU_STATE();
2554
    FORCE_RET();
2555
}
2556
FLOAT_OP(cvtw, d)
2557
{
2558
    CALL_FROM_TB0(do_float_cvtw_d);
2559
    DEBUG_FPU_STATE();
2560
    FORCE_RET();
2561
}
2562

    
2563
FLOAT_OP(pll, ps)
2564
{
2565
    DT2 = ((uint64_t)WT0 << 32) | WT1;
2566
    DEBUG_FPU_STATE();
2567
    FORCE_RET();
2568
}
2569
FLOAT_OP(plu, ps)
2570
{
2571
    DT2 = ((uint64_t)WT0 << 32) | WTH1;
2572
    DEBUG_FPU_STATE();
2573
    FORCE_RET();
2574
}
2575
FLOAT_OP(pul, ps)
2576
{
2577
    DT2 = ((uint64_t)WTH0 << 32) | WT1;
2578
    DEBUG_FPU_STATE();
2579
    FORCE_RET();
2580
}
2581
FLOAT_OP(puu, ps)
2582
{
2583
    DT2 = ((uint64_t)WTH0 << 32) | WTH1;
2584
    DEBUG_FPU_STATE();
2585
    FORCE_RET();
2586
}
2587

    
2588
#define FLOAT_ROUNDOP(op, ttype, stype)                    \
2589
FLOAT_OP(op ## ttype, stype)                               \
2590
{                                                          \
2591
    CALL_FROM_TB0(do_float_ ## op ## ttype ## _ ## stype); \
2592
    DEBUG_FPU_STATE();                                     \
2593
    FORCE_RET();                                           \
2594
}
2595

    
2596
FLOAT_ROUNDOP(round, l, d)
2597
FLOAT_ROUNDOP(round, l, s)
2598
FLOAT_ROUNDOP(round, w, d)
2599
FLOAT_ROUNDOP(round, w, s)
2600

    
2601
FLOAT_ROUNDOP(trunc, l, d)
2602
FLOAT_ROUNDOP(trunc, l, s)
2603
FLOAT_ROUNDOP(trunc, w, d)
2604
FLOAT_ROUNDOP(trunc, w, s)
2605

    
2606
FLOAT_ROUNDOP(ceil, l, d)
2607
FLOAT_ROUNDOP(ceil, l, s)
2608
FLOAT_ROUNDOP(ceil, w, d)
2609
FLOAT_ROUNDOP(ceil, w, s)
2610

    
2611
FLOAT_ROUNDOP(floor, l, d)
2612
FLOAT_ROUNDOP(floor, l, s)
2613
FLOAT_ROUNDOP(floor, w, d)
2614
FLOAT_ROUNDOP(floor, w, s)
2615
#undef FLOAR_ROUNDOP
2616

    
2617
FLOAT_OP(movf, d)
2618
{
2619
    if (!(env->fpu->fcr31 & PARAM1))
2620
        DT2 = DT0;
2621
    DEBUG_FPU_STATE();
2622
    FORCE_RET();
2623
}
2624
FLOAT_OP(movf, s)
2625
{
2626
    if (!(env->fpu->fcr31 & PARAM1))
2627
        WT2 = WT0;
2628
    DEBUG_FPU_STATE();
2629
    FORCE_RET();
2630
}
2631
FLOAT_OP(movf, ps)
2632
{
2633
    if (!(env->fpu->fcr31 & PARAM1)) {
2634
        WT2 = WT0;
2635
        WTH2 = WTH0;
2636
    }
2637
    DEBUG_FPU_STATE();
2638
    FORCE_RET();
2639
}
2640
FLOAT_OP(movt, d)
2641
{
2642
    if (env->fpu->fcr31 & PARAM1)
2643
        DT2 = DT0;
2644
    DEBUG_FPU_STATE();
2645
    FORCE_RET();
2646
}
2647
FLOAT_OP(movt, s)
2648
{
2649
    if (env->fpu->fcr31 & PARAM1)
2650
        WT2 = WT0;
2651
    DEBUG_FPU_STATE();
2652
    FORCE_RET();
2653
}
2654
FLOAT_OP(movt, ps)
2655
{
2656
    if (env->fpu->fcr31 & PARAM1) {
2657
        WT2 = WT0;
2658
        WTH2 = WTH0;
2659
    }
2660
    DEBUG_FPU_STATE();
2661
    FORCE_RET();
2662
}
2663
FLOAT_OP(movz, d)
2664
{
2665
    if (!T0)
2666
        DT2 = DT0;
2667
    DEBUG_FPU_STATE();
2668
    FORCE_RET();
2669
}
2670
FLOAT_OP(movz, s)
2671
{
2672
    if (!T0)
2673
        WT2 = WT0;
2674
    DEBUG_FPU_STATE();
2675
    FORCE_RET();
2676
}
2677
FLOAT_OP(movz, ps)
2678
{
2679
    if (!T0) {
2680
        WT2 = WT0;
2681
        WTH2 = WTH0;
2682
    }
2683
    DEBUG_FPU_STATE();
2684
    FORCE_RET();
2685
}
2686
FLOAT_OP(movn, d)
2687
{
2688
    if (T0)
2689
        DT2 = DT0;
2690
    DEBUG_FPU_STATE();
2691
    FORCE_RET();
2692
}
2693
FLOAT_OP(movn, s)
2694
{
2695
    if (T0)
2696
        WT2 = WT0;
2697
    DEBUG_FPU_STATE();
2698
    FORCE_RET();
2699
}
2700
FLOAT_OP(movn, ps)
2701
{
2702
    if (T0) {
2703
        WT2 = WT0;
2704
        WTH2 = WTH0;
2705
    }
2706
    DEBUG_FPU_STATE();
2707
    FORCE_RET();
2708
}
2709

    
2710
/* operations calling helpers, for s, d and ps */
2711
#define FLOAT_HOP(name)   \
2712
FLOAT_OP(name, d)         \
2713
{                         \
2714
    CALL_FROM_TB0(do_float_ ## name ## _d);  \
2715
    DEBUG_FPU_STATE();    \
2716
    FORCE_RET();          \
2717
}                         \
2718
FLOAT_OP(name, s)         \
2719
{                         \
2720
    CALL_FROM_TB0(do_float_ ## name ## _s);  \
2721
    DEBUG_FPU_STATE();    \
2722
    FORCE_RET();          \
2723
}                         \
2724
FLOAT_OP(name, ps)        \
2725
{                         \
2726
    CALL_FROM_TB0(do_float_ ## name ## _ps); \
2727
    DEBUG_FPU_STATE();    \
2728
    FORCE_RET();          \
2729
}
2730
FLOAT_HOP(add)
2731
FLOAT_HOP(sub)
2732
FLOAT_HOP(mul)
2733
FLOAT_HOP(div)
2734
FLOAT_HOP(recip2)
2735
FLOAT_HOP(rsqrt2)
2736
FLOAT_HOP(rsqrt1)
2737
FLOAT_HOP(recip1)
2738
#undef FLOAT_HOP
2739

    
2740
/* operations calling helpers, for s and d */
2741
#define FLOAT_HOP(name)   \
2742
FLOAT_OP(name, d)         \
2743
{                         \
2744
    CALL_FROM_TB0(do_float_ ## name ## _d);  \
2745
    DEBUG_FPU_STATE();    \
2746
    FORCE_RET();          \
2747
}                         \
2748
FLOAT_OP(name, s)         \
2749
{                         \
2750
    CALL_FROM_TB0(do_float_ ## name ## _s);  \
2751
    DEBUG_FPU_STATE();    \
2752
    FORCE_RET();          \
2753
}
2754
FLOAT_HOP(rsqrt)
2755
FLOAT_HOP(recip)
2756
#undef FLOAT_HOP
2757

    
2758
/* operations calling helpers, for ps */
2759
#define FLOAT_HOP(name)   \
2760
FLOAT_OP(name, ps)        \
2761
{                         \
2762
    CALL_FROM_TB0(do_float_ ## name ## _ps); \
2763
    DEBUG_FPU_STATE();    \
2764
    FORCE_RET();          \
2765
}
2766
FLOAT_HOP(addr)
2767
FLOAT_HOP(mulr)
2768
#undef FLOAT_HOP
2769

    
2770
/* ternary operations */
2771
#define FLOAT_TERNOP(name1, name2) \
2772
FLOAT_OP(name1 ## name2, d)        \
2773
{                                  \
2774
    FDT0 = float64_ ## name1 (FDT0, FDT1, &env->fpu->fp_status);    \
2775
    FDT2 = float64_ ## name2 (FDT0, FDT2, &env->fpu->fp_status);    \
2776
    DEBUG_FPU_STATE();             \
2777
    FORCE_RET();                   \
2778
}                                  \
2779
FLOAT_OP(name1 ## name2, s)        \
2780
{                                  \
2781
    FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status);    \
2782
    FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status);    \
2783
    DEBUG_FPU_STATE();             \
2784
    FORCE_RET();                   \
2785
}                                  \
2786
FLOAT_OP(name1 ## name2, ps)       \
2787
{                                  \
2788
    FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status);    \
2789
    FSTH0 = float32_ ## name1 (FSTH0, FSTH1, &env->fpu->fp_status); \
2790
    FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status);    \
2791
    FSTH2 = float32_ ## name2 (FSTH0, FSTH2, &env->fpu->fp_status); \
2792
    DEBUG_FPU_STATE();             \
2793
    FORCE_RET();                   \
2794
}
2795
FLOAT_TERNOP(mul, add)
2796
FLOAT_TERNOP(mul, sub)
2797
#undef FLOAT_TERNOP
2798

    
2799
/* negated ternary operations */
2800
#define FLOAT_NTERNOP(name1, name2) \
2801
FLOAT_OP(n ## name1 ## name2, d)    \
2802
{                                   \
2803
    FDT0 = float64_ ## name1 (FDT0, FDT1, &env->fpu->fp_status);    \
2804
    FDT2 = float64_ ## name2 (FDT0, FDT2, &env->fpu->fp_status);    \
2805
    FDT2 = float64_chs(FDT2);       \
2806
    DEBUG_FPU_STATE();              \
2807
    FORCE_RET();                    \
2808
}                                   \
2809
FLOAT_OP(n ## name1 ## name2, s)    \
2810
{                                   \
2811
    FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status);    \
2812
    FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status);    \
2813
    FST2 = float32_chs(FST2);       \
2814
    DEBUG_FPU_STATE();              \
2815
    FORCE_RET();                    \
2816
}                                   \
2817
FLOAT_OP(n ## name1 ## name2, ps)   \
2818
{                                   \
2819
    FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status);    \
2820
    FSTH0 = float32_ ## name1 (FSTH0, FSTH1, &env->fpu->fp_status); \
2821
    FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status);    \
2822
    FSTH2 = float32_ ## name2 (FSTH0, FSTH2, &env->fpu->fp_status); \
2823
    FST2 = float32_chs(FST2);       \
2824
    FSTH2 = float32_chs(FSTH2);     \
2825
    DEBUG_FPU_STATE();              \
2826
    FORCE_RET();                    \
2827
}
2828
FLOAT_NTERNOP(mul, add)
2829
FLOAT_NTERNOP(mul, sub)
2830
#undef FLOAT_NTERNOP
2831

    
2832
/* unary operations, modifying fp status  */
2833
#define FLOAT_UNOP(name)  \
2834
FLOAT_OP(name, d)         \
2835
{                         \
2836
    FDT2 = float64_ ## name(FDT0, &env->fpu->fp_status); \
2837
    DEBUG_FPU_STATE();    \
2838
    FORCE_RET();          \
2839
}                         \
2840
FLOAT_OP(name, s)         \
2841
{                         \
2842
    FST2 = float32_ ## name(FST0, &env->fpu->fp_status); \
2843
    DEBUG_FPU_STATE();    \
2844
    FORCE_RET();          \
2845
}
2846
FLOAT_UNOP(sqrt)
2847
#undef FLOAT_UNOP
2848

    
2849
/* unary operations, not modifying fp status  */
2850
#define FLOAT_UNOP(name)  \
2851
FLOAT_OP(name, d)         \
2852
{                         \
2853
    FDT2 = float64_ ## name(FDT0);   \
2854
    DEBUG_FPU_STATE();    \
2855
    FORCE_RET();          \
2856
}                         \
2857
FLOAT_OP(name, s)         \
2858
{                         \
2859
    FST2 = float32_ ## name(FST0);   \
2860
    DEBUG_FPU_STATE();    \
2861
    FORCE_RET();          \
2862
}                         \
2863
FLOAT_OP(name, ps)        \
2864
{                         \
2865
    FST2 = float32_ ## name(FST0);   \
2866
    FSTH2 = float32_ ## name(FSTH0); \
2867
    DEBUG_FPU_STATE();    \
2868
    FORCE_RET();          \
2869
}
2870
FLOAT_UNOP(abs)
2871
FLOAT_UNOP(chs)
2872
#undef FLOAT_UNOP
2873

    
2874
FLOAT_OP(mov, d)
2875
{
2876
    FDT2 = FDT0;
2877
    DEBUG_FPU_STATE();
2878
    FORCE_RET();
2879
}
2880
FLOAT_OP(mov, s)
2881
{
2882
    FST2 = FST0;
2883
    DEBUG_FPU_STATE();
2884
    FORCE_RET();
2885
}
2886
FLOAT_OP(mov, ps)
2887
{
2888
    FST2 = FST0;
2889
    FSTH2 = FSTH0;
2890
    DEBUG_FPU_STATE();
2891
    FORCE_RET();
2892
}
2893
FLOAT_OP(alnv, ps)
2894
{
2895
    switch (T0 & 0x7) {
2896
    case 0:
2897
        FST2 = FST0;
2898
        FSTH2 = FSTH0;
2899
        break;
2900
    case 4:
2901
#ifdef TARGET_WORDS_BIGENDIAN
2902
        FSTH2 = FST0;
2903
        FST2 = FSTH1;
2904
#else
2905
        FSTH2 = FST1;
2906
        FST2 = FSTH0;
2907
#endif
2908
        break;
2909
    default: /* unpredictable */
2910
        break;
2911
    }
2912
    DEBUG_FPU_STATE();
2913
    FORCE_RET();
2914
}
2915

    
2916
#ifdef CONFIG_SOFTFLOAT
2917
#define clear_invalid() do {                                \
2918
    int flags = get_float_exception_flags(&env->fpu->fp_status); \
2919
    flags &= ~float_flag_invalid;                           \
2920
    set_float_exception_flags(flags, &env->fpu->fp_status); \
2921
} while(0)
2922
#else
2923
#define clear_invalid() do { } while(0)
2924
#endif
2925

    
2926
extern void dump_fpu_s(CPUState *env);
2927

    
2928
#define CMP_OP(fmt, op)                                \
2929
void OPPROTO op_cmp ## _ ## fmt ## _ ## op(void)       \
2930
{                                                      \
2931
    CALL_FROM_TB1(do_cmp ## _ ## fmt ## _ ## op, PARAM1); \
2932
    DEBUG_FPU_STATE();                                 \
2933
    FORCE_RET();                                       \
2934
}                                                      \
2935
void OPPROTO op_cmpabs ## _ ## fmt ## _ ## op(void)    \
2936
{                                                      \
2937
    CALL_FROM_TB1(do_cmpabs ## _ ## fmt ## _ ## op, PARAM1); \
2938
    DEBUG_FPU_STATE();                                 \
2939
    FORCE_RET();                                       \
2940
}
2941
#define CMP_OPS(op)   \
2942
CMP_OP(d, op)         \
2943
CMP_OP(s, op)         \
2944
CMP_OP(ps, op)
2945

    
2946
CMP_OPS(f)
2947
CMP_OPS(un)
2948
CMP_OPS(eq)
2949
CMP_OPS(ueq)
2950
CMP_OPS(olt)
2951
CMP_OPS(ult)
2952
CMP_OPS(ole)
2953
CMP_OPS(ule)
2954
CMP_OPS(sf)
2955
CMP_OPS(ngle)
2956
CMP_OPS(seq)
2957
CMP_OPS(ngl)
2958
CMP_OPS(lt)
2959
CMP_OPS(nge)
2960
CMP_OPS(le)
2961
CMP_OPS(ngt)
2962
#undef CMP_OPS
2963
#undef CMP_OP
2964

    
2965
void op_bc1f (void)
2966
{
2967
    T0 = !!(~GET_FP_COND(env->fpu) & (0x1 << PARAM1));
2968
    DEBUG_FPU_STATE();
2969
    FORCE_RET();
2970
}
2971
void op_bc1any2f (void)
2972
{
2973
    T0 = !!(~GET_FP_COND(env->fpu) & (0x3 << PARAM1));
2974
    DEBUG_FPU_STATE();
2975
    FORCE_RET();
2976
}
2977
void op_bc1any4f (void)
2978
{
2979
    T0 = !!(~GET_FP_COND(env->fpu) & (0xf << PARAM1));
2980
    DEBUG_FPU_STATE();
2981
    FORCE_RET();
2982
}
2983

    
2984
void op_bc1t (void)
2985
{
2986
    T0 = !!(GET_FP_COND(env->fpu) & (0x1 << PARAM1));
2987
    DEBUG_FPU_STATE();
2988
    FORCE_RET();
2989
}
2990
void op_bc1any2t (void)
2991
{
2992
    T0 = !!(GET_FP_COND(env->fpu) & (0x3 << PARAM1));
2993
    DEBUG_FPU_STATE();
2994
    FORCE_RET();
2995
}
2996
void op_bc1any4t (void)
2997
{
2998
    T0 = !!(GET_FP_COND(env->fpu) & (0xf << PARAM1));
2999
    DEBUG_FPU_STATE();
3000
    FORCE_RET();
3001
}
3002

    
3003
void op_tlbwi (void)
3004
{
3005
    CALL_FROM_TB0(env->tlb->do_tlbwi);
3006
    FORCE_RET();
3007
}
3008

    
3009
void op_tlbwr (void)
3010
{
3011
    CALL_FROM_TB0(env->tlb->do_tlbwr);
3012
    FORCE_RET();
3013
}
3014

    
3015
void op_tlbp (void)
3016
{
3017
    CALL_FROM_TB0(env->tlb->do_tlbp);
3018
    FORCE_RET();
3019
}
3020

    
3021
void op_tlbr (void)
3022
{
3023
    CALL_FROM_TB0(env->tlb->do_tlbr);
3024
    FORCE_RET();
3025
}
3026

    
3027
/* Specials */
3028
#if defined (CONFIG_USER_ONLY)
3029
void op_tls_value (void)
3030
{
3031
    T0 = env->tls_value;
3032
}
3033
#endif
3034

    
3035
void op_pmon (void)
3036
{
3037
    CALL_FROM_TB1(do_pmon, PARAM1);
3038
    FORCE_RET();
3039
}
3040

    
3041
void op_di (void)
3042
{
3043
    T0 = env->CP0_Status;
3044
    env->CP0_Status = T0 & ~(1 << CP0St_IE);
3045
    CALL_FROM_TB1(cpu_mips_update_irq, env);
3046
    FORCE_RET();
3047
}
3048

    
3049
void op_ei (void)
3050
{
3051
    T0 = env->CP0_Status;
3052
    env->CP0_Status = T0 | (1 << CP0St_IE);
3053
    CALL_FROM_TB1(cpu_mips_update_irq, env);
3054
    FORCE_RET();
3055
}
3056

    
3057
void op_trap (void)
3058
{
3059
    if (T0) {
3060
        CALL_FROM_TB1(do_raise_exception, EXCP_TRAP);
3061
    }
3062
    FORCE_RET();
3063
}
3064

    
3065
void op_debug (void)
3066
{
3067
    CALL_FROM_TB1(do_raise_exception, EXCP_DEBUG);
3068
    FORCE_RET();
3069
}
3070

    
3071
void debug_pre_eret (void);
3072
void debug_post_eret (void);
3073
void op_eret (void)
3074
{
3075
    if (loglevel & CPU_LOG_EXEC)
3076
        CALL_FROM_TB0(debug_pre_eret);
3077
    if (env->CP0_Status & (1 << CP0St_ERL)) {
3078
        env->PC[env->current_tc] = env->CP0_ErrorEPC;
3079
        env->CP0_Status &= ~(1 << CP0St_ERL);
3080
    } else {
3081
        env->PC[env->current_tc] = env->CP0_EPC;
3082
        env->CP0_Status &= ~(1 << CP0St_EXL);
3083
    }
3084
    CALL_FROM_TB1(compute_hflags, env);
3085
    if (loglevel & CPU_LOG_EXEC)
3086
        CALL_FROM_TB0(debug_post_eret);
3087
    env->CP0_LLAddr = 1;
3088
    FORCE_RET();
3089
}
3090

    
3091
void op_deret (void)
3092
{
3093
    if (loglevel & CPU_LOG_EXEC)
3094
        CALL_FROM_TB0(debug_pre_eret);
3095
    env->PC[env->current_tc] = env->CP0_DEPC;
3096
    env->hflags &= MIPS_HFLAG_DM;
3097
    CALL_FROM_TB1(compute_hflags, env);
3098
    if (loglevel & CPU_LOG_EXEC)
3099
        CALL_FROM_TB0(debug_post_eret);
3100
    env->CP0_LLAddr = 1;
3101
    FORCE_RET();
3102
}
3103

    
3104
void op_rdhwr_cpunum(void)
3105
{
3106
    if ((env->hflags & MIPS_HFLAG_CP0) ||
3107
        (env->CP0_HWREna & (1 << 0)))
3108
        T0 = env->CP0_EBase & 0x3ff;
3109
    else
3110
        CALL_FROM_TB1(do_raise_exception, EXCP_RI);
3111
    FORCE_RET();
3112
}
3113

    
3114
void op_rdhwr_synci_step(void)
3115
{
3116
    if ((env->hflags & MIPS_HFLAG_CP0) ||
3117
        (env->CP0_HWREna & (1 << 1)))
3118
        T0 = env->SYNCI_Step;
3119
    else
3120
        CALL_FROM_TB1(do_raise_exception, EXCP_RI);
3121
    FORCE_RET();
3122
}
3123

    
3124
void op_rdhwr_cc(void)
3125
{
3126
    if ((env->hflags & MIPS_HFLAG_CP0) ||
3127
        (env->CP0_HWREna & (1 << 2)))
3128
        T0 = env->CP0_Count;
3129
    else
3130
        CALL_FROM_TB1(do_raise_exception, EXCP_RI);
3131
    FORCE_RET();
3132
}
3133

    
3134
void op_rdhwr_ccres(void)
3135
{
3136
    if ((env->hflags & MIPS_HFLAG_CP0) ||
3137
        (env->CP0_HWREna & (1 << 3)))
3138
        T0 = env->CCRes;
3139
    else
3140
        CALL_FROM_TB1(do_raise_exception, EXCP_RI);
3141
    FORCE_RET();
3142
}
3143

    
3144
void op_save_state (void)
3145
{
3146
    env->hflags = PARAM1;
3147
    FORCE_RET();
3148
}
3149

    
3150
void op_save_pc (void)
3151
{
3152
    env->PC[env->current_tc] = PARAM1;
3153
    FORCE_RET();
3154
}
3155

    
3156
#if defined(TARGET_MIPS64)
3157
void op_save_pc64 (void)
3158
{
3159
    env->PC[env->current_tc] = ((uint64_t)PARAM1 << 32) | (uint32_t)PARAM2;
3160
    FORCE_RET();
3161
}
3162
#endif
3163

    
3164
void op_interrupt_restart (void)
3165
{
3166
    if (!(env->CP0_Status & (1 << CP0St_EXL)) &&
3167
        !(env->CP0_Status & (1 << CP0St_ERL)) &&
3168
        !(env->hflags & MIPS_HFLAG_DM) &&
3169
        (env->CP0_Status & (1 << CP0St_IE)) &&
3170
        (env->CP0_Status & env->CP0_Cause & CP0Ca_IP_mask)) {
3171
        env->CP0_Cause &= ~(0x1f << CP0Ca_EC);
3172
        CALL_FROM_TB1(do_raise_exception, EXCP_EXT_INTERRUPT);
3173
    }
3174
    FORCE_RET();
3175
}
3176

    
3177
void op_raise_exception (void)
3178
{
3179
    CALL_FROM_TB1(do_raise_exception, PARAM1);
3180
    FORCE_RET();
3181
}
3182

    
3183
void op_raise_exception_err (void)
3184
{
3185
    CALL_FROM_TB2(do_raise_exception_err, PARAM1, PARAM2);
3186
    FORCE_RET();
3187
}
3188

    
3189
void op_wait (void)
3190
{
3191
    env->halted = 1;
3192
    CALL_FROM_TB1(do_raise_exception, EXCP_HLT);
3193
    FORCE_RET();
3194
}
3195

    
3196
/* Bitfield operations. */
3197
void op_ext(void)
3198
{
3199
    unsigned int pos = PARAM1;
3200
    unsigned int size = PARAM2;
3201

    
3202
    T0 = (int32_t)((T1 >> pos) & ((size < 32) ? ((1 << size) - 1) : ~0));
3203
    FORCE_RET();
3204
}
3205

    
3206
void op_ins(void)
3207
{
3208
    unsigned int pos = PARAM1;
3209
    unsigned int size = PARAM2;
3210
    target_ulong mask = ((size < 32) ? ((1 << size) - 1) : ~0) << pos;
3211

    
3212
    T0 = (int32_t)((T0 & ~mask) | ((T1 << pos) & mask));
3213
    FORCE_RET();
3214
}
3215

    
3216
void op_wsbh(void)
3217
{
3218
    T0 = (int32_t)(((T1 << 8) & ~0x00FF00FF) | ((T1 >> 8) & 0x00FF00FF));
3219
    FORCE_RET();
3220
}
3221

    
3222
#if defined(TARGET_MIPS64)
3223
void op_dext(void)
3224
{
3225
    unsigned int pos = PARAM1;
3226
    unsigned int size = PARAM2;
3227

    
3228
    T0 = (T1 >> pos) & ((size < 64) ? ((1ULL << size) - 1) : ~0ULL);
3229
    FORCE_RET();
3230
}
3231

    
3232
void op_dins(void)
3233
{
3234
    unsigned int pos = PARAM1;
3235
    unsigned int size = PARAM2;
3236
    target_ulong mask = ((size < 64) ? ((1ULL << size) - 1) : ~0ULL) << pos;
3237

    
3238
    T0 = (T0 & ~mask) | ((T1 << pos) & mask);
3239
    FORCE_RET();
3240
}
3241

    
3242
void op_dsbh(void)
3243
{
3244
    T0 = ((T1 << 8) & ~0x00FF00FF00FF00FFULL) | ((T1 >> 8) & 0x00FF00FF00FF00FFULL);
3245
    FORCE_RET();
3246
}
3247

    
3248
void op_dshd(void)
3249
{
3250
    T1 = ((T1 << 16) & ~0x0000FFFF0000FFFFULL) | ((T1 >> 16) & 0x0000FFFF0000FFFFULL);
3251
    T0 = (T1 << 32) | (T1 >> 32);
3252
    FORCE_RET();
3253
}
3254
#endif
3255

    
3256
void op_seb(void)
3257
{
3258
    T0 = ((T1 & 0xFF) ^ 0x80) - 0x80;
3259
    FORCE_RET();
3260
}
3261

    
3262
void op_seh(void)
3263
{
3264
    T0 = ((T1 & 0xFFFF) ^ 0x8000) - 0x8000;
3265
    FORCE_RET();
3266
}