Statistics
| Branch: | Revision:

root / target-mips / op.c @ 95af5ce5

History | View | Annotate | Download (49.8 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
/* Load and store */
149
#define MEMSUFFIX _raw
150
#include "op_mem.c"
151
#undef MEMSUFFIX
152
#if !defined(CONFIG_USER_ONLY)
153
#define MEMSUFFIX _user
154
#include "op_mem.c"
155
#undef MEMSUFFIX
156

    
157
#define MEMSUFFIX _super
158
#include "op_mem.c"
159
#undef MEMSUFFIX
160

    
161
#define MEMSUFFIX _kernel
162
#include "op_mem.c"
163
#undef MEMSUFFIX
164
#endif
165

    
166
/* 64 bits arithmetic */
167
#if TARGET_LONG_BITS > HOST_LONG_BITS
168
void op_mult (void)
169
{
170
    CALL_FROM_TB0(do_mult);
171
    FORCE_RET();
172
}
173

    
174
void op_multu (void)
175
{
176
    CALL_FROM_TB0(do_multu);
177
    FORCE_RET();
178
}
179

    
180
void op_madd (void)
181
{
182
    CALL_FROM_TB0(do_madd);
183
    FORCE_RET();
184
}
185

    
186
void op_maddu (void)
187
{
188
    CALL_FROM_TB0(do_maddu);
189
    FORCE_RET();
190
}
191

    
192
void op_msub (void)
193
{
194
    CALL_FROM_TB0(do_msub);
195
    FORCE_RET();
196
}
197

    
198
void op_msubu (void)
199
{
200
    CALL_FROM_TB0(do_msubu);
201
    FORCE_RET();
202
}
203

    
204
/* Multiplication variants of the vr54xx. */
205
void op_muls (void)
206
{
207
    CALL_FROM_TB0(do_muls);
208
    FORCE_RET();
209
}
210

    
211
void op_mulsu (void)
212
{
213
    CALL_FROM_TB0(do_mulsu);
214
    FORCE_RET();
215
}
216

    
217
void op_macc (void)
218
{
219
    CALL_FROM_TB0(do_macc);
220
    FORCE_RET();
221
}
222

    
223
void op_macchi (void)
224
{
225
    CALL_FROM_TB0(do_macchi);
226
    FORCE_RET();
227
}
228

    
229
void op_maccu (void)
230
{
231
    CALL_FROM_TB0(do_maccu);
232
    FORCE_RET();
233
}
234
void op_macchiu (void)
235
{
236
    CALL_FROM_TB0(do_macchiu);
237
    FORCE_RET();
238
}
239

    
240
void op_msac (void)
241
{
242
    CALL_FROM_TB0(do_msac);
243
    FORCE_RET();
244
}
245

    
246
void op_msachi (void)
247
{
248
    CALL_FROM_TB0(do_msachi);
249
    FORCE_RET();
250
}
251

    
252
void op_msacu (void)
253
{
254
    CALL_FROM_TB0(do_msacu);
255
    FORCE_RET();
256
}
257

    
258
void op_msachiu (void)
259
{
260
    CALL_FROM_TB0(do_msachiu);
261
    FORCE_RET();
262
}
263

    
264
void op_mulhi (void)
265
{
266
    CALL_FROM_TB0(do_mulhi);
267
    FORCE_RET();
268
}
269

    
270
void op_mulhiu (void)
271
{
272
    CALL_FROM_TB0(do_mulhiu);
273
    FORCE_RET();
274
}
275

    
276
void op_mulshi (void)
277
{
278
    CALL_FROM_TB0(do_mulshi);
279
    FORCE_RET();
280
}
281

    
282
void op_mulshiu (void)
283
{
284
    CALL_FROM_TB0(do_mulshiu);
285
    FORCE_RET();
286
}
287

    
288
#else /* TARGET_LONG_BITS > HOST_LONG_BITS */
289

    
290
static always_inline uint64_t get_HILO (void)
291
{
292
    return ((uint64_t)env->HI[env->current_tc][0] << 32) |
293
            ((uint64_t)(uint32_t)env->LO[env->current_tc][0]);
294
}
295

    
296
static always_inline void set_HILO (uint64_t HILO)
297
{
298
    env->LO[env->current_tc][0] = (int32_t)(HILO & 0xFFFFFFFF);
299
    env->HI[env->current_tc][0] = (int32_t)(HILO >> 32);
300
}
301

    
302
static always_inline void set_HIT0_LO (uint64_t HILO)
303
{
304
    env->LO[env->current_tc][0] = (int32_t)(HILO & 0xFFFFFFFF);
305
    T0 = env->HI[env->current_tc][0] = (int32_t)(HILO >> 32);
306
}
307

    
308
static always_inline void set_HI_LOT0 (uint64_t HILO)
309
{
310
    T0 = env->LO[env->current_tc][0] = (int32_t)(HILO & 0xFFFFFFFF);
311
    env->HI[env->current_tc][0] = (int32_t)(HILO >> 32);
312
}
313

    
314
void op_mult (void)
315
{
316
    set_HILO((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
317
    FORCE_RET();
318
}
319

    
320
void op_multu (void)
321
{
322
    set_HILO((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
323
    FORCE_RET();
324
}
325

    
326
void op_madd (void)
327
{
328
    int64_t tmp;
329

    
330
    tmp = ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
331
    set_HILO((int64_t)get_HILO() + tmp);
332
    FORCE_RET();
333
}
334

    
335
void op_maddu (void)
336
{
337
    uint64_t tmp;
338

    
339
    tmp = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
340
    set_HILO(get_HILO() + tmp);
341
    FORCE_RET();
342
}
343

    
344
void op_msub (void)
345
{
346
    int64_t tmp;
347

    
348
    tmp = ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
349
    set_HILO((int64_t)get_HILO() - tmp);
350
    FORCE_RET();
351
}
352

    
353
void op_msubu (void)
354
{
355
    uint64_t tmp;
356

    
357
    tmp = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
358
    set_HILO(get_HILO() - tmp);
359
    FORCE_RET();
360
}
361

    
362
/* Multiplication variants of the vr54xx. */
363
void op_muls (void)
364
{
365
    set_HI_LOT0(0 - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
366
    FORCE_RET();
367
}
368

    
369
void op_mulsu (void)
370
{
371
    set_HI_LOT0(0 - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
372
    FORCE_RET();
373
}
374

    
375
void op_macc (void)
376
{
377
    set_HI_LOT0(get_HILO() + ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
378
    FORCE_RET();
379
}
380

    
381
void op_macchi (void)
382
{
383
    set_HIT0_LO(get_HILO() + ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
384
    FORCE_RET();
385
}
386

    
387
void op_maccu (void)
388
{
389
    set_HI_LOT0(get_HILO() + ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
390
    FORCE_RET();
391
}
392

    
393
void op_macchiu (void)
394
{
395
    set_HIT0_LO(get_HILO() + ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
396
    FORCE_RET();
397
}
398

    
399
void op_msac (void)
400
{
401
    set_HI_LOT0(get_HILO() - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
402
    FORCE_RET();
403
}
404

    
405
void op_msachi (void)
406
{
407
    set_HIT0_LO(get_HILO() - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
408
    FORCE_RET();
409
}
410

    
411
void op_msacu (void)
412
{
413
    set_HI_LOT0(get_HILO() - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
414
    FORCE_RET();
415
}
416

    
417
void op_msachiu (void)
418
{
419
    set_HIT0_LO(get_HILO() - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
420
    FORCE_RET();
421
}
422

    
423
void op_mulhi (void)
424
{
425
    set_HIT0_LO((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
426
    FORCE_RET();
427
}
428

    
429
void op_mulhiu (void)
430
{
431
    set_HIT0_LO((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
432
    FORCE_RET();
433
}
434

    
435
void op_mulshi (void)
436
{
437
    set_HIT0_LO(0 - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
438
    FORCE_RET();
439
}
440

    
441
void op_mulshiu (void)
442
{
443
    set_HIT0_LO(0 - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
444
    FORCE_RET();
445
}
446

    
447
#endif /* TARGET_LONG_BITS > HOST_LONG_BITS */
448

    
449
#if defined(TARGET_MIPS64)
450
void op_dmult (void)
451
{
452
    CALL_FROM_TB4(muls64, &(env->LO[env->current_tc][0]), &(env->HI[env->current_tc][0]), T0, T1);
453
    FORCE_RET();
454
}
455

    
456
void op_dmultu (void)
457
{
458
    CALL_FROM_TB4(mulu64, &(env->LO[env->current_tc][0]), &(env->HI[env->current_tc][0]), T0, T1);
459
    FORCE_RET();
460
}
461
#endif
462

    
463
/* Conditional moves */
464
void op_movf (void)
465
{
466
    if (!(env->fpu->fcr31 & PARAM1))
467
        T0 = T1;
468
    FORCE_RET();
469
}
470

    
471
void op_movt (void)
472
{
473
    if (env->fpu->fcr31 & PARAM1)
474
        T0 = T1;
475
    FORCE_RET();
476
}
477

    
478
/* CP0 functions */
479
void op_mfc0_index (void)
480
{
481
    T0 = env->CP0_Index;
482
    FORCE_RET();
483
}
484

    
485
void op_mfc0_mvpcontrol (void)
486
{
487
    T0 = env->mvp->CP0_MVPControl;
488
    FORCE_RET();
489
}
490

    
491
void op_mfc0_mvpconf0 (void)
492
{
493
    T0 = env->mvp->CP0_MVPConf0;
494
    FORCE_RET();
495
}
496

    
497
void op_mfc0_mvpconf1 (void)
498
{
499
    T0 = env->mvp->CP0_MVPConf1;
500
    FORCE_RET();
501
}
502

    
503
void op_mfc0_random (void)
504
{
505
    CALL_FROM_TB0(do_mfc0_random);
506
    FORCE_RET();
507
}
508

    
509
void op_mfc0_vpecontrol (void)
510
{
511
    T0 = env->CP0_VPEControl;
512
    FORCE_RET();
513
}
514

    
515
void op_mfc0_vpeconf0 (void)
516
{
517
    T0 = env->CP0_VPEConf0;
518
    FORCE_RET();
519
}
520

    
521
void op_mfc0_vpeconf1 (void)
522
{
523
    T0 = env->CP0_VPEConf1;
524
    FORCE_RET();
525
}
526

    
527
void op_mfc0_yqmask (void)
528
{
529
    T0 = env->CP0_YQMask;
530
    FORCE_RET();
531
}
532

    
533
void op_mfc0_vpeschedule (void)
534
{
535
    T0 = env->CP0_VPESchedule;
536
    FORCE_RET();
537
}
538

    
539
void op_mfc0_vpeschefback (void)
540
{
541
    T0 = env->CP0_VPEScheFBack;
542
    FORCE_RET();
543
}
544

    
545
void op_mfc0_vpeopt (void)
546
{
547
    T0 = env->CP0_VPEOpt;
548
    FORCE_RET();
549
}
550

    
551
void op_mfc0_entrylo0 (void)
552
{
553
    T0 = (int32_t)env->CP0_EntryLo0;
554
    FORCE_RET();
555
}
556

    
557
void op_mfc0_tcstatus (void)
558
{
559
    T0 = env->CP0_TCStatus[env->current_tc];
560
    FORCE_RET();
561
}
562

    
563
void op_mftc0_tcstatus(void)
564
{
565
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
566

    
567
    T0 = env->CP0_TCStatus[other_tc];
568
    FORCE_RET();
569
}
570

    
571
void op_mfc0_tcbind (void)
572
{
573
    T0 = env->CP0_TCBind[env->current_tc];
574
    FORCE_RET();
575
}
576

    
577
void op_mftc0_tcbind(void)
578
{
579
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
580

    
581
    T0 = env->CP0_TCBind[other_tc];
582
    FORCE_RET();
583
}
584

    
585
void op_mfc0_tcrestart (void)
586
{
587
    T0 = env->PC[env->current_tc];
588
    FORCE_RET();
589
}
590

    
591
void op_mftc0_tcrestart(void)
592
{
593
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
594

    
595
    T0 = env->PC[other_tc];
596
    FORCE_RET();
597
}
598

    
599
void op_mfc0_tchalt (void)
600
{
601
    T0 = env->CP0_TCHalt[env->current_tc];
602
    FORCE_RET();
603
}
604

    
605
void op_mftc0_tchalt(void)
606
{
607
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
608

    
609
    T0 = env->CP0_TCHalt[other_tc];
610
    FORCE_RET();
611
}
612

    
613
void op_mfc0_tccontext (void)
614
{
615
    T0 = env->CP0_TCContext[env->current_tc];
616
    FORCE_RET();
617
}
618

    
619
void op_mftc0_tccontext(void)
620
{
621
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
622

    
623
    T0 = env->CP0_TCContext[other_tc];
624
    FORCE_RET();
625
}
626

    
627
void op_mfc0_tcschedule (void)
628
{
629
    T0 = env->CP0_TCSchedule[env->current_tc];
630
    FORCE_RET();
631
}
632

    
633
void op_mftc0_tcschedule(void)
634
{
635
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
636

    
637
    T0 = env->CP0_TCSchedule[other_tc];
638
    FORCE_RET();
639
}
640

    
641
void op_mfc0_tcschefback (void)
642
{
643
    T0 = env->CP0_TCScheFBack[env->current_tc];
644
    FORCE_RET();
645
}
646

    
647
void op_mftc0_tcschefback(void)
648
{
649
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
650

    
651
    T0 = env->CP0_TCScheFBack[other_tc];
652
    FORCE_RET();
653
}
654

    
655
void op_mfc0_entrylo1 (void)
656
{
657
    T0 = (int32_t)env->CP0_EntryLo1;
658
    FORCE_RET();
659
}
660

    
661
void op_mfc0_context (void)
662
{
663
    T0 = (int32_t)env->CP0_Context;
664
    FORCE_RET();
665
}
666

    
667
void op_mfc0_pagemask (void)
668
{
669
    T0 = env->CP0_PageMask;
670
    FORCE_RET();
671
}
672

    
673
void op_mfc0_pagegrain (void)
674
{
675
    T0 = env->CP0_PageGrain;
676
    FORCE_RET();
677
}
678

    
679
void op_mfc0_wired (void)
680
{
681
    T0 = env->CP0_Wired;
682
    FORCE_RET();
683
}
684

    
685
void op_mfc0_srsconf0 (void)
686
{
687
    T0 = env->CP0_SRSConf0;
688
    FORCE_RET();
689
}
690

    
691
void op_mfc0_srsconf1 (void)
692
{
693
    T0 = env->CP0_SRSConf1;
694
    FORCE_RET();
695
}
696

    
697
void op_mfc0_srsconf2 (void)
698
{
699
    T0 = env->CP0_SRSConf2;
700
    FORCE_RET();
701
}
702

    
703
void op_mfc0_srsconf3 (void)
704
{
705
    T0 = env->CP0_SRSConf3;
706
    FORCE_RET();
707
}
708

    
709
void op_mfc0_srsconf4 (void)
710
{
711
    T0 = env->CP0_SRSConf4;
712
    FORCE_RET();
713
}
714

    
715
void op_mfc0_hwrena (void)
716
{
717
    T0 = env->CP0_HWREna;
718
    FORCE_RET();
719
}
720

    
721
void op_mfc0_badvaddr (void)
722
{
723
    T0 = (int32_t)env->CP0_BadVAddr;
724
    FORCE_RET();
725
}
726

    
727
void op_mfc0_count (void)
728
{
729
    CALL_FROM_TB0(do_mfc0_count);
730
    FORCE_RET();
731
}
732

    
733
void op_mfc0_entryhi (void)
734
{
735
    T0 = (int32_t)env->CP0_EntryHi;
736
    FORCE_RET();
737
}
738

    
739
void op_mftc0_entryhi(void)
740
{
741
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
742

    
743
    T0 = (env->CP0_EntryHi & ~0xff) | (env->CP0_TCStatus[other_tc] & 0xff);
744
    FORCE_RET();
745
}
746

    
747
void op_mfc0_compare (void)
748
{
749
    T0 = env->CP0_Compare;
750
    FORCE_RET();
751
}
752

    
753
void op_mfc0_status (void)
754
{
755
    T0 = env->CP0_Status;
756
    FORCE_RET();
757
}
758

    
759
void op_mftc0_status(void)
760
{
761
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
762
    uint32_t tcstatus = env->CP0_TCStatus[other_tc];
763

    
764
    T0 = env->CP0_Status & ~0xf1000018;
765
    T0 |= tcstatus & (0xf << CP0TCSt_TCU0);
766
    T0 |= (tcstatus & (1 << CP0TCSt_TMX)) >> (CP0TCSt_TMX - CP0St_MX);
767
    T0 |= (tcstatus & (0x3 << CP0TCSt_TKSU)) >> (CP0TCSt_TKSU - CP0St_KSU);
768
    FORCE_RET();
769
}
770

    
771
void op_mfc0_intctl (void)
772
{
773
    T0 = env->CP0_IntCtl;
774
    FORCE_RET();
775
}
776

    
777
void op_mfc0_srsctl (void)
778
{
779
    T0 = env->CP0_SRSCtl;
780
    FORCE_RET();
781
}
782

    
783
void op_mfc0_srsmap (void)
784
{
785
    T0 = env->CP0_SRSMap;
786
    FORCE_RET();
787
}
788

    
789
void op_mfc0_cause (void)
790
{
791
    T0 = env->CP0_Cause;
792
    FORCE_RET();
793
}
794

    
795
void op_mfc0_epc (void)
796
{
797
    T0 = (int32_t)env->CP0_EPC;
798
    FORCE_RET();
799
}
800

    
801
void op_mfc0_prid (void)
802
{
803
    T0 = env->CP0_PRid;
804
    FORCE_RET();
805
}
806

    
807
void op_mfc0_ebase (void)
808
{
809
    T0 = env->CP0_EBase;
810
    FORCE_RET();
811
}
812

    
813
void op_mfc0_config0 (void)
814
{
815
    T0 = env->CP0_Config0;
816
    FORCE_RET();
817
}
818

    
819
void op_mfc0_config1 (void)
820
{
821
    T0 = env->CP0_Config1;
822
    FORCE_RET();
823
}
824

    
825
void op_mfc0_config2 (void)
826
{
827
    T0 = env->CP0_Config2;
828
    FORCE_RET();
829
}
830

    
831
void op_mfc0_config3 (void)
832
{
833
    T0 = env->CP0_Config3;
834
    FORCE_RET();
835
}
836

    
837
void op_mfc0_config6 (void)
838
{
839
    T0 = env->CP0_Config6;
840
    FORCE_RET();
841
}
842

    
843
void op_mfc0_config7 (void)
844
{
845
    T0 = env->CP0_Config7;
846
    FORCE_RET();
847
}
848

    
849
void op_mfc0_lladdr (void)
850
{
851
    T0 = (int32_t)env->CP0_LLAddr >> 4;
852
    FORCE_RET();
853
}
854

    
855
void op_mfc0_watchlo (void)
856
{
857
    T0 = (int32_t)env->CP0_WatchLo[PARAM1];
858
    FORCE_RET();
859
}
860

    
861
void op_mfc0_watchhi (void)
862
{
863
    T0 = env->CP0_WatchHi[PARAM1];
864
    FORCE_RET();
865
}
866

    
867
void op_mfc0_xcontext (void)
868
{
869
    T0 = (int32_t)env->CP0_XContext;
870
    FORCE_RET();
871
}
872

    
873
void op_mfc0_framemask (void)
874
{
875
    T0 = env->CP0_Framemask;
876
    FORCE_RET();
877
}
878

    
879
void op_mfc0_debug (void)
880
{
881
    T0 = env->CP0_Debug;
882
    if (env->hflags & MIPS_HFLAG_DM)
883
        T0 |= 1 << CP0DB_DM;
884
    FORCE_RET();
885
}
886

    
887
void op_mftc0_debug(void)
888
{
889
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
890

    
891
    /* XXX: Might be wrong, check with EJTAG spec. */
892
    T0 = (env->CP0_Debug & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) |
893
         (env->CP0_Debug_tcstatus[other_tc] &
894
          ((1 << CP0DB_SSt) | (1 << CP0DB_Halt)));
895
    FORCE_RET();
896
}
897

    
898
void op_mfc0_depc (void)
899
{
900
    T0 = (int32_t)env->CP0_DEPC;
901
    FORCE_RET();
902
}
903

    
904
void op_mfc0_performance0 (void)
905
{
906
    T0 = env->CP0_Performance0;
907
    FORCE_RET();
908
}
909

    
910
void op_mfc0_taglo (void)
911
{
912
    T0 = env->CP0_TagLo;
913
    FORCE_RET();
914
}
915

    
916
void op_mfc0_datalo (void)
917
{
918
    T0 = env->CP0_DataLo;
919
    FORCE_RET();
920
}
921

    
922
void op_mfc0_taghi (void)
923
{
924
    T0 = env->CP0_TagHi;
925
    FORCE_RET();
926
}
927

    
928
void op_mfc0_datahi (void)
929
{
930
    T0 = env->CP0_DataHi;
931
    FORCE_RET();
932
}
933

    
934
void op_mfc0_errorepc (void)
935
{
936
    T0 = (int32_t)env->CP0_ErrorEPC;
937
    FORCE_RET();
938
}
939

    
940
void op_mfc0_desave (void)
941
{
942
    T0 = env->CP0_DESAVE;
943
    FORCE_RET();
944
}
945

    
946
void op_mtc0_index (void)
947
{
948
    int num = 1;
949
    unsigned int tmp = env->tlb->nb_tlb;
950

    
951
    do {
952
        tmp >>= 1;
953
        num <<= 1;
954
    } while (tmp);
955
    env->CP0_Index = (env->CP0_Index & 0x80000000) | (T0 & (num - 1));
956
    FORCE_RET();
957
}
958

    
959
void op_mtc0_mvpcontrol (void)
960
{
961
    uint32_t mask = 0;
962
    uint32_t newval;
963

    
964
    if (env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP))
965
        mask |= (1 << CP0MVPCo_CPA) | (1 << CP0MVPCo_VPC) |
966
                (1 << CP0MVPCo_EVP);
967
    if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
968
        mask |= (1 << CP0MVPCo_STLB);
969
    newval = (env->mvp->CP0_MVPControl & ~mask) | (T0 & mask);
970

    
971
    // TODO: Enable/disable shared TLB, enable/disable VPEs.
972

    
973
    env->mvp->CP0_MVPControl = newval;
974
    FORCE_RET();
975
}
976

    
977
void op_mtc0_vpecontrol (void)
978
{
979
    uint32_t mask;
980
    uint32_t newval;
981

    
982
    mask = (1 << CP0VPECo_YSI) | (1 << CP0VPECo_GSI) |
983
           (1 << CP0VPECo_TE) | (0xff << CP0VPECo_TargTC);
984
    newval = (env->CP0_VPEControl & ~mask) | (T0 & mask);
985

    
986
    /* Yield scheduler intercept not implemented. */
987
    /* Gating storage scheduler intercept not implemented. */
988

    
989
    // TODO: Enable/disable TCs.
990

    
991
    env->CP0_VPEControl = newval;
992
    FORCE_RET();
993
}
994

    
995
void op_mtc0_vpeconf0 (void)
996
{
997
    uint32_t mask = 0;
998
    uint32_t newval;
999

    
1000
    if (env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) {
1001
        if (env->CP0_VPEConf0 & (1 << CP0VPEC0_VPA))
1002
            mask |= (0xff << CP0VPEC0_XTC);
1003
        mask |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
1004
    }
1005
    newval = (env->CP0_VPEConf0 & ~mask) | (T0 & mask);
1006

    
1007
    // TODO: TC exclusive handling due to ERL/EXL.
1008

    
1009
    env->CP0_VPEConf0 = newval;
1010
    FORCE_RET();
1011
}
1012

    
1013
void op_mtc0_vpeconf1 (void)
1014
{
1015
    uint32_t mask = 0;
1016
    uint32_t newval;
1017

    
1018
    if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
1019
        mask |= (0xff << CP0VPEC1_NCX) | (0xff << CP0VPEC1_NCP2) |
1020
                (0xff << CP0VPEC1_NCP1);
1021
    newval = (env->CP0_VPEConf1 & ~mask) | (T0 & mask);
1022

    
1023
    /* UDI not implemented. */
1024
    /* CP2 not implemented. */
1025

    
1026
    // TODO: Handle FPU (CP1) binding.
1027

    
1028
    env->CP0_VPEConf1 = newval;
1029
    FORCE_RET();
1030
}
1031

    
1032
void op_mtc0_yqmask (void)
1033
{
1034
    /* Yield qualifier inputs not implemented. */
1035
    env->CP0_YQMask = 0x00000000;
1036
    FORCE_RET();
1037
}
1038

    
1039
void op_mtc0_vpeschedule (void)
1040
{
1041
    env->CP0_VPESchedule = T0;
1042
    FORCE_RET();
1043
}
1044

    
1045
void op_mtc0_vpeschefback (void)
1046
{
1047
    env->CP0_VPEScheFBack = T0;
1048
    FORCE_RET();
1049
}
1050

    
1051
void op_mtc0_vpeopt (void)
1052
{
1053
    env->CP0_VPEOpt = T0 & 0x0000ffff;
1054
    FORCE_RET();
1055
}
1056

    
1057
void op_mtc0_entrylo0 (void)
1058
{
1059
    /* Large physaddr (PABITS) not implemented */
1060
    /* 1k pages not implemented */
1061
    env->CP0_EntryLo0 = T0 & 0x3FFFFFFF;
1062
    FORCE_RET();
1063
}
1064

    
1065
void op_mtc0_tcstatus (void)
1066
{
1067
    uint32_t mask = env->CP0_TCStatus_rw_bitmask;
1068
    uint32_t newval;
1069

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

    
1072
    // TODO: Sync with CP0_Status.
1073

    
1074
    env->CP0_TCStatus[env->current_tc] = newval;
1075
    FORCE_RET();
1076
}
1077

    
1078
void op_mttc0_tcstatus (void)
1079
{
1080
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1081

    
1082
    // TODO: Sync with CP0_Status.
1083

    
1084
    env->CP0_TCStatus[other_tc] = T0;
1085
    FORCE_RET();
1086
}
1087

    
1088
void op_mtc0_tcbind (void)
1089
{
1090
    uint32_t mask = (1 << CP0TCBd_TBE);
1091
    uint32_t newval;
1092

    
1093
    if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
1094
        mask |= (1 << CP0TCBd_CurVPE);
1095
    newval = (env->CP0_TCBind[env->current_tc] & ~mask) | (T0 & mask);
1096
    env->CP0_TCBind[env->current_tc] = newval;
1097
    FORCE_RET();
1098
}
1099

    
1100
void op_mttc0_tcbind (void)
1101
{
1102
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1103
    uint32_t mask = (1 << CP0TCBd_TBE);
1104
    uint32_t newval;
1105

    
1106
    if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
1107
        mask |= (1 << CP0TCBd_CurVPE);
1108
    newval = (env->CP0_TCBind[other_tc] & ~mask) | (T0 & mask);
1109
    env->CP0_TCBind[other_tc] = newval;
1110
    FORCE_RET();
1111
}
1112

    
1113
void op_mtc0_tcrestart (void)
1114
{
1115
    env->PC[env->current_tc] = T0;
1116
    env->CP0_TCStatus[env->current_tc] &= ~(1 << CP0TCSt_TDS);
1117
    env->CP0_LLAddr = 0ULL;
1118
    /* MIPS16 not implemented. */
1119
    FORCE_RET();
1120
}
1121

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

    
1126
    env->PC[other_tc] = T0;
1127
    env->CP0_TCStatus[other_tc] &= ~(1 << CP0TCSt_TDS);
1128
    env->CP0_LLAddr = 0ULL;
1129
    /* MIPS16 not implemented. */
1130
    FORCE_RET();
1131
}
1132

    
1133
void op_mtc0_tchalt (void)
1134
{
1135
    env->CP0_TCHalt[env->current_tc] = T0 & 0x1;
1136

    
1137
    // TODO: Halt TC / Restart (if allocated+active) TC.
1138

    
1139
    FORCE_RET();
1140
}
1141

    
1142
void op_mttc0_tchalt (void)
1143
{
1144
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1145

    
1146
    // TODO: Halt TC / Restart (if allocated+active) TC.
1147

    
1148
    env->CP0_TCHalt[other_tc] = T0;
1149
    FORCE_RET();
1150
}
1151

    
1152
void op_mtc0_tccontext (void)
1153
{
1154
    env->CP0_TCContext[env->current_tc] = T0;
1155
    FORCE_RET();
1156
}
1157

    
1158
void op_mttc0_tccontext (void)
1159
{
1160
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1161

    
1162
    env->CP0_TCContext[other_tc] = T0;
1163
    FORCE_RET();
1164
}
1165

    
1166
void op_mtc0_tcschedule (void)
1167
{
1168
    env->CP0_TCSchedule[env->current_tc] = T0;
1169
    FORCE_RET();
1170
}
1171

    
1172
void op_mttc0_tcschedule (void)
1173
{
1174
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1175

    
1176
    env->CP0_TCSchedule[other_tc] = T0;
1177
    FORCE_RET();
1178
}
1179

    
1180
void op_mtc0_tcschefback (void)
1181
{
1182
    env->CP0_TCScheFBack[env->current_tc] = T0;
1183
    FORCE_RET();
1184
}
1185

    
1186
void op_mttc0_tcschefback (void)
1187
{
1188
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1189

    
1190
    env->CP0_TCScheFBack[other_tc] = T0;
1191
    FORCE_RET();
1192
}
1193

    
1194
void op_mtc0_entrylo1 (void)
1195
{
1196
    /* Large physaddr (PABITS) not implemented */
1197
    /* 1k pages not implemented */
1198
    env->CP0_EntryLo1 = T0 & 0x3FFFFFFF;
1199
    FORCE_RET();
1200
}
1201

    
1202
void op_mtc0_context (void)
1203
{
1204
    env->CP0_Context = (env->CP0_Context & 0x007FFFFF) | (T0 & ~0x007FFFFF);
1205
    FORCE_RET();
1206
}
1207

    
1208
void op_mtc0_pagemask (void)
1209
{
1210
    /* 1k pages not implemented */
1211
    env->CP0_PageMask = T0 & (0x1FFFFFFF & (TARGET_PAGE_MASK << 1));
1212
    FORCE_RET();
1213
}
1214

    
1215
void op_mtc0_pagegrain (void)
1216
{
1217
    /* SmartMIPS not implemented */
1218
    /* Large physaddr (PABITS) not implemented */
1219
    /* 1k pages not implemented */
1220
    env->CP0_PageGrain = 0;
1221
    FORCE_RET();
1222
}
1223

    
1224
void op_mtc0_wired (void)
1225
{
1226
    env->CP0_Wired = T0 % env->tlb->nb_tlb;
1227
    FORCE_RET();
1228
}
1229

    
1230
void op_mtc0_srsconf0 (void)
1231
{
1232
    env->CP0_SRSConf0 |= T0 & env->CP0_SRSConf0_rw_bitmask;
1233
    FORCE_RET();
1234
}
1235

    
1236
void op_mtc0_srsconf1 (void)
1237
{
1238
    env->CP0_SRSConf1 |= T0 & env->CP0_SRSConf1_rw_bitmask;
1239
    FORCE_RET();
1240
}
1241

    
1242
void op_mtc0_srsconf2 (void)
1243
{
1244
    env->CP0_SRSConf2 |= T0 & env->CP0_SRSConf2_rw_bitmask;
1245
    FORCE_RET();
1246
}
1247

    
1248
void op_mtc0_srsconf3 (void)
1249
{
1250
    env->CP0_SRSConf3 |= T0 & env->CP0_SRSConf3_rw_bitmask;
1251
    FORCE_RET();
1252
}
1253

    
1254
void op_mtc0_srsconf4 (void)
1255
{
1256
    env->CP0_SRSConf4 |= T0 & env->CP0_SRSConf4_rw_bitmask;
1257
    FORCE_RET();
1258
}
1259

    
1260
void op_mtc0_hwrena (void)
1261
{
1262
    env->CP0_HWREna = T0 & 0x0000000F;
1263
    FORCE_RET();
1264
}
1265

    
1266
void op_mtc0_count (void)
1267
{
1268
    CALL_FROM_TB2(cpu_mips_store_count, env, T0);
1269
    FORCE_RET();
1270
}
1271

    
1272
void op_mtc0_entryhi (void)
1273
{
1274
    target_ulong old, val;
1275

    
1276
    /* 1k pages not implemented */
1277
    val = T0 & ((TARGET_PAGE_MASK << 1) | 0xFF);
1278
#if defined(TARGET_MIPS64)
1279
    val &= env->SEGMask;
1280
#endif
1281
    old = env->CP0_EntryHi;
1282
    env->CP0_EntryHi = val;
1283
    if (env->CP0_Config3 & (1 << CP0C3_MT)) {
1284
        uint32_t tcst = env->CP0_TCStatus[env->current_tc] & ~0xff;
1285
        env->CP0_TCStatus[env->current_tc] = tcst | (val & 0xff);
1286
    }
1287
    /* If the ASID changes, flush qemu's TLB.  */
1288
    if ((old & 0xFF) != (val & 0xFF))
1289
        CALL_FROM_TB2(cpu_mips_tlb_flush, env, 1);
1290
    FORCE_RET();
1291
}
1292

    
1293
void op_mttc0_entryhi(void)
1294
{
1295
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1296

    
1297
    env->CP0_EntryHi = (env->CP0_EntryHi & 0xff) | (T0 & ~0xff);
1298
    env->CP0_TCStatus[other_tc] = (env->CP0_TCStatus[other_tc] & ~0xff) | (T0 & 0xff);
1299
    FORCE_RET();
1300
}
1301

    
1302
void op_mtc0_compare (void)
1303
{
1304
    CALL_FROM_TB2(cpu_mips_store_compare, env, T0);
1305
    FORCE_RET();
1306
}
1307

    
1308
void op_mtc0_status (void)
1309
{
1310
    uint32_t val, old;
1311
    uint32_t mask = env->CP0_Status_rw_bitmask;
1312

    
1313
    val = T0 & mask;
1314
    old = env->CP0_Status;
1315
    env->CP0_Status = (env->CP0_Status & ~mask) | val;
1316
    CALL_FROM_TB1(compute_hflags, env);
1317
    if (loglevel & CPU_LOG_EXEC)
1318
        CALL_FROM_TB2(do_mtc0_status_debug, old, val);
1319
    CALL_FROM_TB1(cpu_mips_update_irq, env);
1320
    FORCE_RET();
1321
}
1322

    
1323
void op_mttc0_status(void)
1324
{
1325
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1326
    uint32_t tcstatus = env->CP0_TCStatus[other_tc];
1327

    
1328
    env->CP0_Status = T0 & ~0xf1000018;
1329
    tcstatus = (tcstatus & ~(0xf << CP0TCSt_TCU0)) | (T0 & (0xf << CP0St_CU0));
1330
    tcstatus = (tcstatus & ~(1 << CP0TCSt_TMX)) | ((T0 & (1 << CP0St_MX)) << (CP0TCSt_TMX - CP0St_MX));
1331
    tcstatus = (tcstatus & ~(0x3 << CP0TCSt_TKSU)) | ((T0 & (0x3 << CP0St_KSU)) << (CP0TCSt_TKSU - CP0St_KSU));
1332
    env->CP0_TCStatus[other_tc] = tcstatus;
1333
    FORCE_RET();
1334
}
1335

    
1336
void op_mtc0_intctl (void)
1337
{
1338
    /* vectored interrupts not implemented, no performance counters. */
1339
    env->CP0_IntCtl = (env->CP0_IntCtl & ~0x000002e0) | (T0 & 0x000002e0);
1340
    FORCE_RET();
1341
}
1342

    
1343
void op_mtc0_srsctl (void)
1344
{
1345
    uint32_t mask = (0xf << CP0SRSCtl_ESS) | (0xf << CP0SRSCtl_PSS);
1346
    env->CP0_SRSCtl = (env->CP0_SRSCtl & ~mask) | (T0 & mask);
1347
    FORCE_RET();
1348
}
1349

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

    
1356
void op_mtc0_cause (void)
1357
{
1358
    uint32_t mask = 0x00C00300;
1359
    uint32_t old = env->CP0_Cause;
1360

    
1361
    if (env->insn_flags & ISA_MIPS32R2)
1362
        mask |= 1 << CP0Ca_DC;
1363

    
1364
    env->CP0_Cause = (env->CP0_Cause & ~mask) | (T0 & mask);
1365

    
1366
    if ((old ^ env->CP0_Cause) & (1 << CP0Ca_DC)) {
1367
        if (env->CP0_Cause & (1 << CP0Ca_DC))
1368
            CALL_FROM_TB1(cpu_mips_stop_count, env);
1369
        else
1370
            CALL_FROM_TB1(cpu_mips_start_count, env);
1371
    }
1372

    
1373
    /* Handle the software interrupt as an hardware one, as they
1374
       are very similar */
1375
    if (T0 & CP0Ca_IP_mask) {
1376
        CALL_FROM_TB1(cpu_mips_update_irq, env);
1377
    }
1378
    FORCE_RET();
1379
}
1380

    
1381
void op_mtc0_epc (void)
1382
{
1383
    env->CP0_EPC = T0;
1384
    FORCE_RET();
1385
}
1386

    
1387
void op_mtc0_ebase (void)
1388
{
1389
    /* vectored interrupts not implemented */
1390
    /* Multi-CPU not implemented */
1391
    env->CP0_EBase = 0x80000000 | (T0 & 0x3FFFF000);
1392
    FORCE_RET();
1393
}
1394

    
1395
void op_mtc0_config0 (void)
1396
{
1397
    env->CP0_Config0 = (env->CP0_Config0 & 0x81FFFFF8) | (T0 & 0x00000007);
1398
    FORCE_RET();
1399
}
1400

    
1401
void op_mtc0_config2 (void)
1402
{
1403
    /* tertiary/secondary caches not implemented */
1404
    env->CP0_Config2 = (env->CP0_Config2 & 0x8FFF0FFF);
1405
    FORCE_RET();
1406
}
1407

    
1408
void op_mtc0_watchlo (void)
1409
{
1410
    /* Watch exceptions for instructions, data loads, data stores
1411
       not implemented. */
1412
    env->CP0_WatchLo[PARAM1] = (T0 & ~0x7);
1413
    FORCE_RET();
1414
}
1415

    
1416
void op_mtc0_watchhi (void)
1417
{
1418
    env->CP0_WatchHi[PARAM1] = (T0 & 0x40FF0FF8);
1419
    env->CP0_WatchHi[PARAM1] &= ~(env->CP0_WatchHi[PARAM1] & T0 & 0x7);
1420
    FORCE_RET();
1421
}
1422

    
1423
void op_mtc0_xcontext (void)
1424
{
1425
    target_ulong mask = (1ULL << (env->SEGBITS - 7)) - 1;
1426
    env->CP0_XContext = (env->CP0_XContext & mask) | (T0 & ~mask);
1427
    FORCE_RET();
1428
}
1429

    
1430
void op_mtc0_framemask (void)
1431
{
1432
    env->CP0_Framemask = T0; /* XXX */
1433
    FORCE_RET();
1434
}
1435

    
1436
void op_mtc0_debug (void)
1437
{
1438
    env->CP0_Debug = (env->CP0_Debug & 0x8C03FC1F) | (T0 & 0x13300120);
1439
    if (T0 & (1 << CP0DB_DM))
1440
        env->hflags |= MIPS_HFLAG_DM;
1441
    else
1442
        env->hflags &= ~MIPS_HFLAG_DM;
1443
    FORCE_RET();
1444
}
1445

    
1446
void op_mttc0_debug(void)
1447
{
1448
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1449

    
1450
    /* XXX: Might be wrong, check with EJTAG spec. */
1451
    env->CP0_Debug_tcstatus[other_tc] = T0 & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt));
1452
    env->CP0_Debug = (env->CP0_Debug & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) |
1453
                     (T0 & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt)));
1454
    FORCE_RET();
1455
}
1456

    
1457
void op_mtc0_depc (void)
1458
{
1459
    env->CP0_DEPC = T0;
1460
    FORCE_RET();
1461
}
1462

    
1463
void op_mtc0_performance0 (void)
1464
{
1465
    env->CP0_Performance0 = T0 & 0x000007ff;
1466
    FORCE_RET();
1467
}
1468

    
1469
void op_mtc0_taglo (void)
1470
{
1471
    env->CP0_TagLo = T0 & 0xFFFFFCF6;
1472
    FORCE_RET();
1473
}
1474

    
1475
void op_mtc0_datalo (void)
1476
{
1477
    env->CP0_DataLo = T0; /* XXX */
1478
    FORCE_RET();
1479
}
1480

    
1481
void op_mtc0_taghi (void)
1482
{
1483
    env->CP0_TagHi = T0; /* XXX */
1484
    FORCE_RET();
1485
}
1486

    
1487
void op_mtc0_datahi (void)
1488
{
1489
    env->CP0_DataHi = T0; /* XXX */
1490
    FORCE_RET();
1491
}
1492

    
1493
void op_mtc0_errorepc (void)
1494
{
1495
    env->CP0_ErrorEPC = T0;
1496
    FORCE_RET();
1497
}
1498

    
1499
void op_mtc0_desave (void)
1500
{
1501
    env->CP0_DESAVE = T0;
1502
    FORCE_RET();
1503
}
1504

    
1505
#if defined(TARGET_MIPS64)
1506
void op_dmfc0_yqmask (void)
1507
{
1508
    T0 = env->CP0_YQMask;
1509
    FORCE_RET();
1510
}
1511

    
1512
void op_dmfc0_vpeschedule (void)
1513
{
1514
    T0 = env->CP0_VPESchedule;
1515
    FORCE_RET();
1516
}
1517

    
1518
void op_dmfc0_vpeschefback (void)
1519
{
1520
    T0 = env->CP0_VPEScheFBack;
1521
    FORCE_RET();
1522
}
1523

    
1524
void op_dmfc0_entrylo0 (void)
1525
{
1526
    T0 = env->CP0_EntryLo0;
1527
    FORCE_RET();
1528
}
1529

    
1530
void op_dmfc0_tcrestart (void)
1531
{
1532
    T0 = env->PC[env->current_tc];
1533
    FORCE_RET();
1534
}
1535

    
1536
void op_dmfc0_tchalt (void)
1537
{
1538
    T0 = env->CP0_TCHalt[env->current_tc];
1539
    FORCE_RET();
1540
}
1541

    
1542
void op_dmfc0_tccontext (void)
1543
{
1544
    T0 = env->CP0_TCContext[env->current_tc];
1545
    FORCE_RET();
1546
}
1547

    
1548
void op_dmfc0_tcschedule (void)
1549
{
1550
    T0 = env->CP0_TCSchedule[env->current_tc];
1551
    FORCE_RET();
1552
}
1553

    
1554
void op_dmfc0_tcschefback (void)
1555
{
1556
    T0 = env->CP0_TCScheFBack[env->current_tc];
1557
    FORCE_RET();
1558
}
1559

    
1560
void op_dmfc0_entrylo1 (void)
1561
{
1562
    T0 = env->CP0_EntryLo1;
1563
    FORCE_RET();
1564
}
1565

    
1566
void op_dmfc0_context (void)
1567
{
1568
    T0 = env->CP0_Context;
1569
    FORCE_RET();
1570
}
1571

    
1572
void op_dmfc0_badvaddr (void)
1573
{
1574
    T0 = env->CP0_BadVAddr;
1575
    FORCE_RET();
1576
}
1577

    
1578
void op_dmfc0_entryhi (void)
1579
{
1580
    T0 = env->CP0_EntryHi;
1581
    FORCE_RET();
1582
}
1583

    
1584
void op_dmfc0_epc (void)
1585
{
1586
    T0 = env->CP0_EPC;
1587
    FORCE_RET();
1588
}
1589

    
1590
void op_dmfc0_lladdr (void)
1591
{
1592
    T0 = env->CP0_LLAddr >> 4;
1593
    FORCE_RET();
1594
}
1595

    
1596
void op_dmfc0_watchlo (void)
1597
{
1598
    T0 = env->CP0_WatchLo[PARAM1];
1599
    FORCE_RET();
1600
}
1601

    
1602
void op_dmfc0_xcontext (void)
1603
{
1604
    T0 = env->CP0_XContext;
1605
    FORCE_RET();
1606
}
1607

    
1608
void op_dmfc0_depc (void)
1609
{
1610
    T0 = env->CP0_DEPC;
1611
    FORCE_RET();
1612
}
1613

    
1614
void op_dmfc0_errorepc (void)
1615
{
1616
    T0 = env->CP0_ErrorEPC;
1617
    FORCE_RET();
1618
}
1619
#endif /* TARGET_MIPS64 */
1620

    
1621
/* MIPS MT functions */
1622
void op_mftgpr(void)
1623
{
1624
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1625

    
1626
    T0 = env->gpr[other_tc][PARAM1];
1627
    FORCE_RET();
1628
}
1629

    
1630
void op_mftlo(void)
1631
{
1632
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1633

    
1634
    T0 = env->LO[other_tc][PARAM1];
1635
    FORCE_RET();
1636
}
1637

    
1638
void op_mfthi(void)
1639
{
1640
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1641

    
1642
    T0 = env->HI[other_tc][PARAM1];
1643
    FORCE_RET();
1644
}
1645

    
1646
void op_mftacx(void)
1647
{
1648
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1649

    
1650
    T0 = env->ACX[other_tc][PARAM1];
1651
    FORCE_RET();
1652
}
1653

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

    
1658
    T0 = env->DSPControl[other_tc];
1659
    FORCE_RET();
1660
}
1661

    
1662
void op_mttgpr(void)
1663
{
1664
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1665

    
1666
    T0 = env->gpr[other_tc][PARAM1];
1667
    FORCE_RET();
1668
}
1669

    
1670
void op_mttlo(void)
1671
{
1672
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1673

    
1674
    T0 = env->LO[other_tc][PARAM1];
1675
    FORCE_RET();
1676
}
1677

    
1678
void op_mtthi(void)
1679
{
1680
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1681

    
1682
    T0 = env->HI[other_tc][PARAM1];
1683
    FORCE_RET();
1684
}
1685

    
1686
void op_mttacx(void)
1687
{
1688
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1689

    
1690
    T0 = env->ACX[other_tc][PARAM1];
1691
    FORCE_RET();
1692
}
1693

    
1694
void op_mttdsp(void)
1695
{
1696
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1697

    
1698
    T0 = env->DSPControl[other_tc];
1699
    FORCE_RET();
1700
}
1701

    
1702

    
1703
void op_dmt(void)
1704
{
1705
    // TODO
1706
    T0 = 0;
1707
    // rt = T0
1708
    FORCE_RET();
1709
}
1710

    
1711
void op_emt(void)
1712
{
1713
    // TODO
1714
    T0 = 0;
1715
    // rt = T0
1716
    FORCE_RET();
1717
}
1718

    
1719
void op_dvpe(void)
1720
{
1721
    // TODO
1722
    T0 = 0;
1723
    // rt = T0
1724
    FORCE_RET();
1725
}
1726

    
1727
void op_evpe(void)
1728
{
1729
    // TODO
1730
    T0 = 0;
1731
    // rt = T0
1732
    FORCE_RET();
1733
}
1734

    
1735
void op_fork(void)
1736
{
1737
    // T0 = rt, T1 = rs
1738
    T0 = 0;
1739
    // TODO: store to TC register
1740
    FORCE_RET();
1741
}
1742

    
1743
void op_yield(void)
1744
{
1745
    if (T0 < 0) {
1746
        /* No scheduling policy implemented. */
1747
        if (T0 != -2) {
1748
            if (env->CP0_VPEControl & (1 << CP0VPECo_YSI) &&
1749
                env->CP0_TCStatus[env->current_tc] & (1 << CP0TCSt_DT)) {
1750
                env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT);
1751
                env->CP0_VPEControl |= 4 << CP0VPECo_EXCPT;
1752
                CALL_FROM_TB1(do_raise_exception, EXCP_THREAD);
1753
            }
1754
        }
1755
    } else if (T0 == 0) {
1756
        if (0 /* TODO: TC underflow */) {
1757
            env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT);
1758
            CALL_FROM_TB1(do_raise_exception, EXCP_THREAD);
1759
        } else {
1760
            // TODO: Deallocate TC
1761
        }
1762
    } else if (T0 > 0) {
1763
        /* Yield qualifier inputs not implemented. */
1764
        env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT);
1765
        env->CP0_VPEControl |= 2 << CP0VPECo_EXCPT;
1766
        CALL_FROM_TB1(do_raise_exception, EXCP_THREAD);
1767
    }
1768
    T0 = env->CP0_YQMask;
1769
    FORCE_RET();
1770
}
1771

    
1772
/* CP1 functions */
1773
#if 0
1774
# define DEBUG_FPU_STATE() CALL_FROM_TB1(dump_fpu, env)
1775
#else
1776
# define DEBUG_FPU_STATE() do { } while(0)
1777
#endif
1778

    
1779
void op_cfc1 (void)
1780
{
1781
    CALL_FROM_TB1(do_cfc1, PARAM1);
1782
    DEBUG_FPU_STATE();
1783
    FORCE_RET();
1784
}
1785

    
1786
void op_ctc1 (void)
1787
{
1788
    CALL_FROM_TB1(do_ctc1, PARAM1);
1789
    DEBUG_FPU_STATE();
1790
    FORCE_RET();
1791
}
1792

    
1793
void op_mfc1 (void)
1794
{
1795
    T0 = (int32_t)WT0;
1796
    DEBUG_FPU_STATE();
1797
    FORCE_RET();
1798
}
1799

    
1800
void op_mtc1 (void)
1801
{
1802
    WT0 = T0;
1803
    DEBUG_FPU_STATE();
1804
    FORCE_RET();
1805
}
1806

    
1807
void op_dmfc1 (void)
1808
{
1809
    T0 = DT0;
1810
    DEBUG_FPU_STATE();
1811
    FORCE_RET();
1812
}
1813

    
1814
void op_dmtc1 (void)
1815
{
1816
    DT0 = T0;
1817
    DEBUG_FPU_STATE();
1818
    FORCE_RET();
1819
}
1820

    
1821
void op_mfhc1 (void)
1822
{
1823
    T0 = (int32_t)WTH0;
1824
    DEBUG_FPU_STATE();
1825
    FORCE_RET();
1826
}
1827

    
1828
void op_mthc1 (void)
1829
{
1830
    WTH0 = T0;
1831
    DEBUG_FPU_STATE();
1832
    FORCE_RET();
1833
}
1834

    
1835
/* Float support.
1836
   Single precition routines have a "s" suffix, double precision a
1837
   "d" suffix, 32bit integer "w", 64bit integer "l", paired singe "ps",
1838
   paired single lowwer "pl", paired single upper "pu".  */
1839

    
1840
#define FLOAT_OP(name, p) void OPPROTO op_float_##name##_##p(void)
1841

    
1842
FLOAT_OP(cvtd, s)
1843
{
1844
    CALL_FROM_TB0(do_float_cvtd_s);
1845
    DEBUG_FPU_STATE();
1846
    FORCE_RET();
1847
}
1848
FLOAT_OP(cvtd, w)
1849
{
1850
    CALL_FROM_TB0(do_float_cvtd_w);
1851
    DEBUG_FPU_STATE();
1852
    FORCE_RET();
1853
}
1854
FLOAT_OP(cvtd, l)
1855
{
1856
    CALL_FROM_TB0(do_float_cvtd_l);
1857
    DEBUG_FPU_STATE();
1858
    FORCE_RET();
1859
}
1860
FLOAT_OP(cvtl, d)
1861
{
1862
    CALL_FROM_TB0(do_float_cvtl_d);
1863
    DEBUG_FPU_STATE();
1864
    FORCE_RET();
1865
}
1866
FLOAT_OP(cvtl, s)
1867
{
1868
    CALL_FROM_TB0(do_float_cvtl_s);
1869
    DEBUG_FPU_STATE();
1870
    FORCE_RET();
1871
}
1872
FLOAT_OP(cvtps, s)
1873
{
1874
    WT2 = WT0;
1875
    WTH2 = WT1;
1876
    DEBUG_FPU_STATE();
1877
    FORCE_RET();
1878
}
1879
FLOAT_OP(cvtps, pw)
1880
{
1881
    CALL_FROM_TB0(do_float_cvtps_pw);
1882
    DEBUG_FPU_STATE();
1883
    FORCE_RET();
1884
}
1885
FLOAT_OP(cvtpw, ps)
1886
{
1887
    CALL_FROM_TB0(do_float_cvtpw_ps);
1888
    DEBUG_FPU_STATE();
1889
    FORCE_RET();
1890
}
1891
FLOAT_OP(cvts, d)
1892
{
1893
    CALL_FROM_TB0(do_float_cvts_d);
1894
    DEBUG_FPU_STATE();
1895
    FORCE_RET();
1896
}
1897
FLOAT_OP(cvts, w)
1898
{
1899
    CALL_FROM_TB0(do_float_cvts_w);
1900
    DEBUG_FPU_STATE();
1901
    FORCE_RET();
1902
}
1903
FLOAT_OP(cvts, l)
1904
{
1905
    CALL_FROM_TB0(do_float_cvts_l);
1906
    DEBUG_FPU_STATE();
1907
    FORCE_RET();
1908
}
1909
FLOAT_OP(cvts, pl)
1910
{
1911
    CALL_FROM_TB0(do_float_cvts_pl);
1912
    DEBUG_FPU_STATE();
1913
    FORCE_RET();
1914
}
1915
FLOAT_OP(cvts, pu)
1916
{
1917
    CALL_FROM_TB0(do_float_cvts_pu);
1918
    DEBUG_FPU_STATE();
1919
    FORCE_RET();
1920
}
1921
FLOAT_OP(cvtw, s)
1922
{
1923
    CALL_FROM_TB0(do_float_cvtw_s);
1924
    DEBUG_FPU_STATE();
1925
    FORCE_RET();
1926
}
1927
FLOAT_OP(cvtw, d)
1928
{
1929
    CALL_FROM_TB0(do_float_cvtw_d);
1930
    DEBUG_FPU_STATE();
1931
    FORCE_RET();
1932
}
1933

    
1934
FLOAT_OP(pll, ps)
1935
{
1936
    DT2 = ((uint64_t)WT0 << 32) | WT1;
1937
    DEBUG_FPU_STATE();
1938
    FORCE_RET();
1939
}
1940
FLOAT_OP(plu, ps)
1941
{
1942
    DT2 = ((uint64_t)WT0 << 32) | WTH1;
1943
    DEBUG_FPU_STATE();
1944
    FORCE_RET();
1945
}
1946
FLOAT_OP(pul, ps)
1947
{
1948
    DT2 = ((uint64_t)WTH0 << 32) | WT1;
1949
    DEBUG_FPU_STATE();
1950
    FORCE_RET();
1951
}
1952
FLOAT_OP(puu, ps)
1953
{
1954
    DT2 = ((uint64_t)WTH0 << 32) | WTH1;
1955
    DEBUG_FPU_STATE();
1956
    FORCE_RET();
1957
}
1958

    
1959
#define FLOAT_ROUNDOP(op, ttype, stype)                    \
1960
FLOAT_OP(op ## ttype, stype)                               \
1961
{                                                          \
1962
    CALL_FROM_TB0(do_float_ ## op ## ttype ## _ ## stype); \
1963
    DEBUG_FPU_STATE();                                     \
1964
    FORCE_RET();                                           \
1965
}
1966

    
1967
FLOAT_ROUNDOP(round, l, d)
1968
FLOAT_ROUNDOP(round, l, s)
1969
FLOAT_ROUNDOP(round, w, d)
1970
FLOAT_ROUNDOP(round, w, s)
1971

    
1972
FLOAT_ROUNDOP(trunc, l, d)
1973
FLOAT_ROUNDOP(trunc, l, s)
1974
FLOAT_ROUNDOP(trunc, w, d)
1975
FLOAT_ROUNDOP(trunc, w, s)
1976

    
1977
FLOAT_ROUNDOP(ceil, l, d)
1978
FLOAT_ROUNDOP(ceil, l, s)
1979
FLOAT_ROUNDOP(ceil, w, d)
1980
FLOAT_ROUNDOP(ceil, w, s)
1981

    
1982
FLOAT_ROUNDOP(floor, l, d)
1983
FLOAT_ROUNDOP(floor, l, s)
1984
FLOAT_ROUNDOP(floor, w, d)
1985
FLOAT_ROUNDOP(floor, w, s)
1986
#undef FLOAR_ROUNDOP
1987

    
1988
FLOAT_OP(movf, d)
1989
{
1990
    if (!(env->fpu->fcr31 & PARAM1))
1991
        DT2 = DT0;
1992
    DEBUG_FPU_STATE();
1993
    FORCE_RET();
1994
}
1995
FLOAT_OP(movf, s)
1996
{
1997
    if (!(env->fpu->fcr31 & PARAM1))
1998
        WT2 = WT0;
1999
    DEBUG_FPU_STATE();
2000
    FORCE_RET();
2001
}
2002
FLOAT_OP(movf, ps)
2003
{
2004
    if (!(env->fpu->fcr31 & PARAM1)) {
2005
        WT2 = WT0;
2006
        WTH2 = WTH0;
2007
    }
2008
    DEBUG_FPU_STATE();
2009
    FORCE_RET();
2010
}
2011
FLOAT_OP(movt, d)
2012
{
2013
    if (env->fpu->fcr31 & PARAM1)
2014
        DT2 = DT0;
2015
    DEBUG_FPU_STATE();
2016
    FORCE_RET();
2017
}
2018
FLOAT_OP(movt, s)
2019
{
2020
    if (env->fpu->fcr31 & PARAM1)
2021
        WT2 = WT0;
2022
    DEBUG_FPU_STATE();
2023
    FORCE_RET();
2024
}
2025
FLOAT_OP(movt, ps)
2026
{
2027
    if (env->fpu->fcr31 & PARAM1) {
2028
        WT2 = WT0;
2029
        WTH2 = WTH0;
2030
    }
2031
    DEBUG_FPU_STATE();
2032
    FORCE_RET();
2033
}
2034
FLOAT_OP(movz, d)
2035
{
2036
    if (!T0)
2037
        DT2 = DT0;
2038
    DEBUG_FPU_STATE();
2039
    FORCE_RET();
2040
}
2041
FLOAT_OP(movz, s)
2042
{
2043
    if (!T0)
2044
        WT2 = WT0;
2045
    DEBUG_FPU_STATE();
2046
    FORCE_RET();
2047
}
2048
FLOAT_OP(movz, ps)
2049
{
2050
    if (!T0) {
2051
        WT2 = WT0;
2052
        WTH2 = WTH0;
2053
    }
2054
    DEBUG_FPU_STATE();
2055
    FORCE_RET();
2056
}
2057
FLOAT_OP(movn, d)
2058
{
2059
    if (T0)
2060
        DT2 = DT0;
2061
    DEBUG_FPU_STATE();
2062
    FORCE_RET();
2063
}
2064
FLOAT_OP(movn, s)
2065
{
2066
    if (T0)
2067
        WT2 = WT0;
2068
    DEBUG_FPU_STATE();
2069
    FORCE_RET();
2070
}
2071
FLOAT_OP(movn, ps)
2072
{
2073
    if (T0) {
2074
        WT2 = WT0;
2075
        WTH2 = WTH0;
2076
    }
2077
    DEBUG_FPU_STATE();
2078
    FORCE_RET();
2079
}
2080

    
2081
/* operations calling helpers, for s, d and ps */
2082
#define FLOAT_HOP(name)   \
2083
FLOAT_OP(name, d)         \
2084
{                         \
2085
    CALL_FROM_TB0(do_float_ ## name ## _d);  \
2086
    DEBUG_FPU_STATE();    \
2087
    FORCE_RET();          \
2088
}                         \
2089
FLOAT_OP(name, s)         \
2090
{                         \
2091
    CALL_FROM_TB0(do_float_ ## name ## _s);  \
2092
    DEBUG_FPU_STATE();    \
2093
    FORCE_RET();          \
2094
}                         \
2095
FLOAT_OP(name, ps)        \
2096
{                         \
2097
    CALL_FROM_TB0(do_float_ ## name ## _ps); \
2098
    DEBUG_FPU_STATE();    \
2099
    FORCE_RET();          \
2100
}
2101
FLOAT_HOP(add)
2102
FLOAT_HOP(sub)
2103
FLOAT_HOP(mul)
2104
FLOAT_HOP(div)
2105
FLOAT_HOP(recip2)
2106
FLOAT_HOP(rsqrt2)
2107
FLOAT_HOP(rsqrt1)
2108
FLOAT_HOP(recip1)
2109
#undef FLOAT_HOP
2110

    
2111
/* operations calling helpers, for s and d */
2112
#define FLOAT_HOP(name)   \
2113
FLOAT_OP(name, d)         \
2114
{                         \
2115
    CALL_FROM_TB0(do_float_ ## name ## _d);  \
2116
    DEBUG_FPU_STATE();    \
2117
    FORCE_RET();          \
2118
}                         \
2119
FLOAT_OP(name, s)         \
2120
{                         \
2121
    CALL_FROM_TB0(do_float_ ## name ## _s);  \
2122
    DEBUG_FPU_STATE();    \
2123
    FORCE_RET();          \
2124
}
2125
FLOAT_HOP(rsqrt)
2126
FLOAT_HOP(recip)
2127
#undef FLOAT_HOP
2128

    
2129
/* operations calling helpers, for ps */
2130
#define FLOAT_HOP(name)   \
2131
FLOAT_OP(name, ps)        \
2132
{                         \
2133
    CALL_FROM_TB0(do_float_ ## name ## _ps); \
2134
    DEBUG_FPU_STATE();    \
2135
    FORCE_RET();          \
2136
}
2137
FLOAT_HOP(addr)
2138
FLOAT_HOP(mulr)
2139
#undef FLOAT_HOP
2140

    
2141
/* ternary operations */
2142
#define FLOAT_TERNOP(name1, name2) \
2143
FLOAT_OP(name1 ## name2, d)        \
2144
{                                  \
2145
    FDT0 = float64_ ## name1 (FDT0, FDT1, &env->fpu->fp_status);    \
2146
    FDT2 = float64_ ## name2 (FDT0, FDT2, &env->fpu->fp_status);    \
2147
    DEBUG_FPU_STATE();             \
2148
    FORCE_RET();                   \
2149
}                                  \
2150
FLOAT_OP(name1 ## name2, s)        \
2151
{                                  \
2152
    FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status);    \
2153
    FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status);    \
2154
    DEBUG_FPU_STATE();             \
2155
    FORCE_RET();                   \
2156
}                                  \
2157
FLOAT_OP(name1 ## name2, ps)       \
2158
{                                  \
2159
    FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status);    \
2160
    FSTH0 = float32_ ## name1 (FSTH0, FSTH1, &env->fpu->fp_status); \
2161
    FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status);    \
2162
    FSTH2 = float32_ ## name2 (FSTH0, FSTH2, &env->fpu->fp_status); \
2163
    DEBUG_FPU_STATE();             \
2164
    FORCE_RET();                   \
2165
}
2166
FLOAT_TERNOP(mul, add)
2167
FLOAT_TERNOP(mul, sub)
2168
#undef FLOAT_TERNOP
2169

    
2170
/* negated ternary operations */
2171
#define FLOAT_NTERNOP(name1, name2) \
2172
FLOAT_OP(n ## name1 ## name2, d)    \
2173
{                                   \
2174
    FDT0 = float64_ ## name1 (FDT0, FDT1, &env->fpu->fp_status);    \
2175
    FDT2 = float64_ ## name2 (FDT0, FDT2, &env->fpu->fp_status);    \
2176
    FDT2 = float64_chs(FDT2);       \
2177
    DEBUG_FPU_STATE();              \
2178
    FORCE_RET();                    \
2179
}                                   \
2180
FLOAT_OP(n ## name1 ## name2, s)    \
2181
{                                   \
2182
    FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status);    \
2183
    FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status);    \
2184
    FST2 = float32_chs(FST2);       \
2185
    DEBUG_FPU_STATE();              \
2186
    FORCE_RET();                    \
2187
}                                   \
2188
FLOAT_OP(n ## name1 ## name2, ps)   \
2189
{                                   \
2190
    FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status);    \
2191
    FSTH0 = float32_ ## name1 (FSTH0, FSTH1, &env->fpu->fp_status); \
2192
    FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status);    \
2193
    FSTH2 = float32_ ## name2 (FSTH0, FSTH2, &env->fpu->fp_status); \
2194
    FST2 = float32_chs(FST2);       \
2195
    FSTH2 = float32_chs(FSTH2);     \
2196
    DEBUG_FPU_STATE();              \
2197
    FORCE_RET();                    \
2198
}
2199
FLOAT_NTERNOP(mul, add)
2200
FLOAT_NTERNOP(mul, sub)
2201
#undef FLOAT_NTERNOP
2202

    
2203
/* unary operations, modifying fp status  */
2204
#define FLOAT_UNOP(name)  \
2205
FLOAT_OP(name, d)         \
2206
{                         \
2207
    FDT2 = float64_ ## name(FDT0, &env->fpu->fp_status); \
2208
    DEBUG_FPU_STATE();    \
2209
    FORCE_RET();          \
2210
}                         \
2211
FLOAT_OP(name, s)         \
2212
{                         \
2213
    FST2 = float32_ ## name(FST0, &env->fpu->fp_status); \
2214
    DEBUG_FPU_STATE();    \
2215
    FORCE_RET();          \
2216
}
2217
FLOAT_UNOP(sqrt)
2218
#undef FLOAT_UNOP
2219

    
2220
/* unary operations, not modifying fp status  */
2221
#define FLOAT_UNOP(name)  \
2222
FLOAT_OP(name, d)         \
2223
{                         \
2224
    FDT2 = float64_ ## name(FDT0);   \
2225
    DEBUG_FPU_STATE();    \
2226
    FORCE_RET();          \
2227
}                         \
2228
FLOAT_OP(name, s)         \
2229
{                         \
2230
    FST2 = float32_ ## name(FST0);   \
2231
    DEBUG_FPU_STATE();    \
2232
    FORCE_RET();          \
2233
}                         \
2234
FLOAT_OP(name, ps)        \
2235
{                         \
2236
    FST2 = float32_ ## name(FST0);   \
2237
    FSTH2 = float32_ ## name(FSTH0); \
2238
    DEBUG_FPU_STATE();    \
2239
    FORCE_RET();          \
2240
}
2241
FLOAT_UNOP(abs)
2242
FLOAT_UNOP(chs)
2243
#undef FLOAT_UNOP
2244

    
2245
FLOAT_OP(mov, d)
2246
{
2247
    FDT2 = FDT0;
2248
    DEBUG_FPU_STATE();
2249
    FORCE_RET();
2250
}
2251
FLOAT_OP(mov, s)
2252
{
2253
    FST2 = FST0;
2254
    DEBUG_FPU_STATE();
2255
    FORCE_RET();
2256
}
2257
FLOAT_OP(mov, ps)
2258
{
2259
    FST2 = FST0;
2260
    FSTH2 = FSTH0;
2261
    DEBUG_FPU_STATE();
2262
    FORCE_RET();
2263
}
2264
FLOAT_OP(alnv, ps)
2265
{
2266
    switch (T0 & 0x7) {
2267
    case 0:
2268
        FST2 = FST0;
2269
        FSTH2 = FSTH0;
2270
        break;
2271
    case 4:
2272
#ifdef TARGET_WORDS_BIGENDIAN
2273
        FSTH2 = FST0;
2274
        FST2 = FSTH1;
2275
#else
2276
        FSTH2 = FST1;
2277
        FST2 = FSTH0;
2278
#endif
2279
        break;
2280
    default: /* unpredictable */
2281
        break;
2282
    }
2283
    DEBUG_FPU_STATE();
2284
    FORCE_RET();
2285
}
2286

    
2287
#ifdef CONFIG_SOFTFLOAT
2288
#define clear_invalid() do {                                \
2289
    int flags = get_float_exception_flags(&env->fpu->fp_status); \
2290
    flags &= ~float_flag_invalid;                           \
2291
    set_float_exception_flags(flags, &env->fpu->fp_status); \
2292
} while(0)
2293
#else
2294
#define clear_invalid() do { } while(0)
2295
#endif
2296

    
2297
extern void dump_fpu_s(CPUState *env);
2298

    
2299
#define CMP_OP(fmt, op)                                \
2300
void OPPROTO op_cmp ## _ ## fmt ## _ ## op(void)       \
2301
{                                                      \
2302
    CALL_FROM_TB1(do_cmp ## _ ## fmt ## _ ## op, PARAM1); \
2303
    DEBUG_FPU_STATE();                                 \
2304
    FORCE_RET();                                       \
2305
}                                                      \
2306
void OPPROTO op_cmpabs ## _ ## fmt ## _ ## op(void)    \
2307
{                                                      \
2308
    CALL_FROM_TB1(do_cmpabs ## _ ## fmt ## _ ## op, PARAM1); \
2309
    DEBUG_FPU_STATE();                                 \
2310
    FORCE_RET();                                       \
2311
}
2312
#define CMP_OPS(op)   \
2313
CMP_OP(d, op)         \
2314
CMP_OP(s, op)         \
2315
CMP_OP(ps, op)
2316

    
2317
CMP_OPS(f)
2318
CMP_OPS(un)
2319
CMP_OPS(eq)
2320
CMP_OPS(ueq)
2321
CMP_OPS(olt)
2322
CMP_OPS(ult)
2323
CMP_OPS(ole)
2324
CMP_OPS(ule)
2325
CMP_OPS(sf)
2326
CMP_OPS(ngle)
2327
CMP_OPS(seq)
2328
CMP_OPS(ngl)
2329
CMP_OPS(lt)
2330
CMP_OPS(nge)
2331
CMP_OPS(le)
2332
CMP_OPS(ngt)
2333
#undef CMP_OPS
2334
#undef CMP_OP
2335

    
2336
void op_bc1f (void)
2337
{
2338
    T0 = !!(~GET_FP_COND(env->fpu) & (0x1 << PARAM1));
2339
    DEBUG_FPU_STATE();
2340
    FORCE_RET();
2341
}
2342
void op_bc1any2f (void)
2343
{
2344
    T0 = !!(~GET_FP_COND(env->fpu) & (0x3 << PARAM1));
2345
    DEBUG_FPU_STATE();
2346
    FORCE_RET();
2347
}
2348
void op_bc1any4f (void)
2349
{
2350
    T0 = !!(~GET_FP_COND(env->fpu) & (0xf << PARAM1));
2351
    DEBUG_FPU_STATE();
2352
    FORCE_RET();
2353
}
2354

    
2355
void op_bc1t (void)
2356
{
2357
    T0 = !!(GET_FP_COND(env->fpu) & (0x1 << PARAM1));
2358
    DEBUG_FPU_STATE();
2359
    FORCE_RET();
2360
}
2361
void op_bc1any2t (void)
2362
{
2363
    T0 = !!(GET_FP_COND(env->fpu) & (0x3 << PARAM1));
2364
    DEBUG_FPU_STATE();
2365
    FORCE_RET();
2366
}
2367
void op_bc1any4t (void)
2368
{
2369
    T0 = !!(GET_FP_COND(env->fpu) & (0xf << PARAM1));
2370
    DEBUG_FPU_STATE();
2371
    FORCE_RET();
2372
}
2373

    
2374
void op_tlbwi (void)
2375
{
2376
    CALL_FROM_TB0(env->tlb->do_tlbwi);
2377
    FORCE_RET();
2378
}
2379

    
2380
void op_tlbwr (void)
2381
{
2382
    CALL_FROM_TB0(env->tlb->do_tlbwr);
2383
    FORCE_RET();
2384
}
2385

    
2386
void op_tlbp (void)
2387
{
2388
    CALL_FROM_TB0(env->tlb->do_tlbp);
2389
    FORCE_RET();
2390
}
2391

    
2392
void op_tlbr (void)
2393
{
2394
    CALL_FROM_TB0(env->tlb->do_tlbr);
2395
    FORCE_RET();
2396
}
2397

    
2398
/* Specials */
2399
#if defined (CONFIG_USER_ONLY)
2400
void op_tls_value (void)
2401
{
2402
    T0 = env->tls_value;
2403
}
2404
#endif
2405

    
2406
void op_pmon (void)
2407
{
2408
    CALL_FROM_TB1(do_pmon, PARAM1);
2409
    FORCE_RET();
2410
}
2411

    
2412
void op_di (void)
2413
{
2414
    T0 = env->CP0_Status;
2415
    env->CP0_Status = T0 & ~(1 << CP0St_IE);
2416
    CALL_FROM_TB1(cpu_mips_update_irq, env);
2417
    FORCE_RET();
2418
}
2419

    
2420
void op_ei (void)
2421
{
2422
    T0 = env->CP0_Status;
2423
    env->CP0_Status = T0 | (1 << CP0St_IE);
2424
    CALL_FROM_TB1(cpu_mips_update_irq, env);
2425
    FORCE_RET();
2426
}
2427

    
2428
void op_trap (void)
2429
{
2430
    if (T0) {
2431
        CALL_FROM_TB1(do_raise_exception, EXCP_TRAP);
2432
    }
2433
    FORCE_RET();
2434
}
2435

    
2436
void op_debug (void)
2437
{
2438
    CALL_FROM_TB1(do_raise_exception, EXCP_DEBUG);
2439
    FORCE_RET();
2440
}
2441

    
2442
void debug_pre_eret (void);
2443
void debug_post_eret (void);
2444
void op_eret (void)
2445
{
2446
    if (loglevel & CPU_LOG_EXEC)
2447
        CALL_FROM_TB0(debug_pre_eret);
2448
    if (env->CP0_Status & (1 << CP0St_ERL)) {
2449
        env->PC[env->current_tc] = env->CP0_ErrorEPC;
2450
        env->CP0_Status &= ~(1 << CP0St_ERL);
2451
    } else {
2452
        env->PC[env->current_tc] = env->CP0_EPC;
2453
        env->CP0_Status &= ~(1 << CP0St_EXL);
2454
    }
2455
    CALL_FROM_TB1(compute_hflags, env);
2456
    if (loglevel & CPU_LOG_EXEC)
2457
        CALL_FROM_TB0(debug_post_eret);
2458
    env->CP0_LLAddr = 1;
2459
    FORCE_RET();
2460
}
2461

    
2462
void op_deret (void)
2463
{
2464
    if (loglevel & CPU_LOG_EXEC)
2465
        CALL_FROM_TB0(debug_pre_eret);
2466
    env->PC[env->current_tc] = env->CP0_DEPC;
2467
    env->hflags &= MIPS_HFLAG_DM;
2468
    CALL_FROM_TB1(compute_hflags, env);
2469
    if (loglevel & CPU_LOG_EXEC)
2470
        CALL_FROM_TB0(debug_post_eret);
2471
    env->CP0_LLAddr = 1;
2472
    FORCE_RET();
2473
}
2474

    
2475
void op_rdhwr_cpunum(void)
2476
{
2477
    if ((env->hflags & MIPS_HFLAG_CP0) ||
2478
        (env->CP0_HWREna & (1 << 0)))
2479
        T0 = env->CP0_EBase & 0x3ff;
2480
    else
2481
        CALL_FROM_TB1(do_raise_exception, EXCP_RI);
2482
    FORCE_RET();
2483
}
2484

    
2485
void op_rdhwr_synci_step(void)
2486
{
2487
    if ((env->hflags & MIPS_HFLAG_CP0) ||
2488
        (env->CP0_HWREna & (1 << 1)))
2489
        T0 = env->SYNCI_Step;
2490
    else
2491
        CALL_FROM_TB1(do_raise_exception, EXCP_RI);
2492
    FORCE_RET();
2493
}
2494

    
2495
void op_rdhwr_cc(void)
2496
{
2497
    if ((env->hflags & MIPS_HFLAG_CP0) ||
2498
        (env->CP0_HWREna & (1 << 2)))
2499
        T0 = env->CP0_Count;
2500
    else
2501
        CALL_FROM_TB1(do_raise_exception, EXCP_RI);
2502
    FORCE_RET();
2503
}
2504

    
2505
void op_rdhwr_ccres(void)
2506
{
2507
    if ((env->hflags & MIPS_HFLAG_CP0) ||
2508
        (env->CP0_HWREna & (1 << 3)))
2509
        T0 = env->CCRes;
2510
    else
2511
        CALL_FROM_TB1(do_raise_exception, EXCP_RI);
2512
    FORCE_RET();
2513
}
2514

    
2515
void op_save_state (void)
2516
{
2517
    env->hflags = PARAM1;
2518
    FORCE_RET();
2519
}
2520

    
2521
void op_wait (void)
2522
{
2523
    env->halted = 1;
2524
    CALL_FROM_TB1(do_raise_exception, EXCP_HLT);
2525
    FORCE_RET();
2526
}
2527

    
2528
/* Bitfield operations. */
2529
void op_ext(void)
2530
{
2531
    unsigned int pos = PARAM1;
2532
    unsigned int size = PARAM2;
2533

    
2534
    T0 = (int32_t)((T1 >> pos) & ((size < 32) ? ((1 << size) - 1) : ~0));
2535
    FORCE_RET();
2536
}
2537

    
2538
void op_ins(void)
2539
{
2540
    unsigned int pos = PARAM1;
2541
    unsigned int size = PARAM2;
2542
    target_ulong mask = ((size < 32) ? ((1 << size) - 1) : ~0) << pos;
2543

    
2544
    T0 = (int32_t)((T0 & ~mask) | ((T1 << pos) & mask));
2545
    FORCE_RET();
2546
}
2547

    
2548
void op_wsbh(void)
2549
{
2550
    T0 = (int32_t)(((T1 << 8) & ~0x00FF00FF) | ((T1 >> 8) & 0x00FF00FF));
2551
    FORCE_RET();
2552
}
2553

    
2554
#if defined(TARGET_MIPS64)
2555
void op_dext(void)
2556
{
2557
    unsigned int pos = PARAM1;
2558
    unsigned int size = PARAM2;
2559

    
2560
    T0 = (T1 >> pos) & ((size < 64) ? ((1ULL << size) - 1) : ~0ULL);
2561
    FORCE_RET();
2562
}
2563

    
2564
void op_dins(void)
2565
{
2566
    unsigned int pos = PARAM1;
2567
    unsigned int size = PARAM2;
2568
    target_ulong mask = ((size < 64) ? ((1ULL << size) - 1) : ~0ULL) << pos;
2569

    
2570
    T0 = (T0 & ~mask) | ((T1 << pos) & mask);
2571
    FORCE_RET();
2572
}
2573

    
2574
void op_dsbh(void)
2575
{
2576
    T0 = ((T1 << 8) & ~0x00FF00FF00FF00FFULL) | ((T1 >> 8) & 0x00FF00FF00FF00FFULL);
2577
    FORCE_RET();
2578
}
2579

    
2580
void op_dshd(void)
2581
{
2582
    T1 = ((T1 << 16) & ~0x0000FFFF0000FFFFULL) | ((T1 >> 16) & 0x0000FFFF0000FFFFULL);
2583
    T0 = (T1 << 32) | (T1 >> 32);
2584
    FORCE_RET();
2585
}
2586
#endif