home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Exec 5 / CD_Magazyn_EXEC_nr_5.iso / Programy / Programowanie / PPC / wosdb_src.lzx / ppc_disasm.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-11-10  |  36.2 KB  |  1,807 lines

  1. /* $VER: ppc_disasm.c V1.2 (09.11.2000)
  2.  *
  3.  * Disassembler module for the PowerPC microprocessor family
  4.  * Copyright (c) 1998-2000  Frank Wille
  5.  *
  6.  * ppc_disasm.c is freeware and may be freely redistributed as long as
  7.  * no modifications are made and nothing is charged for it.
  8.  * Non-commercial usage is allowed without any restrictions.
  9.  * EVERY PRODUCT OR PROGRAM DERIVED DIRECTLY FROM MY SOURCE MAY NOT BE
  10.  * SOLD COMMERCIALLY WITHOUT PERMISSION FROM THE AUTHOR.
  11.  *
  12.  *
  13.  * v1.2  (09.11.2000) phx
  14.  *       Fixed syntax of mffs, mtfsf and mtfsfi.
  15.  * v1.1  (19.02.2000) phx
  16.  *       fabs wasn't recognized.
  17.  * v1.0  (30.01.2000) phx
  18.  *       stfsx, stfdx, lfsx, lfdx, stfsux, stfdux, lfsux, lfdux, etc.
  19.  *       printed "rd,ra,rb" as operands instead "fd,ra,rb".
  20.  * v0.4  (01.06.1999) phx
  21.  *       'stwm' shoud have been 'stmw'.
  22.  * v0.3  (17.11.1998) phx
  23.  *       The OE-types (e.g. addo, subfeo, etc.) didn't work for all
  24.  *       instructions.
  25.  *       AA-form branches have an absolute destination.
  26.  *       addze and subfze must not have a third operand.
  27.  *       sc was not recognized.
  28.  * v0.2  (29.05.1998) phx
  29.  *       Sign error. SUBI got negative immediate values.
  30.  * v0.1  (23.05.1998) phx
  31.  *       First version, which implements all PowerPC instructions.
  32.  * v0.0  (09.05.1998) phx
  33.  *       File created.
  34.  */
  35.  
  36. #define PPC_DISASM_C
  37. #include <stdio.h>
  38. #include <string.h>
  39. #include <stdarg.h>
  40. #include <stdlib.h>
  41. #include "ppc_disasm.h"
  42.  
  43.  
  44. static char *trap_condition[32] = {
  45.   NULL,"lgt","llt",NULL,"eq","lge","lle",NULL,
  46.   "gt",NULL,NULL,NULL,"ge",NULL,NULL,NULL,
  47.   "lt",NULL,NULL,NULL,"le",NULL,NULL,NULL,
  48.   "ne",NULL,NULL,NULL,NULL,NULL,NULL,NULL
  49. };
  50.  
  51. static char *cmpname[4] = {
  52.   "cmpw","cmpd","cmplw","cmpld"
  53. };
  54.  
  55. static char *b_ext[4] = {
  56.   "","l","a","la"
  57. };
  58.  
  59. static char *b_condition[8] = {
  60.   "ge","le","ne","ns","lt","gt","eq","so"
  61. };
  62.  
  63. static char *b_decr[16] = {
  64.   "nzf","zf",NULL,NULL,"nzt","zt",NULL,NULL,
  65.   "nz","z",NULL,NULL,"nz","z",NULL,NULL
  66. };
  67.  
  68. static char *regsel[2] = {
  69.   "","r"
  70. };
  71.  
  72. static char *oesel[2] = {
  73.   "","o"
  74. };
  75.  
  76. static char *rcsel[2] = {
  77.   "","."
  78. };
  79.  
  80. static char *ldstnames[] = {
  81.   "lwz","lwzu","lbz","lbzu","stw","stwu","stb","stbu","lhz","lhzu",
  82.   "lha","lhau","sth","sthu","lmw","stmw","lfs","lfsu","lfd","lfdu",
  83.   "stfs","stfsu","stfd","stfdu"
  84. };
  85.  
  86.  
  87.  
  88. static void ierror(char *errtxt,...)
  89. /* display internal error and quit program */
  90. {
  91.   va_list vl;
  92.  
  93.   fprintf(stderr,"\nINTERNAL ERROR (PPC disassembler): ");
  94.   va_start(vl,errtxt);
  95.   vfprintf(stderr,errtxt,vl);
  96.   va_end(vl);
  97.   fprintf(stderr,".\nAborting.\n");
  98.   exit(EXIT_FAILURE);
  99. }
  100.  
  101.  
  102. static ppc_word swapda(ppc_word w)
  103. {
  104.   return ((w&0xfc00ffff)|((w&PPCAMASK)<<5)|((w&PPCDMASK)>>5));
  105. }
  106.  
  107.  
  108. static ppc_word swapab(ppc_word w)
  109. {
  110.   return ((w&0xffe007ff)|((w&PPCBMASK)<<5)|((w&PPCAMASK)>>5));
  111. }
  112.  
  113.  
  114. static void ill(struct DisasmPara_PPC *dp,ppc_word in)
  115. {
  116.   strcpy(dp->opcode,".word");
  117.   sprintf(dp->operands,"0x%08lx",(unsigned long)in);
  118.   dp->flags |= PPCF_ILLEGAL;
  119. }
  120.  
  121.  
  122. static void imm(struct DisasmPara_PPC *dp,ppc_word in,int uimm,int type)
  123. /* Generate immediate instruction operand. */
  124. /* type 0: D-mode, D,A,imm */
  125. /* type 1: S-mode, A,S,imm */
  126. /* type 2: S/D register is ignored (trap,cmpi) */
  127. /* type 3: A register is ignored (li) */
  128. {
  129.   char *s;
  130.   int i = (int)(in & 0xffff);
  131.  
  132.   dp->type = PPCINSTR_IMM;
  133.   if (!uimm) {
  134.     if (i > 0x7fff)
  135.       i -= 0x10000;
  136.   }
  137.   else
  138.     dp->flags |= PPCF_UNSIGNED;
  139.   dp->displacement = i;
  140.  
  141.   switch (type) {
  142.     case 0:
  143.       sprintf(dp->operands,"r%d,r%d,%d",(int)PPCGETD(in),(int)PPCGETA(in),i);
  144.       break;
  145.     case 1:
  146.       sprintf(dp->operands,"r%d,r%d,%d",(int)PPCGETA(in),(int)PPCGETD(in),i);
  147.       break;
  148.     case 2:
  149.       sprintf(dp->operands,"r%d,%d",(int)PPCGETA(in),i);
  150.       break;
  151.     case 3:
  152.       sprintf(dp->operands,"r%d,%d",(int)PPCGETD(in),i);
  153.       break;
  154.     default:
  155.       ierror("imm(): Wrong type");
  156.       break;
  157.   }
  158. }
  159.  
  160.  
  161. static void ra_rb(char *s,ppc_word in)
  162. {
  163.   sprintf(s,"r%d,r%d",(int)PPCGETA(in),(int)PPCGETB(in));
  164. }
  165.  
  166.  
  167. static char *rd_ra_rb(char *s,ppc_word in,int mask)
  168. {
  169.   static const char *fmt = "r%d,";
  170.  
  171.   if (mask) {
  172.     if (mask & 4)
  173.       s += sprintf(s,fmt,(int)PPCGETD(in));
  174.     if (mask & 2)
  175.       s += sprintf(s,fmt,(int)PPCGETA(in));
  176.     if (mask & 1)
  177.       s += sprintf(s,fmt,(int)PPCGETB(in));
  178.     *--s = '\0';
  179.   }
  180.   else
  181.     *s = '\0';
  182.   return (s);
  183. }
  184.  
  185.  
  186. static char *fd_ra_rb(char *s,ppc_word in,int mask)
  187. {
  188.   static const char *ffmt = "f%d,";
  189.   static const char *rfmt = "r%d,";
  190.  
  191.   if (mask) {
  192.     if (mask & 4)
  193.       s += sprintf(s,ffmt,(int)PPCGETD(in));
  194.     if (mask & 2)
  195.       s += sprintf(s,rfmt,(int)PPCGETA(in));
  196.     if (mask & 1)
  197.       s += sprintf(s,rfmt,(int)PPCGETB(in));
  198.     *--s = '\0';
  199.   }
  200.   else
  201.     *s = '\0';
  202.   return (s);
  203. }
  204.  
  205.  
  206. static void trapi(struct DisasmPara_PPC *dp,ppc_word in,unsigned char dmode)
  207. {
  208.   char *cnd;
  209.  
  210.   if (cnd = trap_condition[PPCGETD(in)]) {
  211.     dp->flags |= dmode;
  212.     sprintf(dp->opcode,"t%c%s",dmode?'d':'w',cnd);
  213.     imm(dp,in,0,2);
  214.   }
  215.   else
  216.     ill(dp,in);
  217. }
  218.  
  219.  
  220. static void cmpi(struct DisasmPara_PPC *dp,ppc_word in,int uimm)
  221. {
  222.   char *oper = dp->operands;
  223.   int i = (int)PPCGETL(in);
  224.  
  225.   if (i < 2) {
  226.     if (i)
  227.       dp->flags |= PPCF_64;
  228.     sprintf(dp->opcode,"%si",cmpname[uimm*2+i]);
  229.     if (i = (int)PPCGETCRD(in)) {
  230.       sprintf(oper,"cr%c,",'0'+i);
  231.       dp->operands += 4;
  232.     }
  233.     imm(dp,in,uimm,2);
  234.     dp->operands = oper;
  235.   }
  236.   else
  237.     ill(dp,in);
  238. }
  239.  
  240.  
  241. static void addi(struct DisasmPara_PPC *dp,ppc_word in,char *ext)
  242. {
  243.   if ((in&0x08000000) && !PPCGETA(in)) {
  244.     sprintf(dp->opcode,"l%s",ext);  /* li, lis */
  245.     imm(dp,in,0,3);
  246.   }
  247.   else {
  248.     sprintf(dp->opcode,"%s%s",(in&0x8000)?"sub":"add",ext);
  249.     if (in & 0x8000)
  250.       in = (in^0xffff) + 1;
  251.     imm(dp,in,1,0);
  252.   }
  253. }
  254.  
  255.  
  256. static int branch(struct DisasmPara_PPC *dp,ppc_word in,
  257.                     char *bname,int aform,int bdisp)
  258. /* build a branch instr. and return number of chars written to operand */
  259. {
  260.   int bo = (int)PPCGETD(in);
  261.   int bi = (int)PPCGETA(in);
  262.   char y = (char)(bo & 1);
  263.   int opercnt = 0;
  264.   char *ext = b_ext[aform*2+(int)(in&1)];
  265.  
  266.   if (bdisp < 0)
  267.     y ^= 1;
  268.   y = y ? '+':'-';
  269.  
  270.   if (bo & 4) {
  271.     /* standard case - no decrement */
  272.     if (bo & 16) {
  273.       /* branch always */
  274.       if (PPCGETIDX(in) != 16) {
  275.         sprintf(dp->opcode,"b%s%s",bname,ext);
  276.       }
  277.       else {
  278.         sprintf(dp->opcode,"bc%s",ext);
  279.         opercnt = sprintf(dp->operands,"%d,%d",bo,bi);
  280.       }
  281.     }
  282.     else {
  283.       /* branch conditional */
  284.       sprintf(dp->opcode,"b%s%s%s%c",b_condition[((bo&8)>>1)+(bi&3)],
  285.               bname,ext,y);
  286.       if (bi >= 4)
  287.         opercnt = sprintf(dp->operands,"cr%d",bi>>2);
  288.     }
  289.   }
  290.  
  291.   else {
  292.     /* CTR is decremented and checked */
  293.     sprintf(dp->opcode,"bd%s%s%s%c",b_decr[bo>>1],bname,ext,y);
  294.     if (!(bo & 16))
  295.       opercnt = sprintf(dp->operands,"%d",bi);
  296.   }
  297.  
  298.   return (opercnt);
  299. }
  300.  
  301.  
  302. static void bc(struct DisasmPara_PPC *dp,ppc_word in)
  303. {
  304.   int d = (int)(in & 0xfffc);
  305.   int offs;
  306.   char *oper = dp->operands;
  307.  
  308.   if (d >= 0x8000)
  309.     d -= 0x10000;
  310.   if (offs = branch(dp,in,"",(in&2)?1:0,d)) {
  311.     oper += offs;
  312.     *oper++ = ',';
  313.   }
  314.   if (in & 2)  /* AA ? */
  315.     sprintf(dp->operands,"0x%lx",(unsigned long)d);
  316.   else
  317.     sprintf(oper,"0x%lx",(unsigned long)((char *)dp->iaddr + d));
  318.   dp->type = PPCINSTR_BRANCH;
  319.   dp->displacement = (ppc_word)d;
  320. }
  321.  
  322.  
  323. static void bli(struct DisasmPara_PPC *dp,ppc_word in)
  324. {
  325.   int d = (int)(in & 0x3fffffc);
  326.  
  327.   if (d >= 0x2000000)
  328.     d -= 0x4000000;
  329.   sprintf(dp->opcode,"b%s",b_ext[in&3]);
  330.   if (in & 2)  /* AA ? */
  331.     sprintf(dp->operands,"0x%lx",(unsigned long)d);
  332.   else
  333.     sprintf(dp->operands,"0x%lx",(unsigned long)((char *)dp->iaddr + d));
  334.   dp->type = PPCINSTR_BRANCH;
  335.   dp->displacement = (ppc_word)d;
  336. }
  337.  
  338.  
  339. static void mcrf(struct DisasmPara_PPC *dp,ppc_word in,char c)
  340. {
  341.   if (!(in & 0x0063f801)) {
  342.     sprintf(dp->opcode,"mcrf%c",c);
  343.     sprintf(dp->operands,"cr%d,cr%d",(int)PPCGETCRD(in),(int)PPCGETCRA(in));
  344.   }
  345.   else
  346.     ill(dp,in);
  347. }
  348.  
  349.  
  350. static void crop(struct DisasmPara_PPC *dp,ppc_word in,char *n1,char *n2)
  351. {
  352.   int crd = (int)PPCGETD(in);
  353.   int cra = (int)PPCGETA(in);
  354.   int crb = (int)PPCGETB(in);
  355.  
  356.   if (!(in & 1)) {
  357.     sprintf(dp->opcode,"cr%s",(cra==crb && n2)?n2:n1);
  358.     if (cra == crb && n2)
  359.       sprintf(dp->operands,"%d,%d",crd,cra);
  360.     else
  361.       sprintf(dp->operands,"%d,%d,%d",crd,cra,crb);
  362.   }
  363.   else
  364.     ill(dp,in);
  365. }
  366.  
  367.  
  368. static void nooper(struct DisasmPara_PPC *dp,ppc_word in,char *name,
  369.                    unsigned char dmode)
  370. {
  371.   if (in & (PPCDMASK|PPCAMASK|PPCBMASK|1)) {
  372.     ill(dp,in);
  373.   }
  374.   else {
  375.     dp->flags |= dmode;
  376.     strcpy(dp->opcode,name);
  377.   }
  378. }
  379.  
  380.  
  381. static void rlw(struct DisasmPara_PPC *dp,ppc_word in,char *name,int i)
  382. {
  383.   int s = (int)PPCGETD(in);
  384.   int a = (int)PPCGETA(in);
  385.   int bsh = (int)PPCGETB(in);
  386.   int mb = (int)PPCGETC(in);
  387.   int me = (int)PPCGETM(in);
  388.  
  389.   sprintf(dp->opcode,"rlw%s%c",name,in&1?'.':'\0');
  390.   sprintf(dp->operands,"r%d,r%d,%s%d,%d,%d",a,s,regsel[i],bsh,mb,me);
  391. }
  392.  
  393.  
  394. static void ori(struct DisasmPara_PPC *dp,ppc_word in,char *name)
  395. {
  396.   strcpy(dp->opcode,name);
  397.   imm(dp,in,1,1);
  398. }
  399.  
  400.  
  401. static void rld(struct DisasmPara_PPC *dp,ppc_word in,char *name,int i)
  402. {
  403.   int s = (int)PPCGETD(in);
  404.   int a = (int)PPCGETA(in);
  405.   int bsh = i ? (int)PPCGETB(in) : (int)(((in&2)<<4)+PPCGETB(in));
  406.   int m = (int)(in&0x7e0)>>5;
  407.  
  408.   dp->flags |= PPCF_64;
  409.   sprintf(dp->opcode,"rld%s%c",name,in&1?'.':'\0');
  410.   sprintf(dp->operands,"r%d,r%d,%s%d,%d",a,s,regsel[i],bsh,m);
  411. }
  412.  
  413.  
  414. static void cmp(struct DisasmPara_PPC *dp,ppc_word in)
  415. {
  416.   char *oper = dp->operands;
  417.   int i = (int)PPCGETL(in);
  418.  
  419.   if (i < 2) {
  420.     if (i)
  421.       dp->flags |= PPCF_64;
  422.     strcpy(dp->opcode,cmpname[((in&PPCIDX2MASK)?2:0)+i]);
  423.     if (i = (int)PPCGETCRD(in))
  424.       oper += sprintf(oper,"cr%c,",'0'+i);
  425.     ra_rb(oper,in);
  426.   }
  427.   else
  428.     ill(dp,in);
  429. }
  430.  
  431.  
  432. static void trap(struct DisasmPara_PPC *dp,ppc_word in,unsigned char dmode)
  433. {
  434.   char *cnd;
  435.   int to = (int)PPCGETD(in);
  436.  
  437.   if (cnd = trap_condition[to]) {
  438.     dp->flags |= dmode;
  439.     sprintf(dp->opcode,"t%c%s",dmode?'d':'w',cnd);
  440.     ra_rb(dp->operands,in);
  441.   }
  442.   else {
  443.     if (to == 31) {
  444.       if (dmode) {
  445.         dp->flags |= dmode;
  446.         strcpy(dp->opcode,"td");
  447.         strcpy(dp->operands,"31,0,0");
  448.       }
  449.       else
  450.         strcpy(dp->opcode,"trap");
  451.     }
  452.     else
  453.       ill(dp,in);
  454.   }
  455. }
  456.  
  457.  
  458. static void dab(struct DisasmPara_PPC *dp,ppc_word in,char *name,int mask,
  459.                 int smode,int chkoe,int chkrc,unsigned char dmode)
  460. /* standard instruction: xxxx rD,rA,rB */
  461. {
  462.   if (chkrc>=0 && (in&1)!=chkrc) {
  463.     ill(dp,in);
  464.   }
  465.   else {
  466.     dp->flags |= dmode;
  467.     if (smode)
  468.       in = swapda(in);  /* rA,rS,rB */
  469.     sprintf(dp->opcode,"%s%s%s",name,
  470.             oesel[chkoe&&(in&PPCOE)],rcsel[(chkrc<0)&&(in&1)]);
  471.     rd_ra_rb(dp->operands,in,mask);
  472.   }
  473. }
  474.  
  475.  
  476. static void rrn(struct DisasmPara_PPC *dp,ppc_word in,char *name,
  477.                 int smode,int chkoe,int chkrc,unsigned char dmode)
  478. /* Last operand is no register: xxxx rD,rA,NB */
  479. {
  480.   char *s;
  481.  
  482.   if (chkrc>=0 && (in&1)!=chkrc) {
  483.     ill(dp,in);
  484.   }
  485.   else {
  486.     dp->flags |= dmode;
  487.     if (smode)
  488.       in = swapda(in);  /* rA,rS,NB */
  489.     sprintf(dp->opcode,"%s%s%s",name,
  490.             oesel[chkoe&&(in&PPCOE)],rcsel[(chkrc<0)&&(in&1)]);
  491.     s = rd_ra_rb(dp->operands,in,6);
  492.     sprintf(s,",%d",(int)PPCGETB(in));
  493.   }
  494. }
  495.  
  496.  
  497. static void mtcr(struct DisasmPara_PPC *dp,ppc_word in)
  498. {
  499.   int s = (int)PPCGETD(in);
  500.   int crm = (int)(in&0x000ff000)>>12;
  501.   char *oper = dp->operands;
  502.  
  503.   if (in & 0x00100801) {
  504.     ill(dp,in);
  505.   }
  506.   else {
  507.     sprintf(dp->opcode,"mtcr%c",crm==0xff?'\0':'f');
  508.     if (crm != 0xff)
  509.       oper += sprintf(oper,"0x%02x,",crm);
  510.     sprintf(oper,"r%d",s);
  511.   }
  512. }
  513.  
  514.  
  515. static void msr(struct DisasmPara_PPC *dp,ppc_word in,int smode)
  516. {
  517.   int s = (int)PPCGETD(in);
  518.   int sr = (int)(in&0x000f0000)>>16;
  519.  
  520.   if (in & 0x0010f801) {
  521.     ill(dp,in);
  522.   }
  523.   else {
  524.     dp->flags |= PPCF_SUPER;
  525.     sprintf(dp->opcode,"m%csr",smode?'t':'f');
  526.     if (smode)
  527.       sprintf(dp->operands,"%d,r%d",sr,s);
  528.     else
  529.       sprintf(dp->operands,"r%d,%d",s,sr);
  530.   }
  531. }
  532.  
  533.  
  534. static void mspr(struct DisasmPara_PPC *dp,ppc_word in,int smode)
  535. {
  536.   int d = (int)PPCGETD(in);
  537.   int spr = (int)((PPCGETB(in)<<5)+PPCGETA(in));
  538.   int fmt = 0;
  539.   char *x;
  540.  
  541.   if (in & 1) {
  542.     ill(dp,in);
  543.   }
  544.  
  545.   else {
  546.     if (spr!=1 && spr!=8 && spr!=9)
  547.       dp->flags |= PPCF_SUPER;
  548.     switch (spr) {
  549.       case 1:
  550.         x = "xer";
  551.         break;
  552.       case 8:
  553.         x = "lr";
  554.         break;
  555.       case 9:
  556.         x = "ctr";
  557.         break;
  558.       case 18:
  559.         x = "dsisr";
  560.         break;
  561.       case 19:
  562.         x = "dar";
  563.         break;
  564.       case 22:
  565.         x = "dec";
  566.         break;
  567.       case 25:
  568.         x = "sdr1";
  569.         break;
  570.       case 26:
  571.         x = "srr0";
  572.         break;
  573.       case 27:
  574.         x = "srr1";
  575.         break;
  576.       case 272:
  577.       case 273:
  578.       case 274:
  579.       case 275:
  580.         x = "sprg";
  581.         spr -= 272;
  582.         fmt = 1;
  583.         break;
  584.       case 280:
  585.         x = "asr";
  586.         break;
  587.       case 282:
  588.         x = "ear";
  589.         break;
  590.       case 284:
  591.         x = "tbl";
  592.         break;
  593.       case 285:
  594.         x = "tbu";
  595.         break;
  596.       case 528:
  597.       case 530:
  598.       case 532:
  599.       case 534:
  600.         x = "ibatu";
  601.         spr = (spr-528)>>1;
  602.         fmt = 1;
  603.         break;
  604.       case 529:
  605.       case 531:
  606.       case 533:
  607.       case 535:
  608.         x = "ibatl";
  609.         spr = (spr-529)>>1;
  610.         fmt = 1;
  611.         break;
  612.       case 536:
  613.       case 538:
  614.       case 540:
  615.       case 542:
  616.         x = "dbatu";
  617.         spr = (spr-536)>>1;
  618.         fmt = 1;
  619.         break;
  620.       case 537:
  621.       case 539:
  622.       case 541:
  623.       case 543:
  624.         x = "dbatl";
  625.         spr = (spr-537)>>1;
  626.         fmt = 1;
  627.         break;
  628.       case 1013:
  629.         x = "dabr";
  630.         break;
  631.       default:
  632.         x = "spr";
  633.         fmt = 1;
  634.         break;
  635.     }
  636.  
  637.     sprintf(dp->opcode,"m%c%s",smode?'t':'f',x);
  638.     if (fmt) {
  639.       if (smode)
  640.         sprintf(dp->operands,"%d,r%d",spr,d);
  641.       else
  642.         sprintf(dp->operands,"r%d,%d",d,spr);
  643.     }
  644.     else
  645.       sprintf(dp->operands,"r%d",d);
  646.   }
  647. }
  648.  
  649.  
  650. static void mtb(struct DisasmPara_PPC *dp,ppc_word in)
  651. {
  652.   int d = (int)PPCGETD(in);
  653.   int tbr = (int)((PPCGETB(in)<<5)+PPCGETA(in));
  654.   char *s = dp->operands;
  655.   char x;
  656.  
  657.   if (in & 1) {
  658.     ill(dp,in);
  659.   }
  660.  
  661.   else {
  662.     s += sprintf(s,"r%d",d);
  663.     switch (tbr) {
  664.       case 268:
  665.         x = 'l';
  666.         break;
  667.       case 269:
  668.         x = 'u';
  669.         break;
  670.       default:
  671.         x = '\0';
  672.         dp->flags |= PPCF_SUPER;
  673.         sprintf(s,",%d",tbr);
  674.         break;
  675.     }
  676.     sprintf(dp->opcode,"mftb%c",x);
  677.   }
  678. }
  679.  
  680.  
  681. static void sradi(struct DisasmPara_PPC *dp,ppc_word in)
  682. {
  683.   int s = (int)PPCGETD(in);
  684.   int a = (int)PPCGETA(in);
  685.   int bsh = (int)(((in&2)<<4)+PPCGETB(in));
  686.  
  687.   dp->flags |= PPCF_64;
  688.   sprintf(dp->opcode,"sradi%c",in&1?'.':'\0');
  689.   sprintf(dp->operands,"r%d,r%d,%d",a,s,bsh);
  690. }
  691.  
  692.  
  693. static void ldst(struct DisasmPara_PPC *dp,ppc_word in,char *name,
  694.                  char reg,unsigned char dmode)
  695. {
  696.   int s = (int)PPCGETD(in);
  697.   int a = (int)PPCGETA(in);
  698.   int d = (ppc_word)(in & 0xffff);
  699.  
  700.   dp->type = PPCINSTR_LDST;
  701.   dp->flags |= dmode;
  702.   dp->sreg = (short)a;
  703.   if (d >= 0x8000)
  704.     d -= 0x10000;
  705.   dp->displacement = (ppc_word)d;
  706.   strcpy(dp->opcode,name);
  707.   sprintf(dp->operands,"%c%d,%d(r%d)",reg,s,d,a);
  708. }
  709.  
  710.  
  711. static void fdabc(struct DisasmPara_PPC *dp,ppc_word in,char *name,
  712.                   int mask,unsigned char dmode)
  713. /* standard floating point instruction: xxxx fD,fA,fB,fC */
  714. {
  715.   static const char *fmt = "f%d,";
  716.   char *s = dp->operands;
  717.   int err = 0;
  718.  
  719.   dp->flags |= dmode;
  720.   sprintf(dp->opcode,"f%s%s",name,rcsel[in&1]);
  721.   s += sprintf(s,fmt,(int)PPCGETD(in));
  722.   if (mask & 4)
  723.     s += sprintf(s,fmt,(int)PPCGETA(in));
  724.   else
  725.     err |= (int)PPCGETA(in);
  726.   if (mask & 2)
  727.     s += sprintf(s,fmt,(int)PPCGETB(in));
  728.   else if (PPCGETB(in))
  729.     err |= (int)PPCGETB(in);
  730.   if (mask & 1)
  731.     s += sprintf(s,fmt,(int)PPCGETC(in));
  732.   else if (!(mask&8))
  733.     err |= (int)PPCGETC(in);
  734.   *(s-1) = '\0';
  735.   if (err)
  736.     ill(dp,in);
  737. }
  738.  
  739.  
  740. static void fdab(struct DisasmPara_PPC *dp,ppc_word in,char *name,int mask)
  741. /* indexed float instruction: xxxx fD,rA,rB */
  742. {
  743.   strcpy(dp->opcode,name);
  744.   fd_ra_rb(dp->operands,in,mask);
  745. }
  746.  
  747.  
  748. static void fcmp(struct DisasmPara_PPC *dp,ppc_word in,char c)
  749. {
  750.   if (in & 0x00600001) {
  751.     ill(dp,in);
  752.   }
  753.   else {
  754.     sprintf(dp->opcode,"fcmp%c",c);
  755.     sprintf(dp->operands,"cr%d,f%d,f%d",(int)PPCGETCRD(in),
  756.             (int)PPCGETA(in),(int)PPCGETB(in));
  757.   }
  758. }
  759.  
  760.  
  761. static void mtfsb(struct DisasmPara_PPC *dp,ppc_word in,int n)
  762. {
  763.   if (in & (PPCAMASK|PPCBMASK)) {
  764.     ill(dp,in);
  765.   }
  766.   else {
  767.     sprintf(dp->opcode,"mtfsb%d%s",n,rcsel[in&1]);
  768.     sprintf(dp->operands,"%d",(int)PPCGETD(in));
  769.   }
  770. }
  771.  
  772.  
  773. ppc_word *PPC_Disassemble(struct DisasmPara_PPC *dp)
  774. /* Disassemble PPC instruction and return a pointer to the next */
  775. /* instruction, or NULL if an error occured. */
  776. {
  777.   ppc_word in = *(dp->instr);
  778.  
  779.   if (dp->opcode==NULL || dp->operands==NULL)
  780.     return (NULL);  /* no buffers */
  781.  
  782. #ifdef LITTLEENDIAN
  783.   in = (in & 0xff)<<24 | (in & 0xff00)<<8 | (in & 0xff0000)>>8 |
  784.        (in & 0xff000000)>>24;
  785. #endif
  786.   dp->type = PPCINSTR_OTHER;
  787.   dp->flags = 0;
  788.   *(dp->operands) = 0;
  789.  
  790.   switch (PPCGETIDX(in)) {
  791.     case 2:
  792.       trapi(dp,in,PPCF_64);  /* tdi */
  793.       break;
  794.  
  795.     case 3:
  796.       trapi(dp,in,0);  /* twi */
  797.       break;
  798.  
  799.     case 7: 
  800.       strcpy(dp->opcode,"mulli");
  801.       imm(dp,in,0,0);
  802.       break;
  803.  
  804.     case 8:
  805.       strcpy(dp->opcode,"subfic");
  806.       imm(dp,in,0,0);
  807.       break;
  808.  
  809.     case 10:
  810.       cmpi(dp,in,1);  /* cmpli */
  811.       break;
  812.  
  813.     case 11:
  814.       cmpi(dp,in,0);  /* cmpi */
  815.       break;
  816.  
  817.     case 12:
  818.       addi(dp,in,"ic");  /* addic */
  819.       break;
  820.  
  821.     case 13:
  822.       addi(dp,in,"ic.");  /* addic. */
  823.       break;
  824.  
  825.     case 14:
  826.       addi(dp,in,"i");  /* addi */
  827.       break;
  828.  
  829.     case 15:
  830.       addi(dp,in,"is");  /* addis */
  831.       break;
  832.  
  833.     case 16:
  834.       bc(dp,in);
  835.       break;
  836.  
  837.     case 17:
  838.       if ((in & ~PPCIDXMASK) == 2)
  839.         strcpy(dp->opcode,"sc");
  840.       else
  841.         ill(dp,in);
  842.       break;
  843.  
  844.     case 18:
  845.       bli(dp,in);
  846.       break;
  847.  
  848.     case 19:
  849.       switch (PPCGETIDX2(in)) {
  850.         case 0:
  851.           mcrf(dp,in,'\0');  /* mcrf */
  852.           break;
  853.  
  854.         case 16:
  855.           branch(dp,in,"lr",0,0);  /* bclr */
  856.           break;
  857.  
  858.         case 33:
  859.           crop(dp,in,"nor","not");  /* crnor */
  860.           break;
  861.  
  862.         case 50:
  863.           nooper(dp,in,"rfi",PPCF_SUPER);
  864.           break;
  865.  
  866.         case 129:
  867.           crop(dp,in,"andc",NULL);  /* crandc */
  868.           break;
  869.  
  870.         case 150:
  871.           nooper(dp,in,"isync",0);
  872.           break;
  873.  
  874.         case 193:
  875.           crop(dp,in,"xor","clr");  /* crxor */
  876.           break;
  877.  
  878.         case 225:
  879.           crop(dp,in,"nand",NULL);  /* crnand */
  880.           break;
  881.  
  882.         case 257:
  883.           crop(dp,in,"and",NULL);  /* crand */
  884.           break;
  885.  
  886.         case 289:
  887.           crop(dp,in,"eqv","set");  /* creqv */
  888.           break;
  889.  
  890.         case 417:
  891.           crop(dp,in,"orc",NULL);  /* crorc */
  892.           break;
  893.  
  894.         case 449:
  895.           crop(dp,in,"or","move");  /* cror */
  896.           break;
  897.  
  898.         case 528:
  899.           branch(dp,in,"ctr",0,0);  /* bcctr */
  900.           break;
  901.  
  902.         default:
  903.           ill(dp,in);
  904.           break;
  905.       }
  906.       break;
  907.  
  908.     case 20:
  909.       rlw(dp,in,"imi",0);  /* rlwimi */
  910.       break;
  911.  
  912.     case 21:
  913.       rlw(dp,in,"inm",0);  /* rlwinm */
  914.       break;
  915.  
  916.     case 23:
  917.       rlw(dp,in,"nm",1);  /* rlwnm */
  918.       break;
  919.  
  920.     case 24:
  921.       if (in & ~PPCIDXMASK)
  922.         ori(dp,in,"ori");
  923.       else
  924.         strcpy(dp->opcode,"nop");
  925.       break;
  926.  
  927.     case 25:
  928.       ori(dp,in,"oris");
  929.       break;
  930.  
  931.     case 26:
  932.       ori(dp,in,"xori");
  933.       break;
  934.  
  935.     case 27:
  936.       ori(dp,in,"xoris");
  937.       break;
  938.  
  939.     case 28:
  940.       ori(dp,in,"andi.");
  941.       break;
  942.  
  943.     case 29:
  944.       ori(dp,in,"andis.");
  945.       break;
  946.  
  947.     case 30:
  948.       switch (in & 0x1c) {
  949.         case 0:
  950.           rld(dp,in,"icl",0);  /* rldicl */
  951.           break;
  952.         case 1:
  953.           rld(dp,in,"icr",0);  /* rldicr */
  954.           break;
  955.         case 2:
  956.           rld(dp,in,"ic",0);   /* rldic */
  957.           break;
  958.         case 3:
  959.           rld(dp,in,"imi",0);  /* rldimi */
  960.           break;
  961.         case 4:
  962.           rld(dp,in,in&2?"cl":"cr",1);  /* rldcl, rldcr */
  963.           break;
  964.         default:
  965.           ill(dp,in);
  966.           break;
  967.       }
  968.       break;
  969.  
  970.     case 31:
  971.       switch (PPCGETIDX2(in)) {
  972.         case 0:
  973.         case 32:
  974.           if (in & 1)
  975.             ill(dp,in);
  976.           else
  977.             cmp(dp,in);  /* cmp, cmpl */
  978.           break;
  979.  
  980.         case 4:
  981.           if (in & 1)
  982.             ill(dp,in);
  983.           else
  984.             trap(dp,in,0);  /* tw */
  985.           break;
  986.  
  987.         case 8:
  988.         case (PPCOE>>1)+8:
  989.           dab(dp,swapab(in),"subc",7,0,1,-1,0);
  990.           break;
  991.  
  992.         case 9:
  993.           dab(dp,in,"mulhdu",7,0,0,-1,PPCF_64);
  994.           break;
  995.  
  996.         case 10:
  997.         case (PPCOE>>1)+10:
  998.           dab(dp,in,"addc",7,0,1,-1,0);
  999.           break;
  1000.  
  1001.         case 11:
  1002.           dab(dp,in,"mulhwu",7,0,0,-1,0);
  1003.           break;
  1004.  
  1005.         case 19:
  1006.           if (in & (PPCAMASK|PPCBMASK))
  1007.             ill(dp,in);
  1008.           else
  1009.             dab(dp,in,"mfcr",4,0,0,0,0);
  1010.           break;
  1011.  
  1012.         case 20:
  1013.           dab(dp,in,"lwarx",7,0,0,0,0);
  1014.           break;
  1015.  
  1016.         case 21:
  1017.           dab(dp,in,"ldx",7,0,0,0,PPCF_64);
  1018.           break;
  1019.  
  1020.         case 23:
  1021.           dab(dp,in,"lwzx",7,0,0,0,0);
  1022.           break;
  1023.  
  1024.         case 24:
  1025.           dab(dp,in,"slw",7,1,0,-1,0);
  1026.           break;
  1027.  
  1028.         case 26:
  1029.           if (in & PPCBMASK)
  1030.             ill(dp,in);
  1031.           else
  1032.             dab(dp,in,"cntlzw",6,1,0,-1,0);
  1033.           break;
  1034.  
  1035.         case 27:
  1036.           dab(dp,in,"sld",7,1,0,-1,PPCF_64);
  1037.           break;
  1038.  
  1039.         case 28:
  1040.           dab(dp,in,"and",7,1,0,-1,0);
  1041.           break;
  1042.  
  1043.         case 40:
  1044.         case (PPCOE>>1)+40:
  1045.           dab(dp,swapab(in),"sub",7,0,1,-1,0);
  1046.           break;
  1047.  
  1048.         case 53:
  1049.           dab(dp,in,"ldux",7,0,0,0,PPCF_64);
  1050.           break;
  1051.  
  1052.         case 54:
  1053.           if (in & PPCDMASK)
  1054.             ill(dp,in);
  1055.           else
  1056.             dab(dp,in,"dcbst",3,0,0,0,0);
  1057.           break;
  1058.  
  1059.         case 55:
  1060.           dab(dp,in,"lwzux",7,0,0,0,0);
  1061.           break;
  1062.  
  1063.         case 58:
  1064.           if (in & PPCBMASK)
  1065.             ill(dp,in);
  1066.           else
  1067.             dab(dp,in,"cntlzd",6,1,0,-1,PPCF_64);
  1068.           break;
  1069.  
  1070.         case 60:
  1071.           dab(dp,in,"andc",7,1,0,-1,0);
  1072.           break;
  1073.  
  1074.         case 68:
  1075.           trap(dp,in,PPCF_64);  /* td */
  1076.           break;
  1077.  
  1078.         case 73:
  1079.           dab(dp,in,"mulhd",7,0,0,-1,PPCF_64);
  1080.           break;
  1081.  
  1082.         case 75:
  1083.           dab(dp,in,"mulhw",7,0,0,-1,0);
  1084.           break;
  1085.  
  1086.         case 83:
  1087.           if (in & (PPCAMASK|PPCBMASK))
  1088.             ill(dp,in);
  1089.           else
  1090.             dab(dp,in,"mfmsr",4,0,0,0,PPCF_SUPER);
  1091.           break;
  1092.  
  1093.         case 84:
  1094.           dab(dp,in,"ldarx",7,0,0,0,PPCF_64);
  1095.           break;
  1096.  
  1097.         case 86:
  1098.           if (in & PPCDMASK)
  1099.             ill(dp,in);
  1100.           else
  1101.             dab(dp,in,"dcbf",3,0,0,0,0);
  1102.           break;
  1103.  
  1104.         case 87:
  1105.           dab(dp,in,"lbzx",7,0,0,0,0);
  1106.           break;
  1107.  
  1108.         case 104:
  1109.         case (PPCOE>>1)+104:
  1110.           if (in & PPCBMASK)
  1111.             ill(dp,in);
  1112.           else
  1113.             dab(dp,in,"neg",6,0,1,-1,0);
  1114.           break;
  1115.  
  1116.         case 119:
  1117.           dab(dp,in,"lbzux",7,0,0,0,0);
  1118.           break;
  1119.  
  1120.         case 124:
  1121.           if (PPCGETD(in) == PPCGETB(in))
  1122.             dab(dp,in,"not",6,1,0,-1,0);
  1123.           else
  1124.             dab(dp,in,"nor",7,1,0,-1,0);
  1125.           break;
  1126.  
  1127.         case 136:
  1128.         case (PPCOE>>1)+136:
  1129.           dab(dp,in,"subfe",7,0,1,-1,0);
  1130.           break;
  1131.  
  1132.         case 138:
  1133.         case (PPCOE>>1)+138:
  1134.           dab(dp,in,"adde",7,0,1,-1,0);
  1135.           break;
  1136.  
  1137.         case 144:
  1138.           mtcr(dp,in);
  1139.           break;
  1140.  
  1141.         case 146:
  1142.           if (in & (PPCAMASK|PPCBMASK))
  1143.             ill(dp,in);
  1144.           else
  1145.             dab(dp,in,"mtmsr",4,0,0,0,PPCF_SUPER);
  1146.           break;
  1147.  
  1148.         case 149:
  1149.           dab(dp,in,"stdx",7,0,0,0,PPCF_64);
  1150.           break;
  1151.  
  1152.         case 150:
  1153.           dab(dp,in,"stwcx.",7,0,0,1,0);
  1154.           break;
  1155.  
  1156.         case 151:
  1157.           dab(dp,in,"stwx",7,0,0,0,0);
  1158.           break;
  1159.  
  1160.         case 181:
  1161.           dab(dp,in,"stdux",7,0,0,0,PPCF_64);
  1162.           break;
  1163.  
  1164.         case 183:
  1165.           dab(dp,in,"stwux",7,0,0,0,0);
  1166.           break;
  1167.  
  1168.         case 200:
  1169.         case (PPCOE>>1)+200:
  1170.           if (in & PPCBMASK)
  1171.             ill(dp,in);
  1172.           else
  1173.             dab(dp,in,"subfze",6,0,1,-1,0);
  1174.           break;
  1175.  
  1176.         case 202:
  1177.         case (PPCOE>>1)+202:
  1178.           if (in & PPCBMASK)
  1179.             ill(dp,in);
  1180.           else
  1181.             dab(dp,in,"addze",6,0,1,-1,0);
  1182.           break;
  1183.  
  1184.         case 210:
  1185.           msr(dp,in,1);  /* mfsr */
  1186.           break;
  1187.  
  1188.         case 214:
  1189.           dab(dp,in,"stdcx.",7,0,0,1,PPCF_64);
  1190.           break;
  1191.  
  1192.         case 215:
  1193.           dab(dp,in,"stbx",7,0,0,0,0);
  1194.           break;
  1195.  
  1196.         case 232:
  1197.         case (PPCOE>>1)+232:
  1198.           if (in & PPCBMASK)
  1199.             ill(dp,in);
  1200.           else
  1201.             dab(dp,in,"subfme",6,0,1,-1,0);
  1202.           break;
  1203.  
  1204.         case 233:
  1205.         case (PPCOE>>1)+233:
  1206.           dab(dp,in,"mulld",7,0,1,-1,PPCF_64);
  1207.           break;
  1208.  
  1209.         case 234:
  1210.         case (PPCOE>>1)+234:
  1211.           if (in & PPCBMASK)
  1212.             ill(dp,in);
  1213.           else
  1214.             dab(dp,in,"addme",6,0,1,-1,0);
  1215.           break;
  1216.  
  1217.         case 235:
  1218.         case (PPCOE>>1)+235:
  1219.           dab(dp,in,"mullw",7,0,1,-1,0);
  1220.           break;
  1221.  
  1222.         case 242:
  1223.           if (in & PPCAMASK)
  1224.             ill(dp,in);
  1225.           else
  1226.             dab(dp,in,"mtsrin",5,0,0,0,PPCF_SUPER);
  1227.           break;
  1228.  
  1229.         case 246:
  1230.           if (in & PPCDMASK)
  1231.             ill(dp,in);
  1232.           else
  1233.             dab(dp,in,"dcbtst",3,0,0,0,0);
  1234.           break;
  1235.  
  1236.         case 247:
  1237.           dab(dp,in,"stbux",7,0,0,0,0);
  1238.           break;
  1239.  
  1240.         case 266:
  1241.         case (PPCOE>>1)+266:
  1242.           dab(dp,in,"add",7,0,1,-1,0);
  1243.           break;
  1244.  
  1245.         case 278:
  1246.           if (in & PPCDMASK)
  1247.             ill(dp,in);
  1248.           else
  1249.             dab(dp,in,"dcbt",3,0,0,0,0);
  1250.           break;
  1251.  
  1252.         case 279:
  1253.           dab(dp,in,"lhzx",7,0,0,0,0);
  1254.           break;
  1255.  
  1256.         case 284:
  1257.           dab(dp,in,"eqv",7,1,0,-1,0);
  1258.           break;
  1259.  
  1260.         case 306:
  1261.           if (in & (PPCDMASK|PPCAMASK))
  1262.             ill(dp,in);
  1263.           else
  1264.             dab(dp,in,"tlbie",1,0,0,0,PPCF_SUPER);
  1265.           break;
  1266.  
  1267.         case 310:
  1268.           dab(dp,in,"eciwx",7,0,0,0,0);
  1269.           break;
  1270.  
  1271.         case 311:
  1272.           dab(dp,in,"lhzux",7,0,0,0,0);
  1273.           break;
  1274.  
  1275.         case 316:
  1276.           dab(dp,in,"xor",7,1,0,-1,0);
  1277.           break;
  1278.  
  1279.         case 339:
  1280.           mspr(dp,in,0);  /* mfspr */
  1281.           break;
  1282.  
  1283.         case 341:
  1284.           dab(dp,in,"lwax",7,0,0,0,PPCF_64);
  1285.           break;
  1286.  
  1287.         case 343:
  1288.           dab(dp,in,"lhax",7,0,0,0,0);
  1289.           break;
  1290.  
  1291.         case 370:
  1292.           nooper(dp,in,"tlbia",PPCF_SUPER);
  1293.           break;
  1294.  
  1295.         case 371:
  1296.           mtb(dp,in);  /* mftb */
  1297.           break;
  1298.  
  1299.         case 373:
  1300.           dab(dp,in,"lwaux",7,0,0,0,PPCF_64);
  1301.           break;
  1302.  
  1303.         case 375:
  1304.           dab(dp,in,"lhaux",7,0,0,0,0);
  1305.           break;
  1306.  
  1307.         case 407:
  1308.           dab(dp,in,"sthx",7,0,0,0,0);
  1309.           break;
  1310.  
  1311.         case 412:
  1312.           dab(dp,in,"orc",7,1,0,-1,0);
  1313.           break;
  1314.  
  1315.         case 413:
  1316.           sradi(dp,in);  /* sradi */
  1317.           break;
  1318.  
  1319.         case 434:
  1320.           if (in & (PPCDMASK|PPCAMASK))
  1321.             ill(dp,in);
  1322.           else
  1323.             dab(dp,in,"slbie",1,0,0,0,PPCF_SUPER|PPCF_64);
  1324.           break;
  1325.  
  1326.         case 438:
  1327.           dab(dp,in,"ecowx",7,0,0,0,0);
  1328.           break;
  1329.  
  1330.         case 439:
  1331.           dab(dp,in,"sthux",7,0,0,0,0);
  1332.           break;
  1333.  
  1334.         case 444:
  1335.           if (PPCGETD(in) == PPCGETB(in))
  1336.             dab(dp,in,"mr",6,1,0,-1,0);
  1337.           else
  1338.             dab(dp,in,"or",7,1,0,-1,0);
  1339.           break;
  1340.  
  1341.         case 457:
  1342.         case (PPCOE>>1)+457:
  1343.           dab(dp,in,"divdu",7,0,1,-1,PPCF_64);
  1344.           break;
  1345.  
  1346.         case 459:
  1347.         case (PPCOE>>1)+459:
  1348.           dab(dp,in,"divwu",7,0,1,-1,0);
  1349.           break;
  1350.  
  1351.         case 467:
  1352.           mspr(dp,in,1);  /* mtspr */
  1353.           break;
  1354.  
  1355.         case 470:
  1356.           if (in & PPCDMASK)
  1357.             ill(dp,in);
  1358.           else
  1359.             dab(dp,in,"dcbi",3,0,0,0,0);
  1360.           break;
  1361.  
  1362.         case 476:
  1363.           dab(dp,in,"nand",7,1,0,-1,0);
  1364.           break;
  1365.  
  1366.         case 489:
  1367.         case (PPCOE>>1)+489:
  1368.           dab(dp,in,"divd",7,0,1,-1,PPCF_64);
  1369.           break;
  1370.  
  1371.         case 491:
  1372.         case (PPCOE>>1)+491:
  1373.           dab(dp,in,"divw",7,0,1,-1,0);
  1374.           break;
  1375.  
  1376.         case 498:
  1377.           nooper(dp,in,"slbia",PPCF_SUPER|PPCF_64);
  1378.           break;
  1379.  
  1380.         case 512:
  1381.           if (in & 0x007ff801)
  1382.             ill(dp,in);
  1383.           else {
  1384.             strcpy(dp->opcode,"mcrxr");
  1385.             sprintf(dp->operands,"cr%d",(int)PPCGETCRD(in));
  1386.           }
  1387.           break;
  1388.  
  1389.         case 533:
  1390.           dab(dp,in,"lswx",7,0,0,0,0);
  1391.           break;
  1392.  
  1393.         case 534:
  1394.           dab(dp,in,"lwbrx",7,0,0,0,0);
  1395.           break;
  1396.  
  1397.         case 535:
  1398.           fdab(dp,in,"lfsx",7);
  1399.           break;
  1400.  
  1401.         case 536:
  1402.           dab(dp,in,"srw",7,1,0,-1,0);
  1403.           break;
  1404.  
  1405.         case 539:
  1406.           dab(dp,in,"srd",7,1,0,-1,PPCF_64);
  1407.           break;
  1408.  
  1409.         case 566:
  1410.           nooper(dp,in,"tlbsync",PPCF_SUPER);
  1411.           break;
  1412.  
  1413.         case 567:
  1414.           fdab(dp,in,"lfsux",7);
  1415.           break;
  1416.  
  1417.         case 595:
  1418.           msr(dp,in,0);  /* mfsr */
  1419.           break;
  1420.  
  1421.         case 597:
  1422.           rrn(dp,in,"lswi",0,0,0,0);
  1423.           break;
  1424.  
  1425.         case 598:
  1426.           nooper(dp,in,"sync",PPCF_SUPER);
  1427.           break;
  1428.  
  1429.         case 599:
  1430.           fdab(dp,in,"lfdx",7);
  1431.           break;
  1432.  
  1433.         case 631:
  1434.           fdab(dp,in,"lfdux",7);
  1435.           break;
  1436.  
  1437.         case 659:
  1438.           if (in & PPCAMASK)
  1439.             ill(dp,in);
  1440.           else
  1441.             dab(dp,in,"mfsrin",5,0,0,0,PPCF_SUPER);
  1442.           break;
  1443.  
  1444.         case 661:
  1445.           dab(dp,in,"stswx",7,0,0,0,0);
  1446.           break;
  1447.  
  1448.         case 662:
  1449.           dab(dp,in,"stwbrx",7,0,0,0,0);
  1450.           break;
  1451.  
  1452.         case 663:
  1453.           fdab(dp,in,"stfsx",7);
  1454.           break;
  1455.  
  1456.         case 695:
  1457.           fdab(dp,in,"stfsux",7);
  1458.           break;
  1459.  
  1460.         case 725:
  1461.           rrn(dp,in,"stswi",0,0,0,0);
  1462.           break;
  1463.  
  1464.         case 727:
  1465.           fdab(dp,in,"stfdx",7);
  1466.           break;
  1467.  
  1468.         case 759:
  1469.           fdab(dp,in,"stfdux",7);
  1470.           break;
  1471.  
  1472.         case 790:
  1473.           dab(dp,in,"lhbrx",7,0,0,0,0);
  1474.           break;
  1475.  
  1476.         case 792:
  1477.           dab(dp,in,"sraw",7,1,0,-1,0);
  1478.           break;
  1479.  
  1480.         case 794:
  1481.           dab(dp,in,"srad",7,1,0,-1,PPCF_64);
  1482.           break;
  1483.  
  1484.         case 824:
  1485.           rrn(dp,in,"srawi",1,0,-1,0);
  1486.           break;
  1487.  
  1488.         case 854:
  1489.           nooper(dp,in,"eieio",PPCF_SUPER);
  1490.           break;
  1491.  
  1492.         case 918:
  1493.           dab(dp,in,"sthbrx",7,0,0,0,0);
  1494.           break;
  1495.  
  1496.         case 922:
  1497.           if (in & PPCBMASK)
  1498.             ill(dp,in);
  1499.           else
  1500.             dab(dp,in,"extsh",6,1,0,-1,0);
  1501.           break;
  1502.  
  1503.         case 954:
  1504.           if (in & PPCBMASK)
  1505.             ill(dp,in);
  1506.           else
  1507.             dab(dp,in,"extsb",6,1,0,-1,0);
  1508.           break;
  1509.  
  1510.         case 982:
  1511.           if (in & PPCDMASK)
  1512.             ill(dp,in);
  1513.           else
  1514.             dab(dp,in,"icbi",3,0,0,0,0);
  1515.           break;
  1516.  
  1517.         case 983:
  1518.           fdab(dp,in,"stfiwx",7);
  1519.           break;
  1520.  
  1521.         case 986:
  1522.           if (in & PPCBMASK)
  1523.             ill(dp,in);
  1524.           else
  1525.             dab(dp,in,"extsw",6,1,0,-1,PPCF_64);
  1526.           break;
  1527.  
  1528.         case 1014:
  1529.           if (in & PPCDMASK)
  1530.             ill(dp,in);
  1531.           else
  1532.             dab(dp,in,"dcbz",3,0,0,0,0);
  1533.           break;
  1534.  
  1535.         default:
  1536.           ill(dp,in);
  1537.           break;
  1538.       }
  1539.       break;
  1540.  
  1541.     case 32:
  1542.     case 33:
  1543.     case 34:
  1544.     case 35:
  1545.     case 36:
  1546.     case 37:
  1547.     case 38:
  1548.     case 39:
  1549.     case 40:
  1550.     case 41:
  1551.     case 42:
  1552.     case 43:
  1553.     case 44:
  1554.     case 45:
  1555.     case 46:
  1556.     case 47:
  1557.       ldst(dp,in,ldstnames[PPCGETIDX(in)-32],'r',0);
  1558.       break;
  1559.  
  1560.     case 48:
  1561.     case 49:
  1562.     case 50:
  1563.     case 51:
  1564.     case 52:
  1565.     case 53:
  1566.     case 54:
  1567.     case 55:
  1568.       ldst(dp,in,ldstnames[PPCGETIDX(in)-32],'f',0);
  1569.       break;
  1570.  
  1571.     case 58:
  1572.       switch (in & 3) {
  1573.         case 0:
  1574.           ldst(dp,in&~3,"ld",'r',PPCF_64);
  1575.           break;
  1576.         case 1:
  1577.           ldst(dp,in&~3,"ldu",'r',PPCF_64);
  1578.           break;
  1579.         case 2:
  1580.           ldst(dp,in&~3,"lwa",'r',PPCF_64);
  1581.           break;
  1582.         default:
  1583.           ill(dp,in);
  1584.           break;
  1585.       }
  1586.       break;
  1587.  
  1588.     case 59:
  1589.       switch (in & 0x3e) {
  1590.         case 36:
  1591.           fdabc(dp,in,"divs",6,0);
  1592.           break;
  1593.  
  1594.         case 40:
  1595.           fdabc(dp,in,"subs",6,0);
  1596.           break;
  1597.  
  1598.         case 42:
  1599.           fdabc(dp,in,"adds",6,0);
  1600.           break;
  1601.  
  1602.         case 44:
  1603.           fdabc(dp,in,"sqrts",2,0);
  1604.           break;
  1605.  
  1606.         case 48:
  1607.           fdabc(dp,in,"res",2,0);
  1608.           break;
  1609.  
  1610.         case 50:
  1611.           fdabc(dp,in,"muls",5,0);
  1612.           break;
  1613.  
  1614.         case 56:
  1615.           fdabc(dp,in,"msubs",7,0);
  1616.           break;
  1617.  
  1618.         case 58:
  1619.           fdabc(dp,in,"madds",7,0);
  1620.           break;
  1621.  
  1622.         case 60:
  1623.           fdabc(dp,in,"nmsubs",7,0);
  1624.           break;
  1625.  
  1626.         case 62:
  1627.           fdabc(dp,in,"nmadds",7,0);
  1628.           break;
  1629.  
  1630.         default:
  1631.           ill(dp,in);
  1632.           break;
  1633.       }
  1634.       break;
  1635.  
  1636.     case 62:
  1637.       switch (in & 3) {
  1638.         case 0:
  1639.           ldst(dp,in&~3,"std",'r',PPCF_64);
  1640.           break;
  1641.         case 1:
  1642.           ldst(dp,in&~3,"stdu",'r',PPCF_64);
  1643.           break;
  1644.         default:
  1645.           ill(dp,in);
  1646.           break;
  1647.       }
  1648.       break;
  1649.  
  1650.     case 63:
  1651.       if (in & 32) {
  1652.         switch (in & 0x1e) {
  1653.           case 4:
  1654.             fdabc(dp,in,"div",6,0);
  1655.             break;
  1656.  
  1657.           case 8:
  1658.             fdabc(dp,in,"sub",6,0);
  1659.             break;
  1660.  
  1661.           case 10:
  1662.             fdabc(dp,in,"add",6,0);
  1663.             break;
  1664.  
  1665.           case 12:
  1666.             fdabc(dp,in,"sqrt",2,0);
  1667.             break;
  1668.  
  1669.           case 14:
  1670.             fdabc(dp,in,"sel",7,0);
  1671.             break;
  1672.  
  1673.           case 18:
  1674.             fdabc(dp,in,"mul",5,0);
  1675.             break;
  1676.  
  1677.           case 20:
  1678.             fdabc(dp,in,"sqrte",2,0);
  1679.             break;
  1680.  
  1681.           case 24:
  1682.             fdabc(dp,in,"msub",7,0);
  1683.             break;
  1684.  
  1685.           case 26:
  1686.             fdabc(dp,in,"madd",7,0);
  1687.             break;
  1688.  
  1689.           case 28:
  1690.             fdabc(dp,in,"nmsub",7,0);
  1691.             break;
  1692.  
  1693.           case 30:
  1694.             fdabc(dp,in,"nmadd",7,0);
  1695.             break;
  1696.  
  1697.           default:
  1698.             ill(dp,in);
  1699.             break;
  1700.         }
  1701.       }
  1702.  
  1703.       else {
  1704.         switch (PPCGETIDX2(in)) {
  1705.           case 0:
  1706.             fcmp(dp,in,'u');
  1707.             break;
  1708.  
  1709.           case 12:
  1710.             fdabc(dp,in,"rsp",10,0);
  1711.             break;
  1712.  
  1713.           case 14:
  1714.             fdabc(dp,in,"ctiw",10,0);
  1715.             break;
  1716.  
  1717.           case 15:
  1718.             fdabc(dp,in,"ctiwz",10,0);
  1719.             break;
  1720.  
  1721.           case 32:
  1722.             fcmp(dp,in,'o');
  1723.             break;
  1724.  
  1725.           case 38:
  1726.             mtfsb(dp,in,1);
  1727.             break;
  1728.  
  1729.           case 40:
  1730.             fdabc(dp,in,"neg",10,0);
  1731.             break;
  1732.  
  1733.           case 64:
  1734.             mcrf(dp,in,'s');  /* mcrfs */
  1735.             break;
  1736.  
  1737.           case 70:
  1738.             mtfsb(dp,in,0);
  1739.             break;
  1740.  
  1741.           case 72:
  1742.             fdabc(dp,in,"mr",10,0);
  1743.             break;
  1744.  
  1745.           case 134:
  1746.             if (!(in & 0x006f0800)) {
  1747.               sprintf(dp->opcode,"mtfsfi%s",rcsel[in&1]);
  1748.               sprintf(dp->operands,"%d,%d",(int)PPCGETCRD(in),
  1749.                       (int)(in & 0xf000)>>12);
  1750.             }
  1751.             else
  1752.               ill(dp,in);
  1753.             break;
  1754.  
  1755.           case 136:
  1756.             fdabc(dp,in,"nabs",10,0);
  1757.             break;
  1758.  
  1759.           case 264:
  1760.             fdabc(dp,in,"abs",10,0);
  1761.             break;
  1762.  
  1763.           case 583:
  1764.             if (!(in & (PPCAMASK|PPCBMASK))) {
  1765.               sprintf(dp->opcode,"mffs%s",rcsel[in&1]);
  1766.               sprintf(dp->operands,"f%d",(int)PPCGETD(in));
  1767.             }
  1768.             else
  1769.               ill(dp,in);
  1770.             break;
  1771.  
  1772.           case 711:
  1773.             if (!(in & 0x02010000)) {
  1774.               sprintf(dp->opcode,"mtfsf%s",rcsel[in&1]);
  1775.               sprintf(dp->operands,"%d,f%d",
  1776.                       (int)(in & 0x01fe0000)>>17,(int)PPCGETB(in));
  1777.             }
  1778.             else
  1779.               ill(dp,in);
  1780.             break;
  1781.  
  1782.           case 814:
  1783.             fdabc(dp,in,"fctid",10,PPCF_64);
  1784.             break;
  1785.  
  1786.           case 815:
  1787.             fdabc(dp,in,"fctidz",10,PPCF_64);
  1788.             break;
  1789.  
  1790.           case 846:
  1791.             fdabc(dp,in,"fcfid",10,PPCF_64);
  1792.             break;
  1793.  
  1794.           default:
  1795.             ill(dp,in);
  1796.             break;
  1797.         }
  1798.       }
  1799.       break;
  1800.  
  1801.     default:
  1802.       ill(dp,in);
  1803.       break;
  1804.   }
  1805.   return (dp->instr + 1);
  1806. }
  1807.