Statistics
| Branch: | Revision:

root / target-ppc / op.c @ 61c04807

History | View | Annotate | Download (48.7 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
/* PowerPC state maintenance operations */
126
/* set_Rc0 */
127
void OPPROTO op_set_Rc0 (void)
128
{
129
    env->crf[0] = T0 | xer_so;
130
    RETURN();
131
}
132

    
133
void OPPROTO op_set_T0 (void)
134
{
135
    T0 = (uint32_t)PARAM1;
136
    RETURN();
137
}
138

    
139
#if defined(TARGET_PPC64)
140
void OPPROTO op_set_T0_64 (void)
141
{
142
    T0 = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
143
    RETURN();
144
}
145
#endif
146

    
147
void OPPROTO op_set_T1 (void)
148
{
149
    T1 = (uint32_t)PARAM1;
150
    RETURN();
151
}
152

    
153
#if defined(TARGET_PPC64)
154
void OPPROTO op_set_T1_64 (void)
155
{
156
    T1 = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
157
    RETURN();
158
}
159
#endif
160

    
161
#if 0 // unused
162
void OPPROTO op_set_T2 (void)
163
{
164
    T2 = (uint32_t)PARAM1;
165
    RETURN();
166
}
167
#endif
168

    
169
void OPPROTO op_move_T1_T0 (void)
170
{
171
    T1 = T0;
172
    RETURN();
173
}
174

    
175
void OPPROTO op_move_T2_T0 (void)
176
{
177
    T2 = T0;
178
    RETURN();
179
}
180

    
181
void OPPROTO op_moven_T2_T0 (void)
182
{
183
    T2 = ~T0;
184
    RETURN();
185
}
186

    
187
/* Generate exceptions */
188
void OPPROTO op_raise_exception_err (void)
189
{
190
    do_raise_exception_err(PARAM1, PARAM2);
191
}
192

    
193
void OPPROTO op_debug (void)
194
{
195
    do_raise_exception(EXCP_DEBUG);
196
}
197

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
303
void OPPROTO op_update_riee (void)
304
{
305
    /* We don't call do_store_msr here as we won't trigger
306
     * any special case nor change hflags
307
     */
308
    T0 &= (1 << MSR_RI) | (1 << MSR_EE);
309
    env->msr &= ~(1 << MSR_RI) | (1 << MSR_EE);
310
    env->msr |= T0;
311
    RETURN();
312
}
313
#endif
314

    
315
/* SPR */
316
void OPPROTO op_load_spr (void)
317
{
318
    T0 = env->spr[PARAM1];
319
    RETURN();
320
}
321

    
322
void OPPROTO op_store_spr (void)
323
{
324
    env->spr[PARAM1] = T0;
325
    RETURN();
326
}
327

    
328
void OPPROTO op_load_dump_spr (void)
329
{
330
    T0 = ppc_load_dump_spr(PARAM1);
331
    RETURN();
332
}
333

    
334
void OPPROTO op_store_dump_spr (void)
335
{
336
    ppc_store_dump_spr(PARAM1, T0);
337
    RETURN();
338
}
339

    
340
void OPPROTO op_mask_spr (void)
341
{
342
    env->spr[PARAM1] &= ~T0;
343
    RETURN();
344
}
345

    
346
void OPPROTO op_load_lr (void)
347
{
348
    T0 = env->lr;
349
    RETURN();
350
}
351

    
352
void OPPROTO op_store_lr (void)
353
{
354
    env->lr = T0;
355
    RETURN();
356
}
357

    
358
void OPPROTO op_load_ctr (void)
359
{
360
    T0 = env->ctr;
361
    RETURN();
362
}
363

    
364
void OPPROTO op_store_ctr (void)
365
{
366
    env->ctr = T0;
367
    RETURN();
368
}
369

    
370
void OPPROTO op_load_tbl (void)
371
{
372
    T0 = cpu_ppc_load_tbl(env);
373
    RETURN();
374
}
375

    
376
void OPPROTO op_load_tbu (void)
377
{
378
    T0 = cpu_ppc_load_tbu(env);
379
    RETURN();
380
}
381

    
382
void OPPROTO op_load_atbl (void)
383
{
384
    T0 = cpu_ppc_load_atbl(env);
385
    RETURN();
386
}
387

    
388
void OPPROTO op_load_atbu (void)
389
{
390
    T0 = cpu_ppc_load_atbu(env);
391
    RETURN();
392
}
393

    
394
#if !defined(CONFIG_USER_ONLY)
395
void OPPROTO op_store_tbl (void)
396
{
397
    cpu_ppc_store_tbl(env, T0);
398
    RETURN();
399
}
400

    
401
void OPPROTO op_store_tbu (void)
402
{
403
    cpu_ppc_store_tbu(env, T0);
404
    RETURN();
405
}
406

    
407
void OPPROTO op_store_atbl (void)
408
{
409
    cpu_ppc_store_atbl(env, T0);
410
    RETURN();
411
}
412

    
413
void OPPROTO op_store_atbu (void)
414
{
415
    cpu_ppc_store_atbu(env, T0);
416
    RETURN();
417
}
418

    
419
void OPPROTO op_load_decr (void)
420
{
421
    T0 = cpu_ppc_load_decr(env);
422
    RETURN();
423
}
424

    
425
void OPPROTO op_store_decr (void)
426
{
427
    cpu_ppc_store_decr(env, T0);
428
    RETURN();
429
}
430

    
431
void OPPROTO op_load_ibat (void)
432
{
433
    T0 = env->IBAT[PARAM1][PARAM2];
434
    RETURN();
435
}
436

    
437
void OPPROTO op_store_ibatu (void)
438
{
439
    do_store_ibatu(env, PARAM1, T0);
440
    RETURN();
441
}
442

    
443
void OPPROTO op_store_ibatl (void)
444
{
445
#if 1
446
    env->IBAT[1][PARAM1] = T0;
447
#else
448
    do_store_ibatl(env, PARAM1, T0);
449
#endif
450
    RETURN();
451
}
452

    
453
void OPPROTO op_load_dbat (void)
454
{
455
    T0 = env->DBAT[PARAM1][PARAM2];
456
    RETURN();
457
}
458

    
459
void OPPROTO op_store_dbatu (void)
460
{
461
    do_store_dbatu(env, PARAM1, T0);
462
    RETURN();
463
}
464

    
465
void OPPROTO op_store_dbatl (void)
466
{
467
#if 1
468
    env->DBAT[1][PARAM1] = T0;
469
#else
470
    do_store_dbatl(env, PARAM1, T0);
471
#endif
472
    RETURN();
473
}
474
#endif /* !defined(CONFIG_USER_ONLY) */
475

    
476
/* FPSCR */
477
#ifdef CONFIG_SOFTFLOAT
478
void OPPROTO op_reset_fpstatus (void)
479
{
480
    env->fp_status.float_exception_flags = 0;
481
    RETURN();
482
}
483
#endif
484

    
485
void OPPROTO op_compute_fprf (void)
486
{
487
    do_compute_fprf(PARAM1);
488
    RETURN();
489
}
490

    
491
#ifdef CONFIG_SOFTFLOAT
492
void OPPROTO op_float_check_status (void)
493
{
494
    do_float_check_status();
495
    RETURN();
496
}
497
#else
498
void OPPROTO op_float_check_status (void)
499
{
500
    if (env->exception_index == POWERPC_EXCP_PROGRAM &&
501
        (env->error_code & POWERPC_EXCP_FP)) {
502
        /* Differred floating-point exception after target FPR update */
503
        if (msr_fe0 != 0 || msr_fe1 != 0)
504
            do_raise_exception_err(env->exception_index, env->error_code);
505
    }
506
    RETURN();
507
}
508
#endif
509

    
510
void OPPROTO op_load_fpscr_FT0 (void)
511
{
512
    /* The 32 MSB of the target fpr are undefined.
513
     * They'll be zero...
514
     */
515
    CPU_DoubleU u;
516

    
517
    u.l.upper = 0;
518
    u.l.lower = env->fpscr;
519
    FT0 = u.d;
520
    RETURN();
521
}
522

    
523
void OPPROTO op_set_FT0 (void)
524
{
525
    CPU_DoubleU u;
526

    
527
    u.l.upper = 0;
528
    u.l.lower = PARAM1;
529
    FT0 = u.d;
530
    RETURN();
531
}
532

    
533
void OPPROTO op_load_fpscr_T0 (void)
534
{
535
    T0 = (env->fpscr >> PARAM1) & 0xF;
536
    RETURN();
537
}
538

    
539
void OPPROTO op_load_fpcc (void)
540
{
541
    T0 = fpscr_fpcc;
542
    RETURN();
543
}
544

    
545
void OPPROTO op_fpscr_resetbit (void)
546
{
547
    env->fpscr &= PARAM1;
548
    RETURN();
549
}
550

    
551
void OPPROTO op_fpscr_setbit (void)
552
{
553
    do_fpscr_setbit(PARAM1);
554
    RETURN();
555
}
556

    
557
void OPPROTO op_store_fpscr (void)
558
{
559
    do_store_fpscr(PARAM1);
560
    RETURN();
561
}
562

    
563
/* Branch */
564
#define EIP env->nip
565

    
566
void OPPROTO op_setlr (void)
567
{
568
    env->lr = (uint32_t)PARAM1;
569
    RETURN();
570
}
571

    
572
#if defined (TARGET_PPC64)
573
void OPPROTO op_setlr_64 (void)
574
{
575
    env->lr = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
576
    RETURN();
577
}
578
#endif
579

    
580
void OPPROTO op_b_T1 (void)
581
{
582
    env->nip = (uint32_t)(T1 & ~3);
583
    RETURN();
584
}
585

    
586
#if defined (TARGET_PPC64)
587
void OPPROTO op_b_T1_64 (void)
588
{
589
    env->nip = (uint64_t)(T1 & ~3);
590
    RETURN();
591
}
592
#endif
593

    
594
void OPPROTO op_jz_T0 (void)
595
{
596
    if (!T0)
597
        GOTO_LABEL_PARAM(1);
598
    RETURN();
599
}
600

    
601
void OPPROTO op_btest_T1 (void)
602
{
603
    if (T0) {
604
        env->nip = (uint32_t)(T1 & ~3);
605
    } else {
606
        env->nip = (uint32_t)PARAM1;
607
    }
608
    RETURN();
609
}
610

    
611
#if defined (TARGET_PPC64)
612
void OPPROTO op_btest_T1_64 (void)
613
{
614
    if (T0) {
615
        env->nip = (uint64_t)(T1 & ~3);
616
    } else {
617
        env->nip = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
618
    }
619
    RETURN();
620
}
621
#endif
622

    
623
void OPPROTO op_movl_T1_ctr (void)
624
{
625
    T1 = env->ctr;
626
    RETURN();
627
}
628

    
629
void OPPROTO op_movl_T1_lr (void)
630
{
631
    T1 = env->lr;
632
    RETURN();
633
}
634

    
635
/* tests with result in T0 */
636
void OPPROTO op_test_ctr (void)
637
{
638
    T0 = (uint32_t)env->ctr;
639
    RETURN();
640
}
641

    
642
#if defined(TARGET_PPC64)
643
void OPPROTO op_test_ctr_64 (void)
644
{
645
    T0 = (uint64_t)env->ctr;
646
    RETURN();
647
}
648
#endif
649

    
650
void OPPROTO op_test_ctr_true (void)
651
{
652
    T0 = ((uint32_t)env->ctr != 0 && (T0 & PARAM1) != 0);
653
    RETURN();
654
}
655

    
656
#if defined(TARGET_PPC64)
657
void OPPROTO op_test_ctr_true_64 (void)
658
{
659
    T0 = ((uint64_t)env->ctr != 0 && (T0 & PARAM1) != 0);
660
    RETURN();
661
}
662
#endif
663

    
664
void OPPROTO op_test_ctr_false (void)
665
{
666
    T0 = ((uint32_t)env->ctr != 0 && (T0 & PARAM1) == 0);
667
    RETURN();
668
}
669

    
670
#if defined(TARGET_PPC64)
671
void OPPROTO op_test_ctr_false_64 (void)
672
{
673
    T0 = ((uint64_t)env->ctr != 0 && (T0 & PARAM1) == 0);
674
    RETURN();
675
}
676
#endif
677

    
678
void OPPROTO op_test_ctrz (void)
679
{
680
    T0 = ((uint32_t)env->ctr == 0);
681
    RETURN();
682
}
683

    
684
#if defined(TARGET_PPC64)
685
void OPPROTO op_test_ctrz_64 (void)
686
{
687
    T0 = ((uint64_t)env->ctr == 0);
688
    RETURN();
689
}
690
#endif
691

    
692
void OPPROTO op_test_ctrz_true (void)
693
{
694
    T0 = ((uint32_t)env->ctr == 0 && (T0 & PARAM1) != 0);
695
    RETURN();
696
}
697

    
698
#if defined(TARGET_PPC64)
699
void OPPROTO op_test_ctrz_true_64 (void)
700
{
701
    T0 = ((uint64_t)env->ctr == 0 && (T0 & PARAM1) != 0);
702
    RETURN();
703
}
704
#endif
705

    
706
void OPPROTO op_test_ctrz_false (void)
707
{
708
    T0 = ((uint32_t)env->ctr == 0 && (T0 & PARAM1) == 0);
709
    RETURN();
710
}
711

    
712
#if defined(TARGET_PPC64)
713
void OPPROTO op_test_ctrz_false_64 (void)
714
{
715
    T0 = ((uint64_t)env->ctr == 0 && (T0 & PARAM1) == 0);
716
    RETURN();
717
}
718
#endif
719

    
720
void OPPROTO op_test_true (void)
721
{
722
    T0 = (T0 & PARAM1);
723
    RETURN();
724
}
725

    
726
void OPPROTO op_test_false (void)
727
{
728
    T0 = ((T0 & PARAM1) == 0);
729
    RETURN();
730
}
731

    
732
/* CTR maintenance */
733
void OPPROTO op_dec_ctr (void)
734
{
735
    env->ctr--;
736
    RETURN();
737
}
738

    
739
/***                           Integer arithmetic                          ***/
740
/* add */
741
void OPPROTO op_add (void)
742
{
743
    T0 += T1;
744
    RETURN();
745
}
746

    
747
void OPPROTO op_check_addo (void)
748
{
749
    xer_ov = (((uint32_t)T2 ^ (uint32_t)T1 ^ UINT32_MAX) &
750
              ((uint32_t)T2 ^ (uint32_t)T0)) >> 31;
751
    xer_so |= xer_ov;
752
    RETURN();
753
}
754

    
755
#if defined(TARGET_PPC64)
756
void OPPROTO op_check_addo_64 (void)
757
{
758
    xer_ov = (((uint64_t)T2 ^ (uint64_t)T1 ^ UINT64_MAX) &
759
              ((uint64_t)T2 ^ (uint64_t)T0)) >> 63;
760
    xer_so |= xer_ov;
761
    RETURN();
762
}
763
#endif
764

    
765
/* add carrying */
766
void OPPROTO op_check_addc (void)
767
{
768
    if (likely((uint32_t)T0 >= (uint32_t)T2)) {
769
        xer_ca = 0;
770
    } else {
771
        xer_ca = 1;
772
    }
773
    RETURN();
774
}
775

    
776
#if defined(TARGET_PPC64)
777
void OPPROTO op_check_addc_64 (void)
778
{
779
    if (likely((uint64_t)T0 >= (uint64_t)T2)) {
780
        xer_ca = 0;
781
    } else {
782
        xer_ca = 1;
783
    }
784
    RETURN();
785
}
786
#endif
787

    
788
/* add extended */
789
void OPPROTO op_adde (void)
790
{
791
    do_adde();
792
    RETURN();
793
}
794

    
795
#if defined(TARGET_PPC64)
796
void OPPROTO op_adde_64 (void)
797
{
798
    do_adde_64();
799
    RETURN();
800
}
801
#endif
802

    
803
/* add immediate */
804
void OPPROTO op_addi (void)
805
{
806
    T0 += (int32_t)PARAM1;
807
    RETURN();
808
}
809

    
810
/* add to minus one extended */
811
void OPPROTO op_add_me (void)
812
{
813
    T0 += xer_ca + (-1);
814
    if (likely((uint32_t)T1 != 0))
815
        xer_ca = 1;
816
    else
817
        xer_ca = 0;
818
    RETURN();
819
}
820

    
821
#if defined(TARGET_PPC64)
822
void OPPROTO op_add_me_64 (void)
823
{
824
    T0 += xer_ca + (-1);
825
    if (likely((uint64_t)T1 != 0))
826
        xer_ca = 1;
827
    else
828
        xer_ca = 0;
829
    RETURN();
830
}
831
#endif
832

    
833
void OPPROTO op_addmeo (void)
834
{
835
    do_addmeo();
836
    RETURN();
837
}
838

    
839
void OPPROTO op_addmeo_64 (void)
840
{
841
    do_addmeo();
842
    RETURN();
843
}
844

    
845
/* add to zero extended */
846
void OPPROTO op_add_ze (void)
847
{
848
    T0 += xer_ca;
849
    RETURN();
850
}
851

    
852
/* divide word */
853
void OPPROTO op_divw (void)
854
{
855
    if (unlikely(((int32_t)T0 == INT32_MIN && (int32_t)T1 == (int32_t)-1) ||
856
                 (int32_t)T1 == 0)) {
857
        T0 = (int32_t)(UINT32_MAX * ((uint32_t)T0 >> 31));
858
    } else {
859
        T0 = (int32_t)T0 / (int32_t)T1;
860
    }
861
    RETURN();
862
}
863

    
864
#if defined(TARGET_PPC64)
865
void OPPROTO op_divd (void)
866
{
867
    if (unlikely(((int64_t)T0 == INT64_MIN && (int64_t)T1 == (int64_t)-1LL) ||
868
                 (int64_t)T1 == 0)) {
869
        T0 = (int64_t)(UINT64_MAX * ((uint64_t)T0 >> 63));
870
    } else {
871
        T0 = (int64_t)T0 / (int64_t)T1;
872
    }
873
    RETURN();
874
}
875
#endif
876

    
877
void OPPROTO op_divwo (void)
878
{
879
    do_divwo();
880
    RETURN();
881
}
882

    
883
#if defined(TARGET_PPC64)
884
void OPPROTO op_divdo (void)
885
{
886
    do_divdo();
887
    RETURN();
888
}
889
#endif
890

    
891
/* divide word unsigned */
892
void OPPROTO op_divwu (void)
893
{
894
    if (unlikely(T1 == 0)) {
895
        T0 = 0;
896
    } else {
897
        T0 = (uint32_t)T0 / (uint32_t)T1;
898
    }
899
    RETURN();
900
}
901

    
902
#if defined(TARGET_PPC64)
903
void OPPROTO op_divdu (void)
904
{
905
    if (unlikely(T1 == 0)) {
906
        T0 = 0;
907
    } else {
908
        T0 /= T1;
909
    }
910
    RETURN();
911
}
912
#endif
913

    
914
void OPPROTO op_divwuo (void)
915
{
916
    do_divwuo();
917
    RETURN();
918
}
919

    
920
#if defined(TARGET_PPC64)
921
void OPPROTO op_divduo (void)
922
{
923
    do_divduo();
924
    RETURN();
925
}
926
#endif
927

    
928
/* multiply high word */
929
void OPPROTO op_mulhw (void)
930
{
931
    T0 = ((int64_t)((int32_t)T0) * (int64_t)((int32_t)T1)) >> 32;
932
    RETURN();
933
}
934

    
935
#if defined(TARGET_PPC64)
936
void OPPROTO op_mulhd (void)
937
{
938
    uint64_t tl, th;
939

    
940
    muls64(&tl, &th, T0, T1);
941
    T0 = th;
942
    RETURN();
943
}
944
#endif
945

    
946
/* multiply high word unsigned */
947
void OPPROTO op_mulhwu (void)
948
{
949
    T0 = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1) >> 32;
950
    RETURN();
951
}
952

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

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

    
964
/* multiply low immediate */
965
void OPPROTO op_mulli (void)
966
{
967
    T0 = ((int32_t)T0 * (int32_t)PARAM1);
968
    RETURN();
969
}
970

    
971
/* multiply low word */
972
void OPPROTO op_mullw (void)
973
{
974
    T0 = (int32_t)(T0 * T1);
975
    RETURN();
976
}
977

    
978
#if defined(TARGET_PPC64)
979
void OPPROTO op_mulld (void)
980
{
981
    T0 *= T1;
982
    RETURN();
983
}
984
#endif
985

    
986
void OPPROTO op_mullwo (void)
987
{
988
    do_mullwo();
989
    RETURN();
990
}
991

    
992
#if defined(TARGET_PPC64)
993
void OPPROTO op_mulldo (void)
994
{
995
    do_mulldo();
996
    RETURN();
997
}
998
#endif
999

    
1000
/* negate */
1001
void OPPROTO op_neg (void)
1002
{
1003
    if (likely(T0 != INT32_MIN)) {
1004
        T0 = -(int32_t)T0;
1005
    }
1006
    RETURN();
1007
}
1008

    
1009
#if defined(TARGET_PPC64)
1010
void OPPROTO op_neg_64 (void)
1011
{
1012
    if (likely(T0 != INT64_MIN)) {
1013
        T0 = -(int64_t)T0;
1014
    }
1015
    RETURN();
1016
}
1017
#endif
1018

    
1019
void OPPROTO op_nego (void)
1020
{
1021
    do_nego();
1022
    RETURN();
1023
}
1024

    
1025
#if defined(TARGET_PPC64)
1026
void OPPROTO op_nego_64 (void)
1027
{
1028
    do_nego_64();
1029
    RETURN();
1030
}
1031
#endif
1032

    
1033
/* subtract from */
1034
void OPPROTO op_subf (void)
1035
{
1036
    T0 = T1 - T0;
1037
    RETURN();
1038
}
1039

    
1040
/* subtract from carrying */
1041
void OPPROTO op_check_subfc (void)
1042
{
1043
    if (likely((uint32_t)T0 > (uint32_t)T1)) {
1044
        xer_ca = 0;
1045
    } else {
1046
        xer_ca = 1;
1047
    }
1048
    RETURN();
1049
}
1050

    
1051
#if defined(TARGET_PPC64)
1052
void OPPROTO op_check_subfc_64 (void)
1053
{
1054
    if (likely((uint64_t)T0 > (uint64_t)T1)) {
1055
        xer_ca = 0;
1056
    } else {
1057
        xer_ca = 1;
1058
    }
1059
    RETURN();
1060
}
1061
#endif
1062

    
1063
/* subtract from extended */
1064
void OPPROTO op_subfe (void)
1065
{
1066
    do_subfe();
1067
    RETURN();
1068
}
1069

    
1070
#if defined(TARGET_PPC64)
1071
void OPPROTO op_subfe_64 (void)
1072
{
1073
    do_subfe_64();
1074
    RETURN();
1075
}
1076
#endif
1077

    
1078
/* subtract from immediate carrying */
1079
void OPPROTO op_subfic (void)
1080
{
1081
    T0 = (int32_t)PARAM1 + ~T0 + 1;
1082
    if ((uint32_t)T0 <= (uint32_t)PARAM1) {
1083
        xer_ca = 1;
1084
    } else {
1085
        xer_ca = 0;
1086
    }
1087
    RETURN();
1088
}
1089

    
1090
#if defined(TARGET_PPC64)
1091
void OPPROTO op_subfic_64 (void)
1092
{
1093
    T0 = (int64_t)PARAM1 + ~T0 + 1;
1094
    if ((uint64_t)T0 <= (uint64_t)PARAM1) {
1095
        xer_ca = 1;
1096
    } else {
1097
        xer_ca = 0;
1098
    }
1099
    RETURN();
1100
}
1101
#endif
1102

    
1103
/* subtract from minus one extended */
1104
void OPPROTO op_subfme (void)
1105
{
1106
    T0 = ~T0 + xer_ca - 1;
1107
    if (likely((uint32_t)T0 != UINT32_MAX))
1108
        xer_ca = 1;
1109
    else
1110
        xer_ca = 0;
1111
    RETURN();
1112
}
1113

    
1114
#if defined(TARGET_PPC64)
1115
void OPPROTO op_subfme_64 (void)
1116
{
1117
    T0 = ~T0 + xer_ca - 1;
1118
    if (likely((uint64_t)T0 != UINT64_MAX))
1119
        xer_ca = 1;
1120
    else
1121
        xer_ca = 0;
1122
    RETURN();
1123
}
1124
#endif
1125

    
1126
void OPPROTO op_subfmeo (void)
1127
{
1128
    do_subfmeo();
1129
    RETURN();
1130
}
1131

    
1132
#if defined(TARGET_PPC64)
1133
void OPPROTO op_subfmeo_64 (void)
1134
{
1135
    do_subfmeo_64();
1136
    RETURN();
1137
}
1138
#endif
1139

    
1140
/* subtract from zero extended */
1141
void OPPROTO op_subfze (void)
1142
{
1143
    T1 = ~T0;
1144
    T0 = T1 + xer_ca;
1145
    if ((uint32_t)T0 < (uint32_t)T1) {
1146
        xer_ca = 1;
1147
    } else {
1148
        xer_ca = 0;
1149
    }
1150
    RETURN();
1151
}
1152

    
1153
#if defined(TARGET_PPC64)
1154
void OPPROTO op_subfze_64 (void)
1155
{
1156
    T1 = ~T0;
1157
    T0 = T1 + xer_ca;
1158
    if ((uint64_t)T0 < (uint64_t)T1) {
1159
        xer_ca = 1;
1160
    } else {
1161
        xer_ca = 0;
1162
    }
1163
    RETURN();
1164
}
1165
#endif
1166

    
1167
void OPPROTO op_subfzeo (void)
1168
{
1169
    do_subfzeo();
1170
    RETURN();
1171
}
1172

    
1173
#if defined(TARGET_PPC64)
1174
void OPPROTO op_subfzeo_64 (void)
1175
{
1176
    do_subfzeo_64();
1177
    RETURN();
1178
}
1179
#endif
1180

    
1181
/***                           Integer comparison                          ***/
1182
/* compare */
1183
void OPPROTO op_cmp (void)
1184
{
1185
    if ((int32_t)T0 < (int32_t)T1) {
1186
        T0 = 0x08;
1187
    } else if ((int32_t)T0 > (int32_t)T1) {
1188
        T0 = 0x04;
1189
    } else {
1190
        T0 = 0x02;
1191
    }
1192
    T0 |= xer_so;
1193
    RETURN();
1194
}
1195

    
1196
#if defined(TARGET_PPC64)
1197
void OPPROTO op_cmp_64 (void)
1198
{
1199
    if ((int64_t)T0 < (int64_t)T1) {
1200
        T0 = 0x08;
1201
    } else if ((int64_t)T0 > (int64_t)T1) {
1202
        T0 = 0x04;
1203
    } else {
1204
        T0 = 0x02;
1205
    }
1206
    T0 |= xer_so;
1207
    RETURN();
1208
}
1209
#endif
1210

    
1211
/* compare immediate */
1212
void OPPROTO op_cmpi (void)
1213
{
1214
    if ((int32_t)T0 < (int32_t)PARAM1) {
1215
        T0 = 0x08;
1216
    } else if ((int32_t)T0 > (int32_t)PARAM1) {
1217
        T0 = 0x04;
1218
    } else {
1219
        T0 = 0x02;
1220
    }
1221
    T0 |= xer_so;
1222
    RETURN();
1223
}
1224

    
1225
#if defined(TARGET_PPC64)
1226
void OPPROTO op_cmpi_64 (void)
1227
{
1228
    if ((int64_t)T0 < (int64_t)((int32_t)PARAM1)) {
1229
        T0 = 0x08;
1230
    } else if ((int64_t)T0 > (int64_t)((int32_t)PARAM1)) {
1231
        T0 = 0x04;
1232
    } else {
1233
        T0 = 0x02;
1234
    }
1235
    T0 |= xer_so;
1236
    RETURN();
1237
}
1238
#endif
1239

    
1240
/* compare logical */
1241
void OPPROTO op_cmpl (void)
1242
{
1243
    if ((uint32_t)T0 < (uint32_t)T1) {
1244
        T0 = 0x08;
1245
    } else if ((uint32_t)T0 > (uint32_t)T1) {
1246
        T0 = 0x04;
1247
    } else {
1248
        T0 = 0x02;
1249
    }
1250
    T0 |= xer_so;
1251
    RETURN();
1252
}
1253

    
1254
#if defined(TARGET_PPC64)
1255
void OPPROTO op_cmpl_64 (void)
1256
{
1257
    if ((uint64_t)T0 < (uint64_t)T1) {
1258
        T0 = 0x08;
1259
    } else if ((uint64_t)T0 > (uint64_t)T1) {
1260
        T0 = 0x04;
1261
    } else {
1262
        T0 = 0x02;
1263
    }
1264
    T0 |= xer_so;
1265
    RETURN();
1266
}
1267
#endif
1268

    
1269
/* compare logical immediate */
1270
void OPPROTO op_cmpli (void)
1271
{
1272
    if ((uint32_t)T0 < (uint32_t)PARAM1) {
1273
        T0 = 0x08;
1274
    } else if ((uint32_t)T0 > (uint32_t)PARAM1) {
1275
        T0 = 0x04;
1276
    } else {
1277
        T0 = 0x02;
1278
    }
1279
    T0 |= xer_so;
1280
    RETURN();
1281
}
1282

    
1283
#if defined(TARGET_PPC64)
1284
void OPPROTO op_cmpli_64 (void)
1285
{
1286
    if ((uint64_t)T0 < (uint64_t)PARAM1) {
1287
        T0 = 0x08;
1288
    } else if ((uint64_t)T0 > (uint64_t)PARAM1) {
1289
        T0 = 0x04;
1290
    } else {
1291
        T0 = 0x02;
1292
    }
1293
    T0 |= xer_so;
1294
    RETURN();
1295
}
1296
#endif
1297

    
1298
void OPPROTO op_isel (void)
1299
{
1300
    if (T0)
1301
        T0 = T1;
1302
    else
1303
        T0 = T2;
1304
    RETURN();
1305
}
1306

    
1307
/***                            Integer logical                            ***/
1308
/* and */
1309
void OPPROTO op_and (void)
1310
{
1311
    T0 &= T1;
1312
    RETURN();
1313
}
1314

    
1315
/* andc */
1316
void OPPROTO op_andc (void)
1317
{
1318
    T0 &= ~T1;
1319
    RETURN();
1320
}
1321

    
1322
/* andi. */
1323
void OPPROTO op_andi_T0 (void)
1324
{
1325
    T0 &= (uint32_t)PARAM1;
1326
    RETURN();
1327
}
1328

    
1329
void OPPROTO op_andi_T1 (void)
1330
{
1331
    T1 &= (uint32_t)PARAM1;
1332
    RETURN();
1333
}
1334

    
1335
#if defined(TARGET_PPC64)
1336
void OPPROTO op_andi_T0_64 (void)
1337
{
1338
    T0 &= ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
1339
    RETURN();
1340
}
1341

    
1342
void OPPROTO op_andi_T1_64 (void)
1343
{
1344
    T1 &= ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
1345
    RETURN();
1346
}
1347
#endif
1348

    
1349
/* count leading zero */
1350
void OPPROTO op_cntlzw (void)
1351
{
1352
    do_cntlzw();
1353
    RETURN();
1354
}
1355

    
1356
#if defined(TARGET_PPC64)
1357
void OPPROTO op_cntlzd (void)
1358
{
1359
    do_cntlzd();
1360
    RETURN();
1361
}
1362
#endif
1363

    
1364
/* eqv */
1365
void OPPROTO op_eqv (void)
1366
{
1367
    T0 = ~(T0 ^ T1);
1368
    RETURN();
1369
}
1370

    
1371
/* extend sign byte */
1372
void OPPROTO op_extsb (void)
1373
{
1374
#if defined (TARGET_PPC64)
1375
    T0 = (int64_t)((int8_t)T0);
1376
#else
1377
    T0 = (int32_t)((int8_t)T0);
1378
#endif
1379
    RETURN();
1380
}
1381

    
1382
/* extend sign half word */
1383
void OPPROTO op_extsh (void)
1384
{
1385
#if defined (TARGET_PPC64)
1386
    T0 = (int64_t)((int16_t)T0);
1387
#else
1388
    T0 = (int32_t)((int16_t)T0);
1389
#endif
1390
    RETURN();
1391
}
1392

    
1393
#if defined (TARGET_PPC64)
1394
void OPPROTO op_extsw (void)
1395
{
1396
    T0 = (int64_t)((int32_t)T0);
1397
    RETURN();
1398
}
1399
#endif
1400

    
1401
/* nand */
1402
void OPPROTO op_nand (void)
1403
{
1404
    T0 = ~(T0 & T1);
1405
    RETURN();
1406
}
1407

    
1408
/* nor */
1409
void OPPROTO op_nor (void)
1410
{
1411
    T0 = ~(T0 | T1);
1412
    RETURN();
1413
}
1414

    
1415
/* or */
1416
void OPPROTO op_or (void)
1417
{
1418
    T0 |= T1;
1419
    RETURN();
1420
}
1421

    
1422
/* orc */
1423
void OPPROTO op_orc (void)
1424
{
1425
    T0 |= ~T1;
1426
    RETURN();
1427
}
1428

    
1429
/* ori */
1430
void OPPROTO op_ori (void)
1431
{
1432
    T0 |= (uint32_t)PARAM1;
1433
    RETURN();
1434
}
1435

    
1436
/* xor */
1437
void OPPROTO op_xor (void)
1438
{
1439
    T0 ^= T1;
1440
    RETURN();
1441
}
1442

    
1443
/* xori */
1444
void OPPROTO op_xori (void)
1445
{
1446
    T0 ^= (uint32_t)PARAM1;
1447
    RETURN();
1448
}
1449

    
1450
/***                             Integer rotate                            ***/
1451
void OPPROTO op_rotl32_T0_T1 (void)
1452
{
1453
    T0 = rotl32(T0, T1 & 0x1F);
1454
    RETURN();
1455
}
1456

    
1457
void OPPROTO op_rotli32_T0 (void)
1458
{
1459
    T0 = rotl32(T0, PARAM1);
1460
    RETURN();
1461
}
1462

    
1463
#if defined(TARGET_PPC64)
1464
void OPPROTO op_rotl64_T0_T1 (void)
1465
{
1466
    T0 = rotl64(T0, T1 & 0x3F);
1467
    RETURN();
1468
}
1469

    
1470
void OPPROTO op_rotli64_T0 (void)
1471
{
1472
    T0 = rotl64(T0, PARAM1);
1473
    RETURN();
1474
}
1475
#endif
1476

    
1477
/***                             Integer shift                             ***/
1478
/* shift left word */
1479
void OPPROTO op_slw (void)
1480
{
1481
    if (T1 & 0x20) {
1482
        T0 = 0;
1483
    } else {
1484
        T0 = (uint32_t)(T0 << T1);
1485
    }
1486
    RETURN();
1487
}
1488

    
1489
#if defined(TARGET_PPC64)
1490
void OPPROTO op_sld (void)
1491
{
1492
    if (T1 & 0x40) {
1493
        T0 = 0;
1494
    } else {
1495
        T0 = T0 << T1;
1496
    }
1497
    RETURN();
1498
}
1499
#endif
1500

    
1501
/* shift right algebraic word */
1502
void OPPROTO op_sraw (void)
1503
{
1504
    do_sraw();
1505
    RETURN();
1506
}
1507

    
1508
#if defined(TARGET_PPC64)
1509
void OPPROTO op_srad (void)
1510
{
1511
    do_srad();
1512
    RETURN();
1513
}
1514
#endif
1515

    
1516
/* shift right algebraic word immediate */
1517
void OPPROTO op_srawi (void)
1518
{
1519
    uint32_t mask = (uint32_t)PARAM2;
1520

    
1521
    T0 = (int32_t)T0 >> PARAM1;
1522
    if ((int32_t)T1 < 0 && (T1 & mask) != 0) {
1523
        xer_ca = 1;
1524
    } else {
1525
        xer_ca = 0;
1526
    }
1527
    RETURN();
1528
}
1529

    
1530
#if defined(TARGET_PPC64)
1531
void OPPROTO op_sradi (void)
1532
{
1533
    uint64_t mask = ((uint64_t)PARAM2 << 32) | (uint64_t)PARAM3;
1534

    
1535
    T0 = (int64_t)T0 >> PARAM1;
1536
    if ((int64_t)T1 < 0 && ((uint64_t)T1 & mask) != 0) {
1537
        xer_ca = 1;
1538
    } else {
1539
        xer_ca = 0;
1540
    }
1541
    RETURN();
1542
}
1543
#endif
1544

    
1545
/* shift right word */
1546
void OPPROTO op_srw (void)
1547
{
1548
    if (T1 & 0x20) {
1549
        T0 = 0;
1550
    } else {
1551
        T0 = (uint32_t)T0 >> T1;
1552
    }
1553
    RETURN();
1554
}
1555

    
1556
#if defined(TARGET_PPC64)
1557
void OPPROTO op_srd (void)
1558
{
1559
    if (T1 & 0x40) {
1560
        T0 = 0;
1561
    } else {
1562
        T0 = (uint64_t)T0 >> T1;
1563
    }
1564
    RETURN();
1565
}
1566
#endif
1567

    
1568
void OPPROTO op_sl_T0_T1 (void)
1569
{
1570
    T0 = T0 << T1;
1571
    RETURN();
1572
}
1573

    
1574
void OPPROTO op_sli_T0 (void)
1575
{
1576
    T0 = T0 << PARAM1;
1577
    RETURN();
1578
}
1579

    
1580
void OPPROTO op_sli_T1 (void)
1581
{
1582
    T1 = T1 << PARAM1;
1583
    RETURN();
1584
}
1585

    
1586
void OPPROTO op_srl_T0_T1 (void)
1587
{
1588
    T0 = (uint32_t)T0 >> T1;
1589
    RETURN();
1590
}
1591

    
1592
#if defined(TARGET_PPC64)
1593
void OPPROTO op_srl_T0_T1_64 (void)
1594
{
1595
    T0 = (uint32_t)T0 >> T1;
1596
    RETURN();
1597
}
1598
#endif
1599

    
1600
void OPPROTO op_srli_T0 (void)
1601
{
1602
    T0 = (uint32_t)T0 >> PARAM1;
1603
    RETURN();
1604
}
1605

    
1606
#if defined(TARGET_PPC64)
1607
void OPPROTO op_srli_T0_64 (void)
1608
{
1609
    T0 = (uint64_t)T0 >> PARAM1;
1610
    RETURN();
1611
}
1612
#endif
1613

    
1614
void OPPROTO op_srli_T1 (void)
1615
{
1616
    T1 = (uint32_t)T1 >> PARAM1;
1617
    RETURN();
1618
}
1619

    
1620
#if defined(TARGET_PPC64)
1621
void OPPROTO op_srli_T1_64 (void)
1622
{
1623
    T1 = (uint64_t)T1 >> PARAM1;
1624
    RETURN();
1625
}
1626
#endif
1627

    
1628
/***                       Floating-Point arithmetic                       ***/
1629
/* fadd - fadd. */
1630
void OPPROTO op_fadd (void)
1631
{
1632
#if USE_PRECISE_EMULATION
1633
    do_fadd();
1634
#else
1635
    FT0 = float64_add(FT0, FT1, &env->fp_status);
1636
#endif
1637
    RETURN();
1638
}
1639

    
1640
/* fsub - fsub. */
1641
void OPPROTO op_fsub (void)
1642
{
1643
#if USE_PRECISE_EMULATION
1644
    do_fsub();
1645
#else
1646
    FT0 = float64_sub(FT0, FT1, &env->fp_status);
1647
#endif
1648
    RETURN();
1649
}
1650

    
1651
/* fmul - fmul. */
1652
void OPPROTO op_fmul (void)
1653
{
1654
#if USE_PRECISE_EMULATION
1655
    do_fmul();
1656
#else
1657
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1658
#endif
1659
    RETURN();
1660
}
1661

    
1662
/* fdiv - fdiv. */
1663
void OPPROTO op_fdiv (void)
1664
{
1665
#if USE_PRECISE_EMULATION
1666
    do_fdiv();
1667
#else
1668
    FT0 = float64_div(FT0, FT1, &env->fp_status);
1669
#endif
1670
    RETURN();
1671
}
1672

    
1673
/* fsqrt - fsqrt. */
1674
void OPPROTO op_fsqrt (void)
1675
{
1676
    do_fsqrt();
1677
    RETURN();
1678
}
1679

    
1680
/* fre - fre. */
1681
void OPPROTO op_fre (void)
1682
{
1683
    do_fre();
1684
    RETURN();
1685
}
1686

    
1687
/* fres - fres. */
1688
void OPPROTO op_fres (void)
1689
{
1690
    do_fres();
1691
    RETURN();
1692
}
1693

    
1694
/* frsqrte  - frsqrte. */
1695
void OPPROTO op_frsqrte (void)
1696
{
1697
    do_frsqrte();
1698
    RETURN();
1699
}
1700

    
1701
/* fsel - fsel. */
1702
void OPPROTO op_fsel (void)
1703
{
1704
    do_fsel();
1705
    RETURN();
1706
}
1707

    
1708
/***                     Floating-Point multiply-and-add                   ***/
1709
/* fmadd - fmadd. */
1710
void OPPROTO op_fmadd (void)
1711
{
1712
#if USE_PRECISE_EMULATION
1713
    do_fmadd();
1714
#else
1715
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1716
    FT0 = float64_add(FT0, FT2, &env->fp_status);
1717
#endif
1718
    RETURN();
1719
}
1720

    
1721
/* fmsub - fmsub. */
1722
void OPPROTO op_fmsub (void)
1723
{
1724
#if USE_PRECISE_EMULATION
1725
    do_fmsub();
1726
#else
1727
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1728
    FT0 = float64_sub(FT0, FT2, &env->fp_status);
1729
#endif
1730
    RETURN();
1731
}
1732

    
1733
/* fnmadd - fnmadd. - fnmadds - fnmadds. */
1734
void OPPROTO op_fnmadd (void)
1735
{
1736
    do_fnmadd();
1737
    RETURN();
1738
}
1739

    
1740
/* fnmsub - fnmsub. */
1741
void OPPROTO op_fnmsub (void)
1742
{
1743
    do_fnmsub();
1744
    RETURN();
1745
}
1746

    
1747
/***                     Floating-Point round & convert                    ***/
1748
/* frsp - frsp. */
1749
void OPPROTO op_frsp (void)
1750
{
1751
#if USE_PRECISE_EMULATION
1752
    do_frsp();
1753
#else
1754
    FT0 = float64_to_float32(FT0, &env->fp_status);
1755
#endif
1756
    RETURN();
1757
}
1758

    
1759
/* fctiw - fctiw. */
1760
void OPPROTO op_fctiw (void)
1761
{
1762
    do_fctiw();
1763
    RETURN();
1764
}
1765

    
1766
/* fctiwz - fctiwz. */
1767
void OPPROTO op_fctiwz (void)
1768
{
1769
    do_fctiwz();
1770
    RETURN();
1771
}
1772

    
1773
#if defined(TARGET_PPC64)
1774
/* fcfid - fcfid. */
1775
void OPPROTO op_fcfid (void)
1776
{
1777
    do_fcfid();
1778
    RETURN();
1779
}
1780

    
1781
/* fctid - fctid. */
1782
void OPPROTO op_fctid (void)
1783
{
1784
    do_fctid();
1785
    RETURN();
1786
}
1787

    
1788
/* fctidz - fctidz. */
1789
void OPPROTO op_fctidz (void)
1790
{
1791
    do_fctidz();
1792
    RETURN();
1793
}
1794
#endif
1795

    
1796
void OPPROTO op_frin (void)
1797
{
1798
    do_frin();
1799
    RETURN();
1800
}
1801

    
1802
void OPPROTO op_friz (void)
1803
{
1804
    do_friz();
1805
    RETURN();
1806
}
1807

    
1808
void OPPROTO op_frip (void)
1809
{
1810
    do_frip();
1811
    RETURN();
1812
}
1813

    
1814
void OPPROTO op_frim (void)
1815
{
1816
    do_frim();
1817
    RETURN();
1818
}
1819

    
1820
/***                         Floating-Point compare                        ***/
1821
/* fcmpu */
1822
void OPPROTO op_fcmpu (void)
1823
{
1824
    do_fcmpu();
1825
    RETURN();
1826
}
1827

    
1828
/* fcmpo */
1829
void OPPROTO op_fcmpo (void)
1830
{
1831
    do_fcmpo();
1832
    RETURN();
1833
}
1834

    
1835
/***                         Floating-point move                           ***/
1836
/* fabs */
1837
void OPPROTO op_fabs (void)
1838
{
1839
    FT0 = float64_abs(FT0);
1840
    RETURN();
1841
}
1842

    
1843
/* fnabs */
1844
void OPPROTO op_fnabs (void)
1845
{
1846
    FT0 = float64_abs(FT0);
1847
    FT0 = float64_chs(FT0);
1848
    RETURN();
1849
}
1850

    
1851
/* fneg */
1852
void OPPROTO op_fneg (void)
1853
{
1854
    FT0 = float64_chs(FT0);
1855
    RETURN();
1856
}
1857

    
1858
/* Load and store */
1859
#define MEMSUFFIX _raw
1860
#include "op_helper.h"
1861
#include "op_mem.h"
1862
#if !defined(CONFIG_USER_ONLY)
1863
#define MEMSUFFIX _user
1864
#include "op_helper.h"
1865
#include "op_mem.h"
1866
#define MEMSUFFIX _kernel
1867
#include "op_helper.h"
1868
#include "op_mem.h"
1869
#define MEMSUFFIX _hypv
1870
#include "op_helper.h"
1871
#include "op_mem.h"
1872
#endif
1873

    
1874
/* Special op to check and maybe clear reservation */
1875
void OPPROTO op_check_reservation (void)
1876
{
1877
    if ((uint32_t)env->reserve == (uint32_t)(T0 & ~0x00000003))
1878
        env->reserve = (target_ulong)-1ULL;
1879
    RETURN();
1880
}
1881

    
1882
#if defined(TARGET_PPC64)
1883
void OPPROTO op_check_reservation_64 (void)
1884
{
1885
    if ((uint64_t)env->reserve == (uint64_t)(T0 & ~0x00000003))
1886
        env->reserve = (target_ulong)-1ULL;
1887
    RETURN();
1888
}
1889
#endif
1890

    
1891
void OPPROTO op_wait (void)
1892
{
1893
    env->halted = 1;
1894
    RETURN();
1895
}
1896

    
1897
/* Return from interrupt */
1898
#if !defined(CONFIG_USER_ONLY)
1899
void OPPROTO op_rfi (void)
1900
{
1901
    do_rfi();
1902
    RETURN();
1903
}
1904

    
1905
#if defined(TARGET_PPC64)
1906
void OPPROTO op_rfid (void)
1907
{
1908
    do_rfid();
1909
    RETURN();
1910
}
1911

    
1912
void OPPROTO op_hrfid (void)
1913
{
1914
    do_hrfid();
1915
    RETURN();
1916
}
1917
#endif
1918

    
1919
/* Exception vectors */
1920
void OPPROTO op_store_excp_prefix (void)
1921
{
1922
    T0 &= env->ivpr_mask;
1923
    env->excp_prefix = T0;
1924
    RETURN();
1925
}
1926

    
1927
void OPPROTO op_store_excp_vector (void)
1928
{
1929
    T0 &= env->ivor_mask;
1930
    env->excp_vectors[PARAM1] = T0;
1931
    RETURN();
1932
}
1933
#endif
1934

    
1935
/* Trap word */
1936
void OPPROTO op_tw (void)
1937
{
1938
    do_tw(PARAM1);
1939
    RETURN();
1940
}
1941

    
1942
#if defined(TARGET_PPC64)
1943
void OPPROTO op_td (void)
1944
{
1945
    do_td(PARAM1);
1946
    RETURN();
1947
}
1948
#endif
1949

    
1950
#if !defined(CONFIG_USER_ONLY)
1951
/* tlbia */
1952
void OPPROTO op_tlbia (void)
1953
{
1954
    ppc_tlb_invalidate_all(env);
1955
    RETURN();
1956
}
1957

    
1958
/* tlbie */
1959
void OPPROTO op_tlbie (void)
1960
{
1961
    ppc_tlb_invalidate_one(env, (uint32_t)T0);
1962
    RETURN();
1963
}
1964

    
1965
#if defined(TARGET_PPC64)
1966
void OPPROTO op_tlbie_64 (void)
1967
{
1968
    ppc_tlb_invalidate_one(env, T0);
1969
    RETURN();
1970
}
1971
#endif
1972

    
1973
#if defined(TARGET_PPC64)
1974
void OPPROTO op_slbia (void)
1975
{
1976
    ppc_slb_invalidate_all(env);
1977
    RETURN();
1978
}
1979

    
1980
void OPPROTO op_slbie (void)
1981
{
1982
    ppc_slb_invalidate_one(env, (uint32_t)T0);
1983
    RETURN();
1984
}
1985

    
1986
void OPPROTO op_slbie_64 (void)
1987
{
1988
    ppc_slb_invalidate_one(env, T0);
1989
    RETURN();
1990
}
1991
#endif
1992
#endif
1993

    
1994
#if !defined(CONFIG_USER_ONLY)
1995
/* PowerPC 602/603/755 software TLB load instructions */
1996
void OPPROTO op_6xx_tlbld (void)
1997
{
1998
    do_load_6xx_tlb(0);
1999
    RETURN();
2000
}
2001

    
2002
void OPPROTO op_6xx_tlbli (void)
2003
{
2004
    do_load_6xx_tlb(1);
2005
    RETURN();
2006
}
2007

    
2008
/* PowerPC 74xx software TLB load instructions */
2009
void OPPROTO op_74xx_tlbld (void)
2010
{
2011
    do_load_74xx_tlb(0);
2012
    RETURN();
2013
}
2014

    
2015
void OPPROTO op_74xx_tlbli (void)
2016
{
2017
    do_load_74xx_tlb(1);
2018
    RETURN();
2019
}
2020
#endif
2021

    
2022
/* 601 specific */
2023
void OPPROTO op_load_601_rtcl (void)
2024
{
2025
    T0 = cpu_ppc601_load_rtcl(env);
2026
    RETURN();
2027
}
2028

    
2029
void OPPROTO op_load_601_rtcu (void)
2030
{
2031
    T0 = cpu_ppc601_load_rtcu(env);
2032
    RETURN();
2033
}
2034

    
2035
#if !defined(CONFIG_USER_ONLY)
2036
void OPPROTO op_store_601_rtcl (void)
2037
{
2038
    cpu_ppc601_store_rtcl(env, T0);
2039
    RETURN();
2040
}
2041

    
2042
void OPPROTO op_store_601_rtcu (void)
2043
{
2044
    cpu_ppc601_store_rtcu(env, T0);
2045
    RETURN();
2046
}
2047

    
2048
void OPPROTO op_store_hid0_601 (void)
2049
{
2050
    do_store_hid0_601();
2051
    RETURN();
2052
}
2053

    
2054
void OPPROTO op_load_601_bat (void)
2055
{
2056
    T0 = env->IBAT[PARAM1][PARAM2];
2057
    RETURN();
2058
}
2059

    
2060
void OPPROTO op_store_601_batl (void)
2061
{
2062
    do_store_ibatl_601(env, PARAM1, T0);
2063
    RETURN();
2064
}
2065

    
2066
void OPPROTO op_store_601_batu (void)
2067
{
2068
    do_store_ibatu_601(env, PARAM1, T0);
2069
    RETURN();
2070
}
2071
#endif /* !defined(CONFIG_USER_ONLY) */
2072

    
2073
/* PowerPC 601 specific instructions (POWER bridge) */
2074
/* XXX: those micro-ops need tests ! */
2075
void OPPROTO op_POWER_abs (void)
2076
{
2077
    if ((int32_t)T0 == INT32_MIN)
2078
        T0 = INT32_MAX;
2079
    else if ((int32_t)T0 < 0)
2080
        T0 = -T0;
2081
    RETURN();
2082
}
2083

    
2084
void OPPROTO op_POWER_abso (void)
2085
{
2086
    do_POWER_abso();
2087
    RETURN();
2088
}
2089

    
2090
void OPPROTO op_POWER_clcs (void)
2091
{
2092
    do_POWER_clcs();
2093
    RETURN();
2094
}
2095

    
2096
void OPPROTO op_POWER_div (void)
2097
{
2098
    do_POWER_div();
2099
    RETURN();
2100
}
2101

    
2102
void OPPROTO op_POWER_divo (void)
2103
{
2104
    do_POWER_divo();
2105
    RETURN();
2106
}
2107

    
2108
void OPPROTO op_POWER_divs (void)
2109
{
2110
    do_POWER_divs();
2111
    RETURN();
2112
}
2113

    
2114
void OPPROTO op_POWER_divso (void)
2115
{
2116
    do_POWER_divso();
2117
    RETURN();
2118
}
2119

    
2120
void OPPROTO op_POWER_doz (void)
2121
{
2122
    if ((int32_t)T1 > (int32_t)T0)
2123
        T0 = T1 - T0;
2124
    else
2125
        T0 = 0;
2126
    RETURN();
2127
}
2128

    
2129
void OPPROTO op_POWER_dozo (void)
2130
{
2131
    do_POWER_dozo();
2132
    RETURN();
2133
}
2134

    
2135
void OPPROTO op_load_xer_cmp (void)
2136
{
2137
    T2 = xer_cmp;
2138
    RETURN();
2139
}
2140

    
2141
void OPPROTO op_POWER_maskg (void)
2142
{
2143
    do_POWER_maskg();
2144
    RETURN();
2145
}
2146

    
2147
void OPPROTO op_POWER_maskir (void)
2148
{
2149
    T0 = (T0 & ~T2) | (T1 & T2);
2150
    RETURN();
2151
}
2152

    
2153
void OPPROTO op_POWER_mul (void)
2154
{
2155
    uint64_t tmp;
2156

    
2157
    tmp = (uint64_t)T0 * (uint64_t)T1;
2158
    env->spr[SPR_MQ] = tmp >> 32;
2159
    T0 = tmp;
2160
    RETURN();
2161
}
2162

    
2163
void OPPROTO op_POWER_mulo (void)
2164
{
2165
    do_POWER_mulo();
2166
    RETURN();
2167
}
2168

    
2169
void OPPROTO op_POWER_nabs (void)
2170
{
2171
    if (T0 > 0)
2172
        T0 = -T0;
2173
    RETURN();
2174
}
2175

    
2176
void OPPROTO op_POWER_nabso (void)
2177
{
2178
    /* nabs never overflows */
2179
    if (T0 > 0)
2180
        T0 = -T0;
2181
    xer_ov = 0;
2182
    RETURN();
2183
}
2184

    
2185
/* XXX: factorise POWER rotates... */
2186
void OPPROTO op_POWER_rlmi (void)
2187
{
2188
    T0 = rotl32(T0, T2) & PARAM1;
2189
    T0 |= T1 & (uint32_t)PARAM2;
2190
    RETURN();
2191
}
2192

    
2193
void OPPROTO op_POWER_rrib (void)
2194
{
2195
    T2 &= 0x1FUL;
2196
    T0 = rotl32(T0 & INT32_MIN, T2);
2197
    T0 |= T1 & ~rotl32(INT32_MIN, T2);
2198
    RETURN();
2199
}
2200

    
2201
void OPPROTO op_POWER_sle (void)
2202
{
2203
    T1 &= 0x1FUL;
2204
    env->spr[SPR_MQ] = rotl32(T0, T1);
2205
    T0 = T0 << T1;
2206
    RETURN();
2207
}
2208

    
2209
void OPPROTO op_POWER_sleq (void)
2210
{
2211
    uint32_t tmp = env->spr[SPR_MQ];
2212

    
2213
    T1 &= 0x1FUL;
2214
    env->spr[SPR_MQ] = rotl32(T0, T1);
2215
    T0 = T0 << T1;
2216
    T0 |= tmp >> (32 - T1);
2217
    RETURN();
2218
}
2219

    
2220
void OPPROTO op_POWER_sllq (void)
2221
{
2222
    uint32_t msk = UINT32_MAX;
2223

    
2224
    msk = msk << (T1 & 0x1FUL);
2225
    if (T1 & 0x20UL)
2226
        msk = ~msk;
2227
    T1 &= 0x1FUL;
2228
    T0 = (T0 << T1) & msk;
2229
    T0 |= env->spr[SPR_MQ] & ~msk;
2230
    RETURN();
2231
}
2232

    
2233
void OPPROTO op_POWER_slq (void)
2234
{
2235
    uint32_t msk = UINT32_MAX, tmp;
2236

    
2237
    msk = msk << (T1 & 0x1FUL);
2238
    if (T1 & 0x20UL)
2239
        msk = ~msk;
2240
    T1 &= 0x1FUL;
2241
    tmp = rotl32(T0, T1);
2242
    T0 = tmp & msk;
2243
    env->spr[SPR_MQ] = tmp;
2244
    RETURN();
2245
}
2246

    
2247
void OPPROTO op_POWER_sraq (void)
2248
{
2249
    env->spr[SPR_MQ] = rotl32(T0, 32 - (T1 & 0x1FUL));
2250
    if (T1 & 0x20UL)
2251
        T0 = UINT32_MAX;
2252
    else
2253
        T0 = (int32_t)T0 >> T1;
2254
    RETURN();
2255
}
2256

    
2257
void OPPROTO op_POWER_sre (void)
2258
{
2259
    T1 &= 0x1FUL;
2260
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2261
    T0 = (int32_t)T0 >> T1;
2262
    RETURN();
2263
}
2264

    
2265
void OPPROTO op_POWER_srea (void)
2266
{
2267
    T1 &= 0x1FUL;
2268
    env->spr[SPR_MQ] = T0 >> T1;
2269
    T0 = (int32_t)T0 >> T1;
2270
    RETURN();
2271
}
2272

    
2273
void OPPROTO op_POWER_sreq (void)
2274
{
2275
    uint32_t tmp;
2276
    int32_t msk;
2277

    
2278
    T1 &= 0x1FUL;
2279
    msk = INT32_MIN >> T1;
2280
    tmp = env->spr[SPR_MQ];
2281
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2282
    T0 = T0 >> T1;
2283
    T0 |= tmp & msk;
2284
    RETURN();
2285
}
2286

    
2287
void OPPROTO op_POWER_srlq (void)
2288
{
2289
    uint32_t tmp;
2290
    int32_t msk;
2291

    
2292
    msk = INT32_MIN >> (T1 & 0x1FUL);
2293
    if (T1 & 0x20UL)
2294
        msk = ~msk;
2295
    T1 &= 0x1FUL;
2296
    tmp = env->spr[SPR_MQ];
2297
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2298
    T0 = T0 >> T1;
2299
    T0 &= msk;
2300
    T0 |= tmp & ~msk;
2301
    RETURN();
2302
}
2303

    
2304
void OPPROTO op_POWER_srq (void)
2305
{
2306
    T1 &= 0x1FUL;
2307
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2308
    T0 = T0 >> T1;
2309
    RETURN();
2310
}
2311

    
2312
/* POWER instructions not implemented in PowerPC 601 */
2313
#if !defined(CONFIG_USER_ONLY)
2314
void OPPROTO op_POWER_mfsri (void)
2315
{
2316
    T1 = T0 >> 28;
2317
    T0 = env->sr[T1];
2318
    RETURN();
2319
}
2320

    
2321
void OPPROTO op_POWER_rac (void)
2322
{
2323
    do_POWER_rac();
2324
    RETURN();
2325
}
2326

    
2327
void OPPROTO op_POWER_rfsvc (void)
2328
{
2329
    do_POWER_rfsvc();
2330
    RETURN();
2331
}
2332
#endif
2333

    
2334
/* PowerPC 602 specific instruction */
2335
#if !defined(CONFIG_USER_ONLY)
2336
void OPPROTO op_602_mfrom (void)
2337
{
2338
    do_op_602_mfrom();
2339
    RETURN();
2340
}
2341
#endif
2342

    
2343
/* PowerPC 4xx specific micro-ops */
2344
void OPPROTO op_405_add_T0_T2 (void)
2345
{
2346
    T0 = (int32_t)T0 + (int32_t)T2;
2347
    RETURN();
2348
}
2349

    
2350
void OPPROTO op_405_mulchw (void)
2351
{
2352
    T0 = ((int16_t)T0) * ((int16_t)(T1 >> 16));
2353
    RETURN();
2354
}
2355

    
2356
void OPPROTO op_405_mulchwu (void)
2357
{
2358
    T0 = ((uint16_t)T0) * ((uint16_t)(T1 >> 16));
2359
    RETURN();
2360
}
2361

    
2362
void OPPROTO op_405_mulhhw (void)
2363
{
2364
    T0 = ((int16_t)(T0 >> 16)) * ((int16_t)(T1 >> 16));
2365
    RETURN();
2366
}
2367

    
2368
void OPPROTO op_405_mulhhwu (void)
2369
{
2370
    T0 = ((uint16_t)(T0 >> 16)) * ((uint16_t)(T1 >> 16));
2371
    RETURN();
2372
}
2373

    
2374
void OPPROTO op_405_mullhw (void)
2375
{
2376
    T0 = ((int16_t)T0) * ((int16_t)T1);
2377
    RETURN();
2378
}
2379

    
2380
void OPPROTO op_405_mullhwu (void)
2381
{
2382
    T0 = ((uint16_t)T0) * ((uint16_t)T1);
2383
    RETURN();
2384
}
2385

    
2386
void OPPROTO op_405_check_sat (void)
2387
{
2388
    do_405_check_sat();
2389
    RETURN();
2390
}
2391

    
2392
void OPPROTO op_405_check_ovu (void)
2393
{
2394
    if (likely(T0 >= T2)) {
2395
        xer_ov = 0;
2396
    } else {
2397
        xer_ov = 1;
2398
        xer_so = 1;
2399
    }
2400
    RETURN();
2401
}
2402

    
2403
void OPPROTO op_405_check_satu (void)
2404
{
2405
    if (unlikely(T0 < T2)) {
2406
        /* Saturate result */
2407
        T0 = UINT32_MAX;
2408
    }
2409
    RETURN();
2410
}
2411

    
2412
void OPPROTO op_load_dcr (void)
2413
{
2414
    do_load_dcr();
2415
    RETURN();
2416
}
2417

    
2418
void OPPROTO op_store_dcr (void)
2419
{
2420
    do_store_dcr();
2421
    RETURN();
2422
}
2423

    
2424
#if !defined(CONFIG_USER_ONLY)
2425
/* Return from critical interrupt :
2426
 * same as rfi, except nip & MSR are loaded from SRR2/3 instead of SRR0/1
2427
 */
2428
void OPPROTO op_40x_rfci (void)
2429
{
2430
    do_40x_rfci();
2431
    RETURN();
2432
}
2433

    
2434
void OPPROTO op_rfci (void)
2435
{
2436
    do_rfci();
2437
    RETURN();
2438
}
2439

    
2440
void OPPROTO op_rfdi (void)
2441
{
2442
    do_rfdi();
2443
    RETURN();
2444
}
2445

    
2446
void OPPROTO op_rfmci (void)
2447
{
2448
    do_rfmci();
2449
    RETURN();
2450
}
2451

    
2452
void OPPROTO op_wrte (void)
2453
{
2454
    /* We don't call do_store_msr here as we won't trigger
2455
     * any special case nor change hflags
2456
     */
2457
    T0 &= 1 << MSR_EE;
2458
    env->msr &= ~(1 << MSR_EE);
2459
    env->msr |= T0;
2460
    RETURN();
2461
}
2462

    
2463
void OPPROTO op_440_tlbre (void)
2464
{
2465
    do_440_tlbre(PARAM1);
2466
    RETURN();
2467
}
2468

    
2469
void OPPROTO op_440_tlbsx (void)
2470
{
2471
    T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_440_MMUCR] & 0xFF);
2472
    RETURN();
2473
}
2474

    
2475
void OPPROTO op_4xx_tlbsx_check (void)
2476
{
2477
    int tmp;
2478

    
2479
    tmp = xer_so;
2480
    if ((int)T0 != -1)
2481
        tmp |= 0x02;
2482
    env->crf[0] = tmp;
2483
    RETURN();
2484
}
2485

    
2486
void OPPROTO op_440_tlbwe (void)
2487
{
2488
    do_440_tlbwe(PARAM1);
2489
    RETURN();
2490
}
2491

    
2492
void OPPROTO op_4xx_tlbre_lo (void)
2493
{
2494
    do_4xx_tlbre_lo();
2495
    RETURN();
2496
}
2497

    
2498
void OPPROTO op_4xx_tlbre_hi (void)
2499
{
2500
    do_4xx_tlbre_hi();
2501
    RETURN();
2502
}
2503

    
2504
void OPPROTO op_4xx_tlbsx (void)
2505
{
2506
    T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_40x_PID]);
2507
    RETURN();
2508
}
2509

    
2510
void OPPROTO op_4xx_tlbwe_lo (void)
2511
{
2512
    do_4xx_tlbwe_lo();
2513
    RETURN();
2514
}
2515

    
2516
void OPPROTO op_4xx_tlbwe_hi (void)
2517
{
2518
    do_4xx_tlbwe_hi();
2519
    RETURN();
2520
}
2521
#endif
2522

    
2523
/* SPR micro-ops */
2524
/* 440 specific */
2525
void OPPROTO op_440_dlmzb (void)
2526
{
2527
    do_440_dlmzb();
2528
    RETURN();
2529
}
2530

    
2531
void OPPROTO op_440_dlmzb_update_Rc (void)
2532
{
2533
    if (T0 == 8)
2534
        T0 = 0x2;
2535
    else if (T0 < 4)
2536
        T0 = 0x4;
2537
    else
2538
        T0 = 0x8;
2539
    RETURN();
2540
}
2541

    
2542
#if !defined(CONFIG_USER_ONLY)
2543
void OPPROTO op_store_pir (void)
2544
{
2545
    env->spr[SPR_PIR] = T0 & 0x0000000FUL;
2546
    RETURN();
2547
}
2548

    
2549
void OPPROTO op_load_403_pb (void)
2550
{
2551
    do_load_403_pb(PARAM1);
2552
    RETURN();
2553
}
2554

    
2555
void OPPROTO op_store_403_pb (void)
2556
{
2557
    do_store_403_pb(PARAM1);
2558
    RETURN();
2559
}
2560

    
2561
void OPPROTO op_load_40x_pit (void)
2562
{
2563
    T0 = load_40x_pit(env);
2564
    RETURN();
2565
}
2566

    
2567
void OPPROTO op_store_40x_pit (void)
2568
{
2569
    store_40x_pit(env, T0);
2570
    RETURN();
2571
}
2572

    
2573
void OPPROTO op_store_40x_dbcr0 (void)
2574
{
2575
    store_40x_dbcr0(env, T0);
2576
    RETURN();
2577
}
2578

    
2579
void OPPROTO op_store_40x_sler (void)
2580
{
2581
    store_40x_sler(env, T0);
2582
    RETURN();
2583
}
2584

    
2585
void OPPROTO op_store_booke_tcr (void)
2586
{
2587
    store_booke_tcr(env, T0);
2588
    RETURN();
2589
}
2590

    
2591
void OPPROTO op_store_booke_tsr (void)
2592
{
2593
    store_booke_tsr(env, T0);
2594
    RETURN();
2595
}
2596
#endif /* !defined(CONFIG_USER_ONLY) */
2597

    
2598
/* SPE extension */
2599
void OPPROTO op_splatw_T1_64 (void)
2600
{
2601
    T1_64 = (T1_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL);
2602
    RETURN();
2603
}
2604

    
2605
void OPPROTO op_splatwi_T0_64 (void)
2606
{
2607
    uint64_t tmp = PARAM1;
2608

    
2609
    T0_64 = (tmp << 32) | tmp;
2610
    RETURN();
2611
}
2612

    
2613
void OPPROTO op_splatwi_T1_64 (void)
2614
{
2615
    uint64_t tmp = PARAM1;
2616

    
2617
    T1_64 = (tmp << 32) | tmp;
2618
    RETURN();
2619
}
2620

    
2621
void OPPROTO op_extsh_T1_64 (void)
2622
{
2623
    T1_64 = (int32_t)((int16_t)T1_64);
2624
    RETURN();
2625
}
2626

    
2627
void OPPROTO op_sli16_T1_64 (void)
2628
{
2629
    T1_64 = T1_64 << 16;
2630
    RETURN();
2631
}
2632

    
2633
void OPPROTO op_sli32_T1_64 (void)
2634
{
2635
    T1_64 = T1_64 << 32;
2636
    RETURN();
2637
}
2638

    
2639
void OPPROTO op_srli32_T1_64 (void)
2640
{
2641
    T1_64 = T1_64 >> 32;
2642
    RETURN();
2643
}
2644

    
2645
void OPPROTO op_evsel (void)
2646
{
2647
    do_evsel();
2648
    RETURN();
2649
}
2650

    
2651
void OPPROTO op_evaddw (void)
2652
{
2653
    do_evaddw();
2654
    RETURN();
2655
}
2656

    
2657
void OPPROTO op_evsubfw (void)
2658
{
2659
    do_evsubfw();
2660
    RETURN();
2661
}
2662

    
2663
void OPPROTO op_evneg (void)
2664
{
2665
    do_evneg();
2666
    RETURN();
2667
}
2668

    
2669
void OPPROTO op_evabs (void)
2670
{
2671
    do_evabs();
2672
    RETURN();
2673
}
2674

    
2675
void OPPROTO op_evextsh (void)
2676
{
2677
    T0_64 = ((uint64_t)((int32_t)(int16_t)(T0_64 >> 32)) << 32) |
2678
        (uint64_t)((int32_t)(int16_t)T0_64);
2679
    RETURN();
2680
}
2681

    
2682
void OPPROTO op_evextsb (void)
2683
{
2684
    T0_64 = ((uint64_t)((int32_t)(int8_t)(T0_64 >> 32)) << 32) |
2685
        (uint64_t)((int32_t)(int8_t)T0_64);
2686
    RETURN();
2687
}
2688

    
2689
void OPPROTO op_evcntlzw (void)
2690
{
2691
    do_evcntlzw();
2692
    RETURN();
2693
}
2694

    
2695
void OPPROTO op_evrndw (void)
2696
{
2697
    do_evrndw();
2698
    RETURN();
2699
}
2700

    
2701
void OPPROTO op_brinc (void)
2702
{
2703
    do_brinc();
2704
    RETURN();
2705
}
2706

    
2707
void OPPROTO op_evcntlsw (void)
2708
{
2709
    do_evcntlsw();
2710
    RETURN();
2711
}
2712

    
2713
void OPPROTO op_evand (void)
2714
{
2715
    T0_64 &= T1_64;
2716
    RETURN();
2717
}
2718

    
2719
void OPPROTO op_evandc (void)
2720
{
2721
    T0_64 &= ~T1_64;
2722
    RETURN();
2723
}
2724

    
2725
void OPPROTO op_evor (void)
2726
{
2727
    T0_64 |= T1_64;
2728
    RETURN();
2729
}
2730

    
2731
void OPPROTO op_evxor (void)
2732
{
2733
    T0_64 ^= T1_64;
2734
    RETURN();
2735
}
2736

    
2737
void OPPROTO op_eveqv (void)
2738
{
2739
    T0_64 = ~(T0_64 ^ T1_64);
2740
    RETURN();
2741
}
2742

    
2743
void OPPROTO op_evnor (void)
2744
{
2745
    T0_64 = ~(T0_64 | T1_64);
2746
    RETURN();
2747
}
2748

    
2749
void OPPROTO op_evorc (void)
2750
{
2751
    T0_64 |= ~T1_64;
2752
    RETURN();
2753
}
2754

    
2755
void OPPROTO op_evnand (void)
2756
{
2757
    T0_64 = ~(T0_64 & T1_64);
2758
    RETURN();
2759
}
2760

    
2761
void OPPROTO op_evsrws (void)
2762
{
2763
    do_evsrws();
2764
    RETURN();
2765
}
2766

    
2767
void OPPROTO op_evsrwu (void)
2768
{
2769
    do_evsrwu();
2770
    RETURN();
2771
}
2772

    
2773
void OPPROTO op_evslw (void)
2774
{
2775
    do_evslw();
2776
    RETURN();
2777
}
2778

    
2779
void OPPROTO op_evrlw (void)
2780
{
2781
    do_evrlw();
2782
    RETURN();
2783
}
2784

    
2785
void OPPROTO op_evmergelo (void)
2786
{
2787
    T0_64 = (T0_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL);
2788
    RETURN();
2789
}
2790

    
2791
void OPPROTO op_evmergehi (void)
2792
{
2793
    T0_64 = (T0_64 & 0xFFFFFFFF00000000ULL) | (T1_64 >> 32);
2794
    RETURN();
2795
}
2796

    
2797
void OPPROTO op_evmergelohi (void)
2798
{
2799
    T0_64 = (T0_64 << 32) | (T1_64 >> 32);
2800
    RETURN();
2801
}
2802

    
2803
void OPPROTO op_evmergehilo (void)
2804
{
2805
    T0_64 = (T0_64 & 0xFFFFFFFF00000000ULL) | (T1_64 & 0x00000000FFFFFFFFULL);
2806
    RETURN();
2807
}
2808

    
2809
void OPPROTO op_evcmpgts (void)
2810
{
2811
    do_evcmpgts();
2812
    RETURN();
2813
}
2814

    
2815
void OPPROTO op_evcmpgtu (void)
2816
{
2817
    do_evcmpgtu();
2818
    RETURN();
2819
}
2820

    
2821
void OPPROTO op_evcmplts (void)
2822
{
2823
    do_evcmplts();
2824
    RETURN();
2825
}
2826

    
2827
void OPPROTO op_evcmpltu (void)
2828
{
2829
    do_evcmpltu();
2830
    RETURN();
2831
}
2832

    
2833
void OPPROTO op_evcmpeq (void)
2834
{
2835
    do_evcmpeq();
2836
    RETURN();
2837
}
2838

    
2839
void OPPROTO op_evfssub (void)
2840
{
2841
    do_evfssub();
2842
    RETURN();
2843
}
2844

    
2845
void OPPROTO op_evfsadd (void)
2846
{
2847
    do_evfsadd();
2848
    RETURN();
2849
}
2850

    
2851
void OPPROTO op_evfsnabs (void)
2852
{
2853
    do_evfsnabs();
2854
    RETURN();
2855
}
2856

    
2857
void OPPROTO op_evfsabs (void)
2858
{
2859
    do_evfsabs();
2860
    RETURN();
2861
}
2862

    
2863
void OPPROTO op_evfsneg (void)
2864
{
2865
    do_evfsneg();
2866
    RETURN();
2867
}
2868

    
2869
void OPPROTO op_evfsdiv (void)
2870
{
2871
    do_evfsdiv();
2872
    RETURN();
2873
}
2874

    
2875
void OPPROTO op_evfsmul (void)
2876
{
2877
    do_evfsmul();
2878
    RETURN();
2879
}
2880

    
2881
void OPPROTO op_evfscmplt (void)
2882
{
2883
    do_evfscmplt();
2884
    RETURN();
2885
}
2886

    
2887
void OPPROTO op_evfscmpgt (void)
2888
{
2889
    do_evfscmpgt();
2890
    RETURN();
2891
}
2892

    
2893
void OPPROTO op_evfscmpeq (void)
2894
{
2895
    do_evfscmpeq();
2896
    RETURN();
2897
}
2898

    
2899
void OPPROTO op_evfscfsi (void)
2900
{
2901
    do_evfscfsi();
2902
    RETURN();
2903
}
2904

    
2905
void OPPROTO op_evfscfui (void)
2906
{
2907
    do_evfscfui();
2908
    RETURN();
2909
}
2910

    
2911
void OPPROTO op_evfscfsf (void)
2912
{
2913
    do_evfscfsf();
2914
    RETURN();
2915
}
2916

    
2917
void OPPROTO op_evfscfuf (void)
2918
{
2919
    do_evfscfuf();
2920
    RETURN();
2921
}
2922

    
2923
void OPPROTO op_evfsctsi (void)
2924
{
2925
    do_evfsctsi();
2926
    RETURN();
2927
}
2928

    
2929
void OPPROTO op_evfsctui (void)
2930
{
2931
    do_evfsctui();
2932
    RETURN();
2933
}
2934

    
2935
void OPPROTO op_evfsctsf (void)
2936
{
2937
    do_evfsctsf();
2938
    RETURN();
2939
}
2940

    
2941
void OPPROTO op_evfsctuf (void)
2942
{
2943
    do_evfsctuf();
2944
    RETURN();
2945
}
2946

    
2947
void OPPROTO op_evfsctuiz (void)
2948
{
2949
    do_evfsctuiz();
2950
    RETURN();
2951
}
2952

    
2953
void OPPROTO op_evfsctsiz (void)
2954
{
2955
    do_evfsctsiz();
2956
    RETURN();
2957
}
2958

    
2959
void OPPROTO op_evfststlt (void)
2960
{
2961
    do_evfststlt();
2962
    RETURN();
2963
}
2964

    
2965
void OPPROTO op_evfststgt (void)
2966
{
2967
    do_evfststgt();
2968
    RETURN();
2969
}
2970

    
2971
void OPPROTO op_evfststeq (void)
2972
{
2973
    do_evfststeq();
2974
    RETURN();
2975
}
2976

    
2977
void OPPROTO op_efssub (void)
2978
{
2979
    T0_64 = _do_efssub(T0_64, T1_64);
2980
    RETURN();
2981
}
2982

    
2983
void OPPROTO op_efsadd (void)
2984
{
2985
    T0_64 = _do_efsadd(T0_64, T1_64);
2986
    RETURN();
2987
}
2988

    
2989
void OPPROTO op_efsnabs (void)
2990
{
2991
    T0_64 = _do_efsnabs(T0_64);
2992
    RETURN();
2993
}
2994

    
2995
void OPPROTO op_efsabs (void)
2996
{
2997
    T0_64 = _do_efsabs(T0_64);
2998
    RETURN();
2999
}
3000

    
3001
void OPPROTO op_efsneg (void)
3002
{
3003
    T0_64 = _do_efsneg(T0_64);
3004
    RETURN();
3005
}
3006

    
3007
void OPPROTO op_efsdiv (void)
3008
{
3009
    T0_64 = _do_efsdiv(T0_64, T1_64);
3010
    RETURN();
3011
}
3012

    
3013
void OPPROTO op_efsmul (void)
3014
{
3015
    T0_64 = _do_efsmul(T0_64, T1_64);
3016
    RETURN();
3017
}
3018

    
3019
void OPPROTO op_efscmplt (void)
3020
{
3021
    do_efscmplt();
3022
    RETURN();
3023
}
3024

    
3025
void OPPROTO op_efscmpgt (void)
3026
{
3027
    do_efscmpgt();
3028
    RETURN();
3029
}
3030

    
3031
void OPPROTO op_efscfd (void)
3032
{
3033
    do_efscfd();
3034
    RETURN();
3035
}
3036

    
3037
void OPPROTO op_efscmpeq (void)
3038
{
3039
    do_efscmpeq();
3040
    RETURN();
3041
}
3042

    
3043
void OPPROTO op_efscfsi (void)
3044
{
3045
    do_efscfsi();
3046
    RETURN();
3047
}
3048

    
3049
void OPPROTO op_efscfui (void)
3050
{
3051
    do_efscfui();
3052
    RETURN();
3053
}
3054

    
3055
void OPPROTO op_efscfsf (void)
3056
{
3057
    do_efscfsf();
3058
    RETURN();
3059
}
3060

    
3061
void OPPROTO op_efscfuf (void)
3062
{
3063
    do_efscfuf();
3064
    RETURN();
3065
}
3066

    
3067
void OPPROTO op_efsctsi (void)
3068
{
3069
    do_efsctsi();
3070
    RETURN();
3071
}
3072

    
3073
void OPPROTO op_efsctui (void)
3074
{
3075
    do_efsctui();
3076
    RETURN();
3077
}
3078

    
3079
void OPPROTO op_efsctsf (void)
3080
{
3081
    do_efsctsf();
3082
    RETURN();
3083
}
3084

    
3085
void OPPROTO op_efsctuf (void)
3086
{
3087
    do_efsctuf();
3088
    RETURN();
3089
}
3090

    
3091
void OPPROTO op_efsctsiz (void)
3092
{
3093
    do_efsctsiz();
3094
    RETURN();
3095
}
3096

    
3097
void OPPROTO op_efsctuiz (void)
3098
{
3099
    do_efsctuiz();
3100
    RETURN();
3101
}
3102

    
3103
void OPPROTO op_efststlt (void)
3104
{
3105
    T0 = _do_efststlt(T0_64, T1_64);
3106
    RETURN();
3107
}
3108

    
3109
void OPPROTO op_efststgt (void)
3110
{
3111
    T0 = _do_efststgt(T0_64, T1_64);
3112
    RETURN();
3113
}
3114

    
3115
void OPPROTO op_efststeq (void)
3116
{
3117
    T0 = _do_efststeq(T0_64, T1_64);
3118
    RETURN();
3119
}
3120

    
3121
void OPPROTO op_efdsub (void)
3122
{
3123
    CPU_DoubleU u1, u2;
3124
    u1.ll = T0_64;
3125
    u2.ll = T1_64;
3126
    u1.d = float64_sub(u1.d, u2.d, &env->spe_status);
3127
    T0_64 = u1.ll;
3128
    RETURN();
3129
}
3130

    
3131
void OPPROTO op_efdadd (void)
3132
{
3133
    CPU_DoubleU u1, u2;
3134
    u1.ll = T0_64;
3135
    u2.ll = T1_64;
3136
    u1.d = float64_add(u1.d, u2.d, &env->spe_status);
3137
    T0_64 = u1.ll;
3138
    RETURN();
3139
}
3140

    
3141
void OPPROTO op_efdcfsid (void)
3142
{
3143
    do_efdcfsi();
3144
    RETURN();
3145
}
3146

    
3147
void OPPROTO op_efdcfuid (void)
3148
{
3149
    do_efdcfui();
3150
    RETURN();
3151
}
3152

    
3153
void OPPROTO op_efdnabs (void)
3154
{
3155
    T0_64 |= 0x8000000000000000ULL;
3156
    RETURN();
3157
}
3158

    
3159
void OPPROTO op_efdabs (void)
3160
{
3161
    T0_64 &= ~0x8000000000000000ULL;
3162
    RETURN();
3163
}
3164

    
3165
void OPPROTO op_efdneg (void)
3166
{
3167
    T0_64 ^= 0x8000000000000000ULL;
3168
    RETURN();
3169
}
3170

    
3171
void OPPROTO op_efddiv (void)
3172
{
3173
    CPU_DoubleU u1, u2;
3174
    u1.ll = T0_64;
3175
    u2.ll = T1_64;
3176
    u1.d = float64_div(u1.d, u2.d, &env->spe_status);
3177
    T0_64 = u1.ll;
3178
    RETURN();
3179
}
3180

    
3181
void OPPROTO op_efdmul (void)
3182
{
3183
    CPU_DoubleU u1, u2;
3184
    u1.ll = T0_64;
3185
    u2.ll = T1_64;
3186
    u1.d = float64_mul(u1.d, u2.d, &env->spe_status);
3187
    T0_64 = u1.ll;
3188
    RETURN();
3189
}
3190

    
3191
void OPPROTO op_efdctsidz (void)
3192
{
3193
    do_efdctsiz();
3194
    RETURN();
3195
}
3196

    
3197
void OPPROTO op_efdctuidz (void)
3198
{
3199
    do_efdctuiz();
3200
    RETURN();
3201
}
3202

    
3203
void OPPROTO op_efdcmplt (void)
3204
{
3205
    do_efdcmplt();
3206
    RETURN();
3207
}
3208

    
3209
void OPPROTO op_efdcmpgt (void)
3210
{
3211
    do_efdcmpgt();
3212
    RETURN();
3213
}
3214

    
3215
void OPPROTO op_efdcfs (void)
3216
{
3217
    do_efdcfs();
3218
    RETURN();
3219
}
3220

    
3221
void OPPROTO op_efdcmpeq (void)
3222
{
3223
    do_efdcmpeq();
3224
    RETURN();
3225
}
3226

    
3227
void OPPROTO op_efdcfsi (void)
3228
{
3229
    do_efdcfsi();
3230
    RETURN();
3231
}
3232

    
3233
void OPPROTO op_efdcfui (void)
3234
{
3235
    do_efdcfui();
3236
    RETURN();
3237
}
3238

    
3239
void OPPROTO op_efdcfsf (void)
3240
{
3241
    do_efdcfsf();
3242
    RETURN();
3243
}
3244

    
3245
void OPPROTO op_efdcfuf (void)
3246
{
3247
    do_efdcfuf();
3248
    RETURN();
3249
}
3250

    
3251
void OPPROTO op_efdctsi (void)
3252
{
3253
    do_efdctsi();
3254
    RETURN();
3255
}
3256

    
3257
void OPPROTO op_efdctui (void)
3258
{
3259
    do_efdctui();
3260
    RETURN();
3261
}
3262

    
3263
void OPPROTO op_efdctsf (void)
3264
{
3265
    do_efdctsf();
3266
    RETURN();
3267
}
3268

    
3269
void OPPROTO op_efdctuf (void)
3270
{
3271
    do_efdctuf();
3272
    RETURN();
3273
}
3274

    
3275
void OPPROTO op_efdctuiz (void)
3276
{
3277
    do_efdctuiz();
3278
    RETURN();
3279
}
3280

    
3281
void OPPROTO op_efdctsiz (void)
3282
{
3283
    do_efdctsiz();
3284
    RETURN();
3285
}
3286

    
3287
void OPPROTO op_efdtstlt (void)
3288
{
3289
    T0 = _do_efdtstlt(T0_64, T1_64);
3290
    RETURN();
3291
}
3292

    
3293
void OPPROTO op_efdtstgt (void)
3294
{
3295
    T0 = _do_efdtstgt(T0_64, T1_64);
3296
    RETURN();
3297
}
3298

    
3299
void OPPROTO op_efdtsteq (void)
3300
{
3301
    T0 = _do_efdtsteq(T0_64, T1_64);
3302
    RETURN();
3303
}