use new machine API
[qemu] / target-ppc / op.c
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 }