Statistics
| Branch: | Revision:

root / target-ppc / op.c @ e1571908

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

    
29
/* Generate exceptions */
30
void OPPROTO op_raise_exception_err (void)
31
{
32
    do_raise_exception_err(PARAM1, PARAM2);
33
}
34

    
35
void OPPROTO op_debug (void)
36
{
37
    do_raise_exception(EXCP_DEBUG);
38
}
39

    
40
/* Load/store special registers */
41
#if defined(TARGET_PPC64)
42
void OPPROTO op_store_pri (void)
43
{
44
    do_store_pri(PARAM1);
45
    RETURN();
46
}
47
#endif
48

    
49
#if !defined(CONFIG_USER_ONLY)
50
/* Segment registers load and store */
51
void OPPROTO op_load_sr (void)
52
{
53
    T0 = env->sr[T1];
54
    RETURN();
55
}
56

    
57
void OPPROTO op_store_sr (void)
58
{
59
    do_store_sr(env, T1, T0);
60
    RETURN();
61
}
62

    
63
#if defined(TARGET_PPC64)
64
void OPPROTO op_load_slb (void)
65
{
66
    T0 = ppc_load_slb(env, T1);
67
    RETURN();
68
}
69

    
70
void OPPROTO op_store_slb (void)
71
{
72
    ppc_store_slb(env, T1, T0);
73
    RETURN();
74
}
75
#endif /* defined(TARGET_PPC64) */
76

    
77
void OPPROTO op_load_sdr1 (void)
78
{
79
    T0 = env->sdr1;
80
    RETURN();
81
}
82

    
83
void OPPROTO op_store_sdr1 (void)
84
{
85
    do_store_sdr1(env, T0);
86
    RETURN();
87
}
88

    
89
#if defined (TARGET_PPC64)
90
void OPPROTO op_load_asr (void)
91
{
92
    T0 = env->asr;
93
    RETURN();
94
}
95

    
96
void OPPROTO op_store_asr (void)
97
{
98
    ppc_store_asr(env, T0);
99
    RETURN();
100
}
101
#endif
102

    
103
void OPPROTO op_load_msr (void)
104
{
105
    T0 = env->msr;
106
    RETURN();
107
}
108

    
109
void OPPROTO op_store_msr (void)
110
{
111
    do_store_msr();
112
    RETURN();
113
}
114

    
115
#if defined (TARGET_PPC64)
116
void OPPROTO op_store_msr_32 (void)
117
{
118
    T0 = (env->msr & ~0xFFFFFFFFULL) | (T0 & 0xFFFFFFFF);
119
    do_store_msr();
120
    RETURN();
121
}
122
#endif
123

    
124
void OPPROTO op_update_riee (void)
125
{
126
    /* We don't call do_store_msr here as we won't trigger
127
     * any special case nor change hflags
128
     */
129
    T0 &= (1 << MSR_RI) | (1 << MSR_EE);
130
    env->msr &= ~(1 << MSR_RI) | (1 << MSR_EE);
131
    env->msr |= T0;
132
    RETURN();
133
}
134
#endif
135

    
136
/* SPR */
137
void OPPROTO op_load_spr (void)
138
{
139
    T0 = env->spr[PARAM1];
140
    RETURN();
141
}
142

    
143
void OPPROTO op_store_spr (void)
144
{
145
    env->spr[PARAM1] = T0;
146
    RETURN();
147
}
148

    
149
void OPPROTO op_load_dump_spr (void)
150
{
151
    T0 = ppc_load_dump_spr(PARAM1);
152
    RETURN();
153
}
154

    
155
void OPPROTO op_store_dump_spr (void)
156
{
157
    ppc_store_dump_spr(PARAM1, T0);
158
    RETURN();
159
}
160

    
161
void OPPROTO op_mask_spr (void)
162
{
163
    env->spr[PARAM1] &= ~T0;
164
    RETURN();
165
}
166

    
167
void OPPROTO op_load_tbl (void)
168
{
169
    T0 = cpu_ppc_load_tbl(env);
170
    RETURN();
171
}
172

    
173
void OPPROTO op_load_tbu (void)
174
{
175
    T0 = cpu_ppc_load_tbu(env);
176
    RETURN();
177
}
178

    
179
void OPPROTO op_load_atbl (void)
180
{
181
    T0 = cpu_ppc_load_atbl(env);
182
    RETURN();
183
}
184

    
185
void OPPROTO op_load_atbu (void)
186
{
187
    T0 = cpu_ppc_load_atbu(env);
188
    RETURN();
189
}
190

    
191
#if !defined(CONFIG_USER_ONLY)
192
void OPPROTO op_store_tbl (void)
193
{
194
    cpu_ppc_store_tbl(env, T0);
195
    RETURN();
196
}
197

    
198
void OPPROTO op_store_tbu (void)
199
{
200
    cpu_ppc_store_tbu(env, T0);
201
    RETURN();
202
}
203

    
204
void OPPROTO op_store_atbl (void)
205
{
206
    cpu_ppc_store_atbl(env, T0);
207
    RETURN();
208
}
209

    
210
void OPPROTO op_store_atbu (void)
211
{
212
    cpu_ppc_store_atbu(env, T0);
213
    RETURN();
214
}
215

    
216
void OPPROTO op_load_decr (void)
217
{
218
    T0 = cpu_ppc_load_decr(env);
219
    RETURN();
220
}
221

    
222
void OPPROTO op_store_decr (void)
223
{
224
    cpu_ppc_store_decr(env, T0);
225
    RETURN();
226
}
227

    
228
void OPPROTO op_load_ibat (void)
229
{
230
    T0 = env->IBAT[PARAM1][PARAM2];
231
    RETURN();
232
}
233

    
234
void OPPROTO op_store_ibatu (void)
235
{
236
    do_store_ibatu(env, PARAM1, T0);
237
    RETURN();
238
}
239

    
240
void OPPROTO op_store_ibatl (void)
241
{
242
#if 1
243
    env->IBAT[1][PARAM1] = T0;
244
#else
245
    do_store_ibatl(env, PARAM1, T0);
246
#endif
247
    RETURN();
248
}
249

    
250
void OPPROTO op_load_dbat (void)
251
{
252
    T0 = env->DBAT[PARAM1][PARAM2];
253
    RETURN();
254
}
255

    
256
void OPPROTO op_store_dbatu (void)
257
{
258
    do_store_dbatu(env, PARAM1, T0);
259
    RETURN();
260
}
261

    
262
void OPPROTO op_store_dbatl (void)
263
{
264
#if 1
265
    env->DBAT[1][PARAM1] = T0;
266
#else
267
    do_store_dbatl(env, PARAM1, T0);
268
#endif
269
    RETURN();
270
}
271
#endif /* !defined(CONFIG_USER_ONLY) */
272

    
273
/* FPSCR */
274
#ifdef CONFIG_SOFTFLOAT
275
void OPPROTO op_reset_fpstatus (void)
276
{
277
    env->fp_status.float_exception_flags = 0;
278
    RETURN();
279
}
280
#endif
281

    
282
void OPPROTO op_compute_fprf (void)
283
{
284
    do_compute_fprf(PARAM1);
285
    RETURN();
286
}
287

    
288
#ifdef CONFIG_SOFTFLOAT
289
void OPPROTO op_float_check_status (void)
290
{
291
    do_float_check_status();
292
    RETURN();
293
}
294
#else
295
void OPPROTO op_float_check_status (void)
296
{
297
    if (env->exception_index == POWERPC_EXCP_PROGRAM &&
298
        (env->error_code & POWERPC_EXCP_FP)) {
299
        /* Differred floating-point exception after target FPR update */
300
        if (msr_fe0 != 0 || msr_fe1 != 0)
301
            do_raise_exception_err(env->exception_index, env->error_code);
302
    }
303
    RETURN();
304
}
305
#endif
306

    
307
void OPPROTO op_load_fpscr_FT0 (void)
308
{
309
    /* The 32 MSB of the target fpr are undefined.
310
     * They'll be zero...
311
     */
312
    CPU_DoubleU u;
313

    
314
    u.l.upper = 0;
315
    u.l.lower = env->fpscr;
316
    FT0 = u.d;
317
    RETURN();
318
}
319

    
320
void OPPROTO op_fpscr_resetbit (void)
321
{
322
    env->fpscr &= PARAM1;
323
    RETURN();
324
}
325

    
326
void OPPROTO op_fpscr_setbit (void)
327
{
328
    do_fpscr_setbit(PARAM1);
329
    RETURN();
330
}
331

    
332
void OPPROTO op_store_fpscr (void)
333
{
334
    do_store_fpscr(PARAM1);
335
    RETURN();
336
}
337

    
338
/* Branch */
339
void OPPROTO op_setlr (void)
340
{
341
    env->lr = (uint32_t)PARAM1;
342
    RETURN();
343
}
344

    
345
#if defined (TARGET_PPC64)
346
void OPPROTO op_setlr_64 (void)
347
{
348
    env->lr = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
349
    RETURN();
350
}
351
#endif
352

    
353
void OPPROTO op_jz_T0 (void)
354
{
355
    if (!T0)
356
        GOTO_LABEL_PARAM(1);
357
    RETURN();
358
}
359

    
360
void OPPROTO op_btest_T1 (void)
361
{
362
    if (T0) {
363
        env->nip = (uint32_t)(T1 & ~3);
364
    } else {
365
        env->nip = (uint32_t)PARAM1;
366
    }
367
    RETURN();
368
}
369

    
370
#if defined (TARGET_PPC64)
371
void OPPROTO op_btest_T1_64 (void)
372
{
373
    if (T0) {
374
        env->nip = (uint64_t)(T1 & ~3);
375
    } else {
376
        env->nip = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
377
    }
378
    RETURN();
379
}
380
#endif
381

    
382
void OPPROTO op_movl_T1_ctr (void)
383
{
384
    T1 = env->ctr;
385
    RETURN();
386
}
387

    
388
void OPPROTO op_movl_T1_lr (void)
389
{
390
    T1 = env->lr;
391
    RETURN();
392
}
393

    
394
/* tests with result in T0 */
395
void OPPROTO op_test_ctr (void)
396
{
397
    T0 = (uint32_t)env->ctr;
398
    RETURN();
399
}
400

    
401
#if defined(TARGET_PPC64)
402
void OPPROTO op_test_ctr_64 (void)
403
{
404
    T0 = (uint64_t)env->ctr;
405
    RETURN();
406
}
407
#endif
408

    
409
void OPPROTO op_test_ctr_true (void)
410
{
411
    T0 = ((uint32_t)env->ctr != 0 && (T0 & PARAM1) != 0);
412
    RETURN();
413
}
414

    
415
#if defined(TARGET_PPC64)
416
void OPPROTO op_test_ctr_true_64 (void)
417
{
418
    T0 = ((uint64_t)env->ctr != 0 && (T0 & PARAM1) != 0);
419
    RETURN();
420
}
421
#endif
422

    
423
void OPPROTO op_test_ctr_false (void)
424
{
425
    T0 = ((uint32_t)env->ctr != 0 && (T0 & PARAM1) == 0);
426
    RETURN();
427
}
428

    
429
#if defined(TARGET_PPC64)
430
void OPPROTO op_test_ctr_false_64 (void)
431
{
432
    T0 = ((uint64_t)env->ctr != 0 && (T0 & PARAM1) == 0);
433
    RETURN();
434
}
435
#endif
436

    
437
void OPPROTO op_test_ctrz (void)
438
{
439
    T0 = ((uint32_t)env->ctr == 0);
440
    RETURN();
441
}
442

    
443
#if defined(TARGET_PPC64)
444
void OPPROTO op_test_ctrz_64 (void)
445
{
446
    T0 = ((uint64_t)env->ctr == 0);
447
    RETURN();
448
}
449
#endif
450

    
451
void OPPROTO op_test_ctrz_true (void)
452
{
453
    T0 = ((uint32_t)env->ctr == 0 && (T0 & PARAM1) != 0);
454
    RETURN();
455
}
456

    
457
#if defined(TARGET_PPC64)
458
void OPPROTO op_test_ctrz_true_64 (void)
459
{
460
    T0 = ((uint64_t)env->ctr == 0 && (T0 & PARAM1) != 0);
461
    RETURN();
462
}
463
#endif
464

    
465
void OPPROTO op_test_ctrz_false (void)
466
{
467
    T0 = ((uint32_t)env->ctr == 0 && (T0 & PARAM1) == 0);
468
    RETURN();
469
}
470

    
471
#if defined(TARGET_PPC64)
472
void OPPROTO op_test_ctrz_false_64 (void)
473
{
474
    T0 = ((uint64_t)env->ctr == 0 && (T0 & PARAM1) == 0);
475
    RETURN();
476
}
477
#endif
478

    
479
void OPPROTO op_test_true (void)
480
{
481
    T0 = (T0 & PARAM1);
482
    RETURN();
483
}
484

    
485
void OPPROTO op_test_false (void)
486
{
487
    T0 = ((T0 & PARAM1) == 0);
488
    RETURN();
489
}
490

    
491
/* CTR maintenance */
492
void OPPROTO op_dec_ctr (void)
493
{
494
    env->ctr--;
495
    RETURN();
496
}
497

    
498
/***                           Integer arithmetic                          ***/
499
/* add */
500
void OPPROTO op_check_addo (void)
501
{
502
    int ov = (((uint32_t)T2 ^ (uint32_t)T1 ^ UINT32_MAX) &
503
              ((uint32_t)T2 ^ (uint32_t)T0)) >> 31;
504
    if (ov) {
505
        env->xer |= (1 << XER_OV) | (1 << XER_SO);
506
    } else {
507
        env->xer &= ~(1 << XER_OV);
508
    }
509
    RETURN();
510
}
511

    
512
#if defined(TARGET_PPC64)
513
void OPPROTO op_check_addo_64 (void)
514
{
515
    int ov = (((uint64_t)T2 ^ (uint64_t)T1 ^ UINT64_MAX) &
516
              ((uint64_t)T2 ^ (uint64_t)T0)) >> 63;
517
    if (ov) {
518
        env->xer |= (1 << XER_OV) | (1 << XER_SO);
519
    } else {
520
        env->xer &= ~(1 << XER_OV);
521
    }
522
    RETURN();
523
}
524
#endif
525

    
526
/* add carrying */
527
void OPPROTO op_check_addc (void)
528
{
529
    if (likely((uint32_t)T0 >= (uint32_t)T2)) {
530
        env->xer &= ~(1 << XER_CA);
531
    } else {
532
        env->xer |= (1 << XER_CA);
533
    }
534
    RETURN();
535
}
536

    
537
#if defined(TARGET_PPC64)
538
void OPPROTO op_check_addc_64 (void)
539
{
540
    if (likely((uint64_t)T0 >= (uint64_t)T2)) {
541
        env->xer &= ~(1 << XER_CA);
542
    } else {
543
        env->xer |= (1 << XER_CA);
544
    }
545
    RETURN();
546
}
547
#endif
548

    
549
/* add extended */
550
void OPPROTO op_adde (void)
551
{
552
    do_adde();
553
    RETURN();
554
}
555

    
556
#if defined(TARGET_PPC64)
557
void OPPROTO op_adde_64 (void)
558
{
559
    do_adde_64();
560
    RETURN();
561
}
562
#endif
563

    
564
/* add to minus one extended */
565
void OPPROTO op_add_me (void)
566
{
567
    T0 += xer_ca + (-1);
568
    if (likely((uint32_t)T1 != 0))
569
        env->xer |= (1 << XER_CA);
570
    RETURN();
571
}
572

    
573
#if defined(TARGET_PPC64)
574
void OPPROTO op_add_me_64 (void)
575
{
576
    T0 += xer_ca + (-1);
577
    if (likely((uint64_t)T1 != 0))
578
        env->xer |= (1 << XER_CA);
579
    RETURN();
580
}
581
#endif
582

    
583
void OPPROTO op_addmeo (void)
584
{
585
    do_addmeo();
586
    RETURN();
587
}
588

    
589
void OPPROTO op_addmeo_64 (void)
590
{
591
    do_addmeo();
592
    RETURN();
593
}
594

    
595
/* add to zero extended */
596
void OPPROTO op_add_ze (void)
597
{
598
    T0 += xer_ca;
599
    RETURN();
600
}
601

    
602
/* divide word */
603
void OPPROTO op_divw (void)
604
{
605
    if (unlikely(((int32_t)T0 == INT32_MIN && (int32_t)T1 == (int32_t)-1) ||
606
                 (int32_t)T1 == 0)) {
607
        T0 = (int32_t)(UINT32_MAX * ((uint32_t)T0 >> 31));
608
    } else {
609
        T0 = (int32_t)T0 / (int32_t)T1;
610
    }
611
    RETURN();
612
}
613

    
614
#if defined(TARGET_PPC64)
615
void OPPROTO op_divd (void)
616
{
617
    if (unlikely(((int64_t)T0 == INT64_MIN && (int64_t)T1 == (int64_t)-1LL) ||
618
                 (int64_t)T1 == 0)) {
619
        T0 = (int64_t)(UINT64_MAX * ((uint64_t)T0 >> 63));
620
    } else {
621
        T0 = (int64_t)T0 / (int64_t)T1;
622
    }
623
    RETURN();
624
}
625
#endif
626

    
627
void OPPROTO op_divwo (void)
628
{
629
    do_divwo();
630
    RETURN();
631
}
632

    
633
#if defined(TARGET_PPC64)
634
void OPPROTO op_divdo (void)
635
{
636
    do_divdo();
637
    RETURN();
638
}
639
#endif
640

    
641
/* divide word unsigned */
642
void OPPROTO op_divwu (void)
643
{
644
    if (unlikely(T1 == 0)) {
645
        T0 = 0;
646
    } else {
647
        T0 = (uint32_t)T0 / (uint32_t)T1;
648
    }
649
    RETURN();
650
}
651

    
652
#if defined(TARGET_PPC64)
653
void OPPROTO op_divdu (void)
654
{
655
    if (unlikely(T1 == 0)) {
656
        T0 = 0;
657
    } else {
658
        T0 /= T1;
659
    }
660
    RETURN();
661
}
662
#endif
663

    
664
void OPPROTO op_divwuo (void)
665
{
666
    do_divwuo();
667
    RETURN();
668
}
669

    
670
#if defined(TARGET_PPC64)
671
void OPPROTO op_divduo (void)
672
{
673
    do_divduo();
674
    RETURN();
675
}
676
#endif
677

    
678
/* multiply high word */
679
void OPPROTO op_mulhw (void)
680
{
681
    T0 = ((int64_t)((int32_t)T0) * (int64_t)((int32_t)T1)) >> 32;
682
    RETURN();
683
}
684

    
685
#if defined(TARGET_PPC64)
686
void OPPROTO op_mulhd (void)
687
{
688
    uint64_t tl, th;
689

    
690
    muls64(&tl, &th, T0, T1);
691
    T0 = th;
692
    RETURN();
693
}
694
#endif
695

    
696
/* multiply high word unsigned */
697
void OPPROTO op_mulhwu (void)
698
{
699
    T0 = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1) >> 32;
700
    RETURN();
701
}
702

    
703
#if defined(TARGET_PPC64)
704
void OPPROTO op_mulhdu (void)
705
{
706
    uint64_t tl, th;
707

    
708
    mulu64(&tl, &th, T0, T1);
709
    T0 = th;
710
    RETURN();
711
}
712
#endif
713

    
714
/* multiply low immediate */
715
void OPPROTO op_mulli (void)
716
{
717
    T0 = ((int32_t)T0 * (int32_t)PARAM1);
718
    RETURN();
719
}
720

    
721
/* multiply low word */
722
void OPPROTO op_mullw (void)
723
{
724
#if defined(TARGET_PPC64)
725
    T0 = (int64_t)(int32_t)T0 * (int64_t)(int32_t)T1;
726
#else
727
    T0 = (int32_t)(T0 * T1);
728
#endif
729
    RETURN();
730
}
731

    
732
#if defined(TARGET_PPC64)
733
void OPPROTO op_mulld (void)
734
{
735
    T0 *= T1;
736
    RETURN();
737
}
738
#endif
739

    
740
void OPPROTO op_mullwo (void)
741
{
742
    do_mullwo();
743
    RETURN();
744
}
745

    
746
#if defined(TARGET_PPC64)
747
void OPPROTO op_mulldo (void)
748
{
749
    do_mulldo();
750
    RETURN();
751
}
752
#endif
753

    
754
/* negate */
755
void OPPROTO op_neg (void)
756
{
757
    if (likely(T0 != INT32_MIN)) {
758
        T0 = -(int32_t)T0;
759
    }
760
    RETURN();
761
}
762

    
763
#if defined(TARGET_PPC64)
764
void OPPROTO op_neg_64 (void)
765
{
766
    if (likely(T0 != INT64_MIN)) {
767
        T0 = -(int64_t)T0;
768
    }
769
    RETURN();
770
}
771
#endif
772

    
773
void OPPROTO op_nego (void)
774
{
775
    do_nego();
776
    RETURN();
777
}
778

    
779
#if defined(TARGET_PPC64)
780
void OPPROTO op_nego_64 (void)
781
{
782
    do_nego_64();
783
    RETURN();
784
}
785
#endif
786

    
787
/* subtract from carrying */
788
void OPPROTO op_check_subfc (void)
789
{
790
    if (likely((uint32_t)T0 > (uint32_t)T1)) {
791
        env->xer &= ~(1 << XER_CA);
792
    } else {
793
        env->xer |= (1 << XER_CA);
794
    }
795
    RETURN();
796
}
797

    
798
#if defined(TARGET_PPC64)
799
void OPPROTO op_check_subfc_64 (void)
800
{
801
    if (likely((uint64_t)T0 > (uint64_t)T1)) {
802
        env->xer &= ~(1 << XER_CA);
803
    } else {
804
        env->xer |= (1 << XER_CA);
805
    }
806
    RETURN();
807
}
808
#endif
809

    
810
/* subtract from extended */
811
void OPPROTO op_subfe (void)
812
{
813
    do_subfe();
814
    RETURN();
815
}
816

    
817
#if defined(TARGET_PPC64)
818
void OPPROTO op_subfe_64 (void)
819
{
820
    do_subfe_64();
821
    RETURN();
822
}
823
#endif
824

    
825
/* subtract from immediate carrying */
826
void OPPROTO op_subfic (void)
827
{
828
    T0 = (int32_t)PARAM1 + ~T0 + 1;
829
    if ((uint32_t)T0 <= (uint32_t)PARAM1) {
830
        env->xer |= (1 << XER_CA);
831
    } else {
832
        env->xer &= ~(1 << XER_CA);
833
    }
834
    RETURN();
835
}
836

    
837
#if defined(TARGET_PPC64)
838
void OPPROTO op_subfic_64 (void)
839
{
840
    T0 = (int64_t)PARAM1 + ~T0 + 1;
841
    if ((uint64_t)T0 <= (uint64_t)PARAM1) {
842
        env->xer |= (1 << XER_CA);
843
    } else {
844
        env->xer &= ~(1 << XER_CA);
845
    }
846
    RETURN();
847
}
848
#endif
849

    
850
/* subtract from minus one extended */
851
void OPPROTO op_subfme (void)
852
{
853
    T0 = ~T0 + xer_ca - 1;
854
    if (likely((uint32_t)T0 != UINT32_MAX))
855
        env->xer |= (1 << XER_CA);
856
    RETURN();
857
}
858

    
859
#if defined(TARGET_PPC64)
860
void OPPROTO op_subfme_64 (void)
861
{
862
    T0 = ~T0 + xer_ca - 1;
863
    if (likely((uint64_t)T0 != UINT64_MAX))
864
        env->xer |= (1 << XER_CA);
865
    RETURN();
866
}
867
#endif
868

    
869
void OPPROTO op_subfmeo (void)
870
{
871
    do_subfmeo();
872
    RETURN();
873
}
874

    
875
#if defined(TARGET_PPC64)
876
void OPPROTO op_subfmeo_64 (void)
877
{
878
    do_subfmeo_64();
879
    RETURN();
880
}
881
#endif
882

    
883
/* subtract from zero extended */
884
void OPPROTO op_subfze (void)
885
{
886
    T1 = ~T0;
887
    T0 = T1 + xer_ca;
888
    if ((uint32_t)T0 < (uint32_t)T1) {
889
        env->xer |= (1 << XER_CA);
890
    } else {
891
        env->xer &= ~(1 << XER_CA);
892
    }
893
    RETURN();
894
}
895

    
896
#if defined(TARGET_PPC64)
897
void OPPROTO op_subfze_64 (void)
898
{
899
    T1 = ~T0;
900
    T0 = T1 + xer_ca;
901
    if ((uint64_t)T0 < (uint64_t)T1) {
902
        env->xer |= (1 << XER_CA);
903
    } else {
904
        env->xer &= ~(1 << XER_CA);
905
    }
906
    RETURN();
907
}
908
#endif
909

    
910
void OPPROTO op_subfzeo (void)
911
{
912
    do_subfzeo();
913
    RETURN();
914
}
915

    
916
#if defined(TARGET_PPC64)
917
void OPPROTO op_subfzeo_64 (void)
918
{
919
    do_subfzeo_64();
920
    RETURN();
921
}
922
#endif
923

    
924
void OPPROTO op_popcntb (void)
925
{
926
    do_popcntb();
927
    RETURN();
928
}
929

    
930
#if defined(TARGET_PPC64)
931
void OPPROTO op_popcntb_64 (void)
932
{
933
    do_popcntb_64();
934
    RETURN();
935
}
936
#endif
937

    
938
/***                            Integer logical                            ***/
939
/* and */
940
void OPPROTO op_and (void)
941
{
942
    T0 &= T1;
943
    RETURN();
944
}
945

    
946
/* andc */
947
void OPPROTO op_andc (void)
948
{
949
    T0 &= ~T1;
950
    RETURN();
951
}
952

    
953
/* count leading zero */
954
void OPPROTO op_cntlzw (void)
955
{
956
    do_cntlzw();
957
    RETURN();
958
}
959

    
960
#if defined(TARGET_PPC64)
961
void OPPROTO op_cntlzd (void)
962
{
963
    do_cntlzd();
964
    RETURN();
965
}
966
#endif
967

    
968
/* eqv */
969
void OPPROTO op_eqv (void)
970
{
971
    T0 = ~(T0 ^ T1);
972
    RETURN();
973
}
974

    
975
/* extend sign byte */
976
void OPPROTO op_extsb (void)
977
{
978
#if defined (TARGET_PPC64)
979
    T0 = (int64_t)((int8_t)T0);
980
#else
981
    T0 = (int32_t)((int8_t)T0);
982
#endif
983
    RETURN();
984
}
985

    
986
/* extend sign half word */
987
void OPPROTO op_extsh (void)
988
{
989
#if defined (TARGET_PPC64)
990
    T0 = (int64_t)((int16_t)T0);
991
#else
992
    T0 = (int32_t)((int16_t)T0);
993
#endif
994
    RETURN();
995
}
996

    
997
#if defined (TARGET_PPC64)
998
void OPPROTO op_extsw (void)
999
{
1000
    T0 = (int64_t)((int32_t)T0);
1001
    RETURN();
1002
}
1003
#endif
1004

    
1005
/* nand */
1006
void OPPROTO op_nand (void)
1007
{
1008
    T0 = ~(T0 & T1);
1009
    RETURN();
1010
}
1011

    
1012
/* nor */
1013
void OPPROTO op_nor (void)
1014
{
1015
    T0 = ~(T0 | T1);
1016
    RETURN();
1017
}
1018

    
1019
/* or */
1020
void OPPROTO op_or (void)
1021
{
1022
    T0 |= T1;
1023
    RETURN();
1024
}
1025

    
1026
/* orc */
1027
void OPPROTO op_orc (void)
1028
{
1029
    T0 |= ~T1;
1030
    RETURN();
1031
}
1032

    
1033
/* ori */
1034
void OPPROTO op_ori (void)
1035
{
1036
    T0 |= (uint32_t)PARAM1;
1037
    RETURN();
1038
}
1039

    
1040
/* xor */
1041
void OPPROTO op_xor (void)
1042
{
1043
    T0 ^= T1;
1044
    RETURN();
1045
}
1046

    
1047
/* xori */
1048
void OPPROTO op_xori (void)
1049
{
1050
    T0 ^= (uint32_t)PARAM1;
1051
    RETURN();
1052
}
1053

    
1054
/***                             Integer rotate                            ***/
1055
void OPPROTO op_rotl32_T0_T1 (void)
1056
{
1057
    T0 = rotl32(T0, T1 & 0x1F);
1058
    RETURN();
1059
}
1060

    
1061
void OPPROTO op_rotli32_T0 (void)
1062
{
1063
    T0 = rotl32(T0, PARAM1);
1064
    RETURN();
1065
}
1066

    
1067
#if defined(TARGET_PPC64)
1068
void OPPROTO op_rotl64_T0_T1 (void)
1069
{
1070
    T0 = rotl64(T0, T1 & 0x3F);
1071
    RETURN();
1072
}
1073

    
1074
void OPPROTO op_rotli64_T0 (void)
1075
{
1076
    T0 = rotl64(T0, PARAM1);
1077
    RETURN();
1078
}
1079
#endif
1080

    
1081
/***                             Integer shift                             ***/
1082
/* shift left word */
1083
void OPPROTO op_slw (void)
1084
{
1085
    if (T1 & 0x20) {
1086
        T0 = 0;
1087
    } else {
1088
        T0 = (uint32_t)(T0 << T1);
1089
    }
1090
    RETURN();
1091
}
1092

    
1093
#if defined(TARGET_PPC64)
1094
void OPPROTO op_sld (void)
1095
{
1096
    if (T1 & 0x40) {
1097
        T0 = 0;
1098
    } else {
1099
        T0 = T0 << T1;
1100
    }
1101
    RETURN();
1102
}
1103
#endif
1104

    
1105
/* shift right algebraic word */
1106
void OPPROTO op_sraw (void)
1107
{
1108
    do_sraw();
1109
    RETURN();
1110
}
1111

    
1112
#if defined(TARGET_PPC64)
1113
void OPPROTO op_srad (void)
1114
{
1115
    do_srad();
1116
    RETURN();
1117
}
1118
#endif
1119

    
1120
/* shift right algebraic word immediate */
1121
void OPPROTO op_srawi (void)
1122
{
1123
    uint32_t mask = (uint32_t)PARAM2;
1124

    
1125
    T0 = (int32_t)T0 >> PARAM1;
1126
    if ((int32_t)T1 < 0 && (T1 & mask) != 0) {
1127
        env->xer |= (1 << XER_CA);
1128
    } else {
1129
        env->xer &= ~(1 << XER_CA);
1130
    }
1131
    RETURN();
1132
}
1133

    
1134
#if defined(TARGET_PPC64)
1135
void OPPROTO op_sradi (void)
1136
{
1137
    uint64_t mask = ((uint64_t)PARAM2 << 32) | (uint64_t)PARAM3;
1138

    
1139
    T0 = (int64_t)T0 >> PARAM1;
1140
    if ((int64_t)T1 < 0 && ((uint64_t)T1 & mask) != 0) {
1141
        env->xer |= (1 << XER_CA);
1142
    } else {
1143
        env->xer &= ~(1 << XER_CA);
1144
    }
1145
    RETURN();
1146
}
1147
#endif
1148

    
1149
/* shift right word */
1150
void OPPROTO op_srw (void)
1151
{
1152
    if (T1 & 0x20) {
1153
        T0 = 0;
1154
    } else {
1155
        T0 = (uint32_t)T0 >> T1;
1156
    }
1157
    RETURN();
1158
}
1159

    
1160
#if defined(TARGET_PPC64)
1161
void OPPROTO op_srd (void)
1162
{
1163
    if (T1 & 0x40) {
1164
        T0 = 0;
1165
    } else {
1166
        T0 = (uint64_t)T0 >> T1;
1167
    }
1168
    RETURN();
1169
}
1170
#endif
1171

    
1172
void OPPROTO op_sl_T0_T1 (void)
1173
{
1174
    T0 = T0 << T1;
1175
    RETURN();
1176
}
1177

    
1178
void OPPROTO op_sli_T0 (void)
1179
{
1180
    T0 = T0 << PARAM1;
1181
    RETURN();
1182
}
1183

    
1184
void OPPROTO op_srl_T0_T1 (void)
1185
{
1186
    T0 = (uint32_t)T0 >> T1;
1187
    RETURN();
1188
}
1189

    
1190
#if defined(TARGET_PPC64)
1191
void OPPROTO op_srl_T0_T1_64 (void)
1192
{
1193
    T0 = (uint32_t)T0 >> T1;
1194
    RETURN();
1195
}
1196
#endif
1197

    
1198
void OPPROTO op_srli_T0 (void)
1199
{
1200
    T0 = (uint32_t)T0 >> PARAM1;
1201
    RETURN();
1202
}
1203

    
1204
#if defined(TARGET_PPC64)
1205
void OPPROTO op_srli_T0_64 (void)
1206
{
1207
    T0 = (uint64_t)T0 >> PARAM1;
1208
    RETURN();
1209
}
1210
#endif
1211

    
1212
void OPPROTO op_srli_T1 (void)
1213
{
1214
    T1 = (uint32_t)T1 >> PARAM1;
1215
    RETURN();
1216
}
1217

    
1218
#if defined(TARGET_PPC64)
1219
void OPPROTO op_srli_T1_64 (void)
1220
{
1221
    T1 = (uint64_t)T1 >> PARAM1;
1222
    RETURN();
1223
}
1224
#endif
1225

    
1226
/***                       Floating-Point arithmetic                       ***/
1227
/* fadd - fadd. */
1228
void OPPROTO op_fadd (void)
1229
{
1230
#if USE_PRECISE_EMULATION
1231
    do_fadd();
1232
#else
1233
    FT0 = float64_add(FT0, FT1, &env->fp_status);
1234
#endif
1235
    RETURN();
1236
}
1237

    
1238
/* fsub - fsub. */
1239
void OPPROTO op_fsub (void)
1240
{
1241
#if USE_PRECISE_EMULATION
1242
    do_fsub();
1243
#else
1244
    FT0 = float64_sub(FT0, FT1, &env->fp_status);
1245
#endif
1246
    RETURN();
1247
}
1248

    
1249
/* fmul - fmul. */
1250
void OPPROTO op_fmul (void)
1251
{
1252
#if USE_PRECISE_EMULATION
1253
    do_fmul();
1254
#else
1255
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1256
#endif
1257
    RETURN();
1258
}
1259

    
1260
/* fdiv - fdiv. */
1261
void OPPROTO op_fdiv (void)
1262
{
1263
#if USE_PRECISE_EMULATION
1264
    do_fdiv();
1265
#else
1266
    FT0 = float64_div(FT0, FT1, &env->fp_status);
1267
#endif
1268
    RETURN();
1269
}
1270

    
1271
/* fsqrt - fsqrt. */
1272
void OPPROTO op_fsqrt (void)
1273
{
1274
    do_fsqrt();
1275
    RETURN();
1276
}
1277

    
1278
/* fre - fre. */
1279
void OPPROTO op_fre (void)
1280
{
1281
    do_fre();
1282
    RETURN();
1283
}
1284

    
1285
/* fres - fres. */
1286
void OPPROTO op_fres (void)
1287
{
1288
    do_fres();
1289
    RETURN();
1290
}
1291

    
1292
/* frsqrte  - frsqrte. */
1293
void OPPROTO op_frsqrte (void)
1294
{
1295
    do_frsqrte();
1296
    RETURN();
1297
}
1298

    
1299
/* fsel - fsel. */
1300
void OPPROTO op_fsel (void)
1301
{
1302
    do_fsel();
1303
    RETURN();
1304
}
1305

    
1306
/***                     Floating-Point multiply-and-add                   ***/
1307
/* fmadd - fmadd. */
1308
void OPPROTO op_fmadd (void)
1309
{
1310
#if USE_PRECISE_EMULATION
1311
    do_fmadd();
1312
#else
1313
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1314
    FT0 = float64_add(FT0, FT2, &env->fp_status);
1315
#endif
1316
    RETURN();
1317
}
1318

    
1319
/* fmsub - fmsub. */
1320
void OPPROTO op_fmsub (void)
1321
{
1322
#if USE_PRECISE_EMULATION
1323
    do_fmsub();
1324
#else
1325
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1326
    FT0 = float64_sub(FT0, FT2, &env->fp_status);
1327
#endif
1328
    RETURN();
1329
}
1330

    
1331
/* fnmadd - fnmadd. - fnmadds - fnmadds. */
1332
void OPPROTO op_fnmadd (void)
1333
{
1334
    do_fnmadd();
1335
    RETURN();
1336
}
1337

    
1338
/* fnmsub - fnmsub. */
1339
void OPPROTO op_fnmsub (void)
1340
{
1341
    do_fnmsub();
1342
    RETURN();
1343
}
1344

    
1345
/***                     Floating-Point round & convert                    ***/
1346
/* frsp - frsp. */
1347
void OPPROTO op_frsp (void)
1348
{
1349
#if USE_PRECISE_EMULATION
1350
    do_frsp();
1351
#else
1352
    FT0 = float64_to_float32(FT0, &env->fp_status);
1353
#endif
1354
    RETURN();
1355
}
1356

    
1357
/* fctiw - fctiw. */
1358
void OPPROTO op_fctiw (void)
1359
{
1360
    do_fctiw();
1361
    RETURN();
1362
}
1363

    
1364
/* fctiwz - fctiwz. */
1365
void OPPROTO op_fctiwz (void)
1366
{
1367
    do_fctiwz();
1368
    RETURN();
1369
}
1370

    
1371
#if defined(TARGET_PPC64)
1372
/* fcfid - fcfid. */
1373
void OPPROTO op_fcfid (void)
1374
{
1375
    do_fcfid();
1376
    RETURN();
1377
}
1378

    
1379
/* fctid - fctid. */
1380
void OPPROTO op_fctid (void)
1381
{
1382
    do_fctid();
1383
    RETURN();
1384
}
1385

    
1386
/* fctidz - fctidz. */
1387
void OPPROTO op_fctidz (void)
1388
{
1389
    do_fctidz();
1390
    RETURN();
1391
}
1392
#endif
1393

    
1394
void OPPROTO op_frin (void)
1395
{
1396
    do_frin();
1397
    RETURN();
1398
}
1399

    
1400
void OPPROTO op_friz (void)
1401
{
1402
    do_friz();
1403
    RETURN();
1404
}
1405

    
1406
void OPPROTO op_frip (void)
1407
{
1408
    do_frip();
1409
    RETURN();
1410
}
1411

    
1412
void OPPROTO op_frim (void)
1413
{
1414
    do_frim();
1415
    RETURN();
1416
}
1417

    
1418
/***                         Floating-point move                           ***/
1419
/* fabs */
1420
void OPPROTO op_fabs (void)
1421
{
1422
    FT0 = float64_abs(FT0);
1423
    RETURN();
1424
}
1425

    
1426
/* fnabs */
1427
void OPPROTO op_fnabs (void)
1428
{
1429
    FT0 = float64_abs(FT0);
1430
    FT0 = float64_chs(FT0);
1431
    RETURN();
1432
}
1433

    
1434
/* fneg */
1435
void OPPROTO op_fneg (void)
1436
{
1437
    FT0 = float64_chs(FT0);
1438
    RETURN();
1439
}
1440

    
1441
/* Load and store */
1442
#define MEMSUFFIX _raw
1443
#include "op_helper.h"
1444
#include "op_mem.h"
1445
#if !defined(CONFIG_USER_ONLY)
1446
#define MEMSUFFIX _user
1447
#include "op_helper.h"
1448
#include "op_mem.h"
1449
#define MEMSUFFIX _kernel
1450
#include "op_helper.h"
1451
#include "op_mem.h"
1452
#define MEMSUFFIX _hypv
1453
#include "op_helper.h"
1454
#include "op_mem.h"
1455
#endif
1456

    
1457
/* Special op to check and maybe clear reservation */
1458
void OPPROTO op_check_reservation (void)
1459
{
1460
    if ((uint32_t)env->reserve == (uint32_t)(T0 & ~0x00000003))
1461
        env->reserve = (target_ulong)-1ULL;
1462
    RETURN();
1463
}
1464

    
1465
#if defined(TARGET_PPC64)
1466
void OPPROTO op_check_reservation_64 (void)
1467
{
1468
    if ((uint64_t)env->reserve == (uint64_t)(T0 & ~0x00000003))
1469
        env->reserve = (target_ulong)-1ULL;
1470
    RETURN();
1471
}
1472
#endif
1473

    
1474
void OPPROTO op_wait (void)
1475
{
1476
    env->halted = 1;
1477
    RETURN();
1478
}
1479

    
1480
/* Return from interrupt */
1481
#if !defined(CONFIG_USER_ONLY)
1482
void OPPROTO op_rfi (void)
1483
{
1484
    do_rfi();
1485
    RETURN();
1486
}
1487

    
1488
#if defined(TARGET_PPC64)
1489
void OPPROTO op_rfid (void)
1490
{
1491
    do_rfid();
1492
    RETURN();
1493
}
1494

    
1495
void OPPROTO op_hrfid (void)
1496
{
1497
    do_hrfid();
1498
    RETURN();
1499
}
1500
#endif
1501

    
1502
/* Exception vectors */
1503
void OPPROTO op_store_excp_prefix (void)
1504
{
1505
    T0 &= env->ivpr_mask;
1506
    env->excp_prefix = T0;
1507
    RETURN();
1508
}
1509

    
1510
void OPPROTO op_store_excp_vector (void)
1511
{
1512
    T0 &= env->ivor_mask;
1513
    env->excp_vectors[PARAM1] = T0;
1514
    RETURN();
1515
}
1516
#endif
1517

    
1518
/* Trap word */
1519
void OPPROTO op_tw (void)
1520
{
1521
    do_tw(PARAM1);
1522
    RETURN();
1523
}
1524

    
1525
#if defined(TARGET_PPC64)
1526
void OPPROTO op_td (void)
1527
{
1528
    do_td(PARAM1);
1529
    RETURN();
1530
}
1531
#endif
1532

    
1533
#if !defined(CONFIG_USER_ONLY)
1534
/* tlbia */
1535
void OPPROTO op_tlbia (void)
1536
{
1537
    ppc_tlb_invalidate_all(env);
1538
    RETURN();
1539
}
1540

    
1541
/* tlbie */
1542
void OPPROTO op_tlbie (void)
1543
{
1544
    ppc_tlb_invalidate_one(env, (uint32_t)T0);
1545
    RETURN();
1546
}
1547

    
1548
#if defined(TARGET_PPC64)
1549
void OPPROTO op_tlbie_64 (void)
1550
{
1551
    ppc_tlb_invalidate_one(env, T0);
1552
    RETURN();
1553
}
1554
#endif
1555

    
1556
#if defined(TARGET_PPC64)
1557
void OPPROTO op_slbia (void)
1558
{
1559
    ppc_slb_invalidate_all(env);
1560
    RETURN();
1561
}
1562

    
1563
void OPPROTO op_slbie (void)
1564
{
1565
    ppc_slb_invalidate_one(env, (uint32_t)T0);
1566
    RETURN();
1567
}
1568

    
1569
void OPPROTO op_slbie_64 (void)
1570
{
1571
    ppc_slb_invalidate_one(env, T0);
1572
    RETURN();
1573
}
1574
#endif
1575
#endif
1576

    
1577
#if !defined(CONFIG_USER_ONLY)
1578
/* PowerPC 602/603/755 software TLB load instructions */
1579
void OPPROTO op_6xx_tlbld (void)
1580
{
1581
    do_load_6xx_tlb(0);
1582
    RETURN();
1583
}
1584

    
1585
void OPPROTO op_6xx_tlbli (void)
1586
{
1587
    do_load_6xx_tlb(1);
1588
    RETURN();
1589
}
1590

    
1591
/* PowerPC 74xx software TLB load instructions */
1592
void OPPROTO op_74xx_tlbld (void)
1593
{
1594
    do_load_74xx_tlb(0);
1595
    RETURN();
1596
}
1597

    
1598
void OPPROTO op_74xx_tlbli (void)
1599
{
1600
    do_load_74xx_tlb(1);
1601
    RETURN();
1602
}
1603
#endif
1604

    
1605
/* 601 specific */
1606
void OPPROTO op_load_601_rtcl (void)
1607
{
1608
    T0 = cpu_ppc601_load_rtcl(env);
1609
    RETURN();
1610
}
1611

    
1612
void OPPROTO op_load_601_rtcu (void)
1613
{
1614
    T0 = cpu_ppc601_load_rtcu(env);
1615
    RETURN();
1616
}
1617

    
1618
#if !defined(CONFIG_USER_ONLY)
1619
void OPPROTO op_store_601_rtcl (void)
1620
{
1621
    cpu_ppc601_store_rtcl(env, T0);
1622
    RETURN();
1623
}
1624

    
1625
void OPPROTO op_store_601_rtcu (void)
1626
{
1627
    cpu_ppc601_store_rtcu(env, T0);
1628
    RETURN();
1629
}
1630

    
1631
void OPPROTO op_store_hid0_601 (void)
1632
{
1633
    do_store_hid0_601();
1634
    RETURN();
1635
}
1636

    
1637
void OPPROTO op_load_601_bat (void)
1638
{
1639
    T0 = env->IBAT[PARAM1][PARAM2];
1640
    RETURN();
1641
}
1642

    
1643
void OPPROTO op_store_601_batl (void)
1644
{
1645
    do_store_ibatl_601(env, PARAM1, T0);
1646
    RETURN();
1647
}
1648

    
1649
void OPPROTO op_store_601_batu (void)
1650
{
1651
    do_store_ibatu_601(env, PARAM1, T0);
1652
    RETURN();
1653
}
1654
#endif /* !defined(CONFIG_USER_ONLY) */
1655

    
1656
/* PowerPC 601 specific instructions (POWER bridge) */
1657
/* XXX: those micro-ops need tests ! */
1658
void OPPROTO op_POWER_abs (void)
1659
{
1660
    if ((int32_t)T0 == INT32_MIN)
1661
        T0 = INT32_MAX;
1662
    else if ((int32_t)T0 < 0)
1663
        T0 = -T0;
1664
    RETURN();
1665
}
1666

    
1667
void OPPROTO op_POWER_abso (void)
1668
{
1669
    do_POWER_abso();
1670
    RETURN();
1671
}
1672

    
1673
void OPPROTO op_POWER_clcs (void)
1674
{
1675
    do_POWER_clcs();
1676
    RETURN();
1677
}
1678

    
1679
void OPPROTO op_POWER_div (void)
1680
{
1681
    do_POWER_div();
1682
    RETURN();
1683
}
1684

    
1685
void OPPROTO op_POWER_divo (void)
1686
{
1687
    do_POWER_divo();
1688
    RETURN();
1689
}
1690

    
1691
void OPPROTO op_POWER_divs (void)
1692
{
1693
    do_POWER_divs();
1694
    RETURN();
1695
}
1696

    
1697
void OPPROTO op_POWER_divso (void)
1698
{
1699
    do_POWER_divso();
1700
    RETURN();
1701
}
1702

    
1703
void OPPROTO op_POWER_doz (void)
1704
{
1705
    if ((int32_t)T1 > (int32_t)T0)
1706
        T0 = T1 - T0;
1707
    else
1708
        T0 = 0;
1709
    RETURN();
1710
}
1711

    
1712
void OPPROTO op_POWER_dozo (void)
1713
{
1714
    do_POWER_dozo();
1715
    RETURN();
1716
}
1717

    
1718
void OPPROTO op_load_xer_cmp (void)
1719
{
1720
    T2 = xer_cmp;
1721
    RETURN();
1722
}
1723

    
1724
void OPPROTO op_POWER_maskg (void)
1725
{
1726
    do_POWER_maskg();
1727
    RETURN();
1728
}
1729

    
1730
void OPPROTO op_POWER_maskir (void)
1731
{
1732
    T0 = (T0 & ~T2) | (T1 & T2);
1733
    RETURN();
1734
}
1735

    
1736
void OPPROTO op_POWER_mul (void)
1737
{
1738
    uint64_t tmp;
1739

    
1740
    tmp = (uint64_t)T0 * (uint64_t)T1;
1741
    env->spr[SPR_MQ] = tmp >> 32;
1742
    T0 = tmp;
1743
    RETURN();
1744
}
1745

    
1746
void OPPROTO op_POWER_mulo (void)
1747
{
1748
    do_POWER_mulo();
1749
    RETURN();
1750
}
1751

    
1752
void OPPROTO op_POWER_nabs (void)
1753
{
1754
    if (T0 > 0)
1755
        T0 = -T0;
1756
    RETURN();
1757
}
1758

    
1759
void OPPROTO op_POWER_nabso (void)
1760
{
1761
    /* nabs never overflows */
1762
    if (T0 > 0)
1763
        T0 = -T0;
1764
    env->xer &= ~(1 << XER_OV);
1765
    RETURN();
1766
}
1767

    
1768
/* XXX: factorise POWER rotates... */
1769
void OPPROTO op_POWER_rlmi (void)
1770
{
1771
    T0 = rotl32(T0, T2) & PARAM1;
1772
    T0 |= T1 & (uint32_t)PARAM2;
1773
    RETURN();
1774
}
1775

    
1776
void OPPROTO op_POWER_rrib (void)
1777
{
1778
    T2 &= 0x1FUL;
1779
    T0 = rotl32(T0 & INT32_MIN, T2);
1780
    T0 |= T1 & ~rotl32(INT32_MIN, T2);
1781
    RETURN();
1782
}
1783

    
1784
void OPPROTO op_POWER_sle (void)
1785
{
1786
    T1 &= 0x1FUL;
1787
    env->spr[SPR_MQ] = rotl32(T0, T1);
1788
    T0 = T0 << T1;
1789
    RETURN();
1790
}
1791

    
1792
void OPPROTO op_POWER_sleq (void)
1793
{
1794
    uint32_t tmp = env->spr[SPR_MQ];
1795

    
1796
    T1 &= 0x1FUL;
1797
    env->spr[SPR_MQ] = rotl32(T0, T1);
1798
    T0 = T0 << T1;
1799
    T0 |= tmp >> (32 - T1);
1800
    RETURN();
1801
}
1802

    
1803
void OPPROTO op_POWER_sllq (void)
1804
{
1805
    uint32_t msk = UINT32_MAX;
1806

    
1807
    msk = msk << (T1 & 0x1FUL);
1808
    if (T1 & 0x20UL)
1809
        msk = ~msk;
1810
    T1 &= 0x1FUL;
1811
    T0 = (T0 << T1) & msk;
1812
    T0 |= env->spr[SPR_MQ] & ~msk;
1813
    RETURN();
1814
}
1815

    
1816
void OPPROTO op_POWER_slq (void)
1817
{
1818
    uint32_t msk = UINT32_MAX, tmp;
1819

    
1820
    msk = msk << (T1 & 0x1FUL);
1821
    if (T1 & 0x20UL)
1822
        msk = ~msk;
1823
    T1 &= 0x1FUL;
1824
    tmp = rotl32(T0, T1);
1825
    T0 = tmp & msk;
1826
    env->spr[SPR_MQ] = tmp;
1827
    RETURN();
1828
}
1829

    
1830
void OPPROTO op_POWER_sraq (void)
1831
{
1832
    env->spr[SPR_MQ] = rotl32(T0, 32 - (T1 & 0x1FUL));
1833
    if (T1 & 0x20UL)
1834
        T0 = UINT32_MAX;
1835
    else
1836
        T0 = (int32_t)T0 >> T1;
1837
    RETURN();
1838
}
1839

    
1840
void OPPROTO op_POWER_sre (void)
1841
{
1842
    T1 &= 0x1FUL;
1843
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
1844
    T0 = (int32_t)T0 >> T1;
1845
    RETURN();
1846
}
1847

    
1848
void OPPROTO op_POWER_srea (void)
1849
{
1850
    T1 &= 0x1FUL;
1851
    env->spr[SPR_MQ] = T0 >> T1;
1852
    T0 = (int32_t)T0 >> T1;
1853
    RETURN();
1854
}
1855

    
1856
void OPPROTO op_POWER_sreq (void)
1857
{
1858
    uint32_t tmp;
1859
    int32_t msk;
1860

    
1861
    T1 &= 0x1FUL;
1862
    msk = INT32_MIN >> T1;
1863
    tmp = env->spr[SPR_MQ];
1864
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
1865
    T0 = T0 >> T1;
1866
    T0 |= tmp & msk;
1867
    RETURN();
1868
}
1869

    
1870
void OPPROTO op_POWER_srlq (void)
1871
{
1872
    uint32_t tmp;
1873
    int32_t msk;
1874

    
1875
    msk = INT32_MIN >> (T1 & 0x1FUL);
1876
    if (T1 & 0x20UL)
1877
        msk = ~msk;
1878
    T1 &= 0x1FUL;
1879
    tmp = env->spr[SPR_MQ];
1880
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
1881
    T0 = T0 >> T1;
1882
    T0 &= msk;
1883
    T0 |= tmp & ~msk;
1884
    RETURN();
1885
}
1886

    
1887
void OPPROTO op_POWER_srq (void)
1888
{
1889
    T1 &= 0x1FUL;
1890
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
1891
    T0 = T0 >> T1;
1892
    RETURN();
1893
}
1894

    
1895
/* POWER instructions not implemented in PowerPC 601 */
1896
#if !defined(CONFIG_USER_ONLY)
1897
void OPPROTO op_POWER_mfsri (void)
1898
{
1899
    T1 = T0 >> 28;
1900
    T0 = env->sr[T1];
1901
    RETURN();
1902
}
1903

    
1904
void OPPROTO op_POWER_rac (void)
1905
{
1906
    do_POWER_rac();
1907
    RETURN();
1908
}
1909

    
1910
void OPPROTO op_POWER_rfsvc (void)
1911
{
1912
    do_POWER_rfsvc();
1913
    RETURN();
1914
}
1915
#endif
1916

    
1917
/* PowerPC 602 specific instruction */
1918
#if !defined(CONFIG_USER_ONLY)
1919
void OPPROTO op_602_mfrom (void)
1920
{
1921
    do_op_602_mfrom();
1922
    RETURN();
1923
}
1924
#endif
1925

    
1926
/* PowerPC 4xx specific micro-ops */
1927
void OPPROTO op_405_add_T0_T2 (void)
1928
{
1929
    T0 = (int32_t)T0 + (int32_t)T2;
1930
    RETURN();
1931
}
1932

    
1933
void OPPROTO op_405_mulchw (void)
1934
{
1935
    T0 = ((int16_t)T0) * ((int16_t)(T1 >> 16));
1936
    RETURN();
1937
}
1938

    
1939
void OPPROTO op_405_mulchwu (void)
1940
{
1941
    T0 = ((uint16_t)T0) * ((uint16_t)(T1 >> 16));
1942
    RETURN();
1943
}
1944

    
1945
void OPPROTO op_405_mulhhw (void)
1946
{
1947
    T0 = ((int16_t)(T0 >> 16)) * ((int16_t)(T1 >> 16));
1948
    RETURN();
1949
}
1950

    
1951
void OPPROTO op_405_mulhhwu (void)
1952
{
1953
    T0 = ((uint16_t)(T0 >> 16)) * ((uint16_t)(T1 >> 16));
1954
    RETURN();
1955
}
1956

    
1957
void OPPROTO op_405_mullhw (void)
1958
{
1959
    T0 = ((int16_t)T0) * ((int16_t)T1);
1960
    RETURN();
1961
}
1962

    
1963
void OPPROTO op_405_mullhwu (void)
1964
{
1965
    T0 = ((uint16_t)T0) * ((uint16_t)T1);
1966
    RETURN();
1967
}
1968

    
1969
void OPPROTO op_405_check_sat (void)
1970
{
1971
    do_405_check_sat();
1972
    RETURN();
1973
}
1974

    
1975
void OPPROTO op_405_check_ovu (void)
1976
{
1977
    if (likely(T0 >= T2)) {
1978
        env->xer &= ~(1 << XER_OV);
1979
    } else {
1980
        env->xer |= (1 << XER_OV) | (1 << XER_SO);
1981
    }
1982
    RETURN();
1983
}
1984

    
1985
void OPPROTO op_405_check_satu (void)
1986
{
1987
    if (unlikely(T0 < T2)) {
1988
        /* Saturate result */
1989
        T0 = UINT32_MAX;
1990
    }
1991
    RETURN();
1992
}
1993

    
1994
void OPPROTO op_load_dcr (void)
1995
{
1996
    do_load_dcr();
1997
    RETURN();
1998
}
1999

    
2000
void OPPROTO op_store_dcr (void)
2001
{
2002
    do_store_dcr();
2003
    RETURN();
2004
}
2005

    
2006
#if !defined(CONFIG_USER_ONLY)
2007
/* Return from critical interrupt :
2008
 * same as rfi, except nip & MSR are loaded from SRR2/3 instead of SRR0/1
2009
 */
2010
void OPPROTO op_40x_rfci (void)
2011
{
2012
    do_40x_rfci();
2013
    RETURN();
2014
}
2015

    
2016
void OPPROTO op_rfci (void)
2017
{
2018
    do_rfci();
2019
    RETURN();
2020
}
2021

    
2022
void OPPROTO op_rfdi (void)
2023
{
2024
    do_rfdi();
2025
    RETURN();
2026
}
2027

    
2028
void OPPROTO op_rfmci (void)
2029
{
2030
    do_rfmci();
2031
    RETURN();
2032
}
2033

    
2034
void OPPROTO op_wrte (void)
2035
{
2036
    /* We don't call do_store_msr here as we won't trigger
2037
     * any special case nor change hflags
2038
     */
2039
    T0 &= 1 << MSR_EE;
2040
    env->msr &= ~(1 << MSR_EE);
2041
    env->msr |= T0;
2042
    RETURN();
2043
}
2044

    
2045
void OPPROTO op_440_tlbre (void)
2046
{
2047
    do_440_tlbre(PARAM1);
2048
    RETURN();
2049
}
2050

    
2051
void OPPROTO op_440_tlbsx (void)
2052
{
2053
    T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_440_MMUCR] & 0xFF);
2054
    RETURN();
2055
}
2056

    
2057
void OPPROTO op_4xx_tlbsx_check (void)
2058
{
2059
    int tmp;
2060

    
2061
    tmp = xer_so;
2062
    if ((int)T0 != -1)
2063
        tmp |= 0x02;
2064
    env->crf[0] = tmp;
2065
    RETURN();
2066
}
2067

    
2068
void OPPROTO op_440_tlbwe (void)
2069
{
2070
    do_440_tlbwe(PARAM1);
2071
    RETURN();
2072
}
2073

    
2074
void OPPROTO op_4xx_tlbre_lo (void)
2075
{
2076
    do_4xx_tlbre_lo();
2077
    RETURN();
2078
}
2079

    
2080
void OPPROTO op_4xx_tlbre_hi (void)
2081
{
2082
    do_4xx_tlbre_hi();
2083
    RETURN();
2084
}
2085

    
2086
void OPPROTO op_4xx_tlbsx (void)
2087
{
2088
    T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_40x_PID]);
2089
    RETURN();
2090
}
2091

    
2092
void OPPROTO op_4xx_tlbwe_lo (void)
2093
{
2094
    do_4xx_tlbwe_lo();
2095
    RETURN();
2096
}
2097

    
2098
void OPPROTO op_4xx_tlbwe_hi (void)
2099
{
2100
    do_4xx_tlbwe_hi();
2101
    RETURN();
2102
}
2103
#endif
2104

    
2105
/* SPR micro-ops */
2106
/* 440 specific */
2107
void OPPROTO op_440_dlmzb (void)
2108
{
2109
    do_440_dlmzb();
2110
    RETURN();
2111
}
2112

    
2113
void OPPROTO op_440_dlmzb_update_Rc (void)
2114
{
2115
    if (T0 == 8)
2116
        T0 = 0x2;
2117
    else if (T0 < 4)
2118
        T0 = 0x4;
2119
    else
2120
        T0 = 0x8;
2121
    RETURN();
2122
}
2123

    
2124
#if !defined(CONFIG_USER_ONLY)
2125
void OPPROTO op_store_pir (void)
2126
{
2127
    env->spr[SPR_PIR] = T0 & 0x0000000FUL;
2128
    RETURN();
2129
}
2130

    
2131
void OPPROTO op_load_403_pb (void)
2132
{
2133
    do_load_403_pb(PARAM1);
2134
    RETURN();
2135
}
2136

    
2137
void OPPROTO op_store_403_pb (void)
2138
{
2139
    do_store_403_pb(PARAM1);
2140
    RETURN();
2141
}
2142

    
2143
void OPPROTO op_load_40x_pit (void)
2144
{
2145
    T0 = load_40x_pit(env);
2146
    RETURN();
2147
}
2148

    
2149
void OPPROTO op_store_40x_pit (void)
2150
{
2151
    store_40x_pit(env, T0);
2152
    RETURN();
2153
}
2154

    
2155
void OPPROTO op_store_40x_dbcr0 (void)
2156
{
2157
    store_40x_dbcr0(env, T0);
2158
    RETURN();
2159
}
2160

    
2161
void OPPROTO op_store_40x_sler (void)
2162
{
2163
    store_40x_sler(env, T0);
2164
    RETURN();
2165
}
2166

    
2167
void OPPROTO op_store_booke_tcr (void)
2168
{
2169
    store_booke_tcr(env, T0);
2170
    RETURN();
2171
}
2172

    
2173
void OPPROTO op_store_booke_tsr (void)
2174
{
2175
    store_booke_tsr(env, T0);
2176
    RETURN();
2177
}
2178
#endif /* !defined(CONFIG_USER_ONLY) */
2179

    
2180
/* SPE extension */
2181
void OPPROTO op_splatw_T1_64 (void)
2182
{
2183
    T1_64 = (T1_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL);
2184
    RETURN();
2185
}
2186

    
2187
void OPPROTO op_splatwi_T0_64 (void)
2188
{
2189
    uint64_t tmp = PARAM1;
2190

    
2191
    T0_64 = (tmp << 32) | tmp;
2192
    RETURN();
2193
}
2194

    
2195
void OPPROTO op_splatwi_T1_64 (void)
2196
{
2197
    uint64_t tmp = PARAM1;
2198

    
2199
    T1_64 = (tmp << 32) | tmp;
2200
    RETURN();
2201
}
2202

    
2203
void OPPROTO op_extsh_T1_64 (void)
2204
{
2205
    T1_64 = (int32_t)((int16_t)T1_64);
2206
    RETURN();
2207
}
2208

    
2209
void OPPROTO op_sli16_T1_64 (void)
2210
{
2211
    T1_64 = T1_64 << 16;
2212
    RETURN();
2213
}
2214

    
2215
void OPPROTO op_sli32_T1_64 (void)
2216
{
2217
    T1_64 = T1_64 << 32;
2218
    RETURN();
2219
}
2220

    
2221
void OPPROTO op_srli32_T1_64 (void)
2222
{
2223
    T1_64 = T1_64 >> 32;
2224
    RETURN();
2225
}
2226

    
2227
void OPPROTO op_evsel (void)
2228
{
2229
    do_evsel();
2230
    RETURN();
2231
}
2232

    
2233
void OPPROTO op_evaddw (void)
2234
{
2235
    do_evaddw();
2236
    RETURN();
2237
}
2238

    
2239
void OPPROTO op_evsubfw (void)
2240
{
2241
    do_evsubfw();
2242
    RETURN();
2243
}
2244

    
2245
void OPPROTO op_evneg (void)
2246
{
2247
    do_evneg();
2248
    RETURN();
2249
}
2250

    
2251
void OPPROTO op_evabs (void)
2252
{
2253
    do_evabs();
2254
    RETURN();
2255
}
2256

    
2257
void OPPROTO op_evextsh (void)
2258
{
2259
    T0_64 = ((uint64_t)((int32_t)(int16_t)(T0_64 >> 32)) << 32) |
2260
        (uint64_t)((int32_t)(int16_t)T0_64);
2261
    RETURN();
2262
}
2263

    
2264
void OPPROTO op_evextsb (void)
2265
{
2266
    T0_64 = ((uint64_t)((int32_t)(int8_t)(T0_64 >> 32)) << 32) |
2267
        (uint64_t)((int32_t)(int8_t)T0_64);
2268
    RETURN();
2269
}
2270

    
2271
void OPPROTO op_evcntlzw (void)
2272
{
2273
    do_evcntlzw();
2274
    RETURN();
2275
}
2276

    
2277
void OPPROTO op_evrndw (void)
2278
{
2279
    do_evrndw();
2280
    RETURN();
2281
}
2282

    
2283
void OPPROTO op_brinc (void)
2284
{
2285
    do_brinc();
2286
    RETURN();
2287
}
2288

    
2289
void OPPROTO op_evcntlsw (void)
2290
{
2291
    do_evcntlsw();
2292
    RETURN();
2293
}
2294

    
2295
void OPPROTO op_evsrws (void)
2296
{
2297
    do_evsrws();
2298
    RETURN();
2299
}
2300

    
2301
void OPPROTO op_evsrwu (void)
2302
{
2303
    do_evsrwu();
2304
    RETURN();
2305
}
2306

    
2307
void OPPROTO op_evslw (void)
2308
{
2309
    do_evslw();
2310
    RETURN();
2311
}
2312

    
2313
void OPPROTO op_evrlw (void)
2314
{
2315
    do_evrlw();
2316
    RETURN();
2317
}
2318

    
2319
void OPPROTO op_evmergelo (void)
2320
{
2321
    T0_64 = (T0_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL);
2322
    RETURN();
2323
}
2324

    
2325
void OPPROTO op_evmergehi (void)
2326
{
2327
    T0_64 = (T0_64 & 0xFFFFFFFF00000000ULL) | (T1_64 >> 32);
2328
    RETURN();
2329
}
2330

    
2331
void OPPROTO op_evmergelohi (void)
2332
{
2333
    T0_64 = (T0_64 << 32) | (T1_64 >> 32);
2334
    RETURN();
2335
}
2336

    
2337
void OPPROTO op_evmergehilo (void)
2338
{
2339
    T0_64 = (T0_64 & 0xFFFFFFFF00000000ULL) | (T1_64 & 0x00000000FFFFFFFFULL);
2340
    RETURN();
2341
}
2342

    
2343
void OPPROTO op_evcmpgts (void)
2344
{
2345
    do_evcmpgts();
2346
    RETURN();
2347
}
2348

    
2349
void OPPROTO op_evcmpgtu (void)
2350
{
2351
    do_evcmpgtu();
2352
    RETURN();
2353
}
2354

    
2355
void OPPROTO op_evcmplts (void)
2356
{
2357
    do_evcmplts();
2358
    RETURN();
2359
}
2360

    
2361
void OPPROTO op_evcmpltu (void)
2362
{
2363
    do_evcmpltu();
2364
    RETURN();
2365
}
2366

    
2367
void OPPROTO op_evcmpeq (void)
2368
{
2369
    do_evcmpeq();
2370
    RETURN();
2371
}
2372

    
2373
void OPPROTO op_evfssub (void)
2374
{
2375
    do_evfssub();
2376
    RETURN();
2377
}
2378

    
2379
void OPPROTO op_evfsadd (void)
2380
{
2381
    do_evfsadd();
2382
    RETURN();
2383
}
2384

    
2385
void OPPROTO op_evfsnabs (void)
2386
{
2387
    do_evfsnabs();
2388
    RETURN();
2389
}
2390

    
2391
void OPPROTO op_evfsabs (void)
2392
{
2393
    do_evfsabs();
2394
    RETURN();
2395
}
2396

    
2397
void OPPROTO op_evfsneg (void)
2398
{
2399
    do_evfsneg();
2400
    RETURN();
2401
}
2402

    
2403
void OPPROTO op_evfsdiv (void)
2404
{
2405
    do_evfsdiv();
2406
    RETURN();
2407
}
2408

    
2409
void OPPROTO op_evfsmul (void)
2410
{
2411
    do_evfsmul();
2412
    RETURN();
2413
}
2414

    
2415
void OPPROTO op_evfscmplt (void)
2416
{
2417
    do_evfscmplt();
2418
    RETURN();
2419
}
2420

    
2421
void OPPROTO op_evfscmpgt (void)
2422
{
2423
    do_evfscmpgt();
2424
    RETURN();
2425
}
2426

    
2427
void OPPROTO op_evfscmpeq (void)
2428
{
2429
    do_evfscmpeq();
2430
    RETURN();
2431
}
2432

    
2433
void OPPROTO op_evfscfsi (void)
2434
{
2435
    do_evfscfsi();
2436
    RETURN();
2437
}
2438

    
2439
void OPPROTO op_evfscfui (void)
2440
{
2441
    do_evfscfui();
2442
    RETURN();
2443
}
2444

    
2445
void OPPROTO op_evfscfsf (void)
2446
{
2447
    do_evfscfsf();
2448
    RETURN();
2449
}
2450

    
2451
void OPPROTO op_evfscfuf (void)
2452
{
2453
    do_evfscfuf();
2454
    RETURN();
2455
}
2456

    
2457
void OPPROTO op_evfsctsi (void)
2458
{
2459
    do_evfsctsi();
2460
    RETURN();
2461
}
2462

    
2463
void OPPROTO op_evfsctui (void)
2464
{
2465
    do_evfsctui();
2466
    RETURN();
2467
}
2468

    
2469
void OPPROTO op_evfsctsf (void)
2470
{
2471
    do_evfsctsf();
2472
    RETURN();
2473
}
2474

    
2475
void OPPROTO op_evfsctuf (void)
2476
{
2477
    do_evfsctuf();
2478
    RETURN();
2479
}
2480

    
2481
void OPPROTO op_evfsctuiz (void)
2482
{
2483
    do_evfsctuiz();
2484
    RETURN();
2485
}
2486

    
2487
void OPPROTO op_evfsctsiz (void)
2488
{
2489
    do_evfsctsiz();
2490
    RETURN();
2491
}
2492

    
2493
void OPPROTO op_evfststlt (void)
2494
{
2495
    do_evfststlt();
2496
    RETURN();
2497
}
2498

    
2499
void OPPROTO op_evfststgt (void)
2500
{
2501
    do_evfststgt();
2502
    RETURN();
2503
}
2504

    
2505
void OPPROTO op_evfststeq (void)
2506
{
2507
    do_evfststeq();
2508
    RETURN();
2509
}
2510

    
2511
void OPPROTO op_efssub (void)
2512
{
2513
    T0_64 = _do_efssub(T0_64, T1_64);
2514
    RETURN();
2515
}
2516

    
2517
void OPPROTO op_efsadd (void)
2518
{
2519
    T0_64 = _do_efsadd(T0_64, T1_64);
2520
    RETURN();
2521
}
2522

    
2523
void OPPROTO op_efsnabs (void)
2524
{
2525
    T0_64 = _do_efsnabs(T0_64);
2526
    RETURN();
2527
}
2528

    
2529
void OPPROTO op_efsabs (void)
2530
{
2531
    T0_64 = _do_efsabs(T0_64);
2532
    RETURN();
2533
}
2534

    
2535
void OPPROTO op_efsneg (void)
2536
{
2537
    T0_64 = _do_efsneg(T0_64);
2538
    RETURN();
2539
}
2540

    
2541
void OPPROTO op_efsdiv (void)
2542
{
2543
    T0_64 = _do_efsdiv(T0_64, T1_64);
2544
    RETURN();
2545
}
2546

    
2547
void OPPROTO op_efsmul (void)
2548
{
2549
    T0_64 = _do_efsmul(T0_64, T1_64);
2550
    RETURN();
2551
}
2552

    
2553
void OPPROTO op_efscmplt (void)
2554
{
2555
    do_efscmplt();
2556
    RETURN();
2557
}
2558

    
2559
void OPPROTO op_efscmpgt (void)
2560
{
2561
    do_efscmpgt();
2562
    RETURN();
2563
}
2564

    
2565
void OPPROTO op_efscfd (void)
2566
{
2567
    do_efscfd();
2568
    RETURN();
2569
}
2570

    
2571
void OPPROTO op_efscmpeq (void)
2572
{
2573
    do_efscmpeq();
2574
    RETURN();
2575
}
2576

    
2577
void OPPROTO op_efscfsi (void)
2578
{
2579
    do_efscfsi();
2580
    RETURN();
2581
}
2582

    
2583
void OPPROTO op_efscfui (void)
2584
{
2585
    do_efscfui();
2586
    RETURN();
2587
}
2588

    
2589
void OPPROTO op_efscfsf (void)
2590
{
2591
    do_efscfsf();
2592
    RETURN();
2593
}
2594

    
2595
void OPPROTO op_efscfuf (void)
2596
{
2597
    do_efscfuf();
2598
    RETURN();
2599
}
2600

    
2601
void OPPROTO op_efsctsi (void)
2602
{
2603
    do_efsctsi();
2604
    RETURN();
2605
}
2606

    
2607
void OPPROTO op_efsctui (void)
2608
{
2609
    do_efsctui();
2610
    RETURN();
2611
}
2612

    
2613
void OPPROTO op_efsctsf (void)
2614
{
2615
    do_efsctsf();
2616
    RETURN();
2617
}
2618

    
2619
void OPPROTO op_efsctuf (void)
2620
{
2621
    do_efsctuf();
2622
    RETURN();
2623
}
2624

    
2625
void OPPROTO op_efsctsiz (void)
2626
{
2627
    do_efsctsiz();
2628
    RETURN();
2629
}
2630

    
2631
void OPPROTO op_efsctuiz (void)
2632
{
2633
    do_efsctuiz();
2634
    RETURN();
2635
}
2636

    
2637
void OPPROTO op_efststlt (void)
2638
{
2639
    T0 = _do_efststlt(T0_64, T1_64);
2640
    RETURN();
2641
}
2642

    
2643
void OPPROTO op_efststgt (void)
2644
{
2645
    T0 = _do_efststgt(T0_64, T1_64);
2646
    RETURN();
2647
}
2648

    
2649
void OPPROTO op_efststeq (void)
2650
{
2651
    T0 = _do_efststeq(T0_64, T1_64);
2652
    RETURN();
2653
}
2654

    
2655
void OPPROTO op_efdsub (void)
2656
{
2657
    CPU_DoubleU u1, u2;
2658
    u1.ll = T0_64;
2659
    u2.ll = T1_64;
2660
    u1.d = float64_sub(u1.d, u2.d, &env->spe_status);
2661
    T0_64 = u1.ll;
2662
    RETURN();
2663
}
2664

    
2665
void OPPROTO op_efdadd (void)
2666
{
2667
    CPU_DoubleU u1, u2;
2668
    u1.ll = T0_64;
2669
    u2.ll = T1_64;
2670
    u1.d = float64_add(u1.d, u2.d, &env->spe_status);
2671
    T0_64 = u1.ll;
2672
    RETURN();
2673
}
2674

    
2675
void OPPROTO op_efdcfsid (void)
2676
{
2677
    do_efdcfsi();
2678
    RETURN();
2679
}
2680

    
2681
void OPPROTO op_efdcfuid (void)
2682
{
2683
    do_efdcfui();
2684
    RETURN();
2685
}
2686

    
2687
void OPPROTO op_efdnabs (void)
2688
{
2689
    T0_64 |= 0x8000000000000000ULL;
2690
    RETURN();
2691
}
2692

    
2693
void OPPROTO op_efdabs (void)
2694
{
2695
    T0_64 &= ~0x8000000000000000ULL;
2696
    RETURN();
2697
}
2698

    
2699
void OPPROTO op_efdneg (void)
2700
{
2701
    T0_64 ^= 0x8000000000000000ULL;
2702
    RETURN();
2703
}
2704

    
2705
void OPPROTO op_efddiv (void)
2706
{
2707
    CPU_DoubleU u1, u2;
2708
    u1.ll = T0_64;
2709
    u2.ll = T1_64;
2710
    u1.d = float64_div(u1.d, u2.d, &env->spe_status);
2711
    T0_64 = u1.ll;
2712
    RETURN();
2713
}
2714

    
2715
void OPPROTO op_efdmul (void)
2716
{
2717
    CPU_DoubleU u1, u2;
2718
    u1.ll = T0_64;
2719
    u2.ll = T1_64;
2720
    u1.d = float64_mul(u1.d, u2.d, &env->spe_status);
2721
    T0_64 = u1.ll;
2722
    RETURN();
2723
}
2724

    
2725
void OPPROTO op_efdctsidz (void)
2726
{
2727
    do_efdctsiz();
2728
    RETURN();
2729
}
2730

    
2731
void OPPROTO op_efdctuidz (void)
2732
{
2733
    do_efdctuiz();
2734
    RETURN();
2735
}
2736

    
2737
void OPPROTO op_efdcmplt (void)
2738
{
2739
    do_efdcmplt();
2740
    RETURN();
2741
}
2742

    
2743
void OPPROTO op_efdcmpgt (void)
2744
{
2745
    do_efdcmpgt();
2746
    RETURN();
2747
}
2748

    
2749
void OPPROTO op_efdcfs (void)
2750
{
2751
    do_efdcfs();
2752
    RETURN();
2753
}
2754

    
2755
void OPPROTO op_efdcmpeq (void)
2756
{
2757
    do_efdcmpeq();
2758
    RETURN();
2759
}
2760

    
2761
void OPPROTO op_efdcfsi (void)
2762
{
2763
    do_efdcfsi();
2764
    RETURN();
2765
}
2766

    
2767
void OPPROTO op_efdcfui (void)
2768
{
2769
    do_efdcfui();
2770
    RETURN();
2771
}
2772

    
2773
void OPPROTO op_efdcfsf (void)
2774
{
2775
    do_efdcfsf();
2776
    RETURN();
2777
}
2778

    
2779
void OPPROTO op_efdcfuf (void)
2780
{
2781
    do_efdcfuf();
2782
    RETURN();
2783
}
2784

    
2785
void OPPROTO op_efdctsi (void)
2786
{
2787
    do_efdctsi();
2788
    RETURN();
2789
}
2790

    
2791
void OPPROTO op_efdctui (void)
2792
{
2793
    do_efdctui();
2794
    RETURN();
2795
}
2796

    
2797
void OPPROTO op_efdctsf (void)
2798
{
2799
    do_efdctsf();
2800
    RETURN();
2801
}
2802

    
2803
void OPPROTO op_efdctuf (void)
2804
{
2805
    do_efdctuf();
2806
    RETURN();
2807
}
2808

    
2809
void OPPROTO op_efdctuiz (void)
2810
{
2811
    do_efdctuiz();
2812
    RETURN();
2813
}
2814

    
2815
void OPPROTO op_efdctsiz (void)
2816
{
2817
    do_efdctsiz();
2818
    RETURN();
2819
}
2820

    
2821
void OPPROTO op_efdtstlt (void)
2822
{
2823
    T0 = _do_efdtstlt(T0_64, T1_64);
2824
    RETURN();
2825
}
2826

    
2827
void OPPROTO op_efdtstgt (void)
2828
{
2829
    T0 = _do_efdtstgt(T0_64, T1_64);
2830
    RETURN();
2831
}
2832

    
2833
void OPPROTO op_efdtsteq (void)
2834
{
2835
    T0 = _do_efdtsteq(T0_64, T1_64);
2836
    RETURN();
2837
}