Statistics
| Branch: | Revision:

root / target-ppc / op.c @ bd568f18

History | View | Annotate | Download (47.3 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_set_FT0 (void)
414
{
415
    CPU_DoubleU u;
416

    
417
    u.l.upper = 0;
418
    u.l.lower = PARAM1;
419
    FT0 = u.d;
420
    RETURN();
421
}
422

    
423
void OPPROTO op_load_fpscr_T0 (void)
424
{
425
    T0 = (env->fpscr >> PARAM1) & 0xF;
426
    RETURN();
427
}
428

    
429
void OPPROTO op_load_fpcc (void)
430
{
431
    T0 = fpscr_fpcc;
432
    RETURN();
433
}
434

    
435
void OPPROTO op_fpscr_resetbit (void)
436
{
437
    env->fpscr &= PARAM1;
438
    RETURN();
439
}
440

    
441
void OPPROTO op_fpscr_setbit (void)
442
{
443
    do_fpscr_setbit(PARAM1);
444
    RETURN();
445
}
446

    
447
void OPPROTO op_store_fpscr (void)
448
{
449
    do_store_fpscr(PARAM1);
450
    RETURN();
451
}
452

    
453
/* Branch */
454
void OPPROTO op_setlr (void)
455
{
456
    env->lr = (uint32_t)PARAM1;
457
    RETURN();
458
}
459

    
460
#if defined (TARGET_PPC64)
461
void OPPROTO op_setlr_64 (void)
462
{
463
    env->lr = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
464
    RETURN();
465
}
466
#endif
467

    
468
void OPPROTO op_jz_T0 (void)
469
{
470
    if (!T0)
471
        GOTO_LABEL_PARAM(1);
472
    RETURN();
473
}
474

    
475
void OPPROTO op_btest_T1 (void)
476
{
477
    if (T0) {
478
        env->nip = (uint32_t)(T1 & ~3);
479
    } else {
480
        env->nip = (uint32_t)PARAM1;
481
    }
482
    RETURN();
483
}
484

    
485
#if defined (TARGET_PPC64)
486
void OPPROTO op_btest_T1_64 (void)
487
{
488
    if (T0) {
489
        env->nip = (uint64_t)(T1 & ~3);
490
    } else {
491
        env->nip = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
492
    }
493
    RETURN();
494
}
495
#endif
496

    
497
void OPPROTO op_movl_T1_ctr (void)
498
{
499
    T1 = env->ctr;
500
    RETURN();
501
}
502

    
503
void OPPROTO op_movl_T1_lr (void)
504
{
505
    T1 = env->lr;
506
    RETURN();
507
}
508

    
509
/* tests with result in T0 */
510
void OPPROTO op_test_ctr (void)
511
{
512
    T0 = (uint32_t)env->ctr;
513
    RETURN();
514
}
515

    
516
#if defined(TARGET_PPC64)
517
void OPPROTO op_test_ctr_64 (void)
518
{
519
    T0 = (uint64_t)env->ctr;
520
    RETURN();
521
}
522
#endif
523

    
524
void OPPROTO op_test_ctr_true (void)
525
{
526
    T0 = ((uint32_t)env->ctr != 0 && (T0 & PARAM1) != 0);
527
    RETURN();
528
}
529

    
530
#if defined(TARGET_PPC64)
531
void OPPROTO op_test_ctr_true_64 (void)
532
{
533
    T0 = ((uint64_t)env->ctr != 0 && (T0 & PARAM1) != 0);
534
    RETURN();
535
}
536
#endif
537

    
538
void OPPROTO op_test_ctr_false (void)
539
{
540
    T0 = ((uint32_t)env->ctr != 0 && (T0 & PARAM1) == 0);
541
    RETURN();
542
}
543

    
544
#if defined(TARGET_PPC64)
545
void OPPROTO op_test_ctr_false_64 (void)
546
{
547
    T0 = ((uint64_t)env->ctr != 0 && (T0 & PARAM1) == 0);
548
    RETURN();
549
}
550
#endif
551

    
552
void OPPROTO op_test_ctrz (void)
553
{
554
    T0 = ((uint32_t)env->ctr == 0);
555
    RETURN();
556
}
557

    
558
#if defined(TARGET_PPC64)
559
void OPPROTO op_test_ctrz_64 (void)
560
{
561
    T0 = ((uint64_t)env->ctr == 0);
562
    RETURN();
563
}
564
#endif
565

    
566
void OPPROTO op_test_ctrz_true (void)
567
{
568
    T0 = ((uint32_t)env->ctr == 0 && (T0 & PARAM1) != 0);
569
    RETURN();
570
}
571

    
572
#if defined(TARGET_PPC64)
573
void OPPROTO op_test_ctrz_true_64 (void)
574
{
575
    T0 = ((uint64_t)env->ctr == 0 && (T0 & PARAM1) != 0);
576
    RETURN();
577
}
578
#endif
579

    
580
void OPPROTO op_test_ctrz_false (void)
581
{
582
    T0 = ((uint32_t)env->ctr == 0 && (T0 & PARAM1) == 0);
583
    RETURN();
584
}
585

    
586
#if defined(TARGET_PPC64)
587
void OPPROTO op_test_ctrz_false_64 (void)
588
{
589
    T0 = ((uint64_t)env->ctr == 0 && (T0 & PARAM1) == 0);
590
    RETURN();
591
}
592
#endif
593

    
594
void OPPROTO op_test_true (void)
595
{
596
    T0 = (T0 & PARAM1);
597
    RETURN();
598
}
599

    
600
void OPPROTO op_test_false (void)
601
{
602
    T0 = ((T0 & PARAM1) == 0);
603
    RETURN();
604
}
605

    
606
/* CTR maintenance */
607
void OPPROTO op_dec_ctr (void)
608
{
609
    env->ctr--;
610
    RETURN();
611
}
612

    
613
/***                           Integer arithmetic                          ***/
614
/* add */
615
void OPPROTO op_add (void)
616
{
617
    T0 += T1;
618
    RETURN();
619
}
620

    
621
void OPPROTO op_check_addo (void)
622
{
623
    xer_ov = (((uint32_t)T2 ^ (uint32_t)T1 ^ UINT32_MAX) &
624
              ((uint32_t)T2 ^ (uint32_t)T0)) >> 31;
625
    xer_so |= xer_ov;
626
    RETURN();
627
}
628

    
629
#if defined(TARGET_PPC64)
630
void OPPROTO op_check_addo_64 (void)
631
{
632
    xer_ov = (((uint64_t)T2 ^ (uint64_t)T1 ^ UINT64_MAX) &
633
              ((uint64_t)T2 ^ (uint64_t)T0)) >> 63;
634
    xer_so |= xer_ov;
635
    RETURN();
636
}
637
#endif
638

    
639
/* add carrying */
640
void OPPROTO op_check_addc (void)
641
{
642
    if (likely((uint32_t)T0 >= (uint32_t)T2)) {
643
        xer_ca = 0;
644
    } else {
645
        xer_ca = 1;
646
    }
647
    RETURN();
648
}
649

    
650
#if defined(TARGET_PPC64)
651
void OPPROTO op_check_addc_64 (void)
652
{
653
    if (likely((uint64_t)T0 >= (uint64_t)T2)) {
654
        xer_ca = 0;
655
    } else {
656
        xer_ca = 1;
657
    }
658
    RETURN();
659
}
660
#endif
661

    
662
/* add extended */
663
void OPPROTO op_adde (void)
664
{
665
    do_adde();
666
    RETURN();
667
}
668

    
669
#if defined(TARGET_PPC64)
670
void OPPROTO op_adde_64 (void)
671
{
672
    do_adde_64();
673
    RETURN();
674
}
675
#endif
676

    
677
/* add immediate */
678
void OPPROTO op_addi (void)
679
{
680
    T0 += (int32_t)PARAM1;
681
    RETURN();
682
}
683

    
684
/* add to minus one extended */
685
void OPPROTO op_add_me (void)
686
{
687
    T0 += xer_ca + (-1);
688
    if (likely((uint32_t)T1 != 0))
689
        xer_ca = 1;
690
    else
691
        xer_ca = 0;
692
    RETURN();
693
}
694

    
695
#if defined(TARGET_PPC64)
696
void OPPROTO op_add_me_64 (void)
697
{
698
    T0 += xer_ca + (-1);
699
    if (likely((uint64_t)T1 != 0))
700
        xer_ca = 1;
701
    else
702
        xer_ca = 0;
703
    RETURN();
704
}
705
#endif
706

    
707
void OPPROTO op_addmeo (void)
708
{
709
    do_addmeo();
710
    RETURN();
711
}
712

    
713
void OPPROTO op_addmeo_64 (void)
714
{
715
    do_addmeo();
716
    RETURN();
717
}
718

    
719
/* add to zero extended */
720
void OPPROTO op_add_ze (void)
721
{
722
    T0 += xer_ca;
723
    RETURN();
724
}
725

    
726
/* divide word */
727
void OPPROTO op_divw (void)
728
{
729
    if (unlikely(((int32_t)T0 == INT32_MIN && (int32_t)T1 == (int32_t)-1) ||
730
                 (int32_t)T1 == 0)) {
731
        T0 = (int32_t)(UINT32_MAX * ((uint32_t)T0 >> 31));
732
    } else {
733
        T0 = (int32_t)T0 / (int32_t)T1;
734
    }
735
    RETURN();
736
}
737

    
738
#if defined(TARGET_PPC64)
739
void OPPROTO op_divd (void)
740
{
741
    if (unlikely(((int64_t)T0 == INT64_MIN && (int64_t)T1 == (int64_t)-1LL) ||
742
                 (int64_t)T1 == 0)) {
743
        T0 = (int64_t)(UINT64_MAX * ((uint64_t)T0 >> 63));
744
    } else {
745
        T0 = (int64_t)T0 / (int64_t)T1;
746
    }
747
    RETURN();
748
}
749
#endif
750

    
751
void OPPROTO op_divwo (void)
752
{
753
    do_divwo();
754
    RETURN();
755
}
756

    
757
#if defined(TARGET_PPC64)
758
void OPPROTO op_divdo (void)
759
{
760
    do_divdo();
761
    RETURN();
762
}
763
#endif
764

    
765
/* divide word unsigned */
766
void OPPROTO op_divwu (void)
767
{
768
    if (unlikely(T1 == 0)) {
769
        T0 = 0;
770
    } else {
771
        T0 = (uint32_t)T0 / (uint32_t)T1;
772
    }
773
    RETURN();
774
}
775

    
776
#if defined(TARGET_PPC64)
777
void OPPROTO op_divdu (void)
778
{
779
    if (unlikely(T1 == 0)) {
780
        T0 = 0;
781
    } else {
782
        T0 /= T1;
783
    }
784
    RETURN();
785
}
786
#endif
787

    
788
void OPPROTO op_divwuo (void)
789
{
790
    do_divwuo();
791
    RETURN();
792
}
793

    
794
#if defined(TARGET_PPC64)
795
void OPPROTO op_divduo (void)
796
{
797
    do_divduo();
798
    RETURN();
799
}
800
#endif
801

    
802
/* multiply high word */
803
void OPPROTO op_mulhw (void)
804
{
805
    T0 = ((int64_t)((int32_t)T0) * (int64_t)((int32_t)T1)) >> 32;
806
    RETURN();
807
}
808

    
809
#if defined(TARGET_PPC64)
810
void OPPROTO op_mulhd (void)
811
{
812
    uint64_t tl, th;
813

    
814
    muls64(&tl, &th, T0, T1);
815
    T0 = th;
816
    RETURN();
817
}
818
#endif
819

    
820
/* multiply high word unsigned */
821
void OPPROTO op_mulhwu (void)
822
{
823
    T0 = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1) >> 32;
824
    RETURN();
825
}
826

    
827
#if defined(TARGET_PPC64)
828
void OPPROTO op_mulhdu (void)
829
{
830
    uint64_t tl, th;
831

    
832
    mulu64(&tl, &th, T0, T1);
833
    T0 = th;
834
    RETURN();
835
}
836
#endif
837

    
838
/* multiply low immediate */
839
void OPPROTO op_mulli (void)
840
{
841
    T0 = ((int32_t)T0 * (int32_t)PARAM1);
842
    RETURN();
843
}
844

    
845
/* multiply low word */
846
void OPPROTO op_mullw (void)
847
{
848
    T0 = (int32_t)(T0 * T1);
849
    RETURN();
850
}
851

    
852
#if defined(TARGET_PPC64)
853
void OPPROTO op_mulld (void)
854
{
855
    T0 *= T1;
856
    RETURN();
857
}
858
#endif
859

    
860
void OPPROTO op_mullwo (void)
861
{
862
    do_mullwo();
863
    RETURN();
864
}
865

    
866
#if defined(TARGET_PPC64)
867
void OPPROTO op_mulldo (void)
868
{
869
    do_mulldo();
870
    RETURN();
871
}
872
#endif
873

    
874
/* negate */
875
void OPPROTO op_neg (void)
876
{
877
    if (likely(T0 != INT32_MIN)) {
878
        T0 = -(int32_t)T0;
879
    }
880
    RETURN();
881
}
882

    
883
#if defined(TARGET_PPC64)
884
void OPPROTO op_neg_64 (void)
885
{
886
    if (likely(T0 != INT64_MIN)) {
887
        T0 = -(int64_t)T0;
888
    }
889
    RETURN();
890
}
891
#endif
892

    
893
void OPPROTO op_nego (void)
894
{
895
    do_nego();
896
    RETURN();
897
}
898

    
899
#if defined(TARGET_PPC64)
900
void OPPROTO op_nego_64 (void)
901
{
902
    do_nego_64();
903
    RETURN();
904
}
905
#endif
906

    
907
/* subtract from */
908
void OPPROTO op_subf (void)
909
{
910
    T0 = T1 - T0;
911
    RETURN();
912
}
913

    
914
/* subtract from carrying */
915
void OPPROTO op_check_subfc (void)
916
{
917
    if (likely((uint32_t)T0 > (uint32_t)T1)) {
918
        xer_ca = 0;
919
    } else {
920
        xer_ca = 1;
921
    }
922
    RETURN();
923
}
924

    
925
#if defined(TARGET_PPC64)
926
void OPPROTO op_check_subfc_64 (void)
927
{
928
    if (likely((uint64_t)T0 > (uint64_t)T1)) {
929
        xer_ca = 0;
930
    } else {
931
        xer_ca = 1;
932
    }
933
    RETURN();
934
}
935
#endif
936

    
937
/* subtract from extended */
938
void OPPROTO op_subfe (void)
939
{
940
    do_subfe();
941
    RETURN();
942
}
943

    
944
#if defined(TARGET_PPC64)
945
void OPPROTO op_subfe_64 (void)
946
{
947
    do_subfe_64();
948
    RETURN();
949
}
950
#endif
951

    
952
/* subtract from immediate carrying */
953
void OPPROTO op_subfic (void)
954
{
955
    T0 = (int32_t)PARAM1 + ~T0 + 1;
956
    if ((uint32_t)T0 <= (uint32_t)PARAM1) {
957
        xer_ca = 1;
958
    } else {
959
        xer_ca = 0;
960
    }
961
    RETURN();
962
}
963

    
964
#if defined(TARGET_PPC64)
965
void OPPROTO op_subfic_64 (void)
966
{
967
    T0 = (int64_t)PARAM1 + ~T0 + 1;
968
    if ((uint64_t)T0 <= (uint64_t)PARAM1) {
969
        xer_ca = 1;
970
    } else {
971
        xer_ca = 0;
972
    }
973
    RETURN();
974
}
975
#endif
976

    
977
/* subtract from minus one extended */
978
void OPPROTO op_subfme (void)
979
{
980
    T0 = ~T0 + xer_ca - 1;
981
    if (likely((uint32_t)T0 != UINT32_MAX))
982
        xer_ca = 1;
983
    else
984
        xer_ca = 0;
985
    RETURN();
986
}
987

    
988
#if defined(TARGET_PPC64)
989
void OPPROTO op_subfme_64 (void)
990
{
991
    T0 = ~T0 + xer_ca - 1;
992
    if (likely((uint64_t)T0 != UINT64_MAX))
993
        xer_ca = 1;
994
    else
995
        xer_ca = 0;
996
    RETURN();
997
}
998
#endif
999

    
1000
void OPPROTO op_subfmeo (void)
1001
{
1002
    do_subfmeo();
1003
    RETURN();
1004
}
1005

    
1006
#if defined(TARGET_PPC64)
1007
void OPPROTO op_subfmeo_64 (void)
1008
{
1009
    do_subfmeo_64();
1010
    RETURN();
1011
}
1012
#endif
1013

    
1014
/* subtract from zero extended */
1015
void OPPROTO op_subfze (void)
1016
{
1017
    T1 = ~T0;
1018
    T0 = T1 + xer_ca;
1019
    if ((uint32_t)T0 < (uint32_t)T1) {
1020
        xer_ca = 1;
1021
    } else {
1022
        xer_ca = 0;
1023
    }
1024
    RETURN();
1025
}
1026

    
1027
#if defined(TARGET_PPC64)
1028
void OPPROTO op_subfze_64 (void)
1029
{
1030
    T1 = ~T0;
1031
    T0 = T1 + xer_ca;
1032
    if ((uint64_t)T0 < (uint64_t)T1) {
1033
        xer_ca = 1;
1034
    } else {
1035
        xer_ca = 0;
1036
    }
1037
    RETURN();
1038
}
1039
#endif
1040

    
1041
void OPPROTO op_subfzeo (void)
1042
{
1043
    do_subfzeo();
1044
    RETURN();
1045
}
1046

    
1047
#if defined(TARGET_PPC64)
1048
void OPPROTO op_subfzeo_64 (void)
1049
{
1050
    do_subfzeo_64();
1051
    RETURN();
1052
}
1053
#endif
1054

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

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

    
1085
/* compare immediate */
1086
void OPPROTO op_cmpi (void)
1087
{
1088
    if ((int32_t)T0 < (int32_t)PARAM1) {
1089
        T0 = 0x08;
1090
    } else if ((int32_t)T0 > (int32_t)PARAM1) {
1091
        T0 = 0x04;
1092
    } else {
1093
        T0 = 0x02;
1094
    }
1095
    T0 |= xer_so;
1096
    RETURN();
1097
}
1098

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

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

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

    
1143
/* compare logical immediate */
1144
void OPPROTO op_cmpli (void)
1145
{
1146
    if ((uint32_t)T0 < (uint32_t)PARAM1) {
1147
        T0 = 0x08;
1148
    } else if ((uint32_t)T0 > (uint32_t)PARAM1) {
1149
        T0 = 0x04;
1150
    } else {
1151
        T0 = 0x02;
1152
    }
1153
    T0 |= xer_so;
1154
    RETURN();
1155
}
1156

    
1157
#if defined(TARGET_PPC64)
1158
void OPPROTO op_cmpli_64 (void)
1159
{
1160
    if ((uint64_t)T0 < (uint64_t)PARAM1) {
1161
        T0 = 0x08;
1162
    } else if ((uint64_t)T0 > (uint64_t)PARAM1) {
1163
        T0 = 0x04;
1164
    } else {
1165
        T0 = 0x02;
1166
    }
1167
    T0 |= xer_so;
1168
    RETURN();
1169
}
1170
#endif
1171

    
1172
void OPPROTO op_isel (void)
1173
{
1174
    if (T0)
1175
        T0 = T1;
1176
    else
1177
        T0 = T2;
1178
    RETURN();
1179
}
1180

    
1181
void OPPROTO op_popcntb (void)
1182
{
1183
    do_popcntb();
1184
    RETURN();
1185
}
1186

    
1187
#if defined(TARGET_PPC64)
1188
void OPPROTO op_popcntb_64 (void)
1189
{
1190
    do_popcntb_64();
1191
    RETURN();
1192
}
1193
#endif
1194

    
1195
/***                            Integer logical                            ***/
1196
/* and */
1197
void OPPROTO op_and (void)
1198
{
1199
    T0 &= T1;
1200
    RETURN();
1201
}
1202

    
1203
/* andc */
1204
void OPPROTO op_andc (void)
1205
{
1206
    T0 &= ~T1;
1207
    RETURN();
1208
}
1209

    
1210
/* andi. */
1211
void OPPROTO op_andi_T0 (void)
1212
{
1213
    T0 &= (uint32_t)PARAM1;
1214
    RETURN();
1215
}
1216

    
1217
void OPPROTO op_andi_T1 (void)
1218
{
1219
    T1 &= (uint32_t)PARAM1;
1220
    RETURN();
1221
}
1222

    
1223
#if defined(TARGET_PPC64)
1224
void OPPROTO op_andi_T0_64 (void)
1225
{
1226
    T0 &= ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
1227
    RETURN();
1228
}
1229

    
1230
void OPPROTO op_andi_T1_64 (void)
1231
{
1232
    T1 &= ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
1233
    RETURN();
1234
}
1235
#endif
1236

    
1237
/* count leading zero */
1238
void OPPROTO op_cntlzw (void)
1239
{
1240
    do_cntlzw();
1241
    RETURN();
1242
}
1243

    
1244
#if defined(TARGET_PPC64)
1245
void OPPROTO op_cntlzd (void)
1246
{
1247
    do_cntlzd();
1248
    RETURN();
1249
}
1250
#endif
1251

    
1252
/* eqv */
1253
void OPPROTO op_eqv (void)
1254
{
1255
    T0 = ~(T0 ^ T1);
1256
    RETURN();
1257
}
1258

    
1259
/* extend sign byte */
1260
void OPPROTO op_extsb (void)
1261
{
1262
#if defined (TARGET_PPC64)
1263
    T0 = (int64_t)((int8_t)T0);
1264
#else
1265
    T0 = (int32_t)((int8_t)T0);
1266
#endif
1267
    RETURN();
1268
}
1269

    
1270
/* extend sign half word */
1271
void OPPROTO op_extsh (void)
1272
{
1273
#if defined (TARGET_PPC64)
1274
    T0 = (int64_t)((int16_t)T0);
1275
#else
1276
    T0 = (int32_t)((int16_t)T0);
1277
#endif
1278
    RETURN();
1279
}
1280

    
1281
#if defined (TARGET_PPC64)
1282
void OPPROTO op_extsw (void)
1283
{
1284
    T0 = (int64_t)((int32_t)T0);
1285
    RETURN();
1286
}
1287
#endif
1288

    
1289
/* nand */
1290
void OPPROTO op_nand (void)
1291
{
1292
    T0 = ~(T0 & T1);
1293
    RETURN();
1294
}
1295

    
1296
/* nor */
1297
void OPPROTO op_nor (void)
1298
{
1299
    T0 = ~(T0 | T1);
1300
    RETURN();
1301
}
1302

    
1303
/* or */
1304
void OPPROTO op_or (void)
1305
{
1306
    T0 |= T1;
1307
    RETURN();
1308
}
1309

    
1310
/* orc */
1311
void OPPROTO op_orc (void)
1312
{
1313
    T0 |= ~T1;
1314
    RETURN();
1315
}
1316

    
1317
/* ori */
1318
void OPPROTO op_ori (void)
1319
{
1320
    T0 |= (uint32_t)PARAM1;
1321
    RETURN();
1322
}
1323

    
1324
/* xor */
1325
void OPPROTO op_xor (void)
1326
{
1327
    T0 ^= T1;
1328
    RETURN();
1329
}
1330

    
1331
/* xori */
1332
void OPPROTO op_xori (void)
1333
{
1334
    T0 ^= (uint32_t)PARAM1;
1335
    RETURN();
1336
}
1337

    
1338
/***                             Integer rotate                            ***/
1339
void OPPROTO op_rotl32_T0_T1 (void)
1340
{
1341
    T0 = rotl32(T0, T1 & 0x1F);
1342
    RETURN();
1343
}
1344

    
1345
void OPPROTO op_rotli32_T0 (void)
1346
{
1347
    T0 = rotl32(T0, PARAM1);
1348
    RETURN();
1349
}
1350

    
1351
#if defined(TARGET_PPC64)
1352
void OPPROTO op_rotl64_T0_T1 (void)
1353
{
1354
    T0 = rotl64(T0, T1 & 0x3F);
1355
    RETURN();
1356
}
1357

    
1358
void OPPROTO op_rotli64_T0 (void)
1359
{
1360
    T0 = rotl64(T0, PARAM1);
1361
    RETURN();
1362
}
1363
#endif
1364

    
1365
/***                             Integer shift                             ***/
1366
/* shift left word */
1367
void OPPROTO op_slw (void)
1368
{
1369
    if (T1 & 0x20) {
1370
        T0 = 0;
1371
    } else {
1372
        T0 = (uint32_t)(T0 << T1);
1373
    }
1374
    RETURN();
1375
}
1376

    
1377
#if defined(TARGET_PPC64)
1378
void OPPROTO op_sld (void)
1379
{
1380
    if (T1 & 0x40) {
1381
        T0 = 0;
1382
    } else {
1383
        T0 = T0 << T1;
1384
    }
1385
    RETURN();
1386
}
1387
#endif
1388

    
1389
/* shift right algebraic word */
1390
void OPPROTO op_sraw (void)
1391
{
1392
    do_sraw();
1393
    RETURN();
1394
}
1395

    
1396
#if defined(TARGET_PPC64)
1397
void OPPROTO op_srad (void)
1398
{
1399
    do_srad();
1400
    RETURN();
1401
}
1402
#endif
1403

    
1404
/* shift right algebraic word immediate */
1405
void OPPROTO op_srawi (void)
1406
{
1407
    uint32_t mask = (uint32_t)PARAM2;
1408

    
1409
    T0 = (int32_t)T0 >> PARAM1;
1410
    if ((int32_t)T1 < 0 && (T1 & mask) != 0) {
1411
        xer_ca = 1;
1412
    } else {
1413
        xer_ca = 0;
1414
    }
1415
    RETURN();
1416
}
1417

    
1418
#if defined(TARGET_PPC64)
1419
void OPPROTO op_sradi (void)
1420
{
1421
    uint64_t mask = ((uint64_t)PARAM2 << 32) | (uint64_t)PARAM3;
1422

    
1423
    T0 = (int64_t)T0 >> PARAM1;
1424
    if ((int64_t)T1 < 0 && ((uint64_t)T1 & mask) != 0) {
1425
        xer_ca = 1;
1426
    } else {
1427
        xer_ca = 0;
1428
    }
1429
    RETURN();
1430
}
1431
#endif
1432

    
1433
/* shift right word */
1434
void OPPROTO op_srw (void)
1435
{
1436
    if (T1 & 0x20) {
1437
        T0 = 0;
1438
    } else {
1439
        T0 = (uint32_t)T0 >> T1;
1440
    }
1441
    RETURN();
1442
}
1443

    
1444
#if defined(TARGET_PPC64)
1445
void OPPROTO op_srd (void)
1446
{
1447
    if (T1 & 0x40) {
1448
        T0 = 0;
1449
    } else {
1450
        T0 = (uint64_t)T0 >> T1;
1451
    }
1452
    RETURN();
1453
}
1454
#endif
1455

    
1456
void OPPROTO op_sl_T0_T1 (void)
1457
{
1458
    T0 = T0 << T1;
1459
    RETURN();
1460
}
1461

    
1462
void OPPROTO op_sli_T0 (void)
1463
{
1464
    T0 = T0 << PARAM1;
1465
    RETURN();
1466
}
1467

    
1468
void OPPROTO op_sli_T1 (void)
1469
{
1470
    T1 = T1 << PARAM1;
1471
    RETURN();
1472
}
1473

    
1474
void OPPROTO op_srl_T0_T1 (void)
1475
{
1476
    T0 = (uint32_t)T0 >> T1;
1477
    RETURN();
1478
}
1479

    
1480
#if defined(TARGET_PPC64)
1481
void OPPROTO op_srl_T0_T1_64 (void)
1482
{
1483
    T0 = (uint32_t)T0 >> T1;
1484
    RETURN();
1485
}
1486
#endif
1487

    
1488
void OPPROTO op_srli_T0 (void)
1489
{
1490
    T0 = (uint32_t)T0 >> PARAM1;
1491
    RETURN();
1492
}
1493

    
1494
#if defined(TARGET_PPC64)
1495
void OPPROTO op_srli_T0_64 (void)
1496
{
1497
    T0 = (uint64_t)T0 >> PARAM1;
1498
    RETURN();
1499
}
1500
#endif
1501

    
1502
void OPPROTO op_srli_T1 (void)
1503
{
1504
    T1 = (uint32_t)T1 >> PARAM1;
1505
    RETURN();
1506
}
1507

    
1508
#if defined(TARGET_PPC64)
1509
void OPPROTO op_srli_T1_64 (void)
1510
{
1511
    T1 = (uint64_t)T1 >> PARAM1;
1512
    RETURN();
1513
}
1514
#endif
1515

    
1516
/***                       Floating-Point arithmetic                       ***/
1517
/* fadd - fadd. */
1518
void OPPROTO op_fadd (void)
1519
{
1520
#if USE_PRECISE_EMULATION
1521
    do_fadd();
1522
#else
1523
    FT0 = float64_add(FT0, FT1, &env->fp_status);
1524
#endif
1525
    RETURN();
1526
}
1527

    
1528
/* fsub - fsub. */
1529
void OPPROTO op_fsub (void)
1530
{
1531
#if USE_PRECISE_EMULATION
1532
    do_fsub();
1533
#else
1534
    FT0 = float64_sub(FT0, FT1, &env->fp_status);
1535
#endif
1536
    RETURN();
1537
}
1538

    
1539
/* fmul - fmul. */
1540
void OPPROTO op_fmul (void)
1541
{
1542
#if USE_PRECISE_EMULATION
1543
    do_fmul();
1544
#else
1545
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1546
#endif
1547
    RETURN();
1548
}
1549

    
1550
/* fdiv - fdiv. */
1551
void OPPROTO op_fdiv (void)
1552
{
1553
#if USE_PRECISE_EMULATION
1554
    do_fdiv();
1555
#else
1556
    FT0 = float64_div(FT0, FT1, &env->fp_status);
1557
#endif
1558
    RETURN();
1559
}
1560

    
1561
/* fsqrt - fsqrt. */
1562
void OPPROTO op_fsqrt (void)
1563
{
1564
    do_fsqrt();
1565
    RETURN();
1566
}
1567

    
1568
/* fre - fre. */
1569
void OPPROTO op_fre (void)
1570
{
1571
    do_fre();
1572
    RETURN();
1573
}
1574

    
1575
/* fres - fres. */
1576
void OPPROTO op_fres (void)
1577
{
1578
    do_fres();
1579
    RETURN();
1580
}
1581

    
1582
/* frsqrte  - frsqrte. */
1583
void OPPROTO op_frsqrte (void)
1584
{
1585
    do_frsqrte();
1586
    RETURN();
1587
}
1588

    
1589
/* fsel - fsel. */
1590
void OPPROTO op_fsel (void)
1591
{
1592
    do_fsel();
1593
    RETURN();
1594
}
1595

    
1596
/***                     Floating-Point multiply-and-add                   ***/
1597
/* fmadd - fmadd. */
1598
void OPPROTO op_fmadd (void)
1599
{
1600
#if USE_PRECISE_EMULATION
1601
    do_fmadd();
1602
#else
1603
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1604
    FT0 = float64_add(FT0, FT2, &env->fp_status);
1605
#endif
1606
    RETURN();
1607
}
1608

    
1609
/* fmsub - fmsub. */
1610
void OPPROTO op_fmsub (void)
1611
{
1612
#if USE_PRECISE_EMULATION
1613
    do_fmsub();
1614
#else
1615
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1616
    FT0 = float64_sub(FT0, FT2, &env->fp_status);
1617
#endif
1618
    RETURN();
1619
}
1620

    
1621
/* fnmadd - fnmadd. - fnmadds - fnmadds. */
1622
void OPPROTO op_fnmadd (void)
1623
{
1624
    do_fnmadd();
1625
    RETURN();
1626
}
1627

    
1628
/* fnmsub - fnmsub. */
1629
void OPPROTO op_fnmsub (void)
1630
{
1631
    do_fnmsub();
1632
    RETURN();
1633
}
1634

    
1635
/***                     Floating-Point round & convert                    ***/
1636
/* frsp - frsp. */
1637
void OPPROTO op_frsp (void)
1638
{
1639
#if USE_PRECISE_EMULATION
1640
    do_frsp();
1641
#else
1642
    FT0 = float64_to_float32(FT0, &env->fp_status);
1643
#endif
1644
    RETURN();
1645
}
1646

    
1647
/* fctiw - fctiw. */
1648
void OPPROTO op_fctiw (void)
1649
{
1650
    do_fctiw();
1651
    RETURN();
1652
}
1653

    
1654
/* fctiwz - fctiwz. */
1655
void OPPROTO op_fctiwz (void)
1656
{
1657
    do_fctiwz();
1658
    RETURN();
1659
}
1660

    
1661
#if defined(TARGET_PPC64)
1662
/* fcfid - fcfid. */
1663
void OPPROTO op_fcfid (void)
1664
{
1665
    do_fcfid();
1666
    RETURN();
1667
}
1668

    
1669
/* fctid - fctid. */
1670
void OPPROTO op_fctid (void)
1671
{
1672
    do_fctid();
1673
    RETURN();
1674
}
1675

    
1676
/* fctidz - fctidz. */
1677
void OPPROTO op_fctidz (void)
1678
{
1679
    do_fctidz();
1680
    RETURN();
1681
}
1682
#endif
1683

    
1684
void OPPROTO op_frin (void)
1685
{
1686
    do_frin();
1687
    RETURN();
1688
}
1689

    
1690
void OPPROTO op_friz (void)
1691
{
1692
    do_friz();
1693
    RETURN();
1694
}
1695

    
1696
void OPPROTO op_frip (void)
1697
{
1698
    do_frip();
1699
    RETURN();
1700
}
1701

    
1702
void OPPROTO op_frim (void)
1703
{
1704
    do_frim();
1705
    RETURN();
1706
}
1707

    
1708
/***                         Floating-Point compare                        ***/
1709
/* fcmpu */
1710
void OPPROTO op_fcmpu (void)
1711
{
1712
    do_fcmpu();
1713
    RETURN();
1714
}
1715

    
1716
/* fcmpo */
1717
void OPPROTO op_fcmpo (void)
1718
{
1719
    do_fcmpo();
1720
    RETURN();
1721
}
1722

    
1723
/***                         Floating-point move                           ***/
1724
/* fabs */
1725
void OPPROTO op_fabs (void)
1726
{
1727
    FT0 = float64_abs(FT0);
1728
    RETURN();
1729
}
1730

    
1731
/* fnabs */
1732
void OPPROTO op_fnabs (void)
1733
{
1734
    FT0 = float64_abs(FT0);
1735
    FT0 = float64_chs(FT0);
1736
    RETURN();
1737
}
1738

    
1739
/* fneg */
1740
void OPPROTO op_fneg (void)
1741
{
1742
    FT0 = float64_chs(FT0);
1743
    RETURN();
1744
}
1745

    
1746
/* Load and store */
1747
#define MEMSUFFIX _raw
1748
#include "op_helper.h"
1749
#include "op_mem.h"
1750
#if !defined(CONFIG_USER_ONLY)
1751
#define MEMSUFFIX _user
1752
#include "op_helper.h"
1753
#include "op_mem.h"
1754
#define MEMSUFFIX _kernel
1755
#include "op_helper.h"
1756
#include "op_mem.h"
1757
#define MEMSUFFIX _hypv
1758
#include "op_helper.h"
1759
#include "op_mem.h"
1760
#endif
1761

    
1762
/* Special op to check and maybe clear reservation */
1763
void OPPROTO op_check_reservation (void)
1764
{
1765
    if ((uint32_t)env->reserve == (uint32_t)(T0 & ~0x00000003))
1766
        env->reserve = (target_ulong)-1ULL;
1767
    RETURN();
1768
}
1769

    
1770
#if defined(TARGET_PPC64)
1771
void OPPROTO op_check_reservation_64 (void)
1772
{
1773
    if ((uint64_t)env->reserve == (uint64_t)(T0 & ~0x00000003))
1774
        env->reserve = (target_ulong)-1ULL;
1775
    RETURN();
1776
}
1777
#endif
1778

    
1779
void OPPROTO op_wait (void)
1780
{
1781
    env->halted = 1;
1782
    RETURN();
1783
}
1784

    
1785
/* Return from interrupt */
1786
#if !defined(CONFIG_USER_ONLY)
1787
void OPPROTO op_rfi (void)
1788
{
1789
    do_rfi();
1790
    RETURN();
1791
}
1792

    
1793
#if defined(TARGET_PPC64)
1794
void OPPROTO op_rfid (void)
1795
{
1796
    do_rfid();
1797
    RETURN();
1798
}
1799

    
1800
void OPPROTO op_hrfid (void)
1801
{
1802
    do_hrfid();
1803
    RETURN();
1804
}
1805
#endif
1806

    
1807
/* Exception vectors */
1808
void OPPROTO op_store_excp_prefix (void)
1809
{
1810
    T0 &= env->ivpr_mask;
1811
    env->excp_prefix = T0;
1812
    RETURN();
1813
}
1814

    
1815
void OPPROTO op_store_excp_vector (void)
1816
{
1817
    T0 &= env->ivor_mask;
1818
    env->excp_vectors[PARAM1] = T0;
1819
    RETURN();
1820
}
1821
#endif
1822

    
1823
/* Trap word */
1824
void OPPROTO op_tw (void)
1825
{
1826
    do_tw(PARAM1);
1827
    RETURN();
1828
}
1829

    
1830
#if defined(TARGET_PPC64)
1831
void OPPROTO op_td (void)
1832
{
1833
    do_td(PARAM1);
1834
    RETURN();
1835
}
1836
#endif
1837

    
1838
#if !defined(CONFIG_USER_ONLY)
1839
/* tlbia */
1840
void OPPROTO op_tlbia (void)
1841
{
1842
    ppc_tlb_invalidate_all(env);
1843
    RETURN();
1844
}
1845

    
1846
/* tlbie */
1847
void OPPROTO op_tlbie (void)
1848
{
1849
    ppc_tlb_invalidate_one(env, (uint32_t)T0);
1850
    RETURN();
1851
}
1852

    
1853
#if defined(TARGET_PPC64)
1854
void OPPROTO op_tlbie_64 (void)
1855
{
1856
    ppc_tlb_invalidate_one(env, T0);
1857
    RETURN();
1858
}
1859
#endif
1860

    
1861
#if defined(TARGET_PPC64)
1862
void OPPROTO op_slbia (void)
1863
{
1864
    ppc_slb_invalidate_all(env);
1865
    RETURN();
1866
}
1867

    
1868
void OPPROTO op_slbie (void)
1869
{
1870
    ppc_slb_invalidate_one(env, (uint32_t)T0);
1871
    RETURN();
1872
}
1873

    
1874
void OPPROTO op_slbie_64 (void)
1875
{
1876
    ppc_slb_invalidate_one(env, T0);
1877
    RETURN();
1878
}
1879
#endif
1880
#endif
1881

    
1882
#if !defined(CONFIG_USER_ONLY)
1883
/* PowerPC 602/603/755 software TLB load instructions */
1884
void OPPROTO op_6xx_tlbld (void)
1885
{
1886
    do_load_6xx_tlb(0);
1887
    RETURN();
1888
}
1889

    
1890
void OPPROTO op_6xx_tlbli (void)
1891
{
1892
    do_load_6xx_tlb(1);
1893
    RETURN();
1894
}
1895

    
1896
/* PowerPC 74xx software TLB load instructions */
1897
void OPPROTO op_74xx_tlbld (void)
1898
{
1899
    do_load_74xx_tlb(0);
1900
    RETURN();
1901
}
1902

    
1903
void OPPROTO op_74xx_tlbli (void)
1904
{
1905
    do_load_74xx_tlb(1);
1906
    RETURN();
1907
}
1908
#endif
1909

    
1910
/* 601 specific */
1911
void OPPROTO op_load_601_rtcl (void)
1912
{
1913
    T0 = cpu_ppc601_load_rtcl(env);
1914
    RETURN();
1915
}
1916

    
1917
void OPPROTO op_load_601_rtcu (void)
1918
{
1919
    T0 = cpu_ppc601_load_rtcu(env);
1920
    RETURN();
1921
}
1922

    
1923
#if !defined(CONFIG_USER_ONLY)
1924
void OPPROTO op_store_601_rtcl (void)
1925
{
1926
    cpu_ppc601_store_rtcl(env, T0);
1927
    RETURN();
1928
}
1929

    
1930
void OPPROTO op_store_601_rtcu (void)
1931
{
1932
    cpu_ppc601_store_rtcu(env, T0);
1933
    RETURN();
1934
}
1935

    
1936
void OPPROTO op_store_hid0_601 (void)
1937
{
1938
    do_store_hid0_601();
1939
    RETURN();
1940
}
1941

    
1942
void OPPROTO op_load_601_bat (void)
1943
{
1944
    T0 = env->IBAT[PARAM1][PARAM2];
1945
    RETURN();
1946
}
1947

    
1948
void OPPROTO op_store_601_batl (void)
1949
{
1950
    do_store_ibatl_601(env, PARAM1, T0);
1951
    RETURN();
1952
}
1953

    
1954
void OPPROTO op_store_601_batu (void)
1955
{
1956
    do_store_ibatu_601(env, PARAM1, T0);
1957
    RETURN();
1958
}
1959
#endif /* !defined(CONFIG_USER_ONLY) */
1960

    
1961
/* PowerPC 601 specific instructions (POWER bridge) */
1962
/* XXX: those micro-ops need tests ! */
1963
void OPPROTO op_POWER_abs (void)
1964
{
1965
    if ((int32_t)T0 == INT32_MIN)
1966
        T0 = INT32_MAX;
1967
    else if ((int32_t)T0 < 0)
1968
        T0 = -T0;
1969
    RETURN();
1970
}
1971

    
1972
void OPPROTO op_POWER_abso (void)
1973
{
1974
    do_POWER_abso();
1975
    RETURN();
1976
}
1977

    
1978
void OPPROTO op_POWER_clcs (void)
1979
{
1980
    do_POWER_clcs();
1981
    RETURN();
1982
}
1983

    
1984
void OPPROTO op_POWER_div (void)
1985
{
1986
    do_POWER_div();
1987
    RETURN();
1988
}
1989

    
1990
void OPPROTO op_POWER_divo (void)
1991
{
1992
    do_POWER_divo();
1993
    RETURN();
1994
}
1995

    
1996
void OPPROTO op_POWER_divs (void)
1997
{
1998
    do_POWER_divs();
1999
    RETURN();
2000
}
2001

    
2002
void OPPROTO op_POWER_divso (void)
2003
{
2004
    do_POWER_divso();
2005
    RETURN();
2006
}
2007

    
2008
void OPPROTO op_POWER_doz (void)
2009
{
2010
    if ((int32_t)T1 > (int32_t)T0)
2011
        T0 = T1 - T0;
2012
    else
2013
        T0 = 0;
2014
    RETURN();
2015
}
2016

    
2017
void OPPROTO op_POWER_dozo (void)
2018
{
2019
    do_POWER_dozo();
2020
    RETURN();
2021
}
2022

    
2023
void OPPROTO op_load_xer_cmp (void)
2024
{
2025
    T2 = xer_cmp;
2026
    RETURN();
2027
}
2028

    
2029
void OPPROTO op_POWER_maskg (void)
2030
{
2031
    do_POWER_maskg();
2032
    RETURN();
2033
}
2034

    
2035
void OPPROTO op_POWER_maskir (void)
2036
{
2037
    T0 = (T0 & ~T2) | (T1 & T2);
2038
    RETURN();
2039
}
2040

    
2041
void OPPROTO op_POWER_mul (void)
2042
{
2043
    uint64_t tmp;
2044

    
2045
    tmp = (uint64_t)T0 * (uint64_t)T1;
2046
    env->spr[SPR_MQ] = tmp >> 32;
2047
    T0 = tmp;
2048
    RETURN();
2049
}
2050

    
2051
void OPPROTO op_POWER_mulo (void)
2052
{
2053
    do_POWER_mulo();
2054
    RETURN();
2055
}
2056

    
2057
void OPPROTO op_POWER_nabs (void)
2058
{
2059
    if (T0 > 0)
2060
        T0 = -T0;
2061
    RETURN();
2062
}
2063

    
2064
void OPPROTO op_POWER_nabso (void)
2065
{
2066
    /* nabs never overflows */
2067
    if (T0 > 0)
2068
        T0 = -T0;
2069
    xer_ov = 0;
2070
    RETURN();
2071
}
2072

    
2073
/* XXX: factorise POWER rotates... */
2074
void OPPROTO op_POWER_rlmi (void)
2075
{
2076
    T0 = rotl32(T0, T2) & PARAM1;
2077
    T0 |= T1 & (uint32_t)PARAM2;
2078
    RETURN();
2079
}
2080

    
2081
void OPPROTO op_POWER_rrib (void)
2082
{
2083
    T2 &= 0x1FUL;
2084
    T0 = rotl32(T0 & INT32_MIN, T2);
2085
    T0 |= T1 & ~rotl32(INT32_MIN, T2);
2086
    RETURN();
2087
}
2088

    
2089
void OPPROTO op_POWER_sle (void)
2090
{
2091
    T1 &= 0x1FUL;
2092
    env->spr[SPR_MQ] = rotl32(T0, T1);
2093
    T0 = T0 << T1;
2094
    RETURN();
2095
}
2096

    
2097
void OPPROTO op_POWER_sleq (void)
2098
{
2099
    uint32_t tmp = env->spr[SPR_MQ];
2100

    
2101
    T1 &= 0x1FUL;
2102
    env->spr[SPR_MQ] = rotl32(T0, T1);
2103
    T0 = T0 << T1;
2104
    T0 |= tmp >> (32 - T1);
2105
    RETURN();
2106
}
2107

    
2108
void OPPROTO op_POWER_sllq (void)
2109
{
2110
    uint32_t msk = UINT32_MAX;
2111

    
2112
    msk = msk << (T1 & 0x1FUL);
2113
    if (T1 & 0x20UL)
2114
        msk = ~msk;
2115
    T1 &= 0x1FUL;
2116
    T0 = (T0 << T1) & msk;
2117
    T0 |= env->spr[SPR_MQ] & ~msk;
2118
    RETURN();
2119
}
2120

    
2121
void OPPROTO op_POWER_slq (void)
2122
{
2123
    uint32_t msk = UINT32_MAX, tmp;
2124

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

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

    
2145
void OPPROTO op_POWER_sre (void)
2146
{
2147
    T1 &= 0x1FUL;
2148
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2149
    T0 = (int32_t)T0 >> T1;
2150
    RETURN();
2151
}
2152

    
2153
void OPPROTO op_POWER_srea (void)
2154
{
2155
    T1 &= 0x1FUL;
2156
    env->spr[SPR_MQ] = T0 >> T1;
2157
    T0 = (int32_t)T0 >> T1;
2158
    RETURN();
2159
}
2160

    
2161
void OPPROTO op_POWER_sreq (void)
2162
{
2163
    uint32_t tmp;
2164
    int32_t msk;
2165

    
2166
    T1 &= 0x1FUL;
2167
    msk = INT32_MIN >> T1;
2168
    tmp = env->spr[SPR_MQ];
2169
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2170
    T0 = T0 >> T1;
2171
    T0 |= tmp & msk;
2172
    RETURN();
2173
}
2174

    
2175
void OPPROTO op_POWER_srlq (void)
2176
{
2177
    uint32_t tmp;
2178
    int32_t msk;
2179

    
2180
    msk = INT32_MIN >> (T1 & 0x1FUL);
2181
    if (T1 & 0x20UL)
2182
        msk = ~msk;
2183
    T1 &= 0x1FUL;
2184
    tmp = env->spr[SPR_MQ];
2185
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2186
    T0 = T0 >> T1;
2187
    T0 &= msk;
2188
    T0 |= tmp & ~msk;
2189
    RETURN();
2190
}
2191

    
2192
void OPPROTO op_POWER_srq (void)
2193
{
2194
    T1 &= 0x1FUL;
2195
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2196
    T0 = T0 >> T1;
2197
    RETURN();
2198
}
2199

    
2200
/* POWER instructions not implemented in PowerPC 601 */
2201
#if !defined(CONFIG_USER_ONLY)
2202
void OPPROTO op_POWER_mfsri (void)
2203
{
2204
    T1 = T0 >> 28;
2205
    T0 = env->sr[T1];
2206
    RETURN();
2207
}
2208

    
2209
void OPPROTO op_POWER_rac (void)
2210
{
2211
    do_POWER_rac();
2212
    RETURN();
2213
}
2214

    
2215
void OPPROTO op_POWER_rfsvc (void)
2216
{
2217
    do_POWER_rfsvc();
2218
    RETURN();
2219
}
2220
#endif
2221

    
2222
/* PowerPC 602 specific instruction */
2223
#if !defined(CONFIG_USER_ONLY)
2224
void OPPROTO op_602_mfrom (void)
2225
{
2226
    do_op_602_mfrom();
2227
    RETURN();
2228
}
2229
#endif
2230

    
2231
/* PowerPC 4xx specific micro-ops */
2232
void OPPROTO op_405_add_T0_T2 (void)
2233
{
2234
    T0 = (int32_t)T0 + (int32_t)T2;
2235
    RETURN();
2236
}
2237

    
2238
void OPPROTO op_405_mulchw (void)
2239
{
2240
    T0 = ((int16_t)T0) * ((int16_t)(T1 >> 16));
2241
    RETURN();
2242
}
2243

    
2244
void OPPROTO op_405_mulchwu (void)
2245
{
2246
    T0 = ((uint16_t)T0) * ((uint16_t)(T1 >> 16));
2247
    RETURN();
2248
}
2249

    
2250
void OPPROTO op_405_mulhhw (void)
2251
{
2252
    T0 = ((int16_t)(T0 >> 16)) * ((int16_t)(T1 >> 16));
2253
    RETURN();
2254
}
2255

    
2256
void OPPROTO op_405_mulhhwu (void)
2257
{
2258
    T0 = ((uint16_t)(T0 >> 16)) * ((uint16_t)(T1 >> 16));
2259
    RETURN();
2260
}
2261

    
2262
void OPPROTO op_405_mullhw (void)
2263
{
2264
    T0 = ((int16_t)T0) * ((int16_t)T1);
2265
    RETURN();
2266
}
2267

    
2268
void OPPROTO op_405_mullhwu (void)
2269
{
2270
    T0 = ((uint16_t)T0) * ((uint16_t)T1);
2271
    RETURN();
2272
}
2273

    
2274
void OPPROTO op_405_check_sat (void)
2275
{
2276
    do_405_check_sat();
2277
    RETURN();
2278
}
2279

    
2280
void OPPROTO op_405_check_ovu (void)
2281
{
2282
    if (likely(T0 >= T2)) {
2283
        xer_ov = 0;
2284
    } else {
2285
        xer_ov = 1;
2286
        xer_so = 1;
2287
    }
2288
    RETURN();
2289
}
2290

    
2291
void OPPROTO op_405_check_satu (void)
2292
{
2293
    if (unlikely(T0 < T2)) {
2294
        /* Saturate result */
2295
        T0 = UINT32_MAX;
2296
    }
2297
    RETURN();
2298
}
2299

    
2300
void OPPROTO op_load_dcr (void)
2301
{
2302
    do_load_dcr();
2303
    RETURN();
2304
}
2305

    
2306
void OPPROTO op_store_dcr (void)
2307
{
2308
    do_store_dcr();
2309
    RETURN();
2310
}
2311

    
2312
#if !defined(CONFIG_USER_ONLY)
2313
/* Return from critical interrupt :
2314
 * same as rfi, except nip & MSR are loaded from SRR2/3 instead of SRR0/1
2315
 */
2316
void OPPROTO op_40x_rfci (void)
2317
{
2318
    do_40x_rfci();
2319
    RETURN();
2320
}
2321

    
2322
void OPPROTO op_rfci (void)
2323
{
2324
    do_rfci();
2325
    RETURN();
2326
}
2327

    
2328
void OPPROTO op_rfdi (void)
2329
{
2330
    do_rfdi();
2331
    RETURN();
2332
}
2333

    
2334
void OPPROTO op_rfmci (void)
2335
{
2336
    do_rfmci();
2337
    RETURN();
2338
}
2339

    
2340
void OPPROTO op_wrte (void)
2341
{
2342
    /* We don't call do_store_msr here as we won't trigger
2343
     * any special case nor change hflags
2344
     */
2345
    T0 &= 1 << MSR_EE;
2346
    env->msr &= ~(1 << MSR_EE);
2347
    env->msr |= T0;
2348
    RETURN();
2349
}
2350

    
2351
void OPPROTO op_440_tlbre (void)
2352
{
2353
    do_440_tlbre(PARAM1);
2354
    RETURN();
2355
}
2356

    
2357
void OPPROTO op_440_tlbsx (void)
2358
{
2359
    T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_440_MMUCR] & 0xFF);
2360
    RETURN();
2361
}
2362

    
2363
void OPPROTO op_4xx_tlbsx_check (void)
2364
{
2365
    int tmp;
2366

    
2367
    tmp = xer_so;
2368
    if ((int)T0 != -1)
2369
        tmp |= 0x02;
2370
    env->crf[0] = tmp;
2371
    RETURN();
2372
}
2373

    
2374
void OPPROTO op_440_tlbwe (void)
2375
{
2376
    do_440_tlbwe(PARAM1);
2377
    RETURN();
2378
}
2379

    
2380
void OPPROTO op_4xx_tlbre_lo (void)
2381
{
2382
    do_4xx_tlbre_lo();
2383
    RETURN();
2384
}
2385

    
2386
void OPPROTO op_4xx_tlbre_hi (void)
2387
{
2388
    do_4xx_tlbre_hi();
2389
    RETURN();
2390
}
2391

    
2392
void OPPROTO op_4xx_tlbsx (void)
2393
{
2394
    T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_40x_PID]);
2395
    RETURN();
2396
}
2397

    
2398
void OPPROTO op_4xx_tlbwe_lo (void)
2399
{
2400
    do_4xx_tlbwe_lo();
2401
    RETURN();
2402
}
2403

    
2404
void OPPROTO op_4xx_tlbwe_hi (void)
2405
{
2406
    do_4xx_tlbwe_hi();
2407
    RETURN();
2408
}
2409
#endif
2410

    
2411
/* SPR micro-ops */
2412
/* 440 specific */
2413
void OPPROTO op_440_dlmzb (void)
2414
{
2415
    do_440_dlmzb();
2416
    RETURN();
2417
}
2418

    
2419
void OPPROTO op_440_dlmzb_update_Rc (void)
2420
{
2421
    if (T0 == 8)
2422
        T0 = 0x2;
2423
    else if (T0 < 4)
2424
        T0 = 0x4;
2425
    else
2426
        T0 = 0x8;
2427
    RETURN();
2428
}
2429

    
2430
#if !defined(CONFIG_USER_ONLY)
2431
void OPPROTO op_store_pir (void)
2432
{
2433
    env->spr[SPR_PIR] = T0 & 0x0000000FUL;
2434
    RETURN();
2435
}
2436

    
2437
void OPPROTO op_load_403_pb (void)
2438
{
2439
    do_load_403_pb(PARAM1);
2440
    RETURN();
2441
}
2442

    
2443
void OPPROTO op_store_403_pb (void)
2444
{
2445
    do_store_403_pb(PARAM1);
2446
    RETURN();
2447
}
2448

    
2449
void OPPROTO op_load_40x_pit (void)
2450
{
2451
    T0 = load_40x_pit(env);
2452
    RETURN();
2453
}
2454

    
2455
void OPPROTO op_store_40x_pit (void)
2456
{
2457
    store_40x_pit(env, T0);
2458
    RETURN();
2459
}
2460

    
2461
void OPPROTO op_store_40x_dbcr0 (void)
2462
{
2463
    store_40x_dbcr0(env, T0);
2464
    RETURN();
2465
}
2466

    
2467
void OPPROTO op_store_40x_sler (void)
2468
{
2469
    store_40x_sler(env, T0);
2470
    RETURN();
2471
}
2472

    
2473
void OPPROTO op_store_booke_tcr (void)
2474
{
2475
    store_booke_tcr(env, T0);
2476
    RETURN();
2477
}
2478

    
2479
void OPPROTO op_store_booke_tsr (void)
2480
{
2481
    store_booke_tsr(env, T0);
2482
    RETURN();
2483
}
2484
#endif /* !defined(CONFIG_USER_ONLY) */
2485

    
2486
/* SPE extension */
2487
void OPPROTO op_splatw_T1_64 (void)
2488
{
2489
    T1_64 = (T1_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL);
2490
    RETURN();
2491
}
2492

    
2493
void OPPROTO op_splatwi_T0_64 (void)
2494
{
2495
    uint64_t tmp = PARAM1;
2496

    
2497
    T0_64 = (tmp << 32) | tmp;
2498
    RETURN();
2499
}
2500

    
2501
void OPPROTO op_splatwi_T1_64 (void)
2502
{
2503
    uint64_t tmp = PARAM1;
2504

    
2505
    T1_64 = (tmp << 32) | tmp;
2506
    RETURN();
2507
}
2508

    
2509
void OPPROTO op_extsh_T1_64 (void)
2510
{
2511
    T1_64 = (int32_t)((int16_t)T1_64);
2512
    RETURN();
2513
}
2514

    
2515
void OPPROTO op_sli16_T1_64 (void)
2516
{
2517
    T1_64 = T1_64 << 16;
2518
    RETURN();
2519
}
2520

    
2521
void OPPROTO op_sli32_T1_64 (void)
2522
{
2523
    T1_64 = T1_64 << 32;
2524
    RETURN();
2525
}
2526

    
2527
void OPPROTO op_srli32_T1_64 (void)
2528
{
2529
    T1_64 = T1_64 >> 32;
2530
    RETURN();
2531
}
2532

    
2533
void OPPROTO op_evsel (void)
2534
{
2535
    do_evsel();
2536
    RETURN();
2537
}
2538

    
2539
void OPPROTO op_evaddw (void)
2540
{
2541
    do_evaddw();
2542
    RETURN();
2543
}
2544

    
2545
void OPPROTO op_evsubfw (void)
2546
{
2547
    do_evsubfw();
2548
    RETURN();
2549
}
2550

    
2551
void OPPROTO op_evneg (void)
2552
{
2553
    do_evneg();
2554
    RETURN();
2555
}
2556

    
2557
void OPPROTO op_evabs (void)
2558
{
2559
    do_evabs();
2560
    RETURN();
2561
}
2562

    
2563
void OPPROTO op_evextsh (void)
2564
{
2565
    T0_64 = ((uint64_t)((int32_t)(int16_t)(T0_64 >> 32)) << 32) |
2566
        (uint64_t)((int32_t)(int16_t)T0_64);
2567
    RETURN();
2568
}
2569

    
2570
void OPPROTO op_evextsb (void)
2571
{
2572
    T0_64 = ((uint64_t)((int32_t)(int8_t)(T0_64 >> 32)) << 32) |
2573
        (uint64_t)((int32_t)(int8_t)T0_64);
2574
    RETURN();
2575
}
2576

    
2577
void OPPROTO op_evcntlzw (void)
2578
{
2579
    do_evcntlzw();
2580
    RETURN();
2581
}
2582

    
2583
void OPPROTO op_evrndw (void)
2584
{
2585
    do_evrndw();
2586
    RETURN();
2587
}
2588

    
2589
void OPPROTO op_brinc (void)
2590
{
2591
    do_brinc();
2592
    RETURN();
2593
}
2594

    
2595
void OPPROTO op_evcntlsw (void)
2596
{
2597
    do_evcntlsw();
2598
    RETURN();
2599
}
2600

    
2601
void OPPROTO op_evand (void)
2602
{
2603
    T0_64 &= T1_64;
2604
    RETURN();
2605
}
2606

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

    
2613
void OPPROTO op_evor (void)
2614
{
2615
    T0_64 |= T1_64;
2616
    RETURN();
2617
}
2618

    
2619
void OPPROTO op_evxor (void)
2620
{
2621
    T0_64 ^= T1_64;
2622
    RETURN();
2623
}
2624

    
2625
void OPPROTO op_eveqv (void)
2626
{
2627
    T0_64 = ~(T0_64 ^ T1_64);
2628
    RETURN();
2629
}
2630

    
2631
void OPPROTO op_evnor (void)
2632
{
2633
    T0_64 = ~(T0_64 | T1_64);
2634
    RETURN();
2635
}
2636

    
2637
void OPPROTO op_evorc (void)
2638
{
2639
    T0_64 |= ~T1_64;
2640
    RETURN();
2641
}
2642

    
2643
void OPPROTO op_evnand (void)
2644
{
2645
    T0_64 = ~(T0_64 & T1_64);
2646
    RETURN();
2647
}
2648

    
2649
void OPPROTO op_evsrws (void)
2650
{
2651
    do_evsrws();
2652
    RETURN();
2653
}
2654

    
2655
void OPPROTO op_evsrwu (void)
2656
{
2657
    do_evsrwu();
2658
    RETURN();
2659
}
2660

    
2661
void OPPROTO op_evslw (void)
2662
{
2663
    do_evslw();
2664
    RETURN();
2665
}
2666

    
2667
void OPPROTO op_evrlw (void)
2668
{
2669
    do_evrlw();
2670
    RETURN();
2671
}
2672

    
2673
void OPPROTO op_evmergelo (void)
2674
{
2675
    T0_64 = (T0_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL);
2676
    RETURN();
2677
}
2678

    
2679
void OPPROTO op_evmergehi (void)
2680
{
2681
    T0_64 = (T0_64 & 0xFFFFFFFF00000000ULL) | (T1_64 >> 32);
2682
    RETURN();
2683
}
2684

    
2685
void OPPROTO op_evmergelohi (void)
2686
{
2687
    T0_64 = (T0_64 << 32) | (T1_64 >> 32);
2688
    RETURN();
2689
}
2690

    
2691
void OPPROTO op_evmergehilo (void)
2692
{
2693
    T0_64 = (T0_64 & 0xFFFFFFFF00000000ULL) | (T1_64 & 0x00000000FFFFFFFFULL);
2694
    RETURN();
2695
}
2696

    
2697
void OPPROTO op_evcmpgts (void)
2698
{
2699
    do_evcmpgts();
2700
    RETURN();
2701
}
2702

    
2703
void OPPROTO op_evcmpgtu (void)
2704
{
2705
    do_evcmpgtu();
2706
    RETURN();
2707
}
2708

    
2709
void OPPROTO op_evcmplts (void)
2710
{
2711
    do_evcmplts();
2712
    RETURN();
2713
}
2714

    
2715
void OPPROTO op_evcmpltu (void)
2716
{
2717
    do_evcmpltu();
2718
    RETURN();
2719
}
2720

    
2721
void OPPROTO op_evcmpeq (void)
2722
{
2723
    do_evcmpeq();
2724
    RETURN();
2725
}
2726

    
2727
void OPPROTO op_evfssub (void)
2728
{
2729
    do_evfssub();
2730
    RETURN();
2731
}
2732

    
2733
void OPPROTO op_evfsadd (void)
2734
{
2735
    do_evfsadd();
2736
    RETURN();
2737
}
2738

    
2739
void OPPROTO op_evfsnabs (void)
2740
{
2741
    do_evfsnabs();
2742
    RETURN();
2743
}
2744

    
2745
void OPPROTO op_evfsabs (void)
2746
{
2747
    do_evfsabs();
2748
    RETURN();
2749
}
2750

    
2751
void OPPROTO op_evfsneg (void)
2752
{
2753
    do_evfsneg();
2754
    RETURN();
2755
}
2756

    
2757
void OPPROTO op_evfsdiv (void)
2758
{
2759
    do_evfsdiv();
2760
    RETURN();
2761
}
2762

    
2763
void OPPROTO op_evfsmul (void)
2764
{
2765
    do_evfsmul();
2766
    RETURN();
2767
}
2768

    
2769
void OPPROTO op_evfscmplt (void)
2770
{
2771
    do_evfscmplt();
2772
    RETURN();
2773
}
2774

    
2775
void OPPROTO op_evfscmpgt (void)
2776
{
2777
    do_evfscmpgt();
2778
    RETURN();
2779
}
2780

    
2781
void OPPROTO op_evfscmpeq (void)
2782
{
2783
    do_evfscmpeq();
2784
    RETURN();
2785
}
2786

    
2787
void OPPROTO op_evfscfsi (void)
2788
{
2789
    do_evfscfsi();
2790
    RETURN();
2791
}
2792

    
2793
void OPPROTO op_evfscfui (void)
2794
{
2795
    do_evfscfui();
2796
    RETURN();
2797
}
2798

    
2799
void OPPROTO op_evfscfsf (void)
2800
{
2801
    do_evfscfsf();
2802
    RETURN();
2803
}
2804

    
2805
void OPPROTO op_evfscfuf (void)
2806
{
2807
    do_evfscfuf();
2808
    RETURN();
2809
}
2810

    
2811
void OPPROTO op_evfsctsi (void)
2812
{
2813
    do_evfsctsi();
2814
    RETURN();
2815
}
2816

    
2817
void OPPROTO op_evfsctui (void)
2818
{
2819
    do_evfsctui();
2820
    RETURN();
2821
}
2822

    
2823
void OPPROTO op_evfsctsf (void)
2824
{
2825
    do_evfsctsf();
2826
    RETURN();
2827
}
2828

    
2829
void OPPROTO op_evfsctuf (void)
2830
{
2831
    do_evfsctuf();
2832
    RETURN();
2833
}
2834

    
2835
void OPPROTO op_evfsctuiz (void)
2836
{
2837
    do_evfsctuiz();
2838
    RETURN();
2839
}
2840

    
2841
void OPPROTO op_evfsctsiz (void)
2842
{
2843
    do_evfsctsiz();
2844
    RETURN();
2845
}
2846

    
2847
void OPPROTO op_evfststlt (void)
2848
{
2849
    do_evfststlt();
2850
    RETURN();
2851
}
2852

    
2853
void OPPROTO op_evfststgt (void)
2854
{
2855
    do_evfststgt();
2856
    RETURN();
2857
}
2858

    
2859
void OPPROTO op_evfststeq (void)
2860
{
2861
    do_evfststeq();
2862
    RETURN();
2863
}
2864

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

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

    
2877
void OPPROTO op_efsnabs (void)
2878
{
2879
    T0_64 = _do_efsnabs(T0_64);
2880
    RETURN();
2881
}
2882

    
2883
void OPPROTO op_efsabs (void)
2884
{
2885
    T0_64 = _do_efsabs(T0_64);
2886
    RETURN();
2887
}
2888

    
2889
void OPPROTO op_efsneg (void)
2890
{
2891
    T0_64 = _do_efsneg(T0_64);
2892
    RETURN();
2893
}
2894

    
2895
void OPPROTO op_efsdiv (void)
2896
{
2897
    T0_64 = _do_efsdiv(T0_64, T1_64);
2898
    RETURN();
2899
}
2900

    
2901
void OPPROTO op_efsmul (void)
2902
{
2903
    T0_64 = _do_efsmul(T0_64, T1_64);
2904
    RETURN();
2905
}
2906

    
2907
void OPPROTO op_efscmplt (void)
2908
{
2909
    do_efscmplt();
2910
    RETURN();
2911
}
2912

    
2913
void OPPROTO op_efscmpgt (void)
2914
{
2915
    do_efscmpgt();
2916
    RETURN();
2917
}
2918

    
2919
void OPPROTO op_efscfd (void)
2920
{
2921
    do_efscfd();
2922
    RETURN();
2923
}
2924

    
2925
void OPPROTO op_efscmpeq (void)
2926
{
2927
    do_efscmpeq();
2928
    RETURN();
2929
}
2930

    
2931
void OPPROTO op_efscfsi (void)
2932
{
2933
    do_efscfsi();
2934
    RETURN();
2935
}
2936

    
2937
void OPPROTO op_efscfui (void)
2938
{
2939
    do_efscfui();
2940
    RETURN();
2941
}
2942

    
2943
void OPPROTO op_efscfsf (void)
2944
{
2945
    do_efscfsf();
2946
    RETURN();
2947
}
2948

    
2949
void OPPROTO op_efscfuf (void)
2950
{
2951
    do_efscfuf();
2952
    RETURN();
2953
}
2954

    
2955
void OPPROTO op_efsctsi (void)
2956
{
2957
    do_efsctsi();
2958
    RETURN();
2959
}
2960

    
2961
void OPPROTO op_efsctui (void)
2962
{
2963
    do_efsctui();
2964
    RETURN();
2965
}
2966

    
2967
void OPPROTO op_efsctsf (void)
2968
{
2969
    do_efsctsf();
2970
    RETURN();
2971
}
2972

    
2973
void OPPROTO op_efsctuf (void)
2974
{
2975
    do_efsctuf();
2976
    RETURN();
2977
}
2978

    
2979
void OPPROTO op_efsctsiz (void)
2980
{
2981
    do_efsctsiz();
2982
    RETURN();
2983
}
2984

    
2985
void OPPROTO op_efsctuiz (void)
2986
{
2987
    do_efsctuiz();
2988
    RETURN();
2989
}
2990

    
2991
void OPPROTO op_efststlt (void)
2992
{
2993
    T0 = _do_efststlt(T0_64, T1_64);
2994
    RETURN();
2995
}
2996

    
2997
void OPPROTO op_efststgt (void)
2998
{
2999
    T0 = _do_efststgt(T0_64, T1_64);
3000
    RETURN();
3001
}
3002

    
3003
void OPPROTO op_efststeq (void)
3004
{
3005
    T0 = _do_efststeq(T0_64, T1_64);
3006
    RETURN();
3007
}
3008

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

    
3019
void OPPROTO op_efdadd (void)
3020
{
3021
    CPU_DoubleU u1, u2;
3022
    u1.ll = T0_64;
3023
    u2.ll = T1_64;
3024
    u1.d = float64_add(u1.d, u2.d, &env->spe_status);
3025
    T0_64 = u1.ll;
3026
    RETURN();
3027
}
3028

    
3029
void OPPROTO op_efdcfsid (void)
3030
{
3031
    do_efdcfsi();
3032
    RETURN();
3033
}
3034

    
3035
void OPPROTO op_efdcfuid (void)
3036
{
3037
    do_efdcfui();
3038
    RETURN();
3039
}
3040

    
3041
void OPPROTO op_efdnabs (void)
3042
{
3043
    T0_64 |= 0x8000000000000000ULL;
3044
    RETURN();
3045
}
3046

    
3047
void OPPROTO op_efdabs (void)
3048
{
3049
    T0_64 &= ~0x8000000000000000ULL;
3050
    RETURN();
3051
}
3052

    
3053
void OPPROTO op_efdneg (void)
3054
{
3055
    T0_64 ^= 0x8000000000000000ULL;
3056
    RETURN();
3057
}
3058

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

    
3069
void OPPROTO op_efdmul (void)
3070
{
3071
    CPU_DoubleU u1, u2;
3072
    u1.ll = T0_64;
3073
    u2.ll = T1_64;
3074
    u1.d = float64_mul(u1.d, u2.d, &env->spe_status);
3075
    T0_64 = u1.ll;
3076
    RETURN();
3077
}
3078

    
3079
void OPPROTO op_efdctsidz (void)
3080
{
3081
    do_efdctsiz();
3082
    RETURN();
3083
}
3084

    
3085
void OPPROTO op_efdctuidz (void)
3086
{
3087
    do_efdctuiz();
3088
    RETURN();
3089
}
3090

    
3091
void OPPROTO op_efdcmplt (void)
3092
{
3093
    do_efdcmplt();
3094
    RETURN();
3095
}
3096

    
3097
void OPPROTO op_efdcmpgt (void)
3098
{
3099
    do_efdcmpgt();
3100
    RETURN();
3101
}
3102

    
3103
void OPPROTO op_efdcfs (void)
3104
{
3105
    do_efdcfs();
3106
    RETURN();
3107
}
3108

    
3109
void OPPROTO op_efdcmpeq (void)
3110
{
3111
    do_efdcmpeq();
3112
    RETURN();
3113
}
3114

    
3115
void OPPROTO op_efdcfsi (void)
3116
{
3117
    do_efdcfsi();
3118
    RETURN();
3119
}
3120

    
3121
void OPPROTO op_efdcfui (void)
3122
{
3123
    do_efdcfui();
3124
    RETURN();
3125
}
3126

    
3127
void OPPROTO op_efdcfsf (void)
3128
{
3129
    do_efdcfsf();
3130
    RETURN();
3131
}
3132

    
3133
void OPPROTO op_efdcfuf (void)
3134
{
3135
    do_efdcfuf();
3136
    RETURN();
3137
}
3138

    
3139
void OPPROTO op_efdctsi (void)
3140
{
3141
    do_efdctsi();
3142
    RETURN();
3143
}
3144

    
3145
void OPPROTO op_efdctui (void)
3146
{
3147
    do_efdctui();
3148
    RETURN();
3149
}
3150

    
3151
void OPPROTO op_efdctsf (void)
3152
{
3153
    do_efdctsf();
3154
    RETURN();
3155
}
3156

    
3157
void OPPROTO op_efdctuf (void)
3158
{
3159
    do_efdctuf();
3160
    RETURN();
3161
}
3162

    
3163
void OPPROTO op_efdctuiz (void)
3164
{
3165
    do_efdctuiz();
3166
    RETURN();
3167
}
3168

    
3169
void OPPROTO op_efdctsiz (void)
3170
{
3171
    do_efdctsiz();
3172
    RETURN();
3173
}
3174

    
3175
void OPPROTO op_efdtstlt (void)
3176
{
3177
    T0 = _do_efdtstlt(T0_64, T1_64);
3178
    RETURN();
3179
}
3180

    
3181
void OPPROTO op_efdtstgt (void)
3182
{
3183
    T0 = _do_efdtstgt(T0_64, T1_64);
3184
    RETURN();
3185
}
3186

    
3187
void OPPROTO op_efdtsteq (void)
3188
{
3189
    T0 = _do_efdtsteq(T0_64, T1_64);
3190
    RETURN();
3191
}