Statistics
| Branch: | Revision:

root / target-mips / op.c @ e6bb7d7e

History | View | Annotate | Download (45.1 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
/* CP0 functions */
464
void op_mfc0_mvpcontrol (void)
465
{
466
    T0 = env->mvp->CP0_MVPControl;
467
    FORCE_RET();
468
}
469

    
470
void op_mfc0_mvpconf0 (void)
471
{
472
    T0 = env->mvp->CP0_MVPConf0;
473
    FORCE_RET();
474
}
475

    
476
void op_mfc0_mvpconf1 (void)
477
{
478
    T0 = env->mvp->CP0_MVPConf1;
479
    FORCE_RET();
480
}
481

    
482
void op_mfc0_random (void)
483
{
484
    CALL_FROM_TB0(do_mfc0_random);
485
    FORCE_RET();
486
}
487

    
488
void op_mfc0_tcstatus (void)
489
{
490
    T0 = env->CP0_TCStatus[env->current_tc];
491
    FORCE_RET();
492
}
493

    
494
void op_mftc0_tcstatus(void)
495
{
496
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
497

    
498
    T0 = env->CP0_TCStatus[other_tc];
499
    FORCE_RET();
500
}
501

    
502
void op_mfc0_tcbind (void)
503
{
504
    T0 = env->CP0_TCBind[env->current_tc];
505
    FORCE_RET();
506
}
507

    
508
void op_mftc0_tcbind(void)
509
{
510
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
511

    
512
    T0 = env->CP0_TCBind[other_tc];
513
    FORCE_RET();
514
}
515

    
516
void op_mfc0_tcrestart (void)
517
{
518
    T0 = env->PC[env->current_tc];
519
    FORCE_RET();
520
}
521

    
522
void op_mftc0_tcrestart(void)
523
{
524
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
525

    
526
    T0 = env->PC[other_tc];
527
    FORCE_RET();
528
}
529

    
530
void op_mfc0_tchalt (void)
531
{
532
    T0 = env->CP0_TCHalt[env->current_tc];
533
    FORCE_RET();
534
}
535

    
536
void op_mftc0_tchalt(void)
537
{
538
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
539

    
540
    T0 = env->CP0_TCHalt[other_tc];
541
    FORCE_RET();
542
}
543

    
544
void op_mfc0_tccontext (void)
545
{
546
    T0 = env->CP0_TCContext[env->current_tc];
547
    FORCE_RET();
548
}
549

    
550
void op_mftc0_tccontext(void)
551
{
552
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
553

    
554
    T0 = env->CP0_TCContext[other_tc];
555
    FORCE_RET();
556
}
557

    
558
void op_mfc0_tcschedule (void)
559
{
560
    T0 = env->CP0_TCSchedule[env->current_tc];
561
    FORCE_RET();
562
}
563

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

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

    
572
void op_mfc0_tcschefback (void)
573
{
574
    T0 = env->CP0_TCScheFBack[env->current_tc];
575
    FORCE_RET();
576
}
577

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

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

    
586
void op_mfc0_count (void)
587
{
588
    CALL_FROM_TB0(do_mfc0_count);
589
    FORCE_RET();
590
}
591

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

    
596
    T0 = (env->CP0_EntryHi & ~0xff) | (env->CP0_TCStatus[other_tc] & 0xff);
597
    FORCE_RET();
598
}
599

    
600
void op_mftc0_status(void)
601
{
602
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
603
    uint32_t tcstatus = env->CP0_TCStatus[other_tc];
604

    
605
    T0 = env->CP0_Status & ~0xf1000018;
606
    T0 |= tcstatus & (0xf << CP0TCSt_TCU0);
607
    T0 |= (tcstatus & (1 << CP0TCSt_TMX)) >> (CP0TCSt_TMX - CP0St_MX);
608
    T0 |= (tcstatus & (0x3 << CP0TCSt_TKSU)) >> (CP0TCSt_TKSU - CP0St_KSU);
609
    FORCE_RET();
610
}
611

    
612
void op_mfc0_lladdr (void)
613
{
614
    T0 = (int32_t)env->CP0_LLAddr >> 4;
615
    FORCE_RET();
616
}
617

    
618
void op_mfc0_watchlo (void)
619
{
620
    T0 = (int32_t)env->CP0_WatchLo[PARAM1];
621
    FORCE_RET();
622
}
623

    
624
void op_mfc0_watchhi (void)
625
{
626
    T0 = env->CP0_WatchHi[PARAM1];
627
    FORCE_RET();
628
}
629

    
630
void op_mfc0_debug (void)
631
{
632
    T0 = env->CP0_Debug;
633
    if (env->hflags & MIPS_HFLAG_DM)
634
        T0 |= 1 << CP0DB_DM;
635
    FORCE_RET();
636
}
637

    
638
void op_mftc0_debug(void)
639
{
640
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
641

    
642
    /* XXX: Might be wrong, check with EJTAG spec. */
643
    T0 = (env->CP0_Debug & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) |
644
         (env->CP0_Debug_tcstatus[other_tc] &
645
          ((1 << CP0DB_SSt) | (1 << CP0DB_Halt)));
646
    FORCE_RET();
647
}
648

    
649
void op_mtc0_index (void)
650
{
651
    int num = 1;
652
    unsigned int tmp = env->tlb->nb_tlb;
653

    
654
    do {
655
        tmp >>= 1;
656
        num <<= 1;
657
    } while (tmp);
658
    env->CP0_Index = (env->CP0_Index & 0x80000000) | (T0 & (num - 1));
659
    FORCE_RET();
660
}
661

    
662
void op_mtc0_mvpcontrol (void)
663
{
664
    uint32_t mask = 0;
665
    uint32_t newval;
666

    
667
    if (env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP))
668
        mask |= (1 << CP0MVPCo_CPA) | (1 << CP0MVPCo_VPC) |
669
                (1 << CP0MVPCo_EVP);
670
    if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
671
        mask |= (1 << CP0MVPCo_STLB);
672
    newval = (env->mvp->CP0_MVPControl & ~mask) | (T0 & mask);
673

    
674
    // TODO: Enable/disable shared TLB, enable/disable VPEs.
675

    
676
    env->mvp->CP0_MVPControl = newval;
677
    FORCE_RET();
678
}
679

    
680
void op_mtc0_vpecontrol (void)
681
{
682
    uint32_t mask;
683
    uint32_t newval;
684

    
685
    mask = (1 << CP0VPECo_YSI) | (1 << CP0VPECo_GSI) |
686
           (1 << CP0VPECo_TE) | (0xff << CP0VPECo_TargTC);
687
    newval = (env->CP0_VPEControl & ~mask) | (T0 & mask);
688

    
689
    /* Yield scheduler intercept not implemented. */
690
    /* Gating storage scheduler intercept not implemented. */
691

    
692
    // TODO: Enable/disable TCs.
693

    
694
    env->CP0_VPEControl = newval;
695
    FORCE_RET();
696
}
697

    
698
void op_mtc0_vpeconf0 (void)
699
{
700
    uint32_t mask = 0;
701
    uint32_t newval;
702

    
703
    if (env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) {
704
        if (env->CP0_VPEConf0 & (1 << CP0VPEC0_VPA))
705
            mask |= (0xff << CP0VPEC0_XTC);
706
        mask |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
707
    }
708
    newval = (env->CP0_VPEConf0 & ~mask) | (T0 & mask);
709

    
710
    // TODO: TC exclusive handling due to ERL/EXL.
711

    
712
    env->CP0_VPEConf0 = newval;
713
    FORCE_RET();
714
}
715

    
716
void op_mtc0_vpeconf1 (void)
717
{
718
    uint32_t mask = 0;
719
    uint32_t newval;
720

    
721
    if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
722
        mask |= (0xff << CP0VPEC1_NCX) | (0xff << CP0VPEC1_NCP2) |
723
                (0xff << CP0VPEC1_NCP1);
724
    newval = (env->CP0_VPEConf1 & ~mask) | (T0 & mask);
725

    
726
    /* UDI not implemented. */
727
    /* CP2 not implemented. */
728

    
729
    // TODO: Handle FPU (CP1) binding.
730

    
731
    env->CP0_VPEConf1 = newval;
732
    FORCE_RET();
733
}
734

    
735
void op_mtc0_yqmask (void)
736
{
737
    /* Yield qualifier inputs not implemented. */
738
    env->CP0_YQMask = 0x00000000;
739
    FORCE_RET();
740
}
741

    
742
void op_mtc0_vpeschedule (void)
743
{
744
    env->CP0_VPESchedule = T0;
745
    FORCE_RET();
746
}
747

    
748
void op_mtc0_vpeschefback (void)
749
{
750
    env->CP0_VPEScheFBack = T0;
751
    FORCE_RET();
752
}
753

    
754
void op_mtc0_vpeopt (void)
755
{
756
    env->CP0_VPEOpt = T0 & 0x0000ffff;
757
    FORCE_RET();
758
}
759

    
760
void op_mtc0_entrylo0 (void)
761
{
762
    /* Large physaddr (PABITS) not implemented */
763
    /* 1k pages not implemented */
764
    env->CP0_EntryLo0 = T0 & 0x3FFFFFFF;
765
    FORCE_RET();
766
}
767

    
768
void op_mtc0_tcstatus (void)
769
{
770
    uint32_t mask = env->CP0_TCStatus_rw_bitmask;
771
    uint32_t newval;
772

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

    
775
    // TODO: Sync with CP0_Status.
776

    
777
    env->CP0_TCStatus[env->current_tc] = newval;
778
    FORCE_RET();
779
}
780

    
781
void op_mttc0_tcstatus (void)
782
{
783
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
784

    
785
    // TODO: Sync with CP0_Status.
786

    
787
    env->CP0_TCStatus[other_tc] = T0;
788
    FORCE_RET();
789
}
790

    
791
void op_mtc0_tcbind (void)
792
{
793
    uint32_t mask = (1 << CP0TCBd_TBE);
794
    uint32_t newval;
795

    
796
    if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
797
        mask |= (1 << CP0TCBd_CurVPE);
798
    newval = (env->CP0_TCBind[env->current_tc] & ~mask) | (T0 & mask);
799
    env->CP0_TCBind[env->current_tc] = newval;
800
    FORCE_RET();
801
}
802

    
803
void op_mttc0_tcbind (void)
804
{
805
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
806
    uint32_t mask = (1 << CP0TCBd_TBE);
807
    uint32_t newval;
808

    
809
    if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
810
        mask |= (1 << CP0TCBd_CurVPE);
811
    newval = (env->CP0_TCBind[other_tc] & ~mask) | (T0 & mask);
812
    env->CP0_TCBind[other_tc] = newval;
813
    FORCE_RET();
814
}
815

    
816
void op_mtc0_tcrestart (void)
817
{
818
    env->PC[env->current_tc] = T0;
819
    env->CP0_TCStatus[env->current_tc] &= ~(1 << CP0TCSt_TDS);
820
    env->CP0_LLAddr = 0ULL;
821
    /* MIPS16 not implemented. */
822
    FORCE_RET();
823
}
824

    
825
void op_mttc0_tcrestart (void)
826
{
827
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
828

    
829
    env->PC[other_tc] = T0;
830
    env->CP0_TCStatus[other_tc] &= ~(1 << CP0TCSt_TDS);
831
    env->CP0_LLAddr = 0ULL;
832
    /* MIPS16 not implemented. */
833
    FORCE_RET();
834
}
835

    
836
void op_mtc0_tchalt (void)
837
{
838
    env->CP0_TCHalt[env->current_tc] = T0 & 0x1;
839

    
840
    // TODO: Halt TC / Restart (if allocated+active) TC.
841

    
842
    FORCE_RET();
843
}
844

    
845
void op_mttc0_tchalt (void)
846
{
847
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
848

    
849
    // TODO: Halt TC / Restart (if allocated+active) TC.
850

    
851
    env->CP0_TCHalt[other_tc] = T0;
852
    FORCE_RET();
853
}
854

    
855
void op_mtc0_tccontext (void)
856
{
857
    env->CP0_TCContext[env->current_tc] = T0;
858
    FORCE_RET();
859
}
860

    
861
void op_mttc0_tccontext (void)
862
{
863
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
864

    
865
    env->CP0_TCContext[other_tc] = T0;
866
    FORCE_RET();
867
}
868

    
869
void op_mtc0_tcschedule (void)
870
{
871
    env->CP0_TCSchedule[env->current_tc] = T0;
872
    FORCE_RET();
873
}
874

    
875
void op_mttc0_tcschedule (void)
876
{
877
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
878

    
879
    env->CP0_TCSchedule[other_tc] = T0;
880
    FORCE_RET();
881
}
882

    
883
void op_mtc0_tcschefback (void)
884
{
885
    env->CP0_TCScheFBack[env->current_tc] = T0;
886
    FORCE_RET();
887
}
888

    
889
void op_mttc0_tcschefback (void)
890
{
891
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
892

    
893
    env->CP0_TCScheFBack[other_tc] = T0;
894
    FORCE_RET();
895
}
896

    
897
void op_mtc0_entrylo1 (void)
898
{
899
    /* Large physaddr (PABITS) not implemented */
900
    /* 1k pages not implemented */
901
    env->CP0_EntryLo1 = T0 & 0x3FFFFFFF;
902
    FORCE_RET();
903
}
904

    
905
void op_mtc0_context (void)
906
{
907
    env->CP0_Context = (env->CP0_Context & 0x007FFFFF) | (T0 & ~0x007FFFFF);
908
    FORCE_RET();
909
}
910

    
911
void op_mtc0_pagemask (void)
912
{
913
    /* 1k pages not implemented */
914
    env->CP0_PageMask = T0 & (0x1FFFFFFF & (TARGET_PAGE_MASK << 1));
915
    FORCE_RET();
916
}
917

    
918
void op_mtc0_pagegrain (void)
919
{
920
    /* SmartMIPS not implemented */
921
    /* Large physaddr (PABITS) not implemented */
922
    /* 1k pages not implemented */
923
    env->CP0_PageGrain = 0;
924
    FORCE_RET();
925
}
926

    
927
void op_mtc0_wired (void)
928
{
929
    env->CP0_Wired = T0 % env->tlb->nb_tlb;
930
    FORCE_RET();
931
}
932

    
933
void op_mtc0_srsconf0 (void)
934
{
935
    env->CP0_SRSConf0 |= T0 & env->CP0_SRSConf0_rw_bitmask;
936
    FORCE_RET();
937
}
938

    
939
void op_mtc0_srsconf1 (void)
940
{
941
    env->CP0_SRSConf1 |= T0 & env->CP0_SRSConf1_rw_bitmask;
942
    FORCE_RET();
943
}
944

    
945
void op_mtc0_srsconf2 (void)
946
{
947
    env->CP0_SRSConf2 |= T0 & env->CP0_SRSConf2_rw_bitmask;
948
    FORCE_RET();
949
}
950

    
951
void op_mtc0_srsconf3 (void)
952
{
953
    env->CP0_SRSConf3 |= T0 & env->CP0_SRSConf3_rw_bitmask;
954
    FORCE_RET();
955
}
956

    
957
void op_mtc0_srsconf4 (void)
958
{
959
    env->CP0_SRSConf4 |= T0 & env->CP0_SRSConf4_rw_bitmask;
960
    FORCE_RET();
961
}
962

    
963
void op_mtc0_hwrena (void)
964
{
965
    env->CP0_HWREna = T0 & 0x0000000F;
966
    FORCE_RET();
967
}
968

    
969
void op_mtc0_count (void)
970
{
971
    CALL_FROM_TB2(cpu_mips_store_count, env, T0);
972
    FORCE_RET();
973
}
974

    
975
void op_mtc0_entryhi (void)
976
{
977
    target_ulong old, val;
978

    
979
    /* 1k pages not implemented */
980
    val = T0 & ((TARGET_PAGE_MASK << 1) | 0xFF);
981
#if defined(TARGET_MIPS64)
982
    val &= env->SEGMask;
983
#endif
984
    old = env->CP0_EntryHi;
985
    env->CP0_EntryHi = val;
986
    if (env->CP0_Config3 & (1 << CP0C3_MT)) {
987
        uint32_t tcst = env->CP0_TCStatus[env->current_tc] & ~0xff;
988
        env->CP0_TCStatus[env->current_tc] = tcst | (val & 0xff);
989
    }
990
    /* If the ASID changes, flush qemu's TLB.  */
991
    if ((old & 0xFF) != (val & 0xFF))
992
        CALL_FROM_TB2(cpu_mips_tlb_flush, env, 1);
993
    FORCE_RET();
994
}
995

    
996
void op_mttc0_entryhi(void)
997
{
998
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
999

    
1000
    env->CP0_EntryHi = (env->CP0_EntryHi & 0xff) | (T0 & ~0xff);
1001
    env->CP0_TCStatus[other_tc] = (env->CP0_TCStatus[other_tc] & ~0xff) | (T0 & 0xff);
1002
    FORCE_RET();
1003
}
1004

    
1005
void op_mtc0_compare (void)
1006
{
1007
    CALL_FROM_TB2(cpu_mips_store_compare, env, T0);
1008
    FORCE_RET();
1009
}
1010

    
1011
void op_mtc0_status (void)
1012
{
1013
    uint32_t val, old;
1014
    uint32_t mask = env->CP0_Status_rw_bitmask;
1015

    
1016
    val = T0 & mask;
1017
    old = env->CP0_Status;
1018
    env->CP0_Status = (env->CP0_Status & ~mask) | val;
1019
    CALL_FROM_TB1(compute_hflags, env);
1020
    if (loglevel & CPU_LOG_EXEC)
1021
        CALL_FROM_TB2(do_mtc0_status_debug, old, val);
1022
    CALL_FROM_TB1(cpu_mips_update_irq, env);
1023
    FORCE_RET();
1024
}
1025

    
1026
void op_mttc0_status(void)
1027
{
1028
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1029
    uint32_t tcstatus = env->CP0_TCStatus[other_tc];
1030

    
1031
    env->CP0_Status = T0 & ~0xf1000018;
1032
    tcstatus = (tcstatus & ~(0xf << CP0TCSt_TCU0)) | (T0 & (0xf << CP0St_CU0));
1033
    tcstatus = (tcstatus & ~(1 << CP0TCSt_TMX)) | ((T0 & (1 << CP0St_MX)) << (CP0TCSt_TMX - CP0St_MX));
1034
    tcstatus = (tcstatus & ~(0x3 << CP0TCSt_TKSU)) | ((T0 & (0x3 << CP0St_KSU)) << (CP0TCSt_TKSU - CP0St_KSU));
1035
    env->CP0_TCStatus[other_tc] = tcstatus;
1036
    FORCE_RET();
1037
}
1038

    
1039
void op_mtc0_intctl (void)
1040
{
1041
    /* vectored interrupts not implemented, no performance counters. */
1042
    env->CP0_IntCtl = (env->CP0_IntCtl & ~0x000002e0) | (T0 & 0x000002e0);
1043
    FORCE_RET();
1044
}
1045

    
1046
void op_mtc0_srsctl (void)
1047
{
1048
    uint32_t mask = (0xf << CP0SRSCtl_ESS) | (0xf << CP0SRSCtl_PSS);
1049
    env->CP0_SRSCtl = (env->CP0_SRSCtl & ~mask) | (T0 & mask);
1050
    FORCE_RET();
1051
}
1052

    
1053
void op_mtc0_srsmap (void)
1054
{
1055
    env->CP0_SRSMap = T0;
1056
    FORCE_RET();
1057
}
1058

    
1059
void op_mtc0_cause (void)
1060
{
1061
    uint32_t mask = 0x00C00300;
1062
    uint32_t old = env->CP0_Cause;
1063

    
1064
    if (env->insn_flags & ISA_MIPS32R2)
1065
        mask |= 1 << CP0Ca_DC;
1066

    
1067
    env->CP0_Cause = (env->CP0_Cause & ~mask) | (T0 & mask);
1068

    
1069
    if ((old ^ env->CP0_Cause) & (1 << CP0Ca_DC)) {
1070
        if (env->CP0_Cause & (1 << CP0Ca_DC))
1071
            CALL_FROM_TB1(cpu_mips_stop_count, env);
1072
        else
1073
            CALL_FROM_TB1(cpu_mips_start_count, env);
1074
    }
1075

    
1076
    /* Handle the software interrupt as an hardware one, as they
1077
       are very similar */
1078
    if (T0 & CP0Ca_IP_mask) {
1079
        CALL_FROM_TB1(cpu_mips_update_irq, env);
1080
    }
1081
    FORCE_RET();
1082
}
1083

    
1084
void op_mtc0_epc (void)
1085
{
1086
    env->CP0_EPC = T0;
1087
    FORCE_RET();
1088
}
1089

    
1090
void op_mtc0_ebase (void)
1091
{
1092
    /* vectored interrupts not implemented */
1093
    /* Multi-CPU not implemented */
1094
    env->CP0_EBase = 0x80000000 | (T0 & 0x3FFFF000);
1095
    FORCE_RET();
1096
}
1097

    
1098
void op_mtc0_config0 (void)
1099
{
1100
    env->CP0_Config0 = (env->CP0_Config0 & 0x81FFFFF8) | (T0 & 0x00000007);
1101
    FORCE_RET();
1102
}
1103

    
1104
void op_mtc0_config2 (void)
1105
{
1106
    /* tertiary/secondary caches not implemented */
1107
    env->CP0_Config2 = (env->CP0_Config2 & 0x8FFF0FFF);
1108
    FORCE_RET();
1109
}
1110

    
1111
void op_mtc0_watchlo (void)
1112
{
1113
    /* Watch exceptions for instructions, data loads, data stores
1114
       not implemented. */
1115
    env->CP0_WatchLo[PARAM1] = (T0 & ~0x7);
1116
    FORCE_RET();
1117
}
1118

    
1119
void op_mtc0_watchhi (void)
1120
{
1121
    env->CP0_WatchHi[PARAM1] = (T0 & 0x40FF0FF8);
1122
    env->CP0_WatchHi[PARAM1] &= ~(env->CP0_WatchHi[PARAM1] & T0 & 0x7);
1123
    FORCE_RET();
1124
}
1125

    
1126
void op_mtc0_xcontext (void)
1127
{
1128
    target_ulong mask = (1ULL << (env->SEGBITS - 7)) - 1;
1129
    env->CP0_XContext = (env->CP0_XContext & mask) | (T0 & ~mask);
1130
    FORCE_RET();
1131
}
1132

    
1133
void op_mtc0_framemask (void)
1134
{
1135
    env->CP0_Framemask = T0; /* XXX */
1136
    FORCE_RET();
1137
}
1138

    
1139
void op_mtc0_debug (void)
1140
{
1141
    env->CP0_Debug = (env->CP0_Debug & 0x8C03FC1F) | (T0 & 0x13300120);
1142
    if (T0 & (1 << CP0DB_DM))
1143
        env->hflags |= MIPS_HFLAG_DM;
1144
    else
1145
        env->hflags &= ~MIPS_HFLAG_DM;
1146
    FORCE_RET();
1147
}
1148

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

    
1153
    /* XXX: Might be wrong, check with EJTAG spec. */
1154
    env->CP0_Debug_tcstatus[other_tc] = T0 & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt));
1155
    env->CP0_Debug = (env->CP0_Debug & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) |
1156
                     (T0 & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt)));
1157
    FORCE_RET();
1158
}
1159

    
1160
void op_mtc0_depc (void)
1161
{
1162
    env->CP0_DEPC = T0;
1163
    FORCE_RET();
1164
}
1165

    
1166
void op_mtc0_performance0 (void)
1167
{
1168
    env->CP0_Performance0 = T0 & 0x000007ff;
1169
    FORCE_RET();
1170
}
1171

    
1172
void op_mtc0_taglo (void)
1173
{
1174
    env->CP0_TagLo = T0 & 0xFFFFFCF6;
1175
    FORCE_RET();
1176
}
1177

    
1178
void op_mtc0_datalo (void)
1179
{
1180
    env->CP0_DataLo = T0; /* XXX */
1181
    FORCE_RET();
1182
}
1183

    
1184
void op_mtc0_taghi (void)
1185
{
1186
    env->CP0_TagHi = T0; /* XXX */
1187
    FORCE_RET();
1188
}
1189

    
1190
void op_mtc0_datahi (void)
1191
{
1192
    env->CP0_DataHi = T0; /* XXX */
1193
    FORCE_RET();
1194
}
1195

    
1196
void op_mtc0_errorepc (void)
1197
{
1198
    env->CP0_ErrorEPC = T0;
1199
    FORCE_RET();
1200
}
1201

    
1202
void op_mtc0_desave (void)
1203
{
1204
    env->CP0_DESAVE = T0;
1205
    FORCE_RET();
1206
}
1207

    
1208
#if defined(TARGET_MIPS64)
1209
void op_dmfc0_tcrestart (void)
1210
{
1211
    T0 = env->PC[env->current_tc];
1212
    FORCE_RET();
1213
}
1214

    
1215
void op_dmfc0_tchalt (void)
1216
{
1217
    T0 = env->CP0_TCHalt[env->current_tc];
1218
    FORCE_RET();
1219
}
1220

    
1221
void op_dmfc0_tccontext (void)
1222
{
1223
    T0 = env->CP0_TCContext[env->current_tc];
1224
    FORCE_RET();
1225
}
1226

    
1227
void op_dmfc0_tcschedule (void)
1228
{
1229
    T0 = env->CP0_TCSchedule[env->current_tc];
1230
    FORCE_RET();
1231
}
1232

    
1233
void op_dmfc0_tcschefback (void)
1234
{
1235
    T0 = env->CP0_TCScheFBack[env->current_tc];
1236
    FORCE_RET();
1237
}
1238

    
1239
void op_dmfc0_lladdr (void)
1240
{
1241
    T0 = env->CP0_LLAddr >> 4;
1242
    FORCE_RET();
1243
}
1244

    
1245
void op_dmfc0_watchlo (void)
1246
{
1247
    T0 = env->CP0_WatchLo[PARAM1];
1248
    FORCE_RET();
1249
}
1250
#endif /* TARGET_MIPS64 */
1251

    
1252
/* MIPS MT functions */
1253
void op_mftgpr(void)
1254
{
1255
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1256

    
1257
    T0 = env->gpr[other_tc][PARAM1];
1258
    FORCE_RET();
1259
}
1260

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

    
1265
    T0 = env->LO[other_tc][PARAM1];
1266
    FORCE_RET();
1267
}
1268

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

    
1273
    T0 = env->HI[other_tc][PARAM1];
1274
    FORCE_RET();
1275
}
1276

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

    
1281
    T0 = env->ACX[other_tc][PARAM1];
1282
    FORCE_RET();
1283
}
1284

    
1285
void op_mftdsp(void)
1286
{
1287
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1288

    
1289
    T0 = env->DSPControl[other_tc];
1290
    FORCE_RET();
1291
}
1292

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

    
1297
    T0 = env->gpr[other_tc][PARAM1];
1298
    FORCE_RET();
1299
}
1300

    
1301
void op_mttlo(void)
1302
{
1303
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1304

    
1305
    T0 = env->LO[other_tc][PARAM1];
1306
    FORCE_RET();
1307
}
1308

    
1309
void op_mtthi(void)
1310
{
1311
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1312

    
1313
    T0 = env->HI[other_tc][PARAM1];
1314
    FORCE_RET();
1315
}
1316

    
1317
void op_mttacx(void)
1318
{
1319
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1320

    
1321
    T0 = env->ACX[other_tc][PARAM1];
1322
    FORCE_RET();
1323
}
1324

    
1325
void op_mttdsp(void)
1326
{
1327
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1328

    
1329
    T0 = env->DSPControl[other_tc];
1330
    FORCE_RET();
1331
}
1332

    
1333

    
1334
void op_dmt(void)
1335
{
1336
    // TODO
1337
    T0 = 0;
1338
    // rt = T0
1339
    FORCE_RET();
1340
}
1341

    
1342
void op_emt(void)
1343
{
1344
    // TODO
1345
    T0 = 0;
1346
    // rt = T0
1347
    FORCE_RET();
1348
}
1349

    
1350
void op_dvpe(void)
1351
{
1352
    // TODO
1353
    T0 = 0;
1354
    // rt = T0
1355
    FORCE_RET();
1356
}
1357

    
1358
void op_evpe(void)
1359
{
1360
    // TODO
1361
    T0 = 0;
1362
    // rt = T0
1363
    FORCE_RET();
1364
}
1365

    
1366
void op_fork(void)
1367
{
1368
    // T0 = rt, T1 = rs
1369
    T0 = 0;
1370
    // TODO: store to TC register
1371
    FORCE_RET();
1372
}
1373

    
1374
void op_yield(void)
1375
{
1376
    if (T0 < 0) {
1377
        /* No scheduling policy implemented. */
1378
        if (T0 != -2) {
1379
            if (env->CP0_VPEControl & (1 << CP0VPECo_YSI) &&
1380
                env->CP0_TCStatus[env->current_tc] & (1 << CP0TCSt_DT)) {
1381
                env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT);
1382
                env->CP0_VPEControl |= 4 << CP0VPECo_EXCPT;
1383
                CALL_FROM_TB1(do_raise_exception, EXCP_THREAD);
1384
            }
1385
        }
1386
    } else if (T0 == 0) {
1387
        if (0 /* TODO: TC underflow */) {
1388
            env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT);
1389
            CALL_FROM_TB1(do_raise_exception, EXCP_THREAD);
1390
        } else {
1391
            // TODO: Deallocate TC
1392
        }
1393
    } else if (T0 > 0) {
1394
        /* Yield qualifier inputs not implemented. */
1395
        env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT);
1396
        env->CP0_VPEControl |= 2 << CP0VPECo_EXCPT;
1397
        CALL_FROM_TB1(do_raise_exception, EXCP_THREAD);
1398
    }
1399
    T0 = env->CP0_YQMask;
1400
    FORCE_RET();
1401
}
1402

    
1403
/* CP1 functions */
1404
#if 0
1405
# define DEBUG_FPU_STATE() CALL_FROM_TB1(dump_fpu, env)
1406
#else
1407
# define DEBUG_FPU_STATE() do { } while(0)
1408
#endif
1409

    
1410
void op_cfc1 (void)
1411
{
1412
    CALL_FROM_TB1(do_cfc1, PARAM1);
1413
    DEBUG_FPU_STATE();
1414
    FORCE_RET();
1415
}
1416

    
1417
void op_ctc1 (void)
1418
{
1419
    CALL_FROM_TB1(do_ctc1, PARAM1);
1420
    DEBUG_FPU_STATE();
1421
    FORCE_RET();
1422
}
1423

    
1424
void op_mfc1 (void)
1425
{
1426
    T0 = (int32_t)WT0;
1427
    DEBUG_FPU_STATE();
1428
    FORCE_RET();
1429
}
1430

    
1431
void op_mtc1 (void)
1432
{
1433
    WT0 = T0;
1434
    DEBUG_FPU_STATE();
1435
    FORCE_RET();
1436
}
1437

    
1438
void op_dmfc1 (void)
1439
{
1440
    T0 = DT0;
1441
    DEBUG_FPU_STATE();
1442
    FORCE_RET();
1443
}
1444

    
1445
void op_dmtc1 (void)
1446
{
1447
    DT0 = T0;
1448
    DEBUG_FPU_STATE();
1449
    FORCE_RET();
1450
}
1451

    
1452
void op_mfhc1 (void)
1453
{
1454
    T0 = (int32_t)WTH0;
1455
    DEBUG_FPU_STATE();
1456
    FORCE_RET();
1457
}
1458

    
1459
void op_mthc1 (void)
1460
{
1461
    WTH0 = T0;
1462
    DEBUG_FPU_STATE();
1463
    FORCE_RET();
1464
}
1465

    
1466
/* Float support.
1467
   Single precition routines have a "s" suffix, double precision a
1468
   "d" suffix, 32bit integer "w", 64bit integer "l", paired singe "ps",
1469
   paired single lowwer "pl", paired single upper "pu".  */
1470

    
1471
#define FLOAT_OP(name, p) void OPPROTO op_float_##name##_##p(void)
1472

    
1473
FLOAT_OP(cvtd, s)
1474
{
1475
    CALL_FROM_TB0(do_float_cvtd_s);
1476
    DEBUG_FPU_STATE();
1477
    FORCE_RET();
1478
}
1479
FLOAT_OP(cvtd, w)
1480
{
1481
    CALL_FROM_TB0(do_float_cvtd_w);
1482
    DEBUG_FPU_STATE();
1483
    FORCE_RET();
1484
}
1485
FLOAT_OP(cvtd, l)
1486
{
1487
    CALL_FROM_TB0(do_float_cvtd_l);
1488
    DEBUG_FPU_STATE();
1489
    FORCE_RET();
1490
}
1491
FLOAT_OP(cvtl, d)
1492
{
1493
    CALL_FROM_TB0(do_float_cvtl_d);
1494
    DEBUG_FPU_STATE();
1495
    FORCE_RET();
1496
}
1497
FLOAT_OP(cvtl, s)
1498
{
1499
    CALL_FROM_TB0(do_float_cvtl_s);
1500
    DEBUG_FPU_STATE();
1501
    FORCE_RET();
1502
}
1503
FLOAT_OP(cvtps, s)
1504
{
1505
    WT2 = WT0;
1506
    WTH2 = WT1;
1507
    DEBUG_FPU_STATE();
1508
    FORCE_RET();
1509
}
1510
FLOAT_OP(cvtps, pw)
1511
{
1512
    CALL_FROM_TB0(do_float_cvtps_pw);
1513
    DEBUG_FPU_STATE();
1514
    FORCE_RET();
1515
}
1516
FLOAT_OP(cvtpw, ps)
1517
{
1518
    CALL_FROM_TB0(do_float_cvtpw_ps);
1519
    DEBUG_FPU_STATE();
1520
    FORCE_RET();
1521
}
1522
FLOAT_OP(cvts, d)
1523
{
1524
    CALL_FROM_TB0(do_float_cvts_d);
1525
    DEBUG_FPU_STATE();
1526
    FORCE_RET();
1527
}
1528
FLOAT_OP(cvts, w)
1529
{
1530
    CALL_FROM_TB0(do_float_cvts_w);
1531
    DEBUG_FPU_STATE();
1532
    FORCE_RET();
1533
}
1534
FLOAT_OP(cvts, l)
1535
{
1536
    CALL_FROM_TB0(do_float_cvts_l);
1537
    DEBUG_FPU_STATE();
1538
    FORCE_RET();
1539
}
1540
FLOAT_OP(cvts, pl)
1541
{
1542
    CALL_FROM_TB0(do_float_cvts_pl);
1543
    DEBUG_FPU_STATE();
1544
    FORCE_RET();
1545
}
1546
FLOAT_OP(cvts, pu)
1547
{
1548
    CALL_FROM_TB0(do_float_cvts_pu);
1549
    DEBUG_FPU_STATE();
1550
    FORCE_RET();
1551
}
1552
FLOAT_OP(cvtw, s)
1553
{
1554
    CALL_FROM_TB0(do_float_cvtw_s);
1555
    DEBUG_FPU_STATE();
1556
    FORCE_RET();
1557
}
1558
FLOAT_OP(cvtw, d)
1559
{
1560
    CALL_FROM_TB0(do_float_cvtw_d);
1561
    DEBUG_FPU_STATE();
1562
    FORCE_RET();
1563
}
1564

    
1565
FLOAT_OP(pll, ps)
1566
{
1567
    DT2 = ((uint64_t)WT0 << 32) | WT1;
1568
    DEBUG_FPU_STATE();
1569
    FORCE_RET();
1570
}
1571
FLOAT_OP(plu, ps)
1572
{
1573
    DT2 = ((uint64_t)WT0 << 32) | WTH1;
1574
    DEBUG_FPU_STATE();
1575
    FORCE_RET();
1576
}
1577
FLOAT_OP(pul, ps)
1578
{
1579
    DT2 = ((uint64_t)WTH0 << 32) | WT1;
1580
    DEBUG_FPU_STATE();
1581
    FORCE_RET();
1582
}
1583
FLOAT_OP(puu, ps)
1584
{
1585
    DT2 = ((uint64_t)WTH0 << 32) | WTH1;
1586
    DEBUG_FPU_STATE();
1587
    FORCE_RET();
1588
}
1589

    
1590
#define FLOAT_ROUNDOP(op, ttype, stype)                    \
1591
FLOAT_OP(op ## ttype, stype)                               \
1592
{                                                          \
1593
    CALL_FROM_TB0(do_float_ ## op ## ttype ## _ ## stype); \
1594
    DEBUG_FPU_STATE();                                     \
1595
    FORCE_RET();                                           \
1596
}
1597

    
1598
FLOAT_ROUNDOP(round, l, d)
1599
FLOAT_ROUNDOP(round, l, s)
1600
FLOAT_ROUNDOP(round, w, d)
1601
FLOAT_ROUNDOP(round, w, s)
1602

    
1603
FLOAT_ROUNDOP(trunc, l, d)
1604
FLOAT_ROUNDOP(trunc, l, s)
1605
FLOAT_ROUNDOP(trunc, w, d)
1606
FLOAT_ROUNDOP(trunc, w, s)
1607

    
1608
FLOAT_ROUNDOP(ceil, l, d)
1609
FLOAT_ROUNDOP(ceil, l, s)
1610
FLOAT_ROUNDOP(ceil, w, d)
1611
FLOAT_ROUNDOP(ceil, w, s)
1612

    
1613
FLOAT_ROUNDOP(floor, l, d)
1614
FLOAT_ROUNDOP(floor, l, s)
1615
FLOAT_ROUNDOP(floor, w, d)
1616
FLOAT_ROUNDOP(floor, w, s)
1617
#undef FLOAR_ROUNDOP
1618

    
1619
FLOAT_OP(movf, d)
1620
{
1621
    if (!(env->fpu->fcr31 & PARAM1))
1622
        DT2 = DT0;
1623
    DEBUG_FPU_STATE();
1624
    FORCE_RET();
1625
}
1626
FLOAT_OP(movf, s)
1627
{
1628
    if (!(env->fpu->fcr31 & PARAM1))
1629
        WT2 = WT0;
1630
    DEBUG_FPU_STATE();
1631
    FORCE_RET();
1632
}
1633
FLOAT_OP(movf, ps)
1634
{
1635
    unsigned int mask = GET_FP_COND (env->fpu) >> PARAM1;
1636
    if (!(mask & 1))
1637
        WT2 = WT0;
1638
    if (!(mask & 2))
1639
        WTH2 = WTH0;
1640
    DEBUG_FPU_STATE();
1641
    FORCE_RET();
1642
}
1643
FLOAT_OP(movt, d)
1644
{
1645
    if (env->fpu->fcr31 & PARAM1)
1646
        DT2 = DT0;
1647
    DEBUG_FPU_STATE();
1648
    FORCE_RET();
1649
}
1650
FLOAT_OP(movt, s)
1651
{
1652
    if (env->fpu->fcr31 & PARAM1)
1653
        WT2 = WT0;
1654
    DEBUG_FPU_STATE();
1655
    FORCE_RET();
1656
}
1657
FLOAT_OP(movt, ps)
1658
{
1659
    unsigned int mask = GET_FP_COND (env->fpu) >> PARAM1;
1660
    if (mask & 1)
1661
        WT2 = WT0;
1662
    if (mask & 2)
1663
        WTH2 = WTH0;
1664
    DEBUG_FPU_STATE();
1665
    FORCE_RET();
1666
}
1667
FLOAT_OP(movz, d)
1668
{
1669
    if (!T0)
1670
        DT2 = DT0;
1671
    DEBUG_FPU_STATE();
1672
    FORCE_RET();
1673
}
1674
FLOAT_OP(movz, s)
1675
{
1676
    if (!T0)
1677
        WT2 = WT0;
1678
    DEBUG_FPU_STATE();
1679
    FORCE_RET();
1680
}
1681
FLOAT_OP(movz, ps)
1682
{
1683
    if (!T0) {
1684
        WT2 = WT0;
1685
        WTH2 = WTH0;
1686
    }
1687
    DEBUG_FPU_STATE();
1688
    FORCE_RET();
1689
}
1690
FLOAT_OP(movn, d)
1691
{
1692
    if (T0)
1693
        DT2 = DT0;
1694
    DEBUG_FPU_STATE();
1695
    FORCE_RET();
1696
}
1697
FLOAT_OP(movn, s)
1698
{
1699
    if (T0)
1700
        WT2 = WT0;
1701
    DEBUG_FPU_STATE();
1702
    FORCE_RET();
1703
}
1704
FLOAT_OP(movn, ps)
1705
{
1706
    if (T0) {
1707
        WT2 = WT0;
1708
        WTH2 = WTH0;
1709
    }
1710
    DEBUG_FPU_STATE();
1711
    FORCE_RET();
1712
}
1713

    
1714
/* operations calling helpers, for s, d and ps */
1715
#define FLOAT_HOP(name)   \
1716
FLOAT_OP(name, d)         \
1717
{                         \
1718
    CALL_FROM_TB0(do_float_ ## name ## _d);  \
1719
    DEBUG_FPU_STATE();    \
1720
    FORCE_RET();          \
1721
}                         \
1722
FLOAT_OP(name, s)         \
1723
{                         \
1724
    CALL_FROM_TB0(do_float_ ## name ## _s);  \
1725
    DEBUG_FPU_STATE();    \
1726
    FORCE_RET();          \
1727
}                         \
1728
FLOAT_OP(name, ps)        \
1729
{                         \
1730
    CALL_FROM_TB0(do_float_ ## name ## _ps); \
1731
    DEBUG_FPU_STATE();    \
1732
    FORCE_RET();          \
1733
}
1734
FLOAT_HOP(add)
1735
FLOAT_HOP(sub)
1736
FLOAT_HOP(mul)
1737
FLOAT_HOP(div)
1738
FLOAT_HOP(recip2)
1739
FLOAT_HOP(rsqrt2)
1740
FLOAT_HOP(rsqrt1)
1741
FLOAT_HOP(recip1)
1742
#undef FLOAT_HOP
1743

    
1744
/* operations calling helpers, for s and d */
1745
#define FLOAT_HOP(name)   \
1746
FLOAT_OP(name, d)         \
1747
{                         \
1748
    CALL_FROM_TB0(do_float_ ## name ## _d);  \
1749
    DEBUG_FPU_STATE();    \
1750
    FORCE_RET();          \
1751
}                         \
1752
FLOAT_OP(name, s)         \
1753
{                         \
1754
    CALL_FROM_TB0(do_float_ ## name ## _s);  \
1755
    DEBUG_FPU_STATE();    \
1756
    FORCE_RET();          \
1757
}
1758
FLOAT_HOP(rsqrt)
1759
FLOAT_HOP(recip)
1760
#undef FLOAT_HOP
1761

    
1762
/* operations calling helpers, for ps */
1763
#define FLOAT_HOP(name)   \
1764
FLOAT_OP(name, ps)        \
1765
{                         \
1766
    CALL_FROM_TB0(do_float_ ## name ## _ps); \
1767
    DEBUG_FPU_STATE();    \
1768
    FORCE_RET();          \
1769
}
1770
FLOAT_HOP(addr)
1771
FLOAT_HOP(mulr)
1772
#undef FLOAT_HOP
1773

    
1774
/* ternary operations */
1775
#define FLOAT_TERNOP(name1, name2) \
1776
FLOAT_OP(name1 ## name2, d)        \
1777
{                                  \
1778
    FDT0 = float64_ ## name1 (FDT0, FDT1, &env->fpu->fp_status);    \
1779
    FDT2 = float64_ ## name2 (FDT0, FDT2, &env->fpu->fp_status);    \
1780
    DEBUG_FPU_STATE();             \
1781
    FORCE_RET();                   \
1782
}                                  \
1783
FLOAT_OP(name1 ## name2, s)        \
1784
{                                  \
1785
    FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status);    \
1786
    FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status);    \
1787
    DEBUG_FPU_STATE();             \
1788
    FORCE_RET();                   \
1789
}                                  \
1790
FLOAT_OP(name1 ## name2, ps)       \
1791
{                                  \
1792
    FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status);    \
1793
    FSTH0 = float32_ ## name1 (FSTH0, FSTH1, &env->fpu->fp_status); \
1794
    FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status);    \
1795
    FSTH2 = float32_ ## name2 (FSTH0, FSTH2, &env->fpu->fp_status); \
1796
    DEBUG_FPU_STATE();             \
1797
    FORCE_RET();                   \
1798
}
1799
FLOAT_TERNOP(mul, add)
1800
FLOAT_TERNOP(mul, sub)
1801
#undef FLOAT_TERNOP
1802

    
1803
/* negated ternary operations */
1804
#define FLOAT_NTERNOP(name1, name2) \
1805
FLOAT_OP(n ## name1 ## name2, d)    \
1806
{                                   \
1807
    FDT0 = float64_ ## name1 (FDT0, FDT1, &env->fpu->fp_status);    \
1808
    FDT2 = float64_ ## name2 (FDT0, FDT2, &env->fpu->fp_status);    \
1809
    FDT2 = float64_chs(FDT2);       \
1810
    DEBUG_FPU_STATE();              \
1811
    FORCE_RET();                    \
1812
}                                   \
1813
FLOAT_OP(n ## name1 ## name2, s)    \
1814
{                                   \
1815
    FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status);    \
1816
    FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status);    \
1817
    FST2 = float32_chs(FST2);       \
1818
    DEBUG_FPU_STATE();              \
1819
    FORCE_RET();                    \
1820
}                                   \
1821
FLOAT_OP(n ## name1 ## name2, ps)   \
1822
{                                   \
1823
    FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status);    \
1824
    FSTH0 = float32_ ## name1 (FSTH0, FSTH1, &env->fpu->fp_status); \
1825
    FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status);    \
1826
    FSTH2 = float32_ ## name2 (FSTH0, FSTH2, &env->fpu->fp_status); \
1827
    FST2 = float32_chs(FST2);       \
1828
    FSTH2 = float32_chs(FSTH2);     \
1829
    DEBUG_FPU_STATE();              \
1830
    FORCE_RET();                    \
1831
}
1832
FLOAT_NTERNOP(mul, add)
1833
FLOAT_NTERNOP(mul, sub)
1834
#undef FLOAT_NTERNOP
1835

    
1836
/* unary operations, modifying fp status  */
1837
#define FLOAT_UNOP(name)  \
1838
FLOAT_OP(name, d)         \
1839
{                         \
1840
    FDT2 = float64_ ## name(FDT0, &env->fpu->fp_status); \
1841
    DEBUG_FPU_STATE();    \
1842
    FORCE_RET();          \
1843
}                         \
1844
FLOAT_OP(name, s)         \
1845
{                         \
1846
    FST2 = float32_ ## name(FST0, &env->fpu->fp_status); \
1847
    DEBUG_FPU_STATE();    \
1848
    FORCE_RET();          \
1849
}
1850
FLOAT_UNOP(sqrt)
1851
#undef FLOAT_UNOP
1852

    
1853
/* unary operations, not modifying fp status  */
1854
#define FLOAT_UNOP(name)  \
1855
FLOAT_OP(name, d)         \
1856
{                         \
1857
    FDT2 = float64_ ## name(FDT0);   \
1858
    DEBUG_FPU_STATE();    \
1859
    FORCE_RET();          \
1860
}                         \
1861
FLOAT_OP(name, s)         \
1862
{                         \
1863
    FST2 = float32_ ## name(FST0);   \
1864
    DEBUG_FPU_STATE();    \
1865
    FORCE_RET();          \
1866
}                         \
1867
FLOAT_OP(name, ps)        \
1868
{                         \
1869
    FST2 = float32_ ## name(FST0);   \
1870
    FSTH2 = float32_ ## name(FSTH0); \
1871
    DEBUG_FPU_STATE();    \
1872
    FORCE_RET();          \
1873
}
1874
FLOAT_UNOP(abs)
1875
FLOAT_UNOP(chs)
1876
#undef FLOAT_UNOP
1877

    
1878
FLOAT_OP(mov, d)
1879
{
1880
    FDT2 = FDT0;
1881
    DEBUG_FPU_STATE();
1882
    FORCE_RET();
1883
}
1884
FLOAT_OP(mov, s)
1885
{
1886
    FST2 = FST0;
1887
    DEBUG_FPU_STATE();
1888
    FORCE_RET();
1889
}
1890
FLOAT_OP(mov, ps)
1891
{
1892
    FST2 = FST0;
1893
    FSTH2 = FSTH0;
1894
    DEBUG_FPU_STATE();
1895
    FORCE_RET();
1896
}
1897
FLOAT_OP(alnv, ps)
1898
{
1899
    switch (T0 & 0x7) {
1900
    case 0:
1901
        FST2 = FST0;
1902
        FSTH2 = FSTH0;
1903
        break;
1904
    case 4:
1905
#ifdef TARGET_WORDS_BIGENDIAN
1906
        FSTH2 = FST0;
1907
        FST2 = FSTH1;
1908
#else
1909
        FSTH2 = FST1;
1910
        FST2 = FSTH0;
1911
#endif
1912
        break;
1913
    default: /* unpredictable */
1914
        break;
1915
    }
1916
    DEBUG_FPU_STATE();
1917
    FORCE_RET();
1918
}
1919

    
1920
#ifdef CONFIG_SOFTFLOAT
1921
#define clear_invalid() do {                                \
1922
    int flags = get_float_exception_flags(&env->fpu->fp_status); \
1923
    flags &= ~float_flag_invalid;                           \
1924
    set_float_exception_flags(flags, &env->fpu->fp_status); \
1925
} while(0)
1926
#else
1927
#define clear_invalid() do { } while(0)
1928
#endif
1929

    
1930
extern void dump_fpu_s(CPUState *env);
1931

    
1932
#define CMP_OP(fmt, op)                                \
1933
void OPPROTO op_cmp ## _ ## fmt ## _ ## op(void)       \
1934
{                                                      \
1935
    CALL_FROM_TB1(do_cmp ## _ ## fmt ## _ ## op, PARAM1); \
1936
    DEBUG_FPU_STATE();                                 \
1937
    FORCE_RET();                                       \
1938
}                                                      \
1939
void OPPROTO op_cmpabs ## _ ## fmt ## _ ## op(void)    \
1940
{                                                      \
1941
    CALL_FROM_TB1(do_cmpabs ## _ ## fmt ## _ ## op, PARAM1); \
1942
    DEBUG_FPU_STATE();                                 \
1943
    FORCE_RET();                                       \
1944
}
1945
#define CMP_OPS(op)   \
1946
CMP_OP(d, op)         \
1947
CMP_OP(s, op)         \
1948
CMP_OP(ps, op)
1949

    
1950
CMP_OPS(f)
1951
CMP_OPS(un)
1952
CMP_OPS(eq)
1953
CMP_OPS(ueq)
1954
CMP_OPS(olt)
1955
CMP_OPS(ult)
1956
CMP_OPS(ole)
1957
CMP_OPS(ule)
1958
CMP_OPS(sf)
1959
CMP_OPS(ngle)
1960
CMP_OPS(seq)
1961
CMP_OPS(ngl)
1962
CMP_OPS(lt)
1963
CMP_OPS(nge)
1964
CMP_OPS(le)
1965
CMP_OPS(ngt)
1966
#undef CMP_OPS
1967
#undef CMP_OP
1968

    
1969
void op_bc1f (void)
1970
{
1971
    T0 = !!(~GET_FP_COND(env->fpu) & (0x1 << PARAM1));
1972
    DEBUG_FPU_STATE();
1973
    FORCE_RET();
1974
}
1975
void op_bc1any2f (void)
1976
{
1977
    T0 = !!(~GET_FP_COND(env->fpu) & (0x3 << PARAM1));
1978
    DEBUG_FPU_STATE();
1979
    FORCE_RET();
1980
}
1981
void op_bc1any4f (void)
1982
{
1983
    T0 = !!(~GET_FP_COND(env->fpu) & (0xf << PARAM1));
1984
    DEBUG_FPU_STATE();
1985
    FORCE_RET();
1986
}
1987

    
1988
void op_bc1t (void)
1989
{
1990
    T0 = !!(GET_FP_COND(env->fpu) & (0x1 << PARAM1));
1991
    DEBUG_FPU_STATE();
1992
    FORCE_RET();
1993
}
1994
void op_bc1any2t (void)
1995
{
1996
    T0 = !!(GET_FP_COND(env->fpu) & (0x3 << PARAM1));
1997
    DEBUG_FPU_STATE();
1998
    FORCE_RET();
1999
}
2000
void op_bc1any4t (void)
2001
{
2002
    T0 = !!(GET_FP_COND(env->fpu) & (0xf << PARAM1));
2003
    DEBUG_FPU_STATE();
2004
    FORCE_RET();
2005
}
2006

    
2007
void op_tlbwi (void)
2008
{
2009
    CALL_FROM_TB0(env->tlb->do_tlbwi);
2010
    FORCE_RET();
2011
}
2012

    
2013
void op_tlbwr (void)
2014
{
2015
    CALL_FROM_TB0(env->tlb->do_tlbwr);
2016
    FORCE_RET();
2017
}
2018

    
2019
void op_tlbp (void)
2020
{
2021
    CALL_FROM_TB0(env->tlb->do_tlbp);
2022
    FORCE_RET();
2023
}
2024

    
2025
void op_tlbr (void)
2026
{
2027
    CALL_FROM_TB0(env->tlb->do_tlbr);
2028
    FORCE_RET();
2029
}
2030

    
2031
/* Specials */
2032
#if defined (CONFIG_USER_ONLY)
2033
void op_tls_value (void)
2034
{
2035
    T0 = env->tls_value;
2036
}
2037
#endif
2038

    
2039
void op_pmon (void)
2040
{
2041
    CALL_FROM_TB1(do_pmon, PARAM1);
2042
    FORCE_RET();
2043
}
2044

    
2045
void op_di (void)
2046
{
2047
    T0 = env->CP0_Status;
2048
    env->CP0_Status = T0 & ~(1 << CP0St_IE);
2049
    CALL_FROM_TB1(cpu_mips_update_irq, env);
2050
    FORCE_RET();
2051
}
2052

    
2053
void op_ei (void)
2054
{
2055
    T0 = env->CP0_Status;
2056
    env->CP0_Status = T0 | (1 << CP0St_IE);
2057
    CALL_FROM_TB1(cpu_mips_update_irq, env);
2058
    FORCE_RET();
2059
}
2060

    
2061
void op_trap (void)
2062
{
2063
    if (T0) {
2064
        CALL_FROM_TB1(do_raise_exception, EXCP_TRAP);
2065
    }
2066
    FORCE_RET();
2067
}
2068

    
2069
void op_debug (void)
2070
{
2071
    CALL_FROM_TB1(do_raise_exception, EXCP_DEBUG);
2072
    FORCE_RET();
2073
}
2074

    
2075
void debug_pre_eret (void);
2076
void debug_post_eret (void);
2077
void op_eret (void)
2078
{
2079
    if (loglevel & CPU_LOG_EXEC)
2080
        CALL_FROM_TB0(debug_pre_eret);
2081
    if (env->CP0_Status & (1 << CP0St_ERL)) {
2082
        env->PC[env->current_tc] = env->CP0_ErrorEPC;
2083
        env->CP0_Status &= ~(1 << CP0St_ERL);
2084
    } else {
2085
        env->PC[env->current_tc] = env->CP0_EPC;
2086
        env->CP0_Status &= ~(1 << CP0St_EXL);
2087
    }
2088
    CALL_FROM_TB1(compute_hflags, env);
2089
    if (loglevel & CPU_LOG_EXEC)
2090
        CALL_FROM_TB0(debug_post_eret);
2091
    env->CP0_LLAddr = 1;
2092
    FORCE_RET();
2093
}
2094

    
2095
void op_deret (void)
2096
{
2097
    if (loglevel & CPU_LOG_EXEC)
2098
        CALL_FROM_TB0(debug_pre_eret);
2099
    env->PC[env->current_tc] = env->CP0_DEPC;
2100
    env->hflags &= MIPS_HFLAG_DM;
2101
    CALL_FROM_TB1(compute_hflags, env);
2102
    if (loglevel & CPU_LOG_EXEC)
2103
        CALL_FROM_TB0(debug_post_eret);
2104
    env->CP0_LLAddr = 1;
2105
    FORCE_RET();
2106
}
2107

    
2108
void op_rdhwr_cpunum(void)
2109
{
2110
    if ((env->hflags & MIPS_HFLAG_CP0) ||
2111
        (env->CP0_HWREna & (1 << 0)))
2112
        T0 = env->CP0_EBase & 0x3ff;
2113
    else
2114
        CALL_FROM_TB1(do_raise_exception, EXCP_RI);
2115
    FORCE_RET();
2116
}
2117

    
2118
void op_rdhwr_synci_step(void)
2119
{
2120
    if ((env->hflags & MIPS_HFLAG_CP0) ||
2121
        (env->CP0_HWREna & (1 << 1)))
2122
        T0 = env->SYNCI_Step;
2123
    else
2124
        CALL_FROM_TB1(do_raise_exception, EXCP_RI);
2125
    FORCE_RET();
2126
}
2127

    
2128
void op_rdhwr_cc(void)
2129
{
2130
    if ((env->hflags & MIPS_HFLAG_CP0) ||
2131
        (env->CP0_HWREna & (1 << 2)))
2132
        T0 = env->CP0_Count;
2133
    else
2134
        CALL_FROM_TB1(do_raise_exception, EXCP_RI);
2135
    FORCE_RET();
2136
}
2137

    
2138
void op_rdhwr_ccres(void)
2139
{
2140
    if ((env->hflags & MIPS_HFLAG_CP0) ||
2141
        (env->CP0_HWREna & (1 << 3)))
2142
        T0 = env->CCRes;
2143
    else
2144
        CALL_FROM_TB1(do_raise_exception, EXCP_RI);
2145
    FORCE_RET();
2146
}
2147

    
2148
void op_save_state (void)
2149
{
2150
    env->hflags = PARAM1;
2151
    FORCE_RET();
2152
}
2153

    
2154
void op_wait (void)
2155
{
2156
    env->halted = 1;
2157
    CALL_FROM_TB1(do_raise_exception, EXCP_HLT);
2158
    FORCE_RET();
2159
}
2160

    
2161
/* Bitfield operations. */
2162
void op_ext(void)
2163
{
2164
    unsigned int pos = PARAM1;
2165
    unsigned int size = PARAM2;
2166

    
2167
    T0 = (int32_t)((T1 >> pos) & ((size < 32) ? ((1 << size) - 1) : ~0));
2168
    FORCE_RET();
2169
}
2170

    
2171
void op_ins(void)
2172
{
2173
    unsigned int pos = PARAM1;
2174
    unsigned int size = PARAM2;
2175
    target_ulong mask = ((size < 32) ? ((1 << size) - 1) : ~0) << pos;
2176

    
2177
    T0 = (int32_t)((T0 & ~mask) | ((T1 << pos) & mask));
2178
    FORCE_RET();
2179
}
2180

    
2181
void op_wsbh(void)
2182
{
2183
    T0 = (int32_t)(((T1 << 8) & ~0x00FF00FF) | ((T1 >> 8) & 0x00FF00FF));
2184
    FORCE_RET();
2185
}
2186

    
2187
#if defined(TARGET_MIPS64)
2188
void op_dext(void)
2189
{
2190
    unsigned int pos = PARAM1;
2191
    unsigned int size = PARAM2;
2192

    
2193
    T0 = (T1 >> pos) & ((size < 64) ? ((1ULL << size) - 1) : ~0ULL);
2194
    FORCE_RET();
2195
}
2196

    
2197
void op_dins(void)
2198
{
2199
    unsigned int pos = PARAM1;
2200
    unsigned int size = PARAM2;
2201
    target_ulong mask = ((size < 64) ? ((1ULL << size) - 1) : ~0ULL) << pos;
2202

    
2203
    T0 = (T0 & ~mask) | ((T1 << pos) & mask);
2204
    FORCE_RET();
2205
}
2206

    
2207
void op_dsbh(void)
2208
{
2209
    T0 = ((T1 << 8) & ~0x00FF00FF00FF00FFULL) | ((T1 >> 8) & 0x00FF00FF00FF00FFULL);
2210
    FORCE_RET();
2211
}
2212

    
2213
void op_dshd(void)
2214
{
2215
    T1 = ((T1 << 16) & ~0x0000FFFF0000FFFFULL) | ((T1 >> 16) & 0x0000FFFF0000FFFFULL);
2216
    T0 = (T1 << 32) | (T1 >> 32);
2217
    FORCE_RET();
2218
}
2219
#endif