Statistics
| Branch: | Revision:

root / target-ppc / op.c @ 966439a6

History | View | Annotate | Download (46.8 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
/* count leading zero */
1357
void OPPROTO op_cntlzw (void)
1358
{
1359
    T0 = _do_cntlzw(T0);
1360
    RETURN();
1361
}
1362

    
1363
#if defined(TARGET_PPC64)
1364
void OPPROTO op_cntlzd (void)
1365
{
1366
    T0 = _do_cntlzd(T0);
1367
    RETURN();
1368
}
1369
#endif
1370

    
1371
/* eqv */
1372
void OPPROTO op_eqv (void)
1373
{
1374
    T0 = ~(T0 ^ T1);
1375
    RETURN();
1376
}
1377

    
1378
/* extend sign byte */
1379
void OPPROTO op_extsb (void)
1380
{
1381
#if defined (TARGET_PPC64)
1382
    T0 = (int64_t)((int8_t)T0);
1383
#else
1384
    T0 = (int32_t)((int8_t)T0);
1385
#endif
1386
    RETURN();
1387
}
1388

    
1389
/* extend sign half word */
1390
void OPPROTO op_extsh (void)
1391
{
1392
#if defined (TARGET_PPC64)
1393
    T0 = (int64_t)((int16_t)T0);
1394
#else
1395
    T0 = (int32_t)((int16_t)T0);
1396
#endif
1397
    RETURN();
1398
}
1399

    
1400
#if defined (TARGET_PPC64)
1401
void OPPROTO op_extsw (void)
1402
{
1403
    T0 = (int64_t)((int32_t)T0);
1404
    RETURN();
1405
}
1406
#endif
1407

    
1408
/* nand */
1409
void OPPROTO op_nand (void)
1410
{
1411
    T0 = ~(T0 & T1);
1412
    RETURN();
1413
}
1414

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

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

    
1429
/* orc */
1430
void OPPROTO op_orc (void)
1431
{
1432
    T0 |= ~T1;
1433
    RETURN();
1434
}
1435

    
1436
/* ori */
1437
void OPPROTO op_ori (void)
1438
{
1439
    T0 |= PARAM1;
1440
    RETURN();
1441
}
1442

    
1443
/* xor */
1444
void OPPROTO op_xor (void)
1445
{
1446
    T0 ^= T1;
1447
    RETURN();
1448
}
1449

    
1450
/* xori */
1451
void OPPROTO op_xori (void)
1452
{
1453
    T0 ^= PARAM1;
1454
    RETURN();
1455
}
1456

    
1457
/***                             Integer rotate                            ***/
1458
void OPPROTO op_rotl32_T0_T1 (void)
1459
{
1460
    T0 = rotl32(T0, T1 & 0x1F);
1461
    RETURN();
1462
}
1463

    
1464
void OPPROTO op_rotli32_T0 (void)
1465
{
1466
    T0 = rotl32(T0, PARAM1);
1467
    RETURN();
1468
}
1469

    
1470
#if defined(TARGET_PPC64)
1471
void OPPROTO op_rotl64_T0_T1 (void)
1472
{
1473
    T0 = rotl64(T0, T1 & 0x3F);
1474
    RETURN();
1475
}
1476

    
1477
void OPPROTO op_rotli64_T0 (void)
1478
{
1479
    T0 = rotl64(T0, PARAM1);
1480
    RETURN();
1481
}
1482
#endif
1483

    
1484
/***                             Integer shift                             ***/
1485
/* shift left word */
1486
void OPPROTO op_slw (void)
1487
{
1488
    if (T1 & 0x20) {
1489
        T0 = 0;
1490
    } else {
1491
        T0 = (uint32_t)(T0 << T1);
1492
    }
1493
    RETURN();
1494
}
1495

    
1496
#if defined(TARGET_PPC64)
1497
void OPPROTO op_sld (void)
1498
{
1499
    if (T1 & 0x40) {
1500
        T0 = 0;
1501
    } else {
1502
        T0 = T0 << T1;
1503
    }
1504
    RETURN();
1505
}
1506
#endif
1507

    
1508
/* shift right algebraic word */
1509
void OPPROTO op_sraw (void)
1510
{
1511
    do_sraw();
1512
    RETURN();
1513
}
1514

    
1515
#if defined(TARGET_PPC64)
1516
void OPPROTO op_srad (void)
1517
{
1518
    do_srad();
1519
    RETURN();
1520
}
1521
#endif
1522

    
1523
/* shift right algebraic word immediate */
1524
void OPPROTO op_srawi (void)
1525
{
1526
    uint32_t mask = (uint32_t)PARAM2;
1527

    
1528
    T0 = (int32_t)T0 >> PARAM1;
1529
    if ((int32_t)T1 < 0 && (T1 & mask) != 0) {
1530
        xer_ca = 1;
1531
    } else {
1532
        xer_ca = 0;
1533
    }
1534
    RETURN();
1535
}
1536

    
1537
#if defined(TARGET_PPC64)
1538
void OPPROTO op_sradi (void)
1539
{
1540
    uint64_t mask = ((uint64_t)PARAM2 << 32) | (uint64_t)PARAM3;
1541

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

    
1552
/* shift right word */
1553
void OPPROTO op_srw (void)
1554
{
1555
    if (T1 & 0x20) {
1556
        T0 = 0;
1557
    } else {
1558
        T0 = (uint32_t)T0 >> T1;
1559
    }
1560
    RETURN();
1561
}
1562

    
1563
#if defined(TARGET_PPC64)
1564
void OPPROTO op_srd (void)
1565
{
1566
    if (T1 & 0x40) {
1567
        T0 = 0;
1568
    } else {
1569
        T0 = (uint64_t)T0 >> T1;
1570
    }
1571
    RETURN();
1572
}
1573
#endif
1574

    
1575
void OPPROTO op_sl_T0_T1 (void)
1576
{
1577
    T0 = T0 << T1;
1578
    RETURN();
1579
}
1580

    
1581
void OPPROTO op_sli_T0 (void)
1582
{
1583
    T0 = T0 << PARAM1;
1584
    RETURN();
1585
}
1586

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

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

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

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

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

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

    
1629
/***                       Floating-Point arithmetic                       ***/
1630
/* fadd - fadd. */
1631
void OPPROTO op_fadd (void)
1632
{
1633
    FT0 = float64_add(FT0, FT1, &env->fp_status);
1634
    RETURN();
1635
}
1636

    
1637
/* fsub - fsub. */
1638
void OPPROTO op_fsub (void)
1639
{
1640
    FT0 = float64_sub(FT0, FT1, &env->fp_status);
1641
    RETURN();
1642
}
1643

    
1644
/* fmul - fmul. */
1645
void OPPROTO op_fmul (void)
1646
{
1647
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1648
    RETURN();
1649
}
1650

    
1651
/* fdiv - fdiv. */
1652
void OPPROTO op_fdiv (void)
1653
{
1654
    FT0 = float64_div(FT0, FT1, &env->fp_status);
1655
    RETURN();
1656
}
1657

    
1658
/* fsqrt - fsqrt. */
1659
void OPPROTO op_fsqrt (void)
1660
{
1661
    do_fsqrt();
1662
    RETURN();
1663
}
1664

    
1665
/* fres - fres. */
1666
void OPPROTO op_fres (void)
1667
{
1668
    do_fres();
1669
    RETURN();
1670
}
1671

    
1672
/* frsqrte  - frsqrte. */
1673
void OPPROTO op_frsqrte (void)
1674
{
1675
    do_frsqrte();
1676
    RETURN();
1677
}
1678

    
1679
/* fsel - fsel. */
1680
void OPPROTO op_fsel (void)
1681
{
1682
    do_fsel();
1683
    RETURN();
1684
}
1685

    
1686
/***                     Floating-Point multiply-and-add                   ***/
1687
/* fmadd - fmadd. */
1688
void OPPROTO op_fmadd (void)
1689
{
1690
#if USE_PRECISE_EMULATION
1691
    do_fmadd();
1692
#else
1693
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1694
    FT0 = float64_add(FT0, FT2, &env->fp_status);
1695
#endif
1696
    RETURN();
1697
}
1698

    
1699
/* fmsub - fmsub. */
1700
void OPPROTO op_fmsub (void)
1701
{
1702
#if USE_PRECISE_EMULATION
1703
    do_fmsub();
1704
#else
1705
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1706
    FT0 = float64_sub(FT0, FT2, &env->fp_status);
1707
#endif
1708
    RETURN();
1709
}
1710

    
1711
/* fnmadd - fnmadd. - fnmadds - fnmadds. */
1712
void OPPROTO op_fnmadd (void)
1713
{
1714
    do_fnmadd();
1715
    RETURN();
1716
}
1717

    
1718
/* fnmsub - fnmsub. */
1719
void OPPROTO op_fnmsub (void)
1720
{
1721
    do_fnmsub();
1722
    RETURN();
1723
}
1724

    
1725
/***                     Floating-Point round & convert                    ***/
1726
/* frsp - frsp. */
1727
void OPPROTO op_frsp (void)
1728
{
1729
    FT0 = float64_to_float32(FT0, &env->fp_status);
1730
    RETURN();
1731
}
1732

    
1733
/* fctiw - fctiw. */
1734
void OPPROTO op_fctiw (void)
1735
{
1736
    do_fctiw();
1737
    RETURN();
1738
}
1739

    
1740
/* fctiwz - fctiwz. */
1741
void OPPROTO op_fctiwz (void)
1742
{
1743
    do_fctiwz();
1744
    RETURN();
1745
}
1746

    
1747
#if defined(TARGET_PPC64)
1748
/* fcfid - fcfid. */
1749
void OPPROTO op_fcfid (void)
1750
{
1751
    do_fcfid();
1752
    RETURN();
1753
}
1754

    
1755
/* fctid - fctid. */
1756
void OPPROTO op_fctid (void)
1757
{
1758
    do_fctid();
1759
    RETURN();
1760
}
1761

    
1762
/* fctidz - fctidz. */
1763
void OPPROTO op_fctidz (void)
1764
{
1765
    do_fctidz();
1766
    RETURN();
1767
}
1768
#endif
1769

    
1770
/***                         Floating-Point compare                        ***/
1771
/* fcmpu */
1772
void OPPROTO op_fcmpu (void)
1773
{
1774
    do_fcmpu();
1775
    RETURN();
1776
}
1777

    
1778
/* fcmpo */
1779
void OPPROTO op_fcmpo (void)
1780
{
1781
    do_fcmpo();
1782
    RETURN();
1783
}
1784

    
1785
/***                         Floating-point move                           ***/
1786
/* fabs */
1787
void OPPROTO op_fabs (void)
1788
{
1789
    FT0 = float64_abs(FT0);
1790
    RETURN();
1791
}
1792

    
1793
/* fnabs */
1794
void OPPROTO op_fnabs (void)
1795
{
1796
    FT0 = float64_abs(FT0);
1797
    FT0 = float64_chs(FT0);
1798
    RETURN();
1799
}
1800

    
1801
/* fneg */
1802
void OPPROTO op_fneg (void)
1803
{
1804
    FT0 = float64_chs(FT0);
1805
    RETURN();
1806
}
1807

    
1808
/* Load and store */
1809
#define MEMSUFFIX _raw
1810
#include "op_helper.h"
1811
#include "op_mem.h"
1812
#if !defined(CONFIG_USER_ONLY)
1813
#define MEMSUFFIX _user
1814
#include "op_helper.h"
1815
#include "op_mem.h"
1816
#define MEMSUFFIX _kernel
1817
#include "op_helper.h"
1818
#include "op_mem.h"
1819
#endif
1820

    
1821
/* Special op to check and maybe clear reservation */
1822
void OPPROTO op_check_reservation (void)
1823
{
1824
    if ((uint32_t)env->reserve == (uint32_t)(T0 & ~0x00000003))
1825
        env->reserve = -1;
1826
    RETURN();
1827
}
1828

    
1829
#if defined(TARGET_PPC64)
1830
void OPPROTO op_check_reservation_64 (void)
1831
{
1832
    if ((uint64_t)env->reserve == (uint64_t)(T0 & ~0x00000003))
1833
        env->reserve = -1;
1834
    RETURN();
1835
}
1836
#endif
1837

    
1838
/* Return from interrupt */
1839
#if !defined(CONFIG_USER_ONLY)
1840
void OPPROTO op_rfi (void)
1841
{
1842
    do_rfi();
1843
    RETURN();
1844
}
1845

    
1846
#if defined(TARGET_PPC64)
1847
void OPPROTO op_rfid (void)
1848
{
1849
    do_rfid();
1850
    RETURN();
1851
}
1852
#endif
1853
#endif
1854

    
1855
/* Trap word */
1856
void OPPROTO op_tw (void)
1857
{
1858
    do_tw(PARAM1);
1859
    RETURN();
1860
}
1861

    
1862
#if defined(TARGET_PPC64)
1863
void OPPROTO op_td (void)
1864
{
1865
    do_td(PARAM1);
1866
    RETURN();
1867
}
1868
#endif
1869

    
1870
#if !defined(CONFIG_USER_ONLY)
1871
/* tlbia */
1872
void OPPROTO op_tlbia (void)
1873
{
1874
    do_tlbia();
1875
    RETURN();
1876
}
1877

    
1878
/* tlbie */
1879
void OPPROTO op_tlbie (void)
1880
{
1881
    do_tlbie();
1882
    RETURN();
1883
}
1884

    
1885
#if defined(TARGET_PPC64)
1886
void OPPROTO op_tlbie_64 (void)
1887
{
1888
    do_tlbie_64();
1889
    RETURN();
1890
}
1891
#endif
1892

    
1893
#if defined(TARGET_PPC64)
1894
void OPPROTO op_slbia (void)
1895
{
1896
    do_slbia();
1897
    RETURN();
1898
}
1899

    
1900
void OPPROTO op_slbie (void)
1901
{
1902
    do_slbie();
1903
    RETURN();
1904
}
1905
#endif
1906
#endif
1907

    
1908
/* PowerPC 602/603/755 software TLB load instructions */
1909
#if !defined(CONFIG_USER_ONLY)
1910
void OPPROTO op_6xx_tlbld (void)
1911
{
1912
    do_load_6xx_tlb(0);
1913
    RETURN();
1914
}
1915

    
1916
void OPPROTO op_6xx_tlbli (void)
1917
{
1918
    do_load_6xx_tlb(1);
1919
    RETURN();
1920
}
1921
#endif
1922

    
1923
/* 601 specific */
1924
void OPPROTO op_load_601_rtcl (void)
1925
{
1926
    T0 = cpu_ppc601_load_rtcl(env);
1927
    RETURN();
1928
}
1929

    
1930
void OPPROTO op_load_601_rtcu (void)
1931
{
1932
    T0 = cpu_ppc601_load_rtcu(env);
1933
    RETURN();
1934
}
1935

    
1936
#if !defined(CONFIG_USER_ONLY)
1937
void OPPROTO op_store_601_rtcl (void)
1938
{
1939
    cpu_ppc601_store_rtcl(env, T0);
1940
    RETURN();
1941
}
1942

    
1943
void OPPROTO op_store_601_rtcu (void)
1944
{
1945
    cpu_ppc601_store_rtcu(env, T0);
1946
    RETURN();
1947
}
1948

    
1949
void OPPROTO op_load_601_bat (void)
1950
{
1951
    T0 = env->IBAT[PARAM1][PARAM2];
1952
    RETURN();
1953
}
1954
#endif /* !defined(CONFIG_USER_ONLY) */
1955

    
1956
/* 601 unified BATs store.
1957
 * To avoid using specific MMU code for 601, we store BATs in
1958
 * IBAT and DBAT simultaneously, then emulate unified BATs.
1959
 */
1960
#if !defined(CONFIG_USER_ONLY)
1961
void OPPROTO op_store_601_batl (void)
1962
{
1963
    int nr = PARAM1;
1964

    
1965
    env->IBAT[1][nr] = T0;
1966
    env->DBAT[1][nr] = T0;
1967
    RETURN();
1968
}
1969

    
1970
void OPPROTO op_store_601_batu (void)
1971
{
1972
    do_store_601_batu(PARAM1);
1973
    RETURN();
1974
}
1975
#endif /* !defined(CONFIG_USER_ONLY) */
1976

    
1977
/* PowerPC 601 specific instructions (POWER bridge) */
1978
/* XXX: those micro-ops need tests ! */
1979
void OPPROTO op_POWER_abs (void)
1980
{
1981
    if (T0 == INT32_MIN)
1982
        T0 = INT32_MAX;
1983
    else if (T0 < 0)
1984
        T0 = -T0;
1985
    RETURN();
1986
}
1987

    
1988
void OPPROTO op_POWER_abso (void)
1989
{
1990
    do_POWER_abso();
1991
    RETURN();
1992
}
1993

    
1994
void OPPROTO op_POWER_clcs (void)
1995
{
1996
    do_POWER_clcs();
1997
    RETURN();
1998
}
1999

    
2000
void OPPROTO op_POWER_div (void)
2001
{
2002
    do_POWER_div();
2003
    RETURN();
2004
}
2005

    
2006
void OPPROTO op_POWER_divo (void)
2007
{
2008
    do_POWER_divo();
2009
    RETURN();
2010
}
2011

    
2012
void OPPROTO op_POWER_divs (void)
2013
{
2014
    do_POWER_divs();
2015
    RETURN();
2016
}
2017

    
2018
void OPPROTO op_POWER_divso (void)
2019
{
2020
    do_POWER_divso();
2021
    RETURN();
2022
}
2023

    
2024
void OPPROTO op_POWER_doz (void)
2025
{
2026
    if ((int32_t)T1 > (int32_t)T0)
2027
        T0 = T1 - T0;
2028
    else
2029
        T0 = 0;
2030
    RETURN();
2031
}
2032

    
2033
void OPPROTO op_POWER_dozo (void)
2034
{
2035
    do_POWER_dozo();
2036
    RETURN();
2037
}
2038

    
2039
void OPPROTO op_load_xer_cmp (void)
2040
{
2041
    T2 = xer_cmp;
2042
    RETURN();
2043
}
2044

    
2045
void OPPROTO op_POWER_maskg (void)
2046
{
2047
    do_POWER_maskg();
2048
    RETURN();
2049
}
2050

    
2051
void OPPROTO op_POWER_maskir (void)
2052
{
2053
    T0 = (T0 & ~T2) | (T1 & T2);
2054
    RETURN();
2055
}
2056

    
2057
void OPPROTO op_POWER_mul (void)
2058
{
2059
    uint64_t tmp;
2060

    
2061
    tmp = (uint64_t)T0 * (uint64_t)T1;
2062
    env->spr[SPR_MQ] = tmp >> 32;
2063
    T0 = tmp;
2064
    RETURN();
2065
}
2066

    
2067
void OPPROTO op_POWER_mulo (void)
2068
{
2069
    do_POWER_mulo();
2070
    RETURN();
2071
}
2072

    
2073
void OPPROTO op_POWER_nabs (void)
2074
{
2075
    if (T0 > 0)
2076
        T0 = -T0;
2077
    RETURN();
2078
}
2079

    
2080
void OPPROTO op_POWER_nabso (void)
2081
{
2082
    /* nabs never overflows */
2083
    if (T0 > 0)
2084
        T0 = -T0;
2085
    xer_ov = 0;
2086
    RETURN();
2087
}
2088

    
2089
/* XXX: factorise POWER rotates... */
2090
void OPPROTO op_POWER_rlmi (void)
2091
{
2092
    T0 = rotl32(T0, T2) & PARAM1;
2093
    T0 |= T1 & PARAM2;
2094
    RETURN();
2095
}
2096

    
2097
void OPPROTO op_POWER_rrib (void)
2098
{
2099
    T2 &= 0x1FUL;
2100
    T0 = rotl32(T0 & INT32_MIN, T2);
2101
    T0 |= T1 & ~rotl32(INT32_MIN, T2);
2102
    RETURN();
2103
}
2104

    
2105
void OPPROTO op_POWER_sle (void)
2106
{
2107
    T1 &= 0x1FUL;
2108
    env->spr[SPR_MQ] = rotl32(T0, T1);
2109
    T0 = T0 << T1;
2110
    RETURN();
2111
}
2112

    
2113
void OPPROTO op_POWER_sleq (void)
2114
{
2115
    uint32_t tmp = env->spr[SPR_MQ];
2116

    
2117
    T1 &= 0x1FUL;
2118
    env->spr[SPR_MQ] = rotl32(T0, T1);
2119
    T0 = T0 << T1;
2120
    T0 |= tmp >> (32 - T1);
2121
    RETURN();
2122
}
2123

    
2124
void OPPROTO op_POWER_sllq (void)
2125
{
2126
    uint32_t msk = -1;
2127

    
2128
    msk = msk << (T1 & 0x1FUL);
2129
    if (T1 & 0x20UL)
2130
        msk = ~msk;
2131
    T1 &= 0x1FUL;
2132
    T0 = (T0 << T1) & msk;
2133
    T0 |= env->spr[SPR_MQ] & ~msk;
2134
    RETURN();
2135
}
2136

    
2137
void OPPROTO op_POWER_slq (void)
2138
{
2139
    uint32_t msk = -1, tmp;
2140

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

    
2151
void OPPROTO op_POWER_sraq (void)
2152
{
2153
    env->spr[SPR_MQ] = rotl32(T0, 32 - (T1 & 0x1FUL));
2154
    if (T1 & 0x20UL)
2155
        T0 = -1L;
2156
    else
2157
        T0 = (int32_t)T0 >> T1;
2158
    RETURN();
2159
}
2160

    
2161
void OPPROTO op_POWER_sre (void)
2162
{
2163
    T1 &= 0x1FUL;
2164
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2165
    T0 = (int32_t)T0 >> T1;
2166
    RETURN();
2167
}
2168

    
2169
void OPPROTO op_POWER_srea (void)
2170
{
2171
    T1 &= 0x1FUL;
2172
    env->spr[SPR_MQ] = T0 >> T1;
2173
    T0 = (int32_t)T0 >> T1;
2174
    RETURN();
2175
}
2176

    
2177
void OPPROTO op_POWER_sreq (void)
2178
{
2179
    uint32_t tmp;
2180
    int32_t msk;
2181

    
2182
    T1 &= 0x1FUL;
2183
    msk = INT32_MIN >> T1;
2184
    tmp = env->spr[SPR_MQ];
2185
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2186
    T0 = T0 >> T1;
2187
    T0 |= tmp & msk;
2188
    RETURN();
2189
}
2190

    
2191
void OPPROTO op_POWER_srlq (void)
2192
{
2193
    uint32_t tmp;
2194
    int32_t msk;
2195

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

    
2208
void OPPROTO op_POWER_srq (void)
2209
{
2210
    T1 &= 0x1FUL;
2211
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2212
    T0 = T0 >> T1;
2213
    RETURN();
2214
}
2215

    
2216
/* POWER instructions not implemented in PowerPC 601 */
2217
#if !defined(CONFIG_USER_ONLY)
2218
void OPPROTO op_POWER_mfsri (void)
2219
{
2220
    T1 = T0 >> 28;
2221
    T0 = env->sr[T1];
2222
    RETURN();
2223
}
2224

    
2225
void OPPROTO op_POWER_rac (void)
2226
{
2227
    do_POWER_rac();
2228
    RETURN();
2229
}
2230

    
2231
void OPPROTO op_POWER_rfsvc (void)
2232
{
2233
    do_POWER_rfsvc();
2234
    RETURN();
2235
}
2236
#endif
2237

    
2238
/* PowerPC 602 specific instruction */
2239
#if !defined(CONFIG_USER_ONLY)
2240
void OPPROTO op_602_mfrom (void)
2241
{
2242
    do_op_602_mfrom();
2243
    RETURN();
2244
}
2245
#endif
2246

    
2247
/* PowerPC 4xx specific micro-ops */
2248
void OPPROTO op_405_add_T0_T2 (void)
2249
{
2250
    T0 = (int32_t)T0 + (int32_t)T2;
2251
    RETURN();
2252
}
2253

    
2254
void OPPROTO op_405_mulchw (void)
2255
{
2256
    T0 = ((int16_t)T0) * ((int16_t)(T1 >> 16));
2257
    RETURN();
2258
}
2259

    
2260
void OPPROTO op_405_mulchwu (void)
2261
{
2262
    T0 = ((uint16_t)T0) * ((uint16_t)(T1 >> 16));
2263
    RETURN();
2264
}
2265

    
2266
void OPPROTO op_405_mulhhw (void)
2267
{
2268
    T0 = ((int16_t)(T0 >> 16)) * ((int16_t)(T1 >> 16));
2269
    RETURN();
2270
}
2271

    
2272
void OPPROTO op_405_mulhhwu (void)
2273
{
2274
    T0 = ((uint16_t)(T0 >> 16)) * ((uint16_t)(T1 >> 16));
2275
    RETURN();
2276
}
2277

    
2278
void OPPROTO op_405_mullhw (void)
2279
{
2280
    T0 = ((int16_t)T0) * ((int16_t)T1);
2281
    RETURN();
2282
}
2283

    
2284
void OPPROTO op_405_mullhwu (void)
2285
{
2286
    T0 = ((uint16_t)T0) * ((uint16_t)T1);
2287
    RETURN();
2288
}
2289

    
2290
void OPPROTO op_405_check_ov (void)
2291
{
2292
    do_405_check_ov();
2293
    RETURN();
2294
}
2295

    
2296
void OPPROTO op_405_check_sat (void)
2297
{
2298
    do_405_check_sat();
2299
    RETURN();
2300
}
2301

    
2302
void OPPROTO op_405_check_ovu (void)
2303
{
2304
    if (likely(T0 >= T2)) {
2305
        xer_ov = 0;
2306
    } else {
2307
        xer_ov = 1;
2308
        xer_so = 1;
2309
    }
2310
    RETURN();
2311
}
2312

    
2313
void OPPROTO op_405_check_satu (void)
2314
{
2315
    if (unlikely(T0 < T2)) {
2316
        /* Saturate result */
2317
        T0 = -1;
2318
    }
2319
    RETURN();
2320
}
2321

    
2322
#if !defined(CONFIG_USER_ONLY)
2323
void OPPROTO op_load_dcr (void)
2324
{
2325
    do_load_dcr();
2326
    RETURN();
2327
}
2328

    
2329
void OPPROTO op_store_dcr (void)
2330
{
2331
    do_store_dcr();
2332
    RETURN();
2333
}
2334

    
2335
/* Return from critical interrupt :
2336
 * same as rfi, except nip & MSR are loaded from SRR2/3 instead of SRR0/1
2337
 */
2338
void OPPROTO op_40x_rfci (void)
2339
{
2340
    do_40x_rfci();
2341
    RETURN();
2342
}
2343

    
2344
void OPPROTO op_rfci (void)
2345
{
2346
    do_rfci();
2347
    RETURN();
2348
}
2349

    
2350
void OPPROTO op_rfdi (void)
2351
{
2352
    do_rfdi();
2353
    RETURN();
2354
}
2355

    
2356
void OPPROTO op_rfmci (void)
2357
{
2358
    do_rfmci();
2359
    RETURN();
2360
}
2361

    
2362
void OPPROTO op_wrte (void)
2363
{
2364
    msr_ee = T0 >> 16;
2365
    RETURN();
2366
}
2367

    
2368
void OPPROTO op_4xx_tlbre_lo (void)
2369
{
2370
    do_4xx_tlbre_lo();
2371
    RETURN();
2372
}
2373

    
2374
void OPPROTO op_4xx_tlbre_hi (void)
2375
{
2376
    do_4xx_tlbre_hi();
2377
    RETURN();
2378
}
2379

    
2380
void OPPROTO op_4xx_tlbsx (void)
2381
{
2382
    do_4xx_tlbsx();
2383
    RETURN();
2384
}
2385

    
2386
void OPPROTO op_4xx_tlbsx_ (void)
2387
{
2388
    do_4xx_tlbsx_();
2389
    RETURN();
2390
}
2391

    
2392
void OPPROTO op_4xx_tlbwe_lo (void)
2393
{
2394
    do_4xx_tlbwe_lo();
2395
    RETURN();
2396
}
2397

    
2398
void OPPROTO op_4xx_tlbwe_hi (void)
2399
{
2400
    do_4xx_tlbwe_hi();
2401
    RETURN();
2402
}
2403
#endif
2404

    
2405
/* SPR micro-ops */
2406
/* 440 specific */
2407
void OPPROTO op_440_dlmzb (void)
2408
{
2409
    do_440_dlmzb();
2410
    RETURN();
2411
}
2412

    
2413
void OPPROTO op_440_dlmzb_update_Rc (void)
2414
{
2415
    if (T0 == 8)
2416
        T0 = 0x2;
2417
    else if (T0 < 4)
2418
        T0 = 0x4;
2419
    else
2420
        T0 = 0x8;
2421
    RETURN();
2422
}
2423

    
2424
#if !defined(CONFIG_USER_ONLY)
2425
void OPPROTO op_store_pir (void)
2426
{
2427
    env->spr[SPR_PIR] = T0 & 0x0000000FUL;
2428
    RETURN();
2429
}
2430

    
2431
void OPPROTO op_load_403_pb (void)
2432
{
2433
    do_load_403_pb(PARAM1);
2434
    RETURN();
2435
}
2436

    
2437
void OPPROTO op_store_403_pb (void)
2438
{
2439
    do_store_403_pb(PARAM1);
2440
    RETURN();
2441
}
2442

    
2443
void OPPROTO op_load_40x_pit (void)
2444
{
2445
    T0 = load_40x_pit(env);
2446
    RETURN();
2447
}
2448

    
2449
void OPPROTO op_store_40x_pit (void)
2450
{
2451
    store_40x_pit(env, T0);
2452
    RETURN();
2453
}
2454

    
2455
void OPPROTO op_store_40x_dbcr0 (void)
2456
{
2457
    store_40x_dbcr0(env, T0);
2458
}
2459

    
2460
void OPPROTO op_store_40x_sler (void)
2461
{
2462
    store_40x_sler(env, T0);
2463
    RETURN();
2464
}
2465

    
2466
void OPPROTO op_store_booke_tcr (void)
2467
{
2468
    store_booke_tcr(env, T0);
2469
    RETURN();
2470
}
2471

    
2472
void OPPROTO op_store_booke_tsr (void)
2473
{
2474
    store_booke_tsr(env, T0);
2475
    RETURN();
2476
}
2477

    
2478
#endif /* !defined(CONFIG_USER_ONLY) */
2479

    
2480
#if defined(TARGET_PPCEMB)
2481
/* SPE extension */
2482
void OPPROTO op_splatw_T1_64 (void)
2483
{
2484
    T1_64 = (T1_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL);
2485
    RETURN();
2486
}
2487

    
2488
void OPPROTO op_splatwi_T0_64 (void)
2489
{
2490
    uint64_t tmp = PARAM1;
2491

    
2492
    T0_64 = (tmp << 32) | tmp;
2493
    RETURN();
2494
}
2495

    
2496
void OPPROTO op_splatwi_T1_64 (void)
2497
{
2498
    uint64_t tmp = PARAM1;
2499

    
2500
    T1_64 = (tmp << 32) | tmp;
2501
    RETURN();
2502
}
2503

    
2504
void OPPROTO op_extsh_T1_64 (void)
2505
{
2506
    T1_64 = (int32_t)((int16_t)T1_64);
2507
    RETURN();
2508
}
2509

    
2510
void OPPROTO op_sli16_T1_64 (void)
2511
{
2512
    T1_64 = T1_64 << 16;
2513
    RETURN();
2514
}
2515

    
2516
void OPPROTO op_sli32_T1_64 (void)
2517
{
2518
    T1_64 = T1_64 << 32;
2519
    RETURN();
2520
}
2521

    
2522
void OPPROTO op_srli32_T1_64 (void)
2523
{
2524
    T1_64 = T1_64 >> 32;
2525
    RETURN();
2526
}
2527

    
2528
void OPPROTO op_evsel (void)
2529
{
2530
    do_evsel();
2531
    RETURN();
2532
}
2533

    
2534
void OPPROTO op_evaddw (void)
2535
{
2536
    do_evaddw();
2537
    RETURN();
2538
}
2539

    
2540
void OPPROTO op_evsubfw (void)
2541
{
2542
    do_evsubfw();
2543
    RETURN();
2544
}
2545

    
2546
void OPPROTO op_evneg (void)
2547
{
2548
    do_evneg();
2549
    RETURN();
2550
}
2551

    
2552
void OPPROTO op_evabs (void)
2553
{
2554
    do_evabs();
2555
    RETURN();
2556
}
2557

    
2558
void OPPROTO op_evextsh (void)
2559
{
2560
    T0_64 = ((uint64_t)((int32_t)(int16_t)(T0_64 >> 32)) << 32) |
2561
        (uint64_t)((int32_t)(int16_t)T0_64);
2562
    RETURN();
2563
}
2564

    
2565
void OPPROTO op_evextsb (void)
2566
{
2567
    T0_64 = ((uint64_t)((int32_t)(int8_t)(T0_64 >> 32)) << 32) |
2568
        (uint64_t)((int32_t)(int8_t)T0_64);
2569
    RETURN();
2570
}
2571

    
2572
void OPPROTO op_evcntlzw (void)
2573
{
2574
    do_evcntlzw();
2575
    RETURN();
2576
}
2577

    
2578
void OPPROTO op_evrndw (void)
2579
{
2580
    do_evrndw();
2581
    RETURN();
2582
}
2583

    
2584
void OPPROTO op_brinc (void)
2585
{
2586
    do_brinc();
2587
    RETURN();
2588
}
2589

    
2590
void OPPROTO op_evcntlsw (void)
2591
{
2592
    do_evcntlsw();
2593
    RETURN();
2594
}
2595

    
2596
void OPPROTO op_evand (void)
2597
{
2598
    T0_64 &= T1_64;
2599
    RETURN();
2600
}
2601

    
2602
void OPPROTO op_evandc (void)
2603
{
2604
    T0_64 &= ~T1_64;
2605
    RETURN();
2606
}
2607

    
2608
void OPPROTO op_evor (void)
2609
{
2610
    T0_64 |= T1_64;
2611
    RETURN();
2612
}
2613

    
2614
void OPPROTO op_evxor (void)
2615
{
2616
    T0_64 ^= T1_64;
2617
    RETURN();
2618
}
2619

    
2620
void OPPROTO op_eveqv (void)
2621
{
2622
    T0_64 = ~(T0_64 ^ T1_64);
2623
    RETURN();
2624
}
2625

    
2626
void OPPROTO op_evnor (void)
2627
{
2628
    T0_64 = ~(T0_64 | T1_64);
2629
    RETURN();
2630
}
2631

    
2632
void OPPROTO op_evorc (void)
2633
{
2634
    T0_64 |= ~T1_64;
2635
    RETURN();
2636
}
2637

    
2638
void OPPROTO op_evnand (void)
2639
{
2640
    T0_64 = ~(T0_64 & T1_64);
2641
    RETURN();
2642
}
2643

    
2644
void OPPROTO op_evsrws (void)
2645
{
2646
    do_evsrws();
2647
    RETURN();
2648
}
2649

    
2650
void OPPROTO op_evsrwu (void)
2651
{
2652
    do_evsrwu();
2653
    RETURN();
2654
}
2655

    
2656
void OPPROTO op_evslw (void)
2657
{
2658
    do_evslw();
2659
    RETURN();
2660
}
2661

    
2662
void OPPROTO op_evrlw (void)
2663
{
2664
    do_evrlw();
2665
    RETURN();
2666
}
2667

    
2668
void OPPROTO op_evmergelo (void)
2669
{
2670
    T0_64 = (T0_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL);
2671
    RETURN();
2672
}
2673

    
2674
void OPPROTO op_evmergehi (void)
2675
{
2676
    T0_64 = (T0_64 & 0xFFFFFFFF00000000ULL) | (T1_64 >> 32);
2677
    RETURN();
2678
}
2679

    
2680
void OPPROTO op_evmergelohi (void)
2681
{
2682
    T0_64 = (T0_64 << 32) | (T1_64 >> 32);
2683
    RETURN();
2684
}
2685

    
2686
void OPPROTO op_evmergehilo (void)
2687
{
2688
    T0_64 = (T0_64 & 0xFFFFFFFF00000000ULL) | (T1_64 & 0x00000000FFFFFFFFULL);
2689
    RETURN();
2690
}
2691

    
2692
void OPPROTO op_evcmpgts (void)
2693
{
2694
    do_evcmpgts();
2695
    RETURN();
2696
}
2697

    
2698
void OPPROTO op_evcmpgtu (void)
2699
{
2700
    do_evcmpgtu();
2701
    RETURN();
2702
}
2703

    
2704
void OPPROTO op_evcmplts (void)
2705
{
2706
    do_evcmplts();
2707
    RETURN();
2708
}
2709

    
2710
void OPPROTO op_evcmpltu (void)
2711
{
2712
    do_evcmpltu();
2713
    RETURN();
2714
}
2715

    
2716
void OPPROTO op_evcmpeq (void)
2717
{
2718
    do_evcmpeq();
2719
    RETURN();
2720
}
2721

    
2722
void OPPROTO op_evfssub (void)
2723
{
2724
    do_evfssub();
2725
    RETURN();
2726
}
2727

    
2728
void OPPROTO op_evfsadd (void)
2729
{
2730
    do_evfsadd();
2731
    RETURN();
2732
}
2733

    
2734
void OPPROTO op_evfsnabs (void)
2735
{
2736
    do_evfsnabs();
2737
    RETURN();
2738
}
2739

    
2740
void OPPROTO op_evfsabs (void)
2741
{
2742
    do_evfsabs();
2743
    RETURN();
2744
}
2745

    
2746
void OPPROTO op_evfsneg (void)
2747
{
2748
    do_evfsneg();
2749
    RETURN();
2750
}
2751

    
2752
void OPPROTO op_evfsdiv (void)
2753
{
2754
    do_evfsdiv();
2755
    RETURN();
2756
}
2757

    
2758
void OPPROTO op_evfsmul (void)
2759
{
2760
    do_evfsmul();
2761
    RETURN();
2762
}
2763

    
2764
void OPPROTO op_evfscmplt (void)
2765
{
2766
    do_evfscmplt();
2767
    RETURN();
2768
}
2769

    
2770
void OPPROTO op_evfscmpgt (void)
2771
{
2772
    do_evfscmpgt();
2773
    RETURN();
2774
}
2775

    
2776
void OPPROTO op_evfscmpeq (void)
2777
{
2778
    do_evfscmpeq();
2779
    RETURN();
2780
}
2781

    
2782
void OPPROTO op_evfscfsi (void)
2783
{
2784
    do_evfscfsi();
2785
    RETURN();
2786
}
2787

    
2788
void OPPROTO op_evfscfui (void)
2789
{
2790
    do_evfscfui();
2791
    RETURN();
2792
}
2793

    
2794
void OPPROTO op_evfscfsf (void)
2795
{
2796
    do_evfscfsf();
2797
    RETURN();
2798
}
2799

    
2800
void OPPROTO op_evfscfuf (void)
2801
{
2802
    do_evfscfuf();
2803
    RETURN();
2804
}
2805

    
2806
void OPPROTO op_evfsctsi (void)
2807
{
2808
    do_evfsctsi();
2809
    RETURN();
2810
}
2811

    
2812
void OPPROTO op_evfsctui (void)
2813
{
2814
    do_evfsctui();
2815
    RETURN();
2816
}
2817

    
2818
void OPPROTO op_evfsctsf (void)
2819
{
2820
    do_evfsctsf();
2821
    RETURN();
2822
}
2823

    
2824
void OPPROTO op_evfsctuf (void)
2825
{
2826
    do_evfsctuf();
2827
    RETURN();
2828
}
2829

    
2830
void OPPROTO op_evfsctuiz (void)
2831
{
2832
    do_evfsctuiz();
2833
    RETURN();
2834
}
2835

    
2836
void OPPROTO op_evfsctsiz (void)
2837
{
2838
    do_evfsctsiz();
2839
    RETURN();
2840
}
2841

    
2842
void OPPROTO op_evfststlt (void)
2843
{
2844
    do_evfststlt();
2845
    RETURN();
2846
}
2847

    
2848
void OPPROTO op_evfststgt (void)
2849
{
2850
    do_evfststgt();
2851
    RETURN();
2852
}
2853

    
2854
void OPPROTO op_evfststeq (void)
2855
{
2856
    do_evfststeq();
2857
    RETURN();
2858
}
2859

    
2860
void OPPROTO op_efssub (void)
2861
{
2862
    T0_64 = _do_efssub(T0_64, T1_64);
2863
    RETURN();
2864
}
2865

    
2866
void OPPROTO op_efsadd (void)
2867
{
2868
    T0_64 = _do_efsadd(T0_64, T1_64);
2869
    RETURN();
2870
}
2871

    
2872
void OPPROTO op_efsnabs (void)
2873
{
2874
    T0_64 = _do_efsnabs(T0_64);
2875
    RETURN();
2876
}
2877

    
2878
void OPPROTO op_efsabs (void)
2879
{
2880
    T0_64 = _do_efsabs(T0_64);
2881
    RETURN();
2882
}
2883

    
2884
void OPPROTO op_efsneg (void)
2885
{
2886
    T0_64 = _do_efsneg(T0_64);
2887
    RETURN();
2888
}
2889

    
2890
void OPPROTO op_efsdiv (void)
2891
{
2892
    T0_64 = _do_efsdiv(T0_64, T1_64);
2893
    RETURN();
2894
}
2895

    
2896
void OPPROTO op_efsmul (void)
2897
{
2898
    T0_64 = _do_efsmul(T0_64, T1_64);
2899
    RETURN();
2900
}
2901

    
2902
void OPPROTO op_efscmplt (void)
2903
{
2904
    do_efscmplt();
2905
    RETURN();
2906
}
2907

    
2908
void OPPROTO op_efscmpgt (void)
2909
{
2910
    do_efscmpgt();
2911
    RETURN();
2912
}
2913

    
2914
void OPPROTO op_efscfd (void)
2915
{
2916
    do_efscfd();
2917
    RETURN();
2918
}
2919

    
2920
void OPPROTO op_efscmpeq (void)
2921
{
2922
    do_efscmpeq();
2923
    RETURN();
2924
}
2925

    
2926
void OPPROTO op_efscfsi (void)
2927
{
2928
    do_efscfsi();
2929
    RETURN();
2930
}
2931

    
2932
void OPPROTO op_efscfui (void)
2933
{
2934
    do_efscfui();
2935
    RETURN();
2936
}
2937

    
2938
void OPPROTO op_efscfsf (void)
2939
{
2940
    do_efscfsf();
2941
    RETURN();
2942
}
2943

    
2944
void OPPROTO op_efscfuf (void)
2945
{
2946
    do_efscfuf();
2947
    RETURN();
2948
}
2949

    
2950
void OPPROTO op_efsctsi (void)
2951
{
2952
    do_efsctsi();
2953
    RETURN();
2954
}
2955

    
2956
void OPPROTO op_efsctui (void)
2957
{
2958
    do_efsctui();
2959
    RETURN();
2960
}
2961

    
2962
void OPPROTO op_efsctsf (void)
2963
{
2964
    do_efsctsf();
2965
    RETURN();
2966
}
2967

    
2968
void OPPROTO op_efsctuf (void)
2969
{
2970
    do_efsctuf();
2971
    RETURN();
2972
}
2973

    
2974
void OPPROTO op_efsctsiz (void)
2975
{
2976
    do_efsctsiz();
2977
    RETURN();
2978
}
2979

    
2980
void OPPROTO op_efsctuiz (void)
2981
{
2982
    do_efsctuiz();
2983
    RETURN();
2984
}
2985

    
2986
void OPPROTO op_efststlt (void)
2987
{
2988
    T0 = _do_efststlt(T0_64, T1_64);
2989
    RETURN();
2990
}
2991

    
2992
void OPPROTO op_efststgt (void)
2993
{
2994
    T0 = _do_efststgt(T0_64, T1_64);
2995
    RETURN();
2996
}
2997

    
2998
void OPPROTO op_efststeq (void)
2999
{
3000
    T0 = _do_efststeq(T0_64, T1_64);
3001
    RETURN();
3002
}
3003

    
3004
void OPPROTO op_efdsub (void)
3005
{
3006
    union {
3007
        uint64_t u;
3008
        float64 f;
3009
    } u1, u2;
3010
    u1.u = T0_64;
3011
    u2.u = T1_64;
3012
    u1.f = float64_sub(u1.f, u2.f, &env->spe_status);
3013
    T0_64 = u1.u;
3014
    RETURN();
3015
}
3016

    
3017
void OPPROTO op_efdadd (void)
3018
{
3019
    union {
3020
        uint64_t u;
3021
        float64 f;
3022
    } u1, u2;
3023
    u1.u = T0_64;
3024
    u2.u = T1_64;
3025
    u1.f = float64_add(u1.f, u2.f, &env->spe_status);
3026
    T0_64 = u1.u;
3027
    RETURN();
3028
}
3029

    
3030
void OPPROTO op_efdcfsid (void)
3031
{
3032
    do_efdcfsi();
3033
    RETURN();
3034
}
3035

    
3036
void OPPROTO op_efdcfuid (void)
3037
{
3038
    do_efdcfui();
3039
    RETURN();
3040
}
3041

    
3042
void OPPROTO op_efdnabs (void)
3043
{
3044
    T0_64 |= 0x8000000000000000ULL;
3045
    RETURN();
3046
}
3047

    
3048
void OPPROTO op_efdabs (void)
3049
{
3050
    T0_64 &= ~0x8000000000000000ULL;
3051
    RETURN();
3052
}
3053

    
3054
void OPPROTO op_efdneg (void)
3055
{
3056
    T0_64 ^= 0x8000000000000000ULL;
3057
    RETURN();
3058
}
3059

    
3060
void OPPROTO op_efddiv (void)
3061
{
3062
    union {
3063
        uint64_t u;
3064
        float64 f;
3065
    } u1, u2;
3066
    u1.u = T0_64;
3067
    u2.u = T1_64;
3068
    u1.f = float64_div(u1.f, u2.f, &env->spe_status);
3069
    T0_64 = u1.u;
3070
    RETURN();
3071
}
3072

    
3073
void OPPROTO op_efdmul (void)
3074
{
3075
    union {
3076
        uint64_t u;
3077
        float64 f;
3078
    } u1, u2;
3079
    u1.u = T0_64;
3080
    u2.u = T1_64;
3081
    u1.f = float64_mul(u1.f, u2.f, &env->spe_status);
3082
    T0_64 = u1.u;
3083
    RETURN();
3084
}
3085

    
3086
void OPPROTO op_efdctsidz (void)
3087
{
3088
    do_efdctsiz();
3089
    RETURN();
3090
}
3091

    
3092
void OPPROTO op_efdctuidz (void)
3093
{
3094
    do_efdctuiz();
3095
    RETURN();
3096
}
3097

    
3098
void OPPROTO op_efdcmplt (void)
3099
{
3100
    do_efdcmplt();
3101
    RETURN();
3102
}
3103

    
3104
void OPPROTO op_efdcmpgt (void)
3105
{
3106
    do_efdcmpgt();
3107
    RETURN();
3108
}
3109

    
3110
void OPPROTO op_efdcfs (void)
3111
{
3112
    do_efdcfs();
3113
    RETURN();
3114
}
3115

    
3116
void OPPROTO op_efdcmpeq (void)
3117
{
3118
    do_efdcmpeq();
3119
    RETURN();
3120
}
3121

    
3122
void OPPROTO op_efdcfsi (void)
3123
{
3124
    do_efdcfsi();
3125
    RETURN();
3126
}
3127

    
3128
void OPPROTO op_efdcfui (void)
3129
{
3130
    do_efdcfui();
3131
    RETURN();
3132
}
3133

    
3134
void OPPROTO op_efdcfsf (void)
3135
{
3136
    do_efdcfsf();
3137
    RETURN();
3138
}
3139

    
3140
void OPPROTO op_efdcfuf (void)
3141
{
3142
    do_efdcfuf();
3143
    RETURN();
3144
}
3145

    
3146
void OPPROTO op_efdctsi (void)
3147
{
3148
    do_efdctsi();
3149
    RETURN();
3150
}
3151

    
3152
void OPPROTO op_efdctui (void)
3153
{
3154
    do_efdctui();
3155
    RETURN();
3156
}
3157

    
3158
void OPPROTO op_efdctsf (void)
3159
{
3160
    do_efdctsf();
3161
    RETURN();
3162
}
3163

    
3164
void OPPROTO op_efdctuf (void)
3165
{
3166
    do_efdctuf();
3167
    RETURN();
3168
}
3169

    
3170
void OPPROTO op_efdctuiz (void)
3171
{
3172
    do_efdctuiz();
3173
    RETURN();
3174
}
3175

    
3176
void OPPROTO op_efdctsiz (void)
3177
{
3178
    do_efdctsiz();
3179
    RETURN();
3180
}
3181

    
3182
void OPPROTO op_efdtstlt (void)
3183
{
3184
    T0 = _do_efdtstlt(T0_64, T1_64);
3185
    RETURN();
3186
}
3187

    
3188
void OPPROTO op_efdtstgt (void)
3189
{
3190
    T0 = _do_efdtstgt(T0_64, T1_64);
3191
    RETURN();
3192
}
3193

    
3194
void OPPROTO op_efdtsteq (void)
3195
{
3196
    T0 = _do_efdtsteq(T0_64, T1_64);
3197
    RETURN();
3198
}
3199
#endif /* defined(TARGET_PPCEMB) */