Statistics
| Branch: | Revision:

root / target-ppc / op.c @ 86c581dc

History | View | Annotate | Download (49.2 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
#define REG 0
30
#include "op_template.h"
31

    
32
#define REG 1
33
#include "op_template.h"
34

    
35
#define REG 2
36
#include "op_template.h"
37

    
38
#define REG 3
39
#include "op_template.h"
40

    
41
#define REG 4
42
#include "op_template.h"
43

    
44
#define REG 5
45
#include "op_template.h"
46

    
47
#define REG 6
48
#include "op_template.h"
49

    
50
#define REG 7
51
#include "op_template.h"
52

    
53
#define REG 8
54
#include "op_template.h"
55

    
56
#define REG 9
57
#include "op_template.h"
58

    
59
#define REG 10
60
#include "op_template.h"
61

    
62
#define REG 11
63
#include "op_template.h"
64

    
65
#define REG 12
66
#include "op_template.h"
67

    
68
#define REG 13
69
#include "op_template.h"
70

    
71
#define REG 14
72
#include "op_template.h"
73

    
74
#define REG 15
75
#include "op_template.h"
76

    
77
#define REG 16
78
#include "op_template.h"
79

    
80
#define REG 17
81
#include "op_template.h"
82

    
83
#define REG 18
84
#include "op_template.h"
85

    
86
#define REG 19
87
#include "op_template.h"
88

    
89
#define REG 20
90
#include "op_template.h"
91

    
92
#define REG 21
93
#include "op_template.h"
94

    
95
#define REG 22
96
#include "op_template.h"
97

    
98
#define REG 23
99
#include "op_template.h"
100

    
101
#define REG 24
102
#include "op_template.h"
103

    
104
#define REG 25
105
#include "op_template.h"
106

    
107
#define REG 26
108
#include "op_template.h"
109

    
110
#define REG 27
111
#include "op_template.h"
112

    
113
#define REG 28
114
#include "op_template.h"
115

    
116
#define REG 29
117
#include "op_template.h"
118

    
119
#define REG 30
120
#include "op_template.h"
121

    
122
#define REG 31
123
#include "op_template.h"
124

    
125
void OPPROTO op_print_mem_EA (void)
126
{
127
    do_print_mem_EA(T0);
128
    RETURN();
129
}
130

    
131
/* PowerPC state maintenance operations */
132
/* set_Rc0 */
133
void OPPROTO op_set_Rc0 (void)
134
{
135
    env->crf[0] = T0 | xer_so;
136
    RETURN();
137
}
138

    
139
/* Constants load */
140
void OPPROTO op_moven_T2_T0 (void)
141
{
142
    T2 = ~T0;
143
    RETURN();
144
}
145

    
146
/* Generate exceptions */
147
void OPPROTO op_raise_exception_err (void)
148
{
149
    do_raise_exception_err(PARAM1, PARAM2);
150
}
151

    
152
void OPPROTO op_update_nip (void)
153
{
154
    env->nip = (uint32_t)PARAM1;
155
    RETURN();
156
}
157

    
158
#if defined(TARGET_PPC64)
159
void OPPROTO op_update_nip_64 (void)
160
{
161
    env->nip = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
162
    RETURN();
163
}
164
#endif
165

    
166
void OPPROTO op_debug (void)
167
{
168
    do_raise_exception(EXCP_DEBUG);
169
}
170

    
171
/* Load/store special registers */
172
void OPPROTO op_load_cr (void)
173
{
174
    do_load_cr();
175
    RETURN();
176
}
177

    
178
void OPPROTO op_store_cr (void)
179
{
180
    do_store_cr(PARAM1);
181
    RETURN();
182
}
183

    
184
void OPPROTO op_load_cro (void)
185
{
186
    T0 = env->crf[PARAM1];
187
    RETURN();
188
}
189

    
190
void OPPROTO op_store_cro (void)
191
{
192
    env->crf[PARAM1] = T0;
193
    RETURN();
194
}
195

    
196
void OPPROTO op_load_xer_cr (void)
197
{
198
    T0 = (xer_so << 3) | (xer_ov << 2) | (xer_ca << 1);
199
    RETURN();
200
}
201

    
202
void OPPROTO op_clear_xer_ov (void)
203
{
204
    xer_so = 0;
205
    xer_ov = 0;
206
    RETURN();
207
}
208

    
209
void OPPROTO op_clear_xer_ca (void)
210
{
211
    xer_ca = 0;
212
    RETURN();
213
}
214

    
215
void OPPROTO op_load_xer_bc (void)
216
{
217
    T1 = xer_bc;
218
    RETURN();
219
}
220

    
221
void OPPROTO op_store_xer_bc (void)
222
{
223
    xer_bc = T0;
224
    RETURN();
225
}
226

    
227
void OPPROTO op_load_xer (void)
228
{
229
    T0 = hreg_load_xer(env);
230
    RETURN();
231
}
232

    
233
void OPPROTO op_store_xer (void)
234
{
235
    hreg_store_xer(env, T0);
236
    RETURN();
237
}
238

    
239
#if defined(TARGET_PPC64)
240
void OPPROTO op_store_pri (void)
241
{
242
    do_store_pri(PARAM1);
243
    RETURN();
244
}
245
#endif
246

    
247
#if !defined(CONFIG_USER_ONLY)
248
/* Segment registers load and store */
249
void OPPROTO op_load_sr (void)
250
{
251
    T0 = env->sr[T1];
252
    RETURN();
253
}
254

    
255
void OPPROTO op_store_sr (void)
256
{
257
    do_store_sr(env, T1, T0);
258
    RETURN();
259
}
260

    
261
#if defined(TARGET_PPC64)
262
void OPPROTO op_load_slb (void)
263
{
264
    T0 = ppc_load_slb(env, T1);
265
    RETURN();
266
}
267

    
268
void OPPROTO op_store_slb (void)
269
{
270
    ppc_store_slb(env, T1, T0);
271
    RETURN();
272
}
273
#endif /* defined(TARGET_PPC64) */
274

    
275
void OPPROTO op_load_sdr1 (void)
276
{
277
    T0 = env->sdr1;
278
    RETURN();
279
}
280

    
281
void OPPROTO op_store_sdr1 (void)
282
{
283
    do_store_sdr1(env, T0);
284
    RETURN();
285
}
286

    
287
#if defined (TARGET_PPC64)
288
void OPPROTO op_load_asr (void)
289
{
290
    T0 = env->asr;
291
    RETURN();
292
}
293

    
294
void OPPROTO op_store_asr (void)
295
{
296
    ppc_store_asr(env, T0);
297
    RETURN();
298
}
299
#endif
300

    
301
void OPPROTO op_load_msr (void)
302
{
303
    T0 = env->msr;
304
    RETURN();
305
}
306

    
307
void OPPROTO op_store_msr (void)
308
{
309
    do_store_msr();
310
    RETURN();
311
}
312

    
313
#if defined (TARGET_PPC64)
314
void OPPROTO op_store_msr_32 (void)
315
{
316
    T0 = (env->msr & ~0xFFFFFFFFULL) | (T0 & 0xFFFFFFFF);
317
    do_store_msr();
318
    RETURN();
319
}
320
#endif
321

    
322
void OPPROTO op_update_riee (void)
323
{
324
    /* We don't call do_store_msr here as we won't trigger
325
     * any special case nor change hflags
326
     */
327
    T0 &= (1 << MSR_RI) | (1 << MSR_EE);
328
    env->msr &= ~(1 << MSR_RI) | (1 << MSR_EE);
329
    env->msr |= T0;
330
    RETURN();
331
}
332
#endif
333

    
334
/* SPR */
335
void OPPROTO op_load_spr (void)
336
{
337
    T0 = env->spr[PARAM1];
338
    RETURN();
339
}
340

    
341
void OPPROTO op_store_spr (void)
342
{
343
    env->spr[PARAM1] = T0;
344
    RETURN();
345
}
346

    
347
void OPPROTO op_load_dump_spr (void)
348
{
349
    T0 = ppc_load_dump_spr(PARAM1);
350
    RETURN();
351
}
352

    
353
void OPPROTO op_store_dump_spr (void)
354
{
355
    ppc_store_dump_spr(PARAM1, T0);
356
    RETURN();
357
}
358

    
359
void OPPROTO op_mask_spr (void)
360
{
361
    env->spr[PARAM1] &= ~T0;
362
    RETURN();
363
}
364

    
365
void OPPROTO op_load_lr (void)
366
{
367
    T0 = env->lr;
368
    RETURN();
369
}
370

    
371
void OPPROTO op_store_lr (void)
372
{
373
    env->lr = T0;
374
    RETURN();
375
}
376

    
377
void OPPROTO op_load_ctr (void)
378
{
379
    T0 = env->ctr;
380
    RETURN();
381
}
382

    
383
void OPPROTO op_store_ctr (void)
384
{
385
    env->ctr = T0;
386
    RETURN();
387
}
388

    
389
void OPPROTO op_load_tbl (void)
390
{
391
    T0 = cpu_ppc_load_tbl(env);
392
    RETURN();
393
}
394

    
395
void OPPROTO op_load_tbu (void)
396
{
397
    T0 = cpu_ppc_load_tbu(env);
398
    RETURN();
399
}
400

    
401
void OPPROTO op_load_atbl (void)
402
{
403
    T0 = cpu_ppc_load_atbl(env);
404
    RETURN();
405
}
406

    
407
void OPPROTO op_load_atbu (void)
408
{
409
    T0 = cpu_ppc_load_atbu(env);
410
    RETURN();
411
}
412

    
413
#if !defined(CONFIG_USER_ONLY)
414
void OPPROTO op_store_tbl (void)
415
{
416
    cpu_ppc_store_tbl(env, T0);
417
    RETURN();
418
}
419

    
420
void OPPROTO op_store_tbu (void)
421
{
422
    cpu_ppc_store_tbu(env, T0);
423
    RETURN();
424
}
425

    
426
void OPPROTO op_store_atbl (void)
427
{
428
    cpu_ppc_store_atbl(env, T0);
429
    RETURN();
430
}
431

    
432
void OPPROTO op_store_atbu (void)
433
{
434
    cpu_ppc_store_atbu(env, T0);
435
    RETURN();
436
}
437

    
438
void OPPROTO op_load_decr (void)
439
{
440
    T0 = cpu_ppc_load_decr(env);
441
    RETURN();
442
}
443

    
444
void OPPROTO op_store_decr (void)
445
{
446
    cpu_ppc_store_decr(env, T0);
447
    RETURN();
448
}
449

    
450
void OPPROTO op_load_ibat (void)
451
{
452
    T0 = env->IBAT[PARAM1][PARAM2];
453
    RETURN();
454
}
455

    
456
void OPPROTO op_store_ibatu (void)
457
{
458
    do_store_ibatu(env, PARAM1, T0);
459
    RETURN();
460
}
461

    
462
void OPPROTO op_store_ibatl (void)
463
{
464
#if 1
465
    env->IBAT[1][PARAM1] = T0;
466
#else
467
    do_store_ibatl(env, PARAM1, T0);
468
#endif
469
    RETURN();
470
}
471

    
472
void OPPROTO op_load_dbat (void)
473
{
474
    T0 = env->DBAT[PARAM1][PARAM2];
475
    RETURN();
476
}
477

    
478
void OPPROTO op_store_dbatu (void)
479
{
480
    do_store_dbatu(env, PARAM1, T0);
481
    RETURN();
482
}
483

    
484
void OPPROTO op_store_dbatl (void)
485
{
486
#if 1
487
    env->DBAT[1][PARAM1] = T0;
488
#else
489
    do_store_dbatl(env, PARAM1, T0);
490
#endif
491
    RETURN();
492
}
493
#endif /* !defined(CONFIG_USER_ONLY) */
494

    
495
/* FPSCR */
496
#ifdef CONFIG_SOFTFLOAT
497
void OPPROTO op_reset_fpstatus (void)
498
{
499
    env->fp_status.float_exception_flags = 0;
500
    RETURN();
501
}
502
#endif
503

    
504
void OPPROTO op_compute_fprf (void)
505
{
506
    do_compute_fprf(PARAM1);
507
    RETURN();
508
}
509

    
510
#ifdef CONFIG_SOFTFLOAT
511
void OPPROTO op_float_check_status (void)
512
{
513
    do_float_check_status();
514
    RETURN();
515
}
516
#else
517
void OPPROTO op_float_check_status (void)
518
{
519
    if (env->exception_index == POWERPC_EXCP_PROGRAM &&
520
        (env->error_code & POWERPC_EXCP_FP)) {
521
        /* Differred floating-point exception after target FPR update */
522
        if (msr_fe0 != 0 || msr_fe1 != 0)
523
            do_raise_exception_err(env->exception_index, env->error_code);
524
    }
525
    RETURN();
526
}
527
#endif
528

    
529
void OPPROTO op_load_fpscr_FT0 (void)
530
{
531
    /* The 32 MSB of the target fpr are undefined.
532
     * They'll be zero...
533
     */
534
    CPU_DoubleU u;
535

    
536
    u.l.upper = 0;
537
    u.l.lower = env->fpscr;
538
    FT0 = u.d;
539
    RETURN();
540
}
541

    
542
void OPPROTO op_set_FT0 (void)
543
{
544
    CPU_DoubleU u;
545

    
546
    u.l.upper = 0;
547
    u.l.lower = PARAM1;
548
    FT0 = u.d;
549
    RETURN();
550
}
551

    
552
void OPPROTO op_load_fpscr_T0 (void)
553
{
554
    T0 = (env->fpscr >> PARAM1) & 0xF;
555
    RETURN();
556
}
557

    
558
void OPPROTO op_load_fpcc (void)
559
{
560
    T0 = fpscr_fpcc;
561
    RETURN();
562
}
563

    
564
void OPPROTO op_fpscr_resetbit (void)
565
{
566
    env->fpscr &= PARAM1;
567
    RETURN();
568
}
569

    
570
void OPPROTO op_fpscr_setbit (void)
571
{
572
    do_fpscr_setbit(PARAM1);
573
    RETURN();
574
}
575

    
576
void OPPROTO op_store_fpscr (void)
577
{
578
    do_store_fpscr(PARAM1);
579
    RETURN();
580
}
581

    
582
/* Branch */
583
#define EIP env->nip
584

    
585
void OPPROTO op_setlr (void)
586
{
587
    env->lr = (uint32_t)PARAM1;
588
    RETURN();
589
}
590

    
591
#if defined (TARGET_PPC64)
592
void OPPROTO op_setlr_64 (void)
593
{
594
    env->lr = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
595
    RETURN();
596
}
597
#endif
598

    
599
void OPPROTO op_b_T1 (void)
600
{
601
    env->nip = (uint32_t)(T1 & ~3);
602
    RETURN();
603
}
604

    
605
#if defined (TARGET_PPC64)
606
void OPPROTO op_b_T1_64 (void)
607
{
608
    env->nip = (uint64_t)(T1 & ~3);
609
    RETURN();
610
}
611
#endif
612

    
613
void OPPROTO op_jz_T0 (void)
614
{
615
    if (!T0)
616
        GOTO_LABEL_PARAM(1);
617
    RETURN();
618
}
619

    
620
void OPPROTO op_btest_T1 (void)
621
{
622
    if (T0) {
623
        env->nip = (uint32_t)(T1 & ~3);
624
    } else {
625
        env->nip = (uint32_t)PARAM1;
626
    }
627
    RETURN();
628
}
629

    
630
#if defined (TARGET_PPC64)
631
void OPPROTO op_btest_T1_64 (void)
632
{
633
    if (T0) {
634
        env->nip = (uint64_t)(T1 & ~3);
635
    } else {
636
        env->nip = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
637
    }
638
    RETURN();
639
}
640
#endif
641

    
642
void OPPROTO op_movl_T1_ctr (void)
643
{
644
    T1 = env->ctr;
645
    RETURN();
646
}
647

    
648
void OPPROTO op_movl_T1_lr (void)
649
{
650
    T1 = env->lr;
651
    RETURN();
652
}
653

    
654
/* tests with result in T0 */
655
void OPPROTO op_test_ctr (void)
656
{
657
    T0 = (uint32_t)env->ctr;
658
    RETURN();
659
}
660

    
661
#if defined(TARGET_PPC64)
662
void OPPROTO op_test_ctr_64 (void)
663
{
664
    T0 = (uint64_t)env->ctr;
665
    RETURN();
666
}
667
#endif
668

    
669
void OPPROTO op_test_ctr_true (void)
670
{
671
    T0 = ((uint32_t)env->ctr != 0 && (T0 & PARAM1) != 0);
672
    RETURN();
673
}
674

    
675
#if defined(TARGET_PPC64)
676
void OPPROTO op_test_ctr_true_64 (void)
677
{
678
    T0 = ((uint64_t)env->ctr != 0 && (T0 & PARAM1) != 0);
679
    RETURN();
680
}
681
#endif
682

    
683
void OPPROTO op_test_ctr_false (void)
684
{
685
    T0 = ((uint32_t)env->ctr != 0 && (T0 & PARAM1) == 0);
686
    RETURN();
687
}
688

    
689
#if defined(TARGET_PPC64)
690
void OPPROTO op_test_ctr_false_64 (void)
691
{
692
    T0 = ((uint64_t)env->ctr != 0 && (T0 & PARAM1) == 0);
693
    RETURN();
694
}
695
#endif
696

    
697
void OPPROTO op_test_ctrz (void)
698
{
699
    T0 = ((uint32_t)env->ctr == 0);
700
    RETURN();
701
}
702

    
703
#if defined(TARGET_PPC64)
704
void OPPROTO op_test_ctrz_64 (void)
705
{
706
    T0 = ((uint64_t)env->ctr == 0);
707
    RETURN();
708
}
709
#endif
710

    
711
void OPPROTO op_test_ctrz_true (void)
712
{
713
    T0 = ((uint32_t)env->ctr == 0 && (T0 & PARAM1) != 0);
714
    RETURN();
715
}
716

    
717
#if defined(TARGET_PPC64)
718
void OPPROTO op_test_ctrz_true_64 (void)
719
{
720
    T0 = ((uint64_t)env->ctr == 0 && (T0 & PARAM1) != 0);
721
    RETURN();
722
}
723
#endif
724

    
725
void OPPROTO op_test_ctrz_false (void)
726
{
727
    T0 = ((uint32_t)env->ctr == 0 && (T0 & PARAM1) == 0);
728
    RETURN();
729
}
730

    
731
#if defined(TARGET_PPC64)
732
void OPPROTO op_test_ctrz_false_64 (void)
733
{
734
    T0 = ((uint64_t)env->ctr == 0 && (T0 & PARAM1) == 0);
735
    RETURN();
736
}
737
#endif
738

    
739
void OPPROTO op_test_true (void)
740
{
741
    T0 = (T0 & PARAM1);
742
    RETURN();
743
}
744

    
745
void OPPROTO op_test_false (void)
746
{
747
    T0 = ((T0 & PARAM1) == 0);
748
    RETURN();
749
}
750

    
751
/* CTR maintenance */
752
void OPPROTO op_dec_ctr (void)
753
{
754
    env->ctr--;
755
    RETURN();
756
}
757

    
758
/***                           Integer arithmetic                          ***/
759
/* add */
760
void OPPROTO op_add (void)
761
{
762
    T0 += T1;
763
    RETURN();
764
}
765

    
766
void OPPROTO op_check_addo (void)
767
{
768
    xer_ov = (((uint32_t)T2 ^ (uint32_t)T1 ^ UINT32_MAX) &
769
              ((uint32_t)T2 ^ (uint32_t)T0)) >> 31;
770
    xer_so |= xer_ov;
771
    RETURN();
772
}
773

    
774
#if defined(TARGET_PPC64)
775
void OPPROTO op_check_addo_64 (void)
776
{
777
    xer_ov = (((uint64_t)T2 ^ (uint64_t)T1 ^ UINT64_MAX) &
778
              ((uint64_t)T2 ^ (uint64_t)T0)) >> 63;
779
    xer_so |= xer_ov;
780
    RETURN();
781
}
782
#endif
783

    
784
/* add carrying */
785
void OPPROTO op_check_addc (void)
786
{
787
    if (likely((uint32_t)T0 >= (uint32_t)T2)) {
788
        xer_ca = 0;
789
    } else {
790
        xer_ca = 1;
791
    }
792
    RETURN();
793
}
794

    
795
#if defined(TARGET_PPC64)
796
void OPPROTO op_check_addc_64 (void)
797
{
798
    if (likely((uint64_t)T0 >= (uint64_t)T2)) {
799
        xer_ca = 0;
800
    } else {
801
        xer_ca = 1;
802
    }
803
    RETURN();
804
}
805
#endif
806

    
807
/* add extended */
808
void OPPROTO op_adde (void)
809
{
810
    do_adde();
811
    RETURN();
812
}
813

    
814
#if defined(TARGET_PPC64)
815
void OPPROTO op_adde_64 (void)
816
{
817
    do_adde_64();
818
    RETURN();
819
}
820
#endif
821

    
822
/* add immediate */
823
void OPPROTO op_addi (void)
824
{
825
    T0 += (int32_t)PARAM1;
826
    RETURN();
827
}
828

    
829
/* add to minus one extended */
830
void OPPROTO op_add_me (void)
831
{
832
    T0 += xer_ca + (-1);
833
    if (likely((uint32_t)T1 != 0))
834
        xer_ca = 1;
835
    else
836
        xer_ca = 0;
837
    RETURN();
838
}
839

    
840
#if defined(TARGET_PPC64)
841
void OPPROTO op_add_me_64 (void)
842
{
843
    T0 += xer_ca + (-1);
844
    if (likely((uint64_t)T1 != 0))
845
        xer_ca = 1;
846
    else
847
        xer_ca = 0;
848
    RETURN();
849
}
850
#endif
851

    
852
void OPPROTO op_addmeo (void)
853
{
854
    do_addmeo();
855
    RETURN();
856
}
857

    
858
void OPPROTO op_addmeo_64 (void)
859
{
860
    do_addmeo();
861
    RETURN();
862
}
863

    
864
/* add to zero extended */
865
void OPPROTO op_add_ze (void)
866
{
867
    T0 += xer_ca;
868
    RETURN();
869
}
870

    
871
/* divide word */
872
void OPPROTO op_divw (void)
873
{
874
    if (unlikely(((int32_t)T0 == INT32_MIN && (int32_t)T1 == (int32_t)-1) ||
875
                 (int32_t)T1 == 0)) {
876
        T0 = (int32_t)(UINT32_MAX * ((uint32_t)T0 >> 31));
877
    } else {
878
        T0 = (int32_t)T0 / (int32_t)T1;
879
    }
880
    RETURN();
881
}
882

    
883
#if defined(TARGET_PPC64)
884
void OPPROTO op_divd (void)
885
{
886
    if (unlikely(((int64_t)T0 == INT64_MIN && (int64_t)T1 == (int64_t)-1LL) ||
887
                 (int64_t)T1 == 0)) {
888
        T0 = (int64_t)(UINT64_MAX * ((uint64_t)T0 >> 63));
889
    } else {
890
        T0 = (int64_t)T0 / (int64_t)T1;
891
    }
892
    RETURN();
893
}
894
#endif
895

    
896
void OPPROTO op_divwo (void)
897
{
898
    do_divwo();
899
    RETURN();
900
}
901

    
902
#if defined(TARGET_PPC64)
903
void OPPROTO op_divdo (void)
904
{
905
    do_divdo();
906
    RETURN();
907
}
908
#endif
909

    
910
/* divide word unsigned */
911
void OPPROTO op_divwu (void)
912
{
913
    if (unlikely(T1 == 0)) {
914
        T0 = 0;
915
    } else {
916
        T0 = (uint32_t)T0 / (uint32_t)T1;
917
    }
918
    RETURN();
919
}
920

    
921
#if defined(TARGET_PPC64)
922
void OPPROTO op_divdu (void)
923
{
924
    if (unlikely(T1 == 0)) {
925
        T0 = 0;
926
    } else {
927
        T0 /= T1;
928
    }
929
    RETURN();
930
}
931
#endif
932

    
933
void OPPROTO op_divwuo (void)
934
{
935
    do_divwuo();
936
    RETURN();
937
}
938

    
939
#if defined(TARGET_PPC64)
940
void OPPROTO op_divduo (void)
941
{
942
    do_divduo();
943
    RETURN();
944
}
945
#endif
946

    
947
/* multiply high word */
948
void OPPROTO op_mulhw (void)
949
{
950
    T0 = ((int64_t)((int32_t)T0) * (int64_t)((int32_t)T1)) >> 32;
951
    RETURN();
952
}
953

    
954
#if defined(TARGET_PPC64)
955
void OPPROTO op_mulhd (void)
956
{
957
    uint64_t tl, th;
958

    
959
    muls64(&tl, &th, T0, T1);
960
    T0 = th;
961
    RETURN();
962
}
963
#endif
964

    
965
/* multiply high word unsigned */
966
void OPPROTO op_mulhwu (void)
967
{
968
    T0 = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1) >> 32;
969
    RETURN();
970
}
971

    
972
#if defined(TARGET_PPC64)
973
void OPPROTO op_mulhdu (void)
974
{
975
    uint64_t tl, th;
976

    
977
    mulu64(&tl, &th, T0, T1);
978
    T0 = th;
979
    RETURN();
980
}
981
#endif
982

    
983
/* multiply low immediate */
984
void OPPROTO op_mulli (void)
985
{
986
    T0 = ((int32_t)T0 * (int32_t)PARAM1);
987
    RETURN();
988
}
989

    
990
/* multiply low word */
991
void OPPROTO op_mullw (void)
992
{
993
    T0 = (int32_t)(T0 * T1);
994
    RETURN();
995
}
996

    
997
#if defined(TARGET_PPC64)
998
void OPPROTO op_mulld (void)
999
{
1000
    T0 *= T1;
1001
    RETURN();
1002
}
1003
#endif
1004

    
1005
void OPPROTO op_mullwo (void)
1006
{
1007
    do_mullwo();
1008
    RETURN();
1009
}
1010

    
1011
#if defined(TARGET_PPC64)
1012
void OPPROTO op_mulldo (void)
1013
{
1014
    do_mulldo();
1015
    RETURN();
1016
}
1017
#endif
1018

    
1019
/* negate */
1020
void OPPROTO op_neg (void)
1021
{
1022
    if (likely(T0 != INT32_MIN)) {
1023
        T0 = -(int32_t)T0;
1024
    }
1025
    RETURN();
1026
}
1027

    
1028
#if defined(TARGET_PPC64)
1029
void OPPROTO op_neg_64 (void)
1030
{
1031
    if (likely(T0 != INT64_MIN)) {
1032
        T0 = -(int64_t)T0;
1033
    }
1034
    RETURN();
1035
}
1036
#endif
1037

    
1038
void OPPROTO op_nego (void)
1039
{
1040
    do_nego();
1041
    RETURN();
1042
}
1043

    
1044
#if defined(TARGET_PPC64)
1045
void OPPROTO op_nego_64 (void)
1046
{
1047
    do_nego_64();
1048
    RETURN();
1049
}
1050
#endif
1051

    
1052
/* subtract from */
1053
void OPPROTO op_subf (void)
1054
{
1055
    T0 = T1 - T0;
1056
    RETURN();
1057
}
1058

    
1059
/* subtract from carrying */
1060
void OPPROTO op_check_subfc (void)
1061
{
1062
    if (likely((uint32_t)T0 > (uint32_t)T1)) {
1063
        xer_ca = 0;
1064
    } else {
1065
        xer_ca = 1;
1066
    }
1067
    RETURN();
1068
}
1069

    
1070
#if defined(TARGET_PPC64)
1071
void OPPROTO op_check_subfc_64 (void)
1072
{
1073
    if (likely((uint64_t)T0 > (uint64_t)T1)) {
1074
        xer_ca = 0;
1075
    } else {
1076
        xer_ca = 1;
1077
    }
1078
    RETURN();
1079
}
1080
#endif
1081

    
1082
/* subtract from extended */
1083
void OPPROTO op_subfe (void)
1084
{
1085
    do_subfe();
1086
    RETURN();
1087
}
1088

    
1089
#if defined(TARGET_PPC64)
1090
void OPPROTO op_subfe_64 (void)
1091
{
1092
    do_subfe_64();
1093
    RETURN();
1094
}
1095
#endif
1096

    
1097
/* subtract from immediate carrying */
1098
void OPPROTO op_subfic (void)
1099
{
1100
    T0 = (int32_t)PARAM1 + ~T0 + 1;
1101
    if ((uint32_t)T0 <= (uint32_t)PARAM1) {
1102
        xer_ca = 1;
1103
    } else {
1104
        xer_ca = 0;
1105
    }
1106
    RETURN();
1107
}
1108

    
1109
#if defined(TARGET_PPC64)
1110
void OPPROTO op_subfic_64 (void)
1111
{
1112
    T0 = (int64_t)PARAM1 + ~T0 + 1;
1113
    if ((uint64_t)T0 <= (uint64_t)PARAM1) {
1114
        xer_ca = 1;
1115
    } else {
1116
        xer_ca = 0;
1117
    }
1118
    RETURN();
1119
}
1120
#endif
1121

    
1122
/* subtract from minus one extended */
1123
void OPPROTO op_subfme (void)
1124
{
1125
    T0 = ~T0 + xer_ca - 1;
1126
    if (likely((uint32_t)T0 != UINT32_MAX))
1127
        xer_ca = 1;
1128
    else
1129
        xer_ca = 0;
1130
    RETURN();
1131
}
1132

    
1133
#if defined(TARGET_PPC64)
1134
void OPPROTO op_subfme_64 (void)
1135
{
1136
    T0 = ~T0 + xer_ca - 1;
1137
    if (likely((uint64_t)T0 != UINT64_MAX))
1138
        xer_ca = 1;
1139
    else
1140
        xer_ca = 0;
1141
    RETURN();
1142
}
1143
#endif
1144

    
1145
void OPPROTO op_subfmeo (void)
1146
{
1147
    do_subfmeo();
1148
    RETURN();
1149
}
1150

    
1151
#if defined(TARGET_PPC64)
1152
void OPPROTO op_subfmeo_64 (void)
1153
{
1154
    do_subfmeo_64();
1155
    RETURN();
1156
}
1157
#endif
1158

    
1159
/* subtract from zero extended */
1160
void OPPROTO op_subfze (void)
1161
{
1162
    T1 = ~T0;
1163
    T0 = T1 + xer_ca;
1164
    if ((uint32_t)T0 < (uint32_t)T1) {
1165
        xer_ca = 1;
1166
    } else {
1167
        xer_ca = 0;
1168
    }
1169
    RETURN();
1170
}
1171

    
1172
#if defined(TARGET_PPC64)
1173
void OPPROTO op_subfze_64 (void)
1174
{
1175
    T1 = ~T0;
1176
    T0 = T1 + xer_ca;
1177
    if ((uint64_t)T0 < (uint64_t)T1) {
1178
        xer_ca = 1;
1179
    } else {
1180
        xer_ca = 0;
1181
    }
1182
    RETURN();
1183
}
1184
#endif
1185

    
1186
void OPPROTO op_subfzeo (void)
1187
{
1188
    do_subfzeo();
1189
    RETURN();
1190
}
1191

    
1192
#if defined(TARGET_PPC64)
1193
void OPPROTO op_subfzeo_64 (void)
1194
{
1195
    do_subfzeo_64();
1196
    RETURN();
1197
}
1198
#endif
1199

    
1200
/***                           Integer comparison                          ***/
1201
/* compare */
1202
void OPPROTO op_cmp (void)
1203
{
1204
    if ((int32_t)T0 < (int32_t)T1) {
1205
        T0 = 0x08;
1206
    } else if ((int32_t)T0 > (int32_t)T1) {
1207
        T0 = 0x04;
1208
    } else {
1209
        T0 = 0x02;
1210
    }
1211
    T0 |= xer_so;
1212
    RETURN();
1213
}
1214

    
1215
#if defined(TARGET_PPC64)
1216
void OPPROTO op_cmp_64 (void)
1217
{
1218
    if ((int64_t)T0 < (int64_t)T1) {
1219
        T0 = 0x08;
1220
    } else if ((int64_t)T0 > (int64_t)T1) {
1221
        T0 = 0x04;
1222
    } else {
1223
        T0 = 0x02;
1224
    }
1225
    T0 |= xer_so;
1226
    RETURN();
1227
}
1228
#endif
1229

    
1230
/* compare immediate */
1231
void OPPROTO op_cmpi (void)
1232
{
1233
    if ((int32_t)T0 < (int32_t)PARAM1) {
1234
        T0 = 0x08;
1235
    } else if ((int32_t)T0 > (int32_t)PARAM1) {
1236
        T0 = 0x04;
1237
    } else {
1238
        T0 = 0x02;
1239
    }
1240
    T0 |= xer_so;
1241
    RETURN();
1242
}
1243

    
1244
#if defined(TARGET_PPC64)
1245
void OPPROTO op_cmpi_64 (void)
1246
{
1247
    if ((int64_t)T0 < (int64_t)((int32_t)PARAM1)) {
1248
        T0 = 0x08;
1249
    } else if ((int64_t)T0 > (int64_t)((int32_t)PARAM1)) {
1250
        T0 = 0x04;
1251
    } else {
1252
        T0 = 0x02;
1253
    }
1254
    T0 |= xer_so;
1255
    RETURN();
1256
}
1257
#endif
1258

    
1259
/* compare logical */
1260
void OPPROTO op_cmpl (void)
1261
{
1262
    if ((uint32_t)T0 < (uint32_t)T1) {
1263
        T0 = 0x08;
1264
    } else if ((uint32_t)T0 > (uint32_t)T1) {
1265
        T0 = 0x04;
1266
    } else {
1267
        T0 = 0x02;
1268
    }
1269
    T0 |= xer_so;
1270
    RETURN();
1271
}
1272

    
1273
#if defined(TARGET_PPC64)
1274
void OPPROTO op_cmpl_64 (void)
1275
{
1276
    if ((uint64_t)T0 < (uint64_t)T1) {
1277
        T0 = 0x08;
1278
    } else if ((uint64_t)T0 > (uint64_t)T1) {
1279
        T0 = 0x04;
1280
    } else {
1281
        T0 = 0x02;
1282
    }
1283
    T0 |= xer_so;
1284
    RETURN();
1285
}
1286
#endif
1287

    
1288
/* compare logical immediate */
1289
void OPPROTO op_cmpli (void)
1290
{
1291
    if ((uint32_t)T0 < (uint32_t)PARAM1) {
1292
        T0 = 0x08;
1293
    } else if ((uint32_t)T0 > (uint32_t)PARAM1) {
1294
        T0 = 0x04;
1295
    } else {
1296
        T0 = 0x02;
1297
    }
1298
    T0 |= xer_so;
1299
    RETURN();
1300
}
1301

    
1302
#if defined(TARGET_PPC64)
1303
void OPPROTO op_cmpli_64 (void)
1304
{
1305
    if ((uint64_t)T0 < (uint64_t)PARAM1) {
1306
        T0 = 0x08;
1307
    } else if ((uint64_t)T0 > (uint64_t)PARAM1) {
1308
        T0 = 0x04;
1309
    } else {
1310
        T0 = 0x02;
1311
    }
1312
    T0 |= xer_so;
1313
    RETURN();
1314
}
1315
#endif
1316

    
1317
void OPPROTO op_isel (void)
1318
{
1319
    if (T0)
1320
        T0 = T1;
1321
    else
1322
        T0 = T2;
1323
    RETURN();
1324
}
1325

    
1326
void OPPROTO op_popcntb (void)
1327
{
1328
    do_popcntb();
1329
    RETURN();
1330
}
1331

    
1332
#if defined(TARGET_PPC64)
1333
void OPPROTO op_popcntb_64 (void)
1334
{
1335
    do_popcntb_64();
1336
    RETURN();
1337
}
1338
#endif
1339

    
1340
/***                            Integer logical                            ***/
1341
/* and */
1342
void OPPROTO op_and (void)
1343
{
1344
    T0 &= T1;
1345
    RETURN();
1346
}
1347

    
1348
/* andc */
1349
void OPPROTO op_andc (void)
1350
{
1351
    T0 &= ~T1;
1352
    RETURN();
1353
}
1354

    
1355
/* andi. */
1356
void OPPROTO op_andi_T0 (void)
1357
{
1358
    T0 &= (uint32_t)PARAM1;
1359
    RETURN();
1360
}
1361

    
1362
void OPPROTO op_andi_T1 (void)
1363
{
1364
    T1 &= (uint32_t)PARAM1;
1365
    RETURN();
1366
}
1367

    
1368
#if defined(TARGET_PPC64)
1369
void OPPROTO op_andi_T0_64 (void)
1370
{
1371
    T0 &= ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
1372
    RETURN();
1373
}
1374

    
1375
void OPPROTO op_andi_T1_64 (void)
1376
{
1377
    T1 &= ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
1378
    RETURN();
1379
}
1380
#endif
1381

    
1382
/* count leading zero */
1383
void OPPROTO op_cntlzw (void)
1384
{
1385
    do_cntlzw();
1386
    RETURN();
1387
}
1388

    
1389
#if defined(TARGET_PPC64)
1390
void OPPROTO op_cntlzd (void)
1391
{
1392
    do_cntlzd();
1393
    RETURN();
1394
}
1395
#endif
1396

    
1397
/* eqv */
1398
void OPPROTO op_eqv (void)
1399
{
1400
    T0 = ~(T0 ^ T1);
1401
    RETURN();
1402
}
1403

    
1404
/* extend sign byte */
1405
void OPPROTO op_extsb (void)
1406
{
1407
#if defined (TARGET_PPC64)
1408
    T0 = (int64_t)((int8_t)T0);
1409
#else
1410
    T0 = (int32_t)((int8_t)T0);
1411
#endif
1412
    RETURN();
1413
}
1414

    
1415
/* extend sign half word */
1416
void OPPROTO op_extsh (void)
1417
{
1418
#if defined (TARGET_PPC64)
1419
    T0 = (int64_t)((int16_t)T0);
1420
#else
1421
    T0 = (int32_t)((int16_t)T0);
1422
#endif
1423
    RETURN();
1424
}
1425

    
1426
#if defined (TARGET_PPC64)
1427
void OPPROTO op_extsw (void)
1428
{
1429
    T0 = (int64_t)((int32_t)T0);
1430
    RETURN();
1431
}
1432
#endif
1433

    
1434
/* nand */
1435
void OPPROTO op_nand (void)
1436
{
1437
    T0 = ~(T0 & T1);
1438
    RETURN();
1439
}
1440

    
1441
/* nor */
1442
void OPPROTO op_nor (void)
1443
{
1444
    T0 = ~(T0 | T1);
1445
    RETURN();
1446
}
1447

    
1448
/* or */
1449
void OPPROTO op_or (void)
1450
{
1451
    T0 |= T1;
1452
    RETURN();
1453
}
1454

    
1455
/* orc */
1456
void OPPROTO op_orc (void)
1457
{
1458
    T0 |= ~T1;
1459
    RETURN();
1460
}
1461

    
1462
/* ori */
1463
void OPPROTO op_ori (void)
1464
{
1465
    T0 |= (uint32_t)PARAM1;
1466
    RETURN();
1467
}
1468

    
1469
/* xor */
1470
void OPPROTO op_xor (void)
1471
{
1472
    T0 ^= T1;
1473
    RETURN();
1474
}
1475

    
1476
/* xori */
1477
void OPPROTO op_xori (void)
1478
{
1479
    T0 ^= (uint32_t)PARAM1;
1480
    RETURN();
1481
}
1482

    
1483
/***                             Integer rotate                            ***/
1484
void OPPROTO op_rotl32_T0_T1 (void)
1485
{
1486
    T0 = rotl32(T0, T1 & 0x1F);
1487
    RETURN();
1488
}
1489

    
1490
void OPPROTO op_rotli32_T0 (void)
1491
{
1492
    T0 = rotl32(T0, PARAM1);
1493
    RETURN();
1494
}
1495

    
1496
#if defined(TARGET_PPC64)
1497
void OPPROTO op_rotl64_T0_T1 (void)
1498
{
1499
    T0 = rotl64(T0, T1 & 0x3F);
1500
    RETURN();
1501
}
1502

    
1503
void OPPROTO op_rotli64_T0 (void)
1504
{
1505
    T0 = rotl64(T0, PARAM1);
1506
    RETURN();
1507
}
1508
#endif
1509

    
1510
/***                             Integer shift                             ***/
1511
/* shift left word */
1512
void OPPROTO op_slw (void)
1513
{
1514
    if (T1 & 0x20) {
1515
        T0 = 0;
1516
    } else {
1517
        T0 = (uint32_t)(T0 << T1);
1518
    }
1519
    RETURN();
1520
}
1521

    
1522
#if defined(TARGET_PPC64)
1523
void OPPROTO op_sld (void)
1524
{
1525
    if (T1 & 0x40) {
1526
        T0 = 0;
1527
    } else {
1528
        T0 = T0 << T1;
1529
    }
1530
    RETURN();
1531
}
1532
#endif
1533

    
1534
/* shift right algebraic word */
1535
void OPPROTO op_sraw (void)
1536
{
1537
    do_sraw();
1538
    RETURN();
1539
}
1540

    
1541
#if defined(TARGET_PPC64)
1542
void OPPROTO op_srad (void)
1543
{
1544
    do_srad();
1545
    RETURN();
1546
}
1547
#endif
1548

    
1549
/* shift right algebraic word immediate */
1550
void OPPROTO op_srawi (void)
1551
{
1552
    uint32_t mask = (uint32_t)PARAM2;
1553

    
1554
    T0 = (int32_t)T0 >> PARAM1;
1555
    if ((int32_t)T1 < 0 && (T1 & mask) != 0) {
1556
        xer_ca = 1;
1557
    } else {
1558
        xer_ca = 0;
1559
    }
1560
    RETURN();
1561
}
1562

    
1563
#if defined(TARGET_PPC64)
1564
void OPPROTO op_sradi (void)
1565
{
1566
    uint64_t mask = ((uint64_t)PARAM2 << 32) | (uint64_t)PARAM3;
1567

    
1568
    T0 = (int64_t)T0 >> PARAM1;
1569
    if ((int64_t)T1 < 0 && ((uint64_t)T1 & mask) != 0) {
1570
        xer_ca = 1;
1571
    } else {
1572
        xer_ca = 0;
1573
    }
1574
    RETURN();
1575
}
1576
#endif
1577

    
1578
/* shift right word */
1579
void OPPROTO op_srw (void)
1580
{
1581
    if (T1 & 0x20) {
1582
        T0 = 0;
1583
    } else {
1584
        T0 = (uint32_t)T0 >> T1;
1585
    }
1586
    RETURN();
1587
}
1588

    
1589
#if defined(TARGET_PPC64)
1590
void OPPROTO op_srd (void)
1591
{
1592
    if (T1 & 0x40) {
1593
        T0 = 0;
1594
    } else {
1595
        T0 = (uint64_t)T0 >> T1;
1596
    }
1597
    RETURN();
1598
}
1599
#endif
1600

    
1601
void OPPROTO op_sl_T0_T1 (void)
1602
{
1603
    T0 = T0 << T1;
1604
    RETURN();
1605
}
1606

    
1607
void OPPROTO op_sli_T0 (void)
1608
{
1609
    T0 = T0 << PARAM1;
1610
    RETURN();
1611
}
1612

    
1613
void OPPROTO op_sli_T1 (void)
1614
{
1615
    T1 = T1 << PARAM1;
1616
    RETURN();
1617
}
1618

    
1619
void OPPROTO op_srl_T0_T1 (void)
1620
{
1621
    T0 = (uint32_t)T0 >> T1;
1622
    RETURN();
1623
}
1624

    
1625
#if defined(TARGET_PPC64)
1626
void OPPROTO op_srl_T0_T1_64 (void)
1627
{
1628
    T0 = (uint32_t)T0 >> T1;
1629
    RETURN();
1630
}
1631
#endif
1632

    
1633
void OPPROTO op_srli_T0 (void)
1634
{
1635
    T0 = (uint32_t)T0 >> PARAM1;
1636
    RETURN();
1637
}
1638

    
1639
#if defined(TARGET_PPC64)
1640
void OPPROTO op_srli_T0_64 (void)
1641
{
1642
    T0 = (uint64_t)T0 >> PARAM1;
1643
    RETURN();
1644
}
1645
#endif
1646

    
1647
void OPPROTO op_srli_T1 (void)
1648
{
1649
    T1 = (uint32_t)T1 >> PARAM1;
1650
    RETURN();
1651
}
1652

    
1653
#if defined(TARGET_PPC64)
1654
void OPPROTO op_srli_T1_64 (void)
1655
{
1656
    T1 = (uint64_t)T1 >> PARAM1;
1657
    RETURN();
1658
}
1659
#endif
1660

    
1661
/***                       Floating-Point arithmetic                       ***/
1662
/* fadd - fadd. */
1663
void OPPROTO op_fadd (void)
1664
{
1665
#if USE_PRECISE_EMULATION
1666
    do_fadd();
1667
#else
1668
    FT0 = float64_add(FT0, FT1, &env->fp_status);
1669
#endif
1670
    RETURN();
1671
}
1672

    
1673
/* fsub - fsub. */
1674
void OPPROTO op_fsub (void)
1675
{
1676
#if USE_PRECISE_EMULATION
1677
    do_fsub();
1678
#else
1679
    FT0 = float64_sub(FT0, FT1, &env->fp_status);
1680
#endif
1681
    RETURN();
1682
}
1683

    
1684
/* fmul - fmul. */
1685
void OPPROTO op_fmul (void)
1686
{
1687
#if USE_PRECISE_EMULATION
1688
    do_fmul();
1689
#else
1690
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1691
#endif
1692
    RETURN();
1693
}
1694

    
1695
/* fdiv - fdiv. */
1696
void OPPROTO op_fdiv (void)
1697
{
1698
#if USE_PRECISE_EMULATION
1699
    do_fdiv();
1700
#else
1701
    FT0 = float64_div(FT0, FT1, &env->fp_status);
1702
#endif
1703
    RETURN();
1704
}
1705

    
1706
/* fsqrt - fsqrt. */
1707
void OPPROTO op_fsqrt (void)
1708
{
1709
    do_fsqrt();
1710
    RETURN();
1711
}
1712

    
1713
/* fre - fre. */
1714
void OPPROTO op_fre (void)
1715
{
1716
    do_fre();
1717
    RETURN();
1718
}
1719

    
1720
/* fres - fres. */
1721
void OPPROTO op_fres (void)
1722
{
1723
    do_fres();
1724
    RETURN();
1725
}
1726

    
1727
/* frsqrte  - frsqrte. */
1728
void OPPROTO op_frsqrte (void)
1729
{
1730
    do_frsqrte();
1731
    RETURN();
1732
}
1733

    
1734
/* fsel - fsel. */
1735
void OPPROTO op_fsel (void)
1736
{
1737
    do_fsel();
1738
    RETURN();
1739
}
1740

    
1741
/***                     Floating-Point multiply-and-add                   ***/
1742
/* fmadd - fmadd. */
1743
void OPPROTO op_fmadd (void)
1744
{
1745
#if USE_PRECISE_EMULATION
1746
    do_fmadd();
1747
#else
1748
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1749
    FT0 = float64_add(FT0, FT2, &env->fp_status);
1750
#endif
1751
    RETURN();
1752
}
1753

    
1754
/* fmsub - fmsub. */
1755
void OPPROTO op_fmsub (void)
1756
{
1757
#if USE_PRECISE_EMULATION
1758
    do_fmsub();
1759
#else
1760
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1761
    FT0 = float64_sub(FT0, FT2, &env->fp_status);
1762
#endif
1763
    RETURN();
1764
}
1765

    
1766
/* fnmadd - fnmadd. - fnmadds - fnmadds. */
1767
void OPPROTO op_fnmadd (void)
1768
{
1769
    do_fnmadd();
1770
    RETURN();
1771
}
1772

    
1773
/* fnmsub - fnmsub. */
1774
void OPPROTO op_fnmsub (void)
1775
{
1776
    do_fnmsub();
1777
    RETURN();
1778
}
1779

    
1780
/***                     Floating-Point round & convert                    ***/
1781
/* frsp - frsp. */
1782
void OPPROTO op_frsp (void)
1783
{
1784
#if USE_PRECISE_EMULATION
1785
    do_frsp();
1786
#else
1787
    FT0 = float64_to_float32(FT0, &env->fp_status);
1788
#endif
1789
    RETURN();
1790
}
1791

    
1792
/* fctiw - fctiw. */
1793
void OPPROTO op_fctiw (void)
1794
{
1795
    do_fctiw();
1796
    RETURN();
1797
}
1798

    
1799
/* fctiwz - fctiwz. */
1800
void OPPROTO op_fctiwz (void)
1801
{
1802
    do_fctiwz();
1803
    RETURN();
1804
}
1805

    
1806
#if defined(TARGET_PPC64)
1807
/* fcfid - fcfid. */
1808
void OPPROTO op_fcfid (void)
1809
{
1810
    do_fcfid();
1811
    RETURN();
1812
}
1813

    
1814
/* fctid - fctid. */
1815
void OPPROTO op_fctid (void)
1816
{
1817
    do_fctid();
1818
    RETURN();
1819
}
1820

    
1821
/* fctidz - fctidz. */
1822
void OPPROTO op_fctidz (void)
1823
{
1824
    do_fctidz();
1825
    RETURN();
1826
}
1827
#endif
1828

    
1829
void OPPROTO op_frin (void)
1830
{
1831
    do_frin();
1832
    RETURN();
1833
}
1834

    
1835
void OPPROTO op_friz (void)
1836
{
1837
    do_friz();
1838
    RETURN();
1839
}
1840

    
1841
void OPPROTO op_frip (void)
1842
{
1843
    do_frip();
1844
    RETURN();
1845
}
1846

    
1847
void OPPROTO op_frim (void)
1848
{
1849
    do_frim();
1850
    RETURN();
1851
}
1852

    
1853
/***                         Floating-Point compare                        ***/
1854
/* fcmpu */
1855
void OPPROTO op_fcmpu (void)
1856
{
1857
    do_fcmpu();
1858
    RETURN();
1859
}
1860

    
1861
/* fcmpo */
1862
void OPPROTO op_fcmpo (void)
1863
{
1864
    do_fcmpo();
1865
    RETURN();
1866
}
1867

    
1868
/***                         Floating-point move                           ***/
1869
/* fabs */
1870
void OPPROTO op_fabs (void)
1871
{
1872
    FT0 = float64_abs(FT0);
1873
    RETURN();
1874
}
1875

    
1876
/* fnabs */
1877
void OPPROTO op_fnabs (void)
1878
{
1879
    FT0 = float64_abs(FT0);
1880
    FT0 = float64_chs(FT0);
1881
    RETURN();
1882
}
1883

    
1884
/* fneg */
1885
void OPPROTO op_fneg (void)
1886
{
1887
    FT0 = float64_chs(FT0);
1888
    RETURN();
1889
}
1890

    
1891
/* Load and store */
1892
#define MEMSUFFIX _raw
1893
#include "op_helper.h"
1894
#include "op_mem.h"
1895
#if !defined(CONFIG_USER_ONLY)
1896
#define MEMSUFFIX _user
1897
#include "op_helper.h"
1898
#include "op_mem.h"
1899
#define MEMSUFFIX _kernel
1900
#include "op_helper.h"
1901
#include "op_mem.h"
1902
#define MEMSUFFIX _hypv
1903
#include "op_helper.h"
1904
#include "op_mem.h"
1905
#endif
1906

    
1907
/* Special op to check and maybe clear reservation */
1908
void OPPROTO op_check_reservation (void)
1909
{
1910
    if ((uint32_t)env->reserve == (uint32_t)(T0 & ~0x00000003))
1911
        env->reserve = (target_ulong)-1ULL;
1912
    RETURN();
1913
}
1914

    
1915
#if defined(TARGET_PPC64)
1916
void OPPROTO op_check_reservation_64 (void)
1917
{
1918
    if ((uint64_t)env->reserve == (uint64_t)(T0 & ~0x00000003))
1919
        env->reserve = (target_ulong)-1ULL;
1920
    RETURN();
1921
}
1922
#endif
1923

    
1924
void OPPROTO op_wait (void)
1925
{
1926
    env->halted = 1;
1927
    RETURN();
1928
}
1929

    
1930
/* Return from interrupt */
1931
#if !defined(CONFIG_USER_ONLY)
1932
void OPPROTO op_rfi (void)
1933
{
1934
    do_rfi();
1935
    RETURN();
1936
}
1937

    
1938
#if defined(TARGET_PPC64)
1939
void OPPROTO op_rfid (void)
1940
{
1941
    do_rfid();
1942
    RETURN();
1943
}
1944

    
1945
void OPPROTO op_hrfid (void)
1946
{
1947
    do_hrfid();
1948
    RETURN();
1949
}
1950
#endif
1951

    
1952
/* Exception vectors */
1953
void OPPROTO op_store_excp_prefix (void)
1954
{
1955
    T0 &= env->ivpr_mask;
1956
    env->excp_prefix = T0;
1957
    RETURN();
1958
}
1959

    
1960
void OPPROTO op_store_excp_vector (void)
1961
{
1962
    T0 &= env->ivor_mask;
1963
    env->excp_vectors[PARAM1] = T0;
1964
    RETURN();
1965
}
1966
#endif
1967

    
1968
/* Trap word */
1969
void OPPROTO op_tw (void)
1970
{
1971
    do_tw(PARAM1);
1972
    RETURN();
1973
}
1974

    
1975
#if defined(TARGET_PPC64)
1976
void OPPROTO op_td (void)
1977
{
1978
    do_td(PARAM1);
1979
    RETURN();
1980
}
1981
#endif
1982

    
1983
#if !defined(CONFIG_USER_ONLY)
1984
/* tlbia */
1985
void OPPROTO op_tlbia (void)
1986
{
1987
    ppc_tlb_invalidate_all(env);
1988
    RETURN();
1989
}
1990

    
1991
/* tlbie */
1992
void OPPROTO op_tlbie (void)
1993
{
1994
    ppc_tlb_invalidate_one(env, (uint32_t)T0);
1995
    RETURN();
1996
}
1997

    
1998
#if defined(TARGET_PPC64)
1999
void OPPROTO op_tlbie_64 (void)
2000
{
2001
    ppc_tlb_invalidate_one(env, T0);
2002
    RETURN();
2003
}
2004
#endif
2005

    
2006
#if defined(TARGET_PPC64)
2007
void OPPROTO op_slbia (void)
2008
{
2009
    ppc_slb_invalidate_all(env);
2010
    RETURN();
2011
}
2012

    
2013
void OPPROTO op_slbie (void)
2014
{
2015
    ppc_slb_invalidate_one(env, (uint32_t)T0);
2016
    RETURN();
2017
}
2018

    
2019
void OPPROTO op_slbie_64 (void)
2020
{
2021
    ppc_slb_invalidate_one(env, T0);
2022
    RETURN();
2023
}
2024
#endif
2025
#endif
2026

    
2027
#if !defined(CONFIG_USER_ONLY)
2028
/* PowerPC 602/603/755 software TLB load instructions */
2029
void OPPROTO op_6xx_tlbld (void)
2030
{
2031
    do_load_6xx_tlb(0);
2032
    RETURN();
2033
}
2034

    
2035
void OPPROTO op_6xx_tlbli (void)
2036
{
2037
    do_load_6xx_tlb(1);
2038
    RETURN();
2039
}
2040

    
2041
/* PowerPC 74xx software TLB load instructions */
2042
void OPPROTO op_74xx_tlbld (void)
2043
{
2044
    do_load_74xx_tlb(0);
2045
    RETURN();
2046
}
2047

    
2048
void OPPROTO op_74xx_tlbli (void)
2049
{
2050
    do_load_74xx_tlb(1);
2051
    RETURN();
2052
}
2053
#endif
2054

    
2055
/* 601 specific */
2056
void OPPROTO op_load_601_rtcl (void)
2057
{
2058
    T0 = cpu_ppc601_load_rtcl(env);
2059
    RETURN();
2060
}
2061

    
2062
void OPPROTO op_load_601_rtcu (void)
2063
{
2064
    T0 = cpu_ppc601_load_rtcu(env);
2065
    RETURN();
2066
}
2067

    
2068
#if !defined(CONFIG_USER_ONLY)
2069
void OPPROTO op_store_601_rtcl (void)
2070
{
2071
    cpu_ppc601_store_rtcl(env, T0);
2072
    RETURN();
2073
}
2074

    
2075
void OPPROTO op_store_601_rtcu (void)
2076
{
2077
    cpu_ppc601_store_rtcu(env, T0);
2078
    RETURN();
2079
}
2080

    
2081
void OPPROTO op_store_hid0_601 (void)
2082
{
2083
    do_store_hid0_601();
2084
    RETURN();
2085
}
2086

    
2087
void OPPROTO op_load_601_bat (void)
2088
{
2089
    T0 = env->IBAT[PARAM1][PARAM2];
2090
    RETURN();
2091
}
2092

    
2093
void OPPROTO op_store_601_batl (void)
2094
{
2095
    do_store_ibatl_601(env, PARAM1, T0);
2096
    RETURN();
2097
}
2098

    
2099
void OPPROTO op_store_601_batu (void)
2100
{
2101
    do_store_ibatu_601(env, PARAM1, T0);
2102
    RETURN();
2103
}
2104
#endif /* !defined(CONFIG_USER_ONLY) */
2105

    
2106
/* PowerPC 601 specific instructions (POWER bridge) */
2107
/* XXX: those micro-ops need tests ! */
2108
void OPPROTO op_POWER_abs (void)
2109
{
2110
    if ((int32_t)T0 == INT32_MIN)
2111
        T0 = INT32_MAX;
2112
    else if ((int32_t)T0 < 0)
2113
        T0 = -T0;
2114
    RETURN();
2115
}
2116

    
2117
void OPPROTO op_POWER_abso (void)
2118
{
2119
    do_POWER_abso();
2120
    RETURN();
2121
}
2122

    
2123
void OPPROTO op_POWER_clcs (void)
2124
{
2125
    do_POWER_clcs();
2126
    RETURN();
2127
}
2128

    
2129
void OPPROTO op_POWER_div (void)
2130
{
2131
    do_POWER_div();
2132
    RETURN();
2133
}
2134

    
2135
void OPPROTO op_POWER_divo (void)
2136
{
2137
    do_POWER_divo();
2138
    RETURN();
2139
}
2140

    
2141
void OPPROTO op_POWER_divs (void)
2142
{
2143
    do_POWER_divs();
2144
    RETURN();
2145
}
2146

    
2147
void OPPROTO op_POWER_divso (void)
2148
{
2149
    do_POWER_divso();
2150
    RETURN();
2151
}
2152

    
2153
void OPPROTO op_POWER_doz (void)
2154
{
2155
    if ((int32_t)T1 > (int32_t)T0)
2156
        T0 = T1 - T0;
2157
    else
2158
        T0 = 0;
2159
    RETURN();
2160
}
2161

    
2162
void OPPROTO op_POWER_dozo (void)
2163
{
2164
    do_POWER_dozo();
2165
    RETURN();
2166
}
2167

    
2168
void OPPROTO op_load_xer_cmp (void)
2169
{
2170
    T2 = xer_cmp;
2171
    RETURN();
2172
}
2173

    
2174
void OPPROTO op_POWER_maskg (void)
2175
{
2176
    do_POWER_maskg();
2177
    RETURN();
2178
}
2179

    
2180
void OPPROTO op_POWER_maskir (void)
2181
{
2182
    T0 = (T0 & ~T2) | (T1 & T2);
2183
    RETURN();
2184
}
2185

    
2186
void OPPROTO op_POWER_mul (void)
2187
{
2188
    uint64_t tmp;
2189

    
2190
    tmp = (uint64_t)T0 * (uint64_t)T1;
2191
    env->spr[SPR_MQ] = tmp >> 32;
2192
    T0 = tmp;
2193
    RETURN();
2194
}
2195

    
2196
void OPPROTO op_POWER_mulo (void)
2197
{
2198
    do_POWER_mulo();
2199
    RETURN();
2200
}
2201

    
2202
void OPPROTO op_POWER_nabs (void)
2203
{
2204
    if (T0 > 0)
2205
        T0 = -T0;
2206
    RETURN();
2207
}
2208

    
2209
void OPPROTO op_POWER_nabso (void)
2210
{
2211
    /* nabs never overflows */
2212
    if (T0 > 0)
2213
        T0 = -T0;
2214
    xer_ov = 0;
2215
    RETURN();
2216
}
2217

    
2218
/* XXX: factorise POWER rotates... */
2219
void OPPROTO op_POWER_rlmi (void)
2220
{
2221
    T0 = rotl32(T0, T2) & PARAM1;
2222
    T0 |= T1 & (uint32_t)PARAM2;
2223
    RETURN();
2224
}
2225

    
2226
void OPPROTO op_POWER_rrib (void)
2227
{
2228
    T2 &= 0x1FUL;
2229
    T0 = rotl32(T0 & INT32_MIN, T2);
2230
    T0 |= T1 & ~rotl32(INT32_MIN, T2);
2231
    RETURN();
2232
}
2233

    
2234
void OPPROTO op_POWER_sle (void)
2235
{
2236
    T1 &= 0x1FUL;
2237
    env->spr[SPR_MQ] = rotl32(T0, T1);
2238
    T0 = T0 << T1;
2239
    RETURN();
2240
}
2241

    
2242
void OPPROTO op_POWER_sleq (void)
2243
{
2244
    uint32_t tmp = env->spr[SPR_MQ];
2245

    
2246
    T1 &= 0x1FUL;
2247
    env->spr[SPR_MQ] = rotl32(T0, T1);
2248
    T0 = T0 << T1;
2249
    T0 |= tmp >> (32 - T1);
2250
    RETURN();
2251
}
2252

    
2253
void OPPROTO op_POWER_sllq (void)
2254
{
2255
    uint32_t msk = UINT32_MAX;
2256

    
2257
    msk = msk << (T1 & 0x1FUL);
2258
    if (T1 & 0x20UL)
2259
        msk = ~msk;
2260
    T1 &= 0x1FUL;
2261
    T0 = (T0 << T1) & msk;
2262
    T0 |= env->spr[SPR_MQ] & ~msk;
2263
    RETURN();
2264
}
2265

    
2266
void OPPROTO op_POWER_slq (void)
2267
{
2268
    uint32_t msk = UINT32_MAX, tmp;
2269

    
2270
    msk = msk << (T1 & 0x1FUL);
2271
    if (T1 & 0x20UL)
2272
        msk = ~msk;
2273
    T1 &= 0x1FUL;
2274
    tmp = rotl32(T0, T1);
2275
    T0 = tmp & msk;
2276
    env->spr[SPR_MQ] = tmp;
2277
    RETURN();
2278
}
2279

    
2280
void OPPROTO op_POWER_sraq (void)
2281
{
2282
    env->spr[SPR_MQ] = rotl32(T0, 32 - (T1 & 0x1FUL));
2283
    if (T1 & 0x20UL)
2284
        T0 = UINT32_MAX;
2285
    else
2286
        T0 = (int32_t)T0 >> T1;
2287
    RETURN();
2288
}
2289

    
2290
void OPPROTO op_POWER_sre (void)
2291
{
2292
    T1 &= 0x1FUL;
2293
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2294
    T0 = (int32_t)T0 >> T1;
2295
    RETURN();
2296
}
2297

    
2298
void OPPROTO op_POWER_srea (void)
2299
{
2300
    T1 &= 0x1FUL;
2301
    env->spr[SPR_MQ] = T0 >> T1;
2302
    T0 = (int32_t)T0 >> T1;
2303
    RETURN();
2304
}
2305

    
2306
void OPPROTO op_POWER_sreq (void)
2307
{
2308
    uint32_t tmp;
2309
    int32_t msk;
2310

    
2311
    T1 &= 0x1FUL;
2312
    msk = INT32_MIN >> T1;
2313
    tmp = env->spr[SPR_MQ];
2314
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2315
    T0 = T0 >> T1;
2316
    T0 |= tmp & msk;
2317
    RETURN();
2318
}
2319

    
2320
void OPPROTO op_POWER_srlq (void)
2321
{
2322
    uint32_t tmp;
2323
    int32_t msk;
2324

    
2325
    msk = INT32_MIN >> (T1 & 0x1FUL);
2326
    if (T1 & 0x20UL)
2327
        msk = ~msk;
2328
    T1 &= 0x1FUL;
2329
    tmp = env->spr[SPR_MQ];
2330
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2331
    T0 = T0 >> T1;
2332
    T0 &= msk;
2333
    T0 |= tmp & ~msk;
2334
    RETURN();
2335
}
2336

    
2337
void OPPROTO op_POWER_srq (void)
2338
{
2339
    T1 &= 0x1FUL;
2340
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2341
    T0 = T0 >> T1;
2342
    RETURN();
2343
}
2344

    
2345
/* POWER instructions not implemented in PowerPC 601 */
2346
#if !defined(CONFIG_USER_ONLY)
2347
void OPPROTO op_POWER_mfsri (void)
2348
{
2349
    T1 = T0 >> 28;
2350
    T0 = env->sr[T1];
2351
    RETURN();
2352
}
2353

    
2354
void OPPROTO op_POWER_rac (void)
2355
{
2356
    do_POWER_rac();
2357
    RETURN();
2358
}
2359

    
2360
void OPPROTO op_POWER_rfsvc (void)
2361
{
2362
    do_POWER_rfsvc();
2363
    RETURN();
2364
}
2365
#endif
2366

    
2367
/* PowerPC 602 specific instruction */
2368
#if !defined(CONFIG_USER_ONLY)
2369
void OPPROTO op_602_mfrom (void)
2370
{
2371
    do_op_602_mfrom();
2372
    RETURN();
2373
}
2374
#endif
2375

    
2376
/* PowerPC 4xx specific micro-ops */
2377
void OPPROTO op_405_add_T0_T2 (void)
2378
{
2379
    T0 = (int32_t)T0 + (int32_t)T2;
2380
    RETURN();
2381
}
2382

    
2383
void OPPROTO op_405_mulchw (void)
2384
{
2385
    T0 = ((int16_t)T0) * ((int16_t)(T1 >> 16));
2386
    RETURN();
2387
}
2388

    
2389
void OPPROTO op_405_mulchwu (void)
2390
{
2391
    T0 = ((uint16_t)T0) * ((uint16_t)(T1 >> 16));
2392
    RETURN();
2393
}
2394

    
2395
void OPPROTO op_405_mulhhw (void)
2396
{
2397
    T0 = ((int16_t)(T0 >> 16)) * ((int16_t)(T1 >> 16));
2398
    RETURN();
2399
}
2400

    
2401
void OPPROTO op_405_mulhhwu (void)
2402
{
2403
    T0 = ((uint16_t)(T0 >> 16)) * ((uint16_t)(T1 >> 16));
2404
    RETURN();
2405
}
2406

    
2407
void OPPROTO op_405_mullhw (void)
2408
{
2409
    T0 = ((int16_t)T0) * ((int16_t)T1);
2410
    RETURN();
2411
}
2412

    
2413
void OPPROTO op_405_mullhwu (void)
2414
{
2415
    T0 = ((uint16_t)T0) * ((uint16_t)T1);
2416
    RETURN();
2417
}
2418

    
2419
void OPPROTO op_405_check_sat (void)
2420
{
2421
    do_405_check_sat();
2422
    RETURN();
2423
}
2424

    
2425
void OPPROTO op_405_check_ovu (void)
2426
{
2427
    if (likely(T0 >= T2)) {
2428
        xer_ov = 0;
2429
    } else {
2430
        xer_ov = 1;
2431
        xer_so = 1;
2432
    }
2433
    RETURN();
2434
}
2435

    
2436
void OPPROTO op_405_check_satu (void)
2437
{
2438
    if (unlikely(T0 < T2)) {
2439
        /* Saturate result */
2440
        T0 = UINT32_MAX;
2441
    }
2442
    RETURN();
2443
}
2444

    
2445
void OPPROTO op_load_dcr (void)
2446
{
2447
    do_load_dcr();
2448
    RETURN();
2449
}
2450

    
2451
void OPPROTO op_store_dcr (void)
2452
{
2453
    do_store_dcr();
2454
    RETURN();
2455
}
2456

    
2457
#if !defined(CONFIG_USER_ONLY)
2458
/* Return from critical interrupt :
2459
 * same as rfi, except nip & MSR are loaded from SRR2/3 instead of SRR0/1
2460
 */
2461
void OPPROTO op_40x_rfci (void)
2462
{
2463
    do_40x_rfci();
2464
    RETURN();
2465
}
2466

    
2467
void OPPROTO op_rfci (void)
2468
{
2469
    do_rfci();
2470
    RETURN();
2471
}
2472

    
2473
void OPPROTO op_rfdi (void)
2474
{
2475
    do_rfdi();
2476
    RETURN();
2477
}
2478

    
2479
void OPPROTO op_rfmci (void)
2480
{
2481
    do_rfmci();
2482
    RETURN();
2483
}
2484

    
2485
void OPPROTO op_wrte (void)
2486
{
2487
    /* We don't call do_store_msr here as we won't trigger
2488
     * any special case nor change hflags
2489
     */
2490
    T0 &= 1 << MSR_EE;
2491
    env->msr &= ~(1 << MSR_EE);
2492
    env->msr |= T0;
2493
    RETURN();
2494
}
2495

    
2496
void OPPROTO op_440_tlbre (void)
2497
{
2498
    do_440_tlbre(PARAM1);
2499
    RETURN();
2500
}
2501

    
2502
void OPPROTO op_440_tlbsx (void)
2503
{
2504
    T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_440_MMUCR] & 0xFF);
2505
    RETURN();
2506
}
2507

    
2508
void OPPROTO op_4xx_tlbsx_check (void)
2509
{
2510
    int tmp;
2511

    
2512
    tmp = xer_so;
2513
    if ((int)T0 != -1)
2514
        tmp |= 0x02;
2515
    env->crf[0] = tmp;
2516
    RETURN();
2517
}
2518

    
2519
void OPPROTO op_440_tlbwe (void)
2520
{
2521
    do_440_tlbwe(PARAM1);
2522
    RETURN();
2523
}
2524

    
2525
void OPPROTO op_4xx_tlbre_lo (void)
2526
{
2527
    do_4xx_tlbre_lo();
2528
    RETURN();
2529
}
2530

    
2531
void OPPROTO op_4xx_tlbre_hi (void)
2532
{
2533
    do_4xx_tlbre_hi();
2534
    RETURN();
2535
}
2536

    
2537
void OPPROTO op_4xx_tlbsx (void)
2538
{
2539
    T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_40x_PID]);
2540
    RETURN();
2541
}
2542

    
2543
void OPPROTO op_4xx_tlbwe_lo (void)
2544
{
2545
    do_4xx_tlbwe_lo();
2546
    RETURN();
2547
}
2548

    
2549
void OPPROTO op_4xx_tlbwe_hi (void)
2550
{
2551
    do_4xx_tlbwe_hi();
2552
    RETURN();
2553
}
2554
#endif
2555

    
2556
/* SPR micro-ops */
2557
/* 440 specific */
2558
void OPPROTO op_440_dlmzb (void)
2559
{
2560
    do_440_dlmzb();
2561
    RETURN();
2562
}
2563

    
2564
void OPPROTO op_440_dlmzb_update_Rc (void)
2565
{
2566
    if (T0 == 8)
2567
        T0 = 0x2;
2568
    else if (T0 < 4)
2569
        T0 = 0x4;
2570
    else
2571
        T0 = 0x8;
2572
    RETURN();
2573
}
2574

    
2575
#if !defined(CONFIG_USER_ONLY)
2576
void OPPROTO op_store_pir (void)
2577
{
2578
    env->spr[SPR_PIR] = T0 & 0x0000000FUL;
2579
    RETURN();
2580
}
2581

    
2582
void OPPROTO op_load_403_pb (void)
2583
{
2584
    do_load_403_pb(PARAM1);
2585
    RETURN();
2586
}
2587

    
2588
void OPPROTO op_store_403_pb (void)
2589
{
2590
    do_store_403_pb(PARAM1);
2591
    RETURN();
2592
}
2593

    
2594
void OPPROTO op_load_40x_pit (void)
2595
{
2596
    T0 = load_40x_pit(env);
2597
    RETURN();
2598
}
2599

    
2600
void OPPROTO op_store_40x_pit (void)
2601
{
2602
    store_40x_pit(env, T0);
2603
    RETURN();
2604
}
2605

    
2606
void OPPROTO op_store_40x_dbcr0 (void)
2607
{
2608
    store_40x_dbcr0(env, T0);
2609
    RETURN();
2610
}
2611

    
2612
void OPPROTO op_store_40x_sler (void)
2613
{
2614
    store_40x_sler(env, T0);
2615
    RETURN();
2616
}
2617

    
2618
void OPPROTO op_store_booke_tcr (void)
2619
{
2620
    store_booke_tcr(env, T0);
2621
    RETURN();
2622
}
2623

    
2624
void OPPROTO op_store_booke_tsr (void)
2625
{
2626
    store_booke_tsr(env, T0);
2627
    RETURN();
2628
}
2629
#endif /* !defined(CONFIG_USER_ONLY) */
2630

    
2631
/* SPE extension */
2632
void OPPROTO op_splatw_T1_64 (void)
2633
{
2634
    T1_64 = (T1_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL);
2635
    RETURN();
2636
}
2637

    
2638
void OPPROTO op_splatwi_T0_64 (void)
2639
{
2640
    uint64_t tmp = PARAM1;
2641

    
2642
    T0_64 = (tmp << 32) | tmp;
2643
    RETURN();
2644
}
2645

    
2646
void OPPROTO op_splatwi_T1_64 (void)
2647
{
2648
    uint64_t tmp = PARAM1;
2649

    
2650
    T1_64 = (tmp << 32) | tmp;
2651
    RETURN();
2652
}
2653

    
2654
void OPPROTO op_extsh_T1_64 (void)
2655
{
2656
    T1_64 = (int32_t)((int16_t)T1_64);
2657
    RETURN();
2658
}
2659

    
2660
void OPPROTO op_sli16_T1_64 (void)
2661
{
2662
    T1_64 = T1_64 << 16;
2663
    RETURN();
2664
}
2665

    
2666
void OPPROTO op_sli32_T1_64 (void)
2667
{
2668
    T1_64 = T1_64 << 32;
2669
    RETURN();
2670
}
2671

    
2672
void OPPROTO op_srli32_T1_64 (void)
2673
{
2674
    T1_64 = T1_64 >> 32;
2675
    RETURN();
2676
}
2677

    
2678
void OPPROTO op_evsel (void)
2679
{
2680
    do_evsel();
2681
    RETURN();
2682
}
2683

    
2684
void OPPROTO op_evaddw (void)
2685
{
2686
    do_evaddw();
2687
    RETURN();
2688
}
2689

    
2690
void OPPROTO op_evsubfw (void)
2691
{
2692
    do_evsubfw();
2693
    RETURN();
2694
}
2695

    
2696
void OPPROTO op_evneg (void)
2697
{
2698
    do_evneg();
2699
    RETURN();
2700
}
2701

    
2702
void OPPROTO op_evabs (void)
2703
{
2704
    do_evabs();
2705
    RETURN();
2706
}
2707

    
2708
void OPPROTO op_evextsh (void)
2709
{
2710
    T0_64 = ((uint64_t)((int32_t)(int16_t)(T0_64 >> 32)) << 32) |
2711
        (uint64_t)((int32_t)(int16_t)T0_64);
2712
    RETURN();
2713
}
2714

    
2715
void OPPROTO op_evextsb (void)
2716
{
2717
    T0_64 = ((uint64_t)((int32_t)(int8_t)(T0_64 >> 32)) << 32) |
2718
        (uint64_t)((int32_t)(int8_t)T0_64);
2719
    RETURN();
2720
}
2721

    
2722
void OPPROTO op_evcntlzw (void)
2723
{
2724
    do_evcntlzw();
2725
    RETURN();
2726
}
2727

    
2728
void OPPROTO op_evrndw (void)
2729
{
2730
    do_evrndw();
2731
    RETURN();
2732
}
2733

    
2734
void OPPROTO op_brinc (void)
2735
{
2736
    do_brinc();
2737
    RETURN();
2738
}
2739

    
2740
void OPPROTO op_evcntlsw (void)
2741
{
2742
    do_evcntlsw();
2743
    RETURN();
2744
}
2745

    
2746
void OPPROTO op_evand (void)
2747
{
2748
    T0_64 &= T1_64;
2749
    RETURN();
2750
}
2751

    
2752
void OPPROTO op_evandc (void)
2753
{
2754
    T0_64 &= ~T1_64;
2755
    RETURN();
2756
}
2757

    
2758
void OPPROTO op_evor (void)
2759
{
2760
    T0_64 |= T1_64;
2761
    RETURN();
2762
}
2763

    
2764
void OPPROTO op_evxor (void)
2765
{
2766
    T0_64 ^= T1_64;
2767
    RETURN();
2768
}
2769

    
2770
void OPPROTO op_eveqv (void)
2771
{
2772
    T0_64 = ~(T0_64 ^ T1_64);
2773
    RETURN();
2774
}
2775

    
2776
void OPPROTO op_evnor (void)
2777
{
2778
    T0_64 = ~(T0_64 | T1_64);
2779
    RETURN();
2780
}
2781

    
2782
void OPPROTO op_evorc (void)
2783
{
2784
    T0_64 |= ~T1_64;
2785
    RETURN();
2786
}
2787

    
2788
void OPPROTO op_evnand (void)
2789
{
2790
    T0_64 = ~(T0_64 & T1_64);
2791
    RETURN();
2792
}
2793

    
2794
void OPPROTO op_evsrws (void)
2795
{
2796
    do_evsrws();
2797
    RETURN();
2798
}
2799

    
2800
void OPPROTO op_evsrwu (void)
2801
{
2802
    do_evsrwu();
2803
    RETURN();
2804
}
2805

    
2806
void OPPROTO op_evslw (void)
2807
{
2808
    do_evslw();
2809
    RETURN();
2810
}
2811

    
2812
void OPPROTO op_evrlw (void)
2813
{
2814
    do_evrlw();
2815
    RETURN();
2816
}
2817

    
2818
void OPPROTO op_evmergelo (void)
2819
{
2820
    T0_64 = (T0_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL);
2821
    RETURN();
2822
}
2823

    
2824
void OPPROTO op_evmergehi (void)
2825
{
2826
    T0_64 = (T0_64 & 0xFFFFFFFF00000000ULL) | (T1_64 >> 32);
2827
    RETURN();
2828
}
2829

    
2830
void OPPROTO op_evmergelohi (void)
2831
{
2832
    T0_64 = (T0_64 << 32) | (T1_64 >> 32);
2833
    RETURN();
2834
}
2835

    
2836
void OPPROTO op_evmergehilo (void)
2837
{
2838
    T0_64 = (T0_64 & 0xFFFFFFFF00000000ULL) | (T1_64 & 0x00000000FFFFFFFFULL);
2839
    RETURN();
2840
}
2841

    
2842
void OPPROTO op_evcmpgts (void)
2843
{
2844
    do_evcmpgts();
2845
    RETURN();
2846
}
2847

    
2848
void OPPROTO op_evcmpgtu (void)
2849
{
2850
    do_evcmpgtu();
2851
    RETURN();
2852
}
2853

    
2854
void OPPROTO op_evcmplts (void)
2855
{
2856
    do_evcmplts();
2857
    RETURN();
2858
}
2859

    
2860
void OPPROTO op_evcmpltu (void)
2861
{
2862
    do_evcmpltu();
2863
    RETURN();
2864
}
2865

    
2866
void OPPROTO op_evcmpeq (void)
2867
{
2868
    do_evcmpeq();
2869
    RETURN();
2870
}
2871

    
2872
void OPPROTO op_evfssub (void)
2873
{
2874
    do_evfssub();
2875
    RETURN();
2876
}
2877

    
2878
void OPPROTO op_evfsadd (void)
2879
{
2880
    do_evfsadd();
2881
    RETURN();
2882
}
2883

    
2884
void OPPROTO op_evfsnabs (void)
2885
{
2886
    do_evfsnabs();
2887
    RETURN();
2888
}
2889

    
2890
void OPPROTO op_evfsabs (void)
2891
{
2892
    do_evfsabs();
2893
    RETURN();
2894
}
2895

    
2896
void OPPROTO op_evfsneg (void)
2897
{
2898
    do_evfsneg();
2899
    RETURN();
2900
}
2901

    
2902
void OPPROTO op_evfsdiv (void)
2903
{
2904
    do_evfsdiv();
2905
    RETURN();
2906
}
2907

    
2908
void OPPROTO op_evfsmul (void)
2909
{
2910
    do_evfsmul();
2911
    RETURN();
2912
}
2913

    
2914
void OPPROTO op_evfscmplt (void)
2915
{
2916
    do_evfscmplt();
2917
    RETURN();
2918
}
2919

    
2920
void OPPROTO op_evfscmpgt (void)
2921
{
2922
    do_evfscmpgt();
2923
    RETURN();
2924
}
2925

    
2926
void OPPROTO op_evfscmpeq (void)
2927
{
2928
    do_evfscmpeq();
2929
    RETURN();
2930
}
2931

    
2932
void OPPROTO op_evfscfsi (void)
2933
{
2934
    do_evfscfsi();
2935
    RETURN();
2936
}
2937

    
2938
void OPPROTO op_evfscfui (void)
2939
{
2940
    do_evfscfui();
2941
    RETURN();
2942
}
2943

    
2944
void OPPROTO op_evfscfsf (void)
2945
{
2946
    do_evfscfsf();
2947
    RETURN();
2948
}
2949

    
2950
void OPPROTO op_evfscfuf (void)
2951
{
2952
    do_evfscfuf();
2953
    RETURN();
2954
}
2955

    
2956
void OPPROTO op_evfsctsi (void)
2957
{
2958
    do_evfsctsi();
2959
    RETURN();
2960
}
2961

    
2962
void OPPROTO op_evfsctui (void)
2963
{
2964
    do_evfsctui();
2965
    RETURN();
2966
}
2967

    
2968
void OPPROTO op_evfsctsf (void)
2969
{
2970
    do_evfsctsf();
2971
    RETURN();
2972
}
2973

    
2974
void OPPROTO op_evfsctuf (void)
2975
{
2976
    do_evfsctuf();
2977
    RETURN();
2978
}
2979

    
2980
void OPPROTO op_evfsctuiz (void)
2981
{
2982
    do_evfsctuiz();
2983
    RETURN();
2984
}
2985

    
2986
void OPPROTO op_evfsctsiz (void)
2987
{
2988
    do_evfsctsiz();
2989
    RETURN();
2990
}
2991

    
2992
void OPPROTO op_evfststlt (void)
2993
{
2994
    do_evfststlt();
2995
    RETURN();
2996
}
2997

    
2998
void OPPROTO op_evfststgt (void)
2999
{
3000
    do_evfststgt();
3001
    RETURN();
3002
}
3003

    
3004
void OPPROTO op_evfststeq (void)
3005
{
3006
    do_evfststeq();
3007
    RETURN();
3008
}
3009

    
3010
void OPPROTO op_efssub (void)
3011
{
3012
    T0_64 = _do_efssub(T0_64, T1_64);
3013
    RETURN();
3014
}
3015

    
3016
void OPPROTO op_efsadd (void)
3017
{
3018
    T0_64 = _do_efsadd(T0_64, T1_64);
3019
    RETURN();
3020
}
3021

    
3022
void OPPROTO op_efsnabs (void)
3023
{
3024
    T0_64 = _do_efsnabs(T0_64);
3025
    RETURN();
3026
}
3027

    
3028
void OPPROTO op_efsabs (void)
3029
{
3030
    T0_64 = _do_efsabs(T0_64);
3031
    RETURN();
3032
}
3033

    
3034
void OPPROTO op_efsneg (void)
3035
{
3036
    T0_64 = _do_efsneg(T0_64);
3037
    RETURN();
3038
}
3039

    
3040
void OPPROTO op_efsdiv (void)
3041
{
3042
    T0_64 = _do_efsdiv(T0_64, T1_64);
3043
    RETURN();
3044
}
3045

    
3046
void OPPROTO op_efsmul (void)
3047
{
3048
    T0_64 = _do_efsmul(T0_64, T1_64);
3049
    RETURN();
3050
}
3051

    
3052
void OPPROTO op_efscmplt (void)
3053
{
3054
    do_efscmplt();
3055
    RETURN();
3056
}
3057

    
3058
void OPPROTO op_efscmpgt (void)
3059
{
3060
    do_efscmpgt();
3061
    RETURN();
3062
}
3063

    
3064
void OPPROTO op_efscfd (void)
3065
{
3066
    do_efscfd();
3067
    RETURN();
3068
}
3069

    
3070
void OPPROTO op_efscmpeq (void)
3071
{
3072
    do_efscmpeq();
3073
    RETURN();
3074
}
3075

    
3076
void OPPROTO op_efscfsi (void)
3077
{
3078
    do_efscfsi();
3079
    RETURN();
3080
}
3081

    
3082
void OPPROTO op_efscfui (void)
3083
{
3084
    do_efscfui();
3085
    RETURN();
3086
}
3087

    
3088
void OPPROTO op_efscfsf (void)
3089
{
3090
    do_efscfsf();
3091
    RETURN();
3092
}
3093

    
3094
void OPPROTO op_efscfuf (void)
3095
{
3096
    do_efscfuf();
3097
    RETURN();
3098
}
3099

    
3100
void OPPROTO op_efsctsi (void)
3101
{
3102
    do_efsctsi();
3103
    RETURN();
3104
}
3105

    
3106
void OPPROTO op_efsctui (void)
3107
{
3108
    do_efsctui();
3109
    RETURN();
3110
}
3111

    
3112
void OPPROTO op_efsctsf (void)
3113
{
3114
    do_efsctsf();
3115
    RETURN();
3116
}
3117

    
3118
void OPPROTO op_efsctuf (void)
3119
{
3120
    do_efsctuf();
3121
    RETURN();
3122
}
3123

    
3124
void OPPROTO op_efsctsiz (void)
3125
{
3126
    do_efsctsiz();
3127
    RETURN();
3128
}
3129

    
3130
void OPPROTO op_efsctuiz (void)
3131
{
3132
    do_efsctuiz();
3133
    RETURN();
3134
}
3135

    
3136
void OPPROTO op_efststlt (void)
3137
{
3138
    T0 = _do_efststlt(T0_64, T1_64);
3139
    RETURN();
3140
}
3141

    
3142
void OPPROTO op_efststgt (void)
3143
{
3144
    T0 = _do_efststgt(T0_64, T1_64);
3145
    RETURN();
3146
}
3147

    
3148
void OPPROTO op_efststeq (void)
3149
{
3150
    T0 = _do_efststeq(T0_64, T1_64);
3151
    RETURN();
3152
}
3153

    
3154
void OPPROTO op_efdsub (void)
3155
{
3156
    CPU_DoubleU u1, u2;
3157
    u1.ll = T0_64;
3158
    u2.ll = T1_64;
3159
    u1.d = float64_sub(u1.d, u2.d, &env->spe_status);
3160
    T0_64 = u1.ll;
3161
    RETURN();
3162
}
3163

    
3164
void OPPROTO op_efdadd (void)
3165
{
3166
    CPU_DoubleU u1, u2;
3167
    u1.ll = T0_64;
3168
    u2.ll = T1_64;
3169
    u1.d = float64_add(u1.d, u2.d, &env->spe_status);
3170
    T0_64 = u1.ll;
3171
    RETURN();
3172
}
3173

    
3174
void OPPROTO op_efdcfsid (void)
3175
{
3176
    do_efdcfsi();
3177
    RETURN();
3178
}
3179

    
3180
void OPPROTO op_efdcfuid (void)
3181
{
3182
    do_efdcfui();
3183
    RETURN();
3184
}
3185

    
3186
void OPPROTO op_efdnabs (void)
3187
{
3188
    T0_64 |= 0x8000000000000000ULL;
3189
    RETURN();
3190
}
3191

    
3192
void OPPROTO op_efdabs (void)
3193
{
3194
    T0_64 &= ~0x8000000000000000ULL;
3195
    RETURN();
3196
}
3197

    
3198
void OPPROTO op_efdneg (void)
3199
{
3200
    T0_64 ^= 0x8000000000000000ULL;
3201
    RETURN();
3202
}
3203

    
3204
void OPPROTO op_efddiv (void)
3205
{
3206
    CPU_DoubleU u1, u2;
3207
    u1.ll = T0_64;
3208
    u2.ll = T1_64;
3209
    u1.d = float64_div(u1.d, u2.d, &env->spe_status);
3210
    T0_64 = u1.ll;
3211
    RETURN();
3212
}
3213

    
3214
void OPPROTO op_efdmul (void)
3215
{
3216
    CPU_DoubleU u1, u2;
3217
    u1.ll = T0_64;
3218
    u2.ll = T1_64;
3219
    u1.d = float64_mul(u1.d, u2.d, &env->spe_status);
3220
    T0_64 = u1.ll;
3221
    RETURN();
3222
}
3223

    
3224
void OPPROTO op_efdctsidz (void)
3225
{
3226
    do_efdctsiz();
3227
    RETURN();
3228
}
3229

    
3230
void OPPROTO op_efdctuidz (void)
3231
{
3232
    do_efdctuiz();
3233
    RETURN();
3234
}
3235

    
3236
void OPPROTO op_efdcmplt (void)
3237
{
3238
    do_efdcmplt();
3239
    RETURN();
3240
}
3241

    
3242
void OPPROTO op_efdcmpgt (void)
3243
{
3244
    do_efdcmpgt();
3245
    RETURN();
3246
}
3247

    
3248
void OPPROTO op_efdcfs (void)
3249
{
3250
    do_efdcfs();
3251
    RETURN();
3252
}
3253

    
3254
void OPPROTO op_efdcmpeq (void)
3255
{
3256
    do_efdcmpeq();
3257
    RETURN();
3258
}
3259

    
3260
void OPPROTO op_efdcfsi (void)
3261
{
3262
    do_efdcfsi();
3263
    RETURN();
3264
}
3265

    
3266
void OPPROTO op_efdcfui (void)
3267
{
3268
    do_efdcfui();
3269
    RETURN();
3270
}
3271

    
3272
void OPPROTO op_efdcfsf (void)
3273
{
3274
    do_efdcfsf();
3275
    RETURN();
3276
}
3277

    
3278
void OPPROTO op_efdcfuf (void)
3279
{
3280
    do_efdcfuf();
3281
    RETURN();
3282
}
3283

    
3284
void OPPROTO op_efdctsi (void)
3285
{
3286
    do_efdctsi();
3287
    RETURN();
3288
}
3289

    
3290
void OPPROTO op_efdctui (void)
3291
{
3292
    do_efdctui();
3293
    RETURN();
3294
}
3295

    
3296
void OPPROTO op_efdctsf (void)
3297
{
3298
    do_efdctsf();
3299
    RETURN();
3300
}
3301

    
3302
void OPPROTO op_efdctuf (void)
3303
{
3304
    do_efdctuf();
3305
    RETURN();
3306
}
3307

    
3308
void OPPROTO op_efdctuiz (void)
3309
{
3310
    do_efdctuiz();
3311
    RETURN();
3312
}
3313

    
3314
void OPPROTO op_efdctsiz (void)
3315
{
3316
    do_efdctsiz();
3317
    RETURN();
3318
}
3319

    
3320
void OPPROTO op_efdtstlt (void)
3321
{
3322
    T0 = _do_efdtstlt(T0_64, T1_64);
3323
    RETURN();
3324
}
3325

    
3326
void OPPROTO op_efdtstgt (void)
3327
{
3328
    T0 = _do_efdtstgt(T0_64, T1_64);
3329
    RETURN();
3330
}
3331

    
3332
void OPPROTO op_efdtsteq (void)
3333
{
3334
    T0 = _do_efdtsteq(T0_64, T1_64);
3335
    RETURN();
3336
}