Statistics
| Branch: | Revision:

root / target-ppc / op.c @ d9bce9d9

History | View | Annotate | Download (37 kB)

1
/*
2
 *  PowerPC emulation micro-operations for qemu.
3
 * 
4
 *  Copyright (c) 2003-2007 Jocelyn Mayer
5
 *
6
 * This library is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Lesser General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2 of the License, or (at your option) any later version.
10
 *
11
 * This library is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with this library; if not, write to the Free Software
18
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 */
20

    
21
//#define DEBUG_OP
22

    
23
#include "config.h"
24
#include "exec.h"
25
#include "op_helper.h"
26

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
272
PPC_OP(load_xer_bc)
273
{
274
    T1 = xer_bc;
275
    RETURN();
276
}
277

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

    
284
PPC_OP(load_xer)
285
{
286
    do_load_xer();
287
    RETURN();
288
}
289

    
290
PPC_OP(store_xer)
291
{
292
    do_store_xer();
293
    RETURN();
294
}
295

    
296
#if !defined(CONFIG_USER_ONLY)
297
/* Segment registers load and store */
298
PPC_OP(load_sr)
299
{
300
    T0 = regs->sr[T1];
301
    RETURN();
302
}
303

    
304
PPC_OP(store_sr)
305
{
306
    do_store_sr(env, T1, T0);
307
    RETURN();
308
}
309

    
310
PPC_OP(load_sdr1)
311
{
312
    T0 = regs->sdr1;
313
    RETURN();
314
}
315

    
316
PPC_OP(store_sdr1)
317
{
318
    do_store_sdr1(env, T0);
319
    RETURN();
320
}
321

    
322
#if defined (TARGET_PPC64)
323
void OPPROTO op_load_asr (void)
324
{
325
    T0 = env->asr;
326
    RETURN();
327
}
328

    
329
void OPPROTO op_store_asr (void)
330
{
331
    ppc_store_asr(env, T0);
332
    RETURN();
333
}
334
#endif
335

    
336
PPC_OP(load_msr)
337
{
338
    T0 = do_load_msr(env);
339
    RETURN();
340
}
341

    
342
PPC_OP(store_msr)
343
{
344
    do_store_msr(env, T0);
345
    RETURN();
346
}
347

    
348
#if defined (TARGET_PPC64)
349
void OPPROTO op_store_msr_32 (void)
350
{
351
    ppc_store_msr_32(env, T0);
352
    RETURN();
353
}
354
#endif
355
#endif
356

    
357
/* SPR */
358
PPC_OP(load_spr)
359
{
360
    T0 = regs->spr[PARAM(1)];
361
    RETURN();
362
}
363

    
364
PPC_OP(store_spr)
365
{
366
    regs->spr[PARAM(1)] = T0;
367
    RETURN();
368
}
369

    
370
PPC_OP(load_lr)
371
{
372
    T0 = regs->lr;
373
    RETURN();
374
}
375

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

    
382
PPC_OP(load_ctr)
383
{
384
    T0 = regs->ctr;
385
    RETURN();
386
}
387

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

    
394
PPC_OP(load_tbl)
395
{
396
    T0 = cpu_ppc_load_tbl(regs);
397
    RETURN();
398
}
399

    
400
PPC_OP(load_tbu)
401
{
402
    T0 = cpu_ppc_load_tbu(regs);
403
    RETURN();
404
}
405

    
406
#if !defined(CONFIG_USER_ONLY)
407
PPC_OP(store_tbl)
408
{
409
    cpu_ppc_store_tbl(regs, T0);
410
    RETURN();
411
}
412

    
413
PPC_OP(store_tbu)
414
{
415
    cpu_ppc_store_tbu(regs, T0);
416
    RETURN();
417
}
418

    
419
PPC_OP(load_decr)
420
{
421
    T0 = cpu_ppc_load_decr(regs);
422
    RETURN();
423
}
424

    
425
PPC_OP(store_decr)
426
{
427
    cpu_ppc_store_decr(regs, T0);
428
    RETURN();
429
}
430

    
431
PPC_OP(load_ibat)
432
{
433
    T0 = regs->IBAT[PARAM(1)][PARAM(2)];
434
    RETURN();
435
}
436

    
437
void OPPROTO op_store_ibatu (void)
438
{
439
    do_store_ibatu(env, PARAM1, T0);
440
    RETURN();
441
}
442

    
443
void OPPROTO op_store_ibatl (void)
444
{
445
#if 1
446
    env->IBAT[1][PARAM1] = T0;
447
#else
448
    do_store_ibatl(env, PARAM1, T0);
449
#endif
450
    RETURN();
451
}
452

    
453
PPC_OP(load_dbat)
454
{
455
    T0 = regs->DBAT[PARAM(1)][PARAM(2)];
456
    RETURN();
457
}
458

    
459
void OPPROTO op_store_dbatu (void)
460
{
461
    do_store_dbatu(env, PARAM1, T0);
462
    RETURN();
463
}
464

    
465
void OPPROTO op_store_dbatl (void)
466
{
467
#if 1
468
    env->DBAT[1][PARAM1] = T0;
469
#else
470
    do_store_dbatl(env, PARAM1, T0);
471
#endif
472
    RETURN();
473
}
474
#endif /* !defined(CONFIG_USER_ONLY) */
475

    
476
/* FPSCR */
477
PPC_OP(load_fpscr)
478
{
479
    do_load_fpscr();
480
    RETURN();
481
}
482

    
483
PPC_OP(store_fpscr)
484
{
485
    do_store_fpscr(PARAM1);
486
    RETURN();
487
}
488

    
489
PPC_OP(reset_scrfx)
490
{
491
    regs->fpscr[7] &= ~0x8;
492
    RETURN();
493
}
494

    
495
/* crf operations */
496
PPC_OP(getbit_T0)
497
{
498
    T0 = (T0 >> PARAM(1)) & 1;
499
    RETURN();
500
}
501

    
502
PPC_OP(getbit_T1)
503
{
504
    T1 = (T1 >> PARAM(1)) & 1;
505
    RETURN();
506
}
507

    
508
PPC_OP(setcrfbit)
509
{
510
    T1 = (T1 & PARAM(1)) | (T0 << PARAM(2));
511
    RETURN();
512
}
513

    
514
/* Branch */
515
#define EIP regs->nip
516

    
517
PPC_OP(setlr)
518
{
519
    regs->lr = (uint32_t)PARAM1;
520
    RETURN();
521
}
522

    
523
#if defined (TARGET_PPC64)
524
void OPPROTO op_setlr_64 (void)
525
{
526
    regs->lr = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
527
    RETURN();
528
}
529
#endif
530

    
531
PPC_OP(goto_tb0)
532
{
533
    GOTO_TB(op_goto_tb0, PARAM1, 0);
534
}
535

    
536
PPC_OP(goto_tb1)
537
{
538
    GOTO_TB(op_goto_tb1, PARAM1, 1);
539
}
540

    
541
void OPPROTO op_b_T1 (void)
542
{
543
    regs->nip = (uint32_t)(T1 & ~3);
544
    RETURN();
545
}
546

    
547
#if defined (TARGET_PPC64)
548
void OPPROTO op_b_T1_64 (void)
549
{
550
    regs->nip = (uint64_t)(T1 & ~3);
551
    RETURN();
552
}
553
#endif
554

    
555
PPC_OP(jz_T0)
556
{
557
    if (!T0)
558
        GOTO_LABEL_PARAM(1);
559
    RETURN();
560
}
561

    
562
void OPPROTO op_btest_T1 (void)
563
{
564
    if (T0) {
565
        regs->nip = (uint32_t)(T1 & ~3);
566
    } else {
567
        regs->nip = (uint32_t)PARAM1;
568
    }
569
    RETURN();
570
}
571

    
572
#if defined (TARGET_PPC64)
573
void OPPROTO op_btest_T1_64 (void)
574
{
575
    if (T0) {
576
        regs->nip = (uint64_t)(T1 & ~3);
577
    } else {
578
        regs->nip = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
579
    }
580
    RETURN();
581
}
582
#endif
583

    
584
PPC_OP(movl_T1_ctr)
585
{
586
    T1 = regs->ctr;
587
    RETURN();
588
}
589

    
590
PPC_OP(movl_T1_lr)
591
{
592
    T1 = regs->lr;
593
    RETURN();
594
}
595

    
596
/* tests with result in T0 */
597
void OPPROTO op_test_ctr (void)
598
{
599
    T0 = (uint32_t)regs->ctr;
600
    RETURN();
601
}
602

    
603
#if defined(TARGET_PPC64)
604
void OPPROTO op_test_ctr_64 (void)
605
{
606
    T0 = (uint64_t)regs->ctr;
607
    RETURN();
608
}
609
#endif
610

    
611
void OPPROTO op_test_ctr_true (void)
612
{
613
    T0 = ((uint32_t)regs->ctr != 0 && (T0 & PARAM1) != 0);
614
    RETURN();
615
}
616

    
617
#if defined(TARGET_PPC64)
618
void OPPROTO op_test_ctr_true_64 (void)
619
{
620
    T0 = ((uint64_t)regs->ctr != 0 && (T0 & PARAM1) != 0);
621
    RETURN();
622
}
623
#endif
624

    
625
void OPPROTO op_test_ctr_false (void)
626
{
627
    T0 = ((uint32_t)regs->ctr != 0 && (T0 & PARAM1) == 0);
628
    RETURN();
629
}
630

    
631
#if defined(TARGET_PPC64)
632
void OPPROTO op_test_ctr_false_64 (void)
633
{
634
    T0 = ((uint64_t)regs->ctr != 0 && (T0 & PARAM1) == 0);
635
    RETURN();
636
}
637
#endif
638

    
639
void OPPROTO op_test_ctrz (void)
640
{
641
    T0 = ((uint32_t)regs->ctr == 0);
642
    RETURN();
643
}
644

    
645
#if defined(TARGET_PPC64)
646
void OPPROTO op_test_ctrz_64 (void)
647
{
648
    T0 = ((uint64_t)regs->ctr == 0);
649
    RETURN();
650
}
651
#endif
652

    
653
void OPPROTO op_test_ctrz_true (void)
654
{
655
    T0 = ((uint32_t)regs->ctr == 0 && (T0 & PARAM1) != 0);
656
    RETURN();
657
}
658

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

    
667
void OPPROTO op_test_ctrz_false (void)
668
{
669
    T0 = ((uint32_t)regs->ctr == 0 && (T0 & PARAM1) == 0);
670
    RETURN();
671
}
672

    
673
#if defined(TARGET_PPC64)
674
void OPPROTO op_test_ctrz_false_64 (void)
675
{
676
    T0 = ((uint64_t)regs->ctr == 0 && (T0 & PARAM1) == 0);
677
    RETURN();
678
}
679
#endif
680

    
681
PPC_OP(test_true)
682
{
683
    T0 = (T0 & PARAM(1));
684
    RETURN();
685
}
686

    
687
PPC_OP(test_false)
688
{
689
    T0 = ((T0 & PARAM(1)) == 0);
690
    RETURN();
691
}
692

    
693
/* CTR maintenance */
694
PPC_OP(dec_ctr)
695
{
696
    regs->ctr--;
697
    RETURN();
698
}
699

    
700
/***                           Integer arithmetic                          ***/
701
/* add */
702
PPC_OP(add)
703
{
704
    T0 += T1;
705
    RETURN();
706
}
707

    
708
void OPPROTO op_check_addo (void)
709
{
710
    if (likely(!(((uint32_t)T2 ^ (uint32_t)T1 ^ UINT32_MAX) &
711
                 ((uint32_t)T2 ^ (uint32_t)T0) & (1UL << 31)))) {
712
        xer_ov = 0;
713
    } else {
714
        xer_so = 1;
715
        xer_ov = 1;
716
    }
717
}
718

    
719
#if defined(TARGET_PPC64)
720
void OPPROTO op_check_addo_64 (void)
721
{
722
    if (likely(!(((uint64_t)T2 ^ (uint64_t)T1 ^ UINT64_MAX) &
723
                 ((uint64_t)T2 ^ (uint64_t)T0) & (1UL << 63)))) {
724
        xer_ov = 0;
725
    } else {
726
        xer_so = 1;
727
        xer_ov = 1;
728
    }
729
}
730
#endif
731

    
732
/* add carrying */
733
void OPPROTO op_check_addc (void)
734
{
735
    if (likely((uint32_t)T0 >= (uint32_t)T2)) {
736
        xer_ca = 0;
737
    } else {
738
        xer_ca = 1;
739
    }
740
    RETURN();
741
}
742

    
743
#if defined(TARGET_PPC64)
744
void OPPROTO op_check_addc_64 (void)
745
{
746
    if (likely((uint64_t)T0 >= (uint64_t)T2)) {
747
        xer_ca = 0;
748
    } else {
749
        xer_ca = 1;
750
    }
751
    RETURN();
752
}
753
#endif
754

    
755
/* add extended */
756
void OPPROTO op_adde (void)
757
{
758
    do_adde();
759
    RETURN();
760
}
761

    
762
#if defined(TARGET_PPC64)
763
void OPPROTO op_adde_64 (void)
764
{
765
    do_adde_64();
766
    RETURN();
767
}
768
#endif
769

    
770
/* add immediate */
771
PPC_OP(addi)
772
{
773
    T0 += PARAM(1);
774
    RETURN();
775
}
776

    
777
/* add to minus one extended */
778
void OPPROTO op_add_me (void)
779
{
780
    T0 += xer_ca + (-1);
781
    if (likely((uint32_t)T1 != 0))
782
        xer_ca = 1;
783
    RETURN();
784
}
785

    
786
#if defined(TARGET_PPC64)
787
void OPPROTO op_add_me_64 (void)
788
{
789
    T0 += xer_ca + (-1);
790
    if (likely((uint64_t)T1 != 0))
791
        xer_ca = 1;
792
    RETURN();
793
}
794
#endif
795

    
796
void OPPROTO op_addmeo (void)
797
{
798
    do_addmeo();
799
    RETURN();
800
}
801

    
802
void OPPROTO op_addmeo_64 (void)
803
{
804
    do_addmeo();
805
    RETURN();
806
}
807

    
808
/* add to zero extended */
809
void OPPROTO op_add_ze (void)
810
{
811
    T0 += xer_ca;
812
    RETURN();
813
}
814

    
815
/* divide word */
816
void OPPROTO op_divw (void)
817
{
818
    if (unlikely(((int32_t)T0 == INT32_MIN && (int32_t)T1 == -1) ||
819
                 (int32_t)T1 == 0)) {
820
        T0 = (int32_t)((-1) * ((uint32_t)T0 >> 31));
821
    } else {
822
        T0 = (int32_t)T0 / (int32_t)T1;
823
    }
824
    RETURN();
825
}
826

    
827
#if defined(TARGET_PPC64)
828
void OPPROTO op_divd (void)
829
{
830
    if (unlikely(((int64_t)T0 == INT64_MIN && (int64_t)T1 == -1) ||
831
                 (int64_t)T1 == 0)) {
832
        T0 = (int64_t)((-1ULL) * ((uint64_t)T0 >> 63));
833
    } else {
834
        T0 = (int64_t)T0 / (int64_t)T1;
835
    }
836
    RETURN();
837
}
838
#endif
839

    
840
void OPPROTO op_divwo (void)
841
{
842
    do_divwo();
843
    RETURN();
844
}
845

    
846
#if defined(TARGET_PPC64)
847
void OPPROTO op_divdo (void)
848
{
849
    do_divdo();
850
    RETURN();
851
}
852
#endif
853

    
854
/* divide word unsigned */
855
void OPPROTO op_divwu (void)
856
{
857
    if (unlikely(T1 == 0)) {
858
        T0 = 0;
859
    } else {
860
        T0 = (uint32_t)T0 / (uint32_t)T1;
861
    }
862
    RETURN();
863
}
864

    
865
#if defined(TARGET_PPC64)
866
void OPPROTO op_divdu (void)
867
{
868
    if (unlikely(T1 == 0)) {
869
        T0 = 0;
870
    } else {
871
        T0 /= T1;
872
    }
873
    RETURN();
874
}
875
#endif
876

    
877
void OPPROTO op_divwuo (void)
878
{
879
    do_divwuo();
880
    RETURN();
881
}
882

    
883
#if defined(TARGET_PPC64)
884
void OPPROTO op_divduo (void)
885
{
886
    do_divduo();
887
    RETURN();
888
}
889
#endif
890

    
891
/* multiply high word */
892
void OPPROTO op_mulhw (void)
893
{
894
    T0 = ((int64_t)((int32_t)T0) * (int64_t)((int32_t)T1)) >> 32;
895
    RETURN();
896
}
897

    
898
#if defined(TARGET_PPC64)
899
void OPPROTO op_mulhd (void)
900
{
901
    uint64_t tl, th;
902

    
903
    do_imul64(&tl, &th);
904
    T0 = th;
905
    RETURN();
906
}
907
#endif
908

    
909
/* multiply high word unsigned */
910
void OPPROTO op_mulhwu (void)
911
{
912
    T0 = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1) >> 32;
913
    RETURN();
914
}
915

    
916
#if defined(TARGET_PPC64)
917
void OPPROTO op_mulhdu (void)
918
{
919
    uint64_t tl, th;
920

    
921
    do_mul64(&tl, &th);
922
    T0 = th;
923
    RETURN();
924
}
925
#endif
926

    
927
/* multiply low immediate */
928
PPC_OP(mulli)
929
{
930
    T0 = ((int32_t)T0 * (int32_t)PARAM1);
931
    RETURN();
932
}
933

    
934
/* multiply low word */
935
PPC_OP(mullw)
936
{
937
    T0 = (int32_t)(T0 * T1);
938
    RETURN();
939
}
940

    
941
#if defined(TARGET_PPC64)
942
void OPPROTO op_mulld (void)
943
{
944
    T0 *= T1;
945
    RETURN();
946
}
947
#endif
948

    
949
void OPPROTO op_mullwo (void)
950
{
951
    do_mullwo();
952
    RETURN();
953
}
954

    
955
#if defined(TARGET_PPC64)
956
void OPPROTO op_mulldo (void)
957
{
958
    do_mulldo();
959
    RETURN();
960
}
961
#endif
962

    
963
/* negate */
964
void OPPROTO op_neg (void)
965
{
966
    if (likely(T0 != INT32_MIN)) {
967
        T0 = -(int32_t)T0;
968
    }
969
    RETURN();
970
}
971

    
972
#if defined(TARGET_PPC64)
973
void OPPROTO op_neg_64 (void)
974
{
975
    if (likely(T0 != INT64_MIN)) {
976
        T0 = -(int64_t)T0;
977
    }
978
    RETURN();
979
}
980
#endif
981

    
982
void OPPROTO op_nego (void)
983
{
984
    do_nego();
985
    RETURN();
986
}
987

    
988
#if defined(TARGET_PPC64)
989
void OPPROTO op_nego_64 (void)
990
{
991
    do_nego_64();
992
    RETURN();
993
}
994
#endif
995

    
996
/* substract from */
997
PPC_OP(subf)
998
{
999
    T0 = T1 - T0;
1000
    RETURN();
1001
}
1002

    
1003
void OPPROTO op_check_subfo (void)
1004
{
1005
    if (likely(!(((uint32_t)(~T2) ^ (uint32_t)T1 ^ UINT32_MAX) &
1006
                 ((uint32_t)(~T2) ^ (uint32_t)T0) & (1UL << 31)))) {
1007
        xer_ov = 0;
1008
    } else {
1009
        xer_so = 1;
1010
        xer_ov = 1;
1011
    }
1012
    RETURN();
1013
}
1014

    
1015
#if defined(TARGET_PPC64)
1016
void OPPROTO op_check_subfo_64 (void)
1017
{
1018
    if (likely(!(((uint64_t)(~T2) ^ (uint64_t)T1 ^ UINT64_MAX) &
1019
                 ((uint64_t)(~T2) ^ (uint64_t)T0) & (1ULL << 63)))) {
1020
        xer_ov = 0;
1021
    } else {
1022
        xer_so = 1;
1023
        xer_ov = 1;
1024
    }
1025
    RETURN();
1026
}
1027
#endif
1028

    
1029
/* substract from carrying */
1030
void OPPROTO op_check_subfc (void)
1031
{
1032
    if (likely((uint32_t)T0 > (uint32_t)T1)) {
1033
        xer_ca = 0;
1034
    } else {
1035
        xer_ca = 1;
1036
    }
1037
    RETURN();
1038
}
1039

    
1040
#if defined(TARGET_PPC64)
1041
void OPPROTO op_check_subfc_64 (void)
1042
{
1043
    if (likely((uint64_t)T0 > (uint64_t)T1)) {
1044
        xer_ca = 0;
1045
    } else {
1046
        xer_ca = 1;
1047
    }
1048
    RETURN();
1049
}
1050
#endif
1051

    
1052
/* substract from extended */
1053
void OPPROTO op_subfe (void)
1054
{
1055
    do_subfe();
1056
    RETURN();
1057
}
1058

    
1059
#if defined(TARGET_PPC64)
1060
void OPPROTO op_subfe_64 (void)
1061
{
1062
    do_subfe_64();
1063
    RETURN();
1064
}
1065
#endif
1066

    
1067
/* substract from immediate carrying */
1068
void OPPROTO op_subfic (void)
1069
{
1070
    T0 = PARAM1 + ~T0 + 1;
1071
    if ((uint32_t)T0 <= (uint32_t)PARAM1) {
1072
        xer_ca = 1;
1073
    } else {
1074
        xer_ca = 0;
1075
    }
1076
    RETURN();
1077
}
1078

    
1079
#if defined(TARGET_PPC64)
1080
void OPPROTO op_subfic_64 (void)
1081
{
1082
    T0 = PARAM1 + ~T0 + 1;
1083
    if ((uint64_t)T0 <= (uint64_t)PARAM1) {
1084
        xer_ca = 1;
1085
    } else {
1086
        xer_ca = 0;
1087
    }
1088
    RETURN();
1089
}
1090
#endif
1091

    
1092
/* substract from minus one extended */
1093
void OPPROTO op_subfme (void)
1094
{
1095
    T0 = ~T0 + xer_ca - 1;
1096
    if (likely((uint32_t)T0 != (uint32_t)-1))
1097
        xer_ca = 1;
1098
    RETURN();
1099
}
1100

    
1101
#if defined(TARGET_PPC64)
1102
void OPPROTO op_subfme_64 (void)
1103
{
1104
    T0 = ~T0 + xer_ca - 1;
1105
    if (likely((uint64_t)T0 != (uint64_t)-1))
1106
        xer_ca = 1;
1107
    RETURN();
1108
}
1109
#endif
1110

    
1111
void OPPROTO op_subfmeo (void)
1112
{
1113
    do_subfmeo();
1114
    RETURN();
1115
}
1116

    
1117
#if defined(TARGET_PPC64)
1118
void OPPROTO op_subfmeo_64 (void)
1119
{
1120
    do_subfmeo_64();
1121
    RETURN();
1122
}
1123
#endif
1124

    
1125
/* substract from zero extended */
1126
void OPPROTO op_subfze (void)
1127
{
1128
    T1 = ~T0;
1129
    T0 = T1 + xer_ca;
1130
    if ((uint32_t)T0 < (uint32_t)T1) {
1131
        xer_ca = 1;
1132
    } else {
1133
        xer_ca = 0;
1134
    }
1135
    RETURN();
1136
}
1137

    
1138
#if defined(TARGET_PPC64)
1139
void OPPROTO op_subfze_64 (void)
1140
{
1141
    T1 = ~T0;
1142
    T0 = T1 + xer_ca;
1143
    if ((uint64_t)T0 < (uint64_t)T1) {
1144
        xer_ca = 1;
1145
    } else {
1146
        xer_ca = 0;
1147
    }
1148
    RETURN();
1149
}
1150
#endif
1151

    
1152
void OPPROTO op_subfzeo (void)
1153
{
1154
    do_subfzeo();
1155
    RETURN();
1156
}
1157

    
1158
#if defined(TARGET_PPC64)
1159
void OPPROTO op_subfzeo_64 (void)
1160
{
1161
    do_subfzeo_64();
1162
    RETURN();
1163
}
1164
#endif
1165

    
1166
/***                           Integer comparison                          ***/
1167
/* compare */
1168
void OPPROTO op_cmp (void)
1169
{
1170
    if ((int32_t)T0 < (int32_t)T1) {
1171
        T0 = 0x08;
1172
    } else if ((int32_t)T0 > (int32_t)T1) {
1173
        T0 = 0x04;
1174
    } else {
1175
        T0 = 0x02;
1176
    }
1177
    RETURN();
1178
}
1179

    
1180
#if defined(TARGET_PPC64)
1181
void OPPROTO op_cmp_64 (void)
1182
{
1183
    if ((int64_t)T0 < (int64_t)T1) {
1184
        T0 = 0x08;
1185
    } else if ((int64_t)T0 > (int64_t)T1) {
1186
        T0 = 0x04;
1187
    } else {
1188
        T0 = 0x02;
1189
    }
1190
    RETURN();
1191
}
1192
#endif
1193

    
1194
/* compare immediate */
1195
void OPPROTO op_cmpi (void)
1196
{
1197
    if ((int32_t)T0 < (int32_t)PARAM1) {
1198
        T0 = 0x08;
1199
    } else if ((int32_t)T0 > (int32_t)PARAM1) {
1200
        T0 = 0x04;
1201
    } else {
1202
        T0 = 0x02;
1203
    }
1204
    RETURN();
1205
}
1206

    
1207
#if defined(TARGET_PPC64)
1208
void OPPROTO op_cmpi_64 (void)
1209
{
1210
    if ((int64_t)T0 < (int64_t)((int32_t)PARAM1)) {
1211
        T0 = 0x08;
1212
    } else if ((int64_t)T0 > (int64_t)((int32_t)PARAM1)) {
1213
        T0 = 0x04;
1214
    } else {
1215
        T0 = 0x02;
1216
    }
1217
    RETURN();
1218
}
1219
#endif
1220

    
1221
/* compare logical */
1222
void OPPROTO op_cmpl (void)
1223
{
1224
    if ((uint32_t)T0 < (uint32_t)T1) {
1225
        T0 = 0x08;
1226
    } else if ((uint32_t)T0 > (uint32_t)T1) {
1227
        T0 = 0x04;
1228
    } else {
1229
        T0 = 0x02;
1230
    }
1231
    RETURN();
1232
}
1233

    
1234
#if defined(TARGET_PPC64)
1235
void OPPROTO op_cmpl_64 (void)
1236
{
1237
    if ((uint64_t)T0 < (uint64_t)T1) {
1238
        T0 = 0x08;
1239
    } else if ((uint64_t)T0 > (uint64_t)T1) {
1240
        T0 = 0x04;
1241
    } else {
1242
        T0 = 0x02;
1243
    }
1244
    RETURN();
1245
}
1246
#endif
1247

    
1248
/* compare logical immediate */
1249
void OPPROTO op_cmpli (void)
1250
{
1251
    if ((uint32_t)T0 < (uint32_t)PARAM1) {
1252
        T0 = 0x08;
1253
    } else if ((uint32_t)T0 > (uint32_t)PARAM1) {
1254
        T0 = 0x04;
1255
    } else {
1256
        T0 = 0x02;
1257
    }
1258
    RETURN();
1259
}
1260

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

    
1275
void OPPROTO op_isel (void)
1276
{
1277
    if (T0)
1278
        T0 = T1;
1279
    else
1280
        T0 = T2;
1281
    RETURN();
1282
}
1283

    
1284
void OPPROTO op_popcntb (void)
1285
{
1286
    do_popcntb();
1287
    RETURN();
1288
}
1289

    
1290
#if defined(TARGET_PPC64)
1291
void OPPROTO op_popcntb_64 (void)
1292
{
1293
    do_popcntb_64();
1294
    RETURN();
1295
}
1296
#endif
1297

    
1298
/***                            Integer logical                            ***/
1299
/* and */
1300
PPC_OP(and)
1301
{
1302
    T0 &= T1;
1303
    RETURN();
1304
}
1305

    
1306
/* andc */
1307
PPC_OP(andc)
1308
{
1309
    T0 &= ~T1;
1310
    RETURN();
1311
}
1312

    
1313
/* andi. */
1314
void OPPROTO op_andi_T0 (void)
1315
{
1316
    T0 &= PARAM(1);
1317
    RETURN();
1318
}
1319

    
1320
void OPPROTO op_andi_T1 (void)
1321
{
1322
    T1 &= PARAM1;
1323
    RETURN();
1324
}
1325

    
1326
/* count leading zero */
1327
void OPPROTO op_cntlzw (void)
1328
{
1329
    int cnt;
1330

    
1331
    cnt = 0;
1332
    if (!(T0 & 0xFFFF0000UL)) {
1333
        cnt += 16;
1334
        T0 <<= 16;
1335
    }
1336
    if (!(T0 & 0xFF000000UL)) {
1337
        cnt += 8;
1338
        T0 <<= 8;
1339
    }
1340
    if (!(T0 & 0xF0000000UL)) {
1341
        cnt += 4;
1342
        T0 <<= 4;
1343
    }
1344
    if (!(T0 & 0xC0000000UL)) {
1345
        cnt += 2;
1346
        T0 <<= 2;
1347
    }
1348
    if (!(T0 & 0x80000000UL)) {
1349
        cnt++;
1350
        T0 <<= 1;
1351
    }
1352
    if (!(T0 & 0x80000000UL)) {
1353
        cnt++;
1354
    }
1355
    T0 = cnt;
1356
    RETURN();
1357
}
1358

    
1359
#if defined(TARGET_PPC64)
1360
void OPPROTO op_cntlzd (void)
1361
{
1362
#if HOST_LONG_BITS == 64
1363
    int cnt;
1364

    
1365
    cnt = 0;
1366
    if (!(T0 & 0xFFFFFFFF00000000ULL)) {
1367
        cnt += 32;
1368
        T0 <<= 32;
1369
    }
1370
    if (!(T0 & 0xFFFF000000000000ULL)) {
1371
        cnt += 16;
1372
        T0 <<= 16;
1373
    }
1374
    if (!(T0 & 0xFF00000000000000ULL)) {
1375
        cnt += 8;
1376
        T0 <<= 8;
1377
    }
1378
    if (!(T0 & 0xF000000000000000ULL)) {
1379
        cnt += 4;
1380
        T0 <<= 4;
1381
    }
1382
    if (!(T0 & 0xC000000000000000ULL)) {
1383
        cnt += 2;
1384
        T0 <<= 2;
1385
    }
1386
    if (!(T0 & 0x8000000000000000ULL)) {
1387
        cnt++;
1388
        T0 <<= 1;
1389
    }
1390
    if (!(T0 & 0x8000000000000000ULL)) {
1391
        cnt++;
1392
    }
1393
    T0 = cnt;
1394
#else
1395
    uint32_t tmp;
1396

    
1397
    /* Make it easier on 32 bits host machines */
1398
    if (!(T0 >> 32)) {
1399
        tmp = T0;
1400
        T0 = 32;
1401
    } else {
1402
        tmp = T0 >> 32;
1403
        T0 = 0;
1404
    }
1405
    if (!(tmp & 0xFFFF0000UL)) {
1406
        T0 += 16;
1407
        tmp <<= 16;
1408
    }
1409
    if (!(tmp & 0xFF000000UL)) {
1410
        T0 += 8;
1411
        tmp <<= 8;
1412
    }
1413
    if (!(tmp & 0xF0000000UL)) {
1414
        T0 += 4;
1415
        tmp <<= 4;
1416
    }
1417
    if (!(tmp & 0xC0000000UL)) {
1418
        T0 += 2;
1419
        tmp <<= 2;
1420
    }
1421
    if (!(tmp & 0x80000000UL)) {
1422
        T0++;
1423
        tmp <<= 1;
1424
    }
1425
    if (!(tmp & 0x80000000UL)) {
1426
        T0++;
1427
    }
1428
#endif
1429
    RETURN();
1430
}
1431
#endif
1432

    
1433
/* eqv */
1434
PPC_OP(eqv)
1435
{
1436
    T0 = ~(T0 ^ T1);
1437
    RETURN();
1438
}
1439

    
1440
/* extend sign byte */
1441
void OPPROTO op_extsb (void)
1442
{
1443
#if defined (TARGET_PPC64)
1444
    T0 = (int64_t)((int8_t)T0);
1445
#else
1446
    T0 = (int32_t)((int8_t)T0);
1447
#endif
1448
    RETURN();
1449
}
1450

    
1451
/* extend sign half word */
1452
void OPPROTO op_extsh (void)
1453
{
1454
#if defined (TARGET_PPC64)
1455
    T0 = (int64_t)((int16_t)T0);
1456
#else
1457
    T0 = (int32_t)((int16_t)T0);
1458
#endif
1459
    RETURN();
1460
}
1461

    
1462
#if defined (TARGET_PPC64)
1463
void OPPROTO op_extsw (void)
1464
{
1465
    T0 = (int64_t)((int32_t)T0);
1466
    RETURN();
1467
}
1468
#endif
1469

    
1470
/* nand */
1471
PPC_OP(nand)
1472
{
1473
    T0 = ~(T0 & T1);
1474
    RETURN();
1475
}
1476

    
1477
/* nor */
1478
PPC_OP(nor)
1479
{
1480
    T0 = ~(T0 | T1);
1481
    RETURN();
1482
}
1483

    
1484
/* or */
1485
PPC_OP(or)
1486
{
1487
    T0 |= T1;
1488
    RETURN();
1489
}
1490

    
1491
/* orc */
1492
PPC_OP(orc)
1493
{
1494
    T0 |= ~T1;
1495
    RETURN();
1496
}
1497

    
1498
/* ori */
1499
PPC_OP(ori)
1500
{
1501
    T0 |= PARAM(1);
1502
    RETURN();
1503
}
1504

    
1505
/* xor */
1506
PPC_OP(xor)
1507
{
1508
    T0 ^= T1;
1509
    RETURN();
1510
}
1511

    
1512
/* xori */
1513
PPC_OP(xori)
1514
{
1515
    T0 ^= PARAM(1);
1516
    RETURN();
1517
}
1518

    
1519
/***                             Integer rotate                            ***/
1520
void OPPROTO op_rotl32_T0_T1 (void)
1521
{
1522
    T0 = rotl32(T0, T1 & 0x1F);
1523
    RETURN();
1524
}
1525

    
1526
void OPPROTO op_rotli32_T0 (void)
1527
{
1528
    T0 = rotl32(T0, PARAM1);
1529
    RETURN();
1530
}
1531

    
1532
/***                             Integer shift                             ***/
1533
/* shift left word */
1534
void OPPROTO op_slw (void)
1535
{
1536
    if (T1 & 0x20) {
1537
        T0 = 0;
1538
    } else {
1539
        T0 = (uint32_t)(T0 << T1);
1540
    }
1541
    RETURN();
1542
}
1543

    
1544
#if defined(TARGET_PPC64)
1545
void OPPROTO op_sld (void)
1546
{
1547
    if (T1 & 0x40) {
1548
        T0 = 0;
1549
    } else {
1550
        T0 = T0 << T1;
1551
    }
1552
    RETURN();
1553
}
1554
#endif
1555

    
1556
/* shift right algebraic word */
1557
void OPPROTO op_sraw (void)
1558
{
1559
    do_sraw();
1560
    RETURN();
1561
}
1562

    
1563
#if defined(TARGET_PPC64)
1564
void OPPROTO op_srad (void)
1565
{
1566
    do_srad();
1567
    RETURN();
1568
}
1569
#endif
1570

    
1571
/* shift right algebraic word immediate */
1572
void OPPROTO op_srawi (void)
1573
{
1574
    uint32_t mask = (uint32_t)PARAM2;
1575

    
1576
    T0 = (int32_t)T0 >> PARAM1;
1577
    if ((int32_t)T1 < 0 && (T1 & mask) != 0) {
1578
        xer_ca = 1;
1579
    } else {
1580
        xer_ca = 0;
1581
    }
1582
    RETURN();
1583
}
1584

    
1585
#if defined(TARGET_PPC64)
1586
void OPPROTO op_sradi (void)
1587
{
1588
    uint64_t mask = ((uint64_t)PARAM2 << 32) | (uint64_t)PARAM3;
1589

    
1590
    T0 = (int64_t)T0 >> PARAM1;
1591
    if ((int64_t)T1 < 0 && ((uint64_t)T1 & mask) != 0) {
1592
        xer_ca = 1;
1593
    } else {
1594
        xer_ca = 0;
1595
    }
1596
    RETURN();
1597
}
1598
#endif
1599

    
1600
/* shift right word */
1601
void OPPROTO op_srw (void)
1602
{
1603
    if (T1 & 0x20) {
1604
        T0 = 0;
1605
    } else {
1606
        T0 = (uint32_t)T0 >> T1;
1607
    }
1608
    RETURN();
1609
}
1610

    
1611
#if defined(TARGET_PPC64)
1612
void OPPROTO op_srd (void)
1613
{
1614
    if (T1 & 0x40) {
1615
        T0 = 0;
1616
    } else {
1617
        T0 = (uint64_t)T0 >> T1;
1618
    }
1619
    RETURN();
1620
}
1621
#endif
1622

    
1623
void OPPROTO op_sl_T0_T1 (void)
1624
{
1625
    T0 = T0 << T1;
1626
    RETURN();
1627
}
1628

    
1629
void OPPROTO op_sli_T0 (void)
1630
{
1631
    T0 = T0 << PARAM1;
1632
    RETURN();
1633
}
1634

    
1635
void OPPROTO op_srl_T0_T1 (void)
1636
{
1637
    T0 = (uint32_t)T0 >> T1;
1638
    RETURN();
1639
}
1640

    
1641
#if defined(TARGET_PPC64)
1642
void OPPROTO op_srl_T0_T1_64 (void)
1643
{
1644
    T0 = (uint32_t)T0 >> T1;
1645
    RETURN();
1646
}
1647
#endif
1648

    
1649
void OPPROTO op_srli_T0 (void)
1650
{
1651
    T0 = (uint32_t)T0 >> PARAM1;
1652
    RETURN();
1653
}
1654

    
1655
#if defined(TARGET_PPC64)
1656
void OPPROTO op_srli_T0_64 (void)
1657
{
1658
    T0 = (uint64_t)T0 >> PARAM1;
1659
    RETURN();
1660
}
1661
#endif
1662

    
1663
void OPPROTO op_srli_T1 (void)
1664
{
1665
    T1 = (uint32_t)T1 >> PARAM1;
1666
    RETURN();
1667
}
1668

    
1669
#if defined(TARGET_PPC64)
1670
void OPPROTO op_srli_T1_64 (void)
1671
{
1672
    T1 = (uint64_t)T1 >> PARAM1;
1673
    RETURN();
1674
}
1675
#endif
1676

    
1677
/***                       Floating-Point arithmetic                       ***/
1678
/* fadd - fadd. */
1679
PPC_OP(fadd)
1680
{
1681
    FT0 = float64_add(FT0, FT1, &env->fp_status);
1682
    RETURN();
1683
}
1684

    
1685
/* fsub - fsub. */
1686
PPC_OP(fsub)
1687
{
1688
    FT0 = float64_sub(FT0, FT1, &env->fp_status);
1689
    RETURN();
1690
}
1691

    
1692
/* fmul - fmul. */
1693
PPC_OP(fmul)
1694
{
1695
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1696
    RETURN();
1697
}
1698

    
1699
/* fdiv - fdiv. */
1700
PPC_OP(fdiv)
1701
{
1702
    FT0 = float64_div(FT0, FT1, &env->fp_status);
1703
    RETURN();
1704
}
1705

    
1706
/* fsqrt - fsqrt. */
1707
PPC_OP(fsqrt)
1708
{
1709
    do_fsqrt();
1710
    RETURN();
1711
}
1712

    
1713
/* fres - fres. */
1714
PPC_OP(fres)
1715
{
1716
    do_fres();
1717
    RETURN();
1718
}
1719

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

    
1727
/* fsel - fsel. */
1728
PPC_OP(fsel)
1729
{
1730
    do_fsel();
1731
    RETURN();
1732
}
1733

    
1734
/***                     Floating-Point multiply-and-add                   ***/
1735
/* fmadd - fmadd. */
1736
PPC_OP(fmadd)
1737
{
1738
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1739
    FT0 = float64_add(FT0, FT2, &env->fp_status);
1740
    RETURN();
1741
}
1742

    
1743
/* fmsub - fmsub. */
1744
PPC_OP(fmsub)
1745
{
1746
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1747
    FT0 = float64_sub(FT0, FT2, &env->fp_status);
1748
    RETURN();
1749
}
1750

    
1751
/* fnmadd - fnmadd. - fnmadds - fnmadds. */
1752
PPC_OP(fnmadd)
1753
{
1754
    do_fnmadd();
1755
    RETURN();
1756
}
1757

    
1758
/* fnmsub - fnmsub. */
1759
PPC_OP(fnmsub)
1760
{
1761
    do_fnmsub();
1762
    RETURN();
1763
}
1764

    
1765
/***                     Floating-Point round & convert                    ***/
1766
/* frsp - frsp. */
1767
PPC_OP(frsp)
1768
{
1769
    FT0 = float64_to_float32(FT0, &env->fp_status);
1770
    RETURN();
1771
}
1772

    
1773
/* fctiw - fctiw. */
1774
PPC_OP(fctiw)
1775
{
1776
    do_fctiw();
1777
    RETURN();
1778
}
1779

    
1780
/* fctiwz - fctiwz. */
1781
PPC_OP(fctiwz)
1782
{
1783
    do_fctiwz();
1784
    RETURN();
1785
}
1786

    
1787
/***                         Floating-Point compare                        ***/
1788
/* fcmpu */
1789
PPC_OP(fcmpu)
1790
{
1791
    do_fcmpu();
1792
    RETURN();
1793
}
1794

    
1795
/* fcmpo */
1796
PPC_OP(fcmpo)
1797
{
1798
    do_fcmpo();
1799
    RETURN();
1800
}
1801

    
1802
/***                         Floating-point move                           ***/
1803
/* fabs */
1804
PPC_OP(fabs)
1805
{
1806
    FT0 = float64_abs(FT0);
1807
    RETURN();
1808
}
1809

    
1810
/* fnabs */
1811
PPC_OP(fnabs)
1812
{
1813
    FT0 = float64_abs(FT0);
1814
    FT0 = float64_chs(FT0);
1815
    RETURN();
1816
}
1817

    
1818
/* fneg */
1819
PPC_OP(fneg)
1820
{
1821
    FT0 = float64_chs(FT0);
1822
    RETURN();
1823
}
1824

    
1825
/* Load and store */
1826
#define MEMSUFFIX _raw
1827
#include "op_helper.h"
1828
#include "op_mem.h"
1829
#if !defined(CONFIG_USER_ONLY)
1830
#define MEMSUFFIX _user
1831
#include "op_helper.h"
1832
#include "op_mem.h"
1833
#define MEMSUFFIX _kernel
1834
#include "op_helper.h"
1835
#include "op_mem.h"
1836
#endif
1837

    
1838
/* Special op to check and maybe clear reservation */
1839
void OPPROTO op_check_reservation (void)
1840
{
1841
    if ((uint32_t)env->reserve == (uint32_t)(T0 & ~0x00000003))
1842
        env->reserve = -1;
1843
    RETURN();
1844
}
1845

    
1846
#if defined(TARGET_PPC64)
1847
void OPPROTO op_check_reservation_64 (void)
1848
{
1849
    if ((uint64_t)env->reserve == (uint64_t)(T0 & ~0x00000003))
1850
        env->reserve = -1;
1851
    RETURN();
1852
}
1853
#endif
1854

    
1855
/* Return from interrupt */
1856
#if !defined(CONFIG_USER_ONLY)
1857
void OPPROTO op_rfi (void)
1858
{
1859
    do_rfi();
1860
    RETURN();
1861
}
1862

    
1863
#if defined(TARGET_PPC64)
1864
void OPPROTO op_rfi_32 (void)
1865
{
1866
    do_rfi_32();
1867
    RETURN();
1868
}
1869
#endif
1870
#endif
1871

    
1872
/* Trap word */
1873
void OPPROTO op_tw (void)
1874
{
1875
    do_tw(PARAM1);
1876
    RETURN();
1877
}
1878

    
1879
#if defined(TARGET_PPC64)
1880
void OPPROTO op_td (void)
1881
{
1882
    do_td(PARAM1);
1883
    RETURN();
1884
}
1885
#endif
1886

    
1887
/* Instruction cache block invalidate */
1888
void OPPROTO op_icbi (void)
1889
{
1890
    do_icbi();
1891
    RETURN();
1892
}
1893

    
1894
#if defined(TARGET_PPC64)
1895
void OPPROTO op_icbi_64 (void)
1896
{
1897
    do_icbi_64();
1898
    RETURN();
1899
}
1900
#endif
1901

    
1902
#if !defined(CONFIG_USER_ONLY)
1903
/* tlbia */
1904
PPC_OP(tlbia)
1905
{
1906
    do_tlbia();
1907
    RETURN();
1908
}
1909

    
1910
/* tlbie */
1911
void OPPROTO op_tlbie (void)
1912
{
1913
    do_tlbie();
1914
    RETURN();
1915
}
1916

    
1917
#if defined(TARGET_PPC64)
1918
void OPPROTO op_tlbie_64 (void)
1919
{
1920
    do_tlbie_64();
1921
    RETURN();
1922
}
1923
#endif
1924

    
1925
#if defined(TARGET_PPC64)
1926
void OPPROTO op_slbia (void)
1927
{
1928
    do_slbia();
1929
    RETURN();
1930
}
1931

    
1932
void OPPROTO op_slbie (void)
1933
{
1934
    do_slbie();
1935
    RETURN();
1936
}
1937
#endif
1938
#endif
1939

    
1940
/* PowerPC 602/603/755 software TLB load instructions */
1941
#if !defined(CONFIG_USER_ONLY)
1942
void OPPROTO op_6xx_tlbld (void)
1943
{
1944
    do_load_6xx_tlb(0);
1945
    RETURN();
1946
}
1947

    
1948
void OPPROTO op_6xx_tlbli (void)
1949
{
1950
    do_load_6xx_tlb(1);
1951
    RETURN();
1952
}
1953
#endif
1954

    
1955
/* 601 specific */
1956
void OPPROTO op_load_601_rtcl (void)
1957
{
1958
    T0 = cpu_ppc601_load_rtcl(env);
1959
    RETURN();
1960
}
1961

    
1962
void OPPROTO op_load_601_rtcu (void)
1963
{
1964
    T0 = cpu_ppc601_load_rtcu(env);
1965
    RETURN();
1966
}
1967

    
1968
#if !defined(CONFIG_USER_ONLY)
1969
void OPPROTO op_store_601_rtcl (void)
1970
{
1971
    cpu_ppc601_store_rtcl(env, T0);
1972
    RETURN();
1973
}
1974

    
1975
void OPPROTO op_store_601_rtcu (void)
1976
{
1977
    cpu_ppc601_store_rtcu(env, T0);
1978
    RETURN();
1979
}
1980

    
1981
void OPPROTO op_load_601_bat (void)
1982
{
1983
    T0 = env->IBAT[PARAM1][PARAM2];
1984
    RETURN();
1985
}
1986
#endif /* !defined(CONFIG_USER_ONLY) */
1987

    
1988
/* 601 unified BATs store.
1989
 * To avoid using specific MMU code for 601, we store BATs in
1990
 * IBAT and DBAT simultaneously, then emulate unified BATs.
1991
 */
1992
#if !defined(CONFIG_USER_ONLY)
1993
void OPPROTO op_store_601_batl (void)
1994
{
1995
    int nr = PARAM1;
1996

    
1997
    env->IBAT[1][nr] = T0;
1998
    env->DBAT[1][nr] = T0;
1999
    RETURN();
2000
}
2001

    
2002
void OPPROTO op_store_601_batu (void)
2003
{
2004
    do_store_601_batu(PARAM1);
2005
    RETURN();
2006
}
2007
#endif /* !defined(CONFIG_USER_ONLY) */
2008

    
2009
/* PowerPC 601 specific instructions (POWER bridge) */
2010
/* XXX: those micro-ops need tests ! */
2011
void OPPROTO op_POWER_abs (void)
2012
{
2013
    if (T0 == INT32_MIN)
2014
        T0 = INT32_MAX;
2015
    else if (T0 < 0)
2016
        T0 = -T0;
2017
    RETURN();
2018
}
2019

    
2020
void OPPROTO op_POWER_abso (void)
2021
{
2022
    do_POWER_abso();
2023
    RETURN();
2024
}
2025

    
2026
void OPPROTO op_POWER_clcs (void)
2027
{
2028
    do_POWER_clcs();
2029
    RETURN();
2030
}
2031

    
2032
void OPPROTO op_POWER_div (void)
2033
{
2034
    do_POWER_div();
2035
    RETURN();
2036
}
2037

    
2038
void OPPROTO op_POWER_divo (void)
2039
{
2040
    do_POWER_divo();
2041
    RETURN();
2042
}
2043

    
2044
void OPPROTO op_POWER_divs (void)
2045
{
2046
    do_POWER_divs();
2047
    RETURN();
2048
}
2049

    
2050
void OPPROTO op_POWER_divso (void)
2051
{
2052
    do_POWER_divso();
2053
    RETURN();
2054
}
2055

    
2056
void OPPROTO op_POWER_doz (void)
2057
{
2058
    if ((int32_t)T1 > (int32_t)T0)
2059
        T0 = T1 - T0;
2060
    else
2061
        T0 = 0;
2062
    RETURN();
2063
}
2064

    
2065
void OPPROTO op_POWER_dozo (void)
2066
{
2067
    do_POWER_dozo();
2068
    RETURN();
2069
}
2070

    
2071
void OPPROTO op_load_xer_cmp (void)
2072
{
2073
    T2 = xer_cmp;
2074
    RETURN();
2075
}
2076

    
2077
void OPPROTO op_POWER_maskg (void)
2078
{
2079
    do_POWER_maskg();
2080
    RETURN();
2081
}
2082

    
2083
void OPPROTO op_POWER_maskir (void)
2084
{
2085
    T0 = (T0 & ~T2) | (T1 & T2);
2086
    RETURN();
2087
}
2088

    
2089
void OPPROTO op_POWER_mul (void)
2090
{
2091
    uint64_t tmp;
2092

    
2093
    tmp = (uint64_t)T0 * (uint64_t)T1;
2094
    env->spr[SPR_MQ] = tmp >> 32;
2095
    T0 = tmp;
2096
    RETURN();
2097
}
2098

    
2099
void OPPROTO op_POWER_mulo (void)
2100
{
2101
    do_POWER_mulo();
2102
    RETURN();
2103
}
2104

    
2105
void OPPROTO op_POWER_nabs (void)
2106
{
2107
    if (T0 > 0)
2108
        T0 = -T0;
2109
    RETURN();
2110
}
2111

    
2112
void OPPROTO op_POWER_nabso (void)
2113
{
2114
    /* nabs never overflows */
2115
    if (T0 > 0)
2116
        T0 = -T0;
2117
    xer_ov = 0;
2118
    RETURN();
2119
}
2120

    
2121
/* XXX: factorise POWER rotates... */
2122
void OPPROTO op_POWER_rlmi (void)
2123
{
2124
    T0 = rotl32(T0, T2) & PARAM1;
2125
    T0 |= T1 & PARAM2;
2126
    RETURN();
2127
}
2128

    
2129
void OPPROTO op_POWER_rrib (void)
2130
{
2131
    T2 &= 0x1FUL;
2132
    T0 = rotl32(T0 & INT32_MIN, T2);
2133
    T0 |= T1 & ~rotl32(INT32_MIN, T2);
2134
    RETURN();
2135
}
2136

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

    
2145
void OPPROTO op_POWER_sleq (void)
2146
{
2147
    uint32_t tmp = env->spr[SPR_MQ];
2148

    
2149
    T1 &= 0x1FUL;
2150
    env->spr[SPR_MQ] = rotl32(T0, T1);
2151
    T0 = T0 << T1;
2152
    T0 |= tmp >> (32 - T1);
2153
    RETURN();
2154
}
2155

    
2156
void OPPROTO op_POWER_sllq (void)
2157
{
2158
    uint32_t msk = -1;
2159

    
2160
    msk = msk << (T1 & 0x1FUL);
2161
    if (T1 & 0x20UL)
2162
        msk = ~msk;
2163
    T1 &= 0x1FUL;
2164
    T0 = (T0 << T1) & msk;
2165
    T0 |= env->spr[SPR_MQ] & ~msk;
2166
    RETURN();
2167
}
2168

    
2169
void OPPROTO op_POWER_slq (void)
2170
{
2171
    uint32_t msk = -1, tmp;
2172

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

    
2183
void OPPROTO op_POWER_sraq (void)
2184
{
2185
    env->spr[SPR_MQ] = rotl32(T0, 32 - (T1 & 0x1FUL));
2186
    if (T1 & 0x20UL)
2187
        T0 = -1L;
2188
    else
2189
        T0 = (int32_t)T0 >> T1;
2190
    RETURN();
2191
}
2192

    
2193
void OPPROTO op_POWER_sre (void)
2194
{
2195
    T1 &= 0x1FUL;
2196
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2197
    T0 = (int32_t)T0 >> T1;
2198
    RETURN();
2199
}
2200

    
2201
void OPPROTO op_POWER_srea (void)
2202
{
2203
    T1 &= 0x1FUL;
2204
    env->spr[SPR_MQ] = T0 >> T1;
2205
    T0 = (int32_t)T0 >> T1;
2206
    RETURN();
2207
}
2208

    
2209
void OPPROTO op_POWER_sreq (void)
2210
{
2211
    uint32_t tmp;
2212
    int32_t msk;
2213

    
2214
    T1 &= 0x1FUL;
2215
    msk = INT32_MIN >> T1;
2216
    tmp = env->spr[SPR_MQ];
2217
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2218
    T0 = T0 >> T1;
2219
    T0 |= tmp & msk;
2220
    RETURN();
2221
}
2222

    
2223
void OPPROTO op_POWER_srlq (void)
2224
{
2225
    uint32_t tmp;
2226
    int32_t msk;
2227

    
2228
    msk = INT32_MIN >> (T1 & 0x1FUL);
2229
    if (T1 & 0x20UL)
2230
        msk = ~msk;
2231
    T1 &= 0x1FUL;
2232
    tmp = env->spr[SPR_MQ];
2233
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2234
    T0 = T0 >> T1;
2235
    T0 &= msk;
2236
    T0 |= tmp & ~msk;
2237
    RETURN();
2238
}
2239

    
2240
void OPPROTO op_POWER_srq (void)
2241
{
2242
    T1 &= 0x1FUL;
2243
    env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
2244
    T0 = T0 >> T1;
2245
    RETURN();
2246
}
2247

    
2248
/* POWER instructions not implemented in PowerPC 601 */
2249
#if !defined(CONFIG_USER_ONLY)
2250
void OPPROTO op_POWER_mfsri (void)
2251
{
2252
    T1 = T0 >> 28;
2253
    T0 = env->sr[T1];
2254
    RETURN();
2255
}
2256

    
2257
void OPPROTO op_POWER_rac (void)
2258
{
2259
    do_POWER_rac();
2260
    RETURN();
2261
}
2262

    
2263
void OPPROTO op_POWER_rfsvc (void)
2264
{
2265
    do_POWER_rfsvc();
2266
    RETURN();
2267
}
2268
#endif
2269

    
2270
/* PowerPC 602 specific instruction */
2271
#if !defined(CONFIG_USER_ONLY)
2272
void OPPROTO op_602_mfrom (void)
2273
{
2274
    do_op_602_mfrom();
2275
    RETURN();
2276
}
2277
#endif
2278

    
2279
/* PowerPC 4xx specific micro-ops */
2280
void OPPROTO op_405_add_T0_T2 (void)
2281
{
2282
    T0 = (int32_t)T0 + (int32_t)T2;
2283
    RETURN();
2284
}
2285

    
2286
void OPPROTO op_405_mulchw (void)
2287
{
2288
    T0 = ((int16_t)T0) * ((int16_t)(T1 >> 16));
2289
    RETURN();
2290
}
2291

    
2292
void OPPROTO op_405_mulchwu (void)
2293
{
2294
    T0 = ((uint16_t)T0) * ((uint16_t)(T1 >> 16));
2295
    RETURN();
2296
}
2297

    
2298
void OPPROTO op_405_mulhhw (void)
2299
{
2300
    T0 = ((int16_t)(T0 >> 16)) * ((int16_t)(T1 >> 16));
2301
    RETURN();
2302
}
2303

    
2304
void OPPROTO op_405_mulhhwu (void)
2305
{
2306
    T0 = ((uint16_t)(T0 >> 16)) * ((uint16_t)(T1 >> 16));
2307
    RETURN();
2308
}
2309

    
2310
void OPPROTO op_405_mullhw (void)
2311
{
2312
    T0 = ((int16_t)T0) * ((int16_t)T1);
2313
    RETURN();
2314
}
2315

    
2316
void OPPROTO op_405_mullhwu (void)
2317
{
2318
    T0 = ((uint16_t)T0) * ((uint16_t)T1);
2319
    RETURN();
2320
}
2321

    
2322
void OPPROTO op_405_check_ov (void)
2323
{
2324
    do_405_check_ov();
2325
    RETURN();
2326
}
2327

    
2328
void OPPROTO op_405_check_sat (void)
2329
{
2330
    do_405_check_sat();
2331
    RETURN();
2332
}
2333

    
2334
void OPPROTO op_405_check_ovu (void)
2335
{
2336
    if (likely(T0 >= T2)) {
2337
        xer_ov = 0;
2338
    } else {
2339
        xer_ov = 1;
2340
        xer_so = 1;
2341
    }
2342
    RETURN();
2343
}
2344

    
2345
void OPPROTO op_405_check_satu (void)
2346
{
2347
    if (unlikely(T0 < T2)) {
2348
        /* Saturate result */
2349
        T0 = -1;
2350
    }
2351
    RETURN();
2352
}
2353

    
2354
#if !defined(CONFIG_USER_ONLY)
2355
void OPPROTO op_4xx_load_dcr (void)
2356
{
2357
    do_4xx_load_dcr(PARAM1);
2358
    RETURN();
2359
}
2360

    
2361
void OPPROTO op_4xx_store_dcr (void)
2362
{
2363
    do_4xx_store_dcr(PARAM1);
2364
    RETURN();
2365
}
2366

    
2367
/* Return from critical interrupt :
2368
 * same as rfi, except nip & MSR are loaded from SRR2/3 instead of SRR0/1
2369
 */
2370
void OPPROTO op_4xx_rfci (void)
2371
{
2372
    do_4xx_rfci();
2373
    RETURN();
2374
}
2375

    
2376
void OPPROTO op_4xx_wrte (void)
2377
{
2378
    msr_ee = T0 >> 16;
2379
    RETURN();
2380
}
2381

    
2382
void OPPROTO op_4xx_tlbre_lo (void)
2383
{
2384
    do_4xx_tlbre_lo();
2385
    RETURN();
2386
}
2387

    
2388
void OPPROTO op_4xx_tlbre_hi (void)
2389
{
2390
    do_4xx_tlbre_hi();
2391
    RETURN();
2392
}
2393

    
2394
void OPPROTO op_4xx_tlbsx (void)
2395
{
2396
    do_4xx_tlbsx();
2397
    RETURN();
2398
}
2399

    
2400
void OPPROTO op_4xx_tlbsx_ (void)
2401
{
2402
    do_4xx_tlbsx_();
2403
    RETURN();
2404
}
2405

    
2406
void OPPROTO op_4xx_tlbwe_lo (void)
2407
{
2408
    do_4xx_tlbwe_lo();
2409
    RETURN();
2410
}
2411

    
2412
void OPPROTO op_4xx_tlbwe_hi (void)
2413
{
2414
    do_4xx_tlbwe_hi();
2415
    RETURN();
2416
}
2417
#endif
2418

    
2419
/* SPR micro-ops */
2420
/* 440 specific */
2421
void OPPROTO op_440_dlmzb (void)
2422
{
2423
    do_440_dlmzb();
2424
    RETURN();
2425
}
2426

    
2427
void OPPROTO op_440_dlmzb_update_Rc (void)
2428
{
2429
    if (T0 == 8)
2430
        T0 = 0x2;
2431
    else if (T0 < 4)
2432
        T0 = 0x4;
2433
    else
2434
        T0 = 0x8;
2435
    RETURN();
2436
}
2437

    
2438
#if !defined(CONFIG_USER_ONLY)
2439
void OPPROTO op_store_pir (void)
2440
{
2441
    env->spr[SPR_PIR] = T0 & 0x0000000FUL;
2442
    RETURN();
2443
}
2444

    
2445
void OPPROTO op_load_403_pb (void)
2446
{
2447
    do_load_403_pb(PARAM1);
2448
    RETURN();
2449
}
2450

    
2451
void OPPROTO op_store_403_pb (void)
2452
{
2453
    do_store_403_pb(PARAM1);
2454
    RETURN();
2455
}
2456

    
2457
void OPPROTO op_load_40x_pit (void)
2458
{
2459
    T0 = load_40x_pit(env);
2460
    RETURN();
2461
}
2462

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

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

    
2475
void OPPROTO op_store_booke_tsr (void)
2476
{
2477
    store_booke_tsr(env, T0);
2478
    RETURN();
2479
}
2480
#endif /* !defined(CONFIG_USER_ONLY) */