Statistics
| Branch: | Revision:

root / target-ppc / op.c @ e755699d

History | View | Annotate | Download (49.9 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_move_T1_T0 (void)
183
{
184
    T1 = T0;
185
    RETURN();
186
}
187

    
188
void OPPROTO op_move_T2_T0 (void)
189
{
190
    T2 = T0;
191
    RETURN();
192
}
193

    
194
void OPPROTO op_moven_T2_T0 (void)
195
{
196
    T2 = ~T0;
197
    RETURN();
198
}
199

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

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

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

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

    
225
/* Load/store special registers */
226
void OPPROTO op_load_cr (void)
227
{
228
    do_load_cr();
229
    RETURN();
230
}
231

    
232
void OPPROTO op_store_cr (void)
233
{
234
    do_store_cr(PARAM1);
235
    RETURN();
236
}
237

    
238
void OPPROTO op_load_cro (void)
239
{
240
    T0 = env->crf[PARAM1];
241
    RETURN();
242
}
243

    
244
void OPPROTO op_store_cro (void)
245
{
246
    env->crf[PARAM1] = T0;
247
    RETURN();
248
}
249

    
250
void OPPROTO op_load_xer_cr (void)
251
{
252
    T0 = (xer_so << 3) | (xer_ov << 2) | (xer_ca << 1);
253
    RETURN();
254
}
255

    
256
void OPPROTO op_clear_xer_ov (void)
257
{
258
    xer_so = 0;
259
    xer_ov = 0;
260
    RETURN();
261
}
262

    
263
void OPPROTO op_clear_xer_ca (void)
264
{
265
    xer_ca = 0;
266
    RETURN();
267
}
268

    
269
void OPPROTO op_load_xer_bc (void)
270
{
271
    T1 = xer_bc;
272
    RETURN();
273
}
274

    
275
void OPPROTO op_store_xer_bc (void)
276
{
277
    xer_bc = T0;
278
    RETURN();
279
}
280

    
281
void OPPROTO op_load_xer (void)
282
{
283
    T0 = hreg_load_xer(env);
284
    RETURN();
285
}
286

    
287
void OPPROTO op_store_xer (void)
288
{
289
    hreg_store_xer(env, T0);
290
    RETURN();
291
}
292

    
293
#if defined(TARGET_PPC64)
294
void OPPROTO op_store_pri (void)
295
{
296
    do_store_pri(PARAM1);
297
    RETURN();
298
}
299
#endif
300

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

    
309
void OPPROTO op_store_sr (void)
310
{
311
    do_store_sr(env, T1, T0);
312
    RETURN();
313
}
314

    
315
#if defined(TARGET_PPC64)
316
void OPPROTO op_load_slb (void)
317
{
318
    T0 = ppc_load_slb(env, T1);
319
    RETURN();
320
}
321

    
322
void OPPROTO op_store_slb (void)
323
{
324
    ppc_store_slb(env, T1, T0);
325
    RETURN();
326
}
327
#endif /* defined(TARGET_PPC64) */
328

    
329
void OPPROTO op_load_sdr1 (void)
330
{
331
    T0 = env->sdr1;
332
    RETURN();
333
}
334

    
335
void OPPROTO op_store_sdr1 (void)
336
{
337
    do_store_sdr1(env, T0);
338
    RETURN();
339
}
340

    
341
#if defined (TARGET_PPC64)
342
void OPPROTO op_load_asr (void)
343
{
344
    T0 = env->asr;
345
    RETURN();
346
}
347

    
348
void OPPROTO op_store_asr (void)
349
{
350
    ppc_store_asr(env, T0);
351
    RETURN();
352
}
353
#endif
354

    
355
void OPPROTO op_load_msr (void)
356
{
357
    T0 = env->msr;
358
    RETURN();
359
}
360

    
361
void OPPROTO op_store_msr (void)
362
{
363
    do_store_msr();
364
    RETURN();
365
}
366

    
367
#if defined (TARGET_PPC64)
368
void OPPROTO op_store_msr_32 (void)
369
{
370
    T0 = (env->msr & ~0xFFFFFFFFULL) | (T0 & 0xFFFFFFFF);
371
    do_store_msr();
372
    RETURN();
373
}
374
#endif
375

    
376
void OPPROTO op_update_riee (void)
377
{
378
    /* We don't call do_store_msr here as we won't trigger
379
     * any special case nor change hflags
380
     */
381
    T0 &= (1 << MSR_RI) | (1 << MSR_EE);
382
    env->msr &= ~(1 << MSR_RI) | (1 << MSR_EE);
383
    env->msr |= T0;
384
    RETURN();
385
}
386
#endif
387

    
388
/* SPR */
389
void OPPROTO op_load_spr (void)
390
{
391
    T0 = env->spr[PARAM1];
392
    RETURN();
393
}
394

    
395
void OPPROTO op_store_spr (void)
396
{
397
    env->spr[PARAM1] = T0;
398
    RETURN();
399
}
400

    
401
void OPPROTO op_load_dump_spr (void)
402
{
403
    T0 = ppc_load_dump_spr(PARAM1);
404
    RETURN();
405
}
406

    
407
void OPPROTO op_store_dump_spr (void)
408
{
409
    ppc_store_dump_spr(PARAM1, T0);
410
    RETURN();
411
}
412

    
413
void OPPROTO op_mask_spr (void)
414
{
415
    env->spr[PARAM1] &= ~T0;
416
    RETURN();
417
}
418

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

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

    
431
void OPPROTO op_load_ctr (void)
432
{
433
    T0 = env->ctr;
434
    RETURN();
435
}
436

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

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

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

    
455
void OPPROTO op_load_atbl (void)
456
{
457
    T0 = cpu_ppc_load_atbl(env);
458
    RETURN();
459
}
460

    
461
void OPPROTO op_load_atbu (void)
462
{
463
    T0 = cpu_ppc_load_atbu(env);
464
    RETURN();
465
}
466

    
467
#if !defined(CONFIG_USER_ONLY)
468
void OPPROTO op_store_tbl (void)
469
{
470
    cpu_ppc_store_tbl(env, T0);
471
    RETURN();
472
}
473

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

    
480
void OPPROTO op_store_atbl (void)
481
{
482
    cpu_ppc_store_atbl(env, T0);
483
    RETURN();
484
}
485

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

    
492
void OPPROTO op_load_decr (void)
493
{
494
    T0 = cpu_ppc_load_decr(env);
495
    RETURN();
496
}
497

    
498
void OPPROTO op_store_decr (void)
499
{
500
    cpu_ppc_store_decr(env, T0);
501
    RETURN();
502
}
503

    
504
void OPPROTO op_load_ibat (void)
505
{
506
    T0 = env->IBAT[PARAM1][PARAM2];
507
    RETURN();
508
}
509

    
510
void OPPROTO op_store_ibatu (void)
511
{
512
    do_store_ibatu(env, PARAM1, T0);
513
    RETURN();
514
}
515

    
516
void OPPROTO op_store_ibatl (void)
517
{
518
#if 1
519
    env->IBAT[1][PARAM1] = T0;
520
#else
521
    do_store_ibatl(env, PARAM1, T0);
522
#endif
523
    RETURN();
524
}
525

    
526
void OPPROTO op_load_dbat (void)
527
{
528
    T0 = env->DBAT[PARAM1][PARAM2];
529
    RETURN();
530
}
531

    
532
void OPPROTO op_store_dbatu (void)
533
{
534
    do_store_dbatu(env, PARAM1, T0);
535
    RETURN();
536
}
537

    
538
void OPPROTO op_store_dbatl (void)
539
{
540
#if 1
541
    env->DBAT[1][PARAM1] = T0;
542
#else
543
    do_store_dbatl(env, PARAM1, T0);
544
#endif
545
    RETURN();
546
}
547
#endif /* !defined(CONFIG_USER_ONLY) */
548

    
549
/* FPSCR */
550
#ifdef CONFIG_SOFTFLOAT
551
void OPPROTO op_reset_fpstatus (void)
552
{
553
    env->fp_status.float_exception_flags = 0;
554
    RETURN();
555
}
556
#endif
557

    
558
void OPPROTO op_compute_fprf (void)
559
{
560
    do_compute_fprf(PARAM1);
561
    RETURN();
562
}
563

    
564
#ifdef CONFIG_SOFTFLOAT
565
void OPPROTO op_float_check_status (void)
566
{
567
    do_float_check_status();
568
    RETURN();
569
}
570
#else
571
void OPPROTO op_float_check_status (void)
572
{
573
    if (env->exception_index == POWERPC_EXCP_PROGRAM &&
574
        (env->error_code & POWERPC_EXCP_FP)) {
575
        /* Differred floating-point exception after target FPR update */
576
        if (msr_fe0 != 0 || msr_fe1 != 0)
577
            do_raise_exception_err(env->exception_index, env->error_code);
578
    }
579
    RETURN();
580
}
581
#endif
582

    
583
void OPPROTO op_load_fpscr_FT0 (void)
584
{
585
    /* The 32 MSB of the target fpr are undefined.
586
     * They'll be zero...
587
     */
588
    CPU_DoubleU u;
589

    
590
    u.l.upper = 0;
591
    u.l.lower = env->fpscr;
592
    FT0 = u.d;
593
    RETURN();
594
}
595

    
596
void OPPROTO op_set_FT0 (void)
597
{
598
    CPU_DoubleU u;
599

    
600
    u.l.upper = 0;
601
    u.l.lower = PARAM1;
602
    FT0 = u.d;
603
    RETURN();
604
}
605

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

    
612
void OPPROTO op_load_fpcc (void)
613
{
614
    T0 = fpscr_fpcc;
615
    RETURN();
616
}
617

    
618
void OPPROTO op_fpscr_resetbit (void)
619
{
620
    env->fpscr &= PARAM1;
621
    RETURN();
622
}
623

    
624
void OPPROTO op_fpscr_setbit (void)
625
{
626
    do_fpscr_setbit(PARAM1);
627
    RETURN();
628
}
629

    
630
void OPPROTO op_store_fpscr (void)
631
{
632
    do_store_fpscr(PARAM1);
633
    RETURN();
634
}
635

    
636
/* Branch */
637
#define EIP env->nip
638

    
639
void OPPROTO op_setlr (void)
640
{
641
    env->lr = (uint32_t)PARAM1;
642
    RETURN();
643
}
644

    
645
#if defined (TARGET_PPC64)
646
void OPPROTO op_setlr_64 (void)
647
{
648
    env->lr = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
649
    RETURN();
650
}
651
#endif
652

    
653
void OPPROTO op_b_T1 (void)
654
{
655
    env->nip = (uint32_t)(T1 & ~3);
656
    RETURN();
657
}
658

    
659
#if defined (TARGET_PPC64)
660
void OPPROTO op_b_T1_64 (void)
661
{
662
    env->nip = (uint64_t)(T1 & ~3);
663
    RETURN();
664
}
665
#endif
666

    
667
void OPPROTO op_jz_T0 (void)
668
{
669
    if (!T0)
670
        GOTO_LABEL_PARAM(1);
671
    RETURN();
672
}
673

    
674
void OPPROTO op_btest_T1 (void)
675
{
676
    if (T0) {
677
        env->nip = (uint32_t)(T1 & ~3);
678
    } else {
679
        env->nip = (uint32_t)PARAM1;
680
    }
681
    RETURN();
682
}
683

    
684
#if defined (TARGET_PPC64)
685
void OPPROTO op_btest_T1_64 (void)
686
{
687
    if (T0) {
688
        env->nip = (uint64_t)(T1 & ~3);
689
    } else {
690
        env->nip = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
691
    }
692
    RETURN();
693
}
694
#endif
695

    
696
void OPPROTO op_movl_T1_ctr (void)
697
{
698
    T1 = env->ctr;
699
    RETURN();
700
}
701

    
702
void OPPROTO op_movl_T1_lr (void)
703
{
704
    T1 = env->lr;
705
    RETURN();
706
}
707

    
708
/* tests with result in T0 */
709
void OPPROTO op_test_ctr (void)
710
{
711
    T0 = (uint32_t)env->ctr;
712
    RETURN();
713
}
714

    
715
#if defined(TARGET_PPC64)
716
void OPPROTO op_test_ctr_64 (void)
717
{
718
    T0 = (uint64_t)env->ctr;
719
    RETURN();
720
}
721
#endif
722

    
723
void OPPROTO op_test_ctr_true (void)
724
{
725
    T0 = ((uint32_t)env->ctr != 0 && (T0 & PARAM1) != 0);
726
    RETURN();
727
}
728

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

    
737
void OPPROTO op_test_ctr_false (void)
738
{
739
    T0 = ((uint32_t)env->ctr != 0 && (T0 & PARAM1) == 0);
740
    RETURN();
741
}
742

    
743
#if defined(TARGET_PPC64)
744
void OPPROTO op_test_ctr_false_64 (void)
745
{
746
    T0 = ((uint64_t)env->ctr != 0 && (T0 & PARAM1) == 0);
747
    RETURN();
748
}
749
#endif
750

    
751
void OPPROTO op_test_ctrz (void)
752
{
753
    T0 = ((uint32_t)env->ctr == 0);
754
    RETURN();
755
}
756

    
757
#if defined(TARGET_PPC64)
758
void OPPROTO op_test_ctrz_64 (void)
759
{
760
    T0 = ((uint64_t)env->ctr == 0);
761
    RETURN();
762
}
763
#endif
764

    
765
void OPPROTO op_test_ctrz_true (void)
766
{
767
    T0 = ((uint32_t)env->ctr == 0 && (T0 & PARAM1) != 0);
768
    RETURN();
769
}
770

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

    
779
void OPPROTO op_test_ctrz_false (void)
780
{
781
    T0 = ((uint32_t)env->ctr == 0 && (T0 & PARAM1) == 0);
782
    RETURN();
783
}
784

    
785
#if defined(TARGET_PPC64)
786
void OPPROTO op_test_ctrz_false_64 (void)
787
{
788
    T0 = ((uint64_t)env->ctr == 0 && (T0 & PARAM1) == 0);
789
    RETURN();
790
}
791
#endif
792

    
793
void OPPROTO op_test_true (void)
794
{
795
    T0 = (T0 & PARAM1);
796
    RETURN();
797
}
798

    
799
void OPPROTO op_test_false (void)
800
{
801
    T0 = ((T0 & PARAM1) == 0);
802
    RETURN();
803
}
804

    
805
/* CTR maintenance */
806
void OPPROTO op_dec_ctr (void)
807
{
808
    env->ctr--;
809
    RETURN();
810
}
811

    
812
/***                           Integer arithmetic                          ***/
813
/* add */
814
void OPPROTO op_add (void)
815
{
816
    T0 += T1;
817
    RETURN();
818
}
819

    
820
void OPPROTO op_check_addo (void)
821
{
822
    xer_ov = (((uint32_t)T2 ^ (uint32_t)T1 ^ UINT32_MAX) &
823
              ((uint32_t)T2 ^ (uint32_t)T0)) >> 31;
824
    xer_so |= xer_ov;
825
    RETURN();
826
}
827

    
828
#if defined(TARGET_PPC64)
829
void OPPROTO op_check_addo_64 (void)
830
{
831
    xer_ov = (((uint64_t)T2 ^ (uint64_t)T1 ^ UINT64_MAX) &
832
              ((uint64_t)T2 ^ (uint64_t)T0)) >> 63;
833
    xer_so |= xer_ov;
834
    RETURN();
835
}
836
#endif
837

    
838
/* add carrying */
839
void OPPROTO op_check_addc (void)
840
{
841
    if (likely((uint32_t)T0 >= (uint32_t)T2)) {
842
        xer_ca = 0;
843
    } else {
844
        xer_ca = 1;
845
    }
846
    RETURN();
847
}
848

    
849
#if defined(TARGET_PPC64)
850
void OPPROTO op_check_addc_64 (void)
851
{
852
    if (likely((uint64_t)T0 >= (uint64_t)T2)) {
853
        xer_ca = 0;
854
    } else {
855
        xer_ca = 1;
856
    }
857
    RETURN();
858
}
859
#endif
860

    
861
/* add extended */
862
void OPPROTO op_adde (void)
863
{
864
    do_adde();
865
    RETURN();
866
}
867

    
868
#if defined(TARGET_PPC64)
869
void OPPROTO op_adde_64 (void)
870
{
871
    do_adde_64();
872
    RETURN();
873
}
874
#endif
875

    
876
/* add immediate */
877
void OPPROTO op_addi (void)
878
{
879
    T0 += (int32_t)PARAM1;
880
    RETURN();
881
}
882

    
883
/* add to minus one extended */
884
void OPPROTO op_add_me (void)
885
{
886
    T0 += xer_ca + (-1);
887
    if (likely((uint32_t)T1 != 0))
888
        xer_ca = 1;
889
    else
890
        xer_ca = 0;
891
    RETURN();
892
}
893

    
894
#if defined(TARGET_PPC64)
895
void OPPROTO op_add_me_64 (void)
896
{
897
    T0 += xer_ca + (-1);
898
    if (likely((uint64_t)T1 != 0))
899
        xer_ca = 1;
900
    else
901
        xer_ca = 0;
902
    RETURN();
903
}
904
#endif
905

    
906
void OPPROTO op_addmeo (void)
907
{
908
    do_addmeo();
909
    RETURN();
910
}
911

    
912
void OPPROTO op_addmeo_64 (void)
913
{
914
    do_addmeo();
915
    RETURN();
916
}
917

    
918
/* add to zero extended */
919
void OPPROTO op_add_ze (void)
920
{
921
    T0 += xer_ca;
922
    RETURN();
923
}
924

    
925
/* divide word */
926
void OPPROTO op_divw (void)
927
{
928
    if (unlikely(((int32_t)T0 == INT32_MIN && (int32_t)T1 == (int32_t)-1) ||
929
                 (int32_t)T1 == 0)) {
930
        T0 = (int32_t)(UINT32_MAX * ((uint32_t)T0 >> 31));
931
    } else {
932
        T0 = (int32_t)T0 / (int32_t)T1;
933
    }
934
    RETURN();
935
}
936

    
937
#if defined(TARGET_PPC64)
938
void OPPROTO op_divd (void)
939
{
940
    if (unlikely(((int64_t)T0 == INT64_MIN && (int64_t)T1 == (int64_t)-1LL) ||
941
                 (int64_t)T1 == 0)) {
942
        T0 = (int64_t)(UINT64_MAX * ((uint64_t)T0 >> 63));
943
    } else {
944
        T0 = (int64_t)T0 / (int64_t)T1;
945
    }
946
    RETURN();
947
}
948
#endif
949

    
950
void OPPROTO op_divwo (void)
951
{
952
    do_divwo();
953
    RETURN();
954
}
955

    
956
#if defined(TARGET_PPC64)
957
void OPPROTO op_divdo (void)
958
{
959
    do_divdo();
960
    RETURN();
961
}
962
#endif
963

    
964
/* divide word unsigned */
965
void OPPROTO op_divwu (void)
966
{
967
    if (unlikely(T1 == 0)) {
968
        T0 = 0;
969
    } else {
970
        T0 = (uint32_t)T0 / (uint32_t)T1;
971
    }
972
    RETURN();
973
}
974

    
975
#if defined(TARGET_PPC64)
976
void OPPROTO op_divdu (void)
977
{
978
    if (unlikely(T1 == 0)) {
979
        T0 = 0;
980
    } else {
981
        T0 /= T1;
982
    }
983
    RETURN();
984
}
985
#endif
986

    
987
void OPPROTO op_divwuo (void)
988
{
989
    do_divwuo();
990
    RETURN();
991
}
992

    
993
#if defined(TARGET_PPC64)
994
void OPPROTO op_divduo (void)
995
{
996
    do_divduo();
997
    RETURN();
998
}
999
#endif
1000

    
1001
/* multiply high word */
1002
void OPPROTO op_mulhw (void)
1003
{
1004
    T0 = ((int64_t)((int32_t)T0) * (int64_t)((int32_t)T1)) >> 32;
1005
    RETURN();
1006
}
1007

    
1008
#if defined(TARGET_PPC64)
1009
void OPPROTO op_mulhd (void)
1010
{
1011
    uint64_t tl, th;
1012

    
1013
    muls64(&tl, &th, T0, T1);
1014
    T0 = th;
1015
    RETURN();
1016
}
1017
#endif
1018

    
1019
/* multiply high word unsigned */
1020
void OPPROTO op_mulhwu (void)
1021
{
1022
    T0 = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1) >> 32;
1023
    RETURN();
1024
}
1025

    
1026
#if defined(TARGET_PPC64)
1027
void OPPROTO op_mulhdu (void)
1028
{
1029
    uint64_t tl, th;
1030

    
1031
    mulu64(&tl, &th, T0, T1);
1032
    T0 = th;
1033
    RETURN();
1034
}
1035
#endif
1036

    
1037
/* multiply low immediate */
1038
void OPPROTO op_mulli (void)
1039
{
1040
    T0 = ((int32_t)T0 * (int32_t)PARAM1);
1041
    RETURN();
1042
}
1043

    
1044
/* multiply low word */
1045
void OPPROTO op_mullw (void)
1046
{
1047
    T0 = (int32_t)(T0 * T1);
1048
    RETURN();
1049
}
1050

    
1051
#if defined(TARGET_PPC64)
1052
void OPPROTO op_mulld (void)
1053
{
1054
    T0 *= T1;
1055
    RETURN();
1056
}
1057
#endif
1058

    
1059
void OPPROTO op_mullwo (void)
1060
{
1061
    do_mullwo();
1062
    RETURN();
1063
}
1064

    
1065
#if defined(TARGET_PPC64)
1066
void OPPROTO op_mulldo (void)
1067
{
1068
    do_mulldo();
1069
    RETURN();
1070
}
1071
#endif
1072

    
1073
/* negate */
1074
void OPPROTO op_neg (void)
1075
{
1076
    if (likely(T0 != INT32_MIN)) {
1077
        T0 = -(int32_t)T0;
1078
    }
1079
    RETURN();
1080
}
1081

    
1082
#if defined(TARGET_PPC64)
1083
void OPPROTO op_neg_64 (void)
1084
{
1085
    if (likely(T0 != INT64_MIN)) {
1086
        T0 = -(int64_t)T0;
1087
    }
1088
    RETURN();
1089
}
1090
#endif
1091

    
1092
void OPPROTO op_nego (void)
1093
{
1094
    do_nego();
1095
    RETURN();
1096
}
1097

    
1098
#if defined(TARGET_PPC64)
1099
void OPPROTO op_nego_64 (void)
1100
{
1101
    do_nego_64();
1102
    RETURN();
1103
}
1104
#endif
1105

    
1106
/* subtract from */
1107
void OPPROTO op_subf (void)
1108
{
1109
    T0 = T1 - T0;
1110
    RETURN();
1111
}
1112

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

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

    
1136
/* subtract from extended */
1137
void OPPROTO op_subfe (void)
1138
{
1139
    do_subfe();
1140
    RETURN();
1141
}
1142

    
1143
#if defined(TARGET_PPC64)
1144
void OPPROTO op_subfe_64 (void)
1145
{
1146
    do_subfe_64();
1147
    RETURN();
1148
}
1149
#endif
1150

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

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

    
1176
/* subtract from minus one extended */
1177
void OPPROTO op_subfme (void)
1178
{
1179
    T0 = ~T0 + xer_ca - 1;
1180
    if (likely((uint32_t)T0 != UINT32_MAX))
1181
        xer_ca = 1;
1182
    else
1183
        xer_ca = 0;
1184
    RETURN();
1185
}
1186

    
1187
#if defined(TARGET_PPC64)
1188
void OPPROTO op_subfme_64 (void)
1189
{
1190
    T0 = ~T0 + xer_ca - 1;
1191
    if (likely((uint64_t)T0 != UINT64_MAX))
1192
        xer_ca = 1;
1193
    else
1194
        xer_ca = 0;
1195
    RETURN();
1196
}
1197
#endif
1198

    
1199
void OPPROTO op_subfmeo (void)
1200
{
1201
    do_subfmeo();
1202
    RETURN();
1203
}
1204

    
1205
#if defined(TARGET_PPC64)
1206
void OPPROTO op_subfmeo_64 (void)
1207
{
1208
    do_subfmeo_64();
1209
    RETURN();
1210
}
1211
#endif
1212

    
1213
/* subtract from zero extended */
1214
void OPPROTO op_subfze (void)
1215
{
1216
    T1 = ~T0;
1217
    T0 = T1 + xer_ca;
1218
    if ((uint32_t)T0 < (uint32_t)T1) {
1219
        xer_ca = 1;
1220
    } else {
1221
        xer_ca = 0;
1222
    }
1223
    RETURN();
1224
}
1225

    
1226
#if defined(TARGET_PPC64)
1227
void OPPROTO op_subfze_64 (void)
1228
{
1229
    T1 = ~T0;
1230
    T0 = T1 + xer_ca;
1231
    if ((uint64_t)T0 < (uint64_t)T1) {
1232
        xer_ca = 1;
1233
    } else {
1234
        xer_ca = 0;
1235
    }
1236
    RETURN();
1237
}
1238
#endif
1239

    
1240
void OPPROTO op_subfzeo (void)
1241
{
1242
    do_subfzeo();
1243
    RETURN();
1244
}
1245

    
1246
#if defined(TARGET_PPC64)
1247
void OPPROTO op_subfzeo_64 (void)
1248
{
1249
    do_subfzeo_64();
1250
    RETURN();
1251
}
1252
#endif
1253

    
1254
/***                           Integer comparison                          ***/
1255
/* compare */
1256
void OPPROTO op_cmp (void)
1257
{
1258
    if ((int32_t)T0 < (int32_t)T1) {
1259
        T0 = 0x08;
1260
    } else if ((int32_t)T0 > (int32_t)T1) {
1261
        T0 = 0x04;
1262
    } else {
1263
        T0 = 0x02;
1264
    }
1265
    T0 |= xer_so;
1266
    RETURN();
1267
}
1268

    
1269
#if defined(TARGET_PPC64)
1270
void OPPROTO op_cmp_64 (void)
1271
{
1272
    if ((int64_t)T0 < (int64_t)T1) {
1273
        T0 = 0x08;
1274
    } else if ((int64_t)T0 > (int64_t)T1) {
1275
        T0 = 0x04;
1276
    } else {
1277
        T0 = 0x02;
1278
    }
1279
    T0 |= xer_so;
1280
    RETURN();
1281
}
1282
#endif
1283

    
1284
/* compare immediate */
1285
void OPPROTO op_cmpi (void)
1286
{
1287
    if ((int32_t)T0 < (int32_t)PARAM1) {
1288
        T0 = 0x08;
1289
    } else if ((int32_t)T0 > (int32_t)PARAM1) {
1290
        T0 = 0x04;
1291
    } else {
1292
        T0 = 0x02;
1293
    }
1294
    T0 |= xer_so;
1295
    RETURN();
1296
}
1297

    
1298
#if defined(TARGET_PPC64)
1299
void OPPROTO op_cmpi_64 (void)
1300
{
1301
    if ((int64_t)T0 < (int64_t)((int32_t)PARAM1)) {
1302
        T0 = 0x08;
1303
    } else if ((int64_t)T0 > (int64_t)((int32_t)PARAM1)) {
1304
        T0 = 0x04;
1305
    } else {
1306
        T0 = 0x02;
1307
    }
1308
    T0 |= xer_so;
1309
    RETURN();
1310
}
1311
#endif
1312

    
1313
/* compare logical */
1314
void OPPROTO op_cmpl (void)
1315
{
1316
    if ((uint32_t)T0 < (uint32_t)T1) {
1317
        T0 = 0x08;
1318
    } else if ((uint32_t)T0 > (uint32_t)T1) {
1319
        T0 = 0x04;
1320
    } else {
1321
        T0 = 0x02;
1322
    }
1323
    T0 |= xer_so;
1324
    RETURN();
1325
}
1326

    
1327
#if defined(TARGET_PPC64)
1328
void OPPROTO op_cmpl_64 (void)
1329
{
1330
    if ((uint64_t)T0 < (uint64_t)T1) {
1331
        T0 = 0x08;
1332
    } else if ((uint64_t)T0 > (uint64_t)T1) {
1333
        T0 = 0x04;
1334
    } else {
1335
        T0 = 0x02;
1336
    }
1337
    T0 |= xer_so;
1338
    RETURN();
1339
}
1340
#endif
1341

    
1342
/* compare logical immediate */
1343
void OPPROTO op_cmpli (void)
1344
{
1345
    if ((uint32_t)T0 < (uint32_t)PARAM1) {
1346
        T0 = 0x08;
1347
    } else if ((uint32_t)T0 > (uint32_t)PARAM1) {
1348
        T0 = 0x04;
1349
    } else {
1350
        T0 = 0x02;
1351
    }
1352
    T0 |= xer_so;
1353
    RETURN();
1354
}
1355

    
1356
#if defined(TARGET_PPC64)
1357
void OPPROTO op_cmpli_64 (void)
1358
{
1359
    if ((uint64_t)T0 < (uint64_t)PARAM1) {
1360
        T0 = 0x08;
1361
    } else if ((uint64_t)T0 > (uint64_t)PARAM1) {
1362
        T0 = 0x04;
1363
    } else {
1364
        T0 = 0x02;
1365
    }
1366
    T0 |= xer_so;
1367
    RETURN();
1368
}
1369
#endif
1370

    
1371
void OPPROTO op_isel (void)
1372
{
1373
    if (T0)
1374
        T0 = T1;
1375
    else
1376
        T0 = T2;
1377
    RETURN();
1378
}
1379

    
1380
void OPPROTO op_popcntb (void)
1381
{
1382
    do_popcntb();
1383
    RETURN();
1384
}
1385

    
1386
#if defined(TARGET_PPC64)
1387
void OPPROTO op_popcntb_64 (void)
1388
{
1389
    do_popcntb_64();
1390
    RETURN();
1391
}
1392
#endif
1393

    
1394
/***                            Integer logical                            ***/
1395
/* and */
1396
void OPPROTO op_and (void)
1397
{
1398
    T0 &= T1;
1399
    RETURN();
1400
}
1401

    
1402
/* andc */
1403
void OPPROTO op_andc (void)
1404
{
1405
    T0 &= ~T1;
1406
    RETURN();
1407
}
1408

    
1409
/* andi. */
1410
void OPPROTO op_andi_T0 (void)
1411
{
1412
    T0 &= (uint32_t)PARAM1;
1413
    RETURN();
1414
}
1415

    
1416
void OPPROTO op_andi_T1 (void)
1417
{
1418
    T1 &= (uint32_t)PARAM1;
1419
    RETURN();
1420
}
1421

    
1422
#if defined(TARGET_PPC64)
1423
void OPPROTO op_andi_T0_64 (void)
1424
{
1425
    T0 &= ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
1426
    RETURN();
1427
}
1428

    
1429
void OPPROTO op_andi_T1_64 (void)
1430
{
1431
    T1 &= ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
1432
    RETURN();
1433
}
1434
#endif
1435

    
1436
/* count leading zero */
1437
void OPPROTO op_cntlzw (void)
1438
{
1439
    do_cntlzw();
1440
    RETURN();
1441
}
1442

    
1443
#if defined(TARGET_PPC64)
1444
void OPPROTO op_cntlzd (void)
1445
{
1446
    do_cntlzd();
1447
    RETURN();
1448
}
1449
#endif
1450

    
1451
/* eqv */
1452
void OPPROTO op_eqv (void)
1453
{
1454
    T0 = ~(T0 ^ T1);
1455
    RETURN();
1456
}
1457

    
1458
/* extend sign byte */
1459
void OPPROTO op_extsb (void)
1460
{
1461
#if defined (TARGET_PPC64)
1462
    T0 = (int64_t)((int8_t)T0);
1463
#else
1464
    T0 = (int32_t)((int8_t)T0);
1465
#endif
1466
    RETURN();
1467
}
1468

    
1469
/* extend sign half word */
1470
void OPPROTO op_extsh (void)
1471
{
1472
#if defined (TARGET_PPC64)
1473
    T0 = (int64_t)((int16_t)T0);
1474
#else
1475
    T0 = (int32_t)((int16_t)T0);
1476
#endif
1477
    RETURN();
1478
}
1479

    
1480
#if defined (TARGET_PPC64)
1481
void OPPROTO op_extsw (void)
1482
{
1483
    T0 = (int64_t)((int32_t)T0);
1484
    RETURN();
1485
}
1486
#endif
1487

    
1488
/* nand */
1489
void OPPROTO op_nand (void)
1490
{
1491
    T0 = ~(T0 & T1);
1492
    RETURN();
1493
}
1494

    
1495
/* nor */
1496
void OPPROTO op_nor (void)
1497
{
1498
    T0 = ~(T0 | T1);
1499
    RETURN();
1500
}
1501

    
1502
/* or */
1503
void OPPROTO op_or (void)
1504
{
1505
    T0 |= T1;
1506
    RETURN();
1507
}
1508

    
1509
/* orc */
1510
void OPPROTO op_orc (void)
1511
{
1512
    T0 |= ~T1;
1513
    RETURN();
1514
}
1515

    
1516
/* ori */
1517
void OPPROTO op_ori (void)
1518
{
1519
    T0 |= (uint32_t)PARAM1;
1520
    RETURN();
1521
}
1522

    
1523
/* xor */
1524
void OPPROTO op_xor (void)
1525
{
1526
    T0 ^= T1;
1527
    RETURN();
1528
}
1529

    
1530
/* xori */
1531
void OPPROTO op_xori (void)
1532
{
1533
    T0 ^= (uint32_t)PARAM1;
1534
    RETURN();
1535
}
1536

    
1537
/***                             Integer rotate                            ***/
1538
void OPPROTO op_rotl32_T0_T1 (void)
1539
{
1540
    T0 = rotl32(T0, T1 & 0x1F);
1541
    RETURN();
1542
}
1543

    
1544
void OPPROTO op_rotli32_T0 (void)
1545
{
1546
    T0 = rotl32(T0, PARAM1);
1547
    RETURN();
1548
}
1549

    
1550
#if defined(TARGET_PPC64)
1551
void OPPROTO op_rotl64_T0_T1 (void)
1552
{
1553
    T0 = rotl64(T0, T1 & 0x3F);
1554
    RETURN();
1555
}
1556

    
1557
void OPPROTO op_rotli64_T0 (void)
1558
{
1559
    T0 = rotl64(T0, PARAM1);
1560
    RETURN();
1561
}
1562
#endif
1563

    
1564
/***                             Integer shift                             ***/
1565
/* shift left word */
1566
void OPPROTO op_slw (void)
1567
{
1568
    if (T1 & 0x20) {
1569
        T0 = 0;
1570
    } else {
1571
        T0 = (uint32_t)(T0 << T1);
1572
    }
1573
    RETURN();
1574
}
1575

    
1576
#if defined(TARGET_PPC64)
1577
void OPPROTO op_sld (void)
1578
{
1579
    if (T1 & 0x40) {
1580
        T0 = 0;
1581
    } else {
1582
        T0 = T0 << T1;
1583
    }
1584
    RETURN();
1585
}
1586
#endif
1587

    
1588
/* shift right algebraic word */
1589
void OPPROTO op_sraw (void)
1590
{
1591
    do_sraw();
1592
    RETURN();
1593
}
1594

    
1595
#if defined(TARGET_PPC64)
1596
void OPPROTO op_srad (void)
1597
{
1598
    do_srad();
1599
    RETURN();
1600
}
1601
#endif
1602

    
1603
/* shift right algebraic word immediate */
1604
void OPPROTO op_srawi (void)
1605
{
1606
    uint32_t mask = (uint32_t)PARAM2;
1607

    
1608
    T0 = (int32_t)T0 >> PARAM1;
1609
    if ((int32_t)T1 < 0 && (T1 & mask) != 0) {
1610
        xer_ca = 1;
1611
    } else {
1612
        xer_ca = 0;
1613
    }
1614
    RETURN();
1615
}
1616

    
1617
#if defined(TARGET_PPC64)
1618
void OPPROTO op_sradi (void)
1619
{
1620
    uint64_t mask = ((uint64_t)PARAM2 << 32) | (uint64_t)PARAM3;
1621

    
1622
    T0 = (int64_t)T0 >> PARAM1;
1623
    if ((int64_t)T1 < 0 && ((uint64_t)T1 & mask) != 0) {
1624
        xer_ca = 1;
1625
    } else {
1626
        xer_ca = 0;
1627
    }
1628
    RETURN();
1629
}
1630
#endif
1631

    
1632
/* shift right word */
1633
void OPPROTO op_srw (void)
1634
{
1635
    if (T1 & 0x20) {
1636
        T0 = 0;
1637
    } else {
1638
        T0 = (uint32_t)T0 >> T1;
1639
    }
1640
    RETURN();
1641
}
1642

    
1643
#if defined(TARGET_PPC64)
1644
void OPPROTO op_srd (void)
1645
{
1646
    if (T1 & 0x40) {
1647
        T0 = 0;
1648
    } else {
1649
        T0 = (uint64_t)T0 >> T1;
1650
    }
1651
    RETURN();
1652
}
1653
#endif
1654

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

    
1661
void OPPROTO op_sli_T0 (void)
1662
{
1663
    T0 = T0 << PARAM1;
1664
    RETURN();
1665
}
1666

    
1667
void OPPROTO op_sli_T1 (void)
1668
{
1669
    T1 = T1 << PARAM1;
1670
    RETURN();
1671
}
1672

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

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

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

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

    
1701
void OPPROTO op_srli_T1 (void)
1702
{
1703
    T1 = (uint32_t)T1 >> PARAM1;
1704
    RETURN();
1705
}
1706

    
1707
#if defined(TARGET_PPC64)
1708
void OPPROTO op_srli_T1_64 (void)
1709
{
1710
    T1 = (uint64_t)T1 >> PARAM1;
1711
    RETURN();
1712
}
1713
#endif
1714

    
1715
/***                       Floating-Point arithmetic                       ***/
1716
/* fadd - fadd. */
1717
void OPPROTO op_fadd (void)
1718
{
1719
#ifdef CONFIG_SOFTFLOAT
1720
    do_fadd();
1721
#else
1722
    FT0 = float64_add(FT0, FT1, &env->fp_status);
1723
#endif
1724
    RETURN();
1725
}
1726

    
1727
/* fsub - fsub. */
1728
void OPPROTO op_fsub (void)
1729
{
1730
#ifdef CONFIG_SOFTFLOAT
1731
    do_fsub();
1732
#else
1733
    FT0 = float64_sub(FT0, FT1, &env->fp_status);
1734
#endif
1735
    RETURN();
1736
}
1737

    
1738
/* fmul - fmul. */
1739
void OPPROTO op_fmul (void)
1740
{
1741
#ifdef CONFIG_SOFTFLOAT
1742
    do_fmul();
1743
#else
1744
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1745
#endif
1746
    RETURN();
1747
}
1748

    
1749
/* fdiv - fdiv. */
1750
void OPPROTO op_fdiv (void)
1751
{
1752
#ifdef CONFIG_SOFTFLOAT
1753
    do_fdiv();
1754
#else
1755
    FT0 = float64_div(FT0, FT1, &env->fp_status);
1756
#endif
1757
    RETURN();
1758
}
1759

    
1760
/* fsqrt - fsqrt. */
1761
void OPPROTO op_fsqrt (void)
1762
{
1763
    do_fsqrt();
1764
    RETURN();
1765
}
1766

    
1767
/* fre - fre. */
1768
void OPPROTO op_fre (void)
1769
{
1770
    do_fre();
1771
    RETURN();
1772
}
1773

    
1774
/* fres - fres. */
1775
void OPPROTO op_fres (void)
1776
{
1777
    do_fres();
1778
    RETURN();
1779
}
1780

    
1781
/* frsqrte  - frsqrte. */
1782
void OPPROTO op_frsqrte (void)
1783
{
1784
    do_frsqrte();
1785
    RETURN();
1786
}
1787

    
1788
/* fsel - fsel. */
1789
void OPPROTO op_fsel (void)
1790
{
1791
    do_fsel();
1792
    RETURN();
1793
}
1794

    
1795
/***                     Floating-Point multiply-and-add                   ***/
1796
/* fmadd - fmadd. */
1797
void OPPROTO op_fmadd (void)
1798
{
1799
#ifdef CONFIG_SOFTFLOAT
1800
    do_fmadd();
1801
#else
1802
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1803
    FT0 = float64_add(FT0, FT2, &env->fp_status);
1804
#endif
1805
    RETURN();
1806
}
1807

    
1808
/* fmsub - fmsub. */
1809
void OPPROTO op_fmsub (void)
1810
{
1811
#ifdef CONFIG_SOFTFLOAT
1812
    do_fmsub();
1813
#else
1814
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1815
    FT0 = float64_sub(FT0, FT2, &env->fp_status);
1816
#endif
1817
    RETURN();
1818
}
1819

    
1820
/* fnmadd - fnmadd. - fnmadds - fnmadds. */
1821
void OPPROTO op_fnmadd (void)
1822
{
1823
    do_fnmadd();
1824
    RETURN();
1825
}
1826

    
1827
/* fnmsub - fnmsub. */
1828
void OPPROTO op_fnmsub (void)
1829
{
1830
    do_fnmsub();
1831
    RETURN();
1832
}
1833

    
1834
/***                     Floating-Point round & convert                    ***/
1835
/* frsp - frsp. */
1836
void OPPROTO op_frsp (void)
1837
{
1838
#ifdef CONFIG_SOFTFLOAT
1839
    do_frsp();
1840
#else
1841
    FT0 = float64_to_float32(FT0, &env->fp_status);
1842
#endif
1843
    RETURN();
1844
}
1845

    
1846
/* fctiw - fctiw. */
1847
void OPPROTO op_fctiw (void)
1848
{
1849
    do_fctiw();
1850
    RETURN();
1851
}
1852

    
1853
/* fctiwz - fctiwz. */
1854
void OPPROTO op_fctiwz (void)
1855
{
1856
    do_fctiwz();
1857
    RETURN();
1858
}
1859

    
1860
#if defined(TARGET_PPC64)
1861
/* fcfid - fcfid. */
1862
void OPPROTO op_fcfid (void)
1863
{
1864
    do_fcfid();
1865
    RETURN();
1866
}
1867

    
1868
/* fctid - fctid. */
1869
void OPPROTO op_fctid (void)
1870
{
1871
    do_fctid();
1872
    RETURN();
1873
}
1874

    
1875
/* fctidz - fctidz. */
1876
void OPPROTO op_fctidz (void)
1877
{
1878
    do_fctidz();
1879
    RETURN();
1880
}
1881
#endif
1882

    
1883
void OPPROTO op_frin (void)
1884
{
1885
    do_frin();
1886
    RETURN();
1887
}
1888

    
1889
void OPPROTO op_friz (void)
1890
{
1891
    do_friz();
1892
    RETURN();
1893
}
1894

    
1895
void OPPROTO op_frip (void)
1896
{
1897
    do_frip();
1898
    RETURN();
1899
}
1900

    
1901
void OPPROTO op_frim (void)
1902
{
1903
    do_frim();
1904
    RETURN();
1905
}
1906

    
1907
/***                         Floating-Point compare                        ***/
1908
/* fcmpu */
1909
void OPPROTO op_fcmpu (void)
1910
{
1911
    do_fcmpu();
1912
    RETURN();
1913
}
1914

    
1915
/* fcmpo */
1916
void OPPROTO op_fcmpo (void)
1917
{
1918
    do_fcmpo();
1919
    RETURN();
1920
}
1921

    
1922
/***                         Floating-point move                           ***/
1923
/* fabs */
1924
void OPPROTO op_fabs (void)
1925
{
1926
    FT0 = float64_abs(FT0);
1927
    RETURN();
1928
}
1929

    
1930
/* fnabs */
1931
void OPPROTO op_fnabs (void)
1932
{
1933
    FT0 = float64_abs(FT0);
1934
    FT0 = float64_chs(FT0);
1935
    RETURN();
1936
}
1937

    
1938
/* fneg */
1939
void OPPROTO op_fneg (void)
1940
{
1941
    FT0 = float64_chs(FT0);
1942
    RETURN();
1943
}
1944

    
1945
/* Load and store */
1946
#define MEMSUFFIX _raw
1947
#include "op_helper.h"
1948
#include "op_mem.h"
1949
#if !defined(CONFIG_USER_ONLY)
1950
#define MEMSUFFIX _user
1951
#include "op_helper.h"
1952
#include "op_mem.h"
1953
#define MEMSUFFIX _kernel
1954
#include "op_helper.h"
1955
#include "op_mem.h"
1956
#define MEMSUFFIX _hypv
1957
#include "op_helper.h"
1958
#include "op_mem.h"
1959
#endif
1960

    
1961
/* Special op to check and maybe clear reservation */
1962
void OPPROTO op_check_reservation (void)
1963
{
1964
    if ((uint32_t)env->reserve == (uint32_t)(T0 & ~0x00000003))
1965
        env->reserve = (target_ulong)-1ULL;
1966
    RETURN();
1967
}
1968

    
1969
#if defined(TARGET_PPC64)
1970
void OPPROTO op_check_reservation_64 (void)
1971
{
1972
    if ((uint64_t)env->reserve == (uint64_t)(T0 & ~0x00000003))
1973
        env->reserve = (target_ulong)-1ULL;
1974
    RETURN();
1975
}
1976
#endif
1977

    
1978
void OPPROTO op_wait (void)
1979
{
1980
    env->halted = 1;
1981
    RETURN();
1982
}
1983

    
1984
/* Return from interrupt */
1985
#if !defined(CONFIG_USER_ONLY)
1986
void OPPROTO op_rfi (void)
1987
{
1988
    do_rfi();
1989
    RETURN();
1990
}
1991

    
1992
#if defined(TARGET_PPC64)
1993
void OPPROTO op_rfid (void)
1994
{
1995
    do_rfid();
1996
    RETURN();
1997
}
1998

    
1999
void OPPROTO op_hrfid (void)
2000
{
2001
    do_hrfid();
2002
    RETURN();
2003
}
2004
#endif
2005

    
2006
/* Exception vectors */
2007
void OPPROTO op_store_excp_prefix (void)
2008
{
2009
    T0 &= env->ivpr_mask;
2010
    env->excp_prefix = T0;
2011
    RETURN();
2012
}
2013

    
2014
void OPPROTO op_store_excp_vector (void)
2015
{
2016
    T0 &= env->ivor_mask;
2017
    env->excp_vectors[PARAM1] = T0;
2018
    RETURN();
2019
}
2020
#endif
2021

    
2022
/* Trap word */
2023
void OPPROTO op_tw (void)
2024
{
2025
    do_tw(PARAM1);
2026
    RETURN();
2027
}
2028

    
2029
#if defined(TARGET_PPC64)
2030
void OPPROTO op_td (void)
2031
{
2032
    do_td(PARAM1);
2033
    RETURN();
2034
}
2035
#endif
2036

    
2037
#if !defined(CONFIG_USER_ONLY)
2038
/* tlbia */
2039
void OPPROTO op_tlbia (void)
2040
{
2041
    ppc_tlb_invalidate_all(env);
2042
    RETURN();
2043
}
2044

    
2045
/* tlbie */
2046
void OPPROTO op_tlbie (void)
2047
{
2048
    ppc_tlb_invalidate_one(env, (uint32_t)T0);
2049
    RETURN();
2050
}
2051

    
2052
#if defined(TARGET_PPC64)
2053
void OPPROTO op_tlbie_64 (void)
2054
{
2055
    ppc_tlb_invalidate_one(env, T0);
2056
    RETURN();
2057
}
2058
#endif
2059

    
2060
#if defined(TARGET_PPC64)
2061
void OPPROTO op_slbia (void)
2062
{
2063
    ppc_slb_invalidate_all(env);
2064
    RETURN();
2065
}
2066

    
2067
void OPPROTO op_slbie (void)
2068
{
2069
    ppc_slb_invalidate_one(env, (uint32_t)T0);
2070
    RETURN();
2071
}
2072

    
2073
void OPPROTO op_slbie_64 (void)
2074
{
2075
    ppc_slb_invalidate_one(env, T0);
2076
    RETURN();
2077
}
2078
#endif
2079
#endif
2080

    
2081
#if !defined(CONFIG_USER_ONLY)
2082
/* PowerPC 602/603/755 software TLB load instructions */
2083
void OPPROTO op_6xx_tlbld (void)
2084
{
2085
    do_load_6xx_tlb(0);
2086
    RETURN();
2087
}
2088

    
2089
void OPPROTO op_6xx_tlbli (void)
2090
{
2091
    do_load_6xx_tlb(1);
2092
    RETURN();
2093
}
2094

    
2095
/* PowerPC 74xx software TLB load instructions */
2096
void OPPROTO op_74xx_tlbld (void)
2097
{
2098
    do_load_74xx_tlb(0);
2099
    RETURN();
2100
}
2101

    
2102
void OPPROTO op_74xx_tlbli (void)
2103
{
2104
    do_load_74xx_tlb(1);
2105
    RETURN();
2106
}
2107
#endif
2108

    
2109
/* 601 specific */
2110
void OPPROTO op_load_601_rtcl (void)
2111
{
2112
    T0 = cpu_ppc601_load_rtcl(env);
2113
    RETURN();
2114
}
2115

    
2116
void OPPROTO op_load_601_rtcu (void)
2117
{
2118
    T0 = cpu_ppc601_load_rtcu(env);
2119
    RETURN();
2120
}
2121

    
2122
#if !defined(CONFIG_USER_ONLY)
2123
void OPPROTO op_store_601_rtcl (void)
2124
{
2125
    cpu_ppc601_store_rtcl(env, T0);
2126
    RETURN();
2127
}
2128

    
2129
void OPPROTO op_store_601_rtcu (void)
2130
{
2131
    cpu_ppc601_store_rtcu(env, T0);
2132
    RETURN();
2133
}
2134

    
2135
void OPPROTO op_store_hid0_601 (void)
2136
{
2137
    do_store_hid0_601();
2138
    RETURN();
2139
}
2140

    
2141
void OPPROTO op_load_601_bat (void)
2142
{
2143
    T0 = env->IBAT[PARAM1][PARAM2];
2144
    RETURN();
2145
}
2146

    
2147
void OPPROTO op_store_601_batl (void)
2148
{
2149
    do_store_ibatl_601(env, PARAM1, T0);
2150
    RETURN();
2151
}
2152

    
2153
void OPPROTO op_store_601_batu (void)
2154
{
2155
    do_store_ibatu_601(env, PARAM1, T0);
2156
    RETURN();
2157
}
2158
#endif /* !defined(CONFIG_USER_ONLY) */
2159

    
2160
/* PowerPC 601 specific instructions (POWER bridge) */
2161
/* XXX: those micro-ops need tests ! */
2162
void OPPROTO op_POWER_abs (void)
2163
{
2164
    if ((int32_t)T0 == INT32_MIN)
2165
        T0 = INT32_MAX;
2166
    else if ((int32_t)T0 < 0)
2167
        T0 = -T0;
2168
    RETURN();
2169
}
2170

    
2171
void OPPROTO op_POWER_abso (void)
2172
{
2173
    do_POWER_abso();
2174
    RETURN();
2175
}
2176

    
2177
void OPPROTO op_POWER_clcs (void)
2178
{
2179
    do_POWER_clcs();
2180
    RETURN();
2181
}
2182

    
2183
void OPPROTO op_POWER_div (void)
2184
{
2185
    do_POWER_div();
2186
    RETURN();
2187
}
2188

    
2189
void OPPROTO op_POWER_divo (void)
2190
{
2191
    do_POWER_divo();
2192
    RETURN();
2193
}
2194

    
2195
void OPPROTO op_POWER_divs (void)
2196
{
2197
    do_POWER_divs();
2198
    RETURN();
2199
}
2200

    
2201
void OPPROTO op_POWER_divso (void)
2202
{
2203
    do_POWER_divso();
2204
    RETURN();
2205
}
2206

    
2207
void OPPROTO op_POWER_doz (void)
2208
{
2209
    if ((int32_t)T1 > (int32_t)T0)
2210
        T0 = T1 - T0;
2211
    else
2212
        T0 = 0;
2213
    RETURN();
2214
}
2215

    
2216
void OPPROTO op_POWER_dozo (void)
2217
{
2218
    do_POWER_dozo();
2219
    RETURN();
2220
}
2221

    
2222
void OPPROTO op_load_xer_cmp (void)
2223
{
2224
    T2 = xer_cmp;
2225
    RETURN();
2226
}
2227

    
2228
void OPPROTO op_POWER_maskg (void)
2229
{
2230
    do_POWER_maskg();
2231
    RETURN();
2232
}
2233

    
2234
void OPPROTO op_POWER_maskir (void)
2235
{
2236
    T0 = (T0 & ~T2) | (T1 & T2);
2237
    RETURN();
2238
}
2239

    
2240
void OPPROTO op_POWER_mul (void)
2241
{
2242
    uint64_t tmp;
2243

    
2244
    tmp = (uint64_t)T0 * (uint64_t)T1;
2245
    env->spr[SPR_MQ] = tmp >> 32;
2246
    T0 = tmp;
2247
    RETURN();
2248
}
2249

    
2250
void OPPROTO op_POWER_mulo (void)
2251
{
2252
    do_POWER_mulo();
2253
    RETURN();
2254
}
2255

    
2256
void OPPROTO op_POWER_nabs (void)
2257
{
2258
    if (T0 > 0)
2259
        T0 = -T0;
2260
    RETURN();
2261
}
2262

    
2263
void OPPROTO op_POWER_nabso (void)
2264
{
2265
    /* nabs never overflows */
2266
    if (T0 > 0)
2267
        T0 = -T0;
2268
    xer_ov = 0;
2269
    RETURN();
2270
}
2271

    
2272
/* XXX: factorise POWER rotates... */
2273
void OPPROTO op_POWER_rlmi (void)
2274
{
2275
    T0 = rotl32(T0, T2) & PARAM1;
2276
    T0 |= T1 & (uint32_t)PARAM2;
2277
    RETURN();
2278
}
2279

    
2280
void OPPROTO op_POWER_rrib (void)
2281
{
2282
    T2 &= 0x1FUL;
2283
    T0 = rotl32(T0 & INT32_MIN, T2);
2284
    T0 |= T1 & ~rotl32(INT32_MIN, T2);
2285
    RETURN();
2286
}
2287

    
2288
void OPPROTO op_POWER_sle (void)
2289
{
2290
    T1 &= 0x1FUL;
2291
    env->spr[SPR_MQ] = rotl32(T0, T1);
2292
    T0 = T0 << T1;
2293
    RETURN();
2294
}
2295

    
2296
void OPPROTO op_POWER_sleq (void)
2297
{
2298
    uint32_t tmp = env->spr[SPR_MQ];
2299

    
2300
    T1 &= 0x1FUL;
2301
    env->spr[SPR_MQ] = rotl32(T0, T1);
2302
    T0 = T0 << T1;
2303
    T0 |= tmp >> (32 - T1);
2304
    RETURN();
2305
}
2306

    
2307
void OPPROTO op_POWER_sllq (void)
2308
{
2309
    uint32_t msk = UINT32_MAX;
2310

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

    
2320
void OPPROTO op_POWER_slq (void)
2321
{
2322
    uint32_t msk = UINT32_MAX, tmp;
2323

    
2324
    msk = msk << (T1 & 0x1FUL);
2325
    if (T1 & 0x20UL)
2326
        msk = ~msk;
2327
    T1 &= 0x1FUL;
2328
    tmp = rotl32(T0, T1);
2329
    T0 = tmp & msk;
2330
    env->spr[SPR_MQ] = tmp;
2331
    RETURN();
2332
}
2333

    
2334
void OPPROTO op_POWER_sraq (void)
2335
{
2336
    env->spr[SPR_MQ] = rotl32(T0, 32 - (T1 & 0x1FUL));
2337
    if (T1 & 0x20UL)
2338
        T0 = UINT32_MAX;
2339
    else
2340
        T0 = (int32_t)T0 >> T1;
2341
    RETURN();
2342
}
2343

    
2344
void OPPROTO op_POWER_sre (void)
2345
{
2346
    T1 &= 0x1FUL;
2347
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2348
    T0 = (int32_t)T0 >> T1;
2349
    RETURN();
2350
}
2351

    
2352
void OPPROTO op_POWER_srea (void)
2353
{
2354
    T1 &= 0x1FUL;
2355
    env->spr[SPR_MQ] = T0 >> T1;
2356
    T0 = (int32_t)T0 >> T1;
2357
    RETURN();
2358
}
2359

    
2360
void OPPROTO op_POWER_sreq (void)
2361
{
2362
    uint32_t tmp;
2363
    int32_t msk;
2364

    
2365
    T1 &= 0x1FUL;
2366
    msk = INT32_MIN >> T1;
2367
    tmp = env->spr[SPR_MQ];
2368
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2369
    T0 = T0 >> T1;
2370
    T0 |= tmp & msk;
2371
    RETURN();
2372
}
2373

    
2374
void OPPROTO op_POWER_srlq (void)
2375
{
2376
    uint32_t tmp;
2377
    int32_t msk;
2378

    
2379
    msk = INT32_MIN >> (T1 & 0x1FUL);
2380
    if (T1 & 0x20UL)
2381
        msk = ~msk;
2382
    T1 &= 0x1FUL;
2383
    tmp = env->spr[SPR_MQ];
2384
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2385
    T0 = T0 >> T1;
2386
    T0 &= msk;
2387
    T0 |= tmp & ~msk;
2388
    RETURN();
2389
}
2390

    
2391
void OPPROTO op_POWER_srq (void)
2392
{
2393
    T1 &= 0x1FUL;
2394
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2395
    T0 = T0 >> T1;
2396
    RETURN();
2397
}
2398

    
2399
/* POWER instructions not implemented in PowerPC 601 */
2400
#if !defined(CONFIG_USER_ONLY)
2401
void OPPROTO op_POWER_mfsri (void)
2402
{
2403
    T1 = T0 >> 28;
2404
    T0 = env->sr[T1];
2405
    RETURN();
2406
}
2407

    
2408
void OPPROTO op_POWER_rac (void)
2409
{
2410
    do_POWER_rac();
2411
    RETURN();
2412
}
2413

    
2414
void OPPROTO op_POWER_rfsvc (void)
2415
{
2416
    do_POWER_rfsvc();
2417
    RETURN();
2418
}
2419
#endif
2420

    
2421
/* PowerPC 602 specific instruction */
2422
#if !defined(CONFIG_USER_ONLY)
2423
void OPPROTO op_602_mfrom (void)
2424
{
2425
    do_op_602_mfrom();
2426
    RETURN();
2427
}
2428
#endif
2429

    
2430
/* PowerPC 4xx specific micro-ops */
2431
void OPPROTO op_405_add_T0_T2 (void)
2432
{
2433
    T0 = (int32_t)T0 + (int32_t)T2;
2434
    RETURN();
2435
}
2436

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

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

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

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

    
2461
void OPPROTO op_405_mullhw (void)
2462
{
2463
    T0 = ((int16_t)T0) * ((int16_t)T1);
2464
    RETURN();
2465
}
2466

    
2467
void OPPROTO op_405_mullhwu (void)
2468
{
2469
    T0 = ((uint16_t)T0) * ((uint16_t)T1);
2470
    RETURN();
2471
}
2472

    
2473
void OPPROTO op_405_check_sat (void)
2474
{
2475
    do_405_check_sat();
2476
    RETURN();
2477
}
2478

    
2479
void OPPROTO op_405_check_ovu (void)
2480
{
2481
    if (likely(T0 >= T2)) {
2482
        xer_ov = 0;
2483
    } else {
2484
        xer_ov = 1;
2485
        xer_so = 1;
2486
    }
2487
    RETURN();
2488
}
2489

    
2490
void OPPROTO op_405_check_satu (void)
2491
{
2492
    if (unlikely(T0 < T2)) {
2493
        /* Saturate result */
2494
        T0 = UINT32_MAX;
2495
    }
2496
    RETURN();
2497
}
2498

    
2499
void OPPROTO op_load_dcr (void)
2500
{
2501
    do_load_dcr();
2502
    RETURN();
2503
}
2504

    
2505
void OPPROTO op_store_dcr (void)
2506
{
2507
    do_store_dcr();
2508
    RETURN();
2509
}
2510

    
2511
#if !defined(CONFIG_USER_ONLY)
2512
/* Return from critical interrupt :
2513
 * same as rfi, except nip & MSR are loaded from SRR2/3 instead of SRR0/1
2514
 */
2515
void OPPROTO op_40x_rfci (void)
2516
{
2517
    do_40x_rfci();
2518
    RETURN();
2519
}
2520

    
2521
void OPPROTO op_rfci (void)
2522
{
2523
    do_rfci();
2524
    RETURN();
2525
}
2526

    
2527
void OPPROTO op_rfdi (void)
2528
{
2529
    do_rfdi();
2530
    RETURN();
2531
}
2532

    
2533
void OPPROTO op_rfmci (void)
2534
{
2535
    do_rfmci();
2536
    RETURN();
2537
}
2538

    
2539
void OPPROTO op_wrte (void)
2540
{
2541
    /* We don't call do_store_msr here as we won't trigger
2542
     * any special case nor change hflags
2543
     */
2544
    T0 &= 1 << MSR_EE;
2545
    env->msr &= ~(1 << MSR_EE);
2546
    env->msr |= T0;
2547
    RETURN();
2548
}
2549

    
2550
void OPPROTO op_440_tlbre (void)
2551
{
2552
    do_440_tlbre(PARAM1);
2553
    RETURN();
2554
}
2555

    
2556
void OPPROTO op_440_tlbsx (void)
2557
{
2558
    T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_440_MMUCR] & 0xFF);
2559
    RETURN();
2560
}
2561

    
2562
void OPPROTO op_4xx_tlbsx_check (void)
2563
{
2564
    int tmp;
2565

    
2566
    tmp = xer_so;
2567
    if ((int)T0 != -1)
2568
        tmp |= 0x02;
2569
    env->crf[0] = tmp;
2570
    RETURN();
2571
}
2572

    
2573
void OPPROTO op_440_tlbwe (void)
2574
{
2575
    do_440_tlbwe(PARAM1);
2576
    RETURN();
2577
}
2578

    
2579
void OPPROTO op_4xx_tlbre_lo (void)
2580
{
2581
    do_4xx_tlbre_lo();
2582
    RETURN();
2583
}
2584

    
2585
void OPPROTO op_4xx_tlbre_hi (void)
2586
{
2587
    do_4xx_tlbre_hi();
2588
    RETURN();
2589
}
2590

    
2591
void OPPROTO op_4xx_tlbsx (void)
2592
{
2593
    T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_40x_PID]);
2594
    RETURN();
2595
}
2596

    
2597
void OPPROTO op_4xx_tlbwe_lo (void)
2598
{
2599
    do_4xx_tlbwe_lo();
2600
    RETURN();
2601
}
2602

    
2603
void OPPROTO op_4xx_tlbwe_hi (void)
2604
{
2605
    do_4xx_tlbwe_hi();
2606
    RETURN();
2607
}
2608
#endif
2609

    
2610
/* SPR micro-ops */
2611
/* 440 specific */
2612
void OPPROTO op_440_dlmzb (void)
2613
{
2614
    do_440_dlmzb();
2615
    RETURN();
2616
}
2617

    
2618
void OPPROTO op_440_dlmzb_update_Rc (void)
2619
{
2620
    if (T0 == 8)
2621
        T0 = 0x2;
2622
    else if (T0 < 4)
2623
        T0 = 0x4;
2624
    else
2625
        T0 = 0x8;
2626
    RETURN();
2627
}
2628

    
2629
#if !defined(CONFIG_USER_ONLY)
2630
void OPPROTO op_store_pir (void)
2631
{
2632
    env->spr[SPR_PIR] = T0 & 0x0000000FUL;
2633
    RETURN();
2634
}
2635

    
2636
void OPPROTO op_load_403_pb (void)
2637
{
2638
    do_load_403_pb(PARAM1);
2639
    RETURN();
2640
}
2641

    
2642
void OPPROTO op_store_403_pb (void)
2643
{
2644
    do_store_403_pb(PARAM1);
2645
    RETURN();
2646
}
2647

    
2648
void OPPROTO op_load_40x_pit (void)
2649
{
2650
    T0 = load_40x_pit(env);
2651
    RETURN();
2652
}
2653

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

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

    
2666
void OPPROTO op_store_40x_sler (void)
2667
{
2668
    store_40x_sler(env, T0);
2669
    RETURN();
2670
}
2671

    
2672
void OPPROTO op_store_booke_tcr (void)
2673
{
2674
    store_booke_tcr(env, T0);
2675
    RETURN();
2676
}
2677

    
2678
void OPPROTO op_store_booke_tsr (void)
2679
{
2680
    store_booke_tsr(env, T0);
2681
    RETURN();
2682
}
2683
#endif /* !defined(CONFIG_USER_ONLY) */
2684

    
2685
/* SPE extension */
2686
void OPPROTO op_splatw_T1_64 (void)
2687
{
2688
    T1_64 = (T1_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL);
2689
    RETURN();
2690
}
2691

    
2692
void OPPROTO op_splatwi_T0_64 (void)
2693
{
2694
    uint64_t tmp = PARAM1;
2695

    
2696
    T0_64 = (tmp << 32) | tmp;
2697
    RETURN();
2698
}
2699

    
2700
void OPPROTO op_splatwi_T1_64 (void)
2701
{
2702
    uint64_t tmp = PARAM1;
2703

    
2704
    T1_64 = (tmp << 32) | tmp;
2705
    RETURN();
2706
}
2707

    
2708
void OPPROTO op_extsh_T1_64 (void)
2709
{
2710
    T1_64 = (int32_t)((int16_t)T1_64);
2711
    RETURN();
2712
}
2713

    
2714
void OPPROTO op_sli16_T1_64 (void)
2715
{
2716
    T1_64 = T1_64 << 16;
2717
    RETURN();
2718
}
2719

    
2720
void OPPROTO op_sli32_T1_64 (void)
2721
{
2722
    T1_64 = T1_64 << 32;
2723
    RETURN();
2724
}
2725

    
2726
void OPPROTO op_srli32_T1_64 (void)
2727
{
2728
    T1_64 = T1_64 >> 32;
2729
    RETURN();
2730
}
2731

    
2732
void OPPROTO op_evsel (void)
2733
{
2734
    do_evsel();
2735
    RETURN();
2736
}
2737

    
2738
void OPPROTO op_evaddw (void)
2739
{
2740
    do_evaddw();
2741
    RETURN();
2742
}
2743

    
2744
void OPPROTO op_evsubfw (void)
2745
{
2746
    do_evsubfw();
2747
    RETURN();
2748
}
2749

    
2750
void OPPROTO op_evneg (void)
2751
{
2752
    do_evneg();
2753
    RETURN();
2754
}
2755

    
2756
void OPPROTO op_evabs (void)
2757
{
2758
    do_evabs();
2759
    RETURN();
2760
}
2761

    
2762
void OPPROTO op_evextsh (void)
2763
{
2764
    T0_64 = ((uint64_t)((int32_t)(int16_t)(T0_64 >> 32)) << 32) |
2765
        (uint64_t)((int32_t)(int16_t)T0_64);
2766
    RETURN();
2767
}
2768

    
2769
void OPPROTO op_evextsb (void)
2770
{
2771
    T0_64 = ((uint64_t)((int32_t)(int8_t)(T0_64 >> 32)) << 32) |
2772
        (uint64_t)((int32_t)(int8_t)T0_64);
2773
    RETURN();
2774
}
2775

    
2776
void OPPROTO op_evcntlzw (void)
2777
{
2778
    do_evcntlzw();
2779
    RETURN();
2780
}
2781

    
2782
void OPPROTO op_evrndw (void)
2783
{
2784
    do_evrndw();
2785
    RETURN();
2786
}
2787

    
2788
void OPPROTO op_brinc (void)
2789
{
2790
    do_brinc();
2791
    RETURN();
2792
}
2793

    
2794
void OPPROTO op_evcntlsw (void)
2795
{
2796
    do_evcntlsw();
2797
    RETURN();
2798
}
2799

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

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

    
2812
void OPPROTO op_evor (void)
2813
{
2814
    T0_64 |= T1_64;
2815
    RETURN();
2816
}
2817

    
2818
void OPPROTO op_evxor (void)
2819
{
2820
    T0_64 ^= T1_64;
2821
    RETURN();
2822
}
2823

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

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

    
2836
void OPPROTO op_evorc (void)
2837
{
2838
    T0_64 |= ~T1_64;
2839
    RETURN();
2840
}
2841

    
2842
void OPPROTO op_evnand (void)
2843
{
2844
    T0_64 = ~(T0_64 & T1_64);
2845
    RETURN();
2846
}
2847

    
2848
void OPPROTO op_evsrws (void)
2849
{
2850
    do_evsrws();
2851
    RETURN();
2852
}
2853

    
2854
void OPPROTO op_evsrwu (void)
2855
{
2856
    do_evsrwu();
2857
    RETURN();
2858
}
2859

    
2860
void OPPROTO op_evslw (void)
2861
{
2862
    do_evslw();
2863
    RETURN();
2864
}
2865

    
2866
void OPPROTO op_evrlw (void)
2867
{
2868
    do_evrlw();
2869
    RETURN();
2870
}
2871

    
2872
void OPPROTO op_evmergelo (void)
2873
{
2874
    T0_64 = (T0_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL);
2875
    RETURN();
2876
}
2877

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

    
2884
void OPPROTO op_evmergelohi (void)
2885
{
2886
    T0_64 = (T0_64 << 32) | (T1_64 >> 32);
2887
    RETURN();
2888
}
2889

    
2890
void OPPROTO op_evmergehilo (void)
2891
{
2892
    T0_64 = (T0_64 & 0xFFFFFFFF00000000ULL) | (T1_64 & 0x00000000FFFFFFFFULL);
2893
    RETURN();
2894
}
2895

    
2896
void OPPROTO op_evcmpgts (void)
2897
{
2898
    do_evcmpgts();
2899
    RETURN();
2900
}
2901

    
2902
void OPPROTO op_evcmpgtu (void)
2903
{
2904
    do_evcmpgtu();
2905
    RETURN();
2906
}
2907

    
2908
void OPPROTO op_evcmplts (void)
2909
{
2910
    do_evcmplts();
2911
    RETURN();
2912
}
2913

    
2914
void OPPROTO op_evcmpltu (void)
2915
{
2916
    do_evcmpltu();
2917
    RETURN();
2918
}
2919

    
2920
void OPPROTO op_evcmpeq (void)
2921
{
2922
    do_evcmpeq();
2923
    RETURN();
2924
}
2925

    
2926
void OPPROTO op_evfssub (void)
2927
{
2928
    do_evfssub();
2929
    RETURN();
2930
}
2931

    
2932
void OPPROTO op_evfsadd (void)
2933
{
2934
    do_evfsadd();
2935
    RETURN();
2936
}
2937

    
2938
void OPPROTO op_evfsnabs (void)
2939
{
2940
    do_evfsnabs();
2941
    RETURN();
2942
}
2943

    
2944
void OPPROTO op_evfsabs (void)
2945
{
2946
    do_evfsabs();
2947
    RETURN();
2948
}
2949

    
2950
void OPPROTO op_evfsneg (void)
2951
{
2952
    do_evfsneg();
2953
    RETURN();
2954
}
2955

    
2956
void OPPROTO op_evfsdiv (void)
2957
{
2958
    do_evfsdiv();
2959
    RETURN();
2960
}
2961

    
2962
void OPPROTO op_evfsmul (void)
2963
{
2964
    do_evfsmul();
2965
    RETURN();
2966
}
2967

    
2968
void OPPROTO op_evfscmplt (void)
2969
{
2970
    do_evfscmplt();
2971
    RETURN();
2972
}
2973

    
2974
void OPPROTO op_evfscmpgt (void)
2975
{
2976
    do_evfscmpgt();
2977
    RETURN();
2978
}
2979

    
2980
void OPPROTO op_evfscmpeq (void)
2981
{
2982
    do_evfscmpeq();
2983
    RETURN();
2984
}
2985

    
2986
void OPPROTO op_evfscfsi (void)
2987
{
2988
    do_evfscfsi();
2989
    RETURN();
2990
}
2991

    
2992
void OPPROTO op_evfscfui (void)
2993
{
2994
    do_evfscfui();
2995
    RETURN();
2996
}
2997

    
2998
void OPPROTO op_evfscfsf (void)
2999
{
3000
    do_evfscfsf();
3001
    RETURN();
3002
}
3003

    
3004
void OPPROTO op_evfscfuf (void)
3005
{
3006
    do_evfscfuf();
3007
    RETURN();
3008
}
3009

    
3010
void OPPROTO op_evfsctsi (void)
3011
{
3012
    do_evfsctsi();
3013
    RETURN();
3014
}
3015

    
3016
void OPPROTO op_evfsctui (void)
3017
{
3018
    do_evfsctui();
3019
    RETURN();
3020
}
3021

    
3022
void OPPROTO op_evfsctsf (void)
3023
{
3024
    do_evfsctsf();
3025
    RETURN();
3026
}
3027

    
3028
void OPPROTO op_evfsctuf (void)
3029
{
3030
    do_evfsctuf();
3031
    RETURN();
3032
}
3033

    
3034
void OPPROTO op_evfsctuiz (void)
3035
{
3036
    do_evfsctuiz();
3037
    RETURN();
3038
}
3039

    
3040
void OPPROTO op_evfsctsiz (void)
3041
{
3042
    do_evfsctsiz();
3043
    RETURN();
3044
}
3045

    
3046
void OPPROTO op_evfststlt (void)
3047
{
3048
    do_evfststlt();
3049
    RETURN();
3050
}
3051

    
3052
void OPPROTO op_evfststgt (void)
3053
{
3054
    do_evfststgt();
3055
    RETURN();
3056
}
3057

    
3058
void OPPROTO op_evfststeq (void)
3059
{
3060
    do_evfststeq();
3061
    RETURN();
3062
}
3063

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

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

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

    
3082
void OPPROTO op_efsabs (void)
3083
{
3084
    T0_64 = _do_efsabs(T0_64);
3085
    RETURN();
3086
}
3087

    
3088
void OPPROTO op_efsneg (void)
3089
{
3090
    T0_64 = _do_efsneg(T0_64);
3091
    RETURN();
3092
}
3093

    
3094
void OPPROTO op_efsdiv (void)
3095
{
3096
    T0_64 = _do_efsdiv(T0_64, T1_64);
3097
    RETURN();
3098
}
3099

    
3100
void OPPROTO op_efsmul (void)
3101
{
3102
    T0_64 = _do_efsmul(T0_64, T1_64);
3103
    RETURN();
3104
}
3105

    
3106
void OPPROTO op_efscmplt (void)
3107
{
3108
    do_efscmplt();
3109
    RETURN();
3110
}
3111

    
3112
void OPPROTO op_efscmpgt (void)
3113
{
3114
    do_efscmpgt();
3115
    RETURN();
3116
}
3117

    
3118
void OPPROTO op_efscfd (void)
3119
{
3120
    do_efscfd();
3121
    RETURN();
3122
}
3123

    
3124
void OPPROTO op_efscmpeq (void)
3125
{
3126
    do_efscmpeq();
3127
    RETURN();
3128
}
3129

    
3130
void OPPROTO op_efscfsi (void)
3131
{
3132
    do_efscfsi();
3133
    RETURN();
3134
}
3135

    
3136
void OPPROTO op_efscfui (void)
3137
{
3138
    do_efscfui();
3139
    RETURN();
3140
}
3141

    
3142
void OPPROTO op_efscfsf (void)
3143
{
3144
    do_efscfsf();
3145
    RETURN();
3146
}
3147

    
3148
void OPPROTO op_efscfuf (void)
3149
{
3150
    do_efscfuf();
3151
    RETURN();
3152
}
3153

    
3154
void OPPROTO op_efsctsi (void)
3155
{
3156
    do_efsctsi();
3157
    RETURN();
3158
}
3159

    
3160
void OPPROTO op_efsctui (void)
3161
{
3162
    do_efsctui();
3163
    RETURN();
3164
}
3165

    
3166
void OPPROTO op_efsctsf (void)
3167
{
3168
    do_efsctsf();
3169
    RETURN();
3170
}
3171

    
3172
void OPPROTO op_efsctuf (void)
3173
{
3174
    do_efsctuf();
3175
    RETURN();
3176
}
3177

    
3178
void OPPROTO op_efsctsiz (void)
3179
{
3180
    do_efsctsiz();
3181
    RETURN();
3182
}
3183

    
3184
void OPPROTO op_efsctuiz (void)
3185
{
3186
    do_efsctuiz();
3187
    RETURN();
3188
}
3189

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

    
3196
void OPPROTO op_efststgt (void)
3197
{
3198
    T0 = _do_efststgt(T0_64, T1_64);
3199
    RETURN();
3200
}
3201

    
3202
void OPPROTO op_efststeq (void)
3203
{
3204
    T0 = _do_efststeq(T0_64, T1_64);
3205
    RETURN();
3206
}
3207

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

    
3218
void OPPROTO op_efdadd (void)
3219
{
3220
    CPU_DoubleU u1, u2;
3221
    u1.ll = T0_64;
3222
    u2.ll = T1_64;
3223
    u1.d = float64_add(u1.d, u2.d, &env->spe_status);
3224
    T0_64 = u1.ll;
3225
    RETURN();
3226
}
3227

    
3228
void OPPROTO op_efdcfsid (void)
3229
{
3230
    do_efdcfsi();
3231
    RETURN();
3232
}
3233

    
3234
void OPPROTO op_efdcfuid (void)
3235
{
3236
    do_efdcfui();
3237
    RETURN();
3238
}
3239

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

    
3246
void OPPROTO op_efdabs (void)
3247
{
3248
    T0_64 &= ~0x8000000000000000ULL;
3249
    RETURN();
3250
}
3251

    
3252
void OPPROTO op_efdneg (void)
3253
{
3254
    T0_64 ^= 0x8000000000000000ULL;
3255
    RETURN();
3256
}
3257

    
3258
void OPPROTO op_efddiv (void)
3259
{
3260
    CPU_DoubleU u1, u2;
3261
    u1.ll = T0_64;
3262
    u2.ll = T1_64;
3263
    u1.d = float64_div(u1.d, u2.d, &env->spe_status);
3264
    T0_64 = u1.ll;
3265
    RETURN();
3266
}
3267

    
3268
void OPPROTO op_efdmul (void)
3269
{
3270
    CPU_DoubleU u1, u2;
3271
    u1.ll = T0_64;
3272
    u2.ll = T1_64;
3273
    u1.d = float64_mul(u1.d, u2.d, &env->spe_status);
3274
    T0_64 = u1.ll;
3275
    RETURN();
3276
}
3277

    
3278
void OPPROTO op_efdctsidz (void)
3279
{
3280
    do_efdctsiz();
3281
    RETURN();
3282
}
3283

    
3284
void OPPROTO op_efdctuidz (void)
3285
{
3286
    do_efdctuiz();
3287
    RETURN();
3288
}
3289

    
3290
void OPPROTO op_efdcmplt (void)
3291
{
3292
    do_efdcmplt();
3293
    RETURN();
3294
}
3295

    
3296
void OPPROTO op_efdcmpgt (void)
3297
{
3298
    do_efdcmpgt();
3299
    RETURN();
3300
}
3301

    
3302
void OPPROTO op_efdcfs (void)
3303
{
3304
    do_efdcfs();
3305
    RETURN();
3306
}
3307

    
3308
void OPPROTO op_efdcmpeq (void)
3309
{
3310
    do_efdcmpeq();
3311
    RETURN();
3312
}
3313

    
3314
void OPPROTO op_efdcfsi (void)
3315
{
3316
    do_efdcfsi();
3317
    RETURN();
3318
}
3319

    
3320
void OPPROTO op_efdcfui (void)
3321
{
3322
    do_efdcfui();
3323
    RETURN();
3324
}
3325

    
3326
void OPPROTO op_efdcfsf (void)
3327
{
3328
    do_efdcfsf();
3329
    RETURN();
3330
}
3331

    
3332
void OPPROTO op_efdcfuf (void)
3333
{
3334
    do_efdcfuf();
3335
    RETURN();
3336
}
3337

    
3338
void OPPROTO op_efdctsi (void)
3339
{
3340
    do_efdctsi();
3341
    RETURN();
3342
}
3343

    
3344
void OPPROTO op_efdctui (void)
3345
{
3346
    do_efdctui();
3347
    RETURN();
3348
}
3349

    
3350
void OPPROTO op_efdctsf (void)
3351
{
3352
    do_efdctsf();
3353
    RETURN();
3354
}
3355

    
3356
void OPPROTO op_efdctuf (void)
3357
{
3358
    do_efdctuf();
3359
    RETURN();
3360
}
3361

    
3362
void OPPROTO op_efdctuiz (void)
3363
{
3364
    do_efdctuiz();
3365
    RETURN();
3366
}
3367

    
3368
void OPPROTO op_efdctsiz (void)
3369
{
3370
    do_efdctsiz();
3371
    RETURN();
3372
}
3373

    
3374
void OPPROTO op_efdtstlt (void)
3375
{
3376
    T0 = _do_efdtstlt(T0_64, T1_64);
3377
    RETURN();
3378
}
3379

    
3380
void OPPROTO op_efdtstgt (void)
3381
{
3382
    T0 = _do_efdtstgt(T0_64, T1_64);
3383
    RETURN();
3384
}
3385

    
3386
void OPPROTO op_efdtsteq (void)
3387
{
3388
    T0 = _do_efdtsteq(T0_64, T1_64);
3389
    RETURN();
3390
}