[AArch64][SVE 16/32] Use specific insert/extract methods for fpimm
[deliverable/binutils-gdb.git] / opcodes / arc-dis.c
index 7b78bdcb24c872f4bdace12ebf562f1353efed42..e4df678dfa532f403ea686a4f0361c75610d1113 100644 (file)
@@ -85,6 +85,16 @@ static const char * const regnames[64] =
   "r56", "r57", "ACCL", "ACCH", "lp_count", "rezerved", "LIMM", "pcl"
 };
 
+static const char * const addrtypenames[ARC_NUM_ADDRTYPES] =
+{
+  "bd", "jid", "lbd", "mbd", "sd", "sm", "xa", "xd",
+  "cd", "cbd", "cjid", "clbd", "cm", "csd", "cxa", "cxd"
+};
+
+static int addrtypenames_max = ARC_NUM_ADDRTYPES - 1;
+
+static const char * const addrtypeunknown = "unknown";
+
 /* This structure keeps track which instruction class(es)
    should be ignored durring disassembling.  */
 
@@ -175,7 +185,7 @@ skip_this_opcode (const struct arc_opcode *  opcode,
   /* If we found an incompatibility then we must skip.  */
   if (t != NULL)
     return TRUE;
-  
+
   /* Even if we do not precisely know the if the right mnemonics
      is correctly displayed, keep the disassmbled code class
      consistent.  */
@@ -467,15 +477,15 @@ find_format (bfd_vma                       memaddr,
 {
   const struct arc_opcode *opcode = NULL;
   bfd_boolean needs_limm;
-  const extInstruction_t *einsn;
+  const extInstruction_t *einsn, *i;
 
   /* First, try the extension instructions.  */
   einsn = arcExtMap_insn (OPCODE (insn[0]), insn[0]);
-  if (einsn != NULL)
+  for (i = einsn; (i != NULL) && (opcode == NULL); i = i->next)
     {
       const char *errmsg = NULL;
 
-      opcode = arcExtMap_genOpcode (einsn, isa_mask, &errmsg);
+      opcode = arcExtMap_genOpcode (i, isa_mask, &errmsg);
       if (opcode == NULL)
        {
          (*info->fprintf_func) (info->stream, "\
@@ -653,6 +663,18 @@ get_auxreg (const struct arc_opcode *opcode,
   return NULL;
 }
 
+/* Convert a value representing an address type to a string used to refer to
+   the address type in assembly code.  */
+
+static const char *
+get_addrtype (int value)
+{
+  if (value < 0 || value > addrtypenames_max)
+    return addrtypeunknown;
+
+  return addrtypenames[value];
+}
+
 /* Calculate the instruction length for an instruction starting with MSB
    and LSB, the most and least significant byte.  The ISA_MASK is used to
    filter the instructions considered to only those that are part of the
@@ -916,7 +938,10 @@ print_insn_arc (bfd_vma memaddr,
     case bfd_mach_arc_arcv2:
     default:
       isa_mask = ARC_OPCODE_ARCv2EM;
-      if ((header->e_flags & EF_ARC_MACH_MSK) == EF_ARC_CPU_ARCV2HS)
+      /* TODO: Perhaps remove defitinion of header since it is only used at
+         this location.  */
+      if (header != NULL
+         && (header->e_flags & EF_ARC_MACH_MSK) == EF_ARC_CPU_ARCV2HS)
        {
          isa_mask = ARC_OPCODE_ARCv2HS;
          /* FPU instructions are not extensions for HS.  */
@@ -1104,8 +1129,7 @@ print_insn_arc (bfd_vma memaddr,
        }
 
       /* Only take input from real operands.  */
-      if ((operand->flags & ARC_OPERAND_FAKE)
-         && !(operand->flags & ARC_OPERAND_BRAKET))
+      if (ARC_OPERAND_IS_FAKE (operand))
        continue;
 
       if ((operand->flags & ARC_OPERAND_IGNORE)
@@ -1113,6 +1137,12 @@ print_insn_arc (bfd_vma memaddr,
           && value == -1)
        continue;
 
+      if (operand->flags & ARC_OPERAND_COLON)
+        {
+          (*info->fprintf_func) (info->stream, ":");
+          continue;
+        }
+
       if (need_comma)
        (*info->fprintf_func) (info->stream, ",");
 
@@ -1124,6 +1154,8 @@ print_insn_arc (bfd_vma memaddr,
          continue;
        }
 
+      need_comma = TRUE;
+
       /* Print the operand as directed by the flags.  */
       if (operand->flags & ARC_OPERAND_IR)
        {
@@ -1145,6 +1177,7 @@ print_insn_arc (bfd_vma memaddr,
       else if (operand->flags & ARC_OPERAND_LIMM)
        {
          const char *rname = get_auxreg (opcode, value, isa_mask);
+
          if (rname && open_braket)
            (*info->fprintf_func) (info->stream, "%s", rname);
          else
@@ -1172,6 +1205,13 @@ print_insn_arc (bfd_vma memaddr,
          else
            (*info->fprintf_func) (info->stream, "%d", value);
        }
+      else if (operand->flags & ARC_OPERAND_ADDRTYPE)
+        {
+          const char *addrtype = get_addrtype (value);
+          (*info->fprintf_func) (info->stream, "%s", addrtype);
+          /* A colon follow an address type.  */
+          need_comma = FALSE;
+        }
       else
        {
          if (operand->flags & ARC_OPERAND_TRUNCATE
@@ -1189,8 +1229,6 @@ print_insn_arc (bfd_vma memaddr,
                (*info->fprintf_func) (info->stream, "%#x", value);
            }
        }
-
-      need_comma = TRUE;
     }
 
   return insn_len;
@@ -1200,11 +1238,16 @@ print_insn_arc (bfd_vma memaddr,
 disassembler_ftype
 arc_get_disassembler (bfd *abfd)
 {
-  /* Read the extenssion insns and registers, if any.  */
-  build_ARC_extmap (abfd);
+  /* BFD my be absent, if opcodes is invoked from the debugger that
+     has connected to remote target and doesn't have an ELF file.  */
+  if (abfd != NULL)
+    {
+      /* Read the extension insns and registers, if any.  */
+      build_ARC_extmap (abfd);
 #ifdef DEBUG
-  dump_ARC_extmap ();
+      dump_ARC_extmap ();
 #endif
+    }
 
   return print_insn_arc;
 }
This page took 0.025177 seconds and 4 git commands to generate.