Statistics
| Branch: | Revision:

root / target-ppc / op.c @ 89934337

History | View | Annotate | Download (19.5 kB)

1
/*
2
 *  PPC emulation micro-operations for qemu.
3
 * 
4
 *  Copyright (c) 2003 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

    
26
#define regs (env)
27
#define Ts0 (int32_t)T0
28
#define Ts1 (int32_t)T1
29
#define Ts2 (int32_t)T2
30

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

    
35
#define PPC_OP(name) void 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
/* PPC state maintenance operations */
134
/* set_Rc0 */
135
PPC_OP(set_Rc0)
136
{
137
    uint32_t tmp;
138

    
139
    if (Ts0 < 0) {
140
        tmp = 0x08;
141
    } else if (Ts0 > 0) {
142
        tmp = 0x04;
143
    } else {
144
        tmp = 0x02;
145
    }
146
    tmp |= xer_ov;
147
    env->crf[0] = tmp;
148
    RETURN();
149
}
150

    
151
/* reset_Rc0 */
152
PPC_OP(reset_Rc0)
153
{
154
    env->crf[0] = 0x02 | xer_ov;
155
    RETURN();
156
}
157

    
158
/* set_Rc0_1 */
159
PPC_OP(set_Rc0_1)
160
{
161
    env->crf[0] = 0x04 | xer_ov;
162
    RETURN();
163
}
164

    
165
/* Set Rc1 (for floating point arithmetic) */
166
PPC_OP(set_Rc1)
167
{
168
    env->crf[1] = regs->fpscr[7];
169
    RETURN();
170
}
171

    
172
/* Constants load */
173
PPC_OP(set_T0)
174
{
175
    T0 = PARAM(1);
176
    RETURN();
177
}
178

    
179
PPC_OP(set_T1)
180
{
181
    T1 = PARAM(1);
182
    RETURN();
183
}
184

    
185
PPC_OP(set_T2)
186
{
187
    T2 = PARAM(1);
188
    RETURN();
189
}
190

    
191
/* Generate exceptions */
192
PPC_OP(raise_exception_err)
193
{
194
    do_raise_exception_err(PARAM(1), PARAM(2));
195
}
196

    
197
PPC_OP(raise_exception)
198
{
199
    do_raise_exception(PARAM(1));
200
}
201

    
202
PPC_OP(update_nip)
203
{
204
    env->nip = PARAM(1);
205
}
206

    
207
PPC_OP(debug)
208
{
209
    env->nip = PARAM(1);
210
#if defined (DEBUG_OP)
211
    dump_state();
212
#endif
213
    do_raise_exception(EXCP_DEBUG);
214
    RETURN();
215
}
216

    
217
/* Segment registers load and store with immediate index */
218
PPC_OP(load_srin)
219
{
220
    T0 = regs->sr[T1 >> 28];
221
    RETURN();
222
}
223

    
224
PPC_OP(store_srin)
225
{
226
    do_store_sr(T1 >> 28);
227
    RETURN();
228
}
229

    
230
PPC_OP(load_sdr1)
231
{
232
    T0 = regs->sdr1;
233
    RETURN();
234
}
235

    
236
PPC_OP(store_sdr1)
237
{
238
    regs->sdr1 = T0;
239
    RETURN();
240
}
241

    
242
PPC_OP(exit_tb)
243
{
244
    EXIT_TB();
245
}
246

    
247
/* Load/store special registers */
248
PPC_OP(load_cr)
249
{
250
    do_load_cr();
251
    RETURN();
252
}
253

    
254
PPC_OP(store_cr)
255
{
256
    do_store_cr(PARAM(1));
257
    RETURN();
258
}
259

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

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

    
274
PPC_OP(load_xer_bc)
275
{
276
    T1 = xer_bc;
277
    RETURN();
278
}
279

    
280
PPC_OP(load_xer)
281
{
282
    do_load_xer();
283
    RETURN();
284
}
285

    
286
PPC_OP(store_xer)
287
{
288
    do_store_xer();
289
    RETURN();
290
}
291

    
292
PPC_OP(load_msr)
293
{
294
    do_load_msr();
295
    RETURN();
296
}
297

    
298
PPC_OP(store_msr)
299
{
300
    do_store_msr();
301
    RETURN();
302
}
303

    
304
/* SPR */
305
PPC_OP(load_spr)
306
{
307
    T0 = regs->spr[PARAM(1)];
308
    RETURN();
309
}
310

    
311
PPC_OP(store_spr)
312
{
313
    regs->spr[PARAM(1)] = T0;
314
    RETURN();
315
}
316

    
317
PPC_OP(load_lr)
318
{
319
    T0 = regs->lr;
320
    RETURN();
321
}
322

    
323
PPC_OP(store_lr)
324
{
325
    regs->lr = T0;
326
    RETURN();
327
}
328

    
329
PPC_OP(load_ctr)
330
{
331
    T0 = regs->ctr;
332
    RETURN();
333
}
334

    
335
PPC_OP(store_ctr)
336
{
337
    regs->ctr = T0;
338
    RETURN();
339
}
340

    
341
PPC_OP(load_tbl)
342
{
343
    T0 = cpu_ppc_load_tbl(regs);
344
    RETURN();
345
}
346

    
347
PPC_OP(load_tbu)
348
{
349
    T0 = cpu_ppc_load_tbu(regs);
350
    RETURN();
351
}
352

    
353
PPC_OP(store_tbl)
354
{
355
    cpu_ppc_store_tbl(regs, T0);
356
    RETURN();
357
}
358

    
359
PPC_OP(store_tbu)
360
{
361
    cpu_ppc_store_tbu(regs, T0);
362
    RETURN();
363
}
364

    
365
PPC_OP(load_decr)
366
{
367
    T0 = cpu_ppc_load_decr(regs);
368
    }
369

    
370
PPC_OP(store_decr)
371
{
372
    cpu_ppc_store_decr(regs, T0);
373
    RETURN();
374
}
375

    
376
PPC_OP(load_ibat)
377
{
378
    T0 = regs->IBAT[PARAM(1)][PARAM(2)];
379
}
380

    
381
PPC_OP(store_ibat)
382
{
383
    do_store_ibat(PARAM(1), PARAM(2));
384
}
385

    
386
PPC_OP(load_dbat)
387
{
388
    T0 = regs->DBAT[PARAM(1)][PARAM(2)];
389
}
390

    
391
PPC_OP(store_dbat)
392
{
393
    do_store_dbat(PARAM(1), PARAM(2));
394
}
395

    
396
/* FPSCR */
397
PPC_OP(load_fpscr)
398
{
399
    do_load_fpscr();
400
    RETURN();
401
}
402

    
403
PPC_OP(store_fpscr)
404
{
405
    do_store_fpscr(PARAM(1));
406
    RETURN();
407
}
408

    
409
PPC_OP(reset_scrfx)
410
{
411
    regs->fpscr[7] &= ~0x8;
412
    RETURN();
413
}
414

    
415
/* crf operations */
416
PPC_OP(getbit_T0)
417
{
418
    T0 = (T0 >> PARAM(1)) & 1;
419
    RETURN();
420
}
421

    
422
PPC_OP(getbit_T1)
423
{
424
    T1 = (T1 >> PARAM(1)) & 1;
425
    RETURN();
426
}
427

    
428
PPC_OP(setcrfbit)
429
{
430
    T1 = (T1 & PARAM(1)) | (T0 << PARAM(2)); 
431
    RETURN();
432
}
433

    
434
/* Branch */
435
#define EIP regs->nip
436

    
437
PPC_OP(setlr)
438
{
439
    regs->lr = PARAM1;
440
}
441

    
442
PPC_OP(b)
443
{
444
    JUMP_TB(b1, PARAM1, 0, PARAM2);
445
}
446

    
447
PPC_OP(b_T1)
448
{
449
    regs->nip = T1 & ~3;
450
}
451

    
452
PPC_OP(btest) 
453
{
454
    if (T0) {
455
        JUMP_TB(btest, PARAM1, 0, PARAM2);
456
    } else {
457
        JUMP_TB(btest, PARAM1, 1, PARAM3);
458
    }
459
    RETURN();
460
}
461

    
462
PPC_OP(btest_T1) 
463
{
464
    if (T0) {
465
        regs->nip = T1 & ~3;
466
    } else {
467
        regs->nip = PARAM1;
468
    }
469
    RETURN();
470
}
471

    
472
PPC_OP(movl_T1_ctr)
473
{
474
    T1 = regs->ctr;
475
}
476

    
477
PPC_OP(movl_T1_lr)
478
{
479
    T1 = regs->lr;
480
}
481

    
482
/* tests with result in T0 */
483

    
484
PPC_OP(test_ctr)
485
{
486
    T0 = regs->ctr;
487
}
488

    
489
PPC_OP(test_ctr_true)
490
{
491
    T0 = (regs->ctr != 0 && (T0 & PARAM(1)) != 0);
492
}
493

    
494
PPC_OP(test_ctr_false)
495
{
496
    T0 = (regs->ctr != 0 && (T0 & PARAM(1)) == 0);
497
}
498

    
499
PPC_OP(test_ctrz)
500
{
501
    T0 = (regs->ctr == 0);
502
}
503

    
504
PPC_OP(test_ctrz_true)
505
{
506
    T0 = (regs->ctr == 0 && (T0 & PARAM(1)) != 0);
507
}
508

    
509
PPC_OP(test_ctrz_false)
510
{
511
    T0 = (regs->ctr == 0 && (T0 & PARAM(1)) == 0);
512
}
513

    
514
PPC_OP(test_true)
515
{
516
    T0 = (T0 & PARAM(1));
517
}
518

    
519
PPC_OP(test_false)
520
{
521
    T0 = ((T0 & PARAM(1)) == 0);
522
}
523

    
524
/* CTR maintenance */
525
PPC_OP(dec_ctr)
526
{
527
    regs->ctr--;
528
    RETURN();
529
}
530

    
531
/***                           Integer arithmetic                          ***/
532
/* add */
533
PPC_OP(add)
534
{
535
    T0 += T1;
536
    RETURN();
537
}
538

    
539
PPC_OP(addo)
540
{
541
    T2 = T0;
542
    T0 += T1;
543
    if ((T2 ^ T1 ^ (-1)) & (T2 ^ T0) & (1 << 31)) {
544
        xer_so = 1;
545
        xer_ov = 1;
546
    } else {
547
        xer_ov = 0;
548
    }
549
    RETURN();
550
}
551

    
552
/* add carrying */
553
PPC_OP(addc)
554
{
555
    T2 = T0;
556
    T0 += T1;
557
    if (T0 < T2) {
558
        xer_ca = 1;
559
    } else {
560
        xer_ca = 0;
561
    }
562
    RETURN();
563
}
564

    
565
PPC_OP(addco)
566
{
567
    T2 = T0;
568
    T0 += T1;
569
    if (T0 < T2) {
570
        xer_ca = 1;
571
    } else {
572
        xer_ca = 0;
573
    }
574
    if ((T2 ^ T1 ^ (-1)) & (T2 ^ T0) & (1 << 31)) {
575
        xer_so = 1;
576
        xer_ov = 1;
577
    } else {
578
        xer_ov = 0;
579
    }
580
    RETURN();
581
}
582

    
583
/* add extended */
584
/* candidate for helper (too long) */
585
PPC_OP(adde)
586
{
587
    T2 = T0;
588
    T0 += T1 + xer_ca;
589
    if (T0 < T2 || (xer_ca == 1 && T0 == T2)) {
590
        xer_ca = 1;
591
    } else {
592
        xer_ca = 0;
593
    }
594
    RETURN();
595
}
596

    
597
PPC_OP(addeo)
598
{
599
    T2 = T0;
600
    T0 += T1 + xer_ca;
601
    if (T0 < T2 || (xer_ca == 1 && T0 == T2)) {
602
        xer_ca = 1;
603
    } else {
604
        xer_ca = 0;
605
    }
606
    if ((T2 ^ T1 ^ (-1)) & (T2 ^ T0) & (1 << 31)) {
607
        xer_so = 1;
608
        xer_ov = 1;
609
    } else {
610
        xer_ov = 0;
611
    }
612
    RETURN();
613
}
614

    
615
/* add immediate */
616
PPC_OP(addi)
617
{
618
    T0 += PARAM(1);
619
    RETURN();
620
}
621

    
622
/* add immediate carrying */
623
PPC_OP(addic)
624
{
625
    T1 = T0;
626
    T0 += PARAM(1);
627
    if (T0 < T1) {
628
        xer_ca = 1;
629
    } else {
630
        xer_ca = 0;
631
    }
632
    RETURN();
633
}
634

    
635
/* add to minus one extended */
636
PPC_OP(addme)
637
{
638
    T1 = T0;
639
    T0 += xer_ca + (-1);
640
    if (T1 != 0)
641
        xer_ca = 1;
642
    RETURN();
643
}
644

    
645
PPC_OP(addmeo)
646
{
647
    T1 = T0;
648
    T0 += xer_ca + (-1);
649
    if (T1 & (T1 ^ T0) & (1 << 31)) {
650
        xer_so = 1;
651
        xer_ov = 1;
652
    } else {
653
        xer_ov = 0;
654
    }
655
    if (T1 != 0)
656
        xer_ca = 1;
657
    RETURN();
658
}
659

    
660
/* add to zero extended */
661
PPC_OP(addze)
662
{
663
    T1 = T0;
664
    T0 += xer_ca;
665
    if (T0 < T1) {
666
        xer_ca = 1;
667
    } else {
668
        xer_ca = 0;
669
    }
670
    RETURN();
671
}
672

    
673
PPC_OP(addzeo)
674
{
675
    T1 = T0;
676
    T0 += xer_ca;
677
    if ((T1 ^ (-1)) & (T1 ^ T0) & (1 << 31)) {
678
        xer_so = 1;
679
        xer_ov = 1;
680
    } else {
681
        xer_ov = 0;
682
    }
683
    if (T0 < T1) {
684
        xer_ca = 1;
685
    } else {
686
        xer_ca = 0;
687
    }
688
    RETURN();
689
}
690

    
691
/* divide word */
692
/* candidate for helper (too long) */
693
PPC_OP(divw)
694
{
695
    if ((Ts0 == INT32_MIN && Ts1 == -1) || Ts1 == 0) {
696
        T0 = (int32_t)((-1) * (T0 >> 31));
697
    } else {
698
        T0 = (Ts0 / Ts1);
699
    }
700
    RETURN();
701
}
702

    
703
PPC_OP(divwo)
704
{
705
    if ((Ts0 == INT32_MIN && Ts1 == -1) || Ts1 == 0) {
706
        xer_so = 1;
707
        xer_ov = 1;
708
        T0 = (-1) * (T0 >> 31);
709
    } else {
710
        xer_ov = 0;
711
        T0 = (Ts0 / Ts1);
712
    }
713
    RETURN();
714
}
715

    
716
/* divide word unsigned */
717
PPC_OP(divwu)
718
{
719
    if (T1 == 0) {
720
        T0 = 0;
721
    } else {
722
        T0 /= T1;
723
    }
724
    RETURN();
725
}
726

    
727
PPC_OP(divwuo)
728
{
729
    if (T1 == 0) {
730
        xer_so = 1;
731
        xer_ov = 1;
732
        T0 = 0;
733
    } else {
734
        xer_ov = 0;
735
        T0 /= T1;
736
    }
737
    RETURN();
738
}
739

    
740
/* multiply high word */
741
PPC_OP(mulhw)
742
{
743
    T0 = ((int64_t)Ts0 * (int64_t)Ts1) >> 32;
744
    RETURN();
745
}
746

    
747
/* multiply high word unsigned */
748
PPC_OP(mulhwu)
749
{
750
    T0 = ((uint64_t)T0 * (uint64_t)T1) >> 32;
751
    RETURN();
752
}
753

    
754
/* multiply low immediate */
755
PPC_OP(mulli)
756
{
757
    T0 = (Ts0 * SPARAM(1));
758
    RETURN();
759
}
760

    
761
/* multiply low word */
762
PPC_OP(mullw)
763
{
764
    T0 *= T1;
765
    RETURN();
766
}
767

    
768
PPC_OP(mullwo)
769
{
770
    int64_t res = (int64_t)Ts0 * (int64_t)Ts1;
771

    
772
    if ((int32_t)res != res) {
773
        xer_ov = 1;
774
        xer_so = 1;
775
    } else {
776
        xer_ov = 0;
777
    }
778
    T0 = (int32_t)res;
779
    RETURN();
780
}
781

    
782
/* negate */
783
PPC_OP(neg)
784
{
785
    if (T0 != 0x80000000) {
786
        T0 = -Ts0;
787
    }
788
    RETURN();
789
}
790

    
791
PPC_OP(nego)
792
{
793
    if (T0 == 0x80000000) {
794
        xer_ov = 1;
795
        xer_so = 1;
796
    } else {
797
        xer_ov = 0;
798
        T0 = -Ts0;
799
    }
800
    RETURN();
801
}
802

    
803
/* substract from */
804
PPC_OP(subf)
805
{
806
    T0 = T1 - T0;
807
    RETURN();
808
}
809

    
810
PPC_OP(subfo)
811
{
812
    T2 = T0;
813
    T0 = T1 - T0;
814
    if (((~T2) ^ T1 ^ (-1)) & ((~T2) ^ T0) & (1 << 31)) {
815
        xer_so = 1;
816
        xer_ov = 1;
817
    } else {
818
        xer_ov = 0;
819
    }
820
    RETURN();
821
}
822

    
823
/* substract from carrying */
824
PPC_OP(subfc)
825
{
826
    T0 = T1 - T0;
827
    if (T0 <= T1) {
828
        xer_ca = 1;
829
    } else {
830
        xer_ca = 0;
831
    }
832
    RETURN();
833
}
834

    
835
PPC_OP(subfco)
836
{
837
    T2 = T0;
838
    T0 = T1 - T0;
839
    if (T0 <= T1) {
840
        xer_ca = 1;
841
    } else {
842
        xer_ca = 0;
843
    }
844
    if (((~T2) ^ T1 ^ (-1)) & ((~T2) ^ T0) & (1 << 31)) {
845
        xer_so = 1;
846
        xer_ov = 1;
847
    } else {
848
        xer_ov = 0;
849
    }
850
    RETURN();
851
}
852

    
853
/* substract from extended */
854
/* candidate for helper (too long) */
855
PPC_OP(subfe)
856
{
857
    T0 = T1 + ~T0 + xer_ca;
858
    if (T0 < T1 || (xer_ca == 1 && T0 == T1)) {
859
        xer_ca = 1;
860
    } else {
861
        xer_ca = 0;
862
    }
863
    RETURN();
864
}
865

    
866
PPC_OP(subfeo)
867
{
868
    T2 = T0;
869
    T0 = T1 + ~T0 + xer_ca;
870
    if ((~T2 ^ T1 ^ (-1)) & (~T2 ^ T0) & (1 << 31)) {
871
        xer_so = 1;
872
        xer_ov = 1;
873
    } else {
874
        xer_ov = 0;
875
    }
876
    if (T0 < T1 || (xer_ca == 1 && T0 == T1)) {
877
        xer_ca = 1;
878
    } else {
879
        xer_ca = 0;
880
    }
881
    RETURN();
882
}
883

    
884
/* substract from immediate carrying */
885
PPC_OP(subfic)
886
{
887
    T0 = PARAM(1) + ~T0 + 1;
888
    if (T0 <= PARAM(1)) {
889
        xer_ca = 1;
890
    } else {
891
        xer_ca = 0;
892
    }
893
    RETURN();
894
}
895

    
896
/* substract from minus one extended */
897
PPC_OP(subfme)
898
{
899
    T0 = ~T0 + xer_ca - 1;
900

    
901
    if (T0 != -1)
902
        xer_ca = 1;
903
    RETURN();
904
}
905

    
906
PPC_OP(subfmeo)
907
{
908
    T1 = T0;
909
    T0 = ~T0 + xer_ca - 1;
910
    if (~T1 & (~T1 ^ T0) & (1 << 31)) {
911
        xer_so = 1;
912
        xer_ov = 1;
913
    } else {
914
        xer_ov = 0;
915
    }
916
    if (T1 != -1)
917
        xer_ca = 1;
918
    RETURN();
919
}
920

    
921
/* substract from zero extended */
922
PPC_OP(subfze)
923
{
924
    T1 = ~T0;
925
    T0 = T1 + xer_ca;
926
    if (T0 < T1) {
927
        xer_ca = 1;
928
    } else {
929
        xer_ca = 0;
930
    }
931
    RETURN();
932
}
933

    
934
PPC_OP(subfzeo)
935
{
936
    T1 = T0;
937
    T0 = ~T0 + xer_ca;
938
    if ((~T1 ^ (-1)) & ((~T1) ^ T0) & (1 << 31)) {
939
        xer_ov = 1;
940
        xer_so = 1;
941
    } else {
942
        xer_ov = 0;
943
    }
944
    if (T0 < ~T1) {
945
        xer_ca = 1;
946
    } else {
947
        xer_ca = 0;
948
    }
949
    RETURN();
950
}
951

    
952
/***                           Integer comparison                          ***/
953
/* compare */
954
PPC_OP(cmp)
955
{
956
    if (Ts0 < Ts1) {
957
        T0 = 0x08;
958
    } else if (Ts0 > Ts1) {
959
        T0 = 0x04;
960
    } else {
961
        T0 = 0x02;
962
    }
963
    RETURN();
964
}
965

    
966
/* compare immediate */
967
PPC_OP(cmpi)
968
{
969
    if (Ts0 < SPARAM(1)) {
970
        T0 = 0x08;
971
    } else if (Ts0 > SPARAM(1)) {
972
        T0 = 0x04;
973
    } else {
974
        T0 = 0x02;
975
    }
976
    RETURN();
977
}
978

    
979
/* compare logical */
980
PPC_OP(cmpl)
981
{
982
    if (T0 < T1) {
983
        T0 = 0x08;
984
    } else if (T0 > T1) {
985
        T0 = 0x04;
986
    } else {
987
        T0 = 0x02;
988
    }
989
    RETURN();
990
}
991

    
992
/* compare logical immediate */
993
PPC_OP(cmpli)
994
{
995
    if (T0 < PARAM(1)) {
996
        T0 = 0x08;
997
    } else if (T0 > PARAM(1)) {
998
        T0 = 0x04;
999
    } else {
1000
        T0 = 0x02;
1001
    }
1002
    RETURN();
1003
}
1004

    
1005
/***                            Integer logical                            ***/
1006
/* and */
1007
PPC_OP(and)
1008
{
1009
    T0 &= T1;
1010
    RETURN();
1011
}
1012

    
1013
/* andc */
1014
PPC_OP(andc)
1015
{
1016
    T0 &= ~T1;
1017
    RETURN();
1018
}
1019

    
1020
/* andi. */
1021
PPC_OP(andi_)
1022
{
1023
    T0 &= PARAM(1);
1024
    RETURN();
1025
}
1026

    
1027
/* count leading zero */
1028
PPC_OP(cntlzw)
1029
{
1030
    T1 = T0;
1031
    for (T0 = 32; T1 > 0; T0--)
1032
        T1 = T1 >> 1;
1033
    RETURN();
1034
}
1035

    
1036
/* eqv */
1037
PPC_OP(eqv)
1038
{
1039
    T0 = ~(T0 ^ T1);
1040
    RETURN();
1041
}
1042

    
1043
/* extend sign byte */
1044
PPC_OP(extsb)
1045
{
1046
    T0 = (int32_t)((int8_t)(Ts0));
1047
    RETURN();
1048
}
1049

    
1050
/* extend sign half word */
1051
PPC_OP(extsh)
1052
{
1053
    T0 = (int32_t)((int16_t)(Ts0));
1054
    RETURN();
1055
}
1056

    
1057
/* nand */
1058
PPC_OP(nand)
1059
{
1060
    T0 = ~(T0 & T1);
1061
    RETURN();
1062
}
1063

    
1064
/* nor */
1065
PPC_OP(nor)
1066
{
1067
    T0 = ~(T0 | T1);
1068
    RETURN();
1069
}
1070

    
1071
/* or */
1072
PPC_OP(or)
1073
{
1074
    T0 |= T1;
1075
    RETURN();
1076
}
1077

    
1078
/* orc */
1079
PPC_OP(orc)
1080
{
1081
    T0 |= ~T1;
1082
    RETURN();
1083
}
1084

    
1085
/* ori */
1086
PPC_OP(ori)
1087
{
1088
    T0 |= PARAM(1);
1089
    RETURN();
1090
}
1091

    
1092
/* xor */
1093
PPC_OP(xor)
1094
{
1095
    T0 ^= T1;
1096
    RETURN();
1097
}
1098

    
1099
/* xori */
1100
PPC_OP(xori)
1101
{
1102
    T0 ^= PARAM(1);
1103
    RETURN();
1104
}
1105

    
1106
/***                             Integer rotate                            ***/
1107
/* rotate left word immediate then mask insert */
1108
PPC_OP(rlwimi)
1109
{
1110
    T0 = (rotl(T0, PARAM(1)) & PARAM(2)) | (T1 & PARAM(3));
1111
    RETURN();
1112
}
1113

    
1114
/* rotate left immediate then and with mask insert */
1115
PPC_OP(rotlwi)
1116
{
1117
    T0 = rotl(T0, PARAM(1));
1118
    RETURN();
1119
}
1120

    
1121
PPC_OP(slwi)
1122
{
1123
    T0 = T0 << PARAM(1);
1124
    RETURN();
1125
}
1126

    
1127
PPC_OP(srwi)
1128
{
1129
    T0 = T0 >> PARAM(1);
1130
    RETURN();
1131
}
1132

    
1133
/* rotate left word then and with mask insert */
1134
PPC_OP(rlwinm)
1135
{
1136
    T0 = rotl(T0, PARAM(1)) & PARAM(2);
1137
    RETURN();
1138
}
1139

    
1140
PPC_OP(rotl)
1141
{
1142
    T0 = rotl(T0, T1);
1143
    RETURN();
1144
}
1145

    
1146
PPC_OP(rlwnm)
1147
{
1148
    T0 = rotl(T0, T1) & PARAM(1);
1149
    RETURN();
1150
}
1151

    
1152
/***                             Integer shift                             ***/
1153
/* shift left word */
1154
PPC_OP(slw)
1155
{
1156
    if (T1 & 0x20) {
1157
        T0 = 0;
1158
    } else {
1159
        T0 = T0 << T1;
1160
    }
1161
    RETURN();
1162
}
1163

    
1164
/* shift right algebraic word */
1165
PPC_OP(sraw)
1166
{
1167
    do_sraw();
1168
    RETURN();
1169
}
1170

    
1171
/* shift right algebraic word immediate */
1172
PPC_OP(srawi)
1173
{
1174
    T1 = T0;
1175
    T0 = (Ts0 >> PARAM(1));
1176
    if (Ts1 < 0 && (Ts1 & PARAM(2)) != 0) {
1177
        xer_ca = 1;
1178
    } else {
1179
        xer_ca = 0;
1180
    }
1181
    RETURN();
1182
}
1183

    
1184
/* shift right word */
1185
PPC_OP(srw)
1186
{
1187
    if (T1 & 0x20) {
1188
        T0 = 0;
1189
    } else {
1190
        T0 = T0 >> T1;
1191
    }
1192
    RETURN();
1193
}
1194

    
1195
/***                       Floating-Point arithmetic                       ***/
1196
/* fadd - fadd. */
1197
PPC_OP(fadd)
1198
{
1199
    FT0 += FT1;
1200
    RETURN();
1201
}
1202

    
1203
/* fsub - fsub. */
1204
PPC_OP(fsub)
1205
{
1206
    FT0 -= FT1;
1207
    RETURN();
1208
}
1209

    
1210
/* fmul - fmul. */
1211
PPC_OP(fmul)
1212
{
1213
    FT0 *= FT1;
1214
    RETURN();
1215
}
1216

    
1217
/* fdiv - fdiv. */
1218
void do_fdiv (void);
1219
PPC_OP(fdiv)
1220
{
1221
    do_fdiv();
1222
    RETURN();
1223
}
1224

    
1225
/* fsqrt - fsqrt. */
1226
PPC_OP(fsqrt)
1227
{
1228
    do_fsqrt();
1229
    RETURN();
1230
}
1231

    
1232
/* fres - fres. */
1233
PPC_OP(fres)
1234
{
1235
    do_fres();
1236
    RETURN();
1237
}
1238

    
1239
/* frsqrte  - frsqrte. */
1240
PPC_OP(frsqrte)
1241
{
1242
    do_frsqrte();
1243
    RETURN();
1244
}
1245

    
1246
/* fsel - fsel. */
1247
PPC_OP(fsel)
1248
{
1249
    do_fsel();
1250
    RETURN();
1251
}
1252

    
1253
/***                     Floating-Point multiply-and-add                   ***/
1254
/* fmadd - fmadd. */
1255
PPC_OP(fmadd)
1256
{
1257
    FT0 = (FT0 * FT1) + FT2;
1258
    RETURN();
1259
}
1260

    
1261
/* fmsub - fmsub. */
1262
PPC_OP(fmsub)
1263
{
1264
    FT0 = (FT0 * FT1) - FT2;
1265
    RETURN();
1266
}
1267

    
1268
/* fnmadd - fnmadd. - fnmadds - fnmadds. */
1269
PPC_OP(fnmadd)
1270
{
1271
    do_fnmadd();
1272
    RETURN();
1273
}
1274

    
1275
/* fnmsub - fnmsub. */
1276
PPC_OP(fnmsub)
1277
{
1278
    do_fnmsub();
1279
    RETURN();
1280
}
1281

    
1282
/***                     Floating-Point round & convert                    ***/
1283
/* frsp - frsp. */
1284
PPC_OP(frsp)
1285
{
1286
    FT0 = (float)FT0;
1287
    RETURN();
1288
}
1289

    
1290
/* fctiw - fctiw. */
1291
PPC_OP(fctiw)
1292
{
1293
    do_fctiw();
1294
    RETURN();
1295
}
1296

    
1297
/* fctiwz - fctiwz. */
1298
PPC_OP(fctiwz)
1299
{
1300
    do_fctiwz();
1301
    RETURN();
1302
}
1303

    
1304

    
1305
/***                         Floating-Point compare                        ***/
1306
/* fcmpu */
1307
PPC_OP(fcmpu)
1308
{
1309
    do_fcmpu();
1310
    RETURN();
1311
}
1312

    
1313
/* fcmpo */
1314
PPC_OP(fcmpo)
1315
{
1316
    do_fcmpo();
1317
    RETURN();
1318
}
1319

    
1320
/***                         Floating-point move                           ***/
1321
/* fabs */
1322
void do_fabs (void);
1323
PPC_OP(fabs)
1324
{
1325
    do_fabs();
1326
    RETURN();
1327
}
1328

    
1329
/* fnabs */
1330
void do_fnabs (void);
1331
PPC_OP(fnabs)
1332
{
1333
    do_fnabs();
1334
    RETURN();
1335
}
1336

    
1337
/* fneg */
1338
PPC_OP(fneg)
1339
{
1340
    FT0 = -FT0;
1341
    RETURN();
1342
}
1343

    
1344
/* Load and store */
1345
#define MEMSUFFIX _raw
1346
#include "op_mem.h"
1347
#if !defined(CONFIG_USER_ONLY)
1348
#define MEMSUFFIX _user
1349
#include "op_mem.h"
1350

    
1351
#define MEMSUFFIX _kernel
1352
#include "op_mem.h"
1353
#endif
1354

    
1355
/* Special op to check and maybe clear reservation */
1356
PPC_OP(check_reservation)
1357
{
1358
    do_check_reservation();
1359
    RETURN();
1360
}
1361

    
1362
/* Return from interrupt */
1363
PPC_OP(rfi)
1364
{
1365
    regs->nip = regs->spr[SRR0] & ~0x00000003;
1366
#if 1 // TRY
1367
    T0 = regs->spr[SRR1] & ~0xFFF00000;
1368
#else
1369
    T0 = regs->spr[SRR1] & ~0xFFFF0000;
1370
#endif
1371
    do_store_msr();
1372
#if defined (DEBUG_OP)
1373
    dump_rfi();
1374
#endif
1375
    //    do_tlbia();
1376
    do_raise_exception(EXCP_RFI);
1377
    RETURN();
1378
}
1379

    
1380
/* Trap word */
1381
PPC_OP(tw)
1382
{
1383
    if ((Ts0 < Ts1 && (PARAM(1) & 0x10)) ||
1384
        (Ts0 > Ts1 && (PARAM(1) & 0x08)) ||
1385
        (Ts0 == Ts1 && (PARAM(1) & 0x04)) ||
1386
        (T0 < T1 && (PARAM(1) & 0x02)) ||
1387
        (T0 > T1 && (PARAM(1) & 0x01)))
1388
        do_raise_exception_err(EXCP_PROGRAM, EXCP_TRAP);
1389
    RETURN();
1390
}
1391

    
1392
PPC_OP(twi)
1393
{
1394
    if ((Ts0 < SPARAM(1) && (PARAM(2) & 0x10)) ||
1395
        (Ts0 > SPARAM(1) && (PARAM(2) & 0x08)) ||
1396
        (Ts0 == SPARAM(1) && (PARAM(2) & 0x04)) ||
1397
        (T0 < (uint32_t)SPARAM(1) && (PARAM(2) & 0x02)) ||
1398
        (T0 > (uint32_t)SPARAM(1) && (PARAM(2) & 0x01)))
1399
        do_raise_exception_err(EXCP_PROGRAM, EXCP_TRAP);
1400
    RETURN();
1401
}
1402

    
1403
/* Instruction cache block invalidate */
1404
PPC_OP(icbi)
1405
{
1406
    do_icbi();
1407
    RETURN();
1408
}
1409

    
1410
/* tlbia */
1411
PPC_OP(tlbia)
1412
{
1413
    do_tlbia();
1414
    RETURN();
1415
}
1416

    
1417
/* tlbie */
1418
PPC_OP(tlbie)
1419
{
1420
    do_tlbie();
1421
    RETURN();
1422
}