Statistics
| Branch: | Revision:

root / target-ppc / op.c @ f0413473

History | View | Annotate | Download (49.1 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 "host-utils.h"
26
#include "helper_regs.h"
27
#include "op_helper.h"
28

    
29
#define REG 0
30
#include "op_template.h"
31

    
32
#define REG 1
33
#include "op_template.h"
34

    
35
#define REG 2
36
#include "op_template.h"
37

    
38
#define REG 3
39
#include "op_template.h"
40

    
41
#define REG 4
42
#include "op_template.h"
43

    
44
#define REG 5
45
#include "op_template.h"
46

    
47
#define REG 6
48
#include "op_template.h"
49

    
50
#define REG 7
51
#include "op_template.h"
52

    
53
#define REG 8
54
#include "op_template.h"
55

    
56
#define REG 9
57
#include "op_template.h"
58

    
59
#define REG 10
60
#include "op_template.h"
61

    
62
#define REG 11
63
#include "op_template.h"
64

    
65
#define REG 12
66
#include "op_template.h"
67

    
68
#define REG 13
69
#include "op_template.h"
70

    
71
#define REG 14
72
#include "op_template.h"
73

    
74
#define REG 15
75
#include "op_template.h"
76

    
77
#define REG 16
78
#include "op_template.h"
79

    
80
#define REG 17
81
#include "op_template.h"
82

    
83
#define REG 18
84
#include "op_template.h"
85

    
86
#define REG 19
87
#include "op_template.h"
88

    
89
#define REG 20
90
#include "op_template.h"
91

    
92
#define REG 21
93
#include "op_template.h"
94

    
95
#define REG 22
96
#include "op_template.h"
97

    
98
#define REG 23
99
#include "op_template.h"
100

    
101
#define REG 24
102
#include "op_template.h"
103

    
104
#define REG 25
105
#include "op_template.h"
106

    
107
#define REG 26
108
#include "op_template.h"
109

    
110
#define REG 27
111
#include "op_template.h"
112

    
113
#define REG 28
114
#include "op_template.h"
115

    
116
#define REG 29
117
#include "op_template.h"
118

    
119
#define REG 30
120
#include "op_template.h"
121

    
122
#define REG 31
123
#include "op_template.h"
124

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

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

    
139
/* Generate exceptions */
140
void OPPROTO op_raise_exception_err (void)
141
{
142
    do_raise_exception_err(PARAM1, PARAM2);
143
}
144

    
145
void OPPROTO op_update_nip (void)
146
{
147
    env->nip = (uint32_t)PARAM1;
148
    RETURN();
149
}
150

    
151
#if defined(TARGET_PPC64)
152
void OPPROTO op_update_nip_64 (void)
153
{
154
    env->nip = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
155
    RETURN();
156
}
157
#endif
158

    
159
void OPPROTO op_debug (void)
160
{
161
    do_raise_exception(EXCP_DEBUG);
162
}
163

    
164
/* Load/store special registers */
165
void OPPROTO op_load_cr (void)
166
{
167
    do_load_cr();
168
    RETURN();
169
}
170

    
171
void OPPROTO op_store_cr (void)
172
{
173
    do_store_cr(PARAM1);
174
    RETURN();
175
}
176

    
177
void OPPROTO op_load_cro (void)
178
{
179
    T0 = env->crf[PARAM1];
180
    RETURN();
181
}
182

    
183
void OPPROTO op_store_cro (void)
184
{
185
    env->crf[PARAM1] = T0;
186
    RETURN();
187
}
188

    
189
void OPPROTO op_load_xer_cr (void)
190
{
191
    T0 = (xer_so << 3) | (xer_ov << 2) | (xer_ca << 1);
192
    RETURN();
193
}
194

    
195
void OPPROTO op_clear_xer_ov (void)
196
{
197
    xer_so = 0;
198
    xer_ov = 0;
199
    RETURN();
200
}
201

    
202
void OPPROTO op_clear_xer_ca (void)
203
{
204
    xer_ca = 0;
205
    RETURN();
206
}
207

    
208
void OPPROTO op_load_xer_bc (void)
209
{
210
    T1 = xer_bc;
211
    RETURN();
212
}
213

    
214
void OPPROTO op_store_xer_bc (void)
215
{
216
    xer_bc = T0;
217
    RETURN();
218
}
219

    
220
void OPPROTO op_load_xer (void)
221
{
222
    T0 = hreg_load_xer(env);
223
    RETURN();
224
}
225

    
226
void OPPROTO op_store_xer (void)
227
{
228
    hreg_store_xer(env, T0);
229
    RETURN();
230
}
231

    
232
#if defined(TARGET_PPC64)
233
void OPPROTO op_store_pri (void)
234
{
235
    do_store_pri(PARAM1);
236
    RETURN();
237
}
238
#endif
239

    
240
#if !defined(CONFIG_USER_ONLY)
241
/* Segment registers load and store */
242
void OPPROTO op_load_sr (void)
243
{
244
    T0 = env->sr[T1];
245
    RETURN();
246
}
247

    
248
void OPPROTO op_store_sr (void)
249
{
250
    do_store_sr(env, T1, T0);
251
    RETURN();
252
}
253

    
254
#if defined(TARGET_PPC64)
255
void OPPROTO op_load_slb (void)
256
{
257
    T0 = ppc_load_slb(env, T1);
258
    RETURN();
259
}
260

    
261
void OPPROTO op_store_slb (void)
262
{
263
    ppc_store_slb(env, T1, T0);
264
    RETURN();
265
}
266
#endif /* defined(TARGET_PPC64) */
267

    
268
void OPPROTO op_load_sdr1 (void)
269
{
270
    T0 = env->sdr1;
271
    RETURN();
272
}
273

    
274
void OPPROTO op_store_sdr1 (void)
275
{
276
    do_store_sdr1(env, T0);
277
    RETURN();
278
}
279

    
280
#if defined (TARGET_PPC64)
281
void OPPROTO op_load_asr (void)
282
{
283
    T0 = env->asr;
284
    RETURN();
285
}
286

    
287
void OPPROTO op_store_asr (void)
288
{
289
    ppc_store_asr(env, T0);
290
    RETURN();
291
}
292
#endif
293

    
294
void OPPROTO op_load_msr (void)
295
{
296
    T0 = env->msr;
297
    RETURN();
298
}
299

    
300
void OPPROTO op_store_msr (void)
301
{
302
    do_store_msr();
303
    RETURN();
304
}
305

    
306
#if defined (TARGET_PPC64)
307
void OPPROTO op_store_msr_32 (void)
308
{
309
    T0 = (env->msr & ~0xFFFFFFFFULL) | (T0 & 0xFFFFFFFF);
310
    do_store_msr();
311
    RETURN();
312
}
313
#endif
314

    
315
void OPPROTO op_update_riee (void)
316
{
317
    /* We don't call do_store_msr here as we won't trigger
318
     * any special case nor change hflags
319
     */
320
    T0 &= (1 << MSR_RI) | (1 << MSR_EE);
321
    env->msr &= ~(1 << MSR_RI) | (1 << MSR_EE);
322
    env->msr |= T0;
323
    RETURN();
324
}
325
#endif
326

    
327
/* SPR */
328
void OPPROTO op_load_spr (void)
329
{
330
    T0 = env->spr[PARAM1];
331
    RETURN();
332
}
333

    
334
void OPPROTO op_store_spr (void)
335
{
336
    env->spr[PARAM1] = T0;
337
    RETURN();
338
}
339

    
340
void OPPROTO op_load_dump_spr (void)
341
{
342
    T0 = ppc_load_dump_spr(PARAM1);
343
    RETURN();
344
}
345

    
346
void OPPROTO op_store_dump_spr (void)
347
{
348
    ppc_store_dump_spr(PARAM1, T0);
349
    RETURN();
350
}
351

    
352
void OPPROTO op_mask_spr (void)
353
{
354
    env->spr[PARAM1] &= ~T0;
355
    RETURN();
356
}
357

    
358
void OPPROTO op_load_lr (void)
359
{
360
    T0 = env->lr;
361
    RETURN();
362
}
363

    
364
void OPPROTO op_store_lr (void)
365
{
366
    env->lr = T0;
367
    RETURN();
368
}
369

    
370
void OPPROTO op_load_ctr (void)
371
{
372
    T0 = env->ctr;
373
    RETURN();
374
}
375

    
376
void OPPROTO op_store_ctr (void)
377
{
378
    env->ctr = T0;
379
    RETURN();
380
}
381

    
382
void OPPROTO op_load_tbl (void)
383
{
384
    T0 = cpu_ppc_load_tbl(env);
385
    RETURN();
386
}
387

    
388
void OPPROTO op_load_tbu (void)
389
{
390
    T0 = cpu_ppc_load_tbu(env);
391
    RETURN();
392
}
393

    
394
void OPPROTO op_load_atbl (void)
395
{
396
    T0 = cpu_ppc_load_atbl(env);
397
    RETURN();
398
}
399

    
400
void OPPROTO op_load_atbu (void)
401
{
402
    T0 = cpu_ppc_load_atbu(env);
403
    RETURN();
404
}
405

    
406
#if !defined(CONFIG_USER_ONLY)
407
void OPPROTO op_store_tbl (void)
408
{
409
    cpu_ppc_store_tbl(env, T0);
410
    RETURN();
411
}
412

    
413
void OPPROTO op_store_tbu (void)
414
{
415
    cpu_ppc_store_tbu(env, T0);
416
    RETURN();
417
}
418

    
419
void OPPROTO op_store_atbl (void)
420
{
421
    cpu_ppc_store_atbl(env, T0);
422
    RETURN();
423
}
424

    
425
void OPPROTO op_store_atbu (void)
426
{
427
    cpu_ppc_store_atbu(env, T0);
428
    RETURN();
429
}
430

    
431
void OPPROTO op_load_decr (void)
432
{
433
    T0 = cpu_ppc_load_decr(env);
434
    RETURN();
435
}
436

    
437
void OPPROTO op_store_decr (void)
438
{
439
    cpu_ppc_store_decr(env, T0);
440
    RETURN();
441
}
442

    
443
void OPPROTO op_load_ibat (void)
444
{
445
    T0 = env->IBAT[PARAM1][PARAM2];
446
    RETURN();
447
}
448

    
449
void OPPROTO op_store_ibatu (void)
450
{
451
    do_store_ibatu(env, PARAM1, T0);
452
    RETURN();
453
}
454

    
455
void OPPROTO op_store_ibatl (void)
456
{
457
#if 1
458
    env->IBAT[1][PARAM1] = T0;
459
#else
460
    do_store_ibatl(env, PARAM1, T0);
461
#endif
462
    RETURN();
463
}
464

    
465
void OPPROTO op_load_dbat (void)
466
{
467
    T0 = env->DBAT[PARAM1][PARAM2];
468
    RETURN();
469
}
470

    
471
void OPPROTO op_store_dbatu (void)
472
{
473
    do_store_dbatu(env, PARAM1, T0);
474
    RETURN();
475
}
476

    
477
void OPPROTO op_store_dbatl (void)
478
{
479
#if 1
480
    env->DBAT[1][PARAM1] = T0;
481
#else
482
    do_store_dbatl(env, PARAM1, T0);
483
#endif
484
    RETURN();
485
}
486
#endif /* !defined(CONFIG_USER_ONLY) */
487

    
488
/* FPSCR */
489
#ifdef CONFIG_SOFTFLOAT
490
void OPPROTO op_reset_fpstatus (void)
491
{
492
    env->fp_status.float_exception_flags = 0;
493
    RETURN();
494
}
495
#endif
496

    
497
void OPPROTO op_compute_fprf (void)
498
{
499
    do_compute_fprf(PARAM1);
500
    RETURN();
501
}
502

    
503
#ifdef CONFIG_SOFTFLOAT
504
void OPPROTO op_float_check_status (void)
505
{
506
    do_float_check_status();
507
    RETURN();
508
}
509
#else
510
void OPPROTO op_float_check_status (void)
511
{
512
    if (env->exception_index == POWERPC_EXCP_PROGRAM &&
513
        (env->error_code & POWERPC_EXCP_FP)) {
514
        /* Differred floating-point exception after target FPR update */
515
        if (msr_fe0 != 0 || msr_fe1 != 0)
516
            do_raise_exception_err(env->exception_index, env->error_code);
517
    }
518
    RETURN();
519
}
520
#endif
521

    
522
void OPPROTO op_load_fpscr_FT0 (void)
523
{
524
    /* The 32 MSB of the target fpr are undefined.
525
     * They'll be zero...
526
     */
527
    CPU_DoubleU u;
528

    
529
    u.l.upper = 0;
530
    u.l.lower = env->fpscr;
531
    FT0 = u.d;
532
    RETURN();
533
}
534

    
535
void OPPROTO op_set_FT0 (void)
536
{
537
    CPU_DoubleU u;
538

    
539
    u.l.upper = 0;
540
    u.l.lower = PARAM1;
541
    FT0 = u.d;
542
    RETURN();
543
}
544

    
545
void OPPROTO op_load_fpscr_T0 (void)
546
{
547
    T0 = (env->fpscr >> PARAM1) & 0xF;
548
    RETURN();
549
}
550

    
551
void OPPROTO op_load_fpcc (void)
552
{
553
    T0 = fpscr_fpcc;
554
    RETURN();
555
}
556

    
557
void OPPROTO op_fpscr_resetbit (void)
558
{
559
    env->fpscr &= PARAM1;
560
    RETURN();
561
}
562

    
563
void OPPROTO op_fpscr_setbit (void)
564
{
565
    do_fpscr_setbit(PARAM1);
566
    RETURN();
567
}
568

    
569
void OPPROTO op_store_fpscr (void)
570
{
571
    do_store_fpscr(PARAM1);
572
    RETURN();
573
}
574

    
575
/* Branch */
576
#define EIP env->nip
577

    
578
void OPPROTO op_setlr (void)
579
{
580
    env->lr = (uint32_t)PARAM1;
581
    RETURN();
582
}
583

    
584
#if defined (TARGET_PPC64)
585
void OPPROTO op_setlr_64 (void)
586
{
587
    env->lr = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
588
    RETURN();
589
}
590
#endif
591

    
592
void OPPROTO op_b_T1 (void)
593
{
594
    env->nip = (uint32_t)(T1 & ~3);
595
    RETURN();
596
}
597

    
598
#if defined (TARGET_PPC64)
599
void OPPROTO op_b_T1_64 (void)
600
{
601
    env->nip = (uint64_t)(T1 & ~3);
602
    RETURN();
603
}
604
#endif
605

    
606
void OPPROTO op_jz_T0 (void)
607
{
608
    if (!T0)
609
        GOTO_LABEL_PARAM(1);
610
    RETURN();
611
}
612

    
613
void OPPROTO op_btest_T1 (void)
614
{
615
    if (T0) {
616
        env->nip = (uint32_t)(T1 & ~3);
617
    } else {
618
        env->nip = (uint32_t)PARAM1;
619
    }
620
    RETURN();
621
}
622

    
623
#if defined (TARGET_PPC64)
624
void OPPROTO op_btest_T1_64 (void)
625
{
626
    if (T0) {
627
        env->nip = (uint64_t)(T1 & ~3);
628
    } else {
629
        env->nip = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
630
    }
631
    RETURN();
632
}
633
#endif
634

    
635
void OPPROTO op_movl_T1_ctr (void)
636
{
637
    T1 = env->ctr;
638
    RETURN();
639
}
640

    
641
void OPPROTO op_movl_T1_lr (void)
642
{
643
    T1 = env->lr;
644
    RETURN();
645
}
646

    
647
/* tests with result in T0 */
648
void OPPROTO op_test_ctr (void)
649
{
650
    T0 = (uint32_t)env->ctr;
651
    RETURN();
652
}
653

    
654
#if defined(TARGET_PPC64)
655
void OPPROTO op_test_ctr_64 (void)
656
{
657
    T0 = (uint64_t)env->ctr;
658
    RETURN();
659
}
660
#endif
661

    
662
void OPPROTO op_test_ctr_true (void)
663
{
664
    T0 = ((uint32_t)env->ctr != 0 && (T0 & PARAM1) != 0);
665
    RETURN();
666
}
667

    
668
#if defined(TARGET_PPC64)
669
void OPPROTO op_test_ctr_true_64 (void)
670
{
671
    T0 = ((uint64_t)env->ctr != 0 && (T0 & PARAM1) != 0);
672
    RETURN();
673
}
674
#endif
675

    
676
void OPPROTO op_test_ctr_false (void)
677
{
678
    T0 = ((uint32_t)env->ctr != 0 && (T0 & PARAM1) == 0);
679
    RETURN();
680
}
681

    
682
#if defined(TARGET_PPC64)
683
void OPPROTO op_test_ctr_false_64 (void)
684
{
685
    T0 = ((uint64_t)env->ctr != 0 && (T0 & PARAM1) == 0);
686
    RETURN();
687
}
688
#endif
689

    
690
void OPPROTO op_test_ctrz (void)
691
{
692
    T0 = ((uint32_t)env->ctr == 0);
693
    RETURN();
694
}
695

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

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

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

    
718
void OPPROTO op_test_ctrz_false (void)
719
{
720
    T0 = ((uint32_t)env->ctr == 0 && (T0 & PARAM1) == 0);
721
    RETURN();
722
}
723

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

    
732
void OPPROTO op_test_true (void)
733
{
734
    T0 = (T0 & PARAM1);
735
    RETURN();
736
}
737

    
738
void OPPROTO op_test_false (void)
739
{
740
    T0 = ((T0 & PARAM1) == 0);
741
    RETURN();
742
}
743

    
744
/* CTR maintenance */
745
void OPPROTO op_dec_ctr (void)
746
{
747
    env->ctr--;
748
    RETURN();
749
}
750

    
751
/***                           Integer arithmetic                          ***/
752
/* add */
753
void OPPROTO op_add (void)
754
{
755
    T0 += T1;
756
    RETURN();
757
}
758

    
759
void OPPROTO op_check_addo (void)
760
{
761
    xer_ov = (((uint32_t)T2 ^ (uint32_t)T1 ^ UINT32_MAX) &
762
              ((uint32_t)T2 ^ (uint32_t)T0)) >> 31;
763
    xer_so |= xer_ov;
764
    RETURN();
765
}
766

    
767
#if defined(TARGET_PPC64)
768
void OPPROTO op_check_addo_64 (void)
769
{
770
    xer_ov = (((uint64_t)T2 ^ (uint64_t)T1 ^ UINT64_MAX) &
771
              ((uint64_t)T2 ^ (uint64_t)T0)) >> 63;
772
    xer_so |= xer_ov;
773
    RETURN();
774
}
775
#endif
776

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

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

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

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

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

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

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

    
845
void OPPROTO op_addmeo (void)
846
{
847
    do_addmeo();
848
    RETURN();
849
}
850

    
851
void OPPROTO op_addmeo_64 (void)
852
{
853
    do_addmeo();
854
    RETURN();
855
}
856

    
857
/* add to zero extended */
858
void OPPROTO op_add_ze (void)
859
{
860
    T0 += xer_ca;
861
    RETURN();
862
}
863

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

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

    
889
void OPPROTO op_divwo (void)
890
{
891
    do_divwo();
892
    RETURN();
893
}
894

    
895
#if defined(TARGET_PPC64)
896
void OPPROTO op_divdo (void)
897
{
898
    do_divdo();
899
    RETURN();
900
}
901
#endif
902

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

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

    
926
void OPPROTO op_divwuo (void)
927
{
928
    do_divwuo();
929
    RETURN();
930
}
931

    
932
#if defined(TARGET_PPC64)
933
void OPPROTO op_divduo (void)
934
{
935
    do_divduo();
936
    RETURN();
937
}
938
#endif
939

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

    
947
#if defined(TARGET_PPC64)
948
void OPPROTO op_mulhd (void)
949
{
950
    uint64_t tl, th;
951

    
952
    muls64(&tl, &th, T0, T1);
953
    T0 = th;
954
    RETURN();
955
}
956
#endif
957

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

    
965
#if defined(TARGET_PPC64)
966
void OPPROTO op_mulhdu (void)
967
{
968
    uint64_t tl, th;
969

    
970
    mulu64(&tl, &th, T0, T1);
971
    T0 = th;
972
    RETURN();
973
}
974
#endif
975

    
976
/* multiply low immediate */
977
void OPPROTO op_mulli (void)
978
{
979
    T0 = ((int32_t)T0 * (int32_t)PARAM1);
980
    RETURN();
981
}
982

    
983
/* multiply low word */
984
void OPPROTO op_mullw (void)
985
{
986
    T0 = (int32_t)(T0 * T1);
987
    RETURN();
988
}
989

    
990
#if defined(TARGET_PPC64)
991
void OPPROTO op_mulld (void)
992
{
993
    T0 *= T1;
994
    RETURN();
995
}
996
#endif
997

    
998
void OPPROTO op_mullwo (void)
999
{
1000
    do_mullwo();
1001
    RETURN();
1002
}
1003

    
1004
#if defined(TARGET_PPC64)
1005
void OPPROTO op_mulldo (void)
1006
{
1007
    do_mulldo();
1008
    RETURN();
1009
}
1010
#endif
1011

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

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

    
1031
void OPPROTO op_nego (void)
1032
{
1033
    do_nego();
1034
    RETURN();
1035
}
1036

    
1037
#if defined(TARGET_PPC64)
1038
void OPPROTO op_nego_64 (void)
1039
{
1040
    do_nego_64();
1041
    RETURN();
1042
}
1043
#endif
1044

    
1045
/* subtract from */
1046
void OPPROTO op_subf (void)
1047
{
1048
    T0 = T1 - T0;
1049
    RETURN();
1050
}
1051

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

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

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

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

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

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

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

    
1126
#if defined(TARGET_PPC64)
1127
void OPPROTO op_subfme_64 (void)
1128
{
1129
    T0 = ~T0 + xer_ca - 1;
1130
    if (likely((uint64_t)T0 != UINT64_MAX))
1131
        xer_ca = 1;
1132
    else
1133
        xer_ca = 0;
1134
    RETURN();
1135
}
1136
#endif
1137

    
1138
void OPPROTO op_subfmeo (void)
1139
{
1140
    do_subfmeo();
1141
    RETURN();
1142
}
1143

    
1144
#if defined(TARGET_PPC64)
1145
void OPPROTO op_subfmeo_64 (void)
1146
{
1147
    do_subfmeo_64();
1148
    RETURN();
1149
}
1150
#endif
1151

    
1152
/* subtract from zero extended */
1153
void OPPROTO op_subfze (void)
1154
{
1155
    T1 = ~T0;
1156
    T0 = T1 + xer_ca;
1157
    if ((uint32_t)T0 < (uint32_t)T1) {
1158
        xer_ca = 1;
1159
    } else {
1160
        xer_ca = 0;
1161
    }
1162
    RETURN();
1163
}
1164

    
1165
#if defined(TARGET_PPC64)
1166
void OPPROTO op_subfze_64 (void)
1167
{
1168
    T1 = ~T0;
1169
    T0 = T1 + xer_ca;
1170
    if ((uint64_t)T0 < (uint64_t)T1) {
1171
        xer_ca = 1;
1172
    } else {
1173
        xer_ca = 0;
1174
    }
1175
    RETURN();
1176
}
1177
#endif
1178

    
1179
void OPPROTO op_subfzeo (void)
1180
{
1181
    do_subfzeo();
1182
    RETURN();
1183
}
1184

    
1185
#if defined(TARGET_PPC64)
1186
void OPPROTO op_subfzeo_64 (void)
1187
{
1188
    do_subfzeo_64();
1189
    RETURN();
1190
}
1191
#endif
1192

    
1193
/***                           Integer comparison                          ***/
1194
/* compare */
1195
void OPPROTO op_cmp (void)
1196
{
1197
    if ((int32_t)T0 < (int32_t)T1) {
1198
        T0 = 0x08;
1199
    } else if ((int32_t)T0 > (int32_t)T1) {
1200
        T0 = 0x04;
1201
    } else {
1202
        T0 = 0x02;
1203
    }
1204
    T0 |= xer_so;
1205
    RETURN();
1206
}
1207

    
1208
#if defined(TARGET_PPC64)
1209
void OPPROTO op_cmp_64 (void)
1210
{
1211
    if ((int64_t)T0 < (int64_t)T1) {
1212
        T0 = 0x08;
1213
    } else if ((int64_t)T0 > (int64_t)T1) {
1214
        T0 = 0x04;
1215
    } else {
1216
        T0 = 0x02;
1217
    }
1218
    T0 |= xer_so;
1219
    RETURN();
1220
}
1221
#endif
1222

    
1223
/* compare immediate */
1224
void OPPROTO op_cmpi (void)
1225
{
1226
    if ((int32_t)T0 < (int32_t)PARAM1) {
1227
        T0 = 0x08;
1228
    } else if ((int32_t)T0 > (int32_t)PARAM1) {
1229
        T0 = 0x04;
1230
    } else {
1231
        T0 = 0x02;
1232
    }
1233
    T0 |= xer_so;
1234
    RETURN();
1235
}
1236

    
1237
#if defined(TARGET_PPC64)
1238
void OPPROTO op_cmpi_64 (void)
1239
{
1240
    if ((int64_t)T0 < (int64_t)((int32_t)PARAM1)) {
1241
        T0 = 0x08;
1242
    } else if ((int64_t)T0 > (int64_t)((int32_t)PARAM1)) {
1243
        T0 = 0x04;
1244
    } else {
1245
        T0 = 0x02;
1246
    }
1247
    T0 |= xer_so;
1248
    RETURN();
1249
}
1250
#endif
1251

    
1252
/* compare logical */
1253
void OPPROTO op_cmpl (void)
1254
{
1255
    if ((uint32_t)T0 < (uint32_t)T1) {
1256
        T0 = 0x08;
1257
    } else if ((uint32_t)T0 > (uint32_t)T1) {
1258
        T0 = 0x04;
1259
    } else {
1260
        T0 = 0x02;
1261
    }
1262
    T0 |= xer_so;
1263
    RETURN();
1264
}
1265

    
1266
#if defined(TARGET_PPC64)
1267
void OPPROTO op_cmpl_64 (void)
1268
{
1269
    if ((uint64_t)T0 < (uint64_t)T1) {
1270
        T0 = 0x08;
1271
    } else if ((uint64_t)T0 > (uint64_t)T1) {
1272
        T0 = 0x04;
1273
    } else {
1274
        T0 = 0x02;
1275
    }
1276
    T0 |= xer_so;
1277
    RETURN();
1278
}
1279
#endif
1280

    
1281
/* compare logical immediate */
1282
void OPPROTO op_cmpli (void)
1283
{
1284
    if ((uint32_t)T0 < (uint32_t)PARAM1) {
1285
        T0 = 0x08;
1286
    } else if ((uint32_t)T0 > (uint32_t)PARAM1) {
1287
        T0 = 0x04;
1288
    } else {
1289
        T0 = 0x02;
1290
    }
1291
    T0 |= xer_so;
1292
    RETURN();
1293
}
1294

    
1295
#if defined(TARGET_PPC64)
1296
void OPPROTO op_cmpli_64 (void)
1297
{
1298
    if ((uint64_t)T0 < (uint64_t)PARAM1) {
1299
        T0 = 0x08;
1300
    } else if ((uint64_t)T0 > (uint64_t)PARAM1) {
1301
        T0 = 0x04;
1302
    } else {
1303
        T0 = 0x02;
1304
    }
1305
    T0 |= xer_so;
1306
    RETURN();
1307
}
1308
#endif
1309

    
1310
void OPPROTO op_isel (void)
1311
{
1312
    if (T0)
1313
        T0 = T1;
1314
    else
1315
        T0 = T2;
1316
    RETURN();
1317
}
1318

    
1319
void OPPROTO op_popcntb (void)
1320
{
1321
    do_popcntb();
1322
    RETURN();
1323
}
1324

    
1325
#if defined(TARGET_PPC64)
1326
void OPPROTO op_popcntb_64 (void)
1327
{
1328
    do_popcntb_64();
1329
    RETURN();
1330
}
1331
#endif
1332

    
1333
/***                            Integer logical                            ***/
1334
/* and */
1335
void OPPROTO op_and (void)
1336
{
1337
    T0 &= T1;
1338
    RETURN();
1339
}
1340

    
1341
/* andc */
1342
void OPPROTO op_andc (void)
1343
{
1344
    T0 &= ~T1;
1345
    RETURN();
1346
}
1347

    
1348
/* andi. */
1349
void OPPROTO op_andi_T0 (void)
1350
{
1351
    T0 &= (uint32_t)PARAM1;
1352
    RETURN();
1353
}
1354

    
1355
void OPPROTO op_andi_T1 (void)
1356
{
1357
    T1 &= (uint32_t)PARAM1;
1358
    RETURN();
1359
}
1360

    
1361
#if defined(TARGET_PPC64)
1362
void OPPROTO op_andi_T0_64 (void)
1363
{
1364
    T0 &= ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
1365
    RETURN();
1366
}
1367

    
1368
void OPPROTO op_andi_T1_64 (void)
1369
{
1370
    T1 &= ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
1371
    RETURN();
1372
}
1373
#endif
1374

    
1375
/* count leading zero */
1376
void OPPROTO op_cntlzw (void)
1377
{
1378
    do_cntlzw();
1379
    RETURN();
1380
}
1381

    
1382
#if defined(TARGET_PPC64)
1383
void OPPROTO op_cntlzd (void)
1384
{
1385
    do_cntlzd();
1386
    RETURN();
1387
}
1388
#endif
1389

    
1390
/* eqv */
1391
void OPPROTO op_eqv (void)
1392
{
1393
    T0 = ~(T0 ^ T1);
1394
    RETURN();
1395
}
1396

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

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

    
1419
#if defined (TARGET_PPC64)
1420
void OPPROTO op_extsw (void)
1421
{
1422
    T0 = (int64_t)((int32_t)T0);
1423
    RETURN();
1424
}
1425
#endif
1426

    
1427
/* nand */
1428
void OPPROTO op_nand (void)
1429
{
1430
    T0 = ~(T0 & T1);
1431
    RETURN();
1432
}
1433

    
1434
/* nor */
1435
void OPPROTO op_nor (void)
1436
{
1437
    T0 = ~(T0 | T1);
1438
    RETURN();
1439
}
1440

    
1441
/* or */
1442
void OPPROTO op_or (void)
1443
{
1444
    T0 |= T1;
1445
    RETURN();
1446
}
1447

    
1448
/* orc */
1449
void OPPROTO op_orc (void)
1450
{
1451
    T0 |= ~T1;
1452
    RETURN();
1453
}
1454

    
1455
/* ori */
1456
void OPPROTO op_ori (void)
1457
{
1458
    T0 |= (uint32_t)PARAM1;
1459
    RETURN();
1460
}
1461

    
1462
/* xor */
1463
void OPPROTO op_xor (void)
1464
{
1465
    T0 ^= T1;
1466
    RETURN();
1467
}
1468

    
1469
/* xori */
1470
void OPPROTO op_xori (void)
1471
{
1472
    T0 ^= (uint32_t)PARAM1;
1473
    RETURN();
1474
}
1475

    
1476
/***                             Integer rotate                            ***/
1477
void OPPROTO op_rotl32_T0_T1 (void)
1478
{
1479
    T0 = rotl32(T0, T1 & 0x1F);
1480
    RETURN();
1481
}
1482

    
1483
void OPPROTO op_rotli32_T0 (void)
1484
{
1485
    T0 = rotl32(T0, PARAM1);
1486
    RETURN();
1487
}
1488

    
1489
#if defined(TARGET_PPC64)
1490
void OPPROTO op_rotl64_T0_T1 (void)
1491
{
1492
    T0 = rotl64(T0, T1 & 0x3F);
1493
    RETURN();
1494
}
1495

    
1496
void OPPROTO op_rotli64_T0 (void)
1497
{
1498
    T0 = rotl64(T0, PARAM1);
1499
    RETURN();
1500
}
1501
#endif
1502

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

    
1515
#if defined(TARGET_PPC64)
1516
void OPPROTO op_sld (void)
1517
{
1518
    if (T1 & 0x40) {
1519
        T0 = 0;
1520
    } else {
1521
        T0 = T0 << T1;
1522
    }
1523
    RETURN();
1524
}
1525
#endif
1526

    
1527
/* shift right algebraic word */
1528
void OPPROTO op_sraw (void)
1529
{
1530
    do_sraw();
1531
    RETURN();
1532
}
1533

    
1534
#if defined(TARGET_PPC64)
1535
void OPPROTO op_srad (void)
1536
{
1537
    do_srad();
1538
    RETURN();
1539
}
1540
#endif
1541

    
1542
/* shift right algebraic word immediate */
1543
void OPPROTO op_srawi (void)
1544
{
1545
    uint32_t mask = (uint32_t)PARAM2;
1546

    
1547
    T0 = (int32_t)T0 >> PARAM1;
1548
    if ((int32_t)T1 < 0 && (T1 & mask) != 0) {
1549
        xer_ca = 1;
1550
    } else {
1551
        xer_ca = 0;
1552
    }
1553
    RETURN();
1554
}
1555

    
1556
#if defined(TARGET_PPC64)
1557
void OPPROTO op_sradi (void)
1558
{
1559
    uint64_t mask = ((uint64_t)PARAM2 << 32) | (uint64_t)PARAM3;
1560

    
1561
    T0 = (int64_t)T0 >> PARAM1;
1562
    if ((int64_t)T1 < 0 && ((uint64_t)T1 & mask) != 0) {
1563
        xer_ca = 1;
1564
    } else {
1565
        xer_ca = 0;
1566
    }
1567
    RETURN();
1568
}
1569
#endif
1570

    
1571
/* shift right word */
1572
void OPPROTO op_srw (void)
1573
{
1574
    if (T1 & 0x20) {
1575
        T0 = 0;
1576
    } else {
1577
        T0 = (uint32_t)T0 >> T1;
1578
    }
1579
    RETURN();
1580
}
1581

    
1582
#if defined(TARGET_PPC64)
1583
void OPPROTO op_srd (void)
1584
{
1585
    if (T1 & 0x40) {
1586
        T0 = 0;
1587
    } else {
1588
        T0 = (uint64_t)T0 >> T1;
1589
    }
1590
    RETURN();
1591
}
1592
#endif
1593

    
1594
void OPPROTO op_sl_T0_T1 (void)
1595
{
1596
    T0 = T0 << T1;
1597
    RETURN();
1598
}
1599

    
1600
void OPPROTO op_sli_T0 (void)
1601
{
1602
    T0 = T0 << PARAM1;
1603
    RETURN();
1604
}
1605

    
1606
void OPPROTO op_sli_T1 (void)
1607
{
1608
    T1 = T1 << PARAM1;
1609
    RETURN();
1610
}
1611

    
1612
void OPPROTO op_srl_T0_T1 (void)
1613
{
1614
    T0 = (uint32_t)T0 >> T1;
1615
    RETURN();
1616
}
1617

    
1618
#if defined(TARGET_PPC64)
1619
void OPPROTO op_srl_T0_T1_64 (void)
1620
{
1621
    T0 = (uint32_t)T0 >> T1;
1622
    RETURN();
1623
}
1624
#endif
1625

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

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

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

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

    
1654
/***                       Floating-Point arithmetic                       ***/
1655
/* fadd - fadd. */
1656
void OPPROTO op_fadd (void)
1657
{
1658
#if USE_PRECISE_EMULATION
1659
    do_fadd();
1660
#else
1661
    FT0 = float64_add(FT0, FT1, &env->fp_status);
1662
#endif
1663
    RETURN();
1664
}
1665

    
1666
/* fsub - fsub. */
1667
void OPPROTO op_fsub (void)
1668
{
1669
#if USE_PRECISE_EMULATION
1670
    do_fsub();
1671
#else
1672
    FT0 = float64_sub(FT0, FT1, &env->fp_status);
1673
#endif
1674
    RETURN();
1675
}
1676

    
1677
/* fmul - fmul. */
1678
void OPPROTO op_fmul (void)
1679
{
1680
#if USE_PRECISE_EMULATION
1681
    do_fmul();
1682
#else
1683
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1684
#endif
1685
    RETURN();
1686
}
1687

    
1688
/* fdiv - fdiv. */
1689
void OPPROTO op_fdiv (void)
1690
{
1691
#if USE_PRECISE_EMULATION
1692
    do_fdiv();
1693
#else
1694
    FT0 = float64_div(FT0, FT1, &env->fp_status);
1695
#endif
1696
    RETURN();
1697
}
1698

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

    
1706
/* fre - fre. */
1707
void OPPROTO op_fre (void)
1708
{
1709
    do_fre();
1710
    RETURN();
1711
}
1712

    
1713
/* fres - fres. */
1714
void OPPROTO op_fres (void)
1715
{
1716
    do_fres();
1717
    RETURN();
1718
}
1719

    
1720
/* frsqrte  - frsqrte. */
1721
void OPPROTO op_frsqrte (void)
1722
{
1723
    do_frsqrte();
1724
    RETURN();
1725
}
1726

    
1727
/* fsel - fsel. */
1728
void OPPROTO op_fsel (void)
1729
{
1730
    do_fsel();
1731
    RETURN();
1732
}
1733

    
1734
/***                     Floating-Point multiply-and-add                   ***/
1735
/* fmadd - fmadd. */
1736
void OPPROTO op_fmadd (void)
1737
{
1738
#if USE_PRECISE_EMULATION
1739
    do_fmadd();
1740
#else
1741
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1742
    FT0 = float64_add(FT0, FT2, &env->fp_status);
1743
#endif
1744
    RETURN();
1745
}
1746

    
1747
/* fmsub - fmsub. */
1748
void OPPROTO op_fmsub (void)
1749
{
1750
#if USE_PRECISE_EMULATION
1751
    do_fmsub();
1752
#else
1753
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1754
    FT0 = float64_sub(FT0, FT2, &env->fp_status);
1755
#endif
1756
    RETURN();
1757
}
1758

    
1759
/* fnmadd - fnmadd. - fnmadds - fnmadds. */
1760
void OPPROTO op_fnmadd (void)
1761
{
1762
    do_fnmadd();
1763
    RETURN();
1764
}
1765

    
1766
/* fnmsub - fnmsub. */
1767
void OPPROTO op_fnmsub (void)
1768
{
1769
    do_fnmsub();
1770
    RETURN();
1771
}
1772

    
1773
/***                     Floating-Point round & convert                    ***/
1774
/* frsp - frsp. */
1775
void OPPROTO op_frsp (void)
1776
{
1777
#if USE_PRECISE_EMULATION
1778
    do_frsp();
1779
#else
1780
    FT0 = float64_to_float32(FT0, &env->fp_status);
1781
#endif
1782
    RETURN();
1783
}
1784

    
1785
/* fctiw - fctiw. */
1786
void OPPROTO op_fctiw (void)
1787
{
1788
    do_fctiw();
1789
    RETURN();
1790
}
1791

    
1792
/* fctiwz - fctiwz. */
1793
void OPPROTO op_fctiwz (void)
1794
{
1795
    do_fctiwz();
1796
    RETURN();
1797
}
1798

    
1799
#if defined(TARGET_PPC64)
1800
/* fcfid - fcfid. */
1801
void OPPROTO op_fcfid (void)
1802
{
1803
    do_fcfid();
1804
    RETURN();
1805
}
1806

    
1807
/* fctid - fctid. */
1808
void OPPROTO op_fctid (void)
1809
{
1810
    do_fctid();
1811
    RETURN();
1812
}
1813

    
1814
/* fctidz - fctidz. */
1815
void OPPROTO op_fctidz (void)
1816
{
1817
    do_fctidz();
1818
    RETURN();
1819
}
1820
#endif
1821

    
1822
void OPPROTO op_frin (void)
1823
{
1824
    do_frin();
1825
    RETURN();
1826
}
1827

    
1828
void OPPROTO op_friz (void)
1829
{
1830
    do_friz();
1831
    RETURN();
1832
}
1833

    
1834
void OPPROTO op_frip (void)
1835
{
1836
    do_frip();
1837
    RETURN();
1838
}
1839

    
1840
void OPPROTO op_frim (void)
1841
{
1842
    do_frim();
1843
    RETURN();
1844
}
1845

    
1846
/***                         Floating-Point compare                        ***/
1847
/* fcmpu */
1848
void OPPROTO op_fcmpu (void)
1849
{
1850
    do_fcmpu();
1851
    RETURN();
1852
}
1853

    
1854
/* fcmpo */
1855
void OPPROTO op_fcmpo (void)
1856
{
1857
    do_fcmpo();
1858
    RETURN();
1859
}
1860

    
1861
/***                         Floating-point move                           ***/
1862
/* fabs */
1863
void OPPROTO op_fabs (void)
1864
{
1865
    FT0 = float64_abs(FT0);
1866
    RETURN();
1867
}
1868

    
1869
/* fnabs */
1870
void OPPROTO op_fnabs (void)
1871
{
1872
    FT0 = float64_abs(FT0);
1873
    FT0 = float64_chs(FT0);
1874
    RETURN();
1875
}
1876

    
1877
/* fneg */
1878
void OPPROTO op_fneg (void)
1879
{
1880
    FT0 = float64_chs(FT0);
1881
    RETURN();
1882
}
1883

    
1884
/* Load and store */
1885
#define MEMSUFFIX _raw
1886
#include "op_helper.h"
1887
#include "op_mem.h"
1888
#if !defined(CONFIG_USER_ONLY)
1889
#define MEMSUFFIX _user
1890
#include "op_helper.h"
1891
#include "op_mem.h"
1892
#define MEMSUFFIX _kernel
1893
#include "op_helper.h"
1894
#include "op_mem.h"
1895
#define MEMSUFFIX _hypv
1896
#include "op_helper.h"
1897
#include "op_mem.h"
1898
#endif
1899

    
1900
/* Special op to check and maybe clear reservation */
1901
void OPPROTO op_check_reservation (void)
1902
{
1903
    if ((uint32_t)env->reserve == (uint32_t)(T0 & ~0x00000003))
1904
        env->reserve = (target_ulong)-1ULL;
1905
    RETURN();
1906
}
1907

    
1908
#if defined(TARGET_PPC64)
1909
void OPPROTO op_check_reservation_64 (void)
1910
{
1911
    if ((uint64_t)env->reserve == (uint64_t)(T0 & ~0x00000003))
1912
        env->reserve = (target_ulong)-1ULL;
1913
    RETURN();
1914
}
1915
#endif
1916

    
1917
void OPPROTO op_wait (void)
1918
{
1919
    env->halted = 1;
1920
    RETURN();
1921
}
1922

    
1923
/* Return from interrupt */
1924
#if !defined(CONFIG_USER_ONLY)
1925
void OPPROTO op_rfi (void)
1926
{
1927
    do_rfi();
1928
    RETURN();
1929
}
1930

    
1931
#if defined(TARGET_PPC64)
1932
void OPPROTO op_rfid (void)
1933
{
1934
    do_rfid();
1935
    RETURN();
1936
}
1937

    
1938
void OPPROTO op_hrfid (void)
1939
{
1940
    do_hrfid();
1941
    RETURN();
1942
}
1943
#endif
1944

    
1945
/* Exception vectors */
1946
void OPPROTO op_store_excp_prefix (void)
1947
{
1948
    T0 &= env->ivpr_mask;
1949
    env->excp_prefix = T0;
1950
    RETURN();
1951
}
1952

    
1953
void OPPROTO op_store_excp_vector (void)
1954
{
1955
    T0 &= env->ivor_mask;
1956
    env->excp_vectors[PARAM1] = T0;
1957
    RETURN();
1958
}
1959
#endif
1960

    
1961
/* Trap word */
1962
void OPPROTO op_tw (void)
1963
{
1964
    do_tw(PARAM1);
1965
    RETURN();
1966
}
1967

    
1968
#if defined(TARGET_PPC64)
1969
void OPPROTO op_td (void)
1970
{
1971
    do_td(PARAM1);
1972
    RETURN();
1973
}
1974
#endif
1975

    
1976
#if !defined(CONFIG_USER_ONLY)
1977
/* tlbia */
1978
void OPPROTO op_tlbia (void)
1979
{
1980
    ppc_tlb_invalidate_all(env);
1981
    RETURN();
1982
}
1983

    
1984
/* tlbie */
1985
void OPPROTO op_tlbie (void)
1986
{
1987
    ppc_tlb_invalidate_one(env, (uint32_t)T0);
1988
    RETURN();
1989
}
1990

    
1991
#if defined(TARGET_PPC64)
1992
void OPPROTO op_tlbie_64 (void)
1993
{
1994
    ppc_tlb_invalidate_one(env, T0);
1995
    RETURN();
1996
}
1997
#endif
1998

    
1999
#if defined(TARGET_PPC64)
2000
void OPPROTO op_slbia (void)
2001
{
2002
    ppc_slb_invalidate_all(env);
2003
    RETURN();
2004
}
2005

    
2006
void OPPROTO op_slbie (void)
2007
{
2008
    ppc_slb_invalidate_one(env, (uint32_t)T0);
2009
    RETURN();
2010
}
2011

    
2012
void OPPROTO op_slbie_64 (void)
2013
{
2014
    ppc_slb_invalidate_one(env, T0);
2015
    RETURN();
2016
}
2017
#endif
2018
#endif
2019

    
2020
#if !defined(CONFIG_USER_ONLY)
2021
/* PowerPC 602/603/755 software TLB load instructions */
2022
void OPPROTO op_6xx_tlbld (void)
2023
{
2024
    do_load_6xx_tlb(0);
2025
    RETURN();
2026
}
2027

    
2028
void OPPROTO op_6xx_tlbli (void)
2029
{
2030
    do_load_6xx_tlb(1);
2031
    RETURN();
2032
}
2033

    
2034
/* PowerPC 74xx software TLB load instructions */
2035
void OPPROTO op_74xx_tlbld (void)
2036
{
2037
    do_load_74xx_tlb(0);
2038
    RETURN();
2039
}
2040

    
2041
void OPPROTO op_74xx_tlbli (void)
2042
{
2043
    do_load_74xx_tlb(1);
2044
    RETURN();
2045
}
2046
#endif
2047

    
2048
/* 601 specific */
2049
void OPPROTO op_load_601_rtcl (void)
2050
{
2051
    T0 = cpu_ppc601_load_rtcl(env);
2052
    RETURN();
2053
}
2054

    
2055
void OPPROTO op_load_601_rtcu (void)
2056
{
2057
    T0 = cpu_ppc601_load_rtcu(env);
2058
    RETURN();
2059
}
2060

    
2061
#if !defined(CONFIG_USER_ONLY)
2062
void OPPROTO op_store_601_rtcl (void)
2063
{
2064
    cpu_ppc601_store_rtcl(env, T0);
2065
    RETURN();
2066
}
2067

    
2068
void OPPROTO op_store_601_rtcu (void)
2069
{
2070
    cpu_ppc601_store_rtcu(env, T0);
2071
    RETURN();
2072
}
2073

    
2074
void OPPROTO op_store_hid0_601 (void)
2075
{
2076
    do_store_hid0_601();
2077
    RETURN();
2078
}
2079

    
2080
void OPPROTO op_load_601_bat (void)
2081
{
2082
    T0 = env->IBAT[PARAM1][PARAM2];
2083
    RETURN();
2084
}
2085

    
2086
void OPPROTO op_store_601_batl (void)
2087
{
2088
    do_store_ibatl_601(env, PARAM1, T0);
2089
    RETURN();
2090
}
2091

    
2092
void OPPROTO op_store_601_batu (void)
2093
{
2094
    do_store_ibatu_601(env, PARAM1, T0);
2095
    RETURN();
2096
}
2097
#endif /* !defined(CONFIG_USER_ONLY) */
2098

    
2099
/* PowerPC 601 specific instructions (POWER bridge) */
2100
/* XXX: those micro-ops need tests ! */
2101
void OPPROTO op_POWER_abs (void)
2102
{
2103
    if ((int32_t)T0 == INT32_MIN)
2104
        T0 = INT32_MAX;
2105
    else if ((int32_t)T0 < 0)
2106
        T0 = -T0;
2107
    RETURN();
2108
}
2109

    
2110
void OPPROTO op_POWER_abso (void)
2111
{
2112
    do_POWER_abso();
2113
    RETURN();
2114
}
2115

    
2116
void OPPROTO op_POWER_clcs (void)
2117
{
2118
    do_POWER_clcs();
2119
    RETURN();
2120
}
2121

    
2122
void OPPROTO op_POWER_div (void)
2123
{
2124
    do_POWER_div();
2125
    RETURN();
2126
}
2127

    
2128
void OPPROTO op_POWER_divo (void)
2129
{
2130
    do_POWER_divo();
2131
    RETURN();
2132
}
2133

    
2134
void OPPROTO op_POWER_divs (void)
2135
{
2136
    do_POWER_divs();
2137
    RETURN();
2138
}
2139

    
2140
void OPPROTO op_POWER_divso (void)
2141
{
2142
    do_POWER_divso();
2143
    RETURN();
2144
}
2145

    
2146
void OPPROTO op_POWER_doz (void)
2147
{
2148
    if ((int32_t)T1 > (int32_t)T0)
2149
        T0 = T1 - T0;
2150
    else
2151
        T0 = 0;
2152
    RETURN();
2153
}
2154

    
2155
void OPPROTO op_POWER_dozo (void)
2156
{
2157
    do_POWER_dozo();
2158
    RETURN();
2159
}
2160

    
2161
void OPPROTO op_load_xer_cmp (void)
2162
{
2163
    T2 = xer_cmp;
2164
    RETURN();
2165
}
2166

    
2167
void OPPROTO op_POWER_maskg (void)
2168
{
2169
    do_POWER_maskg();
2170
    RETURN();
2171
}
2172

    
2173
void OPPROTO op_POWER_maskir (void)
2174
{
2175
    T0 = (T0 & ~T2) | (T1 & T2);
2176
    RETURN();
2177
}
2178

    
2179
void OPPROTO op_POWER_mul (void)
2180
{
2181
    uint64_t tmp;
2182

    
2183
    tmp = (uint64_t)T0 * (uint64_t)T1;
2184
    env->spr[SPR_MQ] = tmp >> 32;
2185
    T0 = tmp;
2186
    RETURN();
2187
}
2188

    
2189
void OPPROTO op_POWER_mulo (void)
2190
{
2191
    do_POWER_mulo();
2192
    RETURN();
2193
}
2194

    
2195
void OPPROTO op_POWER_nabs (void)
2196
{
2197
    if (T0 > 0)
2198
        T0 = -T0;
2199
    RETURN();
2200
}
2201

    
2202
void OPPROTO op_POWER_nabso (void)
2203
{
2204
    /* nabs never overflows */
2205
    if (T0 > 0)
2206
        T0 = -T0;
2207
    xer_ov = 0;
2208
    RETURN();
2209
}
2210

    
2211
/* XXX: factorise POWER rotates... */
2212
void OPPROTO op_POWER_rlmi (void)
2213
{
2214
    T0 = rotl32(T0, T2) & PARAM1;
2215
    T0 |= T1 & (uint32_t)PARAM2;
2216
    RETURN();
2217
}
2218

    
2219
void OPPROTO op_POWER_rrib (void)
2220
{
2221
    T2 &= 0x1FUL;
2222
    T0 = rotl32(T0 & INT32_MIN, T2);
2223
    T0 |= T1 & ~rotl32(INT32_MIN, T2);
2224
    RETURN();
2225
}
2226

    
2227
void OPPROTO op_POWER_sle (void)
2228
{
2229
    T1 &= 0x1FUL;
2230
    env->spr[SPR_MQ] = rotl32(T0, T1);
2231
    T0 = T0 << T1;
2232
    RETURN();
2233
}
2234

    
2235
void OPPROTO op_POWER_sleq (void)
2236
{
2237
    uint32_t tmp = env->spr[SPR_MQ];
2238

    
2239
    T1 &= 0x1FUL;
2240
    env->spr[SPR_MQ] = rotl32(T0, T1);
2241
    T0 = T0 << T1;
2242
    T0 |= tmp >> (32 - T1);
2243
    RETURN();
2244
}
2245

    
2246
void OPPROTO op_POWER_sllq (void)
2247
{
2248
    uint32_t msk = UINT32_MAX;
2249

    
2250
    msk = msk << (T1 & 0x1FUL);
2251
    if (T1 & 0x20UL)
2252
        msk = ~msk;
2253
    T1 &= 0x1FUL;
2254
    T0 = (T0 << T1) & msk;
2255
    T0 |= env->spr[SPR_MQ] & ~msk;
2256
    RETURN();
2257
}
2258

    
2259
void OPPROTO op_POWER_slq (void)
2260
{
2261
    uint32_t msk = UINT32_MAX, tmp;
2262

    
2263
    msk = msk << (T1 & 0x1FUL);
2264
    if (T1 & 0x20UL)
2265
        msk = ~msk;
2266
    T1 &= 0x1FUL;
2267
    tmp = rotl32(T0, T1);
2268
    T0 = tmp & msk;
2269
    env->spr[SPR_MQ] = tmp;
2270
    RETURN();
2271
}
2272

    
2273
void OPPROTO op_POWER_sraq (void)
2274
{
2275
    env->spr[SPR_MQ] = rotl32(T0, 32 - (T1 & 0x1FUL));
2276
    if (T1 & 0x20UL)
2277
        T0 = UINT32_MAX;
2278
    else
2279
        T0 = (int32_t)T0 >> T1;
2280
    RETURN();
2281
}
2282

    
2283
void OPPROTO op_POWER_sre (void)
2284
{
2285
    T1 &= 0x1FUL;
2286
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2287
    T0 = (int32_t)T0 >> T1;
2288
    RETURN();
2289
}
2290

    
2291
void OPPROTO op_POWER_srea (void)
2292
{
2293
    T1 &= 0x1FUL;
2294
    env->spr[SPR_MQ] = T0 >> T1;
2295
    T0 = (int32_t)T0 >> T1;
2296
    RETURN();
2297
}
2298

    
2299
void OPPROTO op_POWER_sreq (void)
2300
{
2301
    uint32_t tmp;
2302
    int32_t msk;
2303

    
2304
    T1 &= 0x1FUL;
2305
    msk = INT32_MIN >> T1;
2306
    tmp = env->spr[SPR_MQ];
2307
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2308
    T0 = T0 >> T1;
2309
    T0 |= tmp & msk;
2310
    RETURN();
2311
}
2312

    
2313
void OPPROTO op_POWER_srlq (void)
2314
{
2315
    uint32_t tmp;
2316
    int32_t msk;
2317

    
2318
    msk = INT32_MIN >> (T1 & 0x1FUL);
2319
    if (T1 & 0x20UL)
2320
        msk = ~msk;
2321
    T1 &= 0x1FUL;
2322
    tmp = env->spr[SPR_MQ];
2323
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2324
    T0 = T0 >> T1;
2325
    T0 &= msk;
2326
    T0 |= tmp & ~msk;
2327
    RETURN();
2328
}
2329

    
2330
void OPPROTO op_POWER_srq (void)
2331
{
2332
    T1 &= 0x1FUL;
2333
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2334
    T0 = T0 >> T1;
2335
    RETURN();
2336
}
2337

    
2338
/* POWER instructions not implemented in PowerPC 601 */
2339
#if !defined(CONFIG_USER_ONLY)
2340
void OPPROTO op_POWER_mfsri (void)
2341
{
2342
    T1 = T0 >> 28;
2343
    T0 = env->sr[T1];
2344
    RETURN();
2345
}
2346

    
2347
void OPPROTO op_POWER_rac (void)
2348
{
2349
    do_POWER_rac();
2350
    RETURN();
2351
}
2352

    
2353
void OPPROTO op_POWER_rfsvc (void)
2354
{
2355
    do_POWER_rfsvc();
2356
    RETURN();
2357
}
2358
#endif
2359

    
2360
/* PowerPC 602 specific instruction */
2361
#if !defined(CONFIG_USER_ONLY)
2362
void OPPROTO op_602_mfrom (void)
2363
{
2364
    do_op_602_mfrom();
2365
    RETURN();
2366
}
2367
#endif
2368

    
2369
/* PowerPC 4xx specific micro-ops */
2370
void OPPROTO op_405_add_T0_T2 (void)
2371
{
2372
    T0 = (int32_t)T0 + (int32_t)T2;
2373
    RETURN();
2374
}
2375

    
2376
void OPPROTO op_405_mulchw (void)
2377
{
2378
    T0 = ((int16_t)T0) * ((int16_t)(T1 >> 16));
2379
    RETURN();
2380
}
2381

    
2382
void OPPROTO op_405_mulchwu (void)
2383
{
2384
    T0 = ((uint16_t)T0) * ((uint16_t)(T1 >> 16));
2385
    RETURN();
2386
}
2387

    
2388
void OPPROTO op_405_mulhhw (void)
2389
{
2390
    T0 = ((int16_t)(T0 >> 16)) * ((int16_t)(T1 >> 16));
2391
    RETURN();
2392
}
2393

    
2394
void OPPROTO op_405_mulhhwu (void)
2395
{
2396
    T0 = ((uint16_t)(T0 >> 16)) * ((uint16_t)(T1 >> 16));
2397
    RETURN();
2398
}
2399

    
2400
void OPPROTO op_405_mullhw (void)
2401
{
2402
    T0 = ((int16_t)T0) * ((int16_t)T1);
2403
    RETURN();
2404
}
2405

    
2406
void OPPROTO op_405_mullhwu (void)
2407
{
2408
    T0 = ((uint16_t)T0) * ((uint16_t)T1);
2409
    RETURN();
2410
}
2411

    
2412
void OPPROTO op_405_check_sat (void)
2413
{
2414
    do_405_check_sat();
2415
    RETURN();
2416
}
2417

    
2418
void OPPROTO op_405_check_ovu (void)
2419
{
2420
    if (likely(T0 >= T2)) {
2421
        xer_ov = 0;
2422
    } else {
2423
        xer_ov = 1;
2424
        xer_so = 1;
2425
    }
2426
    RETURN();
2427
}
2428

    
2429
void OPPROTO op_405_check_satu (void)
2430
{
2431
    if (unlikely(T0 < T2)) {
2432
        /* Saturate result */
2433
        T0 = UINT32_MAX;
2434
    }
2435
    RETURN();
2436
}
2437

    
2438
void OPPROTO op_load_dcr (void)
2439
{
2440
    do_load_dcr();
2441
    RETURN();
2442
}
2443

    
2444
void OPPROTO op_store_dcr (void)
2445
{
2446
    do_store_dcr();
2447
    RETURN();
2448
}
2449

    
2450
#if !defined(CONFIG_USER_ONLY)
2451
/* Return from critical interrupt :
2452
 * same as rfi, except nip & MSR are loaded from SRR2/3 instead of SRR0/1
2453
 */
2454
void OPPROTO op_40x_rfci (void)
2455
{
2456
    do_40x_rfci();
2457
    RETURN();
2458
}
2459

    
2460
void OPPROTO op_rfci (void)
2461
{
2462
    do_rfci();
2463
    RETURN();
2464
}
2465

    
2466
void OPPROTO op_rfdi (void)
2467
{
2468
    do_rfdi();
2469
    RETURN();
2470
}
2471

    
2472
void OPPROTO op_rfmci (void)
2473
{
2474
    do_rfmci();
2475
    RETURN();
2476
}
2477

    
2478
void OPPROTO op_wrte (void)
2479
{
2480
    /* We don't call do_store_msr here as we won't trigger
2481
     * any special case nor change hflags
2482
     */
2483
    T0 &= 1 << MSR_EE;
2484
    env->msr &= ~(1 << MSR_EE);
2485
    env->msr |= T0;
2486
    RETURN();
2487
}
2488

    
2489
void OPPROTO op_440_tlbre (void)
2490
{
2491
    do_440_tlbre(PARAM1);
2492
    RETURN();
2493
}
2494

    
2495
void OPPROTO op_440_tlbsx (void)
2496
{
2497
    T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_440_MMUCR] & 0xFF);
2498
    RETURN();
2499
}
2500

    
2501
void OPPROTO op_4xx_tlbsx_check (void)
2502
{
2503
    int tmp;
2504

    
2505
    tmp = xer_so;
2506
    if ((int)T0 != -1)
2507
        tmp |= 0x02;
2508
    env->crf[0] = tmp;
2509
    RETURN();
2510
}
2511

    
2512
void OPPROTO op_440_tlbwe (void)
2513
{
2514
    do_440_tlbwe(PARAM1);
2515
    RETURN();
2516
}
2517

    
2518
void OPPROTO op_4xx_tlbre_lo (void)
2519
{
2520
    do_4xx_tlbre_lo();
2521
    RETURN();
2522
}
2523

    
2524
void OPPROTO op_4xx_tlbre_hi (void)
2525
{
2526
    do_4xx_tlbre_hi();
2527
    RETURN();
2528
}
2529

    
2530
void OPPROTO op_4xx_tlbsx (void)
2531
{
2532
    T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_40x_PID]);
2533
    RETURN();
2534
}
2535

    
2536
void OPPROTO op_4xx_tlbwe_lo (void)
2537
{
2538
    do_4xx_tlbwe_lo();
2539
    RETURN();
2540
}
2541

    
2542
void OPPROTO op_4xx_tlbwe_hi (void)
2543
{
2544
    do_4xx_tlbwe_hi();
2545
    RETURN();
2546
}
2547
#endif
2548

    
2549
/* SPR micro-ops */
2550
/* 440 specific */
2551
void OPPROTO op_440_dlmzb (void)
2552
{
2553
    do_440_dlmzb();
2554
    RETURN();
2555
}
2556

    
2557
void OPPROTO op_440_dlmzb_update_Rc (void)
2558
{
2559
    if (T0 == 8)
2560
        T0 = 0x2;
2561
    else if (T0 < 4)
2562
        T0 = 0x4;
2563
    else
2564
        T0 = 0x8;
2565
    RETURN();
2566
}
2567

    
2568
#if !defined(CONFIG_USER_ONLY)
2569
void OPPROTO op_store_pir (void)
2570
{
2571
    env->spr[SPR_PIR] = T0 & 0x0000000FUL;
2572
    RETURN();
2573
}
2574

    
2575
void OPPROTO op_load_403_pb (void)
2576
{
2577
    do_load_403_pb(PARAM1);
2578
    RETURN();
2579
}
2580

    
2581
void OPPROTO op_store_403_pb (void)
2582
{
2583
    do_store_403_pb(PARAM1);
2584
    RETURN();
2585
}
2586

    
2587
void OPPROTO op_load_40x_pit (void)
2588
{
2589
    T0 = load_40x_pit(env);
2590
    RETURN();
2591
}
2592

    
2593
void OPPROTO op_store_40x_pit (void)
2594
{
2595
    store_40x_pit(env, T0);
2596
    RETURN();
2597
}
2598

    
2599
void OPPROTO op_store_40x_dbcr0 (void)
2600
{
2601
    store_40x_dbcr0(env, T0);
2602
    RETURN();
2603
}
2604

    
2605
void OPPROTO op_store_40x_sler (void)
2606
{
2607
    store_40x_sler(env, T0);
2608
    RETURN();
2609
}
2610

    
2611
void OPPROTO op_store_booke_tcr (void)
2612
{
2613
    store_booke_tcr(env, T0);
2614
    RETURN();
2615
}
2616

    
2617
void OPPROTO op_store_booke_tsr (void)
2618
{
2619
    store_booke_tsr(env, T0);
2620
    RETURN();
2621
}
2622
#endif /* !defined(CONFIG_USER_ONLY) */
2623

    
2624
/* SPE extension */
2625
void OPPROTO op_splatw_T1_64 (void)
2626
{
2627
    T1_64 = (T1_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL);
2628
    RETURN();
2629
}
2630

    
2631
void OPPROTO op_splatwi_T0_64 (void)
2632
{
2633
    uint64_t tmp = PARAM1;
2634

    
2635
    T0_64 = (tmp << 32) | tmp;
2636
    RETURN();
2637
}
2638

    
2639
void OPPROTO op_splatwi_T1_64 (void)
2640
{
2641
    uint64_t tmp = PARAM1;
2642

    
2643
    T1_64 = (tmp << 32) | tmp;
2644
    RETURN();
2645
}
2646

    
2647
void OPPROTO op_extsh_T1_64 (void)
2648
{
2649
    T1_64 = (int32_t)((int16_t)T1_64);
2650
    RETURN();
2651
}
2652

    
2653
void OPPROTO op_sli16_T1_64 (void)
2654
{
2655
    T1_64 = T1_64 << 16;
2656
    RETURN();
2657
}
2658

    
2659
void OPPROTO op_sli32_T1_64 (void)
2660
{
2661
    T1_64 = T1_64 << 32;
2662
    RETURN();
2663
}
2664

    
2665
void OPPROTO op_srli32_T1_64 (void)
2666
{
2667
    T1_64 = T1_64 >> 32;
2668
    RETURN();
2669
}
2670

    
2671
void OPPROTO op_evsel (void)
2672
{
2673
    do_evsel();
2674
    RETURN();
2675
}
2676

    
2677
void OPPROTO op_evaddw (void)
2678
{
2679
    do_evaddw();
2680
    RETURN();
2681
}
2682

    
2683
void OPPROTO op_evsubfw (void)
2684
{
2685
    do_evsubfw();
2686
    RETURN();
2687
}
2688

    
2689
void OPPROTO op_evneg (void)
2690
{
2691
    do_evneg();
2692
    RETURN();
2693
}
2694

    
2695
void OPPROTO op_evabs (void)
2696
{
2697
    do_evabs();
2698
    RETURN();
2699
}
2700

    
2701
void OPPROTO op_evextsh (void)
2702
{
2703
    T0_64 = ((uint64_t)((int32_t)(int16_t)(T0_64 >> 32)) << 32) |
2704
        (uint64_t)((int32_t)(int16_t)T0_64);
2705
    RETURN();
2706
}
2707

    
2708
void OPPROTO op_evextsb (void)
2709
{
2710
    T0_64 = ((uint64_t)((int32_t)(int8_t)(T0_64 >> 32)) << 32) |
2711
        (uint64_t)((int32_t)(int8_t)T0_64);
2712
    RETURN();
2713
}
2714

    
2715
void OPPROTO op_evcntlzw (void)
2716
{
2717
    do_evcntlzw();
2718
    RETURN();
2719
}
2720

    
2721
void OPPROTO op_evrndw (void)
2722
{
2723
    do_evrndw();
2724
    RETURN();
2725
}
2726

    
2727
void OPPROTO op_brinc (void)
2728
{
2729
    do_brinc();
2730
    RETURN();
2731
}
2732

    
2733
void OPPROTO op_evcntlsw (void)
2734
{
2735
    do_evcntlsw();
2736
    RETURN();
2737
}
2738

    
2739
void OPPROTO op_evand (void)
2740
{
2741
    T0_64 &= T1_64;
2742
    RETURN();
2743
}
2744

    
2745
void OPPROTO op_evandc (void)
2746
{
2747
    T0_64 &= ~T1_64;
2748
    RETURN();
2749
}
2750

    
2751
void OPPROTO op_evor (void)
2752
{
2753
    T0_64 |= T1_64;
2754
    RETURN();
2755
}
2756

    
2757
void OPPROTO op_evxor (void)
2758
{
2759
    T0_64 ^= T1_64;
2760
    RETURN();
2761
}
2762

    
2763
void OPPROTO op_eveqv (void)
2764
{
2765
    T0_64 = ~(T0_64 ^ T1_64);
2766
    RETURN();
2767
}
2768

    
2769
void OPPROTO op_evnor (void)
2770
{
2771
    T0_64 = ~(T0_64 | T1_64);
2772
    RETURN();
2773
}
2774

    
2775
void OPPROTO op_evorc (void)
2776
{
2777
    T0_64 |= ~T1_64;
2778
    RETURN();
2779
}
2780

    
2781
void OPPROTO op_evnand (void)
2782
{
2783
    T0_64 = ~(T0_64 & T1_64);
2784
    RETURN();
2785
}
2786

    
2787
void OPPROTO op_evsrws (void)
2788
{
2789
    do_evsrws();
2790
    RETURN();
2791
}
2792

    
2793
void OPPROTO op_evsrwu (void)
2794
{
2795
    do_evsrwu();
2796
    RETURN();
2797
}
2798

    
2799
void OPPROTO op_evslw (void)
2800
{
2801
    do_evslw();
2802
    RETURN();
2803
}
2804

    
2805
void OPPROTO op_evrlw (void)
2806
{
2807
    do_evrlw();
2808
    RETURN();
2809
}
2810

    
2811
void OPPROTO op_evmergelo (void)
2812
{
2813
    T0_64 = (T0_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL);
2814
    RETURN();
2815
}
2816

    
2817
void OPPROTO op_evmergehi (void)
2818
{
2819
    T0_64 = (T0_64 & 0xFFFFFFFF00000000ULL) | (T1_64 >> 32);
2820
    RETURN();
2821
}
2822

    
2823
void OPPROTO op_evmergelohi (void)
2824
{
2825
    T0_64 = (T0_64 << 32) | (T1_64 >> 32);
2826
    RETURN();
2827
}
2828

    
2829
void OPPROTO op_evmergehilo (void)
2830
{
2831
    T0_64 = (T0_64 & 0xFFFFFFFF00000000ULL) | (T1_64 & 0x00000000FFFFFFFFULL);
2832
    RETURN();
2833
}
2834

    
2835
void OPPROTO op_evcmpgts (void)
2836
{
2837
    do_evcmpgts();
2838
    RETURN();
2839
}
2840

    
2841
void OPPROTO op_evcmpgtu (void)
2842
{
2843
    do_evcmpgtu();
2844
    RETURN();
2845
}
2846

    
2847
void OPPROTO op_evcmplts (void)
2848
{
2849
    do_evcmplts();
2850
    RETURN();
2851
}
2852

    
2853
void OPPROTO op_evcmpltu (void)
2854
{
2855
    do_evcmpltu();
2856
    RETURN();
2857
}
2858

    
2859
void OPPROTO op_evcmpeq (void)
2860
{
2861
    do_evcmpeq();
2862
    RETURN();
2863
}
2864

    
2865
void OPPROTO op_evfssub (void)
2866
{
2867
    do_evfssub();
2868
    RETURN();
2869
}
2870

    
2871
void OPPROTO op_evfsadd (void)
2872
{
2873
    do_evfsadd();
2874
    RETURN();
2875
}
2876

    
2877
void OPPROTO op_evfsnabs (void)
2878
{
2879
    do_evfsnabs();
2880
    RETURN();
2881
}
2882

    
2883
void OPPROTO op_evfsabs (void)
2884
{
2885
    do_evfsabs();
2886
    RETURN();
2887
}
2888

    
2889
void OPPROTO op_evfsneg (void)
2890
{
2891
    do_evfsneg();
2892
    RETURN();
2893
}
2894

    
2895
void OPPROTO op_evfsdiv (void)
2896
{
2897
    do_evfsdiv();
2898
    RETURN();
2899
}
2900

    
2901
void OPPROTO op_evfsmul (void)
2902
{
2903
    do_evfsmul();
2904
    RETURN();
2905
}
2906

    
2907
void OPPROTO op_evfscmplt (void)
2908
{
2909
    do_evfscmplt();
2910
    RETURN();
2911
}
2912

    
2913
void OPPROTO op_evfscmpgt (void)
2914
{
2915
    do_evfscmpgt();
2916
    RETURN();
2917
}
2918

    
2919
void OPPROTO op_evfscmpeq (void)
2920
{
2921
    do_evfscmpeq();
2922
    RETURN();
2923
}
2924

    
2925
void OPPROTO op_evfscfsi (void)
2926
{
2927
    do_evfscfsi();
2928
    RETURN();
2929
}
2930

    
2931
void OPPROTO op_evfscfui (void)
2932
{
2933
    do_evfscfui();
2934
    RETURN();
2935
}
2936

    
2937
void OPPROTO op_evfscfsf (void)
2938
{
2939
    do_evfscfsf();
2940
    RETURN();
2941
}
2942

    
2943
void OPPROTO op_evfscfuf (void)
2944
{
2945
    do_evfscfuf();
2946
    RETURN();
2947
}
2948

    
2949
void OPPROTO op_evfsctsi (void)
2950
{
2951
    do_evfsctsi();
2952
    RETURN();
2953
}
2954

    
2955
void OPPROTO op_evfsctui (void)
2956
{
2957
    do_evfsctui();
2958
    RETURN();
2959
}
2960

    
2961
void OPPROTO op_evfsctsf (void)
2962
{
2963
    do_evfsctsf();
2964
    RETURN();
2965
}
2966

    
2967
void OPPROTO op_evfsctuf (void)
2968
{
2969
    do_evfsctuf();
2970
    RETURN();
2971
}
2972

    
2973
void OPPROTO op_evfsctuiz (void)
2974
{
2975
    do_evfsctuiz();
2976
    RETURN();
2977
}
2978

    
2979
void OPPROTO op_evfsctsiz (void)
2980
{
2981
    do_evfsctsiz();
2982
    RETURN();
2983
}
2984

    
2985
void OPPROTO op_evfststlt (void)
2986
{
2987
    do_evfststlt();
2988
    RETURN();
2989
}
2990

    
2991
void OPPROTO op_evfststgt (void)
2992
{
2993
    do_evfststgt();
2994
    RETURN();
2995
}
2996

    
2997
void OPPROTO op_evfststeq (void)
2998
{
2999
    do_evfststeq();
3000
    RETURN();
3001
}
3002

    
3003
void OPPROTO op_efssub (void)
3004
{
3005
    T0_64 = _do_efssub(T0_64, T1_64);
3006
    RETURN();
3007
}
3008

    
3009
void OPPROTO op_efsadd (void)
3010
{
3011
    T0_64 = _do_efsadd(T0_64, T1_64);
3012
    RETURN();
3013
}
3014

    
3015
void OPPROTO op_efsnabs (void)
3016
{
3017
    T0_64 = _do_efsnabs(T0_64);
3018
    RETURN();
3019
}
3020

    
3021
void OPPROTO op_efsabs (void)
3022
{
3023
    T0_64 = _do_efsabs(T0_64);
3024
    RETURN();
3025
}
3026

    
3027
void OPPROTO op_efsneg (void)
3028
{
3029
    T0_64 = _do_efsneg(T0_64);
3030
    RETURN();
3031
}
3032

    
3033
void OPPROTO op_efsdiv (void)
3034
{
3035
    T0_64 = _do_efsdiv(T0_64, T1_64);
3036
    RETURN();
3037
}
3038

    
3039
void OPPROTO op_efsmul (void)
3040
{
3041
    T0_64 = _do_efsmul(T0_64, T1_64);
3042
    RETURN();
3043
}
3044

    
3045
void OPPROTO op_efscmplt (void)
3046
{
3047
    do_efscmplt();
3048
    RETURN();
3049
}
3050

    
3051
void OPPROTO op_efscmpgt (void)
3052
{
3053
    do_efscmpgt();
3054
    RETURN();
3055
}
3056

    
3057
void OPPROTO op_efscfd (void)
3058
{
3059
    do_efscfd();
3060
    RETURN();
3061
}
3062

    
3063
void OPPROTO op_efscmpeq (void)
3064
{
3065
    do_efscmpeq();
3066
    RETURN();
3067
}
3068

    
3069
void OPPROTO op_efscfsi (void)
3070
{
3071
    do_efscfsi();
3072
    RETURN();
3073
}
3074

    
3075
void OPPROTO op_efscfui (void)
3076
{
3077
    do_efscfui();
3078
    RETURN();
3079
}
3080

    
3081
void OPPROTO op_efscfsf (void)
3082
{
3083
    do_efscfsf();
3084
    RETURN();
3085
}
3086

    
3087
void OPPROTO op_efscfuf (void)
3088
{
3089
    do_efscfuf();
3090
    RETURN();
3091
}
3092

    
3093
void OPPROTO op_efsctsi (void)
3094
{
3095
    do_efsctsi();
3096
    RETURN();
3097
}
3098

    
3099
void OPPROTO op_efsctui (void)
3100
{
3101
    do_efsctui();
3102
    RETURN();
3103
}
3104

    
3105
void OPPROTO op_efsctsf (void)
3106
{
3107
    do_efsctsf();
3108
    RETURN();
3109
}
3110

    
3111
void OPPROTO op_efsctuf (void)
3112
{
3113
    do_efsctuf();
3114
    RETURN();
3115
}
3116

    
3117
void OPPROTO op_efsctsiz (void)
3118
{
3119
    do_efsctsiz();
3120
    RETURN();
3121
}
3122

    
3123
void OPPROTO op_efsctuiz (void)
3124
{
3125
    do_efsctuiz();
3126
    RETURN();
3127
}
3128

    
3129
void OPPROTO op_efststlt (void)
3130
{
3131
    T0 = _do_efststlt(T0_64, T1_64);
3132
    RETURN();
3133
}
3134

    
3135
void OPPROTO op_efststgt (void)
3136
{
3137
    T0 = _do_efststgt(T0_64, T1_64);
3138
    RETURN();
3139
}
3140

    
3141
void OPPROTO op_efststeq (void)
3142
{
3143
    T0 = _do_efststeq(T0_64, T1_64);
3144
    RETURN();
3145
}
3146

    
3147
void OPPROTO op_efdsub (void)
3148
{
3149
    CPU_DoubleU u1, u2;
3150
    u1.ll = T0_64;
3151
    u2.ll = T1_64;
3152
    u1.d = float64_sub(u1.d, u2.d, &env->spe_status);
3153
    T0_64 = u1.ll;
3154
    RETURN();
3155
}
3156

    
3157
void OPPROTO op_efdadd (void)
3158
{
3159
    CPU_DoubleU u1, u2;
3160
    u1.ll = T0_64;
3161
    u2.ll = T1_64;
3162
    u1.d = float64_add(u1.d, u2.d, &env->spe_status);
3163
    T0_64 = u1.ll;
3164
    RETURN();
3165
}
3166

    
3167
void OPPROTO op_efdcfsid (void)
3168
{
3169
    do_efdcfsi();
3170
    RETURN();
3171
}
3172

    
3173
void OPPROTO op_efdcfuid (void)
3174
{
3175
    do_efdcfui();
3176
    RETURN();
3177
}
3178

    
3179
void OPPROTO op_efdnabs (void)
3180
{
3181
    T0_64 |= 0x8000000000000000ULL;
3182
    RETURN();
3183
}
3184

    
3185
void OPPROTO op_efdabs (void)
3186
{
3187
    T0_64 &= ~0x8000000000000000ULL;
3188
    RETURN();
3189
}
3190

    
3191
void OPPROTO op_efdneg (void)
3192
{
3193
    T0_64 ^= 0x8000000000000000ULL;
3194
    RETURN();
3195
}
3196

    
3197
void OPPROTO op_efddiv (void)
3198
{
3199
    CPU_DoubleU u1, u2;
3200
    u1.ll = T0_64;
3201
    u2.ll = T1_64;
3202
    u1.d = float64_div(u1.d, u2.d, &env->spe_status);
3203
    T0_64 = u1.ll;
3204
    RETURN();
3205
}
3206

    
3207
void OPPROTO op_efdmul (void)
3208
{
3209
    CPU_DoubleU u1, u2;
3210
    u1.ll = T0_64;
3211
    u2.ll = T1_64;
3212
    u1.d = float64_mul(u1.d, u2.d, &env->spe_status);
3213
    T0_64 = u1.ll;
3214
    RETURN();
3215
}
3216

    
3217
void OPPROTO op_efdctsidz (void)
3218
{
3219
    do_efdctsiz();
3220
    RETURN();
3221
}
3222

    
3223
void OPPROTO op_efdctuidz (void)
3224
{
3225
    do_efdctuiz();
3226
    RETURN();
3227
}
3228

    
3229
void OPPROTO op_efdcmplt (void)
3230
{
3231
    do_efdcmplt();
3232
    RETURN();
3233
}
3234

    
3235
void OPPROTO op_efdcmpgt (void)
3236
{
3237
    do_efdcmpgt();
3238
    RETURN();
3239
}
3240

    
3241
void OPPROTO op_efdcfs (void)
3242
{
3243
    do_efdcfs();
3244
    RETURN();
3245
}
3246

    
3247
void OPPROTO op_efdcmpeq (void)
3248
{
3249
    do_efdcmpeq();
3250
    RETURN();
3251
}
3252

    
3253
void OPPROTO op_efdcfsi (void)
3254
{
3255
    do_efdcfsi();
3256
    RETURN();
3257
}
3258

    
3259
void OPPROTO op_efdcfui (void)
3260
{
3261
    do_efdcfui();
3262
    RETURN();
3263
}
3264

    
3265
void OPPROTO op_efdcfsf (void)
3266
{
3267
    do_efdcfsf();
3268
    RETURN();
3269
}
3270

    
3271
void OPPROTO op_efdcfuf (void)
3272
{
3273
    do_efdcfuf();
3274
    RETURN();
3275
}
3276

    
3277
void OPPROTO op_efdctsi (void)
3278
{
3279
    do_efdctsi();
3280
    RETURN();
3281
}
3282

    
3283
void OPPROTO op_efdctui (void)
3284
{
3285
    do_efdctui();
3286
    RETURN();
3287
}
3288

    
3289
void OPPROTO op_efdctsf (void)
3290
{
3291
    do_efdctsf();
3292
    RETURN();
3293
}
3294

    
3295
void OPPROTO op_efdctuf (void)
3296
{
3297
    do_efdctuf();
3298
    RETURN();
3299
}
3300

    
3301
void OPPROTO op_efdctuiz (void)
3302
{
3303
    do_efdctuiz();
3304
    RETURN();
3305
}
3306

    
3307
void OPPROTO op_efdctsiz (void)
3308
{
3309
    do_efdctsiz();
3310
    RETURN();
3311
}
3312

    
3313
void OPPROTO op_efdtstlt (void)
3314
{
3315
    T0 = _do_efdtstlt(T0_64, T1_64);
3316
    RETURN();
3317
}
3318

    
3319
void OPPROTO op_efdtstgt (void)
3320
{
3321
    T0 = _do_efdtstgt(T0_64, T1_64);
3322
    RETURN();
3323
}
3324

    
3325
void OPPROTO op_efdtsteq (void)
3326
{
3327
    T0 = _do_efdtsteq(T0_64, T1_64);
3328
    RETURN();
3329
}