Statistics
| Branch: | Revision:

root / target-ppc / op.c @ f9fdea6b

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 "helper_regs.h"
26
#include "op_helper.h"
27

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
194
void OPPROTO op_move_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
void OPPROTO op_exit_tb (void)
226
{
227
    EXIT_TB();
228
}
229

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

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

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

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

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

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

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

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

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

    
286
void OPPROTO op_load_xer (void)
287
{
288
    T0 = hreg_load_xer(env);
289
    RETURN();
290
}
291

    
292
void OPPROTO op_store_xer (void)
293
{
294
    hreg_store_xer(env, T0);
295
    RETURN();
296
}
297

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

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

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

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

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

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

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

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

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

    
360
void OPPROTO op_load_msr (void)
361
{
362
    T0 = env->msr;
363
    RETURN();
364
}
365

    
366
void OPPROTO op_store_msr (void)
367
{
368
    do_store_msr();
369
    RETURN();
370
}
371

    
372
#if defined (TARGET_PPC64)
373
void OPPROTO op_store_msr_32 (void)
374
{
375
    T0 = (env->msr & ~0xFFFFFFFFULL) | (T0 & 0xFFFFFFFF);
376
    do_store_msr();
377
    RETURN();
378
}
379
#endif
380

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1929
/* Special op to check and maybe clear reservation */
1930
void OPPROTO op_check_reservation (void)
1931
{
1932
    if ((uint32_t)env->reserve == (uint32_t)(T0 & ~0x00000003))
1933
        env->reserve = -1;
1934
    RETURN();
1935
}
1936

    
1937
#if defined(TARGET_PPC64)
1938
void OPPROTO op_check_reservation_64 (void)
1939
{
1940
    if ((uint64_t)env->reserve == (uint64_t)(T0 & ~0x00000003))
1941
        env->reserve = -1;
1942
    RETURN();
1943
}
1944
#endif
1945

    
1946
void OPPROTO op_wait (void)
1947
{
1948
    env->halted = 1;
1949
    RETURN();
1950
}
1951

    
1952
/* Return from interrupt */
1953
#if !defined(CONFIG_USER_ONLY)
1954
void OPPROTO op_rfi (void)
1955
{
1956
    do_rfi();
1957
    RETURN();
1958
}
1959

    
1960
#if defined(TARGET_PPC64)
1961
void OPPROTO op_rfid (void)
1962
{
1963
    do_rfid();
1964
    RETURN();
1965
}
1966
#endif
1967

    
1968
#if defined(TARGET_PPC64H)
1969
void OPPROTO op_hrfid (void)
1970
{
1971
    do_hrfid();
1972
    RETURN();
1973
}
1974
#endif
1975

    
1976
/* Exception vectors */
1977
void OPPROTO op_store_excp_prefix (void)
1978
{
1979
    T0 &= env->ivpr_mask;
1980
    env->excp_prefix = T0;
1981
    RETURN();
1982
}
1983

    
1984
void OPPROTO op_store_excp_vector (void)
1985
{
1986
    T0 &= env->ivor_mask;
1987
    env->excp_vectors[PARAM1] = T0;
1988
    RETURN();
1989
}
1990
#endif
1991

    
1992
/* Trap word */
1993
void OPPROTO op_tw (void)
1994
{
1995
    do_tw(PARAM1);
1996
    RETURN();
1997
}
1998

    
1999
#if defined(TARGET_PPC64)
2000
void OPPROTO op_td (void)
2001
{
2002
    do_td(PARAM1);
2003
    RETURN();
2004
}
2005
#endif
2006

    
2007
#if !defined(CONFIG_USER_ONLY)
2008
/* tlbia */
2009
void OPPROTO op_tlbia (void)
2010
{
2011
    ppc_tlb_invalidate_all(env);
2012
    RETURN();
2013
}
2014

    
2015
/* tlbie */
2016
void OPPROTO op_tlbie (void)
2017
{
2018
    ppc_tlb_invalidate_one(env, (uint32_t)T0);
2019
    RETURN();
2020
}
2021

    
2022
#if defined(TARGET_PPC64)
2023
void OPPROTO op_tlbie_64 (void)
2024
{
2025
    ppc_tlb_invalidate_one(env, T0);
2026
    RETURN();
2027
}
2028
#endif
2029

    
2030
#if defined(TARGET_PPC64)
2031
void OPPROTO op_slbia (void)
2032
{
2033
    ppc_slb_invalidate_all(env);
2034
    RETURN();
2035
}
2036

    
2037
void OPPROTO op_slbie (void)
2038
{
2039
    ppc_slb_invalidate_one(env, (uint32_t)T0);
2040
    RETURN();
2041
}
2042

    
2043
void OPPROTO op_slbie_64 (void)
2044
{
2045
    ppc_slb_invalidate_one(env, T0);
2046
    RETURN();
2047
}
2048
#endif
2049
#endif
2050

    
2051
#if !defined(CONFIG_USER_ONLY)
2052
/* PowerPC 602/603/755 software TLB load instructions */
2053
void OPPROTO op_6xx_tlbld (void)
2054
{
2055
    do_load_6xx_tlb(0);
2056
    RETURN();
2057
}
2058

    
2059
void OPPROTO op_6xx_tlbli (void)
2060
{
2061
    do_load_6xx_tlb(1);
2062
    RETURN();
2063
}
2064

    
2065
/* PowerPC 74xx software TLB load instructions */
2066
void OPPROTO op_74xx_tlbld (void)
2067
{
2068
    do_load_74xx_tlb(0);
2069
    RETURN();
2070
}
2071

    
2072
void OPPROTO op_74xx_tlbli (void)
2073
{
2074
    do_load_74xx_tlb(1);
2075
    RETURN();
2076
}
2077
#endif
2078

    
2079
/* 601 specific */
2080
void OPPROTO op_load_601_rtcl (void)
2081
{
2082
    T0 = cpu_ppc601_load_rtcl(env);
2083
    RETURN();
2084
}
2085

    
2086
void OPPROTO op_load_601_rtcu (void)
2087
{
2088
    T0 = cpu_ppc601_load_rtcu(env);
2089
    RETURN();
2090
}
2091

    
2092
#if !defined(CONFIG_USER_ONLY)
2093
void OPPROTO op_store_601_rtcl (void)
2094
{
2095
    cpu_ppc601_store_rtcl(env, T0);
2096
    RETURN();
2097
}
2098

    
2099
void OPPROTO op_store_601_rtcu (void)
2100
{
2101
    cpu_ppc601_store_rtcu(env, T0);
2102
    RETURN();
2103
}
2104

    
2105
void OPPROTO op_load_601_bat (void)
2106
{
2107
    T0 = env->IBAT[PARAM1][PARAM2];
2108
    RETURN();
2109
}
2110
#endif /* !defined(CONFIG_USER_ONLY) */
2111

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

    
2121
    env->IBAT[1][nr] = T0;
2122
    env->DBAT[1][nr] = T0;
2123
    RETURN();
2124
}
2125

    
2126
void OPPROTO op_store_601_batu (void)
2127
{
2128
    do_store_601_batu(PARAM1);
2129
    RETURN();
2130
}
2131
#endif /* !defined(CONFIG_USER_ONLY) */
2132

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

    
2144
void OPPROTO op_POWER_abso (void)
2145
{
2146
    do_POWER_abso();
2147
    RETURN();
2148
}
2149

    
2150
void OPPROTO op_POWER_clcs (void)
2151
{
2152
    do_POWER_clcs();
2153
    RETURN();
2154
}
2155

    
2156
void OPPROTO op_POWER_div (void)
2157
{
2158
    do_POWER_div();
2159
    RETURN();
2160
}
2161

    
2162
void OPPROTO op_POWER_divo (void)
2163
{
2164
    do_POWER_divo();
2165
    RETURN();
2166
}
2167

    
2168
void OPPROTO op_POWER_divs (void)
2169
{
2170
    do_POWER_divs();
2171
    RETURN();
2172
}
2173

    
2174
void OPPROTO op_POWER_divso (void)
2175
{
2176
    do_POWER_divso();
2177
    RETURN();
2178
}
2179

    
2180
void OPPROTO op_POWER_doz (void)
2181
{
2182
    if ((int32_t)T1 > (int32_t)T0)
2183
        T0 = T1 - T0;
2184
    else
2185
        T0 = 0;
2186
    RETURN();
2187
}
2188

    
2189
void OPPROTO op_POWER_dozo (void)
2190
{
2191
    do_POWER_dozo();
2192
    RETURN();
2193
}
2194

    
2195
void OPPROTO op_load_xer_cmp (void)
2196
{
2197
    T2 = xer_cmp;
2198
    RETURN();
2199
}
2200

    
2201
void OPPROTO op_POWER_maskg (void)
2202
{
2203
    do_POWER_maskg();
2204
    RETURN();
2205
}
2206

    
2207
void OPPROTO op_POWER_maskir (void)
2208
{
2209
    T0 = (T0 & ~T2) | (T1 & T2);
2210
    RETURN();
2211
}
2212

    
2213
void OPPROTO op_POWER_mul (void)
2214
{
2215
    uint64_t tmp;
2216

    
2217
    tmp = (uint64_t)T0 * (uint64_t)T1;
2218
    env->spr[SPR_MQ] = tmp >> 32;
2219
    T0 = tmp;
2220
    RETURN();
2221
}
2222

    
2223
void OPPROTO op_POWER_mulo (void)
2224
{
2225
    do_POWER_mulo();
2226
    RETURN();
2227
}
2228

    
2229
void OPPROTO op_POWER_nabs (void)
2230
{
2231
    if (T0 > 0)
2232
        T0 = -T0;
2233
    RETURN();
2234
}
2235

    
2236
void OPPROTO op_POWER_nabso (void)
2237
{
2238
    /* nabs never overflows */
2239
    if (T0 > 0)
2240
        T0 = -T0;
2241
    xer_ov = 0;
2242
    RETURN();
2243
}
2244

    
2245
/* XXX: factorise POWER rotates... */
2246
void OPPROTO op_POWER_rlmi (void)
2247
{
2248
    T0 = rotl32(T0, T2) & PARAM1;
2249
    T0 |= T1 & (uint32_t)PARAM2;
2250
    RETURN();
2251
}
2252

    
2253
void OPPROTO op_POWER_rrib (void)
2254
{
2255
    T2 &= 0x1FUL;
2256
    T0 = rotl32(T0 & INT32_MIN, T2);
2257
    T0 |= T1 & ~rotl32(INT32_MIN, T2);
2258
    RETURN();
2259
}
2260

    
2261
void OPPROTO op_POWER_sle (void)
2262
{
2263
    T1 &= 0x1FUL;
2264
    env->spr[SPR_MQ] = rotl32(T0, T1);
2265
    T0 = T0 << T1;
2266
    RETURN();
2267
}
2268

    
2269
void OPPROTO op_POWER_sleq (void)
2270
{
2271
    uint32_t tmp = env->spr[SPR_MQ];
2272

    
2273
    T1 &= 0x1FUL;
2274
    env->spr[SPR_MQ] = rotl32(T0, T1);
2275
    T0 = T0 << T1;
2276
    T0 |= tmp >> (32 - T1);
2277
    RETURN();
2278
}
2279

    
2280
void OPPROTO op_POWER_sllq (void)
2281
{
2282
    uint32_t msk = -1;
2283

    
2284
    msk = msk << (T1 & 0x1FUL);
2285
    if (T1 & 0x20UL)
2286
        msk = ~msk;
2287
    T1 &= 0x1FUL;
2288
    T0 = (T0 << T1) & msk;
2289
    T0 |= env->spr[SPR_MQ] & ~msk;
2290
    RETURN();
2291
}
2292

    
2293
void OPPROTO op_POWER_slq (void)
2294
{
2295
    uint32_t msk = -1, tmp;
2296

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

    
2307
void OPPROTO op_POWER_sraq (void)
2308
{
2309
    env->spr[SPR_MQ] = rotl32(T0, 32 - (T1 & 0x1FUL));
2310
    if (T1 & 0x20UL)
2311
        T0 = -1L;
2312
    else
2313
        T0 = (int32_t)T0 >> T1;
2314
    RETURN();
2315
}
2316

    
2317
void OPPROTO op_POWER_sre (void)
2318
{
2319
    T1 &= 0x1FUL;
2320
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2321
    T0 = (int32_t)T0 >> T1;
2322
    RETURN();
2323
}
2324

    
2325
void OPPROTO op_POWER_srea (void)
2326
{
2327
    T1 &= 0x1FUL;
2328
    env->spr[SPR_MQ] = T0 >> T1;
2329
    T0 = (int32_t)T0 >> T1;
2330
    RETURN();
2331
}
2332

    
2333
void OPPROTO op_POWER_sreq (void)
2334
{
2335
    uint32_t tmp;
2336
    int32_t msk;
2337

    
2338
    T1 &= 0x1FUL;
2339
    msk = INT32_MIN >> T1;
2340
    tmp = env->spr[SPR_MQ];
2341
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2342
    T0 = T0 >> T1;
2343
    T0 |= tmp & msk;
2344
    RETURN();
2345
}
2346

    
2347
void OPPROTO op_POWER_srlq (void)
2348
{
2349
    uint32_t tmp;
2350
    int32_t msk;
2351

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

    
2364
void OPPROTO op_POWER_srq (void)
2365
{
2366
    T1 &= 0x1FUL;
2367
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2368
    T0 = T0 >> T1;
2369
    RETURN();
2370
}
2371

    
2372
/* POWER instructions not implemented in PowerPC 601 */
2373
#if !defined(CONFIG_USER_ONLY)
2374
void OPPROTO op_POWER_mfsri (void)
2375
{
2376
    T1 = T0 >> 28;
2377
    T0 = env->sr[T1];
2378
    RETURN();
2379
}
2380

    
2381
void OPPROTO op_POWER_rac (void)
2382
{
2383
    do_POWER_rac();
2384
    RETURN();
2385
}
2386

    
2387
void OPPROTO op_POWER_rfsvc (void)
2388
{
2389
    do_POWER_rfsvc();
2390
    RETURN();
2391
}
2392
#endif
2393

    
2394
/* PowerPC 602 specific instruction */
2395
#if !defined(CONFIG_USER_ONLY)
2396
void OPPROTO op_602_mfrom (void)
2397
{
2398
    do_op_602_mfrom();
2399
    RETURN();
2400
}
2401
#endif
2402

    
2403
/* PowerPC 4xx specific micro-ops */
2404
void OPPROTO op_405_add_T0_T2 (void)
2405
{
2406
    T0 = (int32_t)T0 + (int32_t)T2;
2407
    RETURN();
2408
}
2409

    
2410
void OPPROTO op_405_mulchw (void)
2411
{
2412
    T0 = ((int16_t)T0) * ((int16_t)(T1 >> 16));
2413
    RETURN();
2414
}
2415

    
2416
void OPPROTO op_405_mulchwu (void)
2417
{
2418
    T0 = ((uint16_t)T0) * ((uint16_t)(T1 >> 16));
2419
    RETURN();
2420
}
2421

    
2422
void OPPROTO op_405_mulhhw (void)
2423
{
2424
    T0 = ((int16_t)(T0 >> 16)) * ((int16_t)(T1 >> 16));
2425
    RETURN();
2426
}
2427

    
2428
void OPPROTO op_405_mulhhwu (void)
2429
{
2430
    T0 = ((uint16_t)(T0 >> 16)) * ((uint16_t)(T1 >> 16));
2431
    RETURN();
2432
}
2433

    
2434
void OPPROTO op_405_mullhw (void)
2435
{
2436
    T0 = ((int16_t)T0) * ((int16_t)T1);
2437
    RETURN();
2438
}
2439

    
2440
void OPPROTO op_405_mullhwu (void)
2441
{
2442
    T0 = ((uint16_t)T0) * ((uint16_t)T1);
2443
    RETURN();
2444
}
2445

    
2446
void OPPROTO op_405_check_ov (void)
2447
{
2448
    do_405_check_ov();
2449
    RETURN();
2450
}
2451

    
2452
void OPPROTO op_405_check_sat (void)
2453
{
2454
    do_405_check_sat();
2455
    RETURN();
2456
}
2457

    
2458
void OPPROTO op_405_check_ovu (void)
2459
{
2460
    if (likely(T0 >= T2)) {
2461
        xer_ov = 0;
2462
    } else {
2463
        xer_ov = 1;
2464
        xer_so = 1;
2465
    }
2466
    RETURN();
2467
}
2468

    
2469
void OPPROTO op_405_check_satu (void)
2470
{
2471
    if (unlikely(T0 < T2)) {
2472
        /* Saturate result */
2473
        T0 = -1;
2474
    }
2475
    RETURN();
2476
}
2477

    
2478
void OPPROTO op_load_dcr (void)
2479
{
2480
    do_load_dcr();
2481
    RETURN();
2482
}
2483

    
2484
void OPPROTO op_store_dcr (void)
2485
{
2486
    do_store_dcr();
2487
    RETURN();
2488
}
2489

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

    
2500
void OPPROTO op_rfci (void)
2501
{
2502
    do_rfci();
2503
    RETURN();
2504
}
2505

    
2506
void OPPROTO op_rfdi (void)
2507
{
2508
    do_rfdi();
2509
    RETURN();
2510
}
2511

    
2512
void OPPROTO op_rfmci (void)
2513
{
2514
    do_rfmci();
2515
    RETURN();
2516
}
2517

    
2518
void OPPROTO op_wrte (void)
2519
{
2520
    /* We don't call do_store_msr here as we won't trigger
2521
     * any special case nor change hflags
2522
     */
2523
    T0 &= 1 << MSR_EE;
2524
    env->msr &= ~(1 << MSR_EE);
2525
    env->msr |= T0;
2526
    RETURN();
2527
}
2528

    
2529
void OPPROTO op_440_tlbre (void)
2530
{
2531
    do_440_tlbre(PARAM1);
2532
    RETURN();
2533
}
2534

    
2535
void OPPROTO op_440_tlbsx (void)
2536
{
2537
    T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_440_MMUCR] & 0xFF);
2538
    RETURN();
2539
}
2540

    
2541
void OPPROTO op_4xx_tlbsx_check (void)
2542
{
2543
    int tmp;
2544

    
2545
    tmp = xer_so;
2546
    if (T0 != -1)
2547
        tmp |= 0x02;
2548
    env->crf[0] = tmp;
2549
    RETURN();
2550
}
2551

    
2552
void OPPROTO op_440_tlbwe (void)
2553
{
2554
    do_440_tlbwe(PARAM1);
2555
    RETURN();
2556
}
2557

    
2558
void OPPROTO op_4xx_tlbre_lo (void)
2559
{
2560
    do_4xx_tlbre_lo();
2561
    RETURN();
2562
}
2563

    
2564
void OPPROTO op_4xx_tlbre_hi (void)
2565
{
2566
    do_4xx_tlbre_hi();
2567
    RETURN();
2568
}
2569

    
2570
void OPPROTO op_4xx_tlbsx (void)
2571
{
2572
    T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_40x_PID]);
2573
    RETURN();
2574
}
2575

    
2576
void OPPROTO op_4xx_tlbwe_lo (void)
2577
{
2578
    do_4xx_tlbwe_lo();
2579
    RETURN();
2580
}
2581

    
2582
void OPPROTO op_4xx_tlbwe_hi (void)
2583
{
2584
    do_4xx_tlbwe_hi();
2585
    RETURN();
2586
}
2587
#endif
2588

    
2589
/* SPR micro-ops */
2590
/* 440 specific */
2591
void OPPROTO op_440_dlmzb (void)
2592
{
2593
    do_440_dlmzb();
2594
    RETURN();
2595
}
2596

    
2597
void OPPROTO op_440_dlmzb_update_Rc (void)
2598
{
2599
    if (T0 == 8)
2600
        T0 = 0x2;
2601
    else if (T0 < 4)
2602
        T0 = 0x4;
2603
    else
2604
        T0 = 0x8;
2605
    RETURN();
2606
}
2607

    
2608
#if !defined(CONFIG_USER_ONLY)
2609
void OPPROTO op_store_pir (void)
2610
{
2611
    env->spr[SPR_PIR] = T0 & 0x0000000FUL;
2612
    RETURN();
2613
}
2614

    
2615
void OPPROTO op_load_403_pb (void)
2616
{
2617
    do_load_403_pb(PARAM1);
2618
    RETURN();
2619
}
2620

    
2621
void OPPROTO op_store_403_pb (void)
2622
{
2623
    do_store_403_pb(PARAM1);
2624
    RETURN();
2625
}
2626

    
2627
void OPPROTO op_load_40x_pit (void)
2628
{
2629
    T0 = load_40x_pit(env);
2630
    RETURN();
2631
}
2632

    
2633
void OPPROTO op_store_40x_pit (void)
2634
{
2635
    store_40x_pit(env, T0);
2636
    RETURN();
2637
}
2638

    
2639
void OPPROTO op_store_40x_dbcr0 (void)
2640
{
2641
    store_40x_dbcr0(env, T0);
2642
    RETURN();
2643
}
2644

    
2645
void OPPROTO op_store_40x_sler (void)
2646
{
2647
    store_40x_sler(env, T0);
2648
    RETURN();
2649
}
2650

    
2651
void OPPROTO op_store_booke_tcr (void)
2652
{
2653
    store_booke_tcr(env, T0);
2654
    RETURN();
2655
}
2656

    
2657
void OPPROTO op_store_booke_tsr (void)
2658
{
2659
    store_booke_tsr(env, T0);
2660
    RETURN();
2661
}
2662
#endif /* !defined(CONFIG_USER_ONLY) */
2663

    
2664
#if defined(TARGET_PPCEMB)
2665
/* SPE extension */
2666
void OPPROTO op_splatw_T1_64 (void)
2667
{
2668
    T1_64 = (T1_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL);
2669
    RETURN();
2670
}
2671

    
2672
void OPPROTO op_splatwi_T0_64 (void)
2673
{
2674
    uint64_t tmp = PARAM1;
2675

    
2676
    T0_64 = (tmp << 32) | tmp;
2677
    RETURN();
2678
}
2679

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

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

    
2688
void OPPROTO op_extsh_T1_64 (void)
2689
{
2690
    T1_64 = (int32_t)((int16_t)T1_64);
2691
    RETURN();
2692
}
2693

    
2694
void OPPROTO op_sli16_T1_64 (void)
2695
{
2696
    T1_64 = T1_64 << 16;
2697
    RETURN();
2698
}
2699

    
2700
void OPPROTO op_sli32_T1_64 (void)
2701
{
2702
    T1_64 = T1_64 << 32;
2703
    RETURN();
2704
}
2705

    
2706
void OPPROTO op_srli32_T1_64 (void)
2707
{
2708
    T1_64 = T1_64 >> 32;
2709
    RETURN();
2710
}
2711

    
2712
void OPPROTO op_evsel (void)
2713
{
2714
    do_evsel();
2715
    RETURN();
2716
}
2717

    
2718
void OPPROTO op_evaddw (void)
2719
{
2720
    do_evaddw();
2721
    RETURN();
2722
}
2723

    
2724
void OPPROTO op_evsubfw (void)
2725
{
2726
    do_evsubfw();
2727
    RETURN();
2728
}
2729

    
2730
void OPPROTO op_evneg (void)
2731
{
2732
    do_evneg();
2733
    RETURN();
2734
}
2735

    
2736
void OPPROTO op_evabs (void)
2737
{
2738
    do_evabs();
2739
    RETURN();
2740
}
2741

    
2742
void OPPROTO op_evextsh (void)
2743
{
2744
    T0_64 = ((uint64_t)((int32_t)(int16_t)(T0_64 >> 32)) << 32) |
2745
        (uint64_t)((int32_t)(int16_t)T0_64);
2746
    RETURN();
2747
}
2748

    
2749
void OPPROTO op_evextsb (void)
2750
{
2751
    T0_64 = ((uint64_t)((int32_t)(int8_t)(T0_64 >> 32)) << 32) |
2752
        (uint64_t)((int32_t)(int8_t)T0_64);
2753
    RETURN();
2754
}
2755

    
2756
void OPPROTO op_evcntlzw (void)
2757
{
2758
    do_evcntlzw();
2759
    RETURN();
2760
}
2761

    
2762
void OPPROTO op_evrndw (void)
2763
{
2764
    do_evrndw();
2765
    RETURN();
2766
}
2767

    
2768
void OPPROTO op_brinc (void)
2769
{
2770
    do_brinc();
2771
    RETURN();
2772
}
2773

    
2774
void OPPROTO op_evcntlsw (void)
2775
{
2776
    do_evcntlsw();
2777
    RETURN();
2778
}
2779

    
2780
void OPPROTO op_evand (void)
2781
{
2782
    T0_64 &= T1_64;
2783
    RETURN();
2784
}
2785

    
2786
void OPPROTO op_evandc (void)
2787
{
2788
    T0_64 &= ~T1_64;
2789
    RETURN();
2790
}
2791

    
2792
void OPPROTO op_evor (void)
2793
{
2794
    T0_64 |= T1_64;
2795
    RETURN();
2796
}
2797

    
2798
void OPPROTO op_evxor (void)
2799
{
2800
    T0_64 ^= T1_64;
2801
    RETURN();
2802
}
2803

    
2804
void OPPROTO op_eveqv (void)
2805
{
2806
    T0_64 = ~(T0_64 ^ T1_64);
2807
    RETURN();
2808
}
2809

    
2810
void OPPROTO op_evnor (void)
2811
{
2812
    T0_64 = ~(T0_64 | T1_64);
2813
    RETURN();
2814
}
2815

    
2816
void OPPROTO op_evorc (void)
2817
{
2818
    T0_64 |= ~T1_64;
2819
    RETURN();
2820
}
2821

    
2822
void OPPROTO op_evnand (void)
2823
{
2824
    T0_64 = ~(T0_64 & T1_64);
2825
    RETURN();
2826
}
2827

    
2828
void OPPROTO op_evsrws (void)
2829
{
2830
    do_evsrws();
2831
    RETURN();
2832
}
2833

    
2834
void OPPROTO op_evsrwu (void)
2835
{
2836
    do_evsrwu();
2837
    RETURN();
2838
}
2839

    
2840
void OPPROTO op_evslw (void)
2841
{
2842
    do_evslw();
2843
    RETURN();
2844
}
2845

    
2846
void OPPROTO op_evrlw (void)
2847
{
2848
    do_evrlw();
2849
    RETURN();
2850
}
2851

    
2852
void OPPROTO op_evmergelo (void)
2853
{
2854
    T0_64 = (T0_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL);
2855
    RETURN();
2856
}
2857

    
2858
void OPPROTO op_evmergehi (void)
2859
{
2860
    T0_64 = (T0_64 & 0xFFFFFFFF00000000ULL) | (T1_64 >> 32);
2861
    RETURN();
2862
}
2863

    
2864
void OPPROTO op_evmergelohi (void)
2865
{
2866
    T0_64 = (T0_64 << 32) | (T1_64 >> 32);
2867
    RETURN();
2868
}
2869

    
2870
void OPPROTO op_evmergehilo (void)
2871
{
2872
    T0_64 = (T0_64 & 0xFFFFFFFF00000000ULL) | (T1_64 & 0x00000000FFFFFFFFULL);
2873
    RETURN();
2874
}
2875

    
2876
void OPPROTO op_evcmpgts (void)
2877
{
2878
    do_evcmpgts();
2879
    RETURN();
2880
}
2881

    
2882
void OPPROTO op_evcmpgtu (void)
2883
{
2884
    do_evcmpgtu();
2885
    RETURN();
2886
}
2887

    
2888
void OPPROTO op_evcmplts (void)
2889
{
2890
    do_evcmplts();
2891
    RETURN();
2892
}
2893

    
2894
void OPPROTO op_evcmpltu (void)
2895
{
2896
    do_evcmpltu();
2897
    RETURN();
2898
}
2899

    
2900
void OPPROTO op_evcmpeq (void)
2901
{
2902
    do_evcmpeq();
2903
    RETURN();
2904
}
2905

    
2906
void OPPROTO op_evfssub (void)
2907
{
2908
    do_evfssub();
2909
    RETURN();
2910
}
2911

    
2912
void OPPROTO op_evfsadd (void)
2913
{
2914
    do_evfsadd();
2915
    RETURN();
2916
}
2917

    
2918
void OPPROTO op_evfsnabs (void)
2919
{
2920
    do_evfsnabs();
2921
    RETURN();
2922
}
2923

    
2924
void OPPROTO op_evfsabs (void)
2925
{
2926
    do_evfsabs();
2927
    RETURN();
2928
}
2929

    
2930
void OPPROTO op_evfsneg (void)
2931
{
2932
    do_evfsneg();
2933
    RETURN();
2934
}
2935

    
2936
void OPPROTO op_evfsdiv (void)
2937
{
2938
    do_evfsdiv();
2939
    RETURN();
2940
}
2941

    
2942
void OPPROTO op_evfsmul (void)
2943
{
2944
    do_evfsmul();
2945
    RETURN();
2946
}
2947

    
2948
void OPPROTO op_evfscmplt (void)
2949
{
2950
    do_evfscmplt();
2951
    RETURN();
2952
}
2953

    
2954
void OPPROTO op_evfscmpgt (void)
2955
{
2956
    do_evfscmpgt();
2957
    RETURN();
2958
}
2959

    
2960
void OPPROTO op_evfscmpeq (void)
2961
{
2962
    do_evfscmpeq();
2963
    RETURN();
2964
}
2965

    
2966
void OPPROTO op_evfscfsi (void)
2967
{
2968
    do_evfscfsi();
2969
    RETURN();
2970
}
2971

    
2972
void OPPROTO op_evfscfui (void)
2973
{
2974
    do_evfscfui();
2975
    RETURN();
2976
}
2977

    
2978
void OPPROTO op_evfscfsf (void)
2979
{
2980
    do_evfscfsf();
2981
    RETURN();
2982
}
2983

    
2984
void OPPROTO op_evfscfuf (void)
2985
{
2986
    do_evfscfuf();
2987
    RETURN();
2988
}
2989

    
2990
void OPPROTO op_evfsctsi (void)
2991
{
2992
    do_evfsctsi();
2993
    RETURN();
2994
}
2995

    
2996
void OPPROTO op_evfsctui (void)
2997
{
2998
    do_evfsctui();
2999
    RETURN();
3000
}
3001

    
3002
void OPPROTO op_evfsctsf (void)
3003
{
3004
    do_evfsctsf();
3005
    RETURN();
3006
}
3007

    
3008
void OPPROTO op_evfsctuf (void)
3009
{
3010
    do_evfsctuf();
3011
    RETURN();
3012
}
3013

    
3014
void OPPROTO op_evfsctuiz (void)
3015
{
3016
    do_evfsctuiz();
3017
    RETURN();
3018
}
3019

    
3020
void OPPROTO op_evfsctsiz (void)
3021
{
3022
    do_evfsctsiz();
3023
    RETURN();
3024
}
3025

    
3026
void OPPROTO op_evfststlt (void)
3027
{
3028
    do_evfststlt();
3029
    RETURN();
3030
}
3031

    
3032
void OPPROTO op_evfststgt (void)
3033
{
3034
    do_evfststgt();
3035
    RETURN();
3036
}
3037

    
3038
void OPPROTO op_evfststeq (void)
3039
{
3040
    do_evfststeq();
3041
    RETURN();
3042
}
3043

    
3044
void OPPROTO op_efssub (void)
3045
{
3046
    T0_64 = _do_efssub(T0_64, T1_64);
3047
    RETURN();
3048
}
3049

    
3050
void OPPROTO op_efsadd (void)
3051
{
3052
    T0_64 = _do_efsadd(T0_64, T1_64);
3053
    RETURN();
3054
}
3055

    
3056
void OPPROTO op_efsnabs (void)
3057
{
3058
    T0_64 = _do_efsnabs(T0_64);
3059
    RETURN();
3060
}
3061

    
3062
void OPPROTO op_efsabs (void)
3063
{
3064
    T0_64 = _do_efsabs(T0_64);
3065
    RETURN();
3066
}
3067

    
3068
void OPPROTO op_efsneg (void)
3069
{
3070
    T0_64 = _do_efsneg(T0_64);
3071
    RETURN();
3072
}
3073

    
3074
void OPPROTO op_efsdiv (void)
3075
{
3076
    T0_64 = _do_efsdiv(T0_64, T1_64);
3077
    RETURN();
3078
}
3079

    
3080
void OPPROTO op_efsmul (void)
3081
{
3082
    T0_64 = _do_efsmul(T0_64, T1_64);
3083
    RETURN();
3084
}
3085

    
3086
void OPPROTO op_efscmplt (void)
3087
{
3088
    do_efscmplt();
3089
    RETURN();
3090
}
3091

    
3092
void OPPROTO op_efscmpgt (void)
3093
{
3094
    do_efscmpgt();
3095
    RETURN();
3096
}
3097

    
3098
void OPPROTO op_efscfd (void)
3099
{
3100
    do_efscfd();
3101
    RETURN();
3102
}
3103

    
3104
void OPPROTO op_efscmpeq (void)
3105
{
3106
    do_efscmpeq();
3107
    RETURN();
3108
}
3109

    
3110
void OPPROTO op_efscfsi (void)
3111
{
3112
    do_efscfsi();
3113
    RETURN();
3114
}
3115

    
3116
void OPPROTO op_efscfui (void)
3117
{
3118
    do_efscfui();
3119
    RETURN();
3120
}
3121

    
3122
void OPPROTO op_efscfsf (void)
3123
{
3124
    do_efscfsf();
3125
    RETURN();
3126
}
3127

    
3128
void OPPROTO op_efscfuf (void)
3129
{
3130
    do_efscfuf();
3131
    RETURN();
3132
}
3133

    
3134
void OPPROTO op_efsctsi (void)
3135
{
3136
    do_efsctsi();
3137
    RETURN();
3138
}
3139

    
3140
void OPPROTO op_efsctui (void)
3141
{
3142
    do_efsctui();
3143
    RETURN();
3144
}
3145

    
3146
void OPPROTO op_efsctsf (void)
3147
{
3148
    do_efsctsf();
3149
    RETURN();
3150
}
3151

    
3152
void OPPROTO op_efsctuf (void)
3153
{
3154
    do_efsctuf();
3155
    RETURN();
3156
}
3157

    
3158
void OPPROTO op_efsctsiz (void)
3159
{
3160
    do_efsctsiz();
3161
    RETURN();
3162
}
3163

    
3164
void OPPROTO op_efsctuiz (void)
3165
{
3166
    do_efsctuiz();
3167
    RETURN();
3168
}
3169

    
3170
void OPPROTO op_efststlt (void)
3171
{
3172
    T0 = _do_efststlt(T0_64, T1_64);
3173
    RETURN();
3174
}
3175

    
3176
void OPPROTO op_efststgt (void)
3177
{
3178
    T0 = _do_efststgt(T0_64, T1_64);
3179
    RETURN();
3180
}
3181

    
3182
void OPPROTO op_efststeq (void)
3183
{
3184
    T0 = _do_efststeq(T0_64, T1_64);
3185
    RETURN();
3186
}
3187

    
3188
void OPPROTO op_efdsub (void)
3189
{
3190
    union {
3191
        uint64_t u;
3192
        float64 f;
3193
    } u1, u2;
3194
    u1.u = T0_64;
3195
    u2.u = T1_64;
3196
    u1.f = float64_sub(u1.f, u2.f, &env->spe_status);
3197
    T0_64 = u1.u;
3198
    RETURN();
3199
}
3200

    
3201
void OPPROTO op_efdadd (void)
3202
{
3203
    union {
3204
        uint64_t u;
3205
        float64 f;
3206
    } u1, u2;
3207
    u1.u = T0_64;
3208
    u2.u = T1_64;
3209
    u1.f = float64_add(u1.f, u2.f, &env->spe_status);
3210
    T0_64 = u1.u;
3211
    RETURN();
3212
}
3213

    
3214
void OPPROTO op_efdcfsid (void)
3215
{
3216
    do_efdcfsi();
3217
    RETURN();
3218
}
3219

    
3220
void OPPROTO op_efdcfuid (void)
3221
{
3222
    do_efdcfui();
3223
    RETURN();
3224
}
3225

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

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

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

    
3244
void OPPROTO op_efddiv (void)
3245
{
3246
    union {
3247
        uint64_t u;
3248
        float64 f;
3249
    } u1, u2;
3250
    u1.u = T0_64;
3251
    u2.u = T1_64;
3252
    u1.f = float64_div(u1.f, u2.f, &env->spe_status);
3253
    T0_64 = u1.u;
3254
    RETURN();
3255
}
3256

    
3257
void OPPROTO op_efdmul (void)
3258
{
3259
    union {
3260
        uint64_t u;
3261
        float64 f;
3262
    } u1, u2;
3263
    u1.u = T0_64;
3264
    u2.u = T1_64;
3265
    u1.f = float64_mul(u1.f, u2.f, &env->spe_status);
3266
    T0_64 = u1.u;
3267
    RETURN();
3268
}
3269

    
3270
void OPPROTO op_efdctsidz (void)
3271
{
3272
    do_efdctsiz();
3273
    RETURN();
3274
}
3275

    
3276
void OPPROTO op_efdctuidz (void)
3277
{
3278
    do_efdctuiz();
3279
    RETURN();
3280
}
3281

    
3282
void OPPROTO op_efdcmplt (void)
3283
{
3284
    do_efdcmplt();
3285
    RETURN();
3286
}
3287

    
3288
void OPPROTO op_efdcmpgt (void)
3289
{
3290
    do_efdcmpgt();
3291
    RETURN();
3292
}
3293

    
3294
void OPPROTO op_efdcfs (void)
3295
{
3296
    do_efdcfs();
3297
    RETURN();
3298
}
3299

    
3300
void OPPROTO op_efdcmpeq (void)
3301
{
3302
    do_efdcmpeq();
3303
    RETURN();
3304
}
3305

    
3306
void OPPROTO op_efdcfsi (void)
3307
{
3308
    do_efdcfsi();
3309
    RETURN();
3310
}
3311

    
3312
void OPPROTO op_efdcfui (void)
3313
{
3314
    do_efdcfui();
3315
    RETURN();
3316
}
3317

    
3318
void OPPROTO op_efdcfsf (void)
3319
{
3320
    do_efdcfsf();
3321
    RETURN();
3322
}
3323

    
3324
void OPPROTO op_efdcfuf (void)
3325
{
3326
    do_efdcfuf();
3327
    RETURN();
3328
}
3329

    
3330
void OPPROTO op_efdctsi (void)
3331
{
3332
    do_efdctsi();
3333
    RETURN();
3334
}
3335

    
3336
void OPPROTO op_efdctui (void)
3337
{
3338
    do_efdctui();
3339
    RETURN();
3340
}
3341

    
3342
void OPPROTO op_efdctsf (void)
3343
{
3344
    do_efdctsf();
3345
    RETURN();
3346
}
3347

    
3348
void OPPROTO op_efdctuf (void)
3349
{
3350
    do_efdctuf();
3351
    RETURN();
3352
}
3353

    
3354
void OPPROTO op_efdctuiz (void)
3355
{
3356
    do_efdctuiz();
3357
    RETURN();
3358
}
3359

    
3360
void OPPROTO op_efdctsiz (void)
3361
{
3362
    do_efdctsiz();
3363
    RETURN();
3364
}
3365

    
3366
void OPPROTO op_efdtstlt (void)
3367
{
3368
    T0 = _do_efdtstlt(T0_64, T1_64);
3369
    RETURN();
3370
}
3371

    
3372
void OPPROTO op_efdtstgt (void)
3373
{
3374
    T0 = _do_efdtstgt(T0_64, T1_64);
3375
    RETURN();
3376
}
3377

    
3378
void OPPROTO op_efdtsteq (void)
3379
{
3380
    T0 = _do_efdtsteq(T0_64, T1_64);
3381
    RETURN();
3382
}
3383
#endif /* defined(TARGET_PPCEMB) */