Statistics
| Branch: | Revision:

root / target-ppc / op.c @ 40d0591e

History | View | Annotate | Download (47.3 kB)

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

    
21
//#define DEBUG_OP
22

    
23
#include "config.h"
24
#include "exec.h"
25
#include "op_helper.h"
26

    
27
#define REG 0
28
#include "op_template.h"
29

    
30
#define REG 1
31
#include "op_template.h"
32

    
33
#define REG 2
34
#include "op_template.h"
35

    
36
#define REG 3
37
#include "op_template.h"
38

    
39
#define REG 4
40
#include "op_template.h"
41

    
42
#define REG 5
43
#include "op_template.h"
44

    
45
#define REG 6
46
#include "op_template.h"
47

    
48
#define REG 7
49
#include "op_template.h"
50

    
51
#define REG 8
52
#include "op_template.h"
53

    
54
#define REG 9
55
#include "op_template.h"
56

    
57
#define REG 10
58
#include "op_template.h"
59

    
60
#define REG 11
61
#include "op_template.h"
62

    
63
#define REG 12
64
#include "op_template.h"
65

    
66
#define REG 13
67
#include "op_template.h"
68

    
69
#define REG 14
70
#include "op_template.h"
71

    
72
#define REG 15
73
#include "op_template.h"
74

    
75
#define REG 16
76
#include "op_template.h"
77

    
78
#define REG 17
79
#include "op_template.h"
80

    
81
#define REG 18
82
#include "op_template.h"
83

    
84
#define REG 19
85
#include "op_template.h"
86

    
87
#define REG 20
88
#include "op_template.h"
89

    
90
#define REG 21
91
#include "op_template.h"
92

    
93
#define REG 22
94
#include "op_template.h"
95

    
96
#define REG 23
97
#include "op_template.h"
98

    
99
#define REG 24
100
#include "op_template.h"
101

    
102
#define REG 25
103
#include "op_template.h"
104

    
105
#define REG 26
106
#include "op_template.h"
107

    
108
#define REG 27
109
#include "op_template.h"
110

    
111
#define REG 28
112
#include "op_template.h"
113

    
114
#define REG 29
115
#include "op_template.h"
116

    
117
#define REG 30
118
#include "op_template.h"
119

    
120
#define REG 31
121
#include "op_template.h"
122

    
123

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

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

    
138
/* Set Rc1 (for floating point arithmetic) */
139
void OPPROTO op_set_Rc1 (void)
140
{
141
    env->crf[1] = env->fpscr[7];
142
    RETURN();
143
}
144

    
145
/* Constants load */
146
void OPPROTO op_reset_T0 (void)
147
{
148
    T0 = 0;
149
    RETURN();
150
}
151

    
152
void OPPROTO op_set_T0 (void)
153
{
154
    T0 = (uint32_t)PARAM1;
155
    RETURN();
156
}
157

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

    
166
void OPPROTO op_set_T1 (void)
167
{
168
    T1 = (uint32_t)PARAM1;
169
    RETURN();
170
}
171

    
172
#if defined(TARGET_PPC64)
173
void OPPROTO op_set_T1_64 (void)
174
{
175
    T1 = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
176
    RETURN();
177
}
178
#endif
179

    
180
#if 0 // unused
181
void OPPROTO op_set_T2 (void)
182
{
183
    T2 = PARAM1;
184
    RETURN();
185
}
186
#endif
187

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

    
194
void OPPROTO op_move_T2_T0 (void)
195
{
196
    T2 = T0;
197
    RETURN();
198
}
199

    
200
/* Generate exceptions */
201
void OPPROTO op_raise_exception_err (void)
202
{
203
    do_raise_exception_err(PARAM1, PARAM2);
204
}
205

    
206
void OPPROTO op_update_nip (void)
207
{
208
    env->nip = (uint32_t)PARAM1;
209
    RETURN();
210
}
211

    
212
#if defined(TARGET_PPC64)
213
void OPPROTO op_update_nip_64 (void)
214
{
215
    env->nip = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
216
    RETURN();
217
}
218
#endif
219

    
220
void OPPROTO op_debug (void)
221
{
222
    do_raise_exception(EXCP_DEBUG);
223
}
224

    
225
void OPPROTO op_exit_tb (void)
226
{
227
    EXIT_TB();
228
}
229

    
230
/* Load/store special registers */
231
void OPPROTO op_load_cr (void)
232
{
233
    do_load_cr();
234
    RETURN();
235
}
236

    
237
void OPPROTO op_store_cr (void)
238
{
239
    do_store_cr(PARAM1);
240
    RETURN();
241
}
242

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

    
249
void OPPROTO op_store_cro (void)
250
{
251
    env->crf[PARAM1] = T0;
252
    RETURN();
253
}
254

    
255
void OPPROTO op_load_xer_cr (void)
256
{
257
    T0 = (xer_so << 3) | (xer_ov << 2) | (xer_ca << 1);
258
    RETURN();
259
}
260

    
261
void OPPROTO op_clear_xer_ov (void)
262
{
263
    xer_so = 0;
264
    xer_ov = 0;
265
    RETURN();
266
}
267

    
268
void OPPROTO op_clear_xer_ca (void)
269
{
270
    xer_ca = 0;
271
    RETURN();
272
}
273

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

    
280
void OPPROTO op_store_xer_bc (void)
281
{
282
    xer_bc = T0;
283
    RETURN();
284
}
285

    
286
void OPPROTO op_load_xer (void)
287
{
288
    do_load_xer();
289
    RETURN();
290
}
291

    
292
void OPPROTO op_store_xer (void)
293
{
294
    do_store_xer();
295
    RETURN();
296
}
297

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

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

    
312
void OPPROTO op_load_sdr1 (void)
313
{
314
    T0 = env->sdr1;
315
    RETURN();
316
}
317

    
318
void OPPROTO op_store_sdr1 (void)
319
{
320
    do_store_sdr1(env, T0);
321
    RETURN();
322
}
323

    
324
#if defined (TARGET_PPC64)
325
void OPPROTO op_load_asr (void)
326
{
327
    T0 = env->asr;
328
    RETURN();
329
}
330

    
331
void OPPROTO op_store_asr (void)
332
{
333
    ppc_store_asr(env, T0);
334
    RETURN();
335
}
336
#endif
337

    
338
void OPPROTO op_load_msr (void)
339
{
340
    T0 = do_load_msr(env);
341
    RETURN();
342
}
343

    
344
void OPPROTO op_store_msr (void)
345
{
346
    do_store_msr(env, T0);
347
    RETURN();
348
}
349

    
350
#if defined (TARGET_PPC64)
351
void OPPROTO op_store_msr_32 (void)
352
{
353
    ppc_store_msr_32(env, T0);
354
    RETURN();
355
}
356
#endif
357
#endif
358

    
359
/* SPR */
360
void OPPROTO op_load_spr (void)
361
{
362
    T0 = env->spr[PARAM1];
363
    RETURN();
364
}
365

    
366
void OPPROTO op_store_spr (void)
367
{
368
    env->spr[PARAM1] = T0;
369
    RETURN();
370
}
371

    
372
void OPPROTO op_load_dump_spr (void)
373
{
374
    T0 = ppc_load_dump_spr(PARAM1);
375
    RETURN();
376
}
377

    
378
void OPPROTO op_store_dump_spr (void)
379
{
380
    ppc_store_dump_spr(PARAM1, T0);
381
    RETURN();
382
}
383

    
384
void OPPROTO op_mask_spr (void)
385
{
386
    env->spr[PARAM1] &= ~T0;
387
    RETURN();
388
}
389

    
390
void OPPROTO op_load_lr (void)
391
{
392
    T0 = env->lr;
393
    RETURN();
394
}
395

    
396
void OPPROTO op_store_lr (void)
397
{
398
    env->lr = T0;
399
    RETURN();
400
}
401

    
402
void OPPROTO op_load_ctr (void)
403
{
404
    T0 = env->ctr;
405
    RETURN();
406
}
407

    
408
void OPPROTO op_store_ctr (void)
409
{
410
    env->ctr = T0;
411
    RETURN();
412
}
413

    
414
void OPPROTO op_load_tbl (void)
415
{
416
    T0 = cpu_ppc_load_tbl(env);
417
    RETURN();
418
}
419

    
420
void OPPROTO op_load_tbu (void)
421
{
422
    T0 = cpu_ppc_load_tbu(env);
423
    RETURN();
424
}
425

    
426
#if !defined(CONFIG_USER_ONLY)
427
void OPPROTO op_store_tbl (void)
428
{
429
    cpu_ppc_store_tbl(env, T0);
430
    RETURN();
431
}
432

    
433
void OPPROTO op_store_tbu (void)
434
{
435
    cpu_ppc_store_tbu(env, T0);
436
    RETURN();
437
}
438

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

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

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

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

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

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

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

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

    
496
/* FPSCR */
497
void OPPROTO op_load_fpscr (void)
498
{
499
    do_load_fpscr();
500
    RETURN();
501
}
502

    
503
void OPPROTO op_store_fpscr (void)
504
{
505
    do_store_fpscr(PARAM1);
506
    RETURN();
507
}
508

    
509
void OPPROTO op_reset_scrfx (void)
510
{
511
    env->fpscr[7] &= ~0x8;
512
    RETURN();
513
}
514

    
515
/* crf operations */
516
void OPPROTO op_getbit_T0 (void)
517
{
518
    T0 = (T0 >> PARAM1) & 1;
519
    RETURN();
520
}
521

    
522
void OPPROTO op_getbit_T1 (void)
523
{
524
    T1 = (T1 >> PARAM1) & 1;
525
    RETURN();
526
}
527

    
528
void OPPROTO op_setcrfbit (void)
529
{
530
    T1 = (T1 & PARAM1) | (T0 << PARAM2);
531
    RETURN();
532
}
533

    
534
/* Branch */
535
#define EIP env->nip
536

    
537
void OPPROTO op_setlr (void)
538
{
539
    env->lr = (uint32_t)PARAM1;
540
    RETURN();
541
}
542

    
543
#if defined (TARGET_PPC64)
544
void OPPROTO op_setlr_64 (void)
545
{
546
    env->lr = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
547
    RETURN();
548
}
549
#endif
550

    
551
void OPPROTO op_goto_tb0 (void)
552
{
553
    GOTO_TB(op_goto_tb0, PARAM1, 0);
554
}
555

    
556
void OPPROTO op_goto_tb1 (void)
557
{
558
    GOTO_TB(op_goto_tb1, PARAM1, 1);
559
}
560

    
561
void OPPROTO op_b_T1 (void)
562
{
563
    env->nip = (uint32_t)(T1 & ~3);
564
    RETURN();
565
}
566

    
567
#if defined (TARGET_PPC64)
568
void OPPROTO op_b_T1_64 (void)
569
{
570
    env->nip = (uint64_t)(T1 & ~3);
571
    RETURN();
572
}
573
#endif
574

    
575
void OPPROTO op_jz_T0 (void)
576
{
577
    if (!T0)
578
        GOTO_LABEL_PARAM(1);
579
    RETURN();
580
}
581

    
582
void OPPROTO op_btest_T1 (void)
583
{
584
    if (T0) {
585
        env->nip = (uint32_t)(T1 & ~3);
586
    } else {
587
        env->nip = (uint32_t)PARAM1;
588
    }
589
    RETURN();
590
}
591

    
592
#if defined (TARGET_PPC64)
593
void OPPROTO op_btest_T1_64 (void)
594
{
595
    if (T0) {
596
        env->nip = (uint64_t)(T1 & ~3);
597
    } else {
598
        env->nip = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
599
    }
600
    RETURN();
601
}
602
#endif
603

    
604
void OPPROTO op_movl_T1_ctr (void)
605
{
606
    T1 = env->ctr;
607
    RETURN();
608
}
609

    
610
void OPPROTO op_movl_T1_lr (void)
611
{
612
    T1 = env->lr;
613
    RETURN();
614
}
615

    
616
/* tests with result in T0 */
617
void OPPROTO op_test_ctr (void)
618
{
619
    T0 = (uint32_t)env->ctr;
620
    RETURN();
621
}
622

    
623
#if defined(TARGET_PPC64)
624
void OPPROTO op_test_ctr_64 (void)
625
{
626
    T0 = (uint64_t)env->ctr;
627
    RETURN();
628
}
629
#endif
630

    
631
void OPPROTO op_test_ctr_true (void)
632
{
633
    T0 = ((uint32_t)env->ctr != 0 && (T0 & PARAM1) != 0);
634
    RETURN();
635
}
636

    
637
#if defined(TARGET_PPC64)
638
void OPPROTO op_test_ctr_true_64 (void)
639
{
640
    T0 = ((uint64_t)env->ctr != 0 && (T0 & PARAM1) != 0);
641
    RETURN();
642
}
643
#endif
644

    
645
void OPPROTO op_test_ctr_false (void)
646
{
647
    T0 = ((uint32_t)env->ctr != 0 && (T0 & PARAM1) == 0);
648
    RETURN();
649
}
650

    
651
#if defined(TARGET_PPC64)
652
void OPPROTO op_test_ctr_false_64 (void)
653
{
654
    T0 = ((uint64_t)env->ctr != 0 && (T0 & PARAM1) == 0);
655
    RETURN();
656
}
657
#endif
658

    
659
void OPPROTO op_test_ctrz (void)
660
{
661
    T0 = ((uint32_t)env->ctr == 0);
662
    RETURN();
663
}
664

    
665
#if defined(TARGET_PPC64)
666
void OPPROTO op_test_ctrz_64 (void)
667
{
668
    T0 = ((uint64_t)env->ctr == 0);
669
    RETURN();
670
}
671
#endif
672

    
673
void OPPROTO op_test_ctrz_true (void)
674
{
675
    T0 = ((uint32_t)env->ctr == 0 && (T0 & PARAM1) != 0);
676
    RETURN();
677
}
678

    
679
#if defined(TARGET_PPC64)
680
void OPPROTO op_test_ctrz_true_64 (void)
681
{
682
    T0 = ((uint64_t)env->ctr == 0 && (T0 & PARAM1) != 0);
683
    RETURN();
684
}
685
#endif
686

    
687
void OPPROTO op_test_ctrz_false (void)
688
{
689
    T0 = ((uint32_t)env->ctr == 0 && (T0 & PARAM1) == 0);
690
    RETURN();
691
}
692

    
693
#if defined(TARGET_PPC64)
694
void OPPROTO op_test_ctrz_false_64 (void)
695
{
696
    T0 = ((uint64_t)env->ctr == 0 && (T0 & PARAM1) == 0);
697
    RETURN();
698
}
699
#endif
700

    
701
void OPPROTO op_test_true (void)
702
{
703
    T0 = (T0 & PARAM1);
704
    RETURN();
705
}
706

    
707
void OPPROTO op_test_false (void)
708
{
709
    T0 = ((T0 & PARAM1) == 0);
710
    RETURN();
711
}
712

    
713
/* CTR maintenance */
714
void OPPROTO op_dec_ctr (void)
715
{
716
    env->ctr--;
717
    RETURN();
718
}
719

    
720
/***                           Integer arithmetic                          ***/
721
/* add */
722
void OPPROTO op_add (void)
723
{
724
    T0 += T1;
725
    RETURN();
726
}
727

    
728
void OPPROTO op_check_addo (void)
729
{
730
    if (likely(!(((uint32_t)T2 ^ (uint32_t)T1 ^ UINT32_MAX) &
731
                 ((uint32_t)T2 ^ (uint32_t)T0) & (1UL << 31)))) {
732
        xer_ov = 0;
733
    } else {
734
        xer_ov = 1;
735
        xer_so = 1;
736
    }
737
    RETURN();
738
}
739

    
740
#if defined(TARGET_PPC64)
741
void OPPROTO op_check_addo_64 (void)
742
{
743
    if (likely(!(((uint64_t)T2 ^ (uint64_t)T1 ^ UINT64_MAX) &
744
                 ((uint64_t)T2 ^ (uint64_t)T0) & (1ULL << 63)))) {
745
        xer_ov = 0;
746
    } else {
747
        xer_ov = 1;
748
        xer_so = 1;
749
    }
750
    RETURN();
751
}
752
#endif
753

    
754
/* add carrying */
755
void OPPROTO op_check_addc (void)
756
{
757
    if (likely((uint32_t)T0 >= (uint32_t)T2)) {
758
        xer_ca = 0;
759
    } else {
760
        xer_ca = 1;
761
    }
762
    RETURN();
763
}
764

    
765
#if defined(TARGET_PPC64)
766
void OPPROTO op_check_addc_64 (void)
767
{
768
    if (likely((uint64_t)T0 >= (uint64_t)T2)) {
769
        xer_ca = 0;
770
    } else {
771
        xer_ca = 1;
772
    }
773
    RETURN();
774
}
775
#endif
776

    
777
/* add extended */
778
void OPPROTO op_adde (void)
779
{
780
    do_adde();
781
    RETURN();
782
}
783

    
784
#if defined(TARGET_PPC64)
785
void OPPROTO op_adde_64 (void)
786
{
787
    do_adde_64();
788
    RETURN();
789
}
790
#endif
791

    
792
/* add immediate */
793
void OPPROTO op_addi (void)
794
{
795
    T0 += (int32_t)PARAM1;
796
    RETURN();
797
}
798

    
799
/* add to minus one extended */
800
void OPPROTO op_add_me (void)
801
{
802
    T0 += xer_ca + (-1);
803
    if (likely((uint32_t)T1 != 0))
804
        xer_ca = 1;
805
    RETURN();
806
}
807

    
808
#if defined(TARGET_PPC64)
809
void OPPROTO op_add_me_64 (void)
810
{
811
    T0 += xer_ca + (-1);
812
    if (likely((uint64_t)T1 != 0))
813
        xer_ca = 1;
814
    RETURN();
815
}
816
#endif
817

    
818
void OPPROTO op_addmeo (void)
819
{
820
    do_addmeo();
821
    RETURN();
822
}
823

    
824
void OPPROTO op_addmeo_64 (void)
825
{
826
    do_addmeo();
827
    RETURN();
828
}
829

    
830
/* add to zero extended */
831
void OPPROTO op_add_ze (void)
832
{
833
    T0 += xer_ca;
834
    RETURN();
835
}
836

    
837
/* divide word */
838
void OPPROTO op_divw (void)
839
{
840
    if (unlikely(((int32_t)T0 == INT32_MIN && (int32_t)T1 == -1) ||
841
                 (int32_t)T1 == 0)) {
842
        T0 = (int32_t)((-1) * ((uint32_t)T0 >> 31));
843
    } else {
844
        T0 = (int32_t)T0 / (int32_t)T1;
845
    }
846
    RETURN();
847
}
848

    
849
#if defined(TARGET_PPC64)
850
void OPPROTO op_divd (void)
851
{
852
    if (unlikely(((int64_t)T0 == INT64_MIN && (int64_t)T1 == -1) ||
853
                 (int64_t)T1 == 0)) {
854
        T0 = (int64_t)((-1ULL) * ((uint64_t)T0 >> 63));
855
    } else {
856
        T0 = (int64_t)T0 / (int64_t)T1;
857
    }
858
    RETURN();
859
}
860
#endif
861

    
862
void OPPROTO op_divwo (void)
863
{
864
    do_divwo();
865
    RETURN();
866
}
867

    
868
#if defined(TARGET_PPC64)
869
void OPPROTO op_divdo (void)
870
{
871
    do_divdo();
872
    RETURN();
873
}
874
#endif
875

    
876
/* divide word unsigned */
877
void OPPROTO op_divwu (void)
878
{
879
    if (unlikely(T1 == 0)) {
880
        T0 = 0;
881
    } else {
882
        T0 = (uint32_t)T0 / (uint32_t)T1;
883
    }
884
    RETURN();
885
}
886

    
887
#if defined(TARGET_PPC64)
888
void OPPROTO op_divdu (void)
889
{
890
    if (unlikely(T1 == 0)) {
891
        T0 = 0;
892
    } else {
893
        T0 /= T1;
894
    }
895
    RETURN();
896
}
897
#endif
898

    
899
void OPPROTO op_divwuo (void)
900
{
901
    do_divwuo();
902
    RETURN();
903
}
904

    
905
#if defined(TARGET_PPC64)
906
void OPPROTO op_divduo (void)
907
{
908
    do_divduo();
909
    RETURN();
910
}
911
#endif
912

    
913
/* multiply high word */
914
void OPPROTO op_mulhw (void)
915
{
916
    T0 = ((int64_t)((int32_t)T0) * (int64_t)((int32_t)T1)) >> 32;
917
    RETURN();
918
}
919

    
920
#if defined(TARGET_PPC64)
921
void OPPROTO op_mulhd (void)
922
{
923
    uint64_t tl, th;
924

    
925
    do_imul64(&tl, &th);
926
    T0 = th;
927
    RETURN();
928
}
929
#endif
930

    
931
/* multiply high word unsigned */
932
void OPPROTO op_mulhwu (void)
933
{
934
    T0 = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1) >> 32;
935
    RETURN();
936
}
937

    
938
#if defined(TARGET_PPC64)
939
void OPPROTO op_mulhdu (void)
940
{
941
    uint64_t tl, th;
942

    
943
    do_mul64(&tl, &th);
944
    T0 = th;
945
    RETURN();
946
}
947
#endif
948

    
949
/* multiply low immediate */
950
void OPPROTO op_mulli (void)
951
{
952
    T0 = ((int32_t)T0 * (int32_t)PARAM1);
953
    RETURN();
954
}
955

    
956
/* multiply low word */
957
void OPPROTO op_mullw (void)
958
{
959
    T0 = (int32_t)(T0 * T1);
960
    RETURN();
961
}
962

    
963
#if defined(TARGET_PPC64)
964
void OPPROTO op_mulld (void)
965
{
966
    T0 *= T1;
967
    RETURN();
968
}
969
#endif
970

    
971
void OPPROTO op_mullwo (void)
972
{
973
    do_mullwo();
974
    RETURN();
975
}
976

    
977
#if defined(TARGET_PPC64)
978
void OPPROTO op_mulldo (void)
979
{
980
    do_mulldo();
981
    RETURN();
982
}
983
#endif
984

    
985
/* negate */
986
void OPPROTO op_neg (void)
987
{
988
    if (likely(T0 != INT32_MIN)) {
989
        T0 = -(int32_t)T0;
990
    }
991
    RETURN();
992
}
993

    
994
#if defined(TARGET_PPC64)
995
void OPPROTO op_neg_64 (void)
996
{
997
    if (likely(T0 != INT64_MIN)) {
998
        T0 = -(int64_t)T0;
999
    }
1000
    RETURN();
1001
}
1002
#endif
1003

    
1004
void OPPROTO op_nego (void)
1005
{
1006
    do_nego();
1007
    RETURN();
1008
}
1009

    
1010
#if defined(TARGET_PPC64)
1011
void OPPROTO op_nego_64 (void)
1012
{
1013
    do_nego_64();
1014
    RETURN();
1015
}
1016
#endif
1017

    
1018
/* subtract from */
1019
void OPPROTO op_subf (void)
1020
{
1021
    T0 = T1 - T0;
1022
    RETURN();
1023
}
1024

    
1025
void OPPROTO op_check_subfo (void)
1026
{
1027
    if (likely(!(((uint32_t)(~T2) ^ (uint32_t)T1 ^ UINT32_MAX) &
1028
                 ((uint32_t)(~T2) ^ (uint32_t)T0) & (1UL << 31)))) {
1029
        xer_ov = 0;
1030
    } else {
1031
        xer_ov = 1;
1032
        xer_so = 1;
1033
    }
1034
    RETURN();
1035
}
1036

    
1037
#if defined(TARGET_PPC64)
1038
void OPPROTO op_check_subfo_64 (void)
1039
{
1040
    if (likely(!(((uint64_t)(~T2) ^ (uint64_t)T1 ^ UINT64_MAX) &
1041
                 ((uint64_t)(~T2) ^ (uint64_t)T0) & (1ULL << 63)))) {
1042
        xer_ov = 0;
1043
    } else {
1044
        xer_ov = 1;
1045
        xer_so = 1;
1046
    }
1047
    RETURN();
1048
}
1049
#endif
1050

    
1051
/* subtract from carrying */
1052
void OPPROTO op_check_subfc (void)
1053
{
1054
    if (likely((uint32_t)T0 > (uint32_t)T1)) {
1055
        xer_ca = 0;
1056
    } else {
1057
        xer_ca = 1;
1058
    }
1059
    RETURN();
1060
}
1061

    
1062
#if defined(TARGET_PPC64)
1063
void OPPROTO op_check_subfc_64 (void)
1064
{
1065
    if (likely((uint64_t)T0 > (uint64_t)T1)) {
1066
        xer_ca = 0;
1067
    } else {
1068
        xer_ca = 1;
1069
    }
1070
    RETURN();
1071
}
1072
#endif
1073

    
1074
/* subtract from extended */
1075
void OPPROTO op_subfe (void)
1076
{
1077
    do_subfe();
1078
    RETURN();
1079
}
1080

    
1081
#if defined(TARGET_PPC64)
1082
void OPPROTO op_subfe_64 (void)
1083
{
1084
    do_subfe_64();
1085
    RETURN();
1086
}
1087
#endif
1088

    
1089
/* subtract from immediate carrying */
1090
void OPPROTO op_subfic (void)
1091
{
1092
    T0 = (int32_t)PARAM1 + ~T0 + 1;
1093
    if ((uint32_t)T0 <= (uint32_t)PARAM1) {
1094
        xer_ca = 1;
1095
    } else {
1096
        xer_ca = 0;
1097
    }
1098
    RETURN();
1099
}
1100

    
1101
#if defined(TARGET_PPC64)
1102
void OPPROTO op_subfic_64 (void)
1103
{
1104
    T0 = PARAM1 + ~T0 + 1;
1105
    if ((uint64_t)T0 <= (uint64_t)PARAM1) {
1106
        xer_ca = 1;
1107
    } else {
1108
        xer_ca = 0;
1109
    }
1110
    RETURN();
1111
}
1112
#endif
1113

    
1114
/* subtract from minus one extended */
1115
void OPPROTO op_subfme (void)
1116
{
1117
    T0 = ~T0 + xer_ca - 1;
1118
    if (likely((uint32_t)T0 != (uint32_t)-1))
1119
        xer_ca = 1;
1120
    RETURN();
1121
}
1122

    
1123
#if defined(TARGET_PPC64)
1124
void OPPROTO op_subfme_64 (void)
1125
{
1126
    T0 = ~T0 + xer_ca - 1;
1127
    if (likely((uint64_t)T0 != (uint64_t)-1))
1128
        xer_ca = 1;
1129
    RETURN();
1130
}
1131
#endif
1132

    
1133
void OPPROTO op_subfmeo (void)
1134
{
1135
    do_subfmeo();
1136
    RETURN();
1137
}
1138

    
1139
#if defined(TARGET_PPC64)
1140
void OPPROTO op_subfmeo_64 (void)
1141
{
1142
    do_subfmeo_64();
1143
    RETURN();
1144
}
1145
#endif
1146

    
1147
/* subtract from zero extended */
1148
void OPPROTO op_subfze (void)
1149
{
1150
    T1 = ~T0;
1151
    T0 = T1 + xer_ca;
1152
    if ((uint32_t)T0 < (uint32_t)T1) {
1153
        xer_ca = 1;
1154
    } else {
1155
        xer_ca = 0;
1156
    }
1157
    RETURN();
1158
}
1159

    
1160
#if defined(TARGET_PPC64)
1161
void OPPROTO op_subfze_64 (void)
1162
{
1163
    T1 = ~T0;
1164
    T0 = T1 + xer_ca;
1165
    if ((uint64_t)T0 < (uint64_t)T1) {
1166
        xer_ca = 1;
1167
    } else {
1168
        xer_ca = 0;
1169
    }
1170
    RETURN();
1171
}
1172
#endif
1173

    
1174
void OPPROTO op_subfzeo (void)
1175
{
1176
    do_subfzeo();
1177
    RETURN();
1178
}
1179

    
1180
#if defined(TARGET_PPC64)
1181
void OPPROTO op_subfzeo_64 (void)
1182
{
1183
    do_subfzeo_64();
1184
    RETURN();
1185
}
1186
#endif
1187

    
1188
/***                           Integer comparison                          ***/
1189
/* compare */
1190
void OPPROTO op_cmp (void)
1191
{
1192
    if ((int32_t)T0 < (int32_t)T1) {
1193
        T0 = 0x08;
1194
    } else if ((int32_t)T0 > (int32_t)T1) {
1195
        T0 = 0x04;
1196
    } else {
1197
        T0 = 0x02;
1198
    }
1199
    T0 |= xer_so;
1200
    RETURN();
1201
}
1202

    
1203
#if defined(TARGET_PPC64)
1204
void OPPROTO op_cmp_64 (void)
1205
{
1206
    if ((int64_t)T0 < (int64_t)T1) {
1207
        T0 = 0x08;
1208
    } else if ((int64_t)T0 > (int64_t)T1) {
1209
        T0 = 0x04;
1210
    } else {
1211
        T0 = 0x02;
1212
    }
1213
    T0 |= xer_so;
1214
    RETURN();
1215
}
1216
#endif
1217

    
1218
/* compare immediate */
1219
void OPPROTO op_cmpi (void)
1220
{
1221
    if ((int32_t)T0 < (int32_t)PARAM1) {
1222
        T0 = 0x08;
1223
    } else if ((int32_t)T0 > (int32_t)PARAM1) {
1224
        T0 = 0x04;
1225
    } else {
1226
        T0 = 0x02;
1227
    }
1228
    T0 |= xer_so;
1229
    RETURN();
1230
}
1231

    
1232
#if defined(TARGET_PPC64)
1233
void OPPROTO op_cmpi_64 (void)
1234
{
1235
    if ((int64_t)T0 < (int64_t)((int32_t)PARAM1)) {
1236
        T0 = 0x08;
1237
    } else if ((int64_t)T0 > (int64_t)((int32_t)PARAM1)) {
1238
        T0 = 0x04;
1239
    } else {
1240
        T0 = 0x02;
1241
    }
1242
    T0 |= xer_so;
1243
    RETURN();
1244
}
1245
#endif
1246

    
1247
/* compare logical */
1248
void OPPROTO op_cmpl (void)
1249
{
1250
    if ((uint32_t)T0 < (uint32_t)T1) {
1251
        T0 = 0x08;
1252
    } else if ((uint32_t)T0 > (uint32_t)T1) {
1253
        T0 = 0x04;
1254
    } else {
1255
        T0 = 0x02;
1256
    }
1257
    T0 |= xer_so;
1258
    RETURN();
1259
}
1260

    
1261
#if defined(TARGET_PPC64)
1262
void OPPROTO op_cmpl_64 (void)
1263
{
1264
    if ((uint64_t)T0 < (uint64_t)T1) {
1265
        T0 = 0x08;
1266
    } else if ((uint64_t)T0 > (uint64_t)T1) {
1267
        T0 = 0x04;
1268
    } else {
1269
        T0 = 0x02;
1270
    }
1271
    T0 |= xer_so;
1272
    RETURN();
1273
}
1274
#endif
1275

    
1276
/* compare logical immediate */
1277
void OPPROTO op_cmpli (void)
1278
{
1279
    if ((uint32_t)T0 < (uint32_t)PARAM1) {
1280
        T0 = 0x08;
1281
    } else if ((uint32_t)T0 > (uint32_t)PARAM1) {
1282
        T0 = 0x04;
1283
    } else {
1284
        T0 = 0x02;
1285
    }
1286
    T0 |= xer_so;
1287
    RETURN();
1288
}
1289

    
1290
#if defined(TARGET_PPC64)
1291
void OPPROTO op_cmpli_64 (void)
1292
{
1293
    if ((uint64_t)T0 < (uint64_t)PARAM1) {
1294
        T0 = 0x08;
1295
    } else if ((uint64_t)T0 > (uint64_t)PARAM1) {
1296
        T0 = 0x04;
1297
    } else {
1298
        T0 = 0x02;
1299
    }
1300
    T0 |= xer_so;
1301
    RETURN();
1302
}
1303
#endif
1304

    
1305
void OPPROTO op_isel (void)
1306
{
1307
    if (T0)
1308
        T0 = T1;
1309
    else
1310
        T0 = T2;
1311
    RETURN();
1312
}
1313

    
1314
void OPPROTO op_popcntb (void)
1315
{
1316
    do_popcntb();
1317
    RETURN();
1318
}
1319

    
1320
#if defined(TARGET_PPC64)
1321
void OPPROTO op_popcntb_64 (void)
1322
{
1323
    do_popcntb_64();
1324
    RETURN();
1325
}
1326
#endif
1327

    
1328
/***                            Integer logical                            ***/
1329
/* and */
1330
void OPPROTO op_and (void)
1331
{
1332
    T0 &= T1;
1333
    RETURN();
1334
}
1335

    
1336
/* andc */
1337
void OPPROTO op_andc (void)
1338
{
1339
    T0 &= ~T1;
1340
    RETURN();
1341
}
1342

    
1343
/* andi. */
1344
void OPPROTO op_andi_T0 (void)
1345
{
1346
    T0 &= PARAM1;
1347
    RETURN();
1348
}
1349

    
1350
void OPPROTO op_andi_T1 (void)
1351
{
1352
    T1 &= PARAM1;
1353
    RETURN();
1354
}
1355

    
1356
#if defined(TARGET_PPC64)
1357
void OPPROTO op_andi_T0_64 (void)
1358
{
1359
    T0 &= ((uint64_t)PARAM1 << 32) | PARAM2;
1360
    RETURN();
1361
}
1362

    
1363
void OPPROTO op_andi_T1_64 (void)
1364
{
1365
    T1 &= ((uint64_t)PARAM1 << 32) | PARAM2;
1366
    RETURN();
1367
}
1368
#endif
1369

    
1370

    
1371
/* count leading zero */
1372
void OPPROTO op_cntlzw (void)
1373
{
1374
    T0 = _do_cntlzw(T0);
1375
    RETURN();
1376
}
1377

    
1378
#if defined(TARGET_PPC64)
1379
void OPPROTO op_cntlzd (void)
1380
{
1381
    T0 = _do_cntlzd(T0);
1382
    RETURN();
1383
}
1384
#endif
1385

    
1386
/* eqv */
1387
void OPPROTO op_eqv (void)
1388
{
1389
    T0 = ~(T0 ^ T1);
1390
    RETURN();
1391
}
1392

    
1393
/* extend sign byte */
1394
void OPPROTO op_extsb (void)
1395
{
1396
#if defined (TARGET_PPC64)
1397
    T0 = (int64_t)((int8_t)T0);
1398
#else
1399
    T0 = (int32_t)((int8_t)T0);
1400
#endif
1401
    RETURN();
1402
}
1403

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

    
1415
#if defined (TARGET_PPC64)
1416
void OPPROTO op_extsw (void)
1417
{
1418
    T0 = (int64_t)((int32_t)T0);
1419
    RETURN();
1420
}
1421
#endif
1422

    
1423
/* nand */
1424
void OPPROTO op_nand (void)
1425
{
1426
    T0 = ~(T0 & T1);
1427
    RETURN();
1428
}
1429

    
1430
/* nor */
1431
void OPPROTO op_nor (void)
1432
{
1433
    T0 = ~(T0 | T1);
1434
    RETURN();
1435
}
1436

    
1437
/* or */
1438
void OPPROTO op_or (void)
1439
{
1440
    T0 |= T1;
1441
    RETURN();
1442
}
1443

    
1444
/* orc */
1445
void OPPROTO op_orc (void)
1446
{
1447
    T0 |= ~T1;
1448
    RETURN();
1449
}
1450

    
1451
/* ori */
1452
void OPPROTO op_ori (void)
1453
{
1454
    T0 |= PARAM1;
1455
    RETURN();
1456
}
1457

    
1458
/* xor */
1459
void OPPROTO op_xor (void)
1460
{
1461
    T0 ^= T1;
1462
    RETURN();
1463
}
1464

    
1465
/* xori */
1466
void OPPROTO op_xori (void)
1467
{
1468
    T0 ^= PARAM1;
1469
    RETURN();
1470
}
1471

    
1472
/***                             Integer rotate                            ***/
1473
void OPPROTO op_rotl32_T0_T1 (void)
1474
{
1475
    T0 = rotl32(T0, T1 & 0x1F);
1476
    RETURN();
1477
}
1478

    
1479
void OPPROTO op_rotli32_T0 (void)
1480
{
1481
    T0 = rotl32(T0, PARAM1);
1482
    RETURN();
1483
}
1484

    
1485
#if defined(TARGET_PPC64)
1486
void OPPROTO op_rotl64_T0_T1 (void)
1487
{
1488
    T0 = rotl64(T0, T1 & 0x3F);
1489
    RETURN();
1490
}
1491

    
1492
void OPPROTO op_rotli64_T0 (void)
1493
{
1494
    T0 = rotl64(T0, PARAM1);
1495
    RETURN();
1496
}
1497
#endif
1498

    
1499
/***                             Integer shift                             ***/
1500
/* shift left word */
1501
void OPPROTO op_slw (void)
1502
{
1503
    if (T1 & 0x20) {
1504
        T0 = 0;
1505
    } else {
1506
        T0 = (uint32_t)(T0 << T1);
1507
    }
1508
    RETURN();
1509
}
1510

    
1511
#if defined(TARGET_PPC64)
1512
void OPPROTO op_sld (void)
1513
{
1514
    if (T1 & 0x40) {
1515
        T0 = 0;
1516
    } else {
1517
        T0 = T0 << T1;
1518
    }
1519
    RETURN();
1520
}
1521
#endif
1522

    
1523
/* shift right algebraic word */
1524
void OPPROTO op_sraw (void)
1525
{
1526
    do_sraw();
1527
    RETURN();
1528
}
1529

    
1530
#if defined(TARGET_PPC64)
1531
void OPPROTO op_srad (void)
1532
{
1533
    do_srad();
1534
    RETURN();
1535
}
1536
#endif
1537

    
1538
/* shift right algebraic word immediate */
1539
void OPPROTO op_srawi (void)
1540
{
1541
    uint32_t mask = (uint32_t)PARAM2;
1542

    
1543
    T0 = (int32_t)T0 >> PARAM1;
1544
    if ((int32_t)T1 < 0 && (T1 & mask) != 0) {
1545
        xer_ca = 1;
1546
    } else {
1547
        xer_ca = 0;
1548
    }
1549
    RETURN();
1550
}
1551

    
1552
#if defined(TARGET_PPC64)
1553
void OPPROTO op_sradi (void)
1554
{
1555
    uint64_t mask = ((uint64_t)PARAM2 << 32) | (uint64_t)PARAM3;
1556

    
1557
    T0 = (int64_t)T0 >> PARAM1;
1558
    if ((int64_t)T1 < 0 && ((uint64_t)T1 & mask) != 0) {
1559
        xer_ca = 1;
1560
    } else {
1561
        xer_ca = 0;
1562
    }
1563
    RETURN();
1564
}
1565
#endif
1566

    
1567
/* shift right word */
1568
void OPPROTO op_srw (void)
1569
{
1570
    if (T1 & 0x20) {
1571
        T0 = 0;
1572
    } else {
1573
        T0 = (uint32_t)T0 >> T1;
1574
    }
1575
    RETURN();
1576
}
1577

    
1578
#if defined(TARGET_PPC64)
1579
void OPPROTO op_srd (void)
1580
{
1581
    if (T1 & 0x40) {
1582
        T0 = 0;
1583
    } else {
1584
        T0 = (uint64_t)T0 >> T1;
1585
    }
1586
    RETURN();
1587
}
1588
#endif
1589

    
1590
void OPPROTO op_sl_T0_T1 (void)
1591
{
1592
    T0 = T0 << T1;
1593
    RETURN();
1594
}
1595

    
1596
void OPPROTO op_sli_T0 (void)
1597
{
1598
    T0 = T0 << PARAM1;
1599
    RETURN();
1600
}
1601

    
1602
void OPPROTO op_srl_T0_T1 (void)
1603
{
1604
    T0 = (uint32_t)T0 >> T1;
1605
    RETURN();
1606
}
1607

    
1608
#if defined(TARGET_PPC64)
1609
void OPPROTO op_srl_T0_T1_64 (void)
1610
{
1611
    T0 = (uint32_t)T0 >> T1;
1612
    RETURN();
1613
}
1614
#endif
1615

    
1616
void OPPROTO op_srli_T0 (void)
1617
{
1618
    T0 = (uint32_t)T0 >> PARAM1;
1619
    RETURN();
1620
}
1621

    
1622
#if defined(TARGET_PPC64)
1623
void OPPROTO op_srli_T0_64 (void)
1624
{
1625
    T0 = (uint64_t)T0 >> PARAM1;
1626
    RETURN();
1627
}
1628
#endif
1629

    
1630
void OPPROTO op_srli_T1 (void)
1631
{
1632
    T1 = (uint32_t)T1 >> PARAM1;
1633
    RETURN();
1634
}
1635

    
1636
#if defined(TARGET_PPC64)
1637
void OPPROTO op_srli_T1_64 (void)
1638
{
1639
    T1 = (uint64_t)T1 >> PARAM1;
1640
    RETURN();
1641
}
1642
#endif
1643

    
1644
/***                       Floating-Point arithmetic                       ***/
1645
/* fadd - fadd. */
1646
void OPPROTO op_fadd (void)
1647
{
1648
    FT0 = float64_add(FT0, FT1, &env->fp_status);
1649
    RETURN();
1650
}
1651

    
1652
/* fsub - fsub. */
1653
void OPPROTO op_fsub (void)
1654
{
1655
    FT0 = float64_sub(FT0, FT1, &env->fp_status);
1656
    RETURN();
1657
}
1658

    
1659
/* fmul - fmul. */
1660
void OPPROTO op_fmul (void)
1661
{
1662
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1663
    RETURN();
1664
}
1665

    
1666
/* fdiv - fdiv. */
1667
void OPPROTO op_fdiv (void)
1668
{
1669
    FT0 = float64_div(FT0, FT1, &env->fp_status);
1670
    RETURN();
1671
}
1672

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

    
1680
/* fres - fres. */
1681
void OPPROTO op_fres (void)
1682
{
1683
    do_fres();
1684
    RETURN();
1685
}
1686

    
1687
/* frsqrte  - frsqrte. */
1688
void OPPROTO op_frsqrte (void)
1689
{
1690
    do_frsqrte();
1691
    RETURN();
1692
}
1693

    
1694
/* fsel - fsel. */
1695
void OPPROTO op_fsel (void)
1696
{
1697
    do_fsel();
1698
    RETURN();
1699
}
1700

    
1701
/***                     Floating-Point multiply-and-add                   ***/
1702
/* fmadd - fmadd. */
1703
void OPPROTO op_fmadd (void)
1704
{
1705
#if USE_PRECISE_EMULATION
1706
    do_fmadd();
1707
#else
1708
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1709
    FT0 = float64_add(FT0, FT2, &env->fp_status);
1710
#endif
1711
    RETURN();
1712
}
1713

    
1714
/* fmsub - fmsub. */
1715
void OPPROTO op_fmsub (void)
1716
{
1717
#if USE_PRECISE_EMULATION
1718
    do_fmsub();
1719
#else
1720
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1721
    FT0 = float64_sub(FT0, FT2, &env->fp_status);
1722
#endif
1723
    RETURN();
1724
}
1725

    
1726
/* fnmadd - fnmadd. - fnmadds - fnmadds. */
1727
void OPPROTO op_fnmadd (void)
1728
{
1729
    do_fnmadd();
1730
    RETURN();
1731
}
1732

    
1733
/* fnmsub - fnmsub. */
1734
void OPPROTO op_fnmsub (void)
1735
{
1736
    do_fnmsub();
1737
    RETURN();
1738
}
1739

    
1740
/***                     Floating-Point round & convert                    ***/
1741
/* frsp - frsp. */
1742
void OPPROTO op_frsp (void)
1743
{
1744
    FT0 = float64_to_float32(FT0, &env->fp_status);
1745
    RETURN();
1746
}
1747

    
1748
/* fctiw - fctiw. */
1749
void OPPROTO op_fctiw (void)
1750
{
1751
    do_fctiw();
1752
    RETURN();
1753
}
1754

    
1755
/* fctiwz - fctiwz. */
1756
void OPPROTO op_fctiwz (void)
1757
{
1758
    do_fctiwz();
1759
    RETURN();
1760
}
1761

    
1762
#if defined(TARGET_PPC64)
1763
/* fcfid - fcfid. */
1764
void OPPROTO op_fcfid (void)
1765
{
1766
    do_fcfid();
1767
    RETURN();
1768
}
1769

    
1770
/* fctid - fctid. */
1771
void OPPROTO op_fctid (void)
1772
{
1773
    do_fctid();
1774
    RETURN();
1775
}
1776

    
1777
/* fctidz - fctidz. */
1778
void OPPROTO op_fctidz (void)
1779
{
1780
    do_fctidz();
1781
    RETURN();
1782
}
1783
#endif
1784

    
1785
/***                         Floating-Point compare                        ***/
1786
/* fcmpu */
1787
void OPPROTO op_fcmpu (void)
1788
{
1789
    do_fcmpu();
1790
    RETURN();
1791
}
1792

    
1793
/* fcmpo */
1794
void OPPROTO op_fcmpo (void)
1795
{
1796
    do_fcmpo();
1797
    RETURN();
1798
}
1799

    
1800
/***                         Floating-point move                           ***/
1801
/* fabs */
1802
void OPPROTO op_fabs (void)
1803
{
1804
    FT0 = float64_abs(FT0);
1805
    RETURN();
1806
}
1807

    
1808
/* fnabs */
1809
void OPPROTO op_fnabs (void)
1810
{
1811
    FT0 = float64_abs(FT0);
1812
    FT0 = float64_chs(FT0);
1813
    RETURN();
1814
}
1815

    
1816
/* fneg */
1817
void OPPROTO op_fneg (void)
1818
{
1819
    FT0 = float64_chs(FT0);
1820
    RETURN();
1821
}
1822

    
1823
/* Load and store */
1824
#define MEMSUFFIX _raw
1825
#include "op_helper.h"
1826
#include "op_mem.h"
1827
#if !defined(CONFIG_USER_ONLY)
1828
#define MEMSUFFIX _user
1829
#include "op_helper.h"
1830
#include "op_mem.h"
1831
#define MEMSUFFIX _kernel
1832
#include "op_helper.h"
1833
#include "op_mem.h"
1834
#endif
1835

    
1836
/* Special op to check and maybe clear reservation */
1837
void OPPROTO op_check_reservation (void)
1838
{
1839
    if ((uint32_t)env->reserve == (uint32_t)(T0 & ~0x00000003))
1840
        env->reserve = -1;
1841
    RETURN();
1842
}
1843

    
1844
#if defined(TARGET_PPC64)
1845
void OPPROTO op_check_reservation_64 (void)
1846
{
1847
    if ((uint64_t)env->reserve == (uint64_t)(T0 & ~0x00000003))
1848
        env->reserve = -1;
1849
    RETURN();
1850
}
1851
#endif
1852

    
1853
/* Return from interrupt */
1854
#if !defined(CONFIG_USER_ONLY)
1855
void OPPROTO op_rfi (void)
1856
{
1857
    do_rfi();
1858
    RETURN();
1859
}
1860

    
1861
#if defined(TARGET_PPC64)
1862
void OPPROTO op_rfid (void)
1863
{
1864
    do_rfid();
1865
    RETURN();
1866
}
1867
#endif
1868
#endif
1869

    
1870
/* Trap word */
1871
void OPPROTO op_tw (void)
1872
{
1873
    do_tw(PARAM1);
1874
    RETURN();
1875
}
1876

    
1877
#if defined(TARGET_PPC64)
1878
void OPPROTO op_td (void)
1879
{
1880
    do_td(PARAM1);
1881
    RETURN();
1882
}
1883
#endif
1884

    
1885
#if !defined(CONFIG_USER_ONLY)
1886
/* tlbia */
1887
void OPPROTO op_tlbia (void)
1888
{
1889
    do_tlbia();
1890
    RETURN();
1891
}
1892

    
1893
/* tlbie */
1894
void OPPROTO op_tlbie (void)
1895
{
1896
    do_tlbie();
1897
    RETURN();
1898
}
1899

    
1900
#if defined(TARGET_PPC64)
1901
void OPPROTO op_tlbie_64 (void)
1902
{
1903
    do_tlbie_64();
1904
    RETURN();
1905
}
1906
#endif
1907

    
1908
#if defined(TARGET_PPC64)
1909
void OPPROTO op_slbia (void)
1910
{
1911
    do_slbia();
1912
    RETURN();
1913
}
1914

    
1915
void OPPROTO op_slbie (void)
1916
{
1917
    do_slbie();
1918
    RETURN();
1919
}
1920
#endif
1921
#endif
1922

    
1923
/* PowerPC 602/603/755 software TLB load instructions */
1924
#if !defined(CONFIG_USER_ONLY)
1925
void OPPROTO op_6xx_tlbld (void)
1926
{
1927
    do_load_6xx_tlb(0);
1928
    RETURN();
1929
}
1930

    
1931
void OPPROTO op_6xx_tlbli (void)
1932
{
1933
    do_load_6xx_tlb(1);
1934
    RETURN();
1935
}
1936
#endif
1937

    
1938
/* 601 specific */
1939
void OPPROTO op_load_601_rtcl (void)
1940
{
1941
    T0 = cpu_ppc601_load_rtcl(env);
1942
    RETURN();
1943
}
1944

    
1945
void OPPROTO op_load_601_rtcu (void)
1946
{
1947
    T0 = cpu_ppc601_load_rtcu(env);
1948
    RETURN();
1949
}
1950

    
1951
#if !defined(CONFIG_USER_ONLY)
1952
void OPPROTO op_store_601_rtcl (void)
1953
{
1954
    cpu_ppc601_store_rtcl(env, T0);
1955
    RETURN();
1956
}
1957

    
1958
void OPPROTO op_store_601_rtcu (void)
1959
{
1960
    cpu_ppc601_store_rtcu(env, T0);
1961
    RETURN();
1962
}
1963

    
1964
void OPPROTO op_load_601_bat (void)
1965
{
1966
    T0 = env->IBAT[PARAM1][PARAM2];
1967
    RETURN();
1968
}
1969
#endif /* !defined(CONFIG_USER_ONLY) */
1970

    
1971
/* 601 unified BATs store.
1972
 * To avoid using specific MMU code for 601, we store BATs in
1973
 * IBAT and DBAT simultaneously, then emulate unified BATs.
1974
 */
1975
#if !defined(CONFIG_USER_ONLY)
1976
void OPPROTO op_store_601_batl (void)
1977
{
1978
    int nr = PARAM1;
1979

    
1980
    env->IBAT[1][nr] = T0;
1981
    env->DBAT[1][nr] = T0;
1982
    RETURN();
1983
}
1984

    
1985
void OPPROTO op_store_601_batu (void)
1986
{
1987
    do_store_601_batu(PARAM1);
1988
    RETURN();
1989
}
1990
#endif /* !defined(CONFIG_USER_ONLY) */
1991

    
1992
/* PowerPC 601 specific instructions (POWER bridge) */
1993
/* XXX: those micro-ops need tests ! */
1994
void OPPROTO op_POWER_abs (void)
1995
{
1996
    if (T0 == INT32_MIN)
1997
        T0 = INT32_MAX;
1998
    else if (T0 < 0)
1999
        T0 = -T0;
2000
    RETURN();
2001
}
2002

    
2003
void OPPROTO op_POWER_abso (void)
2004
{
2005
    do_POWER_abso();
2006
    RETURN();
2007
}
2008

    
2009
void OPPROTO op_POWER_clcs (void)
2010
{
2011
    do_POWER_clcs();
2012
    RETURN();
2013
}
2014

    
2015
void OPPROTO op_POWER_div (void)
2016
{
2017
    do_POWER_div();
2018
    RETURN();
2019
}
2020

    
2021
void OPPROTO op_POWER_divo (void)
2022
{
2023
    do_POWER_divo();
2024
    RETURN();
2025
}
2026

    
2027
void OPPROTO op_POWER_divs (void)
2028
{
2029
    do_POWER_divs();
2030
    RETURN();
2031
}
2032

    
2033
void OPPROTO op_POWER_divso (void)
2034
{
2035
    do_POWER_divso();
2036
    RETURN();
2037
}
2038

    
2039
void OPPROTO op_POWER_doz (void)
2040
{
2041
    if ((int32_t)T1 > (int32_t)T0)
2042
        T0 = T1 - T0;
2043
    else
2044
        T0 = 0;
2045
    RETURN();
2046
}
2047

    
2048
void OPPROTO op_POWER_dozo (void)
2049
{
2050
    do_POWER_dozo();
2051
    RETURN();
2052
}
2053

    
2054
void OPPROTO op_load_xer_cmp (void)
2055
{
2056
    T2 = xer_cmp;
2057
    RETURN();
2058
}
2059

    
2060
void OPPROTO op_POWER_maskg (void)
2061
{
2062
    do_POWER_maskg();
2063
    RETURN();
2064
}
2065

    
2066
void OPPROTO op_POWER_maskir (void)
2067
{
2068
    T0 = (T0 & ~T2) | (T1 & T2);
2069
    RETURN();
2070
}
2071

    
2072
void OPPROTO op_POWER_mul (void)
2073
{
2074
    uint64_t tmp;
2075

    
2076
    tmp = (uint64_t)T0 * (uint64_t)T1;
2077
    env->spr[SPR_MQ] = tmp >> 32;
2078
    T0 = tmp;
2079
    RETURN();
2080
}
2081

    
2082
void OPPROTO op_POWER_mulo (void)
2083
{
2084
    do_POWER_mulo();
2085
    RETURN();
2086
}
2087

    
2088
void OPPROTO op_POWER_nabs (void)
2089
{
2090
    if (T0 > 0)
2091
        T0 = -T0;
2092
    RETURN();
2093
}
2094

    
2095
void OPPROTO op_POWER_nabso (void)
2096
{
2097
    /* nabs never overflows */
2098
    if (T0 > 0)
2099
        T0 = -T0;
2100
    xer_ov = 0;
2101
    RETURN();
2102
}
2103

    
2104
/* XXX: factorise POWER rotates... */
2105
void OPPROTO op_POWER_rlmi (void)
2106
{
2107
    T0 = rotl32(T0, T2) & PARAM1;
2108
    T0 |= T1 & PARAM2;
2109
    RETURN();
2110
}
2111

    
2112
void OPPROTO op_POWER_rrib (void)
2113
{
2114
    T2 &= 0x1FUL;
2115
    T0 = rotl32(T0 & INT32_MIN, T2);
2116
    T0 |= T1 & ~rotl32(INT32_MIN, T2);
2117
    RETURN();
2118
}
2119

    
2120
void OPPROTO op_POWER_sle (void)
2121
{
2122
    T1 &= 0x1FUL;
2123
    env->spr[SPR_MQ] = rotl32(T0, T1);
2124
    T0 = T0 << T1;
2125
    RETURN();
2126
}
2127

    
2128
void OPPROTO op_POWER_sleq (void)
2129
{
2130
    uint32_t tmp = env->spr[SPR_MQ];
2131

    
2132
    T1 &= 0x1FUL;
2133
    env->spr[SPR_MQ] = rotl32(T0, T1);
2134
    T0 = T0 << T1;
2135
    T0 |= tmp >> (32 - T1);
2136
    RETURN();
2137
}
2138

    
2139
void OPPROTO op_POWER_sllq (void)
2140
{
2141
    uint32_t msk = -1;
2142

    
2143
    msk = msk << (T1 & 0x1FUL);
2144
    if (T1 & 0x20UL)
2145
        msk = ~msk;
2146
    T1 &= 0x1FUL;
2147
    T0 = (T0 << T1) & msk;
2148
    T0 |= env->spr[SPR_MQ] & ~msk;
2149
    RETURN();
2150
}
2151

    
2152
void OPPROTO op_POWER_slq (void)
2153
{
2154
    uint32_t msk = -1, tmp;
2155

    
2156
    msk = msk << (T1 & 0x1FUL);
2157
    if (T1 & 0x20UL)
2158
        msk = ~msk;
2159
    T1 &= 0x1FUL;
2160
    tmp = rotl32(T0, T1);
2161
    T0 = tmp & msk;
2162
    env->spr[SPR_MQ] = tmp;
2163
    RETURN();
2164
}
2165

    
2166
void OPPROTO op_POWER_sraq (void)
2167
{
2168
    env->spr[SPR_MQ] = rotl32(T0, 32 - (T1 & 0x1FUL));
2169
    if (T1 & 0x20UL)
2170
        T0 = -1L;
2171
    else
2172
        T0 = (int32_t)T0 >> T1;
2173
    RETURN();
2174
}
2175

    
2176
void OPPROTO op_POWER_sre (void)
2177
{
2178
    T1 &= 0x1FUL;
2179
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2180
    T0 = (int32_t)T0 >> T1;
2181
    RETURN();
2182
}
2183

    
2184
void OPPROTO op_POWER_srea (void)
2185
{
2186
    T1 &= 0x1FUL;
2187
    env->spr[SPR_MQ] = T0 >> T1;
2188
    T0 = (int32_t)T0 >> T1;
2189
    RETURN();
2190
}
2191

    
2192
void OPPROTO op_POWER_sreq (void)
2193
{
2194
    uint32_t tmp;
2195
    int32_t msk;
2196

    
2197
    T1 &= 0x1FUL;
2198
    msk = INT32_MIN >> T1;
2199
    tmp = env->spr[SPR_MQ];
2200
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2201
    T0 = T0 >> T1;
2202
    T0 |= tmp & msk;
2203
    RETURN();
2204
}
2205

    
2206
void OPPROTO op_POWER_srlq (void)
2207
{
2208
    uint32_t tmp;
2209
    int32_t msk;
2210

    
2211
    msk = INT32_MIN >> (T1 & 0x1FUL);
2212
    if (T1 & 0x20UL)
2213
        msk = ~msk;
2214
    T1 &= 0x1FUL;
2215
    tmp = env->spr[SPR_MQ];
2216
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2217
    T0 = T0 >> T1;
2218
    T0 &= msk;
2219
    T0 |= tmp & ~msk;
2220
    RETURN();
2221
}
2222

    
2223
void OPPROTO op_POWER_srq (void)
2224
{
2225
    T1 &= 0x1FUL;
2226
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2227
    T0 = T0 >> T1;
2228
    RETURN();
2229
}
2230

    
2231
/* POWER instructions not implemented in PowerPC 601 */
2232
#if !defined(CONFIG_USER_ONLY)
2233
void OPPROTO op_POWER_mfsri (void)
2234
{
2235
    T1 = T0 >> 28;
2236
    T0 = env->sr[T1];
2237
    RETURN();
2238
}
2239

    
2240
void OPPROTO op_POWER_rac (void)
2241
{
2242
    do_POWER_rac();
2243
    RETURN();
2244
}
2245

    
2246
void OPPROTO op_POWER_rfsvc (void)
2247
{
2248
    do_POWER_rfsvc();
2249
    RETURN();
2250
}
2251
#endif
2252

    
2253
/* PowerPC 602 specific instruction */
2254
#if !defined(CONFIG_USER_ONLY)
2255
void OPPROTO op_602_mfrom (void)
2256
{
2257
    do_op_602_mfrom();
2258
    RETURN();
2259
}
2260
#endif
2261

    
2262
/* PowerPC 4xx specific micro-ops */
2263
void OPPROTO op_405_add_T0_T2 (void)
2264
{
2265
    T0 = (int32_t)T0 + (int32_t)T2;
2266
    RETURN();
2267
}
2268

    
2269
void OPPROTO op_405_mulchw (void)
2270
{
2271
    T0 = ((int16_t)T0) * ((int16_t)(T1 >> 16));
2272
    RETURN();
2273
}
2274

    
2275
void OPPROTO op_405_mulchwu (void)
2276
{
2277
    T0 = ((uint16_t)T0) * ((uint16_t)(T1 >> 16));
2278
    RETURN();
2279
}
2280

    
2281
void OPPROTO op_405_mulhhw (void)
2282
{
2283
    T0 = ((int16_t)(T0 >> 16)) * ((int16_t)(T1 >> 16));
2284
    RETURN();
2285
}
2286

    
2287
void OPPROTO op_405_mulhhwu (void)
2288
{
2289
    T0 = ((uint16_t)(T0 >> 16)) * ((uint16_t)(T1 >> 16));
2290
    RETURN();
2291
}
2292

    
2293
void OPPROTO op_405_mullhw (void)
2294
{
2295
    T0 = ((int16_t)T0) * ((int16_t)T1);
2296
    RETURN();
2297
}
2298

    
2299
void OPPROTO op_405_mullhwu (void)
2300
{
2301
    T0 = ((uint16_t)T0) * ((uint16_t)T1);
2302
    RETURN();
2303
}
2304

    
2305
void OPPROTO op_405_check_ov (void)
2306
{
2307
    do_405_check_ov();
2308
    RETURN();
2309
}
2310

    
2311
void OPPROTO op_405_check_sat (void)
2312
{
2313
    do_405_check_sat();
2314
    RETURN();
2315
}
2316

    
2317
void OPPROTO op_405_check_ovu (void)
2318
{
2319
    if (likely(T0 >= T2)) {
2320
        xer_ov = 0;
2321
    } else {
2322
        xer_ov = 1;
2323
        xer_so = 1;
2324
    }
2325
    RETURN();
2326
}
2327

    
2328
void OPPROTO op_405_check_satu (void)
2329
{
2330
    if (unlikely(T0 < T2)) {
2331
        /* Saturate result */
2332
        T0 = -1;
2333
    }
2334
    RETURN();
2335
}
2336

    
2337
void OPPROTO op_load_dcr (void)
2338
{
2339
    do_load_dcr();
2340
    RETURN();
2341
}
2342

    
2343
void OPPROTO op_store_dcr (void)
2344
{
2345
    do_store_dcr();
2346
    RETURN();
2347
}
2348

    
2349
#if !defined(CONFIG_USER_ONLY)
2350
/* Return from critical interrupt :
2351
 * same as rfi, except nip & MSR are loaded from SRR2/3 instead of SRR0/1
2352
 */
2353
void OPPROTO op_40x_rfci (void)
2354
{
2355
    do_40x_rfci();
2356
    RETURN();
2357
}
2358

    
2359
void OPPROTO op_rfci (void)
2360
{
2361
    do_rfci();
2362
    RETURN();
2363
}
2364

    
2365
void OPPROTO op_rfdi (void)
2366
{
2367
    do_rfdi();
2368
    RETURN();
2369
}
2370

    
2371
void OPPROTO op_rfmci (void)
2372
{
2373
    do_rfmci();
2374
    RETURN();
2375
}
2376

    
2377
void OPPROTO op_wrte (void)
2378
{
2379
    msr_ee = T0 >> 16;
2380
    RETURN();
2381
}
2382

    
2383
void OPPROTO op_440_tlbre (void)
2384
{
2385
    do_440_tlbre(PARAM1);
2386
    RETURN();
2387
}
2388

    
2389
void OPPROTO op_440_tlbsx (void)
2390
{
2391
    do_440_tlbsx();
2392
    RETURN();
2393
}
2394

    
2395
void OPPROTO op_440_tlbsx_ (void)
2396
{
2397
    do_440_tlbsx_();
2398
    RETURN();
2399
}
2400

    
2401
void OPPROTO op_440_tlbwe (void)
2402
{
2403
    do_440_tlbwe(PARAM1);
2404
    RETURN();
2405
}
2406

    
2407
void OPPROTO op_4xx_tlbre_lo (void)
2408
{
2409
    do_4xx_tlbre_lo();
2410
    RETURN();
2411
}
2412

    
2413
void OPPROTO op_4xx_tlbre_hi (void)
2414
{
2415
    do_4xx_tlbre_hi();
2416
    RETURN();
2417
}
2418

    
2419
void OPPROTO op_4xx_tlbsx (void)
2420
{
2421
    do_4xx_tlbsx();
2422
    RETURN();
2423
}
2424

    
2425
void OPPROTO op_4xx_tlbsx_ (void)
2426
{
2427
    do_4xx_tlbsx_();
2428
    RETURN();
2429
}
2430

    
2431
void OPPROTO op_4xx_tlbwe_lo (void)
2432
{
2433
    do_4xx_tlbwe_lo();
2434
    RETURN();
2435
}
2436

    
2437
void OPPROTO op_4xx_tlbwe_hi (void)
2438
{
2439
    do_4xx_tlbwe_hi();
2440
    RETURN();
2441
}
2442
#endif
2443

    
2444
/* SPR micro-ops */
2445
/* 440 specific */
2446
void OPPROTO op_440_dlmzb (void)
2447
{
2448
    do_440_dlmzb();
2449
    RETURN();
2450
}
2451

    
2452
void OPPROTO op_440_dlmzb_update_Rc (void)
2453
{
2454
    if (T0 == 8)
2455
        T0 = 0x2;
2456
    else if (T0 < 4)
2457
        T0 = 0x4;
2458
    else
2459
        T0 = 0x8;
2460
    RETURN();
2461
}
2462

    
2463
#if !defined(CONFIG_USER_ONLY)
2464
void OPPROTO op_store_pir (void)
2465
{
2466
    env->spr[SPR_PIR] = T0 & 0x0000000FUL;
2467
    RETURN();
2468
}
2469

    
2470
void OPPROTO op_load_403_pb (void)
2471
{
2472
    do_load_403_pb(PARAM1);
2473
    RETURN();
2474
}
2475

    
2476
void OPPROTO op_store_403_pb (void)
2477
{
2478
    do_store_403_pb(PARAM1);
2479
    RETURN();
2480
}
2481

    
2482
void OPPROTO op_load_40x_pit (void)
2483
{
2484
    T0 = load_40x_pit(env);
2485
    RETURN();
2486
}
2487

    
2488
void OPPROTO op_store_40x_pit (void)
2489
{
2490
    store_40x_pit(env, T0);
2491
    RETURN();
2492
}
2493

    
2494
void OPPROTO op_store_40x_dbcr0 (void)
2495
{
2496
    store_40x_dbcr0(env, T0);
2497
}
2498

    
2499
void OPPROTO op_store_40x_sler (void)
2500
{
2501
    store_40x_sler(env, T0);
2502
    RETURN();
2503
}
2504

    
2505
void OPPROTO op_store_booke_tcr (void)
2506
{
2507
    store_booke_tcr(env, T0);
2508
    RETURN();
2509
}
2510

    
2511
void OPPROTO op_store_booke_tsr (void)
2512
{
2513
    store_booke_tsr(env, T0);
2514
    RETURN();
2515
}
2516

    
2517
#endif /* !defined(CONFIG_USER_ONLY) */
2518

    
2519
#if defined(TARGET_PPCEMB)
2520
/* SPE extension */
2521
void OPPROTO op_splatw_T1_64 (void)
2522
{
2523
    T1_64 = (T1_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL);
2524
    RETURN();
2525
}
2526

    
2527
void OPPROTO op_splatwi_T0_64 (void)
2528
{
2529
    uint64_t tmp = PARAM1;
2530

    
2531
    T0_64 = (tmp << 32) | tmp;
2532
    RETURN();
2533
}
2534

    
2535
void OPPROTO op_splatwi_T1_64 (void)
2536
{
2537
    uint64_t tmp = PARAM1;
2538

    
2539
    T1_64 = (tmp << 32) | tmp;
2540
    RETURN();
2541
}
2542

    
2543
void OPPROTO op_extsh_T1_64 (void)
2544
{
2545
    T1_64 = (int32_t)((int16_t)T1_64);
2546
    RETURN();
2547
}
2548

    
2549
void OPPROTO op_sli16_T1_64 (void)
2550
{
2551
    T1_64 = T1_64 << 16;
2552
    RETURN();
2553
}
2554

    
2555
void OPPROTO op_sli32_T1_64 (void)
2556
{
2557
    T1_64 = T1_64 << 32;
2558
    RETURN();
2559
}
2560

    
2561
void OPPROTO op_srli32_T1_64 (void)
2562
{
2563
    T1_64 = T1_64 >> 32;
2564
    RETURN();
2565
}
2566

    
2567
void OPPROTO op_evsel (void)
2568
{
2569
    do_evsel();
2570
    RETURN();
2571
}
2572

    
2573
void OPPROTO op_evaddw (void)
2574
{
2575
    do_evaddw();
2576
    RETURN();
2577
}
2578

    
2579
void OPPROTO op_evsubfw (void)
2580
{
2581
    do_evsubfw();
2582
    RETURN();
2583
}
2584

    
2585
void OPPROTO op_evneg (void)
2586
{
2587
    do_evneg();
2588
    RETURN();
2589
}
2590

    
2591
void OPPROTO op_evabs (void)
2592
{
2593
    do_evabs();
2594
    RETURN();
2595
}
2596

    
2597
void OPPROTO op_evextsh (void)
2598
{
2599
    T0_64 = ((uint64_t)((int32_t)(int16_t)(T0_64 >> 32)) << 32) |
2600
        (uint64_t)((int32_t)(int16_t)T0_64);
2601
    RETURN();
2602
}
2603

    
2604
void OPPROTO op_evextsb (void)
2605
{
2606
    T0_64 = ((uint64_t)((int32_t)(int8_t)(T0_64 >> 32)) << 32) |
2607
        (uint64_t)((int32_t)(int8_t)T0_64);
2608
    RETURN();
2609
}
2610

    
2611
void OPPROTO op_evcntlzw (void)
2612
{
2613
    do_evcntlzw();
2614
    RETURN();
2615
}
2616

    
2617
void OPPROTO op_evrndw (void)
2618
{
2619
    do_evrndw();
2620
    RETURN();
2621
}
2622

    
2623
void OPPROTO op_brinc (void)
2624
{
2625
    do_brinc();
2626
    RETURN();
2627
}
2628

    
2629
void OPPROTO op_evcntlsw (void)
2630
{
2631
    do_evcntlsw();
2632
    RETURN();
2633
}
2634

    
2635
void OPPROTO op_evand (void)
2636
{
2637
    T0_64 &= T1_64;
2638
    RETURN();
2639
}
2640

    
2641
void OPPROTO op_evandc (void)
2642
{
2643
    T0_64 &= ~T1_64;
2644
    RETURN();
2645
}
2646

    
2647
void OPPROTO op_evor (void)
2648
{
2649
    T0_64 |= T1_64;
2650
    RETURN();
2651
}
2652

    
2653
void OPPROTO op_evxor (void)
2654
{
2655
    T0_64 ^= T1_64;
2656
    RETURN();
2657
}
2658

    
2659
void OPPROTO op_eveqv (void)
2660
{
2661
    T0_64 = ~(T0_64 ^ T1_64);
2662
    RETURN();
2663
}
2664

    
2665
void OPPROTO op_evnor (void)
2666
{
2667
    T0_64 = ~(T0_64 | T1_64);
2668
    RETURN();
2669
}
2670

    
2671
void OPPROTO op_evorc (void)
2672
{
2673
    T0_64 |= ~T1_64;
2674
    RETURN();
2675
}
2676

    
2677
void OPPROTO op_evnand (void)
2678
{
2679
    T0_64 = ~(T0_64 & T1_64);
2680
    RETURN();
2681
}
2682

    
2683
void OPPROTO op_evsrws (void)
2684
{
2685
    do_evsrws();
2686
    RETURN();
2687
}
2688

    
2689
void OPPROTO op_evsrwu (void)
2690
{
2691
    do_evsrwu();
2692
    RETURN();
2693
}
2694

    
2695
void OPPROTO op_evslw (void)
2696
{
2697
    do_evslw();
2698
    RETURN();
2699
}
2700

    
2701
void OPPROTO op_evrlw (void)
2702
{
2703
    do_evrlw();
2704
    RETURN();
2705
}
2706

    
2707
void OPPROTO op_evmergelo (void)
2708
{
2709
    T0_64 = (T0_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL);
2710
    RETURN();
2711
}
2712

    
2713
void OPPROTO op_evmergehi (void)
2714
{
2715
    T0_64 = (T0_64 & 0xFFFFFFFF00000000ULL) | (T1_64 >> 32);
2716
    RETURN();
2717
}
2718

    
2719
void OPPROTO op_evmergelohi (void)
2720
{
2721
    T0_64 = (T0_64 << 32) | (T1_64 >> 32);
2722
    RETURN();
2723
}
2724

    
2725
void OPPROTO op_evmergehilo (void)
2726
{
2727
    T0_64 = (T0_64 & 0xFFFFFFFF00000000ULL) | (T1_64 & 0x00000000FFFFFFFFULL);
2728
    RETURN();
2729
}
2730

    
2731
void OPPROTO op_evcmpgts (void)
2732
{
2733
    do_evcmpgts();
2734
    RETURN();
2735
}
2736

    
2737
void OPPROTO op_evcmpgtu (void)
2738
{
2739
    do_evcmpgtu();
2740
    RETURN();
2741
}
2742

    
2743
void OPPROTO op_evcmplts (void)
2744
{
2745
    do_evcmplts();
2746
    RETURN();
2747
}
2748

    
2749
void OPPROTO op_evcmpltu (void)
2750
{
2751
    do_evcmpltu();
2752
    RETURN();
2753
}
2754

    
2755
void OPPROTO op_evcmpeq (void)
2756
{
2757
    do_evcmpeq();
2758
    RETURN();
2759
}
2760

    
2761
void OPPROTO op_evfssub (void)
2762
{
2763
    do_evfssub();
2764
    RETURN();
2765
}
2766

    
2767
void OPPROTO op_evfsadd (void)
2768
{
2769
    do_evfsadd();
2770
    RETURN();
2771
}
2772

    
2773
void OPPROTO op_evfsnabs (void)
2774
{
2775
    do_evfsnabs();
2776
    RETURN();
2777
}
2778

    
2779
void OPPROTO op_evfsabs (void)
2780
{
2781
    do_evfsabs();
2782
    RETURN();
2783
}
2784

    
2785
void OPPROTO op_evfsneg (void)
2786
{
2787
    do_evfsneg();
2788
    RETURN();
2789
}
2790

    
2791
void OPPROTO op_evfsdiv (void)
2792
{
2793
    do_evfsdiv();
2794
    RETURN();
2795
}
2796

    
2797
void OPPROTO op_evfsmul (void)
2798
{
2799
    do_evfsmul();
2800
    RETURN();
2801
}
2802

    
2803
void OPPROTO op_evfscmplt (void)
2804
{
2805
    do_evfscmplt();
2806
    RETURN();
2807
}
2808

    
2809
void OPPROTO op_evfscmpgt (void)
2810
{
2811
    do_evfscmpgt();
2812
    RETURN();
2813
}
2814

    
2815
void OPPROTO op_evfscmpeq (void)
2816
{
2817
    do_evfscmpeq();
2818
    RETURN();
2819
}
2820

    
2821
void OPPROTO op_evfscfsi (void)
2822
{
2823
    do_evfscfsi();
2824
    RETURN();
2825
}
2826

    
2827
void OPPROTO op_evfscfui (void)
2828
{
2829
    do_evfscfui();
2830
    RETURN();
2831
}
2832

    
2833
void OPPROTO op_evfscfsf (void)
2834
{
2835
    do_evfscfsf();
2836
    RETURN();
2837
}
2838

    
2839
void OPPROTO op_evfscfuf (void)
2840
{
2841
    do_evfscfuf();
2842
    RETURN();
2843
}
2844

    
2845
void OPPROTO op_evfsctsi (void)
2846
{
2847
    do_evfsctsi();
2848
    RETURN();
2849
}
2850

    
2851
void OPPROTO op_evfsctui (void)
2852
{
2853
    do_evfsctui();
2854
    RETURN();
2855
}
2856

    
2857
void OPPROTO op_evfsctsf (void)
2858
{
2859
    do_evfsctsf();
2860
    RETURN();
2861
}
2862

    
2863
void OPPROTO op_evfsctuf (void)
2864
{
2865
    do_evfsctuf();
2866
    RETURN();
2867
}
2868

    
2869
void OPPROTO op_evfsctuiz (void)
2870
{
2871
    do_evfsctuiz();
2872
    RETURN();
2873
}
2874

    
2875
void OPPROTO op_evfsctsiz (void)
2876
{
2877
    do_evfsctsiz();
2878
    RETURN();
2879
}
2880

    
2881
void OPPROTO op_evfststlt (void)
2882
{
2883
    do_evfststlt();
2884
    RETURN();
2885
}
2886

    
2887
void OPPROTO op_evfststgt (void)
2888
{
2889
    do_evfststgt();
2890
    RETURN();
2891
}
2892

    
2893
void OPPROTO op_evfststeq (void)
2894
{
2895
    do_evfststeq();
2896
    RETURN();
2897
}
2898

    
2899
void OPPROTO op_efssub (void)
2900
{
2901
    T0_64 = _do_efssub(T0_64, T1_64);
2902
    RETURN();
2903
}
2904

    
2905
void OPPROTO op_efsadd (void)
2906
{
2907
    T0_64 = _do_efsadd(T0_64, T1_64);
2908
    RETURN();
2909
}
2910

    
2911
void OPPROTO op_efsnabs (void)
2912
{
2913
    T0_64 = _do_efsnabs(T0_64);
2914
    RETURN();
2915
}
2916

    
2917
void OPPROTO op_efsabs (void)
2918
{
2919
    T0_64 = _do_efsabs(T0_64);
2920
    RETURN();
2921
}
2922

    
2923
void OPPROTO op_efsneg (void)
2924
{
2925
    T0_64 = _do_efsneg(T0_64);
2926
    RETURN();
2927
}
2928

    
2929
void OPPROTO op_efsdiv (void)
2930
{
2931
    T0_64 = _do_efsdiv(T0_64, T1_64);
2932
    RETURN();
2933
}
2934

    
2935
void OPPROTO op_efsmul (void)
2936
{
2937
    T0_64 = _do_efsmul(T0_64, T1_64);
2938
    RETURN();
2939
}
2940

    
2941
void OPPROTO op_efscmplt (void)
2942
{
2943
    do_efscmplt();
2944
    RETURN();
2945
}
2946

    
2947
void OPPROTO op_efscmpgt (void)
2948
{
2949
    do_efscmpgt();
2950
    RETURN();
2951
}
2952

    
2953
void OPPROTO op_efscfd (void)
2954
{
2955
    do_efscfd();
2956
    RETURN();
2957
}
2958

    
2959
void OPPROTO op_efscmpeq (void)
2960
{
2961
    do_efscmpeq();
2962
    RETURN();
2963
}
2964

    
2965
void OPPROTO op_efscfsi (void)
2966
{
2967
    do_efscfsi();
2968
    RETURN();
2969
}
2970

    
2971
void OPPROTO op_efscfui (void)
2972
{
2973
    do_efscfui();
2974
    RETURN();
2975
}
2976

    
2977
void OPPROTO op_efscfsf (void)
2978
{
2979
    do_efscfsf();
2980
    RETURN();
2981
}
2982

    
2983
void OPPROTO op_efscfuf (void)
2984
{
2985
    do_efscfuf();
2986
    RETURN();
2987
}
2988

    
2989
void OPPROTO op_efsctsi (void)
2990
{
2991
    do_efsctsi();
2992
    RETURN();
2993
}
2994

    
2995
void OPPROTO op_efsctui (void)
2996
{
2997
    do_efsctui();
2998
    RETURN();
2999
}
3000

    
3001
void OPPROTO op_efsctsf (void)
3002
{
3003
    do_efsctsf();
3004
    RETURN();
3005
}
3006

    
3007
void OPPROTO op_efsctuf (void)
3008
{
3009
    do_efsctuf();
3010
    RETURN();
3011
}
3012

    
3013
void OPPROTO op_efsctsiz (void)
3014
{
3015
    do_efsctsiz();
3016
    RETURN();
3017
}
3018

    
3019
void OPPROTO op_efsctuiz (void)
3020
{
3021
    do_efsctuiz();
3022
    RETURN();
3023
}
3024

    
3025
void OPPROTO op_efststlt (void)
3026
{
3027
    T0 = _do_efststlt(T0_64, T1_64);
3028
    RETURN();
3029
}
3030

    
3031
void OPPROTO op_efststgt (void)
3032
{
3033
    T0 = _do_efststgt(T0_64, T1_64);
3034
    RETURN();
3035
}
3036

    
3037
void OPPROTO op_efststeq (void)
3038
{
3039
    T0 = _do_efststeq(T0_64, T1_64);
3040
    RETURN();
3041
}
3042

    
3043
void OPPROTO op_efdsub (void)
3044
{
3045
    union {
3046
        uint64_t u;
3047
        float64 f;
3048
    } u1, u2;
3049
    u1.u = T0_64;
3050
    u2.u = T1_64;
3051
    u1.f = float64_sub(u1.f, u2.f, &env->spe_status);
3052
    T0_64 = u1.u;
3053
    RETURN();
3054
}
3055

    
3056
void OPPROTO op_efdadd (void)
3057
{
3058
    union {
3059
        uint64_t u;
3060
        float64 f;
3061
    } u1, u2;
3062
    u1.u = T0_64;
3063
    u2.u = T1_64;
3064
    u1.f = float64_add(u1.f, u2.f, &env->spe_status);
3065
    T0_64 = u1.u;
3066
    RETURN();
3067
}
3068

    
3069
void OPPROTO op_efdcfsid (void)
3070
{
3071
    do_efdcfsi();
3072
    RETURN();
3073
}
3074

    
3075
void OPPROTO op_efdcfuid (void)
3076
{
3077
    do_efdcfui();
3078
    RETURN();
3079
}
3080

    
3081
void OPPROTO op_efdnabs (void)
3082
{
3083
    T0_64 |= 0x8000000000000000ULL;
3084
    RETURN();
3085
}
3086

    
3087
void OPPROTO op_efdabs (void)
3088
{
3089
    T0_64 &= ~0x8000000000000000ULL;
3090
    RETURN();
3091
}
3092

    
3093
void OPPROTO op_efdneg (void)
3094
{
3095
    T0_64 ^= 0x8000000000000000ULL;
3096
    RETURN();
3097
}
3098

    
3099
void OPPROTO op_efddiv (void)
3100
{
3101
    union {
3102
        uint64_t u;
3103
        float64 f;
3104
    } u1, u2;
3105
    u1.u = T0_64;
3106
    u2.u = T1_64;
3107
    u1.f = float64_div(u1.f, u2.f, &env->spe_status);
3108
    T0_64 = u1.u;
3109
    RETURN();
3110
}
3111

    
3112
void OPPROTO op_efdmul (void)
3113
{
3114
    union {
3115
        uint64_t u;
3116
        float64 f;
3117
    } u1, u2;
3118
    u1.u = T0_64;
3119
    u2.u = T1_64;
3120
    u1.f = float64_mul(u1.f, u2.f, &env->spe_status);
3121
    T0_64 = u1.u;
3122
    RETURN();
3123
}
3124

    
3125
void OPPROTO op_efdctsidz (void)
3126
{
3127
    do_efdctsiz();
3128
    RETURN();
3129
}
3130

    
3131
void OPPROTO op_efdctuidz (void)
3132
{
3133
    do_efdctuiz();
3134
    RETURN();
3135
}
3136

    
3137
void OPPROTO op_efdcmplt (void)
3138
{
3139
    do_efdcmplt();
3140
    RETURN();
3141
}
3142

    
3143
void OPPROTO op_efdcmpgt (void)
3144
{
3145
    do_efdcmpgt();
3146
    RETURN();
3147
}
3148

    
3149
void OPPROTO op_efdcfs (void)
3150
{
3151
    do_efdcfs();
3152
    RETURN();
3153
}
3154

    
3155
void OPPROTO op_efdcmpeq (void)
3156
{
3157
    do_efdcmpeq();
3158
    RETURN();
3159
}
3160

    
3161
void OPPROTO op_efdcfsi (void)
3162
{
3163
    do_efdcfsi();
3164
    RETURN();
3165
}
3166

    
3167
void OPPROTO op_efdcfui (void)
3168
{
3169
    do_efdcfui();
3170
    RETURN();
3171
}
3172

    
3173
void OPPROTO op_efdcfsf (void)
3174
{
3175
    do_efdcfsf();
3176
    RETURN();
3177
}
3178

    
3179
void OPPROTO op_efdcfuf (void)
3180
{
3181
    do_efdcfuf();
3182
    RETURN();
3183
}
3184

    
3185
void OPPROTO op_efdctsi (void)
3186
{
3187
    do_efdctsi();
3188
    RETURN();
3189
}
3190

    
3191
void OPPROTO op_efdctui (void)
3192
{
3193
    do_efdctui();
3194
    RETURN();
3195
}
3196

    
3197
void OPPROTO op_efdctsf (void)
3198
{
3199
    do_efdctsf();
3200
    RETURN();
3201
}
3202

    
3203
void OPPROTO op_efdctuf (void)
3204
{
3205
    do_efdctuf();
3206
    RETURN();
3207
}
3208

    
3209
void OPPROTO op_efdctuiz (void)
3210
{
3211
    do_efdctuiz();
3212
    RETURN();
3213
}
3214

    
3215
void OPPROTO op_efdctsiz (void)
3216
{
3217
    do_efdctsiz();
3218
    RETURN();
3219
}
3220

    
3221
void OPPROTO op_efdtstlt (void)
3222
{
3223
    T0 = _do_efdtstlt(T0_64, T1_64);
3224
    RETURN();
3225
}
3226

    
3227
void OPPROTO op_efdtstgt (void)
3228
{
3229
    T0 = _do_efdtstgt(T0_64, T1_64);
3230
    RETURN();
3231
}
3232

    
3233
void OPPROTO op_efdtsteq (void)
3234
{
3235
    T0 = _do_efdtsteq(T0_64, T1_64);
3236
    RETURN();
3237
}
3238
#endif /* defined(TARGET_PPCEMB) */