This is the mail archive of the binutils-cvs@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] FT32B is a new FT32 family member. It has a code compression scheme, which requires the use of linke


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=81b42bcab16f4462eb4c91db2cf09cd76e17402e

commit 81b42bcab16f4462eb4c91db2cf09cd76e17402e
Author: James Bowman <james.bowman@ftdichip.com>
Date:   Wed Nov 1 15:33:24 2017 +0000

    FT32B is a new FT32 family member. It has a code compression scheme, which requires the use of linker relaxations. The change is quite large, so submission is in several parts.
    
    Part 2 adds a relaxation pass, which actually implements the code compression scheme.
    
    bfd	* archures.c: Add bfd_mach_ft32b.
    	* cpu-ft32.c: Add arch_info_struct.
    	* elf32-ft32.c: Add R_FT32_RELAX, SC0, SC1,
    	DIFF32. (ft32_elf_relocate_section): Add clauses
    	for R_FT32_SC0, SC1, DIFF32.  (ft32_reloc_shortable,
    	elf32_ft32_is_diff_reloc, elf32_ft32_adjust_diff_reloc_value,
    	elf32_ft32_adjust_reloc_if_spans_insn,
    	elf32_ft32_relax_delete_bytes, elf32_ft32_relax_is_branch_target,
    	ft32_elf_relax_section): New function.
    	* reloc.c: Add BFD_RELOC_FT32_RELAX, SC0, SC1, DIFF32.
    	* bfd-in2.h: Regenerate.
    	* libbfd.h: Regenerate.
    
    gas	* config/tc-ft32.c (md_assemble): add relaxation reloc
    	BFD_RELOC_FT32_RELAX.  (md_longopts): Add "norelax" and
    	"no-relax". (md_apply_fix): Add reloc BFD_RELOC_FT32_DIFF32.
    	(relaxable_section, ft32_validate_fix_sub, ft32_force_relocation,
    	ft32_allow_local_subtract): New function.
    	* config/tc-ft32.h: remove unused MD_PCREL_FROM_SECTION.
    	* testsuite/gas/ft32/insnsc.s: New test exercising all FT32B
    	shortcodes.
    
    include	* elf/ft32.h: Add R_FT32_RELAX, SC0, SC1, DIFF32.

Diff:
---
 bfd/ChangeLog                         |   17 +
 bfd/archures.c                        |    1 +
 bfd/bfd-in2.h                         |    5 +
 bfd/cpu-ft32.c                        |   36 +-
 bfd/elf32-ft32.c                      |  898 ++++++++++++++++++-
 bfd/libbfd.h                          |    4 +
 bfd/reloc.c                           |    8 +
 binutils/ChangeLog                    |    4 +
 binutils/readelf.c                    |    2 +
 gas/ChangeLog                         |   31 +-
 gas/config/tc-ft32.c                  |  387 ++++++---
 gas/config/tc-ft32.h                  |   31 +-
 gas/testsuite/gas/all/gas.exp         |    2 +
 gas/testsuite/gas/elf/dwarf2-11.d     |    4 +-
 gas/testsuite/gas/elf/dwarf2-12.d     |    4 +-
 gas/testsuite/gas/elf/dwarf2-13.d     |    4 +-
 gas/testsuite/gas/elf/dwarf2-14.d     |    4 +-
 gas/testsuite/gas/elf/dwarf2-15.d     |    4 +-
 gas/testsuite/gas/elf/dwarf2-16.d     |    4 +-
 gas/testsuite/gas/elf/dwarf2-17.d     |    4 +-
 gas/testsuite/gas/elf/dwarf2-18.d     |    4 +-
 gas/testsuite/gas/elf/dwarf2-3.d      |    2 +-
 gas/testsuite/gas/elf/dwarf2-5.d      |    4 +-
 gas/testsuite/gas/elf/dwarf2-7.d      |    4 +-
 gas/testsuite/gas/ft32/ft32.exp       |    1 +
 gas/testsuite/gas/ft32/insn.d         |  472 +++++-----
 gas/testsuite/gas/ft32/insnsc.d       | 1546 +++++++++++++++++++++++++++++++++
 gas/testsuite/gas/ft32/insnsc.s       |  769 ++++++++++++++++
 gas/testsuite/gas/lns/lns-big-delta.d |    2 +-
 gas/testsuite/gas/lns/lns.exp         |    1 +
 include/ChangeLog                     |    4 +
 include/elf/ft32.h                    |    4 +
 32 files changed, 3875 insertions(+), 392 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 35308ab..b8cddd5 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,20 @@
+2017-11-01  James Bowman  <james.bowman@ftdichip.com>
+
+	* archures.c: Add bfd_mach_ft32b.
+	* cpu-ft32.c: Add arch_info_struct.
+	* elf32-ft32.c: Add R_FT32_RELAX, SC0, SC1,
+	DIFF32.
+	(ft32_elf_relocate_section): Add clauses for R_FT32_SC0, SC1,
+	DIFF32.
+	(ft32_reloc_shortable, elf32_ft32_is_diff_reloc)
+	(elf32_ft32_adjust_diff_reloc_value)
+	(elf32_ft32_adjust_reloc_if_spans_insn)
+	(elf32_ft32_relax_delete_bytes, elf32_ft32_relax_is_branch_target)
+	(ft32_elf_relax_section): New function.
+	* reloc.c: Add BFD_RELOC_FT32_RELAX, SC0, SC1, DIFF32.
+	* bfd-in2.h: Regenerate.
+	* libbfd.h: Regenerate.
+
 2017-11-01  Nick Clifton  <nickc@redhat.com>
 
 	PR 22376
diff --git a/bfd/archures.c b/bfd/archures.c
index 433b95f..bd5f933 100644
--- a/bfd/archures.c
+++ b/bfd/archures.c
@@ -406,6 +406,7 @@ DESCRIPTION
 .#define bfd_mach_moxie		1
 .  bfd_arch_ft32,       {* The ft32 processor *}
 .#define bfd_mach_ft32		1
+.#define bfd_mach_ft32b		2
 .  bfd_arch_mcore,
 .  bfd_arch_mep,
 .#define bfd_mach_mep		1
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 503e237..1b483bd 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -2265,6 +2265,7 @@ enum bfd_architecture
 #define bfd_mach_moxie         1
   bfd_arch_ft32,       /* The ft32 processor */
 #define bfd_mach_ft32          1
+#define bfd_mach_ft32b         2
   bfd_arch_mcore,
   bfd_arch_mep,
 #define bfd_mach_mep           1
@@ -3149,7 +3150,11 @@ to compensate for the borrow when the low bits are added.  */
   BFD_RELOC_FT32_20,
   BFD_RELOC_FT32_17,
   BFD_RELOC_FT32_18,
+  BFD_RELOC_FT32_RELAX,
+  BFD_RELOC_FT32_SC0,
+  BFD_RELOC_FT32_SC1,
   BFD_RELOC_FT32_15,
+  BFD_RELOC_FT32_DIFF32,
 
 
 /* Fujitsu Frv Relocations.  */
diff --git a/bfd/cpu-ft32.c b/bfd/cpu-ft32.c
index b24b0fc..033720b 100644
--- a/bfd/cpu-ft32.c
+++ b/bfd/cpu-ft32.c
@@ -23,6 +23,40 @@
 #include "libbfd.h"
 
 
+static const bfd_arch_info_type arch_info_struct[] =
+  {
+    {
+      32,               /* 32 bits in a word.  */
+      32,               /* 32 bits in an address.  */
+      8,                /*  8 bits in a byte.  */
+      bfd_arch_ft32,   /* enum bfd_architecture arch.  */
+      bfd_mach_ft32,
+      "ft32",          /* Arch name.  */
+      "ft32",          /* Printable name.  */
+      2,                /* Unsigned int section alignment power.  */
+      FALSE,             /* The one and only.  */
+      bfd_default_compatible,
+      bfd_default_scan,
+      bfd_arch_default_fill,
+      &arch_info_struct[1],
+    },
+    {
+      32,               /* 32 bits in a word.  */
+      32,               /* 32 bits in an address.  */
+      8,                /*  8 bits in a byte.  */
+      bfd_arch_ft32,   /* enum bfd_architecture arch.  */
+      bfd_mach_ft32b,
+      "ft32b",          /* Arch name.  */
+      "ft32b",          /* Printable name.  */
+      2,                /* Unsigned int section alignment power.  */
+      FALSE,            /* The one and only.  */
+      bfd_default_compatible,
+      bfd_default_scan,
+      bfd_arch_default_fill,
+      0,
+    },
+  };
+
 const bfd_arch_info_type bfd_ft32_arch =
   {
     32,               /* 32 bits in a word.  */
@@ -37,5 +71,5 @@ const bfd_arch_info_type bfd_ft32_arch =
     bfd_default_compatible,
     bfd_default_scan,
     bfd_arch_default_fill,
-    0,
+    arch_info_struct,
   };
diff --git a/bfd/elf32-ft32.c b/bfd/elf32-ft32.c
index 2ee691c..ca09b38 100644
--- a/bfd/elf32-ft32.c
+++ b/bfd/elf32-ft32.c
@@ -27,8 +27,13 @@
 #include "libbfd.h"
 #include "elf-bfd.h"
 #include "elf/ft32.h"
+#include "opcode/ft32.h"
 
-/* Forward declarations.  */
+static bfd_boolean debug_relax = FALSE;
+
+static bfd_reloc_status_type
+bfd_elf_ft32_diff_reloc (bfd *, arelent *, asymbol *, void *,
+			asection *, bfd *, char **);
 
 static reloc_howto_type ft32_elf_howto_table [] =
 {
@@ -69,7 +74,7 @@ static reloc_howto_type ft32_elf_howto_table [] =
 	 16,			/* bitsize */
 	 FALSE,			/* pc_relative */
 	 0,			/* bitpos */
-	 complain_overflow_bitfield, /* complain_on_overflow */
+	 complain_overflow_dont, /* complain_on_overflow */
 	 bfd_elf_generic_reloc,	/* special_function */
 	 "R_FT32_16",		/* name */
 	 FALSE,			/* partial_inplace */
@@ -97,7 +102,7 @@ static reloc_howto_type ft32_elf_howto_table [] =
 	 10,			/* bitsize */
 	 FALSE,			/* pc_relative */
 	 4,			/* bitpos */
-	 complain_overflow_signed, /* complain_on_overflow */
+	 complain_overflow_bitfield, /* complain_on_overflow */
 	 bfd_elf_generic_reloc,	/* special_function */
 	 "R_FT32_10",		/* name */
 	 FALSE,			/* partial_inplace */
@@ -142,11 +147,51 @@ static reloc_howto_type ft32_elf_howto_table [] =
 	 complain_overflow_dont, /* complain_on_overflow */
 	 bfd_elf_generic_reloc,	/* special_function */
 	 "R_FT32_18",		/* name */
-	 FALSE,		/* partial_inplace */
+	 FALSE,			/* partial_inplace */
 	 0x00000000,		/* src_mask */
 	 0x0003ffff,		/* dst_mask */
 	 FALSE),		/* pcrel_offset */
 
+  HOWTO (R_FT32_RELAX,		/* type */
+	 0,			/* rightshift */
+	 1,			/* size (0 = byte, 1 = short, 2 = long) */
+	 10,			/* bitsize */
+	 FALSE,			/* pc_relative */
+	 4,			/* bitpos */
+	 complain_overflow_signed, /* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* special_function */
+	 "R_FT32_RELAX",	/* name */
+	 FALSE,			/* partial_inplace */
+	 0x00000000,		/* src_mask */
+	 0x00000000,		/* dst_mask */
+	 FALSE),		/* pcrel_offset */
+
+  HOWTO (R_FT32_SC0,		/* type */
+	 0,			/* rightshift */
+	 1,			/* size (0 = byte, 1 = short, 2 = long) */
+	 10,			/* bitsize */
+	 FALSE,			/* pc_relative */
+	 4,			/* bitpos */
+	 complain_overflow_signed, /* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* special_function */
+	 "R_FT32_SC0",	        /* name */
+	 FALSE,			/* partial_inplace */
+	 0x00000000,		/* src_mask */
+	 0x00000000,		/* dst_mask */
+	 FALSE),		/* pcrel_offset */
+  HOWTO (R_FT32_SC1,		/* type */
+	 2,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 22,			/* bitsize */
+	 TRUE,			/* pc_relative */
+	 7,			/* bitpos */
+	 complain_overflow_dont, /* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* special_function */
+	 "R_FT32_SC1",	        /* name */
+	 TRUE,			/* partial_inplace */
+	 0x07ffff80,		/* src_mask */
+	 0x07ffff80,		/* dst_mask */
+	 FALSE),		/* pcrel_offset */
   HOWTO (R_FT32_15,		/* type */
 	 0,			/* rightshift */
 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
@@ -160,8 +205,22 @@ static reloc_howto_type ft32_elf_howto_table [] =
 	 0x00000000,		/* src_mask */
 	 0x00007fff,		/* dst_mask */
 	 FALSE),		/* pcrel_offset */
+  HOWTO (R_FT32_DIFF32,  	/* type */
+	 0,             	/* rightshift */
+	 2,         		/* size (0 = byte, 1 = short, 2 = long) */
+	 32,        		/* bitsize */
+	 FALSE,         	/* pc_relative */
+	 0,             	/* bitpos */
+	 complain_overflow_dont, /* complain_on_overflow */
+	 bfd_elf_ft32_diff_reloc, /* special_function */
+	 "R_FT32_DIFF32",     	/* name */
+	 FALSE,         	/* partial_inplace */
+	 0,             	/* src_mask */
+	 0xffffffff,    	/* dst_mask */
+	 FALSE),        	/* pcrel_offset */
 };
 
+
 /* Map BFD reloc types to FT32 ELF reloc types.  */
 
 struct ft32_reloc_map
@@ -172,17 +231,36 @@ struct ft32_reloc_map
 
 static const struct ft32_reloc_map ft32_reloc_map [] =
 {
-  { BFD_RELOC_NONE,            R_FT32_NONE },
-  { BFD_RELOC_32,              R_FT32_32 },
-  { BFD_RELOC_16,              R_FT32_16 },
-  { BFD_RELOC_8,               R_FT32_8 },
-  { BFD_RELOC_FT32_10,           R_FT32_10 },
-  { BFD_RELOC_FT32_20,           R_FT32_20 },
-  { BFD_RELOC_FT32_17,           R_FT32_17 },
-  { BFD_RELOC_FT32_18,           R_FT32_18 },
+  { BFD_RELOC_NONE,             R_FT32_NONE },
+  { BFD_RELOC_32,               R_FT32_32 },
+  { BFD_RELOC_16,               R_FT32_16 },
+  { BFD_RELOC_8,                R_FT32_8 },
+  { BFD_RELOC_FT32_10,          R_FT32_10 },
+  { BFD_RELOC_FT32_20,          R_FT32_20 },
+  { BFD_RELOC_FT32_17,          R_FT32_17 },
+  { BFD_RELOC_FT32_18,          R_FT32_18 },
+  { BFD_RELOC_FT32_RELAX,       R_FT32_RELAX },
+  { BFD_RELOC_FT32_SC0,         R_FT32_SC0 },
+  { BFD_RELOC_FT32_SC1,         R_FT32_SC1 },
   { BFD_RELOC_FT32_15,          R_FT32_15 },
+  { BFD_RELOC_FT32_DIFF32,      R_FT32_DIFF32 },
 };
 
+/* Perform a diff relocation. Nothing to do, as the difference value is
+   already written into the section's contents. */
+
+static bfd_reloc_status_type
+bfd_elf_ft32_diff_reloc (bfd *abfd ATTRIBUTE_UNUSED,
+		      arelent *reloc_entry ATTRIBUTE_UNUSED,
+	      asymbol *symbol ATTRIBUTE_UNUSED,
+	      void *data ATTRIBUTE_UNUSED,
+	      asection *input_section ATTRIBUTE_UNUSED,
+	      bfd *output_bfd ATTRIBUTE_UNUSED,
+	      char **error_message ATTRIBUTE_UNUSED)
+{
+  return bfd_reloc_ok;
+}
+
 static reloc_howto_type *
 ft32_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
 			 bfd_reloc_code_real_type code)
@@ -225,7 +303,7 @@ ft32_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
   BFD_ASSERT (r_type < (unsigned int) R_FT32_max);
   cache_ptr->howto = & ft32_elf_howto_table [r_type];
 }
-
+
 /* Relocate an FT32 ELF section.
 
    The RELOCATE_SECTION function is called by the new ELF backend linker
@@ -323,9 +401,68 @@ ft32_elf_relocate_section (bfd *output_bfd,
       if (bfd_link_relocatable (info))
 	continue;
 
-      r = _bfd_final_link_relocate (howto, input_bfd, input_section,
-				    contents, rel->r_offset,
-				    relocation, rel->r_addend);
+      switch (howto->type)
+	{
+	  case R_FT32_SC0:
+	    {
+	      unsigned int insn;
+	      int offset;
+	      unsigned int code15[2];
+
+	      insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
+	      ft32_split_shortcode (insn, code15);
+
+	      offset = (int)relocation;
+	      offset += (int)(rel->r_addend - rel->r_offset);
+	      offset -= (input_section->output_section->vma +
+			 input_section->output_offset);
+	      if ((offset < -1024) || (offset >= 1024))
+		{
+		  r = bfd_reloc_outofrange;
+		  break;
+		}
+	      code15[0] |= ((offset / 4) & 511);
+	      insn = ft32_merge_shortcode (code15);
+	      bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
+	    }
+	    r = bfd_reloc_ok;
+	    break;
+
+	  case R_FT32_SC1:
+	    {
+	      unsigned int insn;
+	      int offset;
+	      unsigned int code15[2];
+
+	      insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
+	      ft32_split_shortcode (insn, code15);
+
+	      offset = (int)relocation;
+	      offset += (int)(rel->r_addend - rel->r_offset);
+	      offset -= (input_section->output_section->vma +
+			 input_section->output_offset);
+	      if ((offset < -1024) || (offset >= 1024))
+		{
+		  r = bfd_reloc_outofrange;
+		  break;
+		}
+	      code15[1] |= ((offset / 4) & 511);
+	      insn = ft32_merge_shortcode (code15);
+	      bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
+	    }
+	    r = bfd_reloc_ok;
+	    break;
+
+	  case R_FT32_DIFF32:
+	    r = bfd_reloc_ok;
+	    break;
+
+	  default:
+	    r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+					  contents, rel->r_offset,
+					  relocation, rel->r_addend);
+	    break;
+	}
 
       if (r != bfd_reloc_ok)
 	{
@@ -370,6 +507,733 @@ ft32_elf_relocate_section (bfd *output_bfd,
   return TRUE;
 }
 
+/* Relaxation.  */
+
+static bfd_boolean
+ft32_reloc_shortable
+    (bfd *                  abfd,
+     asection *             sec,
+     Elf_Internal_Sym *     isymbuf ATTRIBUTE_UNUSED,
+     bfd_byte *             contents,
+     bfd_vma                pc ATTRIBUTE_UNUSED,
+     Elf_Internal_Rela *    irel,
+     unsigned int *         sc)
+{
+  Elf_Internal_Shdr *symtab_hdr ATTRIBUTE_UNUSED;
+  bfd_vma symval;
+
+  enum elf_ft32_reloc_type r_type;
+  reloc_howto_type *howto = NULL;
+  unsigned int insn;
+  int offset;
+  bfd_vma dot, value;
+
+  r_type = ELF32_R_TYPE (irel->r_info);
+  howto = &ft32_elf_howto_table [r_type];
+
+  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+
+  /* Get the value of the symbol referred to by the reloc.  */
+  if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
+    {
+      /* A local symbol.  */
+      Elf_Internal_Sym *isym;
+      asection *sym_sec;
+
+      isym = isymbuf + ELF32_R_SYM (irel->r_info);
+      sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
+      symval = isym->st_value;
+      /* If the reloc is absolute, it will not have
+	 a symbol or section associated with it.  */
+      if (sym_sec)
+	symval += sym_sec->output_section->vma
+	  + sym_sec->output_offset;
+    }
+  else
+    {
+      unsigned long indx;
+      struct elf_link_hash_entry *h;
+
+      /* An external symbol.  */
+      indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
+      h = elf_sym_hashes (abfd)[indx];
+      BFD_ASSERT (h != NULL);
+      if (h->root.type != bfd_link_hash_defined
+	  && h->root.type != bfd_link_hash_defweak)
+	/* This appears to be a reference to an undefined
+	   symbol.  Just ignore it--it will be caught by the
+	   regular reloc processing.  */
+	return FALSE;
+
+      symval = (h->root.u.def.value
+		+ h->root.u.def.section->output_section->vma
+		+ h->root.u.def.section->output_offset);
+    }
+
+  switch (r_type)
+    {
+      case R_FT32_8:
+      case R_FT32_10:
+      case R_FT32_16:
+      case R_FT32_20:
+      case R_FT32_RELAX:
+	if (symval != 0)
+	  return FALSE;
+	insn = bfd_get_32 (abfd, contents + irel->r_offset);
+	insn |= ((symval + irel->r_addend) << howto->bitpos) & howto->dst_mask;
+	return ft32_shortcode (insn, sc);
+
+      case R_FT32_18:
+	insn = bfd_get_32 (abfd, contents + irel->r_offset);
+	/* Get the address of this instruction.  */
+	dot = (sec->output_section->vma
+	       + sec->output_offset + irel->r_offset);
+	value = symval + irel->r_addend;
+	offset = (value - dot) / 4;
+
+	if ((dot > 0x8c) && (-256 <= offset) && (offset < 256))
+	  {
+	    switch (insn)
+	      {
+		case 0x00200000: *sc = (3 << 13) | (0  << 9); return TRUE;
+		case 0x00280000: *sc = (3 << 13) | (1  << 9); return TRUE;
+		case 0x00600000: *sc = (3 << 13) | (2  << 9); return TRUE;
+		case 0x00680000: *sc = (3 << 13) | (3  << 9); return TRUE;
+		case 0x00a00000: *sc = (3 << 13) | (4  << 9); return TRUE;
+		case 0x00a80000: *sc = (3 << 13) | (5  << 9); return TRUE;
+		case 0x00e00000: *sc = (3 << 13) | (6  << 9); return TRUE;
+		case 0x00e80000: *sc = (3 << 13) | (7  << 9); return TRUE;
+		case 0x01200000: *sc = (3 << 13) | (8  << 9); return TRUE;
+		case 0x01280000: *sc = (3 << 13) | (9  << 9); return TRUE;
+		case 0x01600000: *sc = (3 << 13) | (10 << 9); return TRUE;
+		case 0x01680000: *sc = (3 << 13) | (11 << 9); return TRUE;
+		case 0x01a00000: *sc = (3 << 13) | (12 << 9); return TRUE;
+		case 0x01a80000: *sc = (3 << 13) | (13 << 9); return TRUE;
+
+		case 0x00300000: *sc = (3 << 13) | (14 << 9); return TRUE;
+		case 0x00340000: *sc = (3 << 13) | (15 << 9); return TRUE;
+
+		default:
+		  break;
+	      }
+	  }
+	break;
+
+      default:
+	break;
+    }
+  return FALSE;
+}
+
+/* Returns whether the relocation type passed is a diff reloc.  */
+
+static bfd_boolean
+elf32_ft32_is_diff_reloc (Elf_Internal_Rela *irel)
+{
+  return (ELF32_R_TYPE (irel->r_info) == R_FT32_DIFF32);
+}
+
+/* Reduce the diff value written in the section by count if the shrinked
+   insn address happens to fall between the two symbols for which this
+   diff reloc was emitted.  */
+
+static bfd_boolean
+elf32_ft32_adjust_diff_reloc_value (bfd *abfd,
+				   struct bfd_section *isec,
+				   Elf_Internal_Rela *irel,
+				   bfd_vma symval,
+				   bfd_vma shrinked_insn_address,
+				   int count)
+{
+  unsigned char * reloc_contents = NULL;
+  unsigned char * isec_contents = elf_section_data (isec)->this_hdr.contents;
+  bfd_signed_vma x = 0;
+  bfd_vma sym2_address;
+  bfd_vma sym1_address;
+  bfd_vma start_address;
+  bfd_vma end_address;
+
+
+  if (isec_contents == NULL)
+    {
+      if (! bfd_malloc_and_get_section (abfd, isec, &isec_contents))
+	return FALSE;
+
+      elf_section_data (isec)->this_hdr.contents = isec_contents;
+    }
+
+  reloc_contents = isec_contents + irel->r_offset;
+
+  /* Read value written in object file.  */
+  switch (ELF32_R_TYPE (irel->r_info))
+    {
+    case R_FT32_DIFF32:
+      x = bfd_get_signed_32 (abfd, reloc_contents);
+      break;
+
+    default:
+      return FALSE;
+    }
+
+  /* For a diff reloc sym1 - sym2 the diff at assembly time (x) is written
+     into the object file at the reloc offset. sym2's logical value is
+     symval (<start_of_section>) + reloc addend. Compute the start and end
+     addresses and check if the shrinked insn falls between sym1 and sym2.  */
+  sym2_address = symval + irel->r_addend;
+  sym1_address = sym2_address - x;
+
+  /* Don't assume sym2 is bigger than sym1 - the difference
+     could be negative. Compute start and end addresses, and
+     use those to see if they span shrinked_insn_address.  */
+  start_address = sym1_address < sym2_address ? sym1_address : sym2_address;
+  end_address = sym1_address > sym2_address ? sym1_address : sym2_address;
+
+  if (shrinked_insn_address >= start_address
+      && shrinked_insn_address < end_address)
+    {
+      /* Reduce the diff value by count bytes and write it back into section
+	 contents.  */
+      bfd_signed_vma new_diff = x < 0 ? x + count : x - count;
+
+      if (sym2_address > shrinked_insn_address)
+	irel->r_addend -= count;
+
+      switch (ELF32_R_TYPE (irel->r_info))
+	{
+	case R_FT32_DIFF32:
+	  bfd_put_signed_32 (abfd, new_diff & 0xFFFFFFFF, reloc_contents);
+	  break;
+
+	default:
+	  return FALSE;
+	}
+    }
+
+  return TRUE;
+}
+
+static bfd_boolean
+elf32_ft32_adjust_reloc_if_spans_insn (bfd *abfd,
+				      asection *isec,
+				      Elf_Internal_Rela *irel,  bfd_vma symval,
+				      bfd_vma shrinked_insn_address,
+				      bfd_vma shrink_boundary,
+				      int count)
+{
+
+  if (elf32_ft32_is_diff_reloc (irel))
+    {
+      if (!elf32_ft32_adjust_diff_reloc_value (abfd, isec, irel,
+                                               symval,
+                                               shrinked_insn_address,
+                                               count))
+        return FALSE;
+    }
+  else
+    {
+      bfd_vma reloc_value = symval + irel->r_addend;
+      bfd_boolean addend_within_shrink_boundary =
+	(reloc_value <= shrink_boundary);
+      bfd_boolean reloc_spans_insn =
+	(symval <= shrinked_insn_address
+	 && reloc_value > shrinked_insn_address
+	 && addend_within_shrink_boundary);
+
+      if (! reloc_spans_insn)
+	return TRUE;
+
+      irel->r_addend -= count;
+
+      if (debug_relax)
+	printf ("Relocation's addend needed to be fixed \n");
+    }
+  return TRUE;
+}
+
+/* Delete some bytes from a section while relaxing.  */
+
+static bfd_boolean
+elf32_ft32_relax_delete_bytes (struct bfd_link_info *link_info, bfd * abfd,
+			       asection * sec, bfd_vma addr, int count)
+{
+  Elf_Internal_Shdr *symtab_hdr;
+  unsigned int sec_shndx;
+  bfd_byte *contents;
+  Elf_Internal_Rela *irel, *irelend;
+  bfd_vma toaddr;
+  Elf_Internal_Sym *isym;
+  Elf_Internal_Sym *isymend;
+  struct elf_link_hash_entry **sym_hashes;
+  struct elf_link_hash_entry **end_hashes;
+  struct elf_link_hash_entry **start_hashes;
+  unsigned int symcount;
+  Elf_Internal_Sym *isymbuf = NULL;
+
+  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+  sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
+
+  contents = elf_section_data (sec)->this_hdr.contents;
+
+  toaddr = sec->size;
+
+  irel = elf_section_data (sec)->relocs;
+  irelend = irel + sec->reloc_count;
+
+  /* Actually delete the bytes.  */
+  memmove (contents + addr, contents + addr + count,
+	   (size_t) (toaddr - addr - count));
+  sec->size -= count;
+
+  /* Adjust all the relocs.  */
+  for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
+    /* Get the new reloc address.  */
+    if ((irel->r_offset > addr && irel->r_offset < toaddr))
+      irel->r_offset -= count;
+
+  /* The reloc's own addresses are now ok. However, we need to readjust
+     the reloc's addend, i.e. the reloc's value if two conditions are met:
+     1.) the reloc is relative to a symbol in this section that
+     is located in front of the shrinked instruction
+     2.) symbol plus addend end up behind the shrinked instruction.
+
+     The most common case where this happens are relocs relative to
+     the section-start symbol.
+
+     This step needs to be done for all of the sections of the bfd.  */
+  {
+    struct bfd_section *isec;
+
+    for (isec = abfd->sections; isec; isec = isec->next)
+      {
+	bfd_vma symval;
+	bfd_vma shrinked_insn_address;
+
+	if (isec->reloc_count == 0)
+	  continue;
+
+	shrinked_insn_address = (sec->output_section->vma
+				 + sec->output_offset + addr - count);
+
+	irel = elf_section_data (isec)->relocs;
+	/* PR 12161: Read in the relocs for this section if necessary.  */
+	if (irel == NULL)
+	  irel = _bfd_elf_link_read_relocs (abfd, isec, NULL, NULL, TRUE);
+
+	for (irelend = irel + isec->reloc_count; irel < irelend; irel++)
+	  {
+	    /* Read this BFD's local symbols if we haven't done
+	       so already.  */
+	    if (isymbuf == NULL && symtab_hdr->sh_info != 0)
+	      {
+		isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+		if (isymbuf == NULL)
+		  isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
+						  symtab_hdr->sh_info, 0,
+						  NULL, NULL, NULL);
+		if (isymbuf == NULL)
+		  return FALSE;
+	      }
+
+	    /* Get the value of the symbol referred to by the reloc.  */
+	    if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
+	      {
+		/* A local symbol.  */
+		asection *sym_sec;
+
+		isym = isymbuf + ELF32_R_SYM (irel->r_info);
+		sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
+		symval = isym->st_value;
+		/* If the reloc is absolute, it will not have
+		   a symbol or section associated with it.  */
+		if (sym_sec == sec)
+		  {
+		    symval += sym_sec->output_section->vma
+		      + sym_sec->output_offset;
+
+		    if (debug_relax)
+		      printf ("Checking if the relocation's "
+			      "addend needs corrections.\n"
+			      "Address of anchor symbol: 0x%x \n"
+			      "Address of relocation target: 0x%x \n"
+			      "Address of relaxed insn: 0x%x \n",
+			      (unsigned int) symval,
+			      (unsigned int) (symval + irel->r_addend),
+			      (unsigned int) shrinked_insn_address);
+
+		    if (symval <= shrinked_insn_address
+			&& (symval + irel->r_addend) > shrinked_insn_address)
+		      {
+			/* If there is an alignment boundary, we only need to
+			   adjust addends that end up below the boundary. */
+			bfd_vma shrink_boundary = (toaddr
+						   + sec->output_section->vma
+						   + sec->output_offset);
+
+			if (debug_relax)
+			  printf
+			    ("Relocation's addend needed to be fixed \n");
+
+                        if (!elf32_ft32_adjust_reloc_if_spans_insn (abfd, isec,
+                                                                    irel, symval,
+                                                                    shrinked_insn_address,
+                                                                    shrink_boundary,
+                                                                    count))
+                          return FALSE;
+		      }
+		  }
+		/* else reference symbol is absolute. No adjustment needed. */
+	      }
+	    /* else...Reference symbol is extern.  No need for adjusting
+	       the addend.  */
+	  }
+      }
+  }
+
+  /* Adjust the local symbols defined in this section.  */
+  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+  isym = (Elf_Internal_Sym *) symtab_hdr->contents;
+  if (isym)
+    {
+      for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
+	{
+	  if (isym->st_shndx == sec_shndx
+	      && isym->st_value > addr && isym->st_value < toaddr)
+	    isym->st_value -= count;
+	}
+    }
+
+  /* Now adjust the global symbols defined in this section.  */
+  symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
+	      - symtab_hdr->sh_info);
+  sym_hashes = start_hashes = elf_sym_hashes (abfd);
+  end_hashes = sym_hashes + symcount;
+
+  for (; sym_hashes < end_hashes; sym_hashes++)
+    {
+      struct elf_link_hash_entry *sym_hash = *sym_hashes;
+
+      /* The '--wrap SYMBOL' option is causing a pain when the object file,
+         containing the definition of __wrap_SYMBOL, includes a direct
+         call to SYMBOL as well. Since both __wrap_SYMBOL and SYMBOL reference
+         the same symbol (which is __wrap_SYMBOL), but still exist as two
+         different symbols in 'sym_hashes', we don't want to adjust
+         the global symbol __wrap_SYMBOL twice.
+         This check is only relevant when symbols are being wrapped.  */
+      if (link_info->wrap_hash != NULL)
+	{
+	  struct elf_link_hash_entry **cur_sym_hashes;
+
+	  /* Loop only over the symbols whom been already checked.  */
+	  for (cur_sym_hashes = start_hashes; cur_sym_hashes < sym_hashes;
+	       cur_sym_hashes++)
+	    /* If the current symbol is identical to 'sym_hash', that means
+	       the symbol was already adjusted (or at least checked).  */
+	    if (*cur_sym_hashes == sym_hash)
+	      break;
+
+	  /* Don't adjust the symbol again.  */
+	  if (cur_sym_hashes < sym_hashes)
+	    continue;
+	}
+
+      if ((sym_hash->root.type == bfd_link_hash_defined
+	   || sym_hash->root.type == bfd_link_hash_defweak)
+	  && sym_hash->root.u.def.section == sec
+	  && sym_hash->root.u.def.value > addr
+	  && sym_hash->root.u.def.value < toaddr)
+	sym_hash->root.u.def.value -= count;
+    }
+
+  return TRUE;
+}
+
+/* Return TRUE if LOC can be a target of a branch, jump or call.  */
+
+static bfd_boolean
+elf32_ft32_relax_is_branch_target (struct bfd_link_info *link_info,
+				   bfd * abfd, asection * sec,
+				   bfd_vma loc)
+{
+  Elf_Internal_Shdr *symtab_hdr;
+  Elf_Internal_Rela *irel, *irelend;
+  Elf_Internal_Sym *isym;
+  Elf_Internal_Sym *isymbuf = NULL;
+  bfd_vma symval;
+  struct bfd_section *isec;
+
+  struct elf_link_hash_entry **sym_hashes;
+  struct elf_link_hash_entry **end_hashes;
+  struct elf_link_hash_entry **start_hashes;
+  unsigned int symcount;
+
+  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+
+  /* Now we check for relocations pointing to ret.  */
+  for (isec = abfd->sections; isec; isec = isec->next)
+    {
+      irel = elf_section_data (isec)->relocs;
+      if (irel == NULL)
+	irel = _bfd_elf_link_read_relocs (abfd, isec, NULL, NULL, TRUE);
+
+      irelend = irel + isec->reloc_count;
+
+      for (; irel < irelend; irel++)
+	{
+	  /* Read this BFD's local symbols if we haven't done
+	     so already.  */
+	  if (isymbuf == NULL && symtab_hdr->sh_info != 0)
+	    {
+	      isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+	      if (isymbuf == NULL)
+		isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
+						symtab_hdr->sh_info, 0,
+						NULL, NULL, NULL);
+	      if (isymbuf == NULL)
+		return FALSE;
+	    }
+
+	  /* Get the value of the symbol referred to by the reloc.  */
+	  if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
+	    {
+	      /* A local symbol.  */
+	      asection *sym_sec;
+
+	      isym = isymbuf + ELF32_R_SYM (irel->r_info);
+	      sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
+	      symval = isym->st_value;
+	      /* If the reloc is absolute, it will not have
+		 a symbol or section associated with it.  */
+	      if (sym_sec == sec)
+		{
+		  symval += sym_sec->output_section->vma
+                            + sym_sec->output_offset;
+
+		  if (debug_relax)
+		    printf ("0x%x: Address of anchor symbol: 0x%x "
+			    "Address of relocation target: 0x%x \n",
+			    (unsigned int) irel->r_offset,
+			    (unsigned int) symval,
+			    (unsigned int) (symval + irel->r_addend));
+		  if ((irel->r_addend) == loc)
+		    return TRUE;
+		}
+	    }
+	}
+    }
+
+  symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
+	       - symtab_hdr->sh_info);
+  sym_hashes = start_hashes = elf_sym_hashes (abfd);
+  end_hashes = sym_hashes + symcount;
+
+  for (; sym_hashes < end_hashes; sym_hashes++)
+    {
+      struct elf_link_hash_entry *sym_hash = *sym_hashes;
+
+      /* The '--wrap SYMBOL' option is causing a pain when the object file,
+	 containing the definition of __wrap_SYMBOL, includes a direct
+	 call to SYMBOL as well. Since both __wrap_SYMBOL and SYMBOL reference
+	 the same symbol (which is __wrap_SYMBOL), but still exist as two
+	 different symbols in 'sym_hashes', we don't want to adjust
+	 the global symbol __wrap_SYMBOL twice.
+	 This check is only relevant when symbols are being wrapped.  */
+      if (link_info->wrap_hash != NULL)
+	{
+	  struct elf_link_hash_entry **cur_sym_hashes;
+
+	  /* Loop only over the symbols whom been already checked.  */
+	  for (cur_sym_hashes = start_hashes; cur_sym_hashes < sym_hashes;
+	       cur_sym_hashes++)
+	    /* If the current symbol is identical to 'sym_hash', that means
+	       the symbol was already adjusted (or at least checked).  */
+	    if (*cur_sym_hashes == sym_hash)
+	      break;
+
+	  /* Don't adjust the symbol again.  */
+	  if (cur_sym_hashes < sym_hashes)
+	    continue;
+	}
+
+      if ((sym_hash->root.type == bfd_link_hash_defined
+	  || sym_hash->root.type == bfd_link_hash_defweak)
+	  && sym_hash->root.u.def.section == sec
+	  && sym_hash->root.u.def.value == loc)
+	return TRUE;
+    }
+
+  return FALSE;
+}
+
+static bfd_boolean
+ft32_elf_relax_section
+    (bfd *                  abfd,
+     asection *             sec,
+     struct bfd_link_info * link_info,
+     bfd_boolean *          again)
+{
+  Elf_Internal_Rela * free_relocs = NULL;
+  Elf_Internal_Rela * internal_relocs;
+  Elf_Internal_Rela * irelend;
+  Elf_Internal_Rela * irel;
+  bfd_byte *          contents = NULL;
+  Elf_Internal_Shdr * symtab_hdr;
+  Elf_Internal_Sym *  isymbuf = NULL;
+
+  /* Assume nothing changes.  */
+  *again = FALSE;
+
+  /* We don't have to do anything for a relocatable link, if
+     this section does not have relocs, or if this is not a
+     code section.  */
+  if (bfd_link_relocatable (link_info)
+      || (sec->flags & SEC_RELOC) == 0
+      || sec->reloc_count == 0
+      || (sec->flags & SEC_CODE) == 0)
+    return TRUE;
+
+  /* Get the section contents.  */
+  if (elf_section_data (sec)->this_hdr.contents != NULL)
+    contents = elf_section_data (sec)->this_hdr.contents;
+  /* Go get them off disk.  */
+  else
+    {
+      if (! bfd_malloc_and_get_section (abfd, sec, &contents))
+	goto error_return;
+      elf_section_data (sec)->this_hdr.contents = contents;
+    }
+
+  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+
+  /* Read this BFD's local symbols if we haven't done so already.  */
+  if (isymbuf == NULL && symtab_hdr->sh_info != 0)
+    {
+      isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+      if (isymbuf == NULL)
+	isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
+					symtab_hdr->sh_info, 0,
+					NULL, NULL, NULL);
+      if (isymbuf == NULL)
+	goto error_return;
+      symtab_hdr->contents = (unsigned char *) isymbuf;
+    }
+
+  internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL,
+					       link_info->keep_memory);
+  if (internal_relocs == NULL)
+    goto error_return;
+  if (! link_info->keep_memory)
+    free_relocs = internal_relocs;
+
+  /* Walk through them looking for relaxing opportunities.  */
+  irelend = internal_relocs + sec->reloc_count;
+
+  /* Test every adjacent pair of relocs. If both have shortcodes,
+     fuse them and delete the relocs.  */
+  irel = internal_relocs;
+  while (irel < irelend - 1)
+    {
+      Elf_Internal_Rela * irel_next = irel + 1;
+      unsigned int sc0, sc1;
+      bfd_vma pc;
+
+      pc = irel->r_offset;
+
+      if (((pc + 4) == (irel_next->r_offset))
+	  && ft32_reloc_shortable (abfd, sec, isymbuf, contents, pc, irel,
+				   &sc0)
+	  && ft32_reloc_shortable (abfd, sec, isymbuf, contents, pc,
+				   irel_next, &sc1)
+	  && !elf32_ft32_relax_is_branch_target (link_info, abfd, sec,
+						 irel_next->r_offset))
+	{
+	  unsigned int code30 = (sc1 << 15) | sc0;
+	  unsigned int code27 = code30 >> 3;
+	  unsigned int code3 = code30 & 7;
+	  static const unsigned char pat3[] = {2, 3, 4, 5, 6, 9, 10, 14};
+	  unsigned int pattern = pat3[code3];
+	  unsigned int fused = (pattern << 27) | code27;
+
+	  /* Move second reloc to same place as first.  */
+	  irel_next->r_offset = irel->r_offset;
+
+	  /* Change both relocs to R_FT32_NONE.  */
+
+	  if (ELF32_R_TYPE (irel->r_info) == R_FT32_18)
+	    {
+	      irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+                                           R_FT32_SC0);
+	    }
+	  else
+	    {
+	      irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+                                           R_FT32_NONE);
+	    }
+
+	  if (ELF32_R_TYPE (irel_next->r_info) == R_FT32_18)
+	    {
+	      irel_next->r_info = ELF32_R_INFO (ELF32_R_SYM (irel_next->r_info),
+						R_FT32_SC1);
+	    }
+	  else
+	    {
+	      irel_next->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+						R_FT32_NONE);
+	    }
+
+	  /* Replace the first insn with the fused version.  */
+	  bfd_put_32 (abfd, fused, contents + irel->r_offset);
+
+	  /* Delete the second insn.  */
+	  if (!elf32_ft32_relax_delete_bytes (link_info, abfd, sec,
+					       irel->r_offset + 4, 4))
+	    goto error_return;
+
+	  /* That will change things, so, we should relax again.
+	     Note that this is not required, and it may be slow.  */
+	  *again = TRUE;
+
+	  irel += 2;
+	}
+      else
+	{
+	  irel += 1;
+	}
+    }
+
+  if (isymbuf != NULL
+      && symtab_hdr->contents != (unsigned char *) isymbuf)
+    {
+      if (! link_info->keep_memory)
+	free (isymbuf);
+      else
+       /* Cache the symbols for elf_link_input_bfd.  */
+       symtab_hdr->contents = (unsigned char *) isymbuf;
+    }
+
+  if (contents != NULL
+      && elf_section_data (sec)->this_hdr.contents != contents)
+    {
+      if (! link_info->keep_memory)
+	free (contents);
+      else
+       /* Cache the section contents for elf_link_input_bfd.  */
+       elf_section_data (sec)->this_hdr.contents = contents;
+
+    }
+
+  if (internal_relocs != NULL
+      && elf_section_data (sec)->relocs != internal_relocs)
+    free (internal_relocs);
+
+  return TRUE;
+
+ error_return:
+  if (free_relocs != NULL)
+    free (free_relocs);
+
+  return TRUE;
+}
+
 #define ELF_ARCH		bfd_arch_ft32
 #define ELF_MACHINE_CODE	EM_FT32
 #define ELF_MAXPAGESIZE		0x1
@@ -387,4 +1251,6 @@ ft32_elf_relocate_section (bfd *output_bfd,
 #define bfd_elf32_bfd_reloc_type_lookup		ft32_reloc_type_lookup
 #define bfd_elf32_bfd_reloc_name_lookup		ft32_reloc_name_lookup
 
+#define bfd_elf32_bfd_relax_section		ft32_elf_relax_section
+
 #include "elf32-target.h"
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index 0f8843e..bc45350 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -1216,7 +1216,11 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
   "BFD_RELOC_FT32_20",
   "BFD_RELOC_FT32_17",
   "BFD_RELOC_FT32_18",
+  "BFD_RELOC_FT32_RELAX",
+  "BFD_RELOC_FT32_SC0",
+  "BFD_RELOC_FT32_SC1",
   "BFD_RELOC_FT32_15",
+  "BFD_RELOC_FT32_DIFF32",
 
   "BFD_RELOC_FRV_LABEL16",
   "BFD_RELOC_FRV_LABEL24",
diff --git a/bfd/reloc.c b/bfd/reloc.c
index e4edfd3..7ee7844 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -2488,7 +2488,15 @@ ENUMX
 ENUMX
   BFD_RELOC_FT32_18
 ENUMX
+  BFD_RELOC_FT32_RELAX
+ENUMX
+  BFD_RELOC_FT32_SC0
+ENUMX
+  BFD_RELOC_FT32_SC1
+ENUMX
   BFD_RELOC_FT32_15
+ENUMX
+  BFD_RELOC_FT32_DIFF32
 ENUMDOC
   FT32 ELF relocations.
 COMMENT
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 951807f..231fc84 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,7 @@
+2017-11-01  James Bowman  <james.bowman@ftdichip.com>
+
+	* readelf.c (is_16bit_abs_reloc): Add entry for FT32.
+
 2017-10-31  Nick Clifton  <nickc@redhat.com>
 
 	* readelf.c (process_relocs): Tell users if no static relocs were
diff --git a/binutils/readelf.c b/binutils/readelf.c
index f74d484..9af5d42 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -12453,6 +12453,8 @@ is_16bit_abs_reloc (unsigned int reloc_type)
     case EM_CYGNUS_D10V:
     case EM_D10V:
       return reloc_type == 3; /* R_D10V_16.  */
+    case EM_FT32:
+      return reloc_type == 2; /* R_FT32_16.  */
     case EM_H8S:
     case EM_H8_300:
     case EM_H8_300H:
diff --git a/gas/ChangeLog b/gas/ChangeLog
index c780b7d..82e5580 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,9 +1,36 @@
+2017-11-01  James Bowman  <james.bowman@ftdichip.com>
+
+	* config/tc-ft32.c (md_assemble): Add relaxation reloc
+	BFD_RELOC_FT32_RELAX.
+	(md_longopts): Add "norelax" and "no-relax".
+	(md_apply_fix): Add reloc BFD_RELOC_FT32_DIFF32.
+	(relaxable_section, ft32_validate_fix_sub, ft32_force_relocation,
+	ft32_allow_local_subtract): New function.
+	* config/tc-ft32.h: Remove unused MD_PCREL_FROM_SECTION.
+	* testsuite/gas/ft32/insnsc.s: New test exercising all FT32B
+	shortcodes.
+	* testsuite/gas/ft32/insnsc.d: New driver file.
+	* testsuite/gas/all/gas.exp: Update.
+	* testsuite/gas/ft32/ft32.exp: Run the new test.
+	* testsuite/gas/ft32/insn.d: Update.
+	* testsuite/gas/elf/dwarf2-11.d: Update.
+	* testsuite/gas/elf/dwarf2-12.d: Update.
+	* testsuite/gas/elf/dwarf2-13.d: Update.
+	* testsuite/gas/elf/dwarf2-14.d: Update.
+	* testsuite/gas/elf/dwarf2-15.d: Update.
+	* testsuite/gas/elf/dwarf2-16.d: Update.
+	* testsuite/gas/elf/dwarf2-17.d: Update.
+	* testsuite/gas/elf/dwarf2-18.d: Update.
+	* testsuite/gas/elf/dwarf2-3.d: Update.
+	* testsuite/gas/elf/dwarf2-5.d: Update.
+	* testsuite/gas/elf/dwarf2-7.d: Update.
+
 2017-11-01  Thomas Preud'homme  <thomas.preudhomme@arm.com>
 
 	* config/tc-arm.c (arm_ext_v2): Define to ARM_EXT_V2 feature bit.
-	* testsuite/gas/arm/copro.s: Split into ...
+	* testsuite/gas/arm/copro.s: Split into
 	* testsuite/gas/arm/copro-arm_v2plus-thumb_v6t2plus.s: This while
-	changing it to unified syntax and ...
+	changing it to unified syntax and
 	* testsuite/gas/arm/copro-arm_v5plus-thumb_v6t2plus.s: this and ...
 	* testsuite/gas/arm/copro-arm_v5teplus-thumb_v6t2plus.s: This and ...
 	* testsuite/gas/arm/copro-arm_v6plus-thumb_v6t2plus.s: This.
diff --git a/gas/config/tc-ft32.c b/gas/config/tc-ft32.c
index 2878e14..f401547 100644
--- a/gas/config/tc-ft32.c
+++ b/gas/config/tc-ft32.c
@@ -26,6 +26,9 @@
 
 extern const ft32_opc_info_t ft32_opc_info[128];
 
+/* See md_parse_option() for meanings of these options.  */
+static char norelax;			/* True if -norelax switch seen.  */
+
 const char comment_chars[]        = "#";
 const char line_separator_chars[] = ";";
 const char line_comment_chars[]   = "#";
@@ -58,6 +61,8 @@ md_begin (void)
     hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
 
   bfd_set_arch_mach (stdoutput, TARGET_ARCH, 0);
+  if (!norelax)
+    linkrelax = 1;
 }
 
 /* Parse an expression and then restore the input line pointer.  */
@@ -78,10 +83,13 @@ static int
 parse_condition (char **ptr)
 {
   char *s = *ptr;
-  static const struct {
+  static const struct
+  {
     const char *name;
     int bits;
-  } ccs[] = {
+  }
+  ccs[] =
+  {
     { "gt,"   , (2 << FT32_FLD_CR_BIT) | (5 << FT32_FLD_CB_BIT) | (1 << FT32_FLD_CV_BIT)},
     { "gte,"  , (2 << FT32_FLD_CR_BIT) | (4 << FT32_FLD_CB_BIT) | (1 << FT32_FLD_CV_BIT)},
     { "lt,"   , (2 << FT32_FLD_CR_BIT) | (4 << FT32_FLD_CB_BIT) | (0 << FT32_FLD_CV_BIT)},
@@ -191,18 +199,17 @@ md_assemble (char *str)
 {
   char *op_start;
   char *op_end;
-
   ft32_opc_info_t *opcode;
   char *output;
   int idx = 0;
   char pend;
-
   int nlen = 0;
-
   unsigned int b;
   int f;
-
   expressionS arg;
+  bfd_boolean fixed = FALSE;
+  unsigned int sc;
+  bfd_boolean can_sc;
 
   /* Drop leading whitespace.  */
   while (*str == ' ')
@@ -211,7 +218,10 @@ md_assemble (char *str)
   /* Find the op code end.  */
   op_start = str;
   for (op_end = str;
-       *op_end && !is_end_of_line[*op_end & 0xff] && *op_end != ' ' && *op_end != '.';
+       *op_end
+       && !is_end_of_line[*op_end & 0xff]
+       && *op_end != ' '
+       && *op_end != '.';
        op_end++)
     nlen++;
 
@@ -236,6 +246,7 @@ md_assemble (char *str)
   if (opcode->dw)
     {
       int dw;
+
       if (*op_end == '.')
         {
           switch (op_end[1])
@@ -270,106 +281,115 @@ md_assemble (char *str)
   while (f)
     {
       int lobit = f & -f;
+
       if (f & lobit)
         {
           switch (lobit)
-          {
-          case  FT32_FLD_CBCRCV:
-            b |= parse_condition( &op_end);
-            break;
-          case  FT32_FLD_CB:
-            b |= parse_decimal (&op_end) << FT32_FLD_CB_BIT;
-            break;
-          case  FT32_FLD_R_D:
-            b |= parse_register_operand (&op_end) << FT32_FLD_R_D_BIT;
-            break;
-          case  FT32_FLD_CR:
-            b |= (parse_register_operand (&op_end) - 28) << FT32_FLD_CR_BIT;
-            break;
-          case  FT32_FLD_CV:
-            b |= parse_decimal (&op_end) << FT32_FLD_CV_BIT;
-            break;
-          case  FT32_FLD_R_1:
-            b |= parse_register_operand (&op_end) << FT32_FLD_R_1_BIT;
-            break;
-          case  FT32_FLD_RIMM:
-            if (*op_end == '$')
-              {
-                b |= parse_register_operand (&op_end) << FT32_FLD_RIMM_BIT;
-              }
-            else
-              {
-                b |= 0x400 << FT32_FLD_RIMM_BIT;
-                op_end = parse_exp_save_ilp (op_end, &arg);
-                fix_new_exp (frag_now,
-                             (output - frag_now->fr_literal),
-                             2,
-                             &arg,
-                             0,
-                             BFD_RELOC_FT32_10);
-              }
-            break;
-          case  FT32_FLD_R_2:
-            b |= parse_register_operand (&op_end) << FT32_FLD_R_2_BIT;
-            break;
-          case  FT32_FLD_K20:
-            op_end = parse_exp_save_ilp (op_end, &arg);
-            fix_new_exp (frag_now,
-                         (output - frag_now->fr_literal),
-                         3,
-                         &arg,
-                         0,
-                         BFD_RELOC_FT32_20);
-            break;
-          case  FT32_FLD_PA:
-            op_end = parse_exp_save_ilp (op_end, &arg);
-            fix_new_exp (frag_now,
-                         (output - frag_now->fr_literal),
-                         3,
-                         &arg,
-                         0,
-                         BFD_RELOC_FT32_18);
-            break;
-          case  FT32_FLD_AA:
-            op_end = parse_exp_save_ilp (op_end, &arg);
-            fix_new_exp (frag_now,
-                         (output - frag_now->fr_literal),
-                         3,
-                         &arg,
-                         0,
-                         BFD_RELOC_FT32_17);
-            break;
-          case  FT32_FLD_K16:
-            op_end = parse_exp_save_ilp (op_end, &arg);
-            fix_new_exp (frag_now,
-                         (output - frag_now->fr_literal),
-                         2,
-                         &arg,
-                         0,
-                         BFD_RELOC_16);
-            break;
-          case  FT32_FLD_K15:
-            op_end = parse_exp_save_ilp (op_end, &arg);
-            if (arg.X_add_number & 0x80)
-              arg.X_add_number ^= 0x7f00;
-            fix_new_exp (frag_now,
-                         (output - frag_now->fr_literal),
-                         2,
-                         &arg,
-                         0,
-                         BFD_RELOC_FT32_15);
-            break;
-          case  FT32_FLD_R_D_POST:
-            b |= parse_register_operand (&op_end) << FT32_FLD_R_D_BIT;
-            break;
-          case  FT32_FLD_R_1_POST:
-            b |= parse_register_operand (&op_end) << FT32_FLD_R_1_BIT;
-            break;
-          default:
-            as_bad (_("internal error in argument parsing"));
-            break;
-          }
+	    {
+	    case  FT32_FLD_CBCRCV:
+	      b |= parse_condition( &op_end);
+	      break;
+	    case  FT32_FLD_CB:
+	      b |= parse_decimal (&op_end) << FT32_FLD_CB_BIT;
+	      break;
+	    case  FT32_FLD_R_D:
+	      b |= parse_register_operand (&op_end) << FT32_FLD_R_D_BIT;
+	      break;
+	    case  FT32_FLD_CR:
+	      b |= (parse_register_operand (&op_end) - 28) << FT32_FLD_CR_BIT;
+	      break;
+	    case  FT32_FLD_CV:
+	      b |= parse_decimal (&op_end) << FT32_FLD_CV_BIT;
+	      break;
+	    case  FT32_FLD_R_1:
+	      b |= parse_register_operand (&op_end) << FT32_FLD_R_1_BIT;
+	      break;
+	    case  FT32_FLD_RIMM:
+	      if (*op_end == '$')
+		{
+		  b |= parse_register_operand (&op_end) << FT32_FLD_RIMM_BIT;
+		}
+	      else
+		{
+		  b |= 0x400 << FT32_FLD_RIMM_BIT;
+		  op_end = parse_exp_save_ilp (op_end, &arg);
+		  fixed = TRUE;
+		  fix_new_exp (frag_now,
+			       (output - frag_now->fr_literal),
+			       2,
+			       &arg,
+			       0,
+			       BFD_RELOC_FT32_10);
+		}
+	      break;
+	    case  FT32_FLD_R_2:
+	      b |= parse_register_operand (&op_end) << FT32_FLD_R_2_BIT;
+	      break;
+	    case  FT32_FLD_K20:
+	      op_end = parse_exp_save_ilp (op_end, &arg);
+	      fixed = TRUE;
+	      fix_new_exp (frag_now,
+			   (output - frag_now->fr_literal),
+			   3,
+			   &arg,
+			   0,
+			   BFD_RELOC_FT32_20);
+	      break;
+	    case  FT32_FLD_PA:
+	      op_end = parse_exp_save_ilp (op_end, &arg);
+	      fixed = TRUE;
+	      fix_new_exp (frag_now,
+			   (output - frag_now->fr_literal),
+			   3,
+			   &arg,
+			   0,
+			   BFD_RELOC_FT32_18);
+	      break;
+	    case  FT32_FLD_AA:
+	      op_end = parse_exp_save_ilp (op_end, &arg);
+	      fixed = TRUE;
+	      fix_new_exp (frag_now,
+			   (output - frag_now->fr_literal),
+			   3,
+			   &arg,
+			   0,
+			   BFD_RELOC_FT32_17);
+	      break;
+	    case  FT32_FLD_K16:
+	      op_end = parse_exp_save_ilp (op_end, &arg);
+	      fixed = TRUE;
+	      fix_new_exp (frag_now,
+			   (output - frag_now->fr_literal),
+			   2,
+			   &arg,
+			   0,
+			   BFD_RELOC_16);
+	      break;
+	    case  FT32_FLD_K15:
+	      op_end = parse_exp_save_ilp (op_end, &arg);
+	      if (arg.X_add_number & 0x80)
+		arg.X_add_number ^= 0x7f00;
+	      fixed = TRUE;
+	      fix_new_exp (frag_now,
+			   (output - frag_now->fr_literal),
+			   2,
+			   &arg,
+			   0,
+			   BFD_RELOC_FT32_15);
+	      break;
+	    case  FT32_FLD_R_D_POST:
+	      b |= parse_register_operand (&op_end) << FT32_FLD_R_D_BIT;
+	      break;
+	    case  FT32_FLD_R_1_POST:
+	      b |= parse_register_operand (&op_end) << FT32_FLD_R_1_BIT;
+	      break;
+	    default:
+	      as_bad (_("internal error in argument parsing"));
+	      break;
+	    }
+
           f &= ~lobit;
+
           if (f)
             {
               while (ISSPACE (*op_end))
@@ -387,9 +407,26 @@ md_assemble (char *str)
             }
         }
     }
+
   if (*op_end != 0)
     as_warn (_("extra stuff on line ignored"));
 
+  can_sc = ft32_shortcode (b, &sc);
+
+  if (!fixed && can_sc)
+    {
+      arg.X_op = O_constant;
+      arg.X_add_number = 0;
+      arg.X_add_symbol = NULL;
+      arg.X_op_symbol = NULL;
+      fix_new_exp (frag_now,
+                   (output - frag_now->fr_literal),
+                   2,
+                   &arg,
+                   0,
+                   BFD_RELOC_FT32_RELAX);
+    }
+
   output[idx++] = 0xff & (b >> 0);
   output[idx++] = 0xff & (b >> 8);
   output[idx++] = 0xff & (b >> 16);
@@ -454,6 +491,9 @@ const char *md_shortopts = "";
 
 struct option md_longopts[] =
 {
+#define OPTION_NORELAX (OPTION_MD_BASE)
+  {"norelax", no_argument, NULL, OPTION_NORELAX},
+  {"no-relax", no_argument, NULL, OPTION_NORELAX},
   {NULL, no_argument, NULL, 0}
 };
 size_t md_longopts_size = sizeof (md_longopts);
@@ -463,12 +503,26 @@ size_t md_longopts_size = sizeof (md_longopts);
 int
 md_parse_option (int c ATTRIBUTE_UNUSED, const char *arg ATTRIBUTE_UNUSED)
 {
-  return 0;
+  switch (c)
+    {
+    case OPTION_NORELAX:
+      norelax = 1;
+      break;
+
+    default:
+      return 0;
+    }
+
+  return 1;
 }
 
 void
 md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
 {
+  fprintf (stream, _("FT32 options:\n"));
+  fprintf (stream, _("\n\
+-no-relax		don't relax relocations\n\
+			\n"));
 }
 
 /* Convert from target byte order to host byte order.  */
@@ -487,6 +541,7 @@ md_chars_to_number (char * buf, int n)
 
   return result;
 }
+
 /* Apply a fixup to the object file.  */
 
 void
@@ -497,8 +552,43 @@ md_apply_fix (fixS *fixP ATTRIBUTE_UNUSED,
   long val = *valP;
   long newval;
 
+  if (linkrelax && fixP->fx_subsy)
+    {
+      /* For a subtraction relocation expression, generate one
+         of the DIFF relocs, with the value being the difference.
+         Note that a sym1 - sym2 expression is adjusted into a
+         section_start_sym + sym4_offset_from_section_start - sym1
+         expression. fixP->fx_addsy holds the section start symbol,
+         fixP->fx_offset holds sym2's offset, and fixP->fx_subsy
+         holds sym1. Calculate the current difference and write value,
+         but leave fx_offset as is - during relaxation,
+         fx_offset - value gives sym1's value.  */
+
+       switch (fixP->fx_r_type)
+         {
+           case BFD_RELOC_32:
+             fixP->fx_r_type = BFD_RELOC_FT32_DIFF32;
+             break;
+           default:
+             as_bad_where (fixP->fx_file, fixP->fx_line,
+                           _("expression too complex"));
+             break;
+         }
+
+      val = S_GET_VALUE (fixP->fx_addsy) +
+          fixP->fx_offset - S_GET_VALUE (fixP->fx_subsy);
+      *valP = val;
+
+      fixP->fx_subsy = NULL;
+  }
+
+  /* We don't actually support subtracting a symbol.  */
+  if (fixP->fx_subsy != (symbolS *) NULL)
+    as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex"));
+
   switch (fixP->fx_r_type)
     {
+    case BFD_RELOC_FT32_DIFF32:
     case BFD_RELOC_32:
       buf[3] = val >> 24;
       buf[2] = val >> 16;
@@ -555,13 +645,15 @@ md_apply_fix (fixS *fixP ATTRIBUTE_UNUSED,
       md_number_to_chars (buf, newval, 4);
       break;
 
+    case BFD_RELOC_FT32_RELAX:
+      break;
+
     default:
       abort ();
     }
 
   if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
     fixP->fx_done = 1;
-  // printf("fx_addsy=%p fixP->fx_pcrel=%d fx_done=%d\n", fixP->fx_addsy, fixP->fx_pcrel, fixP->fx_done);
 }
 
 void
@@ -571,6 +663,7 @@ md_number_to_chars (char *ptr, valueT use, int nbytes)
 }
 
 /* Generate a machine-dependent relocation.  */
+
 arelent *
 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
 {
@@ -587,12 +680,15 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
     case BFD_RELOC_FT32_15:
     case BFD_RELOC_FT32_17:
     case BFD_RELOC_FT32_18:
+    case BFD_RELOC_FT32_RELAX:
+    case BFD_RELOC_FT32_DIFF32:
       code = fixP->fx_r_type;
       break;
     default:
       as_bad_where (fixP->fx_file, fixP->fx_line,
-		    _("Semantics error.  This type of operand can not be relocated, it must be an assembly-time constant"));
-      return 0;
+		    _("Semantics error.  This type of operand can not be "
+                      "relocated, it must be an assembly-time constant"));
+      return NULL;
     }
 
   relP = XNEW (arelent);
@@ -617,3 +713,80 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
 
   return relP;
 }
+
+/* TC_FORCE_RELOCATION hook */
+
+static bfd_boolean
+relaxable_section (asection *sec)
+{
+  return ((sec->flags & SEC_DEBUGGING) == 0
+          && (sec->flags & SEC_CODE) != 0
+          && (sec->flags & SEC_ALLOC) != 0);
+}
+
+/* Does whatever the xtensa port does.  */
+
+int
+ft32_validate_fix_sub (fixS *fix)
+{
+  segT add_symbol_segment, sub_symbol_segment;
+
+  /* The difference of two symbols should be resolved by the assembler when
+     linkrelax is not set.  If the linker may relax the section containing
+     the symbols, then an Xtensa DIFF relocation must be generated so that
+     the linker knows to adjust the difference value.  */
+  if (!linkrelax || fix->fx_addsy == NULL)
+    return 0;
+
+  /* Make sure both symbols are in the same segment, and that segment is
+     "normal" and relaxable.  If the segment is not "normal", then the
+     fix is not valid.  If the segment is not "relaxable", then the fix
+     should have been handled earlier.  */
+  add_symbol_segment = S_GET_SEGMENT (fix->fx_addsy);
+  if (! SEG_NORMAL (add_symbol_segment) ||
+      ! relaxable_section (add_symbol_segment))
+    return 0;
+
+  sub_symbol_segment = S_GET_SEGMENT (fix->fx_subsy);
+  return (sub_symbol_segment == add_symbol_segment);
+}
+
+/* TC_FORCE_RELOCATION hook */
+
+/* If linkrelax is turned on, and the symbol to relocate
+   against is in a relaxable segment, don't compute the value -
+   generate a relocation instead.  */
+
+int
+ft32_force_relocation (fixS *fix)
+{
+  if (linkrelax && fix->fx_addsy
+      && relaxable_section (S_GET_SEGMENT (fix->fx_addsy)))
+    {
+      return 1;
+    }
+
+  return generic_force_reloc (fix);
+}
+
+bfd_boolean
+ft32_allow_local_subtract (expressionS * left,
+			   expressionS * right,
+			   segT section)
+{
+  /* If we are not in relaxation mode, subtraction is OK.  */
+  if (!linkrelax)
+    return TRUE;
+
+  /* If the symbols are not in a code section then they are OK.  */
+  if ((section->flags & SEC_CODE) == 0)
+    return TRUE;
+
+  if (left->X_add_symbol == right->X_add_symbol)
+    return TRUE;
+
+  /* We have to assume that there may be instructions between the
+     two symbols and that relaxation may increase the distance between
+     them.  */
+  return FALSE;
+}
diff --git a/gas/config/tc-ft32.h b/gas/config/tc-ft32.h
index cc80c81..b34a886 100644
--- a/gas/config/tc-ft32.h
+++ b/gas/config/tc-ft32.h
@@ -35,14 +35,6 @@
 #define md_estimate_size_before_relax(A, B) (as_fatal (_("estimate size\n")), 0)
 #define md_convert_frag(B, S, F)            (as_fatal (_("convert_frag\n")))
 
-/* If you define this macro, it should return the offset between the
-   address of a PC relative fixup and the position from which the PC
-   relative adjustment 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.  */
-// #define MD_PCREL_FROM_SECTION(FIX, SEC) md_pcrel_from (FIX)
-// extern long md_pcrel_from (struct fix *);
-
 /* PC relative operands are relative to the start of the opcode, and
    the operand is always one byte into the opcode.  */
 #define md_pcrel_from(FIX)						\
@@ -50,4 +42,27 @@
 
 #define md_section_align(SEGMENT, SIZE)     (SIZE)
 
+/* If this macro returns non-zero, it guarantees that a relocation will be emitted
+   even when the value can be resolved locally. Do that if linkrelax is turned on */
+#define TC_FORCE_RELOCATION(fix)	ft32_force_relocation (fix)
+#define TC_FORCE_RELOCATION_SUB_SAME(fix, seg) \
+  (! SEG_NORMAL (seg) || ft32_force_relocation (fix))
+extern int ft32_force_relocation (struct fix *);
+
+#define TC_LINKRELAX_FIXUP(seg) \
+  ((seg->flags & SEC_CODE) || (seg->flags & SEC_DEBUGGING))
+
+/* This macro is evaluated for any fixup with a fx_subsy that
+   fixup_segment cannot reduce to a number.  If the macro returns
+   false an error will be reported. */
+#define TC_VALIDATE_FIX_SUB(fix, seg)   ft32_validate_fix_sub (fix)
+extern int ft32_validate_fix_sub (struct fix *);
+
+/* The difference between same-section symbols may be affected by linker
+   relaxation, so do not resolve such expressions in the assembler.  */
+#define md_allow_local_subtract(l,r,s) ft32_allow_local_subtract (l, r, s)
+extern bfd_boolean ft32_allow_local_subtract (expressionS *,
+                                              expressionS *,
+                                              segT);
+
 #define md_operand(x)
diff --git a/gas/testsuite/gas/all/gas.exp b/gas/testsuite/gas/all/gas.exp
index 942b0b4..7347675 100644
--- a/gas/testsuite/gas/all/gas.exp
+++ b/gas/testsuite/gas/all/gas.exp
@@ -59,6 +59,7 @@ if { ![istarget cris-*-*] && ![istarget crisv32-*-*]
 if {    ![istarget alpha*-*-*vms*]
      && ![istarget am3*-*-*]
      && ![istarget avr-*-*]
+     && ![istarget ft32-*-*]
      && ![istarget hppa*-*-*]
      && ![istarget microblaze-*-*]
      && ![istarget mn10300-*-*]
@@ -276,6 +277,7 @@ if {    ![istarget *c30*-*-*]
      && ![istarget *c54x*-*-*]
      && ![istarget cr16*-*-*]
      && ![istarget crx*-*-*]
+     && ![istarget ft32-*-*]
      && ![istarget h8300*-*-*]
      && ![istarget hppa*-*-*] } then {
     # The vax fails because VMS can apparently actually handle this
diff --git a/gas/testsuite/gas/elf/dwarf2-11.d b/gas/testsuite/gas/elf/dwarf2-11.d
index 636d21b..7a4d7a6 100644
--- a/gas/testsuite/gas/elf/dwarf2-11.d
+++ b/gas/testsuite/gas/elf/dwarf2-11.d
@@ -1,10 +1,10 @@
 #as:
 #readelf: -wL
 #name: DWARF2 11
-# The am33 avr cr16 crx mn10 msp430 nds32 pru rl78 and xtensa targets do not evaluate the subtraction of symbols at assembly time.
+# The am33 avr cr16 crx ft32 mn10 msp430 nds32 pru rl78 and xtensa targets do not evaluate the subtraction of symbols at assembly time.
 # The riscv targets do not support the subtraction of symbols.
 # The tile targets require 8-byte instructions, but the test only simulates 4-byte instructions.
-#not-target: am3*-* avr-* cr16-* crx-* m32c-* mn10*-* msp430-* nds32*-* pru-* riscv*-* rl78-* tile*-* xtensa-*
+#not-target: am3*-* avr-* cr16-* crx-* ft32*-* m32c-* mn10*-* msp430-* nds32*-* pru-* riscv*-* rl78-* tile*-* xtensa-*
 
 Decoded dump of debug contents of section \.debug_line:
 
diff --git a/gas/testsuite/gas/elf/dwarf2-12.d b/gas/testsuite/gas/elf/dwarf2-12.d
index 4caaa46..275d48f 100644
--- a/gas/testsuite/gas/elf/dwarf2-12.d
+++ b/gas/testsuite/gas/elf/dwarf2-12.d
@@ -1,10 +1,10 @@
 #as:
 #readelf: -x.rodata -wL
 #name: DWARF2 12
-# The am33 avr cr16 crx mn10 msp430 nds32 pru rl78 and xtensa targets do not evaluate the subtraction of symbols at assembly time.
+# The am33 avr cr16 crx ft32 mn10 msp430 nds32 pru rl78 and xtensa targets do not evaluate the subtraction of symbols at assembly time.
 # The riscv targets do not support the subtraction of symbols.
 # The tile targets require 8-byte instructions, but the test only simulates 4-byte instructions.
-#not-target: am3*-* avr-* cr16-* crx-* mn10*-* msp430-* nds32*-* pru-* riscv*-* rl78-* tile*-* xtensa-*
+#not-target: am3*-* avr-* cr16-* crx-* ft32-* mn10*-* msp430-* nds32*-* pru-* riscv*-* rl78-* tile*-* xtensa-*
 
 
 Hex dump of section '\.rodata':
diff --git a/gas/testsuite/gas/elf/dwarf2-13.d b/gas/testsuite/gas/elf/dwarf2-13.d
index cbbc199..263413c 100644
--- a/gas/testsuite/gas/elf/dwarf2-13.d
+++ b/gas/testsuite/gas/elf/dwarf2-13.d
@@ -1,10 +1,10 @@
 #as:
 #readelf: -x.rodata -wL
 #name: DWARF2 13
-# The am33 avr cr16 crx mn10 msp430 nds32 pru rl78 and xtensa targets do not evaluate the subtraction of symbols at assembly time.
+# The am33 avr cr16 crx ft32 mn10 msp430 nds32 pru rl78 and xtensa targets do not evaluate the subtraction of symbols at assembly time.
 # The riscv targets do not support the subtraction of symbols.
 # The tile targets require 8-byte instructions, but the test only simulates 4-byte instructions.
-#not-target: am3*-* avr-* cr16-* crx-* mn10*-* msp430-* nds32*-* pru-* riscv*-* rl78-* tile*-* xtensa-*
+#not-target: am3*-* avr-* cr16-* crx-* ft32*-* mn10*-* msp430-* nds32*-* pru-* riscv*-* rl78-* tile*-* xtensa-*
 
 Hex dump of section '\.rodata':
   0x00000000 01 *.*
diff --git a/gas/testsuite/gas/elf/dwarf2-14.d b/gas/testsuite/gas/elf/dwarf2-14.d
index f553e83..0a73d2f 100644
--- a/gas/testsuite/gas/elf/dwarf2-14.d
+++ b/gas/testsuite/gas/elf/dwarf2-14.d
@@ -1,10 +1,10 @@
 #as:
 #readelf: -x.rodata -wL
 #name: DWARF2 14
-# The am33 avr cr16 crx mn10 msp430 nds32 pru rl78 and xtensa targets do not evaluate the subtraction of symbols at assembly time
+# The am33 avr cr16 crx mn10 ft32 msp430 nds32 pru rl78 and xtensa targets do not evaluate the subtraction of symbols at assembly time
 # The riscv targets do not support the subtraction of symbols.
 # The tile targets require 8-byte instructions, but the test only simulates 4-byte instructions.
-#not-target: am3*-* avr-* cr16-* crx-* mn10*-* msp430-* nds32*-* pru-* riscv*-* rl78-* tile*-* xtensa-*
+#not-target: am3*-* avr-* cr16-* crx-* ft32*-* mn10*-* msp430-* nds32*-* pru-* riscv*-* rl78-* tile*-* xtensa-*
 
 Hex dump of section '\.rodata':
   0x00000000 01 *.*
diff --git a/gas/testsuite/gas/elf/dwarf2-15.d b/gas/testsuite/gas/elf/dwarf2-15.d
index 6badad9..add4669 100644
--- a/gas/testsuite/gas/elf/dwarf2-15.d
+++ b/gas/testsuite/gas/elf/dwarf2-15.d
@@ -1,10 +1,10 @@
 #as:
 #readelf: -x.rodata -wL
 #name: DWARF2 15
-# The am33 avr cr16 crx mn10 msp430 nds32 pru rl78 and xtensa targets do not evaluate the subtraction of symbols at assembly time.
+# The am33 avr cr16 crx ft32 mn10 msp430 nds32 pru rl78 and xtensa targets do not evaluate the subtraction of symbols at assembly time.
 # The riscv targets do not support the subtraction of symbols.
 # The tile targets require 8-byte instructions, but the test only simulates 4-byte instructions.
-#not-target: am3*-* avr-* cr16-* crx-* mn10*-* msp430-* nds32*-* pru-* riscv*-* rl78-* tile*-* xtensa-*
+#not-target: am3*-* avr-* cr16-* crx-* ft32*-* mn10*-* msp430-* nds32*-* pru-* riscv*-* rl78-* tile*-* xtensa-*
 
 Hex dump of section '\.rodata':
   0x00000000 01 *.*
diff --git a/gas/testsuite/gas/elf/dwarf2-16.d b/gas/testsuite/gas/elf/dwarf2-16.d
index d01bd79..ecd07ff 100644
--- a/gas/testsuite/gas/elf/dwarf2-16.d
+++ b/gas/testsuite/gas/elf/dwarf2-16.d
@@ -1,11 +1,11 @@
 #as:
 #readelf: -x.rodata -wL
 #name: DWARF2 16
-# The am33 avr cr16 crx mn10 msp430 nds32 pru rl78 and xtensa targets do not evaluate the subtraction of symbols at assembly time.
+# The am33 avr cr16 crx ft32 mn10 msp430 nds32 pru rl78 and xtensa targets do not evaluate the subtraction of symbols at assembly time.
 # The mep target tries to relay code sections which breaks symbolic view computations.
 # The riscv targets do not support the subtraction of symbols.
 # The tile targets require 8-byte instructions, but the test only simulates 4-byte instructions.
-#not-target: am3*-* avr-* cr16-* crx-* mep-* mn10*-* msp430-* nds32*-* pru-* riscv*-* rl78-* tile*-* xtensa-*
+#not-target: am3*-* avr-* cr16-* crx-* ft32*-* mep-* mn10*-* msp430-* nds32*-* pru-* riscv*-* rl78-* tile*-* xtensa-*
 
 Hex dump of section '\.rodata':
   0x00000000 01 *.*
diff --git a/gas/testsuite/gas/elf/dwarf2-17.d b/gas/testsuite/gas/elf/dwarf2-17.d
index c5de9e3..804767f 100644
--- a/gas/testsuite/gas/elf/dwarf2-17.d
+++ b/gas/testsuite/gas/elf/dwarf2-17.d
@@ -1,11 +1,11 @@
 #as:
 #readelf: -x.rodata -wL
 #name: DWARF2 17
-# The am33 avr cr16 crx mn10 msp430 nds32 pru rl78 and xtensa targets do not evaluate the subtraction of symbols at assembly time.
+# The am33 avr cr16 crx ft32 mn10 msp430 nds32 pru rl78 and xtensa targets do not evaluate the subtraction of symbols at assembly time.
 # The mep target tries to relay code sections which breaks symbolic view computations.
 # The riscv targets do not support the subtraction of symbols.
 # The tile targets require 8-byte instructions, but the test only simulates 4-byte instructions.
-#not-target: am3*-* avr-* cr16-* crx-* mep-* mn10*-* msp430-* nds32*-* pru-* riscv*-* rl78-* tile*-* xtensa-*
+#not-target: am3*-* avr-* cr16-* crx-* ft32*-* mep-* mn10*-* msp430-* nds32*-* pru-* riscv*-* rl78-* tile*-* xtensa-*
 
 Hex dump of section '\.rodata':
   0x00000000 00 *.*
diff --git a/gas/testsuite/gas/elf/dwarf2-18.d b/gas/testsuite/gas/elf/dwarf2-18.d
index 437bb2f..33883a2 100644
--- a/gas/testsuite/gas/elf/dwarf2-18.d
+++ b/gas/testsuite/gas/elf/dwarf2-18.d
@@ -1,10 +1,10 @@
 #as:
 #readelf: -x.rodata -wL
 #name: DWARF2 18
-# The am33 avr cr16 crx mn10 msp430 nds32 pru rl78 and xtensa targets do not evaluate the subtraction of symbols at assembly time.
+# The am33 avr cr16 crx ft32 mn10 msp430 nds32 pru rl78 and xtensa targets do not evaluate the subtraction of symbols at assembly time.
 # The riscv targets do not support the subtraction of symbols.
 # The tile targets require 8-byte instructions, but the test only simulates 4-byte instructions.
-#not-target: am3*-* avr-* cr16-* crx-* mn10*-* msp430-* nds32*-* pru-* riscv*-* rl78-* tile*-* xtensa-*
+#not-target: am3*-* avr-* cr16-* crx-* ft32*-* mn10*-* msp430-* nds32*-* pru-* riscv*-* rl78-* tile*-* xtensa-*
 
 Hex dump of section '\.rodata':
   0x00000000 0100 *.*
diff --git a/gas/testsuite/gas/elf/dwarf2-3.d b/gas/testsuite/gas/elf/dwarf2-3.d
index f9f29a6..3cb0834 100644
--- a/gas/testsuite/gas/elf/dwarf2-3.d
+++ b/gas/testsuite/gas/elf/dwarf2-3.d
@@ -1,6 +1,6 @@
 #readelf: -wl
 #name: DWARF2 3
-#not-target: ia64-*-* h8300-*-*
+#not-target: ft32*-* ia64-*-* h8300-*-*
 
 Raw dump of debug contents of section \.z?debug_line:
 
diff --git a/gas/testsuite/gas/elf/dwarf2-5.d b/gas/testsuite/gas/elf/dwarf2-5.d
index 8b2ea2a..03829fb 100644
--- a/gas/testsuite/gas/elf/dwarf2-5.d
+++ b/gas/testsuite/gas/elf/dwarf2-5.d
@@ -1,11 +1,11 @@
 #as:
 #readelf: -x.rodata -wlL
 #name: DWARF2 5
-# The am33 avr cr16 crx mn10 msp430 nds32 pru rl78 rx and xtensa targets do not evaluate the subtraction of symbols at assembly time.
+# The am33 avr cr16 crx ft32 mn10 msp430 nds32 pru rl78 rx and xtensa targets do not evaluate the subtraction of symbols at assembly time.
 # The mep target tries to relay code sections which breaks symbolic view computations.
 # The riscv targets do not support the subtraction of symbols.
 # The tile targets require 8-byte instructions, but the test only simulates 4-byte instructions.
-#not-target: am3*-* avr-* cr16-* crx-* mep-* mn10*-* msp430-* nds32*-* pru-* riscv*-* rl78-* rx-* tile*-* xtensa-*
+#not-target: am3*-* avr-* cr16-* crx-* ft32*-* mep-* mn10*-* msp430-* nds32*-* pru-* riscv*-* rl78-* rx-* tile*-* xtensa-*
 
 Hex dump of section '\.rodata':
   0x00000000 01010201 010203 *.*
diff --git a/gas/testsuite/gas/elf/dwarf2-7.d b/gas/testsuite/gas/elf/dwarf2-7.d
index 0e7963d..c7121d1 100644
--- a/gas/testsuite/gas/elf/dwarf2-7.d
+++ b/gas/testsuite/gas/elf/dwarf2-7.d
@@ -1,10 +1,10 @@
 #as:
 #readelf: -x.rodata -wL
 #name: DWARF2 7
-# The am33 avr cr16 crx mn10 msp430 nds32 pru rl78 and xtensa targets do not evaluate the subtraction of symbols at assembly time.
+# The am33 avr cr16 crx ft32 mn10 msp430 nds32 pru rl78 and xtensa targets do not evaluate the subtraction of symbols at assembly time.
 # The riscv targets do not support the subtraction of symbols.
 # The tile targets require 8-byte instructions, but the test only simulates 4-byte instructions.
-#not-target: am3*-* avr-* cr16-* crx-* mn10*-* msp430-* nds32*-* pru-* riscv*-* rl78-* tile*-* xtensa-*
+#not-target: am3*-* avr-* cr16-* crx-* ft32*-* mn10*-* msp430-* nds32*-* pru-* riscv*-* rl78-* tile*-* xtensa-*
 
 Hex dump of section '\.rodata':
   0x00000000 01 *.*
diff --git a/gas/testsuite/gas/ft32/ft32.exp b/gas/testsuite/gas/ft32/ft32.exp
index bfa8419..4d59d7c 100644
--- a/gas/testsuite/gas/ft32/ft32.exp
+++ b/gas/testsuite/gas/ft32/ft32.exp
@@ -18,4 +18,5 @@
 
 if [istarget ft32-*-*] {
     run_dump_test "insn"
+    run_dump_test "insnsc"
 }
diff --git a/gas/testsuite/gas/ft32/insn.d b/gas/testsuite/gas/ft32/insn.d
index f9b643a..3a7e9e5 100644
--- a/gas/testsuite/gas/ft32/insn.d
+++ b/gas/testsuite/gas/ft32/insn.d
@@ -13,298 +13,298 @@ Disassembly of section .text:
    8:	f0 01 00 44 	440001f0 add.l \$r0,\$r0,\$r31
    c:	40 00 11 44 	44110040 add.l \$r1,\$r2,\$r4
   10:	00 00 88 44 	44880000 add.l \$r8,\$r16,\$r0
-  14:	00 60 f0 45 	45f06000 add.l \$r31,\$r0,200 <pmlabel.*>
+  14:	00 40 f0 45 	45f04000 move.l \$r31,\$r0
   18:	00 c0 0f 44 	440fc000 move.l \$r0,\$r31
-  1c:	10 c0 0f 44 	440fc010 add.l \$r0,\$r31,1 <pmlabel\+0x1>
-  20:	f0 df 0f 44 	440fdff0 add.l \$r0,\$r31,1ff <pmlabel\+0x1ff>
+  1c:	00 c0 0f 44 	440fc000 move.l \$r0,\$r31
+  20:	00 c0 0f 44 	440fc000 move.l \$r0,\$r31
   24:	10 80 0f 42 	420f8010 add.s \$r0,\$r31,\$r1
-  28:	d0 c4 0f 42 	420fc4d0 add.s \$r0,\$r31,4d <pmlabel\+0x4d>
+  28:	00 c0 0f 42 	420fc000 move.s \$r0,\$r31
   2c:	10 80 0f 40 	400f8010 add.b \$r0,\$r31,\$r1
-  30:	d0 c4 0f 40 	400fc4d0 add.b \$r0,\$r31,4d <pmlabel\+0x4d>
+  30:	00 c0 0f 40 	400fc000 move.b \$r0,\$r31
   34:	02 00 f0 45 	45f00002 sub.l \$r31,\$r0,\$r0
   38:	02 80 0f 44 	440f8002 sub.l \$r0,\$r31,\$r0
   3c:	f2 01 00 44 	440001f2 sub.l \$r0,\$r0,\$r31
   40:	42 00 11 44 	44110042 sub.l \$r1,\$r2,\$r4
   44:	02 00 88 44 	44880002 sub.l \$r8,\$r16,\$r0
-  48:	02 60 f0 45 	45f06002 sub.l \$r31,\$r0,200 <pmlabel.*>
-  4c:	02 c0 0f 44 	440fc002 sub.l \$r0,\$r31,0 <pmlabel.*>
-  50:	12 c0 0f 44 	440fc012 sub.l \$r0,\$r31,1 <pmlabel\+0x1>
-  54:	f2 df 0f 44 	440fdff2 sub.l \$r0,\$r31,1ff <pmlabel\+0x1ff>
+  48:	02 40 f0 45 	45f04002 sub.l \$r31,\$r0,0
+  4c:	02 c0 0f 44 	440fc002 sub.l \$r0,\$r31,0
+  50:	02 c0 0f 44 	440fc002 sub.l \$r0,\$r31,0
+  54:	02 c0 0f 44 	440fc002 sub.l \$r0,\$r31,0
   58:	12 80 0f 42 	420f8012 sub.s \$r0,\$r31,\$r1
-  5c:	d2 c4 0f 42 	420fc4d2 sub.s \$r0,\$r31,4d <pmlabel\+0x4d>
+  5c:	02 c0 0f 42 	420fc002 sub.s \$r0,\$r31,0
   60:	12 80 0f 40 	400f8012 sub.b \$r0,\$r31,\$r1
-  64:	d2 c4 0f 40 	400fc4d2 sub.b \$r0,\$r31,4d <pmlabel\+0x4d>
+  64:	02 c0 0f 40 	400fc002 sub.b \$r0,\$r31,0
   68:	04 00 f0 45 	45f00004 and.l \$r31,\$r0,\$r0
   6c:	04 80 0f 44 	440f8004 and.l \$r0,\$r31,\$r0
   70:	f4 01 00 44 	440001f4 and.l \$r0,\$r0,\$r31
   74:	44 00 11 44 	44110044 and.l \$r1,\$r2,\$r4
   78:	04 00 88 44 	44880004 and.l \$r8,\$r16,\$r0
-  7c:	04 60 f0 45 	45f06004 and.l \$r31,\$r0,200 <pmlabel.*>
-  80:	04 c0 0f 44 	440fc004 and.l \$r0,\$r31,0 <pmlabel.*>
-  84:	14 c0 0f 44 	440fc014 and.l \$r0,\$r31,1 <pmlabel\+0x1>
-  88:	f4 df 0f 44 	440fdff4 and.l \$r0,\$r31,1ff <pmlabel\+0x1ff>
+  7c:	04 40 f0 45 	45f04004 and.l \$r31,\$r0,0
+  80:	04 c0 0f 44 	440fc004 and.l \$r0,\$r31,0
+  84:	04 c0 0f 44 	440fc004 and.l \$r0,\$r31,0
+  88:	04 c0 0f 44 	440fc004 and.l \$r0,\$r31,0
   8c:	14 80 0f 42 	420f8014 and.s \$r0,\$r31,\$r1
-  90:	d4 c4 0f 42 	420fc4d4 and.s \$r0,\$r31,4d <pmlabel\+0x4d>
+  90:	04 c0 0f 42 	420fc004 and.s \$r0,\$r31,0
   94:	14 80 0f 40 	400f8014 and.b \$r0,\$r31,\$r1
-  98:	d4 c4 0f 40 	400fc4d4 and.b \$r0,\$r31,4d <pmlabel\+0x4d>
+  98:	04 c0 0f 40 	400fc004 and.b \$r0,\$r31,0
   9c:	05 00 f0 45 	45f00005 or.l \$r31,\$r0,\$r0
   a0:	05 80 0f 44 	440f8005 or.l \$r0,\$r31,\$r0
   a4:	f5 01 00 44 	440001f5 or.l \$r0,\$r0,\$r31
   a8:	45 00 11 44 	44110045 or.l \$r1,\$r2,\$r4
   ac:	05 00 88 44 	44880005 or.l \$r8,\$r16,\$r0
-  b0:	05 60 f0 45 	45f06005 or.l \$r31,\$r0,200 <pmlabel.*>
-  b4:	05 c0 0f 44 	440fc005 or.l \$r0,\$r31,0 <pmlabel.*>
-  b8:	15 c0 0f 44 	440fc015 or.l \$r0,\$r31,1 <pmlabel\+0x1>
-  bc:	f5 df 0f 44 	440fdff5 or.l \$r0,\$r31,1ff <pmlabel\+0x1ff>
+  b0:	05 40 f0 45 	45f04005 or.l \$r31,\$r0,0
+  b4:	05 c0 0f 44 	440fc005 or.l \$r0,\$r31,0
+  b8:	05 c0 0f 44 	440fc005 or.l \$r0,\$r31,0
+  bc:	05 c0 0f 44 	440fc005 or.l \$r0,\$r31,0
   c0:	15 80 0f 42 	420f8015 or.s \$r0,\$r31,\$r1
-  c4:	d5 c4 0f 42 	420fc4d5 or.s \$r0,\$r31,4d <pmlabel\+0x4d>
+  c4:	05 c0 0f 42 	420fc005 or.s \$r0,\$r31,0
   c8:	15 80 0f 40 	400f8015 or.b \$r0,\$r31,\$r1
-  cc:	d5 c4 0f 40 	400fc4d5 or.b \$r0,\$r31,4d <pmlabel\+0x4d>
+  cc:	05 c0 0f 40 	400fc005 or.b \$r0,\$r31,0
   d0:	06 00 f0 45 	45f00006 xor.l \$r31,\$r0,\$r0
   d4:	06 80 0f 44 	440f8006 xor.l \$r0,\$r31,\$r0
   d8:	f6 01 00 44 	440001f6 xor.l \$r0,\$r0,\$r31
   dc:	46 00 11 44 	44110046 xor.l \$r1,\$r2,\$r4
   e0:	06 00 88 44 	44880006 xor.l \$r8,\$r16,\$r0
-  e4:	06 60 f0 45 	45f06006 xor.l \$r31,\$r0,200 <pmlabel.*>
-  e8:	06 c0 0f 44 	440fc006 xor.l \$r0,\$r31,0 <pmlabel.*>
-  ec:	16 c0 0f 44 	440fc016 xor.l \$r0,\$r31,1 <pmlabel\+0x1>
-  f0:	f6 df 0f 44 	440fdff6 xor.l \$r0,\$r31,1ff <pmlabel\+0x1ff>
+  e4:	06 40 f0 45 	45f04006 xor.l \$r31,\$r0,0
+  e8:	06 c0 0f 44 	440fc006 xor.l \$r0,\$r31,0
+  ec:	06 c0 0f 44 	440fc006 xor.l \$r0,\$r31,0
+  f0:	06 c0 0f 44 	440fc006 xor.l \$r0,\$r31,0
   f4:	16 80 0f 42 	420f8016 xor.s \$r0,\$r31,\$r1
-  f8:	d6 c4 0f 42 	420fc4d6 xor.s \$r0,\$r31,4d <pmlabel\+0x4d>
+  f8:	06 c0 0f 42 	420fc006 xor.s \$r0,\$r31,0
   fc:	16 80 0f 40 	400f8016 xor.b \$r0,\$r31,\$r1
- 100:	d6 c4 0f 40 	400fc4d6 xor.b \$r0,\$r31,4d <pmlabel\+0x4d>
+ 100:	06 c0 0f 40 	400fc006 xor.b \$r0,\$r31,0
  104:	07 00 f0 45 	45f00007 xnor.l \$r31,\$r0,\$r0
  108:	07 80 0f 44 	440f8007 xnor.l \$r0,\$r31,\$r0
  10c:	f7 01 00 44 	440001f7 xnor.l \$r0,\$r0,\$r31
  110:	47 00 11 44 	44110047 xnor.l \$r1,\$r2,\$r4
  114:	07 00 88 44 	44880007 xnor.l \$r8,\$r16,\$r0
- 118:	07 60 f0 45 	45f06007 xnor.l \$r31,\$r0,200 <pmlabel.*>
- 11c:	07 c0 0f 44 	440fc007 xnor.l \$r0,\$r31,0 <pmlabel.*>
- 120:	17 c0 0f 44 	440fc017 xnor.l \$r0,\$r31,1 <pmlabel\+0x1>
- 124:	f7 df 0f 44 	440fdff7 xnor.l \$r0,\$r31,1ff <pmlabel\+0x1ff>
+ 118:	07 40 f0 45 	45f04007 xnor.l \$r31,\$r0,0
+ 11c:	07 c0 0f 44 	440fc007 xnor.l \$r0,\$r31,0
+ 120:	07 c0 0f 44 	440fc007 xnor.l \$r0,\$r31,0
+ 124:	07 c0 0f 44 	440fc007 xnor.l \$r0,\$r31,0
  128:	17 80 0f 42 	420f8017 xnor.s \$r0,\$r31,\$r1
- 12c:	d7 c4 0f 42 	420fc4d7 xnor.s \$r0,\$r31,4d <pmlabel\+0x4d>
+ 12c:	07 c0 0f 42 	420fc007 xnor.s \$r0,\$r31,0
  130:	17 80 0f 40 	400f8017 xnor.b \$r0,\$r31,\$r1
- 134:	d7 c4 0f 40 	400fc4d7 xnor.b \$r0,\$r31,4d <pmlabel\+0x4d>
+ 134:	07 c0 0f 40 	400fc007 xnor.b \$r0,\$r31,0
  138:	08 00 f0 45 	45f00008 ashl.l \$r31,\$r0,\$r0
  13c:	08 80 0f 44 	440f8008 ashl.l \$r0,\$r31,\$r0
  140:	f8 01 00 44 	440001f8 ashl.l \$r0,\$r0,\$r31
  144:	48 00 11 44 	44110048 ashl.l \$r1,\$r2,\$r4
  148:	08 00 88 44 	44880008 ashl.l \$r8,\$r16,\$r0
- 14c:	08 60 f0 45 	45f06008 ashl.l \$r31,\$r0,200 <pmlabel.*>
- 150:	08 c0 0f 44 	440fc008 ashl.l \$r0,\$r31,0 <pmlabel.*>
- 154:	18 c0 0f 44 	440fc018 ashl.l \$r0,\$r31,1 <pmlabel\+0x1>
- 158:	f8 df 0f 44 	440fdff8 ashl.l \$r0,\$r31,1ff <pmlabel\+0x1ff>
+ 14c:	08 40 f0 45 	45f04008 ashl.l \$r31,\$r0,0
+ 150:	08 c0 0f 44 	440fc008 ashl.l \$r0,\$r31,0
+ 154:	08 c0 0f 44 	440fc008 ashl.l \$r0,\$r31,0
+ 158:	08 c0 0f 44 	440fc008 ashl.l \$r0,\$r31,0
  15c:	18 80 0f 42 	420f8018 ashl.s \$r0,\$r31,\$r1
- 160:	d8 c4 0f 42 	420fc4d8 ashl.s \$r0,\$r31,4d <pmlabel\+0x4d>
+ 160:	08 c0 0f 42 	420fc008 ashl.s \$r0,\$r31,0
  164:	18 80 0f 40 	400f8018 ashl.b \$r0,\$r31,\$r1
- 168:	d8 c4 0f 40 	400fc4d8 ashl.b \$r0,\$r31,4d <pmlabel\+0x4d>
+ 168:	08 c0 0f 40 	400fc008 ashl.b \$r0,\$r31,0
  16c:	09 00 f0 45 	45f00009 lshr.l \$r31,\$r0,\$r0
  170:	09 80 0f 44 	440f8009 lshr.l \$r0,\$r31,\$r0
  174:	f9 01 00 44 	440001f9 lshr.l \$r0,\$r0,\$r31
  178:	49 00 11 44 	44110049 lshr.l \$r1,\$r2,\$r4
  17c:	09 00 88 44 	44880009 lshr.l \$r8,\$r16,\$r0
- 180:	09 60 f0 45 	45f06009 lshr.l \$r31,\$r0,200 <pmlabel.*>
- 184:	09 c0 0f 44 	440fc009 lshr.l \$r0,\$r31,0 <pmlabel.*>
- 188:	19 c0 0f 44 	440fc019 lshr.l \$r0,\$r31,1 <pmlabel\+0x1>
- 18c:	f9 df 0f 44 	440fdff9 lshr.l \$r0,\$r31,1ff <pmlabel\+0x1ff>
+ 180:	09 40 f0 45 	45f04009 lshr.l \$r31,\$r0,0
+ 184:	09 c0 0f 44 	440fc009 lshr.l \$r0,\$r31,0
+ 188:	09 c0 0f 44 	440fc009 lshr.l \$r0,\$r31,0
+ 18c:	09 c0 0f 44 	440fc009 lshr.l \$r0,\$r31,0
  190:	19 80 0f 42 	420f8019 lshr.s \$r0,\$r31,\$r1
- 194:	d9 c4 0f 42 	420fc4d9 lshr.s \$r0,\$r31,4d <pmlabel\+0x4d>
+ 194:	09 c0 0f 42 	420fc009 lshr.s \$r0,\$r31,0
  198:	19 80 0f 40 	400f8019 lshr.b \$r0,\$r31,\$r1
- 19c:	d9 c4 0f 40 	400fc4d9 lshr.b \$r0,\$r31,4d <pmlabel\+0x4d>
+ 19c:	09 c0 0f 40 	400fc009 lshr.b \$r0,\$r31,0
  1a0:	0a 00 f0 45 	45f0000a ashr.l \$r31,\$r0,\$r0
  1a4:	0a 80 0f 44 	440f800a ashr.l \$r0,\$r31,\$r0
  1a8:	fa 01 00 44 	440001fa ashr.l \$r0,\$r0,\$r31
  1ac:	4a 00 11 44 	4411004a ashr.l \$r1,\$r2,\$r4
  1b0:	0a 00 88 44 	4488000a ashr.l \$r8,\$r16,\$r0
- 1b4:	0a 60 f0 45 	45f0600a ashr.l \$r31,\$r0,200 <pmlabel.*>
- 1b8:	0a c0 0f 44 	440fc00a ashr.l \$r0,\$r31,0 <pmlabel.*>
- 1bc:	1a c0 0f 44 	440fc01a ashr.l \$r0,\$r31,1 <pmlabel\+0x1>
- 1c0:	fa df 0f 44 	440fdffa ashr.l \$r0,\$r31,1ff <pmlabel\+0x1ff>
+ 1b4:	0a 40 f0 45 	45f0400a ashr.l \$r31,\$r0,0
+ 1b8:	0a c0 0f 44 	440fc00a ashr.l \$r0,\$r31,0
+ 1bc:	0a c0 0f 44 	440fc00a ashr.l \$r0,\$r31,0
+ 1c0:	0a c0 0f 44 	440fc00a ashr.l \$r0,\$r31,0
  1c4:	1a 80 0f 42 	420f801a ashr.s \$r0,\$r31,\$r1
- 1c8:	da c4 0f 42 	420fc4da ashr.s \$r0,\$r31,4d <pmlabel\+0x4d>
+ 1c8:	0a c0 0f 42 	420fc00a ashr.s \$r0,\$r31,0
  1cc:	1a 80 0f 40 	400f801a ashr.b \$r0,\$r31,\$r1
- 1d0:	da c4 0f 40 	400fc4da ashr.b \$r0,\$r31,4d <pmlabel\+0x4d>
+ 1d0:	0a c0 0f 40 	400fc00a ashr.b \$r0,\$r31,0
  1d4:	01 00 f0 45 	45f00001 ror.l \$r31,\$r0,\$r0
  1d8:	01 80 0f 44 	440f8001 ror.l \$r0,\$r31,\$r0
  1dc:	f1 01 00 44 	440001f1 ror.l \$r0,\$r0,\$r31
  1e0:	41 00 11 44 	44110041 ror.l \$r1,\$r2,\$r4
  1e4:	01 00 88 44 	44880001 ror.l \$r8,\$r16,\$r0
- 1e8:	01 60 f0 45 	45f06001 ror.l \$r31,\$r0,200 <pmlabel.*>
- 1ec:	01 c0 0f 44 	440fc001 ror.l \$r0,\$r31,0 <pmlabel.*>
- 1f0:	11 c0 0f 44 	440fc011 ror.l \$r0,\$r31,1 <pmlabel\+0x1>
- 1f4:	f1 df 0f 44 	440fdff1 ror.l \$r0,\$r31,1ff <pmlabel\+0x1ff>
+ 1e8:	01 40 f0 45 	45f04001 ror.l \$r31,\$r0,0
+ 1ec:	01 c0 0f 44 	440fc001 ror.l \$r0,\$r31,0
+ 1f0:	01 c0 0f 44 	440fc001 ror.l \$r0,\$r31,0
+ 1f4:	01 c0 0f 44 	440fc001 ror.l \$r0,\$r31,0
  1f8:	11 80 0f 42 	420f8011 ror.s \$r0,\$r31,\$r1
- 1fc:	d1 c4 0f 42 	420fc4d1 ror.s \$r0,\$r31,4d <pmlabel\+0x4d>
+ 1fc:	01 c0 0f 42 	420fc001 ror.s \$r0,\$r31,0
  200:	11 80 0f 40 	400f8011 ror.b \$r0,\$r31,\$r1
- 204:	d1 c4 0f 40 	400fc4d1 ror.b \$r0,\$r31,4d <pmlabel\+0x4d>
+ 204:	01 c0 0f 40 	400fc001 ror.b \$r0,\$r31,0
  208:	03 00 f0 45 	45f00003 ldl.l \$r31,\$r0,\$r0
  20c:	03 80 0f 44 	440f8003 ldl.l \$r0,\$r31,\$r0
  210:	f3 01 00 44 	440001f3 ldl.l \$r0,\$r0,\$r31
  214:	43 00 11 44 	44110043 ldl.l \$r1,\$r2,\$r4
  218:	03 00 88 44 	44880003 ldl.l \$r8,\$r16,\$r0
- 21c:	03 60 f0 45 	45f06003 ldl.l \$r31,\$r0,200 <pmlabel.*>
- 220:	03 c0 0f 44 	440fc003 ldl.l \$r0,\$r31,0 <pmlabel.*>
- 224:	13 c0 0f 44 	440fc013 ldl.l \$r0,\$r31,1 <pmlabel\+0x1>
- 228:	f3 df 0f 44 	440fdff3 ldl.l \$r0,\$r31,1ff <pmlabel\+0x1ff>
+ 21c:	03 40 f0 45 	45f04003 ldl.l \$r31,\$r0,0
+ 220:	03 c0 0f 44 	440fc003 ldl.l \$r0,\$r31,0
+ 224:	03 c0 0f 44 	440fc003 ldl.l \$r0,\$r31,0
+ 228:	03 c0 0f 44 	440fc003 ldl.l \$r0,\$r31,0
  22c:	13 80 0f 42 	420f8013 ldl.s \$r0,\$r31,\$r1
- 230:	d3 c4 0f 42 	420fc4d3 ldl.s \$r0,\$r31,4d <pmlabel\+0x4d>
+ 230:	03 c0 0f 42 	420fc003 ldl.s \$r0,\$r31,0
  234:	13 80 0f 40 	400f8013 ldl.b \$r0,\$r31,\$r1
- 238:	d3 c4 0f 40 	400fc4d3 ldl.b \$r0,\$r31,4d <pmlabel\+0x4d>
+ 238:	03 c0 0f 40 	400fc003 ldl.b \$r0,\$r31,0
  23c:	0b 00 f0 45 	45f0000b bins.l \$r31,\$r0,\$r0
  240:	0b 80 0f 44 	440f800b bins.l \$r0,\$r31,\$r0
  244:	fb 01 00 44 	440001fb bins.l \$r0,\$r0,\$r31
  248:	4b 00 11 44 	4411004b bins.l \$r1,\$r2,\$r4
  24c:	0b 00 88 44 	4488000b bins.l \$r8,\$r16,\$r0
- 250:	0b 60 f0 45 	45f0600b bins.l \$r31,\$r0,200 <pmlabel.*>
- 254:	0b c0 0f 44 	440fc00b bins.l \$r0,\$r31,0 <pmlabel.*>
- 258:	1b c0 0f 44 	440fc01b bins.l \$r0,\$r31,1 <pmlabel\+0x1>
- 25c:	fb df 0f 44 	440fdffb bins.l \$r0,\$r31,1ff <pmlabel\+0x1ff>
+ 250:	0b 40 f0 45 	45f0400b bins.l \$r31,\$r0,0
+ 254:	0b c0 0f 44 	440fc00b bins.l \$r0,\$r31,0
+ 258:	0b c0 0f 44 	440fc00b bins.l \$r0,\$r31,0
+ 25c:	0b c0 0f 44 	440fc00b bins.l \$r0,\$r31,0
  260:	1b 80 0f 42 	420f801b bins.s \$r0,\$r31,\$r1
- 264:	db c4 0f 42 	420fc4db bins.s \$r0,\$r31,4d <pmlabel\+0x4d>
+ 264:	0b c0 0f 42 	420fc00b bins.s \$r0,\$r31,0
  268:	1b 80 0f 40 	400f801b bins.b \$r0,\$r31,\$r1
- 26c:	db c4 0f 40 	400fc4db bins.b \$r0,\$r31,4d <pmlabel\+0x4d>
+ 26c:	0b c0 0f 40 	400fc00b bins.b \$r0,\$r31,0
  270:	0c 00 f0 45 	45f0000c bexts.l \$r31,\$r0,\$r0
  274:	0c 80 0f 44 	440f800c bexts.l \$r0,\$r31,\$r0
  278:	fc 01 00 44 	440001fc bexts.l \$r0,\$r0,\$r31
  27c:	4c 00 11 44 	4411004c bexts.l \$r1,\$r2,\$r4
  280:	0c 00 88 44 	4488000c bexts.l \$r8,\$r16,\$r0
- 284:	0c 60 f0 45 	45f0600c bexts.l \$r31,\$r0,200 <pmlabel.*>
- 288:	0c c0 0f 44 	440fc00c bexts.l \$r0,\$r31,0 <pmlabel.*>
- 28c:	1c c0 0f 44 	440fc01c bexts.l \$r0,\$r31,1 <pmlabel\+0x1>
- 290:	fc df 0f 44 	440fdffc bexts.l \$r0,\$r31,1ff <pmlabel\+0x1ff>
+ 284:	0c 40 f0 45 	45f0400c bexts.l \$r31,\$r0,0
+ 288:	0c c0 0f 44 	440fc00c bexts.l \$r0,\$r31,0
+ 28c:	0c c0 0f 44 	440fc00c bexts.l \$r0,\$r31,0
+ 290:	0c c0 0f 44 	440fc00c bexts.l \$r0,\$r31,0
  294:	1c 80 0f 42 	420f801c bexts.s \$r0,\$r31,\$r1
- 298:	dc c4 0f 42 	420fc4dc bexts.s \$r0,\$r31,4d <pmlabel\+0x4d>
+ 298:	0c c0 0f 42 	420fc00c bexts.s \$r0,\$r31,0
  29c:	1c 80 0f 40 	400f801c bexts.b \$r0,\$r31,\$r1
- 2a0:	dc c4 0f 40 	400fc4dc bexts.b \$r0,\$r31,4d <pmlabel\+0x4d>
+ 2a0:	0c c0 0f 40 	400fc00c bexts.b \$r0,\$r31,0
  2a4:	0d 00 f0 45 	45f0000d bextu.l \$r31,\$r0,\$r0
  2a8:	0d 80 0f 44 	440f800d bextu.l \$r0,\$r31,\$r0
  2ac:	fd 01 00 44 	440001fd bextu.l \$r0,\$r0,\$r31
  2b0:	4d 00 11 44 	4411004d bextu.l \$r1,\$r2,\$r4
  2b4:	0d 00 88 44 	4488000d bextu.l \$r8,\$r16,\$r0
- 2b8:	0d 60 f0 45 	45f0600d bextu.l \$r31,\$r0,200 <pmlabel.*>
- 2bc:	0d c0 0f 44 	440fc00d bextu.l \$r0,\$r31,0 <pmlabel.*>
- 2c0:	1d c0 0f 44 	440fc01d bextu.l \$r0,\$r31,1 <pmlabel\+0x1>
- 2c4:	fd df 0f 44 	440fdffd bextu.l \$r0,\$r31,1ff <pmlabel\+0x1ff>
+ 2b8:	0d 40 f0 45 	45f0400d bextu.l \$r31,\$r0,0
+ 2bc:	0d c0 0f 44 	440fc00d bextu.l \$r0,\$r31,0
+ 2c0:	0d c0 0f 44 	440fc00d bextu.l \$r0,\$r31,0
+ 2c4:	0d c0 0f 44 	440fc00d bextu.l \$r0,\$r31,0
  2c8:	1d 80 0f 42 	420f801d bextu.s \$r0,\$r31,\$r1
- 2cc:	dd c4 0f 42 	420fc4dd bextu.s \$r0,\$r31,4d <pmlabel\+0x4d>
+ 2cc:	0d c0 0f 42 	420fc00d bextu.s \$r0,\$r31,0
  2d0:	1d 80 0f 40 	400f801d bextu.b \$r0,\$r31,\$r1
- 2d4:	dd c4 0f 40 	400fc4dd bextu.b \$r0,\$r31,4d <pmlabel\+0x4d>
+ 2d4:	0d c0 0f 40 	400fc00d bextu.b \$r0,\$r31,0
  2d8:	0e 00 f0 45 	45f0000e flip.l \$r31,\$r0,\$r0
  2dc:	0e 80 0f 44 	440f800e flip.l \$r0,\$r31,\$r0
  2e0:	fe 01 00 44 	440001fe flip.l \$r0,\$r0,\$r31
  2e4:	4e 00 11 44 	4411004e flip.l \$r1,\$r2,\$r4
  2e8:	0e 00 88 44 	4488000e flip.l \$r8,\$r16,\$r0
- 2ec:	0e 60 f0 45 	45f0600e flip.l \$r31,\$r0,200 <pmlabel.*>
- 2f0:	0e c0 0f 44 	440fc00e flip.l \$r0,\$r31,0 <pmlabel.*>
- 2f4:	1e c0 0f 44 	440fc01e flip.l \$r0,\$r31,1 <pmlabel\+0x1>
- 2f8:	fe df 0f 44 	440fdffe flip.l \$r0,\$r31,1ff <pmlabel\+0x1ff>
+ 2ec:	0e 40 f0 45 	45f0400e flip.l \$r31,\$r0,0
+ 2f0:	0e c0 0f 44 	440fc00e flip.l \$r0,\$r31,0
+ 2f4:	0e c0 0f 44 	440fc00e flip.l \$r0,\$r31,0
+ 2f8:	0e c0 0f 44 	440fc00e flip.l \$r0,\$r31,0
  2fc:	1e 80 0f 42 	420f801e flip.s \$r0,\$r31,\$r1
- 300:	de c4 0f 42 	420fc4de flip.s \$r0,\$r31,4d <pmlabel\+0x4d>
+ 300:	0e c0 0f 42 	420fc00e flip.s \$r0,\$r31,0
  304:	1e 80 0f 40 	400f801e flip.b \$r0,\$r31,\$r1
- 308:	de c4 0f 40 	400fc4de flip.b \$r0,\$r31,4d <pmlabel\+0x4d>
+ 308:	0e c0 0f 40 	400fc00e flip.b \$r0,\$r31,0
  30c:	00 00 e0 5d 	5de00000 addcc.l \$r0,\$r0
  310:	00 80 ef 5d 	5def8000 addcc.l \$r31,\$r0
  314:	f0 01 e0 5d 	5de001f0 addcc.l \$r0,\$r31
- 318:	00 60 e0 5d 	5de06000 addcc.l \$r0,200 <pmlabel.*>
- 31c:	00 c0 ef 5d 	5defc000 addcc.l \$r31,0 <pmlabel.*>
- 320:	10 c0 ef 5d 	5defc010 addcc.l \$r31,1 <pmlabel\+0x1>
- 324:	f0 df ef 5d 	5defdff0 addcc.l \$r31,1ff <pmlabel\+0x1ff>
+ 318:	00 40 e0 5d 	5de04000 addcc.l \$r0,0
+ 31c:	00 c0 ef 5d 	5defc000 addcc.l \$r31,0
+ 320:	00 c0 ef 5d 	5defc000 addcc.l \$r31,0
+ 324:	00 c0 ef 5d 	5defc000 addcc.l \$r31,0
  328:	10 80 ef 5b 	5bef8010 addcc.s \$r31,\$r1
- 32c:	d0 c4 ef 5b 	5befc4d0 addcc.s \$r31,4d <pmlabel\+0x4d>
+ 32c:	00 c0 ef 5b 	5befc000 addcc.s \$r31,0
  330:	10 80 ef 59 	59ef8010 addcc.b \$r31,\$r1
- 334:	d0 c4 ef 59 	59efc4d0 addcc.b \$r31,4d <pmlabel\+0x4d>
+ 334:	00 c0 ef 59 	59efc000 addcc.b \$r31,0
  338:	02 00 e0 5d 	5de00002 cmp.l \$r0,\$r0
  33c:	02 80 ef 5d 	5def8002 cmp.l \$r31,\$r0
  340:	f2 01 e0 5d 	5de001f2 cmp.l \$r0,\$r31
- 344:	02 60 e0 5d 	5de06002 cmp.l \$r0,200 <pmlabel.*>
- 348:	02 c0 ef 5d 	5defc002 cmp.l \$r31,0 <pmlabel.*>
- 34c:	12 c0 ef 5d 	5defc012 cmp.l \$r31,1 <pmlabel\+0x1>
- 350:	f2 df ef 5d 	5defdff2 cmp.l \$r31,1ff <pmlabel\+0x1ff>
+ 344:	02 40 e0 5d 	5de04002 cmp.l \$r0,0
+ 348:	02 c0 ef 5d 	5defc002 cmp.l \$r31,0
+ 34c:	02 c0 ef 5d 	5defc002 cmp.l \$r31,0
+ 350:	02 c0 ef 5d 	5defc002 cmp.l \$r31,0
  354:	12 80 ef 5b 	5bef8012 cmp.s \$r31,\$r1
- 358:	d2 c4 ef 5b 	5befc4d2 cmp.s \$r31,4d <pmlabel\+0x4d>
+ 358:	02 c0 ef 5b 	5befc002 cmp.s \$r31,0
  35c:	12 80 ef 59 	59ef8012 cmp.b \$r31,\$r1
- 360:	d2 c4 ef 59 	59efc4d2 cmp.b \$r31,4d <pmlabel\+0x4d>
+ 360:	02 c0 ef 59 	59efc002 cmp.b \$r31,0
  364:	04 00 e0 5d 	5de00004 tst.l \$r0,\$r0
  368:	04 80 ef 5d 	5def8004 tst.l \$r31,\$r0
  36c:	f4 01 e0 5d 	5de001f4 tst.l \$r0,\$r31
- 370:	04 60 e0 5d 	5de06004 tst.l \$r0,200 <pmlabel.*>
- 374:	04 c0 ef 5d 	5defc004 tst.l \$r31,0 <pmlabel.*>
- 378:	14 c0 ef 5d 	5defc014 tst.l \$r31,1 <pmlabel\+0x1>
- 37c:	f4 df ef 5d 	5defdff4 tst.l \$r31,1ff <pmlabel\+0x1ff>
+ 370:	04 40 e0 5d 	5de04004 tst.l \$r0,0
+ 374:	04 c0 ef 5d 	5defc004 tst.l \$r31,0
+ 378:	04 c0 ef 5d 	5defc004 tst.l \$r31,0
+ 37c:	04 c0 ef 5d 	5defc004 tst.l \$r31,0
  380:	14 80 ef 5b 	5bef8014 tst.s \$r31,\$r1
- 384:	d4 c4 ef 5b 	5befc4d4 tst.s \$r31,4d <pmlabel\+0x4d>
+ 384:	04 c0 ef 5b 	5befc004 tst.s \$r31,0
  388:	14 80 ef 59 	59ef8014 tst.b \$r31,\$r1
- 38c:	d4 c4 ef 59 	59efc4d4 tst.b \$r31,4d <pmlabel\+0x4d>
+ 38c:	04 c0 ef 59 	59efc004 tst.b \$r31,0
  390:	0c 00 e0 5d 	5de0000c btst.l \$r0,\$r0
  394:	0c 80 ef 5d 	5def800c btst.l \$r31,\$r0
  398:	fc 01 e0 5d 	5de001fc btst.l \$r0,\$r31
- 39c:	0c 60 e0 5d 	5de0600c btst.l \$r0,200 <pmlabel.*>
- 3a0:	0c c0 ef 5d 	5defc00c btst.l \$r31,0 <pmlabel.*>
- 3a4:	1c c0 ef 5d 	5defc01c btst.l \$r31,1 <pmlabel\+0x1>
- 3a8:	fc df ef 5d 	5defdffc btst.l \$r31,1ff <pmlabel\+0x1ff>
+ 39c:	0c 40 e0 5d 	5de0400c btst.l \$r0,0
+ 3a0:	0c c0 ef 5d 	5defc00c btst.l \$r31,0
+ 3a4:	0c c0 ef 5d 	5defc00c btst.l \$r31,0
+ 3a8:	0c c0 ef 5d 	5defc00c btst.l \$r31,0
  3ac:	1c 80 ef 5b 	5bef801c btst.s \$r31,\$r1
- 3b0:	dc c4 ef 5b 	5befc4dc btst.s \$r31,4d <pmlabel\+0x4d>
+ 3b0:	0c c0 ef 5b 	5befc00c btst.s \$r31,0
  3b4:	1c 80 ef 59 	59ef801c btst.b \$r31,\$r1
- 3b8:	dc c4 ef 59 	59efc4dc btst.b \$r31,4d <pmlabel\+0x4d>
- 3bc:	80 80 0f ac 	ac0f8080 ldi.l \$r0,\$r31,80 <pmlabel\+0x80>
- 3c0:	7f 00 f0 ad 	adf0007f ldi.l \$r31,\$r0,7f <pmlabel\+0x7f>
- 3c4:	80 80 0f aa 	aa0f8080 ldi.s \$r0,\$r31,80 <pmlabel\+0x80>
- 3c8:	7f 80 0f aa 	aa0f807f ldi.s \$r0,\$r31,7f <pmlabel\+0x7f>
- 3cc:	80 00 f0 a9 	a9f00080 ldi.b \$r31,\$r0,80 <pmlabel\+0x80>
- 3d0:	7f 00 f0 a9 	a9f0007f ldi.b \$r31,\$r0,7f <pmlabel\+0x7f>
- 3d4:	80 00 f0 b5 	b5f00080 sti.l \$r31,80 <pmlabel\+0x80>,\$r0
- 3d8:	7f 80 0f b4 	b40f807f sti.l \$r0,7f <pmlabel\+0x7f>,\$r31
- 3dc:	80 00 f0 b3 	b3f00080 sti.s \$r31,80 <pmlabel\+0x80>,\$r0
- 3e0:	7f 00 f0 b3 	b3f0007f sti.s \$r31,7f <pmlabel\+0x7f>,\$r0
- 3e4:	80 80 0f b0 	b00f8080 sti.b \$r0,80 <pmlabel\+0x80>,\$r31
- 3e8:	7f 80 0f b0 	b00f807f sti.b \$r0,7f <pmlabel\+0x7f>,\$r31
- 3ec:	80 80 0f ec 	ec0f8080 exi.l \$r0,\$r31,80 <pmlabel\+0x80>
- 3f0:	7f 00 f0 ed 	edf0007f exi.l \$r31,\$r0,7f <pmlabel\+0x7f>
- 3f4:	80 80 0f ea 	ea0f8080 exi.s \$r0,\$r31,80 <pmlabel\+0x80>
- 3f8:	7f 80 0f ea 	ea0f807f exi.s \$r0,\$r31,7f <pmlabel\+0x7f>
- 3fc:	80 00 f0 e9 	e9f00080 exi.b \$r31,\$r0,80 <pmlabel\+0x80>
- 400:	7f 00 f0 e9 	e9f0007f exi.b \$r31,\$r0,7f <pmlabel\+0x7f>
- 404:	00 00 00 6c 	6c000000 lpm.l \$r0,0 <pmlabel.*>
- 408:	00 00 00 6b 	6b000000 lpm.s \$r16,0 <pmlabel.*>
- 40c:	00 00 f0 69 	69f00000 lpm.b \$r31,0 <pmlabel.*>
- 410:	80 80 00 cc 	cc008080 lpmi.l \$r0,\$r1,80 <pmlabel\+0x80>
- 414:	7f 80 00 cb 	cb00807f lpmi.s \$r16,\$r1,7f <pmlabel\+0x7f>
- 418:	80 80 f0 c9 	c9f08080 lpmi.b \$r31,\$r1,80 <pmlabel\+0x80>
- 41c:	00 00 30 00 	00300000 jmp 0 <pmlabel.*>
+ 3b8:	0c c0 ef 59 	59efc00c btst.b \$r31,0
+ 3bc:	00 80 0f ac 	ac0f8000 ldi.l \$r0,\$r31,0
+ 3c0:	00 00 f0 ad 	adf00000 ldi.l \$r31,\$r0,0
+ 3c4:	00 80 0f aa 	aa0f8000 ldi.s \$r0,\$r31,0
+ 3c8:	00 80 0f aa 	aa0f8000 ldi.s \$r0,\$r31,0
+ 3cc:	00 00 f0 a9 	a9f00000 ldi.b \$r31,\$r0,0
+ 3d0:	00 00 f0 a9 	a9f00000 ldi.b \$r31,\$r0,0
+ 3d4:	00 00 f0 b5 	b5f00000 sti.l \$r31,0,\$r0
+ 3d8:	00 80 0f b4 	b40f8000 sti.l \$r0,0,\$r31
+ 3dc:	00 00 f0 b3 	b3f00000 sti.s \$r31,0,\$r0
+ 3e0:	00 00 f0 b3 	b3f00000 sti.s \$r31,0,\$r0
+ 3e4:	00 80 0f b0 	b00f8000 sti.b \$r0,0,\$r31
+ 3e8:	00 80 0f b0 	b00f8000 sti.b \$r0,0,\$r31
+ 3ec:	00 80 0f ec 	ec0f8000 exi.l \$r0,\$r31,0
+ 3f0:	00 00 f0 ed 	edf00000 exi.l \$r31,\$r0,0
+ 3f4:	00 80 0f ea 	ea0f8000 exi.s \$r0,\$r31,0
+ 3f8:	00 80 0f ea 	ea0f8000 exi.s \$r0,\$r31,0
+ 3fc:	00 00 f0 e9 	e9f00000 exi.b \$r31,\$r0,0
+ 400:	00 00 f0 e9 	e9f00000 exi.b \$r31,\$r0,0
+ 404:	00 00 00 6c 	6c000000 lpm.l \$r0,0 <pmlabel>
+ 408:	00 00 00 6b 	6b000000 lpm.s \$r16,0 <pmlabel>
+ 40c:	00 00 f0 69 	69f00000 lpm.b \$r31,0 <pmlabel>
+ 410:	00 80 00 cc 	cc008000 lpmi.l \$r0,\$r1,0
+ 414:	00 80 00 cb 	cb008000 lpmi.s \$r16,\$r1,0
+ 418:	00 80 f0 c9 	c9f08000 lpmi.b \$r31,\$r1,0
+ 41c:	00 00 30 00 	00300000 jmp 0 <pmlabel>
  420:	00 01 30 08 	08300100 jmpi \$r16
- 424:	00 00 c8 07 	07c80000 jmpx 31,\$r28,1,0 <pmlabel.*>
- 428:	00 00 20 00 	00200000 jmpc nz,0 <pmlabel.*>
- 42c:	00 00 34 00 	00340000 call 0 <pmlabel.*>
+ 424:	00 00 c8 07 	07c80000 jmpx 31,\$r28,1,0 <pmlabel>
+ 428:	00 00 20 00 	00200000 jmpc nz,0 <pmlabel>
+ 42c:	00 00 34 00 	00340000 call 0 <pmlabel>
  430:	00 01 34 08 	08340100 calli \$r16
- 434:	00 00 cc 07 	07cc0000 callx 31,\$r28,1,0 <pmlabel.*>
- 438:	00 00 24 00 	00240000 callc nz,0 <pmlabel.*>
+ 434:	00 00 cc 07 	07cc0000 callx 31,\$r28,1,0 <pmlabel>
+ 438:	00 00 24 00 	00240000 callc nz,0 <pmlabel>
  43c:	00 00 00 84 	84000000 push.l \$r0
  440:	00 00 08 84 	84080000 push.l \$r16
  444:	00 80 0f 84 	840f8000 push.l \$r31
  448:	00 00 00 8c 	8c000000 pop.l \$r0
  44c:	00 00 00 8d 	8d000000 pop.l \$r16
  450:	00 00 f0 8d 	8df00000 pop.l \$r31
- 454:	00 00 00 94 	94000000 link \$r0,0 <pmlabel.*>
- 458:	ff ff 00 95 	9500ffff link \$r16,ffff <pmlabel\+0xffff>
- 45c:	f9 03 f0 95 	95f003f9 link \$r31,3f9 <pmlabel\+0x3f9>
+ 454:	00 00 00 94 	94000000 link \$r0,0
+ 458:	00 00 00 95 	95000000 link \$r16,0
+ 45c:	00 00 f0 95 	95f00000 link \$r31,0
  460:	00 00 00 98 	98000000 unlink \$r0
  464:	00 00 00 99 	99000000 unlink \$r16
  468:	00 00 f0 99 	99f00000 unlink \$r31
  46c:	00 00 00 a0 	a0000000 return 
  470:	00 00 00 a4 	a4000000 reti 
- 474:	00 00 00 c4 	c4000000 lda.l \$r0,0 <pmlabel.*>
- 478:	00 00 00 c3 	c3000000 lda.s \$r16,0 <pmlabel.*>
- 47c:	00 00 f0 c1 	c1f00000 lda.b \$r31,0 <pmlabel.*>
- 480:	00 00 00 bc 	bc000000 sta.l 0 <pmlabel.*>,\$r0
- 484:	00 00 00 bb 	bb000000 sta.s 0 <pmlabel.*>,\$r16
- 488:	00 00 f0 b9 	b9f00000 sta.b 0 <pmlabel.*>,\$r31
- 48c:	00 00 00 3c 	3c000000 exa.l \$r0,0 <pmlabel.*>
- 490:	00 00 00 3b 	3b000000 exa.s \$r16,0 <pmlabel.*>
- 494:	00 00 f0 39 	39f00000 exa.b \$r31,0 <pmlabel.*>
- 498:	00 00 08 64 	64080000 ldk.l \$r0,80000 <pmlabel\+0x80000>
- 49c:	ff ff 07 64 	6407ffff ldk.l \$r0,7ffff <pmlabel\+0x7ffff>
- 4a0:	00 00 00 64 	64000000 ldk.l \$r0,0 <pmlabel.*>
+ 474:	00 00 00 c4 	c4000000 lda.l \$r0,800000 <pmlabel\+0x800000>
+ 478:	00 00 00 c3 	c3000000 lda.s \$r16,800000 <pmlabel\+0x800000>
+ 47c:	00 00 f0 c1 	c1f00000 lda.b \$r31,800000 <pmlabel\+0x800000>
+ 480:	00 00 00 bc 	bc000000 sta.l 800000 <pmlabel\+0x800000>,\$r0
+ 484:	00 00 00 bb 	bb000000 sta.s 800000 <pmlabel\+0x800000>,\$r16
+ 488:	00 00 f0 b9 	b9f00000 sta.b 800000 <pmlabel\+0x800000>,\$r31
+ 48c:	00 00 00 3c 	3c000000 exa.l \$r0,800000 <pmlabel\+0x800000>
+ 490:	00 00 00 3b 	3b000000 exa.s \$r16,800000 <pmlabel\+0x800000>
+ 494:	00 00 f0 39 	39f00000 exa.b \$r31,800000 <pmlabel\+0x800000>
+ 498:	00 00 00 64 	64000000 ldk.l \$r0,0
+ 49c:	00 00 00 64 	64000000 ldk.l \$r0,0
+ 4a0:	00 00 00 64 	64000000 ldk.l \$r0,0
  4a4:	00 c0 0f 44 	440fc000 move.l \$r0,\$r31
  4a8:	00 40 f0 45 	45f04000 move.l \$r31,\$r0
  4ac:	00 00 f0 f5 	f5f00000 udiv.l \$r31,\$r0,\$r0
@@ -312,170 +312,170 @@ Disassembly of section .text:
  4b4:	f0 01 00 f4 	f40001f0 udiv.l \$r0,\$r0,\$r31
  4b8:	40 00 11 f4 	f4110040 udiv.l \$r1,\$r2,\$r4
  4bc:	00 00 88 f4 	f4880000 udiv.l \$r8,\$r16,\$r0
- 4c0:	00 60 f0 f5 	f5f06000 udiv.l \$r31,\$r0,200 <pmlabel.*>
- 4c4:	00 c0 0f f4 	f40fc000 udiv.l \$r0,\$r31,0 <pmlabel.*>
- 4c8:	10 c0 0f f4 	f40fc010 udiv.l \$r0,\$r31,1 <pmlabel\+0x1>
- 4cc:	f0 df 0f f4 	f40fdff0 udiv.l \$r0,\$r31,1ff <pmlabel\+0x1ff>
+ 4c0:	00 40 f0 f5 	f5f04000 udiv.l \$r31,\$r0,0
+ 4c4:	00 c0 0f f4 	f40fc000 udiv.l \$r0,\$r31,0
+ 4c8:	00 c0 0f f4 	f40fc000 udiv.l \$r0,\$r31,0
+ 4cc:	00 c0 0f f4 	f40fc000 udiv.l \$r0,\$r31,0
  4d0:	10 80 0f f2 	f20f8010 udiv.s \$r0,\$r31,\$r1
- 4d4:	d0 c4 0f f2 	f20fc4d0 udiv.s \$r0,\$r31,4d <pmlabel\+0x4d>
+ 4d4:	00 c0 0f f2 	f20fc000 udiv.s \$r0,\$r31,0
  4d8:	10 80 0f f0 	f00f8010 udiv.b \$r0,\$r31,\$r1
- 4dc:	d0 c4 0f f0 	f00fc4d0 udiv.b \$r0,\$r31,4d <pmlabel\+0x4d>
+ 4dc:	00 c0 0f f0 	f00fc000 udiv.b \$r0,\$r31,0
  4e0:	01 00 f0 f5 	f5f00001 umod.l \$r31,\$r0,\$r0
  4e4:	01 80 0f f4 	f40f8001 umod.l \$r0,\$r31,\$r0
  4e8:	f1 01 00 f4 	f40001f1 umod.l \$r0,\$r0,\$r31
  4ec:	41 00 11 f4 	f4110041 umod.l \$r1,\$r2,\$r4
  4f0:	01 00 88 f4 	f4880001 umod.l \$r8,\$r16,\$r0
- 4f4:	01 60 f0 f5 	f5f06001 umod.l \$r31,\$r0,200 <pmlabel.*>
- 4f8:	01 c0 0f f4 	f40fc001 umod.l \$r0,\$r31,0 <pmlabel.*>
- 4fc:	11 c0 0f f4 	f40fc011 umod.l \$r0,\$r31,1 <pmlabel\+0x1>
- 500:	f1 df 0f f4 	f40fdff1 umod.l \$r0,\$r31,1ff <pmlabel\+0x1ff>
+ 4f4:	01 40 f0 f5 	f5f04001 umod.l \$r31,\$r0,0
+ 4f8:	01 c0 0f f4 	f40fc001 umod.l \$r0,\$r31,0
+ 4fc:	01 c0 0f f4 	f40fc001 umod.l \$r0,\$r31,0
+ 500:	01 c0 0f f4 	f40fc001 umod.l \$r0,\$r31,0
  504:	11 80 0f f2 	f20f8011 umod.s \$r0,\$r31,\$r1
- 508:	d1 c4 0f f2 	f20fc4d1 umod.s \$r0,\$r31,4d <pmlabel\+0x4d>
+ 508:	01 c0 0f f2 	f20fc001 umod.s \$r0,\$r31,0
  50c:	11 80 0f f0 	f00f8011 umod.b \$r0,\$r31,\$r1
- 510:	d1 c4 0f f0 	f00fc4d1 umod.b \$r0,\$r31,4d <pmlabel\+0x4d>
+ 510:	01 c0 0f f0 	f00fc001 umod.b \$r0,\$r31,0
  514:	02 00 f0 f5 	f5f00002 div.l \$r31,\$r0,\$r0
  518:	02 80 0f f4 	f40f8002 div.l \$r0,\$r31,\$r0
  51c:	f2 01 00 f4 	f40001f2 div.l \$r0,\$r0,\$r31
  520:	42 00 11 f4 	f4110042 div.l \$r1,\$r2,\$r4
  524:	02 00 88 f4 	f4880002 div.l \$r8,\$r16,\$r0
- 528:	02 60 f0 f5 	f5f06002 div.l \$r31,\$r0,200 <pmlabel.*>
- 52c:	02 c0 0f f4 	f40fc002 div.l \$r0,\$r31,0 <pmlabel.*>
- 530:	12 c0 0f f4 	f40fc012 div.l \$r0,\$r31,1 <pmlabel\+0x1>
- 534:	f2 df 0f f4 	f40fdff2 div.l \$r0,\$r31,1ff <pmlabel\+0x1ff>
+ 528:	02 40 f0 f5 	f5f04002 div.l \$r31,\$r0,0
+ 52c:	02 c0 0f f4 	f40fc002 div.l \$r0,\$r31,0
+ 530:	02 c0 0f f4 	f40fc002 div.l \$r0,\$r31,0
+ 534:	02 c0 0f f4 	f40fc002 div.l \$r0,\$r31,0
  538:	12 80 0f f2 	f20f8012 div.s \$r0,\$r31,\$r1
- 53c:	d2 c4 0f f2 	f20fc4d2 div.s \$r0,\$r31,4d <pmlabel\+0x4d>
+ 53c:	02 c0 0f f2 	f20fc002 div.s \$r0,\$r31,0
  540:	12 80 0f f0 	f00f8012 div.b \$r0,\$r31,\$r1
- 544:	d2 c4 0f f0 	f00fc4d2 div.b \$r0,\$r31,4d <pmlabel\+0x4d>
+ 544:	02 c0 0f f0 	f00fc002 div.b \$r0,\$r31,0
  548:	03 00 f0 f5 	f5f00003 mod.l \$r31,\$r0,\$r0
  54c:	03 80 0f f4 	f40f8003 mod.l \$r0,\$r31,\$r0
  550:	f3 01 00 f4 	f40001f3 mod.l \$r0,\$r0,\$r31
  554:	43 00 11 f4 	f4110043 mod.l \$r1,\$r2,\$r4
  558:	03 00 88 f4 	f4880003 mod.l \$r8,\$r16,\$r0
- 55c:	03 60 f0 f5 	f5f06003 mod.l \$r31,\$r0,200 <pmlabel.*>
- 560:	03 c0 0f f4 	f40fc003 mod.l \$r0,\$r31,0 <pmlabel.*>
- 564:	13 c0 0f f4 	f40fc013 mod.l \$r0,\$r31,1 <pmlabel\+0x1>
- 568:	f3 df 0f f4 	f40fdff3 mod.l \$r0,\$r31,1ff <pmlabel\+0x1ff>
+ 55c:	03 40 f0 f5 	f5f04003 mod.l \$r31,\$r0,0
+ 560:	03 c0 0f f4 	f40fc003 mod.l \$r0,\$r31,0
+ 564:	03 c0 0f f4 	f40fc003 mod.l \$r0,\$r31,0
+ 568:	03 c0 0f f4 	f40fc003 mod.l \$r0,\$r31,0
  56c:	13 80 0f f2 	f20f8013 mod.s \$r0,\$r31,\$r1
- 570:	d3 c4 0f f2 	f20fc4d3 mod.s \$r0,\$r31,4d <pmlabel\+0x4d>
+ 570:	03 c0 0f f2 	f20fc003 mod.s \$r0,\$r31,0
  574:	13 80 0f f0 	f00f8013 mod.b \$r0,\$r31,\$r1
- 578:	d3 c4 0f f0 	f00fc4d3 mod.b \$r0,\$r31,4d <pmlabel\+0x4d>
+ 578:	03 c0 0f f0 	f00fc003 mod.b \$r0,\$r31,0
  57c:	04 00 f0 f5 	f5f00004 strcmp.l \$r31,\$r0,\$r0
  580:	04 80 0f f4 	f40f8004 strcmp.l \$r0,\$r31,\$r0
  584:	f4 01 00 f4 	f40001f4 strcmp.l \$r0,\$r0,\$r31
  588:	44 00 11 f4 	f4110044 strcmp.l \$r1,\$r2,\$r4
  58c:	04 00 88 f4 	f4880004 strcmp.l \$r8,\$r16,\$r0
- 590:	04 60 f0 f5 	f5f06004 strcmp.l \$r31,\$r0,200 <pmlabel.*>
- 594:	04 c0 0f f4 	f40fc004 strcmp.l \$r0,\$r31,0 <pmlabel.*>
- 598:	14 c0 0f f4 	f40fc014 strcmp.l \$r0,\$r31,1 <pmlabel\+0x1>
- 59c:	f4 df 0f f4 	f40fdff4 strcmp.l \$r0,\$r31,1ff <pmlabel\+0x1ff>
+ 590:	04 40 f0 f5 	f5f04004 strcmp.l \$r31,\$r0,0
+ 594:	04 c0 0f f4 	f40fc004 strcmp.l \$r0,\$r31,0
+ 598:	04 c0 0f f4 	f40fc004 strcmp.l \$r0,\$r31,0
+ 59c:	04 c0 0f f4 	f40fc004 strcmp.l \$r0,\$r31,0
  5a0:	14 80 0f f2 	f20f8014 strcmp.s \$r0,\$r31,\$r1
- 5a4:	d4 c4 0f f2 	f20fc4d4 strcmp.s \$r0,\$r31,4d <pmlabel\+0x4d>
+ 5a4:	04 c0 0f f2 	f20fc004 strcmp.s \$r0,\$r31,0
  5a8:	14 80 0f f0 	f00f8014 strcmp.b \$r0,\$r31,\$r1
- 5ac:	d4 c4 0f f0 	f00fc4d4 strcmp.b \$r0,\$r31,4d <pmlabel\+0x4d>
+ 5ac:	04 c0 0f f0 	f00fc004 strcmp.b \$r0,\$r31,0
  5b0:	05 00 f0 f5 	f5f00005 memcpy.l \$r31,\$r0,\$r0
  5b4:	05 80 0f f4 	f40f8005 memcpy.l \$r0,\$r31,\$r0
  5b8:	f5 01 00 f4 	f40001f5 memcpy.l \$r0,\$r0,\$r31
  5bc:	45 00 11 f4 	f4110045 memcpy.l \$r1,\$r2,\$r4
  5c0:	05 00 88 f4 	f4880005 memcpy.l \$r8,\$r16,\$r0
- 5c4:	05 60 f0 f5 	f5f06005 memcpy.l \$r31,\$r0,200 <pmlabel.*>
- 5c8:	05 c0 0f f4 	f40fc005 memcpy.l \$r0,\$r31,0 <pmlabel.*>
- 5cc:	15 c0 0f f4 	f40fc015 memcpy.l \$r0,\$r31,1 <pmlabel\+0x1>
- 5d0:	f5 df 0f f4 	f40fdff5 memcpy.l \$r0,\$r31,1ff <pmlabel\+0x1ff>
+ 5c4:	05 40 f0 f5 	f5f04005 memcpy.l \$r31,\$r0,0
+ 5c8:	05 c0 0f f4 	f40fc005 memcpy.l \$r0,\$r31,0
+ 5cc:	05 c0 0f f4 	f40fc005 memcpy.l \$r0,\$r31,0
+ 5d0:	05 c0 0f f4 	f40fc005 memcpy.l \$r0,\$r31,0
  5d4:	15 80 0f f2 	f20f8015 memcpy.s \$r0,\$r31,\$r1
- 5d8:	d5 c4 0f f2 	f20fc4d5 memcpy.s \$r0,\$r31,4d <pmlabel\+0x4d>
+ [...]

[diff truncated at 100000 bytes]


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]