Statistics
| Branch: | Revision:

root / target-ppc / op.c @ 489251fa

History | View | Annotate | Download (47.1 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_lr (void)
237
{
238
    T0 = env->lr;
239
    RETURN();
240
}
241

    
242
void OPPROTO op_store_lr (void)
243
{
244
    env->lr = T0;
245
    RETURN();
246
}
247

    
248
void OPPROTO op_load_ctr (void)
249
{
250
    T0 = env->ctr;
251
    RETURN();
252
}
253

    
254
void OPPROTO op_store_ctr (void)
255
{
256
    env->ctr = T0;
257
    RETURN();
258
}
259

    
260
void OPPROTO op_load_tbl (void)
261
{
262
    T0 = cpu_ppc_load_tbl(env);
263
    RETURN();
264
}
265

    
266
void OPPROTO op_load_tbu (void)
267
{
268
    T0 = cpu_ppc_load_tbu(env);
269
    RETURN();
270
}
271

    
272
void OPPROTO op_load_atbl (void)
273
{
274
    T0 = cpu_ppc_load_atbl(env);
275
    RETURN();
276
}
277

    
278
void OPPROTO op_load_atbu (void)
279
{
280
    T0 = cpu_ppc_load_atbu(env);
281
    RETURN();
282
}
283

    
284
#if !defined(CONFIG_USER_ONLY)
285
void OPPROTO op_store_tbl (void)
286
{
287
    cpu_ppc_store_tbl(env, T0);
288
    RETURN();
289
}
290

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

    
297
void OPPROTO op_store_atbl (void)
298
{
299
    cpu_ppc_store_atbl(env, T0);
300
    RETURN();
301
}
302

    
303
void OPPROTO op_store_atbu (void)
304
{
305
    cpu_ppc_store_atbu(env, T0);
306
    RETURN();
307
}
308

    
309
void OPPROTO op_load_decr (void)
310
{
311
    T0 = cpu_ppc_load_decr(env);
312
    RETURN();
313
}
314

    
315
void OPPROTO op_store_decr (void)
316
{
317
    cpu_ppc_store_decr(env, T0);
318
    RETURN();
319
}
320

    
321
void OPPROTO op_load_ibat (void)
322
{
323
    T0 = env->IBAT[PARAM1][PARAM2];
324
    RETURN();
325
}
326

    
327
void OPPROTO op_store_ibatu (void)
328
{
329
    do_store_ibatu(env, PARAM1, T0);
330
    RETURN();
331
}
332

    
333
void OPPROTO op_store_ibatl (void)
334
{
335
#if 1
336
    env->IBAT[1][PARAM1] = T0;
337
#else
338
    do_store_ibatl(env, PARAM1, T0);
339
#endif
340
    RETURN();
341
}
342

    
343
void OPPROTO op_load_dbat (void)
344
{
345
    T0 = env->DBAT[PARAM1][PARAM2];
346
    RETURN();
347
}
348

    
349
void OPPROTO op_store_dbatu (void)
350
{
351
    do_store_dbatu(env, PARAM1, T0);
352
    RETURN();
353
}
354

    
355
void OPPROTO op_store_dbatl (void)
356
{
357
#if 1
358
    env->DBAT[1][PARAM1] = T0;
359
#else
360
    do_store_dbatl(env, PARAM1, T0);
361
#endif
362
    RETURN();
363
}
364
#endif /* !defined(CONFIG_USER_ONLY) */
365

    
366
/* FPSCR */
367
#ifdef CONFIG_SOFTFLOAT
368
void OPPROTO op_reset_fpstatus (void)
369
{
370
    env->fp_status.float_exception_flags = 0;
371
    RETURN();
372
}
373
#endif
374

    
375
void OPPROTO op_compute_fprf (void)
376
{
377
    do_compute_fprf(PARAM1);
378
    RETURN();
379
}
380

    
381
#ifdef CONFIG_SOFTFLOAT
382
void OPPROTO op_float_check_status (void)
383
{
384
    do_float_check_status();
385
    RETURN();
386
}
387
#else
388
void OPPROTO op_float_check_status (void)
389
{
390
    if (env->exception_index == POWERPC_EXCP_PROGRAM &&
391
        (env->error_code & POWERPC_EXCP_FP)) {
392
        /* Differred floating-point exception after target FPR update */
393
        if (msr_fe0 != 0 || msr_fe1 != 0)
394
            do_raise_exception_err(env->exception_index, env->error_code);
395
    }
396
    RETURN();
397
}
398
#endif
399

    
400
void OPPROTO op_load_fpscr_FT0 (void)
401
{
402
    /* The 32 MSB of the target fpr are undefined.
403
     * They'll be zero...
404
     */
405
    CPU_DoubleU u;
406

    
407
    u.l.upper = 0;
408
    u.l.lower = env->fpscr;
409
    FT0 = u.d;
410
    RETURN();
411
}
412

    
413
void OPPROTO op_load_fpscr_T0 (void)
414
{
415
    T0 = (env->fpscr >> PARAM1) & 0xF;
416
    RETURN();
417
}
418

    
419
void OPPROTO op_load_fpcc (void)
420
{
421
    T0 = fpscr_fpcc;
422
    RETURN();
423
}
424

    
425
void OPPROTO op_fpscr_resetbit (void)
426
{
427
    env->fpscr &= PARAM1;
428
    RETURN();
429
}
430

    
431
void OPPROTO op_fpscr_setbit (void)
432
{
433
    do_fpscr_setbit(PARAM1);
434
    RETURN();
435
}
436

    
437
void OPPROTO op_store_fpscr (void)
438
{
439
    do_store_fpscr(PARAM1);
440
    RETURN();
441
}
442

    
443
/* Branch */
444
void OPPROTO op_setlr (void)
445
{
446
    env->lr = (uint32_t)PARAM1;
447
    RETURN();
448
}
449

    
450
#if defined (TARGET_PPC64)
451
void OPPROTO op_setlr_64 (void)
452
{
453
    env->lr = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
454
    RETURN();
455
}
456
#endif
457

    
458
void OPPROTO op_jz_T0 (void)
459
{
460
    if (!T0)
461
        GOTO_LABEL_PARAM(1);
462
    RETURN();
463
}
464

    
465
void OPPROTO op_btest_T1 (void)
466
{
467
    if (T0) {
468
        env->nip = (uint32_t)(T1 & ~3);
469
    } else {
470
        env->nip = (uint32_t)PARAM1;
471
    }
472
    RETURN();
473
}
474

    
475
#if defined (TARGET_PPC64)
476
void OPPROTO op_btest_T1_64 (void)
477
{
478
    if (T0) {
479
        env->nip = (uint64_t)(T1 & ~3);
480
    } else {
481
        env->nip = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
482
    }
483
    RETURN();
484
}
485
#endif
486

    
487
void OPPROTO op_movl_T1_ctr (void)
488
{
489
    T1 = env->ctr;
490
    RETURN();
491
}
492

    
493
void OPPROTO op_movl_T1_lr (void)
494
{
495
    T1 = env->lr;
496
    RETURN();
497
}
498

    
499
/* tests with result in T0 */
500
void OPPROTO op_test_ctr (void)
501
{
502
    T0 = (uint32_t)env->ctr;
503
    RETURN();
504
}
505

    
506
#if defined(TARGET_PPC64)
507
void OPPROTO op_test_ctr_64 (void)
508
{
509
    T0 = (uint64_t)env->ctr;
510
    RETURN();
511
}
512
#endif
513

    
514
void OPPROTO op_test_ctr_true (void)
515
{
516
    T0 = ((uint32_t)env->ctr != 0 && (T0 & PARAM1) != 0);
517
    RETURN();
518
}
519

    
520
#if defined(TARGET_PPC64)
521
void OPPROTO op_test_ctr_true_64 (void)
522
{
523
    T0 = ((uint64_t)env->ctr != 0 && (T0 & PARAM1) != 0);
524
    RETURN();
525
}
526
#endif
527

    
528
void OPPROTO op_test_ctr_false (void)
529
{
530
    T0 = ((uint32_t)env->ctr != 0 && (T0 & PARAM1) == 0);
531
    RETURN();
532
}
533

    
534
#if defined(TARGET_PPC64)
535
void OPPROTO op_test_ctr_false_64 (void)
536
{
537
    T0 = ((uint64_t)env->ctr != 0 && (T0 & PARAM1) == 0);
538
    RETURN();
539
}
540
#endif
541

    
542
void OPPROTO op_test_ctrz (void)
543
{
544
    T0 = ((uint32_t)env->ctr == 0);
545
    RETURN();
546
}
547

    
548
#if defined(TARGET_PPC64)
549
void OPPROTO op_test_ctrz_64 (void)
550
{
551
    T0 = ((uint64_t)env->ctr == 0);
552
    RETURN();
553
}
554
#endif
555

    
556
void OPPROTO op_test_ctrz_true (void)
557
{
558
    T0 = ((uint32_t)env->ctr == 0 && (T0 & PARAM1) != 0);
559
    RETURN();
560
}
561

    
562
#if defined(TARGET_PPC64)
563
void OPPROTO op_test_ctrz_true_64 (void)
564
{
565
    T0 = ((uint64_t)env->ctr == 0 && (T0 & PARAM1) != 0);
566
    RETURN();
567
}
568
#endif
569

    
570
void OPPROTO op_test_ctrz_false (void)
571
{
572
    T0 = ((uint32_t)env->ctr == 0 && (T0 & PARAM1) == 0);
573
    RETURN();
574
}
575

    
576
#if defined(TARGET_PPC64)
577
void OPPROTO op_test_ctrz_false_64 (void)
578
{
579
    T0 = ((uint64_t)env->ctr == 0 && (T0 & PARAM1) == 0);
580
    RETURN();
581
}
582
#endif
583

    
584
void OPPROTO op_test_true (void)
585
{
586
    T0 = (T0 & PARAM1);
587
    RETURN();
588
}
589

    
590
void OPPROTO op_test_false (void)
591
{
592
    T0 = ((T0 & PARAM1) == 0);
593
    RETURN();
594
}
595

    
596
/* CTR maintenance */
597
void OPPROTO op_dec_ctr (void)
598
{
599
    env->ctr--;
600
    RETURN();
601
}
602

    
603
/***                           Integer arithmetic                          ***/
604
/* add */
605
void OPPROTO op_add (void)
606
{
607
    T0 += T1;
608
    RETURN();
609
}
610

    
611
void OPPROTO op_check_addo (void)
612
{
613
    xer_ov = (((uint32_t)T2 ^ (uint32_t)T1 ^ UINT32_MAX) &
614
              ((uint32_t)T2 ^ (uint32_t)T0)) >> 31;
615
    xer_so |= xer_ov;
616
    RETURN();
617
}
618

    
619
#if defined(TARGET_PPC64)
620
void OPPROTO op_check_addo_64 (void)
621
{
622
    xer_ov = (((uint64_t)T2 ^ (uint64_t)T1 ^ UINT64_MAX) &
623
              ((uint64_t)T2 ^ (uint64_t)T0)) >> 63;
624
    xer_so |= xer_ov;
625
    RETURN();
626
}
627
#endif
628

    
629
/* add carrying */
630
void OPPROTO op_check_addc (void)
631
{
632
    if (likely((uint32_t)T0 >= (uint32_t)T2)) {
633
        xer_ca = 0;
634
    } else {
635
        xer_ca = 1;
636
    }
637
    RETURN();
638
}
639

    
640
#if defined(TARGET_PPC64)
641
void OPPROTO op_check_addc_64 (void)
642
{
643
    if (likely((uint64_t)T0 >= (uint64_t)T2)) {
644
        xer_ca = 0;
645
    } else {
646
        xer_ca = 1;
647
    }
648
    RETURN();
649
}
650
#endif
651

    
652
/* add extended */
653
void OPPROTO op_adde (void)
654
{
655
    do_adde();
656
    RETURN();
657
}
658

    
659
#if defined(TARGET_PPC64)
660
void OPPROTO op_adde_64 (void)
661
{
662
    do_adde_64();
663
    RETURN();
664
}
665
#endif
666

    
667
/* add immediate */
668
void OPPROTO op_addi (void)
669
{
670
    T0 += (int32_t)PARAM1;
671
    RETURN();
672
}
673

    
674
/* add to minus one extended */
675
void OPPROTO op_add_me (void)
676
{
677
    T0 += xer_ca + (-1);
678
    if (likely((uint32_t)T1 != 0))
679
        xer_ca = 1;
680
    else
681
        xer_ca = 0;
682
    RETURN();
683
}
684

    
685
#if defined(TARGET_PPC64)
686
void OPPROTO op_add_me_64 (void)
687
{
688
    T0 += xer_ca + (-1);
689
    if (likely((uint64_t)T1 != 0))
690
        xer_ca = 1;
691
    else
692
        xer_ca = 0;
693
    RETURN();
694
}
695
#endif
696

    
697
void OPPROTO op_addmeo (void)
698
{
699
    do_addmeo();
700
    RETURN();
701
}
702

    
703
void OPPROTO op_addmeo_64 (void)
704
{
705
    do_addmeo();
706
    RETURN();
707
}
708

    
709
/* add to zero extended */
710
void OPPROTO op_add_ze (void)
711
{
712
    T0 += xer_ca;
713
    RETURN();
714
}
715

    
716
/* divide word */
717
void OPPROTO op_divw (void)
718
{
719
    if (unlikely(((int32_t)T0 == INT32_MIN && (int32_t)T1 == (int32_t)-1) ||
720
                 (int32_t)T1 == 0)) {
721
        T0 = (int32_t)(UINT32_MAX * ((uint32_t)T0 >> 31));
722
    } else {
723
        T0 = (int32_t)T0 / (int32_t)T1;
724
    }
725
    RETURN();
726
}
727

    
728
#if defined(TARGET_PPC64)
729
void OPPROTO op_divd (void)
730
{
731
    if (unlikely(((int64_t)T0 == INT64_MIN && (int64_t)T1 == (int64_t)-1LL) ||
732
                 (int64_t)T1 == 0)) {
733
        T0 = (int64_t)(UINT64_MAX * ((uint64_t)T0 >> 63));
734
    } else {
735
        T0 = (int64_t)T0 / (int64_t)T1;
736
    }
737
    RETURN();
738
}
739
#endif
740

    
741
void OPPROTO op_divwo (void)
742
{
743
    do_divwo();
744
    RETURN();
745
}
746

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

    
755
/* divide word unsigned */
756
void OPPROTO op_divwu (void)
757
{
758
    if (unlikely(T1 == 0)) {
759
        T0 = 0;
760
    } else {
761
        T0 = (uint32_t)T0 / (uint32_t)T1;
762
    }
763
    RETURN();
764
}
765

    
766
#if defined(TARGET_PPC64)
767
void OPPROTO op_divdu (void)
768
{
769
    if (unlikely(T1 == 0)) {
770
        T0 = 0;
771
    } else {
772
        T0 /= T1;
773
    }
774
    RETURN();
775
}
776
#endif
777

    
778
void OPPROTO op_divwuo (void)
779
{
780
    do_divwuo();
781
    RETURN();
782
}
783

    
784
#if defined(TARGET_PPC64)
785
void OPPROTO op_divduo (void)
786
{
787
    do_divduo();
788
    RETURN();
789
}
790
#endif
791

    
792
/* multiply high word */
793
void OPPROTO op_mulhw (void)
794
{
795
    T0 = ((int64_t)((int32_t)T0) * (int64_t)((int32_t)T1)) >> 32;
796
    RETURN();
797
}
798

    
799
#if defined(TARGET_PPC64)
800
void OPPROTO op_mulhd (void)
801
{
802
    uint64_t tl, th;
803

    
804
    muls64(&tl, &th, T0, T1);
805
    T0 = th;
806
    RETURN();
807
}
808
#endif
809

    
810
/* multiply high word unsigned */
811
void OPPROTO op_mulhwu (void)
812
{
813
    T0 = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1) >> 32;
814
    RETURN();
815
}
816

    
817
#if defined(TARGET_PPC64)
818
void OPPROTO op_mulhdu (void)
819
{
820
    uint64_t tl, th;
821

    
822
    mulu64(&tl, &th, T0, T1);
823
    T0 = th;
824
    RETURN();
825
}
826
#endif
827

    
828
/* multiply low immediate */
829
void OPPROTO op_mulli (void)
830
{
831
    T0 = ((int32_t)T0 * (int32_t)PARAM1);
832
    RETURN();
833
}
834

    
835
/* multiply low word */
836
void OPPROTO op_mullw (void)
837
{
838
    T0 = (int32_t)(T0 * T1);
839
    RETURN();
840
}
841

    
842
#if defined(TARGET_PPC64)
843
void OPPROTO op_mulld (void)
844
{
845
    T0 *= T1;
846
    RETURN();
847
}
848
#endif
849

    
850
void OPPROTO op_mullwo (void)
851
{
852
    do_mullwo();
853
    RETURN();
854
}
855

    
856
#if defined(TARGET_PPC64)
857
void OPPROTO op_mulldo (void)
858
{
859
    do_mulldo();
860
    RETURN();
861
}
862
#endif
863

    
864
/* negate */
865
void OPPROTO op_neg (void)
866
{
867
    if (likely(T0 != INT32_MIN)) {
868
        T0 = -(int32_t)T0;
869
    }
870
    RETURN();
871
}
872

    
873
#if defined(TARGET_PPC64)
874
void OPPROTO op_neg_64 (void)
875
{
876
    if (likely(T0 != INT64_MIN)) {
877
        T0 = -(int64_t)T0;
878
    }
879
    RETURN();
880
}
881
#endif
882

    
883
void OPPROTO op_nego (void)
884
{
885
    do_nego();
886
    RETURN();
887
}
888

    
889
#if defined(TARGET_PPC64)
890
void OPPROTO op_nego_64 (void)
891
{
892
    do_nego_64();
893
    RETURN();
894
}
895
#endif
896

    
897
/* subtract from */
898
void OPPROTO op_subf (void)
899
{
900
    T0 = T1 - T0;
901
    RETURN();
902
}
903

    
904
/* subtract from carrying */
905
void OPPROTO op_check_subfc (void)
906
{
907
    if (likely((uint32_t)T0 > (uint32_t)T1)) {
908
        xer_ca = 0;
909
    } else {
910
        xer_ca = 1;
911
    }
912
    RETURN();
913
}
914

    
915
#if defined(TARGET_PPC64)
916
void OPPROTO op_check_subfc_64 (void)
917
{
918
    if (likely((uint64_t)T0 > (uint64_t)T1)) {
919
        xer_ca = 0;
920
    } else {
921
        xer_ca = 1;
922
    }
923
    RETURN();
924
}
925
#endif
926

    
927
/* subtract from extended */
928
void OPPROTO op_subfe (void)
929
{
930
    do_subfe();
931
    RETURN();
932
}
933

    
934
#if defined(TARGET_PPC64)
935
void OPPROTO op_subfe_64 (void)
936
{
937
    do_subfe_64();
938
    RETURN();
939
}
940
#endif
941

    
942
/* subtract from immediate carrying */
943
void OPPROTO op_subfic (void)
944
{
945
    T0 = (int32_t)PARAM1 + ~T0 + 1;
946
    if ((uint32_t)T0 <= (uint32_t)PARAM1) {
947
        xer_ca = 1;
948
    } else {
949
        xer_ca = 0;
950
    }
951
    RETURN();
952
}
953

    
954
#if defined(TARGET_PPC64)
955
void OPPROTO op_subfic_64 (void)
956
{
957
    T0 = (int64_t)PARAM1 + ~T0 + 1;
958
    if ((uint64_t)T0 <= (uint64_t)PARAM1) {
959
        xer_ca = 1;
960
    } else {
961
        xer_ca = 0;
962
    }
963
    RETURN();
964
}
965
#endif
966

    
967
/* subtract from minus one extended */
968
void OPPROTO op_subfme (void)
969
{
970
    T0 = ~T0 + xer_ca - 1;
971
    if (likely((uint32_t)T0 != UINT32_MAX))
972
        xer_ca = 1;
973
    else
974
        xer_ca = 0;
975
    RETURN();
976
}
977

    
978
#if defined(TARGET_PPC64)
979
void OPPROTO op_subfme_64 (void)
980
{
981
    T0 = ~T0 + xer_ca - 1;
982
    if (likely((uint64_t)T0 != UINT64_MAX))
983
        xer_ca = 1;
984
    else
985
        xer_ca = 0;
986
    RETURN();
987
}
988
#endif
989

    
990
void OPPROTO op_subfmeo (void)
991
{
992
    do_subfmeo();
993
    RETURN();
994
}
995

    
996
#if defined(TARGET_PPC64)
997
void OPPROTO op_subfmeo_64 (void)
998
{
999
    do_subfmeo_64();
1000
    RETURN();
1001
}
1002
#endif
1003

    
1004
/* subtract from zero extended */
1005
void OPPROTO op_subfze (void)
1006
{
1007
    T1 = ~T0;
1008
    T0 = T1 + xer_ca;
1009
    if ((uint32_t)T0 < (uint32_t)T1) {
1010
        xer_ca = 1;
1011
    } else {
1012
        xer_ca = 0;
1013
    }
1014
    RETURN();
1015
}
1016

    
1017
#if defined(TARGET_PPC64)
1018
void OPPROTO op_subfze_64 (void)
1019
{
1020
    T1 = ~T0;
1021
    T0 = T1 + xer_ca;
1022
    if ((uint64_t)T0 < (uint64_t)T1) {
1023
        xer_ca = 1;
1024
    } else {
1025
        xer_ca = 0;
1026
    }
1027
    RETURN();
1028
}
1029
#endif
1030

    
1031
void OPPROTO op_subfzeo (void)
1032
{
1033
    do_subfzeo();
1034
    RETURN();
1035
}
1036

    
1037
#if defined(TARGET_PPC64)
1038
void OPPROTO op_subfzeo_64 (void)
1039
{
1040
    do_subfzeo_64();
1041
    RETURN();
1042
}
1043
#endif
1044

    
1045
/***                           Integer comparison                          ***/
1046
/* compare */
1047
void OPPROTO op_cmp (void)
1048
{
1049
    if ((int32_t)T0 < (int32_t)T1) {
1050
        T0 = 0x08;
1051
    } else if ((int32_t)T0 > (int32_t)T1) {
1052
        T0 = 0x04;
1053
    } else {
1054
        T0 = 0x02;
1055
    }
1056
    T0 |= xer_so;
1057
    RETURN();
1058
}
1059

    
1060
#if defined(TARGET_PPC64)
1061
void OPPROTO op_cmp_64 (void)
1062
{
1063
    if ((int64_t)T0 < (int64_t)T1) {
1064
        T0 = 0x08;
1065
    } else if ((int64_t)T0 > (int64_t)T1) {
1066
        T0 = 0x04;
1067
    } else {
1068
        T0 = 0x02;
1069
    }
1070
    T0 |= xer_so;
1071
    RETURN();
1072
}
1073
#endif
1074

    
1075
/* compare immediate */
1076
void OPPROTO op_cmpi (void)
1077
{
1078
    if ((int32_t)T0 < (int32_t)PARAM1) {
1079
        T0 = 0x08;
1080
    } else if ((int32_t)T0 > (int32_t)PARAM1) {
1081
        T0 = 0x04;
1082
    } else {
1083
        T0 = 0x02;
1084
    }
1085
    T0 |= xer_so;
1086
    RETURN();
1087
}
1088

    
1089
#if defined(TARGET_PPC64)
1090
void OPPROTO op_cmpi_64 (void)
1091
{
1092
    if ((int64_t)T0 < (int64_t)((int32_t)PARAM1)) {
1093
        T0 = 0x08;
1094
    } else if ((int64_t)T0 > (int64_t)((int32_t)PARAM1)) {
1095
        T0 = 0x04;
1096
    } else {
1097
        T0 = 0x02;
1098
    }
1099
    T0 |= xer_so;
1100
    RETURN();
1101
}
1102
#endif
1103

    
1104
/* compare logical */
1105
void OPPROTO op_cmpl (void)
1106
{
1107
    if ((uint32_t)T0 < (uint32_t)T1) {
1108
        T0 = 0x08;
1109
    } else if ((uint32_t)T0 > (uint32_t)T1) {
1110
        T0 = 0x04;
1111
    } else {
1112
        T0 = 0x02;
1113
    }
1114
    T0 |= xer_so;
1115
    RETURN();
1116
}
1117

    
1118
#if defined(TARGET_PPC64)
1119
void OPPROTO op_cmpl_64 (void)
1120
{
1121
    if ((uint64_t)T0 < (uint64_t)T1) {
1122
        T0 = 0x08;
1123
    } else if ((uint64_t)T0 > (uint64_t)T1) {
1124
        T0 = 0x04;
1125
    } else {
1126
        T0 = 0x02;
1127
    }
1128
    T0 |= xer_so;
1129
    RETURN();
1130
}
1131
#endif
1132

    
1133
/* compare logical immediate */
1134
void OPPROTO op_cmpli (void)
1135
{
1136
    if ((uint32_t)T0 < (uint32_t)PARAM1) {
1137
        T0 = 0x08;
1138
    } else if ((uint32_t)T0 > (uint32_t)PARAM1) {
1139
        T0 = 0x04;
1140
    } else {
1141
        T0 = 0x02;
1142
    }
1143
    T0 |= xer_so;
1144
    RETURN();
1145
}
1146

    
1147
#if defined(TARGET_PPC64)
1148
void OPPROTO op_cmpli_64 (void)
1149
{
1150
    if ((uint64_t)T0 < (uint64_t)PARAM1) {
1151
        T0 = 0x08;
1152
    } else if ((uint64_t)T0 > (uint64_t)PARAM1) {
1153
        T0 = 0x04;
1154
    } else {
1155
        T0 = 0x02;
1156
    }
1157
    T0 |= xer_so;
1158
    RETURN();
1159
}
1160
#endif
1161

    
1162
void OPPROTO op_isel (void)
1163
{
1164
    if (T0)
1165
        T0 = T1;
1166
    else
1167
        T0 = T2;
1168
    RETURN();
1169
}
1170

    
1171
void OPPROTO op_popcntb (void)
1172
{
1173
    do_popcntb();
1174
    RETURN();
1175
}
1176

    
1177
#if defined(TARGET_PPC64)
1178
void OPPROTO op_popcntb_64 (void)
1179
{
1180
    do_popcntb_64();
1181
    RETURN();
1182
}
1183
#endif
1184

    
1185
/***                            Integer logical                            ***/
1186
/* and */
1187
void OPPROTO op_and (void)
1188
{
1189
    T0 &= T1;
1190
    RETURN();
1191
}
1192

    
1193
/* andc */
1194
void OPPROTO op_andc (void)
1195
{
1196
    T0 &= ~T1;
1197
    RETURN();
1198
}
1199

    
1200
/* andi. */
1201
void OPPROTO op_andi_T0 (void)
1202
{
1203
    T0 &= (uint32_t)PARAM1;
1204
    RETURN();
1205
}
1206

    
1207
void OPPROTO op_andi_T1 (void)
1208
{
1209
    T1 &= (uint32_t)PARAM1;
1210
    RETURN();
1211
}
1212

    
1213
#if defined(TARGET_PPC64)
1214
void OPPROTO op_andi_T0_64 (void)
1215
{
1216
    T0 &= ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
1217
    RETURN();
1218
}
1219

    
1220
void OPPROTO op_andi_T1_64 (void)
1221
{
1222
    T1 &= ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
1223
    RETURN();
1224
}
1225
#endif
1226

    
1227
/* count leading zero */
1228
void OPPROTO op_cntlzw (void)
1229
{
1230
    do_cntlzw();
1231
    RETURN();
1232
}
1233

    
1234
#if defined(TARGET_PPC64)
1235
void OPPROTO op_cntlzd (void)
1236
{
1237
    do_cntlzd();
1238
    RETURN();
1239
}
1240
#endif
1241

    
1242
/* eqv */
1243
void OPPROTO op_eqv (void)
1244
{
1245
    T0 = ~(T0 ^ T1);
1246
    RETURN();
1247
}
1248

    
1249
/* extend sign byte */
1250
void OPPROTO op_extsb (void)
1251
{
1252
#if defined (TARGET_PPC64)
1253
    T0 = (int64_t)((int8_t)T0);
1254
#else
1255
    T0 = (int32_t)((int8_t)T0);
1256
#endif
1257
    RETURN();
1258
}
1259

    
1260
/* extend sign half word */
1261
void OPPROTO op_extsh (void)
1262
{
1263
#if defined (TARGET_PPC64)
1264
    T0 = (int64_t)((int16_t)T0);
1265
#else
1266
    T0 = (int32_t)((int16_t)T0);
1267
#endif
1268
    RETURN();
1269
}
1270

    
1271
#if defined (TARGET_PPC64)
1272
void OPPROTO op_extsw (void)
1273
{
1274
    T0 = (int64_t)((int32_t)T0);
1275
    RETURN();
1276
}
1277
#endif
1278

    
1279
/* nand */
1280
void OPPROTO op_nand (void)
1281
{
1282
    T0 = ~(T0 & T1);
1283
    RETURN();
1284
}
1285

    
1286
/* nor */
1287
void OPPROTO op_nor (void)
1288
{
1289
    T0 = ~(T0 | T1);
1290
    RETURN();
1291
}
1292

    
1293
/* or */
1294
void OPPROTO op_or (void)
1295
{
1296
    T0 |= T1;
1297
    RETURN();
1298
}
1299

    
1300
/* orc */
1301
void OPPROTO op_orc (void)
1302
{
1303
    T0 |= ~T1;
1304
    RETURN();
1305
}
1306

    
1307
/* ori */
1308
void OPPROTO op_ori (void)
1309
{
1310
    T0 |= (uint32_t)PARAM1;
1311
    RETURN();
1312
}
1313

    
1314
/* xor */
1315
void OPPROTO op_xor (void)
1316
{
1317
    T0 ^= T1;
1318
    RETURN();
1319
}
1320

    
1321
/* xori */
1322
void OPPROTO op_xori (void)
1323
{
1324
    T0 ^= (uint32_t)PARAM1;
1325
    RETURN();
1326
}
1327

    
1328
/***                             Integer rotate                            ***/
1329
void OPPROTO op_rotl32_T0_T1 (void)
1330
{
1331
    T0 = rotl32(T0, T1 & 0x1F);
1332
    RETURN();
1333
}
1334

    
1335
void OPPROTO op_rotli32_T0 (void)
1336
{
1337
    T0 = rotl32(T0, PARAM1);
1338
    RETURN();
1339
}
1340

    
1341
#if defined(TARGET_PPC64)
1342
void OPPROTO op_rotl64_T0_T1 (void)
1343
{
1344
    T0 = rotl64(T0, T1 & 0x3F);
1345
    RETURN();
1346
}
1347

    
1348
void OPPROTO op_rotli64_T0 (void)
1349
{
1350
    T0 = rotl64(T0, PARAM1);
1351
    RETURN();
1352
}
1353
#endif
1354

    
1355
/***                             Integer shift                             ***/
1356
/* shift left word */
1357
void OPPROTO op_slw (void)
1358
{
1359
    if (T1 & 0x20) {
1360
        T0 = 0;
1361
    } else {
1362
        T0 = (uint32_t)(T0 << T1);
1363
    }
1364
    RETURN();
1365
}
1366

    
1367
#if defined(TARGET_PPC64)
1368
void OPPROTO op_sld (void)
1369
{
1370
    if (T1 & 0x40) {
1371
        T0 = 0;
1372
    } else {
1373
        T0 = T0 << T1;
1374
    }
1375
    RETURN();
1376
}
1377
#endif
1378

    
1379
/* shift right algebraic word */
1380
void OPPROTO op_sraw (void)
1381
{
1382
    do_sraw();
1383
    RETURN();
1384
}
1385

    
1386
#if defined(TARGET_PPC64)
1387
void OPPROTO op_srad (void)
1388
{
1389
    do_srad();
1390
    RETURN();
1391
}
1392
#endif
1393

    
1394
/* shift right algebraic word immediate */
1395
void OPPROTO op_srawi (void)
1396
{
1397
    uint32_t mask = (uint32_t)PARAM2;
1398

    
1399
    T0 = (int32_t)T0 >> PARAM1;
1400
    if ((int32_t)T1 < 0 && (T1 & mask) != 0) {
1401
        xer_ca = 1;
1402
    } else {
1403
        xer_ca = 0;
1404
    }
1405
    RETURN();
1406
}
1407

    
1408
#if defined(TARGET_PPC64)
1409
void OPPROTO op_sradi (void)
1410
{
1411
    uint64_t mask = ((uint64_t)PARAM2 << 32) | (uint64_t)PARAM3;
1412

    
1413
    T0 = (int64_t)T0 >> PARAM1;
1414
    if ((int64_t)T1 < 0 && ((uint64_t)T1 & mask) != 0) {
1415
        xer_ca = 1;
1416
    } else {
1417
        xer_ca = 0;
1418
    }
1419
    RETURN();
1420
}
1421
#endif
1422

    
1423
/* shift right word */
1424
void OPPROTO op_srw (void)
1425
{
1426
    if (T1 & 0x20) {
1427
        T0 = 0;
1428
    } else {
1429
        T0 = (uint32_t)T0 >> T1;
1430
    }
1431
    RETURN();
1432
}
1433

    
1434
#if defined(TARGET_PPC64)
1435
void OPPROTO op_srd (void)
1436
{
1437
    if (T1 & 0x40) {
1438
        T0 = 0;
1439
    } else {
1440
        T0 = (uint64_t)T0 >> T1;
1441
    }
1442
    RETURN();
1443
}
1444
#endif
1445

    
1446
void OPPROTO op_sl_T0_T1 (void)
1447
{
1448
    T0 = T0 << T1;
1449
    RETURN();
1450
}
1451

    
1452
void OPPROTO op_sli_T0 (void)
1453
{
1454
    T0 = T0 << PARAM1;
1455
    RETURN();
1456
}
1457

    
1458
void OPPROTO op_sli_T1 (void)
1459
{
1460
    T1 = T1 << PARAM1;
1461
    RETURN();
1462
}
1463

    
1464
void OPPROTO op_srl_T0_T1 (void)
1465
{
1466
    T0 = (uint32_t)T0 >> T1;
1467
    RETURN();
1468
}
1469

    
1470
#if defined(TARGET_PPC64)
1471
void OPPROTO op_srl_T0_T1_64 (void)
1472
{
1473
    T0 = (uint32_t)T0 >> T1;
1474
    RETURN();
1475
}
1476
#endif
1477

    
1478
void OPPROTO op_srli_T0 (void)
1479
{
1480
    T0 = (uint32_t)T0 >> PARAM1;
1481
    RETURN();
1482
}
1483

    
1484
#if defined(TARGET_PPC64)
1485
void OPPROTO op_srli_T0_64 (void)
1486
{
1487
    T0 = (uint64_t)T0 >> PARAM1;
1488
    RETURN();
1489
}
1490
#endif
1491

    
1492
void OPPROTO op_srli_T1 (void)
1493
{
1494
    T1 = (uint32_t)T1 >> PARAM1;
1495
    RETURN();
1496
}
1497

    
1498
#if defined(TARGET_PPC64)
1499
void OPPROTO op_srli_T1_64 (void)
1500
{
1501
    T1 = (uint64_t)T1 >> PARAM1;
1502
    RETURN();
1503
}
1504
#endif
1505

    
1506
/***                       Floating-Point arithmetic                       ***/
1507
/* fadd - fadd. */
1508
void OPPROTO op_fadd (void)
1509
{
1510
#if USE_PRECISE_EMULATION
1511
    do_fadd();
1512
#else
1513
    FT0 = float64_add(FT0, FT1, &env->fp_status);
1514
#endif
1515
    RETURN();
1516
}
1517

    
1518
/* fsub - fsub. */
1519
void OPPROTO op_fsub (void)
1520
{
1521
#if USE_PRECISE_EMULATION
1522
    do_fsub();
1523
#else
1524
    FT0 = float64_sub(FT0, FT1, &env->fp_status);
1525
#endif
1526
    RETURN();
1527
}
1528

    
1529
/* fmul - fmul. */
1530
void OPPROTO op_fmul (void)
1531
{
1532
#if USE_PRECISE_EMULATION
1533
    do_fmul();
1534
#else
1535
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1536
#endif
1537
    RETURN();
1538
}
1539

    
1540
/* fdiv - fdiv. */
1541
void OPPROTO op_fdiv (void)
1542
{
1543
#if USE_PRECISE_EMULATION
1544
    do_fdiv();
1545
#else
1546
    FT0 = float64_div(FT0, FT1, &env->fp_status);
1547
#endif
1548
    RETURN();
1549
}
1550

    
1551
/* fsqrt - fsqrt. */
1552
void OPPROTO op_fsqrt (void)
1553
{
1554
    do_fsqrt();
1555
    RETURN();
1556
}
1557

    
1558
/* fre - fre. */
1559
void OPPROTO op_fre (void)
1560
{
1561
    do_fre();
1562
    RETURN();
1563
}
1564

    
1565
/* fres - fres. */
1566
void OPPROTO op_fres (void)
1567
{
1568
    do_fres();
1569
    RETURN();
1570
}
1571

    
1572
/* frsqrte  - frsqrte. */
1573
void OPPROTO op_frsqrte (void)
1574
{
1575
    do_frsqrte();
1576
    RETURN();
1577
}
1578

    
1579
/* fsel - fsel. */
1580
void OPPROTO op_fsel (void)
1581
{
1582
    do_fsel();
1583
    RETURN();
1584
}
1585

    
1586
/***                     Floating-Point multiply-and-add                   ***/
1587
/* fmadd - fmadd. */
1588
void OPPROTO op_fmadd (void)
1589
{
1590
#if USE_PRECISE_EMULATION
1591
    do_fmadd();
1592
#else
1593
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1594
    FT0 = float64_add(FT0, FT2, &env->fp_status);
1595
#endif
1596
    RETURN();
1597
}
1598

    
1599
/* fmsub - fmsub. */
1600
void OPPROTO op_fmsub (void)
1601
{
1602
#if USE_PRECISE_EMULATION
1603
    do_fmsub();
1604
#else
1605
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1606
    FT0 = float64_sub(FT0, FT2, &env->fp_status);
1607
#endif
1608
    RETURN();
1609
}
1610

    
1611
/* fnmadd - fnmadd. - fnmadds - fnmadds. */
1612
void OPPROTO op_fnmadd (void)
1613
{
1614
    do_fnmadd();
1615
    RETURN();
1616
}
1617

    
1618
/* fnmsub - fnmsub. */
1619
void OPPROTO op_fnmsub (void)
1620
{
1621
    do_fnmsub();
1622
    RETURN();
1623
}
1624

    
1625
/***                     Floating-Point round & convert                    ***/
1626
/* frsp - frsp. */
1627
void OPPROTO op_frsp (void)
1628
{
1629
#if USE_PRECISE_EMULATION
1630
    do_frsp();
1631
#else
1632
    FT0 = float64_to_float32(FT0, &env->fp_status);
1633
#endif
1634
    RETURN();
1635
}
1636

    
1637
/* fctiw - fctiw. */
1638
void OPPROTO op_fctiw (void)
1639
{
1640
    do_fctiw();
1641
    RETURN();
1642
}
1643

    
1644
/* fctiwz - fctiwz. */
1645
void OPPROTO op_fctiwz (void)
1646
{
1647
    do_fctiwz();
1648
    RETURN();
1649
}
1650

    
1651
#if defined(TARGET_PPC64)
1652
/* fcfid - fcfid. */
1653
void OPPROTO op_fcfid (void)
1654
{
1655
    do_fcfid();
1656
    RETURN();
1657
}
1658

    
1659
/* fctid - fctid. */
1660
void OPPROTO op_fctid (void)
1661
{
1662
    do_fctid();
1663
    RETURN();
1664
}
1665

    
1666
/* fctidz - fctidz. */
1667
void OPPROTO op_fctidz (void)
1668
{
1669
    do_fctidz();
1670
    RETURN();
1671
}
1672
#endif
1673

    
1674
void OPPROTO op_frin (void)
1675
{
1676
    do_frin();
1677
    RETURN();
1678
}
1679

    
1680
void OPPROTO op_friz (void)
1681
{
1682
    do_friz();
1683
    RETURN();
1684
}
1685

    
1686
void OPPROTO op_frip (void)
1687
{
1688
    do_frip();
1689
    RETURN();
1690
}
1691

    
1692
void OPPROTO op_frim (void)
1693
{
1694
    do_frim();
1695
    RETURN();
1696
}
1697

    
1698
/***                         Floating-Point compare                        ***/
1699
/* fcmpu */
1700
void OPPROTO op_fcmpu (void)
1701
{
1702
    do_fcmpu();
1703
    RETURN();
1704
}
1705

    
1706
/* fcmpo */
1707
void OPPROTO op_fcmpo (void)
1708
{
1709
    do_fcmpo();
1710
    RETURN();
1711
}
1712

    
1713
/***                         Floating-point move                           ***/
1714
/* fabs */
1715
void OPPROTO op_fabs (void)
1716
{
1717
    FT0 = float64_abs(FT0);
1718
    RETURN();
1719
}
1720

    
1721
/* fnabs */
1722
void OPPROTO op_fnabs (void)
1723
{
1724
    FT0 = float64_abs(FT0);
1725
    FT0 = float64_chs(FT0);
1726
    RETURN();
1727
}
1728

    
1729
/* fneg */
1730
void OPPROTO op_fneg (void)
1731
{
1732
    FT0 = float64_chs(FT0);
1733
    RETURN();
1734
}
1735

    
1736
/* Load and store */
1737
#define MEMSUFFIX _raw
1738
#include "op_helper.h"
1739
#include "op_mem.h"
1740
#if !defined(CONFIG_USER_ONLY)
1741
#define MEMSUFFIX _user
1742
#include "op_helper.h"
1743
#include "op_mem.h"
1744
#define MEMSUFFIX _kernel
1745
#include "op_helper.h"
1746
#include "op_mem.h"
1747
#define MEMSUFFIX _hypv
1748
#include "op_helper.h"
1749
#include "op_mem.h"
1750
#endif
1751

    
1752
/* Special op to check and maybe clear reservation */
1753
void OPPROTO op_check_reservation (void)
1754
{
1755
    if ((uint32_t)env->reserve == (uint32_t)(T0 & ~0x00000003))
1756
        env->reserve = (target_ulong)-1ULL;
1757
    RETURN();
1758
}
1759

    
1760
#if defined(TARGET_PPC64)
1761
void OPPROTO op_check_reservation_64 (void)
1762
{
1763
    if ((uint64_t)env->reserve == (uint64_t)(T0 & ~0x00000003))
1764
        env->reserve = (target_ulong)-1ULL;
1765
    RETURN();
1766
}
1767
#endif
1768

    
1769
void OPPROTO op_wait (void)
1770
{
1771
    env->halted = 1;
1772
    RETURN();
1773
}
1774

    
1775
/* Return from interrupt */
1776
#if !defined(CONFIG_USER_ONLY)
1777
void OPPROTO op_rfi (void)
1778
{
1779
    do_rfi();
1780
    RETURN();
1781
}
1782

    
1783
#if defined(TARGET_PPC64)
1784
void OPPROTO op_rfid (void)
1785
{
1786
    do_rfid();
1787
    RETURN();
1788
}
1789

    
1790
void OPPROTO op_hrfid (void)
1791
{
1792
    do_hrfid();
1793
    RETURN();
1794
}
1795
#endif
1796

    
1797
/* Exception vectors */
1798
void OPPROTO op_store_excp_prefix (void)
1799
{
1800
    T0 &= env->ivpr_mask;
1801
    env->excp_prefix = T0;
1802
    RETURN();
1803
}
1804

    
1805
void OPPROTO op_store_excp_vector (void)
1806
{
1807
    T0 &= env->ivor_mask;
1808
    env->excp_vectors[PARAM1] = T0;
1809
    RETURN();
1810
}
1811
#endif
1812

    
1813
/* Trap word */
1814
void OPPROTO op_tw (void)
1815
{
1816
    do_tw(PARAM1);
1817
    RETURN();
1818
}
1819

    
1820
#if defined(TARGET_PPC64)
1821
void OPPROTO op_td (void)
1822
{
1823
    do_td(PARAM1);
1824
    RETURN();
1825
}
1826
#endif
1827

    
1828
#if !defined(CONFIG_USER_ONLY)
1829
/* tlbia */
1830
void OPPROTO op_tlbia (void)
1831
{
1832
    ppc_tlb_invalidate_all(env);
1833
    RETURN();
1834
}
1835

    
1836
/* tlbie */
1837
void OPPROTO op_tlbie (void)
1838
{
1839
    ppc_tlb_invalidate_one(env, (uint32_t)T0);
1840
    RETURN();
1841
}
1842

    
1843
#if defined(TARGET_PPC64)
1844
void OPPROTO op_tlbie_64 (void)
1845
{
1846
    ppc_tlb_invalidate_one(env, T0);
1847
    RETURN();
1848
}
1849
#endif
1850

    
1851
#if defined(TARGET_PPC64)
1852
void OPPROTO op_slbia (void)
1853
{
1854
    ppc_slb_invalidate_all(env);
1855
    RETURN();
1856
}
1857

    
1858
void OPPROTO op_slbie (void)
1859
{
1860
    ppc_slb_invalidate_one(env, (uint32_t)T0);
1861
    RETURN();
1862
}
1863

    
1864
void OPPROTO op_slbie_64 (void)
1865
{
1866
    ppc_slb_invalidate_one(env, T0);
1867
    RETURN();
1868
}
1869
#endif
1870
#endif
1871

    
1872
#if !defined(CONFIG_USER_ONLY)
1873
/* PowerPC 602/603/755 software TLB load instructions */
1874
void OPPROTO op_6xx_tlbld (void)
1875
{
1876
    do_load_6xx_tlb(0);
1877
    RETURN();
1878
}
1879

    
1880
void OPPROTO op_6xx_tlbli (void)
1881
{
1882
    do_load_6xx_tlb(1);
1883
    RETURN();
1884
}
1885

    
1886
/* PowerPC 74xx software TLB load instructions */
1887
void OPPROTO op_74xx_tlbld (void)
1888
{
1889
    do_load_74xx_tlb(0);
1890
    RETURN();
1891
}
1892

    
1893
void OPPROTO op_74xx_tlbli (void)
1894
{
1895
    do_load_74xx_tlb(1);
1896
    RETURN();
1897
}
1898
#endif
1899

    
1900
/* 601 specific */
1901
void OPPROTO op_load_601_rtcl (void)
1902
{
1903
    T0 = cpu_ppc601_load_rtcl(env);
1904
    RETURN();
1905
}
1906

    
1907
void OPPROTO op_load_601_rtcu (void)
1908
{
1909
    T0 = cpu_ppc601_load_rtcu(env);
1910
    RETURN();
1911
}
1912

    
1913
#if !defined(CONFIG_USER_ONLY)
1914
void OPPROTO op_store_601_rtcl (void)
1915
{
1916
    cpu_ppc601_store_rtcl(env, T0);
1917
    RETURN();
1918
}
1919

    
1920
void OPPROTO op_store_601_rtcu (void)
1921
{
1922
    cpu_ppc601_store_rtcu(env, T0);
1923
    RETURN();
1924
}
1925

    
1926
void OPPROTO op_store_hid0_601 (void)
1927
{
1928
    do_store_hid0_601();
1929
    RETURN();
1930
}
1931

    
1932
void OPPROTO op_load_601_bat (void)
1933
{
1934
    T0 = env->IBAT[PARAM1][PARAM2];
1935
    RETURN();
1936
}
1937

    
1938
void OPPROTO op_store_601_batl (void)
1939
{
1940
    do_store_ibatl_601(env, PARAM1, T0);
1941
    RETURN();
1942
}
1943

    
1944
void OPPROTO op_store_601_batu (void)
1945
{
1946
    do_store_ibatu_601(env, PARAM1, T0);
1947
    RETURN();
1948
}
1949
#endif /* !defined(CONFIG_USER_ONLY) */
1950

    
1951
/* PowerPC 601 specific instructions (POWER bridge) */
1952
/* XXX: those micro-ops need tests ! */
1953
void OPPROTO op_POWER_abs (void)
1954
{
1955
    if ((int32_t)T0 == INT32_MIN)
1956
        T0 = INT32_MAX;
1957
    else if ((int32_t)T0 < 0)
1958
        T0 = -T0;
1959
    RETURN();
1960
}
1961

    
1962
void OPPROTO op_POWER_abso (void)
1963
{
1964
    do_POWER_abso();
1965
    RETURN();
1966
}
1967

    
1968
void OPPROTO op_POWER_clcs (void)
1969
{
1970
    do_POWER_clcs();
1971
    RETURN();
1972
}
1973

    
1974
void OPPROTO op_POWER_div (void)
1975
{
1976
    do_POWER_div();
1977
    RETURN();
1978
}
1979

    
1980
void OPPROTO op_POWER_divo (void)
1981
{
1982
    do_POWER_divo();
1983
    RETURN();
1984
}
1985

    
1986
void OPPROTO op_POWER_divs (void)
1987
{
1988
    do_POWER_divs();
1989
    RETURN();
1990
}
1991

    
1992
void OPPROTO op_POWER_divso (void)
1993
{
1994
    do_POWER_divso();
1995
    RETURN();
1996
}
1997

    
1998
void OPPROTO op_POWER_doz (void)
1999
{
2000
    if ((int32_t)T1 > (int32_t)T0)
2001
        T0 = T1 - T0;
2002
    else
2003
        T0 = 0;
2004
    RETURN();
2005
}
2006

    
2007
void OPPROTO op_POWER_dozo (void)
2008
{
2009
    do_POWER_dozo();
2010
    RETURN();
2011
}
2012

    
2013
void OPPROTO op_load_xer_cmp (void)
2014
{
2015
    T2 = xer_cmp;
2016
    RETURN();
2017
}
2018

    
2019
void OPPROTO op_POWER_maskg (void)
2020
{
2021
    do_POWER_maskg();
2022
    RETURN();
2023
}
2024

    
2025
void OPPROTO op_POWER_maskir (void)
2026
{
2027
    T0 = (T0 & ~T2) | (T1 & T2);
2028
    RETURN();
2029
}
2030

    
2031
void OPPROTO op_POWER_mul (void)
2032
{
2033
    uint64_t tmp;
2034

    
2035
    tmp = (uint64_t)T0 * (uint64_t)T1;
2036
    env->spr[SPR_MQ] = tmp >> 32;
2037
    T0 = tmp;
2038
    RETURN();
2039
}
2040

    
2041
void OPPROTO op_POWER_mulo (void)
2042
{
2043
    do_POWER_mulo();
2044
    RETURN();
2045
}
2046

    
2047
void OPPROTO op_POWER_nabs (void)
2048
{
2049
    if (T0 > 0)
2050
        T0 = -T0;
2051
    RETURN();
2052
}
2053

    
2054
void OPPROTO op_POWER_nabso (void)
2055
{
2056
    /* nabs never overflows */
2057
    if (T0 > 0)
2058
        T0 = -T0;
2059
    xer_ov = 0;
2060
    RETURN();
2061
}
2062

    
2063
/* XXX: factorise POWER rotates... */
2064
void OPPROTO op_POWER_rlmi (void)
2065
{
2066
    T0 = rotl32(T0, T2) & PARAM1;
2067
    T0 |= T1 & (uint32_t)PARAM2;
2068
    RETURN();
2069
}
2070

    
2071
void OPPROTO op_POWER_rrib (void)
2072
{
2073
    T2 &= 0x1FUL;
2074
    T0 = rotl32(T0 & INT32_MIN, T2);
2075
    T0 |= T1 & ~rotl32(INT32_MIN, T2);
2076
    RETURN();
2077
}
2078

    
2079
void OPPROTO op_POWER_sle (void)
2080
{
2081
    T1 &= 0x1FUL;
2082
    env->spr[SPR_MQ] = rotl32(T0, T1);
2083
    T0 = T0 << T1;
2084
    RETURN();
2085
}
2086

    
2087
void OPPROTO op_POWER_sleq (void)
2088
{
2089
    uint32_t tmp = env->spr[SPR_MQ];
2090

    
2091
    T1 &= 0x1FUL;
2092
    env->spr[SPR_MQ] = rotl32(T0, T1);
2093
    T0 = T0 << T1;
2094
    T0 |= tmp >> (32 - T1);
2095
    RETURN();
2096
}
2097

    
2098
void OPPROTO op_POWER_sllq (void)
2099
{
2100
    uint32_t msk = UINT32_MAX;
2101

    
2102
    msk = msk << (T1 & 0x1FUL);
2103
    if (T1 & 0x20UL)
2104
        msk = ~msk;
2105
    T1 &= 0x1FUL;
2106
    T0 = (T0 << T1) & msk;
2107
    T0 |= env->spr[SPR_MQ] & ~msk;
2108
    RETURN();
2109
}
2110

    
2111
void OPPROTO op_POWER_slq (void)
2112
{
2113
    uint32_t msk = UINT32_MAX, tmp;
2114

    
2115
    msk = msk << (T1 & 0x1FUL);
2116
    if (T1 & 0x20UL)
2117
        msk = ~msk;
2118
    T1 &= 0x1FUL;
2119
    tmp = rotl32(T0, T1);
2120
    T0 = tmp & msk;
2121
    env->spr[SPR_MQ] = tmp;
2122
    RETURN();
2123
}
2124

    
2125
void OPPROTO op_POWER_sraq (void)
2126
{
2127
    env->spr[SPR_MQ] = rotl32(T0, 32 - (T1 & 0x1FUL));
2128
    if (T1 & 0x20UL)
2129
        T0 = UINT32_MAX;
2130
    else
2131
        T0 = (int32_t)T0 >> T1;
2132
    RETURN();
2133
}
2134

    
2135
void OPPROTO op_POWER_sre (void)
2136
{
2137
    T1 &= 0x1FUL;
2138
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2139
    T0 = (int32_t)T0 >> T1;
2140
    RETURN();
2141
}
2142

    
2143
void OPPROTO op_POWER_srea (void)
2144
{
2145
    T1 &= 0x1FUL;
2146
    env->spr[SPR_MQ] = T0 >> T1;
2147
    T0 = (int32_t)T0 >> T1;
2148
    RETURN();
2149
}
2150

    
2151
void OPPROTO op_POWER_sreq (void)
2152
{
2153
    uint32_t tmp;
2154
    int32_t msk;
2155

    
2156
    T1 &= 0x1FUL;
2157
    msk = INT32_MIN >> T1;
2158
    tmp = env->spr[SPR_MQ];
2159
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2160
    T0 = T0 >> T1;
2161
    T0 |= tmp & msk;
2162
    RETURN();
2163
}
2164

    
2165
void OPPROTO op_POWER_srlq (void)
2166
{
2167
    uint32_t tmp;
2168
    int32_t msk;
2169

    
2170
    msk = INT32_MIN >> (T1 & 0x1FUL);
2171
    if (T1 & 0x20UL)
2172
        msk = ~msk;
2173
    T1 &= 0x1FUL;
2174
    tmp = env->spr[SPR_MQ];
2175
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2176
    T0 = T0 >> T1;
2177
    T0 &= msk;
2178
    T0 |= tmp & ~msk;
2179
    RETURN();
2180
}
2181

    
2182
void OPPROTO op_POWER_srq (void)
2183
{
2184
    T1 &= 0x1FUL;
2185
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2186
    T0 = T0 >> T1;
2187
    RETURN();
2188
}
2189

    
2190
/* POWER instructions not implemented in PowerPC 601 */
2191
#if !defined(CONFIG_USER_ONLY)
2192
void OPPROTO op_POWER_mfsri (void)
2193
{
2194
    T1 = T0 >> 28;
2195
    T0 = env->sr[T1];
2196
    RETURN();
2197
}
2198

    
2199
void OPPROTO op_POWER_rac (void)
2200
{
2201
    do_POWER_rac();
2202
    RETURN();
2203
}
2204

    
2205
void OPPROTO op_POWER_rfsvc (void)
2206
{
2207
    do_POWER_rfsvc();
2208
    RETURN();
2209
}
2210
#endif
2211

    
2212
/* PowerPC 602 specific instruction */
2213
#if !defined(CONFIG_USER_ONLY)
2214
void OPPROTO op_602_mfrom (void)
2215
{
2216
    do_op_602_mfrom();
2217
    RETURN();
2218
}
2219
#endif
2220

    
2221
/* PowerPC 4xx specific micro-ops */
2222
void OPPROTO op_405_add_T0_T2 (void)
2223
{
2224
    T0 = (int32_t)T0 + (int32_t)T2;
2225
    RETURN();
2226
}
2227

    
2228
void OPPROTO op_405_mulchw (void)
2229
{
2230
    T0 = ((int16_t)T0) * ((int16_t)(T1 >> 16));
2231
    RETURN();
2232
}
2233

    
2234
void OPPROTO op_405_mulchwu (void)
2235
{
2236
    T0 = ((uint16_t)T0) * ((uint16_t)(T1 >> 16));
2237
    RETURN();
2238
}
2239

    
2240
void OPPROTO op_405_mulhhw (void)
2241
{
2242
    T0 = ((int16_t)(T0 >> 16)) * ((int16_t)(T1 >> 16));
2243
    RETURN();
2244
}
2245

    
2246
void OPPROTO op_405_mulhhwu (void)
2247
{
2248
    T0 = ((uint16_t)(T0 >> 16)) * ((uint16_t)(T1 >> 16));
2249
    RETURN();
2250
}
2251

    
2252
void OPPROTO op_405_mullhw (void)
2253
{
2254
    T0 = ((int16_t)T0) * ((int16_t)T1);
2255
    RETURN();
2256
}
2257

    
2258
void OPPROTO op_405_mullhwu (void)
2259
{
2260
    T0 = ((uint16_t)T0) * ((uint16_t)T1);
2261
    RETURN();
2262
}
2263

    
2264
void OPPROTO op_405_check_sat (void)
2265
{
2266
    do_405_check_sat();
2267
    RETURN();
2268
}
2269

    
2270
void OPPROTO op_405_check_ovu (void)
2271
{
2272
    if (likely(T0 >= T2)) {
2273
        xer_ov = 0;
2274
    } else {
2275
        xer_ov = 1;
2276
        xer_so = 1;
2277
    }
2278
    RETURN();
2279
}
2280

    
2281
void OPPROTO op_405_check_satu (void)
2282
{
2283
    if (unlikely(T0 < T2)) {
2284
        /* Saturate result */
2285
        T0 = UINT32_MAX;
2286
    }
2287
    RETURN();
2288
}
2289

    
2290
void OPPROTO op_load_dcr (void)
2291
{
2292
    do_load_dcr();
2293
    RETURN();
2294
}
2295

    
2296
void OPPROTO op_store_dcr (void)
2297
{
2298
    do_store_dcr();
2299
    RETURN();
2300
}
2301

    
2302
#if !defined(CONFIG_USER_ONLY)
2303
/* Return from critical interrupt :
2304
 * same as rfi, except nip & MSR are loaded from SRR2/3 instead of SRR0/1
2305
 */
2306
void OPPROTO op_40x_rfci (void)
2307
{
2308
    do_40x_rfci();
2309
    RETURN();
2310
}
2311

    
2312
void OPPROTO op_rfci (void)
2313
{
2314
    do_rfci();
2315
    RETURN();
2316
}
2317

    
2318
void OPPROTO op_rfdi (void)
2319
{
2320
    do_rfdi();
2321
    RETURN();
2322
}
2323

    
2324
void OPPROTO op_rfmci (void)
2325
{
2326
    do_rfmci();
2327
    RETURN();
2328
}
2329

    
2330
void OPPROTO op_wrte (void)
2331
{
2332
    /* We don't call do_store_msr here as we won't trigger
2333
     * any special case nor change hflags
2334
     */
2335
    T0 &= 1 << MSR_EE;
2336
    env->msr &= ~(1 << MSR_EE);
2337
    env->msr |= T0;
2338
    RETURN();
2339
}
2340

    
2341
void OPPROTO op_440_tlbre (void)
2342
{
2343
    do_440_tlbre(PARAM1);
2344
    RETURN();
2345
}
2346

    
2347
void OPPROTO op_440_tlbsx (void)
2348
{
2349
    T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_440_MMUCR] & 0xFF);
2350
    RETURN();
2351
}
2352

    
2353
void OPPROTO op_4xx_tlbsx_check (void)
2354
{
2355
    int tmp;
2356

    
2357
    tmp = xer_so;
2358
    if ((int)T0 != -1)
2359
        tmp |= 0x02;
2360
    env->crf[0] = tmp;
2361
    RETURN();
2362
}
2363

    
2364
void OPPROTO op_440_tlbwe (void)
2365
{
2366
    do_440_tlbwe(PARAM1);
2367
    RETURN();
2368
}
2369

    
2370
void OPPROTO op_4xx_tlbre_lo (void)
2371
{
2372
    do_4xx_tlbre_lo();
2373
    RETURN();
2374
}
2375

    
2376
void OPPROTO op_4xx_tlbre_hi (void)
2377
{
2378
    do_4xx_tlbre_hi();
2379
    RETURN();
2380
}
2381

    
2382
void OPPROTO op_4xx_tlbsx (void)
2383
{
2384
    T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_40x_PID]);
2385
    RETURN();
2386
}
2387

    
2388
void OPPROTO op_4xx_tlbwe_lo (void)
2389
{
2390
    do_4xx_tlbwe_lo();
2391
    RETURN();
2392
}
2393

    
2394
void OPPROTO op_4xx_tlbwe_hi (void)
2395
{
2396
    do_4xx_tlbwe_hi();
2397
    RETURN();
2398
}
2399
#endif
2400

    
2401
/* SPR micro-ops */
2402
/* 440 specific */
2403
void OPPROTO op_440_dlmzb (void)
2404
{
2405
    do_440_dlmzb();
2406
    RETURN();
2407
}
2408

    
2409
void OPPROTO op_440_dlmzb_update_Rc (void)
2410
{
2411
    if (T0 == 8)
2412
        T0 = 0x2;
2413
    else if (T0 < 4)
2414
        T0 = 0x4;
2415
    else
2416
        T0 = 0x8;
2417
    RETURN();
2418
}
2419

    
2420
#if !defined(CONFIG_USER_ONLY)
2421
void OPPROTO op_store_pir (void)
2422
{
2423
    env->spr[SPR_PIR] = T0 & 0x0000000FUL;
2424
    RETURN();
2425
}
2426

    
2427
void OPPROTO op_load_403_pb (void)
2428
{
2429
    do_load_403_pb(PARAM1);
2430
    RETURN();
2431
}
2432

    
2433
void OPPROTO op_store_403_pb (void)
2434
{
2435
    do_store_403_pb(PARAM1);
2436
    RETURN();
2437
}
2438

    
2439
void OPPROTO op_load_40x_pit (void)
2440
{
2441
    T0 = load_40x_pit(env);
2442
    RETURN();
2443
}
2444

    
2445
void OPPROTO op_store_40x_pit (void)
2446
{
2447
    store_40x_pit(env, T0);
2448
    RETURN();
2449
}
2450

    
2451
void OPPROTO op_store_40x_dbcr0 (void)
2452
{
2453
    store_40x_dbcr0(env, T0);
2454
    RETURN();
2455
}
2456

    
2457
void OPPROTO op_store_40x_sler (void)
2458
{
2459
    store_40x_sler(env, T0);
2460
    RETURN();
2461
}
2462

    
2463
void OPPROTO op_store_booke_tcr (void)
2464
{
2465
    store_booke_tcr(env, T0);
2466
    RETURN();
2467
}
2468

    
2469
void OPPROTO op_store_booke_tsr (void)
2470
{
2471
    store_booke_tsr(env, T0);
2472
    RETURN();
2473
}
2474
#endif /* !defined(CONFIG_USER_ONLY) */
2475

    
2476
/* SPE extension */
2477
void OPPROTO op_splatw_T1_64 (void)
2478
{
2479
    T1_64 = (T1_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL);
2480
    RETURN();
2481
}
2482

    
2483
void OPPROTO op_splatwi_T0_64 (void)
2484
{
2485
    uint64_t tmp = PARAM1;
2486

    
2487
    T0_64 = (tmp << 32) | tmp;
2488
    RETURN();
2489
}
2490

    
2491
void OPPROTO op_splatwi_T1_64 (void)
2492
{
2493
    uint64_t tmp = PARAM1;
2494

    
2495
    T1_64 = (tmp << 32) | tmp;
2496
    RETURN();
2497
}
2498

    
2499
void OPPROTO op_extsh_T1_64 (void)
2500
{
2501
    T1_64 = (int32_t)((int16_t)T1_64);
2502
    RETURN();
2503
}
2504

    
2505
void OPPROTO op_sli16_T1_64 (void)
2506
{
2507
    T1_64 = T1_64 << 16;
2508
    RETURN();
2509
}
2510

    
2511
void OPPROTO op_sli32_T1_64 (void)
2512
{
2513
    T1_64 = T1_64 << 32;
2514
    RETURN();
2515
}
2516

    
2517
void OPPROTO op_srli32_T1_64 (void)
2518
{
2519
    T1_64 = T1_64 >> 32;
2520
    RETURN();
2521
}
2522

    
2523
void OPPROTO op_evsel (void)
2524
{
2525
    do_evsel();
2526
    RETURN();
2527
}
2528

    
2529
void OPPROTO op_evaddw (void)
2530
{
2531
    do_evaddw();
2532
    RETURN();
2533
}
2534

    
2535
void OPPROTO op_evsubfw (void)
2536
{
2537
    do_evsubfw();
2538
    RETURN();
2539
}
2540

    
2541
void OPPROTO op_evneg (void)
2542
{
2543
    do_evneg();
2544
    RETURN();
2545
}
2546

    
2547
void OPPROTO op_evabs (void)
2548
{
2549
    do_evabs();
2550
    RETURN();
2551
}
2552

    
2553
void OPPROTO op_evextsh (void)
2554
{
2555
    T0_64 = ((uint64_t)((int32_t)(int16_t)(T0_64 >> 32)) << 32) |
2556
        (uint64_t)((int32_t)(int16_t)T0_64);
2557
    RETURN();
2558
}
2559

    
2560
void OPPROTO op_evextsb (void)
2561
{
2562
    T0_64 = ((uint64_t)((int32_t)(int8_t)(T0_64 >> 32)) << 32) |
2563
        (uint64_t)((int32_t)(int8_t)T0_64);
2564
    RETURN();
2565
}
2566

    
2567
void OPPROTO op_evcntlzw (void)
2568
{
2569
    do_evcntlzw();
2570
    RETURN();
2571
}
2572

    
2573
void OPPROTO op_evrndw (void)
2574
{
2575
    do_evrndw();
2576
    RETURN();
2577
}
2578

    
2579
void OPPROTO op_brinc (void)
2580
{
2581
    do_brinc();
2582
    RETURN();
2583
}
2584

    
2585
void OPPROTO op_evcntlsw (void)
2586
{
2587
    do_evcntlsw();
2588
    RETURN();
2589
}
2590

    
2591
void OPPROTO op_evand (void)
2592
{
2593
    T0_64 &= T1_64;
2594
    RETURN();
2595
}
2596

    
2597
void OPPROTO op_evandc (void)
2598
{
2599
    T0_64 &= ~T1_64;
2600
    RETURN();
2601
}
2602

    
2603
void OPPROTO op_evor (void)
2604
{
2605
    T0_64 |= T1_64;
2606
    RETURN();
2607
}
2608

    
2609
void OPPROTO op_evxor (void)
2610
{
2611
    T0_64 ^= T1_64;
2612
    RETURN();
2613
}
2614

    
2615
void OPPROTO op_eveqv (void)
2616
{
2617
    T0_64 = ~(T0_64 ^ T1_64);
2618
    RETURN();
2619
}
2620

    
2621
void OPPROTO op_evnor (void)
2622
{
2623
    T0_64 = ~(T0_64 | T1_64);
2624
    RETURN();
2625
}
2626

    
2627
void OPPROTO op_evorc (void)
2628
{
2629
    T0_64 |= ~T1_64;
2630
    RETURN();
2631
}
2632

    
2633
void OPPROTO op_evnand (void)
2634
{
2635
    T0_64 = ~(T0_64 & T1_64);
2636
    RETURN();
2637
}
2638

    
2639
void OPPROTO op_evsrws (void)
2640
{
2641
    do_evsrws();
2642
    RETURN();
2643
}
2644

    
2645
void OPPROTO op_evsrwu (void)
2646
{
2647
    do_evsrwu();
2648
    RETURN();
2649
}
2650

    
2651
void OPPROTO op_evslw (void)
2652
{
2653
    do_evslw();
2654
    RETURN();
2655
}
2656

    
2657
void OPPROTO op_evrlw (void)
2658
{
2659
    do_evrlw();
2660
    RETURN();
2661
}
2662

    
2663
void OPPROTO op_evmergelo (void)
2664
{
2665
    T0_64 = (T0_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL);
2666
    RETURN();
2667
}
2668

    
2669
void OPPROTO op_evmergehi (void)
2670
{
2671
    T0_64 = (T0_64 & 0xFFFFFFFF00000000ULL) | (T1_64 >> 32);
2672
    RETURN();
2673
}
2674

    
2675
void OPPROTO op_evmergelohi (void)
2676
{
2677
    T0_64 = (T0_64 << 32) | (T1_64 >> 32);
2678
    RETURN();
2679
}
2680

    
2681
void OPPROTO op_evmergehilo (void)
2682
{
2683
    T0_64 = (T0_64 & 0xFFFFFFFF00000000ULL) | (T1_64 & 0x00000000FFFFFFFFULL);
2684
    RETURN();
2685
}
2686

    
2687
void OPPROTO op_evcmpgts (void)
2688
{
2689
    do_evcmpgts();
2690
    RETURN();
2691
}
2692

    
2693
void OPPROTO op_evcmpgtu (void)
2694
{
2695
    do_evcmpgtu();
2696
    RETURN();
2697
}
2698

    
2699
void OPPROTO op_evcmplts (void)
2700
{
2701
    do_evcmplts();
2702
    RETURN();
2703
}
2704

    
2705
void OPPROTO op_evcmpltu (void)
2706
{
2707
    do_evcmpltu();
2708
    RETURN();
2709
}
2710

    
2711
void OPPROTO op_evcmpeq (void)
2712
{
2713
    do_evcmpeq();
2714
    RETURN();
2715
}
2716

    
2717
void OPPROTO op_evfssub (void)
2718
{
2719
    do_evfssub();
2720
    RETURN();
2721
}
2722

    
2723
void OPPROTO op_evfsadd (void)
2724
{
2725
    do_evfsadd();
2726
    RETURN();
2727
}
2728

    
2729
void OPPROTO op_evfsnabs (void)
2730
{
2731
    do_evfsnabs();
2732
    RETURN();
2733
}
2734

    
2735
void OPPROTO op_evfsabs (void)
2736
{
2737
    do_evfsabs();
2738
    RETURN();
2739
}
2740

    
2741
void OPPROTO op_evfsneg (void)
2742
{
2743
    do_evfsneg();
2744
    RETURN();
2745
}
2746

    
2747
void OPPROTO op_evfsdiv (void)
2748
{
2749
    do_evfsdiv();
2750
    RETURN();
2751
}
2752

    
2753
void OPPROTO op_evfsmul (void)
2754
{
2755
    do_evfsmul();
2756
    RETURN();
2757
}
2758

    
2759
void OPPROTO op_evfscmplt (void)
2760
{
2761
    do_evfscmplt();
2762
    RETURN();
2763
}
2764

    
2765
void OPPROTO op_evfscmpgt (void)
2766
{
2767
    do_evfscmpgt();
2768
    RETURN();
2769
}
2770

    
2771
void OPPROTO op_evfscmpeq (void)
2772
{
2773
    do_evfscmpeq();
2774
    RETURN();
2775
}
2776

    
2777
void OPPROTO op_evfscfsi (void)
2778
{
2779
    do_evfscfsi();
2780
    RETURN();
2781
}
2782

    
2783
void OPPROTO op_evfscfui (void)
2784
{
2785
    do_evfscfui();
2786
    RETURN();
2787
}
2788

    
2789
void OPPROTO op_evfscfsf (void)
2790
{
2791
    do_evfscfsf();
2792
    RETURN();
2793
}
2794

    
2795
void OPPROTO op_evfscfuf (void)
2796
{
2797
    do_evfscfuf();
2798
    RETURN();
2799
}
2800

    
2801
void OPPROTO op_evfsctsi (void)
2802
{
2803
    do_evfsctsi();
2804
    RETURN();
2805
}
2806

    
2807
void OPPROTO op_evfsctui (void)
2808
{
2809
    do_evfsctui();
2810
    RETURN();
2811
}
2812

    
2813
void OPPROTO op_evfsctsf (void)
2814
{
2815
    do_evfsctsf();
2816
    RETURN();
2817
}
2818

    
2819
void OPPROTO op_evfsctuf (void)
2820
{
2821
    do_evfsctuf();
2822
    RETURN();
2823
}
2824

    
2825
void OPPROTO op_evfsctuiz (void)
2826
{
2827
    do_evfsctuiz();
2828
    RETURN();
2829
}
2830

    
2831
void OPPROTO op_evfsctsiz (void)
2832
{
2833
    do_evfsctsiz();
2834
    RETURN();
2835
}
2836

    
2837
void OPPROTO op_evfststlt (void)
2838
{
2839
    do_evfststlt();
2840
    RETURN();
2841
}
2842

    
2843
void OPPROTO op_evfststgt (void)
2844
{
2845
    do_evfststgt();
2846
    RETURN();
2847
}
2848

    
2849
void OPPROTO op_evfststeq (void)
2850
{
2851
    do_evfststeq();
2852
    RETURN();
2853
}
2854

    
2855
void OPPROTO op_efssub (void)
2856
{
2857
    T0_64 = _do_efssub(T0_64, T1_64);
2858
    RETURN();
2859
}
2860

    
2861
void OPPROTO op_efsadd (void)
2862
{
2863
    T0_64 = _do_efsadd(T0_64, T1_64);
2864
    RETURN();
2865
}
2866

    
2867
void OPPROTO op_efsnabs (void)
2868
{
2869
    T0_64 = _do_efsnabs(T0_64);
2870
    RETURN();
2871
}
2872

    
2873
void OPPROTO op_efsabs (void)
2874
{
2875
    T0_64 = _do_efsabs(T0_64);
2876
    RETURN();
2877
}
2878

    
2879
void OPPROTO op_efsneg (void)
2880
{
2881
    T0_64 = _do_efsneg(T0_64);
2882
    RETURN();
2883
}
2884

    
2885
void OPPROTO op_efsdiv (void)
2886
{
2887
    T0_64 = _do_efsdiv(T0_64, T1_64);
2888
    RETURN();
2889
}
2890

    
2891
void OPPROTO op_efsmul (void)
2892
{
2893
    T0_64 = _do_efsmul(T0_64, T1_64);
2894
    RETURN();
2895
}
2896

    
2897
void OPPROTO op_efscmplt (void)
2898
{
2899
    do_efscmplt();
2900
    RETURN();
2901
}
2902

    
2903
void OPPROTO op_efscmpgt (void)
2904
{
2905
    do_efscmpgt();
2906
    RETURN();
2907
}
2908

    
2909
void OPPROTO op_efscfd (void)
2910
{
2911
    do_efscfd();
2912
    RETURN();
2913
}
2914

    
2915
void OPPROTO op_efscmpeq (void)
2916
{
2917
    do_efscmpeq();
2918
    RETURN();
2919
}
2920

    
2921
void OPPROTO op_efscfsi (void)
2922
{
2923
    do_efscfsi();
2924
    RETURN();
2925
}
2926

    
2927
void OPPROTO op_efscfui (void)
2928
{
2929
    do_efscfui();
2930
    RETURN();
2931
}
2932

    
2933
void OPPROTO op_efscfsf (void)
2934
{
2935
    do_efscfsf();
2936
    RETURN();
2937
}
2938

    
2939
void OPPROTO op_efscfuf (void)
2940
{
2941
    do_efscfuf();
2942
    RETURN();
2943
}
2944

    
2945
void OPPROTO op_efsctsi (void)
2946
{
2947
    do_efsctsi();
2948
    RETURN();
2949
}
2950

    
2951
void OPPROTO op_efsctui (void)
2952
{
2953
    do_efsctui();
2954
    RETURN();
2955
}
2956

    
2957
void OPPROTO op_efsctsf (void)
2958
{
2959
    do_efsctsf();
2960
    RETURN();
2961
}
2962

    
2963
void OPPROTO op_efsctuf (void)
2964
{
2965
    do_efsctuf();
2966
    RETURN();
2967
}
2968

    
2969
void OPPROTO op_efsctsiz (void)
2970
{
2971
    do_efsctsiz();
2972
    RETURN();
2973
}
2974

    
2975
void OPPROTO op_efsctuiz (void)
2976
{
2977
    do_efsctuiz();
2978
    RETURN();
2979
}
2980

    
2981
void OPPROTO op_efststlt (void)
2982
{
2983
    T0 = _do_efststlt(T0_64, T1_64);
2984
    RETURN();
2985
}
2986

    
2987
void OPPROTO op_efststgt (void)
2988
{
2989
    T0 = _do_efststgt(T0_64, T1_64);
2990
    RETURN();
2991
}
2992

    
2993
void OPPROTO op_efststeq (void)
2994
{
2995
    T0 = _do_efststeq(T0_64, T1_64);
2996
    RETURN();
2997
}
2998

    
2999
void OPPROTO op_efdsub (void)
3000
{
3001
    CPU_DoubleU u1, u2;
3002
    u1.ll = T0_64;
3003
    u2.ll = T1_64;
3004
    u1.d = float64_sub(u1.d, u2.d, &env->spe_status);
3005
    T0_64 = u1.ll;
3006
    RETURN();
3007
}
3008

    
3009
void OPPROTO op_efdadd (void)
3010
{
3011
    CPU_DoubleU u1, u2;
3012
    u1.ll = T0_64;
3013
    u2.ll = T1_64;
3014
    u1.d = float64_add(u1.d, u2.d, &env->spe_status);
3015
    T0_64 = u1.ll;
3016
    RETURN();
3017
}
3018

    
3019
void OPPROTO op_efdcfsid (void)
3020
{
3021
    do_efdcfsi();
3022
    RETURN();
3023
}
3024

    
3025
void OPPROTO op_efdcfuid (void)
3026
{
3027
    do_efdcfui();
3028
    RETURN();
3029
}
3030

    
3031
void OPPROTO op_efdnabs (void)
3032
{
3033
    T0_64 |= 0x8000000000000000ULL;
3034
    RETURN();
3035
}
3036

    
3037
void OPPROTO op_efdabs (void)
3038
{
3039
    T0_64 &= ~0x8000000000000000ULL;
3040
    RETURN();
3041
}
3042

    
3043
void OPPROTO op_efdneg (void)
3044
{
3045
    T0_64 ^= 0x8000000000000000ULL;
3046
    RETURN();
3047
}
3048

    
3049
void OPPROTO op_efddiv (void)
3050
{
3051
    CPU_DoubleU u1, u2;
3052
    u1.ll = T0_64;
3053
    u2.ll = T1_64;
3054
    u1.d = float64_div(u1.d, u2.d, &env->spe_status);
3055
    T0_64 = u1.ll;
3056
    RETURN();
3057
}
3058

    
3059
void OPPROTO op_efdmul (void)
3060
{
3061
    CPU_DoubleU u1, u2;
3062
    u1.ll = T0_64;
3063
    u2.ll = T1_64;
3064
    u1.d = float64_mul(u1.d, u2.d, &env->spe_status);
3065
    T0_64 = u1.ll;
3066
    RETURN();
3067
}
3068

    
3069
void OPPROTO op_efdctsidz (void)
3070
{
3071
    do_efdctsiz();
3072
    RETURN();
3073
}
3074

    
3075
void OPPROTO op_efdctuidz (void)
3076
{
3077
    do_efdctuiz();
3078
    RETURN();
3079
}
3080

    
3081
void OPPROTO op_efdcmplt (void)
3082
{
3083
    do_efdcmplt();
3084
    RETURN();
3085
}
3086

    
3087
void OPPROTO op_efdcmpgt (void)
3088
{
3089
    do_efdcmpgt();
3090
    RETURN();
3091
}
3092

    
3093
void OPPROTO op_efdcfs (void)
3094
{
3095
    do_efdcfs();
3096
    RETURN();
3097
}
3098

    
3099
void OPPROTO op_efdcmpeq (void)
3100
{
3101
    do_efdcmpeq();
3102
    RETURN();
3103
}
3104

    
3105
void OPPROTO op_efdcfsi (void)
3106
{
3107
    do_efdcfsi();
3108
    RETURN();
3109
}
3110

    
3111
void OPPROTO op_efdcfui (void)
3112
{
3113
    do_efdcfui();
3114
    RETURN();
3115
}
3116

    
3117
void OPPROTO op_efdcfsf (void)
3118
{
3119
    do_efdcfsf();
3120
    RETURN();
3121
}
3122

    
3123
void OPPROTO op_efdcfuf (void)
3124
{
3125
    do_efdcfuf();
3126
    RETURN();
3127
}
3128

    
3129
void OPPROTO op_efdctsi (void)
3130
{
3131
    do_efdctsi();
3132
    RETURN();
3133
}
3134

    
3135
void OPPROTO op_efdctui (void)
3136
{
3137
    do_efdctui();
3138
    RETURN();
3139
}
3140

    
3141
void OPPROTO op_efdctsf (void)
3142
{
3143
    do_efdctsf();
3144
    RETURN();
3145
}
3146

    
3147
void OPPROTO op_efdctuf (void)
3148
{
3149
    do_efdctuf();
3150
    RETURN();
3151
}
3152

    
3153
void OPPROTO op_efdctuiz (void)
3154
{
3155
    do_efdctuiz();
3156
    RETURN();
3157
}
3158

    
3159
void OPPROTO op_efdctsiz (void)
3160
{
3161
    do_efdctsiz();
3162
    RETURN();
3163
}
3164

    
3165
void OPPROTO op_efdtstlt (void)
3166
{
3167
    T0 = _do_efdtstlt(T0_64, T1_64);
3168
    RETURN();
3169
}
3170

    
3171
void OPPROTO op_efdtstgt (void)
3172
{
3173
    T0 = _do_efdtstgt(T0_64, T1_64);
3174
    RETURN();
3175
}
3176

    
3177
void OPPROTO op_efdtsteq (void)
3178
{
3179
    T0 = _do_efdtsteq(T0_64, T1_64);
3180
    RETURN();
3181
}