nindy bug fixes (function types) and opcode library inclusion
[deliverable/binutils-gdb.git] / gdb / rs6000-pinsn.c
index d1e239906a6798ee783e823ccd4202a7041b3d25..03261e59421c59047131b2e2b7afbf60b0b5864a 100644 (file)
@@ -1,12 +1,25 @@
-/* Print rs6000 instructions for objdump.
-   This file is part of the binutils.
-*/
+/* Print IBM RS/6000 instructions for GNU software.
+   Copyright 1991 Free Software Foundation, Inc.
+   Contributed by IBM Corporation.
 
+This file is part of GDB and the GNU binutils.
 
-#include <stdio.h>
-#include "defs.h"
-#include "rs6k-opcode.h"
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
+#include "defs.h"
+#include "opcode/rs6k.h"
 
 /* Print the rs6k instruction at address MEMADDR in debugged memory,
    on STREAM.  Returns length of the instruction, in bytes.  */
@@ -16,7 +29,7 @@ print_insn (memaddr, stream)
   CORE_ADDR memaddr;
   FILE *stream;
 {
-       int  pop, eop;                  /* primary and extended opcodes */
+       int  pop, eop, probable_eop;    /* primary and extended opcodes */
        int  min, max;
        int  best = -1;                 /* found best opcode index      */
        int  oldbest = -1;
@@ -24,7 +37,6 @@ print_insn (memaddr, stream)
 
        read_memory (memaddr, &the_insn, sizeof (the_insn));
        pop = (unsigned)(the_insn >> 26);
-       eop = ((the_insn) >> 1) & 0x3ff;
        min = 0, max = NOPCODES-1;
 
        while (min < max) {
@@ -42,7 +54,7 @@ print_insn (memaddr, stream)
            min = best;
 
          else {
-           /* opcode matched, check extended opcode. */
+           /* Opcode matched, check extended opcode. */
 
            if (rs6k_ops [best].e_opcode == -1) {
              /* there is no valid extended opcode, what we've got is
@@ -50,12 +62,18 @@ print_insn (memaddr, stream)
              goto insn_found;
            }
 
-           else if (eop < rs6k_ops [best].e_opcode) {
+           /* Largest possible value of extended opcode. */
+           probable_eop = ((the_insn) >> 1) & 0x3ff;
+
+           eop = probable_eop & eopMask [rs6k_ops [best].format];
+
+           if (eop < rs6k_ops [best].e_opcode) {
 
              while (pop == rs6k_ops [best].p_opcode) {
                if (eop == rs6k_ops [best].e_opcode)    /* found it! */
                  goto insn_found;
                --best;
+               eop = probable_eop & eopMask [rs6k_ops [best].format];
              }
              goto not_found;
            }
@@ -66,6 +84,7 @@ print_insn (memaddr, stream)
                if (eop == rs6k_ops [best].e_opcode)    /* found it! */
                  goto insn_found;
                ++best;
+               eop = probable_eop & eopMask [rs6k_ops [best].format];
              }
              goto not_found;
            }
@@ -106,20 +125,19 @@ long      memaddr;
 long   insn_word;
 int    insn_no;
 {
-  char buf [BUFSIZ];
+  char buf [20];
   char *qq = buf;
   char *pp = rs6k_ops[insn_no].opr_ext;
   int tmp;
   int nocomma = 0;                     /* true if no comma needed */
 
-  *qq = '\0';
   if (pp) {
     while (*pp) {
 
       switch ( *pp ) {
        case '.':
          if (insn_word & 0x1)
-          *qq++ = '.';
+           *qq++ = '.';
          break;
 
        case 'l':
@@ -164,9 +182,9 @@ int insn_no;
       ++pp;
     }
   }
+  *qq = '\0';
 
-  /* tab between orerator and operand */
-  *qq++ = '\t';
+  fprintf (stream, "%s%s\t", rs6k_ops[insn_no].operator, buf);
 
   /* parse the operand now. */
   pp = rs6k_ops[insn_no].oprnd_format;
@@ -174,31 +192,23 @@ int       insn_no;
   while (1) {
     switch (*pp) {
       case TO  :
-       sprintf (qq, "%d", (insn_word >> 21) & 0x1f);
+       fprintf (stream, "%d", (insn_word >> 21) & 0x1f);
        break;
 
       case RT  :
       case RS  :
-       sprintf (qq, "r%d", (insn_word >> 21) & 0x1f);
+       fprintf (stream, "r%d", (insn_word >> 21) & 0x1f);
        break;
 
       case LI  :
        tmp  = (insn_word >> 16) & 0x1f;
        if (tmp > 11) {
-         fprintf (stderr, "Internal error: unknown cond code: 0x%x\n", insn_word);
+         fprintf (stream, "{unknown cond code: 0x%x}", insn_word);
          tmp = 0;
        }
-       sprintf (qq, "%s", cond_code [tmp]);
+       fprintf (stream, "%s", cond_code [tmp]);
        break;
 
-#if 0
-      case A2  :
-       tmp = (insn_word >> 2) & 0x3fff;
-       if (tmp & 0x2000)
-        tmp -= 0x4000;
-       sprintf (qq, "0x%x", tmp * 4 + memaddr);
-       break;
-#endif
       case A2  :
       case TA14        :
        tmp = (insn_word & 0xfffc);
@@ -208,7 +218,7 @@ int insn_no;
        if ((insn_word & 0x2) == 0)     /* if AA not set        */
          tmp += memaddr;
 
-       sprintf (qq, "0x%x", tmp);
+        print_address (tmp, stream);
        break;
 
       case TA24        :
@@ -219,101 +229,99 @@ int      insn_no;
        if ((insn_word & 0x2) == 0)             /* if no AA bit set */
          tmp += memaddr;
 
-       sprintf (qq, "0x%x", tmp);
+        print_address (tmp, stream);
        break;
 
       case LEV :                       /* for svc only */
        if (insn_word & 0x2) {          /* SA is set    */
          nocomma = 1;
-         *qq = '\0';
        }
        else
-          sprintf (qq, "%d", (insn_word >> 5) & 0x7f);
+          fprintf (stream, "%d", (insn_word >> 5) & 0x7f);
        break;
 
       case FL1 :                       /* for svc only */
        if (insn_word & 0x2) {          /* SA is set    */
          nocomma = 1;
-         *qq = '\0';
        }
        else
-          sprintf (qq, "%d", (insn_word >> 12) & 0xf);
+          fprintf (stream, "%d", (insn_word >> 12) & 0xf);
        break;
 
       case FL2 :                       /* for svc only */
        nocomma = 0;
        if (insn_word & 0x2)            /* SA is set    */
-         sprintf (qq, "%d", (insn_word >> 2) & 0x3fff);
+         fprintf (stream, "%d", (insn_word >> 2) & 0x3fff);
        else
-          sprintf (qq, "%d", (insn_word >> 2) & 0x7);
+          fprintf (stream, "%d", (insn_word >> 2) & 0x7);
        break;
 
       case RA  :
        if (nocomma) {
-         sprintf (qq, "r%d)", (insn_word >> 16) & 0x1f);
+         fprintf (stream, "r%d)", (insn_word >> 16) & 0x1f);
          nocomma = 0;
        }
        else
-         sprintf (qq, "r%d", (insn_word >> 16) & 0x1f);
+         fprintf (stream, "r%d", (insn_word >> 16) & 0x1f);
        break;
 
       case RB  :
-       sprintf (qq, "r%d", (insn_word >> 11) & 0x1f);
+       fprintf (stream, "r%d", (insn_word >> 11) & 0x1f);
        break;
 
       case SI  :
        tmp = insn_word & 0xffff;
        if (tmp & 0x8000)
          tmp -= 0x10000;
-       sprintf (qq, "%d", tmp);
+       fprintf (stream, "%d", tmp);
        break;
 
       case UI  :
-       sprintf (qq, "%d", insn_word & 0xffff);
+       fprintf (stream, "%d", insn_word & 0xffff);
        break;
 
       case BF  :
-       sprintf (qq, "%d", (insn_word >> 23) & 0x7);
+       fprintf (stream, "%d", (insn_word >> 23) & 0x7);
        break;
 
       case BFA :
-       sprintf (qq, "%d", (insn_word >> 18) & 0x7);
+       fprintf (stream, "%d", (insn_word >> 18) & 0x7);
        break;
 
       case BT  :
-       sprintf (qq, "%d", (insn_word >> 21) & 0x1f);
+       fprintf (stream, "%d", (insn_word >> 21) & 0x1f);
        break;
 
       case BA  :
-       sprintf (qq, "%d", (insn_word >> 16) & 0x1f);
+       fprintf (stream, "%d", (insn_word >> 16) & 0x1f);
        break;
 
       case BB  :
-       sprintf (qq, "%d", (insn_word >> 11) & 0x1f);
+       fprintf (stream, "%d", (insn_word >> 11) & 0x1f);
        break;
 
       case BO  :
-       sprintf (qq, "%d", (insn_word >> 21) & 0x1f);
+       fprintf (stream, "%d", (insn_word >> 21) & 0x1f);
        break;
 
       case BI  :
-       sprintf (qq, "%d", (insn_word >> 16) & 0x1f);
+       fprintf (stream, "%d", (insn_word >> 16) & 0x1f);
        break;
 
       case SH  :
-       sprintf (qq, "%d", (insn_word >> 11) & 0x1f);
+       fprintf (stream, "%d", (insn_word >> 11) & 0x1f);
        break;
 
       case MB  :
-       sprintf (qq, "0x%x", (insn_word >> 6) & 0x1f);
+       fprintf (stream, "0x%x", (insn_word >> 6) & 0x1f);
        break;
 
       case ME  :
-       sprintf (qq, "0x%x", (insn_word >> 1) & 0x1f);
+       fprintf (stream, "0x%x", (insn_word >> 1) & 0x1f);
        break;
 
       case SPR :
-       sprintf (qq, "%d", (insn_word >> 16) & 0x1f);
+       fprintf (stream, "%d", (insn_word >> 16) & 0x1f);
        break;
 
       case DIS :
@@ -321,57 +329,52 @@ int       insn_no;
        tmp = insn_word & 0xffff;
        if (tmp & 0x8000)
          tmp -= 0x10000;
-       sprintf (qq, "%d(", tmp);
+       fprintf (stream, "%d(", tmp);
        break;
 
       case FXM :
-       sprintf (qq, "0x%x", (insn_word >> 12) & 0xff);
+       fprintf (stream, "0x%x", (insn_word >> 12) & 0xff);
        break;
 
       case FRT :
       case FRS :
-       sprintf (qq, "f%d", (insn_word >> 21) & 0x1f);
+       fprintf (stream, "f%d", (insn_word >> 21) & 0x1f);
        break;
 
       case FRA :
-       sprintf (qq, "f%d", (insn_word >> 16) & 0x1f);
+       fprintf (stream, "f%d", (insn_word >> 16) & 0x1f);
        break;
 
       case FRB :
-       sprintf (qq, "f%d", (insn_word >> 11) & 0x1f);
+       fprintf (stream, "f%d", (insn_word >> 11) & 0x1f);
        break;
 
       case FRC :
-       sprintf (qq, "f%d", (insn_word >> 6) & 0x1f);
+       fprintf (stream, "f%d", (insn_word >> 6) & 0x1f);
        break;
 
       case FLM :
-       sprintf (qq, "0x%x", (insn_word >> 17) & 0xff);
+       fprintf (stream, "0x%x", (insn_word >> 17) & 0xff);
        break;
 
       case NB  :
-       sprintf (qq, "%d", (insn_word >> 11) & 0x1f);
+       fprintf (stream, "%d", (insn_word >> 11) & 0x1f);
        break;
 
       case I   :
-       sprintf (qq, "%d", (insn_word >> 12) & 0xf);
+       fprintf (stream, "%d", (insn_word >> 12) & 0xf);
        break;
 
       default  :
-       sprintf (qq, "Unknown operand format identifier????");
-       abort ();
+       fprintf (stream,
+                "{Internal error: Unknown operand format identifier %d}",
+                *pp);
     }
-    while (*qq) ++qq;
     ++pp;
 
     if (*pp == '\0')
       break;
     else if (!nocomma)
-      *qq++ = ',';
+      fputc(',', stream);
   }
-  *qq = '\0';
-    
-  fprintf (stream, "0x%08x\t%s%s", 
-       insn_word, rs6k_ops[insn_no].operator, buf);
 }
-
This page took 0.028916 seconds and 4 git commands to generate.