Statistics
| Branch: | Revision:

root / target-ppc / op.c @ cfdcd37a

History | View | Annotate | Download (46.6 kB)

1
/*
2
 *  PowerPC emulation micro-operations for qemu.
3
 *
4
 *  Copyright (c) 2003-2007 Jocelyn Mayer
5
 *
6
 * This library is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Lesser General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2 of the License, or (at your option) any later version.
10
 *
11
 * This library is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with this library; if not, write to the Free Software
18
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 */
20

    
21
//#define DEBUG_OP
22

    
23
#include "config.h"
24
#include "exec.h"
25
#include "host-utils.h"
26
#include "helper_regs.h"
27
#include "op_helper.h"
28

    
29
void OPPROTO op_print_mem_EA (void)
30
{
31
    do_print_mem_EA(T0);
32
    RETURN();
33
}
34

    
35
/* PowerPC state maintenance operations */
36
/* set_Rc0 */
37
void OPPROTO op_set_Rc0 (void)
38
{
39
    env->crf[0] = T0 | xer_so;
40
    RETURN();
41
}
42

    
43
/* Generate exceptions */
44
void OPPROTO op_raise_exception_err (void)
45
{
46
    do_raise_exception_err(PARAM1, PARAM2);
47
}
48

    
49
void OPPROTO op_debug (void)
50
{
51
    do_raise_exception(EXCP_DEBUG);
52
}
53

    
54
/* Load/store special registers */
55
void OPPROTO op_load_cr (void)
56
{
57
    do_load_cr();
58
    RETURN();
59
}
60

    
61
void OPPROTO op_store_cr (void)
62
{
63
    do_store_cr(PARAM1);
64
    RETURN();
65
}
66

    
67
void OPPROTO op_load_xer_cr (void)
68
{
69
    T0 = (xer_so << 3) | (xer_ov << 2) | (xer_ca << 1);
70
    RETURN();
71
}
72

    
73
void OPPROTO op_clear_xer_ov (void)
74
{
75
    xer_so = 0;
76
    xer_ov = 0;
77
    RETURN();
78
}
79

    
80
void OPPROTO op_clear_xer_ca (void)
81
{
82
    xer_ca = 0;
83
    RETURN();
84
}
85

    
86
void OPPROTO op_load_xer_bc (void)
87
{
88
    T1 = xer_bc;
89
    RETURN();
90
}
91

    
92
void OPPROTO op_store_xer_bc (void)
93
{
94
    xer_bc = T0;
95
    RETURN();
96
}
97

    
98
void OPPROTO op_load_xer (void)
99
{
100
    T0 = hreg_load_xer(env);
101
    RETURN();
102
}
103

    
104
void OPPROTO op_store_xer (void)
105
{
106
    hreg_store_xer(env, T0);
107
    RETURN();
108
}
109

    
110
#if defined(TARGET_PPC64)
111
void OPPROTO op_store_pri (void)
112
{
113
    do_store_pri(PARAM1);
114
    RETURN();
115
}
116
#endif
117

    
118
#if !defined(CONFIG_USER_ONLY)
119
/* Segment registers load and store */
120
void OPPROTO op_load_sr (void)
121
{
122
    T0 = env->sr[T1];
123
    RETURN();
124
}
125

    
126
void OPPROTO op_store_sr (void)
127
{
128
    do_store_sr(env, T1, T0);
129
    RETURN();
130
}
131

    
132
#if defined(TARGET_PPC64)
133
void OPPROTO op_load_slb (void)
134
{
135
    T0 = ppc_load_slb(env, T1);
136
    RETURN();
137
}
138

    
139
void OPPROTO op_store_slb (void)
140
{
141
    ppc_store_slb(env, T1, T0);
142
    RETURN();
143
}
144
#endif /* defined(TARGET_PPC64) */
145

    
146
void OPPROTO op_load_sdr1 (void)
147
{
148
    T0 = env->sdr1;
149
    RETURN();
150
}
151

    
152
void OPPROTO op_store_sdr1 (void)
153
{
154
    do_store_sdr1(env, T0);
155
    RETURN();
156
}
157

    
158
#if defined (TARGET_PPC64)
159
void OPPROTO op_load_asr (void)
160
{
161
    T0 = env->asr;
162
    RETURN();
163
}
164

    
165
void OPPROTO op_store_asr (void)
166
{
167
    ppc_store_asr(env, T0);
168
    RETURN();
169
}
170
#endif
171

    
172
void OPPROTO op_load_msr (void)
173
{
174
    T0 = env->msr;
175
    RETURN();
176
}
177

    
178
void OPPROTO op_store_msr (void)
179
{
180
    do_store_msr();
181
    RETURN();
182
}
183

    
184
#if defined (TARGET_PPC64)
185
void OPPROTO op_store_msr_32 (void)
186
{
187
    T0 = (env->msr & ~0xFFFFFFFFULL) | (T0 & 0xFFFFFFFF);
188
    do_store_msr();
189
    RETURN();
190
}
191
#endif
192

    
193
void OPPROTO op_update_riee (void)
194
{
195
    /* We don't call do_store_msr here as we won't trigger
196
     * any special case nor change hflags
197
     */
198
    T0 &= (1 << MSR_RI) | (1 << MSR_EE);
199
    env->msr &= ~(1 << MSR_RI) | (1 << MSR_EE);
200
    env->msr |= T0;
201
    RETURN();
202
}
203
#endif
204

    
205
/* SPR */
206
void OPPROTO op_load_spr (void)
207
{
208
    T0 = env->spr[PARAM1];
209
    RETURN();
210
}
211

    
212
void OPPROTO op_store_spr (void)
213
{
214
    env->spr[PARAM1] = T0;
215
    RETURN();
216
}
217

    
218
void OPPROTO op_load_dump_spr (void)
219
{
220
    T0 = ppc_load_dump_spr(PARAM1);
221
    RETURN();
222
}
223

    
224
void OPPROTO op_store_dump_spr (void)
225
{
226
    ppc_store_dump_spr(PARAM1, T0);
227
    RETURN();
228
}
229

    
230
void OPPROTO op_mask_spr (void)
231
{
232
    env->spr[PARAM1] &= ~T0;
233
    RETURN();
234
}
235

    
236
void OPPROTO op_load_tbl (void)
237
{
238
    T0 = cpu_ppc_load_tbl(env);
239
    RETURN();
240
}
241

    
242
void OPPROTO op_load_tbu (void)
243
{
244
    T0 = cpu_ppc_load_tbu(env);
245
    RETURN();
246
}
247

    
248
void OPPROTO op_load_atbl (void)
249
{
250
    T0 = cpu_ppc_load_atbl(env);
251
    RETURN();
252
}
253

    
254
void OPPROTO op_load_atbu (void)
255
{
256
    T0 = cpu_ppc_load_atbu(env);
257
    RETURN();
258
}
259

    
260
#if !defined(CONFIG_USER_ONLY)
261
void OPPROTO op_store_tbl (void)
262
{
263
    cpu_ppc_store_tbl(env, T0);
264
    RETURN();
265
}
266

    
267
void OPPROTO op_store_tbu (void)
268
{
269
    cpu_ppc_store_tbu(env, T0);
270
    RETURN();
271
}
272

    
273
void OPPROTO op_store_atbl (void)
274
{
275
    cpu_ppc_store_atbl(env, T0);
276
    RETURN();
277
}
278

    
279
void OPPROTO op_store_atbu (void)
280
{
281
    cpu_ppc_store_atbu(env, T0);
282
    RETURN();
283
}
284

    
285
void OPPROTO op_load_decr (void)
286
{
287
    T0 = cpu_ppc_load_decr(env);
288
    RETURN();
289
}
290

    
291
void OPPROTO op_store_decr (void)
292
{
293
    cpu_ppc_store_decr(env, T0);
294
    RETURN();
295
}
296

    
297
void OPPROTO op_load_ibat (void)
298
{
299
    T0 = env->IBAT[PARAM1][PARAM2];
300
    RETURN();
301
}
302

    
303
void OPPROTO op_store_ibatu (void)
304
{
305
    do_store_ibatu(env, PARAM1, T0);
306
    RETURN();
307
}
308

    
309
void OPPROTO op_store_ibatl (void)
310
{
311
#if 1
312
    env->IBAT[1][PARAM1] = T0;
313
#else
314
    do_store_ibatl(env, PARAM1, T0);
315
#endif
316
    RETURN();
317
}
318

    
319
void OPPROTO op_load_dbat (void)
320
{
321
    T0 = env->DBAT[PARAM1][PARAM2];
322
    RETURN();
323
}
324

    
325
void OPPROTO op_store_dbatu (void)
326
{
327
    do_store_dbatu(env, PARAM1, T0);
328
    RETURN();
329
}
330

    
331
void OPPROTO op_store_dbatl (void)
332
{
333
#if 1
334
    env->DBAT[1][PARAM1] = T0;
335
#else
336
    do_store_dbatl(env, PARAM1, T0);
337
#endif
338
    RETURN();
339
}
340
#endif /* !defined(CONFIG_USER_ONLY) */
341

    
342
/* FPSCR */
343
#ifdef CONFIG_SOFTFLOAT
344
void OPPROTO op_reset_fpstatus (void)
345
{
346
    env->fp_status.float_exception_flags = 0;
347
    RETURN();
348
}
349
#endif
350

    
351
void OPPROTO op_compute_fprf (void)
352
{
353
    do_compute_fprf(PARAM1);
354
    RETURN();
355
}
356

    
357
#ifdef CONFIG_SOFTFLOAT
358
void OPPROTO op_float_check_status (void)
359
{
360
    do_float_check_status();
361
    RETURN();
362
}
363
#else
364
void OPPROTO op_float_check_status (void)
365
{
366
    if (env->exception_index == POWERPC_EXCP_PROGRAM &&
367
        (env->error_code & POWERPC_EXCP_FP)) {
368
        /* Differred floating-point exception after target FPR update */
369
        if (msr_fe0 != 0 || msr_fe1 != 0)
370
            do_raise_exception_err(env->exception_index, env->error_code);
371
    }
372
    RETURN();
373
}
374
#endif
375

    
376
void OPPROTO op_load_fpscr_FT0 (void)
377
{
378
    /* The 32 MSB of the target fpr are undefined.
379
     * They'll be zero...
380
     */
381
    CPU_DoubleU u;
382

    
383
    u.l.upper = 0;
384
    u.l.lower = env->fpscr;
385
    FT0 = u.d;
386
    RETURN();
387
}
388

    
389
void OPPROTO op_load_fpscr_T0 (void)
390
{
391
    T0 = (env->fpscr >> PARAM1) & 0xF;
392
    RETURN();
393
}
394

    
395
void OPPROTO op_load_fpcc (void)
396
{
397
    T0 = fpscr_fpcc;
398
    RETURN();
399
}
400

    
401
void OPPROTO op_fpscr_resetbit (void)
402
{
403
    env->fpscr &= PARAM1;
404
    RETURN();
405
}
406

    
407
void OPPROTO op_fpscr_setbit (void)
408
{
409
    do_fpscr_setbit(PARAM1);
410
    RETURN();
411
}
412

    
413
void OPPROTO op_store_fpscr (void)
414
{
415
    do_store_fpscr(PARAM1);
416
    RETURN();
417
}
418

    
419
/* Branch */
420
void OPPROTO op_setlr (void)
421
{
422
    env->lr = (uint32_t)PARAM1;
423
    RETURN();
424
}
425

    
426
#if defined (TARGET_PPC64)
427
void OPPROTO op_setlr_64 (void)
428
{
429
    env->lr = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
430
    RETURN();
431
}
432
#endif
433

    
434
void OPPROTO op_jz_T0 (void)
435
{
436
    if (!T0)
437
        GOTO_LABEL_PARAM(1);
438
    RETURN();
439
}
440

    
441
void OPPROTO op_btest_T1 (void)
442
{
443
    if (T0) {
444
        env->nip = (uint32_t)(T1 & ~3);
445
    } else {
446
        env->nip = (uint32_t)PARAM1;
447
    }
448
    RETURN();
449
}
450

    
451
#if defined (TARGET_PPC64)
452
void OPPROTO op_btest_T1_64 (void)
453
{
454
    if (T0) {
455
        env->nip = (uint64_t)(T1 & ~3);
456
    } else {
457
        env->nip = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
458
    }
459
    RETURN();
460
}
461
#endif
462

    
463
void OPPROTO op_movl_T1_ctr (void)
464
{
465
    T1 = env->ctr;
466
    RETURN();
467
}
468

    
469
void OPPROTO op_movl_T1_lr (void)
470
{
471
    T1 = env->lr;
472
    RETURN();
473
}
474

    
475
/* tests with result in T0 */
476
void OPPROTO op_test_ctr (void)
477
{
478
    T0 = (uint32_t)env->ctr;
479
    RETURN();
480
}
481

    
482
#if defined(TARGET_PPC64)
483
void OPPROTO op_test_ctr_64 (void)
484
{
485
    T0 = (uint64_t)env->ctr;
486
    RETURN();
487
}
488
#endif
489

    
490
void OPPROTO op_test_ctr_true (void)
491
{
492
    T0 = ((uint32_t)env->ctr != 0 && (T0 & PARAM1) != 0);
493
    RETURN();
494
}
495

    
496
#if defined(TARGET_PPC64)
497
void OPPROTO op_test_ctr_true_64 (void)
498
{
499
    T0 = ((uint64_t)env->ctr != 0 && (T0 & PARAM1) != 0);
500
    RETURN();
501
}
502
#endif
503

    
504
void OPPROTO op_test_ctr_false (void)
505
{
506
    T0 = ((uint32_t)env->ctr != 0 && (T0 & PARAM1) == 0);
507
    RETURN();
508
}
509

    
510
#if defined(TARGET_PPC64)
511
void OPPROTO op_test_ctr_false_64 (void)
512
{
513
    T0 = ((uint64_t)env->ctr != 0 && (T0 & PARAM1) == 0);
514
    RETURN();
515
}
516
#endif
517

    
518
void OPPROTO op_test_ctrz (void)
519
{
520
    T0 = ((uint32_t)env->ctr == 0);
521
    RETURN();
522
}
523

    
524
#if defined(TARGET_PPC64)
525
void OPPROTO op_test_ctrz_64 (void)
526
{
527
    T0 = ((uint64_t)env->ctr == 0);
528
    RETURN();
529
}
530
#endif
531

    
532
void OPPROTO op_test_ctrz_true (void)
533
{
534
    T0 = ((uint32_t)env->ctr == 0 && (T0 & PARAM1) != 0);
535
    RETURN();
536
}
537

    
538
#if defined(TARGET_PPC64)
539
void OPPROTO op_test_ctrz_true_64 (void)
540
{
541
    T0 = ((uint64_t)env->ctr == 0 && (T0 & PARAM1) != 0);
542
    RETURN();
543
}
544
#endif
545

    
546
void OPPROTO op_test_ctrz_false (void)
547
{
548
    T0 = ((uint32_t)env->ctr == 0 && (T0 & PARAM1) == 0);
549
    RETURN();
550
}
551

    
552
#if defined(TARGET_PPC64)
553
void OPPROTO op_test_ctrz_false_64 (void)
554
{
555
    T0 = ((uint64_t)env->ctr == 0 && (T0 & PARAM1) == 0);
556
    RETURN();
557
}
558
#endif
559

    
560
void OPPROTO op_test_true (void)
561
{
562
    T0 = (T0 & PARAM1);
563
    RETURN();
564
}
565

    
566
void OPPROTO op_test_false (void)
567
{
568
    T0 = ((T0 & PARAM1) == 0);
569
    RETURN();
570
}
571

    
572
/* CTR maintenance */
573
void OPPROTO op_dec_ctr (void)
574
{
575
    env->ctr--;
576
    RETURN();
577
}
578

    
579
/***                           Integer arithmetic                          ***/
580
/* add */
581
void OPPROTO op_check_addo (void)
582
{
583
    xer_ov = (((uint32_t)T2 ^ (uint32_t)T1 ^ UINT32_MAX) &
584
              ((uint32_t)T2 ^ (uint32_t)T0)) >> 31;
585
    xer_so |= xer_ov;
586
    RETURN();
587
}
588

    
589
#if defined(TARGET_PPC64)
590
void OPPROTO op_check_addo_64 (void)
591
{
592
    xer_ov = (((uint64_t)T2 ^ (uint64_t)T1 ^ UINT64_MAX) &
593
              ((uint64_t)T2 ^ (uint64_t)T0)) >> 63;
594
    xer_so |= xer_ov;
595
    RETURN();
596
}
597
#endif
598

    
599
/* add carrying */
600
void OPPROTO op_check_addc (void)
601
{
602
    if (likely((uint32_t)T0 >= (uint32_t)T2)) {
603
        xer_ca = 0;
604
    } else {
605
        xer_ca = 1;
606
    }
607
    RETURN();
608
}
609

    
610
#if defined(TARGET_PPC64)
611
void OPPROTO op_check_addc_64 (void)
612
{
613
    if (likely((uint64_t)T0 >= (uint64_t)T2)) {
614
        xer_ca = 0;
615
    } else {
616
        xer_ca = 1;
617
    }
618
    RETURN();
619
}
620
#endif
621

    
622
/* add extended */
623
void OPPROTO op_adde (void)
624
{
625
    do_adde();
626
    RETURN();
627
}
628

    
629
#if defined(TARGET_PPC64)
630
void OPPROTO op_adde_64 (void)
631
{
632
    do_adde_64();
633
    RETURN();
634
}
635
#endif
636

    
637
/* add to minus one extended */
638
void OPPROTO op_add_me (void)
639
{
640
    T0 += xer_ca + (-1);
641
    if (likely((uint32_t)T1 != 0))
642
        xer_ca = 1;
643
    else
644
        xer_ca = 0;
645
    RETURN();
646
}
647

    
648
#if defined(TARGET_PPC64)
649
void OPPROTO op_add_me_64 (void)
650
{
651
    T0 += xer_ca + (-1);
652
    if (likely((uint64_t)T1 != 0))
653
        xer_ca = 1;
654
    else
655
        xer_ca = 0;
656
    RETURN();
657
}
658
#endif
659

    
660
void OPPROTO op_addmeo (void)
661
{
662
    do_addmeo();
663
    RETURN();
664
}
665

    
666
void OPPROTO op_addmeo_64 (void)
667
{
668
    do_addmeo();
669
    RETURN();
670
}
671

    
672
/* add to zero extended */
673
void OPPROTO op_add_ze (void)
674
{
675
    T0 += xer_ca;
676
    RETURN();
677
}
678

    
679
/* divide word */
680
void OPPROTO op_divw (void)
681
{
682
    if (unlikely(((int32_t)T0 == INT32_MIN && (int32_t)T1 == (int32_t)-1) ||
683
                 (int32_t)T1 == 0)) {
684
        T0 = (int32_t)(UINT32_MAX * ((uint32_t)T0 >> 31));
685
    } else {
686
        T0 = (int32_t)T0 / (int32_t)T1;
687
    }
688
    RETURN();
689
}
690

    
691
#if defined(TARGET_PPC64)
692
void OPPROTO op_divd (void)
693
{
694
    if (unlikely(((int64_t)T0 == INT64_MIN && (int64_t)T1 == (int64_t)-1LL) ||
695
                 (int64_t)T1 == 0)) {
696
        T0 = (int64_t)(UINT64_MAX * ((uint64_t)T0 >> 63));
697
    } else {
698
        T0 = (int64_t)T0 / (int64_t)T1;
699
    }
700
    RETURN();
701
}
702
#endif
703

    
704
void OPPROTO op_divwo (void)
705
{
706
    do_divwo();
707
    RETURN();
708
}
709

    
710
#if defined(TARGET_PPC64)
711
void OPPROTO op_divdo (void)
712
{
713
    do_divdo();
714
    RETURN();
715
}
716
#endif
717

    
718
/* divide word unsigned */
719
void OPPROTO op_divwu (void)
720
{
721
    if (unlikely(T1 == 0)) {
722
        T0 = 0;
723
    } else {
724
        T0 = (uint32_t)T0 / (uint32_t)T1;
725
    }
726
    RETURN();
727
}
728

    
729
#if defined(TARGET_PPC64)
730
void OPPROTO op_divdu (void)
731
{
732
    if (unlikely(T1 == 0)) {
733
        T0 = 0;
734
    } else {
735
        T0 /= T1;
736
    }
737
    RETURN();
738
}
739
#endif
740

    
741
void OPPROTO op_divwuo (void)
742
{
743
    do_divwuo();
744
    RETURN();
745
}
746

    
747
#if defined(TARGET_PPC64)
748
void OPPROTO op_divduo (void)
749
{
750
    do_divduo();
751
    RETURN();
752
}
753
#endif
754

    
755
/* multiply high word */
756
void OPPROTO op_mulhw (void)
757
{
758
    T0 = ((int64_t)((int32_t)T0) * (int64_t)((int32_t)T1)) >> 32;
759
    RETURN();
760
}
761

    
762
#if defined(TARGET_PPC64)
763
void OPPROTO op_mulhd (void)
764
{
765
    uint64_t tl, th;
766

    
767
    muls64(&tl, &th, T0, T1);
768
    T0 = th;
769
    RETURN();
770
}
771
#endif
772

    
773
/* multiply high word unsigned */
774
void OPPROTO op_mulhwu (void)
775
{
776
    T0 = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1) >> 32;
777
    RETURN();
778
}
779

    
780
#if defined(TARGET_PPC64)
781
void OPPROTO op_mulhdu (void)
782
{
783
    uint64_t tl, th;
784

    
785
    mulu64(&tl, &th, T0, T1);
786
    T0 = th;
787
    RETURN();
788
}
789
#endif
790

    
791
/* multiply low immediate */
792
void OPPROTO op_mulli (void)
793
{
794
    T0 = ((int32_t)T0 * (int32_t)PARAM1);
795
    RETURN();
796
}
797

    
798
/* multiply low word */
799
void OPPROTO op_mullw (void)
800
{
801
    T0 = (int32_t)(T0 * T1);
802
    RETURN();
803
}
804

    
805
#if defined(TARGET_PPC64)
806
void OPPROTO op_mulld (void)
807
{
808
    T0 *= T1;
809
    RETURN();
810
}
811
#endif
812

    
813
void OPPROTO op_mullwo (void)
814
{
815
    do_mullwo();
816
    RETURN();
817
}
818

    
819
#if defined(TARGET_PPC64)
820
void OPPROTO op_mulldo (void)
821
{
822
    do_mulldo();
823
    RETURN();
824
}
825
#endif
826

    
827
/* negate */
828
void OPPROTO op_neg (void)
829
{
830
    if (likely(T0 != INT32_MIN)) {
831
        T0 = -(int32_t)T0;
832
    }
833
    RETURN();
834
}
835

    
836
#if defined(TARGET_PPC64)
837
void OPPROTO op_neg_64 (void)
838
{
839
    if (likely(T0 != INT64_MIN)) {
840
        T0 = -(int64_t)T0;
841
    }
842
    RETURN();
843
}
844
#endif
845

    
846
void OPPROTO op_nego (void)
847
{
848
    do_nego();
849
    RETURN();
850
}
851

    
852
#if defined(TARGET_PPC64)
853
void OPPROTO op_nego_64 (void)
854
{
855
    do_nego_64();
856
    RETURN();
857
}
858
#endif
859

    
860
/* subtract from carrying */
861
void OPPROTO op_check_subfc (void)
862
{
863
    if (likely((uint32_t)T0 > (uint32_t)T1)) {
864
        xer_ca = 0;
865
    } else {
866
        xer_ca = 1;
867
    }
868
    RETURN();
869
}
870

    
871
#if defined(TARGET_PPC64)
872
void OPPROTO op_check_subfc_64 (void)
873
{
874
    if (likely((uint64_t)T0 > (uint64_t)T1)) {
875
        xer_ca = 0;
876
    } else {
877
        xer_ca = 1;
878
    }
879
    RETURN();
880
}
881
#endif
882

    
883
/* subtract from extended */
884
void OPPROTO op_subfe (void)
885
{
886
    do_subfe();
887
    RETURN();
888
}
889

    
890
#if defined(TARGET_PPC64)
891
void OPPROTO op_subfe_64 (void)
892
{
893
    do_subfe_64();
894
    RETURN();
895
}
896
#endif
897

    
898
/* subtract from immediate carrying */
899
void OPPROTO op_subfic (void)
900
{
901
    T0 = (int32_t)PARAM1 + ~T0 + 1;
902
    if ((uint32_t)T0 <= (uint32_t)PARAM1) {
903
        xer_ca = 1;
904
    } else {
905
        xer_ca = 0;
906
    }
907
    RETURN();
908
}
909

    
910
#if defined(TARGET_PPC64)
911
void OPPROTO op_subfic_64 (void)
912
{
913
    T0 = (int64_t)PARAM1 + ~T0 + 1;
914
    if ((uint64_t)T0 <= (uint64_t)PARAM1) {
915
        xer_ca = 1;
916
    } else {
917
        xer_ca = 0;
918
    }
919
    RETURN();
920
}
921
#endif
922

    
923
/* subtract from minus one extended */
924
void OPPROTO op_subfme (void)
925
{
926
    T0 = ~T0 + xer_ca - 1;
927
    if (likely((uint32_t)T0 != UINT32_MAX))
928
        xer_ca = 1;
929
    else
930
        xer_ca = 0;
931
    RETURN();
932
}
933

    
934
#if defined(TARGET_PPC64)
935
void OPPROTO op_subfme_64 (void)
936
{
937
    T0 = ~T0 + xer_ca - 1;
938
    if (likely((uint64_t)T0 != UINT64_MAX))
939
        xer_ca = 1;
940
    else
941
        xer_ca = 0;
942
    RETURN();
943
}
944
#endif
945

    
946
void OPPROTO op_subfmeo (void)
947
{
948
    do_subfmeo();
949
    RETURN();
950
}
951

    
952
#if defined(TARGET_PPC64)
953
void OPPROTO op_subfmeo_64 (void)
954
{
955
    do_subfmeo_64();
956
    RETURN();
957
}
958
#endif
959

    
960
/* subtract from zero extended */
961
void OPPROTO op_subfze (void)
962
{
963
    T1 = ~T0;
964
    T0 = T1 + xer_ca;
965
    if ((uint32_t)T0 < (uint32_t)T1) {
966
        xer_ca = 1;
967
    } else {
968
        xer_ca = 0;
969
    }
970
    RETURN();
971
}
972

    
973
#if defined(TARGET_PPC64)
974
void OPPROTO op_subfze_64 (void)
975
{
976
    T1 = ~T0;
977
    T0 = T1 + xer_ca;
978
    if ((uint64_t)T0 < (uint64_t)T1) {
979
        xer_ca = 1;
980
    } else {
981
        xer_ca = 0;
982
    }
983
    RETURN();
984
}
985
#endif
986

    
987
void OPPROTO op_subfzeo (void)
988
{
989
    do_subfzeo();
990
    RETURN();
991
}
992

    
993
#if defined(TARGET_PPC64)
994
void OPPROTO op_subfzeo_64 (void)
995
{
996
    do_subfzeo_64();
997
    RETURN();
998
}
999
#endif
1000

    
1001
/***                           Integer comparison                          ***/
1002
/* compare */
1003
void OPPROTO op_cmp (void)
1004
{
1005
    if ((int32_t)T0 < (int32_t)T1) {
1006
        T0 = 0x08;
1007
    } else if ((int32_t)T0 > (int32_t)T1) {
1008
        T0 = 0x04;
1009
    } else {
1010
        T0 = 0x02;
1011
    }
1012
    T0 |= xer_so;
1013
    RETURN();
1014
}
1015

    
1016
#if defined(TARGET_PPC64)
1017
void OPPROTO op_cmp_64 (void)
1018
{
1019
    if ((int64_t)T0 < (int64_t)T1) {
1020
        T0 = 0x08;
1021
    } else if ((int64_t)T0 > (int64_t)T1) {
1022
        T0 = 0x04;
1023
    } else {
1024
        T0 = 0x02;
1025
    }
1026
    T0 |= xer_so;
1027
    RETURN();
1028
}
1029
#endif
1030

    
1031
/* compare immediate */
1032
void OPPROTO op_cmpi (void)
1033
{
1034
    if ((int32_t)T0 < (int32_t)PARAM1) {
1035
        T0 = 0x08;
1036
    } else if ((int32_t)T0 > (int32_t)PARAM1) {
1037
        T0 = 0x04;
1038
    } else {
1039
        T0 = 0x02;
1040
    }
1041
    T0 |= xer_so;
1042
    RETURN();
1043
}
1044

    
1045
#if defined(TARGET_PPC64)
1046
void OPPROTO op_cmpi_64 (void)
1047
{
1048
    if ((int64_t)T0 < (int64_t)((int32_t)PARAM1)) {
1049
        T0 = 0x08;
1050
    } else if ((int64_t)T0 > (int64_t)((int32_t)PARAM1)) {
1051
        T0 = 0x04;
1052
    } else {
1053
        T0 = 0x02;
1054
    }
1055
    T0 |= xer_so;
1056
    RETURN();
1057
}
1058
#endif
1059

    
1060
/* compare logical */
1061
void OPPROTO op_cmpl (void)
1062
{
1063
    if ((uint32_t)T0 < (uint32_t)T1) {
1064
        T0 = 0x08;
1065
    } else if ((uint32_t)T0 > (uint32_t)T1) {
1066
        T0 = 0x04;
1067
    } else {
1068
        T0 = 0x02;
1069
    }
1070
    T0 |= xer_so;
1071
    RETURN();
1072
}
1073

    
1074
#if defined(TARGET_PPC64)
1075
void OPPROTO op_cmpl_64 (void)
1076
{
1077
    if ((uint64_t)T0 < (uint64_t)T1) {
1078
        T0 = 0x08;
1079
    } else if ((uint64_t)T0 > (uint64_t)T1) {
1080
        T0 = 0x04;
1081
    } else {
1082
        T0 = 0x02;
1083
    }
1084
    T0 |= xer_so;
1085
    RETURN();
1086
}
1087
#endif
1088

    
1089
/* compare logical immediate */
1090
void OPPROTO op_cmpli (void)
1091
{
1092
    if ((uint32_t)T0 < (uint32_t)PARAM1) {
1093
        T0 = 0x08;
1094
    } else if ((uint32_t)T0 > (uint32_t)PARAM1) {
1095
        T0 = 0x04;
1096
    } else {
1097
        T0 = 0x02;
1098
    }
1099
    T0 |= xer_so;
1100
    RETURN();
1101
}
1102

    
1103
#if defined(TARGET_PPC64)
1104
void OPPROTO op_cmpli_64 (void)
1105
{
1106
    if ((uint64_t)T0 < (uint64_t)PARAM1) {
1107
        T0 = 0x08;
1108
    } else if ((uint64_t)T0 > (uint64_t)PARAM1) {
1109
        T0 = 0x04;
1110
    } else {
1111
        T0 = 0x02;
1112
    }
1113
    T0 |= xer_so;
1114
    RETURN();
1115
}
1116
#endif
1117

    
1118
void OPPROTO op_isel (void)
1119
{
1120
    if (T0)
1121
        T0 = T1;
1122
    else
1123
        T0 = T2;
1124
    RETURN();
1125
}
1126

    
1127
void OPPROTO op_popcntb (void)
1128
{
1129
    do_popcntb();
1130
    RETURN();
1131
}
1132

    
1133
#if defined(TARGET_PPC64)
1134
void OPPROTO op_popcntb_64 (void)
1135
{
1136
    do_popcntb_64();
1137
    RETURN();
1138
}
1139
#endif
1140

    
1141
/***                            Integer logical                            ***/
1142
/* and */
1143
void OPPROTO op_and (void)
1144
{
1145
    T0 &= T1;
1146
    RETURN();
1147
}
1148

    
1149
/* andc */
1150
void OPPROTO op_andc (void)
1151
{
1152
    T0 &= ~T1;
1153
    RETURN();
1154
}
1155

    
1156
/* andi. */
1157
void OPPROTO op_andi_T0 (void)
1158
{
1159
    T0 &= (uint32_t)PARAM1;
1160
    RETURN();
1161
}
1162

    
1163
void OPPROTO op_andi_T1 (void)
1164
{
1165
    T1 &= (uint32_t)PARAM1;
1166
    RETURN();
1167
}
1168

    
1169
#if defined(TARGET_PPC64)
1170
void OPPROTO op_andi_T0_64 (void)
1171
{
1172
    T0 &= ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
1173
    RETURN();
1174
}
1175

    
1176
void OPPROTO op_andi_T1_64 (void)
1177
{
1178
    T1 &= ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
1179
    RETURN();
1180
}
1181
#endif
1182

    
1183
/* count leading zero */
1184
void OPPROTO op_cntlzw (void)
1185
{
1186
    do_cntlzw();
1187
    RETURN();
1188
}
1189

    
1190
#if defined(TARGET_PPC64)
1191
void OPPROTO op_cntlzd (void)
1192
{
1193
    do_cntlzd();
1194
    RETURN();
1195
}
1196
#endif
1197

    
1198
/* eqv */
1199
void OPPROTO op_eqv (void)
1200
{
1201
    T0 = ~(T0 ^ T1);
1202
    RETURN();
1203
}
1204

    
1205
/* extend sign byte */
1206
void OPPROTO op_extsb (void)
1207
{
1208
#if defined (TARGET_PPC64)
1209
    T0 = (int64_t)((int8_t)T0);
1210
#else
1211
    T0 = (int32_t)((int8_t)T0);
1212
#endif
1213
    RETURN();
1214
}
1215

    
1216
/* extend sign half word */
1217
void OPPROTO op_extsh (void)
1218
{
1219
#if defined (TARGET_PPC64)
1220
    T0 = (int64_t)((int16_t)T0);
1221
#else
1222
    T0 = (int32_t)((int16_t)T0);
1223
#endif
1224
    RETURN();
1225
}
1226

    
1227
#if defined (TARGET_PPC64)
1228
void OPPROTO op_extsw (void)
1229
{
1230
    T0 = (int64_t)((int32_t)T0);
1231
    RETURN();
1232
}
1233
#endif
1234

    
1235
/* nand */
1236
void OPPROTO op_nand (void)
1237
{
1238
    T0 = ~(T0 & T1);
1239
    RETURN();
1240
}
1241

    
1242
/* nor */
1243
void OPPROTO op_nor (void)
1244
{
1245
    T0 = ~(T0 | T1);
1246
    RETURN();
1247
}
1248

    
1249
/* or */
1250
void OPPROTO op_or (void)
1251
{
1252
    T0 |= T1;
1253
    RETURN();
1254
}
1255

    
1256
/* orc */
1257
void OPPROTO op_orc (void)
1258
{
1259
    T0 |= ~T1;
1260
    RETURN();
1261
}
1262

    
1263
/* ori */
1264
void OPPROTO op_ori (void)
1265
{
1266
    T0 |= (uint32_t)PARAM1;
1267
    RETURN();
1268
}
1269

    
1270
/* xor */
1271
void OPPROTO op_xor (void)
1272
{
1273
    T0 ^= T1;
1274
    RETURN();
1275
}
1276

    
1277
/* xori */
1278
void OPPROTO op_xori (void)
1279
{
1280
    T0 ^= (uint32_t)PARAM1;
1281
    RETURN();
1282
}
1283

    
1284
/***                             Integer rotate                            ***/
1285
void OPPROTO op_rotl32_T0_T1 (void)
1286
{
1287
    T0 = rotl32(T0, T1 & 0x1F);
1288
    RETURN();
1289
}
1290

    
1291
void OPPROTO op_rotli32_T0 (void)
1292
{
1293
    T0 = rotl32(T0, PARAM1);
1294
    RETURN();
1295
}
1296

    
1297
#if defined(TARGET_PPC64)
1298
void OPPROTO op_rotl64_T0_T1 (void)
1299
{
1300
    T0 = rotl64(T0, T1 & 0x3F);
1301
    RETURN();
1302
}
1303

    
1304
void OPPROTO op_rotli64_T0 (void)
1305
{
1306
    T0 = rotl64(T0, PARAM1);
1307
    RETURN();
1308
}
1309
#endif
1310

    
1311
/***                             Integer shift                             ***/
1312
/* shift left word */
1313
void OPPROTO op_slw (void)
1314
{
1315
    if (T1 & 0x20) {
1316
        T0 = 0;
1317
    } else {
1318
        T0 = (uint32_t)(T0 << T1);
1319
    }
1320
    RETURN();
1321
}
1322

    
1323
#if defined(TARGET_PPC64)
1324
void OPPROTO op_sld (void)
1325
{
1326
    if (T1 & 0x40) {
1327
        T0 = 0;
1328
    } else {
1329
        T0 = T0 << T1;
1330
    }
1331
    RETURN();
1332
}
1333
#endif
1334

    
1335
/* shift right algebraic word */
1336
void OPPROTO op_sraw (void)
1337
{
1338
    do_sraw();
1339
    RETURN();
1340
}
1341

    
1342
#if defined(TARGET_PPC64)
1343
void OPPROTO op_srad (void)
1344
{
1345
    do_srad();
1346
    RETURN();
1347
}
1348
#endif
1349

    
1350
/* shift right algebraic word immediate */
1351
void OPPROTO op_srawi (void)
1352
{
1353
    uint32_t mask = (uint32_t)PARAM2;
1354

    
1355
    T0 = (int32_t)T0 >> PARAM1;
1356
    if ((int32_t)T1 < 0 && (T1 & mask) != 0) {
1357
        xer_ca = 1;
1358
    } else {
1359
        xer_ca = 0;
1360
    }
1361
    RETURN();
1362
}
1363

    
1364
#if defined(TARGET_PPC64)
1365
void OPPROTO op_sradi (void)
1366
{
1367
    uint64_t mask = ((uint64_t)PARAM2 << 32) | (uint64_t)PARAM3;
1368

    
1369
    T0 = (int64_t)T0 >> PARAM1;
1370
    if ((int64_t)T1 < 0 && ((uint64_t)T1 & mask) != 0) {
1371
        xer_ca = 1;
1372
    } else {
1373
        xer_ca = 0;
1374
    }
1375
    RETURN();
1376
}
1377
#endif
1378

    
1379
/* shift right word */
1380
void OPPROTO op_srw (void)
1381
{
1382
    if (T1 & 0x20) {
1383
        T0 = 0;
1384
    } else {
1385
        T0 = (uint32_t)T0 >> T1;
1386
    }
1387
    RETURN();
1388
}
1389

    
1390
#if defined(TARGET_PPC64)
1391
void OPPROTO op_srd (void)
1392
{
1393
    if (T1 & 0x40) {
1394
        T0 = 0;
1395
    } else {
1396
        T0 = (uint64_t)T0 >> T1;
1397
    }
1398
    RETURN();
1399
}
1400
#endif
1401

    
1402
void OPPROTO op_sl_T0_T1 (void)
1403
{
1404
    T0 = T0 << T1;
1405
    RETURN();
1406
}
1407

    
1408
void OPPROTO op_sli_T0 (void)
1409
{
1410
    T0 = T0 << PARAM1;
1411
    RETURN();
1412
}
1413

    
1414
void OPPROTO op_sli_T1 (void)
1415
{
1416
    T1 = T1 << PARAM1;
1417
    RETURN();
1418
}
1419

    
1420
void OPPROTO op_srl_T0_T1 (void)
1421
{
1422
    T0 = (uint32_t)T0 >> T1;
1423
    RETURN();
1424
}
1425

    
1426
#if defined(TARGET_PPC64)
1427
void OPPROTO op_srl_T0_T1_64 (void)
1428
{
1429
    T0 = (uint32_t)T0 >> T1;
1430
    RETURN();
1431
}
1432
#endif
1433

    
1434
void OPPROTO op_srli_T0 (void)
1435
{
1436
    T0 = (uint32_t)T0 >> PARAM1;
1437
    RETURN();
1438
}
1439

    
1440
#if defined(TARGET_PPC64)
1441
void OPPROTO op_srli_T0_64 (void)
1442
{
1443
    T0 = (uint64_t)T0 >> PARAM1;
1444
    RETURN();
1445
}
1446
#endif
1447

    
1448
void OPPROTO op_srli_T1 (void)
1449
{
1450
    T1 = (uint32_t)T1 >> PARAM1;
1451
    RETURN();
1452
}
1453

    
1454
#if defined(TARGET_PPC64)
1455
void OPPROTO op_srli_T1_64 (void)
1456
{
1457
    T1 = (uint64_t)T1 >> PARAM1;
1458
    RETURN();
1459
}
1460
#endif
1461

    
1462
/***                       Floating-Point arithmetic                       ***/
1463
/* fadd - fadd. */
1464
void OPPROTO op_fadd (void)
1465
{
1466
#if USE_PRECISE_EMULATION
1467
    do_fadd();
1468
#else
1469
    FT0 = float64_add(FT0, FT1, &env->fp_status);
1470
#endif
1471
    RETURN();
1472
}
1473

    
1474
/* fsub - fsub. */
1475
void OPPROTO op_fsub (void)
1476
{
1477
#if USE_PRECISE_EMULATION
1478
    do_fsub();
1479
#else
1480
    FT0 = float64_sub(FT0, FT1, &env->fp_status);
1481
#endif
1482
    RETURN();
1483
}
1484

    
1485
/* fmul - fmul. */
1486
void OPPROTO op_fmul (void)
1487
{
1488
#if USE_PRECISE_EMULATION
1489
    do_fmul();
1490
#else
1491
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1492
#endif
1493
    RETURN();
1494
}
1495

    
1496
/* fdiv - fdiv. */
1497
void OPPROTO op_fdiv (void)
1498
{
1499
#if USE_PRECISE_EMULATION
1500
    do_fdiv();
1501
#else
1502
    FT0 = float64_div(FT0, FT1, &env->fp_status);
1503
#endif
1504
    RETURN();
1505
}
1506

    
1507
/* fsqrt - fsqrt. */
1508
void OPPROTO op_fsqrt (void)
1509
{
1510
    do_fsqrt();
1511
    RETURN();
1512
}
1513

    
1514
/* fre - fre. */
1515
void OPPROTO op_fre (void)
1516
{
1517
    do_fre();
1518
    RETURN();
1519
}
1520

    
1521
/* fres - fres. */
1522
void OPPROTO op_fres (void)
1523
{
1524
    do_fres();
1525
    RETURN();
1526
}
1527

    
1528
/* frsqrte  - frsqrte. */
1529
void OPPROTO op_frsqrte (void)
1530
{
1531
    do_frsqrte();
1532
    RETURN();
1533
}
1534

    
1535
/* fsel - fsel. */
1536
void OPPROTO op_fsel (void)
1537
{
1538
    do_fsel();
1539
    RETURN();
1540
}
1541

    
1542
/***                     Floating-Point multiply-and-add                   ***/
1543
/* fmadd - fmadd. */
1544
void OPPROTO op_fmadd (void)
1545
{
1546
#if USE_PRECISE_EMULATION
1547
    do_fmadd();
1548
#else
1549
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1550
    FT0 = float64_add(FT0, FT2, &env->fp_status);
1551
#endif
1552
    RETURN();
1553
}
1554

    
1555
/* fmsub - fmsub. */
1556
void OPPROTO op_fmsub (void)
1557
{
1558
#if USE_PRECISE_EMULATION
1559
    do_fmsub();
1560
#else
1561
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1562
    FT0 = float64_sub(FT0, FT2, &env->fp_status);
1563
#endif
1564
    RETURN();
1565
}
1566

    
1567
/* fnmadd - fnmadd. - fnmadds - fnmadds. */
1568
void OPPROTO op_fnmadd (void)
1569
{
1570
    do_fnmadd();
1571
    RETURN();
1572
}
1573

    
1574
/* fnmsub - fnmsub. */
1575
void OPPROTO op_fnmsub (void)
1576
{
1577
    do_fnmsub();
1578
    RETURN();
1579
}
1580

    
1581
/***                     Floating-Point round & convert                    ***/
1582
/* frsp - frsp. */
1583
void OPPROTO op_frsp (void)
1584
{
1585
#if USE_PRECISE_EMULATION
1586
    do_frsp();
1587
#else
1588
    FT0 = float64_to_float32(FT0, &env->fp_status);
1589
#endif
1590
    RETURN();
1591
}
1592

    
1593
/* fctiw - fctiw. */
1594
void OPPROTO op_fctiw (void)
1595
{
1596
    do_fctiw();
1597
    RETURN();
1598
}
1599

    
1600
/* fctiwz - fctiwz. */
1601
void OPPROTO op_fctiwz (void)
1602
{
1603
    do_fctiwz();
1604
    RETURN();
1605
}
1606

    
1607
#if defined(TARGET_PPC64)
1608
/* fcfid - fcfid. */
1609
void OPPROTO op_fcfid (void)
1610
{
1611
    do_fcfid();
1612
    RETURN();
1613
}
1614

    
1615
/* fctid - fctid. */
1616
void OPPROTO op_fctid (void)
1617
{
1618
    do_fctid();
1619
    RETURN();
1620
}
1621

    
1622
/* fctidz - fctidz. */
1623
void OPPROTO op_fctidz (void)
1624
{
1625
    do_fctidz();
1626
    RETURN();
1627
}
1628
#endif
1629

    
1630
void OPPROTO op_frin (void)
1631
{
1632
    do_frin();
1633
    RETURN();
1634
}
1635

    
1636
void OPPROTO op_friz (void)
1637
{
1638
    do_friz();
1639
    RETURN();
1640
}
1641

    
1642
void OPPROTO op_frip (void)
1643
{
1644
    do_frip();
1645
    RETURN();
1646
}
1647

    
1648
void OPPROTO op_frim (void)
1649
{
1650
    do_frim();
1651
    RETURN();
1652
}
1653

    
1654
/***                         Floating-Point compare                        ***/
1655
/* fcmpu */
1656
void OPPROTO op_fcmpu (void)
1657
{
1658
    do_fcmpu();
1659
    RETURN();
1660
}
1661

    
1662
/* fcmpo */
1663
void OPPROTO op_fcmpo (void)
1664
{
1665
    do_fcmpo();
1666
    RETURN();
1667
}
1668

    
1669
/***                         Floating-point move                           ***/
1670
/* fabs */
1671
void OPPROTO op_fabs (void)
1672
{
1673
    FT0 = float64_abs(FT0);
1674
    RETURN();
1675
}
1676

    
1677
/* fnabs */
1678
void OPPROTO op_fnabs (void)
1679
{
1680
    FT0 = float64_abs(FT0);
1681
    FT0 = float64_chs(FT0);
1682
    RETURN();
1683
}
1684

    
1685
/* fneg */
1686
void OPPROTO op_fneg (void)
1687
{
1688
    FT0 = float64_chs(FT0);
1689
    RETURN();
1690
}
1691

    
1692
/* Load and store */
1693
#define MEMSUFFIX _raw
1694
#include "op_helper.h"
1695
#include "op_mem.h"
1696
#if !defined(CONFIG_USER_ONLY)
1697
#define MEMSUFFIX _user
1698
#include "op_helper.h"
1699
#include "op_mem.h"
1700
#define MEMSUFFIX _kernel
1701
#include "op_helper.h"
1702
#include "op_mem.h"
1703
#define MEMSUFFIX _hypv
1704
#include "op_helper.h"
1705
#include "op_mem.h"
1706
#endif
1707

    
1708
/* Special op to check and maybe clear reservation */
1709
void OPPROTO op_check_reservation (void)
1710
{
1711
    if ((uint32_t)env->reserve == (uint32_t)(T0 & ~0x00000003))
1712
        env->reserve = (target_ulong)-1ULL;
1713
    RETURN();
1714
}
1715

    
1716
#if defined(TARGET_PPC64)
1717
void OPPROTO op_check_reservation_64 (void)
1718
{
1719
    if ((uint64_t)env->reserve == (uint64_t)(T0 & ~0x00000003))
1720
        env->reserve = (target_ulong)-1ULL;
1721
    RETURN();
1722
}
1723
#endif
1724

    
1725
void OPPROTO op_wait (void)
1726
{
1727
    env->halted = 1;
1728
    RETURN();
1729
}
1730

    
1731
/* Return from interrupt */
1732
#if !defined(CONFIG_USER_ONLY)
1733
void OPPROTO op_rfi (void)
1734
{
1735
    do_rfi();
1736
    RETURN();
1737
}
1738

    
1739
#if defined(TARGET_PPC64)
1740
void OPPROTO op_rfid (void)
1741
{
1742
    do_rfid();
1743
    RETURN();
1744
}
1745

    
1746
void OPPROTO op_hrfid (void)
1747
{
1748
    do_hrfid();
1749
    RETURN();
1750
}
1751
#endif
1752

    
1753
/* Exception vectors */
1754
void OPPROTO op_store_excp_prefix (void)
1755
{
1756
    T0 &= env->ivpr_mask;
1757
    env->excp_prefix = T0;
1758
    RETURN();
1759
}
1760

    
1761
void OPPROTO op_store_excp_vector (void)
1762
{
1763
    T0 &= env->ivor_mask;
1764
    env->excp_vectors[PARAM1] = T0;
1765
    RETURN();
1766
}
1767
#endif
1768

    
1769
/* Trap word */
1770
void OPPROTO op_tw (void)
1771
{
1772
    do_tw(PARAM1);
1773
    RETURN();
1774
}
1775

    
1776
#if defined(TARGET_PPC64)
1777
void OPPROTO op_td (void)
1778
{
1779
    do_td(PARAM1);
1780
    RETURN();
1781
}
1782
#endif
1783

    
1784
#if !defined(CONFIG_USER_ONLY)
1785
/* tlbia */
1786
void OPPROTO op_tlbia (void)
1787
{
1788
    ppc_tlb_invalidate_all(env);
1789
    RETURN();
1790
}
1791

    
1792
/* tlbie */
1793
void OPPROTO op_tlbie (void)
1794
{
1795
    ppc_tlb_invalidate_one(env, (uint32_t)T0);
1796
    RETURN();
1797
}
1798

    
1799
#if defined(TARGET_PPC64)
1800
void OPPROTO op_tlbie_64 (void)
1801
{
1802
    ppc_tlb_invalidate_one(env, T0);
1803
    RETURN();
1804
}
1805
#endif
1806

    
1807
#if defined(TARGET_PPC64)
1808
void OPPROTO op_slbia (void)
1809
{
1810
    ppc_slb_invalidate_all(env);
1811
    RETURN();
1812
}
1813

    
1814
void OPPROTO op_slbie (void)
1815
{
1816
    ppc_slb_invalidate_one(env, (uint32_t)T0);
1817
    RETURN();
1818
}
1819

    
1820
void OPPROTO op_slbie_64 (void)
1821
{
1822
    ppc_slb_invalidate_one(env, T0);
1823
    RETURN();
1824
}
1825
#endif
1826
#endif
1827

    
1828
#if !defined(CONFIG_USER_ONLY)
1829
/* PowerPC 602/603/755 software TLB load instructions */
1830
void OPPROTO op_6xx_tlbld (void)
1831
{
1832
    do_load_6xx_tlb(0);
1833
    RETURN();
1834
}
1835

    
1836
void OPPROTO op_6xx_tlbli (void)
1837
{
1838
    do_load_6xx_tlb(1);
1839
    RETURN();
1840
}
1841

    
1842
/* PowerPC 74xx software TLB load instructions */
1843
void OPPROTO op_74xx_tlbld (void)
1844
{
1845
    do_load_74xx_tlb(0);
1846
    RETURN();
1847
}
1848

    
1849
void OPPROTO op_74xx_tlbli (void)
1850
{
1851
    do_load_74xx_tlb(1);
1852
    RETURN();
1853
}
1854
#endif
1855

    
1856
/* 601 specific */
1857
void OPPROTO op_load_601_rtcl (void)
1858
{
1859
    T0 = cpu_ppc601_load_rtcl(env);
1860
    RETURN();
1861
}
1862

    
1863
void OPPROTO op_load_601_rtcu (void)
1864
{
1865
    T0 = cpu_ppc601_load_rtcu(env);
1866
    RETURN();
1867
}
1868

    
1869
#if !defined(CONFIG_USER_ONLY)
1870
void OPPROTO op_store_601_rtcl (void)
1871
{
1872
    cpu_ppc601_store_rtcl(env, T0);
1873
    RETURN();
1874
}
1875

    
1876
void OPPROTO op_store_601_rtcu (void)
1877
{
1878
    cpu_ppc601_store_rtcu(env, T0);
1879
    RETURN();
1880
}
1881

    
1882
void OPPROTO op_store_hid0_601 (void)
1883
{
1884
    do_store_hid0_601();
1885
    RETURN();
1886
}
1887

    
1888
void OPPROTO op_load_601_bat (void)
1889
{
1890
    T0 = env->IBAT[PARAM1][PARAM2];
1891
    RETURN();
1892
}
1893

    
1894
void OPPROTO op_store_601_batl (void)
1895
{
1896
    do_store_ibatl_601(env, PARAM1, T0);
1897
    RETURN();
1898
}
1899

    
1900
void OPPROTO op_store_601_batu (void)
1901
{
1902
    do_store_ibatu_601(env, PARAM1, T0);
1903
    RETURN();
1904
}
1905
#endif /* !defined(CONFIG_USER_ONLY) */
1906

    
1907
/* PowerPC 601 specific instructions (POWER bridge) */
1908
/* XXX: those micro-ops need tests ! */
1909
void OPPROTO op_POWER_abs (void)
1910
{
1911
    if ((int32_t)T0 == INT32_MIN)
1912
        T0 = INT32_MAX;
1913
    else if ((int32_t)T0 < 0)
1914
        T0 = -T0;
1915
    RETURN();
1916
}
1917

    
1918
void OPPROTO op_POWER_abso (void)
1919
{
1920
    do_POWER_abso();
1921
    RETURN();
1922
}
1923

    
1924
void OPPROTO op_POWER_clcs (void)
1925
{
1926
    do_POWER_clcs();
1927
    RETURN();
1928
}
1929

    
1930
void OPPROTO op_POWER_div (void)
1931
{
1932
    do_POWER_div();
1933
    RETURN();
1934
}
1935

    
1936
void OPPROTO op_POWER_divo (void)
1937
{
1938
    do_POWER_divo();
1939
    RETURN();
1940
}
1941

    
1942
void OPPROTO op_POWER_divs (void)
1943
{
1944
    do_POWER_divs();
1945
    RETURN();
1946
}
1947

    
1948
void OPPROTO op_POWER_divso (void)
1949
{
1950
    do_POWER_divso();
1951
    RETURN();
1952
}
1953

    
1954
void OPPROTO op_POWER_doz (void)
1955
{
1956
    if ((int32_t)T1 > (int32_t)T0)
1957
        T0 = T1 - T0;
1958
    else
1959
        T0 = 0;
1960
    RETURN();
1961
}
1962

    
1963
void OPPROTO op_POWER_dozo (void)
1964
{
1965
    do_POWER_dozo();
1966
    RETURN();
1967
}
1968

    
1969
void OPPROTO op_load_xer_cmp (void)
1970
{
1971
    T2 = xer_cmp;
1972
    RETURN();
1973
}
1974

    
1975
void OPPROTO op_POWER_maskg (void)
1976
{
1977
    do_POWER_maskg();
1978
    RETURN();
1979
}
1980

    
1981
void OPPROTO op_POWER_maskir (void)
1982
{
1983
    T0 = (T0 & ~T2) | (T1 & T2);
1984
    RETURN();
1985
}
1986

    
1987
void OPPROTO op_POWER_mul (void)
1988
{
1989
    uint64_t tmp;
1990

    
1991
    tmp = (uint64_t)T0 * (uint64_t)T1;
1992
    env->spr[SPR_MQ] = tmp >> 32;
1993
    T0 = tmp;
1994
    RETURN();
1995
}
1996

    
1997
void OPPROTO op_POWER_mulo (void)
1998
{
1999
    do_POWER_mulo();
2000
    RETURN();
2001
}
2002

    
2003
void OPPROTO op_POWER_nabs (void)
2004
{
2005
    if (T0 > 0)
2006
        T0 = -T0;
2007
    RETURN();
2008
}
2009

    
2010
void OPPROTO op_POWER_nabso (void)
2011
{
2012
    /* nabs never overflows */
2013
    if (T0 > 0)
2014
        T0 = -T0;
2015
    xer_ov = 0;
2016
    RETURN();
2017
}
2018

    
2019
/* XXX: factorise POWER rotates... */
2020
void OPPROTO op_POWER_rlmi (void)
2021
{
2022
    T0 = rotl32(T0, T2) & PARAM1;
2023
    T0 |= T1 & (uint32_t)PARAM2;
2024
    RETURN();
2025
}
2026

    
2027
void OPPROTO op_POWER_rrib (void)
2028
{
2029
    T2 &= 0x1FUL;
2030
    T0 = rotl32(T0 & INT32_MIN, T2);
2031
    T0 |= T1 & ~rotl32(INT32_MIN, T2);
2032
    RETURN();
2033
}
2034

    
2035
void OPPROTO op_POWER_sle (void)
2036
{
2037
    T1 &= 0x1FUL;
2038
    env->spr[SPR_MQ] = rotl32(T0, T1);
2039
    T0 = T0 << T1;
2040
    RETURN();
2041
}
2042

    
2043
void OPPROTO op_POWER_sleq (void)
2044
{
2045
    uint32_t tmp = env->spr[SPR_MQ];
2046

    
2047
    T1 &= 0x1FUL;
2048
    env->spr[SPR_MQ] = rotl32(T0, T1);
2049
    T0 = T0 << T1;
2050
    T0 |= tmp >> (32 - T1);
2051
    RETURN();
2052
}
2053

    
2054
void OPPROTO op_POWER_sllq (void)
2055
{
2056
    uint32_t msk = UINT32_MAX;
2057

    
2058
    msk = msk << (T1 & 0x1FUL);
2059
    if (T1 & 0x20UL)
2060
        msk = ~msk;
2061
    T1 &= 0x1FUL;
2062
    T0 = (T0 << T1) & msk;
2063
    T0 |= env->spr[SPR_MQ] & ~msk;
2064
    RETURN();
2065
}
2066

    
2067
void OPPROTO op_POWER_slq (void)
2068
{
2069
    uint32_t msk = UINT32_MAX, tmp;
2070

    
2071
    msk = msk << (T1 & 0x1FUL);
2072
    if (T1 & 0x20UL)
2073
        msk = ~msk;
2074
    T1 &= 0x1FUL;
2075
    tmp = rotl32(T0, T1);
2076
    T0 = tmp & msk;
2077
    env->spr[SPR_MQ] = tmp;
2078
    RETURN();
2079
}
2080

    
2081
void OPPROTO op_POWER_sraq (void)
2082
{
2083
    env->spr[SPR_MQ] = rotl32(T0, 32 - (T1 & 0x1FUL));
2084
    if (T1 & 0x20UL)
2085
        T0 = UINT32_MAX;
2086
    else
2087
        T0 = (int32_t)T0 >> T1;
2088
    RETURN();
2089
}
2090

    
2091
void OPPROTO op_POWER_sre (void)
2092
{
2093
    T1 &= 0x1FUL;
2094
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2095
    T0 = (int32_t)T0 >> T1;
2096
    RETURN();
2097
}
2098

    
2099
void OPPROTO op_POWER_srea (void)
2100
{
2101
    T1 &= 0x1FUL;
2102
    env->spr[SPR_MQ] = T0 >> T1;
2103
    T0 = (int32_t)T0 >> T1;
2104
    RETURN();
2105
}
2106

    
2107
void OPPROTO op_POWER_sreq (void)
2108
{
2109
    uint32_t tmp;
2110
    int32_t msk;
2111

    
2112
    T1 &= 0x1FUL;
2113
    msk = INT32_MIN >> T1;
2114
    tmp = env->spr[SPR_MQ];
2115
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2116
    T0 = T0 >> T1;
2117
    T0 |= tmp & msk;
2118
    RETURN();
2119
}
2120

    
2121
void OPPROTO op_POWER_srlq (void)
2122
{
2123
    uint32_t tmp;
2124
    int32_t msk;
2125

    
2126
    msk = INT32_MIN >> (T1 & 0x1FUL);
2127
    if (T1 & 0x20UL)
2128
        msk = ~msk;
2129
    T1 &= 0x1FUL;
2130
    tmp = env->spr[SPR_MQ];
2131
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2132
    T0 = T0 >> T1;
2133
    T0 &= msk;
2134
    T0 |= tmp & ~msk;
2135
    RETURN();
2136
}
2137

    
2138
void OPPROTO op_POWER_srq (void)
2139
{
2140
    T1 &= 0x1FUL;
2141
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2142
    T0 = T0 >> T1;
2143
    RETURN();
2144
}
2145

    
2146
/* POWER instructions not implemented in PowerPC 601 */
2147
#if !defined(CONFIG_USER_ONLY)
2148
void OPPROTO op_POWER_mfsri (void)
2149
{
2150
    T1 = T0 >> 28;
2151
    T0 = env->sr[T1];
2152
    RETURN();
2153
}
2154

    
2155
void OPPROTO op_POWER_rac (void)
2156
{
2157
    do_POWER_rac();
2158
    RETURN();
2159
}
2160

    
2161
void OPPROTO op_POWER_rfsvc (void)
2162
{
2163
    do_POWER_rfsvc();
2164
    RETURN();
2165
}
2166
#endif
2167

    
2168
/* PowerPC 602 specific instruction */
2169
#if !defined(CONFIG_USER_ONLY)
2170
void OPPROTO op_602_mfrom (void)
2171
{
2172
    do_op_602_mfrom();
2173
    RETURN();
2174
}
2175
#endif
2176

    
2177
/* PowerPC 4xx specific micro-ops */
2178
void OPPROTO op_405_add_T0_T2 (void)
2179
{
2180
    T0 = (int32_t)T0 + (int32_t)T2;
2181
    RETURN();
2182
}
2183

    
2184
void OPPROTO op_405_mulchw (void)
2185
{
2186
    T0 = ((int16_t)T0) * ((int16_t)(T1 >> 16));
2187
    RETURN();
2188
}
2189

    
2190
void OPPROTO op_405_mulchwu (void)
2191
{
2192
    T0 = ((uint16_t)T0) * ((uint16_t)(T1 >> 16));
2193
    RETURN();
2194
}
2195

    
2196
void OPPROTO op_405_mulhhw (void)
2197
{
2198
    T0 = ((int16_t)(T0 >> 16)) * ((int16_t)(T1 >> 16));
2199
    RETURN();
2200
}
2201

    
2202
void OPPROTO op_405_mulhhwu (void)
2203
{
2204
    T0 = ((uint16_t)(T0 >> 16)) * ((uint16_t)(T1 >> 16));
2205
    RETURN();
2206
}
2207

    
2208
void OPPROTO op_405_mullhw (void)
2209
{
2210
    T0 = ((int16_t)T0) * ((int16_t)T1);
2211
    RETURN();
2212
}
2213

    
2214
void OPPROTO op_405_mullhwu (void)
2215
{
2216
    T0 = ((uint16_t)T0) * ((uint16_t)T1);
2217
    RETURN();
2218
}
2219

    
2220
void OPPROTO op_405_check_sat (void)
2221
{
2222
    do_405_check_sat();
2223
    RETURN();
2224
}
2225

    
2226
void OPPROTO op_405_check_ovu (void)
2227
{
2228
    if (likely(T0 >= T2)) {
2229
        xer_ov = 0;
2230
    } else {
2231
        xer_ov = 1;
2232
        xer_so = 1;
2233
    }
2234
    RETURN();
2235
}
2236

    
2237
void OPPROTO op_405_check_satu (void)
2238
{
2239
    if (unlikely(T0 < T2)) {
2240
        /* Saturate result */
2241
        T0 = UINT32_MAX;
2242
    }
2243
    RETURN();
2244
}
2245

    
2246
void OPPROTO op_load_dcr (void)
2247
{
2248
    do_load_dcr();
2249
    RETURN();
2250
}
2251

    
2252
void OPPROTO op_store_dcr (void)
2253
{
2254
    do_store_dcr();
2255
    RETURN();
2256
}
2257

    
2258
#if !defined(CONFIG_USER_ONLY)
2259
/* Return from critical interrupt :
2260
 * same as rfi, except nip & MSR are loaded from SRR2/3 instead of SRR0/1
2261
 */
2262
void OPPROTO op_40x_rfci (void)
2263
{
2264
    do_40x_rfci();
2265
    RETURN();
2266
}
2267

    
2268
void OPPROTO op_rfci (void)
2269
{
2270
    do_rfci();
2271
    RETURN();
2272
}
2273

    
2274
void OPPROTO op_rfdi (void)
2275
{
2276
    do_rfdi();
2277
    RETURN();
2278
}
2279

    
2280
void OPPROTO op_rfmci (void)
2281
{
2282
    do_rfmci();
2283
    RETURN();
2284
}
2285

    
2286
void OPPROTO op_wrte (void)
2287
{
2288
    /* We don't call do_store_msr here as we won't trigger
2289
     * any special case nor change hflags
2290
     */
2291
    T0 &= 1 << MSR_EE;
2292
    env->msr &= ~(1 << MSR_EE);
2293
    env->msr |= T0;
2294
    RETURN();
2295
}
2296

    
2297
void OPPROTO op_440_tlbre (void)
2298
{
2299
    do_440_tlbre(PARAM1);
2300
    RETURN();
2301
}
2302

    
2303
void OPPROTO op_440_tlbsx (void)
2304
{
2305
    T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_440_MMUCR] & 0xFF);
2306
    RETURN();
2307
}
2308

    
2309
void OPPROTO op_4xx_tlbsx_check (void)
2310
{
2311
    int tmp;
2312

    
2313
    tmp = xer_so;
2314
    if ((int)T0 != -1)
2315
        tmp |= 0x02;
2316
    env->crf[0] = tmp;
2317
    RETURN();
2318
}
2319

    
2320
void OPPROTO op_440_tlbwe (void)
2321
{
2322
    do_440_tlbwe(PARAM1);
2323
    RETURN();
2324
}
2325

    
2326
void OPPROTO op_4xx_tlbre_lo (void)
2327
{
2328
    do_4xx_tlbre_lo();
2329
    RETURN();
2330
}
2331

    
2332
void OPPROTO op_4xx_tlbre_hi (void)
2333
{
2334
    do_4xx_tlbre_hi();
2335
    RETURN();
2336
}
2337

    
2338
void OPPROTO op_4xx_tlbsx (void)
2339
{
2340
    T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_40x_PID]);
2341
    RETURN();
2342
}
2343

    
2344
void OPPROTO op_4xx_tlbwe_lo (void)
2345
{
2346
    do_4xx_tlbwe_lo();
2347
    RETURN();
2348
}
2349

    
2350
void OPPROTO op_4xx_tlbwe_hi (void)
2351
{
2352
    do_4xx_tlbwe_hi();
2353
    RETURN();
2354
}
2355
#endif
2356

    
2357
/* SPR micro-ops */
2358
/* 440 specific */
2359
void OPPROTO op_440_dlmzb (void)
2360
{
2361
    do_440_dlmzb();
2362
    RETURN();
2363
}
2364

    
2365
void OPPROTO op_440_dlmzb_update_Rc (void)
2366
{
2367
    if (T0 == 8)
2368
        T0 = 0x2;
2369
    else if (T0 < 4)
2370
        T0 = 0x4;
2371
    else
2372
        T0 = 0x8;
2373
    RETURN();
2374
}
2375

    
2376
#if !defined(CONFIG_USER_ONLY)
2377
void OPPROTO op_store_pir (void)
2378
{
2379
    env->spr[SPR_PIR] = T0 & 0x0000000FUL;
2380
    RETURN();
2381
}
2382

    
2383
void OPPROTO op_load_403_pb (void)
2384
{
2385
    do_load_403_pb(PARAM1);
2386
    RETURN();
2387
}
2388

    
2389
void OPPROTO op_store_403_pb (void)
2390
{
2391
    do_store_403_pb(PARAM1);
2392
    RETURN();
2393
}
2394

    
2395
void OPPROTO op_load_40x_pit (void)
2396
{
2397
    T0 = load_40x_pit(env);
2398
    RETURN();
2399
}
2400

    
2401
void OPPROTO op_store_40x_pit (void)
2402
{
2403
    store_40x_pit(env, T0);
2404
    RETURN();
2405
}
2406

    
2407
void OPPROTO op_store_40x_dbcr0 (void)
2408
{
2409
    store_40x_dbcr0(env, T0);
2410
    RETURN();
2411
}
2412

    
2413
void OPPROTO op_store_40x_sler (void)
2414
{
2415
    store_40x_sler(env, T0);
2416
    RETURN();
2417
}
2418

    
2419
void OPPROTO op_store_booke_tcr (void)
2420
{
2421
    store_booke_tcr(env, T0);
2422
    RETURN();
2423
}
2424

    
2425
void OPPROTO op_store_booke_tsr (void)
2426
{
2427
    store_booke_tsr(env, T0);
2428
    RETURN();
2429
}
2430
#endif /* !defined(CONFIG_USER_ONLY) */
2431

    
2432
/* SPE extension */
2433
void OPPROTO op_splatw_T1_64 (void)
2434
{
2435
    T1_64 = (T1_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL);
2436
    RETURN();
2437
}
2438

    
2439
void OPPROTO op_splatwi_T0_64 (void)
2440
{
2441
    uint64_t tmp = PARAM1;
2442

    
2443
    T0_64 = (tmp << 32) | tmp;
2444
    RETURN();
2445
}
2446

    
2447
void OPPROTO op_splatwi_T1_64 (void)
2448
{
2449
    uint64_t tmp = PARAM1;
2450

    
2451
    T1_64 = (tmp << 32) | tmp;
2452
    RETURN();
2453
}
2454

    
2455
void OPPROTO op_extsh_T1_64 (void)
2456
{
2457
    T1_64 = (int32_t)((int16_t)T1_64);
2458
    RETURN();
2459
}
2460

    
2461
void OPPROTO op_sli16_T1_64 (void)
2462
{
2463
    T1_64 = T1_64 << 16;
2464
    RETURN();
2465
}
2466

    
2467
void OPPROTO op_sli32_T1_64 (void)
2468
{
2469
    T1_64 = T1_64 << 32;
2470
    RETURN();
2471
}
2472

    
2473
void OPPROTO op_srli32_T1_64 (void)
2474
{
2475
    T1_64 = T1_64 >> 32;
2476
    RETURN();
2477
}
2478

    
2479
void OPPROTO op_evsel (void)
2480
{
2481
    do_evsel();
2482
    RETURN();
2483
}
2484

    
2485
void OPPROTO op_evaddw (void)
2486
{
2487
    do_evaddw();
2488
    RETURN();
2489
}
2490

    
2491
void OPPROTO op_evsubfw (void)
2492
{
2493
    do_evsubfw();
2494
    RETURN();
2495
}
2496

    
2497
void OPPROTO op_evneg (void)
2498
{
2499
    do_evneg();
2500
    RETURN();
2501
}
2502

    
2503
void OPPROTO op_evabs (void)
2504
{
2505
    do_evabs();
2506
    RETURN();
2507
}
2508

    
2509
void OPPROTO op_evextsh (void)
2510
{
2511
    T0_64 = ((uint64_t)((int32_t)(int16_t)(T0_64 >> 32)) << 32) |
2512
        (uint64_t)((int32_t)(int16_t)T0_64);
2513
    RETURN();
2514
}
2515

    
2516
void OPPROTO op_evextsb (void)
2517
{
2518
    T0_64 = ((uint64_t)((int32_t)(int8_t)(T0_64 >> 32)) << 32) |
2519
        (uint64_t)((int32_t)(int8_t)T0_64);
2520
    RETURN();
2521
}
2522

    
2523
void OPPROTO op_evcntlzw (void)
2524
{
2525
    do_evcntlzw();
2526
    RETURN();
2527
}
2528

    
2529
void OPPROTO op_evrndw (void)
2530
{
2531
    do_evrndw();
2532
    RETURN();
2533
}
2534

    
2535
void OPPROTO op_brinc (void)
2536
{
2537
    do_brinc();
2538
    RETURN();
2539
}
2540

    
2541
void OPPROTO op_evcntlsw (void)
2542
{
2543
    do_evcntlsw();
2544
    RETURN();
2545
}
2546

    
2547
void OPPROTO op_evand (void)
2548
{
2549
    T0_64 &= T1_64;
2550
    RETURN();
2551
}
2552

    
2553
void OPPROTO op_evandc (void)
2554
{
2555
    T0_64 &= ~T1_64;
2556
    RETURN();
2557
}
2558

    
2559
void OPPROTO op_evor (void)
2560
{
2561
    T0_64 |= T1_64;
2562
    RETURN();
2563
}
2564

    
2565
void OPPROTO op_evxor (void)
2566
{
2567
    T0_64 ^= T1_64;
2568
    RETURN();
2569
}
2570

    
2571
void OPPROTO op_eveqv (void)
2572
{
2573
    T0_64 = ~(T0_64 ^ T1_64);
2574
    RETURN();
2575
}
2576

    
2577
void OPPROTO op_evnor (void)
2578
{
2579
    T0_64 = ~(T0_64 | T1_64);
2580
    RETURN();
2581
}
2582

    
2583
void OPPROTO op_evorc (void)
2584
{
2585
    T0_64 |= ~T1_64;
2586
    RETURN();
2587
}
2588

    
2589
void OPPROTO op_evnand (void)
2590
{
2591
    T0_64 = ~(T0_64 & T1_64);
2592
    RETURN();
2593
}
2594

    
2595
void OPPROTO op_evsrws (void)
2596
{
2597
    do_evsrws();
2598
    RETURN();
2599
}
2600

    
2601
void OPPROTO op_evsrwu (void)
2602
{
2603
    do_evsrwu();
2604
    RETURN();
2605
}
2606

    
2607
void OPPROTO op_evslw (void)
2608
{
2609
    do_evslw();
2610
    RETURN();
2611
}
2612

    
2613
void OPPROTO op_evrlw (void)
2614
{
2615
    do_evrlw();
2616
    RETURN();
2617
}
2618

    
2619
void OPPROTO op_evmergelo (void)
2620
{
2621
    T0_64 = (T0_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL);
2622
    RETURN();
2623
}
2624

    
2625
void OPPROTO op_evmergehi (void)
2626
{
2627
    T0_64 = (T0_64 & 0xFFFFFFFF00000000ULL) | (T1_64 >> 32);
2628
    RETURN();
2629
}
2630

    
2631
void OPPROTO op_evmergelohi (void)
2632
{
2633
    T0_64 = (T0_64 << 32) | (T1_64 >> 32);
2634
    RETURN();
2635
}
2636

    
2637
void OPPROTO op_evmergehilo (void)
2638
{
2639
    T0_64 = (T0_64 & 0xFFFFFFFF00000000ULL) | (T1_64 & 0x00000000FFFFFFFFULL);
2640
    RETURN();
2641
}
2642

    
2643
void OPPROTO op_evcmpgts (void)
2644
{
2645
    do_evcmpgts();
2646
    RETURN();
2647
}
2648

    
2649
void OPPROTO op_evcmpgtu (void)
2650
{
2651
    do_evcmpgtu();
2652
    RETURN();
2653
}
2654

    
2655
void OPPROTO op_evcmplts (void)
2656
{
2657
    do_evcmplts();
2658
    RETURN();
2659
}
2660

    
2661
void OPPROTO op_evcmpltu (void)
2662
{
2663
    do_evcmpltu();
2664
    RETURN();
2665
}
2666

    
2667
void OPPROTO op_evcmpeq (void)
2668
{
2669
    do_evcmpeq();
2670
    RETURN();
2671
}
2672

    
2673
void OPPROTO op_evfssub (void)
2674
{
2675
    do_evfssub();
2676
    RETURN();
2677
}
2678

    
2679
void OPPROTO op_evfsadd (void)
2680
{
2681
    do_evfsadd();
2682
    RETURN();
2683
}
2684

    
2685
void OPPROTO op_evfsnabs (void)
2686
{
2687
    do_evfsnabs();
2688
    RETURN();
2689
}
2690

    
2691
void OPPROTO op_evfsabs (void)
2692
{
2693
    do_evfsabs();
2694
    RETURN();
2695
}
2696

    
2697
void OPPROTO op_evfsneg (void)
2698
{
2699
    do_evfsneg();
2700
    RETURN();
2701
}
2702

    
2703
void OPPROTO op_evfsdiv (void)
2704
{
2705
    do_evfsdiv();
2706
    RETURN();
2707
}
2708

    
2709
void OPPROTO op_evfsmul (void)
2710
{
2711
    do_evfsmul();
2712
    RETURN();
2713
}
2714

    
2715
void OPPROTO op_evfscmplt (void)
2716
{
2717
    do_evfscmplt();
2718
    RETURN();
2719
}
2720

    
2721
void OPPROTO op_evfscmpgt (void)
2722
{
2723
    do_evfscmpgt();
2724
    RETURN();
2725
}
2726

    
2727
void OPPROTO op_evfscmpeq (void)
2728
{
2729
    do_evfscmpeq();
2730
    RETURN();
2731
}
2732

    
2733
void OPPROTO op_evfscfsi (void)
2734
{
2735
    do_evfscfsi();
2736
    RETURN();
2737
}
2738

    
2739
void OPPROTO op_evfscfui (void)
2740
{
2741
    do_evfscfui();
2742
    RETURN();
2743
}
2744

    
2745
void OPPROTO op_evfscfsf (void)
2746
{
2747
    do_evfscfsf();
2748
    RETURN();
2749
}
2750

    
2751
void OPPROTO op_evfscfuf (void)
2752
{
2753
    do_evfscfuf();
2754
    RETURN();
2755
}
2756

    
2757
void OPPROTO op_evfsctsi (void)
2758
{
2759
    do_evfsctsi();
2760
    RETURN();
2761
}
2762

    
2763
void OPPROTO op_evfsctui (void)
2764
{
2765
    do_evfsctui();
2766
    RETURN();
2767
}
2768

    
2769
void OPPROTO op_evfsctsf (void)
2770
{
2771
    do_evfsctsf();
2772
    RETURN();
2773
}
2774

    
2775
void OPPROTO op_evfsctuf (void)
2776
{
2777
    do_evfsctuf();
2778
    RETURN();
2779
}
2780

    
2781
void OPPROTO op_evfsctuiz (void)
2782
{
2783
    do_evfsctuiz();
2784
    RETURN();
2785
}
2786

    
2787
void OPPROTO op_evfsctsiz (void)
2788
{
2789
    do_evfsctsiz();
2790
    RETURN();
2791
}
2792

    
2793
void OPPROTO op_evfststlt (void)
2794
{
2795
    do_evfststlt();
2796
    RETURN();
2797
}
2798

    
2799
void OPPROTO op_evfststgt (void)
2800
{
2801
    do_evfststgt();
2802
    RETURN();
2803
}
2804

    
2805
void OPPROTO op_evfststeq (void)
2806
{
2807
    do_evfststeq();
2808
    RETURN();
2809
}
2810

    
2811
void OPPROTO op_efssub (void)
2812
{
2813
    T0_64 = _do_efssub(T0_64, T1_64);
2814
    RETURN();
2815
}
2816

    
2817
void OPPROTO op_efsadd (void)
2818
{
2819
    T0_64 = _do_efsadd(T0_64, T1_64);
2820
    RETURN();
2821
}
2822

    
2823
void OPPROTO op_efsnabs (void)
2824
{
2825
    T0_64 = _do_efsnabs(T0_64);
2826
    RETURN();
2827
}
2828

    
2829
void OPPROTO op_efsabs (void)
2830
{
2831
    T0_64 = _do_efsabs(T0_64);
2832
    RETURN();
2833
}
2834

    
2835
void OPPROTO op_efsneg (void)
2836
{
2837
    T0_64 = _do_efsneg(T0_64);
2838
    RETURN();
2839
}
2840

    
2841
void OPPROTO op_efsdiv (void)
2842
{
2843
    T0_64 = _do_efsdiv(T0_64, T1_64);
2844
    RETURN();
2845
}
2846

    
2847
void OPPROTO op_efsmul (void)
2848
{
2849
    T0_64 = _do_efsmul(T0_64, T1_64);
2850
    RETURN();
2851
}
2852

    
2853
void OPPROTO op_efscmplt (void)
2854
{
2855
    do_efscmplt();
2856
    RETURN();
2857
}
2858

    
2859
void OPPROTO op_efscmpgt (void)
2860
{
2861
    do_efscmpgt();
2862
    RETURN();
2863
}
2864

    
2865
void OPPROTO op_efscfd (void)
2866
{
2867
    do_efscfd();
2868
    RETURN();
2869
}
2870

    
2871
void OPPROTO op_efscmpeq (void)
2872
{
2873
    do_efscmpeq();
2874
    RETURN();
2875
}
2876

    
2877
void OPPROTO op_efscfsi (void)
2878
{
2879
    do_efscfsi();
2880
    RETURN();
2881
}
2882

    
2883
void OPPROTO op_efscfui (void)
2884
{
2885
    do_efscfui();
2886
    RETURN();
2887
}
2888

    
2889
void OPPROTO op_efscfsf (void)
2890
{
2891
    do_efscfsf();
2892
    RETURN();
2893
}
2894

    
2895
void OPPROTO op_efscfuf (void)
2896
{
2897
    do_efscfuf();
2898
    RETURN();
2899
}
2900

    
2901
void OPPROTO op_efsctsi (void)
2902
{
2903
    do_efsctsi();
2904
    RETURN();
2905
}
2906

    
2907
void OPPROTO op_efsctui (void)
2908
{
2909
    do_efsctui();
2910
    RETURN();
2911
}
2912

    
2913
void OPPROTO op_efsctsf (void)
2914
{
2915
    do_efsctsf();
2916
    RETURN();
2917
}
2918

    
2919
void OPPROTO op_efsctuf (void)
2920
{
2921
    do_efsctuf();
2922
    RETURN();
2923
}
2924

    
2925
void OPPROTO op_efsctsiz (void)
2926
{
2927
    do_efsctsiz();
2928
    RETURN();
2929
}
2930

    
2931
void OPPROTO op_efsctuiz (void)
2932
{
2933
    do_efsctuiz();
2934
    RETURN();
2935
}
2936

    
2937
void OPPROTO op_efststlt (void)
2938
{
2939
    T0 = _do_efststlt(T0_64, T1_64);
2940
    RETURN();
2941
}
2942

    
2943
void OPPROTO op_efststgt (void)
2944
{
2945
    T0 = _do_efststgt(T0_64, T1_64);
2946
    RETURN();
2947
}
2948

    
2949
void OPPROTO op_efststeq (void)
2950
{
2951
    T0 = _do_efststeq(T0_64, T1_64);
2952
    RETURN();
2953
}
2954

    
2955
void OPPROTO op_efdsub (void)
2956
{
2957
    CPU_DoubleU u1, u2;
2958
    u1.ll = T0_64;
2959
    u2.ll = T1_64;
2960
    u1.d = float64_sub(u1.d, u2.d, &env->spe_status);
2961
    T0_64 = u1.ll;
2962
    RETURN();
2963
}
2964

    
2965
void OPPROTO op_efdadd (void)
2966
{
2967
    CPU_DoubleU u1, u2;
2968
    u1.ll = T0_64;
2969
    u2.ll = T1_64;
2970
    u1.d = float64_add(u1.d, u2.d, &env->spe_status);
2971
    T0_64 = u1.ll;
2972
    RETURN();
2973
}
2974

    
2975
void OPPROTO op_efdcfsid (void)
2976
{
2977
    do_efdcfsi();
2978
    RETURN();
2979
}
2980

    
2981
void OPPROTO op_efdcfuid (void)
2982
{
2983
    do_efdcfui();
2984
    RETURN();
2985
}
2986

    
2987
void OPPROTO op_efdnabs (void)
2988
{
2989
    T0_64 |= 0x8000000000000000ULL;
2990
    RETURN();
2991
}
2992

    
2993
void OPPROTO op_efdabs (void)
2994
{
2995
    T0_64 &= ~0x8000000000000000ULL;
2996
    RETURN();
2997
}
2998

    
2999
void OPPROTO op_efdneg (void)
3000
{
3001
    T0_64 ^= 0x8000000000000000ULL;
3002
    RETURN();
3003
}
3004

    
3005
void OPPROTO op_efddiv (void)
3006
{
3007
    CPU_DoubleU u1, u2;
3008
    u1.ll = T0_64;
3009
    u2.ll = T1_64;
3010
    u1.d = float64_div(u1.d, u2.d, &env->spe_status);
3011
    T0_64 = u1.ll;
3012
    RETURN();
3013
}
3014

    
3015
void OPPROTO op_efdmul (void)
3016
{
3017
    CPU_DoubleU u1, u2;
3018
    u1.ll = T0_64;
3019
    u2.ll = T1_64;
3020
    u1.d = float64_mul(u1.d, u2.d, &env->spe_status);
3021
    T0_64 = u1.ll;
3022
    RETURN();
3023
}
3024

    
3025
void OPPROTO op_efdctsidz (void)
3026
{
3027
    do_efdctsiz();
3028
    RETURN();
3029
}
3030

    
3031
void OPPROTO op_efdctuidz (void)
3032
{
3033
    do_efdctuiz();
3034
    RETURN();
3035
}
3036

    
3037
void OPPROTO op_efdcmplt (void)
3038
{
3039
    do_efdcmplt();
3040
    RETURN();
3041
}
3042

    
3043
void OPPROTO op_efdcmpgt (void)
3044
{
3045
    do_efdcmpgt();
3046
    RETURN();
3047
}
3048

    
3049
void OPPROTO op_efdcfs (void)
3050
{
3051
    do_efdcfs();
3052
    RETURN();
3053
}
3054

    
3055
void OPPROTO op_efdcmpeq (void)
3056
{
3057
    do_efdcmpeq();
3058
    RETURN();
3059
}
3060

    
3061
void OPPROTO op_efdcfsi (void)
3062
{
3063
    do_efdcfsi();
3064
    RETURN();
3065
}
3066

    
3067
void OPPROTO op_efdcfui (void)
3068
{
3069
    do_efdcfui();
3070
    RETURN();
3071
}
3072

    
3073
void OPPROTO op_efdcfsf (void)
3074
{
3075
    do_efdcfsf();
3076
    RETURN();
3077
}
3078

    
3079
void OPPROTO op_efdcfuf (void)
3080
{
3081
    do_efdcfuf();
3082
    RETURN();
3083
}
3084

    
3085
void OPPROTO op_efdctsi (void)
3086
{
3087
    do_efdctsi();
3088
    RETURN();
3089
}
3090

    
3091
void OPPROTO op_efdctui (void)
3092
{
3093
    do_efdctui();
3094
    RETURN();
3095
}
3096

    
3097
void OPPROTO op_efdctsf (void)
3098
{
3099
    do_efdctsf();
3100
    RETURN();
3101
}
3102

    
3103
void OPPROTO op_efdctuf (void)
3104
{
3105
    do_efdctuf();
3106
    RETURN();
3107
}
3108

    
3109
void OPPROTO op_efdctuiz (void)
3110
{
3111
    do_efdctuiz();
3112
    RETURN();
3113
}
3114

    
3115
void OPPROTO op_efdctsiz (void)
3116
{
3117
    do_efdctsiz();
3118
    RETURN();
3119
}
3120

    
3121
void OPPROTO op_efdtstlt (void)
3122
{
3123
    T0 = _do_efdtstlt(T0_64, T1_64);
3124
    RETURN();
3125
}
3126

    
3127
void OPPROTO op_efdtstgt (void)
3128
{
3129
    T0 = _do_efdtstgt(T0_64, T1_64);
3130
    RETURN();
3131
}
3132

    
3133
void OPPROTO op_efdtsteq (void)
3134
{
3135
    T0 = _do_efdtsteq(T0_64, T1_64);
3136
    RETURN();
3137
}