Statistics
| Branch: | Revision:

root / target-ppc / op.c @ fc0d441e

History | View | Annotate | Download (51.3 kB)

1
/*
2
 *  PowerPC emulation micro-operations for qemu.
3
 *
4
 *  Copyright (c) 2003-2007 Jocelyn Mayer
5
 *
6
 * This library is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Lesser General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2 of the License, or (at your option) any later version.
10
 *
11
 * This library is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with this library; if not, write to the Free Software
18
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 */
20

    
21
//#define DEBUG_OP
22

    
23
#include "config.h"
24
#include "exec.h"
25
#include "host-utils.h"
26
#include "helper_regs.h"
27
#include "op_helper.h"
28

    
29
#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
/* Branch */
655
#define EIP env->nip
656

    
657
void OPPROTO op_setlr (void)
658
{
659
    env->lr = (uint32_t)PARAM1;
660
    RETURN();
661
}
662

    
663
#if defined (TARGET_PPC64)
664
void OPPROTO op_setlr_64 (void)
665
{
666
    env->lr = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
667
    RETURN();
668
}
669
#endif
670

    
671
void OPPROTO op_goto_tb0 (void)
672
{
673
    GOTO_TB(op_goto_tb0, PARAM1, 0);
674
}
675

    
676
void OPPROTO op_goto_tb1 (void)
677
{
678
    GOTO_TB(op_goto_tb1, PARAM1, 1);
679
}
680

    
681
void OPPROTO op_b_T1 (void)
682
{
683
    env->nip = (uint32_t)(T1 & ~3);
684
    RETURN();
685
}
686

    
687
#if defined (TARGET_PPC64)
688
void OPPROTO op_b_T1_64 (void)
689
{
690
    env->nip = (uint64_t)(T1 & ~3);
691
    RETURN();
692
}
693
#endif
694

    
695
void OPPROTO op_jz_T0 (void)
696
{
697
    if (!T0)
698
        GOTO_LABEL_PARAM(1);
699
    RETURN();
700
}
701

    
702
void OPPROTO op_btest_T1 (void)
703
{
704
    if (T0) {
705
        env->nip = (uint32_t)(T1 & ~3);
706
    } else {
707
        env->nip = (uint32_t)PARAM1;
708
    }
709
    RETURN();
710
}
711

    
712
#if defined (TARGET_PPC64)
713
void OPPROTO op_btest_T1_64 (void)
714
{
715
    if (T0) {
716
        env->nip = (uint64_t)(T1 & ~3);
717
    } else {
718
        env->nip = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
719
    }
720
    RETURN();
721
}
722
#endif
723

    
724
void OPPROTO op_movl_T1_ctr (void)
725
{
726
    T1 = env->ctr;
727
    RETURN();
728
}
729

    
730
void OPPROTO op_movl_T1_lr (void)
731
{
732
    T1 = env->lr;
733
    RETURN();
734
}
735

    
736
/* tests with result in T0 */
737
void OPPROTO op_test_ctr (void)
738
{
739
    T0 = (uint32_t)env->ctr;
740
    RETURN();
741
}
742

    
743
#if defined(TARGET_PPC64)
744
void OPPROTO op_test_ctr_64 (void)
745
{
746
    T0 = (uint64_t)env->ctr;
747
    RETURN();
748
}
749
#endif
750

    
751
void OPPROTO op_test_ctr_true (void)
752
{
753
    T0 = ((uint32_t)env->ctr != 0 && (T0 & PARAM1) != 0);
754
    RETURN();
755
}
756

    
757
#if defined(TARGET_PPC64)
758
void OPPROTO op_test_ctr_true_64 (void)
759
{
760
    T0 = ((uint64_t)env->ctr != 0 && (T0 & PARAM1) != 0);
761
    RETURN();
762
}
763
#endif
764

    
765
void OPPROTO op_test_ctr_false (void)
766
{
767
    T0 = ((uint32_t)env->ctr != 0 && (T0 & PARAM1) == 0);
768
    RETURN();
769
}
770

    
771
#if defined(TARGET_PPC64)
772
void OPPROTO op_test_ctr_false_64 (void)
773
{
774
    T0 = ((uint64_t)env->ctr != 0 && (T0 & PARAM1) == 0);
775
    RETURN();
776
}
777
#endif
778

    
779
void OPPROTO op_test_ctrz (void)
780
{
781
    T0 = ((uint32_t)env->ctr == 0);
782
    RETURN();
783
}
784

    
785
#if defined(TARGET_PPC64)
786
void OPPROTO op_test_ctrz_64 (void)
787
{
788
    T0 = ((uint64_t)env->ctr == 0);
789
    RETURN();
790
}
791
#endif
792

    
793
void OPPROTO op_test_ctrz_true (void)
794
{
795
    T0 = ((uint32_t)env->ctr == 0 && (T0 & PARAM1) != 0);
796
    RETURN();
797
}
798

    
799
#if defined(TARGET_PPC64)
800
void OPPROTO op_test_ctrz_true_64 (void)
801
{
802
    T0 = ((uint64_t)env->ctr == 0 && (T0 & PARAM1) != 0);
803
    RETURN();
804
}
805
#endif
806

    
807
void OPPROTO op_test_ctrz_false (void)
808
{
809
    T0 = ((uint32_t)env->ctr == 0 && (T0 & PARAM1) == 0);
810
    RETURN();
811
}
812

    
813
#if defined(TARGET_PPC64)
814
void OPPROTO op_test_ctrz_false_64 (void)
815
{
816
    T0 = ((uint64_t)env->ctr == 0 && (T0 & PARAM1) == 0);
817
    RETURN();
818
}
819
#endif
820

    
821
void OPPROTO op_test_true (void)
822
{
823
    T0 = (T0 & PARAM1);
824
    RETURN();
825
}
826

    
827
void OPPROTO op_test_false (void)
828
{
829
    T0 = ((T0 & PARAM1) == 0);
830
    RETURN();
831
}
832

    
833
/* CTR maintenance */
834
void OPPROTO op_dec_ctr (void)
835
{
836
    env->ctr--;
837
    RETURN();
838
}
839

    
840
/***                           Integer arithmetic                          ***/
841
/* add */
842
void OPPROTO op_add (void)
843
{
844
    T0 += T1;
845
    RETURN();
846
}
847

    
848
void OPPROTO op_check_addo (void)
849
{
850
    if (likely(!(((uint32_t)T2 ^ (uint32_t)T1 ^ UINT32_MAX) &
851
                 ((uint32_t)T2 ^ (uint32_t)T0) & (1UL << 31)))) {
852
        xer_ov = 0;
853
    } else {
854
        xer_ov = 1;
855
        xer_so = 1;
856
    }
857
    RETURN();
858
}
859

    
860
#if defined(TARGET_PPC64)
861
void OPPROTO op_check_addo_64 (void)
862
{
863
    if (likely(!(((uint64_t)T2 ^ (uint64_t)T1 ^ UINT64_MAX) &
864
                 ((uint64_t)T2 ^ (uint64_t)T0) & (1ULL << 63)))) {
865
        xer_ov = 0;
866
    } else {
867
        xer_ov = 1;
868
        xer_so = 1;
869
    }
870
    RETURN();
871
}
872
#endif
873

    
874
/* add carrying */
875
void OPPROTO op_check_addc (void)
876
{
877
    if (likely((uint32_t)T0 >= (uint32_t)T2)) {
878
        xer_ca = 0;
879
    } else {
880
        xer_ca = 1;
881
    }
882
    RETURN();
883
}
884

    
885
#if defined(TARGET_PPC64)
886
void OPPROTO op_check_addc_64 (void)
887
{
888
    if (likely((uint64_t)T0 >= (uint64_t)T2)) {
889
        xer_ca = 0;
890
    } else {
891
        xer_ca = 1;
892
    }
893
    RETURN();
894
}
895
#endif
896

    
897
/* add extended */
898
void OPPROTO op_adde (void)
899
{
900
    do_adde();
901
    RETURN();
902
}
903

    
904
#if defined(TARGET_PPC64)
905
void OPPROTO op_adde_64 (void)
906
{
907
    do_adde_64();
908
    RETURN();
909
}
910
#endif
911

    
912
/* add immediate */
913
void OPPROTO op_addi (void)
914
{
915
    T0 += (int32_t)PARAM1;
916
    RETURN();
917
}
918

    
919
/* add to minus one extended */
920
void OPPROTO op_add_me (void)
921
{
922
    T0 += xer_ca + (-1);
923
    if (likely((uint32_t)T1 != 0))
924
        xer_ca = 1;
925
    RETURN();
926
}
927

    
928
#if defined(TARGET_PPC64)
929
void OPPROTO op_add_me_64 (void)
930
{
931
    T0 += xer_ca + (-1);
932
    if (likely((uint64_t)T1 != 0))
933
        xer_ca = 1;
934
    RETURN();
935
}
936
#endif
937

    
938
void OPPROTO op_addmeo (void)
939
{
940
    do_addmeo();
941
    RETURN();
942
}
943

    
944
void OPPROTO op_addmeo_64 (void)
945
{
946
    do_addmeo();
947
    RETURN();
948
}
949

    
950
/* add to zero extended */
951
void OPPROTO op_add_ze (void)
952
{
953
    T0 += xer_ca;
954
    RETURN();
955
}
956

    
957
/* divide word */
958
void OPPROTO op_divw (void)
959
{
960
    if (unlikely(((int32_t)T0 == INT32_MIN && (int32_t)T1 == -1) ||
961
                 (int32_t)T1 == 0)) {
962
        T0 = (int32_t)((-1) * ((uint32_t)T0 >> 31));
963
    } else {
964
        T0 = (int32_t)T0 / (int32_t)T1;
965
    }
966
    RETURN();
967
}
968

    
969
#if defined(TARGET_PPC64)
970
void OPPROTO op_divd (void)
971
{
972
    if (unlikely(((int64_t)T0 == INT64_MIN && (int64_t)T1 == -1) ||
973
                 (int64_t)T1 == 0)) {
974
        T0 = (int64_t)((-1ULL) * ((uint64_t)T0 >> 63));
975
    } else {
976
        T0 = (int64_t)T0 / (int64_t)T1;
977
    }
978
    RETURN();
979
}
980
#endif
981

    
982
void OPPROTO op_divwo (void)
983
{
984
    do_divwo();
985
    RETURN();
986
}
987

    
988
#if defined(TARGET_PPC64)
989
void OPPROTO op_divdo (void)
990
{
991
    do_divdo();
992
    RETURN();
993
}
994
#endif
995

    
996
/* divide word unsigned */
997
void OPPROTO op_divwu (void)
998
{
999
    if (unlikely(T1 == 0)) {
1000
        T0 = 0;
1001
    } else {
1002
        T0 = (uint32_t)T0 / (uint32_t)T1;
1003
    }
1004
    RETURN();
1005
}
1006

    
1007
#if defined(TARGET_PPC64)
1008
void OPPROTO op_divdu (void)
1009
{
1010
    if (unlikely(T1 == 0)) {
1011
        T0 = 0;
1012
    } else {
1013
        T0 /= T1;
1014
    }
1015
    RETURN();
1016
}
1017
#endif
1018

    
1019
void OPPROTO op_divwuo (void)
1020
{
1021
    do_divwuo();
1022
    RETURN();
1023
}
1024

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

    
1033
/* multiply high word */
1034
void OPPROTO op_mulhw (void)
1035
{
1036
    T0 = ((int64_t)((int32_t)T0) * (int64_t)((int32_t)T1)) >> 32;
1037
    RETURN();
1038
}
1039

    
1040
#if defined(TARGET_PPC64)
1041
void OPPROTO op_mulhd (void)
1042
{
1043
    uint64_t tl, th;
1044

    
1045
    muls64(&tl, &th, T0, T1);
1046
    T0 = th;
1047
    RETURN();
1048
}
1049
#endif
1050

    
1051
/* multiply high word unsigned */
1052
void OPPROTO op_mulhwu (void)
1053
{
1054
    T0 = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1) >> 32;
1055
    RETURN();
1056
}
1057

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

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

    
1069
/* multiply low immediate */
1070
void OPPROTO op_mulli (void)
1071
{
1072
    T0 = ((int32_t)T0 * (int32_t)PARAM1);
1073
    RETURN();
1074
}
1075

    
1076
/* multiply low word */
1077
void OPPROTO op_mullw (void)
1078
{
1079
    T0 = (int32_t)(T0 * T1);
1080
    RETURN();
1081
}
1082

    
1083
#if defined(TARGET_PPC64)
1084
void OPPROTO op_mulld (void)
1085
{
1086
    T0 *= T1;
1087
    RETURN();
1088
}
1089
#endif
1090

    
1091
void OPPROTO op_mullwo (void)
1092
{
1093
    do_mullwo();
1094
    RETURN();
1095
}
1096

    
1097
#if defined(TARGET_PPC64)
1098
void OPPROTO op_mulldo (void)
1099
{
1100
    do_mulldo();
1101
    RETURN();
1102
}
1103
#endif
1104

    
1105
/* negate */
1106
void OPPROTO op_neg (void)
1107
{
1108
    if (likely(T0 != INT32_MIN)) {
1109
        T0 = -(int32_t)T0;
1110
    }
1111
    RETURN();
1112
}
1113

    
1114
#if defined(TARGET_PPC64)
1115
void OPPROTO op_neg_64 (void)
1116
{
1117
    if (likely(T0 != INT64_MIN)) {
1118
        T0 = -(int64_t)T0;
1119
    }
1120
    RETURN();
1121
}
1122
#endif
1123

    
1124
void OPPROTO op_nego (void)
1125
{
1126
    do_nego();
1127
    RETURN();
1128
}
1129

    
1130
#if defined(TARGET_PPC64)
1131
void OPPROTO op_nego_64 (void)
1132
{
1133
    do_nego_64();
1134
    RETURN();
1135
}
1136
#endif
1137

    
1138
/* subtract from */
1139
void OPPROTO op_subf (void)
1140
{
1141
    T0 = T1 - T0;
1142
    RETURN();
1143
}
1144

    
1145
void OPPROTO op_check_subfo (void)
1146
{
1147
    if (likely(!(((uint32_t)(~T2) ^ (uint32_t)T1 ^ UINT32_MAX) &
1148
                 ((uint32_t)(~T2) ^ (uint32_t)T0) & (1UL << 31)))) {
1149
        xer_ov = 0;
1150
    } else {
1151
        xer_ov = 1;
1152
        xer_so = 1;
1153
    }
1154
    RETURN();
1155
}
1156

    
1157
#if defined(TARGET_PPC64)
1158
void OPPROTO op_check_subfo_64 (void)
1159
{
1160
    if (likely(!(((uint64_t)(~T2) ^ (uint64_t)T1 ^ UINT64_MAX) &
1161
                 ((uint64_t)(~T2) ^ (uint64_t)T0) & (1ULL << 63)))) {
1162
        xer_ov = 0;
1163
    } else {
1164
        xer_ov = 1;
1165
        xer_so = 1;
1166
    }
1167
    RETURN();
1168
}
1169
#endif
1170

    
1171
/* subtract from carrying */
1172
void OPPROTO op_check_subfc (void)
1173
{
1174
    if (likely((uint32_t)T0 > (uint32_t)T1)) {
1175
        xer_ca = 0;
1176
    } else {
1177
        xer_ca = 1;
1178
    }
1179
    RETURN();
1180
}
1181

    
1182
#if defined(TARGET_PPC64)
1183
void OPPROTO op_check_subfc_64 (void)
1184
{
1185
    if (likely((uint64_t)T0 > (uint64_t)T1)) {
1186
        xer_ca = 0;
1187
    } else {
1188
        xer_ca = 1;
1189
    }
1190
    RETURN();
1191
}
1192
#endif
1193

    
1194
/* subtract from extended */
1195
void OPPROTO op_subfe (void)
1196
{
1197
    do_subfe();
1198
    RETURN();
1199
}
1200

    
1201
#if defined(TARGET_PPC64)
1202
void OPPROTO op_subfe_64 (void)
1203
{
1204
    do_subfe_64();
1205
    RETURN();
1206
}
1207
#endif
1208

    
1209
/* subtract from immediate carrying */
1210
void OPPROTO op_subfic (void)
1211
{
1212
    T0 = (int32_t)PARAM1 + ~T0 + 1;
1213
    if ((uint32_t)T0 <= (uint32_t)PARAM1) {
1214
        xer_ca = 1;
1215
    } else {
1216
        xer_ca = 0;
1217
    }
1218
    RETURN();
1219
}
1220

    
1221
#if defined(TARGET_PPC64)
1222
void OPPROTO op_subfic_64 (void)
1223
{
1224
    T0 = (int64_t)PARAM1 + ~T0 + 1;
1225
    if ((uint64_t)T0 <= (uint64_t)PARAM1) {
1226
        xer_ca = 1;
1227
    } else {
1228
        xer_ca = 0;
1229
    }
1230
    RETURN();
1231
}
1232
#endif
1233

    
1234
/* subtract from minus one extended */
1235
void OPPROTO op_subfme (void)
1236
{
1237
    T0 = ~T0 + xer_ca - 1;
1238
    if (likely((uint32_t)T0 != (uint32_t)-1))
1239
        xer_ca = 1;
1240
    RETURN();
1241
}
1242

    
1243
#if defined(TARGET_PPC64)
1244
void OPPROTO op_subfme_64 (void)
1245
{
1246
    T0 = ~T0 + xer_ca - 1;
1247
    if (likely((uint64_t)T0 != (uint64_t)-1))
1248
        xer_ca = 1;
1249
    RETURN();
1250
}
1251
#endif
1252

    
1253
void OPPROTO op_subfmeo (void)
1254
{
1255
    do_subfmeo();
1256
    RETURN();
1257
}
1258

    
1259
#if defined(TARGET_PPC64)
1260
void OPPROTO op_subfmeo_64 (void)
1261
{
1262
    do_subfmeo_64();
1263
    RETURN();
1264
}
1265
#endif
1266

    
1267
/* subtract from zero extended */
1268
void OPPROTO op_subfze (void)
1269
{
1270
    T1 = ~T0;
1271
    T0 = T1 + xer_ca;
1272
    if ((uint32_t)T0 < (uint32_t)T1) {
1273
        xer_ca = 1;
1274
    } else {
1275
        xer_ca = 0;
1276
    }
1277
    RETURN();
1278
}
1279

    
1280
#if defined(TARGET_PPC64)
1281
void OPPROTO op_subfze_64 (void)
1282
{
1283
    T1 = ~T0;
1284
    T0 = T1 + xer_ca;
1285
    if ((uint64_t)T0 < (uint64_t)T1) {
1286
        xer_ca = 1;
1287
    } else {
1288
        xer_ca = 0;
1289
    }
1290
    RETURN();
1291
}
1292
#endif
1293

    
1294
void OPPROTO op_subfzeo (void)
1295
{
1296
    do_subfzeo();
1297
    RETURN();
1298
}
1299

    
1300
#if defined(TARGET_PPC64)
1301
void OPPROTO op_subfzeo_64 (void)
1302
{
1303
    do_subfzeo_64();
1304
    RETURN();
1305
}
1306
#endif
1307

    
1308
/***                           Integer comparison                          ***/
1309
/* compare */
1310
void OPPROTO op_cmp (void)
1311
{
1312
    if ((int32_t)T0 < (int32_t)T1) {
1313
        T0 = 0x08;
1314
    } else if ((int32_t)T0 > (int32_t)T1) {
1315
        T0 = 0x04;
1316
    } else {
1317
        T0 = 0x02;
1318
    }
1319
    T0 |= xer_so;
1320
    RETURN();
1321
}
1322

    
1323
#if defined(TARGET_PPC64)
1324
void OPPROTO op_cmp_64 (void)
1325
{
1326
    if ((int64_t)T0 < (int64_t)T1) {
1327
        T0 = 0x08;
1328
    } else if ((int64_t)T0 > (int64_t)T1) {
1329
        T0 = 0x04;
1330
    } else {
1331
        T0 = 0x02;
1332
    }
1333
    T0 |= xer_so;
1334
    RETURN();
1335
}
1336
#endif
1337

    
1338
/* compare immediate */
1339
void OPPROTO op_cmpi (void)
1340
{
1341
    if ((int32_t)T0 < (int32_t)PARAM1) {
1342
        T0 = 0x08;
1343
    } else if ((int32_t)T0 > (int32_t)PARAM1) {
1344
        T0 = 0x04;
1345
    } else {
1346
        T0 = 0x02;
1347
    }
1348
    T0 |= xer_so;
1349
    RETURN();
1350
}
1351

    
1352
#if defined(TARGET_PPC64)
1353
void OPPROTO op_cmpi_64 (void)
1354
{
1355
    if ((int64_t)T0 < (int64_t)((int32_t)PARAM1)) {
1356
        T0 = 0x08;
1357
    } else if ((int64_t)T0 > (int64_t)((int32_t)PARAM1)) {
1358
        T0 = 0x04;
1359
    } else {
1360
        T0 = 0x02;
1361
    }
1362
    T0 |= xer_so;
1363
    RETURN();
1364
}
1365
#endif
1366

    
1367
/* compare logical */
1368
void OPPROTO op_cmpl (void)
1369
{
1370
    if ((uint32_t)T0 < (uint32_t)T1) {
1371
        T0 = 0x08;
1372
    } else if ((uint32_t)T0 > (uint32_t)T1) {
1373
        T0 = 0x04;
1374
    } else {
1375
        T0 = 0x02;
1376
    }
1377
    T0 |= xer_so;
1378
    RETURN();
1379
}
1380

    
1381
#if defined(TARGET_PPC64)
1382
void OPPROTO op_cmpl_64 (void)
1383
{
1384
    if ((uint64_t)T0 < (uint64_t)T1) {
1385
        T0 = 0x08;
1386
    } else if ((uint64_t)T0 > (uint64_t)T1) {
1387
        T0 = 0x04;
1388
    } else {
1389
        T0 = 0x02;
1390
    }
1391
    T0 |= xer_so;
1392
    RETURN();
1393
}
1394
#endif
1395

    
1396
/* compare logical immediate */
1397
void OPPROTO op_cmpli (void)
1398
{
1399
    if ((uint32_t)T0 < (uint32_t)PARAM1) {
1400
        T0 = 0x08;
1401
    } else if ((uint32_t)T0 > (uint32_t)PARAM1) {
1402
        T0 = 0x04;
1403
    } else {
1404
        T0 = 0x02;
1405
    }
1406
    T0 |= xer_so;
1407
    RETURN();
1408
}
1409

    
1410
#if defined(TARGET_PPC64)
1411
void OPPROTO op_cmpli_64 (void)
1412
{
1413
    if ((uint64_t)T0 < (uint64_t)PARAM1) {
1414
        T0 = 0x08;
1415
    } else if ((uint64_t)T0 > (uint64_t)PARAM1) {
1416
        T0 = 0x04;
1417
    } else {
1418
        T0 = 0x02;
1419
    }
1420
    T0 |= xer_so;
1421
    RETURN();
1422
}
1423
#endif
1424

    
1425
void OPPROTO op_isel (void)
1426
{
1427
    if (T0)
1428
        T0 = T1;
1429
    else
1430
        T0 = T2;
1431
    RETURN();
1432
}
1433

    
1434
void OPPROTO op_popcntb (void)
1435
{
1436
    do_popcntb();
1437
    RETURN();
1438
}
1439

    
1440
#if defined(TARGET_PPC64)
1441
void OPPROTO op_popcntb_64 (void)
1442
{
1443
    do_popcntb_64();
1444
    RETURN();
1445
}
1446
#endif
1447

    
1448
/***                            Integer logical                            ***/
1449
/* and */
1450
void OPPROTO op_and (void)
1451
{
1452
    T0 &= T1;
1453
    RETURN();
1454
}
1455

    
1456
/* andc */
1457
void OPPROTO op_andc (void)
1458
{
1459
    T0 &= ~T1;
1460
    RETURN();
1461
}
1462

    
1463
/* andi. */
1464
void OPPROTO op_andi_T0 (void)
1465
{
1466
    T0 &= (uint32_t)PARAM1;
1467
    RETURN();
1468
}
1469

    
1470
void OPPROTO op_andi_T1 (void)
1471
{
1472
    T1 &= (uint32_t)PARAM1;
1473
    RETURN();
1474
}
1475

    
1476
#if defined(TARGET_PPC64)
1477
void OPPROTO op_andi_T0_64 (void)
1478
{
1479
    T0 &= ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
1480
    RETURN();
1481
}
1482

    
1483
void OPPROTO op_andi_T1_64 (void)
1484
{
1485
    T1 &= ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
1486
    RETURN();
1487
}
1488
#endif
1489

    
1490
/* count leading zero */
1491
void OPPROTO op_cntlzw (void)
1492
{
1493
    do_cntlzw();
1494
    RETURN();
1495
}
1496

    
1497
#if defined(TARGET_PPC64)
1498
void OPPROTO op_cntlzd (void)
1499
{
1500
    do_cntlzd();
1501
    RETURN();
1502
}
1503
#endif
1504

    
1505
/* eqv */
1506
void OPPROTO op_eqv (void)
1507
{
1508
    T0 = ~(T0 ^ T1);
1509
    RETURN();
1510
}
1511

    
1512
/* extend sign byte */
1513
void OPPROTO op_extsb (void)
1514
{
1515
#if defined (TARGET_PPC64)
1516
    T0 = (int64_t)((int8_t)T0);
1517
#else
1518
    T0 = (int32_t)((int8_t)T0);
1519
#endif
1520
    RETURN();
1521
}
1522

    
1523
/* extend sign half word */
1524
void OPPROTO op_extsh (void)
1525
{
1526
#if defined (TARGET_PPC64)
1527
    T0 = (int64_t)((int16_t)T0);
1528
#else
1529
    T0 = (int32_t)((int16_t)T0);
1530
#endif
1531
    RETURN();
1532
}
1533

    
1534
#if defined (TARGET_PPC64)
1535
void OPPROTO op_extsw (void)
1536
{
1537
    T0 = (int64_t)((int32_t)T0);
1538
    RETURN();
1539
}
1540
#endif
1541

    
1542
/* nand */
1543
void OPPROTO op_nand (void)
1544
{
1545
    T0 = ~(T0 & T1);
1546
    RETURN();
1547
}
1548

    
1549
/* nor */
1550
void OPPROTO op_nor (void)
1551
{
1552
    T0 = ~(T0 | T1);
1553
    RETURN();
1554
}
1555

    
1556
/* or */
1557
void OPPROTO op_or (void)
1558
{
1559
    T0 |= T1;
1560
    RETURN();
1561
}
1562

    
1563
/* orc */
1564
void OPPROTO op_orc (void)
1565
{
1566
    T0 |= ~T1;
1567
    RETURN();
1568
}
1569

    
1570
/* ori */
1571
void OPPROTO op_ori (void)
1572
{
1573
    T0 |= (uint32_t)PARAM1;
1574
    RETURN();
1575
}
1576

    
1577
/* xor */
1578
void OPPROTO op_xor (void)
1579
{
1580
    T0 ^= T1;
1581
    RETURN();
1582
}
1583

    
1584
/* xori */
1585
void OPPROTO op_xori (void)
1586
{
1587
    T0 ^= (uint32_t)PARAM1;
1588
    RETURN();
1589
}
1590

    
1591
/***                             Integer rotate                            ***/
1592
void OPPROTO op_rotl32_T0_T1 (void)
1593
{
1594
    T0 = rotl32(T0, T1 & 0x1F);
1595
    RETURN();
1596
}
1597

    
1598
void OPPROTO op_rotli32_T0 (void)
1599
{
1600
    T0 = rotl32(T0, PARAM1);
1601
    RETURN();
1602
}
1603

    
1604
#if defined(TARGET_PPC64)
1605
void OPPROTO op_rotl64_T0_T1 (void)
1606
{
1607
    T0 = rotl64(T0, T1 & 0x3F);
1608
    RETURN();
1609
}
1610

    
1611
void OPPROTO op_rotli64_T0 (void)
1612
{
1613
    T0 = rotl64(T0, PARAM1);
1614
    RETURN();
1615
}
1616
#endif
1617

    
1618
/***                             Integer shift                             ***/
1619
/* shift left word */
1620
void OPPROTO op_slw (void)
1621
{
1622
    if (T1 & 0x20) {
1623
        T0 = 0;
1624
    } else {
1625
        T0 = (uint32_t)(T0 << T1);
1626
    }
1627
    RETURN();
1628
}
1629

    
1630
#if defined(TARGET_PPC64)
1631
void OPPROTO op_sld (void)
1632
{
1633
    if (T1 & 0x40) {
1634
        T0 = 0;
1635
    } else {
1636
        T0 = T0 << T1;
1637
    }
1638
    RETURN();
1639
}
1640
#endif
1641

    
1642
/* shift right algebraic word */
1643
void OPPROTO op_sraw (void)
1644
{
1645
    do_sraw();
1646
    RETURN();
1647
}
1648

    
1649
#if defined(TARGET_PPC64)
1650
void OPPROTO op_srad (void)
1651
{
1652
    do_srad();
1653
    RETURN();
1654
}
1655
#endif
1656

    
1657
/* shift right algebraic word immediate */
1658
void OPPROTO op_srawi (void)
1659
{
1660
    uint32_t mask = (uint32_t)PARAM2;
1661

    
1662
    T0 = (int32_t)T0 >> PARAM1;
1663
    if ((int32_t)T1 < 0 && (T1 & mask) != 0) {
1664
        xer_ca = 1;
1665
    } else {
1666
        xer_ca = 0;
1667
    }
1668
    RETURN();
1669
}
1670

    
1671
#if defined(TARGET_PPC64)
1672
void OPPROTO op_sradi (void)
1673
{
1674
    uint64_t mask = ((uint64_t)PARAM2 << 32) | (uint64_t)PARAM3;
1675

    
1676
    T0 = (int64_t)T0 >> PARAM1;
1677
    if ((int64_t)T1 < 0 && ((uint64_t)T1 & mask) != 0) {
1678
        xer_ca = 1;
1679
    } else {
1680
        xer_ca = 0;
1681
    }
1682
    RETURN();
1683
}
1684
#endif
1685

    
1686
/* shift right word */
1687
void OPPROTO op_srw (void)
1688
{
1689
    if (T1 & 0x20) {
1690
        T0 = 0;
1691
    } else {
1692
        T0 = (uint32_t)T0 >> T1;
1693
    }
1694
    RETURN();
1695
}
1696

    
1697
#if defined(TARGET_PPC64)
1698
void OPPROTO op_srd (void)
1699
{
1700
    if (T1 & 0x40) {
1701
        T0 = 0;
1702
    } else {
1703
        T0 = (uint64_t)T0 >> T1;
1704
    }
1705
    RETURN();
1706
}
1707
#endif
1708

    
1709
void OPPROTO op_sl_T0_T1 (void)
1710
{
1711
    T0 = T0 << T1;
1712
    RETURN();
1713
}
1714

    
1715
void OPPROTO op_sli_T0 (void)
1716
{
1717
    T0 = T0 << PARAM1;
1718
    RETURN();
1719
}
1720

    
1721
void OPPROTO op_sli_T1 (void)
1722
{
1723
    T1 = T1 << PARAM1;
1724
    RETURN();
1725
}
1726

    
1727
void OPPROTO op_srl_T0_T1 (void)
1728
{
1729
    T0 = (uint32_t)T0 >> T1;
1730
    RETURN();
1731
}
1732

    
1733
#if defined(TARGET_PPC64)
1734
void OPPROTO op_srl_T0_T1_64 (void)
1735
{
1736
    T0 = (uint32_t)T0 >> T1;
1737
    RETURN();
1738
}
1739
#endif
1740

    
1741
void OPPROTO op_srli_T0 (void)
1742
{
1743
    T0 = (uint32_t)T0 >> PARAM1;
1744
    RETURN();
1745
}
1746

    
1747
#if defined(TARGET_PPC64)
1748
void OPPROTO op_srli_T0_64 (void)
1749
{
1750
    T0 = (uint64_t)T0 >> PARAM1;
1751
    RETURN();
1752
}
1753
#endif
1754

    
1755
void OPPROTO op_srli_T1 (void)
1756
{
1757
    T1 = (uint32_t)T1 >> PARAM1;
1758
    RETURN();
1759
}
1760

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

    
1769
/***                       Floating-Point arithmetic                       ***/
1770
/* fadd - fadd. */
1771
void OPPROTO op_fadd (void)
1772
{
1773
#if USE_PRECISE_EMULATION
1774
    do_fadd();
1775
#else
1776
    FT0 = float64_add(FT0, FT1, &env->fp_status);
1777
#endif
1778
    RETURN();
1779
}
1780

    
1781
/* fsub - fsub. */
1782
void OPPROTO op_fsub (void)
1783
{
1784
#if USE_PRECISE_EMULATION
1785
    do_fsub();
1786
#else
1787
    FT0 = float64_sub(FT0, FT1, &env->fp_status);
1788
#endif
1789
    RETURN();
1790
}
1791

    
1792
/* fmul - fmul. */
1793
void OPPROTO op_fmul (void)
1794
{
1795
#if USE_PRECISE_EMULATION
1796
    do_fmul();
1797
#else
1798
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1799
#endif
1800
    RETURN();
1801
}
1802

    
1803
/* fdiv - fdiv. */
1804
void OPPROTO op_fdiv (void)
1805
{
1806
#if USE_PRECISE_EMULATION
1807
    do_fdiv();
1808
#else
1809
    FT0 = float64_div(FT0, FT1, &env->fp_status);
1810
#endif
1811
    RETURN();
1812
}
1813

    
1814
/* fsqrt - fsqrt. */
1815
void OPPROTO op_fsqrt (void)
1816
{
1817
    do_fsqrt();
1818
    RETURN();
1819
}
1820

    
1821
/* fre - fre. */
1822
void OPPROTO op_fre (void)
1823
{
1824
    do_fre();
1825
    RETURN();
1826
}
1827

    
1828
/* fres - fres. */
1829
void OPPROTO op_fres (void)
1830
{
1831
    do_fres();
1832
    RETURN();
1833
}
1834

    
1835
/* frsqrte  - frsqrte. */
1836
void OPPROTO op_frsqrte (void)
1837
{
1838
    do_frsqrte();
1839
    RETURN();
1840
}
1841

    
1842
/* fsel - fsel. */
1843
void OPPROTO op_fsel (void)
1844
{
1845
    do_fsel();
1846
    RETURN();
1847
}
1848

    
1849
/***                     Floating-Point multiply-and-add                   ***/
1850
/* fmadd - fmadd. */
1851
void OPPROTO op_fmadd (void)
1852
{
1853
#if USE_PRECISE_EMULATION
1854
    do_fmadd();
1855
#else
1856
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1857
    FT0 = float64_add(FT0, FT2, &env->fp_status);
1858
#endif
1859
    RETURN();
1860
}
1861

    
1862
/* fmsub - fmsub. */
1863
void OPPROTO op_fmsub (void)
1864
{
1865
#if USE_PRECISE_EMULATION
1866
    do_fmsub();
1867
#else
1868
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1869
    FT0 = float64_sub(FT0, FT2, &env->fp_status);
1870
#endif
1871
    RETURN();
1872
}
1873

    
1874
/* fnmadd - fnmadd. - fnmadds - fnmadds. */
1875
void OPPROTO op_fnmadd (void)
1876
{
1877
    do_fnmadd();
1878
    RETURN();
1879
}
1880

    
1881
/* fnmsub - fnmsub. */
1882
void OPPROTO op_fnmsub (void)
1883
{
1884
    do_fnmsub();
1885
    RETURN();
1886
}
1887

    
1888
/***                     Floating-Point round & convert                    ***/
1889
/* frsp - frsp. */
1890
void OPPROTO op_frsp (void)
1891
{
1892
#if USE_PRECISE_EMULATION
1893
    do_frsp();
1894
#else
1895
    FT0 = float64_to_float32(FT0, &env->fp_status);
1896
#endif
1897
    RETURN();
1898
}
1899

    
1900
/* fctiw - fctiw. */
1901
void OPPROTO op_fctiw (void)
1902
{
1903
    do_fctiw();
1904
    RETURN();
1905
}
1906

    
1907
/* fctiwz - fctiwz. */
1908
void OPPROTO op_fctiwz (void)
1909
{
1910
    do_fctiwz();
1911
    RETURN();
1912
}
1913

    
1914
#if defined(TARGET_PPC64)
1915
/* fcfid - fcfid. */
1916
void OPPROTO op_fcfid (void)
1917
{
1918
    do_fcfid();
1919
    RETURN();
1920
}
1921

    
1922
/* fctid - fctid. */
1923
void OPPROTO op_fctid (void)
1924
{
1925
    do_fctid();
1926
    RETURN();
1927
}
1928

    
1929
/* fctidz - fctidz. */
1930
void OPPROTO op_fctidz (void)
1931
{
1932
    do_fctidz();
1933
    RETURN();
1934
}
1935
#endif
1936

    
1937
void OPPROTO op_frin (void)
1938
{
1939
    do_frin();
1940
    RETURN();
1941
}
1942

    
1943
void OPPROTO op_friz (void)
1944
{
1945
    do_friz();
1946
    RETURN();
1947
}
1948

    
1949
void OPPROTO op_frip (void)
1950
{
1951
    do_frip();
1952
    RETURN();
1953
}
1954

    
1955
void OPPROTO op_frim (void)
1956
{
1957
    do_frim();
1958
    RETURN();
1959
}
1960

    
1961
/***                         Floating-Point compare                        ***/
1962
/* fcmpu */
1963
void OPPROTO op_fcmpu (void)
1964
{
1965
    do_fcmpu();
1966
    RETURN();
1967
}
1968

    
1969
/* fcmpo */
1970
void OPPROTO op_fcmpo (void)
1971
{
1972
    do_fcmpo();
1973
    RETURN();
1974
}
1975

    
1976
/***                         Floating-point move                           ***/
1977
/* fabs */
1978
void OPPROTO op_fabs (void)
1979
{
1980
    FT0 = float64_abs(FT0);
1981
    RETURN();
1982
}
1983

    
1984
/* fnabs */
1985
void OPPROTO op_fnabs (void)
1986
{
1987
    FT0 = float64_abs(FT0);
1988
    FT0 = float64_chs(FT0);
1989
    RETURN();
1990
}
1991

    
1992
/* fneg */
1993
void OPPROTO op_fneg (void)
1994
{
1995
    FT0 = float64_chs(FT0);
1996
    RETURN();
1997
}
1998

    
1999
/* Load and store */
2000
#define MEMSUFFIX _raw
2001
#include "op_helper.h"
2002
#include "op_mem.h"
2003
#if !defined(CONFIG_USER_ONLY)
2004
#define MEMSUFFIX _user
2005
#include "op_helper.h"
2006
#include "op_mem.h"
2007
#define MEMSUFFIX _kernel
2008
#include "op_helper.h"
2009
#include "op_mem.h"
2010
#if defined(TARGET_PPC64H)
2011
#define MEMSUFFIX _hypv
2012
#include "op_helper.h"
2013
#include "op_mem.h"
2014
#endif
2015
#endif
2016

    
2017
/* Special op to check and maybe clear reservation */
2018
void OPPROTO op_check_reservation (void)
2019
{
2020
    if ((uint32_t)env->reserve == (uint32_t)(T0 & ~0x00000003))
2021
        env->reserve = -1;
2022
    RETURN();
2023
}
2024

    
2025
#if defined(TARGET_PPC64)
2026
void OPPROTO op_check_reservation_64 (void)
2027
{
2028
    if ((uint64_t)env->reserve == (uint64_t)(T0 & ~0x00000003))
2029
        env->reserve = -1;
2030
    RETURN();
2031
}
2032
#endif
2033

    
2034
void OPPROTO op_wait (void)
2035
{
2036
    env->halted = 1;
2037
    RETURN();
2038
}
2039

    
2040
/* Return from interrupt */
2041
#if !defined(CONFIG_USER_ONLY)
2042
void OPPROTO op_rfi (void)
2043
{
2044
    do_rfi();
2045
    RETURN();
2046
}
2047

    
2048
#if defined(TARGET_PPC64)
2049
void OPPROTO op_rfid (void)
2050
{
2051
    do_rfid();
2052
    RETURN();
2053
}
2054
#endif
2055

    
2056
#if defined(TARGET_PPC64H)
2057
void OPPROTO op_hrfid (void)
2058
{
2059
    do_hrfid();
2060
    RETURN();
2061
}
2062
#endif
2063

    
2064
/* Exception vectors */
2065
void OPPROTO op_store_excp_prefix (void)
2066
{
2067
    T0 &= env->ivpr_mask;
2068
    env->excp_prefix = T0;
2069
    RETURN();
2070
}
2071

    
2072
void OPPROTO op_store_excp_vector (void)
2073
{
2074
    T0 &= env->ivor_mask;
2075
    env->excp_vectors[PARAM1] = T0;
2076
    RETURN();
2077
}
2078
#endif
2079

    
2080
/* Trap word */
2081
void OPPROTO op_tw (void)
2082
{
2083
    do_tw(PARAM1);
2084
    RETURN();
2085
}
2086

    
2087
#if defined(TARGET_PPC64)
2088
void OPPROTO op_td (void)
2089
{
2090
    do_td(PARAM1);
2091
    RETURN();
2092
}
2093
#endif
2094

    
2095
#if !defined(CONFIG_USER_ONLY)
2096
/* tlbia */
2097
void OPPROTO op_tlbia (void)
2098
{
2099
    ppc_tlb_invalidate_all(env);
2100
    RETURN();
2101
}
2102

    
2103
/* tlbie */
2104
void OPPROTO op_tlbie (void)
2105
{
2106
    ppc_tlb_invalidate_one(env, (uint32_t)T0);
2107
    RETURN();
2108
}
2109

    
2110
#if defined(TARGET_PPC64)
2111
void OPPROTO op_tlbie_64 (void)
2112
{
2113
    ppc_tlb_invalidate_one(env, T0);
2114
    RETURN();
2115
}
2116
#endif
2117

    
2118
#if defined(TARGET_PPC64)
2119
void OPPROTO op_slbia (void)
2120
{
2121
    ppc_slb_invalidate_all(env);
2122
    RETURN();
2123
}
2124

    
2125
void OPPROTO op_slbie (void)
2126
{
2127
    ppc_slb_invalidate_one(env, (uint32_t)T0);
2128
    RETURN();
2129
}
2130

    
2131
void OPPROTO op_slbie_64 (void)
2132
{
2133
    ppc_slb_invalidate_one(env, T0);
2134
    RETURN();
2135
}
2136
#endif
2137
#endif
2138

    
2139
#if !defined(CONFIG_USER_ONLY)
2140
/* PowerPC 602/603/755 software TLB load instructions */
2141
void OPPROTO op_6xx_tlbld (void)
2142
{
2143
    do_load_6xx_tlb(0);
2144
    RETURN();
2145
}
2146

    
2147
void OPPROTO op_6xx_tlbli (void)
2148
{
2149
    do_load_6xx_tlb(1);
2150
    RETURN();
2151
}
2152

    
2153
/* PowerPC 74xx software TLB load instructions */
2154
void OPPROTO op_74xx_tlbld (void)
2155
{
2156
    do_load_74xx_tlb(0);
2157
    RETURN();
2158
}
2159

    
2160
void OPPROTO op_74xx_tlbli (void)
2161
{
2162
    do_load_74xx_tlb(1);
2163
    RETURN();
2164
}
2165
#endif
2166

    
2167
/* 601 specific */
2168
void OPPROTO op_load_601_rtcl (void)
2169
{
2170
    T0 = cpu_ppc601_load_rtcl(env);
2171
    RETURN();
2172
}
2173

    
2174
void OPPROTO op_load_601_rtcu (void)
2175
{
2176
    T0 = cpu_ppc601_load_rtcu(env);
2177
    RETURN();
2178
}
2179

    
2180
#if !defined(CONFIG_USER_ONLY)
2181
void OPPROTO op_store_601_rtcl (void)
2182
{
2183
    cpu_ppc601_store_rtcl(env, T0);
2184
    RETURN();
2185
}
2186

    
2187
void OPPROTO op_store_601_rtcu (void)
2188
{
2189
    cpu_ppc601_store_rtcu(env, T0);
2190
    RETURN();
2191
}
2192

    
2193
void OPPROTO op_load_601_bat (void)
2194
{
2195
    T0 = env->IBAT[PARAM1][PARAM2];
2196
    RETURN();
2197
}
2198
#endif /* !defined(CONFIG_USER_ONLY) */
2199

    
2200
/* 601 unified BATs store.
2201
 * To avoid using specific MMU code for 601, we store BATs in
2202
 * IBAT and DBAT simultaneously, then emulate unified BATs.
2203
 */
2204
#if !defined(CONFIG_USER_ONLY)
2205
void OPPROTO op_store_601_batl (void)
2206
{
2207
    int nr = PARAM1;
2208

    
2209
    env->IBAT[1][nr] = T0;
2210
    env->DBAT[1][nr] = T0;
2211
    RETURN();
2212
}
2213

    
2214
void OPPROTO op_store_601_batu (void)
2215
{
2216
    do_store_601_batu(PARAM1);
2217
    RETURN();
2218
}
2219
#endif /* !defined(CONFIG_USER_ONLY) */
2220

    
2221
/* PowerPC 601 specific instructions (POWER bridge) */
2222
/* XXX: those micro-ops need tests ! */
2223
void OPPROTO op_POWER_abs (void)
2224
{
2225
    if (T0 == INT32_MIN)
2226
        T0 = INT32_MAX;
2227
    else if (T0 < 0)
2228
        T0 = -T0;
2229
    RETURN();
2230
}
2231

    
2232
void OPPROTO op_POWER_abso (void)
2233
{
2234
    do_POWER_abso();
2235
    RETURN();
2236
}
2237

    
2238
void OPPROTO op_POWER_clcs (void)
2239
{
2240
    do_POWER_clcs();
2241
    RETURN();
2242
}
2243

    
2244
void OPPROTO op_POWER_div (void)
2245
{
2246
    do_POWER_div();
2247
    RETURN();
2248
}
2249

    
2250
void OPPROTO op_POWER_divo (void)
2251
{
2252
    do_POWER_divo();
2253
    RETURN();
2254
}
2255

    
2256
void OPPROTO op_POWER_divs (void)
2257
{
2258
    do_POWER_divs();
2259
    RETURN();
2260
}
2261

    
2262
void OPPROTO op_POWER_divso (void)
2263
{
2264
    do_POWER_divso();
2265
    RETURN();
2266
}
2267

    
2268
void OPPROTO op_POWER_doz (void)
2269
{
2270
    if ((int32_t)T1 > (int32_t)T0)
2271
        T0 = T1 - T0;
2272
    else
2273
        T0 = 0;
2274
    RETURN();
2275
}
2276

    
2277
void OPPROTO op_POWER_dozo (void)
2278
{
2279
    do_POWER_dozo();
2280
    RETURN();
2281
}
2282

    
2283
void OPPROTO op_load_xer_cmp (void)
2284
{
2285
    T2 = xer_cmp;
2286
    RETURN();
2287
}
2288

    
2289
void OPPROTO op_POWER_maskg (void)
2290
{
2291
    do_POWER_maskg();
2292
    RETURN();
2293
}
2294

    
2295
void OPPROTO op_POWER_maskir (void)
2296
{
2297
    T0 = (T0 & ~T2) | (T1 & T2);
2298
    RETURN();
2299
}
2300

    
2301
void OPPROTO op_POWER_mul (void)
2302
{
2303
    uint64_t tmp;
2304

    
2305
    tmp = (uint64_t)T0 * (uint64_t)T1;
2306
    env->spr[SPR_MQ] = tmp >> 32;
2307
    T0 = tmp;
2308
    RETURN();
2309
}
2310

    
2311
void OPPROTO op_POWER_mulo (void)
2312
{
2313
    do_POWER_mulo();
2314
    RETURN();
2315
}
2316

    
2317
void OPPROTO op_POWER_nabs (void)
2318
{
2319
    if (T0 > 0)
2320
        T0 = -T0;
2321
    RETURN();
2322
}
2323

    
2324
void OPPROTO op_POWER_nabso (void)
2325
{
2326
    /* nabs never overflows */
2327
    if (T0 > 0)
2328
        T0 = -T0;
2329
    xer_ov = 0;
2330
    RETURN();
2331
}
2332

    
2333
/* XXX: factorise POWER rotates... */
2334
void OPPROTO op_POWER_rlmi (void)
2335
{
2336
    T0 = rotl32(T0, T2) & PARAM1;
2337
    T0 |= T1 & (uint32_t)PARAM2;
2338
    RETURN();
2339
}
2340

    
2341
void OPPROTO op_POWER_rrib (void)
2342
{
2343
    T2 &= 0x1FUL;
2344
    T0 = rotl32(T0 & INT32_MIN, T2);
2345
    T0 |= T1 & ~rotl32(INT32_MIN, T2);
2346
    RETURN();
2347
}
2348

    
2349
void OPPROTO op_POWER_sle (void)
2350
{
2351
    T1 &= 0x1FUL;
2352
    env->spr[SPR_MQ] = rotl32(T0, T1);
2353
    T0 = T0 << T1;
2354
    RETURN();
2355
}
2356

    
2357
void OPPROTO op_POWER_sleq (void)
2358
{
2359
    uint32_t tmp = env->spr[SPR_MQ];
2360

    
2361
    T1 &= 0x1FUL;
2362
    env->spr[SPR_MQ] = rotl32(T0, T1);
2363
    T0 = T0 << T1;
2364
    T0 |= tmp >> (32 - T1);
2365
    RETURN();
2366
}
2367

    
2368
void OPPROTO op_POWER_sllq (void)
2369
{
2370
    uint32_t msk = -1;
2371

    
2372
    msk = msk << (T1 & 0x1FUL);
2373
    if (T1 & 0x20UL)
2374
        msk = ~msk;
2375
    T1 &= 0x1FUL;
2376
    T0 = (T0 << T1) & msk;
2377
    T0 |= env->spr[SPR_MQ] & ~msk;
2378
    RETURN();
2379
}
2380

    
2381
void OPPROTO op_POWER_slq (void)
2382
{
2383
    uint32_t msk = -1, tmp;
2384

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

    
2395
void OPPROTO op_POWER_sraq (void)
2396
{
2397
    env->spr[SPR_MQ] = rotl32(T0, 32 - (T1 & 0x1FUL));
2398
    if (T1 & 0x20UL)
2399
        T0 = -1L;
2400
    else
2401
        T0 = (int32_t)T0 >> T1;
2402
    RETURN();
2403
}
2404

    
2405
void OPPROTO op_POWER_sre (void)
2406
{
2407
    T1 &= 0x1FUL;
2408
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2409
    T0 = (int32_t)T0 >> T1;
2410
    RETURN();
2411
}
2412

    
2413
void OPPROTO op_POWER_srea (void)
2414
{
2415
    T1 &= 0x1FUL;
2416
    env->spr[SPR_MQ] = T0 >> T1;
2417
    T0 = (int32_t)T0 >> T1;
2418
    RETURN();
2419
}
2420

    
2421
void OPPROTO op_POWER_sreq (void)
2422
{
2423
    uint32_t tmp;
2424
    int32_t msk;
2425

    
2426
    T1 &= 0x1FUL;
2427
    msk = INT32_MIN >> T1;
2428
    tmp = env->spr[SPR_MQ];
2429
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2430
    T0 = T0 >> T1;
2431
    T0 |= tmp & msk;
2432
    RETURN();
2433
}
2434

    
2435
void OPPROTO op_POWER_srlq (void)
2436
{
2437
    uint32_t tmp;
2438
    int32_t msk;
2439

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

    
2452
void OPPROTO op_POWER_srq (void)
2453
{
2454
    T1 &= 0x1FUL;
2455
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2456
    T0 = T0 >> T1;
2457
    RETURN();
2458
}
2459

    
2460
/* POWER instructions not implemented in PowerPC 601 */
2461
#if !defined(CONFIG_USER_ONLY)
2462
void OPPROTO op_POWER_mfsri (void)
2463
{
2464
    T1 = T0 >> 28;
2465
    T0 = env->sr[T1];
2466
    RETURN();
2467
}
2468

    
2469
void OPPROTO op_POWER_rac (void)
2470
{
2471
    do_POWER_rac();
2472
    RETURN();
2473
}
2474

    
2475
void OPPROTO op_POWER_rfsvc (void)
2476
{
2477
    do_POWER_rfsvc();
2478
    RETURN();
2479
}
2480
#endif
2481

    
2482
/* PowerPC 602 specific instruction */
2483
#if !defined(CONFIG_USER_ONLY)
2484
void OPPROTO op_602_mfrom (void)
2485
{
2486
    do_op_602_mfrom();
2487
    RETURN();
2488
}
2489
#endif
2490

    
2491
/* PowerPC 4xx specific micro-ops */
2492
void OPPROTO op_405_add_T0_T2 (void)
2493
{
2494
    T0 = (int32_t)T0 + (int32_t)T2;
2495
    RETURN();
2496
}
2497

    
2498
void OPPROTO op_405_mulchw (void)
2499
{
2500
    T0 = ((int16_t)T0) * ((int16_t)(T1 >> 16));
2501
    RETURN();
2502
}
2503

    
2504
void OPPROTO op_405_mulchwu (void)
2505
{
2506
    T0 = ((uint16_t)T0) * ((uint16_t)(T1 >> 16));
2507
    RETURN();
2508
}
2509

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

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

    
2522
void OPPROTO op_405_mullhw (void)
2523
{
2524
    T0 = ((int16_t)T0) * ((int16_t)T1);
2525
    RETURN();
2526
}
2527

    
2528
void OPPROTO op_405_mullhwu (void)
2529
{
2530
    T0 = ((uint16_t)T0) * ((uint16_t)T1);
2531
    RETURN();
2532
}
2533

    
2534
void OPPROTO op_405_check_ov (void)
2535
{
2536
    do_405_check_ov();
2537
    RETURN();
2538
}
2539

    
2540
void OPPROTO op_405_check_sat (void)
2541
{
2542
    do_405_check_sat();
2543
    RETURN();
2544
}
2545

    
2546
void OPPROTO op_405_check_ovu (void)
2547
{
2548
    if (likely(T0 >= T2)) {
2549
        xer_ov = 0;
2550
    } else {
2551
        xer_ov = 1;
2552
        xer_so = 1;
2553
    }
2554
    RETURN();
2555
}
2556

    
2557
void OPPROTO op_405_check_satu (void)
2558
{
2559
    if (unlikely(T0 < T2)) {
2560
        /* Saturate result */
2561
        T0 = -1;
2562
    }
2563
    RETURN();
2564
}
2565

    
2566
void OPPROTO op_load_dcr (void)
2567
{
2568
    do_load_dcr();
2569
    RETURN();
2570
}
2571

    
2572
void OPPROTO op_store_dcr (void)
2573
{
2574
    do_store_dcr();
2575
    RETURN();
2576
}
2577

    
2578
#if !defined(CONFIG_USER_ONLY)
2579
/* Return from critical interrupt :
2580
 * same as rfi, except nip & MSR are loaded from SRR2/3 instead of SRR0/1
2581
 */
2582
void OPPROTO op_40x_rfci (void)
2583
{
2584
    do_40x_rfci();
2585
    RETURN();
2586
}
2587

    
2588
void OPPROTO op_rfci (void)
2589
{
2590
    do_rfci();
2591
    RETURN();
2592
}
2593

    
2594
void OPPROTO op_rfdi (void)
2595
{
2596
    do_rfdi();
2597
    RETURN();
2598
}
2599

    
2600
void OPPROTO op_rfmci (void)
2601
{
2602
    do_rfmci();
2603
    RETURN();
2604
}
2605

    
2606
void OPPROTO op_wrte (void)
2607
{
2608
    /* We don't call do_store_msr here as we won't trigger
2609
     * any special case nor change hflags
2610
     */
2611
    T0 &= 1 << MSR_EE;
2612
    env->msr &= ~(1 << MSR_EE);
2613
    env->msr |= T0;
2614
    RETURN();
2615
}
2616

    
2617
void OPPROTO op_440_tlbre (void)
2618
{
2619
    do_440_tlbre(PARAM1);
2620
    RETURN();
2621
}
2622

    
2623
void OPPROTO op_440_tlbsx (void)
2624
{
2625
    T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_440_MMUCR] & 0xFF);
2626
    RETURN();
2627
}
2628

    
2629
void OPPROTO op_4xx_tlbsx_check (void)
2630
{
2631
    int tmp;
2632

    
2633
    tmp = xer_so;
2634
    if (T0 != -1)
2635
        tmp |= 0x02;
2636
    env->crf[0] = tmp;
2637
    RETURN();
2638
}
2639

    
2640
void OPPROTO op_440_tlbwe (void)
2641
{
2642
    do_440_tlbwe(PARAM1);
2643
    RETURN();
2644
}
2645

    
2646
void OPPROTO op_4xx_tlbre_lo (void)
2647
{
2648
    do_4xx_tlbre_lo();
2649
    RETURN();
2650
}
2651

    
2652
void OPPROTO op_4xx_tlbre_hi (void)
2653
{
2654
    do_4xx_tlbre_hi();
2655
    RETURN();
2656
}
2657

    
2658
void OPPROTO op_4xx_tlbsx (void)
2659
{
2660
    T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_40x_PID]);
2661
    RETURN();
2662
}
2663

    
2664
void OPPROTO op_4xx_tlbwe_lo (void)
2665
{
2666
    do_4xx_tlbwe_lo();
2667
    RETURN();
2668
}
2669

    
2670
void OPPROTO op_4xx_tlbwe_hi (void)
2671
{
2672
    do_4xx_tlbwe_hi();
2673
    RETURN();
2674
}
2675
#endif
2676

    
2677
/* SPR micro-ops */
2678
/* 440 specific */
2679
void OPPROTO op_440_dlmzb (void)
2680
{
2681
    do_440_dlmzb();
2682
    RETURN();
2683
}
2684

    
2685
void OPPROTO op_440_dlmzb_update_Rc (void)
2686
{
2687
    if (T0 == 8)
2688
        T0 = 0x2;
2689
    else if (T0 < 4)
2690
        T0 = 0x4;
2691
    else
2692
        T0 = 0x8;
2693
    RETURN();
2694
}
2695

    
2696
#if !defined(CONFIG_USER_ONLY)
2697
void OPPROTO op_store_pir (void)
2698
{
2699
    env->spr[SPR_PIR] = T0 & 0x0000000FUL;
2700
    RETURN();
2701
}
2702

    
2703
void OPPROTO op_load_403_pb (void)
2704
{
2705
    do_load_403_pb(PARAM1);
2706
    RETURN();
2707
}
2708

    
2709
void OPPROTO op_store_403_pb (void)
2710
{
2711
    do_store_403_pb(PARAM1);
2712
    RETURN();
2713
}
2714

    
2715
void OPPROTO op_load_40x_pit (void)
2716
{
2717
    T0 = load_40x_pit(env);
2718
    RETURN();
2719
}
2720

    
2721
void OPPROTO op_store_40x_pit (void)
2722
{
2723
    store_40x_pit(env, T0);
2724
    RETURN();
2725
}
2726

    
2727
void OPPROTO op_store_40x_dbcr0 (void)
2728
{
2729
    store_40x_dbcr0(env, T0);
2730
    RETURN();
2731
}
2732

    
2733
void OPPROTO op_store_40x_sler (void)
2734
{
2735
    store_40x_sler(env, T0);
2736
    RETURN();
2737
}
2738

    
2739
void OPPROTO op_store_booke_tcr (void)
2740
{
2741
    store_booke_tcr(env, T0);
2742
    RETURN();
2743
}
2744

    
2745
void OPPROTO op_store_booke_tsr (void)
2746
{
2747
    store_booke_tsr(env, T0);
2748
    RETURN();
2749
}
2750
#endif /* !defined(CONFIG_USER_ONLY) */
2751

    
2752
#if defined(TARGET_PPCEMB)
2753
/* SPE extension */
2754
void OPPROTO op_splatw_T1_64 (void)
2755
{
2756
    T1_64 = (T1_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL);
2757
    RETURN();
2758
}
2759

    
2760
void OPPROTO op_splatwi_T0_64 (void)
2761
{
2762
    uint64_t tmp = PARAM1;
2763

    
2764
    T0_64 = (tmp << 32) | tmp;
2765
    RETURN();
2766
}
2767

    
2768
void OPPROTO op_splatwi_T1_64 (void)
2769
{
2770
    uint64_t tmp = PARAM1;
2771

    
2772
    T1_64 = (tmp << 32) | tmp;
2773
    RETURN();
2774
}
2775

    
2776
void OPPROTO op_extsh_T1_64 (void)
2777
{
2778
    T1_64 = (int32_t)((int16_t)T1_64);
2779
    RETURN();
2780
}
2781

    
2782
void OPPROTO op_sli16_T1_64 (void)
2783
{
2784
    T1_64 = T1_64 << 16;
2785
    RETURN();
2786
}
2787

    
2788
void OPPROTO op_sli32_T1_64 (void)
2789
{
2790
    T1_64 = T1_64 << 32;
2791
    RETURN();
2792
}
2793

    
2794
void OPPROTO op_srli32_T1_64 (void)
2795
{
2796
    T1_64 = T1_64 >> 32;
2797
    RETURN();
2798
}
2799

    
2800
void OPPROTO op_evsel (void)
2801
{
2802
    do_evsel();
2803
    RETURN();
2804
}
2805

    
2806
void OPPROTO op_evaddw (void)
2807
{
2808
    do_evaddw();
2809
    RETURN();
2810
}
2811

    
2812
void OPPROTO op_evsubfw (void)
2813
{
2814
    do_evsubfw();
2815
    RETURN();
2816
}
2817

    
2818
void OPPROTO op_evneg (void)
2819
{
2820
    do_evneg();
2821
    RETURN();
2822
}
2823

    
2824
void OPPROTO op_evabs (void)
2825
{
2826
    do_evabs();
2827
    RETURN();
2828
}
2829

    
2830
void OPPROTO op_evextsh (void)
2831
{
2832
    T0_64 = ((uint64_t)((int32_t)(int16_t)(T0_64 >> 32)) << 32) |
2833
        (uint64_t)((int32_t)(int16_t)T0_64);
2834
    RETURN();
2835
}
2836

    
2837
void OPPROTO op_evextsb (void)
2838
{
2839
    T0_64 = ((uint64_t)((int32_t)(int8_t)(T0_64 >> 32)) << 32) |
2840
        (uint64_t)((int32_t)(int8_t)T0_64);
2841
    RETURN();
2842
}
2843

    
2844
void OPPROTO op_evcntlzw (void)
2845
{
2846
    do_evcntlzw();
2847
    RETURN();
2848
}
2849

    
2850
void OPPROTO op_evrndw (void)
2851
{
2852
    do_evrndw();
2853
    RETURN();
2854
}
2855

    
2856
void OPPROTO op_brinc (void)
2857
{
2858
    do_brinc();
2859
    RETURN();
2860
}
2861

    
2862
void OPPROTO op_evcntlsw (void)
2863
{
2864
    do_evcntlsw();
2865
    RETURN();
2866
}
2867

    
2868
void OPPROTO op_evand (void)
2869
{
2870
    T0_64 &= T1_64;
2871
    RETURN();
2872
}
2873

    
2874
void OPPROTO op_evandc (void)
2875
{
2876
    T0_64 &= ~T1_64;
2877
    RETURN();
2878
}
2879

    
2880
void OPPROTO op_evor (void)
2881
{
2882
    T0_64 |= T1_64;
2883
    RETURN();
2884
}
2885

    
2886
void OPPROTO op_evxor (void)
2887
{
2888
    T0_64 ^= T1_64;
2889
    RETURN();
2890
}
2891

    
2892
void OPPROTO op_eveqv (void)
2893
{
2894
    T0_64 = ~(T0_64 ^ T1_64);
2895
    RETURN();
2896
}
2897

    
2898
void OPPROTO op_evnor (void)
2899
{
2900
    T0_64 = ~(T0_64 | T1_64);
2901
    RETURN();
2902
}
2903

    
2904
void OPPROTO op_evorc (void)
2905
{
2906
    T0_64 |= ~T1_64;
2907
    RETURN();
2908
}
2909

    
2910
void OPPROTO op_evnand (void)
2911
{
2912
    T0_64 = ~(T0_64 & T1_64);
2913
    RETURN();
2914
}
2915

    
2916
void OPPROTO op_evsrws (void)
2917
{
2918
    do_evsrws();
2919
    RETURN();
2920
}
2921

    
2922
void OPPROTO op_evsrwu (void)
2923
{
2924
    do_evsrwu();
2925
    RETURN();
2926
}
2927

    
2928
void OPPROTO op_evslw (void)
2929
{
2930
    do_evslw();
2931
    RETURN();
2932
}
2933

    
2934
void OPPROTO op_evrlw (void)
2935
{
2936
    do_evrlw();
2937
    RETURN();
2938
}
2939

    
2940
void OPPROTO op_evmergelo (void)
2941
{
2942
    T0_64 = (T0_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL);
2943
    RETURN();
2944
}
2945

    
2946
void OPPROTO op_evmergehi (void)
2947
{
2948
    T0_64 = (T0_64 & 0xFFFFFFFF00000000ULL) | (T1_64 >> 32);
2949
    RETURN();
2950
}
2951

    
2952
void OPPROTO op_evmergelohi (void)
2953
{
2954
    T0_64 = (T0_64 << 32) | (T1_64 >> 32);
2955
    RETURN();
2956
}
2957

    
2958
void OPPROTO op_evmergehilo (void)
2959
{
2960
    T0_64 = (T0_64 & 0xFFFFFFFF00000000ULL) | (T1_64 & 0x00000000FFFFFFFFULL);
2961
    RETURN();
2962
}
2963

    
2964
void OPPROTO op_evcmpgts (void)
2965
{
2966
    do_evcmpgts();
2967
    RETURN();
2968
}
2969

    
2970
void OPPROTO op_evcmpgtu (void)
2971
{
2972
    do_evcmpgtu();
2973
    RETURN();
2974
}
2975

    
2976
void OPPROTO op_evcmplts (void)
2977
{
2978
    do_evcmplts();
2979
    RETURN();
2980
}
2981

    
2982
void OPPROTO op_evcmpltu (void)
2983
{
2984
    do_evcmpltu();
2985
    RETURN();
2986
}
2987

    
2988
void OPPROTO op_evcmpeq (void)
2989
{
2990
    do_evcmpeq();
2991
    RETURN();
2992
}
2993

    
2994
void OPPROTO op_evfssub (void)
2995
{
2996
    do_evfssub();
2997
    RETURN();
2998
}
2999

    
3000
void OPPROTO op_evfsadd (void)
3001
{
3002
    do_evfsadd();
3003
    RETURN();
3004
}
3005

    
3006
void OPPROTO op_evfsnabs (void)
3007
{
3008
    do_evfsnabs();
3009
    RETURN();
3010
}
3011

    
3012
void OPPROTO op_evfsabs (void)
3013
{
3014
    do_evfsabs();
3015
    RETURN();
3016
}
3017

    
3018
void OPPROTO op_evfsneg (void)
3019
{
3020
    do_evfsneg();
3021
    RETURN();
3022
}
3023

    
3024
void OPPROTO op_evfsdiv (void)
3025
{
3026
    do_evfsdiv();
3027
    RETURN();
3028
}
3029

    
3030
void OPPROTO op_evfsmul (void)
3031
{
3032
    do_evfsmul();
3033
    RETURN();
3034
}
3035

    
3036
void OPPROTO op_evfscmplt (void)
3037
{
3038
    do_evfscmplt();
3039
    RETURN();
3040
}
3041

    
3042
void OPPROTO op_evfscmpgt (void)
3043
{
3044
    do_evfscmpgt();
3045
    RETURN();
3046
}
3047

    
3048
void OPPROTO op_evfscmpeq (void)
3049
{
3050
    do_evfscmpeq();
3051
    RETURN();
3052
}
3053

    
3054
void OPPROTO op_evfscfsi (void)
3055
{
3056
    do_evfscfsi();
3057
    RETURN();
3058
}
3059

    
3060
void OPPROTO op_evfscfui (void)
3061
{
3062
    do_evfscfui();
3063
    RETURN();
3064
}
3065

    
3066
void OPPROTO op_evfscfsf (void)
3067
{
3068
    do_evfscfsf();
3069
    RETURN();
3070
}
3071

    
3072
void OPPROTO op_evfscfuf (void)
3073
{
3074
    do_evfscfuf();
3075
    RETURN();
3076
}
3077

    
3078
void OPPROTO op_evfsctsi (void)
3079
{
3080
    do_evfsctsi();
3081
    RETURN();
3082
}
3083

    
3084
void OPPROTO op_evfsctui (void)
3085
{
3086
    do_evfsctui();
3087
    RETURN();
3088
}
3089

    
3090
void OPPROTO op_evfsctsf (void)
3091
{
3092
    do_evfsctsf();
3093
    RETURN();
3094
}
3095

    
3096
void OPPROTO op_evfsctuf (void)
3097
{
3098
    do_evfsctuf();
3099
    RETURN();
3100
}
3101

    
3102
void OPPROTO op_evfsctuiz (void)
3103
{
3104
    do_evfsctuiz();
3105
    RETURN();
3106
}
3107

    
3108
void OPPROTO op_evfsctsiz (void)
3109
{
3110
    do_evfsctsiz();
3111
    RETURN();
3112
}
3113

    
3114
void OPPROTO op_evfststlt (void)
3115
{
3116
    do_evfststlt();
3117
    RETURN();
3118
}
3119

    
3120
void OPPROTO op_evfststgt (void)
3121
{
3122
    do_evfststgt();
3123
    RETURN();
3124
}
3125

    
3126
void OPPROTO op_evfststeq (void)
3127
{
3128
    do_evfststeq();
3129
    RETURN();
3130
}
3131

    
3132
void OPPROTO op_efssub (void)
3133
{
3134
    T0_64 = _do_efssub(T0_64, T1_64);
3135
    RETURN();
3136
}
3137

    
3138
void OPPROTO op_efsadd (void)
3139
{
3140
    T0_64 = _do_efsadd(T0_64, T1_64);
3141
    RETURN();
3142
}
3143

    
3144
void OPPROTO op_efsnabs (void)
3145
{
3146
    T0_64 = _do_efsnabs(T0_64);
3147
    RETURN();
3148
}
3149

    
3150
void OPPROTO op_efsabs (void)
3151
{
3152
    T0_64 = _do_efsabs(T0_64);
3153
    RETURN();
3154
}
3155

    
3156
void OPPROTO op_efsneg (void)
3157
{
3158
    T0_64 = _do_efsneg(T0_64);
3159
    RETURN();
3160
}
3161

    
3162
void OPPROTO op_efsdiv (void)
3163
{
3164
    T0_64 = _do_efsdiv(T0_64, T1_64);
3165
    RETURN();
3166
}
3167

    
3168
void OPPROTO op_efsmul (void)
3169
{
3170
    T0_64 = _do_efsmul(T0_64, T1_64);
3171
    RETURN();
3172
}
3173

    
3174
void OPPROTO op_efscmplt (void)
3175
{
3176
    do_efscmplt();
3177
    RETURN();
3178
}
3179

    
3180
void OPPROTO op_efscmpgt (void)
3181
{
3182
    do_efscmpgt();
3183
    RETURN();
3184
}
3185

    
3186
void OPPROTO op_efscfd (void)
3187
{
3188
    do_efscfd();
3189
    RETURN();
3190
}
3191

    
3192
void OPPROTO op_efscmpeq (void)
3193
{
3194
    do_efscmpeq();
3195
    RETURN();
3196
}
3197

    
3198
void OPPROTO op_efscfsi (void)
3199
{
3200
    do_efscfsi();
3201
    RETURN();
3202
}
3203

    
3204
void OPPROTO op_efscfui (void)
3205
{
3206
    do_efscfui();
3207
    RETURN();
3208
}
3209

    
3210
void OPPROTO op_efscfsf (void)
3211
{
3212
    do_efscfsf();
3213
    RETURN();
3214
}
3215

    
3216
void OPPROTO op_efscfuf (void)
3217
{
3218
    do_efscfuf();
3219
    RETURN();
3220
}
3221

    
3222
void OPPROTO op_efsctsi (void)
3223
{
3224
    do_efsctsi();
3225
    RETURN();
3226
}
3227

    
3228
void OPPROTO op_efsctui (void)
3229
{
3230
    do_efsctui();
3231
    RETURN();
3232
}
3233

    
3234
void OPPROTO op_efsctsf (void)
3235
{
3236
    do_efsctsf();
3237
    RETURN();
3238
}
3239

    
3240
void OPPROTO op_efsctuf (void)
3241
{
3242
    do_efsctuf();
3243
    RETURN();
3244
}
3245

    
3246
void OPPROTO op_efsctsiz (void)
3247
{
3248
    do_efsctsiz();
3249
    RETURN();
3250
}
3251

    
3252
void OPPROTO op_efsctuiz (void)
3253
{
3254
    do_efsctuiz();
3255
    RETURN();
3256
}
3257

    
3258
void OPPROTO op_efststlt (void)
3259
{
3260
    T0 = _do_efststlt(T0_64, T1_64);
3261
    RETURN();
3262
}
3263

    
3264
void OPPROTO op_efststgt (void)
3265
{
3266
    T0 = _do_efststgt(T0_64, T1_64);
3267
    RETURN();
3268
}
3269

    
3270
void OPPROTO op_efststeq (void)
3271
{
3272
    T0 = _do_efststeq(T0_64, T1_64);
3273
    RETURN();
3274
}
3275

    
3276
void OPPROTO op_efdsub (void)
3277
{
3278
    union {
3279
        uint64_t u;
3280
        float64 f;
3281
    } u1, u2;
3282
    u1.u = T0_64;
3283
    u2.u = T1_64;
3284
    u1.f = float64_sub(u1.f, u2.f, &env->spe_status);
3285
    T0_64 = u1.u;
3286
    RETURN();
3287
}
3288

    
3289
void OPPROTO op_efdadd (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_add(u1.f, u2.f, &env->spe_status);
3298
    T0_64 = u1.u;
3299
    RETURN();
3300
}
3301

    
3302
void OPPROTO op_efdcfsid (void)
3303
{
3304
    do_efdcfsi();
3305
    RETURN();
3306
}
3307

    
3308
void OPPROTO op_efdcfuid (void)
3309
{
3310
    do_efdcfui();
3311
    RETURN();
3312
}
3313

    
3314
void OPPROTO op_efdnabs (void)
3315
{
3316
    T0_64 |= 0x8000000000000000ULL;
3317
    RETURN();
3318
}
3319

    
3320
void OPPROTO op_efdabs (void)
3321
{
3322
    T0_64 &= ~0x8000000000000000ULL;
3323
    RETURN();
3324
}
3325

    
3326
void OPPROTO op_efdneg (void)
3327
{
3328
    T0_64 ^= 0x8000000000000000ULL;
3329
    RETURN();
3330
}
3331

    
3332
void OPPROTO op_efddiv (void)
3333
{
3334
    union {
3335
        uint64_t u;
3336
        float64 f;
3337
    } u1, u2;
3338
    u1.u = T0_64;
3339
    u2.u = T1_64;
3340
    u1.f = float64_div(u1.f, u2.f, &env->spe_status);
3341
    T0_64 = u1.u;
3342
    RETURN();
3343
}
3344

    
3345
void OPPROTO op_efdmul (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_mul(u1.f, u2.f, &env->spe_status);
3354
    T0_64 = u1.u;
3355
    RETURN();
3356
}
3357

    
3358
void OPPROTO op_efdctsidz (void)
3359
{
3360
    do_efdctsiz();
3361
    RETURN();
3362
}
3363

    
3364
void OPPROTO op_efdctuidz (void)
3365
{
3366
    do_efdctuiz();
3367
    RETURN();
3368
}
3369

    
3370
void OPPROTO op_efdcmplt (void)
3371
{
3372
    do_efdcmplt();
3373
    RETURN();
3374
}
3375

    
3376
void OPPROTO op_efdcmpgt (void)
3377
{
3378
    do_efdcmpgt();
3379
    RETURN();
3380
}
3381

    
3382
void OPPROTO op_efdcfs (void)
3383
{
3384
    do_efdcfs();
3385
    RETURN();
3386
}
3387

    
3388
void OPPROTO op_efdcmpeq (void)
3389
{
3390
    do_efdcmpeq();
3391
    RETURN();
3392
}
3393

    
3394
void OPPROTO op_efdcfsi (void)
3395
{
3396
    do_efdcfsi();
3397
    RETURN();
3398
}
3399

    
3400
void OPPROTO op_efdcfui (void)
3401
{
3402
    do_efdcfui();
3403
    RETURN();
3404
}
3405

    
3406
void OPPROTO op_efdcfsf (void)
3407
{
3408
    do_efdcfsf();
3409
    RETURN();
3410
}
3411

    
3412
void OPPROTO op_efdcfuf (void)
3413
{
3414
    do_efdcfuf();
3415
    RETURN();
3416
}
3417

    
3418
void OPPROTO op_efdctsi (void)
3419
{
3420
    do_efdctsi();
3421
    RETURN();
3422
}
3423

    
3424
void OPPROTO op_efdctui (void)
3425
{
3426
    do_efdctui();
3427
    RETURN();
3428
}
3429

    
3430
void OPPROTO op_efdctsf (void)
3431
{
3432
    do_efdctsf();
3433
    RETURN();
3434
}
3435

    
3436
void OPPROTO op_efdctuf (void)
3437
{
3438
    do_efdctuf();
3439
    RETURN();
3440
}
3441

    
3442
void OPPROTO op_efdctuiz (void)
3443
{
3444
    do_efdctuiz();
3445
    RETURN();
3446
}
3447

    
3448
void OPPROTO op_efdctsiz (void)
3449
{
3450
    do_efdctsiz();
3451
    RETURN();
3452
}
3453

    
3454
void OPPROTO op_efdtstlt (void)
3455
{
3456
    T0 = _do_efdtstlt(T0_64, T1_64);
3457
    RETURN();
3458
}
3459

    
3460
void OPPROTO op_efdtstgt (void)
3461
{
3462
    T0 = _do_efdtstgt(T0_64, T1_64);
3463
    RETURN();
3464
}
3465

    
3466
void OPPROTO op_efdtsteq (void)
3467
{
3468
    T0 = _do_efdtsteq(T0_64, T1_64);
3469
    RETURN();
3470
}
3471
#endif /* defined(TARGET_PPCEMB) */