remove support for binutils 2.18 and 2.20
authorImre Kaloz <kaloz@openwrt.org>
Thu, 28 Oct 2010 07:26:07 +0000 (07:26 +0000)
committerImre Kaloz <kaloz@openwrt.org>
Thu, 28 Oct 2010 07:26:07 +0000 (07:26 +0000)
SVN-Revision: 23685

18 files changed:
toolchain/binutils/Config.in
toolchain/binutils/Makefile
toolchain/binutils/patches/2.18/100-uclibc-conf.patch [deleted file]
toolchain/binutils/patches/2.18/110-arm-eabi-conf.patch [deleted file]
toolchain/binutils/patches/2.18/112-arm-uclibc-gas-needs-libm.patch [deleted file]
toolchain/binutils/patches/2.18/300-001_ld_makefile_patch.patch [deleted file]
toolchain/binutils/patches/2.18/300-006_better_file_error.patch [deleted file]
toolchain/binutils/patches/2.18/300-012_check_ldrunpath_length.patch [deleted file]
toolchain/binutils/patches/2.18/500-avr32.patch [deleted file]
toolchain/binutils/patches/2.18/601-cris-errormsg.patch [deleted file]
toolchain/binutils/patches/2.18/700-pr5322-dont-adjust-p_vaddr_offset.patch [deleted file]
toolchain/binutils/patches/2.20/110-arm-eabi-conf.patch [deleted file]
toolchain/binutils/patches/2.20/111-pr7093.elf32-arm.c.patch [deleted file]
toolchain/binutils/patches/2.20/112-arm-uclibc-gas-needs-libm.patch [deleted file]
toolchain/binutils/patches/2.20/120-sh-conf.patch [deleted file]
toolchain/binutils/patches/2.20/200-mips_non_pic.patch [deleted file]
toolchain/binutils/patches/2.20/300-001_ld_makefile_patch.patch [deleted file]
toolchain/binutils/patches/2.20/300-012_check_ldrunpath_length.patch [deleted file]

index 7b5127b..bfc50c7 100644 (file)
@@ -6,17 +6,9 @@ choice
        help
          Select the version of binutils you wish to use.
 
-       config BINUTILS_VERSION_2_18
-               depends !ubicom32
-               bool "binutils 2.18"
-
        config BINUTILS_VERSION_2_19_1
                bool "binutils 2.19.1"
 
-       config BINUTILS_VERSION_2_20
-               depends !avr32
-               depends !ubicom32
-               bool "binutils 2.20"
         config BINUTILS_VERSION_2_20_1
                 depends !avr32
                 depends !ubicom32
@@ -40,9 +32,7 @@ config EXTRA_BINUTILS_CONFIG_OPTIONS
 config BINUTILS_VERSION
        string
        prompt "Binutils Version" if (TOOLCHAINOPTS && NULL)
-       default "2.18"            if BINUTILS_VERSION_2_18
        default "2.19.1"          if BINUTILS_VERSION_2_19_1
-       default "2.20"            if BINUTILS_VERSION_2_20
        default "2.20.1"          if BINUTILS_VERSION_2_20_1
        default "2.19.1+cs"       if BINUTILS_VERSION_CS
        default "2.19.1"
index d829098..7a19d12 100644 (file)
@@ -13,9 +13,6 @@ BIN_VERSION:=$(PKG_VERSION)
 PKG_SOURCE_URL:=@GNU/binutils/
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
 
-ifeq ($(PKG_VERSION),2.18)
-  PKG_MD5SUM:=9d22ee4dafa3a194457caf4706f9cf01
-endif
 ifeq ($(PKG_VERSION),2.19.1)
   PKG_MD5SUM:=09a8c5821a2dfdbb20665bc0bd680791
 endif
@@ -26,9 +23,6 @@ ifeq ($(PKG_VERSION),2.19.1+cs)
   PKG_MD5SUM:=040740e8c864dd1a15886753f9c0bc0b
   HOST_BUILD_DIR:=$(BUILD_DIR_TOOLCHAIN)/binutils-$(BIN_VERSION)
 endif
-ifeq ($(PKG_VERSION),2.20)
-  PKG_MD5SUM:=ee2d3e996e9a2d669808713360fa96f8
-endif
 ifeq ($(PKG_VERSION),2.20.1)
   PKG_MD5SUM:=9cdfb9d6ec0578c166d3beae5e15c4e5
 endif
diff --git a/toolchain/binutils/patches/2.18/100-uclibc-conf.patch b/toolchain/binutils/patches/2.18/100-uclibc-conf.patch
deleted file mode 100644 (file)
index 71ad50c..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-Index: binutils-2.18/configure
-===================================================================
---- binutils-2.18.orig/configure       2007-06-28 09:19:34.903930248 +0200
-+++ binutils-2.18/configure    2007-06-28 09:19:35.030910944 +0200
-@@ -2206,7 +2206,7 @@
-   am33_2.0-*-linux*)
-     noconfigdirs="$noconfigdirs ${libgcj} target-newlib target-libgloss"
-     ;;
--  sh-*-linux*)
-+  sh*-*-linux*)
-     noconfigdirs="$noconfigdirs ${libgcj} target-newlib target-libgloss"
-     ;;
-   sh*-*-pe|mips*-*-pe|*arm-wince-pe)
-@@ -2504,7 +2504,7 @@
-   romp-*-*)
-     noconfigdirs="$noconfigdirs bfd binutils ld gas opcodes target-libgloss ${libgcj}"
-     ;;
--  sh-*-* | sh64-*-*)
-+  sh*-*-* | sh64-*-*)
-     case "${host}" in
-       i[3456789]86-*-vsta) ;; # don't add gprof back in
-       i[3456789]86-*-go32*) ;; # don't add gprof back in
diff --git a/toolchain/binutils/patches/2.18/110-arm-eabi-conf.patch b/toolchain/binutils/patches/2.18/110-arm-eabi-conf.patch
deleted file mode 100644 (file)
index 3e0a25a..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-Index: binutils-2.18/configure
-===================================================================
---- binutils-2.18.orig/configure       2007-06-28 09:19:35.030910944 +0200
-+++ binutils-2.18/configure    2007-06-28 09:19:35.592825520 +0200
-@@ -2235,7 +2235,7 @@
-   arm-*-elf* | strongarm-*-elf* | xscale-*-elf* | arm*-*-eabi* )
-     noconfigdirs="$noconfigdirs target-libffi target-qthreads"
-     ;;
--  arm*-*-linux-gnueabi)
-+  arm*-*-linux-gnueabi | arm*-*-linux-uclibcgnueabi)
-     noconfigdirs="$noconfigdirs target-libffi target-qthreads"
-     noconfigdirs="$noconfigdirs target-libjava target-libobjc"
-     case ${with_newlib} in
diff --git a/toolchain/binutils/patches/2.18/112-arm-uclibc-gas-needs-libm.patch b/toolchain/binutils/patches/2.18/112-arm-uclibc-gas-needs-libm.patch
deleted file mode 100644 (file)
index 2f46afb..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-Source: Khem Raj <raj.khem@gmail.com>
-Disposition: submit upstream.
-
-Description:
-
-We do not need to have the libtool patch anymore for binutils after
-libtool has been updated upstream it include support for it. However
-for building gas natively on uclibc systems we have to link it with
--lm so that it picks up missing symbols.
-
-/local/build_area/BUILD/arm_v5t_le_uclibc/binutils-2.17.50/objdir/libiberty/pic/libiberty.a(floatformat.o): In function `floatformat_from_double':
-floatformat.c:(.text+0x1ec): undefined reference to `frexp'
-floatformat.c:(.text+0x2f8): undefined reference to `ldexp'
-/local/build_area/BUILD/arm_v5t_le_uclibc/binutils-2.17.50/objdir/libiberty/pic/libiberty.a(floatformat.o): In function `floatformat_to_double':
-floatformat.c:(.text+0x38a): undefined reference to `ldexp'
-floatformat.c:(.text+0x3d2): undefined reference to `ldexp'
-floatformat.c:(.text+0x43e): undefined reference to `ldexp'                     floatformat.c:(.text+0x4e2): undefined reference to `ldexp'
-collect2: ld returned 1 exit status
-make[4]: *** [as-new] Error 1
-
-Index: binutils-2.17.50/gas/configure.tgt
-===================================================================
---- binutils-2.17.50.orig/gas/configure.tgt
-+++ binutils-2.17.50/gas/configure.tgt
-@@ -411,6 +411,12 @@ case ${generic_target} in
-   *-*-netware)                                fmt=elf em=netware ;;
- esac
-+case ${generic_target} in
-+  arm-*-*uclibc*)
-+    need_libm=yes
-+    ;;
-+esac
-+
- case ${cpu_type} in
-   alpha | arm | i386 | ia64 | mips | ns32k | pdp11 | ppc | sparc | z80 | z8k)
-     bfd_gas=yes
-
diff --git a/toolchain/binutils/patches/2.18/300-001_ld_makefile_patch.patch b/toolchain/binutils/patches/2.18/300-001_ld_makefile_patch.patch
deleted file mode 100644 (file)
index 4624f29..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-#!/bin/sh -e
-## 001_ld_makefile_patch.dpatch
-##
-## All lines beginning with `## DP:' are a description of the patch.
-## DP: Description: correct where ld scripts are installed
-## DP: Author: Chris Chimelis <chris@debian.org>
-## DP: Upstream status: N/A
-## DP: Date: ??
-
-if [ $# -ne 1 ]; then
-    echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
-    exit 1
-fi
-
-[ -f debian/patches/00patch-opts ] && . debian/patches/00patch-opts
-patch_opts="${patch_opts:--f --no-backup-if-mismatch}"
-
-case "$1" in
-       -patch) patch $patch_opts -p1 < $0;;
-       -unpatch) patch $patch_opts -p1 -R < $0;;
-        *)
-                echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
-                exit 1;;
-esac
-
-exit 0
-
-@DPATCH@
-Index: binutils-2.18/ld/Makefile.am
-===================================================================
---- binutils-2.18.orig/ld/Makefile.am  2007-06-28 09:19:34.837940280 +0200
-+++ binutils-2.18/ld/Makefile.am       2007-06-28 09:19:35.795794664 +0200
-@@ -18,7 +18,7 @@
- # We put the scripts in the directory $(scriptdir)/ldscripts.
- # We can't put the scripts in $(datadir) because the SEARCH_DIR
- # directives need to be different for native and cross linkers.
--scriptdir = $(tooldir)/lib
-+scriptdir = $(libdir)
-
- EMUL = @EMUL@
- EMULATION_OFILES = @EMULATION_OFILES@
-Index: binutils-2.18/ld/Makefile.in
-===================================================================
---- binutils-2.18.orig/ld/Makefile.in  2007-06-28 09:19:34.844939216 +0200
-+++ binutils-2.18/ld/Makefile.in       2007-06-28 09:19:35.796794512 +0200
-@@ -287,7 +287,7 @@
- # We put the scripts in the directory $(scriptdir)/ldscripts.
- # We can't put the scripts in $(datadir) because the SEARCH_DIR
- # directives need to be different for native and cross linkers.
--scriptdir = $(tooldir)/lib
-+scriptdir = $(libdir)
- BASEDIR = $(srcdir)/..
- BFDDIR = $(BASEDIR)/bfd
- INCDIR = $(BASEDIR)/include
diff --git a/toolchain/binutils/patches/2.18/300-006_better_file_error.patch b/toolchain/binutils/patches/2.18/300-006_better_file_error.patch
deleted file mode 100644 (file)
index 30dfb10..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-#!/bin/sh -e
-## 006_better_file_error.dpatch by David Kimdon <dwhedon@gordian.com>
-##
-## All lines beginning with `## DP:' are a description of the patch.
-## DP: Specify which filename is causing an error if the filename is a
-## DP: directory. (#45832)
-
-if [ $# -ne 1 ]; then
-    echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
-    exit 1
-fi
-
-[ -f debian/patches/00patch-opts ] && . debian/patches/00patch-opts
-patch_opts="${patch_opts:--f --no-backup-if-mismatch}"
-
-case "$1" in
-       -patch) patch $patch_opts -p1 < $0;;
-       -unpatch) patch $patch_opts -p1 -R < $0;;
-        *)
-                echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
-                exit 1;;
-esac
-
-exit 0
-
-@DPATCH@
-Index: binutils-2.18/bfd/opncls.c
-===================================================================
---- binutils-2.18.orig/bfd/opncls.c    2007-06-28 09:19:34.818943168 +0200
-+++ binutils-2.18/bfd/opncls.c 2007-06-28 09:19:35.993764568 +0200
-@@ -183,6 +183,13 @@
- {
-   bfd *nbfd;
-   const bfd_target *target_vec;
-+  struct stat s;
-+
-+  if (stat (filename, &s) == 0)
-+    if (S_ISDIR(s.st_mode)) {
-+      bfd_set_error (bfd_error_file_not_recognized);
-+      return NULL;
-+    }
-
-   nbfd = _bfd_new_bfd ();
-   if (nbfd == NULL)
diff --git a/toolchain/binutils/patches/2.18/300-012_check_ldrunpath_length.patch b/toolchain/binutils/patches/2.18/300-012_check_ldrunpath_length.patch
deleted file mode 100644 (file)
index 2662596..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-#!/bin/sh -e
-## 012_check_ldrunpath_length.dpatch by Chris Chimelis <chris@debian.org>
-##
-## All lines beginning with `## DP:' are a description of the patch.
-## DP: Only generate an RPATH entry if LD_RUN_PATH is not empty, for
-## DP: cases where -rpath isn't specified. (#151024)
-
-if [ $# -ne 1 ]; then
-    echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
-    exit 1
-fi
-
-[ -f debian/patches/00patch-opts ] && . debian/patches/00patch-opts
-patch_opts="${patch_opts:--f --no-backup-if-mismatch}"
-
-case "$1" in
-       -patch) patch $patch_opts -p1 < $0;;
-       -unpatch) patch $patch_opts -p1 -R < $0;;
-        *)
-                echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
-                exit 1;;
-esac
-
-exit 0
-
-@DPATCH@
-Index: binutils-2.18/ld/emultempl/elf32.em
-===================================================================
---- binutils-2.18.orig/ld/emultempl/elf32.em   2007-06-28 09:19:34.796946512 +0200
-+++ binutils-2.18/ld/emultempl/elf32.em        2007-06-28 09:19:36.178736448 +0200
-@@ -1216,6 +1216,8 @@
-             && command_line.rpath == NULL)
-           {
-             lib_path = (const char *) getenv ("LD_RUN_PATH");
-+            if ((lib_path) && (strlen (lib_path) == 0))
-+                lib_path = NULL;
-             if (gld${EMULATION_NAME}_search_needed (lib_path, &n,
-                                                     force))
-               break;
-@@ -1400,6 +1402,8 @@
-   rpath = command_line.rpath;
-   if (rpath == NULL)
-     rpath = (const char *) getenv ("LD_RUN_PATH");
-+  if ((rpath) && (strlen (rpath) == 0))
-+      rpath = NULL;
-   if (! (bfd_elf_size_dynamic_sections
-        (output_bfd, command_line.soname, rpath,
-         command_line.filter_shlib,
diff --git a/toolchain/binutils/patches/2.18/500-avr32.patch b/toolchain/binutils/patches/2.18/500-avr32.patch
deleted file mode 100644 (file)
index 40239aa..0000000
+++ /dev/null
@@ -1,52720 +0,0 @@
---- a/bfd/archures.c
-+++ b/bfd/archures.c
-@@ -346,6 +346,11 @@ DESCRIPTION
- .#define bfd_mach_avr4                4
- .#define bfd_mach_avr5                5
- .#define bfd_mach_avr6                6
-+.  bfd_arch_avr32,     {* Atmel AVR32 *}
-+.#define bfd_mach_avr32_ap    7000
-+.#define bfd_mach_avr32_uc    3000
-+.#define bfd_mach_avr32_ucr1    3001
-+.#define bfd_mach_avr32_ucr2    3002
- .  bfd_arch_bfin,        {* ADI Blackfin *}
- .#define bfd_mach_bfin          1
- .  bfd_arch_cr16,       {* National Semiconductor CompactRISC (ie CR16). *}
-@@ -438,6 +443,7 @@ extern const bfd_arch_info_type bfd_alph
- extern const bfd_arch_info_type bfd_arc_arch;
- extern const bfd_arch_info_type bfd_arm_arch;
- extern const bfd_arch_info_type bfd_avr_arch;
-+extern const bfd_arch_info_type bfd_avr32_arch;
- extern const bfd_arch_info_type bfd_bfin_arch;
- extern const bfd_arch_info_type bfd_cr16_arch;
- extern const bfd_arch_info_type bfd_cr16c_arch;
-@@ -509,6 +515,7 @@ static const bfd_arch_info_type * const 
-     &bfd_arc_arch,
-     &bfd_arm_arch,
-     &bfd_avr_arch,
-+    &bfd_avr32_arch,
-     &bfd_bfin_arch,
-     &bfd_cr16_arch,
-     &bfd_cr16c_arch,
---- a/bfd/config.bfd
-+++ b/bfd/config.bfd
-@@ -335,6 +335,10 @@ case "${targ}" in
-     targ_underscore=yes
-     ;;
-+  avr32-*-*)
-+    targ_defvec=bfd_elf32_avr32_vec
-+    ;;
-+
-   c30-*-*aout* | tic30-*-*aout*)
-     targ_defvec=tic30_aout_vec
-     ;;
---- a/bfd/configure.in
-+++ b/bfd/configure.in
-@@ -619,6 +619,7 @@ do
-     bfd_efi_app_ia64_vec)     tb="$tb efi-app-ia64.lo pepigen.lo cofflink.lo"; target_size=64 ;;
-     bfd_elf32_am33lin_vec)    tb="$tb elf32-am33lin.lo elf32.lo $elf" ;;
-     bfd_elf32_avr_vec)                tb="$tb elf32-avr.lo elf32.lo $elf" ;;
-+    bfd_elf32_avr32_vec)      tb="$tb elf32-avr32.lo elf32.lo $elf" ;;
-     bfd_elf32_bfin_vec)               tb="$tb elf32-bfin.lo elf32.lo $elf" ;;
-     bfd_elf32_bfinfdpic_vec)  tb="$tb elf32-bfin.lo elf32.lo $elf" ;;
-     bfd_elf32_big_generic_vec)        tb="$tb elf32-gen.lo elf32.lo $elf" ;;
---- /dev/null
-+++ b/bfd/cpu-avr32.c
-@@ -0,0 +1,51 @@
-+/* BFD library support routines for AVR32.
-+   Copyright 2003-2006 Atmel Corporation.
-+
-+   Written by Haavard Skinnemoen, Atmel Norway, <hskinnemoen@atmel.com>
-+
-+   This is part of BFD, the Binary File Descriptor library.
-+
-+   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 2 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
-+
-+#include "bfd.h"
-+#include "sysdep.h"
-+#include "libbfd.h"
-+
-+#define N(machine, print, default, next)                      \
-+  {                                                           \
-+    32,                               /* 32 bits in a word */         \
-+    32,                               /* 32 bits in an address */     \
-+    8,                                /* 8 bits in a byte */          \
-+    bfd_arch_avr32,           /* architecture */              \
-+    machine,                  /* machine */                   \
-+    "avr32",                  /* arch name */                 \
-+    print,                    /* printable name */            \
-+    1,                                /* section align power */       \
-+    default,                  /* the default machine? */      \
-+    bfd_default_compatible,                                   \
-+    bfd_default_scan,                                         \
-+    next,                                                     \
-+  }
-+
-+static const bfd_arch_info_type cpu_info[] =
-+{
-+  N(bfd_mach_avr32_ap, "avr32:ap", FALSE, &cpu_info[1]),
-+  N(bfd_mach_avr32_uc, "avr32:uc", FALSE, &cpu_info[2]),
-+  N(bfd_mach_avr32_ucr1, "avr32:ucr1", FALSE, &cpu_info[3]),
-+  N(bfd_mach_avr32_ucr2, "avr32:ucr2", FALSE, NULL),
-+};
-+
-+const bfd_arch_info_type bfd_avr32_arch =
-+  N(bfd_mach_avr32_ap, "avr32", TRUE, &cpu_info[0]);
---- /dev/null
-+++ b/bfd/elf32-avr32.c
-@@ -0,0 +1,3915 @@
-+/* AVR32-specific support for 32-bit ELF.
-+   Copyright 2003-2006 Atmel Corporation.
-+
-+   Written by Haavard Skinnemoen, Atmel Norway, <hskinnemoen@atmel.com>
-+
-+   This file is part of BFD, the Binary File Descriptor library.
-+
-+   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 2 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-+
-+#include "bfd.h"
-+#include "sysdep.h"
-+#include "bfdlink.h"
-+#include "libbfd.h"
-+#include "elf-bfd.h"
-+#include "elf/avr32.h"
-+#include "elf32-avr32.h"
-+
-+#define xDEBUG
-+#define xRELAX_DEBUG
-+
-+#ifdef DEBUG
-+# define pr_debug(fmt, args...) fprintf(stderr, fmt, ##args)
-+#else
-+# define pr_debug(fmt, args...) do { } while (0)
-+#endif
-+
-+#ifdef RELAX_DEBUG
-+# define RDBG(fmt, args...) fprintf(stderr, fmt, ##args)
-+#else
-+# define RDBG(fmt, args...) do { } while (0)
-+#endif
-+
-+/* When things go wrong, we want it to blow up, damnit! */
-+#undef BFD_ASSERT
-+#undef abort
-+#define BFD_ASSERT(expr)                                      \
-+  do                                                          \
-+    {                                                         \
-+      if (!(expr))                                            \
-+      {                                                       \
-+        bfd_assert(__FILE__, __LINE__);                       \
-+        abort();                                              \
-+      }                                                       \
-+    }                                                         \
-+  while (0)
-+
-+/* The name of the dynamic interpreter. This is put in the .interp section. */
-+#define ELF_DYNAMIC_INTERPRETER               "/lib/ld.so.1"
-+
-+#define AVR32_GOT_HEADER_SIZE         8
-+#define AVR32_FUNCTION_STUB_SIZE      8
-+
-+#define ELF_R_INFO(x, y) ELF32_R_INFO(x, y)
-+#define ELF_R_TYPE(x) ELF32_R_TYPE(x)
-+#define ELF_R_SYM(x) ELF32_R_SYM(x)
-+
-+#define NOP_OPCODE 0xd703
-+
-+
-+/* Mapping between BFD relocations and ELF relocations */
-+
-+static reloc_howto_type *
-+bfd_elf32_bfd_reloc_type_lookup(bfd *abfd, bfd_reloc_code_real_type code);
-+
-+static reloc_howto_type *
-+bfd_elf32_bfd_reloc_name_lookup(bfd *abfd, const char *r_name);
-+
-+static void
-+avr32_info_to_howto (bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst);
-+
-+/* Generic HOWTO */
-+#define GENH(name, align, size, bitsize, pcrel, bitpos, complain, mask)       \
-+  HOWTO(name, align, size, bitsize, pcrel, bitpos,                    \
-+      complain_overflow_##complain, bfd_elf_generic_reloc, #name,     \
-+      FALSE, 0, mask, pcrel)
-+
-+static reloc_howto_type elf_avr32_howto_table[] = {
-+  /*   NAME            ALN SZ BSZ PCREL  BP COMPLAIN  MASK        */
-+  GENH(R_AVR32_NONE,    0, 0, 0,  FALSE, 0, dont,     0x00000000),
-+
-+  GENH(R_AVR32_32,      0, 2, 32, FALSE, 0, dont,     0xffffffff),
-+  GENH(R_AVR32_16,      0, 1, 16, FALSE, 0, bitfield, 0x0000ffff),
-+  GENH(R_AVR32_8,       0, 0,  8, FALSE, 0, bitfield, 0x000000ff),
-+  GENH(R_AVR32_32_PCREL,  0, 2, 32, TRUE,  0, signed,   0xffffffff),
-+  GENH(R_AVR32_16_PCREL,  0, 1, 16, TRUE,  0, signed,   0x0000ffff),
-+  GENH(R_AVR32_8_PCREL,         0, 0,  8, TRUE,  0, signed,   0x000000ff),
-+
-+  /* Difference between two symbol (sym2 - sym1).  The reloc encodes
-+     the value of sym1.  The field contains the difference before any
-+     relaxing is done.  */
-+  GENH(R_AVR32_DIFF32,          0, 2, 32, FALSE, 0, dont,     0xffffffff),
-+  GENH(R_AVR32_DIFF16,          0, 1, 16, FALSE, 0, signed,   0x0000ffff),
-+  GENH(R_AVR32_DIFF8,   0, 0,  8, FALSE, 0, signed,   0x000000ff),
-+
-+  GENH(R_AVR32_GOT32,   0, 2, 32, FALSE, 0, signed,   0xffffffff),
-+  GENH(R_AVR32_GOT16,   0, 1, 16, FALSE, 0, signed,   0x0000ffff),
-+  GENH(R_AVR32_GOT8,    0, 0,  8, FALSE, 0, signed,   0x000000ff),
-+
-+  GENH(R_AVR32_21S,     0, 2, 21, FALSE, 0, signed,   0x1e10ffff),
-+  GENH(R_AVR32_16U,     0, 2, 16, FALSE, 0, unsigned, 0x0000ffff),
-+  GENH(R_AVR32_16S,     0, 2, 16, FALSE, 0, signed,   0x0000ffff),
-+  GENH(R_AVR32_8S,      0, 1,  8, FALSE, 4, signed,   0x00000ff0),
-+  GENH(R_AVR32_8S_EXT,          0, 2,  8, FALSE, 0, signed,   0x000000ff),
-+
-+  GENH(R_AVR32_22H_PCREL, 1, 2, 21, TRUE,  0, signed, 0x1e10ffff),
-+  GENH(R_AVR32_18W_PCREL, 2, 2, 16, TRUE,  0, signed, 0x0000ffff),
-+  GENH(R_AVR32_16B_PCREL, 0, 2, 16, TRUE,  0, signed, 0x0000ffff),
-+  GENH(R_AVR32_16N_PCREL, 0, 2, 16, TRUE,  0, signed, 0x0000ffff),
-+  GENH(R_AVR32_14UW_PCREL, 2, 2, 12, TRUE, 0, unsigned, 0x0000f0ff),
-+  GENH(R_AVR32_11H_PCREL, 1, 1, 10, TRUE,  4, signed, 0x00000ff3),
-+  GENH(R_AVR32_10UW_PCREL, 2, 2, 8, TRUE,  0, unsigned, 0x000000ff),
-+  GENH(R_AVR32_9H_PCREL,  1, 1,  8, TRUE,  4, signed, 0x00000ff0),
-+  GENH(R_AVR32_9UW_PCREL, 2, 1,  7, TRUE,  4, unsigned,       0x000007f0),
-+
-+  GENH(R_AVR32_HI16,   16, 2, 16, FALSE, 0, dont,     0x0000ffff),
-+  GENH(R_AVR32_LO16,    0, 2, 16, FALSE, 0, dont,     0x0000ffff),
-+
-+  GENH(R_AVR32_GOTPC,   0, 2, 32, FALSE, 0, dont,     0xffffffff),
-+  GENH(R_AVR32_GOTCALL,   2, 2, 21, FALSE, 0, signed, 0x1e10ffff),
-+  GENH(R_AVR32_LDA_GOT,         2, 2, 21, FALSE, 0, signed,   0x1e10ffff),
-+  GENH(R_AVR32_GOT21S,          0, 2, 21, FALSE, 0, signed,   0x1e10ffff),
-+  GENH(R_AVR32_GOT18SW,         2, 2, 16, FALSE, 0, signed,   0x0000ffff),
-+  GENH(R_AVR32_GOT16S,          0, 2, 16, FALSE, 0, signed,   0x0000ffff),
-+  GENH(R_AVR32_GOT7UW,          2, 1,  5, FALSE, 4, unsigned, 0x000001f0),
-+
-+  GENH(R_AVR32_32_CPENT,  0, 2, 32, FALSE, 0, dont,   0xffffffff),
-+  GENH(R_AVR32_CPCALL,          2, 2, 16, TRUE,  0, signed,   0x0000ffff),
-+  GENH(R_AVR32_16_CP,   0, 2, 16, TRUE,  0, signed,   0x0000ffff),
-+  GENH(R_AVR32_9W_CP,   2, 1,  7, TRUE,  4, unsigned, 0x000007f0),
-+
-+  GENH(R_AVR32_RELATIVE,  0, 2, 32, FALSE, 0, signed, 0xffffffff),
-+  GENH(R_AVR32_GLOB_DAT,  0, 2, 32, FALSE, 0, dont,   0xffffffff),
-+  GENH(R_AVR32_JMP_SLOT,  0, 2, 32, FALSE, 0, dont,   0xffffffff),
-+
-+  GENH(R_AVR32_ALIGN,   0, 1, 0,  FALSE, 0, unsigned, 0x00000000),
-+
-+  GENH(R_AVR32_15S,     2, 2, 15, FALSE, 0, signed,   0x00007fff),
-+};
-+
-+struct elf_reloc_map
-+{
-+  bfd_reloc_code_real_type bfd_reloc_val;
-+  unsigned char elf_reloc_val;
-+};
-+
-+static const struct elf_reloc_map avr32_reloc_map[] =
-+{
-+  { BFD_RELOC_NONE,                   R_AVR32_NONE },
-+
-+  { BFD_RELOC_32,                     R_AVR32_32 },
-+  { BFD_RELOC_16,                     R_AVR32_16 },
-+  { BFD_RELOC_8,                      R_AVR32_8 },
-+  { BFD_RELOC_32_PCREL,                       R_AVR32_32_PCREL },
-+  { BFD_RELOC_16_PCREL,                       R_AVR32_16_PCREL },
-+  { BFD_RELOC_8_PCREL,                        R_AVR32_8_PCREL },
-+  { BFD_RELOC_AVR32_DIFF32,           R_AVR32_DIFF32 },
-+  { BFD_RELOC_AVR32_DIFF16,           R_AVR32_DIFF16 },
-+  { BFD_RELOC_AVR32_DIFF8,            R_AVR32_DIFF8 },
-+  { BFD_RELOC_AVR32_GOT32,            R_AVR32_GOT32 },
-+  { BFD_RELOC_AVR32_GOT16,            R_AVR32_GOT16 },
-+  { BFD_RELOC_AVR32_GOT8,             R_AVR32_GOT8 },
-+
-+  { BFD_RELOC_AVR32_21S,              R_AVR32_21S },
-+  { BFD_RELOC_AVR32_16U,              R_AVR32_16U },
-+  { BFD_RELOC_AVR32_16S,              R_AVR32_16S },
-+  { BFD_RELOC_AVR32_SUB5,             R_AVR32_16S },
-+  { BFD_RELOC_AVR32_8S_EXT,           R_AVR32_8S_EXT },
-+  { BFD_RELOC_AVR32_8S,                       R_AVR32_8S },
-+
-+  { BFD_RELOC_AVR32_22H_PCREL,                R_AVR32_22H_PCREL },
-+  { BFD_RELOC_AVR32_18W_PCREL,                R_AVR32_18W_PCREL },
-+  { BFD_RELOC_AVR32_16B_PCREL,                R_AVR32_16B_PCREL },
-+  { BFD_RELOC_AVR32_16N_PCREL,                R_AVR32_16N_PCREL },
-+  { BFD_RELOC_AVR32_11H_PCREL,                R_AVR32_11H_PCREL },
-+  { BFD_RELOC_AVR32_10UW_PCREL,               R_AVR32_10UW_PCREL },
-+  { BFD_RELOC_AVR32_9H_PCREL,         R_AVR32_9H_PCREL },
-+  { BFD_RELOC_AVR32_9UW_PCREL,                R_AVR32_9UW_PCREL },
-+
-+  { BFD_RELOC_HI16,                   R_AVR32_HI16 },
-+  { BFD_RELOC_LO16,                   R_AVR32_LO16 },
-+
-+  { BFD_RELOC_AVR32_GOTPC,            R_AVR32_GOTPC },
-+  { BFD_RELOC_AVR32_GOTCALL,          R_AVR32_GOTCALL },
-+  { BFD_RELOC_AVR32_LDA_GOT,          R_AVR32_LDA_GOT },
-+  { BFD_RELOC_AVR32_GOT21S,           R_AVR32_GOT21S },
-+  { BFD_RELOC_AVR32_GOT18SW,          R_AVR32_GOT18SW },
-+  { BFD_RELOC_AVR32_GOT16S,           R_AVR32_GOT16S },
-+  /* GOT7UW should never be generated by the assembler */
-+
-+  { BFD_RELOC_AVR32_32_CPENT,         R_AVR32_32_CPENT },
-+  { BFD_RELOC_AVR32_CPCALL,           R_AVR32_CPCALL },
-+  { BFD_RELOC_AVR32_16_CP,            R_AVR32_16_CP },
-+  { BFD_RELOC_AVR32_9W_CP,            R_AVR32_9W_CP },
-+
-+  { BFD_RELOC_AVR32_ALIGN,            R_AVR32_ALIGN },
-+
-+  { BFD_RELOC_AVR32_15S,              R_AVR32_15S },
-+};
-+
-+static reloc_howto_type *
-+bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
-+                               bfd_reloc_code_real_type code)
-+{
-+  unsigned int i;
-+
-+  for (i = 0; i < sizeof(avr32_reloc_map) / sizeof(struct elf_reloc_map); i++)
-+    {
-+      if (avr32_reloc_map[i].bfd_reloc_val == code)
-+      return &elf_avr32_howto_table[avr32_reloc_map[i].elf_reloc_val];
-+    }
-+
-+  return NULL;
-+}
-+
-+static reloc_howto_type *
-+bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
-+                 const char *r_name)
-+{
-+  unsigned int i;
-+
-+  for (i = 0;
-+       i < sizeof (elf_avr32_howto_table) / sizeof (elf_avr32_howto_table[0]);
-+       i++)
-+    if (elf_avr32_howto_table[i].name != NULL
-+    && strcasecmp (elf_avr32_howto_table[i].name, r_name) == 0)
-+      return &elf_avr32_howto_table[i];
-+
-+  return NULL;
-+}
-+
-+/* Set the howto pointer for an AVR32 ELF reloc.  */
-+static void
-+avr32_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
-+                   arelent *cache_ptr,
-+                   Elf_Internal_Rela *dst)
-+{
-+  unsigned int r_type;
-+
-+  r_type = ELF32_R_TYPE (dst->r_info);
-+  BFD_ASSERT (r_type < (unsigned int) R_AVR32_max);
-+  cache_ptr->howto = &elf_avr32_howto_table[r_type];
-+}
-+
-+
-+/* AVR32 ELF linker hash table and associated hash entries. */
-+
-+static struct bfd_hash_entry *
-+avr32_elf_link_hash_newfunc(struct bfd_hash_entry *entry,
-+                          struct bfd_hash_table *table,
-+                          const char *string);
-+static void
-+avr32_elf_copy_indirect_symbol(struct bfd_link_info *info,
-+                             struct elf_link_hash_entry *dir,
-+                             struct elf_link_hash_entry *ind);
-+static struct bfd_link_hash_table *
-+avr32_elf_link_hash_table_create(bfd *abfd);
-+
-+/*
-+  Try to limit memory usage to something reasonable when sorting the
-+  GOT.  If just a couple of entries end up getting more references
-+  than this, it won't affect performance at all, but if there are many
-+  of them, we could end up with the wrong symbols being assigned the
-+  first GOT entries.
-+*/
-+#define MAX_NR_GOT_HOLES      2048
-+
-+/*
-+  AVR32 GOT entry.  We need to keep track of refcounts and offsets
-+  simultaneously, since we need the offsets during relaxation, and we
-+  also want to be able to drop GOT entries during relaxation. In
-+  addition to this, we want to keep the list of GOT entries sorted so
-+  that we can keep the most-used entries at the lowest offsets.
-+*/
-+struct got_entry
-+{
-+  struct got_entry *next;
-+  struct got_entry **pprev;
-+  int refcount;
-+  bfd_signed_vma offset;
-+};
-+
-+struct elf_avr32_link_hash_entry
-+{
-+  struct elf_link_hash_entry root;
-+
-+  /* Number of runtime relocations against this symbol.  */
-+  unsigned int possibly_dynamic_relocs;
-+
-+  /* If there are anything but R_AVR32_GOT18 relocations against this
-+     symbol, it means that someone may be taking the address of the
-+     function, and we should therefore not create a stub.  */
-+  bfd_boolean no_fn_stub;
-+
-+  /* If there is a R_AVR32_32 relocation in a read-only section
-+     against this symbol, we could be in trouble. If we're linking a
-+     shared library or this symbol is defined in one, it means we must
-+     emit a run-time reloc for it and that's not allowed in read-only
-+     sections.  */
-+  asection *readonly_reloc_sec;
-+  bfd_vma readonly_reloc_offset;
-+
-+  /* Record which frag (if any) contains the symbol.  This is used
-+     during relaxation in order to avoid having to update all symbols
-+     whenever we move something.  For local symbols, this information
-+     is in the local_sym_frag member of struct elf_obj_tdata.  */
-+  struct fragment *sym_frag;
-+};
-+#define avr32_elf_hash_entry(ent) ((struct elf_avr32_link_hash_entry *)(ent))
-+
-+struct elf_avr32_link_hash_table
-+{
-+  struct elf_link_hash_table root;
-+
-+  /* Shortcuts to get to dynamic linker sections.  */
-+  asection *sgot;
-+  asection *srelgot;
-+  asection *sstub;
-+
-+  /* We use a variation of Pigeonhole Sort to sort the GOT.  After the
-+     initial refcounts have been determined, we initialize
-+     nr_got_holes to the highest refcount ever seen and allocate an
-+     array of nr_got_holes entries for got_hole.  Each GOT entry is
-+     then stored in this array at the index given by its refcount.
-+
-+     When a GOT entry has its refcount decremented during relaxation,
-+     it is moved to a lower index in the got_hole array.
-+   */
-+  struct got_entry **got_hole;
-+  int nr_got_holes;
-+
-+  /* Dynamic relocations to local symbols.  Only used when linking a
-+     shared library and -Bsymbolic is not given.  */
-+  unsigned int local_dynamic_relocs;
-+
-+  bfd_boolean relocations_analyzed;
-+  bfd_boolean symbols_adjusted;
-+  bfd_boolean repeat_pass;
-+  bfd_boolean direct_data_refs;
-+  unsigned int relax_iteration;
-+  unsigned int relax_pass;
-+};
-+#define avr32_elf_hash_table(p)                               \
-+  ((struct elf_avr32_link_hash_table *)((p)->hash))
-+
-+static struct bfd_hash_entry *
-+avr32_elf_link_hash_newfunc(struct bfd_hash_entry *entry,
-+                          struct bfd_hash_table *table,
-+                          const char *string)
-+{
-+  struct elf_avr32_link_hash_entry *ret = avr32_elf_hash_entry(entry);
-+
-+  /* Allocate the structure if it hasn't already been allocated by a
-+     subclass */
-+  if (ret == NULL)
-+    ret = (struct elf_avr32_link_hash_entry *)
-+      bfd_hash_allocate(table, sizeof(struct elf_avr32_link_hash_entry));
-+
-+  if (ret == NULL)
-+    return NULL;
-+
-+  memset(ret, 0, sizeof(struct elf_avr32_link_hash_entry));
-+
-+  /* Give the superclass a chance */
-+  ret = (struct elf_avr32_link_hash_entry *)
-+    _bfd_elf_link_hash_newfunc((struct bfd_hash_entry *)ret, table, string);
-+
-+  return (struct bfd_hash_entry *)ret;
-+}
-+
-+/* Copy data from an indirect symbol to its direct symbol, hiding the
-+   old indirect symbol.  Process additional relocation information.
-+   Also called for weakdefs, in which case we just let
-+   _bfd_elf_link_hash_copy_indirect copy the flags for us.  */
-+
-+static void
-+avr32_elf_copy_indirect_symbol(struct bfd_link_info *info,
-+                             struct elf_link_hash_entry *dir,
-+                             struct elf_link_hash_entry *ind)
-+{
-+  struct elf_avr32_link_hash_entry *edir, *eind;
-+
-+  _bfd_elf_link_hash_copy_indirect (info, dir, ind);
-+
-+  if (ind->root.type != bfd_link_hash_indirect)
-+    return;
-+
-+  edir = (struct elf_avr32_link_hash_entry *)dir;
-+  eind = (struct elf_avr32_link_hash_entry *)ind;
-+
-+  edir->possibly_dynamic_relocs += eind->possibly_dynamic_relocs;
-+  edir->no_fn_stub = edir->no_fn_stub || eind->no_fn_stub;
-+}
-+
-+static struct bfd_link_hash_table *
-+avr32_elf_link_hash_table_create(bfd *abfd)
-+{
-+  struct elf_avr32_link_hash_table *ret;
-+
-+  ret = bfd_zmalloc(sizeof(*ret));
-+  if (ret == NULL)
-+    return NULL;
-+
-+  if (! _bfd_elf_link_hash_table_init(&ret->root, abfd,
-+                                    avr32_elf_link_hash_newfunc,
-+                      sizeof (struct elf_avr32_link_hash_entry)))
-+    {
-+      free(ret);
-+      return NULL;
-+    }
-+
-+  /* Prevent the BFD core from creating bogus got_entry pointers */
-+  ret->root.init_got_refcount.glist = NULL;
-+  ret->root.init_plt_refcount.glist = NULL;
-+  ret->root.init_got_offset.glist = NULL;
-+  ret->root.init_plt_offset.glist = NULL;
-+
-+  return &ret->root.root;
-+}
-+
-+
-+/* Initial analysis and creation of dynamic sections and symbols */
-+
-+static asection *
-+create_dynamic_section(bfd *dynobj, const char *name, flagword flags,
-+                     unsigned int align_power);
-+static struct elf_link_hash_entry *
-+create_dynamic_symbol(bfd *dynobj, struct bfd_link_info *info,
-+                    const char *name, asection *sec,
-+                    bfd_vma offset);
-+static bfd_boolean
-+avr32_elf_create_got_section (bfd *dynobj, struct bfd_link_info *info);
-+static bfd_boolean
-+avr32_elf_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info);
-+static bfd_boolean
-+avr32_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec,
-+                  const Elf_Internal_Rela *relocs);
-+static bfd_boolean
-+avr32_elf_adjust_dynamic_symbol(struct bfd_link_info *info,
-+                              struct elf_link_hash_entry *h);
-+
-+static asection *
-+create_dynamic_section(bfd *dynobj, const char *name, flagword flags,
-+                     unsigned int align_power)
-+{
-+  asection *sec;
-+
-+  sec = bfd_make_section(dynobj, name);
-+  if (!sec
-+      || !bfd_set_section_flags(dynobj, sec, flags)
-+      || !bfd_set_section_alignment(dynobj, sec, align_power))
-+    return NULL;
-+
-+  return sec;
-+}
-+
-+static struct elf_link_hash_entry *
-+create_dynamic_symbol(bfd *dynobj, struct bfd_link_info *info,
-+                    const char *name, asection *sec,
-+                    bfd_vma offset)
-+{
-+  struct bfd_link_hash_entry *bh = NULL;
-+  struct elf_link_hash_entry *h;
-+  const struct elf_backend_data *bed = get_elf_backend_data (dynobj);
-+
-+  if (!(_bfd_generic_link_add_one_symbol
-+      (info, dynobj, name, BSF_GLOBAL, sec, offset, NULL, FALSE,
-+       bed->collect, &bh)))
-+    return NULL;
-+
-+  h = (struct elf_link_hash_entry *)bh;
-+  h->def_regular = 1;
-+  h->type = STT_OBJECT;
-+  h->other = STV_HIDDEN;
-+
-+  return h;
-+}
-+
-+static bfd_boolean
-+avr32_elf_create_got_section (bfd *dynobj, struct bfd_link_info *info)
-+{
-+  struct elf_avr32_link_hash_table *htab;
-+  flagword flags;
-+  const struct elf_backend_data *bed = get_elf_backend_data (dynobj);
-+
-+  htab = avr32_elf_hash_table(info);
-+  flags = bed->dynamic_sec_flags;
-+
-+  if (htab->sgot)
-+    return TRUE;
-+
-+  htab->sgot = create_dynamic_section(dynobj, ".got", flags, 2);
-+  if (!htab->srelgot)
-+    htab->srelgot = create_dynamic_section(dynobj, ".rela.got",
-+                                         flags | SEC_READONLY, 2);
-+
-+  if (!htab->sgot || !htab->srelgot)
-+    return FALSE;
-+
-+  htab->root.hgot = create_dynamic_symbol(dynobj, info, "_GLOBAL_OFFSET_TABLE_",
-+                                        htab->sgot, 0);
-+  if (!htab->root.hgot)
-+    return FALSE;
-+
-+  /* Make room for the GOT header */
-+  htab->sgot->size += bed->got_header_size;
-+
-+  return TRUE;
-+}
-+
-+/* (1) Create all dynamic (i.e. linker generated) sections that we may
-+   need during the link */
-+
-+static bfd_boolean
-+avr32_elf_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
-+{
-+  struct elf_avr32_link_hash_table *htab;
-+  flagword flags;
-+  const struct elf_backend_data *bed = get_elf_backend_data (dynobj);
-+
-+  pr_debug("(1) create dynamic sections\n");
-+
-+  htab = avr32_elf_hash_table(info);
-+  flags = bed->dynamic_sec_flags;
-+
-+  if (!avr32_elf_create_got_section (dynobj, info))
-+    return FALSE;
-+
-+  if (!htab->sstub)
-+    htab->sstub = create_dynamic_section(dynobj, ".stub",
-+                                       flags | SEC_READONLY | SEC_CODE, 2);
-+
-+  if (!htab->sstub)
-+    return FALSE;
-+
-+  return TRUE;
-+}
-+
-+/* (2) Go through all the relocs and count any potential GOT- or
-+   PLT-references to each symbol */
-+
-+static bfd_boolean
-+avr32_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec,
-+                  const Elf_Internal_Rela *relocs)
-+{
-+  Elf_Internal_Shdr *symtab_hdr;
-+  struct elf_avr32_link_hash_table *htab;
-+  struct elf_link_hash_entry **sym_hashes;
-+  const Elf_Internal_Rela *rel, *rel_end;
-+  struct got_entry **local_got_ents;
-+  struct got_entry *got;
-+  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
-+  asection *sgot;
-+  bfd *dynobj;
-+
-+  pr_debug("(2) check relocs for %s:<%s> (size 0x%lx)\n",
-+         abfd->filename, sec->name, sec->size);
-+
-+  if (info->relocatable)
-+    return TRUE;
-+
-+  dynobj = elf_hash_table(info)->dynobj;
-+  symtab_hdr = &elf_tdata(abfd)->symtab_hdr;
-+  sym_hashes = elf_sym_hashes(abfd);
-+  htab = avr32_elf_hash_table(info);
-+  local_got_ents = elf_local_got_ents(abfd);
-+  sgot = htab->sgot;
-+
-+  rel_end = relocs + sec->reloc_count;
-+  for (rel = relocs; rel < rel_end; rel++)
-+    {
-+      unsigned long r_symndx, r_type;
-+      struct elf_avr32_link_hash_entry *h;
-+
-+      r_symndx = ELF32_R_SYM(rel->r_info);
-+      r_type = ELF32_R_TYPE(rel->r_info);
-+
-+      /* Local symbols use local_got_ents, while others store the same
-+       information in the hash entry */
-+      if (r_symndx < symtab_hdr->sh_info)
-+      {
-+        pr_debug("  (2a) processing local symbol %lu\n", r_symndx);
-+        h = NULL;
-+      }
-+      else
-+      {
-+        h = (struct elf_avr32_link_hash_entry *)
-+          sym_hashes[r_symndx - symtab_hdr->sh_info];
-+        while (h->root.type == bfd_link_hash_indirect
-+               || h->root.type == bfd_link_hash_warning)
-+          h = (struct elf_avr32_link_hash_entry *)h->root.root.u.i.link;
-+        pr_debug("  (2a) processing symbol %s\n", h->root.root.root.string);
-+      }
-+
-+      /* Some relocs require special sections to be created.  */
-+      switch (r_type)
-+      {
-+      case R_AVR32_GOT32:
-+      case R_AVR32_GOT16:
-+      case R_AVR32_GOT8:
-+      case R_AVR32_GOT21S:
-+      case R_AVR32_GOT18SW:
-+      case R_AVR32_GOT16S:
-+      case R_AVR32_GOT7UW:
-+      case R_AVR32_LDA_GOT:
-+      case R_AVR32_GOTCALL:
-+        if (rel->r_addend)
-+          {
-+            if (info->callbacks->reloc_dangerous
-+                (info, _("Non-zero addend on GOT-relative relocation"),
-+                 abfd, sec, rel->r_offset) == FALSE)
-+              return FALSE;
-+          }
-+        /* fall through */
-+      case R_AVR32_GOTPC:
-+        if (dynobj == NULL)
-+          elf_hash_table(info)->dynobj = dynobj = abfd;
-+        if (sgot == NULL && !avr32_elf_create_got_section(dynobj, info))
-+          return FALSE;
-+        break;
-+      case R_AVR32_32:
-+        /* We may need to create .rela.dyn later on.  */
-+        if (dynobj == NULL
-+            && (info->shared || h != NULL)
-+            && (sec->flags & SEC_ALLOC))
-+          elf_hash_table(info)->dynobj = dynobj = abfd;
-+        break;
-+      }
-+
-+      if (h != NULL && r_type != R_AVR32_GOT18SW)
-+      h->no_fn_stub = TRUE;
-+
-+      switch (r_type)
-+      {
-+      case R_AVR32_GOT32:
-+      case R_AVR32_GOT16:
-+      case R_AVR32_GOT8:
-+      case R_AVR32_GOT21S:
-+      case R_AVR32_GOT18SW:
-+      case R_AVR32_GOT16S:
-+      case R_AVR32_GOT7UW:
-+      case R_AVR32_LDA_GOT:
-+      case R_AVR32_GOTCALL:
-+        if (h != NULL)
-+          {
-+            got = h->root.got.glist;
-+            if (!got)
-+              {
-+                got = bfd_zalloc(abfd, sizeof(struct got_entry));
-+                if (!got)
-+                  return FALSE;
-+                h->root.got.glist = got;
-+              }
-+          }
-+        else
-+          {
-+            if (!local_got_ents)
-+              {
-+                bfd_size_type size;
-+                bfd_size_type i;
-+                struct got_entry *tmp_entry;
-+
-+                size = symtab_hdr->sh_info;
-+                size *= sizeof(struct got_entry *) + sizeof(struct got_entry);
-+                local_got_ents = bfd_zalloc(abfd, size);
-+                if (!local_got_ents)
-+                  return FALSE;
-+
-+                elf_local_got_ents(abfd) = local_got_ents;
-+
-+                tmp_entry = (struct got_entry *)(local_got_ents
-+                                                 + symtab_hdr->sh_info);
-+                for (i = 0; i < symtab_hdr->sh_info; i++)
-+                  local_got_ents[i] = &tmp_entry[i];
-+              }
-+
-+            got = local_got_ents[r_symndx];
-+          }
-+
-+        got->refcount++;
-+        if (got->refcount > htab->nr_got_holes)
-+          htab->nr_got_holes = got->refcount;
-+        break;
-+
-+      case R_AVR32_32:
-+        if ((info->shared || h != NULL)
-+            && (sec->flags & SEC_ALLOC))
-+          {
-+            if (htab->srelgot == NULL)
-+              {
-+                htab->srelgot = create_dynamic_section(dynobj, ".rela.got",
-+                                                       bed->dynamic_sec_flags
-+                                                       | SEC_READONLY, 2);
-+                if (htab->srelgot == NULL)
-+                  return FALSE;
-+              }
-+
-+            if (sec->flags & SEC_READONLY
-+                && !h->readonly_reloc_sec)
-+              {
-+                h->readonly_reloc_sec = sec;
-+                h->readonly_reloc_offset = rel->r_offset;
-+              }
-+
-+            if (h != NULL)
-+              {
-+                pr_debug("Non-GOT reference to symbol %s\n",
-+                         h->root.root.root.string);
-+                h->possibly_dynamic_relocs++;
-+              }
-+            else
-+              {
-+                pr_debug("Non-GOT reference to local symbol %lu\n",
-+                         r_symndx);
-+                htab->local_dynamic_relocs++;
-+              }
-+          }
-+
-+        break;
-+
-+        /* TODO: GNU_VTINHERIT and GNU_VTENTRY */
-+      }
-+    }
-+
-+  return TRUE;
-+}
-+
-+/* (3) Adjust a symbol defined by a dynamic object and referenced by a
-+   regular object.  The current definition is in some section of the
-+   dynamic object, but we're not including those sections.  We have to
-+   change the definition to something the rest of the link can
-+   understand.  */
-+
-+static bfd_boolean
-+avr32_elf_adjust_dynamic_symbol(struct bfd_link_info *info,
-+                              struct elf_link_hash_entry *h)
-+{
-+  struct elf_avr32_link_hash_table *htab;
-+  struct elf_avr32_link_hash_entry *havr;
-+  bfd *dynobj;
-+
-+  pr_debug("(3) adjust dynamic symbol %s\n", h->root.root.string);
-+
-+  htab = avr32_elf_hash_table(info);
-+  havr = (struct elf_avr32_link_hash_entry *)h;
-+  dynobj = elf_hash_table(info)->dynobj;
-+
-+  /* Make sure we know what is going on here.  */
-+  BFD_ASSERT (dynobj != NULL
-+            && (h->u.weakdef != NULL
-+                || (h->def_dynamic
-+                    && h->ref_regular
-+                    && !h->def_regular)));
-+
-+  /* We don't want dynamic relocations in read-only sections. */
-+  if (havr->readonly_reloc_sec)
-+    {
-+      if (info->callbacks->reloc_dangerous
-+        (info, _("dynamic relocation in read-only section"),
-+         havr->readonly_reloc_sec->owner, havr->readonly_reloc_sec,
-+         havr->readonly_reloc_offset) == FALSE)
-+      return FALSE;
-+    }
-+
-+  /* If this is a function, create a stub if possible and set the
-+     symbol to the stub location.  */
-+  if (0 && !havr->no_fn_stub)
-+    {
-+      if (!h->def_regular)
-+      {
-+        asection *s = htab->sstub;
-+
-+        BFD_ASSERT(s != NULL);
-+
-+        h->root.u.def.section = s;
-+        h->root.u.def.value = s->size;
-+        h->plt.offset = s->size;
-+        s->size += AVR32_FUNCTION_STUB_SIZE;
-+
-+        return TRUE;
-+      }
-+    }
-+  else if (h->type == STT_FUNC)
-+    {
-+      /* This will set the entry for this symbol in the GOT to 0, and
-+       the dynamic linker will take care of this. */
-+      h->root.u.def.value = 0;
-+      return TRUE;
-+    }
-+
-+  /* If this is a weak symbol, and there is a real definition, the
-+     processor independent code will have arranged for us to see the
-+     real definition first, and we can just use the same value.  */
-+  if (h->u.weakdef != NULL)
-+    {
-+      BFD_ASSERT(h->u.weakdef->root.type == bfd_link_hash_defined
-+               || h->u.weakdef->root.type == bfd_link_hash_defweak);
-+      h->root.u.def.section = h->u.weakdef->root.u.def.section;
-+      h->root.u.def.value = h->u.weakdef->root.u.def.value;
-+      return TRUE;
-+    }
-+
-+  /* This is a reference to a symbol defined by a dynamic object which
-+     is not a function.  */
-+
-+  return TRUE;
-+}
-+
-+
-+/* Garbage-collection of unused sections */
-+
-+static asection *
-+avr32_elf_gc_mark_hook(asection *sec,
-+                     struct bfd_link_info *info ATTRIBUTE_UNUSED,
-+                     Elf_Internal_Rela *rel,
-+                     struct elf_link_hash_entry *h,
-+                     Elf_Internal_Sym *sym)
-+{
-+  if (h)
-+    {
-+      switch (ELF32_R_TYPE(rel->r_info))
-+      {
-+        /* TODO: VTINHERIT/VTENTRY */
-+      default:
-+        switch (h->root.type)
-+          {
-+          case bfd_link_hash_defined:
-+          case bfd_link_hash_defweak:
-+            return h->root.u.def.section;
-+
-+          case bfd_link_hash_common:
-+            return h->root.u.c.p->section;
-+
-+          default:
-+            break;
-+          }
-+      }
-+    }
-+  else
-+    return bfd_section_from_elf_index(sec->owner, sym->st_shndx);
-+
-+  return NULL;
-+}
-+
-+/* Update the GOT entry reference counts for the section being removed. */
-+static bfd_boolean
-+avr32_elf_gc_sweep_hook(bfd *abfd,
-+                      struct bfd_link_info *info ATTRIBUTE_UNUSED,
-+                      asection *sec,
-+                      const Elf_Internal_Rela *relocs)
-+{
-+  Elf_Internal_Shdr *symtab_hdr;
-+  struct elf_avr32_link_hash_entry **sym_hashes;
-+  struct got_entry **local_got_ents;
-+  const Elf_Internal_Rela *rel, *relend;
-+
-+  if (!(sec->flags & SEC_ALLOC))
-+    return TRUE;
-+
-+  symtab_hdr = &elf_tdata(abfd)->symtab_hdr;
-+  sym_hashes = (struct elf_avr32_link_hash_entry **)elf_sym_hashes(abfd);
-+  local_got_ents = elf_local_got_ents(abfd);
-+
-+  relend = relocs + sec->reloc_count;
-+  for (rel = relocs; rel < relend; rel++)
-+    {
-+      unsigned long r_symndx;
-+      unsigned int r_type;
-+      struct elf_avr32_link_hash_entry *h = NULL;
-+
-+      r_symndx = ELF32_R_SYM(rel->r_info);
-+      if (r_symndx >= symtab_hdr->sh_info)
-+      {
-+        h = sym_hashes[r_symndx - symtab_hdr->sh_info];
-+        while (h->root.root.type == bfd_link_hash_indirect
-+               || h->root.root.type == bfd_link_hash_warning)
-+          h = (struct elf_avr32_link_hash_entry *)h->root.root.u.i.link;
-+      }
-+
-+      r_type = ELF32_R_TYPE(rel->r_info);
-+
-+      switch (r_type)
-+      {
-+      case R_AVR32_GOT32:
-+      case R_AVR32_GOT16:
-+      case R_AVR32_GOT8:
-+      case R_AVR32_GOT21S:
-+      case R_AVR32_GOT18SW:
-+      case R_AVR32_GOT16S:
-+      case R_AVR32_GOT7UW:
-+      case R_AVR32_LDA_GOT:
-+      case R_AVR32_GOTCALL:
-+        if (h)
-+          h->root.got.glist->refcount--;
-+        else
-+          local_got_ents[r_symndx]->refcount--;
-+        break;
-+
-+      case R_AVR32_32:
-+        if (info->shared || h)
-+          {
-+            if (h)
-+              h->possibly_dynamic_relocs--;
-+            else
-+              avr32_elf_hash_table(info)->local_dynamic_relocs--;
-+          }
-+
-+      default:
-+        break;
-+      }
-+    }
-+
-+  return TRUE;
-+}
-+
-+/* Sizing and refcounting of dynamic sections */
-+
-+static void
-+insert_got_entry(struct elf_avr32_link_hash_table *htab, struct got_entry *got);
-+static void
-+unref_got_entry(struct elf_avr32_link_hash_table *htab, struct got_entry *got);
-+static void
-+ref_got_entry(struct elf_avr32_link_hash_table *htab, struct got_entry *got);
-+static bfd_boolean
-+assign_got_offsets(struct elf_avr32_link_hash_table *htab);
-+static bfd_boolean
-+allocate_dynrelocs(struct elf_link_hash_entry *h, void *_info);
-+static bfd_boolean
-+avr32_elf_size_dynamic_sections (bfd *output_bfd,
-+                               struct bfd_link_info *info);
-+
-+static void
-+insert_got_entry(struct elf_avr32_link_hash_table *htab, struct got_entry *got)
-+{
-+  /* Any entries with got_refcount > htab->nr_got_holes end up in the
-+   * last pigeonhole without any sorting. We expect the number of such
-+   * entries to be small, so it is very unlikely to affect
-+   * performance.  */
-+  int entry = got->refcount;
-+
-+  if (entry > htab->nr_got_holes)
-+    entry = htab->nr_got_holes;
-+
-+  got->pprev = &htab->got_hole[entry];
-+  got->next = htab->got_hole[entry];
-+
-+  if (got->next)
-+    got->next->pprev = &got->next;
-+
-+  htab->got_hole[entry] = got;
-+}
-+
-+/* Decrement the refcount of a GOT entry and update its position in
-+   the pigeonhole array.  */
-+static void
-+unref_got_entry(struct elf_avr32_link_hash_table *htab, struct got_entry *got)
-+{
-+  BFD_ASSERT(got->refcount > 0);
-+
-+  if (got->next)
-+    got->next->pprev = got->pprev;
-+
-+  *(got->pprev) = got->next;
-+  got->refcount--;
-+  insert_got_entry(htab, got);
-+}
-+
-+static void
-+ref_got_entry(struct elf_avr32_link_hash_table *htab, struct got_entry *got)
-+{
-+  if (got->next)
-+    got->next->pprev = got->pprev;
-+
-+  *(got->pprev) = got->next;
-+  got->refcount++;
-+  insert_got_entry(htab, got);
-+
-+  BFD_ASSERT(got->refcount > 0);
-+}
-+
-+/* Assign offsets to all GOT entries we intend to keep.  The entries
-+   that are referenced most often are placed at low offsets so that we
-+   can use compact instructions as much as possible.
-+
-+   Returns TRUE if any offsets or the total size of the GOT changed.  */
-+
-+static bfd_boolean
-+assign_got_offsets(struct elf_avr32_link_hash_table *htab)
-+{
-+  struct got_entry *got;
-+  bfd_size_type got_size = 0;
-+  bfd_boolean changed = FALSE;
-+  bfd_signed_vma offset;
-+  int i;
-+
-+  /* The GOT header provides the address of the DYNAMIC segment, so
-+     we need that even if the GOT is otherwise empty.  */
-+  if (htab->root.dynamic_sections_created)
-+    got_size = AVR32_GOT_HEADER_SIZE;
-+
-+  for (i = htab->nr_got_holes; i > 0; i--)
-+    {
-+      got = htab->got_hole[i];
-+      while (got)
-+      {
-+        if (got->refcount > 0)
-+          {
-+            offset = got_size;
-+            if (got->offset != offset)
-+              {
-+                RDBG("GOT offset changed: %ld -> %ld\n",
-+                     got->offset, offset);
-+                changed = TRUE;
-+              }
-+            got->offset = offset;
-+            got_size += 4;
-+          }
-+        got = got->next;
-+      }
-+    }
-+
-+  if (htab->sgot->size != got_size)
-+    {
-+      RDBG("GOT size changed: %lu -> %lu\n", htab->sgot->size,
-+         got_size);
-+      changed = TRUE;
-+    }
-+  htab->sgot->size = got_size;
-+
-+  RDBG("assign_got_offsets: total size %lu (%s)\n",
-+       got_size, changed ? "changed" : "no change");
-+
-+  return changed;
-+}
-+
-+static bfd_boolean
-+allocate_dynrelocs(struct elf_link_hash_entry *h, void *_info)
-+{
-+  struct bfd_link_info *info = _info;
-+  struct elf_avr32_link_hash_table *htab;
-+  struct elf_avr32_link_hash_entry *havr;
-+  struct got_entry *got;
-+
-+  pr_debug("  (4b) allocate_dynrelocs: %s\n", h->root.root.string);
-+
-+  if (h->root.type == bfd_link_hash_indirect)
-+    return TRUE;
-+
-+  if (h->root.type == bfd_link_hash_warning)
-+    /* When warning symbols are created, they **replace** the "real"
-+       entry in the hash table, thus we never get to see the real
-+       symbol in a hash traversal.  So look at it now.  */
-+    h = (struct elf_link_hash_entry *) h->root.u.i.link;
-+
-+  htab = avr32_elf_hash_table(info);
-+  havr = (struct elf_avr32_link_hash_entry *)h;
-+
-+  got = h->got.glist;
-+
-+  /* If got is NULL, the symbol is never referenced through the GOT */
-+  if (got && got->refcount > 0)
-+    {
-+      insert_got_entry(htab, got);
-+
-+      /* Shared libraries need relocs for all GOT entries unless the
-+       symbol is forced local or -Bsymbolic is used.  Others need
-+       relocs for everything that is not guaranteed to be defined in
-+       a regular object.  */
-+      if ((info->shared
-+         && !info->symbolic
-+         && h->dynindx != -1)
-+        || (htab->root.dynamic_sections_created
-+            && h->def_dynamic
-+            && !h->def_regular))
-+      htab->srelgot->size += sizeof(Elf32_External_Rela);
-+    }
-+
-+  if (havr->possibly_dynamic_relocs
-+      && (info->shared
-+        || (elf_hash_table(info)->dynamic_sections_created
-+            && h->def_dynamic
-+            && !h->def_regular)))
-+    {
-+      pr_debug("Allocating %d dynamic reloc against symbol %s...\n",
-+             havr->possibly_dynamic_relocs, h->root.root.string);
-+      htab->srelgot->size += (havr->possibly_dynamic_relocs
-+                            * sizeof(Elf32_External_Rela));
-+    }
-+
-+  return TRUE;
-+}
-+
-+/* (4) Calculate the sizes of the linker-generated sections and
-+   allocate memory for them.  */
-+
-+static bfd_boolean
-+avr32_elf_size_dynamic_sections (bfd *output_bfd,
-+                               struct bfd_link_info *info)
-+{
-+  struct elf_avr32_link_hash_table *htab;
-+  bfd *dynobj;
-+  asection *s;
-+  bfd *ibfd;
-+  bfd_boolean relocs;
-+
-+  pr_debug("(4) size dynamic sections\n");
-+
-+  htab = avr32_elf_hash_table(info);
-+  dynobj = htab->root.dynobj;
-+  BFD_ASSERT(dynobj != NULL);
-+
-+  if (htab->root.dynamic_sections_created)
-+    {
-+      /* Initialize the contents of the .interp section to the name of
-+       the dynamic loader */
-+      if (info->executable)
-+      {
-+        s = bfd_get_section_by_name(dynobj, ".interp");
-+        BFD_ASSERT(s != NULL);
-+        s->size = sizeof(ELF_DYNAMIC_INTERPRETER);
-+        s->contents = (unsigned char *)ELF_DYNAMIC_INTERPRETER;
-+      }
-+    }
-+
-+  if (htab->nr_got_holes > 0)
-+    {
-+      /* Allocate holes for the pigeonhole sort algorithm */
-+      pr_debug("Highest GOT refcount: %d\n", htab->nr_got_holes);
-+
-+      /* Limit the memory usage by clipping the number of pigeonholes
-+       * at a predefined maximum. All entries with a higher refcount
-+       * will end up in the last pigeonhole.  */
-+    if (htab->nr_got_holes >= MAX_NR_GOT_HOLES)
-+    {
-+        htab->nr_got_holes = MAX_NR_GOT_HOLES - 1;
-+
-+        pr_debug("Limiting maximum number of GOT pigeonholes to %u\n",
-+                    htab->nr_got_holes);
-+    }
-+      htab->got_hole = bfd_zalloc(output_bfd,
-+                                sizeof(struct got_entry *)
-+                                * (htab->nr_got_holes + 1));
-+      if (!htab->got_hole)
-+      return FALSE;
-+
-+      /* Set up .got offsets for local syms.  */
-+      for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
-+      {
-+        struct got_entry **local_got;
-+        struct got_entry **end_local_got;
-+        Elf_Internal_Shdr *symtab_hdr;
-+        bfd_size_type locsymcount;
-+
-+        pr_debug("  (4a) processing file %s...\n", ibfd->filename);
-+
-+        BFD_ASSERT(bfd_get_flavour(ibfd) == bfd_target_elf_flavour);
-+
-+        local_got = elf_local_got_ents(ibfd);
-+        if (!local_got)
-+          continue;
-+
-+        symtab_hdr = &elf_tdata(ibfd)->symtab_hdr;
-+        locsymcount = symtab_hdr->sh_info;
-+        end_local_got = local_got + locsymcount;
-+
-+        for (; local_got < end_local_got; ++local_got)
-+          insert_got_entry(htab, *local_got);
-+      }
-+    }
-+
-+  /* Allocate global sym .got entries and space for global sym
-+     dynamic relocs */
-+  elf_link_hash_traverse(&htab->root, allocate_dynrelocs, info);
-+
-+  /* Now that we have sorted the GOT entries, we are ready to
-+     assign offsets and determine the initial size of the GOT. */
-+  if (htab->sgot)
-+    assign_got_offsets(htab);
-+
-+  /* Allocate space for local sym dynamic relocs */
-+  BFD_ASSERT(htab->local_dynamic_relocs == 0 || info->shared);
-+  if (htab->local_dynamic_relocs)
-+    htab->srelgot->size += (htab->local_dynamic_relocs
-+                          * sizeof(Elf32_External_Rela));
-+
-+  /* We now have determined the sizes of the various dynamic
-+     sections. Allocate memory for them. */
-+  relocs = FALSE;
-+  for (s = dynobj->sections; s; s = s->next)
-+    {
-+      if ((s->flags & SEC_LINKER_CREATED) == 0)
-+      continue;
-+
-+      if (s == htab->sgot
-+        || s == htab->sstub)
-+      {
-+        /* Strip this section if we don't need it */
-+      }
-+      else if (strncmp (bfd_get_section_name(dynobj, s), ".rela", 5) == 0)
-+      {
-+        if (s->size != 0)
-+          relocs = TRUE;
-+
-+        s->reloc_count = 0;
-+      }
-+      else
-+      {
-+        /* It's not one of our sections */
-+        continue;
-+      }
-+
-+      if (s->size == 0)
-+      {
-+        /* Strip unneeded sections */
-+        pr_debug("Stripping section %s from output...\n", s->name);
-+        /* deleted function in 2.17
-+      _bfd_strip_section_from_output(info, s);
-+      */
-+        continue;
-+      }
-+
-+      s->contents = bfd_zalloc(dynobj, s->size);
-+      if (s->contents == NULL)
-+      return FALSE;
-+    }
-+
-+  if (htab->root.dynamic_sections_created)
-+    {
-+      /* Add some entries to the .dynamic section.  We fill in the
-+       values later, in sh_elf_finish_dynamic_sections, but we
-+       must add the entries now so that we get the correct size for
-+       the .dynamic section.  The DT_DEBUG entry is filled in by the
-+       dynamic linker and used by the debugger.  */
-+#define add_dynamic_entry(TAG, VAL) _bfd_elf_add_dynamic_entry(info, TAG, VAL)
-+
-+      if (!add_dynamic_entry(DT_PLTGOT, 0))
-+      return FALSE;
-+      if (!add_dynamic_entry(DT_AVR32_GOTSZ, 0))
-+      return FALSE;
-+
-+      if (info->executable)
-+      {
-+        if (!add_dynamic_entry(DT_DEBUG, 0))
-+          return FALSE;
-+      }
-+      if (relocs)
-+      {
-+        if (!add_dynamic_entry(DT_RELA, 0)
-+            || !add_dynamic_entry(DT_RELASZ, 0)
-+            || !add_dynamic_entry(DT_RELAENT,
-+                                  sizeof(Elf32_External_Rela)))
-+          return FALSE;
-+      }
-+    }
-+#undef add_dynamic_entry
-+
-+  return TRUE;
-+}
-+
-+
-+/* Access to internal relocations, section contents and symbols.
-+   (stolen from the xtensa port)  */
-+
-+static Elf_Internal_Rela *
-+retrieve_internal_relocs (bfd *abfd, asection *sec, bfd_boolean keep_memory);
-+static void
-+pin_internal_relocs (asection *sec, Elf_Internal_Rela *internal_relocs);
-+static void
-+release_internal_relocs (asection *sec, Elf_Internal_Rela *internal_relocs);
-+static bfd_byte *
-+retrieve_contents (bfd *abfd, asection *sec, bfd_boolean keep_memory);
-+/*
-+static void
-+pin_contents (asection *sec, bfd_byte *contents);
-+*/
-+static void
-+release_contents (asection *sec, bfd_byte *contents);
-+static Elf_Internal_Sym *
-+retrieve_local_syms (bfd *input_bfd, bfd_boolean keep_memory);
-+/*
-+static void
-+pin_local_syms (bfd *input_bfd, Elf_Internal_Sym *isymbuf);
-+*/
-+static void
-+release_local_syms (bfd *input_bfd, Elf_Internal_Sym *isymbuf);
-+
-+/* During relaxation, we need to modify relocations, section contents,
-+   and symbol definitions, and we need to keep the original values from
-+   being reloaded from the input files, i.e., we need to "pin" the
-+   modified values in memory.  We also want to continue to observe the
-+   setting of the "keep-memory" flag.  The following functions wrap the
-+   standard BFD functions to take care of this for us.  */
-+
-+static Elf_Internal_Rela *
-+retrieve_internal_relocs (bfd *abfd, asection *sec, bfd_boolean keep_memory)
-+{
-+  /* _bfd_elf_link_read_relocs knows about caching, so no need for us
-+     to be clever here.  */
-+  return _bfd_elf_link_read_relocs(abfd, sec, NULL, NULL, keep_memory);
-+}
-+
-+static void
-+pin_internal_relocs (asection *sec, Elf_Internal_Rela *internal_relocs)
-+{
-+  elf_section_data (sec)->relocs = internal_relocs;
-+}
-+
-+static void
-+release_internal_relocs (asection *sec, Elf_Internal_Rela *internal_relocs)
-+{
-+  if (internal_relocs
-+      && elf_section_data (sec)->relocs != internal_relocs)
-+    free (internal_relocs);
-+}
-+
-+static bfd_byte *
-+retrieve_contents (bfd *abfd, asection *sec, bfd_boolean keep_memory)
-+{
-+  bfd_byte *contents;
-+  bfd_size_type sec_size;
-+
-+  sec_size = bfd_get_section_limit (abfd, sec);
-+  contents = elf_section_data (sec)->this_hdr.contents;
-+
-+  if (contents == NULL && sec_size != 0)
-+    {
-+      if (!bfd_malloc_and_get_section (abfd, sec, &contents))
-+      {
-+        if (contents)
-+          free (contents);
-+        return NULL;
-+      }
-+      if (keep_memory)
-+      elf_section_data (sec)->this_hdr.contents = contents;
-+    }
-+  return contents;
-+}
-+
-+/*
-+static void
-+pin_contents (asection *sec, bfd_byte *contents)
-+{
-+  elf_section_data (sec)->this_hdr.contents = contents;
-+}
-+*/
-+static void
-+release_contents (asection *sec, bfd_byte *contents)
-+{
-+  if (contents && elf_section_data (sec)->this_hdr.contents != contents)
-+    free (contents);
-+}
-+
-+static Elf_Internal_Sym *
-+retrieve_local_syms (bfd *input_bfd, bfd_boolean keep_memory)
-+{
-+  Elf_Internal_Shdr *symtab_hdr;
-+  Elf_Internal_Sym *isymbuf;
-+  size_t locsymcount;
-+
-+  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
-+  locsymcount = symtab_hdr->sh_info;
-+
-+  isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
-+  if (isymbuf == NULL && locsymcount != 0)
-+    {
-+      isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr, locsymcount, 0,
-+                                    NULL, NULL, NULL);
-+      if (isymbuf && keep_memory)
-+      symtab_hdr->contents = (unsigned char *) isymbuf;
-+    }
-+
-+  return isymbuf;
-+}
-+
-+/*
-+static void
-+pin_local_syms (bfd *input_bfd, Elf_Internal_Sym *isymbuf)
-+{
-+  elf_tdata (input_bfd)->symtab_hdr.contents = (unsigned char *)isymbuf;
-+}
-+
-+*/
-+static void
-+release_local_syms (bfd *input_bfd, Elf_Internal_Sym *isymbuf)
-+{
-+  if (isymbuf && (elf_tdata (input_bfd)->symtab_hdr.contents
-+                != (unsigned char *)isymbuf))
-+    free (isymbuf);
-+}
-+
-+\f/* Data structures used during relaxation. */
-+
-+enum relax_state_id {
-+  RS_ERROR = -1,
-+  RS_NONE = 0,
-+  RS_ALIGN,
-+  RS_CPENT,
-+  RS_PIC_CALL,
-+  RS_PIC_MCALL,
-+  RS_PIC_RCALL2,
-+  RS_PIC_RCALL1,
-+  RS_PIC_LDA,
-+  RS_PIC_LDW4,
-+  RS_PIC_LDW3,
-+  RS_PIC_SUB5,
-+  RS_NOPIC_MCALL,
-+  RS_NOPIC_RCALL2,
-+  RS_NOPIC_RCALL1,
-+  RS_NOPIC_LDW4,
-+  RS_NOPIC_LDDPC,
-+  RS_NOPIC_SUB5,
-+  RS_NOPIC_MOV2,
-+  RS_NOPIC_MOV1,
-+  RS_RCALL2,
-+  RS_RCALL1,
-+  RS_BRC2,
-+  RS_BRC1,
-+  RS_BRAL,
-+  RS_RJMP,
-+  RS_MAX,
-+};
-+
-+enum reference_type {
-+  REF_ABSOLUTE,
-+  REF_PCREL,
-+  REF_CPOOL,
-+  REF_GOT,
-+};
-+
-+struct relax_state
-+{
-+  const char *name;
-+  enum relax_state_id id;
-+  enum relax_state_id direct;
-+  enum relax_state_id next;
-+  enum relax_state_id prev;
-+
-+  enum reference_type reftype;
-+
-+  unsigned int r_type;
-+
-+  bfd_vma opcode;
-+  bfd_vma opcode_mask;
-+
-+  bfd_signed_vma range_min;
-+  bfd_signed_vma range_max;
-+
-+  bfd_size_type size;
-+};
-+
-+/*
-+ * This is for relocs that
-+ *   a) has an addend or is of type R_AVR32_DIFF32, and
-+ *   b) references a different section than it's in, and
-+ *   c) references a section that is relaxable
-+ *
-+ * as well as relocs that references the constant pool, in which case
-+ * the add_frag member points to the frag containing the constant pool
-+ * entry.
-+ *
-+ * Such relocs must be fixed up whenever we delete any code. Sections
-+ * that don't have any relocs with all of the above properties don't
-+ * have any additional reloc data, but sections that do will have
-+ * additional data for all its relocs.
-+ */
-+struct avr32_reloc_data
-+{
-+  struct fragment *add_frag;
-+  struct fragment *sub_frag;
-+};
-+
-+/*
-+ * A 'fragment' is a relaxable entity, that is, code may be added or
-+ * deleted at the end of a fragment. When this happens, all subsequent
-+ * fragments in the list will have their offsets updated.
-+ */
-+struct fragment
-+{
-+  enum relax_state_id state;
-+  enum relax_state_id initial_state;
-+
-+  Elf_Internal_Rela *rela;
-+  bfd_size_type size;
-+  bfd_vma offset;
-+  int size_adjust;
-+  int offset_adjust;
-+  bfd_boolean has_grown;
-+
-+  /* Only used by constant pool entries.  When this drops to zero, the
-+     frag is discarded (i.e. size_adjust is set to -4.)  */
-+  int refcount;
-+};
-+
-+struct avr32_relax_data
-+{
-+  unsigned int frag_count;
-+  struct fragment *frag;
-+  struct avr32_reloc_data *reloc_data;
-+
-+  /* TRUE if this section has one or more relaxable relocations */
-+  bfd_boolean is_relaxable;
-+  unsigned int iteration;
-+};
-+
-+struct avr32_section_data
-+{
-+  struct bfd_elf_section_data elf;
-+  struct avr32_relax_data relax_data;
-+};
-+
-+\f/* Relax state definitions */
-+
-+#define PIC_MOV2_OPCODE               0xe0600000
-+#define PIC_MOV2_MASK         0xe1e00000
-+#define PIC_MOV2_RANGE_MIN    (-1048576 * 4)
-+#define PIC_MOV2_RANGE_MAX    (1048575 * 4)
-+#define PIC_MCALL_OPCODE      0xf0160000
-+#define PIC_MCALL_MASK                0xffff0000
-+#define PIC_MCALL_RANGE_MIN   (-131072)
-+#define PIC_MCALL_RANGE_MAX   (131068)
-+#define RCALL2_OPCODE         0xe0a00000
-+#define RCALL2_MASK           0xe1ef0000
-+#define RCALL2_RANGE_MIN      (-2097152)
-+#define RCALL2_RANGE_MAX      (2097150)
-+#define RCALL1_OPCODE         0xc00c0000
-+#define RCALL1_MASK           0xf00c0000
-+#define RCALL1_RANGE_MIN      (-1024)
-+#define RCALL1_RANGE_MAX      (1022)
-+#define PIC_LDW4_OPCODE               0xecf00000
-+#define PIC_LDW4_MASK         0xfff00000
-+#define PIC_LDW4_RANGE_MIN    (-32768)
-+#define PIC_LDW4_RANGE_MAX    (32767)
-+#define PIC_LDW3_OPCODE               0x6c000000
-+#define PIC_LDW3_MASK         0xfe000000
-+#define PIC_LDW3_RANGE_MIN    (0)
-+#define PIC_LDW3_RANGE_MAX    (124)
-+#define SUB5_PC_OPCODE                0xfec00000
-+#define SUB5_PC_MASK          0xfff00000
-+#define SUB5_PC_RANGE_MIN     (-32768)
-+#define SUB5_PC_RANGE_MAX     (32767)
-+#define NOPIC_MCALL_OPCODE    0xf01f0000
-+#define NOPIC_MCALL_MASK      0xffff0000
-+#define NOPIC_MCALL_RANGE_MIN PIC_MCALL_RANGE_MIN
-+#define NOPIC_MCALL_RANGE_MAX PIC_MCALL_RANGE_MAX
-+#define NOPIC_LDW4_OPCODE     0xfef00000
-+#define NOPIC_LDW4_MASK               0xfff00000
-+#define NOPIC_LDW4_RANGE_MIN  PIC_LDW4_RANGE_MIN
-+#define NOPIC_LDW4_RANGE_MAX  PIC_LDW4_RANGE_MAX
-+#define LDDPC_OPCODE          0x48000000
-+#define LDDPC_MASK            0xf8000000
-+#define LDDPC_RANGE_MIN               0
-+#define LDDPC_RANGE_MAX               508
-+
-+#define NOPIC_MOV2_OPCODE  0xe0600000
-+#define NOPIC_MOV2_MASK        0xe1e00000
-+#define NOPIC_MOV2_RANGE_MIN   (-1048576)
-+#define NOPIC_MOV2_RANGE_MAX   (1048575)
-+#define NOPIC_MOV1_OPCODE  0x30000000
-+#define NOPIC_MOV1_MASK        0xf0000000
-+#define NOPIC_MOV1_RANGE_MIN   (-128)
-+#define NOPIC_MOV1_RANGE_MAX   (127)
-+
-+/* Only brc2 variants with cond[3] == 0 is considered, since the
-+   others are not relaxable.  bral is a special case and is handled
-+   separately.  */
-+#define BRC2_OPCODE           0xe0800000
-+#define BRC2_MASK             0xe1e80000
-+#define BRC2_RANGE_MIN                (-2097152)
-+#define BRC2_RANGE_MAX                (2097150)
-+#define BRC1_OPCODE           0xc0000000
-+#define BRC1_MASK             0xf0080000
-+#define BRC1_RANGE_MIN                (-256)
-+#define BRC1_RANGE_MAX                (254)
-+#define BRAL_OPCODE           0xe08f0000
-+#define BRAL_MASK             0xe1ef0000
-+#define BRAL_RANGE_MIN                BRC2_RANGE_MIN
-+#define BRAL_RANGE_MAX                BRC2_RANGE_MAX
-+#define RJMP_OPCODE           0xc0080000
-+#define RJMP_MASK             0xf00c0000
-+#define RJMP_RANGE_MIN                (-1024)
-+#define RJMP_RANGE_MAX                (1022)
-+
-+/* Define a relax state using the GOT  */
-+#define RG(id, dir, next, prev, r_type, opc, size)                    \
-+  { "RS_"#id, RS_##id, RS_##dir, RS_##next, RS_##prev, REF_GOT,               \
-+      R_AVR32_##r_type,       opc##_OPCODE, opc##_MASK,                       \
-+      opc##_RANGE_MIN, opc##_RANGE_MAX, size }
-+/* Define a relax state using the Constant Pool  */
-+#define RC(id, dir, next, prev, r_type, opc, size)                    \
-+  { "RS_"#id, RS_##id, RS_##dir, RS_##next, RS_##prev, REF_CPOOL,     \
-+      R_AVR32_##r_type,       opc##_OPCODE, opc##_MASK,                       \
-+      opc##_RANGE_MIN, opc##_RANGE_MAX, size }
-+
-+/* Define a relax state using pc-relative direct reference  */
-+#define RP(id, dir, next, prev, r_type, opc, size)                    \
-+  { "RS_"#id, RS_##id, RS_##dir, RS_##next, RS_##prev, REF_PCREL,     \
-+      R_AVR32_##r_type,       opc##_OPCODE, opc##_MASK,                       \
-+      opc##_RANGE_MIN, opc##_RANGE_MAX, size }
-+
-+/* Define a relax state using non-pc-relative direct reference */
-+#define RD(id, dir, next, prev, r_type, opc, size)         \
-+  { "RS_"#id, RS_##id, RS_##dir, RS_##next, RS_##prev, REF_ABSOLUTE,   \
-+      R_AVR32_##r_type,    opc##_OPCODE, opc##_MASK,           \
-+      opc##_RANGE_MIN, opc##_RANGE_MAX, size }
-+
-+/* Define a relax state that will be handled specially  */
-+#define RS(id, r_type, size)                                          \
-+  { "RS_"#id, RS_##id, RS_NONE, RS_NONE, RS_NONE, REF_ABSOLUTE,               \
-+      R_AVR32_##r_type, 0, 0, 0, 0, size }
-+
-+const struct relax_state relax_state[RS_MAX] = {
-+  RS(NONE, NONE, 0),
-+  RS(ALIGN, ALIGN, 0),
-+  RS(CPENT, 32_CPENT, 4),
-+
-+  RG(PIC_CALL, PIC_RCALL1, PIC_MCALL, NONE, GOTCALL, PIC_MOV2, 10),
-+  RG(PIC_MCALL, PIC_RCALL1, NONE, PIC_CALL, GOT18SW, PIC_MCALL, 4),
-+  RP(PIC_RCALL2, NONE, PIC_RCALL1, PIC_MCALL, 22H_PCREL, RCALL2, 4),
-+  RP(PIC_RCALL1, NONE, NONE, PIC_RCALL2, 11H_PCREL, RCALL1, 2),
-+
-+  RG(PIC_LDA, PIC_SUB5, PIC_LDW4, NONE, LDA_GOT, PIC_MOV2, 8),
-+  RG(PIC_LDW4, PIC_SUB5, PIC_LDW3, PIC_LDA, GOT16S, PIC_LDW4, 4),
-+  RG(PIC_LDW3, PIC_SUB5, NONE, PIC_LDW4, GOT7UW, PIC_LDW3, 2),
-+  RP(PIC_SUB5, NONE, NONE, PIC_LDW3, 16N_PCREL, SUB5_PC, 4),
-+
-+  RC(NOPIC_MCALL, NOPIC_RCALL1, NONE, NONE, CPCALL, NOPIC_MCALL, 4),
-+  RP(NOPIC_RCALL2, NONE, NOPIC_RCALL1, NOPIC_MCALL, 22H_PCREL, RCALL2, 4),
-+  RP(NOPIC_RCALL1, NONE, NONE, NOPIC_RCALL2, 11H_PCREL, RCALL1, 2),
-+
-+  RC(NOPIC_LDW4, NOPIC_MOV1, NOPIC_LDDPC, NONE, 16_CP, NOPIC_LDW4, 4),
-+  RC(NOPIC_LDDPC, NOPIC_MOV1, NONE, NOPIC_LDW4, 9W_CP, LDDPC, 2),
-+  RP(NOPIC_SUB5, NOPIC_MOV1, NONE, NOPIC_LDDPC, 16N_PCREL, SUB5_PC, 4),
-+  RD(NOPIC_MOV2, NONE, NOPIC_MOV1, NOPIC_SUB5, 21S, NOPIC_MOV2, 4),
-+  RD(NOPIC_MOV1, NONE, NONE, NOPIC_MOV2, 8S, NOPIC_MOV1, 2),
-+
-+  RP(RCALL2, NONE, RCALL1, NONE, 22H_PCREL, RCALL2, 4),
-+  RP(RCALL1, NONE, NONE, RCALL2, 11H_PCREL, RCALL1, 2),
-+  RP(BRC2, NONE, BRC1, NONE, 22H_PCREL, BRC2, 4),
-+  RP(BRC1, NONE, NONE, BRC2, 9H_PCREL, BRC1, 2),
-+  RP(BRAL, NONE, RJMP, NONE, 22H_PCREL, BRAL, 4),
-+  RP(RJMP, NONE, NONE, BRAL, 11H_PCREL, RJMP, 2),
-+};
-+
-+static bfd_boolean
-+avr32_elf_new_section_hook(bfd *abfd, asection *sec)
-+{
-+  struct avr32_section_data *sdata;
-+
-+  sdata = bfd_zalloc(abfd, sizeof(struct avr32_section_data));
-+  if (!sdata)
-+    return FALSE;
-+
-+  sec->used_by_bfd = sdata;
-+  return _bfd_elf_new_section_hook(abfd, sec);
-+}
-+
-+static struct avr32_relax_data *
-+avr32_relax_data(asection *sec)
-+{
-+  struct avr32_section_data *sdata;
-+
-+  BFD_ASSERT(sec->used_by_bfd);
-+
-+  sdata = (struct avr32_section_data *)elf_section_data(sec);
-+  return &sdata->relax_data;
-+}
-+
-+\f/* Link-time relaxation */
-+
-+static bfd_boolean
-+avr32_elf_relax_section(bfd *abfd, asection *sec,
-+                      struct bfd_link_info *info, bfd_boolean *again);
-+
-+enum relax_pass_id {
-+  RELAX_PASS_SIZE_FRAGS,
-+  RELAX_PASS_MOVE_DATA,
-+};
-+
-+/* Stolen from the xtensa port */
-+static int
-+internal_reloc_compare (const void *ap, const void *bp)
-+{
-+  const Elf_Internal_Rela *a = (const Elf_Internal_Rela *) ap;
-+  const Elf_Internal_Rela *b = (const Elf_Internal_Rela *) bp;
-+
-+  if (a->r_offset != b->r_offset)
-+    return (a->r_offset - b->r_offset);
-+
-+  /* We don't need to sort on these criteria for correctness,
-+     but enforcing a more strict ordering prevents unstable qsort
-+     from behaving differently with different implementations.
-+     Without the code below we get correct but different results
-+     on Solaris 2.7 and 2.8.  We would like to always produce the
-+     same results no matter the host.  */
-+
-+  if (a->r_info != b->r_info)
-+    return (a->r_info - b->r_info);
-+
-+  return (a->r_addend - b->r_addend);
-+}
-+
-+static enum relax_state_id
-+get_pcrel22_relax_state(bfd *abfd, asection *sec, struct bfd_link_info *info,
-+                      const Elf_Internal_Rela *rela)
-+{
-+  bfd_byte *contents;
-+  bfd_vma insn;
-+  enum relax_state_id rs = RS_NONE;
-+
-+  contents = retrieve_contents(abfd, sec, info->keep_memory);
-+  if (!contents)
-+    return RS_ERROR;
-+
-+  insn = bfd_get_32(abfd, contents + rela->r_offset);
-+  if ((insn & RCALL2_MASK) == RCALL2_OPCODE)
-+    rs = RS_RCALL2;
-+  else if ((insn & BRAL_MASK) == BRAL_OPCODE)
-+    /* Optimizing bral -> rjmp gets us into all kinds of
-+       trouble with jump tables. Better not do it.  */
-+    rs = RS_NONE;
-+  else if ((insn & BRC2_MASK) == BRC2_OPCODE)
-+    rs = RS_BRC2;
-+
-+  release_contents(sec, contents);
-+
-+  return rs;
-+}
-+
-+static enum relax_state_id
-+get_initial_relax_state(bfd *abfd, asection *sec, struct bfd_link_info *info,
-+                      const Elf_Internal_Rela *rela)
-+{
-+  switch (ELF_R_TYPE(rela->r_info))
-+    {
-+    case R_AVR32_GOTCALL:
-+      return RS_PIC_CALL;
-+    case R_AVR32_GOT18SW:
-+      return RS_PIC_MCALL;
-+    case R_AVR32_LDA_GOT:
-+      return RS_PIC_LDA;
-+    case R_AVR32_GOT16S:
-+      return RS_PIC_LDW4;
-+    case R_AVR32_CPCALL:
-+      return RS_NOPIC_MCALL;
-+    case R_AVR32_16_CP:
-+      return RS_NOPIC_LDW4;
-+    case R_AVR32_9W_CP:
-+      return RS_NOPIC_LDDPC;
-+    case R_AVR32_ALIGN:
-+      return RS_ALIGN;
-+    case R_AVR32_32_CPENT:
-+      return RS_CPENT;
-+    case R_AVR32_22H_PCREL:
-+      return get_pcrel22_relax_state(abfd, sec, info, rela);
-+    case R_AVR32_9H_PCREL:
-+      return RS_BRC1;
-+    default:
-+      return RS_NONE;
-+    }
-+}
-+
-+static bfd_boolean
-+reloc_is_cpool_ref(const Elf_Internal_Rela *rela)
-+{
-+  switch (ELF_R_TYPE(rela->r_info))
-+    {
-+    case R_AVR32_CPCALL:
-+    case R_AVR32_16_CP:
-+    case R_AVR32_9W_CP:
-+      return TRUE;
-+    default:
-+      return FALSE;
-+    }
-+}
-+
-+static struct fragment *
-+new_frag(bfd *abfd ATTRIBUTE_UNUSED, asection *sec,
-+       struct avr32_relax_data *rd, enum relax_state_id state,
-+       Elf_Internal_Rela *rela)
-+{
-+  struct fragment *frag;
-+  bfd_size_type r_size;
-+  bfd_vma r_offset;
-+  unsigned int i = rd->frag_count;
-+
-+  BFD_ASSERT(state >= RS_NONE && state < RS_MAX);
-+
-+  rd->frag_count++;
-+  frag = bfd_realloc(rd->frag, sizeof(struct fragment) * rd->frag_count);
-+  if (!frag)
-+    return NULL;
-+  rd->frag = frag;
-+
-+  frag += i;
-+  memset(frag, 0, sizeof(struct fragment));
-+
-+  if (state == RS_ALIGN)
-+    r_size = (((rela->r_offset + (1 << rela->r_addend) - 1)
-+             & ~((1 << rela->r_addend) - 1)) - rela->r_offset);
-+  else
-+    r_size = relax_state[state].size;
-+
-+  if (rela)
-+    r_offset = rela->r_offset;
-+  else
-+    r_offset = sec->size;
-+
-+  if (i == 0)
-+    {
-+      frag->offset = 0;
-+      frag->size = r_offset + r_size;
-+    }
-+  else
-+    {
-+      frag->offset = rd->frag[i - 1].offset + rd->frag[i - 1].size;
-+      frag->size = r_offset + r_size - frag->offset;
-+    }
-+
-+  if (state != RS_CPENT)
-+    /* Make sure we don't discard this frag */
-+    frag->refcount = 1;
-+
-+  frag->initial_state = frag->state = state;
-+  frag->rela = rela;
-+
-+  return frag;
-+}
-+
-+static struct fragment *
-+find_frag(asection *sec, bfd_vma offset)
-+{
-+  struct fragment *first, *last;
-+  struct avr32_relax_data *rd = avr32_relax_data(sec);
-+
-+  if (rd->frag_count == 0)
-+    return NULL;
-+
-+  first = &rd->frag[0];
-+  last = &rd->frag[rd->frag_count - 1];
-+
-+  /* This may be a reloc referencing the end of a section.  The last
-+     frag will never have a reloc associated with it, so its size will
-+     never change, thus the offset adjustment of the last frag will
-+     always be the same as the offset adjustment of the end of the
-+     section.  */
-+  if (offset == sec->size)
-+    {
-+      BFD_ASSERT(last->offset + last->size == sec->size);
-+      BFD_ASSERT(!last->rela);
-+      return last;
-+    }
-+
-+  while (first <= last)
-+    {
-+      struct fragment *mid;
-+
-+      mid = (last - first) / 2 + first;
-+      if ((mid->offset + mid->size) <= offset)
-+      first = mid + 1;
-+      else if (mid->offset > offset)
-+      last = mid - 1;
-+      else
-+      return mid;
-+    }
-+
-+  return NULL;
-+}
-+
-+/* Look through all relocs in a section and determine if any relocs
-+   may be affected by relaxation in other sections.  If so, allocate
-+   an array of additional relocation data which links the affected
-+   relocations to the frag(s) where the relaxation may occur.
-+
-+   This function also links cpool references to cpool entries and
-+   increments the refcount of the latter when this happens.  */
-+
-+static bfd_boolean
-+allocate_reloc_data(bfd *abfd, asection *sec, Elf_Internal_Rela *relocs,
-+                  struct bfd_link_info *info)
-+{
-+  Elf_Internal_Shdr *symtab_hdr;
-+  Elf_Internal_Sym *isymbuf = NULL;
-+  struct avr32_relax_data *rd;
-+  unsigned int i;
-+  bfd_boolean ret = FALSE;
-+
-+  symtab_hdr = &elf_tdata(abfd)->symtab_hdr;
-+  rd = avr32_relax_data(sec);
-+
-+  RDBG("%s<%s>: allocate_reloc_data\n", abfd->filename, sec->name);
-+
-+  for (i = 0; i < sec->reloc_count; i++)
-+    {
-+      Elf_Internal_Rela *rel = &relocs[i];
-+      asection *sym_sec;
-+      unsigned long r_symndx;
-+      bfd_vma sym_value;
-+
-+      if (!rel->r_addend && ELF_R_TYPE(rel->r_info) != R_AVR32_DIFF32
-+        && !reloc_is_cpool_ref(rel))
-+      continue;
-+
-+      r_symndx = ELF_R_SYM(rel->r_info);
-+
-+      if (r_symndx < symtab_hdr->sh_info)
-+      {
-+        Elf_Internal_Sym *isym;
-+
-+        if (!isymbuf)
-+          isymbuf = retrieve_local_syms(abfd, info->keep_memory);
-+        if (!isymbuf)
-+          return FALSE;
-+
-+        isym = &isymbuf[r_symndx];
-+        sym_sec = bfd_section_from_elf_index(abfd, isym->st_shndx);
-+        sym_value = isym->st_value;
-+      }
-+      else
-+      {
-+        struct elf_link_hash_entry *h;
-+
-+        h = elf_sym_hashes(abfd)[r_symndx - symtab_hdr->sh_info];
-+
-+        while (h->root.type == bfd_link_hash_indirect
-+               || h->root.type == bfd_link_hash_warning)
-+          h = (struct elf_link_hash_entry *)h->root.u.i.link;
-+
-+        if (h->root.type != bfd_link_hash_defined
-+            && h->root.type != bfd_link_hash_defweak)
-+          continue;
-+
-+        sym_sec = h->root.u.def.section;
-+        sym_value = h->root.u.def.value;
-+      }
-+
-+      if (sym_sec && avr32_relax_data(sym_sec)->is_relaxable)
-+      {
-+        bfd_size_type size;
-+        struct fragment *frag;
-+
-+        if (!rd->reloc_data)
-+          {
-+            size = sizeof(struct avr32_reloc_data) * sec->reloc_count;
-+            rd->reloc_data = bfd_zalloc(abfd, size);
-+            if (!rd->reloc_data)
-+              goto out;
-+          }
-+
-+        RDBG("[%3d] 0x%04lx: target: 0x%lx + 0x%lx",
-+             i, rel->r_offset, sym_value, rel->r_addend);
-+
-+        frag = find_frag(sym_sec, sym_value + rel->r_addend);
-+        BFD_ASSERT(frag);
-+        rd->reloc_data[i].add_frag = frag;
-+
-+        RDBG(" -> %s<%s>:%04lx\n", sym_sec->owner->filename, sym_sec->name,
-+             frag->rela ? frag->rela->r_offset : sym_sec->size);
-+
-+        if (reloc_is_cpool_ref(rel))
-+          {
-+            BFD_ASSERT(ELF_R_TYPE(frag->rela->r_info) == R_AVR32_32_CPENT);
-+            frag->refcount++;
-+          }
-+
-+        if (ELF_R_TYPE(rel->r_info) == R_AVR32_DIFF32)
-+          {
-+            bfd_byte *contents;
-+            bfd_signed_vma diff;
-+
-+            contents = retrieve_contents(abfd, sec, info->keep_memory);
-+            if (!contents)
-+              goto out;
-+
-+            diff = bfd_get_signed_32(abfd, contents + rel->r_offset);
-+            frag = find_frag(sym_sec, sym_value + rel->r_addend + diff);
-+            BFD_ASSERT(frag);
-+            rd->reloc_data[i].sub_frag = frag;
-+
-+            release_contents(sec, contents);
-+          }
-+      }
-+    }
-+
-+  ret = TRUE;
-+
-+ out:
-+  release_local_syms(abfd, isymbuf);
-+  return ret;
-+}
-+
-+static bfd_boolean
-+global_sym_set_frag(struct elf_avr32_link_hash_entry *havr,
-+                  struct bfd_link_info *info ATTRIBUTE_UNUSED)
-+{
-+  struct fragment *frag;
-+  asection *sec;
-+
-+  if (havr->root.root.type != bfd_link_hash_defined
-+      && havr->root.root.type != bfd_link_hash_defweak)
-+    return TRUE;
-+
-+  sec = havr->root.root.u.def.section;
-+  if (bfd_is_const_section(sec)
-+      || !avr32_relax_data(sec)->is_relaxable)
-+    return TRUE;
-+
-+  frag = find_frag(sec, havr->root.root.u.def.value);
-+  if (!frag)
-+    {
-+      unsigned int i;
-+      struct avr32_relax_data *rd = avr32_relax_data(sec);
-+
-+      RDBG("In %s: No frag for %s <%s+%lu> (limit %lu)\n",
-+         sec->owner->filename, havr->root.root.root.string,
-+         sec->name, havr->root.root.u.def.value, sec->size);
-+      for (i = 0; i < rd->frag_count; i++)
-+      RDBG("    %8lu - %8lu\n", rd->frag[i].offset,
-+           rd->frag[i].offset + rd->frag[i].size);
-+    }
-+  BFD_ASSERT(frag);
-+
-+  havr->sym_frag = frag;
-+  return TRUE;
-+}
-+
-+static bfd_boolean
-+analyze_relocations(struct bfd_link_info *info)
-+{
-+  bfd *abfd;
-+  asection *sec;
-+
-+  /* Divide all relaxable sections into fragments */
-+  for (abfd = info->input_bfds; abfd; abfd = abfd->link_next)
-+    {
-+      if (!(elf_elfheader(abfd)->e_flags & EF_AVR32_LINKRELAX))
-+      {
-+        if (!(*info->callbacks->warning)
-+            (info, _("input is not relaxable"), NULL, abfd, NULL, 0))
-+          return FALSE;
-+        continue;
-+      }
-+
-+      for (sec = abfd->sections; sec; sec = sec->next)
-+      {
-+        struct avr32_relax_data *rd;
-+        struct fragment *frag;
-+        Elf_Internal_Rela *relocs;
-+        unsigned int i;
-+        bfd_boolean ret = TRUE;
-+
-+        if (!(sec->flags & SEC_RELOC) || sec->reloc_count == 0)
-+          continue;
-+
-+        rd = avr32_relax_data(sec);
-+
-+        relocs = retrieve_internal_relocs(abfd, sec, info->keep_memory);
-+        if (!relocs)
-+          return FALSE;
-+
-+        qsort(relocs, sec->reloc_count, sizeof(Elf_Internal_Rela),
-+              internal_reloc_compare);
-+
-+        for (i = 0; i < sec->reloc_count; i++)
-+          {
-+            enum relax_state_id state;
-+
-+            ret = FALSE;
-+            state = get_initial_relax_state(abfd, sec, info, &relocs[i]);
-+            if (state == RS_ERROR)
-+              break;
-+
-+            if (state)
-+              {
-+                frag = new_frag(abfd, sec, rd, state, &relocs[i]);
-+                if (!frag)
-+                  break;
-+
-+                pin_internal_relocs(sec, relocs);
-+                rd->is_relaxable = TRUE;
-+              }
-+
-+            ret = TRUE;
-+          }
-+
-+        release_internal_relocs(sec, relocs);
-+        if (!ret)
-+          return ret;
-+
-+        if (rd->is_relaxable)
-+          {
-+            frag = new_frag(abfd, sec, rd, RS_NONE, NULL);
-+            if (!frag)
-+              return FALSE;
-+          }
-+      }
-+    }
-+
-+  /* Link each global symbol to the fragment where it's defined.  */
-+  elf_link_hash_traverse(elf_hash_table(info), global_sym_set_frag, info);
-+
-+  /* Do the same for local symbols. */
-+  for (abfd = info->input_bfds; abfd; abfd = abfd->link_next)
-+    {
-+      Elf_Internal_Sym *isymbuf, *isym;
-+      struct fragment **local_sym_frag;
-+      unsigned int i, sym_count;
-+
-+      sym_count = elf_tdata(abfd)->symtab_hdr.sh_info;
-+      if (sym_count == 0)
-+      continue;
-+
-+      local_sym_frag = bfd_zalloc(abfd, sym_count * sizeof(struct fragment *));
-+      if (!local_sym_frag)
-+      return FALSE;
-+      elf_tdata(abfd)->local_sym_frag = local_sym_frag;
-+
-+      isymbuf = retrieve_local_syms(abfd, info->keep_memory);
-+      if (!isymbuf)
-+      return FALSE;
-+
-+      for (i = 0; i < sym_count; i++)
-+      {
-+        struct avr32_relax_data *rd;
-+        struct fragment *frag;
-+        asection *sec;
-+
-+        isym = &isymbuf[i];
-+
-+        sec = bfd_section_from_elf_index(abfd, isym->st_shndx);
-+        if (!sec)
-+          continue;
-+
-+        rd = avr32_relax_data(sec);
-+        if (!rd->is_relaxable)
-+          continue;
-+
-+        frag = find_frag(sec, isym->st_value);
-+        BFD_ASSERT(frag);
-+
-+        local_sym_frag[i] = frag;
-+      }
-+
-+      release_local_syms(abfd, isymbuf);
-+    }
-+
-+  /* And again for relocs with addends and constant pool references */
-+  for (abfd = info->input_bfds; abfd; abfd = abfd->link_next)
-+    for (sec = abfd->sections; sec; sec = sec->next)
-+      {
-+      Elf_Internal_Rela *relocs;
-+      bfd_boolean ret;
-+
-+      if (!(sec->flags & SEC_RELOC) || sec->reloc_count == 0)
-+        continue;
-+
-+      relocs = retrieve_internal_relocs(abfd, sec, info->keep_memory);
-+      if (!relocs)
-+        return FALSE;
-+
-+      ret = allocate_reloc_data(abfd, sec, relocs, info);
-+
-+      release_internal_relocs(sec, relocs);
-+      if (ret == FALSE)
-+        return ret;
-+      }
-+
-+  return TRUE;
-+}
-+
-+static bfd_boolean
-+rs_is_good_enough(const struct relax_state *rs, struct fragment *frag,
-+                bfd_vma symval, bfd_vma addr, struct got_entry *got,
-+                struct avr32_reloc_data *ind_data,
-+                bfd_signed_vma offset_adjust)
-+{
-+  bfd_signed_vma target = 0;
-+
-+  switch (rs->reftype)
-+    {
-+    case REF_ABSOLUTE:
-+      target = symval;
-+      break;
-+    case REF_PCREL:
-+      target = symval - addr;
-+      break;
-+    case REF_CPOOL:
-+      /* cpool frags are always in the same section and always after
-+       all frags referring to it.  So it's always correct to add in
-+       offset_adjust here.  */
-+      target = (ind_data->add_frag->offset + ind_data->add_frag->offset_adjust
-+              + offset_adjust - frag->offset - frag->offset_adjust);
-+      break;
-+    case REF_GOT:
-+      target = got->offset;
-+      break;
-+    default:
-+      abort();
-+    }
-+
-+  if (target >= rs->range_min && target <= rs->range_max)
-+    return TRUE;
-+  else
-+    return FALSE;
-+}
-+
-+static bfd_boolean
-+avr32_size_frags(bfd *abfd, asection *sec, struct bfd_link_info *info)
-+{
-+  struct elf_avr32_link_hash_table *htab;
-+  struct avr32_relax_data *rd;
-+  Elf_Internal_Shdr *symtab_hdr;
-+  Elf_Internal_Rela *relocs = NULL;
-+  Elf_Internal_Sym *isymbuf = NULL;
-+  struct got_entry **local_got_ents;
-+  struct fragment **local_sym_frag;
-+  bfd_boolean ret = FALSE;
-+  bfd_signed_vma delta = 0;
-+  unsigned int i;
-+
-+  htab = avr32_elf_hash_table(info);
-+  rd = avr32_relax_data(sec);
-+
-+  if (sec == htab->sgot)
-+    {
-+      RDBG("Relaxing GOT section (vma: 0x%lx)\n",
-+         sec->output_section->vma + sec->output_offset);
-+      if (assign_got_offsets(htab))
-+      htab->repeat_pass = TRUE;
-+      return TRUE;
-+    }
-+
-+  if (!rd->is_relaxable)
-+    return TRUE;
-+
-+  if (!sec->rawsize)
-+    sec->rawsize = sec->size;
-+
-+  symtab_hdr = &elf_tdata(abfd)->symtab_hdr;
-+  relocs = retrieve_internal_relocs(abfd, sec, info->keep_memory);
-+  if (!relocs)
-+    goto out;
-+
-+  isymbuf = retrieve_local_syms(abfd, info->keep_memory);
-+  if (!isymbuf)
-+    goto out;
-+
-+  local_got_ents = elf_local_got_ents(abfd);
-+  local_sym_frag = elf_tdata(abfd)->local_sym_frag;
-+
-+  RDBG("size_frags: %s<%s>\n  vma: 0x%08lx, size: 0x%08lx\n",
-+       abfd->filename, sec->name,
-+       sec->output_section->vma + sec->output_offset, sec->size);
-+
-+  for (i = 0; i < rd->frag_count; i++)
-+    {
-+      struct fragment *frag = &rd->frag[i];
-+      struct avr32_reloc_data *r_data = NULL, *ind_data = NULL;
-+      const struct relax_state *state, *next_state;
-+      struct fragment *target_frag = NULL;
-+      asection *sym_sec = NULL;
-+      Elf_Internal_Rela *rela;
-+      struct got_entry *got;
-+      bfd_vma symval, r_offset, addend, addr;
-+      bfd_signed_vma size_adjust = 0, distance;
-+      unsigned long r_symndx;
-+      bfd_boolean defined = TRUE, dynamic = FALSE;
-+      unsigned char sym_type;
-+
-+      frag->offset_adjust += delta;
-+      state = next_state = &relax_state[frag->state];
-+      rela = frag->rela;
-+
-+      BFD_ASSERT(state->id == frag->state);
-+
-+      RDBG("  0x%04lx%c%d: %s [size %ld]", rela ? rela->r_offset : sec->rawsize,
-+         (frag->offset_adjust < 0)?'-':'+',
-+         abs(frag->offset_adjust), state->name, state->size);
-+
-+      if (!rela)
-+      {
-+        RDBG(": no reloc, ignoring\n");
-+        continue;
-+      }
-+
-+      BFD_ASSERT((unsigned int)(rela - relocs) < sec->reloc_count);
-+      BFD_ASSERT(state != RS_NONE);
-+
-+      r_offset = rela->r_offset + frag->offset_adjust;
-+      addr = sec->output_section->vma + sec->output_offset + r_offset;
-+
-+      switch (frag->state)
-+      {
-+      case RS_ALIGN:
-+        size_adjust = ((addr + (1 << rela->r_addend) - 1)
-+                       & ~((1 << rela->r_addend) - 1));
-+        size_adjust -= (sec->output_section->vma + sec->output_offset
-+                        + frag->offset + frag->offset_adjust
-+                        + frag->size + frag->size_adjust);
-+
-+        RDBG(": adjusting size %lu -> %lu\n", frag->size + frag->size_adjust,
-+             frag->size + frag->size_adjust + size_adjust);
-+        break;
-+
-+      case RS_CPENT:
-+        if (frag->refcount == 0 && frag->size_adjust == 0)
-+          {
-+            RDBG(": discarding frag\n");
-+            size_adjust = -4;
-+          }
-+        else if (frag->refcount > 0 && frag->size_adjust < 0)
-+          {
-+            RDBG(": un-discarding frag\n");
-+            size_adjust = 4;
-+          }
-+        break;
-+
-+      default:
-+        if (rd->reloc_data)
-+          r_data = &rd->reloc_data[frag->rela - relocs];
-+
-+        /* If this is a cpool reference, we want the symbol that the
-+           cpool entry refers to, not the symbol for the cpool entry
-+           itself, as we already know what frag it's in.  */
-+        if (relax_state[frag->initial_state].reftype == REF_CPOOL)
-+          {
-+            Elf_Internal_Rela *irela = r_data->add_frag->rela;
-+
-+            r_symndx = ELF_R_SYM(irela->r_info);
-+            addend = irela->r_addend;
-+
-+            /* The constant pool must be in the same section as the
-+               reloc referring to it.  */
-+            BFD_ASSERT((unsigned long)(irela - relocs) < sec->reloc_count);
-+
-+            ind_data = r_data;
-+            r_data = &rd->reloc_data[irela - relocs];
-+          }
-+        else
-+          {
-+            r_symndx = ELF_R_SYM(rela->r_info);
-+            addend = rela->r_addend;
-+          }
-+
-+        /* Get the value of the symbol referred to by the reloc.  */
-+        if (r_symndx < symtab_hdr->sh_info)
-+          {
-+            Elf_Internal_Sym *isym;
-+
-+            isym = isymbuf + r_symndx;
-+            symval = 0;
-+
-+            RDBG(" local sym %lu: ", r_symndx);
-+
-+            if (isym->st_shndx == SHN_UNDEF)
-+              defined = FALSE;
-+            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_type = ELF_ST_TYPE(isym->st_info);
-+            target_frag = local_sym_frag[r_symndx];
-+
-+            if (local_got_ents)
-+              got = local_got_ents[r_symndx];
-+            else
-+              got = NULL;
-+          }
-+        else
-+          {
-+            /* Global symbol */
-+            unsigned long index;
-+            struct elf_link_hash_entry *h;
-+            struct elf_avr32_link_hash_entry *havr;
-+
-+            index = r_symndx - symtab_hdr->sh_info;
-+            h = elf_sym_hashes(abfd)[index];
-+            BFD_ASSERT(h != NULL);
-+
-+            while (h->root.type == bfd_link_hash_indirect
-+                   || h->root.type == bfd_link_hash_warning)
-+              h = (struct elf_link_hash_entry *)h->root.u.i.link;
-+
-+            havr = (struct elf_avr32_link_hash_entry *)h;
-+            got = h->got.glist;
-+
-+            symval = 0;
-+
-+            RDBG(" %s: ", h->root.root.string);
-+
-+            if (h->root.type != bfd_link_hash_defined
-+                && h->root.type != bfd_link_hash_defweak)
-+              {
-+                RDBG("(undef)");
-+                defined = FALSE;
-+              }
-+            else if ((info->shared && !info->symbolic && h->dynindx != -1)
-+                     || (htab->root.dynamic_sections_created
-+                         && h->def_dynamic && !h->def_regular))
-+              {
-+                RDBG("(dynamic)");
-+                dynamic = TRUE;
-+                sym_sec = h->root.u.def.section;
-+              }
-+            else
-+              {
-+                sym_sec = h->root.u.def.section;
-+                symval = h->root.u.def.value;
-+                target_frag = havr->sym_frag;
-+              }
-+
-+            sym_type = h->type;
-+          }
-+
-+        /* Thanks to elf32-ppc for this one.  */
-+        if (sym_sec && sym_sec->sec_info_type == ELF_INFO_TYPE_MERGE)
-+          {
-+            /* At this stage in linking, no SEC_MERGE symbol has been
-+               adjusted, so all references to such symbols need to be
-+               passed through _bfd_merged_section_offset.  (Later, in
-+               relocate_section, all SEC_MERGE symbols *except* for
-+               section symbols have been adjusted.)
-+
-+               SEC_MERGE sections are not relaxed by us, as they
-+               shouldn't contain any code.  */
-+
-+            BFD_ASSERT(!target_frag && !(r_data && r_data->add_frag));
-+
-+            /* gas may reduce relocations against symbols in SEC_MERGE
-+               sections to a relocation against the section symbol when
-+               the original addend was zero.  When the reloc is against
-+               a section symbol we should include the addend in the
-+               offset passed to _bfd_merged_section_offset, since the
-+               location of interest is the original symbol.  On the
-+               other hand, an access to "sym+addend" where "sym" is not
-+               a section symbol should not include the addend;  Such an
-+               access is presumed to be an offset from "sym";  The
-+               location of interest is just "sym".  */
-+            RDBG("\n    MERGE: %s: 0x%lx+0x%lx+0x%lx -> ",
-+                 (sym_type == STT_SECTION)?"section":"not section",
-+                 sym_sec->output_section->vma + sym_sec->output_offset,
-+                 symval, addend);
-+
-+            if (sym_type == STT_SECTION)
-+              symval += addend;
-+
-+            symval = (_bfd_merged_section_offset
-+                      (abfd, &sym_sec,
-+                       elf_section_data(sym_sec)->sec_info, symval));
-+
-+            if (sym_type != STT_SECTION)
-+              symval += addend;
-+          }
-+        else
-+          symval += addend;
-+
-+        if (defined && !dynamic)
-+          {
-+            RDBG("0x%lx+0x%lx",
-+                 sym_sec->output_section->vma + sym_sec->output_offset,
-+                 symval);
-+            symval += sym_sec->output_section->vma + sym_sec->output_offset;
-+          }
-+
-+        if (r_data && r_data->add_frag)
-+          /* If the add_frag pointer is set, it means that this reloc
-+             has an addend that may be affected by relaxation.  */
-+          target_frag = r_data->add_frag;
-+
-+        if (target_frag)
-+          {
-+            symval += target_frag->offset_adjust;
-+
-+            /* If target_frag comes after this frag in the same
-+               section, we should assume that it will be moved by
-+               the same amount we are.  */
-+            if ((target_frag - rd->frag) < (int)rd->frag_count
-+                && target_frag > frag)
-+              symval += delta;
-+          }
-+
-+        distance = symval - addr;
-+
-+        /* First, try to make a direct reference.  If the symbol is
-+           dynamic or undefined, we must take care not to change its
-+           reference type, that is, we can't make it direct.
-+
-+           Also, it seems like some sections may actually be resized
-+           after the relaxation code is done, so we can't really
-+           trust that our "distance" is correct.  There's really no
-+           easy solution to this problem, so we'll just disallow
-+           direct references to SEC_DATA sections.
-+
-+           Oh, and .bss isn't actually SEC_DATA, so we disallow
-+           !SEC_HAS_CONTENTS as well. */
-+        if (!dynamic && defined
-+            && (htab->direct_data_refs
-+                || (!(sym_sec->flags & SEC_DATA)
-+                    && (sym_sec->flags & SEC_HAS_CONTENTS)))
-+            && next_state->direct)
-+          {
-+            next_state = &relax_state[next_state->direct];
-+            RDBG(" D-> %s", next_state->name);
-+          }
-+
-+        /* Iterate backwards until we find a state that fits.  */
-+        while (next_state->prev
-+               && !rs_is_good_enough(next_state, frag, symval, addr,
-+                                     got, ind_data, delta))
-+          {
-+            next_state = &relax_state[next_state->prev];
-+            RDBG(" P-> %s", next_state->name);
-+          }
-+
-+        /* Then try to find the best possible state.  */
-+        while (next_state->next)
-+          {
-+            const struct relax_state *candidate;
-+
-+            candidate = &relax_state[next_state->next];
-+            if (!rs_is_good_enough(candidate, frag, symval, addr, got,
-+                                   ind_data, delta))
-+              break;
-+
-+            next_state = candidate;
-+            RDBG(" N-> %s", next_state->name);
-+          }
-+
-+        RDBG(" [size %ld]\n", next_state->size);
-+
-+        BFD_ASSERT(next_state->id);
-+        BFD_ASSERT(!dynamic || next_state->reftype == REF_GOT);
-+
-+        size_adjust = next_state->size - state->size;
-+
-+        /* There's a theoretical possibility that shrinking one frag
-+           may cause another to grow, which may cause the first one to
-+           grow as well, and we're back where we started.  Avoid this
-+           scenario by disallowing a frag that has grown to ever
-+           shrink again.  */
-+        if (state->reftype == REF_GOT && next_state->reftype != REF_GOT)
-+          {
-+            if (frag->has_grown)
-+              next_state = state;
-+            else
-+              unref_got_entry(htab, got);
-+          }
-+        else if (state->reftype != REF_GOT && next_state->reftype == REF_GOT)
-+          {
-+            ref_got_entry(htab, got);
-+            frag->has_grown = TRUE;
-+          }
-+        else if (state->reftype == REF_CPOOL
-+                 && next_state->reftype != REF_CPOOL)
-+          {
-+            if (frag->has_grown)
-+              next_state = state;
-+            else
-+              ind_data->add_frag->refcount--;
-+          }
-+        else if (state->reftype != REF_CPOOL
-+                 && next_state->reftype == REF_CPOOL)
-+          {
-+            ind_data->add_frag->refcount++;
-+            frag->has_grown = TRUE;
-+          }
-+        else
-+          {
-+            if (frag->has_grown && size_adjust < 0)
-+              next_state = state;
-+            else if (size_adjust > 0)
-+              frag->has_grown = TRUE;
-+          }
-+
-+        size_adjust = next_state->size - state->size;
-+        frag->state = next_state->id;
-+
-+        break;
-+      }
-+
-+      if (size_adjust)
-+      htab->repeat_pass = TRUE;
-+
-+      frag->size_adjust += size_adjust;
-+      sec->size += size_adjust;
-+      delta += size_adjust;
-+
-+      BFD_ASSERT((frag->offset + frag->offset_adjust
-+                + frag->size + frag->size_adjust)
-+               == (frag[1].offset + frag[1].offset_adjust + delta));
-+    }
-+
-+  ret = TRUE;
-+
-+ out:
-+  release_local_syms(abfd, isymbuf);
-+  release_internal_relocs(sec, relocs);
-+  return ret;
-+}
-+
-+static bfd_boolean
-+adjust_global_symbol(struct elf_avr32_link_hash_entry *havr,
-+                   struct bfd_link_info *info ATTRIBUTE_UNUSED)
-+{
-+  struct elf_link_hash_entry *h = &havr->root;
-+
-+  if (havr->sym_frag && (h->root.type == bfd_link_hash_defined
-+                       || h->root.type == bfd_link_hash_defweak))
-+    {
-+      RDBG("adjust_global_symbol: %s 0x%08lx -> 0x%08lx\n",
-+         h->root.root.string, h->root.u.def.value,
-+         h->root.u.def.value + havr->sym_frag->offset_adjust);
-+      h->root.u.def.value += havr->sym_frag->offset_adjust;
-+    }
-+  return TRUE;
-+}
-+
-+static bfd_boolean
-+adjust_syms(struct bfd_link_info *info)
-+{
-+  struct elf_avr32_link_hash_table *htab;
-+  bfd *abfd;
-+
-+  htab = avr32_elf_hash_table(info);
-+  elf_link_hash_traverse(&htab->root, adjust_global_symbol, info);
-+
-+  for (abfd = info->input_bfds; abfd; abfd = abfd->link_next)
-+    {
-+      Elf_Internal_Sym *isymbuf;
-+      struct fragment **local_sym_frag, *frag;
-+      unsigned int i, sym_count;
-+
-+      sym_count = elf_tdata(abfd)->symtab_hdr.sh_info;
-+      if (sym_count == 0)
-+      continue;
-+
-+      isymbuf = retrieve_local_syms(abfd, info->keep_memory);
-+      if (!isymbuf)
-+      return FALSE;
-+
-+      local_sym_frag = elf_tdata(abfd)->local_sym_frag;
-+
-+      for (i = 0; i < sym_count; i++)
-+      {
-+        frag = local_sym_frag[i];
-+        if (frag)
-+          {
-+            RDBG("adjust_local_symbol: %s[%u] 0x%08lx -> 0x%08lx\n",
-+                 abfd->filename, i, isymbuf[i].st_value,
-+                 isymbuf[i].st_value + frag->offset_adjust);
-+            isymbuf[i].st_value += frag->offset_adjust;
-+          }
-+      }
-+
-+      release_local_syms(abfd, isymbuf);
-+    }
-+
-+  htab->symbols_adjusted = TRUE;
-+  return TRUE;
-+}
-+
-+static bfd_boolean
-+adjust_relocs(bfd *abfd, asection *sec, struct bfd_link_info *info)
-+{
-+  struct avr32_relax_data *rd;
-+  Elf_Internal_Rela *relocs;
-+  Elf_Internal_Shdr *symtab_hdr;
-+  unsigned int i;
-+  bfd_boolean ret = FALSE;
-+
-+  rd = avr32_relax_data(sec);
-+  if (!rd->reloc_data)
-+    return TRUE;
-+
-+  RDBG("adjust_relocs: %s<%s> (count: %u)\n", abfd->filename, sec->name,
-+       sec->reloc_count);
-+
-+  relocs = retrieve_internal_relocs(abfd, sec, info->keep_memory);
-+  if (!relocs)
-+    return FALSE;
-+
-+  symtab_hdr = &elf_tdata(abfd)->symtab_hdr;
-+
-+  for (i = 0; i < sec->reloc_count; i++)
-+    {
-+      Elf_Internal_Rela *rela = &relocs[i];
-+      struct avr32_reloc_data *r_data = &rd->reloc_data[i];
-+      struct fragment *sym_frag;
-+      unsigned long r_symndx;
-+
-+      if (r_data->add_frag)
-+      {
-+        r_symndx = ELF_R_SYM(rela->r_info);
-+
-+        if (r_symndx < symtab_hdr->sh_info)
-+          sym_frag = elf_tdata(abfd)->local_sym_frag[r_symndx];
-+        else
-+          {
-+            struct elf_link_hash_entry *h;
-+
-+            h = elf_sym_hashes(abfd)[r_symndx - symtab_hdr->sh_info];
-+
-+            while (h->root.type == bfd_link_hash_indirect
-+                   || h->root.type == bfd_link_hash_warning)
-+              h = (struct elf_link_hash_entry *)h->root.u.i.link;
-+
-+            BFD_ASSERT(h->root.type == bfd_link_hash_defined
-+                       || h->root.type == bfd_link_hash_defweak);
-+
-+            sym_frag = ((struct elf_avr32_link_hash_entry *)h)->sym_frag;
-+          }
-+
-+        RDBG("    addend: 0x%08lx -> 0x%08lx\n",
-+             rela->r_addend,
-+             rela->r_addend + r_data->add_frag->offset_adjust
-+             - (sym_frag ? sym_frag->offset_adjust : 0));
-+
-+        /* If this is against a section symbol, we won't find any
-+           sym_frag, so we'll just adjust the addend.  */
-+        rela->r_addend += r_data->add_frag->offset_adjust;
-+        if (sym_frag)
-+          rela->r_addend -= sym_frag->offset_adjust;
-+
-+        if (r_data->sub_frag)
-+          {
-+            bfd_byte *contents;
-+            bfd_signed_vma diff;
-+
-+            contents = retrieve_contents(abfd, sec, info->keep_memory);
-+            if (!contents)
-+              goto out;
-+
-+            /* I realize now that sub_frag is misnamed.  It's
-+               actually add_frag which is subtracted in this
-+               case...  */
-+            diff = bfd_get_signed_32(abfd, contents + rela->r_offset);
-+            diff += (r_data->sub_frag->offset_adjust
-+                     - r_data->add_frag->offset_adjust);
-+            bfd_put_32(abfd, diff, contents + rela->r_offset);
-+
-+            RDBG("   0x%lx: DIFF32 updated: 0x%lx\n", rela->r_offset, diff);
-+
-+            release_contents(sec, contents);
-+          }
-+      }
-+      else
-+      BFD_ASSERT(!r_data->sub_frag);
-+    }
-+
-+  ret = TRUE;
-+
-+ out:
-+  release_internal_relocs(sec, relocs);
-+  return ret;
-+}
-+
-+static bfd_boolean
-+avr32_move_data(bfd *abfd, asection *sec, struct bfd_link_info *info)
-+{
-+  struct elf_avr32_link_hash_table *htab;
-+  struct avr32_relax_data *rd;
-+  struct fragment *frag, *fragend;
-+  Elf_Internal_Rela *relocs = NULL;
-+  bfd_byte *contents = NULL;
-+  unsigned int i;
-+  bfd_boolean ret = FALSE;
-+
-+  htab = avr32_elf_hash_table(info);
-+  rd = avr32_relax_data(sec);
-+
-+  if (!htab->symbols_adjusted)
-+    if (!adjust_syms(info))
-+      return FALSE;
-+
-+  if (rd->is_relaxable)
-+    {
-+      /* Resize the section first, so that we can be sure that enough
-+       memory is allocated in case the section has grown.  */
-+      if (sec->size > sec->rawsize
-+        && elf_section_data(sec)->this_hdr.contents)
-+      {
-+        /* We must not use cached data if the section has grown.  */
-+        free(elf_section_data(sec)->this_hdr.contents);
-+        elf_section_data(sec)->this_hdr.contents = NULL;
-+      }
-+
-+      relocs = retrieve_internal_relocs(abfd, sec, info->keep_memory);
-+      if (!relocs)
-+      goto out;
-+      contents = retrieve_contents(abfd, sec, info->keep_memory);
-+      if (!contents)
-+      goto out;
-+
-+      fragend = rd->frag + rd->frag_count;
-+
-+      RDBG("move_data: %s<%s>: relocs=%p, contents=%p\n",
-+         abfd->filename, sec->name, relocs, contents);
-+
-+      /* First, move the data into place. We must take care to move
-+       frags in the right order so that we don't accidentally
-+       overwrite parts of the next frag.  */
-+      for (frag = rd->frag; frag < fragend; frag++)
-+      {
-+        RDBG("    0x%08lx%c0x%x: size 0x%lx%c0x%x\n",
-+             frag->offset, frag->offset_adjust >= 0 ? '+' : '-',
-+             abs(frag->offset_adjust),
-+             frag->size, frag->size_adjust >= 0 ? '+' : '-',
-+             abs(frag->size_adjust));
-+        if (frag->offset_adjust > 0)
-+          {
-+            struct fragment *prev = frag - 1;
-+            struct fragment *last;
-+
-+            for (last = frag; last < fragend && last->offset_adjust > 0;
-+                 last++) ;
-+
-+            if (last == fragend)
-+              last--;
-+
-+            for (frag = last; frag != prev; frag--)
-+              {
-+                if (frag->offset_adjust
-+                    && frag->size + frag->size_adjust > 0)
-+                  {
-+                    RDBG("memmove 0x%lx -> 0x%lx (size %lu)\n",
-+                         frag->offset, frag->offset + frag->offset_adjust,
-+                         frag->size + frag->size_adjust);
-+                    memmove(contents + frag->offset + frag->offset_adjust,
-+                            contents + frag->offset,
-+                            frag->size + frag->size_adjust);
-+                  }
-+              }
-+            frag = last;
-+          }
-+        else if (frag->offset_adjust && frag->size + frag->size_adjust > 0)
-+          {
-+            RDBG("memmove 0x%lx -> 0x%lx (size %lu)\n",
-+                 frag->offset, frag->offset + frag->offset_adjust,
-+                 frag->size + frag->size_adjust);
-+            memmove(contents + frag->offset + frag->offset_adjust,
-+                    contents + frag->offset,
-+                    frag->size + frag->size_adjust);
-+          }
-+      }
-+
-+      i = 0;
-+
-+      for (frag = rd->frag; frag < fragend; frag++)
-+      {
-+        const struct relax_state *state, *istate;
-+        struct avr32_reloc_data *r_data = NULL;
-+
-+        istate = &relax_state[frag->initial_state];
-+        state = &relax_state[frag->state];
-+
-+        if (rd->reloc_data)
-+          r_data = &rd->reloc_data[frag->rela - relocs];
-+
-+        BFD_ASSERT((long)(frag->size + frag->size_adjust) >= 0);
-+        BFD_ASSERT(state->reftype != REF_CPOOL
-+                   || r_data->add_frag->refcount > 0);
-+
-+        if (istate->reftype == REF_CPOOL && state->reftype != REF_CPOOL)
-+          {
-+            struct fragment *ifrag;
-+
-+            /* An indirect reference through the cpool has been
-+               converted to a direct reference.  We must update the
-+               reloc to point to the symbol itself instead of the
-+               constant pool entry.  The reloc type will be updated
-+               later.  */
-+            ifrag = r_data->add_frag;
-+            frag->rela->r_info = ifrag->rela->r_info;
-+            frag->rela->r_addend = ifrag->rela->r_addend;
-+
-+            /* Copy the reloc data so the addend will be adjusted
-+               correctly later.  */
-+            *r_data = rd->reloc_data[ifrag->rela - relocs];
-+          }
-+
-+        /* Move all relocs covered by this frag.  */
-+        if (frag->rela)
-+          BFD_ASSERT(&relocs[i] <= frag->rela);
-+        else
-+          BFD_ASSERT((frag + 1) == fragend && frag->state == RS_NONE);
-+
-+        if (frag == rd->frag)
-+          BFD_ASSERT(i == 0);
-+        else
-+          BFD_ASSERT(&relocs[i] > frag[-1].rela);
-+
-+        /* If non-null, frag->rela is the last relocation in the
-+           fragment.  frag->rela can only be null in the last
-+           fragment, so in that case, we'll just do the rest.  */
-+        for (; (i < sec->reloc_count
-+                && (!frag->rela || &relocs[i] <= frag->rela)); i++)
-+          {
-+            RDBG("[%4u] r_offset 0x%08lx -> 0x%08lx\n", i, relocs[i].r_offset,
-+                 relocs[i].r_offset + frag->offset_adjust);
-+            relocs[i].r_offset += frag->offset_adjust;
-+          }
-+
-+        if (frag->refcount == 0)
-+          {
-+            /* If this frag is to be discarded, make sure we won't
-+               relocate it later on.  */
-+            BFD_ASSERT(frag->state == RS_CPENT);
-+            frag->rela->r_info = ELF_R_INFO(ELF_R_SYM(frag->rela->r_info),
-+                                          R_AVR32_NONE);
-+          }
-+        else if (frag->state == RS_ALIGN)
-+          {
-+            bfd_vma addr, addr_end;
-+
-+            addr = frag->rela->r_offset;
-+            addr_end = (frag->offset + frag->offset_adjust
-+                        + frag->size + frag->size_adjust);
-+
-+            /* If the section is executable, insert NOPs.
-+               Otherwise, insert zeroes.  */
-+            if (sec->flags & SEC_CODE)
-+              {
-+                if (addr & 1)
-+                  {
-+                    bfd_put_8(abfd, 0, contents + addr);
-+                    addr++;
-+                  }
-+
-+                BFD_ASSERT(!((addr_end - addr) & 1));
-+
-+                while (addr < addr_end)
-+                  {
-+                    bfd_put_16(abfd, NOP_OPCODE, contents + addr);
-+                    addr += 2;
-+                  }
-+              }
-+            else
-+              memset(contents + addr, 0, addr_end - addr);
-+          }
-+        else if (state->opcode_mask)
-+          {
-+            bfd_vma insn;
-+
-+            /* Update the opcode and the relocation type unless it's a
-+               "special" relax state (i.e. RS_NONE, RS_ALIGN or
-+               RS_CPENT.), in which case the opcode mask is zero.  */
-+            insn = bfd_get_32(abfd, contents + frag->rela->r_offset);
-+            insn &= ~state->opcode_mask;
-+            insn |= state->opcode;
-+            RDBG("    0x%lx: inserting insn %08lx\n",
-+                 frag->rela->r_offset, insn);
-+            bfd_put_32(abfd, insn, contents + frag->rela->r_offset);
-+
-+            frag->rela->r_info = ELF_R_INFO(ELF_R_SYM(frag->rela->r_info),
-+                                            state->r_type);
-+          }
-+
-+        if ((frag + 1) == fragend)
-+          BFD_ASSERT((frag->offset + frag->size + frag->offset_adjust
-+                      + frag->size_adjust) == sec->size);
-+        else
-+          BFD_ASSERT((frag->offset + frag->size + frag->offset_adjust
-+                      + frag->size_adjust)
-+                     == (frag[1].offset + frag[1].offset_adjust));
-+      }
-+    }
-+
-+  /* Adjust reloc addends and DIFF32 differences */
-+  if (!adjust_relocs(abfd, sec, info))
-+    return FALSE;
-+
-+  ret = TRUE;
-+
-+ out:
-+  release_contents(sec, contents);
-+  release_internal_relocs(sec, relocs);
-+  return ret;
-+}
-+
-+static bfd_boolean
-+avr32_elf_relax_section(bfd *abfd, asection *sec,
-+                      struct bfd_link_info *info, bfd_boolean *again)
-+{
-+  struct elf_avr32_link_hash_table *htab;
-+  struct avr32_relax_data *rd;
-+
-+  *again = FALSE;
-+  if (info->relocatable)
-+    return TRUE;
-+
-+  htab = avr32_elf_hash_table(info);
-+  if ((!(sec->flags & SEC_RELOC) || sec->reloc_count == 0)
-+      && sec != htab->sgot)
-+    return TRUE;
-+
-+  if (!htab->relocations_analyzed)
-+    {
-+      if (!analyze_relocations(info))
-+      return FALSE;
-+      htab->relocations_analyzed = TRUE;
-+    }
-+
-+  rd = avr32_relax_data(sec);
-+
-+  if (rd->iteration != htab->relax_iteration)
-+    {
-+      if (!htab->repeat_pass)
-+      htab->relax_pass++;
-+      htab->relax_iteration++;
-+      htab->repeat_pass = FALSE;
-+    }
-+
-+  rd->iteration++;
-+
-+  switch (htab->relax_pass)
-+    {
-+    case RELAX_PASS_SIZE_FRAGS:
-+      if (!avr32_size_frags(abfd, sec, info))
-+      return FALSE;
-+      *again = TRUE;
-+      break;
-+    case RELAX_PASS_MOVE_DATA:
-+      if (!avr32_move_data(abfd, sec, info))
-+      return FALSE;
-+      break;
-+  }
-+
-+  return TRUE;
-+}
-+
-+
-+/* Relocation */
-+
-+static bfd_reloc_status_type
-+avr32_check_reloc_value(asection *sec, Elf_Internal_Rela *rela,
-+                      bfd_signed_vma relocation, reloc_howto_type *howto);
-+static bfd_reloc_status_type
-+avr32_final_link_relocate(reloc_howto_type *howto, bfd *input_bfd,
-+                        asection *input_section, bfd_byte *contents,
-+                        Elf_Internal_Rela *rel, bfd_vma value);
-+static bfd_boolean
-+avr32_elf_relocate_section(bfd *output_bfd, struct bfd_link_info *info,
-+                         bfd *input_bfd, asection *input_section,
-+                         bfd_byte *contents, Elf_Internal_Rela *relocs,
-+                         Elf_Internal_Sym *local_syms,
-+                         asection **local_sections);
-+
-+
-+#define symbol_address(symbol) \
-+  symbol->value + symbol->section->output_section->vma \
-+  + symbol->section->output_offset
-+
-+#define avr32_elf_insert_field(size, field, abfd, reloc_entry, data)  \
-+  do                                                                  \
-+    {                                                                 \
-+      unsigned long x;                                                        \
-+      x = bfd_get_##size (abfd, data + reloc_entry->address);         \
-+      x &= ~reloc_entry->howto->dst_mask;                             \
-+      x |= field & reloc_entry->howto->dst_mask;                      \
-+      bfd_put_##size (abfd, (bfd_vma) x, data + reloc_entry->address);        \
-+    }                                                                 \
-+  while(0)
-+
-+static bfd_reloc_status_type
-+avr32_check_reloc_value(asection *sec ATTRIBUTE_UNUSED,
-+                      Elf_Internal_Rela *rela ATTRIBUTE_UNUSED,
-+                      bfd_signed_vma relocation,
-+                      reloc_howto_type *howto)
-+{
-+  bfd_vma reloc_u;
-+
-+  /* We take "complain_overflow_dont" to mean "don't complain on
-+     alignment either". This way, we don't have to special-case
-+     R_AVR32_HI16 */
-+  if (howto->complain_on_overflow == complain_overflow_dont)
-+    return bfd_reloc_ok;
-+
-+  /* Check if the value is correctly aligned */
-+  if (relocation & ((1 << howto->rightshift) - 1))
-+    {
-+      RDBG("misaligned: %s<%s+%lx>: %s: 0x%lx (align %u)\n",
-+         sec->owner->filename, sec->name, rela->r_offset,
-+         howto->name, relocation, howto->rightshift);
-+      return bfd_reloc_overflow;
-+    }
-+
-+  /* Now, get rid of the unnecessary bits */
-+  relocation >>= howto->rightshift;
-+  reloc_u = (bfd_vma)relocation;
-+
-+  switch (howto->complain_on_overflow)
-+    {
-+    case complain_overflow_unsigned:
-+    case complain_overflow_bitfield:
-+      if (reloc_u > (unsigned long)((1 << howto->bitsize) - 1))
-+      {
-+        RDBG("unsigned overflow: %s<%s+%lx>: %s: 0x%lx (size %u)\n",
-+             sec->owner->filename, sec->name, rela->r_offset,
-+             howto->name, reloc_u, howto->bitsize);
-+        RDBG("reloc vma: 0x%lx\n",
-+             sec->output_section->vma + sec->output_offset + rela->r_offset);
-+
-+        return bfd_reloc_overflow;
-+      }
-+      break;
-+    case complain_overflow_signed:
-+      if (relocation > (1 << (howto->bitsize - 1)) - 1)
-+      {
-+        RDBG("signed overflow: %s<%s+%lx>: %s: 0x%lx (size %u)\n",
-+             sec->owner->filename, sec->name, rela->r_offset,
-+             howto->name, reloc_u, howto->bitsize);
-+        RDBG("reloc vma: 0x%lx\n",
-+             sec->output_section->vma + sec->output_offset + rela->r_offset);
-+
-+        return bfd_reloc_overflow;
-+      }
-+      if (relocation < -(1 << (howto->bitsize - 1)))
-+      {
-+        RDBG("signed overflow: %s<%s+%lx>: %s: -0x%lx (size %u)\n",
-+             sec->owner->filename, sec->name, rela->r_offset,
-+             howto->name, -relocation, howto->bitsize);
-+        RDBG("reloc vma: 0x%lx\n",
-+             sec->output_section->vma + sec->output_offset + rela->r_offset);
-+
-+        return bfd_reloc_overflow;
-+      }
-+      break;
-+    default:
-+      abort();
-+    }
-+
-+  return bfd_reloc_ok;
-+}
-+
-+
-+static bfd_reloc_status_type
-+avr32_final_link_relocate(reloc_howto_type *howto,
-+                        bfd *input_bfd,
-+                        asection *input_section,
-+                        bfd_byte *contents,
-+                        Elf_Internal_Rela *rel,
-+                        bfd_vma value)
-+{
-+  bfd_vma field;
-+  bfd_vma relocation;
-+  bfd_reloc_status_type status;
-+  bfd_byte *p = contents + rel->r_offset;
-+  unsigned long x;
-+
-+  pr_debug("  (6b) final link relocate\n");
-+
-+  /* Sanity check the address */
-+  if (rel->r_offset > input_section->size)
-+    {
-+      (*_bfd_error_handler)
-+      ("%B: %A+0x%lx: offset out of range (section size: 0x%lx)",
-+       input_bfd, input_section, rel->r_offset, input_section->size);
-+      return bfd_reloc_outofrange;
-+    }
-+
-+  relocation = value + rel->r_addend;
-+
-+  if (howto->pc_relative)
-+    {
-+      bfd_vma addr;
-+
-+      addr = input_section->output_section->vma
-+      + input_section->output_offset + rel->r_offset;
-+      addr &= ~0UL << howto->rightshift;
-+      relocation -= addr;
-+    }
-+
-+  switch (ELF32_R_TYPE(rel->r_info))
-+    {
-+    case R_AVR32_16N_PCREL:
-+      /* sub reg, pc, . - (sym + addend) */
-+      relocation = -relocation;
-+      break;
-+    }
-+
-+  status = avr32_check_reloc_value(input_section, rel, relocation, howto);
-+
-+  relocation >>= howto->rightshift;
-+  if (howto->bitsize == 21)
-+    field = (relocation & 0xffff)
-+      | ((relocation & 0x10000) << 4)
-+      | ((relocation & 0x1e0000) << 8);
-+  else if (howto->bitsize == 12)
-+    field = (relocation & 0xff) | ((relocation & 0xf00) << 4);
-+  else if (howto->bitsize == 10)
-+    field = ((relocation & 0xff) << 4)
-+      | ((relocation & 0x300) >> 8);
-+  else
-+    field = relocation << howto->bitpos;
-+
-+  switch (howto->size)
-+    {
-+    case 0:
-+      x = bfd_get_8 (input_bfd, p);
-+      x &= ~howto->dst_mask;
-+      x |= field & howto->dst_mask;
-+      bfd_put_8 (input_bfd, (bfd_vma) x, p);
-+      break;
-+    case 1:
-+      x = bfd_get_16 (input_bfd, p);
-+      x &= ~howto->dst_mask;
-+      x |= field & howto->dst_mask;
-+      bfd_put_16 (input_bfd, (bfd_vma) x, p);
-+      break;
-+    case 2:
-+      x = bfd_get_32 (input_bfd, p);
-+      x &= ~howto->dst_mask;
-+      x |= field & howto->dst_mask;
-+      bfd_put_32 (input_bfd, (bfd_vma) x, p);
-+      break;
-+    default:
-+      abort();
-+    }
-+
-+  return status;
-+}
-+
-+/* (6) Apply relocations to the normal (non-dynamic) sections */
-+
-+static bfd_boolean
-+avr32_elf_relocate_section(bfd *output_bfd, struct bfd_link_info *info,
-+                         bfd *input_bfd, asection *input_section,
-+                         bfd_byte *contents, Elf_Internal_Rela *relocs,
-+                         Elf_Internal_Sym *local_syms,
-+                         asection **local_sections)
-+{
-+  struct elf_avr32_link_hash_table *htab;
-+  Elf_Internal_Shdr *symtab_hdr;
-+  Elf_Internal_Rela *rel, *relend;
-+  struct elf_link_hash_entry **sym_hashes;
-+  struct got_entry **local_got_ents;
-+  asection *sgot;
-+  asection *srelgot;
-+
-+  pr_debug("(6) relocate section %s:<%s> (size 0x%lx)\n",
-+         input_bfd->filename, input_section->name, input_section->size);
-+
-+  /* If we're doing a partial link, we don't have to do anything since
-+     we're using RELA relocations */
-+  if (info->relocatable)
-+    return TRUE;
-+
-+  htab = avr32_elf_hash_table(info);
-+  symtab_hdr = &elf_tdata(input_bfd)->symtab_hdr;
-+  sym_hashes = elf_sym_hashes(input_bfd);
-+  local_got_ents = elf_local_got_ents(input_bfd);
-+  sgot = htab->sgot;
-+  srelgot = htab->srelgot;
-+
-+  relend = relocs + input_section->reloc_count;
-+  for (rel = relocs; rel < relend; rel++)
-+    {
-+      unsigned long r_type, r_symndx;
-+      reloc_howto_type *howto;
-+      Elf_Internal_Sym *sym = NULL;
-+      struct elf_link_hash_entry *h = NULL;
-+      asection *sec = NULL;
-+      bfd_vma value;
-+      bfd_vma offset;
-+      bfd_reloc_status_type status;
-+
-+      r_type = ELF32_R_TYPE(rel->r_info);
-+      r_symndx = ELF32_R_SYM(rel->r_info);
-+
-+      if (r_type == R_AVR32_NONE
-+        || r_type == R_AVR32_ALIGN
-+        || r_type == R_AVR32_DIFF32
-+        || r_type == R_AVR32_DIFF16
-+        || r_type == R_AVR32_DIFF8)
-+      continue;
-+
-+      /* Sanity check */
-+      if (r_type > R_AVR32_max)
-+      {
-+        bfd_set_error(bfd_error_bad_value);
-+        return FALSE;
-+      }
-+
-+      howto = &elf_avr32_howto_table[r_type];
-+
-+      if (r_symndx < symtab_hdr->sh_info)
-+      {
-+        sym = local_syms + r_symndx;
-+        sec = local_sections[r_symndx];
-+
-+        pr_debug("  (6a) processing %s against local symbol %lu\n",
-+                 howto->name, r_symndx);
-+
-+        /* The following function changes rel->r_addend behind our back. */
-+        value = _bfd_elf_rela_local_sym(output_bfd, sym, &sec, rel);
-+        pr_debug("    => value: %lx, addend: %lx\n", value, rel->r_addend);
-+      }
-+      else
-+      {
-+        if (sym_hashes == NULL)
-+          return FALSE;
-+
-+        h = sym_hashes[r_symndx - symtab_hdr->sh_info];
-+        while (h->root.type == bfd_link_hash_indirect
-+               || h->root.type == bfd_link_hash_warning)
-+          h = (struct elf_link_hash_entry *)h->root.u.i.link;
-+
-+        pr_debug("  (6a) processing %s against symbol %s\n",
-+                 howto->name, h->root.root.string);
-+
-+        if (h->root.type == bfd_link_hash_defined
-+            || h->root.type == bfd_link_hash_defweak)
-+          {
-+            bfd_boolean dyn;
-+
-+            dyn = htab->root.dynamic_sections_created;
-+            sec = h->root.u.def.section;
-+
-+            if (sec->output_section)
-+              value = (h->root.u.def.value
-+                       + sec->output_section->vma
-+                       + sec->output_offset);
-+            else
-+              value = h->root.u.def.value;
-+          }
-+        else if (h->root.type == bfd_link_hash_undefweak)
-+          value = 0;
-+        else if (info->unresolved_syms_in_objects == RM_IGNORE
-+                 && ELF_ST_VISIBILITY(h->other) == STV_DEFAULT)
-+          value = 0;
-+        else
-+          {
-+            bfd_boolean err;
-+            err = (info->unresolved_syms_in_objects == RM_GENERATE_ERROR
-+                   || ELF_ST_VISIBILITY(h->other) != STV_DEFAULT);
-+            if (!info->callbacks->undefined_symbol
-+                (info, h->root.root.string, input_bfd,
-+                 input_section, rel->r_offset, err))
-+              return FALSE;
-+            value = 0;
-+          }
-+
-+        pr_debug("    => value: %lx, addend: %lx\n", value, rel->r_addend);
-+      }
-+
-+      switch (r_type)
-+      {
-+      case R_AVR32_GOT32:
-+      case R_AVR32_GOT16:
-+      case R_AVR32_GOT8:
-+      case R_AVR32_GOT21S:
-+      case R_AVR32_GOT18SW:
-+      case R_AVR32_GOT16S:
-+      case R_AVR32_GOT7UW:
-+      case R_AVR32_LDA_GOT:
-+      case R_AVR32_GOTCALL:
-+        BFD_ASSERT(sgot != NULL);
-+
-+        if (h != NULL)
-+          {
-+            BFD_ASSERT(h->got.glist->refcount > 0);
-+            offset = h->got.glist->offset;
-+
-+            BFD_ASSERT(offset < sgot->size);
-+            if (!elf_hash_table(info)->dynamic_sections_created
-+                || (h->def_regular
-+                    && (!info->shared
-+                        || info->symbolic
-+                        || h->dynindx == -1)))
-+              {
-+                /* This is actually a static link, or it is a
-+                   -Bsymbolic link and the symbol is defined
-+                   locally, or the symbol was forced to be local.  */
-+                bfd_put_32(output_bfd, value, sgot->contents + offset);
-+              }
-+          }
-+        else
-+          {
-+            BFD_ASSERT(local_got_ents &&
-+                       local_got_ents[r_symndx]->refcount > 0);
-+            offset = local_got_ents[r_symndx]->offset;
-+
-+            /* Local GOT entries don't have relocs.  If this is a
-+               shared library, the dynamic linker will add the load
-+               address to the initial value at startup.  */
-+            BFD_ASSERT(offset < sgot->size);
-+            pr_debug("Initializing GOT entry at offset %lu: 0x%lx\n",
-+                     offset, value);
-+            bfd_put_32 (output_bfd, value, sgot->contents + offset);
-+          }
-+
-+        value = sgot->output_offset + offset;
-+        pr_debug("GOT reference: New value %lx\n", value);
-+        break;
-+
-+      case R_AVR32_GOTPC:
-+        /* This relocation type is for constant pool entries used in
-+           the calculation "Rd = PC - (PC - GOT)", where the
-+           constant pool supplies the constant (PC - GOT)
-+           offset. The symbol value + addend indicates where the
-+           value of PC is taken. */
-+        value -= sgot->output_section->vma;
-+        break;
-+
-+      case R_AVR32_32_PCREL:
-+        /* We must adjust r_offset to account for discarded data in
-+           the .eh_frame section.  This is probably not the right
-+           way to do this, since AFAICS all other architectures do
-+           it some other way.  I just can't figure out how...  */
-+        {
-+          bfd_vma r_offset;
-+
-+          r_offset = _bfd_elf_section_offset(output_bfd, info,
-+                                             input_section,
-+                                             rel->r_offset);
-+          if (r_offset == (bfd_vma)-1
-+              || r_offset == (bfd_vma)-2)
-+            continue;
-+          rel->r_offset = r_offset;
-+        }
-+        break;
-+
-+      case R_AVR32_32:
-+        /* We need to emit a run-time relocation in the following cases:
-+             - we're creating a shared library
-+             - the symbol is not defined in any regular objects
-+
-+           Of course, sections that aren't going to be part of the
-+           run-time image will not get any relocs, and undefined
-+           symbols won't have any either (only weak undefined
-+           symbols should get this far).  */
-+        if ((info->shared
-+             || (elf_hash_table(info)->dynamic_sections_created
-+                 && h != NULL
-+                 && h->def_dynamic
-+                 && !h->def_regular))
-+            && r_symndx != 0
-+            && (input_section->flags & SEC_ALLOC))
-+          {
-+            Elf_Internal_Rela outrel;
-+            bfd_byte *loc;
-+            bfd_boolean skip, relocate;
-+            struct elf_avr32_link_hash_entry *avrh;
-+
-+            pr_debug("Going to generate dynamic reloc...\n");
-+
-+            skip = FALSE;
-+            relocate = FALSE;
-+
-+            outrel.r_offset = _bfd_elf_section_offset(output_bfd, info,
-+                                                      input_section,
-+                                                      rel->r_offset);
-+            if (outrel.r_offset == (bfd_vma)-1)
-+              skip = TRUE;
-+            else if (outrel.r_offset == (bfd_vma)-2)
-+              skip = TRUE, relocate = TRUE;
-+
-+            outrel.r_offset += (input_section->output_section->vma
-+                                + input_section->output_offset);
-+
-+            pr_debug("    ... offset %lx, dynindx %ld\n",
-+                     outrel.r_offset, h ? h->dynindx : -1);
-+
-+            if (skip)
-+              memset(&outrel, 0, sizeof(outrel));
-+            else
-+              {
-+                avrh = (struct elf_avr32_link_hash_entry *)h;
-+                /* h->dynindx may be -1 if this symbol was marked to
-+                   become local.  */
-+                if (h == NULL
-+                    || ((info->symbolic || h->dynindx == -1)
-+                        && h->def_regular))
-+                  {
-+                    relocate = TRUE;
-+                    outrel.r_info = ELF32_R_INFO(0, R_AVR32_RELATIVE);
-+                    outrel.r_addend = value + rel->r_addend;
-+                    pr_debug("    ... R_AVR32_RELATIVE\n");
-+                  }
-+                else
-+                  {
-+                    BFD_ASSERT(h->dynindx != -1);
-+                    relocate = TRUE;
-+                    outrel.r_info = ELF32_R_INFO(h->dynindx, R_AVR32_GLOB_DAT);
-+                    outrel.r_addend = rel->r_addend;
-+                    pr_debug("    ... R_AVR32_GLOB_DAT\n");
-+                  }
-+              }
-+
-+            pr_debug("srelgot reloc_count: %d, size %lu\n",
-+                     srelgot->reloc_count, srelgot->size);
-+
-+            loc = srelgot->contents;
-+            loc += srelgot->reloc_count++ * sizeof(Elf32_External_Rela);
-+            bfd_elf32_swap_reloca_out(output_bfd, &outrel, loc);
-+
-+            BFD_ASSERT(srelgot->reloc_count * sizeof(Elf32_External_Rela)
-+                       <= srelgot->size);
-+
-+            if (!relocate)
-+              continue;
-+          }
-+        break;
-+      }
-+
-+      status = avr32_final_link_relocate(howto, input_bfd, input_section,
-+                                       contents, rel, value);
-+
-+      switch (status)
-+      {
-+      case bfd_reloc_ok:
-+        break;
-+
-+      case bfd_reloc_overflow:
-+        {
-+          const char *name;
-+
-+          if (h != NULL)
-+            name = h->root.root.string;
-+          else
-+            {
-+              name = bfd_elf_string_from_elf_section(input_bfd,
-+                                                     symtab_hdr->sh_link,
-+                                                     sym->st_name);
-+              if (name == NULL)
-+                return FALSE;
-+              if (*name == '\0')
-+                name = bfd_section_name(input_bfd, sec);
-+            }
-+          if (!((*info->callbacks->reloc_overflow)
-+                (info, (h ? &h->root : NULL), name, howto->name,
-+                 rel->r_addend, input_bfd, input_section, rel->r_offset)))
-+            return FALSE;
-+        }
-+        break;
-+
-+      case bfd_reloc_outofrange:
-+      default:
-+        abort();
-+      }
-+    }
-+
-+  return TRUE;
-+}
-+
-+
-+/* Additional processing of dynamic sections after relocation */
-+
-+static bfd_boolean
-+avr32_elf_finish_dynamic_symbol(bfd *output_bfd, struct bfd_link_info *info,
-+                              struct elf_link_hash_entry *h,
-+                              Elf_Internal_Sym *sym);
-+static bfd_boolean
-+avr32_elf_finish_dynamic_sections(bfd *output_bfd, struct bfd_link_info *info);
-+
-+
-+/* (7) Initialize the contents of a dynamic symbol and/or emit
-+   relocations for it */
-+
-+static bfd_boolean
-+avr32_elf_finish_dynamic_symbol(bfd *output_bfd, struct bfd_link_info *info,
-+                              struct elf_link_hash_entry *h,
-+                              Elf_Internal_Sym *sym)
-+{
-+  struct elf_avr32_link_hash_table *htab;
-+  struct got_entry *got;
-+
-+  pr_debug("(7) finish dynamic symbol: %s\n", h->root.root.string);
-+
-+  htab = avr32_elf_hash_table(info);
-+  got = h->got.glist;
-+
-+  if (got && got->refcount > 0)
-+    {
-+      asection *sgot;
-+      asection *srelgot;
-+      Elf_Internal_Rela rel;
-+      bfd_byte *loc;
-+
-+      /* This symbol has an entry in the GOT. Set it up. */
-+      sgot = htab->sgot;
-+      srelgot = htab->srelgot;
-+      BFD_ASSERT(sgot && srelgot);
-+
-+      rel.r_offset = (sgot->output_section->vma
-+                    + sgot->output_offset
-+                    + got->offset);
-+
-+      /* If this is a static link, or it is a -Bsymbolic link and the
-+       symbol is defined locally or was forced to be local because
-+       of a version file, we just want to emit a RELATIVE reloc. The
-+       entry in the global offset table will already have been
-+       initialized in the relocate_section function. */
-+      if ((info->shared
-+         && !info->symbolic
-+         && h->dynindx != -1)
-+        || (htab->root.dynamic_sections_created
-+            && h->def_dynamic
-+            && !h->def_regular))
-+      {
-+        bfd_put_32(output_bfd, 0, sgot->contents + got->offset);
-+        rel.r_info = ELF32_R_INFO(h->dynindx, R_AVR32_GLOB_DAT);
-+        rel.r_addend = 0;
-+
-+        pr_debug("GOT reloc R_AVR32_GLOB_DAT, dynindx: %ld\n", h->dynindx);
-+        pr_debug("    srelgot reloc_count: %d, size: %lu\n",
-+                 srelgot->reloc_count, srelgot->size);
-+
-+        loc = (srelgot->contents
-+               + srelgot->reloc_count++ * sizeof(Elf32_External_Rela));
-+        bfd_elf32_swap_reloca_out(output_bfd, &rel, loc);
-+
-+        BFD_ASSERT(srelgot->reloc_count * sizeof(Elf32_External_Rela)
-+                   <= srelgot->size);
-+      }
-+    }
-+
-+  /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute */
-+  if (strcmp(h->root.root.string, "_DYNAMIC") == 0
-+      || strcmp(h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
-+    sym->st_shndx = SHN_ABS;
-+
-+  return TRUE;
-+}
-+
-+/* (8) Do any remaining initialization of the dynamic sections */
-+
-+static bfd_boolean
-+avr32_elf_finish_dynamic_sections(bfd *output_bfd, struct bfd_link_info *info)
-+{
-+  struct elf_avr32_link_hash_table *htab;
-+  asection *sgot, *sdyn;
-+
-+  pr_debug("(8) finish dynamic sections\n");
-+
-+  htab = avr32_elf_hash_table(info);
-+  sgot = htab->sgot;
-+  sdyn = bfd_get_section_by_name(htab->root.dynobj, ".dynamic");
-+
-+  if (htab->root.dynamic_sections_created)
-+    {
-+      Elf32_External_Dyn *dyncon, *dynconend;
-+
-+      BFD_ASSERT(sdyn && sgot && sgot->size >= AVR32_GOT_HEADER_SIZE);
-+
-+      dyncon = (Elf32_External_Dyn *)sdyn->contents;
-+      dynconend = (Elf32_External_Dyn *)(sdyn->contents + sdyn->size);
-+      for (; dyncon < dynconend; dyncon++)
-+      {
-+        Elf_Internal_Dyn dyn;
-+        asection *s;
-+
-+        bfd_elf32_swap_dyn_in(htab->root.dynobj, dyncon, &dyn);
-+
-+        switch (dyn.d_tag)
-+          {
-+          default:
-+            break;
-+
-+          case DT_PLTGOT:
-+            s = sgot->output_section;
-+            BFD_ASSERT(s != NULL);
-+            dyn.d_un.d_ptr = s->vma;
-+            bfd_elf32_swap_dyn_out(output_bfd, &dyn, dyncon);
-+            break;
-+
-+          case DT_AVR32_GOTSZ:
-+            s = sgot->output_section;
-+            BFD_ASSERT(s != NULL);
-+            dyn.d_un.d_val = s->size;
-+            bfd_elf32_swap_dyn_out(output_bfd, &dyn, dyncon);
-+            break;
-+          }
-+      }
-+
-+      /* Fill in the first two entries in the global offset table */
-+      bfd_put_32(output_bfd,
-+               sdyn->output_section->vma + sdyn->output_offset,
-+               sgot->contents);
-+
-+      /* The runtime linker will fill this one in with the address of
-+       the run-time link map */
-+      bfd_put_32(output_bfd, 0, sgot->contents + 4);
-+    }
-+
-+  if (sgot)
-+    elf_section_data(sgot->output_section)->this_hdr.sh_entsize = 4;
-+
-+  return TRUE;
-+}
-+
-+
-+/* AVR32-specific private ELF data */
-+
-+static bfd_boolean
-+avr32_elf_set_private_flags(bfd *abfd, flagword flags);
-+static bfd_boolean
-+avr32_elf_copy_private_bfd_data(bfd *ibfd, bfd *obfd);
-+static bfd_boolean
-+avr32_elf_merge_private_bfd_data(bfd *ibfd, bfd *obfd);
-+static bfd_boolean
-+avr32_elf_print_private_bfd_data(bfd *abfd, void *ptr);
-+
-+static bfd_boolean
-+avr32_elf_set_private_flags(bfd *abfd, flagword flags)
-+{
-+  elf_elfheader(abfd)->e_flags = flags;
-+  elf_flags_init(abfd) = TRUE;
-+
-+  return TRUE;
-+}
-+
-+/* Copy backend specific data from one object module to another.  */
-+
-+static bfd_boolean
-+avr32_elf_copy_private_bfd_data(bfd *ibfd, bfd *obfd)
-+{
-+  elf_elfheader(obfd)->e_flags = elf_elfheader(ibfd)->e_flags;
-+  return TRUE;
-+}
-+
-+/* Merge backend specific data from an object file to the output
-+   object file when linking.  */
-+
-+static bfd_boolean
-+avr32_elf_merge_private_bfd_data(bfd *ibfd, bfd *obfd)
-+{
-+  flagword out_flags, in_flags;
-+
-+  pr_debug("(0) merge_private_bfd_data: %s -> %s\n",
-+         ibfd->filename, obfd->filename);
-+
-+  in_flags = elf_elfheader(ibfd)->e_flags;
-+  out_flags = elf_elfheader(obfd)->e_flags;
-+
-+  if (elf_flags_init(obfd))
-+    {
-+      /* If one of the inputs are non-PIC, the output must be
-+       considered non-PIC.  The same applies to linkrelax.  */
-+      if (!(in_flags & EF_AVR32_PIC))
-+      out_flags &= ~EF_AVR32_PIC;
-+      if (!(in_flags & EF_AVR32_LINKRELAX))
-+      out_flags &= ~EF_AVR32_LINKRELAX;
-+    }
-+  else
-+    {
-+      elf_flags_init(obfd) = TRUE;
-+      out_flags = in_flags;
-+    }
-+
-+  elf_elfheader(obfd)->e_flags = out_flags;
-+
-+  return TRUE;
-+}
-+
-+static bfd_boolean
-+avr32_elf_print_private_bfd_data(bfd *abfd, void *ptr)
-+{
-+  FILE *file = (FILE *)ptr;
-+  unsigned long flags;
-+
-+  BFD_ASSERT(abfd != NULL && ptr != NULL);
-+
-+  _bfd_elf_print_private_bfd_data(abfd, ptr);
-+
-+  flags = elf_elfheader(abfd)->e_flags;
-+
-+  fprintf(file, _("private flags = %lx:"), elf_elfheader(abfd)->e_flags);
-+
-+  if (flags & EF_AVR32_PIC)
-+    fprintf(file, " [PIC]");
-+  if (flags & EF_AVR32_LINKRELAX)
-+    fprintf(file, " [linker relaxable]");
-+
-+  flags &= ~(EF_AVR32_PIC | EF_AVR32_LINKRELAX);
-+
-+  if (flags)
-+    fprintf(file, _("<Unrecognized flag bits set>"));
-+
-+  fputc('\n', file);
-+
-+  return TRUE;
-+}
-+
-+/* Set avr32-specific linker options.  */
-+void bfd_elf32_avr32_set_options(struct bfd_link_info *info,
-+                               int direct_data_refs)
-+{
-+  struct elf_avr32_link_hash_table *htab;
-+
-+  htab = avr32_elf_hash_table (info);
-+  htab->direct_data_refs = !!direct_data_refs;
-+}
-+
-+
-+
-+/* Understanding core dumps */
-+
-+static bfd_boolean
-+avr32_elf_grok_prstatus(bfd *abfd, Elf_Internal_Note *note);
-+static bfd_boolean
-+avr32_elf_grok_psinfo(bfd *abfd, Elf_Internal_Note *note);
-+
-+static bfd_boolean
-+avr32_elf_grok_prstatus(bfd *abfd, Elf_Internal_Note *note)
-+{
-+  /* Linux/AVR32B elf_prstatus */
-+  if (note->descsz != 148)
-+    return FALSE;
-+
-+  /* pr_cursig */
-+  elf_tdata(abfd)->core_signal = bfd_get_16(abfd, note->descdata + 12);
-+
-+  /* pr_pid */
-+  elf_tdata(abfd)->core_pid = bfd_get_32(abfd, note->descdata + 24);
-+
-+  /* Make a ".reg/999" section for pr_reg. The size is for 16
-+     general-purpose registers, SR and r12_orig (18 * 4 = 72).  */
-+  return _bfd_elfcore_make_pseudosection(abfd, ".reg", 72,
-+                                       note->descpos + 72);
-+}
-+
-+static bfd_boolean
-+avr32_elf_grok_psinfo(bfd *abfd, Elf_Internal_Note *note)
-+{
-+  /* Linux/AVR32B elf_prpsinfo */
-+  if (note->descsz != 128)
-+    return FALSE;
-+
-+  elf_tdata(abfd)->core_program
-+    = _bfd_elfcore_strndup(abfd, note->descdata + 32, 16);
-+  elf_tdata(abfd)->core_command
-+    = _bfd_elfcore_strndup(abfd, note->descdata + 48, 80);
-+
-+  /* Note that for some reason, a spurious space is tacked
-+     onto the end of the args in some (at least one anyway)
-+     implementations, so strip it off if it exists.  */
-+
-+  {
-+    char *command = elf_tdata (abfd)->core_command;
-+    int n = strlen (command);
-+
-+    if (0 < n && command[n - 1] == ' ')
-+      command[n - 1] = '\0';
-+  }
-+
-+  return TRUE;
-+}
-+
-+
-+#define ELF_ARCH                      bfd_arch_avr32
-+#define ELF_MACHINE_CODE              EM_AVR32
-+#define ELF_MAXPAGESIZE                       0x1000
-+
-+#define TARGET_BIG_SYM                        bfd_elf32_avr32_vec
-+#define TARGET_BIG_NAME                       "elf32-avr32"
-+
-+#define elf_backend_grok_prstatus     avr32_elf_grok_prstatus
-+#define elf_backend_grok_psinfo               avr32_elf_grok_psinfo
-+
-+/* Only RELA relocations are used */
-+#define elf_backend_may_use_rel_p     0
-+#define elf_backend_may_use_rela_p    1
-+#define elf_backend_default_use_rela_p        1
-+#define elf_backend_rela_normal               1
-+#define elf_info_to_howto_rel         NULL
-+#define elf_info_to_howto             avr32_info_to_howto
-+
-+#define bfd_elf32_bfd_copy_private_bfd_data   avr32_elf_copy_private_bfd_data
-+#define bfd_elf32_bfd_merge_private_bfd_data  avr32_elf_merge_private_bfd_data
-+#define bfd_elf32_bfd_set_private_flags               avr32_elf_set_private_flags
-+#define bfd_elf32_bfd_print_private_bfd_data  avr32_elf_print_private_bfd_data
-+#define bfd_elf32_new_section_hook            avr32_elf_new_section_hook
-+
-+#define elf_backend_gc_mark_hook              avr32_elf_gc_mark_hook
-+#define elf_backend_gc_sweep_hook             avr32_elf_gc_sweep_hook
-+#define elf_backend_relocate_section  avr32_elf_relocate_section
-+#define elf_backend_copy_indirect_symbol avr32_elf_copy_indirect_symbol
-+#define elf_backend_create_dynamic_sections avr32_elf_create_dynamic_sections
-+#define bfd_elf32_bfd_link_hash_table_create avr32_elf_link_hash_table_create
-+#define elf_backend_adjust_dynamic_symbol avr32_elf_adjust_dynamic_symbol
-+#define elf_backend_size_dynamic_sections avr32_elf_size_dynamic_sections
-+#define elf_backend_finish_dynamic_symbol avr32_elf_finish_dynamic_symbol
-+#define elf_backend_finish_dynamic_sections avr32_elf_finish_dynamic_sections
-+
-+#define bfd_elf32_bfd_relax_section   avr32_elf_relax_section
-+
-+/* Find out which symbols need an entry in .got. */
-+#define elf_backend_check_relocs      avr32_check_relocs
-+#define elf_backend_can_refcount      1
-+#define elf_backend_can_gc_sections   1
-+#define elf_backend_plt_readonly      1
-+#define elf_backend_plt_not_loaded    1
-+#define elf_backend_want_plt_sym      0
-+#define elf_backend_plt_alignment     2
-+#define elf_backend_want_dynbss               0
-+#define elf_backend_want_got_plt      0
-+#define elf_backend_want_got_sym      1
-+#define elf_backend_got_header_size   AVR32_GOT_HEADER_SIZE
-+
-+#include "elf32-target.h"
---- /dev/null
-+++ b/bfd/elf32-avr32.h
-@@ -0,0 +1,23 @@
-+/* AVR32-specific support for 32-bit ELF.
-+   Copyright 2007 Atmel Corporation.
-+
-+   Written by Haavard Skinnemoen, Atmel Norway, <hskinnemoen@atmel.com>
-+
-+   This file is part of BFD, the Binary File Descriptor library.
-+
-+   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 2 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-+
-+void bfd_elf32_avr32_set_options(struct bfd_link_info *info,
-+                               int direct_data_refs);
---- a/bfd/elf-bfd.h
-+++ b/bfd/elf-bfd.h
-@@ -1400,6 +1400,10 @@ struct elf_obj_tdata
-      find_nearest_line.  */
-   struct mips_elf_find_line *find_line_info;
-+  /* Used by AVR32 ELF relaxation code.  Contains an array of pointers
-+     for each local symbol to the fragment where it is defined.  */
-+  struct fragment **local_sym_frag;
-+
-   /* A place to stash dwarf1 info for this bfd.  */
-   struct dwarf1_debug *dwarf1_find_line_info;
---- a/bfd/Makefile.am
-+++ b/bfd/Makefile.am
-@@ -63,6 +63,7 @@ ALL_MACHINES = \
-       cpu-arc.lo \
-       cpu-arm.lo \
-       cpu-avr.lo \
-+      cpu-avr32.lo \
-       cpu-bfin.lo \
-       cpu-cr16.lo \
-       cpu-cr16c.lo \
-@@ -243,6 +244,7 @@ BFD32_BACKENDS = \
-       elf32-arc.lo \
-       elf32-arm.lo \
-       elf32-avr.lo \
-+      elf32-avr32.lo \
-       elf32-bfin.lo \
-       elf32-cr16.lo \
-       elf32-cr16c.lo \
-@@ -1328,6 +1330,10 @@ elf32-cr16.lo: elf32-cr16.c $(INCDIR)/fi
-   $(INCDIR)/hashtab.h $(INCDIR)/libiberty.h elf-bfd.h \
-   $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
-   $(INCDIR)/elf/cr16.h $(INCDIR)/elf/reloc-macros.h elf32-target.h
-+elf32-avr32.lo: elf32-avr32.c $(INCDIR)/filenames.h elf-bfd.h \
-+  $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
-+  $(INCDIR)/bfdlink.h $(INCDIR)/elf/avr32.h $(INCDIR)/elf/reloc-macros.h \
-+  elf32-target.h
- elf32-cr16c.lo: elf32-cr16c.c $(INCDIR)/filenames.h \
-   $(INCDIR)/hashtab.h $(INCDIR)/bfdlink.h $(INCDIR)/elf/cr16c.h \
-   $(INCDIR)/elf/reloc-macros.h elf-bfd.h $(INCDIR)/elf/common.h \
---- a/bfd/reloc.c
-+++ b/bfd/reloc.c
-@@ -3948,6 +3948,131 @@ ENUMDOC
-   instructions
- ENUM
-+  BFD_RELOC_AVR32_DIFF32
-+ENUMX
-+  BFD_RELOC_AVR32_DIFF16
-+ENUMX
-+  BFD_RELOC_AVR32_DIFF8
-+ENUMDOC
-+  Difference between two labels: L2 - L1. The value of L1 is encoded
-+  as sym + addend, while the initial difference after assembly is
-+  inserted into the object file by the assembler.
-+ENUM
-+  BFD_RELOC_AVR32_GOT32
-+ENUMX
-+  BFD_RELOC_AVR32_GOT16
-+ENUMX
-+  BFD_RELOC_AVR32_GOT8
-+ENUMDOC
-+  Reference to a symbol through the Global Offset Table. The linker
-+  will allocate an entry for symbol in the GOT and insert the offset
-+  of this entry as the relocation value.
-+ENUM
-+  BFD_RELOC_AVR32_21S
-+ENUMX
-+  BFD_RELOC_AVR32_16U
-+ENUMX
-+  BFD_RELOC_AVR32_16S
-+ENUMX
-+  BFD_RELOC_AVR32_SUB5
-+ENUMX
-+  BFD_RELOC_AVR32_8S_EXT
-+ENUMX
-+  BFD_RELOC_AVR32_8S
-+ENUMX
-+  BFD_RELOC_AVR32_15S
-+ENUMDOC
-+  Normal (non-pc-relative) code relocations. Alignment and signedness
-+  is indicated by the suffixes. S means signed, U means unsigned. W
-+  means word-aligned, H means halfword-aligned, neither means
-+  byte-aligned (no alignment.) SUB5 is the same relocation as 16S.
-+ENUM
-+  BFD_RELOC_AVR32_22H_PCREL
-+ENUMX
-+  BFD_RELOC_AVR32_18W_PCREL
-+ENUMX
-+  BFD_RELOC_AVR32_16B_PCREL
-+ENUMX
-+  BFD_RELOC_AVR32_16N_PCREL
-+ENUMX
-+  BFD_RELOC_AVR32_14UW_PCREL
-+ENUMX
-+  BFD_RELOC_AVR32_11H_PCREL
-+ENUMX
-+  BFD_RELOC_AVR32_10UW_PCREL
-+ENUMX
-+  BFD_RELOC_AVR32_9H_PCREL
-+ENUMX
-+  BFD_RELOC_AVR32_9UW_PCREL
-+ENUMDOC
-+  PC-relative relocations are signed if neither 'U' nor 'S' is
-+  specified. However, we explicitly tack on a 'B' to indicate no
-+  alignment, to avoid confusion with data relocs. All of these resolve
-+  to sym + addend - offset, except the one with 'N' (negated) suffix.
-+  This particular one resolves to offset - sym - addend.
-+ENUM
-+  BFD_RELOC_AVR32_GOTPC
-+ENUMDOC
-+  Subtract the link-time address of the GOT from (symbol + addend)
-+  and insert the result.
-+ENUM
-+  BFD_RELOC_AVR32_GOTCALL
-+ENUMX
-+  BFD_RELOC_AVR32_LDA_GOT
-+ENUMX
-+  BFD_RELOC_AVR32_GOT21S
-+ENUMX
-+  BFD_RELOC_AVR32_GOT18SW
-+ENUMX
-+  BFD_RELOC_AVR32_GOT16S
-+ENUMDOC
-+  Reference to a symbol through the GOT. The linker will allocate an
-+  entry for symbol in the GOT and insert the offset of this entry as
-+  the relocation value. addend must be zero. As usual, 'S' means
-+  signed, 'W' means word-aligned, etc.
-+ENUM
-+  BFD_RELOC_AVR32_32_CPENT
-+ENUMDOC
-+  32-bit constant pool entry. I don't think 8- and 16-bit entries make
-+  a whole lot of sense.
-+ENUM
-+  BFD_RELOC_AVR32_CPCALL
-+ENUMX
-+  BFD_RELOC_AVR32_16_CP
-+ENUMX
-+  BFD_RELOC_AVR32_9W_CP
-+ENUMDOC
-+  Constant pool references. Some of these relocations are signed,
-+  others are unsigned. It doesn't really matter, since the constant
-+  pool always comes after the code that references it.
-+ENUM
-+  BFD_RELOC_AVR32_ALIGN
-+ENUMDOC
-+  sym must be the absolute symbol. The addend specifies the alignment
-+  order, e.g. if addend is 2, the linker must add padding so that the
-+  next address is aligned to a 4-byte boundary.
-+ENUM
-+  BFD_RELOC_AVR32_14UW
-+ENUMX
-+  BFD_RELOC_AVR32_10UW
-+ENUMX
-+  BFD_RELOC_AVR32_10SW
-+ENUMX
-+  BFD_RELOC_AVR32_STHH_W
-+ENUMX
-+  BFD_RELOC_AVR32_7UW
-+ENUMX
-+  BFD_RELOC_AVR32_6S
-+ENUMX
-+  BFD_RELOC_AVR32_6UW
-+ENUMX
-+  BFD_RELOC_AVR32_4UH
-+ENUMX
-+  BFD_RELOC_AVR32_3U
-+ENUMDOC
-+  Code relocations that will never make it to the output file.
-+
-+ENUM
-   BFD_RELOC_390_12
- ENUMDOC
-    Direct 12 bit.
---- a/bfd/targets.c
-+++ b/bfd/targets.c
-@@ -564,6 +564,7 @@ extern const bfd_target bfd_efi_app_ia32
- extern const bfd_target bfd_efi_app_x86_64_vec;
- extern const bfd_target bfd_efi_app_ia64_vec;
- extern const bfd_target bfd_elf32_avr_vec;
-+extern const bfd_target bfd_elf32_avr32_vec;
- extern const bfd_target bfd_elf32_bfin_vec;
- extern const bfd_target bfd_elf32_bfinfdpic_vec;
- extern const bfd_target bfd_elf32_big_generic_vec;
-@@ -884,6 +885,7 @@ static const bfd_target * const _bfd_tar
-       &bfd_efi_app_ia64_vec,
- #endif
-       &bfd_elf32_avr_vec,
-+      &bfd_elf32_avr32_vec,
-       &bfd_elf32_bfin_vec,
-       &bfd_elf32_bfinfdpic_vec,
---- a/binutils/Makefile.am
-+++ b/binutils/Makefile.am
-@@ -577,7 +577,7 @@ readelf.o: readelf.c sysdep.h $(INCDIR)/
-   $(INCDIR)/ansidecl.h $(INCDIR)/symcat.h bucomm.h dwarf.h \
-   $(INCDIR)/elf/common.h $(INCDIR)/elf/external.h $(INCDIR)/elf/internal.h \
-   $(INCDIR)/elf/h8.h $(INCDIR)/elf/reloc-macros.h $(INCDIR)/elf/alpha.h \
--  $(INCDIR)/elf/arc.h $(INCDIR)/elf/arm.h $(INCDIR)/elf/avr.h \
-+  $(INCDIR)/elf/arc.h $(INCDIR)/elf/arm.h $(INCDIR)/elf/avr.h $(INCDIR)/elf/avr32.h\
-   $(INCDIR)/elf/bfin.h $(INCDIR)/elf/cris.h $(INCDIR)/elf/crx.h \
-   $(INCDIR)/elf/d10v.h $(INCDIR)/elf/d30v.h $(INCDIR)/elf/dlx.h \
-   $(INCDIR)/elf/fr30.h $(INCDIR)/elf/frv.h $(INCDIR)/elf/hppa.h \
---- a/binutils/readelf.c
-+++ b/binutils/readelf.c
-@@ -21,7 +21,7 @@
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
-    02110-1301, USA.  */
--\f
-+
- /* The difference between readelf and objdump:
-   Both programs are capable of displaying the contents of ELF format files,
-@@ -40,7 +40,7 @@
-   There is also the case that readelf can provide more information about an
-   ELF file than is provided by objdump.  In particular it can display DWARF
-   debugging information which (at the moment) objdump cannot.  */
--\f
-+
- #include "sysdep.h"
- #include <assert.h>
- #include <sys/stat.h>
-@@ -109,6 +109,7 @@
- #include "elf/arc.h"
- #include "elf/arm.h"
- #include "elf/avr.h"
-+#include "elf/avr32.h"
- #include "elf/bfin.h"
- #include "elf/cr16.h"
- #include "elf/cris.h"
-@@ -303,7 +304,7 @@ static void (*byte_put) (unsigned char *
- #define streq(a,b)      (strcmp ((a), (b)) == 0)
- #define strneq(a,b,n)   (strncmp ((a), (b), (n)) == 0)
- #define const_strneq(a,b) (strncmp ((a), (b), sizeof (b) - 1) == 0)
--\f
-+
- static void *
- get_data (void *var, FILE *file, long offset, size_t size, size_t nmemb,
-         const char *reason)
-@@ -614,6 +615,7 @@ guess_is_rela (unsigned long e_machine)
-     case EM_ALPHA:
-     case EM_ALTERA_NIOS2:
-     case EM_AVR:
-+    case EM_AVR32:
-     case EM_AVR_OLD:
-     case EM_BLACKFIN:
-     case EM_CR16:
-@@ -1006,6 +1008,10 @@ dump_relocations (FILE *file,
-         rtype = elf_avr_reloc_type (type);
-         break;
-+      case EM_AVR32:
-+        rtype = elf_avr32_reloc_type (type);
-+        break;
-+
-       case EM_OLD_SPARCV9:
-       case EM_SPARC32PLUS:
-       case EM_SPARCV9:
-@@ -1763,6 +1769,7 @@ get_machine_name (unsigned e_machine)
-     case EM_VAX:              return "Digital VAX";
-     case EM_AVR_OLD:
-     case EM_AVR:              return "Atmel AVR 8-bit microcontroller";
-+    case EM_AVR32:            return "Atmel AVR32";
-     case EM_CRIS:             return "Axis Communications 32-bit embedded processor";
-     case EM_JAVELIN:          return "Infineon Technologies 32-bit embedded cpu";
-     case EM_FIREPATH:         return "Element 14 64-bit DSP processor";
---- a/gas/as.c
-+++ b/gas/as.c
-@@ -441,10 +441,10 @@ parse_args (int * pargc, char *** pargv)
-        the end of the preceeding line so that it is simpler to
-        selectively add and remove lines from this list.  */
-     {"alternate", no_argument, NULL, OPTION_ALTERNATE}
--    /* The entry for "a" is here to prevent getopt_long_only() from
--       considering that -a is an abbreviation for --alternate.  This is
--       necessary because -a=<FILE> is a valid switch but getopt would
--       normally reject it since --alternate does not take an argument.  */
-+    /* The next two entries are here to prevent getopt_long_only() from
-+       considering that -a or -al is an abbreviation for --alternate.
-+       This is necessary because -a=<FILE> is a valid switch but getopt
-+       would normally reject it since --alternate does not take an argument.  */
-     ,{"a", optional_argument, NULL, 'a'}
-     /* Handle -al=<FILE>.  */
-     ,{"al", optional_argument, NULL, OPTION_AL}
-@@ -803,8 +803,15 @@ This program has absolutely no warranty.
-       case 'a':
-         if (optarg)
-           {
--            if (optarg != old_argv[optind] && optarg[-1] == '=')
--              --optarg;
-+            /* If optarg is part of the -a switch and not a separate argument
-+               in its own right, then scan backwards to the just after the -a.
-+               This means skipping over both '=' and 'l' which might have been
-+               taken to be part of the -a switch itself.  */
-+            if (optarg != old_argv[optind])
-+              {
-+                while (optarg[-1] == '=' || optarg[-1] == 'l')
-+                  --optarg;
-+              }
-             if (md_parse_option (optc, optarg) != 0)
-               break;
-@@ -1234,7 +1241,7 @@ main (int argc, char ** argv)
-     keep_it = 0;
-   if (!keep_it)
--    unlink_if_ordinary (out_file_name);
-+    unlink (out_file_name);
-   input_scrub_end ();
---- /dev/null
-+++ b/gas/config/tc-avr32.c
-@@ -0,0 +1,4806 @@
-+/* Assembler implementation for AVR32.
-+   Copyright 2003-2006 Atmel Corporation.
-+
-+   Written by Haavard Skinnemoen, Atmel Norway, <hskinnemoen@atmel.com>
-+
-+   This file is part of GAS, the GNU Assembler.
-+
-+   GAS 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 2, or (at your option)
-+   any later version.
-+
-+   GAS 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 GAS; see the file COPYING.  If not, write to the Free
-+   Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-+   02111-1307, USA.  */
-+
-+#include <stdio.h>
-+#include "as.h"
-+#include "safe-ctype.h"
-+#include "subsegs.h"
-+#include "symcat.h"
-+#include "opcodes/avr32-opc.h"
-+#include "opcodes/avr32-asm.h"
-+#include "elf/avr32.h"
-+#include "dwarf2dbg.h"
-+
-+#define xDEBUG
-+#define xOPC_CONSISTENCY_CHECK
-+
-+#ifdef DEBUG
-+# define pr_debug(fmt, args...) fprintf(stderr, fmt, ##args)
-+#else
-+# define pr_debug(fmt, args...)
-+#endif
-+
-+/* 3 MSB of instruction word indicate group. Group 7 -> extended */
-+#define AVR32_COMPACT_P(opcode) ((opcode[0] & 0xe0) != 0xe0)
-+
-+#define streq(a, b)           (strcmp(a, b) == 0)
-+#define skip_whitespace(str)  do { while(*(str) == ' ') ++(str); } while(0)
-+
-+/* Flags given on the command line */
-+static int avr32_pic  = FALSE;
-+int linkrelax = FALSE;
-+int avr32_iarcompat   = FALSE;
-+
-+/* This array holds the chars that always start a comment. */
-+const char comment_chars[]            = "#";
-+
-+/* This array holds the chars that only start a comment at the
-+   beginning of a line.  We must include '#' here because the compiler
-+   may produce #APP and #NO_APP in its output.  */
-+const char line_comment_chars[]               = "#";
-+
-+/* These may be used instead of newline (same as ';' in C).  */
-+const char line_separator_chars[]     = ";";
-+
-+/* Chars that can be used to separate mantissa from exponent in
-+   floating point numbers.  */
-+const char EXP_CHARS[]                        = "eE";
-+
-+/* Chars that mean this number is a floating point constant.  */
-+const char FLT_CHARS[]                        = "dD";
-+
-+/* Pre-defined "_GLOBAL_OFFSET_TABLE_"  */
-+symbolS *GOT_symbol;
-+
-+static struct hash_control *avr32_mnemonic_htab;
-+
-+struct avr32_ifield_data
-+{
-+  bfd_vma value;
-+  /* FIXME: Get rid of align_order and complain. complain is never
-+     used, align_order is used in one place.  Try to use the relax
-+     table instead.  */
-+  unsigned int align_order;
-+};
-+
-+struct avr32_insn
-+{
-+  const struct avr32_syntax *syntax;
-+  expressionS immediate;
-+  int pcrel;
-+  int force_extended;
-+  unsigned int next_slot;
-+  bfd_reloc_code_real_type r_type;
-+  struct avr32_ifield_data field_value[AVR32_MAX_FIELDS];
-+};
-+
-+static struct avr32_insn current_insn;
-+
-+/* The target specific pseudo-ops we support. */
-+static void s_rseg (int);
-+static void s_cpool(int);
-+
-+const pseudo_typeS md_pseudo_table[] =
-+{
-+  /* Make sure that .word is 32 bits */
-+  { "word", cons, 4 },
-+  { "file", (void (*) PARAMS ((int))) dwarf2_directive_file, 0 },
-+  { "loc", dwarf2_directive_loc, 0 },
-+
-+  /* .lcomm requires an explicit alignment parameter */
-+  { "lcomm", s_lcomm, 1 },
-+
-+  /* AVR32-specific pseudo-ops */
-+  { "cpool", s_cpool, 0},
-+
-+  /* IAR compatible pseudo-ops */
-+  { "program", s_ignore, 0 },
-+  { "public", s_globl, 0 },
-+  { "extern", s_ignore, 0 },
-+  { "module", s_ignore, 0 },
-+  { "rseg", s_rseg, 0 },
-+  { "dc8", cons, 1 },
-+  { "dc16", cons, 2 },
-+  { "dc32", cons, 4 },
-+
-+  { NULL, NULL, 0 }
-+};
-+
-+/* Questionable stuff starts here */
-+
-+enum avr32_opinfo {
-+  AVR32_OPINFO_NONE = BFD_RELOC_NONE,
-+  AVR32_OPINFO_GOT,
-+  AVR32_OPINFO_TLSGD,
-+  AVR32_OPINFO_HI,
-+  AVR32_OPINFO_LO,
-+};
-+
-+enum avr32_arch {
-+  ARCH_TYPE_AP,
-+  ARCH_TYPE_UCR1,
-+  ARCH_TYPE_UCR2,
-+};
-+
-+struct arch_type_s
-+{
-+  /* Architecture name */
-+  char *name;
-+  /* Instruction Set Architecture Flags */
-+  unsigned long isa_flags;
-+};
-+
-+struct part_type_s
-+{
-+  /* Part name */
-+  char *name;
-+  /* Architecture type */
-+  unsigned int arch;
-+};
-+
-+static struct arch_type_s arch_types[] =
-+{
-+  {"ap", AVR32_V1 | AVR32_SIMD | AVR32_DSP | AVR32_PICO},
-+  {"ucr1", AVR32_V1 | AVR32_DSP | AVR32_RMW},
-+  {"ucr2", AVR32_V1 | AVR32_V2 | AVR32_DSP | AVR32_RMW},
-+  {"all-insn", AVR32_V1 | AVR32_V2 | AVR32_SIMD | AVR32_DSP | AVR32_RMW | AVR32_FP | AVR32_PICO},
-+  {NULL, 0}
-+};
-+
-+static struct part_type_s part_types[] = {
-+  {"ap7000", ARCH_TYPE_AP},
-+  {"ap7001", ARCH_TYPE_AP},
-+  {"ap7002", ARCH_TYPE_AP},
-+  {"ap7200", ARCH_TYPE_AP},
-+  {"uc3a0128", ARCH_TYPE_UCR2},
-+  {"uc3a0256", ARCH_TYPE_UCR2},
-+  {"uc3a0512es", ARCH_TYPE_UCR1},
-+  {"uc3a0512", ARCH_TYPE_UCR2},
-+  {"uc3a1128", ARCH_TYPE_UCR2},
-+  {"uc3a1256es", ARCH_TYPE_UCR1},
-+  {"uc3a1256", ARCH_TYPE_UCR2},
-+  {"uc3a1512es", ARCH_TYPE_UCR1},
-+  {"uc3a1512", ARCH_TYPE_UCR2},
-+  {"uc3a364", ARCH_TYPE_UCR2},
-+  {"uc3a364s", ARCH_TYPE_UCR2},
-+  {"uc3a3128", ARCH_TYPE_UCR2},
-+  {"uc3a3128s", ARCH_TYPE_UCR2},
-+  {"uc3a3256", ARCH_TYPE_UCR2},
-+  {"uc3a3256s", ARCH_TYPE_UCR2},
-+  {"uc3b064", ARCH_TYPE_UCR1},
-+  {"uc3b0128", ARCH_TYPE_UCR1},
-+  {"uc3b0256es", ARCH_TYPE_UCR1},
-+  {"uc3b0256", ARCH_TYPE_UCR1},
-+  {"uc3b164", ARCH_TYPE_UCR1},
-+  {"uc3b1128", ARCH_TYPE_UCR1},
-+  {"uc3b1256es", ARCH_TYPE_UCR1},
-+  {"uc3b1256", ARCH_TYPE_UCR1},
-+  {NULL, 0}
-+};
-+
-+/* Current architecture type.  */
-+static struct arch_type_s default_arch = {"all-insn", AVR32_V1 | AVR32_V2 | AVR32_SIMD | AVR32_DSP | AVR32_RMW | AVR32_FP | AVR32_PICO };
-+static struct arch_type_s *avr32_arch = &default_arch;
-+
-+/* Display nicely formatted list of known part- and architecture names.  */
-+
-+static void
-+show_arch_list (FILE *stream)
-+{
-+  int i, x;
-+
-+  fprintf (stream, _("Known architecture names:"));
-+  x = 1000;
-+
-+  for (i = 0; arch_types[i].name; i++)
-+    {
-+      int len = strlen (arch_types[i].name);
-+
-+      x += len + 1;
-+
-+      if (x < 75)
-+      fprintf (stream, " %s", arch_types[i].name);
-+      else
-+      {
-+        fprintf (stream, "\n  %s", arch_types[i].name);
-+        x = len + 2;
-+      }
-+    }
-+
-+  fprintf (stream, "\n");
-+}
-+
-+static void
-+show_part_list (FILE *stream)
-+{
-+  int i, x;
-+
-+  fprintf (stream, _("Known part names:"));
-+  x = 1000;
-+
-+  for (i = 0; part_types[i].name; i++)
-+    {
-+      int len = strlen(part_types[i].name);
-+
-+      x += len + 1;
-+
-+      if (x < 75)
-+      fprintf (stream, " %s", part_types[i].name);
-+      else
-+      {
-+        fprintf(stream, "\n  %s", part_types[i].name);
-+        x = len + 2;
-+      }
-+    }
-+
-+  fprintf (stream, "\n");
-+}
-+
-+const char *md_shortopts = "";
-+struct option md_longopts[] =
-+{
-+#define OPTION_ARCH           (OPTION_MD_BASE)
-+#define OPTION_PART           (OPTION_ARCH + 1)
-+#define OPTION_IAR            (OPTION_PART + 1)
-+#define OPTION_PIC            (OPTION_IAR + 1)
-+#define OPTION_NOPIC          (OPTION_PIC + 1)
-+#define OPTION_LINKRELAX      (OPTION_NOPIC + 1)
-+#define OPTION_NOLINKRELAX    (OPTION_LINKRELAX + 1)
-+#define OPTION_DIRECT_DATA_REFS (OPTION_NOLINKRELAX + 1)
-+  {"march",           required_argument, NULL, OPTION_ARCH},
-+  {"mpart",           required_argument, NULL, OPTION_PART},
-+  {"iar",             no_argument, NULL, OPTION_IAR},
-+  {"pic",             no_argument, NULL, OPTION_PIC},
-+  {"no-pic",          no_argument, NULL, OPTION_NOPIC},
-+  {"linkrelax",               no_argument, NULL, OPTION_LINKRELAX},
-+  {"no-linkrelax",    no_argument, NULL, OPTION_NOLINKRELAX},
-+  /* deprecated alias for -mpart=xxx */
-+  {"mcpu",            required_argument, NULL, OPTION_PART},
-+  {NULL,              no_argument, NULL, 0}
-+};
-+
-+size_t md_longopts_size = sizeof (md_longopts);
-+
-+void
-+md_show_usage (FILE *stream)
-+{
-+  fprintf (stream, _("\
-+AVR32 options:\n\
-+  -march=[arch-name]      Select cpu architecture. [Default `all-insn']\n\
-+  -mpart=[part-name]      Select specific part. [Default `none']\n\
-+  --pic                   Produce Position-Independent Code\n\
-+  --no-pic                Don't produce Position-Independent Code\n\
-+  --linkrelax             Produce output suitable for linker relaxing\n\
-+  --no-linkrelax          Don't produce output suitable for linker relaxing\n"));
-+  show_arch_list(stream);
-+}
-+
-+int
-+md_parse_option (int c, char *arg ATTRIBUTE_UNUSED)
-+{
-+  switch (c)
-+    {
-+    case OPTION_ARCH:
-+      {
-+      int i;
-+      char *s = alloca (strlen (arg) + 1);
-+
-+      {
-+        char *t = s;
-+        char *arg1 = arg;
-+
-+        do
-+          *t = TOLOWER (*arg1++);
-+        while (*t++);
-+      }
-+
-+        /* Add backward compability */
-+        if (strcmp ("uc", s)== 0)
-+          {
-+            as_warn("Deprecated arch `%s' specified. "
-+                    "Please use '-march=ucr1' instead. "
-+                    "Converting to arch 'ucr1'\n",
-+                     s);
-+            s="ucr1";
-+          }
-+
-+      for (i = 0; arch_types[i].name; ++i)
-+        if (strcmp (arch_types[i].name, s) == 0)
-+          break;
-+
-+      if (!arch_types[i].name)
-+        {
-+          show_arch_list (stderr);
-+          as_fatal (_("unknown architecture: %s\n"), arg);
-+        }
-+
-+        avr32_arch = &arch_types[i];
-+      break;
-+      }
-+    case OPTION_PART:
-+      {
-+      int i;
-+      char *s = alloca (strlen (arg) + 1);
-+      char *t = s;
-+      char *p = arg;
-+
-+      /* If arch type has already been set, don't bother.
-+         -march= always overrides -mpart=  */
-+      if (avr32_arch != &default_arch)
-+        break;
-+
-+      do
-+        *t = TOLOWER (*p++);
-+      while (*t++);
-+
-+      for (i = 0; part_types[i].name; ++i)
-+        if (strcmp (part_types[i].name, s) == 0)
-+          break;
-+
-+      if (!part_types[i].name)
-+        {
-+          show_part_list (stderr);
-+          as_fatal (_("unknown part: %s\n"), arg);
-+        }
-+
-+      avr32_arch = &arch_types[part_types[i].arch];
-+      break;
-+      }
-+    case OPTION_IAR:
-+      avr32_iarcompat = 1;
-+      break;
-+    case OPTION_PIC:
-+      avr32_pic = 1;
-+      break;
-+    case OPTION_NOPIC:
-+      avr32_pic = 0;
-+      break;
-+    case OPTION_LINKRELAX:
-+      linkrelax = 1;
-+      break;
-+    case OPTION_NOLINKRELAX:
-+      linkrelax = 0;
-+      break;
-+    default:
-+      return 0;
-+    }
-+  return 1;
-+}
-+
-+/* Can't use symbol_new here, so have to create a symbol and then at
-+   a later date assign it a value. Thats what these functions do.
-+
-+   Shamelessly stolen from ARM.  */
-+
-+static void
-+symbol_locate (symbolS *    symbolP,
-+             const char * name,       /* It is copied, the caller can modify.  */
-+             segT         segment,    /* Segment identifier (SEG_<something>).  */
-+             valueT       valu,       /* Symbol value.  */
-+             fragS *      frag)       /* Associated fragment.  */
-+{
-+  unsigned int name_length;
-+  char * preserved_copy_of_name;
-+
-+  name_length = strlen (name) + 1;   /* +1 for \0.  */
-+  obstack_grow (&notes, name, name_length);
-+  preserved_copy_of_name = obstack_finish (&notes);
-+#ifdef STRIP_UNDERSCORE
-+  if (preserved_copy_of_name[0] == '_')
-+    preserved_copy_of_name++;
-+#endif
-+
-+#ifdef tc_canonicalize_symbol_name
-+  preserved_copy_of_name =
-+    tc_canonicalize_symbol_name (preserved_copy_of_name);
-+#endif
-+
-+  S_SET_NAME (symbolP, preserved_copy_of_name);
-+
-+  S_SET_SEGMENT (symbolP, segment);
-+  S_SET_VALUE (symbolP, valu);
-+  symbol_clear_list_pointers (symbolP);
-+
-+  symbol_set_frag (symbolP, frag);
-+
-+  /* Link to end of symbol chain.  */
-+  {
-+    extern int symbol_table_frozen;
-+
-+    if (symbol_table_frozen)
-+      abort ();
-+  }
-+
-+  symbol_append (symbolP, symbol_lastP, & symbol_rootP, & symbol_lastP);
-+
-+  obj_symbol_new_hook (symbolP);
-+
-+#ifdef tc_symbol_new_hook
-+  tc_symbol_new_hook (symbolP);
-+#endif
-+
-+#ifdef DEBUG_SYMS
-+  verify_symbol_chain (symbol_rootP, symbol_lastP);
-+#endif /* DEBUG_SYMS  */
-+}
-+
-+struct cpool_entry
-+{
-+  int                 refcount;
-+  offsetT             offset;
-+  expressionS         exp;
-+};
-+
-+struct cpool
-+{
-+  struct cpool                *next;
-+  int                 used;
-+  struct cpool_entry  *literals;
-+  unsigned int                padding;
-+  unsigned int                next_free_entry;
-+  unsigned int                id;
-+  symbolS             *symbol;
-+  segT                        section;
-+  subsegT             sub_section;
-+};
-+
-+struct cpool *cpool_list = NULL;
-+
-+static struct cpool *
-+find_cpool(segT section, subsegT sub_section)
-+{
-+  struct cpool *pool;
-+
-+  for (pool = cpool_list; pool != NULL; pool = pool->next)
-+    {
-+      if (!pool->used
-+        && pool->section == section
-+        && pool->sub_section == sub_section)
-+      break;
-+    }
-+
-+  return pool;
-+}
-+
-+static struct cpool *
-+find_or_make_cpool(segT section, subsegT sub_section)
-+{
-+  static unsigned int next_cpool_id = 0;
-+  struct cpool *pool;
-+
-+  pool = find_cpool(section, sub_section);
-+
-+  if (!pool)
-+    {
-+      pool = xmalloc(sizeof(*pool));
-+      if (!pool)
-+      return NULL;
-+
-+      pool->used = 0;
-+      pool->literals = NULL;
-+      pool->padding = 0;
-+      pool->next_free_entry = 0;
-+      pool->section = section;
-+      pool->sub_section = sub_section;
-+      pool->next = cpool_list;
-+      pool->symbol = NULL;
-+
-+      cpool_list = pool;
-+    }
-+
-+  /* NULL symbol means that the pool is new or has just been emptied.  */
-+  if (!pool->symbol)
-+    {
-+      pool->symbol = symbol_create(FAKE_LABEL_NAME, undefined_section,
-+                                 0, &zero_address_frag);
-+      pool->id = next_cpool_id++;
-+    }
-+
-+  return pool;
-+}
-+
-+static struct cpool *
-+add_to_cpool(expressionS *exp, unsigned int *index, int ref)
-+{
-+  struct cpool *pool;
-+  unsigned int entry;
-+
-+  pool = find_or_make_cpool(now_seg, now_subseg);
-+
-+  /* Check if this constant is already in the pool.  */
-+  for (entry = 0; entry < pool->next_free_entry; entry++)
-+    {
-+      if ((pool->literals[entry].exp.X_op == exp->X_op)
-+        && (exp->X_op == O_constant)
-+        && (pool->literals[entry].exp.X_add_number
-+            == exp->X_add_number)
-+        && (pool->literals[entry].exp.X_unsigned
-+            == exp->X_unsigned))
-+      break;
-+
-+      if ((pool->literals[entry].exp.X_op == exp->X_op)
-+        && (exp->X_op == O_symbol)
-+        && (pool->literals[entry].exp.X_add_number
-+            == exp->X_add_number)
-+        && (pool->literals[entry].exp.X_add_symbol
-+            == exp->X_add_symbol)
-+        && (pool->literals[entry].exp.X_op_symbol
-+            == exp->X_op_symbol))
-+      break;
-+    }
-+
-+  /* Create an entry if we didn't find a match */
-+  if (entry == pool->next_free_entry)
-+    {
-+      pool->literals = xrealloc(pool->literals,
-+                              sizeof(struct cpool_entry) * (entry + 1));
-+      pool->literals[entry].exp = *exp;
-+      pool->literals[entry].refcount = 0;
-+      pool->next_free_entry++;
-+    }
-+
-+  if (index)
-+    *index = entry;
-+  if (ref)
-+    pool->literals[entry].refcount++;
-+
-+  return pool;
-+}
-+
-+struct avr32_operand
-+{
-+  int id;
-+  int is_signed;
-+  int is_pcrel;
-+  int align_order;
-+  int (*match)(char *str);
-+  void (*parse)(const struct avr32_operand *op, char *str, int opindex);
-+};
-+
-+static int
-+match_anything(char *str ATTRIBUTE_UNUSED)
-+{
-+  return 1;
-+}
-+
-+static int
-+match_intreg(char *str)
-+{
-+  int regid, ret = 1;
-+
-+  regid = avr32_parse_intreg(str);
-+  if (regid < 0)
-+    ret = 0;
-+
-+  pr_debug("match_intreg: `%s': %d\n", str, ret);
-+
-+  return ret;
-+}
-+
-+static int
-+match_intreg_predec(char *str)
-+{
-+  int regid;
-+
-+  if (str[0] != '-' || str[1] != '-')
-+    return 0;
-+
-+  regid = avr32_parse_intreg(str + 2);
-+  if (regid < 0)
-+    return 0;
-+
-+  return 1;
-+}
-+
-+static int
-+match_intreg_postinc(char *str)
-+{
-+  int regid, ret = 1;
-+  char *p, c;
-+
-+  for (p = str; *p; p++)
-+    if (*p == '+')
-+      break;
-+
-+  if (p[0] != '+' || p[1] != '+')
-+    return 0;
-+
-+  c = *p, *p = 0;
-+  regid = avr32_parse_intreg(str);
-+  if (regid < 0)
-+    ret = 0;
-+
-+  *p = c;
-+  return ret;
-+}
-+
-+static int
-+match_intreg_lsl(char *str)
-+{
-+  int regid, ret = 1;
-+  char *p, c;
-+
-+  for (p = str; *p; p++)
-+    if (*p == '<')
-+      break;
-+
-+  if (p[0] && p[1] != '<')
-+    return 0;
-+
-+  c = *p, *p = 0;
-+  regid = avr32_parse_intreg(str);
-+  if (regid < 0)
-+    ret = 0;
-+
-+  *p = c;
-+  return ret;
-+}
-+
-+static int
-+match_intreg_lsr(char *str)
-+{
-+  int regid, ret = 1;
-+  char *p, c;
-+
-+  for (p = str; *p; p++)
-+    if (*p == '>')
-+      break;
-+
-+  if (p[0] && p[1] != '>')
-+    return 0;
-+
-+  c = *p, *p = 0;
-+
-+  regid = avr32_parse_intreg(str);
-+  if (regid < 0)
-+    ret = 0;
-+
-+  *p = c;
-+  return ret;
-+}
-+
-+static int
-+match_intreg_part(char *str)
-+{
-+  int regid, ret = 1;
-+  char *p, c;
-+
-+  for (p = str; *p; p++)
-+    if (*p == ':')
-+      break;
-+
-+  if (p[0] != ':' || !ISPRINT(p[1]) || p[2] != '\0')
-+    return 0;
-+
-+  c = *p, *p = 0;
-+  regid = avr32_parse_intreg(str);
-+  if (regid < 0)
-+    ret = 0;
-+
-+  *p = c;
-+
-+  return ret;
-+}
-+
-+#define match_intreg_disp match_anything
-+
-+static int
-+match_intreg_index(char *str)
-+{
-+  int regid, ret = 1;
-+  char *p, *end, c;
-+
-+  for (p = str; *p; p++)
-+    if (*p == '[')
-+      break;
-+
-+  /* don't allow empty displacement here (it makes no sense) */
-+  if (p[0] != '[')
-+    return 0;
-+
-+  for (end = p + 1; *end; end++) ;
-+  if (*(--end) != ']')
-+    return 0;
-+
-+  c = *end, *end = 0;
-+  if (!match_intreg_lsl(p + 1))
-+    ret = 0;
-+  *end = c;
-+
-+  if (ret)
-+    {
-+      c = *p, *p = 0;
-+      regid = avr32_parse_intreg(str);
-+      if (regid < 0)
-+      ret = 0;
-+      *p = c;
-+    }
-+
-+  return ret;
-+}
-+
-+static int
-+match_intreg_xindex(char *str)
-+{
-+  int regid, ret = 1;
-+  char *p, *end, c;
-+
-+  for (p = str; *p; p++)
-+    if (*p == '[')
-+      break;
-+
-+  /* empty displacement makes no sense here either */
-+  if (p[0] != '[')
-+    return 0;
-+
-+  for (end = p + 1; *end; end++)
-+    if (*end == '<')
-+      break;
-+
-+  if (!streq(end, "<<2]"))
-+    return 0;
-+
-+  c = *end, *end = 0;
-+  if (!match_intreg_part(p + 1))
-+    ret = 0;
-+  *end = c;
-+
-+  if (ret)
-+    {
-+      c = *p, *p = 0;
-+      regid = avr32_parse_intreg(str);
-+      if (regid < 0)
-+      ret = 0;
-+      *p = c;
-+    }
-+
-+  return ret;
-+}
-+
-+/* The PC_UDISP_W operator may show up as a label or as a pc[disp]
-+   expression.  So there's no point in attempting to match this...  */
-+#define match_pc_disp match_anything
-+
-+static int
-+match_sp(char *str)
-+{
-+  /* SP in any form will do */
-+  return avr32_parse_intreg(str) == AVR32_REG_SP;
-+}
-+
-+static int
-+match_sp_disp(char *str)
-+{
-+  int regid, ret = 1;
-+  char *p, c;
-+
-+  for (p = str; *p; p++)
-+    if (*p == '[')
-+      break;
-+
-+  /* allow empty displacement, meaning zero */
-+  if (p[0] == '[')
-+    {
-+      char *end;
-+      for (end = p + 1; *end; end++) ;
-+      if (end[-1] != ']')
-+      return 0;
-+    }
-+
-+  c = *p, *p = 0;
-+  regid = avr32_parse_intreg(str);
-+  if (regid != AVR32_REG_SP)
-+    ret = 0;
-+
-+  *p = c;
-+  return ret;
-+}
-+
-+static int
-+match_cpno(char *str)
-+{
-+  if (strncasecmp(str, "cp", 2) != 0)
-+    return 0;
-+  return 1;
-+}
-+
-+static int
-+match_cpreg(char *str)
-+{
-+  if (strncasecmp(str, "cr", 2) != 0)
-+    return 0;
-+  return 1;
-+}
-+
-+/* We allow complex expressions, and register names may show up as
-+   symbols.  Just make sure immediate expressions are always matched
-+   last.  */
-+#define match_const           match_anything
-+#define match_jmplabel                match_anything
-+#define match_number          match_anything
-+
-+/* Mnemonics that take reglists never accept anything else */
-+#define match_reglist8                match_anything
-+#define match_reglist9                match_anything
-+#define match_reglist16               match_anything
-+#define match_reglist_ldm     match_anything
-+#define match_reglist_cp8     match_anything
-+#define match_reglist_cpd8    match_anything
-+
-+/* Ditto for retval, jospinc and mcall */
-+#define match_retval          match_anything
-+#define match_jospinc         match_anything
-+#define match_mcall           match_anything
-+
-+/* COH is used to select between two different syntaxes */
-+static int
-+match_coh(char *str)
-+{
-+  return strcasecmp(str, "coh") == 0;
-+}
-+
-+static int
-+match_fpreg(char *str)
-+{
-+  unsigned long regid;
-+  char *endptr;
-+
-+  if ((str[0] != 'f' && str[0] != 'F')
-+      || (str[1] != 'r' && str[1] != 'R'))
-+    return 0;
-+
-+  str += 2;
-+  regid = strtoul(str, &endptr, 10);
-+  if (!*str || *endptr)
-+    return 0;
-+
-+  return 1;
-+}
-+
-+static int
-+match_picoreg(char *str)
-+{
-+  int regid;
-+
-+  regid = avr32_parse_picoreg(str);
-+  if (regid < 0)
-+    return 0;
-+  return 1;
-+}
-+
-+#define match_pico_reglist_w  match_anything
-+#define match_pico_reglist_d  match_anything
-+
-+static int
-+match_pico_in(char *str)
-+{
-+  unsigned long regid;
-+  char *end;
-+
-+  if (strncasecmp(str, "in", 2) != 0)
-+    return 0;
-+
-+  str += 2;
-+  regid = strtoul(str, &end, 10);
-+  if (!*str || *end)
-+    return 0;
-+
-+  return 1;
-+}
-+
-+static int
-+match_pico_out0(char *str)
-+{
-+  if (strcasecmp(str, "out0") != 0)
-+    return 0;
-+  return 1;
-+}
-+
-+static int
-+match_pico_out1(char *str)
-+{
-+  if (strcasecmp(str, "out1") != 0)
-+    return 0;
-+  return 1;
-+}
-+
-+static int
-+match_pico_out2(char *str)
-+{
-+  if (strcasecmp(str, "out2") != 0)
-+    return 0;
-+  return 1;
-+}
-+
-+static int
-+match_pico_out3(char *str)
-+{
-+  if (strcasecmp(str, "out3") != 0)
-+    return 0;
-+  return 1;
-+}
-+
-+static void parse_nothing(const struct avr32_operand *op ATTRIBUTE_UNUSED,
-+                        char *str ATTRIBUTE_UNUSED,
-+                        int opindex ATTRIBUTE_UNUSED)
-+{
-+  /* Do nothing (this is used for "match-only" operands like COH) */
-+}
-+
-+static void
-+parse_const(const struct avr32_operand *op, char *str,
-+          int opindex ATTRIBUTE_UNUSED)
-+{
-+  expressionS *exp = &current_insn.immediate;
-+  expressionS *sym_exp;
-+  int slot;
-+  char *save;
-+
-+  pr_debug("parse_const: `%s' (signed: %d, pcrel: %d, align: %d)\n",
-+         str, op->is_signed, op->is_pcrel, op->align_order);
-+
-+  save = input_line_pointer;
-+  input_line_pointer = str;
-+
-+  expression(exp);
-+
-+  slot = current_insn.next_slot++;
-+  current_insn.field_value[slot].align_order = op->align_order;
-+  current_insn.pcrel = op->is_pcrel;
-+
-+  switch (exp->X_op)
-+    {
-+    case O_illegal:
-+      as_bad(_("illegal operand"));
-+      break;
-+    case O_absent:
-+      as_bad(_("missing operand"));
-+      break;
-+    case O_constant:
-+      pr_debug("  -> constant: %ld\n", (long)exp->X_add_number);
-+      current_insn.field_value[slot].value = exp->X_add_number;
-+      break;
-+    case O_uminus:
-+      pr_debug("  -> uminus\n");
-+      sym_exp = symbol_get_value_expression(exp->X_add_symbol);
-+      switch (sym_exp->X_op) {
-+      case O_subtract:
-+      pr_debug("     -> subtract: switching operands\n");
-+      exp->X_op_symbol = sym_exp->X_add_symbol;
-+      exp->X_add_symbol = sym_exp->X_op_symbol;
-+      exp->X_op = O_subtract;
-+      /* TODO: Remove the old X_add_symbol */
-+      break;
-+      default:
-+      as_bad(_("Expression too complex\n"));
-+      break;
-+      }
-+      break;
-+#if 0
-+    case O_subtract:
-+      /* Any expression subtracting a symbol from the current section
-+       can be made PC-relative by adding the right offset.  */
-+      if (S_GET_SEGMENT(exp->X_op_symbol) == now_seg)
-+      current_insn.pcrel = TRUE;
-+      pr_debug("  -> subtract: pcrel? %s\n",
-+             current_insn.pcrel ? "yes" : "no");
-+      /* fall through */
-+#endif
-+    default:
-+      pr_debug("  -> (%p <%d> %p + %d)\n",
-+             exp->X_add_symbol, exp->X_op, exp->X_op_symbol,
-+             exp->X_add_number);
-+      current_insn.field_value[slot].value = 0;
-+      break;
-+    }
-+
-+  input_line_pointer = save;
-+}
-+
-+static void
-+parse_jmplabel(const struct avr32_operand *op, char *str,
-+             int opindex ATTRIBUTE_UNUSED)
-+{
-+  expressionS *exp = &current_insn.immediate;
-+  int slot;
-+  char *save;
-+
-+  pr_debug("parse_jmplabel: `%s' (signed: %d, pcrel: %d, align: %d)\n",
-+         str, op->is_signed, op->is_pcrel, op->align_order);
-+
-+  save = input_line_pointer;
-+  input_line_pointer = str;
-+
-+  expression(exp);
-+
-+  slot = current_insn.next_slot++;
-+  current_insn.field_value[slot].align_order = op->align_order;
-+  current_insn.pcrel = TRUE;
-+
-+  switch (exp->X_op)
-+    {
-+    case O_illegal:
-+      as_bad(_("illegal operand"));
-+      break;
-+    case O_absent:
-+      as_bad(_("missing operand"));
-+      break;
-+    case O_constant:
-+      pr_debug("  -> constant: %ld\n", (long)exp->X_add_number);
-+      current_insn.field_value[slot].value = exp->X_add_number;
-+      current_insn.pcrel = 0;
-+      break;
-+    default:
-+      pr_debug("  -> (%p <%d> %p + %d)\n",
-+             exp->X_add_symbol, exp->X_op, exp->X_op_symbol,
-+             exp->X_add_number);
-+      current_insn.field_value[slot].value = 0;
-+      break;
-+    }
-+
-+  input_line_pointer = save;
-+}
-+
-+static void
-+parse_intreg(const struct avr32_operand *op ATTRIBUTE_UNUSED,
-+           char *str, int opindex ATTRIBUTE_UNUSED)
-+{
-+  int regid, slot;
-+
-+  pr_debug("parse_intreg: `%s'\n", str);
-+
-+  regid = avr32_parse_intreg(str);
-+  assert(regid >= 0);
-+
-+  slot = current_insn.next_slot++;
-+  current_insn.field_value[slot].value = regid;
-+  current_insn.field_value[slot].align_order = op->align_order;
-+}
-+
-+static void
-+parse_intreg_predec(const struct avr32_operand *op, char *str, int opindex)
-+{
-+  parse_intreg(op, str + 2, opindex);
-+}
-+
-+static void
-+parse_intreg_postinc(const struct avr32_operand *op, char *str, int opindex)
-+{
-+  char *p, c;
-+
-+  pr_debug("parse_intreg_postinc: `%s'\n", str);
-+
-+  for (p = str; *p != '+'; p++) ;
-+
-+  c = *p, *p = 0;
-+  parse_intreg(op, str, opindex);
-+  *p = c;
-+}
-+
-+static void
-+parse_intreg_shift(const struct avr32_operand *op ATTRIBUTE_UNUSED,
-+                 char *str, int opindex ATTRIBUTE_UNUSED)
-+{
-+  int regid, slot, shift = 0;
-+  char *p, c;
-+  char shiftop;
-+
-+  pr_debug("parse Ry<<sa: `%s'\n", str);
-+
-+  for (p = str; *p; p++)
-+    if (*p == '<' || *p == '>')
-+      break;
-+
-+  shiftop = *p;
-+
-+  c = *p, *p = 0;
-+  regid = avr32_parse_intreg(str);
-+  assert(regid >= 0);
-+  *p = c;
-+
-+  if (c)
-+    {
-+      if (p[0] != shiftop || p[1] != shiftop)
-+      as_bad(_("expected shift operator in `%s'"), p);
-+      else
-+      {
-+        expressionS exp;
-+        char *saved;
-+
-+        saved = input_line_pointer;
-+        input_line_pointer = p + 2;
-+        expression(&exp);
-+        input_line_pointer = saved;
-+
-+        if (exp.X_op != O_constant)
-+          as_bad(_("shift amount must be a numeric constant"));
-+        else
-+          shift = exp.X_add_number;
-+      }
-+    }
-+
-+  slot = current_insn.next_slot++;
-+  current_insn.field_value[slot].value = regid;
-+  slot = current_insn.next_slot++;
-+  current_insn.field_value[slot].value = shift;
-+}
-+
-+/* The match() function selected the right opcode, so it doesn't
-+   matter which way we shift any more.  */
-+#define parse_intreg_lsl      parse_intreg_shift
-+#define parse_intreg_lsr      parse_intreg_shift
-+
-+static void
-+parse_intreg_part(const struct avr32_operand *op, char *str,
-+                int opindex ATTRIBUTE_UNUSED)
-+{
-+  static const char bparts[] = { 'b', 'l', 'u', 't' };
-+  static const char hparts[] = { 'b', 't' };
-+  unsigned int slot, sel;
-+  int regid;
-+  char *p, c;
-+
-+  pr_debug("parse reg:part `%s'\n", str);
-+
-+  for (p = str; *p; p++)
-+    if (*p == ':')
-+      break;
-+
-+  c = *p, *p = 0;
-+  regid = avr32_parse_intreg(str);
-+  assert(regid >= 0);
-+  *p = c;
-+
-+  assert(c == ':');
-+
-+  if (op->align_order)
-+    {
-+      for (sel = 0; sel < sizeof(hparts); sel++)
-+      if (TOLOWER(p[1]) == hparts[sel])
-+        break;
-+
-+      if (sel >= sizeof(hparts))
-+      {
-+        as_bad(_("invalid halfword selector `%c' (must be either b or t)"),
-+               p[1]);
-+        sel = 0;
-+      }
-+    }
-+  else
-+    {
-+      for (sel = 0; sel < sizeof(bparts); sel++)
-+      if (TOLOWER(p[1]) == bparts[sel])
-+        break;
-+
-+      if (sel >= sizeof(bparts))
-+      {
-+        as_bad(_("invalid byte selector `%c' (must be one of b,l,u,t)"),
-+               p[1]);
-+        sel = 0;
-+      }
-+    }
-+
-+  slot = current_insn.next_slot++;
-+  current_insn.field_value[slot].value = regid;
-+  slot = current_insn.next_slot++;
-+  current_insn.field_value[slot].value = sel;
-+}
-+
-+/* This is the parser for "Rp[displacement]" expressions.  In addition
-+   to the "official" syntax, we accept a label as a replacement for
-+   the register expression.  This syntax implies Rp=PC and the
-+   displacement is the pc-relative distance to the label.  */
-+static void
-+parse_intreg_disp(const struct avr32_operand *op, char *str, int opindex)
-+{
-+  expressionS *exp = &current_insn.immediate;
-+  int slot, regid;
-+  char *save, *p, c;
-+
-+  pr_debug("parse_intreg_disp: `%s' (signed: %d, pcrel: %d, align: %d)\n",
-+         str, op->is_signed, op->is_pcrel, op->align_order);
-+
-+  for (p = str; *p; p++)
-+    if (*p == '[')
-+      break;
-+
-+  slot = current_insn.next_slot++;
-+
-+  /* First, check if we have a valid register either before '[' or as
-+     the sole expression.  If so, we use the Rp[disp] syntax.  */
-+  c = *p, *p = 0;
-+  regid = avr32_parse_intreg(str);
-+  *p = c;
-+
-+  if (regid >= 0)
-+    {
-+      current_insn.field_value[slot].value = regid;
-+
-+      slot = current_insn.next_slot++;
-+      current_insn.field_value[slot].align_order = op->align_order;
-+
-+      if (c == '[')
-+      {
-+        save = input_line_pointer;
-+        input_line_pointer = p + 1;
-+
-+        expression(exp);
-+
-+        if (*input_line_pointer != ']')
-+          as_bad(_("junk after displacement expression"));
-+
-+        input_line_pointer = save;
-+
-+        switch (exp->X_op)
-+          {
-+          case O_illegal:
-+            as_bad(_("illegal displacement expression"));
-+            break;
-+          case O_absent:
-+            as_bad(_("missing displacement expression"));
-+            break;
-+          case O_constant:
-+            pr_debug("  -> constant: %ld\n", exp->X_add_number);
-+            current_insn.field_value[slot].value = exp->X_add_number;
-+            break;
-+#if 0
-+          case O_subtract:
-+            if (S_GET_SEGMENT(exp->X_op_symbol) == now_seg)
-+              current_insn.pcrel = TRUE;
-+            pr_debug("  -> subtract: pcrel? %s\n",
-+                     current_insn.pcrel ? "yes" : "no");
-+            /* fall through */
-+#endif
-+          default:
-+            pr_debug("  -> (%p <%d> %p + %d)\n",
-+                     exp->X_add_symbol, exp->X_op, exp->X_op_symbol,
-+                     exp->X_add_number);
-+            current_insn.field_value[slot].value = 0;
-+          }
-+      }
-+      else
-+      {
-+        exp->X_op = O_constant;
-+        exp->X_add_number = 0;
-+        current_insn.field_value[slot].value = 0;
-+      }
-+    }
-+  else
-+    {
-+      /* Didn't find a valid register.  Try parsing it as a label.  */
-+      current_insn.field_value[slot].value = AVR32_REG_PC;
-+      parse_jmplabel(op, str, opindex);
-+    }
-+}
-+
-+static void
-+parse_intreg_index(const struct avr32_operand *op ATTRIBUTE_UNUSED,
-+                 char *str, int opindex ATTRIBUTE_UNUSED)
-+{
-+  int slot, regid;
-+  char *p, *end, c;
-+
-+  for (p = str; *p; p++)
-+    if (*p == '[')
-+      break;
-+
-+  assert(*p);
-+
-+  c = *p, *p = 0;
-+  regid = avr32_parse_intreg(str);
-+  assert(regid >= 0);
-+  *p = c;
-+
-+  slot = current_insn.next_slot++;
-+  current_insn.field_value[slot].value = regid;
-+
-+  p++;
-+  for (end = p; *end; end++)
-+    if (*end == ']' || *end == '<')
-+      break;
-+
-+  assert(*end);
-+
-+  c = *end, *end = 0;
-+  regid = avr32_parse_intreg(p);
-+  assert(regid >= 0);
-+  *end = c;
-+
-+  slot = current_insn.next_slot++;
-+  current_insn.field_value[slot].value = regid;
-+
-+  slot = current_insn.next_slot++;
-+  current_insn.field_value[slot].value = 0;
-+
-+  if (*end == '<')
-+    {
-+      expressionS exp;
-+      char *save;
-+
-+      p = end + 2;
-+      for (end = p; *end; end++)
-+      if (*end == ']')
-+        break;
-+
-+      assert(*end == ']');
-+
-+      c = *end, *end = 0;
-+      save = input_line_pointer;
-+      input_line_pointer = p;
-+      expression(&exp);
-+
-+      if (*input_line_pointer)
-+      as_bad(_("junk after shift expression"));
-+
-+      *end = c;
-+      input_line_pointer = save;
-+
-+      if (exp.X_op == O_constant)
-+      current_insn.field_value[slot].value = exp.X_add_number;
-+      else
-+      as_bad(_("shift expression too complex"));
-+    }
-+}
-+
-+static void
-+parse_intreg_xindex(const struct avr32_operand *op, char *str, int opindex)
-+{
-+  int slot, regid;
-+  char *p, *end, c;
-+
-+  for (p = str; *p; p++)
-+    if (*p == '[')
-+      break;
-+
-+  assert(*p);
-+
-+  c = *p, *p = 0;
-+  regid = avr32_parse_intreg(str);
-+  assert(regid >= 0);
-+  *p = c;
-+
-+  slot = current_insn.next_slot++;
-+  current_insn.field_value[slot].value = regid;
-+
-+  p++;
-+  for (end = p; *end; end++)
-+    if (*end == '<')
-+      break;
-+
-+  assert(*end);
-+
-+  c = *end, *end = 0;
-+  parse_intreg_part(op, p, opindex);
-+  *end = c;
-+}
-+
-+static void
-+parse_pc_disp(const struct avr32_operand *op, char *str, int opindex)
-+{
-+  char *p, c;
-+
-+  for (p = str; *p; p++)
-+    if (*p == '[')
-+      break;
-+
-+  /* The lddpc instruction comes in two different syntax variants:
-+       lddpc reg, expression
-+       lddpc reg, pc[disp]
-+     If the operand contains a '[', we use the second form.  */
-+  if (*p)
-+    {
-+      int regid;
-+
-+      c = *p, *p = 0;
-+      regid = avr32_parse_intreg(str);
-+      *p = c;
-+      if (regid == AVR32_REG_PC)
-+      {
-+        char *end;
-+
-+        for (end = ++p; *end; end++) ;
-+        if (*(--end) != ']')
-+          as_bad(_("unrecognized form of instruction: `%s'"), str);
-+        else
-+          {
-+            c = *end, *end = 0;
-+            parse_const(op, p, opindex);
-+            *end = c;
-+            current_insn.pcrel = 0;
-+          }
-+      }
-+      else
-+      as_bad(_("unrecognized form of instruction: `%s'"), str);
-+    }
-+  else
-+    {
-+      parse_jmplabel(op, str, opindex);
-+    }
-+}
-+
-+static void parse_sp(const struct avr32_operand *op ATTRIBUTE_UNUSED,
-+                   char *str ATTRIBUTE_UNUSED,
-+                   int opindex ATTRIBUTE_UNUSED)
-+{
-+  int slot;
-+
-+  slot = current_insn.next_slot++;
-+  current_insn.field_value[slot].value = AVR32_REG_SP;
-+}
-+
-+static void
-+parse_sp_disp(const struct avr32_operand *op, char *str, int opindex)
-+{
-+  char *p, c;
-+
-+  for (; *str; str++)
-+    if (*str == '[')
-+      break;
-+
-+  assert(*str);
-+
-+  for (p = ++str; *p; p++)
-+    if (*p == ']')
-+      break;
-+
-+  c = *p, *p = 0;
-+  parse_const(op, str, opindex);
-+  *p = c;
-+}
-+
-+static void
-+parse_cpno(const struct avr32_operand *op ATTRIBUTE_UNUSED, char *str,
-+         int opindex ATTRIBUTE_UNUSED)
-+{
-+  int slot;
-+
-+  str += 2;
-+  if (*str == '#')
-+    str++;
-+  if (*str < '0' || *str > '7' || str[1])
-+    as_bad(_("invalid coprocessor `%s'"), str);
-+
-+  slot = current_insn.next_slot++;
-+  current_insn.field_value[slot].value = *str - '0';
-+}
-+
-+static void
-+parse_cpreg(const struct avr32_operand *op, char *str,
-+          int opindex ATTRIBUTE_UNUSED)
-+{
-+  unsigned int crid;
-+  int slot;
-+  char *endptr;
-+
-+  str += 2;
-+  crid = strtoul(str, &endptr, 10);
-+  if (*endptr || crid > 15 || crid & ((1 << op->align_order) - 1))
-+    as_bad(_("invalid coprocessor register `%s'"), str);
-+
-+  crid >>= op->align_order;
-+
-+  slot = current_insn.next_slot++;
-+  current_insn.field_value[slot].value = crid;
-+}
-+
-+static void
-+parse_number(const struct avr32_operand *op, char *str,
-+           int opindex ATTRIBUTE_UNUSED)
-+{
-+  expressionS exp;
-+  int slot;
-+  char *save;
-+
-+  save = input_line_pointer;
-+  input_line_pointer = str;
-+  expression(&exp);
-+  input_line_pointer = save;
-+
-+  slot = current_insn.next_slot++;
-+  current_insn.field_value[slot].align_order = op->align_order;
-+
-+  if (exp.X_op == O_constant)
-+      current_insn.field_value[slot].value = exp.X_add_number;
-+  else
-+      as_bad(_("invalid numeric expression `%s'"), str);
-+}
-+
-+static void
-+parse_reglist8(const struct avr32_operand *op ATTRIBUTE_UNUSED,
-+             char *str, int opindex ATTRIBUTE_UNUSED)
-+{
-+  unsigned long regmask;
-+  unsigned long value = 0;
-+  int slot;
-+  char *tail;
-+
-+  regmask = avr32_parse_reglist(str, &tail);
-+  if (*tail)
-+    as_bad(_("invalid register list `%s'"), str);
-+  else
-+    {
-+      if (avr32_make_regmask8(regmask, &value))
-+      as_bad(_("register list `%s' doesn't fit"), str);
-+    }
-+
-+  slot = current_insn.next_slot++;
-+  current_insn.field_value[slot].value = value;
-+}
-+
-+static int
-+parse_reglist_tail(char *str, unsigned long regmask)
-+{
-+  expressionS exp;
-+  char *save, *p, c;
-+  int regid;
-+
-+  for (p = str + 1; *p; p++)
-+    if (*p == '=')
-+      break;
-+
-+  if (!*p)
-+    {
-+      as_bad(_("invalid register list `%s'"), str);
-+      return -2;
-+    }
-+
-+  c = *p, *p = 0;
-+  regid = avr32_parse_intreg(str);
-+  *p = c;
-+
-+  if (regid != 12)
-+    {
-+      as_bad(_("invalid register list `%s'"), str);
-+      return -2;
-+    }
-+
-+  /* If we have an assignment, we must pop PC and we must _not_
-+     pop LR or R12 */
-+  if (!(regmask & (1 << AVR32_REG_PC)))
-+    {
-+      as_bad(_("return value specified for non-return instruction"));
-+      return -2;
-+    }
-+  else if (regmask & ((1 << AVR32_REG_R12) | (1 << AVR32_REG_LR)))
-+    {
-+      as_bad(_("can't pop LR or R12 when specifying return value"));
-+      return -2;
-+    }
-+
-+  save = input_line_pointer;
-+  input_line_pointer = p + 1;
-+  expression(&exp);
-+  input_line_pointer = save;
-+
-+  if (exp.X_op != O_constant
-+      || exp.X_add_number < -1
-+      || exp.X_add_number > 1)
-+    {
-+      as_bad(_("invalid return value `%s'"), str);
-+      return -2;
-+    }
-+
-+  return exp.X_add_number;
-+}
-+
-+static void
-+parse_reglist9(const struct avr32_operand *op ATTRIBUTE_UNUSED,
-+             char *str, int opindex ATTRIBUTE_UNUSED)
-+{
-+  unsigned long regmask;
-+  unsigned long value = 0, kbit = 0;
-+  int slot;
-+  char *tail;
-+
-+  regmask = avr32_parse_reglist(str, &tail);
-+  /* printf("parsed reglist16: %04lx, tail: `%s'\n", regmask, tail); */
-+  if (*tail)
-+    {
-+      int retval;
-+
-+      retval = parse_reglist_tail(tail, regmask);
-+
-+      switch (retval)
-+      {
-+      case -1:
-+        regmask |= 1 << AVR32_REG_LR;
-+        break;
-+      case 0:
-+        break;
-+      case 1:
-+        regmask |= 1 << AVR32_REG_R12;
-+        break;
-+      default:
-+        break;
-+      }
-+
-+      kbit = 1;
-+    }
-+
-+  if (avr32_make_regmask8(regmask, &value))
-+    as_bad(_("register list `%s' doesn't fit"), str);
-+
-+
-+  slot = current_insn.next_slot++;
-+  current_insn.field_value[slot].value = (value << 1) | kbit;
-+}
-+
-+static void
-+parse_reglist16(const struct avr32_operand *op ATTRIBUTE_UNUSED,
-+              char *str, int opindex ATTRIBUTE_UNUSED)
-+{
-+  unsigned long regmask;
-+  int slot;
-+  char *tail;
-+
-+  regmask = avr32_parse_reglist(str, &tail);
-+  if (*tail)
-+    as_bad(_("invalid register list `%s'"), str);
-+
-+  slot = current_insn.next_slot++;
-+  current_insn.field_value[slot].value = regmask;
-+}
-+
-+static void
-+parse_reglist_ldm(const struct avr32_operand *op ATTRIBUTE_UNUSED,
-+                char *str, int opindex ATTRIBUTE_UNUSED)
-+{
-+  unsigned long regmask;
-+  int slot, rp, w_bit = 0;
-+  char *tail, *p, c;
-+
-+  for (p = str; *p && *p != ','; p++)
-+    if (*p == '+')
-+      break;
-+
-+  c = *p, *p = 0;
-+  rp = avr32_parse_intreg(str);
-+  *p = c;
-+  if (rp < 0)
-+    {
-+      as_bad(_("invalid destination register in `%s'"), str);
-+      return;
-+    }
-+
-+  if (p[0] == '+' && p[1] == '+')
-+    {
-+      w_bit = 1;
-+      p += 2;
-+    }
-+
-+  if (*p != ',')
-+    {
-+      as_bad(_("expected `,' after destination register in `%s'"), str);
-+      return;
-+    }
-+
-+  str = p + 1;
-+  regmask = avr32_parse_reglist(str, &tail);
-+  if (*tail)
-+    {
-+      int retval;
-+
-+      if (rp != AVR32_REG_SP)
-+      {
-+        as_bad(_("junk at end of line: `%s'"), tail);
-+        return;
-+      }
-+
-+      rp = AVR32_REG_PC;
-+
-+      retval = parse_reglist_tail(tail, regmask);
-+
-+      switch (retval)
-+      {
-+      case -1:
-+        regmask |= 1 << AVR32_REG_LR;
-+        break;
-+      case 0:
-+        break;
-+      case 1:
-+        regmask |= 1 << AVR32_REG_R12;
-+        break;
-+      default:
-+        return;
-+      }
-+    }
-+
-+  slot = current_insn.next_slot++;
-+  current_insn.field_value[slot].value = rp;
-+  slot = current_insn.next_slot++;
-+  current_insn.field_value[slot].value = w_bit;
-+  slot = current_insn.next_slot++;
-+  current_insn.field_value[slot].value = regmask;
-+}
-+
-+static void
-+parse_reglist_cp8(const struct avr32_operand *op ATTRIBUTE_UNUSED,
-+                char *str, int opindex ATTRIBUTE_UNUSED)
-+{
-+  unsigned long regmask;
-+  int slot, h_bit = 0;
-+  char *tail;
-+
-+  regmask = avr32_parse_cpreglist(str, &tail);
-+  if (*tail)
-+    as_bad(_("junk at end of line: `%s'"), tail);
-+  else if (regmask & 0xffUL)
-+    {
-+      if (regmask & 0xff00UL)
-+      as_bad(_("register list `%s' doesn't fit"), str);
-+      regmask &= 0xff;
-+    }
-+  else if (regmask & 0xff00UL)
-+    {
-+      regmask >>= 8;
-+      h_bit = 1;
-+    }
-+  else
-+    as_warn(_("register list is empty"));
-+
-+  slot = current_insn.next_slot++;
-+  current_insn.field_value[slot].value = regmask;
-+  slot = current_insn.next_slot++;
-+  current_insn.field_value[slot].value = h_bit;
-+}
-+
-+static void
-+parse_reglist_cpd8(const struct avr32_operand *op ATTRIBUTE_UNUSED,
-+                 char *str, int opindex ATTRIBUTE_UNUSED)
-+{
-+  unsigned long regmask, regmask_d = 0;
-+  int slot, i;
-+  char *tail;
-+
-+  regmask = avr32_parse_cpreglist(str, &tail);
-+  if (*tail)
-+    as_bad(_("junk at end of line: `%s'"), tail);
-+
-+  for (i = 0; i < 8; i++)
-+    {
-+      if (regmask & 1)
-+      {
-+        if (!(regmask & 2))
-+          {
-+            as_bad(_("register list `%s' doesn't fit"), str);
-+            break;
-+          }
-+        regmask_d |= 1 << i;
-+      }
-+      else if (regmask & 2)
-+      {
-+        as_bad(_("register list `%s' doesn't fit"), str);
-+        break;
-+      }
-+
-+      regmask >>= 2;
-+    }
-+
-+  slot = current_insn.next_slot++;
-+  current_insn.field_value[slot].value = regmask_d;
-+}
-+
-+static void
-+parse_retval(const struct avr32_operand *op ATTRIBUTE_UNUSED,
-+           char *str, int opindex ATTRIBUTE_UNUSED)
-+{
-+  int regid, slot;
-+
-+  regid = avr32_parse_intreg(str);
-+  if (regid < 0)
-+    {
-+      expressionS exp;
-+      char *save;
-+
-+      regid = 0;
-+
-+      save = input_line_pointer;
-+      input_line_pointer = str;
-+      expression(&exp);
-+      input_line_pointer = save;
-+
-+      if (exp.X_op != O_constant)
-+      as_bad(_("invalid return value `%s'"), str);
-+      else
-+      switch (exp.X_add_number)
-+        {
-+        case -1:
-+          regid = AVR32_REG_LR;
-+          break;
-+        case 0:
-+          regid = AVR32_REG_SP;
-+          break;
-+        case 1:
-+          regid = AVR32_REG_PC;
-+          break;
-+        default:
-+          as_bad(_("invalid return value `%s'"), str);
-+          break;
-+        }
-+    }
-+
-+  slot = current_insn.next_slot++;
-+  current_insn.field_value[slot].value = regid;
-+}
-+
-+#define parse_mcall parse_intreg_disp
-+
-+static void
-+parse_jospinc(const struct avr32_operand *op ATTRIBUTE_UNUSED,
-+            char *str, int opindex ATTRIBUTE_UNUSED)
-+{
-+  expressionS exp;
-+  int slot;
-+  char *save;
-+
-+  save = input_line_pointer;
-+  input_line_pointer = str;
-+  expression(&exp);
-+  input_line_pointer = save;
-+
-+  slot = current_insn.next_slot++;
-+
-+  if (exp.X_op == O_constant)
-+    {
-+      if (exp.X_add_number > 0)
-+      exp.X_add_number--;
-+      current_insn.field_value[slot].value = exp.X_add_number;
-+    }
-+  else
-+    as_bad(_("invalid numeric expression `%s'"), str);
-+}
-+
-+#define parse_coh             parse_nothing
-+
-+static void
-+parse_fpreg(const struct avr32_operand *op,
-+          char *str, int opindex ATTRIBUTE_UNUSED)
-+{
-+  unsigned long regid;
-+  int slot;
-+
-+  regid = strtoul(str + 2, NULL, 10);
-+
-+  if ((regid >= 16) || (regid & ((1 << op->align_order) - 1)))
-+    as_bad(_("invalid floating-point register `%s'"), str);
-+
-+  slot = current_insn.next_slot++;
-+  current_insn.field_value[slot].value = regid;
-+  current_insn.field_value[slot].align_order = op->align_order;
-+}
-+
-+static void
-+parse_picoreg(const struct avr32_operand *op,
-+            char *str, int opindex ATTRIBUTE_UNUSED)
-+{
-+  unsigned long regid;
-+  int slot;
-+
-+  regid = avr32_parse_picoreg(str);
-+  if (regid & ((1 << op->align_order) - 1))
-+    as_bad(_("invalid double-word PiCo register `%s'"), str);
-+
-+  slot = current_insn.next_slot++;
-+  current_insn.field_value[slot].value = regid;
-+  current_insn.field_value[slot].align_order = op->align_order;
-+}
-+
-+static void
-+parse_pico_reglist_w(const struct avr32_operand *op ATTRIBUTE_UNUSED,
-+                   char *str, int opindex ATTRIBUTE_UNUSED)
-+{
-+  unsigned long regmask;
-+  int slot, h_bit = 0;
-+  char *tail;
-+
-+  regmask = avr32_parse_pico_reglist(str, &tail);
-+  if (*tail)
-+    as_bad(_("junk at end of line: `%s'"), tail);
-+
-+  if (regmask & 0x00ffUL)
-+    {
-+      if (regmask & 0xff00UL)
-+      as_bad(_("register list `%s' doesn't fit"), str);
-+      regmask &= 0x00ffUL;
-+    }
-+  else if (regmask & 0xff00UL)
-+    {
-+      regmask >>= 8;
-+      h_bit = 1;
-+    }
-+  else
-+    as_warn(_("register list is empty"));
-+
-+  slot = current_insn.next_slot++;
-+  current_insn.field_value[slot].value = regmask;
-+  slot = current_insn.next_slot++;
-+  current_insn.field_value[slot].value = h_bit;
-+}
-+
-+static void
-+parse_pico_reglist_d(const struct avr32_operand *op ATTRIBUTE_UNUSED,
-+                   char *str, int opindex ATTRIBUTE_UNUSED)
-+{
-+  unsigned long regmask, regmask_d = 0;
-+  int slot, i;
-+  char *tail;
-+
-+  regmask = avr32_parse_pico_reglist(str, &tail);
-+  if (*tail)
-+    as_bad(_("junk at end of line: `%s'"), tail);
-+
-+  for (i = 0; i < 8; i++)
-+    {
-+      if (regmask & 1)
-+      {
-+        if (!(regmask & 2))
-+          {
-+            as_bad(_("register list `%s' doesn't fit"), str);
-+            break;
-+          }
-+        regmask_d |= 1 << i;
-+      }
-+      else if (regmask & 2)
-+      {
-+        as_bad(_("register list `%s' doesn't fit"), str);
-+        break;
-+      }
-+
-+      regmask >>= 2;
-+    }
-+
-+  slot = current_insn.next_slot++;
-+  current_insn.field_value[slot].value = regmask_d;
-+}
-+
-+static void
-+parse_pico_in(const struct avr32_operand *op ATTRIBUTE_UNUSED,
-+            char *str, int opindex ATTRIBUTE_UNUSED)
-+{
-+  unsigned long regid;
-+  int slot;
-+
-+  regid = strtoul(str + 2, NULL, 10);
-+
-+  if (regid >= 12)
-+    as_bad(_("invalid PiCo IN register `%s'"), str);
-+
-+  slot = current_insn.next_slot++;
-+  current_insn.field_value[slot].value = regid;
-+  current_insn.field_value[slot].align_order = 0;
-+}
-+
-+#define parse_pico_out0               parse_nothing
-+#define parse_pico_out1               parse_nothing
-+#define parse_pico_out2               parse_nothing
-+#define parse_pico_out3               parse_nothing
-+
-+#define OP(name, sgn, pcrel, align, func) \
-+  { AVR32_OPERAND_##name, sgn, pcrel, align, match_##func, parse_##func }
-+
-+struct avr32_operand avr32_operand_table[] = {
-+  OP(INTREG, 0, 0, 0, intreg),
-+  OP(INTREG_PREDEC, 0, 0, 0, intreg_predec),
-+  OP(INTREG_POSTINC, 0, 0, 0, intreg_postinc),
-+  OP(INTREG_LSL, 0, 0, 0, intreg_lsl),
-+  OP(INTREG_LSR, 0, 0, 0, intreg_lsr),
-+  OP(INTREG_BSEL, 0, 0, 0, intreg_part),
-+  OP(INTREG_HSEL, 0, 0, 1, intreg_part),
-+  OP(INTREG_SDISP, 1, 0, 0, intreg_disp),
-+  OP(INTREG_SDISP_H, 1, 0, 1, intreg_disp),
-+  OP(INTREG_SDISP_W, 1, 0, 2, intreg_disp),
-+  OP(INTREG_UDISP, 0, 0, 0, intreg_disp),
-+  OP(INTREG_UDISP_H, 0, 0, 1, intreg_disp),
-+  OP(INTREG_UDISP_W, 0, 0, 2, intreg_disp),
-+  OP(INTREG_INDEX, 0, 0, 0, intreg_index),
-+  OP(INTREG_XINDEX, 0, 0, 0, intreg_xindex),
-+  OP(DWREG, 0, 0, 1, intreg),
-+  OP(PC_UDISP_W, 0, 1, 2, pc_disp),
-+  OP(SP, 0, 0, 0, sp),
-+  OP(SP_UDISP_W, 0, 0, 2, sp_disp),
-+  OP(CPNO, 0, 0, 0, cpno),
-+  OP(CPREG, 0, 0, 0, cpreg),
-+  OP(CPREG_D, 0, 0, 1, cpreg),
-+  OP(UNSIGNED_CONST, 0, 0, 0, const),
-+  OP(UNSIGNED_CONST_W, 0, 0, 2, const),
-+  OP(SIGNED_CONST, 1, 0, 0, const),
-+  OP(SIGNED_CONST_W, 1, 0, 2, const),
-+  OP(JMPLABEL, 1, 1, 1, jmplabel),
-+  OP(UNSIGNED_NUMBER, 0, 0, 0, number),
-+  OP(UNSIGNED_NUMBER_W, 0, 0, 2, number),
-+  OP(REGLIST8, 0, 0, 0, reglist8),
-+  OP(REGLIST9, 0, 0, 0, reglist9),
-+  OP(REGLIST16, 0, 0, 0, reglist16),
-+  OP(REGLIST_LDM, 0, 0, 0, reglist_ldm),
-+  OP(REGLIST_CP8, 0, 0, 0, reglist_cp8),
-+  OP(REGLIST_CPD8, 0, 0, 0, reglist_cpd8),
-+  OP(RETVAL, 0, 0, 0, retval),
-+  OP(MCALL, 1, 0, 2, mcall),
-+  OP(JOSPINC, 0, 0, 0, jospinc),
-+  OP(COH, 0, 0, 0, coh),
-+  OP(FPREG_S, 0, 0, 0, fpreg),
-+  OP(FPREG_D, 0, 0, 1, fpreg),
-+  OP(PICO_REG_W, 0, 0, 0, picoreg),
-+  OP(PICO_REG_D, 0, 0, 1, picoreg),
-+  OP(PICO_REGLIST_W, 0, 0, 0, pico_reglist_w),
-+  OP(PICO_REGLIST_D, 0, 0, 0, pico_reglist_d),
-+  OP(PICO_IN, 0, 0, 0, pico_in),
-+  OP(PICO_OUT0, 0, 0, 0, pico_out0),
-+  OP(PICO_OUT1, 0, 0, 0, pico_out1),
-+  OP(PICO_OUT2, 0, 0, 0, pico_out2),
-+  OP(PICO_OUT3, 0, 0, 0, pico_out3),
-+};
-+
-+symbolS *
-+md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
-+{
-+  pr_debug("md_undefined_symbol: %s\n", name);
-+  return 0;
-+}
-+
-+struct avr32_relax_type
-+{
-+  long lower_bound;
-+  long upper_bound;
-+  unsigned char align;
-+  unsigned char length;
-+  signed short next;
-+};
-+
-+#define EMPTY { 0, 0, 0, 0, -1 }
-+#define C(lower, upper, align, next)                  \
-+  { (lower), (upper), (align), 2, AVR32_OPC_##next }
-+#define E(lower, upper, align)                                \
-+  { (lower), (upper), (align), 4, -1 }
-+
-+static const struct avr32_relax_type avr32_relax_table[] =
-+  {
-+    /* 0 */
-+    EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-+    EMPTY, EMPTY, EMPTY,
-+    E(0, 65535, 0), E(0, 65535, 0), E(0, 65535, 0), E(0, 65535, 0),
-+    EMPTY,
-+    /* 16 */
-+    EMPTY, EMPTY, EMPTY, EMPTY,
-+
-+    C(-256, 254, 1, BREQ2), C(-256, 254, 1, BRNE2),
-+    C(-256, 254, 1, BRCC2), C(-256, 254, 1, BRCS2),
-+    C(-256, 254, 1, BRGE2), C(-256, 254, 1, BRLT2),
-+    C(-256, 254, 1, BRMI2), C(-256, 254, 1, BRPL2),
-+    E(-2097152, 2097150, 1), E(-2097152, 2097150, 1),
-+    E(-2097152, 2097150, 1), E(-2097152, 2097150, 1),
-+    /* 32 */
-+    E(-2097152, 2097150, 1), E(-2097152, 2097150, 1),
-+    E(-2097152, 2097150, 1), E(-2097152, 2097150, 1),
-+    E(-2097152, 2097150, 1), E(-2097152, 2097150, 1),
-+    E(-2097152, 2097150, 1), E(-2097152, 2097150, 1),
-+    E(-2097152, 2097150, 1), E(-2097152, 2097150, 1),
-+    E(-2097152, 2097150, 1), E(-2097152, 2097150, 1),
-+
-+    EMPTY, EMPTY, EMPTY, EMPTY,
-+    /* 48 */
-+    EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-+    EMPTY, EMPTY, EMPTY,
-+
-+    C(-32, 31, 0, CP_W3), E(-1048576, 1048575, 0),
-+
-+    EMPTY, EMPTY, EMPTY,
-+    /* 64: csrfcz */
-+    EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-+    E(0, 65535, 0), E(0, 65535, 0),
-+    EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-+    E(-32768, 32767, 0),
-+    /* 80: LD_SB2 */
-+    EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-+
-+    C(0, 7, 0, LD_UB4), E(-32768, 32767, 0),
-+
-+    EMPTY,
-+    EMPTY, EMPTY,
-+
-+    C(0, 14, 1, LD_SH4), E(-32768, 32767, 0),
-+
-+    EMPTY, EMPTY, EMPTY,
-+
-+    C(0, 14, 1, LD_UH4),
-+
-+    /* 96: LD_UH4 */
-+    E(-32768, 32767, 0),
-+
-+    EMPTY, EMPTY, EMPTY, EMPTY,
-+
-+    C(0, 124, 2, LD_W4), E(-32768, 32767, 0),
-+
-+    E(0, 1020, 2),    /* LDC_D1 */
-+    EMPTY, EMPTY,
-+    E(0, 1020, 2),    /* LDC_W1 */
-+    EMPTY, EMPTY,
-+    E(0, 16380, 2),   /* LDC0_D */
-+    E(0, 16380, 2),   /* LDC0_W */
-+    EMPTY,
-+
-+    /* 112: LDCM_D_PU */
-+    EMPTY, EMPTY, EMPTY,
-+
-+    C(0, 508, 2, LDDPC_EXT), E(-32768, 32767, 0),
-+
-+    EMPTY,EMPTY, EMPTY,
-+    EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-+
-+    EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-+    /* 134: MACHH_W */
-+    EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-+    E(-131072, 131068, 2),    /* MCALL */
-+    E(0, 1020, 2),            /* MFDR */
-+    E(0, 1020, 2),            /* MFSR */
-+    EMPTY, EMPTY,
-+
-+    C(-128, 127, 0, MOV2), E(-1048576, 1048575, 0),
-+
-+    EMPTY, EMPTY, EMPTY,
-+    EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-+    EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-+
-+    E(-128, 127, 0),          /* MOVEQ2 */
-+    E(-128, 127, 0),          /* MOVNE2 */
-+    E(-128, 127, 0),          /* MOVCC2 */
-+    E(-128, 127, 0),          /* 166: MOVCS2 */
-+    E(-128, 127, 0),          /* MOVGE2 */
-+    E(-128, 127, 0),          /* MOVLT2 */
-+    E(-128, 127, 0),          /* MOVMI2 */
-+    E(-128, 127, 0),          /* MOVPL2 */
-+    E(-128, 127, 0),          /* MOVLS2 */
-+    E(-128, 127, 0),          /* MOVGT2 */
-+    E(-128, 127, 0),          /* MOVLE2 */
-+    E(-128, 127, 0),          /* MOVHI2 */
-+    E(-128, 127, 0),          /* MOVVS2 */
-+    E(-128, 127, 0),          /* MOVVC2 */
-+    E(-128, 127, 0),          /* MOVQS2 */
-+    E(-128, 127, 0),          /* MOVAL2 */
-+
-+    E(0, 1020, 2),            /* MTDR */
-+    E(0, 1020, 2),            /* MTSR */
-+    EMPTY,
-+    EMPTY,
-+    E(-128, 127, 0),          /* MUL3 */
-+    EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-+    EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-+    /* 198: MVCR_W */
-+    EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-+    E(0, 65535, 0), E(0, 65535, 0),
-+    EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-+    EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-+    EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-+    /* 230: PASR_H */
-+    EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-+    EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-+    EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-+    EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-+    /* 262: PUNPCKSB_H */
-+    EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-+
-+    C(-1024, 1022, 1, RCALL2), E(-2097152, 2097150, 1),
-+
-+    EMPTY,
-+    EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-+    EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-+    EMPTY, EMPTY, EMPTY,
-+
-+    C(-1024, 1022, 1, BRAL),
-+
-+    EMPTY, EMPTY, EMPTY,
-+    E(-128, 127, 0),          /* RSUB2 */
-+    /* 294: SATADD_H */
-+    EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-+    EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-+    E(0, 255, 0),             /* SLEEP */
-+    EMPTY, EMPTY,
-+    EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-+    EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-+    /* 326: ST_B2 */
-+    EMPTY, EMPTY,
-+    C(0, 7, 0, ST_B4), E(-32768, 32767, 0),
-+    EMPTY, EMPTY, EMPTY, EMPTY,
-+    E(-32768, 32767, 0),
-+    EMPTY, EMPTY, EMPTY,
-+    C(0, 14, 1, ST_H4), E(-32768, 32767, 0),
-+    EMPTY, EMPTY,
-+    EMPTY,
-+    C(0, 60, 2, ST_W4), E(-32768, 32767, 0),
-+    E(0, 1020, 2),    /* STC_D1 */
-+    EMPTY, EMPTY,
-+    E(0, 1020, 2),    /* STC_W1 */
-+    EMPTY, EMPTY,
-+    E(0, 16380, 2),   /* STC0_D */
-+    E(0, 16380, 2),   /* STC0_W */
-+
-+    EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-+    /* 358: STDSP */
-+    EMPTY, EMPTY,
-+    E(0, 1020, 2),    /* STHH_W1 */
-+    EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-+    EMPTY, EMPTY, EMPTY,
-+    E(-32768, 32767, 0),
-+    C(-512, 508, 2, SUB4),
-+    C(-128, 127, 0, SUB4), E(-1048576, 1048576, 0),
-+    /* SUB{cond} */
-+    E(-128, 127, 0), E(-128, 127, 0), E(-128, 127, 0), E(-128, 127, 0),
-+    E(-128, 127, 0), E(-128, 127, 0), E(-128, 127, 0), E(-128, 127, 0),
-+    E(-128, 127, 0), E(-128, 127, 0), E(-128, 127, 0), E(-128, 127, 0),
-+    E(-128, 127, 0), E(-128, 127, 0), E(-128, 127, 0), E(-128, 127, 0),
-+    /* SUBF{cond} */
-+    E(-128, 127, 0), E(-128, 127, 0), E(-128, 127, 0), E(-128, 127, 0),
-+    E(-128, 127, 0), E(-128, 127, 0), E(-128, 127, 0), E(-128, 127, 0),
-+    E(-128, 127, 0), E(-128, 127, 0), E(-128, 127, 0), E(-128, 127, 0),
-+    E(-128, 127, 0), E(-128, 127, 0), E(-128, 127, 0), E(-128, 127, 0),
-+    EMPTY,
-+
-+    /* 406: SWAP_B */
-+    EMPTY, EMPTY, EMPTY,
-+    E(0, 255, 0),     /* SYNC */
-+    EMPTY, EMPTY, EMPTY, EMPTY,
-+    /* 414: TST */
-+    EMPTY, EMPTY, E(-65536, 65535, 2), E(-65536, 65535, 2), E(-65536, 65535, 2), EMPTY, EMPTY, EMPTY,
-+    /* 422: RSUB{cond} */
-+    E(-128, 127, 0), E(-128, 127, 0), E(-128, 127, 0), E(-128, 127, 0),
-+    E(-128, 127, 0), E(-128, 127, 0), E(-128, 127, 0), E(-128, 127, 0),
-+    E(-128, 127, 0), E(-128, 127, 0), E(-128, 127, 0), E(-128, 127, 0),
-+    E(-128, 127, 0), E(-128, 127, 0), E(-128, 127, 0), E(-128, 127, 0),
-+    /* 436: ADD{cond} */
-+    EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-+    EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-+    /* 454: SUB{cond} */
-+    EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-+    EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-+    /* 472: AND{cond} */
-+    EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-+    EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-+    /* 486: OR{cond} */
-+    EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-+    EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-+    /* 502: EOR{cond} */
-+    EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-+    EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-+    /* 518: LD.w{cond} */
-+    EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-+    EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-+    /* 534: LD.sh{cond} */
-+    EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-+    EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-+    /* 550: LD.uh{cond} */
-+    EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-+    EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-+    /* 566: LD.sb{cond} */
-+    EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-+    EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-+    /* 582: LD.ub{cond} */
-+    EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-+    EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-+    /* 596: ST.w{cond} */
-+    EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-+    EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-+    /* 614: ST.h{cond} */
-+    EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-+    EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-+    /* 630: ST.b{cond} */
-+    EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-+    EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
-+    /* 646: movh */
-+    E(0, 65535, 0)
-+  };
-+
-+#undef E
-+#undef C
-+#undef EMPTY
-+
-+#define AVR32_RS_NONE (-1)
-+
-+#define avr32_rs_size(state) (avr32_relax_table[(state)].length)
-+#define avr32_rs_align(state) (avr32_relax_table[(state)].align)
-+#define relax_more(state) (avr32_relax_table[(state)].next)
-+
-+#define opc_initial_substate(opc) ((opc)->id)
-+
-+static int need_relax(int subtype, offsetT distance)
-+{
-+  offsetT upper_bound, lower_bound;
-+
-+  upper_bound = avr32_relax_table[subtype].upper_bound;
-+  lower_bound = avr32_relax_table[subtype].lower_bound;
-+
-+  if (distance & ((1 << avr32_rs_align(subtype)) - 1))
-+    return 1;
-+  if ((distance > upper_bound) || (distance < lower_bound))
-+    return 1;
-+
-+  return 0;
-+}
-+
-+enum {
-+  LDA_SUBTYPE_MOV1,
-+  LDA_SUBTYPE_MOV2,
-+  LDA_SUBTYPE_SUB,
-+  LDA_SUBTYPE_LDDPC,
-+  LDA_SUBTYPE_LDW,
-+  LDA_SUBTYPE_GOTLOAD,
-+  LDA_SUBTYPE_GOTLOAD_LARGE,
-+};
-+
-+enum {
-+  CALL_SUBTYPE_RCALL1,
-+  CALL_SUBTYPE_RCALL2,
-+  CALL_SUBTYPE_MCALL_CP,
-+  CALL_SUBTYPE_MCALL_GOT,
-+  CALL_SUBTYPE_MCALL_LARGE,
-+};
-+
-+#define LDA_INITIAL_SIZE      (avr32_pic ? 4 : 2)
-+#define CALL_INITIAL_SIZE     2
-+
-+#define need_reloc(sym, seg, pcrel)                                   \
-+  (!(S_IS_DEFINED(sym)                                                        \
-+     && ((pcrel && S_GET_SEGMENT(sym) == seg)                         \
-+       || (!pcrel && S_GET_SEGMENT(sym) == absolute_section)))        \
-+   || S_FORCE_RELOC(sym, 1))
-+
-+/* Return an initial guess of the length by which a fragment must grow to
-+   hold a branch to reach its destination.
-+   Also updates fr_type/fr_subtype as necessary.
-+
-+   Called just before doing relaxation.
-+   Any symbol that is now undefined will not become defined.
-+   The guess for fr_var is ACTUALLY the growth beyond fr_fix.
-+   Whatever we do to grow fr_fix or fr_var contributes to our returned value.
-+   Although it may not be explicit in the frag, pretend fr_var starts with a
-+   0 value.  */
-+
-+static int
-+avr32_default_estimate_size_before_relax (fragS *fragP, segT segment)
-+{
-+  int growth = 0;
-+
-+  assert(fragP);
-+  assert(fragP->fr_symbol);
-+
-+  if (fragP->tc_frag_data.force_extended
-+      || need_reloc(fragP->fr_symbol, segment, fragP->tc_frag_data.pcrel))
-+    {
-+      int largest_state = fragP->fr_subtype;
-+      while (relax_more(largest_state) != AVR32_RS_NONE)
-+      largest_state = relax_more(largest_state);
-+      growth = avr32_rs_size(largest_state) - fragP->fr_var;
-+    }
-+  else
-+    {
-+      growth = avr32_rs_size(fragP->fr_subtype) - fragP->fr_var;
-+    }
-+
-+  pr_debug("%s:%d: md_estimate_size_before_relax: %d\n",
-+         fragP->fr_file, fragP->fr_line, growth);
-+
-+  return growth;
-+}
-+
-+static int
-+avr32_lda_estimate_size_before_relax(fragS *fragP, segT segment ATTRIBUTE_UNUSED)
-+{
-+  return fragP->fr_var - LDA_INITIAL_SIZE;
-+}
-+
-+static int
-+avr32_call_estimate_size_before_relax(fragS *fragP, segT segment ATTRIBUTE_UNUSED)
-+{
-+  return fragP->fr_var - CALL_INITIAL_SIZE;
-+}
-+
-+static int
-+avr32_cpool_estimate_size_before_relax(fragS *fragP,
-+                                     segT segment ATTRIBUTE_UNUSED)
-+{
-+  return fragP->fr_var;
-+}
-+
-+/* This macro may be defined to relax a frag. GAS will call this with the
-+ * segment, the frag, and the change in size of all previous frags;
-+ * md_relax_frag should return the change in size of the frag. */
-+static long
-+avr32_default_relax_frag (segT segment, fragS *fragP, long stretch)
-+{
-+  int state, next_state;
-+  symbolS *symbolP;   /* The target symbol */
-+  long growth = 0;
-+
-+  state = next_state = fragP->fr_subtype;
-+
-+  symbolP = fragP->fr_symbol;
-+
-+  if (fragP->tc_frag_data.force_extended
-+      || need_reloc(symbolP, segment, fragP->tc_frag_data.pcrel))
-+    {
-+      /* Symbol must be resolved by the linker. Emit the largest
-+       possible opcode. */
-+      while (relax_more(next_state) != AVR32_RS_NONE)
-+      next_state = relax_more(next_state);
-+    }
-+  else
-+    {
-+      addressT address;       /* The address of fragP */
-+      addressT target;        /* The address of the target symbol */
-+      offsetT distance;       /* The distance between the insn and the symbol */
-+      fragS *sym_frag;
-+
-+      address = fragP->fr_address;
-+      target = fragP->fr_offset;
-+      symbolP = fragP->fr_symbol;
-+      sym_frag = symbol_get_frag(symbolP);
-+
-+      address += fragP->fr_fix - fragP->fr_var;
-+      target += S_GET_VALUE(symbolP);
-+
-+      if (stretch != 0
-+        && sym_frag->relax_marker != fragP->relax_marker
-+        && S_GET_SEGMENT(symbolP) == segment)
-+      /* if it was correctly aligned before, make sure it stays aligned */
-+      target += stretch & (~0UL << avr32_rs_align(state));
-+
-+      if (fragP->tc_frag_data.pcrel)
-+      distance = target - (address & (~0UL << avr32_rs_align(state)));
-+      else
-+      distance = target;
-+
-+      pr_debug("%s:%d: relax more? 0x%x - 0x%x = 0x%x (%d), align %d\n",
-+             fragP->fr_file, fragP->fr_line, target, address,
-+             distance, distance, avr32_rs_align(state));
-+
-+      if (need_relax(state, distance))
-+      {
-+        if (relax_more(state) != AVR32_RS_NONE)
-+          next_state = relax_more(state);
-+        pr_debug("%s:%d: relax more %d -> %d (%d - %d, align %d)\n",
-+                 fragP->fr_file, fragP->fr_line, state, next_state,
-+                 target, address, avr32_rs_align(state));
-+      }
-+    }
-+
-+  growth = avr32_rs_size(next_state) - avr32_rs_size(state);
-+  fragP->fr_subtype = next_state;
-+
-+  pr_debug("%s:%d: md_relax_frag: growth=%d, subtype=%d, opc=0x%08lx\n",
-+         fragP->fr_file, fragP->fr_line, growth, fragP->fr_subtype,
-+         avr32_opc_table[next_state].value);
-+
-+  return growth;
-+}
-+
-+static long
-+avr32_lda_relax_frag(segT segment, fragS *fragP, long stretch)
-+{
-+  struct cpool *pool= NULL;
-+  unsigned int entry = 0;
-+  addressT address, target;
-+  offsetT distance;
-+  symbolS *symbolP;
-+  fragS *sym_frag;
-+  long old_size, new_size;
-+
-+  symbolP = fragP->fr_symbol;
-+  old_size = fragP->fr_var;
-+  if (!avr32_pic)
-+    {
-+      pool = fragP->tc_frag_data.pool;
-+      entry = fragP->tc_frag_data.pool_entry;
-+    }
-+
-+  address = fragP->fr_address;
-+  address += fragP->fr_fix - LDA_INITIAL_SIZE;
-+
-+  if (!S_IS_DEFINED(symbolP) || S_FORCE_RELOC(symbolP, 1))
-+    goto relax_max;
-+
-+  target = fragP->fr_offset;
-+  sym_frag = symbol_get_frag(symbolP);
-+  target += S_GET_VALUE(symbolP);
-+
-+  if (sym_frag->relax_marker != fragP->relax_marker
-+      && S_GET_SEGMENT(symbolP) == segment)
-+    target += stretch;
-+
-+  distance = target - address;
-+
-+  pr_debug("lda_relax_frag: target: %d, address: %d, var: %d\n",
-+         target, address, fragP->fr_var);
-+
-+  if (!avr32_pic && S_GET_SEGMENT(symbolP) == absolute_section
-+      && target <= 127 && (offsetT)target >= -128)
-+    {
-+      if (fragP->fr_subtype == LDA_SUBTYPE_LDDPC
-+        || fragP->fr_subtype == LDA_SUBTYPE_LDW)
-+      pool->literals[entry].refcount--;
-+      new_size = 2;
-+      fragP->fr_subtype = LDA_SUBTYPE_MOV1;
-+    }
-+  else if (!avr32_pic && S_GET_SEGMENT(symbolP) == absolute_section
-+         && target <= 1048575 && (offsetT)target >= -1048576)
-+    {
-+      if (fragP->fr_subtype == LDA_SUBTYPE_LDDPC
-+        || fragP->fr_subtype == LDA_SUBTYPE_LDW)
-+      pool->literals[entry].refcount--;
-+      new_size = 4;
-+      fragP->fr_subtype = LDA_SUBTYPE_MOV2;
-+    }
-+  else if (!linkrelax && S_GET_SEGMENT(symbolP) == segment
-+         /* the field will be negated, so this is really -(-32768)
-+            and -(32767) */
-+         && distance <= 32768 && distance >= -32767)
-+    {
-+      if (!avr32_pic
-+        && (fragP->fr_subtype == LDA_SUBTYPE_LDDPC
-+            || fragP->fr_subtype == LDA_SUBTYPE_LDW))
-+      pool->literals[entry].refcount--;
-+      new_size = 4;
-+      fragP->fr_subtype = LDA_SUBTYPE_SUB;
-+    }
-+  else
-+    {
-+    relax_max:
-+      if (avr32_pic)
-+      {
-+        if (linkrelax)
-+          {
-+            new_size = 8;
-+            fragP->fr_subtype = LDA_SUBTYPE_GOTLOAD_LARGE;
-+          }
-+        else
-+          {
-+            new_size = 4;
-+            fragP->fr_subtype = LDA_SUBTYPE_GOTLOAD;
-+          }
-+      }
-+      else
-+      {
-+        if (fragP->fr_subtype != LDA_SUBTYPE_LDDPC
-+            && fragP->fr_subtype != LDA_SUBTYPE_LDW)
-+          pool->literals[entry].refcount++;
-+
-+        sym_frag = symbol_get_frag(pool->symbol);
-+        target = (sym_frag->fr_address + sym_frag->fr_fix
-+                  + pool->padding + pool->literals[entry].offset);
-+
-+        pr_debug("cpool sym address: 0x%lx\n",
-+                 sym_frag->fr_address + sym_frag->fr_fix);
-+
-+        know(pool->section == segment);
-+
-+        if (sym_frag->relax_marker != fragP->relax_marker)
-+          target += stretch;
-+
-+        distance = target - address;
-+        if (distance <= 508 && distance >= 0)
-+          {
-+            new_size = 2;
-+            fragP->fr_subtype = LDA_SUBTYPE_LDDPC;
-+          }
-+        else
-+          {
-+            new_size = 4;
-+            fragP->fr_subtype = LDA_SUBTYPE_LDW;
-+          }
-+
-+        pr_debug("lda_relax_frag (cpool): target=0x%lx, address=0x%lx, refcount=%d\n",
-+                 target, address, pool->literals[entry].refcount);
-+      }
-+    }
-+
-+  fragP->fr_var = new_size;
-+
-+  pr_debug("%s:%d: lda: relax pass done. subtype: %d, growth: %ld\n",
-+         fragP->fr_file, fragP->fr_line,
-+         fragP->fr_subtype, new_size - old_size);
-+
-+  return new_size - old_size;
-+}
-+
-+static long
-+avr32_call_relax_frag(segT segment, fragS *fragP, long stretch)
-+{
-+  struct cpool *pool = NULL;
-+  unsigned int entry = 0;
-+  addressT address, target;
-+  offsetT distance;
-+  symbolS *symbolP;
-+  fragS *sym_frag;
-+  long old_size, new_size;
-+
-+  symbolP = fragP->fr_symbol;
-+  old_size = fragP->fr_var;
-+  if (!avr32_pic)
-+    {
-+      pool = fragP->tc_frag_data.pool;
-+      entry = fragP->tc_frag_data.pool_entry;
-+    }
-+
-+  address = fragP->fr_address;
-+  address += fragP->fr_fix - CALL_INITIAL_SIZE;
-+
-+  if (need_reloc(symbolP, segment, 1))
-+    {
-+      pr_debug("call: must emit reloc\n");
-+      goto relax_max;
-+    }
-+
-+  target = fragP->fr_offset;
-+  sym_frag = symbol_get_frag(symbolP);
-+  target += S_GET_VALUE(symbolP);
-+
-+  if (sym_frag->relax_marker != fragP->relax_marker
-+      && S_GET_SEGMENT(symbolP) == segment)
-+    target += stretch;
-+
-+  distance = target - address;
-+
-+  if (distance <= 1022 && distance >= -1024)
-+    {
-+      pr_debug("call: distance is %d, emitting short rcall\n", distance);
-+      if (!avr32_pic && fragP->fr_subtype == CALL_SUBTYPE_MCALL_CP)
-+      pool->literals[entry].refcount--;
-+      new_size = 2;
-+      fragP->fr_subtype = CALL_SUBTYPE_RCALL1;
-+    }
-+  else if (distance <= 2097150 && distance >= -2097152)
-+    {
-+      pr_debug("call: distance is %d, emitting long rcall\n", distance);
-+      if (!avr32_pic && fragP->fr_subtype == CALL_SUBTYPE_MCALL_CP)
-+      pool->literals[entry].refcount--;
-+      new_size = 4;
-+      fragP->fr_subtype = CALL_SUBTYPE_RCALL2;
-+    }
-+  else
-+    {
-+      pr_debug("call: distance %d too far, emitting something big\n", distance);
-+
-+    relax_max:
-+      if (avr32_pic)
-+      {
-+        if (linkrelax)
-+          {
-+            new_size = 10;
-+            fragP->fr_subtype = CALL_SUBTYPE_MCALL_LARGE;
-+          }
-+        else
-+          {
-+            new_size = 4;
-+            fragP->fr_subtype = CALL_SUBTYPE_MCALL_GOT;
-+          }
-+      }
-+      else
-+      {
-+        if (fragP->fr_subtype != CALL_SUBTYPE_MCALL_CP)
-+          pool->literals[entry].refcount++;
-+
-+        new_size = 4;
-+        fragP->fr_subtype = CALL_SUBTYPE_MCALL_CP;
-+      }
-+    }
-+
-+  fragP->fr_var = new_size;
-+
-+  pr_debug("%s:%d: call: relax pass done, growth: %d, fr_var: %d\n",
-+         fragP->fr_file, fragP->fr_line,
-+         new_size - old_size, fragP->fr_var);
-+
-+  return new_size - old_size;
-+}
-+
-+static long
-+avr32_cpool_relax_frag(segT segment ATTRIBUTE_UNUSED,
-+                     fragS *fragP,
-+                     long stretch ATTRIBUTE_UNUSED)
-+{
-+  struct cpool *pool;
-+  addressT address;
-+  long old_size, new_size;
-+  unsigned int entry;
-+
-+  pool = fragP->tc_frag_data.pool;
-+  address = fragP->fr_address + fragP->fr_fix;
-+  old_size = fragP->fr_var;
-+  new_size = 0;
-+
-+  for (entry = 0; entry < pool->next_free_entry; entry++)
-+    {
-+      if (pool->literals[entry].refcount > 0)
-+      {
-+        pool->literals[entry].offset = new_size;
-+        new_size += 4;
-+      }
-+    }
-+
-+  fragP->fr_var = new_size;
-+
-+  return new_size - old_size;
-+}
-+
-+/* *fragP has been relaxed to its final size, and now needs to have
-+   the bytes inside it modified to conform to the new size.
-+
-+   Called after relaxation is finished.
-+   fragP->fr_type == rs_machine_dependent.
-+   fragP->fr_subtype is the subtype of what the address relaxed to.  */
-+
-+static void
-+avr32_default_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
-+                          segT segment ATTRIBUTE_UNUSED,
-+                          fragS *fragP)
-+{
-+  const struct avr32_opcode *opc;
-+  const struct avr32_ifield *ifield;
-+  bfd_reloc_code_real_type r_type;
-+  symbolS *symbolP;
-+  fixS *fixP;
-+  bfd_vma value;
-+  int subtype;
-+
-+  opc = &avr32_opc_table[fragP->fr_subtype];
-+  ifield = opc->fields[opc->var_field];
-+  symbolP = fragP->fr_symbol;
-+  subtype = fragP->fr_subtype;
-+  r_type = opc->reloc_type;
-+
-+  /* Clear the opcode bits and the bits belonging to the relaxed
-+     field.  We assume all other fields stay the same.  */
-+  value = bfd_getb32(fragP->fr_opcode);
-+  value &= ~(opc->mask | ifield->mask);
-+
-+  /* Insert the new opcode */
-+  value |= opc->value;
-+  bfd_putb32(value, fragP->fr_opcode);
-+
-+  fragP->fr_fix += opc->size - fragP->fr_var;
-+
-+  if (fragP->tc_frag_data.reloc_info != AVR32_OPINFO_NONE)
-+    {
-+      switch (fragP->tc_frag_data.reloc_info)
-+      {
-+      case AVR32_OPINFO_HI:
-+        r_type = BFD_RELOC_HI16;
-+        break;
-+      case AVR32_OPINFO_LO:
-+        r_type = BFD_RELOC_LO16;
-+        break;
-+      case AVR32_OPINFO_GOT:
-+        switch (r_type)
-+          {
-+          case BFD_RELOC_AVR32_18W_PCREL:
-+            r_type = BFD_RELOC_AVR32_GOT18SW;
-+            break;
-+          case BFD_RELOC_AVR32_16S:
-+            r_type = BFD_RELOC_AVR32_GOT16S;
-+            break;
-+          default:
-+            BAD_CASE(r_type);
-+            break;
-+          }
-+        break;
-+      default:
-+        BAD_CASE(fragP->tc_frag_data.reloc_info);
-+        break;
-+      }
-+    }
-+
-+  pr_debug("%s:%d: convert_frag: new %s fixup\n",
-+         fragP->fr_file, fragP->fr_line,
-+         bfd_get_reloc_code_name(r_type));
-+
-+#if 1
-+  fixP = fix_new_exp(fragP, fragP->fr_fix - opc->size, opc->size,
-+                   &fragP->tc_frag_data.exp,
-+                   fragP->tc_frag_data.pcrel, r_type);
-+#else
-+  fixP = fix_new(fragP, fragP->fr_fix - opc->size, opc->size, symbolP,
-+               fragP->fr_offset, fragP->tc_frag_data.pcrel, r_type);
-+#endif
-+
-+  /* Revert fix_new brain damage. "dot_value" is the value of PC at
-+     the point of the fixup, relative to the frag address.  fix_new()
-+     and friends think they are only being called during the assembly
-+     pass, not during relaxation or similar, so fx_dot_value, fx_file
-+     and fx_line are all initialized to the wrong value.  But we don't
-+     know the size of the fixup until now, so we really can't live up
-+     to the assumptions these functions make about the target.  What
-+     do these functions think the "where" and "frag" argument mean
-+     anyway?  */
-+  fixP->fx_dot_value = fragP->fr_fix - opc->size;
-+  fixP->fx_file = fragP->fr_file;
-+  fixP->fx_line = fragP->fr_line;
-+
-+  fixP->tc_fix_data.ifield = ifield;
-+  fixP->tc_fix_data.align = avr32_rs_align(subtype);
-+  fixP->tc_fix_data.min = avr32_relax_table[subtype].lower_bound;
-+  fixP->tc_fix_data.max = avr32_relax_table[subtype].upper_bound;
-+}
-+
-+static void
-+avr32_lda_convert_frag(bfd *abfd ATTRIBUTE_UNUSED,
-+                     segT segment ATTRIBUTE_UNUSED,
-+                     fragS *fragP)
-+{
-+  const struct avr32_opcode *opc;
-+  const struct avr32_ifield *ifield;
-+  bfd_reloc_code_real_type r_type;
-+  expressionS exp;
-+  struct cpool *pool;
-+  fixS *fixP;
-+  bfd_vma value;
-+  int regid, pcrel = 0, align = 0;
-+  char *p;
-+
-+  r_type = BFD_RELOC_NONE;
-+  regid = fragP->tc_frag_data.reloc_info;
-+  p = fragP->fr_opcode;
-+  exp.X_add_symbol = fragP->fr_symbol;
-+  exp.X_add_number = fragP->fr_offset;
-+  exp.X_op = O_symbol;
-+
-+  pr_debug("%s:%d: lda_convert_frag, subtype: %d, fix: %d, var: %d, regid: %d\n",
-+         fragP->fr_file, fragP->fr_line,
-+         fragP->fr_subtype, fragP->fr_fix, fragP->fr_var, regid);
-+
-+  switch (fragP->fr_subtype)
-+    {
-+    case LDA_SUBTYPE_MOV1:
-+      opc = &avr32_opc_table[AVR32_OPC_MOV1];
-+      opc->fields[0]->insert(opc->fields[0], p, regid);
-+      ifield = opc->fields[1];
-+      r_type = opc->reloc_type;
-+      break;
-+    case LDA_SUBTYPE_MOV2:
-+      opc = &avr32_opc_table[AVR32_OPC_MOV2];
-+      opc->fields[0]->insert(opc->fields[0], p, regid);
-+      ifield = opc->fields[1];
-+      r_type = opc->reloc_type;
-+      break;
-+    case LDA_SUBTYPE_SUB:
-+      opc = &avr32_opc_table[AVR32_OPC_SUB5];
-+      opc->fields[0]->insert(opc->fields[0], p, regid);
-+      opc->fields[1]->insert(opc->fields[1], p, AVR32_REG_PC);
-+      ifield = opc->fields[2];
-+      r_type = BFD_RELOC_AVR32_16N_PCREL;
-+
-+      /* Pretend that SUB5 isn't a "negated" pcrel expression for now.
-+       We'll have to fix it up later when we know whether to
-+       generate a reloc for it (in which case the linker will negate
-+       it, so we shouldn't). */
-+      pcrel = 1;
-+      break;
-+    case LDA_SUBTYPE_LDDPC:
-+      opc = &avr32_opc_table[AVR32_OPC_LDDPC];
-+      align = 2;
-+      r_type = BFD_RELOC_AVR32_9W_CP;
-+      goto cpool_common;
-+    case LDA_SUBTYPE_LDW:
-+      opc = &avr32_opc_table[AVR32_OPC_LDDPC_EXT];
-+      r_type = BFD_RELOC_AVR32_16_CP;
-+    cpool_common:
-+      opc->fields[0]->insert(opc->fields[0], p, regid);
-+      ifield = opc->fields[1];
-+      pool = fragP->tc_frag_data.pool;
-+      exp.X_add_symbol = pool->symbol;
-+      exp.X_add_number = pool->literals[fragP->tc_frag_data.pool_entry].offset;
-+      pcrel = 1;
-+      break;
-+    case LDA_SUBTYPE_GOTLOAD_LARGE:
-+      /* ld.w Rd, r6[Rd << 2] (last) */
-+      opc = &avr32_opc_table[AVR32_OPC_LD_W5];
-+      bfd_putb32(opc->value, p + 4);
-+      opc->fields[0]->insert(opc->fields[0], p + 4, regid);
-+      opc->fields[1]->insert(opc->fields[1], p + 4, 6);
-+      opc->fields[2]->insert(opc->fields[2], p + 4, regid);
-+      opc->fields[3]->insert(opc->fields[3], p + 4, 2);
-+
-+      /* mov Rd, (got_offset / 4) */
-+      opc = &avr32_opc_table[AVR32_OPC_MOV2];
-+      opc->fields[0]->insert(opc->fields[0], p, regid);
-+      ifield = opc->fields[1];
-+      r_type = BFD_RELOC_AVR32_LDA_GOT;
-+      break;
-+    case LDA_SUBTYPE_GOTLOAD:
-+      opc = &avr32_opc_table[AVR32_OPC_LD_W4];
-+      opc->fields[0]->insert(opc->fields[0], p, regid);
-+      opc->fields[1]->insert(opc->fields[1], p, 6);
-+      ifield = opc->fields[2];
-+      if (r_type == BFD_RELOC_NONE)
-+      r_type = BFD_RELOC_AVR32_GOT16S;
-+      break;
-+    default:
-+      BAD_CASE(fragP->fr_subtype);
-+    }
-+
-+  value = bfd_getb32(p);
-+  value &= ~(opc->mask | ifield->mask);
-+  value |= opc->value;
-+  bfd_putb32(value, p);
-+
-+  fragP->fr_fix += fragP->fr_var - LDA_INITIAL_SIZE;
-+
-+  if (fragP->fr_next
-+      && ((offsetT)(fragP->fr_next->fr_address - fragP->fr_address)
-+        != fragP->fr_fix))
-+    {
-+      fprintf(stderr, "LDA frag: fr_fix is wrong! fragP->fr_var = %ld, r_type = %s\n",
-+            fragP->fr_var, bfd_get_reloc_code_name(r_type));
-+      abort();
-+    }
-+
-+  fixP = fix_new_exp(fragP, fragP->fr_fix - fragP->fr_var, fragP->fr_var,
-+                   &exp, pcrel, r_type);
-+
-+  /* Revert fix_new brain damage. "dot_value" is the value of PC at
-+     the point of the fixup, relative to the frag address.  fix_new()
-+     and friends think they are only being called during the assembly
-+     pass, not during relaxation or similar, so fx_dot_value, fx_file
-+     and fx_line are all initialized to the wrong value.  But we don't
-+     know the size of the fixup until now, so we really can't live up
-+     to the assumptions these functions make about the target.  What
-+     do these functions think the "where" and "frag" argument mean
-+     anyway?  */
-+  fixP->fx_dot_value = fragP->fr_fix - opc->size;
-+  fixP->fx_file = fragP->fr_file;
-+  fixP->fx_line = fragP->fr_line;
-+
-+  fixP->tc_fix_data.ifield = ifield;
-+  fixP->tc_fix_data.align = align;
-+  /* these are only used if the fixup can actually be resolved */
-+  fixP->tc_fix_data.min = -32768;
-+  fixP->tc_fix_data.max = 32767;
-+}
-+
-+static void
-+avr32_call_convert_frag(bfd *abfd ATTRIBUTE_UNUSED,
-+                     segT segment ATTRIBUTE_UNUSED,
-+                     fragS *fragP)
-+{
-+  const struct avr32_opcode *opc = NULL;
-+  const struct avr32_ifield *ifield;
-+  bfd_reloc_code_real_type r_type;
-+  symbolS *symbol;
-+  offsetT offset;
-+  fixS *fixP;
-+  bfd_vma value;
-+  int pcrel = 0, align = 0;
-+  char *p;
-+
-+  symbol = fragP->fr_symbol;
-+  offset = fragP->fr_offset;
-+  r_type = BFD_RELOC_NONE;
-+  p = fragP->fr_opcode;
-+
-+  pr_debug("%s:%d: call_convert_frag, subtype: %d, fix: %d, var: %d\n",
-+         fragP->fr_file, fragP->fr_line,
-+         fragP->fr_subtype, fragP->fr_fix, fragP->fr_var);
-+
-+  switch (fragP->fr_subtype)
-+    {
-+    case CALL_SUBTYPE_RCALL1:
-+      opc = &avr32_opc_table[AVR32_OPC_RCALL1];
-+      /* fall through */
-+    case CALL_SUBTYPE_RCALL2:
-+      if (!opc)
-+      opc = &avr32_opc_table[AVR32_OPC_RCALL2];
-+      ifield = opc->fields[0];
-+      r_type = opc->reloc_type;
-+      pcrel = 1;
-+      align = 1;
-+      break;
-+    case CALL_SUBTYPE_MCALL_CP:
-+      opc = &avr32_opc_table[AVR32_OPC_MCALL];
-+      opc->fields[0]->insert(opc->fields[0], p, AVR32_REG_PC);
-+      ifield = opc->fields[1];
-+      r_type = BFD_RELOC_AVR32_CPCALL;
-+      symbol = fragP->tc_frag_data.pool->symbol;
-+      offset = fragP->tc_frag_data.pool->literals[fragP->tc_frag_data.pool_entry].offset;
-+      assert(fragP->tc_frag_data.pool->literals[fragP->tc_frag_data.pool_entry].refcount > 0);
-+      pcrel = 1;
-+      align = 2;
-+      break;
-+    case CALL_SUBTYPE_MCALL_GOT:
-+      opc = &avr32_opc_table[AVR32_OPC_MCALL];
-+      opc->fields[0]->insert(opc->fields[0], p, 6);
-+      ifield = opc->fields[1];
-+      r_type = BFD_RELOC_AVR32_GOT18SW;
-+      break;
-+    case CALL_SUBTYPE_MCALL_LARGE:
-+      assert(fragP->fr_var == 10);
-+      /* ld.w lr, r6[lr << 2] */
-+      opc = &avr32_opc_table[AVR32_OPC_LD_W5];
-+      bfd_putb32(opc->value, p + 4);
-+      opc->fields[0]->insert(opc->fields[0], p + 4, AVR32_REG_LR);
-+      opc->fields[1]->insert(opc->fields[1], p + 4, 6);
-+      opc->fields[2]->insert(opc->fields[2], p + 4, AVR32_REG_LR);
-+      opc->fields[3]->insert(opc->fields[3], p + 4, 2);
-+
-+      /* icall lr */
-+      opc = &avr32_opc_table[AVR32_OPC_ICALL];
-+      bfd_putb16(opc->value >> 16, p + 8);
-+      opc->fields[0]->insert(opc->fields[0], p + 8, AVR32_REG_LR);
-+
-+      /* mov lr, (got_offset / 4) */
-+      opc = &avr32_opc_table[AVR32_OPC_MOV2];
-+      opc->fields[0]->insert(opc->fields[0], p, AVR32_REG_LR);
-+      ifield = opc->fields[1];
-+      r_type = BFD_RELOC_AVR32_GOTCALL;
-+      break;
-+    default:
-+      BAD_CASE(fragP->fr_subtype);
-+    }
-+
-+  /* Insert the opcode and clear the variable ifield */
-+  value = bfd_getb32(p);
-+  value &= ~(opc->mask | ifield->mask);
-+  value |= opc->value;
-+  bfd_putb32(value, p);
-+
-+  fragP->fr_fix += fragP->fr_var - CALL_INITIAL_SIZE;
-+
-+  if (fragP->fr_next
-+      && ((offsetT)(fragP->fr_next->fr_address - fragP->fr_address)
-+        != fragP->fr_fix))
-+    {
-+      fprintf(stderr, "%s:%d: fr_fix %lu is wrong! fr_var=%lu, r_type=%s\n",
-+            fragP->fr_file, fragP->fr_line,
-+            fragP->fr_fix, fragP->fr_var, bfd_get_reloc_code_name(r_type));
-+      fprintf(stderr, "fr_fix should be %ld. next frag is %s:%d\n",
-+            (offsetT)(fragP->fr_next->fr_address - fragP->fr_address),
-+            fragP->fr_next->fr_file, fragP->fr_next->fr_line);
-+    }
-+
-+  fixP = fix_new(fragP, fragP->fr_fix - fragP->fr_var, fragP->fr_var,
-+               symbol, offset, pcrel, r_type);
-+
-+  /* Revert fix_new brain damage. "dot_value" is the value of PC at
-+     the point of the fixup, relative to the frag address.  fix_new()
-+     and friends think they are only being called during the assembly
-+     pass, not during relaxation or similar, so fx_dot_value, fx_file
-+     and fx_line are all initialized to the wrong value.  But we don't
-+     know the size of the fixup until now, so we really can't live up
-+     to the assumptions these functions make about the target.  What
-+     do these functions think the "where" and "frag" argument mean
-+     anyway?  */
-+  fixP->fx_dot_value = fragP->fr_fix - opc->size;
-+  fixP->fx_file = fragP->fr_file;
-+  fixP->fx_line = fragP->fr_line;
-+
-+  fixP->tc_fix_data.ifield = ifield;
-+  fixP->tc_fix_data.align = align;
-+  /* these are only used if the fixup can actually be resolved */
-+  fixP->tc_fix_data.min = -2097152;
-+  fixP->tc_fix_data.max = 2097150;
-+}
-+
-+static void
-+avr32_cpool_convert_frag(bfd *abfd ATTRIBUTE_UNUSED,
-+                       segT segment ATTRIBUTE_UNUSED,
-+                       fragS *fragP)
-+{
-+  struct cpool *pool;
-+  addressT address;
-+  unsigned int entry;
-+  char *p;
-+  char sym_name[20];
-+
-+  /* Did we get rid of the frag altogether? */
-+  if (!fragP->fr_var)
-+    return;
-+
-+  pool = fragP->tc_frag_data.pool;
-+  address = fragP->fr_address + fragP->fr_fix;
-+  p = fragP->fr_literal + fragP->fr_fix;
-+
-+  sprintf(sym_name, "$$cp_\002%x", pool->id);
-+  symbol_locate(pool->symbol, sym_name, pool->section, fragP->fr_fix, fragP);
-+  symbol_table_insert(pool->symbol);
-+
-+  for (entry = 0; entry < pool->next_free_entry; entry++)
-+    {
-+      if (pool->literals[entry].refcount > 0)
-+      {
-+        fix_new_exp(fragP, fragP->fr_fix, 4, &pool->literals[entry].exp,
-+                    FALSE, BFD_RELOC_AVR32_32_CPENT);
-+        fragP->fr_fix += 4;
-+      }
-+    }
-+}
-+
-+static struct avr32_relaxer avr32_default_relaxer = {
-+  .estimate_size      = avr32_default_estimate_size_before_relax,
-+  .relax_frag         = avr32_default_relax_frag,
-+  .convert_frag               = avr32_default_convert_frag,
-+};
-+static struct avr32_relaxer avr32_lda_relaxer = {
-+  .estimate_size      = avr32_lda_estimate_size_before_relax,
-+  .relax_frag         = avr32_lda_relax_frag,
-+  .convert_frag               = avr32_lda_convert_frag,
-+};
-+static struct avr32_relaxer avr32_call_relaxer = {
-+  .estimate_size      = avr32_call_estimate_size_before_relax,
-+  .relax_frag         = avr32_call_relax_frag,
-+  .convert_frag               = avr32_call_convert_frag,
-+};
-+static struct avr32_relaxer avr32_cpool_relaxer = {
-+  .estimate_size      = avr32_cpool_estimate_size_before_relax,
-+  .relax_frag         = avr32_cpool_relax_frag,
-+  .convert_frag               = avr32_cpool_convert_frag,
-+};
-+
-+static void s_cpool(int arg ATTRIBUTE_UNUSED)
-+{
-+  struct cpool *pool;
-+  unsigned int max_size;
-+  char *buf;
-+
-+  pool = find_cpool(now_seg, now_subseg);
-+  if (!pool || !pool->symbol || pool->next_free_entry == 0)
-+    return;
-+
-+  /* Make sure the constant pool is properly aligned */
-+  frag_align_code(2, 0);
-+  if (bfd_get_section_alignment(stdoutput, pool->section) < 2)
-+    bfd_set_section_alignment(stdoutput, pool->section, 2);
-+
-+  /* Assume none of the entries are discarded, and that we need the
-+     maximum amount of alignment.  But we're not going to allocate
-+     anything up front. */
-+  max_size = pool->next_free_entry * 4 + 2;
-+  frag_grow(max_size);
-+  buf = frag_more(0);
-+
-+  frag_now->tc_frag_data.relaxer = &avr32_cpool_relaxer;
-+  frag_now->tc_frag_data.pool = pool;
-+
-+  symbol_set_frag(pool->symbol, frag_now);
-+
-+  /* Assume zero initial size, allowing other relaxers to be
-+     optimistic about things.  */
-+  frag_var(rs_machine_dependent, max_size, 0,
-+         0, pool->symbol, 0, NULL);
-+
-+  /* Mark the pool as empty.  */
-+  pool->used = 1;
-+}
-+
-+/* The location from which a PC relative jump should be calculated,
-+   given a PC relative reloc.  */
-+
-+long
-+md_pcrel_from_section (fixS *fixP, segT sec)
-+{
-+  pr_debug("pcrel_from_section, fx_offset = %d\n", fixP->fx_offset);
-+
-+  if (fixP->fx_addsy != NULL
-+      && (! S_IS_DEFINED (fixP->fx_addsy)
-+          || S_GET_SEGMENT (fixP->fx_addsy) != sec
-+        || S_FORCE_RELOC(fixP->fx_addsy, 1)))
-+    {
-+      pr_debug("Unknown pcrel symbol: %s\n", S_GET_NAME(fixP->fx_addsy));
-+
-+      /* The symbol is undefined (or is defined but not in this section).
-+       Let the linker figure it out.  */
-+      return 0;
-+    }
-+
-+  pr_debug("pcrel from %x + %x, symbol: %s (%x)\n",
-+         fixP->fx_frag->fr_address, fixP->fx_where,
-+         fixP->fx_addsy?S_GET_NAME(fixP->fx_addsy):"(null)",
-+         fixP->fx_addsy?S_GET_VALUE(fixP->fx_addsy):0);
-+
-+  return ((fixP->fx_frag->fr_address + fixP->fx_where)
-+        & (~0UL << fixP->tc_fix_data.align));
-+}
-+
-+valueT
-+md_section_align (segT segment, valueT size)
-+{
-+  int align = bfd_get_section_alignment (stdoutput, segment);
-+  return ((size + (1 << align) - 1) & (-1 << align));
-+}
-+
-+static int syntax_matches(const struct avr32_syntax *syntax,
-+                        char *str)
-+{
-+  int i;
-+
-+  pr_debug("syntax %d matches `%s'?\n", syntax->id, str);
-+
-+  if (syntax->nr_operands < 0)
-+    {
-+      struct avr32_operand *op;
-+      int optype;
-+
-+      for (i = 0; i < (-syntax->nr_operands - 1); i++)
-+      {
-+        char *p;
-+        char c;
-+
-+        optype = syntax->operand[i];
-+        assert(optype < AVR32_NR_OPERANDS);
-+        op = &avr32_operand_table[optype];
-+
-+        for (p = str; *p; p++)
-+          if (*p == ',')
-+            break;
-+
-+        if (p == str)
-+          return 0;
-+
-+        c = *p;
-+        *p = 0;
-+
-+        if (!op->match(str))
-+          {
-+            *p = c;
-+            return 0;
-+          }
-+
-+        str = p;
-+        *p = c;
-+        if (c)
-+          str++;
-+      }
-+
-+      optype = syntax->operand[i];
-+      assert(optype < AVR32_NR_OPERANDS);
-+      op = &avr32_operand_table[optype];
-+
-+      if (!op->match(str))
-+      return 0;
-+      return 1;
-+    }
-+
-+  for (i = 0; i < syntax->nr_operands; i++)
-+    {
-+      struct avr32_operand *op;
-+      int optype = syntax->operand[i];
-+      char *p;
-+      char c;
-+
-+      assert(optype < AVR32_NR_OPERANDS);
-+      op = &avr32_operand_table[optype];
-+
-+      for (p = str; *p; p++)
-+      if (*p == ',')
-+        break;
-+
-+      if (p == str)
-+      return 0;
-+
-+      c = *p;
-+      *p = 0;
-+
-+      if (!op->match(str))
-+      {
-+        *p = c;
-+        return 0;
-+      }
-+
-+      str = p;
-+      *p = c;
-+      if (c)
-+      str++;
-+    }
-+
-+  if (*str == '\0')
-+    return 1;
-+
-+  if ((*str == 'e' || *str == 'E') && !str[1])
-+    return 1;
-+
-+  return 0;
-+}
-+
-+static int parse_operands(char *str)
-+{
-+  int i;
-+
-+  if (current_insn.syntax->nr_operands < 0)
-+    {
-+      int optype;
-+      struct avr32_operand *op;
-+
-+      for (i = 0; i < (-current_insn.syntax->nr_operands - 1); i++)
-+      {
-+        char *p;
-+        char c;
-+
-+        optype = current_insn.syntax->operand[i];
-+        op = &avr32_operand_table[optype];
-+
-+        for (p = str; *p; p++)
-+          if (*p == ',')
-+            break;
-+
-+        assert(p != str);
-+
-+        c = *p, *p = 0;
-+        op->parse(op, str, i);
-+        *p = c;
-+
-+        str = p;
-+        if (c) str++;
-+      }
-+
-+      /* give the rest of the line to the last operand */
-+      optype = current_insn.syntax->operand[i];
-+      op = &avr32_operand_table[optype];
-+      op->parse(op, str, i);
-+    }
-+  else
-+    {
-+      for (i = 0; i < current_insn.syntax->nr_operands; i++)
-+      {
-+        int optype = current_insn.syntax->operand[i];
-+        struct avr32_operand *op = &avr32_operand_table[optype];
-+        char *p;
-+        char c;
-+
-+        skip_whitespace(str);
-+
-+        for (p = str; *p; p++)
-+          if (*p == ',')
-+            break;
-+
-+        assert(p != str);
-+
-+        c = *p, *p = 0;
-+        op->parse(op, str, i);
-+        *p = c;
-+
-+        str = p;
-+        if (c) str++;
-+      }
-+
-+      if (*str == 'E' || *str == 'e')
-+      current_insn.force_extended = 1;
-+    }
-+
-+  return 0;
-+}
-+
-+static const char *
-+finish_insn(const struct avr32_opcode *opc)
-+{
-+  expressionS *exp = &current_insn.immediate;
-+  unsigned int i;
-+  int will_relax = 0;
-+  char *buf;
-+
-+  assert(current_insn.next_slot == opc->nr_fields);
-+
-+  pr_debug("%s:%d: finish_insn: trying opcode %d\n",
-+         frag_now->fr_file, frag_now->fr_line, opc->id);
-+
-+  /* Go through the relaxation stage for all instructions that can
-+     possibly take a symbolic immediate.  The relax code will take
-+     care of range checking and alignment.  */
-+  if (opc->var_field != -1)
-+    {
-+      int substate, largest_substate;
-+      symbolS *sym;
-+      offsetT off;
-+
-+      will_relax = 1;
-+      substate = largest_substate = opc_initial_substate(opc);
-+
-+      while (relax_more(largest_substate) != AVR32_RS_NONE)
-+      largest_substate = relax_more(largest_substate);
-+
-+      pr_debug("will relax. initial substate: %d (size %d), largest substate: %d (size %d)\n",
-+             substate, avr32_rs_size(substate),
-+             largest_substate, avr32_rs_size(largest_substate));
-+
-+      /* make sure we have enough room for the largest possible opcode */
-+      frag_grow(avr32_rs_size(largest_substate));
-+      buf = frag_more(opc->size);
-+
-+      dwarf2_emit_insn(opc->size);
-+
-+      frag_now->tc_frag_data.reloc_info = AVR32_OPINFO_NONE;
-+      frag_now->tc_frag_data.pcrel = current_insn.pcrel;
-+      frag_now->tc_frag_data.force_extended = current_insn.force_extended;
-+      frag_now->tc_frag_data.relaxer = &avr32_default_relaxer;
-+
-+      if (exp->X_op == O_hi)
-+      {
-+        frag_now->tc_frag_data.reloc_info = AVR32_OPINFO_HI;
-+        exp->X_op = exp->X_md;
-+      }
-+      else if (exp->X_op == O_lo)
-+      {
-+        frag_now->tc_frag_data.reloc_info = AVR32_OPINFO_LO;
-+        exp->X_op = exp->X_md;
-+      }
-+      else if (exp->X_op == O_got)
-+      {
-+        frag_now->tc_frag_data.reloc_info = AVR32_OPINFO_GOT;
-+        exp->X_op = O_symbol;
-+      }
-+
-+#if 0
-+      if ((opc->reloc_type == BFD_RELOC_AVR32_SUB5)
-+        && exp->X_op == O_subtract)
-+      {
-+        symbolS *tmp;
-+        tmp = exp->X_add_symbol;
-+        exp->X_add_symbol = exp->X_op_symbol;
-+        exp->X_op_symbol = tmp;
-+      }
-+#endif
-+
-+      frag_now->tc_frag_data.exp = current_insn.immediate;
-+
-+      sym = exp->X_add_symbol;
-+      off = exp->X_add_number;
-+      if (exp->X_op != O_symbol)
-+      {
-+        sym = make_expr_symbol(exp);
-+        off = 0;
-+      }
-+
-+      frag_var(rs_machine_dependent,
-+             avr32_rs_size(largest_substate) - opc->size,
-+             opc->size,
-+             substate, sym, off, buf);
-+    }
-+  else
-+    {
-+      assert(avr32_rs_size(opc_initial_substate(opc)) == 0);
-+
-+      /* Make sure we always have room for another whole word, as the ifield
-+       inserters can only write words. */
-+      frag_grow(4);
-+      buf = frag_more(opc->size);
-+      dwarf2_emit_insn(opc->size);
-+    }
-+
-+  assert(!(opc->value & ~opc->mask));
-+
-+  pr_debug("inserting opcode: 0x%lx\n", opc->value);
-+  bfd_putb32(opc->value, buf);
-+
-+  for (i = 0; i < opc->nr_fields; i++)
-+    {
-+      const struct avr32_ifield *f = opc->fields[i];
-+      const struct avr32_ifield_data *fd = &current_insn.field_value[i];
-+
-+      pr_debug("inserting field: 0x%lx & 0x%lx\n",
-+             fd->value >> fd->align_order, f->mask);
-+
-+      f->insert(f, buf, fd->value >> fd->align_order);
-+    }
-+
-+  assert(will_relax || !current_insn.immediate.X_add_symbol);
-+  return NULL;
-+}
-+
-+static const char *
-+finish_alias(const struct avr32_alias *alias)
-+{
-+  const struct avr32_opcode *opc;
-+  struct {
-+    unsigned long value;
-+    unsigned long align;
-+  } mapped_operand[AVR32_MAX_OPERANDS];
-+  unsigned int i;
-+
-+  opc = alias->opc;
-+
-+  /* Remap the operands from the alias to the real opcode */
-+  for (i = 0; i < opc->nr_fields; i++)
-+    {
-+      if (alias->operand_map[i].is_opindex)
-+      {
-+        struct avr32_ifield_data *fd;
-+        fd = &current_insn.field_value[alias->operand_map[i].value];
-+        mapped_operand[i].value = fd->value;
-+        mapped_operand[i].align = fd->align_order;
-+      }
-+      else
-+      {
-+        mapped_operand[i].value = alias->operand_map[i].value;
-+        mapped_operand[i].align = 0;
-+      }
-+    }
-+
-+  for (i = 0; i < opc->nr_fields; i++)
-+    {
-+      current_insn.field_value[i].value = mapped_operand[i].value;
-+      if (opc->id == AVR32_OPC_COP)
-+      current_insn.field_value[i].align_order = 0;
-+      else
-+      current_insn.field_value[i].align_order
-+        = mapped_operand[i].align;
-+    }
-+
-+  current_insn.next_slot = opc->nr_fields;
-+
-+  return finish_insn(opc);
-+}
-+
-+static const char *
-+finish_lda(const struct avr32_syntax *syntax ATTRIBUTE_UNUSED)
-+{
-+  expressionS *exp = &current_insn.immediate;
-+  relax_substateT initial_subtype;
-+  symbolS *sym;
-+  offsetT off;
-+  int initial_size, max_size;
-+  char *buf;
-+
-+  initial_size = LDA_INITIAL_SIZE;
-+
-+  if (avr32_pic)
-+    {
-+      initial_subtype = LDA_SUBTYPE_SUB;
-+      if (linkrelax)
-+      max_size = 8;
-+      else
-+      max_size = 4;
-+    }
-+  else
-+    {
-+      initial_subtype = LDA_SUBTYPE_MOV1;
-+      max_size = 4;
-+    }
-+
-+  frag_grow(max_size);
-+  buf = frag_more(initial_size);
-+  dwarf2_emit_insn(initial_size);
-+
-+  if (exp->X_op == O_symbol)
-+    {
-+      sym = exp->X_add_symbol;
-+      off = exp->X_add_number;
-+    }
-+  else
-+    {
-+      sym = make_expr_symbol(exp);
-+      off = 0;
-+    }
-+
-+  frag_now->tc_frag_data.reloc_info = current_insn.field_value[0].value;
-+  frag_now->tc_frag_data.relaxer = &avr32_lda_relaxer;
-+
-+  if (!avr32_pic)
-+    {
-+      /* The relaxer will bump the refcount if necessary */
-+      frag_now->tc_frag_data.pool
-+      = add_to_cpool(exp, &frag_now->tc_frag_data.pool_entry, 0);
-+    }
-+
-+  frag_var(rs_machine_dependent, max_size - initial_size,
-+         initial_size, initial_subtype, sym, off, buf);
-+
-+  return NULL;
-+}
-+
-+static const char *
-+finish_call(const struct avr32_syntax *syntax ATTRIBUTE_UNUSED)
-+{
-+  expressionS *exp = &current_insn.immediate;
-+  symbolS *sym;
-+  offsetT off;
-+  int initial_size, max_size;
-+  char *buf;
-+
-+  initial_size = CALL_INITIAL_SIZE;
-+
-+  if (avr32_pic)
-+    {
-+      if (linkrelax)
-+      max_size = 10;
-+      else
-+      max_size = 4;
-+    }
-+  else
-+    max_size = 4;
-+
-+  frag_grow(max_size);
-+  buf = frag_more(initial_size);
-+  dwarf2_emit_insn(initial_size);
-+
-+  frag_now->tc_frag_data.relaxer = &avr32_call_relaxer;
-+
-+  if (exp->X_op == O_symbol)
-+    {
-+      sym = exp->X_add_symbol;
-+      off = exp->X_add_number;
-+    }
-+  else
-+    {
-+      sym = make_expr_symbol(exp);
-+      off = 0;
-+    }
-+
-+  if (!avr32_pic)
-+    {
-+      /* The relaxer will bump the refcount if necessary */
-+      frag_now->tc_frag_data.pool
-+      = add_to_cpool(exp, &frag_now->tc_frag_data.pool_entry, 0);
-+    }
-+
-+  frag_var(rs_machine_dependent, max_size - initial_size,
-+         initial_size, CALL_SUBTYPE_RCALL1, sym, off, buf);
-+
-+  return NULL;
-+}
-+
-+void
-+md_begin (void)
-+{
-+  unsigned long flags = 0;
-+  int i;
-+
-+  avr32_mnemonic_htab = hash_new();
-+
-+  if (!avr32_mnemonic_htab)
-+    as_fatal(_("virtual memory exhausted"));
-+
-+  for (i = 0; i < AVR32_NR_MNEMONICS; i++)
-+    {
-+      hash_insert(avr32_mnemonic_htab, avr32_mnemonic_table[i].name,
-+                (void *)&avr32_mnemonic_table[i]);
-+    }
-+
-+  if (linkrelax)
-+    flags |= EF_AVR32_LINKRELAX;
-+  if (avr32_pic)
-+    flags |= EF_AVR32_PIC;
-+
-+  bfd_set_private_flags(stdoutput, flags);
-+
-+#ifdef OPC_CONSISTENCY_CHECK
-+  if (sizeof(avr32_operand_table)/sizeof(avr32_operand_table[0])
-+      < AVR32_NR_OPERANDS)
-+    as_fatal(_("operand table is incomplete"));
-+
-+  for (i = 0; i < AVR32_NR_OPERANDS; i++)
-+    if (avr32_operand_table[i].id != i)
-+      as_fatal(_("operand table inconsistency found at index %d\n"), i);
-+  pr_debug("%d operands verified\n", AVR32_NR_OPERANDS);
-+
-+  for (i = 0; i < AVR32_NR_IFIELDS; i++)
-+    if (avr32_ifield_table[i].id != i)
-+      as_fatal(_("ifield table inconsistency found at index %d\n"), i);
-+  pr_debug("%d instruction fields verified\n", AVR32_NR_IFIELDS);
-+
-+  for (i = 0; i < AVR32_NR_OPCODES; i++)
-+    {
-+      if (avr32_opc_table[i].id != i)
-+      as_fatal(_("opcode table inconsistency found at index %d\n"), i);
-+      if ((avr32_opc_table[i].var_field == -1
-+         && avr32_relax_table[i].length != 0)
-+        || (avr32_opc_table[i].var_field != -1
-+            && avr32_relax_table[i].length == 0))
-+      as_fatal(_("relax table inconsistency found at index %d\n"), i);
-+    }
-+  pr_debug("%d opcodes verified\n", AVR32_NR_OPCODES);
-+
-+  for (i = 0; i < AVR32_NR_SYNTAX; i++)
-+    if (avr32_syntax_table[i].id != i)
-+      as_fatal(_("syntax table inconsistency found at index %d\n"), i);
-+  pr_debug("%d syntax variants verified\n", AVR32_NR_SYNTAX);
-+
-+  for (i = 0; i < AVR32_NR_ALIAS; i++)
-+    if (avr32_alias_table[i].id != i)
-+      as_fatal(_("alias table inconsistency found at index %d\n"), i);
-+  pr_debug("%d aliases verified\n", AVR32_NR_ALIAS);
-+
-+  for (i = 0; i < AVR32_NR_MNEMONICS; i++)
-+    if (avr32_mnemonic_table[i].id != i)
-+      as_fatal(_("mnemonic table inconsistency found at index %d\n"), i);
-+  pr_debug("%d mnemonics verified\n", AVR32_NR_MNEMONICS);
-+#endif
-+}
-+
-+void
-+md_assemble (char *str)
-+{
-+  struct avr32_mnemonic *mnemonic;
-+  char *p, c;
-+
-+  memset(&current_insn, 0, sizeof(current_insn));
-+  current_insn.immediate.X_op = O_constant;
-+
-+  skip_whitespace(str);
-+  for (p = str; *p; p++)
-+    if (*p == ' ')
-+      break;
-+  c = *p;
-+  *p = 0;
-+
-+  mnemonic = hash_find(avr32_mnemonic_htab, str);
-+  *p = c;
-+  if (c) p++;
-+
-+  if (mnemonic)
-+    {
-+      const struct avr32_syntax *syntax;
-+
-+      for (syntax = mnemonic->syntax; syntax; syntax = syntax->next)
-+      {
-+        const char *errmsg = NULL;
-+
-+        if (syntax_matches(syntax, p))
-+          {
-+            if (!(syntax->isa_flags & avr32_arch->isa_flags))
-+              {
-+                as_bad(_("Selected architecture `%s'  does not support `%s'"),
-+                       avr32_arch->name, str);
-+                return;
-+              }
-+
-+            current_insn.syntax = syntax;
-+            parse_operands(p);
-+
-+            switch (syntax->type)
-+              {
-+              case AVR32_PARSER_NORMAL:
-+                errmsg = finish_insn(syntax->u.opc);
-+                break;
-+              case AVR32_PARSER_ALIAS:
-+                errmsg = finish_alias(syntax->u.alias);
-+                break;
-+              case AVR32_PARSER_LDA:
-+                errmsg = finish_lda(syntax);
-+                break;
-+              case AVR32_PARSER_CALL:
-+                errmsg = finish_call(syntax);
-+                break;
-+              default:
-+                BAD_CASE(syntax->type);
-+                break;
-+              }
-+
-+            if (errmsg)
-+              as_bad("%s in `%s'", errmsg, str);
-+
-+            return;
-+          }
-+      }
-+
-+      as_bad(_("unrecognized form of instruction: `%s'"), str);
-+    }
-+  else
-+    as_bad(_("unrecognized instruction `%s'"), str);
-+}
-+
-+void avr32_cleanup(void)
-+{
-+  struct cpool *pool;
-+
-+  /* Emit any constant pools that haven't been explicitly flushed with
-+     a .cpool directive. */
-+  for (pool = cpool_list; pool; pool = pool->next)
-+    {
-+      subseg_set(pool->section, pool->sub_section);
-+      s_cpool(0);
-+    }
-+}
-+
-+/* Handle any PIC-related operands in data allocation pseudo-ops */
-+void
-+avr32_cons_fix_new (fragS *frag, int off, int size, expressionS *exp)
-+{
-+  bfd_reloc_code_real_type r_type = BFD_RELOC_UNUSED;
-+  int pcrel = 0;
-+
-+  pr_debug("%s:%u: cons_fix_new, add_sym: %s, op_sym: %s, op: %d, add_num: %d\n",
-+         frag->fr_file, frag->fr_line,
-+         exp->X_add_symbol?S_GET_NAME(exp->X_add_symbol):"(none)",
-+         exp->X_op_symbol?S_GET_NAME(exp->X_op_symbol):"(none)",
-+         exp->X_op, exp->X_add_number);
-+
-+  if (exp->X_op == O_subtract && exp->X_op_symbol)
-+    {
-+      if (exp->X_op_symbol == GOT_symbol)
-+      {
-+        if (size != 4)
-+          goto bad_size;
-+        r_type = BFD_RELOC_AVR32_GOTPC;
-+        exp->X_op = O_symbol;
-+        exp->X_op_symbol = NULL;
-+      }
-+    }
-+  else if (exp->X_op == O_got)
-+    {
-+      switch (size)
-+      {
-+      case 1:
-+        r_type = BFD_RELOC_AVR32_GOT8;
-+        break;
-+      case 2:
-+        r_type = BFD_RELOC_AVR32_GOT16;
-+        break;
-+      case 4:
-+        r_type = BFD_RELOC_AVR32_GOT32;
-+        break;
-+      default:
-+        goto bad_size;
-+      }
-+
-+      exp->X_op = O_symbol;
-+    }
-+
-+  if (r_type == BFD_RELOC_UNUSED)
-+    switch (size)
-+      {
-+      case 1:
-+      r_type = BFD_RELOC_8;
-+      break;
-+      case 2:
-+      r_type = BFD_RELOC_16;
-+      break;
-+      case 4:
-+      r_type = BFD_RELOC_32;
-+      break;
-+      default:
-+      goto bad_size;
-+      }
-+  else if (size != 4)
-+    {
-+    bad_size:
-+      as_bad(_("unsupported BFD relocation size %u"), size);
-+      r_type = BFD_RELOC_UNUSED;
-+    }
-+
-+  fix_new_exp (frag, off, size, exp, pcrel, r_type);
-+}
-+
-+static void
-+avr32_frob_section(bfd *abfd ATTRIBUTE_UNUSED, segT sec,
-+                 void *ignore ATTRIBUTE_UNUSED)
-+{
-+  segment_info_type *seginfo;
-+  fixS *fix;
-+
-+  seginfo = seg_info(sec);
-+  if (!seginfo)
-+    return;
-+
-+  for (fix = seginfo->fix_root; fix; fix = fix->fx_next)
-+    {
-+      if (fix->fx_done)
-+      continue;
-+
-+      if (fix->fx_r_type == BFD_RELOC_AVR32_SUB5
-+        && fix->fx_addsy && fix->fx_subsy)
-+      {
-+        if (S_GET_SEGMENT(fix->fx_addsy) != S_GET_SEGMENT(fix->fx_subsy)
-+            || linkrelax)
-+          {
-+            symbolS *tmp;
-+#ifdef DEBUG
-+            fprintf(stderr, "Swapping symbols in fixup:\n");
-+            print_fixup(fix);
-+#endif
-+            tmp = fix->fx_addsy;
-+            fix->fx_addsy = fix->fx_subsy;
-+            fix->fx_subsy = tmp;
-+            fix->fx_offset = -fix->fx_offset;
-+          }
-+      }
-+    }
-+}
-+
-+/* We need to look for SUB5 instructions with expressions that will be
-+   made PC-relative and switch fx_addsy with fx_subsy.  This has to be
-+   done before adjustment or the wrong symbol might be adjusted.
-+
-+   This applies to fixups that are a result of expressions like -(sym
-+   - .) and that will make it all the way to md_apply_fix3().  LDA
-+   does the right thing in convert_frag, so we must not convert
-+   those. */
-+void
-+avr32_frob_file(void)
-+{
-+  /* if (1 || !linkrelax)
-+     return; */
-+
-+  bfd_map_over_sections(stdoutput, avr32_frob_section, NULL);
-+}
-+
-+static bfd_boolean
-+convert_to_diff_reloc(fixS *fixP)
-+{
-+  switch (fixP->fx_r_type)
-+    {
-+    case BFD_RELOC_32:
-+      fixP->fx_r_type = BFD_RELOC_AVR32_DIFF32;
-+      break;
-+    case BFD_RELOC_16:
-+      fixP->fx_r_type = BFD_RELOC_AVR32_DIFF16;
-+      break;
-+    case BFD_RELOC_8:
-+      fixP->fx_r_type = BFD_RELOC_AVR32_DIFF8;
-+      break;
-+    default:
-+      return FALSE;
-+    }
-+
-+  return TRUE;
-+}
-+
-+/* Simplify a fixup.  If possible, the fixup is reduced to a single
-+   constant which is written to the output file.  Otherwise, a
-+   relocation is generated so that the linker can take care of the
-+   rest.
-+
-+   ELF relocations have certain constraints: They can only take a
-+   single symbol and a single addend.  This means that for difference
-+   expressions, we _must_ get rid of the fx_subsy symbol somehow.
-+
-+   The difference between two labels in the same section can be
-+   calculated directly unless 'linkrelax' is set, or a relocation is
-+   forced.  If so, we must emit a R_AVR32_DIFFxx relocation.  If there
-+   are addends involved at this point, we must be especially careful
-+   as the relocation must point exactly to the symbol being
-+   subtracted.
-+
-+   When subtracting a symbol defined in the same section as the fixup,
-+   we might be able to convert it to a PC-relative expression, unless
-+   linkrelax is set. If this is the case, there's no way we can make
-+   sure that the difference between the fixup and fx_subsy stays
-+   constant.  So for now, we're just going to disallow that.
-+   */
-+void
-+avr32_process_fixup(fixS *fixP, segT this_segment)
-+{
-+  segT add_symbol_segment = absolute_section;
-+  segT sub_symbol_segment = absolute_section;
-+  symbolS *fx_addsy, *fx_subsy;
-+  offsetT value = 0, fx_offset;
-+  bfd_boolean apply = FALSE;
-+
-+  assert(this_segment != absolute_section);
-+
-+  if (fixP->fx_r_type >= BFD_RELOC_UNUSED)
-+    {
-+      as_bad_where(fixP->fx_file, fixP->fx_line,
-+                 _("Bad relocation type %d\n"), fixP->fx_r_type);
-+      return;
-+    }
-+
-+  /* BFD_RELOC_AVR32_SUB5 fixups have been swapped by avr32_frob_section() */
-+  fx_addsy = fixP->fx_addsy;
-+  fx_subsy = fixP->fx_subsy;
-+  fx_offset = fixP->fx_offset;
-+
-+  if (fx_addsy)
-+    add_symbol_segment = S_GET_SEGMENT(fx_addsy);
-+
-+  if (fx_subsy)
-+    {
-+      resolve_symbol_value(fx_subsy);
-+      sub_symbol_segment = S_GET_SEGMENT(fx_subsy);
-+
-+      if (sub_symbol_segment == this_segment
-+        && (!linkrelax
-+            || S_GET_VALUE(fx_subsy) == (fixP->fx_frag->fr_address
-+                                         + fixP->fx_where)))
-+      {
-+        fixP->fx_pcrel = TRUE;
-+        fx_offset += (fixP->fx_frag->fr_address + fixP->fx_where
-+                      - S_GET_VALUE(fx_subsy));
-+        fx_subsy = NULL;
-+      }
-+      else if (sub_symbol_segment == absolute_section)
-+      {
-+        /* The symbol is really a constant.  */
-+        fx_offset -= S_GET_VALUE(fx_subsy);
-+        fx_subsy = NULL;
-+      }
-+      else if (SEG_NORMAL(add_symbol_segment)
-+             && sub_symbol_segment == add_symbol_segment
-+             && (!linkrelax || convert_to_diff_reloc(fixP)))
-+      {
-+        /* Difference between two labels in the same section.  */
-+        if (linkrelax)
-+          {
-+            /* convert_to_diff() has ensured that the reloc type is
-+               either DIFF32, DIFF16 or DIFF8.  */
-+            value = (S_GET_VALUE(fx_addsy) + fixP->fx_offset
-+                     - S_GET_VALUE(fx_subsy));
-+
-+            /* Try to convert it to a section symbol if possible  */
-+            if (!S_FORCE_RELOC(fx_addsy, 1)
-+                && !(sub_symbol_segment->flags & SEC_THREAD_LOCAL))
-+              {
-+                fx_offset = S_GET_VALUE(fx_subsy);
-+                fx_addsy = section_symbol(sub_symbol_segment);
-+              }
-+            else
-+              {
-+                fx_addsy = fx_subsy;
-+                fx_offset = 0;
-+              }
-+
-+            fx_subsy = NULL;
-+            apply = TRUE;
-+          }
-+        else
-+          {
-+            fx_offset += S_GET_VALUE(fx_addsy);
-+            fx_offset -= S_GET_VALUE(fx_subsy);
-+            fx_addsy = NULL;
-+            fx_subsy = NULL;
-+          }
-+      }
-+      else
-+      {
-+        as_bad_where(fixP->fx_file, fixP->fx_line,
-+                     _("can't resolve `%s' {%s section} - `%s' {%s section}"),
-+                     fx_addsy ? S_GET_NAME (fx_addsy) : "0",
-+                     segment_name (add_symbol_segment),
-+                     S_GET_NAME (fx_subsy),
-+                     segment_name (sub_symbol_segment));
-+        return;
-+      }
-+    }
-+
-+  if (fx_addsy && !TC_FORCE_RELOCATION(fixP))
-+    {
-+      if (add_symbol_segment == this_segment
-+        && fixP->fx_pcrel)
-+      {
-+        value += S_GET_VALUE(fx_addsy);
-+        value -= md_pcrel_from_section(fixP, this_segment);
-+        fx_addsy = NULL;
-+        fixP->fx_pcrel = FALSE;
-+      }
-+      else if (add_symbol_segment == absolute_section)
-+      {
-+        fx_offset += S_GET_VALUE(fixP->fx_addsy);
-+        fx_addsy = NULL;
-+      }
-+    }
-+
-+  if (!fx_addsy)
-+    fixP->fx_done = TRUE;
-+
-+  if (fixP->fx_pcrel)
-+    {
-+      if (fx_addsy != NULL
-+        && S_IS_DEFINED(fx_addsy)
-+        && S_GET_SEGMENT(fx_addsy) != this_segment)
-+      value += md_pcrel_from_section(fixP, this_segment);
-+
-+      switch (fixP->fx_r_type)
-+      {
-+      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;
-+      case BFD_RELOC_8:
-+        fixP->fx_r_type = BFD_RELOC_8_PCREL;
-+        break;
-+      case BFD_RELOC_AVR32_SUB5:
-+        fixP->fx_r_type = BFD_RELOC_AVR32_16N_PCREL;
-+        break;
-+      case BFD_RELOC_AVR32_16S:
-+        fixP->fx_r_type = BFD_RELOC_AVR32_16B_PCREL;
-+        break;
-+      case BFD_RELOC_AVR32_14UW:
-+        fixP->fx_r_type = BFD_RELOC_AVR32_14UW_PCREL;
-+        break;
-+      case BFD_RELOC_AVR32_10UW:
-+        fixP->fx_r_type = BFD_RELOC_AVR32_10UW_PCREL;
-+        break;
-+      default:
-+        /* Should have been taken care of already */
-+        break;
-+      }
-+    }
-+
-+  if (fixP->fx_done || apply)
-+    {
-+      const struct avr32_ifield *ifield;
-+      char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
-+
-+      if (fixP->fx_done)
-+      value += fx_offset;
-+
-+      /* For hosts with longs bigger than 32-bits make sure that the top
-+         bits of a 32-bit negative value read in by the parser are set,
-+         so that the correct comparisons are made.  */
-+      if (value & 0x80000000)
-+        value |= (-1L << 31);
-+
-+      switch (fixP->fx_r_type)
-+      {
-+      case BFD_RELOC_32:
-+      case BFD_RELOC_16:
-+      case BFD_RELOC_8:
-+      case BFD_RELOC_AVR32_DIFF32:
-+      case BFD_RELOC_AVR32_DIFF16:
-+      case BFD_RELOC_AVR32_DIFF8:
-+        md_number_to_chars(buf, value, fixP->fx_size);
-+        break;
-+      case BFD_RELOC_HI16:
-+        value >>= 16;
-+      case BFD_RELOC_LO16:
-+        value &= 0xffff;
-+        md_number_to_chars(buf + 2, value, 2);
-+        break;
-+      case BFD_RELOC_AVR32_16N_PCREL:
-+        value = -value;
-+        /* fall through */
-+      case BFD_RELOC_AVR32_22H_PCREL:
-+      case BFD_RELOC_AVR32_18W_PCREL:
-+      case BFD_RELOC_AVR32_16B_PCREL:
-+      case BFD_RELOC_AVR32_11H_PCREL:
-+      case BFD_RELOC_AVR32_9H_PCREL:
-+      case BFD_RELOC_AVR32_9UW_PCREL:
-+      case BFD_RELOC_AVR32_3U:
-+      case BFD_RELOC_AVR32_4UH:
-+      case BFD_RELOC_AVR32_6UW:
-+      case BFD_RELOC_AVR32_6S:
-+      case BFD_RELOC_AVR32_7UW:
-+      case BFD_RELOC_AVR32_8S_EXT:
-+      case BFD_RELOC_AVR32_8S:
-+      case BFD_RELOC_AVR32_10UW:
-+      case BFD_RELOC_AVR32_10SW:
-+      case BFD_RELOC_AVR32_STHH_W:
-+      case BFD_RELOC_AVR32_14UW:
-+      case BFD_RELOC_AVR32_16S:
-+      case BFD_RELOC_AVR32_16U:
-+      case BFD_RELOC_AVR32_21S:
-+      case BFD_RELOC_AVR32_SUB5:
-+      case BFD_RELOC_AVR32_CPCALL:
-+      case BFD_RELOC_AVR32_16_CP:
-+      case BFD_RELOC_AVR32_9W_CP:
-+      case BFD_RELOC_AVR32_15S:
-+        ifield = fixP->tc_fix_data.ifield;
-+        pr_debug("insert field: %ld <= %ld <= %ld (align %u)\n",
-+                 fixP->tc_fix_data.min, value, fixP->tc_fix_data.max,
-+                 fixP->tc_fix_data.align);
-+        if (value < fixP->tc_fix_data.min || value > fixP->tc_fix_data.max)
-+          as_bad_where(fixP->fx_file, fixP->fx_line,
-+                       _("operand out of range (%ld not between %ld and %ld)"),
-+                       value, fixP->tc_fix_data.min, fixP->tc_fix_data.max);
-+        if (value & ((1 << fixP->tc_fix_data.align) - 1))
-+          as_bad_where(fixP->fx_file, fixP->fx_line,
-+                       _("misaligned operand (required alignment: %d)"),
-+                       1 << fixP->tc_fix_data.align);
-+        ifield->insert(ifield, buf, value >> fixP->tc_fix_data.align);
-+        break;
-+      case BFD_RELOC_AVR32_ALIGN:
-+        /* Nothing to do */
-+        fixP->fx_done = FALSE;
-+        break;
-+      default:
-+        as_fatal("reloc type %s not handled\n",
-+                 bfd_get_reloc_code_name(fixP->fx_r_type));
-+      }
-+    }
-+
-+  fixP->fx_addsy = fx_addsy;
-+  fixP->fx_subsy = fx_subsy;
-+  fixP->fx_offset = fx_offset;
-+
-+  if (!fixP->fx_done)
-+    {
-+      if (!fixP->fx_addsy)
-+      fixP->fx_addsy = abs_section_sym;
-+
-+      symbol_mark_used_in_reloc(fixP->fx_addsy);
-+      if (fixP->fx_subsy)
-+      abort();
-+    }
-+}
-+
-+#if 0
-+void
-+md_apply_fix3 (fixS *fixP, valueT *valP, segT seg)
-+{
-+  const struct avr32_ifield *ifield;
-+  offsetT     value = *valP;
-+  char                *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
-+  bfd_boolean apply;
-+
-+  pr_debug("%s:%u: apply_fix3: r_type=%d value=%lx offset=%lx\n",
-+         fixP->fx_file, fixP->fx_line, fixP->fx_r_type, *valP,
-+         fixP->fx_offset);
-+
-+  if (fixP->fx_r_type >= BFD_RELOC_UNUSED)
-+    {
-+      as_bad_where(fixP->fx_file, fixP->fx_line,
-+                 _("Bad relocation type %d\n"), fixP->fx_r_type);
-+      return;
-+    }
-+
-+  if (!fixP->fx_addsy && !fixP->fx_subsy)
-+    fixP->fx_done = 1;
-+
-+  if (fixP->fx_pcrel)
-+    {
-+      if (fixP->fx_addsy != NULL
-+        && S_IS_DEFINED(fixP->fx_addsy)
-+        && S_GET_SEGMENT(fixP->fx_addsy) != seg)
-+      value += md_pcrel_from_section(fixP, seg);
-+
-+      switch (fixP->fx_r_type)
-+      {
-+      case BFD_RELOC_32:
-+        fixP->fx_r_type = BFD_RELOC_32_PCREL;
-+        break;
-+      case BFD_RELOC_16:
-+      case BFD_RELOC_8:
-+        as_bad_where (fixP->fx_file, fixP->fx_line,
-+                      _("8- and 16-bit PC-relative relocations not supported"));
-+        break;
-+      case BFD_RELOC_AVR32_SUB5:
-+        fixP->fx_r_type = BFD_RELOC_AVR32_PCREL_SUB5;
-+        break;
-+      case BFD_RELOC_AVR32_16S:
-+        fixP->fx_r_type = BFD_RELOC_AVR32_16_PCREL;
-+        break;
-+      default:
-+        /* Should have been taken care of already */
-+        break;
-+      }
-+    }
-+
-+  if (fixP->fx_r_type == BFD_RELOC_32
-+      && fixP->fx_subsy)
-+    {
-+      fixP->fx_r_type = BFD_RELOC_AVR32_DIFF32;
-+
-+      /* Offsets are only allowed if it's a result of adjusting a
-+       local symbol into a section-relative offset.
-+       tc_fix_adjustable() should prevent any adjustment if there
-+       was an offset involved before.  */
-+      if (fixP->fx_offset && !symbol_section_p(fixP->fx_addsy))
-+      as_bad_where(fixP->fx_file, fixP->fx_line,
-+                   _("cannot represent symbol difference with an offset"));
-+
-+      value = (S_GET_VALUE(fixP->fx_addsy) + fixP->fx_offset
-+             - S_GET_VALUE(fixP->fx_subsy));
-+
-+      /* The difference before any relaxing takes place is written
-+       out, and the DIFF32 reloc identifies the address of the first
-+       symbol (i.e. the on that's subtracted.)  */
-+      *valP = value;
-+      fixP->fx_offset -= value;
-+      fixP->fx_subsy = NULL;
-+
-+      md_number_to_chars(buf, value, fixP->fx_size);
-+    }
-+
-+  if (fixP->fx_done)
-+    {
-+      switch (fixP->fx_r_type)
-+      {
-+      case BFD_RELOC_8:
-+      case BFD_RELOC_16:
-+      case BFD_RELOC_32:
-+        md_number_to_chars(buf, value, fixP->fx_size);
-+        break;
-+      case BFD_RELOC_HI16:
-+        value >>= 16;
-+      case BFD_RELOC_LO16:
-+        value &= 0xffff;
-+        *valP = value;
-+        md_number_to_chars(buf + 2, value, 2);
-+        break;
-+      case BFD_RELOC_AVR32_PCREL_SUB5:
-+        value = -value;
-+        /* fall through */
-+      case BFD_RELOC_AVR32_9_PCREL:
-+      case BFD_RELOC_AVR32_11_PCREL:
-+      case BFD_RELOC_AVR32_16_PCREL:
-+      case BFD_RELOC_AVR32_18_PCREL:
-+      case BFD_RELOC_AVR32_22_PCREL:
-+      case BFD_RELOC_AVR32_3U:
-+      case BFD_RELOC_AVR32_4UH:
-+      case BFD_RELOC_AVR32_6UW:
-+      case BFD_RELOC_AVR32_6S:
-+      case BFD_RELOC_AVR32_7UW:
-+      case BFD_RELOC_AVR32_8S:
-+      case BFD_RELOC_AVR32_10UW:
-+      case BFD_RELOC_AVR32_10SW:
-+      case BFD_RELOC_AVR32_14UW:
-+      case BFD_RELOC_AVR32_16S:
-+      case BFD_RELOC_AVR32_16U:
-+      case BFD_RELOC_AVR32_21S:
-+      case BFD_RELOC_AVR32_BRC1:
-+      case BFD_RELOC_AVR32_SUB5:
-+      case BFD_RELOC_AVR32_CPCALL:
-+      case BFD_RELOC_AVR32_16_CP:
-+      case BFD_RELOC_AVR32_9_CP:
-+      case BFD_RELOC_AVR32_15S:
-+        ifield = fixP->tc_fix_data.ifield;
-+        pr_debug("insert field: %ld <= %ld <= %ld (align %u)\n",
-+                 fixP->tc_fix_data.min, value, fixP->tc_fix_data.max,
-+                 fixP->tc_fix_data.align);
-+        if (value < fixP->tc_fix_data.min || value > fixP->tc_fix_data.max)
-+          as_bad_where(fixP->fx_file, fixP->fx_line,
-+                       _("operand out of range (%ld not between %ld and %ld)"),
-+                       value, fixP->tc_fix_data.min, fixP->tc_fix_data.max);
-+        if (value & ((1 << fixP->tc_fix_data.align) - 1))
-+          as_bad_where(fixP->fx_file, fixP->fx_line,
-+                       _("misaligned operand (required alignment: %d)"),
-+                       1 << fixP->tc_fix_data.align);
-+        ifield->insert(ifield, buf, value >> fixP->tc_fix_data.align);
-+        break;
-+      case BFD_RELOC_AVR32_ALIGN:
-+        /* Nothing to do */
-+        fixP->fx_done = FALSE;
-+        break;
-+      default:
-+        as_fatal("reloc type %s not handled\n",
-+                 bfd_get_reloc_code_name(fixP->fx_r_type));
-+      }
-+    }
-+}
-+#endif
-+
-+arelent *
-+tc_gen_reloc (asection *section ATTRIBUTE_UNUSED,
-+            fixS *fixp)
-+{
-+  arelent *reloc;
-+  bfd_reloc_code_real_type code;
-+
-+  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->addend = fixp->fx_offset;
-+  code = fixp->fx_r_type;
-+
-+  reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
-+
-+  if (reloc->howto == NULL)
-+    {
-+      as_bad_where (fixp->fx_file, fixp->fx_line,
-+                  _("cannot represent relocation %s in this object file format"),
-+                  bfd_get_reloc_code_name (code));
-+      return NULL;
-+    }
-+
-+  return reloc;
-+}
-+
-+bfd_boolean
-+avr32_force_reloc(fixS *fixP)
-+{
-+  if (linkrelax && fixP->fx_addsy
-+      && !(S_GET_SEGMENT(fixP->fx_addsy)->flags & SEC_DEBUGGING)
-+      && S_GET_SEGMENT(fixP->fx_addsy) != absolute_section)
-+    {
-+      pr_debug(stderr, "force reloc: addsy=%p, r_type=%d, sec=%s\n",
-+             fixP->fx_addsy, fixP->fx_r_type, S_GET_SEGMENT(fixP->fx_addsy)->name);
-+      return 1;
-+    }
-+
-+  return generic_force_reloc(fixP);
-+}
-+
-+bfd_boolean
-+avr32_fix_adjustable(fixS *fixP)
-+{
-+  switch (fixP->fx_r_type)
-+    {
-+      /* GOT relocations can't have addends since BFD treats all
-+       references to a given symbol the same. This means that we
-+       must avoid section-relative references to local symbols when
-+       dealing with these kinds of relocs */
-+    case BFD_RELOC_AVR32_GOT32:
-+    case BFD_RELOC_AVR32_GOT16:
-+    case BFD_RELOC_AVR32_GOT8:
-+    case BFD_RELOC_AVR32_GOT21S:
-+    case BFD_RELOC_AVR32_GOT18SW:
-+    case BFD_RELOC_AVR32_GOT16S:
-+    case BFD_RELOC_AVR32_LDA_GOT:
-+    case BFD_RELOC_AVR32_GOTCALL:
-+      pr_debug("fix not adjustable\n");
-+      return 0;
-+
-+    default:
-+      break;
-+    }
-+
-+  return 1;
-+}
-+
-+/* When we want the linker to be able to relax the code, we need to
-+   output a reloc for every .align directive requesting an alignment
-+   to a four byte boundary or larger.  If we don't do this, the linker
-+   can't guarantee that the alignment is actually maintained in the
-+   linker output.
-+
-+   TODO: Might as well insert proper NOPs while we're at it... */
-+void
-+avr32_handle_align(fragS *frag)
-+{
-+  if (linkrelax
-+      && frag->fr_type == rs_align_code
-+      && frag->fr_address + frag->fr_fix > 0
-+      && frag->fr_offset > 0)
-+    {
-+      /* The alignment order (fr_offset) is stored in the addend. */
-+      fix_new(frag, frag->fr_fix, 2, &abs_symbol, frag->fr_offset,
-+            FALSE, BFD_RELOC_AVR32_ALIGN);
-+    }
-+}
-+
-+/* Relax_align. Advance location counter to next address that has 'alignment'
-+   lowest order bits all 0s, return size of adjustment made.  */
-+relax_addressT
-+avr32_relax_align(segT segment ATTRIBUTE_UNUSED,
-+                fragS *fragP,
-+                relax_addressT address)
-+{
-+  relax_addressT mask;
-+  relax_addressT new_address;
-+  int alignment;
-+
-+  alignment = fragP->fr_offset;
-+  mask = ~((~0) << alignment);
-+  new_address = (address + mask) & (~mask);
-+
-+  return new_address - address;
-+}
-+
-+/* Turn a string in input_line_pointer into a floating point constant
-+   of type type, and store the appropriate bytes in *litP.  The number
-+   of LITTLENUMS emitted is stored in *sizeP .  An error message is
-+   returned, or NULL on OK. */
-+
-+/* Equal to MAX_PRECISION in atof-ieee.c */
-+#define MAX_LITTLENUMS 6
-+
-+char *
-+md_atof (type, litP, sizeP)
-+char   type;
-+char * litP;
-+int *  sizeP;
-+{
-+  int              i;
-+  int              prec;
-+  LITTLENUM_TYPE   words [MAX_LITTLENUMS];
-+  char *           t;
-+
-+  switch (type)
-+  {
-+    case 'f':
-+    case 'F':
-+    case 's':
-+    case 'S':
-+      prec = 2;
-+      break;
-+
-+    case 'd':
-+    case 'D':
-+    case 'r':
-+    case 'R':
-+      prec = 4;
-+      break;
-+
-+      /* FIXME: Some targets allow other format chars for bigger sizes here.  */
-+
-+    default:
-+      * sizeP = 0;
-+      return _("Bad call to md_atof()");
-+  }
-+
-+  t = atof_ieee (input_line_pointer, type, words);
-+  if (t)
-+    input_line_pointer = t;
-+  * sizeP = prec * sizeof (LITTLENUM_TYPE);
-+
-+  for (i = 0; i < prec; i++)
-+  {
-+    md_number_to_chars (litP, (valueT) words[i],
-+                        sizeof (LITTLENUM_TYPE));
-+    litP += sizeof (LITTLENUM_TYPE);
-+  }
-+
-+  return 0;
-+}
-+
-+static char *avr32_end_of_match(char *cont, char *what)
-+{
-+  int len = strlen (what);
-+
-+  if (! is_part_of_name (cont[len])
-+      && strncasecmp (cont, what, len) == 0)
-+    return cont + len;
-+
-+  return NULL;
-+}
-+
-+int
-+avr32_parse_name (char const *name, expressionS *exp, char *nextchar)
-+{
-+  char *next = input_line_pointer;
-+  char *next_end;
-+
-+  pr_debug("parse_name: %s, nextchar=%c (%02x)\n", name, *nextchar, *nextchar);
-+
-+  if (*nextchar == '(')
-+    {
-+      if (strcasecmp(name, "hi") == 0)
-+      {
-+        *next = *nextchar;
-+
-+        expression(exp);
-+
-+        if (exp->X_op == O_constant)
-+          {
-+            pr_debug("  -> constant hi(0x%08lx) -> 0x%04lx\n",
-+                     exp->X_add_number, exp->X_add_number >> 16);
-+            exp->X_add_number = (exp->X_add_number >> 16) & 0xffff;
-+          }
-+        else
-+          {
-+            exp->X_md = exp->X_op;
-+            exp->X_op = O_hi;
-+          }
-+
-+        return 1;
-+      }
-+      else if (strcasecmp(name, "lo") == 0)
-+      {
-+        *next = *nextchar;
-+
-+        expression(exp);
-+
-+        if (exp->X_op == O_constant)
-+          exp->X_add_number &= 0xffff;
-+        else
-+          {
-+            exp->X_md = exp->X_op;
-+            exp->X_op = O_lo;
-+          }
-+
-+        return 1;
-+      }
-+    }
-+  else if (*nextchar == '@')
-+    {
-+      exp->X_md = exp->X_op;
-+
-+      if ((next_end = avr32_end_of_match (next + 1, "got")))
-+      exp->X_op = O_got;
-+      else if ((next_end = avr32_end_of_match (next + 1, "tlsgd")))
-+      exp->X_op = O_tlsgd;
-+      /* Add more as needed */
-+      else
-+      {
-+        char c;
-+        input_line_pointer++;
-+        c = get_symbol_end();
-+        as_bad (_("unknown relocation override `%s'"), next + 1);
-+        *input_line_pointer = c;
-+        input_line_pointer = next;
-+        return 0;
-+      }
-+
-+      exp->X_op_symbol = NULL;
-+      exp->X_add_symbol = symbol_find_or_make (name);
-+      exp->X_add_number = 0;
-+
-+      *input_line_pointer = *nextchar;
-+      input_line_pointer = next_end;
-+      *nextchar = *input_line_pointer;
-+      *input_line_pointer = '\0';
-+      return 1;
-+    }
-+  else if (strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0)
-+    {
-+      if (!GOT_symbol)
-+      GOT_symbol = symbol_find_or_make(name);
-+
-+      exp->X_add_symbol = GOT_symbol;
-+      exp->X_op = O_symbol;
-+      exp->X_add_number = 0;
-+      return 1;
-+    }
-+
-+  return 0;
-+}
-+
-+static void
-+s_rseg (int value ATTRIBUTE_UNUSED)
-+{
-+  /* Syntax: RSEG segment_name [:type] [NOROOT|ROOT] [(align)]
-+   * Defaults:
-+   *  - type: undocumented ("typically CODE or DATA")
-+   *  - ROOT
-+   *  - align: 1 for code, 0 for others
-+   *
-+   * TODO: NOROOT is ignored. If gas supports discardable segments, it should
-+   * be implemented.
-+   */
-+  char *name, *end;
-+  int length, type, attr;
-+  int align = 0;
-+
-+  SKIP_WHITESPACE();
-+
-+  end = input_line_pointer;
-+  while (0 == strchr ("\n\t;:( ", *end))
-+    end++;
-+  if (end == input_line_pointer)
-+    {
-+      as_warn (_("missing name"));
-+      ignore_rest_of_line();
-+      return;
-+    }
-+
-+  name = xmalloc (end - input_line_pointer + 1);
-+  memcpy (name, input_line_pointer, end - input_line_pointer);
-+  name[end - input_line_pointer] = '\0';
-+  input_line_pointer = end;
-+
-+  SKIP_WHITESPACE();
-+
-+  type = SHT_NULL;
-+  attr = 0;
-+
-+  if (*input_line_pointer == ':')
-+    {
-+      /* Skip the colon */
-+      ++input_line_pointer;
-+      SKIP_WHITESPACE();
-+
-+      /* Possible options at this point:
-+       *   - flag (ROOT or NOROOT)
-+       *   - a segment type
-+       */
-+      end = input_line_pointer;
-+      while (0 == strchr ("\n\t;:( ", *end))
-+      end++;
-+      length = end - input_line_pointer;
-+      if (((length == 4) && (0 == strncasecmp( input_line_pointer, "ROOT", 4))) ||
-+        ((length == 6) && (0 == strncasecmp( input_line_pointer, "NOROOT", 6))))
-+      {
-+        /* Ignore ROOT/NOROOT */
-+        input_line_pointer = end;
-+      }
-+      else
-+      {
-+        /* Must be a segment type */
-+        switch (*input_line_pointer)
-+          {
-+          case 'C':
-+          case 'c':
-+            if ((length == 4) &&
-+                (0 == strncasecmp (input_line_pointer, "CODE", 4)))
-+              {
-+                attr |= SHF_ALLOC | SHF_EXECINSTR;
-+                type = SHT_PROGBITS;
-+                align = 1;
-+                break;
-+              }
-+            if ((length == 5) &&
-+                (0 == strncasecmp (input_line_pointer, "CONST", 5)))
-+              {
-+                attr |= SHF_ALLOC;
-+                type = SHT_PROGBITS;
-+                break;
-+              }
-+            goto de_fault;
-+
-+          case 'D':
-+          case 'd':
-+            if ((length == 4) &&
-+                (0 == strncasecmp (input_line_pointer, "DATA", 4)))
-+              {
-+                attr |= SHF_ALLOC | SHF_WRITE;
-+                type = SHT_PROGBITS;
-+                break;
-+              }
-+            goto de_fault;
-+
-+            /* TODO: Add FAR*, HUGE*, IDATA and NEAR* if necessary */
-+
-+          case 'U':
-+          case 'u':
-+            if ((length == 7) &&
-+                (0 == strncasecmp (input_line_pointer, "UNTYPED", 7)))
-+              break;
-+            goto de_fault;
-+
-+            /* TODO: Add XDATA and ZPAGE if necessary */
-+
-+          de_fault:
-+          default:
-+            as_warn (_("unrecognized segment type"));
-+          }
-+
-+        input_line_pointer = end;
-+        SKIP_WHITESPACE();
-+
-+        if (*input_line_pointer == ':')
-+          {
-+            /*  ROOT/NOROOT */
-+            ++input_line_pointer;
-+            SKIP_WHITESPACE();
-+
-+            end = input_line_pointer;
-+            while (0 == strchr ("\n\t;:( ", *end))
-+              end++;
-+            length = end - input_line_pointer;
-+            if (! ((length == 4) &&
-+                   (0 == strncasecmp( input_line_pointer, "ROOT", 4))) &&
-+                ! ((length == 6) &&
-+                   (0 == strncasecmp( input_line_pointer, "NOROOT", 6))))
-+              {
-+                as_warn (_("unrecognized segment flag"));
-+              }
-+
-+            input_line_pointer = end;
-+            SKIP_WHITESPACE();
-+          }
-+      }
-+    }
-+
-+  if (*input_line_pointer == '(')
-+    {
-+      align = get_absolute_expression ();
-+    }
-+
-+  demand_empty_rest_of_line();
-+
-+  obj_elf_change_section (name, type, attr, 0, NULL, 0, 0);
-+#ifdef AVR32_DEBUG
-+  fprintf( stderr, "RSEG: Changed section to %s, type: 0x%x, attr: 0x%x\n",
-+      name, type, attr );
-+  fprintf( stderr, "RSEG: Aligning to 2**%d\n", align );
-+#endif
-+
-+  if (align > 15)
-+    {
-+      align = 15;
-+      as_warn (_("alignment too large: %u assumed"), align);
-+    }
-+
-+  /* Hope not, that is */
-+  assert (now_seg != absolute_section);
-+
-+  /* Only make a frag if we HAVE to... */
-+  if (align != 0 && !need_pass_2)
-+    {
-+      if (subseg_text_p (now_seg))
-+      frag_align_code (align, 0);
-+      else
-+      frag_align (align, 0, 0);
-+    }
-+
-+  record_alignment (now_seg, align - OCTETS_PER_BYTE_POWER);
-+}
-+
-+/* vim: syntax=c sw=2
-+ */
---- /dev/null
-+++ b/gas/config/tc-avr32.h
-@@ -0,0 +1,325 @@
-+/* Assembler definitions for AVR32.
-+   Copyright 2003-2006 Atmel Corporation.
-+
-+   Written by Haavard Skinnemoen, Atmel Norway, <hskinnemoen@atmel.com>
-+
-+   This file is part of GAS, the GNU Assembler.
-+
-+   GAS 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 2, or (at your option)
-+   any later version.
-+
-+   GAS 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 GAS; see the file COPYING.  If not, write to the Free
-+   Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-+   02111-1307, USA.  */
-+
-+#if 0
-+#define DEBUG
-+#define DEBUG1
-+#define DEBUG2
-+#define DEBUG3
-+#define DEBUG4
-+#define DEBUG5
-+#endif
-+
-+/* Are we trying to be compatible with the IAR assembler? (--iar) */
-+extern int avr32_iarcompat;
-+
-+/* By convention, you should define this macro in the `.h' file.  For
-+   example, `tc-m68k.h' defines `TC_M68K'.  You might have to use this
-+   if it is necessary to add CPU specific code to the object format
-+   file.  */
-+#define TC_AVR32
-+
-+/* This macro is the BFD target name to use when creating the output
-+   file.  This will normally depend upon the `OBJ_FMT' macro.  */
-+#define TARGET_FORMAT "elf32-avr32"
-+
-+/* This macro is the BFD architecture to pass to `bfd_set_arch_mach'.  */
-+#define TARGET_ARCH bfd_arch_avr32
-+
-+/* This macro is the BFD machine number to pass to
-+   `bfd_set_arch_mach'.  If it is not defined, GAS will use 0.  */
-+#define TARGET_MACH 0
-+
-+/* UNDOCUMENTED: Allow //-style comments */
-+#define DOUBLESLASH_LINE_COMMENTS
-+
-+/* You should define this macro to be non-zero if the target is big
-+   endian, and zero if the target is little endian.  */
-+#define TARGET_BYTES_BIG_ENDIAN 1
-+
-+/* FIXME: It seems that GAS only expects a one-byte opcode...
-+   #define NOP_OPCODE 0xd703 */
-+
-+/* If you define this macro, GAS will warn about the use of
-+   nonstandard escape sequences in a string.  */
-+#undef ONLY_STANDARD_ESCAPES
-+
-+#define DWARF2_FORMAT() dwarf2_format_32bit
-+
-+/* Instructions are either 2 or 4 bytes long */
-+/* #define DWARF2_LINE_MIN_INSN_LENGTH 2 */
-+
-+/* GAS will call this function for any expression that can not be
-+   recognized.  When the function is called, `input_line_pointer'
-+   will point to the start of the expression.  */
-+#define md_operand(x)
-+
-+#define md_parse_name(name, expr, mode, c) avr32_parse_name(name, expr, c)
-+extern int avr32_parse_name(const char *, struct expressionS *, char *);
-+
-+/* You may define this macro to generate a fixup for a data
-+   allocation pseudo-op.  */
-+#define TC_CONS_FIX_NEW(FRAG, OFF, LEN, EXP)  \
-+  avr32_cons_fix_new(FRAG, OFF, LEN, EXP)
-+void avr32_cons_fix_new (fragS *, int, int, expressionS *);
-+
-+/* `extsym - .' expressions can be emitted using PC-relative relocs */
-+#define DIFF_EXPR_OK
-+
-+/* This is used to construct expressions out of @gotoff, etc. The
-+   relocation type is stored in X_md */
-+#define O_got         O_md1
-+#define O_hi          O_md2
-+#define O_lo          O_md3
-+#define O_tlsgd               O_md4
-+
-+/* You may define this macro to parse an expression used in a data
-+   allocation pseudo-op such as `.word'.  You can use this to
-+   recognize relocation directives that may appear in such directives.  */
-+/* #define TC_PARSE_CONS_EXPRESSION(EXPR,N) avr_parse_cons_expression (EXPR,N)
-+   void avr_parse_cons_expression (expressionS *exp, int nbytes); */
-+
-+/* This should just call either `number_to_chars_bigendian' or
-+   `number_to_chars_littleendian', whichever is appropriate.  On
-+   targets like the MIPS which support options to change the
-+   endianness, which function to call is a runtime decision.  On
-+   other targets, `md_number_to_chars' can be a simple macro.  */
-+#define md_number_to_chars number_to_chars_bigendian
-+
-+/* `md_short_jump_size'
-+   `md_long_jump_size'
-+   `md_create_short_jump'
-+   `md_create_long_jump'
-+   If `WORKING_DOT_WORD' is defined, GAS will not do broken word
-+   processing (*note Broken words::.).  Otherwise, you should set
-+   `md_short_jump_size' to the size of a short jump (a jump that is
-+   just long enough to jump around a long jmp) and
-+   `md_long_jump_size' to the size of a long jump (a jump that can go
-+   anywhere in the function), You should define
-+   `md_create_short_jump' to create a short jump around a long jump,
-+   and define `md_create_long_jump' to create a long jump.  */
-+#define WORKING_DOT_WORD
-+
-+/* If you define this macro, it means that `tc_gen_reloc' may return
-+   multiple relocation entries for a single fixup.  In this case, the
-+   return value of `tc_gen_reloc' is a pointer to a null terminated
-+   array.  */
-+#undef RELOC_EXPANSION_POSSIBLE
-+
-+/* If you define this macro, GAS will not require pseudo-ops to start with a .
-+   character. */
-+#define NO_PSEUDO_DOT (avr32_iarcompat)
-+
-+/* The IAR assembler uses $ as the location counter. Unfortunately, we
-+   can't make this dependent on avr32_iarcompat... */
-+#define DOLLAR_DOT
-+
-+/* Values passed to md_apply_fix3 don't include the symbol value.  */
-+#define MD_APPLY_SYM_VALUE(FIX) 0
-+
-+/* The number of bytes to put into a word in a listing.  This affects
-+   the way the bytes are clumped together in the listing.  For
-+   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 LISTING_WORD_SIZE 4
-+
-+/* extern const struct relax_type md_relax_table[];
-+#define TC_GENERIC_RELAX_TABLE md_relax_table */
-+
-+/*
-+  An `.lcomm' directive with no explicit alignment parameter will use
-+  this macro to set P2VAR to the alignment that a request for SIZE
-+  bytes will have.  The alignment is expressed as a power of two.  If
-+  no alignment should take place, the macro definition should do
-+  nothing.  Some targets define a `.bss' directive that is also
-+  affected by this macro.  The default definition will set P2VAR to
-+  the truncated power of two of sizes up to eight bytes.
-+
-+  We want doublewords to be word-aligned, so we're going to modify the
-+  default definition a tiny bit.
-+*/
-+#define TC_IMPLICIT_LCOMM_ALIGNMENT(SIZE, P2VAR)      \
-+  do                                                  \
-+    {                                                 \
-+      if ((SIZE) >= 4)                                        \
-+      (P2VAR) = 2;                                    \
-+      else if ((SIZE) >= 2)                           \
-+      (P2VAR) = 1;                                    \
-+      else                                            \
-+      (P2VAR) = 0;                                    \
-+    }                                                 \
-+  while (0)
-+
-+/* When relaxing, we need to generate relocations for alignment
-+   directives.  */
-+#define HANDLE_ALIGN(frag) avr32_handle_align(frag)
-+extern void avr32_handle_align(fragS *);
-+
-+/* See internals doc for explanation. Oh wait...
-+   Now, can you guess where "alignment" comes from? ;-) */
-+#define MAX_MEM_FOR_RS_ALIGN_CODE ((1 << alignment) - 1)
-+
-+/* We need to stop gas from reducing certain expressions (e.g. GOT
-+   references) */
-+#define tc_fix_adjustable(fix) avr32_fix_adjustable(fix)
-+extern bfd_boolean avr32_fix_adjustable(struct fix *);
-+
-+/* The linker needs to be passed a little more information when relaxing. */
-+#define TC_FORCE_RELOCATION(fix) avr32_force_reloc(fix)
-+extern bfd_boolean avr32_force_reloc(struct fix *);
-+
-+/* I'm tired of working around all the madness in fixup_segment().
-+   This hook will do basically the same things as the generic code,
-+   and then it will "goto" right past it.  */
-+#define TC_VALIDATE_FIX(FIX, SEG, SKIP)               \
-+  do                                          \
-+    {                                         \
-+      avr32_process_fixup(FIX, SEG);          \
-+      if (!(FIX)->fx_done)                    \
-+      ++seg_reloc_count;                      \
-+      goto SKIP;                              \
-+    }                                         \
-+  while (0)
-+extern void avr32_process_fixup(struct fix *fixP, segT this_segment);
-+
-+/* Positive values of TC_FX_SIZE_SLACK allow a target to define
-+   fixups that far past the end of a frag.  Having such fixups
-+   is of course most most likely a bug in setting fx_size correctly.
-+   A negative value disables the fixup check entirely, which is
-+   appropriate for something like the Renesas / SuperH SH_COUNT
-+   reloc.  */
-+/* This target is buggy, and sets fix size too large.  */
-+#define TC_FX_SIZE_SLACK(FIX) -1
-+
-+/* We don't want the gas core to make any assumptions about our way of
-+   doing linkrelaxing.  */
-+#define TC_LINKRELAX_FIXUP(SEG)                       0
-+
-+/* ... but we do want it to insert lots of padding. */
-+#define LINKER_RELAXING_SHRINKS_ONLY
-+
-+/* Better do it ourselves, really... */
-+#define TC_RELAX_ALIGN(SEG, FRAG, ADDR)       avr32_relax_align(SEG, FRAG, ADDR)
-+extern relax_addressT
-+avr32_relax_align(segT segment, fragS *fragP, relax_addressT address);
-+
-+/* Use line number format that is amenable to linker relaxation.  */
-+#define DWARF2_USE_FIXED_ADVANCE_PC (linkrelax != 0)
-+
-+/* This is called by write_object_file() just before symbols are
-+   attempted converted into section symbols.  */
-+#define tc_frob_file_before_adjust()  avr32_frob_file()
-+extern void avr32_frob_file(void);
-+
-+/* If you define this macro, GAS will call it at the end of each input
-+   file.  */
-+#define md_cleanup() avr32_cleanup()
-+extern void avr32_cleanup(void);
-+
-+/* There's an AVR32-specific hack in operand() which creates O_md
-+   expressions when encountering HWRD or LWRD. We need to generate
-+   proper relocs for them */
-+/* #define md_cgen_record_fixup_exp avr32_cgen_record_fixup_exp */
-+
-+/* I needed to add an extra hook in gas_cgen_finish_insn() for
-+   conversion of O_md* operands because md_cgen_record_fixup_exp()
-+   isn't called for relaxable insns */
-+/* #define md_cgen_convert_expr(exp, opinfo) avr32_cgen_convert_expr(exp, opinfo)
-+   int avr32_cgen_convert_expr(expressionS *, int); */
-+
-+/* #define tc_gen_reloc gas_cgen_tc_gen_reloc */
-+
-+/* If you define this macro, it should return the position from which
-+   the PC relative adjustment for a PC relative fixup should be
-+   made. On many processors, the base of a PC relative instruction is
-+   the next instruction, so this macro would return the length of an
-+   instruction, plus the address of the PC relative fixup. The latter
-+   can be calculated as fixp->fx_where + fixp->fx_frag->fr_address. */
-+extern long md_pcrel_from_section (struct fix *, segT);
-+#define MD_PCREL_FROM_SECTION(FIX, SEC) md_pcrel_from_section (FIX, SEC)
-+
-+#define LOCAL_LABEL(name) (name[0] == '.' && (name[1] == 'L'))
-+#define LOCAL_LABELS_FB               1
-+
-+struct avr32_relaxer
-+{
-+  int (*estimate_size)(fragS *, segT);
-+  long (*relax_frag)(segT, fragS *, long);
-+  void (*convert_frag)(bfd *, segT, fragS *);
-+};
-+
-+/* AVR32 has quite complex instruction coding, which means we need
-+ * lots of information in order to do the right thing during relaxing
-+ * (basically, we need to be able to reconstruct a whole new opcode if
-+ * necessary) */
-+#define TC_FRAG_TYPE struct avr32_frag_data
-+
-+struct cpool;
-+
-+struct avr32_frag_data
-+{
-+  /* TODO: Maybe add an expression object here so that we can use
-+     fix_new_exp() in md_convert_frag?  We may have to decide
-+     pcrel-ness in md_estimate_size_before_relax() as well...or we
-+     might do it when parsing.  Doing it while parsing may fail
-+     because the sub_symbol is undefined then... */
-+  int pcrel;
-+  int force_extended;
-+  int reloc_info;
-+  struct avr32_relaxer *relaxer;
-+  expressionS exp;
-+
-+  /* Points to associated constant pool, for use by LDA and CALL in
-+     non-pic mode, and when relaxing the .cpool directive */
-+  struct cpool *pool;
-+  unsigned int pool_entry;
-+};
-+
-+/* We will have to initialize the fields explicitly when needed */
-+#define TC_FRAG_INIT(fragP)
-+
-+#define md_estimate_size_before_relax(fragP, segT)                    \
-+  ((fragP)->tc_frag_data.relaxer->estimate_size(fragP, segT))
-+#define md_relax_frag(segment, fragP, stretch)                                \
-+  ((fragP)->tc_frag_data.relaxer->relax_frag(segment, fragP, stretch))
-+#define md_convert_frag(abfd, segment, fragP)                         \
-+  ((fragP)->tc_frag_data.relaxer->convert_frag(abfd, segment, fragP))
-+
-+#define TC_FIX_TYPE struct avr32_fix_data
-+
-+struct avr32_fix_data
-+{
-+  const struct avr32_ifield *ifield;
-+  unsigned int align;
-+  long min;
-+  long max;
-+};
-+
-+#define TC_INIT_FIX_DATA(fixP)                        \
-+  do                                          \
-+    {                                         \
-+      (fixP)->tc_fix_data.ifield = NULL;      \
-+      (fixP)->tc_fix_data.align = 0;          \
-+      (fixP)->tc_fix_data.min = 0;            \
-+      (fixP)->tc_fix_data.max = 0;            \
-+    }                                         \
-+  while (0)
---- a/gas/configure.tgt
-+++ b/gas/configure.tgt
-@@ -33,6 +33,7 @@ case ${cpu} in
-   am33_2.0)           cpu_type=mn10300 endian=little ;;
-   arm*be|arm*b)               cpu_type=arm endian=big ;;
-   arm*)                       cpu_type=arm endian=little ;;
-+  avr32*)             cpu_type=avr32 endian=big ;;
-   bfin*)              cpu_type=bfin endian=little ;;
-   c4x*)                       cpu_type=tic4x ;;
-   cr16*)              cpu_type=cr16 endian=little ;;
-@@ -129,6 +130,9 @@ case ${generic_target} in
-   bfin-*elf)                          fmt=elf ;;
-   cr16-*-elf*)                                fmt=elf ;;
-+  avr32-*-linux*)                     fmt=elf  em=linux bfd_gas=yes ;;
-+  avr32*)                             fmt=elf  bfd_gas=yes ;;
-+
-   cris-*-linux-* | crisv32-*-linux-*)
-                                       fmt=multi em=linux ;;
-   cris-*-* | crisv32-*-*)             fmt=multi ;;
---- a/gas/doc/all.texi
-+++ b/gas/doc/all.texi
-@@ -30,6 +30,7 @@
- @set ARC
- @set ARM
- @set AVR
-+@set AVR32
- @set BFIN
- @set CR16
- @set CRIS
---- a/gas/doc/as.texinfo
-+++ b/gas/doc/as.texinfo
-@@ -6353,6 +6353,9 @@ subject, see the hardware manufacturer's
- @ifset AVR
- * AVR-Dependent::               AVR Dependent Features
- @end ifset
-+@ifset AVR32
-+* AVR32-Dependent::             AVR32 Dependent Features
-+@end ifset
- @ifset BFIN
- * BFIN-Dependent::            BFIN Dependent Features
- @end ifset
-@@ -6476,6 +6479,10 @@ subject, see the hardware manufacturer's
- @include c-avr.texi
- @end ifset
-+@ifset AVR32
-+@include c-avr32.texi
-+@end ifset
-+
- @ifset BFIN
- @include c-bfin.texi
- @end ifset
---- /dev/null
-+++ b/gas/doc/c-avr32.texi
-@@ -0,0 +1,247 @@
-+@c Copyright 2005, 2006
-+@c Atmel Corporation
-+@c This is part of the GAS manual.
-+@c For copying conditions, see the file as.texinfo.
-+
-+@ifset GENERIC
-+@page
-+@node AVR32-Dependent
-+@chapter AVR32 Dependent Features
-+@end ifset
-+
-+@ifclear GENERIC
-+@node Machine Dependencies
-+@chapter AVR32 Dependent Features
-+@end ifclear
-+
-+@cindex AVR32 support
-+@menu
-+* AVR32 Options::               Options
-+* AVR32 Syntax::                Syntax
-+* AVR32 Directives::            Directives
-+* AVR32 Opcodes::               Opcodes
-+@end menu
-+
-+@node AVR32 Options
-+@section Options
-+@cindex AVR32 options
-+@cindex options for AVR32
-+
-+There are currently no AVR32-specific options.  However, the following
-+options are planned:
-+
-+@table @code
-+
-+@cindex @code{--pic} command line option, AVR32
-+@cindex PIC code generation for AVR32
-+@item --pic
-+This option specifies that the output of the assembler should be marked
-+as position-independent code (PIC).  It will also ensure that
-+pseudo-instructions that deal with address calculation are output as
-+PIC, and that all absolute address references in the code are marked as
-+such.
-+
-+@cindex @code{--linkrelax} command line option, AVR32
-+@item --linkrelax
-+This option specifies that the output of the assembler should be marked
-+as linker-relaxable.  It will also ensure that all PC-relative operands
-+that may change during linker relaxation get appropriate relocations.
-+
-+@end table
-+
-+
-+@node AVR32 Syntax
-+@section Syntax
-+@menu
-+* AVR32-Chars::              Special Characters
-+* AVR32-Symrefs::            Symbol references
-+@end menu
-+
-+@node AVR32-Chars
-+@subsection Special Characters
-+
-+@cindex line comment character, AVR32
-+@cindex AVR32 line comment character
-+The presence of a @samp{//} on a line indicates the start of a comment
-+that extends to the end of the current line.  If a @samp{#} appears as
-+the first character of a line, the whole line is treated as a comment.
-+
-+@cindex line separator, AVR32
-+@cindex statement separator, AVR32
-+@cindex AVR32 line separator
-+The @samp{;} character can be used instead of a newline to separate
-+statements.
-+
-+@node AVR32-Symrefs
-+@subsection Symbol references
-+
-+The absolute value of a symbol can be obtained by simply naming the
-+symbol.  However, as AVR32 symbols have 32-bit values, most symbols have
-+values that are outside the range of any instructions.
-+
-+Instructions that take a PC-relative offset, e.g. @code{lddpc} or
-+@code{rcall}, can also reference a symbol by simply naming the symbol
-+(no explicit calculations necessary).  In this case, the assembler or
-+linker subtracts the address of the instruction from the symbol's value
-+and inserts the result into the instruction.  Note that even though an
-+overflow is less likely to happen for a relative reference than for an
-+absolute reference, the assembler or linker will generate an error if
-+the referenced symbol is too far away from the current location.
-+
-+Relative references can be used for data as well.  For example:
-+
-+@smallexample
-+        lddpc   r0, 2f
-+1:      add     r0, pc
-+        ...
-+        .align  2
-+2:      .int    @var{some_symbol} - 1b
-+@end smallexample
-+
-+Here, r0 will end up with the run-time address of @var{some_symbol} even
-+if the program was loaded at a different address than it was linked
-+(position-independent code).
-+
-+@subsubsection Symbol modifiers
-+
-+@table @code
-+
-+@item @code{hi(@var{symbol})}
-+Evaluates to the value of the symbol shifted right 16 bits.  This will
-+work even if @var{symbol} is defined in a different module.
-+
-+@item @code{lo(@var{symbol})}
-+Evaluates to the low 16 bits of the symbol's value.  This will work even
-+if @var{symbol} is defined in a different module.
-+
-+@item @code{@var{symbol}@@got}
-+Create a GOT entry for @var{symbol} and return the offset of that entry
-+relative to the GOT base.
-+
-+@end table
-+
-+
-+@node AVR32 Directives
-+@section Directives
-+@cindex machine directives, AVR32
-+@cindex AVR32 directives
-+
-+@table @code
-+
-+@cindex @code{.cpool} directive, AVR32
-+@item .cpool
-+This directive causes the current contents of the constant pool to be
-+dumped into the current section at the current location (aligned to a
-+word boundary).  @code{GAS} maintains a separate constant pool for each
-+section and each sub-section.  The @code{.cpool} directive will only
-+affect the constant pool of the current section and sub-section.  At the
-+end of assembly, all remaining, non-empty constant pools will
-+automatically be dumped.
-+
-+@end table
-+
-+
-+@node AVR32 Opcodes
-+@section Opcodes
-+@cindex AVR32 opcodes
-+@cindex opcodes for AVR32
-+
-+@code{@value{AS}} implements all the standard AVR32 opcodes.  It also
-+implements several pseudo-opcodes, which are recommended to use wherever
-+possible because they give the tool chain better freedom to generate
-+optimal code.
-+
-+@table @code
-+
-+@cindex @code{LDA.W reg, symbol} pseudo op, AVR32
-+@item LDA.W
-+@smallexample
-+        lda.w   @var{reg}, @var{symbol}
-+@end smallexample
-+
-+This instruction will load the address of @var{symbol} into
-+@var{reg}. The instruction will evaluate to one of the following,
-+depending on the relative distance to the symbol, the relative distance
-+to the constant pool and whether the @code{--pic} option has been
-+specified. If the @code{--pic} option has not been specified, the
-+alternatives are as follows:
-+@smallexample
-+        /* @var{symbol} evaluates to a small enough value */
-+        mov     @var{reg}, @var{symbol}
-+
-+        /* (. - @var{symbol}) evaluates to a small enough value */
-+        sub     @var{reg}, pc, . - @var{symbol}
-+
-+        /* Constant pool is close enough */
-+        lddpc   @var{reg}, @var{cpent}
-+        ...
-+@var{cpent}:
-+        .long   @var{symbol}
-+
-+        /* Otherwise (not implemented yet, probably not necessary) */
-+        mov     @var{reg}, lo(@var{symbol})
-+        orh     @var{reg}, hi(@var{symbol})
-+@end smallexample
-+
-+If the @code{--pic} option has been specified, the alternatives are as
-+follows:
-+@smallexample
-+        /* (. - @var{symbol}) evaluates to a small enough value */
-+        sub     @var{reg}, pc, . - @var{symbol}
-+
-+        /* If @code{--linkrelax} not specified */
-+        ld.w    @var{reg}, r6[@var{symbol}@@got]
-+
-+        /* Otherwise */
-+        mov     @var{reg}, @var{symbol}@@got / 4
-+        ld.w    @var{reg}, r6[@var{reg} << 2]
-+@end smallexample
-+
-+If @var{symbol} is not defined in the same file and section as the
-+@code{LDA.W} instruction, the most pessimistic alternative of the
-+above is selected. The linker may convert it back into the most
-+optimal alternative when the final value of all symbols is known.
-+
-+@cindex @code{CALL symbol} pseudo op, AVR32
-+@item CALL
-+@smallexample
-+        call    @var{symbol}
-+@end smallexample
-+
-+This instruction will insert code to call the subroutine identified by
-+@var{symbol}. It will evaluate to one of the following, depending on
-+the relative distance to the symbol as well as the @code{--linkrelax}
-+and @code{--pic} command-line options.
-+
-+If @var{symbol} is defined in the same section and input file, and the
-+distance is small enough, an @code{rcall} instruction is inserted:
-+@smallexample
-+        rcall   @var{symbol}
-+@end smallexample
-+
-+Otherwise, if the @code{--pic} option has not been specified:
-+@smallexample
-+        mcall   @var{cpent}
-+        ...
-+@var{cpent}:
-+        .long   @var{symbol}
-+@end smallexample
-+
-+Finally, if nothing else fits and the @code{--pic} option has been
-+specified, the assembler will indirect the call through the Global
-+Offset Table:
-+@smallexample
-+        /* If @code{--linkrelax} not specified */
-+        mcall   r6[@var{symbol}@@got]
-+
-+        /* If @code{--linkrelax} specified */
-+        mov     lr, @var{symbol}@@got / 4
-+        ld.w    lr, r6[lr << 2]
-+        icall   lr
-+@end smallexample
-+
-+The linker, after determining the final value of @var{symbol}, may
-+convert any of these into more optimal alternatives. This includes
-+deleting any superfluous constant pool- and GOT-entries.
-+
-+@end table
---- a/gas/doc/Makefile.am
-+++ b/gas/doc/Makefile.am
-@@ -33,6 +33,7 @@ CPU_DOCS = \
-       c-arc.texi \
-       c-arm.texi \
-       c-avr.texi \
-+    c-avr32.texi \
-       c-bfin.texi \
-       c-cr16.texi \
-       c-d10v.texi \
---- a/gas/Makefile.am
-+++ b/gas/Makefile.am
-@@ -47,6 +47,7 @@ CPU_TYPES = \
-       arc \
-       arm \
-       avr \
-+      avr32 \
-       bfin \
-       cr16 \
-       cris \
-@@ -241,6 +242,7 @@ TARGET_CPU_CFILES = \
-       config/tc-arc.c \
-       config/tc-arm.c \
-       config/tc-avr.c \
-+      config/tc-avr32.c \
-       config/tc-bfin.c \
-       config/tc-cr16.c \
-       config/tc-cris.c \
-@@ -296,6 +298,7 @@ TARGET_CPU_HFILES = \
-       config/tc-arc.h \
-       config/tc-arm.h \
-       config/tc-avr.h \
-+      config/tc-avr32.h \
-       config/tc-bfin.h \
-       config/tc-cr16.h \
-       config/tc-cris.h \
-@@ -1050,6 +1053,11 @@ DEPTC_avr_elf = $(srcdir)/config/obj-elf
-   $(INCDIR)/bfdlink.h $(srcdir)/config/tc-avr.h dwarf2dbg.h \
-   $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
-   $(INCDIR)/opcode/avr.h
-+DEPTC_avr32_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
-+  $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
-+  $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-avr32.h \
-+  $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
-+  $(srcdir)/../opcodes/avr32-opc.h $(srcdir)/../opcodes/avr32-asm.h
- DEPTC_bfin_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
-   $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
-   $(INCDIR)/bfdlink.h $(srcdir)/config/tc-bfin.h dwarf2dbg.h \
-@@ -1487,6 +1495,11 @@ DEPOBJ_avr_elf = $(srcdir)/config/obj-el
-   $(INCDIR)/bfdlink.h $(srcdir)/config/tc-avr.h dwarf2dbg.h \
-   $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
-   $(INCDIR)/obstack.h struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
-+DEPOBJ_avr32_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
-+  $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
-+  $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-avr32.h \
-+  $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
-+  struc-symbol.h dwarf2dbg.h
- DEPOBJ_bfin_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
-   $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
-   $(INCDIR)/bfdlink.h $(srcdir)/config/tc-bfin.h dwarf2dbg.h \
-@@ -1858,6 +1871,9 @@ DEP_cr16_elf = $(srcdir)/config/obj-elf.
-   $(INCDIR)/bfdlink.h $(srcdir)/config/tc-cr16.h dwarf2dbg.h \
-   $(srcdir)/config/obj-coff.h $(INCDIR)/coff/internal.h \
-   $(BFDDIR)/libcoff.h
-+DEP_avr32_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
-+  $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
-+  $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-avr32.h
- DEP_cris_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-cris.h \
-   $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h
- DEP_cris_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
---- /dev/null
-+++ b/gas/testsuite/gas/avr32/aliases.d
-@@ -0,0 +1,19 @@
-+#as:
-+#objdump: -dr
-+#name: aliases
-+
-+.*: +file format .*
-+
-+Disassembly of section \.text:
-+
-+00000000 <ld_nodisp>:
-+   0: 19 80      [ \t]+ld\.ub r0,r12\[0x0\]
-+   2: f9 20 00 00[ \t]+ld\.sb r0,r12\[0\]
-+   6: 98 80      [ \t]+ld\.uh r0,r12\[0x0\]
-+   8: 98 00      [ \t]+ld\.sh r0,r12\[0x0\]
-+   a: 78 00      [ \t]+ld\.w r0,r12\[0x0\]
-+
-+0000000c <st_nodisp>:
-+   c: b8 80      [ \t]+st\.b r12\[0x0\],r0
-+   e: b8 00      [ \t]+st\.h r12\[0x0\],r0
-+  10: 99 00      [ \t]+st\.w r12\[0x0\],r0
---- /dev/null
-+++ b/gas/testsuite/gas/avr32/aliases.s
-@@ -0,0 +1,14 @@
-+      .text
-+      .global ld_nodisp
-+ld_nodisp:
-+      ld.ub   r0, r12
-+      ld.sb   r0, r12
-+      ld.uh   r0, r12
-+      ld.sh   r0, r12
-+      ld.w    r0, r12
-+
-+      .global st_nodisp
-+st_nodisp:
-+      st.b    r12, r0
-+      st.h    r12, r0
-+      st.w    r12, r0
---- /dev/null
-+++ b/gas/testsuite/gas/avr32/allinsn.d
-@@ -0,0 +1,2987 @@
-+#as:
-+#objdump: -dr
-+#name: allinsn
-+
-+.*: +file format .*
-+
-+Disassembly of section \.text:
-+
-+[0-9a-f]* <ld_d5>:
-+ *[0-9a-f]*:  fe 0f 02 3e     ld\.d lr,pc\[pc<<0x3\]
-+ *[0-9a-f]*:  e0 00 02 00     ld\.d r0,r0\[r0\]
-+ *[0-9a-f]*:  ea 05 02 26     ld\.d r6,r5\[r5<<0x2\]
-+ *[0-9a-f]*:  e8 04 02 14     ld\.d r4,r4\[r4<<0x1\]
-+ *[0-9a-f]*:  fc 0e 02 1e     ld\.d lr,lr\[lr<<0x1\]
-+ *[0-9a-f]*:  e6 0d 02 2a     ld\.d r10,r3\[sp<<0x2\]
-+ *[0-9a-f]*:  f4 06 02 28     ld\.d r8,r10\[r6<<0x2\]
-+ *[0-9a-f]*:  ee 09 02 02     ld\.d r2,r7\[r9\]
-+
-+[0-9a-f]* <ld_w5>:
-+ *[0-9a-f]*:  fe 0f 03 0f     ld\.w pc,pc\[pc\]
-+ *[0-9a-f]*:  f8 0c 03 3c     ld\.w r12,r12\[r12<<0x3\]
-+ *[0-9a-f]*:  ea 05 03 25     ld\.w r5,r5\[r5<<0x2\]
-+ *[0-9a-f]*:  e8 04 03 14     ld\.w r4,r4\[r4<<0x1\]
-+ *[0-9a-f]*:  fc 0e 03 1e     ld\.w lr,lr\[lr<<0x1\]
-+ *[0-9a-f]*:  f2 09 03 02     ld\.w r2,r9\[r9\]
-+ *[0-9a-f]*:  e4 06 03 0b     ld\.w r11,r2\[r6\]
-+ *[0-9a-f]*:  e4 0d 03 30     ld\.w r0,r2\[sp<<0x3\]
-+
-+[0-9a-f]* <ld_sh5>:
-+ *[0-9a-f]*:  fe 0f 04 0f     ld\.sh pc,pc\[pc\]
-+ *[0-9a-f]*:  f8 0c 04 3c     ld\.sh r12,r12\[r12<<0x3\]
-+ *[0-9a-f]*:  ea 05 04 25     ld\.sh r5,r5\[r5<<0x2\]
-+ *[0-9a-f]*:  e8 04 04 14     ld\.sh r4,r4\[r4<<0x1\]
-+ *[0-9a-f]*:  fc 0e 04 1e     ld\.sh lr,lr\[lr<<0x1\]
-+ *[0-9a-f]*:  e0 0f 04 2b     ld\.sh r11,r0\[pc<<0x2\]
-+ *[0-9a-f]*:  fa 06 04 2a     ld\.sh r10,sp\[r6<<0x2\]
-+ *[0-9a-f]*:  e4 02 04 0c     ld\.sh r12,r2\[r2\]
-+
-+[0-9a-f]* <ld_uh5>:
-+ *[0-9a-f]*:  fe 0f 05 0f     ld\.uh pc,pc\[pc\]
-+ *[0-9a-f]*:  f8 0c 05 3c     ld\.uh r12,r12\[r12<<0x3\]
-+ *[0-9a-f]*:  ea 05 05 25     ld\.uh r5,r5\[r5<<0x2\]
-+ *[0-9a-f]*:  e8 04 05 14     ld\.uh r4,r4\[r4<<0x1\]
-+ *[0-9a-f]*:  fc 0e 05 1e     ld\.uh lr,lr\[lr<<0x1\]
-+ *[0-9a-f]*:  fe 0e 05 38     ld\.uh r8,pc\[lr<<0x3\]
-+ *[0-9a-f]*:  e2 0f 05 16     ld\.uh r6,r1\[pc<<0x1\]
-+ *[0-9a-f]*:  fc 0d 05 16     ld\.uh r6,lr\[sp<<0x1\]
-+
-+[0-9a-f]* <ld_sb2>:
-+ *[0-9a-f]*:  fe 0f 06 0f     ld\.sb pc,pc\[pc\]
-+ *[0-9a-f]*:  f8 0c 06 3c     ld\.sb r12,r12\[r12<<0x3\]
-+ *[0-9a-f]*:  ea 05 06 25     ld\.sb r5,r5\[r5<<0x2\]
-+ *[0-9a-f]*:  e8 04 06 14     ld\.sb r4,r4\[r4<<0x1\]
-+ *[0-9a-f]*:  fc 0e 06 1e     ld\.sb lr,lr\[lr<<0x1\]
-+ *[0-9a-f]*:  e2 0f 06 39     ld\.sb r9,r1\[pc<<0x3\]
-+ *[0-9a-f]*:  e6 0b 06 10     ld\.sb r0,r3\[r11<<0x1\]
-+ *[0-9a-f]*:  ea 05 06 1a     ld\.sb r10,r5\[r5<<0x1\]
-+
-+[0-9a-f]* <ld_ub5>:
-+ *[0-9a-f]*:  fe 0f 07 0f     ld\.ub pc,pc\[pc\]
-+ *[0-9a-f]*:  f8 0c 07 3c     ld\.ub r12,r12\[r12<<0x3\]
-+ *[0-9a-f]*:  ea 05 07 25     ld\.ub r5,r5\[r5<<0x2\]
-+ *[0-9a-f]*:  e8 04 07 14     ld\.ub r4,r4\[r4<<0x1\]
-+ *[0-9a-f]*:  fc 0e 07 1e     ld\.ub lr,lr\[lr<<0x1\]
-+ *[0-9a-f]*:  f8 07 07 36     ld\.ub r6,r12\[r7<<0x3\]
-+ *[0-9a-f]*:  ec 0c 07 02     ld\.ub r2,r6\[r12\]
-+ *[0-9a-f]*:  ee 0b 07 10     ld\.ub r0,r7\[r11<<0x1\]
-+
-+[0-9a-f]* <st_d5>:
-+ *[0-9a-f]*:  fe 0f 08 0e     st\.d pc\[pc\],lr
-+ *[0-9a-f]*:  f8 0c 08 3c     st\.d r12\[r12<<0x3\],r12
-+ *[0-9a-f]*:  ea 05 08 26     st\.d r5\[r5<<0x2\],r6
-+ *[0-9a-f]*:  e8 04 08 14     st\.d r4\[r4<<0x1\],r4
-+ *[0-9a-f]*:  fc 0e 08 1e     st\.d lr\[lr<<0x1\],lr
-+ *[0-9a-f]*:  e2 09 08 14     st\.d r1\[r9<<0x1\],r4
-+ *[0-9a-f]*:  f4 02 08 14     st\.d r10\[r2<<0x1\],r4
-+ *[0-9a-f]*:  f8 06 08 0e     st\.d r12\[r6\],lr
-+
-+[0-9a-f]* <st_w5>:
-+ *[0-9a-f]*:  fe 0f 09 0f     st\.w pc\[pc\],pc
-+ *[0-9a-f]*:  f8 0c 09 3c     st\.w r12\[r12<<0x3\],r12
-+ *[0-9a-f]*:  ea 05 09 25     st\.w r5\[r5<<0x2\],r5
-+ *[0-9a-f]*:  e8 04 09 14     st\.w r4\[r4<<0x1\],r4
-+ *[0-9a-f]*:  fc 0e 09 1e     st\.w lr\[lr<<0x1\],lr
-+ *[0-9a-f]*:  e2 0a 09 03     st\.w r1\[r10\],r3
-+ *[0-9a-f]*:  e0 0a 09 19     st\.w r0\[r10<<0x1\],r9
-+ *[0-9a-f]*:  e8 05 09 3f     st\.w r4\[r5<<0x3\],pc
-+
-+[0-9a-f]* <st_h5>:
-+ *[0-9a-f]*:  fe 0f 0a 0f     st\.h pc\[pc\],pc
-+ *[0-9a-f]*:  f8 0c 0a 3c     st\.h r12\[r12<<0x3\],r12
-+ *[0-9a-f]*:  ea 05 0a 25     st\.h r5\[r5<<0x2\],r5
-+ *[0-9a-f]*:  e8 04 0a 14     st\.h r4\[r4<<0x1\],r4
-+ *[0-9a-f]*:  fc 0e 0a 1e     st\.h lr\[lr<<0x1\],lr
-+ *[0-9a-f]*:  e4 09 0a 0b     st\.h r2\[r9\],r11
-+ *[0-9a-f]*:  ea 01 0a 2c     st\.h r5\[r1<<0x2\],r12
-+ *[0-9a-f]*:  fe 08 0a 23     st\.h pc\[r8<<0x2\],r3
-+
-+[0-9a-f]* <st_b5>:
-+ *[0-9a-f]*:  fe 0f 0b 0f     st\.b pc\[pc\],pc
-+ *[0-9a-f]*:  f8 0c 0b 3c     st\.b r12\[r12<<0x3\],r12
-+ *[0-9a-f]*:  ea 05 0b 25     st\.b r5\[r5<<0x2\],r5
-+ *[0-9a-f]*:  e8 04 0b 14     st\.b r4\[r4<<0x1\],r4
-+ *[0-9a-f]*:  fc 0e 0b 1e     st\.b lr\[lr<<0x1\],lr
-+ *[0-9a-f]*:  e2 08 0b 16     st\.b r1\[r8<<0x1\],r6
-+ *[0-9a-f]*:  fc 0e 0b 31     st\.b lr\[lr<<0x3\],r1
-+ *[0-9a-f]*:  ea 00 0b 2f     st\.b r5\[r0<<0x2\],pc
-+
-+[0-9a-f]* <divs>:
-+ *[0-9a-f]*:  fe 0f 0c 0f     divs pc,pc,pc
-+ *[0-9a-f]*:  f8 0c 0c 0c     divs r12,r12,r12
-+ *[0-9a-f]*:  ea 05 0c 05     divs r5,r5,r5
-+ *[0-9a-f]*:  e8 04 0c 04     divs r4,r4,r4
-+ *[0-9a-f]*:  fc 0e 0c 0e     divs lr,lr,lr
-+ *[0-9a-f]*:  fe 0f 0c 03     divs r3,pc,pc
-+ *[0-9a-f]*:  f8 02 0c 09     divs r9,r12,r2
-+ *[0-9a-f]*:  e8 01 0c 07     divs r7,r4,r1
-+
-+[0-9a-f]* <add1>:
-+ *[0-9a-f]*:  1e 0f           add pc,pc
-+ *[0-9a-f]*:  18 0c           add r12,r12
-+ *[0-9a-f]*:  0a 05           add r5,r5
-+ *[0-9a-f]*:  08 04           add r4,r4
-+ *[0-9a-f]*:  1c 0e           add lr,lr
-+ *[0-9a-f]*:  12 0c           add r12,r9
-+ *[0-9a-f]*:  06 06           add r6,r3
-+ *[0-9a-f]*:  18 0a           add r10,r12
-+
-+[0-9a-f]* <sub1>:
-+ *[0-9a-f]*:  1e 1f           sub pc,pc
-+ *[0-9a-f]*:  18 1c           sub r12,r12
-+ *[0-9a-f]*:  0a 15           sub r5,r5
-+ *[0-9a-f]*:  08 14           sub r4,r4
-+ *[0-9a-f]*:  1c 1e           sub lr,lr
-+ *[0-9a-f]*:  0c 1e           sub lr,r6
-+ *[0-9a-f]*:  1a 10           sub r0,sp
-+ *[0-9a-f]*:  18 16           sub r6,r12
-+
-+[0-9a-f]* <rsub1>:
-+ *[0-9a-f]*:  1e 2f           rsub pc,pc
-+ *[0-9a-f]*:  18 2c           rsub r12,r12
-+ *[0-9a-f]*:  0a 25           rsub r5,r5
-+ *[0-9a-f]*:  08 24           rsub r4,r4
-+ *[0-9a-f]*:  1c 2e           rsub lr,lr
-+ *[0-9a-f]*:  1a 2b           rsub r11,sp
-+ *[0-9a-f]*:  08 27           rsub r7,r4
-+ *[0-9a-f]*:  02 29           rsub r9,r1
-+
-+[0-9a-f]* <cp1>:
-+ *[0-9a-f]*:  1e 3f           cp\.w pc,pc
-+ *[0-9a-f]*:  18 3c           cp\.w r12,r12
-+ *[0-9a-f]*:  0a 35           cp\.w r5,r5
-+ *[0-9a-f]*:  08 34           cp\.w r4,r4
-+ *[0-9a-f]*:  1c 3e           cp\.w lr,lr
-+ *[0-9a-f]*:  04 36           cp\.w r6,r2
-+ *[0-9a-f]*:  12 30           cp\.w r0,r9
-+ *[0-9a-f]*:  1a 33           cp\.w r3,sp
-+
-+[0-9a-f]* <or1>:
-+ *[0-9a-f]*:  1e 4f           or pc,pc
-+ *[0-9a-f]*:  18 4c           or r12,r12
-+ *[0-9a-f]*:  0a 45           or r5,r5
-+ *[0-9a-f]*:  08 44           or r4,r4
-+ *[0-9a-f]*:  1c 4e           or lr,lr
-+ *[0-9a-f]*:  12 44           or r4,r9
-+ *[0-9a-f]*:  08 4b           or r11,r4
-+ *[0-9a-f]*:  00 44           or r4,r0
-+
-+[0-9a-f]* <eor1>:
-+ *[0-9a-f]*:  1e 5f           eor pc,pc
-+ *[0-9a-f]*:  18 5c           eor r12,r12
-+ *[0-9a-f]*:  0a 55           eor r5,r5
-+ *[0-9a-f]*:  08 54           eor r4,r4
-+ *[0-9a-f]*:  1c 5e           eor lr,lr
-+ *[0-9a-f]*:  16 5c           eor r12,r11
-+ *[0-9a-f]*:  02 50           eor r0,r1
-+ *[0-9a-f]*:  1e 55           eor r5,pc
-+
-+[0-9a-f]* <and1>:
-+ *[0-9a-f]*:  1e 6f           and pc,pc
-+ *[0-9a-f]*:  18 6c           and r12,r12
-+ *[0-9a-f]*:  0a 65           and r5,r5
-+ *[0-9a-f]*:  08 64           and r4,r4
-+ *[0-9a-f]*:  1c 6e           and lr,lr
-+ *[0-9a-f]*:  02 68           and r8,r1
-+ *[0-9a-f]*:  1a 60           and r0,sp
-+ *[0-9a-f]*:  0a 6a           and r10,r5
-+
-+[0-9a-f]* <tst>:
-+ *[0-9a-f]*:  1e 7f           tst pc,pc
-+ *[0-9a-f]*:  18 7c           tst r12,r12
-+ *[0-9a-f]*:  0a 75           tst r5,r5
-+ *[0-9a-f]*:  08 74           tst r4,r4
-+ *[0-9a-f]*:  1c 7e           tst lr,lr
-+ *[0-9a-f]*:  18 70           tst r0,r12
-+ *[0-9a-f]*:  0c 7a           tst r10,r6
-+ *[0-9a-f]*:  08 7d           tst sp,r4
-+
-+[0-9a-f]* <andn>:
-+ *[0-9a-f]*:  1e 8f           andn pc,pc
-+ *[0-9a-f]*:  18 8c           andn r12,r12
-+ *[0-9a-f]*:  0a 85           andn r5,r5
-+ *[0-9a-f]*:  08 84           andn r4,r4
-+ *[0-9a-f]*:  1c 8e           andn lr,lr
-+ *[0-9a-f]*:  18 89           andn r9,r12
-+ *[0-9a-f]*:  1a 8b           andn r11,sp
-+ *[0-9a-f]*:  0a 8c           andn r12,r5
-+
-+[0-9a-f]* <mov3>:
-+ *[0-9a-f]*:  1e 9f           mov pc,pc
-+ *[0-9a-f]*:  18 9c           mov r12,r12
-+ *[0-9a-f]*:  0a 95           mov r5,r5
-+ *[0-9a-f]*:  08 94           mov r4,r4
-+ *[0-9a-f]*:  1c 9e           mov lr,lr
-+ *[0-9a-f]*:  12 95           mov r5,r9
-+ *[0-9a-f]*:  16 9b           mov r11,r11
-+ *[0-9a-f]*:  1c 92           mov r2,lr
-+
-+[0-9a-f]* <st_w1>:
-+ *[0-9a-f]*:  1e af           st\.w pc\+\+,pc
-+ *[0-9a-f]*:  18 ac           st\.w r12\+\+,r12
-+ *[0-9a-f]*:  0a a5           st\.w r5\+\+,r5
-+ *[0-9a-f]*:  08 a4           st\.w r4\+\+,r4
-+ *[0-9a-f]*:  1c ae           st\.w lr\+\+,lr
-+ *[0-9a-f]*:  02 ab           st\.w r1\+\+,r11
-+ *[0-9a-f]*:  1a a0           st\.w sp\+\+,r0
-+ *[0-9a-f]*:  1a a1           st\.w sp\+\+,r1
-+
-+[0-9a-f]* <st_h1>:
-+ *[0-9a-f]*:  1e bf           st\.h pc\+\+,pc
-+ *[0-9a-f]*:  18 bc           st\.h r12\+\+,r12
-+ *[0-9a-f]*:  0a b5           st\.h r5\+\+,r5
-+ *[0-9a-f]*:  08 b4           st\.h r4\+\+,r4
-+ *[0-9a-f]*:  1c be           st\.h lr\+\+,lr
-+ *[0-9a-f]*:  18 bd           st\.h r12\+\+,sp
-+ *[0-9a-f]*:  0e be           st\.h r7\+\+,lr
-+ *[0-9a-f]*:  0e b4           st\.h r7\+\+,r4
-+
-+[0-9a-f]* <st_b1>:
-+ *[0-9a-f]*:  1e cf           st\.b pc\+\+,pc
-+ *[0-9a-f]*:  18 cc           st\.b r12\+\+,r12
-+ *[0-9a-f]*:  0a c5           st\.b r5\+\+,r5
-+ *[0-9a-f]*:  08 c4           st\.b r4\+\+,r4
-+ *[0-9a-f]*:  1c ce           st\.b lr\+\+,lr
-+ *[0-9a-f]*:  12 cd           st\.b r9\+\+,sp
-+ *[0-9a-f]*:  02 cd           st\.b r1\+\+,sp
-+ *[0-9a-f]*:  00 c4           st\.b r0\+\+,r4
-+
-+[0-9a-f]* <st_w2>:
-+ *[0-9a-f]*:  1e df           st\.w --pc,pc
-+ *[0-9a-f]*: