* ppc-opc.c (powerpc_operands): Make comment match the
authorFred Fish <fnf@specifix.com>
Sat, 4 Jan 1997 01:39:30 +0000 (01:39 +0000)
committerFred Fish <fnf@specifix.com>
Sat, 4 Jan 1997 01:39:30 +0000 (01:39 +0000)
actual fields (no shift field).
* sparc-opc.c (sparc_opcodes): Document why this cannot be "const".

* tic80-dis.c (print_insn_tic80): Replace abort stub with a
partial implementation, work in progress.
* tic80-opc.c (tic80_operands): Begin construction operands table.
(tic80_opcodes): Continue populating opcodes table and start
filling in the operand indices.
(tic80_num_opcodes): Add this.

opcodes/ChangeLog
opcodes/tic80-dis.c
opcodes/tic80-opc.c

index 7002b8470d0c3e4bae4fa6e81dfa7564e2c51f72..165d9b3e900981aa70658d4db28448c0d56d6928 100644 (file)
@@ -1,3 +1,17 @@
+Fri Jan  3 18:32:11 1997  Fred Fish  <fnf@cygnus.com>
+
+       * ppc-opc.c (powerpc_operands): Make comment match the
+       actual fields (no shift field).
+       * sparc-opc.c (sparc_opcodes): Document why this cannot be "const".
+start-sanitize-tic80
+       * tic80-dis.c (print_insn_tic80): Replace abort stub with a
+       partial implementation, work in progress.
+       * tic80-opc.c (tic80_operands): Begin construction operands table.
+       (tic80_opcodes): Continue populating opcodes table and start
+       filling in the operand indices.
+       (tic80_num_opcodes): Add this.
+end-sanitize-tic80
+
 Fri Jan  3 12:13:52 1997  Ian Lance Taylor  <ian@cygnus.com>
 
        * m68k-opc.c: Add #B case for moveq.
index d78d6763e231d100c53b7e7210ab846e5843f8d7..d930c80dcc6f7ee08efa39d39ce8d7764d3ed853 100644 (file)
@@ -26,5 +26,180 @@ print_insn_tic80 (memaddr, info)
      bfd_vma memaddr;
      struct disassemble_info *info;
 {
-  abort ();
+  bfd_byte buffer[4];
+  int status;
+  unsigned long insn[2];
+  const struct tic80_opcode *opcode;
+  const struct tic80_opcode *opcode_end;
+  const unsigned char *opindex;
+  const struct tic80_operand *operand;
+  int need_comma;
+  int need_paren;
+  int length = 4;
+
+  status = (*info->read_memory_func) (memaddr, buffer, 4, info);
+  if (status != 0)
+    {
+      (*info->memory_error_func) (status, memaddr, info);
+      return -1;
+    }
+
+  if (info -> endian == BFD_ENDIAN_LITTLE)
+    {
+      insn[0] = bfd_getl32 (buffer);
+    }
+  else if (info -> endian == BFD_ENDIAN_BIG)
+    {
+      insn[0] = bfd_getb32 (buffer);
+    }
+  else
+    {
+      /* FIXME: Should probably just default to one or the other */
+      abort ();
+    }
+
+  /* Find the first opcode match in the opcodes table.  FIXME: there should
+     be faster ways to find one (hash table or binary search), but don't
+     worry too much about it until other TIc80 support is finished. */
+
+  opcode_end = tic80_opcodes + tic80_num_opcodes;
+  for (opcode = tic80_opcodes; opcode < opcode_end; opcode++)
+    {
+      if ((insn[0] & opcode -> mask) == opcode -> opcode)
+       {
+         break;
+       }
+    }
+
+  if (opcode == opcode_end)
+    {
+      /* No match found, just print the bits as a .word directive */
+      (*info -> fprintf_func) (info -> stream, ".word %#08lx", insn[0]);
+    }
+  else
+    {
+      /* Match found, decode the instruction.  */
+      (*info -> fprintf_func) (info -> stream, "%s", opcode -> name);
+
+      /* Now extract and print the operands. */
+      need_comma = 0;
+      need_paren = 0;
+      if (opcode -> operands[0] != 0)
+       {
+         (*info -> fprintf_func) (info -> stream, "\t");
+       }
+      for (opindex = opcode -> operands; *opindex != 0; opindex++)
+       {
+         long value;
+
+         operand = tic80_operands + *opindex;
+
+         /* Extract the value from the instruction.  */
+         if (operand -> extract)
+           {
+             value = (*operand -> extract) (insn[0], (int *) NULL);
+           }
+         else if (operand -> bits == 32)
+           {
+             status = (*info->read_memory_func) (memaddr + 4, buffer, 4, info);
+             if (status != 0)
+               {
+                 (*info->memory_error_func) (status, memaddr, info);
+                 return -1;
+               }
+
+             if (info -> endian == BFD_ENDIAN_LITTLE)
+               {
+                 insn[1] = bfd_getl32 (buffer);
+               }
+             else if (info -> endian == BFD_ENDIAN_BIG)
+               {
+                 insn[1] = bfd_getb32 (buffer);
+               }
+             value = (long) insn[1];
+             length += 4;
+           }
+         else
+           {
+             value = (insn[0] >> operand -> shift) & ((1 << operand -> bits) - 1);
+             if ((operand -> flags & TIC80_OPERAND_SIGNED) != 0
+                 && (value & (1 << (operand -> bits - 1))) != 0)
+               value -= 1 << operand -> bits;
+           }
+
+         if (need_comma)
+           {
+             (*info -> fprintf_func) (info -> stream, ",");
+             need_comma = 0;
+           }
+
+         /* Print the operand as directed by the flags.  */
+         if ((operand -> flags & TIC80_OPERAND_GPR) != 0)
+           {
+             (*info -> fprintf_func) (info -> stream, "r%ld", value);
+           }
+         else if ((operand -> flags & TIC80_OPERAND_FPA) != 0)
+           {
+             (*info -> fprintf_func) (info -> stream, "a%ld", value);
+           }
+         else if ((operand -> flags & TIC80_OPERAND_RELATIVE) != 0)
+           {
+             (*info -> print_address_func) (memaddr + value, info);
+           }
+         else if ((operand -> flags & TIC80_OPERAND_CC_SZ) != 0)
+           {
+#if 0  /* FIXME */           
+             if (operand -> bits == 3)
+               (*info -> fprintf_func) (info -> stream, "cr%d", value);
+             else
+               {
+                 static const char *cbnames[4] = { "lt", "gt", "eq", "so" };
+                 int cr;
+                 int cc;
+
+                 cr = value >> 2;
+                 if (cr != 0)
+                   (*info -> fprintf_func) (info -> stream, "4*cr%d", cr);
+                 cc = value & 3;
+                 if (cc != 0)
+                   {
+                     if (cr != 0)
+                       (*info -> fprintf_func) (info -> stream, "+");
+                     (*info -> fprintf_func) (info -> stream, "%s", cbnames[cc]);
+                   }
+               }
+#endif
+           }
+         else
+           {
+             if ((value > 999 || value < -999)
+                 || operand -> flags & TIC80_OPERAND_BITFIELD)
+               {
+                 (*info -> fprintf_func) (info -> stream, "%#lx", value);
+               }
+             else
+               {
+                 (*info -> fprintf_func) (info -> stream, "%ld", value);
+               }
+           }
+
+         if (need_paren)
+           {
+             (*info -> fprintf_func) (info -> stream, ")");
+             need_paren = 0;
+           }
+
+         if ((operand -> flags & TIC80_OPERAND_PARENS) == 0)
+           {
+             need_comma = 1;
+           }
+         else
+           {
+             (*info -> fprintf_func) (info -> stream, "(");
+             need_paren = 1;
+           }
+       }
+    }
+
+  return (length);
 }
index 37799c4d643b188ec73a22540b11959dbddd2878..96931b5864acde42473a3e5b4c57b01c8ee84f07 100644 (file)
@@ -17,5 +17,237 @@ You should have received a copy of the GNU General Public License
 along with this file; see the file COPYING.  If not, write to the Free
 Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
+#include <stdio.h>
 #include "ansidecl.h"
 #include "opcode/tic80.h"
+
+/* This file holds the TMS320C80 (MVP) opcode table.  The table is
+   strictly constant data, so the compiler should be able to put it in
+   the .text section.
+
+   This file also holds the operand table.  All knowledge about
+   inserting operands into instructions and vice-versa is kept in this
+   file.  */
+
+\f
+/* The operands table.  The fields are:
+
+       bits, shift, insertion function, extraction function, flags
+ */
+
+const struct tic80_operand tic80_operands[] =
+{
+
+  /* The zero index is used to indicate the end of the list of operands.  */
+
+#define UNUSED (0)
+  { 0, 0, 0, 0, 0 },
+
+  /* Short signed immediate value in bits 14-0. */
+
+#define SSI (UNUSED + 1)
+  { 15, 0, NULL, NULL, TIC80_OPERAND_SIGNED },
+
+  /* Short unsigned immediate value in bits 14-0 */
+
+#define SUI (SSI + 1)
+  { 15, 0, NULL, NULL, 0 },
+
+  /* Short unsigned bitfield in bits 14-0.  We distinguish this
+     from a regular unsigned immediate value only for the convenience
+     of the disassembler and the user. */
+
+#define SUBF (SUI + 1)
+  { 15, 0, NULL, NULL, TIC80_OPERAND_BITFIELD },
+
+  /* Long signed immediate in following 32 bit word */
+
+#define LSI (SUBF + 1)
+  { 32, 0, NULL, NULL, TIC80_OPERAND_SIGNED },
+
+  /* Long unsigned immediate in following 32 bit word */
+
+#define LUI (LSI + 1)
+  { 32, 0, NULL, NULL, 0 },
+
+  /* Long unsigned bitfield in following 32 bit word.  We distinguish
+     this from a regular unsigned immediate value only for the
+     convenience of the disassembler and the user. */
+
+#define LUBF (LUI + 1)
+  { 32, 0, NULL, NULL, TIC80_OPERAND_BITFIELD },
+
+  /* Register in bits 4-0 */
+
+#define REG0 (LUBF + 1)
+  { 5, 0, NULL, NULL, TIC80_OPERAND_GPR },
+
+  /* Register in bits 26-22 */
+
+#define REG22 (REG0 + 1)
+  { 5, 22, NULL, NULL, TIC80_OPERAND_GPR },
+
+  /* Register in bits 31-27 */
+
+#define REG27 (REG22 + 1)
+  { 5, 27, NULL, NULL, TIC80_OPERAND_GPR },
+
+};
+
+const int tic80_num_operands = sizeof (tic80_operands)/sizeof(*tic80_operands);
+
+\f
+/* Macros used to generate entries for the opcodes table. */
+
+#define FIXME 0
+
+/* Short-Immediate Format Instructions */
+#define OP_SI(x)       (((x) & 0x7F) << 15)
+#define MASK_SI                OP_SI(0x7F)
+#define MASK_SI_M      OP_SI(0x7B)     /* Short-Immediate with embedded M bit */
+
+/* Long-Immediate Format Instructions */
+#define OP_LI(x)       (((x) & 0x3FF) << 12)
+#define MASK_LI                OP_LI(0x3FF)
+#define MASK_LI_M      OP_LI(0x3F7)    /* Long-Immediate with embedded M bit */
+
+/* Register Format Instructions */
+#define OP_REG(x)      OP_LI(x)        /* For readability */
+#define MASK_REG       MASK_LI         /* For readability */
+#define MASK_REG_M     MASK_LI_M       /* For readability */
+
+const struct tic80_opcode tic80_opcodes[] = {
+
+  /* Signed integer ADD */
+
+  {"add",      OP_SI(0x58),    MASK_SI,        FMT_SI,         {SSI, REG22, REG27}     },
+  {"add",      OP_LI(0x3B1),   MASK_LI,        FMT_LI,         {LSI, REG22, REG27}     },
+  {"add",      OP_REG(0x3B0),  MASK_REG,       FMT_REG,        {REG0, REG22, REG27}    },
+
+  /* Unsigned integer ADD */
+
+  {"addu",     OP_SI(0x59),    MASK_SI,        FMT_SI,         {SSI, REG22, REG27}     },
+  {"addu",     OP_LI(0x3B3),   MASK_LI,        FMT_LI,         {LSI, REG22, REG27}     },
+  {"addu",     OP_REG(0x3B2),  MASK_REG,       FMT_REG,        {REG0, REG22, REG27}    },
+
+  /* Bitwise AND */
+
+  {"and",      OP_SI(0x11),    MASK_SI,        FMT_SI,         {SUBF, REG22, REG27}    },
+  {"and",      OP_LI(0x323),   MASK_LI,        FMT_LI,         {LUBF, REG22, REG27}    },
+  {"and",      OP_REG(0x322),  MASK_REG,       FMT_REG,        {REG0, REG22, REG27}    },
+
+  {"and.tt",   OP_SI(0x11),    MASK_SI,        FMT_SI,         {SUBF, REG22, REG27}    },
+  {"and.tt",   OP_LI(0x323),   MASK_LI,        FMT_LI,         {LUBF, REG22, REG27}    },
+  {"and.tt",   OP_REG(0x322),  MASK_REG,       FMT_REG,        {REG0, REG22, REG27}    },
+
+  /* Bitwise AND with ones complement of both sources */
+
+  {"and.ff",   OP_SI(0x18),    MASK_SI,        FMT_SI,         {SUBF, REG22, REG27}    },
+  {"and.ff",   OP_LI(0x331),   MASK_LI,        FMT_LI,         {LUBF, REG22, REG27}    },
+  {"and.ff",   OP_REG(0x330),  MASK_REG,       FMT_REG,        {REG0, REG22, REG27}    },
+
+  /* Bitwise AND with ones complement of source 1 */
+
+  {"and.ft",   OP_SI(0x14),    MASK_SI,        FMT_SI,         {SUBF, REG22, REG27}    },
+  {"and.ft",   OP_LI(0x329),   MASK_LI,        FMT_LI,         {LUBF, REG22, REG27}    },
+  {"and.ft",   OP_REG(0x328),  MASK_REG,       FMT_REG,        {REG0, REG22, REG27}    },
+
+  /* Bitwise AND with ones complement of source 2 */
+
+  {"and.tf",   OP_SI(0x12),    MASK_SI,        FMT_SI,         {SUBF, REG22, REG27}    },
+  {"and.tf",   OP_LI(0x325),   MASK_LI,        FMT_LI,         {LUBF, REG22, REG27}    },
+  {"and.tf",   OP_REG(0x324),  MASK_REG,       FMT_REG,        {REG0, REG22, REG27}    },
+
+  /* WORK IN PROGRESS BELOW THIS POINT */
+
+  {"brcr",     OP_LI(0x30D),   MASK_LI,        FMT_LI,         FIXME},
+  {"brcr",     OP_REG(0x30C),  MASK_REG,       FMT_REG,        FIXME},
+  {"brcr",     OP_SI(0x6),     MASK_SI,        FMT_SI,         FIXME},
+  {"cmnd",     OP_LI(0x305),   MASK_LI,        FMT_LI,         FIXME},
+  {"cmnd",     OP_REG(0x304),  MASK_REG,       FMT_REG,        FIXME},
+  {"cmnd",     OP_SI(0x2),     MASK_SI,        FMT_SI,         FIXME},
+  {"illop0",   OP_SI(0),       MASK_SI,        FMT_SI,         FIXME},
+  {"ld",       OP_LI(0x345),   MASK_LI_M,      FMT_LI,         FIXME},
+  {"ld",       OP_REG(0x344),  MASK_REG_M,     FMT_REG,        FIXME},
+  {"ld",       OP_SI(0x22),    MASK_SI_M,      FMT_SI,         FIXME},
+  {"ld.b",     OP_LI(0x341),   MASK_LI_M,      FMT_LI,         FIXME},
+  {"ld.b",     OP_REG(0x340),  MASK_REG_M,     FMT_REG,        FIXME},
+  {"ld.b",     OP_SI(0x20),    MASK_SI_M,      FMT_SI,         FIXME},
+  {"ld.d",     OP_LI(0x347),   MASK_LI_M,      FMT_LI,         FIXME},
+  {"ld.d",     OP_REG(0x346),  MASK_REG_M,     FMT_REG,        FIXME},
+  {"ld.d",     OP_SI(0x23),    MASK_SI_M,      FMT_SI,         FIXME},
+  {"ld.h",     OP_LI(0x343),   MASK_LI_M,      FMT_LI,         FIXME},
+  {"ld.h",     OP_REG(0x342),  MASK_REG_M,     FMT_REG,        FIXME},
+  {"ld.h",     OP_SI(0x21),    MASK_SI_M,      FMT_SI,         FIXME},
+  {"ld.u",     OP_LI(0x355),   MASK_LI_M,      FMT_LI,         FIXME},
+  {"ld.u",     OP_REG(0x354),  MASK_REG_M,     FMT_REG,        FIXME},
+  {"ld.u",     OP_SI(0x2A),    MASK_SI_M,      FMT_SI,         FIXME},
+  {"ld.ub",    OP_LI(0x351),   MASK_LI_M,      FMT_LI,         FIXME},
+  {"ld.ub",    OP_REG(0x350),  MASK_REG_M,     FMT_REG,        FIXME},
+  {"ld.ub",    OP_SI(0x28),    MASK_SI_M,      FMT_SI,         FIXME},
+  {"ld.ud",    OP_LI(0x357),   MASK_LI_M,      FMT_LI,         FIXME},
+  {"ld.ud",    OP_REG(0x356),  MASK_REG_M,     FMT_REG,        FIXME},
+  {"ld.ud",    OP_SI(0x2B),    MASK_SI_M,      FMT_SI,         FIXME},
+  {"ld.uh",    OP_LI(0x353),   MASK_LI_M,      FMT_LI,         FIXME},
+  {"ld.uh",    OP_REG(0x352),  MASK_REG_M,     FMT_REG,        FIXME},
+  {"ld.uh",    OP_SI(0x29),    MASK_SI_M,      FMT_SI,         FIXME},
+  {"or.ff",    OP_LI(0x33D),   MASK_LI,        FMT_LI,         FIXME},
+  {"or.ff",    OP_REG(0x33C),  MASK_REG,       FMT_REG,        FIXME},
+  {"or.ff",    OP_SI(0x1E),    MASK_SI,        FMT_SI,         FIXME},
+  {"or.ft",    OP_LI(0x33B),   MASK_LI,        FMT_LI,         FIXME},
+  {"or.ft",    OP_REG(0x33A),  MASK_REG,       FMT_REG,        FIXME},
+  {"or.ft",    OP_SI(0x1D),    MASK_SI,        FMT_SI,         FIXME},
+  {"or.tf",    OP_LI(0x337),   MASK_LI,        FMT_LI,         FIXME},
+  {"or.tf",    OP_REG(0x336),  MASK_REG,       FMT_REG,        FIXME},
+  {"or.tf",    OP_SI(0x1B),    MASK_SI,        FMT_SI,         FIXME},
+  {"or.tt",    OP_LI(0x32F),   MASK_LI,        FMT_LI,         FIXME},
+  {"or.tt",    OP_REG(0x32E),  MASK_REG,       FMT_REG,        FIXME},
+  {"or.tt",    OP_SI(0x17),    MASK_SI,        FMT_SI,         FIXME},
+  {"rdcr",     OP_LI(0x309),   MASK_LI,        FMT_LI,         FIXME},
+  {"rdcr",     OP_REG(0x308),  MASK_REG,       FMT_REG,        FIXME},
+  {"rdcr",     OP_SI(0x4),     MASK_SI,        FMT_SI,         FIXME},
+  {"shift.dm", OP_REG(0x312),  MASK_REG,       FMT_REG,        FIXME},
+  {"shift.dm", OP_SI(0x9),     MASK_SI,        FMT_SI,         FIXME},
+  {"shift.ds", OP_REG(0x314),  MASK_REG,       FMT_REG,        FIXME},
+  {"shift.ds", OP_SI(0xA),     MASK_SI,        FMT_SI,         FIXME},
+  {"shift.dz", OP_REG(0x310),  MASK_REG,       FMT_REG,        FIXME},
+  {"shift.dz", OP_SI(0x8),     MASK_SI,        FMT_SI,         FIXME},
+  {"shift.em", OP_REG(0x318),  MASK_REG,       FMT_REG,        FIXME},
+  {"shift.em", OP_SI(0xC),     MASK_SI,        FMT_SI,         FIXME},
+  {"shift.es", OP_REG(0x31A),  MASK_REG,       FMT_REG,        FIXME},
+  {"shift.es", OP_SI(0xD),     MASK_SI,        FMT_SI,         FIXME},
+  {"shift.ez", OP_REG(0x316),  MASK_REG,       FMT_REG,        FIXME},
+  {"shift.ez", OP_SI(0xB),     MASK_SI,        FMT_SI,         FIXME},
+  {"shift.im", OP_REG(0x31E),  MASK_REG,       FMT_REG,        FIXME},
+  {"shift.im", OP_SI(0xF),     MASK_SI,        FMT_SI,         FIXME},
+  {"shift.iz", OP_REG(0x31C),  MASK_REG,       FMT_REG,        FIXME},
+  {"shift.iz", OP_SI(0xE),     MASK_SI,        FMT_SI,         FIXME},
+  {"st",       OP_LI(0x365),   MASK_LI_M,      FMT_LI,         FIXME},
+  {"st",       OP_REG(0x364),  MASK_REG_M,     FMT_REG,        FIXME},
+  {"st",       OP_SI(0x32),    MASK_SI_M,      FMT_SI,         FIXME},
+  {"st.b",     OP_LI(0x361),   MASK_LI_M,      FMT_LI,         FIXME},
+  {"st.b",     OP_REG(0x360),  MASK_REG_M,     FMT_REG,        FIXME},
+  {"st.b",     OP_SI(0x30),    MASK_SI_M,      FMT_SI,         FIXME},
+  {"st.d",     OP_LI(0x367),   MASK_LI_M,      FMT_LI,         FIXME},
+  {"st.d",     OP_REG(0x366),  MASK_REG_M,     FMT_REG,        FIXME},
+  {"st.d",     OP_SI(0x33),    MASK_SI_M,      FMT_SI,         FIXME},
+  {"st.h",     OP_LI(0x363),   MASK_LI_M,      FMT_LI,         FIXME},
+  {"st.h",     OP_REG(0x362),  MASK_REG_M,     FMT_REG,        FIXME},
+  {"st.h",     OP_SI(0x31),    MASK_SI_M,      FMT_SI,         FIXME},
+  {"swcr",     OP_LI(0x30B),   MASK_LI,        FMT_LI,         FIXME},
+  {"swcr",     OP_REG(0x30A),  MASK_REG,       FMT_REG,        FIXME},
+  {"swcr",     OP_SI(0x5),     MASK_SI,        FMT_SI,         FIXME},
+  {"trap",     OP_LI(0x303),   MASK_LI,        FMT_LI,         FIXME},
+  {"trap",     OP_REG(0x302),  MASK_REG,       FMT_REG,        FIXME},
+  {"trap",     OP_SI(0x1),     MASK_SI,        FMT_SI,         FIXME},
+  {"xnor",     OP_LI(0x333),   MASK_LI,        FMT_LI,         FIXME},
+  {"xnor",     OP_REG(0x332),  MASK_REG,       FMT_REG,        FIXME},
+  {"xnor",     OP_SI(0x19),    MASK_SI,        FMT_SI,         FIXME},
+  {"xor",      OP_LI(0x32D),   MASK_LI,        FMT_LI,         FIXME},
+  {"xor",      OP_REG(0x32C),  MASK_REG,       FMT_REG,        FIXME},
+  {"xor",      OP_SI(0x16),    MASK_SI,        FMT_SI,         FIXME},
+
+};
+
+const int tic80_num_opcodes = sizeof (tic80_opcodes) / sizeof (tic80_opcodes[0]);
+