Statistics
| Branch: | Revision:

root / target-ppc / op.c @ 0cfec834

History | View | Annotate | Download (45.6 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
/* subtract 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
/* subtract 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
/* subtract 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
/* subtract 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
/* subtract 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
/* subtract 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_40x_dbcr0 (void)
2458
{
2459
    store_40x_dbcr0(env, T0);
2460
}
2461

    
2462
void OPPROTO op_store_40x_sler (void)
2463
{
2464
    store_40x_sler(env, T0);
2465
    RETURN();
2466
}
2467

    
2468
void OPPROTO op_store_booke_tcr (void)
2469
{
2470
    store_booke_tcr(env, T0);
2471
    RETURN();
2472
}
2473

    
2474
void OPPROTO op_store_booke_tsr (void)
2475
{
2476
    store_booke_tsr(env, T0);
2477
    RETURN();
2478
}
2479

    
2480
#endif /* !defined(CONFIG_USER_ONLY) */
2481

    
2482
#if defined(TARGET_PPCEMB)
2483
/* SPE extension */
2484
void OPPROTO op_splatw_T1_64 (void)
2485
{
2486
    T1_64 = (T1_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL);
2487
    RETURN();
2488
}
2489

    
2490
void OPPROTO op_splatwi_T0_64 (void)
2491
{
2492
    uint64_t tmp = PARAM1;
2493

    
2494
    T0_64 = (tmp << 32) | tmp;
2495
    RETURN();
2496
}
2497

    
2498
void OPPROTO op_splatwi_T1_64 (void)
2499
{
2500
    uint64_t tmp = PARAM1;
2501

    
2502
    T1_64 = (tmp << 32) | tmp;
2503
    RETURN();
2504
}
2505

    
2506
void OPPROTO op_extsh_T1_64 (void)
2507
{
2508
    T1_64 = (int32_t)((int16_t)T1_64);
2509
    RETURN();
2510
}
2511

    
2512
void OPPROTO op_sli16_T1_64 (void)
2513
{
2514
    T1_64 = T1_64 << 16;
2515
    RETURN();
2516
}
2517

    
2518
void OPPROTO op_sli32_T1_64 (void)
2519
{
2520
    T1_64 = T1_64 << 32;
2521
    RETURN();
2522
}
2523

    
2524
void OPPROTO op_srli32_T1_64 (void)
2525
{
2526
    T1_64 = T1_64 >> 32;
2527
    RETURN();
2528
}
2529

    
2530
void OPPROTO op_evsel (void)
2531
{
2532
    do_evsel();
2533
    RETURN();
2534
}
2535

    
2536
void OPPROTO op_evaddw (void)
2537
{
2538
    do_evaddw();
2539
    RETURN();
2540
}
2541

    
2542
void OPPROTO op_evsubfw (void)
2543
{
2544
    do_evsubfw();
2545
    RETURN();
2546
}
2547

    
2548
void OPPROTO op_evneg (void)
2549
{
2550
    do_evneg();
2551
    RETURN();
2552
}
2553

    
2554
void OPPROTO op_evabs (void)
2555
{
2556
    do_evabs();
2557
    RETURN();
2558
}
2559

    
2560
void OPPROTO op_evextsh (void)
2561
{
2562
    T0_64 = ((uint64_t)((int32_t)(int16_t)(T0_64 >> 32)) << 32) |
2563
        (uint64_t)((int32_t)(int16_t)T0_64);
2564
    RETURN();
2565
}
2566

    
2567
void OPPROTO op_evextsb (void)
2568
{
2569
    T0_64 = ((uint64_t)((int32_t)(int8_t)(T0_64 >> 32)) << 32) |
2570
        (uint64_t)((int32_t)(int8_t)T0_64);
2571
    RETURN();
2572
}
2573

    
2574
void OPPROTO op_evcntlzw (void)
2575
{
2576
    do_evcntlzw();
2577
    RETURN();
2578
}
2579

    
2580
void OPPROTO op_evrndw (void)
2581
{
2582
    do_evrndw();
2583
    RETURN();
2584
}
2585

    
2586
void OPPROTO op_brinc (void)
2587
{
2588
    do_brinc();
2589
    RETURN();
2590
}
2591

    
2592
void OPPROTO op_evcntlsw (void)
2593
{
2594
    do_evcntlsw();
2595
    RETURN();
2596
}
2597

    
2598
void OPPROTO op_evand (void)
2599
{
2600
    T0_64 &= T1_64;
2601
    RETURN();
2602
}
2603

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

    
2610
void OPPROTO op_evor (void)
2611
{
2612
    T0_64 |= T1_64;
2613
    RETURN();
2614
}
2615

    
2616
void OPPROTO op_evxor (void)
2617
{
2618
    T0_64 ^= T1_64;
2619
    RETURN();
2620
}
2621

    
2622
void OPPROTO op_eveqv (void)
2623
{
2624
    T0_64 = ~(T0_64 ^ T1_64);
2625
    RETURN();
2626
}
2627

    
2628
void OPPROTO op_evnor (void)
2629
{
2630
    T0_64 = ~(T0_64 | T1_64);
2631
    RETURN();
2632
}
2633

    
2634
void OPPROTO op_evorc (void)
2635
{
2636
    T0_64 |= ~T1_64;
2637
    RETURN();
2638
}
2639

    
2640
void OPPROTO op_evnand (void)
2641
{
2642
    T0_64 = ~(T0_64 & T1_64);
2643
    RETURN();
2644
}
2645

    
2646
void OPPROTO op_evsrws (void)
2647
{
2648
    do_evsrws();
2649
    RETURN();
2650
}
2651

    
2652
void OPPROTO op_evsrwu (void)
2653
{
2654
    do_evsrwu();
2655
    RETURN();
2656
}
2657

    
2658
void OPPROTO op_evslw (void)
2659
{
2660
    do_evslw();
2661
    RETURN();
2662
}
2663

    
2664
void OPPROTO op_evrlw (void)
2665
{
2666
    do_evrlw();
2667
    RETURN();
2668
}
2669

    
2670
void OPPROTO op_evmergelo (void)
2671
{
2672
    T0_64 = (T0_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL);
2673
    RETURN();
2674
}
2675

    
2676
void OPPROTO op_evmergehi (void)
2677
{
2678
    T0_64 = (T0_64 & 0xFFFFFFFF00000000ULL) | (T1_64 >> 32);
2679
    RETURN();
2680
}
2681

    
2682
void OPPROTO op_evmergelohi (void)
2683
{
2684
    T0_64 = (T0_64 << 32) | (T1_64 >> 32);
2685
    RETURN();
2686
}
2687

    
2688
void OPPROTO op_evmergehilo (void)
2689
{
2690
    T0_64 = (T0_64 & 0xFFFFFFFF00000000ULL) | (T1_64 & 0x00000000FFFFFFFFULL);
2691
    RETURN();
2692
}
2693

    
2694
void OPPROTO op_evcmpgts (void)
2695
{
2696
    do_evcmpgts();
2697
    RETURN();
2698
}
2699

    
2700
void OPPROTO op_evcmpgtu (void)
2701
{
2702
    do_evcmpgtu();
2703
    RETURN();
2704
}
2705

    
2706
void OPPROTO op_evcmplts (void)
2707
{
2708
    do_evcmplts();
2709
    RETURN();
2710
}
2711

    
2712
void OPPROTO op_evcmpltu (void)
2713
{
2714
    do_evcmpltu();
2715
    RETURN();
2716
}
2717

    
2718
void OPPROTO op_evcmpeq (void)
2719
{
2720
    do_evcmpeq();
2721
    RETURN();
2722
}
2723

    
2724
void OPPROTO op_evfssub (void)
2725
{
2726
    do_evfssub();
2727
    RETURN();
2728
}
2729

    
2730
void OPPROTO op_evfsadd (void)
2731
{
2732
    do_evfsadd();
2733
    RETURN();
2734
}
2735

    
2736
void OPPROTO op_evfsnabs (void)
2737
{
2738
    do_evfsnabs();
2739
    RETURN();
2740
}
2741

    
2742
void OPPROTO op_evfsabs (void)
2743
{
2744
    do_evfsabs();
2745
    RETURN();
2746
}
2747

    
2748
void OPPROTO op_evfsneg (void)
2749
{
2750
    do_evfsneg();
2751
    RETURN();
2752
}
2753

    
2754
void OPPROTO op_evfsdiv (void)
2755
{
2756
    do_evfsdiv();
2757
    RETURN();
2758
}
2759

    
2760
void OPPROTO op_evfsmul (void)
2761
{
2762
    do_evfsmul();
2763
    RETURN();
2764
}
2765

    
2766
void OPPROTO op_evfscmplt (void)
2767
{
2768
    do_evfscmplt();
2769
    RETURN();
2770
}
2771

    
2772
void OPPROTO op_evfscmpgt (void)
2773
{
2774
    do_evfscmpgt();
2775
    RETURN();
2776
}
2777

    
2778
void OPPROTO op_evfscmpeq (void)
2779
{
2780
    do_evfscmpeq();
2781
    RETURN();
2782
}
2783

    
2784
void OPPROTO op_evfscfsi (void)
2785
{
2786
    do_evfscfsi();
2787
    RETURN();
2788
}
2789

    
2790
void OPPROTO op_evfscfui (void)
2791
{
2792
    do_evfscfui();
2793
    RETURN();
2794
}
2795

    
2796
void OPPROTO op_evfscfsf (void)
2797
{
2798
    do_evfscfsf();
2799
    RETURN();
2800
}
2801

    
2802
void OPPROTO op_evfscfuf (void)
2803
{
2804
    do_evfscfuf();
2805
    RETURN();
2806
}
2807

    
2808
void OPPROTO op_evfsctsi (void)
2809
{
2810
    do_evfsctsi();
2811
    RETURN();
2812
}
2813

    
2814
void OPPROTO op_evfsctui (void)
2815
{
2816
    do_evfsctui();
2817
    RETURN();
2818
}
2819

    
2820
void OPPROTO op_evfsctsf (void)
2821
{
2822
    do_evfsctsf();
2823
    RETURN();
2824
}
2825

    
2826
void OPPROTO op_evfsctuf (void)
2827
{
2828
    do_evfsctuf();
2829
    RETURN();
2830
}
2831

    
2832
void OPPROTO op_evfsctuiz (void)
2833
{
2834
    do_evfsctuiz();
2835
    RETURN();
2836
}
2837

    
2838
void OPPROTO op_evfsctsiz (void)
2839
{
2840
    do_evfsctsiz();
2841
    RETURN();
2842
}
2843

    
2844
void OPPROTO op_evfststlt (void)
2845
{
2846
    do_evfststlt();
2847
    RETURN();
2848
}
2849

    
2850
void OPPROTO op_evfststgt (void)
2851
{
2852
    do_evfststgt();
2853
    RETURN();
2854
}
2855

    
2856
void OPPROTO op_evfststeq (void)
2857
{
2858
    do_evfststeq();
2859
    RETURN();
2860
}
2861

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

    
2868
void OPPROTO op_efsadd (void)
2869
{
2870
    T0_64 = _do_efsadd(T0_64, T1_64);
2871
    RETURN();
2872
}
2873

    
2874
void OPPROTO op_efsnabs (void)
2875
{
2876
    T0_64 = _do_efsnabs(T0_64);
2877
    RETURN();
2878
}
2879

    
2880
void OPPROTO op_efsabs (void)
2881
{
2882
    T0_64 = _do_efsabs(T0_64);
2883
    RETURN();
2884
}
2885

    
2886
void OPPROTO op_efsneg (void)
2887
{
2888
    T0_64 = _do_efsneg(T0_64);
2889
    RETURN();
2890
}
2891

    
2892
void OPPROTO op_efsdiv (void)
2893
{
2894
    T0_64 = _do_efsdiv(T0_64, T1_64);
2895
    RETURN();
2896
}
2897

    
2898
void OPPROTO op_efsmul (void)
2899
{
2900
    T0_64 = _do_efsmul(T0_64, T1_64);
2901
    RETURN();
2902
}
2903

    
2904
void OPPROTO op_efscmplt (void)
2905
{
2906
    do_efscmplt();
2907
    RETURN();
2908
}
2909

    
2910
void OPPROTO op_efscmpgt (void)
2911
{
2912
    do_efscmpgt();
2913
    RETURN();
2914
}
2915

    
2916
void OPPROTO op_efscfd (void)
2917
{
2918
    do_efscfd();
2919
    RETURN();
2920
}
2921

    
2922
void OPPROTO op_efscmpeq (void)
2923
{
2924
    do_efscmpeq();
2925
    RETURN();
2926
}
2927

    
2928
void OPPROTO op_efscfsi (void)
2929
{
2930
    do_efscfsi();
2931
    RETURN();
2932
}
2933

    
2934
void OPPROTO op_efscfui (void)
2935
{
2936
    do_efscfui();
2937
    RETURN();
2938
}
2939

    
2940
void OPPROTO op_efscfsf (void)
2941
{
2942
    do_efscfsf();
2943
    RETURN();
2944
}
2945

    
2946
void OPPROTO op_efscfuf (void)
2947
{
2948
    do_efscfuf();
2949
    RETURN();
2950
}
2951

    
2952
void OPPROTO op_efsctsi (void)
2953
{
2954
    do_efsctsi();
2955
    RETURN();
2956
}
2957

    
2958
void OPPROTO op_efsctui (void)
2959
{
2960
    do_efsctui();
2961
    RETURN();
2962
}
2963

    
2964
void OPPROTO op_efsctsf (void)
2965
{
2966
    do_efsctsf();
2967
    RETURN();
2968
}
2969

    
2970
void OPPROTO op_efsctuf (void)
2971
{
2972
    do_efsctuf();
2973
    RETURN();
2974
}
2975

    
2976
void OPPROTO op_efsctsiz (void)
2977
{
2978
    do_efsctsiz();
2979
    RETURN();
2980
}
2981

    
2982
void OPPROTO op_efsctuiz (void)
2983
{
2984
    do_efsctuiz();
2985
    RETURN();
2986
}
2987

    
2988
void OPPROTO op_efststlt (void)
2989
{
2990
    T0 = _do_efststlt(T0_64, T1_64);
2991
    RETURN();
2992
}
2993

    
2994
void OPPROTO op_efststgt (void)
2995
{
2996
    T0 = _do_efststgt(T0_64, T1_64);
2997
    RETURN();
2998
}
2999

    
3000
void OPPROTO op_efststeq (void)
3001
{
3002
    T0 = _do_efststeq(T0_64, T1_64);
3003
    RETURN();
3004
}
3005

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

    
3019
void OPPROTO op_efdadd (void)
3020
{
3021
    union {
3022
        uint64_t u;
3023
        float64 f;
3024
    } u1, u2;
3025
    u1.u = T0_64;
3026
    u2.u = T1_64;
3027
    u1.f = float64_add(u1.f, u2.f, &env->spe_status);
3028
    T0_64 = u1.u;
3029
    RETURN();
3030
}
3031

    
3032
void OPPROTO op_efdcfsid (void)
3033
{
3034
    do_efdcfsi();
3035
    RETURN();
3036
}
3037

    
3038
void OPPROTO op_efdcfuid (void)
3039
{
3040
    do_efdcfui();
3041
    RETURN();
3042
}
3043

    
3044
void OPPROTO op_efdnabs (void)
3045
{
3046
    T0_64 |= 0x8000000000000000ULL;
3047
    RETURN();
3048
}
3049

    
3050
void OPPROTO op_efdabs (void)
3051
{
3052
    T0_64 &= ~0x8000000000000000ULL;
3053
    RETURN();
3054
}
3055

    
3056
void OPPROTO op_efdneg (void)
3057
{
3058
    T0_64 ^= 0x8000000000000000ULL;
3059
    RETURN();
3060
}
3061

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

    
3075
void OPPROTO op_efdmul (void)
3076
{
3077
    union {
3078
        uint64_t u;
3079
        float64 f;
3080
    } u1, u2;
3081
    u1.u = T0_64;
3082
    u2.u = T1_64;
3083
    u1.f = float64_mul(u1.f, u2.f, &env->spe_status);
3084
    T0_64 = u1.u;
3085
    RETURN();
3086
}
3087

    
3088
void OPPROTO op_efdctsidz (void)
3089
{
3090
    do_efdctsiz();
3091
    RETURN();
3092
}
3093

    
3094
void OPPROTO op_efdctuidz (void)
3095
{
3096
    do_efdctuiz();
3097
    RETURN();
3098
}
3099

    
3100
void OPPROTO op_efdcmplt (void)
3101
{
3102
    do_efdcmplt();
3103
    RETURN();
3104
}
3105

    
3106
void OPPROTO op_efdcmpgt (void)
3107
{
3108
    do_efdcmpgt();
3109
    RETURN();
3110
}
3111

    
3112
void OPPROTO op_efdcfs (void)
3113
{
3114
    do_efdcfs();
3115
    RETURN();
3116
}
3117

    
3118
void OPPROTO op_efdcmpeq (void)
3119
{
3120
    do_efdcmpeq();
3121
    RETURN();
3122
}
3123

    
3124
void OPPROTO op_efdcfsi (void)
3125
{
3126
    do_efdcfsi();
3127
    RETURN();
3128
}
3129

    
3130
void OPPROTO op_efdcfui (void)
3131
{
3132
    do_efdcfui();
3133
    RETURN();
3134
}
3135

    
3136
void OPPROTO op_efdcfsf (void)
3137
{
3138
    do_efdcfsf();
3139
    RETURN();
3140
}
3141

    
3142
void OPPROTO op_efdcfuf (void)
3143
{
3144
    do_efdcfuf();
3145
    RETURN();
3146
}
3147

    
3148
void OPPROTO op_efdctsi (void)
3149
{
3150
    do_efdctsi();
3151
    RETURN();
3152
}
3153

    
3154
void OPPROTO op_efdctui (void)
3155
{
3156
    do_efdctui();
3157
    RETURN();
3158
}
3159

    
3160
void OPPROTO op_efdctsf (void)
3161
{
3162
    do_efdctsf();
3163
    RETURN();
3164
}
3165

    
3166
void OPPROTO op_efdctuf (void)
3167
{
3168
    do_efdctuf();
3169
    RETURN();
3170
}
3171

    
3172
void OPPROTO op_efdctuiz (void)
3173
{
3174
    do_efdctuiz();
3175
    RETURN();
3176
}
3177

    
3178
void OPPROTO op_efdctsiz (void)
3179
{
3180
    do_efdctsiz();
3181
    RETURN();
3182
}
3183

    
3184
void OPPROTO op_efdtstlt (void)
3185
{
3186
    T0 = _do_efdtstlt(T0_64, T1_64);
3187
    RETURN();
3188
}
3189

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

    
3196
void OPPROTO op_efdtsteq (void)
3197
{
3198
    T0 = _do_efdtsteq(T0_64, T1_64);
3199
    RETURN();
3200
}
3201
#endif /* defined(TARGET_PPCEMB) */