Back to index

cell-binutils  2.17cvs20070401
crx-dis.c
Go to the documentation of this file.
00001 /* Disassembler code for CRX.
00002    Copyright 2004, 2005 Free Software Foundation, Inc.
00003    Contributed by Tomer Levi, NSC, Israel.
00004    Written by Tomer Levi.
00005 
00006    This file is part of the GNU binutils and GDB, the GNU debugger.
00007 
00008    This program is free software; you can redistribute it and/or modify it under
00009    the terms of the GNU General Public License as published by the Free
00010    Software Foundation; either version 2, or (at your option)
00011    any later version.
00012 
00013    This program is distributed in the hope that it will be useful, but WITHOUT
00014    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00015    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
00016    more details.
00017 
00018    You should have received a copy of the GNU General Public License
00019    along with this program; if not, write to the Free Software
00020    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
00021 
00022 #include "dis-asm.h"
00023 #include "sysdep.h"
00024 #include "opcode/crx.h"
00025 
00026 /* String to print when opcode was not matched.  */
00027 #define ILLEGAL      "illegal"
00028   /* Escape to 16-bit immediate.  */
00029 #define ESCAPE_16_BIT  0xE
00030 
00031 /* Extract 'n_bits' from 'a' starting from offset 'offs'.  */
00032 #define EXTRACT(a, offs, n_bits)       \
00033   (n_bits == 32 ? (((a) >> (offs)) & 0xffffffffL)   \
00034   : (((a) >> (offs)) & ((1 << (n_bits)) -1)))
00035 
00036 /* Set Bit Mask - a mask to set all bits starting from offset 'offs'.  */
00037 #define SBM(offs)  ((((1 << (32 - offs)) -1) << (offs)))
00038 
00039 typedef unsigned long dwordU;
00040 typedef unsigned short wordU;
00041 
00042 typedef struct
00043 {
00044   dwordU val;
00045   int nbits;
00046 } parameter;
00047 
00048 /* Structure to hold valid 'cinv' instruction options.  */
00049 
00050 typedef struct
00051   {
00052     /* Cinv printed string.  */
00053     char *str;
00054     /* Value corresponding to the string.  */
00055     unsigned int value;
00056   }
00057 cinv_entry;
00058 
00059 /* CRX 'cinv' options.  */
00060 const cinv_entry crx_cinvs[] =
00061 {
00062   {"[i]", 2}, {"[i,u]", 3}, {"[d]", 4}, {"[d,u]", 5}, 
00063   {"[d,i]", 6}, {"[d,i,u]", 7}, {"[b]", 8}, 
00064   {"[b,i]", 10}, {"[b,i,u]", 11}, {"[b,d]", 12}, 
00065   {"[b,d,u]", 13}, {"[b,d,i]", 14}, {"[b,d,i,u]", 15}
00066 };
00067 
00068 /* Enum to distinguish different registers argument types.  */
00069 typedef enum REG_ARG_TYPE
00070   {
00071     /* General purpose register (r<N>).  */
00072     REG_ARG = 0,
00073     /* User register (u<N>).  */
00074     USER_REG_ARG,
00075     /* CO-Processor register (c<N>).  */
00076     COP_ARG,
00077     /* CO-Processor special register (cs<N>).  */
00078     COPS_ARG 
00079   }
00080 REG_ARG_TYPE;
00081 
00082 /* Number of valid 'cinv' instruction options.  */
00083 int NUMCINVS = ((sizeof crx_cinvs)/(sizeof crx_cinvs[0]));
00084 /* Current opcode table entry we're disassembling.  */
00085 const inst *instruction;
00086 /* Current instruction we're disassembling.  */
00087 ins currInsn;
00088 /* The current instruction is read into 3 consecutive words.  */
00089 wordU words[3];
00090 /* Contains all words in appropriate order.  */
00091 ULONGLONG allWords;
00092 /* Holds the current processed argument number.  */
00093 int processing_argument_number;
00094 /* Nonzero means a CST4 instruction.  */
00095 int cst4flag;
00096 /* Nonzero means the instruction's original size is
00097    incremented (escape sequence is used).  */
00098 int size_changed;
00099 
00100 static int get_number_of_operands (void);
00101 static argtype getargtype     (operand_type);
00102 static int getbits         (operand_type);
00103 static char *getregname           (reg);
00104 static char *getcopregname    (copreg, reg_type);
00105 static char * getprocregname  (int);
00106 static char *gettrapstring    (unsigned);
00107 static char *getcinvstring    (unsigned);
00108 static void getregliststring  (int, char *, enum REG_ARG_TYPE);
00109 static wordU get_word_at_PC   (bfd_vma, struct disassemble_info *);
00110 static void get_words_at_PC   (bfd_vma, struct disassemble_info *);
00111 static unsigned long build_mask (void);
00112 static int powerof2        (int);
00113 static int match_opcode           (void);
00114 static void make_instruction  (void);
00115 static void print_arguments   (ins *, bfd_vma, struct disassemble_info *);
00116 static void print_arg             (argument *, bfd_vma, struct disassemble_info *);
00117 
00118 /* Retrieve the number of operands for the current assembled instruction.  */
00119 
00120 static int
00121 get_number_of_operands (void)
00122 {
00123   int i;
00124 
00125   for (i = 0; instruction->operands[i].op_type && i < MAX_OPERANDS; i++)
00126     ;
00127 
00128   return i;
00129 }
00130 
00131 /* Return the bit size for a given operand.  */
00132 
00133 static int
00134 getbits (operand_type op)
00135 {
00136   if (op < MAX_OPRD)
00137     return crx_optab[op].bit_size;
00138   else
00139     return 0;
00140 }
00141 
00142 /* Return the argument type of a given operand.  */
00143 
00144 static argtype
00145 getargtype (operand_type op)
00146 {
00147   if (op < MAX_OPRD)
00148     return crx_optab[op].arg_type;
00149   else
00150     return nullargs;
00151 }
00152 
00153 /* Given the trap index in dispatch table, return its name.
00154    This routine is used when disassembling the 'excp' instruction.  */
00155 
00156 static char *
00157 gettrapstring (unsigned int index)
00158 {
00159   const trap_entry *trap;
00160 
00161   for (trap = crx_traps; trap < crx_traps + NUMTRAPS; trap++)
00162     if (trap->entry == index)
00163       return trap->name;
00164 
00165   return ILLEGAL;
00166 }
00167 
00168 /* Given a 'cinv' instruction constant operand, return its corresponding string.
00169    This routine is used when disassembling the 'cinv' instruction.  */
00170 
00171 static char *
00172 getcinvstring (unsigned int num)
00173 {
00174   const cinv_entry *cinv;
00175 
00176   for (cinv = crx_cinvs; cinv < (crx_cinvs + NUMCINVS); cinv++)
00177     if (cinv->value == num)
00178       return cinv->str;
00179 
00180   return ILLEGAL;
00181 }
00182 
00183 /* Given a register enum value, retrieve its name.  */
00184 
00185 char *
00186 getregname (reg r)
00187 {
00188   const reg_entry *reg = &crx_regtab[r];
00189 
00190   if (reg->type != CRX_R_REGTYPE)
00191     return ILLEGAL;
00192   else
00193     return reg->name;
00194 }
00195 
00196 /* Given a coprocessor register enum value, retrieve its name.  */
00197 
00198 char *
00199 getcopregname (copreg r, reg_type type)
00200 {
00201   const reg_entry *reg;
00202 
00203   if (type == CRX_C_REGTYPE)
00204     reg = &crx_copregtab[r];
00205   else if (type == CRX_CS_REGTYPE)
00206     reg = &crx_copregtab[r+(cs0-c0)];
00207   else
00208     return ILLEGAL;
00209 
00210   return reg->name;
00211 }
00212 
00213 
00214 /* Getting a processor register name.  */
00215 
00216 static char *
00217 getprocregname (int index)
00218 {
00219   const reg_entry *r;
00220 
00221   for (r = crx_regtab; r < crx_regtab + NUMREGS; r++)
00222     if (r->image == index)
00223       return r->name;
00224 
00225   return "ILLEGAL REGISTER";
00226 }
00227 
00228 /* Get the power of two for a given integer.  */
00229 
00230 static int
00231 powerof2 (int x)
00232 {
00233   int product, i;
00234 
00235   for (i = 0, product = 1; i < x; i++)
00236     product *= 2;
00237 
00238   return product;
00239 }
00240 
00241 /* Transform a register bit mask to a register list.  */
00242 
00243 void
00244 getregliststring (int mask, char *string, enum REG_ARG_TYPE core_cop)
00245 {
00246   char temp_string[5];
00247   int i;
00248 
00249   string[0] = '{';
00250   string[1] = '\0';
00251 
00252 
00253   /* A zero mask means HI/LO registers.  */
00254   if (mask == 0)
00255     {
00256       if (core_cop == USER_REG_ARG)
00257        strcat (string, "ulo,uhi");
00258       else
00259        strcat (string, "lo,hi");
00260     }
00261   else
00262     {
00263       for (i = 0; i < 16; i++)
00264        {
00265          if (mask & 0x1)
00266            {
00267              switch (core_cop)
00268              {
00269              case REG_ARG:
00270               sprintf (temp_string, "r%d", i);
00271               break;
00272              case USER_REG_ARG:
00273               sprintf (temp_string, "u%d", i);
00274               break;
00275              case COP_ARG:
00276               sprintf (temp_string, "c%d", i);
00277               break;
00278              case COPS_ARG:
00279               sprintf (temp_string, "cs%d", i);
00280               break;
00281              default:
00282               break;
00283              }
00284              strcat (string, temp_string);
00285              if (mask & 0xfffe)
00286               strcat (string, ",");
00287            }
00288          mask >>= 1;
00289        }
00290     }
00291 
00292   strcat (string, "}");
00293 }
00294 
00295 /* START and END are relating 'allWords' struct, which is 48 bits size.
00296 
00297                        START|--------|END
00298            +---------+---------+---------+---------+
00299            |        |          V    |     A        |   L           |
00300            +---------+---------+---------+---------+
00301                     0              16       32       48
00302     words              [0]      [1]             [2]     */
00303 
00304 static parameter
00305 makelongparameter (ULONGLONG val, int start, int end)
00306 {
00307   parameter p;
00308 
00309   p.val = (dwordU) EXTRACT(val, 48 - end, end - start);
00310   p.nbits = end - start;
00311   return p;
00312 }
00313 
00314 /* Build a mask of the instruction's 'constant' opcode,
00315    based on the instruction's printing flags.  */
00316 
00317 static unsigned long
00318 build_mask (void)
00319 {
00320   unsigned int print_flags;
00321   unsigned long mask;
00322 
00323   print_flags = instruction->flags & FMT_CRX;
00324   switch (print_flags)
00325     {
00326       case FMT_1:
00327        mask = 0xF0F00000;
00328        break;
00329       case FMT_2:
00330        mask = 0xFFF0FF00;
00331        break;
00332       case FMT_3:
00333        mask = 0xFFF00F00;
00334        break;
00335       case FMT_4:
00336        mask = 0xFFF0F000;
00337        break;
00338       case FMT_5:
00339        mask = 0xFFF0FFF0;
00340        break;
00341       default:
00342        mask = SBM(instruction->match_bits);
00343        break;
00344     }
00345 
00346   return mask;
00347 }
00348 
00349 /* Search for a matching opcode. Return 1 for success, 0 for failure.  */
00350 
00351 static int
00352 match_opcode (void)
00353 {
00354   unsigned long mask;
00355 
00356   /* The instruction 'constant' opcode doewsn't exceed 32 bits.  */
00357   unsigned long doubleWord = words[1] + (words[0] << 16);
00358 
00359   /* Start searching from end of instruction table.  */
00360   instruction = &crx_instruction[NUMOPCODES - 2];
00361 
00362   /* Loop over instruction table until a full match is found.  */
00363   while (instruction >= crx_instruction)
00364     {
00365       mask = build_mask ();
00366       if ((doubleWord & mask) == BIN(instruction->match, instruction->match_bits))
00367        return 1;
00368       else
00369        instruction--;
00370     }
00371   return 0;
00372 }
00373 
00374 /* Set the proper parameter value for different type of arguments.  */
00375 
00376 static void
00377 make_argument (argument * a, int start_bits)
00378 {
00379   int inst_bit_size, total_size;
00380   parameter p;
00381 
00382   if ((instruction->size == 3) && a->size >= 16)
00383     inst_bit_size = 48;
00384   else
00385     inst_bit_size = 32;
00386 
00387   switch (a->type)
00388     {
00389     case arg_copr:
00390     case arg_copsr:
00391       p = makelongparameter (allWords, inst_bit_size - (start_bits + a->size),
00392                           inst_bit_size - start_bits);
00393       a->cr = p.val;
00394       break;
00395 
00396     case arg_r:
00397       p = makelongparameter (allWords, inst_bit_size - (start_bits + a->size),
00398                           inst_bit_size - start_bits);
00399       a->r = p.val;
00400       break;
00401 
00402     case arg_ic:
00403       p = makelongparameter (allWords, inst_bit_size - (start_bits + a->size),
00404                           inst_bit_size - start_bits);
00405 
00406       if ((p.nbits == 4) && cst4flag)
00407         {
00408          if (IS_INSN_TYPE (CMPBR_INS) && (p.val == ESCAPE_16_BIT))
00409            {
00410              /* A special case, where the value is actually stored
00411                in the last 4 bits.  */
00412              p = makelongparameter (allWords, 44, 48);
00413              /* The size of the instruction should be incremented.  */
00414              size_changed = 1;
00415            }
00416 
00417           if (p.val == 6)
00418             p.val = -1;
00419           else if (p.val == 13)
00420             p.val = 48;
00421           else if (p.val == 5)
00422             p.val = -4;
00423           else if (p.val == 10)
00424             p.val = 32;
00425           else if (p.val == 11)
00426             p.val = 20;
00427           else if (p.val == 9)
00428             p.val = 16;
00429         }
00430 
00431       a->constant = p.val;
00432       break;
00433 
00434     case arg_idxr:
00435       a->scale = 0;
00436       total_size = a->size + 10;  /* sizeof(rbase + ridx + scl2) = 10.  */
00437       p = makelongparameter (allWords, inst_bit_size - total_size,
00438                           inst_bit_size - (total_size - 4));
00439       a->r = p.val;
00440       p = makelongparameter (allWords, inst_bit_size - (total_size - 4),
00441                           inst_bit_size - (total_size - 8));
00442       a->i_r = p.val;
00443       p = makelongparameter (allWords, inst_bit_size - (total_size - 8),
00444                           inst_bit_size - (total_size - 10));
00445       a->scale = p.val;
00446       p = makelongparameter (allWords, inst_bit_size - (total_size - 10),
00447                           inst_bit_size);
00448       a->constant = p.val;
00449       break;
00450 
00451     case arg_rbase:
00452       p = makelongparameter (allWords, inst_bit_size - (start_bits + 4),
00453                           inst_bit_size - start_bits);
00454       a->r = p.val;
00455       break;
00456 
00457     case arg_cr:
00458       if (a->size <= 8)
00459         {
00460           p = makelongparameter (allWords, inst_bit_size - (start_bits + 4),
00461                              inst_bit_size - start_bits);
00462           a->r = p.val;
00463           /* Case for opc4 r dispu rbase.  */
00464           p = makelongparameter (allWords, inst_bit_size - (start_bits + 8),
00465                              inst_bit_size - (start_bits + 4));
00466         }
00467       else
00468         {
00469          /* The 'rbase' start_bits is always relative to a 32-bit data type.  */
00470           p = makelongparameter (allWords, 32 - (start_bits + 4),
00471                              32 - start_bits);
00472           a->r = p.val;
00473           p = makelongparameter (allWords, 32 - start_bits,
00474                              inst_bit_size);
00475         }
00476       if ((p.nbits == 4) && cst4flag)
00477         {
00478           if (instruction->flags & DISPUW4)
00479            p.val *= 2;
00480           else if (instruction->flags & DISPUD4)
00481            p.val *= 4;
00482         }
00483       a->constant = p.val;
00484       break;
00485 
00486     case arg_c:
00487       p = makelongparameter (allWords, inst_bit_size - (start_bits + a->size),
00488                           inst_bit_size - start_bits);
00489       a->constant = p.val;
00490       break;
00491     default:
00492       break;
00493     }
00494 }
00495 
00496 /*  Print a single argument.  */
00497 
00498 static void
00499 print_arg (argument *a, bfd_vma memaddr, struct disassemble_info *info)
00500 {
00501   LONGLONG longdisp, mask;
00502   int sign_flag = 0;
00503   int relative = 0;
00504   bfd_vma number;
00505   int op_index = 0;
00506   char string[200];
00507   PTR stream = info->stream;
00508   fprintf_ftype func = info->fprintf_func;
00509 
00510   switch (a->type)
00511     {
00512     case arg_copr:
00513       func (stream, "%s", getcopregname (a->cr, CRX_C_REGTYPE));
00514       break;
00515 
00516     case arg_copsr:
00517       func (stream, "%s", getcopregname (a->cr, CRX_CS_REGTYPE));
00518       break;
00519 
00520     case arg_r:
00521       if (IS_INSN_MNEMONIC ("mtpr") || IS_INSN_MNEMONIC ("mfpr"))
00522        func (stream, "%s", getprocregname (a->r));
00523       else
00524        func (stream, "%s", getregname (a->r));
00525       break;
00526 
00527     case arg_ic:
00528       if (IS_INSN_MNEMONIC ("excp"))
00529        func (stream, "%s", gettrapstring (a->constant));
00530 
00531       else if (IS_INSN_MNEMONIC ("cinv"))
00532        func (stream, "%s", getcinvstring (a->constant));
00533 
00534       else if (INST_HAS_REG_LIST)
00535         {
00536          REG_ARG_TYPE reg_arg_type = IS_INSN_TYPE (COP_REG_INS) ? 
00537                              COP_ARG : IS_INSN_TYPE (COPS_REG_INS) ? 
00538                              COPS_ARG : (instruction->flags & USER_REG) ?
00539                              USER_REG_ARG : REG_ARG;
00540 
00541           if ((reg_arg_type == COP_ARG) || (reg_arg_type == COPS_ARG))
00542            {
00543               /*  Check for proper argument number.  */
00544               if (processing_argument_number == 2)
00545                 {
00546                   getregliststring (a->constant, string, reg_arg_type);
00547                   func (stream, "%s", string);
00548                 }
00549               else
00550                 func (stream, "$0x%lx", a->constant);
00551            }
00552          else
00553             {
00554               getregliststring (a->constant, string, reg_arg_type);
00555               func (stream, "%s", string);
00556             }
00557         }
00558       else
00559        func (stream, "$0x%lx", a->constant);
00560       break;
00561 
00562     case arg_idxr:
00563       func (stream, "0x%lx(%s,%s,%d)", a->constant, getregname (a->r),
00564            getregname (a->i_r), powerof2 (a->scale));
00565       break;
00566 
00567     case arg_rbase:
00568       func (stream, "(%s)", getregname (a->r));
00569       break;
00570 
00571     case arg_cr:
00572       func (stream, "0x%lx(%s)", a->constant, getregname (a->r));
00573 
00574       if (IS_INSN_TYPE (LD_STOR_INS_INC))
00575        func (stream, "+");
00576       break;
00577 
00578     case arg_c:
00579       /* Removed the *2 part as because implicit zeros are no more required.
00580         Have to fix this as this needs a bit of extension in terms of branchins.
00581         Have to add support for cmp and branch instructions.  */
00582       if (IS_INSN_TYPE (BRANCH_INS) || IS_INSN_MNEMONIC ("bal")
00583          || IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (DCR_BRANCH_INS)
00584          || IS_INSN_TYPE (COP_BRANCH_INS))
00585         {
00586          relative = 1;
00587           longdisp = a->constant;
00588           longdisp <<= 1;
00589 
00590           switch (a->size)
00591             {
00592             case 8:
00593            case 16:
00594            case 24:
00595            case 32:
00596              mask = ((LONGLONG)1 << a->size) - 1;
00597               if (longdisp & ((LONGLONG)1 << a->size))
00598                 {
00599                   sign_flag = 1;
00600                   longdisp = ~(longdisp) + 1;
00601                 }
00602               a->constant = (unsigned long int) (longdisp & mask);
00603               break;
00604             default:
00605              func (stream,
00606                   "Wrong offset used in branch/bal instruction");
00607               break;
00608             }
00609 
00610         }
00611       /* For branch Neq instruction it is 2*offset + 2.  */
00612       else if (IS_INSN_TYPE (BRANCH_NEQ_INS))
00613        a->constant = 2 * a->constant + 2;
00614       else if (IS_INSN_TYPE (LD_STOR_INS_INC)
00615          || IS_INSN_TYPE (LD_STOR_INS)
00616          || IS_INSN_TYPE (STOR_IMM_INS)
00617          || IS_INSN_TYPE (CSTBIT_INS))
00618         {
00619           op_index = instruction->flags & REVERSE_MATCH ? 0 : 1;
00620           if (instruction->operands[op_index].op_type == abs16)
00621            a->constant |= 0xFFFF0000;
00622         }
00623       func (stream, "%s", "0x");
00624       number = (relative ? memaddr : 0)
00625               + (sign_flag ? -a->constant : a->constant);
00626       (*info->print_address_func) (number, info);
00627       break;
00628     default:
00629       break;
00630     }
00631 }
00632 
00633 /* Print all the arguments of CURRINSN instruction.  */
00634 
00635 static void
00636 print_arguments (ins *currInsn, bfd_vma memaddr, struct disassemble_info *info)
00637 {
00638   int i;
00639 
00640   for (i = 0; i < currInsn->nargs; i++)
00641     {
00642       processing_argument_number = i;
00643 
00644       print_arg (&currInsn->arg[i], memaddr, info);
00645 
00646       if (i != currInsn->nargs - 1)
00647        info->fprintf_func (info->stream, ", ");
00648     }
00649 }
00650 
00651 /* Build the instruction's arguments.  */
00652 
00653 static void
00654 make_instruction (void)
00655 {
00656   int i;
00657   unsigned int shift;
00658 
00659   for (i = 0; i < currInsn.nargs; i++)
00660     {
00661       argument a;
00662 
00663       memset (&a, 0, sizeof (a));
00664       a.type = getargtype (instruction->operands[i].op_type);
00665       if (instruction->operands[i].op_type == cst4
00666          || instruction->operands[i].op_type == rbase_dispu4)
00667        cst4flag = 1;
00668       a.size = getbits (instruction->operands[i].op_type);
00669       shift = instruction->operands[i].shift;
00670 
00671       make_argument (&a, shift);
00672       currInsn.arg[i] = a;
00673     }
00674 
00675   /* Calculate instruction size (in bytes).  */
00676   currInsn.size = instruction->size + (size_changed ? 1 : 0);
00677   /* Now in bits.  */
00678   currInsn.size *= 2;
00679 }
00680 
00681 /* Retrieve a single word from a given memory address.  */
00682 
00683 static wordU
00684 get_word_at_PC (bfd_vma memaddr, struct disassemble_info *info)
00685 {
00686   bfd_byte buffer[4];
00687   int status;
00688   wordU insn = 0;
00689 
00690   status = info->read_memory_func (memaddr, buffer, 2, info);
00691 
00692   if (status == 0)
00693     insn = (wordU) bfd_getl16 (buffer);
00694 
00695   return insn;
00696 }
00697 
00698 /* Retrieve multiple words (3) from a given memory address.  */
00699 
00700 static void
00701 get_words_at_PC (bfd_vma memaddr, struct disassemble_info *info)
00702 {
00703   int i;
00704   bfd_vma mem;
00705 
00706   for (i = 0, mem = memaddr; i < 3; i++, mem += 2)
00707     words[i] = get_word_at_PC (mem, info);
00708 
00709   allWords =
00710     ((ULONGLONG) words[0] << 32) + ((unsigned long) words[1] << 16) + words[2];
00711 }
00712 
00713 /* Prints the instruction by calling print_arguments after proper matching.  */
00714 
00715 int
00716 print_insn_crx (memaddr, info)
00717      bfd_vma memaddr;
00718      struct disassemble_info *info;
00719 {
00720   int is_decoded;     /* Nonzero means instruction has a match.  */
00721 
00722   /* Initialize global variables.  */
00723   cst4flag = 0;
00724   size_changed = 0;
00725 
00726   /* Retrieve the encoding from current memory location.  */
00727   get_words_at_PC (memaddr, info);
00728   /* Find a matching opcode in table.  */
00729   is_decoded = match_opcode ();
00730   /* If found, print the instruction's mnemonic and arguments.  */
00731   if (is_decoded > 0 && (words[0] << 16 || words[1]) != 0)
00732     {
00733       info->fprintf_func (info->stream, "%s", instruction->mnemonic);
00734       if ((currInsn.nargs = get_number_of_operands ()) != 0)
00735        info->fprintf_func (info->stream, "\t");
00736       make_instruction ();
00737       print_arguments (&currInsn, memaddr, info);
00738       return currInsn.size;
00739     }
00740 
00741   /* No match found.  */
00742   info->fprintf_func (info->stream,"%s ",ILLEGAL);
00743   return 2;
00744 }