version 1.1.1.2, 2016/10/26 17:03:38 |
version 1.1.1.3, 2018/04/14 15:37:32 |
|
|
/* Print mips instructions for GDB, the GNU debugger, or for objdump. |
/* 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). |
Contributed by Nobuyuki Hikichi(hikichi@sra.co.jp). |
|
|
This file is part of the GNU opcodes library. |
This file is part of the GNU opcodes library. |
Line 563 const struct mips_arch_choice mips_arch_ |
|
Line 563 const struct mips_arch_choice mips_arch_ |
|
{ "mips32r6", 1, bfd_mach_mipsisa32r6, CPU_MIPS32R6, |
{ "mips32r6", 1, bfd_mach_mipsisa32r6, CPU_MIPS32R6, |
ISA_MIPS32R6, |
ISA_MIPS32R6, |
(ASE_EVA | ASE_MSA | ASE_VIRT | ASE_XPA | ASE_MCU | ASE_MT | ASE_DSP |
(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_cp0_names_mips3264r2, |
mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2), |
mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2), |
mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 }, |
mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 }, |
Line 602 const struct mips_arch_choice mips_arch_ |
|
Line 602 const struct mips_arch_choice mips_arch_ |
|
{ "mips64r6", 1, bfd_mach_mipsisa64r6, CPU_MIPS64R6, |
{ "mips64r6", 1, bfd_mach_mipsisa64r6, CPU_MIPS64R6, |
ISA_MIPS64R6, |
ISA_MIPS64R6, |
(ASE_EVA | ASE_MSA | ASE_MSA64 | ASE_XPA | ASE_VIRT | ASE_VIRT64 |
(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_cp0_names_mips3264r2, |
mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2), |
mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2), |
mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 }, |
mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 }, |
Line 1894 print_mips16_insn_arg (struct disassembl |
|
Line 1894 print_mips16_insn_arg (struct disassembl |
|
{ |
{ |
operand = ext_operand; |
operand = ext_operand; |
if (operand->size == 16) |
if (operand->size == 16) |
uval |= ((extend & 0x1f) << 11) | (extend & 0x7e0); |
uval = (((extend & 0x1f) << 11) | (extend & 0x7e0) |
|
| (uval & 0x1f)); |
else if (operand->size == 15) |
else if (operand->size == 15) |
uval |= ((extend & 0xf) << 11) | (extend & 0x7f0); |
uval |= ((extend & 0xf) << 11) | (extend & 0x7f0); |
else |
else |
uval = ((extend >> 6) & 0x1f) | (extend & 0x20); |
uval = ((((extend >> 6) & 0x1f) | (extend & 0x20)) |
|
& ((1U << operand->size) - 1)); |
} |
} |
} |
} |
} |
} |
Line 2185 print_insn_micromips (bfd_vma memaddr, s |
|
Line 2187 print_insn_micromips (bfd_vma memaddr, s |
|
else |
else |
insn = bfd_getl16 (buffer); |
insn = bfd_getl16 (buffer); |
|
|
if ((insn & 0xfc00) == 0x7c00) |
if ((insn & 0x1c00) == 0x0000 || (insn & 0x1000) == 0x1000) |
{ |
|
/* 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) |
|
{ |
{ |
/* This is a 32-bit microMIPS instruction. */ |
/* This is a 32-bit microMIPS instruction. */ |
higher = insn; |
higher = insn; |
Line 2300 print_insn_micromips (bfd_vma memaddr, s |
|
Line 2268 print_insn_micromips (bfd_vma memaddr, s |
|
} |
} |
|
|
/* Return 1 if a symbol associated with the location being disassembled |
/* Return 1 if a symbol associated with the location being disassembled |
indicates a compressed (MIPS16 or microMIPS) mode. We iterate over |
indicates a compressed mode, either MIPS16 or microMIPS, according to |
all the symbols at the address being considered assuming if at least |
MICROMIPS_P. We iterate over all the symbols at the address being |
one of them indicates code compression, then such code has been |
considered assuming if at least one of them indicates code compression, |
genuinely produced here (other symbols could have been derived from |
then such code has been genuinely produced here (other symbols could |
function symbols defined elsewhere or could define data). Otherwise, |
have been derived from function symbols defined elsewhere or could |
return 0. */ |
define data). Otherwise, return 0. */ |
|
|
static bfd_boolean |
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 i; |
int l; |
int l; |
|
|
for (i = info->symtab_pos, l = i + info->num_symbols; i < l; i++) |
for (i = info->symtab_pos, l = i + info->num_symbols; i < l; i++) |
if (((info->symtab[i])->flags & BSF_SYNTHETIC) != 0 |
if (((info->symtab[i])->flags & BSF_SYNTHETIC) != 0 |
&& ((!micromips_ase |
&& ((!micromips_p |
&& ELF_ST_IS_MIPS16 ((*info->symbols)->udata.i)) |
&& ELF_ST_IS_MIPS16 ((*info->symbols)->udata.i)) |
|| (micromips_ase |
|| (micromips_p |
&& ELF_ST_IS_MICROMIPS ((*info->symbols)->udata.i)))) |
&& ELF_ST_IS_MICROMIPS ((*info->symbols)->udata.i)))) |
return 1; |
return 1; |
else if (bfd_asymbol_flavour (info->symtab[i]) == bfd_target_elf_flavour |
else if (bfd_asymbol_flavour (info->symtab[i]) == bfd_target_elf_flavour |
&& info->symtab[i]->section == info->section) |
&& info->symtab[i]->section == info->section) |
{ |
{ |
elf_symbol_type *symbol = (elf_symbol_type *) info->symtab[i]; |
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)) |
&& ELF_ST_IS_MIPS16 (symbol->internal_elf_sym.st_other)) |
|| (micromips_ase |
|| (micromips_p |
&& ELF_ST_IS_MICROMIPS (symbol->internal_elf_sym.st_other))) |
&& ELF_ST_IS_MICROMIPS (symbol->internal_elf_sym.st_other))) |
return 1; |
return 1; |
} |
} |
Line 2345 _print_insn_mips (bfd_vma memaddr, |
|
Line 2313 _print_insn_mips (bfd_vma memaddr, |
|
struct disassemble_info *info, |
struct disassemble_info *info, |
enum bfd_endian endianness) |
enum bfd_endian endianness) |
{ |
{ |
int (*print_insn_compr) (bfd_vma, struct disassemble_info *); |
|
bfd_byte buffer[INSNLEN]; |
bfd_byte buffer[INSNLEN]; |
int status; |
int status; |
|
|
Line 2357 _print_insn_mips (bfd_vma memaddr, |
|
Line 2324 _print_insn_mips (bfd_vma memaddr, |
|
if (info->mach == bfd_mach_mips_micromips) |
if (info->mach == bfd_mach_mips_micromips) |
return print_insn_micromips (memaddr, info); |
return print_insn_micromips (memaddr, info); |
|
|
print_insn_compr = !micromips_ase ? print_insn_mips16 : print_insn_micromips; |
|
|
|
#if 1 |
#if 1 |
/* FIXME: If odd address, this is CLEARLY a compressed instruction. */ |
/* FIXME: If odd address, this is CLEARLY a compressed instruction. */ |
/* Only a few tools will work this way. */ |
/* Only a few tools will work this way. */ |
if (memaddr & 0x01) |
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 |
#endif |
|
|
#if SYMTAB_AVAILABLE |
#if SYMTAB_AVAILABLE |
if (is_compressed_mode_p (info)) |
if (is_compressed_mode_p (info, TRUE)) |
return print_insn_compr (memaddr, info); |
return print_insn_micromips (memaddr, info); |
|
if (is_compressed_mode_p (info, FALSE)) |
|
return print_insn_mips16 (memaddr, info); |
#endif |
#endif |
|
|
status = (*info->read_memory_func) (memaddr, buffer, INSNLEN, info); |
status = (*info->read_memory_func) (memaddr, buffer, INSNLEN, info); |