* tic80-dis.c (print_insn_tic80): Print TIC80_OPERAND_RELATIVE
authorFred Fish <fnf@specifix.com>
Sun, 5 Jan 1997 02:10:14 +0000 (02:10 +0000)
committerFred Fish <fnf@specifix.com>
Sun, 5 Jan 1997 02:10:14 +0000 (02:10 +0000)
correctly.  Add support for printing TIC80_OPERAND_BITNUM and
TIC80_OPERAND_CC, and TIC80_OPERAND_CR operands in symbolic
form.
* tic80-opc.c (tic80_operands): Add SSOFF, LSOFF, BITNUM,
CC, SICR, and LICR table entries.
(tic80_opcodes): Add and test "nop", "br", "bbo", "bbz",
"bcnd", and "brcr" opcodes.

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

index 165d9b3e900981aa70658d4db28448c0d56d6928..c0c820a02938eaa15bb5cbb650687bc5708de6f2 100644 (file)
@@ -1,3 +1,16 @@
+start-sanitize-tic80
+Sat Jan  4 19:05:05 1997  Fred Fish  <fnf@cygnus.com>
+
+       * tic80-dis.c (print_insn_tic80): Print TIC80_OPERAND_RELATIVE
+       correctly.  Add support for printing TIC80_OPERAND_BITNUM and
+       TIC80_OPERAND_CC, and TIC80_OPERAND_CR operands in symbolic
+       form.
+       * tic80-opc.c (tic80_operands): Add SSOFF, LSOFF, BITNUM,
+       CC, SICR, and LICR table entries.
+       (tic80_opcodes): Add and test "nop", "br", "bbo", "bbz",
+       "bcnd", and "brcr" opcodes.
+
+end-sanitize-tic80
 Fri Jan  3 18:32:11 1997  Fred Fish  <fnf@cygnus.com>
 
        * ppc-opc.c (powerpc_operands): Make comment match the
index d930c80dcc6f7ee08efa39d39ce8d7764d3ed853..2cb0753b4ee2f1c5cf87a6283c0658c63f3119ef 100644 (file)
@@ -144,31 +144,123 @@ print_insn_tic80 (memaddr, info)
            }
          else if ((operand -> flags & TIC80_OPERAND_RELATIVE) != 0)
            {
-             (*info -> print_address_func) (memaddr + value, info);
+             (*info -> print_address_func) (memaddr + 4 * value, info);
            }
-         else if ((operand -> flags & TIC80_OPERAND_CC_SZ) != 0)
+         else if ((operand -> flags & TIC80_OPERAND_BITNUM) != 0)
            {
-#if 0  /* FIXME */           
-             if (operand -> bits == 3)
-               (*info -> fprintf_func) (info -> stream, "cr%d", value);
+             char *syms[30] = {
+               "eq.b", "ne.b", "gt.b", "le.b", "lt.b", "ge.b",
+               "hi.b", "ls.b", "lo.b", "hs.b", "eq.h", "ne.h",
+               "gt.h", "le.h", "lt.h", "ge.h", "hi.h", "ls.h",
+               "lo.h", "hs.h", "eq.w", "ne.w", "gt.w", "le.w",
+               "lt.w", "ge.w", "hi.w", "ls.w", "lo.w", "hs.w"
+             };
+             int bitnum = ~value & 0x1F;
+
+             if (bitnum < 30)
+               {
+                 /* Found a value within range */
+                 (*info -> fprintf_func) (info -> stream, "%s", syms[bitnum]);
+               }
              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]);
-                   }
+                 /* Not in range, just print as bit number */
+                 (*info -> fprintf_func) (info -> stream, "%ld", bitnum);
+               }
+           }
+         else if ((operand -> flags & TIC80_OPERAND_CC) != 0)
+           {
+             char *syms[24] = {
+               "nev.b", "gt0.b", "eq0.b", "ge0.b", "lt0.b", "ne0.b", "le0.b", "alw.b",
+               "nev.h", "gt0.h", "eq0.h", "ge0.h", "lt0.h", "ne0.h", "le0.h", "alw.h",
+               "nev.w", "gt0.w", "eq0.w", "ge0.w", "lt0.w", "ne0.w", "le0.w", "alw.w"
+             };
+             if (value < 24)
+               {
+                 /* Found a value within range */
+                 (*info -> fprintf_func) (info -> stream, "%s", syms[value]);
+               }
+             else
+               {
+                 /* Not in range, just print as decimal digit. */
+                 (*info -> fprintf_func) (info -> stream, "%ld", value);
+               }
+           }
+         else if ((operand -> flags & TIC80_OPERAND_CR) != 0)
+           {
+             char *tmp;
+             switch (value)
+               {
+               case 0:         tmp = "EPC";            break;
+               case 1:         tmp = "EIP";            break;
+               case 2:         tmp = "CONFIG";         break;
+               case 4:         tmp = "INTPEN";         break;
+               case 6:         tmp = "IE";             break;
+               case 8:         tmp = "FPST";           break;
+               case 0xA:       tmp = "PPERROR";        break;
+               case 0xD:       tmp = "PKTREQ";         break;
+               case 0xE:       tmp = "TCOUNT";         break;
+               case 0xF:       tmp = "TSCALE";         break;
+               case 0x10:      tmp = "FLTOP";          break;
+               case 0x11:      tmp = "FLTADR";         break;
+               case 0x12:      tmp = "FLTTAG";         break;
+               case 0x13:      tmp = "FLTDTL";         break;
+               case 0x14:      tmp = "FLTDTH";         break;
+               case 0x20:      tmp = "SYSSTK";         break;
+               case 0x21:      tmp = "SYSTMP";         break;
+               case 0x30:      tmp = "MPC";            break;
+               case 0x31:      tmp = "MIP";            break;
+               case 0x33:      tmp = "ECOMCNTL";       break;
+               case 0x34:      tmp = "ANASTAT";        break;
+               case 0x39:      tmp = "BRK1";           break;
+               case 0x3A:      tmp = "BRK2";           break;
+               case 0x200:     tmp = "ITAG0";          break;
+               case 0x201:     tmp = "ITAG1";          break;
+               case 0x202:     tmp = "ITAG2";          break;
+               case 0x203:     tmp = "ITAG3";          break;
+               case 0x204:     tmp = "ITAG4";          break;
+               case 0x205:     tmp = "ITAG5";          break;
+               case 0x206:     tmp = "ITAG6";          break;
+               case 0x207:     tmp = "ITAG7";          break;
+               case 0x208:     tmp = "ITAG8";          break;
+               case 0x209:     tmp = "ITAG9";          break;
+               case 0x20A:     tmp = "ITAG10";         break;
+               case 0x20B:     tmp = "ITAG11";         break;
+               case 0x20C:     tmp = "ITAG12";         break;
+               case 0x20D:     tmp = "ITAG13";         break;
+               case 0x20E:     tmp = "ITAG14";         break;
+               case 0x20F:     tmp = "ITAG15";         break;
+               case 0x300:     tmp = "ILRU";           break;
+               case 0x400:     tmp = "DTAG0";          break;
+               case 0x401:     tmp = "DTAG1";          break;
+               case 0x402:     tmp = "DTAG2";          break;
+               case 0x403:     tmp = "DTAG3";          break;
+               case 0x404:     tmp = "DTAG4";          break;
+               case 0x405:     tmp = "DTAG5";          break;
+               case 0x406:     tmp = "DTAG6";          break;
+               case 0x407:     tmp = "DTAG7";          break;
+               case 0x408:     tmp = "DTAG8";          break;
+               case 0x409:     tmp = "DTAG9";          break;
+               case 0x40A:     tmp = "DTAG10";         break;
+               case 0x40B:     tmp = "DTAG11";         break;
+               case 0x40C:     tmp = "DTAG12";         break;
+               case 0x40D:     tmp = "DTAG13";         break;
+               case 0x40E:     tmp = "DTAG14";         break;
+               case 0x40F:     tmp = "DTAG15";         break;
+               case 0x500:     tmp = "DLRU";           break;
+               case 0x4000:    tmp = "IN0P";           break;
+               case 0x4001:    tmp = "IN1P";           break;
+               case 0x4002:    tmp = "OUTP";           break;
+               default:        tmp = NULL;             break;
+               }
+             if (tmp != NULL)
+               {
+                 (*info -> fprintf_func) (info -> stream, "%s", tmp);
+               }
+             else
+               {
+                 (*info -> fprintf_func) (info -> stream, "%#lx", value);
                }
-#endif
            }
          else
            {
index 96931b5864acde42473a3e5b4c57b01c8ee84f07..27b853d576c68bd9d268989683a88738a1fa3fc1 100644 (file)
@@ -92,6 +92,36 @@ const struct tic80_operand tic80_operands[] =
 #define REG27 (REG22 + 1)
   { 5, 27, NULL, NULL, TIC80_OPERAND_GPR },
 
+  /* Short signed offset in bits 14-0 */
+
+#define SSOFF (REG27 + 1)
+  { 15, 0, NULL, NULL, TIC80_OPERAND_RELATIVE | TIC80_OPERAND_SIGNED },
+
+  /* Long signed offset in following 32 bit word */
+
+#define LSOFF (SSOFF + 1)
+  {32, 0, NULL, NULL, TIC80_OPERAND_RELATIVE | TIC80_OPERAND_SIGNED },
+
+  /* BITNUM in bits 31-27 */
+
+#define BITNUM (LSOFF + 1)
+  { 5, 27, NULL, NULL, TIC80_OPERAND_BITNUM },
+
+  /* Condition code in bits 31-27 */
+
+#define CC (BITNUM + 1)
+  { 5, 27, NULL, NULL, TIC80_OPERAND_CC },
+
+  /* Control register number in bits 14-0 */
+
+#define SICR (CC + 1)
+  { 15, 0, NULL, NULL, TIC80_OPERAND_CR },
+
+  /* Control register number in next 32 bit word */
+
+#define LICR (SICR + 1)
+  { 32, 0, NULL, NULL, TIC80_OPERAND_CR },
+
 };
 
 const int tic80_num_operands = sizeof (tic80_operands)/sizeof(*tic80_operands);
@@ -118,6 +148,23 @@ const int tic80_num_operands = sizeof (tic80_operands)/sizeof(*tic80_operands);
 
 const struct tic80_opcode tic80_opcodes[] = {
 
+  /* The "nop" instruction is really "rdcr 0,r0".  We put it first so that this
+     specific bit pattern will get dissembled as a nop rather than an rdcr. The
+     mask of all ones ensures that this will happen. */
+
+  {"nop",      OP_SI(0x4),     ~0,             0,              {0}                     },
+
+  /* The "br" instruction is really "bbz target,r0,31".  We put it first so that
+     this specific bit pattern will get disassembled as a br rather than bbz. */
+
+  {"br",       OP_SI(0x48),    0xFFFF8000,     0,              {SSOFF}                 },
+  {"br",       OP_LI(0x391),   0xFFFFF000,     0,              {LSOFF}                 },
+  {"br",       OP_REG(0x390),  0xFFFFF000,     0,              {REG0}                  },
+
+  {"br.a",     OP_SI(0x49),    0xFFFF8000,     0,              {SSOFF}                 },
+  {"br.a",     OP_LI(0x393),   0xFFFFF000,     0,              {LSOFF}                 },
+  {"br.a",     OP_REG(0x392),  0xFFFFF000,     0,              {REG0}                  },
+
   /* Signed integer ADD */
 
   {"add",      OP_SI(0x58),    MASK_SI,        FMT_SI,         {SSI, REG22, REG27}     },
@@ -158,11 +205,50 @@ const struct tic80_opcode tic80_opcodes[] = {
   {"and.tf",   OP_LI(0x325),   MASK_LI,        FMT_LI,         {LUBF, REG22, REG27}    },
   {"and.tf",   OP_REG(0x324),  MASK_REG,       FMT_REG,        {REG0, REG22, REG27}    },
 
+  /* Branch Bit One - nonannulled */
+
+  {"bbo",      OP_SI(0x4A),    MASK_SI,        FMT_SI,         {SSOFF, REG22, BITNUM}  },
+  {"bbo",      OP_LI(0x395),   MASK_LI,        FMT_LI,         {LSOFF, REG22, BITNUM}  },
+  {"bbo",      OP_REG(0x394),  MASK_REG,       FMT_REG,        {REG0, REG22, BITNUM}   },
+
+  /* Branch Bit One - annulled */
+
+  {"bbo.a",    OP_SI(0x4B),    MASK_SI,        FMT_SI,         {SSOFF, REG22, BITNUM}  },
+  {"bbo.a",    OP_LI(0x397),   MASK_LI,        FMT_LI,         {LSOFF, REG22, BITNUM}  },
+  {"bbo.a",    OP_REG(0x396),  MASK_REG,       FMT_REG,        {REG0, REG22, BITNUM}   },
+
+  /* Branch Bit Zero - nonannulled */
+
+  {"bbz",      OP_SI(0x48),    MASK_SI,        FMT_SI,         {SSOFF, REG22, BITNUM}  },
+  {"bbz",      OP_LI(0x391),   MASK_LI,        FMT_LI,         {LSOFF, REG22, BITNUM}  },
+  {"bbz",      OP_REG(0x390),  MASK_REG,       FMT_REG,        {REG0, REG22, BITNUM}   },
+
+  /* Branch Bit Zero - annulled */
+
+  {"bbz.a",    OP_SI(0x49),    MASK_SI,        FMT_SI,         {SSOFF, REG22, BITNUM}  },
+  {"bbz.a",    OP_LI(0x393),   MASK_LI,        FMT_LI,         {LSOFF, REG22, BITNUM}  },
+  {"bbz.a",    OP_REG(0x392),  MASK_REG,       FMT_REG,        {REG0, REG22, BITNUM}   },
+
+  /* Branch Conditional - nonannulled */
+
+  {"bcnd",     OP_SI(0x4C),    MASK_SI,        FMT_SI,         {SSOFF, REG22, CC}      },
+  {"bcnd",     OP_LI(0x399),   MASK_LI,        FMT_LI,         {LSOFF, REG22, CC}      },
+  {"bcnd",     OP_REG(0x398),  MASK_REG,       FMT_REG,        {REG0, REG22, CC}       },
+
+  /* Branch Conditional - annulled */
+
+  {"bcnd.a",   OP_SI(0x4D),    MASK_SI,        FMT_SI,         {SSOFF, REG22, CC}      },
+  {"bcnd.a",   OP_LI(0x39B),   MASK_LI,        FMT_LI,         {LSOFF, REG22, CC}      },
+  {"bcnd.a",   OP_REG(0x39A),  MASK_REG,       FMT_REG,        {REG0, REG22, CC}       },
+
+  /* Branch Control Register */
+
+  {"brcr",     OP_SI(0x6),     MASK_SI,        FMT_SI,         {SICR}                  },
+  {"brcr",     OP_LI(0x30D),   MASK_LI,        FMT_LI,         {LICR}                  },
+  {"brcr",     OP_REG(0x30C),  MASK_REG,       FMT_REG,        {REG0}                  },
+
   /* 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},