Statistics
| Branch: | Revision:

root / target-ppc / op.c @ 3a3b925d

History | View | Annotate | Download (46.9 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_check_addo (void)
606
{
607
    xer_ov = (((uint32_t)T2 ^ (uint32_t)T1 ^ UINT32_MAX) &
608
              ((uint32_t)T2 ^ (uint32_t)T0)) >> 31;
609
    xer_so |= xer_ov;
610
    RETURN();
611
}
612

    
613
#if defined(TARGET_PPC64)
614
void OPPROTO op_check_addo_64 (void)
615
{
616
    xer_ov = (((uint64_t)T2 ^ (uint64_t)T1 ^ UINT64_MAX) &
617
              ((uint64_t)T2 ^ (uint64_t)T0)) >> 63;
618
    xer_so |= xer_ov;
619
    RETURN();
620
}
621
#endif
622

    
623
/* add carrying */
624
void OPPROTO op_check_addc (void)
625
{
626
    if (likely((uint32_t)T0 >= (uint32_t)T2)) {
627
        xer_ca = 0;
628
    } else {
629
        xer_ca = 1;
630
    }
631
    RETURN();
632
}
633

    
634
#if defined(TARGET_PPC64)
635
void OPPROTO op_check_addc_64 (void)
636
{
637
    if (likely((uint64_t)T0 >= (uint64_t)T2)) {
638
        xer_ca = 0;
639
    } else {
640
        xer_ca = 1;
641
    }
642
    RETURN();
643
}
644
#endif
645

    
646
/* add extended */
647
void OPPROTO op_adde (void)
648
{
649
    do_adde();
650
    RETURN();
651
}
652

    
653
#if defined(TARGET_PPC64)
654
void OPPROTO op_adde_64 (void)
655
{
656
    do_adde_64();
657
    RETURN();
658
}
659
#endif
660

    
661
/* add to minus one extended */
662
void OPPROTO op_add_me (void)
663
{
664
    T0 += xer_ca + (-1);
665
    if (likely((uint32_t)T1 != 0))
666
        xer_ca = 1;
667
    else
668
        xer_ca = 0;
669
    RETURN();
670
}
671

    
672
#if defined(TARGET_PPC64)
673
void OPPROTO op_add_me_64 (void)
674
{
675
    T0 += xer_ca + (-1);
676
    if (likely((uint64_t)T1 != 0))
677
        xer_ca = 1;
678
    else
679
        xer_ca = 0;
680
    RETURN();
681
}
682
#endif
683

    
684
void OPPROTO op_addmeo (void)
685
{
686
    do_addmeo();
687
    RETURN();
688
}
689

    
690
void OPPROTO op_addmeo_64 (void)
691
{
692
    do_addmeo();
693
    RETURN();
694
}
695

    
696
/* add to zero extended */
697
void OPPROTO op_add_ze (void)
698
{
699
    T0 += xer_ca;
700
    RETURN();
701
}
702

    
703
/* divide word */
704
void OPPROTO op_divw (void)
705
{
706
    if (unlikely(((int32_t)T0 == INT32_MIN && (int32_t)T1 == (int32_t)-1) ||
707
                 (int32_t)T1 == 0)) {
708
        T0 = (int32_t)(UINT32_MAX * ((uint32_t)T0 >> 31));
709
    } else {
710
        T0 = (int32_t)T0 / (int32_t)T1;
711
    }
712
    RETURN();
713
}
714

    
715
#if defined(TARGET_PPC64)
716
void OPPROTO op_divd (void)
717
{
718
    if (unlikely(((int64_t)T0 == INT64_MIN && (int64_t)T1 == (int64_t)-1LL) ||
719
                 (int64_t)T1 == 0)) {
720
        T0 = (int64_t)(UINT64_MAX * ((uint64_t)T0 >> 63));
721
    } else {
722
        T0 = (int64_t)T0 / (int64_t)T1;
723
    }
724
    RETURN();
725
}
726
#endif
727

    
728
void OPPROTO op_divwo (void)
729
{
730
    do_divwo();
731
    RETURN();
732
}
733

    
734
#if defined(TARGET_PPC64)
735
void OPPROTO op_divdo (void)
736
{
737
    do_divdo();
738
    RETURN();
739
}
740
#endif
741

    
742
/* divide word unsigned */
743
void OPPROTO op_divwu (void)
744
{
745
    if (unlikely(T1 == 0)) {
746
        T0 = 0;
747
    } else {
748
        T0 = (uint32_t)T0 / (uint32_t)T1;
749
    }
750
    RETURN();
751
}
752

    
753
#if defined(TARGET_PPC64)
754
void OPPROTO op_divdu (void)
755
{
756
    if (unlikely(T1 == 0)) {
757
        T0 = 0;
758
    } else {
759
        T0 /= T1;
760
    }
761
    RETURN();
762
}
763
#endif
764

    
765
void OPPROTO op_divwuo (void)
766
{
767
    do_divwuo();
768
    RETURN();
769
}
770

    
771
#if defined(TARGET_PPC64)
772
void OPPROTO op_divduo (void)
773
{
774
    do_divduo();
775
    RETURN();
776
}
777
#endif
778

    
779
/* multiply high word */
780
void OPPROTO op_mulhw (void)
781
{
782
    T0 = ((int64_t)((int32_t)T0) * (int64_t)((int32_t)T1)) >> 32;
783
    RETURN();
784
}
785

    
786
#if defined(TARGET_PPC64)
787
void OPPROTO op_mulhd (void)
788
{
789
    uint64_t tl, th;
790

    
791
    muls64(&tl, &th, T0, T1);
792
    T0 = th;
793
    RETURN();
794
}
795
#endif
796

    
797
/* multiply high word unsigned */
798
void OPPROTO op_mulhwu (void)
799
{
800
    T0 = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1) >> 32;
801
    RETURN();
802
}
803

    
804
#if defined(TARGET_PPC64)
805
void OPPROTO op_mulhdu (void)
806
{
807
    uint64_t tl, th;
808

    
809
    mulu64(&tl, &th, T0, T1);
810
    T0 = th;
811
    RETURN();
812
}
813
#endif
814

    
815
/* multiply low immediate */
816
void OPPROTO op_mulli (void)
817
{
818
    T0 = ((int32_t)T0 * (int32_t)PARAM1);
819
    RETURN();
820
}
821

    
822
/* multiply low word */
823
void OPPROTO op_mullw (void)
824
{
825
    T0 = (int32_t)(T0 * T1);
826
    RETURN();
827
}
828

    
829
#if defined(TARGET_PPC64)
830
void OPPROTO op_mulld (void)
831
{
832
    T0 *= T1;
833
    RETURN();
834
}
835
#endif
836

    
837
void OPPROTO op_mullwo (void)
838
{
839
    do_mullwo();
840
    RETURN();
841
}
842

    
843
#if defined(TARGET_PPC64)
844
void OPPROTO op_mulldo (void)
845
{
846
    do_mulldo();
847
    RETURN();
848
}
849
#endif
850

    
851
/* negate */
852
void OPPROTO op_neg (void)
853
{
854
    if (likely(T0 != INT32_MIN)) {
855
        T0 = -(int32_t)T0;
856
    }
857
    RETURN();
858
}
859

    
860
#if defined(TARGET_PPC64)
861
void OPPROTO op_neg_64 (void)
862
{
863
    if (likely(T0 != INT64_MIN)) {
864
        T0 = -(int64_t)T0;
865
    }
866
    RETURN();
867
}
868
#endif
869

    
870
void OPPROTO op_nego (void)
871
{
872
    do_nego();
873
    RETURN();
874
}
875

    
876
#if defined(TARGET_PPC64)
877
void OPPROTO op_nego_64 (void)
878
{
879
    do_nego_64();
880
    RETURN();
881
}
882
#endif
883

    
884
/* subtract from carrying */
885
void OPPROTO op_check_subfc (void)
886
{
887
    if (likely((uint32_t)T0 > (uint32_t)T1)) {
888
        xer_ca = 0;
889
    } else {
890
        xer_ca = 1;
891
    }
892
    RETURN();
893
}
894

    
895
#if defined(TARGET_PPC64)
896
void OPPROTO op_check_subfc_64 (void)
897
{
898
    if (likely((uint64_t)T0 > (uint64_t)T1)) {
899
        xer_ca = 0;
900
    } else {
901
        xer_ca = 1;
902
    }
903
    RETURN();
904
}
905
#endif
906

    
907
/* subtract from extended */
908
void OPPROTO op_subfe (void)
909
{
910
    do_subfe();
911
    RETURN();
912
}
913

    
914
#if defined(TARGET_PPC64)
915
void OPPROTO op_subfe_64 (void)
916
{
917
    do_subfe_64();
918
    RETURN();
919
}
920
#endif
921

    
922
/* subtract from immediate carrying */
923
void OPPROTO op_subfic (void)
924
{
925
    T0 = (int32_t)PARAM1 + ~T0 + 1;
926
    if ((uint32_t)T0 <= (uint32_t)PARAM1) {
927
        xer_ca = 1;
928
    } else {
929
        xer_ca = 0;
930
    }
931
    RETURN();
932
}
933

    
934
#if defined(TARGET_PPC64)
935
void OPPROTO op_subfic_64 (void)
936
{
937
    T0 = (int64_t)PARAM1 + ~T0 + 1;
938
    if ((uint64_t)T0 <= (uint64_t)PARAM1) {
939
        xer_ca = 1;
940
    } else {
941
        xer_ca = 0;
942
    }
943
    RETURN();
944
}
945
#endif
946

    
947
/* subtract from minus one extended */
948
void OPPROTO op_subfme (void)
949
{
950
    T0 = ~T0 + xer_ca - 1;
951
    if (likely((uint32_t)T0 != UINT32_MAX))
952
        xer_ca = 1;
953
    else
954
        xer_ca = 0;
955
    RETURN();
956
}
957

    
958
#if defined(TARGET_PPC64)
959
void OPPROTO op_subfme_64 (void)
960
{
961
    T0 = ~T0 + xer_ca - 1;
962
    if (likely((uint64_t)T0 != UINT64_MAX))
963
        xer_ca = 1;
964
    else
965
        xer_ca = 0;
966
    RETURN();
967
}
968
#endif
969

    
970
void OPPROTO op_subfmeo (void)
971
{
972
    do_subfmeo();
973
    RETURN();
974
}
975

    
976
#if defined(TARGET_PPC64)
977
void OPPROTO op_subfmeo_64 (void)
978
{
979
    do_subfmeo_64();
980
    RETURN();
981
}
982
#endif
983

    
984
/* subtract from zero extended */
985
void OPPROTO op_subfze (void)
986
{
987
    T1 = ~T0;
988
    T0 = T1 + xer_ca;
989
    if ((uint32_t)T0 < (uint32_t)T1) {
990
        xer_ca = 1;
991
    } else {
992
        xer_ca = 0;
993
    }
994
    RETURN();
995
}
996

    
997
#if defined(TARGET_PPC64)
998
void OPPROTO op_subfze_64 (void)
999
{
1000
    T1 = ~T0;
1001
    T0 = T1 + xer_ca;
1002
    if ((uint64_t)T0 < (uint64_t)T1) {
1003
        xer_ca = 1;
1004
    } else {
1005
        xer_ca = 0;
1006
    }
1007
    RETURN();
1008
}
1009
#endif
1010

    
1011
void OPPROTO op_subfzeo (void)
1012
{
1013
    do_subfzeo();
1014
    RETURN();
1015
}
1016

    
1017
#if defined(TARGET_PPC64)
1018
void OPPROTO op_subfzeo_64 (void)
1019
{
1020
    do_subfzeo_64();
1021
    RETURN();
1022
}
1023
#endif
1024

    
1025
/***                           Integer comparison                          ***/
1026
/* compare */
1027
void OPPROTO op_cmp (void)
1028
{
1029
    if ((int32_t)T0 < (int32_t)T1) {
1030
        T0 = 0x08;
1031
    } else if ((int32_t)T0 > (int32_t)T1) {
1032
        T0 = 0x04;
1033
    } else {
1034
        T0 = 0x02;
1035
    }
1036
    T0 |= xer_so;
1037
    RETURN();
1038
}
1039

    
1040
#if defined(TARGET_PPC64)
1041
void OPPROTO op_cmp_64 (void)
1042
{
1043
    if ((int64_t)T0 < (int64_t)T1) {
1044
        T0 = 0x08;
1045
    } else if ((int64_t)T0 > (int64_t)T1) {
1046
        T0 = 0x04;
1047
    } else {
1048
        T0 = 0x02;
1049
    }
1050
    T0 |= xer_so;
1051
    RETURN();
1052
}
1053
#endif
1054

    
1055
/* compare immediate */
1056
void OPPROTO op_cmpi (void)
1057
{
1058
    if ((int32_t)T0 < (int32_t)PARAM1) {
1059
        T0 = 0x08;
1060
    } else if ((int32_t)T0 > (int32_t)PARAM1) {
1061
        T0 = 0x04;
1062
    } else {
1063
        T0 = 0x02;
1064
    }
1065
    T0 |= xer_so;
1066
    RETURN();
1067
}
1068

    
1069
#if defined(TARGET_PPC64)
1070
void OPPROTO op_cmpi_64 (void)
1071
{
1072
    if ((int64_t)T0 < (int64_t)((int32_t)PARAM1)) {
1073
        T0 = 0x08;
1074
    } else if ((int64_t)T0 > (int64_t)((int32_t)PARAM1)) {
1075
        T0 = 0x04;
1076
    } else {
1077
        T0 = 0x02;
1078
    }
1079
    T0 |= xer_so;
1080
    RETURN();
1081
}
1082
#endif
1083

    
1084
/* compare logical */
1085
void OPPROTO op_cmpl (void)
1086
{
1087
    if ((uint32_t)T0 < (uint32_t)T1) {
1088
        T0 = 0x08;
1089
    } else if ((uint32_t)T0 > (uint32_t)T1) {
1090
        T0 = 0x04;
1091
    } else {
1092
        T0 = 0x02;
1093
    }
1094
    T0 |= xer_so;
1095
    RETURN();
1096
}
1097

    
1098
#if defined(TARGET_PPC64)
1099
void OPPROTO op_cmpl_64 (void)
1100
{
1101
    if ((uint64_t)T0 < (uint64_t)T1) {
1102
        T0 = 0x08;
1103
    } else if ((uint64_t)T0 > (uint64_t)T1) {
1104
        T0 = 0x04;
1105
    } else {
1106
        T0 = 0x02;
1107
    }
1108
    T0 |= xer_so;
1109
    RETURN();
1110
}
1111
#endif
1112

    
1113
/* compare logical immediate */
1114
void OPPROTO op_cmpli (void)
1115
{
1116
    if ((uint32_t)T0 < (uint32_t)PARAM1) {
1117
        T0 = 0x08;
1118
    } else if ((uint32_t)T0 > (uint32_t)PARAM1) {
1119
        T0 = 0x04;
1120
    } else {
1121
        T0 = 0x02;
1122
    }
1123
    T0 |= xer_so;
1124
    RETURN();
1125
}
1126

    
1127
#if defined(TARGET_PPC64)
1128
void OPPROTO op_cmpli_64 (void)
1129
{
1130
    if ((uint64_t)T0 < (uint64_t)PARAM1) {
1131
        T0 = 0x08;
1132
    } else if ((uint64_t)T0 > (uint64_t)PARAM1) {
1133
        T0 = 0x04;
1134
    } else {
1135
        T0 = 0x02;
1136
    }
1137
    T0 |= xer_so;
1138
    RETURN();
1139
}
1140
#endif
1141

    
1142
void OPPROTO op_isel (void)
1143
{
1144
    if (T0)
1145
        T0 = T1;
1146
    else
1147
        T0 = T2;
1148
    RETURN();
1149
}
1150

    
1151
void OPPROTO op_popcntb (void)
1152
{
1153
    do_popcntb();
1154
    RETURN();
1155
}
1156

    
1157
#if defined(TARGET_PPC64)
1158
void OPPROTO op_popcntb_64 (void)
1159
{
1160
    do_popcntb_64();
1161
    RETURN();
1162
}
1163
#endif
1164

    
1165
/***                            Integer logical                            ***/
1166
/* and */
1167
void OPPROTO op_and (void)
1168
{
1169
    T0 &= T1;
1170
    RETURN();
1171
}
1172

    
1173
/* andc */
1174
void OPPROTO op_andc (void)
1175
{
1176
    T0 &= ~T1;
1177
    RETURN();
1178
}
1179

    
1180
/* andi. */
1181
void OPPROTO op_andi_T0 (void)
1182
{
1183
    T0 &= (uint32_t)PARAM1;
1184
    RETURN();
1185
}
1186

    
1187
void OPPROTO op_andi_T1 (void)
1188
{
1189
    T1 &= (uint32_t)PARAM1;
1190
    RETURN();
1191
}
1192

    
1193
#if defined(TARGET_PPC64)
1194
void OPPROTO op_andi_T0_64 (void)
1195
{
1196
    T0 &= ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
1197
    RETURN();
1198
}
1199

    
1200
void OPPROTO op_andi_T1_64 (void)
1201
{
1202
    T1 &= ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
1203
    RETURN();
1204
}
1205
#endif
1206

    
1207
/* count leading zero */
1208
void OPPROTO op_cntlzw (void)
1209
{
1210
    do_cntlzw();
1211
    RETURN();
1212
}
1213

    
1214
#if defined(TARGET_PPC64)
1215
void OPPROTO op_cntlzd (void)
1216
{
1217
    do_cntlzd();
1218
    RETURN();
1219
}
1220
#endif
1221

    
1222
/* eqv */
1223
void OPPROTO op_eqv (void)
1224
{
1225
    T0 = ~(T0 ^ T1);
1226
    RETURN();
1227
}
1228

    
1229
/* extend sign byte */
1230
void OPPROTO op_extsb (void)
1231
{
1232
#if defined (TARGET_PPC64)
1233
    T0 = (int64_t)((int8_t)T0);
1234
#else
1235
    T0 = (int32_t)((int8_t)T0);
1236
#endif
1237
    RETURN();
1238
}
1239

    
1240
/* extend sign half word */
1241
void OPPROTO op_extsh (void)
1242
{
1243
#if defined (TARGET_PPC64)
1244
    T0 = (int64_t)((int16_t)T0);
1245
#else
1246
    T0 = (int32_t)((int16_t)T0);
1247
#endif
1248
    RETURN();
1249
}
1250

    
1251
#if defined (TARGET_PPC64)
1252
void OPPROTO op_extsw (void)
1253
{
1254
    T0 = (int64_t)((int32_t)T0);
1255
    RETURN();
1256
}
1257
#endif
1258

    
1259
/* nand */
1260
void OPPROTO op_nand (void)
1261
{
1262
    T0 = ~(T0 & T1);
1263
    RETURN();
1264
}
1265

    
1266
/* nor */
1267
void OPPROTO op_nor (void)
1268
{
1269
    T0 = ~(T0 | T1);
1270
    RETURN();
1271
}
1272

    
1273
/* or */
1274
void OPPROTO op_or (void)
1275
{
1276
    T0 |= T1;
1277
    RETURN();
1278
}
1279

    
1280
/* orc */
1281
void OPPROTO op_orc (void)
1282
{
1283
    T0 |= ~T1;
1284
    RETURN();
1285
}
1286

    
1287
/* ori */
1288
void OPPROTO op_ori (void)
1289
{
1290
    T0 |= (uint32_t)PARAM1;
1291
    RETURN();
1292
}
1293

    
1294
/* xor */
1295
void OPPROTO op_xor (void)
1296
{
1297
    T0 ^= T1;
1298
    RETURN();
1299
}
1300

    
1301
/* xori */
1302
void OPPROTO op_xori (void)
1303
{
1304
    T0 ^= (uint32_t)PARAM1;
1305
    RETURN();
1306
}
1307

    
1308
/***                             Integer rotate                            ***/
1309
void OPPROTO op_rotl32_T0_T1 (void)
1310
{
1311
    T0 = rotl32(T0, T1 & 0x1F);
1312
    RETURN();
1313
}
1314

    
1315
void OPPROTO op_rotli32_T0 (void)
1316
{
1317
    T0 = rotl32(T0, PARAM1);
1318
    RETURN();
1319
}
1320

    
1321
#if defined(TARGET_PPC64)
1322
void OPPROTO op_rotl64_T0_T1 (void)
1323
{
1324
    T0 = rotl64(T0, T1 & 0x3F);
1325
    RETURN();
1326
}
1327

    
1328
void OPPROTO op_rotli64_T0 (void)
1329
{
1330
    T0 = rotl64(T0, PARAM1);
1331
    RETURN();
1332
}
1333
#endif
1334

    
1335
/***                             Integer shift                             ***/
1336
/* shift left word */
1337
void OPPROTO op_slw (void)
1338
{
1339
    if (T1 & 0x20) {
1340
        T0 = 0;
1341
    } else {
1342
        T0 = (uint32_t)(T0 << T1);
1343
    }
1344
    RETURN();
1345
}
1346

    
1347
#if defined(TARGET_PPC64)
1348
void OPPROTO op_sld (void)
1349
{
1350
    if (T1 & 0x40) {
1351
        T0 = 0;
1352
    } else {
1353
        T0 = T0 << T1;
1354
    }
1355
    RETURN();
1356
}
1357
#endif
1358

    
1359
/* shift right algebraic word */
1360
void OPPROTO op_sraw (void)
1361
{
1362
    do_sraw();
1363
    RETURN();
1364
}
1365

    
1366
#if defined(TARGET_PPC64)
1367
void OPPROTO op_srad (void)
1368
{
1369
    do_srad();
1370
    RETURN();
1371
}
1372
#endif
1373

    
1374
/* shift right algebraic word immediate */
1375
void OPPROTO op_srawi (void)
1376
{
1377
    uint32_t mask = (uint32_t)PARAM2;
1378

    
1379
    T0 = (int32_t)T0 >> PARAM1;
1380
    if ((int32_t)T1 < 0 && (T1 & mask) != 0) {
1381
        xer_ca = 1;
1382
    } else {
1383
        xer_ca = 0;
1384
    }
1385
    RETURN();
1386
}
1387

    
1388
#if defined(TARGET_PPC64)
1389
void OPPROTO op_sradi (void)
1390
{
1391
    uint64_t mask = ((uint64_t)PARAM2 << 32) | (uint64_t)PARAM3;
1392

    
1393
    T0 = (int64_t)T0 >> PARAM1;
1394
    if ((int64_t)T1 < 0 && ((uint64_t)T1 & mask) != 0) {
1395
        xer_ca = 1;
1396
    } else {
1397
        xer_ca = 0;
1398
    }
1399
    RETURN();
1400
}
1401
#endif
1402

    
1403
/* shift right word */
1404
void OPPROTO op_srw (void)
1405
{
1406
    if (T1 & 0x20) {
1407
        T0 = 0;
1408
    } else {
1409
        T0 = (uint32_t)T0 >> T1;
1410
    }
1411
    RETURN();
1412
}
1413

    
1414
#if defined(TARGET_PPC64)
1415
void OPPROTO op_srd (void)
1416
{
1417
    if (T1 & 0x40) {
1418
        T0 = 0;
1419
    } else {
1420
        T0 = (uint64_t)T0 >> T1;
1421
    }
1422
    RETURN();
1423
}
1424
#endif
1425

    
1426
void OPPROTO op_sl_T0_T1 (void)
1427
{
1428
    T0 = T0 << T1;
1429
    RETURN();
1430
}
1431

    
1432
void OPPROTO op_sli_T0 (void)
1433
{
1434
    T0 = T0 << PARAM1;
1435
    RETURN();
1436
}
1437

    
1438
void OPPROTO op_sli_T1 (void)
1439
{
1440
    T1 = T1 << PARAM1;
1441
    RETURN();
1442
}
1443

    
1444
void OPPROTO op_srl_T0_T1 (void)
1445
{
1446
    T0 = (uint32_t)T0 >> T1;
1447
    RETURN();
1448
}
1449

    
1450
#if defined(TARGET_PPC64)
1451
void OPPROTO op_srl_T0_T1_64 (void)
1452
{
1453
    T0 = (uint32_t)T0 >> T1;
1454
    RETURN();
1455
}
1456
#endif
1457

    
1458
void OPPROTO op_srli_T0 (void)
1459
{
1460
    T0 = (uint32_t)T0 >> PARAM1;
1461
    RETURN();
1462
}
1463

    
1464
#if defined(TARGET_PPC64)
1465
void OPPROTO op_srli_T0_64 (void)
1466
{
1467
    T0 = (uint64_t)T0 >> PARAM1;
1468
    RETURN();
1469
}
1470
#endif
1471

    
1472
void OPPROTO op_srli_T1 (void)
1473
{
1474
    T1 = (uint32_t)T1 >> PARAM1;
1475
    RETURN();
1476
}
1477

    
1478
#if defined(TARGET_PPC64)
1479
void OPPROTO op_srli_T1_64 (void)
1480
{
1481
    T1 = (uint64_t)T1 >> PARAM1;
1482
    RETURN();
1483
}
1484
#endif
1485

    
1486
/***                       Floating-Point arithmetic                       ***/
1487
/* fadd - fadd. */
1488
void OPPROTO op_fadd (void)
1489
{
1490
#if USE_PRECISE_EMULATION
1491
    do_fadd();
1492
#else
1493
    FT0 = float64_add(FT0, FT1, &env->fp_status);
1494
#endif
1495
    RETURN();
1496
}
1497

    
1498
/* fsub - fsub. */
1499
void OPPROTO op_fsub (void)
1500
{
1501
#if USE_PRECISE_EMULATION
1502
    do_fsub();
1503
#else
1504
    FT0 = float64_sub(FT0, FT1, &env->fp_status);
1505
#endif
1506
    RETURN();
1507
}
1508

    
1509
/* fmul - fmul. */
1510
void OPPROTO op_fmul (void)
1511
{
1512
#if USE_PRECISE_EMULATION
1513
    do_fmul();
1514
#else
1515
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1516
#endif
1517
    RETURN();
1518
}
1519

    
1520
/* fdiv - fdiv. */
1521
void OPPROTO op_fdiv (void)
1522
{
1523
#if USE_PRECISE_EMULATION
1524
    do_fdiv();
1525
#else
1526
    FT0 = float64_div(FT0, FT1, &env->fp_status);
1527
#endif
1528
    RETURN();
1529
}
1530

    
1531
/* fsqrt - fsqrt. */
1532
void OPPROTO op_fsqrt (void)
1533
{
1534
    do_fsqrt();
1535
    RETURN();
1536
}
1537

    
1538
/* fre - fre. */
1539
void OPPROTO op_fre (void)
1540
{
1541
    do_fre();
1542
    RETURN();
1543
}
1544

    
1545
/* fres - fres. */
1546
void OPPROTO op_fres (void)
1547
{
1548
    do_fres();
1549
    RETURN();
1550
}
1551

    
1552
/* frsqrte  - frsqrte. */
1553
void OPPROTO op_frsqrte (void)
1554
{
1555
    do_frsqrte();
1556
    RETURN();
1557
}
1558

    
1559
/* fsel - fsel. */
1560
void OPPROTO op_fsel (void)
1561
{
1562
    do_fsel();
1563
    RETURN();
1564
}
1565

    
1566
/***                     Floating-Point multiply-and-add                   ***/
1567
/* fmadd - fmadd. */
1568
void OPPROTO op_fmadd (void)
1569
{
1570
#if USE_PRECISE_EMULATION
1571
    do_fmadd();
1572
#else
1573
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1574
    FT0 = float64_add(FT0, FT2, &env->fp_status);
1575
#endif
1576
    RETURN();
1577
}
1578

    
1579
/* fmsub - fmsub. */
1580
void OPPROTO op_fmsub (void)
1581
{
1582
#if USE_PRECISE_EMULATION
1583
    do_fmsub();
1584
#else
1585
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1586
    FT0 = float64_sub(FT0, FT2, &env->fp_status);
1587
#endif
1588
    RETURN();
1589
}
1590

    
1591
/* fnmadd - fnmadd. - fnmadds - fnmadds. */
1592
void OPPROTO op_fnmadd (void)
1593
{
1594
    do_fnmadd();
1595
    RETURN();
1596
}
1597

    
1598
/* fnmsub - fnmsub. */
1599
void OPPROTO op_fnmsub (void)
1600
{
1601
    do_fnmsub();
1602
    RETURN();
1603
}
1604

    
1605
/***                     Floating-Point round & convert                    ***/
1606
/* frsp - frsp. */
1607
void OPPROTO op_frsp (void)
1608
{
1609
#if USE_PRECISE_EMULATION
1610
    do_frsp();
1611
#else
1612
    FT0 = float64_to_float32(FT0, &env->fp_status);
1613
#endif
1614
    RETURN();
1615
}
1616

    
1617
/* fctiw - fctiw. */
1618
void OPPROTO op_fctiw (void)
1619
{
1620
    do_fctiw();
1621
    RETURN();
1622
}
1623

    
1624
/* fctiwz - fctiwz. */
1625
void OPPROTO op_fctiwz (void)
1626
{
1627
    do_fctiwz();
1628
    RETURN();
1629
}
1630

    
1631
#if defined(TARGET_PPC64)
1632
/* fcfid - fcfid. */
1633
void OPPROTO op_fcfid (void)
1634
{
1635
    do_fcfid();
1636
    RETURN();
1637
}
1638

    
1639
/* fctid - fctid. */
1640
void OPPROTO op_fctid (void)
1641
{
1642
    do_fctid();
1643
    RETURN();
1644
}
1645

    
1646
/* fctidz - fctidz. */
1647
void OPPROTO op_fctidz (void)
1648
{
1649
    do_fctidz();
1650
    RETURN();
1651
}
1652
#endif
1653

    
1654
void OPPROTO op_frin (void)
1655
{
1656
    do_frin();
1657
    RETURN();
1658
}
1659

    
1660
void OPPROTO op_friz (void)
1661
{
1662
    do_friz();
1663
    RETURN();
1664
}
1665

    
1666
void OPPROTO op_frip (void)
1667
{
1668
    do_frip();
1669
    RETURN();
1670
}
1671

    
1672
void OPPROTO op_frim (void)
1673
{
1674
    do_frim();
1675
    RETURN();
1676
}
1677

    
1678
/***                         Floating-Point compare                        ***/
1679
/* fcmpu */
1680
void OPPROTO op_fcmpu (void)
1681
{
1682
    do_fcmpu();
1683
    RETURN();
1684
}
1685

    
1686
/* fcmpo */
1687
void OPPROTO op_fcmpo (void)
1688
{
1689
    do_fcmpo();
1690
    RETURN();
1691
}
1692

    
1693
/***                         Floating-point move                           ***/
1694
/* fabs */
1695
void OPPROTO op_fabs (void)
1696
{
1697
    FT0 = float64_abs(FT0);
1698
    RETURN();
1699
}
1700

    
1701
/* fnabs */
1702
void OPPROTO op_fnabs (void)
1703
{
1704
    FT0 = float64_abs(FT0);
1705
    FT0 = float64_chs(FT0);
1706
    RETURN();
1707
}
1708

    
1709
/* fneg */
1710
void OPPROTO op_fneg (void)
1711
{
1712
    FT0 = float64_chs(FT0);
1713
    RETURN();
1714
}
1715

    
1716
/* Load and store */
1717
#define MEMSUFFIX _raw
1718
#include "op_helper.h"
1719
#include "op_mem.h"
1720
#if !defined(CONFIG_USER_ONLY)
1721
#define MEMSUFFIX _user
1722
#include "op_helper.h"
1723
#include "op_mem.h"
1724
#define MEMSUFFIX _kernel
1725
#include "op_helper.h"
1726
#include "op_mem.h"
1727
#define MEMSUFFIX _hypv
1728
#include "op_helper.h"
1729
#include "op_mem.h"
1730
#endif
1731

    
1732
/* Special op to check and maybe clear reservation */
1733
void OPPROTO op_check_reservation (void)
1734
{
1735
    if ((uint32_t)env->reserve == (uint32_t)(T0 & ~0x00000003))
1736
        env->reserve = (target_ulong)-1ULL;
1737
    RETURN();
1738
}
1739

    
1740
#if defined(TARGET_PPC64)
1741
void OPPROTO op_check_reservation_64 (void)
1742
{
1743
    if ((uint64_t)env->reserve == (uint64_t)(T0 & ~0x00000003))
1744
        env->reserve = (target_ulong)-1ULL;
1745
    RETURN();
1746
}
1747
#endif
1748

    
1749
void OPPROTO op_wait (void)
1750
{
1751
    env->halted = 1;
1752
    RETURN();
1753
}
1754

    
1755
/* Return from interrupt */
1756
#if !defined(CONFIG_USER_ONLY)
1757
void OPPROTO op_rfi (void)
1758
{
1759
    do_rfi();
1760
    RETURN();
1761
}
1762

    
1763
#if defined(TARGET_PPC64)
1764
void OPPROTO op_rfid (void)
1765
{
1766
    do_rfid();
1767
    RETURN();
1768
}
1769

    
1770
void OPPROTO op_hrfid (void)
1771
{
1772
    do_hrfid();
1773
    RETURN();
1774
}
1775
#endif
1776

    
1777
/* Exception vectors */
1778
void OPPROTO op_store_excp_prefix (void)
1779
{
1780
    T0 &= env->ivpr_mask;
1781
    env->excp_prefix = T0;
1782
    RETURN();
1783
}
1784

    
1785
void OPPROTO op_store_excp_vector (void)
1786
{
1787
    T0 &= env->ivor_mask;
1788
    env->excp_vectors[PARAM1] = T0;
1789
    RETURN();
1790
}
1791
#endif
1792

    
1793
/* Trap word */
1794
void OPPROTO op_tw (void)
1795
{
1796
    do_tw(PARAM1);
1797
    RETURN();
1798
}
1799

    
1800
#if defined(TARGET_PPC64)
1801
void OPPROTO op_td (void)
1802
{
1803
    do_td(PARAM1);
1804
    RETURN();
1805
}
1806
#endif
1807

    
1808
#if !defined(CONFIG_USER_ONLY)
1809
/* tlbia */
1810
void OPPROTO op_tlbia (void)
1811
{
1812
    ppc_tlb_invalidate_all(env);
1813
    RETURN();
1814
}
1815

    
1816
/* tlbie */
1817
void OPPROTO op_tlbie (void)
1818
{
1819
    ppc_tlb_invalidate_one(env, (uint32_t)T0);
1820
    RETURN();
1821
}
1822

    
1823
#if defined(TARGET_PPC64)
1824
void OPPROTO op_tlbie_64 (void)
1825
{
1826
    ppc_tlb_invalidate_one(env, T0);
1827
    RETURN();
1828
}
1829
#endif
1830

    
1831
#if defined(TARGET_PPC64)
1832
void OPPROTO op_slbia (void)
1833
{
1834
    ppc_slb_invalidate_all(env);
1835
    RETURN();
1836
}
1837

    
1838
void OPPROTO op_slbie (void)
1839
{
1840
    ppc_slb_invalidate_one(env, (uint32_t)T0);
1841
    RETURN();
1842
}
1843

    
1844
void OPPROTO op_slbie_64 (void)
1845
{
1846
    ppc_slb_invalidate_one(env, T0);
1847
    RETURN();
1848
}
1849
#endif
1850
#endif
1851

    
1852
#if !defined(CONFIG_USER_ONLY)
1853
/* PowerPC 602/603/755 software TLB load instructions */
1854
void OPPROTO op_6xx_tlbld (void)
1855
{
1856
    do_load_6xx_tlb(0);
1857
    RETURN();
1858
}
1859

    
1860
void OPPROTO op_6xx_tlbli (void)
1861
{
1862
    do_load_6xx_tlb(1);
1863
    RETURN();
1864
}
1865

    
1866
/* PowerPC 74xx software TLB load instructions */
1867
void OPPROTO op_74xx_tlbld (void)
1868
{
1869
    do_load_74xx_tlb(0);
1870
    RETURN();
1871
}
1872

    
1873
void OPPROTO op_74xx_tlbli (void)
1874
{
1875
    do_load_74xx_tlb(1);
1876
    RETURN();
1877
}
1878
#endif
1879

    
1880
/* 601 specific */
1881
void OPPROTO op_load_601_rtcl (void)
1882
{
1883
    T0 = cpu_ppc601_load_rtcl(env);
1884
    RETURN();
1885
}
1886

    
1887
void OPPROTO op_load_601_rtcu (void)
1888
{
1889
    T0 = cpu_ppc601_load_rtcu(env);
1890
    RETURN();
1891
}
1892

    
1893
#if !defined(CONFIG_USER_ONLY)
1894
void OPPROTO op_store_601_rtcl (void)
1895
{
1896
    cpu_ppc601_store_rtcl(env, T0);
1897
    RETURN();
1898
}
1899

    
1900
void OPPROTO op_store_601_rtcu (void)
1901
{
1902
    cpu_ppc601_store_rtcu(env, T0);
1903
    RETURN();
1904
}
1905

    
1906
void OPPROTO op_store_hid0_601 (void)
1907
{
1908
    do_store_hid0_601();
1909
    RETURN();
1910
}
1911

    
1912
void OPPROTO op_load_601_bat (void)
1913
{
1914
    T0 = env->IBAT[PARAM1][PARAM2];
1915
    RETURN();
1916
}
1917

    
1918
void OPPROTO op_store_601_batl (void)
1919
{
1920
    do_store_ibatl_601(env, PARAM1, T0);
1921
    RETURN();
1922
}
1923

    
1924
void OPPROTO op_store_601_batu (void)
1925
{
1926
    do_store_ibatu_601(env, PARAM1, T0);
1927
    RETURN();
1928
}
1929
#endif /* !defined(CONFIG_USER_ONLY) */
1930

    
1931
/* PowerPC 601 specific instructions (POWER bridge) */
1932
/* XXX: those micro-ops need tests ! */
1933
void OPPROTO op_POWER_abs (void)
1934
{
1935
    if ((int32_t)T0 == INT32_MIN)
1936
        T0 = INT32_MAX;
1937
    else if ((int32_t)T0 < 0)
1938
        T0 = -T0;
1939
    RETURN();
1940
}
1941

    
1942
void OPPROTO op_POWER_abso (void)
1943
{
1944
    do_POWER_abso();
1945
    RETURN();
1946
}
1947

    
1948
void OPPROTO op_POWER_clcs (void)
1949
{
1950
    do_POWER_clcs();
1951
    RETURN();
1952
}
1953

    
1954
void OPPROTO op_POWER_div (void)
1955
{
1956
    do_POWER_div();
1957
    RETURN();
1958
}
1959

    
1960
void OPPROTO op_POWER_divo (void)
1961
{
1962
    do_POWER_divo();
1963
    RETURN();
1964
}
1965

    
1966
void OPPROTO op_POWER_divs (void)
1967
{
1968
    do_POWER_divs();
1969
    RETURN();
1970
}
1971

    
1972
void OPPROTO op_POWER_divso (void)
1973
{
1974
    do_POWER_divso();
1975
    RETURN();
1976
}
1977

    
1978
void OPPROTO op_POWER_doz (void)
1979
{
1980
    if ((int32_t)T1 > (int32_t)T0)
1981
        T0 = T1 - T0;
1982
    else
1983
        T0 = 0;
1984
    RETURN();
1985
}
1986

    
1987
void OPPROTO op_POWER_dozo (void)
1988
{
1989
    do_POWER_dozo();
1990
    RETURN();
1991
}
1992

    
1993
void OPPROTO op_load_xer_cmp (void)
1994
{
1995
    T2 = xer_cmp;
1996
    RETURN();
1997
}
1998

    
1999
void OPPROTO op_POWER_maskg (void)
2000
{
2001
    do_POWER_maskg();
2002
    RETURN();
2003
}
2004

    
2005
void OPPROTO op_POWER_maskir (void)
2006
{
2007
    T0 = (T0 & ~T2) | (T1 & T2);
2008
    RETURN();
2009
}
2010

    
2011
void OPPROTO op_POWER_mul (void)
2012
{
2013
    uint64_t tmp;
2014

    
2015
    tmp = (uint64_t)T0 * (uint64_t)T1;
2016
    env->spr[SPR_MQ] = tmp >> 32;
2017
    T0 = tmp;
2018
    RETURN();
2019
}
2020

    
2021
void OPPROTO op_POWER_mulo (void)
2022
{
2023
    do_POWER_mulo();
2024
    RETURN();
2025
}
2026

    
2027
void OPPROTO op_POWER_nabs (void)
2028
{
2029
    if (T0 > 0)
2030
        T0 = -T0;
2031
    RETURN();
2032
}
2033

    
2034
void OPPROTO op_POWER_nabso (void)
2035
{
2036
    /* nabs never overflows */
2037
    if (T0 > 0)
2038
        T0 = -T0;
2039
    xer_ov = 0;
2040
    RETURN();
2041
}
2042

    
2043
/* XXX: factorise POWER rotates... */
2044
void OPPROTO op_POWER_rlmi (void)
2045
{
2046
    T0 = rotl32(T0, T2) & PARAM1;
2047
    T0 |= T1 & (uint32_t)PARAM2;
2048
    RETURN();
2049
}
2050

    
2051
void OPPROTO op_POWER_rrib (void)
2052
{
2053
    T2 &= 0x1FUL;
2054
    T0 = rotl32(T0 & INT32_MIN, T2);
2055
    T0 |= T1 & ~rotl32(INT32_MIN, T2);
2056
    RETURN();
2057
}
2058

    
2059
void OPPROTO op_POWER_sle (void)
2060
{
2061
    T1 &= 0x1FUL;
2062
    env->spr[SPR_MQ] = rotl32(T0, T1);
2063
    T0 = T0 << T1;
2064
    RETURN();
2065
}
2066

    
2067
void OPPROTO op_POWER_sleq (void)
2068
{
2069
    uint32_t tmp = env->spr[SPR_MQ];
2070

    
2071
    T1 &= 0x1FUL;
2072
    env->spr[SPR_MQ] = rotl32(T0, T1);
2073
    T0 = T0 << T1;
2074
    T0 |= tmp >> (32 - T1);
2075
    RETURN();
2076
}
2077

    
2078
void OPPROTO op_POWER_sllq (void)
2079
{
2080
    uint32_t msk = UINT32_MAX;
2081

    
2082
    msk = msk << (T1 & 0x1FUL);
2083
    if (T1 & 0x20UL)
2084
        msk = ~msk;
2085
    T1 &= 0x1FUL;
2086
    T0 = (T0 << T1) & msk;
2087
    T0 |= env->spr[SPR_MQ] & ~msk;
2088
    RETURN();
2089
}
2090

    
2091
void OPPROTO op_POWER_slq (void)
2092
{
2093
    uint32_t msk = UINT32_MAX, tmp;
2094

    
2095
    msk = msk << (T1 & 0x1FUL);
2096
    if (T1 & 0x20UL)
2097
        msk = ~msk;
2098
    T1 &= 0x1FUL;
2099
    tmp = rotl32(T0, T1);
2100
    T0 = tmp & msk;
2101
    env->spr[SPR_MQ] = tmp;
2102
    RETURN();
2103
}
2104

    
2105
void OPPROTO op_POWER_sraq (void)
2106
{
2107
    env->spr[SPR_MQ] = rotl32(T0, 32 - (T1 & 0x1FUL));
2108
    if (T1 & 0x20UL)
2109
        T0 = UINT32_MAX;
2110
    else
2111
        T0 = (int32_t)T0 >> T1;
2112
    RETURN();
2113
}
2114

    
2115
void OPPROTO op_POWER_sre (void)
2116
{
2117
    T1 &= 0x1FUL;
2118
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2119
    T0 = (int32_t)T0 >> T1;
2120
    RETURN();
2121
}
2122

    
2123
void OPPROTO op_POWER_srea (void)
2124
{
2125
    T1 &= 0x1FUL;
2126
    env->spr[SPR_MQ] = T0 >> T1;
2127
    T0 = (int32_t)T0 >> T1;
2128
    RETURN();
2129
}
2130

    
2131
void OPPROTO op_POWER_sreq (void)
2132
{
2133
    uint32_t tmp;
2134
    int32_t msk;
2135

    
2136
    T1 &= 0x1FUL;
2137
    msk = INT32_MIN >> T1;
2138
    tmp = env->spr[SPR_MQ];
2139
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2140
    T0 = T0 >> T1;
2141
    T0 |= tmp & msk;
2142
    RETURN();
2143
}
2144

    
2145
void OPPROTO op_POWER_srlq (void)
2146
{
2147
    uint32_t tmp;
2148
    int32_t msk;
2149

    
2150
    msk = INT32_MIN >> (T1 & 0x1FUL);
2151
    if (T1 & 0x20UL)
2152
        msk = ~msk;
2153
    T1 &= 0x1FUL;
2154
    tmp = env->spr[SPR_MQ];
2155
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2156
    T0 = T0 >> T1;
2157
    T0 &= msk;
2158
    T0 |= tmp & ~msk;
2159
    RETURN();
2160
}
2161

    
2162
void OPPROTO op_POWER_srq (void)
2163
{
2164
    T1 &= 0x1FUL;
2165
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2166
    T0 = T0 >> T1;
2167
    RETURN();
2168
}
2169

    
2170
/* POWER instructions not implemented in PowerPC 601 */
2171
#if !defined(CONFIG_USER_ONLY)
2172
void OPPROTO op_POWER_mfsri (void)
2173
{
2174
    T1 = T0 >> 28;
2175
    T0 = env->sr[T1];
2176
    RETURN();
2177
}
2178

    
2179
void OPPROTO op_POWER_rac (void)
2180
{
2181
    do_POWER_rac();
2182
    RETURN();
2183
}
2184

    
2185
void OPPROTO op_POWER_rfsvc (void)
2186
{
2187
    do_POWER_rfsvc();
2188
    RETURN();
2189
}
2190
#endif
2191

    
2192
/* PowerPC 602 specific instruction */
2193
#if !defined(CONFIG_USER_ONLY)
2194
void OPPROTO op_602_mfrom (void)
2195
{
2196
    do_op_602_mfrom();
2197
    RETURN();
2198
}
2199
#endif
2200

    
2201
/* PowerPC 4xx specific micro-ops */
2202
void OPPROTO op_405_add_T0_T2 (void)
2203
{
2204
    T0 = (int32_t)T0 + (int32_t)T2;
2205
    RETURN();
2206
}
2207

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

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

    
2220
void OPPROTO op_405_mulhhw (void)
2221
{
2222
    T0 = ((int16_t)(T0 >> 16)) * ((int16_t)(T1 >> 16));
2223
    RETURN();
2224
}
2225

    
2226
void OPPROTO op_405_mulhhwu (void)
2227
{
2228
    T0 = ((uint16_t)(T0 >> 16)) * ((uint16_t)(T1 >> 16));
2229
    RETURN();
2230
}
2231

    
2232
void OPPROTO op_405_mullhw (void)
2233
{
2234
    T0 = ((int16_t)T0) * ((int16_t)T1);
2235
    RETURN();
2236
}
2237

    
2238
void OPPROTO op_405_mullhwu (void)
2239
{
2240
    T0 = ((uint16_t)T0) * ((uint16_t)T1);
2241
    RETURN();
2242
}
2243

    
2244
void OPPROTO op_405_check_sat (void)
2245
{
2246
    do_405_check_sat();
2247
    RETURN();
2248
}
2249

    
2250
void OPPROTO op_405_check_ovu (void)
2251
{
2252
    if (likely(T0 >= T2)) {
2253
        xer_ov = 0;
2254
    } else {
2255
        xer_ov = 1;
2256
        xer_so = 1;
2257
    }
2258
    RETURN();
2259
}
2260

    
2261
void OPPROTO op_405_check_satu (void)
2262
{
2263
    if (unlikely(T0 < T2)) {
2264
        /* Saturate result */
2265
        T0 = UINT32_MAX;
2266
    }
2267
    RETURN();
2268
}
2269

    
2270
void OPPROTO op_load_dcr (void)
2271
{
2272
    do_load_dcr();
2273
    RETURN();
2274
}
2275

    
2276
void OPPROTO op_store_dcr (void)
2277
{
2278
    do_store_dcr();
2279
    RETURN();
2280
}
2281

    
2282
#if !defined(CONFIG_USER_ONLY)
2283
/* Return from critical interrupt :
2284
 * same as rfi, except nip & MSR are loaded from SRR2/3 instead of SRR0/1
2285
 */
2286
void OPPROTO op_40x_rfci (void)
2287
{
2288
    do_40x_rfci();
2289
    RETURN();
2290
}
2291

    
2292
void OPPROTO op_rfci (void)
2293
{
2294
    do_rfci();
2295
    RETURN();
2296
}
2297

    
2298
void OPPROTO op_rfdi (void)
2299
{
2300
    do_rfdi();
2301
    RETURN();
2302
}
2303

    
2304
void OPPROTO op_rfmci (void)
2305
{
2306
    do_rfmci();
2307
    RETURN();
2308
}
2309

    
2310
void OPPROTO op_wrte (void)
2311
{
2312
    /* We don't call do_store_msr here as we won't trigger
2313
     * any special case nor change hflags
2314
     */
2315
    T0 &= 1 << MSR_EE;
2316
    env->msr &= ~(1 << MSR_EE);
2317
    env->msr |= T0;
2318
    RETURN();
2319
}
2320

    
2321
void OPPROTO op_440_tlbre (void)
2322
{
2323
    do_440_tlbre(PARAM1);
2324
    RETURN();
2325
}
2326

    
2327
void OPPROTO op_440_tlbsx (void)
2328
{
2329
    T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_440_MMUCR] & 0xFF);
2330
    RETURN();
2331
}
2332

    
2333
void OPPROTO op_4xx_tlbsx_check (void)
2334
{
2335
    int tmp;
2336

    
2337
    tmp = xer_so;
2338
    if ((int)T0 != -1)
2339
        tmp |= 0x02;
2340
    env->crf[0] = tmp;
2341
    RETURN();
2342
}
2343

    
2344
void OPPROTO op_440_tlbwe (void)
2345
{
2346
    do_440_tlbwe(PARAM1);
2347
    RETURN();
2348
}
2349

    
2350
void OPPROTO op_4xx_tlbre_lo (void)
2351
{
2352
    do_4xx_tlbre_lo();
2353
    RETURN();
2354
}
2355

    
2356
void OPPROTO op_4xx_tlbre_hi (void)
2357
{
2358
    do_4xx_tlbre_hi();
2359
    RETURN();
2360
}
2361

    
2362
void OPPROTO op_4xx_tlbsx (void)
2363
{
2364
    T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_40x_PID]);
2365
    RETURN();
2366
}
2367

    
2368
void OPPROTO op_4xx_tlbwe_lo (void)
2369
{
2370
    do_4xx_tlbwe_lo();
2371
    RETURN();
2372
}
2373

    
2374
void OPPROTO op_4xx_tlbwe_hi (void)
2375
{
2376
    do_4xx_tlbwe_hi();
2377
    RETURN();
2378
}
2379
#endif
2380

    
2381
/* SPR micro-ops */
2382
/* 440 specific */
2383
void OPPROTO op_440_dlmzb (void)
2384
{
2385
    do_440_dlmzb();
2386
    RETURN();
2387
}
2388

    
2389
void OPPROTO op_440_dlmzb_update_Rc (void)
2390
{
2391
    if (T0 == 8)
2392
        T0 = 0x2;
2393
    else if (T0 < 4)
2394
        T0 = 0x4;
2395
    else
2396
        T0 = 0x8;
2397
    RETURN();
2398
}
2399

    
2400
#if !defined(CONFIG_USER_ONLY)
2401
void OPPROTO op_store_pir (void)
2402
{
2403
    env->spr[SPR_PIR] = T0 & 0x0000000FUL;
2404
    RETURN();
2405
}
2406

    
2407
void OPPROTO op_load_403_pb (void)
2408
{
2409
    do_load_403_pb(PARAM1);
2410
    RETURN();
2411
}
2412

    
2413
void OPPROTO op_store_403_pb (void)
2414
{
2415
    do_store_403_pb(PARAM1);
2416
    RETURN();
2417
}
2418

    
2419
void OPPROTO op_load_40x_pit (void)
2420
{
2421
    T0 = load_40x_pit(env);
2422
    RETURN();
2423
}
2424

    
2425
void OPPROTO op_store_40x_pit (void)
2426
{
2427
    store_40x_pit(env, T0);
2428
    RETURN();
2429
}
2430

    
2431
void OPPROTO op_store_40x_dbcr0 (void)
2432
{
2433
    store_40x_dbcr0(env, T0);
2434
    RETURN();
2435
}
2436

    
2437
void OPPROTO op_store_40x_sler (void)
2438
{
2439
    store_40x_sler(env, T0);
2440
    RETURN();
2441
}
2442

    
2443
void OPPROTO op_store_booke_tcr (void)
2444
{
2445
    store_booke_tcr(env, T0);
2446
    RETURN();
2447
}
2448

    
2449
void OPPROTO op_store_booke_tsr (void)
2450
{
2451
    store_booke_tsr(env, T0);
2452
    RETURN();
2453
}
2454
#endif /* !defined(CONFIG_USER_ONLY) */
2455

    
2456
/* SPE extension */
2457
void OPPROTO op_splatw_T1_64 (void)
2458
{
2459
    T1_64 = (T1_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL);
2460
    RETURN();
2461
}
2462

    
2463
void OPPROTO op_splatwi_T0_64 (void)
2464
{
2465
    uint64_t tmp = PARAM1;
2466

    
2467
    T0_64 = (tmp << 32) | tmp;
2468
    RETURN();
2469
}
2470

    
2471
void OPPROTO op_splatwi_T1_64 (void)
2472
{
2473
    uint64_t tmp = PARAM1;
2474

    
2475
    T1_64 = (tmp << 32) | tmp;
2476
    RETURN();
2477
}
2478

    
2479
void OPPROTO op_extsh_T1_64 (void)
2480
{
2481
    T1_64 = (int32_t)((int16_t)T1_64);
2482
    RETURN();
2483
}
2484

    
2485
void OPPROTO op_sli16_T1_64 (void)
2486
{
2487
    T1_64 = T1_64 << 16;
2488
    RETURN();
2489
}
2490

    
2491
void OPPROTO op_sli32_T1_64 (void)
2492
{
2493
    T1_64 = T1_64 << 32;
2494
    RETURN();
2495
}
2496

    
2497
void OPPROTO op_srli32_T1_64 (void)
2498
{
2499
    T1_64 = T1_64 >> 32;
2500
    RETURN();
2501
}
2502

    
2503
void OPPROTO op_evsel (void)
2504
{
2505
    do_evsel();
2506
    RETURN();
2507
}
2508

    
2509
void OPPROTO op_evaddw (void)
2510
{
2511
    do_evaddw();
2512
    RETURN();
2513
}
2514

    
2515
void OPPROTO op_evsubfw (void)
2516
{
2517
    do_evsubfw();
2518
    RETURN();
2519
}
2520

    
2521
void OPPROTO op_evneg (void)
2522
{
2523
    do_evneg();
2524
    RETURN();
2525
}
2526

    
2527
void OPPROTO op_evabs (void)
2528
{
2529
    do_evabs();
2530
    RETURN();
2531
}
2532

    
2533
void OPPROTO op_evextsh (void)
2534
{
2535
    T0_64 = ((uint64_t)((int32_t)(int16_t)(T0_64 >> 32)) << 32) |
2536
        (uint64_t)((int32_t)(int16_t)T0_64);
2537
    RETURN();
2538
}
2539

    
2540
void OPPROTO op_evextsb (void)
2541
{
2542
    T0_64 = ((uint64_t)((int32_t)(int8_t)(T0_64 >> 32)) << 32) |
2543
        (uint64_t)((int32_t)(int8_t)T0_64);
2544
    RETURN();
2545
}
2546

    
2547
void OPPROTO op_evcntlzw (void)
2548
{
2549
    do_evcntlzw();
2550
    RETURN();
2551
}
2552

    
2553
void OPPROTO op_evrndw (void)
2554
{
2555
    do_evrndw();
2556
    RETURN();
2557
}
2558

    
2559
void OPPROTO op_brinc (void)
2560
{
2561
    do_brinc();
2562
    RETURN();
2563
}
2564

    
2565
void OPPROTO op_evcntlsw (void)
2566
{
2567
    do_evcntlsw();
2568
    RETURN();
2569
}
2570

    
2571
void OPPROTO op_evand (void)
2572
{
2573
    T0_64 &= T1_64;
2574
    RETURN();
2575
}
2576

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

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

    
2589
void OPPROTO op_evxor (void)
2590
{
2591
    T0_64 ^= T1_64;
2592
    RETURN();
2593
}
2594

    
2595
void OPPROTO op_eveqv (void)
2596
{
2597
    T0_64 = ~(T0_64 ^ T1_64);
2598
    RETURN();
2599
}
2600

    
2601
void OPPROTO op_evnor (void)
2602
{
2603
    T0_64 = ~(T0_64 | T1_64);
2604
    RETURN();
2605
}
2606

    
2607
void OPPROTO op_evorc (void)
2608
{
2609
    T0_64 |= ~T1_64;
2610
    RETURN();
2611
}
2612

    
2613
void OPPROTO op_evnand (void)
2614
{
2615
    T0_64 = ~(T0_64 & T1_64);
2616
    RETURN();
2617
}
2618

    
2619
void OPPROTO op_evsrws (void)
2620
{
2621
    do_evsrws();
2622
    RETURN();
2623
}
2624

    
2625
void OPPROTO op_evsrwu (void)
2626
{
2627
    do_evsrwu();
2628
    RETURN();
2629
}
2630

    
2631
void OPPROTO op_evslw (void)
2632
{
2633
    do_evslw();
2634
    RETURN();
2635
}
2636

    
2637
void OPPROTO op_evrlw (void)
2638
{
2639
    do_evrlw();
2640
    RETURN();
2641
}
2642

    
2643
void OPPROTO op_evmergelo (void)
2644
{
2645
    T0_64 = (T0_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL);
2646
    RETURN();
2647
}
2648

    
2649
void OPPROTO op_evmergehi (void)
2650
{
2651
    T0_64 = (T0_64 & 0xFFFFFFFF00000000ULL) | (T1_64 >> 32);
2652
    RETURN();
2653
}
2654

    
2655
void OPPROTO op_evmergelohi (void)
2656
{
2657
    T0_64 = (T0_64 << 32) | (T1_64 >> 32);
2658
    RETURN();
2659
}
2660

    
2661
void OPPROTO op_evmergehilo (void)
2662
{
2663
    T0_64 = (T0_64 & 0xFFFFFFFF00000000ULL) | (T1_64 & 0x00000000FFFFFFFFULL);
2664
    RETURN();
2665
}
2666

    
2667
void OPPROTO op_evcmpgts (void)
2668
{
2669
    do_evcmpgts();
2670
    RETURN();
2671
}
2672

    
2673
void OPPROTO op_evcmpgtu (void)
2674
{
2675
    do_evcmpgtu();
2676
    RETURN();
2677
}
2678

    
2679
void OPPROTO op_evcmplts (void)
2680
{
2681
    do_evcmplts();
2682
    RETURN();
2683
}
2684

    
2685
void OPPROTO op_evcmpltu (void)
2686
{
2687
    do_evcmpltu();
2688
    RETURN();
2689
}
2690

    
2691
void OPPROTO op_evcmpeq (void)
2692
{
2693
    do_evcmpeq();
2694
    RETURN();
2695
}
2696

    
2697
void OPPROTO op_evfssub (void)
2698
{
2699
    do_evfssub();
2700
    RETURN();
2701
}
2702

    
2703
void OPPROTO op_evfsadd (void)
2704
{
2705
    do_evfsadd();
2706
    RETURN();
2707
}
2708

    
2709
void OPPROTO op_evfsnabs (void)
2710
{
2711
    do_evfsnabs();
2712
    RETURN();
2713
}
2714

    
2715
void OPPROTO op_evfsabs (void)
2716
{
2717
    do_evfsabs();
2718
    RETURN();
2719
}
2720

    
2721
void OPPROTO op_evfsneg (void)
2722
{
2723
    do_evfsneg();
2724
    RETURN();
2725
}
2726

    
2727
void OPPROTO op_evfsdiv (void)
2728
{
2729
    do_evfsdiv();
2730
    RETURN();
2731
}
2732

    
2733
void OPPROTO op_evfsmul (void)
2734
{
2735
    do_evfsmul();
2736
    RETURN();
2737
}
2738

    
2739
void OPPROTO op_evfscmplt (void)
2740
{
2741
    do_evfscmplt();
2742
    RETURN();
2743
}
2744

    
2745
void OPPROTO op_evfscmpgt (void)
2746
{
2747
    do_evfscmpgt();
2748
    RETURN();
2749
}
2750

    
2751
void OPPROTO op_evfscmpeq (void)
2752
{
2753
    do_evfscmpeq();
2754
    RETURN();
2755
}
2756

    
2757
void OPPROTO op_evfscfsi (void)
2758
{
2759
    do_evfscfsi();
2760
    RETURN();
2761
}
2762

    
2763
void OPPROTO op_evfscfui (void)
2764
{
2765
    do_evfscfui();
2766
    RETURN();
2767
}
2768

    
2769
void OPPROTO op_evfscfsf (void)
2770
{
2771
    do_evfscfsf();
2772
    RETURN();
2773
}
2774

    
2775
void OPPROTO op_evfscfuf (void)
2776
{
2777
    do_evfscfuf();
2778
    RETURN();
2779
}
2780

    
2781
void OPPROTO op_evfsctsi (void)
2782
{
2783
    do_evfsctsi();
2784
    RETURN();
2785
}
2786

    
2787
void OPPROTO op_evfsctui (void)
2788
{
2789
    do_evfsctui();
2790
    RETURN();
2791
}
2792

    
2793
void OPPROTO op_evfsctsf (void)
2794
{
2795
    do_evfsctsf();
2796
    RETURN();
2797
}
2798

    
2799
void OPPROTO op_evfsctuf (void)
2800
{
2801
    do_evfsctuf();
2802
    RETURN();
2803
}
2804

    
2805
void OPPROTO op_evfsctuiz (void)
2806
{
2807
    do_evfsctuiz();
2808
    RETURN();
2809
}
2810

    
2811
void OPPROTO op_evfsctsiz (void)
2812
{
2813
    do_evfsctsiz();
2814
    RETURN();
2815
}
2816

    
2817
void OPPROTO op_evfststlt (void)
2818
{
2819
    do_evfststlt();
2820
    RETURN();
2821
}
2822

    
2823
void OPPROTO op_evfststgt (void)
2824
{
2825
    do_evfststgt();
2826
    RETURN();
2827
}
2828

    
2829
void OPPROTO op_evfststeq (void)
2830
{
2831
    do_evfststeq();
2832
    RETURN();
2833
}
2834

    
2835
void OPPROTO op_efssub (void)
2836
{
2837
    T0_64 = _do_efssub(T0_64, T1_64);
2838
    RETURN();
2839
}
2840

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

    
2847
void OPPROTO op_efsnabs (void)
2848
{
2849
    T0_64 = _do_efsnabs(T0_64);
2850
    RETURN();
2851
}
2852

    
2853
void OPPROTO op_efsabs (void)
2854
{
2855
    T0_64 = _do_efsabs(T0_64);
2856
    RETURN();
2857
}
2858

    
2859
void OPPROTO op_efsneg (void)
2860
{
2861
    T0_64 = _do_efsneg(T0_64);
2862
    RETURN();
2863
}
2864

    
2865
void OPPROTO op_efsdiv (void)
2866
{
2867
    T0_64 = _do_efsdiv(T0_64, T1_64);
2868
    RETURN();
2869
}
2870

    
2871
void OPPROTO op_efsmul (void)
2872
{
2873
    T0_64 = _do_efsmul(T0_64, T1_64);
2874
    RETURN();
2875
}
2876

    
2877
void OPPROTO op_efscmplt (void)
2878
{
2879
    do_efscmplt();
2880
    RETURN();
2881
}
2882

    
2883
void OPPROTO op_efscmpgt (void)
2884
{
2885
    do_efscmpgt();
2886
    RETURN();
2887
}
2888

    
2889
void OPPROTO op_efscfd (void)
2890
{
2891
    do_efscfd();
2892
    RETURN();
2893
}
2894

    
2895
void OPPROTO op_efscmpeq (void)
2896
{
2897
    do_efscmpeq();
2898
    RETURN();
2899
}
2900

    
2901
void OPPROTO op_efscfsi (void)
2902
{
2903
    do_efscfsi();
2904
    RETURN();
2905
}
2906

    
2907
void OPPROTO op_efscfui (void)
2908
{
2909
    do_efscfui();
2910
    RETURN();
2911
}
2912

    
2913
void OPPROTO op_efscfsf (void)
2914
{
2915
    do_efscfsf();
2916
    RETURN();
2917
}
2918

    
2919
void OPPROTO op_efscfuf (void)
2920
{
2921
    do_efscfuf();
2922
    RETURN();
2923
}
2924

    
2925
void OPPROTO op_efsctsi (void)
2926
{
2927
    do_efsctsi();
2928
    RETURN();
2929
}
2930

    
2931
void OPPROTO op_efsctui (void)
2932
{
2933
    do_efsctui();
2934
    RETURN();
2935
}
2936

    
2937
void OPPROTO op_efsctsf (void)
2938
{
2939
    do_efsctsf();
2940
    RETURN();
2941
}
2942

    
2943
void OPPROTO op_efsctuf (void)
2944
{
2945
    do_efsctuf();
2946
    RETURN();
2947
}
2948

    
2949
void OPPROTO op_efsctsiz (void)
2950
{
2951
    do_efsctsiz();
2952
    RETURN();
2953
}
2954

    
2955
void OPPROTO op_efsctuiz (void)
2956
{
2957
    do_efsctuiz();
2958
    RETURN();
2959
}
2960

    
2961
void OPPROTO op_efststlt (void)
2962
{
2963
    T0 = _do_efststlt(T0_64, T1_64);
2964
    RETURN();
2965
}
2966

    
2967
void OPPROTO op_efststgt (void)
2968
{
2969
    T0 = _do_efststgt(T0_64, T1_64);
2970
    RETURN();
2971
}
2972

    
2973
void OPPROTO op_efststeq (void)
2974
{
2975
    T0 = _do_efststeq(T0_64, T1_64);
2976
    RETURN();
2977
}
2978

    
2979
void OPPROTO op_efdsub (void)
2980
{
2981
    CPU_DoubleU u1, u2;
2982
    u1.ll = T0_64;
2983
    u2.ll = T1_64;
2984
    u1.d = float64_sub(u1.d, u2.d, &env->spe_status);
2985
    T0_64 = u1.ll;
2986
    RETURN();
2987
}
2988

    
2989
void OPPROTO op_efdadd (void)
2990
{
2991
    CPU_DoubleU u1, u2;
2992
    u1.ll = T0_64;
2993
    u2.ll = T1_64;
2994
    u1.d = float64_add(u1.d, u2.d, &env->spe_status);
2995
    T0_64 = u1.ll;
2996
    RETURN();
2997
}
2998

    
2999
void OPPROTO op_efdcfsid (void)
3000
{
3001
    do_efdcfsi();
3002
    RETURN();
3003
}
3004

    
3005
void OPPROTO op_efdcfuid (void)
3006
{
3007
    do_efdcfui();
3008
    RETURN();
3009
}
3010

    
3011
void OPPROTO op_efdnabs (void)
3012
{
3013
    T0_64 |= 0x8000000000000000ULL;
3014
    RETURN();
3015
}
3016

    
3017
void OPPROTO op_efdabs (void)
3018
{
3019
    T0_64 &= ~0x8000000000000000ULL;
3020
    RETURN();
3021
}
3022

    
3023
void OPPROTO op_efdneg (void)
3024
{
3025
    T0_64 ^= 0x8000000000000000ULL;
3026
    RETURN();
3027
}
3028

    
3029
void OPPROTO op_efddiv (void)
3030
{
3031
    CPU_DoubleU u1, u2;
3032
    u1.ll = T0_64;
3033
    u2.ll = T1_64;
3034
    u1.d = float64_div(u1.d, u2.d, &env->spe_status);
3035
    T0_64 = u1.ll;
3036
    RETURN();
3037
}
3038

    
3039
void OPPROTO op_efdmul (void)
3040
{
3041
    CPU_DoubleU u1, u2;
3042
    u1.ll = T0_64;
3043
    u2.ll = T1_64;
3044
    u1.d = float64_mul(u1.d, u2.d, &env->spe_status);
3045
    T0_64 = u1.ll;
3046
    RETURN();
3047
}
3048

    
3049
void OPPROTO op_efdctsidz (void)
3050
{
3051
    do_efdctsiz();
3052
    RETURN();
3053
}
3054

    
3055
void OPPROTO op_efdctuidz (void)
3056
{
3057
    do_efdctuiz();
3058
    RETURN();
3059
}
3060

    
3061
void OPPROTO op_efdcmplt (void)
3062
{
3063
    do_efdcmplt();
3064
    RETURN();
3065
}
3066

    
3067
void OPPROTO op_efdcmpgt (void)
3068
{
3069
    do_efdcmpgt();
3070
    RETURN();
3071
}
3072

    
3073
void OPPROTO op_efdcfs (void)
3074
{
3075
    do_efdcfs();
3076
    RETURN();
3077
}
3078

    
3079
void OPPROTO op_efdcmpeq (void)
3080
{
3081
    do_efdcmpeq();
3082
    RETURN();
3083
}
3084

    
3085
void OPPROTO op_efdcfsi (void)
3086
{
3087
    do_efdcfsi();
3088
    RETURN();
3089
}
3090

    
3091
void OPPROTO op_efdcfui (void)
3092
{
3093
    do_efdcfui();
3094
    RETURN();
3095
}
3096

    
3097
void OPPROTO op_efdcfsf (void)
3098
{
3099
    do_efdcfsf();
3100
    RETURN();
3101
}
3102

    
3103
void OPPROTO op_efdcfuf (void)
3104
{
3105
    do_efdcfuf();
3106
    RETURN();
3107
}
3108

    
3109
void OPPROTO op_efdctsi (void)
3110
{
3111
    do_efdctsi();
3112
    RETURN();
3113
}
3114

    
3115
void OPPROTO op_efdctui (void)
3116
{
3117
    do_efdctui();
3118
    RETURN();
3119
}
3120

    
3121
void OPPROTO op_efdctsf (void)
3122
{
3123
    do_efdctsf();
3124
    RETURN();
3125
}
3126

    
3127
void OPPROTO op_efdctuf (void)
3128
{
3129
    do_efdctuf();
3130
    RETURN();
3131
}
3132

    
3133
void OPPROTO op_efdctuiz (void)
3134
{
3135
    do_efdctuiz();
3136
    RETURN();
3137
}
3138

    
3139
void OPPROTO op_efdctsiz (void)
3140
{
3141
    do_efdctsiz();
3142
    RETURN();
3143
}
3144

    
3145
void OPPROTO op_efdtstlt (void)
3146
{
3147
    T0 = _do_efdtstlt(T0_64, T1_64);
3148
    RETURN();
3149
}
3150

    
3151
void OPPROTO op_efdtstgt (void)
3152
{
3153
    T0 = _do_efdtstgt(T0_64, T1_64);
3154
    RETURN();
3155
}
3156

    
3157
void OPPROTO op_efdtsteq (void)
3158
{
3159
    T0 = _do_efdtsteq(T0_64, T1_64);
3160
    RETURN();
3161
}