diff options
-rw-r--r-- | binutils/ChangeLog | 7 | ||||
-rw-r--r-- | binutils/testsuite/binutils-all/mips/mips.exp | 1 | ||||
-rw-r--r-- | binutils/testsuite/binutils-all/mips/mixed-mips16-micromips.d | 30 | ||||
-rw-r--r-- | binutils/testsuite/binutils-all/mips/mixed-mips16-micromips.s | 32 | ||||
-rw-r--r-- | opcodes/ChangeLog | 7 | ||||
-rw-r--r-- | opcodes/mips-dis.c | 38 |
6 files changed, 98 insertions, 17 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 6eb3fa7..c4bb34e 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,10 @@ +2016-05-18 Maciej W. Rozycki <macro@imgtec.com> + + * testsuite/binutils-all/mips/mixed-mips16-micromips.d: New test. + * testsuite/binutils-all/mips/mixed-mips16-micromips.s: New test + source. + * testsuite/binutils-all/mips/mips.exp: Run the new test. + 2016-05-18 Nick Clifton <nickc@redhat.com> * po/sv.po: Updated Swedish translation. diff --git a/binutils/testsuite/binutils-all/mips/mips.exp b/binutils/testsuite/binutils-all/mips/mips.exp index 5c93959..4dab9a6 100644 --- a/binutils/testsuite/binutils-all/mips/mips.exp +++ b/binutils/testsuite/binutils-all/mips/mips.exp @@ -22,5 +22,6 @@ if ![istarget mips*-*-*] { if [is_elf_format] { run_dump_test "mixed-mips16" run_dump_test "mixed-micromips" + run_dump_test "mixed-mips16-micromips" run_dump_test "mips16-undecoded" } diff --git a/binutils/testsuite/binutils-all/mips/mixed-mips16-micromips.d b/binutils/testsuite/binutils-all/mips/mixed-mips16-micromips.d new file mode 100644 index 0000000..4a53dfb --- /dev/null +++ b/binutils/testsuite/binutils-all/mips/mixed-mips16-micromips.d @@ -0,0 +1,30 @@ +#PROG: objcopy +#objdump: -drt +#name: Mixed MIPS16 and microMIPS disassembly + +# Test mixed-mode compressed disassembly. + +.*: +file format .*mips.* + +SYMBOL TABLE: +#... +[0-9a-f]+ g +F +\.text 0+00000c 0xf0 foo +#... +[0-9a-f]+ g +F +\.text 0+00000c 0x80 bar + +Disassembly of section \.text: +[0-9a-f]+ <foo>: + +[0-9a-f]+: b202 lw v0,8 <\.foo\.data> + +[0-9a-f]+: 9a60 lw v1,0\(v0\) + +[0-9a-f]+: eb00 jr v1 + +[0-9a-f]+: 653b move t9,v1 + +[0-9a-f]+ <\.foo\.data>: + +[0-9a-f]+: 4040 4040 0000 0000 @@@@\.\.\.\. + +[0-9a-f]+ <bar>: + +[0-9a-f]+: 41a3 0000 lui v1,0x0 + +[0-9a-f]+: ff23 0000 lw t9,0\(v1\) + +[0-9a-f]+: 45b9 jrc t9 + +[0-9a-f]+: 0c00 nop + \.\.\. diff --git a/binutils/testsuite/binutils-all/mips/mixed-mips16-micromips.s b/binutils/testsuite/binutils-all/mips/mixed-mips16-micromips.s new file mode 100644 index 0000000..07dcceb --- /dev/null +++ b/binutils/testsuite/binutils-all/mips/mixed-mips16-micromips.s @@ -0,0 +1,32 @@ + .align 4, 0 + .set mips16 + .globl foo + .ent foo +foo: + lw $v0, .foo.data + lw $v1, 0($v0) + move $t9, $v1 + jr $v1 + + .type .foo.data, @object +.foo.data: + .word 0x40404040 + .size .foo.data, . - .foo.data + .end foo + .set nomips16 + + .align 4, 0 + .set micromips + .globl bar + .ent bar +bar: + lui $v1, 0 + lw $t9, 0($v1) + jrc $t9 + nop + .end bar + .set nomicromips + +# Force some (non-delay-slot) zero bytes, to make 'objdump' print ... + .align 4, 0 + .space 16 diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index ce23ca1..680d2d8 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,10 @@ +2016-05-18 Maciej W. Rozycki <macro@imgtec.com> + + * mips-dis.c (is_compressed_mode_p): Add `micromips_p' operand, + replacing references to `micromips_ase' throughout. + (_print_insn_mips): Don't use file-level microMIPS annotation to + determine the disassembly mode with the symbol table. + 2016-05-13 Peter Bergner <bergner@vnet.ibm.com> * ppc-opc.c (IMM8): Use PPC_OPERAND_SIGNOPT. diff --git a/opcodes/mips-dis.c b/opcodes/mips-dis.c index 535c14a..3f874e7 100644 --- a/opcodes/mips-dis.c +++ b/opcodes/mips-dis.c @@ -2268,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; } @@ -2313,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; @@ -2325,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); |