Statistics
| Branch: | Revision:

root / target-ppc / op.c @ a42bd6cc

History | View | Annotate | Download (45.1 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
#if defined(TARGET_PPC64)
1725
/* fcfid - fcfid. */
1726
PPC_OP(fcfid)
1727
{
1728
    do_fcfid();
1729
    RETURN();
1730
}
1731

    
1732
/* fctid - fctid. */
1733
PPC_OP(fctid)
1734
{
1735
    do_fctid();
1736
    RETURN();
1737
}
1738

    
1739
/* fctidz - fctidz. */
1740
PPC_OP(fctidz)
1741
{
1742
    do_fctidz();
1743
    RETURN();
1744
}
1745
#endif
1746

    
1747
/***                         Floating-Point compare                        ***/
1748
/* fcmpu */
1749
PPC_OP(fcmpu)
1750
{
1751
    do_fcmpu();
1752
    RETURN();
1753
}
1754

    
1755
/* fcmpo */
1756
PPC_OP(fcmpo)
1757
{
1758
    do_fcmpo();
1759
    RETURN();
1760
}
1761

    
1762
/***                         Floating-point move                           ***/
1763
/* fabs */
1764
PPC_OP(fabs)
1765
{
1766
    FT0 = float64_abs(FT0);
1767
    RETURN();
1768
}
1769

    
1770
/* fnabs */
1771
PPC_OP(fnabs)
1772
{
1773
    FT0 = float64_abs(FT0);
1774
    FT0 = float64_chs(FT0);
1775
    RETURN();
1776
}
1777

    
1778
/* fneg */
1779
PPC_OP(fneg)
1780
{
1781
    FT0 = float64_chs(FT0);
1782
    RETURN();
1783
}
1784

    
1785
/* Load and store */
1786
#define MEMSUFFIX _raw
1787
#include "op_helper.h"
1788
#include "op_mem.h"
1789
#if !defined(CONFIG_USER_ONLY)
1790
#define MEMSUFFIX _user
1791
#include "op_helper.h"
1792
#include "op_mem.h"
1793
#define MEMSUFFIX _kernel
1794
#include "op_helper.h"
1795
#include "op_mem.h"
1796
#endif
1797

    
1798
/* Special op to check and maybe clear reservation */
1799
void OPPROTO op_check_reservation (void)
1800
{
1801
    if ((uint32_t)env->reserve == (uint32_t)(T0 & ~0x00000003))
1802
        env->reserve = -1;
1803
    RETURN();
1804
}
1805

    
1806
#if defined(TARGET_PPC64)
1807
void OPPROTO op_check_reservation_64 (void)
1808
{
1809
    if ((uint64_t)env->reserve == (uint64_t)(T0 & ~0x00000003))
1810
        env->reserve = -1;
1811
    RETURN();
1812
}
1813
#endif
1814

    
1815
/* Return from interrupt */
1816
#if !defined(CONFIG_USER_ONLY)
1817
void OPPROTO op_rfi (void)
1818
{
1819
    do_rfi();
1820
    RETURN();
1821
}
1822

    
1823
#if defined(TARGET_PPC64)
1824
void OPPROTO op_rfid (void)
1825
{
1826
    do_rfid();
1827
    RETURN();
1828
}
1829
#endif
1830
#endif
1831

    
1832
/* Trap word */
1833
void OPPROTO op_tw (void)
1834
{
1835
    do_tw(PARAM1);
1836
    RETURN();
1837
}
1838

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

    
1847
#if !defined(CONFIG_USER_ONLY)
1848
/* tlbia */
1849
PPC_OP(tlbia)
1850
{
1851
    do_tlbia();
1852
    RETURN();
1853
}
1854

    
1855
/* tlbie */
1856
void OPPROTO op_tlbie (void)
1857
{
1858
    do_tlbie();
1859
    RETURN();
1860
}
1861

    
1862
#if defined(TARGET_PPC64)
1863
void OPPROTO op_tlbie_64 (void)
1864
{
1865
    do_tlbie_64();
1866
    RETURN();
1867
}
1868
#endif
1869

    
1870
#if defined(TARGET_PPC64)
1871
void OPPROTO op_slbia (void)
1872
{
1873
    do_slbia();
1874
    RETURN();
1875
}
1876

    
1877
void OPPROTO op_slbie (void)
1878
{
1879
    do_slbie();
1880
    RETURN();
1881
}
1882
#endif
1883
#endif
1884

    
1885
/* PowerPC 602/603/755 software TLB load instructions */
1886
#if !defined(CONFIG_USER_ONLY)
1887
void OPPROTO op_6xx_tlbld (void)
1888
{
1889
    do_load_6xx_tlb(0);
1890
    RETURN();
1891
}
1892

    
1893
void OPPROTO op_6xx_tlbli (void)
1894
{
1895
    do_load_6xx_tlb(1);
1896
    RETURN();
1897
}
1898
#endif
1899

    
1900
/* 601 specific */
1901
void OPPROTO op_load_601_rtcl (void)
1902
{
1903
    T0 = cpu_ppc601_load_rtcl(env);
1904
    RETURN();
1905
}
1906

    
1907
void OPPROTO op_load_601_rtcu (void)
1908
{
1909
    T0 = cpu_ppc601_load_rtcu(env);
1910
    RETURN();
1911
}
1912

    
1913
#if !defined(CONFIG_USER_ONLY)
1914
void OPPROTO op_store_601_rtcl (void)
1915
{
1916
    cpu_ppc601_store_rtcl(env, T0);
1917
    RETURN();
1918
}
1919

    
1920
void OPPROTO op_store_601_rtcu (void)
1921
{
1922
    cpu_ppc601_store_rtcu(env, T0);
1923
    RETURN();
1924
}
1925

    
1926
void OPPROTO op_load_601_bat (void)
1927
{
1928
    T0 = env->IBAT[PARAM1][PARAM2];
1929
    RETURN();
1930
}
1931
#endif /* !defined(CONFIG_USER_ONLY) */
1932

    
1933
/* 601 unified BATs store.
1934
 * To avoid using specific MMU code for 601, we store BATs in
1935
 * IBAT and DBAT simultaneously, then emulate unified BATs.
1936
 */
1937
#if !defined(CONFIG_USER_ONLY)
1938
void OPPROTO op_store_601_batl (void)
1939
{
1940
    int nr = PARAM1;
1941

    
1942
    env->IBAT[1][nr] = T0;
1943
    env->DBAT[1][nr] = T0;
1944
    RETURN();
1945
}
1946

    
1947
void OPPROTO op_store_601_batu (void)
1948
{
1949
    do_store_601_batu(PARAM1);
1950
    RETURN();
1951
}
1952
#endif /* !defined(CONFIG_USER_ONLY) */
1953

    
1954
/* PowerPC 601 specific instructions (POWER bridge) */
1955
/* XXX: those micro-ops need tests ! */
1956
void OPPROTO op_POWER_abs (void)
1957
{
1958
    if (T0 == INT32_MIN)
1959
        T0 = INT32_MAX;
1960
    else if (T0 < 0)
1961
        T0 = -T0;
1962
    RETURN();
1963
}
1964

    
1965
void OPPROTO op_POWER_abso (void)
1966
{
1967
    do_POWER_abso();
1968
    RETURN();
1969
}
1970

    
1971
void OPPROTO op_POWER_clcs (void)
1972
{
1973
    do_POWER_clcs();
1974
    RETURN();
1975
}
1976

    
1977
void OPPROTO op_POWER_div (void)
1978
{
1979
    do_POWER_div();
1980
    RETURN();
1981
}
1982

    
1983
void OPPROTO op_POWER_divo (void)
1984
{
1985
    do_POWER_divo();
1986
    RETURN();
1987
}
1988

    
1989
void OPPROTO op_POWER_divs (void)
1990
{
1991
    do_POWER_divs();
1992
    RETURN();
1993
}
1994

    
1995
void OPPROTO op_POWER_divso (void)
1996
{
1997
    do_POWER_divso();
1998
    RETURN();
1999
}
2000

    
2001
void OPPROTO op_POWER_doz (void)
2002
{
2003
    if ((int32_t)T1 > (int32_t)T0)
2004
        T0 = T1 - T0;
2005
    else
2006
        T0 = 0;
2007
    RETURN();
2008
}
2009

    
2010
void OPPROTO op_POWER_dozo (void)
2011
{
2012
    do_POWER_dozo();
2013
    RETURN();
2014
}
2015

    
2016
void OPPROTO op_load_xer_cmp (void)
2017
{
2018
    T2 = xer_cmp;
2019
    RETURN();
2020
}
2021

    
2022
void OPPROTO op_POWER_maskg (void)
2023
{
2024
    do_POWER_maskg();
2025
    RETURN();
2026
}
2027

    
2028
void OPPROTO op_POWER_maskir (void)
2029
{
2030
    T0 = (T0 & ~T2) | (T1 & T2);
2031
    RETURN();
2032
}
2033

    
2034
void OPPROTO op_POWER_mul (void)
2035
{
2036
    uint64_t tmp;
2037

    
2038
    tmp = (uint64_t)T0 * (uint64_t)T1;
2039
    env->spr[SPR_MQ] = tmp >> 32;
2040
    T0 = tmp;
2041
    RETURN();
2042
}
2043

    
2044
void OPPROTO op_POWER_mulo (void)
2045
{
2046
    do_POWER_mulo();
2047
    RETURN();
2048
}
2049

    
2050
void OPPROTO op_POWER_nabs (void)
2051
{
2052
    if (T0 > 0)
2053
        T0 = -T0;
2054
    RETURN();
2055
}
2056

    
2057
void OPPROTO op_POWER_nabso (void)
2058
{
2059
    /* nabs never overflows */
2060
    if (T0 > 0)
2061
        T0 = -T0;
2062
    xer_ov = 0;
2063
    RETURN();
2064
}
2065

    
2066
/* XXX: factorise POWER rotates... */
2067
void OPPROTO op_POWER_rlmi (void)
2068
{
2069
    T0 = rotl32(T0, T2) & PARAM1;
2070
    T0 |= T1 & PARAM2;
2071
    RETURN();
2072
}
2073

    
2074
void OPPROTO op_POWER_rrib (void)
2075
{
2076
    T2 &= 0x1FUL;
2077
    T0 = rotl32(T0 & INT32_MIN, T2);
2078
    T0 |= T1 & ~rotl32(INT32_MIN, T2);
2079
    RETURN();
2080
}
2081

    
2082
void OPPROTO op_POWER_sle (void)
2083
{
2084
    T1 &= 0x1FUL;
2085
    env->spr[SPR_MQ] = rotl32(T0, T1);
2086
    T0 = T0 << T1;
2087
    RETURN();
2088
}
2089

    
2090
void OPPROTO op_POWER_sleq (void)
2091
{
2092
    uint32_t tmp = env->spr[SPR_MQ];
2093

    
2094
    T1 &= 0x1FUL;
2095
    env->spr[SPR_MQ] = rotl32(T0, T1);
2096
    T0 = T0 << T1;
2097
    T0 |= tmp >> (32 - T1);
2098
    RETURN();
2099
}
2100

    
2101
void OPPROTO op_POWER_sllq (void)
2102
{
2103
    uint32_t msk = -1;
2104

    
2105
    msk = msk << (T1 & 0x1FUL);
2106
    if (T1 & 0x20UL)
2107
        msk = ~msk;
2108
    T1 &= 0x1FUL;
2109
    T0 = (T0 << T1) & msk;
2110
    T0 |= env->spr[SPR_MQ] & ~msk;
2111
    RETURN();
2112
}
2113

    
2114
void OPPROTO op_POWER_slq (void)
2115
{
2116
    uint32_t msk = -1, tmp;
2117

    
2118
    msk = msk << (T1 & 0x1FUL);
2119
    if (T1 & 0x20UL)
2120
        msk = ~msk;
2121
    T1 &= 0x1FUL;
2122
    tmp = rotl32(T0, T1);
2123
    T0 = tmp & msk;
2124
    env->spr[SPR_MQ] = tmp;
2125
    RETURN();
2126
}
2127

    
2128
void OPPROTO op_POWER_sraq (void)
2129
{
2130
    env->spr[SPR_MQ] = rotl32(T0, 32 - (T1 & 0x1FUL));
2131
    if (T1 & 0x20UL)
2132
        T0 = -1L;
2133
    else
2134
        T0 = (int32_t)T0 >> T1;
2135
    RETURN();
2136
}
2137

    
2138
void OPPROTO op_POWER_sre (void)
2139
{
2140
    T1 &= 0x1FUL;
2141
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2142
    T0 = (int32_t)T0 >> T1;
2143
    RETURN();
2144
}
2145

    
2146
void OPPROTO op_POWER_srea (void)
2147
{
2148
    T1 &= 0x1FUL;
2149
    env->spr[SPR_MQ] = T0 >> T1;
2150
    T0 = (int32_t)T0 >> T1;
2151
    RETURN();
2152
}
2153

    
2154
void OPPROTO op_POWER_sreq (void)
2155
{
2156
    uint32_t tmp;
2157
    int32_t msk;
2158

    
2159
    T1 &= 0x1FUL;
2160
    msk = INT32_MIN >> T1;
2161
    tmp = env->spr[SPR_MQ];
2162
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2163
    T0 = T0 >> T1;
2164
    T0 |= tmp & msk;
2165
    RETURN();
2166
}
2167

    
2168
void OPPROTO op_POWER_srlq (void)
2169
{
2170
    uint32_t tmp;
2171
    int32_t msk;
2172

    
2173
    msk = INT32_MIN >> (T1 & 0x1FUL);
2174
    if (T1 & 0x20UL)
2175
        msk = ~msk;
2176
    T1 &= 0x1FUL;
2177
    tmp = env->spr[SPR_MQ];
2178
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2179
    T0 = T0 >> T1;
2180
    T0 &= msk;
2181
    T0 |= tmp & ~msk;
2182
    RETURN();
2183
}
2184

    
2185
void OPPROTO op_POWER_srq (void)
2186
{
2187
    T1 &= 0x1FUL;
2188
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2189
    T0 = T0 >> T1;
2190
    RETURN();
2191
}
2192

    
2193
/* POWER instructions not implemented in PowerPC 601 */
2194
#if !defined(CONFIG_USER_ONLY)
2195
void OPPROTO op_POWER_mfsri (void)
2196
{
2197
    T1 = T0 >> 28;
2198
    T0 = env->sr[T1];
2199
    RETURN();
2200
}
2201

    
2202
void OPPROTO op_POWER_rac (void)
2203
{
2204
    do_POWER_rac();
2205
    RETURN();
2206
}
2207

    
2208
void OPPROTO op_POWER_rfsvc (void)
2209
{
2210
    do_POWER_rfsvc();
2211
    RETURN();
2212
}
2213
#endif
2214

    
2215
/* PowerPC 602 specific instruction */
2216
#if !defined(CONFIG_USER_ONLY)
2217
void OPPROTO op_602_mfrom (void)
2218
{
2219
    do_op_602_mfrom();
2220
    RETURN();
2221
}
2222
#endif
2223

    
2224
/* PowerPC 4xx specific micro-ops */
2225
void OPPROTO op_405_add_T0_T2 (void)
2226
{
2227
    T0 = (int32_t)T0 + (int32_t)T2;
2228
    RETURN();
2229
}
2230

    
2231
void OPPROTO op_405_mulchw (void)
2232
{
2233
    T0 = ((int16_t)T0) * ((int16_t)(T1 >> 16));
2234
    RETURN();
2235
}
2236

    
2237
void OPPROTO op_405_mulchwu (void)
2238
{
2239
    T0 = ((uint16_t)T0) * ((uint16_t)(T1 >> 16));
2240
    RETURN();
2241
}
2242

    
2243
void OPPROTO op_405_mulhhw (void)
2244
{
2245
    T0 = ((int16_t)(T0 >> 16)) * ((int16_t)(T1 >> 16));
2246
    RETURN();
2247
}
2248

    
2249
void OPPROTO op_405_mulhhwu (void)
2250
{
2251
    T0 = ((uint16_t)(T0 >> 16)) * ((uint16_t)(T1 >> 16));
2252
    RETURN();
2253
}
2254

    
2255
void OPPROTO op_405_mullhw (void)
2256
{
2257
    T0 = ((int16_t)T0) * ((int16_t)T1);
2258
    RETURN();
2259
}
2260

    
2261
void OPPROTO op_405_mullhwu (void)
2262
{
2263
    T0 = ((uint16_t)T0) * ((uint16_t)T1);
2264
    RETURN();
2265
}
2266

    
2267
void OPPROTO op_405_check_ov (void)
2268
{
2269
    do_405_check_ov();
2270
    RETURN();
2271
}
2272

    
2273
void OPPROTO op_405_check_sat (void)
2274
{
2275
    do_405_check_sat();
2276
    RETURN();
2277
}
2278

    
2279
void OPPROTO op_405_check_ovu (void)
2280
{
2281
    if (likely(T0 >= T2)) {
2282
        xer_ov = 0;
2283
    } else {
2284
        xer_ov = 1;
2285
        xer_so = 1;
2286
    }
2287
    RETURN();
2288
}
2289

    
2290
void OPPROTO op_405_check_satu (void)
2291
{
2292
    if (unlikely(T0 < T2)) {
2293
        /* Saturate result */
2294
        T0 = -1;
2295
    }
2296
    RETURN();
2297
}
2298

    
2299
#if !defined(CONFIG_USER_ONLY)
2300
void OPPROTO op_load_dcr (void)
2301
{
2302
    do_load_dcr();
2303
    RETURN();
2304
}
2305

    
2306
void OPPROTO op_store_dcr (void)
2307
{
2308
    do_store_dcr();
2309
    RETURN();
2310
}
2311

    
2312
/* Return from critical interrupt :
2313
 * same as rfi, except nip & MSR are loaded from SRR2/3 instead of SRR0/1
2314
 */
2315
void OPPROTO op_40x_rfci (void)
2316
{
2317
    do_40x_rfci();
2318
    RETURN();
2319
}
2320

    
2321
void OPPROTO op_rfci (void)
2322
{
2323
    do_rfci();
2324
    RETURN();
2325
}
2326

    
2327
void OPPROTO op_rfdi (void)
2328
{
2329
    do_rfdi();
2330
    RETURN();
2331
}
2332

    
2333
void OPPROTO op_rfmci (void)
2334
{
2335
    do_rfmci();
2336
    RETURN();
2337
}
2338

    
2339
void OPPROTO op_wrte (void)
2340
{
2341
    msr_ee = T0 >> 16;
2342
    RETURN();
2343
}
2344

    
2345
void OPPROTO op_4xx_tlbre_lo (void)
2346
{
2347
    do_4xx_tlbre_lo();
2348
    RETURN();
2349
}
2350

    
2351
void OPPROTO op_4xx_tlbre_hi (void)
2352
{
2353
    do_4xx_tlbre_hi();
2354
    RETURN();
2355
}
2356

    
2357
void OPPROTO op_4xx_tlbsx (void)
2358
{
2359
    do_4xx_tlbsx();
2360
    RETURN();
2361
}
2362

    
2363
void OPPROTO op_4xx_tlbsx_ (void)
2364
{
2365
    do_4xx_tlbsx_();
2366
    RETURN();
2367
}
2368

    
2369
void OPPROTO op_4xx_tlbwe_lo (void)
2370
{
2371
    do_4xx_tlbwe_lo();
2372
    RETURN();
2373
}
2374

    
2375
void OPPROTO op_4xx_tlbwe_hi (void)
2376
{
2377
    do_4xx_tlbwe_hi();
2378
    RETURN();
2379
}
2380
#endif
2381

    
2382
/* SPR micro-ops */
2383
/* 440 specific */
2384
void OPPROTO op_440_dlmzb (void)
2385
{
2386
    do_440_dlmzb();
2387
    RETURN();
2388
}
2389

    
2390
void OPPROTO op_440_dlmzb_update_Rc (void)
2391
{
2392
    if (T0 == 8)
2393
        T0 = 0x2;
2394
    else if (T0 < 4)
2395
        T0 = 0x4;
2396
    else
2397
        T0 = 0x8;
2398
    RETURN();
2399
}
2400

    
2401
#if !defined(CONFIG_USER_ONLY)
2402
void OPPROTO op_store_pir (void)
2403
{
2404
    env->spr[SPR_PIR] = T0 & 0x0000000FUL;
2405
    RETURN();
2406
}
2407

    
2408
void OPPROTO op_load_403_pb (void)
2409
{
2410
    do_load_403_pb(PARAM1);
2411
    RETURN();
2412
}
2413

    
2414
void OPPROTO op_store_403_pb (void)
2415
{
2416
    do_store_403_pb(PARAM1);
2417
    RETURN();
2418
}
2419

    
2420
void OPPROTO op_load_40x_pit (void)
2421
{
2422
    T0 = load_40x_pit(env);
2423
    RETURN();
2424
}
2425

    
2426
void OPPROTO op_store_40x_pit (void)
2427
{
2428
    store_40x_pit(env, T0);
2429
    RETURN();
2430
}
2431

    
2432
void OPPROTO op_store_booke_tcr (void)
2433
{
2434
    store_booke_tcr(env, T0);
2435
    RETURN();
2436
}
2437

    
2438
void OPPROTO op_store_booke_tsr (void)
2439
{
2440
    store_booke_tsr(env, T0);
2441
    RETURN();
2442
}
2443

    
2444
#endif /* !defined(CONFIG_USER_ONLY) */
2445

    
2446
#if defined(TARGET_PPCSPE)
2447
/* SPE extension */
2448
void OPPROTO op_splatw_T1_64 (void)
2449
{
2450
    T1_64 = (T1_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL);
2451
    RETURN();
2452
}
2453

    
2454
void OPPROTO op_splatwi_T0_64 (void)
2455
{
2456
    uint64_t tmp = PARAM1;
2457

    
2458
    T0_64 = (tmp << 32) | tmp;
2459
    RETURN();
2460
}
2461

    
2462
void OPPROTO op_splatwi_T1_64 (void)
2463
{
2464
    uint64_t tmp = PARAM1;
2465

    
2466
    T1_64 = (tmp << 32) | tmp;
2467
    RETURN();
2468
}
2469

    
2470
void OPPROTO op_extsh_T1_64 (void)
2471
{
2472
    T1_64 = (int32_t)((int16_t)T1_64);
2473
    RETURN();
2474
}
2475

    
2476
void OPPROTO op_sli16_T1_64 (void)
2477
{
2478
    T1_64 = T1_64 << 16;
2479
    RETURN();
2480
}
2481

    
2482
void OPPROTO op_sli32_T1_64 (void)
2483
{
2484
    T1_64 = T1_64 << 32;
2485
    RETURN();
2486
}
2487

    
2488
void OPPROTO op_srli32_T1_64 (void)
2489
{
2490
    T1_64 = T1_64 >> 32;
2491
    RETURN();
2492
}
2493

    
2494
void OPPROTO op_evsel (void)
2495
{
2496
    do_evsel();
2497
    RETURN();
2498
}
2499

    
2500
void OPPROTO op_evaddw (void)
2501
{
2502
    do_evaddw();
2503
    RETURN();
2504
}
2505

    
2506
void OPPROTO op_evsubfw (void)
2507
{
2508
    do_evsubfw();
2509
    RETURN();
2510
}
2511

    
2512
void OPPROTO op_evneg (void)
2513
{
2514
    do_evneg();
2515
    RETURN();
2516
}
2517

    
2518
void OPPROTO op_evabs (void)
2519
{
2520
    do_evabs();
2521
    RETURN();
2522
}
2523

    
2524
void OPPROTO op_evextsh (void)
2525
{
2526
    T0_64 = ((uint64_t)((int32_t)(int16_t)(T0_64 >> 32)) << 32) |
2527
        (uint64_t)((int32_t)(int16_t)T0_64);
2528
    RETURN();
2529
}
2530

    
2531
void OPPROTO op_evextsb (void)
2532
{
2533
    T0_64 = ((uint64_t)((int32_t)(int8_t)(T0_64 >> 32)) << 32) |
2534
        (uint64_t)((int32_t)(int8_t)T0_64);
2535
    RETURN();
2536
}
2537

    
2538
void OPPROTO op_evcntlzw (void)
2539
{
2540
    do_evcntlzw();
2541
    RETURN();
2542
}
2543

    
2544
void OPPROTO op_evrndw (void)
2545
{
2546
    do_evrndw();
2547
    RETURN();
2548
}
2549

    
2550
void OPPROTO op_brinc (void)
2551
{
2552
    do_brinc();
2553
    RETURN();
2554
}
2555

    
2556
void OPPROTO op_evcntlsw (void)
2557
{
2558
    do_evcntlsw();
2559
    RETURN();
2560
}
2561

    
2562
void OPPROTO op_evand (void)
2563
{
2564
    T0_64 &= T1_64;
2565
    RETURN();
2566
}
2567

    
2568
void OPPROTO op_evandc (void)
2569
{
2570
    T0_64 &= ~T1_64;
2571
    RETURN();
2572
}
2573

    
2574
void OPPROTO op_evor (void)
2575
{
2576
    T0_64 |= T1_64;
2577
    RETURN();
2578
}
2579

    
2580
void OPPROTO op_evxor (void)
2581
{
2582
    T0_64 ^= T1_64;
2583
    RETURN();
2584
}
2585

    
2586
void OPPROTO op_eveqv (void)
2587
{
2588
    T0_64 = ~(T0_64 ^ T1_64);
2589
    RETURN();
2590
}
2591

    
2592
void OPPROTO op_evnor (void)
2593
{
2594
    T0_64 = ~(T0_64 | T1_64);
2595
    RETURN();
2596
}
2597

    
2598
void OPPROTO op_evorc (void)
2599
{
2600
    T0_64 |= ~T1_64;
2601
    RETURN();
2602
}
2603

    
2604
void OPPROTO op_evnand (void)
2605
{
2606
    T0_64 = ~(T0_64 & T1_64);
2607
    RETURN();
2608
}
2609

    
2610
void OPPROTO op_evsrws (void)
2611
{
2612
    do_evsrws();
2613
    RETURN();
2614
}
2615

    
2616
void OPPROTO op_evsrwu (void)
2617
{
2618
    do_evsrwu();
2619
    RETURN();
2620
}
2621

    
2622
void OPPROTO op_evslw (void)
2623
{
2624
    do_evslw();
2625
    RETURN();
2626
}
2627

    
2628
void OPPROTO op_evrlw (void)
2629
{
2630
    do_evrlw();
2631
    RETURN();
2632
}
2633

    
2634
void OPPROTO op_evmergelo (void)
2635
{
2636
    T0_64 = (T0_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL);
2637
    RETURN();
2638
}
2639

    
2640
void OPPROTO op_evmergehi (void)
2641
{
2642
    T0_64 = (T0_64 & 0xFFFFFFFF00000000ULL) | (T1_64 >> 32);
2643
    RETURN();
2644
}
2645

    
2646
void OPPROTO op_evmergelohi (void)
2647
{
2648
    T0_64 = (T0_64 << 32) | (T1_64 >> 32);
2649
    RETURN();
2650
}
2651

    
2652
void OPPROTO op_evmergehilo (void)
2653
{
2654
    T0_64 = (T0_64 & 0xFFFFFFFF00000000ULL) | (T1_64 & 0x00000000FFFFFFFFULL);
2655
    RETURN();
2656
}
2657

    
2658
void OPPROTO op_evcmpgts (void)
2659
{
2660
    do_evcmpgts();
2661
    RETURN();
2662
}
2663

    
2664
void OPPROTO op_evcmpgtu (void)
2665
{
2666
    do_evcmpgtu();
2667
    RETURN();
2668
}
2669

    
2670
void OPPROTO op_evcmplts (void)
2671
{
2672
    do_evcmplts();
2673
    RETURN();
2674
}
2675

    
2676
void OPPROTO op_evcmpltu (void)
2677
{
2678
    do_evcmpltu();
2679
    RETURN();
2680
}
2681

    
2682
void OPPROTO op_evcmpeq (void)
2683
{
2684
    do_evcmpeq();
2685
    RETURN();
2686
}
2687

    
2688
void OPPROTO op_evfssub (void)
2689
{
2690
    do_evfssub();
2691
    RETURN();
2692
}
2693

    
2694
void OPPROTO op_evfsadd (void)
2695
{
2696
    do_evfsadd();
2697
    RETURN();
2698
}
2699

    
2700
void OPPROTO op_evfsnabs (void)
2701
{
2702
    do_evfsnabs();
2703
    RETURN();
2704
}
2705

    
2706
void OPPROTO op_evfsabs (void)
2707
{
2708
    do_evfsabs();
2709
    RETURN();
2710
}
2711

    
2712
void OPPROTO op_evfsneg (void)
2713
{
2714
    do_evfsneg();
2715
    RETURN();
2716
}
2717

    
2718
void OPPROTO op_evfsdiv (void)
2719
{
2720
    do_evfsdiv();
2721
    RETURN();
2722
}
2723

    
2724
void OPPROTO op_evfsmul (void)
2725
{
2726
    do_evfsmul();
2727
    RETURN();
2728
}
2729

    
2730
void OPPROTO op_evfscmplt (void)
2731
{
2732
    do_evfscmplt();
2733
    RETURN();
2734
}
2735

    
2736
void OPPROTO op_evfscmpgt (void)
2737
{
2738
    do_evfscmpgt();
2739
    RETURN();
2740
}
2741

    
2742
void OPPROTO op_evfscmpeq (void)
2743
{
2744
    do_evfscmpeq();
2745
    RETURN();
2746
}
2747

    
2748
void OPPROTO op_evfscfsi (void)
2749
{
2750
    do_evfscfsi();
2751
    RETURN();
2752
}
2753

    
2754
void OPPROTO op_evfscfui (void)
2755
{
2756
    do_evfscfui();
2757
    RETURN();
2758
}
2759

    
2760
void OPPROTO op_evfscfsf (void)
2761
{
2762
    do_evfscfsf();
2763
    RETURN();
2764
}
2765

    
2766
void OPPROTO op_evfscfuf (void)
2767
{
2768
    do_evfscfuf();
2769
    RETURN();
2770
}
2771

    
2772
void OPPROTO op_evfsctsi (void)
2773
{
2774
    do_evfsctsi();
2775
    RETURN();
2776
}
2777

    
2778
void OPPROTO op_evfsctui (void)
2779
{
2780
    do_evfsctui();
2781
    RETURN();
2782
}
2783

    
2784
void OPPROTO op_evfsctsf (void)
2785
{
2786
    do_evfsctsf();
2787
    RETURN();
2788
}
2789

    
2790
void OPPROTO op_evfsctuf (void)
2791
{
2792
    do_evfsctuf();
2793
    RETURN();
2794
}
2795

    
2796
void OPPROTO op_evfsctuiz (void)
2797
{
2798
    do_evfsctuiz();
2799
    RETURN();
2800
}
2801

    
2802
void OPPROTO op_evfsctsiz (void)
2803
{
2804
    do_evfsctsiz();
2805
    RETURN();
2806
}
2807

    
2808
void OPPROTO op_evfststlt (void)
2809
{
2810
    do_evfststlt();
2811
    RETURN();
2812
}
2813

    
2814
void OPPROTO op_evfststgt (void)
2815
{
2816
    do_evfststgt();
2817
    RETURN();
2818
}
2819

    
2820
void OPPROTO op_evfststeq (void)
2821
{
2822
    do_evfststeq();
2823
    RETURN();
2824
}
2825

    
2826
void OPPROTO op_efssub (void)
2827
{
2828
    T0_64 = _do_efssub(T0_64, T1_64);
2829
    RETURN();
2830
}
2831

    
2832
void OPPROTO op_efsadd (void)
2833
{
2834
    T0_64 = _do_efsadd(T0_64, T1_64);
2835
    RETURN();
2836
}
2837

    
2838
void OPPROTO op_efsnabs (void)
2839
{
2840
    T0_64 = _do_efsnabs(T0_64);
2841
    RETURN();
2842
}
2843

    
2844
void OPPROTO op_efsabs (void)
2845
{
2846
    T0_64 = _do_efsabs(T0_64);
2847
    RETURN();
2848
}
2849

    
2850
void OPPROTO op_efsneg (void)
2851
{
2852
    T0_64 = _do_efsneg(T0_64);
2853
    RETURN();
2854
}
2855

    
2856
void OPPROTO op_efsdiv (void)
2857
{
2858
    T0_64 = _do_efsdiv(T0_64, T1_64);
2859
    RETURN();
2860
}
2861

    
2862
void OPPROTO op_efsmul (void)
2863
{
2864
    T0_64 = _do_efsmul(T0_64, T1_64);
2865
    RETURN();
2866
}
2867

    
2868
void OPPROTO op_efscmplt (void)
2869
{
2870
    do_efscmplt();
2871
    RETURN();
2872
}
2873

    
2874
void OPPROTO op_efscmpgt (void)
2875
{
2876
    do_efscmpgt();
2877
    RETURN();
2878
}
2879

    
2880
void OPPROTO op_efscfd (void)
2881
{
2882
    do_efscfd();
2883
    RETURN();
2884
}
2885

    
2886
void OPPROTO op_efscmpeq (void)
2887
{
2888
    do_efscmpeq();
2889
    RETURN();
2890
}
2891

    
2892
void OPPROTO op_efscfsi (void)
2893
{
2894
    do_efscfsi();
2895
    RETURN();
2896
}
2897

    
2898
void OPPROTO op_efscfui (void)
2899
{
2900
    do_efscfui();
2901
    RETURN();
2902
}
2903

    
2904
void OPPROTO op_efscfsf (void)
2905
{
2906
    do_efscfsf();
2907
    RETURN();
2908
}
2909

    
2910
void OPPROTO op_efscfuf (void)
2911
{
2912
    do_efscfuf();
2913
    RETURN();
2914
}
2915

    
2916
void OPPROTO op_efsctsi (void)
2917
{
2918
    do_efsctsi();
2919
    RETURN();
2920
}
2921

    
2922
void OPPROTO op_efsctui (void)
2923
{
2924
    do_efsctui();
2925
    RETURN();
2926
}
2927

    
2928
void OPPROTO op_efsctsf (void)
2929
{
2930
    do_efsctsf();
2931
    RETURN();
2932
}
2933

    
2934
void OPPROTO op_efsctuf (void)
2935
{
2936
    do_efsctuf();
2937
    RETURN();
2938
}
2939

    
2940
void OPPROTO op_efsctsiz (void)
2941
{
2942
    do_efsctsiz();
2943
    RETURN();
2944
}
2945

    
2946
void OPPROTO op_efsctuiz (void)
2947
{
2948
    do_efsctuiz();
2949
    RETURN();
2950
}
2951

    
2952
void OPPROTO op_efststlt (void)
2953
{
2954
    T0 = _do_efststlt(T0_64, T1_64);
2955
    RETURN();
2956
}
2957

    
2958
void OPPROTO op_efststgt (void)
2959
{
2960
    T0 = _do_efststgt(T0_64, T1_64);
2961
    RETURN();
2962
}
2963

    
2964
void OPPROTO op_efststeq (void)
2965
{
2966
    T0 = _do_efststeq(T0_64, T1_64);
2967
    RETURN();
2968
}
2969

    
2970
void OPPROTO op_efdsub (void)
2971
{
2972
    union {
2973
        uint64_t u;
2974
        float64 f;
2975
    } u1, u2;
2976
    u1.u = T0_64;
2977
    u2.u = T1_64;
2978
    u1.f = float64_sub(u1.f, u2.f, &env->spe_status);
2979
    T0_64 = u1.u;
2980
    RETURN();
2981
}
2982

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

    
2996
void OPPROTO op_efdcfsid (void)
2997
{
2998
    do_efdcfsi();
2999
    RETURN();
3000
}
3001

    
3002
void OPPROTO op_efdcfuid (void)
3003
{
3004
    do_efdcfui();
3005
    RETURN();
3006
}
3007

    
3008
void OPPROTO op_efdnabs (void)
3009
{
3010
    T0_64 |= 0x8000000000000000ULL;
3011
    RETURN();
3012
}
3013

    
3014
void OPPROTO op_efdabs (void)
3015
{
3016
    T0_64 &= ~0x8000000000000000ULL;
3017
    RETURN();
3018
}
3019

    
3020
void OPPROTO op_efdneg (void)
3021
{
3022
    T0_64 ^= 0x8000000000000000ULL;
3023
    RETURN();
3024
}
3025

    
3026
void OPPROTO op_efddiv (void)
3027
{
3028
    union {
3029
        uint64_t u;
3030
        float64 f;
3031
    } u1, u2;
3032
    u1.u = T0_64;
3033
    u2.u = T1_64;
3034
    u1.f = float64_div(u1.f, u2.f, &env->spe_status);
3035
    T0_64 = u1.u;
3036
    RETURN();
3037
}
3038

    
3039
void OPPROTO op_efdmul (void)
3040
{
3041
    union {
3042
        uint64_t u;
3043
        float64 f;
3044
    } u1, u2;
3045
    u1.u = T0_64;
3046
    u2.u = T1_64;
3047
    u1.f = float64_mul(u1.f, u2.f, &env->spe_status);
3048
    T0_64 = u1.u;
3049
    RETURN();
3050
}
3051

    
3052
void OPPROTO op_efdctsidz (void)
3053
{
3054
    do_efdctsiz();
3055
    RETURN();
3056
}
3057

    
3058
void OPPROTO op_efdctuidz (void)
3059
{
3060
    do_efdctuiz();
3061
    RETURN();
3062
}
3063

    
3064
void OPPROTO op_efdcmplt (void)
3065
{
3066
    do_efdcmplt();
3067
    RETURN();
3068
}
3069

    
3070
void OPPROTO op_efdcmpgt (void)
3071
{
3072
    do_efdcmpgt();
3073
    RETURN();
3074
}
3075

    
3076
void OPPROTO op_efdcfs (void)
3077
{
3078
    do_efdcfs();
3079
    RETURN();
3080
}
3081

    
3082
void OPPROTO op_efdcmpeq (void)
3083
{
3084
    do_efdcmpeq();
3085
    RETURN();
3086
}
3087

    
3088
void OPPROTO op_efdcfsi (void)
3089
{
3090
    do_efdcfsi();
3091
    RETURN();
3092
}
3093

    
3094
void OPPROTO op_efdcfui (void)
3095
{
3096
    do_efdcfui();
3097
    RETURN();
3098
}
3099

    
3100
void OPPROTO op_efdcfsf (void)
3101
{
3102
    do_efdcfsf();
3103
    RETURN();
3104
}
3105

    
3106
void OPPROTO op_efdcfuf (void)
3107
{
3108
    do_efdcfuf();
3109
    RETURN();
3110
}
3111

    
3112
void OPPROTO op_efdctsi (void)
3113
{
3114
    do_efdctsi();
3115
    RETURN();
3116
}
3117

    
3118
void OPPROTO op_efdctui (void)
3119
{
3120
    do_efdctui();
3121
    RETURN();
3122
}
3123

    
3124
void OPPROTO op_efdctsf (void)
3125
{
3126
    do_efdctsf();
3127
    RETURN();
3128
}
3129

    
3130
void OPPROTO op_efdctuf (void)
3131
{
3132
    do_efdctuf();
3133
    RETURN();
3134
}
3135

    
3136
void OPPROTO op_efdctuiz (void)
3137
{
3138
    do_efdctuiz();
3139
    RETURN();
3140
}
3141

    
3142
void OPPROTO op_efdctsiz (void)
3143
{
3144
    do_efdctsiz();
3145
    RETURN();
3146
}
3147

    
3148
void OPPROTO op_efdtstlt (void)
3149
{
3150
    T0 = _do_efdtstlt(T0_64, T1_64);
3151
    RETURN();
3152
}
3153

    
3154
void OPPROTO op_efdtstgt (void)
3155
{
3156
    T0 = _do_efdtstgt(T0_64, T1_64);
3157
    RETURN();
3158
}
3159

    
3160
void OPPROTO op_efdtsteq (void)
3161
{
3162
    T0 = _do_efdtsteq(T0_64, T1_64);
3163
    RETURN();
3164
}
3165
#endif /* defined(TARGET_PPCSPE) */