aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2013-05-24 10:44:59 -0700
committerH.J. Lu <hjl.tools@gmail.com>2013-05-24 10:44:59 -0700
commit4e469ecbe632e5011a25238fbee2cc5c9de4996f (patch)
treec9e5c4c4b1813582734dee28440551bbeb2c2b31
parente30d1ef956c66239f8f23c9aef8f56054215041e (diff)
parent77cc918cee4071c3be0153677778a91e5b87d7a0 (diff)
downloadbinutils-hjl/lto/master.tar.gz
Merge remote-tracking branch 'origin/master' into hjl/lto/masterhjl/lto/master
-rw-r--r--COPYING.NEWLIB31
-rw-r--r--ChangeLog4
-rw-r--r--bfd/ChangeLog145
-rw-r--r--bfd/archures.c13
-rw-r--r--bfd/bfd-in2.h24
-rw-r--r--bfd/bfd.c4
-rw-r--r--bfd/coff-rs6000.c4
-rw-r--r--bfd/coff64-rs6000.c3
-rw-r--r--bfd/coffcode.h6
-rw-r--r--bfd/config.bfd3
-rwxr-xr-xbfd/configure1
-rw-r--r--bfd/configure.in3
-rw-r--r--bfd/cpu-msp430.c46
-rw-r--r--bfd/ecoff.c4
-rw-r--r--bfd/elf-bfd.h5
-rw-r--r--bfd/elf-ifunc.c48
-rw-r--r--bfd/elf32-i386.c3
-rw-r--r--bfd/elf32-mips.c4
-rw-r--r--bfd/elf32-msp430.c1833
-rw-r--r--bfd/elf32-vax.c19
-rw-r--r--bfd/elf64-aarch64.c56
-rw-r--r--bfd/elf64-mips.c27
-rw-r--r--bfd/elf64-ppc.c29
-rw-r--r--bfd/elf64-x86-64.c1
-rw-r--r--bfd/elflink.c43
-rw-r--r--bfd/elfn32-mips.c27
-rw-r--r--bfd/elfxx-mips.c2
-rw-r--r--bfd/format.c22
-rw-r--r--bfd/libbfd.h15
-rw-r--r--bfd/reloc.c30
-rw-r--r--bfd/srec.c7
-rw-r--r--bfd/targets.c6
-rw-r--r--bfd/version.h2
-rw-r--r--binutils/ChangeLog25
-rw-r--r--binutils/doc/binutils.texi3
-rw-r--r--binutils/dwarf.c33
-rw-r--r--binutils/elfcomm.c119
-rw-r--r--binutils/readelf.c209
-rw-r--r--binutils/testsuite/ChangeLog9
-rw-r--r--binutils/testsuite/binutils-all/readelf.exp6
-rw-r--r--binutils/testsuite/lib/binutils-common.exp1
-rw-r--r--config/ChangeLog10
-rw-r--r--config/bootstrap-asan.mk1
-rw-r--r--config/dfp.m42
-rw-r--r--config/picflag.m44
-rw-r--r--gas/ChangeLog110
-rw-r--r--gas/NEWS2
-rw-r--r--gas/config/tc-mips.c178
-rw-r--r--gas/config/tc-msp430.c2630
-rw-r--r--gas/config/tc-msp430.h56
-rw-r--r--gas/config/tc-ppc.c369
-rw-r--r--gas/configure.tgt2
-rw-r--r--gas/doc/c-mips.texi14
-rw-r--r--gas/doc/c-msp430.texi38
-rw-r--r--gas/testsuite/ChangeLog110
-rw-r--r--gas/testsuite/gas/aarch64/diagnostic.l4
-rw-r--r--gas/testsuite/gas/aarch64/diagnostic.s2
-rw-r--r--gas/testsuite/gas/aarch64/movi.d3
-rw-r--r--gas/testsuite/gas/aarch64/movi.s5
-rw-r--r--gas/testsuite/gas/all/gas.exp8
-rw-r--r--gas/testsuite/gas/all/sleb128-4.d1
-rw-r--r--gas/testsuite/gas/elf/elf.exp8
-rw-r--r--gas/testsuite/gas/elf/section2.e-msp4309
-rw-r--r--gas/testsuite/gas/lns/lns-big-delta.d4
-rw-r--r--gas/testsuite/gas/lns/lns.exp1
-rw-r--r--gas/testsuite/gas/mips/ext-ill.l6
-rw-r--r--gas/testsuite/gas/mips/ext-ill.s9
-rw-r--r--gas/testsuite/gas/mips/micromips-warn-branch-delay.d30
-rw-r--r--gas/testsuite/gas/mips/mips.exp7
-rw-r--r--gas/testsuite/gas/mips/mips16-stabs.d6
-rw-r--r--gas/testsuite/gas/mips/mips16-stabs.s8
-rw-r--r--gas/testsuite/gas/mips/r5900-full.d18
-rw-r--r--gas/testsuite/gas/mips/r5900-full.s12
-rw-r--r--gas/testsuite/gas/mips/r5900-vu0.d66
-rw-r--r--gas/testsuite/gas/mips/r5900-vu0.s76
-rw-r--r--gas/testsuite/gas/mips/virt.d20
-rw-r--r--gas/testsuite/gas/mips/virt.s22
-rw-r--r--gas/testsuite/gas/mips/virt64.d12
-rw-r--r--gas/testsuite/gas/mips/virt64.s12
-rw-r--r--gas/testsuite/gas/msp430/msp430.exp4
-rw-r--r--gas/testsuite/gas/msp430/msp430x.d216
-rw-r--r--gas/testsuite/gas/msp430/msp430x.s261
-rw-r--r--gas/testsuite/gas/msp430/opcode.d8
-rw-r--r--gas/testsuite/gas/msp430/opcode.s2
-rw-r--r--gas/testsuite/gas/ppc/altivec2.d64
-rw-r--r--gas/testsuite/gas/ppc/altivec2.s65
-rw-r--r--gas/testsuite/gas/ppc/power8.d124
-rw-r--r--gas/testsuite/gas/ppc/power8.s123
-rw-r--r--gas/testsuite/gas/ppc/ppc.exp3
-rw-r--r--gas/testsuite/gas/ppc/vsx.d5
-rw-r--r--gas/testsuite/gas/ppc/vsx.s4
-rw-r--r--gas/testsuite/gas/ppc/vsx2.d65
-rw-r--r--gas/testsuite/gas/ppc/vsx2.s57
-rw-r--r--gas/testsuite/gas/s390/zarch-zEC12.d8
-rw-r--r--gas/testsuite/gas/s390/zarch-zEC12.s8
-rw-r--r--gold/ChangeLog87
-rw-r--r--gold/Makefile.in1
-rwxr-xr-xgold/configure3
-rw-r--r--gold/configure.ac2
-rw-r--r--gold/layout.cc131
-rw-r--r--gold/merge.cc43
-rw-r--r--gold/merge.h3
-rw-r--r--gold/object.cc13
-rw-r--r--gold/object.h4
-rw-r--r--gold/options.cc233
-rw-r--r--gold/options.h433
-rw-r--r--gold/output.cc5
-rw-r--r--gold/stringpool.cc14
-rw-r--r--gold/stringpool.h4
-rw-r--r--gold/symtab.h5
-rw-r--r--gold/target-reloc.h8
-rw-r--r--gold/testsuite/Makefile.am51
-rw-r--r--gold/testsuite/Makefile.in54
-rwxr-xr-xgold/testsuite/debug_msg.sh31
-rwxr-xr-xgold/testsuite/merge_string_literals.sh41
-rw-r--r--gold/testsuite/merge_string_literals_1.c31
-rw-r--r--gold/testsuite/merge_string_literals_2.c31
-rw-r--r--gold/testsuite/missing_key_func.cc46
-rwxr-xr-xgold/testsuite/missing_key_func.sh58
-rw-r--r--gprof/ChangeLog12
-rw-r--r--gprof/Makefile.am2
-rw-r--r--gprof/Makefile.in6
-rw-r--r--gprof/aarch64.c99
-rw-r--r--gprof/corefile.c5
-rw-r--r--include/ChangeLog5
-rw-r--r--include/elf/ChangeLog14
-rw-r--r--include/elf/common.h5
-rw-r--r--include/elf/mips.h5
-rw-r--r--include/elf/msp430.h47
-rw-r--r--include/opcode/ChangeLog17
-rw-r--r--include/opcode/mips.h19
-rw-r--r--include/opcode/msp430.h70
-rw-r--r--ld/ChangeLog43
-rw-r--r--ld/Makefile.am5
-rw-r--r--ld/Makefile.in6
-rw-r--r--ld/NEWS2
-rw-r--r--ld/configure.tgt6
-rw-r--r--ld/emulparams/msp430all.sh9
-rw-r--r--ld/emultempl/elf32.em23
-rw-r--r--ld/emultempl/generic.em12
-rw-r--r--ld/ld.texinfo8
-rw-r--r--ld/ldmain.c8
-rw-r--r--ld/ldmain.h12
-rw-r--r--ld/scripttempl/elf32msp430.sc138
-rw-r--r--ld/scripttempl/elf32msp430_3.sc16
-rw-r--r--ld/testsuite/ChangeLog77
-rw-r--r--ld/testsuite/ld-arm/arm-elf.exp2
-rw-r--r--ld/testsuite/ld-arm/ifunc-17.dd22
-rw-r--r--ld/testsuite/ld-arm/ifunc-17.gd8
-rw-r--r--ld/testsuite/ld-arm/ifunc-17.rd6
-rw-r--r--ld/testsuite/ld-elf/ehdr_start.d2
-rw-r--r--ld/testsuite/ld-elf/flags1.d4
-rw-r--r--ld/testsuite/ld-elf/init-fini-arrays.d5
-rw-r--r--ld/testsuite/ld-elf/merge.d2
-rw-r--r--ld/testsuite/ld-elf/provide-hidden-1.ld15
-rw-r--r--ld/testsuite/ld-elf/provide-hidden-1.s4
-rw-r--r--ld/testsuite/ld-elf/provide-hidden-2.ld12
-rw-r--r--ld/testsuite/ld-elf/provide-hidden-2.s5
-rw-r--r--ld/testsuite/ld-elf/provide-hidden-3.s4
-rw-r--r--ld/testsuite/ld-elf/provide-hidden-4.s5
-rw-r--r--ld/testsuite/ld-elf/provide-hidden-abs.nd5
-rw-r--r--ld/testsuite/ld-elf/provide-hidden-def.nd5
-rw-r--r--ld/testsuite/ld-elf/provide-hidden-dyn.nd7
-rw-r--r--ld/testsuite/ld-elf/provide-hidden-dynabs.nd8
-rw-r--r--ld/testsuite/ld-elf/provide-hidden-dynsec.nd8
-rw-r--r--ld/testsuite/ld-elf/provide-hidden-s.ld11
-rw-r--r--ld/testsuite/ld-elf/provide-hidden-s.nd8
-rw-r--r--ld/testsuite/ld-elf/provide-hidden-sec.nd5
-rw-r--r--ld/testsuite/ld-elf/provide-hidden.exp154
-rw-r--r--ld/testsuite/ld-elf/sec64k.exp1
-rw-r--r--ld/testsuite/ld-gc/pr13683.d2
-rw-r--r--ld/testsuite/ld-mips-elf/ehdr_start-1.ld9
-rw-r--r--ld/testsuite/ld-mips-elf/ehdr_start-1.nd4
-rw-r--r--ld/testsuite/ld-mips-elf/ehdr_start-2.ld10
-rw-r--r--ld/testsuite/ld-mips-elf/ehdr_start-2.nd4
-rw-r--r--ld/testsuite/ld-mips-elf/ehdr_start-new.s13
-rw-r--r--ld/testsuite/ld-mips-elf/ehdr_start-o32.s14
-rw-r--r--ld/testsuite/ld-mips-elf/mips-elf.exp25
-rw-r--r--ld/testsuite/ld-plugin/pr12982.d3
-rw-r--r--ld/testsuite/ld-powerpc/aix-core-sec-1.hd2
-rw-r--r--ld/testsuite/ld-powerpc/aix-core-sec-2.hd2
-rw-r--r--ld/testsuite/ld-powerpc/aix-core-sec-3.hd2
-rw-r--r--ld/testsuite/ld-powerpc/export-class.exp33
-rw-r--r--ld/testsuite/ld-powerpc/powerpc-64-export-class.xd20
-rw-r--r--ld/testsuite/ld-srec/srec.exp8
-rw-r--r--ld/testsuite/ld-undefined/undefined.exp5
-rw-r--r--ld/testsuite/lib/ld-lib.exp3
-rw-r--r--libiberty/ChangeLog8
-rw-r--r--libiberty/hashtab.c13
-rw-r--r--opcodes/ChangeLog73
-rw-r--r--opcodes/aarch64-asm.c1
-rw-r--r--opcodes/aarch64-opc.c6
-rw-r--r--opcodes/i386-gen.c2
-rw-r--r--opcodes/i386-init.h2
-rw-r--r--opcodes/ia64-asmtab.c10
-rw-r--r--opcodes/ia64-raw.tbl8
-rw-r--r--opcodes/ia64-waw.tbl2
-rw-r--r--opcodes/mips-dis.c19
-rw-r--r--opcodes/mips-opc.c53
-rw-r--r--opcodes/msp430-dis.c712
-rw-r--r--opcodes/ppc-dis.c5
-rw-r--r--opcodes/ppc-opc.c186
-rw-r--r--opcodes/s390-opc.c4
203 files changed, 9371 insertions, 1970 deletions
diff --git a/COPYING.NEWLIB b/COPYING.NEWLIB
index 6849eb5b4..73379ffc3 100644
--- a/COPYING.NEWLIB
+++ b/COPYING.NEWLIB
@@ -894,3 +894,34 @@ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(40) - Altera Corportion (nios2-* targets)
+
+Copyright (c) 2003 Altera Corporation
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+ o Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ o Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ o Neither the name of Altera Corporation nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY ALTERA CORPORATION, THE COPYRIGHT HOLDER,
+AND ITS CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/ChangeLog b/ChangeLog
index 06c7d47f4..2d6d31082 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2013-05-06 Sandra Loosemore <sandra@codesourcery.com>
+
+ * COPYING.NEWLIB: Add Altera Corporation copyright.
+
2013-04-29 Jan-Benedict Glaw <jbglaw@lug-owl.de>
* config.guess: Update from config repo.
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 06bdfe7fe..d01e6875e 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,148 @@
+2013-05-23 Alan Modra <amodra@gmail.com>
+
+ * format.c (bfd_check_format_matches): Don't match a target in
+ targ_selvecs if some other target is a better match. If
+ targets implement match priority, fall back to the first of
+ the best matches.
+
+2013-05-22 Eric Herman <eric@freesa.org>
+
+ PR binutils/15462
+ * elfxx-mips.c (_bfd_mips_elf_relocate_section): Warning fix.
+
+2013-05-22 Ralf Dreesen <gamma@dreesen.net>
+
+ PR binutils/15474
+ * srec.c (srec_set_section_contents): Properly convert size
+ and offset to address when octets_per_byte is not unity.
+
+2013-05-20 Maciej W. Rozycki <macro@linux-mips.org>
+
+ * elf32-vax.c (elf_vax_instantiate_got_entries): Only set the
+ refcount member of the gotplt_union when resetting the reference
+ count. Adjust comment.
+
+2013-05-20 Will Newton <will.newton@linaro.org>
+
+ * elf64-aarch64.c (elf64_aarch64_link_hash_entry): Remove
+ relocs_copied member.
+ (elf64_aarch64_link_hash_newfunc): Remove initialization of
+ relocs_copied member.
+ (elf64_aarch64_copy_indirect_symbol): Remove code to copy
+ relocs_copied member.
+
+2013-05-19 Maciej W. Rozycki <macro@linux-mips.org>
+
+ * elf32-vax.c (elf_vax_adjust_dynamic_symbol): Convert K&R
+ function definition.
+
+2013-05-16 Cary Coutant <ccoutant@google.com>
+
+ * ecoff.c (ecoff_link_check_archive_element): Add initializers for
+ external_ext_size and esize.
+
+2013-05-16 Tristan Gingold <gingold@adacore.com>
+
+ * coff-rs6000.c (_bfd_xcoff_reloc_type_lookup): Handle BFD_RELOC_16.
+ * coff64-rs6000.c (xcoff64_reloc_type_lookup): Likewise.
+
+2013-05-15 Andreas Schwab <schwab@suse.de>
+
+ * elf64-aarch64.c (elf_backend_default_execstack): Define to 0.
+
+2013-05-10 Joel Brobecker <brobecker@adacore.com>
+
+ * coffcode.h (styp_to_sec_flags) [RS6000COFF_C]: Add handling
+ of STYP_EXCEPT, STYP_LOADER and STYP_TYPCHK sections.
+
+2013-05-09 Joel Brobecker <brobecker@adacore.com>
+
+ * bfd.c (_bfd_default_error_handler): Replace use of putc
+ by fputc. Add comment explaining why.
+
+2013-05-09 Alan Modra <amodra@gmail.com>
+
+ * elflink.c (elf_link_add_object_symbols): Don't omit reading
+ of symbols when hashes already exist.
+
+2013-05-07 Will Newton <will.newton@linaro.org>
+
+ * elf-ifunc.c (_bfd_elf_allocate_ifunc_dyn_relocs): Add a
+ plt_header_size argument for ports where it differs from
+ plt_entry_size.
+ * elf-bfd.h: Likewise.
+ * elf32-i386.c: Pass plt_header_size to
+ _bfd_elf_allocate_ifunc_dyn_relocs.
+ * elf64-x86-64.c: Likewise.
+
+2013-05-07 Will Newton <will.newton@linaro.org>
+
+ * elf-ifunc.c (_bfd_elf_create_ifunc_dyn_reloc): Remove unused
+ function.
+ * elf-bfd.h: Likewise.
+
+2013-05-06 Paul Brook <paul@codesourcery.com>
+
+ * elf64-mips.c (elf_mips_gnu_pcrel32): New.
+ (bfd_elf64_bfd_reloc_type_lookup, bfd_elf64_bfd_reloc_name_lookup,
+ mips_elf64_rtype_to_howto): Handle R_MIPS_PC32.
+ * elfn32-mips.c (elf_mips_gnu_pcrel32): New.
+ (bfd_elfn32_bfd_reloc_type_lookup, bfd_elfn32_bfd_reloc_name_lookup,
+ mips_elfn32_rtype_to_howto): Handle R_MIPS_PC32.
+
+2013-05-06 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (opd_entry_value): Handle case where symbol
+ hashes are not available.
+
+2013-05-06 Alan Modra <amodra@gmail.com>
+
+ * elflink.c (elf_link_add_object_symbols): Don't save symbol
+ hashes around loading as-needed library. Zero them on allocation,
+ and restore to initial all-zero state if library not needed.
+ Arrange to reuse hashes if we load library again later.
+
+2013-05-04 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * elf32-mips.c (elf_mips_copy_howto, elf_mips_jump_slot_howto):
+ Use _bfd_mips_elf_generic_reloc instead of bfd_elf_generic_reloc.
+ * elfn32-mips.c: Likewise.
+ * elf64-mips.c: Likewise.
+
+2013-05-02 Nick Clifton <nickc@redhat.com>
+
+ * archures.c: Add some more MSP430 machine numbers.
+ * config.bfd (msp430): Define targ_selvecs.
+ * configure.in: Add bfd_elf32_msp430_ti_vec.
+ * cpu-msp430.c: Add some more MSP430 machine numbers.
+ * elf32-msp430.c Add support for MSP430X relocations.
+ Add support for TI compiler generated relocations.
+ Add support for sym_diff relocations.
+ Add support for relaxing out of range short branches into long
+ branches.
+ Add support for MSP430 attribute section.
+ * reloc.c: Add MSP430X relocations.
+ * targets.c: Add bfd_elf32_msp430_ti_vec.
+ * bfd-in2.h: Regenerate.
+ * configure: Regenerate.
+ * libbfd.h: Regenerate.
+
+2013-05-01 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * config.bfd: Replace alpha*-*-linuxecoff* pattern with
+ alpha*-*-linux*ecoff*.
+
+2013-04-30 Olaf Flebbe <o.flebbe@science-computing.de>
+
+ PR binutils/15417
+ * elflink.c (elf_link_add_object_symbols): Initialise 'idx' to
+ zero.
+
+2013-04-30 Alan Modra <amodra@gmail.com>
+
+ * elflink.c (bfd_elf_record_link_assignment): Dont make
+ STV_INTERNAL symbols STV_HIDDEN.
+
2013-04-29 Nick Clifton <nickc@redhat.com>
* elflink.c (_bfd_elf_gc_mark_extra_sections): Remove mark from
diff --git a/bfd/archures.c b/bfd/archures.c
index 0be72da52..f7cef8bfb 100644
--- a/bfd/archures.c
+++ b/bfd/archures.c
@@ -1,7 +1,5 @@
/* BFD library support routines for architectures.
- Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011,
- 2012, 2013 Free Software Foundation, Inc.
+ Copyright 1990-2013 Free Software Foundation, Inc.
Hacked by John Gilmore and Steve Chamberlain of Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
@@ -437,7 +435,12 @@ DESCRIPTION
.#define bfd_mach_msp14 14
.#define bfd_mach_msp15 15
.#define bfd_mach_msp16 16
+.#define bfd_mach_msp20 20
.#define bfd_mach_msp21 21
+.#define bfd_mach_msp22 22
+.#define bfd_mach_msp23 23
+.#define bfd_mach_msp24 24
+.#define bfd_mach_msp26 26
.#define bfd_mach_msp31 31
.#define bfd_mach_msp32 32
.#define bfd_mach_msp33 33
@@ -445,6 +448,10 @@ DESCRIPTION
.#define bfd_mach_msp42 42
.#define bfd_mach_msp43 43
.#define bfd_mach_msp44 44
+.#define bfd_mach_msp430x 45
+.#define bfd_mach_msp46 46
+.#define bfd_mach_msp47 47
+.#define bfd_mach_msp54 54
. bfd_arch_xc16x, {* Infineon's XC16X Series. *}
.#define bfd_mach_xc16x 1
.#define bfd_mach_xc16xl 2
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 9fc98fe54..878def79c 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -2176,7 +2176,12 @@ enum bfd_architecture
#define bfd_mach_msp14 14
#define bfd_mach_msp15 15
#define bfd_mach_msp16 16
+#define bfd_mach_msp20 20
#define bfd_mach_msp21 21
+#define bfd_mach_msp22 22
+#define bfd_mach_msp23 23
+#define bfd_mach_msp24 24
+#define bfd_mach_msp26 26
#define bfd_mach_msp31 31
#define bfd_mach_msp32 32
#define bfd_mach_msp33 33
@@ -2184,6 +2189,10 @@ enum bfd_architecture
#define bfd_mach_msp42 42
#define bfd_mach_msp43 43
#define bfd_mach_msp44 44
+#define bfd_mach_msp430x 45
+#define bfd_mach_msp46 46
+#define bfd_mach_msp47 47
+#define bfd_mach_msp54 54
bfd_arch_xc16x, /* Infineon's XC16X Series. */
#define bfd_mach_xc16x 1
#define bfd_mach_xc16xl 2
@@ -4924,6 +4933,21 @@ a matching LO8XG part. */
BFD_RELOC_MSP430_16_BYTE,
BFD_RELOC_MSP430_2X_PCREL,
BFD_RELOC_MSP430_RL_PCREL,
+ BFD_RELOC_MSP430_ABS8,
+ BFD_RELOC_MSP430X_PCR20_EXT_SRC,
+ BFD_RELOC_MSP430X_PCR20_EXT_DST,
+ BFD_RELOC_MSP430X_PCR20_EXT_ODST,
+ BFD_RELOC_MSP430X_ABS20_EXT_SRC,
+ BFD_RELOC_MSP430X_ABS20_EXT_DST,
+ BFD_RELOC_MSP430X_ABS20_EXT_ODST,
+ BFD_RELOC_MSP430X_ABS20_ADR_SRC,
+ BFD_RELOC_MSP430X_ABS20_ADR_DST,
+ BFD_RELOC_MSP430X_PCR16,
+ BFD_RELOC_MSP430X_PCR20_CALL,
+ BFD_RELOC_MSP430X_ABS16,
+ BFD_RELOC_MSP430_ABS_HI16,
+ BFD_RELOC_MSP430_PREL31,
+ BFD_RELOC_MSP430_SYM_DIFF,
/* Relocations used by the Altera Nios II core. */
BFD_RELOC_NIOS2_S16,
diff --git a/bfd/bfd.c b/bfd/bfd.c
index 416efdcbc..2ef48a7e9 100644
--- a/bfd/bfd.c
+++ b/bfd/bfd.c
@@ -747,7 +747,9 @@ _bfd_default_error_handler (const char *fmt, ...)
vfprintf (stderr, new_fmt, ap);
va_end (ap);
- putc ('\n', stderr);
+ /* On AIX, putc is implemented as a macro that triggers a -Wunused-value
+ warning, so use the fputc function to avoid it. */
+ fputc ('\n', stderr);
fflush (stderr);
}
diff --git a/bfd/coff-rs6000.c b/bfd/coff-rs6000.c
index 0945aca0e..aa61afbba 100644
--- a/bfd/coff-rs6000.c
+++ b/bfd/coff-rs6000.c
@@ -1098,7 +1098,6 @@ reloc_howto_type xcoff_howto_table[] =
0xffff, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
-
};
void
@@ -1146,6 +1145,9 @@ _bfd_xcoff_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
return &xcoff_howto_table[8];
case BFD_RELOC_PPC_TOC16:
return &xcoff_howto_table[3];
+ case BFD_RELOC_16:
+ /* Note that this relocation is only internally used by gas. */
+ return &xcoff_howto_table[0xc];
case BFD_RELOC_32:
case BFD_RELOC_CTOR:
return &xcoff_howto_table[0];
diff --git a/bfd/coff64-rs6000.c b/bfd/coff64-rs6000.c
index 5f4a502c5..56a0d2573 100644
--- a/bfd/coff64-rs6000.c
+++ b/bfd/coff64-rs6000.c
@@ -1826,6 +1826,9 @@ xcoff64_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
return &xcoff64_howto_table[8];
case BFD_RELOC_PPC_TOC16:
return &xcoff64_howto_table[3];
+ case BFD_RELOC_16:
+ /* Note that this relocation is only internally used by gas. */
+ return &xcoff64_howto_table[0xc];
case BFD_RELOC_32:
case BFD_RELOC_CTOR:
return &xcoff64_howto_table[0x1c];
diff --git a/bfd/coffcode.h b/bfd/coffcode.h
index 9d9c99215..2a1a17260 100644
--- a/bfd/coffcode.h
+++ b/bfd/coffcode.h
@@ -795,6 +795,12 @@ styp_to_sec_flags (bfd *abfd ATTRIBUTE_UNUSED,
else if (styp_flags & STYP_PAD)
sec_flags = 0;
#ifdef RS6000COFF_C
+ else if (styp_flags & STYP_EXCEPT)
+ sec_flags |= SEC_LOAD;
+ else if (styp_flags & STYP_LOADER)
+ sec_flags |= SEC_LOAD;
+ else if (styp_flags & STYP_TYPCHK)
+ sec_flags |= SEC_LOAD;
else if (styp_flags & STYP_DWARF)
sec_flags |= SEC_DEBUGGING;
#endif
diff --git a/bfd/config.bfd b/bfd/config.bfd
index 228e7c1a5..ebc9d40a8 100644
--- a/bfd/config.bfd
+++ b/bfd/config.bfd
@@ -202,7 +202,7 @@ case "${targ}" in
targ_selvecs=nlm32_alpha_vec
want64=true
;;
- alpha*-*-linuxecoff*)
+ alpha*-*-linux*ecoff*)
targ_defvec=ecoffalpha_little_vec
targ_selvecs=bfd_elf64_alpha_vec
want64=true
@@ -1134,6 +1134,7 @@ case "${targ}" in
msp430-*-*)
targ_defvec=bfd_elf32_msp430_vec
+ targ_selvecs=bfd_elf32_msp430_ti_vec
;;
ns32k-pc532-mach* | ns32k-pc532-ux*)
diff --git a/bfd/configure b/bfd/configure
index 24f6fd3d4..5fc08e4fe 100755
--- a/bfd/configure
+++ b/bfd/configure
@@ -15292,6 +15292,7 @@ do
bfd_elf32_mn10300_vec) tb="$tb elf-m10300.lo elf32.lo $elf" ;;
bfd_elf32_mt_vec) tb="$tb elf32-mt.lo elf32.lo $elf" ;;
bfd_elf32_msp430_vec) tb="$tb elf32-msp430.lo elf32.lo $elf" ;;
+ bfd_elf32_msp430_ti_vec) tb="$tb elf32-msp430.lo elf32.lo $elf" ;;
bfd_elf32_nbigmips_vec) tb="$tb elfn32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
bfd_elf32_nlittlemips_vec) tb="$tb elfn32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
bfd_elf32_ntradbigmips_vec | bfd_elf32_ntradbigmips_freebsd_vec)
diff --git a/bfd/configure.in b/bfd/configure.in
index d9bef830c..befcf2709 100644
--- a/bfd/configure.in
+++ b/bfd/configure.in
@@ -1,6 +1,6 @@
dnl Process this file with autoconf to produce a configure script.
dnl
-dnl Copyright 2012 Free Software Foundation
+dnl Copyright 2012-2013 Free Software Foundation
dnl
dnl This file is free software; you can redistribute it and/or modify
dnl it under the terms of the GNU General Public License as published by
@@ -789,6 +789,7 @@ do
bfd_elf32_mn10300_vec) tb="$tb elf-m10300.lo elf32.lo $elf" ;;
bfd_elf32_mt_vec) tb="$tb elf32-mt.lo elf32.lo $elf" ;;
bfd_elf32_msp430_vec) tb="$tb elf32-msp430.lo elf32.lo $elf" ;;
+ bfd_elf32_msp430_ti_vec) tb="$tb elf32-msp430.lo elf32.lo $elf" ;;
bfd_elf32_nbigmips_vec) tb="$tb elfn32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
bfd_elf32_nlittlemips_vec) tb="$tb elfn32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
bfd_elf32_ntradbigmips_vec | bfd_elf32_ntradbigmips_freebsd_vec)
diff --git a/bfd/cpu-msp430.c b/bfd/cpu-msp430.c
index 09c0e54f0..73b6e664d 100644
--- a/bfd/cpu-msp430.c
+++ b/bfd/cpu-msp430.c
@@ -1,6 +1,5 @@
/* BFD library support routines for the MSP architecture.
- Copyright (C) 2002, 2003, 2005, 2007, 2012
- Free Software Foundation, Inc.
+ Copyright (C) 2002-2013 Free Software Foundation, Inc.
Contributed by Dmitry Diky <diwil@mail.ru>
This file is part of BFD, the Binary File Descriptor library.
@@ -82,29 +81,56 @@ static const bfd_arch_info_type arch_info_struct[] =
/* msp430x16x. */
N (16, bfd_mach_msp16, "msp:16", FALSE, & arch_info_struct[7]),
+ /* msp430x20x. */
+ N (16, bfd_mach_msp20, "msp:20", FALSE, & arch_info_struct[8]),
+
/* msp430x21x. */
- N (16, bfd_mach_msp21, "msp:21", FALSE, & arch_info_struct[8]),
+ N (16, bfd_mach_msp21, "msp:21", FALSE, & arch_info_struct[9]),
+
+ /* msp430x22x. */
+ N (16, bfd_mach_msp22, "msp:22", FALSE, & arch_info_struct[10]),
+
+ /* msp430x23x. */
+ N (16, bfd_mach_msp23, "msp:23", FALSE, & arch_info_struct[11]),
+
+ /* msp430x24x. */
+ N (16, bfd_mach_msp24, "msp:24", FALSE, & arch_info_struct[12]),
+
+ /* msp430x26x. */
+ N (16, bfd_mach_msp26, "msp:26", FALSE, & arch_info_struct[13]),
/* msp430x31x. */
- N (16, bfd_mach_msp31, "msp:31", FALSE, & arch_info_struct[9]),
+ N (16, bfd_mach_msp31, "msp:31", FALSE, & arch_info_struct[14]),
/* msp430x32x. */
- N (16, bfd_mach_msp32, "msp:32", FALSE, & arch_info_struct[10]),
+ N (16, bfd_mach_msp32, "msp:32", FALSE, & arch_info_struct[15]),
/* msp430x33x. */
- N (16, bfd_mach_msp33, "msp:33", FALSE, & arch_info_struct[11]),
+ N (16, bfd_mach_msp33, "msp:33", FALSE, & arch_info_struct[16]),
/* msp430x41x. */
- N (16, bfd_mach_msp41, "msp:41", FALSE, & arch_info_struct[12]),
+ N (16, bfd_mach_msp41, "msp:41", FALSE, & arch_info_struct[17]),
/* msp430x42x. */
- N (16, bfd_mach_msp42, "msp:42", FALSE, & arch_info_struct[13]),
+ N (16, bfd_mach_msp42, "msp:42", FALSE, & arch_info_struct[18]),
/* msp430x43x. */
- N (16, bfd_mach_msp43, "msp:43", FALSE, & arch_info_struct[14]),
+ N (16, bfd_mach_msp43, "msp:43", FALSE, & arch_info_struct[19]),
/* msp430x44x. */
- N (16, bfd_mach_msp43, "msp:44", FALSE, NULL)
+ N (16, bfd_mach_msp43, "msp:44", FALSE, & arch_info_struct[20]),
+
+ /* msp430x46x. */
+ N (16, bfd_mach_msp46, "msp:46", FALSE, & arch_info_struct[21]),
+
+ /* msp430x47x. */
+ N (16, bfd_mach_msp47, "msp:47", FALSE, & arch_info_struct[22]),
+
+ /* msp430x54x. */
+ N (16, bfd_mach_msp54, "msp:54", FALSE, & arch_info_struct[23]),
+
+ N (32, bfd_mach_msp430x, "msp:430X", FALSE, NULL)
+
};
const bfd_arch_info_type bfd_msp430_arch =
diff --git a/bfd/ecoff.c b/bfd/ecoff.c
index 5add50cf5..7bfb333f1 100644
--- a/bfd/ecoff.c
+++ b/bfd/ecoff.c
@@ -3561,9 +3561,9 @@ ecoff_link_check_archive_element (bfd *abfd,
void (* const swap_ext_in) (bfd *, void *, EXTR *)
= backend->debug_swap.swap_ext_in;
HDRR *symhdr;
- bfd_size_type external_ext_size;
+ bfd_size_type external_ext_size = 0;
void * external_ext = NULL;
- bfd_size_type esize;
+ bfd_size_type esize = 0;
char *ssext = NULL;
char *ext_ptr;
char *ext_end;
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index b643dbc8a..4a67d0219 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -2378,12 +2378,9 @@ struct elf_dyn_relocs
extern bfd_boolean _bfd_elf_create_ifunc_sections
(bfd *, struct bfd_link_info *);
-extern asection * _bfd_elf_create_ifunc_dyn_reloc
- (bfd *, struct bfd_link_info *, asection *sec, asection *sreloc,
- struct elf_dyn_relocs **);
extern bfd_boolean _bfd_elf_allocate_ifunc_dyn_relocs
(struct bfd_link_info *, struct elf_link_hash_entry *,
- struct elf_dyn_relocs **, unsigned int, unsigned int);
+ struct elf_dyn_relocs **, unsigned int, unsigned int, unsigned int);
extern void elf_append_rela (bfd *, asection *, Elf_Internal_Rela *);
extern void elf_append_rel (bfd *, asection *, Elf_Internal_Rela *);
diff --git a/bfd/elf-ifunc.c b/bfd/elf-ifunc.c
index c2fa163a5..8d48e66ee 100644
--- a/bfd/elf-ifunc.c
+++ b/bfd/elf-ifunc.c
@@ -104,51 +104,6 @@ _bfd_elf_create_ifunc_sections (bfd *abfd, struct bfd_link_info *info)
return TRUE;
}
-/* For a STT_GNU_IFUNC symbol, create a dynamic reloc section, SRELOC,
- for the input section, SEC, and append this reloc to HEAD. */
-
-asection *
-_bfd_elf_create_ifunc_dyn_reloc (bfd *abfd, struct bfd_link_info *info,
- asection *sec, asection *sreloc,
- struct elf_dyn_relocs **head)
-{
- struct elf_dyn_relocs *p;
- struct elf_link_hash_table *htab = elf_hash_table (info);
-
- if (sreloc == NULL)
- {
- const struct elf_backend_data *bed = get_elf_backend_data (abfd);
-
- if (htab->dynobj == NULL)
- htab->dynobj = abfd;
-
- sreloc = _bfd_elf_make_dynamic_reloc_section (sec, htab->dynobj,
- bed->s->log_file_align,
- abfd,
- bed->rela_plts_and_copies_p);
- if (sreloc == NULL)
- return NULL;
- }
-
- p = *head;
- if (p == NULL || p->sec != sec)
- {
- bfd_size_type amt = sizeof *p;
-
- p = ((struct elf_dyn_relocs *) bfd_alloc (htab->dynobj, amt));
- if (p == NULL)
- return NULL;
- p->next = *head;
- *head = p;
- p->sec = sec;
- p->count = 0;
- p->pc_count = 0;
- }
- p->count += 1;
-
- return sreloc;
-}
-
/* Allocate space in .plt, .got and associated reloc sections for
dynamic relocs against a STT_GNU_IFUNC symbol definition. */
@@ -157,6 +112,7 @@ _bfd_elf_allocate_ifunc_dyn_relocs (struct bfd_link_info *info,
struct elf_link_hash_entry *h,
struct elf_dyn_relocs **head,
unsigned int plt_entry_size,
+ unsigned int plt_header_size,
unsigned int got_entry_size)
{
asection *plt, *gotplt, *relplt;
@@ -238,7 +194,7 @@ keep:
/* If this is the first .plt entry, make room for the special
first entry. */
if (plt->size == 0)
- plt->size += plt_entry_size;
+ plt->size += plt_header_size;
}
else
{
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index 2609130d8..cc8b48efe 100644
--- a/bfd/elf32-i386.c
+++ b/bfd/elf32-i386.c
@@ -2197,7 +2197,8 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
if (h->type == STT_GNU_IFUNC
&& h->def_regular)
return _bfd_elf_allocate_ifunc_dyn_relocs (info, h, &eh->dyn_relocs,
- plt_entry_size, 4);
+ plt_entry_size,
+ plt_entry_size, 4);
else if (htab->elf.dynamic_sections_created
&& h->plt.refcount > 0)
{
diff --git a/bfd/elf32-mips.c b/bfd/elf32-mips.c
index cb7692bf0..54ae641c2 100644
--- a/bfd/elf32-mips.c
+++ b/bfd/elf32-mips.c
@@ -1515,7 +1515,7 @@ static reloc_howto_type elf_mips_copy_howto =
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
- bfd_elf_generic_reloc, /* special_function */
+ _bfd_mips_elf_generic_reloc, /* special_function */
"R_MIPS_COPY", /* name */
FALSE, /* partial_inplace */
0x0, /* src_mask */
@@ -1531,7 +1531,7 @@ static reloc_howto_type elf_mips_jump_slot_howto =
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
- bfd_elf_generic_reloc, /* special_function */
+ _bfd_mips_elf_generic_reloc, /* special_function */
"R_MIPS_JUMP_SLOT", /* name */
FALSE, /* partial_inplace */
0x0, /* src_mask */
diff --git a/bfd/elf32-msp430.c b/bfd/elf32-msp430.c
index b46e72ce0..6f6628248 100644
--- a/bfd/elf32-msp430.c
+++ b/bfd/elf32-msp430.c
@@ -1,6 +1,5 @@
/* MSP430-specific support for 32-bit ELF
- Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2010, 2012
- Free Software Foundation, Inc.
+ Copyright (C) 2002-2013 Free Software Foundation, Inc.
Contributed by Dmitry Diky <diwil@mail.ru>
This file is part of BFD, the Binary File Descriptor library.
@@ -27,9 +26,6 @@
#include "elf-bfd.h"
#include "elf/msp430.h"
-/* Use RELA instead of REL. */
-#undef USE_REL
-
static reloc_howto_type elf_msp430_howto_table[] =
{
HOWTO (R_MSP430_NONE, /* type */
@@ -69,7 +65,7 @@ static reloc_howto_type elf_msp430_howto_table[] =
0, /* bitpos */
complain_overflow_bitfield,/* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
- "R_MSP430_13_PCREL", /* name */
+ "R_MSP430_10_PCREL", /* name */
FALSE, /* partial_inplace */
0xfff, /* src_mask */
0xfff, /* dst_mask */
@@ -90,7 +86,7 @@ static reloc_howto_type elf_msp430_howto_table[] =
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
- /* A 16 bit absolute relocation for command address. */
+ /* A 16 bit PC relative relocation for command address. */
HOWTO (R_MSP430_16_PCREL, /* type */
1, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
@@ -164,6 +160,340 @@ static reloc_howto_type elf_msp430_howto_table[] =
0, /* src_mask */
0xffff, /* dst_mask */
TRUE) /* pcrel_offset */
+
+ /* A 8-bit absolute relocation. */
+ , HOWTO (R_MSP430_8, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MSP430_8", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Together with a following reloc, allows for the difference
+ between two symbols to be the real addend of the second reloc. */
+ HOWTO (R_MSP430_SYM_DIFF, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ NULL, /* special handler. */
+ "R_MSP430_SYM_DIFF", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE) /* pcrel_offset */
+};
+
+static reloc_howto_type elf_msp430x_howto_table[] =
+{
+ HOWTO (R_MSP430_NONE, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MSP430_NONE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_MSP430_ABS32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MSP430_ABS32", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_MSP430_ABS16, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MSP430_ABS16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_MSP430_ABS8, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MSP430_ABS8", /* name */
+ FALSE, /* partial_inplace */
+ 0xff, /* src_mask */
+ 0xff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_MSP430_PCR16, /* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MSP430_PCR16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MSP430X_PCR20_EXT_SRC,/* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MSP430X_PCR20_EXT_SRC",/* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MSP430X_PCR20_EXT_DST,/* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MSP430X_PCR20_EXT_DST",/* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MSP430X_PCR20_EXT_ODST,/* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MSP430X_PCR20_EXT_ODST",/* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MSP430X_ABS20_EXT_SRC,/* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MSP430X_ABS20_EXT_SRC",/* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MSP430X_ABS20_EXT_DST,/* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MSP430X_ABS20_EXT_DST",/* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MSP430X_ABS20_EXT_ODST,/* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MSP430X_ABS20_EXT_ODST",/* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MSP430X_ABS20_ADR_SRC,/* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MSP430X_ABS20_ADR_SRC",/* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MSP430X_ABS20_ADR_DST,/* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MSP430X_ABS20_ADR_DST",/* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MSP430X_PCR16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MSP430X_PCR16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MSP430X_PCR20_CALL, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MSP430X_PCR20_CALL",/* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MSP430X_ABS16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MSP430X_ABS16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MSP430_ABS_HI16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MSP430_ABS_HI16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MSP430_PREL31, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MSP430_PREL31", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ EMPTY_HOWTO (R_MSP430_EHTYPE),
+
+ /* A 13 bit PC relative relocation. */
+ HOWTO (R_MSP430X_10_PCREL, /* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 10, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MSP430X_10_PCREL", /* name */
+ FALSE, /* partial_inplace */
+ 0xfff, /* src_mask */
+ 0xfff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* A 13 bit PC relative relocation for complicated polymorphs. */
+ HOWTO (R_MSP430X_2X_PCREL, /* type */
+ 1, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 10, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MSP430X_2X_PCREL", /* name */
+ FALSE, /* partial_inplace */
+ 0xfff, /* src_mask */
+ 0xfff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* Together with a following reloc, allows for the difference
+ between two symbols to be the real addend of the second reloc. */
+ HOWTO (R_MSP430X_SYM_DIFF, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ NULL, /* special handler. */
+ "R_MSP430X_SYM_DIFF", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE) /* pcrel_offset */
};
/* Map BFD reloc types to MSP430 ELF reloc types. */
@@ -175,18 +505,55 @@ struct msp430_reloc_map
};
static const struct msp430_reloc_map msp430_reloc_map[] =
- {
- {BFD_RELOC_NONE, R_MSP430_NONE},
- {BFD_RELOC_32, R_MSP430_32},
- {BFD_RELOC_MSP430_10_PCREL, R_MSP430_10_PCREL},
- {BFD_RELOC_16, R_MSP430_16_BYTE},
- {BFD_RELOC_MSP430_16_PCREL, R_MSP430_16_PCREL},
- {BFD_RELOC_MSP430_16, R_MSP430_16},
- {BFD_RELOC_MSP430_16_PCREL_BYTE, R_MSP430_16_PCREL_BYTE},
- {BFD_RELOC_MSP430_16_BYTE, R_MSP430_16_BYTE},
- {BFD_RELOC_MSP430_2X_PCREL, R_MSP430_2X_PCREL},
- {BFD_RELOC_MSP430_RL_PCREL, R_MSP430_RL_PCREL}
- };
+{
+ {BFD_RELOC_NONE, R_MSP430_NONE},
+ {BFD_RELOC_32, R_MSP430_32},
+ {BFD_RELOC_MSP430_10_PCREL, R_MSP430_10_PCREL},
+ {BFD_RELOC_16, R_MSP430_16_BYTE},
+ {BFD_RELOC_MSP430_16_PCREL, R_MSP430_16_PCREL},
+ {BFD_RELOC_MSP430_16, R_MSP430_16},
+ {BFD_RELOC_MSP430_16_PCREL_BYTE, R_MSP430_16_PCREL_BYTE},
+ {BFD_RELOC_MSP430_16_BYTE, R_MSP430_16_BYTE},
+ {BFD_RELOC_MSP430_2X_PCREL, R_MSP430_2X_PCREL},
+ {BFD_RELOC_MSP430_RL_PCREL, R_MSP430_RL_PCREL},
+ {BFD_RELOC_8, R_MSP430_8},
+ {BFD_RELOC_MSP430_SYM_DIFF, R_MSP430_SYM_DIFF}
+};
+
+static const struct msp430_reloc_map msp430x_reloc_map[] =
+{
+ {BFD_RELOC_NONE, R_MSP430_NONE},
+ {BFD_RELOC_32, R_MSP430_ABS32},
+ {BFD_RELOC_16, R_MSP430_ABS16},
+ {BFD_RELOC_8, R_MSP430_ABS8},
+ {BFD_RELOC_MSP430_ABS8, R_MSP430_ABS8},
+ {BFD_RELOC_MSP430X_PCR20_EXT_SRC, R_MSP430X_PCR20_EXT_SRC},
+ {BFD_RELOC_MSP430X_PCR20_EXT_DST, R_MSP430X_PCR20_EXT_DST},
+ {BFD_RELOC_MSP430X_PCR20_EXT_ODST, R_MSP430X_PCR20_EXT_ODST},
+ {BFD_RELOC_MSP430X_ABS20_EXT_SRC, R_MSP430X_ABS20_EXT_SRC},
+ {BFD_RELOC_MSP430X_ABS20_EXT_DST, R_MSP430X_ABS20_EXT_DST},
+ {BFD_RELOC_MSP430X_ABS20_EXT_ODST, R_MSP430X_ABS20_EXT_ODST},
+ {BFD_RELOC_MSP430X_ABS20_ADR_SRC, R_MSP430X_ABS20_ADR_SRC},
+ {BFD_RELOC_MSP430X_ABS20_ADR_DST, R_MSP430X_ABS20_ADR_DST},
+ {BFD_RELOC_MSP430X_PCR16, R_MSP430X_PCR16},
+ {BFD_RELOC_MSP430X_PCR20_CALL, R_MSP430X_PCR20_CALL},
+ {BFD_RELOC_MSP430X_ABS16, R_MSP430X_ABS16},
+ {BFD_RELOC_MSP430_ABS_HI16, R_MSP430_ABS_HI16},
+ {BFD_RELOC_MSP430_PREL31, R_MSP430_PREL31},
+ {BFD_RELOC_MSP430_10_PCREL, R_MSP430X_10_PCREL},
+ {BFD_RELOC_MSP430_2X_PCREL, R_MSP430X_2X_PCREL},
+ {BFD_RELOC_MSP430_RL_PCREL, R_MSP430X_PCR16},
+ {BFD_RELOC_MSP430_SYM_DIFF, R_MSP430X_SYM_DIFF}
+};
+
+static inline bfd_boolean
+uses_msp430x_relocs (bfd * abfd)
+{
+ extern const bfd_target bfd_elf32_msp430_ti_vec;
+
+ return bfd_get_mach (abfd) == bfd_mach_msp430x
+ || abfd->xvec == & bfd_elf32_msp430_ti_vec;
+}
static reloc_howto_type *
bfd_elf32_bfd_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
@@ -194,9 +561,18 @@ bfd_elf32_bfd_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
{
unsigned int i;
- for (i = 0; i < ARRAY_SIZE (msp430_reloc_map); i++)
- if (msp430_reloc_map[i].bfd_reloc_val == code)
- return &elf_msp430_howto_table[msp430_reloc_map[i].elf_reloc_val];
+ if (uses_msp430x_relocs (abfd))
+ {
+ for (i = ARRAY_SIZE (msp430x_reloc_map); i--;)
+ if (msp430x_reloc_map[i].bfd_reloc_val == code)
+ return elf_msp430x_howto_table + msp430x_reloc_map[i].elf_reloc_val;
+ }
+ else
+ {
+ for (i = 0; i < ARRAY_SIZE (msp430_reloc_map); i++)
+ if (msp430_reloc_map[i].bfd_reloc_val == code)
+ return &elf_msp430_howto_table[msp430_reloc_map[i].elf_reloc_val];
+ }
return NULL;
}
@@ -207,13 +583,23 @@ bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
{
unsigned int i;
- for (i = 0;
- i < (sizeof (elf_msp430_howto_table)
- / sizeof (elf_msp430_howto_table[0]));
- i++)
- if (elf_msp430_howto_table[i].name != NULL
- && strcasecmp (elf_msp430_howto_table[i].name, r_name) == 0)
- return &elf_msp430_howto_table[i];
+ if (uses_msp430x_relocs (abfd))
+ {
+ for (i = ARRAY_SIZE (elf_msp430x_howto_table); i--;)
+ if (elf_msp430x_howto_table[i].name != NULL
+ && strcasecmp (elf_msp430x_howto_table[i].name, r_name) == 0)
+ return elf_msp430x_howto_table + i;
+ }
+ else
+ {
+ for (i = 0;
+ i < (sizeof (elf_msp430_howto_table)
+ / sizeof (elf_msp430_howto_table[0]));
+ i++)
+ if (elf_msp430_howto_table[i].name != NULL
+ && strcasecmp (elf_msp430_howto_table[i].name, r_name) == 0)
+ return &elf_msp430_howto_table[i];
+ }
return NULL;
}
@@ -228,6 +614,14 @@ msp430_info_to_howto_rela (bfd * abfd ATTRIBUTE_UNUSED,
unsigned int r_type;
r_type = ELF32_R_TYPE (dst->r_info);
+
+ if (uses_msp430x_relocs (abfd))
+ {
+ BFD_ASSERT (r_type < (unsigned int) R_MSP430x_max);
+ cache_ptr->howto = elf_msp430x_howto_table + r_type;
+ return;
+ }
+
BFD_ASSERT (r_type < (unsigned int) R_MSP430_max);
cache_ptr->howto = &elf_msp430_howto_table[r_type];
}
@@ -280,16 +674,413 @@ elf32_msp430_check_relocs (bfd * abfd, struct bfd_link_info * info,
routines, but a few relocs, we have to do them ourselves. */
static bfd_reloc_status_type
-msp430_final_link_relocate (reloc_howto_type * howto, bfd * input_bfd,
- asection * input_section, bfd_byte * contents,
- Elf_Internal_Rela * rel, bfd_vma relocation)
+msp430_final_link_relocate (reloc_howto_type * howto,
+ bfd * input_bfd,
+ asection * input_section,
+ bfd_byte * contents,
+ Elf_Internal_Rela * rel,
+ bfd_vma relocation,
+ struct bfd_link_info * info)
{
+ static asection * sym_diff_section;
+ static bfd_vma sym_diff_value;
+
+ struct bfd_elf_section_data * esd = elf_section_data (input_section);
bfd_reloc_status_type r = bfd_reloc_ok;
bfd_vma x;
bfd_signed_vma srel;
+ bfd_boolean is_rel_reloc = FALSE;
- switch (howto->type)
+ if (uses_msp430x_relocs (input_bfd))
{
+ /* See if we have a REL type relocation. */
+ is_rel_reloc = (esd->rel.hdr != NULL);
+ /* Sanity check - only one type of relocation per section.
+ FIXME: Theoretically it is possible to have both types,
+ but if that happens how can we distinguish between the two ? */
+ BFD_ASSERT (! is_rel_reloc || ! esd->rela.hdr);
+ /* If we are using a REL relocation then the addend should be empty. */
+ BFD_ASSERT (! is_rel_reloc || rel->r_addend == 0);
+ }
+
+ if (sym_diff_section != NULL)
+ {
+ BFD_ASSERT (sym_diff_section == input_section);
+
+ if (uses_msp430x_relocs (input_bfd))
+ switch (howto->type)
+ {
+ case R_MSP430_ABS32:
+ /* If we are computing a 32-bit value for the location lists
+ and the result is 0 then we add one to the value. A zero
+ value can result because of linker relaxation deleteing
+ prologue instructions and using a value of 1 (for the begin
+ and end offsets in the location list entry) results in a
+ nul entry which does not prevent the following entries from
+ being parsed. */
+ if (relocation == sym_diff_value
+ && strcmp (input_section->name, ".debug_loc") == 0)
+ ++ relocation;
+ /* Fall through. */
+ case R_MSP430_ABS16:
+ case R_MSP430X_ABS16:
+ case R_MSP430_ABS8:
+ BFD_ASSERT (! is_rel_reloc);
+ relocation -= sym_diff_value;
+ break;
+
+ default:
+ return bfd_reloc_dangerous;
+ }
+ else
+ switch (howto->type)
+ {
+ case R_MSP430_32:
+ case R_MSP430_16:
+ case R_MSP430_16_BYTE:
+ case R_MSP430_8:
+ relocation -= sym_diff_value;
+ break;
+
+ default:
+ return bfd_reloc_dangerous;
+ }
+
+ sym_diff_section = NULL;
+ }
+
+ if (uses_msp430x_relocs (input_bfd))
+ switch (howto->type)
+ {
+ case R_MSP430X_SYM_DIFF:
+ /* Cache the input section and value.
+ The offset is unreliable, since relaxation may
+ have reduced the following reloc's offset. */
+ BFD_ASSERT (! is_rel_reloc);
+ sym_diff_section = input_section;
+ sym_diff_value = relocation;
+ return bfd_reloc_ok;
+
+ case R_MSP430_ABS16:
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation;
+ if (is_rel_reloc)
+ srel += bfd_get_16 (input_bfd, contents);
+ else
+ srel += rel->r_addend;
+ bfd_put_16 (input_bfd, srel & 0xffff, contents);
+ break;
+
+ case R_MSP430X_10_PCREL:
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation;
+ if (is_rel_reloc)
+ srel += bfd_get_16 (input_bfd, contents) & 0x3ff;
+ else
+ srel += rel->r_addend;
+ srel -= rel->r_offset;
+ srel -= 2; /* Branch instructions add 2 to the PC... */
+ srel -= (input_section->output_section->vma +
+ input_section->output_offset);
+ if (srel & 1)
+ return bfd_reloc_outofrange;
+
+ /* MSP430 addresses commands as words. */
+ srel >>= 1;
+
+ /* Check for an overflow. */
+ if (srel < -512 || srel > 511)
+ {
+ if (info->disable_target_specific_optimizations < 0)
+ {
+ static bfd_boolean warned = FALSE;
+ if (! warned)
+ {
+ info->callbacks->warning
+ (info,
+ _("Try enabling relaxation to avoid relocation truncations"),
+ NULL, input_bfd, input_section, relocation);
+ warned = TRUE;
+ }
+ }
+ return bfd_reloc_overflow;
+ }
+
+ x = bfd_get_16 (input_bfd, contents);
+ x = (x & 0xfc00) | (srel & 0x3ff);
+ bfd_put_16 (input_bfd, x, contents);
+ break;
+
+ case R_MSP430X_PCR20_EXT_ODST:
+ /* [0,4]+[48,16] = ---F ---- FFFF */
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation;
+ if (is_rel_reloc)
+ {
+ bfd_vma addend;
+ addend = (bfd_get_16 (input_bfd, contents) & 0xf) << 16;
+ addend |= bfd_get_16 (input_bfd, contents+4);
+ srel += addend;
+
+ }
+ else
+ srel += rel->r_addend;
+ srel -= rel->r_offset;
+ srel -= (input_section->output_section->vma +
+ input_section->output_offset);
+ bfd_put_16 (input_bfd, (srel & 0xffff), contents + 6);
+ x = bfd_get_16 (input_bfd, contents);
+ x = (x & 0xfff0) | ((srel >> 16) & 0xf);
+ bfd_put_16 (input_bfd, x, contents);
+ break;
+
+ case R_MSP430X_ABS20_EXT_SRC:
+ /* [7,4]+[32,16] = -78- FFFF */
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation;
+ if (is_rel_reloc)
+ {
+ bfd_vma addend;
+ addend = (bfd_get_16 (input_bfd, contents) & 0x0780) << 9;
+ addend |= bfd_get_16 (input_bfd, contents+2);
+ srel += addend;
+ }
+ else
+ srel += rel->r_addend;
+ bfd_put_16 (input_bfd, (srel & 0xffff), contents + 4);
+ srel >>= 16;
+ x = bfd_get_16 (input_bfd, contents);
+ x = (x & 0xf87f) | ((srel << 7) & 0x0780);
+ bfd_put_16 (input_bfd, x, contents);
+ break;
+
+ case R_MSP430_16_PCREL:
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation;
+ if (is_rel_reloc)
+ srel += bfd_get_16 (input_bfd, contents);
+ else
+ srel += rel->r_addend;
+ srel -= rel->r_offset;
+ /* Only branch instructions add 2 to the PC... */
+ srel -= (input_section->output_section->vma +
+ input_section->output_offset);
+ if (srel & 1)
+ return bfd_reloc_outofrange;
+ bfd_put_16 (input_bfd, srel & 0xffff, contents);
+ break;
+
+ case R_MSP430X_PCR20_EXT_DST:
+ /* [0,4]+[32,16] = ---F FFFF */
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation;
+ if (is_rel_reloc)
+ {
+ bfd_vma addend;
+ addend = (bfd_get_16 (input_bfd, contents) & 0xf) << 16;
+ addend |= bfd_get_16 (input_bfd, contents+2);
+ srel += addend;
+ }
+ else
+ srel += rel->r_addend;
+ srel -= rel->r_offset;
+ srel -= (input_section->output_section->vma +
+ input_section->output_offset);
+ bfd_put_16 (input_bfd, (srel & 0xffff), contents + 4);
+ srel >>= 16;
+ x = bfd_get_16 (input_bfd, contents);
+ x = (x & 0xfff0) | (srel & 0xf);
+ bfd_put_16 (input_bfd, x, contents);
+ break;
+
+ case R_MSP430X_PCR20_EXT_SRC:
+ /* [7,4]+32,16] = -78- FFFF */
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation;
+ if (is_rel_reloc)
+ {
+ bfd_vma addend;
+ addend = ((bfd_get_16 (input_bfd, contents) & 0x0780) << 9);
+ addend |= bfd_get_16 (input_bfd, contents+2);
+ srel += addend;;
+ }
+ else
+ srel += rel->r_addend;
+ srel -= rel->r_offset;
+ /* Only branch instructions add 2 to the PC... */
+ srel -= (input_section->output_section->vma +
+ input_section->output_offset);
+ bfd_put_16 (input_bfd, (srel & 0xffff), contents + 4);
+ srel >>= 16;
+ x = bfd_get_16 (input_bfd, contents);
+ x = (x & 0xf87f) | ((srel << 7) & 0x0780);
+ bfd_put_16 (input_bfd, x, contents);
+ break;
+
+ case R_MSP430_ABS8:
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation;
+ if (is_rel_reloc)
+ srel += bfd_get_8 (input_bfd, contents);
+ else
+ srel += rel->r_addend;
+ bfd_put_8 (input_bfd, srel & 0xff, contents);
+ break;
+
+ case R_MSP430X_ABS20_EXT_DST:
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation;
+ if (is_rel_reloc)
+ srel += bfd_get_16 (input_bfd, contents) & 0xf;
+ else
+ srel += rel->r_addend;
+ bfd_put_16 (input_bfd, (srel & 0xffff), contents + 4);
+ srel >>= 16;
+ x = bfd_get_16 (input_bfd, contents);
+ x = (x & 0xfff0) | (srel & 0xf);
+ bfd_put_16 (input_bfd, x, contents);
+ break;
+
+ case R_MSP430X_ABS20_EXT_ODST:
+ /* [0,4]+[48,16] = ---F ---- FFFF */
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation;
+ if (is_rel_reloc)
+ {
+ bfd_vma addend;
+ addend = (bfd_get_16 (input_bfd, contents) & 0xf) << 16;
+ addend |= bfd_get_16 (input_bfd, contents+4);
+ srel += addend;
+ }
+ else
+ srel += rel->r_addend;
+ bfd_put_16 (input_bfd, (srel & 0xffff), contents + 6);
+ srel >>= 16;
+ x = bfd_get_16 (input_bfd, contents);
+ x = (x & 0xfff0) | (srel & 0xf);
+ bfd_put_16 (input_bfd, x, contents);
+ break;
+
+ case R_MSP430X_ABS20_ADR_SRC:
+ /* [8,4]+[32,16] = -F-- FFFF */
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation;
+ if (is_rel_reloc)
+ {
+ bfd_vma addend;
+
+ addend = ((bfd_get_16 (input_bfd, contents) & 0xf00) << 8);
+ addend |= bfd_get_16 (input_bfd, contents+2);
+ srel += addend;
+ }
+ else
+ srel += rel->r_addend;
+ bfd_put_16 (input_bfd, (srel & 0xffff), contents + 2);
+ srel >>= 16;
+ x = bfd_get_16 (input_bfd, contents);
+ x = (x & 0xf0ff) | ((srel << 8) & 0x0f00);
+ bfd_put_16 (input_bfd, x, contents);
+ break;
+
+ case R_MSP430X_ABS20_ADR_DST:
+ /* [0,4]+[32,16] = ---F FFFF */
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation;
+ if (is_rel_reloc)
+ {
+ bfd_vma addend;
+ addend = ((bfd_get_16 (input_bfd, contents) & 0xf) << 16);
+ addend |= bfd_get_16 (input_bfd, contents+2);
+ srel += addend;
+ }
+ else
+ srel += rel->r_addend;
+ bfd_put_16 (input_bfd, (srel & 0xffff), contents + 2);
+ srel >>= 16;
+ x = bfd_get_16 (input_bfd, contents);
+ x = (x & 0xfff0) | (srel & 0xf);
+ bfd_put_16 (input_bfd, x, contents);
+ break;
+
+ case R_MSP430X_ABS16:
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation;
+ if (is_rel_reloc)
+ srel += bfd_get_16 (input_bfd, contents);
+ else
+ srel += rel->r_addend;
+ x = srel;
+ if (x > 0xffff)
+ return bfd_reloc_overflow;
+ bfd_put_16 (input_bfd, srel & 0xffff, contents);
+ break;
+
+ case R_MSP430_ABS_HI16:
+ /* The EABI specifies that this must be a RELA reloc. */
+ BFD_ASSERT (! is_rel_reloc);
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation;
+ srel += rel->r_addend;
+ bfd_put_16 (input_bfd, (srel >> 16) & 0xffff, contents);
+ break;
+
+ case R_MSP430X_PCR20_CALL:
+ /* [0,4]+[32,16] = ---F FFFF*/
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation;
+ if (is_rel_reloc)
+ {
+ bfd_vma addend;
+ addend = (bfd_get_16 (input_bfd, contents) & 0xf) << 16;
+ addend |= bfd_get_16 (input_bfd, contents+2);
+ srel += addend;
+ }
+ else
+ srel += rel->r_addend;
+ srel -= rel->r_offset;
+ srel -= (input_section->output_section->vma +
+ input_section->output_offset);
+ bfd_put_16 (input_bfd, srel & 0xffff, contents + 2);
+ srel >>= 16;
+ x = bfd_get_16 (input_bfd, contents);
+ x = (x & 0xfff0) | (srel & 0xf);
+ bfd_put_16 (input_bfd, x, contents);
+ break;
+
+ case R_MSP430X_PCR16:
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation;
+ if (is_rel_reloc)
+ srel += bfd_get_16 (input_bfd, contents);
+ else
+ srel += rel->r_addend;
+ srel -= rel->r_offset;
+ srel -= (input_section->output_section->vma +
+ input_section->output_offset);
+ bfd_put_16 (input_bfd, srel & 0xffff, contents);
+ break;
+
+ case R_MSP430_PREL31:
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation;
+ if (is_rel_reloc)
+ srel += (bfd_get_32 (input_bfd, contents) & 0x7fffffff);
+ else
+ srel += rel->r_addend;
+ srel += rel->r_addend;
+ x = bfd_get_32 (input_bfd, contents);
+ x = (x & 0x80000000) | ((srel >> 31) & 0x7fffffff);
+ bfd_put_32 (input_bfd, x, contents);
+ break;
+
+ default:
+ r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset,
+ relocation, rel->r_addend);
+ }
+ else
+ switch (howto->type)
+ {
case R_MSP430_10_PCREL:
contents += rel->r_offset;
srel = (bfd_signed_vma) relocation;
@@ -307,8 +1098,22 @@ msp430_final_link_relocate (reloc_howto_type * howto, bfd * input_bfd,
/* Check for an overflow. */
if (srel < -512 || srel > 511)
- return bfd_reloc_overflow;
-
+ {
+ if (info->disable_target_specific_optimizations < 0)
+ {
+ static bfd_boolean warned = FALSE;
+ if (! warned)
+ {
+ info->callbacks->warning
+ (info,
+ _("Try enabling relaxation to avoid relocation truncations"),
+ NULL, input_bfd, input_section, relocation);
+ warned = TRUE;
+ }
+ }
+ return bfd_reloc_overflow;
+ }
+
x = bfd_get_16 (input_bfd, contents);
x = (x & 0xfc00) | (srel & 0x3ff);
bfd_put_16 (input_bfd, x, contents);
@@ -389,11 +1194,27 @@ msp430_final_link_relocate (reloc_howto_type * howto, bfd * input_bfd,
bfd_put_16 (input_bfd, srel & 0xffff, contents);
break;
- default:
- r = _bfd_final_link_relocate (howto, input_bfd, input_section,
- contents, rel->r_offset,
- relocation, rel->r_addend);
- }
+ case R_MSP430_8:
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation;
+ srel += rel->r_addend;
+
+ bfd_put_8 (input_bfd, srel & 0xff, contents);
+ break;
+
+ case R_MSP430_SYM_DIFF:
+ /* Cache the input section and value.
+ The offset is unreliable, since relaxation may
+ have reduced the following reloc's offset. */
+ sym_diff_section = input_section;
+ sym_diff_value = relocation;
+ return bfd_reloc_ok;
+
+ default:
+ r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset,
+ relocation, rel->r_addend);
+ }
return r;
}
@@ -433,7 +1254,12 @@ elf32_msp430_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED,
r_type = ELF32_R_TYPE (rel->r_info);
r_symndx = ELF32_R_SYM (rel->r_info);
- howto = elf_msp430_howto_table + r_type;
+
+ if (uses_msp430x_relocs (input_bfd))
+ howto = elf_msp430x_howto_table + r_type;
+ else
+ howto = elf_msp430_howto_table + r_type;
+
h = NULL;
sym = NULL;
sec = NULL;
@@ -446,7 +1272,7 @@ elf32_msp430_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED,
name = bfd_elf_string_from_elf_section
(input_bfd, symtab_hdr->sh_link, sym->st_name);
- name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
+ name = (name == NULL || * name == 0) ? bfd_section_name (input_bfd, sec) : name;
}
else
{
@@ -456,6 +1282,7 @@ elf32_msp430_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED,
r_symndx, symtab_hdr, sym_hashes,
h, sec, relocation,
unresolved_reloc, warned);
+ name = h->root.root.string;
}
if (sec != NULL && discarded_section (sec))
@@ -466,7 +1293,7 @@ elf32_msp430_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED,
continue;
r = msp430_final_link_relocate (howto, input_bfd, input_section,
- contents, rel, relocation);
+ contents, rel, relocation, info);
if (r != bfd_reloc_ok)
{
@@ -476,7 +1303,7 @@ elf32_msp430_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED,
{
case bfd_reloc_overflow:
r = info->callbacks->reloc_overflow
- (info, (h ? &h->root : NULL), name, howto->name,
+ (info, (h ? &h->root : NULL), name, howto->name,
(bfd_vma) 0, input_bfd, input_section,
rel->r_offset);
break;
@@ -487,7 +1314,7 @@ elf32_msp430_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED,
break;
case bfd_reloc_outofrange:
- msg = _("internal error: out of range error");
+ msg = _("internal error: branch/jump to an odd address detected");
break;
case bfd_reloc_notsupported:
@@ -529,61 +1356,29 @@ bfd_elf_msp430_final_write_processing (bfd * abfd,
switch (bfd_get_mach (abfd))
{
default:
- case bfd_mach_msp110:
- val = E_MSP430_MACH_MSP430x11x1;
- break;
-
- case bfd_mach_msp11:
- val = E_MSP430_MACH_MSP430x11;
- break;
-
- case bfd_mach_msp12:
- val = E_MSP430_MACH_MSP430x12;
- break;
-
- case bfd_mach_msp13:
- val = E_MSP430_MACH_MSP430x13;
- break;
-
- case bfd_mach_msp14:
- val = E_MSP430_MACH_MSP430x14;
- break;
-
- case bfd_mach_msp15:
- val = E_MSP430_MACH_MSP430x15;
- break;
-
- case bfd_mach_msp16:
- val = E_MSP430_MACH_MSP430x16;
- break;
-
- case bfd_mach_msp31:
- val = E_MSP430_MACH_MSP430x31;
- break;
-
- case bfd_mach_msp32:
- val = E_MSP430_MACH_MSP430x32;
- break;
-
- case bfd_mach_msp33:
- val = E_MSP430_MACH_MSP430x33;
- break;
-
- case bfd_mach_msp41:
- val = E_MSP430_MACH_MSP430x41;
- break;
-
- case bfd_mach_msp42:
- val = E_MSP430_MACH_MSP430x42;
- break;
-
- case bfd_mach_msp43:
- val = E_MSP430_MACH_MSP430x43;
- break;
-
- case bfd_mach_msp44:
- val = E_MSP430_MACH_MSP430x44;
- break;
+ case bfd_mach_msp110: val = E_MSP430_MACH_MSP430x11x1; break;
+ case bfd_mach_msp11: val = E_MSP430_MACH_MSP430x11; break;
+ case bfd_mach_msp12: val = E_MSP430_MACH_MSP430x12; break;
+ case bfd_mach_msp13: val = E_MSP430_MACH_MSP430x13; break;
+ case bfd_mach_msp14: val = E_MSP430_MACH_MSP430x14; break;
+ case bfd_mach_msp15: val = E_MSP430_MACH_MSP430x15; break;
+ case bfd_mach_msp16: val = E_MSP430_MACH_MSP430x16; break;
+ case bfd_mach_msp31: val = E_MSP430_MACH_MSP430x31; break;
+ case bfd_mach_msp32: val = E_MSP430_MACH_MSP430x32; break;
+ case bfd_mach_msp33: val = E_MSP430_MACH_MSP430x33; break;
+ case bfd_mach_msp41: val = E_MSP430_MACH_MSP430x41; break;
+ case bfd_mach_msp42: val = E_MSP430_MACH_MSP430x42; break;
+ case bfd_mach_msp43: val = E_MSP430_MACH_MSP430x43; break;
+ case bfd_mach_msp44: val = E_MSP430_MACH_MSP430x44; break;
+ case bfd_mach_msp20: val = E_MSP430_MACH_MSP430x20; break;
+ case bfd_mach_msp22: val = E_MSP430_MACH_MSP430x22; break;
+ case bfd_mach_msp23: val = E_MSP430_MACH_MSP430x23; break;
+ case bfd_mach_msp24: val = E_MSP430_MACH_MSP430x24; break;
+ case bfd_mach_msp26: val = E_MSP430_MACH_MSP430x26; break;
+ case bfd_mach_msp46: val = E_MSP430_MACH_MSP430x46; break;
+ case bfd_mach_msp47: val = E_MSP430_MACH_MSP430x47; break;
+ case bfd_mach_msp54: val = E_MSP430_MACH_MSP430x54; break;
+ case bfd_mach_msp430x: val = E_MSP430_MACH_MSP430X; break;
}
elf_elfheader (abfd)->e_machine = EM_MSP430;
@@ -606,64 +1401,32 @@ elf32_msp430_object_p (bfd * abfd)
switch (e_mach)
{
default:
- case E_MSP430_MACH_MSP430x11:
- e_set = bfd_mach_msp11;
- break;
-
- case E_MSP430_MACH_MSP430x11x1:
- e_set = bfd_mach_msp110;
- break;
-
- case E_MSP430_MACH_MSP430x12:
- e_set = bfd_mach_msp12;
- break;
-
- case E_MSP430_MACH_MSP430x13:
- e_set = bfd_mach_msp13;
- break;
-
- case E_MSP430_MACH_MSP430x14:
- e_set = bfd_mach_msp14;
- break;
-
- case E_MSP430_MACH_MSP430x15:
- e_set = bfd_mach_msp15;
- break;
-
- case E_MSP430_MACH_MSP430x16:
- e_set = bfd_mach_msp16;
- break;
-
- case E_MSP430_MACH_MSP430x31:
- e_set = bfd_mach_msp31;
- break;
-
- case E_MSP430_MACH_MSP430x32:
- e_set = bfd_mach_msp32;
- break;
-
- case E_MSP430_MACH_MSP430x33:
- e_set = bfd_mach_msp33;
- break;
-
- case E_MSP430_MACH_MSP430x41:
- e_set = bfd_mach_msp41;
- break;
-
- case E_MSP430_MACH_MSP430x42:
- e_set = bfd_mach_msp42;
- break;
-
- case E_MSP430_MACH_MSP430x43:
- e_set = bfd_mach_msp43;
- break;
-
- case E_MSP430_MACH_MSP430x44:
- e_set = bfd_mach_msp44;
- break;
+ case E_MSP430_MACH_MSP430x11: e_set = bfd_mach_msp11; break;
+ case E_MSP430_MACH_MSP430x11x1: e_set = bfd_mach_msp110; break;
+ case E_MSP430_MACH_MSP430x12: e_set = bfd_mach_msp12; break;
+ case E_MSP430_MACH_MSP430x13: e_set = bfd_mach_msp13; break;
+ case E_MSP430_MACH_MSP430x14: e_set = bfd_mach_msp14; break;
+ case E_MSP430_MACH_MSP430x15: e_set = bfd_mach_msp15; break;
+ case E_MSP430_MACH_MSP430x16: e_set = bfd_mach_msp16; break;
+ case E_MSP430_MACH_MSP430x31: e_set = bfd_mach_msp31; break;
+ case E_MSP430_MACH_MSP430x32: e_set = bfd_mach_msp32; break;
+ case E_MSP430_MACH_MSP430x33: e_set = bfd_mach_msp33; break;
+ case E_MSP430_MACH_MSP430x41: e_set = bfd_mach_msp41; break;
+ case E_MSP430_MACH_MSP430x42: e_set = bfd_mach_msp42; break;
+ case E_MSP430_MACH_MSP430x43: e_set = bfd_mach_msp43; break;
+ case E_MSP430_MACH_MSP430x44: e_set = bfd_mach_msp44; break;
+ case E_MSP430_MACH_MSP430x20: e_set = bfd_mach_msp20; break;
+ case E_MSP430_MACH_MSP430x22: e_set = bfd_mach_msp22; break;
+ case E_MSP430_MACH_MSP430x23: e_set = bfd_mach_msp23; break;
+ case E_MSP430_MACH_MSP430x24: e_set = bfd_mach_msp24; break;
+ case E_MSP430_MACH_MSP430x26: e_set = bfd_mach_msp26; break;
+ case E_MSP430_MACH_MSP430x46: e_set = bfd_mach_msp46; break;
+ case E_MSP430_MACH_MSP430x47: e_set = bfd_mach_msp47; break;
+ case E_MSP430_MACH_MSP430x54: e_set = bfd_mach_msp54; break;
+ case E_MSP430_MACH_MSP430X: e_set = bfd_mach_msp430x; break;
}
}
-
+
return bfd_default_set_arch_mach (abfd, bfd_arch_msp430, e_set);
}
@@ -674,6 +1437,8 @@ elf32_msp430_object_p (bfd * abfd)
- Sibling calls. This will affect only 'jump label' polymorph. Without
relaxing this enlarges code by 2 bytes. Sibcalls implemented but
do not work in gcc's port by the reason I do not know.
+ - To convert out of range conditional jump instructions (found inside
+ a function) into inverted jumps over an unconditional branch instruction.
Anyway, if a relaxation required, user should pass -relax option to the
linker.
@@ -797,11 +1562,13 @@ msp430_elf_symbol_address_p (bfd * abfd,
return FALSE;
}
-/* Adjust all local symbols defined as '.section + 0xXXXX' (.section has sec_shndx)
- referenced from current and other sections. */
+/* Adjust all local symbols defined as '.section + 0xXXXX' (.section has
+ sec_shndx) referenced from current and other sections. */
+
static bfd_boolean
-msp430_elf_relax_adjust_locals(bfd * abfd, asection * sec, bfd_vma addr,
- int count, unsigned int sec_shndx, bfd_vma toaddr)
+msp430_elf_relax_adjust_locals (bfd * abfd, asection * sec, bfd_vma addr,
+ int count, unsigned int sec_shndx,
+ bfd_vma toaddr)
{
Elf_Internal_Shdr *symtab_hdr;
Elf_Internal_Rela *irel;
@@ -809,21 +1576,24 @@ msp430_elf_relax_adjust_locals(bfd * abfd, asection * sec, bfd_vma addr,
Elf_Internal_Sym *isym;
irel = elf_section_data (sec)->relocs;
+ if (irel == NULL)
+ return TRUE;
+
irelend = irel + sec->reloc_count;
symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
isym = (Elf_Internal_Sym *) symtab_hdr->contents;
-
- for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
+
+ for (;irel < irelend; irel++)
{
int sidx = ELF32_R_SYM(irel->r_info);
Elf_Internal_Sym *lsym = isym + sidx;
-
+
/* Adjust symbols referenced by .sec+0xXX */
- if (irel->r_addend > addr && irel->r_addend < toaddr
+ if (irel->r_addend > addr && irel->r_addend < toaddr
&& lsym->st_shndx == sec_shndx)
irel->r_addend -= count;
}
-
+
return TRUE;
}
@@ -863,7 +1633,7 @@ msp430_elf_relax_delete_bytes (bfd * abfd, asection * sec, bfd_vma addr,
/* Adjust all the relocs. */
symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
isym = (Elf_Internal_Sym *) symtab_hdr->contents;
- for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
+ for (; irel < irelend; irel++)
{
/* Get the new reloc address. */
if ((irel->r_offset > addr && irel->r_offset < toaddr))
@@ -871,8 +1641,8 @@ msp430_elf_relax_delete_bytes (bfd * abfd, asection * sec, bfd_vma addr,
}
for (p = abfd->sections; p != NULL; p = p->next)
- msp430_elf_relax_adjust_locals(abfd,p,addr,count,sec_shndx,toaddr);
-
+ msp430_elf_relax_adjust_locals (abfd,p,addr,count,sec_shndx,toaddr);
+
/* Adjust the local symbols defined in this section. */
symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
isym = (Elf_Internal_Sym *) symtab_hdr->contents;
@@ -901,6 +1671,82 @@ msp430_elf_relax_delete_bytes (bfd * abfd, asection * sec, bfd_vma addr,
return TRUE;
}
+/* Insert two words into a section whilst relaxing. */
+
+static bfd_byte *
+msp430_elf_relax_add_two_words (bfd * abfd, asection * sec, bfd_vma addr,
+ int word1, int word2)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ unsigned int sec_shndx;
+ bfd_byte *contents;
+ Elf_Internal_Rela *irel;
+ Elf_Internal_Rela *irelend;
+ Elf_Internal_Sym *isym;
+ Elf_Internal_Sym *isymend;
+ struct elf_link_hash_entry **sym_hashes;
+ struct elf_link_hash_entry **end_hashes;
+ unsigned int symcount;
+ bfd_vma sec_end;
+ asection *p;
+
+ contents = elf_section_data (sec)->this_hdr.contents;
+ sec_end = sec->size;
+
+ /* Make space for the new words. */
+ contents = bfd_realloc (contents, sec_end + 4);
+ memmove (contents + addr + 4, contents + addr, sec_end - addr);
+
+ /* Insert the new words. */
+ bfd_put_16 (abfd, word1, contents + addr);
+ bfd_put_16 (abfd, word2, contents + addr + 2);
+
+ /* Update the section information. */
+ sec->size += 4;
+ elf_section_data (sec)->this_hdr.contents = contents;
+
+ /* Adjust all the relocs. */
+ irel = elf_section_data (sec)->relocs;
+ irelend = irel + sec->reloc_count;
+
+ for (; irel < irelend; irel++)
+ if ((irel->r_offset >= addr && irel->r_offset < sec_end))
+ irel->r_offset += 4;
+
+ /* Adjust the local symbols defined in this section. */
+ sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
+ for (p = abfd->sections; p != NULL; p = p->next)
+ msp430_elf_relax_adjust_locals (abfd, p, addr, -4,
+ sec_shndx, sec_end);
+
+ /* Adjust the global symbols affected by the move. */
+ symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
+ isym = (Elf_Internal_Sym *) symtab_hdr->contents;
+ for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
+ if (isym->st_shndx == sec_shndx
+ && isym->st_value >= addr && isym->st_value < sec_end)
+ isym->st_value += 4;
+
+ /* Now adjust the global symbols defined in this section. */
+ symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
+ - symtab_hdr->sh_info);
+ sym_hashes = elf_sym_hashes (abfd);
+ end_hashes = sym_hashes + symcount;
+ for (; sym_hashes < end_hashes; sym_hashes++)
+ {
+ struct elf_link_hash_entry *sym_hash = *sym_hashes;
+
+ if ((sym_hash->root.type == bfd_link_hash_defined
+ || sym_hash->root.type == bfd_link_hash_defweak)
+ && sym_hash->root.u.def.section == sec
+ && sym_hash->root.u.def.value >= addr
+ && sym_hash->root.u.def.value < sec_end)
+ sym_hash->root.u.def.value += 4;
+ }
+
+ return contents;
+}
+
static bfd_boolean
msp430_elf_relax_section (bfd * abfd, asection * sec,
struct bfd_link_info * link_info,
@@ -913,6 +1759,7 @@ msp430_elf_relax_section (bfd * abfd, asection * sec,
bfd_byte * contents = NULL;
Elf_Internal_Sym * isymbuf = NULL;
+
/* Assume nothing changes. */
*again = FALSE;
@@ -920,8 +1767,8 @@ msp430_elf_relax_section (bfd * abfd, asection * sec,
this section does not have relocs, or if this is not a
code section. */
if (link_info->relocatable
- || (sec->flags & SEC_RELOC) == 0
- || sec->reloc_count == 0 || (sec->flags & SEC_CODE) == 0)
+ || (sec->flags & SEC_RELOC) == 0
+ || sec->reloc_count == 0 || (sec->flags & SEC_CODE) == 0)
return TRUE;
symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
@@ -934,13 +1781,21 @@ msp430_elf_relax_section (bfd * abfd, asection * sec,
/* Walk through them looking for relaxing opportunities. */
irelend = internal_relocs + sec->reloc_count;
+
+ /* Do code size growing relocs first. */
for (irel = internal_relocs; irel < irelend; irel++)
{
bfd_vma symval;
/* If this isn't something that can be relaxed, then ignore
this reloc. */
- if (ELF32_R_TYPE (irel->r_info) != (int) R_MSP430_RL_PCREL)
+ if (uses_msp430x_relocs (abfd)
+ && ELF32_R_TYPE (irel->r_info) == (int) R_MSP430X_10_PCREL)
+ ;
+ else if (! uses_msp430x_relocs (abfd)
+ && ELF32_R_TYPE (irel->r_info) == (int) R_MSP430_10_PCREL)
+ ;
+ else
continue;
/* Get the section contents if we haven't done so already. */
@@ -1014,108 +1869,287 @@ msp430_elf_relax_section (bfd * abfd, asection * sec,
that would be more work, but would require less memory when
the linker is run. */
- /* Try to turn a 16bit pc-relative branch into a 10bit pc-relative
- branch. */
- /* Paranoia? paranoia... */
- if (ELF32_R_TYPE (irel->r_info) == (int) R_MSP430_RL_PCREL)
- {
- bfd_vma value = symval;
+ bfd_signed_vma value = symval;
+ int opcode;
- /* Deal with pc-relative gunk. */
- value -= (sec->output_section->vma + sec->output_offset);
- value -= irel->r_offset;
- value += irel->r_addend;
+ /* Compute the value that will be relocated. */
+ value += irel->r_addend;
+ /* Convert to PC relative. */
+ value -= (sec->output_section->vma + sec->output_offset);
+ value -= irel->r_offset;
+ value -= 2;
+ /* Scale. */
+ value >>= 1;
- /* See if the value will fit in 10 bits, note the high value is
- 1016 as the target will be two bytes closer if we are
- able to relax. */
- if ((long) value < 1016 && (long) value > -1016)
- {
- int code0 = 0, code1 = 0, code2 = 0;
- int i;
- struct rcodes_s *rx;
+ /* If it is in range then no modifications are needed. */
+ if (value >= -512 && value <= 511)
+ continue;
- /* Get the opcode. */
- if (irel->r_offset >= 6)
- code0 = bfd_get_16 (abfd, contents + irel->r_offset - 6);
+ /* Get the opcode. */
+ opcode = bfd_get_16 (abfd, contents + irel->r_offset);
+
+ /* Compute the new opcode. We are going to convert:
+ J<cond> label
+ into:
+ J<inv-cond> 1f
+ BR[A] #label
+ 1: */
+ switch (opcode & 0xfc00)
+ {
+ case 0x3800: opcode = 0x3402; break; /* Jl -> Jge +2 */
+ case 0x3400: opcode = 0x3802; break; /* Jge -> Jl +2 */
+ case 0x2c00: opcode = 0x2802; break; /* Jhs -> Jlo +2 */
+ case 0x2800: opcode = 0x2c02; break; /* Jlo -> Jhs +2 */
+ case 0x2400: opcode = 0x2002; break; /* Jeq -> Jne +2 */
+ case 0x2000: opcode = 0x2402; break; /* jne -> Jeq +2 */
+ case 0x3000: /* jn */
+ /* There is no direct inverse of the Jn insn.
+ FIXME: we could do this as:
+ Jn 1f
+ br 2f
+ 1: br label
+ 2: */
+ continue;
+ default:
+ /* Not a conditional branch instruction. */
+ /* fprintf (stderr, "unrecog: %x\n", opcode); */
+ goto error_return;
+ }
- if (irel->r_offset >= 4)
- code1 = bfd_get_16 (abfd, contents + irel->r_offset - 4);
+ /* Note that we've changed the relocs, section contents, etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ elf_section_data (sec)->this_hdr.contents = contents;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
- code2 = bfd_get_16 (abfd, contents + irel->r_offset - 2);
+ /* Install the new opcode. */
+ bfd_put_16 (abfd, opcode, contents + irel->r_offset);
- if (code2 != 0x4010)
- continue;
+ /* Insert the new branch instruction. */
+ if (uses_msp430x_relocs (abfd))
+ {
+ /* Insert an absolute branch (aka MOVA) instruction. */
+ contents = msp430_elf_relax_add_two_words
+ (abfd, sec, irel->r_offset + 2, 0x0080, 0x0000);
+
+ /* Update the relocation to point to the inserted branch
+ instruction. Note - we are changing a PC-relative reloc
+ into an absolute reloc, but this is OK because we have
+ arranged with the assembler to have the reloc's value be
+ a (local) symbol, not a section+offset value. */
+ irel->r_offset += 2;
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_MSP430X_ABS20_ADR_SRC);
+ }
+ else
+ {
+ contents = msp430_elf_relax_add_two_words
+ (abfd, sec, irel->r_offset + 2, 0x4030, 0x0000);
+
+ /* See comment above about converting a 10-bit PC-rel
+ relocation into a 16-bit absolute relocation. */
+ irel->r_offset += 4;
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_MSP430_16);
+ }
- /* Check r4 and r3. */
- for (i = NUMB_RELAX_CODES - 1; i >= 0; i--)
- {
- rx = &rcode[i];
- if (rx->cdx == 2 && rx->f0 == code0 && rx->f1 == code1)
- break;
- else if (rx->cdx == 1 && rx->f1 == code1)
- break;
- else if (rx->cdx == 0) /* This is an unconditional jump. */
- break;
- }
+ /* Growing the section may mean that other
+ conditional branches need to be fixed. */
+ *again = TRUE;
+ }
- /* Check labels:
+ if (! uses_msp430x_relocs (abfd))
+ /* Now perform the relocations that shrink the code size.
+ We only do this for non msp430x as gas only generates the RL
+ reloc for the msp430. */
+ for (irel = internal_relocs; irel < irelend; irel++)
+ {
+ bfd_vma symval;
+
+ /* Get the section contents if we haven't done so already. */
+ if (contents == NULL)
+ {
+ /* Get cached copy if it exists. */
+ if (elf_section_data (sec)->this_hdr.contents != NULL)
+ contents = elf_section_data (sec)->this_hdr.contents;
+ else if (! bfd_malloc_and_get_section (abfd, sec, &contents))
+ goto error_return;
+ }
+
+ /* Read this BFD's local symbols if we haven't done so already. */
+ if (isymbuf == NULL && symtab_hdr->sh_info != 0)
+ {
+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (isymbuf == NULL)
+ isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ if (isymbuf == NULL)
+ goto error_return;
+ }
+
+ /* Get the value of the symbol referred to by the reloc. */
+ if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
+ {
+ /* A local symbol. */
+ Elf_Internal_Sym *isym;
+ asection *sym_sec;
+
+ isym = isymbuf + ELF32_R_SYM (irel->r_info);
+ if (isym->st_shndx == SHN_UNDEF)
+ sym_sec = bfd_und_section_ptr;
+ else if (isym->st_shndx == SHN_ABS)
+ sym_sec = bfd_abs_section_ptr;
+ else if (isym->st_shndx == SHN_COMMON)
+ sym_sec = bfd_com_section_ptr;
+ else
+ sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
+ symval = (isym->st_value
+ + sym_sec->output_section->vma + sym_sec->output_offset);
+ }
+ else
+ {
+ unsigned long indx;
+ struct elf_link_hash_entry *h;
+
+ /* An external symbol. */
+ indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
+ h = elf_sym_hashes (abfd)[indx];
+ BFD_ASSERT (h != NULL);
+
+ if (h->root.type != bfd_link_hash_defined
+ && h->root.type != bfd_link_hash_defweak)
+ /* This appears to be a reference to an undefined
+ symbol. Just ignore it--it will be caught by the
+ regular reloc processing. */
+ continue;
+
+ symval = (h->root.u.def.value
+ + h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset);
+ }
+
+ /* For simplicity of coding, we are going to modify the section
+ contents, the section relocs, and the BFD symbol table. We
+ must tell the rest of the code not to free up this
+ information. It would be possible to instead create a table
+ of changes which have to be made, as is done in coff-mips.c;
+ that would be more work, but would require less memory when
+ the linker is run. */
+
+ /* Try to turn a 16bit pc-relative branch into a 10bit pc-relative
+ branch. */
+ /* Paranoia? paranoia... */
+ if (ELF32_R_TYPE (irel->r_info) == (int) R_MSP430_RL_PCREL)
+ {
+ bfd_vma value = symval;
+
+ /* Deal with pc-relative gunk. */
+ value -= (sec->output_section->vma + sec->output_offset);
+ value -= irel->r_offset;
+ value += irel->r_addend;
+
+ /* See if the value will fit in 10 bits, note the high value is
+ 1016 as the target will be two bytes closer if we are
+ able to relax. */
+ if ((long) value < 1016 && (long) value > -1016)
+ {
+ int code0 = 0, code1 = 0, code2 = 0;
+ int i;
+ struct rcodes_s *rx;
+
+ /* Get the opcode. */
+ if (irel->r_offset >= 6)
+ code0 = bfd_get_16 (abfd, contents + irel->r_offset - 6);
+
+ if (irel->r_offset >= 4)
+ code1 = bfd_get_16 (abfd, contents + irel->r_offset - 4);
+
+ code2 = bfd_get_16 (abfd, contents + irel->r_offset - 2);
+
+ if (code2 != 0x4010)
+ continue;
+
+ /* Check r4 and r3. */
+ for (i = NUMB_RELAX_CODES - 1; i >= 0; i--)
+ {
+ rx = &rcode[i];
+ if (rx->cdx == 2 && rx->f0 == code0 && rx->f1 == code1)
+ break;
+ else if (rx->cdx == 1 && rx->f1 == code1)
+ break;
+ else if (rx->cdx == 0) /* This is an unconditional jump. */
+ break;
+ }
+
+ /* Check labels:
.Label0: ; we do not care about this label
- jeq +6
+ jeq +6
.Label1: ; make sure there is no label here
- jl +4
+ jl +4
.Label2: ; make sure there is no label here
- br .Label_dst
-
- So, if there is .Label1 or .Label2 we cannot relax this code.
- This actually should not happen, cause for relaxable
- instructions we use RL_PCREL reloc instead of 16_PCREL.
- Will change this in the future. */
-
- if (rx->cdx > 0
- && msp430_elf_symbol_address_p (abfd, sec, isymbuf,
- irel->r_offset - 2))
- continue;
- if (rx->cdx > 1
- && msp430_elf_symbol_address_p (abfd, sec, isymbuf,
- irel->r_offset - 4))
- continue;
-
- /* Note that we've changed the relocs, section contents, etc. */
- elf_section_data (sec)->relocs = internal_relocs;
- elf_section_data (sec)->this_hdr.contents = contents;
- symtab_hdr->contents = (unsigned char *) isymbuf;
-
- /* Fix the relocation's type. */
- if (rx->labels == 3) /* Handle special cases. */
- irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
- R_MSP430_2X_PCREL);
- else
- irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
- R_MSP430_10_PCREL);
-
- /* Fix the opcode right way. */
- bfd_put_16 (abfd, rx->t0, contents + irel->r_offset - rx->off);
- if (rx->t1)
- bfd_put_16 (abfd, rx->t1,
- contents + irel->r_offset - rx->off + 2);
-
- /* Delete bytes. */
- if (!msp430_elf_relax_delete_bytes (abfd, sec,
- irel->r_offset - rx->off +
- rx->ncl, rx->bs))
- goto error_return;
-
- /* Handle unconditional jumps. */
- if (rx->cdx == 0)
- irel->r_offset -= 2;
-
- /* That will change things, so, we should relax again.
- Note that this is not required, and it may be slow. */
- *again = TRUE;
- }
- }
- }
+ br .Label_dst
+
+ So, if there is .Label1 or .Label2 we cannot relax this code.
+ This actually should not happen, cause for relaxable
+ instructions we use RL_PCREL reloc instead of 16_PCREL.
+ Will change this in the future. */
+
+ if (rx->cdx > 0
+ && msp430_elf_symbol_address_p (abfd, sec, isymbuf,
+ irel->r_offset - 2))
+ continue;
+ if (rx->cdx > 1
+ && msp430_elf_symbol_address_p (abfd, sec, isymbuf,
+ irel->r_offset - 4))
+ continue;
+
+ /* Note that we've changed the relocs, section contents, etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ elf_section_data (sec)->this_hdr.contents = contents;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+
+ /* Fix the relocation's type. */
+ if (uses_msp430x_relocs (abfd))
+ {
+ if (rx->labels == 3) /* Handle special cases. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_MSP430X_2X_PCREL);
+ else
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_MSP430X_10_PCREL);
+ }
+ else
+ {
+ if (rx->labels == 3) /* Handle special cases. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_MSP430_2X_PCREL);
+ else
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_MSP430_10_PCREL);
+ }
+
+ /* Fix the opcode right way. */
+ bfd_put_16 (abfd, rx->t0, contents + irel->r_offset - rx->off);
+ if (rx->t1)
+ bfd_put_16 (abfd, rx->t1,
+ contents + irel->r_offset - rx->off + 2);
+
+ /* Delete bytes. */
+ if (!msp430_elf_relax_delete_bytes (abfd, sec,
+ irel->r_offset - rx->off +
+ rx->ncl, rx->bs))
+ goto error_return;
+
+ /* Handle unconditional jumps. */
+ if (rx->cdx == 0)
+ irel->r_offset -= 2;
+
+ /* That will change things, so, we should relax again.
+ Note that this is not required, and it may be slow. */
+ *again = TRUE;
+ }
+ }
+ }
if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
{
@@ -1159,11 +2193,259 @@ error_return:
return FALSE;
}
+/* Handle an MSP430 specific section when reading an object file.
+ This is called when bfd_section_from_shdr finds a section with
+ an unknown type. */
+
+static bfd_boolean
+elf32_msp430_section_from_shdr (bfd *abfd,
+ Elf_Internal_Shdr * hdr,
+ const char *name,
+ int shindex)
+{
+ switch (hdr->sh_type)
+ {
+ case SHT_MSP430_SEC_FLAGS:
+ case SHT_MSP430_SYM_ALIASES:
+ case SHT_MSP430_ATTRIBUTES:
+ return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
+ default:
+ return FALSE;
+ }
+}
+
+static bfd_boolean
+elf32_msp430_obj_attrs_handle_unknown (bfd *abfd, int tag)
+{
+ _bfd_error_handler
+ (_("Warning: %B: Unknown MSPABI object attribute %d"),
+ abfd, tag);
+ return TRUE;
+}
+
+/* Determine whether an object attribute tag takes an integer, a
+ string or both. */
+
+static int
+elf32_msp430_obj_attrs_arg_type (int tag)
+{
+ if (tag == Tag_compatibility)
+ return ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL;
+
+ if (tag < 32)
+ return ATTR_TYPE_FLAG_INT_VAL;
+
+ return (tag & 1) != 0 ? ATTR_TYPE_FLAG_STR_VAL : ATTR_TYPE_FLAG_INT_VAL;
+}
+
+static inline const char *
+isa_type (int isa)
+{
+ switch (isa)
+ {
+ case 1: return "MSP430";
+ case 2: return "MSP430X";
+ default: return "unknown";
+ }
+}
+
+static inline const char *
+code_model (int model)
+{
+ switch (model)
+ {
+ case 1: return "small";
+ case 2: return "large";
+ default: return "unknown";
+ }
+}
+
+static inline const char *
+data_model (int model)
+{
+ switch (model)
+ {
+ case 1: return "small";
+ case 2: return "large";
+ case 3: return "restricted large";
+ default: return "unknown";
+ }
+}
+
+/* Merge MSPABI object attributes from IBFD into OBFD.
+ Raise an error if there are conflicting attributes. */
+
+static bfd_boolean
+elf32_msp430_merge_mspabi_attributes (bfd *ibfd, bfd *obfd)
+{
+ obj_attribute *in_attr;
+ obj_attribute *out_attr;
+ bfd_boolean result = TRUE;
+ static bfd * first_input_bfd = NULL;
+
+ /* Skip linker created files. */
+ if (ibfd->flags & BFD_LINKER_CREATED)
+ return TRUE;
+
+ /* If this is the first real object just copy the attributes. */
+ if (!elf_known_obj_attributes_proc (obfd)[0].i)
+ {
+ _bfd_elf_copy_obj_attributes (ibfd, obfd);
+
+ out_attr = elf_known_obj_attributes_proc (obfd);
+
+ /* Use the Tag_null value to indicate that
+ the attributes have been initialized. */
+ out_attr[0].i = 1;
+
+ first_input_bfd = ibfd;
+ return TRUE;
+ }
+
+ in_attr = elf_known_obj_attributes_proc (ibfd);
+ out_attr = elf_known_obj_attributes_proc (obfd);
+
+ /* The ISAs must be the same. */
+ if (in_attr[OFBA_MSPABI_Tag_ISA].i != out_attr[OFBA_MSPABI_Tag_ISA].i)
+ {
+ _bfd_error_handler
+ (_("error: %B uses %s instructions but %B uses %s"),
+ ibfd, first_input_bfd,
+ isa_type (in_attr[OFBA_MSPABI_Tag_ISA].i),
+ isa_type (out_attr[OFBA_MSPABI_Tag_ISA].i));
+ result = FALSE;
+ }
+
+ /* The code models must be the same. */
+ if (in_attr[OFBA_MSPABI_Tag_Code_Model].i !=
+ out_attr[OFBA_MSPABI_Tag_Code_Model].i)
+ {
+ _bfd_error_handler
+ (_("error: %B uses the %s code model whereas %B uses the %s code model"),
+ ibfd, first_input_bfd,
+ code_model (in_attr[OFBA_MSPABI_Tag_Code_Model].i),
+ code_model (out_attr[OFBA_MSPABI_Tag_Code_Model].i));
+ result = FALSE;
+ }
+
+ /* The large code model is only supported by the MSP430X. */
+ if (in_attr[OFBA_MSPABI_Tag_Code_Model].i == 2
+ && out_attr[OFBA_MSPABI_Tag_ISA].i != 2)
+ {
+ _bfd_error_handler
+ (_("error: %B uses the large code model but %B uses MSP430 instructions"),
+ ibfd, first_input_bfd);
+ result = FALSE;
+ }
+
+ /* The data models must be the same. */
+ if (in_attr[OFBA_MSPABI_Tag_Data_Model].i !=
+ out_attr[OFBA_MSPABI_Tag_Data_Model].i)
+ {
+ _bfd_error_handler
+ (_("error: %B uses the %s data model whereas %B uses the %s data model"),
+ ibfd, first_input_bfd,
+ data_model (in_attr[OFBA_MSPABI_Tag_Data_Model].i),
+ data_model (out_attr[OFBA_MSPABI_Tag_Data_Model].i));
+ result = FALSE;
+ }
+
+ /* The small code model requires the use of the small data model. */
+ if (in_attr[OFBA_MSPABI_Tag_Code_Model].i == 1
+ && out_attr[OFBA_MSPABI_Tag_Data_Model].i != 1)
+ {
+ _bfd_error_handler
+ (_("error: %B uses the small code model but %B uses the %s data model"),
+ ibfd, first_input_bfd,
+ data_model (out_attr[OFBA_MSPABI_Tag_Data_Model].i));
+ result = FALSE;
+ }
+
+ /* The large data models are only supported by the MSP430X. */
+ if (in_attr[OFBA_MSPABI_Tag_Data_Model].i > 1
+ && out_attr[OFBA_MSPABI_Tag_ISA].i != 2)
+ {
+ _bfd_error_handler
+ (_("error: %B uses the %s data model but %B only uses MSP430 instructions"),
+ ibfd, first_input_bfd,
+ data_model (in_attr[OFBA_MSPABI_Tag_Data_Model].i));
+ result = FALSE;
+ }
+
+ return result;
+}
+
+/* Merge backend specific data from an object file to the output
+ object file when linking. */
+
+static bfd_boolean
+elf32_msp430_merge_private_bfd_data (bfd * ibfd, bfd * obfd)
+{
+ /* Make sure that the machine number reflects the most
+ advanced version of the MSP architecture required. */
+#define max(a,b) ((a) > (b) ? (a) : (b))
+ if (bfd_get_mach (ibfd) != bfd_get_mach (obfd))
+ bfd_default_set_arch_mach (obfd, bfd_get_arch (obfd),
+ max (bfd_get_mach (ibfd), bfd_get_mach (obfd)));
+#undef max
+
+ return elf32_msp430_merge_mspabi_attributes (ibfd, obfd);
+}
+
+/* Copy backend specific data from one object module to another. */
+
+static bfd_boolean
+elf32_msp430_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
+{
+ /* Copy object attributes. */
+ _bfd_elf_copy_obj_attributes (ibfd, obfd);
+
+ return TRUE;
+}
+
+static bfd_boolean
+msp430_elf_is_target_special_symbol (bfd *abfd, asymbol *sym)
+{
+ return _bfd_elf_is_local_label_name (abfd, sym->name);
+}
+
+/* This is gross. The MSP430 EABI says that (sec 11.5):
+
+ "An implementation may choose to use Rel or Rela
+ type relocations for other relocations."
+
+ But it also says that:
+
+ "Certain relocations are identified as Rela only. [snip]
+ Where Rela is specified, an implementation must honor
+ this requirement."
+
+ There is one relocation marked as requiring RELA - R_MSP430_ABS_HI16 - but
+ to keep things simple we choose to use RELA relocations throughout. The
+ problem is that the TI compiler generates REL relocations, so we have to
+ be able to accept those as well. */
+
+#define elf_backend_may_use_rel_p 1
+#define elf_backend_may_use_rela_p 1
+#define elf_backend_default_use_rela_p 1
+
+#undef elf_backend_obj_attrs_vendor
+#define elf_backend_obj_attrs_vendor "mspabi"
+#undef elf_backend_obj_attrs_section
+#define elf_backend_obj_attrs_section ".MSP430.attributes"
+#undef elf_backend_obj_attrs_section_type
+#define elf_backend_obj_attrs_section_type SHT_MSP430_ATTRIBUTES
+#define elf_backend_section_from_shdr elf32_msp430_section_from_shdr
+#define elf_backend_obj_attrs_handle_unknown elf32_msp430_obj_attrs_handle_unknown
+#undef elf_backend_obj_attrs_arg_type
+#define elf_backend_obj_attrs_arg_type elf32_msp430_obj_attrs_arg_type
+#define bfd_elf32_bfd_copy_private_bfd_data elf32_msp430_copy_private_bfd_data
+#define bfd_elf32_bfd_merge_private_bfd_data elf32_msp430_merge_private_bfd_data
#define ELF_ARCH bfd_arch_msp430
#define ELF_MACHINE_CODE EM_MSP430
#define ELF_MACHINE_ALT1 EM_MSP430_OLD
-#define ELF_MAXPAGESIZE 1
+#define ELF_MAXPAGESIZE 4
#define ELF_OSABI ELFOSABI_STANDALONE
#define TARGET_LITTLE_SYM bfd_elf32_msp430_vec
@@ -1178,5 +2460,30 @@ error_return:
#define elf_backend_object_p elf32_msp430_object_p
#define elf_backend_post_process_headers _bfd_elf_set_osabi
#define bfd_elf32_bfd_relax_section msp430_elf_relax_section
+#define bfd_elf32_bfd_is_target_special_symbol msp430_elf_is_target_special_symbol
+
+#undef elf32_bed
+#define elf32_bed elf32_msp430_bed
+
+#include "elf32-target.h"
+
+/* The TI compiler sets the OSABI field to ELFOSABI_NONE. */
+#undef TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM bfd_elf32_msp430_ti_vec
+
+#undef elf32_bed
+#define elf32_bed elf32_msp430_ti_bed
+
+#undef ELF_OSABI
+#define ELF_OSABI ELFOSABI_NONE
+
+static const struct bfd_elf_special_section msp430_ti_elf_special_sections[] =
+{
+ /* prefix, prefix_length, suffix_len, type, attributes. */
+ { STRING_COMMA_LEN (".TI.symbol.alias"), 0, SHT_MSP430_SYM_ALIASES, 0 },
+ { STRING_COMMA_LEN (".TI.section.flags"), 0, SHT_MSP430_SEC_FLAGS, 0 },
+ { STRING_COMMA_LEN ("_TI_build_attrib"), 0, SHT_MSP430_ATTRIBUTES, 0 },
+ { NULL, 0, 0, 0, 0 }
+};
#include "elf32-target.h"
diff --git a/bfd/elf32-vax.c b/bfd/elf32-vax.c
index f13ec1b78..77b8e0d8a 100644
--- a/bfd/elf32-vax.c
+++ b/bfd/elf32-vax.c
@@ -914,9 +914,8 @@ elf_vax_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info, asection *sec,
understand. */
static bfd_boolean
-elf_vax_adjust_dynamic_symbol (info, h)
- struct bfd_link_info *info;
- struct elf_link_hash_entry *h;
+elf_vax_adjust_dynamic_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *h)
{
bfd *dynobj;
asection *s;
@@ -1263,10 +1262,10 @@ elf_vax_discard_copies (struct elf_vax_link_hash_entry *h,
/* This function is called via elf_link_hash_traverse. It looks for entries
that have GOT or PLT (.GOT) references. If creating a static object or a
- shared object with -Bsymbolic, it resets the reference count back to 0
- and sets the offset to -1 so normal PC32 relocation will be done. If
- creating a shared object or executable, space in the .got and .rela.got
- will be reserved for the symbol. */
+ shared object with -Bsymbolic, or the symbol has been forced local, then
+ it resets the reference count back to -1 so normal PC32 relocation will
+ be done. Otherwise space in the .got and .rela.got will be reserved for
+ the symbol. */
static bfd_boolean
elf_vax_instantiate_got_entries (struct elf_link_hash_entry *h, void * infoptr)
@@ -1291,10 +1290,8 @@ elf_vax_instantiate_got_entries (struct elf_link_hash_entry *h, void * infoptr)
|| (info->shared && info->symbolic)
|| h->forced_local)
{
- h->got.refcount = 0;
- h->got.offset = (bfd_vma) -1;
- h->plt.refcount = 0;
- h->plt.offset = (bfd_vma) -1;
+ h->got.refcount = -1;
+ h->plt.refcount = -1;
}
else if (h->got.refcount > 0)
{
diff --git a/bfd/elf64-aarch64.c b/bfd/elf64-aarch64.c
index e3cae9565..fe9d5b17c 100644
--- a/bfd/elf64-aarch64.c
+++ b/bfd/elf64-aarch64.c
@@ -1730,26 +1730,6 @@ elf64_aarch64_mkobject (bfd *abfd)
AARCH64_ELF_DATA);
}
-/* The AArch64 linker needs to keep track of the number of relocs that it
- decides to copy in check_relocs for each symbol. This is so that
- it can discard PC relative relocs if it doesn't need them when
- linking with -Bsymbolic. We store the information in a field
- extending the regular ELF linker hash table. */
-
-/* This structure keeps track of the number of relocs we have copied
- for a given symbol. */
-struct elf64_aarch64_relocs_copied
-{
- /* Next section. */
- struct elf64_aarch64_relocs_copied *next;
- /* A section in dynobj. */
- asection *section;
- /* Number of relocs copied in this section. */
- bfd_size_type count;
- /* Number of PC-relative relocs copied in this section. */
- bfd_size_type pc_count;
-};
-
#define elf64_aarch64_hash_entry(ent) \
((struct elf64_aarch64_link_hash_entry *)(ent))
@@ -1769,9 +1749,6 @@ struct elf64_aarch64_link_hash_entry
/* Track dynamic relocs copied for this symbol. */
struct elf_dyn_relocs *dyn_relocs;
- /* Number of PC relative relocs copied for this symbol. */
- struct elf64_aarch64_relocs_copied *relocs_copied;
-
/* Since PLT entries have variable size, we need to record the
index into .got.plt instead of recomputing it from the PLT
offset. */
@@ -1950,7 +1927,6 @@ elf64_aarch64_link_hash_newfunc (struct bfd_hash_entry *entry,
if (ret != NULL)
{
ret->dyn_relocs = NULL;
- ret->relocs_copied = NULL;
ret->got_type = GOT_UNKNOWN;
ret->plt_got_offset = (bfd_vma) - 1;
ret->stub_cache = NULL;
@@ -2041,37 +2017,6 @@ elf64_aarch64_copy_indirect_symbol (struct bfd_link_info *info,
eind->dyn_relocs = NULL;
}
- if (eind->relocs_copied != NULL)
- {
- if (edir->relocs_copied != NULL)
- {
- struct elf64_aarch64_relocs_copied **pp;
- struct elf64_aarch64_relocs_copied *p;
-
- /* Add reloc counts against the indirect sym to the direct sym
- list. Merge any entries against the same section. */
- for (pp = &eind->relocs_copied; (p = *pp) != NULL;)
- {
- struct elf64_aarch64_relocs_copied *q;
-
- for (q = edir->relocs_copied; q != NULL; q = q->next)
- if (q->section == p->section)
- {
- q->pc_count += p->pc_count;
- q->count += p->count;
- *pp = p->next;
- break;
- }
- if (q == NULL)
- pp = &p->next;
- }
- *pp = edir->relocs_copied;
- }
-
- edir->relocs_copied = eind->relocs_copied;
- eind->relocs_copied = NULL;
- }
-
if (ind->root.type == bfd_link_hash_indirect)
{
/* Copy over PLT info. */
@@ -7181,6 +7126,7 @@ const struct elf_size_info elf64_aarch64_size_info =
#define elf_backend_may_use_rela_p 1
#define elf_backend_default_use_rela_p 1
#define elf_backend_got_header_size (GOT_ENTRY_SIZE * 3)
+#define elf_backend_default_execstack 0
#undef elf_backend_obj_attrs_section
#define elf_backend_obj_attrs_section ".ARM.attributes"
diff --git a/bfd/elf64-mips.c b/bfd/elf64-mips.c
index c24a4ee4e..e69209976 100644
--- a/bfd/elf64-mips.c
+++ b/bfd/elf64-mips.c
@@ -2622,6 +2622,23 @@ static reloc_howto_type elf_mips_gnu_rela16_s2 =
0, /* src_mask */
0x0000ffff, /* dst_mask */
TRUE); /* pcrel_offset */
+
+/* 32 bit pc-relative. Used for compact EH tables. */
+static reloc_howto_type elf_mips_gnu_pcrel32 =
+ HOWTO (R_MIPS_PC32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_PC32", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE); /* pcrel_offset */
+
/* Originally a VxWorks extension, but now used for other systems too. */
static reloc_howto_type elf_mips_copy_howto =
@@ -2632,7 +2649,7 @@ static reloc_howto_type elf_mips_copy_howto =
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
- bfd_elf_generic_reloc, /* special_function */
+ _bfd_mips_elf_generic_reloc, /* special_function */
"R_MIPS_COPY", /* name */
FALSE, /* partial_inplace */
0x0, /* src_mask */
@@ -2648,7 +2665,7 @@ static reloc_howto_type elf_mips_jump_slot_howto =
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
- bfd_elf_generic_reloc, /* special_function */
+ _bfd_mips_elf_generic_reloc, /* special_function */
"R_MIPS_JUMP_SLOT", /* name */
FALSE, /* partial_inplace */
0x0, /* src_mask */
@@ -3257,6 +3274,8 @@ bfd_elf64_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
return &elf_mips_gnu_vtinherit_howto;
case BFD_RELOC_VTABLE_ENTRY:
return &elf_mips_gnu_vtentry_howto;
+ case BFD_RELOC_32_PCREL:
+ return &elf_mips_gnu_pcrel32;
case BFD_RELOC_MIPS_COPY:
return &elf_mips_copy_howto;
case BFD_RELOC_MIPS_JUMP_SLOT:
@@ -3304,6 +3323,8 @@ bfd_elf64_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
return &elf_mips_gnu_rel16_s2;
if (strcasecmp (elf_mips_gnu_rela16_s2.name, r_name) == 0)
return &elf_mips_gnu_rela16_s2;
+ if (strcasecmp (elf_mips_gnu_pcrel32.name, r_name) == 0)
+ return &elf_mips_gnu_pcrel32;
if (strcasecmp (elf_mips_copy_howto.name, r_name) == 0)
return &elf_mips_copy_howto;
if (strcasecmp (elf_mips_jump_slot_howto.name, r_name) == 0)
@@ -3328,6 +3349,8 @@ mips_elf64_rtype_to_howto (unsigned int r_type, bfd_boolean rela_p)
return &elf_mips_gnu_rela16_s2;
else
return &elf_mips_gnu_rel16_s2;
+ case R_MIPS_PC32:
+ return &elf_mips_gnu_pcrel32;
case R_MIPS_COPY:
return &elf_mips_copy_howto;
case R_MIPS_JUMP_SLOT:
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index cb33821a7..d4415e457 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -5665,11 +5665,30 @@ opd_entry_value (asection *opd_sec,
sym_hashes = elf_sym_hashes (opd_bfd);
rh = sym_hashes[symndx - symtab_hdr->sh_info];
- rh = elf_follow_link (rh);
- BFD_ASSERT (rh->root.type == bfd_link_hash_defined
- || rh->root.type == bfd_link_hash_defweak);
- val = rh->root.u.def.value;
- sec = rh->root.u.def.section;
+ if (rh != NULL)
+ {
+ rh = elf_follow_link (rh);
+ BFD_ASSERT (rh->root.type == bfd_link_hash_defined
+ || rh->root.type == bfd_link_hash_defweak);
+ val = rh->root.u.def.value;
+ sec = rh->root.u.def.section;
+ }
+ else
+ {
+ /* Handle the odd case where we can be called
+ during bfd_elf_link_add_symbols before the
+ symbol hashes have been fully populated. */
+ Elf_Internal_Sym *sym;
+
+ sym = bfd_elf_get_elf_syms (opd_bfd, symtab_hdr, 1,
+ symndx, NULL, NULL, NULL);
+ if (sym == NULL)
+ break;
+
+ val = sym->st_value;
+ sec = bfd_section_from_elf_index (opd_bfd, sym->st_shndx);
+ free (sym);
+ }
}
val += look->r_addend;
if (code_off != NULL)
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index 9adc959f9..758231e2c 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -2260,6 +2260,7 @@ elf_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
return _bfd_elf_allocate_ifunc_dyn_relocs (info, h,
&eh->dyn_relocs,
plt_entry_size,
+ plt_entry_size,
GOT_ENTRY_SIZE);
else if (htab->elf.dynamic_sections_created
&& h->plt.refcount > 0)
diff --git a/bfd/elflink.c b/bfd/elflink.c
index f5a36d21f..692cb7ac7 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -573,7 +573,8 @@ bfd_elf_record_link_assignment (bfd *output_bfd,
if (hidden)
{
bed = get_elf_backend_data (output_bfd);
- h->other = (h->other & ~ELF_ST_VISIBILITY (-1)) | STV_HIDDEN;
+ if (ELF_ST_VISIBILITY (h->other) != STV_INTERNAL)
+ h->other = (h->other & ~ELF_ST_VISIBILITY (-1)) | STV_HIDDEN;
(*bed->elf_backend_hide_symbol) (info, h, TRUE);
}
@@ -3351,14 +3352,12 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
unsigned int old_size = 0;
unsigned int old_count = 0;
void *old_tab = NULL;
- void *old_hash;
void *old_ent;
struct bfd_link_hash_entry *old_undefs = NULL;
struct bfd_link_hash_entry *old_undefs_tail = NULL;
long old_dynsymcount = 0;
bfd_size_type old_dynstr_size = 0;
size_t tabsize = 0;
- size_t hashsize = 0;
htab = elf_hash_table (info);
bed = get_elf_backend_data (abfd);
@@ -3713,7 +3712,7 @@ error_free_dyn:
extsymoff = hdr->sh_info;
}
- sym_hash = NULL;
+ sym_hash = elf_sym_hashes (abfd);
if (extsymcount != 0)
{
isymbuf = bfd_elf_get_elf_syms (abfd, hdr, extsymcount, extsymoff,
@@ -3721,13 +3720,16 @@ error_free_dyn:
if (isymbuf == NULL)
goto error_return;
- /* We store a pointer to the hash table entry for each external
- symbol. */
- amt = extsymcount * sizeof (struct elf_link_hash_entry *);
- sym_hash = (struct elf_link_hash_entry **) bfd_alloc (abfd, amt);
if (sym_hash == NULL)
- goto error_free_sym;
- elf_sym_hashes (abfd) = sym_hash;
+ {
+ /* We store a pointer to the hash table entry for each
+ external symbol. */
+ amt = extsymcount * sizeof (struct elf_link_hash_entry *);
+ sym_hash = (struct elf_link_hash_entry **) bfd_zalloc (abfd, amt);
+ if (sym_hash == NULL)
+ goto error_free_sym;
+ elf_sym_hashes (abfd) = sym_hash;
+ }
}
if (dynamic)
@@ -3777,8 +3779,7 @@ error_free_dyn:
}
tabsize = htab->root.table.size * sizeof (struct bfd_hash_entry *);
- hashsize = extsymcount * sizeof (struct elf_link_hash_entry *);
- old_tab = bfd_malloc (tabsize + entsize + hashsize);
+ old_tab = bfd_malloc (tabsize + entsize);
if (old_tab == NULL)
goto error_free_vers;
@@ -3794,12 +3795,10 @@ error_free_dyn:
notice_as_needed, 0, NULL))
goto error_free_vers;
- /* Clone the symbol table and sym hashes. Remember some
- pointers into the symbol table, and dynamic symbol count. */
- old_hash = (char *) old_tab + tabsize;
- old_ent = (char *) old_hash + hashsize;
+ /* Clone the symbol table. Remember some pointers into the
+ symbol table, and dynamic symbol count. */
+ old_ent = (char *) old_tab + tabsize;
memcpy (old_tab, htab->root.table.table, tabsize);
- memcpy (old_hash, sym_hash, hashsize);
old_undefs = htab->root.undefs;
old_undefs_tail = htab->root.undefs_tail;
old_table = htab->root.table.table;
@@ -3856,7 +3855,6 @@ error_free_dyn:
flags = BSF_NO_FLAGS;
sec = NULL;
value = isym->st_value;
- *sym_hash = NULL;
common = bed->common_definition (isym);
bind = ELF_ST_BIND (isym->st_info);
@@ -4490,14 +4488,13 @@ error_free_dyn:
/* Restore the symbol table. */
if (bed->as_needed_cleanup)
(*bed->as_needed_cleanup) (abfd, info);
- old_hash = (char *) old_tab + tabsize;
- old_ent = (char *) old_hash + hashsize;
- sym_hash = elf_sym_hashes (abfd);
+ old_ent = (char *) old_tab + tabsize;
+ memset (elf_sym_hashes (abfd), 0,
+ extsymcount * sizeof (struct elf_link_hash_entry *));
htab->root.table.table = old_table;
htab->root.table.size = old_size;
htab->root.table.count = old_count;
memcpy (htab->root.table.table, old_tab, tabsize);
- memcpy (sym_hash, old_hash, hashsize);
htab->root.undefs = old_undefs;
htab->root.undefs_tail = old_undefs_tail;
_bfd_elf_strtab_restore_size (htab->dynstr, old_dynstr_size);
@@ -4678,7 +4675,7 @@ error_free_dyn:
struct elf_link_hash_entry *hlook;
asection *slook;
bfd_vma vlook;
- size_t i, j, idx;
+ size_t i, j, idx = 0;
hlook = weaks;
weaks = hlook->u.weakdef;
diff --git a/bfd/elfn32-mips.c b/bfd/elfn32-mips.c
index 18c3d40da..131de33fe 100644
--- a/bfd/elfn32-mips.c
+++ b/bfd/elfn32-mips.c
@@ -2587,6 +2587,23 @@ static reloc_howto_type elf_mips_gnu_rela16_s2 =
0, /* src_mask */
0x0000ffff, /* dst_mask */
TRUE); /* pcrel_offset */
+
+/* 32 bit pc-relative. Used for compact EH tables. */
+static reloc_howto_type elf_mips_gnu_pcrel32 =
+ HOWTO (R_MIPS_PC32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_PC32", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE); /* pcrel_offset */
+
/* Originally a VxWorks extension, but now used for other systems too. */
static reloc_howto_type elf_mips_copy_howto =
@@ -2597,7 +2614,7 @@ static reloc_howto_type elf_mips_copy_howto =
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
- bfd_elf_generic_reloc, /* special_function */
+ _bfd_mips_elf_generic_reloc, /* special_function */
"R_MIPS_COPY", /* name */
FALSE, /* partial_inplace */
0x0, /* src_mask */
@@ -2613,7 +2630,7 @@ static reloc_howto_type elf_mips_jump_slot_howto =
FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
- bfd_elf_generic_reloc, /* special_function */
+ _bfd_mips_elf_generic_reloc, /* special_function */
"R_MIPS_JUMP_SLOT", /* name */
FALSE, /* partial_inplace */
0x0, /* src_mask */
@@ -3073,6 +3090,8 @@ bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
return &elf_mips_gnu_vtinherit_howto;
case BFD_RELOC_VTABLE_ENTRY:
return &elf_mips_gnu_vtentry_howto;
+ case BFD_RELOC_32_PCREL:
+ return &elf_mips_gnu_pcrel32;
case BFD_RELOC_MIPS_COPY:
return &elf_mips_copy_howto;
case BFD_RELOC_MIPS_JUMP_SLOT:
@@ -3121,6 +3140,8 @@ bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
return &elf_mips_gnu_rel16_s2;
if (strcasecmp (elf_mips_gnu_rela16_s2.name, r_name) == 0)
return &elf_mips_gnu_rela16_s2;
+ if (strcasecmp (elf_mips_gnu_pcrel32.name, r_name) == 0)
+ return &elf_mips_gnu_pcrel32;
if (strcasecmp (elf_mips_copy_howto.name, r_name) == 0)
return &elf_mips_copy_howto;
if (strcasecmp (elf_mips_jump_slot_howto.name, r_name) == 0)
@@ -3145,6 +3166,8 @@ mips_elf_n32_rtype_to_howto (unsigned int r_type, bfd_boolean rela_p)
return &elf_mips_gnu_rela16_s2;
else
return &elf_mips_gnu_rel16_s2;
+ case R_MIPS_PC32:
+ return &elf_mips_gnu_pcrel32;
case R_MIPS_COPY:
return &elf_mips_copy_howto;
case R_MIPS_JUMP_SLOT:
diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c
index fa807713c..a3b50f30d 100644
--- a/bfd/elfxx-mips.c
+++ b/bfd/elfxx-mips.c
@@ -9354,7 +9354,7 @@ _bfd_mips_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
const char *name;
bfd_vma value = 0;
reloc_howto_type *howto;
- bfd_boolean cross_mode_jump_p;
+ bfd_boolean cross_mode_jump_p = FALSE;
/* TRUE if the relocation is a RELA relocation, rather than a
REL relocation. */
bfd_boolean rela_relocation_p = TRUE;
diff --git a/bfd/format.c b/bfd/format.c
index 2c602e50a..b0fb4831e 100644
--- a/bfd/format.c
+++ b/bfd/format.c
@@ -406,6 +406,9 @@ bfd_check_format_matches (bfd *abfd, bfd_format format, char ***matching)
}
}
+ /* We have more than one equally good match. If any of the best
+ matches is a target in config.bfd targ_defvec or targ_selvecs,
+ choose it. */
if (match_count > 1)
{
const bfd_target * const *assoc = bfd_associated_vector;
@@ -415,7 +418,8 @@ bfd_check_format_matches (bfd *abfd, bfd_format format, char ***matching)
int i = match_count;
while (--i >= 0)
- if (matching_vector[i] == right_targ)
+ if (matching_vector[i] == right_targ
+ && right_targ->match_priority <= best_match)
break;
if (i >= 0)
@@ -426,6 +430,22 @@ bfd_check_format_matches (bfd *abfd, bfd_format format, char ***matching)
}
}
+ /* We still have more than one equally good match, and at least some
+ of the targets support match priority. Choose the first of the
+ best matches. */
+ if (match_count > 1 && best_count != match_count)
+ {
+ int i;
+
+ for (i = 0; i < match_count; i++)
+ {
+ right_targ = matching_vector[i];
+ if (right_targ->match_priority <= best_match)
+ break;
+ }
+ match_count = 1;
+ }
+
/* There is way too much undoing of half-known state here. We
really shouldn't iterate on live bfd's. Note that saving the
whole bfd and restoring it would be even worse; the first thing
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index 6a4b5724f..1c4d36f91 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -2376,6 +2376,21 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_MSP430_16_BYTE",
"BFD_RELOC_MSP430_2X_PCREL",
"BFD_RELOC_MSP430_RL_PCREL",
+ "BFD_RELOC_MSP430_ABS8",
+ "BFD_RELOC_MSP430X_PCR20_EXT_SRC",
+ "BFD_RELOC_MSP430X_PCR20_EXT_DST",
+ "BFD_RELOC_MSP430X_PCR20_EXT_ODST",
+ "BFD_RELOC_MSP430X_ABS20_EXT_SRC",
+ "BFD_RELOC_MSP430X_ABS20_EXT_DST",
+ "BFD_RELOC_MSP430X_ABS20_EXT_ODST",
+ "BFD_RELOC_MSP430X_ABS20_ADR_SRC",
+ "BFD_RELOC_MSP430X_ABS20_ADR_DST",
+ "BFD_RELOC_MSP430X_PCR16",
+ "BFD_RELOC_MSP430X_PCR20_CALL",
+ "BFD_RELOC_MSP430X_ABS16",
+ "BFD_RELOC_MSP430_ABS_HI16",
+ "BFD_RELOC_MSP430_PREL31",
+ "BFD_RELOC_MSP430_SYM_DIFF",
"BFD_RELOC_NIOS2_S16",
"BFD_RELOC_NIOS2_U16",
"BFD_RELOC_NIOS2_CALL26",
diff --git a/bfd/reloc.c b/bfd/reloc.c
index e93b3b9da..57df51b39 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -5662,6 +5662,36 @@ ENUMX
BFD_RELOC_MSP430_2X_PCREL
ENUMX
BFD_RELOC_MSP430_RL_PCREL
+ENUMX
+ BFD_RELOC_MSP430_ABS8
+ENUMX
+ BFD_RELOC_MSP430X_PCR20_EXT_SRC
+ENUMX
+ BFD_RELOC_MSP430X_PCR20_EXT_DST
+ENUMX
+ BFD_RELOC_MSP430X_PCR20_EXT_ODST
+ENUMX
+ BFD_RELOC_MSP430X_ABS20_EXT_SRC
+ENUMX
+ BFD_RELOC_MSP430X_ABS20_EXT_DST
+ENUMX
+ BFD_RELOC_MSP430X_ABS20_EXT_ODST
+ENUMX
+ BFD_RELOC_MSP430X_ABS20_ADR_SRC
+ENUMX
+ BFD_RELOC_MSP430X_ABS20_ADR_DST
+ENUMX
+ BFD_RELOC_MSP430X_PCR16
+ENUMX
+ BFD_RELOC_MSP430X_PCR20_CALL
+ENUMX
+ BFD_RELOC_MSP430X_ABS16
+ENUMX
+ BFD_RELOC_MSP430_ABS_HI16
+ENUMX
+ BFD_RELOC_MSP430_PREL31
+ENUMX
+ BFD_RELOC_MSP430_SYM_DIFF
ENUMDOC
msp430 specific relocation codes
diff --git a/bfd/srec.c b/bfd/srec.c
index 622677338..ded9e76ca 100644
--- a/bfd/srec.c
+++ b/bfd/srec.c
@@ -870,6 +870,7 @@ srec_set_section_contents (bfd *abfd,
file_ptr offset,
bfd_size_type bytes_to_do)
{
+ int opb = bfd_octets_per_byte (abfd);
tdata_type *tdata = abfd->tdata.srec_data;
srec_data_list_type *entry;
@@ -892,16 +893,16 @@ srec_set_section_contents (bfd *abfd,
regardless of the siez of the addresses. */
if (S3Forced)
tdata->type = 3;
- else if ((section->lma + offset + bytes_to_do - 1) <= 0xffff)
+ else if ((section->lma + (offset + bytes_to_do) / opb - 1) <= 0xffff)
; /* The default, S1, is OK. */
- else if ((section->lma + offset + bytes_to_do - 1) <= 0xffffff
+ else if ((section->lma + (offset + bytes_to_do) / opb - 1) <= 0xffffff
&& tdata->type <= 2)
tdata->type = 2;
else
tdata->type = 3;
entry->data = data;
- entry->where = section->lma + offset;
+ entry->where = section->lma + offset / opb;
entry->size = bytes_to_do;
/* Sort the records by address. Optimize for the common case of
diff --git a/bfd/targets.c b/bfd/targets.c
index c9fbbc2fe..c6794ee50 100644
--- a/bfd/targets.c
+++ b/bfd/targets.c
@@ -1,7 +1,5 @@
/* Generic target-file-type support for the BFD library.
- Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
- Free Software Foundation, Inc.
+ Copyright 1990-2013 Free Software Foundation, Inc.
Written by Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
@@ -668,6 +666,7 @@ extern const bfd_target bfd_elf32_mn10200_vec;
extern const bfd_target bfd_elf32_mn10300_vec;
extern const bfd_target bfd_elf32_mt_vec;
extern const bfd_target bfd_elf32_msp430_vec;
+extern const bfd_target bfd_elf32_msp430_ti_vec;
extern const bfd_target bfd_elf32_nbigmips_vec;
extern const bfd_target bfd_elf32_nlittlemips_vec;
extern const bfd_target bfd_elf32_ntradbigmips_vec;
@@ -1047,6 +1046,7 @@ static const bfd_target * const _bfd_target_vector[] =
&bfd_elf32_mn10300_vec,
&bfd_elf32_mt_vec,
&bfd_elf32_msp430_vec,
+ &bfd_elf32_msp430_ti_vec,
#ifdef BFD64
&bfd_elf32_nbigmips_vec,
&bfd_elf32_nlittlemips_vec,
diff --git a/bfd/version.h b/bfd/version.h
index 291d2f22f..5a9850410 100644
--- a/bfd/version.h
+++ b/bfd/version.h
@@ -1,4 +1,4 @@
-#define BFD_VERSION_DATE 20130429
+#define BFD_VERSION_DATE 20130524
#define BFD_VERSION @bfd_version@
#define BFD_VERSION_STRING @bfd_version_package@ @bfd_version_string@
#define REPORT_BUGS_TO @report_bugs_to@
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 58f7657fd..fa6abb521 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,28 @@
+2013-05-15 Cary Coutant <ccoutant@google.com>
+
+ * dwarf.c (SAFE_BYTE_GET64): Correct end-of-buffer check;
+ don't increment PTR.
+ (decode_location_expression): DW_OP_const2u should read 2 bytes.
+ (display_debug_lines_decoded): Adjust formatting.
+ * elfcomm.c (byte_get_little_endian): Add cases for 5-, 6-, and
+ 7-byte reads.
+ (byte_get_big_endian): Likewise.
+ (byte_get_signed): Likewise.
+
+2013-05-09 Andrew Pinski <apinski@cavium.com>
+
+ * doc/binutils.texi: Document -Mvirt disassembler option.
+
+2013-05-02 Nick Clifton <nickc@redhat.com>
+
+ * readelf.c: Add support for MSP430X architecture.
+
+2013-05-02 Nick Clifton <nickc@redhat.com>
+
+ * dwarf.c (display_debug_lines_raw): Do not treat .debug_line.dwo
+ sections as if they were fragmentary .debug_line sections.
+ (display_debug_lines_decoded): Likewise.
+
2013-04-29 Nick Clifton <nickc@redhat.com>
* dwarf.c (read_debug_line_header): New function. Reads in a
diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi
index 0bb1d92ad..aaa0bdbdb 100644
--- a/binutils/doc/binutils.texi
+++ b/binutils/doc/binutils.texi
@@ -2113,6 +2113,9 @@ Print the 'raw' instruction mnemonic instead of some pseudo
instruction mnemonic. I.e., print 'daddu' or 'or' instead of 'move',
'sll' instead of 'nop', etc.
+@item virt
+Disassemble the virtualization ASE instructions.
+
@item gpr-names=@var{ABI}
Print GPR (general-purpose register) names as appropriate
for the specified ABI. By default, GPR names are selected according to
diff --git a/binutils/dwarf.c b/binutils/dwarf.c
index b11169b7b..862a060bd 100644
--- a/binutils/dwarf.c
+++ b/binutils/dwarf.c
@@ -337,13 +337,12 @@ read_uleb128 (unsigned char * data,
#define SAFE_BYTE_GET64(PTR, HIGH, LOW, END) \
do \
{ \
- if (((PTR) + 8) < (END)) \
+ if (((PTR) + 8) <= (END)) \
{ \
byte_get_64 ((PTR), (HIGH), (LOW)); \
} \
else \
{ \
- PTR = END; \
* (LOW) = * (HIGH) = 0; \
} \
} \
@@ -883,7 +882,7 @@ decode_location_expression (unsigned char * data,
printf ("DW_OP_const1s: %ld", (long) svalue);
break;
case DW_OP_const2u:
- SAFE_BYTE_GET_AND_INC (uvalue, data, 1, end);
+ SAFE_BYTE_GET_AND_INC (uvalue, data, 2, end);
printf ("DW_OP_const2u: %lu", (unsigned long) uvalue);
break;
case DW_OP_const2s:
@@ -2659,7 +2658,10 @@ display_debug_lines_raw (struct dwarf_section *section,
unsigned char *end_of_sequence;
int i;
- if (const_strneq (section->name, ".debug_line."))
+ if (const_strneq (section->name, ".debug_line.")
+ /* Note: the following does not apply to .debug_line.dwo sections.
+ These are full debug_line sections. */
+ && strcmp (section->name, ".debug_line.dwo") != 0)
{
/* Sections named .debug_line.<foo> are fragments of a .debug_line
section containing just the Line Number Statements. They are
@@ -2668,9 +2670,9 @@ display_debug_lines_raw (struct dwarf_section *section,
garbage collection decides to discard a .text.<foo> section it
can then also discard the line number information in .debug_line.<foo>.
- Since the section is a fragmnent it does not have the details
+ Since the section is a fragment it does not have the details
needed to fill out a LineInfo structure, so instead we use the
- details from the last one we processed. */
+ details from the last full debug_line section that we processed. */
end_of_sequence = end;
standard_opcodes = NULL;
linfo = saved_linfo;
@@ -2994,18 +2996,12 @@ display_debug_lines_decoded (struct dwarf_section *section,
unsigned char **directory_table = NULL;
unsigned int n_directories = 0;
- if (const_strneq (section->name, ".debug_line."))
+ if (const_strneq (section->name, ".debug_line.")
+ /* Note: the following does not apply to .debug_line.dwo sections.
+ These are full debug_line sections. */
+ && strcmp (section->name, ".debug_line.dwo") != 0)
{
- /* Sections named .debug_line.<foo> are fragments of a .debug_line
- section containing just the Line Number Statements. They are
- created by the assembler and intended to be used alongside gcc's
- -ffunction-sections command line option. When the linker's
- garbage collection decides to discard a .text.<foo> section it
- can then also discard the line number information in .debug_line.<foo>.
-
- Since the section is a fragmnent it does not have the details
- needed to fill out a LineInfo structure, so instead we use the
- details from the last one we processed. */
+ /* See comment in display_debug_lines_raw(). */
end_of_sequence = end;
standard_opcodes = NULL;
linfo = saved_linfo;
@@ -3187,7 +3183,8 @@ display_debug_lines_decoded (struct dwarf_section *section,
break;
case DW_LNE_set_address:
SAFE_BYTE_GET_AND_INC (state_machine_regs.address,
- op_code_data, ext_op_code_len - bytes_read - 1,
+ op_code_data,
+ ext_op_code_len - bytes_read - 1,
end);
state_machine_regs.op_index = 0;
break;
diff --git a/binutils/elfcomm.c b/binutils/elfcomm.c
index 1a1fae98b..d5b431388 100644
--- a/binutils/elfcomm.c
+++ b/binutils/elfcomm.c
@@ -150,6 +150,57 @@ byte_get_little_endian (unsigned char *field, int size)
| (((unsigned long) (field[2])) << 16)
| (((unsigned long) (field[3])) << 24);
+ case 5:
+ if (sizeof (elf_vma) == 8)
+ return ((elf_vma) (field[0]))
+ | (((elf_vma) (field[1])) << 8)
+ | (((elf_vma) (field[2])) << 16)
+ | (((elf_vma) (field[3])) << 24)
+ | (((elf_vma) (field[4])) << 32);
+ else if (sizeof (elf_vma) == 4)
+ /* We want to extract data from an 8 byte wide field and
+ place it into a 4 byte wide field. Since this is a little
+ endian source we can just use the 4 byte extraction code. */
+ return ((unsigned long) (field[0]))
+ | (((unsigned long) (field[1])) << 8)
+ | (((unsigned long) (field[2])) << 16)
+ | (((unsigned long) (field[3])) << 24);
+
+ case 6:
+ if (sizeof (elf_vma) == 8)
+ return ((elf_vma) (field[0]))
+ | (((elf_vma) (field[1])) << 8)
+ | (((elf_vma) (field[2])) << 16)
+ | (((elf_vma) (field[3])) << 24)
+ | (((elf_vma) (field[4])) << 32)
+ | (((elf_vma) (field[5])) << 40);
+ else if (sizeof (elf_vma) == 4)
+ /* We want to extract data from an 8 byte wide field and
+ place it into a 4 byte wide field. Since this is a little
+ endian source we can just use the 4 byte extraction code. */
+ return ((unsigned long) (field[0]))
+ | (((unsigned long) (field[1])) << 8)
+ | (((unsigned long) (field[2])) << 16)
+ | (((unsigned long) (field[3])) << 24);
+
+ case 7:
+ if (sizeof (elf_vma) == 8)
+ return ((elf_vma) (field[0]))
+ | (((elf_vma) (field[1])) << 8)
+ | (((elf_vma) (field[2])) << 16)
+ | (((elf_vma) (field[3])) << 24)
+ | (((elf_vma) (field[4])) << 32)
+ | (((elf_vma) (field[5])) << 40)
+ | (((elf_vma) (field[6])) << 48);
+ else if (sizeof (elf_vma) == 4)
+ /* We want to extract data from an 8 byte wide field and
+ place it into a 4 byte wide field. Since this is a little
+ endian source we can just use the 4 byte extraction code. */
+ return ((unsigned long) (field[0]))
+ | (((unsigned long) (field[1])) << 8)
+ | (((unsigned long) (field[2])) << 16)
+ | (((unsigned long) (field[3])) << 24);
+
case 8:
if (sizeof (elf_vma) == 8)
return ((elf_vma) (field[0]))
@@ -197,6 +248,63 @@ byte_get_big_endian (unsigned char *field, int size)
| (((unsigned long) (field[1])) << 16)
| (((unsigned long) (field[0])) << 24);
+ case 5:
+ if (sizeof (elf_vma) == 8)
+ return ((elf_vma) (field[4]))
+ | (((elf_vma) (field[3])) << 8)
+ | (((elf_vma) (field[2])) << 16)
+ | (((elf_vma) (field[1])) << 24)
+ | (((elf_vma) (field[0])) << 32);
+ else if (sizeof (elf_vma) == 4)
+ {
+ /* Although we are extracting data from an 8 byte wide field,
+ we are returning only 4 bytes of data. */
+ field += 1;
+ return ((unsigned long) (field[3]))
+ | (((unsigned long) (field[2])) << 8)
+ | (((unsigned long) (field[1])) << 16)
+ | (((unsigned long) (field[0])) << 24);
+ }
+
+ case 6:
+ if (sizeof (elf_vma) == 8)
+ return ((elf_vma) (field[5]))
+ | (((elf_vma) (field[4])) << 8)
+ | (((elf_vma) (field[3])) << 16)
+ | (((elf_vma) (field[2])) << 24)
+ | (((elf_vma) (field[1])) << 32)
+ | (((elf_vma) (field[0])) << 40);
+ else if (sizeof (elf_vma) == 4)
+ {
+ /* Although we are extracting data from an 8 byte wide field,
+ we are returning only 4 bytes of data. */
+ field += 2;
+ return ((unsigned long) (field[3]))
+ | (((unsigned long) (field[2])) << 8)
+ | (((unsigned long) (field[1])) << 16)
+ | (((unsigned long) (field[0])) << 24);
+ }
+
+ case 7:
+ if (sizeof (elf_vma) == 8)
+ return ((elf_vma) (field[6]))
+ | (((elf_vma) (field[5])) << 8)
+ | (((elf_vma) (field[4])) << 16)
+ | (((elf_vma) (field[3])) << 24)
+ | (((elf_vma) (field[2])) << 32)
+ | (((elf_vma) (field[1])) << 40)
+ | (((elf_vma) (field[0])) << 48);
+ else if (sizeof (elf_vma) == 4)
+ {
+ /* Although we are extracting data from an 8 byte wide field,
+ we are returning only 4 bytes of data. */
+ field += 3;
+ return ((unsigned long) (field[3]))
+ | (((unsigned long) (field[2])) << 8)
+ | (((unsigned long) (field[1])) << 16)
+ | (((unsigned long) (field[0])) << 24);
+ }
+
case 8:
if (sizeof (elf_vma) == 8)
return ((elf_vma) (field[7]))
@@ -209,7 +317,7 @@ byte_get_big_endian (unsigned char *field, int size)
| (((elf_vma) (field[0])) << 56);
else if (sizeof (elf_vma) == 4)
{
- /* Although we are extracing data from an 8 byte wide field,
+ /* Although we are extracting data from an 8 byte wide field,
we are returning only 4 bytes of data. */
field += 4;
return ((unsigned long) (field[3]))
@@ -235,9 +343,18 @@ byte_get_signed (unsigned char *field, int size)
return (x ^ 0x80) - 0x80;
case 2:
return (x ^ 0x8000) - 0x8000;
+ case 3:
+ return (x ^ 0x800000) - 0x800000;
case 4:
return (x ^ 0x80000000) - 0x80000000;
+ case 5:
+ case 6:
+ case 7:
case 8:
+ /* Reads of 5-, 6-, and 7-byte numbers are the result of
+ trying to read past the end of a buffer, and will therefore
+ not have meaningful values, so we don't try to deal with
+ the sign in these cases. */
return x;
default:
abort ();
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 8298557fa..cd429ef22 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -131,6 +131,7 @@
#include "elf/moxie.h"
#include "elf/mt.h"
#include "elf/msp430.h"
+#include "elf/nios2.h"
#include "elf/or32.h"
#include "elf/pj.h"
#include "elf/ppc.h"
@@ -153,8 +154,6 @@
#include "elf/xstormy16.h"
#include "elf/xtensa.h"
-#include "elf/nios2.h"
-
#include "getopt.h"
#include "libiberty.h"
#include "safe-ctype.h"
@@ -903,6 +902,17 @@ get_reloc_symindex (bfd_vma reloc_info)
return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
}
+static inline bfd_boolean
+uses_msp430x_relocs (void)
+{
+ return
+ elf_header.e_machine == EM_MSP430 /* Paranoia. */
+ /* GCC uses osabi == ELFOSBI_STANDALONE. */
+ && (((elf_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
+ /* TI compiler uses ELFOSABI_NONE. */
+ || (elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
+}
+
/* Display the contents of the relocation data found at the specified
offset. */
@@ -1125,6 +1135,11 @@ dump_relocations (FILE * file,
break;
case EM_MSP430:
+ if (uses_msp430x_relocs ())
+ {
+ rtype = elf_msp430x_reloc_type (type);
+ break;
+ }
case EM_MSP430_OLD:
rtype = elf_msp430_reloc_type (type);
break;
@@ -2781,6 +2796,32 @@ get_machine_flags (unsigned e_flags, unsigned e_machine)
if ((e_flags & EF_C6000_REL))
strcat (buf, ", relocatable module");
break;
+
+ case EM_MSP430:
+ strcat (buf, _(": architecture variant: "));
+ switch (e_flags & EF_MSP430_MACH)
+ {
+ case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
+ case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
+ case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
+ case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
+ case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
+ case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
+ case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
+ case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
+ case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
+ case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
+ case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
+ case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
+ case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
+ case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
+ case E_MSP430_MACH_MSP430X : strcat (buf, "MSP430X"); break;
+ default:
+ strcat (buf, _(": unknown")); break;
+ }
+
+ if (e_flags & ~ EF_MSP430_MACH)
+ strcat (buf, _(": unknown extra flag bits also present"));
}
}
@@ -3206,6 +3247,18 @@ get_tic6x_section_type_name (unsigned int sh_type)
}
static const char *
+get_msp430x_section_type_name (unsigned int sh_type)
+{
+ switch (sh_type)
+ {
+ case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
+ case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
+ case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
+ default: return NULL;
+ }
+}
+
+static const char *
get_section_type_name (unsigned int sh_type)
{
static char buff[32];
@@ -3271,6 +3324,9 @@ get_section_type_name (unsigned int sh_type)
case EM_TI_C6000:
result = get_tic6x_section_type_name (sh_type);
break;
+ case EM_MSP430:
+ result = get_msp430x_section_type_name (sh_type);
+ break;
default:
result = NULL;
break;
@@ -8995,8 +9051,13 @@ get_symbol_type (unsigned int type)
default:
if (type >= STT_LOPROC && type <= STT_HIPROC)
{
- if (elf_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
- return "THUMB_FUNC";
+ if (elf_header.e_machine == EM_ARM)
+ {
+ if (type == STT_ARM_TFUNC)
+ return "THUMB_FUNC";
+ if (type == STT_ARM_16BIT)
+ return "THUMB_LABEL";
+ }
if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
return "REGISTER";
@@ -9962,6 +10023,60 @@ target_specific_reloc_handling (Elf_Internal_Rela * reloc,
switch (elf_header.e_machine)
{
+ case EM_MSP430:
+ case EM_MSP430_OLD:
+ {
+ static Elf_Internal_Sym * saved_sym = NULL;
+
+ switch (reloc_type)
+ {
+ case 10: /* R_MSP430_SYM_DIFF */
+ if (uses_msp430x_relocs ())
+ break;
+ case 21: /* R_MSP430X_SYM_DIFF */
+ saved_sym = symtab + get_reloc_symindex (reloc->r_info);
+ return TRUE;
+
+ case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
+ case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
+ goto handle_sym_diff;
+
+ case 5: /* R_MSP430_16_BYTE */
+ case 9: /* R_MSP430_8 */
+ if (uses_msp430x_relocs ())
+ break;
+ goto handle_sym_diff;
+
+ case 2: /* R_MSP430_ABS16 */
+ case 15: /* R_MSP430X_ABS16 */
+ if (! uses_msp430x_relocs ())
+ break;
+ goto handle_sym_diff;
+
+ handle_sym_diff:
+ if (saved_sym != NULL)
+ {
+ bfd_vma value;
+
+ value = reloc->r_addend
+ + (symtab[get_reloc_symindex (reloc->r_info)].st_value
+ - saved_sym->st_value);
+
+ byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
+
+ saved_sym = NULL;
+ return TRUE;
+ }
+ break;
+
+ default:
+ if (saved_sym != NULL)
+ error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc"));
+ break;
+ }
+ break;
+ }
+
case EM_MN10300:
case EM_CYGNUS_MN10300:
{
@@ -10101,7 +10216,7 @@ is_32bit_abs_reloc (unsigned int reloc_type)
return reloc_type == 1; /* R_MOXIE_32. */
case EM_MSP430_OLD:
case EM_MSP430:
- return reloc_type == 1; /* R_MSP43_32. */
+ return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
case EM_MT:
return reloc_type == 2; /* R_MT_32. */
case EM_ALTERA_NIOS2:
@@ -10353,6 +10468,8 @@ is_16bit_abs_reloc (unsigned int reloc_type)
case EM_M32C:
return reloc_type == 1; /* R_M32C_16 */
case EM_MSP430:
+ if (uses_msp430x_relocs ())
+ return reloc_type == 2; /* R_MSP430_ABS16. */
case EM_MSP430_OLD:
return reloc_type == 5; /* R_MSP430_16_BYTE. */
case EM_ALTERA_NIOS2:
@@ -11906,6 +12023,79 @@ display_raw_attribute (unsigned char * p, unsigned char * end)
putchar ('\n');
}
+static unsigned char *
+display_msp430x_attribute (unsigned char * p,
+ const unsigned char * const end)
+{
+ unsigned int len;
+ int val;
+ int tag;
+
+ tag = read_uleb128 (p, & len, end);
+ p += len;
+
+ switch (tag)
+ {
+ case OFBA_MSPABI_Tag_ISA:
+ val = read_uleb128 (p, &len, end);
+ p += len;
+ printf (" Tag_ISA: ");
+ switch (val)
+ {
+ case 0: printf (_("None\n")); break;
+ case 1: printf (_("MSP430\n")); break;
+ case 2: printf (_("MSP430X\n")); break;
+ default: printf ("??? (%d)\n", val); break;
+ }
+ break;
+
+ case OFBA_MSPABI_Tag_Code_Model:
+ val = read_uleb128 (p, &len, end);
+ p += len;
+ printf (" Tag_Code_Model: ");
+ switch (val)
+ {
+ case 0: printf (_("None\n")); break;
+ case 1: printf (_("Small\n")); break;
+ case 2: printf (_("Large\n")); break;
+ default: printf ("??? (%d)\n", val); break;
+ }
+ break;
+
+ case OFBA_MSPABI_Tag_Data_Model:
+ val = read_uleb128 (p, &len, end);
+ p += len;
+ printf (" Tag_Data_Model: ");
+ switch (val)
+ {
+ case 0: printf (_("None\n")); break;
+ case 1: printf (_("Small\n")); break;
+ case 2: printf (_("Large\n")); break;
+ case 3: printf (_("Restricted Large\n")); break;
+ default: printf ("??? (%d)\n", val); break;
+ }
+ break;
+
+ default:
+ printf (_(" <unknown tag %d>: "), tag);
+
+ if (tag & 1)
+ {
+ printf ("\"%s\"\n", p);
+ p += strlen ((char *) p) + 1;
+ }
+ else
+ {
+ val = read_uleb128 (p, &len, end);
+ p += len;
+ printf ("%d (0x%x)\n", val, val);
+ }
+ break;
+ }
+
+ return p;
+}
+
static int
process_attributes (FILE * file,
const char * public_name,
@@ -12077,6 +12267,13 @@ process_tic6x_specific (FILE * file)
display_tic6x_attribute, NULL);
}
+static int
+process_msp430x_specific (FILE * file)
+{
+ return process_attributes (file, "mspabi", SHT_MSP430_ATTRIBUTES,
+ display_msp430x_attribute, NULL);
+}
+
/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
Print the Address, Access and Initial fields of an entry at VMA ADDR
and return the VMA of the next entry. */
@@ -13555,6 +13752,8 @@ process_arch_specific (FILE * file)
case EM_TI_C6000:
return process_tic6x_specific (file);
break;
+ case EM_MSP430:
+ return process_msp430x_specific (file);
default:
break;
}
diff --git a/binutils/testsuite/ChangeLog b/binutils/testsuite/ChangeLog
index 06fd5e443..37cb9d675 100644
--- a/binutils/testsuite/ChangeLog
+++ b/binutils/testsuite/ChangeLog
@@ -1,3 +1,12 @@
+2013-05-02 Nick Clifton <nickc@redhat.com>
+
+ * readelf.exp: Expect -wi test to fail for the MSP430.
+
+2013-05-01 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * lib/binutils-common.exp (is_elf_format): Also exclude
+ *-*-linux*ecoff*.
+
2013-02-26 Nick Clifton <nickc@redhat.com>
PR binutils/15191
diff --git a/binutils/testsuite/binutils-all/readelf.exp b/binutils/testsuite/binutils-all/readelf.exp
index c1d7286de..db56a8685 100644
--- a/binutils/testsuite/binutils-all/readelf.exp
+++ b/binutils/testsuite/binutils-all/readelf.exp
@@ -1,5 +1,4 @@
-# Copyright 1999, 2000, 2001, 2003, 2004, 2007, 2009, 2012
-# Free Software Foundation, Inc.
+# Copyright 1999-2013 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -196,6 +195,9 @@ proc readelf_wi_test {} {
".*\(DW_OP_addr: 0\).*"
}
+ # The MSP430 in LARGE mode does not generate a DW_OP_addr.
+ setup_xfail msp430*-*-*
+
foreach looked_for $sought {
set lines [grep $output $looked_for]
if ![llength $lines] then {
diff --git a/binutils/testsuite/lib/binutils-common.exp b/binutils/testsuite/lib/binutils-common.exp
index 68efb90c7..af0040ec0 100644
--- a/binutils/testsuite/lib/binutils-common.exp
+++ b/binutils/testsuite/lib/binutils-common.exp
@@ -44,6 +44,7 @@ proc is_elf_format {} {
}
if { [istarget *-*-linux*aout*]
+ || [istarget *-*-linux*ecoff*]
|| [istarget *-*-linux*oldld*]
|| [istarget h8500-*-rtems*]
|| [istarget i960-*-rtems*]
diff --git a/config/ChangeLog b/config/ChangeLog
index c6e8b256e..cdc733c70 100644
--- a/config/ChangeLog
+++ b/config/ChangeLog
@@ -1,3 +1,13 @@
+2013-03-27 Kai Tietz <ktietz@redhat.com>
+
+ * dfp.m4: Add support for cygwin x64 target.
+ * picflag.m4: Likewise.
+
+2013-02-25 H.J. Lu <hongjiu.lu@intel.com>
+
+ * bootstrap-asan.mk (POSTSTAGE1_LDFLAGS): Add
+ -B$$r/prev-$(TARGET_SUBDIR)/libsanitizer/asan/.
+
2013-01-15 Richard Biener <rguenther@suse.de>
PR other/55973
diff --git a/config/bootstrap-asan.mk b/config/bootstrap-asan.mk
index d37a9da6b..e3f34f5ad 100644
--- a/config/bootstrap-asan.mk
+++ b/config/bootstrap-asan.mk
@@ -3,4 +3,5 @@
STAGE2_CFLAGS += -fsanitize=address
STAGE3_CFLAGS += -fsanitize=address
POSTSTAGE1_LDFLAGS += -fsanitize=address -static-libasan \
+ -B$$r/prev-$(TARGET_SUBDIR)/libsanitizer/asan/ \
-B$$r/prev-$(TARGET_SUBDIR)/libsanitizer/asan/.libs
diff --git a/config/dfp.m4 b/config/dfp.m4
index e971db4dc..48683f0f9 100644
--- a/config/dfp.m4
+++ b/config/dfp.m4
@@ -23,7 +23,7 @@ Valid choices are 'yes', 'bid', 'dpd', and 'no'.]) ;;
powerpc*-*-linux* | i?86*-*-linux* | x86_64*-*-linux* | s390*-*-linux* | \
i?86*-*-gnu* | \
i?86*-*-mingw* | x86_64*-*-mingw* | \
- i?86*-*-cygwin*)
+ i?86*-*-cygwin* | x86_64*-*-cygwin*)
enable_decimal_float=yes
;;
*)
diff --git a/config/picflag.m4 b/config/picflag.m4
index bd818125a..2ee5cd078 100644
--- a/config/picflag.m4
+++ b/config/picflag.m4
@@ -17,7 +17,9 @@ case "${$2}" in
hppa*64*-*-hpux*)
# PIC is the default for 64-bit PA HP-UX.
;;
- i[[34567]]86-*-cygwin* | i[[34567]]86-*-mingw* | x86_64-*-mingw*)
+ i[[34567]]86-*-cygwin* | x86_64-*-cygwin*)
+ ;;
+ i[[34567]]86-*-mingw* | x86_64-*-mingw*)
;;
i[[34567]]86-*-interix[[3-9]]*)
# Interix 3.x gcc -fpic/-fPIC options generate broken code.
diff --git a/gas/ChangeLog b/gas/ChangeLog
index ec756d8fc..83fb073d9 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,113 @@
+2013-05-22 Jürgen Urban <JuergenUrban@gmx.de>
+
+ * config/tc-mips.c (macro): Handle M_LQC2_AB and M_SQC2_AB.
+
+2013-05-20 Peter Bergner <bergner@vnet.ibm.com>
+
+ * config/tc-ppc.c (ppc_setup_opcodes): Use new_seg to fix error
+ and clean up warning when using PRINT_OPCODE_TABLE.
+
+2013-05-20 Alan Modra <amodra@gmail.com>
+
+ * config/tc-ppc.c (md_apply_fix): Hoist code common to insn
+ and data fixups performing shift/high adjust/sign extension on
+ fieldval. Sink fx_pcrel handling and checks. Use fixP->fx_size
+ when writing data fixups rather than recalculating size.
+
+2013-05-16 Jan-Benedict Glaw <jbglaw@lug-owl.de>
+
+ * doc/c-msp430.texi: Fix typo.
+
+2013-05-16 Tristan Gingold <gingold@adacore.com>
+
+ * config/tc-ppc.c (ppc_is_toc_sym): Symbols of class XMC_TC
+ are also TOC symbols.
+
+2013-05-16 Nick Clifton <nickc@redhat.com>
+
+ * config/tc-msp430.c: Make -mmcu recognise more part numbers.
+ Add -mcpu command to specify core type.
+ * doc/c-msp430.texi: Update documentation.
+
+2013-05-09 Andrew Pinski <apinski@cavium.com>
+
+ * config/tc-mips.c (struct mips_set_options): New ase_virt field.
+ (mips_opts): Update for the new field.
+ (file_ase_virt): New variable.
+ (ISA_SUPPORTS_VIRT_ASE): New macro.
+ (ISA_SUPPORTS_VIRT64_ASE): New macro.
+ (MIPS_CPU_ASE_VIRT): New define.
+ (is_opcode_valid): Handle ase_virt.
+ (macro_build): Handle "+J".
+ (validate_mips_insn): Likewise.
+ (mips_ip): Likewise.
+ (enum options): Add OPTION_VIRT and OPTION_NO_VIRT.
+ (md_longopts): Add mvirt and mnovirt
+ (md_parse_option): Handle OPTION_VIRT and OPTION_NO_VIRT.
+ (mips_after_parse_args): Handle ase_virt field.
+ (s_mipsset): Handle "virt" and "novirt".
+ (mips_elf_final_processing): Add a comment about virt ASE might need
+ a new flag.
+ (md_show_usage): Print out the usage of -mvirt and mno-virt options.
+ * doc/c-mips.texi: Document -mvirt and -mno-virt.
+ Document ".set virt" and ".set novirt".
+
+2013-05-09 Alan Modra <amodra@gmail.com>
+
+ * config/tc-ppc.c (md_apply_fix): Sign extend fieldval under
+ control of operand flag bits.
+
+2013-05-07 Alan Modra <amodra@gmail.com>
+
+ * config/tc-ppc.c (PPC_VLE_SPLIT16A): Delete unused macro.
+ (PPC_VLE_SPLIT16D, PPC_VLE_LO16A, PPC_VLE_LO16D): Likewise.
+ (PPC_VLE_HI16A, PPC_VLE_HI16D): Likewise.
+ (PPC_VLE_HA16A, PPC_VLE_HA16D): Likewise.
+ (md_apply_fix): Set fx_no_overflow for assorted relocations.
+ Shift and sign-extend fieldval for use by some VLE reloc
+ operand->insert functions.
+
+2013-05-06 Paul Brook <paul@codesourcery.com>
+ Catherine Moore <clm@codesourcery.com>
+
+ * config/tc-mips.c (md_pcrel_from): Handle BFD_RELOC_32_PCREL.
+ (limited_pcrel_reloc_p): Likewise.
+ (md_apply_fix): Likewise.
+ (tc_gen_reloc): Likewise.
+
+2013-05-06 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * config/tc-mips.c (limited_pcrel_reloc_p): New function.
+ (mips_fix_adjustable): Adjust pc-relative check to use
+ limited_pc_reloc_p.
+
+2013-05-02 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * config/tc-mips.c (mips_pseudo_table): Add stabd and stabs entries.
+ (s_mips_stab): Do not restrict to stabn only.
+
+2013-05-02 Nick Clifton <nickc@redhat.com>
+
+ * config/tc-msp430.c: Add support for the MSP430X architecture.
+ Add code to insert a NOP instruction after any instruction that
+ might change the interrupt state.
+ Add support for the LARGE memory model.
+ Add code to initialise the .MSP430.attributes section.
+ * config/tc-msp430.h: Add support for the MSP430X architecture.
+ * doc/c-msp430.texi: Document the new -mL and -mN command line
+ options.
+ * NEWS: Mention support for the MSP430X architecture.
+
+2013-05-01 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * configure.tgt: Replace alpha*-*-linuxecoff* pattern with
+ alpha*-*-linux*ecoff*.
+
+2013-04-30 Chao-ying Fu <Chao-ying.Fu@imgtec.com>
+
+ * config/tc-mips.c (mips_ip): Add sizelo.
+ For "+C", "+G", and "+H", set sizelo and compare against it.
+
2013-04-29 Nick Clifton <nickc@redhat.com>
* as.c (Options): Add -gdwarf-sections.
diff --git a/gas/NEWS b/gas/NEWS
index 202db36aa..29b0fdf97 100644
--- a/gas/NEWS
+++ b/gas/NEWS
@@ -1,5 +1,7 @@
-*- text -*-
+* Add support for the Texas Instruments MSP430X processor.
+
* Add -gdwarf-sections command line option to enable per-code-section
generation of DWARF .debug_line sections.
diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c
index a9b46e971..9b191bbe8 100644
--- a/gas/config/tc-mips.c
+++ b/gas/config/tc-mips.c
@@ -218,6 +218,7 @@ struct mips_set_options
int ase_dspr2;
int ase_mt;
int ase_mcu;
+ int ase_virt;
/* Whether we are assembling for the mips16 processor. 0 if we are
not, 1 if we are, and -1 if the value has not been initialized.
Changed by `.set mips16' and `.set nomips16', and the -mips16 and
@@ -292,10 +293,11 @@ static struct mips_set_options mips_opts =
{
/* isa */ ISA_UNKNOWN, /* ase_mips3d */ -1, /* ase_mdmx */ -1,
/* ase_smartmips */ 0, /* ase_dsp */ -1, /* ase_dspr2 */ -1, /* ase_mt */ -1,
- /* ase_mcu */ -1, /* mips16 */ -1, /* micromips */ -1, /* noreorder */ 0,
- /* at */ ATREG, /* warn_about_macros */ 0, /* nomove */ 0, /* nobopt */ 0,
- /* noautoextend */ 0, /* gp32 */ 0, /* fp32 */ 0, /* arch */ CPU_UNKNOWN,
- /* sym32 */ FALSE, /* soft_float */ FALSE, /* single_float */ FALSE
+ /* ase_mcu */ -1, /* ase_virt */ -1, /* mips16 */ -1,/* micromips */ -1,
+ /* noreorder */ 0, /* at */ ATREG, /* warn_about_macros */ 0,
+ /* nomove */ 0, /* nobopt */ 0, /* noautoextend */ 0, /* gp32 */ 0,
+ /* fp32 */ 0, /* arch */ CPU_UNKNOWN, /* sym32 */ FALSE,
+ /* soft_float */ FALSE, /* single_float */ FALSE
};
/* These variables are filled in with the masks of registers used.
@@ -374,6 +376,15 @@ static int file_ase_mt;
|| mips_opts.isa == ISA_MIPS64R2 \
|| mips_opts.micromips)
+/* True if -mvirt was passed or implied by arguments passed on the
+ command line (e.g., by -march). */
+static int file_ase_virt;
+
+#define ISA_SUPPORTS_VIRT_ASE (mips_opts.isa == ISA_MIPS32R2 \
+ || mips_opts.isa == ISA_MIPS64R2)
+
+#define ISA_SUPPORTS_VIRT64_ASE (mips_opts.isa == ISA_MIPS64R2)
+
/* The argument of the -march= flag. The architecture we are assembling. */
static int file_mips_arch = CPU_UNKNOWN;
static const char *mips_arch_string;
@@ -1395,6 +1406,7 @@ struct mips_cpu_info
#define MIPS_CPU_ASE_MDMX 0x0020 /* CPU implements MDMX ASE */
#define MIPS_CPU_ASE_DSPR2 0x0040 /* CPU implements DSP R2 ASE */
#define MIPS_CPU_ASE_MCU 0x0080 /* CPU implements MCU ASE */
+#define MIPS_CPU_ASE_VIRT 0x0100 /* CPU implements Virtualization ASE */
static const struct mips_cpu_info *mips_parse_cpu (const char *, const char *);
static const struct mips_cpu_info *mips_cpu_info_from_isa (int);
@@ -1472,7 +1484,9 @@ static const pseudo_typeS mips_pseudo_table[] =
{"section", s_change_section, 0},
{"short", s_cons, 1},
{"single", s_float_cons, 'f'},
+ {"stabd", s_mips_stab, 'd'},
{"stabn", s_mips_stab, 'n'},
+ {"stabs", s_mips_stab, 's'},
{"text", s_change_sec, 't'},
{"word", s_cons, 2},
@@ -2256,6 +2270,10 @@ is_opcode_valid (const struct mips_opcode *mo)
isa |= INSN_SMARTMIPS;
if (mips_opts.ase_mcu)
isa |= INSN_MCU;
+ if (mips_opts.ase_virt)
+ isa |= INSN_VIRT;
+ if (mips_opts.ase_virt && ISA_SUPPORTS_VIRT64_ASE)
+ isa |= INSN_VIRT64;
if (!opcode_is_member (mo, isa, mips_opts.arch))
return FALSE;
@@ -2742,6 +2760,28 @@ jalr_reloc_p (bfd_reloc_code_real_type reloc)
return reloc == BFD_RELOC_MIPS_JALR || reloc == BFD_RELOC_MICROMIPS_JALR;
}
+/* Return true if RELOC is a PC-relative relocation that does not have
+ full address range. */
+
+static inline bfd_boolean
+limited_pcrel_reloc_p (bfd_reloc_code_real_type reloc)
+{
+ switch (reloc)
+ {
+ case BFD_RELOC_16_PCREL_S2:
+ case BFD_RELOC_MICROMIPS_7_PCREL_S1:
+ case BFD_RELOC_MICROMIPS_10_PCREL_S1:
+ case BFD_RELOC_MICROMIPS_16_PCREL_S1:
+ return TRUE;
+
+ case BFD_RELOC_32_PCREL:
+ return HAVE_64BIT_ADDRESSES;
+
+ default:
+ return FALSE;
+ }
+}
+
/* Return true if the given relocation might need a matching %lo().
This is only "might" because SVR4 R_MIPS_GOT16 relocations only
need a matching %lo() when applied to local symbols. */
@@ -5012,6 +5052,11 @@ macro_build (expressionS *ep, const char *name, const char *fmt, ...)
INSMSB, insn, va_arg (args, int));
continue;
+ case 'J':
+ gas_assert (!mips_opts.micromips);
+ INSERT_OPERAND (0, CODE10, insn, va_arg (args, int));
+ continue;
+
case 'C':
case 'G':
case 'H':
@@ -8156,6 +8201,13 @@ macro (struct mips_cl_insn *ip)
/* Itbl support may require additional care here. */
coproc = 1;
goto ld_st;
+ case M_LQC2_AB:
+ ab = 1;
+ s = "lqc2";
+ fmt = "E,o(b)";
+ /* Itbl support may require additional care here. */
+ coproc = 1;
+ goto ld_st;
case M_LDC3_AB:
ab = 1;
s = "ldc3";
@@ -8345,6 +8397,13 @@ macro (struct mips_cl_insn *ip)
/* Itbl support may require additional care here. */
coproc = 1;
goto ld_st;
+ case M_SQC2_AB:
+ ab = 1;
+ s = "sqc2";
+ fmt = "E,o(b)";
+ /* Itbl support may require additional care here. */
+ coproc = 1;
+ goto ld_st;
case M_SDC3_AB:
ab = 1;
gas_assert (!mips_opts.micromips);
@@ -10392,6 +10451,7 @@ validate_mips_insn (const struct mips_opcode *opc)
case 'G': USE_BITS (OP_MASK_EXTMSBD, OP_SH_EXTMSBD); break;
case 'H': USE_BITS (OP_MASK_EXTMSBD, OP_SH_EXTMSBD); break;
case 'I': break;
+ case 'J': USE_BITS (OP_MASK_CODE10, OP_SH_CODE10); break;
case 't': USE_BITS (OP_MASK_RT, OP_SH_RT); break;
case 'T': USE_BITS (OP_MASK_RT, OP_SH_RT);
USE_BITS (OP_MASK_SEL, OP_SH_SEL); break;
@@ -10790,6 +10850,7 @@ mips_ip (char *str, struct mips_cl_insn *ip)
unsigned int destregno = 0;
unsigned int lastpos = 0;
unsigned int limlo, limhi;
+ int sizelo;
char *s_reset;
offsetT min_range, max_range;
long opend;
@@ -11314,6 +11375,23 @@ mips_ip (char *str, struct mips_cl_insn *ip)
}
continue;
+ case 'J': /* 10-bit hypcall code. */
+ gas_assert (!mips_opts.micromips);
+ {
+ unsigned long mask = OP_MASK_CODE10;
+
+ my_getExpression (&imm_expr, s);
+ check_absolute_expr (ip, &imm_expr);
+ if ((unsigned long) imm_expr.X_add_number > mask)
+ as_warn (_("Code for %s not in range 0..%lu (%lu)"),
+ ip->insn_mo->name,
+ mask, (unsigned long) imm_expr.X_add_number);
+ INSERT_OPERAND (0, CODE10, *ip, imm_expr.X_add_number);
+ imm_expr.X_op = O_absent;
+ s = expr_end;
+ }
+ continue;
+
case 'A': /* ins/ext position, becomes LSB. */
limlo = 0;
limhi = 31;
@@ -11374,23 +11452,25 @@ mips_ip (char *str, struct mips_cl_insn *ip)
case 'C': /* ext size, becomes MSBD. */
limlo = 1;
limhi = 32;
+ sizelo = 1;
goto do_msbd;
case 'G':
limlo = 33;
limhi = 64;
+ sizelo = 33;
goto do_msbd;
case 'H':
limlo = 33;
limhi = 64;
+ sizelo = 1;
goto do_msbd;
do_msbd:
my_getExpression (&imm_expr, s);
check_absolute_expr (ip, &imm_expr);
- /* Check for negative input so that small negative numbers
- will not succeed incorrectly. The checks against
- (pos+size) transitively check "size" itself,
- assuming that "pos" is reasonable. */
- if ((long) imm_expr.X_add_number < 0
+ /* The checks against (pos+size) don't transitively check
+ "size" itself, assuming that "pos" is reasonable.
+ We also need to check the lower bound of "size". */
+ if ((long) imm_expr.X_add_number < sizelo
|| ((unsigned long) imm_expr.X_add_number
+ lastpos) < limlo
|| ((unsigned long) imm_expr.X_add_number
@@ -14469,6 +14549,8 @@ enum options
OPTION_NO_DSP,
OPTION_MT,
OPTION_NO_MT,
+ OPTION_VIRT,
+ OPTION_NO_VIRT,
OPTION_SMARTMIPS,
OPTION_NO_SMARTMIPS,
OPTION_DSPR2,
@@ -14573,6 +14655,8 @@ struct option md_longopts[] =
{"mno-micromips", no_argument, NULL, OPTION_NO_MICROMIPS},
{"mmcu", no_argument, NULL, OPTION_MCU},
{"mno-mcu", no_argument, NULL, OPTION_NO_MCU},
+ {"mvirt", no_argument, NULL, OPTION_VIRT},
+ {"mno-virt", no_argument, NULL, OPTION_NO_VIRT},
/* Old-style architecture options. Don't add more of these. */
{"m4650", no_argument, NULL, OPTION_M4650},
@@ -14850,6 +14934,14 @@ md_parse_option (int c, char *arg)
mips_no_prev_insn ();
break;
+ case OPTION_VIRT:
+ mips_opts.ase_virt = 1;
+ break;
+
+ case OPTION_NO_VIRT:
+ mips_opts.ase_virt = 0;
+ break;
+
case OPTION_MIPS16:
if (mips_opts.micromips == 1)
{
@@ -15343,6 +15435,12 @@ mips_after_parse_args (void)
as_warn (_("%s ISA does not support MCU ASE"),
mips_cpu_info_from_isa (mips_opts.isa)->name);
+ if (mips_opts.ase_virt == -1)
+ mips_opts.ase_virt = (arch_info->flags & MIPS_CPU_ASE_VIRT) ? 1 : 0;
+ if (mips_opts.ase_virt && !ISA_SUPPORTS_VIRT_ASE)
+ as_warn (_("%s ISA does not support Virtualization ASE"),
+ mips_cpu_info_from_isa (mips_opts.isa)->name);
+
file_mips_isa = mips_opts.isa;
file_ase_mips3d = mips_opts.ase_mips3d;
file_ase_mdmx = mips_opts.ase_mdmx;
@@ -15350,6 +15448,7 @@ mips_after_parse_args (void)
file_ase_dsp = mips_opts.ase_dsp;
file_ase_dspr2 = mips_opts.ase_dspr2;
file_ase_mt = mips_opts.ase_mt;
+ file_ase_virt = mips_opts.ase_virt;
mips_opts.gp32 = file_mips_gp32;
mips_opts.fp32 = file_mips_fp32;
mips_opts.soft_float = file_mips_soft_float;
@@ -15392,6 +15491,9 @@ md_pcrel_from (fixS *fixP)
/* Return the address of the delay slot. */
return addr + 4;
+ case BFD_RELOC_32_PCREL:
+ return addr;
+
default:
/* We have no relocation type for PC relative MIPS16 instructions. */
if (fixP->fx_addsy && S_GET_SEGMENT (fixP->fx_addsy) != now_seg)
@@ -15614,7 +15716,8 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
gas_assert (!fixP->fx_pcrel || fixP->fx_r_type == BFD_RELOC_16_PCREL_S2
|| fixP->fx_r_type == BFD_RELOC_MICROMIPS_7_PCREL_S1
|| fixP->fx_r_type == BFD_RELOC_MICROMIPS_10_PCREL_S1
- || fixP->fx_r_type == BFD_RELOC_MICROMIPS_16_PCREL_S1);
+ || fixP->fx_r_type == BFD_RELOC_MICROMIPS_16_PCREL_S1
+ || fixP->fx_r_type == BFD_RELOC_32_PCREL);
/* Don't treat parts of a composite relocation as done. There are two
reasons for this:
@@ -15762,6 +15865,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
case BFD_RELOC_RVA:
case BFD_RELOC_32:
+ case BFD_RELOC_32_PCREL:
case BFD_RELOC_16:
/* If we are deleting this reloc entry, we must fill in the
value now. This can happen if we have a .word which is not
@@ -16414,6 +16518,15 @@ s_mipsset (int x ATTRIBUTE_UNUSED)
mips_opts.ase_mcu = 1;
else if (strcmp (name, "nomcu") == 0)
mips_opts.ase_mcu = 0;
+ else if (strcmp (name, "virt") == 0)
+ {
+ if (!ISA_SUPPORTS_VIRT_ASE)
+ as_warn (_("%s ISA does not support Virtualization ASE"),
+ mips_cpu_info_from_isa (mips_opts.isa)->name);
+ mips_opts.ase_virt = 1;
+ }
+ else if (strcmp (name, "novirt") == 0)
+ mips_opts.ase_virt = 0;
else if (strncmp (name, "mips", 4) == 0 || strncmp (name, "arch=", 5) == 0)
{
int reset = 0;
@@ -17085,18 +17198,24 @@ s_insn (int ignore ATTRIBUTE_UNUSED)
demand_empty_rest_of_line ();
}
-/* Handle a .stabn directive. We need these in order to mark a label
- as being a mips16 text label correctly. Sometimes the compiler
- will emit a label, followed by a .stabn, and then switch sections.
- If the label and .stabn are in mips16 mode, then the label is
- really a mips16 text label. */
+/* Handle a .stab[snd] directive. Ideally these directives would be
+ implemented in a transparent way, so that removing them would not
+ have any effect on the generated instructions. However, s_stab
+ internally changes the section, so in practice we need to decide
+ now whether the preceding label marks compressed code. We do not
+ support changing the compression mode of a label after a .stab*
+ directive, such as in:
+
+ foo:
+ .stabs ...
+ .set mips16
+
+ so the current mode wins. */
static void
s_mips_stab (int type)
{
- if (type == 'n')
- mips_mark_labels ();
-
+ mips_mark_labels ();
s_stab (type);
}
@@ -17803,11 +17922,12 @@ mips_fix_adjustable (fixS *fixp)
return 0;
/* There is no place to store an in-place offset for JALR relocations.
- Likewise an in-range offset of PC-relative relocations may overflow
- the in-place relocatable field if recalculated against the start
- address of the symbol's containing section. */
+ Likewise an in-range offset of limited PC-relative relocations may
+ overflow the in-place relocatable field if recalculated against the
+ start address of the symbol's containing section. */
if (HAVE_IN_PLACE_ADDENDS
- && (fixp->fx_pcrel || jalr_reloc_p (fixp->fx_r_type)))
+ && (limited_pcrel_reloc_p (fixp->fx_r_type)
+ || jalr_reloc_p (fixp->fx_r_type)))
return 0;
#ifdef OBJ_ELF
@@ -17887,7 +18007,8 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
gas_assert (fixp->fx_r_type == BFD_RELOC_16_PCREL_S2
|| fixp->fx_r_type == BFD_RELOC_MICROMIPS_7_PCREL_S1
|| fixp->fx_r_type == BFD_RELOC_MICROMIPS_10_PCREL_S1
- || fixp->fx_r_type == BFD_RELOC_MICROMIPS_16_PCREL_S1);
+ || fixp->fx_r_type == BFD_RELOC_MICROMIPS_16_PCREL_S1
+ || fixp->fx_r_type == BFD_RELOC_32_PCREL);
/* At this point, fx_addnumber is "symbol offset - pcrel address".
Relocations want only the symbol offset. */
@@ -18678,12 +18799,8 @@ mips_elf_final_processing (void)
if (mips_abicalls)
elf_elfheader (stdoutput)->e_flags |= EF_MIPS_CPIC;
- /* Set MIPS ELF flags for ASEs. */
- /* We may need to define a new flag for DSP ASE, and set this flag when
- file_ase_dsp is true. */
- /* Same for DSP R2. */
- /* We may need to define a new flag for MT ASE, and set this flag when
- file_ase_mt is true. */
+ /* Set MIPS ELF flags for ASEs. Note that not all ASEs have flags
+ defined at present; this might need to change in future. */
if (file_ase_mips16)
elf_elfheader (stdoutput)->e_flags |= EF_MIPS_ARCH_ASE_M16;
if (file_ase_micromips)
@@ -19554,6 +19671,9 @@ MIPS options:\n\
-mmcu generate MCU instructions\n\
-mno-mcu do not generate MCU instructions\n"));
fprintf (stream, _("\
+-mvirt generate Virtualization instructions\n\
+-mno-virt do not generate Virtualization instructions\n"));
+ fprintf (stream, _("\
-mfix-loongson2f-jump work around Loongson2F JUMP instructions\n\
-mfix-loongson2f-nop work around Loongson2F NOP errata\n\
-mfix-vr4120 work around certain VR4120 errata\n\
diff --git a/gas/config/tc-msp430.c b/gas/config/tc-msp430.c
index 8ec754640..f319b2365 100644
--- a/gas/config/tc-msp430.c
+++ b/gas/config/tc-msp430.c
@@ -1,7 +1,6 @@
/* tc-msp430.c -- Assembler code for the Texas Instruments MSP430
- Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010, 2012
- Free Software Foundation, Inc.
+ Copyright (C) 2002-2013 Free Software Foundation, Inc.
Contributed by Dmitry Diky <diwil@mail.ru>
This file is part of GAS, the GNU Assembler.
@@ -28,6 +27,7 @@
#include "opcode/msp430.h"
#include "safe-ctype.h"
#include "dwarf2dbg.h"
+#include "elf/msp430.h"
/* We will disable polymorphs by default because it is dangerous.
The potential problem here is the following: assume we got the
@@ -39,7 +39,7 @@
.l1:
nop
ret
-
+
In case of assembly time relaxation we'll get:
0: jmp .l1 <.text +0x08> (reloc deleted)
2: nop
@@ -63,15 +63,18 @@
If polymorphs are enabled, and relax isn't, treat all jumps as long jumps,
do not delete any relocs and leave them for linker.
-
+
If relax is enabled, relax at assembly time and kill relocs as necessary. */
int msp430_enable_relax;
int msp430_enable_polys;
+/* Set linkrelax here to avoid fixups in most sections. */
+int linkrelax = 1;
+
/* GCC uses the some condition codes which we'll
implement as new polymorph instructions.
-
+
COND EXPL SHORT JUMP LONG JUMP
===============================================
eq == jeq jne +4; br lab
@@ -80,7 +83,7 @@ int msp430_enable_polys;
ltn honours no-overflow flag
ltn < jn jn +2; jmp +4; br lab
- lt < jl jge +4; br lab
+ lt < jl jge +4; br lab
ltu < jlo lhs +4; br lab
le <= see below
leu <= see below
@@ -93,14 +96,14 @@ int msp430_enable_polys;
Therefore, new opcodes are (BranchEQ -> beq; and so on...)
beq,bne,blt,bltn,bltu,bge,bgeu
- 'u' means unsigned compares
-
+ 'u' means unsigned compares
+
Also, we add 'jump' instruction:
jump UNCOND -> jmp br lab
They will have fmt == 4, and insn_opnumb == number of instruction. */
-struct rcodes_s
+struct rcodes_s
{
char * name;
int index; /* Corresponding insn_opnumb. */
@@ -114,7 +117,7 @@ struct rcodes_s
#define MSP430_RLC(n,i,sop,o1) \
{#n, i, sop, 2, (o1 + 2), 0x4010, 0}
-static struct rcodes_s msp430_rcodes[] =
+static struct rcodes_s msp430_rcodes[] =
{
MSP430_RLC (beq, 0, 0x2400, 0x2000),
MSP430_RLC (bne, 1, 0x2000, 0x2400),
@@ -126,11 +129,27 @@ static struct rcodes_s msp430_rcodes[] =
{"jump", 7, 0x3c00, 1, 0x4010, 0, 0},
{0,0,0,0,0,0,0}
};
-#undef MSP430_RLC
+#undef MSP430_RLC
+#define MSP430_RLC(n,i,sop,o1) \
+ {#n, i, sop, 2, (o1 + 2), 0x0030, 0}
+
+static struct rcodes_s msp430x_rcodes[] =
+{
+ MSP430_RLC (beq, 0, 0x2400, 0x2000),
+ MSP430_RLC (bne, 1, 0x2000, 0x2400),
+ MSP430_RLC (blt, 2, 0x3800, 0x3400),
+ MSP430_RLC (bltu, 3, 0x2800, 0x2c00),
+ MSP430_RLC (bge, 4, 0x3400, 0x3800),
+ MSP430_RLC (bgeu, 5, 0x2c00, 0x2800),
+ {"bltn", 6, 0x3000, 3, 0x0030 + 1, 0x3c00 + 2, 0x3000},
+ {"jump", 7, 0x3c00, 1, 0x0030, 0, 0},
+ {0,0,0,0,0,0,0}
+};
+#undef MSP430_RLC
/* More difficult than above and they have format 5.
-
+
COND EXPL SHORT LONG
=================================================================
gt > jeq +2; jge label jeq +6; jl +4; br label
@@ -139,9 +158,9 @@ static struct rcodes_s msp430_rcodes[] =
le <= jeq label; jl label jeq +2; jge +4; br label
================================================================= */
-struct hcodes_s
+struct hcodes_s
{
- char * name;
+ char * name;
int index; /* Corresponding insn_opnumb. */
int tlab; /* Number of labels in short mode. */
int op0; /* Opcode for first word of short jump. */
@@ -151,7 +170,7 @@ struct hcodes_s
int lop2;
};
-static struct hcodes_s msp430_hcodes[] =
+static struct hcodes_s msp430_hcodes[] =
{
{"bgt", 0, 1, 0x2401, 0x3400, 0x2403, 0x3802, 0x4010 },
{"bgtu", 1, 1, 0x2401, 0x2c00, 0x2403, 0x2802, 0x4010 },
@@ -160,6 +179,15 @@ static struct hcodes_s msp430_hcodes[] =
{0,0,0,0,0,0,0,0}
};
+static struct hcodes_s msp430x_hcodes[] =
+{
+ {"bgt", 0, 1, 0x2401, 0x3400, 0x2403, 0x3802, 0x0030 },
+ {"bgtu", 1, 1, 0x2401, 0x2c00, 0x2403, 0x2802, 0x0030 },
+ {"bleu", 2, 2, 0x2400, 0x2800, 0x2401, 0x2c02, 0x0030 },
+ {"ble", 3, 2, 0x2400, 0x3800, 0x2401, 0x3402, 0x0030 },
+ {0,0,0,0,0,0,0,0}
+};
+
const char comment_chars[] = ";";
const char line_comment_chars[] = "#";
const char line_separator_chars[] = "{";
@@ -229,115 +257,506 @@ relax_typeS md_relax_table[] =
#define MAX_OP_LEN 256
+typedef enum msp_isa
+{
+ MSP_ISA_430,
+ MSP_ISA_430X,
+ MSP_ISA_430Xv2
+} msp_isa;
+
struct mcu_type_s
{
- char * name;
- int isa;
- int mach;
+ char * name;
+ msp_isa isa;
};
-#define MSP430_ISA_11 11
-#define MSP430_ISA_110 110
-#define MSP430_ISA_12 12
-#define MSP430_ISA_13 13
-#define MSP430_ISA_14 14
-#define MSP430_ISA_15 15
-#define MSP430_ISA_16 16
-#define MSP430_ISA_21 21
-#define MSP430_ISA_31 31
-#define MSP430_ISA_32 32
-#define MSP430_ISA_33 33
-#define MSP430_ISA_41 41
-#define MSP430_ISA_42 42
-#define MSP430_ISA_43 43
-#define MSP430_ISA_44 44
-
-#define CHECK_RELOC_MSP430 ((imm_op || byte_op)?BFD_RELOC_MSP430_16_BYTE:BFD_RELOC_MSP430_16)
-#define CHECK_RELOC_MSP430_PCREL ((imm_op || byte_op)?BFD_RELOC_MSP430_16_PCREL_BYTE:BFD_RELOC_MSP430_16_PCREL)
-
static struct mcu_type_s mcu_types[] =
{
- {"msp1", MSP430_ISA_11, bfd_mach_msp11},
- {"msp2", MSP430_ISA_14, bfd_mach_msp14},
- {"msp430x110", MSP430_ISA_11, bfd_mach_msp11},
- {"msp430x112", MSP430_ISA_11, bfd_mach_msp11},
- {"msp430x1101", MSP430_ISA_110, bfd_mach_msp110},
- {"msp430x1111", MSP430_ISA_110, bfd_mach_msp110},
- {"msp430x1121", MSP430_ISA_110, bfd_mach_msp110},
- {"msp430x1122", MSP430_ISA_11, bfd_mach_msp110},
- {"msp430x1132", MSP430_ISA_11, bfd_mach_msp110},
-
- {"msp430x122", MSP430_ISA_12, bfd_mach_msp12},
- {"msp430x123", MSP430_ISA_12, bfd_mach_msp12},
- {"msp430x1222", MSP430_ISA_12, bfd_mach_msp12},
- {"msp430x1232", MSP430_ISA_12, bfd_mach_msp12},
-
- {"msp430x133", MSP430_ISA_13, bfd_mach_msp13},
- {"msp430x135", MSP430_ISA_13, bfd_mach_msp13},
- {"msp430x1331", MSP430_ISA_13, bfd_mach_msp13},
- {"msp430x1351", MSP430_ISA_13, bfd_mach_msp13},
- {"msp430x147", MSP430_ISA_14, bfd_mach_msp14},
- {"msp430x148", MSP430_ISA_14, bfd_mach_msp14},
- {"msp430x149", MSP430_ISA_14, bfd_mach_msp14},
-
- {"msp430x155", MSP430_ISA_15, bfd_mach_msp15},
- {"msp430x156", MSP430_ISA_15, bfd_mach_msp15},
- {"msp430x157", MSP430_ISA_15, bfd_mach_msp15},
- {"msp430x167", MSP430_ISA_16, bfd_mach_msp16},
- {"msp430x168", MSP430_ISA_16, bfd_mach_msp16},
- {"msp430x169", MSP430_ISA_16, bfd_mach_msp16},
- {"msp430x1610", MSP430_ISA_16, bfd_mach_msp16},
- {"msp430x1611", MSP430_ISA_16, bfd_mach_msp16},
- {"msp430x1612", MSP430_ISA_16, bfd_mach_msp16},
-
- {"msp430x2101", MSP430_ISA_21, bfd_mach_msp21},
- {"msp430x2111", MSP430_ISA_21, bfd_mach_msp21},
- {"msp430x2121", MSP430_ISA_21, bfd_mach_msp21},
- {"msp430x2131", MSP430_ISA_21, bfd_mach_msp21},
-
- {"msp430x311", MSP430_ISA_31, bfd_mach_msp31},
- {"msp430x312", MSP430_ISA_31, bfd_mach_msp31},
- {"msp430x313", MSP430_ISA_31, bfd_mach_msp31},
- {"msp430x314", MSP430_ISA_31, bfd_mach_msp31},
- {"msp430x315", MSP430_ISA_31, bfd_mach_msp31},
- {"msp430x323", MSP430_ISA_32, bfd_mach_msp32},
- {"msp430x325", MSP430_ISA_32, bfd_mach_msp32},
- {"msp430x336", MSP430_ISA_33, bfd_mach_msp33},
- {"msp430x337", MSP430_ISA_33, bfd_mach_msp33},
-
- {"msp430x412", MSP430_ISA_41, bfd_mach_msp41},
- {"msp430x413", MSP430_ISA_41, bfd_mach_msp41},
- {"msp430x415", MSP430_ISA_41, bfd_mach_msp41},
- {"msp430x417", MSP430_ISA_41, bfd_mach_msp41},
-
- {"msp430xE423", MSP430_ISA_42, bfd_mach_msp42},
- {"msp430xE425", MSP430_ISA_42, bfd_mach_msp42},
- {"msp430xE427", MSP430_ISA_42, bfd_mach_msp42},
-
- {"msp430xW423", MSP430_ISA_42, bfd_mach_msp42},
- {"msp430xW425", MSP430_ISA_42, bfd_mach_msp42},
- {"msp430xW427", MSP430_ISA_42, bfd_mach_msp42},
-
- {"msp430xG437", MSP430_ISA_43, bfd_mach_msp43},
- {"msp430xG438", MSP430_ISA_43, bfd_mach_msp43},
- {"msp430xG439", MSP430_ISA_43, bfd_mach_msp43},
-
- {"msp430x435", MSP430_ISA_43, bfd_mach_msp43},
- {"msp430x436", MSP430_ISA_43, bfd_mach_msp43},
- {"msp430x437", MSP430_ISA_43, bfd_mach_msp43},
- {"msp430x447", MSP430_ISA_44, bfd_mach_msp44},
- {"msp430x448", MSP430_ISA_44, bfd_mach_msp44},
- {"msp430x449", MSP430_ISA_44, bfd_mach_msp44},
-
- {NULL, 0, 0}
+ {"msp430afe221", MSP_ISA_430},
+ {"msp430afe222", MSP_ISA_430},
+ {"msp430afe223", MSP_ISA_430},
+ {"msp430afe231", MSP_ISA_430},
+ {"msp430afe232", MSP_ISA_430},
+ {"msp430afe233", MSP_ISA_430},
+ {"msp430afe251", MSP_ISA_430},
+ {"msp430afe252", MSP_ISA_430},
+ {"msp430afe253", MSP_ISA_430},
+ {"msp430c091", MSP_ISA_430},
+ {"msp430c092", MSP_ISA_430},
+ {"msp430c111", MSP_ISA_430},
+ {"msp430c1111", MSP_ISA_430},
+ {"msp430c112", MSP_ISA_430},
+ {"msp430c1121", MSP_ISA_430},
+ {"msp430e112", MSP_ISA_430},
+ {"msp430c1331", MSP_ISA_430},
+ {"msp430c1351", MSP_ISA_430},
+ {"msp430c311s", MSP_ISA_430},
+ {"msp430c312", MSP_ISA_430},
+ {"msp430c313", MSP_ISA_430},
+ {"msp430c314", MSP_ISA_430},
+ {"msp430c315", MSP_ISA_430},
+ {"msp430c323", MSP_ISA_430},
+ {"msp430c325", MSP_ISA_430},
+ {"msp430c336", MSP_ISA_430},
+ {"msp430c337", MSP_ISA_430},
+ {"msp430c412", MSP_ISA_430},
+ {"msp430c413", MSP_ISA_430},
+ {"msp430e313", MSP_ISA_430},
+ {"msp430e315", MSP_ISA_430},
+ {"msp430e325", MSP_ISA_430},
+ {"msp430e337", MSP_ISA_430},
+ {"msp430f110", MSP_ISA_430},
+ {"msp430f1101", MSP_ISA_430},
+ {"msp430f1101a", MSP_ISA_430},
+ {"msp430f1111", MSP_ISA_430},
+ {"msp430f1111a", MSP_ISA_430},
+ {"msp430f112", MSP_ISA_430},
+ {"msp430f1121", MSP_ISA_430},
+ {"msp430f1121a", MSP_ISA_430},
+ {"msp430f1122", MSP_ISA_430},
+ {"msp430f1132", MSP_ISA_430},
+ {"msp430f122", MSP_ISA_430},
+ {"msp430f1222", MSP_ISA_430},
+ {"msp430f123", MSP_ISA_430},
+ {"msp430f1232", MSP_ISA_430},
+ {"msp430f133", MSP_ISA_430},
+ {"msp430f135", MSP_ISA_430},
+ {"msp430f147", MSP_ISA_430},
+ {"msp430f1471", MSP_ISA_430},
+ {"msp430f148", MSP_ISA_430},
+ {"msp430f1481", MSP_ISA_430},
+ {"msp430f149", MSP_ISA_430},
+ {"msp430f1491", MSP_ISA_430},
+ {"msp430f155", MSP_ISA_430},
+ {"msp430f156", MSP_ISA_430},
+ {"msp430f157", MSP_ISA_430},
+ {"msp430f1610", MSP_ISA_430},
+ {"msp430f1611", MSP_ISA_430},
+ {"msp430f1612", MSP_ISA_430},
+ {"msp430f167", MSP_ISA_430},
+ {"msp430f168", MSP_ISA_430},
+ {"msp430f169", MSP_ISA_430},
+ {"msp430f2001", MSP_ISA_430},
+ {"msp430f2002", MSP_ISA_430},
+ {"msp430f2003", MSP_ISA_430},
+ {"msp430f2011", MSP_ISA_430},
+ {"msp430f2012", MSP_ISA_430},
+ {"msp430f2013", MSP_ISA_430},
+ {"msp430f2101", MSP_ISA_430},
+ {"msp430f2111", MSP_ISA_430},
+ {"msp430f2112", MSP_ISA_430},
+ {"msp430f2121", MSP_ISA_430},
+ {"msp430f2122", MSP_ISA_430},
+ {"msp430f2131", MSP_ISA_430},
+ {"msp430f2132", MSP_ISA_430},
+ {"msp430f2232", MSP_ISA_430},
+ {"msp430f2234", MSP_ISA_430},
+ {"msp430f2252", MSP_ISA_430},
+ {"msp430f2254", MSP_ISA_430},
+ {"msp430f2272", MSP_ISA_430},
+ {"msp430f2274", MSP_ISA_430},
+ {"msp430f233", MSP_ISA_430},
+ {"msp430f2330", MSP_ISA_430},
+ {"msp430f235", MSP_ISA_430},
+ {"msp430f2350", MSP_ISA_430},
+ {"msp430f2370", MSP_ISA_430},
+ {"msp430f2410", MSP_ISA_430},
+ {"msp430f247", MSP_ISA_430},
+ {"msp430f2471", MSP_ISA_430},
+ {"msp430f248", MSP_ISA_430},
+ {"msp430f2481", MSP_ISA_430},
+ {"msp430f249", MSP_ISA_430},
+ {"msp430f2491", MSP_ISA_430},
+ {"msp430f412", MSP_ISA_430},
+ {"msp430f413", MSP_ISA_430},
+ {"msp430f4132", MSP_ISA_430},
+ {"msp430f415", MSP_ISA_430},
+ {"msp430f4152", MSP_ISA_430},
+ {"msp430f417", MSP_ISA_430},
+ {"msp430f423", MSP_ISA_430},
+ {"msp430f423a", MSP_ISA_430},
+ {"msp430f425", MSP_ISA_430},
+ {"msp430f4250", MSP_ISA_430},
+ {"msp430f425a", MSP_ISA_430},
+ {"msp430f4260", MSP_ISA_430},
+ {"msp430f427", MSP_ISA_430},
+ {"msp430f4270", MSP_ISA_430},
+ {"msp430f427a", MSP_ISA_430},
+ {"msp430f435", MSP_ISA_430},
+ {"msp430f4351", MSP_ISA_430},
+ {"msp430f436", MSP_ISA_430},
+ {"msp430f4361", MSP_ISA_430},
+ {"msp430f437", MSP_ISA_430},
+ {"msp430f4371", MSP_ISA_430},
+ {"msp430f438", MSP_ISA_430},
+ {"msp430f439", MSP_ISA_430},
+ {"msp430f447", MSP_ISA_430},
+ {"msp430f448", MSP_ISA_430},
+ {"msp430f4481", MSP_ISA_430},
+ {"msp430f449", MSP_ISA_430},
+ {"msp430f4491", MSP_ISA_430},
+ {"msp430f477", MSP_ISA_430},
+ {"msp430f478", MSP_ISA_430},
+ {"msp430f4783", MSP_ISA_430},
+ {"msp430f4784", MSP_ISA_430},
+ {"msp430f479", MSP_ISA_430},
+ {"msp430f4793", MSP_ISA_430},
+ {"msp430f4794", MSP_ISA_430},
+ {"msp430fe423", MSP_ISA_430},
+ {"msp430fe4232", MSP_ISA_430},
+ {"msp430fe423a", MSP_ISA_430},
+ {"msp430fe4242", MSP_ISA_430},
+ {"msp430fe425", MSP_ISA_430},
+ {"msp430fe4252", MSP_ISA_430},
+ {"msp430fe425a", MSP_ISA_430},
+ {"msp430fe427", MSP_ISA_430},
+ {"msp430fe4272", MSP_ISA_430},
+ {"msp430fe427a", MSP_ISA_430},
+ {"msp430fg4250", MSP_ISA_430},
+ {"msp430fg4260", MSP_ISA_430},
+ {"msp430fg4270", MSP_ISA_430},
+ {"msp430fg437", MSP_ISA_430},
+ {"msp430fg438", MSP_ISA_430},
+ {"msp430fg439", MSP_ISA_430},
+ {"msp430fg477", MSP_ISA_430},
+ {"msp430fg478", MSP_ISA_430},
+ {"msp430fg479", MSP_ISA_430},
+ {"msp430fw423", MSP_ISA_430},
+ {"msp430fw425", MSP_ISA_430},
+ {"msp430fw427", MSP_ISA_430},
+ {"msp430fw428", MSP_ISA_430},
+ {"msp430fw429", MSP_ISA_430},
+ {"msp430g2001", MSP_ISA_430},
+ {"msp430g2101", MSP_ISA_430},
+ {"msp430g2102", MSP_ISA_430},
+ {"msp430g2111", MSP_ISA_430},
+ {"msp430g2112", MSP_ISA_430},
+ {"msp430g2113", MSP_ISA_430},
+ {"msp430g2121", MSP_ISA_430},
+ {"msp430g2131", MSP_ISA_430},
+ {"msp430g2132", MSP_ISA_430},
+ {"msp430g2152", MSP_ISA_430},
+ {"msp430g2153", MSP_ISA_430},
+ {"msp430g2201", MSP_ISA_430},
+ {"msp430g2202", MSP_ISA_430},
+ {"msp430g2203", MSP_ISA_430},
+ {"msp430g2210", MSP_ISA_430},
+ {"msp430g2211", MSP_ISA_430},
+ {"msp430g2212", MSP_ISA_430},
+ {"msp430g2213", MSP_ISA_430},
+ {"msp430g2221", MSP_ISA_430},
+ {"msp430g2230", MSP_ISA_430},
+ {"msp430g2231", MSP_ISA_430},
+ {"msp430g2232", MSP_ISA_430},
+ {"msp430g2233", MSP_ISA_430},
+ {"msp430g2252", MSP_ISA_430},
+ {"msp430g2253", MSP_ISA_430},
+ {"msp430g2302", MSP_ISA_430},
+ {"msp430g2303", MSP_ISA_430},
+ {"msp430g2312", MSP_ISA_430},
+ {"msp430g2313", MSP_ISA_430},
+ {"msp430g2332", MSP_ISA_430},
+ {"msp430g2333", MSP_ISA_430},
+ {"msp430g2352", MSP_ISA_430},
+ {"msp430g2353", MSP_ISA_430},
+ {"msp430g2402", MSP_ISA_430},
+ {"msp430g2403", MSP_ISA_430},
+ {"msp430g2412", MSP_ISA_430},
+ {"msp430g2413", MSP_ISA_430},
+ {"msp430g2432", MSP_ISA_430},
+ {"msp430g2433", MSP_ISA_430},
+ {"msp430g2444", MSP_ISA_430},
+ {"msp430g2452", MSP_ISA_430},
+ {"msp430g2453", MSP_ISA_430},
+ {"msp430g2513", MSP_ISA_430},
+ {"msp430g2533", MSP_ISA_430},
+ {"msp430g2544", MSP_ISA_430},
+ {"msp430g2553", MSP_ISA_430},
+ {"msp430g2744", MSP_ISA_430},
+ {"msp430g2755", MSP_ISA_430},
+ {"msp430g2855", MSP_ISA_430},
+ {"msp430g2955", MSP_ISA_430},
+ {"msp430l092", MSP_ISA_430},
+ {"msp430p112", MSP_ISA_430},
+ {"msp430p313", MSP_ISA_430},
+ {"msp430p315", MSP_ISA_430},
+ {"msp430p315s", MSP_ISA_430},
+ {"msp430p325", MSP_ISA_430},
+ {"msp430p337", MSP_ISA_430},
+ {"msp430tch5e", MSP_ISA_430},
+
+ {"msp430cg4616", MSP_ISA_430X},
+ {"msp430cg4617", MSP_ISA_430X},
+ {"msp430cg4618", MSP_ISA_430X},
+ {"msp430cg4619", MSP_ISA_430X},
+ {"msp430f2416", MSP_ISA_430X},
+ {"msp430f2417", MSP_ISA_430X},
+ {"msp430f2418", MSP_ISA_430X},
+ {"msp430f2419", MSP_ISA_430X},
+ {"msp430f2616", MSP_ISA_430X},
+ {"msp430f2617", MSP_ISA_430X},
+ {"msp430f2618", MSP_ISA_430X},
+ {"msp430f2619", MSP_ISA_430X},
+ {"msp430f47126", MSP_ISA_430X},
+ {"msp430f47127", MSP_ISA_430X},
+ {"msp430f47163", MSP_ISA_430X},
+ {"msp430f47173", MSP_ISA_430X},
+ {"msp430f47183", MSP_ISA_430X},
+ {"msp430f47193", MSP_ISA_430X},
+ {"msp430f47166", MSP_ISA_430X},
+ {"msp430f47176", MSP_ISA_430X},
+ {"msp430f47186", MSP_ISA_430X},
+ {"msp430f47196", MSP_ISA_430X},
+ {"msp430f47167", MSP_ISA_430X},
+ {"msp430f47177", MSP_ISA_430X},
+ {"msp430f47187", MSP_ISA_430X},
+ {"msp430f47197", MSP_ISA_430X},
+ {"msp430f46161", MSP_ISA_430X},
+ {"msp430f46171", MSP_ISA_430X},
+ {"msp430f46181", MSP_ISA_430X},
+ {"msp430f46191", MSP_ISA_430X},
+ {"msp430f4616", MSP_ISA_430X},
+ {"msp430f4617", MSP_ISA_430X},
+ {"msp430f4618", MSP_ISA_430X},
+ {"msp430f4619", MSP_ISA_430X},
+ {"msp430fg4616", MSP_ISA_430X},
+ {"msp430fg4617", MSP_ISA_430X},
+ {"msp430fg4618", MSP_ISA_430X},
+ {"msp430fg4619", MSP_ISA_430X},
+
+ {"msp430f5418", MSP_ISA_430Xv2},
+ {"msp430f5419", MSP_ISA_430Xv2},
+ {"msp430f5435", MSP_ISA_430Xv2},
+ {"msp430f5436", MSP_ISA_430Xv2},
+ {"msp430f5437", MSP_ISA_430Xv2},
+ {"msp430f5438", MSP_ISA_430Xv2},
+ {"msp430f5418a", MSP_ISA_430Xv2},
+ {"msp430f5419a", MSP_ISA_430Xv2},
+ {"msp430f5435a", MSP_ISA_430Xv2},
+ {"msp430f5436a", MSP_ISA_430Xv2},
+ {"msp430f5437a", MSP_ISA_430Xv2},
+ {"msp430f5438a", MSP_ISA_430Xv2},
+ {"msp430f5212", MSP_ISA_430Xv2},
+ {"msp430f5213", MSP_ISA_430Xv2},
+ {"msp430f5214", MSP_ISA_430Xv2},
+ {"msp430f5217", MSP_ISA_430Xv2},
+ {"msp430f5218", MSP_ISA_430Xv2},
+ {"msp430f5219", MSP_ISA_430Xv2},
+ {"msp430f5222", MSP_ISA_430Xv2},
+ {"msp430f5223", MSP_ISA_430Xv2},
+ {"msp430f5224", MSP_ISA_430Xv2},
+ {"msp430f5227", MSP_ISA_430Xv2},
+ {"msp430f5228", MSP_ISA_430Xv2},
+ {"msp430f5229", MSP_ISA_430Xv2},
+ {"msp430f5304", MSP_ISA_430Xv2},
+ {"msp430f5308", MSP_ISA_430Xv2},
+ {"msp430f5309", MSP_ISA_430Xv2},
+ {"msp430f5310", MSP_ISA_430Xv2},
+ {"msp430f5340", MSP_ISA_430Xv2},
+ {"msp430f5341", MSP_ISA_430Xv2},
+ {"msp430f5342", MSP_ISA_430Xv2},
+ {"msp430f5324", MSP_ISA_430Xv2},
+ {"msp430f5325", MSP_ISA_430Xv2},
+ {"msp430f5326", MSP_ISA_430Xv2},
+ {"msp430f5327", MSP_ISA_430Xv2},
+ {"msp430f5328", MSP_ISA_430Xv2},
+ {"msp430f5329", MSP_ISA_430Xv2},
+ {"msp430f5500", MSP_ISA_430Xv2},
+ {"msp430f5501", MSP_ISA_430Xv2},
+ {"msp430f5502", MSP_ISA_430Xv2},
+ {"msp430f5503", MSP_ISA_430Xv2},
+ {"msp430f5504", MSP_ISA_430Xv2},
+ {"msp430f5505", MSP_ISA_430Xv2},
+ {"msp430f5506", MSP_ISA_430Xv2},
+ {"msp430f5507", MSP_ISA_430Xv2},
+ {"msp430f5508", MSP_ISA_430Xv2},
+ {"msp430f5509", MSP_ISA_430Xv2},
+ {"msp430f5510", MSP_ISA_430Xv2},
+ {"msp430f5513", MSP_ISA_430Xv2},
+ {"msp430f5514", MSP_ISA_430Xv2},
+ {"msp430f5515", MSP_ISA_430Xv2},
+ {"msp430f5517", MSP_ISA_430Xv2},
+ {"msp430f5519", MSP_ISA_430Xv2},
+ {"msp430f5521", MSP_ISA_430Xv2},
+ {"msp430f5522", MSP_ISA_430Xv2},
+ {"msp430f5524", MSP_ISA_430Xv2},
+ {"msp430f5525", MSP_ISA_430Xv2},
+ {"msp430f5526", MSP_ISA_430Xv2},
+ {"msp430f5527", MSP_ISA_430Xv2},
+ {"msp430f5528", MSP_ISA_430Xv2},
+ {"msp430f5529", MSP_ISA_430Xv2},
+ {"cc430f5133", MSP_ISA_430Xv2},
+ {"cc430f5135", MSP_ISA_430Xv2},
+ {"cc430f5137", MSP_ISA_430Xv2},
+ {"cc430f6125", MSP_ISA_430Xv2},
+ {"cc430f6126", MSP_ISA_430Xv2},
+ {"cc430f6127", MSP_ISA_430Xv2},
+ {"cc430f6135", MSP_ISA_430Xv2},
+ {"cc430f6137", MSP_ISA_430Xv2},
+ {"cc430f5123", MSP_ISA_430Xv2},
+ {"cc430f5125", MSP_ISA_430Xv2},
+ {"cc430f5143", MSP_ISA_430Xv2},
+ {"cc430f5145", MSP_ISA_430Xv2},
+ {"cc430f5147", MSP_ISA_430Xv2},
+ {"cc430f6143", MSP_ISA_430Xv2},
+ {"cc430f6145", MSP_ISA_430Xv2},
+ {"cc430f6147", MSP_ISA_430Xv2},
+ {"msp430f5333", MSP_ISA_430Xv2},
+ {"msp430f5335", MSP_ISA_430Xv2},
+ {"msp430f5336", MSP_ISA_430Xv2},
+ {"msp430f5338", MSP_ISA_430Xv2},
+ {"msp430f5630", MSP_ISA_430Xv2},
+ {"msp430f5631", MSP_ISA_430Xv2},
+ {"msp430f5632", MSP_ISA_430Xv2},
+ {"msp430f5633", MSP_ISA_430Xv2},
+ {"msp430f5634", MSP_ISA_430Xv2},
+ {"msp430f5635", MSP_ISA_430Xv2},
+ {"msp430f5636", MSP_ISA_430Xv2},
+ {"msp430f5637", MSP_ISA_430Xv2},
+ {"msp430f5638", MSP_ISA_430Xv2},
+ {"msp430f6433", MSP_ISA_430Xv2},
+ {"msp430f6435", MSP_ISA_430Xv2},
+ {"msp430f6436", MSP_ISA_430Xv2},
+ {"msp430f6438", MSP_ISA_430Xv2},
+ {"msp430f6630", MSP_ISA_430Xv2},
+ {"msp430f6631", MSP_ISA_430Xv2},
+ {"msp430f6632", MSP_ISA_430Xv2},
+ {"msp430f6633", MSP_ISA_430Xv2},
+ {"msp430f6634", MSP_ISA_430Xv2},
+ {"msp430f6635", MSP_ISA_430Xv2},
+ {"msp430f6636", MSP_ISA_430Xv2},
+ {"msp430f6637", MSP_ISA_430Xv2},
+ {"msp430f6638", MSP_ISA_430Xv2},
+ {"msp430f5358", MSP_ISA_430Xv2},
+ {"msp430f5359", MSP_ISA_430Xv2},
+ {"msp430f5658", MSP_ISA_430Xv2},
+ {"msp430f5659", MSP_ISA_430Xv2},
+ {"msp430f6458", MSP_ISA_430Xv2},
+ {"msp430f6459", MSP_ISA_430Xv2},
+ {"msp430f6658", MSP_ISA_430Xv2},
+ {"msp430f6659", MSP_ISA_430Xv2},
+ {"msp430f5131", MSP_ISA_430Xv2},
+ {"msp430f5151", MSP_ISA_430Xv2},
+ {"msp430f5171", MSP_ISA_430Xv2},
+ {"msp430f5132", MSP_ISA_430Xv2},
+ {"msp430f5152", MSP_ISA_430Xv2},
+ {"msp430f5172", MSP_ISA_430Xv2},
+ {"msp430f6720", MSP_ISA_430Xv2},
+ {"msp430f6721", MSP_ISA_430Xv2},
+ {"msp430f6723", MSP_ISA_430Xv2},
+ {"msp430f6724", MSP_ISA_430Xv2},
+ {"msp430f6725", MSP_ISA_430Xv2},
+ {"msp430f6726", MSP_ISA_430Xv2},
+ {"msp430f6730", MSP_ISA_430Xv2},
+ {"msp430f6731", MSP_ISA_430Xv2},
+ {"msp430f6733", MSP_ISA_430Xv2},
+ {"msp430f6734", MSP_ISA_430Xv2},
+ {"msp430f6735", MSP_ISA_430Xv2},
+ {"msp430f6736", MSP_ISA_430Xv2},
+ {"msp430f67451", MSP_ISA_430Xv2},
+ {"msp430f67651", MSP_ISA_430Xv2},
+ {"msp430f67751", MSP_ISA_430Xv2},
+ {"msp430f67461", MSP_ISA_430Xv2},
+ {"msp430f67661", MSP_ISA_430Xv2},
+ {"msp430f67761", MSP_ISA_430Xv2},
+ {"msp430f67471", MSP_ISA_430Xv2},
+ {"msp430f67671", MSP_ISA_430Xv2},
+ {"msp430f67771", MSP_ISA_430Xv2},
+ {"msp430f67481", MSP_ISA_430Xv2},
+ {"msp430f67681", MSP_ISA_430Xv2},
+ {"msp430f67781", MSP_ISA_430Xv2},
+ {"msp430f67491", MSP_ISA_430Xv2},
+ {"msp430f67691", MSP_ISA_430Xv2},
+ {"msp430f67791", MSP_ISA_430Xv2},
+ {"msp430f6745", MSP_ISA_430Xv2},
+ {"msp430f6765", MSP_ISA_430Xv2},
+ {"msp430f6775", MSP_ISA_430Xv2},
+ {"msp430f6746", MSP_ISA_430Xv2},
+ {"msp430f6766", MSP_ISA_430Xv2},
+ {"msp430f6776", MSP_ISA_430Xv2},
+ {"msp430f6747", MSP_ISA_430Xv2},
+ {"msp430f6767", MSP_ISA_430Xv2},
+ {"msp430f6777", MSP_ISA_430Xv2},
+ {"msp430f6748", MSP_ISA_430Xv2},
+ {"msp430f6768", MSP_ISA_430Xv2},
+ {"msp430f6778", MSP_ISA_430Xv2},
+ {"msp430f6749", MSP_ISA_430Xv2},
+ {"msp430f6769", MSP_ISA_430Xv2},
+ {"msp430f6779", MSP_ISA_430Xv2},
+ {"msp430fr5720", MSP_ISA_430Xv2},
+ {"msp430fr5721", MSP_ISA_430Xv2},
+ {"msp430fr5722", MSP_ISA_430Xv2},
+ {"msp430fr5723", MSP_ISA_430Xv2},
+ {"msp430fr5724", MSP_ISA_430Xv2},
+ {"msp430fr5725", MSP_ISA_430Xv2},
+ {"msp430fr5726", MSP_ISA_430Xv2},
+ {"msp430fr5727", MSP_ISA_430Xv2},
+ {"msp430fr5728", MSP_ISA_430Xv2},
+ {"msp430fr5729", MSP_ISA_430Xv2},
+ {"msp430fr5730", MSP_ISA_430Xv2},
+ {"msp430fr5731", MSP_ISA_430Xv2},
+ {"msp430fr5732", MSP_ISA_430Xv2},
+ {"msp430fr5733", MSP_ISA_430Xv2},
+ {"msp430fr5734", MSP_ISA_430Xv2},
+ {"msp430fr5735", MSP_ISA_430Xv2},
+ {"msp430fr5736", MSP_ISA_430Xv2},
+ {"msp430fr5737", MSP_ISA_430Xv2},
+ {"msp430fr5738", MSP_ISA_430Xv2},
+ {"msp430fr5739", MSP_ISA_430Xv2},
+ {"msp430bt5190", MSP_ISA_430Xv2},
+ {"msp430fr5949", MSP_ISA_430Xv2},
+ {"msp430fr5969", MSP_ISA_430Xv2},
+ {"msp430sl5438a", MSP_ISA_430Xv2},
+
+ /* Generic names. */
+ {"msp430", MSP_ISA_430},
+ {"msp430X", MSP_ISA_430X},
+ {"msp430Xv2", MSP_ISA_430Xv2},
+
+ {NULL, 0}
};
-
-static struct mcu_type_s default_mcu =
- { "msp430x11", MSP430_ISA_11, bfd_mach_msp11 };
+static struct mcu_type_s default_mcu = { "msp430x11", MSP_ISA_430 };
+static struct mcu_type_s msp430x_mcu = { "msp430x", MSP_ISA_430X };
+static struct mcu_type_s msp430xv2_mcu = { "msp430xv2", MSP_ISA_430Xv2 };
static struct mcu_type_s * msp430_mcu = & default_mcu;
+static inline bfd_boolean
+target_is_430x (void)
+{
+ return msp430_mcu->isa >= MSP_ISA_430X;
+}
+
+static inline bfd_boolean
+target_is_430xv2 (void)
+{
+ return msp430_mcu->isa == MSP_ISA_430Xv2;
+}
+
+/* Generate a 16-bit relocation.
+ For the 430X we generate a relocation without linkwer range checking
+ if the value is being used in an extended (ie 20-bit) instruction.
+ For the 430 we generate a relocation without assembler range checking
+ if we are handling an immediate value or a byte-width instruction. */
+#undef CHECK_RELOC_MSP430
+#define CHECK_RELOC_MSP430 \
+ (target_is_430x () \
+ ? (extended_op ? BFD_RELOC_16 : BFD_RELOC_MSP430X_ABS16) \
+ : ((imm_op || byte_op) \
+ ? BFD_RELOC_MSP430_16_BYTE : BFD_RELOC_MSP430_16))
+
+/* Generate a 16-bit pc-relative relocation.
+ For the 430X we generate a relocation without linkwer range checking.
+ For the 430 we generate a relocation without assembler range checking
+ if we are handling an immediate value or a byte-width instruction. */
+#undef CHECK_RELOC_MSP430_PCREL
+#define CHECK_RELOC_MSP430_PCREL \
+ (target_is_430x () \
+ ? BFD_RELOC_MSP430X_PCR16 \
+ : (imm_op || byte_op) \
+ ? BFD_RELOC_MSP430_16_PCREL_BYTE : BFD_RELOC_MSP430_16_PCREL)
+
/* Profiling capability:
It is a performance hit to use gcc's profiling approach for this tiny target.
Even more -- jtag hardware facility does not perform any profiling functions.
@@ -699,16 +1118,22 @@ extract_word (char * from, char * to, int limit)
#define OPTION_MMCU 'm'
#define OPTION_RELAX 'Q'
#define OPTION_POLYMORPHS 'P'
+#define OPTION_LARGE 'l'
+static bfd_boolean large_model = FALSE;
+#define OPTION_NO_INTR_NOPS 'N'
+static bfd_boolean gen_interrupt_nops = TRUE;
+#define OPTION_MCPU 'c'
static void
-msp430_set_arch (int dummy ATTRIBUTE_UNUSED)
+msp430_set_arch (int option)
{
char *str = (char *) alloca (32); /* 32 for good measure. */
input_line_pointer = extract_word (input_line_pointer, str, 32);
- md_parse_option (OPTION_MMCU, str);
- bfd_set_arch_mach (stdoutput, TARGET_ARCH, msp430_mcu->mach);
+ md_parse_option (option, str);
+ bfd_set_arch_mach (stdoutput, TARGET_ARCH,
+ target_is_430x () ? bfd_mach_msp430x : bfd_mach_msp11);
}
static void
@@ -719,7 +1144,11 @@ show_mcu_list (FILE * stream)
fprintf (stream, _("Known MCU names:\n"));
for (i = 0; mcu_types[i].name; i++)
- fprintf (stream, _("\t %s\n"), mcu_types[i].name);
+ {
+ fprintf (stream, "%14.14s", mcu_types[i].name);
+ if ((i % 6) == 5)
+ fprintf (stream, "\n");
+ }
fprintf (stream, "\n");
}
@@ -732,33 +1161,55 @@ md_parse_option (int c, char * arg)
switch (c)
{
case OPTION_MMCU:
+ if (arg == NULL)
+ as_fatal (_("MCU option requires a name\n"));
+
for (i = 0; mcu_types[i].name; ++i)
- if (strcmp (mcu_types[i].name, arg) == 0)
+ if (strcasecmp (mcu_types[i].name, arg) == 0)
break;
- if (!mcu_types[i].name)
+ if (mcu_types[i].name == NULL)
{
show_mcu_list (stderr);
as_fatal (_("unknown MCU: %s\n"), arg);
}
- if (msp430_mcu == &default_mcu || msp430_mcu->mach == mcu_types[i].mach)
- msp430_mcu = &mcu_types[i];
+ /* Allow switching to the same or a lesser architecture. */
+ if (msp430_mcu == &default_mcu || msp430_mcu->isa >= mcu_types[i].isa)
+ msp430_mcu = mcu_types + i;
else
- as_fatal (_("redefinition of mcu type %s' to %s'"),
+ as_fatal (_("redefinition of mcu type '%s' to '%s'"),
msp430_mcu->name, mcu_types[i].name);
return 1;
- break;
+
+ case OPTION_MCPU:
+ if (strcmp (arg, "430") == 0)
+ msp430_mcu = & default_mcu;
+ else if (strcmp (arg, "430x") == 0
+ || strcmp (arg, "430X") == 0)
+ msp430_mcu = & msp430x_mcu;
+ else if (strcasecmp (arg, "430xv2") == 0)
+ msp430_mcu = & msp430xv2_mcu;
+ else
+ as_fatal (_("unrecognised argument to -mcpu option '%s'"), arg);
+
+ return 1;
case OPTION_RELAX:
- msp430_enable_relax = 1;
+ msp430_enable_relax = 1;
return 1;
- break;
-
+
case OPTION_POLYMORPHS:
msp430_enable_polys = 1;
return 1;
- break;
+
+ case OPTION_LARGE:
+ large_model = TRUE;
+ return 1;
+
+ case OPTION_NO_INTR_NOPS:
+ gen_interrupt_nops = FALSE;
+ return 1;
}
return 0;
@@ -767,18 +1218,22 @@ md_parse_option (int c, char * arg)
const pseudo_typeS md_pseudo_table[] =
{
- {"arch", msp430_set_arch, 0},
+ {"arch", msp430_set_arch, OPTION_MMCU},
+ {"cpu", msp430_set_arch, OPTION_MCPU},
{"profiler", msp430_profiler, 0},
{NULL, NULL, 0}
};
-const char *md_shortopts = "m:";
+const char *md_shortopts = "mm:,mP,mQ,ml,mN";
struct option md_longopts[] =
{
{"mmcu", required_argument, NULL, OPTION_MMCU},
+ {"mcpu", required_argument, NULL, OPTION_MCPU},
{"mP", no_argument, NULL, OPTION_POLYMORPHS},
{"mQ", no_argument, NULL, OPTION_RELAX},
+ {"ml", no_argument, NULL, OPTION_LARGE},
+ {"mN", no_argument, NULL, OPTION_NO_INTR_NOPS},
{NULL, no_argument, NULL, 0}
};
@@ -789,30 +1244,15 @@ md_show_usage (FILE * stream)
{
fprintf (stream,
_("MSP430 options:\n"
- " -mmcu=[msp430-name] select microcontroller type\n"
- " msp430x110 msp430x112\n"
- " msp430x1101 msp430x1111\n"
- " msp430x1121 msp430x1122 msp430x1132\n"
- " msp430x122 msp430x123\n"
- " msp430x1222 msp430x1232\n"
- " msp430x133 msp430x135\n"
- " msp430x1331 msp430x1351\n"
- " msp430x147 msp430x148 msp430x149\n"
- " msp430x155 msp430x156 msp430x157\n"
- " msp430x167 msp430x168 msp430x169\n"
- " msp430x1610 msp430x1611 msp430x1612\n"
- " msp430x311 msp430x312 msp430x313 msp430x314 msp430x315\n"
- " msp430x323 msp430x325\n"
- " msp430x336 msp430x337\n"
- " msp430x412 msp430x413 msp430x415 msp430x417\n"
- " msp430xE423 msp430xE425 msp430E427\n"
- " msp430xW423 msp430xW425 msp430W427\n"
- " msp430xG437 msp430xG438 msp430G439\n"
- " msp430x435 msp430x436 msp430x437\n"
- " msp430x447 msp430x448 msp430x449\n"));
+ " -mmcu=<msp430-name> - select microcontroller type\n"
+ " -mcpu={430|430x|430xv2} - select microcontroller architecture\n"));
fprintf (stream,
_(" -mQ - enable relaxation at assembly time. DANGEROUS!\n"
" -mP - enable polymorph instructions\n"));
+ fprintf (stream,
+ _(" -ml - enable large code model\n"));
+ fprintf (stream,
+ _(" -mN - disable generation of NOP after changing interrupts\n"));
show_mcu_list (stream);
}
@@ -820,7 +1260,7 @@ md_show_usage (FILE * stream)
symbolS *
md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
{
- return 0;
+ return NULL;
}
static char *
@@ -855,34 +1295,53 @@ md_begin (void)
for (opcode = msp430_opcodes; opcode->name; opcode++)
hash_insert (msp430_hash, opcode->name, (char *) opcode);
- bfd_set_arch_mach (stdoutput, TARGET_ARCH, msp430_mcu->mach);
+ bfd_set_arch_mach (stdoutput, TARGET_ARCH,
+ target_is_430x () ? bfd_mach_msp430x : bfd_mach_msp11);
}
-static int
+/* Returns the register number equivalent to the string T.
+ Returns -1 if there is no such register.
+ Skips a leading 'r' or 'R' character if there is one.
+ Handles the register aliases PC and SP. */
+
+static signed int
check_reg (char * t)
{
- /* If this is a reg numb, str 't' must be a number from 0 - 15. */
+ signed int val;
- if (strlen (t) > 2 && *(t + 2) != '+')
- return 1;
+ if (t == NULL)
+ return -1;
- while (*t)
- {
- if ((*t < '0' || *t > '9') && *t != '+')
- break;
- t++;
- }
+ if (*t == 'r' || *t == 'R')
+ ++t;
+
+ if (strncasecmp (t, "pc", 2) == 0)
+ return 0;
- if (*t)
+ if (strncasecmp (t, "sp", 2) == 0)
return 1;
- return 0;
-}
+ if (strncasecmp (t, "sr", 2) == 0)
+ return 2;
+ if (*t == '0')
+ return 0;
+
+ val = atoi (t);
+
+ if (val < 1 || val > 15)
+ return -1;
+
+ return val;
+}
static int
msp430_srcoperand (struct msp430_operand_s * op,
- char * l, int bin, int * imm_op)
+ char * l,
+ int bin,
+ int * imm_op,
+ bfd_boolean allow_20bit_values,
+ bfd_boolean constants_allowed)
{
char *__tl = l;
@@ -963,7 +1422,15 @@ msp430_srcoperand (struct msp430_operand_s * op,
x = op->exp.X_add_number;
}
- if (op->exp.X_add_number > 65535 || op->exp.X_add_number < -32768)
+ if (allow_20bit_values)
+ {
+ if (op->exp.X_add_number > 0xfffff || op->exp.X_add_number < - (0x7ffff))
+ {
+ as_bad (_("value 0x%x out of extended range."), x);
+ return 1;
+ }
+ }
+ else if (op->exp.X_add_number > 65535 || op->exp.X_add_number < -32768)
{
as_bad (_("value %d out of range. Use #lo() or #hi()"), x);
return 1;
@@ -972,9 +1439,12 @@ msp430_srcoperand (struct msp430_operand_s * op,
/* Now check constants. */
/* Substitute register mode with a constant generator if applicable. */
- x = (short) x; /* Extend sign. */
+ if (!allow_20bit_values)
+ x = (short) x; /* Extend sign. */
- if (x == 0)
+ if (! constants_allowed)
+ ;
+ else if (x == 0)
{
op->reg = 3;
op->am = 0;
@@ -1126,9 +1596,17 @@ msp430_srcoperand (struct msp430_operand_s * op,
{
int x = op->exp.X_add_number;
- if (x > 65535 || x < -32768)
+ if (allow_20bit_values)
{
- as_bad (_("value out of range: %d"), x);
+ if (x > 0xfffff || x < -(0x7ffff))
+ {
+ as_bad (_("value 0x%x out of extended range."), x);
+ return 1;
+ }
+ }
+ else if (x > 65535 || x < -32768)
+ {
+ as_bad (_("value out of range: 0x%x"), x);
return 1;
}
}
@@ -1160,31 +1638,16 @@ msp430_srcoperand (struct msp430_operand_s * op,
}
t++;
- if (*t != 'r' && *t != 'R')
- {
- as_bad (_("unknown addressing mode %s"), l);
- return 1;
- }
-
- t++; /* Points to the reg value. */
- if (check_reg (t))
+ if ((op->reg = check_reg (t)) == -1)
{
- as_bad (_("Bad register name r%s"), t);
+ as_bad (_("Bad register name %s"), t);
return 1;
}
op->mode = OP_REG;
op->am = m ? 3 : 2;
op->ol = 0;
- if (m)
- *m = 0; /* strip '+' */
- op->reg = atoi (t);
- if (op->reg < 0 || op->reg > 15)
- {
- as_bad (_("MSP430 does not have %d registers"), op->reg);
- return 1;
- }
return 0;
}
@@ -1209,48 +1672,21 @@ msp430_srcoperand (struct msp430_operand_s * op,
t = h;
op->am = 1;
op->ol = 1;
- /* Extract a register. */
- t++; /* Advance pointer. */
- if (*t != 'r' && *t != 'R')
+ /* Extract a register. */
+ if ((op->reg = check_reg (t + 1)) == -1)
{
as_bad (_
("unknown operator %s. Did you mean X(Rn) or #[hl][hl][oi](CONST) ?"),
l);
return 1;
}
- t++;
- op->reg = *t - '0';
- if (op->reg > 9 || op->reg < 0)
+ if (op->reg == 2)
{
- as_bad (_("unknown operator (r%s substituted as a register name"),
- t);
+ as_bad (_("r2 should not be used in indexed addressing mode"));
return 1;
}
- t++;
- if (*t != ')')
- {
- op->reg = op->reg * 10;
- op->reg += *t - '0';
-
- if (op->reg > 15)
- {
- as_bad (_("unknown operator %s"), l);
- return 1;
- }
- if (op->reg == 2)
- {
- as_bad (_("r2 should not be used in indexed addressing mode"));
- return 1;
- }
-
- if (*(t + 1) != ')')
- {
- as_bad (_("unknown operator %s"), l);
- return 1;
- }
- }
/* Extract constant. */
__tl = l;
@@ -1261,9 +1697,17 @@ msp430_srcoperand (struct msp430_operand_s * op,
{
int x = op->exp.X_add_number;
- if (x > 65535 || x < -32768)
+ if (allow_20bit_values)
{
- as_bad (_("value out of range: %d"), x);
+ if (x > 0xfffff || x < - (0x7ffff))
+ {
+ as_bad (_("value 0x%x out of extended range."), x);
+ return 1;
+ }
+ }
+ else if (x > 65535 || x < -32768)
+ {
+ as_bad (_("value out of range: 0x%x"), x);
return 1;
}
@@ -1292,37 +1736,22 @@ msp430_srcoperand (struct msp430_operand_s * op,
}
while (0);
- /* Register mode 'mov r1,r2'. */
- do
+ /* Possibly register mode 'mov r1,r2'. */
+ if ((op->reg = check_reg (l)) != -1)
{
- char *t = l;
-
- /* Operand should be a register. */
- if (*t == 'r' || *t == 'R')
- {
- int x = atoi (t + 1);
-
- if (check_reg (t + 1))
- break;
-
- if (x < 0 || x > 15)
- break; /* Symbolic mode. */
-
- op->mode = OP_REG;
- op->am = 0;
- op->ol = 0;
- op->reg = x;
- return 0;
- }
+ op->mode = OP_REG;
+ op->am = 0;
+ op->ol = 0;
+ return 0;
}
- while (0);
/* Symbolic mode 'mov a, b' == 'mov x(pc), y(pc)'. */
do
{
op->mode = OP_EXP;
op->reg = 0; /* PC relative... be careful. */
- op->am = 1;
+ /* An expression starting with a minus sign is a constant, not an address. */
+ op->am = (*l == '-' ? 3 : 1);
op->ol = 1;
__tl = l;
parse_exp (__tl, &(op->exp));
@@ -1337,10 +1766,16 @@ msp430_srcoperand (struct msp430_operand_s * op,
static int
-msp430_dstoperand (struct msp430_operand_s * op, char * l, int bin)
+msp430_dstoperand (struct msp430_operand_s * op,
+ char * l,
+ int bin,
+ bfd_boolean allow_20bit_values,
+ bfd_boolean constants_allowed)
{
int dummy;
- int ret = msp430_srcoperand (op, l, bin, & dummy);
+ int ret = msp430_srcoperand (op, l, bin, & dummy,
+ allow_20bit_values,
+ constants_allowed);
if (ret)
return ret;
@@ -1373,6 +1808,267 @@ msp430_dstoperand (struct msp430_operand_s * op, char * l, int bin)
}
+/* Attempt to encode a MOVA instruction with the given operands.
+ Returns the length of the encoded instruction if successful
+ or 0 upon failure. If the encoding fails, an error message
+ will be returned if a pointer is provided. */
+
+static int
+try_encode_mova (bfd_boolean imm_op,
+ int bin,
+ struct msp430_operand_s * op1,
+ struct msp430_operand_s * op2,
+ const char ** error_message_return)
+{
+ short ZEROS = 0;
+ char *frag;
+ int where;
+
+ /* Only a restricted subset of the normal MSP430 addressing modes
+ are supported here, so check for the ones that are allowed. */
+ if (imm_op)
+ {
+ if (op1->mode == OP_EXP)
+ {
+ if (op2->mode != OP_REG)
+ {
+ if (error_message_return != NULL)
+ * error_message_return = _("expected register as second argument of %s");
+ return 0;
+ }
+
+ if (op1->am == 3)
+ {
+ /* MOVA #imm20, Rdst. */
+ bin |= 0x80 | op2->reg;
+ frag = frag_more (4);
+ where = frag - frag_now->fr_literal;
+ if (op1->exp.X_op == O_constant)
+ {
+ bin |= ((op1->exp.X_add_number >> 16) & 0xf) << 8;
+ bfd_putl16 ((bfd_vma) bin, frag);
+ bfd_putl16 (op1->exp.X_add_number & 0xffff, frag + 2);
+ }
+ else
+ {
+ bfd_putl16 ((bfd_vma) bin, frag);
+ fix_new_exp (frag_now, where, 4, &(op1->exp), FALSE,
+ BFD_RELOC_MSP430X_ABS20_ADR_SRC);
+ bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
+ }
+
+ return 4;
+ }
+ else if (op1->am == 1)
+ {
+ /* MOVA z16(Rsrc), Rdst. */
+ bin |= 0x30 | (op1->reg << 8) | op2->reg;
+ frag = frag_more (4);
+ where = frag - frag_now->fr_literal;
+ bfd_putl16 ((bfd_vma) bin, frag);
+ if (op1->exp.X_op == O_constant)
+ {
+ if (op1->exp.X_add_number > 0xffff
+ || op1->exp.X_add_number < -(0x7fff))
+ {
+ if (error_message_return != NULL)
+ * error_message_return = _("index value too big for %s");
+ return 0;
+ }
+ bfd_putl16 (op1->exp.X_add_number & 0xffff, frag + 2);
+ }
+ else
+ {
+ bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
+ fix_new_exp (frag_now, where + 2, 2, &(op1->exp), FALSE,
+ op1->reg == 0 ?
+ BFD_RELOC_MSP430X_PCR16 :
+ BFD_RELOC_MSP430X_ABS16);
+ }
+ return 4;
+ }
+
+ if (error_message_return != NULL)
+ * error_message_return = _("unexpected addressing mode for %s");
+ return 0;
+ }
+ else if (op1->am == 0)
+ {
+ /* MOVA Rsrc, ... */
+ if (op2->mode == OP_REG)
+ {
+ bin |= 0xc0 | (op1->reg << 8) | op2->reg;
+ frag = frag_more (2);
+ where = frag - frag_now->fr_literal;
+ bfd_putl16 ((bfd_vma) bin, frag);
+ return 2;
+ }
+ else if (op2->am == 1)
+ {
+ if (op2->reg == 2)
+ {
+ /* MOVA Rsrc, &abs20. */
+ bin |= 0x60 | (op1->reg << 8);
+ frag = frag_more (4);
+ where = frag - frag_now->fr_literal;
+ if (op2->exp.X_op == O_constant)
+ {
+ bin |= (op2->exp.X_add_number >> 16) & 0xf;
+ bfd_putl16 ((bfd_vma) bin, frag);
+ bfd_putl16 (op2->exp.X_add_number & 0xffff, frag + 2);
+ }
+ else
+ {
+ bfd_putl16 ((bfd_vma) bin, frag);
+ bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
+ fix_new_exp (frag_now, where, 4, &(op2->exp), FALSE,
+ BFD_RELOC_MSP430X_ABS20_ADR_DST);
+ }
+ return 4;
+ }
+
+ /* MOVA Rsrc, z16(Rdst). */
+ bin |= 0x70 | (op1->reg << 8) | op2->reg;
+ frag = frag_more (4);
+ where = frag - frag_now->fr_literal;
+ bfd_putl16 ((bfd_vma) bin, frag);
+ if (op2->exp.X_op == O_constant)
+ {
+ if (op2->exp.X_add_number > 0xffff
+ || op2->exp.X_add_number < -(0x7fff))
+ {
+ if (error_message_return != NULL)
+ * error_message_return = _("index value too big for %s");
+ return 0;
+ }
+ bfd_putl16 (op2->exp.X_add_number & 0xffff, frag + 2);
+ }
+ else
+ {
+ bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
+ fix_new_exp (frag_now, where + 2, 2, &(op2->exp), FALSE,
+ op2->reg == 0 ?
+ BFD_RELOC_MSP430X_PCR16 :
+ BFD_RELOC_MSP430X_ABS16);
+ }
+ return 4;
+ }
+
+ if (error_message_return != NULL)
+ * error_message_return = _("unexpected addressing mode for %s");
+ return 0;
+ }
+ }
+
+ /* imm_op == FALSE. */
+
+ if (op1->reg == 2 && op1->am == 1 && op1->mode == OP_EXP)
+ {
+ /* MOVA &abs20, Rdst. */
+ if (op2->mode != OP_REG)
+ {
+ if (error_message_return != NULL)
+ * error_message_return = _("expected register as second argument of %s");
+ return 0;
+ }
+
+ if (op2->reg == 2 || op2->reg == 3)
+ {
+ if (error_message_return != NULL)
+ * error_message_return = _("constant generator destination register found in %s");
+ return 0;
+ }
+
+ bin |= 0x20 | op2->reg;
+ frag = frag_more (4);
+ where = frag - frag_now->fr_literal;
+ if (op1->exp.X_op == O_constant)
+ {
+ bin |= ((op1->exp.X_add_number >> 16) & 0xf) << 8;
+ bfd_putl16 ((bfd_vma) bin, frag);
+ bfd_putl16 (op1->exp.X_add_number & 0xffff, frag + 2);
+ }
+ else
+ {
+ bfd_putl16 ((bfd_vma) bin, frag);
+ bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
+ fix_new_exp (frag_now, where, 4, &(op1->exp), FALSE,
+ BFD_RELOC_MSP430X_ABS20_ADR_SRC);
+ }
+ return 4;
+ }
+ else if (op1->mode == OP_REG)
+ {
+ if (op1->am == 3)
+ {
+ /* MOVA @Rsrc+, Rdst. */
+ if (op2->mode != OP_REG)
+ {
+ if (error_message_return != NULL)
+ * error_message_return = _("expected register as second argument of %s");
+ return 0;
+ }
+
+ if (op2->reg == 2 || op2->reg == 3)
+ {
+ if (error_message_return != NULL)
+ * error_message_return = _("constant generator destination register found in %s");
+ return 0;
+ }
+
+ if (op1->reg == 2 || op1->reg == 3)
+ {
+ if (error_message_return != NULL)
+ * error_message_return = _("constant generator source register found in %s");
+ return 0;
+ }
+
+ bin |= 0x10 | (op1->reg << 8) | op2->reg;
+ frag = frag_more (2);
+ where = frag - frag_now->fr_literal;
+ bfd_putl16 ((bfd_vma) bin, frag);
+ return 2;
+ }
+ else if (op1->am == 2)
+ {
+ /* MOVA @Rsrc,Rdst */
+ if (op2->mode != OP_REG)
+ {
+ if (error_message_return != NULL)
+ * error_message_return = _("expected register as second argument of %s");
+ return 0;
+ }
+
+ if (op2->reg == 2 || op2->reg == 3)
+ {
+ if (error_message_return != NULL)
+ * error_message_return = _("constant generator destination register found in %s");
+ return 0;
+ }
+
+ if (op1->reg == 2 || op1->reg == 3)
+ {
+ if (error_message_return != NULL)
+ * error_message_return = _("constant generator source register found in %s");
+ return 0;
+ }
+
+ bin |= (op1->reg << 8) | op2->reg;
+ frag = frag_more (2);
+ where = frag - frag_now->fr_literal;
+ bfd_putl16 ((bfd_vma) bin, frag);
+ return 2;
+ }
+ }
+
+ if (error_message_return != NULL)
+ * error_message_return = _("unexpected addressing mode for %s");
+
+ return 0;
+}
+
+#define is_opcode(NAME) (strcmp (opcode->name, NAME) == 0)
+
/* Parse instruction operands.
Return binary opcode. */
@@ -1380,7 +2076,7 @@ static unsigned int
msp430_operands (struct msp430_opcode_s * opcode, char * line)
{
int bin = opcode->bin_opcode; /* Opcode mask. */
- int __is = 0;
+ int insn_length = 0;
char l1[MAX_OP_LEN], l2[MAX_OP_LEN];
char *frag;
int where;
@@ -1388,6 +2084,14 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
int res = 0;
static short ZEROS = 0;
int byte_op, imm_op;
+ int op_length = 0;
+ int fmt;
+ int extended = 0x1800;
+ bfd_boolean extended_op = FALSE;
+ bfd_boolean addr_op;
+ const char * error_message;
+ static signed int repeat_count = 0;
+ bfd_boolean fix_emitted;
/* Opcode is the one from opcodes table
line contains something like
@@ -1404,11 +2108,22 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
else
byte_op = 0;
- /* skip .[bwBW]. */
+ /* "Address" ops work on 20-bit values. */
+ if (*line == '.' && TOLOWER (*(line + 1)) == 'a')
+ {
+ addr_op = TRUE;
+ bin |= BYTE_OPERATION;
+ }
+ else
+ addr_op = FALSE;
+
+ /* skip .[aAbwBW]. */
while (! ISSPACE (*line) && *line)
line++;
- if (opcode->insn_opnumb && (!*line || *line == '\n'))
+ if (opcode->fmt != -1
+ && opcode->insn_opnumb
+ && (!*line || *line == '\n'))
{
as_bad (_("instruction %s requires %d operand(s)"),
opcode->name, opcode->insn_opnumb);
@@ -1422,204 +2137,1018 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
imm_op = 0;
- switch (opcode->fmt)
+ if ((fmt = opcode->fmt) < 0)
+ {
+ if (! target_is_430x ())
+ {
+ as_bad (_("instruction %s requires MSP430X mcu"),
+ opcode->name);
+ return 0;
+ }
+
+ fmt = (-fmt) - 1;
+ extended_op = TRUE;
+ }
+
+ if (repeat_count)
+ {
+ /* If requested set the extended instruction repeat count. */
+ if (extended_op)
+ {
+ if (repeat_count > 0)
+ extended |= (repeat_count - 1);
+ else
+ extended |= (1 << 7) | (- repeat_count);
+ }
+ else
+ as_bad (_("unable to repeat %s insn"), opcode->name);
+
+ repeat_count = 0;
+ }
+
+ switch (fmt)
{
case 0: /* Emulated. */
switch (opcode->insn_opnumb)
{
case 0:
/* Set/clear bits instructions. */
- __is = 2;
- frag = frag_more (__is);
+ if (extended_op)
+ {
+ if (!addr_op)
+ extended |= BYTE_OPERATION;
+
+ /* Emit the extension word. */
+ insn_length += 2;
+ frag = frag_more (insn_length);
+ bfd_putl16 (extended, frag);
+ }
+
+ insn_length += 2;
+ frag = frag_more (insn_length);
bfd_putl16 ((bfd_vma) bin, frag);
- dwarf2_emit_insn (__is);
+
+ if (gen_interrupt_nops
+ && target_is_430xv2 ()
+ && (is_opcode ("eint") || is_opcode ("dint")))
+ {
+ /* Emit a NOP following interrupt enable/disable.
+ See 1.3.4.1 of the MSP430x5xx User Guide. */
+ insn_length += 2;
+ frag = frag_more (2);
+ bfd_putl16 ((bfd_vma) 0x4303 /* NOP */, frag);
+ }
+ dwarf2_emit_insn (insn_length);
break;
+
case 1:
/* Something which works with destination operand. */
line = extract_operand (line, l1, sizeof (l1));
- res = msp430_dstoperand (&op1, l1, opcode->bin_opcode);
+ res = msp430_dstoperand (&op1, l1, opcode->bin_opcode, extended_op, TRUE);
if (res)
break;
+ /* Compute the entire instruction length, in bytes. */
+ insn_length = (extended_op ? 2 : 0) + 2 + (op1.ol * 2);
+ frag = frag_more (insn_length);
+ where = frag - frag_now->fr_literal;
+
+ if (extended_op)
+ {
+ if (!addr_op)
+ extended |= BYTE_OPERATION;
+
+ if (op1.ol != 0 && ((extended & 0xf) != 0))
+ {
+ as_bad (_("repeat instruction used with non-register mode instruction"));
+ extended &= ~ 0xf;
+ }
+
+ if (op1.mode == OP_EXP)
+ {
+ if (op1.exp.X_op == O_constant)
+ extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7;
+
+ else if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
+ fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
+ BFD_RELOC_MSP430X_ABS20_EXT_SRC);
+ else
+ fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
+ BFD_RELOC_MSP430X_PCR20_EXT_SRC);
+ }
+
+ /* Emit the extension word. */
+ bfd_putl16 (extended, frag);
+ frag += 2;
+ where += 2;
+ }
+
bin |= (op1.reg | (op1.am << 7));
- __is = 1 + op1.ol;
- frag = frag_more (2 * __is);
+ bfd_putl16 ((bfd_vma) bin, frag);
+ frag += 2;
+ where += 2;
+
+ if (op1.mode == OP_EXP)
+ {
+ if (op1.exp.X_op == O_constant)
+ {
+ bfd_putl16 (op1.exp.X_add_number & 0xffff, frag);
+ }
+ else
+ {
+ bfd_putl16 ((bfd_vma) ZEROS, frag);
+
+ if (!extended_op)
+ {
+ if (op1.reg)
+ fix_new_exp (frag_now, where, 2,
+ &(op1.exp), FALSE, CHECK_RELOC_MSP430);
+ else
+ fix_new_exp (frag_now, where, 2,
+ &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
+ }
+ }
+ }
+
+ if (gen_interrupt_nops
+ && target_is_430xv2 ()
+ && is_opcode ("clr")
+ && bin == 0x4302 /* CLR R2*/)
+ {
+ /* Emit a NOP following interrupt enable/disable.
+ See 1.3.4.1 of the MSP430x5xx User Guide. */
+ insn_length += 2;
+ frag = frag_more (2);
+ bfd_putl16 ((bfd_vma) 0x4303 /* NOP */, frag);
+ }
+
+ dwarf2_emit_insn (insn_length);
+ break;
+
+ case 2:
+ /* Shift instruction. */
+ line = extract_operand (line, l1, sizeof (l1));
+ strncpy (l2, l1, sizeof (l2));
+ l2[sizeof (l2) - 1] = '\0';
+ res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op, extended_op, TRUE);
+ res += msp430_dstoperand (&op2, l2, opcode->bin_opcode, extended_op, TRUE);
+
+ if (res)
+ break; /* An error occurred. All warnings were done before. */
+
+ insn_length = (extended_op ? 2 : 0) + 2 + (op1.ol * 2) + (op2.ol * 2);
+ frag = frag_more (insn_length);
where = frag - frag_now->fr_literal;
+
+ /* Issue 3831743. */
+ if (op1.mode == OP_REG
+ && op1.reg == 0
+ && (is_opcode ("rlax")
+ || is_opcode ("rlcx")
+ || is_opcode ("rla")
+ || is_opcode ("rlc")))
+ {
+ as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
+ return 0;
+ }
+
+ if (extended_op)
+ {
+ if (!addr_op)
+ extended |= BYTE_OPERATION;
+
+ if ((op1.ol != 0 || op2.ol != 0) && ((extended & 0xf) != 0))
+ {
+ as_bad (_("repeat instruction used with non-register mode instruction"));
+ extended &= ~ 0xf;
+ }
+
+ if (op1.mode == OP_EXP)
+ {
+ if (op1.exp.X_op == O_constant)
+ extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7;
+
+ else if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
+ fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
+ BFD_RELOC_MSP430X_ABS20_EXT_SRC);
+ else
+ fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
+ BFD_RELOC_MSP430X_PCR20_EXT_SRC);
+ }
+
+ if (op2.mode == OP_EXP)
+ {
+ if (op2.exp.X_op == O_constant)
+ extended |= (op2.exp.X_add_number >> 16) & 0xf;
+
+ else if (op1.mode == OP_EXP)
+ fix_new_exp (frag_now, where, 8, &(op2.exp), FALSE,
+ op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_ODST
+ : BFD_RELOC_MSP430X_PCR20_EXT_ODST);
+ else
+ fix_new_exp (frag_now, where, 6, &(op2.exp), FALSE,
+ op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_DST
+ : BFD_RELOC_MSP430X_PCR20_EXT_DST);
+ }
+
+ /* Emit the extension word. */
+ bfd_putl16 (extended, frag);
+ frag += 2;
+ where += 2;
+ }
+
+ bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7));
bfd_putl16 ((bfd_vma) bin, frag);
- dwarf2_emit_insn (2 * __is);
+ frag += 2;
+ where += 2;
if (op1.mode == OP_EXP)
{
+ if (op1.exp.X_op == O_constant)
+ {
+ bfd_putl16 (op1.exp.X_add_number & 0xffff, frag);
+ }
+ else
+ {
+ bfd_putl16 ((bfd_vma) ZEROS, frag);
+
+ if (!extended_op)
+ {
+ if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
+ fix_new_exp (frag_now, where, 2,
+ &(op1.exp), FALSE, CHECK_RELOC_MSP430);
+ else
+ fix_new_exp (frag_now, where, 2,
+ &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
+ }
+ }
+ frag += 2;
where += 2;
- bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
+ }
- if (op1.reg)
- fix_new_exp (frag_now, where, 2,
- &(op1.exp), FALSE, CHECK_RELOC_MSP430);
+ if (op2.mode == OP_EXP)
+ {
+ if (op2.exp.X_op == O_constant)
+ {
+ bfd_putl16 (op2.exp.X_add_number & 0xffff, frag);
+ }
else
- fix_new_exp (frag_now, where, 2,
- &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
+ {
+ bfd_putl16 ((bfd_vma) ZEROS, frag);
+
+ if (!extended_op)
+ {
+ if (op2.reg) /* Not PC relative. */
+ fix_new_exp (frag_now, where, 2,
+ &(op2.exp), FALSE, CHECK_RELOC_MSP430);
+ else
+ fix_new_exp (frag_now, where, 2,
+ &(op2.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
+ }
+ }
}
+
+ dwarf2_emit_insn (insn_length);
break;
- case 2:
+ case 3:
+ /* Branch instruction => mov dst, r0. */
+ if (extended_op)
+ {
+ as_bad ("Internal error: state 0/3 not coded for extended instructions");
+ return 0;
+ }
+
+ line = extract_operand (line, l1, sizeof (l1));
+ res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op, extended_op, FALSE);
+ if (res)
+ break;
+
+ byte_op = 0;
+ imm_op = 0;
+ bin |= ((op1.reg << 8) | (op1.am << 4));
+ op_length = 2 + 2 * op1.ol;
+ frag = frag_more (op_length);
+ where = frag - frag_now->fr_literal;
+ bfd_putl16 ((bfd_vma) bin, frag);
+
+ if (op1.mode == OP_EXP)
+ {
+ if (op1.exp.X_op == O_constant)
+ {
+ bfd_putl16 (op1.exp.X_add_number & 0xffff, frag + 2);
+ }
+ else
+ {
+ where += 2;
+
+ bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
+
+ if (op1.reg || (op1.reg == 0 && op1.am == 3))
+ fix_new_exp (frag_now, where, 2,
+ &(op1.exp), FALSE, CHECK_RELOC_MSP430);
+ else
+ fix_new_exp (frag_now, where, 2,
+ &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
+ }
+ }
+
+ dwarf2_emit_insn (insn_length + op_length);
+ break;
+
+ case 4:
+ /* CALLA instructions. */
+ fix_emitted = FALSE;
+
+ line = extract_operand (line, l1, sizeof (l1));
+ imm_op = 0;
+
+ res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op,
+ extended_op, FALSE);
+ if (res)
+ break;
+
+ byte_op = 0;
+
+ op_length = 2 + 2 * op1.ol;
+ frag = frag_more (op_length);
+ where = frag - frag_now->fr_literal;
+
+ if (imm_op)
+ {
+ if (op1.am == 3)
+ {
+ bin |= 0xb0;
+
+ fix_new_exp (frag_now, where, 4, &(op1.exp), FALSE,
+ BFD_RELOC_MSP430X_ABS20_ADR_DST);
+ fix_emitted = TRUE;
+ }
+ else if (op1.am == 1)
+ {
+ if (op1.reg == 0)
+ {
+ bin |= 0x90;
+
+ fix_new_exp (frag_now, where, 4, &(op1.exp), FALSE,
+ BFD_RELOC_MSP430X_PCR20_CALL);
+ fix_emitted = TRUE;
+ }
+ else
+ bin |= 0x50 | op1.reg;
+ }
+ else if (op1.am == 0)
+ bin |= 0x40 | op1.reg;
+ }
+ else if (op1.am == 1)
+ {
+ bin |= 0x80;
+
+ fix_new_exp (frag_now, where, 4, &(op1.exp), FALSE,
+ BFD_RELOC_MSP430X_ABS20_ADR_DST);
+ fix_emitted = TRUE;
+ }
+ else if (op1.am == 2)
+ bin |= 0x60 | op1.reg;
+ else if (op1.am == 3)
+ bin |= 0x70 | op1.reg;
+
+ bfd_putl16 ((bfd_vma) bin, frag);
+
+ if (op1.mode == OP_EXP)
+ {
+ if (op1.ol != 1)
+ {
+ as_bad ("Internal error: unexpected CALLA instruction length: %d\n", op1.ol);
+ return 0;
+ }
+
+ bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
+
+ if (! fix_emitted)
+ fix_new_exp (frag_now, where + 2, 2,
+ &(op1.exp), FALSE, BFD_RELOC_16);
+ }
+
+ dwarf2_emit_insn (insn_length + op_length);
+ break;
+
+ case 5:
{
- /* Shift instruction. */
+ int n;
+ int reg;
+
+ /* [POP|PUSH]M[.A] #N, Rd */
line = extract_operand (line, l1, sizeof (l1));
- strncpy (l2, l1, sizeof (l2));
- l2[sizeof (l2) - 1] = '\0';
- res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op);
- res += msp430_dstoperand (&op2, l2, opcode->bin_opcode);
+ line = extract_operand (line, l2, sizeof (l2));
- if (res)
- break; /* An error occurred. All warnings were done before. */
+ if (*l1 != '#')
+ {
+ as_bad (_("expected #n as first argument of %s"), opcode->name);
+ return 0;
+ }
+ parse_exp (l1 + 1, &(op1.exp));
+ if (op1.exp.X_op != O_constant)
+ {
+ as_bad (_("expected constant expression for first argument of %s"),
+ opcode->name);
+ return 0;
+ }
- bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7));
+ if ((reg = check_reg (l2)) == -1)
+ {
+ as_bad (_("expected register as second argument of %s"),
+ opcode->name);
+ return 0;
+ }
- __is = 1 + op1.ol + op2.ol; /* insn size in words. */
- frag = frag_more (2 * __is);
+ op_length = 2;
+ frag = frag_more (op_length);
where = frag - frag_now->fr_literal;
+ bin = opcode->bin_opcode;
+ if (! addr_op)
+ bin |= 0x100;
+ n = op1.exp.X_add_number;
+ bin |= (n - 1) << 4;
+ if (is_opcode ("pushm"))
+ bin |= reg;
+ else
+ {
+ if (reg - n + 1 < 0)
+ {
+ as_bad (_("Too many registers popped"));
+ return 0;
+ }
+
+ /* Issue 3831713: CPU21 parts cannot use POPM to restore the SR register. */
+ if (target_is_430x ()
+ && (reg - n + 1 < 3)
+ && reg >= 2
+ && is_opcode ("popm"))
+ {
+ as_bad (_("Cannot use POPM to restore the SR register"));
+ return 0;
+ }
+
+ bin |= (reg - n + 1);
+ }
+
bfd_putl16 ((bfd_vma) bin, frag);
- dwarf2_emit_insn (2 * __is);
-
- if (op1.mode == OP_EXP)
+ dwarf2_emit_insn (op_length);
+ break;
+ }
+
+ case 6:
+ {
+ int n;
+ int reg;
+
+ /* Bit rotation instructions. RRCM, RRAM, RRUM, RLAM. */
+ if (extended & 0xff)
{
- where += 2; /* Advance 'where' as we do not know _where_. */
- bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
+ as_bad (_("repeat count cannot be used with %s"), opcode->name);
+ return 0;
+ }
- if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
- fix_new_exp (frag_now, where, 2,
- &(op1.exp), FALSE, CHECK_RELOC_MSP430);
- else
- fix_new_exp (frag_now, where, 2,
- &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
+ line = extract_operand (line, l1, sizeof (l1));
+ line = extract_operand (line, l2, sizeof (l2));
+
+ if (*l1 != '#')
+ {
+ as_bad (_("expected #n as first argument of %s"), opcode->name);
+ return 0;
+ }
+ parse_exp (l1 + 1, &(op1.exp));
+ if (op1.exp.X_op != O_constant)
+ {
+ as_bad (_("expected constant expression for first argument of %s"),
+ opcode->name);
+ return 0;
+ }
+ n = op1.exp.X_add_number;
+ if (n > 4 || n < 1)
+ {
+ as_bad (_("expected first argument of %s to be in the range 1-4"),
+ opcode->name);
+ return 0;
}
- if (op2.mode == OP_EXP)
+ if ((reg = check_reg (l2)) == -1)
{
- imm_op = 0;
- bfd_putl16 ((bfd_vma) ZEROS, frag + 2 + ((__is == 3) ? 2 : 0));
+ as_bad (_("expected register as second argument of %s"),
+ opcode->name);
+ return 0;
+ }
- if (op2.reg) /* Not PC relative. */
- fix_new_exp (frag_now, where + 2, 2,
- &(op2.exp), FALSE, CHECK_RELOC_MSP430);
- else
- fix_new_exp (frag_now, where + 2, 2,
- &(op2.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
+ /* Issue 3831743. */
+ if (reg == 0)
+ {
+ as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
+ return 0;
}
+
+ op_length = 2;
+ frag = frag_more (op_length);
+ where = frag - frag_now->fr_literal;
+
+ bin = opcode->bin_opcode;
+ if (! addr_op)
+ bin |= 0x10;
+ bin |= (n - 1) << 10;
+ bin |= reg;
+
+ bfd_putl16 ((bfd_vma) bin, frag);
+ dwarf2_emit_insn (op_length);
break;
}
- case 3:
- /* Branch instruction => mov dst, r0. */
- line = extract_operand (line, l1, sizeof (l1));
- res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op);
- if (res)
+ case 7:
+ {
+ int reg;
+
+ /* RRUX: Synthetic unsigned right shift of a register by one bit. */
+ if (extended & 0xff)
+ {
+ as_bad (_("repeat count cannot be used with %s"), opcode->name);
+ return 0;
+ }
+
+ line = extract_operand (line, l1, sizeof (l1));
+ if ((reg = check_reg (l1)) == -1)
+ {
+ as_bad (_("expected register as argument of %s"),
+ opcode->name);
+ return 0;
+ }
+
+ /* Issue 3831743. */
+ if (reg == 0)
+ {
+ as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
+ return 0;
+ }
+
+ if (byte_op)
+ {
+ /* Tricky - there is no single instruction that will do this.
+ Encode as: RRA.B rN { BIC.B #0x80, rN */
+ op_length = 6;
+ frag = frag_more (op_length);
+ where = frag - frag_now->fr_literal;
+ bin = 0x1140 | reg;
+ bfd_putl16 ((bfd_vma) bin, frag);
+ dwarf2_emit_insn (2);
+ bin = 0xc070 | reg;
+ bfd_putl16 ((bfd_vma) bin, frag + 2);
+ bin = 0x0080;
+ bfd_putl16 ((bfd_vma) bin, frag + 4);
+ dwarf2_emit_insn (4);
+ }
+ else
+ {
+ /* Encode as RRUM[.A] rN. */
+ bin = opcode->bin_opcode;
+ if (! addr_op)
+ bin |= 0x10;
+ bin |= reg;
+ op_length = 2;
+ frag = frag_more (op_length);
+ where = frag - frag_now->fr_literal;
+ bfd_putl16 ((bfd_vma) bin, frag);
+ dwarf2_emit_insn (op_length);
+ }
break;
+ }
- byte_op = 0;
+ case 8:
+ {
+ bfd_boolean need_reloc = FALSE;
+ int n;
+ int reg;
+
+ /* ADDA, CMPA and SUBA address instructions. */
+ if (extended & 0xff)
+ {
+ as_bad (_("repeat count cannot be used with %s"), opcode->name);
+ return 0;
+ }
+
+ line = extract_operand (line, l1, sizeof (l1));
+ line = extract_operand (line, l2, sizeof (l2));
+
+ bin = opcode->bin_opcode;
+
+ if (*l1 == '#')
+ {
+ parse_exp (l1 + 1, &(op1.exp));
+
+ if (op1.exp.X_op == O_constant)
+ {
+ n = op1.exp.X_add_number;
+ if (n > 0xfffff || n < - (0x7ffff))
+ {
+ as_bad (_("expected value of first argument of %s to fit into 20-bits"),
+ opcode->name);
+ return 0;
+ }
+
+ bin |= ((n >> 16) & 0xf) << 8;
+ }
+ else
+ {
+ n = 0;
+ need_reloc = TRUE;
+ }
+
+ op_length = 4;
+ }
+ else
+ {
+ if ((n = check_reg (l1)) == -1)
+ {
+ as_bad (_("expected register name or constant as first argument of %s"),
+ opcode->name);
+ return 0;
+ }
+
+ bin |= (n << 8) | (1 << 6);
+ op_length = 2;
+ }
+
+ if ((reg = check_reg (l2)) == -1)
+ {
+ as_bad (_("expected register as second argument of %s"),
+ opcode->name);
+ return 0;
+ }
+
+ frag = frag_more (op_length);
+ where = frag - frag_now->fr_literal;
+ bin |= reg;
+ if (need_reloc)
+ fix_new_exp (frag_now, where, 4, &(op1.exp), FALSE,
+ BFD_RELOC_MSP430X_ABS20_ADR_SRC);
+
+ bfd_putl16 ((bfd_vma) bin, frag);
+ if (op_length == 4)
+ bfd_putl16 ((bfd_vma) (n & 0xffff), frag + 2);
+ dwarf2_emit_insn (op_length);
+ break;
+ }
+
+ case 9: /* MOVA, BRA, RETA. */
imm_op = 0;
+ bin = opcode->bin_opcode;
- bin |= ((op1.reg << 8) | (op1.am << 4));
- __is = 1 + op1.ol;
- frag = frag_more (2 * __is);
- where = frag - frag_now->fr_literal;
- bfd_putl16 ((bfd_vma) bin, frag);
- dwarf2_emit_insn (2 * __is);
+ if (is_opcode ("reta"))
+ {
+ /* The RETA instruction does not take any arguments.
+ The implicit first argument is @SP+.
+ The implicit second argument is PC. */
+ op1.mode = OP_REG;
+ op1.am = 3;
+ op1.reg = 1;
+
+ op2.mode = OP_REG;
+ op2.reg = 0;
+ }
+ else
+ {
+ line = extract_operand (line, l1, sizeof (l1));
+ res = msp430_srcoperand (&op1, l1, opcode->bin_opcode,
+ &imm_op, extended_op, FALSE);
- if (op1.mode == OP_EXP)
+ if (is_opcode ("bra"))
+ {
+ /* This is the BRA synthetic instruction.
+ The second argument is always PC. */
+ op2.mode = OP_REG;
+ op2.reg = 0;
+ }
+ else
+ {
+ line = extract_operand (line, l2, sizeof (l2));
+ res += msp430_dstoperand (&op2, l2, opcode->bin_opcode,
+ extended_op, TRUE);
+ }
+
+ if (res)
+ break; /* Error occurred. All warnings were done before. */
+ }
+
+ /* Only a restricted subset of the normal MSP430 addressing modes
+ are supported here, so check for the ones that are allowed. */
+ if ((op_length = try_encode_mova (imm_op, bin, & op1, & op2,
+ & error_message)) == 0)
{
- where += 2;
- bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
+ as_bad (error_message, opcode->name);
+ return 0;
+ }
+ dwarf2_emit_insn (op_length);
+ break;
+
+ case 10: /* RPT */
+ line = extract_operand (line, l1, sizeof l1);
+ /* The RPT instruction only accepted immediates and registers. */
+ if (*l1 == '#')
+ {
+ parse_exp (l1 + 1, &(op1.exp));
+ if (op1.exp.X_op != O_constant)
+ {
+ as_bad (_("expected constant value as argument to RPT"));
+ return 0;
+ }
+ if (op1.exp.X_add_number < 1
+ || op1.exp.X_add_number > (1 << 4))
+ {
+ as_bad (_("expected constant in the range 2..16"));
+ return 0;
+ }
+
+ /* We silently accept and ignore a repeat count of 1. */
+ if (op1.exp.X_add_number > 1)
+ repeat_count = op1.exp.X_add_number;
+ }
+ else
+ {
+ int reg;
- if (op1.reg || (op1.reg == 0 && op1.am == 3))
- fix_new_exp (frag_now, where, 2,
- &(op1.exp), FALSE, CHECK_RELOC_MSP430);
+ if ((reg = check_reg (l1)) != -1)
+ {
+ if (reg == 0)
+ as_warn (_("PC used as an argument to RPT"));
+ else
+ repeat_count = - reg;
+ }
else
- fix_new_exp (frag_now, where, 2,
- &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
+ {
+ as_bad (_("expected constant or register name as argument to RPT insn"));
+ return 0;
+ }
}
break;
+
+ default:
+ as_bad (_("Illegal emulated instruction "));
+ break;
}
break;
case 1: /* Format 1, double operand. */
line = extract_operand (line, l1, sizeof (l1));
line = extract_operand (line, l2, sizeof (l2));
- res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op);
- res += msp430_dstoperand (&op2, l2, opcode->bin_opcode);
+ res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op, extended_op, TRUE);
+ res += msp430_dstoperand (&op2, l2, opcode->bin_opcode, extended_op, TRUE);
if (res)
break; /* Error occurred. All warnings were done before. */
- bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7));
+ if (extended_op
+ && is_opcode ("movx")
+ && addr_op
+ && msp430_enable_relax)
+ {
+ /* This is the MOVX.A instruction. See if we can convert
+ it into the MOVA instruction instead. This saves 2 bytes. */
+ if ((op_length = try_encode_mova (imm_op, 0x0000, & op1, & op2,
+ NULL)) != 0)
+ {
+ dwarf2_emit_insn (op_length);
+ break;
+ }
+ }
+
+ /* Compute the entire length of the instruction in bytes. */
+ insn_length =
+ (extended_op ? 2 : 0) /* The extension word. */
+ + 2 /* The opcode */
+ + (2 * op1.ol) /* The first operand. */
+ + (2 * op2.ol); /* The second operand. */
- __is = 1 + op1.ol + op2.ol; /* insn size in words. */
- frag = frag_more (2 * __is);
+ frag = frag_more (insn_length);
where = frag - frag_now->fr_literal;
+
+ if (extended_op)
+ {
+ if (!addr_op)
+ extended |= BYTE_OPERATION;
+
+ if ((op1.ol != 0 || op2.ol != 0) && ((extended & 0xf) != 0))
+ {
+ as_bad (_("repeat instruction used with non-register mode instruction"));
+ extended &= ~ 0xf;
+ }
+
+ /* If necessary, emit a reloc to update the extension word. */
+ if (op1.mode == OP_EXP)
+ {
+ if (op1.exp.X_op == O_constant)
+ extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7;
+
+ else if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
+ fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
+ BFD_RELOC_MSP430X_ABS20_EXT_SRC);
+ else
+ fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
+ BFD_RELOC_MSP430X_PCR20_EXT_SRC);
+ }
+
+ if (op2.mode == OP_EXP)
+ {
+ if (op2.exp.X_op == O_constant)
+ extended |= (op2.exp.X_add_number >> 16) & 0xf;
+
+ else if (op1.mode == OP_EXP)
+ fix_new_exp (frag_now, where, 8, &(op2.exp), FALSE,
+ op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_ODST
+ : BFD_RELOC_MSP430X_PCR20_EXT_ODST);
+
+ else
+ fix_new_exp (frag_now, where, 6, &(op2.exp), FALSE,
+ op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_DST
+ : BFD_RELOC_MSP430X_PCR20_EXT_DST);
+ }
+
+ /* Emit the extension word. */
+ bfd_putl16 (extended, frag);
+ where += 2;
+ frag += 2;
+ }
+
+ bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7));
bfd_putl16 ((bfd_vma) bin, frag);
- dwarf2_emit_insn (2 * __is);
+ where += 2;
+ frag += 2;
if (op1.mode == OP_EXP)
{
- where += 2; /* Advance where as we do not know _where_. */
- bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
-
- if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
- fix_new_exp (frag_now, where, 2,
- &(op1.exp), FALSE, CHECK_RELOC_MSP430);
+ if (op1.exp.X_op == O_constant)
+ {
+ bfd_putl16 (op1.exp.X_add_number & 0xffff, frag);
+ }
else
- fix_new_exp (frag_now, where, 2,
- &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
+ {
+ bfd_putl16 ((bfd_vma) ZEROS, frag);
+
+ if (!extended_op)
+ {
+ if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
+ fix_new_exp (frag_now, where, 2,
+ &(op1.exp), FALSE, CHECK_RELOC_MSP430);
+ else
+ fix_new_exp (frag_now, where, 2,
+ &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
+ }
+ }
+
+ where += 2;
+ frag += 2;
}
if (op2.mode == OP_EXP)
{
- imm_op = 0;
- bfd_putl16 ((bfd_vma) ZEROS, frag + 2 + ((__is == 3) ? 2 : 0));
-
- if (op2.reg) /* Not PC relative. */
- fix_new_exp (frag_now, where + 2, 2,
- &(op2.exp), FALSE, CHECK_RELOC_MSP430);
+ if (op2.exp.X_op == O_constant)
+ {
+ bfd_putl16 (op2.exp.X_add_number & 0xffff, frag);
+ }
else
- fix_new_exp (frag_now, where + 2, 2,
- &(op2.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
+ {
+ bfd_putl16 ((bfd_vma) ZEROS, frag);
+
+ if (!extended_op)
+ {
+ if (op2.reg) /* Not PC relative. */
+ fix_new_exp (frag_now, where, 2,
+ &(op2.exp), FALSE, CHECK_RELOC_MSP430);
+ else
+ fix_new_exp (frag_now, where, 2,
+ &(op2.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
+ }
+ }
}
+
+ if (gen_interrupt_nops
+ && target_is_430xv2 ()
+ && ( (is_opcode ("bic") && bin == 0xc232)
+ || (is_opcode ("bis") && bin == 0xd232)
+ || (is_opcode ("mov") && op2.mode == OP_REG && op2.reg == 2)))
+ {
+ /* Emit a NOP following interrupt enable/disable.
+ See 1.3.4.1 of the MSP430x5xx User Guide. */
+ insn_length += 2;
+ frag = frag_more (2);
+ bfd_putl16 ((bfd_vma) 0x4303 /* NOP */, frag);
+ }
+
+ dwarf2_emit_insn (insn_length);
break;
case 2: /* Single-operand mostly instr. */
if (opcode->insn_opnumb == 0)
{
/* reti instruction. */
+ insn_length += 2;
frag = frag_more (2);
bfd_putl16 ((bfd_vma) bin, frag);
- dwarf2_emit_insn (2);
+ dwarf2_emit_insn (insn_length);
break;
}
line = extract_operand (line, l1, sizeof (l1));
- res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op);
+ res = msp430_srcoperand (&op1, l1, opcode->bin_opcode,
+ &imm_op, extended_op, TRUE);
if (res)
break; /* Error in operand. */
- bin |= op1.reg | (op1.am << 4);
- __is = 1 + op1.ol;
- frag = frag_more (2 * __is);
+ /* Issue 3831743. */
+ if (op1.mode == OP_REG
+ && op1.reg == 0
+ && (is_opcode ("rrax")
+ || is_opcode ("rrcx")
+ || is_opcode ("rra")
+ || is_opcode ("rrc")))
+ {
+ as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
+ return 0;
+ }
+
+ insn_length = (extended_op ? 2 : 0) + 2 + (op1.ol * 2);
+ frag = frag_more (insn_length);
where = frag - frag_now->fr_literal;
+
+ if (extended_op)
+ {
+ if (is_opcode ("swpbx") || is_opcode ("sxtx"))
+ {
+ /* These two instructions use a special
+ encoding of the A/L and B/W bits. */
+ bin &= ~ BYTE_OPERATION;
+
+ if (byte_op)
+ {
+ as_bad (_("%s instruction does not accept a .b suffix"),
+ opcode->name);
+ return 0;
+ }
+ else if (! addr_op)
+ extended |= BYTE_OPERATION;
+ }
+ else if (! addr_op)
+ extended |= BYTE_OPERATION;
+
+ if (op1.ol != 0 && ((extended & 0xf) != 0))
+ {
+ as_bad (_("repeat instruction used with non-register mode instruction"));
+ extended &= ~ 0xf;
+ }
+
+ if (op1.mode == OP_EXP)
+ {
+ if (op1.exp.X_op == O_constant)
+ extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7;
+
+ else if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
+ fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
+ BFD_RELOC_MSP430X_ABS20_EXT_SRC);
+ else
+ fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
+ BFD_RELOC_MSP430X_PCR20_EXT_SRC);
+ }
+
+ /* Emit the extension word. */
+ bfd_putl16 (extended, frag);
+ frag += 2;
+ where += 2;
+ }
+
+ bin |= op1.reg | (op1.am << 4);
bfd_putl16 ((bfd_vma) bin, frag);
- dwarf2_emit_insn (2 * __is);
+ frag += 2;
+ where += 2;
if (op1.mode == OP_EXP)
{
- bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
-
- if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
- fix_new_exp (frag_now, where + 2, 2,
- &(op1.exp), FALSE, CHECK_RELOC_MSP430);
+ if (op1.exp.X_op == O_constant)
+ {
+ bfd_putl16 (op1.exp.X_add_number & 0xffff, frag);
+ }
else
- fix_new_exp (frag_now, where + 2, 2,
- &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
+ {
+ bfd_putl16 ((bfd_vma) ZEROS, frag);
+
+ if (!extended_op)
+ {
+ if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
+ fix_new_exp (frag_now, where, 2,
+ &(op1.exp), FALSE, CHECK_RELOC_MSP430);
+ else
+ fix_new_exp (frag_now, where, 2,
+ &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
+ }
+ }
}
+
+ dwarf2_emit_insn (insn_length);
break;
case 3: /* Conditional jumps instructions. */
@@ -1634,7 +3163,6 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
m++;
parse_exp (m, &exp);
- frag = frag_more (2); /* Instr size is 1 word. */
/* In order to handle something like:
@@ -1678,11 +3206,16 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
break;
}
+ insn_length += 2;
+ frag = frag_more (2); /* Instr size is 1 word. */
+
bin |= x & 0x3ff;
bfd_putl16 ((bfd_vma) bin, frag);
}
else if (exp.X_op == O_symbol && *l1 != '$')
{
+ insn_length += 2;
+ frag = frag_more (2); /* Instr size is 1 word. */
where = frag - frag_now->fr_literal;
fix_new_exp (frag_now, where, 2,
&exp, TRUE, BFD_RELOC_MSP430_10_PCREL);
@@ -1694,11 +3227,9 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
as_bad (_("instruction requires label sans '$'"));
}
else
- {
- as_bad (_
- ("instruction requires label or value in range -511:512"));
- }
- dwarf2_emit_insn (2 * __is);
+ as_bad (_
+ ("instruction requires label or value in range -511:512"));
+ dwarf2_emit_insn (insn_length);
break;
}
else
@@ -1731,15 +3262,20 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
/* Relaxation required. */
struct rcodes_s rc = msp430_rcodes[opcode->insn_opnumb];
- /* The parameter to dwarf2_emit_insn is actually the offset to the start
- of the insn from the fix piece of instruction that was emitted.
- Since next fragments may have variable size we tie debug info
- to the beginning of the instruction. */
+ if (target_is_430x ())
+ rc = msp430x_rcodes[opcode->insn_opnumb];
+
+ /* The parameter to dwarf2_emit_insn is actually the offset to
+ the start of the insn from the fix piece of instruction that
+ was emitted. Since next fragments may have variable size we
+ tie debug info to the beginning of the instruction. */
+ insn_length += 8;
frag = frag_more (8);
dwarf2_emit_insn (0);
bfd_putl16 ((bfd_vma) rc.sop, frag);
frag = frag_variant (rs_machine_dependent, 8, 2,
- ENCODE_RELAX (rc.lpos, STATE_BITS10), /* Wild guess. */
+ /* Wild guess. */
+ ENCODE_RELAX (rc.lpos, STATE_BITS10),
exp.X_add_symbol,
0, /* Offset is zero if jump dist less than 1K. */
(char *) frag);
@@ -1772,6 +3308,10 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
/* Relaxation required. */
struct hcodes_s hc = msp430_hcodes[opcode->insn_opnumb];
+ if (target_is_430x ())
+ hc = msp430x_hcodes[opcode->insn_opnumb];
+
+ insn_length += 8;
frag = frag_more (8);
dwarf2_emit_insn (0);
bfd_putl16 ((bfd_vma) hc.op0, frag);
@@ -1866,16 +3406,20 @@ md_pcrel_from_section (fixS * fixp, segT sec)
/* Replaces standard TC_FORCE_RELOCATION_LOCAL.
Now it handles the situation when relocations
- have to be passed to linker. */
+ have to be passed to linker. */
int
-msp430_force_relocation_local(fixS *fixp)
+msp430_force_relocation_local (fixS *fixp)
{
+ if (fixp->fx_r_type == BFD_RELOC_MSP430_10_PCREL)
+ return 1;
+ if (fixp->fx_pcrel)
+ return 1;
if (msp430_enable_polys
&& !msp430_enable_relax)
return 1;
- else
- return (!fixp->fx_pcrel
- || generic_force_reloc(fixp));
+
+ return (!fixp->fx_pcrel
+ || generic_force_reloc (fixp));
}
@@ -1928,19 +3472,13 @@ md_apply_fix (fixS * fixp, valueT * valuep, segT seg)
value -= S_GET_VALUE (fixp->fx_subsy);
fixp->fx_done = 1;
}
- else
- {
- /* We don't actually support subtracting a symbol. */
- as_bad_where (fixp->fx_file, fixp->fx_line,
- _("expression too complex"));
- }
}
}
fixp->fx_no_overflow = 1;
- /* if polymorphs are enabled and relax disabled.
- do not kill any relocs and pass them to linker. */
+ /* If polymorphs are enabled and relax disabled.
+ do not kill any relocs and pass them to linker. */
if (msp430_enable_polys
&& !msp430_enable_relax)
{
@@ -1955,7 +3493,6 @@ md_apply_fix (fixS * fixp, valueT * valuep, segT seg)
{
/* Fetch the instruction, insert the fully resolved operand
value, and stuff the instruction back again. */
-
where = (unsigned char *) fixp->fx_frag->fr_literal + fixp->fx_where;
insn = bfd_getl16 (where);
@@ -1979,27 +3516,25 @@ md_apply_fix (fixS * fixp, valueT * valuep, segT seg)
bfd_putl16 ((bfd_vma) (value | insn), where);
break;
+ case BFD_RELOC_MSP430X_PCR16:
case BFD_RELOC_MSP430_RL_PCREL:
case BFD_RELOC_MSP430_16_PCREL:
if (value & 1)
as_bad_where (fixp->fx_file, fixp->fx_line,
_("odd address operand: %ld"), value);
-
- /* Nothing to be corrected here. */
- if (value < -32768 || value > 65536)
- as_bad_where (fixp->fx_file, fixp->fx_line,
- _("operand out of range: %ld"), value);
-
- value &= 0xffff; /* Get rid of extended sign. */
- bfd_putl16 ((bfd_vma) value, where);
- break;
+ /* Fall through. */
case BFD_RELOC_MSP430_16_PCREL_BYTE:
/* Nothing to be corrected here. */
if (value < -32768 || value > 65536)
as_bad_where (fixp->fx_file, fixp->fx_line,
_("operand out of range: %ld"), value);
+ /* Fall through. */
+ case BFD_RELOC_MSP430X_ABS16:
+ case BFD_RELOC_MSP430_16:
+ case BFD_RELOC_16:
+ case BFD_RELOC_MSP430_16_BYTE:
value &= 0xffff; /* Get rid of extended sign. */
bfd_putl16 ((bfd_vma) value, where);
break;
@@ -2008,13 +3543,55 @@ md_apply_fix (fixS * fixp, valueT * valuep, segT seg)
bfd_putl16 ((bfd_vma) value, where);
break;
- case BFD_RELOC_MSP430_16:
- case BFD_RELOC_16:
- case BFD_RELOC_MSP430_16_BYTE:
- value &= 0xffff;
- bfd_putl16 ((bfd_vma) value, where);
+ case BFD_RELOC_MSP430_ABS8:
+ case BFD_RELOC_8:
+ bfd_put_8 (NULL, (bfd_vma) value, where);
+ break;
+
+ case BFD_RELOC_MSP430X_ABS20_EXT_SRC:
+ case BFD_RELOC_MSP430X_PCR20_EXT_SRC:
+ bfd_putl16 ((bfd_vma) (value & 0xffff), where + 4);
+ value >>= 16;
+ bfd_putl16 ((bfd_vma) (((value & 0xf) << 7) | insn), where);
break;
+ case BFD_RELOC_MSP430X_ABS20_ADR_SRC:
+ bfd_putl16 ((bfd_vma) (value & 0xffff), where + 2);
+ value >>= 16;
+ bfd_putl16 ((bfd_vma) (((value & 0xf) << 8) | insn), where);
+ break;
+
+ case BFD_RELOC_MSP430X_ABS20_EXT_ODST:
+ bfd_putl16 ((bfd_vma) (value & 0xffff), where + 6);
+ value >>= 16;
+ bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
+ break;
+
+ case BFD_RELOC_MSP430X_PCR20_CALL:
+ bfd_putl16 ((bfd_vma) (value & 0xffff), where + 2);
+ value >>= 16;
+ bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
+ break;
+
+ case BFD_RELOC_MSP430X_ABS20_EXT_DST:
+ case BFD_RELOC_MSP430X_PCR20_EXT_DST:
+ bfd_putl16 ((bfd_vma) (value & 0xffff), where + 4);
+ value >>= 16;
+ bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
+ break;
+
+ case BFD_RELOC_MSP430X_PCR20_EXT_ODST:
+ bfd_putl16 ((bfd_vma) (value & 0xffff), where + 6);
+ value >>= 16;
+ bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
+ break;
+
+ case BFD_RELOC_MSP430X_ABS20_ADR_DST:
+ bfd_putl16 ((bfd_vma) (value & 0xffff), where + 2);
+ value >>= 16;
+ bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
+ break;
+
default:
as_fatal (_("line %d: unknown relocation type: 0x%x"),
fixp->fx_line, fixp->fx_r_type);
@@ -2027,6 +3604,20 @@ md_apply_fix (fixS * fixp, valueT * valuep, segT seg)
}
}
+static bfd_boolean
+S_IS_GAS_LOCAL (symbolS * s)
+{
+ const char * name;
+ unsigned int len;
+
+ if (s == NULL)
+ return FALSE;
+ name = S_GET_NAME (s);
+ len = strlen (name) - 1;
+
+ return name[len] == 1 || name[len] == 2;
+}
+
/* GAS will call this to generate a reloc, passing the resulting reloc
to `bfd_install_relocation'. This currently works poorly, as
`bfd_install_relocation' often does the wrong thing, and instances of
@@ -2036,33 +3627,157 @@ md_apply_fix (fixS * fixp, valueT * valuep, segT seg)
/* If while processing a fixup, a reloc really needs to be created
then it is done here. */
-arelent *
+arelent **
tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, fixS * fixp)
{
- arelent * reloc;
+ static arelent * no_relocs = NULL;
+ static arelent * relocs[MAX_RELOC_EXPANSION + 1];
+ arelent *reloc;
reloc = xmalloc (sizeof (arelent));
-
- reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
- *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
-
reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
+
if (reloc->howto == (reloc_howto_type *) NULL)
{
as_bad_where (fixp->fx_file, fixp->fx_line,
_("reloc %d not supported by object file format"),
(int) fixp->fx_r_type);
- return NULL;
+ free (reloc);
+ return & no_relocs;
}
- if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
- || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
- reloc->address = fixp->fx_offset;
+ relocs[0] = reloc;
+ relocs[1] = NULL;
- reloc->addend = fixp->fx_offset;
+ if (fixp->fx_subsy
+ && S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
+ {
+ fixp->fx_offset -= S_GET_VALUE (fixp->fx_subsy);
+ fixp->fx_subsy = NULL;
+ }
- return reloc;
+ if (fixp->fx_addsy && fixp->fx_subsy)
+ {
+ asection *asec, *ssec;
+
+ asec = S_GET_SEGMENT (fixp->fx_addsy);
+ ssec = S_GET_SEGMENT (fixp->fx_subsy);
+
+ /* If we have a difference between two different, non-absolute symbols
+ we must generate two relocs (one for each symbol) and allow the
+ linker to resolve them - relaxation may change the distances between
+ symbols, even local symbols defined in the same section.
+
+ Unfortunately we cannot do this with assembler generated local labels
+ because there can be multiple incarnations of the same label, with
+ exactly the same name, in any given section and the linker will have
+ no way to identify the correct one. Instead we just have to hope
+ that no relaxtion will occur between the local label and the other
+ symbol in the expression.
+
+ Similarly we have to compute differences between symbols in the .eh_frame
+ section as the linker is not smart enough to apply relocations there
+ before attempting to process it. */
+ if ((ssec != absolute_section || asec != absolute_section)
+ && (fixp->fx_addsy != fixp->fx_subsy)
+ && strcmp (ssec->name, ".eh_frame") != 0
+ && ! S_IS_GAS_LOCAL (fixp->fx_addsy)
+ && ! S_IS_GAS_LOCAL (fixp->fx_subsy))
+ {
+ arelent * reloc2 = xmalloc (sizeof * reloc);
+
+ relocs[0] = reloc2;
+ relocs[1] = reloc;
+
+ reloc2->address = reloc->address;
+ reloc2->howto = bfd_reloc_type_lookup (stdoutput,
+ BFD_RELOC_MSP430_SYM_DIFF);
+ reloc2->addend = - S_GET_VALUE (fixp->fx_subsy);
+
+ if (ssec == absolute_section)
+ reloc2->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
+ else
+ {
+ reloc2->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
+ *reloc2->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_subsy);
+ }
+
+ reloc->addend = fixp->fx_offset;
+ if (asec == absolute_section)
+ {
+ reloc->addend += S_GET_VALUE (fixp->fx_addsy);
+ reloc->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
+ }
+ else
+ {
+ reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
+ *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
+ }
+
+ fixp->fx_pcrel = 0;
+ fixp->fx_done = 1;
+ return relocs;
+ }
+ else
+ {
+ char *fixpos = fixp->fx_where + fixp->fx_frag->fr_literal;
+
+ reloc->addend = (S_GET_VALUE (fixp->fx_addsy)
+ - S_GET_VALUE (fixp->fx_subsy) + fixp->fx_offset);
+
+ switch (fixp->fx_r_type)
+ {
+ case BFD_RELOC_8:
+ md_number_to_chars (fixpos, reloc->addend, 1);
+ break;
+
+ case BFD_RELOC_16:
+ md_number_to_chars (fixpos, reloc->addend, 2);
+ break;
+
+ case BFD_RELOC_24:
+ md_number_to_chars (fixpos, reloc->addend, 3);
+ break;
+
+ case BFD_RELOC_32:
+ md_number_to_chars (fixpos, reloc->addend, 4);
+ break;
+
+ default:
+ reloc->sym_ptr_ptr
+ = (asymbol **) bfd_abs_section_ptr->symbol_ptr_ptr;
+ return relocs;
+ }
+
+ free (reloc);
+ return & no_relocs;
+ }
+ }
+ else
+ {
+#if 0
+ if (fixp->fx_r_type == BFD_RELOC_MSP430X_ABS16
+ && S_GET_SEGMENT (fixp->fx_addsy) == absolute_section)
+ {
+ bfd_vma amount = S_GET_VALUE (fixp->fx_addsy);
+ char *fixpos = fixp->fx_where + fixp->fx_frag->fr_literal;
+
+ md_number_to_chars (fixpos, amount, 2);
+ free (reloc);
+ return & no_relocs;
+ }
+#endif
+ reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
+ *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
+ reloc->addend = fixp->fx_offset;
+
+ if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+ || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+ reloc->address = fixp->fx_offset;
+ }
+
+ return relocs;
}
int
@@ -2121,7 +3836,10 @@ md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_WORD):
case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_UNDEF):
/* Convert uncond branch jmp lab -> br lab. */
- cc = & msp430_rcodes[7];
+ if (target_is_430x ())
+ cc = msp430x_rcodes + 7;
+ else
+ cc = msp430_rcodes + 7;
where = fragP->fr_literal + fragP->fr_fix;
bfd_putl16 (cc->lop0, where);
rela = BFD_RELOC_MSP430_RL_PCREL;
@@ -2136,9 +3854,19 @@ md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
insn &= 0xffff;
/* Find actual instruction. */
- for (i = 0; i < 7 && !cc; i++)
- if (msp430_rcodes[i].sop == insn)
- cc = & msp430_rcodes[i];
+ if (target_is_430x ())
+ {
+ for (i = 0; i < 7 && !cc; i++)
+ if (msp430x_rcodes[i].sop == insn)
+ cc = msp430x_rcodes + i;
+ }
+ else
+ {
+ for (i = 0; i < 7 && !cc; i++)
+ if (msp430_rcodes[i].sop == insn)
+ cc = & msp430_rcodes[i];
+ }
+
if (!cc || !cc->name)
as_fatal (_("internal inconsistency problem in %s: insn %04lx"),
__FUNCTION__, (long) insn);
@@ -2152,7 +3880,10 @@ md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_WORD):
case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_UNDEF):
- cc = & msp430_rcodes[6];
+ if (target_is_430x ())
+ cc = msp430x_rcodes + 6;
+ else
+ cc = msp430_rcodes + 6;
where = fragP->fr_literal + fragP->fr_fix;
bfd_putl16 (cc->lop0, where);
bfd_putl16 (cc->lop1, where + 2);
@@ -2166,9 +3897,18 @@ md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
int insn = bfd_getl16 (fragP->fr_opcode + 2);
insn &= 0xffff;
- for (i = 0; i < 4 && !hc; i++)
- if (msp430_hcodes[i].op1 == insn)
- hc = &msp430_hcodes[i];
+ if (target_is_430x ())
+ {
+ for (i = 0; i < 4 && !hc; i++)
+ if (msp430x_hcodes[i].op1 == insn)
+ hc = msp430x_hcodes + i;
+ }
+ else
+ {
+ for (i = 0; i < 4 && !hc; i++)
+ if (msp430_hcodes[i].op1 == insn)
+ hc = &msp430_hcodes[i];
+ }
if (!hc || !hc->name)
as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
__FUNCTION__, (long) insn);
@@ -2177,7 +3917,7 @@ md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
another fix will be applied to the next word of insn anyway. */
if (hc->tlab == 2)
fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
- fragP->fr_offset, TRUE, rela);
+ fragP->fr_offset, TRUE, rela);
fragP->fr_fix += 2;
}
@@ -2189,9 +3929,18 @@ md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
int insn = bfd_getl16 (fragP->fr_opcode + 2);
insn &= 0xffff;
- for (i = 0; i < 4 && !hc; i++)
- if (msp430_hcodes[i].op1 == insn)
- hc = & msp430_hcodes[i];
+ if (target_is_430x ())
+ {
+ for (i = 0; i < 4 && !hc; i++)
+ if (msp430x_hcodes[i].op1 == insn)
+ hc = msp430x_hcodes + i;
+ }
+ else
+ {
+ for (i = 0; i < 4 && !hc; i++)
+ if (msp430_hcodes[i].op1 == insn)
+ hc = & msp430_hcodes[i];
+ }
if (!hc || !hc->name)
as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
__FUNCTION__, (long) insn);
@@ -2251,7 +4000,7 @@ msp430_relax_frag (segT seg ATTRIBUTE_UNUSED, fragS * fragP,
if (!msp430_enable_relax)
{
/* Relaxation is not enabled. So, make all jump as long ones
- by setting 'aim' to quite high value. */
+ by setting 'aim' to quite high value. */
aim = 0x7fff;
}
@@ -2292,3 +4041,58 @@ msp430_relax_frag (segT seg ATTRIBUTE_UNUSED, fragS * fragP,
fragP->fr_subtype = this_state;
return growth;
}
+
+/* Return FALSE if the fixup in fixp should be left alone and not
+ adjusted. We return FALSE here so that linker relaxation will
+ work. */
+
+bfd_boolean
+msp430_fix_adjustable (struct fix *fixp ATTRIBUTE_UNUSED)
+{
+ /* If the symbol is in a non-code section then it should be OK. */
+ if (fixp->fx_addsy
+ && ((S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_CODE) == 0))
+ return TRUE;
+
+ return FALSE;
+}
+
+/* Set the contents of the .MSP430.attributes section. */
+
+void
+msp430_md_end (void)
+{
+ bfd_elf_add_proc_attr_int (stdoutput, OFBA_MSPABI_Tag_ISA,
+ target_is_430x () ? 2 : 1);
+
+ bfd_elf_add_proc_attr_int (stdoutput, OFBA_MSPABI_Tag_Code_Model,
+ large_model ? 2 : 1);
+
+ bfd_elf_add_proc_attr_int (stdoutput, OFBA_MSPABI_Tag_Data_Model,
+ large_model ? 2 : 1);
+}
+
+/* Returns FALSE if there is a msp430 specific reason why the
+ subtraction of two same-section symbols cannot be computed by
+ the assembler. */
+
+bfd_boolean
+msp430_allow_local_subtract (expressionS * left,
+ expressionS * right,
+ segT section)
+{
+ /* If the symbols are not in a code section then they are OK. */
+ if ((section->flags & SEC_CODE) == 0)
+ return TRUE;
+
+ if (S_IS_GAS_LOCAL (left->X_add_symbol) || S_IS_GAS_LOCAL (right->X_add_symbol))
+ return TRUE;
+
+ if (left->X_add_symbol == right->X_add_symbol)
+ return TRUE;
+
+ /* We have to assume that there may be instructions between the
+ two symbols and that relaxation may increase the distance between
+ them. */
+ return FALSE;
+}
diff --git a/gas/config/tc-msp430.h b/gas/config/tc-msp430.h
index 118b46d3f..f805f666d 100644
--- a/gas/config/tc-msp430.h
+++ b/gas/config/tc-msp430.h
@@ -1,5 +1,5 @@
/* This file is tc-msp430.h
- Copyright (C) 2002, 2004, 2005, 2007 Free Software Foundation, Inc.
+ Copyright (C) 2002-2013 Free Software Foundation, Inc.
Contributed by Dmitry Diky <diwil@mail.ru>
@@ -99,8 +99,9 @@ extern long md_pcrel_from_section (struct fix *, segT);
example, a value of 2 might print `1234 5678' where a value of 1
would print `12 34 56 78'. The default value is 4. */
-#define LEX_DOLLAR 0
-/* MSP430 port does not use `$' as a logical line separator */
+/* Support symbols like: C$$IO$$. */
+#undef LEX_DOLLAR
+#define LEX_DOLLAR 1
#define TC_IMPLICIT_LCOMM_ALIGNMENT(SIZE, P2VAR) (P2VAR) = 0
/* An `.lcomm' directive with no explicit alignment parameter will
@@ -116,9 +117,52 @@ extern long md_pcrel_from_section (struct fix *, segT);
extern long msp430_relax_frag (segT, fragS *, long);
#define TC_FORCE_RELOCATION_LOCAL(FIX) \
- msp430_force_relocation_local(FIX)
-extern int msp430_force_relocation_local(struct fix *);
-
+ msp430_force_relocation_local (FIX)
+extern int msp430_force_relocation_local (struct fix *);
extern int msp430_enable_relax;
extern int msp430_enable_polys;
+
+#define tc_fix_adjustable(FIX) msp430_fix_adjustable (FIX)
+extern bfd_boolean msp430_fix_adjustable (struct fix *);
+
+/* Allow hexadeciaml numbers with 'h' suffix. Note that if the number
+ starts with a letter it will be interpreted as a symbol name not a
+ constant. Thus "beach" is a symbol not the hex value 0xbeac. So
+ is A5A5h... */
+#define NUMBERS_WITH_SUFFIX 1
+
+#define md_end msp430_md_end
+extern void msp430_md_end (void);
+
+/* Do not allow call frame debug info optimization as otherwise we could
+ generate the DWARF directives without the relocs necessary to patch
+ them up. */
+#define md_allow_eh_opt 0
+
+/* The difference between same-section symbols may be affected by linker
+ relaxation, so do not resolve such expressions in the assembler. */
+#define md_allow_local_subtract(l,r,s) msp430_allow_local_subtract (l, r, s)
+extern bfd_boolean msp430_allow_local_subtract (expressionS *, expressionS *, segT);
+
+#define RELOC_EXPANSION_POSSIBLE
+#define MAX_RELOC_EXPANSION 2
+
+#define DIFF_EXPR_OK
+
+/* Do not adjust relocations involving symbols in code sections,
+ because it breaks linker relaxations. This could be fixed in the
+ linker, but this fix is simpler, and it pretty much only affects
+ object size a little bit. */
+#define TC_FORCE_RELOCATION_SUB_SAME(FIX, SEC) \
+ (((SEC)->flags & SEC_CODE) != 0 \
+ || ! SEG_NORMAL (SEC) \
+ || TC_FORCE_RELOCATION (FIX))
+
+/* We validate subtract arguments within tc_gen_reloc(),
+ so don't report errors at this point. */
+#define TC_VALIDATE_FIX_SUB(FIX, SEG) 1
+
+#define DWARF2_USE_FIXED_ADVANCE_PC 1
+
+#define TC_LINKRELAX_FIXUP(seg) (seg->flags & SEC_CODE)
diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c
index 0929e5224..d4f6b7168 100644
--- a/gas/config/tc-ppc.c
+++ b/gas/config/tc-ppc.c
@@ -64,40 +64,14 @@ static int set_target_endian = 0;
/* #lo(value) denotes the least significant 16 bits of the indicated. */
#define PPC_LO(v) ((v) & 0xffff)
-/* Split the indicated value with the msbs in bits 11-15
- and the lsbs in bits 21-31. */
-#define PPC_VLE_SPLIT16A(v) ((v & 0xf800) << 11) | (v & 0x7ff)
-
-/* Split the indicated value with the msbs in bits 6-10
- and the lsbs in bits 21-31. */
-#define PPC_VLE_SPLIT16D(v) ((v & 0xf800) << 5) | (v & 0x7ff)
-
-/* #lo(value) denotes the lsb 16 bits in split16a format. */
-#define PPC_VLE_LO16A(v) PPC_VLE_SPLIT16A(PPC_LO(v))
-
-/* #lo(value) denotes the lsb 16 bits in split16d format. */
-#define PPC_VLE_LO16D(v) PPC_VLE_SPLIT16D(PPC_LO(v))
-
/* #hi(value) denotes bits 16 through 31 of the indicated value. */
#define PPC_HI(v) (((v) >> 16) & 0xffff)
-/* #lo(value) denotes the msb 16 bits in split16a format. */
-#define PPC_VLE_HI16A(v) PPC_VLE_SPLIT16A(PPC_HI(v))
-
-/* #lo(value) denotes the msb 16 bits in split16d format. */
-#define PPC_VLE_HI16D(v) PPC_VLE_SPLIT16D(PPC_HI(v))
-
/* #ha(value) denotes the high adjusted value: bits 16 through 31 of
the indicated value, compensating for #lo() being treated as a
signed number. */
#define PPC_HA(v) PPC_HI ((v) + 0x8000)
-/* #ha(value) denotes the high adjusted value in split16a format. */
-#define PPC_VLE_HA16A(v) PPC_VLE_SPLIT16A(PPC_HA(v))
-
-/* #ha(value) denotes the high adjusted value in split16d format. */
-#define PPC_VLE_HA16D(v) PPC_VLE_SPLIT16D(PPC_HA(v))
-
/* #higher(value) denotes bits 32 through 47 of the indicated value. */
#define PPC_HIGHER(v) (((v) >> 16 >> 16) & 0xffff)
@@ -1552,10 +1526,10 @@ ppc_setup_opcodes (void)
int new_opcode = PPC_OP (op[0].opcode);
#ifdef PRINT_OPCODE_TABLE
- printf ("%-14s\t#%04d\tmajor op: 0x%x\top: 0x%x\tmask: 0x%x\tflags: 0x%llx\n",
- op->name, op - powerpc_opcodes, (unsigned int) new_opcode,
- (unsigned int) op->opcode, (unsigned int) op->mask,
- (unsigned long long) op->flags);
+ printf ("%-14s\t#%04u\tmajor op: 0x%x\top: 0x%x\tmask: 0x%x\tflags: 0x%llx\n",
+ op->name, (unsigned int) (op - powerpc_opcodes),
+ (unsigned int) new_opcode, (unsigned int) op->opcode,
+ (unsigned int) op->mask, (unsigned long long) op->flags);
#endif
/* The major opcodes had better be sorted. Code in the
@@ -1605,10 +1579,10 @@ ppc_setup_opcodes (void)
new_seg = VLE_OP_TO_SEG (new_seg);
#ifdef PRINT_OPCODE_TABLE
- printf ("%-14s\t#%04d\tmajor op: 0x%x\top: 0x%x\tmask: 0x%x\tflags: 0x%llx\n",
- op->name, op - powerpc_opcodes, (unsigned int) new_opcode,
- (unsigned int) op->opcode, (unsigned int) op->mask,
- (unsigned long long) op->flags);
+ printf ("%-14s\t#%04u\tmajor op: 0x%x\top: 0x%x\tmask: 0x%x\tflags: 0x%llx\n",
+ op->name, (unsigned int) (op - powerpc_opcodes),
+ (unsigned int) new_seg, (unsigned int) op->opcode,
+ (unsigned int) op->mask, (unsigned long long) op->flags);
#endif
/* The major opcodes had better be sorted. Code in the
disassembler assumes the insns are sorted according to
@@ -2454,7 +2428,8 @@ static int
ppc_is_toc_sym (symbolS *sym)
{
#ifdef OBJ_XCOFF
- return symbol_get_tc (sym)->symbol_class == XMC_TC;
+ return (symbol_get_tc (sym)->symbol_class == XMC_TC
+ || symbol_get_tc (sym)->symbol_class == XMC_TC0);
#endif
#ifdef OBJ_ELF
const char *sname = segment_name (S_GET_SEGMENT (sym));
@@ -6312,6 +6287,8 @@ void
md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
{
valueT value = * valP;
+ offsetT fieldval;
+ const struct powerpc_operand *operand;
#ifdef OBJ_ELF
if (fixP->fx_addsy != NULL)
@@ -6350,16 +6327,13 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex"));
}
+ operand = NULL;
if (fixP->fx_pcrel_adjust != 0)
{
- /* Handle relocs in an insn. */
-
+ /* This is a fixup on an instruction. */
int opindex = fixP->fx_pcrel_adjust & 0xff;
- const struct powerpc_operand *operand = &powerpc_operands[opindex];
- char *where;
- unsigned long insn;
- offsetT fieldval;
+ operand = &powerpc_operands[opindex];
#ifdef OBJ_XCOFF
/* An instruction like `lwz 9,sym(30)' when `sym' is not a TOC symbol
does not generate a reloc. It uses the offset of `sym' within its
@@ -6379,64 +6353,75 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
fixP->fx_done = 1;
}
#endif
- fieldval = value;
- switch (fixP->fx_r_type)
- {
+ }
+
+ /* Calculate value to be stored in field. */
+ fieldval = value;
+ switch (fixP->fx_r_type)
+ {
#ifdef OBJ_ELF
- case BFD_RELOC_PPC64_ADDR16_LO_DS:
- if (fixP->fx_pcrel)
- goto bad_pcrel;
- /* fall through */
+ case BFD_RELOC_PPC64_ADDR16_LO_DS:
+ case BFD_RELOC_PPC_VLE_LO16A:
+ case BFD_RELOC_PPC_VLE_LO16D:
#endif
- case BFD_RELOC_LO16:
- if (fixP->fx_pcrel)
- fixP->fx_r_type = BFD_RELOC_LO16_PCREL;
- /* fall through */
- case BFD_RELOC_LO16_PCREL:
- fieldval = SEX16 (value);
- break;
+ case BFD_RELOC_LO16:
+ case BFD_RELOC_LO16_PCREL:
+ fieldval = value & 0xffff;
+ sign_extend_16:
+ if (operand != NULL && (operand->flags & PPC_OPERAND_SIGNED) != 0)
+ fieldval = (fieldval ^ 0x8000) - 0x8000;
+ fixP->fx_no_overflow = 1;
+ break;
- case BFD_RELOC_HI16:
- if (fixP->fx_pcrel)
- fixP->fx_r_type = BFD_RELOC_HI16_PCREL;
- /* fall through */
- case BFD_RELOC_HI16_PCREL:
- fieldval = SEX16 (PPC_HI (value));
- break;
+#ifdef OBJ_ELF
+ case BFD_RELOC_PPC_VLE_HI16A:
+ case BFD_RELOC_PPC_VLE_HI16D:
+#endif
+ case BFD_RELOC_HI16:
+ case BFD_RELOC_HI16_PCREL:
+ fieldval = PPC_HI (value);
+ goto sign_extend_16;
- case BFD_RELOC_HI16_S:
- if (fixP->fx_pcrel)
- fixP->fx_r_type = BFD_RELOC_HI16_S_PCREL;
- /* fall through */
- case BFD_RELOC_HI16_S_PCREL:
- fieldval = SEX16 (PPC_HA (value));
- break;
+#ifdef OBJ_ELF
+ case BFD_RELOC_PPC_VLE_HA16A:
+ case BFD_RELOC_PPC_VLE_HA16D:
+#endif
+ case BFD_RELOC_HI16_S:
+ case BFD_RELOC_HI16_S_PCREL:
+ fieldval = PPC_HA (value);
+ goto sign_extend_16;
#ifdef OBJ_ELF
- case BFD_RELOC_PPC64_HIGHER:
- if (fixP->fx_pcrel)
- goto bad_pcrel;
- fieldval = SEX16 (PPC_HIGHER (value));
- break;
+ case BFD_RELOC_PPC64_HIGHER:
+ fieldval = PPC_HIGHER (value);
+ goto sign_extend_16;
- case BFD_RELOC_PPC64_HIGHER_S:
- if (fixP->fx_pcrel)
- goto bad_pcrel;
- fieldval = SEX16 (PPC_HIGHERA (value));
- break;
+ case BFD_RELOC_PPC64_HIGHER_S:
+ fieldval = PPC_HIGHERA (value);
+ goto sign_extend_16;
- case BFD_RELOC_PPC64_HIGHEST:
- if (fixP->fx_pcrel)
- goto bad_pcrel;
- fieldval = SEX16 (PPC_HIGHEST (value));
- break;
+ case BFD_RELOC_PPC64_HIGHEST:
+ fieldval = PPC_HIGHEST (value);
+ goto sign_extend_16;
- case BFD_RELOC_PPC64_HIGHEST_S:
- if (fixP->fx_pcrel)
- goto bad_pcrel;
- fieldval = SEX16 (PPC_HIGHESTA (value));
- break;
+ case BFD_RELOC_PPC64_HIGHEST_S:
+ fieldval = PPC_HIGHESTA (value);
+ goto sign_extend_16;
+#endif
+
+ default:
+ break;
+ }
+
+ if (operand != NULL)
+ {
+ /* Handle relocs in an insn. */
+ char *where;
+ unsigned long insn;
+#ifdef OBJ_ELF
+ switch (fixP->fx_r_type)
+ {
/* The following relocs can't be calculated by the assembler.
Leave the field zero. */
case BFD_RELOC_PPC_TPREL16:
@@ -6478,8 +6463,6 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
gas_assert (fixP->fx_addsy != NULL);
S_SET_THREAD_LOCAL (fixP->fx_addsy);
fieldval = 0;
- if (fixP->fx_pcrel)
- goto bad_pcrel;
break;
/* These also should leave the field zero for the same
@@ -6546,14 +6529,12 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
case BFD_RELOC_PPC_TLSGD:
case BFD_RELOC_PPC_TLSLD:
fieldval = 0;
- if (fixP->fx_pcrel)
- goto bad_pcrel;
break;
-#endif
default:
break;
}
+#endif
#ifdef OBJ_ELF
/* powerpc uses RELA style relocs, so if emitting a reloc the field
@@ -6625,79 +6606,9 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
}
else
{
- int size = 0;
- offsetT fieldval = value;
-
/* Handle relocs in data. */
switch (fixP->fx_r_type)
{
- case BFD_RELOC_CTOR:
- if (ppc_obj64)
- goto ctor64;
- /* fall through */
-
- case BFD_RELOC_32:
- if (fixP->fx_pcrel)
- fixP->fx_r_type = BFD_RELOC_32_PCREL;
- /* fall through */
-
- case BFD_RELOC_32_PCREL:
- case BFD_RELOC_RVA:
- size = 4;
- break;
-
- case BFD_RELOC_64:
- ctor64:
- if (fixP->fx_pcrel)
- fixP->fx_r_type = BFD_RELOC_64_PCREL;
- /* fall through */
-
- case BFD_RELOC_64_PCREL:
- size = 8;
- break;
-
- case BFD_RELOC_16:
- if (fixP->fx_pcrel)
- fixP->fx_r_type = BFD_RELOC_16_PCREL;
- /* fall through */
-
- case BFD_RELOC_16_PCREL:
- size = 2;
- break;
-
- case BFD_RELOC_8:
- if (fixP->fx_pcrel)
- {
-#ifdef OBJ_ELF
- bad_pcrel:
-#endif
- if (fixP->fx_addsy)
- {
- char *sfile;
- unsigned int sline;
-
- /* Use expr_symbol_where to see if this is an
- expression symbol. */
- if (expr_symbol_where (fixP->fx_addsy, &sfile, &sline))
- as_bad_where (fixP->fx_file, fixP->fx_line,
- _("unresolved expression that must"
- " be resolved"));
- else
- as_bad_where (fixP->fx_file, fixP->fx_line,
- _("cannot emit PC relative %s relocation"
- " against %s"),
- bfd_get_reloc_code_name (fixP->fx_r_type),
- S_GET_NAME (fixP->fx_addsy));
- }
- else
- as_bad_where (fixP->fx_file, fixP->fx_line,
- _("unable to resolve expression"));
- fixP->fx_done = 1;
- }
- else
- size = 1;
- break;
-
case BFD_RELOC_VTABLE_INHERIT:
if (fixP->fx_addsy
&& !S_IS_DEFINED (fixP->fx_addsy)
@@ -6712,54 +6623,15 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
#ifdef OBJ_ELF
/* These can appear with @l etc. in data. */
case BFD_RELOC_LO16:
- if (fixP->fx_pcrel)
- fixP->fx_r_type = BFD_RELOC_LO16_PCREL;
case BFD_RELOC_LO16_PCREL:
- size = 2;
- break;
-
case BFD_RELOC_HI16:
- if (fixP->fx_pcrel)
- fixP->fx_r_type = BFD_RELOC_HI16_PCREL;
case BFD_RELOC_HI16_PCREL:
- size = 2;
- fieldval = PPC_HI (value);
- break;
-
case BFD_RELOC_HI16_S:
- if (fixP->fx_pcrel)
- fixP->fx_r_type = BFD_RELOC_HI16_S_PCREL;
case BFD_RELOC_HI16_S_PCREL:
- size = 2;
- fieldval = PPC_HA (value);
- break;
-
case BFD_RELOC_PPC64_HIGHER:
- if (fixP->fx_pcrel)
- goto bad_pcrel;
- size = 2;
- fieldval = PPC_HIGHER (value);
- break;
-
case BFD_RELOC_PPC64_HIGHER_S:
- if (fixP->fx_pcrel)
- goto bad_pcrel;
- size = 2;
- fieldval = PPC_HIGHERA (value);
- break;
-
case BFD_RELOC_PPC64_HIGHEST:
- if (fixP->fx_pcrel)
- goto bad_pcrel;
- size = 2;
- fieldval = PPC_HIGHEST (value);
- break;
-
case BFD_RELOC_PPC64_HIGHEST_S:
- if (fixP->fx_pcrel)
- goto bad_pcrel;
- size = 2;
- fieldval = PPC_HIGHESTA (value);
break;
case BFD_RELOC_PPC_DTPMOD:
@@ -6850,8 +6722,17 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
#ifdef OBJ_XCOFF
case BFD_RELOC_NONE:
- break;
#endif
+ case BFD_RELOC_CTOR:
+ case BFD_RELOC_32:
+ case BFD_RELOC_32_PCREL:
+ case BFD_RELOC_RVA:
+ case BFD_RELOC_64:
+ case BFD_RELOC_64_PCREL:
+ case BFD_RELOC_16:
+ case BFD_RELOC_16_PCREL:
+ case BFD_RELOC_8:
+ break;
default:
fprintf (stderr,
@@ -6860,9 +6741,85 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
abort ();
}
- if (size && APPLY_RELOC)
+ if (fixP->fx_size && APPLY_RELOC)
md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
- fieldval, size);
+ fieldval, fixP->fx_size);
+ }
+
+ /* We are only able to convert some relocs to pc-relative. */
+ if (!fixP->fx_done && fixP->fx_pcrel)
+ {
+ switch (fixP->fx_r_type)
+ {
+ case BFD_RELOC_LO16:
+ fixP->fx_r_type = BFD_RELOC_LO16_PCREL;
+ break;
+
+ case BFD_RELOC_HI16:
+ fixP->fx_r_type = BFD_RELOC_HI16_PCREL;
+ break;
+
+ case BFD_RELOC_HI16_S:
+ fixP->fx_r_type = BFD_RELOC_HI16_S_PCREL;
+ break;
+
+ case BFD_RELOC_64:
+ fixP->fx_r_type = BFD_RELOC_64_PCREL;
+ break;
+
+ case BFD_RELOC_32:
+ fixP->fx_r_type = BFD_RELOC_32_PCREL;
+ break;
+
+ case BFD_RELOC_16:
+ fixP->fx_r_type = BFD_RELOC_16_PCREL;
+ break;
+
+ /* Some of course are already pc-relative. */
+ case BFD_RELOC_LO16_PCREL:
+ case BFD_RELOC_HI16_PCREL:
+ case BFD_RELOC_HI16_S_PCREL:
+ case BFD_RELOC_64_PCREL:
+ case BFD_RELOC_32_PCREL:
+ case BFD_RELOC_16_PCREL:
+ case BFD_RELOC_PPC_B16:
+ case BFD_RELOC_PPC_B16_BRTAKEN:
+ case BFD_RELOC_PPC_B16_BRNTAKEN:
+ case BFD_RELOC_PPC_B26:
+ case BFD_RELOC_PPC_LOCAL24PC:
+ case BFD_RELOC_24_PLT_PCREL:
+ case BFD_RELOC_32_PLT_PCREL:
+ case BFD_RELOC_64_PLT_PCREL:
+ case BFD_RELOC_PPC_VLE_REL8:
+ case BFD_RELOC_PPC_VLE_REL15:
+ case BFD_RELOC_PPC_VLE_REL24:
+ break;
+
+ default:
+ if (fixP->fx_addsy)
+ {
+ char *sfile;
+ unsigned int sline;
+
+ /* Use expr_symbol_where to see if this is an
+ expression symbol. */
+ if (expr_symbol_where (fixP->fx_addsy, &sfile, &sline))
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("unresolved expression that must"
+ " be resolved"));
+ else
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("cannot emit PC relative %s relocation"
+ " against %s"),
+ bfd_get_reloc_code_name (fixP->fx_r_type),
+ S_GET_NAME (fixP->fx_addsy));
+ }
+ else
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("unable to resolve expression"));
+ fixP->fx_done = 1;
+ break;
+ }
}
#ifdef OBJ_ELF
diff --git a/gas/configure.tgt b/gas/configure.tgt
index da6f65a18..f41614916 100644
--- a/gas/configure.tgt
+++ b/gas/configure.tgt
@@ -121,7 +121,7 @@ case ${generic_target} in
alpha-*-*vms*) fmt=evax ;;
alpha-*-osf*) fmt=ecoff ;;
- alpha-*-linuxecoff*) fmt=ecoff ;;
+ alpha-*-linux*ecoff*) fmt=ecoff ;;
alpha-*-linux-*) fmt=elf em=linux ;;
alpha-*-netbsd*) fmt=elf em=nbsd ;;
alpha-*-openbsd*) fmt=elf em=obsd ;;
diff --git a/gas/doc/c-mips.texi b/gas/doc/c-mips.texi
index 7df5f79e6..b8953be94 100644
--- a/gas/doc/c-mips.texi
+++ b/gas/doc/c-mips.texi
@@ -181,6 +181,12 @@ Generate code for the MCU Application Specific Extension.
This tells the assembler to accept MCU instructions.
@samp{-mno-mcu} turns off this option.
+@item -mvirt
+@itemx -mno-virt
+Generate code for the Virtualization Application Specific Extension.
+This tells the assembler to accept Virtualization instructions.
+@samp{-mno-virt} turns off this option.
+
@item -mfix7000
@itemx -mno-fix7000
Cause nops to be inserted if the read of the destination register
@@ -684,6 +690,14 @@ from the MCU Application Specific Extension from that point on
in the assembly. The @code{.set nomcu} directive prevents MCU
instructions from being accepted.
+@cindex Virtualization instruction generation override
+@kindex @code{.set virt}
+@kindex @code{.set novirt}
+The directive @code{.set virt} makes the assembler accept instructions
+from the Virtualization Application Specific Extension from that point
+on in the assembly. The @code{.set novirt} directive prevents Virtualization
+instructions from being accepted.
+
Traditional @sc{mips} assemblers do not support these directives.
@node MIPS floating-point
diff --git a/gas/doc/c-msp430.texi b/gas/doc/c-msp430.texi
index 4beb90a0b..538133a6d 100644
--- a/gas/doc/c-msp430.texi
+++ b/gas/doc/c-msp430.texi
@@ -1,4 +1,4 @@
-@c Copyright 2002, 2004, 2005, 2011 Free Software Foundation, Inc.
+@c Copyright 2002-2013 Free Software Foundation, Inc.
@c This is part of the GAS manual.
@c For copying conditions, see the file as.texinfo.
@ifset GENERIC
@@ -28,14 +28,35 @@
@cindex options for MSP430 (none)
@table @code
-@item -m
-select the mpu arch. Currently has no effect.
+@item -mmcu
+selects the mpu arch. If the architecture is 430Xv2 then this also
+enables NOP generation unless the @option{-mN} is also specified.
+
+@item -mcpu
+selects the cpu architecture. If the architecture is 430Xv2 then this
+also enables NOP generation unless the @option{-mN} is also
+specified.
+
@item -mP
enables polymorph instructions handler.
@item -mQ
enables relaxation at assembly time. DANGEROUS!
+@item -ml
+indicates that the input uses the large code model.
+
+@item -mN
+disables the generation of a NOP instruction following any instruction
+that might change the interrupts enabled/disabled state. For the
+430Xv2 architecture the instructions: @code{EINT}, @code{DINT},
+@code{BIC #8, SR}, @code{BIS #8, SR} and @code{MOV.W <>, SR} must be
+followed by a NOP instruction in order to ensure the correct
+processing of interrupts. By default generation of the NOP
+instruction happens automatically, but this command line option
+disables this behaviour. It is then up to the programmer to ensure
+that interrupts are enabled and disabled correctly.
+
@end table
@node MSP430 Syntax
@@ -215,10 +236,15 @@ used for the directive called @code{.app-file} in the MSP 430 support.
This directive is ignored; it is accepted for compatibility with other
MSP 430 assemblers.
-@cindex @code{sect} directive, MSP 430
+@cindex @code{arch} directive, MSP 430
@item .arch
-Currently this directive is ignored; it is accepted for compatibility with other
-MSP 430 assemblers.
+Sets the target microcontroller in the same way as the @option{-mmcu}
+command line option.
+
+@cindex @code{cpu} directive, MSP 430
+@item .cpu
+Sets the target architecture in the same way as the @option{-mcpu}
+command line option.
@cindex @code{profiler} directive, MSP 430
@item .profiler
diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog
index ed428596b..faa07c105 100644
--- a/gas/testsuite/ChangeLog
+++ b/gas/testsuite/ChangeLog
@@ -1,3 +1,113 @@
+2013-05-23 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
+
+ * gas/s390/zarch-zEC12.d: Adjust length operands for cdzt, cxzt,
+ czdt, and czxt.
+ * gas/s390/zarch-zEC12.d: Likewise.
+
+2013-05-22 Jürgen Urban <JuergenUrban@gmx.de>
+
+ * gas/mips/r5900-full.s, gas/mips/r5900-full.d: Add tests for LQ
+ and SQ macros.
+ * gas/mips/r5900-vu0.s, gas/mips/r5900-vu0.d: New test.
+ * gas/mips/mips.exp: Run it.
+
+2013-05-21 Alan Modra <amodra@gmail.com>
+
+ * gas/ppc/vsx2.d: Ignore trailing padding.
+
+2013-05-20 Peter Bergner <bergner@vnet.ibm.com>
+
+ * gas/ppc/altivec2.d <bcdadd., bcdadd., vaddcuq, vaddecuq, vaddeuqm,
+ vaddudm, vadduqm, vbpermq, vcipher, vcipherlast, vclzb, vclzd, vclzh,
+ vclzw, vcmpequd, vcmpequd., vcmpgtsd, vcmpgtsd., vcmpgtud, vcmpgtud.,
+ veqv, vgbbd, vmaxsd, vmaxud, vminsd, vminud, vmrgew, vmrgow, vmulesw,
+ vmuleuw, vmulosw, vmulouw, vmuluwm, vnand, vncipher, vncipherlast,
+ vorc, vpermxor, vpksdss, vpksdus, vpkudum, vpkudus, vpmsumb, vpmsumd,
+ vpmsumh, vpmsumw, vpopcntb, vpopcntd, vpopcnth, vpopcntw, vrld, vsbox,
+ vshasigmad, vshasigmaw, vsld, vsrad, vsrd, vsubcuq, vsubecuq, vsubeuqm,
+ vsubudm, vsubuqm, vupkhsw, vupklsw>: Add new tests.
+ * gas/ppc/altivec2.s: Likewise.
+ * gas/ppc/power8.d <bcdadd., bcdsub., bctar, bctarl, clrbhrb, fmrgew,
+ fmrgow, lqarx, lxsiwax, lxsiwzx, lxsspx, mfbhrbe, mfvsrd, mfvsrwz,
+ msgclrp, msgsndp, mtsle, mtvsrd, mtvsrwa, mtvsrwz, pbt., rfebb,
+ stqcx., stxsiwx, stxsspx, vaddcuq, vaddecuq, vaddeuqm, vaddudm,
+ vadduqm, vbpermq, vcipher, vcipherlast, vclzb, vclzd, vclzh, vclzw,
+ vcmpequd, vcmpequd., vcmpgtsd, vcmpgtsd., vcmpgtud, vcmpgtud., veqv,
+ vgbbd, vmaxsd, vmaxud, vminsd, vminud, vmrgow, vmulesw, vmuleuw,
+ vmulosw, vmulouw, vmuluwm, vnand, vncipher, vncipherlast, vorc,
+ vpermxor, vpksdss, vpksdus, vpkudum, vpkudus, vpmsumb, vpmsumd,
+ vpmsumh, vpmsumw, vpopcntb, vpopcntd, vpopcnth, vpopcntw, vrld, vsbox,
+ vshasigmad, vshasigmaw, vsld, vsrad, vsrd, vsubcuq, vsubecuq, vsubeuqm,
+ vsubuqm, vupkhsw, vupklsw, waitasec, xsaddsp, xscvdpspn, xscvspdpn,
+ xscvsxdsp, xscvuxdsp, xsdivsp, xsmaddasp, xsmaddmsp, xsmsubasp,
+ xsmsubmsp, xsmulsp, xsnmaddasp, xsnmaddmsp, xsnmsubasp, xsnmsubmsp,
+ xsresp, xsrsp, xsrsqrtesp, xssqrtsp, xssubsp, xxleqv, xxlnand,
+ xxlorc>: Add new tests.
+ * gas/ppc/power8.s Likewise.
+ * gas/ppc/vsx.d <lxvd2x, stxvd2x>: Add new tests.
+ * gas/ppc/vsx.s Likewise.
+ * gas/ppc/vsx2.d: New test file.
+ * gas/ppc/vsx2.s: Likewise.
+ * gas/ppc/ppc.exp: Run it.
+
+2013-05-16 Tristan Gingold <gingold@adacore.com>
+
+ * gas/ppc/ppc.exp: Do not run simpshft on aix.
+
+2013-05-16 Nick Clifton <nickc@redhat.com>
+
+ * gas/msp430/opcodes.s: Use correct value for .arch pseudo.
+ * gas/msp430/msp430x.d: Use correct value for -mcpu option.
+
+2013-05-13 Yufeng Zhang <yufeng.zhang@arm.com>
+
+ * gas/aarch64/diagnostic.s: Update.
+ * gas/aarch64/diagnostic.l: Ditto.
+ * gas/aarch64/movi.s: Add new tests.
+ * gas/aarch64/movi.d: Update.
+
+2013-05-09 Andrew Pinski <apinski@cavium.com>
+
+ * gas/mips/mips.exp: Run virt and virt64 testcases.
+ * gas/mips/virt.d: New file.
+ * gas/mips/virt.s: New file.
+ * gas/mips/virt64.d: New file.
+ * gas/mips/virt64.s: New file.
+
+2013-05-04 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * gas/mips/micromips-warn-branch-delay.d: Use numeric registers.
+
+2013-05-02 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * gas/mips/mips16-stabs.s, gas/mips/mips16-stabs.d: New test.
+ * gas/mips/mips.exp: Run it.
+
+2013-05-02 Nick Clifton <nickc@redhat.com>
+
+ * gas/all/gas.exp: Skip the DIFF1 test for the MSP430.
+ Expect the FORWARD test to pass for the MSP430.
+ Skip the REDEF tests for the MSP430.
+ Expect the 930509A test to fail for the MSP430.
+ * gas/all/sleb128-4.d: Skip for the MSP430.
+ * gas/elf/elf.exp: Set target_machine to msp430 for the MSP430.
+ Skip the EHOPT0 test for the MSP430.
+ Skip the REDEF and EQU-RELOC tests for the MSP430.
+ * gas/elf/section2.e-msp430: New file.
+ * gas/lns/lns-big-delta.d: Remove expectation of 20-bit
+ addresses.
+ * gas/lns/lns.exp: Use alternate LNS COMMON test for the MSP430.
+ * gas/msp430/msp430x.s: New test.
+ * gas/msp430/msp430x.d: Expected disassembly.
+ * gas/msp430/msp430.exp: Run new test.
+ * gas/msp430/opcode.d: Update expected disassembly.
+
+2013-04-30 Chao-ying Fu <Chao-ying.Fu@imgtec.com>
+
+ * gas/mips/ext-ill.s: New file.
+ * gas/mips/ext-ill.l: New file.
+ * gas/mips/mips.exp: Run new tests.
+
2013-04-29 Nick Clifton <nickc@redhat.com>
* gas/elf/dwarf2-3.d: Fix expected readelf output.
diff --git a/gas/testsuite/gas/aarch64/diagnostic.l b/gas/testsuite/gas/aarch64/diagnostic.l
index 0a0801123..cca8881bc 100644
--- a/gas/testsuite/gas/aarch64/diagnostic.l
+++ b/gas/testsuite/gas/aarch64/diagnostic.l
@@ -38,8 +38,8 @@
[^:]*:40: Error: invalid shift amount at operand 3 -- `shll v1.4s,v2.4h,#32'
[^:]*:41: Error: immediate value out of range 0 to 31 at operand 3 -- `shl v1.2s,v2.2s,32'
[^:]*:42: Error: immediate value out of range 1 to 8 at operand 3 -- `sqshrn2 v2.16b,v3.8h,#17'
-[^:]*:43: Error: immediate value out of range 0 to 255 at operand 2 -- `movi v1.4h,256'
-[^:]*:44: Error: immediate value out of range 0 to 255 at operand 2 -- `movi v1.4h,-1'
+[^:]*:43: Error: immediate value out of range -128 to 255 at operand 2 -- `movi v1.4h,256'
+[^:]*:44: Error: immediate value out of range -128 to 255 at operand 2 -- `movi v1.4h,-129'
[^:]*:45: Error: invalid shift operator at operand 2 -- `movi v1.4h,255,msl#8'
[^:]*:46: Error: invalid value for immediate at operand 2 -- `movi d0,256'
[^:]*:47: Error: immediate value should be a multiple of 8 at operand 2 -- `movi v1.4h,255,lsl#7'
diff --git a/gas/testsuite/gas/aarch64/diagnostic.s b/gas/testsuite/gas/aarch64/diagnostic.s
index 99ebf8fa5..e5443ab75 100644
--- a/gas/testsuite/gas/aarch64/diagnostic.s
+++ b/gas/testsuite/gas/aarch64/diagnostic.s
@@ -41,7 +41,7 @@
shl v1.2s, v2.2s, 32
sqshrn2 v2.16b, v3.8h, #17
movi v1.4h, 256
- movi v1.4h, -1
+ movi v1.4h, -129
movi v1.4h, 255, msl #8
movi d0, 256
movi v1.4h, 255, lsl #7
diff --git a/gas/testsuite/gas/aarch64/movi.d b/gas/testsuite/gas/aarch64/movi.d
index cd54cfd22..e159e4705 100644
--- a/gas/testsuite/gas/aarch64/movi.d
+++ b/gas/testsuite/gas/aarch64/movi.d
@@ -8713,3 +8713,6 @@ Disassembly of section \.text:
8804: 6f07e7e0 movi v0.2d, #0xffffffffffffffff
8808: 6f07e7e0 movi v0.2d, #0xffffffffffffffff
880c: 2f07e7ff movi d31, #0xffffffffffffffff
+ 8810: 0f04e403 movi v3.8b, #0x80
+ 8814: 0f04e423 movi v3.8b, #0x81
+ 8818: 0f07e7e3 movi v3.8b, #0xff
diff --git a/gas/testsuite/gas/aarch64/movi.s b/gas/testsuite/gas/aarch64/movi.s
index a65079017..3a15e3d16 100644
--- a/gas/testsuite/gas/aarch64/movi.s
+++ b/gas/testsuite/gas/aarch64/movi.s
@@ -113,3 +113,8 @@
movi v0.2d, bignum
movi d31, 18446744073709551615
.set bignum, 0xffffffffffffffff
+
+ // Allow -128 to 255 in #<imm8>
+ movi v3.8b, -128
+ movi v3.8b, -127
+ movi v3.8b, -1
diff --git a/gas/testsuite/gas/all/gas.exp b/gas/testsuite/gas/all/gas.exp
index 709b44870..f604ac943 100644
--- a/gas/testsuite/gas/all/gas.exp
+++ b/gas/testsuite/gas/all/gas.exp
@@ -61,6 +61,7 @@ if { ![istarget hppa*-*-*]
&& ![istarget alpha*-*-*vms*]
&& ![istarget rx-*-*]
&& ![istarget mn10300-*-*]
+ && ![istarget msp430*-*-*]
&& ![istarget am3*-*-*] } then {
gas_test_error "diff1.s" "" "difference of two undefined symbols"
}
@@ -99,7 +100,7 @@ case $target_triplet in {
default {
# Some targets don't manage to resolve BFD_RELOC_8 for constants.
setup_xfail "alpha*-*-*" "*c30*-*-*" "*c4x*-*-*" \
- "d\[13\]0v*-*-*" "i860-*-*" "mips*-*-*" "msp430-*-*" \
+ "d\[13\]0v*-*-*" "i860-*-*" "mips*-*-*" \
"pdp11-*-*" "xtensa*-*-*"
run_dump_test forward
}
@@ -139,6 +140,7 @@ case $target_triplet in {
{ mips*-*-* } { }
{ mn10200-*-* } { }
{ mn10300-*-* } { }
+ { msp430*-*-* } { }
{ pdp11-*-* } { }
{ tic30*-*-* } { }
{ tic4x*-*-* } { }
@@ -266,8 +268,8 @@ if { ![istarget hppa*-*-*] &&
![istarget *c54x*-*-*] } then {
# the vax fails because VMS can apparently actually handle this
# case in relocs, so gas doesn't handle it itself.
- # mn10300 emits two relocs to handle the difference of two symbols.
- setup_xfail "mn10300*-*-*" "vax*-*-vms*"
+ # msp430 and mn10300 emit two relocs to handle the difference of two symbols.
+ setup_xfail "mn10300*-*-*" "msp430*-*-*" "vax*-*-vms*"
do_930509a
}
diff --git a/gas/testsuite/gas/all/sleb128-4.d b/gas/testsuite/gas/all/sleb128-4.d
index 0c56696d8..89b956530 100644
--- a/gas/testsuite/gas/all/sleb128-4.d
+++ b/gas/testsuite/gas/all/sleb128-4.d
@@ -1,5 +1,6 @@
#objdump : -s -j .data -j "\$DATA\$"
#name : .sleb128 tests (4)
+#skip: msp430*-*-*
.*: .*
diff --git a/gas/testsuite/gas/elf/elf.exp b/gas/testsuite/gas/elf/elf.exp
index 9ffd25733..4196fd7da 100644
--- a/gas/testsuite/gas/elf/elf.exp
+++ b/gas/testsuite/gas/elf/elf.exp
@@ -1,5 +1,4 @@
-# Copyright 2012
-# Free Software Foundation, Inc.
+# Copyright 2012-2013 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -62,6 +61,9 @@ if { [is_elf_format] } then {
if {[istarget m32r*-*-*]} then {
set target_machine -m32r
}
+ if {[istarget "msp430-*-*"]} then {
+ set target_machine -msp430
+ }
if {[istarget "score-*-*"]} then {
set target_machine -score
}
@@ -91,6 +93,7 @@ if { [is_elf_format] } then {
# function prologues.
if {![istarget "mn10300-*-*"]
&& ![istarget "xtensa*-*-*"]
+ && ![istarget "msp430*-*-*"]
&& ![istarget "am3*-*-*"]} then {
run_dump_test "ehopt0"
}
@@ -136,6 +139,7 @@ if { [is_elf_format] } then {
{ mips*-*-* } { }
{ mn10200-*-* } { }
{ mn10300-*-* } { }
+ { msp43*-*-* } { }
{ *c54x*-*-* } { }
{ rx-*-* } { }
default {
diff --git a/gas/testsuite/gas/elf/section2.e-msp430 b/gas/testsuite/gas/elf/section2.e-msp430
new file mode 100644
index 000000000..115bae217
--- /dev/null
+++ b/gas/testsuite/gas/elf/section2.e-msp430
@@ -0,0 +1,9 @@
+
+Symbol table '.symtab' contains 6 entries:
+ +Num: +Value +Size +Type +Bind +Vis +Ndx +Name
+ +0: 0+0 +0 +NOTYPE +LOCAL +DEFAULT +UND
+ +1: 0+0 +0 +SECTION +LOCAL +DEFAULT +1
+ +2: 0+0 +0 +SECTION +LOCAL +DEFAULT +2
+ +3: 0+0 +0 +SECTION +LOCAL +DEFAULT +3
+ +4: 0+0 +0 +SECTION +LOCAL +DEFAULT +4
+ +5: 0+0 +0 +SECTION +LOCAL +DEFAULT +5
diff --git a/gas/testsuite/gas/lns/lns-big-delta.d b/gas/testsuite/gas/lns/lns-big-delta.d
index b6a113e81..f4bdcf43b 100644
--- a/gas/testsuite/gas/lns/lns-big-delta.d
+++ b/gas/testsuite/gas/lns/lns-big-delta.d
@@ -10,8 +10,8 @@ Raw dump of debug contents of section \.debug_line:
Advance PC by fixed size amount 0 to 0x0
Copy
Advance Line by 1 to 3
- Extended opcode 2: set Address to 0x.....
+ Extended opcode 2: set Address to 0x.*
Copy
- Advance PC by fixed size amount . to 0x.....
+ Advance PC by fixed size amount . to 0x.*
Extended opcode 1: End of Sequence
#pass
diff --git a/gas/testsuite/gas/lns/lns.exp b/gas/testsuite/gas/lns/lns.exp
index 0febe0be7..f1d7f98b1 100644
--- a/gas/testsuite/gas/lns/lns.exp
+++ b/gas/testsuite/gas/lns/lns.exp
@@ -38,6 +38,7 @@ if {
|| [istarget am3*-*-*]
|| [istarget cr16-*-*]
|| [istarget crx-*-*]
+ || [istarget msp430-*-*]
|| [istarget mn10*-*-*] } {
run_dump_test "lns-common-1-alt"
run_dump_test "lns-big-delta"
diff --git a/gas/testsuite/gas/mips/ext-ill.l b/gas/testsuite/gas/mips/ext-ill.l
new file mode 100644
index 000000000..0f4ed354d
--- /dev/null
+++ b/gas/testsuite/gas/mips/ext-ill.l
@@ -0,0 +1,6 @@
+.*: Assembler messages:
+.*:5: Error: Improper extract size \(0, position 1\)
+.*:6: Error: Improper extract size \(0, position 1\)
+.*:7: Error: Improper extract size \(2, position 31\)
+.*:8: Error: Improper extract size \(32, position 1\)
+.*:9: Error: Improper extract size \(0, position 33\)
diff --git a/gas/testsuite/gas/mips/ext-ill.s b/gas/testsuite/gas/mips/ext-ill.s
new file mode 100644
index 000000000..e4ce35a1d
--- /dev/null
+++ b/gas/testsuite/gas/mips/ext-ill.s
@@ -0,0 +1,9 @@
+# source file to test illegal ext, dext, dextm, dextu instructions
+
+ .text
+text_label:
+ ext $2, $3, 1, 0
+ dext $2, $3, 1, 0
+ dextm $2, $3, 31, 2
+ dextm $2, $3, 1, 32
+ dextu $2, $3, 33, 0
diff --git a/gas/testsuite/gas/mips/micromips-warn-branch-delay.d b/gas/testsuite/gas/mips/micromips-warn-branch-delay.d
index fde0af5c6..936dab7f1 100644
--- a/gas/testsuite/gas/mips/micromips-warn-branch-delay.d
+++ b/gas/testsuite/gas/mips/micromips-warn-branch-delay.d
@@ -1,4 +1,4 @@
-#objdump: -dr --show-raw-insn
+#objdump: -dr --show-raw-insn -M gpr-names=numeric
#name: microMIPS fixed-size branch delay slots
#as: -mmicromips
#source: micromips-warn-branch-delay.s
@@ -9,18 +9,18 @@
Disassembly of section \.text:
[0-9a-f]+ <foo>:
-[ 0-9a-f]+: 45e2 jalrs v0
-[ 0-9a-f]+: 0083 1250 and v0,v1,a0
-[ 0-9a-f]+: 45e2 jalrs v0
-[ 0-9a-f]+: 6043 9000 swr v0,0\(v1\)
-[ 0-9a-f]+: 45e2 jalrs v0
-[ 0-9a-f]+: 6043 8000 swl v0,0\(v1\)
-[ 0-9a-f]+: 45e2 jalrs v0
-[ 0-9a-f]+: 0272 8210 mul s0,s2,s3
-[ 0-9a-f]+: 45e2 jalrs v0
-[ 0-9a-f]+: 001f 8b90 sltu s1,ra,zero
-[ 0-9a-f]+: 45e2 jalrs v0
-[ 0-9a-f]+: 0220 8910 add s1,zero,s1
-[ 0-9a-f]+: 45e2 jalrs v0
-[ 0-9a-f]+: 01b1 8990 sub s1,s1,t5
+[ 0-9a-f]+: 45e2 jalrs \$2
+[ 0-9a-f]+: 0083 1250 and \$2,\$3,\$4
+[ 0-9a-f]+: 45e2 jalrs \$2
+[ 0-9a-f]+: 6043 9000 swr \$2,0\(\$3\)
+[ 0-9a-f]+: 45e2 jalrs \$2
+[ 0-9a-f]+: 6043 8000 swl \$2,0\(\$3\)
+[ 0-9a-f]+: 45e2 jalrs \$2
+[ 0-9a-f]+: 0272 8210 mul \$16,\$18,\$19
+[ 0-9a-f]+: 45e2 jalrs \$2
+[ 0-9a-f]+: 001f 8b90 sltu \$17,\$31,\$0
+[ 0-9a-f]+: 45e2 jalrs \$2
+[ 0-9a-f]+: 0220 8910 add \$17,\$0,\$17
+[ 0-9a-f]+: 45e2 jalrs \$2
+[ 0-9a-f]+: 01b1 8990 sub \$17,\$17,\$13
#pass
diff --git a/gas/testsuite/gas/mips/mips.exp b/gas/testsuite/gas/mips/mips.exp
index 145824ab5..aef771a65 100644
--- a/gas/testsuite/gas/mips/mips.exp
+++ b/gas/testsuite/gas/mips/mips.exp
@@ -786,6 +786,9 @@ if { [istarget mips*-*-vxworks*] } {
run_dump_test "lineno"
run_dump_test "sync"
+ run_dump_test_arches "virt" [mips_arch_list_matching mips32r2 !micromips]
+ run_dump_test_arches "virt64" [mips_arch_list_matching mips64r2 !micromips]
+
run_dump_test_arches "mips32" [mips_arch_list_matching mips32]
run_dump_test_arches "mips32-imm" [mips_arch_list_matching mips32]
@@ -1086,6 +1089,7 @@ if { [istarget mips*-*-vxworks*] } {
if $has_newabi {
run_dump_test "mips16-dwarf2-n32"
}
+ run_dump_test "mips16-stabs"
}
if { !$no_mips16 } {
run_dump_test "mips16e-jrc"
@@ -1169,4 +1173,7 @@ if { [istarget mips*-*-vxworks*] } {
run_dump_test "r5900"
run_dump_test "r5900-full"
if $elf { run_list_test "r5900-nollsc" "-mabi=o64 -march=r5900" }
+ run_dump_test "r5900-vu0"
+
+ run_list_test_arches "ext-ill" [mips_arch_list_matching mips64r2]
}
diff --git a/gas/testsuite/gas/mips/mips16-stabs.d b/gas/testsuite/gas/mips/mips16-stabs.d
new file mode 100644
index 000000000..db7673a98
--- /dev/null
+++ b/gas/testsuite/gas/mips/mips16-stabs.d
@@ -0,0 +1,6 @@
+#as: -mips3 -EB
+#objdump: -dr
+#...
+0+ <foo>:
+ 0: e820 jr ra
+#pass
diff --git a/gas/testsuite/gas/mips/mips16-stabs.s b/gas/testsuite/gas/mips/mips16-stabs.s
new file mode 100644
index 000000000..f44ad6a64
--- /dev/null
+++ b/gas/testsuite/gas/mips/mips16-stabs.s
@@ -0,0 +1,8 @@
+ .align 2
+ .set mips16
+ .globl foo
+ .ent foo
+foo:
+ .stabs "foo:F(0,49)",36,0,0,foo
+ jr $31
+ .end foo
diff --git a/gas/testsuite/gas/mips/r5900-full.d b/gas/testsuite/gas/mips/r5900-full.d
index 26d97ca57..96892091f 100644
--- a/gas/testsuite/gas/mips/r5900-full.d
+++ b/gas/testsuite/gas/mips/r5900-full.d
@@ -43,10 +43,28 @@ Disassembly of section \.text:
[0-9a-f]+ <[^>]*> 7c217fff sq \$1,32767\(\$1\)
[0-9a-f]+ <[^>]*> 7d088000 sq \$8,-32768\(\$8\)
[0-9a-f]+ <[^>]*> 7fffffff sq \$31,-1\(\$31\)
+[0-9a-f]+ <[^>]*> 3c010001 lui \$1,0x1
+[0-9a-f]+ <[^>]*> 00220821 addu \$1,\$1,\$2
+[0-9a-f]+ <[^>]*> 7c208000 sq \$0,-32768\(\$1\)
+[0-9a-f]+ <[^>]*> 3c01ffff lui \$1,0xffff
+[0-9a-f]+ <[^>]*> 003f0821 addu \$1,\$1,\$31
+[0-9a-f]+ <[^>]*> 7c287fff sq \$8,32767\(\$1\)
+[0-9a-f]+ <[^>]*> 3c01f123 lui \$1,0xf123
+[0-9a-f]+ <[^>]*> 00240821 addu \$1,\$1,\$4
+[0-9a-f]+ <[^>]*> 7c3f4567 sq \$31,17767\(\$1\)
[0-9a-f]+ <[^>]*> 78000000 lq \$0,0\(\$0\)
[0-9a-f]+ <[^>]*> 78217fff lq \$1,32767\(\$1\)
[0-9a-f]+ <[^>]*> 79088000 lq \$8,-32768\(\$8\)
[0-9a-f]+ <[^>]*> 7bffffff lq \$31,-1\(\$31\)
+[0-9a-f]+ <[^>]*> 3c030001 lui \$3,0x1
+[0-9a-f]+ <[^>]*> 00621821 addu \$3,\$3,\$2
+[0-9a-f]+ <[^>]*> 78638000 lq \$3,-32768\(\$3\)
+[0-9a-f]+ <[^>]*> 3c08ffff lui \$8,0xffff
+[0-9a-f]+ <[^>]*> 011f4021 addu \$8,\$8,\$31
+[0-9a-f]+ <[^>]*> 79087fff lq \$8,32767\(\$8\)
+[0-9a-f]+ <[^>]*> 3c1ff123 lui \$31,0xf123
+[0-9a-f]+ <[^>]*> 03e4f821 addu \$31,\$31,\$4
+[0-9a-f]+ <[^>]*> 7bff4567 lq \$31,17767\(\$31\)
[0-9a-f]+ <[^>]*> cc000000 pref 0x0,0\(\$0\)
[0-9a-f]+ <[^>]*> cc217fff pref 0x1,32767\(\$1\)
[0-9a-f]+ <[^>]*> cd088000 pref 0x8,-32768\(\$8\)
diff --git a/gas/testsuite/gas/mips/r5900-full.s b/gas/testsuite/gas/mips/r5900-full.s
index f3c24541a..9560dc7b7 100644
--- a/gas/testsuite/gas/mips/r5900-full.s
+++ b/gas/testsuite/gas/mips/r5900-full.s
@@ -53,7 +53,7 @@ stuff:
trunc.w.s $f0, $f31
trunc.w.s $f31, $f0
- # Test ei/di, but not the R5900 has a bug. ei/di should not be used.
+ # Test ei/di, but the R5900 has a bug. ei/di should not be used.
di
ei
@@ -68,12 +68,20 @@ stuff:
sq $1, 0x7fff($1)
sq $8, -0x8000($8)
sq $31, -1($31)
+ .set at
+ sq $0, 0x8000($2)
+ sq $8, -0x8001($31)
+ sq $31, 0xF1234567($4)
+ .set noat
# 128 bit load instruction.
lq $0, 0($0)
lq $1, 0x7fff($1)
lq $8, -0x8000($8)
lq $31, -1($31)
+ lq $3, 0x8000($2)
+ lq $8, -0x8001($31)
+ lq $31, 0xF1234567($4)
# Prefetch cache
pref 0, 0($0)
@@ -210,7 +218,7 @@ stuff:
rsqrt.s $f0, $f31, $f0
rsqrt.s $f31, $f0, $f31
- # FLoating point subtract to accumulator
+ # Floating point subtract to accumulator
suba.s $f0, $f31
suba.s $f31, $f0
diff --git a/gas/testsuite/gas/mips/r5900-vu0.d b/gas/testsuite/gas/mips/r5900-vu0.d
new file mode 100644
index 000000000..83759466d
--- /dev/null
+++ b/gas/testsuite/gas/mips/r5900-vu0.d
@@ -0,0 +1,66 @@
+#objdump: -dr --prefix-addresses --show-raw-insn -M gpr-names=numeric -mmips:5900
+#name: MIPS R5900 VU0
+#as: -march=r5900
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+[0-9a-f]+ <[^>]*> d8000000 lqc2 \$0,0\(\$0\)
+[0-9a-f]+ <[^>]*> d8217fff lqc2 \$1,32767\(\$1\)
+[0-9a-f]+ <[^>]*> d9088000 lqc2 \$8,-32768\(\$8\)
+[0-9a-f]+ <[^>]*> dbffffff lqc2 \$31,-1\(\$31\)
+[0-9a-f]+ <[^>]*> 3c010001 lui \$1,0x1
+[0-9a-f]+ <[^>]*> 00220821 addu \$1,\$1,\$2
+[0-9a-f]+ <[^>]*> d8208000 lqc2 \$0,-32768\(\$1\)
+[0-9a-f]+ <[^>]*> 3c01ffff lui \$1,0xffff
+[0-9a-f]+ <[^>]*> 003f0821 addu \$1,\$1,\$31
+[0-9a-f]+ <[^>]*> d8287fff lqc2 \$8,32767\(\$1\)
+[0-9a-f]+ <[^>]*> 3c01f123 lui \$1,0xf123
+[0-9a-f]+ <[^>]*> 00240821 addu \$1,\$1,\$4
+[0-9a-f]+ <[^>]*> d83f4567 lqc2 \$31,17767\(\$1\)
+[0-9a-f]+ <[^>]*> f8000000 sqc2 \$0,0\(\$0\)
+[0-9a-f]+ <[^>]*> f8217fff sqc2 \$1,32767\(\$1\)
+[0-9a-f]+ <[^>]*> f9088000 sqc2 \$8,-32768\(\$8\)
+[0-9a-f]+ <[^>]*> fbffffff sqc2 \$31,-1\(\$31\)
+[0-9a-f]+ <[^>]*> 3c010001 lui \$1,0x1
+[0-9a-f]+ <[^>]*> 00220821 addu \$1,\$1,\$2
+[0-9a-f]+ <[^>]*> f8208000 sqc2 \$0,-32768\(\$1\)
+[0-9a-f]+ <[^>]*> 3c01ffff lui \$1,0xffff
+[0-9a-f]+ <[^>]*> 003f0821 addu \$1,\$1,\$31
+[0-9a-f]+ <[^>]*> f8287fff sqc2 \$8,32767\(\$1\)
+[0-9a-f]+ <[^>]*> 3c01f123 lui \$1,0xf123
+[0-9a-f]+ <[^>]*> 00240821 addu \$1,\$1,\$4
+[0-9a-f]+ <[^>]*> f83f4567 sqc2 \$31,17767\(\$1\)
+[0-9a-f]+ <[^>]*> 48400000 cfc2 \$0,\$0
+[0-9a-f]+ <[^>]*> 4840f800 cfc2 \$0,\$31
+[0-9a-f]+ <[^>]*> 48400001 cfc2.i \$0,\$0
+[0-9a-f]+ <[^>]*> 4840f801 cfc2.i \$0,\$31
+[0-9a-f]+ <[^>]*> 48400000 cfc2 \$0,\$0
+[0-9a-f]+ <[^>]*> 4840f800 cfc2 \$0,\$31
+[0-9a-f]+ <[^>]*> 48c00000 ctc2 \$0,\$0
+[0-9a-f]+ <[^>]*> 48c0f800 ctc2 \$0,\$31
+[0-9a-f]+ <[^>]*> 48c00001 ctc2.i \$0,\$0
+[0-9a-f]+ <[^>]*> 48c0f801 ctc2.i \$0,\$31
+[0-9a-f]+ <[^>]*> 48c00000 ctc2 \$0,\$0
+[0-9a-f]+ <[^>]*> 48c0f800 ctc2 \$0,\$31
+[0-9a-f]+ <[^>]*> 48200000 qmfc2 \$0,\$0
+[0-9a-f]+ <[^>]*> 4820f800 qmfc2 \$0,\$31
+[0-9a-f]+ <[^>]*> 48200001 qmfc2.i \$0,\$0
+[0-9a-f]+ <[^>]*> 4820f801 qmfc2.i \$0,\$31
+[0-9a-f]+ <[^>]*> 48200000 qmfc2 \$0,\$0
+[0-9a-f]+ <[^>]*> 4820f800 qmfc2 \$0,\$31
+[0-9a-f]+ <[^>]*> 48a00000 qmtc2 \$0,\$0
+[0-9a-f]+ <[^>]*> 48a0f800 qmtc2 \$0,\$31
+[0-9a-f]+ <[^>]*> 48a00001 qmtc2.i \$0,\$0
+[0-9a-f]+ <[^>]*> 48a0f801 qmtc2.i \$0,\$31
+[0-9a-f]+ <[^>]*> 48a00000 qmtc2 \$0,\$0
+[0-9a-f]+ <[^>]*> 48a0f800 qmtc2 \$0,\$31
+[0-9a-f]+ <[^>]*> 4900ffff bc2f [0-9a-f]+ <branch_label>
+[0-9a-f]+ <[^>]*> 00000000 nop
+[0-9a-f]+ <[^>]*> 4902fffd bc2fl [0-9a-f]+ <branch_label>
+[0-9a-f]+ <[^>]*> 00000000 nop
+[0-9a-f]+ <[^>]*> 4901fffb bc2t [0-9a-f]+ <branch_label>
+[0-9a-f]+ <[^>]*> 00000000 nop
+[0-9a-f]+ <[^>]*> 4903fff9 bc2tl [0-9a-f]+ <branch_label>
+[0-9a-f]+ <[^>]*> 00000000 nop
+ \.\.\.
diff --git a/gas/testsuite/gas/mips/r5900-vu0.s b/gas/testsuite/gas/mips/r5900-vu0.s
new file mode 100644
index 000000000..13fe3d8e5
--- /dev/null
+++ b/gas/testsuite/gas/mips/r5900-vu0.s
@@ -0,0 +1,76 @@
+ .text
+
+ .set noreorder
+ .set noat
+
+ .ent text_label
+ .global text_label
+text_label:
+ # Floating point transfer to VU
+ lqc2 $0,0($0)
+ lqc2 $1, 0x7fff($1)
+ lqc2 $8, -0x8000($8)
+ lqc2 $31, -1($31)
+ .set at
+ lqc2 $0, 0x8000($2)
+ lqc2 $8, -0x8001($31)
+ lqc2 $31, 0xF1234567($4)
+ .set noat
+
+ # Floating point transfer from VU
+ sqc2 $0,0($0)
+ sqc2 $1, 0x7fff($1)
+ sqc2 $8, -0x8000($8)
+ sqc2 $31, -1($31)
+ .set at
+ sqc2 $0, 0x8000($2)
+ sqc2 $8, -0x8001($31)
+ sqc2 $31, 0xF1234567($4)
+ .set noat
+
+ # Integer transfer from VU
+ cfc2 $0,$0
+ cfc2 $0,$31
+ cfc2.i $0,$0
+ cfc2.i $0,$31
+ cfc2.ni $0,$0
+ cfc2.ni $0,$31
+
+ # Integer transfer to VU
+ ctc2 $0,$0
+ ctc2 $0,$31
+ ctc2.i $0,$0
+ ctc2.i $0,$31
+ ctc2.ni $0,$0
+ ctc2.ni $0,$31
+
+ # Floating point transfer from VU
+ qmfc2 $0,$0
+ qmfc2 $0,$31
+ qmfc2.i $0,$0
+ qmfc2.i $0,$31
+ qmfc2.ni $0,$0
+ qmfc2.ni $0,$31
+
+ # Floating point transfer to VU
+ qmtc2 $0,$0
+ qmtc2 $0,$31
+ qmtc2.i $0,$0
+ qmtc2.i $0,$31
+ qmtc2.ni $0,$0
+ qmtc2.ni $0,$31
+
+ # COP2 conditional branch instructions
+branch_label:
+ bc2f branch_label
+ nop
+ bc2fl branch_label
+ nop
+ bc2t branch_label
+ nop
+ bc2tl branch_label
+ nop
+
+# Force at least 8 (non-delay-slot) zero bytes, to make 'objdump' print ...
+ .space 8
+ .end text_label
diff --git a/gas/testsuite/gas/mips/virt.d b/gas/testsuite/gas/mips/virt.d
new file mode 100644
index 000000000..c22f86785
--- /dev/null
+++ b/gas/testsuite/gas/mips/virt.d
@@ -0,0 +1,20 @@
+#objdump: -dr --prefix-addresses --show-raw-insn -Mvirt,cp0-names=mips32r2
+#name: virt instructions
+#as: -32 -mvirt
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+[0-9a-f]+ <[^>]*> 4063e800 mfgc0 v1,c0_taghi
+[0-9a-f]+ <[^>]*> 406ba005 mfgc0 t3,\$20,5
+[0-9a-f]+ <[^>]*> 40771200 mtgc0 s7,c0_entrylo0
+[0-9a-f]+ <[^>]*> 40677202 mtgc0 a3,\$14,2
+[0-9a-f]+ <[^>]*> 42000028 hypcall
+[0-9a-f]+ <[^>]*> 4212b028 hypcall 0x256
+[0-9a-f]+ <[^>]*> 4200000b tlbginv
+[0-9a-f]+ <[^>]*> 4200000c tlbginvf
+[0-9a-f]+ <[^>]*> 42000010 tlbgp
+[0-9a-f]+ <[^>]*> 42000009 tlbgr
+[0-9a-f]+ <[^>]*> 4200000a tlbgwi
+[0-9a-f]+ <[^>]*> 4200000e tlbgwr
+ ...
diff --git a/gas/testsuite/gas/mips/virt.s b/gas/testsuite/gas/mips/virt.s
new file mode 100644
index 000000000..eca5e02fb
--- /dev/null
+++ b/gas/testsuite/gas/mips/virt.s
@@ -0,0 +1,22 @@
+ .text
+ .set noreorder
+
+foo:
+ mfgc0 $3,$29
+ mfgc0 $11,$20,5
+ mtgc0 $23,$2
+ mtgc0 $7,$14,2
+
+ hypcall
+ hypcall 0x256
+
+ tlbginv
+ tlbginvf
+ tlbgp
+ tlbgr
+ tlbgwi
+ tlbgwr
+
+# Force at least 8 (non-delay-slot) zero bytes, to make 'objdump' print ...
+ .align 2
+ .space 8
diff --git a/gas/testsuite/gas/mips/virt64.d b/gas/testsuite/gas/mips/virt64.d
new file mode 100644
index 000000000..7a86ff94f
--- /dev/null
+++ b/gas/testsuite/gas/mips/virt64.d
@@ -0,0 +1,12 @@
+#objdump: -dr --prefix-addresses --show-raw-insn -Mvirt,cp0-names=mips64r2
+#name: virt64 instructions
+#as: -64 -mvirt
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+[0-9a-f]+ <[^>]*> 4063e900 dmfgc0 v1,c0_taghi
+[0-9a-f]+ <[^>]*> 406ba105 dmfgc0 a7,\$20,5
+[0-9a-f]+ <[^>]*> 40771300 dmtgc0 s7,c0_entrylo0
+[0-9a-f]+ <[^>]*> 40677302 dmtgc0 a3,\$14,2
+ ...
diff --git a/gas/testsuite/gas/mips/virt64.s b/gas/testsuite/gas/mips/virt64.s
new file mode 100644
index 000000000..f3cd7b5c0
--- /dev/null
+++ b/gas/testsuite/gas/mips/virt64.s
@@ -0,0 +1,12 @@
+ .text
+ .set noreorder
+
+foo:
+ dmfgc0 $3,$29
+ dmfgc0 $11,$20,5
+ dmtgc0 $23,$2
+ dmtgc0 $7,$14,2
+
+# Force at least 8 (non-delay-slot) zero bytes, to make 'objdump' print ...
+ .align 2
+ .space 8
diff --git a/gas/testsuite/gas/msp430/msp430.exp b/gas/testsuite/gas/msp430/msp430.exp
index 27df90098..656ace826 100644
--- a/gas/testsuite/gas/msp430/msp430.exp
+++ b/gas/testsuite/gas/msp430/msp430.exp
@@ -1,5 +1,4 @@
-# Copyright 2012
-# Free Software Foundation, Inc.
+# Copyright 2012-2013 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -21,4 +20,5 @@
if [expr [istarget "msp430-*-*"]] then {
run_dump_test "opcode"
+ run_dump_test "msp430x"
}
diff --git a/gas/testsuite/gas/msp430/msp430x.d b/gas/testsuite/gas/msp430/msp430x.d
new file mode 100644
index 000000000..13fdb0bee
--- /dev/null
+++ b/gas/testsuite/gas/msp430/msp430x.d
@@ -0,0 +1,216 @@
+#objdump: -d --prefix-addresses --show-raw-insn
+#name: MSP430X instructions
+#as: -mcpu=430X
+
+.*: +file format .*msp.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> 04 63 adc r4 ;
+0+0002 <[^>]*> 40 18 04 63 adcx.w r4 ;
+0+0006 <[^>]*> 00 18 c0 63 00 00 adcx.a 0x0000 ;PC rel. abs addr 0x000a
+0+000c <[^>]*> 40 18 46 63 adcx.b r6 ;
+0+0010 <[^>]*> 40 18 07 63 adcx.w r7 ;
+0+0014 <[^>]*> 40 18 09 68 addcx.w r8, r9 ;
+0+0018 <[^>]*> 80 18 7a 60 45 23 addcx.a #74565, r10 ;0x12345
+0+001e <[^>]*> 40 18 4c 6b addcx.b r11, r12 ;
+0+0022 <[^>]*> 40 18 0e 6d addcx.w r13, r14 ;
+0+0026 <[^>]*> 40 18 20 59 addx.w @r9, r0 ;
+0+002a <[^>]*> 40 18 00 59 addx.w r9, r0 ;
+0+002e <[^>]*> 00 18 70 50 00 00 addx.a #0, r0 ;
+0+0034 <[^>]*> 00 18 50 52 00 00 addx.a &0x0000,r0 ;0x0000
+0+003a <[^>]*> 00 18 70 59 addx.a @r9\+, r0 ;
+0+003e <[^>]*> 00 18 50 50 00 00 addx.a 0x0000, r0 ;PC rel. 0x0042
+0+0044 <[^>]*> 40 18 42 51 addx.b r1, r2 ;
+0+0048 <[^>]*> 40 18 04 53 addx.w #0, r4 ;r3 As==00
+0+004c <[^>]*> 40 18 15 54 00 00 addx.w 0\(r4\), r5 ;
+0+0052 <[^>]*> 40 18 b6 f0 d2 04 04 00 andx.w #1234, 4\(r6\) ;#0x04d2
+0+005a <[^>]*> 40 18 96 f7 04 00 04 00 andx.w 4\(r7\), 4\(r6\) ;
+0+0062 <[^>]*> 40 18 b6 f5 04 00 andx.w @r5\+, 4\(r6\) ;
+0+0068 <[^>]*> 40 18 96 f0 00 00 04 00 andx.w 0x0000, 4\(r6\) ;PC rel. 0x006c
+0+0070 <[^>]*> 40 18 90 f0 00 00 00 00 andx.w 0x0000, 0x0000 ;PC rel. 0x0074, PC rel. 0x0076
+0+0078 <[^>]*> 00 18 e6 f5 04 00 andx.a @r5, 4\(r6\) ;
+0+007e <[^>]*> 00 18 c6 f5 04 00 andx.a r5, 4\(r6\) ;
+0+0084 <[^>]*> 40 18 d6 f2 00 00 04 00 andx.b &0x0000,4\(r6\) ;0x0000
+0+008c <[^>]*> 40 18 02 f1 andx.w r1, r2 ;
+0+0090 <[^>]*> 40 18 3e c0 a0 00 bicx.w #160, r14 ;#0x00a0
+0+0096 <[^>]*> 00 18 7e c0 a0 00 bicx.a #160, r14 ;#0x00a0
+0+009c <[^>]*> 40 18 7e c0 a0 00 bicx.b #160, r14 ;#0x00a0
+0+00a2 <[^>]*> 40 18 3e c0 a0 00 bicx.w #160, r14 ;#0x00a0
+0+00a8 <[^>]*> 40 18 3b d2 bisx.w #8, r11 ;r2 As==11
+0+00ac <[^>]*> 00 18 7b d2 bisx.a #8, r11 ;r2 As==11
+0+00b0 <[^>]*> 40 18 7b d2 bisx.b #8, r11 ;r2 As==11
+0+00b4 <[^>]*> 40 18 3b d2 bisx.w #8, r11 ;r2 As==11
+0+00b8 <[^>]*> 40 18 38 b0 14 00 bitx.w #20, r8 ;#0x0014
+0+00be <[^>]*> 40 18 92 b2 00 00 00 00 bitx.w &0x0000,&0x0000 ;0x0000
+0+00c6 <[^>]*> 40 18 18 b2 00 00 bitx.w &0x0000,r8 ;0x0000
+0+00cc <[^>]*> 40 18 18 b5 02 00 bitx.w 2\(r5\), r8 ;
+0+00d2 <[^>]*> 40 18 92 b1 08 00 00 00 bitx.w 8\(r1\), &0x0000 ;
+0+00da <[^>]*> 40 18 b2 b5 00 00 bitx.w @r5\+, &0x0000 ;
+0+00e0 <[^>]*> 40 18 38 b5 bitx.w @r5\+, r8 ;
+0+00e4 <[^>]*> 40 18 28 b5 bitx.w @r5, r8 ;
+0+00e8 <[^>]*> 40 18 92 b0 00 00 00 00 bitx.w 0x0000, &0x0000 ;PC rel. 0x00ec
+0+00f0 <[^>]*> 40 18 f2 b0 0c 00 00 00 bitx.b #12, &0x0000 ;#0x000c
+0+00f8 <[^>]*> 40 18 e2 b5 00 00 bitx.b @r5, &0x0000 ;
+0+00fe <[^>]*> 40 18 58 b0 00 00 bitx.b 0x0000, r8 ;PC rel. 0x0102
+0+0104 <[^>]*> 40 18 48 b5 bitx.b r5, r8 ;
+0+0108 <[^>]*> 40 18 82 b5 00 00 bitx.w r5, &0x0000 ;
+0+010e <[^>]*> 40 18 80 43 00 00 movx.w #0, 0x0000 ;r3 As==00, PC rel. 0x0112
+0+0114 <[^>]*> 00 18 c0 43 00 00 movx.a #0, 0x0000 ;r3 As==00, PC rel. 0x0118
+0+011a <[^>]*> 40 18 c0 43 00 00 movx.b #0, 0x0000 ;r3 As==00, PC rel. 0x011e
+0+0120 <[^>]*> 40 18 80 43 00 00 movx.w #0, 0x0000 ;r3 As==00, PC rel. 0x0124
+0+0126 <[^>]*> 40 18 0f 93 cmpx.w #0, r15 ;r3 As==00
+0+012a <[^>]*> 00 18 f0 90 00 18 00 00 cmpx.a #6144, 0x0000 ;#0x1800, PC rel. 0x0130
+0+0132 <[^>]*> 40 18 6f 91 cmpx.b @r1, r15 ;
+0+0136 <[^>]*> 40 18 b2 92 00 00 cmpx.w #8, &0x0000 ;r2 As==11
+0+013c <[^>]*> 40 18 80 a3 00 00 dadcx.w 0x0000 ;PC rel. abs addr 0x0140
+0+0142 <[^>]*> 00 18 cc a3 00 00 dadcx.a 0\(r12\) ;
+0+0148 <[^>]*> 40 18 c0 a3 00 00 dadcx.b 0x0000 ;PC rel. abs addr 0x014c
+0+014e <[^>]*> 40 18 0c a3 dadcx.w r12 ;
+0+0152 <[^>]*> 40 18 27 a5 daddx.w @r5, r7 ;
+0+0156 <[^>]*> 00 18 f2 a0 10 00 00 00 daddx.a #16, &0x0000 ;#0x0010
+0+015e <[^>]*> 40 18 54 a6 02 00 daddx.b 2\(r6\), r4 ;
+0+0164 <[^>]*> 40 18 14 a0 00 00 daddx.w 0x0000, r4 ;PC rel. 0x0168
+0+016a <[^>]*> 40 18 90 83 00 00 decx.w 0x0000 ;PC rel. abs addr 0x016e
+0+0170 <[^>]*> 00 18 d0 83 00 00 decx.a 0x0000 ;PC rel. abs addr 0x0174
+0+0176 <[^>]*> 40 18 d0 83 00 00 decx.b 0x0000 ;PC rel. abs addr 0x017a
+0+017c <[^>]*> 40 18 90 83 00 00 decx.w 0x0000 ;PC rel. abs addr 0x0180
+0+0182 <[^>]*> 40 18 a0 83 00 00 decdx.w 0x0000 ;PC rel. abs addr 0x0186
+0+0188 <[^>]*> 00 18 e0 83 00 00 decdx.a 0x0000 ;PC rel. abs addr 0x018c
+0+018e <[^>]*> 40 18 e0 83 00 00 decdx.b 0x0000 ;PC rel. abs addr 0x0192
+0+0194 <[^>]*> 40 18 a0 83 00 00 decdx.w 0x0000 ;PC rel. abs addr 0x0198
+0+019a <[^>]*> 40 18 14 53 incx.w r4 ;
+0+019e <[^>]*> 00 18 55 53 incx.a r5 ;
+0+01a2 <[^>]*> 40 18 56 53 incx.b r6 ;
+0+01a6 <[^>]*> 40 18 17 53 incx.w r7 ;
+0+01aa <[^>]*> 40 18 28 53 incdx.w r8 ;
+0+01ae <[^>]*> 00 18 69 53 incdx.a r9 ;
+0+01b2 <[^>]*> 40 18 6a 53 incdx.b r10 ;
+0+01b6 <[^>]*> 40 18 2b 53 incdx.w r11 ;
+0+01ba <[^>]*> 40 18 3c e3 invx.w r12 ;
+0+01be <[^>]*> 00 18 f0 e3 00 00 xorx.a #-1, 0x0000 ;r3 As==11, PC rel. 0x01c2
+0+01c4 <[^>]*> 40 18 7e e3 xorx.b #-1, r14 ;r3 As==11
+0+01c8 <[^>]*> 40 18 3f e3 invx.w r15 ;
+0+01cc <[^>]*> 40 18 34 40 00 00 movx.w #0, r4 ;
+0+01d2 <[^>]*> 00 18 75 40 00 00 movx.a #0, r5 ;
+0+01d8 <[^>]*> 40 18 76 40 00 00 movx.b #0, r6 ;
+0+01de <[^>]*> 40 18 37 40 00 00 movx.w #0, r7 ;
+0+01e4 <[^>]*> 40 18 15 42 00 00 movx.w &0x0000,r5 ;0x0000
+0+01ea <[^>]*> 40 18 35 40 00 00 movx.w #0, r5 ;
+0+01f0 <[^>]*> 40 18 82 45 00 00 movx.w r5, &0x0000 ;
+0+01f6 <[^>]*> 40 1d b2 40 de bc 00 00 movx.w #-344866,&0x0000 ;0xabcde
+0+01fe <[^>]*> 40 18 92 42 00 00 00 00 movx.w &0x0000,&0x0000 ;0x0000
+0+0206 <[^>]*> 40 18 b2 40 00 00 00 00 movx.w #0, &0x0000 ;
+0+020e <[^>]*> 40 18 15 40 00 00 movx.w 0x0000, r5 ;PC rel. 0x0212
+0+0214 <[^>]*> 40 18 80 45 00 00 movx.w r5, 0x0000 ; PC rel. 0x0218
+0+021a <[^>]*> 40 1d b0 40 de bc 00 00 movx.w #-344866,0x0000 ;0xabcde, PC rel. 0x0220
+0+0222 <[^>]*> 40 18 90 40 00 00 00 00 movx.w 0x0000, 0x0000 ;PC rel. 0x0226, PC rel. 0x0228
+0+022a <[^>]*> 40 18 0f 73 sbcx.w r15 ;
+0+022e <[^>]*> 00 18 40 73 sbcx.a r0 ;
+0+0232 <[^>]*> 40 18 4f 73 sbcx.b r15 ;
+0+0236 <[^>]*> 40 18 87 73 00 00 sbcx.w 0\(r7\) ;
+0+023c <[^>]*> 40 18 0f 7f subcx.w r15, r15 ;
+0+0240 <[^>]*> 80 18 7f 70 45 23 subcx.a #74565, r15 ;0x12345
+0+0246 <[^>]*> 40 18 4f 7f subcx.b r15, r15 ;
+0+024a <[^>]*> 40 18 b7 75 00 00 subcx.w @r5\+, 0\(r7\) ;
+0+0250 <[^>]*> 40 18 10 86 02 00 subx.w 2\(r6\), r0 ;
+0+0256 <[^>]*> 00 18 f0 80 67 11 00 00 subx.a #4455, 0x0000 ;#0x1167, PC rel. 0x025c
+0+025e <[^>]*> 40 18 50 86 02 00 subx.b 2\(r6\), r0 ;
+0+0264 <[^>]*> 40 18 10 86 02 00 subx.w 2\(r6\), r0 ;
+0+026a <[^>]*> 40 18 80 93 00 00 cmpx.w #0, 0x0000 ;r3 As==00, PC rel. 0x026e
+0+0270 <[^>]*> 00 18 c0 93 00 00 cmpx.a #0, 0x0000 ;r3 As==00, PC rel. 0x0274
+0+0276 <[^>]*> 40 18 c0 93 00 00 cmpx.b #0, 0x0000 ;r3 As==00, PC rel. 0x027a
+0+027c <[^>]*> 40 18 80 93 00 00 cmpx.w #0, 0x0000 ;r3 As==00, PC rel. 0x0280
+0+0282 <[^>]*> 40 18 b0 e0 5a 5a 00 00 xorx.w #23130, 0x0000 ;#0x5a5a, PC rel. 0x0288
+0+028a <[^>]*> 40 18 90 e2 00 00 00 00 xorx.w &0x0000,0x0000 ;0x0000, PC rel. 0x0290
+0+0292 <[^>]*> 40 18 a0 e8 00 00 xorx.w @r8, 0x0000 ; PC rel. 0x0296
+0+0298 <[^>]*> 40 18 80 e8 00 00 xorx.w r8, 0x0000 ; PC rel. 0x029c
+0+029e <[^>]*> 40 18 d0 e6 02 00 00 00 xorx.b 2\(r6\), 0x0000 ; PC rel. 0x02a4
+0+02a6 <[^>]*> 40 18 f0 e8 00 00 xorx.b @r8\+, 0x0000 ; PC rel. 0x02aa
+0+02ac <[^>]*> 00 18 d2 e0 00 00 00 00 xorx.a 0x0000, &0x0000 ;PC rel. 0x02b0
+0+02b4 <[^>]*> 40 18 26 e5 xorx.w @r5, r6 ;
+0+02b8 <[^>]*> 04 18 ff e0 39 30 78 56 xorx.a #12345, 284280\(r15\);#0x3039, 0x45678
+0+02c0 <[^>]*> a7 01 45 23 adda #74565, r7 ;0x12345
+0+02c4 <[^>]*> ee 06 adda r6, r14 ;
+0+02c6 <[^>]*> 80 00 00 00 mova #0, r0 ;
+0+02ca <[^>]*> 80 01 44 10 mova #69700, r0 ;0x11044
+0+02ce <[^>]*> c0 05 mova r5, r0 ;
+0+02d0 <[^>]*> 20 00 00 00 bra &0 ;
+0+02d4 <[^>]*> 00 05 bra @r5 ;
+0+02d6 <[^>]*> 10 05 bra @r5\+ ;
+0+02d8 <[^>]*> 30 05 76 98 bra -26506\(r5\) ;0xffff9876
+0+02dc <[^>]*> 45 13 calla r5 ;
+0+02de <[^>]*> 56 13 00 00 calla 0\(r6\) ;0x00000
+0+02e2 <[^>]*> 67 13 calla @r7 ;
+0+02e4 <[^>]*> 78 13 calla @r8\+ ;
+0+02e6 <[^>]*> 80 13 00 00 calla &0 ;0x00000
+0+02ea <[^>]*> 90 13 00 00 calla 0\(PC\) ;PC rel. 0x002ec
+0+02ee <[^>]*> b0 13 00 00 calla #0 ;0x00000
+0+02f2 <[^>]*> 40 18 06 43 clrx.w r6 ;
+0+02f6 <[^>]*> d2 01 cmpa r1, r2 ;
+0+02f8 <[^>]*> 93 0f cb ed cmpa #1043915,r3 ;0xfedcb
+0+02fc <[^>]*> 40 18 25 83 decdx.w r5 ;
+0+0300 <[^>]*> 40 18 25 53 incdx.w r5 ;
+0+0304 <[^>]*> c8 09 mova r9, r8 ;
+0+0306 <[^>]*> 8c 01 45 23 mova #74565, r12 ;0x12345
+0+030a <[^>]*> 38 09 00 01 mova 256\(r9\),r8 ;0x00100
+0+030e <[^>]*> 2c 00 00 00 mova &0, r12 ;
+0+0312 <[^>]*> 08 09 mova @r9, r8 ;
+0+0314 <[^>]*> 18 09 mova @r9\+, r8 ;
+0+0316 <[^>]*> 79 08 00 01 mova r8, 256\(r9\) ; 0x00100
+0+031a <[^>]*> 60 0d 00 00 mova r13, &0 ;
+0+031e <[^>]*> 10 01 reta ;
+0+0320 <[^>]*> 00 13 reti
+0+0322 <[^>]*> f6 05 suba r5, r6 ;
+0+0324 <[^>]*> b6 0f ff ff suba #1048575,r6 ;0xfffff
+0+0328 <[^>]*> 40 18 80 93 00 00 cmpx.w #0, 0x0000 ;r3 As==00, PC rel. 0x032c
+0+032e <[^>]*> 05 17 popm #1, r5 ;16-bit words
+0+0330 <[^>]*> 2d 16 popm.a #3, r15 ;20-bit words
+0+0332 <[^>]*> 75 17 popm #8, r12 ;16-bit words
+0+0334 <[^>]*> 40 18 3a 41 popx.w r10 ;
+0+0338 <[^>]*> 00 18 7a 41 popx.a r10 ;
+0+033c <[^>]*> 40 18 7a 41 popx.b r10 ;
+0+0340 <[^>]*> 40 18 3a 41 popx.w r10 ;
+0+0344 <[^>]*> 09 15 pushm #1, r9 ;16-bit words
+0+0346 <[^>]*> 19 14 pushm.a #2, r9 ;20-bit words
+0+0348 <[^>]*> 29 15 pushm #3, r9 ;16-bit words
+0+034a <[^>]*> 40 18 08 12 pushx.w r8 ;
+0+034e <[^>]*> 00 18 48 12 pushx.a r8 ;
+0+0352 <[^>]*> 40 18 52 12 00 00 pushx.b &0x0000 ;
+0+0358 <[^>]*> 40 18 08 12 pushx.w r8 ;
+0+035c <[^>]*> 5f 02 rlam #1, r15 ;
+0+035e <[^>]*> 4f 06 rlam.a #2, r15 ;
+0+0360 <[^>]*> 5f 0a rlam #3, r15 ;
+0+0362 <[^>]*> 40 18 06 56 rlax.w r6 ;
+0+0366 <[^>]*> 00 18 46 56 rlax.a r6 ;
+0+036a <[^>]*> 40 18 06 56 rlax.w r6 ;
+0+036e <[^>]*> 40 18 06 66 rlcx.w r6 ;
+0+0372 <[^>]*> 00 18 46 66 rlcx.a r6 ;
+0+0376 <[^>]*> 40 18 06 66 rlcx.w r6 ;
+0+037a <[^>]*> 56 01 rram #1, r6 ;
+0+037c <[^>]*> 46 0d rram.a #4, r6 ;
+0+037e <[^>]*> 56 05 rram #2, r6 ;
+0+0380 <[^>]*> 40 18 0b 11 rrax.w r11 ;
+0+0384 <[^>]*> 00 18 4b 11 rrax.a r11 ;
+0+0388 <[^>]*> 40 18 0b 11 rrax.w r11 ;
+0+038c <[^>]*> 55 0c rrcm #4, r5 ;
+0+038e <[^>]*> 45 00 rrcm.a #1, r5 ;
+0+0390 <[^>]*> 55 08 rrcm #3, r5 ;
+0+0392 <[^>]*> 40 18 0d 10 rrcx.w r13 ;
+0+0396 <[^>]*> 00 18 4d 10 rrcx.a r13 ;
+0+039a <[^>]*> 40 18 0d 10 rrcx.w r13 ;
+0+039e <[^>]*> 54 0b rrum #3, r4 ;
+0+03a0 <[^>]*> 44 07 rrum.a #2, r4 ;
+0+03a2 <[^>]*> 54 03 rrum #1, r4 ;
+0+03a4 <[^>]*> 54 03 rrum #1, r4 ;
+0+03a6 <[^>]*> 47 03 rrum.a #1, r7 ;
+0+03a8 <[^>]*> 45 11 rra.b r5 ;
+0+03aa <[^>]*> 75 c0 80 00 bic.b #128, r5 ;#0x0080
+0+03ae <[^>]*> 56 03 rrum #1, r6 ;
+0+03b0 <[^>]*> 40 18 81 10 swpbx.w r1 ;
+0+03b4 <[^>]*> 00 18 90 10 00 00 swpbx.a 0x0000 ;PC rel. 0x03b8
+0+03ba <[^>]*> 40 18 8c 10 swpbx.w r12 ;
+0+03be <[^>]*> 40 18 82 11 sxtx.w r2 ;
+0+03c2 <[^>]*> 00 18 92 11 00 00 sxtx.a &0x0000 ;
+0+03c8 <[^>]*> 40 18 82 11 sxtx.w r2 ;
+0+03cc <[^>]*> 04 18 45 11 rpt #5 \{ rrax.a r5 ;
+0+03d0 <[^>]*> 85 18 45 11 rpt r5 \{ rrax.a r5 ;
diff --git a/gas/testsuite/gas/msp430/msp430x.s b/gas/testsuite/gas/msp430/msp430x.s
new file mode 100644
index 000000000..db27597f8
--- /dev/null
+++ b/gas/testsuite/gas/msp430/msp430x.s
@@ -0,0 +1,261 @@
+ .text
+ .global foo
+foo:
+ adc r4 ; MSP430 instruction for comparison purposes.
+
+ adcx r4
+ adcx.a bar
+ adcx.b r6
+ adcx.w r7
+
+ addcx r8, r9
+ addcx.a #0x12345, r10
+ addcx.b r11, r12
+ addcx.w r13, r14
+
+ ADDX @R9, PC
+ ADDX R9, PC
+ ADDX.A #FE000h, PC
+ ADDX.A &EDE, PC
+ ADDX.A @R9+, PC
+ ADDX.A EDE, PC
+ addx.b r1, r2
+ addx.w r3, r4
+ ADDX K(R4), R5
+
+ ANDX #1234, 4(R6)
+ ANDX 4(R7), 4(R6)
+ ANDX @R5+, 4(R6)
+ ANDX EDE, 4(R6)
+ ANDX EDE, TONI
+ ANDX.A @R5, 4(R6)
+ ANDX.A R5, 4(R6)
+ ANDX.B &EDE, 4(R6)
+ andx.w r1, r2
+
+ bicx #0xa0, r14
+ bicx.a #0xa0, r14
+ bicx.b #0xa0, r14
+ bicx.w #0xa0, r14
+
+ bisx #8, r11
+ bisx.a #8, r11
+ bisx.b #8, r11
+ bisx.w #8, r11
+
+ BITX #20, R8
+ BITX &EDE, &TONI
+ BITX &EDE, R8
+ BITX 2(R5), R8
+ BITX 8(SP), &EDE
+ BITX @R5+, &EDE
+ BITX @R5+, R8
+ BITX @R5, R8
+ BITX EDE, &TONI
+ BITX.B #12, &EDE
+ BITX.B @R5, &EDE
+ BITX.B EDE, R8
+ BITX.B R5, R8
+ BITX.W R5, &EDE
+
+ clrx TONI
+ clrx.a fooz
+ clrx.b bar
+ clrx.w baz
+
+ cmpx #0, r15
+ cmpx.a #01800h, ede
+ cmpx.b @r1, r15
+ cmpx.w @r2+, &pin
+
+ dadcx fooz
+ dadcx.a 0(r12)
+ dadcx.b bar
+ dadcx.w r12
+
+ daddx @r5, r7
+ daddx.a #10h, &decdr
+ daddx.b 2(r6), r4
+ daddx.w bcd, r4
+
+ decx toni
+ decx.a fooz
+ decx.b bar
+ decx.w fred
+
+ decdx toni
+ decdx.a fooz
+ decdx.b bar
+ decdx.w fred
+
+ incx r4
+ incx.a r5
+ incx.b r6
+ incx.w r7
+
+ incdx r8
+ incdx.a r9
+ incdx.b r10
+ incdx.w r11
+
+ invx r12
+ invx.a LEO
+ invx.b r14
+ invx.w r15
+
+ movx #foo, r4
+ movx.a #foo, r5
+ movx.b #foo, r6
+ movx.w #foo, r7
+ MOVX &X, R5
+ MOVX #X, R5
+ MOVX R5, &Y
+ MOVX #0xabcde, &Y
+ MOVX &X, &Y
+ MOVX #X, &Y
+ MOVX X, R5
+ MOVX R5, Y
+ MOVX #0xabcde, Y
+ MOVX X, Y
+
+ sbcx r15
+ sbcx.a 012345h
+ sbcx.b r15
+ sbcx.w 0(r7)
+
+ subcx r15, r15
+ subcx.a #012345h, r15
+ subcx.b r15, r15
+ subcx.w @r5+, 0(r7)
+
+ SUBX 2(R6), PC
+ SUBX.A #4455, ede
+ SUBX.B 2(R6), PC
+ SUBX.W 2(R6), PC
+
+ tstx LEO
+ tstx.a foo
+ tstx.b bar
+ tstx.w baz
+
+ XORX #5A5Ah, EDE
+ XORX &EDE, TONI
+ XORX @R8, EDE
+ XORX R8, EDE
+ XORX.B 2(R6), EDE
+ XORX.B @R8+, EDE
+ xorx.a toni, &cntr
+ xorx.w @r5, r6
+ xorx.a #12345, 0x45678h(r15)
+
+ adda #0x12345, r7
+ adda r6, r14
+
+ bra #bar
+ bra #011044H
+ bra r5
+ bra &ede
+ bra @r5
+ bra @r5+
+ bra 0x9876(r5)
+
+ calla r5
+ calla 0x1234(r6)
+ calla @r7
+ calla @r8+
+ calla &foo
+ calla bar
+ calla #011004h
+
+ clra r6
+
+ cmpa r1, r2
+ cmpa #0xfedcb, r3
+
+ decda r5
+ incda r5
+
+ mova R9,R8
+ MOVA #12345h,R12
+ MOVA 100h(R9),R8
+ MOVA &EDE,R12
+ MOVA @R9,R8
+ MOVA @R9+,R8
+ MOVA R8,100h(R9)
+ MOVA R13,&EDE
+
+ reta
+ reti
+
+ suba r5, r6
+ suba #0xfffff, r6
+
+ tsta fooz
+
+ popm #1, r5
+ popm.a #3, r15
+ popm.w #8, r12
+
+ popx r10
+ popx.a r10
+ popx.b r10
+ popx.w r10
+
+ pushm #1, r9
+ pushm.a #2, r9
+ pushm.w #3, r9
+
+ pushx r8
+ pushx.a r8
+ pushx.b &ede
+ pushx.w r8
+
+ rlam #1, r15
+ rlam.a #2, r15
+ rlam.w #3, r15
+
+ rlax r6
+ rlax.a r6
+ rlax.w r6
+
+ rlcx r6
+ rlcx.a r6
+ rlcx.w r6
+
+ rram #1, r6
+ rram.a #4, r6
+ rram.w #2, r6
+
+ rrax r11
+ rrax.a r11
+ rrax.w r11
+
+ rrcm #4, r5
+ rrcm.a #1, r5
+ rrcm.w #3, r5
+
+ rrcx r13
+ rrcx.a r13
+ rrcx.w r13
+
+ rrum #3, r4
+ rrum.a #2, r4
+ rrum.w #1, r4
+
+ rrux r4
+ rrux.a r7
+ rrux.b r5
+ rrux.w r6
+
+ swpbx r1
+ swpbx.a ede
+ swpbx.w r12
+
+ sxtx r2
+ sxtx.a &ede
+ sxtx.w r2
+
+ rpt #5
+ rrax.a r5
+ rpt r5
+ rrax.a r5
diff --git a/gas/testsuite/gas/msp430/opcode.d b/gas/testsuite/gas/msp430/opcode.d
index 22df51c52..9212d89e6 100644
--- a/gas/testsuite/gas/msp430/opcode.d
+++ b/gas/testsuite/gas/msp430/opcode.d
@@ -22,14 +22,14 @@ Disassembly of section .text:
0+024 <[^>]*> 8c 10 swpb r12 ;
0+026 <[^>]*> 0d 10 rrc r13 ;
0+028 <[^>]*> 30 41 ret
-0+02a <[^>]*> 31 40 00 00 mov #0, r1 ;#0x0000
-0+02e <[^>]*> b0 12 00 00 call #0 ;#0x0000
+0+02a <[^>]*> 31 40 00 00 mov #0, r1 ;
+0+02e <[^>]*> b0 12 00 00 call #0 ;
0+032 <[^>]*> 1e 42 00 00 mov &0x0000,r14 ;0x0000
0+036 <[^>]*> 0f 4e mov r14, r15 ;
0+038 <[^>]*> 0f 5f rla r15 ;
0+03a <[^>]*> 0f 7f subc r15, r15 ;
0+03c <[^>]*> 3f e3 inv r15 ;
-0+03e <[^>]*> b0 12 00 00 call #0 ;#0x0000
+0+03e <[^>]*> b0 12 00 00 call #0 ;
0+042 <[^>]*> 82 4e 00 00 mov r14, &0x0000 ;
0+046 <[^>]*> 82 4f 00 00 mov r15, &0x0000 ;
0+04a <[^>]*> 1e 42 00 00 mov &0x0000,r14 ;0x0000
@@ -37,7 +37,7 @@ Disassembly of section .text:
0+050 <[^>]*> 0f 5f rla r15 ;
0+052 <[^>]*> 0f 7f subc r15, r15 ;
0+054 <[^>]*> 3f e3 inv r15 ;
-0+056 <[^>]*> b0 12 00 00 call #0 ;#0x0000
+0+056 <[^>]*> b0 12 00 00 call #0 ;
0+05a <[^>]*> 82 4e 00 00 mov r14, &0x0000 ;
0+05e <[^>]*> 82 4f 00 00 mov r15, &0x0000 ;
0+062 <[^>]*> 3f 40 f0 00 mov #240, r15 ;#0x00f0
diff --git a/gas/testsuite/gas/msp430/opcode.s b/gas/testsuite/gas/msp430/opcode.s
index b85a4636d..4924a6017 100644
--- a/gas/testsuite/gas/msp430/opcode.s
+++ b/gas/testsuite/gas/msp430/opcode.s
@@ -1,4 +1,4 @@
- .arch msp430x123
+ .arch msp430f123
.text
.p2align 1,0
diff --git a/gas/testsuite/gas/ppc/altivec2.d b/gas/testsuite/gas/ppc/altivec2.d
index 90a4b108f..fc10fb5a2 100644
--- a/gas/testsuite/gas/ppc/altivec2.d
+++ b/gas/testsuite/gas/ppc/altivec2.d
@@ -58,4 +58,68 @@ Disassembly of section \.text:
c0: (10 d1 84 03|03 84 d1 10) vabsdub v6,v17,v16
c4: (12 b2 24 43|43 24 b2 12) vabsduh v21,v18,v4
c8: (13 34 4c 83|83 4c 34 13) vabsduw v25,v20,v9
+ cc: (10 d1 a6 ad|ad a6 d1 10) vpermxor v6,v17,v20,v26
+ d0: (13 ba 7f 3c|3c 7f ba 13) vaddeuqm v29,v26,v15,v28
+ d4: (11 e8 3e 3d|3d 3e e8 11) vaddecuq v15,v8,v7,v24
+ d8: (10 46 a8 7e|7e a8 46 10) vsubeuqm v2,v6,v21,v1
+ dc: (13 a6 01 3f|3f 01 a6 13) vsubecuq v29,v6,v0,v4
+ e0: (11 c9 18 88|88 18 c9 11) vmulouw v14,v9,v3
+ e4: (13 10 90 89|89 90 10 13) vmuluwm v24,v16,v18
+ e8: (11 51 88 c0|c0 88 51 11) vaddudm v10,v17,v17
+ ec: (13 d9 20 c2|c2 20 d9 13) vmaxud v30,v25,v4
+ f0: (11 46 e0 c4|c4 e0 46 11) vrld v10,v6,v28
+ f4: (13 67 38 c7|c7 38 67 13) vcmpequd v27,v7,v7
+ f8: (12 d0 c9 00|00 c9 d0 12) vadduqm v22,v16,v25
+ fc: (10 35 e9 40|40 e9 35 10) vaddcuq v1,v21,v29
+ 100: (12 8b 99 88|88 99 8b 12) vmulosw v20,v11,v19
+ 104: (13 13 09 c2|c2 09 13 13) vmaxsd v24,v19,v1
+ 108: (11 bb f2 88|88 f2 bb 11) vmuleuw v13,v27,v30
+ 10c: (11 38 8a c2|c2 8a 38 11) vminud v9,v24,v17
+ 110: (11 52 e2 c7|c7 e2 52 11) vcmpgtud v10,v18,v28
+ 114: (10 1d b3 88|88 b3 1d 10) vmulesw v0,v29,v22
+ 118: (11 bc 0b c2|c2 0b bc 11) vminsd v13,v28,v1
+ 11c: (11 54 2b c4|c4 2b 54 11) vsrad v10,v20,v5
+ 120: (13 75 2b c7|c7 2b 75 13) vcmpgtsd v27,v21,v5
+ 124: (10 17 f6 01|01 f6 17 10) bcdadd\. v0,v23,v30,1
+ 128: (13 38 d4 08|08 d4 38 13) vpmsumb v25,v24,v26
+ 12c: (11 04 26 41|41 26 04 11) bcdsub\. v8,v4,v4,1
+ 130: (12 0e d4 48|48 d4 0e 12) vpmsumh v16,v14,v26
+ 134: (13 62 d4 4e|4e d4 62 13) vpkudum v27,v2,v26
+ 138: (10 d7 8c 88|88 8c d7 10) vpmsumw v6,v23,v17
+ 13c: (12 86 cc c8|c8 cc 86 12) vpmsumd v20,v6,v25
+ 140: (13 76 84 ce|ce 84 76 13) vpkudus v27,v22,v16
+ 144: (12 b4 94 c0|c0 94 b4 12) vsubudm v21,v20,v18
+ 148: (12 b4 95 00|00 95 b4 12) vsubuqm v21,v20,v18
+ 14c: (13 bd 35 08|08 35 bd 13) vcipher v29,v29,v6
+ 150: (10 4d a5 09|09 a5 4d 10) vcipherlast v2,v13,v20
+ 154: (12 80 95 0c|0c 95 80 12) vgbbd v20,v18
+ 158: (12 68 cd 40|40 cd 68 12) vsubcuq v19,v8,v25
+ 15c: (11 3a ed 44|44 ed 3a 11) vorc v9,v26,v29
+ 160: (12 94 6d 48|48 6d 94 12) vncipher v20,v20,v13
+ 164: (11 e5 dd 49|49 dd e5 11) vncipherlast v15,v5,v27
+ 168: (10 73 35 4c|4c 35 73 10) vbpermq v3,v19,v6
+ 16c: (13 c4 e5 4e|4e e5 c4 13) vpksdus v30,v4,v28
+ 170: (10 04 75 84|84 75 04 10) vnand v0,v4,v14
+ 174: (12 28 ed c4|c4 ed 28 12) vsld v17,v8,v29
+ 178: (13 b4 05 c8|c8 05 b4 13) vsbox v29,v20
+ 17c: (11 67 5d ce|ce 5d 67 11) vpksdss v11,v7,v11
+ 180: (10 73 84 c7|c7 84 73 10) vcmpequd\. v3,v19,v16
+ 184: (12 40 8e 4e|4e 8e 40 12) vupkhsw v18,v17
+ 188: (13 a8 6e 82|82 6e a8 13) vshasigmaw v29,v8,0,13
+ 18c: (12 fc d6 84|84 d6 fc 12) veqv v23,v28,v26
+ 190: (13 a0 17 8c|8c 17 a0 13) vmrgew v29,v0,v2
+ 194: (13 a0 16 8c|8c 16 a0 13) vmrgow v29,v0,v2
+ 198: (13 73 06 c2|c2 06 73 13) vshasigmad v27,v19,0,0
+ 19c: (12 9c e6 c4|c4 e6 9c 12) vsrd v20,v28,v28
+ 1a0: (12 40 ae ce|ce ae 40 12) vupklsw v18,v21
+ 1a4: (13 c0 3f 02|02 3f c0 13) vclzb v30,v7
+ 1a8: (13 a0 af 03|03 af a0 13) vpopcntb v29,v21
+ 1ac: (13 20 af 42|42 af 20 13) vclzh v25,v21
+ 1b0: (12 00 f7 43|43 f7 00 12) vpopcnth v16,v30
+ 1b4: (13 80 1f 82|82 1f 80 13) vclzw v28,v3
+ 1b8: (11 40 4f 83|83 4f 40 11) vpopcntw v10,v9
+ 1bc: (12 c0 4f c2|c2 4f c0 12) vclzd v22,v9
+ 1c0: (11 e0 f7 c3|c3 f7 e0 11) vpopcntd v15,v30
+ 1c4: (10 5f 36 c7|c7 36 5f 10) vcmpgtud\. v2,v31,v6
+ 1c8: (12 8f 17 c7|c7 17 8f 12) vcmpgtsd\. v20,v15,v2
#pass
diff --git a/gas/testsuite/gas/ppc/altivec2.s b/gas/testsuite/gas/ppc/altivec2.s
index 9f11a8bf6..6233c0e52 100644
--- a/gas/testsuite/gas/ppc/altivec2.s
+++ b/gas/testsuite/gas/ppc/altivec2.s
@@ -1,3 +1,4 @@
+ .text
start:
lvepxl 3,0,28
lvepxl 19,4,18
@@ -50,3 +51,67 @@ start:
vabsdub 6,17,16
vabsduh 21,18,4
vabsduw 25,20,9
+ vpermxor 6,17,20,26
+ vaddeuqm 29,26,15,28
+ vaddecuq 15,8,7,24
+ vsubeuqm 2,6,21,1
+ vsubecuq 29,6,0,4
+ vmulouw 14,9,3
+ vmuluwm 24,16,18
+ vaddudm 10,17,17
+ vmaxud 30,25,4
+ vrld 10,6,28
+ vcmpequd 27,7,7
+ vadduqm 22,16,25
+ vaddcuq 1,21,29
+ vmulosw 20,11,19
+ vmaxsd 24,19,1
+ vmuleuw 13,27,30
+ vminud 9,24,17
+ vcmpgtud 10,18,28
+ vmulesw 0,29,22
+ vminsd 13,28,1
+ vsrad 10,20,5
+ vcmpgtsd 27,21,5
+ bcdadd. 0,23,30,1
+ vpmsumb 25,24,26
+ bcdsub. 8,4,4,1
+ vpmsumh 16,14,26
+ vpkudum 27,2,26
+ vpmsumw 6,23,17
+ vpmsumd 20,6,25
+ vpkudus 27,22,16
+ vsubudm 21,20,18
+ vsubuqm 21,20,18
+ vcipher 29,29,6
+ vcipherlast 2,13,20
+ vgbbd 20,18
+ vsubcuq 19,8,25
+ vorc 9,26,29
+ vncipher 20,20,13
+ vncipherlast 15,5,27
+ vbpermq 3,19,6
+ vpksdus 30,4,28
+ vnand 0,4,14
+ vsld 17,8,29
+ vsbox 29,20
+ vpksdss 11,7,11
+ vcmpequd. 3,19,16
+ vupkhsw 18,17
+ vshasigmaw 29,8,0,13
+ veqv 23,28,26
+ vmrgew 29,0,2
+ vmrgow 29,0,2
+ vshasigmad 27,19,0,0
+ vsrd 20,28,28
+ vupklsw 18,21
+ vclzb 30,7
+ vpopcntb 29,21
+ vclzh 25,21
+ vpopcnth 16,30
+ vclzw 28,3
+ vpopcntw 10,9
+ vclzd 22,9
+ vpopcntd 15,30
+ vcmpgtud. 2,31,6
+ vcmpgtsd. 20,15,2
diff --git a/gas/testsuite/gas/ppc/power8.d b/gas/testsuite/gas/ppc/power8.d
index 1eb7fa9c3..2d576e6f3 100644
--- a/gas/testsuite/gas/ppc/power8.d
+++ b/gas/testsuite/gas/ppc/power8.d
@@ -27,3 +27,127 @@ Disassembly of section \.text:
44: (60 42 00 00|00 00 42 60) ori r2,r2,0
48: (60 00 00 00|00 00 00 60) nop
4c: (60 42 00 00|00 00 42 60) ori r2,r2,0
+ 50: (4c 00 01 24|24 01 00 4c) rfebb
+ 54: (4c 00 01 24|24 01 00 4c) rfebb
+ 58: (4c 00 09 24|24 09 00 4c) rfebb 1
+ 5c: (4d 95 04 60|60 04 95 4d) bctar- 12,4\*cr5\+gt
+ 60: (4c 87 04 61|61 04 87 4c) bctarl- 4,4\*cr1\+so
+ 64: (4d ac 04 60|60 04 ac 4d) bctar\+ 12,4\*cr3\+lt
+ 68: (4c a2 04 61|61 04 a2 4c) bctarl\+ 4,eq
+ 6c: (4c 88 0c 60|60 0c 88 4c) bctar 4,4\*cr2\+lt,1
+ 70: (4c 87 14 61|61 14 87 4c) bctarl 4,4\*cr1\+so,2
+ 74: (7c 00 00 3c|3c 00 00 7c) waitasec
+ 78: (7c 00 41 1c|1c 41 00 7c) msgsndp r8
+ 7c: (7c 20 01 26|26 01 20 7c) mtsle 1
+ 80: (7c 00 d9 5c|5c d9 00 7c) msgclrp r27
+ 84: (7d 4a 61 6d|6d 61 4a 7d) stqcx\. r10,r10,r12
+ 88: (7f 80 39 6d|6d 39 80 7f) stqcx\. r28,0,r7
+ 8c: (7f 13 5a 28|28 5a 13 7f) lqarx r24,r19,r11
+ 90: (7e c0 5a 28|28 5a c0 7e) lqarx r22,0,r11
+ 94: (7e 80 32 5c|5c 32 80 7e) mfbhrbe r20,6
+ 98: (7f b1 83 29|29 83 b1 7f) pbt\. r29,r17,r16
+ 9c: (7d c0 3b 29|29 3b c0 7d) pbt\. r14,0,r7
+ a0: (7c 00 03 5c|5c 03 00 7c) clrbhrb
+ a4: (11 6a 05 ed|ed 05 6a 11) vpermxor v11,v10,v0,v23
+ a8: (13 02 39 3c|3c 39 02 13) vaddeuqm v24,v2,v7,v4
+ ac: (11 4a 40 bd|bd 40 4a 11) vaddecuq v10,v10,v8,v2
+ b0: (10 af 44 fe|fe 44 af 10) vsubeuqm v5,v15,v8,v19
+ b4: (11 9f 87 7f|7f 87 9f 11) vsubecuq v12,v31,v16,v29
+ b8: (12 9d 68 88|88 68 9d 12) vmulouw v20,v29,v13
+ bc: (13 a0 d0 89|89 d0 a0 13) vmuluwm v29,v0,v26
+ c0: (11 15 e0 c0|c0 e0 15 11) vaddudm v8,v21,v28
+ c4: (10 3a 08 c2|c2 08 3a 10) vmaxud v1,v26,v1
+ c8: (12 83 08 c4|c4 08 83 12) vrld v20,v3,v1
+ cc: (10 93 58 c7|c7 58 93 10) vcmpequd v4,v19,v11
+ d0: (12 ee f1 00|00 f1 ee 12) vadduqm v23,v14,v30
+ d4: (11 08 69 40|40 69 08 11) vaddcuq v8,v8,v13
+ d8: (13 9b 21 88|88 21 9b 13) vmulosw v28,v27,v4
+ dc: (10 64 21 c2|c2 21 64 10) vmaxsd v3,v4,v4
+ e0: (10 13 aa 88|88 aa 13 10) vmuleuw v0,v19,v21
+ e4: (13 14 9a c2|c2 9a 14 13) vminud v24,v20,v19
+ e8: (10 1c 7a c7|c7 7a 1c 10) vcmpgtud v0,v28,v15
+ ec: (12 a0 13 88|88 13 a0 12) vmulesw v21,v0,v2
+ f0: (11 3a 4b c2|c2 4b 3a 11) vminsd v9,v26,v9
+ f4: (13 3d 5b c4|c4 5b 3d 13) vsrad v25,v29,v11
+ f8: (11 7c 5b c7|c7 5b 7c 11) vcmpgtsd v11,v28,v11
+ fc: (10 a8 d6 01|01 d6 a8 10) bcdadd\. v5,v8,v26,1
+ 100: (10 83 64 08|08 64 83 10) vpmsumb v4,v3,v12
+ 104: (13 5f ae 41|41 ae 5f 13) bcdsub\. v26,v31,v21,1
+ 108: (10 b1 84 48|48 84 b1 10) vpmsumh v5,v17,v16
+ 10c: (12 f1 a4 4e|4e a4 f1 12) vpkudum v23,v17,v20
+ 110: (13 15 ec 88|88 ec 15 13) vpmsumw v24,v21,v29
+ 114: (11 36 6c c8|c8 6c 36 11) vpmsumd v9,v22,v13
+ 118: (12 53 94 ce|ce 94 53 12) vpkudus v18,v19,v18
+ 11c: (13 d0 b5 00|00 b5 d0 13) vsubuqm v30,v16,v22
+ 120: (11 cb 3d 08|08 3d cb 11) vcipher v14,v11,v7
+ 124: (11 42 b5 09|09 b5 42 11) vcipherlast v10,v2,v22
+ 128: (12 e0 6d 0c|0c 6d e0 12) vgbbd v23,v13
+ 12c: (12 19 85 40|40 85 19 12) vsubcuq v16,v25,v16
+ 130: (13 e1 2d 44|44 2d e1 13) vorc v31,v1,v5
+ 134: (10 91 fd 48|48 fd 91 10) vncipher v4,v17,v31
+ 138: (13 02 dd 49|49 dd 02 13) vncipherlast v24,v2,v27
+ 13c: (12 f5 bd 4c|4c bd f5 12) vbpermq v23,v21,v23
+ 140: (13 72 4d 4e|4e 4d 72 13) vpksdus v27,v18,v9
+ 144: (13 7d dd 84|84 dd 7d 13) vnand v27,v29,v27
+ 148: (12 73 c5 c4|c4 c5 73 12) vsld v19,v19,v24
+ 14c: (10 ad 05 c8|c8 05 ad 10) vsbox v5,v13
+ 150: (13 23 3d ce|ce 3d 23 13) vpksdss v25,v3,v7
+ 154: (13 88 04 c7|c7 04 88 13) vcmpequd\. v28,v8,v0
+ 158: (13 40 d6 4e|4e d6 40 13) vupkhsw v26,v26
+ 15c: (10 a7 36 82|82 36 a7 10) vshasigmaw v5,v7,0,6
+ 160: (13 95 76 84|84 76 95 13) veqv v28,v21,v14
+ 164: (10 28 9e 8c|8c 9e 28 10) vmrgow v1,v8,v19
+ 168: (10 0a 56 c2|c2 56 0a 10) vshasigmad v0,v10,0,10
+ 16c: (10 bb 76 c4|c4 76 bb 10) vsrd v5,v27,v14
+ 170: (11 60 6e ce|ce 6e 60 11) vupklsw v11,v13
+ 174: (11 c0 87 02|02 87 c0 11) vclzb v14,v16
+ 178: (12 80 df 03|03 df 80 12) vpopcntb v20,v27
+ 17c: (13 80 5f 42|42 5f 80 13) vclzh v28,v11
+ 180: (13 00 4f 43|43 4f 00 13) vpopcnth v24,v9
+ 184: (13 60 ff 82|82 ff 60 13) vclzw v27,v31
+ 188: (12 20 9f 83|83 9f 20 12) vpopcntw v17,v19
+ 18c: (11 80 ef c2|c2 ef 80 11) vclzd v12,v29
+ 190: (12 e0 b7 c3|c3 b7 e0 12) vpopcntd v23,v22
+ 194: (13 14 ee c7|c7 ee 14 13) vcmpgtud\. v24,v20,v29
+ 198: (11 26 df c7|c7 df 26 11) vcmpgtsd\. v9,v6,v27
+ 19c: (7f ce d0 19|19 d0 ce 7f) lxsiwzx vs62,r14,r26
+ 1a0: (7d 00 c8 19|19 c8 00 7d) lxsiwzx vs40,0,r25
+ 1a4: (7f 20 d0 98|98 d0 20 7f) lxsiwax vs25,0,r26
+ 1a8: (7c 60 18 98|98 18 60 7c) lxsiwax vs3,0,r3
+ 1ac: (7f cc 00 67|67 00 cc 7f) mfvsrd r12,vs62
+ 1b0: (7d 94 00 e6|e6 00 94 7d) mffprwz r20,f12
+ 1b4: (7d c9 71 18|18 71 c9 7d) stxsiwx vs14,r9,r14
+ 1b8: (7e a0 41 18|18 41 a0 7e) stxsiwx vs21,0,r8
+ 1bc: (7e 0b 01 67|67 01 0b 7e) mtvsrd vs48,r11
+ 1c0: (7f f7 01 a7|a7 01 f7 7f) mtvrwa v31,r23
+ 1c4: (7e 1a 01 e6|e6 01 1a 7e) mtfprwz f16,r26
+ 1c8: (7d b3 6c 18|18 6c b3 7d) lxsspx vs13,r19,r13
+ 1cc: (7e 40 6c 18|18 6c 40 7e) lxsspx vs18,0,r13
+ 1d0: (7d 62 25 19|19 25 62 7d) stxsspx vs43,r2,r4
+ 1d4: (7e e0 5d 19|19 5d e0 7e) stxsspx vs55,0,r11
+ 1d8: (f2 d0 c8 05|05 c8 d0 f2) xsaddsp vs54,vs48,vs25
+ 1dc: (f1 d2 08 0c|0c 08 d2 f1) xsmaddasp vs14,vs50,vs1
+ 1e0: (f3 56 50 42|42 50 56 f3) xssubsp vs26,vs22,vs42
+ 1e4: (f3 75 a0 4e|4e a0 75 f3) xsmaddmsp vs27,vs53,vs52
+ 1e8: (f1 00 d8 2a|2a d8 00 f1) xsrsqrtesp vs8,vs59
+ 1ec: (f1 80 48 2e|2e 48 80 f1) xssqrtsp vs12,vs41
+ 1f0: (f3 2b 00 83|83 00 2b f3) xsmulsp vs57,vs11,vs32
+ 1f4: (f0 d4 d0 89|89 d0 d4 f0) xsmsubasp vs38,vs20,vs26
+ 1f8: (f3 53 30 c0|c0 30 53 f3) xsdivsp vs26,vs19,vs6
+ 1fc: (f0 65 b8 cf|cf b8 65 f0) xsmsubmsp vs35,vs37,vs55
+ 200: (f3 60 40 69|69 40 60 f3) xsresp vs59,vs8
+ 204: (f1 81 0c 0f|0f 0c 81 f1) xsnmaddasp vs44,vs33,vs33
+ 208: (f2 3e f4 4c|4c f4 3e f2) xsnmaddmsp vs17,vs62,vs30
+ 20c: (f2 d4 fc 8d|8d fc d4 f2) xsnmsubasp vs54,vs52,vs31
+ 210: (f0 a5 d4 cb|cb d4 a5 f0) xsnmsubmsp vs37,vs5,vs58
+ 214: (f3 d6 65 56|56 65 d6 f3) xxlorc vs30,vs54,vs44
+ 218: (f2 2e ed 91|91 ed 2e f2) xxlnand vs49,vs14,vs29
+ 21c: (f3 d6 f5 d1|d1 f5 d6 f3) xxleqv vs62,vs22,vs30
+ 220: (f3 80 b4 2f|2f b4 80 f3) xscvdpspn vs60,vs54
+ 224: (f2 c0 6c 66|66 6c c0 f2) xsrsp vs22,vs45
+ 228: (f3 40 dc a2|a2 dc 40 f3) xscvuxdsp vs26,vs59
+ 22c: (f0 c0 8c e3|e3 8c c0 f0) xscvsxdsp vs38,vs49
+ 230: (f3 60 d5 2d|2d d5 60 f3) xscvspdpn vs59,vs26
+ 234: (ff 0e 16 8c|8c 16 0e ff) fmrgow f24,f14,f2
+ 238: (fe c7 2f 8c|8c 2f c7 fe) fmrgew f22,f7,f5
+#pass
diff --git a/gas/testsuite/gas/ppc/power8.s b/gas/testsuite/gas/ppc/power8.s
index 7b4a28eaa..8df4f6b20 100644
--- a/gas/testsuite/gas/ppc/power8.s
+++ b/gas/testsuite/gas/ppc/power8.s
@@ -19,3 +19,126 @@ power8:
tresume.
ori 2,2,0
.p2align 4,,15
+ rfebb 0
+ rfebb
+ rfebb 1
+ bctar- 12,21
+ bctarl- 4,7
+ bctar+ 12,12
+ bctarl+ 4,2
+ bctar 4,8,1
+ bctarl 4,7,2
+ waitasec
+ msgsndp 8
+ mtsle 1
+ msgclrp 27
+ stqcx. 10,10,12
+ stqcx. 28,0,7
+ lqarx 24,19,11,0
+ lqarx 22,0,11,0
+ mfbhrbe 20,6
+ pbt. 29,17,16
+ pbt. 14,0,7
+ clrbhrb
+ vpermxor 11,10,0,23
+ vaddeuqm 24,2,7,4
+ vaddecuq 10,10,8,2
+ vsubeuqm 5,15,8,19
+ vsubecuq 12,31,16,29
+ vmulouw 20,29,13
+ vmuluwm 29,0,26
+ vaddudm 8,21,28
+ vmaxud 1,26,1
+ vrld 20,3,1
+ vcmpequd 4,19,11
+ vadduqm 23,14,30
+ vaddcuq 8,8,13
+ vmulosw 28,27,4
+ vmaxsd 3,4,4
+ vmuleuw 0,19,21
+ vminud 24,20,19
+ vcmpgtud 0,28,15
+ vmulesw 21,0,2
+ vminsd 9,26,9
+ vsrad 25,29,11
+ vcmpgtsd 11,28,11
+ bcdadd. 5,8,26,1
+ vpmsumb 4,3,12
+ bcdsub. 26,31,21,1
+ vpmsumh 5,17,16
+ vpkudum 23,17,20
+ vpmsumw 24,21,29
+ vpmsumd 9,22,13
+ vpkudus 18,19,18
+ vsubuqm 30,16,22
+ vcipher 14,11,7
+ vcipherlast 10,2,22
+ vgbbd 23,13
+ vsubcuq 16,25,16
+ vorc 31,1,5
+ vncipher 4,17,31
+ vncipherlast 24,2,27
+ vbpermq 23,21,23
+ vpksdus 27,18,9
+ vnand 27,29,27
+ vsld 19,19,24
+ vsbox 5,13
+ vpksdss 25,3,7
+ vcmpequd. 28,8,0
+ vupkhsw 26,26
+ vshasigmaw 5,7,0,6
+ veqv 28,21,14
+ vmrgow 1,8,19
+ vshasigmad 0,10,0,10
+ vsrd 5,27,14
+ vupklsw 11,13
+ vclzb 14,16
+ vpopcntb 20,27
+ vclzh 28,11
+ vpopcnth 24,9
+ vclzw 27,31
+ vpopcntw 17,19
+ vclzd 12,29
+ vpopcntd 23,22
+ vcmpgtud. 24,20,29
+ vcmpgtsd. 9,6,27
+ lxsiwzx 62,14,26
+ lxsiwzx 40,0,25
+ lxsiwax 25,0,26
+ lxsiwax 3,0,3
+ mfvsrd 12,62
+ mfvsrwz 20,12
+ stxsiwx 14,9,14
+ stxsiwx 21,0,8
+ mtvsrd 48,11
+ mtvsrwa 63,23
+ mtvsrwz 16,26
+ lxsspx 13,19,13
+ lxsspx 18,0,13
+ stxsspx 43,2,4
+ stxsspx 55,0,11
+ xsaddsp 54,48,25
+ xsmaddasp 14,50,1
+ xssubsp 26,22,42
+ xsmaddmsp 27,53,52
+ xsrsqrtesp 8,59
+ xssqrtsp 12,41
+ xsmulsp 57,11,32
+ xsmsubasp 38,20,26
+ xsdivsp 26,19,6
+ xsmsubmsp 35,37,55
+ xsresp 59,8
+ xsnmaddasp 44,33,33
+ xsnmaddmsp 17,62,30
+ xsnmsubasp 54,52,31
+ xsnmsubmsp 37,5,58
+ xxlorc 30,54,44
+ xxlnand 49,14,29
+ xxleqv 62,22,30
+ xscvdpspn 60,54
+ xsrsp 22,45
+ xscvuxdsp 26,59
+ xscvsxdsp 38,49
+ xscvspdpn 59,26
+ fmrgow 24,14,2
+ fmrgew 22,7,5
diff --git a/gas/testsuite/gas/ppc/ppc.exp b/gas/testsuite/gas/ppc/ppc.exp
index b7f56b0be..fec714cbf 100644
--- a/gas/testsuite/gas/ppc/ppc.exp
+++ b/gas/testsuite/gas/ppc/ppc.exp
@@ -44,7 +44,6 @@ if { [istarget powerpc64*-*-*] || [istarget *-*-elf64*]} then {
}
if { [istarget powerpc*-*-*] } then {
- run_dump_test "simpshft"
run_dump_test "regnames"
if { [is_elf_format] } then {
run_dump_test "machine"
@@ -67,6 +66,7 @@ if { [istarget powerpc*-*-*] } then {
run_dump_test "altivec_xcoff"
run_dump_test "altivec_xcoff64"
} else {
+ run_dump_test "simpshft"
run_dump_test "altivec"
run_dump_test "altivec2"
run_dump_test "altivec_and_spe"
@@ -85,6 +85,7 @@ if { [istarget powerpc*-*-*] } then {
run_dump_test "power7"
run_dump_test "power8"
run_dump_test "vsx"
+ run_dump_test "vsx2"
run_dump_test "htm"
run_dump_test "titan"
}
diff --git a/gas/testsuite/gas/ppc/vsx.d b/gas/testsuite/gas/ppc/vsx.d
index 7ce57dace..f5a6a1478 100644
--- a/gas/testsuite/gas/ppc/vsx.d
+++ b/gas/testsuite/gas/ppc/vsx.d
@@ -166,3 +166,8 @@ Disassembly of section \.text:
26c: (f1 12 e7 bf|bf e7 12 f1) xxsel vs40,vs50,vs60,vs62
270: (f1 12 e2 17|17 e2 12 f1) xxsldwi vs40,vs50,vs60,2
274: (f1 02 e2 93|93 e2 02 f1) xxspltw vs40,vs60,2
+ 278: (7d 00 a6 99|99 a6 00 7d) lxvd2x vs40,0,r20
+ 27c: (7d 0a a6 99|99 a6 0a 7d) lxvd2x vs40,r10,r20
+ 280: (7d 00 a7 99|99 a7 00 7d) stxvd2x vs40,0,r20
+ 284: (7d 0a a7 99|99 a7 0a 7d) stxvd2x vs40,r10,r20
+#pass
diff --git a/gas/testsuite/gas/ppc/vsx.s b/gas/testsuite/gas/ppc/vsx.s
index 6927ee175..bcc9c2d3a 100644
--- a/gas/testsuite/gas/ppc/vsx.s
+++ b/gas/testsuite/gas/ppc/vsx.s
@@ -158,3 +158,7 @@ start:
xxsel 40,50,60,62
xxsldwi 40,50,60,2
xxspltw 40,60,2
+ lxvx 40,0,20
+ lxvx 40,10,20
+ stxvx 40,0,20
+ stxvx 40,10,20
diff --git a/gas/testsuite/gas/ppc/vsx2.d b/gas/testsuite/gas/ppc/vsx2.d
new file mode 100644
index 000000000..04e42941b
--- /dev/null
+++ b/gas/testsuite/gas/ppc/vsx2.d
@@ -0,0 +1,65 @@
+#as: -mvsx
+#objdump: -dr -Mvsx
+#name: VSX ISA 2.07 instructions
+
+.*
+
+Disassembly of section \.text:
+
+0+00 <vsx2>:
+ 0: (7f ce d0 19|19 d0 ce 7f) lxsiwzx vs62,r14,r26
+ 4: (7d 00 c8 19|19 c8 00 7d) lxsiwzx vs40,0,r25
+ 8: (7f 20 d0 98|98 d0 20 7f) lxsiwax vs25,0,r26
+ c: (7c 60 18 98|98 18 60 7c) lxsiwax vs3,0,r3
+ 10: (7f cc 00 66|66 00 cc 7f) mfvsrd r12,vs30
+ 14: (7f cc 00 66|66 00 cc 7f) mfvsrd r12,vs30
+ 18: (7f cc 00 67|67 00 cc 7f) mfvsrd r12,vs62
+ 1c: (7f cc 00 67|67 00 cc 7f) mfvsrd r12,vs62
+ 20: (7d 94 00 e6|e6 00 94 7d) mffprwz r20,f12
+ 24: (7d 94 00 e6|e6 00 94 7d) mffprwz r20,f12
+ 28: (7d 95 00 e7|e7 00 95 7d) mfvrwz r21,v12
+ 2c: (7d 95 00 e7|e7 00 95 7d) mfvrwz r21,v12
+ 30: (7d c9 71 18|18 71 c9 7d) stxsiwx vs14,r9,r14
+ 34: (7e a0 41 18|18 41 a0 7e) stxsiwx vs21,0,r8
+ 38: (7d 7c 01 66|66 01 7c 7d) mtvsrd vs11,r28
+ 3c: (7d 7c 01 66|66 01 7c 7d) mtvsrd vs11,r28
+ 40: (7d 7d 01 67|67 01 7d 7d) mtvsrd vs43,r29
+ 44: (7d 7d 01 67|67 01 7d 7d) mtvsrd vs43,r29
+ 48: (7f 16 01 a6|a6 01 16 7f) mtfprwa f24,r22
+ 4c: (7f 16 01 a6|a6 01 16 7f) mtfprwa f24,r22
+ 50: (7f 37 01 a7|a7 01 37 7f) mtvrwa v25,r23
+ 54: (7f 37 01 a7|a7 01 37 7f) mtvrwa v25,r23
+ 58: (7f 5b 01 e6|e6 01 5b 7f) mtfprwz f26,r27
+ 5c: (7f 5b 01 e6|e6 01 5b 7f) mtfprwz f26,r27
+ 60: (7f 7c 01 e7|e7 01 7c 7f) mtvrwz v27,r28
+ 64: (7f 7c 01 e7|e7 01 7c 7f) mtvrwz v27,r28
+ 68: (7d b3 6c 18|18 6c b3 7d) lxsspx vs13,r19,r13
+ 6c: (7e 40 6c 18|18 6c 40 7e) lxsspx vs18,0,r13
+ 70: (7d 62 25 19|19 25 62 7d) stxsspx vs43,r2,r4
+ 74: (7e e0 5d 19|19 5d e0 7e) stxsspx vs55,0,r11
+ 78: (f2 d0 c8 05|05 c8 d0 f2) xsaddsp vs54,vs48,vs25
+ 7c: (f1 d2 08 0c|0c 08 d2 f1) xsmaddasp vs14,vs50,vs1
+ 80: (f3 56 50 42|42 50 56 f3) xssubsp vs26,vs22,vs42
+ 84: (f3 75 a0 4e|4e a0 75 f3) xsmaddmsp vs27,vs53,vs52
+ 88: (f1 00 d8 2a|2a d8 00 f1) xsrsqrtesp vs8,vs59
+ 8c: (f1 80 48 2e|2e 48 80 f1) xssqrtsp vs12,vs41
+ 90: (f3 2b 00 83|83 00 2b f3) xsmulsp vs57,vs11,vs32
+ 94: (f0 d4 d0 89|89 d0 d4 f0) xsmsubasp vs38,vs20,vs26
+ 98: (f3 53 30 c0|c0 30 53 f3) xsdivsp vs26,vs19,vs6
+ 9c: (f0 65 b8 cf|cf b8 65 f0) xsmsubmsp vs35,vs37,vs55
+ a0: (f3 60 40 69|69 40 60 f3) xsresp vs59,vs8
+ a4: (f1 81 0c 0f|0f 0c 81 f1) xsnmaddasp vs44,vs33,vs33
+ a8: (f2 3e f4 4c|4c f4 3e f2) xsnmaddmsp vs17,vs62,vs30
+ ac: (f2 d4 fc 8d|8d fc d4 f2) xsnmsubasp vs54,vs52,vs31
+ b0: (f0 a5 d4 cb|cb d4 a5 f0) xsnmsubmsp vs37,vs5,vs58
+ b4: (f3 d6 65 56|56 65 d6 f3) xxlorc vs30,vs54,vs44
+ b8: (f2 2e ed 91|91 ed 2e f2) xxlnand vs49,vs14,vs29
+ bc: (f3 d6 f5 d1|d1 f5 d6 f3) xxleqv vs62,vs22,vs30
+ c0: (f3 80 b4 2f|2f b4 80 f3) xscvdpspn vs60,vs54
+ c4: (f2 c0 6c 66|66 6c c0 f2) xsrsp vs22,vs45
+ c8: (f3 40 dc a2|a2 dc 40 f3) xscvuxdsp vs26,vs59
+ cc: (f0 c0 8c e3|e3 8c c0 f0) xscvsxdsp vs38,vs49
+ d0: (f3 60 d5 2d|2d d5 60 f3) xscvspdpn vs59,vs26
+ d4: (ff 0e 16 8c|8c 16 0e ff) fmrgow f24,f14,f2
+ d8: (fe c7 2f 8c|8c 2f c7 fe) fmrgew f22,f7,f5
+#pass
diff --git a/gas/testsuite/gas/ppc/vsx2.s b/gas/testsuite/gas/ppc/vsx2.s
new file mode 100644
index 000000000..624614d5b
--- /dev/null
+++ b/gas/testsuite/gas/ppc/vsx2.s
@@ -0,0 +1,57 @@
+ .text
+vsx2:
+ lxsiwzx 62,14,26
+ lxsiwzx 40,0,25
+ lxsiwax 25,0,26
+ lxsiwax 3,0,3
+ mfvsrd 12,30
+ mffprd 12,30
+ mfvsrd 12,62
+ mfvrd 12,30
+ mfvsrwz 20,12
+ mffprwz 20,12
+ mfvsrwz 21,44
+ mfvrwz 21,12
+ stxsiwx 14,9,14
+ stxsiwx 21,0,8
+ mtvsrd 11,28
+ mtfprd 11,28
+ mtvsrd 43,29
+ mtvrd 11,29
+ mtvsrwa 24,22
+ mtfprwa 24,22
+ mtvsrwa 57,23
+ mtvrwa 25,23
+ mtvsrwz 26,27
+ mtfprwz 26,27
+ mtvsrwz 59,28
+ mtvrwz 27,28
+ lxsspx 13,19,13
+ lxsspx 18,0,13
+ stxsspx 43,2,4
+ stxsspx 55,0,11
+ xsaddsp 54,48,25
+ xsmaddasp 14,50,1
+ xssubsp 26,22,42
+ xsmaddmsp 27,53,52
+ xsrsqrtesp 8,59
+ xssqrtsp 12,41
+ xsmulsp 57,11,32
+ xsmsubasp 38,20,26
+ xsdivsp 26,19,6
+ xsmsubmsp 35,37,55
+ xsresp 59,8
+ xsnmaddasp 44,33,33
+ xsnmaddmsp 17,62,30
+ xsnmsubasp 54,52,31
+ xsnmsubmsp 37,5,58
+ xxlorc 30,54,44
+ xxlnand 49,14,29
+ xxleqv 62,22,30
+ xscvdpspn 60,54
+ xsrsp 22,45
+ xscvuxdsp 26,59
+ xscvsxdsp 38,49
+ xscvspdpn 59,26
+ fmrgow 24,14,2
+ fmrgew 22,7,5
diff --git a/gas/testsuite/gas/s390/zarch-zEC12.d b/gas/testsuite/gas/s390/zarch-zEC12.d
index 829e4d3d2..25424c915 100644
--- a/gas/testsuite/gas/s390/zarch-zEC12.d
+++ b/gas/testsuite/gas/s390/zarch-zEC12.d
@@ -47,10 +47,10 @@ Disassembly of section .text:
.*: eb 6c 7a 4d fe 2b [ ]*clgtnh %r6,-5555\(%r7\)
.*: eb 6c 7a 4d fe 2b [ ]*clgtnh %r6,-5555\(%r7\)
.*: ec 67 0c 0d 0e 59 [ ]*risbgn %r6,%r7,12,13,14
-.*: ed 90 8f a0 6d aa [ ]*cdzt %f6,4000\(10,%r8\),13
-.*: ed 90 8f a0 4d ab [ ]*cxzt %f4,4000\(10,%r8\),13
-.*: ed 90 8f a0 6d a8 [ ]*czdt %f6,4000\(10,%r8\),13
-.*: ed 90 8f a0 4d a9 [ ]*czxt %f4,4000\(10,%r8\),13
+.*: ed 0f 8f a0 6d aa [ ]*cdzt %f6,4000\(16,%r8\),13
+.*: ed 21 8f a0 4d ab [ ]*cxzt %f4,4000\(34,%r8\),13
+.*: ed 0f 8f a0 6d a8 [ ]*czdt %f6,4000\(16,%r8\),13
+.*: ed 21 8f a0 4d a9 [ ]*czxt %f4,4000\(34,%r8\),13
.*: b2 e8 c0 56 [ ]*ppa %r5,%r6,12
.*: b9 8f 60 59 [ ]*crdte %r5,%r6,%r9,0
.*: b9 8f 61 59 [ ]*crdte %r5,%r6,%r9,1
diff --git a/gas/testsuite/gas/s390/zarch-zEC12.s b/gas/testsuite/gas/s390/zarch-zEC12.s
index d1c58cd41..a5ece0f9f 100644
--- a/gas/testsuite/gas/s390/zarch-zEC12.s
+++ b/gas/testsuite/gas/s390/zarch-zEC12.s
@@ -44,10 +44,10 @@ foo:
clgtnh %r6,-5555(%r7)
risbgn %r6,%r7,12,13,14
- cdzt %f6,4000(10,%r8),13
- cxzt %f4,4000(10,%r8),13
- czdt %f6,4000(10,%r8),13
- czxt %f4,4000(10,%r8),13
+ cdzt %f6,4000(16,%r8),13
+ cxzt %f4,4000(34,%r8),13
+ czdt %f6,4000(16,%r8),13
+ czxt %f4,4000(34,%r8),13
ppa %r5,%r6,12
crdte %r5,%r6,%r9
diff --git a/gold/ChangeLog b/gold/ChangeLog
index 97d2e3554..d53df062e 100644
--- a/gold/ChangeLog
+++ b/gold/ChangeLog
@@ -1,3 +1,88 @@
+2013-05-21 Cary Coutant <ccoutant@google.com>
+
+ * symtab.h (Symbol::is_cxx_vtable): New function.
+ * target-reloc.h (relocate_section): Check for vtable symbol.
+ * testsuite/Makefile.am (missing_key_func.sh): New test case.
+ * testsuite/Makefile.in: Regenerate.
+ * testsuite/missing_key_func.cc: New test source.
+ * testsuite/missing_key_func.sh: New test script.
+
+2013-05-21 Cary Coutant <ccoutant@google.com>
+
+ * object.cc (Sized_relobj_file::get_symbol_location_info): Set
+ type of enclosing symbol.
+ (Relocate_info::location): Check symbol type when describing symbol.
+ * object.h (Symbol_location_info): Remove unused line_number;
+ add enclosing_symbol_type.
+ * testsuite/debug_msg.sh: Adjust expected output.
+
+2013-05-13 Cary Coutant <ccoutant@google.com>
+
+ * configure.ac: Export DEFAULT_TARGET.
+ * configure: Regenerate.
+ * Makefile.in: Regenerate.
+ * testsuite/Makefile.am: Add .EXPORT_ALL_VARIABLES.
+ * testsuite/Makefile.in: Regenerate.
+ * testsuite/debug_msg.sh: Delete duplicate tests.
+ Don't check undef_int error message match for powerpc where the
+ source file and line number aren't available.
+
+2013-05-10 Roland McGrath <mcgrathr@google.com>
+
+ * options.h (General_options): Add --rosegment-gap option.
+ * options.cc (finalize): --rosegment-gap implies --rosegment.
+ * layout.cc (set_segment_offsets): Let user option override
+ target->rosegment_gap().
+
+2013-05-10 Roland McGrath <mcgrathr@google.com>
+
+ * options.h (General_options): Remove leading space from help
+ messages for -nostdlib and --rosegment.
+
+2013-05-03 Maciej W. Rozycki <macro@codesourcery.com>
+
+ PR ld/15365
+ * layout.cc (Layout::finalize): Make __ehdr_start STV_HIDDEN.
+
+2013-05-03 Alan Modra <amodra@gmail.com>
+
+ * merge.cc (Output_merge_string::do_add_input_section): Correct
+ scan for number of strings. Rename vars to avoid shadowing.
+ Include missing terminator in input_size_.
+
+2013-05-01 H.J. Lu <hongjiu.lu@intel.com>
+
+ * merge.cc (Output_merge_string<Char_type>::do_add_input_section):
+ Restore empty string handling.
+
+2013-05-01 Cary Coutant <ccoutant@google.com>
+
+ * stringpool.cc (Stringpool_template::new_key_offset): Fix
+ uninitialized warning.
+
+2013-04-29 Alexander Ivchenko <alexander.ivchenko@intel.com>
+
+ * output.cc (Output_section::add_merge_input_section): Allow
+ to merge sections if the alignment is more than character size.
+ * merge.h (Output_merge_string::Output_merge_string): Remove
+ assert.
+ * merge.cc (Output_merge_string<Char_type>::do_add_input_section): Count
+ only not-null strings. Check the alignment of strings.
+ * stringpool.h
+ (Stringpool_template<Stringpool_char>::Stringpool_template): Add
+ alignment as the argument.
+ (Stringpool_template<Stringpool_char>::addralign_): New class member.
+ * stringpool.cc (Stringpool_template<Stringpool_char>::new_key_offset):
+ Align non-zero length strings according to the addralign_.
+ (Stringpool_template<Stringpool_char>::set_string_offsets):
+ Updating offsets according to the given alignment.
+ * testsuite/Makefile.am (text_section_grouping): Test if string
+ literals are getting merged.
+ * testsuite/Makefile.in: Regenerate.
+ * testsuite/merge_string_literals_1.c: New file.
+ * testsuite/merge_string_literals_2.c: Ditto.
+ * testsuite/merge_string_literals.sh: Ditto.
+
2013-04-26 Ian Lance Taylor <iant@google.com>
* target-reloc.h (relocate_section): If the reloc offset is out of
@@ -14758,7 +14843,7 @@
* Added source code to GNU binutils.
-Copyright (C) 2008-2012 Free Software Foundation, Inc.
+Copyright (C) 2008-2013 Free Software Foundation, Inc.
Copying and distribution of this file, with or without modification,
are permitted in any medium without royalty provided the copyright
diff --git a/gold/Makefile.in b/gold/Makefile.in
index 5c4c4d6f7..09de14ca5 100644
--- a/gold/Makefile.in
+++ b/gold/Makefile.in
@@ -288,6 +288,7 @@ CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DATADIRNAME = @DATADIRNAME@
+DEFAULT_TARGET = @DEFAULT_TARGET@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLOPEN_LIBS = @DLOPEN_LIBS@
diff --git a/gold/configure b/gold/configure
index 7e58cdfd5..cb56b651c 100755
--- a/gold/configure
+++ b/gold/configure
@@ -680,6 +680,7 @@ CFLAGS
CC
NM
TARGETOBJS
+DEFAULT_TARGET
DEFAULT_TARGET_TILEGX_FALSE
DEFAULT_TARGET_TILEGX_TRUE
DEFAULT_TARGET_X86_64_FALSE
@@ -3475,6 +3476,8 @@ else
DEFAULT_TARGET_TILEGX_FALSE=
fi
+ DEFAULT_TARGET=${targ_obj}
+
fi
fi
fi
diff --git a/gold/configure.ac b/gold/configure.ac
index b03c09de0..e3e10b3db 100644
--- a/gold/configure.ac
+++ b/gold/configure.ac
@@ -206,6 +206,8 @@ for targ in $target $canon_targets; do
AM_CONDITIONAL(DEFAULT_TARGET_SPARC, test "$targ_obj" = "sparc")
AM_CONDITIONAL(DEFAULT_TARGET_X86_64, test "$targ_obj" = "x86_64")
AM_CONDITIONAL(DEFAULT_TARGET_TILEGX, test "$targ_obj" = "tilegx")
+ DEFAULT_TARGET=${targ_obj}
+ AC_SUBST(DEFAULT_TARGET)
fi
fi
fi
diff --git a/gold/layout.cc b/gold/layout.cc
index b593acdb0..33fa473c1 100644
--- a/gold/layout.cc
+++ b/gold/layout.cc
@@ -1,6 +1,6 @@
// layout.cc -- lay out output file sections for gold
-// Copyright 2006, 2007, 2008, 2009, 2010, 2011, 2012
+// Copyright 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
// Free Software Foundation, Inc.
// Written by Ian Lance Taylor <iant@google.com>.
@@ -244,10 +244,10 @@ class Hash_task : public Task
{
public:
Hash_task(const unsigned char* src,
- size_t size,
- unsigned char* dst,
- Task_token* build_id_blocker,
- Task_token* final_blocker)
+ size_t size,
+ unsigned char* dst,
+ Task_token* build_id_blocker,
+ Task_token* final_blocker)
: src_(src), size_(size), dst_(dst), build_id_blocker_(build_id_blocker),
final_blocker_(final_blocker)
{ }
@@ -1098,7 +1098,7 @@ Layout::special_ordering_of_input_section(const char* name)
// wind up in the .text section. Sections that start with these
// prefixes must appear first, and must appear in the order listed
// here.
- static const char* const text_section_sort[] =
+ static const char* const text_section_sort[] =
{
".text.unlikely",
".text.exit",
@@ -1158,7 +1158,7 @@ Layout::layout(Sized_relobj_file<size, big_endian>* object, unsigned int shndx,
= this->section_segment_map_.find(Const_section_id(object, shndx));
if (it == this->section_segment_map_.end())
{
- os = this->choose_output_section(object, name, sh_type,
+ os = this->choose_output_section(object, name, sh_type,
shdr.get_sh_flags(), true,
ORDER_INVALID, false);
}
@@ -1254,7 +1254,7 @@ void
Layout::insert_section_segment_map(Const_section_id secn,
Unique_segment_info *s)
{
- gold_assert(this->unique_segment_for_sections_specified_);
+ gold_assert(this->unique_segment_for_sections_specified_);
this->section_segment_map_[secn] = s;
}
@@ -1890,44 +1890,44 @@ Layout::attach_allocated_section_to_segment(const Target* target,
if (!os->is_unique_segment())
{
for (p = this->segment_list_.begin();
- p != this->segment_list_.end();
+ p != this->segment_list_.end();
++p)
{
- if ((*p)->type() != elfcpp::PT_LOAD)
- continue;
- if ((*p)->is_unique_segment())
- continue;
- if (!parameters->options().omagic()
- && ((*p)->flags() & elfcpp::PF_W) != (seg_flags & elfcpp::PF_W))
- continue;
- if ((target->isolate_execinstr() || parameters->options().rosegment())
- && ((*p)->flags() & elfcpp::PF_X) != (seg_flags & elfcpp::PF_X))
- continue;
- // If -Tbss was specified, we need to separate the data and BSS
- // segments.
- if (parameters->options().user_set_Tbss())
- {
- if ((os->type() == elfcpp::SHT_NOBITS)
- == (*p)->has_any_data_sections())
- continue;
- }
- if (os->is_large_data_section() && !(*p)->is_large_data_segment())
- continue;
-
- if (is_address_set)
- {
- if ((*p)->are_addresses_set())
- continue;
-
- (*p)->add_initial_output_data(os);
- (*p)->update_flags_for_output_section(seg_flags);
- (*p)->set_addresses(addr, addr);
- break;
- }
-
- (*p)->add_output_section_to_load(this, os, seg_flags);
- break;
- }
+ if ((*p)->type() != elfcpp::PT_LOAD)
+ continue;
+ if ((*p)->is_unique_segment())
+ continue;
+ if (!parameters->options().omagic()
+ && ((*p)->flags() & elfcpp::PF_W) != (seg_flags & elfcpp::PF_W))
+ continue;
+ if ((target->isolate_execinstr() || parameters->options().rosegment())
+ && ((*p)->flags() & elfcpp::PF_X) != (seg_flags & elfcpp::PF_X))
+ continue;
+ // If -Tbss was specified, we need to separate the data and BSS
+ // segments.
+ if (parameters->options().user_set_Tbss())
+ {
+ if ((os->type() == elfcpp::SHT_NOBITS)
+ == (*p)->has_any_data_sections())
+ continue;
+ }
+ if (os->is_large_data_section() && !(*p)->is_large_data_segment())
+ continue;
+
+ if (is_address_set)
+ {
+ if ((*p)->are_addresses_set())
+ continue;
+
+ (*p)->add_initial_output_data(os);
+ (*p)->update_flags_for_output_section(seg_flags);
+ (*p)->set_addresses(addr, addr);
+ break;
+ }
+
+ (*p)->add_output_section_to_load(this, os, seg_flags);
+ break;
+ }
}
if (p == this->segment_list_.end()
@@ -2713,7 +2713,7 @@ Layout::finalize(const Input_objects* input_objects, Symbol_table* symtab,
symtab->define_in_output_segment("__ehdr_start", NULL,
Symbol_table::PREDEFINED, load_seg, 0, 0,
elfcpp::STT_NOTYPE, elfcpp::STB_GLOBAL,
- elfcpp::STV_DEFAULT, 0,
+ elfcpp::STV_HIDDEN, 0,
Symbol::SEGMENT_START, true);
// Set the file offsets of all the non-data sections we've seen so
@@ -3457,7 +3457,10 @@ Layout::set_segment_offsets(const Target* target, Output_segment* load_seg,
// If the target wants a fixed minimum distance from the
// text segment to the read-only segment, move up now.
- uint64_t min_addr = start_addr + target->rosegment_gap();
+ uint64_t min_addr =
+ start_addr + (parameters->options().user_set_rosegment_gap()
+ ? parameters->options().rosegment_gap()
+ : target->rosegment_gap());
if (addr < min_addr)
addr = min_addr;
@@ -5270,20 +5273,20 @@ Layout::write_sections_after_input_sections(Output_file* of)
Task_token*
Layout::queue_build_id_tasks(Workqueue* workqueue, Task_token* build_id_blocker,
- Output_file* of)
+ Output_file* of)
{
const size_t filesize = (this->output_file_size() <= 0 ? 0
- : static_cast<size_t>(this->output_file_size()));
+ : static_cast<size_t>(this->output_file_size()));
if (this->build_id_note_ != NULL
&& strcmp(parameters->options().build_id(), "tree") == 0
&& parameters->options().build_id_chunk_size_for_treehash() > 0
&& filesize > 0
&& (filesize >=
- parameters->options().build_id_min_file_size_for_treehash()))
+ parameters->options().build_id_min_file_size_for_treehash()))
{
static const size_t MD5_OUTPUT_SIZE_IN_BYTES = 16;
const size_t chunk_size =
- parameters->options().build_id_chunk_size_for_treehash();
+ parameters->options().build_id_chunk_size_for_treehash();
const size_t num_hashes = ((filesize - 1) / chunk_size) + 1;
Task_token* post_hash_tasks_blocker = new Task_token(true);
post_hash_tasks_blocker->add_blockers(num_hashes);
@@ -5293,15 +5296,15 @@ Layout::queue_build_id_tasks(Workqueue* workqueue, Task_token* build_id_blocker,
unsigned char *dst = new unsigned char[this->size_of_array_of_hashes_];
this->array_of_hashes_ = dst;
for (size_t i = 0, src_offset = 0; i < num_hashes;
- i++, dst += MD5_OUTPUT_SIZE_IN_BYTES, src_offset += chunk_size)
- {
- size_t size = std::min(chunk_size, filesize - src_offset);
- workqueue->queue(new Hash_task(src + src_offset,
- size,
- dst,
- build_id_blocker,
- post_hash_tasks_blocker));
- }
+ i++, dst += MD5_OUTPUT_SIZE_IN_BYTES, src_offset += chunk_size)
+ {
+ size_t size = std::min(chunk_size, filesize - src_offset);
+ workqueue->queue(new Hash_task(src + src_offset,
+ size,
+ dst,
+ build_id_blocker,
+ post_hash_tasks_blocker));
+ }
return post_hash_tasks_blocker;
}
return build_id_blocker;
@@ -5318,7 +5321,7 @@ Layout::write_build_id(Output_file* of) const
return;
unsigned char* ov = of->get_output_view(this->build_id_note_->offset(),
- this->build_id_note_->data_size());
+ this->build_id_note_->data_size());
if (this->array_of_hashes_ == NULL)
{
@@ -5329,11 +5332,11 @@ Layout::write_build_id(Output_file* of) const
// If we get here with style == "tree" then the output must be
// too small for chunking, and we use SHA-1 in that case.
if ((strcmp(style, "sha1") == 0) || (strcmp(style, "tree") == 0))
- sha1_buffer(reinterpret_cast<const char*>(iv), output_file_size, ov);
+ sha1_buffer(reinterpret_cast<const char*>(iv), output_file_size, ov);
else if (strcmp(style, "md5") == 0)
- md5_buffer(reinterpret_cast<const char*>(iv), output_file_size, ov);
+ md5_buffer(reinterpret_cast<const char*>(iv), output_file_size, ov);
else
- gold_unreachable();
+ gold_unreachable();
of->free_input_view(0, output_file_size, iv);
}
@@ -5342,7 +5345,7 @@ Layout::write_build_id(Output_file* of) const
// Non-overlapping substrings of the output file have been hashed.
// Compute SHA-1 hash of the hashes.
sha1_buffer(reinterpret_cast<const char*>(this->array_of_hashes_),
- this->size_of_array_of_hashes_, ov);
+ this->size_of_array_of_hashes_, ov);
delete[] this->array_of_hashes_;
of->free_input_view(0, this->output_file_size(), this->input_view_);
}
diff --git a/gold/merge.cc b/gold/merge.cc
index dde43e9b1..f370c9cb9 100644
--- a/gold/merge.cc
+++ b/gold/merge.cc
@@ -505,17 +505,17 @@ bool
Output_merge_string<Char_type>::do_add_input_section(Relobj* object,
unsigned int shndx)
{
- section_size_type len;
+ section_size_type sec_len;
bool is_new;
const unsigned char* pdata = object->decompressed_section_contents(shndx,
- &len,
+ &sec_len,
&is_new);
const Char_type* p = reinterpret_cast<const Char_type*>(pdata);
- const Char_type* pend = p + len / sizeof(Char_type);
+ const Char_type* pend = p + sec_len / sizeof(Char_type);
const Char_type* pend0 = pend;
- if (len % sizeof(Char_type) != 0)
+ if (sec_len % sizeof(Char_type) != 0)
{
object->error(_("mergeable string section length not multiple of "
"character size"));
@@ -540,25 +540,44 @@ Output_merge_string<Char_type>::do_add_input_section(Relobj* object,
this->merged_strings_lists_.push_back(merged_strings_list);
Merged_strings& merged_strings = merged_strings_list->merged_strings;
- // Count the number of strings in the section and size the list.
+ // Count the number of non-null strings in the section and size the list.
size_t count = 0;
- for (const Char_type* pt = p; pt < pend0; pt += string_length(pt) + 1)
- ++count;
+ const Char_type* pt = p;
+ while (pt < pend0)
+ {
+ size_t len = string_length(pt);
+ if (len != 0)
+ ++count;
+ pt += len + 1;
+ }
if (pend0 < pend)
++count;
merged_strings.reserve(count + 1);
// The index I is in bytes, not characters.
section_size_type i = 0;
+
+ // We assume here that the beginning of the section is correctly
+ // aligned, so each string within the section must retain the same
+ // modulo.
+ uintptr_t init_align_modulo = (reinterpret_cast<uintptr_t>(pdata)
+ & (this->addralign() - 1));
+ bool has_misaligned_strings = false;
+
while (p < pend0)
{
size_t len = string_length(p);
+ // Within merge input section each string must be aligned.
+ if (len != 0
+ && ((reinterpret_cast<uintptr_t>(p) & (this->addralign() - 1))
+ != init_align_modulo))
+ has_misaligned_strings = true;
+
Stringpool::Key key;
this->stringpool_.add_with_length(p, len, true, &key);
merged_strings.push_back(Merged_string(i, key));
-
p += len + 1;
i += (len + 1) * sizeof(Char_type);
}
@@ -579,7 +598,13 @@ Output_merge_string<Char_type>::do_add_input_section(Relobj* object,
merged_strings.push_back(Merged_string(i, 0));
this->input_count_ += count;
- this->input_size_ += len;
+ this->input_size_ += i;
+
+ if (has_misaligned_strings)
+ gold_warning(_("%s: section %s contains incorrectly aligned strings;"
+ " the alignment of those strings won't be preserved"),
+ object->name().c_str(),
+ object->section_name(shndx).c_str());
// For script processing, we keep the input sections.
if (this->keeps_input_sections())
diff --git a/gold/merge.h b/gold/merge.h
index 625d731c8..92c634a57 100644
--- a/gold/merge.h
+++ b/gold/merge.h
@@ -461,10 +461,9 @@ class Output_merge_string : public Output_merge_base
{
public:
Output_merge_string(uint64_t addralign)
- : Output_merge_base(sizeof(Char_type), addralign), stringpool_(),
+ : Output_merge_base(sizeof(Char_type), addralign), stringpool_(addralign),
merged_strings_lists_(), input_count_(0), input_size_(0)
{
- gold_assert(addralign <= sizeof(Char_type));
this->stringpool_.set_no_zero_null();
}
diff --git a/gold/object.cc b/gold/object.cc
index 715f7acd4..1f113d14f 100644
--- a/gold/object.cc
+++ b/gold/object.cc
@@ -1,6 +1,6 @@
// object.cc -- support for an object file for linking in gold
-// Copyright 2006, 2007, 2008, 2009, 2010, 2011, 2012
+// Copyright 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
// Free Software Foundation, Inc.
// Written by Ian Lance Taylor <iant@google.com>.
@@ -2687,6 +2687,7 @@ Sized_relobj_file<size, big_endian>::get_symbol_location_info(
&& (static_cast<off_t>(sym.get_st_value() + sym.get_st_size())
> offset))
{
+ info->enclosing_symbol_type = sym.get_st_type();
if (sym.get_st_name() > names_size)
info->enclosing_symbol_name = "(invalid)";
else
@@ -2996,12 +2997,10 @@ Relocate_info<size, big_endian>::location(size_t, off_t offset) const
ret += ":";
ret += info.source_file;
}
- size_t len = info.enclosing_symbol_name.length() + 100;
- char* buf = new char[len];
- snprintf(buf, len, _(":function %s"),
- info.enclosing_symbol_name.c_str());
- ret += buf;
- delete[] buf;
+ ret += ":";
+ if (info.enclosing_symbol_type == elfcpp::STT_FUNC)
+ ret += _("function ");
+ ret += info.enclosing_symbol_name;
return ret;
}
diff --git a/gold/object.h b/gold/object.h
index a2baecc0d..c17c13d28 100644
--- a/gold/object.h
+++ b/gold/object.h
@@ -1,6 +1,6 @@
// object.h -- support for an object file for linking in gold -*- C++ -*-
-// Copyright 2006, 2007, 2008, 2009, 2010, 2011, 2012
+// Copyright 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
// Free Software Foundation, Inc.
// Written by Ian Lance Taylor <iant@google.com>.
@@ -103,7 +103,7 @@ struct Symbol_location_info
{
std::string source_file;
std::string enclosing_symbol_name;
- int line_number;
+ elfcpp::STT enclosing_symbol_type;
};
// Data about a single relocation section. This is read in
diff --git a/gold/options.cc b/gold/options.cc
index 5b94faefa..000e6d07a 100644
--- a/gold/options.cc
+++ b/gold/options.cc
@@ -1,6 +1,7 @@
// options.c -- handle command line options for gold
-// Copyright 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+// Copyright 2006, 2007, 2008, 2009, 2010, 2011, 2013
+// Free Software Foundation, Inc.
// Written by Ian Lance Taylor <iant@google.com>.
// This file is part of gold.
@@ -101,11 +102,11 @@ One_option::print() const
{
len += printf("-%c", this->shortname);
if (this->helparg)
- {
- // -z takes long-names only.
- gold_assert(this->dashes != DASH_Z);
- len += printf(" %s", gettext(this->helparg));
- }
+ {
+ // -z takes long-names only.
+ gold_assert(this->dashes != DASH_Z);
+ len += printf(" %s", gettext(this->helparg));
+ }
comma = true;
}
if (!this->longname.empty()
@@ -113,29 +114,29 @@ One_option::print() const
&& this->longname[1] == '\0'))
{
if (comma)
- len += printf(", ");
+ len += printf(", ");
switch (this->dashes)
- {
- case options::ONE_DASH: case options::EXACTLY_ONE_DASH:
- len += printf("-");
- break;
- case options::TWO_DASHES: case options::EXACTLY_TWO_DASHES:
- len += printf("--");
- break;
- case options::DASH_Z:
- len += printf("-z ");
- break;
- default:
- gold_unreachable();
- }
+ {
+ case options::ONE_DASH: case options::EXACTLY_ONE_DASH:
+ len += printf("-");
+ break;
+ case options::TWO_DASHES: case options::EXACTLY_TWO_DASHES:
+ len += printf("--");
+ break;
+ case options::DASH_Z:
+ len += printf("-z ");
+ break;
+ default:
+ gold_unreachable();
+ }
len += printf("%s", this->longname.c_str());
if (this->helparg)
- {
- // For most options, we print "--frob FOO". But for -z
- // we print "-z frob=FOO".
- len += printf("%c%s", this->dashes == options::DASH_Z ? '=' : ' ',
- gettext(this->helparg));
- }
+ {
+ // For most options, we print "--frob FOO". But for -z
+ // we print "-z frob=FOO".
+ len += printf("%c%s", this->dashes == options::DASH_Z ? '=' : ' ',
+ gettext(this->helparg));
+ }
}
if (len >= 30)
@@ -200,7 +201,7 @@ parse_uint(const char* option_name, const char* arg, int* retval)
*retval = strtol(arg, &endptr, 0);
if (*endptr != '\0' || *retval < 0)
gold_fatal(_("%s: invalid option value (expected an integer): %s"),
- option_name, arg);
+ option_name, arg);
}
void
@@ -210,7 +211,7 @@ parse_int(const char* option_name, const char* arg, int* retval)
*retval = strtol(arg, &endptr, 0);
if (*endptr != '\0')
gold_fatal(_("%s: invalid option value (expected an integer): %s"),
- option_name, arg);
+ option_name, arg);
}
void
@@ -220,7 +221,7 @@ parse_uint64(const char* option_name, const char* arg, uint64_t* retval)
*retval = strtoull(arg, &endptr, 0);
if (*endptr != '\0')
gold_fatal(_("%s: invalid option value (expected an integer): %s"),
- option_name, arg);
+ option_name, arg);
}
void
@@ -273,13 +274,13 @@ parse_set(const char*, const char* arg, String_set* retval)
void
parse_choices(const char* option_name, const char* arg, const char** retval,
- const char* choices[], int num_choices)
+ const char* choices[], int num_choices)
{
for (int i = 0; i < num_choices; i++)
if (strcmp(choices[i], arg) == 0)
{
- *retval = arg;
- return;
+ *retval = arg;
+ return;
}
// If we get here, the user did not enter a valid choice, so we die.
@@ -288,10 +289,10 @@ parse_choices(const char* option_name, const char* arg, const char** retval,
{
choices_list += choices[i];
if (i != num_choices - 1)
- choices_list += ", ";
+ choices_list += ", ";
}
gold_fatal(_("%s: must take one of the following arguments: %s"),
- option_name, choices_list.c_str());
+ option_name, choices_list.c_str());
}
} // End namespace options.
@@ -340,21 +341,21 @@ General_options::parse_V(const char*, const char*, Command_line*)
void
General_options::parse_defsym(const char*, const char* arg,
- Command_line* cmdline)
+ Command_line* cmdline)
{
cmdline->script_options().define_symbol(arg);
}
void
General_options::parse_incremental(const char*, const char*,
- Command_line*)
+ Command_line*)
{
this->incremental_mode_ = INCREMENTAL_AUTO;
}
void
General_options::parse_no_incremental(const char*, const char*,
- Command_line*)
+ Command_line*)
{
this->incremental_mode_ = INCREMENTAL_OFF;
}
@@ -375,7 +376,7 @@ General_options::parse_incremental_update(const char*, const char*,
void
General_options::parse_incremental_changed(const char*, const char*,
- Command_line*)
+ Command_line*)
{
this->implicit_incremental_ = true;
this->incremental_disposition_ = INCREMENTAL_CHANGED;
@@ -383,7 +384,7 @@ General_options::parse_incremental_changed(const char*, const char*,
void
General_options::parse_incremental_unchanged(const char*, const char*,
- Command_line*)
+ Command_line*)
{
this->implicit_incremental_ = true;
this->incremental_disposition_ = INCREMENTAL_UNCHANGED;
@@ -391,7 +392,7 @@ General_options::parse_incremental_unchanged(const char*, const char*,
void
General_options::parse_incremental_unknown(const char*, const char*,
- Command_line*)
+ Command_line*)
{
this->implicit_incremental_ = true;
this->incremental_disposition_ = INCREMENTAL_CHECK;
@@ -407,7 +408,7 @@ General_options::parse_incremental_startup_unchanged(const char*, const char*,
void
General_options::parse_library(const char*, const char* arg,
- Command_line* cmdline)
+ Command_line* cmdline)
{
Input_file_argument::Input_file_type type;
const char* name;
@@ -428,7 +429,7 @@ General_options::parse_library(const char*, const char* arg,
#ifdef ENABLE_PLUGINS
void
General_options::parse_plugin(const char*, const char* arg,
- Command_line*)
+ Command_line*)
{
this->add_plugin(arg);
}
@@ -437,7 +438,7 @@ General_options::parse_plugin(const char*, const char* arg,
void
General_options::parse_plugin_opt(const char*, const char* arg,
- Command_line*)
+ Command_line*)
{
this->add_plugin_option(arg);
}
@@ -445,7 +446,7 @@ General_options::parse_plugin_opt(const char*, const char* arg,
void
General_options::parse_R(const char* option, const char* arg,
- Command_line* cmdline)
+ Command_line* cmdline)
{
struct stat s;
if (::stat(arg, &s) != 0 || S_ISDIR(s.st_mode))
@@ -456,7 +457,7 @@ General_options::parse_R(const char* option, const char* arg,
void
General_options::parse_just_symbols(const char*, const char* arg,
- Command_line* cmdline)
+ Command_line* cmdline)
{
Input_file_argument file(arg, Input_file_argument::INPUT_FILE_TYPE_FILE,
"", true, *this);
@@ -528,7 +529,7 @@ General_options::parse_static(const char*, const char*, Command_line*)
void
General_options::parse_script(const char*, const char* arg,
- Command_line* cmdline)
+ Command_line* cmdline)
{
if (!read_commandline_script(arg, cmdline))
gold::gold_fatal(_("unable to parse script file %s"), arg);
@@ -536,7 +537,7 @@ General_options::parse_script(const char*, const char* arg,
void
General_options::parse_version_script(const char*, const char* arg,
- Command_line* cmdline)
+ Command_line* cmdline)
{
if (!read_version_script(arg, cmdline))
gold::gold_fatal(_("unable to parse version script file %s"), arg);
@@ -544,7 +545,7 @@ General_options::parse_version_script(const char*, const char* arg,
void
General_options::parse_dynamic_list(const char*, const char* arg,
- Command_line* cmdline)
+ Command_line* cmdline)
{
if (!read_dynamic_list(arg, cmdline, &this->dynamic_list_))
gold::gold_fatal(_("unable to parse dynamic-list script file %s"), arg);
@@ -552,28 +553,28 @@ General_options::parse_dynamic_list(const char*, const char* arg,
void
General_options::parse_start_group(const char*, const char*,
- Command_line* cmdline)
+ Command_line* cmdline)
{
cmdline->inputs().start_group();
}
void
General_options::parse_end_group(const char*, const char*,
- Command_line* cmdline)
+ Command_line* cmdline)
{
cmdline->inputs().end_group();
}
void
General_options::parse_start_lib(const char*, const char*,
- Command_line* cmdline)
+ Command_line* cmdline)
{
cmdline->inputs().start_lib(cmdline->position_dependent_options());
}
void
General_options::parse_end_lib(const char*, const char*,
- Command_line* cmdline)
+ Command_line* cmdline)
{
cmdline->inputs().end_lib();
}
@@ -585,7 +586,7 @@ General_options::parse_end_lib(const char*, const char*,
void
General_options::parse_exclude_libs(const char*, const char* arg,
- Command_line*)
+ Command_line*)
{
const char* p = arg;
@@ -659,15 +660,15 @@ General_options::string_to_object_format(const char* arg)
else
{
gold::gold_error(_("format '%s' not supported; treating as elf "
- "(supported formats: elf, binary)"),
- arg);
+ "(supported formats: elf, binary)"),
+ arg);
return gold::General_options::OBJECT_FORMAT_ELF;
}
}
void
General_options::parse_fix_v4bx(const char*, const char*,
- Command_line*)
+ Command_line*)
{
this->fix_v4bx_ = FIX_V4BX_REPLACE;
}
@@ -700,8 +701,8 @@ void
usage()
{
fprintf(stderr,
- _("%s: use the --help option for usage information\n"),
- gold::program_name);
+ _("%s: use the --help option for usage information\n"),
+ gold::program_name);
::exit(EXIT_FAILURE);
}
@@ -709,8 +710,8 @@ void
usage(const char* msg, const char* opt)
{
fprintf(stderr,
- _("%s: %s: %s\n"),
- gold::program_name, opt, msg);
+ _("%s: %s: %s\n"),
+ gold::program_name, opt, msg);
usage();
}
@@ -721,12 +722,12 @@ static char*
get_relative_sysroot(const char* from)
{
char* path = make_relative_prefix(gold::program_name, from,
- TARGET_SYSTEM_ROOT);
+ TARGET_SYSTEM_ROOT);
if (path != NULL)
{
struct stat s;
if (::stat(path, &s) == 0 && S_ISDIR(s.st_mode))
- return path;
+ return path;
free(path);
}
@@ -749,9 +750,9 @@ get_default_sysroot()
{
char* path = get_relative_sysroot(BINDIR);
if (path == NULL)
- path = get_relative_sysroot(TOOLBINDIR);
+ path = get_relative_sysroot(TOOLBINDIR);
if (path != NULL)
- return path;
+ return path;
}
return sysroot;
@@ -768,14 +769,14 @@ get_default_sysroot()
// NOTE: it is safe for argv and arg to point to the same place.
gold::options::One_option*
parse_long_option(int argc, const char** argv, bool equals_only,
- const char** arg, int* i)
+ const char** arg, int* i)
{
const char* const this_argv = argv[*i];
const char* equals = strchr(this_argv, '=');
const char* option_start = this_argv + strspn(this_argv, "-");
std::string option(option_start,
- equals ? equals - option_start : strlen(option_start));
+ equals ? equals - option_start : strlen(option_start));
gold::options::Option_map::iterator it
= gold::options::long_options->find(option);
@@ -788,21 +789,21 @@ parse_long_option(int argc, const char** argv, bool equals_only,
if (this_argv[0] != '-') // no dashes at all: had better be "-z <longopt>"
{
if (retval->dashes != gold::options::DASH_Z)
- return NULL;
+ return NULL;
}
else if (this_argv[1] != '-') // one dash
{
if (retval->dashes != gold::options::ONE_DASH
- && retval->dashes != gold::options::EXACTLY_ONE_DASH
- && retval->dashes != gold::options::TWO_DASHES)
- return NULL;
+ && retval->dashes != gold::options::EXACTLY_ONE_DASH
+ && retval->dashes != gold::options::TWO_DASHES)
+ return NULL;
}
else // two dashes (or more!)
{
if (retval->dashes != gold::options::TWO_DASHES
- && retval->dashes != gold::options::EXACTLY_TWO_DASHES
- && retval->dashes != gold::options::ONE_DASH)
- return NULL;
+ && retval->dashes != gold::options::EXACTLY_TWO_DASHES
+ && retval->dashes != gold::options::ONE_DASH)
+ return NULL;
}
// Now that we know the option is good (or else bad in a way that
@@ -813,20 +814,20 @@ parse_long_option(int argc, const char** argv, bool equals_only,
if (!retval->takes_argument())
{
if (equals)
- usage(_("unexpected argument"), this_argv);
+ usage(_("unexpected argument"), this_argv);
else
- *arg = NULL;
+ *arg = NULL;
}
else
{
if (equals)
- *arg = equals + 1;
+ *arg = equals + 1;
else if (retval->takes_optional_argument())
*arg = retval->default_value;
else if (*i < argc && !equals_only)
- *arg = argv[(*i)++];
+ *arg = argv[(*i)++];
else
- usage(_("missing argument"), this_argv);
+ usage(_("missing argument"), this_argv);
}
return retval;
@@ -844,7 +845,7 @@ parse_long_option(int argc, const char** argv, bool equals_only,
// another short option in the same word.
gold::options::One_option*
parse_short_option(int argc, const char** argv, int pos_in_argv_i,
- const char** arg, int* i)
+ const char** arg, int* i)
{
const char* const this_argv = argv[*i];
@@ -853,7 +854,7 @@ parse_short_option(int argc, const char** argv, int pos_in_argv_i,
// We handle -z as a special case.
static gold::options::One_option dash_z("", gold::options::DASH_Z,
- 'z', "", NULL, "Z-OPTION", false,
+ 'z', "", NULL, "Z-OPTION", false,
NULL);
gold::options::One_option* retval = NULL;
if (this_argv[pos_in_argv_i] == 'z')
@@ -862,7 +863,7 @@ parse_short_option(int argc, const char** argv, int pos_in_argv_i,
{
const int char_as_int = static_cast<int>(this_argv[pos_in_argv_i]);
if (char_as_int > 0 && char_as_int < 128)
- retval = gold::options::short_options[char_as_int];
+ retval = gold::options::short_options[char_as_int];
}
if (retval == NULL)
@@ -874,20 +875,20 @@ parse_short_option(int argc, const char** argv, int pos_in_argv_i,
*arg = NULL;
// We only advance past this argument if it's the only one in argv.
if (this_argv[pos_in_argv_i + 1] == '\0')
- ++(*i);
+ ++(*i);
}
else
{
// If we take an argument, we'll eat up this entire argv entry.
++(*i);
if (this_argv[pos_in_argv_i + 1] != '\0')
- *arg = this_argv + pos_in_argv_i + 1;
+ *arg = this_argv + pos_in_argv_i + 1;
else if (retval->takes_optional_argument())
*arg = retval->default_value;
else if (*i < argc)
- *arg = argv[(*i)++];
+ *arg = argv[(*i)++];
else
- usage(_("missing argument"), this_argv);
+ usage(_("missing argument"), this_argv);
}
// If we're a -z option, we need to parse our argument as a
@@ -898,7 +899,7 @@ parse_short_option(int argc, const char** argv, int pos_in_argv_i,
const char* dash_z_arg = *arg;
retval = parse_long_option(1, arg, true, arg, &dummy_i);
if (retval == NULL)
- usage(_("unknown -z option"), dash_z_arg);
+ usage(_("unknown -z option"), dash_z_arg);
}
return retval;
@@ -952,7 +953,7 @@ General_options::add_sysroot()
{
this->set_sysroot(get_default_sysroot());
if (this->sysroot() == NULL || this->sysroot()[0] == '\0')
- return;
+ return;
}
char* canonical_sysroot = lrealpath(this->sysroot());
@@ -1117,8 +1118,8 @@ General_options::finalize()
if (this->thread_count() > 0 || this->thread_count_initial() > 0
|| this->thread_count_middle() > 0 || this->thread_count_final() > 0)
gold_warning(_("ignoring --thread-count: "
- "%s was compiled without thread support"),
- program_name);
+ "%s was compiled without thread support"),
+ program_name);
#endif
std::string libpath;
@@ -1170,17 +1171,17 @@ General_options::finalize()
std::ifstream in;
in.open(this->retain_symbols_file());
if (!in)
- gold_fatal(_("unable to open -retain-symbols-file file %s: %s"),
- this->retain_symbols_file(), strerror(errno));
+ gold_fatal(_("unable to open -retain-symbols-file file %s: %s"),
+ this->retain_symbols_file(), strerror(errno));
std::string line;
std::getline(in, line); // this chops off the trailing \n, if any
while (in)
- {
- if (!line.empty() && line[line.length() - 1] == '\r') // Windows
- line.resize(line.length() - 1);
- this->symbols_to_retain_.insert(line);
- std::getline(in, line);
- }
+ {
+ if (!line.empty() && line[line.length() - 1] == '\r') // Windows
+ line.resize(line.length() - 1);
+ this->symbols_to_retain_.insert(line);
+ std::getline(in, line);
+ }
}
// -Bgroup implies --unresolved-symbols=report-all.
@@ -1239,7 +1240,7 @@ General_options::finalize()
if (this->implicit_incremental_ && this->incremental_mode_ == INCREMENTAL_OFF)
gold_fatal(_("Options --incremental-changed, --incremental-unchanged, "
- "--incremental-unknown require the use of --incremental"));
+ "--incremental-unknown require the use of --incremental"));
// Check for options that are not compatible with incremental linking.
// Where an option can be disabled without seriously changing the semantics
@@ -1272,6 +1273,10 @@ General_options::finalize()
}
}
+ // --rosegment-gap implies --rosegment.
+ if (this->user_set_rosegment_gap())
+ this->set_rosegment(true);
+
// FIXME: we can/should be doing a lot more sanity checking here.
}
@@ -1282,14 +1287,14 @@ General_options::finalize()
void
Search_directory::add_sysroot(const char* sysroot,
- const char* canonical_sysroot)
+ const char* canonical_sysroot)
{
gold_assert(*sysroot != '\0');
if (this->put_in_sysroot_)
{
if (!IS_DIR_SEPARATOR(this->name_[0])
- && !IS_DIR_SEPARATOR(sysroot[strlen(sysroot) - 1]))
- this->name_ = '/' + this->name_;
+ && !IS_DIR_SEPARATOR(sysroot[strlen(sysroot) - 1]))
+ this->name_ = '/' + this->name_;
this->name_ = sysroot + this->name_;
this->is_in_sysroot_ = true;
}
@@ -1302,12 +1307,12 @@ Search_directory::add_sysroot(const char* sysroot,
int canonical_name_len = strlen(canonical_name);
int canonical_sysroot_len = strlen(canonical_sysroot);
if (canonical_name_len > canonical_sysroot_len
- && IS_DIR_SEPARATOR(canonical_name[canonical_sysroot_len]))
- {
- canonical_name[canonical_sysroot_len] = '\0';
- if (FILENAME_CMP(canonical_name, canonical_sysroot) == 0)
- this->is_in_sysroot_ = true;
- }
+ && IS_DIR_SEPARATOR(canonical_name[canonical_sysroot_len]))
+ {
+ canonical_name[canonical_sysroot_len] = '\0';
+ if (FILENAME_CMP(canonical_name, canonical_sysroot) == 0)
+ this->is_in_sysroot_ = true;
+ }
free(canonical_name);
}
}
@@ -1406,7 +1411,7 @@ Command_line::Pre_options::Pre_options()
int
Command_line::process_one_option(int argc, const char** argv, int i,
- bool* no_more_options)
+ bool* no_more_options)
{
gold_assert(argv[i][0] == '-' && !(*no_more_options));
@@ -1437,7 +1442,7 @@ Command_line::process_one_option(int argc, const char** argv, int i,
{
option = parse_short_option(argc, argv, pos_in_argv_i, &arg, &new_i);
if (!option)
- break;
+ break;
option->reader->parse_to_value(argv[i], arg, this, &this->options_);
++pos_in_argv_i;
}
@@ -1459,15 +1464,15 @@ Command_line::process(int argc, const char** argv)
{
this->position_options_.copy_from_options(this->options());
if (no_more_options || argv[i][0] != '-')
- {
+ {
Input_file_argument file(argv[i],
Input_file_argument::INPUT_FILE_TYPE_FILE,
"", false, this->position_options_);
- this->inputs_.add_file(file);
- ++i;
- }
+ this->inputs_.add_file(file);
+ ++i;
+ }
else
- i = process_one_option(argc, argv, i, &no_more_options);
+ i = process_one_option(argc, argv, i, &no_more_options);
}
if (this->inputs_.in_group())
diff --git a/gold/options.h b/gold/options.h
index 75dbee5da..005582690 100644
--- a/gold/options.h
+++ b/gold/options.h
@@ -1,6 +1,7 @@
// options.h -- handle command line options for gold -*- C++ -*-
-// Copyright 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+// Copyright 2006, 2007, 2008, 2009, 2010, 2011, 2013
+// Free Software Foundation, Inc.
// Written by Ian Lance Taylor <iant@google.com>.
// This file is part of gold.
@@ -120,7 +121,7 @@ parse_set(const char* option_name, const char* arg, String_set* retval);
extern void
parse_choices(const char* option_name, const char* arg, const char** retval,
- const char* choices[], int num_choices);
+ const char* choices[], int num_choices);
struct Struct_var;
@@ -168,7 +169,7 @@ struct One_option
Struct_var* reader;
One_option(const char* ln, Dashes d, char sn, const char* dv,
- const char* hs, const char* ha, bool oa, Struct_var* r)
+ const char* hs, const char* ha, bool oa, Struct_var* r)
: longname(ln), dashes(d), shortname(sn), default_value(dv ? dv : ""),
helpstring(hs), helparg(ha), optional_arg(oa), reader(r)
{
@@ -219,7 +220,7 @@ struct Struct_var
// OPTIONS: the global General_options object. Used by DEFINE_special.
virtual void
parse_to_value(const char* option, const char* arg,
- Command_line* cmdline, General_options* options) = 0;
+ Command_line* cmdline, General_options* options) = 0;
virtual
~Struct_var() // To make gcc happy.
{ }
@@ -230,16 +231,16 @@ struct Struct_special : public Struct_var
{
// If you change this, change the parse-fn in DEFINE_special as well.
typedef void (General_options::*Parse_function)(const char*, const char*,
- Command_line*);
+ Command_line*);
Struct_special(const char* varname, Dashes dashes, char shortname,
- Parse_function parse_function,
- const char* helpstring, const char* helparg)
+ Parse_function parse_function,
+ const char* helpstring, const char* helparg)
: option(varname, dashes, shortname, "", helpstring, helparg, false, this),
parse(parse_function)
{ }
void parse_to_value(const char* option, const char* arg,
- Command_line* cmdline, General_options* options)
+ Command_line* cmdline, General_options* options)
{ (options->*(this->parse))(option, arg, cmdline); }
One_option option;
@@ -261,17 +262,17 @@ struct Struct_special : public Struct_var
// avoid unintended macro substitution of "assert()", we need to enclose
// varname__ with parenthese.
#define DEFINE_var(varname__, dashes__, shortname__, default_value__, \
- default_value_as_string__, helpstring__, helparg__, \
- optional_arg__, type__, param_type__, parse_fn__) \
+ default_value_as_string__, helpstring__, helparg__, \
+ optional_arg__, type__, param_type__, parse_fn__) \
public: \
param_type__ \
(varname__)() const \
{ return this->varname__##_.value; } \
- \
+ \
bool \
user_set_##varname__() const \
{ return this->varname__##_.user_set_via_option; } \
- \
+ \
void \
set_user_set_##varname__() \
{ this->varname__##_.user_set_via_option = true; } \
@@ -281,18 +282,18 @@ struct Struct_special : public Struct_var
{ \
Struct_##varname__() \
: option(#varname__, dashes__, shortname__, default_value_as_string__, \
- helpstring__, helparg__, optional_arg__, this), \
- user_set_via_option(false), value(default_value__) \
+ helpstring__, helparg__, optional_arg__, this), \
+ user_set_via_option(false), value(default_value__) \
{ } \
- \
+ \
void \
parse_to_value(const char* option_name, const char* arg, \
- Command_line*, General_options*) \
+ Command_line*, General_options*) \
{ \
parse_fn__(option_name, arg, &this->value); \
this->user_set_via_option = true; \
} \
- \
+ \
options::One_option option; \
bool user_set_via_option; \
type__ value; \
@@ -308,71 +309,71 @@ struct Struct_special : public Struct_var
// VARNAME, we also create an option called no-VARNAME (or, for a -z
// option, noVARNAME).
#define DEFINE_bool(varname__, dashes__, shortname__, default_value__, \
- helpstring__, no_helpstring__) \
+ helpstring__, no_helpstring__) \
DEFINE_var(varname__, dashes__, shortname__, default_value__, \
- default_value__ ? "true" : "false", helpstring__, NULL, \
- false, bool, bool, options::parse_bool) \
+ default_value__ ? "true" : "false", helpstring__, NULL, \
+ false, bool, bool, options::parse_bool) \
struct Struct_no_##varname__ : public options::Struct_var \
{ \
Struct_no_##varname__() : option((dashes__ == options::DASH_Z \
? "no" #varname__ \
: "no-" #varname__), \
dashes__, '\0', \
- default_value__ ? "false" : "true", \
- no_helpstring__, NULL, false, this) \
+ default_value__ ? "false" : "true", \
+ no_helpstring__, NULL, false, this) \
{ } \
- \
+ \
void \
parse_to_value(const char*, const char*, \
- Command_line*, General_options* options) \
+ Command_line*, General_options* options) \
{ \
options->set_##varname__(false); \
options->set_user_set_##varname__(); \
} \
- \
+ \
options::One_option option; \
}; \
Struct_no_##varname__ no_##varname__##_initializer_
#define DEFINE_enable(varname__, dashes__, shortname__, default_value__, \
- helpstring__, no_helpstring__) \
+ helpstring__, no_helpstring__) \
DEFINE_var(enable_##varname__, dashes__, shortname__, default_value__, \
- default_value__ ? "true" : "false", helpstring__, NULL, \
- false, bool, bool, options::parse_bool) \
+ default_value__ ? "true" : "false", helpstring__, NULL, \
+ false, bool, bool, options::parse_bool) \
struct Struct_disable_##varname__ : public options::Struct_var \
{ \
Struct_disable_##varname__() : option("disable-" #varname__, \
- dashes__, '\0', \
- default_value__ ? "false" : "true", \
- no_helpstring__, NULL, false, this) \
+ dashes__, '\0', \
+ default_value__ ? "false" : "true", \
+ no_helpstring__, NULL, false, this) \
{ } \
- \
+ \
void \
parse_to_value(const char*, const char*, \
- Command_line*, General_options* options) \
+ Command_line*, General_options* options) \
{ options->set_enable_##varname__(false); } \
- \
+ \
options::One_option option; \
}; \
Struct_disable_##varname__ disable_##varname__##_initializer_
#define DEFINE_int(varname__, dashes__, shortname__, default_value__, \
- helpstring__, helparg__) \
+ helpstring__, helparg__) \
DEFINE_var(varname__, dashes__, shortname__, default_value__, \
- #default_value__, helpstring__, helparg__, false, \
- int, int, options::parse_int)
+ #default_value__, helpstring__, helparg__, false, \
+ int, int, options::parse_int)
#define DEFINE_uint(varname__, dashes__, shortname__, default_value__, \
- helpstring__, helparg__) \
+ helpstring__, helparg__) \
DEFINE_var(varname__, dashes__, shortname__, default_value__, \
- #default_value__, helpstring__, helparg__, false, \
- int, int, options::parse_uint)
+ #default_value__, helpstring__, helparg__, false, \
+ int, int, options::parse_uint)
#define DEFINE_uint64(varname__, dashes__, shortname__, default_value__, \
- helpstring__, helparg__) \
+ helpstring__, helparg__) \
DEFINE_var(varname__, dashes__, shortname__, default_value__, \
- #default_value__, helpstring__, helparg__, false, \
- uint64_t, uint64_t, options::parse_uint64)
+ #default_value__, helpstring__, helparg__, false, \
+ uint64_t, uint64_t, options::parse_uint64)
#define DEFINE_double(varname__, dashes__, shortname__, default_value__, \
helpstring__, helparg__) \
@@ -387,19 +388,19 @@ struct Struct_special : public Struct_var
double, double, options::parse_percent)
#define DEFINE_string(varname__, dashes__, shortname__, default_value__, \
- helpstring__, helparg__) \
+ helpstring__, helparg__) \
DEFINE_var(varname__, dashes__, shortname__, default_value__, \
- default_value__, helpstring__, helparg__, false, \
- const char*, const char*, options::parse_string)
+ default_value__, helpstring__, helparg__, false, \
+ const char*, const char*, options::parse_string)
// This is like DEFINE_string, but we convert each occurrence to a
// Search_directory and store it in a vector. Thus we also have the
// add_to_VARNAME() method, to append to the vector.
#define DEFINE_dirlist(varname__, dashes__, shortname__, \
- helpstring__, helparg__) \
+ helpstring__, helparg__) \
DEFINE_var(varname__, dashes__, shortname__, , \
- "", helpstring__, helparg__, false, options::Dir_list, \
- const options::Dir_list&, options::parse_dirlist) \
+ "", helpstring__, helparg__, false, options::Dir_list, \
+ const options::Dir_list&, options::parse_dirlist) \
void \
add_to_##varname__(const char* new_value) \
{ options::parse_dirlist(NULL, new_value, &this->varname__##_.value); } \
@@ -409,10 +410,10 @@ struct Struct_special : public Struct_var
// This is like DEFINE_string, but we store a set of strings.
#define DEFINE_set(varname__, dashes__, shortname__, \
- helpstring__, helparg__) \
+ helpstring__, helparg__) \
DEFINE_var(varname__, dashes__, shortname__, , \
- "", helpstring__, helparg__, false, options::String_set, \
- const options::String_set&, options::parse_set) \
+ "", helpstring__, helparg__, false, options::String_set, \
+ const options::String_set&, options::parse_set) \
public: \
bool \
any_##varname__() const \
@@ -422,8 +423,8 @@ struct Struct_special : public Struct_var
is_##varname__(const char* symbol) const \
{ \
return (!this->varname__##_.value.empty() \
- && (this->varname__##_.value.find(std::string(symbol)) \
- != this->varname__##_.value.end())); \
+ && (this->varname__##_.value.find(std::string(symbol)) \
+ != this->varname__##_.value.end())); \
} \
\
options::String_set::const_iterator \
@@ -438,17 +439,17 @@ struct Struct_special : public Struct_var
// After helparg__ should come an initializer list, like
// {"foo", "bar", "baz"}
#define DEFINE_enum(varname__, dashes__, shortname__, default_value__, \
- helpstring__, helparg__, ...) \
+ helpstring__, helparg__, ...) \
DEFINE_var(varname__, dashes__, shortname__, default_value__, \
- default_value__, helpstring__, helparg__, false, \
- const char*, const char*, parse_choices_##varname__) \
+ default_value__, helpstring__, helparg__, false, \
+ const char*, const char*, parse_choices_##varname__) \
private: \
static void parse_choices_##varname__(const char* option_name, \
- const char* arg, \
- const char** retval) { \
+ const char* arg, \
+ const char** retval) { \
const char* choices[] = __VA_ARGS__; \
options::parse_choices(option_name, arg, retval, \
- choices, sizeof(choices) / sizeof(*choices)); \
+ choices, sizeof(choices) / sizeof(*choices)); \
}
// This is like DEFINE_bool, but VARNAME is the name of a different
@@ -530,16 +531,16 @@ struct Struct_special : public Struct_var
// General_options; you are responsible for defining it there.
// helparg__ should be NULL iff this special-option is a boolean.
#define DEFINE_special(varname__, dashes__, shortname__, \
- helpstring__, helparg__) \
+ helpstring__, helparg__) \
private: \
void parse_##varname__(const char* option, const char* arg, \
- Command_line* inputs); \
+ Command_line* inputs); \
struct Struct_##varname__ : public options::Struct_special \
{ \
Struct_##varname__() \
: options::Struct_special(#varname__, dashes__, shortname__, \
- &General_options::parse_##varname__, \
- helpstring__, helparg__) \
+ &General_options::parse_##varname__, \
+ helpstring__, helparg__) \
{ } \
}; \
Struct_##varname__ varname__##_initializer_
@@ -551,8 +552,8 @@ struct Struct_special : public Struct_var
default_value__, \
helpstring__, helparg__) \
DEFINE_var(varname__, dashes__, shortname__, default_value__, \
- default_value__, helpstring__, helparg__, true, \
- const char*, const char*, options::parse_optional_string)
+ default_value__, helpstring__, helparg__, true, \
+ const char*, const char*, options::parse_optional_string)
// A directory to search. For each directory we record whether it is
// in the sysroot. We need to know this so that, if a linker script
@@ -620,11 +621,11 @@ class General_options
// NOTE: For every option that you add here, also consider if you
// should add it to Position_dependent_options.
DEFINE_special(help, options::TWO_DASHES, '\0',
- N_("Report usage information"), NULL);
+ N_("Report usage information"), NULL);
DEFINE_special(version, options::TWO_DASHES, 'v',
- N_("Report version information"), NULL);
+ N_("Report version information"), NULL);
DEFINE_special(V, options::EXACTLY_ONE_DASH, '\0',
- N_("Report version and target information"), NULL);
+ N_("Report version and target information"), NULL);
// These options are sorted approximately so that for each letter in
// the alphabet, we show the option whose shortname is that letter
@@ -641,12 +642,12 @@ class General_options
N_("Do not allow multiple definitions"), false);
DEFINE_bool(allow_shlib_undefined, options::TWO_DASHES, '\0', false,
- N_("Allow unresolved references in shared libraries"),
- N_("Do not allow unresolved references in shared libraries"));
+ N_("Allow unresolved references in shared libraries"),
+ N_("Do not allow unresolved references in shared libraries"));
DEFINE_bool(as_needed, options::TWO_DASHES, '\0', false,
- N_("Only set DT_NEEDED for shared libraries if used"),
- N_("Always DT_NEEDED for shared libraries"));
+ N_("Only set DT_NEEDED for shared libraries if used"),
+ N_("Always DT_NEEDED for shared libraries"));
DEFINE_enum(assert, options::ONE_DASH, '\0', NULL,
N_("Ignored"), N_("[ignored]"),
@@ -657,10 +658,10 @@ class General_options
// accept any string. We'll fail later (when the string is parsed),
// if the target isn't actually supported.
DEFINE_string(format, options::TWO_DASHES, 'b', "elf",
- N_("Set input format"), ("[elf,binary]"));
+ N_("Set input format"), ("[elf,binary]"));
DEFINE_bool(Bdynamic, options::ONE_DASH, '\0', true,
- N_("-l searches for shared libraries"), NULL);
+ N_("-l searches for shared libraries"), NULL);
DEFINE_bool_alias(Bstatic, Bdynamic, options::ONE_DASH, '\0',
N_("-l does not search for shared libraries"), NULL,
true);
@@ -673,7 +674,7 @@ class General_options
N_("Use group name lookup rules for shared library"), NULL);
DEFINE_bool(Bsymbolic, options::ONE_DASH, '\0', false,
- N_("Bind defined symbols locally"), NULL);
+ N_("Bind defined symbols locally"), NULL);
DEFINE_bool(Bsymbolic_functions, options::ONE_DASH, '\0', false,
N_("Bind defined function symbols locally"), NULL);
@@ -683,13 +684,13 @@ class General_options
N_("[=STYLE]"));
DEFINE_uint64(build_id_chunk_size_for_treehash,
- options::TWO_DASHES, '\0', 2 << 20,
- N_("Chunk size for '--build-id=tree'"), N_("SIZE"));
+ options::TWO_DASHES, '\0', 2 << 20,
+ N_("Chunk size for '--build-id=tree'"), N_("SIZE"));
DEFINE_uint64(build_id_min_file_size_for_treehash, options::TWO_DASHES,
- '\0', 40 << 20,
- N_("Minimum output file size for '--build-id=tree' to work"
- " differently than '--build-id=sha1'"), N_("SIZE"));
+ '\0', 40 << 20,
+ N_("Minimum output file size for '--build-id=tree' to work"
+ " differently than '--build-id=sha1'"), N_("SIZE"));
DEFINE_bool(check_sections, options::TWO_DASHES, '\0', true,
N_("Check segment addresses for overlaps (default)"),
@@ -697,14 +698,14 @@ class General_options
#ifdef HAVE_ZLIB_H
DEFINE_enum(compress_debug_sections, options::TWO_DASHES, '\0', "none",
- N_("Compress .debug_* sections in the output file"),
- ("[none,zlib]"),
- {"none", "zlib"});
+ N_("Compress .debug_* sections in the output file"),
+ ("[none,zlib]"),
+ {"none", "zlib"});
#else
DEFINE_enum(compress_debug_sections, options::TWO_DASHES, '\0', "none",
- N_("Compress .debug_* sections in the output file"),
- N_("[none]"),
- {"none"});
+ N_("Compress .debug_* sections in the output file"),
+ N_("[none]"),
+ {"none"});
#endif
DEFINE_bool(copy_dt_needed_entries, options::TWO_DASHES, '\0', false,
@@ -720,19 +721,19 @@ class General_options
N_("Handle constructors as directed by compiler"));
DEFINE_bool(define_common, options::TWO_DASHES, 'd', false,
- N_("Define common symbols"),
- N_("Do not define common symbols"));
+ N_("Define common symbols"),
+ N_("Do not define common symbols"));
DEFINE_bool(dc, options::ONE_DASH, '\0', false,
- N_("Alias for -d"), NULL);
+ N_("Alias for -d"), NULL);
DEFINE_bool(dp, options::ONE_DASH, '\0', false,
- N_("Alias for -d"), NULL);
+ N_("Alias for -d"), NULL);
DEFINE_string(debug, options::TWO_DASHES, '\0', "",
- N_("Turn on debugging"),
- N_("[all,files,script,task][,...]"));
+ N_("Turn on debugging"),
+ N_("[all,files,script,task][,...]"));
DEFINE_special(defsym, options::TWO_DASHES, '\0',
- N_("Define a symbol"), N_("SYMBOL=EXPRESSION"));
+ N_("Define a symbol"), N_("SYMBOL=EXPRESSION"));
DEFINE_optional_string(demangle, options::TWO_DASHES, '\0', NULL,
N_("Demangle C++ symbols in log messages"),
@@ -743,35 +744,35 @@ class General_options
NULL);
DEFINE_bool(detect_odr_violations, options::TWO_DASHES, '\0', false,
- N_("Look for violations of the C++ One Definition Rule"),
+ N_("Look for violations of the C++ One Definition Rule"),
N_("Do not look for violations of the C++ One Definition Rule"));
DEFINE_bool(discard_all, options::TWO_DASHES, 'x', false,
N_("Delete all local symbols"), NULL);
DEFINE_bool(discard_locals, options::TWO_DASHES, 'X', false,
- N_("Delete all temporary local symbols"), NULL);
+ N_("Delete all temporary local symbols"), NULL);
DEFINE_bool(dynamic_list_data, options::TWO_DASHES, '\0', false,
- N_("Add data symbols to dynamic symbols"), NULL);
+ N_("Add data symbols to dynamic symbols"), NULL);
DEFINE_bool(dynamic_list_cpp_new, options::TWO_DASHES, '\0', false,
- N_("Add C++ operator new/delete to dynamic symbols"), NULL);
+ N_("Add C++ operator new/delete to dynamic symbols"), NULL);
DEFINE_bool(dynamic_list_cpp_typeinfo, options::TWO_DASHES, '\0', false,
- N_("Add C++ typeinfo to dynamic symbols"), NULL);
+ N_("Add C++ typeinfo to dynamic symbols"), NULL);
DEFINE_special(dynamic_list, options::TWO_DASHES, '\0',
- N_("Read a list of dynamic symbols"), N_("FILE"));
+ N_("Read a list of dynamic symbols"), N_("FILE"));
DEFINE_string(entry, options::TWO_DASHES, 'e', NULL,
- N_("Set program start address"), N_("ADDRESS"));
+ N_("Set program start address"), N_("ADDRESS"));
DEFINE_special(exclude_libs, options::TWO_DASHES, '\0',
N_("Exclude libraries from automatic export"),
N_(("lib,lib ...")));
DEFINE_bool(export_dynamic, options::TWO_DASHES, 'E', false,
- N_("Export all dynamic symbols"),
+ N_("Export all dynamic symbols"),
N_("Do not export all dynamic symbols (default)"));
DEFINE_set(export_dynamic_symbol, options::TWO_DASHES, '\0',
@@ -784,7 +785,7 @@ class General_options
N_("Link little-endian objects."), NULL);
DEFINE_bool(eh_frame_hdr, options::TWO_DASHES, '\0', false,
- N_("Create exception frame header"), NULL);
+ N_("Create exception frame header"), NULL);
DEFINE_bool(enum_size_warning, options::TWO_DASHES, '\0', true, NULL,
N_("(ARM only) Do not warn about objects with incompatible "
@@ -803,7 +804,7 @@ class General_options
N_("Do not treat warnings as errors"));
DEFINE_string(fini, options::ONE_DASH, '\0', "_fini",
- N_("Call SYMBOL at unload-time"), N_("SYMBOL"));
+ N_("Call SYMBOL at unload-time"), N_("SYMBOL"));
DEFINE_bool(fix_cortex_a8, options::TWO_DASHES, '\0', false,
N_("(ARM only) Fix binaries for Cortex-A8 erratum."),
@@ -818,13 +819,13 @@ class General_options
N_("(ARM only) Do not merge exidx entries in debuginfo."));
DEFINE_special(fix_v4bx, options::TWO_DASHES, '\0',
- N_("(ARM only) Rewrite BX rn as MOV pc, rn for ARMv4"),
- NULL);
+ N_("(ARM only) Rewrite BX rn as MOV pc, rn for ARMv4"),
+ NULL);
DEFINE_special(fix_v4bx_interworking, options::TWO_DASHES, '\0',
- N_("(ARM only) Rewrite BX rn branch to ARMv4 interworking "
- "veneer"),
- NULL);
+ N_("(ARM only) Rewrite BX rn branch to ARMv4 interworking "
+ "veneer"),
+ NULL);
DEFINE_bool(g, options::EXACTLY_ONE_DASH, '\0', false,
N_("Ignored"), NULL);
@@ -838,7 +839,7 @@ class General_options
N_("Disable STB_GNU_UNIQUE symbol binding"));
DEFINE_string(soname, options::ONE_DASH, 'h', NULL,
- N_("Set shared library name"), N_("FILENAME"));
+ N_("Set shared library name"), N_("FILENAME"));
DEFINE_double(hash_bucket_empty_fraction, options::TWO_DASHES, '\0', 0.0,
N_("Min fraction of empty buckets in dynamic hash"),
@@ -849,7 +850,7 @@ class General_options
{"sysv", "gnu", "both"});
DEFINE_string(dynamic_linker, options::TWO_DASHES, 'I', NULL,
- N_("Set dynamic linker path"), N_("PROGRAM"));
+ N_("Set dynamic linker path"), N_("PROGRAM"));
DEFINE_special(incremental, options::TWO_DASHES, '\0',
N_("Do an incremental link if possible; "
@@ -867,21 +868,21 @@ class General_options
N_("Do an incremental link; exit if not possible"), NULL);
DEFINE_string(incremental_base, options::TWO_DASHES, '\0', NULL,
- N_("Set base file for incremental linking"
- " (default is output file)"),
- N_("FILE"));
+ N_("Set base file for incremental linking"
+ " (default is output file)"),
+ N_("FILE"));
DEFINE_special(incremental_changed, options::TWO_DASHES, '\0',
- N_("Assume files changed"), NULL);
+ N_("Assume files changed"), NULL);
DEFINE_special(incremental_unchanged, options::TWO_DASHES, '\0',
- N_("Assume files didn't change"), NULL);
+ N_("Assume files didn't change"), NULL);
DEFINE_special(incremental_unknown, options::TWO_DASHES, '\0',
- N_("Use timestamps to check files (default)"), NULL);
+ N_("Use timestamps to check files (default)"), NULL);
DEFINE_special(incremental_startup_unchanged, options::TWO_DASHES, '\0',
- N_("Assume startup files unchanged "
+ N_("Assume startup files unchanged "
"(files preceding this option)"), NULL);
DEFINE_percent(incremental_patch, options::TWO_DASHES, '\0', 10,
@@ -889,29 +890,29 @@ class General_options
N_("PERCENT"));
DEFINE_string(init, options::ONE_DASH, '\0', "_init",
- N_("Call SYMBOL at load-time"), N_("SYMBOL"));
+ N_("Call SYMBOL at load-time"), N_("SYMBOL"));
DEFINE_special(just_symbols, options::TWO_DASHES, '\0',
- N_("Read only symbol values from FILE"), N_("FILE"));
+ N_("Read only symbol values from FILE"), N_("FILE"));
DEFINE_bool(map_whole_files, options::TWO_DASHES, '\0',
sizeof(void*) >= 8,
- N_("Map whole files to memory (default on 64-bit hosts)"),
- N_("Map relevant file parts to memory (default on 32-bit "
- "hosts)"));
+ N_("Map whole files to memory (default on 64-bit hosts)"),
+ N_("Map relevant file parts to memory (default on 32-bit "
+ "hosts)"));
DEFINE_bool(keep_files_mapped, options::TWO_DASHES, '\0', true,
- N_("Keep files mapped across passes (default)"),
- N_("Release mapped files after each pass"));
+ N_("Keep files mapped across passes (default)"),
+ N_("Release mapped files after each pass"));
DEFINE_bool(ld_generated_unwind_info, options::TWO_DASHES, '\0', true,
N_("Generate unwind information for PLT (default)"),
N_("Do not generate unwind information for PLT"));
DEFINE_special(library, options::TWO_DASHES, 'l',
- N_("Search for library LIBNAME"), N_("LIBNAME"));
+ N_("Search for library LIBNAME"), N_("LIBNAME"));
DEFINE_dirlist(library_path, options::TWO_DASHES, 'L',
- N_("Add directory to search path"), N_("DIR"));
+ N_("Add directory to search path"), N_("DIR"));
DEFINE_bool(text_reorder, options::TWO_DASHES, '\0', true,
N_("Enable text section reordering for GCC section names "
@@ -919,19 +920,23 @@ class General_options
N_("Disable text section reordering for GCC section names"));
DEFINE_bool(nostdlib, options::ONE_DASH, '\0', false,
- N_(" Only search directories specified on the command line."),
- NULL);
+ N_("Only search directories specified on the command line."),
+ NULL);
DEFINE_bool(rosegment, options::TWO_DASHES, '\0', false,
- N_(" Put read-only non-executable sections in their own segment"),
- NULL);
+ N_("Put read-only non-executable sections in their own segment"),
+ NULL);
+
+ DEFINE_uint64(rosegment_gap, options::TWO_DASHES, '\0', -1U,
+ N_("Set offset between executable and read-only segments"),
+ N_("OFFSET"));
DEFINE_string(m, options::EXACTLY_ONE_DASH, 'm', "",
- N_("Set GNU linker emulation; obsolete"), N_("EMULATION"));
+ N_("Set GNU linker emulation; obsolete"), N_("EMULATION"));
DEFINE_bool(mmap_output_file, options::TWO_DASHES, '\0', true,
- N_("Map the output file for writing (default)."),
- N_("Do not map the output file for writing."));
+ N_("Map the output file for writing (default)."),
+ N_("Do not map the output file for writing."));
DEFINE_bool(print_map, options::TWO_DASHES, 'M', false,
N_("Write map file on standard output"), NULL);
@@ -956,10 +961,10 @@ class General_options
NULL, false);
DEFINE_string(output, options::TWO_DASHES, 'o', "a.out",
- N_("Set output file name"), N_("FILE"));
+ N_("Set output file name"), N_("FILE"));
DEFINE_uint(optimize, options::EXACTLY_ONE_DASH, 'O', 0,
- N_("Optimize output file size"), N_("LEVEL"));
+ N_("Optimize output file size"), N_("LEVEL"));
DEFINE_string(oformat, options::EXACTLY_TWO_DASHES, '\0', "elf",
N_("Set output format"), N_("[binary]"));
@@ -990,18 +995,18 @@ class General_options
#ifdef ENABLE_PLUGINS
DEFINE_special(plugin, options::TWO_DASHES, '\0',
- N_("Load a plugin library"), N_("PLUGIN"));
+ N_("Load a plugin library"), N_("PLUGIN"));
DEFINE_special(plugin_opt, options::TWO_DASHES, '\0',
- N_("Pass an option to the plugin"), N_("OPTION"));
+ N_("Pass an option to the plugin"), N_("OPTION"));
#endif
DEFINE_bool(posix_fallocate, options::TWO_DASHES, '\0', true,
- N_("Use posix_fallocate to reserve space in the output file"
+ N_("Use posix_fallocate to reserve space in the output file"
" (default)."),
- N_("Use fallocate or ftruncate to reserve space."));
+ N_("Use fallocate or ftruncate to reserve space."));
DEFINE_bool(preread_archive_symbols, options::TWO_DASHES, '\0', false,
- N_("Preread archive symbols when multi-threaded"), NULL);
+ N_("Preread archive symbols when multi-threaded"), NULL);
DEFINE_bool(print_output_format, options::TWO_DASHES, '\0', false,
N_("Print default output format"), NULL);
@@ -1014,10 +1019,10 @@ class General_options
N_("Ignored for SVR4 compatibility"), NULL);
DEFINE_bool(emit_relocs, options::TWO_DASHES, 'q', false,
- N_("Generate relocations in output"), NULL);
+ N_("Generate relocations in output"), NULL);
DEFINE_bool(relocatable, options::EXACTLY_ONE_DASH, 'r', false,
- N_("Generate relocatable output"), NULL);
+ N_("Generate relocatable output"), NULL);
DEFINE_bool_alias(i, relocatable, options::EXACTLY_ONE_DASH, '\0',
N_("Synonym for -r"), NULL, false);
@@ -1025,20 +1030,20 @@ class General_options
N_("Relax branches on certain targets"), NULL);
DEFINE_string(retain_symbols_file, options::TWO_DASHES, '\0', NULL,
- N_("keep only symbols listed in this file"), N_("FILE"));
+ N_("keep only symbols listed in this file"), N_("FILE"));
// -R really means -rpath, but can mean --just-symbols for
// compatibility with GNU ld. -rpath is always -rpath, so we list
// it separately.
DEFINE_special(R, options::EXACTLY_ONE_DASH, 'R',
- N_("Add DIR to runtime search path"), N_("DIR"));
+ N_("Add DIR to runtime search path"), N_("DIR"));
DEFINE_dirlist(rpath, options::ONE_DASH, '\0',
- N_("Add DIR to runtime search path"), N_("DIR"));
+ N_("Add DIR to runtime search path"), N_("DIR"));
DEFINE_dirlist(rpath_link, options::TWO_DASHES, '\0',
- N_("Add DIR to link time shared library search path"),
- N_("DIR"));
+ N_("Add DIR to link time shared library search path"),
+ N_("DIR"));
DEFINE_string(section_ordering_file, options::TWO_DASHES, '\0', NULL,
N_("Layout sections in the order specified."),
@@ -1056,33 +1061,33 @@ class General_options
N_("COUNT"));
DEFINE_bool(strip_all, options::TWO_DASHES, 's', false,
- N_("Strip all symbols"), NULL);
+ N_("Strip all symbols"), NULL);
DEFINE_bool(strip_debug, options::TWO_DASHES, 'S', false,
- N_("Strip debugging information"), NULL);
+ N_("Strip debugging information"), NULL);
DEFINE_bool(strip_debug_non_line, options::TWO_DASHES, '\0', false,
- N_("Emit only debug line number information"), NULL);
+ N_("Emit only debug line number information"), NULL);
DEFINE_bool(strip_debug_gdb, options::TWO_DASHES, '\0', false,
- N_("Strip debug symbols that are unused by gdb "
- "(at least versions <= 7.4)"), NULL);
+ N_("Strip debug symbols that are unused by gdb "
+ "(at least versions <= 7.4)"), NULL);
DEFINE_bool(strip_lto_sections, options::TWO_DASHES, '\0', true,
- N_("Strip LTO intermediate code sections"), NULL);
+ N_("Strip LTO intermediate code sections"), NULL);
DEFINE_int(stub_group_size, options::TWO_DASHES , '\0', 1,
- N_("(ARM, PowerPC only) The maximum distance from instructions "
+ N_("(ARM, PowerPC only) The maximum distance from instructions "
"in a group of sections to their stubs. Negative values mean "
"stubs are always after (PowerPC before) the group. 1 means "
"use default size.\n"),
N_("SIZE"));
DEFINE_bool(no_keep_memory, options::TWO_DASHES, '\0', false,
- N_("Use less memory and more disk I/O "
- "(included only for compatibility with GNU ld)"), NULL);
+ N_("Use less memory and more disk I/O "
+ "(included only for compatibility with GNU ld)"), NULL);
DEFINE_bool(shared, options::ONE_DASH, 'G', false,
- N_("Generate shared library"), NULL);
+ N_("Generate shared library"), NULL);
DEFINE_bool(Bshareable, options::ONE_DASH, '\0', false,
- N_("Generate shared library"), NULL);
+ N_("Generate shared library"), NULL);
DEFINE_uint(split_stack_adjust_size, options::TWO_DASHES, '\0', 0x4000,
N_("Stack size when -fsplit-stack function calls non-split"),
@@ -1091,63 +1096,63 @@ class General_options
// This is not actually special in any way, but I need to give it
// a non-standard accessor-function name because 'static' is a keyword.
DEFINE_special(static, options::ONE_DASH, '\0',
- N_("Do not link against shared libraries"), NULL);
+ N_("Do not link against shared libraries"), NULL);
DEFINE_enum(icf, options::TWO_DASHES, '\0', "none",
- N_("Identical Code Folding. "
- "\'--icf=safe\' Folds ctors, dtors and functions whose"
- " pointers are definitely not taken."),
- ("[none,all,safe]"),
- {"none", "all", "safe"});
+ N_("Identical Code Folding. "
+ "\'--icf=safe\' Folds ctors, dtors and functions whose"
+ " pointers are definitely not taken."),
+ ("[none,all,safe]"),
+ {"none", "all", "safe"});
DEFINE_uint(icf_iterations, options::TWO_DASHES , '\0', 0,
- N_("Number of iterations of ICF (default 2)"), N_("COUNT"));
+ N_("Number of iterations of ICF (default 2)"), N_("COUNT"));
DEFINE_bool(print_icf_sections, options::TWO_DASHES, '\0', false,
- N_("List folded identical sections on stderr"),
- N_("Do not list folded identical sections"));
+ N_("List folded identical sections on stderr"),
+ N_("Do not list folded identical sections"));
DEFINE_set(keep_unique, options::TWO_DASHES, '\0',
N_("Do not fold this symbol during ICF"), N_("SYMBOL"));
DEFINE_bool(gc_sections, options::TWO_DASHES, '\0', false,
- N_("Remove unused sections"),
- N_("Don't remove unused sections (default)"));
+ N_("Remove unused sections"),
+ N_("Don't remove unused sections (default)"));
DEFINE_bool(print_gc_sections, options::TWO_DASHES, '\0', false,
- N_("List removed unused sections on stderr"),
- N_("Do not list removed unused sections"));
+ N_("List removed unused sections on stderr"),
+ N_("Do not list removed unused sections"));
DEFINE_bool(stats, options::TWO_DASHES, '\0', false,
- N_("Print resource usage statistics"), NULL);
+ N_("Print resource usage statistics"), NULL);
DEFINE_string(sysroot, options::TWO_DASHES, '\0', "",
- N_("Set target system root directory"), N_("DIR"));
+ N_("Set target system root directory"), N_("DIR"));
DEFINE_bool(trace, options::TWO_DASHES, 't', false,
- N_("Print the name of each input file"), NULL);
+ N_("Print the name of each input file"), NULL);
DEFINE_special(script, options::TWO_DASHES, 'T',
- N_("Read linker script"), N_("FILE"));
+ N_("Read linker script"), N_("FILE"));
DEFINE_bool(threads, options::TWO_DASHES, '\0', false,
- N_("Run the linker multi-threaded"),
- N_("Do not run the linker multi-threaded"));
+ N_("Run the linker multi-threaded"),
+ N_("Do not run the linker multi-threaded"));
DEFINE_uint(thread_count, options::TWO_DASHES, '\0', 0,
- N_("Number of threads to use"), N_("COUNT"));
+ N_("Number of threads to use"), N_("COUNT"));
DEFINE_uint(thread_count_initial, options::TWO_DASHES, '\0', 0,
- N_("Number of threads to use in initial pass"), N_("COUNT"));
+ N_("Number of threads to use in initial pass"), N_("COUNT"));
DEFINE_uint(thread_count_middle, options::TWO_DASHES, '\0', 0,
- N_("Number of threads to use in middle pass"), N_("COUNT"));
+ N_("Number of threads to use in middle pass"), N_("COUNT"));
DEFINE_uint(thread_count_final, options::TWO_DASHES, '\0', 0,
- N_("Number of threads to use in final pass"), N_("COUNT"));
+ N_("Number of threads to use in final pass"), N_("COUNT"));
DEFINE_uint64(Tbss, options::ONE_DASH, '\0', -1U,
- N_("Set the address of the bss segment"), N_("ADDRESS"));
+ N_("Set the address of the bss segment"), N_("ADDRESS"));
DEFINE_uint64(Tdata, options::ONE_DASH, '\0', -1U,
- N_("Set the address of the data segment"), N_("ADDRESS"));
+ N_("Set the address of the data segment"), N_("ADDRESS"));
DEFINE_uint64(Ttext, options::ONE_DASH, '\0', -1U,
- N_("Set the address of the text segment"), N_("ADDRESS"));
+ N_("Set the address of the text segment"), N_("ADDRESS"));
DEFINE_uint64_alias(Ttext_segment, Ttext, options::ONE_DASH, '\0',
N_("Set the address of the text segment"),
N_("ADDRESS"));
@@ -1171,10 +1176,10 @@ class General_options
"ignore-in-shared-libs"});
DEFINE_bool(verbose, options::TWO_DASHES, '\0', false,
- N_("Synonym for --debug=files"), NULL);
+ N_("Synonym for --debug=files"), NULL);
DEFINE_special(version_script, options::TWO_DASHES, '\0',
- N_("Read version script"), N_("FILE"));
+ N_("Read version script"), N_("FILE"));
DEFINE_bool(warn_common, options::TWO_DASHES, '\0', false,
N_("Warn about duplicate common symbols"),
@@ -1214,14 +1219,14 @@ class General_options
"wchar_t sizes"));
DEFINE_bool(whole_archive, options::TWO_DASHES, '\0', false,
- N_("Include all archive contents"),
- N_("Include only needed archive contents"));
+ N_("Include all archive contents"),
+ N_("Include only needed archive contents"));
DEFINE_set(wrap, options::TWO_DASHES, '\0',
N_("Use wrapper functions for SYMBOL"), N_("SYMBOL"));
DEFINE_set(trace_symbol, options::TWO_DASHES, 'y',
- N_("Trace references to symbol"), N_("SYMBOL"));
+ N_("Trace references to symbol"), N_("SYMBOL"));
DEFINE_bool(undefined_version, options::TWO_DASHES, '\0', true,
N_("Allow unused version in script (default)"),
@@ -1232,15 +1237,15 @@ class General_options
N_("PATH"));
DEFINE_special(start_group, options::TWO_DASHES, '(',
- N_("Start a library search group"), NULL);
+ N_("Start a library search group"), NULL);
DEFINE_special(end_group, options::TWO_DASHES, ')',
- N_("End a library search group"), NULL);
+ N_("End a library search group"), NULL);
DEFINE_special(start_lib, options::TWO_DASHES, '\0',
- N_("Start a library"), NULL);
+ N_("Start a library"), NULL);
DEFINE_special(end_lib, options::TWO_DASHES, '\0',
- N_("End a library "), NULL);
+ N_("End a library "), NULL);
DEFINE_string(fuse_ld, options::ONE_DASH, '\0', "",
N_("Ignored for GCC linker option compatibility"),
@@ -1252,12 +1257,12 @@ class General_options
N_("Sort dynamic relocs"),
N_("Do not sort dynamic relocs"));
DEFINE_uint64(common_page_size, options::DASH_Z, '\0', 0,
- N_("Set common page size to SIZE"), N_("SIZE"));
+ N_("Set common page size to SIZE"), N_("SIZE"));
DEFINE_bool(defs, options::DASH_Z, '\0', false,
- N_("Report undefined symbols (even with --shared)"),
- NULL);
+ N_("Report undefined symbols (even with --shared)"),
+ NULL);
DEFINE_bool(execstack, options::DASH_Z, '\0', false,
- N_("Mark output as requiring executable stack"), NULL);
+ N_("Mark output as requiring executable stack"), NULL);
DEFINE_bool(initfirst, options::DASH_Z, '\0', false,
N_("Mark DSO to be initialized first at runtime"),
NULL);
@@ -1271,7 +1276,7 @@ class General_options
N_("Mark object requiring immediate process"),
NULL);
DEFINE_uint64(max_page_size, options::DASH_Z, '\0', 0,
- N_("Set maximum page size to SIZE"), N_("SIZE"));
+ N_("Set maximum page size to SIZE"), N_("SIZE"));
DEFINE_bool(muldefs, options::DASH_Z, '\0', false,
N_("Allow multiple definitions of symbols"),
NULL);
@@ -1293,13 +1298,13 @@ class General_options
N_("Mark DSO not available to dldump"),
NULL);
DEFINE_bool(noexecstack, options::DASH_Z, '\0', false,
- N_("Mark output as not requiring executable stack"), NULL);
+ N_("Mark output as not requiring executable stack"), NULL);
DEFINE_bool(now, options::DASH_Z, '\0', false,
N_("Mark object for immediate function binding"),
NULL);
DEFINE_bool(origin, options::DASH_Z, '\0', false,
N_("Mark DSO to indicate that needs immediate $ORIGIN "
- "processing at runtime"), NULL);
+ "processing at runtime"), NULL);
DEFINE_bool(relro, options::DASH_Z, '\0', false,
N_("Where possible mark variables read-only after relocation"),
N_("Don't mark variables read-only after relocation"));
@@ -1381,7 +1386,7 @@ class General_options
should_retain_symbol(const char* symbol_name) const
{
if (symbols_to_retain_.empty()) // means flag wasn't specified
- return true;
+ return true;
return symbols_to_retain_.find(symbol_name) != symbols_to_retain_.end();
}
@@ -1524,7 +1529,7 @@ class General_options
// Do not fold any functions (Default or --icf=none).
ICF_NONE,
// All functions are candidates for folding. (--icf=all).
- ICF_ALL,
+ ICF_ALL,
// Only ctors and dtors are candidates for folding. (--icf=safe).
ICF_SAFE
};
@@ -1617,7 +1622,7 @@ class General_options
type__ \
varname__() const \
{ return this->varname__##_; } \
- \
+ \
void \
set_##varname__(type__ value) \
{ this->varname__##_ = value; } \
@@ -1628,7 +1633,7 @@ class Position_dependent_options
{
public:
Position_dependent_options(const General_options& options
- = Position_dependent_options::default_options_)
+ = Position_dependent_options::default_options_)
{ copy_from_options(options); }
void copy_from_options(const General_options& options)
@@ -1685,9 +1690,9 @@ class Input_file_argument
{ }
Input_file_argument(const char* name, Input_file_type type,
- const char* extra_search_path,
- bool just_symbols,
- const Position_dependent_options& options)
+ const char* extra_search_path,
+ bool just_symbols,
+ const Position_dependent_options& options)
: name_(name), type_(type), extra_search_path_(extra_search_path),
just_symbols_(just_symbols), options_(options), arg_serial_(0)
{ }
@@ -1697,9 +1702,9 @@ class Input_file_argument
// position-independent vars from the General_options and only store
// those.
Input_file_argument(const char* name, Input_file_type type,
- const char* extra_search_path,
- bool just_symbols,
- const General_options& options)
+ const char* extra_search_path,
+ bool just_symbols,
+ const General_options& options)
: name_(name), type_(type), extra_search_path_(extra_search_path),
just_symbols_(just_symbols), options_(options), arg_serial_(0)
{ }
@@ -1724,8 +1729,8 @@ class Input_file_argument
extra_search_path() const
{
return (this->extra_search_path_.empty()
- ? NULL
- : this->extra_search_path_.c_str());
+ ? NULL
+ : this->extra_search_path_.c_str());
}
// Return whether we should only read symbols from this file.
@@ -2038,7 +2043,7 @@ class Command_line
// is set to true if argv[i] is "--".
int
process_one_option(int argc, const char** argv, int i,
- bool* no_more_options);
+ bool* no_more_options);
// Get the general options.
const General_options&
diff --git a/gold/output.cc b/gold/output.cc
index 22c0bf02b..75ce84093 100644
--- a/gold/output.cc
+++ b/gold/output.cc
@@ -2635,11 +2635,6 @@ Output_section::add_merge_input_section(Relobj* object, unsigned int shndx,
{
bool is_string = (flags & elfcpp::SHF_STRINGS) != 0;
- // We only merge strings if the alignment is not more than the
- // character size. This could be handled, but it's unusual.
- if (is_string && addralign > entsize)
- return false;
-
// We cannot restore merged input section states.
gold_assert(this->checkpoint_ == NULL);
diff --git a/gold/stringpool.cc b/gold/stringpool.cc
index 434b2d625..665fcc8ce 100644
--- a/gold/stringpool.cc
+++ b/gold/stringpool.cc
@@ -34,9 +34,10 @@ namespace gold
{
template<typename Stringpool_char>
-Stringpool_template<Stringpool_char>::Stringpool_template()
+Stringpool_template<Stringpool_char>::Stringpool_template(uint64_t addralign)
: string_set_(), key_to_offset_(), strings_(), strtab_size_(0),
- zero_null_(true), optimize_(false), offset_(sizeof(Stringpool_char))
+ zero_null_(true), optimize_(false), offset_(sizeof(Stringpool_char)),
+ addralign_(addralign)
{
if (parameters->options_valid() && parameters->options().optimize() >= 2)
this->optimize_ = true;
@@ -222,7 +223,10 @@ Stringpool_template<Stringpool_char>::new_key_offset(size_t length)
else
{
offset = this->offset_;
- this->offset_ += (length + 1) * sizeof(Stringpool_char);
+ // Align non-zero length strings.
+ if (length != 0)
+ offset = align_address(offset, this->addralign_);
+ this->offset_ = offset + (length + 1) * sizeof(Stringpool_char);
}
this->key_to_offset_.push_back(offset);
}
@@ -421,8 +425,8 @@ Stringpool_template<Stringpool_char>::set_string_offsets()
* charsize));
else
{
- this_offset = offset;
- offset += ((*curr)->first.length + 1) * charsize;
+ this_offset = align_address(offset, this->addralign_);
+ offset = this_offset + ((*curr)->first.length + 1) * charsize;
}
this->key_to_offset_[(*curr)->second - 1] = this_offset;
last_offset = this_offset;
diff --git a/gold/stringpool.h b/gold/stringpool.h
index c51b143be..b6383296a 100644
--- a/gold/stringpool.h
+++ b/gold/stringpool.h
@@ -180,7 +180,7 @@ class Stringpool_template
typedef size_t Key;
// Create a Stringpool.
- Stringpool_template();
+ Stringpool_template(uint64_t addralign = 1);
~Stringpool_template();
@@ -409,6 +409,8 @@ class Stringpool_template
bool optimize_;
// offset of the next string.
section_offset_type offset_;
+ // The alignment of strings in the stringpool.
+ uint64_t addralign_;
};
// The most common type of Stringpool.
diff --git a/gold/symtab.h b/gold/symtab.h
index 689d99f5b..9299ea8ab 100644
--- a/gold/symtab.h
+++ b/gold/symtab.h
@@ -817,6 +817,11 @@ class Symbol
is_predefined() const
{ return this->is_predefined_; }
+ // Return true if this is a C++ vtable symbol.
+ bool
+ is_cxx_vtable() const
+ { return is_prefix_of("_ZTV", this->name_); }
+
protected:
// Instances of this class should always be created at a specific
// size.
diff --git a/gold/target-reloc.h b/gold/target-reloc.h
index cf5e38956..b544c78f3 100644
--- a/gold/target-reloc.h
+++ b/gold/target-reloc.h
@@ -411,7 +411,13 @@ relocate_section(
}
if (issue_undefined_symbol_error(sym))
- gold_undefined_symbol_at_location(sym, relinfo, i, offset);
+ {
+ gold_undefined_symbol_at_location(sym, relinfo, i, offset);
+ if (sym->is_cxx_vtable())
+ gold_info(_("%s: the vtable symbol may be undefined because "
+ "the class is missing its key function"),
+ program_name);
+ }
else if (sym != NULL
&& sym->visibility() != elfcpp::STV_DEFAULT
&& (sym->is_undefined() || sym->is_from_dynobj()))
diff --git a/gold/testsuite/Makefile.am b/gold/testsuite/Makefile.am
index 4d0292569..4936e1488 100644
--- a/gold/testsuite/Makefile.am
+++ b/gold/testsuite/Makefile.am
@@ -53,26 +53,6 @@ TEST_AR = $(top_builddir)/../binutils/ar
TEST_NM = $(top_builddir)/../binutils/nm-new
TEST_AS = $(top_builddir)/../gas/as-new
-# Make the default target available to scripts as $DEFAULT_TARGET.
-if DEFAULT_TARGET_ARM
-export DEFAULT_TARGET = arm
-endif
-if DEFAULT_TARGET_I386
-export DEFAULT_TARGET = i386
-endif
-if DEFAULT_TARGET_POWERPC
-export DEFAULT_TARGET = powerpc
-endif
-if DEFAULT_TARGET_SPARC
-export DEFAULT_TARGET = sparc
-endif
-if DEFAULT_TARGET_X86_64
-export DEFAULT_TARGET = x86_64
-endif
-if DEFAULT_TARGET_TILEGX
-export DEFAULT_TARGET = tilegx
-endif
-
if PLUGINS
LIBDL = -ldl
endif
@@ -91,7 +71,10 @@ endif
# the right choice for files 'make' builds that people rebuild.
MOSTLYCLEANFILES = *.so *.syms *.stdout
-
+# Export make variables to the shell scripts so that they can see
+# (for example) DEFAULT_TARGET.
+.EXPORT_ALL_VARIABLES:
+
# We will add to these later, for each individual test. Note
# that we add each test under check_SCRIPTS or check_PROGRAMS;
# the TESTS variable is automatically populated from these.
@@ -329,6 +312,18 @@ icf_sht_rel_addend_test: icf_sht_rel_addend_test_1.o icf_sht_rel_addend_test_2.o
icf_sht_rel_addend_test.stdout: icf_sht_rel_addend_test
$(TEST_NM) icf_sht_rel_addend_test > icf_sht_rel_addend_test.stdout
+check_SCRIPTS += merge_string_literals.sh
+check_DATA += merge_string_literals.stdout
+MOSTLYCLEANFILES += merge_string_literals
+merge_string_literals_1.o: merge_string_literals_1.c
+ $(CXXCOMPILE) -O2 -c -fPIC -g -o $@ $<
+merge_string_literals_2.o: merge_string_literals_2.c
+ $(CXXCOMPILE) -O2 -c -fPIC -g -o $@ $<
+merge_string_literals: merge_string_literals_1.o merge_string_literals_2.o gcctestdir/ld
+ $(CXXLINK) -Bgcctestdir/ merge_string_literals_1.o merge_string_literals_2.o -O2 -shared -nostdlib
+merge_string_literals.stdout: merge_string_literals
+ $(TEST_OBJDUMP) -s -j.rodata merge_string_literals > merge_string_literals.stdout
+
check_PROGRAMS += basic_test
check_PROGRAMS += basic_pic_test
basic_test.o: basic_test.cc
@@ -979,6 +974,20 @@ debug_msg.err: debug_msg.o odr_violation1.o odr_violation2.o gcctestdir/ld
exit 1; \
fi
+# Test error message when a vtable is undefined.
+check_SCRIPTS += missing_key_func.sh
+check_DATA += missing_key_func.err
+MOSTLYCLEANFILES += missing_key_func.err
+missing_key_func.o: missing_key_func.cc
+ $(CXXCOMPILE) -O0 -g -c -o $@ $(srcdir)/missing_key_func.cc
+missing_key_func.err: missing_key_func.o gcctestdir/ld
+ @echo $(CXXLINK) -Bgcctestdir/ -o missing_key_func missing_key_func.o "2>$@"
+ @if $(CXXLINK) -Bgcctestdir/ -o missing_key_func missing_key_func.o 2>$@; \
+ then \
+ echo 1>&2 "Link of missing_key_func should have failed"; \
+ rm -f $@; \
+ exit 1; \
+ fi
if HAVE_ZLIB
diff --git a/gold/testsuite/Makefile.in b/gold/testsuite/Makefile.in
index fa9e80f83..495b7d06f 100644
--- a/gold/testsuite/Makefile.in
+++ b/gold/testsuite/Makefile.in
@@ -69,6 +69,8 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \
# Test --detect-odr-violations
+# Test error message when a vtable is undefined.
+
# Similar to --detect-odr-violations: check for undefined symbols in .so's
# Test --dynamic-list, --dynamic-list-data, --dynamic-list-cpp-new,
@@ -85,12 +87,13 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_preemptible_functions_test.sh \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_string_merge_test.sh \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_sht_rel_addend_test.sh \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ merge_string_literals.sh \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ two_file_shared.sh weak_plt.sh \
-@GCC_TRUE@@NATIVE_LINKER_TRUE@ debug_msg.sh undef_symbol.sh \
-@GCC_TRUE@@NATIVE_LINKER_TRUE@ ver_test_1.sh ver_test_2.sh \
-@GCC_TRUE@@NATIVE_LINKER_TRUE@ ver_test_4.sh ver_test_5.sh \
-@GCC_TRUE@@NATIVE_LINKER_TRUE@ ver_test_7.sh ver_test_10.sh \
-@GCC_TRUE@@NATIVE_LINKER_TRUE@ relro_test.sh \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ debug_msg.sh missing_key_func.sh \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ undef_symbol.sh ver_test_1.sh \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ ver_test_2.sh ver_test_4.sh \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ ver_test_5.sh ver_test_7.sh \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ ver_test_10.sh relro_test.sh \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ ver_matching_test.sh \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_3.sh \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_4.sh \
@@ -119,8 +122,10 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_preemptible_functions_test.stdout \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_string_merge_test.stdout \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_sht_rel_addend_test.stdout \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ merge_string_literals.stdout \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ two_file_shared.dbg \
-@GCC_TRUE@@NATIVE_LINKER_TRUE@ weak_plt_shared.so debug_msg.err
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ weak_plt_shared.so debug_msg.err \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ missing_key_func.err
@GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_4 = incremental_test \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ incremental_test.cmdline \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ gc_comdat_test gc_tls_test \
@@ -140,6 +145,7 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_preemptible_functions_test \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_string_merge_test \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_sht_rel_addend_test \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ merge_string_literals \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ two_file_shared.dbg \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ alt/weak_undef_lib.so
@GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_5 = icf_virtual_function_folding_test \
@@ -222,7 +228,8 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ many_sections_check.h
@GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_26 = many_sections_define.h \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ many_sections_check.h \
-@GCC_TRUE@@NATIVE_LINKER_TRUE@ debug_msg.err
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ debug_msg.err \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ missing_key_func.err
@GCC_FALSE@initpri1_DEPENDENCIES =
@NATIVE_LINKER_FALSE@initpri1_DEPENDENCIES =
@GCC_FALSE@initpri2_DEPENDENCIES =
@@ -1904,6 +1911,7 @@ CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DATADIRNAME = @DATADIRNAME@
+DEFAULT_TARGET = @DEFAULT_TARGET@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLOPEN_LIBS = @DLOPEN_LIBS@
@@ -3755,12 +3763,16 @@ icf_string_merge_test.sh.log: icf_string_merge_test.sh
@p='icf_string_merge_test.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
icf_sht_rel_addend_test.sh.log: icf_sht_rel_addend_test.sh
@p='icf_sht_rel_addend_test.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+merge_string_literals.sh.log: merge_string_literals.sh
+ @p='merge_string_literals.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
two_file_shared.sh.log: two_file_shared.sh
@p='two_file_shared.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
weak_plt.sh.log: weak_plt.sh
@p='weak_plt.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
debug_msg.sh.log: debug_msg.sh
@p='debug_msg.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+missing_key_func.sh.log: missing_key_func.sh
+ @p='missing_key_func.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
undef_symbol.sh.log: undef_symbol.sh
@p='undef_symbol.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
ver_test_1.sh.log: ver_test_1.sh
@@ -4296,13 +4308,9 @@ uninstall-am:
recheck recheck-html tags uninstall uninstall-am
-# Make the default target available to scripts as $DEFAULT_TARGET.
-@DEFAULT_TARGET_ARM_TRUE@export DEFAULT_TARGET = arm
-@DEFAULT_TARGET_I386_TRUE@export DEFAULT_TARGET = i386
-@DEFAULT_TARGET_POWERPC_TRUE@export DEFAULT_TARGET = powerpc
-@DEFAULT_TARGET_SPARC_TRUE@export DEFAULT_TARGET = sparc
-@DEFAULT_TARGET_X86_64_TRUE@export DEFAULT_TARGET = x86_64
-@DEFAULT_TARGET_TILEGX_TRUE@export DEFAULT_TARGET = tilegx
+# Export make variables to the shell scripts so that they can see
+# (for example) DEFAULT_TARGET.
+.EXPORT_ALL_VARIABLES:
# The unittests themselves
@@ -4440,6 +4448,14 @@ uninstall-am:
@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXLINK) -Bgcctestdir/ -Wl,--icf=all icf_sht_rel_addend_test_1.o icf_sht_rel_addend_test_2.o
@GCC_TRUE@@NATIVE_LINKER_TRUE@icf_sht_rel_addend_test.stdout: icf_sht_rel_addend_test
@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_NM) icf_sht_rel_addend_test > icf_sht_rel_addend_test.stdout
+@GCC_TRUE@@NATIVE_LINKER_TRUE@merge_string_literals_1.o: merge_string_literals_1.c
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXCOMPILE) -O2 -c -fPIC -g -o $@ $<
+@GCC_TRUE@@NATIVE_LINKER_TRUE@merge_string_literals_2.o: merge_string_literals_2.c
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXCOMPILE) -O2 -c -fPIC -g -o $@ $<
+@GCC_TRUE@@NATIVE_LINKER_TRUE@merge_string_literals: merge_string_literals_1.o merge_string_literals_2.o gcctestdir/ld
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXLINK) -Bgcctestdir/ merge_string_literals_1.o merge_string_literals_2.o -O2 -shared -nostdlib
+@GCC_TRUE@@NATIVE_LINKER_TRUE@merge_string_literals.stdout: merge_string_literals
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_OBJDUMP) -s -j.rodata merge_string_literals > merge_string_literals.stdout
@GCC_TRUE@@NATIVE_LINKER_TRUE@basic_test.o: basic_test.cc
@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXCOMPILE) -O0 -c -o $@ $<
@GCC_TRUE@@NATIVE_LINKER_TRUE@basic_test: basic_test.o gcctestdir/ld
@@ -4653,6 +4669,16 @@ uninstall-am:
@GCC_TRUE@@NATIVE_LINKER_TRUE@ rm -f $@; \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ exit 1; \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ fi
+@GCC_TRUE@@NATIVE_LINKER_TRUE@missing_key_func.o: missing_key_func.cc
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXCOMPILE) -O0 -g -c -o $@ $(srcdir)/missing_key_func.cc
+@GCC_TRUE@@NATIVE_LINKER_TRUE@missing_key_func.err: missing_key_func.o gcctestdir/ld
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ @echo $(CXXLINK) -Bgcctestdir/ -o missing_key_func missing_key_func.o "2>$@"
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ @if $(CXXLINK) -Bgcctestdir/ -o missing_key_func missing_key_func.o 2>$@; \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ then \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ echo 1>&2 "Link of missing_key_func should have failed"; \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ rm -f $@; \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ exit 1; \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ fi
@GCC_TRUE@@HAVE_ZLIB_TRUE@@NATIVE_LINKER_TRUE@debug_msg_cdebug.o: debug_msg.cc gcctestdir/as
@GCC_TRUE@@HAVE_ZLIB_TRUE@@NATIVE_LINKER_TRUE@ $(CXXCOMPILE) -Bgcctestdir/ -O0 -g -Wa,--compress-debug-sections -c -w -o $@ $(srcdir)/debug_msg.cc
@GCC_TRUE@@HAVE_ZLIB_TRUE@@NATIVE_LINKER_TRUE@odr_violation1_cdebug.o: odr_violation1.cc gcctestdir/as
diff --git a/gold/testsuite/debug_msg.sh b/gold/testsuite/debug_msg.sh
index c0d03b3d5..1227f3f07 100755
--- a/gold/testsuite/debug_msg.sh
+++ b/gold/testsuite/debug_msg.sh
@@ -2,7 +2,8 @@
# debug_msg.sh -- a test case for printing debug info for missing symbols.
-# Copyright 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+# Copyright 2006, 2007, 2008, 2009, 2010, 2011, 2013
+# Free Software Foundation, Inc.
# Written by Ian Lance Taylor <iant@google.com>.
# This file is part of gold.
@@ -55,9 +56,9 @@ check_missing()
# We don't know how the compiler might order these variables, so we
# can't test for the actual offset from .data, hence the regexp.
-check debug_msg.err "debug_msg.o:debug_msg.cc:function fn_array: error: undefined reference to 'undef_fn1()'"
-check debug_msg.err "debug_msg.o:debug_msg.cc:function fn_array: error: undefined reference to 'undef_fn2()'"
-check debug_msg.err "debug_msg.o:debug_msg.cc:function badref1: error: undefined reference to 'undef_int'"
+check debug_msg.err "debug_msg.o:debug_msg.cc:fn_array: error: undefined reference to 'undef_fn1()'"
+check debug_msg.err "debug_msg.o:debug_msg.cc:fn_array: error: undefined reference to 'undef_fn2()'"
+check debug_msg.err "debug_msg.o:debug_msg.cc:badref1: error: undefined reference to 'undef_int'"
# These tests check only for the source file's file name (not the complete
# path) because use of -fdebug-prefix-map may change the path to the source
@@ -66,10 +67,10 @@ check debug_msg.err ".*/debug_msg.cc:50: error: undefined reference to 'undef_fn
check debug_msg.err ".*/debug_msg.cc:55: error: undefined reference to 'undef_fn2()'"
check debug_msg.err ".*/debug_msg.cc:43: error: undefined reference to 'undef_fn1()'"
check debug_msg.err ".*/debug_msg.cc:44: error: undefined reference to 'undef_fn2()'"
-check debug_msg.err ".*/debug_msg.cc:.*: error: undefined reference to 'undef_int'"
-check debug_msg.err ".*/debug_msg.cc:43: error: undefined reference to 'undef_fn1()'"
-check debug_msg.err ".*/debug_msg.cc:44: error: undefined reference to 'undef_fn2()'"
-check debug_msg.err ".*/debug_msg.cc:.*: error: undefined reference to 'undef_int'"
+if test "$DEFAULT_TARGET" != "powerpc"
+then
+ check debug_msg.err ".*/debug_msg.cc:.*: error: undefined reference to 'undef_int'"
+fi
# Check we detected the ODR (One Definition Rule) violation.
check debug_msg.err ": symbol 'Ordering::operator()(int, int)' defined in multiple places (possible ODR violation):"
@@ -93,17 +94,17 @@ check debug_msg.err "odr_violation2.cc:27"
# Check for the same error messages when using --compressed-debug-sections.
if test -r debug_msg_cdebug.err
then
- check debug_msg_cdebug.err "debug_msg_cdebug.o:debug_msg.cc:function fn_array: error: undefined reference to 'undef_fn1()'"
- check debug_msg_cdebug.err "debug_msg_cdebug.o:debug_msg.cc:function fn_array: error: undefined reference to 'undef_fn2()'"
- check debug_msg_cdebug.err "debug_msg_cdebug.o:debug_msg.cc:function badref1: error: undefined reference to 'undef_int'"
+ check debug_msg_cdebug.err "debug_msg_cdebug.o:debug_msg.cc:fn_array: error: undefined reference to 'undef_fn1()'"
+ check debug_msg_cdebug.err "debug_msg_cdebug.o:debug_msg.cc:fn_array: error: undefined reference to 'undef_fn2()'"
+ check debug_msg_cdebug.err "debug_msg_cdebug.o:debug_msg.cc:badref1: error: undefined reference to 'undef_int'"
check debug_msg_cdebug.err ".*/debug_msg.cc:50: error: undefined reference to 'undef_fn1()'"
check debug_msg_cdebug.err ".*/debug_msg.cc:55: error: undefined reference to 'undef_fn2()'"
check debug_msg_cdebug.err ".*/debug_msg.cc:43: error: undefined reference to 'undef_fn1()'"
check debug_msg_cdebug.err ".*/debug_msg.cc:44: error: undefined reference to 'undef_fn2()'"
- check debug_msg_cdebug.err ".*/debug_msg.cc:.*: error: undefined reference to 'undef_int'"
- check debug_msg_cdebug.err ".*/debug_msg.cc:43: error: undefined reference to 'undef_fn1()'"
- check debug_msg_cdebug.err ".*/debug_msg.cc:44: error: undefined reference to 'undef_fn2()'"
- check debug_msg_cdebug.err ".*/debug_msg.cc:.*: error: undefined reference to 'undef_int'"
+ if test "$DEFAULT_TARGET" != "powerpc"
+ then
+ check debug_msg_cdebug.err ".*/debug_msg.cc:.*: error: undefined reference to 'undef_int'"
+ fi
check debug_msg_cdebug.err ": symbol 'Ordering::operator()(int, int)' defined in multiple places (possible ODR violation):"
check debug_msg_cdebug.err "odr_violation1.cc:6"
check debug_msg_cdebug.err "odr_violation2.cc:12"
diff --git a/gold/testsuite/merge_string_literals.sh b/gold/testsuite/merge_string_literals.sh
new file mode 100755
index 000000000..486a89596
--- /dev/null
+++ b/gold/testsuite/merge_string_literals.sh
@@ -0,0 +1,41 @@
+#!/bin/sh
+
+# merge_string_literals.sh -- test
+
+# Copyright 2013 Free Software Foundation, Inc.
+# Written by Alexander Ivchenko <alexander.ivchenko@intel.com>.
+
+# This file is part of gold.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+# MA 02110-1301, USA.
+
+# The goal of this program is to check whether string literals from different
+# object files are merged together
+
+set -e
+
+check()
+{
+ number_of_occurrence=`grep $2 ./$1 -o| wc -l`
+ if [ $number_of_occurrence != $3 ]
+ then
+ echo "String literals were not merged"
+ exit 1
+ fi
+}
+
+# If string literals were merged, then "abcd" appears two times
+check merge_string_literals.stdout "abcd" 2
diff --git a/gold/testsuite/merge_string_literals_1.c b/gold/testsuite/merge_string_literals_1.c
new file mode 100644
index 000000000..fc0487c3b
--- /dev/null
+++ b/gold/testsuite/merge_string_literals_1.c
@@ -0,0 +1,31 @@
+// merge_string_literals_1.c -- a test case for gold
+
+// Copyright 2013 Free Software Foundation, Inc.
+// Written by Alexander Ivchenko <alexander.ivchenko@intel.com>
+
+// This file is part of gold.
+
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+// MA 02110-1301, USA.
+
+// The goal of this program is to check whether string literals from different
+// object files are merged together
+
+const char* bar1() {
+ return "abcdefghijklmnopqrstuvwxyz0123456789";
+}
+const char* bar1_short() {
+ return "abcdef";
+}
diff --git a/gold/testsuite/merge_string_literals_2.c b/gold/testsuite/merge_string_literals_2.c
new file mode 100644
index 000000000..d1185cde1
--- /dev/null
+++ b/gold/testsuite/merge_string_literals_2.c
@@ -0,0 +1,31 @@
+// merge_string_literals_2.c -- a test case for gold
+
+// Copyright 2013 Free Software Foundation, Inc.
+// Written by Alexander Ivchenko <alexander.ivchenko@intel.com>
+
+// This file is part of gold.
+
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+// MA 02110-1301, USA.
+
+// The goal of this program is to check whether string literals from different
+// object files are merged together
+
+const char* bar2() {
+ return "abcdefghijklmnopqrstuvwxyz0123456789";
+}
+const char* bar2_short() {
+ return "abcdef";
+}
diff --git a/gold/testsuite/missing_key_func.cc b/gold/testsuite/missing_key_func.cc
new file mode 100644
index 000000000..5a5b7d954
--- /dev/null
+++ b/gold/testsuite/missing_key_func.cc
@@ -0,0 +1,46 @@
+// basic_test.cc -- a test case for gold
+
+// Copyright 2013 Free Software Foundation, Inc.
+// Written by Cary Coutant <ccoutant@google.com>.
+
+// This file is part of gold.
+
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+// MA 02110-1301, USA.
+
+// Define a class, but leave its key function undefined.
+
+class C
+{
+ public:
+ C() : c(1) { }
+ virtual void set();
+ virtual void clear();
+ int c;
+};
+
+void
+C::clear()
+{
+ c = 0;
+}
+
+int
+main()
+{
+ C c;
+ c.clear();
+ return c.c;
+}
diff --git a/gold/testsuite/missing_key_func.sh b/gold/testsuite/missing_key_func.sh
new file mode 100755
index 000000000..54c7b57be
--- /dev/null
+++ b/gold/testsuite/missing_key_func.sh
@@ -0,0 +1,58 @@
+#!/bin/sh
+
+# missing_key_func.sh -- a test case for printing error messages when
+# a class is missing its key function.
+
+# Copyright 2013 Free Software Foundation, Inc.
+# Written by Cary Coutant <ccoutant@google.com>
+
+# This file is part of gold.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+# MA 02110-1301, USA.
+
+# This file goes with debug_msg.cc, a C++ source file constructed to
+# have undefined references. We compile that file with debug
+# information and then try to link it, and make sure the proper errors
+# are displayed. The errors will be found in debug_msg.err.
+
+check()
+{
+ if ! grep -q "$2" "$1"
+ then
+ echo "Did not find expected error in $1:"
+ echo " $2"
+ echo ""
+ echo "Actual error output below:"
+ cat "$1"
+ exit 1
+ fi
+}
+
+check_missing()
+{
+ if grep -q "$2" "$1"
+ then
+ echo "Found unexpected error in $1:"
+ echo " $2"
+ echo ""
+ echo "Actual error output below:"
+ cat "$1"
+ exit 1
+ fi
+}
+
+check missing_key_func.err "error: undefined reference to 'vtable for C'"
+check missing_key_func.err "class is missing its key function"
diff --git a/gprof/ChangeLog b/gprof/ChangeLog
index 847c75f3c..d8556672c 100644
--- a/gprof/ChangeLog
+++ b/gprof/ChangeLog
@@ -1,3 +1,15 @@
+2013-05-24 Alan Modra <amodra@gmail.com>
+
+ * aarch64.c (aarch64_find_call): Promote to bfd_vma before sign
+ extending.
+
+2013-05-22 Venkataramanan Kumar <Venkataramanan.kumar@linaro.org>
+
+ * aarch64.c: New file.
+ * corefile.c (find_call): Call aarch64_find_call for bfd_arch_aarch64.
+ * Makefile.am (sources): Add aarch64.c.
+ * Makefile.in: Regenerate.
+
For older changes see ChangeLog-2012
Copyright (C) 2013 Free Software Foundation, Inc.
diff --git a/gprof/Makefile.am b/gprof/Makefile.am
index 0540793a9..97d8c1741 100644
--- a/gprof/Makefile.am
+++ b/gprof/Makefile.am
@@ -43,7 +43,7 @@ bin_PROGRAMS = gprof
sources = basic_blocks.c call_graph.c cg_arcs.c cg_dfn.c \
cg_print.c corefile.c gmon_io.c gprof.c hertz.c hist.c source.c \
search_list.c symtab.c sym_ids.c utils.c \
- i386.c alpha.c vax.c tahoe.c sparc.c mips.c
+ i386.c alpha.c vax.c tahoe.c sparc.c mips.c aarch64.c
gprof_SOURCES = $(sources) flat_bl.c bsd_callg_bl.c fsf_callg_bl.c
gprof_DEPENDENCIES = ../bfd/libbfd.la ../libiberty/libiberty.a $(LIBINTL_DEP)
gprof_LDADD = ../bfd/libbfd.la ../libiberty/libiberty.a $(LIBINTL)
diff --git a/gprof/Makefile.in b/gprof/Makefile.in
index c9f828e70..3a5bcdc55 100644
--- a/gprof/Makefile.in
+++ b/gprof/Makefile.in
@@ -92,7 +92,8 @@ am__objects_1 = basic_blocks.$(OBJEXT) call_graph.$(OBJEXT) \
hertz.$(OBJEXT) hist.$(OBJEXT) source.$(OBJEXT) \
search_list.$(OBJEXT) symtab.$(OBJEXT) sym_ids.$(OBJEXT) \
utils.$(OBJEXT) i386.$(OBJEXT) alpha.$(OBJEXT) vax.$(OBJEXT) \
- tahoe.$(OBJEXT) sparc.$(OBJEXT) mips.$(OBJEXT)
+ tahoe.$(OBJEXT) sparc.$(OBJEXT) mips.$(OBJEXT) \
+ aarch64.$(OBJEXT)
am_gprof_OBJECTS = $(am__objects_1) flat_bl.$(OBJEXT) \
bsd_callg_bl.$(OBJEXT) fsf_callg_bl.$(OBJEXT)
gprof_OBJECTS = $(am_gprof_OBJECTS)
@@ -309,7 +310,7 @@ AM_CPPFLAGS = -DDEBUG -I../bfd -I$(srcdir)/../include \
sources = basic_blocks.c call_graph.c cg_arcs.c cg_dfn.c \
cg_print.c corefile.c gmon_io.c gprof.c hertz.c hist.c source.c \
search_list.c symtab.c sym_ids.c utils.c \
- i386.c alpha.c vax.c tahoe.c sparc.c mips.c
+ i386.c alpha.c vax.c tahoe.c sparc.c mips.c aarch64.c
gprof_SOURCES = $(sources) flat_bl.c bsd_callg_bl.c fsf_callg_bl.c
gprof_DEPENDENCIES = ../bfd/libbfd.la ../libiberty/libiberty.a $(LIBINTL_DEP)
@@ -451,6 +452,7 @@ mostlyclean-compile:
distclean-compile:
-rm -f *.tab.c
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aarch64.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alpha.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/basic_blocks.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bsd_callg_bl.Po@am__quote@
diff --git a/gprof/aarch64.c b/gprof/aarch64.c
new file mode 100644
index 000000000..68febf937
--- /dev/null
+++ b/gprof/aarch64.c
@@ -0,0 +1,99 @@
+/* Gprof -c option support for AArch64.
+ Copyright 2013 Linaro Ltd.
+
+ Based upon gprof/i386.c.
+
+ Copyright (c) 1983, 1993, 2001
+ The Regents of the University of California. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE. */
+
+#include "gprof.h"
+#include "search_list.h"
+#include "source.h"
+#include "symtab.h"
+#include "cg_arcs.h"
+#include "corefile.h"
+#include "hist.h"
+
+#define BRANCH_MASK 0x7c000000
+#define BRANCH_PATTERN 0x14000000
+
+void aarch64_find_call (Sym *, bfd_vma, bfd_vma);
+
+void
+aarch64_find_call (Sym *parent, bfd_vma p_lowpc, bfd_vma p_highpc)
+{
+ bfd_vma pc, dest_pc, offset;
+ unsigned int insn;
+ Sym *child;
+
+ DBG (CALLDEBUG, printf ("[find_call] %s: 0x%lx to 0x%lx\n",
+ parent->name, (unsigned long) p_lowpc,
+ (unsigned long) p_highpc));
+
+ for (pc = p_lowpc; pc < p_highpc; pc += 4)
+ {
+
+ insn = bfd_get_32 (core_bfd, ((unsigned char *) core_text_space
+ + pc - core_text_sect->vma));
+
+ if ((insn & BRANCH_MASK) == BRANCH_PATTERN)
+ {
+ DBG (CALLDEBUG,
+ printf ("[find_call] 0x%lx: bl", (unsigned long) pc));
+
+ /* Regular pc relative addressing check that this is the
+ address of a function. */
+ offset = ((((bfd_vma) insn & 0x3ffffff) ^ 0x2000000) - 0x2000000) << 2;
+
+ dest_pc = pc + offset;
+
+ if (hist_check_address (dest_pc))
+ {
+ child = sym_lookup (&symtab, dest_pc);
+
+ if (child)
+ {
+ DBG (CALLDEBUG,
+ printf ("\tdest_pc=0x%lx, (name=%s, addr=0x%lx)\n",
+ (unsigned long) dest_pc, child->name,
+ (unsigned long) child->addr));
+
+ if (child->addr == dest_pc)
+ {
+ /* a hit. */
+ arc_add (parent, child, (unsigned long) 0);
+ continue;
+ }
+ }
+ }
+
+ /* Something funny going on. */
+ DBG (CALLDEBUG, printf ("\tbut it's a botch\n"));
+ }
+ }
+}
diff --git a/gprof/corefile.c b/gprof/corefile.c
index 985ea2684..0aabbadeb 100644
--- a/gprof/corefile.c
+++ b/gprof/corefile.c
@@ -54,6 +54,7 @@ extern void vax_find_call (Sym *, bfd_vma, bfd_vma);
extern void tahoe_find_call (Sym *, bfd_vma, bfd_vma);
extern void sparc_find_call (Sym *, bfd_vma, bfd_vma);
extern void mips_find_call (Sym *, bfd_vma, bfd_vma);
+extern void aarch64_find_call (Sym *, bfd_vma, bfd_vma);
static void
parse_error (const char *filename)
@@ -320,6 +321,10 @@ find_call (Sym *parent, bfd_vma p_lowpc, bfd_vma p_highpc)
mips_find_call (parent, p_lowpc, p_highpc);
break;
+ case bfd_arch_aarch64:
+ aarch64_find_call (parent, p_lowpc, p_highpc);
+ break;
+
default:
fprintf (stderr, _("%s: -c not supported on architecture %s\n"),
whoami, bfd_printable_name(core_bfd));
diff --git a/include/ChangeLog b/include/ChangeLog
index f084976f3..4d02320bc 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,8 @@
+2013-05-06 Paul Brook <paul@codesourcery.com>
+
+ include/elf/
+ * mips.h (R_MIPS_PC32): Update comment.
+
2013-04-03 Jason Merrill <jason@redhat.com>
Demangle C++11 ref-qualifier.
diff --git a/include/elf/ChangeLog b/include/elf/ChangeLog
index c72659207..2263307f4 100644
--- a/include/elf/ChangeLog
+++ b/include/elf/ChangeLog
@@ -1,3 +1,17 @@
+2013-05-22 H.J. Lu <hongjiu.lu@intel.com>
+
+ * common.h (EM_INTEL205): New.
+ (EM_INTEL206): Likewise.
+ (EM_INTEL207): Likewise.
+ (EM_INTEL208): Likewise.
+ (EM_INTEL209): Likewise.
+
+2013-05-02 Nick Clifton <nickc@redhat.com>
+
+ * msp430.h: Add MSP430X relocs.
+ Add some more MSP430 machine numbers.
+ Add values used by .MSP430.attributes section.
+
2013-03-21 Michael Schewe <michael.schewe@gmx.net>
* h8.h: Add new reloc R_H8_DISP32A16 for relaxation of
diff --git a/include/elf/common.h b/include/elf/common.h
index 697a6e663..decd37f87 100644
--- a/include/elf/common.h
+++ b/include/elf/common.h
@@ -296,6 +296,11 @@
#define EM_TILEGX 191 /* Tilera TILE-Gx multicore architecture family */
#define EM_RL78 197 /* Renesas RL78 family. */
#define EM_78K0R 199 /* Renesas 78K0R. */
+#define EM_INTEL205 205 /* Reserved by Intel */
+#define EM_INTEL206 206 /* Reserved by Intel */
+#define EM_INTEL207 207 /* Reserved by Intel */
+#define EM_INTEL208 208 /* Reserved by Intel */
+#define EM_INTEL209 209 /* Reserved by Intel */
/* If it is necessary to assign new unofficial EM_* values, please pick large
random numbers (0x8523, 0xa7f2, etc.) to minimize the chances of collision
diff --git a/include/elf/mips.h b/include/elf/mips.h
index ca9fdcd78..493bbfd21 100644
--- a/include/elf/mips.h
+++ b/include/elf/mips.h
@@ -152,9 +152,8 @@ START_RELOC_NUMBERS (elf_mips_reloc_type)
FAKE_RELOC (R_MICROMIPS_max, 174)
/* This was a GNU extension used by embedded-PIC. It was co-opted by
- mips-linux for exception-handling data. It is no longer used, but
- should continue to be supported by the linker for backward
- compatibility. (GCC stopped using it in May, 2004.) */
+ mips-linux for exception-handling data. GCC stopped using it in
+ May, 2004, then started using it again for compact unwind tables. */
RELOC_NUMBER (R_MIPS_PC32, 248)
/* FIXME: this relocation is used internally by gas. */
RELOC_NUMBER (R_MIPS_GNU_REL16_S2, 250)
diff --git a/include/elf/msp430.h b/include/elf/msp430.h
index 44f5c51a7..ac8e28c31 100644
--- a/include/elf/msp430.h
+++ b/include/elf/msp430.h
@@ -1,5 +1,5 @@
/* MSP430 ELF support for BFD.
- Copyright (C) 2002, 2003, 2004, 2010 Free Software Foundation, Inc.
+ Copyright (C) 2002-2013 Free Software Foundation, Inc.
Contributed by Dmitry Diky <diwil@mail.ru>
This file is part of BFD, the Binary File Descriptor library.
@@ -33,6 +33,11 @@
#define E_MSP430_MACH_MSP430x14 14
#define E_MSP430_MACH_MSP430x15 15
#define E_MSP430_MACH_MSP430x16 16
+#define E_MSP430_MACH_MSP430x20 20
+#define E_MSP430_MACH_MSP430x22 22
+#define E_MSP430_MACH_MSP430x23 23
+#define E_MSP430_MACH_MSP430x24 24
+#define E_MSP430_MACH_MSP430x26 26
#define E_MSP430_MACH_MSP430x31 31
#define E_MSP430_MACH_MSP430x32 32
#define E_MSP430_MACH_MSP430x33 33
@@ -40,6 +45,19 @@
#define E_MSP430_MACH_MSP430x42 42
#define E_MSP430_MACH_MSP430x43 43
#define E_MSP430_MACH_MSP430x44 44
+#define E_MSP430_MACH_MSP430X 45
+#define E_MSP430_MACH_MSP430x46 46
+#define E_MSP430_MACH_MSP430x47 47
+#define E_MSP430_MACH_MSP430x54 54
+
+#define SHT_MSP430_ATTRIBUTES 0x70000003 /* Section holds ABI attributes. */
+#define SHT_MSP430_SEC_FLAGS 0x7f000005 /* Holds TI compiler's section flags. */
+#define SHT_MSP430_SYM_ALIASES 0x7f000006 /* Holds TI compiler's symbol aliases. */
+
+/* Tag values for an attribute section. */
+#define OFBA_MSPABI_Tag_ISA 4
+#define OFBA_MSPABI_Tag_Code_Model 6
+#define OFBA_MSPABI_Tag_Data_Model 8
/* Relocations. */
START_RELOC_NUMBERS (elf_msp430_reloc_type)
@@ -52,7 +70,32 @@ START_RELOC_NUMBERS (elf_msp430_reloc_type)
RELOC_NUMBER (R_MSP430_16_PCREL_BYTE, 6)
RELOC_NUMBER (R_MSP430_2X_PCREL, 7)
RELOC_NUMBER (R_MSP430_RL_PCREL, 8)
-
+ RELOC_NUMBER (R_MSP430_8, 9)
+ RELOC_NUMBER (R_MSP430_SYM_DIFF, 10)
END_RELOC_NUMBERS (R_MSP430_max)
+START_RELOC_NUMBERS (elf_msp430x_reloc_type)
+ RELOC_NUMBER (R_MSP430_ABS32, 1) /* aka R_MSP430_32 */
+ RELOC_NUMBER (R_MSP430_ABS16, 2) /* aka R_MSP430_16 */
+ RELOC_NUMBER (R_MSP430_ABS8, 3)
+ RELOC_NUMBER (R_MSP430_PCR16, 4) /* aka R_MSP430_16_PCREL */
+ RELOC_NUMBER (R_MSP430X_PCR20_EXT_SRC, 5)
+ RELOC_NUMBER (R_MSP430X_PCR20_EXT_DST, 6)
+ RELOC_NUMBER (R_MSP430X_PCR20_EXT_ODST, 7)
+ RELOC_NUMBER (R_MSP430X_ABS20_EXT_SRC, 8)
+ RELOC_NUMBER (R_MSP430X_ABS20_EXT_DST, 9)
+ RELOC_NUMBER (R_MSP430X_ABS20_EXT_ODST, 10)
+ RELOC_NUMBER (R_MSP430X_ABS20_ADR_SRC, 11)
+ RELOC_NUMBER (R_MSP430X_ABS20_ADR_DST, 12)
+ RELOC_NUMBER (R_MSP430X_PCR16, 13) /* Like R_MSP430_PCR16 but with overflow checking. */
+ RELOC_NUMBER (R_MSP430X_PCR20_CALL, 14)
+ RELOC_NUMBER (R_MSP430X_ABS16, 15) /* Like R_MSP430_ABS16 but with overflow checking. */
+ RELOC_NUMBER (R_MSP430_ABS_HI16, 16)
+ RELOC_NUMBER (R_MSP430_PREL31, 17)
+ RELOC_NUMBER (R_MSP430_EHTYPE, 18) /* Mentioned in ABI. */
+ RELOC_NUMBER (R_MSP430X_10_PCREL, 19) /* Red Hat invention. Used for Jump instructions. */
+ RELOC_NUMBER (R_MSP430X_2X_PCREL, 20) /* Red Hat invention. Used for relaxing jumps. */
+ RELOC_NUMBER (R_MSP430X_SYM_DIFF, 21) /* Red Hat invention. Used for relaxing debug info. */
+END_RELOC_NUMBERS (R_MSP430x_max)
+
#endif /* _ELF_MSP430_H */
diff --git a/include/opcode/ChangeLog b/include/opcode/ChangeLog
index 9eed10498..7ed2c6874 100644
--- a/include/opcode/ChangeLog
+++ b/include/opcode/ChangeLog
@@ -1,3 +1,20 @@
+2013-05-22 Jürgen Urban <JuergenUrban@gmx.de>
+
+ * mips.h (M_LQC2_AB, M_SQC2_AB): New macros.
+
+2013-05-09 Andrew Pinski <apinski@cavium.com>
+
+ * mips.h (OP_MASK_CODE10): Correct definition.
+ (OP_SH_CODE10): Likewise.
+ Add a comment that "+J" is used now for OP_*CODE10.
+ (INSN_ASE_MASK): Update.
+ (INSN_VIRT): New macro.
+ (INSN_VIRT64): New macro
+
+2013-05-02 Nick Clifton <nickc@redhat.com>
+
+ * msp430.h: Add patterns for MSP430X instructions.
+
2013-04-06 David S. Miller <davem@davemloft.net>
* sparc.h (F_PREFERRED): Define.
diff --git a/include/opcode/mips.h b/include/opcode/mips.h
index ef81bbe2b..07259ea06 100644
--- a/include/opcode/mips.h
+++ b/include/opcode/mips.h
@@ -212,6 +212,10 @@
#define OP_OP_SDC2 0x3e
#define OP_OP_SDC3 0x3f /* a.k.a. sd */
+/* MIPS VIRT ASE */
+#define OP_MASK_CODE10 0x3ff
+#define OP_SH_CODE10 11
+
/* Values in the 'VSEL' field. */
#define MDMX_FMTSEL_IMM_QH 0x1d
#define MDMX_FMTSEL_IMM_OB 0x1e
@@ -255,8 +259,6 @@
of the operand handling in GAS. The fields below only exist
in the microMIPS encoding, so define each one to have an empty
range. */
-#define OP_MASK_CODE10 0
-#define OP_SH_CODE10 0
#define OP_MASK_TRAP 0
#define OP_SH_TRAP 0
#define OP_MASK_OFFSET10 0
@@ -486,6 +488,9 @@ struct mips_opcode
"~" 12 bit offset (OP_*_OFFSET12)
"\" 3 bit position for aset and aclr (OP_*_3BITPOS)
+ VIRT ASE usage:
+ "+J" 10-bit hypcall code (OP_*CODE10)
+
UDI immediates:
"+1" UDI immediate bits 6-10
"+2" UDI immediate bits 6-15
@@ -528,7 +533,7 @@ struct mips_opcode
Extension character sequences used so far ("+" followed by the
following), for quick reference when adding more:
"1234"
- "ABCDEFGHIPQSTXZ"
+ "ABCDEFGHIJPQSTXZ"
"abcpstxz"
*/
@@ -726,7 +731,7 @@ static const unsigned int mips_isa_table[] =
#define INSN_OCTEON2 0x00000100
/* Masks used for MIPS-defined ASEs. */
-#define INSN_ASE_MASK 0x3c00f010
+#define INSN_ASE_MASK 0x3c00f0d0
/* DSP ASE */
#define INSN_DSP 0x00001000
@@ -735,6 +740,10 @@ static const unsigned int mips_isa_table[] =
/* MIPS R5900 instruction */
#define INSN_5900 0x00004000
+/* Virtualization ASE */
+#define INSN_VIRT 0x00000080
+#define INSN_VIRT64 0x00000040
+
/* MIPS-3D ASE */
#define INSN_MIPS3D 0x00008000
@@ -1061,6 +1070,7 @@ enum
M_LDC1_AB,
M_LDC2_AB,
M_LDC2_OB,
+ M_LQC2_AB,
M_LDC3_AB,
M_LDL_AB,
M_LDL_OB,
@@ -1154,6 +1164,7 @@ enum
M_SDC1_AB,
M_SDC2_AB,
M_SDC2_OB,
+ M_SQC2_AB,
M_SDC3_AB,
M_SDL_AB,
M_SDL_OB,
diff --git a/include/opcode/msp430.h b/include/opcode/msp430.h
index d3bf130ee..caddc42db 100644
--- a/include/opcode/msp430.h
+++ b/include/opcode/msp430.h
@@ -1,6 +1,6 @@
/* Opcode table for the TI MSP430 microcontrollers
- Copyright 2002, 2004, 2010 Free Software Foundation, Inc.
+ Copyright 2002-2013 Free Software Foundation, Inc.
Contributed by Dmitry Diky <diwil@mail.ru>
This program is free software; you can redistribute it and/or modify
@@ -119,6 +119,74 @@ static struct msp430_opcode_s msp430_opcodes[] =
MSP_INSN (bleu, 5, 2, 0, 0xffff),
MSP_INSN (ble, 5, 3, 0, 0xffff),
+ /* MSP430X instructions - these ones use an extension word.
+ A negative format indicates an MSP430X instruction. */
+ MSP_INSN (addcx, -2, 2, 0x6000, 0xf000),
+ MSP_INSN (addx, -2, 2, 0x5000, 0xf000),
+ MSP_INSN (andx, -2, 2, 0xf000, 0xf000),
+ MSP_INSN (bicx, -2, 2, 0xc000, 0xf000),
+ MSP_INSN (bisx, -2, 2, 0xd000, 0xf000),
+ MSP_INSN (bitx, -2, 2, 0xb000, 0xf000),
+ MSP_INSN (cmpx, -2, 2, 0x9000, 0xf000),
+ MSP_INSN (daddx, -2, 2, 0xa000, 0xf000),
+ MSP_INSN (movx, -2, 2, 0x4000, 0xf000),
+ MSP_INSN (subcx, -2, 2, 0x7000, 0xf000),
+ MSP_INSN (subx, -2, 2, 0x8000, 0xf000),
+ MSP_INSN (xorx, -2, 2, 0xe000, 0xf000),
+
+ /* MSP430X Synthetic instructions. */
+ MSP_INSN (adcx, -1, 1, 0x6300, 0xff30),
+ MSP_INSN (clra, -1, 1, 0x4300, 0xff30),
+ MSP_INSN (clrx, -1, 1, 0x4300, 0xff30),
+ MSP_INSN (dadcx, -1, 1, 0xa300, 0xff30),
+ MSP_INSN (decx, -1, 1, 0x8310, 0xff30),
+ MSP_INSN (decda, -1, 1, 0x8320, 0xff30),
+ MSP_INSN (decdx, -1, 1, 0x8320, 0xff30),
+ MSP_INSN (incx, -1, 1, 0x5310, 0xff30),
+ MSP_INSN (incda, -1, 1, 0x5320, 0xff30),
+ MSP_INSN (incdx, -1, 1, 0x5320, 0xff30),
+ MSP_INSN (invx, -1, 1, 0xe330, 0xfff0),
+ MSP_INSN (popx, -1, 1, 0x4130, 0xff30),
+ MSP_INSN (rlax, -1, 2, 0x5000, 0xf000),
+ MSP_INSN (rlcx, -1, 2, 0x6000, 0xf000),
+ MSP_INSN (sbcx, -1, 1, 0x7300, 0xff30),
+ MSP_INSN (tsta, -1, 1, 0x9300, 0xff30),
+ MSP_INSN (tstx, -1, 1, 0x9300, 0xff30),
+
+ MSP_INSN (pushx, -3, 1, 0x1200, 0xff80),
+ MSP_INSN (rrax, -3, 1, 0x1100, 0xff80),
+ MSP_INSN (rrcx, -3, 1, 0x1000, 0xff80),
+ MSP_INSN (swpbx, -3, 1, 0x1080, 0xffc0),
+ MSP_INSN (sxtx, -3, 1, 0x1180, 0xffc0),
+
+ /* MSP430X Address instructions - no extension word needed.
+ The insn_opnumb field is used to encode the nature of the
+ instruction for assembly and disassembly purposes. */
+ MSP_INSN (calla, -1, 4, 0x1300, 0xff00),
+
+ MSP_INSN (popm, -1, 5, 0x1600, 0xfe00),
+ MSP_INSN (pushm, -1, 5, 0x1400, 0xfe00),
+
+ MSP_INSN (rrcm, -1, 6, 0x0040, 0xf3e0),
+ MSP_INSN (rram, -1, 6, 0x0140, 0xf3e0),
+ MSP_INSN (rlam, -1, 6, 0x0240, 0xf3e0),
+ MSP_INSN (rrum, -1, 6, 0x0340, 0xf3e0),
+
+ MSP_INSN (rrux, -1, 7, 0x0340, 0xffe0), /* Synthesized in terms of RRUM. */
+
+ MSP_INSN (adda, -1, 8, 0x00a0, 0xf0b0),
+ MSP_INSN (cmpa, -1, 8, 0x0090, 0xf0b0),
+ MSP_INSN (suba, -1, 8, 0x00b0, 0xf0b0),
+
+ MSP_INSN (reta, -1, 9, 0x0110, 0xffff),
+ MSP_INSN (bra, -1, 9, 0x0000, 0xf0cf),
+ MSP_INSN (mova, -1, 9, 0x0000, 0xf080),
+ MSP_INSN (mova, -1, 9, 0x0080, 0xf0b0),
+ MSP_INSN (mova, -1, 9, 0x00c0, 0xf0f0),
+
+ /* Pseudo instruction to set the repeat field in the extension word. */
+ MSP_INSN (rpt, -1, 10, 0x0000, 0x0000),
+
/* End of instruction set. */
{ NULL, 0, 0, 0, 0 }
};
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 7317e4388..e41c4dd14 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,46 @@
+2013-05-03 Alan Modra <amodra@gmail.com>
+
+ PR ld/15365
+ * emultempl/elf32.em (gld${EMULATION_NAME}_before_allocation):
+ Restrict __ehdr_start's export class to no less than STV_HIDDEN.
+
+2013-05-03 Alan Modra <amodra@gmail.com>
+
+ * emultempl/elf32.em (gld${EMULATION_NAME}_before_allocation):
+ Only call lang_for_each_statement if an ELF hash table is used.
+
+2013-05-02 Nick Clifton <nickc@redhat.com>
+
+ * Makefile.am: Add emsp430X.c
+ * Makefine.in: Regenerate.
+ * configure.tgt (msp430): Add msp430X emulation.
+ * ldmain.c (multiple_definition): Only disable relaxation if it
+ was enabled by the user.
+ * ldmain.h (RELAXATION_ENABLED_BY_USER): New macro.
+ * emulparams/msp430all.sh: Add support for MSP430X.
+ * emultempl/generic.em: (before_parse): Enable relaxation for the
+ MSP430.
+ * scripttempl/msp430.sc: Reorganize sections. Add .rodata
+ section.
+ * scripttempl/msp430_3.sc: Likewise.
+ * NEWS: Mention support for MSP430X.
+
+2013-05-01 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * configure.tgt: Replace alpha*-*-linuxecoff* pattern with
+ alpha*-*-linux*ecoff*. Update the `sed' pattern used to convert
+ from alpha*-*-linux-* to alpha*-*-linux*ecoff*.
+
+2013-05-01 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * emultempl/elf32.em (gld${EMULATION_NAME}_before_allocation):
+ Use is_elf_hash_table rather than a handcoded condition.
+
+2013-04-30 Nick Clifton <nickc@redhat.com>
+
+ * ld.texinfo (SORT_BY_ALIGNMENT): Fix and clarify typo - sections
+ are sorted by descending order of alignment.
+
2013-04-29 Nick Clifton <nickc@redhat.com>
* scripttempl/DWARF.sc: Add support for .debug_line.* and
diff --git a/ld/Makefile.am b/ld/Makefile.am
index e0366f366..0eba8a9d3 100644
--- a/ld/Makefile.am
+++ b/ld/Makefile.am
@@ -424,6 +424,7 @@ ALL_EMULATION_SOURCES = \
emsp430xW423.c \
emsp430xW425.c \
emsp430xW427.c \
+ emsp430X.c \
enews.c \
ens32knbsd.c \
eor32.c \
@@ -1773,6 +1774,10 @@ emsp430xW427.c: $(srcdir)/emulparams/msp430all.sh \
$(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
${GEN_DEPENDS}
${GENSCRIPTS} msp430xW427 "$(tdir_msp430xW427)" msp430all
+emsp430X.c: $(srcdir)/emulparams/msp430all.sh \
+ $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
+ ${GEN_DEPENDS}
+ ${GENSCRIPTS} msp430X "$(tdir_msp430X)" msp430all
enews.c: $(srcdir)/emulparams/news.sh \
$(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
${GENSCRIPTS} news "$(tdir_news)"
diff --git a/ld/Makefile.in b/ld/Makefile.in
index 042e9f23a..9140c7350 100644
--- a/ld/Makefile.in
+++ b/ld/Makefile.in
@@ -732,6 +732,7 @@ ALL_EMULATION_SOURCES = \
emsp430xW423.c \
emsp430xW425.c \
emsp430xW427.c \
+ emsp430X.c \
enews.c \
ens32knbsd.c \
eor32.c \
@@ -1343,6 +1344,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emmo.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emn10200.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emn10300.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430X.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x110.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x1101.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x1111.Po@am__quote@
@@ -3259,6 +3261,10 @@ emsp430xW427.c: $(srcdir)/emulparams/msp430all.sh \
$(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
${GEN_DEPENDS}
${GENSCRIPTS} msp430xW427 "$(tdir_msp430xW427)" msp430all
+emsp430X.c: $(srcdir)/emulparams/msp430all.sh \
+ $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
+ ${GEN_DEPENDS}
+ ${GENSCRIPTS} msp430X "$(tdir_msp430X)" msp430all
enews.c: $(srcdir)/emulparams/news.sh \
$(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
${GENSCRIPTS} news "$(tdir_news)"
diff --git a/ld/NEWS b/ld/NEWS
index 5217e4c7c..fa11d2d9f 100644
--- a/ld/NEWS
+++ b/ld/NEWS
@@ -1,5 +1,7 @@
-*- text -*-
+* Add support for the Texas Instruments MSP430X processor.
+
* Add support for Altera Nios II.
* Add support for the V850E3V5 architecture.
diff --git a/ld/configure.tgt b/ld/configure.tgt
index 65884fae8..56945808c 100644
--- a/ld/configure.tgt
+++ b/ld/configure.tgt
@@ -57,10 +57,10 @@ alpha*-*-freebsd* | alpha*-*-kfreebsd*-gnu)
targ_emul=elf64alpha_fbsd
targ_extra_emuls="elf64alpha alpha"
tdir_alpha=`echo ${targ_alias} | sed -e 's/freebsd/freebsdecoff/'` ;;
-alpha*-*-linuxecoff*) targ_emul=alpha targ_extra_emuls=elf64alpha
+alpha*-*-linux*ecoff*) targ_emul=alpha targ_extra_emuls=elf64alpha
tdir_elf64alpha=`echo ${targ_alias} | sed -e 's/ecoff//'` ;;
alpha*-*-linux-*) targ_emul=elf64alpha targ_extra_emuls=alpha
- tdir_alpha=`echo ${targ_alias} | sed -e 's/linux/linuxecoff/'` ;;
+ tdir_alpha=`echo ${targ_alias} | sed -e 's/linux\(-gnu\)*/linux\1ecoff/'` ;;
alpha*-*-osf*) targ_emul=alpha ;;
alpha*-*-gnu*) targ_emul=elf64alpha ;;
alpha*-*-netware*) targ_emul=alpha ;;
@@ -519,7 +519,7 @@ mn10300-*-*) targ_emul=mn10300
mt-*elf) targ_emul=elf32mt
;;
msp430-*-*) targ_emul=msp430x110
- targ_extra_emuls="msp430x112 msp430x1101 msp430x1111 msp430x1121 msp430x1122 msp430x1132 msp430x122 msp430x123 msp430x1222 msp430x1232 msp430x133 msp430x135 msp430x1331 msp430x1351 msp430x147 msp430x148 msp430x149 msp430x155 msp430x156 msp430x157 msp430x167 msp430x168 msp430x169 msp430x1610 msp430x1611 msp430x1612 msp430x2101 msp430x2111 msp430x2121 msp430x2131 msp430x311 msp430x312 msp430x313 msp430x314 msp430x315 msp430x323 msp430x325 msp430x336 msp430x337 msp430x412 msp430x413 msp430x415 msp430x417 msp430xE423 msp430xE425 msp430xE427 msp430xW423 msp430xW425 msp430xW427 msp430xG437 msp430xG438 msp430xG439 msp430x435 msp430x436 msp430x437 msp430x447 msp430x448 msp430x449"
+ targ_extra_emuls="msp430x112 msp430x1101 msp430x1111 msp430x1121 msp430x1122 msp430x1132 msp430x122 msp430x123 msp430x1222 msp430x1232 msp430x133 msp430x135 msp430x1331 msp430x1351 msp430x147 msp430x148 msp430x149 msp430x155 msp430x156 msp430x157 msp430x167 msp430x168 msp430x169 msp430x1610 msp430x1611 msp430x1612 msp430x2101 msp430x2111 msp430x2121 msp430x2131 msp430x311 msp430x312 msp430x313 msp430x314 msp430x315 msp430x323 msp430x325 msp430x336 msp430x337 msp430x412 msp430x413 msp430x415 msp430x417 msp430xE423 msp430xE425 msp430xE427 msp430xW423 msp430xW425 msp430xW427 msp430xG437 msp430xG438 msp430xG439 msp430x435 msp430x436 msp430x437 msp430x447 msp430x448 msp430x449 msp430X"
;;
nios2*-*-*) targ_emul=nios2elf ;;
ns32k-pc532-mach* | ns32k-pc532-ux*) targ_emul=pc532macha ;;
diff --git a/ld/emulparams/msp430all.sh b/ld/emulparams/msp430all.sh
index 57d21c2d4..3a2f79dc3 100644
--- a/ld/emulparams/msp430all.sh
+++ b/ld/emulparams/msp430all.sh
@@ -551,3 +551,12 @@ RAM_START=0x0200
RAM_SIZE=0x400
STACK=0x600
fi
+
+if [ "${MSP430_NAME}" = "msp430X" ] ; then
+ARCH=msp:43
+ROM_START=0x02000
+ROM_SIZE=0x0dfe0
+RAM_START=0x10000
+RAM_SIZE=0x30000
+STACK=0x600
+fi
diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em
index 3653955cb..aa4f35574 100644
--- a/ld/emultempl/elf32.em
+++ b/ld/emultempl/elf32.em
@@ -1484,13 +1484,22 @@ gld${EMULATION_NAME}_before_allocation (void)
asection *sinterp;
bfd *abfd;
- if (link_info.hash->type == bfd_link_elf_hash_table)
- _bfd_elf_tls_setup (link_info.output_bfd, &link_info);
-
- /* If we are going to make any variable assignments, we need to let
- the ELF backend know about them in case the variables are
- referred to by dynamic objects. */
- lang_for_each_statement (gld${EMULATION_NAME}_find_statement_assignment);
+ if (is_elf_hash_table (link_info.hash))
+ {
+ _bfd_elf_tls_setup (link_info.output_bfd, &link_info);
+
+ /* Make __ehdr_start hidden if it has been referenced, to
+ prevent the symbol from being dynamic. */
+ if (!bfd_elf_record_link_assignment (link_info.output_bfd, &link_info,
+ "__ehdr_start", TRUE, TRUE))
+ einfo ("%P%F: failed to record assignment to %s: %E\n",
+ "__ehdr_start");
+
+ /* If we are going to make any variable assignments, we need to
+ let the ELF backend know about them in case the variables are
+ referred to by dynamic objects. */
+ lang_for_each_statement (gld${EMULATION_NAME}_find_statement_assignment);
+ }
/* Let the ELF backend work out the sizes of any sections required
by dynamic linking. */
diff --git a/ld/emultempl/generic.em b/ld/emultempl/generic.em
index 20ec35613..dce2bffd1 100644
--- a/ld/emultempl/generic.em
+++ b/ld/emultempl/generic.em
@@ -57,6 +57,18 @@ gld${EMULATION_NAME}_before_parse (void)
#ifndef TARGET_ /* I.e., if not generic. */
ldfile_set_output_arch ("`echo ${ARCH}`", bfd_arch_unknown);
#endif /* not TARGET_ */
+EOF
+ # The MSP430 port *needs* linker relaxtion in order to cope with large
+ # functions where conditional branches do not fit into a +/- 1024 byte range.
+ case ${target} in
+ msp430-*-* )
+fragment <<EOF
+ if (! link_info.relocatable)
+ TARGET_ENABLE_RELAXATION;
+EOF
+ ;;
+ esac
+fragment <<EOF
}
EOF
diff --git a/ld/ld.texinfo b/ld/ld.texinfo
index 79591c7f7..0e31d31d1 100644
--- a/ld/ld.texinfo
+++ b/ld/ld.texinfo
@@ -4031,7 +4031,9 @@ into ascending order by name before placing them in the output file.
@cindex SORT_BY_ALIGNMENT
@code{SORT_BY_ALIGNMENT} is very similar to @code{SORT_BY_NAME}. The
difference is @code{SORT_BY_ALIGNMENT} will sort sections into
-ascending order by alignment before placing them in the output file.
+descending order by alignment before placing them in the output file.
+Larger alignments are placed before smaller alignments in order to
+reduce the amount of padding necessary.
@cindex SORT_BY_INIT_PRIORITY
@code{SORT_BY_INIT_PRIORITY} is very similar to @code{SORT_BY_NAME}. The
@@ -4048,11 +4050,11 @@ can be at most 1 level of nesting for section sorting commands.
@enumerate
@item
@code{SORT_BY_NAME} (@code{SORT_BY_ALIGNMENT} (wildcard section pattern)).
-It will sort the input sections by name first, then by alignment if 2
+It will sort the input sections by name first, then by alignment if two
sections have the same name.
@item
@code{SORT_BY_ALIGNMENT} (@code{SORT_BY_NAME} (wildcard section pattern)).
-It will sort the input sections by alignment first, then by name if 2
+It will sort the input sections by alignment first, then by name if two
sections have the same alignment.
@item
@code{SORT_BY_NAME} (@code{SORT_BY_NAME} (wildcard section pattern)) is
diff --git a/ld/ldmain.c b/ld/ldmain.c
index e7d726ad9..5181c61e9 100644
--- a/ld/ldmain.c
+++ b/ld/ldmain.c
@@ -1,7 +1,5 @@
/* Main program of GNU linker.
- Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
- 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
- Free Software Foundation, Inc.
+ Copyright 1991-2013 Free Software Foundation, Inc.
Written by Steve Chamberlain steve@cygnus.com
This file is part of the GNU Binutils.
@@ -936,10 +934,10 @@ multiple_definition (struct bfd_link_info *info,
if (obfd != NULL)
einfo (_("%D: first defined here\n"), obfd, osec, oval);
- if (RELAXATION_ENABLED)
+ if (RELAXATION_ENABLED_BY_USER)
{
einfo (_("%P: Disabling relaxation: it will not work with multiple definitions\n"));
- link_info.disable_target_specific_optimizations = -1;
+ DISABLE_RELAXATION;
}
return TRUE;
diff --git a/ld/ldmain.h b/ld/ldmain.h
index 66aa6288b..39ab0143d 100644
--- a/ld/ldmain.h
+++ b/ld/ldmain.h
@@ -1,6 +1,5 @@
/* ldmain.h -
- Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1999, 2002, 2003, 2004,
- 2005, 2007, 2008, 2009, 2012 Free Software Foundation, Inc.
+ Copyright 1991-2013 Free Software Foundation, Inc.
This file is part of the GNU Binutils.
@@ -42,11 +41,16 @@ extern int overflow_cutoff_limit;
#define RELAXATION_DISABLED_BY_DEFAULT \
(link_info.disable_target_specific_optimizations < 0)
#define RELAXATION_DISABLED_BY_USER \
- (link_info.disable_target_specific_optimizations > 0)
+ (link_info.disable_target_specific_optimizations > 1)
#define RELAXATION_ENABLED \
+ (link_info.disable_target_specific_optimizations == 0 \
+ || link_info.disable_target_specific_optimizations == 1)
+#define RELAXATION_ENABLED_BY_USER \
(link_info.disable_target_specific_optimizations == 0)
-#define DISABLE_RELAXATION \
+#define TARGET_ENABLE_RELAXATION \
do { link_info.disable_target_specific_optimizations = 1; } while (0)
+#define DISABLE_RELAXATION \
+ do { link_info.disable_target_specific_optimizations = 2; } while (0)
#define ENABLE_RELAXATION \
do { link_info.disable_target_specific_optimizations = 0; } while (0)
diff --git a/ld/scripttempl/elf32msp430.sc b/ld/scripttempl/elf32msp430.sc
index 53a87b852..c699a9163 100644
--- a/ld/scripttempl/elf32msp430.sc
+++ b/ld/scripttempl/elf32msp430.sc
@@ -35,6 +35,31 @@ MEMORY
SECTIONS
{
+ /* Bootloader. */
+ .bootloader ${RELOCATING-0} :
+ {
+ ${RELOCATING+ PROVIDE (__boot_start = .) ; }
+ *(.bootloader)
+ ${RELOCATING+. = ALIGN(2);}
+ *(.bootloader.*)
+ } ${RELOCATING+ > bootloader}
+
+ /* Information memory. */
+ .infomem ${RELOCATING-0} :
+ {
+ *(.infomem)
+ ${RELOCATING+. = ALIGN(2);}
+ *(.infomem.*)
+ } ${RELOCATING+ > infomem}
+
+ /* Information memory (not loaded into MPU). */
+ .infomemnobits ${RELOCATING-0} :
+ {
+ *(.infomemnobits)
+ ${RELOCATING+. = ALIGN(2);}
+ *(.infomemnobits.*)
+ } ${RELOCATING+ > infomemnobits}
+
/* Read-only sections, merged into text segment. */
${TEXT_DYNAMIC+${DYNAMIC}}
.hash ${RELOCATING-0} : { *(.hash) }
@@ -122,6 +147,8 @@ SECTIONS
*(.text)
${RELOCATING+. = ALIGN(2);}
*(.text.*)
+ ${RELOCATING+. = ALIGN(2);}
+ *(.text:*)
${RELOCATING+. = ALIGN(2);}
*(SORT_NONE(.fini9))
@@ -139,42 +166,84 @@ SECTIONS
_etext = .;
} ${RELOCATING+ > text}
- .data ${RELOCATING-0} : ${RELOCATING+AT (ADDR (.text) + SIZEOF (.text))}
+ .rodata :
+ {
+ . = ALIGN(2);
+ *(.plt)
+ *(.rodata .rodata.* .gnu.linkonce.r.* .const .const:*)
+ *(.rodata1)
+
+ *(.eh_frame_hdr)
+ KEEP (*(.eh_frame))
+
+ KEEP (*(.gcc_except_table)) *(.gcc_except_table.*)
+
+ PROVIDE (__preinit_array_start = .);
+ KEEP (*(.preinit_array))
+ PROVIDE (__preinit_array_end = .);
+
+ PROVIDE (__init_array_start = .);
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ PROVIDE (__init_array_end = .);
+
+ PROVIDE (__fini_array_start = .);
+ KEEP (*(.fini_array))
+ KEEP (*(SORT(.fini_array.*)))
+ PROVIDE (__fini_array_end = .);
+ LONG(0); /* Sentinel. */
+
+ /* gcc uses crtbegin.o to find the start of the constructors, so
+ we make sure it is first. Because this is a wildcard, it
+ doesn't matter if the user does not actually link against
+ crtbegin.o; the linker won't look for a file to match a
+ wildcard. The wildcard also means that it doesn't matter which
+ directory crtbegin.o is in. */
+ KEEP (*crtbegin*.o(.ctors))
+
+ /* We don't want to include the .ctor section from from the
+ crtend.o file until after the sorted ctors. The .ctor section
+ from the crtend file contains the end of ctors marker and it
+ must be last */
+ KEEP (*(EXCLUDE_FILE (*crtend*.o ) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*(.ctors))
+
+ KEEP (*crtbegin*.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*(.dtors))
+ } ${RELOCATING+ > text}
+
+ .vectors ${RELOCATING-0}:
+ {
+ ${RELOCATING+ PROVIDE (__vectors_start = .) ; }
+ *(.vectors*)
+ ${RELOCATING+ _vectors_end = . ; }
+ } ${RELOCATING+ > vectors}
+
+ .data ${RELOCATING-0} : ${RELOCATING+AT (ADDR (.text) + SIZEOF (.text) + SIZEOF (.rodata))}
{
${RELOCATING+ PROVIDE (__data_start = .) ; }
+ ${RELOCATING+ PROVIDE (__datastart = .) ; }
${RELOCATING+. = ALIGN(2);}
+
+ KEEP (*(.jcr))
+ *(.data.rel.ro.local) *(.data.rel.ro*)
+ *(.dynamic)
+
*(.data)
*(.data.*)
*(.gnu.linkonce.d*)
+ KEEP (*(.gnu.linkonce.d.*personality*))
+ *(.data1)
+ *(.got.plt) *(.got)
+ ${RELOCATING+. = ALIGN(2);}
+ *(.sdata .sdata.* .gnu.linkonce.s.*)
${RELOCATING+. = ALIGN(2);}
${RELOCATING+ _edata = . ; }
} ${RELOCATING+ > data}
- /* Bootloader. */
- .bootloader ${RELOCATING-0} :
- {
- ${RELOCATING+ PROVIDE (__boot_start = .) ; }
- *(.bootloader)
- ${RELOCATING+. = ALIGN(2);}
- *(.bootloader.*)
- } ${RELOCATING+ > bootloader}
-
- /* Information memory. */
- .infomem ${RELOCATING-0} :
- {
- *(.infomem)
- ${RELOCATING+. = ALIGN(2);}
- *(.infomem.*)
- } ${RELOCATING+ > infomem}
-
- /* Information memory (not loaded into MPU). */
- .infomemnobits ${RELOCATING-0} :
- {
- *(.infomemnobits)
- ${RELOCATING+. = ALIGN(2);}
- *(.infomemnobits.*)
- } ${RELOCATING+ > infomemnobits}
-
.bss ${RELOCATING+ SIZEOF(.data) + ADDR(.data)} :
{
${RELOCATING+. = ALIGN(2);}
@@ -194,13 +263,6 @@ SECTIONS
${RELOCATING+ _end = . ; }
} ${RELOCATING+ > data}
- .vectors ${RELOCATING-0}:
- {
- ${RELOCATING+ PROVIDE (__vectors_start = .) ; }
- *(.vectors*)
- ${RELOCATING+ _vectors_end = . ; }
- } ${RELOCATING+ > vectors}
-
${HEAP_SECTION_MSP430}
/* Stabs for profiling information*/
@@ -214,12 +276,18 @@ SECTIONS
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
-
EOF
-. $srcdir/scripttempl/DWARF.sc
+source $srcdir/scripttempl/DWARF.sc
cat <<EOF
+ .MP430.attributes 0 :
+ {
+ KEEP (*(.MSP430.attributes))
+ KEEP (*(.gnu.attributes))
+ KEEP (*(__TI_build_attributes))
+ }
+
PROVIDE (__stack = ${STACK}) ;
PROVIDE (__data_start_rom = _etext) ;
PROVIDE (__data_end_rom = _etext + SIZEOF (.data)) ;
diff --git a/ld/scripttempl/elf32msp430_3.sc b/ld/scripttempl/elf32msp430_3.sc
index 9a23d02ff..ade5fcb08 100644
--- a/ld/scripttempl/elf32msp430_3.sc
+++ b/ld/scripttempl/elf32msp430_3.sc
@@ -98,6 +98,8 @@ SECTIONS
*(.text)
${RELOCATING+. = ALIGN(2);}
*(.text.*)
+ ${RELOCATING+. = ALIGN(2);}
+ *(.text:*)
${RELOCATING+. = ALIGN(2);}
*(SORT_NONE(.fini9))
@@ -115,6 +117,13 @@ SECTIONS
${RELOCATING+ _etext = . ; }
} ${RELOCATING+ > text}
+ .rodata :
+ {
+ *(.rodata .rodata.* .gnu.linkonce.r.*)
+ *(.const)
+ *(.const:*)
+ } ${RELOCATING+ > text}
+
.data ${RELOCATING-0} : ${RELOCATING+AT (ADDR (.text) + SIZEOF (.text))}
{
${RELOCATING+ PROVIDE (__data_start = .) ; }
@@ -152,6 +161,13 @@ SECTIONS
${RELOCATING+ _vectors_end = . ; }
} ${RELOCATING+ > vectors}
+ .MP430.attributes 0 :
+ {
+ KEEP (*(.MSP430.attributes))
+ KEEP (*(.gnu.attributes))
+ KEEP (*(__TI_build_attributes))
+ }
+
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog
index 27dae44d1..cad469ce7 100644
--- a/ld/testsuite/ChangeLog
+++ b/ld/testsuite/ChangeLog
@@ -1,3 +1,80 @@
+2013-05-21 Alan Modra <amodra@gmail.com>
+
+ PR ld/12982
+ * ld-plugin/pr12982.d: Fail if RWE GNU_STACK present.
+
+2013-05-21 Alan Modra <amodra@gmail.com>
+
+ * ld-powerpc/export-class.exp (supports_ppc64): Delete.
+ (powerpc_export_class_test): Add "endian" param.
+ (abis): Add little-endian targets and test.
+ * ld-powerpc/powerpc-64-export-class.xd: Update for little-endian.
+
+2013-05-10 Joel Brobecker <brobecker@adacore.com>
+
+ * ld-powerpc/aix-core-sec-1.hd, ld-powerpc/aix-core-sec-2.hd,
+ ld-powerpc/aix-core-sec-3.hd: Adjust expected section flags
+ for section .loader.
+
+2013-05-03 Maciej W. Rozycki <macro@codesourcery.com>
+
+ PR ld/15365
+ * ld-elf/ehdr_start.d: Expect __ehdr_start to be STB_LOCAL.
+ * ld-mips-elf/ehdr_start-1.nd: New test.
+ * ld-mips-elf/ehdr_start-2.nd: New test.
+ * ld-mips-elf/ehdr_start-1.ld: New test linker script.
+ * ld-mips-elf/ehdr_start-2.ld: New test linker script.
+ * ld-mips-elf/ehdr_start-new.s: New test source.
+ * ld-mips-elf/ehdr_start-o32.s: New test source.
+ * ld-mips-elf/mips-elf.exp: Run the new tests.
+
+2013-05-03 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * ld-elf/provide-hidden-s.nd: New test.
+ * ld-elf/provide-hidden-abs.nd: New test.
+ * ld-elf/provide-hidden-def.nd: New test.
+ * ld-elf/provide-hidden-dyn.nd: New test.
+ * ld-elf/provide-hidden-sec.nd: New test.
+ * ld-elf/provide-hidden-dynabs.nd: New test.
+ * ld-elf/provide-hidden-dynsec.nd: New test.
+ * ld-elf/provide-hidden-s.ld: New test linker script.
+ * ld-elf/provide-hidden-1.ld: New test linker script.
+ * ld-elf/provide-hidden-2.ld: New test linker script.
+ * ld-elf/provide-hidden-1.s: New test source.
+ * ld-elf/provide-hidden-2.s: New test source.
+ * ld-elf/provide-hidden-3.s: New test source.
+ * ld-elf/provide-hidden-4.s: New test source.
+ * ld-elf/provide-hidden.exp: New test script.
+
+2013-05-02 Nick Clifton <nickc@redhat.com>
+
+ * ld-elf/flags1.d: Expect this test to pass on the MSP430.
+ * ld-elf/init-fini-arrays.d: Expect this test to fail on the
+ MSP430.
+ * ld-elf/merge.d: Expect this test to pass on the MSP430.
+ * ld-elf/sec64k.exp: Skip these tests for the MSP430.
+ * ld-gc/pr13683.d: Expect this test to fail on the MSP430.
+ * ld-srec/srec.exp: Expect these tests to fail on the MSP430.
+ * ld-undefined/undefined.exp: Expect the UNDEFINED LINE test to
+ fail on the MSP430.
+
+2013-05-01 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * lib/ld-lib.exp (check_shared_lib_support): Also exclude
+ mips*-*-elf.
+
+2013-04-30 Hans-Peter Nilsson <hp@axis.com>
+
+ * lib/ld-lib.exp (check_shared_lib_support): Match cris*-*-elf as
+ a negative pattern instead of cris*-*-*.
+
+2013-04-30 Will Newton <will.newton@linaro.org>
+
+ * ld-arm/arm-elf.exp: Use linker script for IFUNC test 17.
+ * ld-arm/ifunc-17.dd: Update offsets for linker script.
+ * ld-arm/ifunc-17.gd: Likewise.
+ * ld-arm/ifunc-17.rd: Likewise.
+
2013-04-29 Will Newton <will.newton@linaro.org>
* ld-arm/arm-elf.exp: Add IFUNC test 17.
diff --git a/ld/testsuite/ld-arm/arm-elf.exp b/ld/testsuite/ld-arm/arm-elf.exp
index c488e3cba..a6abe8287 100644
--- a/ld/testsuite/ld-arm/arm-elf.exp
+++ b/ld/testsuite/ld-arm/arm-elf.exp
@@ -451,7 +451,7 @@ set armelftests_nonacl {
{objdump {-s -j.data -j.got} ifunc-16.gd}
{readelf -r ifunc-16.rd}}
"ifunc-16"}
- {"IFUNC test 17" "" "" "" {ifunc-17.s}
+ {"IFUNC test 17" "-T ifunc-static.ld" "" "" {ifunc-17.s}
{{objdump -d ifunc-17.dd}
{objdump {-s -j.data -j.got} ifunc-17.gd}
{readelf -r ifunc-17.rd}}
diff --git a/ld/testsuite/ld-arm/ifunc-17.dd b/ld/testsuite/ld-arm/ifunc-17.dd
index f23a2490c..ee5cd050a 100644
--- a/ld/testsuite/ld-arm/ifunc-17.dd
+++ b/ld/testsuite/ld-arm/ifunc-17.dd
@@ -4,22 +4,22 @@
Disassembly of section \.iplt:
-00008084 <.iplt>:
+00009000 <.iplt>:
#------------------------------------------------------------------------------
#------ appfunc1's .iplt entry
#------------------------------------------------------------------------------
- 8084: e28fc600 add ip, pc, #0, 12
- 8088: e28cca08 add ip, ip, #8, 20 ; 0x8000
- 808c: e5bcf01c ldr pc, \[ip, #28\]!
+ 9000: e28fc600 add ip, pc, #0, 12
+ 9004: e28cca08 add ip, ip, #8, 20 ; 0x8000
+ 9008: e5bcf004 ldr pc, \[ip, #4\]!
Disassembly of section \.text:
-00008090 <appfunc1>:
- 8090: 46f7 mov pc, lr
+0000a000 <appfunc1>:
+ a000: 46f7 mov pc, lr
-00008092 <appfunc2>:
- 8092: 46f7 mov pc, lr
+0000a002 <appfunc2>:
+ a002: 46f7 mov pc, lr
-00008094 <_start>:
- 8094: f7ff eff6 blx 8084 <appfunc1-0xc>
- 8098: 00000010 \.word 0x00000010
+0000a004 <_start>:
+ a004: f7fe effc blx 9000 <appfunc1-0x1000>
+ a008: 00000010 \.word 0x00000010
diff --git a/ld/testsuite/ld-arm/ifunc-17.gd b/ld/testsuite/ld-arm/ifunc-17.gd
index 4a12eb87f..dadfc9eeb 100644
--- a/ld/testsuite/ld-arm/ifunc-17.gd
+++ b/ld/testsuite/ld-arm/ifunc-17.gd
@@ -3,8 +3,8 @@
Contents of section \.got:
#------------------------------------------------------------------------------
-#------ 000100a8: 0x8091 (appfunc1)
-#------ 000100ac: 0x8093 (appfunc2)
+#------ 0001100c: 0xa001 (appfunc1)
+#------ 00011010: 0xa003 (appfunc2)
#------------------------------------------------------------------------------
- 1009c 00000000 00000000 00000000 91800000 .*
- 100ac 93800000 .*
+ 11000 00000000 00000000 00000000 01a00000 .*
+ 11010 03a00000 .*
diff --git a/ld/testsuite/ld-arm/ifunc-17.rd b/ld/testsuite/ld-arm/ifunc-17.rd
index a93fd64a9..b167f4529 100644
--- a/ld/testsuite/ld-arm/ifunc-17.rd
+++ b/ld/testsuite/ld-arm/ifunc-17.rd
@@ -1,5 +1,5 @@
-Relocation section '\.rel\.dyn' at offset 0x74 contains 2 entries:
+Relocation section '\.rel\.dyn' at offset 0x8000 contains 2 entries:
Offset Info Type Sym\.Value Sym\. Name
-000100a8 ......a0 R_ARM_IRELATIVE
-000100ac ......a0 R_ARM_IRELATIVE
+0001100c ......a0 R_ARM_IRELATIVE
+00011010 ......a0 R_ARM_IRELATIVE
diff --git a/ld/testsuite/ld-elf/ehdr_start.d b/ld/testsuite/ld-elf/ehdr_start.d
index 9a8288242..52e5b5488 100644
--- a/ld/testsuite/ld-elf/ehdr_start.d
+++ b/ld/testsuite/ld-elf/ehdr_start.d
@@ -4,5 +4,5 @@
#target: *-*-linux* *-*-gnu* *-*-nacl*
#...
-[0-9a-f]*000 [ADRT] __ehdr_start
+[0-9a-f]*000 [Adrt] __ehdr_start
#pass
diff --git a/ld/testsuite/ld-elf/flags1.d b/ld/testsuite/ld-elf/flags1.d
index ab8facc99..63c2e3a04 100644
--- a/ld/testsuite/ld-elf/flags1.d
+++ b/ld/testsuite/ld-elf/flags1.d
@@ -3,9 +3,9 @@
#objcopy_linked_file: --set-section-flags .post_text_reserve=contents,alloc,load,readonly,code
#readelf: -l --wide
#xfail: "avr-*-*" "dlx-*-*" "h8300-*-*" "i960-*-*" "ip2k-*-*" "m32r-*-*"
-#xfail: "moxie-*-*" "mt-*-*" "msp430-*-*" "*-*-nacl*"
+#xfail: "moxie-*-*" "mt-*-*" "*-*-nacl*"
#xfail: "*-*-hpux*" "hppa*64*-*-*"
-# Fails on the AVR, DLX, H8300, I960, IP2K, M32R, MOXIE, MT, and MSP430,
+# Fails on the AVR, DLX, H8300, I960, IP2K, M32R, MOXIE, MT,
# and all NaCl targets,
# because the two sections are not merged into one segment.
# (There is no good reason why they have to be).
diff --git a/ld/testsuite/ld-elf/init-fini-arrays.d b/ld/testsuite/ld-elf/init-fini-arrays.d
index 1b182b945..46b536c9c 100644
--- a/ld/testsuite/ld-elf/init-fini-arrays.d
+++ b/ld/testsuite/ld-elf/init-fini-arrays.d
@@ -1,9 +1,10 @@
#source: init-fini-arrays.s
#ld: -r
#readelf: -S --wide
-#xfail: cr16-*-* crx-*-*
+#xfail: cr16-*-* crx-*-* msp430-*-*
+# msp430 puts the init_array and fini_array inside the .rodata section.
# cr16 and crx use non-standard scripts with memory regions, which don't play
-# well with unique group sections under ld -r.
+# well with unique group sections under ld -r.
#...
\[[ 0-9]+\] \.init_array\.01000[ \t]+PROGBITS[ \t0-9a-f]+WA?.*
diff --git a/ld/testsuite/ld-elf/merge.d b/ld/testsuite/ld-elf/merge.d
index 3593f9676..c50de1030 100644
--- a/ld/testsuite/ld-elf/merge.d
+++ b/ld/testsuite/ld-elf/merge.d
@@ -4,7 +4,7 @@
#xfail: "arc-*-*" "avr-*-*" "bfin-*-*" "cr16-*-*" "cris*-*-*" "crx-*-*" "d10v-*-*" "d30v-*-*"
#xfail: "dlx-*-*" "fr30-*-*" "frv-*-*" "hppa*64*-*-*" "h8300-*-*" "score-*-*"
#xfail: "i370-*-*" "i860-*-*" "i960-*-*" "ip2k-*-*" "iq2000-*-*" "lm32-*-*"
-#xfail: "mcore-*-*" "mn102*-*-*" "mips*-*-*" "ms1-*-*" "msp430-*-*" "mep-*-*"
+#xfail: "mcore-*-*" "mn102*-*-*" "mips*-*-*" "ms1-*-*" "mep-*-*"
#xfail: "or32-*-*" "pj-*-*" "sparc*-*-*" "tic6x-*-*" "vax-*-*" "xstormy16-*-*"
#xfail: "xtensa*-*-*" "metag-*-*"
diff --git a/ld/testsuite/ld-elf/provide-hidden-1.ld b/ld/testsuite/ld-elf/provide-hidden-1.ld
new file mode 100644
index 000000000..47cdbb7fa
--- /dev/null
+++ b/ld/testsuite/ld-elf/provide-hidden-1.ld
@@ -0,0 +1,15 @@
+SECTIONS
+{
+ . = 0x12300000;
+ .data :
+ {
+ PROVIDE_HIDDEN (foo = . + 0x11100000);
+ *(.data)
+ }
+ .got : { *(.got) }
+ .interp : { *(.interp) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .dynamic : { *(.dynamic) }
+ .hash : { *(.hash) }
+}
diff --git a/ld/testsuite/ld-elf/provide-hidden-1.s b/ld/testsuite/ld-elf/provide-hidden-1.s
new file mode 100644
index 000000000..c845ffb9a
--- /dev/null
+++ b/ld/testsuite/ld-elf/provide-hidden-1.s
@@ -0,0 +1,4 @@
+ .data
+ .globl foo
+foo:
+ .dc.a foo
diff --git a/ld/testsuite/ld-elf/provide-hidden-2.ld b/ld/testsuite/ld-elf/provide-hidden-2.ld
new file mode 100644
index 000000000..0b04c4997
--- /dev/null
+++ b/ld/testsuite/ld-elf/provide-hidden-2.ld
@@ -0,0 +1,12 @@
+SECTIONS
+{
+ . = 0x12300000;
+ PROVIDE_HIDDEN (foo = . + 0x11100000);
+ .data : { *(.data) }
+ .got : { *(.got) }
+ .interp : { *(.interp) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .dynamic : { *(.dynamic) }
+ .hash : { *(.hash) }
+}
diff --git a/ld/testsuite/ld-elf/provide-hidden-2.s b/ld/testsuite/ld-elf/provide-hidden-2.s
new file mode 100644
index 000000000..bbaa7de50
--- /dev/null
+++ b/ld/testsuite/ld-elf/provide-hidden-2.s
@@ -0,0 +1,5 @@
+ .data
+ .globl foo
+ .internal foo
+foo:
+ .dc.a foo
diff --git a/ld/testsuite/ld-elf/provide-hidden-3.s b/ld/testsuite/ld-elf/provide-hidden-3.s
new file mode 100644
index 000000000..941328063
--- /dev/null
+++ b/ld/testsuite/ld-elf/provide-hidden-3.s
@@ -0,0 +1,4 @@
+ .data
+ .globl bar
+bar:
+ .dc.a foo
diff --git a/ld/testsuite/ld-elf/provide-hidden-4.s b/ld/testsuite/ld-elf/provide-hidden-4.s
new file mode 100644
index 000000000..2d8f37e6f
--- /dev/null
+++ b/ld/testsuite/ld-elf/provide-hidden-4.s
@@ -0,0 +1,5 @@
+ .data
+ .globl bar
+ .internal foo
+bar:
+ .dc.a foo
diff --git a/ld/testsuite/ld-elf/provide-hidden-abs.nd b/ld/testsuite/ld-elf/provide-hidden-abs.nd
new file mode 100644
index 000000000..642a7a0e4
--- /dev/null
+++ b/ld/testsuite/ld-elf/provide-hidden-abs.nd
@@ -0,0 +1,5 @@
+#...
+Symbol table '\.symtab' contains [0-9]+ entries:
+#...
+ *[0-9]+: 0*23400000 +0 (?:NOTYPE|OBJECT) +LOCAL +DEFAULT +ABS foo
+#pass
diff --git a/ld/testsuite/ld-elf/provide-hidden-def.nd b/ld/testsuite/ld-elf/provide-hidden-def.nd
new file mode 100644
index 000000000..d4355c80d
--- /dev/null
+++ b/ld/testsuite/ld-elf/provide-hidden-def.nd
@@ -0,0 +1,5 @@
+#...
+Symbol table '\.symtab' contains [0-9]+ entries:
+#...
+ *[0-9]+: 0*12300000 +0 (?:NOTYPE|OBJECT) +LOCAL +DEFAULT +[0-9]+ foo
+#pass
diff --git a/ld/testsuite/ld-elf/provide-hidden-dyn.nd b/ld/testsuite/ld-elf/provide-hidden-dyn.nd
new file mode 100644
index 000000000..230f7fd7b
--- /dev/null
+++ b/ld/testsuite/ld-elf/provide-hidden-dyn.nd
@@ -0,0 +1,7 @@
+#failif
+Symbol table '\.dynsym' contains [0-9]+ entries:
+#...
+.* foo
+#...
+Symbol table '\.symtab' contains [0-9]+ entries:
+#pass
diff --git a/ld/testsuite/ld-elf/provide-hidden-dynabs.nd b/ld/testsuite/ld-elf/provide-hidden-dynabs.nd
new file mode 100644
index 000000000..86e3adcdf
--- /dev/null
+++ b/ld/testsuite/ld-elf/provide-hidden-dynabs.nd
@@ -0,0 +1,8 @@
+Symbol table '\.dynsym' contains [0-9]+ entries:
+#...
+ *[0-9]+: 0*23400000 +0 (?:NOTYPE|OBJECT) +LOCAL +DEFAULT +ABS foo
+#...
+Symbol table '\.symtab' contains [0-9]+ entries:
+#...
+ *[0-9]+: 0*23400000 +0 (?:NOTYPE|OBJECT) +LOCAL +DEFAULT +ABS foo
+#pass
diff --git a/ld/testsuite/ld-elf/provide-hidden-dynsec.nd b/ld/testsuite/ld-elf/provide-hidden-dynsec.nd
new file mode 100644
index 000000000..716dfa1f7
--- /dev/null
+++ b/ld/testsuite/ld-elf/provide-hidden-dynsec.nd
@@ -0,0 +1,8 @@
+Symbol table '\.dynsym' contains [0-9]+ entries:
+#...
+ *[0-9]+: 0*23400000 +0 (?:NOTYPE|OBJECT) +LOCAL +DEFAULT +[0-9]+ foo
+#...
+Symbol table '\.symtab' contains [0-9]+ entries:
+#...
+ *[0-9]+: 0*23400000 +0 (?:NOTYPE|OBJECT) +LOCAL +DEFAULT +[0-9]+ foo
+#pass
diff --git a/ld/testsuite/ld-elf/provide-hidden-s.ld b/ld/testsuite/ld-elf/provide-hidden-s.ld
new file mode 100644
index 000000000..cca804f77
--- /dev/null
+++ b/ld/testsuite/ld-elf/provide-hidden-s.ld
@@ -0,0 +1,11 @@
+SECTIONS
+{
+ . = 0x12300000;
+ .data : { *(.data) }
+ .got : { *(.got) }
+ .interp : { *(.interp) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .dynamic : { *(.dynamic) }
+ .hash : { *(.hash) }
+}
diff --git a/ld/testsuite/ld-elf/provide-hidden-s.nd b/ld/testsuite/ld-elf/provide-hidden-s.nd
new file mode 100644
index 000000000..4fd2cc57b
--- /dev/null
+++ b/ld/testsuite/ld-elf/provide-hidden-s.nd
@@ -0,0 +1,8 @@
+Symbol table '\.dynsym' contains [0-9]+ entries:
+#...
+ *[0-9]+: 0*12300000 +0 (?:NOTYPE|OBJECT) +GLOBAL +DEFAULT +[0-9]+ foo
+#...
+Symbol table '\.symtab' contains [0-9]+ entries:
+#...
+ *[0-9]+: 0*12300000 +0 (?:NOTYPE|OBJECT) +GLOBAL +DEFAULT +[0-9]+ foo
+#pass
diff --git a/ld/testsuite/ld-elf/provide-hidden-sec.nd b/ld/testsuite/ld-elf/provide-hidden-sec.nd
new file mode 100644
index 000000000..f155d6696
--- /dev/null
+++ b/ld/testsuite/ld-elf/provide-hidden-sec.nd
@@ -0,0 +1,5 @@
+#...
+Symbol table '\.symtab' contains [0-9]+ entries:
+#...
+ *[0-9]+: 0*23400000 +0 (?:NOTYPE|OBJECT) +LOCAL +DEFAULT +[0-9]+ foo
+#pass
diff --git a/ld/testsuite/ld-elf/provide-hidden.exp b/ld/testsuite/ld-elf/provide-hidden.exp
new file mode 100644
index 000000000..7246d110d
--- /dev/null
+++ b/ld/testsuite/ld-elf/provide-hidden.exp
@@ -0,0 +1,154 @@
+# Expect script for the PROVIDE_HIDDEN linker script command.
+#
+# Copyright 2013 Free Software Foundation, Inc.
+#
+# This file is part of the GNU Binutils.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+# MA 02110-1301, USA.
+#
+
+#
+# Written by Maciej W. Rozycki <macro@codesourcery.com>
+#
+
+# Export classes only make sense for ELF shared-library targets.
+if { ![is_elf_format] || ![check_shared_lib_support] } {
+ return
+}
+
+# This target requires extra GAS options when building code for shared
+# libraries.
+set AFLAGS_PIC ""
+if [istarget "tic6x-*-*"] {
+ append AFLAGS_PIC " -mpic -mpid=near"
+}
+
+set testname "PROVIDE_HIDDEN test"
+
+run_ld_link_tests [list \
+ [list \
+ "$testname (auxiliary shared object)" \
+ "-shared -T provide-hidden-s.ld" "" \
+ "$AFLAGS_PIC" \
+ [list provide-hidden-1.s ] \
+ [list "readelf -s provide-hidden-s.nd"] \
+ "provide-hidden-s.so"]]
+
+run_ld_link_tests [list \
+ [list \
+ "$testname 1" \
+ "-T provide-hidden-1.ld" "" \
+ "" \
+ [list provide-hidden-1.s] \
+ [list \
+ [list readelf -s provide-hidden-def.nd] \
+ [list readelf -s provide-hidden-dyn.nd]] \
+ "provide-hidden-1"] \
+ [list \
+ "$testname 2" \
+ "-T provide-hidden-1.ld" "" \
+ "" \
+ [list provide-hidden-2.s] \
+ [list \
+ [list readelf -s provide-hidden-def.nd] \
+ [list readelf -s provide-hidden-dyn.nd]] \
+ "provide-hidden-2"] \
+ [list \
+ "$testname 3" \
+ "-T provide-hidden-1.ld" "" \
+ "" \
+ [list provide-hidden-3.s] \
+ [list \
+ [list readelf -s provide-hidden-sec.nd] \
+ [list readelf -s provide-hidden-dyn.nd]] \
+ "provide-hidden-3"] \
+ [list \
+ "$testname 4" \
+ "-T provide-hidden-1.ld" "tmpdir/provide-hidden-s.so" \
+ "" \
+ [list provide-hidden-3.s] \
+ [list "readelf -s provide-hidden-dynsec.nd"] \
+ "provide-hidden-4"] \
+ [list \
+ "$testname 5" \
+ "-T provide-hidden-1.ld" "" \
+ "" \
+ [list provide-hidden-4.s] \
+ [list \
+ [list readelf -s provide-hidden-sec.nd] \
+ [list readelf -s provide-hidden-dyn.nd]] \
+ "provide-hidden-5"] \
+ [list \
+ "$testname 6" \
+ "-T provide-hidden-1.ld" "tmpdir/provide-hidden-s.so" \
+ "" \
+ [list provide-hidden-4.s] \
+ [list \
+ [list readelf -s provide-hidden-sec.nd] \
+ [list readelf -s provide-hidden-dyn.nd]] \
+ "provide-hidden-6"] \
+ [list \
+ "$testname 7" \
+ "-T provide-hidden-2.ld" "" \
+ "" \
+ [list provide-hidden-1.s] \
+ [list \
+ [list readelf -s provide-hidden-def.nd] \
+ [list readelf -s provide-hidden-dyn.nd]] \
+ "provide-hidden-7"] \
+ [list \
+ "$testname 8" \
+ "-T provide-hidden-2.ld" "" \
+ "" \
+ [list provide-hidden-2.s] \
+ [list \
+ [list readelf -s provide-hidden-def.nd] \
+ [list readelf -s provide-hidden-dyn.nd]] \
+ "provide-hidden-8"] \
+ [list \
+ "$testname 9" \
+ "-T provide-hidden-2.ld" "" \
+ "" \
+ [list provide-hidden-3.s] \
+ [list \
+ [list readelf -s provide-hidden-abs.nd] \
+ [list readelf -s provide-hidden-dyn.nd]] \
+ "provide-hidden-9"] \
+ [list \
+ "$testname 10" \
+ "-T provide-hidden-2.ld" "tmpdir/provide-hidden-s.so" \
+ "" \
+ [list provide-hidden-3.s] \
+ [list "readelf -s provide-hidden-dynabs.nd"] \
+ "provide-hidden-10"] \
+ [list \
+ "$testname 11" \
+ "-T provide-hidden-2.ld" "" \
+ "" \
+ [list provide-hidden-4.s] \
+ [list \
+ [list readelf -s provide-hidden-abs.nd] \
+ [list readelf -s provide-hidden-dyn.nd]] \
+ "provide-hidden-11"] \
+ [list \
+ "$testname 12" \
+ "-T provide-hidden-2.ld" "tmpdir/provide-hidden-s.so" \
+ "" \
+ [list provide-hidden-4.s] \
+ [list \
+ [list readelf -s provide-hidden-abs.nd] \
+ [list readelf -s provide-hidden-dyn.nd]] \
+ "provide-hidden-12"]]
diff --git a/ld/testsuite/ld-elf/sec64k.exp b/ld/testsuite/ld-elf/sec64k.exp
index 7c04c9b87..7c9f2929c 100644
--- a/ld/testsuite/ld-elf/sec64k.exp
+++ b/ld/testsuite/ld-elf/sec64k.exp
@@ -34,6 +34,7 @@ if { [istarget "arc-*-*"]
|| [istarget "d30v-*-*"]
|| [istarget "dlx-*-*"]
|| [istarget "i960-*-*"]
+ || [istarget "msp430*-*-*"]
|| [istarget "or32-*-*"]
|| [istarget "pj*-*-*"]
|| [istarget "m32r-*-*"] } {
diff --git a/ld/testsuite/ld-gc/pr13683.d b/ld/testsuite/ld-gc/pr13683.d
index 19b2598e4..b38b9d164 100644
--- a/ld/testsuite/ld-gc/pr13683.d
+++ b/ld/testsuite/ld-gc/pr13683.d
@@ -2,7 +2,7 @@
#source: dummy.s
#ld: --gc-sections -e main --defsym foo=foo2 tmpdir/pr13683.o
#nm: --format=bsd
-#xfail: sh64*-*-* iq2000-*-* lm32-*-* epiphany-*-* mips64vr-*-* frv-*-* m32c-*-* rl78-*-* rx-*-* sh-*-* powerpc*-*-eabivle
+#xfail: sh64*-*-* iq2000-*-* lm32-*-* epiphany-*-* mips64vr-*-* frv-*-* m32c-*-* rl78-*-* rx-*-* sh-*-* powerpc*-*-eabivle msp430-*-*
# Note - look for both "foo" and "foo2" being defined, non-zero function symbols
diff --git a/ld/testsuite/ld-mips-elf/ehdr_start-1.ld b/ld/testsuite/ld-mips-elf/ehdr_start-1.ld
new file mode 100644
index 000000000..0485b057f
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ehdr_start-1.ld
@@ -0,0 +1,9 @@
+ENTRY (__start)
+SECTIONS
+{
+ . = 0x12300000 + SIZEOF_HEADERS;
+ .text : { *(.text) }
+ . = 0x23400000;
+ HIDDEN (_gp = ALIGN (16) + 0x7ff0);
+ .got : { *(.got) }
+}
diff --git a/ld/testsuite/ld-mips-elf/ehdr_start-1.nd b/ld/testsuite/ld-mips-elf/ehdr_start-1.nd
new file mode 100644
index 000000000..9496b7d00
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ehdr_start-1.nd
@@ -0,0 +1,4 @@
+Symbol table '\.symtab' contains [0-9]+ entries:
+#...
+ *[0-9]+: 0*12300000 +0 (?:NOTYPE|OBJECT) +LOCAL +DEFAULT +[0-9]+ __ehdr_start
+#pass
diff --git a/ld/testsuite/ld-mips-elf/ehdr_start-2.ld b/ld/testsuite/ld-mips-elf/ehdr_start-2.ld
new file mode 100644
index 000000000..5d5e183c1
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ehdr_start-2.ld
@@ -0,0 +1,10 @@
+ENTRY (__start)
+SECTIONS
+{
+ . = 0x12300000 + SIZEOF_HEADERS;
+ .text : { *(.text) }
+ . = 0x23400000;
+ __ehdr_start = .;
+ HIDDEN (_gp = ALIGN (16) + 0x7ff0);
+ .got : { *(.got) }
+}
diff --git a/ld/testsuite/ld-mips-elf/ehdr_start-2.nd b/ld/testsuite/ld-mips-elf/ehdr_start-2.nd
new file mode 100644
index 000000000..986c2a26c
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ehdr_start-2.nd
@@ -0,0 +1,4 @@
+Symbol table '\.symtab' contains [0-9]+ entries:
+#...
+ *[0-9]+: 0*23400000 +0 (?:NOTYPE|OBJECT) +LOCAL +DEFAULT +[0-9]+ __ehdr_start
+#pass
diff --git a/ld/testsuite/ld-mips-elf/ehdr_start-new.s b/ld/testsuite/ld-mips-elf/ehdr_start-new.s
new file mode 100644
index 000000000..5ee00dc4a
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ehdr_start-new.s
@@ -0,0 +1,13 @@
+ .abicalls
+ .text
+ .weak __ehdr_start
+ .globl __start
+ .ent __start
+ .frame $29, 0, $31
+ .mask 0x00000000, 0
+__start:
+ .cplocal $2
+ .cpsetup $t9, $zero, __start
+ lw $2, __ehdr_start
+ jr $31
+ .end __start
diff --git a/ld/testsuite/ld-mips-elf/ehdr_start-o32.s b/ld/testsuite/ld-mips-elf/ehdr_start-o32.s
new file mode 100644
index 000000000..09734473f
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ehdr_start-o32.s
@@ -0,0 +1,14 @@
+ .abicalls
+ .text
+ .weak __ehdr_start
+ .globl __start
+ .ent __start
+ .frame $29, 0, $31
+ .mask 0x00000000, 0
+__start:
+ .set noreorder
+ .cpload $25
+ .set reorder
+ lw $2, __ehdr_start
+ jr $31
+ .end __start
diff --git a/ld/testsuite/ld-mips-elf/mips-elf.exp b/ld/testsuite/ld-mips-elf/mips-elf.exp
index 902ae006a..97e0c2ce6 100644
--- a/ld/testsuite/ld-mips-elf/mips-elf.exp
+++ b/ld/testsuite/ld-mips-elf/mips-elf.exp
@@ -709,3 +709,28 @@ foreach { abi } $abis {
"readelf -A export-class-call16-${abi}.gd"] \
"export-class-call16-${abi}.so"]]
}
+
+# Magic __ehdr_start symbol tests.
+set abis [concat o32 [expr {$has_newabi ? "n32 n64" : ""}]]
+foreach { abi } $abis {
+ set suff [string map {o32 o32 n32 new n64 new} $abi]
+ run_ld_link_tests [list \
+ [list \
+ "MIPS magic __ehdr_start symbol test 1 ($abi)" \
+ "$abi_ldflags($abi) -T ehdr_start-1.ld" "" \
+ "$abi_asflags($abi)" \
+ [list ehdr_start-${suff}.s] \
+ [list "readelf -s ehdr_start-1.nd"] \
+ "ehdr_start-1-${abi}"]]
+ if [regexp "(?:n32|n64)" "$abi"] {
+ setup_kfail "mips*-*-*" "ld/15428"
+ }
+ run_ld_link_tests [list \
+ [list \
+ "MIPS magic __ehdr_start symbol test 2 ($abi)" \
+ "$abi_ldflags($abi) -T ehdr_start-2.ld" "" \
+ "$abi_asflags($abi)" \
+ [list ehdr_start-${suff}.s] \
+ [list "readelf -s ehdr_start-2.nd"] \
+ "ehdr_start-2-${abi}"]]
+}
diff --git a/ld/testsuite/ld-plugin/pr12982.d b/ld/testsuite/ld-plugin/pr12982.d
index f536d5b64..9b01a58f6 100644
--- a/ld/testsuite/ld-plugin/pr12982.d
+++ b/ld/testsuite/ld-plugin/pr12982.d
@@ -1,3 +1,4 @@
+#failif
#...
-[ \t]+GNU_STACK[ \t]+0x[0-9a-f]+ +0x[0-9a-f]+ +0x[0-9a-f]+ +0x[0-9a-f]+ +0x[0-9a-f]+ +RW +0x[0-9a-f]+
+ +GNU_STACK .* RWE .*
#pass
diff --git a/ld/testsuite/ld-powerpc/aix-core-sec-1.hd b/ld/testsuite/ld-powerpc/aix-core-sec-1.hd
index 19d09e47e..8d81e50aa 100644
--- a/ld/testsuite/ld-powerpc/aix-core-sec-1.hd
+++ b/ld/testsuite/ld-powerpc/aix-core-sec-1.hd
@@ -8,4 +8,4 @@ Sections:
* 2 * \.bss * 0+0 .*
* ALLOC
* 3 * \.loader .*
- * CONTENTS, ALLOC, LOAD
+ * CONTENTS, LOAD
diff --git a/ld/testsuite/ld-powerpc/aix-core-sec-2.hd b/ld/testsuite/ld-powerpc/aix-core-sec-2.hd
index 39facd81e..1152013a4 100644
--- a/ld/testsuite/ld-powerpc/aix-core-sec-2.hd
+++ b/ld/testsuite/ld-powerpc/aix-core-sec-2.hd
@@ -8,4 +8,4 @@ Sections:
* 2 * \.bss * 0+0 .*
* ALLOC
* 3 * \.loader .*
- * CONTENTS, ALLOC, LOAD
+ * CONTENTS, LOAD
diff --git a/ld/testsuite/ld-powerpc/aix-core-sec-3.hd b/ld/testsuite/ld-powerpc/aix-core-sec-3.hd
index f7acc39ec..61a93ae7f 100644
--- a/ld/testsuite/ld-powerpc/aix-core-sec-3.hd
+++ b/ld/testsuite/ld-powerpc/aix-core-sec-3.hd
@@ -8,4 +8,4 @@ Sections:
* 2 * \.bss * 0+8 .*
* ALLOC
* 3 * \.loader .*
- * CONTENTS, ALLOC, LOAD
+ * CONTENTS, LOAD
diff --git a/ld/testsuite/ld-powerpc/export-class.exp b/ld/testsuite/ld-powerpc/export-class.exp
index 5b721fcd2..6171d135f 100644
--- a/ld/testsuite/ld-powerpc/export-class.exp
+++ b/ld/testsuite/ld-powerpc/export-class.exp
@@ -30,22 +30,11 @@ if { ![istarget powerpc*-*-linux*] } {
return
}
-proc supports_ppc64 { } {
- global ld
+proc powerpc_export_class_test { abi endian emul } {
- catch "exec $ld --help | grep emulations" tmp
- if [string match "*elf64ppc*" $tmp] then {
- return 1
- } else {
- return 0
- }
-}
-
-proc powerpc_export_class_test { abi emul } {
-
- set testname "PowerPC $abi symbol export class test"
+ set testname "PowerPC $abi $endian symbol export class test"
- set AFLAGS "-a$abi -be"
+ set AFLAGS "-a$abi -$endian"
set LDFLAGS "-m$emul"
# Build an auxiliary shared object with conflicting versioned symbol
@@ -96,11 +85,13 @@ proc powerpc_export_class_test { abi emul } {
]
}
-if { [supports_ppc64] } {
- set abis { 32 elf32ppclinux 64 elf64ppc }
-} else {
- set abis { 32 elf32ppclinux }
-}
-foreach { abi emul } $abis {
- powerpc_export_class_test $abi $emul
+set abis { 32 be elf32ppclinux 32 le elf32lppclinux 64 be elf64ppc 64 le elf64lppc }
+
+global ld
+catch "exec $ld --help | grep emulations" ldemul
+
+foreach { abi endian emul } $abis {
+ if { [string first $emul $ldemul] != -1 } then {
+ powerpc_export_class_test $abi $endian $emul
+ }
}
diff --git a/ld/testsuite/ld-powerpc/powerpc-64-export-class.xd b/ld/testsuite/ld-powerpc/powerpc-64-export-class.xd
index d0388ad13..264803cf2 100644
--- a/ld/testsuite/ld-powerpc/powerpc-64-export-class.xd
+++ b/ld/testsuite/ld-powerpc/powerpc-64-export-class.xd
@@ -1,11 +1,11 @@
Hex dump of section '\.data':
- 0x12340000 00000000 123400a0 00000000 00000000 .*
- 0x12340010 00000000 123400a0 00000000 00000000 .*
- 0x12340020 00000000 123400a0 00000000 00000000 .*
- 0x12340030 00000000 00000000 00000000 00000000 .*
- 0x12340040 00000000 123400a0 00000000 00000000 .*
- 0x12340050 00000000 123400a0 00000000 00000000 .*
- 0x12340060 00000000 123400a0 00000000 00000000 .*
- 0x12340070 00000000 123400a0 00000000 00000000 .*
- 0x12340080 00000000 123400a0 00000000 00000000 .*
- 0x12340090 00000000 123400a0 00000000 00000000 .*
+ 0x12340000 (00000000|a0003412) (123400a0|00000000) 00000000 00000000 .*
+ 0x12340010 (00000000|a0003412) (123400a0|00000000) 00000000 00000000 .*
+ 0x12340020 (00000000|a0003412) (123400a0|00000000) 00000000 00000000 .*
+ 0x12340030 (00000000|00000000) (00000000|00000000) 00000000 00000000 .*
+ 0x12340040 (00000000|a0003412) (123400a0|00000000) 00000000 00000000 .*
+ 0x12340050 (00000000|a0003412) (123400a0|00000000) 00000000 00000000 .*
+ 0x12340060 (00000000|a0003412) (123400a0|00000000) 00000000 00000000 .*
+ 0x12340070 (00000000|a0003412) (123400a0|00000000) 00000000 00000000 .*
+ 0x12340080 (00000000|a0003412) (123400a0|00000000) 00000000 00000000 .*
+ 0x12340090 (00000000|a0003412) (123400a0|00000000) 00000000 00000000 .*
diff --git a/ld/testsuite/ld-srec/srec.exp b/ld/testsuite/ld-srec/srec.exp
index 001fb2e16..4a433d1f3 100644
--- a/ld/testsuite/ld-srec/srec.exp
+++ b/ld/testsuite/ld-srec/srec.exp
@@ -1,7 +1,6 @@
# Test linking directly to S-records.
# By Ian Lance Taylor, Cygnus Support.
-# Copyright 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2009, 2011, 2012
-# Free Software Foundation, Inc.
+# Copyright 1999-2013 Free Software Foundation, Inc.
#
# This file is part of the GNU Binutils.
#
@@ -269,6 +268,11 @@ proc run_srec_test { test objs } {
set flags "$flags -no-relax"
}
+ # MSP430 targets always relax.
+ if [istarget msp430*-*-*] {
+ setup_xfail "msp430*-*-*"
+ }
+
# Epiphany needs some help too
if [istarget epiphany*-*-*] {
set flags "$flags --defsym _start=00000060"
diff --git a/ld/testsuite/ld-undefined/undefined.exp b/ld/testsuite/ld-undefined/undefined.exp
index 65fbc4b4d..49af737e3 100644
--- a/ld/testsuite/ld-undefined/undefined.exp
+++ b/ld/testsuite/ld-undefined/undefined.exp
@@ -128,6 +128,11 @@ setup_xfail mcore-*-elf
setup_xfail mep-*-*
setup_xfail mips-sgi-irix6*
setup_xfail "sh64-*-*"
+# Fails for the MSP430 because it uses SYM_DIFF relocs but it does
+# not provide a special_function for handling them. If optimization
+# is enabled then this test passes because function()'s prologue is
+# eliminated.
+setup_xfail "msp430-*-*"
# The undefined test fails on 31 bit s/390 because the address of the
# function `this_function_is_not_defined' is stored in the literal pool of
diff --git a/ld/testsuite/lib/ld-lib.exp b/ld/testsuite/lib/ld-lib.exp
index 4b88093ee..ffbfd8b41 100644
--- a/ld/testsuite/lib/ld-lib.exp
+++ b/ld/testsuite/lib/ld-lib.exp
@@ -1565,7 +1565,7 @@ proc check_shared_lib_support { } {
&& ![istarget arm*-*-elf]
&& ![istarget avr-*-*]
&& ![istarget cr16-*-*]
- && ![istarget cris*-*-*]
+ && ![istarget cris*-*-elf]
&& ![istarget crx-*-*]
&& ![istarget d10v-*-*]
&& ![istarget d30v-*-*]
@@ -1587,6 +1587,7 @@ proc check_shared_lib_support { } {
&& ![istarget mcore*-*-*]
&& ![istarget mep-*-*]
&& ![istarget microblaze-*-*]
+ && ![istarget mips*-*-elf]
&& ![istarget mn10200-*-*]
&& ![istarget moxie-*-*]
&& ![istarget msp430-*-*]
diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog
index 1420ad402..a30a363a3 100644
--- a/libiberty/ChangeLog
+++ b/libiberty/ChangeLog
@@ -1,3 +1,11 @@
+2013-05-06 David Edelsohn <dje.gcc@gmail.com>
+ Peter Bergner <bergner@vnet.ibm.com>
+ Segher Boessenkool <segher@kernel.crashing.org>
+ Jakub Jelinek <jakub@redhat.com>
+
+ * hashtab.c (hash_pointer): Remove conditional and avoid
+ unexecuted shift equal to wordsize.
+
2013-04-22 Andi Kleen <ak@linux.intel.com>
* hashtab.c (hash_pointer): Move to end of file and reimplement.
diff --git a/libiberty/hashtab.c b/libiberty/hashtab.c
index a2fe3ee3b..04607ea6a 100644
--- a/libiberty/hashtab.c
+++ b/libiberty/hashtab.c
@@ -990,17 +990,8 @@ hash_pointer (const PTR p)
unsigned a, b, c;
a = b = 0x9e3779b9;
- if (sizeof (intptr_t) == 4)
- {
- /* Mix as 16bit for now */
- a += v >> 16;
- b += v & 0xffff;
- }
- else
- {
- a += v >> 32;
- b += v & 0xffffffff;
- }
+ a += v >> (sizeof (intptr_t) * CHAR_BIT / 2);
+ b += v & (((intptr_t) 1 << (sizeof (intptr_t) * CHAR_BIT / 2)) - 1);
c = 0x42135234;
mix (a, b, c);
return c;
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index 291276511..eb16b0a0c 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,3 +1,76 @@
+2013-05-23 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
+
+ * s390-opc.c: Fix length operand in RSL_LRDFU and RSL_LRDFEU
+ instruction format.
+
+2013-05-22 Jürgen Urban <JuergenUrban@gmx.de>
+
+ * mips-opc.c (mips_builtin_opcodes): Add R5900 VU0 instructions.
+
+2013-05-20 Peter Bergner <bergner@vnet.ibm.com>
+
+ * ppc-dis.c (powerpc_init_dialect): Set default dialect to power8.
+ * ppc-opc.c (BHRBE, ST, SIX, PS, SXL, VXPS_MASK, XX1RB_MASK,
+ XLS_MASK, PPCVSX2): New defines.
+ (powerpc_opcodes) <bcdadd., bcdsub., bctar, bctar, bctarl, clrbhrb,
+ fmrgew, fmrgow, lqarx, lxsiwax, lxsiwzx, lxsspx, mfbhrbe,
+ mffprd, mffprwz, mfvrd, mfvrwz, mfvsrd, mfvsrwz, msgclrp, msgsndp,
+ mtfprd, mtfprwa, mtfprwz, mtsle, mtvrd, mtvrwa, mtvrwz, mtvsrd,
+ mtvsrwa, mtvsrwz, pbt., rfebb, stqcx., stxsiwx, stxsspx,
+ vaddcuq, vaddecuq, vaddeuqm, vaddudm, vadduqm, vbpermq, vcipher,
+ vcipherlast, vclzb, vclzd, vclzh, vclzw, vcmpequd, vcmpequd.,
+ vcmpgtsd, vcmpgtsd., vcmpgtud, vcmpgtud., veqv, vgbbd, vmaxsd,
+ vmaxud, vminsd, vminud, vmrgew, vmrgow, vmulesw, vmuleuw, vmulosw,
+ vmulouw, vmuluwm, vnand, vncipher, vncipherlast, vorc, vpermxor,
+ vpksdss, vpksdus, vpkudum, vpkudus, vpmsumb, vpmsumd, vpmsumh,
+ vpmsumw, vpopcntb, vpopcntd, vpopcnth, vpopcntw, vrld, vsbox,
+ vshasigmad, vshasigmaw, vsld, vsrad, vsrd, vsubcuq, vsubecuq,
+ vsubeuqm, vsubudm, vsubuqm, vupkhsw, vupklsw, waitasec, xsaddsp,
+ xscvdpspn, xscvspdpn, xscvsxdsp, xscvuxdsp, xsdivsp, xsmaddasp,
+ xsmaddmsp, xsmsubasp, xsmsubmsp, xsmulsp, xsnmaddasp, xsnmaddmsp,
+ xsnmsubasp, xsnmsubmsp, xsresp, xsrsp, xsrsqrtesp, xssqrtsp,
+ xssubsp, xxleqv, xxlnand, xxlorc>: New instructions.
+ <lxvx, stxvx>: New extended mnemonics.
+
+2013-05-17 Alan Modra <amodra@gmail.com>
+
+ * ia64-raw.tbl: Replace non-ASCII char.
+ * ia64-waw.tbl: Likewise.
+ * ia64-asmtab.c: Regenerate.
+
+2013-05-15 Saravanan Ekanathan <saravanan.ekanathan@amd.com>
+
+ * i386-gen.c (cpu_flag_init): Add CpuFSGSBase in CPU_BDVER3_FLAGS.
+ * i386-init.h: Regenerated.
+
+2013-05-13 Yufeng Zhang <yufeng.zhang@arm.com>
+
+ * aarch64-asm.c (aarch64_ins_advsimd_imm_modified): Remove assertion.
+ * aarch64-opc.c (operand_general_constraint_met_p): Relax the range
+ check from [0, 255] to [-128, 255].
+
+2013-05-09 Andrew Pinski <apinski@cavium.com>
+
+ * mips-dis.c (mips_arch_choices): Add INSN_VIRT to mips32r2.
+ Add INSN_VIRT and INSN_VIRT64 to mips64r2.
+ (parse_mips_dis_option): Handle the virt option.
+ (print_insn_args): Handle "+J".
+ (print_mips_disassembler_options): Print out message about virt64.
+ * mips-opc.c (IVIRT): New define.
+ (IVIRT64): New define.
+ (mips_builtin_opcodes): Add dmfgc0, dmtgc0, hypcall, mfgc0, mtgc0,
+ tlbgr, tlbgwi, tlbginv, tlbginvf, tlbgwr, tlbgp VIRT instructions.
+ Move rfe to the bottom as it conflicts with tlbgp.
+
+2013-05-09 Alan Modra <amodra@gmail.com>
+
+ * ppc-opc.c (extract_vlesi): Properly sign extend.
+ (extract_vlensi): Likewise. Comment reason for setting invalid.
+
+2013-05-02 Nick Clifton <nickc@redhat.com>
+
+ * msp430-dis.c: Add support for MSP430X instructions.
+
2013-04-24 Sandra Loosemore <sandra@codesourcery.com>
* nios2-opc.c (nios2_builtin_reg): Rename "fstatus" control register
diff --git a/opcodes/aarch64-asm.c b/opcodes/aarch64-asm.c
index 7a92b49ac..96396e87d 100644
--- a/opcodes/aarch64-asm.c
+++ b/opcodes/aarch64-asm.c
@@ -370,7 +370,6 @@ aarch64_ins_advsimd_imm_modified (const aarch64_operand *self ATTRIBUTE_UNUSED,
imm = aarch64_shrink_expanded_imm8 (imm);
assert ((int)imm >= 0);
}
- assert (imm <= 255);
insert_fields (code, imm, 0, 2, FLD_defgh, FLD_abc);
if (kind == AARCH64_MOD_NONE)
diff --git a/opcodes/aarch64-opc.c b/opcodes/aarch64-opc.c
index b7b1b4a91..74f282603 100644
--- a/opcodes/aarch64-opc.c
+++ b/opcodes/aarch64-opc.c
@@ -1724,10 +1724,10 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
assert (idx == 1);
if (aarch64_get_qualifier_esize (opnds[0].qualifier) != 8)
{
- /* uimm8 */
- if (!value_in_range_p (opnd->imm.value, 0, 255))
+ /* uimm8 or simm8 */
+ if (!value_in_range_p (opnd->imm.value, -128, 255))
{
- set_imm_out_of_range_error (mismatch_detail, idx, 0, 255);
+ set_imm_out_of_range_error (mismatch_detail, idx, -128, 255);
return 0;
}
}
diff --git a/opcodes/i386-gen.c b/opcodes/i386-gen.c
index 3e7481b4d..7aff3fa56 100644
--- a/opcodes/i386-gen.c
+++ b/opcodes/i386-gen.c
@@ -93,7 +93,7 @@ static initializer cpu_flag_init[] =
{ "CPU_BDVER2_FLAGS",
"Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM|CpuFMA|CpuFMA4|CpuXOP|CpuLWP|CpuBMI|CpuTBM|CpuF16C|CpuCX16|CpuClflush|CpuSSSE3|CpuSVME|CpuSSE4_1|CpuSSE4_2|CpuXsave|CpuAES|CpuAVX|CpuPCLMUL|CpuLZCNT|CpuPRFCHW" },
{ "CPU_BDVER3_FLAGS",
- "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM|CpuFMA|CpuFMA4|CpuXOP|CpuLWP|CpuBMI|CpuTBM|CpuF16C|CpuCX16|CpuClflush|CpuSSSE3|CpuSVME|CpuSSE4_1|CpuSSE4_2|CpuAES|CpuAVX|CpuPCLMUL|CpuLZCNT|CpuPRFCHW|CpuXsave|CpuXsaveopt" },
+ "Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuFISTTP|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSE4a|CpuABM|CpuLM|CpuFMA|CpuFMA4|CpuXOP|CpuLWP|CpuBMI|CpuTBM|CpuF16C|CpuCX16|CpuClflush|CpuSSSE3|CpuSVME|CpuSSE4_1|CpuSSE4_2|CpuAES|CpuAVX|CpuPCLMUL|CpuLZCNT|CpuPRFCHW|CpuXsave|CpuXsaveopt|CpuFSGSBase" },
{ "CPU_BTVER1_FLAGS",
"Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686|CpuSYSCALL|CpuRdtscp|Cpu387|Cpu687|CpuNop|CpuMMX|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4a|CpuABM|CpuLM|CpuPRFCHW|CpuCX16|CpuClflush|CpuFISTTP|CpuSVME|CpuLZCNT" },
{ "CPU_BTVER2_FLAGS",
diff --git a/opcodes/i386-init.h b/opcodes/i386-init.h
index 3d484116e..d5b9c1557 100644
--- a/opcodes/i386-init.h
+++ b/opcodes/i386-init.h
@@ -172,7 +172,7 @@
#define CPU_BDVER3_FLAGS \
{ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, \
0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, \
- 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, \
+ 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, \
0, 0, 0, 0 } }
#define CPU_BTVER1_FLAGS \
diff --git a/opcodes/ia64-asmtab.c b/opcodes/ia64-asmtab.c
index f17dc918c..92e958cd6 100644
--- a/opcodes/ia64-asmtab.c
+++ b/opcodes/ia64-asmtab.c
@@ -102,7 +102,7 @@ dependencies[] = {
{ "CPUID#", 7, 0, 5, -1, NULL, },
{ "CR[CMCV]", 29, 0, 3, 74, NULL, },
{ "CR[DCR]", 29, 0, 3, 0, NULL, },
- { "CR[EOI]", 29, 0, 7, 67, "SC Section 5.8.3.4, \"End of External Interrupt Register (EOI Ð CR67)\" on page 2:119", },
+ { "CR[EOI]", 29, 0, 7, 67, "SC Section 5.8.3.4, \"End of External Interrupt Register (EOI - CR67)\" on page 2:119", },
{ "CR[GPTA]", 29, 0, 3, 9, NULL, },
{ "CR[IFA]", 29, 0, 1, 20, NULL, },
{ "CR[IFA]", 29, 0, 3, 20, NULL, },
@@ -124,13 +124,13 @@ dependencies[] = {
{ "CR[ITM]", 29, 0, 3, 1, NULL, },
{ "CR[ITV]", 29, 0, 3, 72, NULL, },
{ "CR[IVA]", 29, 0, 4, 2, NULL, },
- { "CR[IVR]", 29, 0, 7, 65, "SC Section 5.8.3.2, \"External Interrupt Vector Register (IVR Ð CR65)\" on page 2:118", },
- { "CR[LID]", 29, 0, 7, 64, "SC Section 5.8.3.1, \"Local ID (LID Ð CR64)\" on page 2:117", },
+ { "CR[IVR]", 29, 0, 7, 65, "SC Section 5.8.3.2, \"External Interrupt Vector Register (IVR - CR65)\" on page 2:118", },
+ { "CR[LID]", 29, 0, 7, 64, "SC Section 5.8.3.1, \"Local ID (LID - CR64)\" on page 2:117", },
{ "CR[LRR%], % in 0 - 1", 10, 0, 3, -1, NULL, },
{ "CR[PMV]", 29, 0, 3, 73, NULL, },
{ "CR[PTA]", 29, 0, 3, 8, NULL, },
{ "CR[TPR]", 29, 0, 3, 66, NULL, },
- { "CR[TPR]", 29, 0, 7, 66, "SC Section 5.8.3.3, \"Task Priority Register (TPR Ð CR66)\" on page 2:119", },
+ { "CR[TPR]", 29, 0, 7, 66, "SC Section 5.8.3.3, \"Task Priority Register (TPR - CR66)\" on page 2:119", },
{ "CR[TPR]", 29, 0, 1, 66, NULL, },
{ "CR%, % in 3-7, 10-15, 18, 28-63, 75-79, 82-127", 11, 0, 0, -1, NULL, },
{ "DAHR%, % in 0-7", 12, 0, 1, -1, NULL, },
@@ -305,7 +305,7 @@ dependencies[] = {
{ "CPUID#", 7, 1, 0, -1, NULL, },
{ "CR[CMCV]", 29, 1, 2, 74, NULL, },
{ "CR[DCR]", 29, 1, 2, 0, NULL, },
- { "CR[EOI]", 29, 1, 7, 67, "SC Section 5.8.3.4, \"End of External Interrupt Register (EOI Ð CR67)\" on page 2:119", },
+ { "CR[EOI]", 29, 1, 7, 67, "SC Section 5.8.3.4, \"End of External Interrupt Register (EOI - CR67)\" on page 2:119", },
{ "CR[GPTA]", 29, 1, 2, 9, NULL, },
{ "CR[IFA]", 29, 1, 2, 20, NULL, },
{ "CR[IFS]", 29, 1, 2, 23, NULL, },
diff --git a/opcodes/ia64-raw.tbl b/opcodes/ia64-raw.tbl
index 88d6ec56d..1dcb90820 100644
--- a/opcodes/ia64-raw.tbl
+++ b/opcodes/ia64-raw.tbl
@@ -45,7 +45,7 @@ CFM; alloc; IC:cfm-readers; none
CPUID#; IC:none; IC:mov-from-IND-CPUID+3; specific
CR[CMCV]; IC:mov-to-CR-CMCV; IC:mov-from-CR-CMCV; data
CR[DCR]; IC:mov-to-CR-DCR; IC:mov-from-CR-DCR, IC:mem-readers-spec; data
-CR[EOI]; IC:mov-to-CR-EOI; IC:none; SC Section 5.8.3.4, "End of External Interrupt Register (EOI Ð CR67)" on page 2:119
+CR[EOI]; IC:mov-to-CR-EOI; IC:none; SC Section 5.8.3.4, "End of External Interrupt Register (EOI - CR67)" on page 2:119
CR[GPTA]; IC:mov-to-CR-GPTA; IC:mov-from-CR-GPTA, thash; data
CR[IFA]; IC:mov-to-CR-IFA; itc.i, itc.d, itr.i, itr.d; implied
CR[IFA]; IC:mov-to-CR-IFA; IC:mov-from-CR-IFA; data
@@ -67,13 +67,13 @@ CR[ITIR]; IC:mov-to-CR-ITIR; itc.i, itc.d, itr.i, itr.d; implied
CR[ITM]; IC:mov-to-CR-ITM; IC:mov-from-CR-ITM; data
CR[ITV]; IC:mov-to-CR-ITV; IC:mov-from-CR-ITV; data
CR[IVA]; IC:mov-to-CR-IVA; IC:mov-from-CR-IVA; instr
-CR[IVR]; IC:none; IC:mov-from-CR-IVR; SC Section 5.8.3.2, "External Interrupt Vector Register (IVR Ð CR65)" on page 2:118
-CR[LID]; IC:mov-to-CR-LID; IC:mov-from-CR-LID; SC Section 5.8.3.1, "Local ID (LID Ð CR64)" on page 2:117
+CR[IVR]; IC:none; IC:mov-from-CR-IVR; SC Section 5.8.3.2, "External Interrupt Vector Register (IVR - CR65)" on page 2:118
+CR[LID]; IC:mov-to-CR-LID; IC:mov-from-CR-LID; SC Section 5.8.3.1, "Local ID (LID - CR64)" on page 2:117
CR[LRR%], % in 0 - 1; IC:mov-to-CR-LRR+1; IC:mov-from-CR-LRR+1; data
CR[PMV]; IC:mov-to-CR-PMV; IC:mov-from-CR-PMV; data
CR[PTA]; IC:mov-to-CR-PTA; IC:mov-from-CR-PTA, IC:mem-readers, IC:mem-writers, IC:non-access, thash; data
CR[TPR]; IC:mov-to-CR-TPR; IC:mov-from-CR-TPR, IC:mov-from-CR-IVR; data
-CR[TPR]; IC:mov-to-CR-TPR; IC:mov-to-PSR-l+17, ssm+17; SC Section 5.8.3.3, "Task Priority Register (TPR Ð CR66)" on page 2:119
+CR[TPR]; IC:mov-to-CR-TPR; IC:mov-to-PSR-l+17, ssm+17; SC Section 5.8.3.3, "Task Priority Register (TPR - CR66)" on page 2:119
CR[TPR]; IC:mov-to-CR-TPR; rfi; implied
CR%, % in 3-7, 10-15, 18, 28-63, 75-79, 82-127; IC:none; IC:mov-from-CR-rv+1; none
DAHR%, % in 0-7; br.call, brl.call, br.ret, IC:mov-to-DAHR; br.call, IC:mem-readers, IC:mem-writers, IC:mov-from-DAHR; implied
diff --git a/opcodes/ia64-waw.tbl b/opcodes/ia64-waw.tbl
index 44efaa831..6fe9a8435 100644
--- a/opcodes/ia64-waw.tbl
+++ b/opcodes/ia64-waw.tbl
@@ -44,7 +44,7 @@ CFM; IC:mod-sched-brs, br.call, brl.call, br.ret, alloc, clrrrb, cover, rfi; IC:
CPUID#; IC:none; IC:none; none
CR[CMCV]; IC:mov-to-CR-CMCV; IC:mov-to-CR-CMCV; impliedF
CR[DCR]; IC:mov-to-CR-DCR; IC:mov-to-CR-DCR; impliedF
-CR[EOI]; IC:mov-to-CR-EOI; IC:mov-to-CR-EOI; SC Section 5.8.3.4, "End of External Interrupt Register (EOI Ð CR67)" on page 2:119
+CR[EOI]; IC:mov-to-CR-EOI; IC:mov-to-CR-EOI; SC Section 5.8.3.4, "End of External Interrupt Register (EOI - CR67)" on page 2:119
CR[GPTA]; IC:mov-to-CR-GPTA; IC:mov-to-CR-GPTA; impliedF
CR[IFA]; IC:mov-to-CR-IFA; IC:mov-to-CR-IFA; impliedF
CR[IFS]; IC:mov-to-CR-IFS, cover; IC:mov-to-CR-IFS, cover; impliedF
diff --git a/opcodes/mips-dis.c b/opcodes/mips-dis.c
index 018ac94f3..834fd5c7d 100644
--- a/opcodes/mips-dis.c
+++ b/opcodes/mips-dis.c
@@ -590,7 +590,7 @@ const struct mips_arch_choice mips_arch_choices[] =
{ "mips32r2", 1, bfd_mach_mipsisa32r2, CPU_MIPS32R2,
(ISA_MIPS32R2 | INSN_SMARTMIPS | INSN_DSP | INSN_DSPR2
- | INSN_MIPS3D | INSN_MT | INSN_MCU),
+ | INSN_MIPS3D | INSN_MT | INSN_MCU | INSN_VIRT),
mips_cp0_names_mips3264r2,
mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
mips_hwr_names_mips3264r2 },
@@ -604,7 +604,7 @@ const struct mips_arch_choice mips_arch_choices[] =
{ "mips64r2", 1, bfd_mach_mipsisa64r2, CPU_MIPS64R2,
(ISA_MIPS64R2 | INSN_MIPS3D | INSN_DSP | INSN_DSPR2
- | INSN_DSP64 | INSN_MT | INSN_MDMX | INSN_MCU),
+ | INSN_DSP64 | INSN_MT | INSN_MDMX | INSN_MCU | INSN_VIRT | INSN_VIRT64),
mips_cp0_names_mips3264r2,
mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
mips_hwr_names_mips3264r2 },
@@ -824,6 +824,14 @@ parse_mips_dis_option (const char *option, unsigned int len)
no_aliases = 1;
return;
}
+
+ if (CONST_STRNEQ (option, "virt"))
+ {
+ mips_isa |= INSN_VIRT;
+ if (mips_isa & ISA_MIPS64R2)
+ mips_isa |= INSN_VIRT64;
+ return;
+ }
/* Look for the = that delimits the end of the option name. */
for (i = 0; i < len; i++)
@@ -1066,6 +1074,10 @@ print_insn_args (const char *d,
infprintf (is, "0x%x", msbd + 1);
break;
+ case 'J': /* hypcall operand */
+ infprintf (is, "0x%x", GET_OP (l, CODE10));
+ break;
+
case 't': /* Coprocessor 0 reg name */
infprintf (is, "%s", mips_cp0_names[GET_OP (l, RT)]);
break;
@@ -3034,6 +3046,9 @@ The following MIPS specific disassembler options are supported for use\n\
with the -M switch (multiple options should be separated by commas):\n"));
fprintf (stream, _("\n\
+ virt Recognize the virtualization ASE instructions.\n"));
+
+ fprintf (stream, _("\n\
gpr-names=ABI Print GPR names according to specified ABI.\n\
Default: based on binary being disassembled.\n"));
diff --git a/opcodes/mips-opc.c b/opcodes/mips-opc.c
index ee189c273..c22156d21 100644
--- a/opcodes/mips-opc.c
+++ b/opcodes/mips-opc.c
@@ -128,6 +128,8 @@
#define IOCTP (INSN_OCTEONP | INSN_OCTEON2)
#define IOCT2 INSN_OCTEON2
#define XLR INSN_XLR
+#define IVIRT INSN_VIRT
+#define IVIRT64 INSN_VIRT64
#define G1 (T3 \
|EE \
@@ -718,11 +720,17 @@ const struct mips_opcode mips_builtin_opcodes[] =
{"dmfc0", "t,G", 0x40200000, 0xffe007ff, LCD|WR_t|RD_C0, 0, I3, EE },
{"dmfc0", "t,+D", 0x40200000, 0xffe007f8, LCD|WR_t|RD_C0, 0, I64 },
{"dmfc0", "t,G,H", 0x40200000, 0xffe007f8, LCD|WR_t|RD_C0, 0, I64 },
+{"dmfgc0", "t,G", 0x40600100, 0xffe007ff, LCD|WR_t|RD_C0, 0, IVIRT64 },
+{"dmfgc0", "t,+D", 0x40600100, 0xffe007f8, LCD|WR_t|RD_C0, 0, IVIRT64 },
+{"dmfgc0", "t,G,H", 0x40600100, 0xffe007f8, LCD|WR_t|RD_C0, 0, IVIRT64 },
{"dmt", "", 0x41600bc1, 0xffffffff, TRAP, 0, MT32 },
{"dmt", "t", 0x41600bc1, 0xffe0ffff, TRAP|WR_t, 0, MT32 },
{"dmtc0", "t,G", 0x40a00000, 0xffe007ff, COD|RD_t|WR_C0|WR_CC, 0, I3, EE },
{"dmtc0", "t,+D", 0x40a00000, 0xffe007f8, COD|RD_t|WR_C0|WR_CC, 0, I64 },
{"dmtc0", "t,G,H", 0x40a00000, 0xffe007f8, COD|RD_t|WR_C0|WR_CC, 0, I64 },
+{"dmtgc0", "t,G", 0x40600300, 0xffe007ff, COD|RD_t|WR_C0|WR_CC, 0, IVIRT64 },
+{"dmtgc0", "t,+D", 0x40600300, 0xffe007f8, COD|RD_t|WR_C0|WR_CC, 0, IVIRT64 },
+{"dmtgc0", "t,G,H", 0x40600300, 0xffe007f8, COD|RD_t|WR_C0|WR_CC, 0, IVIRT64 },
{"dmfc1", "t,S", 0x44200000, 0xffe007ff, LCD|WR_t|RD_S|FP_D, 0, I3, SF },
{"dmfc1", "t,G", 0x44200000, 0xffe007ff, LCD|WR_t|RD_S|FP_D, 0, I3, SF },
{"dmtc1", "t,S", 0x44a00000, 0xffe007ff, COD|RD_t|WR_S|FP_D, 0, I3, SF },
@@ -811,6 +819,8 @@ const struct mips_opcode mips_builtin_opcodes[] =
{"floor.w.d", "D,S", 0x4620000f, 0xffff003f, WR_D|RD_S|FP_S|FP_D, 0, I2, SF },
{"floor.w.s", "D,S", 0x4600000f, 0xffff003f, WR_D|RD_S|FP_S, 0, I2 },
{"hibernate","", 0x42000023, 0xffffffff, 0, 0, V1 },
+{"hypcall", "", 0x42000028, 0xffffffff, TRAP, 0, IVIRT },
+{"hypcall", "+J", 0x42000028, 0xffe007ff, TRAP, 0, IVIRT },
{"ins", "t,r,+A,+B", 0x7c000004, 0xfc00003f, WR_t|RD_s, 0, I33 },
{"iret", "", 0x42000038, 0xffffffff, NODS, 0, MC },
{"jr", "s", 0x00000008, 0xfc1fffff, UBD|RD_s, 0, I1 },
@@ -904,6 +914,8 @@ const struct mips_opcode mips_builtin_opcodes[] =
{"lld", "t,A(b)", 0, (int) M_LLD_AB, INSN_MACRO, 0, I3, EE },
{"lq", "t,o(b)", 0x78000000, 0xfc000000, WR_t|RD_b, 0, MMI },
{"lq", "t,A(b)", 0, (int) M_LQ_AB, INSN_MACRO, 0, MMI },
+{"lqc2", "E,o(b)", 0xd8000000, 0xfc000000, RD_b|WR_C2, 0, EE },
+{"lqc2", "E,A(b)", 0, (int) M_LQC2_AB, INSN_MACRO, 0, EE },
{"lui", "t,u", 0x3c000000, 0xffe00000, WR_t, 0, I1 },
{"luxc1", "D,t(b)", 0x4c000005, 0xfc00f83f, LDD|WR_D|RD_t|RD_b|FP_D, 0, I5_33|N55},
{"lw", "t,o(b)", 0x8c000000, 0xfc000000, LDD|RD_b|WR_t, 0, I1 },
@@ -1010,6 +1022,9 @@ const struct mips_opcode mips_builtin_opcodes[] =
{"mfc0", "t,G", 0x40000000, 0xffe007ff, LCD|WR_t|RD_C0, 0, I1 },
{"mfc0", "t,+D",0x40000000, 0xffe007f8, LCD|WR_t|RD_C0, 0, I32 },
{"mfc0", "t,G,H", 0x40000000, 0xffe007f8, LCD|WR_t|RD_C0, 0, I32 },
+{"mfgc0", "t,G", 0x40600000, 0xffe007ff, LCD|WR_t|RD_C0, 0, IVIRT },
+{"mfgc0", "t,+D", 0x40600000, 0xffe007f8, LCD|WR_t|RD_C0, 0, IVIRT },
+{"mfgc0", "t,G,H", 0x40600000, 0xffe007f8, LCD|WR_t|RD_C0, 0, IVIRT },
{"mfc1", "t,S", 0x44000000, 0xffe007ff, LCD|WR_t|RD_S|FP_S, 0, I1 },
{"mfc1", "t,G", 0x44000000, 0xffe007ff, LCD|WR_t|RD_S|FP_S, 0, I1 },
{"mfhc1", "t,S", 0x44600000, 0xffe007ff, LCD|WR_t|RD_S|FP_D, 0, I33 },
@@ -1104,6 +1119,9 @@ const struct mips_opcode mips_builtin_opcodes[] =
{"mtc0", "t,G", 0x40800000, 0xffe007ff, COD|RD_t|WR_C0|WR_CC, 0, I1 },
{"mtc0", "t,+D", 0x40800000, 0xffe007f8, COD|RD_t|WR_C0|WR_CC, 0, I32 },
{"mtc0", "t,G,H", 0x40800000, 0xffe007f8, COD|RD_t|WR_C0|WR_CC, 0, I32 },
+{"mtgc0", "t,G", 0x40600200, 0xffe007ff, COD|RD_t|WR_C0|WR_CC, 0, IVIRT },
+{"mtgc0", "t,+D", 0x40600200, 0xffe007f8, COD|RD_t|WR_C0|WR_CC, 0, IVIRT },
+{"mtgc0", "t,G,H", 0x40600200, 0xffe007f8, COD|RD_t|WR_C0|WR_CC, 0, IVIRT },
{"mtc1", "t,S", 0x44800000, 0xffe007ff, COD|RD_t|WR_S|FP_S, 0, I1 },
{"mtc1", "t,G", 0x44800000, 0xffe007ff, COD|RD_t|WR_S|FP_S, 0, I1 },
{"mthc1", "t,S", 0x44e00000, 0xffe007ff, COD|RD_t|WR_S|FP_D, 0, I33 },
@@ -1379,7 +1397,7 @@ const struct mips_opcode mips_builtin_opcodes[] =
{"remu", "d,v,I", 0, (int) M_REMU_3I, INSN_MACRO, 0, I1 },
{"rdhwr", "t,K", 0x7c00003b, 0xffe007ff, WR_t, 0, I33 },
{"rdpgpr", "d,w", 0x41400000, 0xffe007ff, WR_d, 0, I33 },
-{"rfe", "", 0x42000010, 0xffffffff, 0, 0, I1|T3 },
+/* rfe is moved below as it now conflicts with tlbgp */
{"rnas.qh", "X,Q", 0x78200025, 0xfc20f83f, WR_D|RD_T|FP_D, RD_MACC, MX },
{"rnau.ob", "X,Q", 0x78000021, 0xfc20f83f, WR_D|RD_T|FP_D, RD_MACC, MX|SB1 },
{"rnau.qh", "X,Q", 0x78200021, 0xfc20f83f, WR_D|RD_T|FP_D, RD_MACC, MX },
@@ -1519,6 +1537,8 @@ const struct mips_opcode mips_builtin_opcodes[] =
{"snei", "t,r,+Q", 0x7000002f, 0xfc00003f, WR_t|RD_s, 0, IOCT },
{"sq", "t,o(b)", 0x7c000000, 0xfc000000, SM|RD_t|RD_b, 0, MMI },
{"sq", "t,A(b)", 0, (int) M_SQ_AB, INSN_MACRO, 0, MMI },
+{"sqc2", "E,o(b)", 0xf8000000, 0xfc000000, SM|RD_C2|RD_b, 0, EE },
+{"sqc2", "E,A(b)", 0, (int) M_SQC2_AB, INSN_MACRO, 0, EE },
{"sqrt.d", "D,S", 0x46200004, 0xffff003f, WR_D|RD_S|FP_D, 0, I2, SF },
{"sqrt.s", "D,S", 0x46000004, 0xffff003f, WR_D|RD_S|FP_S, 0, I2 },
{"sqrt.ps", "D,S", 0x46c00004, 0xffff003f, WR_D|RD_S|FP_D, 0, SB1 },
@@ -1624,6 +1644,12 @@ const struct mips_opcode mips_builtin_opcodes[] =
{"tlbr", "", 0x42000001, 0xffffffff, INSN_TLB, 0, I1 },
{"tlbwi", "", 0x42000002, 0xffffffff, INSN_TLB, 0, I1 },
{"tlbwr", "", 0x42000006, 0xffffffff, INSN_TLB, 0, I1 },
+{"tlbgr", "", 0x42000009, 0xffffffff, INSN_TLB, 0, IVIRT },
+{"tlbgwi", "", 0x4200000a, 0xffffffff, INSN_TLB, 0, IVIRT },
+{"tlbginv", "", 0x4200000b, 0xffffffff, INSN_TLB, 0, IVIRT },
+{"tlbginvf","", 0x4200000c, 0xffffffff, INSN_TLB, 0, IVIRT },
+{"tlbgwr", "", 0x4200000e, 0xffffffff, INSN_TLB, 0, IVIRT },
+{"tlbgp", "", 0x42000010, 0xffffffff, INSN_TLB, 0, IVIRT },
{"tlti", "s,j", 0x040a0000, 0xfc1f0000, RD_s|TRAP, 0, I2 },
{"tlt", "s,t", 0x00000032, 0xfc00ffff, RD_s|RD_t|TRAP, 0, I2 },
{"tlt", "s,t,q", 0x00000032, 0xfc00003f, RD_s|RD_t|TRAP, 0, I2 },
@@ -1759,16 +1785,20 @@ const struct mips_opcode mips_builtin_opcodes[] =
/* Coprocessor 2 move/branch operations overlap with VR5400 .ob format
instructions so they are here for the latters to take precedence. */
-{"bc2f", "p", 0x49000000, 0xffff0000, CBD|RD_CC, 0, I1, IOCT|IOCTP|IOCT2|EE },
+{"bc2f", "p", 0x49000000, 0xffff0000, CBD|RD_CC, 0, I1, IOCT|IOCTP|IOCT2 },
{"bc2f", "N,p", 0x49000000, 0xffe30000, CBD|RD_CC, 0, I32, IOCT|IOCTP|IOCT2 },
-{"bc2fl", "p", 0x49020000, 0xffff0000, CBL|RD_CC, 0, I2|T3, IOCT|IOCTP|IOCT2|EE },
+{"bc2fl", "p", 0x49020000, 0xffff0000, CBL|RD_CC, 0, I2|T3, IOCT|IOCTP|IOCT2 },
{"bc2fl", "N,p", 0x49020000, 0xffe30000, CBL|RD_CC, 0, I32, IOCT|IOCTP|IOCT2 },
-{"bc2t", "p", 0x49010000, 0xffff0000, CBD|RD_CC, 0, I1, IOCT|IOCTP|IOCT2|EE },
+{"bc2t", "p", 0x49010000, 0xffff0000, CBD|RD_CC, 0, I1, IOCT|IOCTP|IOCT2 },
{"bc2t", "N,p", 0x49010000, 0xffe30000, CBD|RD_CC, 0, I32, IOCT|IOCTP|IOCT2 },
-{"bc2tl", "p", 0x49030000, 0xffff0000, CBL|RD_CC, 0, I2|T3, IOCT|IOCTP|IOCT2|EE },
+{"bc2tl", "p", 0x49030000, 0xffff0000, CBL|RD_CC, 0, I2|T3, IOCT|IOCTP|IOCT2 },
{"bc2tl", "N,p", 0x49030000, 0xffe30000, CBL|RD_CC, 0, I32, IOCT|IOCTP|IOCT2 },
-{"cfc2", "t,G", 0x48400000, 0xffe007ff, LCD|WR_t|RD_C2, 0, I1, IOCT|IOCTP|IOCT2|EE },
-{"ctc2", "t,G", 0x48c00000, 0xffe007ff, COD|RD_t|WR_CC, 0, I1, IOCT|IOCTP|IOCT2|EE },
+{"cfc2", "t,G", 0x48400000, 0xffe007ff, LCD|WR_t|RD_C2, 0, I1, IOCT|IOCTP|IOCT2 },
+{"cfc2.i", "t,G", 0x48400001, 0xffe007ff, LCD|WR_t|RD_C2, 0, EE },
+{"cfc2.ni", "t,G", 0x48400000, 0xffe007ff, LCD|WR_t|RD_C2, 0, EE },
+{"ctc2", "t,G", 0x48c00000, 0xffe007ff, COD|RD_t|WR_CC, 0, I1, IOCT|IOCTP|IOCT2 },
+{"ctc2.i", "t,G", 0x48c00001, 0xffe007ff, COD|RD_t|WR_CC, 0, EE },
+{"ctc2.ni", "t,G", 0x48c00000, 0xffe007ff, COD|RD_t|WR_CC, 0, EE },
{"dmfc2", "t,i", 0x48200000, 0xffe00000, LCD|WR_t|RD_C2, 0, IOCT },
{"dmfc2", "t,G", 0x48200000, 0xffe007ff, LCD|WR_t|RD_C2, 0, I3, IOCT|IOCTP|IOCT2|EE },
{"dmfc2", "t,G,H", 0x48200000, 0xffe007f8, LCD|WR_t|RD_C2, 0, I64, IOCT|IOCTP|IOCT2 },
@@ -1785,7 +1815,12 @@ const struct mips_opcode mips_builtin_opcodes[] =
{"mthc2", "t,G", 0x48e00000, 0xffe007ff, COD|RD_t|WR_C2|WR_CC, 0, I33, IOCT|IOCTP|IOCT2 },
{"mthc2", "t,G,H", 0x48e00000, 0xffe007f8, COD|RD_t|WR_C2|WR_CC, 0, I33, IOCT|IOCTP|IOCT2 },
{"mthc2", "t,i", 0x48e00000, 0xffe00000, COD|RD_t|WR_C2|WR_CC, 0, I33, IOCT|IOCTP|IOCT2 },
-
+{"qmfc2", "t,G", 0x48200000, 0xffe007ff, WR_t|RD_C2, 0, EE },
+{"qmfc2.i", "t,G", 0x48200001, 0xffe007ff, WR_t|RD_C2, 0, EE },
+{"qmfc2.ni","t,G", 0x48200000, 0xffe007ff, WR_t|RD_C2, 0, EE },
+{"qmtc2", "t,G", 0x48a00000, 0xffe007ff, RD_t|WR_C2, 0, EE },
+{"qmtc2.i", "t,G", 0x48a00001, 0xffe007ff, RD_t|WR_C2, 0, EE },
+{"qmtc2.ni","t,G", 0x48a00000, 0xffe007ff, RD_t|WR_C2, 0, EE },
/* Coprocessor 3 move/branch operations overlap with MIPS IV COP1X
instructions, so they are here for the latters to take precedence. */
{"bc3f", "p", 0x4d000000, 0xffff0000, CBD|RD_CC, 0, I1, IOCT|IOCTP|IOCT2|EE },
@@ -2273,6 +2308,8 @@ const struct mips_opcode mips_builtin_opcodes[] =
{"cop1", "C", 0, (int) M_COP1, INSN_MACRO, INSN2_M_FP_S, I1 },
{"cop2", "C", 0, (int) M_COP2, INSN_MACRO, 0, I1, IOCT|IOCTP|IOCT2 },
{"cop3", "C", 0, (int) M_COP3, INSN_MACRO, 0, I1, IOCT|IOCTP|IOCT2 },
+/* RFE conflicts with the new Virt spec instruction tlbgp. */
+{"rfe", "", 0x42000010, 0xffffffff, 0, 0, I1|T3 },
};
#define MIPS_NUM_OPCODES \
diff --git a/opcodes/msp430-dis.c b/opcodes/msp430-dis.c
index 71690a3c6..46da3ccc6 100644
--- a/opcodes/msp430-dis.c
+++ b/opcodes/msp430-dis.c
@@ -1,7 +1,6 @@
/* Disassemble MSP430 instructions.
- Copyright (C) 2002, 2004, 2005, 2007, 2009, 2010, 2012
- Free Software Foundation, Inc.
-
+ Copyright (C) 2002-2013 Free Software Foundation, Inc.
+
Contributed by Dmitry Diky <diwil@mail.ru>
This file is part of the GNU opcodes library.
@@ -83,26 +82,80 @@ msp430_nooperands (struct msp430_opcode_s *opcode,
}
static int
+print_as2_reg_name (int regno, char * op1, char * comm1,
+ int c2, int c3, int cd)
+{
+ switch (regno)
+ {
+ case 2:
+ sprintf (op1, "#4");
+ sprintf (comm1, "r2 As==10");
+ return c2;
+
+ case 3:
+ sprintf (op1, "#2");
+ sprintf (comm1, "r3 As==10");
+ return c3;
+
+ default:
+ /* Indexed register mode @Rn. */
+ sprintf (op1, "@r%d", regno);
+ return cd;
+ }
+}
+
+static int
+print_as3_reg_name (int regno, char * op1, char * comm1,
+ int c2, int c3, int cd)
+{
+ switch (regno)
+ {
+ case 2:
+ sprintf (op1, "#8");
+ sprintf (comm1, "r2 As==11");
+ return c2;
+
+ case 3:
+ sprintf (op1, "#-1");
+ sprintf (comm1, "r3 As==11");
+ return c3;
+
+ default:
+ /* Post incremented @Rn+. */
+ sprintf (op1, "@r%d+", regno);
+ return cd;
+ }
+}
+
+static int
msp430_singleoperand (disassemble_info *info,
struct msp430_opcode_s *opcode,
bfd_vma addr,
unsigned short insn,
char *op,
char *comm,
+ unsigned short extension_word,
int *cycles)
{
int regs = 0, regd = 0;
int ad = 0, as = 0;
int where = 0;
int cmd_len = 2;
- short dst = 0;
+ int dst = 0;
+ int fmt;
+ int extended_dst = extension_word & 0xf;
regd = insn & 0x0f;
regs = (insn & 0x0f00) >> 8;
as = (insn & 0x0030) >> 4;
ad = (insn & 0x0080) >> 7;
- switch (opcode->fmt)
+ if (opcode->fmt < 0)
+ fmt = (- opcode->fmt) - 1;
+ else
+ fmt = opcode->fmt;
+
+ switch (fmt)
{
case 0: /* Emulated work with dst register. */
if (regs != 2 && regs != 3 && regs != 1)
@@ -146,6 +199,13 @@ msp430_singleoperand (disassemble_info *info,
sprintf (op, "0x%04x", dst);
sprintf (comm, "PC rel. abs addr 0x%04x",
PS ((short) (addr + 2) + dst));
+ if (extended_dst)
+ {
+ dst |= extended_dst << 16;
+ sprintf (op, "0x%05x", dst);
+ sprintf (comm, "PC rel. abs addr 0x%05lx",
+ (long)((addr + 2 + dst) & 0xfffff));
+ }
}
else if (regd == 2)
{
@@ -154,12 +214,25 @@ msp430_singleoperand (disassemble_info *info,
cmd_len += 2;
*cycles = 4;
sprintf (op, "&0x%04x", PS (dst));
+ if (extended_dst)
+ {
+ dst |= extended_dst << 16;
+ sprintf (op, "&0x%05x", dst & 0xfffff);
+ }
}
else
{
dst = msp430dis_opcode (addr + 2, info);
cmd_len += 2;
*cycles = 4;
+ if (extended_dst)
+ {
+ dst |= extended_dst << 16;
+ if (dst & 0x80000)
+ dst |= -1 << 20;
+ }
+ else if (dst & 0x8000)
+ dst |= -1 << 16;
sprintf (op, "%d(r%d)", dst, regd);
}
}
@@ -183,51 +256,31 @@ msp430_singleoperand (disassemble_info *info,
}
else if (as == 2)
{
- *cycles = 1;
- if (regd == 2)
- {
- sprintf (op, "#4");
- sprintf (comm, "r2 As==10");
- }
- else if (regd == 3)
- {
- sprintf (op, "#2");
- sprintf (comm, "r3 As==10");
- }
- else
- {
- *cycles = 3;
- /* Indexed register mode @Rn. */
- sprintf (op, "@r%d", regd);
- }
+ * cycles = print_as2_reg_name (regd, op, comm, 1, 1, 3);
}
else if (as == 3)
{
- *cycles = 1;
- if (regd == 2)
- {
- sprintf (op, "#8");
- sprintf (comm, "r2 As==11");
- }
- else if (regd == 3)
- {
- sprintf (op, "#-1");
- sprintf (comm, "r3 As==11");
- }
- else if (regd == 0)
+ if (regd == 0)
{
*cycles = 3;
/* absolute. @pc+ */
dst = msp430dis_opcode (addr + 2, info);
cmd_len += 2;
sprintf (op, "#%d", dst);
- sprintf (comm, "#0x%04x", PS (dst));
+ if (dst > 9 || dst < 0)
+ sprintf (comm, "#0x%04x", PS (dst));
+ if (extended_dst)
+ {
+ dst |= extended_dst << 16;
+ if (dst & 0x80000)
+ dst |= -1 << 20;
+ sprintf (op, "#%d", dst);
+ if (dst > 9 || dst < 0)
+ sprintf (comm, "#0x%05x", dst);
+ }
}
else
- {
- *cycles = 3;
- sprintf (op, "@r%d+", regd);
- }
+ * cycles = print_as3_reg_name (regd, op, comm, 1, 1, 3);
}
else if (as == 1)
{
@@ -240,6 +293,13 @@ msp430_singleoperand (disassemble_info *info,
sprintf (op, "0x%04x", PS (dst));
sprintf (comm, "PC rel. 0x%04x",
PS ((short) addr + 2 + dst));
+ if (extended_dst)
+ {
+ dst |= extended_dst << 16;
+ sprintf (op, "0x%05x", dst & 0xffff);
+ sprintf (comm, "PC rel. 0x%05lx",
+ (long)((addr + 2 + dst) & 0xfffff));
+ }
}
else if (regd == 2)
{
@@ -247,6 +307,11 @@ msp430_singleoperand (disassemble_info *info,
dst = msp430dis_opcode (addr + 2, info);
cmd_len += 2;
sprintf (op, "&0x%04x", PS (dst));
+ if (extended_dst)
+ {
+ dst |= extended_dst << 16;
+ sprintf (op, "&0x%05x", dst & 0xfffff);
+ }
}
else if (regd == 3)
{
@@ -256,10 +321,20 @@ msp430_singleoperand (disassemble_info *info,
}
else
{
- /* Indexd. */
+ /* Indexed. */
dst = msp430dis_opcode (addr + 2, info);
cmd_len += 2;
+ if (extended_dst)
+ {
+ dst |= extended_dst << 16;
+ if (dst & 0x80000)
+ dst |= -1 << 20;
+ }
+ else if (dst & 0x8000)
+ dst |= -1 << 16;
sprintf (op, "%d(r%d)", dst, regd);
+ if (dst > 9 || dst < 0)
+ sprintf (comm, "%05x", dst);
}
}
break;
@@ -273,7 +348,7 @@ msp430_singleoperand (disassemble_info *info,
where *= 2;
sprintf (op, "$%+-8d", where + 2);
- sprintf (comm, "abs 0x%x", PS ((short) (addr) + 2 + where));
+ sprintf (comm, "abs 0x%lx", (long) (addr + 2 + where));
*cycles = 2;
return 2;
break;
@@ -293,19 +368,28 @@ msp430_doubleoperand (disassemble_info *info,
char *op2,
char *comm1,
char *comm2,
+ unsigned short extension_word,
int *cycles)
{
int regs = 0, regd = 0;
int ad = 0, as = 0;
int cmd_len = 2;
- short dst = 0;
+ int dst = 0;
+ int fmt;
+ int extended_dst = extension_word & 0xf;
+ int extended_src = (extension_word >> 7) & 0xf;
regd = insn & 0x0f;
regs = (insn & 0x0f00) >> 8;
as = (insn & 0x0030) >> 4;
ad = (insn & 0x0080) >> 7;
- if (opcode->fmt == 0)
+ if (opcode->fmt < 0)
+ fmt = (- opcode->fmt) - 1;
+ else
+ fmt = opcode->fmt;
+
+ if (fmt == 0)
{
/* Special case: rla and rlc are the only 2 emulated instructions that
fall into two operand instructions. */
@@ -343,7 +427,15 @@ msp430_doubleoperand (disassemble_info *info,
sprintf (op1, "0x%04x", PS (dst));
sprintf (comm1, "PC rel. 0x%04x",
PS ((short) addr + 2 + dst));
-
+ if (extended_dst)
+ {
+ dst |= extended_dst << 16;
+ if (dst & 0x80000)
+ dst |= -1 << 20;
+ sprintf (op1, "0x%05x", dst & 0xfffff);
+ sprintf (comm1, "PC rel. 0x%05lx",
+ (long)((addr + 2 + dst) & 0xfffff));
+ }
}
else if (regd == 2)
{
@@ -356,19 +448,35 @@ msp430_doubleoperand (disassemble_info *info,
cmd_len += 4;
*cycles = 6;
sprintf (op1, "&0x%04x", PS (dst));
+ if (extended_dst)
+ {
+ dst |= extended_dst << 16;
+ sprintf (op1, "&0x%05x", dst & 0xfffff);
+ }
}
else
{
/* Indexed. */
dst = msp430dis_opcode (addr + 2, info);
+ if (extended_dst)
+ {
+ dst |= extended_dst << 16;
+ if (dst & 0x80000)
+ dst |= -1 << 20;
+ }
+ else if (dst & 0x8000)
+ dst |= -1 << 16;
cmd_len += 4;
*cycles = 6;
sprintf (op1, "%d(r%d)", dst, regd);
+ if (dst > 9 || dst < -9)
+ sprintf (comm1, "#0x%05x", dst);
}
}
*op2 = 0;
*comm2 = 0;
+
return cmd_len;
}
@@ -386,7 +494,7 @@ msp430_doubleoperand (disassemble_info *info,
*cycles = 1;
if (regs == 3)
{
- /* Constsnts. */
+ /* Constants. */
sprintf (op1, "#0");
sprintf (comm1, "r3 As==00");
}
@@ -398,56 +506,31 @@ msp430_doubleoperand (disassemble_info *info,
}
else if (as == 2)
{
- *cycles = 1;
-
- if (regs == 2)
- {
- sprintf (op1, "#4");
- sprintf (comm1, "r2 As==10");
- }
- else if (regs == 3)
- {
- sprintf (op1, "#2");
- sprintf (comm1, "r3 As==10");
- }
- else
- {
- *cycles = 2;
-
- /* Indexed register mode @Rn. */
- sprintf (op1, "@r%d", regs);
- }
- if (!regs)
- *cycles = 3;
+ * cycles = print_as2_reg_name (regs, op1, comm1, 1, 1, regs == 0 ? 3 : 2);
}
else if (as == 3)
{
- if (regs == 2)
- {
- sprintf (op1, "#8");
- sprintf (comm1, "r2 As==11");
- *cycles = 1;
- }
- else if (regs == 3)
- {
- sprintf (op1, "#-1");
- sprintf (comm1, "r3 As==11");
- *cycles = 1;
- }
- else if (regs == 0)
+ if (regs == 0)
{
*cycles = 3;
/* Absolute. @pc+. */
dst = msp430dis_opcode (addr + 2, info);
cmd_len += 2;
sprintf (op1, "#%d", dst);
- sprintf (comm1, "#0x%04x", PS (dst));
+ if (dst > 9 || dst < 0)
+ sprintf (comm1, "#0x%04x", PS (dst));
+ if (extended_src)
+ {
+ dst |= extended_src << 16;
+ if (dst & 0x80000)
+ dst |= -1 << 20;
+ sprintf (op1, "#%d", dst);
+ if (dst > 9 || dst < 0)
+ sprintf (comm1, "0x%05x", dst & 0xfffff);
+ }
}
else
- {
- *cycles = 2;
- sprintf (op1, "@r%d+", regs);
- }
+ * cycles = print_as3_reg_name (regs, op1, comm1, 1, 1, 2);
}
else if (as == 1)
{
@@ -460,6 +543,15 @@ msp430_doubleoperand (disassemble_info *info,
sprintf (op1, "0x%04x", PS (dst));
sprintf (comm1, "PC rel. 0x%04x",
PS ((short) addr + 2 + dst));
+ if (extended_src)
+ {
+ dst |= extended_src << 16;
+ if (dst & 0x80000)
+ dst |= -1 << 20;
+ sprintf (op1, "0x%05x", dst & 0xfffff);
+ sprintf (comm1, "PC rel. 0x%05lx",
+ (long) ((addr + 2 + dst) & 0xfffff));
+ }
}
else if (regs == 2)
{
@@ -469,6 +561,12 @@ msp430_doubleoperand (disassemble_info *info,
cmd_len += 2;
sprintf (op1, "&0x%04x", PS (dst));
sprintf (comm1, "0x%04x", PS (dst));
+ if (extended_src)
+ {
+ dst |= extended_src << 16;
+ sprintf (op1, "&0x%05x", dst & 0xfffff);
+ * comm1 = 0;
+ }
}
else if (regs == 3)
{
@@ -482,7 +580,17 @@ msp430_doubleoperand (disassemble_info *info,
/* Indexed. */
dst = msp430dis_opcode (addr + 2, info);
cmd_len += 2;
+ if (extended_src)
+ {
+ dst |= extended_src << 16;
+ if (dst & 0x80000)
+ dst |= -1 << 20;
+ }
+ else if (dst & 0x8000)
+ dst |= -1 << 16;
sprintf (op1, "%d(r%d)", dst, regs);
+ if (dst > 9 || dst < -9)
+ sprintf (comm1, "0x%05x", dst);
}
}
@@ -517,6 +625,15 @@ msp430_doubleoperand (disassemble_info *info,
sprintf (op2, "0x%04x", PS (dst));
sprintf (comm2, "PC rel. 0x%04x",
PS ((short) addr + cmd_len + dst));
+ if (extended_dst)
+ {
+ dst |= extended_dst << 16;
+ if (dst & 0x80000)
+ dst |= -1 << 20;
+ sprintf (op2, "0x%05x", dst & 0xfffff);
+ sprintf (comm2, "PC rel. 0x%05lx",
+ (long)((addr + cmd_len + dst) & 0xfffff));
+ }
cmd_len += 2;
}
else if (regd == 2)
@@ -525,11 +642,28 @@ msp430_doubleoperand (disassemble_info *info,
dst = msp430dis_opcode (addr + cmd_len, info);
cmd_len += 2;
sprintf (op2, "&0x%04x", PS (dst));
+ if (extended_dst)
+ {
+ dst |= extended_dst << 16;
+ sprintf (op2, "&0x%05x", dst & 0xfffff);
+ }
}
else
{
dst = msp430dis_opcode (addr + cmd_len, info);
cmd_len += 2;
+ if (dst & 0x8000)
+ dst |= -1 << 16;
+ if (dst > 9 || dst < 0)
+ sprintf (comm2, "0x%04x", PS (dst));
+ if (extended_dst)
+ {
+ dst |= extended_dst << 16;
+ if (dst & 0x80000)
+ dst |= -1 << 20;
+ if (dst > 9 || dst < 0)
+ sprintf (comm2, "0x%05x", dst & 0xfffff);
+ }
sprintf (op2, "%d(r%d)", dst, regd);
}
}
@@ -577,40 +711,11 @@ msp430_branchinstr (disassemble_info *info,
}
else if (as == 2)
{
- if (regs == 2)
- {
- *cycles = 2;
- sprintf (op1, "#4");
- sprintf (comm1, "r2 As==10");
- }
- else if (regs == 3)
- {
- *cycles = 1;
- sprintf (op1, "#2");
- sprintf (comm1, "r3 As==10");
- }
- else
- {
- /* Indexed register mode @Rn. */
- *cycles = 2;
- sprintf (op1, "@r%d", regs);
- }
+ * cycles = print_as2_reg_name (regs, op1, comm1, 2, 1, 2);
}
else if (as == 3)
{
- if (regs == 2)
- {
- *cycles = 1;
- sprintf (op1, "#8");
- sprintf (comm1, "r2 As==11");
- }
- else if (regs == 3)
- {
- *cycles = 1;
- sprintf (op1, "#-1");
- sprintf (comm1, "r3 As==11");
- }
- else if (regs == 0)
+ if (regs == 0)
{
/* Absolute. @pc+ */
*cycles = 3;
@@ -619,10 +724,7 @@ msp430_branchinstr (disassemble_info *info,
sprintf (op1, "#0x%04x", PS (dst));
}
else
- {
- *cycles = 2;
- sprintf (op1, "@r%d+", regs);
- }
+ * cycles = print_as3_reg_name (regs, op1, comm1, 1, 1, 2);
}
else if (as == 1)
{
@@ -653,9 +755,11 @@ msp430_branchinstr (disassemble_info *info,
}
else
{
- /* Indexd. */
+ /* Indexed. */
dst = msp430dis_opcode (addr + 2, info);
cmd_len += 2;
+ if (dst & 0x8000)
+ dst |= -1 << 16;
sprintf (op1, "%d(r%d)", dst, regs);
}
}
@@ -663,6 +767,82 @@ msp430_branchinstr (disassemble_info *info,
return cmd_len;
}
+static int
+msp430x_calla_instr (disassemble_info * info,
+ bfd_vma addr,
+ unsigned short insn,
+ char * op1,
+ char * comm1,
+ int * cycles)
+{
+ unsigned int ureg = insn & 0xf;
+ int reg = insn & 0xf;
+ int am = (insn & 0xf0) >> 4;
+ int cmd_len = 2;
+ unsigned short udst = 0;
+ short dst = 0;
+
+ switch (am)
+ {
+ case 4: /* CALLA Rdst */
+ *cycles = 1;
+ sprintf (op1, "r%d", reg);
+ break;
+
+ case 5: /* CALLA x(Rdst) */
+ *cycles = 3;
+ dst = msp430dis_opcode (addr + 2, info);
+ cmd_len += 2;
+ sprintf (op1, "%d(r%d)", dst, reg);
+ if (reg == 0)
+ sprintf (comm1, "PC rel. 0x%05lx", (long) (addr + 2 + dst));
+ else
+ sprintf (comm1, "0x%05x", dst);
+ break;
+
+ case 6: /* CALLA @Rdst */
+ *cycles = 2;
+ sprintf (op1, "@r%d", reg);
+ break;
+
+ case 7: /* CALLA @Rdst+ */
+ *cycles = 2;
+ sprintf (op1, "@r%d+", reg);
+ break;
+
+ case 8: /* CALLA &abs20 */
+ udst = msp430dis_opcode (addr + 2, info);
+ cmd_len += 2;
+ *cycles = 4;
+ sprintf (op1, "&%d", (ureg << 16) + udst);
+ sprintf (comm1, "0x%05x", (ureg << 16) + udst);
+ break;
+
+ case 9: /* CALLA pcrel-sym */
+ dst = msp430dis_opcode (addr + 2, info);
+ cmd_len += 2;
+ *cycles = 4;
+ sprintf (op1, "%d(PC)", (reg << 16) + dst);
+ sprintf (comm1, "PC rel. 0x%05lx",
+ (long) (addr + 2 + dst + (reg << 16)));
+ break;
+
+ case 11: /* CALLA #imm20 */
+ udst = msp430dis_opcode (addr + 2, info);
+ cmd_len += 2;
+ *cycles = 4;
+ sprintf (op1, "#%d", (ureg << 16) + udst);
+ sprintf (comm1, "0x%05x", (ureg << 16) + udst);
+ break;
+
+ default:
+ strcpy (comm1, _("unercognised CALLA addressing mode"));
+ return -1;
+ }
+
+ return cmd_len;
+}
+
int
print_insn_msp430 (bfd_vma addr, disassemble_info *info)
{
@@ -674,10 +854,14 @@ print_insn_msp430 (bfd_vma addr, disassemble_info *info)
unsigned short insn;
int cycles = 0;
char *bc = "";
- char dinfo[32]; /* Debug purposes. */
+ unsigned short extension_word = 0;
insn = msp430dis_opcode (addr, info);
- sprintf (dinfo, "0x%04x", insn);
+ if (insn == (unsigned short) -1)
+ {
+ prin (stream, ".word 0xffff; ????");
+ return 2;
+ }
if (((int) addr & 0xffff) > 0xffdf)
{
@@ -688,6 +872,20 @@ print_insn_msp430 (bfd_vma addr, disassemble_info *info)
*comm1 = 0;
*comm2 = 0;
+ /* Check for an extension word. */
+ if ((insn & 0xf800) == 0x1800)
+ {
+ extension_word = insn;
+ addr += 2;
+ insn = msp430dis_opcode (addr, info);
+ if (insn == (unsigned short) -1)
+ {
+ prin (stream, ".word 0x%04x, 0xffff; ????",
+ extension_word);
+ return 4;
+ }
+ }
+
for (opcode = msp430_opcodes; opcode->name; opcode++)
{
if ((insn & opcode->bin_mask) == opcode->bin_opcode
@@ -699,10 +897,11 @@ print_insn_msp430 (bfd_vma addr, disassemble_info *info)
*comm2 = 0;
/* r0 as destination. Ad should be zero. */
- if (opcode->insn_opnumb == 3 && (insn & 0x000f) == 0
- && (0x0080 & insn) == 0)
+ if (opcode->insn_opnumb == 3
+ && (insn & 0x000f) == 0
+ && (insn & 0x0080) == 0)
{
- cmd_len =
+ cmd_len +=
msp430_branchinstr (info, opcode, addr, insn, op1, comm1,
&cycles);
if (cmd_len)
@@ -711,22 +910,244 @@ print_insn_msp430 (bfd_vma addr, disassemble_info *info)
switch (opcode->insn_opnumb)
{
+ int n;
+ int reg;
+
+ case 4:
+ cmd_len += msp430x_calla_instr (info, addr, insn,
+ op1, comm1, & cycles);
+ break;
+
+ case 5: /* PUSHM/POPM */
+ n = (insn & 0xf0) >> 4;
+ reg = (insn & 0xf);
+
+ sprintf (op1, "#%d", n + 1);
+ if (opcode->bin_opcode == 0x1400)
+ /* PUSHM */
+ sprintf (op2, "r%d", reg);
+ else
+ /* POPM */
+ sprintf (op2, "r%d", reg + n);
+ if (insn & 0x100)
+ sprintf (comm1, "16-bit words");
+ else
+ {
+ sprintf (comm1, "20-bit words");
+ bc =".a";
+ }
+
+ cycles = 2; /*FIXME*/
+ cmd_len = 2;
+ break;
+
+ case 6: /* RRAM, RRCM, RRUM, RLAM. */
+ n = ((insn >> 10) & 0x3) + 1;
+ reg = (insn & 0xf);
+ if ((insn & 0x10) == 0)
+ bc =".a";
+ sprintf (op1, "#%d", n);
+ sprintf (op2, "r%d", reg);
+ cycles = 2; /*FIXME*/
+ cmd_len = 2;
+ break;
+
+ case 8: /* ADDA, CMPA, SUBA. */
+ reg = (insn & 0xf);
+ n = (insn >> 8) & 0xf;
+ if (insn & 0x40)
+ {
+ sprintf (op1, "r%d", n);
+ cmd_len = 2;
+ }
+ else
+ {
+ n <<= 16;
+ n |= msp430dis_opcode (addr + 2, info);
+ sprintf (op1, "#%d", n);
+ if (n > 9 || n < 0)
+ sprintf (comm1, "0x%05x", n);
+ cmd_len = 4;
+ }
+ sprintf (op2, "r%d", reg);
+ cycles = 2; /*FIXME*/
+ break;
+
+ case 9: /* MOVA */
+ reg = (insn & 0xf);
+ n = (insn >> 8) & 0xf;
+ switch ((insn >> 4) & 0xf)
+ {
+ case 0: /* MOVA @Rsrc, Rdst */
+ cmd_len = 2;
+ sprintf (op1, "@r%d", n);
+ if (strcmp (opcode->name, "bra") != 0)
+ sprintf (op2, "r%d", reg);
+ break;
+
+ case 1: /* MOVA @Rsrc+, Rdst */
+ cmd_len = 2;
+ if (strcmp (opcode->name, "reta") != 0)
+ {
+ sprintf (op1, "@r%d+", n);
+ if (strcmp (opcode->name, "bra") != 0)
+ sprintf (op2, "r%d", reg);
+ }
+ break;
+
+ case 2: /* MOVA &abs20, Rdst */
+ cmd_len = 4;
+ n <<= 16;
+ n |= msp430dis_opcode (addr + 2, info);
+ sprintf (op1, "&%d", n);
+ if (n > 9 || n < 0)
+ sprintf (comm1, "0x%05x", n);
+ if (strcmp (opcode->name, "bra") != 0)
+ sprintf (op2, "r%d", reg);
+ break;
+
+ case 3: /* MOVA x(Rsrc), Rdst */
+ cmd_len = 4;
+ if (strcmp (opcode->name, "bra") != 0)
+ sprintf (op2, "r%d", reg);
+ reg = n;
+ n = msp430dis_opcode (addr + 2, info);
+ if (n & 0x8000)
+ n |= -1 << 16;
+ sprintf (op1, "%d(r%d)", n, reg);
+ if (n > 9 || n < 0)
+ {
+ if (reg == 0)
+ sprintf (comm1, "PC rel. 0x%05lx",
+ (long) (addr + 2 + n));
+ else
+ sprintf (comm1, "0x%05x", n);
+ }
+ break;
+
+ case 6: /* MOVA Rsrc, &abs20 */
+ cmd_len = 4;
+ reg <<= 16;
+ reg |= msp430dis_opcode (addr + 2, info);
+ sprintf (op1, "r%d", n);
+ sprintf (op2, "&%d", reg);
+ if (reg > 9 || reg < 0)
+ sprintf (comm2, "0x%05x", reg);
+ break;
+
+ case 7: /* MOVA Rsrc, x(Rdst) */
+ cmd_len = 4;
+ sprintf (op1, "r%d", n);
+ n = msp430dis_opcode (addr + 2, info);
+ if (n & 0x8000)
+ n |= -1 << 16;
+ sprintf (op2, "%d(r%d)", n, reg);
+ if (n > 9 || n < 0)
+ {
+ if (reg == 0)
+ sprintf (comm2, "PC rel. 0x%05lx",
+ (long) (addr + 2 + n));
+ else
+ sprintf (comm2, "0x%05x", n);
+ }
+ break;
+
+ case 8: /* MOVA #imm20, Rdst */
+ cmd_len = 4;
+ n <<= 16;
+ n |= msp430dis_opcode (addr + 2, info);
+ if (n & 0x80000)
+ n |= -1 << 20;
+ sprintf (op1, "#%d", n);
+ if (n > 9 || n < 0)
+ sprintf (comm1, "0x%05x", n);
+ if (strcmp (opcode->name, "bra") != 0)
+ sprintf (op2, "r%d", reg);
+ break;
+
+ case 12: /* MOVA Rsrc, Rdst */
+ cmd_len = 2;
+ sprintf (op1, "r%d", n);
+ if (strcmp (opcode->name, "bra") != 0)
+ sprintf (op2, "r%d", reg);
+ break;
+
+ default:
+ break;
+ }
+ cycles = 2; /* FIXME */
+ break;
+ }
+
+ if (cmd_len)
+ break;
+
+ switch (opcode->insn_opnumb)
+ {
case 0:
- cmd_len = msp430_nooperands (opcode, addr, insn, comm1, &cycles);
+ cmd_len += msp430_nooperands (opcode, addr, insn, comm1, &cycles);
break;
case 2:
- cmd_len =
+ cmd_len +=
msp430_doubleoperand (info, opcode, addr, insn, op1, op2,
- comm1, comm2, &cycles);
+ comm1, comm2,
+ extension_word,
+ &cycles);
if (insn & BYTE_OPERATION)
- bc = ".b";
+ {
+ if (extension_word != 0 && ((extension_word & BYTE_OPERATION) == 0))
+ bc = ".a";
+ else
+ bc = ".b";
+ }
+ else if (extension_word)
+ {
+ if (extension_word & (1 << 6))
+ bc = ".w";
+ else
+ {
+ bc = ".?";
+ sprintf (comm2, _("Reserved use of A/L and B/W bits detected"));
+ }
+ }
+
break;
case 1:
- cmd_len =
+ cmd_len +=
msp430_singleoperand (info, opcode, addr, insn, op1, comm1,
+ extension_word,
&cycles);
- if (insn & BYTE_OPERATION && opcode->fmt != 3)
- bc = ".b";
+ if (extension_word
+ && (strcmp (opcode->name, "swpb") == 0
+ || strcmp (opcode->name, "sxt") == 0))
+ {
+ if (insn & BYTE_OPERATION)
+ {
+ bc = ".?";
+ sprintf (comm2, _("Reserved use of A/L and B/W bits detected"));
+ }
+ else if (extension_word & BYTE_OPERATION)
+ bc = ".w";
+ else
+ bc = ".a";
+ }
+ else if (insn & BYTE_OPERATION && opcode->fmt != 3)
+ {
+ if (extension_word != 0 && ((extension_word & BYTE_OPERATION) == 0))
+ bc = ".a";
+ else
+ bc = ".b";
+ }
+ else if (extension_word)
+ {
+ if (extension_word & (1 << 6))
+ bc = ".w";
+ else
+ {
+ bc = ".?";
+ sprintf (comm2, _("Reserved use of A/L and B/W bits detected"));
+ }
+ }
break;
default:
break;
@@ -737,16 +1158,33 @@ print_insn_msp430 (bfd_vma addr, disassemble_info *info)
break;
}
- dinfo[5] = 0;
-
if (cmd_len < 1)
{
/* Unknown opcode, or invalid combination of operands. */
+ if (extension_word)
+ {
+ prin (stream, ".word 0x%04x, 0x%04x; ????", extension_word, PS (insn));
+ if (*comm1)
+ prin (stream, "\t %s", comm1);
+ return 4;
+ }
(*prin) (stream, ".word 0x%04x; ????", PS (insn));
return 2;
}
- (*prin) (stream, "%s%s", opcode->name, bc);
+ /* Display the repeat count (if set) for extended register mode. */
+ if (cmd_len == 2 && ((extension_word & 0xf) != 0))
+ {
+ if (extension_word & (1 << 7))
+ prin (stream, "rpt r%d { ", extension_word & 0xf);
+ else
+ prin (stream, "rpt #%d { ", (extension_word & 0xf) + 1);
+ }
+
+ if (extension_word && opcode->name[strlen (opcode->name) - 1] != 'x')
+ (*prin) (stream, "%sx%s", opcode->name, bc);
+ else
+ (*prin) (stream, "%s%s", opcode->name, bc);
if (*op1)
(*prin) (stream, "\t%s", op1);
@@ -783,5 +1221,9 @@ print_insn_msp430 (bfd_vma addr, disassemble_info *info)
(*prin) (stream, ",");
if (*comm2)
(*prin) (stream, " %s", comm2);
+
+ if (extension_word)
+ cmd_len += 2;
+
return cmd_len;
}
diff --git a/opcodes/ppc-dis.c b/opcodes/ppc-dis.c
index 2c6869e63..4e2bcd783 100644
--- a/opcodes/ppc-dis.c
+++ b/opcodes/ppc-dis.c
@@ -315,10 +315,7 @@ powerpc_init_dialect (struct disassemble_info *info)
dialect = (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_VLE);
break;
default:
- dialect = (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64
- | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
- | PPC_OPCODE_POWER7 | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX
- | PPC_OPCODE_ANY);
+ dialect = ppc_parse_cpu (dialect, &sticky, "power8") | PPC_OPCODE_ANY;
}
arg = info->disassembler_options;
diff --git a/opcodes/ppc-opc.c b/opcodes/ppc-opc.c
index 80dfa2461..a257f861e 100644
--- a/opcodes/ppc-opc.c
+++ b/opcodes/ppc-opc.c
@@ -315,14 +315,18 @@ const struct powerpc_operand powerpc_operands[] =
{ 0xfffc, 0, NULL, NULL,
PPC_OPERAND_PARENS | PPC_OPERAND_SIGNED | PPC_OPERAND_DS },
- /* The DUIS field in a XFX form instruction, 10 bits unsigned imediate */
+ /* The DUIS or BHRBE fields in a XFX form instruction, 10 bits
+ unsigned imediate */
#define DUIS DS + 1
+#define BHRBE DUIS
{ 0x3ff, 11, NULL, NULL, 0 },
/* The E field in a wrteei instruction. */
/* And the W bit in the pair singles instructions. */
+ /* And the ST field in a VX form instruction. */
#define E DUIS + 1
#define PSW E
+#define ST E
{ 0x1, 15, NULL, NULL, 0 },
/* The FL1 field in a POWER SC form instruction. */
@@ -695,8 +699,16 @@ const struct powerpc_operand powerpc_operands[] =
#define UIMM3 UIMM + 1
{ 0x7, 16, NULL, NULL, 0 },
+ /* The SIX field in a VX form instruction. */
+#define SIX UIMM3 + 1
+ { 0xf, 11, NULL, NULL, 0 },
+
+ /* The PS field in a VX form instruction. */
+#define PS SIX + 1
+ { 0x1, 9, NULL, NULL, 0 },
+
/* The SHB field in a VA form instruction. */
-#define SHB UIMM3 + 1
+#define SHB PS + 1
{ 0xf, 6, NULL, NULL, 0 },
/* The other UIMM field in a half word EVX form instruction. */
@@ -751,8 +763,12 @@ const struct powerpc_operand powerpc_operands[] =
#define S SP + 1
{ 0x1, 20, NULL, NULL, 0 },
+ /* The S field in a XL form instruction. */
+#define SXL S + 1
+ { 0x1, 11, NULL, NULL, PPC_OPERAND_OPTIONAL },
+
/* SH field starting at bit position 16. */
-#define SH16 S + 1
+#define SH16 SXL + 1
/* The DCM and DGM fields in a Z form instruction. */
#define DCM SH16
#define DGM DCM
@@ -2022,11 +2038,8 @@ extract_vlesi (unsigned long insn,
ppc_cpu_t dialect ATTRIBUTE_UNUSED,
int *invalid ATTRIBUTE_UNUSED)
{
- /* RWRW Because I don't know how to make int be 16 and long be 32 */
- /* I can't rely on casting an int to long to get sign extension. */
long value = ((insn >> 10) & 0xf800) | (insn & 0x7ff);
- if (value & 0x8000)
- value |= 0xffff0000;
+ value = (value ^ 0x8000) - 0x8000;
return value;
}
@@ -2045,8 +2058,8 @@ extract_vlensi (unsigned long insn,
int *invalid ATTRIBUTE_UNUSED)
{
long value = ((insn >> 10) & 0xf800) | (insn & 0x7ff);
- if (value & 0x8000)
- value |= 0xffff0000;
+ value = (value ^ 0x8000) - 0x8000;
+ /* Don't use for disassembly. */
*invalid = 1;
return -value;
}
@@ -2328,6 +2341,9 @@ extract_vleil (unsigned long insn,
/* A VX_MASK with a UIMM2 field. */
#define VXUIMM2_MASK (VX_MASK | (0x7 << 18))
+/* A VX_MASK with a PS field. */
+#define VXPS_MASK (VX_MASK & ~(0x1 << 9))
+
/* A VA form instruction. */
#define VXA(op, xop) (OP (op) | (((unsigned long)(xop)) & 0x03f))
@@ -2382,6 +2398,9 @@ extract_vleil (unsigned long insn,
/* The mask for an XX1 form instruction. */
#define XX1_MASK X (0x3f, 0x3ff)
+/* An XX1_MASK with the RB field fixed. */
+#define XX1RB_MASK (XX1_MASK | RB_MASK)
+
/* The mask for an XX2 form instruction. */
#define XX2_MASK (XX2 (0x3f, 0x1ff) | (0x1f << 16))
@@ -2519,6 +2538,9 @@ extract_vleil (unsigned long insn,
/* The mask for an XL form instruction. */
#define XL_MASK XLLK (0x3f, 0x3ff, 1)
+/* An XL_MASK with the RT, RA and RB fields fixed, but S bit clear. */
+#define XLS_MASK ((XL_MASK | RT_MASK | RA_MASK | RB_MASK) & ~(1 << 11))
+
/* An XL form instruction which explicitly sets the BO field. */
#define XLO(op, bo, xop, lk) \
(XLLK ((op), (xop), (lk)) | ((((unsigned long)(bo)) & 0x1f) << 21))
@@ -2702,6 +2724,7 @@ extract_vleil (unsigned long insn,
#define PPCVEC PPC_OPCODE_ALTIVEC
#define PPCVEC2 PPC_OPCODE_ALTIVEC2
#define PPCVSX PPC_OPCODE_VSX
+#define PPCVSX2 PPC_OPCODE_VSX
#define POWER PPC_OPCODE_POWER
#define POWER2 PPC_OPCODE_POWER | PPC_OPCODE_POWER2
#define PWR2COM PPC_OPCODE_POWER | PPC_OPCODE_POWER2 | PPC_OPCODE_COMMON
@@ -2848,6 +2871,7 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"vperm", VXA(4, 43), VXA_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB, VC}},
{"vsldoi", VXA(4, 44), VXASHB_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB, SHB}},
{"ps_sel", A (4, 23,0), A_MASK, PPCPS, PPCNONE, {FRT, FRA, FRC, FRB}},
+{"vpermxor", VXA(4, 45), VXA_MASK, PPCVEC2, PPCNONE, {VD, VA, VB, VC}},
{"vmaddfp", VXA(4, 46), VXA_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VC, VB}},
{"ps_sel.", A (4, 23,1), A_MASK, PPCPS, PPCNONE, {FRT, FRA, FRC, FRB}},
{"vnmsubfp", VXA(4, 47), VXA_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VC, VB}},
@@ -2866,6 +2890,10 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"ps_nmadd", A (4, 31,0), A_MASK, PPCPS, PPCNONE, {FRT, FRA, FRC, FRB}},
{"ps_nmadd.", A (4, 31,1), A_MASK, PPCPS, PPCNONE, {FRT, FRA, FRC, FRB}},
{"ps_cmpo0", X (4, 32), X_MASK|(3<<21), PPCPS, PPCNONE, {BF, FRA, FRB}},
+{"vaddeuqm", VXA(4, 60), VXA_MASK, PPCVEC2, PPCNONE, {VD, VA, VB, VC}},
+{"vaddecuq", VXA(4, 61), VXA_MASK, PPCVEC2, PPCNONE, {VD, VA, VB, VC}},
+{"vsubeuqm", VXA(4, 62), VXA_MASK, PPCVEC2, PPCNONE, {VD, VA, VB, VC}},
+{"vsubecuq", VXA(4, 63), VXA_MASK, PPCVEC2, PPCNONE, {VD, VA, VB, VC}},
{"vadduhm", VX (4, 64), VX_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
{"vmaxuh", VX (4, 66), VX_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
{"vrlh", VX (4, 68), VX_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
@@ -2889,6 +2917,8 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"vmaxuw", VX (4, 130), VX_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
{"vrlw", VX (4, 132), VX_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
{"vcmpequw", VXR(4, 134,0), VXR_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
+{"vmulouw", VX (4, 136), VX_MASK, PPCVEC2, PPCNONE, {VD, VA, VB}},
+{"vmuluwm", VX (4, 137), VX_MASK, PPCVEC2, PPCNONE, {VD, VA, VB}},
{"vmrghw", VX (4, 140), VX_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
{"vpkuhus", VX (4, 142), VX_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
{"ps_mr", XRC(4, 72,0), XRA_MASK, PPCPS, PPCNONE, {FRT, FRB}},
@@ -2896,12 +2926,17 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"machhwsu", XO (4, 76,0,0),XO_MASK, MULHW|PPCVLE, PPCNONE, {RT, RA, RB}},
{"machhwsu.", XO (4, 76,0,1),XO_MASK, MULHW|PPCVLE, PPCNONE, {RT, RA, RB}},
{"ps_cmpo1", X (4, 96), X_MASK|(3<<21), PPCPS, PPCNONE, {BF, FRA, FRB}},
+{"vaddudm", VX (4, 192), VX_MASK, PPCVEC2, PPCNONE, {VD, VA, VB}},
+{"vmaxud", VX (4, 194), VX_MASK, PPCVEC2, PPCNONE, {VD, VA, VB}},
+{"vrld", VX (4, 196), VX_MASK, PPCVEC2, PPCNONE, {VD, VA, VB}},
{"vcmpeqfp", VXR(4, 198,0), VXR_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
+{"vcmpequd", VXR(4, 199,0), VXR_MASK, PPCVEC2, PPCNONE, {VD, VA, VB}},
{"vpkuwus", VX (4, 206), VX_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
{"machhws", XO (4, 108,0,0),XO_MASK, MULHW|PPCVLE, PPCNONE, {RT, RA, RB}},
{"machhws.", XO (4, 108,0,1),XO_MASK, MULHW|PPCVLE, PPCNONE, {RT, RA, RB}},
{"nmachhws", XO (4, 110,0,0),XO_MASK, MULHW|PPCVLE, PPCNONE, {RT, RA, RB}},
{"nmachhws.", XO (4, 110,0,1),XO_MASK, MULHW|PPCVLE, PPCNONE, {RT, RA, RB}},
+{"vadduqm", VX (4, 256), VX_MASK, PPCVEC2, PPCNONE, {VD, VA, VB}},
{"vmaxsb", VX (4, 258), VX_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
{"vslb", VX (4, 260), VX_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
{"vmulosb", VX (4, 264), VX_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
@@ -2914,6 +2949,7 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"mulchwu.", XRC(4, 136,1), X_MASK, MULHW|PPCVLE, PPCNONE, {RT, RA, RB}},
{"macchwu", XO (4, 140,0,0),XO_MASK, MULHW|PPCVLE, PPCNONE, {RT, RA, RB}},
{"macchwu.", XO (4, 140,0,1),XO_MASK, MULHW|PPCVLE, PPCNONE, {RT, RA, RB}},
+{"vaddcuq", VX (4, 320), VX_MASK, PPCVEC2, PPCNONE, {VD, VA, VB}},
{"vmaxsh", VX (4, 322), VX_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
{"vslh", VX (4, 324), VX_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
{"vmulosh", VX (4, 328), VX_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
@@ -2929,11 +2965,13 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"vaddcuw", VX (4, 384), VX_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
{"vmaxsw", VX (4, 386), VX_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
{"vslw", VX (4, 388), VX_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
+{"vmulosw", VX (4, 392), VX_MASK, PPCVEC2, PPCNONE, {VD, VA, VB}},
{"vexptefp", VX (4, 394), VXVA_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VB}},
{"vmrglw", VX (4, 396), VX_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
{"vpkshss", VX (4, 398), VX_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
{"macchwsu", XO (4, 204,0,0),XO_MASK, MULHW|PPCVLE, PPCNONE, {RT, RA, RB}},
{"macchwsu.", XO (4, 204,0,1),XO_MASK, MULHW|PPCVLE, PPCNONE, {RT, RA, RB}},
+{"vmaxsd", VX (4, 450), VX_MASK, PPCVEC2, PPCNONE, {VD, VA, VB}},
{"vsl", VX (4, 452), VX_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
{"vcmpgefp", VXR(4, 454,0), VXR_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
{"vlogefp", VX (4, 458), VXVA_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VB}},
@@ -3017,6 +3055,7 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"evfsnabs", VX (4, 645), VX_MASK, PPCSPE|PPCVLE, PPCNONE, {RS, RA}},
{"evfsneg", VX (4, 646), VX_MASK, PPCSPE|PPCVLE, PPCNONE, {RS, RA}},
{"vcmpgtuw", VXR(4, 646,0), VXR_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
+{"vmuleuw", VX (4, 648), VX_MASK, PPCVEC2, PPCNONE, {VD, VA, VB}},
{"evfsmul", VX (4, 648), VX_MASK, PPCSPE|PPCVLE, PPCNONE, {RS, RA, RB}},
{"evfsdiv", VX (4, 649), VX_MASK, PPCSPE|PPCVLE, PPCNONE, {RS, RA, RB}},
{"vrfip", VX (4, 650), VXVA_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VB}},
@@ -3042,11 +3081,13 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"cput", APU(4, 348,0), APU_RT_MASK, PPC405, PPCNONE, {RA, FSL}},
{"efsadd", VX (4, 704), VX_MASK, PPCEFS|PPCVLE, PPCNONE, {RS, RA, RB}},
{"efssub", VX (4, 705), VX_MASK, PPCEFS|PPCVLE, PPCNONE, {RS, RA, RB}},
+{"vminud", VX (4, 706), VX_MASK, PPCVEC2, PPCNONE, {VD, VA, VB}},
{"efsabs", VX (4, 708), VX_MASK, PPCEFS|PPCVLE, PPCNONE, {RS, RA}},
{"vsr", VX (4, 708), VX_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
{"efsnabs", VX (4, 709), VX_MASK, PPCEFS|PPCVLE, PPCNONE, {RS, RA}},
{"efsneg", VX (4, 710), VX_MASK, PPCEFS|PPCVLE, PPCNONE, {RS, RA}},
{"vcmpgtfp", VXR(4, 710,0), VXR_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
+{"vcmpgtud", VXR(4, 711,0), VXR_MASK, PPCVEC2, PPCNONE, {VD, VA, VB}},
{"efsmul", VX (4, 712), VX_MASK, PPCEFS|PPCVLE, PPCNONE, {RS, RA, RB}},
{"efsdiv", VX (4, 713), VX_MASK, PPCEFS|PPCVLE, PPCNONE, {RS, RA, RB}},
{"vrfim", VX (4, 714), VXVA_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VB}},
@@ -3166,12 +3207,16 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"vminsw", VX (4, 898), VX_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
{"vsraw", VX (4, 900), VX_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
{"vcmpgtsw", VXR(4, 902,0), VXR_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
+{"vmulesw", VX (4, 904), VX_MASK, PPCVEC2, PPCNONE, {VD, VA, VB}},
{"vctuxs", VX (4, 906), VX_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VB, UIMM}},
{"vcfpuxws", VX (4, 906), VX_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VB, UIMM}},
{"vspltisw", VX (4, 908), VXVB_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, SIMM}},
{"maclhwsu", XO (4, 460,0,0),XO_MASK, MULHW|PPCVLE, PPCNONE, {RT, RA, RB}},
{"maclhwsu.", XO (4, 460,0,1),XO_MASK, MULHW|PPCVLE, PPCNONE, {RT, RA, RB}},
+{"vminsd", VX (4, 962), VX_MASK, PPCVEC2, PPCNONE, {VD, VA, VB}},
+{"vsrad", VX (4, 964), VX_MASK, PPCVEC2, PPCNONE, {VD, VA, VB}},
{"vcmpbfp", VXR(4, 966,0), VXR_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
+{"vcmpgtsd", VXR(4, 967,0), VXR_MASK, PPCVEC2, PPCNONE, {VD, VA, VB}},
{"vctsxs", VX (4, 970), VX_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VB, UIMM}},
{"vcfpsxws", VX (4, 970), VX_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VB, UIMM}},
{"vupklpx", VX (4, 974), VXVA_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VB}},
@@ -3180,6 +3225,7 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"nmaclhws", XO (4, 494,0,0),XO_MASK, MULHW|PPCVLE, PPCNONE, {RT, RA, RB}},
{"nmaclhws.", XO (4, 494,0,1),XO_MASK, MULHW|PPCVLE, PPCNONE, {RT, RA, RB}},
{"vsububm", VX (4,1024), VX_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
+{"bcdadd.", VX (4,1025), VXPS_MASK, PPCVEC2, PPCNONE, {VD, VA, VB, PS}},
{"vavgub", VX (4,1026), VX_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
{"vabsdub", VX (4,1027), VX_MASK, PPCVEC2, PPCNONE, {VD, VA, VB}},
{"evmhessf", VX (4,1027), VX_MASK, PPCSPE|PPCVLE, PPCNONE, {RS, RA, RB}},
@@ -3188,6 +3234,7 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"udi0fcm.", APU(4, 515,0), APU_MASK, PPC405|PPC440, PPC476, {URT, URA, URB}},
{"udi0fcm", APU(4, 515,1), APU_MASK, PPC405|PPC440, PPC476, {URT, URA, URB}},
{"evmhossf", VX (4,1031), VX_MASK, PPCSPE|PPCVLE, PPCNONE, {RS, RA, RB}},
+{"vpmsumb", VX (4,1032), VX_MASK, PPCVEC2, PPCNONE, {VD, VA, VB}},
{"evmheumi", VX (4,1032), VX_MASK, PPCSPE|PPCVLE, PPCNONE, {RS, RA, RB}},
{"evmhesmi", VX (4,1033), VX_MASK, PPCSPE|PPCVLE, PPCNONE, {RS, RA, RB}},
{"vmaxfp", VX (4,1034), VX_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
@@ -3209,6 +3256,7 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"evmhosmia", VX (4,1069), VX_MASK, PPCSPE|PPCVLE, PPCNONE, {RS, RA, RB}},
{"evmhosmfa", VX (4,1071), VX_MASK, PPCSPE|PPCVLE, PPCNONE, {RS, RA, RB}},
{"vsubuhm", VX (4,1088), VX_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
+{"bcdsub.", VX (4,1089), VXPS_MASK, PPCVEC2, PPCNONE, {VD, VA, VB, PS}},
{"vavguh", VX (4,1090), VX_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
{"vabsduh", VX (4,1091), VX_MASK, PPCVEC2, PPCNONE, {VD, VA, VB}},
{"vandc", VX (4,1092), VX_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
@@ -3216,11 +3264,13 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"udi1fcm.", APU(4, 547,0), APU_MASK, PPC405|PPC440, PPC476, {URT, URA, URB}},
{"udi1fcm", APU(4, 547,1), APU_MASK, PPC405|PPC440, PPC476, {URT, URA, URB}},
{"evmwhssf", VX (4,1095), VX_MASK, PPCSPE|PPCVLE, PPCNONE, {RS, RA, RB}},
+{"vpmsumh", VX (4,1096), VX_MASK, PPCVEC2, PPCNONE, {VD, VA, VB}},
{"evmwlumi", VX (4,1096), VX_MASK, PPCSPE|PPCVLE, PPCNONE, {RS, RA, RB}},
{"vminfp", VX (4,1098), VX_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
{"evmwhumi", VX (4,1100), VX_MASK, PPCSPE|PPCVLE, PPCNONE, {RS, RA, RB}},
{"vsro", VX (4,1100), VX_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
{"evmwhsmi", VX (4,1101), VX_MASK, PPCSPE|PPCVLE, PPCNONE, {RS, RA, RB}},
+{"vpkudum", VX (4,1102), VX_MASK, PPCVEC2, PPCNONE, {VD, VA, VB}},
{"evmwhsmf", VX (4,1103), VX_MASK, PPCSPE|PPCVLE, PPCNONE, {RS, RA, RB}},
{"evmwssf", VX (4,1107), VX_MASK, PPCSPE|PPCVLE, PPCNONE, {RS, RA, RB}},
{"machhwo", XO (4, 44,1,0),XO_MASK, MULHW|PPCVLE, PPCNONE, {RT, RA, RB}},
@@ -3246,6 +3296,7 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"vabsduw", VX (4,1155), VX_MASK, PPCVEC2, PPCNONE, {VD, VA, VB}},
{"vmr", VX (4,1156), VX_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VBA}},
{"vor", VX (4,1156), VX_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
+{"vpmsumw", VX (4,1160), VX_MASK, PPCVEC2, PPCNONE, {VD, VA, VB}},
{"vcmpequw.", VXR(4, 134,1), VXR_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
{"udi2fcm.", APU(4, 579,0), APU_MASK, PPC405|PPC440, PPC476, {URT, URA, URB}},
{"udi2fcm", APU(4, 579,1), APU_MASK, PPC405|PPC440, PPC476, {URT, URA, URB}},
@@ -3253,6 +3304,7 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"machhwsuo.", XO (4, 76,1,1),XO_MASK, MULHW|PPCVLE, PPCNONE, {RT, RA, RB}},
{"ps_merge10", XOPS(4,592,0), XOPS_MASK, PPCPS, PPCNONE, {FRT, FRA, FRB}},
{"ps_merge10.", XOPS(4,592,1), XOPS_MASK, PPCPS, PPCNONE, {FRT, FRA, FRB}},
+{"vsubudm", VX (4,1216), VX_MASK, PPCVEC2, PPCNONE, {VD, VA, VB}},
{"evaddusiaaw", VX (4,1216), VX_MASK, PPCSPE|PPCVLE, PPCNONE, {RS, RA}},
{"evaddssiaaw", VX (4,1217), VX_MASK, PPCSPE|PPCVLE, PPCNONE, {RS, RA}},
{"evsubfusiaaw",VX (4,1218), VX_MASK, PPCSPE|PPCVLE, PPCNONE, {RS, RA}},
@@ -3262,18 +3314,22 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"evdivws", VX (4,1222), VX_MASK, PPCSPE|PPCVLE, PPCNONE, {RS, RA, RB}},
{"vcmpeqfp.", VXR(4, 198,1), VXR_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
{"udi3fcm.", APU(4, 611,0), APU_MASK, PPC405|PPC440, PPC476, {URT, URA, URB}},
+{"vcmpequd.", VXR(4, 199,1), VXR_MASK, PPCVEC2, PPCNONE, {VD, VA, VB}},
{"udi3fcm", APU(4, 611,1), APU_MASK, PPC405|PPC440, PPC476, {URT, URA, URB}},
{"evdivwu", VX (4,1223), VX_MASK, PPCSPE|PPCVLE, PPCNONE, {RS, RA, RB}},
+{"vpmsumd", VX (4,1224), VX_MASK, PPCVEC2, PPCNONE, {VD, VA, VB}},
{"evaddumiaaw", VX (4,1224), VX_MASK, PPCSPE|PPCVLE, PPCNONE, {RS, RA}},
{"evaddsmiaaw", VX (4,1225), VX_MASK, PPCSPE|PPCVLE, PPCNONE, {RS, RA}},
{"evsubfumiaaw",VX (4,1226), VX_MASK, PPCSPE|PPCVLE, PPCNONE, {RS, RA}},
{"evsubfsmiaaw",VX (4,1227), VX_MASK, PPCSPE|PPCVLE, PPCNONE, {RS, RA}},
+{"vpkudus", VX (4,1230), VX_MASK, PPCVEC2, PPCNONE, {VD, VA, VB}},
{"machhwso", XO (4, 108,1,0),XO_MASK, MULHW|PPCVLE, PPCNONE, {RT, RA, RB}},
{"machhwso.", XO (4, 108,1,1),XO_MASK, MULHW|PPCVLE, PPCNONE, {RT, RA, RB}},
{"nmachhwso", XO (4, 110,1,0),XO_MASK, MULHW|PPCVLE, PPCNONE, {RT, RA, RB}},
{"nmachhwso.", XO (4, 110,1,1),XO_MASK, MULHW|PPCVLE, PPCNONE, {RT, RA, RB}},
{"ps_merge11", XOPS(4,624,0), XOPS_MASK, PPCPS, PPCNONE, {FRT, FRA, FRB}},
{"ps_merge11.", XOPS(4,624,1), XOPS_MASK, PPCPS, PPCNONE, {FRT, FRA, FRB}},
+{"vsubuqm", VX (4,1280), VX_MASK, PPCVEC2, PPCNONE, {VD, VA, VB}},
{"evmheusiaaw", VX (4,1280), VX_MASK, PPCSPE|PPCVLE, PPCNONE, {RS, RA, RB}},
{"evmhessiaaw", VX (4,1281), VX_MASK, PPCSPE|PPCVLE, PPCNONE, {RS, RA, RB}},
{"vavgsb", VX (4,1282), VX_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
@@ -3286,8 +3342,11 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"udi4fcm", APU(4, 643,1), APU_MASK, PPC405|PPC440, PPC476, {URT, URA, URB}},
{"evmhossfaaw", VX (4,1287), VX_MASK, PPCSPE|PPCVLE, PPCNONE, {RS, RA, RB}},
{"evmheumiaaw", VX (4,1288), VX_MASK, PPCSPE|PPCVLE, PPCNONE, {RS, RA, RB}},
+{"vcipher", VX (4,1288), VX_MASK, PPCVEC2, PPCNONE, {VD, VA, VB}},
+{"vcipherlast", VX (4,1289), VX_MASK, PPCVEC2, PPCNONE, {VD, VA, VB}},
{"evmhesmiaaw", VX (4,1289), VX_MASK, PPCSPE|PPCVLE, PPCNONE, {RS, RA, RB}},
{"evmhesmfaaw", VX (4,1291), VX_MASK, PPCSPE|PPCVLE, PPCNONE, {RS, RA, RB}},
+{"vgbbd", VX (4,1292), VXVA_MASK, PPCVEC2, PPCNONE, {VD, VB}},
{"evmhoumiaaw", VX (4,1292), VX_MASK, PPCSPE|PPCVLE, PPCNONE, {RS, RA, RB}},
{"evmhosmiaaw", VX (4,1293), VX_MASK, PPCSPE|PPCVLE, PPCNONE, {RS, RA, RB}},
{"evmhosmfaaw", VX (4,1295), VX_MASK, PPCSPE|PPCVLE, PPCNONE, {RS, RA, RB}},
@@ -3299,13 +3358,19 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"evmhogumiaa", VX (4,1324), VX_MASK, PPCSPE|PPCVLE, PPCNONE, {RS, RA, RB}},
{"evmhogsmiaa", VX (4,1325), VX_MASK, PPCSPE|PPCVLE, PPCNONE, {RS, RA, RB}},
{"evmhogsmfaa", VX (4,1327), VX_MASK, PPCSPE|PPCVLE, PPCNONE, {RS, RA, RB}},
+{"vsubcuq", VX (4,1344), VX_MASK, PPCVEC2, PPCNONE, {VD, VA, VB}},
{"evmwlusiaaw", VX (4,1344), VX_MASK, PPCSPE|PPCVLE, PPCNONE, {RS, RA, RB}},
{"evmwlssiaaw", VX (4,1345), VX_MASK, PPCSPE|PPCVLE, PPCNONE, {RS, RA, RB}},
{"vavgsh", VX (4,1346), VX_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
+{"vorc", VX (4,1348), VX_MASK, PPCVEC2, PPCNONE, {VD, VA, VB}},
{"udi5fcm.", APU(4, 675,0), APU_MASK, PPC405|PPC440, PPC476, {URT, URA, URB}},
{"udi5fcm", APU(4, 675,1), APU_MASK, PPC405|PPC440, PPC476, {URT, URA, URB}},
+{"vncipher", VX (4,1352), VX_MASK, PPCVEC2, PPCNONE, {VD, VA, VB}},
{"evmwlumiaaw", VX (4,1352), VX_MASK, PPCSPE|PPCVLE, PPCNONE, {RS, RA, RB}},
+{"vncipherlast",VX (4,1353), VX_MASK, PPCVEC2, PPCNONE, {VD, VA, VB}},
{"evmwlsmiaaw", VX (4,1353), VX_MASK, PPCSPE|PPCVLE, PPCNONE, {RS, RA, RB}},
+{"vbpermq", VX (4,1356), VX_MASK, PPCVEC2, PPCNONE, {VD, VA, VB}},
+{"vpksdus", VX (4,1358), VX_MASK, PPCVEC2, PPCNONE, {VD, VA, VB}},
{"evmwssfaa", VX (4,1363), VX_MASK, PPCSPE|PPCVLE, PPCNONE, {RS, RA, RB}},
{"macchwo", XO (4, 172,1,0),XO_MASK, MULHW|PPCVLE, PPCNONE, {RT, RA, RB}},
{"evmwumiaa", VX (4,1368), VX_MASK, PPCSPE|PPCVLE, PPCNONE, {RS, RA, RB}},
@@ -3319,6 +3384,7 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"evmhessianw", VX (4,1409), VX_MASK, PPCSPE|PPCVLE, PPCNONE, {RS, RA, RB}},
{"vavgsw", VX (4,1410), VX_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
{"evmhessfanw", VX (4,1411), VX_MASK, PPCSPE|PPCVLE, PPCNONE, {RS, RA, RB}},
+{"vnand", VX (4,1412), VX_MASK, PPCVEC2, PPCNONE, {VD, VA, VB}},
{"evmhousianw", VX (4,1412), VX_MASK, PPCSPE|PPCVLE, PPCNONE, {RS, RA, RB}},
{"evmhossianw", VX (4,1413), VX_MASK, PPCSPE|PPCVLE, PPCNONE, {RS, RA, RB}},
{"udi6fcm.", APU(4, 707,0), APU_MASK, PPC405|PPC440, PPC476, {URT, URA, URB}},
@@ -3340,11 +3406,14 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"evmhogsmfan", VX (4,1455), VX_MASK, PPCSPE|PPCVLE, PPCNONE, {RS, RA, RB}},
{"evmwlusianw", VX (4,1472), VX_MASK, PPCSPE|PPCVLE, PPCNONE, {RS, RA, RB}},
{"evmwlssianw", VX (4,1473), VX_MASK, PPCSPE|PPCVLE, PPCNONE, {RS, RA, RB}},
+{"vsld", VX (4,1476), VX_MASK, PPCVEC2, PPCNONE, {VD, VA, VB}},
{"vcmpgefp.", VXR(4, 454,1), VXR_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
{"udi7fcm.", APU(4, 739,0), APU_MASK, PPC405|PPC440, PPC476, {URT, URA, URB}},
{"udi7fcm", APU(4, 739,1), APU_MASK, PPC405|PPC440, PPC476, {URT, URA, URB}},
+{"vsbox", VX (4,1480), VXVB_MASK, PPCVEC2, PPCNONE, {VD, VA}},
{"evmwlumianw", VX (4,1480), VX_MASK, PPCSPE|PPCVLE, PPCNONE, {RS, RA, RB}},
{"evmwlsmianw", VX (4,1481), VX_MASK, PPCSPE|PPCVLE, PPCNONE, {RS, RA, RB}},
+{"vpksdss", VX (4,1486), VX_MASK, PPCVEC2, PPCNONE, {VD, VA, VB}},
{"evmwssfan", VX (4,1491), VX_MASK, PPCSPE|PPCVLE, PPCNONE, {RS, RA, RB}},
{"macchwso", XO (4, 236,1,0),XO_MASK, MULHW|PPCVLE, PPCNONE, {RT, RA, RB}},
{"evmwumian", VX (4,1496), VX_MASK, PPCSPE|PPCVLE, PPCNONE, {RS, RA, RB}},
@@ -3365,15 +3434,25 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"vsum4shs", VX (4,1608), VX_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
{"udi9fcm.", APU(4, 804,0), APU_MASK, PPC440, PPC476, {URT, URA, URB}},
{"udi9fcm", APU(4, 804,1), APU_MASK, PPC440, PPC476, {URT, URA, URB}},
+{"vupkhsw", VX (4,1614), VXVA_MASK, PPCVEC2, PPCNONE, {VD, VB}},
{"vsubuws", VX (4,1664), VX_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
+{"vshasigmaw", VX (4,1666), VX_MASK, PPCVEC2, PPCNONE, {VD, VA, ST, SIX}},
+{"veqv", VX (4,1668), VX_MASK, PPCVEC2, PPCNONE, {VD, VA, VB}},
{"vcmpgtuw.", VXR(4, 646,1), VXR_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
{"udi10fcm.", APU(4, 835,0), APU_MASK, PPC440, PPC476, {URT, URA, URB}},
{"udi10fcm", APU(4, 835,1), APU_MASK, PPC440, PPC476, {URT, URA, URB}},
{"vsum2sws", VX (4,1672), VX_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
+{"vmrgow", VX (4,1676), VX_MASK, PPCVEC2, PPCNONE, {VD, VA, VB}},
+{"vshasigmad", VX (4,1730), VX_MASK, PPCVEC2, PPCNONE, {VD, VA, ST, SIX}},
+{"vsrd", VX (4,1732), VX_MASK, PPCVEC2, PPCNONE, {VD, VA, VB}},
{"vcmpgtfp.", VXR(4, 710,1), VXR_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
{"udi11fcm.", APU(4, 867,0), APU_MASK, PPC440, PPC476, {URT, URA, URB}},
+{"vcmpgtud.", VXR(4, 711,1), VXR_MASK, PPCVEC2, PPCNONE, {VD, VA, VB}},
{"udi11fcm", APU(4, 867,1), APU_MASK, PPC440, PPC476, {URT, URA, URB}},
+{"vupklsw", VX (4,1742), VXVA_MASK, PPCVEC2, PPCNONE, {VD, VB}},
{"vsubsbs", VX (4,1792), VX_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
+{"vclzb", VX (4,1794), VXVA_MASK, PPCVEC2, PPCNONE, {VD, VB}},
+{"vpopcntb", VX (4,1795), VXVA_MASK, PPCVEC2, PPCNONE, {VD, VB}},
{"vcmpgtsb.", VXR(4, 774,1), VXR_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
{"udi12fcm.", APU(4, 899,0), APU_MASK, PPC440, PPC476, {URT, URA, URB}},
{"udi12fcm", APU(4, 899,1), APU_MASK, PPC440, PPC476, {URT, URA, URB}},
@@ -3381,6 +3460,8 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"maclhwuo", XO (4, 396,1,0),XO_MASK, MULHW|PPCVLE, PPCNONE, {RT, RA, RB}},
{"maclhwuo.", XO (4, 396,1,1),XO_MASK, MULHW|PPCVLE, PPCNONE, {RT, RA, RB}},
{"vsubshs", VX (4,1856), VX_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
+{"vclzh", VX (4,1858), VXVA_MASK, PPCVEC2, PPCNONE, {VD, VB}},
+{"vpopcnth", VX (4,1859), VXVA_MASK, PPCVEC2, PPCNONE, {VD, VB}},
{"vcmpgtsh.", VXR(4, 838,1), VXR_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
{"udi13fcm.", APU(4, 931,0), APU_MASK, PPC440, PPC476, {URT, URA, URB}},
{"udi13fcm", APU(4, 931,1), APU_MASK, PPC440, PPC476, {URT, URA, URB}},
@@ -3389,14 +3470,20 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"nmaclhwo", XO (4, 430,1,0),XO_MASK, MULHW|PPCVLE, PPCNONE, {RT, RA, RB}},
{"nmaclhwo.", XO (4, 430,1,1),XO_MASK, MULHW|PPCVLE, PPCNONE, {RT, RA, RB}},
{"vsubsws", VX (4,1920), VX_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
+{"vclzw", VX (4,1922), VXVA_MASK, PPCVEC2, PPCNONE, {VD, VB}},
+{"vpopcntw", VX (4,1923), VXVA_MASK, PPCVEC2, PPCNONE, {VD, VB}},
{"vcmpgtsw.", VXR(4, 902,1), VXR_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
{"udi14fcm.", APU(4, 963,0), APU_MASK, PPC440, PPC476, {URT, URA, URB}},
{"udi14fcm", APU(4, 963,1), APU_MASK, PPC440, PPC476, {URT, URA, URB}},
{"vsumsws", VX (4,1928), VX_MASK, PPCVEC|PPCVLE, PPCNONE, {VD, VA, VB}},
+{"vmrgew", VX (4,1932), VX_MASK, PPCVEC2, PPCNONE, {VD, VA, VB}},
{"maclhwsuo", XO (4, 460,1,0),XO_MASK, MULHW|PPCVLE, PPCNONE, {RT, RA, RB}},
{"maclhwsuo.", XO (4, 460,1,1),XO_MASK, MULHW|PPCVLE, PPCNONE, {RT, RA, RB}},
+{"vclzd", VX (4,1986), VXVA_MASK, PPCVEC2, PPCNONE, {VD, VB}},
+{"vpopcntd", VX (4,1987), VXVA_MASK, PPCVEC2, PPCNONE, {VD, VB}},
{"vcmpbfp.", VXR(4, 966,1), VXR_MASK, PPCVEC, PPCNONE, {VD, VA, VB}},
{"udi15fcm.", APU(4, 995,0), APU_MASK, PPC440, PPC476, {URT, URA, URB}},
+{"vcmpgtsd.", VXR(4, 967,1), VXR_MASK, PPCVEC2, PPCNONE, {VD, VA, VB}},
{"udi15fcm", APU(4, 995,1), APU_MASK, PPC440, PPC476, {URT, URA, URB}},
{"maclhwso", XO (4, 492,1,0),XO_MASK, MULHW|PPCVLE, PPCNONE, {RT, RA, RB}},
{"maclhwso.", XO (4, 492,1,1),XO_MASK, MULHW|PPCVLE, PPCNONE, {RT, RA, RB}},
@@ -3968,6 +4055,8 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"crandc", XL(19,129), XL_MASK, COM, PPCNONE, {BT, BA, BB}},
+{"rfebb", XL(19,146), XLS_MASK, POWER8, PPCNONE, {SXL}},
+
{"isync", XL(19,150), 0xffffffff, PPCCOM, PPCNONE, {0}},
{"ics", XL(19,150), 0xffffffff, PWRCOM, PPCNONE, {0}},
@@ -4151,6 +4240,13 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"bcctrl", XLLK(19,528,1), XLBH_MASK, PPCCOM, PPCNONE, {BO, BI, BH}},
{"bccl", XLLK(19,528,1), XLBB_MASK, PWRCOM, PPCNONE, {BO, BI}},
+{"bctar-", XLYLK(19,560,0,0), XLYBB_MASK, POWER8, PPCNONE, {BOE, BI}},
+{"bctarl-", XLYLK(19,560,0,1), XLYBB_MASK, POWER8, PPCNONE, {BOE, BI}},
+{"bctar+", XLYLK(19,560,1,0), XLYBB_MASK, POWER8, PPCNONE, {BOE, BI}},
+{"bctarl+", XLYLK(19,560,1,1), XLYBB_MASK, POWER8, PPCNONE, {BOE, BI}},
+{"bctar", XLLK(19,560,0), XLBH_MASK, POWER8, PPCNONE, {BO, BI, BH}},
+{"bctarl", XLLK(19,560,1), XLBH_MASK, POWER8, PPCNONE, {BO, BI, BH}},
+
{"rlwimi", M(20,0), M_MASK, PPCCOM, PPCNONE, {RA, RS, SH, MBE, ME}},
{"rlimi", M(20,0), M_MASK, PWRCOM, PPCNONE, {RA, RS, SH, MBE, ME}},
@@ -4279,6 +4375,8 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"mulhwu", XO(31,11,0,0), XO_MASK, PPC|PPCVLE, PPCNONE, {RT, RA, RB}},
{"mulhwu.", XO(31,11,0,1), XO_MASK, PPC|PPCVLE, PPCNONE, {RT, RA, RB}},
+{"lxsiwzx", X(31,12), XX1_MASK, PPCVSX2, PPCNONE, {XT6, RA0, RB}},
+
{"isellt", X(31,15), X_MASK, PPCISEL, PPCNONE, {RT, RA0, RB}},
{"tlbilxlpid", XTO(31,18,0), XTO_MASK, E500MC|PPCA2, PPCNONE, {0}},
@@ -4319,6 +4417,9 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"maskg.", XRC(31,29,1), X_MASK, M601, PPCA2, {RA, RS, RB}},
{"ldepx", X(31,29), X_MASK, E500MC|PPCA2|PPCVLE, PPCNONE, {RT, RA0, RB}},
+
+{"waitasec", X(31,30), XRTRARB_MASK,POWER8, PPCNONE, {0}},
+
{"lwepx", X(31,31), X_MASK, E500MC|PPCA2|PPCVLE, PPCNONE, {RT, RA0, RB}},
{"cmplw", XOPL(31,32,0), XCMPL_MASK, PPCCOM|PPCVLE, PPCNONE, {OBF, RA, RB}},
@@ -4338,6 +4439,8 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"addg6s", XO(31,74,0,0), XO_MASK, POWER6, PPCNONE, {RT, RA, RB}},
+{"lxsiwax", X(31,76), XX1_MASK, PPCVSX2, PPCNONE, {XT6, RA0, RB}},
+
{"iseleq", X(31,79), X_MASK, PPCISEL, PPCNONE, {RT, RA0, RB}},
{"isel", XISEL(31,15), XISEL_MASK, PPCISEL|TITAN|PPCVLE, PPCNONE, {RT, RA0, RB, CRB}},
@@ -4347,6 +4450,9 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"subf.", XO(31,40,0,1), XO_MASK, PPC|PPCVLE, PPCNONE, {RT, RA, RB}},
{"sub.", XO(31,40,0,1), XO_MASK, PPC|PPCVLE, PPCNONE, {RT, RB, RA}},
+{"mfvsrd", X(31,51), XX1RB_MASK, PPCVSX2, PPCNONE, {RA, XS6}},
+{"mffprd", X(31,51), XX1RB_MASK|1, PPCVSX2, PPCNONE, {RA, FRS}},
+{"mfvrd", X(31,51)|1, XX1RB_MASK|1, PPCVSX2, PPCNONE, {RA, VS}},
{"eratilx", X(31,51), X_MASK, PPCA2, PPCNONE, {ERAT_T, RA, RB}},
{"lbarx", X(31,52), XEH_MASK, POWER7|PPCVLE, PPCNONE, {RT, RA0, RB, EH}},
@@ -4424,6 +4530,10 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"mtsrdin", X(31,114), XRA_MASK, PPC64, PPCNONE, {RS, RB}},
+{"mffprwz", X(31,115), XX1RB_MASK|1, PPCVSX2, PPCNONE, {RA, FRS}},
+{"mfvrwz", X(31,115)|1, XX1RB_MASK|1, PPCVSX2, PPCNONE, {RA, VS}},
+{"mfvsrwz", X(31,115), XX1RB_MASK, PPCVSX2, PPCNONE, {RA, XS6}},
+
{"lharx", X(31,116), XEH_MASK, POWER7|PPCVLE, PPCNONE, {RT, RA0, RB, EH}},
{"clf", X(31,118), XTO_MASK, POWER, PPCNONE, {RA, RB}},
@@ -4456,6 +4566,9 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"adde.", XO(31,138,0,1), XO_MASK, PPCCOM|PPCVLE, PPCNONE, {RT, RA, RB}},
{"ae.", XO(31,138,0,1), XO_MASK, PWRCOM, PPCNONE, {RT, RA, RB}},
+{"stxsiwx", X(31,140), XX1_MASK, PPCVSX2, PPCNONE, {XS6, RA0, RB}},
+
+{"msgsndp", XRTRA(31,142,0,0), XRTRA_MASK, POWER8, PPCNONE, {RB}},
{"dcbtstlse", X(31,142), X_MASK, PPCCHLK, E500MC, {CT, RA0, RB}},
{"mtcr", XFXM(31,144,0xff,0), XRARB_MASK, COM, PPCNONE, {RS}},
@@ -4464,6 +4577,8 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"mtmsr", X(31,146), XRLARB_MASK, COM|PPCVLE, PPCNONE, {RS, A_L}},
+{"mtsle", X(31,147), XRTLRARB_MASK, POWER8, PPCNONE, {L}},
+
{"eratsx", XRC(31,147,0), X_MASK, PPCA2, PPCNONE, {RT, RA0, RB}},
{"eratsx.", XRC(31,147,1), X_MASK, PPCA2, PPCNONE, {RT, RA0, RB}},
@@ -4493,14 +4608,19 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"stvehx", X(31,167), X_MASK, PPCVEC, PPCNONE, {VS, RA0, RB}},
{"sthfcmx", APU(31,167,0), APU_MASK, PPC405, PPCNONE, {FCRT, RA, RB}},
+{"msgclrp", XRTRA(31,174,0,0), XRTRA_MASK, POWER8, PPCNONE, {RB}},
{"dcbtlse", X(31,174), X_MASK, PPCCHLK, E500MC, {CT, RA0, RB}},
{"mtmsrd", X(31,178), XRLARB_MASK, PPC64, PPCNONE, {RS, A_L}},
+{"mtvsrd", X(31,179), XX1RB_MASK, PPCVSX2, PPCNONE, {XT6, RA}},
+{"mtfprd", X(31,179), XX1RB_MASK|1, PPCVSX2, PPCNONE, {FRT, RA}},
+{"mtvrd", X(31,179)|1, XX1RB_MASK|1, PPCVSX2, PPCNONE, {VD, RA}},
{"eratre", X(31,179), X_MASK, PPCA2, PPCNONE, {RT, RA, WS}},
{"stdux", X(31,181), X_MASK, PPC64|PPCVLE, PPCNONE, {RS, RAS, RB}},
+{"stqcx.", XRC(31,182,1), X_MASK, POWER8, PPCNONE, {RSQ, RA0, RB}},
{"wchkall", X(31,182), X_MASK, PPCA2, PPCNONE, {OBF}},
{"stwux", X(31,183), X_MASK, PPCCOM|PPCVLE, PPCNONE, {RS, RAS, RB}},
@@ -4530,6 +4650,9 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"mtsr", X(31,210), XRB_MASK|(1<<20), COM, NON32, {SR, RS}},
+{"mtfprwa", X(31,211), XX1RB_MASK|1, PPCVSX2, PPCNONE, {FRT, RA}},
+{"mtvrwa", X(31,211)|1, XX1RB_MASK|1, PPCVSX2, PPCNONE, {VD, RA}},
+{"mtvsrwa", X(31,211), XX1RB_MASK, PPCVSX2, PPCNONE, {XT6, RA}},
{"eratwe", X(31,211), X_MASK, PPCA2, PPCNONE, {RS, RA, WS}},
{"ldawx.", XRC(31,212,1), X_MASK, PPCA2, PPCNONE, {RT, RA0, RB}},
@@ -4574,6 +4697,10 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"mtsrin", X(31,242), XRA_MASK, PPC, NON32, {RS, RB}},
{"mtsri", X(31,242), XRA_MASK, POWER, NON32, {RS, RB}},
+{"mtfprwz", X(31,243), XX1RB_MASK|1, PPCVSX2, PPCNONE, {FRT, RA}},
+{"mtvrwz", X(31,243)|1, XX1RB_MASK|1, PPCVSX2, PPCNONE, {VD, RA}},
+{"mtvsrwz", X(31,243), XX1RB_MASK, PPCVSX2, PPCNONE, {XT6, RA}},
+
{"dcbtstt", XRT(31,246,0x10), XRT_MASK, POWER7, PPCNONE, {RA0, RB}},
{"dcbtst", X(31,246), X_MASK, POWER4, PPCNONE, {RA0, RB, CT}},
{"dcbtst", X(31,246), X_MASK, PPC|PPCVLE, POWER4, {CT, RA0, RB}},
@@ -4611,6 +4738,8 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"mfapidi", X(31,275), X_MASK, BOOKE, TITAN, {RT, RA}},
+{"lqarx", X(31,276), XEH_MASK, POWER8, PPCNONE, {RTQ, RAX, RBX, EH}},
+
{"lscbx", XRC(31,277,0), X_MASK, M601, PPCNONE, {RT, RA, RB}},
{"lscbx.", XRC(31,277,1), X_MASK, M601, PPCNONE, {RT, RA, RB}},
@@ -4632,6 +4761,8 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"lvexhx", X(31,293), X_MASK, PPCVEC2, PPCNONE, {VD, RA0, RB}},
{"lvepx", X(31,295), X_MASK, PPCVEC2|PPCVLE, PPCNONE, {VD, RA0, RB}},
+{"mfbhrbe", X(31,302), X_MASK, POWER8, PPCNONE, {RT, BHRBE}},
+
{"tlbie", X(31,306), XRTLRA_MASK, PPC, TITAN, {RB, L}},
{"tlbi", X(31,306), XRT_MASK, POWER, PPCNONE, {RA0, RB}},
@@ -4940,6 +5071,8 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"slbmte", X(31,402), XRA_MASK, PPC64, PPCNONE, {RS, RB}},
+{"pbt.", XRC(31,404,1), X_MASK, POWER8, PPCNONE, {RS, RA0, RB}},
+
{"icswx", XRC(31,406,0), X_MASK, POWER7|PPCA2, PPCNONE, {RS, RA, RB}},
{"icswx.", XRC(31,406,1), X_MASK, POWER7|PPCA2, PPCNONE, {RS, RA, RB}},
@@ -4961,6 +5094,8 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"divwe", XO(31,427,0,0), XO_MASK, POWER7|PPCA2, PPCNONE, {RT, RA, RB}},
{"divwe.", XO(31,427,0,1), XO_MASK, POWER7|PPCA2, PPCNONE, {RT, RA, RB}},
+{"clrbhrb", X(31,430), 0xffffffff, POWER8, PPCNONE, {0}},
+
{"slbie", X(31,434), XRTRA_MASK, PPC64, PPCNONE, {RB}},
{"ecowx", X(31,438), X_MASK, PPC, TITAN, {RT, RA0, RB}},
@@ -5249,6 +5384,8 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"addco.", XO(31,10,1,1), XO_MASK, PPCCOM|PPCVLE, PPCNONE, {RT, RA, RB}},
{"ao.", XO(31,10,1,1), XO_MASK, PWRCOM, PPCNONE, {RT, RA, RB}},
+{"lxsspx", X(31,524), XX1_MASK, PPCVSX2, PPCNONE, {XT6, RA0, RB}},
+
{"clcs", X(31,531), XRB_MASK, M601, PPCNONE, {RT, RA}},
{"ldbrx", X(31,532), X_MASK, CELL|POWER7|PPCA2, PPCNONE, {RT, RA0, RB}},
@@ -5343,6 +5480,8 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"stvlx", X(31,647), X_MASK, CELL, PPCNONE, {VS, RA0, RB}},
{"stbfcmux", APU(31,647,0), APU_MASK, PPC405, PPCNONE, {FCRT, RA, RB}},
+{"stxsspx", X(31,652), XX1_MASK, PPCVSX2, PPCNONE, {XS6, RA0, RB}},
+
{"tbegin.", XRC(31,654,1), XRTLRARB_MASK,PPCHTM, PPCNONE, {HTM_R}},
{"subfeo", XO(31,136,1,0), XO_MASK, PPCCOM|PPCVLE, PPCNONE, {RT, RA, RB}},
@@ -5528,6 +5667,7 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"divo.", XO(31,331,1,1), XO_MASK, M601, PPCNONE, {RT, RA, RB}},
{"lxvd2x", X(31,844), XX1_MASK, PPCVSX, PPCNONE, {XT6, RA0, RB}},
+{"lxvx", X(31,844), XX1_MASK, PPCVSX, PPCNONE, {XT6, RA0, RB}},
{"tabortwci.", XRC(31,846,1), X_MASK, PPCHTM, PPCNONE, {TO, RA, HTM_SI}},
@@ -5639,6 +5779,7 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"divwuo.", XO(31,459,1,1), XO_MASK, PPC|PPCVLE, PPCNONE, {RT, RA, RB}},
{"stxvd2x", X(31,972), XX1_MASK, PPCVSX, PPCNONE, {XS6, RA0, RB}},
+{"stxvx", X(31,972), XX1_MASK, PPCVSX, PPCNONE, {XS6, RA0, RB}},
{"tlbld", X(31,978), XRTRA_MASK, PPC, PPC403|BOOKE|PPCA2|PPC476, {RB}},
{"tlbwehi", XTLB(31,978,0), XTLB_MASK, PPC403, PPCNONE, {RT, RA}},
@@ -5871,14 +6012,25 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"fcfidus", XRC(59,974,0), XRA_MASK, POWER7|PPCA2, PPCNONE, {FRT, FRB}},
{"fcfidus.", XRC(59,974,1), XRA_MASK, POWER7|PPCA2, PPCNONE, {FRT, FRB}},
+{"xsaddsp", XX3(60,0), XX3_MASK, PPCVSX2, PPCNONE, {XT6, XA6, XB6}},
+{"xsmaddasp", XX3(60,1), XX3_MASK, PPCVSX2, PPCNONE, {XT6, XA6, XB6}},
{"xxsldwi", XX3(60,2), XX3SHW_MASK, PPCVSX, PPCNONE, {XT6, XA6, XB6, SHW}},
{"xxsel", XX4(60,3), XX4_MASK, PPCVSX, PPCNONE, {XT6, XA6, XB6, XC6}},
+{"xssubsp", XX3(60,8), XX3_MASK, PPCVSX2, PPCNONE, {XT6, XA6, XB6}},
+{"xsmaddmsp", XX3(60,9), XX3_MASK, PPCVSX2, PPCNONE, {XT6, XA6, XB6}},
{"xxspltd", XX3(60,10), XX3DM_MASK, PPCVSX, PPCNONE, {XT6, XA6, XB6S, DMEX}},
{"xxmrghd", XX3(60,10), XX3_MASK, PPCVSX, PPCNONE, {XT6, XA6, XB6}},
{"xxswapd", XX3(60,10)|(2<<8), XX3_MASK, PPCVSX, PPCNONE, {XT6, XA6, XB6S}},
{"xxmrgld", XX3(60,10)|(3<<8), XX3_MASK, PPCVSX, PPCNONE, {XT6, XA6, XB6}},
{"xxpermdi", XX3(60,10), XX3DM_MASK, PPCVSX, PPCNONE, {XT6, XA6, XB6, DM}},
+{"xsrsqrtesp", XX2(60,10), XX2_MASK, PPCVSX2, PPCNONE, {XT6, XB6}},
+{"xssqrtsp", XX2(60,11), XX2_MASK, PPCVSX2, PPCNONE, {XT6, XB6}},
+{"xsmulsp", XX3(60,16), XX3_MASK, PPCVSX2, PPCNONE, {XT6, XA6, XB6}},
+{"xsmsubasp", XX3(60,17), XX3_MASK, PPCVSX2, PPCNONE, {XT6, XA6, XB6}},
{"xxmrghw", XX3(60,18), XX3_MASK, PPCVSX, PPCNONE, {XT6, XA6, XB6}},
+{"xsdivsp", XX3(60,24), XX3_MASK, PPCVSX2, PPCNONE, {XT6, XA6, XB6}},
+{"xsmsubmsp", XX3(60,25), XX3_MASK, PPCVSX2, PPCNONE, {XT6, XA6, XB6}},
+{"xsresp", XX2(60,26), XX2_MASK, PPCVSX2, PPCNONE, {XT6, XB6}},
{"xsadddp", XX3(60,32), XX3_MASK, PPCVSX, PPCNONE, {XT6, XA6, XB6}},
{"xsmaddadp", XX3(60,33), XX3_MASK, PPCVSX, PPCNONE, {XT6, XA6, XB6}},
{"xscmpudp", XX3(60,35), XX3BF_MASK, PPCVSX, PPCNONE, {BF, XA6, XB6}},
@@ -5932,14 +6084,18 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"xvmsubmdp", XX3(60,121), XX3_MASK, PPCVSX, PPCNONE, {XT6, XA6, XB6}},
{"xsrdpim", XX2(60,121), XX2_MASK, PPCVSX, PPCNONE, {XT6, XB6}},
{"xvtdivdp", XX3(60,125), XX3BF_MASK, PPCVSX, PPCNONE, {BF, XA6, XB6}},
+{"xsnmaddasp", XX3(60,129), XX3_MASK, PPCVSX2, PPCNONE, {XT6, XA6, XB6}},
{"xxland", XX3(60,130), XX3_MASK, PPCVSX, PPCNONE, {XT6, XA6, XB6}},
{"xvcvspuxws", XX2(60,136), XX2_MASK, PPCVSX, PPCNONE, {XT6, XB6}},
+{"xsnmaddmsp", XX3(60,137), XX3_MASK, PPCVSX2, PPCNONE, {XT6, XA6, XB6}},
{"xvrspi", XX2(60,137), XX2_MASK, PPCVSX, PPCNONE, {XT6, XB6}},
{"xxlandc", XX3(60,138), XX3_MASK, PPCVSX, PPCNONE, {XT6, XA6, XB6}},
{"xvrsqrtesp", XX2(60,138), XX2_MASK, PPCVSX, PPCNONE, {XT6, XB6}},
{"xvsqrtsp", XX2(60,139), XX2_MASK, PPCVSX, PPCNONE, {XT6, XB6}},
+{"xsnmsubasp", XX3(60,145), XX3_MASK, PPCVSX2, PPCNONE, {XT6, XA6, XB6}},
{"xxlor", XX3(60,146), XX3_MASK, PPCVSX, PPCNONE, {XT6, XA6, XB6}},
{"xvcvspsxws", XX2(60,152), XX2_MASK, PPCVSX, PPCNONE, {XT6, XB6}},
+{"xsnmsubmsp", XX3(60,153), XX3_MASK, PPCVSX2, PPCNONE, {XT6, XA6, XB6}},
{"xvrspiz", XX2(60,153), XX2_MASK, PPCVSX, PPCNONE, {XT6, XB6}},
{"xxlxor", XX3(60,154), XX3_MASK, PPCVSX, PPCNONE, {XT6, XA6, XB6}},
{"xvresp", XX2(60,154), XX2_MASK, PPCVSX, PPCNONE, {XT6, XB6}},
@@ -5952,12 +6108,15 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"xsnmaddmdp", XX3(60,169), XX3_MASK, PPCVSX, PPCNONE, {XT6, XA6, XB6}},
{"xvrspip", XX2(60,169), XX2_MASK, PPCVSX, PPCNONE, {XT6, XB6}},
{"xvtsqrtsp", XX2(60,170), XX2BF_MASK, PPCVSX, PPCNONE, {BF, XB6}},
+{"xxlorc", XX3(60,170), XX3_MASK, PPCVSX2, PPCNONE, {XT6, XA6, XB6}},
{"xvrspic", XX2(60,171), XX2_MASK, PPCVSX, PPCNONE, {XT6, XB6}},
{"xscpsgndp", XX3(60,176), XX3_MASK, PPCVSX, PPCNONE, {XT6, XA6, XB6}},
{"xsnmsubadp", XX3(60,177), XX3_MASK, PPCVSX, PPCNONE, {XT6, XA6, XB6}},
+{"xxlnand", XX3(60,178), XX3_MASK, PPCVSX2, PPCNONE, {XT6, XA6, XB6}},
{"xvcvsxwsp", XX2(60,184), XX2_MASK, PPCVSX, PPCNONE, {XT6, XB6}},
{"xsnmsubmdp", XX3(60,185), XX3_MASK, PPCVSX, PPCNONE, {XT6, XA6, XB6}},
{"xvrspim", XX2(60,185), XX2_MASK, PPCVSX, PPCNONE, {XT6, XB6}},
+{"xxleqv", XX3(60,186), XX3_MASK, PPCVSX2, PPCNONE, {XT6, XA6, XB6}},
{"xvmaxsp", XX3(60,192), XX3_MASK, PPCVSX, PPCNONE, {XT6, XA6, XB6}},
{"xvnmaddasp", XX3(60,193), XX3_MASK, PPCVSX, PPCNONE, {XT6, XA6, XB6}},
{"xvminsp", XX3(60,200), XX3_MASK, PPCVSX, PPCNONE, {XT6, XA6, XB6}},
@@ -5988,8 +6147,13 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"xvnmsubmdp", XX3(60,249), XX3_MASK, PPCVSX, PPCNONE, {XT6, XA6, XB6}},
{"xvrdpim", XX2(60,249), XX2_MASK, PPCVSX, PPCNONE, {XT6, XB6}},
{"xscvdpsp", XX2(60,265), XX2_MASK, PPCVSX, PPCNONE, {XT6, XB6}},
+{"xscvdpspn", XX2(60,267), XX2_MASK, PPCVSX2, PPCNONE, {XT6, XB6}},
+{"xsrsp", XX2(60,281), XX2_MASK, PPCVSX2, PPCNONE, {XT6, XB6}},
+{"xscvuxdsp", XX2(60,296), XX2_MASK, PPCVSX2, PPCNONE, {XT6, XB6}},
+{"xscvsxdsp", XX2(60,312), XX2_MASK, PPCVSX2, PPCNONE, {XT6, XB6}},
{"xscvdpuxds", XX2(60,328), XX2_MASK, PPCVSX, PPCNONE, {XT6, XB6}},
{"xscvspdp", XX2(60,329), XX2_MASK, PPCVSX, PPCNONE, {XT6, XB6}},
+{"xscvspdpn", XX2(60,331), XX2_MASK, PPCVSX2, PPCNONE, {XT6, XB6}},
{"xscvdpsxds", XX2(60,344), XX2_MASK, PPCVSX, PPCNONE, {XT6, XB6}},
{"xsabsdp", XX2(60,345), XX2_MASK, PPCVSX, PPCNONE, {XT6, XB6}},
{"xscvuxddp", XX2(60,360), XX2_MASK, PPCVSX, PPCNONE, {XT6, XB6}},
@@ -6225,6 +6389,8 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"denbcdq", XRC(63,834,0), X_MASK, POWER6, PPCNONE, {S, FRTp, FRBp}},
{"denbcdq.", XRC(63,834,1), X_MASK, POWER6, PPCNONE, {S, FRTp, FRBp}},
+{"fmrgow", X(63,838), X_MASK, PPCVSX2, PPCNONE, {FRT, FRA, FRB}},
+
{"fcfid", XRC(63,846,0), XRA_MASK, PPC64, PPCNONE, {FRT, FRB}},
{"fcfid", XRC(63,846,0), XRA_MASK, PPC476, PPCNONE, {FRT, FRB}},
{"fcfid.", XRC(63,846,1), XRA_MASK, PPC64, PPCNONE, {FRT, FRB}},
@@ -6239,6 +6405,8 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"fctiduz", XRC(63,943,0), XRA_MASK, POWER7|PPCA2, PPCNONE, {FRT, FRB}},
{"fctiduz.", XRC(63,943,1), XRA_MASK, POWER7|PPCA2, PPCNONE, {FRT, FRB}},
+{"fmrgew", X(63,966), X_MASK, PPCVSX2, PPCNONE, {FRT, FRA, FRB}},
+
{"fcfidu", XRC(63,974,0), XRA_MASK, POWER7|PPCA2, PPCNONE, {FRT, FRB}},
{"fcfidu.", XRC(63,974,1), XRA_MASK, POWER7|PPCA2, PPCNONE, {FRT, FRB}},
};
diff --git a/opcodes/s390-opc.c b/opcodes/s390-opc.c
index 0ae5603d2..adfc5b4ab 100644
--- a/opcodes/s390-opc.c
+++ b/opcodes/s390-opc.c
@@ -388,8 +388,8 @@ const struct s390_operand s390_operands[] =
#define INSTR_RSE_CCRD 6, { C_8,C_12,D_20,B_16,0,0 } /* e.g. lmh */
#define INSTR_RSE_RURD 6, { R_8,U4_12,D_20,B_16,0,0 } /* e.g. icmh */
#define INSTR_RSL_R0RD 6, { D_20,L4_8,B_16,0,0,0 } /* e.g. tp */
-#define INSTR_RSL_LRDFU 6, { F_32,D_20,L4_8,B_16,U4_36,0 } /* e.g. cdzt */
-#define INSTR_RSL_LRDFEU 6, { FE_32,D_20,L4_8,B_16,U4_36,0 } /* e.g. cxzt */
+#define INSTR_RSL_LRDFU 6, { F_32,D_20,L8_8,B_16,U4_36,0 } /* e.g. cdzt */
+#define INSTR_RSL_LRDFEU 6, { FE_32,D_20,L8_8,B_16,U4_36,0 } /* e.g. cxzt */
#define INSTR_RSI_RRP 4, { R_8,R_12,J16_16,0,0,0 } /* e.g. brxh */
#define INSTR_RSY_RRRD 6, { R_8,R_12,D20_20,B_16,0,0 } /* e.g. stmy */
#define INSTR_RSY_RERERD 6, { RE_8,RE_12,D20_20,B_16,0,0 } /* e.g. cdsy */