Statistics
| Branch: | Revision:

root / target-ppc / op.c @ a062e36c

History | View | Annotate | Download (47.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_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
void OPPROTO op_load_atbl (void)
427
{
428
    T0 = cpu_ppc_load_atbl(env);
429
    RETURN();
430
}
431

    
432
void OPPROTO op_load_atbu (void)
433
{
434
    T0 = cpu_ppc_load_atbu(env);
435
    RETURN();
436
}
437

    
438
#if !defined(CONFIG_USER_ONLY)
439
void OPPROTO op_store_tbl (void)
440
{
441
    cpu_ppc_store_tbl(env, T0);
442
    RETURN();
443
}
444

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

    
451
void OPPROTO op_store_atbl (void)
452
{
453
    cpu_ppc_store_atbl(env, T0);
454
    RETURN();
455
}
456

    
457
void OPPROTO op_store_atbu (void)
458
{
459
    cpu_ppc_store_atbu(env, T0);
460
    RETURN();
461
}
462

    
463
void OPPROTO op_load_decr (void)
464
{
465
    T0 = cpu_ppc_load_decr(env);
466
    RETURN();
467
}
468

    
469
void OPPROTO op_store_decr (void)
470
{
471
    cpu_ppc_store_decr(env, T0);
472
    RETURN();
473
}
474

    
475
void OPPROTO op_load_ibat (void)
476
{
477
    T0 = env->IBAT[PARAM1][PARAM2];
478
    RETURN();
479
}
480

    
481
void OPPROTO op_store_ibatu (void)
482
{
483
    do_store_ibatu(env, PARAM1, T0);
484
    RETURN();
485
}
486

    
487
void OPPROTO op_store_ibatl (void)
488
{
489
#if 1
490
    env->IBAT[1][PARAM1] = T0;
491
#else
492
    do_store_ibatl(env, PARAM1, T0);
493
#endif
494
    RETURN();
495
}
496

    
497
void OPPROTO op_load_dbat (void)
498
{
499
    T0 = env->DBAT[PARAM1][PARAM2];
500
    RETURN();
501
}
502

    
503
void OPPROTO op_store_dbatu (void)
504
{
505
    do_store_dbatu(env, PARAM1, T0);
506
    RETURN();
507
}
508

    
509
void OPPROTO op_store_dbatl (void)
510
{
511
#if 1
512
    env->DBAT[1][PARAM1] = T0;
513
#else
514
    do_store_dbatl(env, PARAM1, T0);
515
#endif
516
    RETURN();
517
}
518
#endif /* !defined(CONFIG_USER_ONLY) */
519

    
520
/* FPSCR */
521
void OPPROTO op_load_fpscr (void)
522
{
523
    do_load_fpscr();
524
    RETURN();
525
}
526

    
527
void OPPROTO op_store_fpscr (void)
528
{
529
    do_store_fpscr(PARAM1);
530
    RETURN();
531
}
532

    
533
void OPPROTO op_reset_scrfx (void)
534
{
535
    env->fpscr[7] &= ~0x8;
536
    RETURN();
537
}
538

    
539
/* crf operations */
540
void OPPROTO op_getbit_T0 (void)
541
{
542
    T0 = (T0 >> PARAM1) & 1;
543
    RETURN();
544
}
545

    
546
void OPPROTO op_getbit_T1 (void)
547
{
548
    T1 = (T1 >> PARAM1) & 1;
549
    RETURN();
550
}
551

    
552
void OPPROTO op_setcrfbit (void)
553
{
554
    T1 = (T1 & PARAM1) | (T0 << PARAM2);
555
    RETURN();
556
}
557

    
558
/* Branch */
559
#define EIP env->nip
560

    
561
void OPPROTO op_setlr (void)
562
{
563
    env->lr = (uint32_t)PARAM1;
564
    RETURN();
565
}
566

    
567
#if defined (TARGET_PPC64)
568
void OPPROTO op_setlr_64 (void)
569
{
570
    env->lr = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
571
    RETURN();
572
}
573
#endif
574

    
575
void OPPROTO op_goto_tb0 (void)
576
{
577
    GOTO_TB(op_goto_tb0, PARAM1, 0);
578
}
579

    
580
void OPPROTO op_goto_tb1 (void)
581
{
582
    GOTO_TB(op_goto_tb1, PARAM1, 1);
583
}
584

    
585
void OPPROTO op_b_T1 (void)
586
{
587
    env->nip = (uint32_t)(T1 & ~3);
588
    RETURN();
589
}
590

    
591
#if defined (TARGET_PPC64)
592
void OPPROTO op_b_T1_64 (void)
593
{
594
    env->nip = (uint64_t)(T1 & ~3);
595
    RETURN();
596
}
597
#endif
598

    
599
void OPPROTO op_jz_T0 (void)
600
{
601
    if (!T0)
602
        GOTO_LABEL_PARAM(1);
603
    RETURN();
604
}
605

    
606
void OPPROTO op_btest_T1 (void)
607
{
608
    if (T0) {
609
        env->nip = (uint32_t)(T1 & ~3);
610
    } else {
611
        env->nip = (uint32_t)PARAM1;
612
    }
613
    RETURN();
614
}
615

    
616
#if defined (TARGET_PPC64)
617
void OPPROTO op_btest_T1_64 (void)
618
{
619
    if (T0) {
620
        env->nip = (uint64_t)(T1 & ~3);
621
    } else {
622
        env->nip = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
623
    }
624
    RETURN();
625
}
626
#endif
627

    
628
void OPPROTO op_movl_T1_ctr (void)
629
{
630
    T1 = env->ctr;
631
    RETURN();
632
}
633

    
634
void OPPROTO op_movl_T1_lr (void)
635
{
636
    T1 = env->lr;
637
    RETURN();
638
}
639

    
640
/* tests with result in T0 */
641
void OPPROTO op_test_ctr (void)
642
{
643
    T0 = (uint32_t)env->ctr;
644
    RETURN();
645
}
646

    
647
#if defined(TARGET_PPC64)
648
void OPPROTO op_test_ctr_64 (void)
649
{
650
    T0 = (uint64_t)env->ctr;
651
    RETURN();
652
}
653
#endif
654

    
655
void OPPROTO op_test_ctr_true (void)
656
{
657
    T0 = ((uint32_t)env->ctr != 0 && (T0 & PARAM1) != 0);
658
    RETURN();
659
}
660

    
661
#if defined(TARGET_PPC64)
662
void OPPROTO op_test_ctr_true_64 (void)
663
{
664
    T0 = ((uint64_t)env->ctr != 0 && (T0 & PARAM1) != 0);
665
    RETURN();
666
}
667
#endif
668

    
669
void OPPROTO op_test_ctr_false (void)
670
{
671
    T0 = ((uint32_t)env->ctr != 0 && (T0 & PARAM1) == 0);
672
    RETURN();
673
}
674

    
675
#if defined(TARGET_PPC64)
676
void OPPROTO op_test_ctr_false_64 (void)
677
{
678
    T0 = ((uint64_t)env->ctr != 0 && (T0 & PARAM1) == 0);
679
    RETURN();
680
}
681
#endif
682

    
683
void OPPROTO op_test_ctrz (void)
684
{
685
    T0 = ((uint32_t)env->ctr == 0);
686
    RETURN();
687
}
688

    
689
#if defined(TARGET_PPC64)
690
void OPPROTO op_test_ctrz_64 (void)
691
{
692
    T0 = ((uint64_t)env->ctr == 0);
693
    RETURN();
694
}
695
#endif
696

    
697
void OPPROTO op_test_ctrz_true (void)
698
{
699
    T0 = ((uint32_t)env->ctr == 0 && (T0 & PARAM1) != 0);
700
    RETURN();
701
}
702

    
703
#if defined(TARGET_PPC64)
704
void OPPROTO op_test_ctrz_true_64 (void)
705
{
706
    T0 = ((uint64_t)env->ctr == 0 && (T0 & PARAM1) != 0);
707
    RETURN();
708
}
709
#endif
710

    
711
void OPPROTO op_test_ctrz_false (void)
712
{
713
    T0 = ((uint32_t)env->ctr == 0 && (T0 & PARAM1) == 0);
714
    RETURN();
715
}
716

    
717
#if defined(TARGET_PPC64)
718
void OPPROTO op_test_ctrz_false_64 (void)
719
{
720
    T0 = ((uint64_t)env->ctr == 0 && (T0 & PARAM1) == 0);
721
    RETURN();
722
}
723
#endif
724

    
725
void OPPROTO op_test_true (void)
726
{
727
    T0 = (T0 & PARAM1);
728
    RETURN();
729
}
730

    
731
void OPPROTO op_test_false (void)
732
{
733
    T0 = ((T0 & PARAM1) == 0);
734
    RETURN();
735
}
736

    
737
/* CTR maintenance */
738
void OPPROTO op_dec_ctr (void)
739
{
740
    env->ctr--;
741
    RETURN();
742
}
743

    
744
/***                           Integer arithmetic                          ***/
745
/* add */
746
void OPPROTO op_add (void)
747
{
748
    T0 += T1;
749
    RETURN();
750
}
751

    
752
void OPPROTO op_check_addo (void)
753
{
754
    if (likely(!(((uint32_t)T2 ^ (uint32_t)T1 ^ UINT32_MAX) &
755
                 ((uint32_t)T2 ^ (uint32_t)T0) & (1UL << 31)))) {
756
        xer_ov = 0;
757
    } else {
758
        xer_ov = 1;
759
        xer_so = 1;
760
    }
761
    RETURN();
762
}
763

    
764
#if defined(TARGET_PPC64)
765
void OPPROTO op_check_addo_64 (void)
766
{
767
    if (likely(!(((uint64_t)T2 ^ (uint64_t)T1 ^ UINT64_MAX) &
768
                 ((uint64_t)T2 ^ (uint64_t)T0) & (1ULL << 63)))) {
769
        xer_ov = 0;
770
    } else {
771
        xer_ov = 1;
772
        xer_so = 1;
773
    }
774
    RETURN();
775
}
776
#endif
777

    
778
/* add carrying */
779
void OPPROTO op_check_addc (void)
780
{
781
    if (likely((uint32_t)T0 >= (uint32_t)T2)) {
782
        xer_ca = 0;
783
    } else {
784
        xer_ca = 1;
785
    }
786
    RETURN();
787
}
788

    
789
#if defined(TARGET_PPC64)
790
void OPPROTO op_check_addc_64 (void)
791
{
792
    if (likely((uint64_t)T0 >= (uint64_t)T2)) {
793
        xer_ca = 0;
794
    } else {
795
        xer_ca = 1;
796
    }
797
    RETURN();
798
}
799
#endif
800

    
801
/* add extended */
802
void OPPROTO op_adde (void)
803
{
804
    do_adde();
805
    RETURN();
806
}
807

    
808
#if defined(TARGET_PPC64)
809
void OPPROTO op_adde_64 (void)
810
{
811
    do_adde_64();
812
    RETURN();
813
}
814
#endif
815

    
816
/* add immediate */
817
void OPPROTO op_addi (void)
818
{
819
    T0 += (int32_t)PARAM1;
820
    RETURN();
821
}
822

    
823
/* add to minus one extended */
824
void OPPROTO op_add_me (void)
825
{
826
    T0 += xer_ca + (-1);
827
    if (likely((uint32_t)T1 != 0))
828
        xer_ca = 1;
829
    RETURN();
830
}
831

    
832
#if defined(TARGET_PPC64)
833
void OPPROTO op_add_me_64 (void)
834
{
835
    T0 += xer_ca + (-1);
836
    if (likely((uint64_t)T1 != 0))
837
        xer_ca = 1;
838
    RETURN();
839
}
840
#endif
841

    
842
void OPPROTO op_addmeo (void)
843
{
844
    do_addmeo();
845
    RETURN();
846
}
847

    
848
void OPPROTO op_addmeo_64 (void)
849
{
850
    do_addmeo();
851
    RETURN();
852
}
853

    
854
/* add to zero extended */
855
void OPPROTO op_add_ze (void)
856
{
857
    T0 += xer_ca;
858
    RETURN();
859
}
860

    
861
/* divide word */
862
void OPPROTO op_divw (void)
863
{
864
    if (unlikely(((int32_t)T0 == INT32_MIN && (int32_t)T1 == -1) ||
865
                 (int32_t)T1 == 0)) {
866
        T0 = (int32_t)((-1) * ((uint32_t)T0 >> 31));
867
    } else {
868
        T0 = (int32_t)T0 / (int32_t)T1;
869
    }
870
    RETURN();
871
}
872

    
873
#if defined(TARGET_PPC64)
874
void OPPROTO op_divd (void)
875
{
876
    if (unlikely(((int64_t)T0 == INT64_MIN && (int64_t)T1 == -1) ||
877
                 (int64_t)T1 == 0)) {
878
        T0 = (int64_t)((-1ULL) * ((uint64_t)T0 >> 63));
879
    } else {
880
        T0 = (int64_t)T0 / (int64_t)T1;
881
    }
882
    RETURN();
883
}
884
#endif
885

    
886
void OPPROTO op_divwo (void)
887
{
888
    do_divwo();
889
    RETURN();
890
}
891

    
892
#if defined(TARGET_PPC64)
893
void OPPROTO op_divdo (void)
894
{
895
    do_divdo();
896
    RETURN();
897
}
898
#endif
899

    
900
/* divide word unsigned */
901
void OPPROTO op_divwu (void)
902
{
903
    if (unlikely(T1 == 0)) {
904
        T0 = 0;
905
    } else {
906
        T0 = (uint32_t)T0 / (uint32_t)T1;
907
    }
908
    RETURN();
909
}
910

    
911
#if defined(TARGET_PPC64)
912
void OPPROTO op_divdu (void)
913
{
914
    if (unlikely(T1 == 0)) {
915
        T0 = 0;
916
    } else {
917
        T0 /= T1;
918
    }
919
    RETURN();
920
}
921
#endif
922

    
923
void OPPROTO op_divwuo (void)
924
{
925
    do_divwuo();
926
    RETURN();
927
}
928

    
929
#if defined(TARGET_PPC64)
930
void OPPROTO op_divduo (void)
931
{
932
    do_divduo();
933
    RETURN();
934
}
935
#endif
936

    
937
/* multiply high word */
938
void OPPROTO op_mulhw (void)
939
{
940
    T0 = ((int64_t)((int32_t)T0) * (int64_t)((int32_t)T1)) >> 32;
941
    RETURN();
942
}
943

    
944
#if defined(TARGET_PPC64)
945
void OPPROTO op_mulhd (void)
946
{
947
    uint64_t tl, th;
948

    
949
    do_imul64(&tl, &th);
950
    T0 = th;
951
    RETURN();
952
}
953
#endif
954

    
955
/* multiply high word unsigned */
956
void OPPROTO op_mulhwu (void)
957
{
958
    T0 = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1) >> 32;
959
    RETURN();
960
}
961

    
962
#if defined(TARGET_PPC64)
963
void OPPROTO op_mulhdu (void)
964
{
965
    uint64_t tl, th;
966

    
967
    do_mul64(&tl, &th);
968
    T0 = th;
969
    RETURN();
970
}
971
#endif
972

    
973
/* multiply low immediate */
974
void OPPROTO op_mulli (void)
975
{
976
    T0 = ((int32_t)T0 * (int32_t)PARAM1);
977
    RETURN();
978
}
979

    
980
/* multiply low word */
981
void OPPROTO op_mullw (void)
982
{
983
    T0 = (int32_t)(T0 * T1);
984
    RETURN();
985
}
986

    
987
#if defined(TARGET_PPC64)
988
void OPPROTO op_mulld (void)
989
{
990
    T0 *= T1;
991
    RETURN();
992
}
993
#endif
994

    
995
void OPPROTO op_mullwo (void)
996
{
997
    do_mullwo();
998
    RETURN();
999
}
1000

    
1001
#if defined(TARGET_PPC64)
1002
void OPPROTO op_mulldo (void)
1003
{
1004
    do_mulldo();
1005
    RETURN();
1006
}
1007
#endif
1008

    
1009
/* negate */
1010
void OPPROTO op_neg (void)
1011
{
1012
    if (likely(T0 != INT32_MIN)) {
1013
        T0 = -(int32_t)T0;
1014
    }
1015
    RETURN();
1016
}
1017

    
1018
#if defined(TARGET_PPC64)
1019
void OPPROTO op_neg_64 (void)
1020
{
1021
    if (likely(T0 != INT64_MIN)) {
1022
        T0 = -(int64_t)T0;
1023
    }
1024
    RETURN();
1025
}
1026
#endif
1027

    
1028
void OPPROTO op_nego (void)
1029
{
1030
    do_nego();
1031
    RETURN();
1032
}
1033

    
1034
#if defined(TARGET_PPC64)
1035
void OPPROTO op_nego_64 (void)
1036
{
1037
    do_nego_64();
1038
    RETURN();
1039
}
1040
#endif
1041

    
1042
/* subtract from */
1043
void OPPROTO op_subf (void)
1044
{
1045
    T0 = T1 - T0;
1046
    RETURN();
1047
}
1048

    
1049
void OPPROTO op_check_subfo (void)
1050
{
1051
    if (likely(!(((uint32_t)(~T2) ^ (uint32_t)T1 ^ UINT32_MAX) &
1052
                 ((uint32_t)(~T2) ^ (uint32_t)T0) & (1UL << 31)))) {
1053
        xer_ov = 0;
1054
    } else {
1055
        xer_ov = 1;
1056
        xer_so = 1;
1057
    }
1058
    RETURN();
1059
}
1060

    
1061
#if defined(TARGET_PPC64)
1062
void OPPROTO op_check_subfo_64 (void)
1063
{
1064
    if (likely(!(((uint64_t)(~T2) ^ (uint64_t)T1 ^ UINT64_MAX) &
1065
                 ((uint64_t)(~T2) ^ (uint64_t)T0) & (1ULL << 63)))) {
1066
        xer_ov = 0;
1067
    } else {
1068
        xer_ov = 1;
1069
        xer_so = 1;
1070
    }
1071
    RETURN();
1072
}
1073
#endif
1074

    
1075
/* subtract from carrying */
1076
void OPPROTO op_check_subfc (void)
1077
{
1078
    if (likely((uint32_t)T0 > (uint32_t)T1)) {
1079
        xer_ca = 0;
1080
    } else {
1081
        xer_ca = 1;
1082
    }
1083
    RETURN();
1084
}
1085

    
1086
#if defined(TARGET_PPC64)
1087
void OPPROTO op_check_subfc_64 (void)
1088
{
1089
    if (likely((uint64_t)T0 > (uint64_t)T1)) {
1090
        xer_ca = 0;
1091
    } else {
1092
        xer_ca = 1;
1093
    }
1094
    RETURN();
1095
}
1096
#endif
1097

    
1098
/* subtract from extended */
1099
void OPPROTO op_subfe (void)
1100
{
1101
    do_subfe();
1102
    RETURN();
1103
}
1104

    
1105
#if defined(TARGET_PPC64)
1106
void OPPROTO op_subfe_64 (void)
1107
{
1108
    do_subfe_64();
1109
    RETURN();
1110
}
1111
#endif
1112

    
1113
/* subtract from immediate carrying */
1114
void OPPROTO op_subfic (void)
1115
{
1116
    T0 = (int32_t)PARAM1 + ~T0 + 1;
1117
    if ((uint32_t)T0 <= (uint32_t)PARAM1) {
1118
        xer_ca = 1;
1119
    } else {
1120
        xer_ca = 0;
1121
    }
1122
    RETURN();
1123
}
1124

    
1125
#if defined(TARGET_PPC64)
1126
void OPPROTO op_subfic_64 (void)
1127
{
1128
    T0 = PARAM1 + ~T0 + 1;
1129
    if ((uint64_t)T0 <= (uint64_t)PARAM1) {
1130
        xer_ca = 1;
1131
    } else {
1132
        xer_ca = 0;
1133
    }
1134
    RETURN();
1135
}
1136
#endif
1137

    
1138
/* subtract from minus one extended */
1139
void OPPROTO op_subfme (void)
1140
{
1141
    T0 = ~T0 + xer_ca - 1;
1142
    if (likely((uint32_t)T0 != (uint32_t)-1))
1143
        xer_ca = 1;
1144
    RETURN();
1145
}
1146

    
1147
#if defined(TARGET_PPC64)
1148
void OPPROTO op_subfme_64 (void)
1149
{
1150
    T0 = ~T0 + xer_ca - 1;
1151
    if (likely((uint64_t)T0 != (uint64_t)-1))
1152
        xer_ca = 1;
1153
    RETURN();
1154
}
1155
#endif
1156

    
1157
void OPPROTO op_subfmeo (void)
1158
{
1159
    do_subfmeo();
1160
    RETURN();
1161
}
1162

    
1163
#if defined(TARGET_PPC64)
1164
void OPPROTO op_subfmeo_64 (void)
1165
{
1166
    do_subfmeo_64();
1167
    RETURN();
1168
}
1169
#endif
1170

    
1171
/* subtract from zero extended */
1172
void OPPROTO op_subfze (void)
1173
{
1174
    T1 = ~T0;
1175
    T0 = T1 + xer_ca;
1176
    if ((uint32_t)T0 < (uint32_t)T1) {
1177
        xer_ca = 1;
1178
    } else {
1179
        xer_ca = 0;
1180
    }
1181
    RETURN();
1182
}
1183

    
1184
#if defined(TARGET_PPC64)
1185
void OPPROTO op_subfze_64 (void)
1186
{
1187
    T1 = ~T0;
1188
    T0 = T1 + xer_ca;
1189
    if ((uint64_t)T0 < (uint64_t)T1) {
1190
        xer_ca = 1;
1191
    } else {
1192
        xer_ca = 0;
1193
    }
1194
    RETURN();
1195
}
1196
#endif
1197

    
1198
void OPPROTO op_subfzeo (void)
1199
{
1200
    do_subfzeo();
1201
    RETURN();
1202
}
1203

    
1204
#if defined(TARGET_PPC64)
1205
void OPPROTO op_subfzeo_64 (void)
1206
{
1207
    do_subfzeo_64();
1208
    RETURN();
1209
}
1210
#endif
1211

    
1212
/***                           Integer comparison                          ***/
1213
/* compare */
1214
void OPPROTO op_cmp (void)
1215
{
1216
    if ((int32_t)T0 < (int32_t)T1) {
1217
        T0 = 0x08;
1218
    } else if ((int32_t)T0 > (int32_t)T1) {
1219
        T0 = 0x04;
1220
    } else {
1221
        T0 = 0x02;
1222
    }
1223
    T0 |= xer_so;
1224
    RETURN();
1225
}
1226

    
1227
#if defined(TARGET_PPC64)
1228
void OPPROTO op_cmp_64 (void)
1229
{
1230
    if ((int64_t)T0 < (int64_t)T1) {
1231
        T0 = 0x08;
1232
    } else if ((int64_t)T0 > (int64_t)T1) {
1233
        T0 = 0x04;
1234
    } else {
1235
        T0 = 0x02;
1236
    }
1237
    T0 |= xer_so;
1238
    RETURN();
1239
}
1240
#endif
1241

    
1242
/* compare immediate */
1243
void OPPROTO op_cmpi (void)
1244
{
1245
    if ((int32_t)T0 < (int32_t)PARAM1) {
1246
        T0 = 0x08;
1247
    } else if ((int32_t)T0 > (int32_t)PARAM1) {
1248
        T0 = 0x04;
1249
    } else {
1250
        T0 = 0x02;
1251
    }
1252
    T0 |= xer_so;
1253
    RETURN();
1254
}
1255

    
1256
#if defined(TARGET_PPC64)
1257
void OPPROTO op_cmpi_64 (void)
1258
{
1259
    if ((int64_t)T0 < (int64_t)((int32_t)PARAM1)) {
1260
        T0 = 0x08;
1261
    } else if ((int64_t)T0 > (int64_t)((int32_t)PARAM1)) {
1262
        T0 = 0x04;
1263
    } else {
1264
        T0 = 0x02;
1265
    }
1266
    T0 |= xer_so;
1267
    RETURN();
1268
}
1269
#endif
1270

    
1271
/* compare logical */
1272
void OPPROTO op_cmpl (void)
1273
{
1274
    if ((uint32_t)T0 < (uint32_t)T1) {
1275
        T0 = 0x08;
1276
    } else if ((uint32_t)T0 > (uint32_t)T1) {
1277
        T0 = 0x04;
1278
    } else {
1279
        T0 = 0x02;
1280
    }
1281
    T0 |= xer_so;
1282
    RETURN();
1283
}
1284

    
1285
#if defined(TARGET_PPC64)
1286
void OPPROTO op_cmpl_64 (void)
1287
{
1288
    if ((uint64_t)T0 < (uint64_t)T1) {
1289
        T0 = 0x08;
1290
    } else if ((uint64_t)T0 > (uint64_t)T1) {
1291
        T0 = 0x04;
1292
    } else {
1293
        T0 = 0x02;
1294
    }
1295
    T0 |= xer_so;
1296
    RETURN();
1297
}
1298
#endif
1299

    
1300
/* compare logical immediate */
1301
void OPPROTO op_cmpli (void)
1302
{
1303
    if ((uint32_t)T0 < (uint32_t)PARAM1) {
1304
        T0 = 0x08;
1305
    } else if ((uint32_t)T0 > (uint32_t)PARAM1) {
1306
        T0 = 0x04;
1307
    } else {
1308
        T0 = 0x02;
1309
    }
1310
    T0 |= xer_so;
1311
    RETURN();
1312
}
1313

    
1314
#if defined(TARGET_PPC64)
1315
void OPPROTO op_cmpli_64 (void)
1316
{
1317
    if ((uint64_t)T0 < (uint64_t)PARAM1) {
1318
        T0 = 0x08;
1319
    } else if ((uint64_t)T0 > (uint64_t)PARAM1) {
1320
        T0 = 0x04;
1321
    } else {
1322
        T0 = 0x02;
1323
    }
1324
    T0 |= xer_so;
1325
    RETURN();
1326
}
1327
#endif
1328

    
1329
void OPPROTO op_isel (void)
1330
{
1331
    if (T0)
1332
        T0 = T1;
1333
    else
1334
        T0 = T2;
1335
    RETURN();
1336
}
1337

    
1338
void OPPROTO op_popcntb (void)
1339
{
1340
    do_popcntb();
1341
    RETURN();
1342
}
1343

    
1344
#if defined(TARGET_PPC64)
1345
void OPPROTO op_popcntb_64 (void)
1346
{
1347
    do_popcntb_64();
1348
    RETURN();
1349
}
1350
#endif
1351

    
1352
/***                            Integer logical                            ***/
1353
/* and */
1354
void OPPROTO op_and (void)
1355
{
1356
    T0 &= T1;
1357
    RETURN();
1358
}
1359

    
1360
/* andc */
1361
void OPPROTO op_andc (void)
1362
{
1363
    T0 &= ~T1;
1364
    RETURN();
1365
}
1366

    
1367
/* andi. */
1368
void OPPROTO op_andi_T0 (void)
1369
{
1370
    T0 &= PARAM1;
1371
    RETURN();
1372
}
1373

    
1374
void OPPROTO op_andi_T1 (void)
1375
{
1376
    T1 &= PARAM1;
1377
    RETURN();
1378
}
1379

    
1380
#if defined(TARGET_PPC64)
1381
void OPPROTO op_andi_T0_64 (void)
1382
{
1383
    T0 &= ((uint64_t)PARAM1 << 32) | PARAM2;
1384
    RETURN();
1385
}
1386

    
1387
void OPPROTO op_andi_T1_64 (void)
1388
{
1389
    T1 &= ((uint64_t)PARAM1 << 32) | PARAM2;
1390
    RETURN();
1391
}
1392
#endif
1393

    
1394

    
1395
/* count leading zero */
1396
void OPPROTO op_cntlzw (void)
1397
{
1398
    T0 = _do_cntlzw(T0);
1399
    RETURN();
1400
}
1401

    
1402
#if defined(TARGET_PPC64)
1403
void OPPROTO op_cntlzd (void)
1404
{
1405
    T0 = _do_cntlzd(T0);
1406
    RETURN();
1407
}
1408
#endif
1409

    
1410
/* eqv */
1411
void OPPROTO op_eqv (void)
1412
{
1413
    T0 = ~(T0 ^ T1);
1414
    RETURN();
1415
}
1416

    
1417
/* extend sign byte */
1418
void OPPROTO op_extsb (void)
1419
{
1420
#if defined (TARGET_PPC64)
1421
    T0 = (int64_t)((int8_t)T0);
1422
#else
1423
    T0 = (int32_t)((int8_t)T0);
1424
#endif
1425
    RETURN();
1426
}
1427

    
1428
/* extend sign half word */
1429
void OPPROTO op_extsh (void)
1430
{
1431
#if defined (TARGET_PPC64)
1432
    T0 = (int64_t)((int16_t)T0);
1433
#else
1434
    T0 = (int32_t)((int16_t)T0);
1435
#endif
1436
    RETURN();
1437
}
1438

    
1439
#if defined (TARGET_PPC64)
1440
void OPPROTO op_extsw (void)
1441
{
1442
    T0 = (int64_t)((int32_t)T0);
1443
    RETURN();
1444
}
1445
#endif
1446

    
1447
/* nand */
1448
void OPPROTO op_nand (void)
1449
{
1450
    T0 = ~(T0 & T1);
1451
    RETURN();
1452
}
1453

    
1454
/* nor */
1455
void OPPROTO op_nor (void)
1456
{
1457
    T0 = ~(T0 | T1);
1458
    RETURN();
1459
}
1460

    
1461
/* or */
1462
void OPPROTO op_or (void)
1463
{
1464
    T0 |= T1;
1465
    RETURN();
1466
}
1467

    
1468
/* orc */
1469
void OPPROTO op_orc (void)
1470
{
1471
    T0 |= ~T1;
1472
    RETURN();
1473
}
1474

    
1475
/* ori */
1476
void OPPROTO op_ori (void)
1477
{
1478
    T0 |= PARAM1;
1479
    RETURN();
1480
}
1481

    
1482
/* xor */
1483
void OPPROTO op_xor (void)
1484
{
1485
    T0 ^= T1;
1486
    RETURN();
1487
}
1488

    
1489
/* xori */
1490
void OPPROTO op_xori (void)
1491
{
1492
    T0 ^= PARAM1;
1493
    RETURN();
1494
}
1495

    
1496
/***                             Integer rotate                            ***/
1497
void OPPROTO op_rotl32_T0_T1 (void)
1498
{
1499
    T0 = rotl32(T0, T1 & 0x1F);
1500
    RETURN();
1501
}
1502

    
1503
void OPPROTO op_rotli32_T0 (void)
1504
{
1505
    T0 = rotl32(T0, PARAM1);
1506
    RETURN();
1507
}
1508

    
1509
#if defined(TARGET_PPC64)
1510
void OPPROTO op_rotl64_T0_T1 (void)
1511
{
1512
    T0 = rotl64(T0, T1 & 0x3F);
1513
    RETURN();
1514
}
1515

    
1516
void OPPROTO op_rotli64_T0 (void)
1517
{
1518
    T0 = rotl64(T0, PARAM1);
1519
    RETURN();
1520
}
1521
#endif
1522

    
1523
/***                             Integer shift                             ***/
1524
/* shift left word */
1525
void OPPROTO op_slw (void)
1526
{
1527
    if (T1 & 0x20) {
1528
        T0 = 0;
1529
    } else {
1530
        T0 = (uint32_t)(T0 << T1);
1531
    }
1532
    RETURN();
1533
}
1534

    
1535
#if defined(TARGET_PPC64)
1536
void OPPROTO op_sld (void)
1537
{
1538
    if (T1 & 0x40) {
1539
        T0 = 0;
1540
    } else {
1541
        T0 = T0 << T1;
1542
    }
1543
    RETURN();
1544
}
1545
#endif
1546

    
1547
/* shift right algebraic word */
1548
void OPPROTO op_sraw (void)
1549
{
1550
    do_sraw();
1551
    RETURN();
1552
}
1553

    
1554
#if defined(TARGET_PPC64)
1555
void OPPROTO op_srad (void)
1556
{
1557
    do_srad();
1558
    RETURN();
1559
}
1560
#endif
1561

    
1562
/* shift right algebraic word immediate */
1563
void OPPROTO op_srawi (void)
1564
{
1565
    uint32_t mask = (uint32_t)PARAM2;
1566

    
1567
    T0 = (int32_t)T0 >> PARAM1;
1568
    if ((int32_t)T1 < 0 && (T1 & mask) != 0) {
1569
        xer_ca = 1;
1570
    } else {
1571
        xer_ca = 0;
1572
    }
1573
    RETURN();
1574
}
1575

    
1576
#if defined(TARGET_PPC64)
1577
void OPPROTO op_sradi (void)
1578
{
1579
    uint64_t mask = ((uint64_t)PARAM2 << 32) | (uint64_t)PARAM3;
1580

    
1581
    T0 = (int64_t)T0 >> PARAM1;
1582
    if ((int64_t)T1 < 0 && ((uint64_t)T1 & mask) != 0) {
1583
        xer_ca = 1;
1584
    } else {
1585
        xer_ca = 0;
1586
    }
1587
    RETURN();
1588
}
1589
#endif
1590

    
1591
/* shift right word */
1592
void OPPROTO op_srw (void)
1593
{
1594
    if (T1 & 0x20) {
1595
        T0 = 0;
1596
    } else {
1597
        T0 = (uint32_t)T0 >> T1;
1598
    }
1599
    RETURN();
1600
}
1601

    
1602
#if defined(TARGET_PPC64)
1603
void OPPROTO op_srd (void)
1604
{
1605
    if (T1 & 0x40) {
1606
        T0 = 0;
1607
    } else {
1608
        T0 = (uint64_t)T0 >> T1;
1609
    }
1610
    RETURN();
1611
}
1612
#endif
1613

    
1614
void OPPROTO op_sl_T0_T1 (void)
1615
{
1616
    T0 = T0 << T1;
1617
    RETURN();
1618
}
1619

    
1620
void OPPROTO op_sli_T0 (void)
1621
{
1622
    T0 = T0 << PARAM1;
1623
    RETURN();
1624
}
1625

    
1626
void OPPROTO op_srl_T0_T1 (void)
1627
{
1628
    T0 = (uint32_t)T0 >> T1;
1629
    RETURN();
1630
}
1631

    
1632
#if defined(TARGET_PPC64)
1633
void OPPROTO op_srl_T0_T1_64 (void)
1634
{
1635
    T0 = (uint32_t)T0 >> T1;
1636
    RETURN();
1637
}
1638
#endif
1639

    
1640
void OPPROTO op_srli_T0 (void)
1641
{
1642
    T0 = (uint32_t)T0 >> PARAM1;
1643
    RETURN();
1644
}
1645

    
1646
#if defined(TARGET_PPC64)
1647
void OPPROTO op_srli_T0_64 (void)
1648
{
1649
    T0 = (uint64_t)T0 >> PARAM1;
1650
    RETURN();
1651
}
1652
#endif
1653

    
1654
void OPPROTO op_srli_T1 (void)
1655
{
1656
    T1 = (uint32_t)T1 >> PARAM1;
1657
    RETURN();
1658
}
1659

    
1660
#if defined(TARGET_PPC64)
1661
void OPPROTO op_srli_T1_64 (void)
1662
{
1663
    T1 = (uint64_t)T1 >> PARAM1;
1664
    RETURN();
1665
}
1666
#endif
1667

    
1668
/***                       Floating-Point arithmetic                       ***/
1669
/* fadd - fadd. */
1670
void OPPROTO op_fadd (void)
1671
{
1672
    FT0 = float64_add(FT0, FT1, &env->fp_status);
1673
    RETURN();
1674
}
1675

    
1676
/* fsub - fsub. */
1677
void OPPROTO op_fsub (void)
1678
{
1679
    FT0 = float64_sub(FT0, FT1, &env->fp_status);
1680
    RETURN();
1681
}
1682

    
1683
/* fmul - fmul. */
1684
void OPPROTO op_fmul (void)
1685
{
1686
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1687
    RETURN();
1688
}
1689

    
1690
/* fdiv - fdiv. */
1691
void OPPROTO op_fdiv (void)
1692
{
1693
    FT0 = float64_div(FT0, FT1, &env->fp_status);
1694
    RETURN();
1695
}
1696

    
1697
/* fsqrt - fsqrt. */
1698
void OPPROTO op_fsqrt (void)
1699
{
1700
    do_fsqrt();
1701
    RETURN();
1702
}
1703

    
1704
/* fres - fres. */
1705
void OPPROTO op_fres (void)
1706
{
1707
    do_fres();
1708
    RETURN();
1709
}
1710

    
1711
/* frsqrte  - frsqrte. */
1712
void OPPROTO op_frsqrte (void)
1713
{
1714
    do_frsqrte();
1715
    RETURN();
1716
}
1717

    
1718
/* fsel - fsel. */
1719
void OPPROTO op_fsel (void)
1720
{
1721
    do_fsel();
1722
    RETURN();
1723
}
1724

    
1725
/***                     Floating-Point multiply-and-add                   ***/
1726
/* fmadd - fmadd. */
1727
void OPPROTO op_fmadd (void)
1728
{
1729
#if USE_PRECISE_EMULATION
1730
    do_fmadd();
1731
#else
1732
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1733
    FT0 = float64_add(FT0, FT2, &env->fp_status);
1734
#endif
1735
    RETURN();
1736
}
1737

    
1738
/* fmsub - fmsub. */
1739
void OPPROTO op_fmsub (void)
1740
{
1741
#if USE_PRECISE_EMULATION
1742
    do_fmsub();
1743
#else
1744
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1745
    FT0 = float64_sub(FT0, FT2, &env->fp_status);
1746
#endif
1747
    RETURN();
1748
}
1749

    
1750
/* fnmadd - fnmadd. - fnmadds - fnmadds. */
1751
void OPPROTO op_fnmadd (void)
1752
{
1753
    do_fnmadd();
1754
    RETURN();
1755
}
1756

    
1757
/* fnmsub - fnmsub. */
1758
void OPPROTO op_fnmsub (void)
1759
{
1760
    do_fnmsub();
1761
    RETURN();
1762
}
1763

    
1764
/***                     Floating-Point round & convert                    ***/
1765
/* frsp - frsp. */
1766
void OPPROTO op_frsp (void)
1767
{
1768
    FT0 = float64_to_float32(FT0, &env->fp_status);
1769
    RETURN();
1770
}
1771

    
1772
/* fctiw - fctiw. */
1773
void OPPROTO op_fctiw (void)
1774
{
1775
    do_fctiw();
1776
    RETURN();
1777
}
1778

    
1779
/* fctiwz - fctiwz. */
1780
void OPPROTO op_fctiwz (void)
1781
{
1782
    do_fctiwz();
1783
    RETURN();
1784
}
1785

    
1786
#if defined(TARGET_PPC64)
1787
/* fcfid - fcfid. */
1788
void OPPROTO op_fcfid (void)
1789
{
1790
    do_fcfid();
1791
    RETURN();
1792
}
1793

    
1794
/* fctid - fctid. */
1795
void OPPROTO op_fctid (void)
1796
{
1797
    do_fctid();
1798
    RETURN();
1799
}
1800

    
1801
/* fctidz - fctidz. */
1802
void OPPROTO op_fctidz (void)
1803
{
1804
    do_fctidz();
1805
    RETURN();
1806
}
1807
#endif
1808

    
1809
/***                         Floating-Point compare                        ***/
1810
/* fcmpu */
1811
void OPPROTO op_fcmpu (void)
1812
{
1813
    do_fcmpu();
1814
    RETURN();
1815
}
1816

    
1817
/* fcmpo */
1818
void OPPROTO op_fcmpo (void)
1819
{
1820
    do_fcmpo();
1821
    RETURN();
1822
}
1823

    
1824
/***                         Floating-point move                           ***/
1825
/* fabs */
1826
void OPPROTO op_fabs (void)
1827
{
1828
    FT0 = float64_abs(FT0);
1829
    RETURN();
1830
}
1831

    
1832
/* fnabs */
1833
void OPPROTO op_fnabs (void)
1834
{
1835
    FT0 = float64_abs(FT0);
1836
    FT0 = float64_chs(FT0);
1837
    RETURN();
1838
}
1839

    
1840
/* fneg */
1841
void OPPROTO op_fneg (void)
1842
{
1843
    FT0 = float64_chs(FT0);
1844
    RETURN();
1845
}
1846

    
1847
/* Load and store */
1848
#define MEMSUFFIX _raw
1849
#include "op_helper.h"
1850
#include "op_mem.h"
1851
#if !defined(CONFIG_USER_ONLY)
1852
#define MEMSUFFIX _user
1853
#include "op_helper.h"
1854
#include "op_mem.h"
1855
#define MEMSUFFIX _kernel
1856
#include "op_helper.h"
1857
#include "op_mem.h"
1858
#endif
1859

    
1860
/* Special op to check and maybe clear reservation */
1861
void OPPROTO op_check_reservation (void)
1862
{
1863
    if ((uint32_t)env->reserve == (uint32_t)(T0 & ~0x00000003))
1864
        env->reserve = -1;
1865
    RETURN();
1866
}
1867

    
1868
#if defined(TARGET_PPC64)
1869
void OPPROTO op_check_reservation_64 (void)
1870
{
1871
    if ((uint64_t)env->reserve == (uint64_t)(T0 & ~0x00000003))
1872
        env->reserve = -1;
1873
    RETURN();
1874
}
1875
#endif
1876

    
1877
/* Return from interrupt */
1878
#if !defined(CONFIG_USER_ONLY)
1879
void OPPROTO op_rfi (void)
1880
{
1881
    do_rfi();
1882
    RETURN();
1883
}
1884

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

    
1894
/* Trap word */
1895
void OPPROTO op_tw (void)
1896
{
1897
    do_tw(PARAM1);
1898
    RETURN();
1899
}
1900

    
1901
#if defined(TARGET_PPC64)
1902
void OPPROTO op_td (void)
1903
{
1904
    do_td(PARAM1);
1905
    RETURN();
1906
}
1907
#endif
1908

    
1909
#if !defined(CONFIG_USER_ONLY)
1910
/* tlbia */
1911
void OPPROTO op_tlbia (void)
1912
{
1913
    do_tlbia();
1914
    RETURN();
1915
}
1916

    
1917
/* tlbie */
1918
void OPPROTO op_tlbie (void)
1919
{
1920
    do_tlbie();
1921
    RETURN();
1922
}
1923

    
1924
#if defined(TARGET_PPC64)
1925
void OPPROTO op_tlbie_64 (void)
1926
{
1927
    do_tlbie_64();
1928
    RETURN();
1929
}
1930
#endif
1931

    
1932
#if defined(TARGET_PPC64)
1933
void OPPROTO op_slbia (void)
1934
{
1935
    do_slbia();
1936
    RETURN();
1937
}
1938

    
1939
void OPPROTO op_slbie (void)
1940
{
1941
    do_slbie();
1942
    RETURN();
1943
}
1944
#endif
1945
#endif
1946

    
1947
/* PowerPC 602/603/755 software TLB load instructions */
1948
#if !defined(CONFIG_USER_ONLY)
1949
void OPPROTO op_6xx_tlbld (void)
1950
{
1951
    do_load_6xx_tlb(0);
1952
    RETURN();
1953
}
1954

    
1955
void OPPROTO op_6xx_tlbli (void)
1956
{
1957
    do_load_6xx_tlb(1);
1958
    RETURN();
1959
}
1960
#endif
1961

    
1962
/* 601 specific */
1963
void OPPROTO op_load_601_rtcl (void)
1964
{
1965
    T0 = cpu_ppc601_load_rtcl(env);
1966
    RETURN();
1967
}
1968

    
1969
void OPPROTO op_load_601_rtcu (void)
1970
{
1971
    T0 = cpu_ppc601_load_rtcu(env);
1972
    RETURN();
1973
}
1974

    
1975
#if !defined(CONFIG_USER_ONLY)
1976
void OPPROTO op_store_601_rtcl (void)
1977
{
1978
    cpu_ppc601_store_rtcl(env, T0);
1979
    RETURN();
1980
}
1981

    
1982
void OPPROTO op_store_601_rtcu (void)
1983
{
1984
    cpu_ppc601_store_rtcu(env, T0);
1985
    RETURN();
1986
}
1987

    
1988
void OPPROTO op_load_601_bat (void)
1989
{
1990
    T0 = env->IBAT[PARAM1][PARAM2];
1991
    RETURN();
1992
}
1993
#endif /* !defined(CONFIG_USER_ONLY) */
1994

    
1995
/* 601 unified BATs store.
1996
 * To avoid using specific MMU code for 601, we store BATs in
1997
 * IBAT and DBAT simultaneously, then emulate unified BATs.
1998
 */
1999
#if !defined(CONFIG_USER_ONLY)
2000
void OPPROTO op_store_601_batl (void)
2001
{
2002
    int nr = PARAM1;
2003

    
2004
    env->IBAT[1][nr] = T0;
2005
    env->DBAT[1][nr] = T0;
2006
    RETURN();
2007
}
2008

    
2009
void OPPROTO op_store_601_batu (void)
2010
{
2011
    do_store_601_batu(PARAM1);
2012
    RETURN();
2013
}
2014
#endif /* !defined(CONFIG_USER_ONLY) */
2015

    
2016
/* PowerPC 601 specific instructions (POWER bridge) */
2017
/* XXX: those micro-ops need tests ! */
2018
void OPPROTO op_POWER_abs (void)
2019
{
2020
    if (T0 == INT32_MIN)
2021
        T0 = INT32_MAX;
2022
    else if (T0 < 0)
2023
        T0 = -T0;
2024
    RETURN();
2025
}
2026

    
2027
void OPPROTO op_POWER_abso (void)
2028
{
2029
    do_POWER_abso();
2030
    RETURN();
2031
}
2032

    
2033
void OPPROTO op_POWER_clcs (void)
2034
{
2035
    do_POWER_clcs();
2036
    RETURN();
2037
}
2038

    
2039
void OPPROTO op_POWER_div (void)
2040
{
2041
    do_POWER_div();
2042
    RETURN();
2043
}
2044

    
2045
void OPPROTO op_POWER_divo (void)
2046
{
2047
    do_POWER_divo();
2048
    RETURN();
2049
}
2050

    
2051
void OPPROTO op_POWER_divs (void)
2052
{
2053
    do_POWER_divs();
2054
    RETURN();
2055
}
2056

    
2057
void OPPROTO op_POWER_divso (void)
2058
{
2059
    do_POWER_divso();
2060
    RETURN();
2061
}
2062

    
2063
void OPPROTO op_POWER_doz (void)
2064
{
2065
    if ((int32_t)T1 > (int32_t)T0)
2066
        T0 = T1 - T0;
2067
    else
2068
        T0 = 0;
2069
    RETURN();
2070
}
2071

    
2072
void OPPROTO op_POWER_dozo (void)
2073
{
2074
    do_POWER_dozo();
2075
    RETURN();
2076
}
2077

    
2078
void OPPROTO op_load_xer_cmp (void)
2079
{
2080
    T2 = xer_cmp;
2081
    RETURN();
2082
}
2083

    
2084
void OPPROTO op_POWER_maskg (void)
2085
{
2086
    do_POWER_maskg();
2087
    RETURN();
2088
}
2089

    
2090
void OPPROTO op_POWER_maskir (void)
2091
{
2092
    T0 = (T0 & ~T2) | (T1 & T2);
2093
    RETURN();
2094
}
2095

    
2096
void OPPROTO op_POWER_mul (void)
2097
{
2098
    uint64_t tmp;
2099

    
2100
    tmp = (uint64_t)T0 * (uint64_t)T1;
2101
    env->spr[SPR_MQ] = tmp >> 32;
2102
    T0 = tmp;
2103
    RETURN();
2104
}
2105

    
2106
void OPPROTO op_POWER_mulo (void)
2107
{
2108
    do_POWER_mulo();
2109
    RETURN();
2110
}
2111

    
2112
void OPPROTO op_POWER_nabs (void)
2113
{
2114
    if (T0 > 0)
2115
        T0 = -T0;
2116
    RETURN();
2117
}
2118

    
2119
void OPPROTO op_POWER_nabso (void)
2120
{
2121
    /* nabs never overflows */
2122
    if (T0 > 0)
2123
        T0 = -T0;
2124
    xer_ov = 0;
2125
    RETURN();
2126
}
2127

    
2128
/* XXX: factorise POWER rotates... */
2129
void OPPROTO op_POWER_rlmi (void)
2130
{
2131
    T0 = rotl32(T0, T2) & PARAM1;
2132
    T0 |= T1 & PARAM2;
2133
    RETURN();
2134
}
2135

    
2136
void OPPROTO op_POWER_rrib (void)
2137
{
2138
    T2 &= 0x1FUL;
2139
    T0 = rotl32(T0 & INT32_MIN, T2);
2140
    T0 |= T1 & ~rotl32(INT32_MIN, T2);
2141
    RETURN();
2142
}
2143

    
2144
void OPPROTO op_POWER_sle (void)
2145
{
2146
    T1 &= 0x1FUL;
2147
    env->spr[SPR_MQ] = rotl32(T0, T1);
2148
    T0 = T0 << T1;
2149
    RETURN();
2150
}
2151

    
2152
void OPPROTO op_POWER_sleq (void)
2153
{
2154
    uint32_t tmp = env->spr[SPR_MQ];
2155

    
2156
    T1 &= 0x1FUL;
2157
    env->spr[SPR_MQ] = rotl32(T0, T1);
2158
    T0 = T0 << T1;
2159
    T0 |= tmp >> (32 - T1);
2160
    RETURN();
2161
}
2162

    
2163
void OPPROTO op_POWER_sllq (void)
2164
{
2165
    uint32_t msk = -1;
2166

    
2167
    msk = msk << (T1 & 0x1FUL);
2168
    if (T1 & 0x20UL)
2169
        msk = ~msk;
2170
    T1 &= 0x1FUL;
2171
    T0 = (T0 << T1) & msk;
2172
    T0 |= env->spr[SPR_MQ] & ~msk;
2173
    RETURN();
2174
}
2175

    
2176
void OPPROTO op_POWER_slq (void)
2177
{
2178
    uint32_t msk = -1, tmp;
2179

    
2180
    msk = msk << (T1 & 0x1FUL);
2181
    if (T1 & 0x20UL)
2182
        msk = ~msk;
2183
    T1 &= 0x1FUL;
2184
    tmp = rotl32(T0, T1);
2185
    T0 = tmp & msk;
2186
    env->spr[SPR_MQ] = tmp;
2187
    RETURN();
2188
}
2189

    
2190
void OPPROTO op_POWER_sraq (void)
2191
{
2192
    env->spr[SPR_MQ] = rotl32(T0, 32 - (T1 & 0x1FUL));
2193
    if (T1 & 0x20UL)
2194
        T0 = -1L;
2195
    else
2196
        T0 = (int32_t)T0 >> T1;
2197
    RETURN();
2198
}
2199

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

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

    
2216
void OPPROTO op_POWER_sreq (void)
2217
{
2218
    uint32_t tmp;
2219
    int32_t msk;
2220

    
2221
    T1 &= 0x1FUL;
2222
    msk = INT32_MIN >> T1;
2223
    tmp = env->spr[SPR_MQ];
2224
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2225
    T0 = T0 >> T1;
2226
    T0 |= tmp & msk;
2227
    RETURN();
2228
}
2229

    
2230
void OPPROTO op_POWER_srlq (void)
2231
{
2232
    uint32_t tmp;
2233
    int32_t msk;
2234

    
2235
    msk = INT32_MIN >> (T1 & 0x1FUL);
2236
    if (T1 & 0x20UL)
2237
        msk = ~msk;
2238
    T1 &= 0x1FUL;
2239
    tmp = env->spr[SPR_MQ];
2240
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2241
    T0 = T0 >> T1;
2242
    T0 &= msk;
2243
    T0 |= tmp & ~msk;
2244
    RETURN();
2245
}
2246

    
2247
void OPPROTO op_POWER_srq (void)
2248
{
2249
    T1 &= 0x1FUL;
2250
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2251
    T0 = T0 >> T1;
2252
    RETURN();
2253
}
2254

    
2255
/* POWER instructions not implemented in PowerPC 601 */
2256
#if !defined(CONFIG_USER_ONLY)
2257
void OPPROTO op_POWER_mfsri (void)
2258
{
2259
    T1 = T0 >> 28;
2260
    T0 = env->sr[T1];
2261
    RETURN();
2262
}
2263

    
2264
void OPPROTO op_POWER_rac (void)
2265
{
2266
    do_POWER_rac();
2267
    RETURN();
2268
}
2269

    
2270
void OPPROTO op_POWER_rfsvc (void)
2271
{
2272
    do_POWER_rfsvc();
2273
    RETURN();
2274
}
2275
#endif
2276

    
2277
/* PowerPC 602 specific instruction */
2278
#if !defined(CONFIG_USER_ONLY)
2279
void OPPROTO op_602_mfrom (void)
2280
{
2281
    do_op_602_mfrom();
2282
    RETURN();
2283
}
2284
#endif
2285

    
2286
/* PowerPC 4xx specific micro-ops */
2287
void OPPROTO op_405_add_T0_T2 (void)
2288
{
2289
    T0 = (int32_t)T0 + (int32_t)T2;
2290
    RETURN();
2291
}
2292

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

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

    
2305
void OPPROTO op_405_mulhhw (void)
2306
{
2307
    T0 = ((int16_t)(T0 >> 16)) * ((int16_t)(T1 >> 16));
2308
    RETURN();
2309
}
2310

    
2311
void OPPROTO op_405_mulhhwu (void)
2312
{
2313
    T0 = ((uint16_t)(T0 >> 16)) * ((uint16_t)(T1 >> 16));
2314
    RETURN();
2315
}
2316

    
2317
void OPPROTO op_405_mullhw (void)
2318
{
2319
    T0 = ((int16_t)T0) * ((int16_t)T1);
2320
    RETURN();
2321
}
2322

    
2323
void OPPROTO op_405_mullhwu (void)
2324
{
2325
    T0 = ((uint16_t)T0) * ((uint16_t)T1);
2326
    RETURN();
2327
}
2328

    
2329
void OPPROTO op_405_check_ov (void)
2330
{
2331
    do_405_check_ov();
2332
    RETURN();
2333
}
2334

    
2335
void OPPROTO op_405_check_sat (void)
2336
{
2337
    do_405_check_sat();
2338
    RETURN();
2339
}
2340

    
2341
void OPPROTO op_405_check_ovu (void)
2342
{
2343
    if (likely(T0 >= T2)) {
2344
        xer_ov = 0;
2345
    } else {
2346
        xer_ov = 1;
2347
        xer_so = 1;
2348
    }
2349
    RETURN();
2350
}
2351

    
2352
void OPPROTO op_405_check_satu (void)
2353
{
2354
    if (unlikely(T0 < T2)) {
2355
        /* Saturate result */
2356
        T0 = -1;
2357
    }
2358
    RETURN();
2359
}
2360

    
2361
void OPPROTO op_load_dcr (void)
2362
{
2363
    do_load_dcr();
2364
    RETURN();
2365
}
2366

    
2367
void OPPROTO op_store_dcr (void)
2368
{
2369
    do_store_dcr();
2370
    RETURN();
2371
}
2372

    
2373
#if !defined(CONFIG_USER_ONLY)
2374
/* Return from critical interrupt :
2375
 * same as rfi, except nip & MSR are loaded from SRR2/3 instead of SRR0/1
2376
 */
2377
void OPPROTO op_40x_rfci (void)
2378
{
2379
    do_40x_rfci();
2380
    RETURN();
2381
}
2382

    
2383
void OPPROTO op_rfci (void)
2384
{
2385
    do_rfci();
2386
    RETURN();
2387
}
2388

    
2389
void OPPROTO op_rfdi (void)
2390
{
2391
    do_rfdi();
2392
    RETURN();
2393
}
2394

    
2395
void OPPROTO op_rfmci (void)
2396
{
2397
    do_rfmci();
2398
    RETURN();
2399
}
2400

    
2401
void OPPROTO op_wrte (void)
2402
{
2403
    msr_ee = T0 >> 16;
2404
    RETURN();
2405
}
2406

    
2407
void OPPROTO op_440_tlbre (void)
2408
{
2409
    do_440_tlbre(PARAM1);
2410
    RETURN();
2411
}
2412

    
2413
void OPPROTO op_440_tlbsx (void)
2414
{
2415
    do_440_tlbsx();
2416
    RETURN();
2417
}
2418

    
2419
void OPPROTO op_440_tlbsx_ (void)
2420
{
2421
    do_440_tlbsx_();
2422
    RETURN();
2423
}
2424

    
2425
void OPPROTO op_440_tlbwe (void)
2426
{
2427
    do_440_tlbwe(PARAM1);
2428
    RETURN();
2429
}
2430

    
2431
void OPPROTO op_4xx_tlbre_lo (void)
2432
{
2433
    do_4xx_tlbre_lo();
2434
    RETURN();
2435
}
2436

    
2437
void OPPROTO op_4xx_tlbre_hi (void)
2438
{
2439
    do_4xx_tlbre_hi();
2440
    RETURN();
2441
}
2442

    
2443
void OPPROTO op_4xx_tlbsx (void)
2444
{
2445
    do_4xx_tlbsx();
2446
    RETURN();
2447
}
2448

    
2449
void OPPROTO op_4xx_tlbsx_ (void)
2450
{
2451
    do_4xx_tlbsx_();
2452
    RETURN();
2453
}
2454

    
2455
void OPPROTO op_4xx_tlbwe_lo (void)
2456
{
2457
    do_4xx_tlbwe_lo();
2458
    RETURN();
2459
}
2460

    
2461
void OPPROTO op_4xx_tlbwe_hi (void)
2462
{
2463
    do_4xx_tlbwe_hi();
2464
    RETURN();
2465
}
2466
#endif
2467

    
2468
/* SPR micro-ops */
2469
/* 440 specific */
2470
void OPPROTO op_440_dlmzb (void)
2471
{
2472
    do_440_dlmzb();
2473
    RETURN();
2474
}
2475

    
2476
void OPPROTO op_440_dlmzb_update_Rc (void)
2477
{
2478
    if (T0 == 8)
2479
        T0 = 0x2;
2480
    else if (T0 < 4)
2481
        T0 = 0x4;
2482
    else
2483
        T0 = 0x8;
2484
    RETURN();
2485
}
2486

    
2487
#if !defined(CONFIG_USER_ONLY)
2488
void OPPROTO op_store_pir (void)
2489
{
2490
    env->spr[SPR_PIR] = T0 & 0x0000000FUL;
2491
    RETURN();
2492
}
2493

    
2494
void OPPROTO op_load_403_pb (void)
2495
{
2496
    do_load_403_pb(PARAM1);
2497
    RETURN();
2498
}
2499

    
2500
void OPPROTO op_store_403_pb (void)
2501
{
2502
    do_store_403_pb(PARAM1);
2503
    RETURN();
2504
}
2505

    
2506
void OPPROTO op_load_40x_pit (void)
2507
{
2508
    T0 = load_40x_pit(env);
2509
    RETURN();
2510
}
2511

    
2512
void OPPROTO op_store_40x_pit (void)
2513
{
2514
    store_40x_pit(env, T0);
2515
    RETURN();
2516
}
2517

    
2518
void OPPROTO op_store_40x_dbcr0 (void)
2519
{
2520
    store_40x_dbcr0(env, T0);
2521
}
2522

    
2523
void OPPROTO op_store_40x_sler (void)
2524
{
2525
    store_40x_sler(env, T0);
2526
    RETURN();
2527
}
2528

    
2529
void OPPROTO op_store_booke_tcr (void)
2530
{
2531
    store_booke_tcr(env, T0);
2532
    RETURN();
2533
}
2534

    
2535
void OPPROTO op_store_booke_tsr (void)
2536
{
2537
    store_booke_tsr(env, T0);
2538
    RETURN();
2539
}
2540

    
2541
#endif /* !defined(CONFIG_USER_ONLY) */
2542

    
2543
#if defined(TARGET_PPCEMB)
2544
/* SPE extension */
2545
void OPPROTO op_splatw_T1_64 (void)
2546
{
2547
    T1_64 = (T1_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL);
2548
    RETURN();
2549
}
2550

    
2551
void OPPROTO op_splatwi_T0_64 (void)
2552
{
2553
    uint64_t tmp = PARAM1;
2554

    
2555
    T0_64 = (tmp << 32) | tmp;
2556
    RETURN();
2557
}
2558

    
2559
void OPPROTO op_splatwi_T1_64 (void)
2560
{
2561
    uint64_t tmp = PARAM1;
2562

    
2563
    T1_64 = (tmp << 32) | tmp;
2564
    RETURN();
2565
}
2566

    
2567
void OPPROTO op_extsh_T1_64 (void)
2568
{
2569
    T1_64 = (int32_t)((int16_t)T1_64);
2570
    RETURN();
2571
}
2572

    
2573
void OPPROTO op_sli16_T1_64 (void)
2574
{
2575
    T1_64 = T1_64 << 16;
2576
    RETURN();
2577
}
2578

    
2579
void OPPROTO op_sli32_T1_64 (void)
2580
{
2581
    T1_64 = T1_64 << 32;
2582
    RETURN();
2583
}
2584

    
2585
void OPPROTO op_srli32_T1_64 (void)
2586
{
2587
    T1_64 = T1_64 >> 32;
2588
    RETURN();
2589
}
2590

    
2591
void OPPROTO op_evsel (void)
2592
{
2593
    do_evsel();
2594
    RETURN();
2595
}
2596

    
2597
void OPPROTO op_evaddw (void)
2598
{
2599
    do_evaddw();
2600
    RETURN();
2601
}
2602

    
2603
void OPPROTO op_evsubfw (void)
2604
{
2605
    do_evsubfw();
2606
    RETURN();
2607
}
2608

    
2609
void OPPROTO op_evneg (void)
2610
{
2611
    do_evneg();
2612
    RETURN();
2613
}
2614

    
2615
void OPPROTO op_evabs (void)
2616
{
2617
    do_evabs();
2618
    RETURN();
2619
}
2620

    
2621
void OPPROTO op_evextsh (void)
2622
{
2623
    T0_64 = ((uint64_t)((int32_t)(int16_t)(T0_64 >> 32)) << 32) |
2624
        (uint64_t)((int32_t)(int16_t)T0_64);
2625
    RETURN();
2626
}
2627

    
2628
void OPPROTO op_evextsb (void)
2629
{
2630
    T0_64 = ((uint64_t)((int32_t)(int8_t)(T0_64 >> 32)) << 32) |
2631
        (uint64_t)((int32_t)(int8_t)T0_64);
2632
    RETURN();
2633
}
2634

    
2635
void OPPROTO op_evcntlzw (void)
2636
{
2637
    do_evcntlzw();
2638
    RETURN();
2639
}
2640

    
2641
void OPPROTO op_evrndw (void)
2642
{
2643
    do_evrndw();
2644
    RETURN();
2645
}
2646

    
2647
void OPPROTO op_brinc (void)
2648
{
2649
    do_brinc();
2650
    RETURN();
2651
}
2652

    
2653
void OPPROTO op_evcntlsw (void)
2654
{
2655
    do_evcntlsw();
2656
    RETURN();
2657
}
2658

    
2659
void OPPROTO op_evand (void)
2660
{
2661
    T0_64 &= T1_64;
2662
    RETURN();
2663
}
2664

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

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

    
2677
void OPPROTO op_evxor (void)
2678
{
2679
    T0_64 ^= T1_64;
2680
    RETURN();
2681
}
2682

    
2683
void OPPROTO op_eveqv (void)
2684
{
2685
    T0_64 = ~(T0_64 ^ T1_64);
2686
    RETURN();
2687
}
2688

    
2689
void OPPROTO op_evnor (void)
2690
{
2691
    T0_64 = ~(T0_64 | T1_64);
2692
    RETURN();
2693
}
2694

    
2695
void OPPROTO op_evorc (void)
2696
{
2697
    T0_64 |= ~T1_64;
2698
    RETURN();
2699
}
2700

    
2701
void OPPROTO op_evnand (void)
2702
{
2703
    T0_64 = ~(T0_64 & T1_64);
2704
    RETURN();
2705
}
2706

    
2707
void OPPROTO op_evsrws (void)
2708
{
2709
    do_evsrws();
2710
    RETURN();
2711
}
2712

    
2713
void OPPROTO op_evsrwu (void)
2714
{
2715
    do_evsrwu();
2716
    RETURN();
2717
}
2718

    
2719
void OPPROTO op_evslw (void)
2720
{
2721
    do_evslw();
2722
    RETURN();
2723
}
2724

    
2725
void OPPROTO op_evrlw (void)
2726
{
2727
    do_evrlw();
2728
    RETURN();
2729
}
2730

    
2731
void OPPROTO op_evmergelo (void)
2732
{
2733
    T0_64 = (T0_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL);
2734
    RETURN();
2735
}
2736

    
2737
void OPPROTO op_evmergehi (void)
2738
{
2739
    T0_64 = (T0_64 & 0xFFFFFFFF00000000ULL) | (T1_64 >> 32);
2740
    RETURN();
2741
}
2742

    
2743
void OPPROTO op_evmergelohi (void)
2744
{
2745
    T0_64 = (T0_64 << 32) | (T1_64 >> 32);
2746
    RETURN();
2747
}
2748

    
2749
void OPPROTO op_evmergehilo (void)
2750
{
2751
    T0_64 = (T0_64 & 0xFFFFFFFF00000000ULL) | (T1_64 & 0x00000000FFFFFFFFULL);
2752
    RETURN();
2753
}
2754

    
2755
void OPPROTO op_evcmpgts (void)
2756
{
2757
    do_evcmpgts();
2758
    RETURN();
2759
}
2760

    
2761
void OPPROTO op_evcmpgtu (void)
2762
{
2763
    do_evcmpgtu();
2764
    RETURN();
2765
}
2766

    
2767
void OPPROTO op_evcmplts (void)
2768
{
2769
    do_evcmplts();
2770
    RETURN();
2771
}
2772

    
2773
void OPPROTO op_evcmpltu (void)
2774
{
2775
    do_evcmpltu();
2776
    RETURN();
2777
}
2778

    
2779
void OPPROTO op_evcmpeq (void)
2780
{
2781
    do_evcmpeq();
2782
    RETURN();
2783
}
2784

    
2785
void OPPROTO op_evfssub (void)
2786
{
2787
    do_evfssub();
2788
    RETURN();
2789
}
2790

    
2791
void OPPROTO op_evfsadd (void)
2792
{
2793
    do_evfsadd();
2794
    RETURN();
2795
}
2796

    
2797
void OPPROTO op_evfsnabs (void)
2798
{
2799
    do_evfsnabs();
2800
    RETURN();
2801
}
2802

    
2803
void OPPROTO op_evfsabs (void)
2804
{
2805
    do_evfsabs();
2806
    RETURN();
2807
}
2808

    
2809
void OPPROTO op_evfsneg (void)
2810
{
2811
    do_evfsneg();
2812
    RETURN();
2813
}
2814

    
2815
void OPPROTO op_evfsdiv (void)
2816
{
2817
    do_evfsdiv();
2818
    RETURN();
2819
}
2820

    
2821
void OPPROTO op_evfsmul (void)
2822
{
2823
    do_evfsmul();
2824
    RETURN();
2825
}
2826

    
2827
void OPPROTO op_evfscmplt (void)
2828
{
2829
    do_evfscmplt();
2830
    RETURN();
2831
}
2832

    
2833
void OPPROTO op_evfscmpgt (void)
2834
{
2835
    do_evfscmpgt();
2836
    RETURN();
2837
}
2838

    
2839
void OPPROTO op_evfscmpeq (void)
2840
{
2841
    do_evfscmpeq();
2842
    RETURN();
2843
}
2844

    
2845
void OPPROTO op_evfscfsi (void)
2846
{
2847
    do_evfscfsi();
2848
    RETURN();
2849
}
2850

    
2851
void OPPROTO op_evfscfui (void)
2852
{
2853
    do_evfscfui();
2854
    RETURN();
2855
}
2856

    
2857
void OPPROTO op_evfscfsf (void)
2858
{
2859
    do_evfscfsf();
2860
    RETURN();
2861
}
2862

    
2863
void OPPROTO op_evfscfuf (void)
2864
{
2865
    do_evfscfuf();
2866
    RETURN();
2867
}
2868

    
2869
void OPPROTO op_evfsctsi (void)
2870
{
2871
    do_evfsctsi();
2872
    RETURN();
2873
}
2874

    
2875
void OPPROTO op_evfsctui (void)
2876
{
2877
    do_evfsctui();
2878
    RETURN();
2879
}
2880

    
2881
void OPPROTO op_evfsctsf (void)
2882
{
2883
    do_evfsctsf();
2884
    RETURN();
2885
}
2886

    
2887
void OPPROTO op_evfsctuf (void)
2888
{
2889
    do_evfsctuf();
2890
    RETURN();
2891
}
2892

    
2893
void OPPROTO op_evfsctuiz (void)
2894
{
2895
    do_evfsctuiz();
2896
    RETURN();
2897
}
2898

    
2899
void OPPROTO op_evfsctsiz (void)
2900
{
2901
    do_evfsctsiz();
2902
    RETURN();
2903
}
2904

    
2905
void OPPROTO op_evfststlt (void)
2906
{
2907
    do_evfststlt();
2908
    RETURN();
2909
}
2910

    
2911
void OPPROTO op_evfststgt (void)
2912
{
2913
    do_evfststgt();
2914
    RETURN();
2915
}
2916

    
2917
void OPPROTO op_evfststeq (void)
2918
{
2919
    do_evfststeq();
2920
    RETURN();
2921
}
2922

    
2923
void OPPROTO op_efssub (void)
2924
{
2925
    T0_64 = _do_efssub(T0_64, T1_64);
2926
    RETURN();
2927
}
2928

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

    
2935
void OPPROTO op_efsnabs (void)
2936
{
2937
    T0_64 = _do_efsnabs(T0_64);
2938
    RETURN();
2939
}
2940

    
2941
void OPPROTO op_efsabs (void)
2942
{
2943
    T0_64 = _do_efsabs(T0_64);
2944
    RETURN();
2945
}
2946

    
2947
void OPPROTO op_efsneg (void)
2948
{
2949
    T0_64 = _do_efsneg(T0_64);
2950
    RETURN();
2951
}
2952

    
2953
void OPPROTO op_efsdiv (void)
2954
{
2955
    T0_64 = _do_efsdiv(T0_64, T1_64);
2956
    RETURN();
2957
}
2958

    
2959
void OPPROTO op_efsmul (void)
2960
{
2961
    T0_64 = _do_efsmul(T0_64, T1_64);
2962
    RETURN();
2963
}
2964

    
2965
void OPPROTO op_efscmplt (void)
2966
{
2967
    do_efscmplt();
2968
    RETURN();
2969
}
2970

    
2971
void OPPROTO op_efscmpgt (void)
2972
{
2973
    do_efscmpgt();
2974
    RETURN();
2975
}
2976

    
2977
void OPPROTO op_efscfd (void)
2978
{
2979
    do_efscfd();
2980
    RETURN();
2981
}
2982

    
2983
void OPPROTO op_efscmpeq (void)
2984
{
2985
    do_efscmpeq();
2986
    RETURN();
2987
}
2988

    
2989
void OPPROTO op_efscfsi (void)
2990
{
2991
    do_efscfsi();
2992
    RETURN();
2993
}
2994

    
2995
void OPPROTO op_efscfui (void)
2996
{
2997
    do_efscfui();
2998
    RETURN();
2999
}
3000

    
3001
void OPPROTO op_efscfsf (void)
3002
{
3003
    do_efscfsf();
3004
    RETURN();
3005
}
3006

    
3007
void OPPROTO op_efscfuf (void)
3008
{
3009
    do_efscfuf();
3010
    RETURN();
3011
}
3012

    
3013
void OPPROTO op_efsctsi (void)
3014
{
3015
    do_efsctsi();
3016
    RETURN();
3017
}
3018

    
3019
void OPPROTO op_efsctui (void)
3020
{
3021
    do_efsctui();
3022
    RETURN();
3023
}
3024

    
3025
void OPPROTO op_efsctsf (void)
3026
{
3027
    do_efsctsf();
3028
    RETURN();
3029
}
3030

    
3031
void OPPROTO op_efsctuf (void)
3032
{
3033
    do_efsctuf();
3034
    RETURN();
3035
}
3036

    
3037
void OPPROTO op_efsctsiz (void)
3038
{
3039
    do_efsctsiz();
3040
    RETURN();
3041
}
3042

    
3043
void OPPROTO op_efsctuiz (void)
3044
{
3045
    do_efsctuiz();
3046
    RETURN();
3047
}
3048

    
3049
void OPPROTO op_efststlt (void)
3050
{
3051
    T0 = _do_efststlt(T0_64, T1_64);
3052
    RETURN();
3053
}
3054

    
3055
void OPPROTO op_efststgt (void)
3056
{
3057
    T0 = _do_efststgt(T0_64, T1_64);
3058
    RETURN();
3059
}
3060

    
3061
void OPPROTO op_efststeq (void)
3062
{
3063
    T0 = _do_efststeq(T0_64, T1_64);
3064
    RETURN();
3065
}
3066

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

    
3080
void OPPROTO op_efdadd (void)
3081
{
3082
    union {
3083
        uint64_t u;
3084
        float64 f;
3085
    } u1, u2;
3086
    u1.u = T0_64;
3087
    u2.u = T1_64;
3088
    u1.f = float64_add(u1.f, u2.f, &env->spe_status);
3089
    T0_64 = u1.u;
3090
    RETURN();
3091
}
3092

    
3093
void OPPROTO op_efdcfsid (void)
3094
{
3095
    do_efdcfsi();
3096
    RETURN();
3097
}
3098

    
3099
void OPPROTO op_efdcfuid (void)
3100
{
3101
    do_efdcfui();
3102
    RETURN();
3103
}
3104

    
3105
void OPPROTO op_efdnabs (void)
3106
{
3107
    T0_64 |= 0x8000000000000000ULL;
3108
    RETURN();
3109
}
3110

    
3111
void OPPROTO op_efdabs (void)
3112
{
3113
    T0_64 &= ~0x8000000000000000ULL;
3114
    RETURN();
3115
}
3116

    
3117
void OPPROTO op_efdneg (void)
3118
{
3119
    T0_64 ^= 0x8000000000000000ULL;
3120
    RETURN();
3121
}
3122

    
3123
void OPPROTO op_efddiv (void)
3124
{
3125
    union {
3126
        uint64_t u;
3127
        float64 f;
3128
    } u1, u2;
3129
    u1.u = T0_64;
3130
    u2.u = T1_64;
3131
    u1.f = float64_div(u1.f, u2.f, &env->spe_status);
3132
    T0_64 = u1.u;
3133
    RETURN();
3134
}
3135

    
3136
void OPPROTO op_efdmul (void)
3137
{
3138
    union {
3139
        uint64_t u;
3140
        float64 f;
3141
    } u1, u2;
3142
    u1.u = T0_64;
3143
    u2.u = T1_64;
3144
    u1.f = float64_mul(u1.f, u2.f, &env->spe_status);
3145
    T0_64 = u1.u;
3146
    RETURN();
3147
}
3148

    
3149
void OPPROTO op_efdctsidz (void)
3150
{
3151
    do_efdctsiz();
3152
    RETURN();
3153
}
3154

    
3155
void OPPROTO op_efdctuidz (void)
3156
{
3157
    do_efdctuiz();
3158
    RETURN();
3159
}
3160

    
3161
void OPPROTO op_efdcmplt (void)
3162
{
3163
    do_efdcmplt();
3164
    RETURN();
3165
}
3166

    
3167
void OPPROTO op_efdcmpgt (void)
3168
{
3169
    do_efdcmpgt();
3170
    RETURN();
3171
}
3172

    
3173
void OPPROTO op_efdcfs (void)
3174
{
3175
    do_efdcfs();
3176
    RETURN();
3177
}
3178

    
3179
void OPPROTO op_efdcmpeq (void)
3180
{
3181
    do_efdcmpeq();
3182
    RETURN();
3183
}
3184

    
3185
void OPPROTO op_efdcfsi (void)
3186
{
3187
    do_efdcfsi();
3188
    RETURN();
3189
}
3190

    
3191
void OPPROTO op_efdcfui (void)
3192
{
3193
    do_efdcfui();
3194
    RETURN();
3195
}
3196

    
3197
void OPPROTO op_efdcfsf (void)
3198
{
3199
    do_efdcfsf();
3200
    RETURN();
3201
}
3202

    
3203
void OPPROTO op_efdcfuf (void)
3204
{
3205
    do_efdcfuf();
3206
    RETURN();
3207
}
3208

    
3209
void OPPROTO op_efdctsi (void)
3210
{
3211
    do_efdctsi();
3212
    RETURN();
3213
}
3214

    
3215
void OPPROTO op_efdctui (void)
3216
{
3217
    do_efdctui();
3218
    RETURN();
3219
}
3220

    
3221
void OPPROTO op_efdctsf (void)
3222
{
3223
    do_efdctsf();
3224
    RETURN();
3225
}
3226

    
3227
void OPPROTO op_efdctuf (void)
3228
{
3229
    do_efdctuf();
3230
    RETURN();
3231
}
3232

    
3233
void OPPROTO op_efdctuiz (void)
3234
{
3235
    do_efdctuiz();
3236
    RETURN();
3237
}
3238

    
3239
void OPPROTO op_efdctsiz (void)
3240
{
3241
    do_efdctsiz();
3242
    RETURN();
3243
}
3244

    
3245
void OPPROTO op_efdtstlt (void)
3246
{
3247
    T0 = _do_efdtstlt(T0_64, T1_64);
3248
    RETURN();
3249
}
3250

    
3251
void OPPROTO op_efdtstgt (void)
3252
{
3253
    T0 = _do_efdtstgt(T0_64, T1_64);
3254
    RETURN();
3255
}
3256

    
3257
void OPPROTO op_efdtsteq (void)
3258
{
3259
    T0 = _do_efdtsteq(T0_64, T1_64);
3260
    RETURN();
3261
}
3262
#endif /* defined(TARGET_PPCEMB) */