Statistics
| Branch: | Revision:

root / target-ppc / op.c @ 36081602

History | View | Annotate | Download (46.6 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_ov;
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_so = 1;
735
        xer_ov = 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_so = 1;
748
        xer_ov = 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_so = 1;
1032
        xer_ov = 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_so = 1;
1045
        xer_ov = 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
    RETURN();
1200
}
1201

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

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

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

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

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

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

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

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

    
1306
void OPPROTO op_popcntb (void)
1307
{
1308
    do_popcntb();
1309
    RETURN();
1310
}
1311

    
1312
#if defined(TARGET_PPC64)
1313
void OPPROTO op_popcntb_64 (void)
1314
{
1315
    do_popcntb_64();
1316
    RETURN();
1317
}
1318
#endif
1319

    
1320
/***                            Integer logical                            ***/
1321
/* and */
1322
void OPPROTO op_and (void)
1323
{
1324
    T0 &= T1;
1325
    RETURN();
1326
}
1327

    
1328
/* andc */
1329
void OPPROTO op_andc (void)
1330
{
1331
    T0 &= ~T1;
1332
    RETURN();
1333
}
1334

    
1335
/* andi. */
1336
void OPPROTO op_andi_T0 (void)
1337
{
1338
    T0 &= PARAM1;
1339
    RETURN();
1340
}
1341

    
1342
void OPPROTO op_andi_T1 (void)
1343
{
1344
    T1 &= PARAM1;
1345
    RETURN();
1346
}
1347

    
1348
/* count leading zero */
1349
void OPPROTO op_cntlzw (void)
1350
{
1351
    T0 = _do_cntlzw(T0);
1352
    RETURN();
1353
}
1354

    
1355
#if defined(TARGET_PPC64)
1356
void OPPROTO op_cntlzd (void)
1357
{
1358
    T0 = _do_cntlzd(T0);
1359
    RETURN();
1360
}
1361
#endif
1362

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1579
void OPPROTO op_srl_T0_T1 (void)
1580
{
1581
    T0 = (uint32_t)T0 >> T1;
1582
    RETURN();
1583
}
1584

    
1585
#if defined(TARGET_PPC64)
1586
void OPPROTO op_srl_T0_T1_64 (void)
1587
{
1588
    T0 = (uint32_t)T0 >> T1;
1589
    RETURN();
1590
}
1591
#endif
1592

    
1593
void OPPROTO op_srli_T0 (void)
1594
{
1595
    T0 = (uint32_t)T0 >> PARAM1;
1596
    RETURN();
1597
}
1598

    
1599
#if defined(TARGET_PPC64)
1600
void OPPROTO op_srli_T0_64 (void)
1601
{
1602
    T0 = (uint64_t)T0 >> PARAM1;
1603
    RETURN();
1604
}
1605
#endif
1606

    
1607
void OPPROTO op_srli_T1 (void)
1608
{
1609
    T1 = (uint32_t)T1 >> PARAM1;
1610
    RETURN();
1611
}
1612

    
1613
#if defined(TARGET_PPC64)
1614
void OPPROTO op_srli_T1_64 (void)
1615
{
1616
    T1 = (uint64_t)T1 >> PARAM1;
1617
    RETURN();
1618
}
1619
#endif
1620

    
1621
/***                       Floating-Point arithmetic                       ***/
1622
/* fadd - fadd. */
1623
void OPPROTO op_fadd (void)
1624
{
1625
    FT0 = float64_add(FT0, FT1, &env->fp_status);
1626
    RETURN();
1627
}
1628

    
1629
/* fsub - fsub. */
1630
void OPPROTO op_fsub (void)
1631
{
1632
    FT0 = float64_sub(FT0, FT1, &env->fp_status);
1633
    RETURN();
1634
}
1635

    
1636
/* fmul - fmul. */
1637
void OPPROTO op_fmul (void)
1638
{
1639
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1640
    RETURN();
1641
}
1642

    
1643
/* fdiv - fdiv. */
1644
void OPPROTO op_fdiv (void)
1645
{
1646
    FT0 = float64_div(FT0, FT1, &env->fp_status);
1647
    RETURN();
1648
}
1649

    
1650
/* fsqrt - fsqrt. */
1651
void OPPROTO op_fsqrt (void)
1652
{
1653
    do_fsqrt();
1654
    RETURN();
1655
}
1656

    
1657
/* fres - fres. */
1658
void OPPROTO op_fres (void)
1659
{
1660
    do_fres();
1661
    RETURN();
1662
}
1663

    
1664
/* frsqrte  - frsqrte. */
1665
void OPPROTO op_frsqrte (void)
1666
{
1667
    do_frsqrte();
1668
    RETURN();
1669
}
1670

    
1671
/* fsel - fsel. */
1672
void OPPROTO op_fsel (void)
1673
{
1674
    do_fsel();
1675
    RETURN();
1676
}
1677

    
1678
/***                     Floating-Point multiply-and-add                   ***/
1679
/* fmadd - fmadd. */
1680
void OPPROTO op_fmadd (void)
1681
{
1682
#if USE_PRECISE_EMULATION
1683
    do_fmadd();
1684
#else
1685
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1686
    FT0 = float64_add(FT0, FT2, &env->fp_status);
1687
#endif
1688
    RETURN();
1689
}
1690

    
1691
/* fmsub - fmsub. */
1692
void OPPROTO op_fmsub (void)
1693
{
1694
#if USE_PRECISE_EMULATION
1695
    do_fmsub();
1696
#else
1697
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1698
    FT0 = float64_sub(FT0, FT2, &env->fp_status);
1699
#endif
1700
    RETURN();
1701
}
1702

    
1703
/* fnmadd - fnmadd. - fnmadds - fnmadds. */
1704
void OPPROTO op_fnmadd (void)
1705
{
1706
    do_fnmadd();
1707
    RETURN();
1708
}
1709

    
1710
/* fnmsub - fnmsub. */
1711
void OPPROTO op_fnmsub (void)
1712
{
1713
    do_fnmsub();
1714
    RETURN();
1715
}
1716

    
1717
/***                     Floating-Point round & convert                    ***/
1718
/* frsp - frsp. */
1719
void OPPROTO op_frsp (void)
1720
{
1721
    FT0 = float64_to_float32(FT0, &env->fp_status);
1722
    RETURN();
1723
}
1724

    
1725
/* fctiw - fctiw. */
1726
void OPPROTO op_fctiw (void)
1727
{
1728
    do_fctiw();
1729
    RETURN();
1730
}
1731

    
1732
/* fctiwz - fctiwz. */
1733
void OPPROTO op_fctiwz (void)
1734
{
1735
    do_fctiwz();
1736
    RETURN();
1737
}
1738

    
1739
#if defined(TARGET_PPC64)
1740
/* fcfid - fcfid. */
1741
void OPPROTO op_fcfid (void)
1742
{
1743
    do_fcfid();
1744
    RETURN();
1745
}
1746

    
1747
/* fctid - fctid. */
1748
void OPPROTO op_fctid (void)
1749
{
1750
    do_fctid();
1751
    RETURN();
1752
}
1753

    
1754
/* fctidz - fctidz. */
1755
void OPPROTO op_fctidz (void)
1756
{
1757
    do_fctidz();
1758
    RETURN();
1759
}
1760
#endif
1761

    
1762
/***                         Floating-Point compare                        ***/
1763
/* fcmpu */
1764
void OPPROTO op_fcmpu (void)
1765
{
1766
    do_fcmpu();
1767
    RETURN();
1768
}
1769

    
1770
/* fcmpo */
1771
void OPPROTO op_fcmpo (void)
1772
{
1773
    do_fcmpo();
1774
    RETURN();
1775
}
1776

    
1777
/***                         Floating-point move                           ***/
1778
/* fabs */
1779
void OPPROTO op_fabs (void)
1780
{
1781
    FT0 = float64_abs(FT0);
1782
    RETURN();
1783
}
1784

    
1785
/* fnabs */
1786
void OPPROTO op_fnabs (void)
1787
{
1788
    FT0 = float64_abs(FT0);
1789
    FT0 = float64_chs(FT0);
1790
    RETURN();
1791
}
1792

    
1793
/* fneg */
1794
void OPPROTO op_fneg (void)
1795
{
1796
    FT0 = float64_chs(FT0);
1797
    RETURN();
1798
}
1799

    
1800
/* Load and store */
1801
#define MEMSUFFIX _raw
1802
#include "op_helper.h"
1803
#include "op_mem.h"
1804
#if !defined(CONFIG_USER_ONLY)
1805
#define MEMSUFFIX _user
1806
#include "op_helper.h"
1807
#include "op_mem.h"
1808
#define MEMSUFFIX _kernel
1809
#include "op_helper.h"
1810
#include "op_mem.h"
1811
#endif
1812

    
1813
/* Special op to check and maybe clear reservation */
1814
void OPPROTO op_check_reservation (void)
1815
{
1816
    if ((uint32_t)env->reserve == (uint32_t)(T0 & ~0x00000003))
1817
        env->reserve = -1;
1818
    RETURN();
1819
}
1820

    
1821
#if defined(TARGET_PPC64)
1822
void OPPROTO op_check_reservation_64 (void)
1823
{
1824
    if ((uint64_t)env->reserve == (uint64_t)(T0 & ~0x00000003))
1825
        env->reserve = -1;
1826
    RETURN();
1827
}
1828
#endif
1829

    
1830
/* Return from interrupt */
1831
#if !defined(CONFIG_USER_ONLY)
1832
void OPPROTO op_rfi (void)
1833
{
1834
    do_rfi();
1835
    RETURN();
1836
}
1837

    
1838
#if defined(TARGET_PPC64)
1839
void OPPROTO op_rfid (void)
1840
{
1841
    do_rfid();
1842
    RETURN();
1843
}
1844
#endif
1845
#endif
1846

    
1847
/* Trap word */
1848
void OPPROTO op_tw (void)
1849
{
1850
    do_tw(PARAM1);
1851
    RETURN();
1852
}
1853

    
1854
#if defined(TARGET_PPC64)
1855
void OPPROTO op_td (void)
1856
{
1857
    do_td(PARAM1);
1858
    RETURN();
1859
}
1860
#endif
1861

    
1862
#if !defined(CONFIG_USER_ONLY)
1863
/* tlbia */
1864
void OPPROTO op_tlbia (void)
1865
{
1866
    do_tlbia();
1867
    RETURN();
1868
}
1869

    
1870
/* tlbie */
1871
void OPPROTO op_tlbie (void)
1872
{
1873
    do_tlbie();
1874
    RETURN();
1875
}
1876

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

    
1885
#if defined(TARGET_PPC64)
1886
void OPPROTO op_slbia (void)
1887
{
1888
    do_slbia();
1889
    RETURN();
1890
}
1891

    
1892
void OPPROTO op_slbie (void)
1893
{
1894
    do_slbie();
1895
    RETURN();
1896
}
1897
#endif
1898
#endif
1899

    
1900
/* PowerPC 602/603/755 software TLB load instructions */
1901
#if !defined(CONFIG_USER_ONLY)
1902
void OPPROTO op_6xx_tlbld (void)
1903
{
1904
    do_load_6xx_tlb(0);
1905
    RETURN();
1906
}
1907

    
1908
void OPPROTO op_6xx_tlbli (void)
1909
{
1910
    do_load_6xx_tlb(1);
1911
    RETURN();
1912
}
1913
#endif
1914

    
1915
/* 601 specific */
1916
void OPPROTO op_load_601_rtcl (void)
1917
{
1918
    T0 = cpu_ppc601_load_rtcl(env);
1919
    RETURN();
1920
}
1921

    
1922
void OPPROTO op_load_601_rtcu (void)
1923
{
1924
    T0 = cpu_ppc601_load_rtcu(env);
1925
    RETURN();
1926
}
1927

    
1928
#if !defined(CONFIG_USER_ONLY)
1929
void OPPROTO op_store_601_rtcl (void)
1930
{
1931
    cpu_ppc601_store_rtcl(env, T0);
1932
    RETURN();
1933
}
1934

    
1935
void OPPROTO op_store_601_rtcu (void)
1936
{
1937
    cpu_ppc601_store_rtcu(env, T0);
1938
    RETURN();
1939
}
1940

    
1941
void OPPROTO op_load_601_bat (void)
1942
{
1943
    T0 = env->IBAT[PARAM1][PARAM2];
1944
    RETURN();
1945
}
1946
#endif /* !defined(CONFIG_USER_ONLY) */
1947

    
1948
/* 601 unified BATs store.
1949
 * To avoid using specific MMU code for 601, we store BATs in
1950
 * IBAT and DBAT simultaneously, then emulate unified BATs.
1951
 */
1952
#if !defined(CONFIG_USER_ONLY)
1953
void OPPROTO op_store_601_batl (void)
1954
{
1955
    int nr = PARAM1;
1956

    
1957
    env->IBAT[1][nr] = T0;
1958
    env->DBAT[1][nr] = T0;
1959
    RETURN();
1960
}
1961

    
1962
void OPPROTO op_store_601_batu (void)
1963
{
1964
    do_store_601_batu(PARAM1);
1965
    RETURN();
1966
}
1967
#endif /* !defined(CONFIG_USER_ONLY) */
1968

    
1969
/* PowerPC 601 specific instructions (POWER bridge) */
1970
/* XXX: those micro-ops need tests ! */
1971
void OPPROTO op_POWER_abs (void)
1972
{
1973
    if (T0 == INT32_MIN)
1974
        T0 = INT32_MAX;
1975
    else if (T0 < 0)
1976
        T0 = -T0;
1977
    RETURN();
1978
}
1979

    
1980
void OPPROTO op_POWER_abso (void)
1981
{
1982
    do_POWER_abso();
1983
    RETURN();
1984
}
1985

    
1986
void OPPROTO op_POWER_clcs (void)
1987
{
1988
    do_POWER_clcs();
1989
    RETURN();
1990
}
1991

    
1992
void OPPROTO op_POWER_div (void)
1993
{
1994
    do_POWER_div();
1995
    RETURN();
1996
}
1997

    
1998
void OPPROTO op_POWER_divo (void)
1999
{
2000
    do_POWER_divo();
2001
    RETURN();
2002
}
2003

    
2004
void OPPROTO op_POWER_divs (void)
2005
{
2006
    do_POWER_divs();
2007
    RETURN();
2008
}
2009

    
2010
void OPPROTO op_POWER_divso (void)
2011
{
2012
    do_POWER_divso();
2013
    RETURN();
2014
}
2015

    
2016
void OPPROTO op_POWER_doz (void)
2017
{
2018
    if ((int32_t)T1 > (int32_t)T0)
2019
        T0 = T1 - T0;
2020
    else
2021
        T0 = 0;
2022
    RETURN();
2023
}
2024

    
2025
void OPPROTO op_POWER_dozo (void)
2026
{
2027
    do_POWER_dozo();
2028
    RETURN();
2029
}
2030

    
2031
void OPPROTO op_load_xer_cmp (void)
2032
{
2033
    T2 = xer_cmp;
2034
    RETURN();
2035
}
2036

    
2037
void OPPROTO op_POWER_maskg (void)
2038
{
2039
    do_POWER_maskg();
2040
    RETURN();
2041
}
2042

    
2043
void OPPROTO op_POWER_maskir (void)
2044
{
2045
    T0 = (T0 & ~T2) | (T1 & T2);
2046
    RETURN();
2047
}
2048

    
2049
void OPPROTO op_POWER_mul (void)
2050
{
2051
    uint64_t tmp;
2052

    
2053
    tmp = (uint64_t)T0 * (uint64_t)T1;
2054
    env->spr[SPR_MQ] = tmp >> 32;
2055
    T0 = tmp;
2056
    RETURN();
2057
}
2058

    
2059
void OPPROTO op_POWER_mulo (void)
2060
{
2061
    do_POWER_mulo();
2062
    RETURN();
2063
}
2064

    
2065
void OPPROTO op_POWER_nabs (void)
2066
{
2067
    if (T0 > 0)
2068
        T0 = -T0;
2069
    RETURN();
2070
}
2071

    
2072
void OPPROTO op_POWER_nabso (void)
2073
{
2074
    /* nabs never overflows */
2075
    if (T0 > 0)
2076
        T0 = -T0;
2077
    xer_ov = 0;
2078
    RETURN();
2079
}
2080

    
2081
/* XXX: factorise POWER rotates... */
2082
void OPPROTO op_POWER_rlmi (void)
2083
{
2084
    T0 = rotl32(T0, T2) & PARAM1;
2085
    T0 |= T1 & PARAM2;
2086
    RETURN();
2087
}
2088

    
2089
void OPPROTO op_POWER_rrib (void)
2090
{
2091
    T2 &= 0x1FUL;
2092
    T0 = rotl32(T0 & INT32_MIN, T2);
2093
    T0 |= T1 & ~rotl32(INT32_MIN, T2);
2094
    RETURN();
2095
}
2096

    
2097
void OPPROTO op_POWER_sle (void)
2098
{
2099
    T1 &= 0x1FUL;
2100
    env->spr[SPR_MQ] = rotl32(T0, T1);
2101
    T0 = T0 << T1;
2102
    RETURN();
2103
}
2104

    
2105
void OPPROTO op_POWER_sleq (void)
2106
{
2107
    uint32_t tmp = env->spr[SPR_MQ];
2108

    
2109
    T1 &= 0x1FUL;
2110
    env->spr[SPR_MQ] = rotl32(T0, T1);
2111
    T0 = T0 << T1;
2112
    T0 |= tmp >> (32 - T1);
2113
    RETURN();
2114
}
2115

    
2116
void OPPROTO op_POWER_sllq (void)
2117
{
2118
    uint32_t msk = -1;
2119

    
2120
    msk = msk << (T1 & 0x1FUL);
2121
    if (T1 & 0x20UL)
2122
        msk = ~msk;
2123
    T1 &= 0x1FUL;
2124
    T0 = (T0 << T1) & msk;
2125
    T0 |= env->spr[SPR_MQ] & ~msk;
2126
    RETURN();
2127
}
2128

    
2129
void OPPROTO op_POWER_slq (void)
2130
{
2131
    uint32_t msk = -1, tmp;
2132

    
2133
    msk = msk << (T1 & 0x1FUL);
2134
    if (T1 & 0x20UL)
2135
        msk = ~msk;
2136
    T1 &= 0x1FUL;
2137
    tmp = rotl32(T0, T1);
2138
    T0 = tmp & msk;
2139
    env->spr[SPR_MQ] = tmp;
2140
    RETURN();
2141
}
2142

    
2143
void OPPROTO op_POWER_sraq (void)
2144
{
2145
    env->spr[SPR_MQ] = rotl32(T0, 32 - (T1 & 0x1FUL));
2146
    if (T1 & 0x20UL)
2147
        T0 = -1L;
2148
    else
2149
        T0 = (int32_t)T0 >> T1;
2150
    RETURN();
2151
}
2152

    
2153
void OPPROTO op_POWER_sre (void)
2154
{
2155
    T1 &= 0x1FUL;
2156
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2157
    T0 = (int32_t)T0 >> T1;
2158
    RETURN();
2159
}
2160

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

    
2169
void OPPROTO op_POWER_sreq (void)
2170
{
2171
    uint32_t tmp;
2172
    int32_t msk;
2173

    
2174
    T1 &= 0x1FUL;
2175
    msk = INT32_MIN >> T1;
2176
    tmp = env->spr[SPR_MQ];
2177
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2178
    T0 = T0 >> T1;
2179
    T0 |= tmp & msk;
2180
    RETURN();
2181
}
2182

    
2183
void OPPROTO op_POWER_srlq (void)
2184
{
2185
    uint32_t tmp;
2186
    int32_t msk;
2187

    
2188
    msk = INT32_MIN >> (T1 & 0x1FUL);
2189
    if (T1 & 0x20UL)
2190
        msk = ~msk;
2191
    T1 &= 0x1FUL;
2192
    tmp = env->spr[SPR_MQ];
2193
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2194
    T0 = T0 >> T1;
2195
    T0 &= msk;
2196
    T0 |= tmp & ~msk;
2197
    RETURN();
2198
}
2199

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

    
2208
/* POWER instructions not implemented in PowerPC 601 */
2209
#if !defined(CONFIG_USER_ONLY)
2210
void OPPROTO op_POWER_mfsri (void)
2211
{
2212
    T1 = T0 >> 28;
2213
    T0 = env->sr[T1];
2214
    RETURN();
2215
}
2216

    
2217
void OPPROTO op_POWER_rac (void)
2218
{
2219
    do_POWER_rac();
2220
    RETURN();
2221
}
2222

    
2223
void OPPROTO op_POWER_rfsvc (void)
2224
{
2225
    do_POWER_rfsvc();
2226
    RETURN();
2227
}
2228
#endif
2229

    
2230
/* PowerPC 602 specific instruction */
2231
#if !defined(CONFIG_USER_ONLY)
2232
void OPPROTO op_602_mfrom (void)
2233
{
2234
    do_op_602_mfrom();
2235
    RETURN();
2236
}
2237
#endif
2238

    
2239
/* PowerPC 4xx specific micro-ops */
2240
void OPPROTO op_405_add_T0_T2 (void)
2241
{
2242
    T0 = (int32_t)T0 + (int32_t)T2;
2243
    RETURN();
2244
}
2245

    
2246
void OPPROTO op_405_mulchw (void)
2247
{
2248
    T0 = ((int16_t)T0) * ((int16_t)(T1 >> 16));
2249
    RETURN();
2250
}
2251

    
2252
void OPPROTO op_405_mulchwu (void)
2253
{
2254
    T0 = ((uint16_t)T0) * ((uint16_t)(T1 >> 16));
2255
    RETURN();
2256
}
2257

    
2258
void OPPROTO op_405_mulhhw (void)
2259
{
2260
    T0 = ((int16_t)(T0 >> 16)) * ((int16_t)(T1 >> 16));
2261
    RETURN();
2262
}
2263

    
2264
void OPPROTO op_405_mulhhwu (void)
2265
{
2266
    T0 = ((uint16_t)(T0 >> 16)) * ((uint16_t)(T1 >> 16));
2267
    RETURN();
2268
}
2269

    
2270
void OPPROTO op_405_mullhw (void)
2271
{
2272
    T0 = ((int16_t)T0) * ((int16_t)T1);
2273
    RETURN();
2274
}
2275

    
2276
void OPPROTO op_405_mullhwu (void)
2277
{
2278
    T0 = ((uint16_t)T0) * ((uint16_t)T1);
2279
    RETURN();
2280
}
2281

    
2282
void OPPROTO op_405_check_ov (void)
2283
{
2284
    do_405_check_ov();
2285
    RETURN();
2286
}
2287

    
2288
void OPPROTO op_405_check_sat (void)
2289
{
2290
    do_405_check_sat();
2291
    RETURN();
2292
}
2293

    
2294
void OPPROTO op_405_check_ovu (void)
2295
{
2296
    if (likely(T0 >= T2)) {
2297
        xer_ov = 0;
2298
    } else {
2299
        xer_ov = 1;
2300
        xer_so = 1;
2301
    }
2302
    RETURN();
2303
}
2304

    
2305
void OPPROTO op_405_check_satu (void)
2306
{
2307
    if (unlikely(T0 < T2)) {
2308
        /* Saturate result */
2309
        T0 = -1;
2310
    }
2311
    RETURN();
2312
}
2313

    
2314
#if !defined(CONFIG_USER_ONLY)
2315
void OPPROTO op_load_dcr (void)
2316
{
2317
    do_load_dcr();
2318
    RETURN();
2319
}
2320

    
2321
void OPPROTO op_store_dcr (void)
2322
{
2323
    do_store_dcr();
2324
    RETURN();
2325
}
2326

    
2327
/* Return from critical interrupt :
2328
 * same as rfi, except nip & MSR are loaded from SRR2/3 instead of SRR0/1
2329
 */
2330
void OPPROTO op_40x_rfci (void)
2331
{
2332
    do_40x_rfci();
2333
    RETURN();
2334
}
2335

    
2336
void OPPROTO op_rfci (void)
2337
{
2338
    do_rfci();
2339
    RETURN();
2340
}
2341

    
2342
void OPPROTO op_rfdi (void)
2343
{
2344
    do_rfdi();
2345
    RETURN();
2346
}
2347

    
2348
void OPPROTO op_rfmci (void)
2349
{
2350
    do_rfmci();
2351
    RETURN();
2352
}
2353

    
2354
void OPPROTO op_wrte (void)
2355
{
2356
    msr_ee = T0 >> 16;
2357
    RETURN();
2358
}
2359

    
2360
void OPPROTO op_4xx_tlbre_lo (void)
2361
{
2362
    do_4xx_tlbre_lo();
2363
    RETURN();
2364
}
2365

    
2366
void OPPROTO op_4xx_tlbre_hi (void)
2367
{
2368
    do_4xx_tlbre_hi();
2369
    RETURN();
2370
}
2371

    
2372
void OPPROTO op_4xx_tlbsx (void)
2373
{
2374
    do_4xx_tlbsx();
2375
    RETURN();
2376
}
2377

    
2378
void OPPROTO op_4xx_tlbsx_ (void)
2379
{
2380
    do_4xx_tlbsx_();
2381
    RETURN();
2382
}
2383

    
2384
void OPPROTO op_4xx_tlbwe_lo (void)
2385
{
2386
    do_4xx_tlbwe_lo();
2387
    RETURN();
2388
}
2389

    
2390
void OPPROTO op_4xx_tlbwe_hi (void)
2391
{
2392
    do_4xx_tlbwe_hi();
2393
    RETURN();
2394
}
2395
#endif
2396

    
2397
/* SPR micro-ops */
2398
/* 440 specific */
2399
void OPPROTO op_440_dlmzb (void)
2400
{
2401
    do_440_dlmzb();
2402
    RETURN();
2403
}
2404

    
2405
void OPPROTO op_440_dlmzb_update_Rc (void)
2406
{
2407
    if (T0 == 8)
2408
        T0 = 0x2;
2409
    else if (T0 < 4)
2410
        T0 = 0x4;
2411
    else
2412
        T0 = 0x8;
2413
    RETURN();
2414
}
2415

    
2416
#if !defined(CONFIG_USER_ONLY)
2417
void OPPROTO op_store_pir (void)
2418
{
2419
    env->spr[SPR_PIR] = T0 & 0x0000000FUL;
2420
    RETURN();
2421
}
2422

    
2423
void OPPROTO op_load_403_pb (void)
2424
{
2425
    do_load_403_pb(PARAM1);
2426
    RETURN();
2427
}
2428

    
2429
void OPPROTO op_store_403_pb (void)
2430
{
2431
    do_store_403_pb(PARAM1);
2432
    RETURN();
2433
}
2434

    
2435
void OPPROTO op_load_40x_pit (void)
2436
{
2437
    T0 = load_40x_pit(env);
2438
    RETURN();
2439
}
2440

    
2441
void OPPROTO op_store_40x_pit (void)
2442
{
2443
    store_40x_pit(env, T0);
2444
    RETURN();
2445
}
2446

    
2447
void OPPROTO op_store_40x_dbcr0 (void)
2448
{
2449
    store_40x_dbcr0(env, T0);
2450
}
2451

    
2452
void OPPROTO op_store_40x_sler (void)
2453
{
2454
    store_40x_sler(env, T0);
2455
    RETURN();
2456
}
2457

    
2458
void OPPROTO op_store_booke_tcr (void)
2459
{
2460
    store_booke_tcr(env, T0);
2461
    RETURN();
2462
}
2463

    
2464
void OPPROTO op_store_booke_tsr (void)
2465
{
2466
    store_booke_tsr(env, T0);
2467
    RETURN();
2468
}
2469

    
2470
#endif /* !defined(CONFIG_USER_ONLY) */
2471

    
2472
#if defined(TARGET_PPCEMB)
2473
/* SPE extension */
2474
void OPPROTO op_splatw_T1_64 (void)
2475
{
2476
    T1_64 = (T1_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL);
2477
    RETURN();
2478
}
2479

    
2480
void OPPROTO op_splatwi_T0_64 (void)
2481
{
2482
    uint64_t tmp = PARAM1;
2483

    
2484
    T0_64 = (tmp << 32) | tmp;
2485
    RETURN();
2486
}
2487

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

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

    
2496
void OPPROTO op_extsh_T1_64 (void)
2497
{
2498
    T1_64 = (int32_t)((int16_t)T1_64);
2499
    RETURN();
2500
}
2501

    
2502
void OPPROTO op_sli16_T1_64 (void)
2503
{
2504
    T1_64 = T1_64 << 16;
2505
    RETURN();
2506
}
2507

    
2508
void OPPROTO op_sli32_T1_64 (void)
2509
{
2510
    T1_64 = T1_64 << 32;
2511
    RETURN();
2512
}
2513

    
2514
void OPPROTO op_srli32_T1_64 (void)
2515
{
2516
    T1_64 = T1_64 >> 32;
2517
    RETURN();
2518
}
2519

    
2520
void OPPROTO op_evsel (void)
2521
{
2522
    do_evsel();
2523
    RETURN();
2524
}
2525

    
2526
void OPPROTO op_evaddw (void)
2527
{
2528
    do_evaddw();
2529
    RETURN();
2530
}
2531

    
2532
void OPPROTO op_evsubfw (void)
2533
{
2534
    do_evsubfw();
2535
    RETURN();
2536
}
2537

    
2538
void OPPROTO op_evneg (void)
2539
{
2540
    do_evneg();
2541
    RETURN();
2542
}
2543

    
2544
void OPPROTO op_evabs (void)
2545
{
2546
    do_evabs();
2547
    RETURN();
2548
}
2549

    
2550
void OPPROTO op_evextsh (void)
2551
{
2552
    T0_64 = ((uint64_t)((int32_t)(int16_t)(T0_64 >> 32)) << 32) |
2553
        (uint64_t)((int32_t)(int16_t)T0_64);
2554
    RETURN();
2555
}
2556

    
2557
void OPPROTO op_evextsb (void)
2558
{
2559
    T0_64 = ((uint64_t)((int32_t)(int8_t)(T0_64 >> 32)) << 32) |
2560
        (uint64_t)((int32_t)(int8_t)T0_64);
2561
    RETURN();
2562
}
2563

    
2564
void OPPROTO op_evcntlzw (void)
2565
{
2566
    do_evcntlzw();
2567
    RETURN();
2568
}
2569

    
2570
void OPPROTO op_evrndw (void)
2571
{
2572
    do_evrndw();
2573
    RETURN();
2574
}
2575

    
2576
void OPPROTO op_brinc (void)
2577
{
2578
    do_brinc();
2579
    RETURN();
2580
}
2581

    
2582
void OPPROTO op_evcntlsw (void)
2583
{
2584
    do_evcntlsw();
2585
    RETURN();
2586
}
2587

    
2588
void OPPROTO op_evand (void)
2589
{
2590
    T0_64 &= T1_64;
2591
    RETURN();
2592
}
2593

    
2594
void OPPROTO op_evandc (void)
2595
{
2596
    T0_64 &= ~T1_64;
2597
    RETURN();
2598
}
2599

    
2600
void OPPROTO op_evor (void)
2601
{
2602
    T0_64 |= T1_64;
2603
    RETURN();
2604
}
2605

    
2606
void OPPROTO op_evxor (void)
2607
{
2608
    T0_64 ^= T1_64;
2609
    RETURN();
2610
}
2611

    
2612
void OPPROTO op_eveqv (void)
2613
{
2614
    T0_64 = ~(T0_64 ^ T1_64);
2615
    RETURN();
2616
}
2617

    
2618
void OPPROTO op_evnor (void)
2619
{
2620
    T0_64 = ~(T0_64 | T1_64);
2621
    RETURN();
2622
}
2623

    
2624
void OPPROTO op_evorc (void)
2625
{
2626
    T0_64 |= ~T1_64;
2627
    RETURN();
2628
}
2629

    
2630
void OPPROTO op_evnand (void)
2631
{
2632
    T0_64 = ~(T0_64 & T1_64);
2633
    RETURN();
2634
}
2635

    
2636
void OPPROTO op_evsrws (void)
2637
{
2638
    do_evsrws();
2639
    RETURN();
2640
}
2641

    
2642
void OPPROTO op_evsrwu (void)
2643
{
2644
    do_evsrwu();
2645
    RETURN();
2646
}
2647

    
2648
void OPPROTO op_evslw (void)
2649
{
2650
    do_evslw();
2651
    RETURN();
2652
}
2653

    
2654
void OPPROTO op_evrlw (void)
2655
{
2656
    do_evrlw();
2657
    RETURN();
2658
}
2659

    
2660
void OPPROTO op_evmergelo (void)
2661
{
2662
    T0_64 = (T0_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL);
2663
    RETURN();
2664
}
2665

    
2666
void OPPROTO op_evmergehi (void)
2667
{
2668
    T0_64 = (T0_64 & 0xFFFFFFFF00000000ULL) | (T1_64 >> 32);
2669
    RETURN();
2670
}
2671

    
2672
void OPPROTO op_evmergelohi (void)
2673
{
2674
    T0_64 = (T0_64 << 32) | (T1_64 >> 32);
2675
    RETURN();
2676
}
2677

    
2678
void OPPROTO op_evmergehilo (void)
2679
{
2680
    T0_64 = (T0_64 & 0xFFFFFFFF00000000ULL) | (T1_64 & 0x00000000FFFFFFFFULL);
2681
    RETURN();
2682
}
2683

    
2684
void OPPROTO op_evcmpgts (void)
2685
{
2686
    do_evcmpgts();
2687
    RETURN();
2688
}
2689

    
2690
void OPPROTO op_evcmpgtu (void)
2691
{
2692
    do_evcmpgtu();
2693
    RETURN();
2694
}
2695

    
2696
void OPPROTO op_evcmplts (void)
2697
{
2698
    do_evcmplts();
2699
    RETURN();
2700
}
2701

    
2702
void OPPROTO op_evcmpltu (void)
2703
{
2704
    do_evcmpltu();
2705
    RETURN();
2706
}
2707

    
2708
void OPPROTO op_evcmpeq (void)
2709
{
2710
    do_evcmpeq();
2711
    RETURN();
2712
}
2713

    
2714
void OPPROTO op_evfssub (void)
2715
{
2716
    do_evfssub();
2717
    RETURN();
2718
}
2719

    
2720
void OPPROTO op_evfsadd (void)
2721
{
2722
    do_evfsadd();
2723
    RETURN();
2724
}
2725

    
2726
void OPPROTO op_evfsnabs (void)
2727
{
2728
    do_evfsnabs();
2729
    RETURN();
2730
}
2731

    
2732
void OPPROTO op_evfsabs (void)
2733
{
2734
    do_evfsabs();
2735
    RETURN();
2736
}
2737

    
2738
void OPPROTO op_evfsneg (void)
2739
{
2740
    do_evfsneg();
2741
    RETURN();
2742
}
2743

    
2744
void OPPROTO op_evfsdiv (void)
2745
{
2746
    do_evfsdiv();
2747
    RETURN();
2748
}
2749

    
2750
void OPPROTO op_evfsmul (void)
2751
{
2752
    do_evfsmul();
2753
    RETURN();
2754
}
2755

    
2756
void OPPROTO op_evfscmplt (void)
2757
{
2758
    do_evfscmplt();
2759
    RETURN();
2760
}
2761

    
2762
void OPPROTO op_evfscmpgt (void)
2763
{
2764
    do_evfscmpgt();
2765
    RETURN();
2766
}
2767

    
2768
void OPPROTO op_evfscmpeq (void)
2769
{
2770
    do_evfscmpeq();
2771
    RETURN();
2772
}
2773

    
2774
void OPPROTO op_evfscfsi (void)
2775
{
2776
    do_evfscfsi();
2777
    RETURN();
2778
}
2779

    
2780
void OPPROTO op_evfscfui (void)
2781
{
2782
    do_evfscfui();
2783
    RETURN();
2784
}
2785

    
2786
void OPPROTO op_evfscfsf (void)
2787
{
2788
    do_evfscfsf();
2789
    RETURN();
2790
}
2791

    
2792
void OPPROTO op_evfscfuf (void)
2793
{
2794
    do_evfscfuf();
2795
    RETURN();
2796
}
2797

    
2798
void OPPROTO op_evfsctsi (void)
2799
{
2800
    do_evfsctsi();
2801
    RETURN();
2802
}
2803

    
2804
void OPPROTO op_evfsctui (void)
2805
{
2806
    do_evfsctui();
2807
    RETURN();
2808
}
2809

    
2810
void OPPROTO op_evfsctsf (void)
2811
{
2812
    do_evfsctsf();
2813
    RETURN();
2814
}
2815

    
2816
void OPPROTO op_evfsctuf (void)
2817
{
2818
    do_evfsctuf();
2819
    RETURN();
2820
}
2821

    
2822
void OPPROTO op_evfsctuiz (void)
2823
{
2824
    do_evfsctuiz();
2825
    RETURN();
2826
}
2827

    
2828
void OPPROTO op_evfsctsiz (void)
2829
{
2830
    do_evfsctsiz();
2831
    RETURN();
2832
}
2833

    
2834
void OPPROTO op_evfststlt (void)
2835
{
2836
    do_evfststlt();
2837
    RETURN();
2838
}
2839

    
2840
void OPPROTO op_evfststgt (void)
2841
{
2842
    do_evfststgt();
2843
    RETURN();
2844
}
2845

    
2846
void OPPROTO op_evfststeq (void)
2847
{
2848
    do_evfststeq();
2849
    RETURN();
2850
}
2851

    
2852
void OPPROTO op_efssub (void)
2853
{
2854
    T0_64 = _do_efssub(T0_64, T1_64);
2855
    RETURN();
2856
}
2857

    
2858
void OPPROTO op_efsadd (void)
2859
{
2860
    T0_64 = _do_efsadd(T0_64, T1_64);
2861
    RETURN();
2862
}
2863

    
2864
void OPPROTO op_efsnabs (void)
2865
{
2866
    T0_64 = _do_efsnabs(T0_64);
2867
    RETURN();
2868
}
2869

    
2870
void OPPROTO op_efsabs (void)
2871
{
2872
    T0_64 = _do_efsabs(T0_64);
2873
    RETURN();
2874
}
2875

    
2876
void OPPROTO op_efsneg (void)
2877
{
2878
    T0_64 = _do_efsneg(T0_64);
2879
    RETURN();
2880
}
2881

    
2882
void OPPROTO op_efsdiv (void)
2883
{
2884
    T0_64 = _do_efsdiv(T0_64, T1_64);
2885
    RETURN();
2886
}
2887

    
2888
void OPPROTO op_efsmul (void)
2889
{
2890
    T0_64 = _do_efsmul(T0_64, T1_64);
2891
    RETURN();
2892
}
2893

    
2894
void OPPROTO op_efscmplt (void)
2895
{
2896
    do_efscmplt();
2897
    RETURN();
2898
}
2899

    
2900
void OPPROTO op_efscmpgt (void)
2901
{
2902
    do_efscmpgt();
2903
    RETURN();
2904
}
2905

    
2906
void OPPROTO op_efscfd (void)
2907
{
2908
    do_efscfd();
2909
    RETURN();
2910
}
2911

    
2912
void OPPROTO op_efscmpeq (void)
2913
{
2914
    do_efscmpeq();
2915
    RETURN();
2916
}
2917

    
2918
void OPPROTO op_efscfsi (void)
2919
{
2920
    do_efscfsi();
2921
    RETURN();
2922
}
2923

    
2924
void OPPROTO op_efscfui (void)
2925
{
2926
    do_efscfui();
2927
    RETURN();
2928
}
2929

    
2930
void OPPROTO op_efscfsf (void)
2931
{
2932
    do_efscfsf();
2933
    RETURN();
2934
}
2935

    
2936
void OPPROTO op_efscfuf (void)
2937
{
2938
    do_efscfuf();
2939
    RETURN();
2940
}
2941

    
2942
void OPPROTO op_efsctsi (void)
2943
{
2944
    do_efsctsi();
2945
    RETURN();
2946
}
2947

    
2948
void OPPROTO op_efsctui (void)
2949
{
2950
    do_efsctui();
2951
    RETURN();
2952
}
2953

    
2954
void OPPROTO op_efsctsf (void)
2955
{
2956
    do_efsctsf();
2957
    RETURN();
2958
}
2959

    
2960
void OPPROTO op_efsctuf (void)
2961
{
2962
    do_efsctuf();
2963
    RETURN();
2964
}
2965

    
2966
void OPPROTO op_efsctsiz (void)
2967
{
2968
    do_efsctsiz();
2969
    RETURN();
2970
}
2971

    
2972
void OPPROTO op_efsctuiz (void)
2973
{
2974
    do_efsctuiz();
2975
    RETURN();
2976
}
2977

    
2978
void OPPROTO op_efststlt (void)
2979
{
2980
    T0 = _do_efststlt(T0_64, T1_64);
2981
    RETURN();
2982
}
2983

    
2984
void OPPROTO op_efststgt (void)
2985
{
2986
    T0 = _do_efststgt(T0_64, T1_64);
2987
    RETURN();
2988
}
2989

    
2990
void OPPROTO op_efststeq (void)
2991
{
2992
    T0 = _do_efststeq(T0_64, T1_64);
2993
    RETURN();
2994
}
2995

    
2996
void OPPROTO op_efdsub (void)
2997
{
2998
    union {
2999
        uint64_t u;
3000
        float64 f;
3001
    } u1, u2;
3002
    u1.u = T0_64;
3003
    u2.u = T1_64;
3004
    u1.f = float64_sub(u1.f, u2.f, &env->spe_status);
3005
    T0_64 = u1.u;
3006
    RETURN();
3007
}
3008

    
3009
void OPPROTO op_efdadd (void)
3010
{
3011
    union {
3012
        uint64_t u;
3013
        float64 f;
3014
    } u1, u2;
3015
    u1.u = T0_64;
3016
    u2.u = T1_64;
3017
    u1.f = float64_add(u1.f, u2.f, &env->spe_status);
3018
    T0_64 = u1.u;
3019
    RETURN();
3020
}
3021

    
3022
void OPPROTO op_efdcfsid (void)
3023
{
3024
    do_efdcfsi();
3025
    RETURN();
3026
}
3027

    
3028
void OPPROTO op_efdcfuid (void)
3029
{
3030
    do_efdcfui();
3031
    RETURN();
3032
}
3033

    
3034
void OPPROTO op_efdnabs (void)
3035
{
3036
    T0_64 |= 0x8000000000000000ULL;
3037
    RETURN();
3038
}
3039

    
3040
void OPPROTO op_efdabs (void)
3041
{
3042
    T0_64 &= ~0x8000000000000000ULL;
3043
    RETURN();
3044
}
3045

    
3046
void OPPROTO op_efdneg (void)
3047
{
3048
    T0_64 ^= 0x8000000000000000ULL;
3049
    RETURN();
3050
}
3051

    
3052
void OPPROTO op_efddiv (void)
3053
{
3054
    union {
3055
        uint64_t u;
3056
        float64 f;
3057
    } u1, u2;
3058
    u1.u = T0_64;
3059
    u2.u = T1_64;
3060
    u1.f = float64_div(u1.f, u2.f, &env->spe_status);
3061
    T0_64 = u1.u;
3062
    RETURN();
3063
}
3064

    
3065
void OPPROTO op_efdmul (void)
3066
{
3067
    union {
3068
        uint64_t u;
3069
        float64 f;
3070
    } u1, u2;
3071
    u1.u = T0_64;
3072
    u2.u = T1_64;
3073
    u1.f = float64_mul(u1.f, u2.f, &env->spe_status);
3074
    T0_64 = u1.u;
3075
    RETURN();
3076
}
3077

    
3078
void OPPROTO op_efdctsidz (void)
3079
{
3080
    do_efdctsiz();
3081
    RETURN();
3082
}
3083

    
3084
void OPPROTO op_efdctuidz (void)
3085
{
3086
    do_efdctuiz();
3087
    RETURN();
3088
}
3089

    
3090
void OPPROTO op_efdcmplt (void)
3091
{
3092
    do_efdcmplt();
3093
    RETURN();
3094
}
3095

    
3096
void OPPROTO op_efdcmpgt (void)
3097
{
3098
    do_efdcmpgt();
3099
    RETURN();
3100
}
3101

    
3102
void OPPROTO op_efdcfs (void)
3103
{
3104
    do_efdcfs();
3105
    RETURN();
3106
}
3107

    
3108
void OPPROTO op_efdcmpeq (void)
3109
{
3110
    do_efdcmpeq();
3111
    RETURN();
3112
}
3113

    
3114
void OPPROTO op_efdcfsi (void)
3115
{
3116
    do_efdcfsi();
3117
    RETURN();
3118
}
3119

    
3120
void OPPROTO op_efdcfui (void)
3121
{
3122
    do_efdcfui();
3123
    RETURN();
3124
}
3125

    
3126
void OPPROTO op_efdcfsf (void)
3127
{
3128
    do_efdcfsf();
3129
    RETURN();
3130
}
3131

    
3132
void OPPROTO op_efdcfuf (void)
3133
{
3134
    do_efdcfuf();
3135
    RETURN();
3136
}
3137

    
3138
void OPPROTO op_efdctsi (void)
3139
{
3140
    do_efdctsi();
3141
    RETURN();
3142
}
3143

    
3144
void OPPROTO op_efdctui (void)
3145
{
3146
    do_efdctui();
3147
    RETURN();
3148
}
3149

    
3150
void OPPROTO op_efdctsf (void)
3151
{
3152
    do_efdctsf();
3153
    RETURN();
3154
}
3155

    
3156
void OPPROTO op_efdctuf (void)
3157
{
3158
    do_efdctuf();
3159
    RETURN();
3160
}
3161

    
3162
void OPPROTO op_efdctuiz (void)
3163
{
3164
    do_efdctuiz();
3165
    RETURN();
3166
}
3167

    
3168
void OPPROTO op_efdctsiz (void)
3169
{
3170
    do_efdctsiz();
3171
    RETURN();
3172
}
3173

    
3174
void OPPROTO op_efdtstlt (void)
3175
{
3176
    T0 = _do_efdtstlt(T0_64, T1_64);
3177
    RETURN();
3178
}
3179

    
3180
void OPPROTO op_efdtstgt (void)
3181
{
3182
    T0 = _do_efdtstgt(T0_64, T1_64);
3183
    RETURN();
3184
}
3185

    
3186
void OPPROTO op_efdtsteq (void)
3187
{
3188
    T0 = _do_efdtsteq(T0_64, T1_64);
3189
    RETURN();
3190
}
3191
#endif /* defined(TARGET_PPCEMB) */