]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/binutils-tumbl.git/blobdiff - opcodes/microblaze-dis.c
MBTumbl: Implement support for conditional execution
[fpga/lx-cpu1/binutils-tumbl.git] / opcodes / microblaze-dis.c
index 49db4d2fa8f96835707bd38366dfd2e32d34ccc5..2ecec054dabbb298c41d778364139590b0dd95c1 100644 (file)
@@ -86,6 +86,63 @@ get_field_imm15 (long instr)
   return (strdup (tmpstr));
 }
 
+#else
+
+static char *
+get_field_itt_cond (long instr)
+{
+  const char *cond = NULL; 
+
+  switch ((instr & COND_MASK) >> COND_LOW)
+  {
+    case COND_EQ:
+      cond = "eq";
+      break;
+    case COND_NE:
+      cond = "ne";
+      break;
+    case COND_LE:
+      cond = "le";
+      break;
+    case COND_LT:
+      cond = "lt";
+      break;
+    case COND_GE:
+      cond = "ge";
+      break;
+    case COND_GT:
+      cond = "gt";
+      break;
+  }
+
+  if (cond == NULL)
+    return NULL;
+  return (strdup (cond));
+}
+
+static char *
+get_field_itt (long instr)
+{
+  const char *cond_type = NULL; 
+
+  switch ((instr & COND_TYPE_MASK) >> COND_TYPE_LOW)
+  {
+    case COND_TYPE_IT:
+      cond_type = "it";
+      break;
+    case COND_TYPE_ITT:
+      cond_type = "itt";
+      break;
+    case COND_TYPE_ITE:
+      cond_type = "ite";
+      break;
+  }
+
+  if (cond_type == NULL)
+    return NULL;
+  return (strdup (cond_type));
+}
+
 #endif
 
 static char *
@@ -186,7 +243,7 @@ read_insn_microblaze (bfd_vma memaddr,
 
   /* Just a linear search of the table.  */
   for (op = opcodes; op->name != 0; op ++)
-    if (op->bit_sequence == (inst & op->opcode_mask))
+    if ((op->bit_sequence == (inst & op->opcode_mask)) && (op->inst_type != pseudo_inst))
       break;
 
   *opr = op;
@@ -206,6 +263,10 @@ print_insn_microblaze (bfd_vma memaddr, struct disassemble_info * info)
   static bfd_vma      prev_insn_addr = -1; /* Init the prev insn addr.  */
   static int          prev_insn_vma = -1;  /* Init the prev insn vma.  */
   int                 curr_insn_vma = info->buffer_vma;
+#ifdef ARCH_mbtumbl
+  char *              cmp_cond;
+  char *              cmp_cond_type;
+#endif
 
   info->bytes_per_chunk = 4;
 
@@ -248,7 +309,18 @@ print_insn_microblaze (bfd_vma memaddr, struct disassemble_info * info)
         case INST_TYPE_RD_R1_R2:
           print_func (stream, "\t%s, %s, %s", get_field_rd (inst),
                   get_field_r1(inst), get_field_r2 (inst));
+
+#ifdef ARCH_mbtumbl
+          /* Maybe CMP with ITT */
+          if (!strcmp(op->name, "cmp") || !strcmp(op->name, "cmpu"))
+          {
+            cmp_cond = get_field_itt_cond(inst);
+            cmp_cond_type = get_field_itt(inst);
+            if (cmp_cond && cmp_cond_type)
+              print_func (stream, "\t\t%s\t%s", cmp_cond_type, cmp_cond);
+          }
           break;
+#endif
         case INST_TYPE_RD_R1_IMM:
          print_func (stream, "\t%s, %s, %s", get_field_rd (inst),
                   get_field_r1(inst), get_field_imm (inst));