Statistics
| Branch: | Revision:

root / target-ppc / op.c @ 603fccce

History | View | Annotate | Download (51.5 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_reset_T0 (void)
141
{
142
    T0 = 0;
143
    RETURN();
144
}
145

    
146
void OPPROTO op_set_T0 (void)
147
{
148
    T0 = (uint32_t)PARAM1;
149
    RETURN();
150
}
151

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

    
160
void OPPROTO op_set_T1 (void)
161
{
162
    T1 = (uint32_t)PARAM1;
163
    RETURN();
164
}
165

    
166
#if defined(TARGET_PPC64)
167
void OPPROTO op_set_T1_64 (void)
168
{
169
    T1 = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
170
    RETURN();
171
}
172
#endif
173

    
174
#if 0 // unused
175
void OPPROTO op_set_T2 (void)
176
{
177
    T2 = (uint32_t)PARAM1;
178
    RETURN();
179
}
180
#endif
181

    
182
void OPPROTO op_move_T1_T0 (void)
183
{
184
    T1 = T0;
185
    RETURN();
186
}
187

    
188
void OPPROTO op_move_T2_T0 (void)
189
{
190
    T2 = T0;
191
    RETURN();
192
}
193

    
194
/* Generate exceptions */
195
void OPPROTO op_raise_exception_err (void)
196
{
197
    do_raise_exception_err(PARAM1, PARAM2);
198
}
199

    
200
void OPPROTO op_update_nip (void)
201
{
202
    env->nip = (uint32_t)PARAM1;
203
    RETURN();
204
}
205

    
206
#if defined(TARGET_PPC64)
207
void OPPROTO op_update_nip_64 (void)
208
{
209
    env->nip = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
210
    RETURN();
211
}
212
#endif
213

    
214
void OPPROTO op_debug (void)
215
{
216
    do_raise_exception(EXCP_DEBUG);
217
}
218

    
219
void OPPROTO op_exit_tb (void)
220
{
221
    EXIT_TB();
222
}
223

    
224
/* Load/store special registers */
225
void OPPROTO op_load_cr (void)
226
{
227
    do_load_cr();
228
    RETURN();
229
}
230

    
231
void OPPROTO op_store_cr (void)
232
{
233
    do_store_cr(PARAM1);
234
    RETURN();
235
}
236

    
237
void OPPROTO op_load_cro (void)
238
{
239
    T0 = env->crf[PARAM1];
240
    RETURN();
241
}
242

    
243
void OPPROTO op_store_cro (void)
244
{
245
    env->crf[PARAM1] = T0;
246
    RETURN();
247
}
248

    
249
void OPPROTO op_load_xer_cr (void)
250
{
251
    T0 = (xer_so << 3) | (xer_ov << 2) | (xer_ca << 1);
252
    RETURN();
253
}
254

    
255
void OPPROTO op_clear_xer_ov (void)
256
{
257
    xer_so = 0;
258
    xer_ov = 0;
259
    RETURN();
260
}
261

    
262
void OPPROTO op_clear_xer_ca (void)
263
{
264
    xer_ca = 0;
265
    RETURN();
266
}
267

    
268
void OPPROTO op_load_xer_bc (void)
269
{
270
    T1 = xer_bc;
271
    RETURN();
272
}
273

    
274
void OPPROTO op_store_xer_bc (void)
275
{
276
    xer_bc = T0;
277
    RETURN();
278
}
279

    
280
void OPPROTO op_load_xer (void)
281
{
282
    T0 = hreg_load_xer(env);
283
    RETURN();
284
}
285

    
286
void OPPROTO op_store_xer (void)
287
{
288
    hreg_store_xer(env, T0);
289
    RETURN();
290
}
291

    
292
#if defined(TARGET_PPC64)
293
void OPPROTO op_store_pri (void)
294
{
295
    do_store_pri(PARAM1);
296
    RETURN();
297
}
298
#endif
299

    
300
#if !defined(CONFIG_USER_ONLY)
301
/* Segment registers load and store */
302
void OPPROTO op_load_sr (void)
303
{
304
    T0 = env->sr[T1];
305
    RETURN();
306
}
307

    
308
void OPPROTO op_store_sr (void)
309
{
310
    do_store_sr(env, T1, T0);
311
    RETURN();
312
}
313

    
314
#if defined(TARGET_PPC64)
315
void OPPROTO op_load_slb (void)
316
{
317
    T0 = ppc_load_slb(env, T1);
318
    RETURN();
319
}
320

    
321
void OPPROTO op_store_slb (void)
322
{
323
    ppc_store_slb(env, T1, T0);
324
    RETURN();
325
}
326
#endif /* defined(TARGET_PPC64) */
327

    
328
void OPPROTO op_load_sdr1 (void)
329
{
330
    T0 = env->sdr1;
331
    RETURN();
332
}
333

    
334
void OPPROTO op_store_sdr1 (void)
335
{
336
    do_store_sdr1(env, T0);
337
    RETURN();
338
}
339

    
340
#if defined (TARGET_PPC64)
341
void OPPROTO op_load_asr (void)
342
{
343
    T0 = env->asr;
344
    RETURN();
345
}
346

    
347
void OPPROTO op_store_asr (void)
348
{
349
    ppc_store_asr(env, T0);
350
    RETURN();
351
}
352
#endif
353

    
354
void OPPROTO op_load_msr (void)
355
{
356
    T0 = env->msr;
357
    RETURN();
358
}
359

    
360
void OPPROTO op_store_msr (void)
361
{
362
    do_store_msr();
363
    RETURN();
364
}
365

    
366
#if defined (TARGET_PPC64)
367
void OPPROTO op_store_msr_32 (void)
368
{
369
    T0 = (env->msr & ~0xFFFFFFFFULL) | (T0 & 0xFFFFFFFF);
370
    do_store_msr();
371
    RETURN();
372
}
373
#endif
374

    
375
void OPPROTO op_update_riee (void)
376
{
377
    /* We don't call do_store_msr here as we won't trigger
378
     * any special case nor change hflags
379
     */
380
    T0 &= (1 << MSR_RI) | (1 << MSR_EE);
381
    env->msr &= ~(1 << MSR_RI) | (1 << MSR_EE);
382
    env->msr |= T0;
383
    RETURN();
384
}
385
#endif
386

    
387
/* SPR */
388
void OPPROTO op_load_spr (void)
389
{
390
    T0 = env->spr[PARAM1];
391
    RETURN();
392
}
393

    
394
void OPPROTO op_store_spr (void)
395
{
396
    env->spr[PARAM1] = T0;
397
    RETURN();
398
}
399

    
400
void OPPROTO op_load_dump_spr (void)
401
{
402
    T0 = ppc_load_dump_spr(PARAM1);
403
    RETURN();
404
}
405

    
406
void OPPROTO op_store_dump_spr (void)
407
{
408
    ppc_store_dump_spr(PARAM1, T0);
409
    RETURN();
410
}
411

    
412
void OPPROTO op_mask_spr (void)
413
{
414
    env->spr[PARAM1] &= ~T0;
415
    RETURN();
416
}
417

    
418
void OPPROTO op_load_lr (void)
419
{
420
    T0 = env->lr;
421
    RETURN();
422
}
423

    
424
void OPPROTO op_store_lr (void)
425
{
426
    env->lr = T0;
427
    RETURN();
428
}
429

    
430
void OPPROTO op_load_ctr (void)
431
{
432
    T0 = env->ctr;
433
    RETURN();
434
}
435

    
436
void OPPROTO op_store_ctr (void)
437
{
438
    env->ctr = T0;
439
    RETURN();
440
}
441

    
442
void OPPROTO op_load_tbl (void)
443
{
444
    T0 = cpu_ppc_load_tbl(env);
445
    RETURN();
446
}
447

    
448
void OPPROTO op_load_tbu (void)
449
{
450
    T0 = cpu_ppc_load_tbu(env);
451
    RETURN();
452
}
453

    
454
void OPPROTO op_load_atbl (void)
455
{
456
    T0 = cpu_ppc_load_atbl(env);
457
    RETURN();
458
}
459

    
460
void OPPROTO op_load_atbu (void)
461
{
462
    T0 = cpu_ppc_load_atbu(env);
463
    RETURN();
464
}
465

    
466
#if !defined(CONFIG_USER_ONLY)
467
void OPPROTO op_store_tbl (void)
468
{
469
    cpu_ppc_store_tbl(env, T0);
470
    RETURN();
471
}
472

    
473
void OPPROTO op_store_tbu (void)
474
{
475
    cpu_ppc_store_tbu(env, T0);
476
    RETURN();
477
}
478

    
479
void OPPROTO op_store_atbl (void)
480
{
481
    cpu_ppc_store_atbl(env, T0);
482
    RETURN();
483
}
484

    
485
void OPPROTO op_store_atbu (void)
486
{
487
    cpu_ppc_store_atbu(env, T0);
488
    RETURN();
489
}
490

    
491
void OPPROTO op_load_decr (void)
492
{
493
    T0 = cpu_ppc_load_decr(env);
494
    RETURN();
495
}
496

    
497
void OPPROTO op_store_decr (void)
498
{
499
    cpu_ppc_store_decr(env, T0);
500
    RETURN();
501
}
502

    
503
void OPPROTO op_load_ibat (void)
504
{
505
    T0 = env->IBAT[PARAM1][PARAM2];
506
    RETURN();
507
}
508

    
509
void OPPROTO op_store_ibatu (void)
510
{
511
    do_store_ibatu(env, PARAM1, T0);
512
    RETURN();
513
}
514

    
515
void OPPROTO op_store_ibatl (void)
516
{
517
#if 1
518
    env->IBAT[1][PARAM1] = T0;
519
#else
520
    do_store_ibatl(env, PARAM1, T0);
521
#endif
522
    RETURN();
523
}
524

    
525
void OPPROTO op_load_dbat (void)
526
{
527
    T0 = env->DBAT[PARAM1][PARAM2];
528
    RETURN();
529
}
530

    
531
void OPPROTO op_store_dbatu (void)
532
{
533
    do_store_dbatu(env, PARAM1, T0);
534
    RETURN();
535
}
536

    
537
void OPPROTO op_store_dbatl (void)
538
{
539
#if 1
540
    env->DBAT[1][PARAM1] = T0;
541
#else
542
    do_store_dbatl(env, PARAM1, T0);
543
#endif
544
    RETURN();
545
}
546
#endif /* !defined(CONFIG_USER_ONLY) */
547

    
548
/* FPSCR */
549
#ifdef CONFIG_SOFTFLOAT
550
void OPPROTO op_reset_fpstatus (void)
551
{
552
    env->fp_status.float_exception_flags = 0;
553
    RETURN();
554
}
555
#endif
556

    
557
void OPPROTO op_compute_fprf (void)
558
{
559
    do_compute_fprf(PARAM1);
560
    RETURN();
561
}
562

    
563
#ifdef CONFIG_SOFTFLOAT
564
void OPPROTO op_float_check_status (void)
565
{
566
    do_float_check_status();
567
    RETURN();
568
}
569
#else
570
void OPPROTO op_float_check_status (void)
571
{
572
    if (env->exception_index == POWERPC_EXCP_PROGRAM &&
573
        (env->error_code & POWERPC_EXCP_FP)) {
574
        /* Differred floating-point exception after target FPR update */
575
        if (msr_fe0 != 0 || msr_fe1 != 0)
576
            do_raise_exception_err(env->exception_index, env->error_code);
577
    }
578
    RETURN();
579
}
580
#endif
581

    
582
#if defined(WORDS_BIGENDIAN)
583
#define WORD0 0
584
#define WORD1 1
585
#else
586
#define WORD0 1
587
#define WORD1 0
588
#endif
589
void OPPROTO op_load_fpscr_FT0 (void)
590
{
591
    /* The 32 MSB of the target fpr are undefined.
592
     * They'll be zero...
593
     */
594
    union {
595
        float64 d;
596
        struct {
597
            uint32_t u[2];
598
        } s;
599
    } u;
600

    
601
    u.s.u[WORD0] = 0;
602
    u.s.u[WORD1] = env->fpscr;
603
    FT0 = u.d;
604
    RETURN();
605
}
606

    
607
void OPPROTO op_set_FT0 (void)
608
{
609
    union {
610
        float64 d;
611
        struct {
612
            uint32_t u[2];
613
        } s;
614
    } u;
615

    
616
    u.s.u[WORD0] = 0;
617
    u.s.u[WORD1] = PARAM1;
618
    FT0 = u.d;
619
    RETURN();
620
}
621
#undef WORD0
622
#undef WORD1
623

    
624
void OPPROTO op_load_fpscr_T0 (void)
625
{
626
    T0 = (env->fpscr >> PARAM1) & 0xF;
627
    RETURN();
628
}
629

    
630
void OPPROTO op_load_fpcc (void)
631
{
632
    T0 = fpscr_fpcc;
633
    RETURN();
634
}
635

    
636
void OPPROTO op_fpscr_resetbit (void)
637
{
638
    env->fpscr &= PARAM1;
639
    RETURN();
640
}
641

    
642
void OPPROTO op_fpscr_setbit (void)
643
{
644
    do_fpscr_setbit(PARAM1);
645
    RETURN();
646
}
647

    
648
void OPPROTO op_store_fpscr (void)
649
{
650
    do_store_fpscr(PARAM1);
651
    RETURN();
652
}
653

    
654
/* crf operations */
655
void OPPROTO op_getbit_T0 (void)
656
{
657
    T0 = (T0 >> PARAM1) & 1;
658
    RETURN();
659
}
660

    
661
void OPPROTO op_getbit_T1 (void)
662
{
663
    T1 = (T1 >> PARAM1) & 1;
664
    RETURN();
665
}
666

    
667
void OPPROTO op_setcrfbit (void)
668
{
669
    T1 = (T1 & (uint32_t)PARAM1) | (T0 << PARAM2);
670
    RETURN();
671
}
672

    
673
/* Branch */
674
#define EIP env->nip
675

    
676
void OPPROTO op_setlr (void)
677
{
678
    env->lr = (uint32_t)PARAM1;
679
    RETURN();
680
}
681

    
682
#if defined (TARGET_PPC64)
683
void OPPROTO op_setlr_64 (void)
684
{
685
    env->lr = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
686
    RETURN();
687
}
688
#endif
689

    
690
void OPPROTO op_goto_tb0 (void)
691
{
692
    GOTO_TB(op_goto_tb0, PARAM1, 0);
693
}
694

    
695
void OPPROTO op_goto_tb1 (void)
696
{
697
    GOTO_TB(op_goto_tb1, PARAM1, 1);
698
}
699

    
700
void OPPROTO op_b_T1 (void)
701
{
702
    env->nip = (uint32_t)(T1 & ~3);
703
    RETURN();
704
}
705

    
706
#if defined (TARGET_PPC64)
707
void OPPROTO op_b_T1_64 (void)
708
{
709
    env->nip = (uint64_t)(T1 & ~3);
710
    RETURN();
711
}
712
#endif
713

    
714
void OPPROTO op_jz_T0 (void)
715
{
716
    if (!T0)
717
        GOTO_LABEL_PARAM(1);
718
    RETURN();
719
}
720

    
721
void OPPROTO op_btest_T1 (void)
722
{
723
    if (T0) {
724
        env->nip = (uint32_t)(T1 & ~3);
725
    } else {
726
        env->nip = (uint32_t)PARAM1;
727
    }
728
    RETURN();
729
}
730

    
731
#if defined (TARGET_PPC64)
732
void OPPROTO op_btest_T1_64 (void)
733
{
734
    if (T0) {
735
        env->nip = (uint64_t)(T1 & ~3);
736
    } else {
737
        env->nip = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
738
    }
739
    RETURN();
740
}
741
#endif
742

    
743
void OPPROTO op_movl_T1_ctr (void)
744
{
745
    T1 = env->ctr;
746
    RETURN();
747
}
748

    
749
void OPPROTO op_movl_T1_lr (void)
750
{
751
    T1 = env->lr;
752
    RETURN();
753
}
754

    
755
/* tests with result in T0 */
756
void OPPROTO op_test_ctr (void)
757
{
758
    T0 = (uint32_t)env->ctr;
759
    RETURN();
760
}
761

    
762
#if defined(TARGET_PPC64)
763
void OPPROTO op_test_ctr_64 (void)
764
{
765
    T0 = (uint64_t)env->ctr;
766
    RETURN();
767
}
768
#endif
769

    
770
void OPPROTO op_test_ctr_true (void)
771
{
772
    T0 = ((uint32_t)env->ctr != 0 && (T0 & PARAM1) != 0);
773
    RETURN();
774
}
775

    
776
#if defined(TARGET_PPC64)
777
void OPPROTO op_test_ctr_true_64 (void)
778
{
779
    T0 = ((uint64_t)env->ctr != 0 && (T0 & PARAM1) != 0);
780
    RETURN();
781
}
782
#endif
783

    
784
void OPPROTO op_test_ctr_false (void)
785
{
786
    T0 = ((uint32_t)env->ctr != 0 && (T0 & PARAM1) == 0);
787
    RETURN();
788
}
789

    
790
#if defined(TARGET_PPC64)
791
void OPPROTO op_test_ctr_false_64 (void)
792
{
793
    T0 = ((uint64_t)env->ctr != 0 && (T0 & PARAM1) == 0);
794
    RETURN();
795
}
796
#endif
797

    
798
void OPPROTO op_test_ctrz (void)
799
{
800
    T0 = ((uint32_t)env->ctr == 0);
801
    RETURN();
802
}
803

    
804
#if defined(TARGET_PPC64)
805
void OPPROTO op_test_ctrz_64 (void)
806
{
807
    T0 = ((uint64_t)env->ctr == 0);
808
    RETURN();
809
}
810
#endif
811

    
812
void OPPROTO op_test_ctrz_true (void)
813
{
814
    T0 = ((uint32_t)env->ctr == 0 && (T0 & PARAM1) != 0);
815
    RETURN();
816
}
817

    
818
#if defined(TARGET_PPC64)
819
void OPPROTO op_test_ctrz_true_64 (void)
820
{
821
    T0 = ((uint64_t)env->ctr == 0 && (T0 & PARAM1) != 0);
822
    RETURN();
823
}
824
#endif
825

    
826
void OPPROTO op_test_ctrz_false (void)
827
{
828
    T0 = ((uint32_t)env->ctr == 0 && (T0 & PARAM1) == 0);
829
    RETURN();
830
}
831

    
832
#if defined(TARGET_PPC64)
833
void OPPROTO op_test_ctrz_false_64 (void)
834
{
835
    T0 = ((uint64_t)env->ctr == 0 && (T0 & PARAM1) == 0);
836
    RETURN();
837
}
838
#endif
839

    
840
void OPPROTO op_test_true (void)
841
{
842
    T0 = (T0 & PARAM1);
843
    RETURN();
844
}
845

    
846
void OPPROTO op_test_false (void)
847
{
848
    T0 = ((T0 & PARAM1) == 0);
849
    RETURN();
850
}
851

    
852
/* CTR maintenance */
853
void OPPROTO op_dec_ctr (void)
854
{
855
    env->ctr--;
856
    RETURN();
857
}
858

    
859
/***                           Integer arithmetic                          ***/
860
/* add */
861
void OPPROTO op_add (void)
862
{
863
    T0 += T1;
864
    RETURN();
865
}
866

    
867
void OPPROTO op_check_addo (void)
868
{
869
    if (likely(!(((uint32_t)T2 ^ (uint32_t)T1 ^ UINT32_MAX) &
870
                 ((uint32_t)T2 ^ (uint32_t)T0) & (1UL << 31)))) {
871
        xer_ov = 0;
872
    } else {
873
        xer_ov = 1;
874
        xer_so = 1;
875
    }
876
    RETURN();
877
}
878

    
879
#if defined(TARGET_PPC64)
880
void OPPROTO op_check_addo_64 (void)
881
{
882
    if (likely(!(((uint64_t)T2 ^ (uint64_t)T1 ^ UINT64_MAX) &
883
                 ((uint64_t)T2 ^ (uint64_t)T0) & (1ULL << 63)))) {
884
        xer_ov = 0;
885
    } else {
886
        xer_ov = 1;
887
        xer_so = 1;
888
    }
889
    RETURN();
890
}
891
#endif
892

    
893
/* add carrying */
894
void OPPROTO op_check_addc (void)
895
{
896
    if (likely((uint32_t)T0 >= (uint32_t)T2)) {
897
        xer_ca = 0;
898
    } else {
899
        xer_ca = 1;
900
    }
901
    RETURN();
902
}
903

    
904
#if defined(TARGET_PPC64)
905
void OPPROTO op_check_addc_64 (void)
906
{
907
    if (likely((uint64_t)T0 >= (uint64_t)T2)) {
908
        xer_ca = 0;
909
    } else {
910
        xer_ca = 1;
911
    }
912
    RETURN();
913
}
914
#endif
915

    
916
/* add extended */
917
void OPPROTO op_adde (void)
918
{
919
    do_adde();
920
    RETURN();
921
}
922

    
923
#if defined(TARGET_PPC64)
924
void OPPROTO op_adde_64 (void)
925
{
926
    do_adde_64();
927
    RETURN();
928
}
929
#endif
930

    
931
/* add immediate */
932
void OPPROTO op_addi (void)
933
{
934
    T0 += (int32_t)PARAM1;
935
    RETURN();
936
}
937

    
938
/* add to minus one extended */
939
void OPPROTO op_add_me (void)
940
{
941
    T0 += xer_ca + (-1);
942
    if (likely((uint32_t)T1 != 0))
943
        xer_ca = 1;
944
    RETURN();
945
}
946

    
947
#if defined(TARGET_PPC64)
948
void OPPROTO op_add_me_64 (void)
949
{
950
    T0 += xer_ca + (-1);
951
    if (likely((uint64_t)T1 != 0))
952
        xer_ca = 1;
953
    RETURN();
954
}
955
#endif
956

    
957
void OPPROTO op_addmeo (void)
958
{
959
    do_addmeo();
960
    RETURN();
961
}
962

    
963
void OPPROTO op_addmeo_64 (void)
964
{
965
    do_addmeo();
966
    RETURN();
967
}
968

    
969
/* add to zero extended */
970
void OPPROTO op_add_ze (void)
971
{
972
    T0 += xer_ca;
973
    RETURN();
974
}
975

    
976
/* divide word */
977
void OPPROTO op_divw (void)
978
{
979
    if (unlikely(((int32_t)T0 == INT32_MIN && (int32_t)T1 == -1) ||
980
                 (int32_t)T1 == 0)) {
981
        T0 = (int32_t)((-1) * ((uint32_t)T0 >> 31));
982
    } else {
983
        T0 = (int32_t)T0 / (int32_t)T1;
984
    }
985
    RETURN();
986
}
987

    
988
#if defined(TARGET_PPC64)
989
void OPPROTO op_divd (void)
990
{
991
    if (unlikely(((int64_t)T0 == INT64_MIN && (int64_t)T1 == -1) ||
992
                 (int64_t)T1 == 0)) {
993
        T0 = (int64_t)((-1ULL) * ((uint64_t)T0 >> 63));
994
    } else {
995
        T0 = (int64_t)T0 / (int64_t)T1;
996
    }
997
    RETURN();
998
}
999
#endif
1000

    
1001
void OPPROTO op_divwo (void)
1002
{
1003
    do_divwo();
1004
    RETURN();
1005
}
1006

    
1007
#if defined(TARGET_PPC64)
1008
void OPPROTO op_divdo (void)
1009
{
1010
    do_divdo();
1011
    RETURN();
1012
}
1013
#endif
1014

    
1015
/* divide word unsigned */
1016
void OPPROTO op_divwu (void)
1017
{
1018
    if (unlikely(T1 == 0)) {
1019
        T0 = 0;
1020
    } else {
1021
        T0 = (uint32_t)T0 / (uint32_t)T1;
1022
    }
1023
    RETURN();
1024
}
1025

    
1026
#if defined(TARGET_PPC64)
1027
void OPPROTO op_divdu (void)
1028
{
1029
    if (unlikely(T1 == 0)) {
1030
        T0 = 0;
1031
    } else {
1032
        T0 /= T1;
1033
    }
1034
    RETURN();
1035
}
1036
#endif
1037

    
1038
void OPPROTO op_divwuo (void)
1039
{
1040
    do_divwuo();
1041
    RETURN();
1042
}
1043

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

    
1052
/* multiply high word */
1053
void OPPROTO op_mulhw (void)
1054
{
1055
    T0 = ((int64_t)((int32_t)T0) * (int64_t)((int32_t)T1)) >> 32;
1056
    RETURN();
1057
}
1058

    
1059
#if defined(TARGET_PPC64)
1060
void OPPROTO op_mulhd (void)
1061
{
1062
    uint64_t tl, th;
1063

    
1064
    muls64(&tl, &th, T0, T1);
1065
    T0 = th;
1066
    RETURN();
1067
}
1068
#endif
1069

    
1070
/* multiply high word unsigned */
1071
void OPPROTO op_mulhwu (void)
1072
{
1073
    T0 = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1) >> 32;
1074
    RETURN();
1075
}
1076

    
1077
#if defined(TARGET_PPC64)
1078
void OPPROTO op_mulhdu (void)
1079
{
1080
    uint64_t tl, th;
1081

    
1082
    mulu64(&tl, &th, T0, T1);
1083
    T0 = th;
1084
    RETURN();
1085
}
1086
#endif
1087

    
1088
/* multiply low immediate */
1089
void OPPROTO op_mulli (void)
1090
{
1091
    T0 = ((int32_t)T0 * (int32_t)PARAM1);
1092
    RETURN();
1093
}
1094

    
1095
/* multiply low word */
1096
void OPPROTO op_mullw (void)
1097
{
1098
    T0 = (int32_t)(T0 * T1);
1099
    RETURN();
1100
}
1101

    
1102
#if defined(TARGET_PPC64)
1103
void OPPROTO op_mulld (void)
1104
{
1105
    T0 *= T1;
1106
    RETURN();
1107
}
1108
#endif
1109

    
1110
void OPPROTO op_mullwo (void)
1111
{
1112
    do_mullwo();
1113
    RETURN();
1114
}
1115

    
1116
#if defined(TARGET_PPC64)
1117
void OPPROTO op_mulldo (void)
1118
{
1119
    do_mulldo();
1120
    RETURN();
1121
}
1122
#endif
1123

    
1124
/* negate */
1125
void OPPROTO op_neg (void)
1126
{
1127
    if (likely(T0 != INT32_MIN)) {
1128
        T0 = -(int32_t)T0;
1129
    }
1130
    RETURN();
1131
}
1132

    
1133
#if defined(TARGET_PPC64)
1134
void OPPROTO op_neg_64 (void)
1135
{
1136
    if (likely(T0 != INT64_MIN)) {
1137
        T0 = -(int64_t)T0;
1138
    }
1139
    RETURN();
1140
}
1141
#endif
1142

    
1143
void OPPROTO op_nego (void)
1144
{
1145
    do_nego();
1146
    RETURN();
1147
}
1148

    
1149
#if defined(TARGET_PPC64)
1150
void OPPROTO op_nego_64 (void)
1151
{
1152
    do_nego_64();
1153
    RETURN();
1154
}
1155
#endif
1156

    
1157
/* subtract from */
1158
void OPPROTO op_subf (void)
1159
{
1160
    T0 = T1 - T0;
1161
    RETURN();
1162
}
1163

    
1164
void OPPROTO op_check_subfo (void)
1165
{
1166
    if (likely(!(((uint32_t)(~T2) ^ (uint32_t)T1 ^ UINT32_MAX) &
1167
                 ((uint32_t)(~T2) ^ (uint32_t)T0) & (1UL << 31)))) {
1168
        xer_ov = 0;
1169
    } else {
1170
        xer_ov = 1;
1171
        xer_so = 1;
1172
    }
1173
    RETURN();
1174
}
1175

    
1176
#if defined(TARGET_PPC64)
1177
void OPPROTO op_check_subfo_64 (void)
1178
{
1179
    if (likely(!(((uint64_t)(~T2) ^ (uint64_t)T1 ^ UINT64_MAX) &
1180
                 ((uint64_t)(~T2) ^ (uint64_t)T0) & (1ULL << 63)))) {
1181
        xer_ov = 0;
1182
    } else {
1183
        xer_ov = 1;
1184
        xer_so = 1;
1185
    }
1186
    RETURN();
1187
}
1188
#endif
1189

    
1190
/* subtract from carrying */
1191
void OPPROTO op_check_subfc (void)
1192
{
1193
    if (likely((uint32_t)T0 > (uint32_t)T1)) {
1194
        xer_ca = 0;
1195
    } else {
1196
        xer_ca = 1;
1197
    }
1198
    RETURN();
1199
}
1200

    
1201
#if defined(TARGET_PPC64)
1202
void OPPROTO op_check_subfc_64 (void)
1203
{
1204
    if (likely((uint64_t)T0 > (uint64_t)T1)) {
1205
        xer_ca = 0;
1206
    } else {
1207
        xer_ca = 1;
1208
    }
1209
    RETURN();
1210
}
1211
#endif
1212

    
1213
/* subtract from extended */
1214
void OPPROTO op_subfe (void)
1215
{
1216
    do_subfe();
1217
    RETURN();
1218
}
1219

    
1220
#if defined(TARGET_PPC64)
1221
void OPPROTO op_subfe_64 (void)
1222
{
1223
    do_subfe_64();
1224
    RETURN();
1225
}
1226
#endif
1227

    
1228
/* subtract from immediate carrying */
1229
void OPPROTO op_subfic (void)
1230
{
1231
    T0 = (int32_t)PARAM1 + ~T0 + 1;
1232
    if ((uint32_t)T0 <= (uint32_t)PARAM1) {
1233
        xer_ca = 1;
1234
    } else {
1235
        xer_ca = 0;
1236
    }
1237
    RETURN();
1238
}
1239

    
1240
#if defined(TARGET_PPC64)
1241
void OPPROTO op_subfic_64 (void)
1242
{
1243
    T0 = (int64_t)PARAM1 + ~T0 + 1;
1244
    if ((uint64_t)T0 <= (uint64_t)PARAM1) {
1245
        xer_ca = 1;
1246
    } else {
1247
        xer_ca = 0;
1248
    }
1249
    RETURN();
1250
}
1251
#endif
1252

    
1253
/* subtract from minus one extended */
1254
void OPPROTO op_subfme (void)
1255
{
1256
    T0 = ~T0 + xer_ca - 1;
1257
    if (likely((uint32_t)T0 != (uint32_t)-1))
1258
        xer_ca = 1;
1259
    RETURN();
1260
}
1261

    
1262
#if defined(TARGET_PPC64)
1263
void OPPROTO op_subfme_64 (void)
1264
{
1265
    T0 = ~T0 + xer_ca - 1;
1266
    if (likely((uint64_t)T0 != (uint64_t)-1))
1267
        xer_ca = 1;
1268
    RETURN();
1269
}
1270
#endif
1271

    
1272
void OPPROTO op_subfmeo (void)
1273
{
1274
    do_subfmeo();
1275
    RETURN();
1276
}
1277

    
1278
#if defined(TARGET_PPC64)
1279
void OPPROTO op_subfmeo_64 (void)
1280
{
1281
    do_subfmeo_64();
1282
    RETURN();
1283
}
1284
#endif
1285

    
1286
/* subtract from zero extended */
1287
void OPPROTO op_subfze (void)
1288
{
1289
    T1 = ~T0;
1290
    T0 = T1 + xer_ca;
1291
    if ((uint32_t)T0 < (uint32_t)T1) {
1292
        xer_ca = 1;
1293
    } else {
1294
        xer_ca = 0;
1295
    }
1296
    RETURN();
1297
}
1298

    
1299
#if defined(TARGET_PPC64)
1300
void OPPROTO op_subfze_64 (void)
1301
{
1302
    T1 = ~T0;
1303
    T0 = T1 + xer_ca;
1304
    if ((uint64_t)T0 < (uint64_t)T1) {
1305
        xer_ca = 1;
1306
    } else {
1307
        xer_ca = 0;
1308
    }
1309
    RETURN();
1310
}
1311
#endif
1312

    
1313
void OPPROTO op_subfzeo (void)
1314
{
1315
    do_subfzeo();
1316
    RETURN();
1317
}
1318

    
1319
#if defined(TARGET_PPC64)
1320
void OPPROTO op_subfzeo_64 (void)
1321
{
1322
    do_subfzeo_64();
1323
    RETURN();
1324
}
1325
#endif
1326

    
1327
/***                           Integer comparison                          ***/
1328
/* compare */
1329
void OPPROTO op_cmp (void)
1330
{
1331
    if ((int32_t)T0 < (int32_t)T1) {
1332
        T0 = 0x08;
1333
    } else if ((int32_t)T0 > (int32_t)T1) {
1334
        T0 = 0x04;
1335
    } else {
1336
        T0 = 0x02;
1337
    }
1338
    T0 |= xer_so;
1339
    RETURN();
1340
}
1341

    
1342
#if defined(TARGET_PPC64)
1343
void OPPROTO op_cmp_64 (void)
1344
{
1345
    if ((int64_t)T0 < (int64_t)T1) {
1346
        T0 = 0x08;
1347
    } else if ((int64_t)T0 > (int64_t)T1) {
1348
        T0 = 0x04;
1349
    } else {
1350
        T0 = 0x02;
1351
    }
1352
    T0 |= xer_so;
1353
    RETURN();
1354
}
1355
#endif
1356

    
1357
/* compare immediate */
1358
void OPPROTO op_cmpi (void)
1359
{
1360
    if ((int32_t)T0 < (int32_t)PARAM1) {
1361
        T0 = 0x08;
1362
    } else if ((int32_t)T0 > (int32_t)PARAM1) {
1363
        T0 = 0x04;
1364
    } else {
1365
        T0 = 0x02;
1366
    }
1367
    T0 |= xer_so;
1368
    RETURN();
1369
}
1370

    
1371
#if defined(TARGET_PPC64)
1372
void OPPROTO op_cmpi_64 (void)
1373
{
1374
    if ((int64_t)T0 < (int64_t)((int32_t)PARAM1)) {
1375
        T0 = 0x08;
1376
    } else if ((int64_t)T0 > (int64_t)((int32_t)PARAM1)) {
1377
        T0 = 0x04;
1378
    } else {
1379
        T0 = 0x02;
1380
    }
1381
    T0 |= xer_so;
1382
    RETURN();
1383
}
1384
#endif
1385

    
1386
/* compare logical */
1387
void OPPROTO op_cmpl (void)
1388
{
1389
    if ((uint32_t)T0 < (uint32_t)T1) {
1390
        T0 = 0x08;
1391
    } else if ((uint32_t)T0 > (uint32_t)T1) {
1392
        T0 = 0x04;
1393
    } else {
1394
        T0 = 0x02;
1395
    }
1396
    T0 |= xer_so;
1397
    RETURN();
1398
}
1399

    
1400
#if defined(TARGET_PPC64)
1401
void OPPROTO op_cmpl_64 (void)
1402
{
1403
    if ((uint64_t)T0 < (uint64_t)T1) {
1404
        T0 = 0x08;
1405
    } else if ((uint64_t)T0 > (uint64_t)T1) {
1406
        T0 = 0x04;
1407
    } else {
1408
        T0 = 0x02;
1409
    }
1410
    T0 |= xer_so;
1411
    RETURN();
1412
}
1413
#endif
1414

    
1415
/* compare logical immediate */
1416
void OPPROTO op_cmpli (void)
1417
{
1418
    if ((uint32_t)T0 < (uint32_t)PARAM1) {
1419
        T0 = 0x08;
1420
    } else if ((uint32_t)T0 > (uint32_t)PARAM1) {
1421
        T0 = 0x04;
1422
    } else {
1423
        T0 = 0x02;
1424
    }
1425
    T0 |= xer_so;
1426
    RETURN();
1427
}
1428

    
1429
#if defined(TARGET_PPC64)
1430
void OPPROTO op_cmpli_64 (void)
1431
{
1432
    if ((uint64_t)T0 < (uint64_t)PARAM1) {
1433
        T0 = 0x08;
1434
    } else if ((uint64_t)T0 > (uint64_t)PARAM1) {
1435
        T0 = 0x04;
1436
    } else {
1437
        T0 = 0x02;
1438
    }
1439
    T0 |= xer_so;
1440
    RETURN();
1441
}
1442
#endif
1443

    
1444
void OPPROTO op_isel (void)
1445
{
1446
    if (T0)
1447
        T0 = T1;
1448
    else
1449
        T0 = T2;
1450
    RETURN();
1451
}
1452

    
1453
void OPPROTO op_popcntb (void)
1454
{
1455
    do_popcntb();
1456
    RETURN();
1457
}
1458

    
1459
#if defined(TARGET_PPC64)
1460
void OPPROTO op_popcntb_64 (void)
1461
{
1462
    do_popcntb_64();
1463
    RETURN();
1464
}
1465
#endif
1466

    
1467
/***                            Integer logical                            ***/
1468
/* and */
1469
void OPPROTO op_and (void)
1470
{
1471
    T0 &= T1;
1472
    RETURN();
1473
}
1474

    
1475
/* andc */
1476
void OPPROTO op_andc (void)
1477
{
1478
    T0 &= ~T1;
1479
    RETURN();
1480
}
1481

    
1482
/* andi. */
1483
void OPPROTO op_andi_T0 (void)
1484
{
1485
    T0 &= (uint32_t)PARAM1;
1486
    RETURN();
1487
}
1488

    
1489
void OPPROTO op_andi_T1 (void)
1490
{
1491
    T1 &= (uint32_t)PARAM1;
1492
    RETURN();
1493
}
1494

    
1495
#if defined(TARGET_PPC64)
1496
void OPPROTO op_andi_T0_64 (void)
1497
{
1498
    T0 &= ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
1499
    RETURN();
1500
}
1501

    
1502
void OPPROTO op_andi_T1_64 (void)
1503
{
1504
    T1 &= ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
1505
    RETURN();
1506
}
1507
#endif
1508

    
1509
/* count leading zero */
1510
void OPPROTO op_cntlzw (void)
1511
{
1512
    do_cntlzw();
1513
    RETURN();
1514
}
1515

    
1516
#if defined(TARGET_PPC64)
1517
void OPPROTO op_cntlzd (void)
1518
{
1519
    do_cntlzd();
1520
    RETURN();
1521
}
1522
#endif
1523

    
1524
/* eqv */
1525
void OPPROTO op_eqv (void)
1526
{
1527
    T0 = ~(T0 ^ T1);
1528
    RETURN();
1529
}
1530

    
1531
/* extend sign byte */
1532
void OPPROTO op_extsb (void)
1533
{
1534
#if defined (TARGET_PPC64)
1535
    T0 = (int64_t)((int8_t)T0);
1536
#else
1537
    T0 = (int32_t)((int8_t)T0);
1538
#endif
1539
    RETURN();
1540
}
1541

    
1542
/* extend sign half word */
1543
void OPPROTO op_extsh (void)
1544
{
1545
#if defined (TARGET_PPC64)
1546
    T0 = (int64_t)((int16_t)T0);
1547
#else
1548
    T0 = (int32_t)((int16_t)T0);
1549
#endif
1550
    RETURN();
1551
}
1552

    
1553
#if defined (TARGET_PPC64)
1554
void OPPROTO op_extsw (void)
1555
{
1556
    T0 = (int64_t)((int32_t)T0);
1557
    RETURN();
1558
}
1559
#endif
1560

    
1561
/* nand */
1562
void OPPROTO op_nand (void)
1563
{
1564
    T0 = ~(T0 & T1);
1565
    RETURN();
1566
}
1567

    
1568
/* nor */
1569
void OPPROTO op_nor (void)
1570
{
1571
    T0 = ~(T0 | T1);
1572
    RETURN();
1573
}
1574

    
1575
/* or */
1576
void OPPROTO op_or (void)
1577
{
1578
    T0 |= T1;
1579
    RETURN();
1580
}
1581

    
1582
/* orc */
1583
void OPPROTO op_orc (void)
1584
{
1585
    T0 |= ~T1;
1586
    RETURN();
1587
}
1588

    
1589
/* ori */
1590
void OPPROTO op_ori (void)
1591
{
1592
    T0 |= (uint32_t)PARAM1;
1593
    RETURN();
1594
}
1595

    
1596
/* xor */
1597
void OPPROTO op_xor (void)
1598
{
1599
    T0 ^= T1;
1600
    RETURN();
1601
}
1602

    
1603
/* xori */
1604
void OPPROTO op_xori (void)
1605
{
1606
    T0 ^= (uint32_t)PARAM1;
1607
    RETURN();
1608
}
1609

    
1610
/***                             Integer rotate                            ***/
1611
void OPPROTO op_rotl32_T0_T1 (void)
1612
{
1613
    T0 = rotl32(T0, T1 & 0x1F);
1614
    RETURN();
1615
}
1616

    
1617
void OPPROTO op_rotli32_T0 (void)
1618
{
1619
    T0 = rotl32(T0, PARAM1);
1620
    RETURN();
1621
}
1622

    
1623
#if defined(TARGET_PPC64)
1624
void OPPROTO op_rotl64_T0_T1 (void)
1625
{
1626
    T0 = rotl64(T0, T1 & 0x3F);
1627
    RETURN();
1628
}
1629

    
1630
void OPPROTO op_rotli64_T0 (void)
1631
{
1632
    T0 = rotl64(T0, PARAM1);
1633
    RETURN();
1634
}
1635
#endif
1636

    
1637
/***                             Integer shift                             ***/
1638
/* shift left word */
1639
void OPPROTO op_slw (void)
1640
{
1641
    if (T1 & 0x20) {
1642
        T0 = 0;
1643
    } else {
1644
        T0 = (uint32_t)(T0 << T1);
1645
    }
1646
    RETURN();
1647
}
1648

    
1649
#if defined(TARGET_PPC64)
1650
void OPPROTO op_sld (void)
1651
{
1652
    if (T1 & 0x40) {
1653
        T0 = 0;
1654
    } else {
1655
        T0 = T0 << T1;
1656
    }
1657
    RETURN();
1658
}
1659
#endif
1660

    
1661
/* shift right algebraic word */
1662
void OPPROTO op_sraw (void)
1663
{
1664
    do_sraw();
1665
    RETURN();
1666
}
1667

    
1668
#if defined(TARGET_PPC64)
1669
void OPPROTO op_srad (void)
1670
{
1671
    do_srad();
1672
    RETURN();
1673
}
1674
#endif
1675

    
1676
/* shift right algebraic word immediate */
1677
void OPPROTO op_srawi (void)
1678
{
1679
    uint32_t mask = (uint32_t)PARAM2;
1680

    
1681
    T0 = (int32_t)T0 >> PARAM1;
1682
    if ((int32_t)T1 < 0 && (T1 & mask) != 0) {
1683
        xer_ca = 1;
1684
    } else {
1685
        xer_ca = 0;
1686
    }
1687
    RETURN();
1688
}
1689

    
1690
#if defined(TARGET_PPC64)
1691
void OPPROTO op_sradi (void)
1692
{
1693
    uint64_t mask = ((uint64_t)PARAM2 << 32) | (uint64_t)PARAM3;
1694

    
1695
    T0 = (int64_t)T0 >> PARAM1;
1696
    if ((int64_t)T1 < 0 && ((uint64_t)T1 & mask) != 0) {
1697
        xer_ca = 1;
1698
    } else {
1699
        xer_ca = 0;
1700
    }
1701
    RETURN();
1702
}
1703
#endif
1704

    
1705
/* shift right word */
1706
void OPPROTO op_srw (void)
1707
{
1708
    if (T1 & 0x20) {
1709
        T0 = 0;
1710
    } else {
1711
        T0 = (uint32_t)T0 >> T1;
1712
    }
1713
    RETURN();
1714
}
1715

    
1716
#if defined(TARGET_PPC64)
1717
void OPPROTO op_srd (void)
1718
{
1719
    if (T1 & 0x40) {
1720
        T0 = 0;
1721
    } else {
1722
        T0 = (uint64_t)T0 >> T1;
1723
    }
1724
    RETURN();
1725
}
1726
#endif
1727

    
1728
void OPPROTO op_sl_T0_T1 (void)
1729
{
1730
    T0 = T0 << T1;
1731
    RETURN();
1732
}
1733

    
1734
void OPPROTO op_sli_T0 (void)
1735
{
1736
    T0 = T0 << PARAM1;
1737
    RETURN();
1738
}
1739

    
1740
void OPPROTO op_srl_T0_T1 (void)
1741
{
1742
    T0 = (uint32_t)T0 >> T1;
1743
    RETURN();
1744
}
1745

    
1746
#if defined(TARGET_PPC64)
1747
void OPPROTO op_srl_T0_T1_64 (void)
1748
{
1749
    T0 = (uint32_t)T0 >> T1;
1750
    RETURN();
1751
}
1752
#endif
1753

    
1754
void OPPROTO op_srli_T0 (void)
1755
{
1756
    T0 = (uint32_t)T0 >> PARAM1;
1757
    RETURN();
1758
}
1759

    
1760
#if defined(TARGET_PPC64)
1761
void OPPROTO op_srli_T0_64 (void)
1762
{
1763
    T0 = (uint64_t)T0 >> PARAM1;
1764
    RETURN();
1765
}
1766
#endif
1767

    
1768
void OPPROTO op_srli_T1 (void)
1769
{
1770
    T1 = (uint32_t)T1 >> PARAM1;
1771
    RETURN();
1772
}
1773

    
1774
#if defined(TARGET_PPC64)
1775
void OPPROTO op_srli_T1_64 (void)
1776
{
1777
    T1 = (uint64_t)T1 >> PARAM1;
1778
    RETURN();
1779
}
1780
#endif
1781

    
1782
/***                       Floating-Point arithmetic                       ***/
1783
/* fadd - fadd. */
1784
void OPPROTO op_fadd (void)
1785
{
1786
#if USE_PRECISE_EMULATION
1787
    do_fadd();
1788
#else
1789
    FT0 = float64_add(FT0, FT1, &env->fp_status);
1790
#endif
1791
    RETURN();
1792
}
1793

    
1794
/* fsub - fsub. */
1795
void OPPROTO op_fsub (void)
1796
{
1797
#if USE_PRECISE_EMULATION
1798
    do_fsub();
1799
#else
1800
    FT0 = float64_sub(FT0, FT1, &env->fp_status);
1801
#endif
1802
    RETURN();
1803
}
1804

    
1805
/* fmul - fmul. */
1806
void OPPROTO op_fmul (void)
1807
{
1808
#if USE_PRECISE_EMULATION
1809
    do_fmul();
1810
#else
1811
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1812
#endif
1813
    RETURN();
1814
}
1815

    
1816
/* fdiv - fdiv. */
1817
void OPPROTO op_fdiv (void)
1818
{
1819
#if USE_PRECISE_EMULATION
1820
    do_fdiv();
1821
#else
1822
    FT0 = float64_div(FT0, FT1, &env->fp_status);
1823
#endif
1824
    RETURN();
1825
}
1826

    
1827
/* fsqrt - fsqrt. */
1828
void OPPROTO op_fsqrt (void)
1829
{
1830
    do_fsqrt();
1831
    RETURN();
1832
}
1833

    
1834
/* fre - fre. */
1835
void OPPROTO op_fre (void)
1836
{
1837
    do_fre();
1838
    RETURN();
1839
}
1840

    
1841
/* fres - fres. */
1842
void OPPROTO op_fres (void)
1843
{
1844
    do_fres();
1845
    RETURN();
1846
}
1847

    
1848
/* frsqrte  - frsqrte. */
1849
void OPPROTO op_frsqrte (void)
1850
{
1851
    do_frsqrte();
1852
    RETURN();
1853
}
1854

    
1855
/* fsel - fsel. */
1856
void OPPROTO op_fsel (void)
1857
{
1858
    do_fsel();
1859
    RETURN();
1860
}
1861

    
1862
/***                     Floating-Point multiply-and-add                   ***/
1863
/* fmadd - fmadd. */
1864
void OPPROTO op_fmadd (void)
1865
{
1866
#if USE_PRECISE_EMULATION
1867
    do_fmadd();
1868
#else
1869
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1870
    FT0 = float64_add(FT0, FT2, &env->fp_status);
1871
#endif
1872
    RETURN();
1873
}
1874

    
1875
/* fmsub - fmsub. */
1876
void OPPROTO op_fmsub (void)
1877
{
1878
#if USE_PRECISE_EMULATION
1879
    do_fmsub();
1880
#else
1881
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1882
    FT0 = float64_sub(FT0, FT2, &env->fp_status);
1883
#endif
1884
    RETURN();
1885
}
1886

    
1887
/* fnmadd - fnmadd. - fnmadds - fnmadds. */
1888
void OPPROTO op_fnmadd (void)
1889
{
1890
    do_fnmadd();
1891
    RETURN();
1892
}
1893

    
1894
/* fnmsub - fnmsub. */
1895
void OPPROTO op_fnmsub (void)
1896
{
1897
    do_fnmsub();
1898
    RETURN();
1899
}
1900

    
1901
/***                     Floating-Point round & convert                    ***/
1902
/* frsp - frsp. */
1903
void OPPROTO op_frsp (void)
1904
{
1905
#if USE_PRECISE_EMULATION
1906
    do_frsp();
1907
#else
1908
    FT0 = float64_to_float32(FT0, &env->fp_status);
1909
#endif
1910
    RETURN();
1911
}
1912

    
1913
/* fctiw - fctiw. */
1914
void OPPROTO op_fctiw (void)
1915
{
1916
    do_fctiw();
1917
    RETURN();
1918
}
1919

    
1920
/* fctiwz - fctiwz. */
1921
void OPPROTO op_fctiwz (void)
1922
{
1923
    do_fctiwz();
1924
    RETURN();
1925
}
1926

    
1927
#if defined(TARGET_PPC64)
1928
/* fcfid - fcfid. */
1929
void OPPROTO op_fcfid (void)
1930
{
1931
    do_fcfid();
1932
    RETURN();
1933
}
1934

    
1935
/* fctid - fctid. */
1936
void OPPROTO op_fctid (void)
1937
{
1938
    do_fctid();
1939
    RETURN();
1940
}
1941

    
1942
/* fctidz - fctidz. */
1943
void OPPROTO op_fctidz (void)
1944
{
1945
    do_fctidz();
1946
    RETURN();
1947
}
1948
#endif
1949

    
1950
void OPPROTO op_frin (void)
1951
{
1952
    do_frin();
1953
    RETURN();
1954
}
1955

    
1956
void OPPROTO op_friz (void)
1957
{
1958
    do_friz();
1959
    RETURN();
1960
}
1961

    
1962
void OPPROTO op_frip (void)
1963
{
1964
    do_frip();
1965
    RETURN();
1966
}
1967

    
1968
void OPPROTO op_frim (void)
1969
{
1970
    do_frim();
1971
    RETURN();
1972
}
1973

    
1974
/***                         Floating-Point compare                        ***/
1975
/* fcmpu */
1976
void OPPROTO op_fcmpu (void)
1977
{
1978
    do_fcmpu();
1979
    RETURN();
1980
}
1981

    
1982
/* fcmpo */
1983
void OPPROTO op_fcmpo (void)
1984
{
1985
    do_fcmpo();
1986
    RETURN();
1987
}
1988

    
1989
/***                         Floating-point move                           ***/
1990
/* fabs */
1991
void OPPROTO op_fabs (void)
1992
{
1993
    FT0 = float64_abs(FT0);
1994
    RETURN();
1995
}
1996

    
1997
/* fnabs */
1998
void OPPROTO op_fnabs (void)
1999
{
2000
    FT0 = float64_abs(FT0);
2001
    FT0 = float64_chs(FT0);
2002
    RETURN();
2003
}
2004

    
2005
/* fneg */
2006
void OPPROTO op_fneg (void)
2007
{
2008
    FT0 = float64_chs(FT0);
2009
    RETURN();
2010
}
2011

    
2012
/* Load and store */
2013
#define MEMSUFFIX _raw
2014
#include "op_helper.h"
2015
#include "op_mem.h"
2016
#if !defined(CONFIG_USER_ONLY)
2017
#define MEMSUFFIX _user
2018
#include "op_helper.h"
2019
#include "op_mem.h"
2020
#define MEMSUFFIX _kernel
2021
#include "op_helper.h"
2022
#include "op_mem.h"
2023
#if defined(TARGET_PPC64H)
2024
#define MEMSUFFIX _hypv
2025
#include "op_helper.h"
2026
#include "op_mem.h"
2027
#endif
2028
#endif
2029

    
2030
/* Special op to check and maybe clear reservation */
2031
void OPPROTO op_check_reservation (void)
2032
{
2033
    if ((uint32_t)env->reserve == (uint32_t)(T0 & ~0x00000003))
2034
        env->reserve = -1;
2035
    RETURN();
2036
}
2037

    
2038
#if defined(TARGET_PPC64)
2039
void OPPROTO op_check_reservation_64 (void)
2040
{
2041
    if ((uint64_t)env->reserve == (uint64_t)(T0 & ~0x00000003))
2042
        env->reserve = -1;
2043
    RETURN();
2044
}
2045
#endif
2046

    
2047
void OPPROTO op_wait (void)
2048
{
2049
    env->halted = 1;
2050
    RETURN();
2051
}
2052

    
2053
/* Return from interrupt */
2054
#if !defined(CONFIG_USER_ONLY)
2055
void OPPROTO op_rfi (void)
2056
{
2057
    do_rfi();
2058
    RETURN();
2059
}
2060

    
2061
#if defined(TARGET_PPC64)
2062
void OPPROTO op_rfid (void)
2063
{
2064
    do_rfid();
2065
    RETURN();
2066
}
2067
#endif
2068

    
2069
#if defined(TARGET_PPC64H)
2070
void OPPROTO op_hrfid (void)
2071
{
2072
    do_hrfid();
2073
    RETURN();
2074
}
2075
#endif
2076

    
2077
/* Exception vectors */
2078
void OPPROTO op_store_excp_prefix (void)
2079
{
2080
    T0 &= env->ivpr_mask;
2081
    env->excp_prefix = T0;
2082
    RETURN();
2083
}
2084

    
2085
void OPPROTO op_store_excp_vector (void)
2086
{
2087
    T0 &= env->ivor_mask;
2088
    env->excp_vectors[PARAM1] = T0;
2089
    RETURN();
2090
}
2091
#endif
2092

    
2093
/* Trap word */
2094
void OPPROTO op_tw (void)
2095
{
2096
    do_tw(PARAM1);
2097
    RETURN();
2098
}
2099

    
2100
#if defined(TARGET_PPC64)
2101
void OPPROTO op_td (void)
2102
{
2103
    do_td(PARAM1);
2104
    RETURN();
2105
}
2106
#endif
2107

    
2108
#if !defined(CONFIG_USER_ONLY)
2109
/* tlbia */
2110
void OPPROTO op_tlbia (void)
2111
{
2112
    ppc_tlb_invalidate_all(env);
2113
    RETURN();
2114
}
2115

    
2116
/* tlbie */
2117
void OPPROTO op_tlbie (void)
2118
{
2119
    ppc_tlb_invalidate_one(env, (uint32_t)T0);
2120
    RETURN();
2121
}
2122

    
2123
#if defined(TARGET_PPC64)
2124
void OPPROTO op_tlbie_64 (void)
2125
{
2126
    ppc_tlb_invalidate_one(env, T0);
2127
    RETURN();
2128
}
2129
#endif
2130

    
2131
#if defined(TARGET_PPC64)
2132
void OPPROTO op_slbia (void)
2133
{
2134
    ppc_slb_invalidate_all(env);
2135
    RETURN();
2136
}
2137

    
2138
void OPPROTO op_slbie (void)
2139
{
2140
    ppc_slb_invalidate_one(env, (uint32_t)T0);
2141
    RETURN();
2142
}
2143

    
2144
void OPPROTO op_slbie_64 (void)
2145
{
2146
    ppc_slb_invalidate_one(env, T0);
2147
    RETURN();
2148
}
2149
#endif
2150
#endif
2151

    
2152
#if !defined(CONFIG_USER_ONLY)
2153
/* PowerPC 602/603/755 software TLB load instructions */
2154
void OPPROTO op_6xx_tlbld (void)
2155
{
2156
    do_load_6xx_tlb(0);
2157
    RETURN();
2158
}
2159

    
2160
void OPPROTO op_6xx_tlbli (void)
2161
{
2162
    do_load_6xx_tlb(1);
2163
    RETURN();
2164
}
2165

    
2166
/* PowerPC 74xx software TLB load instructions */
2167
void OPPROTO op_74xx_tlbld (void)
2168
{
2169
    do_load_74xx_tlb(0);
2170
    RETURN();
2171
}
2172

    
2173
void OPPROTO op_74xx_tlbli (void)
2174
{
2175
    do_load_74xx_tlb(1);
2176
    RETURN();
2177
}
2178
#endif
2179

    
2180
/* 601 specific */
2181
void OPPROTO op_load_601_rtcl (void)
2182
{
2183
    T0 = cpu_ppc601_load_rtcl(env);
2184
    RETURN();
2185
}
2186

    
2187
void OPPROTO op_load_601_rtcu (void)
2188
{
2189
    T0 = cpu_ppc601_load_rtcu(env);
2190
    RETURN();
2191
}
2192

    
2193
#if !defined(CONFIG_USER_ONLY)
2194
void OPPROTO op_store_601_rtcl (void)
2195
{
2196
    cpu_ppc601_store_rtcl(env, T0);
2197
    RETURN();
2198
}
2199

    
2200
void OPPROTO op_store_601_rtcu (void)
2201
{
2202
    cpu_ppc601_store_rtcu(env, T0);
2203
    RETURN();
2204
}
2205

    
2206
void OPPROTO op_load_601_bat (void)
2207
{
2208
    T0 = env->IBAT[PARAM1][PARAM2];
2209
    RETURN();
2210
}
2211
#endif /* !defined(CONFIG_USER_ONLY) */
2212

    
2213
/* 601 unified BATs store.
2214
 * To avoid using specific MMU code for 601, we store BATs in
2215
 * IBAT and DBAT simultaneously, then emulate unified BATs.
2216
 */
2217
#if !defined(CONFIG_USER_ONLY)
2218
void OPPROTO op_store_601_batl (void)
2219
{
2220
    int nr = PARAM1;
2221

    
2222
    env->IBAT[1][nr] = T0;
2223
    env->DBAT[1][nr] = T0;
2224
    RETURN();
2225
}
2226

    
2227
void OPPROTO op_store_601_batu (void)
2228
{
2229
    do_store_601_batu(PARAM1);
2230
    RETURN();
2231
}
2232
#endif /* !defined(CONFIG_USER_ONLY) */
2233

    
2234
/* PowerPC 601 specific instructions (POWER bridge) */
2235
/* XXX: those micro-ops need tests ! */
2236
void OPPROTO op_POWER_abs (void)
2237
{
2238
    if (T0 == INT32_MIN)
2239
        T0 = INT32_MAX;
2240
    else if (T0 < 0)
2241
        T0 = -T0;
2242
    RETURN();
2243
}
2244

    
2245
void OPPROTO op_POWER_abso (void)
2246
{
2247
    do_POWER_abso();
2248
    RETURN();
2249
}
2250

    
2251
void OPPROTO op_POWER_clcs (void)
2252
{
2253
    do_POWER_clcs();
2254
    RETURN();
2255
}
2256

    
2257
void OPPROTO op_POWER_div (void)
2258
{
2259
    do_POWER_div();
2260
    RETURN();
2261
}
2262

    
2263
void OPPROTO op_POWER_divo (void)
2264
{
2265
    do_POWER_divo();
2266
    RETURN();
2267
}
2268

    
2269
void OPPROTO op_POWER_divs (void)
2270
{
2271
    do_POWER_divs();
2272
    RETURN();
2273
}
2274

    
2275
void OPPROTO op_POWER_divso (void)
2276
{
2277
    do_POWER_divso();
2278
    RETURN();
2279
}
2280

    
2281
void OPPROTO op_POWER_doz (void)
2282
{
2283
    if ((int32_t)T1 > (int32_t)T0)
2284
        T0 = T1 - T0;
2285
    else
2286
        T0 = 0;
2287
    RETURN();
2288
}
2289

    
2290
void OPPROTO op_POWER_dozo (void)
2291
{
2292
    do_POWER_dozo();
2293
    RETURN();
2294
}
2295

    
2296
void OPPROTO op_load_xer_cmp (void)
2297
{
2298
    T2 = xer_cmp;
2299
    RETURN();
2300
}
2301

    
2302
void OPPROTO op_POWER_maskg (void)
2303
{
2304
    do_POWER_maskg();
2305
    RETURN();
2306
}
2307

    
2308
void OPPROTO op_POWER_maskir (void)
2309
{
2310
    T0 = (T0 & ~T2) | (T1 & T2);
2311
    RETURN();
2312
}
2313

    
2314
void OPPROTO op_POWER_mul (void)
2315
{
2316
    uint64_t tmp;
2317

    
2318
    tmp = (uint64_t)T0 * (uint64_t)T1;
2319
    env->spr[SPR_MQ] = tmp >> 32;
2320
    T0 = tmp;
2321
    RETURN();
2322
}
2323

    
2324
void OPPROTO op_POWER_mulo (void)
2325
{
2326
    do_POWER_mulo();
2327
    RETURN();
2328
}
2329

    
2330
void OPPROTO op_POWER_nabs (void)
2331
{
2332
    if (T0 > 0)
2333
        T0 = -T0;
2334
    RETURN();
2335
}
2336

    
2337
void OPPROTO op_POWER_nabso (void)
2338
{
2339
    /* nabs never overflows */
2340
    if (T0 > 0)
2341
        T0 = -T0;
2342
    xer_ov = 0;
2343
    RETURN();
2344
}
2345

    
2346
/* XXX: factorise POWER rotates... */
2347
void OPPROTO op_POWER_rlmi (void)
2348
{
2349
    T0 = rotl32(T0, T2) & PARAM1;
2350
    T0 |= T1 & (uint32_t)PARAM2;
2351
    RETURN();
2352
}
2353

    
2354
void OPPROTO op_POWER_rrib (void)
2355
{
2356
    T2 &= 0x1FUL;
2357
    T0 = rotl32(T0 & INT32_MIN, T2);
2358
    T0 |= T1 & ~rotl32(INT32_MIN, T2);
2359
    RETURN();
2360
}
2361

    
2362
void OPPROTO op_POWER_sle (void)
2363
{
2364
    T1 &= 0x1FUL;
2365
    env->spr[SPR_MQ] = rotl32(T0, T1);
2366
    T0 = T0 << T1;
2367
    RETURN();
2368
}
2369

    
2370
void OPPROTO op_POWER_sleq (void)
2371
{
2372
    uint32_t tmp = env->spr[SPR_MQ];
2373

    
2374
    T1 &= 0x1FUL;
2375
    env->spr[SPR_MQ] = rotl32(T0, T1);
2376
    T0 = T0 << T1;
2377
    T0 |= tmp >> (32 - T1);
2378
    RETURN();
2379
}
2380

    
2381
void OPPROTO op_POWER_sllq (void)
2382
{
2383
    uint32_t msk = -1;
2384

    
2385
    msk = msk << (T1 & 0x1FUL);
2386
    if (T1 & 0x20UL)
2387
        msk = ~msk;
2388
    T1 &= 0x1FUL;
2389
    T0 = (T0 << T1) & msk;
2390
    T0 |= env->spr[SPR_MQ] & ~msk;
2391
    RETURN();
2392
}
2393

    
2394
void OPPROTO op_POWER_slq (void)
2395
{
2396
    uint32_t msk = -1, tmp;
2397

    
2398
    msk = msk << (T1 & 0x1FUL);
2399
    if (T1 & 0x20UL)
2400
        msk = ~msk;
2401
    T1 &= 0x1FUL;
2402
    tmp = rotl32(T0, T1);
2403
    T0 = tmp & msk;
2404
    env->spr[SPR_MQ] = tmp;
2405
    RETURN();
2406
}
2407

    
2408
void OPPROTO op_POWER_sraq (void)
2409
{
2410
    env->spr[SPR_MQ] = rotl32(T0, 32 - (T1 & 0x1FUL));
2411
    if (T1 & 0x20UL)
2412
        T0 = -1L;
2413
    else
2414
        T0 = (int32_t)T0 >> T1;
2415
    RETURN();
2416
}
2417

    
2418
void OPPROTO op_POWER_sre (void)
2419
{
2420
    T1 &= 0x1FUL;
2421
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2422
    T0 = (int32_t)T0 >> T1;
2423
    RETURN();
2424
}
2425

    
2426
void OPPROTO op_POWER_srea (void)
2427
{
2428
    T1 &= 0x1FUL;
2429
    env->spr[SPR_MQ] = T0 >> T1;
2430
    T0 = (int32_t)T0 >> T1;
2431
    RETURN();
2432
}
2433

    
2434
void OPPROTO op_POWER_sreq (void)
2435
{
2436
    uint32_t tmp;
2437
    int32_t msk;
2438

    
2439
    T1 &= 0x1FUL;
2440
    msk = INT32_MIN >> T1;
2441
    tmp = env->spr[SPR_MQ];
2442
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2443
    T0 = T0 >> T1;
2444
    T0 |= tmp & msk;
2445
    RETURN();
2446
}
2447

    
2448
void OPPROTO op_POWER_srlq (void)
2449
{
2450
    uint32_t tmp;
2451
    int32_t msk;
2452

    
2453
    msk = INT32_MIN >> (T1 & 0x1FUL);
2454
    if (T1 & 0x20UL)
2455
        msk = ~msk;
2456
    T1 &= 0x1FUL;
2457
    tmp = env->spr[SPR_MQ];
2458
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2459
    T0 = T0 >> T1;
2460
    T0 &= msk;
2461
    T0 |= tmp & ~msk;
2462
    RETURN();
2463
}
2464

    
2465
void OPPROTO op_POWER_srq (void)
2466
{
2467
    T1 &= 0x1FUL;
2468
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2469
    T0 = T0 >> T1;
2470
    RETURN();
2471
}
2472

    
2473
/* POWER instructions not implemented in PowerPC 601 */
2474
#if !defined(CONFIG_USER_ONLY)
2475
void OPPROTO op_POWER_mfsri (void)
2476
{
2477
    T1 = T0 >> 28;
2478
    T0 = env->sr[T1];
2479
    RETURN();
2480
}
2481

    
2482
void OPPROTO op_POWER_rac (void)
2483
{
2484
    do_POWER_rac();
2485
    RETURN();
2486
}
2487

    
2488
void OPPROTO op_POWER_rfsvc (void)
2489
{
2490
    do_POWER_rfsvc();
2491
    RETURN();
2492
}
2493
#endif
2494

    
2495
/* PowerPC 602 specific instruction */
2496
#if !defined(CONFIG_USER_ONLY)
2497
void OPPROTO op_602_mfrom (void)
2498
{
2499
    do_op_602_mfrom();
2500
    RETURN();
2501
}
2502
#endif
2503

    
2504
/* PowerPC 4xx specific micro-ops */
2505
void OPPROTO op_405_add_T0_T2 (void)
2506
{
2507
    T0 = (int32_t)T0 + (int32_t)T2;
2508
    RETURN();
2509
}
2510

    
2511
void OPPROTO op_405_mulchw (void)
2512
{
2513
    T0 = ((int16_t)T0) * ((int16_t)(T1 >> 16));
2514
    RETURN();
2515
}
2516

    
2517
void OPPROTO op_405_mulchwu (void)
2518
{
2519
    T0 = ((uint16_t)T0) * ((uint16_t)(T1 >> 16));
2520
    RETURN();
2521
}
2522

    
2523
void OPPROTO op_405_mulhhw (void)
2524
{
2525
    T0 = ((int16_t)(T0 >> 16)) * ((int16_t)(T1 >> 16));
2526
    RETURN();
2527
}
2528

    
2529
void OPPROTO op_405_mulhhwu (void)
2530
{
2531
    T0 = ((uint16_t)(T0 >> 16)) * ((uint16_t)(T1 >> 16));
2532
    RETURN();
2533
}
2534

    
2535
void OPPROTO op_405_mullhw (void)
2536
{
2537
    T0 = ((int16_t)T0) * ((int16_t)T1);
2538
    RETURN();
2539
}
2540

    
2541
void OPPROTO op_405_mullhwu (void)
2542
{
2543
    T0 = ((uint16_t)T0) * ((uint16_t)T1);
2544
    RETURN();
2545
}
2546

    
2547
void OPPROTO op_405_check_ov (void)
2548
{
2549
    do_405_check_ov();
2550
    RETURN();
2551
}
2552

    
2553
void OPPROTO op_405_check_sat (void)
2554
{
2555
    do_405_check_sat();
2556
    RETURN();
2557
}
2558

    
2559
void OPPROTO op_405_check_ovu (void)
2560
{
2561
    if (likely(T0 >= T2)) {
2562
        xer_ov = 0;
2563
    } else {
2564
        xer_ov = 1;
2565
        xer_so = 1;
2566
    }
2567
    RETURN();
2568
}
2569

    
2570
void OPPROTO op_405_check_satu (void)
2571
{
2572
    if (unlikely(T0 < T2)) {
2573
        /* Saturate result */
2574
        T0 = -1;
2575
    }
2576
    RETURN();
2577
}
2578

    
2579
void OPPROTO op_load_dcr (void)
2580
{
2581
    do_load_dcr();
2582
    RETURN();
2583
}
2584

    
2585
void OPPROTO op_store_dcr (void)
2586
{
2587
    do_store_dcr();
2588
    RETURN();
2589
}
2590

    
2591
#if !defined(CONFIG_USER_ONLY)
2592
/* Return from critical interrupt :
2593
 * same as rfi, except nip & MSR are loaded from SRR2/3 instead of SRR0/1
2594
 */
2595
void OPPROTO op_40x_rfci (void)
2596
{
2597
    do_40x_rfci();
2598
    RETURN();
2599
}
2600

    
2601
void OPPROTO op_rfci (void)
2602
{
2603
    do_rfci();
2604
    RETURN();
2605
}
2606

    
2607
void OPPROTO op_rfdi (void)
2608
{
2609
    do_rfdi();
2610
    RETURN();
2611
}
2612

    
2613
void OPPROTO op_rfmci (void)
2614
{
2615
    do_rfmci();
2616
    RETURN();
2617
}
2618

    
2619
void OPPROTO op_wrte (void)
2620
{
2621
    /* We don't call do_store_msr here as we won't trigger
2622
     * any special case nor change hflags
2623
     */
2624
    T0 &= 1 << MSR_EE;
2625
    env->msr &= ~(1 << MSR_EE);
2626
    env->msr |= T0;
2627
    RETURN();
2628
}
2629

    
2630
void OPPROTO op_440_tlbre (void)
2631
{
2632
    do_440_tlbre(PARAM1);
2633
    RETURN();
2634
}
2635

    
2636
void OPPROTO op_440_tlbsx (void)
2637
{
2638
    T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_440_MMUCR] & 0xFF);
2639
    RETURN();
2640
}
2641

    
2642
void OPPROTO op_4xx_tlbsx_check (void)
2643
{
2644
    int tmp;
2645

    
2646
    tmp = xer_so;
2647
    if (T0 != -1)
2648
        tmp |= 0x02;
2649
    env->crf[0] = tmp;
2650
    RETURN();
2651
}
2652

    
2653
void OPPROTO op_440_tlbwe (void)
2654
{
2655
    do_440_tlbwe(PARAM1);
2656
    RETURN();
2657
}
2658

    
2659
void OPPROTO op_4xx_tlbre_lo (void)
2660
{
2661
    do_4xx_tlbre_lo();
2662
    RETURN();
2663
}
2664

    
2665
void OPPROTO op_4xx_tlbre_hi (void)
2666
{
2667
    do_4xx_tlbre_hi();
2668
    RETURN();
2669
}
2670

    
2671
void OPPROTO op_4xx_tlbsx (void)
2672
{
2673
    T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_40x_PID]);
2674
    RETURN();
2675
}
2676

    
2677
void OPPROTO op_4xx_tlbwe_lo (void)
2678
{
2679
    do_4xx_tlbwe_lo();
2680
    RETURN();
2681
}
2682

    
2683
void OPPROTO op_4xx_tlbwe_hi (void)
2684
{
2685
    do_4xx_tlbwe_hi();
2686
    RETURN();
2687
}
2688
#endif
2689

    
2690
/* SPR micro-ops */
2691
/* 440 specific */
2692
void OPPROTO op_440_dlmzb (void)
2693
{
2694
    do_440_dlmzb();
2695
    RETURN();
2696
}
2697

    
2698
void OPPROTO op_440_dlmzb_update_Rc (void)
2699
{
2700
    if (T0 == 8)
2701
        T0 = 0x2;
2702
    else if (T0 < 4)
2703
        T0 = 0x4;
2704
    else
2705
        T0 = 0x8;
2706
    RETURN();
2707
}
2708

    
2709
#if !defined(CONFIG_USER_ONLY)
2710
void OPPROTO op_store_pir (void)
2711
{
2712
    env->spr[SPR_PIR] = T0 & 0x0000000FUL;
2713
    RETURN();
2714
}
2715

    
2716
void OPPROTO op_load_403_pb (void)
2717
{
2718
    do_load_403_pb(PARAM1);
2719
    RETURN();
2720
}
2721

    
2722
void OPPROTO op_store_403_pb (void)
2723
{
2724
    do_store_403_pb(PARAM1);
2725
    RETURN();
2726
}
2727

    
2728
void OPPROTO op_load_40x_pit (void)
2729
{
2730
    T0 = load_40x_pit(env);
2731
    RETURN();
2732
}
2733

    
2734
void OPPROTO op_store_40x_pit (void)
2735
{
2736
    store_40x_pit(env, T0);
2737
    RETURN();
2738
}
2739

    
2740
void OPPROTO op_store_40x_dbcr0 (void)
2741
{
2742
    store_40x_dbcr0(env, T0);
2743
    RETURN();
2744
}
2745

    
2746
void OPPROTO op_store_40x_sler (void)
2747
{
2748
    store_40x_sler(env, T0);
2749
    RETURN();
2750
}
2751

    
2752
void OPPROTO op_store_booke_tcr (void)
2753
{
2754
    store_booke_tcr(env, T0);
2755
    RETURN();
2756
}
2757

    
2758
void OPPROTO op_store_booke_tsr (void)
2759
{
2760
    store_booke_tsr(env, T0);
2761
    RETURN();
2762
}
2763
#endif /* !defined(CONFIG_USER_ONLY) */
2764

    
2765
#if defined(TARGET_PPCEMB)
2766
/* SPE extension */
2767
void OPPROTO op_splatw_T1_64 (void)
2768
{
2769
    T1_64 = (T1_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL);
2770
    RETURN();
2771
}
2772

    
2773
void OPPROTO op_splatwi_T0_64 (void)
2774
{
2775
    uint64_t tmp = PARAM1;
2776

    
2777
    T0_64 = (tmp << 32) | tmp;
2778
    RETURN();
2779
}
2780

    
2781
void OPPROTO op_splatwi_T1_64 (void)
2782
{
2783
    uint64_t tmp = PARAM1;
2784

    
2785
    T1_64 = (tmp << 32) | tmp;
2786
    RETURN();
2787
}
2788

    
2789
void OPPROTO op_extsh_T1_64 (void)
2790
{
2791
    T1_64 = (int32_t)((int16_t)T1_64);
2792
    RETURN();
2793
}
2794

    
2795
void OPPROTO op_sli16_T1_64 (void)
2796
{
2797
    T1_64 = T1_64 << 16;
2798
    RETURN();
2799
}
2800

    
2801
void OPPROTO op_sli32_T1_64 (void)
2802
{
2803
    T1_64 = T1_64 << 32;
2804
    RETURN();
2805
}
2806

    
2807
void OPPROTO op_srli32_T1_64 (void)
2808
{
2809
    T1_64 = T1_64 >> 32;
2810
    RETURN();
2811
}
2812

    
2813
void OPPROTO op_evsel (void)
2814
{
2815
    do_evsel();
2816
    RETURN();
2817
}
2818

    
2819
void OPPROTO op_evaddw (void)
2820
{
2821
    do_evaddw();
2822
    RETURN();
2823
}
2824

    
2825
void OPPROTO op_evsubfw (void)
2826
{
2827
    do_evsubfw();
2828
    RETURN();
2829
}
2830

    
2831
void OPPROTO op_evneg (void)
2832
{
2833
    do_evneg();
2834
    RETURN();
2835
}
2836

    
2837
void OPPROTO op_evabs (void)
2838
{
2839
    do_evabs();
2840
    RETURN();
2841
}
2842

    
2843
void OPPROTO op_evextsh (void)
2844
{
2845
    T0_64 = ((uint64_t)((int32_t)(int16_t)(T0_64 >> 32)) << 32) |
2846
        (uint64_t)((int32_t)(int16_t)T0_64);
2847
    RETURN();
2848
}
2849

    
2850
void OPPROTO op_evextsb (void)
2851
{
2852
    T0_64 = ((uint64_t)((int32_t)(int8_t)(T0_64 >> 32)) << 32) |
2853
        (uint64_t)((int32_t)(int8_t)T0_64);
2854
    RETURN();
2855
}
2856

    
2857
void OPPROTO op_evcntlzw (void)
2858
{
2859
    do_evcntlzw();
2860
    RETURN();
2861
}
2862

    
2863
void OPPROTO op_evrndw (void)
2864
{
2865
    do_evrndw();
2866
    RETURN();
2867
}
2868

    
2869
void OPPROTO op_brinc (void)
2870
{
2871
    do_brinc();
2872
    RETURN();
2873
}
2874

    
2875
void OPPROTO op_evcntlsw (void)
2876
{
2877
    do_evcntlsw();
2878
    RETURN();
2879
}
2880

    
2881
void OPPROTO op_evand (void)
2882
{
2883
    T0_64 &= T1_64;
2884
    RETURN();
2885
}
2886

    
2887
void OPPROTO op_evandc (void)
2888
{
2889
    T0_64 &= ~T1_64;
2890
    RETURN();
2891
}
2892

    
2893
void OPPROTO op_evor (void)
2894
{
2895
    T0_64 |= T1_64;
2896
    RETURN();
2897
}
2898

    
2899
void OPPROTO op_evxor (void)
2900
{
2901
    T0_64 ^= T1_64;
2902
    RETURN();
2903
}
2904

    
2905
void OPPROTO op_eveqv (void)
2906
{
2907
    T0_64 = ~(T0_64 ^ T1_64);
2908
    RETURN();
2909
}
2910

    
2911
void OPPROTO op_evnor (void)
2912
{
2913
    T0_64 = ~(T0_64 | T1_64);
2914
    RETURN();
2915
}
2916

    
2917
void OPPROTO op_evorc (void)
2918
{
2919
    T0_64 |= ~T1_64;
2920
    RETURN();
2921
}
2922

    
2923
void OPPROTO op_evnand (void)
2924
{
2925
    T0_64 = ~(T0_64 & T1_64);
2926
    RETURN();
2927
}
2928

    
2929
void OPPROTO op_evsrws (void)
2930
{
2931
    do_evsrws();
2932
    RETURN();
2933
}
2934

    
2935
void OPPROTO op_evsrwu (void)
2936
{
2937
    do_evsrwu();
2938
    RETURN();
2939
}
2940

    
2941
void OPPROTO op_evslw (void)
2942
{
2943
    do_evslw();
2944
    RETURN();
2945
}
2946

    
2947
void OPPROTO op_evrlw (void)
2948
{
2949
    do_evrlw();
2950
    RETURN();
2951
}
2952

    
2953
void OPPROTO op_evmergelo (void)
2954
{
2955
    T0_64 = (T0_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL);
2956
    RETURN();
2957
}
2958

    
2959
void OPPROTO op_evmergehi (void)
2960
{
2961
    T0_64 = (T0_64 & 0xFFFFFFFF00000000ULL) | (T1_64 >> 32);
2962
    RETURN();
2963
}
2964

    
2965
void OPPROTO op_evmergelohi (void)
2966
{
2967
    T0_64 = (T0_64 << 32) | (T1_64 >> 32);
2968
    RETURN();
2969
}
2970

    
2971
void OPPROTO op_evmergehilo (void)
2972
{
2973
    T0_64 = (T0_64 & 0xFFFFFFFF00000000ULL) | (T1_64 & 0x00000000FFFFFFFFULL);
2974
    RETURN();
2975
}
2976

    
2977
void OPPROTO op_evcmpgts (void)
2978
{
2979
    do_evcmpgts();
2980
    RETURN();
2981
}
2982

    
2983
void OPPROTO op_evcmpgtu (void)
2984
{
2985
    do_evcmpgtu();
2986
    RETURN();
2987
}
2988

    
2989
void OPPROTO op_evcmplts (void)
2990
{
2991
    do_evcmplts();
2992
    RETURN();
2993
}
2994

    
2995
void OPPROTO op_evcmpltu (void)
2996
{
2997
    do_evcmpltu();
2998
    RETURN();
2999
}
3000

    
3001
void OPPROTO op_evcmpeq (void)
3002
{
3003
    do_evcmpeq();
3004
    RETURN();
3005
}
3006

    
3007
void OPPROTO op_evfssub (void)
3008
{
3009
    do_evfssub();
3010
    RETURN();
3011
}
3012

    
3013
void OPPROTO op_evfsadd (void)
3014
{
3015
    do_evfsadd();
3016
    RETURN();
3017
}
3018

    
3019
void OPPROTO op_evfsnabs (void)
3020
{
3021
    do_evfsnabs();
3022
    RETURN();
3023
}
3024

    
3025
void OPPROTO op_evfsabs (void)
3026
{
3027
    do_evfsabs();
3028
    RETURN();
3029
}
3030

    
3031
void OPPROTO op_evfsneg (void)
3032
{
3033
    do_evfsneg();
3034
    RETURN();
3035
}
3036

    
3037
void OPPROTO op_evfsdiv (void)
3038
{
3039
    do_evfsdiv();
3040
    RETURN();
3041
}
3042

    
3043
void OPPROTO op_evfsmul (void)
3044
{
3045
    do_evfsmul();
3046
    RETURN();
3047
}
3048

    
3049
void OPPROTO op_evfscmplt (void)
3050
{
3051
    do_evfscmplt();
3052
    RETURN();
3053
}
3054

    
3055
void OPPROTO op_evfscmpgt (void)
3056
{
3057
    do_evfscmpgt();
3058
    RETURN();
3059
}
3060

    
3061
void OPPROTO op_evfscmpeq (void)
3062
{
3063
    do_evfscmpeq();
3064
    RETURN();
3065
}
3066

    
3067
void OPPROTO op_evfscfsi (void)
3068
{
3069
    do_evfscfsi();
3070
    RETURN();
3071
}
3072

    
3073
void OPPROTO op_evfscfui (void)
3074
{
3075
    do_evfscfui();
3076
    RETURN();
3077
}
3078

    
3079
void OPPROTO op_evfscfsf (void)
3080
{
3081
    do_evfscfsf();
3082
    RETURN();
3083
}
3084

    
3085
void OPPROTO op_evfscfuf (void)
3086
{
3087
    do_evfscfuf();
3088
    RETURN();
3089
}
3090

    
3091
void OPPROTO op_evfsctsi (void)
3092
{
3093
    do_evfsctsi();
3094
    RETURN();
3095
}
3096

    
3097
void OPPROTO op_evfsctui (void)
3098
{
3099
    do_evfsctui();
3100
    RETURN();
3101
}
3102

    
3103
void OPPROTO op_evfsctsf (void)
3104
{
3105
    do_evfsctsf();
3106
    RETURN();
3107
}
3108

    
3109
void OPPROTO op_evfsctuf (void)
3110
{
3111
    do_evfsctuf();
3112
    RETURN();
3113
}
3114

    
3115
void OPPROTO op_evfsctuiz (void)
3116
{
3117
    do_evfsctuiz();
3118
    RETURN();
3119
}
3120

    
3121
void OPPROTO op_evfsctsiz (void)
3122
{
3123
    do_evfsctsiz();
3124
    RETURN();
3125
}
3126

    
3127
void OPPROTO op_evfststlt (void)
3128
{
3129
    do_evfststlt();
3130
    RETURN();
3131
}
3132

    
3133
void OPPROTO op_evfststgt (void)
3134
{
3135
    do_evfststgt();
3136
    RETURN();
3137
}
3138

    
3139
void OPPROTO op_evfststeq (void)
3140
{
3141
    do_evfststeq();
3142
    RETURN();
3143
}
3144

    
3145
void OPPROTO op_efssub (void)
3146
{
3147
    T0_64 = _do_efssub(T0_64, T1_64);
3148
    RETURN();
3149
}
3150

    
3151
void OPPROTO op_efsadd (void)
3152
{
3153
    T0_64 = _do_efsadd(T0_64, T1_64);
3154
    RETURN();
3155
}
3156

    
3157
void OPPROTO op_efsnabs (void)
3158
{
3159
    T0_64 = _do_efsnabs(T0_64);
3160
    RETURN();
3161
}
3162

    
3163
void OPPROTO op_efsabs (void)
3164
{
3165
    T0_64 = _do_efsabs(T0_64);
3166
    RETURN();
3167
}
3168

    
3169
void OPPROTO op_efsneg (void)
3170
{
3171
    T0_64 = _do_efsneg(T0_64);
3172
    RETURN();
3173
}
3174

    
3175
void OPPROTO op_efsdiv (void)
3176
{
3177
    T0_64 = _do_efsdiv(T0_64, T1_64);
3178
    RETURN();
3179
}
3180

    
3181
void OPPROTO op_efsmul (void)
3182
{
3183
    T0_64 = _do_efsmul(T0_64, T1_64);
3184
    RETURN();
3185
}
3186

    
3187
void OPPROTO op_efscmplt (void)
3188
{
3189
    do_efscmplt();
3190
    RETURN();
3191
}
3192

    
3193
void OPPROTO op_efscmpgt (void)
3194
{
3195
    do_efscmpgt();
3196
    RETURN();
3197
}
3198

    
3199
void OPPROTO op_efscfd (void)
3200
{
3201
    do_efscfd();
3202
    RETURN();
3203
}
3204

    
3205
void OPPROTO op_efscmpeq (void)
3206
{
3207
    do_efscmpeq();
3208
    RETURN();
3209
}
3210

    
3211
void OPPROTO op_efscfsi (void)
3212
{
3213
    do_efscfsi();
3214
    RETURN();
3215
}
3216

    
3217
void OPPROTO op_efscfui (void)
3218
{
3219
    do_efscfui();
3220
    RETURN();
3221
}
3222

    
3223
void OPPROTO op_efscfsf (void)
3224
{
3225
    do_efscfsf();
3226
    RETURN();
3227
}
3228

    
3229
void OPPROTO op_efscfuf (void)
3230
{
3231
    do_efscfuf();
3232
    RETURN();
3233
}
3234

    
3235
void OPPROTO op_efsctsi (void)
3236
{
3237
    do_efsctsi();
3238
    RETURN();
3239
}
3240

    
3241
void OPPROTO op_efsctui (void)
3242
{
3243
    do_efsctui();
3244
    RETURN();
3245
}
3246

    
3247
void OPPROTO op_efsctsf (void)
3248
{
3249
    do_efsctsf();
3250
    RETURN();
3251
}
3252

    
3253
void OPPROTO op_efsctuf (void)
3254
{
3255
    do_efsctuf();
3256
    RETURN();
3257
}
3258

    
3259
void OPPROTO op_efsctsiz (void)
3260
{
3261
    do_efsctsiz();
3262
    RETURN();
3263
}
3264

    
3265
void OPPROTO op_efsctuiz (void)
3266
{
3267
    do_efsctuiz();
3268
    RETURN();
3269
}
3270

    
3271
void OPPROTO op_efststlt (void)
3272
{
3273
    T0 = _do_efststlt(T0_64, T1_64);
3274
    RETURN();
3275
}
3276

    
3277
void OPPROTO op_efststgt (void)
3278
{
3279
    T0 = _do_efststgt(T0_64, T1_64);
3280
    RETURN();
3281
}
3282

    
3283
void OPPROTO op_efststeq (void)
3284
{
3285
    T0 = _do_efststeq(T0_64, T1_64);
3286
    RETURN();
3287
}
3288

    
3289
void OPPROTO op_efdsub (void)
3290
{
3291
    union {
3292
        uint64_t u;
3293
        float64 f;
3294
    } u1, u2;
3295
    u1.u = T0_64;
3296
    u2.u = T1_64;
3297
    u1.f = float64_sub(u1.f, u2.f, &env->spe_status);
3298
    T0_64 = u1.u;
3299
    RETURN();
3300
}
3301

    
3302
void OPPROTO op_efdadd (void)
3303
{
3304
    union {
3305
        uint64_t u;
3306
        float64 f;
3307
    } u1, u2;
3308
    u1.u = T0_64;
3309
    u2.u = T1_64;
3310
    u1.f = float64_add(u1.f, u2.f, &env->spe_status);
3311
    T0_64 = u1.u;
3312
    RETURN();
3313
}
3314

    
3315
void OPPROTO op_efdcfsid (void)
3316
{
3317
    do_efdcfsi();
3318
    RETURN();
3319
}
3320

    
3321
void OPPROTO op_efdcfuid (void)
3322
{
3323
    do_efdcfui();
3324
    RETURN();
3325
}
3326

    
3327
void OPPROTO op_efdnabs (void)
3328
{
3329
    T0_64 |= 0x8000000000000000ULL;
3330
    RETURN();
3331
}
3332

    
3333
void OPPROTO op_efdabs (void)
3334
{
3335
    T0_64 &= ~0x8000000000000000ULL;
3336
    RETURN();
3337
}
3338

    
3339
void OPPROTO op_efdneg (void)
3340
{
3341
    T0_64 ^= 0x8000000000000000ULL;
3342
    RETURN();
3343
}
3344

    
3345
void OPPROTO op_efddiv (void)
3346
{
3347
    union {
3348
        uint64_t u;
3349
        float64 f;
3350
    } u1, u2;
3351
    u1.u = T0_64;
3352
    u2.u = T1_64;
3353
    u1.f = float64_div(u1.f, u2.f, &env->spe_status);
3354
    T0_64 = u1.u;
3355
    RETURN();
3356
}
3357

    
3358
void OPPROTO op_efdmul (void)
3359
{
3360
    union {
3361
        uint64_t u;
3362
        float64 f;
3363
    } u1, u2;
3364
    u1.u = T0_64;
3365
    u2.u = T1_64;
3366
    u1.f = float64_mul(u1.f, u2.f, &env->spe_status);
3367
    T0_64 = u1.u;
3368
    RETURN();
3369
}
3370

    
3371
void OPPROTO op_efdctsidz (void)
3372
{
3373
    do_efdctsiz();
3374
    RETURN();
3375
}
3376

    
3377
void OPPROTO op_efdctuidz (void)
3378
{
3379
    do_efdctuiz();
3380
    RETURN();
3381
}
3382

    
3383
void OPPROTO op_efdcmplt (void)
3384
{
3385
    do_efdcmplt();
3386
    RETURN();
3387
}
3388

    
3389
void OPPROTO op_efdcmpgt (void)
3390
{
3391
    do_efdcmpgt();
3392
    RETURN();
3393
}
3394

    
3395
void OPPROTO op_efdcfs (void)
3396
{
3397
    do_efdcfs();
3398
    RETURN();
3399
}
3400

    
3401
void OPPROTO op_efdcmpeq (void)
3402
{
3403
    do_efdcmpeq();
3404
    RETURN();
3405
}
3406

    
3407
void OPPROTO op_efdcfsi (void)
3408
{
3409
    do_efdcfsi();
3410
    RETURN();
3411
}
3412

    
3413
void OPPROTO op_efdcfui (void)
3414
{
3415
    do_efdcfui();
3416
    RETURN();
3417
}
3418

    
3419
void OPPROTO op_efdcfsf (void)
3420
{
3421
    do_efdcfsf();
3422
    RETURN();
3423
}
3424

    
3425
void OPPROTO op_efdcfuf (void)
3426
{
3427
    do_efdcfuf();
3428
    RETURN();
3429
}
3430

    
3431
void OPPROTO op_efdctsi (void)
3432
{
3433
    do_efdctsi();
3434
    RETURN();
3435
}
3436

    
3437
void OPPROTO op_efdctui (void)
3438
{
3439
    do_efdctui();
3440
    RETURN();
3441
}
3442

    
3443
void OPPROTO op_efdctsf (void)
3444
{
3445
    do_efdctsf();
3446
    RETURN();
3447
}
3448

    
3449
void OPPROTO op_efdctuf (void)
3450
{
3451
    do_efdctuf();
3452
    RETURN();
3453
}
3454

    
3455
void OPPROTO op_efdctuiz (void)
3456
{
3457
    do_efdctuiz();
3458
    RETURN();
3459
}
3460

    
3461
void OPPROTO op_efdctsiz (void)
3462
{
3463
    do_efdctsiz();
3464
    RETURN();
3465
}
3466

    
3467
void OPPROTO op_efdtstlt (void)
3468
{
3469
    T0 = _do_efdtstlt(T0_64, T1_64);
3470
    RETURN();
3471
}
3472

    
3473
void OPPROTO op_efdtstgt (void)
3474
{
3475
    T0 = _do_efdtstgt(T0_64, T1_64);
3476
    RETURN();
3477
}
3478

    
3479
void OPPROTO op_efdtsteq (void)
3480
{
3481
    T0 = _do_efdtsteq(T0_64, T1_64);
3482
    RETURN();
3483
}
3484
#endif /* defined(TARGET_PPCEMB) */