opcodes/
[deliverable/binutils-gdb.git] / opcodes / bfin-dis.c
index 00799d254c0e7e6e0ce44e824e32415dbf9535c1..ebacd4618f9604dece3900f78ab3c1810cbcc648 100644 (file)
@@ -138,6 +138,9 @@ fmtconst (const_forms_t cf, TIword x, bfd_vma pc, disassemble_info *outf)
       if (constant_formats[cf].pcrel)
        ea += pc;
 
+     /* truncate to 32-bits for proper symbol lookup/matching */
+     ea = (bu32)ea;
+
      if (outf->symbol_at_address_func (ea, outf) || !constant_formats[cf].exact)
        {
          outf->print_address_func (ea, outf);
@@ -242,6 +245,7 @@ enum machine_registers
   REG_BL0, REG_BL1, REG_BL2, REG_BL3, REG_LL0, REG_LL1, REG_LL2, REG_LL3,
   REG_IH0, REG_IH1, REG_IH2, REG_IH3, REG_MH0, REG_MH1, REG_MH2, REG_MH3,
   REG_BH0, REG_BH1, REG_BH2, REG_BH3, REG_LH0, REG_LH1, REG_LH2, REG_LH3,
+  REG_AC0_COPY, REG_V_COPY, REG_RND_MOD,
   REG_LASTREG,
 };
 
@@ -277,6 +281,7 @@ static const char *reg_names[] =
   "B0.L", "B1.L", "B2.L", "B3.L", "L0.L", "L1.L", "L2.L", "L3.L",
   "I0.H", "I1.H", "I2.H", "I3.H", "M0.H", "M1.H", "M2.H", "M3.H",
   "B0.H", "B1.H", "B2.H", "B3.H", "L0.H", "L1.H", "L2.H", "L3.H",
+  "AC0_COPY", "V_COPY", "RND_MOD",
   "LASTREG",
   0
 };
@@ -398,10 +403,14 @@ static enum machine_registers decode_regs_hi[] =
 
 static enum machine_registers decode_statbits[] =
 {
-  REG_AZ, REG_AN, REG_LASTREG, REG_LASTREG, REG_LASTREG, REG_LASTREG, REG_AQ, REG_LASTREG,
-  REG_LASTREG, REG_LASTREG, REG_LASTREG, REG_LASTREG, REG_AC0, REG_AC1, REG_LASTREG, REG_LASTREG,
-  REG_AV0, REG_AV0S, REG_AV1, REG_AV1S, REG_LASTREG, REG_LASTREG, REG_LASTREG, REG_LASTREG,
-  REG_V, REG_VS, REG_LASTREG, REG_LASTREG, REG_LASTREG, REG_LASTREG, REG_LASTREG, REG_LASTREG,
+  REG_AZ,        REG_AN,        REG_AC0_COPY,    REG_V_COPY,
+  REG_LASTREG,   REG_LASTREG,   REG_AQ,          REG_LASTREG,
+  REG_RND_MOD,   REG_LASTREG,   REG_LASTREG,     REG_LASTREG,
+  REG_AC0,       REG_AC1,       REG_LASTREG,     REG_LASTREG,
+  REG_AV0,       REG_AV0S,      REG_AV1,         REG_AV1S,
+  REG_LASTREG,   REG_LASTREG,   REG_LASTREG,     REG_LASTREG,
+  REG_V,         REG_VS,        REG_LASTREG,     REG_LASTREG,
+  REG_LASTREG,   REG_LASTREG,   REG_LASTREG,     REG_LASTREG,
 };
 
 #define statbits(x) REGNAME (decode_statbits[(x) & 31])
@@ -430,13 +439,18 @@ static enum machine_registers decode_allregs[] =
   REG_LASTREG,
 };
 
-#define IS_DREG(g,r)   ((g) == 0)
-#define IS_PREG(g,r)   ((g) == 1)
+#define IS_DREG(g,r)   ((g) == 0 && (r) < 8)
+#define IS_PREG(g,r)   ((g) == 1 && (r) < 8)
 #define IS_AREG(g,r)   ((g) == 4 && (r) >= 0 && (r) < 4)
-#define IS_GENREG(g,r) ((g) == 0 || (g) == 1 || IS_AREG (g, r))
-#define IS_DAGREG(g,r) ((g) == 2 || (g) == 3)
+#define IS_GENREG(g,r) ((((g) == 0 || (g) == 1) && (r) < 8) || IS_AREG (g, r))
+#define IS_DAGREG(g,r) (((g) == 2 || (g) == 3) && (r) < 8)
 #define IS_SYSREG(g,r) \
   (((g) == 4 && ((r) == 6 || (r) == 7)) || (g) == 6 || (g) == 7)
+#define IS_RESERVEDREG(g,r) \
+  (((r) > 7) || ((g) == 4 && ((r) == 4 || (r) == 5)) || (g) == 5)
+
+#define allreg(r,g)    (!IS_RESERVEDREG (g, r))
+#define mostreg(r,g)   (!(IS_DREG (g, r) || IS_PREG (g, r) || IS_RESERVEDREG (g, r)))
 
 #define allregs(x,i)   REGNAME (decode_allregs[((i) << 3) | x])
 #define uimm16s4(x)    fmtconst (c_uimm16s4, x, 0, outf)
@@ -749,6 +763,8 @@ decode_ProgCtrl_0 (TIword iw0, disassemble_info *outf)
 
   if (prgfunc == 0 && poprnd == 0)
     OUTS (outf, "NOP");
+  else if (parallel)
+    return 0;
   else if (prgfunc == 1 && poprnd == 0)
     OUTS (outf, "RTS");
   else if (prgfunc == 1 && poprnd == 1)
@@ -767,35 +783,35 @@ decode_ProgCtrl_0 (TIword iw0, disassemble_info *outf)
     OUTS (outf, "SSYNC");
   else if (prgfunc == 2 && poprnd == 5)
     OUTS (outf, "EMUEXCPT");
-  else if (prgfunc == 3)
+  else if (prgfunc == 3 && IS_DREG (0, poprnd))
     {
       OUTS (outf, "CLI ");
       OUTS (outf, dregs (poprnd));
     }
-  else if (prgfunc == 4)
+  else if (prgfunc == 4 && IS_DREG (0, poprnd))
     {
       OUTS (outf, "STI ");
       OUTS (outf, dregs (poprnd));
     }
-  else if (prgfunc == 5)
+  else if (prgfunc == 5 && IS_PREG (1, poprnd))
     {
       OUTS (outf, "JUMP (");
       OUTS (outf, pregs (poprnd));
       OUTS (outf, ")");
     }
-  else if (prgfunc == 6)
+  else if (prgfunc == 6 && IS_PREG (1, poprnd))
     {
       OUTS (outf, "CALL (");
       OUTS (outf, pregs (poprnd));
       OUTS (outf, ")");
     }
-  else if (prgfunc == 7)
+  else if (prgfunc == 7 && IS_PREG (1, poprnd))
     {
       OUTS (outf, "CALL (PC + ");
       OUTS (outf, pregs (poprnd));
       OUTS (outf, ")");
     }
-  else if (prgfunc == 8)
+  else if (prgfunc == 8 && IS_PREG (1, poprnd))
     {
       OUTS (outf, "JUMP (PC + ");
       OUTS (outf, pregs (poprnd));
@@ -811,7 +827,7 @@ decode_ProgCtrl_0 (TIword iw0, disassemble_info *outf)
       OUTS (outf, "EXCPT ");
       OUTS (outf, uimm4 (poprnd));
     }
-  else if (prgfunc == 11)
+  else if (prgfunc == 11 && IS_PREG (1, poprnd) && poprnd <= 5)
     {
       OUTS (outf, "TESTSET (");
       OUTS (outf, pregs (poprnd));
@@ -833,6 +849,9 @@ decode_CaCTRL_0 (TIword iw0, disassemble_info *outf)
   int op  = ((iw0 >> CaCTRL_op_bits) & CaCTRL_op_mask);
   int reg = ((iw0 >> CaCTRL_reg_bits) & CaCTRL_reg_mask);
 
+  if (parallel)
+    return 0;
+
   if (a == 0 && op == 0)
     {
       OUTS (outf, "PREFETCH[");
@@ -897,12 +916,15 @@ decode_PushPopReg_0 (TIword iw0, disassemble_info *outf)
   int grp = ((iw0 >> PushPopReg_grp_bits) & PushPopReg_grp_mask);
   int reg = ((iw0 >> PushPopReg_reg_bits) & PushPopReg_reg_mask);
 
-  if (W == 0)
+  if (parallel)
+    return 0;
+
+  if (W == 0 && mostreg (reg, grp))
     {
       OUTS (outf, allregs (reg, grp));
       OUTS (outf, " = [SP++]");
     }
-  else if (W == 1)
+  else if (W == 1 && allreg (reg, grp) && !(grp == 1 && reg == 6))
     {
       OUTS (outf, "[--SP] = ");
       OUTS (outf, allregs (reg, grp));
@@ -925,6 +947,12 @@ decode_PushPopMultiple_0 (TIword iw0, disassemble_info *outf)
   int dr = ((iw0 >> PushPopMultiple_dr_bits) & PushPopMultiple_dr_mask);
   int pr = ((iw0 >> PushPopMultiple_pr_bits) & PushPopMultiple_pr_mask);
 
+  if (parallel)
+    return 0;
+
+  if (pr > 5)
+    return 0;
+
   if (W == 1 && d == 1 && p == 1)
     {
       OUTS (outf, "[--SP] = (R7:");
@@ -933,13 +961,13 @@ decode_PushPopMultiple_0 (TIword iw0, disassemble_info *outf)
       OUTS (outf, imm5d (pr));
       OUTS (outf, ")");
     }
-  else if (W == 1 && d == 1 && p == 0)
+  else if (W == 1 && d == 1 && p == 0 && pr == 0)
     {
       OUTS (outf, "[--SP] = (R7:");
       OUTS (outf, imm5d (dr));
       OUTS (outf, ")");
     }
-  else if (W == 1 && d == 0 && p == 1)
+  else if (W == 1 && d == 0 && p == 1 && dr == 0)
     {
       OUTS (outf, "[--SP] = (P5:");
       OUTS (outf, imm5d (pr));
@@ -953,13 +981,13 @@ decode_PushPopMultiple_0 (TIword iw0, disassemble_info *outf)
       OUTS (outf, imm5d (pr));
       OUTS (outf, ") = [SP++]");
     }
-  else if (W == 0 && d == 1 && p == 0)
+  else if (W == 0 && d == 1 && p == 0 && pr == 0)
     {
       OUTS (outf, "(R7:");
       OUTS (outf, imm5d (dr));
       OUTS (outf, ") = [SP++]");
     }
-  else if (W == 0 && d == 0 && p == 1)
+  else if (W == 0 && d == 0 && p == 1 && dr == 0)
     {
       OUTS (outf, "(P5:");
       OUTS (outf, imm5d (pr));
@@ -983,6 +1011,9 @@ decode_ccMV_0 (TIword iw0, disassemble_info *outf)
   int src = ((iw0 >> CCmv_src_bits) & CCmv_src_mask);
   int dst = ((iw0 >> CCmv_dst_bits) & CCmv_dst_mask);
 
+  if (parallel)
+    return 0;
+
   if (T == 1)
     {
       OUTS (outf, "IF CC ");
@@ -1015,6 +1046,9 @@ decode_CCflag_0 (TIword iw0, disassemble_info *outf)
   int G = ((iw0 >> CCflag_G_bits) & CCflag_G_mask);
   int opc = ((iw0 >> CCflag_opc_bits) & CCflag_opc_mask);
 
+  if (parallel)
+    return 0;
+
   if (opc == 0 && I == 0 && G == 0)
     {
       OUTS (outf, "CC = ");
@@ -1163,13 +1197,13 @@ decode_CCflag_0 (TIword iw0, disassemble_info *outf)
       OUTS (outf, uimm3 (y));
       OUTS (outf, " (IU)");
     }
-  else if (opc == 5 && I == 0 && G == 0)
+  else if (opc == 5 && I == 0 && G == 0 && x == 0 && y == 0)
     OUTS (outf, "CC = A0 == A1");
 
-  else if (opc == 6 && I == 0 && G == 0)
+  else if (opc == 6 && I == 0 && G == 0 && x == 0 && y == 0)
     OUTS (outf, "CC = A0 < A1");
 
-  else if (opc == 7 && I == 0 && G == 0)
+  else if (opc == 7 && I == 0 && G == 0 && x == 0 && y == 0)
     OUTS (outf, "CC = A0 <= A1");
 
   else
@@ -1187,6 +1221,9 @@ decode_CC2dreg_0 (TIword iw0, disassemble_info *outf)
   int op  = ((iw0 >> CC2dreg_op_bits) & CC2dreg_op_mask);
   int reg = ((iw0 >> CC2dreg_reg_bits) & CC2dreg_reg_mask);
 
+  if (parallel)
+    return 0;
+
   if (op == 0)
     {
       OUTS (outf, dregs (reg));
@@ -1197,7 +1234,7 @@ decode_CC2dreg_0 (TIword iw0, disassemble_info *outf)
       OUTS (outf, "CC = ");
       OUTS (outf, dregs (reg));
     }
-  else if (op == 3)
+  else if (op == 3 && reg == 0)
     OUTS (outf, "CC = !CC");
   else
     return 0;
@@ -1216,44 +1253,62 @@ decode_CC2stat_0 (TIword iw0, disassemble_info *outf)
   int op   = ((iw0 >> CC2stat_op_bits) & CC2stat_op_mask);
   int cbit = ((iw0 >> CC2stat_cbit_bits) & CC2stat_cbit_mask);
 
+  const char *bitname = statbits (cbit);
+
+  if (parallel)
+    return 0;
+
+  if (decode_statbits[cbit] == REG_LASTREG)
+    {
+      /* All ASTAT bits except CC may be operated on in hardware, but may
+         not have a dedicated insn, so still decode "valid" insns.  */
+      static char bitnames[64];
+      if (cbit != 5)
+       sprintf (bitnames, "ASTAT[%i /* unused bit */]", cbit);
+      else
+       return 0;
+
+      bitname = bitnames;
+    }
+
   if (op == 0 && D == 0)
     {
       OUTS (outf, "CC = ");
-      OUTS (outf, statbits (cbit));
+      OUTS (outf, bitname);
     }
   else if (op == 1 && D == 0)
     {
       OUTS (outf, "CC |= ");
-      OUTS (outf, statbits (cbit));
+      OUTS (outf, bitname);
     }
   else if (op == 2 && D == 0)
     {
       OUTS (outf, "CC &= ");
-      OUTS (outf, statbits (cbit));
+      OUTS (outf, bitname);
     }
   else if (op == 3 && D == 0)
     {
       OUTS (outf, "CC ^= ");
-      OUTS (outf, statbits (cbit));
+      OUTS (outf, bitname);
     }
   else if (op == 0 && D == 1)
     {
-      OUTS (outf, statbits (cbit));
+      OUTS (outf, bitname);
       OUTS (outf, " = CC");
     }
   else if (op == 1 && D == 1)
     {
-      OUTS (outf, statbits (cbit));
+      OUTS (outf, bitname);
       OUTS (outf, " |= CC");
     }
   else if (op == 2 && D == 1)
     {
-      OUTS (outf, statbits (cbit));
+      OUTS (outf, bitname);
       OUTS (outf, " &= CC");
     }
   else if (op == 3 && D == 1)
     {
-      OUTS (outf, statbits (cbit));
+      OUTS (outf, bitname);
       OUTS (outf, " ^= CC");
     }
   else
@@ -1273,6 +1328,9 @@ decode_BRCC_0 (TIword iw0, bfd_vma pc, disassemble_info *outf)
   int T = ((iw0 >> BRCC_T_bits) & BRCC_T_mask);
   int offset = ((iw0 >> BRCC_offset_bits) & BRCC_offset_mask);
 
+  if (parallel)
+    return 0;
+
   if (T == 1 && B == 1)
     {
       OUTS (outf, "IF CC JUMP 0x");
@@ -1310,6 +1368,9 @@ decode_UJUMP_0 (TIword iw0, bfd_vma pc, disassemble_info *outf)
      +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
   int offset = ((iw0 >> UJump_offset_bits) & UJump_offset_mask);
 
+  if (parallel)
+    return 0;
+
   OUTS (outf, "JUMP.S 0x");
   OUTS (outf, pcrel12 (offset));
   return 2;
@@ -1327,19 +1388,37 @@ decode_REGMV_0 (TIword iw0, disassemble_info *outf)
   int src = ((iw0 >> RegMv_src_bits) & RegMv_src_mask);
   int dst = ((iw0 >> RegMv_dst_bits) & RegMv_dst_mask);
 
-  if (!((IS_GENREG (gd, dst) && IS_GENREG (gs, src))
-       || (IS_GENREG (gd, dst) && IS_DAGREG (gs, src))
-       || (IS_DAGREG (gd, dst) && IS_GENREG (gs, src))
-       || (IS_DAGREG (gd, dst) && IS_DAGREG (gs, src))
-       || (IS_GENREG (gd, dst) && gs == 7 && src == 0)
-       || (gd == 7 && dst == 0 && IS_GENREG (gs, src))
-       || (IS_DREG (gd, dst) && IS_SYSREG (gs, src))
-       || (IS_PREG (gd, dst) && IS_SYSREG (gs, src))
-       || (IS_SYSREG (gd, dst) && IS_DREG (gs, src))
-       || (IS_SYSREG (gd, dst) && IS_PREG (gs, src))
-       || (IS_SYSREG (gd, dst) && gs == 7 && src == 0)))
-    return 0;
+ /* Reserved slots cannot be a src/dst.  */
+  if (IS_RESERVEDREG (gs, src) || IS_RESERVEDREG (gd, dst))
+    goto invalid_move;
+
+  /* Standard register moves  */
+  if ((gs < 2) ||                               /* Dregs/Pregs as source  */
+      (gd < 2) ||                               /* Dregs/Pregs as dest    */
+      (gs == 4 && src < 4) ||                   /* Accumulators as source */
+      (gd == 4 && dst < 4 && (gs < 4)) ||       /* Accumulators as dest   */
+      (gs == 7 && src == 7 && !(gd == 4 && dst < 4)) || /* EMUDAT as src  */
+      (gd == 7 && dst == 7))                    /* EMUDAT as dest         */
+    goto valid_move;
+
+  /* dareg = dareg (IMBL) */
+  if (gs < 4 && gd < 4)
+    goto valid_move;
+
+  /* USP can be src to sysregs, but not dagregs.  */
+  if ((gs == 7 && src == 0) && (gd >= 4))
+    goto valid_move;
+
+  /* USP can move between genregs (only check Accumulators).  */
+  if (((gs == 7 && src == 0) && (gd == 4 && dst < 4)) ||
+      ((gd == 7 && dst == 0) && (gs == 4 && src < 4)))
+    goto valid_move;
+
+  /* Still here ?  Invalid reg pair.  */
+ invalid_move:
+  return 0;
 
+ valid_move:
   OUTS (outf, allregs (dst, gd));
   OUTS (outf, " = ");
   OUTS (outf, allregs (src, gs));
@@ -1541,6 +1620,9 @@ decode_LOGI2op_0 (TIword iw0, disassemble_info *outf)
   int opc = ((iw0 >> LOGI2op_opc_bits) & LOGI2op_opc_mask);
   int dst = ((iw0 >> LOGI2op_dst_bits) & LOGI2op_dst_mask);
 
+  if (parallel)
+    return 0;
+
   if (opc == 0)
     {
       OUTS (outf, "CC = !BITTST (");
@@ -1724,6 +1806,9 @@ decode_COMPI2opD_0 (TIword iw0, disassemble_info *outf)
 
   bu32 *pval = get_allreg (0, dst);
 
+  if (parallel)
+    return 0;
+
   /* Since we don't have 32-bit immediate loads, we allow the disassembler
      to combine them, so it prints out the right values.
      Here we keep track of the registers.  */
@@ -1779,6 +1864,9 @@ decode_COMPI2opP_0 (TIword iw0, disassemble_info *outf)
 
   bu32 *pval = get_allreg (1, dst);
 
+  if (parallel)
+    return 0;
+
   if (op == 0)
     {
       *pval = imm7_val (src);
@@ -1962,7 +2050,7 @@ decode_dagMODim_0 (TIword iw0, disassemble_info *outf)
       OUTS (outf, " += ");
       OUTS (outf, mregs (m));
     }
-  else if (op == 1)
+  else if (op == 1 && br == 0)
     {
       OUTS (outf, iregs (i));
       OUTS (outf, " -= ");
@@ -2205,7 +2293,7 @@ decode_LDST_0 (TIword iw0, disassemble_info *outf)
       OUTS (outf, pregs (ptr));
       OUTS (outf, "++]");
     }
-  else if (aop == 0 && sz == 0 && Z == 1 && W == 0)
+  else if (aop == 0 && sz == 0 && Z == 1 && W == 0 && reg != ptr)
     {
       OUTS (outf, pregs (reg));
       OUTS (outf, " = [");
@@ -2247,7 +2335,7 @@ decode_LDST_0 (TIword iw0, disassemble_info *outf)
       OUTS (outf, pregs (ptr));
       OUTS (outf, "--]");
     }
-  else if (aop == 1 && sz == 0 && Z == 1 && W == 0)
+  else if (aop == 1 && sz == 0 && Z == 1 && W == 0 && reg != ptr)
     {
       OUTS (outf, pregs (reg));
       OUTS (outf, " = [");
@@ -2541,6 +2629,9 @@ decode_LoopSetup_0 (TIword iw0, TIword iw1, bfd_vma pc, disassemble_info *outf)
   int soffset = ((iw0 >> (LoopSetup_soffset_bits - 16)) & LoopSetup_soffset_mask);
   int eoffset = ((iw1 >> LoopSetup_eoffset_bits) & LoopSetup_eoffset_mask);
 
+  if (parallel)
+    return 0;
+
   if (rop == 0)
     {
       OUTS (outf, "LSETUP");
@@ -2599,6 +2690,9 @@ decode_LDIMMhalf_0 (TIword iw0, TIword iw1, disassemble_info *outf)
 
   bu32 *pval = get_allreg (grp, reg);
 
+  if (parallel)
+    return 0;
+
   /* Since we don't have 32-bit immediate loads, we allow the disassembler
      to combine them, so it prints out the right values.
      Here we keep track of the registers.  */
@@ -2732,6 +2826,9 @@ decode_CALLa_0 (TIword iw0, TIword iw1, bfd_vma pc, disassemble_info *outf)
   int lsw = ((iw1 >> 0) & 0xffff);
   int msw = ((iw0 >> 0) & 0xff);
 
+  if (parallel)
+    return 0;
+
   if (S == 1)
     OUTS (outf, "CALL 0x");
   else if (S == 0)
@@ -2865,6 +2962,9 @@ decode_linkage_0 (TIword iw0, TIword iw1, disassemble_info *outf)
   int R = ((iw0 >> (Linkage_R_bits - 16)) & Linkage_R_mask);
   int framesize = ((iw1 >> Linkage_framesize_bits) & Linkage_framesize_mask);
 
+  if (parallel)
+    return 0;
+
   if (R == 0)
     {
       OUTS (outf, "LINK ");
@@ -3288,11 +3388,11 @@ decode_dsp32alu_0 (TIword iw0, TIword iw1, disassemble_info *outf)
       OUTS (outf, " = BYTEOP2M (");
       OUTS (outf, dregs (src0 + 1));
       OUTS (outf, ":");
-      OUTS (outf, imm5 (src0));
+      OUTS (outf, imm5d (src0));
       OUTS (outf, ", ");
       OUTS (outf, dregs (src1 + 1));
       OUTS (outf, ":");
-      OUTS (outf, imm5 (src1));
+      OUTS (outf, imm5d (src1));
       OUTS (outf, ") (TH");
       if (s == 1)
        OUTS (outf, ", R)");
@@ -3305,11 +3405,11 @@ decode_dsp32alu_0 (TIword iw0, TIword iw1, disassemble_info *outf)
       OUTS (outf, " = BYTEOP2M (");
       OUTS (outf, dregs (src0 + 1));
       OUTS (outf, ":");
-      OUTS (outf, imm5 (src0));
+      OUTS (outf, imm5d (src0));
       OUTS (outf, ", ");
       OUTS (outf, dregs (src1 + 1));
       OUTS (outf, ":");
-      OUTS (outf, imm5 (src1));
+      OUTS (outf, imm5d (src1));
       OUTS (outf, ") (TL");
       if (s == 1)
        OUTS (outf, ", R)");
@@ -3322,11 +3422,11 @@ decode_dsp32alu_0 (TIword iw0, TIword iw1, disassemble_info *outf)
       OUTS (outf, " = BYTEOP2M (");
       OUTS (outf, dregs (src0 + 1));
       OUTS (outf, ":");
-      OUTS (outf, imm5 (src0));
+      OUTS (outf, imm5d (src0));
       OUTS (outf, ", ");
       OUTS (outf, dregs (src1 + 1));
       OUTS (outf, ":");
-      OUTS (outf, imm5 (src1));
+      OUTS (outf, imm5d (src1));
       OUTS (outf, ") (RNDH");
       if (s == 1)
        OUTS (outf, ", R)");
@@ -3339,11 +3439,11 @@ decode_dsp32alu_0 (TIword iw0, TIword iw1, disassemble_info *outf)
       OUTS (outf, " = BYTEOP2M (");
       OUTS (outf, dregs (src0 + 1));
       OUTS (outf, ":");
-      OUTS (outf, imm5 (src0));
+      OUTS (outf, imm5d (src0));
       OUTS (outf, ", ");
       OUTS (outf, dregs (src1 + 1));
       OUTS (outf, ":");
-      OUTS (outf, imm5 (src1));
+      OUTS (outf, imm5d (src1));
       OUTS (outf, ") (RNDL");
       if (s == 1)
        OUTS (outf, ", R)");
@@ -4437,7 +4537,7 @@ decode_dsp32shiftimm_0 (TIword iw0, TIword iw1, disassemble_info *outf)
       OUTS (outf, dregs (src1));
       OUTS (outf, " >>> ");
       OUTS (outf, imm5 (-immag));
-      OUTS (outf, " (V)");
+      OUTS (outf, " (V, S)");
     }
   else if (sop == 2 && sopcde == 1 && bit8 == 1)
     {
@@ -4524,6 +4624,9 @@ decode_pseudoDEBUG_0 (TIword iw0, disassemble_info *outf)
   int grp = ((iw0 >> PseudoDbg_grp_bits) & PseudoDbg_grp_mask);
   int reg = ((iw0 >> PseudoDbg_reg_bits) & PseudoDbg_reg_mask);
 
+  if (parallel)
+    return 0;
+
   if (reg == 0 && fn == 3)
     OUTS (outf, "DBG A0");
 
@@ -4550,12 +4653,12 @@ decode_pseudoDEBUG_0 (TIword iw0, disassemble_info *outf)
 
   else if (grp == 0 && fn == 2)
     {
-      OUTS (outf, "OUTC");
+      OUTS (outf, "OUTC ");
       OUTS (outf, dregs (reg));
     }
   else if (fn == 0)
     {
-      OUTS (outf, "DBG");
+      OUTS (outf, "DBG ");
       OUTS (outf, allregs (reg, grp));
     }
   else if (fn == 1)
@@ -4569,6 +4672,24 @@ decode_pseudoDEBUG_0 (TIword iw0, disassemble_info *outf)
   return 2;
 }
 
+static int
+decode_pseudoOChar_0 (TIword iw0, disassemble_info *outf)
+{
+  /* psedoOChar
+     +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+     | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 |.ch............................|
+     +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
+  int ch = ((iw0 >> PseudoChr_ch_bits) & PseudoChr_ch_mask);
+
+  if (parallel)
+    return 0;
+
+  OUTS (outf, "OUTC ");
+  OUTS (outf, uimm8 (ch));
+
+  return 2;
+}
+
 static int
 decode_pseudodbg_assert_0 (TIword iw0, TIword iw1, disassemble_info *outf)
 {
@@ -4582,6 +4703,9 @@ decode_pseudodbg_assert_0 (TIword iw0, TIword iw1, disassemble_info *outf)
   int grp      = ((iw0 >> (PseudoDbg_Assert_grp_bits - 16)) & PseudoDbg_Assert_grp_mask);
   int regtest  = ((iw0 >> (PseudoDbg_Assert_regtest_bits - 16)) & PseudoDbg_Assert_regtest_mask);
 
+  if (parallel)
+    return 0;
+
   if (dbgop == 0)
     {
       OUTS (outf, "DBGA (");
@@ -4640,6 +4764,11 @@ _print_insn_bfin (bfd_vma pc, disassemble_info *outf)
 
   if ((iw0 & 0xf7ff) == 0xc003 && iw1 == 0x1800)
     {
+      if (parallel)
+       {
+          OUTS (outf, "ILLEGAL");
+          return 0;
+       }
       OUTS (outf, "MNOP");
       return 4;
     }
@@ -4713,13 +4842,14 @@ _print_insn_bfin (bfd_vma pc, disassemble_info *outf)
     rv = decode_dsp32shiftimm_0 (iw0, iw1, outf);
   else if ((iw0 & 0xff00) == 0xf800)
     rv = decode_pseudoDEBUG_0 (iw0, outf);
-#if 0
   else if ((iw0 & 0xFF00) == 0xF900)
-    rv = decode_pseudoOChar_0 (iw0, iw1, pc, outf);
-#endif
+    rv = decode_pseudoOChar_0 (iw0, outf);
   else if ((iw0 & 0xFF00) == 0xf000 && (iw1 & 0x0000) == 0x0000)
     rv = decode_pseudodbg_assert_0 (iw0, iw1, outf);
 
+  if (rv == 0)
+    OUTS (outf, "ILLEGAL");
+
   return rv;
 }
 
@@ -4741,24 +4871,39 @@ print_insn_bfin (bfd_vma pc, disassemble_info *outf)
 
   /* Proper display of multiple issue instructions.  */
 
-  if ((iw0 & 0xc000) == 0xc000 && (iw0 & BIT_MULTI_INS)
+  if (count == 4 && (iw0 & 0xc000) == 0xc000 && (iw0 & BIT_MULTI_INS)
       && ((iw0 & 0xe800) != 0xe800 /* Not Linkage.  */ ))
     {
+      int legal = 1;
+      int len;
+
       parallel = 1;
       outf->fprintf_func (outf->stream, " || ");
-      count += _print_insn_bfin (pc + 4, outf);
+      len = _print_insn_bfin (pc + 4, outf);
       outf->fprintf_func (outf->stream, " || ");
-      count += _print_insn_bfin (pc + 6, outf);
+      if (len != 2)
+         legal = 0;
+      len = _print_insn_bfin (pc + 6, outf);
+      if (len != 2)
+       legal = 0;
+
+      if (legal)
+       count = 8;
+      else
+       {
+         outf->fprintf_func (outf->stream, ";\t\t/* ILLEGAL PARALLEL INSTRUCTION */");
+         comment = 1;
+         count = 0;
+       }
       parallel = 0;
     }
-  if (count == 0)
-    {
-      outf->fprintf_func (outf->stream, "ILLEGAL");
-      return 2;
-    }
+
   if (!comment)
     outf->fprintf_func (outf->stream, ";");
 
+  if (count == 0)
+    return 2;
+
   comment = 0;
 
   return count;
This page took 0.032416 seconds and 4 git commands to generate.