Added -V option to print version number.
[binutils-gdb.git] / binutils / sparc-pinsn.c
index 550722b8a79c2ba6e36362feb375ba197bb63341..2430b5d4f6165748bb7d5729cbf88c514c762d79 100644 (file)
@@ -1,12 +1,12 @@
 /* disassemble sparc instructions for objdump
-   Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
+   Copyright (C) 1986, 1987, 1989, 1991 Free Software Foundation, Inc.
 
 
 This file is part of the binutils.
 
 The binutils are 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 1, or (at your option)
+the Free Software Foundation; either version 2, or (at your option)
 any later version.
 
 The binutils are distributed in the hope that they will be useful,
@@ -18,41 +18,11 @@ You should have received a copy of the GNU General Public License
 along with the binutils; see the file COPYING.  If not, write to
 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
-/* $Id$
-   $Log$
-   Revision 1.1  1991/03/21 21:26:55  gumby
-   Initial revision
-
- * Revision 1.1  1991/03/13  00:34:40  chrisb
- * Initial revision
- *
- * Revision 1.3  1991/03/09  04:36:31  rich
- *  Modified Files:
- *     sparc-pinsn.c ostrip.c objdump.c m68k-pinsn.c i960-pinsn.c
- *     binutils.h
- *
- * Pulled sysdep.h out of bfd.h.
- *
- * Revision 1.2  1991/03/08  21:54:53  rich
- *  Modified Files:
- *     Makefile ar.c binutils.h bucomm.c copy.c cplus-dem.c getopt.c
- *     i960-pinsn.c m68k-pinsn.c nm.c objdump.c sparc-opcode.h
- *     sparc-pinsn.c strip.c
- *
- * Verifying Portland tree with steve's last changes.  Also, some partial
- * porting.
- *
- * Revision 1.1  1991/02/22  16:48:04  sac
- * Initial revision
- *
-*/
-
-#include <stdio.h>
-#include "sysdep.h"
 #include "bfd.h"
-#include "sparc-opcode.h"
-
-extern int fputs();
+#include "sysdep.h"
+#include <stdio.h>
+#include "opcode/sparc.h"
+#include "objdump.h"
 extern int print_address();
 
 static  char *reg_names[] =
@@ -73,41 +43,60 @@ union sparc_insn
     unsigned long int code;
     struct
       {
-       unsigned int OP:2;
-#define        op      ldst.OP
-       unsigned int RD:5;
-#define        rd      ldst.RD
+       unsigned int _OP:2;
+#define        op      ldst._OP
+       unsigned int _RD:5;
+#define        rd      ldst._RD
        unsigned int op3:6;
-       unsigned int RS1:5;
-#define        rs1     ldst.RS1
+       unsigned int _RS1:5;
+#define        rs1     ldst._RS1
        unsigned int i:1;
-       unsigned int ASI:8;
-#define        asi     ldst.ASI
-       unsigned int RS2:5;
-#define        rs2     ldst.RS2
+       unsigned int _ASI:8;
+#define        asi     ldst._ASI
+       unsigned int _RS2:5;
+#define        rs2     ldst._RS2
 #define        shcnt   rs2
       } ldst;
     struct
       {
-       unsigned int OP:2, RD:5, op3:6, RS1:5, i:1;
+       unsigned int _OP:2, _RD:5, op3:6, _RS1:5, i:1;
        unsigned int IMM13:13;
 #define        imm13   IMM13.IMM13
       } IMM13;
     struct
       {
-       unsigned int OP:2;
+       unsigned int _OP:2;
        unsigned int a:1;
        unsigned int cond:4;
        unsigned int op2:3;
        unsigned int DISP22:22;
 #define        disp22  branch.DISP22
       } branch;
+#ifndef NO_V9
+    struct
+      {
+       unsigned int _OP:2, _RD:5, op3:6, _RS1:5;
+       unsigned int DISP14:14;
+#define        disp14  DISP14.DISP14
+      } DISP14;
+    struct
+      {
+       unsigned int _OP:2;
+       unsigned int a:1;
+       unsigned int cond:4;
+       unsigned int op2:3;
+       unsigned int p:1;
+       unsigned int DISP21:21;
+#define        disp21  branch2.DISP21
+      } branch2;
+#endif /* NO_V9 */
+
 #define        imm22   disp22
     struct
       {
-       unsigned int OP:2;
-       unsigned int DISP30:30;
-#define        disp30  call.DISP30
+       unsigned int _OP:2;
+       unsigned int _DISP30:30;
+#define        disp30  call._DISP30
       } call;
   };
 
@@ -123,7 +112,7 @@ is_delayed_branch (insn)
       const struct sparc_opcode *opcode = &sparc_opcodes[i];
       if ((opcode->match & insn.code) == opcode->match
          && (opcode->lose & insn.code) == 0
-         && (opcode->delayed))
+         && (opcode->flags&F_DELAYED))
        return 1;
     }
   return 0;
@@ -191,18 +180,35 @@ memcpy(&insn,buffer, sizeof (insn));
              fputs (" ", stream);
            for (s = opcode->args; *s != '\0'; ++s)
              {
-               if (*s == ',')
+               while (*s == ',')
                  {
                    fputs (",", stream);
                    ++s;
-                   if (*s == 'a')
-                     {
-                       fputs ("a", stream);
-                       ++s;
-                     }
-                   fputs (" ", stream);
-                 }
 
+                   switch (*s) {
+                   case 'a':
+                     fputs ("a", stream);
+                     ++s;
+                     continue;
+#ifndef NO_V9
+                   case 'N':
+                     fputs("pn", stream);
+                     ++s;
+                     continue;
+
+                   case 'T':
+                     fputs("pt", stream);
+                     ++s;
+                     continue;
+#endif                         /* NO_V9 */
+
+                   default:
+                     break;
+                   }           /* switch on arg */
+                 }             /* while there are comma started args */
+
+               fputs (" ", stream);
+                       
                switch (*s)
                  {
                  case '+':
@@ -234,14 +240,30 @@ memcpy(&insn,buffer, sizeof (insn));
 
 #define        freg(n) fprintf (stream, "%%%s", freg_names[n])
                  case 'e':
+                 case 'v':     /* double/even */
+                 case 'V':     /* quad/multiple of 4 */
                    freg (insn.rs1);
                    break;
 
                  case 'f':
+                 case 'B':     /* double/even */
+                 case 'R':     /* quad/multiple of 4 */
                    freg (insn.rs2);
                    break;
 
+#ifndef NO_V9
+/* Somebody who know needs to define rs3.
+                 case 'j':
+                 case 'u':     * double/even *
+                 case 'U':     * quad/multiple of 4 *
+                   freg (insn.rs3);
+                   break;
+*/
+#endif                         /* NO_V9 */
+
                  case 'g':
+                 case 'H':     /* double/even */
+                 case 'J':     /* quad/multiple of 4 */
                    freg (insn.rd);
                    break;
 #undef freg
@@ -262,7 +284,7 @@ memcpy(&insn,buffer, sizeof (insn));
 
                  case 'h':
                    fprintf (stream, "%%hi(%#x)",
-                                     (unsigned int) insn.imm22 << 10);
+                            (unsigned int) insn.imm22 << 10);
                    break;
 
                  case 'i':
@@ -273,7 +295,7 @@ memcpy(&insn,buffer, sizeof (insn));
 
                      /* Check to see whether we have a 1+i, and take
                         note of that fact.
-
+                        
                         Note: because of the way we sort the table,
                         we will be matching 1+i rather than i+1,
                         so it is OK to assume that i is after +,
@@ -288,6 +310,50 @@ memcpy(&insn,buffer, sizeof (insn));
                    }
                    break;
 
+#ifndef NO_V9
+                 case 'k':
+                   print_address ((bfd_vma)
+                                  (memaddr
+                                   + (((int) insn.disp14 << 18) >> 18) * 4),
+                                  stream);
+                   break;
+
+                 case 'G':
+                   print_address ((bfd_vma)
+                                  (memaddr
+                                   /* We use only 19 of the 21 bits.  */
+                                   + (((int) insn.disp21 << 13) >> 13) * 4),
+                                  stream);
+                   break;
+
+                 case 'Y':
+                   fputs ("%amr", stream);
+                   break;
+
+                 case '6':
+                 case '7':
+                 case '8':
+                 case '9':
+                   fprintf (stream, "fcc%c", *s - '6' + '0');
+                   break;
+
+                 case 'z':
+                   fputs ("icc", stream);
+                   break;
+
+                 case 'Z':
+                   fputs ("xcc", stream);
+                   break;
+#endif                         /* NO_V9 */
+
+                 case 'M':
+                   fprintf(stream, "%%asr%d", insn.rs1);
+                   break;
+                   
+                 case 'm':
+                   fprintf(stream, "%%asr%d", insn.rd);
+                   break;
+                   
                  case 'L':
                    print_address ((bfd_vma) memaddr + insn.disp30 * 4,
                                   stream);
@@ -298,7 +364,7 @@ memcpy(&insn,buffer, sizeof (insn));
                      /* Special case for `unimp'.  Don't try to turn
                         it's operand into a function offset.  */
                      fprintf (stream, "%#x",
-                                       (unsigned) (((int) insn.disp22 << 10) >> 10));
+                              (unsigned) (((int) insn.disp22 << 10) >> 10));
                    else
                      /* We cannot trust the compiler to sign-extend
                         when extracting the bitfield, hence the shifts.  */
@@ -356,7 +422,7 @@ memcpy(&insn,buffer, sizeof (insn));
          if (imm_added_to_rs1)
            {
              union sparc_insn prev_insn;
-             int errcode;
+             int errcode = 0;
 
              memcpy(&prev_insn, buffer -4,  sizeof (prev_insn));
 
@@ -397,7 +463,7 @@ memcpy(&insn,buffer, sizeof (insn));
        }
     }
 
-  fprintf ("%#8x", insn.code);
+  fprintf (stream, "%#8x", insn.code);
   return sizeof (insn);
 }