Statistics
| Branch: | Revision:

root / target-ppc / op.c @ e55fd934

History | View | Annotate | Download (49.8 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
/* Constants load */
140
void OPPROTO op_reset_T0 (void)
141
{
142
    T0 = 0;
143
    RETURN();
144
}
145

    
146
void OPPROTO op_set_T0 (void)
147
{
148
    T0 = (uint32_t)PARAM1;
149
    RETURN();
150
}
151

    
152
#if defined(TARGET_PPC64)
153
void OPPROTO op_set_T0_64 (void)
154
{
155
    T0 = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
156
    RETURN();
157
}
158
#endif
159

    
160
void OPPROTO op_set_T1 (void)
161
{
162
    T1 = (uint32_t)PARAM1;
163
    RETURN();
164
}
165

    
166
#if defined(TARGET_PPC64)
167
void OPPROTO op_set_T1_64 (void)
168
{
169
    T1 = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
170
    RETURN();
171
}
172
#endif
173

    
174
#if 0 // unused
175
void OPPROTO op_set_T2 (void)
176
{
177
    T2 = (uint32_t)PARAM1;
178
    RETURN();
179
}
180
#endif
181

    
182
void OPPROTO op_moven_T2_T0 (void)
183
{
184
    T2 = ~T0;
185
    RETURN();
186
}
187

    
188
/* Generate exceptions */
189
void OPPROTO op_raise_exception_err (void)
190
{
191
    do_raise_exception_err(PARAM1, PARAM2);
192
}
193

    
194
void OPPROTO op_update_nip (void)
195
{
196
    env->nip = (uint32_t)PARAM1;
197
    RETURN();
198
}
199

    
200
#if defined(TARGET_PPC64)
201
void OPPROTO op_update_nip_64 (void)
202
{
203
    env->nip = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
204
    RETURN();
205
}
206
#endif
207

    
208
void OPPROTO op_debug (void)
209
{
210
    do_raise_exception(EXCP_DEBUG);
211
}
212

    
213
/* Load/store special registers */
214
void OPPROTO op_load_cr (void)
215
{
216
    do_load_cr();
217
    RETURN();
218
}
219

    
220
void OPPROTO op_store_cr (void)
221
{
222
    do_store_cr(PARAM1);
223
    RETURN();
224
}
225

    
226
void OPPROTO op_load_cro (void)
227
{
228
    T0 = env->crf[PARAM1];
229
    RETURN();
230
}
231

    
232
void OPPROTO op_store_cro (void)
233
{
234
    env->crf[PARAM1] = T0;
235
    RETURN();
236
}
237

    
238
void OPPROTO op_load_xer_cr (void)
239
{
240
    T0 = (xer_so << 3) | (xer_ov << 2) | (xer_ca << 1);
241
    RETURN();
242
}
243

    
244
void OPPROTO op_clear_xer_ov (void)
245
{
246
    xer_so = 0;
247
    xer_ov = 0;
248
    RETURN();
249
}
250

    
251
void OPPROTO op_clear_xer_ca (void)
252
{
253
    xer_ca = 0;
254
    RETURN();
255
}
256

    
257
void OPPROTO op_load_xer_bc (void)
258
{
259
    T1 = xer_bc;
260
    RETURN();
261
}
262

    
263
void OPPROTO op_store_xer_bc (void)
264
{
265
    xer_bc = T0;
266
    RETURN();
267
}
268

    
269
void OPPROTO op_load_xer (void)
270
{
271
    T0 = hreg_load_xer(env);
272
    RETURN();
273
}
274

    
275
void OPPROTO op_store_xer (void)
276
{
277
    hreg_store_xer(env, T0);
278
    RETURN();
279
}
280

    
281
#if defined(TARGET_PPC64)
282
void OPPROTO op_store_pri (void)
283
{
284
    do_store_pri(PARAM1);
285
    RETURN();
286
}
287
#endif
288

    
289
#if !defined(CONFIG_USER_ONLY)
290
/* Segment registers load and store */
291
void OPPROTO op_load_sr (void)
292
{
293
    T0 = env->sr[T1];
294
    RETURN();
295
}
296

    
297
void OPPROTO op_store_sr (void)
298
{
299
    do_store_sr(env, T1, T0);
300
    RETURN();
301
}
302

    
303
#if defined(TARGET_PPC64)
304
void OPPROTO op_load_slb (void)
305
{
306
    T0 = ppc_load_slb(env, T1);
307
    RETURN();
308
}
309

    
310
void OPPROTO op_store_slb (void)
311
{
312
    ppc_store_slb(env, T1, T0);
313
    RETURN();
314
}
315
#endif /* defined(TARGET_PPC64) */
316

    
317
void OPPROTO op_load_sdr1 (void)
318
{
319
    T0 = env->sdr1;
320
    RETURN();
321
}
322

    
323
void OPPROTO op_store_sdr1 (void)
324
{
325
    do_store_sdr1(env, T0);
326
    RETURN();
327
}
328

    
329
#if defined (TARGET_PPC64)
330
void OPPROTO op_load_asr (void)
331
{
332
    T0 = env->asr;
333
    RETURN();
334
}
335

    
336
void OPPROTO op_store_asr (void)
337
{
338
    ppc_store_asr(env, T0);
339
    RETURN();
340
}
341
#endif
342

    
343
void OPPROTO op_load_msr (void)
344
{
345
    T0 = env->msr;
346
    RETURN();
347
}
348

    
349
void OPPROTO op_store_msr (void)
350
{
351
    do_store_msr();
352
    RETURN();
353
}
354

    
355
#if defined (TARGET_PPC64)
356
void OPPROTO op_store_msr_32 (void)
357
{
358
    T0 = (env->msr & ~0xFFFFFFFFULL) | (T0 & 0xFFFFFFFF);
359
    do_store_msr();
360
    RETURN();
361
}
362
#endif
363

    
364
void OPPROTO op_update_riee (void)
365
{
366
    /* We don't call do_store_msr here as we won't trigger
367
     * any special case nor change hflags
368
     */
369
    T0 &= (1 << MSR_RI) | (1 << MSR_EE);
370
    env->msr &= ~(1 << MSR_RI) | (1 << MSR_EE);
371
    env->msr |= T0;
372
    RETURN();
373
}
374
#endif
375

    
376
/* SPR */
377
void OPPROTO op_load_spr (void)
378
{
379
    T0 = env->spr[PARAM1];
380
    RETURN();
381
}
382

    
383
void OPPROTO op_store_spr (void)
384
{
385
    env->spr[PARAM1] = T0;
386
    RETURN();
387
}
388

    
389
void OPPROTO op_load_dump_spr (void)
390
{
391
    T0 = ppc_load_dump_spr(PARAM1);
392
    RETURN();
393
}
394

    
395
void OPPROTO op_store_dump_spr (void)
396
{
397
    ppc_store_dump_spr(PARAM1, T0);
398
    RETURN();
399
}
400

    
401
void OPPROTO op_mask_spr (void)
402
{
403
    env->spr[PARAM1] &= ~T0;
404
    RETURN();
405
}
406

    
407
void OPPROTO op_load_lr (void)
408
{
409
    T0 = env->lr;
410
    RETURN();
411
}
412

    
413
void OPPROTO op_store_lr (void)
414
{
415
    env->lr = T0;
416
    RETURN();
417
}
418

    
419
void OPPROTO op_load_ctr (void)
420
{
421
    T0 = env->ctr;
422
    RETURN();
423
}
424

    
425
void OPPROTO op_store_ctr (void)
426
{
427
    env->ctr = T0;
428
    RETURN();
429
}
430

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

    
437
void OPPROTO op_load_tbu (void)
438
{
439
    T0 = cpu_ppc_load_tbu(env);
440
    RETURN();
441
}
442

    
443
void OPPROTO op_load_atbl (void)
444
{
445
    T0 = cpu_ppc_load_atbl(env);
446
    RETURN();
447
}
448

    
449
void OPPROTO op_load_atbu (void)
450
{
451
    T0 = cpu_ppc_load_atbu(env);
452
    RETURN();
453
}
454

    
455
#if !defined(CONFIG_USER_ONLY)
456
void OPPROTO op_store_tbl (void)
457
{
458
    cpu_ppc_store_tbl(env, T0);
459
    RETURN();
460
}
461

    
462
void OPPROTO op_store_tbu (void)
463
{
464
    cpu_ppc_store_tbu(env, T0);
465
    RETURN();
466
}
467

    
468
void OPPROTO op_store_atbl (void)
469
{
470
    cpu_ppc_store_atbl(env, T0);
471
    RETURN();
472
}
473

    
474
void OPPROTO op_store_atbu (void)
475
{
476
    cpu_ppc_store_atbu(env, T0);
477
    RETURN();
478
}
479

    
480
void OPPROTO op_load_decr (void)
481
{
482
    T0 = cpu_ppc_load_decr(env);
483
    RETURN();
484
}
485

    
486
void OPPROTO op_store_decr (void)
487
{
488
    cpu_ppc_store_decr(env, T0);
489
    RETURN();
490
}
491

    
492
void OPPROTO op_load_ibat (void)
493
{
494
    T0 = env->IBAT[PARAM1][PARAM2];
495
    RETURN();
496
}
497

    
498
void OPPROTO op_store_ibatu (void)
499
{
500
    do_store_ibatu(env, PARAM1, T0);
501
    RETURN();
502
}
503

    
504
void OPPROTO op_store_ibatl (void)
505
{
506
#if 1
507
    env->IBAT[1][PARAM1] = T0;
508
#else
509
    do_store_ibatl(env, PARAM1, T0);
510
#endif
511
    RETURN();
512
}
513

    
514
void OPPROTO op_load_dbat (void)
515
{
516
    T0 = env->DBAT[PARAM1][PARAM2];
517
    RETURN();
518
}
519

    
520
void OPPROTO op_store_dbatu (void)
521
{
522
    do_store_dbatu(env, PARAM1, T0);
523
    RETURN();
524
}
525

    
526
void OPPROTO op_store_dbatl (void)
527
{
528
#if 1
529
    env->DBAT[1][PARAM1] = T0;
530
#else
531
    do_store_dbatl(env, PARAM1, T0);
532
#endif
533
    RETURN();
534
}
535
#endif /* !defined(CONFIG_USER_ONLY) */
536

    
537
/* FPSCR */
538
#ifdef CONFIG_SOFTFLOAT
539
void OPPROTO op_reset_fpstatus (void)
540
{
541
    env->fp_status.float_exception_flags = 0;
542
    RETURN();
543
}
544
#endif
545

    
546
void OPPROTO op_compute_fprf (void)
547
{
548
    do_compute_fprf(PARAM1);
549
    RETURN();
550
}
551

    
552
#ifdef CONFIG_SOFTFLOAT
553
void OPPROTO op_float_check_status (void)
554
{
555
    do_float_check_status();
556
    RETURN();
557
}
558
#else
559
void OPPROTO op_float_check_status (void)
560
{
561
    if (env->exception_index == POWERPC_EXCP_PROGRAM &&
562
        (env->error_code & POWERPC_EXCP_FP)) {
563
        /* Differred floating-point exception after target FPR update */
564
        if (msr_fe0 != 0 || msr_fe1 != 0)
565
            do_raise_exception_err(env->exception_index, env->error_code);
566
    }
567
    RETURN();
568
}
569
#endif
570

    
571
void OPPROTO op_load_fpscr_FT0 (void)
572
{
573
    /* The 32 MSB of the target fpr are undefined.
574
     * They'll be zero...
575
     */
576
    CPU_DoubleU u;
577

    
578
    u.l.upper = 0;
579
    u.l.lower = env->fpscr;
580
    FT0 = u.d;
581
    RETURN();
582
}
583

    
584
void OPPROTO op_set_FT0 (void)
585
{
586
    CPU_DoubleU u;
587

    
588
    u.l.upper = 0;
589
    u.l.lower = PARAM1;
590
    FT0 = u.d;
591
    RETURN();
592
}
593

    
594
void OPPROTO op_load_fpscr_T0 (void)
595
{
596
    T0 = (env->fpscr >> PARAM1) & 0xF;
597
    RETURN();
598
}
599

    
600
void OPPROTO op_load_fpcc (void)
601
{
602
    T0 = fpscr_fpcc;
603
    RETURN();
604
}
605

    
606
void OPPROTO op_fpscr_resetbit (void)
607
{
608
    env->fpscr &= PARAM1;
609
    RETURN();
610
}
611

    
612
void OPPROTO op_fpscr_setbit (void)
613
{
614
    do_fpscr_setbit(PARAM1);
615
    RETURN();
616
}
617

    
618
void OPPROTO op_store_fpscr (void)
619
{
620
    do_store_fpscr(PARAM1);
621
    RETURN();
622
}
623

    
624
/* Branch */
625
#define EIP env->nip
626

    
627
void OPPROTO op_setlr (void)
628
{
629
    env->lr = (uint32_t)PARAM1;
630
    RETURN();
631
}
632

    
633
#if defined (TARGET_PPC64)
634
void OPPROTO op_setlr_64 (void)
635
{
636
    env->lr = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
637
    RETURN();
638
}
639
#endif
640

    
641
void OPPROTO op_b_T1 (void)
642
{
643
    env->nip = (uint32_t)(T1 & ~3);
644
    RETURN();
645
}
646

    
647
#if defined (TARGET_PPC64)
648
void OPPROTO op_b_T1_64 (void)
649
{
650
    env->nip = (uint64_t)(T1 & ~3);
651
    RETURN();
652
}
653
#endif
654

    
655
void OPPROTO op_jz_T0 (void)
656
{
657
    if (!T0)
658
        GOTO_LABEL_PARAM(1);
659
    RETURN();
660
}
661

    
662
void OPPROTO op_btest_T1 (void)
663
{
664
    if (T0) {
665
        env->nip = (uint32_t)(T1 & ~3);
666
    } else {
667
        env->nip = (uint32_t)PARAM1;
668
    }
669
    RETURN();
670
}
671

    
672
#if defined (TARGET_PPC64)
673
void OPPROTO op_btest_T1_64 (void)
674
{
675
    if (T0) {
676
        env->nip = (uint64_t)(T1 & ~3);
677
    } else {
678
        env->nip = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
679
    }
680
    RETURN();
681
}
682
#endif
683

    
684
void OPPROTO op_movl_T1_ctr (void)
685
{
686
    T1 = env->ctr;
687
    RETURN();
688
}
689

    
690
void OPPROTO op_movl_T1_lr (void)
691
{
692
    T1 = env->lr;
693
    RETURN();
694
}
695

    
696
/* tests with result in T0 */
697
void OPPROTO op_test_ctr (void)
698
{
699
    T0 = (uint32_t)env->ctr;
700
    RETURN();
701
}
702

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

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

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

    
725
void OPPROTO op_test_ctr_false (void)
726
{
727
    T0 = ((uint32_t)env->ctr != 0 && (T0 & PARAM1) == 0);
728
    RETURN();
729
}
730

    
731
#if defined(TARGET_PPC64)
732
void OPPROTO op_test_ctr_false_64 (void)
733
{
734
    T0 = ((uint64_t)env->ctr != 0 && (T0 & PARAM1) == 0);
735
    RETURN();
736
}
737
#endif
738

    
739
void OPPROTO op_test_ctrz (void)
740
{
741
    T0 = ((uint32_t)env->ctr == 0);
742
    RETURN();
743
}
744

    
745
#if defined(TARGET_PPC64)
746
void OPPROTO op_test_ctrz_64 (void)
747
{
748
    T0 = ((uint64_t)env->ctr == 0);
749
    RETURN();
750
}
751
#endif
752

    
753
void OPPROTO op_test_ctrz_true (void)
754
{
755
    T0 = ((uint32_t)env->ctr == 0 && (T0 & PARAM1) != 0);
756
    RETURN();
757
}
758

    
759
#if defined(TARGET_PPC64)
760
void OPPROTO op_test_ctrz_true_64 (void)
761
{
762
    T0 = ((uint64_t)env->ctr == 0 && (T0 & PARAM1) != 0);
763
    RETURN();
764
}
765
#endif
766

    
767
void OPPROTO op_test_ctrz_false (void)
768
{
769
    T0 = ((uint32_t)env->ctr == 0 && (T0 & PARAM1) == 0);
770
    RETURN();
771
}
772

    
773
#if defined(TARGET_PPC64)
774
void OPPROTO op_test_ctrz_false_64 (void)
775
{
776
    T0 = ((uint64_t)env->ctr == 0 && (T0 & PARAM1) == 0);
777
    RETURN();
778
}
779
#endif
780

    
781
void OPPROTO op_test_true (void)
782
{
783
    T0 = (T0 & PARAM1);
784
    RETURN();
785
}
786

    
787
void OPPROTO op_test_false (void)
788
{
789
    T0 = ((T0 & PARAM1) == 0);
790
    RETURN();
791
}
792

    
793
/* CTR maintenance */
794
void OPPROTO op_dec_ctr (void)
795
{
796
    env->ctr--;
797
    RETURN();
798
}
799

    
800
/***                           Integer arithmetic                          ***/
801
/* add */
802
void OPPROTO op_add (void)
803
{
804
    T0 += T1;
805
    RETURN();
806
}
807

    
808
void OPPROTO op_check_addo (void)
809
{
810
    xer_ov = (((uint32_t)T2 ^ (uint32_t)T1 ^ UINT32_MAX) &
811
              ((uint32_t)T2 ^ (uint32_t)T0)) >> 31;
812
    xer_so |= xer_ov;
813
    RETURN();
814
}
815

    
816
#if defined(TARGET_PPC64)
817
void OPPROTO op_check_addo_64 (void)
818
{
819
    xer_ov = (((uint64_t)T2 ^ (uint64_t)T1 ^ UINT64_MAX) &
820
              ((uint64_t)T2 ^ (uint64_t)T0)) >> 63;
821
    xer_so |= xer_ov;
822
    RETURN();
823
}
824
#endif
825

    
826
/* add carrying */
827
void OPPROTO op_check_addc (void)
828
{
829
    if (likely((uint32_t)T0 >= (uint32_t)T2)) {
830
        xer_ca = 0;
831
    } else {
832
        xer_ca = 1;
833
    }
834
    RETURN();
835
}
836

    
837
#if defined(TARGET_PPC64)
838
void OPPROTO op_check_addc_64 (void)
839
{
840
    if (likely((uint64_t)T0 >= (uint64_t)T2)) {
841
        xer_ca = 0;
842
    } else {
843
        xer_ca = 1;
844
    }
845
    RETURN();
846
}
847
#endif
848

    
849
/* add extended */
850
void OPPROTO op_adde (void)
851
{
852
    do_adde();
853
    RETURN();
854
}
855

    
856
#if defined(TARGET_PPC64)
857
void OPPROTO op_adde_64 (void)
858
{
859
    do_adde_64();
860
    RETURN();
861
}
862
#endif
863

    
864
/* add immediate */
865
void OPPROTO op_addi (void)
866
{
867
    T0 += (int32_t)PARAM1;
868
    RETURN();
869
}
870

    
871
/* add to minus one extended */
872
void OPPROTO op_add_me (void)
873
{
874
    T0 += xer_ca + (-1);
875
    if (likely((uint32_t)T1 != 0))
876
        xer_ca = 1;
877
    else
878
        xer_ca = 0;
879
    RETURN();
880
}
881

    
882
#if defined(TARGET_PPC64)
883
void OPPROTO op_add_me_64 (void)
884
{
885
    T0 += xer_ca + (-1);
886
    if (likely((uint64_t)T1 != 0))
887
        xer_ca = 1;
888
    else
889
        xer_ca = 0;
890
    RETURN();
891
}
892
#endif
893

    
894
void OPPROTO op_addmeo (void)
895
{
896
    do_addmeo();
897
    RETURN();
898
}
899

    
900
void OPPROTO op_addmeo_64 (void)
901
{
902
    do_addmeo();
903
    RETURN();
904
}
905

    
906
/* add to zero extended */
907
void OPPROTO op_add_ze (void)
908
{
909
    T0 += xer_ca;
910
    RETURN();
911
}
912

    
913
/* divide word */
914
void OPPROTO op_divw (void)
915
{
916
    if (unlikely(((int32_t)T0 == INT32_MIN && (int32_t)T1 == (int32_t)-1) ||
917
                 (int32_t)T1 == 0)) {
918
        T0 = (int32_t)(UINT32_MAX * ((uint32_t)T0 >> 31));
919
    } else {
920
        T0 = (int32_t)T0 / (int32_t)T1;
921
    }
922
    RETURN();
923
}
924

    
925
#if defined(TARGET_PPC64)
926
void OPPROTO op_divd (void)
927
{
928
    if (unlikely(((int64_t)T0 == INT64_MIN && (int64_t)T1 == (int64_t)-1LL) ||
929
                 (int64_t)T1 == 0)) {
930
        T0 = (int64_t)(UINT64_MAX * ((uint64_t)T0 >> 63));
931
    } else {
932
        T0 = (int64_t)T0 / (int64_t)T1;
933
    }
934
    RETURN();
935
}
936
#endif
937

    
938
void OPPROTO op_divwo (void)
939
{
940
    do_divwo();
941
    RETURN();
942
}
943

    
944
#if defined(TARGET_PPC64)
945
void OPPROTO op_divdo (void)
946
{
947
    do_divdo();
948
    RETURN();
949
}
950
#endif
951

    
952
/* divide word unsigned */
953
void OPPROTO op_divwu (void)
954
{
955
    if (unlikely(T1 == 0)) {
956
        T0 = 0;
957
    } else {
958
        T0 = (uint32_t)T0 / (uint32_t)T1;
959
    }
960
    RETURN();
961
}
962

    
963
#if defined(TARGET_PPC64)
964
void OPPROTO op_divdu (void)
965
{
966
    if (unlikely(T1 == 0)) {
967
        T0 = 0;
968
    } else {
969
        T0 /= T1;
970
    }
971
    RETURN();
972
}
973
#endif
974

    
975
void OPPROTO op_divwuo (void)
976
{
977
    do_divwuo();
978
    RETURN();
979
}
980

    
981
#if defined(TARGET_PPC64)
982
void OPPROTO op_divduo (void)
983
{
984
    do_divduo();
985
    RETURN();
986
}
987
#endif
988

    
989
/* multiply high word */
990
void OPPROTO op_mulhw (void)
991
{
992
    T0 = ((int64_t)((int32_t)T0) * (int64_t)((int32_t)T1)) >> 32;
993
    RETURN();
994
}
995

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

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

    
1007
/* multiply high word unsigned */
1008
void OPPROTO op_mulhwu (void)
1009
{
1010
    T0 = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1) >> 32;
1011
    RETURN();
1012
}
1013

    
1014
#if defined(TARGET_PPC64)
1015
void OPPROTO op_mulhdu (void)
1016
{
1017
    uint64_t tl, th;
1018

    
1019
    mulu64(&tl, &th, T0, T1);
1020
    T0 = th;
1021
    RETURN();
1022
}
1023
#endif
1024

    
1025
/* multiply low immediate */
1026
void OPPROTO op_mulli (void)
1027
{
1028
    T0 = ((int32_t)T0 * (int32_t)PARAM1);
1029
    RETURN();
1030
}
1031

    
1032
/* multiply low word */
1033
void OPPROTO op_mullw (void)
1034
{
1035
    T0 = (int32_t)(T0 * T1);
1036
    RETURN();
1037
}
1038

    
1039
#if defined(TARGET_PPC64)
1040
void OPPROTO op_mulld (void)
1041
{
1042
    T0 *= T1;
1043
    RETURN();
1044
}
1045
#endif
1046

    
1047
void OPPROTO op_mullwo (void)
1048
{
1049
    do_mullwo();
1050
    RETURN();
1051
}
1052

    
1053
#if defined(TARGET_PPC64)
1054
void OPPROTO op_mulldo (void)
1055
{
1056
    do_mulldo();
1057
    RETURN();
1058
}
1059
#endif
1060

    
1061
/* negate */
1062
void OPPROTO op_neg (void)
1063
{
1064
    if (likely(T0 != INT32_MIN)) {
1065
        T0 = -(int32_t)T0;
1066
    }
1067
    RETURN();
1068
}
1069

    
1070
#if defined(TARGET_PPC64)
1071
void OPPROTO op_neg_64 (void)
1072
{
1073
    if (likely(T0 != INT64_MIN)) {
1074
        T0 = -(int64_t)T0;
1075
    }
1076
    RETURN();
1077
}
1078
#endif
1079

    
1080
void OPPROTO op_nego (void)
1081
{
1082
    do_nego();
1083
    RETURN();
1084
}
1085

    
1086
#if defined(TARGET_PPC64)
1087
void OPPROTO op_nego_64 (void)
1088
{
1089
    do_nego_64();
1090
    RETURN();
1091
}
1092
#endif
1093

    
1094
/* subtract from */
1095
void OPPROTO op_subf (void)
1096
{
1097
    T0 = T1 - T0;
1098
    RETURN();
1099
}
1100

    
1101
/* subtract from carrying */
1102
void OPPROTO op_check_subfc (void)
1103
{
1104
    if (likely((uint32_t)T0 > (uint32_t)T1)) {
1105
        xer_ca = 0;
1106
    } else {
1107
        xer_ca = 1;
1108
    }
1109
    RETURN();
1110
}
1111

    
1112
#if defined(TARGET_PPC64)
1113
void OPPROTO op_check_subfc_64 (void)
1114
{
1115
    if (likely((uint64_t)T0 > (uint64_t)T1)) {
1116
        xer_ca = 0;
1117
    } else {
1118
        xer_ca = 1;
1119
    }
1120
    RETURN();
1121
}
1122
#endif
1123

    
1124
/* subtract from extended */
1125
void OPPROTO op_subfe (void)
1126
{
1127
    do_subfe();
1128
    RETURN();
1129
}
1130

    
1131
#if defined(TARGET_PPC64)
1132
void OPPROTO op_subfe_64 (void)
1133
{
1134
    do_subfe_64();
1135
    RETURN();
1136
}
1137
#endif
1138

    
1139
/* subtract from immediate carrying */
1140
void OPPROTO op_subfic (void)
1141
{
1142
    T0 = (int32_t)PARAM1 + ~T0 + 1;
1143
    if ((uint32_t)T0 <= (uint32_t)PARAM1) {
1144
        xer_ca = 1;
1145
    } else {
1146
        xer_ca = 0;
1147
    }
1148
    RETURN();
1149
}
1150

    
1151
#if defined(TARGET_PPC64)
1152
void OPPROTO op_subfic_64 (void)
1153
{
1154
    T0 = (int64_t)PARAM1 + ~T0 + 1;
1155
    if ((uint64_t)T0 <= (uint64_t)PARAM1) {
1156
        xer_ca = 1;
1157
    } else {
1158
        xer_ca = 0;
1159
    }
1160
    RETURN();
1161
}
1162
#endif
1163

    
1164
/* subtract from minus one extended */
1165
void OPPROTO op_subfme (void)
1166
{
1167
    T0 = ~T0 + xer_ca - 1;
1168
    if (likely((uint32_t)T0 != UINT32_MAX))
1169
        xer_ca = 1;
1170
    else
1171
        xer_ca = 0;
1172
    RETURN();
1173
}
1174

    
1175
#if defined(TARGET_PPC64)
1176
void OPPROTO op_subfme_64 (void)
1177
{
1178
    T0 = ~T0 + xer_ca - 1;
1179
    if (likely((uint64_t)T0 != UINT64_MAX))
1180
        xer_ca = 1;
1181
    else
1182
        xer_ca = 0;
1183
    RETURN();
1184
}
1185
#endif
1186

    
1187
void OPPROTO op_subfmeo (void)
1188
{
1189
    do_subfmeo();
1190
    RETURN();
1191
}
1192

    
1193
#if defined(TARGET_PPC64)
1194
void OPPROTO op_subfmeo_64 (void)
1195
{
1196
    do_subfmeo_64();
1197
    RETURN();
1198
}
1199
#endif
1200

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

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

    
1228
void OPPROTO op_subfzeo (void)
1229
{
1230
    do_subfzeo();
1231
    RETURN();
1232
}
1233

    
1234
#if defined(TARGET_PPC64)
1235
void OPPROTO op_subfzeo_64 (void)
1236
{
1237
    do_subfzeo_64();
1238
    RETURN();
1239
}
1240
#endif
1241

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

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

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

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

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

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

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

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

    
1359
void OPPROTO op_isel (void)
1360
{
1361
    if (T0)
1362
        T0 = T1;
1363
    else
1364
        T0 = T2;
1365
    RETURN();
1366
}
1367

    
1368
void OPPROTO op_popcntb (void)
1369
{
1370
    do_popcntb();
1371
    RETURN();
1372
}
1373

    
1374
#if defined(TARGET_PPC64)
1375
void OPPROTO op_popcntb_64 (void)
1376
{
1377
    do_popcntb_64();
1378
    RETURN();
1379
}
1380
#endif
1381

    
1382
/***                            Integer logical                            ***/
1383
/* and */
1384
void OPPROTO op_and (void)
1385
{
1386
    T0 &= T1;
1387
    RETURN();
1388
}
1389

    
1390
/* andc */
1391
void OPPROTO op_andc (void)
1392
{
1393
    T0 &= ~T1;
1394
    RETURN();
1395
}
1396

    
1397
/* andi. */
1398
void OPPROTO op_andi_T0 (void)
1399
{
1400
    T0 &= (uint32_t)PARAM1;
1401
    RETURN();
1402
}
1403

    
1404
void OPPROTO op_andi_T1 (void)
1405
{
1406
    T1 &= (uint32_t)PARAM1;
1407
    RETURN();
1408
}
1409

    
1410
#if defined(TARGET_PPC64)
1411
void OPPROTO op_andi_T0_64 (void)
1412
{
1413
    T0 &= ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
1414
    RETURN();
1415
}
1416

    
1417
void OPPROTO op_andi_T1_64 (void)
1418
{
1419
    T1 &= ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
1420
    RETURN();
1421
}
1422
#endif
1423

    
1424
/* count leading zero */
1425
void OPPROTO op_cntlzw (void)
1426
{
1427
    do_cntlzw();
1428
    RETURN();
1429
}
1430

    
1431
#if defined(TARGET_PPC64)
1432
void OPPROTO op_cntlzd (void)
1433
{
1434
    do_cntlzd();
1435
    RETURN();
1436
}
1437
#endif
1438

    
1439
/* eqv */
1440
void OPPROTO op_eqv (void)
1441
{
1442
    T0 = ~(T0 ^ T1);
1443
    RETURN();
1444
}
1445

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

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

    
1468
#if defined (TARGET_PPC64)
1469
void OPPROTO op_extsw (void)
1470
{
1471
    T0 = (int64_t)((int32_t)T0);
1472
    RETURN();
1473
}
1474
#endif
1475

    
1476
/* nand */
1477
void OPPROTO op_nand (void)
1478
{
1479
    T0 = ~(T0 & T1);
1480
    RETURN();
1481
}
1482

    
1483
/* nor */
1484
void OPPROTO op_nor (void)
1485
{
1486
    T0 = ~(T0 | T1);
1487
    RETURN();
1488
}
1489

    
1490
/* or */
1491
void OPPROTO op_or (void)
1492
{
1493
    T0 |= T1;
1494
    RETURN();
1495
}
1496

    
1497
/* orc */
1498
void OPPROTO op_orc (void)
1499
{
1500
    T0 |= ~T1;
1501
    RETURN();
1502
}
1503

    
1504
/* ori */
1505
void OPPROTO op_ori (void)
1506
{
1507
    T0 |= (uint32_t)PARAM1;
1508
    RETURN();
1509
}
1510

    
1511
/* xor */
1512
void OPPROTO op_xor (void)
1513
{
1514
    T0 ^= T1;
1515
    RETURN();
1516
}
1517

    
1518
/* xori */
1519
void OPPROTO op_xori (void)
1520
{
1521
    T0 ^= (uint32_t)PARAM1;
1522
    RETURN();
1523
}
1524

    
1525
/***                             Integer rotate                            ***/
1526
void OPPROTO op_rotl32_T0_T1 (void)
1527
{
1528
    T0 = rotl32(T0, T1 & 0x1F);
1529
    RETURN();
1530
}
1531

    
1532
void OPPROTO op_rotli32_T0 (void)
1533
{
1534
    T0 = rotl32(T0, PARAM1);
1535
    RETURN();
1536
}
1537

    
1538
#if defined(TARGET_PPC64)
1539
void OPPROTO op_rotl64_T0_T1 (void)
1540
{
1541
    T0 = rotl64(T0, T1 & 0x3F);
1542
    RETURN();
1543
}
1544

    
1545
void OPPROTO op_rotli64_T0 (void)
1546
{
1547
    T0 = rotl64(T0, PARAM1);
1548
    RETURN();
1549
}
1550
#endif
1551

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

    
1564
#if defined(TARGET_PPC64)
1565
void OPPROTO op_sld (void)
1566
{
1567
    if (T1 & 0x40) {
1568
        T0 = 0;
1569
    } else {
1570
        T0 = T0 << T1;
1571
    }
1572
    RETURN();
1573
}
1574
#endif
1575

    
1576
/* shift right algebraic word */
1577
void OPPROTO op_sraw (void)
1578
{
1579
    do_sraw();
1580
    RETURN();
1581
}
1582

    
1583
#if defined(TARGET_PPC64)
1584
void OPPROTO op_srad (void)
1585
{
1586
    do_srad();
1587
    RETURN();
1588
}
1589
#endif
1590

    
1591
/* shift right algebraic word immediate */
1592
void OPPROTO op_srawi (void)
1593
{
1594
    uint32_t mask = (uint32_t)PARAM2;
1595

    
1596
    T0 = (int32_t)T0 >> PARAM1;
1597
    if ((int32_t)T1 < 0 && (T1 & mask) != 0) {
1598
        xer_ca = 1;
1599
    } else {
1600
        xer_ca = 0;
1601
    }
1602
    RETURN();
1603
}
1604

    
1605
#if defined(TARGET_PPC64)
1606
void OPPROTO op_sradi (void)
1607
{
1608
    uint64_t mask = ((uint64_t)PARAM2 << 32) | (uint64_t)PARAM3;
1609

    
1610
    T0 = (int64_t)T0 >> PARAM1;
1611
    if ((int64_t)T1 < 0 && ((uint64_t)T1 & mask) != 0) {
1612
        xer_ca = 1;
1613
    } else {
1614
        xer_ca = 0;
1615
    }
1616
    RETURN();
1617
}
1618
#endif
1619

    
1620
/* shift right word */
1621
void OPPROTO op_srw (void)
1622
{
1623
    if (T1 & 0x20) {
1624
        T0 = 0;
1625
    } else {
1626
        T0 = (uint32_t)T0 >> T1;
1627
    }
1628
    RETURN();
1629
}
1630

    
1631
#if defined(TARGET_PPC64)
1632
void OPPROTO op_srd (void)
1633
{
1634
    if (T1 & 0x40) {
1635
        T0 = 0;
1636
    } else {
1637
        T0 = (uint64_t)T0 >> T1;
1638
    }
1639
    RETURN();
1640
}
1641
#endif
1642

    
1643
void OPPROTO op_sl_T0_T1 (void)
1644
{
1645
    T0 = T0 << T1;
1646
    RETURN();
1647
}
1648

    
1649
void OPPROTO op_sli_T0 (void)
1650
{
1651
    T0 = T0 << PARAM1;
1652
    RETURN();
1653
}
1654

    
1655
void OPPROTO op_sli_T1 (void)
1656
{
1657
    T1 = T1 << PARAM1;
1658
    RETURN();
1659
}
1660

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

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

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

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

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

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

    
1703
/***                       Floating-Point arithmetic                       ***/
1704
/* fadd - fadd. */
1705
void OPPROTO op_fadd (void)
1706
{
1707
#if USE_PRECISE_EMULATION
1708
    do_fadd();
1709
#else
1710
    FT0 = float64_add(FT0, FT1, &env->fp_status);
1711
#endif
1712
    RETURN();
1713
}
1714

    
1715
/* fsub - fsub. */
1716
void OPPROTO op_fsub (void)
1717
{
1718
#if USE_PRECISE_EMULATION
1719
    do_fsub();
1720
#else
1721
    FT0 = float64_sub(FT0, FT1, &env->fp_status);
1722
#endif
1723
    RETURN();
1724
}
1725

    
1726
/* fmul - fmul. */
1727
void OPPROTO op_fmul (void)
1728
{
1729
#if USE_PRECISE_EMULATION
1730
    do_fmul();
1731
#else
1732
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1733
#endif
1734
    RETURN();
1735
}
1736

    
1737
/* fdiv - fdiv. */
1738
void OPPROTO op_fdiv (void)
1739
{
1740
#if USE_PRECISE_EMULATION
1741
    do_fdiv();
1742
#else
1743
    FT0 = float64_div(FT0, FT1, &env->fp_status);
1744
#endif
1745
    RETURN();
1746
}
1747

    
1748
/* fsqrt - fsqrt. */
1749
void OPPROTO op_fsqrt (void)
1750
{
1751
    do_fsqrt();
1752
    RETURN();
1753
}
1754

    
1755
/* fre - fre. */
1756
void OPPROTO op_fre (void)
1757
{
1758
    do_fre();
1759
    RETURN();
1760
}
1761

    
1762
/* fres - fres. */
1763
void OPPROTO op_fres (void)
1764
{
1765
    do_fres();
1766
    RETURN();
1767
}
1768

    
1769
/* frsqrte  - frsqrte. */
1770
void OPPROTO op_frsqrte (void)
1771
{
1772
    do_frsqrte();
1773
    RETURN();
1774
}
1775

    
1776
/* fsel - fsel. */
1777
void OPPROTO op_fsel (void)
1778
{
1779
    do_fsel();
1780
    RETURN();
1781
}
1782

    
1783
/***                     Floating-Point multiply-and-add                   ***/
1784
/* fmadd - fmadd. */
1785
void OPPROTO op_fmadd (void)
1786
{
1787
#if USE_PRECISE_EMULATION
1788
    do_fmadd();
1789
#else
1790
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1791
    FT0 = float64_add(FT0, FT2, &env->fp_status);
1792
#endif
1793
    RETURN();
1794
}
1795

    
1796
/* fmsub - fmsub. */
1797
void OPPROTO op_fmsub (void)
1798
{
1799
#if USE_PRECISE_EMULATION
1800
    do_fmsub();
1801
#else
1802
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1803
    FT0 = float64_sub(FT0, FT2, &env->fp_status);
1804
#endif
1805
    RETURN();
1806
}
1807

    
1808
/* fnmadd - fnmadd. - fnmadds - fnmadds. */
1809
void OPPROTO op_fnmadd (void)
1810
{
1811
    do_fnmadd();
1812
    RETURN();
1813
}
1814

    
1815
/* fnmsub - fnmsub. */
1816
void OPPROTO op_fnmsub (void)
1817
{
1818
    do_fnmsub();
1819
    RETURN();
1820
}
1821

    
1822
/***                     Floating-Point round & convert                    ***/
1823
/* frsp - frsp. */
1824
void OPPROTO op_frsp (void)
1825
{
1826
#if USE_PRECISE_EMULATION
1827
    do_frsp();
1828
#else
1829
    FT0 = float64_to_float32(FT0, &env->fp_status);
1830
#endif
1831
    RETURN();
1832
}
1833

    
1834
/* fctiw - fctiw. */
1835
void OPPROTO op_fctiw (void)
1836
{
1837
    do_fctiw();
1838
    RETURN();
1839
}
1840

    
1841
/* fctiwz - fctiwz. */
1842
void OPPROTO op_fctiwz (void)
1843
{
1844
    do_fctiwz();
1845
    RETURN();
1846
}
1847

    
1848
#if defined(TARGET_PPC64)
1849
/* fcfid - fcfid. */
1850
void OPPROTO op_fcfid (void)
1851
{
1852
    do_fcfid();
1853
    RETURN();
1854
}
1855

    
1856
/* fctid - fctid. */
1857
void OPPROTO op_fctid (void)
1858
{
1859
    do_fctid();
1860
    RETURN();
1861
}
1862

    
1863
/* fctidz - fctidz. */
1864
void OPPROTO op_fctidz (void)
1865
{
1866
    do_fctidz();
1867
    RETURN();
1868
}
1869
#endif
1870

    
1871
void OPPROTO op_frin (void)
1872
{
1873
    do_frin();
1874
    RETURN();
1875
}
1876

    
1877
void OPPROTO op_friz (void)
1878
{
1879
    do_friz();
1880
    RETURN();
1881
}
1882

    
1883
void OPPROTO op_frip (void)
1884
{
1885
    do_frip();
1886
    RETURN();
1887
}
1888

    
1889
void OPPROTO op_frim (void)
1890
{
1891
    do_frim();
1892
    RETURN();
1893
}
1894

    
1895
/***                         Floating-Point compare                        ***/
1896
/* fcmpu */
1897
void OPPROTO op_fcmpu (void)
1898
{
1899
    do_fcmpu();
1900
    RETURN();
1901
}
1902

    
1903
/* fcmpo */
1904
void OPPROTO op_fcmpo (void)
1905
{
1906
    do_fcmpo();
1907
    RETURN();
1908
}
1909

    
1910
/***                         Floating-point move                           ***/
1911
/* fabs */
1912
void OPPROTO op_fabs (void)
1913
{
1914
    FT0 = float64_abs(FT0);
1915
    RETURN();
1916
}
1917

    
1918
/* fnabs */
1919
void OPPROTO op_fnabs (void)
1920
{
1921
    FT0 = float64_abs(FT0);
1922
    FT0 = float64_chs(FT0);
1923
    RETURN();
1924
}
1925

    
1926
/* fneg */
1927
void OPPROTO op_fneg (void)
1928
{
1929
    FT0 = float64_chs(FT0);
1930
    RETURN();
1931
}
1932

    
1933
/* Load and store */
1934
#define MEMSUFFIX _raw
1935
#include "op_helper.h"
1936
#include "op_mem.h"
1937
#if !defined(CONFIG_USER_ONLY)
1938
#define MEMSUFFIX _user
1939
#include "op_helper.h"
1940
#include "op_mem.h"
1941
#define MEMSUFFIX _kernel
1942
#include "op_helper.h"
1943
#include "op_mem.h"
1944
#define MEMSUFFIX _hypv
1945
#include "op_helper.h"
1946
#include "op_mem.h"
1947
#endif
1948

    
1949
/* Special op to check and maybe clear reservation */
1950
void OPPROTO op_check_reservation (void)
1951
{
1952
    if ((uint32_t)env->reserve == (uint32_t)(T0 & ~0x00000003))
1953
        env->reserve = (target_ulong)-1ULL;
1954
    RETURN();
1955
}
1956

    
1957
#if defined(TARGET_PPC64)
1958
void OPPROTO op_check_reservation_64 (void)
1959
{
1960
    if ((uint64_t)env->reserve == (uint64_t)(T0 & ~0x00000003))
1961
        env->reserve = (target_ulong)-1ULL;
1962
    RETURN();
1963
}
1964
#endif
1965

    
1966
void OPPROTO op_wait (void)
1967
{
1968
    env->halted = 1;
1969
    RETURN();
1970
}
1971

    
1972
/* Return from interrupt */
1973
#if !defined(CONFIG_USER_ONLY)
1974
void OPPROTO op_rfi (void)
1975
{
1976
    do_rfi();
1977
    RETURN();
1978
}
1979

    
1980
#if defined(TARGET_PPC64)
1981
void OPPROTO op_rfid (void)
1982
{
1983
    do_rfid();
1984
    RETURN();
1985
}
1986

    
1987
void OPPROTO op_hrfid (void)
1988
{
1989
    do_hrfid();
1990
    RETURN();
1991
}
1992
#endif
1993

    
1994
/* Exception vectors */
1995
void OPPROTO op_store_excp_prefix (void)
1996
{
1997
    T0 &= env->ivpr_mask;
1998
    env->excp_prefix = T0;
1999
    RETURN();
2000
}
2001

    
2002
void OPPROTO op_store_excp_vector (void)
2003
{
2004
    T0 &= env->ivor_mask;
2005
    env->excp_vectors[PARAM1] = T0;
2006
    RETURN();
2007
}
2008
#endif
2009

    
2010
/* Trap word */
2011
void OPPROTO op_tw (void)
2012
{
2013
    do_tw(PARAM1);
2014
    RETURN();
2015
}
2016

    
2017
#if defined(TARGET_PPC64)
2018
void OPPROTO op_td (void)
2019
{
2020
    do_td(PARAM1);
2021
    RETURN();
2022
}
2023
#endif
2024

    
2025
#if !defined(CONFIG_USER_ONLY)
2026
/* tlbia */
2027
void OPPROTO op_tlbia (void)
2028
{
2029
    ppc_tlb_invalidate_all(env);
2030
    RETURN();
2031
}
2032

    
2033
/* tlbie */
2034
void OPPROTO op_tlbie (void)
2035
{
2036
    ppc_tlb_invalidate_one(env, (uint32_t)T0);
2037
    RETURN();
2038
}
2039

    
2040
#if defined(TARGET_PPC64)
2041
void OPPROTO op_tlbie_64 (void)
2042
{
2043
    ppc_tlb_invalidate_one(env, T0);
2044
    RETURN();
2045
}
2046
#endif
2047

    
2048
#if defined(TARGET_PPC64)
2049
void OPPROTO op_slbia (void)
2050
{
2051
    ppc_slb_invalidate_all(env);
2052
    RETURN();
2053
}
2054

    
2055
void OPPROTO op_slbie (void)
2056
{
2057
    ppc_slb_invalidate_one(env, (uint32_t)T0);
2058
    RETURN();
2059
}
2060

    
2061
void OPPROTO op_slbie_64 (void)
2062
{
2063
    ppc_slb_invalidate_one(env, T0);
2064
    RETURN();
2065
}
2066
#endif
2067
#endif
2068

    
2069
#if !defined(CONFIG_USER_ONLY)
2070
/* PowerPC 602/603/755 software TLB load instructions */
2071
void OPPROTO op_6xx_tlbld (void)
2072
{
2073
    do_load_6xx_tlb(0);
2074
    RETURN();
2075
}
2076

    
2077
void OPPROTO op_6xx_tlbli (void)
2078
{
2079
    do_load_6xx_tlb(1);
2080
    RETURN();
2081
}
2082

    
2083
/* PowerPC 74xx software TLB load instructions */
2084
void OPPROTO op_74xx_tlbld (void)
2085
{
2086
    do_load_74xx_tlb(0);
2087
    RETURN();
2088
}
2089

    
2090
void OPPROTO op_74xx_tlbli (void)
2091
{
2092
    do_load_74xx_tlb(1);
2093
    RETURN();
2094
}
2095
#endif
2096

    
2097
/* 601 specific */
2098
void OPPROTO op_load_601_rtcl (void)
2099
{
2100
    T0 = cpu_ppc601_load_rtcl(env);
2101
    RETURN();
2102
}
2103

    
2104
void OPPROTO op_load_601_rtcu (void)
2105
{
2106
    T0 = cpu_ppc601_load_rtcu(env);
2107
    RETURN();
2108
}
2109

    
2110
#if !defined(CONFIG_USER_ONLY)
2111
void OPPROTO op_store_601_rtcl (void)
2112
{
2113
    cpu_ppc601_store_rtcl(env, T0);
2114
    RETURN();
2115
}
2116

    
2117
void OPPROTO op_store_601_rtcu (void)
2118
{
2119
    cpu_ppc601_store_rtcu(env, T0);
2120
    RETURN();
2121
}
2122

    
2123
void OPPROTO op_store_hid0_601 (void)
2124
{
2125
    do_store_hid0_601();
2126
    RETURN();
2127
}
2128

    
2129
void OPPROTO op_load_601_bat (void)
2130
{
2131
    T0 = env->IBAT[PARAM1][PARAM2];
2132
    RETURN();
2133
}
2134

    
2135
void OPPROTO op_store_601_batl (void)
2136
{
2137
    do_store_ibatl_601(env, PARAM1, T0);
2138
    RETURN();
2139
}
2140

    
2141
void OPPROTO op_store_601_batu (void)
2142
{
2143
    do_store_ibatu_601(env, PARAM1, T0);
2144
    RETURN();
2145
}
2146
#endif /* !defined(CONFIG_USER_ONLY) */
2147

    
2148
/* PowerPC 601 specific instructions (POWER bridge) */
2149
/* XXX: those micro-ops need tests ! */
2150
void OPPROTO op_POWER_abs (void)
2151
{
2152
    if ((int32_t)T0 == INT32_MIN)
2153
        T0 = INT32_MAX;
2154
    else if ((int32_t)T0 < 0)
2155
        T0 = -T0;
2156
    RETURN();
2157
}
2158

    
2159
void OPPROTO op_POWER_abso (void)
2160
{
2161
    do_POWER_abso();
2162
    RETURN();
2163
}
2164

    
2165
void OPPROTO op_POWER_clcs (void)
2166
{
2167
    do_POWER_clcs();
2168
    RETURN();
2169
}
2170

    
2171
void OPPROTO op_POWER_div (void)
2172
{
2173
    do_POWER_div();
2174
    RETURN();
2175
}
2176

    
2177
void OPPROTO op_POWER_divo (void)
2178
{
2179
    do_POWER_divo();
2180
    RETURN();
2181
}
2182

    
2183
void OPPROTO op_POWER_divs (void)
2184
{
2185
    do_POWER_divs();
2186
    RETURN();
2187
}
2188

    
2189
void OPPROTO op_POWER_divso (void)
2190
{
2191
    do_POWER_divso();
2192
    RETURN();
2193
}
2194

    
2195
void OPPROTO op_POWER_doz (void)
2196
{
2197
    if ((int32_t)T1 > (int32_t)T0)
2198
        T0 = T1 - T0;
2199
    else
2200
        T0 = 0;
2201
    RETURN();
2202
}
2203

    
2204
void OPPROTO op_POWER_dozo (void)
2205
{
2206
    do_POWER_dozo();
2207
    RETURN();
2208
}
2209

    
2210
void OPPROTO op_load_xer_cmp (void)
2211
{
2212
    T2 = xer_cmp;
2213
    RETURN();
2214
}
2215

    
2216
void OPPROTO op_POWER_maskg (void)
2217
{
2218
    do_POWER_maskg();
2219
    RETURN();
2220
}
2221

    
2222
void OPPROTO op_POWER_maskir (void)
2223
{
2224
    T0 = (T0 & ~T2) | (T1 & T2);
2225
    RETURN();
2226
}
2227

    
2228
void OPPROTO op_POWER_mul (void)
2229
{
2230
    uint64_t tmp;
2231

    
2232
    tmp = (uint64_t)T0 * (uint64_t)T1;
2233
    env->spr[SPR_MQ] = tmp >> 32;
2234
    T0 = tmp;
2235
    RETURN();
2236
}
2237

    
2238
void OPPROTO op_POWER_mulo (void)
2239
{
2240
    do_POWER_mulo();
2241
    RETURN();
2242
}
2243

    
2244
void OPPROTO op_POWER_nabs (void)
2245
{
2246
    if (T0 > 0)
2247
        T0 = -T0;
2248
    RETURN();
2249
}
2250

    
2251
void OPPROTO op_POWER_nabso (void)
2252
{
2253
    /* nabs never overflows */
2254
    if (T0 > 0)
2255
        T0 = -T0;
2256
    xer_ov = 0;
2257
    RETURN();
2258
}
2259

    
2260
/* XXX: factorise POWER rotates... */
2261
void OPPROTO op_POWER_rlmi (void)
2262
{
2263
    T0 = rotl32(T0, T2) & PARAM1;
2264
    T0 |= T1 & (uint32_t)PARAM2;
2265
    RETURN();
2266
}
2267

    
2268
void OPPROTO op_POWER_rrib (void)
2269
{
2270
    T2 &= 0x1FUL;
2271
    T0 = rotl32(T0 & INT32_MIN, T2);
2272
    T0 |= T1 & ~rotl32(INT32_MIN, T2);
2273
    RETURN();
2274
}
2275

    
2276
void OPPROTO op_POWER_sle (void)
2277
{
2278
    T1 &= 0x1FUL;
2279
    env->spr[SPR_MQ] = rotl32(T0, T1);
2280
    T0 = T0 << T1;
2281
    RETURN();
2282
}
2283

    
2284
void OPPROTO op_POWER_sleq (void)
2285
{
2286
    uint32_t tmp = env->spr[SPR_MQ];
2287

    
2288
    T1 &= 0x1FUL;
2289
    env->spr[SPR_MQ] = rotl32(T0, T1);
2290
    T0 = T0 << T1;
2291
    T0 |= tmp >> (32 - T1);
2292
    RETURN();
2293
}
2294

    
2295
void OPPROTO op_POWER_sllq (void)
2296
{
2297
    uint32_t msk = UINT32_MAX;
2298

    
2299
    msk = msk << (T1 & 0x1FUL);
2300
    if (T1 & 0x20UL)
2301
        msk = ~msk;
2302
    T1 &= 0x1FUL;
2303
    T0 = (T0 << T1) & msk;
2304
    T0 |= env->spr[SPR_MQ] & ~msk;
2305
    RETURN();
2306
}
2307

    
2308
void OPPROTO op_POWER_slq (void)
2309
{
2310
    uint32_t msk = UINT32_MAX, tmp;
2311

    
2312
    msk = msk << (T1 & 0x1FUL);
2313
    if (T1 & 0x20UL)
2314
        msk = ~msk;
2315
    T1 &= 0x1FUL;
2316
    tmp = rotl32(T0, T1);
2317
    T0 = tmp & msk;
2318
    env->spr[SPR_MQ] = tmp;
2319
    RETURN();
2320
}
2321

    
2322
void OPPROTO op_POWER_sraq (void)
2323
{
2324
    env->spr[SPR_MQ] = rotl32(T0, 32 - (T1 & 0x1FUL));
2325
    if (T1 & 0x20UL)
2326
        T0 = UINT32_MAX;
2327
    else
2328
        T0 = (int32_t)T0 >> T1;
2329
    RETURN();
2330
}
2331

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

    
2340
void OPPROTO op_POWER_srea (void)
2341
{
2342
    T1 &= 0x1FUL;
2343
    env->spr[SPR_MQ] = T0 >> T1;
2344
    T0 = (int32_t)T0 >> T1;
2345
    RETURN();
2346
}
2347

    
2348
void OPPROTO op_POWER_sreq (void)
2349
{
2350
    uint32_t tmp;
2351
    int32_t msk;
2352

    
2353
    T1 &= 0x1FUL;
2354
    msk = INT32_MIN >> T1;
2355
    tmp = env->spr[SPR_MQ];
2356
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2357
    T0 = T0 >> T1;
2358
    T0 |= tmp & msk;
2359
    RETURN();
2360
}
2361

    
2362
void OPPROTO op_POWER_srlq (void)
2363
{
2364
    uint32_t tmp;
2365
    int32_t msk;
2366

    
2367
    msk = INT32_MIN >> (T1 & 0x1FUL);
2368
    if (T1 & 0x20UL)
2369
        msk = ~msk;
2370
    T1 &= 0x1FUL;
2371
    tmp = env->spr[SPR_MQ];
2372
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2373
    T0 = T0 >> T1;
2374
    T0 &= msk;
2375
    T0 |= tmp & ~msk;
2376
    RETURN();
2377
}
2378

    
2379
void OPPROTO op_POWER_srq (void)
2380
{
2381
    T1 &= 0x1FUL;
2382
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2383
    T0 = T0 >> T1;
2384
    RETURN();
2385
}
2386

    
2387
/* POWER instructions not implemented in PowerPC 601 */
2388
#if !defined(CONFIG_USER_ONLY)
2389
void OPPROTO op_POWER_mfsri (void)
2390
{
2391
    T1 = T0 >> 28;
2392
    T0 = env->sr[T1];
2393
    RETURN();
2394
}
2395

    
2396
void OPPROTO op_POWER_rac (void)
2397
{
2398
    do_POWER_rac();
2399
    RETURN();
2400
}
2401

    
2402
void OPPROTO op_POWER_rfsvc (void)
2403
{
2404
    do_POWER_rfsvc();
2405
    RETURN();
2406
}
2407
#endif
2408

    
2409
/* PowerPC 602 specific instruction */
2410
#if !defined(CONFIG_USER_ONLY)
2411
void OPPROTO op_602_mfrom (void)
2412
{
2413
    do_op_602_mfrom();
2414
    RETURN();
2415
}
2416
#endif
2417

    
2418
/* PowerPC 4xx specific micro-ops */
2419
void OPPROTO op_405_add_T0_T2 (void)
2420
{
2421
    T0 = (int32_t)T0 + (int32_t)T2;
2422
    RETURN();
2423
}
2424

    
2425
void OPPROTO op_405_mulchw (void)
2426
{
2427
    T0 = ((int16_t)T0) * ((int16_t)(T1 >> 16));
2428
    RETURN();
2429
}
2430

    
2431
void OPPROTO op_405_mulchwu (void)
2432
{
2433
    T0 = ((uint16_t)T0) * ((uint16_t)(T1 >> 16));
2434
    RETURN();
2435
}
2436

    
2437
void OPPROTO op_405_mulhhw (void)
2438
{
2439
    T0 = ((int16_t)(T0 >> 16)) * ((int16_t)(T1 >> 16));
2440
    RETURN();
2441
}
2442

    
2443
void OPPROTO op_405_mulhhwu (void)
2444
{
2445
    T0 = ((uint16_t)(T0 >> 16)) * ((uint16_t)(T1 >> 16));
2446
    RETURN();
2447
}
2448

    
2449
void OPPROTO op_405_mullhw (void)
2450
{
2451
    T0 = ((int16_t)T0) * ((int16_t)T1);
2452
    RETURN();
2453
}
2454

    
2455
void OPPROTO op_405_mullhwu (void)
2456
{
2457
    T0 = ((uint16_t)T0) * ((uint16_t)T1);
2458
    RETURN();
2459
}
2460

    
2461
void OPPROTO op_405_check_sat (void)
2462
{
2463
    do_405_check_sat();
2464
    RETURN();
2465
}
2466

    
2467
void OPPROTO op_405_check_ovu (void)
2468
{
2469
    if (likely(T0 >= T2)) {
2470
        xer_ov = 0;
2471
    } else {
2472
        xer_ov = 1;
2473
        xer_so = 1;
2474
    }
2475
    RETURN();
2476
}
2477

    
2478
void OPPROTO op_405_check_satu (void)
2479
{
2480
    if (unlikely(T0 < T2)) {
2481
        /* Saturate result */
2482
        T0 = UINT32_MAX;
2483
    }
2484
    RETURN();
2485
}
2486

    
2487
void OPPROTO op_load_dcr (void)
2488
{
2489
    do_load_dcr();
2490
    RETURN();
2491
}
2492

    
2493
void OPPROTO op_store_dcr (void)
2494
{
2495
    do_store_dcr();
2496
    RETURN();
2497
}
2498

    
2499
#if !defined(CONFIG_USER_ONLY)
2500
/* Return from critical interrupt :
2501
 * same as rfi, except nip & MSR are loaded from SRR2/3 instead of SRR0/1
2502
 */
2503
void OPPROTO op_40x_rfci (void)
2504
{
2505
    do_40x_rfci();
2506
    RETURN();
2507
}
2508

    
2509
void OPPROTO op_rfci (void)
2510
{
2511
    do_rfci();
2512
    RETURN();
2513
}
2514

    
2515
void OPPROTO op_rfdi (void)
2516
{
2517
    do_rfdi();
2518
    RETURN();
2519
}
2520

    
2521
void OPPROTO op_rfmci (void)
2522
{
2523
    do_rfmci();
2524
    RETURN();
2525
}
2526

    
2527
void OPPROTO op_wrte (void)
2528
{
2529
    /* We don't call do_store_msr here as we won't trigger
2530
     * any special case nor change hflags
2531
     */
2532
    T0 &= 1 << MSR_EE;
2533
    env->msr &= ~(1 << MSR_EE);
2534
    env->msr |= T0;
2535
    RETURN();
2536
}
2537

    
2538
void OPPROTO op_440_tlbre (void)
2539
{
2540
    do_440_tlbre(PARAM1);
2541
    RETURN();
2542
}
2543

    
2544
void OPPROTO op_440_tlbsx (void)
2545
{
2546
    T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_440_MMUCR] & 0xFF);
2547
    RETURN();
2548
}
2549

    
2550
void OPPROTO op_4xx_tlbsx_check (void)
2551
{
2552
    int tmp;
2553

    
2554
    tmp = xer_so;
2555
    if ((int)T0 != -1)
2556
        tmp |= 0x02;
2557
    env->crf[0] = tmp;
2558
    RETURN();
2559
}
2560

    
2561
void OPPROTO op_440_tlbwe (void)
2562
{
2563
    do_440_tlbwe(PARAM1);
2564
    RETURN();
2565
}
2566

    
2567
void OPPROTO op_4xx_tlbre_lo (void)
2568
{
2569
    do_4xx_tlbre_lo();
2570
    RETURN();
2571
}
2572

    
2573
void OPPROTO op_4xx_tlbre_hi (void)
2574
{
2575
    do_4xx_tlbre_hi();
2576
    RETURN();
2577
}
2578

    
2579
void OPPROTO op_4xx_tlbsx (void)
2580
{
2581
    T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_40x_PID]);
2582
    RETURN();
2583
}
2584

    
2585
void OPPROTO op_4xx_tlbwe_lo (void)
2586
{
2587
    do_4xx_tlbwe_lo();
2588
    RETURN();
2589
}
2590

    
2591
void OPPROTO op_4xx_tlbwe_hi (void)
2592
{
2593
    do_4xx_tlbwe_hi();
2594
    RETURN();
2595
}
2596
#endif
2597

    
2598
/* SPR micro-ops */
2599
/* 440 specific */
2600
void OPPROTO op_440_dlmzb (void)
2601
{
2602
    do_440_dlmzb();
2603
    RETURN();
2604
}
2605

    
2606
void OPPROTO op_440_dlmzb_update_Rc (void)
2607
{
2608
    if (T0 == 8)
2609
        T0 = 0x2;
2610
    else if (T0 < 4)
2611
        T0 = 0x4;
2612
    else
2613
        T0 = 0x8;
2614
    RETURN();
2615
}
2616

    
2617
#if !defined(CONFIG_USER_ONLY)
2618
void OPPROTO op_store_pir (void)
2619
{
2620
    env->spr[SPR_PIR] = T0 & 0x0000000FUL;
2621
    RETURN();
2622
}
2623

    
2624
void OPPROTO op_load_403_pb (void)
2625
{
2626
    do_load_403_pb(PARAM1);
2627
    RETURN();
2628
}
2629

    
2630
void OPPROTO op_store_403_pb (void)
2631
{
2632
    do_store_403_pb(PARAM1);
2633
    RETURN();
2634
}
2635

    
2636
void OPPROTO op_load_40x_pit (void)
2637
{
2638
    T0 = load_40x_pit(env);
2639
    RETURN();
2640
}
2641

    
2642
void OPPROTO op_store_40x_pit (void)
2643
{
2644
    store_40x_pit(env, T0);
2645
    RETURN();
2646
}
2647

    
2648
void OPPROTO op_store_40x_dbcr0 (void)
2649
{
2650
    store_40x_dbcr0(env, T0);
2651
    RETURN();
2652
}
2653

    
2654
void OPPROTO op_store_40x_sler (void)
2655
{
2656
    store_40x_sler(env, T0);
2657
    RETURN();
2658
}
2659

    
2660
void OPPROTO op_store_booke_tcr (void)
2661
{
2662
    store_booke_tcr(env, T0);
2663
    RETURN();
2664
}
2665

    
2666
void OPPROTO op_store_booke_tsr (void)
2667
{
2668
    store_booke_tsr(env, T0);
2669
    RETURN();
2670
}
2671
#endif /* !defined(CONFIG_USER_ONLY) */
2672

    
2673
/* SPE extension */
2674
void OPPROTO op_splatw_T1_64 (void)
2675
{
2676
    T1_64 = (T1_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL);
2677
    RETURN();
2678
}
2679

    
2680
void OPPROTO op_splatwi_T0_64 (void)
2681
{
2682
    uint64_t tmp = PARAM1;
2683

    
2684
    T0_64 = (tmp << 32) | tmp;
2685
    RETURN();
2686
}
2687

    
2688
void OPPROTO op_splatwi_T1_64 (void)
2689
{
2690
    uint64_t tmp = PARAM1;
2691

    
2692
    T1_64 = (tmp << 32) | tmp;
2693
    RETURN();
2694
}
2695

    
2696
void OPPROTO op_extsh_T1_64 (void)
2697
{
2698
    T1_64 = (int32_t)((int16_t)T1_64);
2699
    RETURN();
2700
}
2701

    
2702
void OPPROTO op_sli16_T1_64 (void)
2703
{
2704
    T1_64 = T1_64 << 16;
2705
    RETURN();
2706
}
2707

    
2708
void OPPROTO op_sli32_T1_64 (void)
2709
{
2710
    T1_64 = T1_64 << 32;
2711
    RETURN();
2712
}
2713

    
2714
void OPPROTO op_srli32_T1_64 (void)
2715
{
2716
    T1_64 = T1_64 >> 32;
2717
    RETURN();
2718
}
2719

    
2720
void OPPROTO op_evsel (void)
2721
{
2722
    do_evsel();
2723
    RETURN();
2724
}
2725

    
2726
void OPPROTO op_evaddw (void)
2727
{
2728
    do_evaddw();
2729
    RETURN();
2730
}
2731

    
2732
void OPPROTO op_evsubfw (void)
2733
{
2734
    do_evsubfw();
2735
    RETURN();
2736
}
2737

    
2738
void OPPROTO op_evneg (void)
2739
{
2740
    do_evneg();
2741
    RETURN();
2742
}
2743

    
2744
void OPPROTO op_evabs (void)
2745
{
2746
    do_evabs();
2747
    RETURN();
2748
}
2749

    
2750
void OPPROTO op_evextsh (void)
2751
{
2752
    T0_64 = ((uint64_t)((int32_t)(int16_t)(T0_64 >> 32)) << 32) |
2753
        (uint64_t)((int32_t)(int16_t)T0_64);
2754
    RETURN();
2755
}
2756

    
2757
void OPPROTO op_evextsb (void)
2758
{
2759
    T0_64 = ((uint64_t)((int32_t)(int8_t)(T0_64 >> 32)) << 32) |
2760
        (uint64_t)((int32_t)(int8_t)T0_64);
2761
    RETURN();
2762
}
2763

    
2764
void OPPROTO op_evcntlzw (void)
2765
{
2766
    do_evcntlzw();
2767
    RETURN();
2768
}
2769

    
2770
void OPPROTO op_evrndw (void)
2771
{
2772
    do_evrndw();
2773
    RETURN();
2774
}
2775

    
2776
void OPPROTO op_brinc (void)
2777
{
2778
    do_brinc();
2779
    RETURN();
2780
}
2781

    
2782
void OPPROTO op_evcntlsw (void)
2783
{
2784
    do_evcntlsw();
2785
    RETURN();
2786
}
2787

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

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

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

    
2806
void OPPROTO op_evxor (void)
2807
{
2808
    T0_64 ^= T1_64;
2809
    RETURN();
2810
}
2811

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

    
2818
void OPPROTO op_evnor (void)
2819
{
2820
    T0_64 = ~(T0_64 | T1_64);
2821
    RETURN();
2822
}
2823

    
2824
void OPPROTO op_evorc (void)
2825
{
2826
    T0_64 |= ~T1_64;
2827
    RETURN();
2828
}
2829

    
2830
void OPPROTO op_evnand (void)
2831
{
2832
    T0_64 = ~(T0_64 & T1_64);
2833
    RETURN();
2834
}
2835

    
2836
void OPPROTO op_evsrws (void)
2837
{
2838
    do_evsrws();
2839
    RETURN();
2840
}
2841

    
2842
void OPPROTO op_evsrwu (void)
2843
{
2844
    do_evsrwu();
2845
    RETURN();
2846
}
2847

    
2848
void OPPROTO op_evslw (void)
2849
{
2850
    do_evslw();
2851
    RETURN();
2852
}
2853

    
2854
void OPPROTO op_evrlw (void)
2855
{
2856
    do_evrlw();
2857
    RETURN();
2858
}
2859

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

    
2866
void OPPROTO op_evmergehi (void)
2867
{
2868
    T0_64 = (T0_64 & 0xFFFFFFFF00000000ULL) | (T1_64 >> 32);
2869
    RETURN();
2870
}
2871

    
2872
void OPPROTO op_evmergelohi (void)
2873
{
2874
    T0_64 = (T0_64 << 32) | (T1_64 >> 32);
2875
    RETURN();
2876
}
2877

    
2878
void OPPROTO op_evmergehilo (void)
2879
{
2880
    T0_64 = (T0_64 & 0xFFFFFFFF00000000ULL) | (T1_64 & 0x00000000FFFFFFFFULL);
2881
    RETURN();
2882
}
2883

    
2884
void OPPROTO op_evcmpgts (void)
2885
{
2886
    do_evcmpgts();
2887
    RETURN();
2888
}
2889

    
2890
void OPPROTO op_evcmpgtu (void)
2891
{
2892
    do_evcmpgtu();
2893
    RETURN();
2894
}
2895

    
2896
void OPPROTO op_evcmplts (void)
2897
{
2898
    do_evcmplts();
2899
    RETURN();
2900
}
2901

    
2902
void OPPROTO op_evcmpltu (void)
2903
{
2904
    do_evcmpltu();
2905
    RETURN();
2906
}
2907

    
2908
void OPPROTO op_evcmpeq (void)
2909
{
2910
    do_evcmpeq();
2911
    RETURN();
2912
}
2913

    
2914
void OPPROTO op_evfssub (void)
2915
{
2916
    do_evfssub();
2917
    RETURN();
2918
}
2919

    
2920
void OPPROTO op_evfsadd (void)
2921
{
2922
    do_evfsadd();
2923
    RETURN();
2924
}
2925

    
2926
void OPPROTO op_evfsnabs (void)
2927
{
2928
    do_evfsnabs();
2929
    RETURN();
2930
}
2931

    
2932
void OPPROTO op_evfsabs (void)
2933
{
2934
    do_evfsabs();
2935
    RETURN();
2936
}
2937

    
2938
void OPPROTO op_evfsneg (void)
2939
{
2940
    do_evfsneg();
2941
    RETURN();
2942
}
2943

    
2944
void OPPROTO op_evfsdiv (void)
2945
{
2946
    do_evfsdiv();
2947
    RETURN();
2948
}
2949

    
2950
void OPPROTO op_evfsmul (void)
2951
{
2952
    do_evfsmul();
2953
    RETURN();
2954
}
2955

    
2956
void OPPROTO op_evfscmplt (void)
2957
{
2958
    do_evfscmplt();
2959
    RETURN();
2960
}
2961

    
2962
void OPPROTO op_evfscmpgt (void)
2963
{
2964
    do_evfscmpgt();
2965
    RETURN();
2966
}
2967

    
2968
void OPPROTO op_evfscmpeq (void)
2969
{
2970
    do_evfscmpeq();
2971
    RETURN();
2972
}
2973

    
2974
void OPPROTO op_evfscfsi (void)
2975
{
2976
    do_evfscfsi();
2977
    RETURN();
2978
}
2979

    
2980
void OPPROTO op_evfscfui (void)
2981
{
2982
    do_evfscfui();
2983
    RETURN();
2984
}
2985

    
2986
void OPPROTO op_evfscfsf (void)
2987
{
2988
    do_evfscfsf();
2989
    RETURN();
2990
}
2991

    
2992
void OPPROTO op_evfscfuf (void)
2993
{
2994
    do_evfscfuf();
2995
    RETURN();
2996
}
2997

    
2998
void OPPROTO op_evfsctsi (void)
2999
{
3000
    do_evfsctsi();
3001
    RETURN();
3002
}
3003

    
3004
void OPPROTO op_evfsctui (void)
3005
{
3006
    do_evfsctui();
3007
    RETURN();
3008
}
3009

    
3010
void OPPROTO op_evfsctsf (void)
3011
{
3012
    do_evfsctsf();
3013
    RETURN();
3014
}
3015

    
3016
void OPPROTO op_evfsctuf (void)
3017
{
3018
    do_evfsctuf();
3019
    RETURN();
3020
}
3021

    
3022
void OPPROTO op_evfsctuiz (void)
3023
{
3024
    do_evfsctuiz();
3025
    RETURN();
3026
}
3027

    
3028
void OPPROTO op_evfsctsiz (void)
3029
{
3030
    do_evfsctsiz();
3031
    RETURN();
3032
}
3033

    
3034
void OPPROTO op_evfststlt (void)
3035
{
3036
    do_evfststlt();
3037
    RETURN();
3038
}
3039

    
3040
void OPPROTO op_evfststgt (void)
3041
{
3042
    do_evfststgt();
3043
    RETURN();
3044
}
3045

    
3046
void OPPROTO op_evfststeq (void)
3047
{
3048
    do_evfststeq();
3049
    RETURN();
3050
}
3051

    
3052
void OPPROTO op_efssub (void)
3053
{
3054
    T0_64 = _do_efssub(T0_64, T1_64);
3055
    RETURN();
3056
}
3057

    
3058
void OPPROTO op_efsadd (void)
3059
{
3060
    T0_64 = _do_efsadd(T0_64, T1_64);
3061
    RETURN();
3062
}
3063

    
3064
void OPPROTO op_efsnabs (void)
3065
{
3066
    T0_64 = _do_efsnabs(T0_64);
3067
    RETURN();
3068
}
3069

    
3070
void OPPROTO op_efsabs (void)
3071
{
3072
    T0_64 = _do_efsabs(T0_64);
3073
    RETURN();
3074
}
3075

    
3076
void OPPROTO op_efsneg (void)
3077
{
3078
    T0_64 = _do_efsneg(T0_64);
3079
    RETURN();
3080
}
3081

    
3082
void OPPROTO op_efsdiv (void)
3083
{
3084
    T0_64 = _do_efsdiv(T0_64, T1_64);
3085
    RETURN();
3086
}
3087

    
3088
void OPPROTO op_efsmul (void)
3089
{
3090
    T0_64 = _do_efsmul(T0_64, T1_64);
3091
    RETURN();
3092
}
3093

    
3094
void OPPROTO op_efscmplt (void)
3095
{
3096
    do_efscmplt();
3097
    RETURN();
3098
}
3099

    
3100
void OPPROTO op_efscmpgt (void)
3101
{
3102
    do_efscmpgt();
3103
    RETURN();
3104
}
3105

    
3106
void OPPROTO op_efscfd (void)
3107
{
3108
    do_efscfd();
3109
    RETURN();
3110
}
3111

    
3112
void OPPROTO op_efscmpeq (void)
3113
{
3114
    do_efscmpeq();
3115
    RETURN();
3116
}
3117

    
3118
void OPPROTO op_efscfsi (void)
3119
{
3120
    do_efscfsi();
3121
    RETURN();
3122
}
3123

    
3124
void OPPROTO op_efscfui (void)
3125
{
3126
    do_efscfui();
3127
    RETURN();
3128
}
3129

    
3130
void OPPROTO op_efscfsf (void)
3131
{
3132
    do_efscfsf();
3133
    RETURN();
3134
}
3135

    
3136
void OPPROTO op_efscfuf (void)
3137
{
3138
    do_efscfuf();
3139
    RETURN();
3140
}
3141

    
3142
void OPPROTO op_efsctsi (void)
3143
{
3144
    do_efsctsi();
3145
    RETURN();
3146
}
3147

    
3148
void OPPROTO op_efsctui (void)
3149
{
3150
    do_efsctui();
3151
    RETURN();
3152
}
3153

    
3154
void OPPROTO op_efsctsf (void)
3155
{
3156
    do_efsctsf();
3157
    RETURN();
3158
}
3159

    
3160
void OPPROTO op_efsctuf (void)
3161
{
3162
    do_efsctuf();
3163
    RETURN();
3164
}
3165

    
3166
void OPPROTO op_efsctsiz (void)
3167
{
3168
    do_efsctsiz();
3169
    RETURN();
3170
}
3171

    
3172
void OPPROTO op_efsctuiz (void)
3173
{
3174
    do_efsctuiz();
3175
    RETURN();
3176
}
3177

    
3178
void OPPROTO op_efststlt (void)
3179
{
3180
    T0 = _do_efststlt(T0_64, T1_64);
3181
    RETURN();
3182
}
3183

    
3184
void OPPROTO op_efststgt (void)
3185
{
3186
    T0 = _do_efststgt(T0_64, T1_64);
3187
    RETURN();
3188
}
3189

    
3190
void OPPROTO op_efststeq (void)
3191
{
3192
    T0 = _do_efststeq(T0_64, T1_64);
3193
    RETURN();
3194
}
3195

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

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

    
3216
void OPPROTO op_efdcfsid (void)
3217
{
3218
    do_efdcfsi();
3219
    RETURN();
3220
}
3221

    
3222
void OPPROTO op_efdcfuid (void)
3223
{
3224
    do_efdcfui();
3225
    RETURN();
3226
}
3227

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

    
3234
void OPPROTO op_efdabs (void)
3235
{
3236
    T0_64 &= ~0x8000000000000000ULL;
3237
    RETURN();
3238
}
3239

    
3240
void OPPROTO op_efdneg (void)
3241
{
3242
    T0_64 ^= 0x8000000000000000ULL;
3243
    RETURN();
3244
}
3245

    
3246
void OPPROTO op_efddiv (void)
3247
{
3248
    CPU_DoubleU u1, u2;
3249
    u1.ll = T0_64;
3250
    u2.ll = T1_64;
3251
    u1.d = float64_div(u1.d, u2.d, &env->spe_status);
3252
    T0_64 = u1.ll;
3253
    RETURN();
3254
}
3255

    
3256
void OPPROTO op_efdmul (void)
3257
{
3258
    CPU_DoubleU u1, u2;
3259
    u1.ll = T0_64;
3260
    u2.ll = T1_64;
3261
    u1.d = float64_mul(u1.d, u2.d, &env->spe_status);
3262
    T0_64 = u1.ll;
3263
    RETURN();
3264
}
3265

    
3266
void OPPROTO op_efdctsidz (void)
3267
{
3268
    do_efdctsiz();
3269
    RETURN();
3270
}
3271

    
3272
void OPPROTO op_efdctuidz (void)
3273
{
3274
    do_efdctuiz();
3275
    RETURN();
3276
}
3277

    
3278
void OPPROTO op_efdcmplt (void)
3279
{
3280
    do_efdcmplt();
3281
    RETURN();
3282
}
3283

    
3284
void OPPROTO op_efdcmpgt (void)
3285
{
3286
    do_efdcmpgt();
3287
    RETURN();
3288
}
3289

    
3290
void OPPROTO op_efdcfs (void)
3291
{
3292
    do_efdcfs();
3293
    RETURN();
3294
}
3295

    
3296
void OPPROTO op_efdcmpeq (void)
3297
{
3298
    do_efdcmpeq();
3299
    RETURN();
3300
}
3301

    
3302
void OPPROTO op_efdcfsi (void)
3303
{
3304
    do_efdcfsi();
3305
    RETURN();
3306
}
3307

    
3308
void OPPROTO op_efdcfui (void)
3309
{
3310
    do_efdcfui();
3311
    RETURN();
3312
}
3313

    
3314
void OPPROTO op_efdcfsf (void)
3315
{
3316
    do_efdcfsf();
3317
    RETURN();
3318
}
3319

    
3320
void OPPROTO op_efdcfuf (void)
3321
{
3322
    do_efdcfuf();
3323
    RETURN();
3324
}
3325

    
3326
void OPPROTO op_efdctsi (void)
3327
{
3328
    do_efdctsi();
3329
    RETURN();
3330
}
3331

    
3332
void OPPROTO op_efdctui (void)
3333
{
3334
    do_efdctui();
3335
    RETURN();
3336
}
3337

    
3338
void OPPROTO op_efdctsf (void)
3339
{
3340
    do_efdctsf();
3341
    RETURN();
3342
}
3343

    
3344
void OPPROTO op_efdctuf (void)
3345
{
3346
    do_efdctuf();
3347
    RETURN();
3348
}
3349

    
3350
void OPPROTO op_efdctuiz (void)
3351
{
3352
    do_efdctuiz();
3353
    RETURN();
3354
}
3355

    
3356
void OPPROTO op_efdctsiz (void)
3357
{
3358
    do_efdctsiz();
3359
    RETURN();
3360
}
3361

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

    
3368
void OPPROTO op_efdtstgt (void)
3369
{
3370
    T0 = _do_efdtstgt(T0_64, T1_64);
3371
    RETURN();
3372
}
3373

    
3374
void OPPROTO op_efdtsteq (void)
3375
{
3376
    T0 = _do_efdtsteq(T0_64, T1_64);
3377
    RETURN();
3378
}