Statistics
| Branch: | Revision:

root / target-ppc / op.c @ b33c17e1

History | View | Annotate | Download (49.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
void OPPROTO op_print_mem_EA (void)
124
{
125
    do_print_mem_EA(T0);
126
    RETURN();
127
}
128

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
297
#if defined(TARGET_PPC64)
298
void OPPROTO op_store_pri (void)
299
{
300
    do_store_pri(PARAM1);
301
    RETURN();
302
}
303
#endif
304

    
305
#if !defined(CONFIG_USER_ONLY)
306
/* Segment registers load and store */
307
void OPPROTO op_load_sr (void)
308
{
309
    T0 = env->sr[T1];
310
    RETURN();
311
}
312

    
313
void OPPROTO op_store_sr (void)
314
{
315
    do_store_sr(env, T1, T0);
316
    RETURN();
317
}
318

    
319
#if defined(TARGET_PPC64)
320
void OPPROTO op_load_slb (void)
321
{
322
    T0 = ppc_load_slb(env, T1);
323
    RETURN();
324
}
325

    
326
void OPPROTO op_store_slb (void)
327
{
328
    ppc_store_slb(env, T1, T0);
329
    RETURN();
330
}
331
#endif /* defined(TARGET_PPC64) */
332

    
333
void OPPROTO op_load_sdr1 (void)
334
{
335
    T0 = env->sdr1;
336
    RETURN();
337
}
338

    
339
void OPPROTO op_store_sdr1 (void)
340
{
341
    do_store_sdr1(env, T0);
342
    RETURN();
343
}
344

    
345
#if defined (TARGET_PPC64)
346
void OPPROTO op_load_asr (void)
347
{
348
    T0 = env->asr;
349
    RETURN();
350
}
351

    
352
void OPPROTO op_store_asr (void)
353
{
354
    ppc_store_asr(env, T0);
355
    RETURN();
356
}
357
#endif
358

    
359
void OPPROTO op_load_msr (void)
360
{
361
    T0 = do_load_msr(env);
362
    RETURN();
363
}
364

    
365
void OPPROTO op_store_msr (void)
366
{
367
    if (do_store_msr(env, T0)) {
368
        env->halted = 1;
369
        do_raise_exception(EXCP_HLT);
370
    }
371
    RETURN();
372
}
373

    
374
void OPPROTO op_update_riee (void)
375
{
376
    msr_ri = (T0 >> MSR_RI) & 1;
377
    msr_ee = (T0 >> MSR_EE) & 1;
378
    RETURN();
379
}
380

    
381
#if defined (TARGET_PPC64)
382
void OPPROTO op_store_msr_32 (void)
383
{
384
    if (ppc_store_msr_32(env, T0)) {
385
        env->halted = 1;
386
        do_raise_exception(EXCP_HLT);
387
    }
388
    RETURN();
389
}
390
#endif
391
#endif
392

    
393
/* SPR */
394
void OPPROTO op_load_spr (void)
395
{
396
    T0 = env->spr[PARAM1];
397
    RETURN();
398
}
399

    
400
void OPPROTO op_store_spr (void)
401
{
402
    env->spr[PARAM1] = T0;
403
    RETURN();
404
}
405

    
406
void OPPROTO op_load_dump_spr (void)
407
{
408
    T0 = ppc_load_dump_spr(PARAM1);
409
    RETURN();
410
}
411

    
412
void OPPROTO op_store_dump_spr (void)
413
{
414
    ppc_store_dump_spr(PARAM1, T0);
415
    RETURN();
416
}
417

    
418
void OPPROTO op_mask_spr (void)
419
{
420
    env->spr[PARAM1] &= ~T0;
421
    RETURN();
422
}
423

    
424
void OPPROTO op_load_lr (void)
425
{
426
    T0 = env->lr;
427
    RETURN();
428
}
429

    
430
void OPPROTO op_store_lr (void)
431
{
432
    env->lr = T0;
433
    RETURN();
434
}
435

    
436
void OPPROTO op_load_ctr (void)
437
{
438
    T0 = env->ctr;
439
    RETURN();
440
}
441

    
442
void OPPROTO op_store_ctr (void)
443
{
444
    env->ctr = T0;
445
    RETURN();
446
}
447

    
448
void OPPROTO op_load_tbl (void)
449
{
450
    T0 = cpu_ppc_load_tbl(env);
451
    RETURN();
452
}
453

    
454
void OPPROTO op_load_tbu (void)
455
{
456
    T0 = cpu_ppc_load_tbu(env);
457
    RETURN();
458
}
459

    
460
void OPPROTO op_load_atbl (void)
461
{
462
    T0 = cpu_ppc_load_atbl(env);
463
    RETURN();
464
}
465

    
466
void OPPROTO op_load_atbu (void)
467
{
468
    T0 = cpu_ppc_load_atbu(env);
469
    RETURN();
470
}
471

    
472
#if !defined(CONFIG_USER_ONLY)
473
void OPPROTO op_store_tbl (void)
474
{
475
    cpu_ppc_store_tbl(env, T0);
476
    RETURN();
477
}
478

    
479
void OPPROTO op_store_tbu (void)
480
{
481
    cpu_ppc_store_tbu(env, T0);
482
    RETURN();
483
}
484

    
485
void OPPROTO op_store_atbl (void)
486
{
487
    cpu_ppc_store_atbl(env, T0);
488
    RETURN();
489
}
490

    
491
void OPPROTO op_store_atbu (void)
492
{
493
    cpu_ppc_store_atbu(env, T0);
494
    RETURN();
495
}
496

    
497
void OPPROTO op_load_decr (void)
498
{
499
    T0 = cpu_ppc_load_decr(env);
500
    RETURN();
501
}
502

    
503
void OPPROTO op_store_decr (void)
504
{
505
    cpu_ppc_store_decr(env, T0);
506
    RETURN();
507
}
508

    
509
void OPPROTO op_load_ibat (void)
510
{
511
    T0 = env->IBAT[PARAM1][PARAM2];
512
    RETURN();
513
}
514

    
515
void OPPROTO op_store_ibatu (void)
516
{
517
    do_store_ibatu(env, PARAM1, T0);
518
    RETURN();
519
}
520

    
521
void OPPROTO op_store_ibatl (void)
522
{
523
#if 1
524
    env->IBAT[1][PARAM1] = T0;
525
#else
526
    do_store_ibatl(env, PARAM1, T0);
527
#endif
528
    RETURN();
529
}
530

    
531
void OPPROTO op_load_dbat (void)
532
{
533
    T0 = env->DBAT[PARAM1][PARAM2];
534
    RETURN();
535
}
536

    
537
void OPPROTO op_store_dbatu (void)
538
{
539
    do_store_dbatu(env, PARAM1, T0);
540
    RETURN();
541
}
542

    
543
void OPPROTO op_store_dbatl (void)
544
{
545
#if 1
546
    env->DBAT[1][PARAM1] = T0;
547
#else
548
    do_store_dbatl(env, PARAM1, T0);
549
#endif
550
    RETURN();
551
}
552
#endif /* !defined(CONFIG_USER_ONLY) */
553

    
554
/* FPSCR */
555
void OPPROTO op_load_fpscr (void)
556
{
557
    do_load_fpscr();
558
    RETURN();
559
}
560

    
561
void OPPROTO op_store_fpscr (void)
562
{
563
    do_store_fpscr(PARAM1);
564
    RETURN();
565
}
566

    
567
void OPPROTO op_reset_scrfx (void)
568
{
569
    env->fpscr[7] &= ~0x8;
570
    RETURN();
571
}
572

    
573
/* crf operations */
574
void OPPROTO op_getbit_T0 (void)
575
{
576
    T0 = (T0 >> PARAM1) & 1;
577
    RETURN();
578
}
579

    
580
void OPPROTO op_getbit_T1 (void)
581
{
582
    T1 = (T1 >> PARAM1) & 1;
583
    RETURN();
584
}
585

    
586
void OPPROTO op_setcrfbit (void)
587
{
588
    T1 = (T1 & (uint32_t)PARAM1) | (T0 << PARAM2);
589
    RETURN();
590
}
591

    
592
/* Branch */
593
#define EIP env->nip
594

    
595
void OPPROTO op_setlr (void)
596
{
597
    env->lr = (uint32_t)PARAM1;
598
    RETURN();
599
}
600

    
601
#if defined (TARGET_PPC64)
602
void OPPROTO op_setlr_64 (void)
603
{
604
    env->lr = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
605
    RETURN();
606
}
607
#endif
608

    
609
void OPPROTO op_goto_tb0 (void)
610
{
611
    GOTO_TB(op_goto_tb0, PARAM1, 0);
612
}
613

    
614
void OPPROTO op_goto_tb1 (void)
615
{
616
    GOTO_TB(op_goto_tb1, PARAM1, 1);
617
}
618

    
619
void OPPROTO op_b_T1 (void)
620
{
621
    env->nip = (uint32_t)(T1 & ~3);
622
    RETURN();
623
}
624

    
625
#if defined (TARGET_PPC64)
626
void OPPROTO op_b_T1_64 (void)
627
{
628
    env->nip = (uint64_t)(T1 & ~3);
629
    RETURN();
630
}
631
#endif
632

    
633
void OPPROTO op_jz_T0 (void)
634
{
635
    if (!T0)
636
        GOTO_LABEL_PARAM(1);
637
    RETURN();
638
}
639

    
640
void OPPROTO op_btest_T1 (void)
641
{
642
    if (T0) {
643
        env->nip = (uint32_t)(T1 & ~3);
644
    } else {
645
        env->nip = (uint32_t)PARAM1;
646
    }
647
    RETURN();
648
}
649

    
650
#if defined (TARGET_PPC64)
651
void OPPROTO op_btest_T1_64 (void)
652
{
653
    if (T0) {
654
        env->nip = (uint64_t)(T1 & ~3);
655
    } else {
656
        env->nip = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
657
    }
658
    RETURN();
659
}
660
#endif
661

    
662
void OPPROTO op_movl_T1_ctr (void)
663
{
664
    T1 = env->ctr;
665
    RETURN();
666
}
667

    
668
void OPPROTO op_movl_T1_lr (void)
669
{
670
    T1 = env->lr;
671
    RETURN();
672
}
673

    
674
/* tests with result in T0 */
675
void OPPROTO op_test_ctr (void)
676
{
677
    T0 = (uint32_t)env->ctr;
678
    RETURN();
679
}
680

    
681
#if defined(TARGET_PPC64)
682
void OPPROTO op_test_ctr_64 (void)
683
{
684
    T0 = (uint64_t)env->ctr;
685
    RETURN();
686
}
687
#endif
688

    
689
void OPPROTO op_test_ctr_true (void)
690
{
691
    T0 = ((uint32_t)env->ctr != 0 && (T0 & PARAM1) != 0);
692
    RETURN();
693
}
694

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

    
703
void OPPROTO op_test_ctr_false (void)
704
{
705
    T0 = ((uint32_t)env->ctr != 0 && (T0 & PARAM1) == 0);
706
    RETURN();
707
}
708

    
709
#if defined(TARGET_PPC64)
710
void OPPROTO op_test_ctr_false_64 (void)
711
{
712
    T0 = ((uint64_t)env->ctr != 0 && (T0 & PARAM1) == 0);
713
    RETURN();
714
}
715
#endif
716

    
717
void OPPROTO op_test_ctrz (void)
718
{
719
    T0 = ((uint32_t)env->ctr == 0);
720
    RETURN();
721
}
722

    
723
#if defined(TARGET_PPC64)
724
void OPPROTO op_test_ctrz_64 (void)
725
{
726
    T0 = ((uint64_t)env->ctr == 0);
727
    RETURN();
728
}
729
#endif
730

    
731
void OPPROTO op_test_ctrz_true (void)
732
{
733
    T0 = ((uint32_t)env->ctr == 0 && (T0 & PARAM1) != 0);
734
    RETURN();
735
}
736

    
737
#if defined(TARGET_PPC64)
738
void OPPROTO op_test_ctrz_true_64 (void)
739
{
740
    T0 = ((uint64_t)env->ctr == 0 && (T0 & PARAM1) != 0);
741
    RETURN();
742
}
743
#endif
744

    
745
void OPPROTO op_test_ctrz_false (void)
746
{
747
    T0 = ((uint32_t)env->ctr == 0 && (T0 & PARAM1) == 0);
748
    RETURN();
749
}
750

    
751
#if defined(TARGET_PPC64)
752
void OPPROTO op_test_ctrz_false_64 (void)
753
{
754
    T0 = ((uint64_t)env->ctr == 0 && (T0 & PARAM1) == 0);
755
    RETURN();
756
}
757
#endif
758

    
759
void OPPROTO op_test_true (void)
760
{
761
    T0 = (T0 & PARAM1);
762
    RETURN();
763
}
764

    
765
void OPPROTO op_test_false (void)
766
{
767
    T0 = ((T0 & PARAM1) == 0);
768
    RETURN();
769
}
770

    
771
/* CTR maintenance */
772
void OPPROTO op_dec_ctr (void)
773
{
774
    env->ctr--;
775
    RETURN();
776
}
777

    
778
/***                           Integer arithmetic                          ***/
779
/* add */
780
void OPPROTO op_add (void)
781
{
782
    T0 += T1;
783
    RETURN();
784
}
785

    
786
void OPPROTO op_check_addo (void)
787
{
788
    if (likely(!(((uint32_t)T2 ^ (uint32_t)T1 ^ UINT32_MAX) &
789
                 ((uint32_t)T2 ^ (uint32_t)T0) & (1UL << 31)))) {
790
        xer_ov = 0;
791
    } else {
792
        xer_ov = 1;
793
        xer_so = 1;
794
    }
795
    RETURN();
796
}
797

    
798
#if defined(TARGET_PPC64)
799
void OPPROTO op_check_addo_64 (void)
800
{
801
    if (likely(!(((uint64_t)T2 ^ (uint64_t)T1 ^ UINT64_MAX) &
802
                 ((uint64_t)T2 ^ (uint64_t)T0) & (1ULL << 63)))) {
803
        xer_ov = 0;
804
    } else {
805
        xer_ov = 1;
806
        xer_so = 1;
807
    }
808
    RETURN();
809
}
810
#endif
811

    
812
/* add carrying */
813
void OPPROTO op_check_addc (void)
814
{
815
    if (likely((uint32_t)T0 >= (uint32_t)T2)) {
816
        xer_ca = 0;
817
    } else {
818
        xer_ca = 1;
819
    }
820
    RETURN();
821
}
822

    
823
#if defined(TARGET_PPC64)
824
void OPPROTO op_check_addc_64 (void)
825
{
826
    if (likely((uint64_t)T0 >= (uint64_t)T2)) {
827
        xer_ca = 0;
828
    } else {
829
        xer_ca = 1;
830
    }
831
    RETURN();
832
}
833
#endif
834

    
835
/* add extended */
836
void OPPROTO op_adde (void)
837
{
838
    do_adde();
839
    RETURN();
840
}
841

    
842
#if defined(TARGET_PPC64)
843
void OPPROTO op_adde_64 (void)
844
{
845
    do_adde_64();
846
    RETURN();
847
}
848
#endif
849

    
850
/* add immediate */
851
void OPPROTO op_addi (void)
852
{
853
    T0 += (int32_t)PARAM1;
854
    RETURN();
855
}
856

    
857
/* add to minus one extended */
858
void OPPROTO op_add_me (void)
859
{
860
    T0 += xer_ca + (-1);
861
    if (likely((uint32_t)T1 != 0))
862
        xer_ca = 1;
863
    RETURN();
864
}
865

    
866
#if defined(TARGET_PPC64)
867
void OPPROTO op_add_me_64 (void)
868
{
869
    T0 += xer_ca + (-1);
870
    if (likely((uint64_t)T1 != 0))
871
        xer_ca = 1;
872
    RETURN();
873
}
874
#endif
875

    
876
void OPPROTO op_addmeo (void)
877
{
878
    do_addmeo();
879
    RETURN();
880
}
881

    
882
void OPPROTO op_addmeo_64 (void)
883
{
884
    do_addmeo();
885
    RETURN();
886
}
887

    
888
/* add to zero extended */
889
void OPPROTO op_add_ze (void)
890
{
891
    T0 += xer_ca;
892
    RETURN();
893
}
894

    
895
/* divide word */
896
void OPPROTO op_divw (void)
897
{
898
    if (unlikely(((int32_t)T0 == INT32_MIN && (int32_t)T1 == -1) ||
899
                 (int32_t)T1 == 0)) {
900
        T0 = (int32_t)((-1) * ((uint32_t)T0 >> 31));
901
    } else {
902
        T0 = (int32_t)T0 / (int32_t)T1;
903
    }
904
    RETURN();
905
}
906

    
907
#if defined(TARGET_PPC64)
908
void OPPROTO op_divd (void)
909
{
910
    if (unlikely(((int64_t)T0 == INT64_MIN && (int64_t)T1 == -1) ||
911
                 (int64_t)T1 == 0)) {
912
        T0 = (int64_t)((-1ULL) * ((uint64_t)T0 >> 63));
913
    } else {
914
        T0 = (int64_t)T0 / (int64_t)T1;
915
    }
916
    RETURN();
917
}
918
#endif
919

    
920
void OPPROTO op_divwo (void)
921
{
922
    do_divwo();
923
    RETURN();
924
}
925

    
926
#if defined(TARGET_PPC64)
927
void OPPROTO op_divdo (void)
928
{
929
    do_divdo();
930
    RETURN();
931
}
932
#endif
933

    
934
/* divide word unsigned */
935
void OPPROTO op_divwu (void)
936
{
937
    if (unlikely(T1 == 0)) {
938
        T0 = 0;
939
    } else {
940
        T0 = (uint32_t)T0 / (uint32_t)T1;
941
    }
942
    RETURN();
943
}
944

    
945
#if defined(TARGET_PPC64)
946
void OPPROTO op_divdu (void)
947
{
948
    if (unlikely(T1 == 0)) {
949
        T0 = 0;
950
    } else {
951
        T0 /= T1;
952
    }
953
    RETURN();
954
}
955
#endif
956

    
957
void OPPROTO op_divwuo (void)
958
{
959
    do_divwuo();
960
    RETURN();
961
}
962

    
963
#if defined(TARGET_PPC64)
964
void OPPROTO op_divduo (void)
965
{
966
    do_divduo();
967
    RETURN();
968
}
969
#endif
970

    
971
/* multiply high word */
972
void OPPROTO op_mulhw (void)
973
{
974
    T0 = ((int64_t)((int32_t)T0) * (int64_t)((int32_t)T1)) >> 32;
975
    RETURN();
976
}
977

    
978
#if defined(TARGET_PPC64)
979
void OPPROTO op_mulhd (void)
980
{
981
    uint64_t tl, th;
982

    
983
    do_imul64(&tl, &th);
984
    T0 = th;
985
    RETURN();
986
}
987
#endif
988

    
989
/* multiply high word unsigned */
990
void OPPROTO op_mulhwu (void)
991
{
992
    T0 = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1) >> 32;
993
    RETURN();
994
}
995

    
996
#if defined(TARGET_PPC64)
997
void OPPROTO op_mulhdu (void)
998
{
999
    uint64_t tl, th;
1000

    
1001
    do_mul64(&tl, &th);
1002
    T0 = th;
1003
    RETURN();
1004
}
1005
#endif
1006

    
1007
/* multiply low immediate */
1008
void OPPROTO op_mulli (void)
1009
{
1010
    T0 = ((int32_t)T0 * (int32_t)PARAM1);
1011
    RETURN();
1012
}
1013

    
1014
/* multiply low word */
1015
void OPPROTO op_mullw (void)
1016
{
1017
    T0 = (int32_t)(T0 * T1);
1018
    RETURN();
1019
}
1020

    
1021
#if defined(TARGET_PPC64)
1022
void OPPROTO op_mulld (void)
1023
{
1024
    T0 *= T1;
1025
    RETURN();
1026
}
1027
#endif
1028

    
1029
void OPPROTO op_mullwo (void)
1030
{
1031
    do_mullwo();
1032
    RETURN();
1033
}
1034

    
1035
#if defined(TARGET_PPC64)
1036
void OPPROTO op_mulldo (void)
1037
{
1038
    do_mulldo();
1039
    RETURN();
1040
}
1041
#endif
1042

    
1043
/* negate */
1044
void OPPROTO op_neg (void)
1045
{
1046
    if (likely(T0 != INT32_MIN)) {
1047
        T0 = -(int32_t)T0;
1048
    }
1049
    RETURN();
1050
}
1051

    
1052
#if defined(TARGET_PPC64)
1053
void OPPROTO op_neg_64 (void)
1054
{
1055
    if (likely(T0 != INT64_MIN)) {
1056
        T0 = -(int64_t)T0;
1057
    }
1058
    RETURN();
1059
}
1060
#endif
1061

    
1062
void OPPROTO op_nego (void)
1063
{
1064
    do_nego();
1065
    RETURN();
1066
}
1067

    
1068
#if defined(TARGET_PPC64)
1069
void OPPROTO op_nego_64 (void)
1070
{
1071
    do_nego_64();
1072
    RETURN();
1073
}
1074
#endif
1075

    
1076
/* subtract from */
1077
void OPPROTO op_subf (void)
1078
{
1079
    T0 = T1 - T0;
1080
    RETURN();
1081
}
1082

    
1083
void OPPROTO op_check_subfo (void)
1084
{
1085
    if (likely(!(((uint32_t)(~T2) ^ (uint32_t)T1 ^ UINT32_MAX) &
1086
                 ((uint32_t)(~T2) ^ (uint32_t)T0) & (1UL << 31)))) {
1087
        xer_ov = 0;
1088
    } else {
1089
        xer_ov = 1;
1090
        xer_so = 1;
1091
    }
1092
    RETURN();
1093
}
1094

    
1095
#if defined(TARGET_PPC64)
1096
void OPPROTO op_check_subfo_64 (void)
1097
{
1098
    if (likely(!(((uint64_t)(~T2) ^ (uint64_t)T1 ^ UINT64_MAX) &
1099
                 ((uint64_t)(~T2) ^ (uint64_t)T0) & (1ULL << 63)))) {
1100
        xer_ov = 0;
1101
    } else {
1102
        xer_ov = 1;
1103
        xer_so = 1;
1104
    }
1105
    RETURN();
1106
}
1107
#endif
1108

    
1109
/* subtract from carrying */
1110
void OPPROTO op_check_subfc (void)
1111
{
1112
    if (likely((uint32_t)T0 > (uint32_t)T1)) {
1113
        xer_ca = 0;
1114
    } else {
1115
        xer_ca = 1;
1116
    }
1117
    RETURN();
1118
}
1119

    
1120
#if defined(TARGET_PPC64)
1121
void OPPROTO op_check_subfc_64 (void)
1122
{
1123
    if (likely((uint64_t)T0 > (uint64_t)T1)) {
1124
        xer_ca = 0;
1125
    } else {
1126
        xer_ca = 1;
1127
    }
1128
    RETURN();
1129
}
1130
#endif
1131

    
1132
/* subtract from extended */
1133
void OPPROTO op_subfe (void)
1134
{
1135
    do_subfe();
1136
    RETURN();
1137
}
1138

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

    
1147
/* subtract from immediate carrying */
1148
void OPPROTO op_subfic (void)
1149
{
1150
    T0 = (int32_t)PARAM1 + ~T0 + 1;
1151
    if ((uint32_t)T0 <= (uint32_t)PARAM1) {
1152
        xer_ca = 1;
1153
    } else {
1154
        xer_ca = 0;
1155
    }
1156
    RETURN();
1157
}
1158

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

    
1172
/* subtract from minus one extended */
1173
void OPPROTO op_subfme (void)
1174
{
1175
    T0 = ~T0 + xer_ca - 1;
1176
    if (likely((uint32_t)T0 != (uint32_t)-1))
1177
        xer_ca = 1;
1178
    RETURN();
1179
}
1180

    
1181
#if defined(TARGET_PPC64)
1182
void OPPROTO op_subfme_64 (void)
1183
{
1184
    T0 = ~T0 + xer_ca - 1;
1185
    if (likely((uint64_t)T0 != (uint64_t)-1))
1186
        xer_ca = 1;
1187
    RETURN();
1188
}
1189
#endif
1190

    
1191
void OPPROTO op_subfmeo (void)
1192
{
1193
    do_subfmeo();
1194
    RETURN();
1195
}
1196

    
1197
#if defined(TARGET_PPC64)
1198
void OPPROTO op_subfmeo_64 (void)
1199
{
1200
    do_subfmeo_64();
1201
    RETURN();
1202
}
1203
#endif
1204

    
1205
/* subtract from zero extended */
1206
void OPPROTO op_subfze (void)
1207
{
1208
    T1 = ~T0;
1209
    T0 = T1 + xer_ca;
1210
    if ((uint32_t)T0 < (uint32_t)T1) {
1211
        xer_ca = 1;
1212
    } else {
1213
        xer_ca = 0;
1214
    }
1215
    RETURN();
1216
}
1217

    
1218
#if defined(TARGET_PPC64)
1219
void OPPROTO op_subfze_64 (void)
1220
{
1221
    T1 = ~T0;
1222
    T0 = T1 + xer_ca;
1223
    if ((uint64_t)T0 < (uint64_t)T1) {
1224
        xer_ca = 1;
1225
    } else {
1226
        xer_ca = 0;
1227
    }
1228
    RETURN();
1229
}
1230
#endif
1231

    
1232
void OPPROTO op_subfzeo (void)
1233
{
1234
    do_subfzeo();
1235
    RETURN();
1236
}
1237

    
1238
#if defined(TARGET_PPC64)
1239
void OPPROTO op_subfzeo_64 (void)
1240
{
1241
    do_subfzeo_64();
1242
    RETURN();
1243
}
1244
#endif
1245

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

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

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

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

    
1305
/* compare logical */
1306
void OPPROTO op_cmpl (void)
1307
{
1308
    if ((uint32_t)T0 < (uint32_t)T1) {
1309
        T0 = 0x08;
1310
    } else if ((uint32_t)T0 > (uint32_t)T1) {
1311
        T0 = 0x04;
1312
    } else {
1313
        T0 = 0x02;
1314
    }
1315
    T0 |= xer_so;
1316
    RETURN();
1317
}
1318

    
1319
#if defined(TARGET_PPC64)
1320
void OPPROTO op_cmpl_64 (void)
1321
{
1322
    if ((uint64_t)T0 < (uint64_t)T1) {
1323
        T0 = 0x08;
1324
    } else if ((uint64_t)T0 > (uint64_t)T1) {
1325
        T0 = 0x04;
1326
    } else {
1327
        T0 = 0x02;
1328
    }
1329
    T0 |= xer_so;
1330
    RETURN();
1331
}
1332
#endif
1333

    
1334
/* compare logical immediate */
1335
void OPPROTO op_cmpli (void)
1336
{
1337
    if ((uint32_t)T0 < (uint32_t)PARAM1) {
1338
        T0 = 0x08;
1339
    } else if ((uint32_t)T0 > (uint32_t)PARAM1) {
1340
        T0 = 0x04;
1341
    } else {
1342
        T0 = 0x02;
1343
    }
1344
    T0 |= xer_so;
1345
    RETURN();
1346
}
1347

    
1348
#if defined(TARGET_PPC64)
1349
void OPPROTO op_cmpli_64 (void)
1350
{
1351
    if ((uint64_t)T0 < (uint64_t)PARAM1) {
1352
        T0 = 0x08;
1353
    } else if ((uint64_t)T0 > (uint64_t)PARAM1) {
1354
        T0 = 0x04;
1355
    } else {
1356
        T0 = 0x02;
1357
    }
1358
    T0 |= xer_so;
1359
    RETURN();
1360
}
1361
#endif
1362

    
1363
void OPPROTO op_isel (void)
1364
{
1365
    if (T0)
1366
        T0 = T1;
1367
    else
1368
        T0 = T2;
1369
    RETURN();
1370
}
1371

    
1372
void OPPROTO op_popcntb (void)
1373
{
1374
    do_popcntb();
1375
    RETURN();
1376
}
1377

    
1378
#if defined(TARGET_PPC64)
1379
void OPPROTO op_popcntb_64 (void)
1380
{
1381
    do_popcntb_64();
1382
    RETURN();
1383
}
1384
#endif
1385

    
1386
/***                            Integer logical                            ***/
1387
/* and */
1388
void OPPROTO op_and (void)
1389
{
1390
    T0 &= T1;
1391
    RETURN();
1392
}
1393

    
1394
/* andc */
1395
void OPPROTO op_andc (void)
1396
{
1397
    T0 &= ~T1;
1398
    RETURN();
1399
}
1400

    
1401
/* andi. */
1402
void OPPROTO op_andi_T0 (void)
1403
{
1404
    T0 &= (uint32_t)PARAM1;
1405
    RETURN();
1406
}
1407

    
1408
void OPPROTO op_andi_T1 (void)
1409
{
1410
    T1 &= (uint32_t)PARAM1;
1411
    RETURN();
1412
}
1413

    
1414
#if defined(TARGET_PPC64)
1415
void OPPROTO op_andi_T0_64 (void)
1416
{
1417
    T0 &= ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
1418
    RETURN();
1419
}
1420

    
1421
void OPPROTO op_andi_T1_64 (void)
1422
{
1423
    T1 &= ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
1424
    RETURN();
1425
}
1426
#endif
1427

    
1428
/* count leading zero */
1429
void OPPROTO op_cntlzw (void)
1430
{
1431
    T0 = _do_cntlzw(T0);
1432
    RETURN();
1433
}
1434

    
1435
#if defined(TARGET_PPC64)
1436
void OPPROTO op_cntlzd (void)
1437
{
1438
    T0 = _do_cntlzd(T0);
1439
    RETURN();
1440
}
1441
#endif
1442

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

    
1450
/* extend sign byte */
1451
void OPPROTO op_extsb (void)
1452
{
1453
#if defined (TARGET_PPC64)
1454
    T0 = (int64_t)((int8_t)T0);
1455
#else
1456
    T0 = (int32_t)((int8_t)T0);
1457
#endif
1458
    RETURN();
1459
}
1460

    
1461
/* extend sign half word */
1462
void OPPROTO op_extsh (void)
1463
{
1464
#if defined (TARGET_PPC64)
1465
    T0 = (int64_t)((int16_t)T0);
1466
#else
1467
    T0 = (int32_t)((int16_t)T0);
1468
#endif
1469
    RETURN();
1470
}
1471

    
1472
#if defined (TARGET_PPC64)
1473
void OPPROTO op_extsw (void)
1474
{
1475
    T0 = (int64_t)((int32_t)T0);
1476
    RETURN();
1477
}
1478
#endif
1479

    
1480
/* nand */
1481
void OPPROTO op_nand (void)
1482
{
1483
    T0 = ~(T0 & T1);
1484
    RETURN();
1485
}
1486

    
1487
/* nor */
1488
void OPPROTO op_nor (void)
1489
{
1490
    T0 = ~(T0 | T1);
1491
    RETURN();
1492
}
1493

    
1494
/* or */
1495
void OPPROTO op_or (void)
1496
{
1497
    T0 |= T1;
1498
    RETURN();
1499
}
1500

    
1501
/* orc */
1502
void OPPROTO op_orc (void)
1503
{
1504
    T0 |= ~T1;
1505
    RETURN();
1506
}
1507

    
1508
/* ori */
1509
void OPPROTO op_ori (void)
1510
{
1511
    T0 |= (uint32_t)PARAM1;
1512
    RETURN();
1513
}
1514

    
1515
/* xor */
1516
void OPPROTO op_xor (void)
1517
{
1518
    T0 ^= T1;
1519
    RETURN();
1520
}
1521

    
1522
/* xori */
1523
void OPPROTO op_xori (void)
1524
{
1525
    T0 ^= (uint32_t)PARAM1;
1526
    RETURN();
1527
}
1528

    
1529
/***                             Integer rotate                            ***/
1530
void OPPROTO op_rotl32_T0_T1 (void)
1531
{
1532
    T0 = rotl32(T0, T1 & 0x1F);
1533
    RETURN();
1534
}
1535

    
1536
void OPPROTO op_rotli32_T0 (void)
1537
{
1538
    T0 = rotl32(T0, PARAM1);
1539
    RETURN();
1540
}
1541

    
1542
#if defined(TARGET_PPC64)
1543
void OPPROTO op_rotl64_T0_T1 (void)
1544
{
1545
    T0 = rotl64(T0, T1 & 0x3F);
1546
    RETURN();
1547
}
1548

    
1549
void OPPROTO op_rotli64_T0 (void)
1550
{
1551
    T0 = rotl64(T0, PARAM1);
1552
    RETURN();
1553
}
1554
#endif
1555

    
1556
/***                             Integer shift                             ***/
1557
/* shift left word */
1558
void OPPROTO op_slw (void)
1559
{
1560
    if (T1 & 0x20) {
1561
        T0 = 0;
1562
    } else {
1563
        T0 = (uint32_t)(T0 << T1);
1564
    }
1565
    RETURN();
1566
}
1567

    
1568
#if defined(TARGET_PPC64)
1569
void OPPROTO op_sld (void)
1570
{
1571
    if (T1 & 0x40) {
1572
        T0 = 0;
1573
    } else {
1574
        T0 = T0 << T1;
1575
    }
1576
    RETURN();
1577
}
1578
#endif
1579

    
1580
/* shift right algebraic word */
1581
void OPPROTO op_sraw (void)
1582
{
1583
    do_sraw();
1584
    RETURN();
1585
}
1586

    
1587
#if defined(TARGET_PPC64)
1588
void OPPROTO op_srad (void)
1589
{
1590
    do_srad();
1591
    RETURN();
1592
}
1593
#endif
1594

    
1595
/* shift right algebraic word immediate */
1596
void OPPROTO op_srawi (void)
1597
{
1598
    uint32_t mask = (uint32_t)PARAM2;
1599

    
1600
    T0 = (int32_t)T0 >> PARAM1;
1601
    if ((int32_t)T1 < 0 && (T1 & mask) != 0) {
1602
        xer_ca = 1;
1603
    } else {
1604
        xer_ca = 0;
1605
    }
1606
    RETURN();
1607
}
1608

    
1609
#if defined(TARGET_PPC64)
1610
void OPPROTO op_sradi (void)
1611
{
1612
    uint64_t mask = ((uint64_t)PARAM2 << 32) | (uint64_t)PARAM3;
1613

    
1614
    T0 = (int64_t)T0 >> PARAM1;
1615
    if ((int64_t)T1 < 0 && ((uint64_t)T1 & mask) != 0) {
1616
        xer_ca = 1;
1617
    } else {
1618
        xer_ca = 0;
1619
    }
1620
    RETURN();
1621
}
1622
#endif
1623

    
1624
/* shift right word */
1625
void OPPROTO op_srw (void)
1626
{
1627
    if (T1 & 0x20) {
1628
        T0 = 0;
1629
    } else {
1630
        T0 = (uint32_t)T0 >> T1;
1631
    }
1632
    RETURN();
1633
}
1634

    
1635
#if defined(TARGET_PPC64)
1636
void OPPROTO op_srd (void)
1637
{
1638
    if (T1 & 0x40) {
1639
        T0 = 0;
1640
    } else {
1641
        T0 = (uint64_t)T0 >> T1;
1642
    }
1643
    RETURN();
1644
}
1645
#endif
1646

    
1647
void OPPROTO op_sl_T0_T1 (void)
1648
{
1649
    T0 = T0 << T1;
1650
    RETURN();
1651
}
1652

    
1653
void OPPROTO op_sli_T0 (void)
1654
{
1655
    T0 = T0 << PARAM1;
1656
    RETURN();
1657
}
1658

    
1659
void OPPROTO op_srl_T0_T1 (void)
1660
{
1661
    T0 = (uint32_t)T0 >> T1;
1662
    RETURN();
1663
}
1664

    
1665
#if defined(TARGET_PPC64)
1666
void OPPROTO op_srl_T0_T1_64 (void)
1667
{
1668
    T0 = (uint32_t)T0 >> T1;
1669
    RETURN();
1670
}
1671
#endif
1672

    
1673
void OPPROTO op_srli_T0 (void)
1674
{
1675
    T0 = (uint32_t)T0 >> PARAM1;
1676
    RETURN();
1677
}
1678

    
1679
#if defined(TARGET_PPC64)
1680
void OPPROTO op_srli_T0_64 (void)
1681
{
1682
    T0 = (uint64_t)T0 >> PARAM1;
1683
    RETURN();
1684
}
1685
#endif
1686

    
1687
void OPPROTO op_srli_T1 (void)
1688
{
1689
    T1 = (uint32_t)T1 >> PARAM1;
1690
    RETURN();
1691
}
1692

    
1693
#if defined(TARGET_PPC64)
1694
void OPPROTO op_srli_T1_64 (void)
1695
{
1696
    T1 = (uint64_t)T1 >> PARAM1;
1697
    RETURN();
1698
}
1699
#endif
1700

    
1701
/***                       Floating-Point arithmetic                       ***/
1702
/* fadd - fadd. */
1703
void OPPROTO op_fadd (void)
1704
{
1705
    FT0 = float64_add(FT0, FT1, &env->fp_status);
1706
    RETURN();
1707
}
1708

    
1709
/* fsub - fsub. */
1710
void OPPROTO op_fsub (void)
1711
{
1712
    FT0 = float64_sub(FT0, FT1, &env->fp_status);
1713
    RETURN();
1714
}
1715

    
1716
/* fmul - fmul. */
1717
void OPPROTO op_fmul (void)
1718
{
1719
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1720
    RETURN();
1721
}
1722

    
1723
/* fdiv - fdiv. */
1724
void OPPROTO op_fdiv (void)
1725
{
1726
    FT0 = float64_div(FT0, FT1, &env->fp_status);
1727
    RETURN();
1728
}
1729

    
1730
/* fsqrt - fsqrt. */
1731
void OPPROTO op_fsqrt (void)
1732
{
1733
    do_fsqrt();
1734
    RETURN();
1735
}
1736

    
1737
/* fre - fre. */
1738
void OPPROTO op_fre (void)
1739
{
1740
    do_fre();
1741
    RETURN();
1742
}
1743

    
1744
/* fres - fres. */
1745
void OPPROTO op_fres (void)
1746
{
1747
    do_fres();
1748
    RETURN();
1749
}
1750

    
1751
/* frsqrte  - frsqrte. */
1752
void OPPROTO op_frsqrte (void)
1753
{
1754
    do_frsqrte();
1755
    RETURN();
1756
}
1757

    
1758
/* fsel - fsel. */
1759
void OPPROTO op_fsel (void)
1760
{
1761
    do_fsel();
1762
    RETURN();
1763
}
1764

    
1765
/***                     Floating-Point multiply-and-add                   ***/
1766
/* fmadd - fmadd. */
1767
void OPPROTO op_fmadd (void)
1768
{
1769
#if USE_PRECISE_EMULATION
1770
    do_fmadd();
1771
#else
1772
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1773
    FT0 = float64_add(FT0, FT2, &env->fp_status);
1774
#endif
1775
    RETURN();
1776
}
1777

    
1778
/* fmsub - fmsub. */
1779
void OPPROTO op_fmsub (void)
1780
{
1781
#if USE_PRECISE_EMULATION
1782
    do_fmsub();
1783
#else
1784
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1785
    FT0 = float64_sub(FT0, FT2, &env->fp_status);
1786
#endif
1787
    RETURN();
1788
}
1789

    
1790
/* fnmadd - fnmadd. - fnmadds - fnmadds. */
1791
void OPPROTO op_fnmadd (void)
1792
{
1793
    do_fnmadd();
1794
    RETURN();
1795
}
1796

    
1797
/* fnmsub - fnmsub. */
1798
void OPPROTO op_fnmsub (void)
1799
{
1800
    do_fnmsub();
1801
    RETURN();
1802
}
1803

    
1804
/***                     Floating-Point round & convert                    ***/
1805
/* frsp - frsp. */
1806
void OPPROTO op_frsp (void)
1807
{
1808
    FT0 = float64_to_float32(FT0, &env->fp_status);
1809
    RETURN();
1810
}
1811

    
1812
/* fctiw - fctiw. */
1813
void OPPROTO op_fctiw (void)
1814
{
1815
    do_fctiw();
1816
    RETURN();
1817
}
1818

    
1819
/* fctiwz - fctiwz. */
1820
void OPPROTO op_fctiwz (void)
1821
{
1822
    do_fctiwz();
1823
    RETURN();
1824
}
1825

    
1826
#if defined(TARGET_PPC64)
1827
/* fcfid - fcfid. */
1828
void OPPROTO op_fcfid (void)
1829
{
1830
    do_fcfid();
1831
    RETURN();
1832
}
1833

    
1834
/* fctid - fctid. */
1835
void OPPROTO op_fctid (void)
1836
{
1837
    do_fctid();
1838
    RETURN();
1839
}
1840

    
1841
/* fctidz - fctidz. */
1842
void OPPROTO op_fctidz (void)
1843
{
1844
    do_fctidz();
1845
    RETURN();
1846
}
1847
#endif
1848

    
1849
void OPPROTO op_frin (void)
1850
{
1851
    do_frin();
1852
    RETURN();
1853
}
1854

    
1855
void OPPROTO op_friz (void)
1856
{
1857
    do_friz();
1858
    RETURN();
1859
}
1860

    
1861
void OPPROTO op_frip (void)
1862
{
1863
    do_frip();
1864
    RETURN();
1865
}
1866

    
1867
void OPPROTO op_frim (void)
1868
{
1869
    do_frim();
1870
    RETURN();
1871
}
1872

    
1873
/***                         Floating-Point compare                        ***/
1874
/* fcmpu */
1875
void OPPROTO op_fcmpu (void)
1876
{
1877
    do_fcmpu();
1878
    RETURN();
1879
}
1880

    
1881
/* fcmpo */
1882
void OPPROTO op_fcmpo (void)
1883
{
1884
    do_fcmpo();
1885
    RETURN();
1886
}
1887

    
1888
/***                         Floating-point move                           ***/
1889
/* fabs */
1890
void OPPROTO op_fabs (void)
1891
{
1892
    FT0 = float64_abs(FT0);
1893
    RETURN();
1894
}
1895

    
1896
/* fnabs */
1897
void OPPROTO op_fnabs (void)
1898
{
1899
    FT0 = float64_abs(FT0);
1900
    FT0 = float64_chs(FT0);
1901
    RETURN();
1902
}
1903

    
1904
/* fneg */
1905
void OPPROTO op_fneg (void)
1906
{
1907
    FT0 = float64_chs(FT0);
1908
    RETURN();
1909
}
1910

    
1911
/* Load and store */
1912
#define MEMSUFFIX _raw
1913
#include "op_helper.h"
1914
#include "op_mem.h"
1915
#if !defined(CONFIG_USER_ONLY)
1916
#define MEMSUFFIX _user
1917
#include "op_helper.h"
1918
#include "op_mem.h"
1919
#define MEMSUFFIX _kernel
1920
#include "op_helper.h"
1921
#include "op_mem.h"
1922
#endif
1923

    
1924
/* Special op to check and maybe clear reservation */
1925
void OPPROTO op_check_reservation (void)
1926
{
1927
    if ((uint32_t)env->reserve == (uint32_t)(T0 & ~0x00000003))
1928
        env->reserve = -1;
1929
    RETURN();
1930
}
1931

    
1932
#if defined(TARGET_PPC64)
1933
void OPPROTO op_check_reservation_64 (void)
1934
{
1935
    if ((uint64_t)env->reserve == (uint64_t)(T0 & ~0x00000003))
1936
        env->reserve = -1;
1937
    RETURN();
1938
}
1939
#endif
1940

    
1941
void OPPROTO op_wait (void)
1942
{
1943
    env->halted = 1;
1944
    RETURN();
1945
}
1946

    
1947
/* Return from interrupt */
1948
#if !defined(CONFIG_USER_ONLY)
1949
void OPPROTO op_rfi (void)
1950
{
1951
    do_rfi();
1952
    RETURN();
1953
}
1954

    
1955
#if defined(TARGET_PPC64)
1956
void OPPROTO op_rfid (void)
1957
{
1958
    do_rfid();
1959
    RETURN();
1960
}
1961
#endif
1962

    
1963
#if defined(TARGET_PPC64H)
1964
void OPPROTO op_hrfid (void)
1965
{
1966
    do_hrfid();
1967
    RETURN();
1968
}
1969
#endif
1970

    
1971
/* Exception vectors */
1972
void OPPROTO op_store_excp_prefix (void)
1973
{
1974
    T0 &= env->ivpr_mask;
1975
    env->excp_prefix = T0;
1976
    RETURN();
1977
}
1978

    
1979
void OPPROTO op_store_excp_vector (void)
1980
{
1981
    T0 &= env->ivor_mask;
1982
    env->excp_vectors[PARAM1] = T0;
1983
    RETURN();
1984
}
1985
#endif
1986

    
1987
/* Trap word */
1988
void OPPROTO op_tw (void)
1989
{
1990
    do_tw(PARAM1);
1991
    RETURN();
1992
}
1993

    
1994
#if defined(TARGET_PPC64)
1995
void OPPROTO op_td (void)
1996
{
1997
    do_td(PARAM1);
1998
    RETURN();
1999
}
2000
#endif
2001

    
2002
#if !defined(CONFIG_USER_ONLY)
2003
/* tlbia */
2004
void OPPROTO op_tlbia (void)
2005
{
2006
    ppc_tlb_invalidate_all(env);
2007
    RETURN();
2008
}
2009

    
2010
/* tlbie */
2011
void OPPROTO op_tlbie (void)
2012
{
2013
    ppc_tlb_invalidate_one(env, (uint32_t)T0);
2014
    RETURN();
2015
}
2016

    
2017
#if defined(TARGET_PPC64)
2018
void OPPROTO op_tlbie_64 (void)
2019
{
2020
    ppc_tlb_invalidate_one(env, T0);
2021
    RETURN();
2022
}
2023
#endif
2024

    
2025
#if defined(TARGET_PPC64)
2026
void OPPROTO op_slbia (void)
2027
{
2028
    ppc_slb_invalidate_all(env);
2029
    RETURN();
2030
}
2031

    
2032
void OPPROTO op_slbie (void)
2033
{
2034
    ppc_slb_invalidate_one(env, (uint32_t)T0);
2035
    RETURN();
2036
}
2037

    
2038
void OPPROTO op_slbie_64 (void)
2039
{
2040
    ppc_slb_invalidate_one(env, T0);
2041
    RETURN();
2042
}
2043
#endif
2044
#endif
2045

    
2046
#if !defined(CONFIG_USER_ONLY)
2047
/* PowerPC 602/603/755 software TLB load instructions */
2048
void OPPROTO op_6xx_tlbld (void)
2049
{
2050
    do_load_6xx_tlb(0);
2051
    RETURN();
2052
}
2053

    
2054
void OPPROTO op_6xx_tlbli (void)
2055
{
2056
    do_load_6xx_tlb(1);
2057
    RETURN();
2058
}
2059

    
2060
/* PowerPC 74xx software TLB load instructions */
2061
void OPPROTO op_74xx_tlbld (void)
2062
{
2063
    do_load_74xx_tlb(0);
2064
    RETURN();
2065
}
2066

    
2067
void OPPROTO op_74xx_tlbli (void)
2068
{
2069
    do_load_74xx_tlb(1);
2070
    RETURN();
2071
}
2072
#endif
2073

    
2074
/* 601 specific */
2075
void OPPROTO op_load_601_rtcl (void)
2076
{
2077
    T0 = cpu_ppc601_load_rtcl(env);
2078
    RETURN();
2079
}
2080

    
2081
void OPPROTO op_load_601_rtcu (void)
2082
{
2083
    T0 = cpu_ppc601_load_rtcu(env);
2084
    RETURN();
2085
}
2086

    
2087
#if !defined(CONFIG_USER_ONLY)
2088
void OPPROTO op_store_601_rtcl (void)
2089
{
2090
    cpu_ppc601_store_rtcl(env, T0);
2091
    RETURN();
2092
}
2093

    
2094
void OPPROTO op_store_601_rtcu (void)
2095
{
2096
    cpu_ppc601_store_rtcu(env, T0);
2097
    RETURN();
2098
}
2099

    
2100
void OPPROTO op_load_601_bat (void)
2101
{
2102
    T0 = env->IBAT[PARAM1][PARAM2];
2103
    RETURN();
2104
}
2105
#endif /* !defined(CONFIG_USER_ONLY) */
2106

    
2107
/* 601 unified BATs store.
2108
 * To avoid using specific MMU code for 601, we store BATs in
2109
 * IBAT and DBAT simultaneously, then emulate unified BATs.
2110
 */
2111
#if !defined(CONFIG_USER_ONLY)
2112
void OPPROTO op_store_601_batl (void)
2113
{
2114
    int nr = PARAM1;
2115

    
2116
    env->IBAT[1][nr] = T0;
2117
    env->DBAT[1][nr] = T0;
2118
    RETURN();
2119
}
2120

    
2121
void OPPROTO op_store_601_batu (void)
2122
{
2123
    do_store_601_batu(PARAM1);
2124
    RETURN();
2125
}
2126
#endif /* !defined(CONFIG_USER_ONLY) */
2127

    
2128
/* PowerPC 601 specific instructions (POWER bridge) */
2129
/* XXX: those micro-ops need tests ! */
2130
void OPPROTO op_POWER_abs (void)
2131
{
2132
    if (T0 == INT32_MIN)
2133
        T0 = INT32_MAX;
2134
    else if (T0 < 0)
2135
        T0 = -T0;
2136
    RETURN();
2137
}
2138

    
2139
void OPPROTO op_POWER_abso (void)
2140
{
2141
    do_POWER_abso();
2142
    RETURN();
2143
}
2144

    
2145
void OPPROTO op_POWER_clcs (void)
2146
{
2147
    do_POWER_clcs();
2148
    RETURN();
2149
}
2150

    
2151
void OPPROTO op_POWER_div (void)
2152
{
2153
    do_POWER_div();
2154
    RETURN();
2155
}
2156

    
2157
void OPPROTO op_POWER_divo (void)
2158
{
2159
    do_POWER_divo();
2160
    RETURN();
2161
}
2162

    
2163
void OPPROTO op_POWER_divs (void)
2164
{
2165
    do_POWER_divs();
2166
    RETURN();
2167
}
2168

    
2169
void OPPROTO op_POWER_divso (void)
2170
{
2171
    do_POWER_divso();
2172
    RETURN();
2173
}
2174

    
2175
void OPPROTO op_POWER_doz (void)
2176
{
2177
    if ((int32_t)T1 > (int32_t)T0)
2178
        T0 = T1 - T0;
2179
    else
2180
        T0 = 0;
2181
    RETURN();
2182
}
2183

    
2184
void OPPROTO op_POWER_dozo (void)
2185
{
2186
    do_POWER_dozo();
2187
    RETURN();
2188
}
2189

    
2190
void OPPROTO op_load_xer_cmp (void)
2191
{
2192
    T2 = xer_cmp;
2193
    RETURN();
2194
}
2195

    
2196
void OPPROTO op_POWER_maskg (void)
2197
{
2198
    do_POWER_maskg();
2199
    RETURN();
2200
}
2201

    
2202
void OPPROTO op_POWER_maskir (void)
2203
{
2204
    T0 = (T0 & ~T2) | (T1 & T2);
2205
    RETURN();
2206
}
2207

    
2208
void OPPROTO op_POWER_mul (void)
2209
{
2210
    uint64_t tmp;
2211

    
2212
    tmp = (uint64_t)T0 * (uint64_t)T1;
2213
    env->spr[SPR_MQ] = tmp >> 32;
2214
    T0 = tmp;
2215
    RETURN();
2216
}
2217

    
2218
void OPPROTO op_POWER_mulo (void)
2219
{
2220
    do_POWER_mulo();
2221
    RETURN();
2222
}
2223

    
2224
void OPPROTO op_POWER_nabs (void)
2225
{
2226
    if (T0 > 0)
2227
        T0 = -T0;
2228
    RETURN();
2229
}
2230

    
2231
void OPPROTO op_POWER_nabso (void)
2232
{
2233
    /* nabs never overflows */
2234
    if (T0 > 0)
2235
        T0 = -T0;
2236
    xer_ov = 0;
2237
    RETURN();
2238
}
2239

    
2240
/* XXX: factorise POWER rotates... */
2241
void OPPROTO op_POWER_rlmi (void)
2242
{
2243
    T0 = rotl32(T0, T2) & PARAM1;
2244
    T0 |= T1 & (uint32_t)PARAM2;
2245
    RETURN();
2246
}
2247

    
2248
void OPPROTO op_POWER_rrib (void)
2249
{
2250
    T2 &= 0x1FUL;
2251
    T0 = rotl32(T0 & INT32_MIN, T2);
2252
    T0 |= T1 & ~rotl32(INT32_MIN, T2);
2253
    RETURN();
2254
}
2255

    
2256
void OPPROTO op_POWER_sle (void)
2257
{
2258
    T1 &= 0x1FUL;
2259
    env->spr[SPR_MQ] = rotl32(T0, T1);
2260
    T0 = T0 << T1;
2261
    RETURN();
2262
}
2263

    
2264
void OPPROTO op_POWER_sleq (void)
2265
{
2266
    uint32_t tmp = env->spr[SPR_MQ];
2267

    
2268
    T1 &= 0x1FUL;
2269
    env->spr[SPR_MQ] = rotl32(T0, T1);
2270
    T0 = T0 << T1;
2271
    T0 |= tmp >> (32 - T1);
2272
    RETURN();
2273
}
2274

    
2275
void OPPROTO op_POWER_sllq (void)
2276
{
2277
    uint32_t msk = -1;
2278

    
2279
    msk = msk << (T1 & 0x1FUL);
2280
    if (T1 & 0x20UL)
2281
        msk = ~msk;
2282
    T1 &= 0x1FUL;
2283
    T0 = (T0 << T1) & msk;
2284
    T0 |= env->spr[SPR_MQ] & ~msk;
2285
    RETURN();
2286
}
2287

    
2288
void OPPROTO op_POWER_slq (void)
2289
{
2290
    uint32_t msk = -1, tmp;
2291

    
2292
    msk = msk << (T1 & 0x1FUL);
2293
    if (T1 & 0x20UL)
2294
        msk = ~msk;
2295
    T1 &= 0x1FUL;
2296
    tmp = rotl32(T0, T1);
2297
    T0 = tmp & msk;
2298
    env->spr[SPR_MQ] = tmp;
2299
    RETURN();
2300
}
2301

    
2302
void OPPROTO op_POWER_sraq (void)
2303
{
2304
    env->spr[SPR_MQ] = rotl32(T0, 32 - (T1 & 0x1FUL));
2305
    if (T1 & 0x20UL)
2306
        T0 = -1L;
2307
    else
2308
        T0 = (int32_t)T0 >> T1;
2309
    RETURN();
2310
}
2311

    
2312
void OPPROTO op_POWER_sre (void)
2313
{
2314
    T1 &= 0x1FUL;
2315
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2316
    T0 = (int32_t)T0 >> T1;
2317
    RETURN();
2318
}
2319

    
2320
void OPPROTO op_POWER_srea (void)
2321
{
2322
    T1 &= 0x1FUL;
2323
    env->spr[SPR_MQ] = T0 >> T1;
2324
    T0 = (int32_t)T0 >> T1;
2325
    RETURN();
2326
}
2327

    
2328
void OPPROTO op_POWER_sreq (void)
2329
{
2330
    uint32_t tmp;
2331
    int32_t msk;
2332

    
2333
    T1 &= 0x1FUL;
2334
    msk = INT32_MIN >> T1;
2335
    tmp = env->spr[SPR_MQ];
2336
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2337
    T0 = T0 >> T1;
2338
    T0 |= tmp & msk;
2339
    RETURN();
2340
}
2341

    
2342
void OPPROTO op_POWER_srlq (void)
2343
{
2344
    uint32_t tmp;
2345
    int32_t msk;
2346

    
2347
    msk = INT32_MIN >> (T1 & 0x1FUL);
2348
    if (T1 & 0x20UL)
2349
        msk = ~msk;
2350
    T1 &= 0x1FUL;
2351
    tmp = env->spr[SPR_MQ];
2352
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2353
    T0 = T0 >> T1;
2354
    T0 &= msk;
2355
    T0 |= tmp & ~msk;
2356
    RETURN();
2357
}
2358

    
2359
void OPPROTO op_POWER_srq (void)
2360
{
2361
    T1 &= 0x1FUL;
2362
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2363
    T0 = T0 >> T1;
2364
    RETURN();
2365
}
2366

    
2367
/* POWER instructions not implemented in PowerPC 601 */
2368
#if !defined(CONFIG_USER_ONLY)
2369
void OPPROTO op_POWER_mfsri (void)
2370
{
2371
    T1 = T0 >> 28;
2372
    T0 = env->sr[T1];
2373
    RETURN();
2374
}
2375

    
2376
void OPPROTO op_POWER_rac (void)
2377
{
2378
    do_POWER_rac();
2379
    RETURN();
2380
}
2381

    
2382
void OPPROTO op_POWER_rfsvc (void)
2383
{
2384
    do_POWER_rfsvc();
2385
    RETURN();
2386
}
2387
#endif
2388

    
2389
/* PowerPC 602 specific instruction */
2390
#if !defined(CONFIG_USER_ONLY)
2391
void OPPROTO op_602_mfrom (void)
2392
{
2393
    do_op_602_mfrom();
2394
    RETURN();
2395
}
2396
#endif
2397

    
2398
/* PowerPC 4xx specific micro-ops */
2399
void OPPROTO op_405_add_T0_T2 (void)
2400
{
2401
    T0 = (int32_t)T0 + (int32_t)T2;
2402
    RETURN();
2403
}
2404

    
2405
void OPPROTO op_405_mulchw (void)
2406
{
2407
    T0 = ((int16_t)T0) * ((int16_t)(T1 >> 16));
2408
    RETURN();
2409
}
2410

    
2411
void OPPROTO op_405_mulchwu (void)
2412
{
2413
    T0 = ((uint16_t)T0) * ((uint16_t)(T1 >> 16));
2414
    RETURN();
2415
}
2416

    
2417
void OPPROTO op_405_mulhhw (void)
2418
{
2419
    T0 = ((int16_t)(T0 >> 16)) * ((int16_t)(T1 >> 16));
2420
    RETURN();
2421
}
2422

    
2423
void OPPROTO op_405_mulhhwu (void)
2424
{
2425
    T0 = ((uint16_t)(T0 >> 16)) * ((uint16_t)(T1 >> 16));
2426
    RETURN();
2427
}
2428

    
2429
void OPPROTO op_405_mullhw (void)
2430
{
2431
    T0 = ((int16_t)T0) * ((int16_t)T1);
2432
    RETURN();
2433
}
2434

    
2435
void OPPROTO op_405_mullhwu (void)
2436
{
2437
    T0 = ((uint16_t)T0) * ((uint16_t)T1);
2438
    RETURN();
2439
}
2440

    
2441
void OPPROTO op_405_check_ov (void)
2442
{
2443
    do_405_check_ov();
2444
    RETURN();
2445
}
2446

    
2447
void OPPROTO op_405_check_sat (void)
2448
{
2449
    do_405_check_sat();
2450
    RETURN();
2451
}
2452

    
2453
void OPPROTO op_405_check_ovu (void)
2454
{
2455
    if (likely(T0 >= T2)) {
2456
        xer_ov = 0;
2457
    } else {
2458
        xer_ov = 1;
2459
        xer_so = 1;
2460
    }
2461
    RETURN();
2462
}
2463

    
2464
void OPPROTO op_405_check_satu (void)
2465
{
2466
    if (unlikely(T0 < T2)) {
2467
        /* Saturate result */
2468
        T0 = -1;
2469
    }
2470
    RETURN();
2471
}
2472

    
2473
void OPPROTO op_load_dcr (void)
2474
{
2475
    do_load_dcr();
2476
    RETURN();
2477
}
2478

    
2479
void OPPROTO op_store_dcr (void)
2480
{
2481
    do_store_dcr();
2482
    RETURN();
2483
}
2484

    
2485
#if !defined(CONFIG_USER_ONLY)
2486
/* Return from critical interrupt :
2487
 * same as rfi, except nip & MSR are loaded from SRR2/3 instead of SRR0/1
2488
 */
2489
void OPPROTO op_40x_rfci (void)
2490
{
2491
    do_40x_rfci();
2492
    RETURN();
2493
}
2494

    
2495
void OPPROTO op_rfci (void)
2496
{
2497
    do_rfci();
2498
    RETURN();
2499
}
2500

    
2501
void OPPROTO op_rfdi (void)
2502
{
2503
    do_rfdi();
2504
    RETURN();
2505
}
2506

    
2507
void OPPROTO op_rfmci (void)
2508
{
2509
    do_rfmci();
2510
    RETURN();
2511
}
2512

    
2513
void OPPROTO op_wrte (void)
2514
{
2515
    msr_ee = T0 >> 16;
2516
    RETURN();
2517
}
2518

    
2519
void OPPROTO op_440_tlbre (void)
2520
{
2521
    do_440_tlbre(PARAM1);
2522
    RETURN();
2523
}
2524

    
2525
void OPPROTO op_440_tlbsx (void)
2526
{
2527
    T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_440_MMUCR] & 0xFF);
2528
    RETURN();
2529
}
2530

    
2531
void OPPROTO op_4xx_tlbsx_check (void)
2532
{
2533
    int tmp;
2534

    
2535
    tmp = xer_so;
2536
    if (T0 != -1)
2537
        tmp |= 0x02;
2538
    env->crf[0] = tmp;
2539
    RETURN();
2540
}
2541

    
2542
void OPPROTO op_440_tlbwe (void)
2543
{
2544
    do_440_tlbwe(PARAM1);
2545
    RETURN();
2546
}
2547

    
2548
void OPPROTO op_4xx_tlbre_lo (void)
2549
{
2550
    do_4xx_tlbre_lo();
2551
    RETURN();
2552
}
2553

    
2554
void OPPROTO op_4xx_tlbre_hi (void)
2555
{
2556
    do_4xx_tlbre_hi();
2557
    RETURN();
2558
}
2559

    
2560
void OPPROTO op_4xx_tlbsx (void)
2561
{
2562
    T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_40x_PID]);
2563
    RETURN();
2564
}
2565

    
2566
void OPPROTO op_4xx_tlbwe_lo (void)
2567
{
2568
    do_4xx_tlbwe_lo();
2569
    RETURN();
2570
}
2571

    
2572
void OPPROTO op_4xx_tlbwe_hi (void)
2573
{
2574
    do_4xx_tlbwe_hi();
2575
    RETURN();
2576
}
2577
#endif
2578

    
2579
/* SPR micro-ops */
2580
/* 440 specific */
2581
void OPPROTO op_440_dlmzb (void)
2582
{
2583
    do_440_dlmzb();
2584
    RETURN();
2585
}
2586

    
2587
void OPPROTO op_440_dlmzb_update_Rc (void)
2588
{
2589
    if (T0 == 8)
2590
        T0 = 0x2;
2591
    else if (T0 < 4)
2592
        T0 = 0x4;
2593
    else
2594
        T0 = 0x8;
2595
    RETURN();
2596
}
2597

    
2598
#if !defined(CONFIG_USER_ONLY)
2599
void OPPROTO op_store_pir (void)
2600
{
2601
    env->spr[SPR_PIR] = T0 & 0x0000000FUL;
2602
    RETURN();
2603
}
2604

    
2605
void OPPROTO op_load_403_pb (void)
2606
{
2607
    do_load_403_pb(PARAM1);
2608
    RETURN();
2609
}
2610

    
2611
void OPPROTO op_store_403_pb (void)
2612
{
2613
    do_store_403_pb(PARAM1);
2614
    RETURN();
2615
}
2616

    
2617
void OPPROTO op_load_40x_pit (void)
2618
{
2619
    T0 = load_40x_pit(env);
2620
    RETURN();
2621
}
2622

    
2623
void OPPROTO op_store_40x_pit (void)
2624
{
2625
    store_40x_pit(env, T0);
2626
    RETURN();
2627
}
2628

    
2629
void OPPROTO op_store_40x_dbcr0 (void)
2630
{
2631
    store_40x_dbcr0(env, T0);
2632
    RETURN();
2633
}
2634

    
2635
void OPPROTO op_store_40x_sler (void)
2636
{
2637
    store_40x_sler(env, T0);
2638
    RETURN();
2639
}
2640

    
2641
void OPPROTO op_store_booke_tcr (void)
2642
{
2643
    store_booke_tcr(env, T0);
2644
    RETURN();
2645
}
2646

    
2647
void OPPROTO op_store_booke_tsr (void)
2648
{
2649
    store_booke_tsr(env, T0);
2650
    RETURN();
2651
}
2652
#endif /* !defined(CONFIG_USER_ONLY) */
2653

    
2654
#if defined(TARGET_PPCEMB)
2655
/* SPE extension */
2656
void OPPROTO op_splatw_T1_64 (void)
2657
{
2658
    T1_64 = (T1_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL);
2659
    RETURN();
2660
}
2661

    
2662
void OPPROTO op_splatwi_T0_64 (void)
2663
{
2664
    uint64_t tmp = PARAM1;
2665

    
2666
    T0_64 = (tmp << 32) | tmp;
2667
    RETURN();
2668
}
2669

    
2670
void OPPROTO op_splatwi_T1_64 (void)
2671
{
2672
    uint64_t tmp = PARAM1;
2673

    
2674
    T1_64 = (tmp << 32) | tmp;
2675
    RETURN();
2676
}
2677

    
2678
void OPPROTO op_extsh_T1_64 (void)
2679
{
2680
    T1_64 = (int32_t)((int16_t)T1_64);
2681
    RETURN();
2682
}
2683

    
2684
void OPPROTO op_sli16_T1_64 (void)
2685
{
2686
    T1_64 = T1_64 << 16;
2687
    RETURN();
2688
}
2689

    
2690
void OPPROTO op_sli32_T1_64 (void)
2691
{
2692
    T1_64 = T1_64 << 32;
2693
    RETURN();
2694
}
2695

    
2696
void OPPROTO op_srli32_T1_64 (void)
2697
{
2698
    T1_64 = T1_64 >> 32;
2699
    RETURN();
2700
}
2701

    
2702
void OPPROTO op_evsel (void)
2703
{
2704
    do_evsel();
2705
    RETURN();
2706
}
2707

    
2708
void OPPROTO op_evaddw (void)
2709
{
2710
    do_evaddw();
2711
    RETURN();
2712
}
2713

    
2714
void OPPROTO op_evsubfw (void)
2715
{
2716
    do_evsubfw();
2717
    RETURN();
2718
}
2719

    
2720
void OPPROTO op_evneg (void)
2721
{
2722
    do_evneg();
2723
    RETURN();
2724
}
2725

    
2726
void OPPROTO op_evabs (void)
2727
{
2728
    do_evabs();
2729
    RETURN();
2730
}
2731

    
2732
void OPPROTO op_evextsh (void)
2733
{
2734
    T0_64 = ((uint64_t)((int32_t)(int16_t)(T0_64 >> 32)) << 32) |
2735
        (uint64_t)((int32_t)(int16_t)T0_64);
2736
    RETURN();
2737
}
2738

    
2739
void OPPROTO op_evextsb (void)
2740
{
2741
    T0_64 = ((uint64_t)((int32_t)(int8_t)(T0_64 >> 32)) << 32) |
2742
        (uint64_t)((int32_t)(int8_t)T0_64);
2743
    RETURN();
2744
}
2745

    
2746
void OPPROTO op_evcntlzw (void)
2747
{
2748
    do_evcntlzw();
2749
    RETURN();
2750
}
2751

    
2752
void OPPROTO op_evrndw (void)
2753
{
2754
    do_evrndw();
2755
    RETURN();
2756
}
2757

    
2758
void OPPROTO op_brinc (void)
2759
{
2760
    do_brinc();
2761
    RETURN();
2762
}
2763

    
2764
void OPPROTO op_evcntlsw (void)
2765
{
2766
    do_evcntlsw();
2767
    RETURN();
2768
}
2769

    
2770
void OPPROTO op_evand (void)
2771
{
2772
    T0_64 &= T1_64;
2773
    RETURN();
2774
}
2775

    
2776
void OPPROTO op_evandc (void)
2777
{
2778
    T0_64 &= ~T1_64;
2779
    RETURN();
2780
}
2781

    
2782
void OPPROTO op_evor (void)
2783
{
2784
    T0_64 |= T1_64;
2785
    RETURN();
2786
}
2787

    
2788
void OPPROTO op_evxor (void)
2789
{
2790
    T0_64 ^= T1_64;
2791
    RETURN();
2792
}
2793

    
2794
void OPPROTO op_eveqv (void)
2795
{
2796
    T0_64 = ~(T0_64 ^ T1_64);
2797
    RETURN();
2798
}
2799

    
2800
void OPPROTO op_evnor (void)
2801
{
2802
    T0_64 = ~(T0_64 | T1_64);
2803
    RETURN();
2804
}
2805

    
2806
void OPPROTO op_evorc (void)
2807
{
2808
    T0_64 |= ~T1_64;
2809
    RETURN();
2810
}
2811

    
2812
void OPPROTO op_evnand (void)
2813
{
2814
    T0_64 = ~(T0_64 & T1_64);
2815
    RETURN();
2816
}
2817

    
2818
void OPPROTO op_evsrws (void)
2819
{
2820
    do_evsrws();
2821
    RETURN();
2822
}
2823

    
2824
void OPPROTO op_evsrwu (void)
2825
{
2826
    do_evsrwu();
2827
    RETURN();
2828
}
2829

    
2830
void OPPROTO op_evslw (void)
2831
{
2832
    do_evslw();
2833
    RETURN();
2834
}
2835

    
2836
void OPPROTO op_evrlw (void)
2837
{
2838
    do_evrlw();
2839
    RETURN();
2840
}
2841

    
2842
void OPPROTO op_evmergelo (void)
2843
{
2844
    T0_64 = (T0_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL);
2845
    RETURN();
2846
}
2847

    
2848
void OPPROTO op_evmergehi (void)
2849
{
2850
    T0_64 = (T0_64 & 0xFFFFFFFF00000000ULL) | (T1_64 >> 32);
2851
    RETURN();
2852
}
2853

    
2854
void OPPROTO op_evmergelohi (void)
2855
{
2856
    T0_64 = (T0_64 << 32) | (T1_64 >> 32);
2857
    RETURN();
2858
}
2859

    
2860
void OPPROTO op_evmergehilo (void)
2861
{
2862
    T0_64 = (T0_64 & 0xFFFFFFFF00000000ULL) | (T1_64 & 0x00000000FFFFFFFFULL);
2863
    RETURN();
2864
}
2865

    
2866
void OPPROTO op_evcmpgts (void)
2867
{
2868
    do_evcmpgts();
2869
    RETURN();
2870
}
2871

    
2872
void OPPROTO op_evcmpgtu (void)
2873
{
2874
    do_evcmpgtu();
2875
    RETURN();
2876
}
2877

    
2878
void OPPROTO op_evcmplts (void)
2879
{
2880
    do_evcmplts();
2881
    RETURN();
2882
}
2883

    
2884
void OPPROTO op_evcmpltu (void)
2885
{
2886
    do_evcmpltu();
2887
    RETURN();
2888
}
2889

    
2890
void OPPROTO op_evcmpeq (void)
2891
{
2892
    do_evcmpeq();
2893
    RETURN();
2894
}
2895

    
2896
void OPPROTO op_evfssub (void)
2897
{
2898
    do_evfssub();
2899
    RETURN();
2900
}
2901

    
2902
void OPPROTO op_evfsadd (void)
2903
{
2904
    do_evfsadd();
2905
    RETURN();
2906
}
2907

    
2908
void OPPROTO op_evfsnabs (void)
2909
{
2910
    do_evfsnabs();
2911
    RETURN();
2912
}
2913

    
2914
void OPPROTO op_evfsabs (void)
2915
{
2916
    do_evfsabs();
2917
    RETURN();
2918
}
2919

    
2920
void OPPROTO op_evfsneg (void)
2921
{
2922
    do_evfsneg();
2923
    RETURN();
2924
}
2925

    
2926
void OPPROTO op_evfsdiv (void)
2927
{
2928
    do_evfsdiv();
2929
    RETURN();
2930
}
2931

    
2932
void OPPROTO op_evfsmul (void)
2933
{
2934
    do_evfsmul();
2935
    RETURN();
2936
}
2937

    
2938
void OPPROTO op_evfscmplt (void)
2939
{
2940
    do_evfscmplt();
2941
    RETURN();
2942
}
2943

    
2944
void OPPROTO op_evfscmpgt (void)
2945
{
2946
    do_evfscmpgt();
2947
    RETURN();
2948
}
2949

    
2950
void OPPROTO op_evfscmpeq (void)
2951
{
2952
    do_evfscmpeq();
2953
    RETURN();
2954
}
2955

    
2956
void OPPROTO op_evfscfsi (void)
2957
{
2958
    do_evfscfsi();
2959
    RETURN();
2960
}
2961

    
2962
void OPPROTO op_evfscfui (void)
2963
{
2964
    do_evfscfui();
2965
    RETURN();
2966
}
2967

    
2968
void OPPROTO op_evfscfsf (void)
2969
{
2970
    do_evfscfsf();
2971
    RETURN();
2972
}
2973

    
2974
void OPPROTO op_evfscfuf (void)
2975
{
2976
    do_evfscfuf();
2977
    RETURN();
2978
}
2979

    
2980
void OPPROTO op_evfsctsi (void)
2981
{
2982
    do_evfsctsi();
2983
    RETURN();
2984
}
2985

    
2986
void OPPROTO op_evfsctui (void)
2987
{
2988
    do_evfsctui();
2989
    RETURN();
2990
}
2991

    
2992
void OPPROTO op_evfsctsf (void)
2993
{
2994
    do_evfsctsf();
2995
    RETURN();
2996
}
2997

    
2998
void OPPROTO op_evfsctuf (void)
2999
{
3000
    do_evfsctuf();
3001
    RETURN();
3002
}
3003

    
3004
void OPPROTO op_evfsctuiz (void)
3005
{
3006
    do_evfsctuiz();
3007
    RETURN();
3008
}
3009

    
3010
void OPPROTO op_evfsctsiz (void)
3011
{
3012
    do_evfsctsiz();
3013
    RETURN();
3014
}
3015

    
3016
void OPPROTO op_evfststlt (void)
3017
{
3018
    do_evfststlt();
3019
    RETURN();
3020
}
3021

    
3022
void OPPROTO op_evfststgt (void)
3023
{
3024
    do_evfststgt();
3025
    RETURN();
3026
}
3027

    
3028
void OPPROTO op_evfststeq (void)
3029
{
3030
    do_evfststeq();
3031
    RETURN();
3032
}
3033

    
3034
void OPPROTO op_efssub (void)
3035
{
3036
    T0_64 = _do_efssub(T0_64, T1_64);
3037
    RETURN();
3038
}
3039

    
3040
void OPPROTO op_efsadd (void)
3041
{
3042
    T0_64 = _do_efsadd(T0_64, T1_64);
3043
    RETURN();
3044
}
3045

    
3046
void OPPROTO op_efsnabs (void)
3047
{
3048
    T0_64 = _do_efsnabs(T0_64);
3049
    RETURN();
3050
}
3051

    
3052
void OPPROTO op_efsabs (void)
3053
{
3054
    T0_64 = _do_efsabs(T0_64);
3055
    RETURN();
3056
}
3057

    
3058
void OPPROTO op_efsneg (void)
3059
{
3060
    T0_64 = _do_efsneg(T0_64);
3061
    RETURN();
3062
}
3063

    
3064
void OPPROTO op_efsdiv (void)
3065
{
3066
    T0_64 = _do_efsdiv(T0_64, T1_64);
3067
    RETURN();
3068
}
3069

    
3070
void OPPROTO op_efsmul (void)
3071
{
3072
    T0_64 = _do_efsmul(T0_64, T1_64);
3073
    RETURN();
3074
}
3075

    
3076
void OPPROTO op_efscmplt (void)
3077
{
3078
    do_efscmplt();
3079
    RETURN();
3080
}
3081

    
3082
void OPPROTO op_efscmpgt (void)
3083
{
3084
    do_efscmpgt();
3085
    RETURN();
3086
}
3087

    
3088
void OPPROTO op_efscfd (void)
3089
{
3090
    do_efscfd();
3091
    RETURN();
3092
}
3093

    
3094
void OPPROTO op_efscmpeq (void)
3095
{
3096
    do_efscmpeq();
3097
    RETURN();
3098
}
3099

    
3100
void OPPROTO op_efscfsi (void)
3101
{
3102
    do_efscfsi();
3103
    RETURN();
3104
}
3105

    
3106
void OPPROTO op_efscfui (void)
3107
{
3108
    do_efscfui();
3109
    RETURN();
3110
}
3111

    
3112
void OPPROTO op_efscfsf (void)
3113
{
3114
    do_efscfsf();
3115
    RETURN();
3116
}
3117

    
3118
void OPPROTO op_efscfuf (void)
3119
{
3120
    do_efscfuf();
3121
    RETURN();
3122
}
3123

    
3124
void OPPROTO op_efsctsi (void)
3125
{
3126
    do_efsctsi();
3127
    RETURN();
3128
}
3129

    
3130
void OPPROTO op_efsctui (void)
3131
{
3132
    do_efsctui();
3133
    RETURN();
3134
}
3135

    
3136
void OPPROTO op_efsctsf (void)
3137
{
3138
    do_efsctsf();
3139
    RETURN();
3140
}
3141

    
3142
void OPPROTO op_efsctuf (void)
3143
{
3144
    do_efsctuf();
3145
    RETURN();
3146
}
3147

    
3148
void OPPROTO op_efsctsiz (void)
3149
{
3150
    do_efsctsiz();
3151
    RETURN();
3152
}
3153

    
3154
void OPPROTO op_efsctuiz (void)
3155
{
3156
    do_efsctuiz();
3157
    RETURN();
3158
}
3159

    
3160
void OPPROTO op_efststlt (void)
3161
{
3162
    T0 = _do_efststlt(T0_64, T1_64);
3163
    RETURN();
3164
}
3165

    
3166
void OPPROTO op_efststgt (void)
3167
{
3168
    T0 = _do_efststgt(T0_64, T1_64);
3169
    RETURN();
3170
}
3171

    
3172
void OPPROTO op_efststeq (void)
3173
{
3174
    T0 = _do_efststeq(T0_64, T1_64);
3175
    RETURN();
3176
}
3177

    
3178
void OPPROTO op_efdsub (void)
3179
{
3180
    union {
3181
        uint64_t u;
3182
        float64 f;
3183
    } u1, u2;
3184
    u1.u = T0_64;
3185
    u2.u = T1_64;
3186
    u1.f = float64_sub(u1.f, u2.f, &env->spe_status);
3187
    T0_64 = u1.u;
3188
    RETURN();
3189
}
3190

    
3191
void OPPROTO op_efdadd (void)
3192
{
3193
    union {
3194
        uint64_t u;
3195
        float64 f;
3196
    } u1, u2;
3197
    u1.u = T0_64;
3198
    u2.u = T1_64;
3199
    u1.f = float64_add(u1.f, u2.f, &env->spe_status);
3200
    T0_64 = u1.u;
3201
    RETURN();
3202
}
3203

    
3204
void OPPROTO op_efdcfsid (void)
3205
{
3206
    do_efdcfsi();
3207
    RETURN();
3208
}
3209

    
3210
void OPPROTO op_efdcfuid (void)
3211
{
3212
    do_efdcfui();
3213
    RETURN();
3214
}
3215

    
3216
void OPPROTO op_efdnabs (void)
3217
{
3218
    T0_64 |= 0x8000000000000000ULL;
3219
    RETURN();
3220
}
3221

    
3222
void OPPROTO op_efdabs (void)
3223
{
3224
    T0_64 &= ~0x8000000000000000ULL;
3225
    RETURN();
3226
}
3227

    
3228
void OPPROTO op_efdneg (void)
3229
{
3230
    T0_64 ^= 0x8000000000000000ULL;
3231
    RETURN();
3232
}
3233

    
3234
void OPPROTO op_efddiv (void)
3235
{
3236
    union {
3237
        uint64_t u;
3238
        float64 f;
3239
    } u1, u2;
3240
    u1.u = T0_64;
3241
    u2.u = T1_64;
3242
    u1.f = float64_div(u1.f, u2.f, &env->spe_status);
3243
    T0_64 = u1.u;
3244
    RETURN();
3245
}
3246

    
3247
void OPPROTO op_efdmul (void)
3248
{
3249
    union {
3250
        uint64_t u;
3251
        float64 f;
3252
    } u1, u2;
3253
    u1.u = T0_64;
3254
    u2.u = T1_64;
3255
    u1.f = float64_mul(u1.f, u2.f, &env->spe_status);
3256
    T0_64 = u1.u;
3257
    RETURN();
3258
}
3259

    
3260
void OPPROTO op_efdctsidz (void)
3261
{
3262
    do_efdctsiz();
3263
    RETURN();
3264
}
3265

    
3266
void OPPROTO op_efdctuidz (void)
3267
{
3268
    do_efdctuiz();
3269
    RETURN();
3270
}
3271

    
3272
void OPPROTO op_efdcmplt (void)
3273
{
3274
    do_efdcmplt();
3275
    RETURN();
3276
}
3277

    
3278
void OPPROTO op_efdcmpgt (void)
3279
{
3280
    do_efdcmpgt();
3281
    RETURN();
3282
}
3283

    
3284
void OPPROTO op_efdcfs (void)
3285
{
3286
    do_efdcfs();
3287
    RETURN();
3288
}
3289

    
3290
void OPPROTO op_efdcmpeq (void)
3291
{
3292
    do_efdcmpeq();
3293
    RETURN();
3294
}
3295

    
3296
void OPPROTO op_efdcfsi (void)
3297
{
3298
    do_efdcfsi();
3299
    RETURN();
3300
}
3301

    
3302
void OPPROTO op_efdcfui (void)
3303
{
3304
    do_efdcfui();
3305
    RETURN();
3306
}
3307

    
3308
void OPPROTO op_efdcfsf (void)
3309
{
3310
    do_efdcfsf();
3311
    RETURN();
3312
}
3313

    
3314
void OPPROTO op_efdcfuf (void)
3315
{
3316
    do_efdcfuf();
3317
    RETURN();
3318
}
3319

    
3320
void OPPROTO op_efdctsi (void)
3321
{
3322
    do_efdctsi();
3323
    RETURN();
3324
}
3325

    
3326
void OPPROTO op_efdctui (void)
3327
{
3328
    do_efdctui();
3329
    RETURN();
3330
}
3331

    
3332
void OPPROTO op_efdctsf (void)
3333
{
3334
    do_efdctsf();
3335
    RETURN();
3336
}
3337

    
3338
void OPPROTO op_efdctuf (void)
3339
{
3340
    do_efdctuf();
3341
    RETURN();
3342
}
3343

    
3344
void OPPROTO op_efdctuiz (void)
3345
{
3346
    do_efdctuiz();
3347
    RETURN();
3348
}
3349

    
3350
void OPPROTO op_efdctsiz (void)
3351
{
3352
    do_efdctsiz();
3353
    RETURN();
3354
}
3355

    
3356
void OPPROTO op_efdtstlt (void)
3357
{
3358
    T0 = _do_efdtstlt(T0_64, T1_64);
3359
    RETURN();
3360
}
3361

    
3362
void OPPROTO op_efdtstgt (void)
3363
{
3364
    T0 = _do_efdtstgt(T0_64, T1_64);
3365
    RETURN();
3366
}
3367

    
3368
void OPPROTO op_efdtsteq (void)
3369
{
3370
    T0 = _do_efdtsteq(T0_64, T1_64);
3371
    RETURN();
3372
}
3373
#endif /* defined(TARGET_PPCEMB) */