[ARC] Improve printing of pc-relative instructions.
[deliverable/binutils-gdb.git] / opcodes / arc-dis.c
index 7541b74d23034a10fa79bc00925a0d022d805323..71acc10b42f60005eda9a7585c558c20f8a87064 100644 (file)
@@ -923,9 +923,10 @@ print_insn_arc (bfd_vma memaddr,
   bfd_boolean open_braket;
   int size;
   const struct arc_operand *operand;
-  int value;
+  int value, vpcl;
   struct arc_operand_iterator iter;
   struct arc_disassemble_info *arc_infop;
+  bfd_boolean rpcl = FALSE, rset = FALSE;
 
   if (info->disassembler_options)
     {
@@ -1022,6 +1023,7 @@ print_insn_arc (bfd_vma memaddr,
 
   /* Read the insn into a host word.  */
   status = (*info->read_memory_func) (memaddr, buffer, size, info);
+
   if (status != 0)
     {
       (*info->memory_error_func) (status, memaddr, info);
@@ -1132,23 +1134,23 @@ print_insn_arc (bfd_vma memaddr,
       switch (insn_len)
        {
        case 2:
-         (*info->fprintf_func) (info->stream, ".long %#04llx",
+         (*info->fprintf_func) (info->stream, ".shor\t%#04llx",
                                 insn & 0xffff);
          break;
        case 4:
-         (*info->fprintf_func) (info->stream, ".long %#08llx",
+         (*info->fprintf_func) (info->stream, ".word\t%#08llx",
                                 insn & 0xffffffff);
          break;
        case 6:
-         (*info->fprintf_func) (info->stream, ".long %#08llx",
+         (*info->fprintf_func) (info->stream, ".long\t%#08llx",
                                 insn & 0xffffffff);
-         (*info->fprintf_func) (info->stream, ".long %#04llx",
+         (*info->fprintf_func) (info->stream, ".long\t%#04llx",
                                 (insn >> 32) & 0xffff);
          break;
        case 8:
-         (*info->fprintf_func) (info->stream, ".long %#08llx",
+         (*info->fprintf_func) (info->stream, ".long\t%#08llx",
                                 insn & 0xffffffff);
-         (*info->fprintf_func) (info->stream, ".long %#08llx",
+         (*info->fprintf_func) (info->stream, ".long\t%#08llx",
                                 insn >> 32);
          break;
        default:
@@ -1178,6 +1180,7 @@ print_insn_arc (bfd_vma memaddr,
 
   /* Now extract and print the operands.  */
   operand = NULL;
+  vpcl = 0;
   while (operand_iterator_next (&iter, &operand, &value))
     {
       if (open_braket && (operand->flags & ARC_OPERAND_BRAKET))
@@ -1215,6 +1218,20 @@ print_insn_arc (bfd_vma memaddr,
 
       need_comma = TRUE;
 
+      if (operand->flags & ARC_OPERAND_PCREL)
+       {
+         rpcl = TRUE;
+         vpcl = value;
+         rset = TRUE;
+
+         info->target = (bfd_vma) (memaddr & ~3) + value;
+       }
+      else if (!(operand->flags & ARC_OPERAND_IR))
+       {
+         vpcl = value;
+         rset = TRUE;
+       }
+
       /* Print the operand as directed by the flags.  */
       if (operand->flags & ARC_OPERAND_IR)
        {
@@ -1232,6 +1249,10 @@ print_insn_arc (bfd_vma memaddr,
                rname = regnames[value + 1];
              (*info->fprintf_func) (info->stream, "%s", rname);
            }
+         if (value == 63)
+           rpcl = TRUE;
+         else
+           rpcl = FALSE;
        }
       else if (operand->flags & ARC_OPERAND_LIMM)
        {
@@ -1247,15 +1268,6 @@ print_insn_arc (bfd_vma memaddr,
                info->target = (bfd_vma) value;
            }
        }
-      else if (operand->flags & ARC_OPERAND_PCREL)
-       {
-          /* PCL relative.  */
-         if (info->flags & INSN_HAS_RELOC)
-           memaddr = 0;
-         (*info->print_address_func) ((memaddr & ~3) + value, info);
-
-         info->target = (bfd_vma) (memaddr & ~3) + value;
-       }
       else if (operand->flags & ARC_OPERAND_SIGNED)
        {
          const char *rname = get_auxreg (opcode, value, isa_mask);
@@ -1283,6 +1295,7 @@ print_insn_arc (bfd_vma memaddr,
              && !(operand->flags & ARC_OPERAND_ALIGNED16)
              && value >= 0 && value <= 14)
            {
+             /* Leave/Enter mnemonics.  */
              switch (value)
                {
                case 0:
@@ -1296,6 +1309,8 @@ print_insn_arc (bfd_vma memaddr,
                                         regnames[13 + value - 1]);
                  break;
                }
+             rpcl = FALSE;
+             rset = FALSE;
            }
          else
            {
@@ -1326,6 +1341,21 @@ print_insn_arc (bfd_vma memaddr,
       arc_infop->operands_count ++;
     }
 
+  /* Pretty print extra info for pc-relative operands.  */
+  if (rpcl && rset)
+    {
+      if (info->flags & INSN_HAS_RELOC)
+       /* If the instruction has a reloc associated with it, then the
+          offset field in the instruction will actually be the addend
+          for the reloc.  (We are using REL type relocs).  In such
+          cases, we can ignore the pc when computing addresses, since
+          the addend is not currently pc-relative.  */
+       memaddr = 0;
+
+      (*info->fprintf_func) (info->stream, "\t;");
+      (*info->print_address_func) ((memaddr & ~3) + vpcl, info);
+    }
+
   return insn_len;
 }
 
This page took 0.025813 seconds and 4 git commands to generate.