This is the mail archive of the binutils@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]

RE: [PATCH, FT32] initial support (2nd attempt)


OK, thanks for the review Alan. I have reworked the patch, all fixes made, and added a gas testsuite for FT32 that checks all opcodes.
The updated patch is below.

This patch adds FT32 support to binutils. Please can someone review it, and if appropriate
commit it, as I do not have write access to the tree.

The FSF have acknowledged receipt of FTDI's copyright assignment papers.

Thanks very much.

--
James Bowman
FTDI Open Source Liaison

From: James Bowman <james.bowman@ftdichip.com>
Date: Mon, 5 Jan 2015 11:59:47 -0800
Subject: [PATCH] FT32 initial support

---
 bfd/Makefile.am                 |    4 +
 bfd/Makefile.in                 |    5 +
 bfd/archures.c                  |    4 +
 bfd/bfd-in2.h                   |    9 +
 bfd/config.bfd                  |    4 +
 bfd/configure                   |    1 +
 bfd/configure.ac                |    1 +
 bfd/cpu-ft32.c                  |   41 +++
 bfd/elf32-ft32.c                |  380 +++++++++++++++++++++++
 bfd/libbfd.h                    |    5 +
 bfd/reloc.c                     |   12 +
 bfd/targets.c                   |    3 +
 binutils/readelf.c              |   10 +
 configure                       |    6 +
 configure.ac                    |    6 +
 gas/Makefile.am                 |    2 +
 gas/Makefile.in                 |   10 +
 gas/config/tc-ft32.c            |  636 +++++++++++++++++++++++++++++++++++++++
 gas/config/tc-ft32.h            |   55 ++++
 gas/configure.tgt               |    2 +
 gas/testsuite/gas/ft32/ft32.exp |   21 ++
 gas/testsuite/gas/ft32/insn.d   |  490 ++++++++++++++++++++++++++++++
 gas/testsuite/gas/ft32/insn.s   |  185 ++++++++++++
 gas/testsuite/go                |    7 +
 include/dis-asm.h               |    1 +
 include/elf/common.h            |    2 +
 include/elf/ft32.h              |   37 +++
 include/opcode/ft32.h           |  100 ++++++
 ld/Makefile.am                  |    4 +
 ld/Makefile.in                  |    5 +
 ld/configure.tgt                |    2 +
 ld/emulparams/elf32ft32.sh      |    8 +
 ld/scripttempl/ft32.sc          |   62 ++++
 opcodes/Makefile.am             |    2 +
 opcodes/Makefile.in             |    4 +
 opcodes/configure               |    1 +
 opcodes/configure.ac            |    1 +
 opcodes/disassemble.c           |    6 +
 opcodes/ft32-dis.c              |  177 +++++++++++
 opcodes/ft32-opc.c              |   88 ++++++
 40 files changed, 2399 insertions(+)
 create mode 100644 bfd/cpu-ft32.c
 create mode 100644 bfd/elf32-ft32.c
 create mode 100644 gas/config/tc-ft32.c
 create mode 100644 gas/config/tc-ft32.h
 create mode 100644 gas/testsuite/gas/ft32/ft32.exp
 create mode 100644 gas/testsuite/gas/ft32/insn.d
 create mode 100644 gas/testsuite/gas/ft32/insn.s
 create mode 100644 gas/testsuite/go
 create mode 100644 include/elf/ft32.h
 create mode 100644 include/opcode/ft32.h
 create mode 100644 ld/emulparams/elf32ft32.sh
 create mode 100644 ld/scripttempl/ft32.sc
 create mode 100644 opcodes/ft32-dis.c
 create mode 100644 opcodes/ft32-opc.c

diff --git a/bfd/Makefile.am b/bfd/Makefile.am
index 8ffdbb1..5d7f899 100644
--- a/bfd/Makefile.am
+++ b/bfd/Makefile.am
@@ -99,6 +99,7 @@ ALL_MACHINES = \
 	cpu-epiphany.lo \
 	cpu-fr30.lo \
 	cpu-frv.lo \
+	cpu-ft32.lo \
 	cpu-h8300.lo \
 	cpu-h8500.lo \
 	cpu-hppa.lo \
@@ -184,6 +185,7 @@ ALL_MACHINES_CFILES = \
 	cpu-epiphany.c \
 	cpu-fr30.c \
 	cpu-frv.c \
+	cpu-ft32.c \
 	cpu-h8300.c \
 	cpu-h8500.c \
 	cpu-hppa.c \
@@ -323,6 +325,7 @@ BFD32_BACKENDS = \
 	elf32-epiphany.lo \
 	elf32-fr30.lo \
 	elf32-frv.lo \
+	elf32-ft32.lo \
 	elf32-gen.lo \
 	elf32-h8300.lo \
 	elf32-hppa.lo \
@@ -513,6 +516,7 @@ BFD32_BACKENDS_CFILES = \
 	elf32-epiphany.c \
 	elf32-fr30.c \
 	elf32-frv.c \
+	elf32-ft32.c \
 	elf32-gen.c \
 	elf32-h8300.c \
 	elf32-hppa.c \
diff --git a/bfd/Makefile.in b/bfd/Makefile.in
index 2c9435c..af55123 100644
--- a/bfd/Makefile.in
+++ b/bfd/Makefile.in
@@ -399,6 +399,7 @@ ALL_MACHINES = \
 	cpu-epiphany.lo \
 	cpu-fr30.lo \
 	cpu-frv.lo \
+	cpu-ft32.lo \
 	cpu-h8300.lo \
 	cpu-h8500.lo \
 	cpu-hppa.lo \
@@ -484,6 +485,7 @@ ALL_MACHINES_CFILES = \
 	cpu-epiphany.c \
 	cpu-fr30.c \
 	cpu-frv.c \
+	cpu-ft32.c \
 	cpu-h8300.c \
 	cpu-h8500.c \
 	cpu-hppa.c \
@@ -624,6 +626,7 @@ BFD32_BACKENDS = \
 	elf32-epiphany.lo \
 	elf32-fr30.lo \
 	elf32-frv.lo \
+	elf32-ft32.lo \
 	elf32-gen.lo \
 	elf32-h8300.lo \
 	elf32-hppa.lo \
@@ -814,6 +817,7 @@ BFD32_BACKENDS_CFILES = \
 	elf32-epiphany.c \
 	elf32-fr30.c \
 	elf32-frv.c \
+	elf32-ft32.c \
 	elf32-gen.c \
 	elf32-h8300.c \
 	elf32-hppa.c \
@@ -1319,6 +1323,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-epiphany.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-fr30.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-frv.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-ft32.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-h8300.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-h8500.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-hppa.Plo@am__quote@
diff --git a/bfd/archures.c b/bfd/archures.c
index ca20fb2..7a12985 100644
--- a/bfd/archures.c
+++ b/bfd/archures.c
@@ -378,6 +378,8 @@ DESCRIPTION
 .#define bfd_mach_fr550		550
 .  bfd_arch_moxie,       {* The moxie processor *}
 .#define bfd_mach_moxie		1
+.  bfd_arch_ft32,       {* The ft32 processor *}
+.#define bfd_mach_ft32		1
 .  bfd_arch_mcore,
 .  bfd_arch_mep,
 .#define bfd_mach_mep		1
@@ -589,6 +591,7 @@ extern const bfd_arch_info_type bfd_mmix_arch;
 extern const bfd_arch_info_type bfd_mn10200_arch;
 extern const bfd_arch_info_type bfd_mn10300_arch;
 extern const bfd_arch_info_type bfd_moxie_arch;
+extern const bfd_arch_info_type bfd_ft32_arch;
 extern const bfd_arch_info_type bfd_msp430_arch;
 extern const bfd_arch_info_type bfd_mt_arch;
 extern const bfd_arch_info_type bfd_nds32_arch;
@@ -679,6 +682,7 @@ static const bfd_arch_info_type * const bfd_archures_list[] =
     &bfd_mn10200_arch,
     &bfd_mn10300_arch,
     &bfd_moxie_arch,
+    &bfd_ft32_arch,
     &bfd_msp430_arch,
     &bfd_mt_arch,
     &bfd_nds32_arch,
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index b718f10..2a8dbfc 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -2139,6 +2139,8 @@ enum bfd_architecture
 #define bfd_mach_fr550         550
   bfd_arch_moxie,       /* The moxie processor */
 #define bfd_mach_moxie         1
+  bfd_arch_ft32,       /* The ft32 processor */
+#define bfd_mach_ft32            1
   bfd_arch_mcore,
   bfd_arch_mep,
 #define bfd_mach_mep           1
@@ -3002,6 +3004,13 @@ to compensate for the borrow when the low bits are added.  */
   BFD_RELOC_MOXIE_10_PCREL,
 
 
+/* FT32 ELF relocations.  */
+  BFD_RELOC_FT32_10,
+  BFD_RELOC_FT32_20,
+  BFD_RELOC_FT32_17,
+  BFD_RELOC_FT32_18,
+
+
 /* Fujitsu Frv Relocations.  */
   BFD_RELOC_FRV_LABEL16,
   BFD_RELOC_FRV_LABEL24,
diff --git a/bfd/config.bfd b/bfd/config.bfd
index 75f21e3..62f8ee4 100644
--- a/bfd/config.bfd
+++ b/bfd/config.bfd
@@ -1628,6 +1628,10 @@ case "${targ}" in
     targ_defvec=tilepro_elf32_vec
     ;;
 
+  ft32*-*-*)
+    targ_defvec=ft32_elf32_vec
+    ;;
+
   v850*-*-*)
     targ_defvec=v850_elf32_vec
     targ_selvecs="v800_elf32_vec"
diff --git a/bfd/configure b/bfd/configure
index f7a9e81..1fc7991 100755
--- a/bfd/configure
+++ b/bfd/configure
@@ -15598,6 +15598,7 @@ do
     vax_aout_bsd_vec)		 tb="$tb vaxbsd.lo aout32.lo" ;;
     vax_aout_nbsd_vec)		 tb="$tb vaxnetbsd.lo aout32.lo" ;;
     vax_elf32_vec)		 tb="$tb elf32-vax.lo elf32.lo $elf" ;;
+    ft32_elf32_vec)		 tb="$tb elf32-ft32.lo elf32.lo $elf" ;;
     visium_elf32_vec)		 tb="$tb elf32-visium.lo elf32.lo $elf" ;;
     w65_coff_vec)		 tb="$tb coff-w65.lo reloc16.lo $coffgen" ;;
     we32k_coff_vec)		 tb="$tb coff-we32k.lo $coffgen" ;;
diff --git a/bfd/configure.ac b/bfd/configure.ac
index a2743a0..337a23f 100644
--- a/bfd/configure.ac
+++ b/bfd/configure.ac
@@ -999,6 +999,7 @@ do
     vax_aout_bsd_vec)		 tb="$tb vaxbsd.lo aout32.lo" ;;
     vax_aout_nbsd_vec)		 tb="$tb vaxnetbsd.lo aout32.lo" ;;
     vax_elf32_vec)		 tb="$tb elf32-vax.lo elf32.lo $elf" ;;
+    ft32_elf32_vec)		 tb="$tb elf32-ft32.lo elf32.lo $elf" ;;
     visium_elf32_vec)		 tb="$tb elf32-visium.lo elf32.lo $elf" ;;
     w65_coff_vec)		 tb="$tb coff-w65.lo reloc16.lo $coffgen" ;;
     we32k_coff_vec)		 tb="$tb coff-we32k.lo $coffgen" ;;
diff --git a/bfd/cpu-ft32.c b/bfd/cpu-ft32.c
new file mode 100644
index 0000000..ab05fa9
--- /dev/null
+++ b/bfd/cpu-ft32.c
@@ -0,0 +1,41 @@
+/* BFD support for the ft32 processor.
+   Copyright 2013 Free Software Foundation, Inc.
+   Written by FTDI (support@ftdichip.com)
+
+   This file is part of BFD, the Binary File Descriptor library.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+
+const bfd_arch_info_type bfd_ft32_arch =
+  {
+    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.  */
+    TRUE,             /* The one and only.  */
+    bfd_default_compatible,
+    bfd_default_scan,
+    bfd_arch_default_fill,
+    0,
+  };
diff --git a/bfd/elf32-ft32.c b/bfd/elf32-ft32.c
new file mode 100644
index 0000000..a5b7c4f
--- /dev/null
+++ b/bfd/elf32-ft32.c
@@ -0,0 +1,380 @@
+/* ft32-specific support for 32-bit ELF.
+   Copyright 2013 Free Software Foundation, Inc.
+
+   Copied from elf32-moxie.c which is..
+   Copyright 2009, 2010, 2012 Free Software Foundation, Inc.
+   Free Software Foundation, Inc.
+
+   This file is part of BFD, the Binary File Descriptor library.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/ft32.h"
+
+/* Forward declarations.  */
+
+static reloc_howto_type ft32_elf_howto_table [] =
+{
+  /* This reloc does nothing.  */
+  HOWTO (R_FT32_NONE,		/* type */
+	 0,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 32,			/* bitsize */
+	 FALSE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_bitfield, /* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* special_function */
+	 "R_FT32_NONE",		/* name */
+	 FALSE,			/* partial_inplace */
+	 0,			/* src_mask */
+	 0,			/* dst_mask */
+	 FALSE),		/* pcrel_offset */
+
+  /* A 32 bit absolute relocation.  */
+
+  HOWTO (R_FT32_32,		/* type */
+	 0,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 32,			/* bitsize */
+	 FALSE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_bitfield, /* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* special_function */
+	 "R_FT32_32",		/* name */
+	 FALSE,			/* partial_inplace */
+	 0x00000000,		/* src_mask */
+	 0x000fffff,		/* dst_mask */
+	 FALSE),		/* pcrel_offset */
+
+  HOWTO (R_FT32_16,		/* type */
+	 0,			/* rightshift */
+	 1,			/* size (0 = byte, 1 = short, 2 = long) */
+	 16,			/* bitsize */
+	 FALSE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_bitfield, /* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* special_function */
+	 "R_FT32_16",		/* name */
+	 FALSE,			/* partial_inplace */
+	 0x00000000,		/* src_mask */
+	 0x0000ffff,		/* dst_mask */
+	 FALSE),		/* pcrel_offset */
+
+  HOWTO (R_FT32_8,		/* type */
+	 0,			/* rightshift */
+	 0,			/* size (0 = byte, 1 = short, 2 = long) */
+	 8,			/* bitsize */
+	 FALSE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_signed, /* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* special_function */
+	 "R_FT32_8",		/* name */
+	 FALSE,			/* partial_inplace */
+	 0x00000000,		/* src_mask */
+	 0x000000ff,		/* dst_mask */
+	 FALSE),		/* pcrel_offset */
+
+  HOWTO (R_FT32_10,		/* 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_10",		/* name */
+	 FALSE,			/* partial_inplace */
+	 0x00000000,		/* src_mask */
+	 0x00003ff0,		/* dst_mask */
+	 FALSE),		/* pcrel_offset */
+
+  HOWTO (R_FT32_20,		/* type */
+	 0,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 20,			/* bitsize */
+	 FALSE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_dont, /* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* special_function */
+	 "R_FT32_20",		/* name */
+	 FALSE,			/* partial_inplace */
+	 0x00000000,		/* src_mask */
+	 0x000fffff,		/* dst_mask */
+	 FALSE),		/* pcrel_offset */
+
+  HOWTO (R_FT32_17,		/* type */
+	 0,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 17,			/* bitsize */
+	 FALSE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_dont, /* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* special_function */
+	 "R_FT32_17",		/* name */
+	 FALSE,			/* partial_inplace */
+	 0x00000000,		/* src_mask */
+	 0x0001ffff,		/* dst_mask */
+	 FALSE),		/* pcrel_offset */
+
+  HOWTO (R_FT32_18,		/* type */
+	 2,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 18,			/* bitsize */
+	 FALSE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_signed, /* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* special_function */
+	 "R_FT32_18",		/* name */
+	 FALSE,		/* partial_inplace */
+	 0x00000000,		/* src_mask */
+	 0x0003ffff,		/* dst_mask */
+	 FALSE),		/* pcrel_offset */
+
+};
+
+/* Map BFD reloc types to FT32 ELF reloc types.  */
+
+struct ft32_reloc_map
+{
+  bfd_reloc_code_real_type bfd_reloc_val;
+  unsigned int ft32_reloc_val;
+};
+
+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 },
+};
+
+static reloc_howto_type *
+ft32_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+			 bfd_reloc_code_real_type code)
+{
+  unsigned int i;
+
+  for (i = sizeof (ft32_reloc_map) / sizeof (ft32_reloc_map[0]);
+       --i;)
+    if (ft32_reloc_map [i].bfd_reloc_val == code)
+      return & ft32_elf_howto_table [ft32_reloc_map[i].ft32_reloc_val];
+
+  return NULL;
+}
+
+static reloc_howto_type *
+ft32_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
+{
+  unsigned int i;
+
+  for (i = 0;
+       i < sizeof (ft32_elf_howto_table) / sizeof (ft32_elf_howto_table[0]);
+       i++)
+    if (ft32_elf_howto_table[i].name != NULL
+	&& strcasecmp (ft32_elf_howto_table[i].name, r_name) == 0)
+      return &ft32_elf_howto_table[i];
+
+  return NULL;
+}
+
+/* Set the howto pointer for an FT32 ELF reloc.  */
+
+static void
+ft32_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
+			  arelent *cache_ptr,
+			  Elf_Internal_Rela *dst)
+{
+  unsigned int r_type;
+
+  r_type = ELF32_R_TYPE (dst->r_info);
+  BFD_ASSERT (r_type < (unsigned int) R_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
+   to handle the relocations for a section.
+
+   The relocs are always passed as Rela structures; if the section
+   actually uses Rel structures, the r_addend field will always be
+   zero.
+
+   This function is responsible for adjusting the section contents as
+   necessary, and (if using Rela relocs and generating a relocatable
+   output file) adjusting the reloc addend as necessary.
+
+   This function does not have to worry about setting the reloc
+   address or the reloc symbol index.
+
+   LOCAL_SYMS is a pointer to the swapped in local symbols.
+
+   LOCAL_SECTIONS is an array giving the section in the input file
+   corresponding to the st_shndx field of each local symbol.
+
+   The global hash table entry for the global symbols can be found
+   via elf_sym_hashes (input_bfd).
+
+   When generating relocatable output, this function must handle
+   STB_LOCAL/STT_SECTION symbols specially.  The output symbol is
+   going to be the section symbol corresponding to the output
+   section, which means that the addend must be adjusted
+   accordingly.  */
+
+static bfd_boolean
+ft32_elf_relocate_section (bfd *output_bfd,
+			    struct bfd_link_info *info,
+			    bfd *input_bfd,
+			    asection *input_section,
+			    bfd_byte *contents,
+			    Elf_Internal_Rela *relocs,
+			    Elf_Internal_Sym *local_syms,
+			    asection **local_sections)
+{
+  Elf_Internal_Shdr *symtab_hdr;
+  struct elf_link_hash_entry **sym_hashes;
+  Elf_Internal_Rela *rel;
+  Elf_Internal_Rela *relend;
+
+  symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
+  sym_hashes = elf_sym_hashes (input_bfd);
+  relend     = relocs + input_section->reloc_count;
+
+  for (rel = relocs; rel < relend; rel ++)
+    {
+      reloc_howto_type *howto;
+      unsigned long r_symndx;
+      Elf_Internal_Sym *sym;
+      asection *sec;
+      struct elf_link_hash_entry *h;
+      bfd_vma relocation;
+      bfd_reloc_status_type r;
+      const char *name;
+      int r_type;
+
+      r_type = ELF32_R_TYPE (rel->r_info);
+      r_symndx = ELF32_R_SYM (rel->r_info);
+      howto  = ft32_elf_howto_table + r_type;
+      h      = NULL;
+      sym    = NULL;
+      sec    = NULL;
+
+      if (r_symndx < symtab_hdr->sh_info)
+	{
+	  sym = local_syms + r_symndx;
+	  sec = local_sections [r_symndx];
+	  relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
+
+	  name = bfd_elf_string_from_elf_section
+	    (input_bfd, symtab_hdr->sh_link, sym->st_name);
+	  name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
+	}
+      else
+	{
+	  bfd_boolean unresolved_reloc, warned, ignored;
+
+	  RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+				   r_symndx, symtab_hdr, sym_hashes,
+				   h, sec, relocation,
+				   unresolved_reloc, warned, ignored);
+
+	  name = h->root.root.string;
+	}
+
+      if (sec != NULL && discarded_section (sec))
+	RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+					 rel, 1, relend, howto, 0, contents);
+
+      if (info->relocatable)
+	continue;
+
+      r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+				    contents, rel->r_offset,
+				    relocation, rel->r_addend);
+
+      if (r != bfd_reloc_ok)
+	{
+	  const char * msg = NULL;
+
+	  switch (r)
+	    {
+	    case bfd_reloc_overflow:
+	      r = info->callbacks->reloc_overflow
+		(info, (h ? &h->root : NULL), name, howto->name,
+		 (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
+	      break;
+
+	    case bfd_reloc_undefined:
+	      r = info->callbacks->undefined_symbol
+		(info, name, input_bfd, input_section, rel->r_offset,
+		 TRUE);
+	      break;
+
+	    case bfd_reloc_outofrange:
+	      msg = _("internal error: out of range error");
+	      break;
+
+	    case bfd_reloc_notsupported:
+	      msg = _("internal error: unsupported relocation error");
+	      break;
+
+	    case bfd_reloc_dangerous:
+	      msg = _("internal error: dangerous relocation");
+	      break;
+
+	    default:
+	      msg = _("internal error: unknown error");
+	      break;
+	    }
+
+	  if (msg)
+	    r = info->callbacks->warning
+	      (info, msg, name, input_bfd, input_section, rel->r_offset);
+
+	  if (! r)
+	    return FALSE;
+	}
+    }
+
+  return TRUE;
+}
+
+#define ELF_ARCH		bfd_arch_ft32
+#define ELF_MACHINE_CODE	EM_FT32
+#define ELF_MAXPAGESIZE		0x1
+
+#define TARGET_LITTLE_SYM       ft32_elf32_vec
+#define TARGET_LITTLE_NAME	"elf32-ft32"
+
+#define elf_info_to_howto_rel			NULL
+#define elf_info_to_howto			ft32_info_to_howto_rela
+#define elf_backend_relocate_section		ft32_elf_relocate_section
+
+#define elf_backend_can_gc_sections		1
+#define elf_backend_rela_normal			1
+
+#define bfd_elf32_bfd_reloc_type_lookup		ft32_reloc_type_lookup
+#define bfd_elf32_bfd_reloc_name_lookup		ft32_reloc_name_lookup
+
+#include "elf32-target.h"
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index bf1ebb6..a1c0a01 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -1193,6 +1193,11 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
 
   "BFD_RELOC_MOXIE_10_PCREL",
 
+  "BFD_RELOC_FT32_10",
+  "BFD_RELOC_FT32_20",
+  "BFD_RELOC_FT32_17",
+  "BFD_RELOC_FT32_18",
+
   "BFD_RELOC_FRV_LABEL16",
   "BFD_RELOC_FRV_LABEL24",
   "BFD_RELOC_FRV_LO16",
diff --git a/bfd/reloc.c b/bfd/reloc.c
index fe7d8be..193841a 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -2445,6 +2445,18 @@ ENUMDOC
 COMMENT
 
 ENUM
+  BFD_RELOC_FT32_10
+ENUMX
+  BFD_RELOC_FT32_20
+ENUMX
+  BFD_RELOC_FT32_17
+ENUMX
+  BFD_RELOC_FT32_18
+ENUMDOC
+  FT32 ELF relocations.
+COMMENT
+
+ENUM
   BFD_RELOC_FRV_LABEL16
 ENUMX
   BFD_RELOC_FRV_LABEL24
diff --git a/bfd/targets.c b/bfd/targets.c
index dc1e3ca..0c7fed5 100644
--- a/bfd/targets.c
+++ b/bfd/targets.c
@@ -872,6 +872,7 @@ extern const bfd_target tilegx_elf64_le_vec;
 extern const bfd_target tilepro_elf32_vec;
 extern const bfd_target v800_elf32_vec;
 extern const bfd_target v850_elf32_vec;
+extern const bfd_target ft32_elf32_vec;
 extern const bfd_target vax_aout_1knbsd_vec;
 extern const bfd_target vax_aout_bsd_vec;
 extern const bfd_target vax_aout_nbsd_vec;
@@ -1378,6 +1379,8 @@ static const bfd_target * const _bfd_target_vector[] =
 #endif
 	&tilepro_elf32_vec,
 
+	&ft32_elf32_vec,
+
 	&v800_elf32_vec,
 	&v850_elf32_vec,
 
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 6c47d9a..50e6285 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -106,6 +106,7 @@
 #include "elf/epiphany.h"
 #include "elf/fr30.h"
 #include "elf/frv.h"
+#include "elf/ft32.h"
 #include "elf/h8.h"
 #include "elf/hppa.h"
 #include "elf/i386.h"
@@ -709,6 +710,7 @@ guess_is_rela (unsigned int e_machine)
     case EM_D30V:
     case EM_CYGNUS_D30V:
     case EM_FR30:
+    case EM_FT32:
     case EM_CYGNUS_FR30:
     case EM_CYGNUS_FRV:
     case EM_H8S:
@@ -1234,6 +1236,10 @@ dump_relocations (FILE * file,
 	  rtype = elf_frv_reloc_type (type);
 	  break;
 
+	case EM_FT32:
+	  rtype = elf_ft32_reloc_type (type);
+	  break;
+
 	case EM_MCORE:
 	  rtype = elf_mcore_reloc_type (type);
 	  break;
@@ -2072,6 +2078,7 @@ get_machine_name (unsigned e_machine)
     case EM_PPC:		return "PowerPC";
     case EM_PPC64:		return "PowerPC64";
     case EM_FR20:		return "Fujitsu FR20";
+    case EM_FT32:		return "FTDI FT32";
     case EM_RH32:		return "TRW RH32";
     case EM_MCORE:		return "MCORE";
     case EM_ARM:		return "ARM";
@@ -11022,6 +11029,8 @@ is_32bit_abs_reloc (unsigned int reloc_type)
     case EM_CYGNUS_FR30:
     case EM_FR30:
       return reloc_type == 3; /* R_FR30_32.  */
+    case EM_FT32:
+      return reloc_type == 1; /* R_FT32_32.  */
     case EM_H8S:
     case EM_H8_300:
     case EM_H8_300H:
@@ -11389,6 +11398,7 @@ is_none_reloc (unsigned int reloc_type)
     case EM_L1OM:    /* R_X86_64_NONE.  */
     case EM_K1OM:    /* R_X86_64_NONE.  */
     case EM_MN10300: /* R_MN10300_NONE.  */
+    case EM_FT32:    /* R_FT32_NONE.  */
     case EM_MOXIE:   /* R_MOXIE_NONE.  */
     case EM_M32R:    /* R_M32R_NONE.  */
     case EM_TI_C6000:/* R_C6000_NONE.  */
diff --git a/configure b/configure
index 87677bc..7a972b0 100755
--- a/configure
+++ b/configure
@@ -3439,6 +3439,9 @@ case "${target}" in
   rs6000-*-aix*)
     noconfigdirs="$noconfigdirs ${libgcj}"
     ;;
+  ft32-*-*)
+    noconfigdirs="$noconfigdirs ${libgcj}"
+    ;;
   *-*-lynxos*)
     noconfigdirs="$noconfigdirs ${libgcj}"
     ;;
@@ -3664,6 +3667,9 @@ case "${target}" in
   fr30-*-elf*)
     noconfigdirs="$noconfigdirs gdb"
     ;;
+  ft32-*-*)
+    noconfigdirs="$noconfigdirs target-rda gprof"
+    ;;
   moxie-*-*)
     noconfigdirs="$noconfigdirs gprof"
     ;;
diff --git a/configure.ac b/configure.ac
index 4bb4865..a6df864 100644
--- a/configure.ac
+++ b/configure.ac
@@ -767,6 +767,9 @@ case "${target}" in
   rs6000-*-aix*)
     noconfigdirs="$noconfigdirs ${libgcj}"
     ;;
+  ft32-*-*)
+    noconfigdirs="$noconfigdirs ${libgcj}"
+    ;;
   *-*-lynxos*)
     noconfigdirs="$noconfigdirs ${libgcj}"
     ;; 
@@ -992,6 +995,9 @@ case "${target}" in
   fr30-*-elf*)
     noconfigdirs="$noconfigdirs gdb"
     ;;
+  ft32-*-*)
+    noconfigdirs="$noconfigdirs target-rda gprof"
+    ;;
   moxie-*-*)
     noconfigdirs="$noconfigdirs gprof"
     ;;
diff --git a/gas/Makefile.am b/gas/Makefile.am
index f875c93..a822be7 100644
--- a/gas/Makefile.am
+++ b/gas/Makefile.am
@@ -139,6 +139,7 @@ TARGET_CPU_CFILES = \
 	config/tc-epiphany.c \
 	config/tc-fr30.c \
 	config/tc-frv.c \
+	config/tc-ft32.c \
 	config/tc-h8300.c \
 	config/tc-hppa.c \
 	config/tc-ia64.c \
@@ -212,6 +213,7 @@ TARGET_CPU_HFILES = \
 	config/tc-epiphany.h \
 	config/tc-fr30.h \
 	config/tc-frv.h \
+	config/tc-ft32.h \
 	config/tc-h8300.h \
 	config/tc-hppa.h \
 	config/tc-ia64.h \
diff --git a/gas/Makefile.in b/gas/Makefile.in
index f190714..21a1452 100644
--- a/gas/Makefile.in
+++ b/gas/Makefile.in
@@ -408,6 +408,7 @@ TARGET_CPU_CFILES = \
 	config/tc-epiphany.c \
 	config/tc-fr30.c \
 	config/tc-frv.c \
+	config/tc-ft32.c \
 	config/tc-h8300.c \
 	config/tc-hppa.c \
 	config/tc-ia64.c \
@@ -481,6 +482,7 @@ TARGET_CPU_HFILES = \
 	config/tc-epiphany.h \
 	config/tc-fr30.h \
 	config/tc-frv.h \
+	config/tc-ft32.h \
 	config/tc-h8300.h \
 	config/tc-hppa.h \
 	config/tc-ia64.h \
@@ -836,6 +838,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-epiphany.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-fr30.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-frv.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-ft32.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-h8300.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-hppa.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-i370.Po@am__quote@
@@ -1126,6 +1129,13 @@ tc-frv.obj: config/tc-frv.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tc-frv.obj `if test -f 'config/tc-frv.c'; then $(CYGPATH_W) 'config/tc-frv.c'; else $(CYGPATH_W) '$(srcdir)/config/tc-frv.c'; fi`
 
+tc-ft32.o: config/tc-ft32.c
+@am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tc-ft32.o -MD -MP -MF $(DEPDIR)/tc-ft32.Tpo -c -o tc-ft32.o `test -f 'config/tc-ft32.c' || echo '$(srcdir)/'`config/tc-ft32.c
+@am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/tc-ft32.Tpo $(DEPDIR)/tc-ft32.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='config/tc-ft32.c' object='tc-ft32.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tc-ft32.o `test -f 'config/tc-ft32.c' || echo '$(srcdir)/'`config/tc-ft32.c
+
 tc-h8300.o: config/tc-h8300.c
 @am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tc-h8300.o -MD -MP -MF $(DEPDIR)/tc-h8300.Tpo -c -o tc-h8300.o `test -f 'config/tc-h8300.c' || echo '$(srcdir)/'`config/tc-h8300.c
 @am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/tc-h8300.Tpo $(DEPDIR)/tc-h8300.Po
diff --git a/gas/config/tc-ft32.c b/gas/config/tc-ft32.c
new file mode 100644
index 0000000..5b9e33d
--- /dev/null
+++ b/gas/config/tc-ft32.c
@@ -0,0 +1,636 @@
+/* tc-ft32.c -- Assemble code for ft32
+   Copyright 2008
+   Free Software Foundation, Inc.
+
+   This file is part of GAS, the GNU Assembler.
+
+   GAS is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   GAS is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GAS; see the file COPYING.  If not, write to
+   the Free Software Foundation, 51 Franklin Street - Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
+
+/* Contributed by Anthony Green <green@spindazzle.org>.  */
+
+#include "as.h"
+#include "safe-ctype.h"
+#include "opcode/ft32.h"
+
+extern const ft32_opc_info_t ft32_opc_info[128];
+
+const char comment_chars[]        = "#";
+const char line_separator_chars[] = ";";
+const char line_comment_chars[]   = "#";
+
+static int pending_reloc;
+static struct hash_control *opcode_hash_control;
+
+static valueT md_chars_to_number (char * buf, int n);
+
+const pseudo_typeS md_pseudo_table[] =
+{
+  {0, 0, 0}
+};
+
+const char FLT_CHARS[] = "rRsSfFdDxXpP";
+const char EXP_CHARS[] = "eE";
+
+/* This function is called once, at assembler startup time.  It sets
+   up the hash table with all the opcodes in it, and also initializes
+   some aliases for compatibility with other assemblers.  */
+
+void
+md_begin (void)
+{
+  const ft32_opc_info_t *opcode;
+  opcode_hash_control = hash_new ();
+
+  /* Insert names into hash table.  */
+  for (opcode = ft32_opc_info; opcode->name; opcode++)
+    hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
+
+  bfd_set_arch_mach (stdoutput, TARGET_ARCH, 0);
+}
+
+/* Parse an expression and then restore the input line pointer.  */
+
+static char *
+parse_exp_save_ilp (char *s, expressionS *op)
+{
+  char *save = input_line_pointer;
+
+  input_line_pointer = s;
+  expression (op);
+  s = input_line_pointer;
+  input_line_pointer = save;
+  return s;
+}
+
+static int
+parse_condition (char **ptr)
+{
+  char *s = *ptr;
+  static const struct {
+    char *name;
+    int bits;
+  } 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)},
+    { "lte,"  , (2 << FT32_FLD_CR_BIT) | (5 << FT32_FLD_CB_BIT) | (0 << FT32_FLD_CV_BIT)},
+    { "a,"    , (2 << FT32_FLD_CR_BIT) | (6 << FT32_FLD_CB_BIT) | (1 << FT32_FLD_CV_BIT)},
+    { "ae,"   , (2 << FT32_FLD_CR_BIT) | (1 << FT32_FLD_CB_BIT) | (0 << FT32_FLD_CV_BIT)},
+    { "be,"   , (2 << FT32_FLD_CR_BIT) | (6 << FT32_FLD_CB_BIT) | (0 << FT32_FLD_CV_BIT)},
+    { "b,"    , (2 << FT32_FLD_CR_BIT) | (1 << FT32_FLD_CB_BIT) | (1 << FT32_FLD_CV_BIT)},
+    { "nz,"   , (2 << FT32_FLD_CR_BIT) | (0 << FT32_FLD_CB_BIT) | (0 << FT32_FLD_CV_BIT)},
+    { "z,"    , (2 << FT32_FLD_CR_BIT) | (0 << FT32_FLD_CB_BIT) | (1 << FT32_FLD_CV_BIT)},
+    { "nc,"   , (2 << FT32_FLD_CR_BIT) | (1 << FT32_FLD_CB_BIT) | (0 << FT32_FLD_CV_BIT)},
+    { "c,"    , (2 << FT32_FLD_CR_BIT) | (1 << FT32_FLD_CB_BIT) | (1 << FT32_FLD_CV_BIT)},
+    { "no,"   , (2 << FT32_FLD_CR_BIT) | (2 << FT32_FLD_CB_BIT) | (0 << FT32_FLD_CV_BIT)},
+    { "o,"    , (2 << FT32_FLD_CR_BIT) | (2 << FT32_FLD_CB_BIT) | (1 << FT32_FLD_CV_BIT)},
+    { "ns,"   , (2 << FT32_FLD_CR_BIT) | (3 << FT32_FLD_CB_BIT) | (0 << FT32_FLD_CV_BIT)},
+    { "s,"    , (2 << FT32_FLD_CR_BIT) | (3 << FT32_FLD_CB_BIT) | (1 << FT32_FLD_CV_BIT)},
+    { NULL, 0}
+  }, *pc;
+
+  for (pc = ccs; pc->name; pc++)
+    {
+      if (memcmp(pc->name, s, strlen(pc->name)) == 0)
+        {
+          *ptr += strlen(pc->name) - 1;
+          return pc->bits;
+        }
+    }
+  return -1;
+}
+
+static int
+parse_decimal (char **ptr)
+{
+  int r = 0;
+  char *s = *ptr;
+
+  while (('0' <= *s) && (*s <= '9'))
+    {
+      r *= 10;
+      r += (*s++ - '0');
+    }
+  *ptr = s;
+  return r;
+}
+
+static int
+parse_register_operand (char **ptr)
+{
+  int reg;
+  char *s = *ptr;
+
+  if (*s != '$')
+    {
+      as_bad (_("expecting register"));
+      ignore_rest_of_line ();
+      return -1;
+    }
+  if ((s[1] == 's') && (s[2] == 'p'))
+    {
+      reg = 31;
+    }
+  else if ((s[1] == 'c') && (s[2] == 'c'))
+    {
+      reg = 30;
+    }
+  else if ((s[1] == 'f') && (s[2] == 'p'))
+    {
+      reg = 29;
+    }
+  else if (s[1] == 'r')
+    {
+      reg = s[2] - '0';
+      if ((reg < 0) || (reg > 9))
+	{
+	  as_bad (_("illegal register number"));
+	  ignore_rest_of_line ();
+	  return -1;
+	}
+      if ((reg == 1) || (reg == 2) || (reg == 3))
+	{
+	  int r2 = s[3] - '0';
+	  if ((r2 >= 0) && (r2 <= 9))
+	    {
+	      reg = (reg * 10) + r2;
+	      *ptr += 1;
+	    }
+	}
+    }
+  else
+    {
+      as_bad (_("illegal register number"));
+      ignore_rest_of_line ();
+      return -1;
+    }
+
+  *ptr += 3;
+
+  return reg;
+}
+
+/* This is the guts of the machine-dependent assembler.  STR points to
+   a machine dependent instruction.  This function is supposed to emit
+   the frags/bytes it assembles to.  */
+
+void
+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;
+
+  /* Drop leading whitespace.  */
+  while (*str == ' ')
+    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++)
+    nlen++;
+
+  pend = *op_end;
+  *op_end = 0;
+
+  if (nlen == 0)
+    as_bad (_("can't find opcode "));
+
+  opcode = (ft32_opc_info_t *) hash_find (opcode_hash_control, op_start);
+  *op_end = pend;
+
+  if (opcode == NULL)
+    {
+      as_bad (_("unknown opcode %s"), op_start);
+      return;
+    }
+
+  b = opcode->bits;
+  f = opcode->fields;
+
+  if (opcode->dw)
+    {
+      int dw;
+      if (*op_end == '.')
+        {
+          switch (op_end[1])
+            {
+              case 'b':
+                dw = 0;
+                break;
+              case 's':
+                dw = 1;
+                break;
+              case 'l':
+                dw = 2;
+                break;
+              default:
+                as_bad (_("unknown width specifier '.%c'"), op_end[1]);
+                return;
+            }
+          op_end += 2;
+        }
+      else
+        {
+          dw = 2; /* default is ".l" */
+        }
+      b |= dw << FT32_FLD_DW_BIT;
+    }
+
+  while (ISSPACE (*op_end))
+    op_end++;
+
+  output = frag_more (4);
+
+  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_K8:
+            op_end = parse_exp_save_ilp (op_end, &arg);
+            fix_new_exp (frag_now,
+                         (output - frag_now->fr_literal),
+                         1,
+                         &arg,
+                         0,
+                         BFD_RELOC_8);
+            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))
+                op_end++;
+
+              if (*op_end != ',')
+                {
+                  as_bad (_("expected comma separator"));
+                  ignore_rest_of_line ();
+                }
+
+              op_end++;
+              while (ISSPACE (*op_end))
+                op_end++;
+            }
+        }
+    }
+  if (*op_end != 0)
+    as_warn (_("extra stuff on line ignored"));
+
+  output[idx++] = 0xff & (b >> 0);
+  output[idx++] = 0xff & (b >> 8);
+  output[idx++] = 0xff & (b >> 16);
+  output[idx++] = 0xff & (b >> 24);
+
+  while (ISSPACE (*op_end))
+    op_end++;
+
+  if (*op_end != 0)
+    as_warn ("extra stuff on line ignored");
+
+  if (pending_reloc)
+    as_bad ("Something forgot to clean up\n");
+}
+
+/* Turn a string in input_line_pointer into a floating point constant
+   of type type, and store the appropriate bytes in *LITP.  The number
+   of LITTLENUMS emitted is stored in *SIZEP .  An error message is
+   returned, or NULL on OK.  */
+
+char *
+md_atof (int type, char *litP, int *sizeP)
+{
+  int prec;
+  LITTLENUM_TYPE words[4];
+  char *t;
+  int i;
+
+  switch (type)
+    {
+    case 'f':
+      prec = 2;
+      break;
+
+    case 'd':
+      prec = 4;
+      break;
+
+    default:
+      *sizeP = 0;
+      return _("bad call to md_atof");
+    }
+
+  t = atof_ieee (input_line_pointer, type, words);
+  if (t)
+    input_line_pointer = t;
+
+  *sizeP = prec * 2;
+
+  for (i = prec - 1; i >= 0; i--)
+    {
+      md_number_to_chars (litP, (valueT) words[i], 2);
+      litP += 2;
+    }
+
+  return NULL;
+}
+
+const char *md_shortopts = "";
+
+struct option md_longopts[] =
+{
+  {NULL, no_argument, NULL, 0}
+};
+size_t md_longopts_size = sizeof (md_longopts);
+
+/* We have no target specific options yet, so these next
+   two functions are empty.  */
+int
+md_parse_option (int c ATTRIBUTE_UNUSED, char *arg ATTRIBUTE_UNUSED)
+{
+  return 0;
+}
+
+void
+md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
+{
+}
+
+/* Convert from target byte order to host byte order.  */
+
+static valueT
+md_chars_to_number (char * buf, int n)
+{
+  valueT result = 0;
+  unsigned char * where = (unsigned char *) buf;
+
+  while (n--)
+    {
+      result <<= 8;
+      result |= (where[n] & 255);
+    }
+
+  return result;
+}
+/* Apply a fixup to the object file.  */
+
+void
+md_apply_fix (fixS *fixP ATTRIBUTE_UNUSED,
+	      valueT * valP ATTRIBUTE_UNUSED, segT seg ATTRIBUTE_UNUSED)
+{
+  char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
+  long val = *valP;
+  long newval;
+
+  switch (fixP->fx_r_type)
+    {
+    case BFD_RELOC_32:
+      buf[3] = val >> 24;
+      buf[2] = val >> 16;
+      buf[1] = val >> 8;
+      buf[0] = val >> 0;
+      break;
+
+    case BFD_RELOC_16:
+      buf[1] = val >> 8;
+      buf[0] = val >> 0;
+      break;
+
+    case BFD_RELOC_8:
+      *buf = val;
+      break;
+
+    case BFD_RELOC_FT32_10:
+      if (!val)
+	break;
+      newval = md_chars_to_number (buf, 2);
+      newval |= (val & ((1 << 10) - 1)) << FT32_FLD_RIMM_BIT;
+      md_number_to_chars (buf, newval, 2);
+      break;
+
+    case BFD_RELOC_FT32_20:
+      if (!val)
+	break;
+      newval = md_chars_to_number (buf, 3);
+      newval |= val & ((1 << 20) - 1);
+      md_number_to_chars (buf, newval, 3);
+      break;
+
+    case BFD_RELOC_FT32_17:
+      if (!val)
+	break;
+      newval = md_chars_to_number (buf, 3);
+      newval |= val & ((1 << 17) - 1);
+      md_number_to_chars (buf, newval, 3);
+      break;
+
+    case BFD_RELOC_FT32_18:
+      if (!val)
+	break;
+      newval = md_chars_to_number (buf, 4);
+      newval |= (val >> 2) & ((1 << 18) - 1);
+      md_number_to_chars (buf, newval, 4);
+      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
+md_number_to_chars (char *ptr, valueT use, int nbytes)
+{
+  number_to_chars_littleendian (ptr, use, nbytes);
+}
+
+/* Generate a machine-dependent relocation.  */
+arelent *
+tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
+{
+  arelent *relP;
+  bfd_reloc_code_real_type code;
+
+  switch (fixP->fx_r_type)
+    {
+    case BFD_RELOC_32:
+    case BFD_RELOC_16:
+    case BFD_RELOC_8:
+    case BFD_RELOC_FT32_10:
+    case BFD_RELOC_FT32_20:
+    case BFD_RELOC_FT32_17:
+    case BFD_RELOC_FT32_18:
+      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;
+    }
+
+  relP = xmalloc (sizeof (arelent));
+  gas_assert (relP != 0);
+  relP->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
+  *relP->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
+  relP->address = fixP->fx_frag->fr_address + fixP->fx_where;
+
+  relP->addend = fixP->fx_offset;
+
+  /* This is the standard place for KLUDGEs to work around bugs in
+     bfd_install_relocation (first such note in the documentation
+     appears with binutils-2.8).
+
+     That function bfd_install_relocation does the wrong thing with
+     putting stuff into the addend of a reloc (it should stay out) for a
+     weak symbol.  The really bad thing is that it adds the
+     "segment-relative offset" of the symbol into the reloc.  In this
+     case, the reloc should instead be relative to the symbol with no
+     other offset than the assembly code shows; and since the symbol is
+     weak, any local definition should be ignored until link time (or
+     thereafter).
+     To wit:  weaksym+42  should be weaksym+42 in the reloc,
+     not weaksym+(offset_from_segment_of_local_weaksym_definition)
+
+     To "work around" this, we subtract the segment-relative offset of
+     "known" weak symbols.  This evens out the extra offset.
+
+     That happens for a.out but not for ELF, since for ELF,
+     bfd_install_relocation uses the "special function" field of the
+     howto, and does not execute the code that needs to be undone.  */
+
+  if (OUTPUT_FLAVOR == bfd_target_aout_flavour
+      && fixP->fx_addsy && S_IS_WEAK (fixP->fx_addsy)
+      && ! bfd_is_und_section (S_GET_SEGMENT (fixP->fx_addsy)))
+    {
+      relP->addend -= S_GET_VALUE (fixP->fx_addsy);
+    }
+
+  relP->howto = bfd_reloc_type_lookup (stdoutput, code);
+  if (! relP->howto)
+    {
+      const char *name;
+
+      name = S_GET_NAME (fixP->fx_addsy);
+      if (name == NULL)
+	name = _("<unknown>");
+      as_fatal (_("Cannot generate relocation type for symbol %s, code %s"),
+		name, bfd_get_reloc_code_name (code));
+    }
+
+  return relP;
+}
diff --git a/gas/config/tc-ft32.h b/gas/config/tc-ft32.h
new file mode 100644
index 0000000..f5a4d4b
--- /dev/null
+++ b/gas/config/tc-ft32.h
@@ -0,0 +1,55 @@
+/* tc-ft32.h -- Header file for tc-ft32.c.
+
+   Copyright 2013 Free Software Foundation, Inc.
+   Contributed by FTDI (support@ftdichip.com)
+
+   This file is part of GAS, the GNU Assembler.
+
+   GAS is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   GAS is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along
+   with GAS; see the file COPYING.  If not, write to the Free Software
+   Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+#define TC_FT32 1
+#define TARGET_BYTES_BIG_ENDIAN 0
+#define WORKING_DOT_WORD
+
+/* This macro is the BFD architecture to pass to `bfd_set_arch_mach'.  */
+const char *ft32_target_format;
+#define DEFAULT_TARGET_FORMAT  "elf32-ft32"
+#define TARGET_FORMAT          ft32_target_format
+
+#define TARGET_ARCH bfd_arch_ft32
+
+#define md_undefined_symbol(NAME)           0
+
+/* These macros must be defined, but is will be a fatal assembler
+   error if we ever hit them.  */
+#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")), 0)
+
+/* 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)						\
+	((FIX)->fx_where + (FIX)->fx_frag->fr_address - 1)
+
+#define md_section_align(SEGMENT, SIZE)     (SIZE)
+
+#define md_operand(x)
diff --git a/gas/configure.tgt b/gas/configure.tgt
index af90198..ee07266 100644
--- a/gas/configure.tgt
+++ b/gas/configure.tgt
@@ -183,6 +183,8 @@ case ${generic_target} in
   frv-*-*linux*)			fmt=elf em=linux;;
   frv-*-*)				fmt=elf ;;
 
+  ft32-*-*)				fmt=elf ;;
+
   hppa-*-linux*)
     case ${cpu} in
       hppa*64*)				fmt=elf em=hppalinux64 ;;
diff --git a/gas/testsuite/gas/ft32/ft32.exp b/gas/testsuite/gas/ft32/ft32.exp
new file mode 100644
index 0000000..bec2096
--- /dev/null
+++ b/gas/testsuite/gas/ft32/ft32.exp
@@ -0,0 +1,21 @@
+# Copyright (C) 2012-2015 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  
+
+# FT32 testcases
+
+if [istarget ft32-*-*] {
+    run_dump_test "insn"
+}
diff --git a/gas/testsuite/gas/ft32/insn.d b/gas/testsuite/gas/ft32/insn.d
new file mode 100644
index 0000000..cdaa140
--- /dev/null
+++ b/gas/testsuite/gas/ft32/insn.d
@@ -0,0 +1,490 @@
+#as:
+#objdump: -d
+#name: insn
+
+dump.o:     file format elf32-ft32
+
+
+Disassembly of section .text:
+
+00000000 <pmlabel>:
+   0:	00 00 f0 45 	45f00000 add.l \$r31,\$r0,\$r0
+   4:	00 80 0f 44 	440f8000 add.l \$r0,\$r31,\$r0
+   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,0 <pmlabel>
+  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>
+  24:	10 80 0f 42 	420f8010 add.s \$r0,\$r31,\$r1
+  28:	d0 c4 0f 42 	420fc4d0 add.s \$r0,\$r31,4d <pmlabel\+0x4d>
+  2c:	10 80 0f 40 	400f8010 add.b \$r0,\$r31,\$r1
+  30:	d0 c4 0f 40 	400fc4d0 add.b \$r0,\$r31,4d <pmlabel\+0x4d>
+  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,0 <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>
+  58:	12 80 0f 42 	420f8012 sub.s \$r0,\$r31,\$r1
+  5c:	d2 c4 0f 42 	420fc4d2 sub.s \$r0,\$r31,4d <pmlabel\+0x4d>
+  60:	12 80 0f 40 	400f8012 sub.b \$r0,\$r31,\$r1
+  64:	d2 c4 0f 40 	400fc4d2 sub.b \$r0,\$r31,4d <pmlabel\+0x4d>
+  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,0 <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>
+  8c:	14 80 0f 42 	420f8014 and.s \$r0,\$r31,\$r1
+  90:	d4 c4 0f 42 	420fc4d4 and.s \$r0,\$r31,4d <pmlabel\+0x4d>
+  94:	14 80 0f 40 	400f8014 and.b \$r0,\$r31,\$r1
+  98:	d4 c4 0f 40 	400fc4d4 and.b \$r0,\$r31,4d <pmlabel\+0x4d>
+  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,0 <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>
+  c0:	15 80 0f 42 	420f8015 or.s \$r0,\$r31,\$r1
+  c4:	d5 c4 0f 42 	420fc4d5 or.s \$r0,\$r31,4d <pmlabel\+0x4d>
+  c8:	15 80 0f 40 	400f8015 or.b \$r0,\$r31,\$r1
+  cc:	d5 c4 0f 40 	400fc4d5 or.b \$r0,\$r31,4d <pmlabel\+0x4d>
+  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,0 <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>
+  f4:	16 80 0f 42 	420f8016 xor.s \$r0,\$r31,\$r1
+  f8:	d6 c4 0f 42 	420fc4d6 xor.s \$r0,\$r31,4d <pmlabel\+0x4d>
+  fc:	16 80 0f 40 	400f8016 xor.b \$r0,\$r31,\$r1
+ 100:	d6 c4 0f 40 	400fc4d6 xor.b \$r0,\$r31,4d <pmlabel\+0x4d>
+ 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,0 <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>
+ 128:	17 80 0f 42 	420f8017 xnor.s \$r0,\$r31,\$r1
+ 12c:	d7 c4 0f 42 	420fc4d7 xnor.s \$r0,\$r31,4d <pmlabel\+0x4d>
+ 130:	17 80 0f 40 	400f8017 xnor.b \$r0,\$r31,\$r1
+ 134:	d7 c4 0f 40 	400fc4d7 xnor.b \$r0,\$r31,4d <pmlabel\+0x4d>
+ 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,0 <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>
+ 15c:	18 80 0f 42 	420f8018 ashl.s \$r0,\$r31,\$r1
+ 160:	d8 c4 0f 42 	420fc4d8 ashl.s \$r0,\$r31,4d <pmlabel\+0x4d>
+ 164:	18 80 0f 40 	400f8018 ashl.b \$r0,\$r31,\$r1
+ 168:	d8 c4 0f 40 	400fc4d8 ashl.b \$r0,\$r31,4d <pmlabel\+0x4d>
+ 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,0 <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>
+ 190:	19 80 0f 42 	420f8019 lshr.s \$r0,\$r31,\$r1
+ 194:	d9 c4 0f 42 	420fc4d9 lshr.s \$r0,\$r31,4d <pmlabel\+0x4d>
+ 198:	19 80 0f 40 	400f8019 lshr.b \$r0,\$r31,\$r1
+ 19c:	d9 c4 0f 40 	400fc4d9 lshr.b \$r0,\$r31,4d <pmlabel\+0x4d>
+ 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,0 <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>
+ 1c4:	1a 80 0f 42 	420f801a ashr.s \$r0,\$r31,\$r1
+ 1c8:	da c4 0f 42 	420fc4da ashr.s \$r0,\$r31,4d <pmlabel\+0x4d>
+ 1cc:	1a 80 0f 40 	400f801a ashr.b \$r0,\$r31,\$r1
+ 1d0:	da c4 0f 40 	400fc4da ashr.b \$r0,\$r31,4d <pmlabel\+0x4d>
+ 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,0 <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>
+ 1f8:	11 80 0f 42 	420f8011 ror.s \$r0,\$r31,\$r1
+ 1fc:	d1 c4 0f 42 	420fc4d1 ror.s \$r0,\$r31,4d <pmlabel\+0x4d>
+ 200:	11 80 0f 40 	400f8011 ror.b \$r0,\$r31,\$r1
+ 204:	d1 c4 0f 40 	400fc4d1 ror.b \$r0,\$r31,4d <pmlabel\+0x4d>
+ 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,0 <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>
+ 22c:	13 80 0f 42 	420f8013 ldl.s \$r0,\$r31,\$r1
+ 230:	d3 c4 0f 42 	420fc4d3 ldl.s \$r0,\$r31,4d <pmlabel\+0x4d>
+ 234:	13 80 0f 40 	400f8013 ldl.b \$r0,\$r31,\$r1
+ 238:	d3 c4 0f 40 	400fc4d3 ldl.b \$r0,\$r31,4d <pmlabel\+0x4d>
+ 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,0 <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>
+ 260:	1b 80 0f 42 	420f801b bins.s \$r0,\$r31,\$r1
+ 264:	db c4 0f 42 	420fc4db bins.s \$r0,\$r31,4d <pmlabel\+0x4d>
+ 268:	1b 80 0f 40 	400f801b bins.b \$r0,\$r31,\$r1
+ 26c:	db c4 0f 40 	400fc4db bins.b \$r0,\$r31,4d <pmlabel\+0x4d>
+ 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,0 <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>
+ 294:	1c 80 0f 42 	420f801c bexts.s \$r0,\$r31,\$r1
+ 298:	dc c4 0f 42 	420fc4dc bexts.s \$r0,\$r31,4d <pmlabel\+0x4d>
+ 29c:	1c 80 0f 40 	400f801c bexts.b \$r0,\$r31,\$r1
+ 2a0:	dc c4 0f 40 	400fc4dc bexts.b \$r0,\$r31,4d <pmlabel\+0x4d>
+ 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,0 <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>
+ 2c8:	1d 80 0f 42 	420f801d bextu.s \$r0,\$r31,\$r1
+ 2cc:	dd c4 0f 42 	420fc4dd bextu.s \$r0,\$r31,4d <pmlabel\+0x4d>
+ 2d0:	1d 80 0f 40 	400f801d bextu.b \$r0,\$r31,\$r1
+ 2d4:	dd c4 0f 40 	400fc4dd bextu.b \$r0,\$r31,4d <pmlabel\+0x4d>
+ 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,0 <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>
+ 2fc:	1e 80 0f 42 	420f801e flip.s \$r0,\$r31,\$r1
+ 300:	de c4 0f 42 	420fc4de flip.s \$r0,\$r31,4d <pmlabel\+0x4d>
+ 304:	1e 80 0f 40 	400f801e flip.b \$r0,\$r31,\$r1
+ 308:	de c4 0f 40 	400fc4de flip.b \$r0,\$r31,4d <pmlabel\+0x4d>
+ 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,0 <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>
+ 328:	10 80 ef 5b 	5bef8010 addcc.s \$r31,\$r1
+ 32c:	d0 c4 ef 5b 	5befc4d0 addcc.s \$r31,4d <pmlabel\+0x4d>
+ 330:	10 80 ef 59 	59ef8010 addcc.b \$r31,\$r1
+ 334:	d0 c4 ef 59 	59efc4d0 addcc.b \$r31,4d <pmlabel\+0x4d>
+ 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,0 <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>
+ 354:	12 80 ef 5b 	5bef8012 cmp.s \$r31,\$r1
+ 358:	d2 c4 ef 5b 	5befc4d2 cmp.s \$r31,4d <pmlabel\+0x4d>
+ 35c:	12 80 ef 59 	59ef8012 cmp.b \$r31,\$r1
+ 360:	d2 c4 ef 59 	59efc4d2 cmp.b \$r31,4d <pmlabel\+0x4d>
+ 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,0 <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>
+ 380:	14 80 ef 5b 	5bef8014 tst.s \$r31,\$r1
+ 384:	d4 c4 ef 5b 	5befc4d4 tst.s \$r31,4d <pmlabel\+0x4d>
+ 388:	14 80 ef 59 	59ef8014 tst.b \$r31,\$r1
+ 38c:	d4 c4 ef 59 	59efc4d4 tst.b \$r31,4d <pmlabel\+0x4d>
+ 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,0 <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>
+ 3ac:	1c 80 ef 5b 	5bef801c btst.s \$r31,\$r1
+ 3b0:	dc c4 ef 5b 	5befc4dc btst.s \$r31,4d <pmlabel\+0x4d>
+ 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>
+ 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>
+ 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>
+ 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>
+ 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>
+ 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
+ 4b0:	00 80 0f f4 	f40f8000 udiv.l \$r0,\$r31,\$r0
+ 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,0 <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>
+ 4d0:	10 80 0f f2 	f20f8010 udiv.s \$r0,\$r31,\$r1
+ 4d4:	d0 c4 0f f2 	f20fc4d0 udiv.s \$r0,\$r31,4d <pmlabel\+0x4d>
+ 4d8:	10 80 0f f0 	f00f8010 udiv.b \$r0,\$r31,\$r1
+ 4dc:	d0 c4 0f f0 	f00fc4d0 udiv.b \$r0,\$r31,4d <pmlabel\+0x4d>
+ 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,0 <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>
+ 504:	11 80 0f f2 	f20f8011 umod.s \$r0,\$r31,\$r1
+ 508:	d1 c4 0f f2 	f20fc4d1 umod.s \$r0,\$r31,4d <pmlabel\+0x4d>
+ 50c:	11 80 0f f0 	f00f8011 umod.b \$r0,\$r31,\$r1
+ 510:	d1 c4 0f f0 	f00fc4d1 umod.b \$r0,\$r31,4d <pmlabel\+0x4d>
+ 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,0 <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>
+ 538:	12 80 0f f2 	f20f8012 div.s \$r0,\$r31,\$r1
+ 53c:	d2 c4 0f f2 	f20fc4d2 div.s \$r0,\$r31,4d <pmlabel\+0x4d>
+ 540:	12 80 0f f0 	f00f8012 div.b \$r0,\$r31,\$r1
+ 544:	d2 c4 0f f0 	f00fc4d2 div.b \$r0,\$r31,4d <pmlabel\+0x4d>
+ 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,0 <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>
+ 56c:	13 80 0f f2 	f20f8013 mod.s \$r0,\$r31,\$r1
+ 570:	d3 c4 0f f2 	f20fc4d3 mod.s \$r0,\$r31,4d <pmlabel\+0x4d>
+ 574:	13 80 0f f0 	f00f8013 mod.b \$r0,\$r31,\$r1
+ 578:	d3 c4 0f f0 	f00fc4d3 mod.b \$r0,\$r31,4d <pmlabel\+0x4d>
+ 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,0 <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>
+ 5a0:	14 80 0f f2 	f20f8014 strcmp.s \$r0,\$r31,\$r1
+ 5a4:	d4 c4 0f f2 	f20fc4d4 strcmp.s \$r0,\$r31,4d <pmlabel\+0x4d>
+ 5a8:	14 80 0f f0 	f00f8014 strcmp.b \$r0,\$r31,\$r1
+ 5ac:	d4 c4 0f f0 	f00fc4d4 strcmp.b \$r0,\$r31,4d <pmlabel\+0x4d>
+ 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,0 <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>
+ 5d4:	15 80 0f f2 	f20f8015 memcpy.s \$r0,\$r31,\$r1
+ 5d8:	d5 c4 0f f2 	f20fc4d5 memcpy.s \$r0,\$r31,4d <pmlabel\+0x4d>
+ 5dc:	15 80 0f f0 	f00f8015 memcpy.b \$r0,\$r31,\$r1
+ 5e0:	d5 c4 0f f0 	f00fc4d5 memcpy.b \$r0,\$r31,4d <pmlabel\+0x4d>
+ 5e4:	07 00 f0 f5 	f5f00007 memset.l \$r31,\$r0,\$r0
+ 5e8:	07 80 0f f4 	f40f8007 memset.l \$r0,\$r31,\$r0
+ 5ec:	f7 01 00 f4 	f40001f7 memset.l \$r0,\$r0,\$r31
+ 5f0:	47 00 11 f4 	f4110047 memset.l \$r1,\$r2,\$r4
+ 5f4:	07 00 88 f4 	f4880007 memset.l \$r8,\$r16,\$r0
+ 5f8:	07 60 f0 f5 	f5f06007 memset.l \$r31,\$r0,0 <pmlabel>
+ 5fc:	07 c0 0f f4 	f40fc007 memset.l \$r0,\$r31,0 <pmlabel>
+ 600:	17 c0 0f f4 	f40fc017 memset.l \$r0,\$r31,1 <pmlabel\+0x1>
+ 604:	f7 df 0f f4 	f40fdff7 memset.l \$r0,\$r31,1ff <pmlabel\+0x1ff>
+ 608:	17 80 0f f2 	f20f8017 memset.s \$r0,\$r31,\$r1
+ 60c:	d7 c4 0f f2 	f20fc4d7 memset.s \$r0,\$r31,4d <pmlabel\+0x4d>
+ 610:	17 80 0f f0 	f00f8017 memset.b \$r0,\$r31,\$r1
+ 614:	d7 c4 0f f0 	f00fc4d7 memset.b \$r0,\$r31,4d <pmlabel\+0x4d>
+ 618:	08 00 f0 f5 	f5f00008 mul.l \$r31,\$r0,\$r0
+ 61c:	08 80 0f f4 	f40f8008 mul.l \$r0,\$r31,\$r0
+ 620:	f8 01 00 f4 	f40001f8 mul.l \$r0,\$r0,\$r31
+ 624:	48 00 11 f4 	f4110048 mul.l \$r1,\$r2,\$r4
+ 628:	08 00 88 f4 	f4880008 mul.l \$r8,\$r16,\$r0
+ 62c:	08 60 f0 f5 	f5f06008 mul.l \$r31,\$r0,0 <pmlabel>
+ 630:	08 c0 0f f4 	f40fc008 mul.l \$r0,\$r31,0 <pmlabel>
+ 634:	18 c0 0f f4 	f40fc018 mul.l \$r0,\$r31,1 <pmlabel\+0x1>
+ 638:	f8 df 0f f4 	f40fdff8 mul.l \$r0,\$r31,1ff <pmlabel\+0x1ff>
+ 63c:	18 80 0f f2 	f20f8018 mul.s \$r0,\$r31,\$r1
+ 640:	d8 c4 0f f2 	f20fc4d8 mul.s \$r0,\$r31,4d <pmlabel\+0x4d>
+ 644:	18 80 0f f0 	f00f8018 mul.b \$r0,\$r31,\$r1
+ 648:	d8 c4 0f f0 	f00fc4d8 mul.b \$r0,\$r31,4d <pmlabel\+0x4d>
+ 64c:	09 00 f0 f5 	f5f00009 muluh.l \$r31,\$r0,\$r0
+ 650:	09 80 0f f4 	f40f8009 muluh.l \$r0,\$r31,\$r0
+ 654:	f9 01 00 f4 	f40001f9 muluh.l \$r0,\$r0,\$r31
+ 658:	49 00 11 f4 	f4110049 muluh.l \$r1,\$r2,\$r4
+ 65c:	09 00 88 f4 	f4880009 muluh.l \$r8,\$r16,\$r0
+ 660:	09 60 f0 f5 	f5f06009 muluh.l \$r31,\$r0,0 <pmlabel>
+ 664:	09 c0 0f f4 	f40fc009 muluh.l \$r0,\$r31,0 <pmlabel>
+ 668:	19 c0 0f f4 	f40fc019 muluh.l \$r0,\$r31,1 <pmlabel\+0x1>
+ 66c:	f9 df 0f f4 	f40fdff9 muluh.l \$r0,\$r31,1ff <pmlabel\+0x1ff>
+ 670:	19 80 0f f2 	f20f8019 muluh.s \$r0,\$r31,\$r1
+ 674:	d9 c4 0f f2 	f20fc4d9 muluh.s \$r0,\$r31,4d <pmlabel\+0x4d>
+ 678:	19 80 0f f0 	f00f8019 muluh.b \$r0,\$r31,\$r1
+ 67c:	d9 c4 0f f0 	f00fc4d9 muluh.b \$r0,\$r31,4d <pmlabel\+0x4d>
+ 680:	0c 00 f0 f5 	f5f0000c streamin.l \$r31,\$r0,\$r0
+ 684:	0c 80 0f f4 	f40f800c streamin.l \$r0,\$r31,\$r0
+ 688:	fc 01 00 f4 	f40001fc streamin.l \$r0,\$r0,\$r31
+ 68c:	4c 00 11 f4 	f411004c streamin.l \$r1,\$r2,\$r4
+ 690:	0c 00 88 f4 	f488000c streamin.l \$r8,\$r16,\$r0
+ 694:	0c 60 f0 f5 	f5f0600c streamin.l \$r31,\$r0,0 <pmlabel>
+ 698:	0c c0 0f f4 	f40fc00c streamin.l \$r0,\$r31,0 <pmlabel>
+ 69c:	1c c0 0f f4 	f40fc01c streamin.l \$r0,\$r31,1 <pmlabel\+0x1>
+ 6a0:	fc df 0f f4 	f40fdffc streamin.l \$r0,\$r31,1ff <pmlabel\+0x1ff>
+ 6a4:	1c 80 0f f2 	f20f801c streamin.s \$r0,\$r31,\$r1
+ 6a8:	dc c4 0f f2 	f20fc4dc streamin.s \$r0,\$r31,4d <pmlabel\+0x4d>
+ 6ac:	1c 80 0f f0 	f00f801c streamin.b \$r0,\$r31,\$r1
+ 6b0:	dc c4 0f f0 	f00fc4dc streamin.b \$r0,\$r31,4d <pmlabel\+0x4d>
+ 6b4:	0d 00 f0 f5 	f5f0000d streamini.l \$r31,\$r0,\$r0
+ 6b8:	0d 80 0f f4 	f40f800d streamini.l \$r0,\$r31,\$r0
+ 6bc:	fd 01 00 f4 	f40001fd streamini.l \$r0,\$r0,\$r31
+ 6c0:	4d 00 11 f4 	f411004d streamini.l \$r1,\$r2,\$r4
+ 6c4:	0d 00 88 f4 	f488000d streamini.l \$r8,\$r16,\$r0
+ 6c8:	0d 60 f0 f5 	f5f0600d streamini.l \$r31,\$r0,0 <pmlabel>
+ 6cc:	0d c0 0f f4 	f40fc00d streamini.l \$r0,\$r31,0 <pmlabel>
+ 6d0:	1d c0 0f f4 	f40fc01d streamini.l \$r0,\$r31,1 <pmlabel\+0x1>
+ 6d4:	fd df 0f f4 	f40fdffd streamini.l \$r0,\$r31,1ff <pmlabel\+0x1ff>
+ 6d8:	1d 80 0f f2 	f20f801d streamini.s \$r0,\$r31,\$r1
+ 6dc:	dd c4 0f f2 	f20fc4dd streamini.s \$r0,\$r31,4d <pmlabel\+0x4d>
+ 6e0:	1d 80 0f f0 	f00f801d streamini.b \$r0,\$r31,\$r1
+ 6e4:	dd c4 0f f0 	f00fc4dd streamini.b \$r0,\$r31,4d <pmlabel\+0x4d>
+ 6e8:	0e 00 f0 f5 	f5f0000e streamout.l \$r31,\$r0,\$r0
+ 6ec:	0e 80 0f f4 	f40f800e streamout.l \$r0,\$r31,\$r0
+ 6f0:	fe 01 00 f4 	f40001fe streamout.l \$r0,\$r0,\$r31
+ 6f4:	4e 00 11 f4 	f411004e streamout.l \$r1,\$r2,\$r4
+ 6f8:	0e 00 88 f4 	f488000e streamout.l \$r8,\$r16,\$r0
+ 6fc:	0e 60 f0 f5 	f5f0600e streamout.l \$r31,\$r0,0 <pmlabel>
+ 700:	0e c0 0f f4 	f40fc00e streamout.l \$r0,\$r31,0 <pmlabel>
+ 704:	1e c0 0f f4 	f40fc01e streamout.l \$r0,\$r31,1 <pmlabel\+0x1>
+ 708:	fe df 0f f4 	f40fdffe streamout.l \$r0,\$r31,1ff <pmlabel\+0x1ff>
+ 70c:	1e 80 0f f2 	f20f801e streamout.s \$r0,\$r31,\$r1
+ 710:	de c4 0f f2 	f20fc4de streamout.s \$r0,\$r31,4d <pmlabel\+0x4d>
+ 714:	1e 80 0f f0 	f00f801e streamout.b \$r0,\$r31,\$r1
+ 718:	de c4 0f f0 	f00fc4de streamout.b \$r0,\$r31,4d <pmlabel\+0x4d>
+ 71c:	0f 00 f0 f5 	f5f0000f streamouti.l \$r31,\$r0,\$r0
+ 720:	0f 80 0f f4 	f40f800f streamouti.l \$r0,\$r31,\$r0
+ 724:	ff 01 00 f4 	f40001ff streamouti.l \$r0,\$r0,\$r31
+ 728:	4f 00 11 f4 	f411004f streamouti.l \$r1,\$r2,\$r4
+ 72c:	0f 00 88 f4 	f488000f streamouti.l \$r8,\$r16,\$r0
+ 730:	0f 60 f0 f5 	f5f0600f streamouti.l \$r31,\$r0,0 <pmlabel>
+ 734:	0f c0 0f f4 	f40fc00f streamouti.l \$r0,\$r31,0 <pmlabel>
+ 738:	1f c0 0f f4 	f40fc01f streamouti.l \$r0,\$r31,1 <pmlabel\+0x1>
+ 73c:	ff df 0f f4 	f40fdfff streamouti.l \$r0,\$r31,1ff <pmlabel\+0x1ff>
+ 740:	1f 80 0f f2 	f20f801f streamouti.s \$r0,\$r31,\$r1
+ 744:	df c4 0f f2 	f20fc4df streamouti.s \$r0,\$r31,4d <pmlabel\+0x4d>
+ 748:	1f 80 0f f0 	f00f801f streamouti.b \$r0,\$r31,\$r1
+ 74c:	df c4 0f f0 	f00fc4df streamouti.b \$r0,\$r31,4d <pmlabel\+0x4d>
+ 750:	06 c0 0f f4 	f40fc006 strlen.l \$r0,\$r31
+ 754:	06 40 f0 f5 	f5f04006 strlen.l \$r31,\$r0
+ 758:	06 c0 0f f2 	f20fc006 strlen.s \$r0,\$r31
+ 75c:	06 40 f0 f3 	f3f04006 strlen.s \$r31,\$r0
+ 760:	06 c0 0f f0 	f00fc006 strlen.b \$r0,\$r31
+ 764:	06 40 f0 f1 	f1f04006 strlen.b \$r31,\$r0
+ 768:	0a c0 0f f4 	f40fc00a stpcpy.l \$r0,\$r31
+ 76c:	0a 40 f0 f5 	f5f0400a stpcpy.l \$r31,\$r0
+ 770:	0a c0 0f f2 	f20fc00a stpcpy.s \$r0,\$r31
+ 774:	0a 40 f0 f3 	f3f0400a stpcpy.s \$r31,\$r0
+ 778:	0a c0 0f f0 	f00fc00a stpcpy.b \$r0,\$r31
+ 77c:	0a 40 f0 f1 	f1f0400a stpcpy.b \$r31,\$r0
diff --git a/gas/testsuite/gas/ft32/insn.s b/gas/testsuite/gas/ft32/insn.s
new file mode 100644
index 0000000..6806c89
--- /dev/null
+++ b/gas/testsuite/gas/ft32/insn.s
@@ -0,0 +1,185 @@
+        # Used for all instructions that have a 3-address form
+	.macro TERNARY insn	
+        # reg-reg
+        \insn   $r31, $r0, $r0
+        \insn   $r0, $r31, $r0
+        \insn   $r0, $r0, $r31
+        \insn   $r1, $r2, $r4
+        \insn   $r8, $r16, $r0
+
+        # immediate
+        \insn   $r31, $r0, -512
+        \insn   $r0, $r31, 0
+        \insn   $r0, $r31, 1
+        \insn   $r0, $r31, 511
+
+        # short and byte
+        \insn\().s $r0, $r31, $r1
+        \insn\().s $r0, $r31, 77
+        \insn\().b $r0, $r31, $r1
+        \insn\().b $r0, $r31, 77
+
+        .endm
+
+        .macro RegUImm insn
+        \insn   r0, r0, 0
+        \insn   r0, r0, 65535
+        \insn   r0, r31, 0
+        \insn   r0, r31, 65535
+        \insn   r31, r0, 0
+        \insn   r31, r0, 65535
+        .endm
+
+	.macro CMPOP insn	
+        # reg-reg
+        \insn   $r0, $r0
+        \insn   $r31, $r0
+        \insn   $r0, $r31
+
+        # immediate
+        \insn   $r0, -512
+        \insn   $r31, 0
+        \insn   $r31, 1
+        \insn   $r31, 511
+
+        # short and byte
+        \insn\().s $r31, $r1
+        \insn\().s $r31, 77
+        \insn\().b $r31, $r1
+        \insn\().b $r31, 77
+
+        .endm
+
+        .section .data
+dalabel:
+        .long   0
+
+        .section .text
+pmlabel:
+
+        TERNARY add
+        TERNARY sub
+        TERNARY and
+        TERNARY or
+        TERNARY xor
+        TERNARY xnor
+        TERNARY ashl
+        TERNARY lshr
+        TERNARY ashr
+        TERNARY ror
+        TERNARY ldl
+        TERNARY bins
+        TERNARY bexts
+        TERNARY bextu
+        TERNARY flip
+
+        CMPOP   addcc
+        CMPOP   cmp
+        CMPOP   tst
+        CMPOP   btst
+
+        # LDI, STI, EXI
+        ldi.l   $r0,$r31,-128
+        ldi.l   $r31,$r0,127
+        ldi.s   $r0,$r31,-128
+        ldi.s   $r0,$r31,127
+        ldi.b   $r31,$r0,-128
+        ldi.b   $r31,$r0,127
+        sti.l   $r31,-128,$r0
+        sti.l   $r0,127,$r31
+        sti.s   $r31,-128,$r0
+        sti.s   $r31,127,$r0
+        sti.b   $r0,-128,$r31
+        sti.b   $r0,127,$r31
+        exi.l   $r0,$r31,-128
+        exi.l   $r31,$r0,127
+        exi.s   $r0,$r31,-128
+        exi.s   $r0,$r31,127
+        exi.b   $r31,$r0,-128
+        exi.b   $r31,$r0,127
+
+        # LPM, LPMI
+        lpm.l   $r0,pmlabel
+        lpm.s   $r16,pmlabel
+        lpm.b   $r31,pmlabel
+        lpmi.l  $r0,$r1,-128
+        lpmi.s  $r16,$r1,127
+        lpmi.b  $r31,$r1,-128
+
+        # JMP
+        jmp     pmlabel
+        jmpi    $r16
+        jmpx    31,$r28,1,pmlabel
+        jmpc    nz,pmlabel
+
+        # CALL
+        call    pmlabel
+        calli   $r16
+        callx   31,$r28,1,pmlabel
+        callc   nz,pmlabel
+
+        # PUSH, POP
+        push    $r0
+        push    $r16
+        push    $r31
+        pop     $r0
+        pop     $r16
+        pop     $r31
+
+        # LINK,UNLINK
+        link    $r0,0
+        link    $r16,65535
+        link    $r31,1017
+        unlink  $r0
+        unlink  $r16
+        unlink  $r31
+
+        # RETURN,RETI
+        return
+        reti
+
+        # LDA,STA,EXA
+        lda.l   $r0,dalabel
+        lda.s   $r16,dalabel
+        lda.b   $r31,dalabel
+        sta.l   dalabel,$r0
+        sta.s   dalabel,$r16
+        sta.b   dalabel,$r31
+        exa.l   $r0,dalabel
+        exa.s   $r16,dalabel
+        exa.b   $r31,dalabel
+
+        # LDK
+        ldk     $r0,-524288
+        ldk     $r0,524287
+        ldk     $r0,0
+        
+        move    $r0,$r31
+        move    $r31,$r0
+
+        TERNARY udiv
+        TERNARY umod
+        TERNARY div
+        TERNARY mod
+        TERNARY strcmp
+        TERNARY memcpy
+        TERNARY memset
+        TERNARY mul
+        TERNARY muluh
+        TERNARY streamin
+        TERNARY streamini
+        TERNARY streamout
+        TERNARY streamouti
+
+        strlen.l $r0,$r31
+        strlen.l $r31,$r0
+        strlen.s $r0,$r31
+        strlen.s $r31,$r0
+        strlen.b $r0,$r31
+        strlen.b $r31,$r0
+        stpcpy.l $r0,$r31
+        stpcpy.l $r31,$r0
+        stpcpy.s $r0,$r31
+        stpcpy.s $r31,$r0
+        stpcpy.b $r0,$r31
+        stpcpy.b $r31,$r0
diff --git a/gas/testsuite/go b/gas/testsuite/go
new file mode 100644
index 0000000..13bac17
--- /dev/null
+++ b/gas/testsuite/go
@@ -0,0 +1,7 @@
+cd ../../../build/binutils-gdb || exit
+make check-gas
+exit
+# ./gas/testsuite/gas.log
+cd gas/testsuite
+../as-new   -o dump.o /home/james/v3/gnu/binutils-gdb/gas/testsuite/gas/ft32/insn.s
+/home/james/v3/gnu/build/binutils-gdb/gas/testsuite/../../binutils/objdump  -d dump.o > /tmp/0
diff --git a/include/dis-asm.h b/include/dis-asm.h
index f9e9ee5..198a6f8 100644
--- a/include/dis-asm.h
+++ b/include/dis-asm.h
@@ -236,6 +236,7 @@ extern int print_insn_dlx 		(bfd_vma, disassemble_info *);
 extern int print_insn_epiphany		(bfd_vma, disassemble_info *);
 extern int print_insn_fr30		(bfd_vma, disassemble_info *);
 extern int print_insn_frv		(bfd_vma, disassemble_info *);
+extern int print_insn_ft32  		(bfd_vma, disassemble_info *);
 extern int print_insn_h8300		(bfd_vma, disassemble_info *);
 extern int print_insn_h8300h		(bfd_vma, disassemble_info *);
 extern int print_insn_h8300s		(bfd_vma, disassemble_info *);
diff --git a/include/elf/common.h b/include/elf/common.h
index a564cae..94a4cbf 100644
--- a/include/elf/common.h
+++ b/include/elf/common.h
@@ -302,6 +302,7 @@
 #define EM_INTEL208	208	/* Reserved by Intel */
 #define EM_INTEL209	209	/* Reserved by Intel */
 #define EM_VISIUM	221	/* Controls and Data Services VISIUMcore processor */
+#define EM_FT32         222     /* FTDI Chip FT32 high performance 32-bit RISC architecture */
 
 /* If it is necessary to assign new unofficial EM_* values, please pick large
    random numbers (0x8523, 0xa7f2, etc.) to minimize the chances of collision
@@ -396,6 +397,7 @@
 
 #define EM_MOXIE                0xFEED  /* Moxie */
 
+
 /* Old Sunplus S+core7 backend magic number. Written in the absence of an ABI.  */
 #define EM_SCORE_OLD            95
 
diff --git a/include/elf/ft32.h b/include/elf/ft32.h
new file mode 100644
index 0000000..392ed22
--- /dev/null
+++ b/include/elf/ft32.h
@@ -0,0 +1,37 @@
+/* ft32 ELF support for BFD.
+   Copyright 2009, 2010 Free Software Foundation, Inc.
+
+   This file is part of BFD, the Binary File Descriptor library.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+#ifndef _ELF_FT32_H
+#define _ELF_FT32_H
+
+#include "elf/reloc-macros.h"
+
+/* Relocation types.  */
+START_RELOC_NUMBERS (elf_ft32_reloc_type)
+  RELOC_NUMBER (R_FT32_NONE, 0)
+  RELOC_NUMBER (R_FT32_32, 1)
+  RELOC_NUMBER (R_FT32_16, 2)
+  RELOC_NUMBER (R_FT32_8,  3)
+  RELOC_NUMBER (R_FT32_10, 4)
+  RELOC_NUMBER (R_FT32_20, 5)
+  RELOC_NUMBER (R_FT32_17, 6)
+  RELOC_NUMBER (R_FT32_18, 7)
+END_RELOC_NUMBERS (R_FT32_max)
+
+#endif /* _ELF_FT32_H */
diff --git a/include/opcode/ft32.h b/include/opcode/ft32.h
new file mode 100644
index 0000000..9dfb2d4
--- /dev/null
+++ b/include/opcode/ft32.h
@@ -0,0 +1,100 @@
+/* Definitions for decoding the ft32 opcode table.
+   Copyright 2013 Free Software Foundation, Inc.
+   Contributed by FTDI (support@ftdichip.com)
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+02110-1301, USA.  */
+
+typedef struct ft32_opc_info_t
+{
+  const char *name;
+  int dw;
+  unsigned int mask;
+  unsigned int bits;
+  int fields;
+} ft32_opc_info_t;
+
+#define FT32_PAT_ALUOP    0x08
+#define FT32_PAT_LDA      0x18
+#define FT32_PAT_TOCI     0x01
+#define FT32_PAT_CMPOP    0x0b
+#define FT32_PAT_STA      0x17
+#define FT32_PAT_EXA      0x07
+#define FT32_PAT_LDK      0x0c
+#define FT32_PAT_FFUOP    0x1e
+#define FT32_PAT_LDI      0x15
+#define FT32_PAT_STI      0x16
+#define FT32_PAT_EXI      0x1d
+#define FT32_PAT_POP      0x11
+#define FT32_PAT_LPM      0x0d
+#define FT32_PAT_LINK     0x12
+#define FT32_PAT_TOC      0x00
+#define FT32_PAT_PUSH     0x10
+#define FT32_PAT_RETURN   0x14
+#define FT32_PAT_UNLINK   0x13
+#define FT32_PAT_LPMI     0x19
+
+#define FT32_FLD_CBCRCV (1 << 0)
+#define FT32_FLD_INT (1 << 1)
+#define FT32_FLD_INT_BIT 26
+#define FT32_FLD_INT_SIZ 1
+#define FT32_FLD_DW (1 << 2)
+#define FT32_FLD_DW_BIT 25
+#define FT32_FLD_DW_SIZ 2
+#define FT32_FLD_CB (1 << 3)
+#define FT32_FLD_CB_BIT 22
+#define FT32_FLD_CB_SIZ 5
+#define FT32_FLD_R_D (1 << 4)
+#define FT32_FLD_R_D_BIT 20
+#define FT32_FLD_R_D_SIZ 5
+#define FT32_FLD_CR (1 << 5)
+#define FT32_FLD_CR_BIT 20
+#define FT32_FLD_CR_SIZ 2
+#define FT32_FLD_CV (1 << 6)
+#define FT32_FLD_CV_BIT 19
+#define FT32_FLD_CV_SIZ 1
+#define FT32_FLD_BT (1 << 7)
+#define FT32_FLD_BT_BIT 18
+#define FT32_FLD_BT_SIZ 1
+#define FT32_FLD_R_1 (1 << 8)
+#define FT32_FLD_R_1_BIT 15
+#define FT32_FLD_R_1_SIZ 5
+#define FT32_FLD_RIMM (1 << 9)
+#define FT32_FLD_RIMM_BIT 4
+#define FT32_FLD_RIMM_SIZ 11
+#define FT32_FLD_R_2 (1 << 10)
+#define FT32_FLD_R_2_BIT 4
+#define FT32_FLD_R_2_SIZ 5
+#define FT32_FLD_K20 (1 << 11)
+#define FT32_FLD_K20_BIT 0
+#define FT32_FLD_K20_SIZ 20
+#define FT32_FLD_PA (1 << 12)
+#define FT32_FLD_PA_BIT 0
+#define FT32_FLD_PA_SIZ 18
+#define FT32_FLD_AA (1 << 13)
+#define FT32_FLD_AA_BIT 0
+#define FT32_FLD_AA_SIZ 17
+#define FT32_FLD_K16 (1 << 14)
+#define FT32_FLD_K16_BIT 0
+#define FT32_FLD_K16_SIZ 16
+#define FT32_FLD_K8 (1 << 15)
+#define FT32_FLD_K8_BIT 0
+#define FT32_FLD_K8_SIZ 8
+#define FT32_FLD_AL (1 << 16)
+#define FT32_FLD_AL_BIT 0
+#define FT32_FLD_AL_SIZ 4
+
+#define FT32_FLD_R_D_POST (1 << 17)
+#define FT32_FLD_R_1_POST (1 << 18)
diff --git a/ld/Makefile.am b/ld/Makefile.am
index 68ff02f..18bcf8b 100644
--- a/ld/Makefile.am
+++ b/ld/Makefile.am
@@ -228,6 +228,7 @@ ALL_EMULATION_SOURCES = \
 	eelf32fr30.c \
 	eelf32frv.c \
 	eelf32frvfd.c \
+	eelf32ft32.c \
 	eelf32i370.c \
 	eelf32ip2k.c \
 	eelf32iq10.c \
@@ -1053,6 +1054,9 @@ eelf32frvfd.c: $(srcdir)/emulparams/elf32frvfd.sh \
   $(srcdir)/emulparams/elf32frv.sh \
   $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
 
+eelf32ft32.c: $(srcdir)/emulparams/elf32ft32.sh \
+  $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+
 eelf32i370.c: $(srcdir)/emulparams/elf32i370.sh \
   $(ELF_DEPS) $(srcdir)/scripttempl/elfi370.sc ${GEN_DEPENDS}
 
diff --git a/ld/Makefile.in b/ld/Makefile.in
index 311452d..a3011c9 100644
--- a/ld/Makefile.in
+++ b/ld/Makefile.in
@@ -536,6 +536,7 @@ ALL_EMULATION_SOURCES = \
 	eelf32fr30.c \
 	eelf32frv.c \
 	eelf32frvfd.c \
+	eelf32ft32.c \
 	eelf32i370.c \
 	eelf32ip2k.c \
 	eelf32iq10.c \
@@ -1146,6 +1147,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32fr30.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32frv.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32frvfd.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ft32.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32i370.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ip2k.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32iq10.Po@am__quote@
@@ -2495,6 +2497,9 @@ eelf32frvfd.c: $(srcdir)/emulparams/elf32frvfd.sh \
   $(srcdir)/emulparams/elf32frv.sh \
   $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
 
+eelf32ft32.c: $(srcdir)/emulparams/elf32ft32.sh \
+  $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+
 eelf32i370.c: $(srcdir)/emulparams/elf32i370.sh \
   $(ELF_DEPS) $(srcdir)/scripttempl/elfi370.sc ${GEN_DEPENDS}
 
diff --git a/ld/configure.tgt b/ld/configure.tgt
index ef876b2..f16c845 100644
--- a/ld/configure.tgt
+++ b/ld/configure.tgt
@@ -744,6 +744,8 @@ tilegxbe-*-*)		targ_emul=elf64tilegx_be
 			targ_extra_emuls="elf64tilegx elf32tilegx elf32tilegx_be"
 			targ_extra_libpath=$targ_extra_emuls ;;
 tilepro-*-*)		targ_emul=elf32tilepro ;;
+ft32-*-*)		targ_emul=elf32ft32
+			;;
 v850*-*-*)		targ_emul=v850_rh850
 			targ_extra_emuls=v850
 			;;
diff --git a/ld/emulparams/elf32ft32.sh b/ld/emulparams/elf32ft32.sh
new file mode 100644
index 0000000..4b74f9b
--- /dev/null
+++ b/ld/emulparams/elf32ft32.sh
@@ -0,0 +1,8 @@
+SCRIPT_NAME=ft32
+TEMPLATE_NAME=generic
+EXTRA_EM_FILE=genelf
+OUTPUT_FORMAT="elf32-ft32"
+TEXT_START_ADDR=0x0000
+MAXPAGESIZE="CONSTANT (MAXPAGESIZE)"
+ARCH=ft32
+EMBEDDED=yes
diff --git a/ld/scripttempl/ft32.sc b/ld/scripttempl/ft32.sc
new file mode 100644
index 0000000..8ceee44
--- /dev/null
+++ b/ld/scripttempl/ft32.sc
@@ -0,0 +1,62 @@
+TORS=".tors :
+  {
+    ___ctors = . ;
+    *(.ctors)
+    ___ctors_end = . ;
+    ___dtors = . ;
+    *(.dtors)
+    ___dtors_end = . ;
+    . = ALIGN(4);
+  } > ram"
+
+cat <<EOF
+OUTPUT_FORMAT("${OUTPUT_FORMAT}")
+OUTPUT_ARCH(${ARCH})
+${LIB_SEARCH_DIRS}
+
+MEMORY
+{
+  flash     (rx)   : ORIGIN = 0, LENGTH = 256K
+  ram       (rw!x) : ORIGIN = 0x800000, LENGTH = 64K
+}
+SECTIONS
+{
+  .text :
+  {
+    *(.text*)
+    *(.strings)
+    *(._pm*)
+    *(.init)
+    *(.fini)
+    ${RELOCATING+ _etext = . ; }
+    . = ALIGN(4);
+  } ${RELOCATING+ > flash}
+  ${CONSTRUCTING+${TORS}}
+  .data	  : AT (ADDR (.text) + SIZEOF (.text))
+  {
+    *(.data)
+    *(.rodata)
+    *(.rodata*)
+    ${RELOCATING+ _edata = . ; }
+  } ${RELOCATING+ > ram}
+  .bss  SIZEOF(.data) + ADDR(.data) :
+  {
+    ${RELOCATING+ _bss_start = . ; }
+    *(.bss)
+    *(COMMON)
+    ${RELOCATING+ _end = . ;  }
+  } ${RELOCATING+ > ram}
+
+  ${RELOCATING+ __data_load_start = LOADADDR(.data); }
+  ${RELOCATING+ __data_load_end = __data_load_start + SIZEOF(.data); }
+
+  .stab 0 ${RELOCATING+(NOLOAD)} :
+  {
+    *(.stab)
+  }
+  .stabstr 0 ${RELOCATING+(NOLOAD)} :
+  {
+    *(.stabstr)
+  }
+}
+EOF
diff --git a/opcodes/Makefile.am b/opcodes/Makefile.am
index 320f8bb..4adc6ff 100644
--- a/opcodes/Makefile.am
+++ b/opcodes/Makefile.am
@@ -135,6 +135,8 @@ TARGET_LIBOPCODES_CFILES = \
 	frv-dis.c \
 	frv-ibld.c \
 	frv-opc.c \
+	ft32-dis.c \
+	ft32-opc.c \
 	h8300-dis.c \
 	h8500-dis.c \
 	hppa-dis.c \
diff --git a/opcodes/Makefile.in b/opcodes/Makefile.in
index 31876ca..d9ddefa 100644
--- a/opcodes/Makefile.in
+++ b/opcodes/Makefile.in
@@ -408,6 +408,8 @@ TARGET_LIBOPCODES_CFILES = \
 	frv-dis.c \
 	frv-ibld.c \
 	frv-opc.c \
+	ft32-dis.c \
+	ft32-opc.c \
 	h8300-dis.c \
 	h8500-dis.c \
 	hppa-dis.c \
@@ -810,6 +812,8 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/frv-dis.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/frv-ibld.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/frv-opc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft32-dis.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft32-opc.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/h8300-dis.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/h8500-dis.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hppa-dis.Plo@am__quote@
diff --git a/opcodes/configure b/opcodes/configure
index c97bdf6..cd3aa83 100755
--- a/opcodes/configure
+++ b/opcodes/configure
@@ -12549,6 +12549,7 @@ if test x${all_targets} = xfalse ; then
 	bfd_dlx_arch)		ta="$ta dlx-dis.lo" ;;
 	bfd_fr30_arch)		ta="$ta fr30-asm.lo fr30-desc.lo fr30-dis.lo fr30-ibld.lo fr30-opc.lo" using_cgen=yes ;;
 	bfd_frv_arch)		ta="$ta frv-asm.lo frv-desc.lo frv-dis.lo frv-ibld.lo frv-opc.lo" using_cgen=yes ;;
+	bfd_ft32_arch)		ta="$ta ft32-opc.lo ft32-dis.lo" ;;
 	bfd_moxie_arch)		ta="$ta moxie-dis.lo moxie-opc.lo" ;;
 	bfd_h8300_arch)		ta="$ta h8300-dis.lo" ;;
 	bfd_h8500_arch)		ta="$ta h8500-dis.lo" ;;
diff --git a/opcodes/configure.ac b/opcodes/configure.ac
index 74bccff..eab16d6 100644
--- a/opcodes/configure.ac
+++ b/opcodes/configure.ac
@@ -266,6 +266,7 @@ if test x${all_targets} = xfalse ; then
 	bfd_dlx_arch)		ta="$ta dlx-dis.lo" ;;
 	bfd_fr30_arch)		ta="$ta fr30-asm.lo fr30-desc.lo fr30-dis.lo fr30-ibld.lo fr30-opc.lo" using_cgen=yes ;;
 	bfd_frv_arch)		ta="$ta frv-asm.lo frv-desc.lo frv-dis.lo frv-ibld.lo frv-opc.lo" using_cgen=yes ;;
+	bfd_ft32_arch)		ta="$ta ft32-opc.lo ft32-dis.lo" ;;
 	bfd_moxie_arch)		ta="$ta moxie-dis.lo moxie-opc.lo" ;;
 	bfd_h8300_arch)		ta="$ta h8300-dis.lo" ;;
 	bfd_h8500_arch)		ta="$ta h8500-dis.lo" ;;
diff --git a/opcodes/disassemble.c b/opcodes/disassemble.c
index 0c1d7e0..f47a190 100644
--- a/opcodes/disassemble.c
+++ b/opcodes/disassemble.c
@@ -37,6 +37,7 @@
 #define ARCH_epiphany
 #define ARCH_fr30
 #define ARCH_frv
+#define ARCH_ft32
 #define ARCH_h8300
 #define ARCH_h8500
 #define ARCH_hppa
@@ -445,6 +446,11 @@ disassembler (abfd)
       disassemble = print_insn_tic80;
       break;
 #endif
+#ifdef ARCH_ft32
+    case bfd_arch_ft32:
+      disassemble = print_insn_ft32;
+      break;
+#endif
 #ifdef ARCH_v850
     case bfd_arch_v850:
     case bfd_arch_v850_rh850:
diff --git a/opcodes/ft32-dis.c b/opcodes/ft32-dis.c
new file mode 100644
index 0000000..477f557
--- /dev/null
+++ b/opcodes/ft32-dis.c
@@ -0,0 +1,177 @@
+/* Disassemble ft32 instructions.
+   Copyright 2013 Free Software Foundation, Inc.
+   Contributed by FTDI (support@ftdichip.com)
+
+   This file is part of the GNU opcodes library.
+
+   This library is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   It is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "sysdep.h"
+#include <stdio.h>
+#define STATIC_TABLE
+#define DEFINE_TABLE
+
+#include "opcode/ft32.h"
+#include "dis-asm.h"
+
+extern const ft32_opc_info_t ft32_opc_info[128];
+
+static fprintf_ftype fpr;
+static void *stream;
+
+int
+print_insn_ft32 (bfd_vma addr, struct disassemble_info *info)
+{
+  int status;
+  stream = info->stream;
+  bfd_byte buffer[4];
+  unsigned int iword;
+  const ft32_opc_info_t *oo;
+
+  fpr = info->fprintf_func;
+
+  if ((status = info->read_memory_func (addr, buffer, 4, info)))
+    goto fail;
+
+  iword = bfd_getl32 (buffer);
+
+  for (oo = ft32_opc_info; oo->name; oo++)
+    if ((iword & oo->mask) == oo->bits)
+      break;
+
+  if (oo->name)
+    {
+      int f = oo->fields;
+      int imm;
+
+      fpr (stream, "%08x %s", iword, oo->name);
+      if (oo->dw)
+        {
+          fpr (stream, ".%c ", "bsl"[(iword >> FT32_FLD_DW_BIT) & 3]);
+        }
+      else
+        {
+          fpr (stream, " ");
+        }
+
+      while (f)
+        {
+          int lobit = f & -f;
+          if (f & lobit)
+            {
+              switch (lobit)
+              {
+              case  FT32_FLD_CBCRCV:
+                // imm is {CB, CV}
+                imm = ((iword >> FT32_FLD_CB_BIT) & ((1 << FT32_FLD_CB_SIZ) - 1)) << 4;
+                imm |= ((iword >> FT32_FLD_CV_BIT) & ((1 << FT32_FLD_CV_SIZ) - 1));
+                switch (imm)
+                {
+                case 0x00: fpr(stream, "nz");  break;
+                case 0x01: fpr(stream, "z");   break;
+                case 0x10: fpr(stream, "ae");  break;
+                case 0x11: fpr(stream, "b");   break;
+                case 0x20: fpr(stream, "no");  break;
+                case 0x21: fpr(stream, "o");   break;
+                case 0x30: fpr(stream, "ns");  break;
+                case 0x31: fpr(stream, "s");   break;
+                case 0x40: fpr(stream, "lt");  break;
+                case 0x41: fpr(stream, "gte"); break;
+                case 0x50: fpr(stream, "lte"); break;
+                case 0x51: fpr(stream, "gt");  break;
+                case 0x60: fpr(stream, "be");  break;
+                case 0x61: fpr(stream, "a");   break;
+                default:   fpr(stream, "%d,$r30,%d", (imm >> 4), (imm & 1)); break;
+                }
+                break;
+              case  FT32_FLD_CB:
+                imm = (iword >> FT32_FLD_CB_BIT) & ((1 << FT32_FLD_CB_SIZ) - 1);
+                fpr(stream, "%d", imm);
+                break;
+              case  FT32_FLD_R_D:
+                fpr(stream, "$r%d", (iword >> FT32_FLD_R_D_BIT) & 0x1f);
+                break;
+              case  FT32_FLD_CR:
+                imm = (iword >> FT32_FLD_CR_BIT) & ((1 << FT32_FLD_CR_SIZ) - 1);
+                fpr(stream, "$r%d", 28 + imm);
+                break;
+              case  FT32_FLD_CV:
+                imm = (iword >> FT32_FLD_CV_BIT) & ((1 << FT32_FLD_CV_SIZ) - 1);
+                fpr(stream, "%d", imm);
+                break;
+              case  FT32_FLD_R_1:
+                fpr(stream, "$r%d", (iword >> FT32_FLD_R_1_BIT) & 0x1f);
+                break;
+              case  FT32_FLD_RIMM:
+                imm = (iword >> FT32_FLD_RIMM_BIT) & ((1 << FT32_FLD_RIMM_SIZ) - 1);
+                if (imm & 0x400)
+                  info->print_address_func ((bfd_vma) imm & 0x1ff, info);
+                else
+                  fpr(stream, "$r%d", imm & 0x1f);
+                break;
+              case  FT32_FLD_R_2:
+                fpr(stream, "$r%d", (iword >> FT32_FLD_R_2_BIT) & 0x1f);
+                break;
+              case  FT32_FLD_K20:
+                imm = iword & ((1 << FT32_FLD_K20_SIZ) - 1);
+                info->print_address_func ((bfd_vma) imm, info);
+                break;
+              case  FT32_FLD_PA:
+                imm = (iword & ((1 << FT32_FLD_PA_SIZ) - 1)) << 2;
+                info->print_address_func ((bfd_vma) imm, info);
+                break;
+              case  FT32_FLD_AA:
+                imm = iword & ((1 << FT32_FLD_AA_SIZ) - 1);
+                info->print_address_func ((bfd_vma) imm, info);
+                break;
+                break;
+              case  FT32_FLD_K16:
+                imm = iword & ((1 << FT32_FLD_K16_SIZ) - 1);
+                info->print_address_func ((bfd_vma) imm, info);
+                break;
+              case  FT32_FLD_K8:
+                imm = iword & ((1 << FT32_FLD_K8_SIZ) - 1);
+                info->print_address_func ((bfd_vma) imm, info);
+                break;
+                break;
+              case  FT32_FLD_R_D_POST:
+                fpr(stream, "$r%d", (iword >> FT32_FLD_R_D_BIT) & 0x1f);
+                break;
+              case  FT32_FLD_R_1_POST:
+                fpr(stream, "$r%d", (iword >> FT32_FLD_R_1_BIT) & 0x1f);
+                break;
+              default:
+                break;
+              }
+              f &= ~lobit;
+              if (f)
+                {
+                  fpr(stream, ",");
+                }
+            }
+        }
+    }
+    else
+    {
+      fpr (stream, "%08x!", iword);
+    }
+
+  return 4;
+
+ fail:
+  info->memory_error_func (status, addr, info);
+  return -1;
+}
diff --git a/opcodes/ft32-opc.c b/opcodes/ft32-opc.c
new file mode 100644
index 0000000..84cfe11
--- /dev/null
+++ b/opcodes/ft32-opc.c
@@ -0,0 +1,88 @@
+/* ft32-opc.c -- Definitions for ft32 opcodes.
+   Copyright 2013 Free Software Foundation, Inc.
+   Contributed by FTDI (support@ftdichip.com)
+
+   This file is part of the GNU opcodes library.
+
+   This library is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   It is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this file; see the file COPYING.  If not, write to the
+   Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "sysdep.h"
+#include "opcode/ft32.h"
+
+const ft32_opc_info_t ft32_opc_info[] =
+{
+{       "nop", 0, 0xffffffffU, 0x40004000U, 0},
+{      "move", 1, 0xf8007fffU, 0x40004000U, FT32_FLD_R_D|FT32_FLD_R_1},
+{  "streamin", 1, 0xf800000fU, 0xf000000cU, FT32_FLD_R_D|FT32_FLD_R_1|FT32_FLD_RIMM},
+{       "ldi", 1, 0xf8000000U, 0xa8000000U, FT32_FLD_R_D|FT32_FLD_R_1|FT32_FLD_K8},
+{       "exi", 1, 0xf8000000U, 0xe8000000U, FT32_FLD_R_D|FT32_FLD_R_1|FT32_FLD_K8},
+{    "return", 0, 0xfc000000U, 0xa0000000U, 0},
+{        "or", 1, 0xf800000fU, 0x40000005U, FT32_FLD_R_D|FT32_FLD_R_1|FT32_FLD_RIMM},
+{       "pop", 1, 0xf8000000U, 0x88000000U, FT32_FLD_R_D},
+{       "sta", 1, 0xf8000000U, 0xb8000000U, FT32_FLD_AA|FT32_FLD_R_D_POST},
+{       "xor", 1, 0xf800000fU, 0x40000006U, FT32_FLD_R_D|FT32_FLD_R_1|FT32_FLD_RIMM},
+{    "memcpy", 1, 0xf800000fU, 0xf0000005U, FT32_FLD_R_D|FT32_FLD_R_1|FT32_FLD_RIMM},
+{    "strlen", 1, 0xf8007fffU, 0xf0004006U, FT32_FLD_R_D|FT32_FLD_R_1},
+{       "cmp", 1, 0xf9f0000fU, 0x59e00002U, FT32_FLD_R_1|FT32_FLD_RIMM},
+{      "btst", 1, 0xf9f0000fU, 0x59e0000cU, FT32_FLD_R_1|FT32_FLD_RIMM},
+{      "link", 0, 0xfe000000U, 0x94000000U, FT32_FLD_R_D|FT32_FLD_K16},
+{      "call", 0, 0xfffc0000U, 0x00340000U, FT32_FLD_PA},
+{     "callc", 0, 0xf8340000U, 0x00240000U, FT32_FLD_CBCRCV|FT32_FLD_PA},
+{     "callx", 0, 0xf8040000U, 0x00040000U, FT32_FLD_CR|FT32_FLD_CB|FT32_FLD_CV|FT32_FLD_PA},
+{ "streamini", 1, 0xf800000fU, 0xf000000dU, FT32_FLD_R_D|FT32_FLD_R_1|FT32_FLD_RIMM},
+{       "lda", 1, 0xf8000000U, 0xc0000000U, FT32_FLD_R_D|FT32_FLD_AA},
+{       "exa", 1, 0xf8000000U, 0x38000000U, FT32_FLD_R_D|FT32_FLD_AA},
+{    "unlink", 0, 0xf8000000U, 0x98000000U, FT32_FLD_R_D},
+{     "calli", 0, 0xfffc0000U, 0x08340000U, FT32_FLD_R_2},
+{    "stpcpy", 1, 0xf8007fffU, 0xf000400aU, FT32_FLD_R_D|FT32_FLD_R_1},
+{       "jmp", 0, 0xfffc0000U, 0x00300000U, FT32_FLD_PA},
+{    "strcmp", 1, 0xf800000fU, 0xf0000004U, FT32_FLD_R_D|FT32_FLD_R_1|FT32_FLD_RIMM},
+{       "mul", 1, 0xf800000fU, 0xf0000008U, FT32_FLD_R_D|FT32_FLD_R_1|FT32_FLD_RIMM},
+{      "push", 1, 0xf8000000U, 0x80000000U, FT32_FLD_R_1},
+{       "sti", 1, 0xf8000000U, 0xb0000000U, FT32_FLD_R_D|FT32_FLD_K8|FT32_FLD_R_1_POST},
+{       "mod", 1, 0xf800000fU, 0xf0000003U, FT32_FLD_R_D|FT32_FLD_R_1|FT32_FLD_RIMM},
+{      "umod", 1, 0xf800000fU, 0xf0000001U, FT32_FLD_R_D|FT32_FLD_R_1|FT32_FLD_RIMM},
+{     "addcc", 1, 0xf9f0000fU, 0x59e00000U, FT32_FLD_R_1|FT32_FLD_RIMM},
+{ "streamout", 1, 0xf800000fU, 0xf000000eU, FT32_FLD_R_D|FT32_FLD_R_1|FT32_FLD_RIMM},
+{      "lpmi", 1, 0xf8000000U, 0xc8000000U, FT32_FLD_R_D|FT32_FLD_R_1|FT32_FLD_K8},
+{      "udiv", 1, 0xf800000fU, 0xf0000000U, FT32_FLD_R_D|FT32_FLD_R_1|FT32_FLD_RIMM},
+{       "sub", 1, 0xf800000fU, 0x40000002U, FT32_FLD_R_D|FT32_FLD_R_1|FT32_FLD_RIMM},
+{      "lshr", 1, 0xf800000fU, 0x40000009U, FT32_FLD_R_D|FT32_FLD_R_1|FT32_FLD_RIMM},
+{       "tst", 1, 0xf9f0000fU, 0x59e00004U, FT32_FLD_R_1|FT32_FLD_RIMM},
+{      "xnor", 1, 0xf800000fU, 0x40000007U, FT32_FLD_R_D|FT32_FLD_R_1|FT32_FLD_RIMM},
+{     "muluh", 1, 0xf800000fU, 0xf0000009U, FT32_FLD_R_D|FT32_FLD_R_1|FT32_FLD_RIMM},
+{       "and", 1, 0xf800000fU, 0x40000004U, FT32_FLD_R_D|FT32_FLD_R_1|FT32_FLD_RIMM},
+{       "add", 1, 0xf800000fU, 0x40000000U, FT32_FLD_R_D|FT32_FLD_R_1|FT32_FLD_RIMM},
+{       "ror", 1, 0xf800000fU, 0x40000001U, FT32_FLD_R_D|FT32_FLD_R_1|FT32_FLD_RIMM},
+{       "ldl", 1, 0xf800000fU, 0x40000003U, FT32_FLD_R_D|FT32_FLD_R_1|FT32_FLD_RIMM},
+{      "bins", 1, 0xf800000fU, 0x4000000bU, FT32_FLD_R_D|FT32_FLD_R_1|FT32_FLD_RIMM},
+{     "bexts", 1, 0xf800000fU, 0x4000000cU, FT32_FLD_R_D|FT32_FLD_R_1|FT32_FLD_RIMM},
+{     "bextu", 1, 0xf800000fU, 0x4000000dU, FT32_FLD_R_D|FT32_FLD_R_1|FT32_FLD_RIMM},
+{      "flip", 1, 0xf800000fU, 0x4000000eU, FT32_FLD_R_D|FT32_FLD_R_1|FT32_FLD_RIMM},
+{    "memset", 1, 0xf800000fU, 0xf0000007U, FT32_FLD_R_D|FT32_FLD_R_1|FT32_FLD_RIMM},
+{       "div", 1, 0xf800000fU, 0xf0000002U, FT32_FLD_R_D|FT32_FLD_R_1|FT32_FLD_RIMM},
+{       "ldk", 1, 0xf8000000U, 0x60000000U, FT32_FLD_R_D|FT32_FLD_K20},
+{      "reti", 0, 0xfc000000U, 0xa4000000U, 0},
+{      "ashr", 1, 0xf800000fU, 0x4000000aU, FT32_FLD_R_D|FT32_FLD_R_1|FT32_FLD_RIMM},
+{      "jmpi", 0, 0xfffc0000U, 0x08300000U, FT32_FLD_R_2},
+{     "jmpic", 0, 0xf8040000U, 0x08000000U, FT32_FLD_CBCRCV|FT32_FLD_R_2},
+{      "ashl", 1, 0xf800000fU, 0x40000008U, FT32_FLD_R_D|FT32_FLD_R_1|FT32_FLD_RIMM},
+{      "jmpc", 0, 0xf8340000U, 0x00200000U, FT32_FLD_CBCRCV|FT32_FLD_PA},
+{      "jmpx", 0, 0xf8040000U, 0x00000000U, FT32_FLD_CR|FT32_FLD_CB|FT32_FLD_CV|FT32_FLD_PA},
+{       "lpm", 1, 0xf8000000U, 0x68000000U, FT32_FLD_R_D|FT32_FLD_PA},
+{"streamouti", 1, 0xf800000fU, 0xf000000fU, FT32_FLD_R_D|FT32_FLD_R_1|FT32_FLD_RIMM},
+{ NULL, 0, 0, 0, 0}
+};
-- 
1.7.9.5


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