Statistics
| Branch: | Revision:

root / target-ppc / op.c @ a496775f

History | View | Annotate | Download (45.5 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

    
134
void OPPROTO op_print_mem_EA (void)
135
{
136
    do_print_mem_EA(T0);
137
    RETURN();
138
}
139

    
140
/* PowerPC state maintenance operations */
141
/* set_Rc0 */
142
PPC_OP(set_Rc0)
143
{
144
    env->crf[0] = T0 | xer_ov;
145
    RETURN();
146
}
147

    
148
/* Set Rc1 (for floating point arithmetic) */
149
PPC_OP(set_Rc1)
150
{
151
    env->crf[1] = regs->fpscr[7];
152
    RETURN();
153
}
154

    
155
/* Constants load */
156
void OPPROTO op_reset_T0 (void)
157
{
158
    T0 = 0;
159
    RETURN();
160
}
161

    
162
PPC_OP(set_T0)
163
{
164
    T0 = (uint32_t)PARAM1;
165
    RETURN();
166
}
167

    
168
#if defined(TARGET_PPC64)
169
void OPPROTO op_set_T0_64 (void)
170
{
171
    T0 = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
172
    RETURN();
173
}
174
#endif
175

    
176
PPC_OP(set_T1)
177
{
178
    T1 = (uint32_t)PARAM1;
179
    RETURN();
180
}
181

    
182
#if defined(TARGET_PPC64)
183
void OPPROTO op_set_T1_64 (void)
184
{
185
    T1 = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
186
    RETURN();
187
}
188
#endif
189

    
190
#if 0 // unused
191
PPC_OP(set_T2)
192
{
193
    T2 = PARAM(1);
194
    RETURN();
195
}
196
#endif
197

    
198
void OPPROTO op_move_T1_T0 (void)
199
{
200
    T1 = T0;
201
    RETURN();
202
}
203

    
204
void OPPROTO op_move_T2_T0 (void)
205
{
206
    T2 = T0;
207
    RETURN();
208
}
209

    
210
/* Generate exceptions */
211
PPC_OP(raise_exception_err)
212
{
213
    do_raise_exception_err(PARAM(1), PARAM(2));
214
}
215

    
216
PPC_OP(update_nip)
217
{
218
    env->nip = (uint32_t)PARAM1;
219
    RETURN();
220
}
221

    
222
#if defined(TARGET_PPC64)
223
void OPPROTO op_update_nip_64 (void)
224
{
225
    env->nip = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
226
    RETURN();
227
}
228
#endif
229

    
230
PPC_OP(debug)
231
{
232
    do_raise_exception(EXCP_DEBUG);
233
}
234

    
235
PPC_OP(exit_tb)
236
{
237
    EXIT_TB();
238
}
239

    
240
/* Load/store special registers */
241
PPC_OP(load_cr)
242
{
243
    do_load_cr();
244
    RETURN();
245
}
246

    
247
PPC_OP(store_cr)
248
{
249
    do_store_cr(PARAM(1));
250
    RETURN();
251
}
252

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

    
259
void OPPROTO op_store_cro (void)
260
{
261
    env->crf[PARAM1] = T0;
262
    RETURN();
263
}
264

    
265
PPC_OP(load_xer_cr)
266
{
267
    T0 = (xer_so << 3) | (xer_ov << 2) | (xer_ca << 1);
268
    RETURN();
269
}
270

    
271
PPC_OP(clear_xer_ov)
272
{
273
    xer_so = 0;
274
    xer_ov = 0;
275
    RETURN();
276
}
277

    
278
PPC_OP(clear_xer_ca)
279
{
280
    xer_ca = 0;
281
    RETURN();
282
}
283

    
284
PPC_OP(load_xer_bc)
285
{
286
    T1 = xer_bc;
287
    RETURN();
288
}
289

    
290
void OPPROTO op_store_xer_bc (void)
291
{
292
    xer_bc = T0;
293
    RETURN();
294
}
295

    
296
PPC_OP(load_xer)
297
{
298
    do_load_xer();
299
    RETURN();
300
}
301

    
302
PPC_OP(store_xer)
303
{
304
    do_store_xer();
305
    RETURN();
306
}
307

    
308
#if !defined(CONFIG_USER_ONLY)
309
/* Segment registers load and store */
310
PPC_OP(load_sr)
311
{
312
    T0 = regs->sr[T1];
313
    RETURN();
314
}
315

    
316
PPC_OP(store_sr)
317
{
318
    do_store_sr(env, T1, T0);
319
    RETURN();
320
}
321

    
322
PPC_OP(load_sdr1)
323
{
324
    T0 = regs->sdr1;
325
    RETURN();
326
}
327

    
328
PPC_OP(store_sdr1)
329
{
330
    do_store_sdr1(env, T0);
331
    RETURN();
332
}
333

    
334
#if defined (TARGET_PPC64)
335
void OPPROTO op_load_asr (void)
336
{
337
    T0 = env->asr;
338
    RETURN();
339
}
340

    
341
void OPPROTO op_store_asr (void)
342
{
343
    ppc_store_asr(env, T0);
344
    RETURN();
345
}
346
#endif
347

    
348
PPC_OP(load_msr)
349
{
350
    T0 = do_load_msr(env);
351
    RETURN();
352
}
353

    
354
PPC_OP(store_msr)
355
{
356
    do_store_msr(env, T0);
357
    RETURN();
358
}
359

    
360
#if defined (TARGET_PPC64)
361
void OPPROTO op_store_msr_32 (void)
362
{
363
    ppc_store_msr_32(env, T0);
364
    RETURN();
365
}
366
#endif
367
#endif
368

    
369
/* SPR */
370
void OPPROTO op_load_spr (void)
371
{
372
    T0 = env->spr[PARAM1];
373
    RETURN();
374
}
375

    
376
void OPPROTO op_store_spr (void)
377
{
378
    env->spr[PARAM1] = T0;
379
    RETURN();
380
}
381

    
382
void OPPROTO op_load_dump_spr (void)
383
{
384
    T0 = ppc_load_dump_spr(PARAM1);
385
    RETURN();
386
}
387

    
388
void OPPROTO op_store_dump_spr (void)
389
{
390
    ppc_store_dump_spr(PARAM1, T0);
391
    RETURN();
392
}
393

    
394
void OPPROTO op_mask_spr (void)
395
{
396
    env->spr[PARAM1] &= ~T0;
397
    RETURN();
398
}
399

    
400
PPC_OP(load_lr)
401
{
402
    T0 = regs->lr;
403
    RETURN();
404
}
405

    
406
PPC_OP(store_lr)
407
{
408
    regs->lr = T0;
409
    RETURN();
410
}
411

    
412
PPC_OP(load_ctr)
413
{
414
    T0 = regs->ctr;
415
    RETURN();
416
}
417

    
418
PPC_OP(store_ctr)
419
{
420
    regs->ctr = T0;
421
    RETURN();
422
}
423

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

    
430
PPC_OP(load_tbu)
431
{
432
    T0 = cpu_ppc_load_tbu(regs);
433
    RETURN();
434
}
435

    
436
#if !defined(CONFIG_USER_ONLY)
437
PPC_OP(store_tbl)
438
{
439
    cpu_ppc_store_tbl(regs, T0);
440
    RETURN();
441
}
442

    
443
PPC_OP(store_tbu)
444
{
445
    cpu_ppc_store_tbu(regs, T0);
446
    RETURN();
447
}
448

    
449
PPC_OP(load_decr)
450
{
451
    T0 = cpu_ppc_load_decr(regs);
452
    RETURN();
453
}
454

    
455
PPC_OP(store_decr)
456
{
457
    cpu_ppc_store_decr(regs, T0);
458
    RETURN();
459
}
460

    
461
PPC_OP(load_ibat)
462
{
463
    T0 = regs->IBAT[PARAM(1)][PARAM(2)];
464
    RETURN();
465
}
466

    
467
void OPPROTO op_store_ibatu (void)
468
{
469
    do_store_ibatu(env, PARAM1, T0);
470
    RETURN();
471
}
472

    
473
void OPPROTO op_store_ibatl (void)
474
{
475
#if 1
476
    env->IBAT[1][PARAM1] = T0;
477
#else
478
    do_store_ibatl(env, PARAM1, T0);
479
#endif
480
    RETURN();
481
}
482

    
483
PPC_OP(load_dbat)
484
{
485
    T0 = regs->DBAT[PARAM(1)][PARAM(2)];
486
    RETURN();
487
}
488

    
489
void OPPROTO op_store_dbatu (void)
490
{
491
    do_store_dbatu(env, PARAM1, T0);
492
    RETURN();
493
}
494

    
495
void OPPROTO op_store_dbatl (void)
496
{
497
#if 1
498
    env->DBAT[1][PARAM1] = T0;
499
#else
500
    do_store_dbatl(env, PARAM1, T0);
501
#endif
502
    RETURN();
503
}
504
#endif /* !defined(CONFIG_USER_ONLY) */
505

    
506
/* FPSCR */
507
PPC_OP(load_fpscr)
508
{
509
    do_load_fpscr();
510
    RETURN();
511
}
512

    
513
PPC_OP(store_fpscr)
514
{
515
    do_store_fpscr(PARAM1);
516
    RETURN();
517
}
518

    
519
PPC_OP(reset_scrfx)
520
{
521
    regs->fpscr[7] &= ~0x8;
522
    RETURN();
523
}
524

    
525
/* crf operations */
526
PPC_OP(getbit_T0)
527
{
528
    T0 = (T0 >> PARAM(1)) & 1;
529
    RETURN();
530
}
531

    
532
PPC_OP(getbit_T1)
533
{
534
    T1 = (T1 >> PARAM(1)) & 1;
535
    RETURN();
536
}
537

    
538
PPC_OP(setcrfbit)
539
{
540
    T1 = (T1 & PARAM(1)) | (T0 << PARAM(2));
541
    RETURN();
542
}
543

    
544
/* Branch */
545
#define EIP regs->nip
546

    
547
PPC_OP(setlr)
548
{
549
    regs->lr = (uint32_t)PARAM1;
550
    RETURN();
551
}
552

    
553
#if defined (TARGET_PPC64)
554
void OPPROTO op_setlr_64 (void)
555
{
556
    regs->lr = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
557
    RETURN();
558
}
559
#endif
560

    
561
PPC_OP(goto_tb0)
562
{
563
    GOTO_TB(op_goto_tb0, PARAM1, 0);
564
}
565

    
566
PPC_OP(goto_tb1)
567
{
568
    GOTO_TB(op_goto_tb1, PARAM1, 1);
569
}
570

    
571
void OPPROTO op_b_T1 (void)
572
{
573
    regs->nip = (uint32_t)(T1 & ~3);
574
    RETURN();
575
}
576

    
577
#if defined (TARGET_PPC64)
578
void OPPROTO op_b_T1_64 (void)
579
{
580
    regs->nip = (uint64_t)(T1 & ~3);
581
    RETURN();
582
}
583
#endif
584

    
585
PPC_OP(jz_T0)
586
{
587
    if (!T0)
588
        GOTO_LABEL_PARAM(1);
589
    RETURN();
590
}
591

    
592
void OPPROTO op_btest_T1 (void)
593
{
594
    if (T0) {
595
        regs->nip = (uint32_t)(T1 & ~3);
596
    } else {
597
        regs->nip = (uint32_t)PARAM1;
598
    }
599
    RETURN();
600
}
601

    
602
#if defined (TARGET_PPC64)
603
void OPPROTO op_btest_T1_64 (void)
604
{
605
    if (T0) {
606
        regs->nip = (uint64_t)(T1 & ~3);
607
    } else {
608
        regs->nip = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
609
    }
610
    RETURN();
611
}
612
#endif
613

    
614
PPC_OP(movl_T1_ctr)
615
{
616
    T1 = regs->ctr;
617
    RETURN();
618
}
619

    
620
PPC_OP(movl_T1_lr)
621
{
622
    T1 = regs->lr;
623
    RETURN();
624
}
625

    
626
/* tests with result in T0 */
627
void OPPROTO op_test_ctr (void)
628
{
629
    T0 = (uint32_t)regs->ctr;
630
    RETURN();
631
}
632

    
633
#if defined(TARGET_PPC64)
634
void OPPROTO op_test_ctr_64 (void)
635
{
636
    T0 = (uint64_t)regs->ctr;
637
    RETURN();
638
}
639
#endif
640

    
641
void OPPROTO op_test_ctr_true (void)
642
{
643
    T0 = ((uint32_t)regs->ctr != 0 && (T0 & PARAM1) != 0);
644
    RETURN();
645
}
646

    
647
#if defined(TARGET_PPC64)
648
void OPPROTO op_test_ctr_true_64 (void)
649
{
650
    T0 = ((uint64_t)regs->ctr != 0 && (T0 & PARAM1) != 0);
651
    RETURN();
652
}
653
#endif
654

    
655
void OPPROTO op_test_ctr_false (void)
656
{
657
    T0 = ((uint32_t)regs->ctr != 0 && (T0 & PARAM1) == 0);
658
    RETURN();
659
}
660

    
661
#if defined(TARGET_PPC64)
662
void OPPROTO op_test_ctr_false_64 (void)
663
{
664
    T0 = ((uint64_t)regs->ctr != 0 && (T0 & PARAM1) == 0);
665
    RETURN();
666
}
667
#endif
668

    
669
void OPPROTO op_test_ctrz (void)
670
{
671
    T0 = ((uint32_t)regs->ctr == 0);
672
    RETURN();
673
}
674

    
675
#if defined(TARGET_PPC64)
676
void OPPROTO op_test_ctrz_64 (void)
677
{
678
    T0 = ((uint64_t)regs->ctr == 0);
679
    RETURN();
680
}
681
#endif
682

    
683
void OPPROTO op_test_ctrz_true (void)
684
{
685
    T0 = ((uint32_t)regs->ctr == 0 && (T0 & PARAM1) != 0);
686
    RETURN();
687
}
688

    
689
#if defined(TARGET_PPC64)
690
void OPPROTO op_test_ctrz_true_64 (void)
691
{
692
    T0 = ((uint64_t)regs->ctr == 0 && (T0 & PARAM1) != 0);
693
    RETURN();
694
}
695
#endif
696

    
697
void OPPROTO op_test_ctrz_false (void)
698
{
699
    T0 = ((uint32_t)regs->ctr == 0 && (T0 & PARAM1) == 0);
700
    RETURN();
701
}
702

    
703
#if defined(TARGET_PPC64)
704
void OPPROTO op_test_ctrz_false_64 (void)
705
{
706
    T0 = ((uint64_t)regs->ctr == 0 && (T0 & PARAM1) == 0);
707
    RETURN();
708
}
709
#endif
710

    
711
PPC_OP(test_true)
712
{
713
    T0 = (T0 & PARAM(1));
714
    RETURN();
715
}
716

    
717
PPC_OP(test_false)
718
{
719
    T0 = ((T0 & PARAM(1)) == 0);
720
    RETURN();
721
}
722

    
723
/* CTR maintenance */
724
PPC_OP(dec_ctr)
725
{
726
    regs->ctr--;
727
    RETURN();
728
}
729

    
730
/***                           Integer arithmetic                          ***/
731
/* add */
732
PPC_OP(add)
733
{
734
    T0 += T1;
735
    RETURN();
736
}
737

    
738
void OPPROTO op_check_addo (void)
739
{
740
    if (likely(!(((uint32_t)T2 ^ (uint32_t)T1 ^ UINT32_MAX) &
741
                 ((uint32_t)T2 ^ (uint32_t)T0) & (1UL << 31)))) {
742
        xer_ov = 0;
743
    } else {
744
        xer_so = 1;
745
        xer_ov = 1;
746
    }
747
    RETURN();
748
}
749

    
750
#if defined(TARGET_PPC64)
751
void OPPROTO op_check_addo_64 (void)
752
{
753
    if (likely(!(((uint64_t)T2 ^ (uint64_t)T1 ^ UINT64_MAX) &
754
                 ((uint64_t)T2 ^ (uint64_t)T0) & (1ULL << 63)))) {
755
        xer_ov = 0;
756
    } else {
757
        xer_so = 1;
758
        xer_ov = 1;
759
    }
760
    RETURN();
761
}
762
#endif
763

    
764
/* add carrying */
765
void OPPROTO op_check_addc (void)
766
{
767
    if (likely((uint32_t)T0 >= (uint32_t)T2)) {
768
        xer_ca = 0;
769
    } else {
770
        xer_ca = 1;
771
    }
772
    RETURN();
773
}
774

    
775
#if defined(TARGET_PPC64)
776
void OPPROTO op_check_addc_64 (void)
777
{
778
    if (likely((uint64_t)T0 >= (uint64_t)T2)) {
779
        xer_ca = 0;
780
    } else {
781
        xer_ca = 1;
782
    }
783
    RETURN();
784
}
785
#endif
786

    
787
/* add extended */
788
void OPPROTO op_adde (void)
789
{
790
    do_adde();
791
    RETURN();
792
}
793

    
794
#if defined(TARGET_PPC64)
795
void OPPROTO op_adde_64 (void)
796
{
797
    do_adde_64();
798
    RETURN();
799
}
800
#endif
801

    
802
/* add immediate */
803
PPC_OP(addi)
804
{
805
    T0 += (int32_t)PARAM(1);
806
    RETURN();
807
}
808

    
809
/* add to minus one extended */
810
void OPPROTO op_add_me (void)
811
{
812
    T0 += xer_ca + (-1);
813
    if (likely((uint32_t)T1 != 0))
814
        xer_ca = 1;
815
    RETURN();
816
}
817

    
818
#if defined(TARGET_PPC64)
819
void OPPROTO op_add_me_64 (void)
820
{
821
    T0 += xer_ca + (-1);
822
    if (likely((uint64_t)T1 != 0))
823
        xer_ca = 1;
824
    RETURN();
825
}
826
#endif
827

    
828
void OPPROTO op_addmeo (void)
829
{
830
    do_addmeo();
831
    RETURN();
832
}
833

    
834
void OPPROTO op_addmeo_64 (void)
835
{
836
    do_addmeo();
837
    RETURN();
838
}
839

    
840
/* add to zero extended */
841
void OPPROTO op_add_ze (void)
842
{
843
    T0 += xer_ca;
844
    RETURN();
845
}
846

    
847
/* divide word */
848
void OPPROTO op_divw (void)
849
{
850
    if (unlikely(((int32_t)T0 == INT32_MIN && (int32_t)T1 == -1) ||
851
                 (int32_t)T1 == 0)) {
852
        T0 = (int32_t)((-1) * ((uint32_t)T0 >> 31));
853
    } else {
854
        T0 = (int32_t)T0 / (int32_t)T1;
855
    }
856
    RETURN();
857
}
858

    
859
#if defined(TARGET_PPC64)
860
void OPPROTO op_divd (void)
861
{
862
    if (unlikely(((int64_t)T0 == INT64_MIN && (int64_t)T1 == -1) ||
863
                 (int64_t)T1 == 0)) {
864
        T0 = (int64_t)((-1ULL) * ((uint64_t)T0 >> 63));
865
    } else {
866
        T0 = (int64_t)T0 / (int64_t)T1;
867
    }
868
    RETURN();
869
}
870
#endif
871

    
872
void OPPROTO op_divwo (void)
873
{
874
    do_divwo();
875
    RETURN();
876
}
877

    
878
#if defined(TARGET_PPC64)
879
void OPPROTO op_divdo (void)
880
{
881
    do_divdo();
882
    RETURN();
883
}
884
#endif
885

    
886
/* divide word unsigned */
887
void OPPROTO op_divwu (void)
888
{
889
    if (unlikely(T1 == 0)) {
890
        T0 = 0;
891
    } else {
892
        T0 = (uint32_t)T0 / (uint32_t)T1;
893
    }
894
    RETURN();
895
}
896

    
897
#if defined(TARGET_PPC64)
898
void OPPROTO op_divdu (void)
899
{
900
    if (unlikely(T1 == 0)) {
901
        T0 = 0;
902
    } else {
903
        T0 /= T1;
904
    }
905
    RETURN();
906
}
907
#endif
908

    
909
void OPPROTO op_divwuo (void)
910
{
911
    do_divwuo();
912
    RETURN();
913
}
914

    
915
#if defined(TARGET_PPC64)
916
void OPPROTO op_divduo (void)
917
{
918
    do_divduo();
919
    RETURN();
920
}
921
#endif
922

    
923
/* multiply high word */
924
void OPPROTO op_mulhw (void)
925
{
926
    T0 = ((int64_t)((int32_t)T0) * (int64_t)((int32_t)T1)) >> 32;
927
    RETURN();
928
}
929

    
930
#if defined(TARGET_PPC64)
931
void OPPROTO op_mulhd (void)
932
{
933
    uint64_t tl, th;
934

    
935
    do_imul64(&tl, &th);
936
    T0 = th;
937
    RETURN();
938
}
939
#endif
940

    
941
/* multiply high word unsigned */
942
void OPPROTO op_mulhwu (void)
943
{
944
    T0 = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1) >> 32;
945
    RETURN();
946
}
947

    
948
#if defined(TARGET_PPC64)
949
void OPPROTO op_mulhdu (void)
950
{
951
    uint64_t tl, th;
952

    
953
    do_mul64(&tl, &th);
954
    T0 = th;
955
    RETURN();
956
}
957
#endif
958

    
959
/* multiply low immediate */
960
PPC_OP(mulli)
961
{
962
    T0 = ((int32_t)T0 * (int32_t)PARAM1);
963
    RETURN();
964
}
965

    
966
/* multiply low word */
967
PPC_OP(mullw)
968
{
969
    T0 = (int32_t)(T0 * T1);
970
    RETURN();
971
}
972

    
973
#if defined(TARGET_PPC64)
974
void OPPROTO op_mulld (void)
975
{
976
    T0 *= T1;
977
    RETURN();
978
}
979
#endif
980

    
981
void OPPROTO op_mullwo (void)
982
{
983
    do_mullwo();
984
    RETURN();
985
}
986

    
987
#if defined(TARGET_PPC64)
988
void OPPROTO op_mulldo (void)
989
{
990
    do_mulldo();
991
    RETURN();
992
}
993
#endif
994

    
995
/* negate */
996
void OPPROTO op_neg (void)
997
{
998
    if (likely(T0 != INT32_MIN)) {
999
        T0 = -(int32_t)T0;
1000
    }
1001
    RETURN();
1002
}
1003

    
1004
#if defined(TARGET_PPC64)
1005
void OPPROTO op_neg_64 (void)
1006
{
1007
    if (likely(T0 != INT64_MIN)) {
1008
        T0 = -(int64_t)T0;
1009
    }
1010
    RETURN();
1011
}
1012
#endif
1013

    
1014
void OPPROTO op_nego (void)
1015
{
1016
    do_nego();
1017
    RETURN();
1018
}
1019

    
1020
#if defined(TARGET_PPC64)
1021
void OPPROTO op_nego_64 (void)
1022
{
1023
    do_nego_64();
1024
    RETURN();
1025
}
1026
#endif
1027

    
1028
/* substract from */
1029
PPC_OP(subf)
1030
{
1031
    T0 = T1 - T0;
1032
    RETURN();
1033
}
1034

    
1035
void OPPROTO op_check_subfo (void)
1036
{
1037
    if (likely(!(((uint32_t)(~T2) ^ (uint32_t)T1 ^ UINT32_MAX) &
1038
                 ((uint32_t)(~T2) ^ (uint32_t)T0) & (1UL << 31)))) {
1039
        xer_ov = 0;
1040
    } else {
1041
        xer_so = 1;
1042
        xer_ov = 1;
1043
    }
1044
    RETURN();
1045
}
1046

    
1047
#if defined(TARGET_PPC64)
1048
void OPPROTO op_check_subfo_64 (void)
1049
{
1050
    if (likely(!(((uint64_t)(~T2) ^ (uint64_t)T1 ^ UINT64_MAX) &
1051
                 ((uint64_t)(~T2) ^ (uint64_t)T0) & (1ULL << 63)))) {
1052
        xer_ov = 0;
1053
    } else {
1054
        xer_so = 1;
1055
        xer_ov = 1;
1056
    }
1057
    RETURN();
1058
}
1059
#endif
1060

    
1061
/* substract from carrying */
1062
void OPPROTO op_check_subfc (void)
1063
{
1064
    if (likely((uint32_t)T0 > (uint32_t)T1)) {
1065
        xer_ca = 0;
1066
    } else {
1067
        xer_ca = 1;
1068
    }
1069
    RETURN();
1070
}
1071

    
1072
#if defined(TARGET_PPC64)
1073
void OPPROTO op_check_subfc_64 (void)
1074
{
1075
    if (likely((uint64_t)T0 > (uint64_t)T1)) {
1076
        xer_ca = 0;
1077
    } else {
1078
        xer_ca = 1;
1079
    }
1080
    RETURN();
1081
}
1082
#endif
1083

    
1084
/* substract from extended */
1085
void OPPROTO op_subfe (void)
1086
{
1087
    do_subfe();
1088
    RETURN();
1089
}
1090

    
1091
#if defined(TARGET_PPC64)
1092
void OPPROTO op_subfe_64 (void)
1093
{
1094
    do_subfe_64();
1095
    RETURN();
1096
}
1097
#endif
1098

    
1099
/* substract from immediate carrying */
1100
void OPPROTO op_subfic (void)
1101
{
1102
    T0 = (int32_t)PARAM1 + ~T0 + 1;
1103
    if ((uint32_t)T0 <= (uint32_t)PARAM1) {
1104
        xer_ca = 1;
1105
    } else {
1106
        xer_ca = 0;
1107
    }
1108
    RETURN();
1109
}
1110

    
1111
#if defined(TARGET_PPC64)
1112
void OPPROTO op_subfic_64 (void)
1113
{
1114
    T0 = PARAM1 + ~T0 + 1;
1115
    if ((uint64_t)T0 <= (uint64_t)PARAM1) {
1116
        xer_ca = 1;
1117
    } else {
1118
        xer_ca = 0;
1119
    }
1120
    RETURN();
1121
}
1122
#endif
1123

    
1124
/* substract from minus one extended */
1125
void OPPROTO op_subfme (void)
1126
{
1127
    T0 = ~T0 + xer_ca - 1;
1128
    if (likely((uint32_t)T0 != (uint32_t)-1))
1129
        xer_ca = 1;
1130
    RETURN();
1131
}
1132

    
1133
#if defined(TARGET_PPC64)
1134
void OPPROTO op_subfme_64 (void)
1135
{
1136
    T0 = ~T0 + xer_ca - 1;
1137
    if (likely((uint64_t)T0 != (uint64_t)-1))
1138
        xer_ca = 1;
1139
    RETURN();
1140
}
1141
#endif
1142

    
1143
void OPPROTO op_subfmeo (void)
1144
{
1145
    do_subfmeo();
1146
    RETURN();
1147
}
1148

    
1149
#if defined(TARGET_PPC64)
1150
void OPPROTO op_subfmeo_64 (void)
1151
{
1152
    do_subfmeo_64();
1153
    RETURN();
1154
}
1155
#endif
1156

    
1157
/* substract from zero extended */
1158
void OPPROTO op_subfze (void)
1159
{
1160
    T1 = ~T0;
1161
    T0 = T1 + xer_ca;
1162
    if ((uint32_t)T0 < (uint32_t)T1) {
1163
        xer_ca = 1;
1164
    } else {
1165
        xer_ca = 0;
1166
    }
1167
    RETURN();
1168
}
1169

    
1170
#if defined(TARGET_PPC64)
1171
void OPPROTO op_subfze_64 (void)
1172
{
1173
    T1 = ~T0;
1174
    T0 = T1 + xer_ca;
1175
    if ((uint64_t)T0 < (uint64_t)T1) {
1176
        xer_ca = 1;
1177
    } else {
1178
        xer_ca = 0;
1179
    }
1180
    RETURN();
1181
}
1182
#endif
1183

    
1184
void OPPROTO op_subfzeo (void)
1185
{
1186
    do_subfzeo();
1187
    RETURN();
1188
}
1189

    
1190
#if defined(TARGET_PPC64)
1191
void OPPROTO op_subfzeo_64 (void)
1192
{
1193
    do_subfzeo_64();
1194
    RETURN();
1195
}
1196
#endif
1197

    
1198
/***                           Integer comparison                          ***/
1199
/* compare */
1200
void OPPROTO op_cmp (void)
1201
{
1202
    if ((int32_t)T0 < (int32_t)T1) {
1203
        T0 = 0x08;
1204
    } else if ((int32_t)T0 > (int32_t)T1) {
1205
        T0 = 0x04;
1206
    } else {
1207
        T0 = 0x02;
1208
    }
1209
    RETURN();
1210
}
1211

    
1212
#if defined(TARGET_PPC64)
1213
void OPPROTO op_cmp_64 (void)
1214
{
1215
    if ((int64_t)T0 < (int64_t)T1) {
1216
        T0 = 0x08;
1217
    } else if ((int64_t)T0 > (int64_t)T1) {
1218
        T0 = 0x04;
1219
    } else {
1220
        T0 = 0x02;
1221
    }
1222
    RETURN();
1223
}
1224
#endif
1225

    
1226
/* compare immediate */
1227
void OPPROTO op_cmpi (void)
1228
{
1229
    if ((int32_t)T0 < (int32_t)PARAM1) {
1230
        T0 = 0x08;
1231
    } else if ((int32_t)T0 > (int32_t)PARAM1) {
1232
        T0 = 0x04;
1233
    } else {
1234
        T0 = 0x02;
1235
    }
1236
    RETURN();
1237
}
1238

    
1239
#if defined(TARGET_PPC64)
1240
void OPPROTO op_cmpi_64 (void)
1241
{
1242
    if ((int64_t)T0 < (int64_t)((int32_t)PARAM1)) {
1243
        T0 = 0x08;
1244
    } else if ((int64_t)T0 > (int64_t)((int32_t)PARAM1)) {
1245
        T0 = 0x04;
1246
    } else {
1247
        T0 = 0x02;
1248
    }
1249
    RETURN();
1250
}
1251
#endif
1252

    
1253
/* compare logical */
1254
void OPPROTO op_cmpl (void)
1255
{
1256
    if ((uint32_t)T0 < (uint32_t)T1) {
1257
        T0 = 0x08;
1258
    } else if ((uint32_t)T0 > (uint32_t)T1) {
1259
        T0 = 0x04;
1260
    } else {
1261
        T0 = 0x02;
1262
    }
1263
    RETURN();
1264
}
1265

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

    
1280
/* compare logical immediate */
1281
void OPPROTO op_cmpli (void)
1282
{
1283
    if ((uint32_t)T0 < (uint32_t)PARAM1) {
1284
        T0 = 0x08;
1285
    } else if ((uint32_t)T0 > (uint32_t)PARAM1) {
1286
        T0 = 0x04;
1287
    } else {
1288
        T0 = 0x02;
1289
    }
1290
    RETURN();
1291
}
1292

    
1293
#if defined(TARGET_PPC64)
1294
void OPPROTO op_cmpli_64 (void)
1295
{
1296
    if ((uint64_t)T0 < (uint64_t)PARAM1) {
1297
        T0 = 0x08;
1298
    } else if ((uint64_t)T0 > (uint64_t)PARAM1) {
1299
        T0 = 0x04;
1300
    } else {
1301
        T0 = 0x02;
1302
    }
1303
    RETURN();
1304
}
1305
#endif
1306

    
1307
void OPPROTO op_isel (void)
1308
{
1309
    if (T0)
1310
        T0 = T1;
1311
    else
1312
        T0 = T2;
1313
    RETURN();
1314
}
1315

    
1316
void OPPROTO op_popcntb (void)
1317
{
1318
    do_popcntb();
1319
    RETURN();
1320
}
1321

    
1322
#if defined(TARGET_PPC64)
1323
void OPPROTO op_popcntb_64 (void)
1324
{
1325
    do_popcntb_64();
1326
    RETURN();
1327
}
1328
#endif
1329

    
1330
/***                            Integer logical                            ***/
1331
/* and */
1332
PPC_OP(and)
1333
{
1334
    T0 &= T1;
1335
    RETURN();
1336
}
1337

    
1338
/* andc */
1339
PPC_OP(andc)
1340
{
1341
    T0 &= ~T1;
1342
    RETURN();
1343
}
1344

    
1345
/* andi. */
1346
void OPPROTO op_andi_T0 (void)
1347
{
1348
    T0 &= PARAM(1);
1349
    RETURN();
1350
}
1351

    
1352
void OPPROTO op_andi_T1 (void)
1353
{
1354
    T1 &= PARAM1;
1355
    RETURN();
1356
}
1357

    
1358
/* count leading zero */
1359
void OPPROTO op_cntlzw (void)
1360
{
1361
    T0 = _do_cntlzw(T0);
1362
    RETURN();
1363
}
1364

    
1365
#if defined(TARGET_PPC64)
1366
void OPPROTO op_cntlzd (void)
1367
{
1368
    T0 = _do_cntlzd(T0);
1369
    RETURN();
1370
}
1371
#endif
1372

    
1373
/* eqv */
1374
PPC_OP(eqv)
1375
{
1376
    T0 = ~(T0 ^ T1);
1377
    RETURN();
1378
}
1379

    
1380
/* extend sign byte */
1381
void OPPROTO op_extsb (void)
1382
{
1383
#if defined (TARGET_PPC64)
1384
    T0 = (int64_t)((int8_t)T0);
1385
#else
1386
    T0 = (int32_t)((int8_t)T0);
1387
#endif
1388
    RETURN();
1389
}
1390

    
1391
/* extend sign half word */
1392
void OPPROTO op_extsh (void)
1393
{
1394
#if defined (TARGET_PPC64)
1395
    T0 = (int64_t)((int16_t)T0);
1396
#else
1397
    T0 = (int32_t)((int16_t)T0);
1398
#endif
1399
    RETURN();
1400
}
1401

    
1402
#if defined (TARGET_PPC64)
1403
void OPPROTO op_extsw (void)
1404
{
1405
    T0 = (int64_t)((int32_t)T0);
1406
    RETURN();
1407
}
1408
#endif
1409

    
1410
/* nand */
1411
PPC_OP(nand)
1412
{
1413
    T0 = ~(T0 & T1);
1414
    RETURN();
1415
}
1416

    
1417
/* nor */
1418
PPC_OP(nor)
1419
{
1420
    T0 = ~(T0 | T1);
1421
    RETURN();
1422
}
1423

    
1424
/* or */
1425
PPC_OP(or)
1426
{
1427
    T0 |= T1;
1428
    RETURN();
1429
}
1430

    
1431
/* orc */
1432
PPC_OP(orc)
1433
{
1434
    T0 |= ~T1;
1435
    RETURN();
1436
}
1437

    
1438
/* ori */
1439
PPC_OP(ori)
1440
{
1441
    T0 |= PARAM(1);
1442
    RETURN();
1443
}
1444

    
1445
/* xor */
1446
PPC_OP(xor)
1447
{
1448
    T0 ^= T1;
1449
    RETURN();
1450
}
1451

    
1452
/* xori */
1453
PPC_OP(xori)
1454
{
1455
    T0 ^= PARAM(1);
1456
    RETURN();
1457
}
1458

    
1459
/***                             Integer rotate                            ***/
1460
void OPPROTO op_rotl32_T0_T1 (void)
1461
{
1462
    T0 = rotl32(T0, T1 & 0x1F);
1463
    RETURN();
1464
}
1465

    
1466
void OPPROTO op_rotli32_T0 (void)
1467
{
1468
    T0 = rotl32(T0, PARAM1);
1469
    RETURN();
1470
}
1471

    
1472
#if defined(TARGET_PPC64)
1473
void OPPROTO op_rotl64_T0_T1 (void)
1474
{
1475
    T0 = rotl64(T0, T1 & 0x3F);
1476
    RETURN();
1477
}
1478

    
1479
void OPPROTO op_rotli64_T0 (void)
1480
{
1481
    T0 = rotl64(T0, PARAM1);
1482
    RETURN();
1483
}
1484
#endif
1485

    
1486
/***                             Integer shift                             ***/
1487
/* shift left word */
1488
void OPPROTO op_slw (void)
1489
{
1490
    if (T1 & 0x20) {
1491
        T0 = 0;
1492
    } else {
1493
        T0 = (uint32_t)(T0 << T1);
1494
    }
1495
    RETURN();
1496
}
1497

    
1498
#if defined(TARGET_PPC64)
1499
void OPPROTO op_sld (void)
1500
{
1501
    if (T1 & 0x40) {
1502
        T0 = 0;
1503
    } else {
1504
        T0 = T0 << T1;
1505
    }
1506
    RETURN();
1507
}
1508
#endif
1509

    
1510
/* shift right algebraic word */
1511
void OPPROTO op_sraw (void)
1512
{
1513
    do_sraw();
1514
    RETURN();
1515
}
1516

    
1517
#if defined(TARGET_PPC64)
1518
void OPPROTO op_srad (void)
1519
{
1520
    do_srad();
1521
    RETURN();
1522
}
1523
#endif
1524

    
1525
/* shift right algebraic word immediate */
1526
void OPPROTO op_srawi (void)
1527
{
1528
    uint32_t mask = (uint32_t)PARAM2;
1529

    
1530
    T0 = (int32_t)T0 >> PARAM1;
1531
    if ((int32_t)T1 < 0 && (T1 & mask) != 0) {
1532
        xer_ca = 1;
1533
    } else {
1534
        xer_ca = 0;
1535
    }
1536
    RETURN();
1537
}
1538

    
1539
#if defined(TARGET_PPC64)
1540
void OPPROTO op_sradi (void)
1541
{
1542
    uint64_t mask = ((uint64_t)PARAM2 << 32) | (uint64_t)PARAM3;
1543

    
1544
    T0 = (int64_t)T0 >> PARAM1;
1545
    if ((int64_t)T1 < 0 && ((uint64_t)T1 & mask) != 0) {
1546
        xer_ca = 1;
1547
    } else {
1548
        xer_ca = 0;
1549
    }
1550
    RETURN();
1551
}
1552
#endif
1553

    
1554
/* shift right word */
1555
void OPPROTO op_srw (void)
1556
{
1557
    if (T1 & 0x20) {
1558
        T0 = 0;
1559
    } else {
1560
        T0 = (uint32_t)T0 >> T1;
1561
    }
1562
    RETURN();
1563
}
1564

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

    
1577
void OPPROTO op_sl_T0_T1 (void)
1578
{
1579
    T0 = T0 << T1;
1580
    RETURN();
1581
}
1582

    
1583
void OPPROTO op_sli_T0 (void)
1584
{
1585
    T0 = T0 << PARAM1;
1586
    RETURN();
1587
}
1588

    
1589
void OPPROTO op_srl_T0_T1 (void)
1590
{
1591
    T0 = (uint32_t)T0 >> T1;
1592
    RETURN();
1593
}
1594

    
1595
#if defined(TARGET_PPC64)
1596
void OPPROTO op_srl_T0_T1_64 (void)
1597
{
1598
    T0 = (uint32_t)T0 >> T1;
1599
    RETURN();
1600
}
1601
#endif
1602

    
1603
void OPPROTO op_srli_T0 (void)
1604
{
1605
    T0 = (uint32_t)T0 >> PARAM1;
1606
    RETURN();
1607
}
1608

    
1609
#if defined(TARGET_PPC64)
1610
void OPPROTO op_srli_T0_64 (void)
1611
{
1612
    T0 = (uint64_t)T0 >> PARAM1;
1613
    RETURN();
1614
}
1615
#endif
1616

    
1617
void OPPROTO op_srli_T1 (void)
1618
{
1619
    T1 = (uint32_t)T1 >> PARAM1;
1620
    RETURN();
1621
}
1622

    
1623
#if defined(TARGET_PPC64)
1624
void OPPROTO op_srli_T1_64 (void)
1625
{
1626
    T1 = (uint64_t)T1 >> PARAM1;
1627
    RETURN();
1628
}
1629
#endif
1630

    
1631
/***                       Floating-Point arithmetic                       ***/
1632
/* fadd - fadd. */
1633
PPC_OP(fadd)
1634
{
1635
    FT0 = float64_add(FT0, FT1, &env->fp_status);
1636
    RETURN();
1637
}
1638

    
1639
/* fsub - fsub. */
1640
PPC_OP(fsub)
1641
{
1642
    FT0 = float64_sub(FT0, FT1, &env->fp_status);
1643
    RETURN();
1644
}
1645

    
1646
/* fmul - fmul. */
1647
PPC_OP(fmul)
1648
{
1649
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1650
    RETURN();
1651
}
1652

    
1653
/* fdiv - fdiv. */
1654
PPC_OP(fdiv)
1655
{
1656
    FT0 = float64_div(FT0, FT1, &env->fp_status);
1657
    RETURN();
1658
}
1659

    
1660
/* fsqrt - fsqrt. */
1661
PPC_OP(fsqrt)
1662
{
1663
    do_fsqrt();
1664
    RETURN();
1665
}
1666

    
1667
/* fres - fres. */
1668
PPC_OP(fres)
1669
{
1670
    do_fres();
1671
    RETURN();
1672
}
1673

    
1674
/* frsqrte  - frsqrte. */
1675
PPC_OP(frsqrte)
1676
{
1677
    do_frsqrte();
1678
    RETURN();
1679
}
1680

    
1681
/* fsel - fsel. */
1682
PPC_OP(fsel)
1683
{
1684
    do_fsel();
1685
    RETURN();
1686
}
1687

    
1688
/***                     Floating-Point multiply-and-add                   ***/
1689
/* fmadd - fmadd. */
1690
PPC_OP(fmadd)
1691
{
1692
#if USE_PRECISE_EMULATION
1693
    do_fmadd();
1694
#else
1695
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1696
    FT0 = float64_add(FT0, FT2, &env->fp_status);
1697
#endif
1698
    RETURN();
1699
}
1700

    
1701
/* fmsub - fmsub. */
1702
PPC_OP(fmsub)
1703
{
1704
#if USE_PRECISE_EMULATION
1705
    do_fmsub();
1706
#else
1707
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1708
    FT0 = float64_sub(FT0, FT2, &env->fp_status);
1709
#endif
1710
    RETURN();
1711
}
1712

    
1713
/* fnmadd - fnmadd. - fnmadds - fnmadds. */
1714
PPC_OP(fnmadd)
1715
{
1716
    do_fnmadd();
1717
    RETURN();
1718
}
1719

    
1720
/* fnmsub - fnmsub. */
1721
PPC_OP(fnmsub)
1722
{
1723
    do_fnmsub();
1724
    RETURN();
1725
}
1726

    
1727
/***                     Floating-Point round & convert                    ***/
1728
/* frsp - frsp. */
1729
PPC_OP(frsp)
1730
{
1731
    FT0 = float64_to_float32(FT0, &env->fp_status);
1732
    RETURN();
1733
}
1734

    
1735
/* fctiw - fctiw. */
1736
PPC_OP(fctiw)
1737
{
1738
    do_fctiw();
1739
    RETURN();
1740
}
1741

    
1742
/* fctiwz - fctiwz. */
1743
PPC_OP(fctiwz)
1744
{
1745
    do_fctiwz();
1746
    RETURN();
1747
}
1748

    
1749
#if defined(TARGET_PPC64)
1750
/* fcfid - fcfid. */
1751
PPC_OP(fcfid)
1752
{
1753
    do_fcfid();
1754
    RETURN();
1755
}
1756

    
1757
/* fctid - fctid. */
1758
PPC_OP(fctid)
1759
{
1760
    do_fctid();
1761
    RETURN();
1762
}
1763

    
1764
/* fctidz - fctidz. */
1765
PPC_OP(fctidz)
1766
{
1767
    do_fctidz();
1768
    RETURN();
1769
}
1770
#endif
1771

    
1772
/***                         Floating-Point compare                        ***/
1773
/* fcmpu */
1774
PPC_OP(fcmpu)
1775
{
1776
    do_fcmpu();
1777
    RETURN();
1778
}
1779

    
1780
/* fcmpo */
1781
PPC_OP(fcmpo)
1782
{
1783
    do_fcmpo();
1784
    RETURN();
1785
}
1786

    
1787
/***                         Floating-point move                           ***/
1788
/* fabs */
1789
PPC_OP(fabs)
1790
{
1791
    FT0 = float64_abs(FT0);
1792
    RETURN();
1793
}
1794

    
1795
/* fnabs */
1796
PPC_OP(fnabs)
1797
{
1798
    FT0 = float64_abs(FT0);
1799
    FT0 = float64_chs(FT0);
1800
    RETURN();
1801
}
1802

    
1803
/* fneg */
1804
PPC_OP(fneg)
1805
{
1806
    FT0 = float64_chs(FT0);
1807
    RETURN();
1808
}
1809

    
1810
/* Load and store */
1811
#define MEMSUFFIX _raw
1812
#include "op_helper.h"
1813
#include "op_mem.h"
1814
#if !defined(CONFIG_USER_ONLY)
1815
#define MEMSUFFIX _user
1816
#include "op_helper.h"
1817
#include "op_mem.h"
1818
#define MEMSUFFIX _kernel
1819
#include "op_helper.h"
1820
#include "op_mem.h"
1821
#endif
1822

    
1823
/* Special op to check and maybe clear reservation */
1824
void OPPROTO op_check_reservation (void)
1825
{
1826
    if ((uint32_t)env->reserve == (uint32_t)(T0 & ~0x00000003))
1827
        env->reserve = -1;
1828
    RETURN();
1829
}
1830

    
1831
#if defined(TARGET_PPC64)
1832
void OPPROTO op_check_reservation_64 (void)
1833
{
1834
    if ((uint64_t)env->reserve == (uint64_t)(T0 & ~0x00000003))
1835
        env->reserve = -1;
1836
    RETURN();
1837
}
1838
#endif
1839

    
1840
/* Return from interrupt */
1841
#if !defined(CONFIG_USER_ONLY)
1842
void OPPROTO op_rfi (void)
1843
{
1844
    do_rfi();
1845
    RETURN();
1846
}
1847

    
1848
#if defined(TARGET_PPC64)
1849
void OPPROTO op_rfid (void)
1850
{
1851
    do_rfid();
1852
    RETURN();
1853
}
1854
#endif
1855
#endif
1856

    
1857
/* Trap word */
1858
void OPPROTO op_tw (void)
1859
{
1860
    do_tw(PARAM1);
1861
    RETURN();
1862
}
1863

    
1864
#if defined(TARGET_PPC64)
1865
void OPPROTO op_td (void)
1866
{
1867
    do_td(PARAM1);
1868
    RETURN();
1869
}
1870
#endif
1871

    
1872
#if !defined(CONFIG_USER_ONLY)
1873
/* tlbia */
1874
PPC_OP(tlbia)
1875
{
1876
    do_tlbia();
1877
    RETURN();
1878
}
1879

    
1880
/* tlbie */
1881
void OPPROTO op_tlbie (void)
1882
{
1883
    do_tlbie();
1884
    RETURN();
1885
}
1886

    
1887
#if defined(TARGET_PPC64)
1888
void OPPROTO op_tlbie_64 (void)
1889
{
1890
    do_tlbie_64();
1891
    RETURN();
1892
}
1893
#endif
1894

    
1895
#if defined(TARGET_PPC64)
1896
void OPPROTO op_slbia (void)
1897
{
1898
    do_slbia();
1899
    RETURN();
1900
}
1901

    
1902
void OPPROTO op_slbie (void)
1903
{
1904
    do_slbie();
1905
    RETURN();
1906
}
1907
#endif
1908
#endif
1909

    
1910
/* PowerPC 602/603/755 software TLB load instructions */
1911
#if !defined(CONFIG_USER_ONLY)
1912
void OPPROTO op_6xx_tlbld (void)
1913
{
1914
    do_load_6xx_tlb(0);
1915
    RETURN();
1916
}
1917

    
1918
void OPPROTO op_6xx_tlbli (void)
1919
{
1920
    do_load_6xx_tlb(1);
1921
    RETURN();
1922
}
1923
#endif
1924

    
1925
/* 601 specific */
1926
void OPPROTO op_load_601_rtcl (void)
1927
{
1928
    T0 = cpu_ppc601_load_rtcl(env);
1929
    RETURN();
1930
}
1931

    
1932
void OPPROTO op_load_601_rtcu (void)
1933
{
1934
    T0 = cpu_ppc601_load_rtcu(env);
1935
    RETURN();
1936
}
1937

    
1938
#if !defined(CONFIG_USER_ONLY)
1939
void OPPROTO op_store_601_rtcl (void)
1940
{
1941
    cpu_ppc601_store_rtcl(env, T0);
1942
    RETURN();
1943
}
1944

    
1945
void OPPROTO op_store_601_rtcu (void)
1946
{
1947
    cpu_ppc601_store_rtcu(env, T0);
1948
    RETURN();
1949
}
1950

    
1951
void OPPROTO op_load_601_bat (void)
1952
{
1953
    T0 = env->IBAT[PARAM1][PARAM2];
1954
    RETURN();
1955
}
1956
#endif /* !defined(CONFIG_USER_ONLY) */
1957

    
1958
/* 601 unified BATs store.
1959
 * To avoid using specific MMU code for 601, we store BATs in
1960
 * IBAT and DBAT simultaneously, then emulate unified BATs.
1961
 */
1962
#if !defined(CONFIG_USER_ONLY)
1963
void OPPROTO op_store_601_batl (void)
1964
{
1965
    int nr = PARAM1;
1966

    
1967
    env->IBAT[1][nr] = T0;
1968
    env->DBAT[1][nr] = T0;
1969
    RETURN();
1970
}
1971

    
1972
void OPPROTO op_store_601_batu (void)
1973
{
1974
    do_store_601_batu(PARAM1);
1975
    RETURN();
1976
}
1977
#endif /* !defined(CONFIG_USER_ONLY) */
1978

    
1979
/* PowerPC 601 specific instructions (POWER bridge) */
1980
/* XXX: those micro-ops need tests ! */
1981
void OPPROTO op_POWER_abs (void)
1982
{
1983
    if (T0 == INT32_MIN)
1984
        T0 = INT32_MAX;
1985
    else if (T0 < 0)
1986
        T0 = -T0;
1987
    RETURN();
1988
}
1989

    
1990
void OPPROTO op_POWER_abso (void)
1991
{
1992
    do_POWER_abso();
1993
    RETURN();
1994
}
1995

    
1996
void OPPROTO op_POWER_clcs (void)
1997
{
1998
    do_POWER_clcs();
1999
    RETURN();
2000
}
2001

    
2002
void OPPROTO op_POWER_div (void)
2003
{
2004
    do_POWER_div();
2005
    RETURN();
2006
}
2007

    
2008
void OPPROTO op_POWER_divo (void)
2009
{
2010
    do_POWER_divo();
2011
    RETURN();
2012
}
2013

    
2014
void OPPROTO op_POWER_divs (void)
2015
{
2016
    do_POWER_divs();
2017
    RETURN();
2018
}
2019

    
2020
void OPPROTO op_POWER_divso (void)
2021
{
2022
    do_POWER_divso();
2023
    RETURN();
2024
}
2025

    
2026
void OPPROTO op_POWER_doz (void)
2027
{
2028
    if ((int32_t)T1 > (int32_t)T0)
2029
        T0 = T1 - T0;
2030
    else
2031
        T0 = 0;
2032
    RETURN();
2033
}
2034

    
2035
void OPPROTO op_POWER_dozo (void)
2036
{
2037
    do_POWER_dozo();
2038
    RETURN();
2039
}
2040

    
2041
void OPPROTO op_load_xer_cmp (void)
2042
{
2043
    T2 = xer_cmp;
2044
    RETURN();
2045
}
2046

    
2047
void OPPROTO op_POWER_maskg (void)
2048
{
2049
    do_POWER_maskg();
2050
    RETURN();
2051
}
2052

    
2053
void OPPROTO op_POWER_maskir (void)
2054
{
2055
    T0 = (T0 & ~T2) | (T1 & T2);
2056
    RETURN();
2057
}
2058

    
2059
void OPPROTO op_POWER_mul (void)
2060
{
2061
    uint64_t tmp;
2062

    
2063
    tmp = (uint64_t)T0 * (uint64_t)T1;
2064
    env->spr[SPR_MQ] = tmp >> 32;
2065
    T0 = tmp;
2066
    RETURN();
2067
}
2068

    
2069
void OPPROTO op_POWER_mulo (void)
2070
{
2071
    do_POWER_mulo();
2072
    RETURN();
2073
}
2074

    
2075
void OPPROTO op_POWER_nabs (void)
2076
{
2077
    if (T0 > 0)
2078
        T0 = -T0;
2079
    RETURN();
2080
}
2081

    
2082
void OPPROTO op_POWER_nabso (void)
2083
{
2084
    /* nabs never overflows */
2085
    if (T0 > 0)
2086
        T0 = -T0;
2087
    xer_ov = 0;
2088
    RETURN();
2089
}
2090

    
2091
/* XXX: factorise POWER rotates... */
2092
void OPPROTO op_POWER_rlmi (void)
2093
{
2094
    T0 = rotl32(T0, T2) & PARAM1;
2095
    T0 |= T1 & PARAM2;
2096
    RETURN();
2097
}
2098

    
2099
void OPPROTO op_POWER_rrib (void)
2100
{
2101
    T2 &= 0x1FUL;
2102
    T0 = rotl32(T0 & INT32_MIN, T2);
2103
    T0 |= T1 & ~rotl32(INT32_MIN, T2);
2104
    RETURN();
2105
}
2106

    
2107
void OPPROTO op_POWER_sle (void)
2108
{
2109
    T1 &= 0x1FUL;
2110
    env->spr[SPR_MQ] = rotl32(T0, T1);
2111
    T0 = T0 << T1;
2112
    RETURN();
2113
}
2114

    
2115
void OPPROTO op_POWER_sleq (void)
2116
{
2117
    uint32_t tmp = env->spr[SPR_MQ];
2118

    
2119
    T1 &= 0x1FUL;
2120
    env->spr[SPR_MQ] = rotl32(T0, T1);
2121
    T0 = T0 << T1;
2122
    T0 |= tmp >> (32 - T1);
2123
    RETURN();
2124
}
2125

    
2126
void OPPROTO op_POWER_sllq (void)
2127
{
2128
    uint32_t msk = -1;
2129

    
2130
    msk = msk << (T1 & 0x1FUL);
2131
    if (T1 & 0x20UL)
2132
        msk = ~msk;
2133
    T1 &= 0x1FUL;
2134
    T0 = (T0 << T1) & msk;
2135
    T0 |= env->spr[SPR_MQ] & ~msk;
2136
    RETURN();
2137
}
2138

    
2139
void OPPROTO op_POWER_slq (void)
2140
{
2141
    uint32_t msk = -1, tmp;
2142

    
2143
    msk = msk << (T1 & 0x1FUL);
2144
    if (T1 & 0x20UL)
2145
        msk = ~msk;
2146
    T1 &= 0x1FUL;
2147
    tmp = rotl32(T0, T1);
2148
    T0 = tmp & msk;
2149
    env->spr[SPR_MQ] = tmp;
2150
    RETURN();
2151
}
2152

    
2153
void OPPROTO op_POWER_sraq (void)
2154
{
2155
    env->spr[SPR_MQ] = rotl32(T0, 32 - (T1 & 0x1FUL));
2156
    if (T1 & 0x20UL)
2157
        T0 = -1L;
2158
    else
2159
        T0 = (int32_t)T0 >> T1;
2160
    RETURN();
2161
}
2162

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

    
2171
void OPPROTO op_POWER_srea (void)
2172
{
2173
    T1 &= 0x1FUL;
2174
    env->spr[SPR_MQ] = T0 >> T1;
2175
    T0 = (int32_t)T0 >> T1;
2176
    RETURN();
2177
}
2178

    
2179
void OPPROTO op_POWER_sreq (void)
2180
{
2181
    uint32_t tmp;
2182
    int32_t msk;
2183

    
2184
    T1 &= 0x1FUL;
2185
    msk = INT32_MIN >> T1;
2186
    tmp = env->spr[SPR_MQ];
2187
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2188
    T0 = T0 >> T1;
2189
    T0 |= tmp & msk;
2190
    RETURN();
2191
}
2192

    
2193
void OPPROTO op_POWER_srlq (void)
2194
{
2195
    uint32_t tmp;
2196
    int32_t msk;
2197

    
2198
    msk = INT32_MIN >> (T1 & 0x1FUL);
2199
    if (T1 & 0x20UL)
2200
        msk = ~msk;
2201
    T1 &= 0x1FUL;
2202
    tmp = env->spr[SPR_MQ];
2203
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2204
    T0 = T0 >> T1;
2205
    T0 &= msk;
2206
    T0 |= tmp & ~msk;
2207
    RETURN();
2208
}
2209

    
2210
void OPPROTO op_POWER_srq (void)
2211
{
2212
    T1 &= 0x1FUL;
2213
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2214
    T0 = T0 >> T1;
2215
    RETURN();
2216
}
2217

    
2218
/* POWER instructions not implemented in PowerPC 601 */
2219
#if !defined(CONFIG_USER_ONLY)
2220
void OPPROTO op_POWER_mfsri (void)
2221
{
2222
    T1 = T0 >> 28;
2223
    T0 = env->sr[T1];
2224
    RETURN();
2225
}
2226

    
2227
void OPPROTO op_POWER_rac (void)
2228
{
2229
    do_POWER_rac();
2230
    RETURN();
2231
}
2232

    
2233
void OPPROTO op_POWER_rfsvc (void)
2234
{
2235
    do_POWER_rfsvc();
2236
    RETURN();
2237
}
2238
#endif
2239

    
2240
/* PowerPC 602 specific instruction */
2241
#if !defined(CONFIG_USER_ONLY)
2242
void OPPROTO op_602_mfrom (void)
2243
{
2244
    do_op_602_mfrom();
2245
    RETURN();
2246
}
2247
#endif
2248

    
2249
/* PowerPC 4xx specific micro-ops */
2250
void OPPROTO op_405_add_T0_T2 (void)
2251
{
2252
    T0 = (int32_t)T0 + (int32_t)T2;
2253
    RETURN();
2254
}
2255

    
2256
void OPPROTO op_405_mulchw (void)
2257
{
2258
    T0 = ((int16_t)T0) * ((int16_t)(T1 >> 16));
2259
    RETURN();
2260
}
2261

    
2262
void OPPROTO op_405_mulchwu (void)
2263
{
2264
    T0 = ((uint16_t)T0) * ((uint16_t)(T1 >> 16));
2265
    RETURN();
2266
}
2267

    
2268
void OPPROTO op_405_mulhhw (void)
2269
{
2270
    T0 = ((int16_t)(T0 >> 16)) * ((int16_t)(T1 >> 16));
2271
    RETURN();
2272
}
2273

    
2274
void OPPROTO op_405_mulhhwu (void)
2275
{
2276
    T0 = ((uint16_t)(T0 >> 16)) * ((uint16_t)(T1 >> 16));
2277
    RETURN();
2278
}
2279

    
2280
void OPPROTO op_405_mullhw (void)
2281
{
2282
    T0 = ((int16_t)T0) * ((int16_t)T1);
2283
    RETURN();
2284
}
2285

    
2286
void OPPROTO op_405_mullhwu (void)
2287
{
2288
    T0 = ((uint16_t)T0) * ((uint16_t)T1);
2289
    RETURN();
2290
}
2291

    
2292
void OPPROTO op_405_check_ov (void)
2293
{
2294
    do_405_check_ov();
2295
    RETURN();
2296
}
2297

    
2298
void OPPROTO op_405_check_sat (void)
2299
{
2300
    do_405_check_sat();
2301
    RETURN();
2302
}
2303

    
2304
void OPPROTO op_405_check_ovu (void)
2305
{
2306
    if (likely(T0 >= T2)) {
2307
        xer_ov = 0;
2308
    } else {
2309
        xer_ov = 1;
2310
        xer_so = 1;
2311
    }
2312
    RETURN();
2313
}
2314

    
2315
void OPPROTO op_405_check_satu (void)
2316
{
2317
    if (unlikely(T0 < T2)) {
2318
        /* Saturate result */
2319
        T0 = -1;
2320
    }
2321
    RETURN();
2322
}
2323

    
2324
#if !defined(CONFIG_USER_ONLY)
2325
void OPPROTO op_load_dcr (void)
2326
{
2327
    do_load_dcr();
2328
    RETURN();
2329
}
2330

    
2331
void OPPROTO op_store_dcr (void)
2332
{
2333
    do_store_dcr();
2334
    RETURN();
2335
}
2336

    
2337
/* Return from critical interrupt :
2338
 * same as rfi, except nip & MSR are loaded from SRR2/3 instead of SRR0/1
2339
 */
2340
void OPPROTO op_40x_rfci (void)
2341
{
2342
    do_40x_rfci();
2343
    RETURN();
2344
}
2345

    
2346
void OPPROTO op_rfci (void)
2347
{
2348
    do_rfci();
2349
    RETURN();
2350
}
2351

    
2352
void OPPROTO op_rfdi (void)
2353
{
2354
    do_rfdi();
2355
    RETURN();
2356
}
2357

    
2358
void OPPROTO op_rfmci (void)
2359
{
2360
    do_rfmci();
2361
    RETURN();
2362
}
2363

    
2364
void OPPROTO op_wrte (void)
2365
{
2366
    msr_ee = T0 >> 16;
2367
    RETURN();
2368
}
2369

    
2370
void OPPROTO op_4xx_tlbre_lo (void)
2371
{
2372
    do_4xx_tlbre_lo();
2373
    RETURN();
2374
}
2375

    
2376
void OPPROTO op_4xx_tlbre_hi (void)
2377
{
2378
    do_4xx_tlbre_hi();
2379
    RETURN();
2380
}
2381

    
2382
void OPPROTO op_4xx_tlbsx (void)
2383
{
2384
    do_4xx_tlbsx();
2385
    RETURN();
2386
}
2387

    
2388
void OPPROTO op_4xx_tlbsx_ (void)
2389
{
2390
    do_4xx_tlbsx_();
2391
    RETURN();
2392
}
2393

    
2394
void OPPROTO op_4xx_tlbwe_lo (void)
2395
{
2396
    do_4xx_tlbwe_lo();
2397
    RETURN();
2398
}
2399

    
2400
void OPPROTO op_4xx_tlbwe_hi (void)
2401
{
2402
    do_4xx_tlbwe_hi();
2403
    RETURN();
2404
}
2405
#endif
2406

    
2407
/* SPR micro-ops */
2408
/* 440 specific */
2409
void OPPROTO op_440_dlmzb (void)
2410
{
2411
    do_440_dlmzb();
2412
    RETURN();
2413
}
2414

    
2415
void OPPROTO op_440_dlmzb_update_Rc (void)
2416
{
2417
    if (T0 == 8)
2418
        T0 = 0x2;
2419
    else if (T0 < 4)
2420
        T0 = 0x4;
2421
    else
2422
        T0 = 0x8;
2423
    RETURN();
2424
}
2425

    
2426
#if !defined(CONFIG_USER_ONLY)
2427
void OPPROTO op_store_pir (void)
2428
{
2429
    env->spr[SPR_PIR] = T0 & 0x0000000FUL;
2430
    RETURN();
2431
}
2432

    
2433
void OPPROTO op_load_403_pb (void)
2434
{
2435
    do_load_403_pb(PARAM1);
2436
    RETURN();
2437
}
2438

    
2439
void OPPROTO op_store_403_pb (void)
2440
{
2441
    do_store_403_pb(PARAM1);
2442
    RETURN();
2443
}
2444

    
2445
void OPPROTO op_load_40x_pit (void)
2446
{
2447
    T0 = load_40x_pit(env);
2448
    RETURN();
2449
}
2450

    
2451
void OPPROTO op_store_40x_pit (void)
2452
{
2453
    store_40x_pit(env, T0);
2454
    RETURN();
2455
}
2456

    
2457
void OPPROTO op_store_booke_tcr (void)
2458
{
2459
    store_booke_tcr(env, T0);
2460
    RETURN();
2461
}
2462

    
2463
void OPPROTO op_store_booke_tsr (void)
2464
{
2465
    store_booke_tsr(env, T0);
2466
    RETURN();
2467
}
2468

    
2469
#endif /* !defined(CONFIG_USER_ONLY) */
2470

    
2471
#if defined(TARGET_PPCSPE)
2472
/* SPE extension */
2473
void OPPROTO op_splatw_T1_64 (void)
2474
{
2475
    T1_64 = (T1_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL);
2476
    RETURN();
2477
}
2478

    
2479
void OPPROTO op_splatwi_T0_64 (void)
2480
{
2481
    uint64_t tmp = PARAM1;
2482

    
2483
    T0_64 = (tmp << 32) | tmp;
2484
    RETURN();
2485
}
2486

    
2487
void OPPROTO op_splatwi_T1_64 (void)
2488
{
2489
    uint64_t tmp = PARAM1;
2490

    
2491
    T1_64 = (tmp << 32) | tmp;
2492
    RETURN();
2493
}
2494

    
2495
void OPPROTO op_extsh_T1_64 (void)
2496
{
2497
    T1_64 = (int32_t)((int16_t)T1_64);
2498
    RETURN();
2499
}
2500

    
2501
void OPPROTO op_sli16_T1_64 (void)
2502
{
2503
    T1_64 = T1_64 << 16;
2504
    RETURN();
2505
}
2506

    
2507
void OPPROTO op_sli32_T1_64 (void)
2508
{
2509
    T1_64 = T1_64 << 32;
2510
    RETURN();
2511
}
2512

    
2513
void OPPROTO op_srli32_T1_64 (void)
2514
{
2515
    T1_64 = T1_64 >> 32;
2516
    RETURN();
2517
}
2518

    
2519
void OPPROTO op_evsel (void)
2520
{
2521
    do_evsel();
2522
    RETURN();
2523
}
2524

    
2525
void OPPROTO op_evaddw (void)
2526
{
2527
    do_evaddw();
2528
    RETURN();
2529
}
2530

    
2531
void OPPROTO op_evsubfw (void)
2532
{
2533
    do_evsubfw();
2534
    RETURN();
2535
}
2536

    
2537
void OPPROTO op_evneg (void)
2538
{
2539
    do_evneg();
2540
    RETURN();
2541
}
2542

    
2543
void OPPROTO op_evabs (void)
2544
{
2545
    do_evabs();
2546
    RETURN();
2547
}
2548

    
2549
void OPPROTO op_evextsh (void)
2550
{
2551
    T0_64 = ((uint64_t)((int32_t)(int16_t)(T0_64 >> 32)) << 32) |
2552
        (uint64_t)((int32_t)(int16_t)T0_64);
2553
    RETURN();
2554
}
2555

    
2556
void OPPROTO op_evextsb (void)
2557
{
2558
    T0_64 = ((uint64_t)((int32_t)(int8_t)(T0_64 >> 32)) << 32) |
2559
        (uint64_t)((int32_t)(int8_t)T0_64);
2560
    RETURN();
2561
}
2562

    
2563
void OPPROTO op_evcntlzw (void)
2564
{
2565
    do_evcntlzw();
2566
    RETURN();
2567
}
2568

    
2569
void OPPROTO op_evrndw (void)
2570
{
2571
    do_evrndw();
2572
    RETURN();
2573
}
2574

    
2575
void OPPROTO op_brinc (void)
2576
{
2577
    do_brinc();
2578
    RETURN();
2579
}
2580

    
2581
void OPPROTO op_evcntlsw (void)
2582
{
2583
    do_evcntlsw();
2584
    RETURN();
2585
}
2586

    
2587
void OPPROTO op_evand (void)
2588
{
2589
    T0_64 &= T1_64;
2590
    RETURN();
2591
}
2592

    
2593
void OPPROTO op_evandc (void)
2594
{
2595
    T0_64 &= ~T1_64;
2596
    RETURN();
2597
}
2598

    
2599
void OPPROTO op_evor (void)
2600
{
2601
    T0_64 |= T1_64;
2602
    RETURN();
2603
}
2604

    
2605
void OPPROTO op_evxor (void)
2606
{
2607
    T0_64 ^= T1_64;
2608
    RETURN();
2609
}
2610

    
2611
void OPPROTO op_eveqv (void)
2612
{
2613
    T0_64 = ~(T0_64 ^ T1_64);
2614
    RETURN();
2615
}
2616

    
2617
void OPPROTO op_evnor (void)
2618
{
2619
    T0_64 = ~(T0_64 | T1_64);
2620
    RETURN();
2621
}
2622

    
2623
void OPPROTO op_evorc (void)
2624
{
2625
    T0_64 |= ~T1_64;
2626
    RETURN();
2627
}
2628

    
2629
void OPPROTO op_evnand (void)
2630
{
2631
    T0_64 = ~(T0_64 & T1_64);
2632
    RETURN();
2633
}
2634

    
2635
void OPPROTO op_evsrws (void)
2636
{
2637
    do_evsrws();
2638
    RETURN();
2639
}
2640

    
2641
void OPPROTO op_evsrwu (void)
2642
{
2643
    do_evsrwu();
2644
    RETURN();
2645
}
2646

    
2647
void OPPROTO op_evslw (void)
2648
{
2649
    do_evslw();
2650
    RETURN();
2651
}
2652

    
2653
void OPPROTO op_evrlw (void)
2654
{
2655
    do_evrlw();
2656
    RETURN();
2657
}
2658

    
2659
void OPPROTO op_evmergelo (void)
2660
{
2661
    T0_64 = (T0_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL);
2662
    RETURN();
2663
}
2664

    
2665
void OPPROTO op_evmergehi (void)
2666
{
2667
    T0_64 = (T0_64 & 0xFFFFFFFF00000000ULL) | (T1_64 >> 32);
2668
    RETURN();
2669
}
2670

    
2671
void OPPROTO op_evmergelohi (void)
2672
{
2673
    T0_64 = (T0_64 << 32) | (T1_64 >> 32);
2674
    RETURN();
2675
}
2676

    
2677
void OPPROTO op_evmergehilo (void)
2678
{
2679
    T0_64 = (T0_64 & 0xFFFFFFFF00000000ULL) | (T1_64 & 0x00000000FFFFFFFFULL);
2680
    RETURN();
2681
}
2682

    
2683
void OPPROTO op_evcmpgts (void)
2684
{
2685
    do_evcmpgts();
2686
    RETURN();
2687
}
2688

    
2689
void OPPROTO op_evcmpgtu (void)
2690
{
2691
    do_evcmpgtu();
2692
    RETURN();
2693
}
2694

    
2695
void OPPROTO op_evcmplts (void)
2696
{
2697
    do_evcmplts();
2698
    RETURN();
2699
}
2700

    
2701
void OPPROTO op_evcmpltu (void)
2702
{
2703
    do_evcmpltu();
2704
    RETURN();
2705
}
2706

    
2707
void OPPROTO op_evcmpeq (void)
2708
{
2709
    do_evcmpeq();
2710
    RETURN();
2711
}
2712

    
2713
void OPPROTO op_evfssub (void)
2714
{
2715
    do_evfssub();
2716
    RETURN();
2717
}
2718

    
2719
void OPPROTO op_evfsadd (void)
2720
{
2721
    do_evfsadd();
2722
    RETURN();
2723
}
2724

    
2725
void OPPROTO op_evfsnabs (void)
2726
{
2727
    do_evfsnabs();
2728
    RETURN();
2729
}
2730

    
2731
void OPPROTO op_evfsabs (void)
2732
{
2733
    do_evfsabs();
2734
    RETURN();
2735
}
2736

    
2737
void OPPROTO op_evfsneg (void)
2738
{
2739
    do_evfsneg();
2740
    RETURN();
2741
}
2742

    
2743
void OPPROTO op_evfsdiv (void)
2744
{
2745
    do_evfsdiv();
2746
    RETURN();
2747
}
2748

    
2749
void OPPROTO op_evfsmul (void)
2750
{
2751
    do_evfsmul();
2752
    RETURN();
2753
}
2754

    
2755
void OPPROTO op_evfscmplt (void)
2756
{
2757
    do_evfscmplt();
2758
    RETURN();
2759
}
2760

    
2761
void OPPROTO op_evfscmpgt (void)
2762
{
2763
    do_evfscmpgt();
2764
    RETURN();
2765
}
2766

    
2767
void OPPROTO op_evfscmpeq (void)
2768
{
2769
    do_evfscmpeq();
2770
    RETURN();
2771
}
2772

    
2773
void OPPROTO op_evfscfsi (void)
2774
{
2775
    do_evfscfsi();
2776
    RETURN();
2777
}
2778

    
2779
void OPPROTO op_evfscfui (void)
2780
{
2781
    do_evfscfui();
2782
    RETURN();
2783
}
2784

    
2785
void OPPROTO op_evfscfsf (void)
2786
{
2787
    do_evfscfsf();
2788
    RETURN();
2789
}
2790

    
2791
void OPPROTO op_evfscfuf (void)
2792
{
2793
    do_evfscfuf();
2794
    RETURN();
2795
}
2796

    
2797
void OPPROTO op_evfsctsi (void)
2798
{
2799
    do_evfsctsi();
2800
    RETURN();
2801
}
2802

    
2803
void OPPROTO op_evfsctui (void)
2804
{
2805
    do_evfsctui();
2806
    RETURN();
2807
}
2808

    
2809
void OPPROTO op_evfsctsf (void)
2810
{
2811
    do_evfsctsf();
2812
    RETURN();
2813
}
2814

    
2815
void OPPROTO op_evfsctuf (void)
2816
{
2817
    do_evfsctuf();
2818
    RETURN();
2819
}
2820

    
2821
void OPPROTO op_evfsctuiz (void)
2822
{
2823
    do_evfsctuiz();
2824
    RETURN();
2825
}
2826

    
2827
void OPPROTO op_evfsctsiz (void)
2828
{
2829
    do_evfsctsiz();
2830
    RETURN();
2831
}
2832

    
2833
void OPPROTO op_evfststlt (void)
2834
{
2835
    do_evfststlt();
2836
    RETURN();
2837
}
2838

    
2839
void OPPROTO op_evfststgt (void)
2840
{
2841
    do_evfststgt();
2842
    RETURN();
2843
}
2844

    
2845
void OPPROTO op_evfststeq (void)
2846
{
2847
    do_evfststeq();
2848
    RETURN();
2849
}
2850

    
2851
void OPPROTO op_efssub (void)
2852
{
2853
    T0_64 = _do_efssub(T0_64, T1_64);
2854
    RETURN();
2855
}
2856

    
2857
void OPPROTO op_efsadd (void)
2858
{
2859
    T0_64 = _do_efsadd(T0_64, T1_64);
2860
    RETURN();
2861
}
2862

    
2863
void OPPROTO op_efsnabs (void)
2864
{
2865
    T0_64 = _do_efsnabs(T0_64);
2866
    RETURN();
2867
}
2868

    
2869
void OPPROTO op_efsabs (void)
2870
{
2871
    T0_64 = _do_efsabs(T0_64);
2872
    RETURN();
2873
}
2874

    
2875
void OPPROTO op_efsneg (void)
2876
{
2877
    T0_64 = _do_efsneg(T0_64);
2878
    RETURN();
2879
}
2880

    
2881
void OPPROTO op_efsdiv (void)
2882
{
2883
    T0_64 = _do_efsdiv(T0_64, T1_64);
2884
    RETURN();
2885
}
2886

    
2887
void OPPROTO op_efsmul (void)
2888
{
2889
    T0_64 = _do_efsmul(T0_64, T1_64);
2890
    RETURN();
2891
}
2892

    
2893
void OPPROTO op_efscmplt (void)
2894
{
2895
    do_efscmplt();
2896
    RETURN();
2897
}
2898

    
2899
void OPPROTO op_efscmpgt (void)
2900
{
2901
    do_efscmpgt();
2902
    RETURN();
2903
}
2904

    
2905
void OPPROTO op_efscfd (void)
2906
{
2907
    do_efscfd();
2908
    RETURN();
2909
}
2910

    
2911
void OPPROTO op_efscmpeq (void)
2912
{
2913
    do_efscmpeq();
2914
    RETURN();
2915
}
2916

    
2917
void OPPROTO op_efscfsi (void)
2918
{
2919
    do_efscfsi();
2920
    RETURN();
2921
}
2922

    
2923
void OPPROTO op_efscfui (void)
2924
{
2925
    do_efscfui();
2926
    RETURN();
2927
}
2928

    
2929
void OPPROTO op_efscfsf (void)
2930
{
2931
    do_efscfsf();
2932
    RETURN();
2933
}
2934

    
2935
void OPPROTO op_efscfuf (void)
2936
{
2937
    do_efscfuf();
2938
    RETURN();
2939
}
2940

    
2941
void OPPROTO op_efsctsi (void)
2942
{
2943
    do_efsctsi();
2944
    RETURN();
2945
}
2946

    
2947
void OPPROTO op_efsctui (void)
2948
{
2949
    do_efsctui();
2950
    RETURN();
2951
}
2952

    
2953
void OPPROTO op_efsctsf (void)
2954
{
2955
    do_efsctsf();
2956
    RETURN();
2957
}
2958

    
2959
void OPPROTO op_efsctuf (void)
2960
{
2961
    do_efsctuf();
2962
    RETURN();
2963
}
2964

    
2965
void OPPROTO op_efsctsiz (void)
2966
{
2967
    do_efsctsiz();
2968
    RETURN();
2969
}
2970

    
2971
void OPPROTO op_efsctuiz (void)
2972
{
2973
    do_efsctuiz();
2974
    RETURN();
2975
}
2976

    
2977
void OPPROTO op_efststlt (void)
2978
{
2979
    T0 = _do_efststlt(T0_64, T1_64);
2980
    RETURN();
2981
}
2982

    
2983
void OPPROTO op_efststgt (void)
2984
{
2985
    T0 = _do_efststgt(T0_64, T1_64);
2986
    RETURN();
2987
}
2988

    
2989
void OPPROTO op_efststeq (void)
2990
{
2991
    T0 = _do_efststeq(T0_64, T1_64);
2992
    RETURN();
2993
}
2994

    
2995
void OPPROTO op_efdsub (void)
2996
{
2997
    union {
2998
        uint64_t u;
2999
        float64 f;
3000
    } u1, u2;
3001
    u1.u = T0_64;
3002
    u2.u = T1_64;
3003
    u1.f = float64_sub(u1.f, u2.f, &env->spe_status);
3004
    T0_64 = u1.u;
3005
    RETURN();
3006
}
3007

    
3008
void OPPROTO op_efdadd (void)
3009
{
3010
    union {
3011
        uint64_t u;
3012
        float64 f;
3013
    } u1, u2;
3014
    u1.u = T0_64;
3015
    u2.u = T1_64;
3016
    u1.f = float64_add(u1.f, u2.f, &env->spe_status);
3017
    T0_64 = u1.u;
3018
    RETURN();
3019
}
3020

    
3021
void OPPROTO op_efdcfsid (void)
3022
{
3023
    do_efdcfsi();
3024
    RETURN();
3025
}
3026

    
3027
void OPPROTO op_efdcfuid (void)
3028
{
3029
    do_efdcfui();
3030
    RETURN();
3031
}
3032

    
3033
void OPPROTO op_efdnabs (void)
3034
{
3035
    T0_64 |= 0x8000000000000000ULL;
3036
    RETURN();
3037
}
3038

    
3039
void OPPROTO op_efdabs (void)
3040
{
3041
    T0_64 &= ~0x8000000000000000ULL;
3042
    RETURN();
3043
}
3044

    
3045
void OPPROTO op_efdneg (void)
3046
{
3047
    T0_64 ^= 0x8000000000000000ULL;
3048
    RETURN();
3049
}
3050

    
3051
void OPPROTO op_efddiv (void)
3052
{
3053
    union {
3054
        uint64_t u;
3055
        float64 f;
3056
    } u1, u2;
3057
    u1.u = T0_64;
3058
    u2.u = T1_64;
3059
    u1.f = float64_div(u1.f, u2.f, &env->spe_status);
3060
    T0_64 = u1.u;
3061
    RETURN();
3062
}
3063

    
3064
void OPPROTO op_efdmul (void)
3065
{
3066
    union {
3067
        uint64_t u;
3068
        float64 f;
3069
    } u1, u2;
3070
    u1.u = T0_64;
3071
    u2.u = T1_64;
3072
    u1.f = float64_mul(u1.f, u2.f, &env->spe_status);
3073
    T0_64 = u1.u;
3074
    RETURN();
3075
}
3076

    
3077
void OPPROTO op_efdctsidz (void)
3078
{
3079
    do_efdctsiz();
3080
    RETURN();
3081
}
3082

    
3083
void OPPROTO op_efdctuidz (void)
3084
{
3085
    do_efdctuiz();
3086
    RETURN();
3087
}
3088

    
3089
void OPPROTO op_efdcmplt (void)
3090
{
3091
    do_efdcmplt();
3092
    RETURN();
3093
}
3094

    
3095
void OPPROTO op_efdcmpgt (void)
3096
{
3097
    do_efdcmpgt();
3098
    RETURN();
3099
}
3100

    
3101
void OPPROTO op_efdcfs (void)
3102
{
3103
    do_efdcfs();
3104
    RETURN();
3105
}
3106

    
3107
void OPPROTO op_efdcmpeq (void)
3108
{
3109
    do_efdcmpeq();
3110
    RETURN();
3111
}
3112

    
3113
void OPPROTO op_efdcfsi (void)
3114
{
3115
    do_efdcfsi();
3116
    RETURN();
3117
}
3118

    
3119
void OPPROTO op_efdcfui (void)
3120
{
3121
    do_efdcfui();
3122
    RETURN();
3123
}
3124

    
3125
void OPPROTO op_efdcfsf (void)
3126
{
3127
    do_efdcfsf();
3128
    RETURN();
3129
}
3130

    
3131
void OPPROTO op_efdcfuf (void)
3132
{
3133
    do_efdcfuf();
3134
    RETURN();
3135
}
3136

    
3137
void OPPROTO op_efdctsi (void)
3138
{
3139
    do_efdctsi();
3140
    RETURN();
3141
}
3142

    
3143
void OPPROTO op_efdctui (void)
3144
{
3145
    do_efdctui();
3146
    RETURN();
3147
}
3148

    
3149
void OPPROTO op_efdctsf (void)
3150
{
3151
    do_efdctsf();
3152
    RETURN();
3153
}
3154

    
3155
void OPPROTO op_efdctuf (void)
3156
{
3157
    do_efdctuf();
3158
    RETURN();
3159
}
3160

    
3161
void OPPROTO op_efdctuiz (void)
3162
{
3163
    do_efdctuiz();
3164
    RETURN();
3165
}
3166

    
3167
void OPPROTO op_efdctsiz (void)
3168
{
3169
    do_efdctsiz();
3170
    RETURN();
3171
}
3172

    
3173
void OPPROTO op_efdtstlt (void)
3174
{
3175
    T0 = _do_efdtstlt(T0_64, T1_64);
3176
    RETURN();
3177
}
3178

    
3179
void OPPROTO op_efdtstgt (void)
3180
{
3181
    T0 = _do_efdtstgt(T0_64, T1_64);
3182
    RETURN();
3183
}
3184

    
3185
void OPPROTO op_efdtsteq (void)
3186
{
3187
    T0 = _do_efdtsteq(T0_64, T1_64);
3188
    RETURN();
3189
}
3190
#endif /* defined(TARGET_PPCSPE) */