Constify main.c:get_init_files.
[deliverable/binutils-gdb.git] / opcodes / mips-dis.c
index 3395f1a33f0173a1c0143976b1ef7507a3223f94..ee5827cada6405b9ec93b4200207bd3493c23dcd 100644 (file)
@@ -591,8 +591,8 @@ const struct mips_arch_choice mips_arch_choices[] =
 
   { "mips32r2",        1, bfd_mach_mipsisa32r2, CPU_MIPS32R2,
     ISA_MIPS32R2,
-    (ASE_SMARTMIPS | ASE_DSP | ASE_DSPR2 | ASE_MIPS3D | ASE_MT
-     | ASE_MCU | ASE_VIRT),
+    (ASE_SMARTMIPS | ASE_DSP | ASE_DSPR2 | ASE_EVA | ASE_MIPS3D
+     | ASE_MT | ASE_MCU | ASE_VIRT),
     mips_cp0_names_mips3264r2,
     mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
     mips_hwr_names_mips3264r2 },
@@ -606,8 +606,8 @@ const struct mips_arch_choice mips_arch_choices[] =
 
   { "mips64r2",        1, bfd_mach_mipsisa64r2, CPU_MIPS64R2,
     ISA_MIPS64R2,
-    (ASE_MIPS3D | ASE_DSP | ASE_DSPR2 | ASE_DSP64 | ASE_MT | ASE_MDMX
-     | ASE_MCU | ASE_VIRT | ASE_VIRT64),
+    (ASE_MIPS3D | ASE_DSP | ASE_DSPR2 | ASE_DSP64 | ASE_EVA | ASE_MT
+     | ASE_MDMX | ASE_MCU | ASE_VIRT | ASE_VIRT64),
     mips_cp0_names_mips3264r2,
     mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
     mips_hwr_names_mips3264r2 },
@@ -1152,6 +1152,10 @@ print_insn_args (const char *d,
              infprintf (is, "%s", mips_fpr_names[GET_OP (l, FZ)]);
              break;
 
+           case 'j':   /* 9-bit signed offset in bit 7.  */
+             infprintf (is, "%d", GET_OP_S (l, EVAOFFSET));
+             break;
+
            default:
              /* xgettext:c-format */
              infprintf (is,
@@ -2052,6 +2056,23 @@ print_mips16_insn_arg (char type,
     }
 }
 
+
+/* Check if the given address is the last word of a MIPS16 PLT entry.
+   This word is data and depending on the value it may interfere with
+   disassembly of further PLT entries.  We make use of the fact PLT
+   symbols are marked BSF_SYNTHETIC.  */
+static bfd_boolean
+is_mips16_plt_tail (struct disassemble_info *info, bfd_vma addr)
+{
+  if (info->symbols
+      && info->symbols[0]
+      && (info->symbols[0]->flags & BSF_SYNTHETIC)
+      && addr == bfd_asymbol_value (info->symbols[0]) + 12)
+    return TRUE;
+
+  return FALSE;
+}
+
 /* Disassemble mips16 instructions.  */
 
 static int
@@ -2059,7 +2080,7 @@ print_insn_mips16 (bfd_vma memaddr, struct disassemble_info *info)
 {
   const fprintf_ftype infprintf = info->fprintf_func;
   int status;
-  bfd_byte buffer[2];
+  bfd_byte buffer[4];
   int length;
   int insn;
   bfd_boolean use_extend;
@@ -2072,11 +2093,32 @@ print_insn_mips16 (bfd_vma memaddr, struct disassemble_info *info)
   info->insn_info_valid = 1;
   info->branch_delay_insns = 0;
   info->data_size = 0;
-  info->insn_type = dis_nonbranch;
   info->target = 0;
   info->target2 = 0;
 
-  status = (*info->read_memory_func) (memaddr, buffer, 2, info);
+  /* Decode PLT entry's GOT slot address word.  */
+  if (is_mips16_plt_tail (info, memaddr))
+    {
+      info->insn_type = dis_noninsn;
+      status = (*info->read_memory_func) (memaddr, buffer, 4, info);
+      if (status == 0)
+       {
+         unsigned int gotslot;
+
+         if (info->endian == BFD_ENDIAN_BIG)
+           gotslot = bfd_getb32 (buffer);
+         else
+           gotslot = bfd_getl32 (buffer);
+         infprintf (is, ".word\t0x%x", gotslot);
+
+         return 4;
+       }
+    }
+  else
+    {
+      info->insn_type = dis_nonbranch;
+      status = (*info->read_memory_func) (memaddr, buffer, 2, info);
+    }
   if (status != 0)
     {
       (*info->memory_error_func) (status, memaddr, info);
@@ -2554,8 +2596,12 @@ print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
                    {
                    case 0x000000fc:                            /* mfc0  */
                    case 0x000002fc:                            /* mtc0  */
+                   case 0x000004fc:                            /* mfgc0  */
+                   case 0x000006fc:                            /* mtgc0  */
                    case 0x580000fc:                            /* dmfc0 */
                    case 0x580002fc:                            /* dmtc0 */
+                   case 0x580000e7:                            /* dmfgc0 */
+                   case 0x580002e7:                            /* dmtgc0 */
                      infprintf (is, "%s", mips_cp0_names[GET_OP (insn, RS)]);
                      break;
                    default:
@@ -2655,6 +2701,11 @@ print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
                      infprintf (is, "0x%x", msbd + 1);
                      break;
 
+                   case 'j':   /* 9-bit signed offset in bit 0. */
+                     delta = GET_OP_S (insn, EVAOFFSET);
+                     infprintf (is, "%d", delta);
+                     break;
+
                    default:
                      /* xgettext:c-format */
                      infprintf (is,
@@ -2950,27 +3001,26 @@ print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
 static bfd_boolean
 is_compressed_mode_p (struct disassemble_info *info)
 {
-  elf_symbol_type *symbol;
-  int pos;
   int i;
-
-  for (i = 0; i < info->num_symbols; i++)
-    {
-      pos = info->symtab_pos + i;
-
-      if (bfd_asymbol_flavour (info->symtab[pos]) != bfd_target_elf_flavour)
-       continue;
-
-      if (info->symtab[pos]->section != info->section)
-       continue;
-
-      symbol = (elf_symbol_type *) info->symtab[pos];
-      if ((!micromips_ase
-          && ELF_ST_IS_MIPS16 (symbol->internal_elf_sym.st_other))
-         || (micromips_ase
-             && ELF_ST_IS_MICROMIPS (symbol->internal_elf_sym.st_other)))
-           return 1;
-    }
+  int l;
+
+  for (i = info->symtab_pos, l = i + info->num_symbols; i < l; i++)
+    if (((info->symtab[i])->flags & BSF_SYNTHETIC) != 0
+       && ((!micromips_ase
+            && ELF_ST_IS_MIPS16 ((*info->symbols)->udata.i))
+           || (micromips_ase
+               && ELF_ST_IS_MICROMIPS ((*info->symbols)->udata.i))))
+      return 1;
+    else if (bfd_asymbol_flavour (info->symtab[i]) == bfd_target_elf_flavour
+             && info->symtab[i]->section == info->section)
+      {
+       elf_symbol_type *symbol = (elf_symbol_type *) info->symtab[i];
+       if ((!micromips_ase
+            && ELF_ST_IS_MIPS16 (symbol->internal_elf_sym.st_other))
+           || (micromips_ase
+               && ELF_ST_IS_MICROMIPS (symbol->internal_elf_sym.st_other)))
+         return 1;
+      }
 
   return 0;
 }
This page took 0.027413 seconds and 4 git commands to generate.