[AArch64] PR target/20553, fix opcode mask for SIMD multiply by element
[deliverable/binutils-gdb.git] / opcodes / mips-dis.c
index 820092024af270f50218ed3fb73a7134b280042f..3f874e72f5e3443b7b88eb3da79d321bdef359bc 100644 (file)
@@ -1,5 +1,5 @@
 /* Print mips instructions for GDB, the GNU debugger, or for objdump.
-   Copyright (C) 1989-2015 Free Software Foundation, Inc.
+   Copyright (C) 1989-2016 Free Software Foundation, Inc.
    Contributed by Nobuyuki Hikichi(hikichi@sra.co.jp).
 
    This file is part of the GNU opcodes library.
@@ -563,7 +563,7 @@ const struct mips_arch_choice mips_arch_choices[] =
   { "mips32r6",        1, bfd_mach_mipsisa32r6, CPU_MIPS32R6,
     ISA_MIPS32R6,
     (ASE_EVA | ASE_MSA | ASE_VIRT | ASE_XPA | ASE_MCU | ASE_MT | ASE_DSP
-     | ASE_DSPR2),
+     | ASE_DSPR2 | ASE_DSPR3),
     mips_cp0_names_mips3264r2,
     mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
     mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
@@ -602,7 +602,7 @@ const struct mips_arch_choice mips_arch_choices[] =
   { "mips64r6",        1, bfd_mach_mipsisa64r6, CPU_MIPS64R6,
     ISA_MIPS64R6,
     (ASE_EVA | ASE_MSA | ASE_MSA64 | ASE_XPA | ASE_VIRT | ASE_VIRT64
-     | ASE_MCU | ASE_MT | ASE_DSP | ASE_DSPR2),
+     | ASE_MCU | ASE_MT | ASE_DSP | ASE_DSPR2 | ASE_DSPR3),
     mips_cp0_names_mips3264r2,
     mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
     mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
@@ -1894,11 +1894,13 @@ print_mips16_insn_arg (struct disassemble_info *info,
                {
                  operand = ext_operand;
                  if (operand->size == 16)
-                   uval |= ((extend & 0x1f) << 11) | (extend & 0x7e0);
+                   uval = (((extend & 0x1f) << 11) | (extend & 0x7e0)
+                           | (uval & 0x1f));
                  else if (operand->size == 15)
                    uval |= ((extend & 0xf) << 11) | (extend & 0x7f0);
                  else
-                   uval = ((extend >> 6) & 0x1f) | (extend & 0x20);
+                   uval = ((((extend >> 6) & 0x1f) | (extend & 0x20))
+                           & ((1U << operand->size) - 1));
                }
            }
        }
@@ -2185,41 +2187,7 @@ print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
   else
     insn = bfd_getl16 (buffer);
 
-  if ((insn & 0xfc00) == 0x7c00)
-    {
-      /* This is a 48-bit microMIPS instruction.  */
-      higher = insn;
-
-      status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
-      if (status != 0)
-       {
-         infprintf (is, "micromips 0x%x", higher);
-         (*info->memory_error_func) (status, memaddr + 2, info);
-         return -1;
-       }
-      if (info->endian == BFD_ENDIAN_BIG)
-       insn = bfd_getb16 (buffer);
-      else
-       insn = bfd_getl16 (buffer);
-      higher = (higher << 16) | insn;
-
-      status = (*info->read_memory_func) (memaddr + 4, buffer, 2, info);
-      if (status != 0)
-       {
-         infprintf (is, "micromips 0x%x", higher);
-         (*info->memory_error_func) (status, memaddr + 4, info);
-         return -1;
-       }
-      if (info->endian == BFD_ENDIAN_BIG)
-       insn = bfd_getb16 (buffer);
-      else
-       insn = bfd_getl16 (buffer);
-      infprintf (is, "0x%x%04x (48-bit insn)", higher, insn);
-
-      info->insn_type = dis_noninsn;
-      return 6;
-    }
-  else if ((insn & 0x1c00) == 0x0000 || (insn & 0x1000) == 0x1000)
+  if ((insn & 0x1c00) == 0x0000 || (insn & 0x1000) == 0x1000)
     {
       /* This is a 32-bit microMIPS instruction.  */
       higher = insn;
@@ -2300,33 +2268,33 @@ print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
 }
 
 /* Return 1 if a symbol associated with the location being disassembled
-   indicates a compressed (MIPS16 or microMIPS) mode.  We iterate over
-   all the symbols at the address being considered assuming if at least
-   one of them indicates code compression, then such code has been
-   genuinely produced here (other symbols could have been derived from
-   function symbols defined elsewhere or could define data).  Otherwise,
-   return 0.  */
+   indicates a compressed mode, either MIPS16 or microMIPS, according to
+   MICROMIPS_P.  We iterate over all the symbols at the address being
+   considered assuming if at least one of them indicates code compression,
+   then such code has been genuinely produced here (other symbols could
+   have been derived from function symbols defined elsewhere or could
+   define data).  Otherwise, return 0.  */
 
 static bfd_boolean
-is_compressed_mode_p (struct disassemble_info *info)
+is_compressed_mode_p (struct disassemble_info *info, bfd_boolean micromips_p)
 {
   int i;
   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
+       && ((!micromips_p
             && ELF_ST_IS_MIPS16 ((*info->symbols)->udata.i))
-           || (micromips_ase
+           || (micromips_p
                && 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
+       if ((!micromips_p
             && ELF_ST_IS_MIPS16 (symbol->internal_elf_sym.st_other))
-           || (micromips_ase
+           || (micromips_p
                && ELF_ST_IS_MICROMIPS (symbol->internal_elf_sym.st_other)))
          return 1;
       }
@@ -2345,7 +2313,6 @@ _print_insn_mips (bfd_vma memaddr,
                  struct disassemble_info *info,
                  enum bfd_endian endianness)
 {
-  int (*print_insn_compr) (bfd_vma, struct disassemble_info *);
   bfd_byte buffer[INSNLEN];
   int status;
 
@@ -2357,18 +2324,23 @@ _print_insn_mips (bfd_vma memaddr,
   if (info->mach == bfd_mach_mips_micromips)
     return print_insn_micromips (memaddr, info);
 
-  print_insn_compr = !micromips_ase ? print_insn_mips16 : print_insn_micromips;
-
 #if 1
   /* FIXME: If odd address, this is CLEARLY a compressed instruction.  */
   /* Only a few tools will work this way.  */
   if (memaddr & 0x01)
-    return print_insn_compr (memaddr, info);
+    {
+      if (micromips_ase)
+       return print_insn_micromips (memaddr, info);
+      else
+       return print_insn_mips16 (memaddr, info);
+    }
 #endif
 
 #if SYMTAB_AVAILABLE
-  if (is_compressed_mode_p (info))
-    return print_insn_compr (memaddr, info);
+  if (is_compressed_mode_p (info, TRUE))
+    return print_insn_micromips (memaddr, info);
+  if (is_compressed_mode_p (info, FALSE))
+    return print_insn_mips16 (memaddr, info);
 #endif
 
   status = (*info->read_memory_func) (memaddr, buffer, INSNLEN, info);
This page took 0.025451 seconds and 4 git commands to generate.