ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/mon/src/mon_ppc.cpp
(Generate patch)

Comparing mon/src/mon_ppc.cpp (file contents):
Revision 1.1.1.1 by cebix, 1999-10-04T19:31:09Z vs.
Revision 1.11 by cebix, 2010-02-21T11:58:33Z

# Line 1 | Line 1
1   /*
2   *  mon_ppc.cpp - PowerPC disassembler
3   *
4 < *  (C) 1997-1999 Christian Bauer
4 > *  cxmon (C) Christian Bauer, Marc Hellwig
5 > *
6 > *  This program is free software; you can redistribute it and/or modify
7 > *  it under the terms of the GNU General Public License as published by
8 > *  the Free Software Foundation; either version 2 of the License, or
9 > *  (at your option) any later version.
10 > *
11 > *  This program 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
14 > *  GNU General Public License for more details.
15 > *
16 > *  You should have received a copy of the GNU General Public License
17 > *  along with this program; if not, write to the Free Software
18 > *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19   */
20  
21 < #include <stdio.h>
21 > #include "sysdeps.h"
22  
23   #include "mon.h"
24 < #include "mon_ppc.h"
24 > #include "mon_disass.h"
25  
26  
27   // Instruction fields
28 < static int primop, exop, ra, rb, rc, rd;
28 > static int primop, exop, vxop, ra, rb, rc, rd;
29   static unsigned short imm;
30  
31  
32   // Codes for trap instructions
33 < static char *to_code[32] = {
33 > static const char *to_code[32] = {
34          NULL, "lgt", "llt", NULL, "eq", "lge", "lle", NULL,
35          "gt", NULL, NULL, NULL, "ge", NULL, NULL, NULL,
36          "lt", NULL, NULL, NULL, "le", NULL, NULL, NULL,
# Line 82 | Line 96 | static char *to_code[32] = {
96  
97   #define dsform(s) fprintf(f, "%s\tr%d,$%04x(r%d)\n", s, rd, short(imm & 0xfffc), ra)
98  
99 + #define xform_vls(s) \
100 +        if (ra == 0) \
101 +                fprintf(f, "%s\tv%d,r%d\n", s, rd, rb); \
102 +        else \
103 +                fprintf(f, "%s\tv%d,r%d,r%d\n", s, rd, ra, rb)
104   #define xform_ls(s) \
105          if (ra == 0) \
106                  fprintf(f, "%s\tr%d,r%d\n", s, rd, rb); \
# Line 146 | Line 165 | static char *to_code[32] = {
165  
166   #define mdsform(s) fprintf(f, "%s%s\tr%d,r%d,r%d,%d\n", s, w & 1 ? "." : "", ra, rd, rb, rc | (w & 32 ? 32 : 0))
167  
168 + #define va_form(s) fprintf(f, "%s\tv%d,v%d,v%d,v%d\n", s, rd, ra, rb, rc)
169 + #define vx_form(s) fprintf(f, "%s\tv%d,v%d,v%d\n", s, rd, ra, rb)
170 + #define vxr_form(s) fprintf(f, "%s%s\tv%d,v%d,v%d\n", s, w & (1 << 10) ? "." : "", rd, ra, rb)
171 + #define vxi_ra_form(s) fprintf(f, "%s\tv%d,v%d,%d\n", s, rd, rb, ra)
172 + #define vx_raz_form(s) \
173 +        if (ra == 0) \
174 +                fprintf(f, "%s\tv%d,v%d\n", s, rd, rb); \
175 +        else \
176 +                fprintf(f, "?\n")
177 + #define vxi_ras_rbz_form(s) \
178 +        if (rb == 0) \
179 +                fprintf(f, "%s\tv%d,%d\n", s, rd, ra - (ra & 0x10 ? 0x20 : 0)); \
180 +        else \
181 +                fprintf(f, "?\n")
182  
183   // Prototypes
184 + static void disass4(FILE *f, unsigned int adr, unsigned int w);
185   static void disass19(FILE *f, unsigned int adr, unsigned int w);
186   static void disass31(FILE *f, unsigned int adr, unsigned int w);
187   static void disass59(FILE *f, unsigned int adr, unsigned int w);
188   static void disass63(FILE *f, unsigned int adr, unsigned int w);
189   static unsigned int mbme2mask(int mb, int me);
190 < static char *get_spr(int reg);
190 > static const char *get_spr(int reg);
191  
192  
193   /*
# Line 169 | Line 203 | void disass_ppc(FILE *f, unsigned int ad
203          rb = w >> 11 & 0x1f;
204          rc = w >> 6 & 0x1f;
205          exop = w >> 1 & 0x3ff;
206 +        vxop = w & 0x7ff;
207          imm = w & 0xffff;
208  
209          // Decode primary opcode
# Line 187 | Line 222 | void disass_ppc(FILE *f, unsigned int ad
222                                  dform_to("twi");
223                          break;
224  
225 < //              case 4: // AltiVec
225 >                case 4: // AltiVec
226 >                        disass4(f, adr, w);
227 >                        break;
228  
229                  case 7: dform_simm("mulli"); break;
230                  case 8: dform_simm("subfic"); break;
# Line 242 | Line 279 | void disass_ppc(FILE *f, unsigned int ad
279  
280                  case 16: {
281                          int target = short(imm & 0xfffc);
282 <                        char *form;
282 >                        const char *form;
283                          if (w & 1)
284                                  if (w & 2)
285                                          form = "la";
# Line 379 | Line 416 | void disass_ppc(FILE *f, unsigned int ad
416  
417  
418   /*
419 + *  Disassemble instruction with primary opcode = 4 (VX-Form)
420 + */
421 +
422 + static void disass4(FILE *f, unsigned int adr, unsigned int w)
423 + {
424 +        switch (vxop) {
425 +        case 1540:
426 +                if (ra == 0 && rb == 0)
427 +                        fprintf(f, "mfvscr\tv%d\n", rd);
428 +                else
429 +                        fprintf(f, "?\n");
430 +                break;
431 +        case 1604:
432 +                if (rd == 0 && ra == 0)
433 +                        fprintf(f, "mtvscr\tv%d\n", rb);
434 +                else
435 +                        fprintf(f, "?\n");
436 +                break;
437 +        case 384: vx_form("vaddcuw"); break;
438 +        case 10: vx_form("vaddfp"); break;
439 +        case 768: vx_form("vaddsbs"); break;
440 +        case 832: vx_form("vaddshs"); break;
441 +        case 896: vx_form("vaddsws"); break;
442 +        case 0: vx_form("vaddubm"); break;
443 +        case 512: vx_form("vaddubs"); break;
444 +        case 64: vx_form("vadduhm"); break;
445 +        case 576: vx_form("vadduhs"); break;
446 +        case 128: vx_form("vadduwm"); break;
447 +        case 640: vx_form("vadduws"); break;
448 +        case 1028: vx_form("vand"); break;
449 +        case 1092: vx_form("vandc"); break;
450 +        case 1282: vx_form("vavgsb"); break;
451 +        case 1346: vx_form("vavgsh"); break;
452 +        case 1410: vx_form("vavgsw"); break;
453 +        case 1026: vx_form("vavgub"); break;
454 +        case 1090: vx_form("vavguh"); break;
455 +        case 1154: vx_form("vavguw"); break;
456 +        case 842: vxi_ra_form("vcfsx"); break;
457 +        case 778: vxi_ra_form("vcfux"); break;
458 +        case 966: case 966+1024: vxr_form("vcmpbfp"); break;
459 +        case 198: case 198+1024: vxr_form("vcmpeqfp"); break;
460 +        case 6: case 6+1024: vxr_form("vcmpequb"); break;
461 +        case 70: case 70+1024: vxr_form("vcmpequh"); break;
462 +        case 134: case 134+1024: vxr_form("vcmpequw"); break;
463 +        case 454: case 454+1024: vxr_form("vcmpgefp"); break;
464 +        case 710: case 710+1024: vxr_form("vcmpgtfp"); break;
465 +        case 774: case 774+1024: vxr_form("vcmpgtsb"); break;
466 +        case 838: case 838+1024: vxr_form("vcmpgtsh"); break;
467 +        case 902: case 902+1024: vxr_form("vcmpgtsw"); break;
468 +        case 518: case 518+1024: vxr_form("vcmpgtub"); break;
469 +        case 582: case 582+1024: vxr_form("vcmpgtuh"); break;
470 +        case 646: case 646+1024: vxr_form("vcmpgtuw"); break;
471 +        case 970: vxi_ra_form("vctsxs"); break;
472 +        case 906: vxi_ra_form("vctuxs"); break;
473 +        case 394: vx_raz_form("vexptefp"); break;
474 +        case 458: vx_raz_form("vlogefp"); break;
475 +        case 1034: vx_form("vmaxfp"); break;
476 +        case 258: vx_form("vmaxsb"); break;
477 +        case 322: vx_form("vmaxsh"); break;
478 +        case 386: vx_form("vmaxsw"); break;
479 +        case 2: vx_form("vmaxub"); break;
480 +        case 66: vx_form("vmaxuh"); break;
481 +        case 130: vx_form("vmaxuw"); break;
482 +        case 1098: vx_form("vminfp"); break;
483 +        case 770: vx_form("vminsb"); break;
484 +        case 834: vx_form("vminsh"); break;
485 +        case 898: vx_form("vminsw"); break;
486 +        case 514: vx_form("vminub"); break;
487 +        case 578: vx_form("vminuh"); break;
488 +        case 642: vx_form("vminuw"); break;
489 +        case 12: vx_form("vmrghb"); break;
490 +        case 76: vx_form("vmrghh"); break;
491 +        case 140: vx_form("vmrghw"); break;
492 +        case 268: vx_form("vmrglb"); break;
493 +        case 332: vx_form("vmrglh"); break;
494 +        case 396: vx_form("vmrglw"); break;
495 +        case 776: vx_form("vmulesb"); break;
496 +        case 840: vx_form("vmulesh"); break;
497 +        case 520: vx_form("vmuleub"); break;
498 +        case 584: vx_form("vmuleuh"); break;
499 +        case 264: vx_form("vmulosb"); break;
500 +        case 328: vx_form("vmulosh"); break;
501 +        case 8: vx_form("vmuloub"); break;
502 +        case 72: vx_form("vmulouh"); break;
503 +        case 1284: vx_form("vnor"); break;
504 +        case 1156: vx_form("vor"); break;
505 +        case 782: vx_form("vpkpx"); break;
506 +        case 398: vx_form("vpkshss"); break;
507 +        case 270: vx_form("vpkshus"); break;
508 +        case 462: vx_form("vpkswss"); break;
509 +        case 334: vx_form("vpkswus"); break;
510 +        case 14: vx_form("vpkuhum"); break;
511 +        case 142: vx_form("vpkuhus"); break;
512 +        case 78: vx_form("vpkuwum"); break;
513 +        case 206: vx_form("vpkuwus"); break;
514 +        case 266: vx_raz_form("vrefp"); break;
515 +        case 714: vx_raz_form("vrfim"); break;
516 +        case 522: vx_raz_form("vrfin"); break;
517 +        case 650: vx_raz_form("vrfip"); break;
518 +        case 586: vx_raz_form("vrfiz"); break;
519 +        case 4: vx_form("vrlb"); break;
520 +        case 68: vx_form("vrlh"); break;
521 +        case 132: vx_form("vrlw"); break;
522 +        case 330: vx_raz_form("vrsqrtefp"); break;
523 +        case 452: vx_form("vsl"); break;
524 +        case 260: vx_form("vslb"); break;
525 +        case 324: vx_form("vslh"); break;
526 +        case 1036: vx_form("vslo"); break;
527 +        case 388: vx_form("vslw"); break;
528 +        case 524: vxi_ra_form("vspltb"); break;
529 +        case 588: vxi_ra_form("vsplth"); break;
530 +        case 780: vxi_ras_rbz_form("vspltisb"); break;
531 +        case 844: vxi_ras_rbz_form("vspltish"); break;
532 +        case 908: vxi_ras_rbz_form("vspltisw"); break;
533 +        case 652: vxi_ra_form("vspltw"); break;
534 +        case 708: vx_form("vsr"); break;
535 +        case 772: vx_form("vsrab"); break;
536 +        case 836: vx_form("vsrah"); break;
537 +        case 900: vx_form("vsraw"); break;
538 +        case 516: vx_form("vsrb"); break;
539 +        case 580: vx_form("vsrh"); break;
540 +        case 1100: vx_form("vsro"); break;
541 +        case 644: vx_form("vsrw"); break;
542 +        case 1408: vx_form("vsubcuw"); break;
543 +        case 74: vx_form("vsubfp"); break;
544 +        case 1792: vx_form("vsubsbs"); break;
545 +        case 1856: vx_form("vsubshs"); break;
546 +        case 1920: vx_form("vsubsws"); break;
547 +        case 1024: vx_form("vsububm"); break;
548 +        case 1536: vx_form("vsububs"); break;
549 +        case 1088: vx_form("vsubuhm"); break;
550 +        case 1600: vx_form("vsubuhs"); break;
551 +        case 1152: vx_form("vsubuwm"); break;
552 +        case 1664: vx_form("vsubuws"); break;
553 +        case 1928: vx_form("vsumsws"); break;
554 +        case 1672: vx_form("vsum2sws"); break;
555 +        case 1800: vx_form("vsum4sbs"); break;
556 +        case 1608: vx_form("vsum4shs"); break;
557 +        case 1544: vx_form("vsum4ubs"); break;
558 +        case 846: vx_raz_form("vupkhpx"); break;
559 +        case 526: vx_raz_form("vupkhsb"); break;
560 +        case 590: vx_raz_form("vupkhsh"); break;
561 +        case 974: vx_raz_form("vupklpx"); break;
562 +        case 654: vx_raz_form("vupklsb"); break;
563 +        case 718: vx_raz_form("vupklsh"); break;
564 +        case 1220: vx_form("vxor"); break;
565 +        default:
566 +                if ((vxop & 0x43f) == 44) {             // vsldoi vD,vA,vB,SHB
567 +                        fprintf(f, "vsldoi\tv%d,v%d,v%d,%d\n", rd, ra, rb, rc & 15);
568 +                        break;
569 +                }
570 +                switch (vxop & 0x3f) {                  // VA-form, must come last
571 +                case 46: va_form("vmaddfp"); break;
572 +                case 32: va_form("vmhaddshs"); break;
573 +                case 33: va_form("vmhraddshs"); break;
574 +                case 34: va_form("vmladduhm"); break;
575 +                case 37: va_form("vmsummbm"); break;
576 +                case 40: va_form("vmsumshm"); break;
577 +                case 41: va_form("vmsumshs"); break;
578 +                case 36: va_form("vmsumubm"); break;
579 +                case 38: va_form("vmsumuhm"); break;
580 +                case 39: va_form("vmsumuhs"); break;
581 +                case 47: va_form("vnmsubfp"); break;
582 +                case 43: va_form("vperm"); break;
583 +                case 42: va_form("vsel"); break;
584 +                default: fprintf(f, "?\n"); break;
585 +                }
586 +                break;
587 +        }
588 + }
589 +
590 +
591 + /*
592   *  Disassemble instruction with primary opcode = 19 (XL-Form)
593   */
594  
# Line 480 | Line 690 | static void disass31(FILE *f, unsigned i
690                                  xform_to("tw");
691                          break;
692  
693 +                case 6: xform_vls("lvsl"); break;
694 +                case 7: xform_vls("lvebx"); break;
695                  case 8: xoform_dab("subfc"); break;
696                  case 8+512: xoform_dab("subfco"); break;
697                  case 9: case 9+512: xoform_dab("mulhdu"); break; // 64 bit
# Line 502 | Line 714 | static void disass31(FILE *f, unsigned i
714                                  xform_crlab("cmplw");
715                          break;
716  
717 +                case 38: xform_vls("lvsr"); break;
718 +                case 39: xform_vls("lvehx"); break;
719                  case 40: xoform_dab("subf"); break;
720                  case 40+512: xoform_dab("subfo"); break;
721                  case 53: xform_ls("ldux"); break; // 64 bit
# Line 517 | Line 731 | static void disass31(FILE *f, unsigned i
731                                  xform_to("td");
732                          break;
733  
734 +                case 71: xform_vls("lvewx"); break;
735                  case 73: case 73+512: xoform_dab("mulhd"); break; // 64 bit
736                  case 75: case 75+512: xoform_dab("mulhw"); break;
737                  case 83: xform_d("mfmsr"); break;
738                  case 84: xform_ls("ldarx"); break; // 64 bit
739                  case 86: xform_ab("dcbf"); break;
740                  case 87: xform_ls("lbzx"); break;
741 +                case 103: xform_vls("lvx"); break;
742                  case 104: xoform_da("neg"); break;
743                  case 104+512: xoform_da("nego"); break;
744                  case 119: xform_ls("lbzux"); break;
# Line 534 | Line 750 | static void disass31(FILE *f, unsigned i
750                                  xform_sabc("nor");
751                          break;
752  
753 +                case 135: xform_vls("stvebx"); break;
754                  case 136: xoform_dab("subfe"); break;
755                  case 136+512: xoform_dab("subfeo"); break;
756                  case 138: xoform_dab("adde"); break;
# Line 550 | Line 767 | static void disass31(FILE *f, unsigned i
767                          break;
768  
769                  case 151: xform_ls("stwx"); break;
770 +                case 167: xform_vls("stvehx"); break;
771                  case 181: xform_ls("stdux"); break; // 64 bit
772                  case 183: xform_ls("stwux"); break;
773 +                case 199: xform_vls("stvewx"); break;
774                  case 200: xoform_da("subfze"); break;
775                  case 200+512: xoform_da("subfzeo"); break;
776                  case 202: xoform_da("addze"); break;
# Line 566 | Line 785 | static void disass31(FILE *f, unsigned i
785                          break;
786  
787                  case 215: xform_ls("stbx"); break;
788 +                case 231: xform_vls("stvx"); break;
789                  case 232: xoform_da("subfme"); break;
790                  case 232+512: xoform_da("subfmeo"); break;
791                  case 233: xoform_dab("mulld"); break; // 64 bit
# Line 594 | Line 814 | static void disass31(FILE *f, unsigned i
814                                  fprintf(f, "mflr\tr%d\n", rd);
815                          else if ((ra | (rb << 5)) == 9)
816                                  fprintf(f, "mfctr\tr%d\n", rd);
817 +                        else if ((ra | (rb << 5)) == 256)
818 +                                fprintf(f, "mfvrsave\tr%d\n", rd);
819                          else {
820 <                                char *spr = get_spr(ra | (rb << 5));
820 >                                const char *spr = get_spr(ra | (rb << 5));
821                                  if (spr)
822                                          fprintf(f, "mfspr\tr%d,%s\n", rd, spr);
823                                  else
# Line 605 | Line 827 | static void disass31(FILE *f, unsigned i
827  
828                  case 341: xform_ls("lwax"); break; // 64 bit
829                  case 343: xform_ls("lhax"); break;
830 +                case 359: xform_vls("lvxl"); break;
831                  case 370: xform("tlbia"); break;
832  
833 +                case 822: // AltiVec
834 +                        if ((rd & 0xc) == 0 && ra == 0 && rb == 0 && (w & 1) == 0) {
835 +                                if (rd & 0x10)
836 +                                        fprintf(f, "dssall\n");
837 +                                else
838 +                                        fprintf(f, "dss\t%d\n", rd & 3);
839 +                        }
840 +                        else
841 +                                fprintf(f, "?\n");
842 +                        break;
843 +
844 +                case 342: // AltiVec
845 +                        if ((rd & 0xc) == 0 && (w & 1) == 0)
846 +                                fprintf(f, "dst%s\tr%d,r%d,%d\n", rd & 0x10 ? "t" : "", ra, rb, rd & 3);
847 +                        else
848 +                                fprintf(f, "?\n");
849 +                        break;
850 +
851 +                case 374: // AltiVec
852 +                        if ((rd & 0xc) == 0 && (w & 1) == 0)
853 +                                fprintf(f, "dstst%s\tr%d,r%d,%d\n", rd & 0x10 ? "t" : "", ra, rb, rd & 3);
854 +                        else
855 +                                fprintf(f, "?\n");
856 +                        break;
857 +
858                  case 371:
859                          if ((ra | (rb << 5)) == 268)
860                                  xfxform_tb("mftb");
# Line 643 | Line 891 | static void disass31(FILE *f, unsigned i
891                                  fprintf(f, "mtlr\tr%d\n", rd);
892                          else if ((ra | (rb << 5)) == 9)
893                                  fprintf(f, "mtctr\tr%d\n", rd);
894 +                        else if ((ra | (rb << 5)) == 256)
895 +                                fprintf(f, "mtvrsave\tr%d\n", rd);
896                          else {
897 <                                char *spr = get_spr(ra | (rb << 5));
897 >                                const char *spr = get_spr(ra | (rb << 5));
898                                  if (spr)
899                                          fprintf(f, "mtspr\t%s,r%d\n", spr, rd);
900                                  else
# Line 654 | Line 904 | static void disass31(FILE *f, unsigned i
904  
905                  case 470: xform_ab("dcbi"); break;
906                  case 476: xform_sabc("nand"); break;
907 +                case 487: xform_vls("stvxl"); break;
908                  case 489: xoform_dab("divd"); break; // 64 bit
909                  case 489+512: xoform_dab("divdo"); break; // 64 bit
910                  case 491: xoform_dab("divw"); break;
# Line 807 | Line 1058 | static unsigned int mbme2mask(int mb, in
1058   *  Convert SPR number to register name
1059   */
1060  
1061 < char *get_spr(int reg)
1061 > const char *get_spr(int reg)
1062   {
1063          switch (reg) {
1064                  case 1: return "xer";

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines