Statistics
| Branch: | Revision:

root / target-ppc / op.c @ 51789c41

History | View | Annotate | Download (44.7 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 "op_helper.h"
26

    
27
/* XXX: this is to be suppressed */
28
#define regs (env)
29

    
30
#define FT0 (env->ft0)
31
#define FT1 (env->ft1)
32
#define FT2 (env->ft2)
33

    
34
/* XXX: this is to be suppressed... */
35
#define PPC_OP(name) void OPPROTO glue(op_, name)(void)
36

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
124
#define REG 29
125
#include "op_template.h"
126

    
127
#define REG 30
128
#include "op_template.h"
129

    
130
#define REG 31
131
#include "op_template.h"
132

    
133
/* PowerPC state maintenance operations */
134
/* set_Rc0 */
135
PPC_OP(set_Rc0)
136
{
137
    env->crf[0] = T0 | xer_ov;
138
    RETURN();
139
}
140

    
141
/* Set Rc1 (for floating point arithmetic) */
142
PPC_OP(set_Rc1)
143
{
144
    env->crf[1] = regs->fpscr[7];
145
    RETURN();
146
}
147

    
148
/* Constants load */
149
void OPPROTO op_reset_T0 (void)
150
{
151
    T0 = 0;
152
    RETURN();
153
}
154

    
155
PPC_OP(set_T0)
156
{
157
    T0 = (uint32_t)PARAM1;
158
    RETURN();
159
}
160

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

    
169
PPC_OP(set_T1)
170
{
171
    T1 = (uint32_t)PARAM1;
172
    RETURN();
173
}
174

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

    
183
#if 0 // unused
184
PPC_OP(set_T2)
185
{
186
    T2 = PARAM(1);
187
    RETURN();
188
}
189
#endif
190

    
191
void OPPROTO op_move_T1_T0 (void)
192
{
193
    T1 = T0;
194
    RETURN();
195
}
196

    
197
void OPPROTO op_move_T2_T0 (void)
198
{
199
    T2 = T0;
200
    RETURN();
201
}
202

    
203
/* Generate exceptions */
204
PPC_OP(raise_exception_err)
205
{
206
    do_raise_exception_err(PARAM(1), PARAM(2));
207
}
208

    
209
PPC_OP(update_nip)
210
{
211
    env->nip = (uint32_t)PARAM1;
212
    RETURN();
213
}
214

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

    
223
PPC_OP(debug)
224
{
225
    do_raise_exception(EXCP_DEBUG);
226
}
227

    
228
PPC_OP(exit_tb)
229
{
230
    EXIT_TB();
231
}
232

    
233
/* Load/store special registers */
234
PPC_OP(load_cr)
235
{
236
    do_load_cr();
237
    RETURN();
238
}
239

    
240
PPC_OP(store_cr)
241
{
242
    do_store_cr(PARAM(1));
243
    RETURN();
244
}
245

    
246
void OPPROTO op_load_cro (void)
247
{
248
    T0 = env->crf[PARAM1];
249
    RETURN();
250
}
251

    
252
void OPPROTO op_store_cro (void)
253
{
254
    env->crf[PARAM1] = T0;
255
    RETURN();
256
}
257

    
258
PPC_OP(load_xer_cr)
259
{
260
    T0 = (xer_so << 3) | (xer_ov << 2) | (xer_ca << 1);
261
    RETURN();
262
}
263

    
264
PPC_OP(clear_xer_ov)
265
{
266
    xer_so = 0;
267
    xer_ov = 0;
268
    RETURN();
269
}
270

    
271
PPC_OP(clear_xer_ca)
272
{
273
    xer_ca = 0;
274
    RETURN();
275
}
276

    
277
PPC_OP(load_xer_bc)
278
{
279
    T1 = xer_bc;
280
    RETURN();
281
}
282

    
283
void OPPROTO op_store_xer_bc (void)
284
{
285
    xer_bc = T0;
286
    RETURN();
287
}
288

    
289
PPC_OP(load_xer)
290
{
291
    do_load_xer();
292
    RETURN();
293
}
294

    
295
PPC_OP(store_xer)
296
{
297
    do_store_xer();
298
    RETURN();
299
}
300

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

    
309
PPC_OP(store_sr)
310
{
311
    do_store_sr(env, T1, T0);
312
    RETURN();
313
}
314

    
315
PPC_OP(load_sdr1)
316
{
317
    T0 = regs->sdr1;
318
    RETURN();
319
}
320

    
321
PPC_OP(store_sdr1)
322
{
323
    do_store_sdr1(env, T0);
324
    RETURN();
325
}
326

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

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

    
341
PPC_OP(load_msr)
342
{
343
    T0 = do_load_msr(env);
344
    RETURN();
345
}
346

    
347
PPC_OP(store_msr)
348
{
349
    do_store_msr(env, T0);
350
    RETURN();
351
}
352

    
353
#if defined (TARGET_PPC64)
354
void OPPROTO op_store_msr_32 (void)
355
{
356
    ppc_store_msr_32(env, T0);
357
    RETURN();
358
}
359
#endif
360
#endif
361

    
362
/* SPR */
363
PPC_OP(load_spr)
364
{
365
    T0 = regs->spr[PARAM(1)];
366
    RETURN();
367
}
368

    
369
PPC_OP(store_spr)
370
{
371
    regs->spr[PARAM(1)] = T0;
372
    RETURN();
373
}
374

    
375
PPC_OP(load_lr)
376
{
377
    T0 = regs->lr;
378
    RETURN();
379
}
380

    
381
PPC_OP(store_lr)
382
{
383
    regs->lr = T0;
384
    RETURN();
385
}
386

    
387
PPC_OP(load_ctr)
388
{
389
    T0 = regs->ctr;
390
    RETURN();
391
}
392

    
393
PPC_OP(store_ctr)
394
{
395
    regs->ctr = T0;
396
    RETURN();
397
}
398

    
399
PPC_OP(load_tbl)
400
{
401
    T0 = cpu_ppc_load_tbl(regs);
402
    RETURN();
403
}
404

    
405
PPC_OP(load_tbu)
406
{
407
    T0 = cpu_ppc_load_tbu(regs);
408
    RETURN();
409
}
410

    
411
#if !defined(CONFIG_USER_ONLY)
412
PPC_OP(store_tbl)
413
{
414
    cpu_ppc_store_tbl(regs, T0);
415
    RETURN();
416
}
417

    
418
PPC_OP(store_tbu)
419
{
420
    cpu_ppc_store_tbu(regs, T0);
421
    RETURN();
422
}
423

    
424
PPC_OP(load_decr)
425
{
426
    T0 = cpu_ppc_load_decr(regs);
427
    RETURN();
428
}
429

    
430
PPC_OP(store_decr)
431
{
432
    cpu_ppc_store_decr(regs, T0);
433
    RETURN();
434
}
435

    
436
PPC_OP(load_ibat)
437
{
438
    T0 = regs->IBAT[PARAM(1)][PARAM(2)];
439
    RETURN();
440
}
441

    
442
void OPPROTO op_store_ibatu (void)
443
{
444
    do_store_ibatu(env, PARAM1, T0);
445
    RETURN();
446
}
447

    
448
void OPPROTO op_store_ibatl (void)
449
{
450
#if 1
451
    env->IBAT[1][PARAM1] = T0;
452
#else
453
    do_store_ibatl(env, PARAM1, T0);
454
#endif
455
    RETURN();
456
}
457

    
458
PPC_OP(load_dbat)
459
{
460
    T0 = regs->DBAT[PARAM(1)][PARAM(2)];
461
    RETURN();
462
}
463

    
464
void OPPROTO op_store_dbatu (void)
465
{
466
    do_store_dbatu(env, PARAM1, T0);
467
    RETURN();
468
}
469

    
470
void OPPROTO op_store_dbatl (void)
471
{
472
#if 1
473
    env->DBAT[1][PARAM1] = T0;
474
#else
475
    do_store_dbatl(env, PARAM1, T0);
476
#endif
477
    RETURN();
478
}
479
#endif /* !defined(CONFIG_USER_ONLY) */
480

    
481
/* FPSCR */
482
PPC_OP(load_fpscr)
483
{
484
    do_load_fpscr();
485
    RETURN();
486
}
487

    
488
PPC_OP(store_fpscr)
489
{
490
    do_store_fpscr(PARAM1);
491
    RETURN();
492
}
493

    
494
PPC_OP(reset_scrfx)
495
{
496
    regs->fpscr[7] &= ~0x8;
497
    RETURN();
498
}
499

    
500
/* crf operations */
501
PPC_OP(getbit_T0)
502
{
503
    T0 = (T0 >> PARAM(1)) & 1;
504
    RETURN();
505
}
506

    
507
PPC_OP(getbit_T1)
508
{
509
    T1 = (T1 >> PARAM(1)) & 1;
510
    RETURN();
511
}
512

    
513
PPC_OP(setcrfbit)
514
{
515
    T1 = (T1 & PARAM(1)) | (T0 << PARAM(2));
516
    RETURN();
517
}
518

    
519
/* Branch */
520
#define EIP regs->nip
521

    
522
PPC_OP(setlr)
523
{
524
    regs->lr = (uint32_t)PARAM1;
525
    RETURN();
526
}
527

    
528
#if defined (TARGET_PPC64)
529
void OPPROTO op_setlr_64 (void)
530
{
531
    regs->lr = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
532
    RETURN();
533
}
534
#endif
535

    
536
PPC_OP(goto_tb0)
537
{
538
    GOTO_TB(op_goto_tb0, PARAM1, 0);
539
}
540

    
541
PPC_OP(goto_tb1)
542
{
543
    GOTO_TB(op_goto_tb1, PARAM1, 1);
544
}
545

    
546
void OPPROTO op_b_T1 (void)
547
{
548
    regs->nip = (uint32_t)(T1 & ~3);
549
    RETURN();
550
}
551

    
552
#if defined (TARGET_PPC64)
553
void OPPROTO op_b_T1_64 (void)
554
{
555
    regs->nip = (uint64_t)(T1 & ~3);
556
    RETURN();
557
}
558
#endif
559

    
560
PPC_OP(jz_T0)
561
{
562
    if (!T0)
563
        GOTO_LABEL_PARAM(1);
564
    RETURN();
565
}
566

    
567
void OPPROTO op_btest_T1 (void)
568
{
569
    if (T0) {
570
        regs->nip = (uint32_t)(T1 & ~3);
571
    } else {
572
        regs->nip = (uint32_t)PARAM1;
573
    }
574
    RETURN();
575
}
576

    
577
#if defined (TARGET_PPC64)
578
void OPPROTO op_btest_T1_64 (void)
579
{
580
    if (T0) {
581
        regs->nip = (uint64_t)(T1 & ~3);
582
    } else {
583
        regs->nip = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
584
    }
585
    RETURN();
586
}
587
#endif
588

    
589
PPC_OP(movl_T1_ctr)
590
{
591
    T1 = regs->ctr;
592
    RETURN();
593
}
594

    
595
PPC_OP(movl_T1_lr)
596
{
597
    T1 = regs->lr;
598
    RETURN();
599
}
600

    
601
/* tests with result in T0 */
602
void OPPROTO op_test_ctr (void)
603
{
604
    T0 = (uint32_t)regs->ctr;
605
    RETURN();
606
}
607

    
608
#if defined(TARGET_PPC64)
609
void OPPROTO op_test_ctr_64 (void)
610
{
611
    T0 = (uint64_t)regs->ctr;
612
    RETURN();
613
}
614
#endif
615

    
616
void OPPROTO op_test_ctr_true (void)
617
{
618
    T0 = ((uint32_t)regs->ctr != 0 && (T0 & PARAM1) != 0);
619
    RETURN();
620
}
621

    
622
#if defined(TARGET_PPC64)
623
void OPPROTO op_test_ctr_true_64 (void)
624
{
625
    T0 = ((uint64_t)regs->ctr != 0 && (T0 & PARAM1) != 0);
626
    RETURN();
627
}
628
#endif
629

    
630
void OPPROTO op_test_ctr_false (void)
631
{
632
    T0 = ((uint32_t)regs->ctr != 0 && (T0 & PARAM1) == 0);
633
    RETURN();
634
}
635

    
636
#if defined(TARGET_PPC64)
637
void OPPROTO op_test_ctr_false_64 (void)
638
{
639
    T0 = ((uint64_t)regs->ctr != 0 && (T0 & PARAM1) == 0);
640
    RETURN();
641
}
642
#endif
643

    
644
void OPPROTO op_test_ctrz (void)
645
{
646
    T0 = ((uint32_t)regs->ctr == 0);
647
    RETURN();
648
}
649

    
650
#if defined(TARGET_PPC64)
651
void OPPROTO op_test_ctrz_64 (void)
652
{
653
    T0 = ((uint64_t)regs->ctr == 0);
654
    RETURN();
655
}
656
#endif
657

    
658
void OPPROTO op_test_ctrz_true (void)
659
{
660
    T0 = ((uint32_t)regs->ctr == 0 && (T0 & PARAM1) != 0);
661
    RETURN();
662
}
663

    
664
#if defined(TARGET_PPC64)
665
void OPPROTO op_test_ctrz_true_64 (void)
666
{
667
    T0 = ((uint64_t)regs->ctr == 0 && (T0 & PARAM1) != 0);
668
    RETURN();
669
}
670
#endif
671

    
672
void OPPROTO op_test_ctrz_false (void)
673
{
674
    T0 = ((uint32_t)regs->ctr == 0 && (T0 & PARAM1) == 0);
675
    RETURN();
676
}
677

    
678
#if defined(TARGET_PPC64)
679
void OPPROTO op_test_ctrz_false_64 (void)
680
{
681
    T0 = ((uint64_t)regs->ctr == 0 && (T0 & PARAM1) == 0);
682
    RETURN();
683
}
684
#endif
685

    
686
PPC_OP(test_true)
687
{
688
    T0 = (T0 & PARAM(1));
689
    RETURN();
690
}
691

    
692
PPC_OP(test_false)
693
{
694
    T0 = ((T0 & PARAM(1)) == 0);
695
    RETURN();
696
}
697

    
698
/* CTR maintenance */
699
PPC_OP(dec_ctr)
700
{
701
    regs->ctr--;
702
    RETURN();
703
}
704

    
705
/***                           Integer arithmetic                          ***/
706
/* add */
707
PPC_OP(add)
708
{
709
    T0 += T1;
710
    RETURN();
711
}
712

    
713
void OPPROTO op_check_addo (void)
714
{
715
    if (likely(!(((uint32_t)T2 ^ (uint32_t)T1 ^ UINT32_MAX) &
716
                 ((uint32_t)T2 ^ (uint32_t)T0) & (1UL << 31)))) {
717
        xer_ov = 0;
718
    } else {
719
        xer_so = 1;
720
        xer_ov = 1;
721
    }
722
    RETURN();
723
}
724

    
725
#if defined(TARGET_PPC64)
726
void OPPROTO op_check_addo_64 (void)
727
{
728
    if (likely(!(((uint64_t)T2 ^ (uint64_t)T1 ^ UINT64_MAX) &
729
                 ((uint64_t)T2 ^ (uint64_t)T0) & (1ULL << 63)))) {
730
        xer_ov = 0;
731
    } else {
732
        xer_so = 1;
733
        xer_ov = 1;
734
    }
735
    RETURN();
736
}
737
#endif
738

    
739
/* add carrying */
740
void OPPROTO op_check_addc (void)
741
{
742
    if (likely((uint32_t)T0 >= (uint32_t)T2)) {
743
        xer_ca = 0;
744
    } else {
745
        xer_ca = 1;
746
    }
747
    RETURN();
748
}
749

    
750
#if defined(TARGET_PPC64)
751
void OPPROTO op_check_addc_64 (void)
752
{
753
    if (likely((uint64_t)T0 >= (uint64_t)T2)) {
754
        xer_ca = 0;
755
    } else {
756
        xer_ca = 1;
757
    }
758
    RETURN();
759
}
760
#endif
761

    
762
/* add extended */
763
void OPPROTO op_adde (void)
764
{
765
    do_adde();
766
    RETURN();
767
}
768

    
769
#if defined(TARGET_PPC64)
770
void OPPROTO op_adde_64 (void)
771
{
772
    do_adde_64();
773
    RETURN();
774
}
775
#endif
776

    
777
/* add immediate */
778
PPC_OP(addi)
779
{
780
    T0 += PARAM(1);
781
    RETURN();
782
}
783

    
784
/* add to minus one extended */
785
void OPPROTO op_add_me (void)
786
{
787
    T0 += xer_ca + (-1);
788
    if (likely((uint32_t)T1 != 0))
789
        xer_ca = 1;
790
    RETURN();
791
}
792

    
793
#if defined(TARGET_PPC64)
794
void OPPROTO op_add_me_64 (void)
795
{
796
    T0 += xer_ca + (-1);
797
    if (likely((uint64_t)T1 != 0))
798
        xer_ca = 1;
799
    RETURN();
800
}
801
#endif
802

    
803
void OPPROTO op_addmeo (void)
804
{
805
    do_addmeo();
806
    RETURN();
807
}
808

    
809
void OPPROTO op_addmeo_64 (void)
810
{
811
    do_addmeo();
812
    RETURN();
813
}
814

    
815
/* add to zero extended */
816
void OPPROTO op_add_ze (void)
817
{
818
    T0 += xer_ca;
819
    RETURN();
820
}
821

    
822
/* divide word */
823
void OPPROTO op_divw (void)
824
{
825
    if (unlikely(((int32_t)T0 == INT32_MIN && (int32_t)T1 == -1) ||
826
                 (int32_t)T1 == 0)) {
827
        T0 = (int32_t)((-1) * ((uint32_t)T0 >> 31));
828
    } else {
829
        T0 = (int32_t)T0 / (int32_t)T1;
830
    }
831
    RETURN();
832
}
833

    
834
#if defined(TARGET_PPC64)
835
void OPPROTO op_divd (void)
836
{
837
    if (unlikely(((int64_t)T0 == INT64_MIN && (int64_t)T1 == -1) ||
838
                 (int64_t)T1 == 0)) {
839
        T0 = (int64_t)((-1ULL) * ((uint64_t)T0 >> 63));
840
    } else {
841
        T0 = (int64_t)T0 / (int64_t)T1;
842
    }
843
    RETURN();
844
}
845
#endif
846

    
847
void OPPROTO op_divwo (void)
848
{
849
    do_divwo();
850
    RETURN();
851
}
852

    
853
#if defined(TARGET_PPC64)
854
void OPPROTO op_divdo (void)
855
{
856
    do_divdo();
857
    RETURN();
858
}
859
#endif
860

    
861
/* divide word unsigned */
862
void OPPROTO op_divwu (void)
863
{
864
    if (unlikely(T1 == 0)) {
865
        T0 = 0;
866
    } else {
867
        T0 = (uint32_t)T0 / (uint32_t)T1;
868
    }
869
    RETURN();
870
}
871

    
872
#if defined(TARGET_PPC64)
873
void OPPROTO op_divdu (void)
874
{
875
    if (unlikely(T1 == 0)) {
876
        T0 = 0;
877
    } else {
878
        T0 /= T1;
879
    }
880
    RETURN();
881
}
882
#endif
883

    
884
void OPPROTO op_divwuo (void)
885
{
886
    do_divwuo();
887
    RETURN();
888
}
889

    
890
#if defined(TARGET_PPC64)
891
void OPPROTO op_divduo (void)
892
{
893
    do_divduo();
894
    RETURN();
895
}
896
#endif
897

    
898
/* multiply high word */
899
void OPPROTO op_mulhw (void)
900
{
901
    T0 = ((int64_t)((int32_t)T0) * (int64_t)((int32_t)T1)) >> 32;
902
    RETURN();
903
}
904

    
905
#if defined(TARGET_PPC64)
906
void OPPROTO op_mulhd (void)
907
{
908
    uint64_t tl, th;
909

    
910
    do_imul64(&tl, &th);
911
    T0 = th;
912
    RETURN();
913
}
914
#endif
915

    
916
/* multiply high word unsigned */
917
void OPPROTO op_mulhwu (void)
918
{
919
    T0 = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1) >> 32;
920
    RETURN();
921
}
922

    
923
#if defined(TARGET_PPC64)
924
void OPPROTO op_mulhdu (void)
925
{
926
    uint64_t tl, th;
927

    
928
    do_mul64(&tl, &th);
929
    T0 = th;
930
    RETURN();
931
}
932
#endif
933

    
934
/* multiply low immediate */
935
PPC_OP(mulli)
936
{
937
    T0 = ((int32_t)T0 * (int32_t)PARAM1);
938
    RETURN();
939
}
940

    
941
/* multiply low word */
942
PPC_OP(mullw)
943
{
944
    T0 = (int32_t)(T0 * T1);
945
    RETURN();
946
}
947

    
948
#if defined(TARGET_PPC64)
949
void OPPROTO op_mulld (void)
950
{
951
    T0 *= T1;
952
    RETURN();
953
}
954
#endif
955

    
956
void OPPROTO op_mullwo (void)
957
{
958
    do_mullwo();
959
    RETURN();
960
}
961

    
962
#if defined(TARGET_PPC64)
963
void OPPROTO op_mulldo (void)
964
{
965
    do_mulldo();
966
    RETURN();
967
}
968
#endif
969

    
970
/* negate */
971
void OPPROTO op_neg (void)
972
{
973
    if (likely(T0 != INT32_MIN)) {
974
        T0 = -(int32_t)T0;
975
    }
976
    RETURN();
977
}
978

    
979
#if defined(TARGET_PPC64)
980
void OPPROTO op_neg_64 (void)
981
{
982
    if (likely(T0 != INT64_MIN)) {
983
        T0 = -(int64_t)T0;
984
    }
985
    RETURN();
986
}
987
#endif
988

    
989
void OPPROTO op_nego (void)
990
{
991
    do_nego();
992
    RETURN();
993
}
994

    
995
#if defined(TARGET_PPC64)
996
void OPPROTO op_nego_64 (void)
997
{
998
    do_nego_64();
999
    RETURN();
1000
}
1001
#endif
1002

    
1003
/* substract from */
1004
PPC_OP(subf)
1005
{
1006
    T0 = T1 - T0;
1007
    RETURN();
1008
}
1009

    
1010
void OPPROTO op_check_subfo (void)
1011
{
1012
    if (likely(!(((uint32_t)(~T2) ^ (uint32_t)T1 ^ UINT32_MAX) &
1013
                 ((uint32_t)(~T2) ^ (uint32_t)T0) & (1UL << 31)))) {
1014
        xer_ov = 0;
1015
    } else {
1016
        xer_so = 1;
1017
        xer_ov = 1;
1018
    }
1019
    RETURN();
1020
}
1021

    
1022
#if defined(TARGET_PPC64)
1023
void OPPROTO op_check_subfo_64 (void)
1024
{
1025
    if (likely(!(((uint64_t)(~T2) ^ (uint64_t)T1 ^ UINT64_MAX) &
1026
                 ((uint64_t)(~T2) ^ (uint64_t)T0) & (1ULL << 63)))) {
1027
        xer_ov = 0;
1028
    } else {
1029
        xer_so = 1;
1030
        xer_ov = 1;
1031
    }
1032
    RETURN();
1033
}
1034
#endif
1035

    
1036
/* substract from carrying */
1037
void OPPROTO op_check_subfc (void)
1038
{
1039
    if (likely((uint32_t)T0 > (uint32_t)T1)) {
1040
        xer_ca = 0;
1041
    } else {
1042
        xer_ca = 1;
1043
    }
1044
    RETURN();
1045
}
1046

    
1047
#if defined(TARGET_PPC64)
1048
void OPPROTO op_check_subfc_64 (void)
1049
{
1050
    if (likely((uint64_t)T0 > (uint64_t)T1)) {
1051
        xer_ca = 0;
1052
    } else {
1053
        xer_ca = 1;
1054
    }
1055
    RETURN();
1056
}
1057
#endif
1058

    
1059
/* substract from extended */
1060
void OPPROTO op_subfe (void)
1061
{
1062
    do_subfe();
1063
    RETURN();
1064
}
1065

    
1066
#if defined(TARGET_PPC64)
1067
void OPPROTO op_subfe_64 (void)
1068
{
1069
    do_subfe_64();
1070
    RETURN();
1071
}
1072
#endif
1073

    
1074
/* substract from immediate carrying */
1075
void OPPROTO op_subfic (void)
1076
{
1077
    T0 = PARAM1 + ~T0 + 1;
1078
    if ((uint32_t)T0 <= (uint32_t)PARAM1) {
1079
        xer_ca = 1;
1080
    } else {
1081
        xer_ca = 0;
1082
    }
1083
    RETURN();
1084
}
1085

    
1086
#if defined(TARGET_PPC64)
1087
void OPPROTO op_subfic_64 (void)
1088
{
1089
    T0 = PARAM1 + ~T0 + 1;
1090
    if ((uint64_t)T0 <= (uint64_t)PARAM1) {
1091
        xer_ca = 1;
1092
    } else {
1093
        xer_ca = 0;
1094
    }
1095
    RETURN();
1096
}
1097
#endif
1098

    
1099
/* substract from minus one extended */
1100
void OPPROTO op_subfme (void)
1101
{
1102
    T0 = ~T0 + xer_ca - 1;
1103
    if (likely((uint32_t)T0 != (uint32_t)-1))
1104
        xer_ca = 1;
1105
    RETURN();
1106
}
1107

    
1108
#if defined(TARGET_PPC64)
1109
void OPPROTO op_subfme_64 (void)
1110
{
1111
    T0 = ~T0 + xer_ca - 1;
1112
    if (likely((uint64_t)T0 != (uint64_t)-1))
1113
        xer_ca = 1;
1114
    RETURN();
1115
}
1116
#endif
1117

    
1118
void OPPROTO op_subfmeo (void)
1119
{
1120
    do_subfmeo();
1121
    RETURN();
1122
}
1123

    
1124
#if defined(TARGET_PPC64)
1125
void OPPROTO op_subfmeo_64 (void)
1126
{
1127
    do_subfmeo_64();
1128
    RETURN();
1129
}
1130
#endif
1131

    
1132
/* substract from zero extended */
1133
void OPPROTO op_subfze (void)
1134
{
1135
    T1 = ~T0;
1136
    T0 = T1 + xer_ca;
1137
    if ((uint32_t)T0 < (uint32_t)T1) {
1138
        xer_ca = 1;
1139
    } else {
1140
        xer_ca = 0;
1141
    }
1142
    RETURN();
1143
}
1144

    
1145
#if defined(TARGET_PPC64)
1146
void OPPROTO op_subfze_64 (void)
1147
{
1148
    T1 = ~T0;
1149
    T0 = T1 + xer_ca;
1150
    if ((uint64_t)T0 < (uint64_t)T1) {
1151
        xer_ca = 1;
1152
    } else {
1153
        xer_ca = 0;
1154
    }
1155
    RETURN();
1156
}
1157
#endif
1158

    
1159
void OPPROTO op_subfzeo (void)
1160
{
1161
    do_subfzeo();
1162
    RETURN();
1163
}
1164

    
1165
#if defined(TARGET_PPC64)
1166
void OPPROTO op_subfzeo_64 (void)
1167
{
1168
    do_subfzeo_64();
1169
    RETURN();
1170
}
1171
#endif
1172

    
1173
/***                           Integer comparison                          ***/
1174
/* compare */
1175
void OPPROTO op_cmp (void)
1176
{
1177
    if ((int32_t)T0 < (int32_t)T1) {
1178
        T0 = 0x08;
1179
    } else if ((int32_t)T0 > (int32_t)T1) {
1180
        T0 = 0x04;
1181
    } else {
1182
        T0 = 0x02;
1183
    }
1184
    RETURN();
1185
}
1186

    
1187
#if defined(TARGET_PPC64)
1188
void OPPROTO op_cmp_64 (void)
1189
{
1190
    if ((int64_t)T0 < (int64_t)T1) {
1191
        T0 = 0x08;
1192
    } else if ((int64_t)T0 > (int64_t)T1) {
1193
        T0 = 0x04;
1194
    } else {
1195
        T0 = 0x02;
1196
    }
1197
    RETURN();
1198
}
1199
#endif
1200

    
1201
/* compare immediate */
1202
void OPPROTO op_cmpi (void)
1203
{
1204
    if ((int32_t)T0 < (int32_t)PARAM1) {
1205
        T0 = 0x08;
1206
    } else if ((int32_t)T0 > (int32_t)PARAM1) {
1207
        T0 = 0x04;
1208
    } else {
1209
        T0 = 0x02;
1210
    }
1211
    RETURN();
1212
}
1213

    
1214
#if defined(TARGET_PPC64)
1215
void OPPROTO op_cmpi_64 (void)
1216
{
1217
    if ((int64_t)T0 < (int64_t)((int32_t)PARAM1)) {
1218
        T0 = 0x08;
1219
    } else if ((int64_t)T0 > (int64_t)((int32_t)PARAM1)) {
1220
        T0 = 0x04;
1221
    } else {
1222
        T0 = 0x02;
1223
    }
1224
    RETURN();
1225
}
1226
#endif
1227

    
1228
/* compare logical */
1229
void OPPROTO op_cmpl (void)
1230
{
1231
    if ((uint32_t)T0 < (uint32_t)T1) {
1232
        T0 = 0x08;
1233
    } else if ((uint32_t)T0 > (uint32_t)T1) {
1234
        T0 = 0x04;
1235
    } else {
1236
        T0 = 0x02;
1237
    }
1238
    RETURN();
1239
}
1240

    
1241
#if defined(TARGET_PPC64)
1242
void OPPROTO op_cmpl_64 (void)
1243
{
1244
    if ((uint64_t)T0 < (uint64_t)T1) {
1245
        T0 = 0x08;
1246
    } else if ((uint64_t)T0 > (uint64_t)T1) {
1247
        T0 = 0x04;
1248
    } else {
1249
        T0 = 0x02;
1250
    }
1251
    RETURN();
1252
}
1253
#endif
1254

    
1255
/* compare logical immediate */
1256
void OPPROTO op_cmpli (void)
1257
{
1258
    if ((uint32_t)T0 < (uint32_t)PARAM1) {
1259
        T0 = 0x08;
1260
    } else if ((uint32_t)T0 > (uint32_t)PARAM1) {
1261
        T0 = 0x04;
1262
    } else {
1263
        T0 = 0x02;
1264
    }
1265
    RETURN();
1266
}
1267

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

    
1282
void OPPROTO op_isel (void)
1283
{
1284
    if (T0)
1285
        T0 = T1;
1286
    else
1287
        T0 = T2;
1288
    RETURN();
1289
}
1290

    
1291
void OPPROTO op_popcntb (void)
1292
{
1293
    do_popcntb();
1294
    RETURN();
1295
}
1296

    
1297
#if defined(TARGET_PPC64)
1298
void OPPROTO op_popcntb_64 (void)
1299
{
1300
    do_popcntb_64();
1301
    RETURN();
1302
}
1303
#endif
1304

    
1305
/***                            Integer logical                            ***/
1306
/* and */
1307
PPC_OP(and)
1308
{
1309
    T0 &= T1;
1310
    RETURN();
1311
}
1312

    
1313
/* andc */
1314
PPC_OP(andc)
1315
{
1316
    T0 &= ~T1;
1317
    RETURN();
1318
}
1319

    
1320
/* andi. */
1321
void OPPROTO op_andi_T0 (void)
1322
{
1323
    T0 &= PARAM(1);
1324
    RETURN();
1325
}
1326

    
1327
void OPPROTO op_andi_T1 (void)
1328
{
1329
    T1 &= PARAM1;
1330
    RETURN();
1331
}
1332

    
1333
/* count leading zero */
1334
void OPPROTO op_cntlzw (void)
1335
{
1336
    T0 = _do_cntlzw(T0);
1337
    RETURN();
1338
}
1339

    
1340
#if defined(TARGET_PPC64)
1341
void OPPROTO op_cntlzd (void)
1342
{
1343
    T0 = _do_cntlzd(T0);
1344
    RETURN();
1345
}
1346
#endif
1347

    
1348
/* eqv */
1349
PPC_OP(eqv)
1350
{
1351
    T0 = ~(T0 ^ T1);
1352
    RETURN();
1353
}
1354

    
1355
/* extend sign byte */
1356
void OPPROTO op_extsb (void)
1357
{
1358
#if defined (TARGET_PPC64)
1359
    T0 = (int64_t)((int8_t)T0);
1360
#else
1361
    T0 = (int32_t)((int8_t)T0);
1362
#endif
1363
    RETURN();
1364
}
1365

    
1366
/* extend sign half word */
1367
void OPPROTO op_extsh (void)
1368
{
1369
#if defined (TARGET_PPC64)
1370
    T0 = (int64_t)((int16_t)T0);
1371
#else
1372
    T0 = (int32_t)((int16_t)T0);
1373
#endif
1374
    RETURN();
1375
}
1376

    
1377
#if defined (TARGET_PPC64)
1378
void OPPROTO op_extsw (void)
1379
{
1380
    T0 = (int64_t)((int32_t)T0);
1381
    RETURN();
1382
}
1383
#endif
1384

    
1385
/* nand */
1386
PPC_OP(nand)
1387
{
1388
    T0 = ~(T0 & T1);
1389
    RETURN();
1390
}
1391

    
1392
/* nor */
1393
PPC_OP(nor)
1394
{
1395
    T0 = ~(T0 | T1);
1396
    RETURN();
1397
}
1398

    
1399
/* or */
1400
PPC_OP(or)
1401
{
1402
    T0 |= T1;
1403
    RETURN();
1404
}
1405

    
1406
/* orc */
1407
PPC_OP(orc)
1408
{
1409
    T0 |= ~T1;
1410
    RETURN();
1411
}
1412

    
1413
/* ori */
1414
PPC_OP(ori)
1415
{
1416
    T0 |= PARAM(1);
1417
    RETURN();
1418
}
1419

    
1420
/* xor */
1421
PPC_OP(xor)
1422
{
1423
    T0 ^= T1;
1424
    RETURN();
1425
}
1426

    
1427
/* xori */
1428
PPC_OP(xori)
1429
{
1430
    T0 ^= PARAM(1);
1431
    RETURN();
1432
}
1433

    
1434
/***                             Integer rotate                            ***/
1435
void OPPROTO op_rotl32_T0_T1 (void)
1436
{
1437
    T0 = rotl32(T0, T1 & 0x1F);
1438
    RETURN();
1439
}
1440

    
1441
void OPPROTO op_rotli32_T0 (void)
1442
{
1443
    T0 = rotl32(T0, PARAM1);
1444
    RETURN();
1445
}
1446

    
1447
#if defined(TARGET_PPC64)
1448
void OPPROTO op_rotl64_T0_T1 (void)
1449
{
1450
    T0 = rotl64(T0, T1 & 0x3F);
1451
    RETURN();
1452
}
1453

    
1454
void OPPROTO op_rotli64_T0 (void)
1455
{
1456
    T0 = rotl64(T0, PARAM1);
1457
    RETURN();
1458
}
1459
#endif
1460

    
1461
/***                             Integer shift                             ***/
1462
/* shift left word */
1463
void OPPROTO op_slw (void)
1464
{
1465
    if (T1 & 0x20) {
1466
        T0 = 0;
1467
    } else {
1468
        T0 = (uint32_t)(T0 << T1);
1469
    }
1470
    RETURN();
1471
}
1472

    
1473
#if defined(TARGET_PPC64)
1474
void OPPROTO op_sld (void)
1475
{
1476
    if (T1 & 0x40) {
1477
        T0 = 0;
1478
    } else {
1479
        T0 = T0 << T1;
1480
    }
1481
    RETURN();
1482
}
1483
#endif
1484

    
1485
/* shift right algebraic word */
1486
void OPPROTO op_sraw (void)
1487
{
1488
    do_sraw();
1489
    RETURN();
1490
}
1491

    
1492
#if defined(TARGET_PPC64)
1493
void OPPROTO op_srad (void)
1494
{
1495
    do_srad();
1496
    RETURN();
1497
}
1498
#endif
1499

    
1500
/* shift right algebraic word immediate */
1501
void OPPROTO op_srawi (void)
1502
{
1503
    uint32_t mask = (uint32_t)PARAM2;
1504

    
1505
    T0 = (int32_t)T0 >> PARAM1;
1506
    if ((int32_t)T1 < 0 && (T1 & mask) != 0) {
1507
        xer_ca = 1;
1508
    } else {
1509
        xer_ca = 0;
1510
    }
1511
    RETURN();
1512
}
1513

    
1514
#if defined(TARGET_PPC64)
1515
void OPPROTO op_sradi (void)
1516
{
1517
    uint64_t mask = ((uint64_t)PARAM2 << 32) | (uint64_t)PARAM3;
1518

    
1519
    T0 = (int64_t)T0 >> PARAM1;
1520
    if ((int64_t)T1 < 0 && ((uint64_t)T1 & mask) != 0) {
1521
        xer_ca = 1;
1522
    } else {
1523
        xer_ca = 0;
1524
    }
1525
    RETURN();
1526
}
1527
#endif
1528

    
1529
/* shift right word */
1530
void OPPROTO op_srw (void)
1531
{
1532
    if (T1 & 0x20) {
1533
        T0 = 0;
1534
    } else {
1535
        T0 = (uint32_t)T0 >> T1;
1536
    }
1537
    RETURN();
1538
}
1539

    
1540
#if defined(TARGET_PPC64)
1541
void OPPROTO op_srd (void)
1542
{
1543
    if (T1 & 0x40) {
1544
        T0 = 0;
1545
    } else {
1546
        T0 = (uint64_t)T0 >> T1;
1547
    }
1548
    RETURN();
1549
}
1550
#endif
1551

    
1552
void OPPROTO op_sl_T0_T1 (void)
1553
{
1554
    T0 = T0 << T1;
1555
    RETURN();
1556
}
1557

    
1558
void OPPROTO op_sli_T0 (void)
1559
{
1560
    T0 = T0 << PARAM1;
1561
    RETURN();
1562
}
1563

    
1564
void OPPROTO op_srl_T0_T1 (void)
1565
{
1566
    T0 = (uint32_t)T0 >> T1;
1567
    RETURN();
1568
}
1569

    
1570
#if defined(TARGET_PPC64)
1571
void OPPROTO op_srl_T0_T1_64 (void)
1572
{
1573
    T0 = (uint32_t)T0 >> T1;
1574
    RETURN();
1575
}
1576
#endif
1577

    
1578
void OPPROTO op_srli_T0 (void)
1579
{
1580
    T0 = (uint32_t)T0 >> PARAM1;
1581
    RETURN();
1582
}
1583

    
1584
#if defined(TARGET_PPC64)
1585
void OPPROTO op_srli_T0_64 (void)
1586
{
1587
    T0 = (uint64_t)T0 >> PARAM1;
1588
    RETURN();
1589
}
1590
#endif
1591

    
1592
void OPPROTO op_srli_T1 (void)
1593
{
1594
    T1 = (uint32_t)T1 >> PARAM1;
1595
    RETURN();
1596
}
1597

    
1598
#if defined(TARGET_PPC64)
1599
void OPPROTO op_srli_T1_64 (void)
1600
{
1601
    T1 = (uint64_t)T1 >> PARAM1;
1602
    RETURN();
1603
}
1604
#endif
1605

    
1606
/***                       Floating-Point arithmetic                       ***/
1607
/* fadd - fadd. */
1608
PPC_OP(fadd)
1609
{
1610
    FT0 = float64_add(FT0, FT1, &env->fp_status);
1611
    RETURN();
1612
}
1613

    
1614
/* fsub - fsub. */
1615
PPC_OP(fsub)
1616
{
1617
    FT0 = float64_sub(FT0, FT1, &env->fp_status);
1618
    RETURN();
1619
}
1620

    
1621
/* fmul - fmul. */
1622
PPC_OP(fmul)
1623
{
1624
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1625
    RETURN();
1626
}
1627

    
1628
/* fdiv - fdiv. */
1629
PPC_OP(fdiv)
1630
{
1631
    FT0 = float64_div(FT0, FT1, &env->fp_status);
1632
    RETURN();
1633
}
1634

    
1635
/* fsqrt - fsqrt. */
1636
PPC_OP(fsqrt)
1637
{
1638
    do_fsqrt();
1639
    RETURN();
1640
}
1641

    
1642
/* fres - fres. */
1643
PPC_OP(fres)
1644
{
1645
    do_fres();
1646
    RETURN();
1647
}
1648

    
1649
/* frsqrte  - frsqrte. */
1650
PPC_OP(frsqrte)
1651
{
1652
    do_frsqrte();
1653
    RETURN();
1654
}
1655

    
1656
/* fsel - fsel. */
1657
PPC_OP(fsel)
1658
{
1659
    do_fsel();
1660
    RETURN();
1661
}
1662

    
1663
/***                     Floating-Point multiply-and-add                   ***/
1664
/* fmadd - fmadd. */
1665
PPC_OP(fmadd)
1666
{
1667
#if USE_PRECISE_EMULATION
1668
    do_fmadd();
1669
#else
1670
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1671
    FT0 = float64_add(FT0, FT2, &env->fp_status);
1672
#endif
1673
    RETURN();
1674
}
1675

    
1676
/* fmsub - fmsub. */
1677
PPC_OP(fmsub)
1678
{
1679
#if USE_PRECISE_EMULATION
1680
    do_fmsub();
1681
#else
1682
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1683
    FT0 = float64_sub(FT0, FT2, &env->fp_status);
1684
#endif
1685
    RETURN();
1686
}
1687

    
1688
/* fnmadd - fnmadd. - fnmadds - fnmadds. */
1689
PPC_OP(fnmadd)
1690
{
1691
    do_fnmadd();
1692
    RETURN();
1693
}
1694

    
1695
/* fnmsub - fnmsub. */
1696
PPC_OP(fnmsub)
1697
{
1698
    do_fnmsub();
1699
    RETURN();
1700
}
1701

    
1702
/***                     Floating-Point round & convert                    ***/
1703
/* frsp - frsp. */
1704
PPC_OP(frsp)
1705
{
1706
    FT0 = float64_to_float32(FT0, &env->fp_status);
1707
    RETURN();
1708
}
1709

    
1710
/* fctiw - fctiw. */
1711
PPC_OP(fctiw)
1712
{
1713
    do_fctiw();
1714
    RETURN();
1715
}
1716

    
1717
/* fctiwz - fctiwz. */
1718
PPC_OP(fctiwz)
1719
{
1720
    do_fctiwz();
1721
    RETURN();
1722
}
1723

    
1724
/***                         Floating-Point compare                        ***/
1725
/* fcmpu */
1726
PPC_OP(fcmpu)
1727
{
1728
    do_fcmpu();
1729
    RETURN();
1730
}
1731

    
1732
/* fcmpo */
1733
PPC_OP(fcmpo)
1734
{
1735
    do_fcmpo();
1736
    RETURN();
1737
}
1738

    
1739
/***                         Floating-point move                           ***/
1740
/* fabs */
1741
PPC_OP(fabs)
1742
{
1743
    FT0 = float64_abs(FT0);
1744
    RETURN();
1745
}
1746

    
1747
/* fnabs */
1748
PPC_OP(fnabs)
1749
{
1750
    FT0 = float64_abs(FT0);
1751
    FT0 = float64_chs(FT0);
1752
    RETURN();
1753
}
1754

    
1755
/* fneg */
1756
PPC_OP(fneg)
1757
{
1758
    FT0 = float64_chs(FT0);
1759
    RETURN();
1760
}
1761

    
1762
/* Load and store */
1763
#define MEMSUFFIX _raw
1764
#include "op_helper.h"
1765
#include "op_mem.h"
1766
#if !defined(CONFIG_USER_ONLY)
1767
#define MEMSUFFIX _user
1768
#include "op_helper.h"
1769
#include "op_mem.h"
1770
#define MEMSUFFIX _kernel
1771
#include "op_helper.h"
1772
#include "op_mem.h"
1773
#endif
1774

    
1775
/* Special op to check and maybe clear reservation */
1776
void OPPROTO op_check_reservation (void)
1777
{
1778
    if ((uint32_t)env->reserve == (uint32_t)(T0 & ~0x00000003))
1779
        env->reserve = -1;
1780
    RETURN();
1781
}
1782

    
1783
#if defined(TARGET_PPC64)
1784
void OPPROTO op_check_reservation_64 (void)
1785
{
1786
    if ((uint64_t)env->reserve == (uint64_t)(T0 & ~0x00000003))
1787
        env->reserve = -1;
1788
    RETURN();
1789
}
1790
#endif
1791

    
1792
/* Return from interrupt */
1793
#if !defined(CONFIG_USER_ONLY)
1794
void OPPROTO op_rfi (void)
1795
{
1796
    do_rfi();
1797
    RETURN();
1798
}
1799

    
1800
#if defined(TARGET_PPC64)
1801
void OPPROTO op_rfi_32 (void)
1802
{
1803
    do_rfi_32();
1804
    RETURN();
1805
}
1806
#endif
1807
#endif
1808

    
1809
/* Trap word */
1810
void OPPROTO op_tw (void)
1811
{
1812
    do_tw(PARAM1);
1813
    RETURN();
1814
}
1815

    
1816
#if defined(TARGET_PPC64)
1817
void OPPROTO op_td (void)
1818
{
1819
    do_td(PARAM1);
1820
    RETURN();
1821
}
1822
#endif
1823

    
1824
#if !defined(CONFIG_USER_ONLY)
1825
/* tlbia */
1826
PPC_OP(tlbia)
1827
{
1828
    do_tlbia();
1829
    RETURN();
1830
}
1831

    
1832
/* tlbie */
1833
void OPPROTO op_tlbie (void)
1834
{
1835
    do_tlbie();
1836
    RETURN();
1837
}
1838

    
1839
#if defined(TARGET_PPC64)
1840
void OPPROTO op_tlbie_64 (void)
1841
{
1842
    do_tlbie_64();
1843
    RETURN();
1844
}
1845
#endif
1846

    
1847
#if defined(TARGET_PPC64)
1848
void OPPROTO op_slbia (void)
1849
{
1850
    do_slbia();
1851
    RETURN();
1852
}
1853

    
1854
void OPPROTO op_slbie (void)
1855
{
1856
    do_slbie();
1857
    RETURN();
1858
}
1859
#endif
1860
#endif
1861

    
1862
/* PowerPC 602/603/755 software TLB load instructions */
1863
#if !defined(CONFIG_USER_ONLY)
1864
void OPPROTO op_6xx_tlbld (void)
1865
{
1866
    do_load_6xx_tlb(0);
1867
    RETURN();
1868
}
1869

    
1870
void OPPROTO op_6xx_tlbli (void)
1871
{
1872
    do_load_6xx_tlb(1);
1873
    RETURN();
1874
}
1875
#endif
1876

    
1877
/* 601 specific */
1878
void OPPROTO op_load_601_rtcl (void)
1879
{
1880
    T0 = cpu_ppc601_load_rtcl(env);
1881
    RETURN();
1882
}
1883

    
1884
void OPPROTO op_load_601_rtcu (void)
1885
{
1886
    T0 = cpu_ppc601_load_rtcu(env);
1887
    RETURN();
1888
}
1889

    
1890
#if !defined(CONFIG_USER_ONLY)
1891
void OPPROTO op_store_601_rtcl (void)
1892
{
1893
    cpu_ppc601_store_rtcl(env, T0);
1894
    RETURN();
1895
}
1896

    
1897
void OPPROTO op_store_601_rtcu (void)
1898
{
1899
    cpu_ppc601_store_rtcu(env, T0);
1900
    RETURN();
1901
}
1902

    
1903
void OPPROTO op_load_601_bat (void)
1904
{
1905
    T0 = env->IBAT[PARAM1][PARAM2];
1906
    RETURN();
1907
}
1908
#endif /* !defined(CONFIG_USER_ONLY) */
1909

    
1910
/* 601 unified BATs store.
1911
 * To avoid using specific MMU code for 601, we store BATs in
1912
 * IBAT and DBAT simultaneously, then emulate unified BATs.
1913
 */
1914
#if !defined(CONFIG_USER_ONLY)
1915
void OPPROTO op_store_601_batl (void)
1916
{
1917
    int nr = PARAM1;
1918

    
1919
    env->IBAT[1][nr] = T0;
1920
    env->DBAT[1][nr] = T0;
1921
    RETURN();
1922
}
1923

    
1924
void OPPROTO op_store_601_batu (void)
1925
{
1926
    do_store_601_batu(PARAM1);
1927
    RETURN();
1928
}
1929
#endif /* !defined(CONFIG_USER_ONLY) */
1930

    
1931
/* PowerPC 601 specific instructions (POWER bridge) */
1932
/* XXX: those micro-ops need tests ! */
1933
void OPPROTO op_POWER_abs (void)
1934
{
1935
    if (T0 == INT32_MIN)
1936
        T0 = INT32_MAX;
1937
    else if (T0 < 0)
1938
        T0 = -T0;
1939
    RETURN();
1940
}
1941

    
1942
void OPPROTO op_POWER_abso (void)
1943
{
1944
    do_POWER_abso();
1945
    RETURN();
1946
}
1947

    
1948
void OPPROTO op_POWER_clcs (void)
1949
{
1950
    do_POWER_clcs();
1951
    RETURN();
1952
}
1953

    
1954
void OPPROTO op_POWER_div (void)
1955
{
1956
    do_POWER_div();
1957
    RETURN();
1958
}
1959

    
1960
void OPPROTO op_POWER_divo (void)
1961
{
1962
    do_POWER_divo();
1963
    RETURN();
1964
}
1965

    
1966
void OPPROTO op_POWER_divs (void)
1967
{
1968
    do_POWER_divs();
1969
    RETURN();
1970
}
1971

    
1972
void OPPROTO op_POWER_divso (void)
1973
{
1974
    do_POWER_divso();
1975
    RETURN();
1976
}
1977

    
1978
void OPPROTO op_POWER_doz (void)
1979
{
1980
    if ((int32_t)T1 > (int32_t)T0)
1981
        T0 = T1 - T0;
1982
    else
1983
        T0 = 0;
1984
    RETURN();
1985
}
1986

    
1987
void OPPROTO op_POWER_dozo (void)
1988
{
1989
    do_POWER_dozo();
1990
    RETURN();
1991
}
1992

    
1993
void OPPROTO op_load_xer_cmp (void)
1994
{
1995
    T2 = xer_cmp;
1996
    RETURN();
1997
}
1998

    
1999
void OPPROTO op_POWER_maskg (void)
2000
{
2001
    do_POWER_maskg();
2002
    RETURN();
2003
}
2004

    
2005
void OPPROTO op_POWER_maskir (void)
2006
{
2007
    T0 = (T0 & ~T2) | (T1 & T2);
2008
    RETURN();
2009
}
2010

    
2011
void OPPROTO op_POWER_mul (void)
2012
{
2013
    uint64_t tmp;
2014

    
2015
    tmp = (uint64_t)T0 * (uint64_t)T1;
2016
    env->spr[SPR_MQ] = tmp >> 32;
2017
    T0 = tmp;
2018
    RETURN();
2019
}
2020

    
2021
void OPPROTO op_POWER_mulo (void)
2022
{
2023
    do_POWER_mulo();
2024
    RETURN();
2025
}
2026

    
2027
void OPPROTO op_POWER_nabs (void)
2028
{
2029
    if (T0 > 0)
2030
        T0 = -T0;
2031
    RETURN();
2032
}
2033

    
2034
void OPPROTO op_POWER_nabso (void)
2035
{
2036
    /* nabs never overflows */
2037
    if (T0 > 0)
2038
        T0 = -T0;
2039
    xer_ov = 0;
2040
    RETURN();
2041
}
2042

    
2043
/* XXX: factorise POWER rotates... */
2044
void OPPROTO op_POWER_rlmi (void)
2045
{
2046
    T0 = rotl32(T0, T2) & PARAM1;
2047
    T0 |= T1 & PARAM2;
2048
    RETURN();
2049
}
2050

    
2051
void OPPROTO op_POWER_rrib (void)
2052
{
2053
    T2 &= 0x1FUL;
2054
    T0 = rotl32(T0 & INT32_MIN, T2);
2055
    T0 |= T1 & ~rotl32(INT32_MIN, T2);
2056
    RETURN();
2057
}
2058

    
2059
void OPPROTO op_POWER_sle (void)
2060
{
2061
    T1 &= 0x1FUL;
2062
    env->spr[SPR_MQ] = rotl32(T0, T1);
2063
    T0 = T0 << T1;
2064
    RETURN();
2065
}
2066

    
2067
void OPPROTO op_POWER_sleq (void)
2068
{
2069
    uint32_t tmp = env->spr[SPR_MQ];
2070

    
2071
    T1 &= 0x1FUL;
2072
    env->spr[SPR_MQ] = rotl32(T0, T1);
2073
    T0 = T0 << T1;
2074
    T0 |= tmp >> (32 - T1);
2075
    RETURN();
2076
}
2077

    
2078
void OPPROTO op_POWER_sllq (void)
2079
{
2080
    uint32_t msk = -1;
2081

    
2082
    msk = msk << (T1 & 0x1FUL);
2083
    if (T1 & 0x20UL)
2084
        msk = ~msk;
2085
    T1 &= 0x1FUL;
2086
    T0 = (T0 << T1) & msk;
2087
    T0 |= env->spr[SPR_MQ] & ~msk;
2088
    RETURN();
2089
}
2090

    
2091
void OPPROTO op_POWER_slq (void)
2092
{
2093
    uint32_t msk = -1, tmp;
2094

    
2095
    msk = msk << (T1 & 0x1FUL);
2096
    if (T1 & 0x20UL)
2097
        msk = ~msk;
2098
    T1 &= 0x1FUL;
2099
    tmp = rotl32(T0, T1);
2100
    T0 = tmp & msk;
2101
    env->spr[SPR_MQ] = tmp;
2102
    RETURN();
2103
}
2104

    
2105
void OPPROTO op_POWER_sraq (void)
2106
{
2107
    env->spr[SPR_MQ] = rotl32(T0, 32 - (T1 & 0x1FUL));
2108
    if (T1 & 0x20UL)
2109
        T0 = -1L;
2110
    else
2111
        T0 = (int32_t)T0 >> T1;
2112
    RETURN();
2113
}
2114

    
2115
void OPPROTO op_POWER_sre (void)
2116
{
2117
    T1 &= 0x1FUL;
2118
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2119
    T0 = (int32_t)T0 >> T1;
2120
    RETURN();
2121
}
2122

    
2123
void OPPROTO op_POWER_srea (void)
2124
{
2125
    T1 &= 0x1FUL;
2126
    env->spr[SPR_MQ] = T0 >> T1;
2127
    T0 = (int32_t)T0 >> T1;
2128
    RETURN();
2129
}
2130

    
2131
void OPPROTO op_POWER_sreq (void)
2132
{
2133
    uint32_t tmp;
2134
    int32_t msk;
2135

    
2136
    T1 &= 0x1FUL;
2137
    msk = INT32_MIN >> T1;
2138
    tmp = env->spr[SPR_MQ];
2139
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2140
    T0 = T0 >> T1;
2141
    T0 |= tmp & msk;
2142
    RETURN();
2143
}
2144

    
2145
void OPPROTO op_POWER_srlq (void)
2146
{
2147
    uint32_t tmp;
2148
    int32_t msk;
2149

    
2150
    msk = INT32_MIN >> (T1 & 0x1FUL);
2151
    if (T1 & 0x20UL)
2152
        msk = ~msk;
2153
    T1 &= 0x1FUL;
2154
    tmp = env->spr[SPR_MQ];
2155
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2156
    T0 = T0 >> T1;
2157
    T0 &= msk;
2158
    T0 |= tmp & ~msk;
2159
    RETURN();
2160
}
2161

    
2162
void OPPROTO op_POWER_srq (void)
2163
{
2164
    T1 &= 0x1FUL;
2165
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2166
    T0 = T0 >> T1;
2167
    RETURN();
2168
}
2169

    
2170
/* POWER instructions not implemented in PowerPC 601 */
2171
#if !defined(CONFIG_USER_ONLY)
2172
void OPPROTO op_POWER_mfsri (void)
2173
{
2174
    T1 = T0 >> 28;
2175
    T0 = env->sr[T1];
2176
    RETURN();
2177
}
2178

    
2179
void OPPROTO op_POWER_rac (void)
2180
{
2181
    do_POWER_rac();
2182
    RETURN();
2183
}
2184

    
2185
void OPPROTO op_POWER_rfsvc (void)
2186
{
2187
    do_POWER_rfsvc();
2188
    RETURN();
2189
}
2190
#endif
2191

    
2192
/* PowerPC 602 specific instruction */
2193
#if !defined(CONFIG_USER_ONLY)
2194
void OPPROTO op_602_mfrom (void)
2195
{
2196
    do_op_602_mfrom();
2197
    RETURN();
2198
}
2199
#endif
2200

    
2201
/* PowerPC 4xx specific micro-ops */
2202
void OPPROTO op_405_add_T0_T2 (void)
2203
{
2204
    T0 = (int32_t)T0 + (int32_t)T2;
2205
    RETURN();
2206
}
2207

    
2208
void OPPROTO op_405_mulchw (void)
2209
{
2210
    T0 = ((int16_t)T0) * ((int16_t)(T1 >> 16));
2211
    RETURN();
2212
}
2213

    
2214
void OPPROTO op_405_mulchwu (void)
2215
{
2216
    T0 = ((uint16_t)T0) * ((uint16_t)(T1 >> 16));
2217
    RETURN();
2218
}
2219

    
2220
void OPPROTO op_405_mulhhw (void)
2221
{
2222
    T0 = ((int16_t)(T0 >> 16)) * ((int16_t)(T1 >> 16));
2223
    RETURN();
2224
}
2225

    
2226
void OPPROTO op_405_mulhhwu (void)
2227
{
2228
    T0 = ((uint16_t)(T0 >> 16)) * ((uint16_t)(T1 >> 16));
2229
    RETURN();
2230
}
2231

    
2232
void OPPROTO op_405_mullhw (void)
2233
{
2234
    T0 = ((int16_t)T0) * ((int16_t)T1);
2235
    RETURN();
2236
}
2237

    
2238
void OPPROTO op_405_mullhwu (void)
2239
{
2240
    T0 = ((uint16_t)T0) * ((uint16_t)T1);
2241
    RETURN();
2242
}
2243

    
2244
void OPPROTO op_405_check_ov (void)
2245
{
2246
    do_405_check_ov();
2247
    RETURN();
2248
}
2249

    
2250
void OPPROTO op_405_check_sat (void)
2251
{
2252
    do_405_check_sat();
2253
    RETURN();
2254
}
2255

    
2256
void OPPROTO op_405_check_ovu (void)
2257
{
2258
    if (likely(T0 >= T2)) {
2259
        xer_ov = 0;
2260
    } else {
2261
        xer_ov = 1;
2262
        xer_so = 1;
2263
    }
2264
    RETURN();
2265
}
2266

    
2267
void OPPROTO op_405_check_satu (void)
2268
{
2269
    if (unlikely(T0 < T2)) {
2270
        /* Saturate result */
2271
        T0 = -1;
2272
    }
2273
    RETURN();
2274
}
2275

    
2276
#if !defined(CONFIG_USER_ONLY)
2277
void OPPROTO op_4xx_load_dcr (void)
2278
{
2279
    do_4xx_load_dcr(PARAM1);
2280
    RETURN();
2281
}
2282

    
2283
void OPPROTO op_4xx_store_dcr (void)
2284
{
2285
    do_4xx_store_dcr(PARAM1);
2286
    RETURN();
2287
}
2288

    
2289
/* Return from critical interrupt :
2290
 * same as rfi, except nip & MSR are loaded from SRR2/3 instead of SRR0/1
2291
 */
2292
void OPPROTO op_4xx_rfci (void)
2293
{
2294
    do_4xx_rfci();
2295
    RETURN();
2296
}
2297

    
2298
void OPPROTO op_4xx_wrte (void)
2299
{
2300
    msr_ee = T0 >> 16;
2301
    RETURN();
2302
}
2303

    
2304
void OPPROTO op_4xx_tlbre_lo (void)
2305
{
2306
    do_4xx_tlbre_lo();
2307
    RETURN();
2308
}
2309

    
2310
void OPPROTO op_4xx_tlbre_hi (void)
2311
{
2312
    do_4xx_tlbre_hi();
2313
    RETURN();
2314
}
2315

    
2316
void OPPROTO op_4xx_tlbsx (void)
2317
{
2318
    do_4xx_tlbsx();
2319
    RETURN();
2320
}
2321

    
2322
void OPPROTO op_4xx_tlbsx_ (void)
2323
{
2324
    do_4xx_tlbsx_();
2325
    RETURN();
2326
}
2327

    
2328
void OPPROTO op_4xx_tlbwe_lo (void)
2329
{
2330
    do_4xx_tlbwe_lo();
2331
    RETURN();
2332
}
2333

    
2334
void OPPROTO op_4xx_tlbwe_hi (void)
2335
{
2336
    do_4xx_tlbwe_hi();
2337
    RETURN();
2338
}
2339
#endif
2340

    
2341
/* SPR micro-ops */
2342
/* 440 specific */
2343
void OPPROTO op_440_dlmzb (void)
2344
{
2345
    do_440_dlmzb();
2346
    RETURN();
2347
}
2348

    
2349
void OPPROTO op_440_dlmzb_update_Rc (void)
2350
{
2351
    if (T0 == 8)
2352
        T0 = 0x2;
2353
    else if (T0 < 4)
2354
        T0 = 0x4;
2355
    else
2356
        T0 = 0x8;
2357
    RETURN();
2358
}
2359

    
2360
#if !defined(CONFIG_USER_ONLY)
2361
void OPPROTO op_store_pir (void)
2362
{
2363
    env->spr[SPR_PIR] = T0 & 0x0000000FUL;
2364
    RETURN();
2365
}
2366

    
2367
void OPPROTO op_load_403_pb (void)
2368
{
2369
    do_load_403_pb(PARAM1);
2370
    RETURN();
2371
}
2372

    
2373
void OPPROTO op_store_403_pb (void)
2374
{
2375
    do_store_403_pb(PARAM1);
2376
    RETURN();
2377
}
2378

    
2379
void OPPROTO op_load_40x_pit (void)
2380
{
2381
    T0 = load_40x_pit(env);
2382
    RETURN();
2383
}
2384

    
2385
void OPPROTO op_store_40x_pit (void)
2386
{
2387
    store_40x_pit(env, T0);
2388
    RETURN();
2389
}
2390

    
2391
void OPPROTO op_store_booke_tcr (void)
2392
{
2393
    store_booke_tcr(env, T0);
2394
    RETURN();
2395
}
2396

    
2397
void OPPROTO op_store_booke_tsr (void)
2398
{
2399
    store_booke_tsr(env, T0);
2400
    RETURN();
2401
}
2402

    
2403
#endif /* !defined(CONFIG_USER_ONLY) */
2404

    
2405
#if defined(TARGET_PPCSPE)
2406
/* SPE extension */
2407
void OPPROTO op_splatw_T1_64 (void)
2408
{
2409
    T1_64 = (T1_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL);
2410
    RETURN();
2411
}
2412

    
2413
void OPPROTO op_splatwi_T0_64 (void)
2414
{
2415
    uint64_t tmp = PARAM1;
2416

    
2417
    T0_64 = (tmp << 32) | tmp;
2418
    RETURN();
2419
}
2420

    
2421
void OPPROTO op_splatwi_T1_64 (void)
2422
{
2423
    uint64_t tmp = PARAM1;
2424

    
2425
    T1_64 = (tmp << 32) | tmp;
2426
    RETURN();
2427
}
2428

    
2429
void OPPROTO op_extsh_T1_64 (void)
2430
{
2431
    T1_64 = (int32_t)((int16_t)T1_64);
2432
    RETURN();
2433
}
2434

    
2435
void OPPROTO op_sli16_T1_64 (void)
2436
{
2437
    T1_64 = T1_64 << 16;
2438
    RETURN();
2439
}
2440

    
2441
void OPPROTO op_sli32_T1_64 (void)
2442
{
2443
    T1_64 = T1_64 << 32;
2444
    RETURN();
2445
}
2446

    
2447
void OPPROTO op_srli32_T1_64 (void)
2448
{
2449
    T1_64 = T1_64 >> 32;
2450
    RETURN();
2451
}
2452

    
2453
void OPPROTO op_evsel (void)
2454
{
2455
    do_evsel();
2456
    RETURN();
2457
}
2458

    
2459
void OPPROTO op_evaddw (void)
2460
{
2461
    do_evaddw();
2462
    RETURN();
2463
}
2464

    
2465
void OPPROTO op_evsubfw (void)
2466
{
2467
    do_evsubfw();
2468
    RETURN();
2469
}
2470

    
2471
void OPPROTO op_evneg (void)
2472
{
2473
    do_evneg();
2474
    RETURN();
2475
}
2476

    
2477
void OPPROTO op_evabs (void)
2478
{
2479
    do_evabs();
2480
    RETURN();
2481
}
2482

    
2483
void OPPROTO op_evextsh (void)
2484
{
2485
    T0_64 = ((uint64_t)((int32_t)(int16_t)(T0_64 >> 32)) << 32) |
2486
        (uint64_t)((int32_t)(int16_t)T0_64);
2487
    RETURN();
2488
}
2489

    
2490
void OPPROTO op_evextsb (void)
2491
{
2492
    T0_64 = ((uint64_t)((int32_t)(int8_t)(T0_64 >> 32)) << 32) |
2493
        (uint64_t)((int32_t)(int8_t)T0_64);
2494
    RETURN();
2495
}
2496

    
2497
void OPPROTO op_evcntlzw (void)
2498
{
2499
    do_evcntlzw();
2500
    RETURN();
2501
}
2502

    
2503
void OPPROTO op_evrndw (void)
2504
{
2505
    do_evrndw();
2506
    RETURN();
2507
}
2508

    
2509
void OPPROTO op_brinc (void)
2510
{
2511
    do_brinc();
2512
    RETURN();
2513
}
2514

    
2515
void OPPROTO op_evcntlsw (void)
2516
{
2517
    do_evcntlsw();
2518
    RETURN();
2519
}
2520

    
2521
void OPPROTO op_evand (void)
2522
{
2523
    T0_64 &= T1_64;
2524
    RETURN();
2525
}
2526

    
2527
void OPPROTO op_evandc (void)
2528
{
2529
    T0_64 &= ~T1_64;
2530
    RETURN();
2531
}
2532

    
2533
void OPPROTO op_evor (void)
2534
{
2535
    T0_64 |= T1_64;
2536
    RETURN();
2537
}
2538

    
2539
void OPPROTO op_evxor (void)
2540
{
2541
    T0_64 ^= T1_64;
2542
    RETURN();
2543
}
2544

    
2545
void OPPROTO op_eveqv (void)
2546
{
2547
    T0_64 = ~(T0_64 ^ T1_64);
2548
    RETURN();
2549
}
2550

    
2551
void OPPROTO op_evnor (void)
2552
{
2553
    T0_64 = ~(T0_64 | T1_64);
2554
    RETURN();
2555
}
2556

    
2557
void OPPROTO op_evorc (void)
2558
{
2559
    T0_64 |= ~T1_64;
2560
    RETURN();
2561
}
2562

    
2563
void OPPROTO op_evnand (void)
2564
{
2565
    T0_64 = ~(T0_64 & T1_64);
2566
    RETURN();
2567
}
2568

    
2569
void OPPROTO op_evsrws (void)
2570
{
2571
    do_evsrws();
2572
    RETURN();
2573
}
2574

    
2575
void OPPROTO op_evsrwu (void)
2576
{
2577
    do_evsrwu();
2578
    RETURN();
2579
}
2580

    
2581
void OPPROTO op_evslw (void)
2582
{
2583
    do_evslw();
2584
    RETURN();
2585
}
2586

    
2587
void OPPROTO op_evrlw (void)
2588
{
2589
    do_evrlw();
2590
    RETURN();
2591
}
2592

    
2593
void OPPROTO op_evmergelo (void)
2594
{
2595
    T0_64 = (T0_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL);
2596
    RETURN();
2597
}
2598

    
2599
void OPPROTO op_evmergehi (void)
2600
{
2601
    T0_64 = (T0_64 & 0xFFFFFFFF00000000ULL) | (T1_64 >> 32);
2602
    RETURN();
2603
}
2604

    
2605
void OPPROTO op_evmergelohi (void)
2606
{
2607
    T0_64 = (T0_64 << 32) | (T1_64 >> 32);
2608
    RETURN();
2609
}
2610

    
2611
void OPPROTO op_evmergehilo (void)
2612
{
2613
    T0_64 = (T0_64 & 0xFFFFFFFF00000000ULL) | (T1_64 & 0x00000000FFFFFFFFULL);
2614
    RETURN();
2615
}
2616

    
2617
void OPPROTO op_evcmpgts (void)
2618
{
2619
    do_evcmpgts();
2620
    RETURN();
2621
}
2622

    
2623
void OPPROTO op_evcmpgtu (void)
2624
{
2625
    do_evcmpgtu();
2626
    RETURN();
2627
}
2628

    
2629
void OPPROTO op_evcmplts (void)
2630
{
2631
    do_evcmplts();
2632
    RETURN();
2633
}
2634

    
2635
void OPPROTO op_evcmpltu (void)
2636
{
2637
    do_evcmpltu();
2638
    RETURN();
2639
}
2640

    
2641
void OPPROTO op_evcmpeq (void)
2642
{
2643
    do_evcmpeq();
2644
    RETURN();
2645
}
2646

    
2647
void OPPROTO op_evfssub (void)
2648
{
2649
    do_evfssub();
2650
    RETURN();
2651
}
2652

    
2653
void OPPROTO op_evfsadd (void)
2654
{
2655
    do_evfsadd();
2656
    RETURN();
2657
}
2658

    
2659
void OPPROTO op_evfsnabs (void)
2660
{
2661
    do_evfsnabs();
2662
    RETURN();
2663
}
2664

    
2665
void OPPROTO op_evfsabs (void)
2666
{
2667
    do_evfsabs();
2668
    RETURN();
2669
}
2670

    
2671
void OPPROTO op_evfsneg (void)
2672
{
2673
    do_evfsneg();
2674
    RETURN();
2675
}
2676

    
2677
void OPPROTO op_evfsdiv (void)
2678
{
2679
    do_evfsdiv();
2680
    RETURN();
2681
}
2682

    
2683
void OPPROTO op_evfsmul (void)
2684
{
2685
    do_evfsmul();
2686
    RETURN();
2687
}
2688

    
2689
void OPPROTO op_evfscmplt (void)
2690
{
2691
    do_evfscmplt();
2692
    RETURN();
2693
}
2694

    
2695
void OPPROTO op_evfscmpgt (void)
2696
{
2697
    do_evfscmpgt();
2698
    RETURN();
2699
}
2700

    
2701
void OPPROTO op_evfscmpeq (void)
2702
{
2703
    do_evfscmpeq();
2704
    RETURN();
2705
}
2706

    
2707
void OPPROTO op_evfscfsi (void)
2708
{
2709
    do_evfscfsi();
2710
    RETURN();
2711
}
2712

    
2713
void OPPROTO op_evfscfui (void)
2714
{
2715
    do_evfscfui();
2716
    RETURN();
2717
}
2718

    
2719
void OPPROTO op_evfscfsf (void)
2720
{
2721
    do_evfscfsf();
2722
    RETURN();
2723
}
2724

    
2725
void OPPROTO op_evfscfuf (void)
2726
{
2727
    do_evfscfuf();
2728
    RETURN();
2729
}
2730

    
2731
void OPPROTO op_evfsctsi (void)
2732
{
2733
    do_evfsctsi();
2734
    RETURN();
2735
}
2736

    
2737
void OPPROTO op_evfsctui (void)
2738
{
2739
    do_evfsctui();
2740
    RETURN();
2741
}
2742

    
2743
void OPPROTO op_evfsctsf (void)
2744
{
2745
    do_evfsctsf();
2746
    RETURN();
2747
}
2748

    
2749
void OPPROTO op_evfsctuf (void)
2750
{
2751
    do_evfsctuf();
2752
    RETURN();
2753
}
2754

    
2755
void OPPROTO op_evfsctuiz (void)
2756
{
2757
    do_evfsctuiz();
2758
    RETURN();
2759
}
2760

    
2761
void OPPROTO op_evfsctsiz (void)
2762
{
2763
    do_evfsctsiz();
2764
    RETURN();
2765
}
2766

    
2767
void OPPROTO op_evfststlt (void)
2768
{
2769
    do_evfststlt();
2770
    RETURN();
2771
}
2772

    
2773
void OPPROTO op_evfststgt (void)
2774
{
2775
    do_evfststgt();
2776
    RETURN();
2777
}
2778

    
2779
void OPPROTO op_evfststeq (void)
2780
{
2781
    do_evfststeq();
2782
    RETURN();
2783
}
2784

    
2785
void OPPROTO op_efssub (void)
2786
{
2787
    T0_64 = _do_efssub(T0_64, T1_64);
2788
    RETURN();
2789
}
2790

    
2791
void OPPROTO op_efsadd (void)
2792
{
2793
    T0_64 = _do_efsadd(T0_64, T1_64);
2794
    RETURN();
2795
}
2796

    
2797
void OPPROTO op_efsnabs (void)
2798
{
2799
    T0_64 = _do_efsnabs(T0_64);
2800
    RETURN();
2801
}
2802

    
2803
void OPPROTO op_efsabs (void)
2804
{
2805
    T0_64 = _do_efsabs(T0_64);
2806
    RETURN();
2807
}
2808

    
2809
void OPPROTO op_efsneg (void)
2810
{
2811
    T0_64 = _do_efsneg(T0_64);
2812
    RETURN();
2813
}
2814

    
2815
void OPPROTO op_efsdiv (void)
2816
{
2817
    T0_64 = _do_efsdiv(T0_64, T1_64);
2818
    RETURN();
2819
}
2820

    
2821
void OPPROTO op_efsmul (void)
2822
{
2823
    T0_64 = _do_efsmul(T0_64, T1_64);
2824
    RETURN();
2825
}
2826

    
2827
void OPPROTO op_efscmplt (void)
2828
{
2829
    do_efscmplt();
2830
    RETURN();
2831
}
2832

    
2833
void OPPROTO op_efscmpgt (void)
2834
{
2835
    do_efscmpgt();
2836
    RETURN();
2837
}
2838

    
2839
void OPPROTO op_efscfd (void)
2840
{
2841
    do_efscfd();
2842
    RETURN();
2843
}
2844

    
2845
void OPPROTO op_efscmpeq (void)
2846
{
2847
    do_efscmpeq();
2848
    RETURN();
2849
}
2850

    
2851
void OPPROTO op_efscfsi (void)
2852
{
2853
    do_efscfsi();
2854
    RETURN();
2855
}
2856

    
2857
void OPPROTO op_efscfui (void)
2858
{
2859
    do_efscfui();
2860
    RETURN();
2861
}
2862

    
2863
void OPPROTO op_efscfsf (void)
2864
{
2865
    do_efscfsf();
2866
    RETURN();
2867
}
2868

    
2869
void OPPROTO op_efscfuf (void)
2870
{
2871
    do_efscfuf();
2872
    RETURN();
2873
}
2874

    
2875
void OPPROTO op_efsctsi (void)
2876
{
2877
    do_efsctsi();
2878
    RETURN();
2879
}
2880

    
2881
void OPPROTO op_efsctui (void)
2882
{
2883
    do_efsctui();
2884
    RETURN();
2885
}
2886

    
2887
void OPPROTO op_efsctsf (void)
2888
{
2889
    do_efsctsf();
2890
    RETURN();
2891
}
2892

    
2893
void OPPROTO op_efsctuf (void)
2894
{
2895
    do_efsctuf();
2896
    RETURN();
2897
}
2898

    
2899
void OPPROTO op_efsctsiz (void)
2900
{
2901
    do_efsctsiz();
2902
    RETURN();
2903
}
2904

    
2905
void OPPROTO op_efsctuiz (void)
2906
{
2907
    do_efsctuiz();
2908
    RETURN();
2909
}
2910

    
2911
void OPPROTO op_efststlt (void)
2912
{
2913
    T0 = _do_efststlt(T0_64, T1_64);
2914
    RETURN();
2915
}
2916

    
2917
void OPPROTO op_efststgt (void)
2918
{
2919
    T0 = _do_efststgt(T0_64, T1_64);
2920
    RETURN();
2921
}
2922

    
2923
void OPPROTO op_efststeq (void)
2924
{
2925
    T0 = _do_efststeq(T0_64, T1_64);
2926
    RETURN();
2927
}
2928

    
2929
void OPPROTO op_efdsub (void)
2930
{
2931
    union {
2932
        uint64_t u;
2933
        float64 f;
2934
    } u1, u2;
2935
    u1.u = T0_64;
2936
    u2.u = T1_64;
2937
    u1.f = float64_sub(u1.f, u2.f, &env->spe_status);
2938
    T0_64 = u1.u;
2939
    RETURN();
2940
}
2941

    
2942
void OPPROTO op_efdadd (void)
2943
{
2944
    union {
2945
        uint64_t u;
2946
        float64 f;
2947
    } u1, u2;
2948
    u1.u = T0_64;
2949
    u2.u = T1_64;
2950
    u1.f = float64_add(u1.f, u2.f, &env->spe_status);
2951
    T0_64 = u1.u;
2952
    RETURN();
2953
}
2954

    
2955
void OPPROTO op_efdcfsid (void)
2956
{
2957
    do_efdcfsi();
2958
    RETURN();
2959
}
2960

    
2961
void OPPROTO op_efdcfuid (void)
2962
{
2963
    do_efdcfui();
2964
    RETURN();
2965
}
2966

    
2967
void OPPROTO op_efdnabs (void)
2968
{
2969
    T0_64 |= 0x8000000000000000ULL;
2970
    RETURN();
2971
}
2972

    
2973
void OPPROTO op_efdabs (void)
2974
{
2975
    T0_64 &= ~0x8000000000000000ULL;
2976
    RETURN();
2977
}
2978

    
2979
void OPPROTO op_efdneg (void)
2980
{
2981
    T0_64 ^= 0x8000000000000000ULL;
2982
    RETURN();
2983
}
2984

    
2985
void OPPROTO op_efddiv (void)
2986
{
2987
    union {
2988
        uint64_t u;
2989
        float64 f;
2990
    } u1, u2;
2991
    u1.u = T0_64;
2992
    u2.u = T1_64;
2993
    u1.f = float64_div(u1.f, u2.f, &env->spe_status);
2994
    T0_64 = u1.u;
2995
    RETURN();
2996
}
2997

    
2998
void OPPROTO op_efdmul (void)
2999
{
3000
    union {
3001
        uint64_t u;
3002
        float64 f;
3003
    } u1, u2;
3004
    u1.u = T0_64;
3005
    u2.u = T1_64;
3006
    u1.f = float64_mul(u1.f, u2.f, &env->spe_status);
3007
    T0_64 = u1.u;
3008
    RETURN();
3009
}
3010

    
3011
void OPPROTO op_efdctsidz (void)
3012
{
3013
    do_efdctsiz();
3014
    RETURN();
3015
}
3016

    
3017
void OPPROTO op_efdctuidz (void)
3018
{
3019
    do_efdctuiz();
3020
    RETURN();
3021
}
3022

    
3023
void OPPROTO op_efdcmplt (void)
3024
{
3025
    do_efdcmplt();
3026
    RETURN();
3027
}
3028

    
3029
void OPPROTO op_efdcmpgt (void)
3030
{
3031
    do_efdcmpgt();
3032
    RETURN();
3033
}
3034

    
3035
void OPPROTO op_efdcfs (void)
3036
{
3037
    do_efdcfs();
3038
    RETURN();
3039
}
3040

    
3041
void OPPROTO op_efdcmpeq (void)
3042
{
3043
    do_efdcmpeq();
3044
    RETURN();
3045
}
3046

    
3047
void OPPROTO op_efdcfsi (void)
3048
{
3049
    do_efdcfsi();
3050
    RETURN();
3051
}
3052

    
3053
void OPPROTO op_efdcfui (void)
3054
{
3055
    do_efdcfui();
3056
    RETURN();
3057
}
3058

    
3059
void OPPROTO op_efdcfsf (void)
3060
{
3061
    do_efdcfsf();
3062
    RETURN();
3063
}
3064

    
3065
void OPPROTO op_efdcfuf (void)
3066
{
3067
    do_efdcfuf();
3068
    RETURN();
3069
}
3070

    
3071
void OPPROTO op_efdctsi (void)
3072
{
3073
    do_efdctsi();
3074
    RETURN();
3075
}
3076

    
3077
void OPPROTO op_efdctui (void)
3078
{
3079
    do_efdctui();
3080
    RETURN();
3081
}
3082

    
3083
void OPPROTO op_efdctsf (void)
3084
{
3085
    do_efdctsf();
3086
    RETURN();
3087
}
3088

    
3089
void OPPROTO op_efdctuf (void)
3090
{
3091
    do_efdctuf();
3092
    RETURN();
3093
}
3094

    
3095
void OPPROTO op_efdctuiz (void)
3096
{
3097
    do_efdctuiz();
3098
    RETURN();
3099
}
3100

    
3101
void OPPROTO op_efdctsiz (void)
3102
{
3103
    do_efdctsiz();
3104
    RETURN();
3105
}
3106

    
3107
void OPPROTO op_efdtstlt (void)
3108
{
3109
    T0 = _do_efdtstlt(T0_64, T1_64);
3110
    RETURN();
3111
}
3112

    
3113
void OPPROTO op_efdtstgt (void)
3114
{
3115
    T0 = _do_efdtstgt(T0_64, T1_64);
3116
    RETURN();
3117
}
3118

    
3119
void OPPROTO op_efdtsteq (void)
3120
{
3121
    T0 = _do_efdtsteq(T0_64, T1_64);
3122
    RETURN();
3123
}
3124
#endif /* defined(TARGET_PPCSPE) */