Add support for Motorola XGATE embedded CPU
authorNick Clifton <nickc@redhat.com>
Thu, 3 May 2012 13:12:08 +0000 (13:12 +0000)
committerNick Clifton <nickc@redhat.com>
Thu, 3 May 2012 13:12:08 +0000 (13:12 +0000)
57 files changed:
bfd/ChangeLog
bfd/bfd-in2.h
bfd/config.bfd
bfd/configure
bfd/configure.in
bfd/elf-bfd.h
bfd/libbfd.h
bfd/reloc.c
bfd/targets.c
binutils/ChangeLog
binutils/readelf.c
gas/ChangeLog
gas/Makefile.am
gas/Makefile.in
gas/NEWS
gas/config/tc-xgate.c [new file with mode: 0644]
gas/config/tc-xgate.h [new file with mode: 0644]
gas/configure.tgt
gas/doc/Makefile.am
gas/doc/Makefile.in
gas/doc/all.texi
gas/doc/as.texinfo
gas/doc/c-xgate.texi [new file with mode: 0644]
gas/testsuite/ChangeLog
gas/testsuite/gas/all/gas.exp
gas/testsuite/gas/xgate/abi-xgate-16-32.d [new file with mode: 0644]
gas/testsuite/gas/xgate/abi-xgate-16-64.d [new file with mode: 0644]
gas/testsuite/gas/xgate/abi-xgate-32-32.d [new file with mode: 0644]
gas/testsuite/gas/xgate/abi-xgate-32-64.d [new file with mode: 0644]
gas/testsuite/gas/xgate/abi.s [new file with mode: 0644]
gas/testsuite/gas/xgate/all_insns.d [new file with mode: 0644]
gas/testsuite/gas/xgate/all_insns.s [new file with mode: 0644]
gas/testsuite/gas/xgate/insns-dwarf2.d [new file with mode: 0644]
gas/testsuite/gas/xgate/insns.d [new file with mode: 0644]
gas/testsuite/gas/xgate/insns.s [new file with mode: 0644]
gas/testsuite/gas/xgate/xgate.exp [new file with mode: 0644]
include/ChangeLog
include/dis-asm.h
include/elf/ChangeLog
include/elf/xgate.h [new file with mode: 0644]
include/opcode/ChangeLog
include/opcode/xgate.h [new file with mode: 0644]
ld/ChangeLog
ld/Makefile.am
ld/Makefile.in
ld/NEWS
ld/configure.tgt
ld/emulparams/xgateelf.sh [new file with mode: 0644]
ld/scripttempl/elfxgate.sc [new file with mode: 0644]
opcodes/ChangeLog
opcodes/Makefile.am
opcodes/Makefile.in
opcodes/configure
opcodes/configure.in
opcodes/disassemble.c
opcodes/xgate-dis.c [new file with mode: 0644]
opcodes/xgate-opc.c [new file with mode: 0644]

index 4167a0d..733c546 100644 (file)
@@ -1,3 +1,23 @@
+2012-05-03  Sean Keys  <skeys@ipdatasys.com>
+
+       * cpu-xgate.c: New file. Added XGATE support.
+       * archures.c (bfd_architecture): Add XGATE architecture.
+       (bfd_archures_list): Add reference to XGATE architecture info.
+       * elf-bfd.h (prep_headers): Handle bfd_arch_xgate.
+       * reloc.c: Add various XGATE relocation enums.
+       * targets.c (bfd_elf32_xgate_vec): Declare and add to target vector
+       list.
+       * Makefile.am: Add support for XGATE elf.
+       * configure.in: Ditto.
+       * config.bfd: Ditto.
+       * Makefile.in: Regenerate.
+       * configure: Ditto.
+       * bfd-in2.h: Ditto.
+       * libbfd.h: Ditto.
+       Added files for XGATE relocations.
+       * elf32-xgate.c: Created minimal relocation file.
+       * elf32-xgate.h: Created minimal header file for elf32-xgate.
+
 2012-05-03  Tristan Gingold  <gingold@adacore.com>
 
        * dwarf2.c (decode_line_info): Ignore
index 17dbbe1..6b94f72 100644 (file)
@@ -2141,7 +2141,9 @@ enum bfd_architecture
   bfd_arch_xc16x,     /* Infineon's XC16X Series.               */
 #define bfd_mach_xc16x         1
 #define bfd_mach_xc16xl        2
-#define bfd_mach_xc16xs         3
+#define bfd_mach_xc16xs        3
+  bfd_arch_xgate,   /* Freescale XGATE */
+#define bfd_mach_xgate         1
   bfd_arch_xtensa,    /* Tensilica's Xtensa cores.  */
 #define bfd_mach_xtensa        1
   bfd_arch_z80,
@@ -4472,6 +4474,57 @@ to follow the 16K memory bank of 68HC12 (seen as mapped in the window).  */
 This is the 5 bits of a value.  */
   BFD_RELOC_M68HC12_5B,
 
+/* Freescale XGATE reloc.
+This reloc marks the beginning of a bra/jal instruction.  */
+  BFD_RELOC_XGATE_RL_JUMP,
+
+/* Freescale XGATE reloc.
+This reloc marks a group of several instructions that gcc generates
+and for which the linker relaxation pass can modify and/or remove
+some of them.  */
+  BFD_RELOC_XGATE_RL_GROUP,
+
+/* Freescale XGATE reloc.
+This is the 16-bit lower part of an address.  It is used for the '16-bit'
+instructions.  */
+  BFD_RELOC_XGATE_LO16,
+
+/* Freescale XGATE reloc.  */
+  BFD_RELOC_XGATE_GPAGE,
+
+/* Freescale XGATE reloc.  */
+  BFD_RELOC_XGATE_24,
+
+/* Freescale XGATE reloc.
+This is a 9-bit pc-relative reloc.  */
+  BFD_RELOC_XGATE_PCREL_9,
+
+/* Freescale XGATE reloc.
+This is a 10-bit pc-relative reloc.  */
+  BFD_RELOC_XGATE_PCREL_10,
+
+/* Freescale XGATE reloc.
+This is the 16-bit lower part of an address.  It is used for the '16-bit'
+instructions.  */
+  BFD_RELOC_XGATE_IMM8_LO,
+
+/* Freescale XGATE reloc.
+This is the 16-bit higher part of an address.  It is used for the '16-bit'
+instructions.  */
+  BFD_RELOC_XGATE_IMM8_HI,
+
+/* Freescale XGATE reloc.
+This is a 3-bit pc-relative reloc.  */
+  BFD_RELOC_XGATE_IMM3,
+
+/* Freescale XGATE reloc.
+This is a 4-bit pc-relative reloc.  */
+  BFD_RELOC_XGATE_IMM4,
+
+/* Freescale XGATE reloc.
+This is a 5-bit pc-relative reloc.  */
+  BFD_RELOC_XGATE_IMM5,
+
 /* NS CR16C Relocations.  */
   BFD_RELOC_16C_NUM08,
   BFD_RELOC_16C_NUM08_C,
index ab72cf3..3f758c0 100644 (file)
@@ -105,6 +105,7 @@ tilepro*)    targ_archs=bfd_tilepro_arch ;;
 v850*)          targ_archs=bfd_v850_arch ;;
 x86_64*)        targ_archs=bfd_i386_arch ;;
 xtensa*)        targ_archs=bfd_xtensa_arch ;;
+xgate)          targ_archs=bfd_xgate_arch ;;
 z80|r800)       targ_archs=bfd_z80_arch ;;
 z8k*)           targ_archs=bfd_z8k_arch ;;
 *)              targ_archs=bfd_${targ_cpu}_arch ;;
@@ -1576,7 +1577,12 @@ case "${targ}" in
   w65-*-*)
     targ_defvec=w65_vec
     ;;
-
+    
+  xgate-*-*)
+    targ_defvec=bfd_elf32_xgate_vec
+    targ_selvecs="bfd_elf32_xgate_vec"
+    ;;
+       
   xstormy16-*-elf)
     targ_defvec=bfd_elf32_xstormy16_vec
     ;;
index fc5c9ad..7c52478 100755 (executable)
@@ -15332,6 +15332,7 @@ do
     bfd_elf32_vax_vec)         tb="$tb elf32-vax.lo elf32.lo $elf" ;;
     bfd_elf32_xstormy16_vec)   tb="$tb elf32-xstormy16.lo elf32.lo $elf" ;;
     bfd_elf32_xc16x_vec)               tb="$tb elf32-xc16x.lo elf32.lo $elf" ;;
+    bfd_elf32_xgate_vec)       tb="$tb elf32-xgate.lo elf32.lo $elf" ;;
     bfd_elf32_xtensa_le_vec)   tb="$tb xtensa-isa.lo xtensa-modules.lo elf32-xtensa.lo elf32.lo $elf" ;;
     bfd_elf32_xtensa_be_vec)   tb="$tb xtensa-isa.lo xtensa-modules.lo elf32-xtensa.lo elf32.lo $elf" ;;
     bfd_elf64_alpha_freebsd_vec) tb="$tb elf64-alpha.lo elf64.lo $elf"; target_size=64 ;;
index 3cb4b70..47631cc 100644 (file)
@@ -818,6 +818,7 @@ do
     bfd_elf32_vax_vec)         tb="$tb elf32-vax.lo elf32.lo $elf" ;;
     bfd_elf32_xstormy16_vec)   tb="$tb elf32-xstormy16.lo elf32.lo $elf" ;;
     bfd_elf32_xc16x_vec)               tb="$tb elf32-xc16x.lo elf32.lo $elf" ;;
+    bfd_elf32_xgate_vec)       tb="$tb elf32-xgate.lo elf32.lo $elf" ;;
     bfd_elf32_xtensa_le_vec)   tb="$tb xtensa-isa.lo xtensa-modules.lo elf32-xtensa.lo elf32.lo $elf" ;;
     bfd_elf32_xtensa_be_vec)   tb="$tb xtensa-isa.lo xtensa-modules.lo elf32-xtensa.lo elf32.lo $elf" ;;
     bfd_elf64_alpha_freebsd_vec) tb="$tb elf64-alpha.lo elf64.lo $elf"; target_size=64 ;;
index 4821eaf..5af924c 100644 (file)
@@ -428,6 +428,7 @@ enum elf_target_id
   TIC6X_ELF_DATA,
   X86_64_ELF_DATA,
   XTENSA_ELF_DATA,
+  XGATE_ELF_DATA,
   TILEGX_ELF_DATA,
   TILEPRO_ELF_DATA,
   GENERIC_ELF_DATA
index ab3c897..e4acdb0 100644 (file)
@@ -2093,6 +2093,18 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
   "BFD_RELOC_M68HC11_PAGE",
   "BFD_RELOC_M68HC11_24",
   "BFD_RELOC_M68HC12_5B",
+  "BFD_RELOC_XGATE_RL_JUMP",
+  "BFD_RELOC_XGATE_RL_GROUP",
+  "BFD_RELOC_XGATE_LO16",
+  "BFD_RELOC_XGATE_GPAGE",
+  "BFD_RELOC_XGATE_24",
+  "BFD_RELOC_XGATE_PCREL_9",
+  "BFD_RELOC_XGATE_PCREL_10",
+  "BFD_RELOC_XGATE_IMM8_LO",
+  "BFD_RELOC_XGATE_IMM8_HI",
+  "BFD_RELOC_XGATE_IMM3",
+  "BFD_RELOC_XGATE_IMM4",
+  "BFD_RELOC_XGATE_IMM5",
   "BFD_RELOC_16C_NUM08",
   "BFD_RELOC_16C_NUM08_C",
   "BFD_RELOC_16C_NUM16",
index 7aa9f96..0ec1b61 100644 (file)
@@ -4979,7 +4979,69 @@ ENUM
 ENUMDOC
   Motorola 68HC12 reloc.
   This is the 5 bits of a value.
-
+ENUM
+  BFD_RELOC_XGATE_RL_JUMP
+ENUMDOC
+  Freescale XGATE reloc.
+  This reloc marks the beginning of a bra/jal instruction.
+ENUM
+  BFD_RELOC_XGATE_RL_GROUP
+ENUMDOC
+  Freescale XGATE reloc.
+  This reloc marks a group of several instructions that gcc generates
+  and for which the linker relaxation pass can modify and/or remove
+  some of them.
+ENUM
+  BFD_RELOC_XGATE_LO16
+ENUMDOC
+  Freescale XGATE reloc.
+  This is the 16-bit lower part of an address.  It is used for the '16-bit'
+  instructions.
+ENUM
+  BFD_RELOC_XGATE_GPAGE
+ENUMDOC
+  Freescale XGATE reloc.
+ENUM
+  BFD_RELOC_XGATE_24
+ENUMDOC
+  Freescale XGATE reloc.
+ENUM
+  BFD_RELOC_XGATE_PCREL_9
+ENUMDOC
+  Freescale XGATE reloc.
+  This is a 9-bit pc-relative reloc.
+ENUM
+  BFD_RELOC_XGATE_PCREL_10
+ENUMDOC
+  Freescale XGATE reloc.
+  This is a 10-bit pc-relative reloc.
+ENUM
+  BFD_RELOC_XGATE_IMM8_LO
+ENUMDOC
+  Freescale XGATE reloc.
+  This is the 16-bit lower part of an address.  It is used for the '16-bit'
+  instructions.
+ENUM
+  BFD_RELOC_XGATE_IMM8_HI
+ENUMDOC
+  Freescale XGATE reloc.
+  This is the 16-bit higher part of an address.  It is used for the '16-bit'
+  instructions.
+ENUM
+  BFD_RELOC_XGATE_IMM3
+ENUMDOC
+  Freescale XGATE reloc.
+  This is a 3-bit pc-relative reloc.
+ENUM
+  BFD_RELOC_XGATE_IMM4
+ENUMDOC
+  Freescale XGATE reloc.
+  This is a 4-bit pc-relative reloc.
+ENUM
+  BFD_RELOC_XGATE_IMM5
+ENUMDOC
+  Freescale XGATE reloc.
+  This is a 5-bit pc-relative reloc.
 ENUM
   BFD_RELOC_16C_NUM08
 ENUMX
index 78b4288..f94fed5 100644 (file)
@@ -717,6 +717,7 @@ extern const bfd_target bfd_elf32_us_cris_vec;
 extern const bfd_target bfd_elf32_v850_vec;
 extern const bfd_target bfd_elf32_vax_vec;
 extern const bfd_target bfd_elf32_xc16x_vec;
+extern const bfd_target bfd_elf32_xgate_vec;
 extern const bfd_target bfd_elf32_xstormy16_vec;
 extern const bfd_target bfd_elf32_xtensa_be_vec;
 extern const bfd_target bfd_elf32_xtensa_le_vec;
@@ -1090,6 +1091,7 @@ static const bfd_target * const _bfd_target_vector[] =
        &bfd_elf32_v850_vec,
        &bfd_elf32_vax_vec,
        &bfd_elf32_xc16x_vec,
+       &bfd_elf32_xgate_vec,
        &bfd_elf32_xstormy16_vec,
        &bfd_elf32_xtensa_be_vec,
        &bfd_elf32_xtensa_le_vec,
index 69c849a..693b100 100644 (file)
@@ -1,3 +1,7 @@
+2012-05-03  Sean Keys  <skeys@ipdatasys.com>
+
+       * readelf.c: Add support for XGATE.
+
 2012-05-02  Nick Clifton  <nickc@redhat.com>
 
        * po/vi.po: Updated Vietnamese translation.
index f42039e..937cac1 100644 (file)
 #include "elf/vax.h"
 #include "elf/x86-64.h"
 #include "elf/xc16x.h"
+#include "elf/xgate.h"
 #include "elf/xstormy16.h"
 #include "elf/xtensa.h"
 
@@ -547,6 +548,7 @@ guess_is_rela (unsigned int e_machine)
     case EM_OPENRISC:
     case EM_OR32:
     case EM_SCORE:
+    case EM_XGATE:
       return FALSE;
 
       /* Targets that use RELA relocations.  */
@@ -559,7 +561,6 @@ guess_is_rela (unsigned int e_machine)
     case EM_AVR_OLD:
     case EM_BLACKFIN:
     case EM_CR16:
-    case EM_CR16_OLD:
     case EM_CRIS:
     case EM_CRX:
     case EM_D30V:
@@ -1210,7 +1211,6 @@ dump_relocations (FILE * file,
          break;
 
        case EM_CR16:
-       case EM_CR16_OLD:
          rtype = elf_cr16_reloc_type (type);
          break;
 
@@ -1243,6 +1243,10 @@ dump_relocations (FILE * file,
        case EM_TILEPRO:
          rtype = elf_tilepro_reloc_type (type);
          break;
+
+       case EM_XGATE:
+         rtype = elf_xgate_reloc_type (type);
+         break;
        }
 
       if (rtype == NULL)
@@ -1869,7 +1873,7 @@ get_machine_name (unsigned e_machine)
     case EM_CYGNUS_M32R:
     case EM_M32R:              return "Renesas M32R (formerly Mitsubishi M32r)";
     case EM_CYGNUS_V850:
-    case EM_V850:              return "Renesas v850";
+    case EM_V850:              return "Renesas V850";
     case EM_CYGNUS_MN10300:
     case EM_MN10300:           return "mn10300";
     case EM_CYGNUS_MN10200:
@@ -1979,8 +1983,7 @@ get_machine_name (unsigned e_machine)
     case EM_CRAYNV2:           return "Cray Inc. NV2 vector architecture";
     case EM_CYGNUS_MEP:         return "Toshiba MeP Media Engine";
     case EM_CR16:
-    case EM_CR16_OLD:          return "National Semiconductor's CR16";
-    case EM_MICROBLAZE:                return "Xilinx MicroBlaze";
+    case EM_MICROBLAZE:
     case EM_MICROBLAZE_OLD:    return "Xilinx MicroBlaze";
     case EM_RL78:              return "Renesas RL78";
     case EM_RX:                        return "Renesas RX";
@@ -1995,6 +1998,7 @@ get_machine_name (unsigned e_machine)
     case EM_TILEPRO:           return "Tilera TILEPro multicore architecture family";
     case EM_TILEGX:            return "Tilera TILE-Gx multicore architecture family";
     case EM_CUDA:              return "NVIDIA CUDA architecture";
+    case EM_XGATE:             return "Motorola XGATE embedded processor";
     default:
       snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
       return buff;
@@ -9778,7 +9782,6 @@ is_32bit_abs_reloc (unsigned int reloc_type)
     case EM_CRIS:
       return reloc_type == 3; /* R_CRIS_32.  */
     case EM_CR16:
-    case EM_CR16_OLD:
       return reloc_type == 3; /* R_CR16_NUM32.  */
     case EM_CRX:
       return reloc_type == 15; /* R_CRX_NUM32.  */
@@ -9890,6 +9893,8 @@ is_32bit_abs_reloc (unsigned int reloc_type)
     case EM_XC16X:
     case EM_C166:
       return reloc_type == 3; /* R_XC16C_ABS_32.  */
+    case EM_XGATE:
+      return reloc_type == 4; /* R_XGATE_32.  */
     case EM_XSTORMY16:
       return reloc_type == 1; /* R_XSTROMY16_32.  */
     case EM_XTENSA_OLD:
@@ -10087,6 +10092,8 @@ is_16bit_abs_reloc (unsigned int reloc_type)
     case EM_CYGNUS_MN10300:
     case EM_MN10300:
       return reloc_type == 2; /* R_MN10300_16.  */
+    case EM_XGATE:
+      return reloc_type == 3; /* R_XGATE_16.  */
     default:
       return FALSE;
     }
index dfbdb28..e04a49f 100644 (file)
@@ -1,3 +1,18 @@
+2012-05-03  Sean Keys  <skeys@ipdatasys.com>
+
+       * configure, Makefile.in: Regenerate.
+       * Makefile.am (CPU_TYPES, TARGET_CPU_CFILES, TARGET_CPU_HFILES):
+       * configure.tgt: Added cpu type.
+       Added files for XGATE assembler.
+       * config/tc-xgate.c: Assembler for XGATE.
+       * config/tc-xgate.h: Header definition for assembler
+       Added files for XGATE testsuite.
+       * doc/Makefile.am (CPU_DOCS): Added XGATE file.
+       * doc/c-xgate.texi: Document XGATE and XGATE port.
+       * doc/as.texinfo: Ditto.
+       * doc/all.texi: Ditto
+       * NEWS: Mention the new support.
+
 2012-04-30  DJ Delorie  <dj@redhat.com>
 
        * config/rx-parse.y (rx_intop): Add parameter for operation size.
index 8f7b7cd..80a2fd0 100644 (file)
@@ -169,6 +169,7 @@ TARGET_CPU_CFILES = \
        config/tc-v850.c \
        config/tc-xstormy16.c \
        config/tc-xc16x.c \
+       config/tc-xgate.c \
        config/tc-xtensa.c \
        config/tc-z80.c \
        config/tc-z8k.c \
@@ -236,6 +237,7 @@ TARGET_CPU_HFILES = \
        config/tc-v850.h \
        config/tc-xstormy16.h \
        config/tc-xc16x.h \
+       config/tc-xgate.h \
        config/tc-xtensa.h \
        config/tc-z80.h \
        config/tc-z8k.h \
index 39af3e8..672de79 100644 (file)
@@ -53,6 +53,7 @@ am__aclocal_m4_deps = $(top_srcdir)/../bfd/acinclude.m4 \
        $(top_srcdir)/../config/depstand.m4 \
        $(top_srcdir)/../config/gettext-sister.m4 \
        $(top_srcdir)/../config/largefile.m4 \
+       $(top_srcdir)/../config/lcmessage.m4 \
        $(top_srcdir)/../config/lead-dot.m4 \
        $(top_srcdir)/../config/nls.m4 \
        $(top_srcdir)/../config/override.m4 \
@@ -436,6 +437,7 @@ TARGET_CPU_CFILES = \
        config/tc-v850.c \
        config/tc-xstormy16.c \
        config/tc-xc16x.c \
+       config/tc-xgate.c \
        config/tc-xtensa.c \
        config/tc-z80.c \
        config/tc-z8k.c \
@@ -503,6 +505,7 @@ TARGET_CPU_HFILES = \
        config/tc-v850.h \
        config/tc-xstormy16.h \
        config/tc-xc16x.h \
+       config/tc-xgate.h \
        config/tc-xtensa.h \
        config/tc-z80.h \
        config/tc-z8k.h \
@@ -851,6 +854,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-v850.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-vax.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-xc16x.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-xgate.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-xstormy16.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-xtensa.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-z80.Po@am__quote@
@@ -1748,6 +1752,20 @@ tc-xc16x.obj: config/tc-xc16x.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-xc16x.obj `if test -f 'config/tc-xc16x.c'; then $(CYGPATH_W) 'config/tc-xc16x.c'; else $(CYGPATH_W) '$(srcdir)/config/tc-xc16x.c'; fi`
 
+tc-xgate.o: config/tc-xgate.c
+@am__fastdepCC_TRUE@   $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tc-xgate.o -MD -MP -MF $(DEPDIR)/tc-xgate.Tpo -c -o tc-xgate.o `test -f 'config/tc-xgate.c' || echo '$(srcdir)/'`config/tc-xgate.c
+@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/tc-xgate.Tpo $(DEPDIR)/tc-xgate.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='config/tc-xgate.c' object='tc-xgate.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-xgate.o `test -f 'config/tc-xgate.c' || echo '$(srcdir)/'`config/tc-xgate.c
+
+tc-xgate.obj: config/tc-xgate.c
+@am__fastdepCC_TRUE@   $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tc-xgate.obj -MD -MP -MF $(DEPDIR)/tc-xgate.Tpo -c -o tc-xgate.obj `if test -f 'config/tc-xgate.c'; then $(CYGPATH_W) 'config/tc-xgate.c'; else $(CYGPATH_W) '$(srcdir)/config/tc-xgate.c'; fi`
+@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/tc-xgate.Tpo $(DEPDIR)/tc-xgate.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='config/tc-xgate.c' object='tc-xgate.obj' 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-xgate.obj `if test -f 'config/tc-xgate.c'; then $(CYGPATH_W) 'config/tc-xgate.c'; else $(CYGPATH_W) '$(srcdir)/config/tc-xgate.c'; fi`
+
 tc-xtensa.o: config/tc-xtensa.c
 @am__fastdepCC_TRUE@   $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tc-xtensa.o -MD -MP -MF $(DEPDIR)/tc-xtensa.Tpo -c -o tc-xtensa.o `test -f 'config/tc-xtensa.c' || echo '$(srcdir)/'`config/tc-xtensa.c
 @am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/tc-xtensa.Tpo $(DEPDIR)/tc-xtensa.Po
index 6e2abff..e8dcf50 100644 (file)
--- a/gas/NEWS
+++ b/gas/NEWS
@@ -1,5 +1,7 @@
 -*- text -*-
 
+* Add support for the Freescale XGATE architecture.
+
 * Add support for .bundle_align_mode, .bundle_lock, and .bundle_unlock
   directives.  These are currently available only for x86 and ARM targets.
 
diff --git a/gas/config/tc-xgate.c b/gas/config/tc-xgate.c
new file mode 100644 (file)
index 0000000..954acdc
--- /dev/null
@@ -0,0 +1,1416 @@
+/* tc-xgate.c -- Assembler code for Freescale XGATE
+   Copyright 2010, 2011, 2012
+   Free Software Foundation, Inc.
+   Contributed by Sean Keys <skeys@ipdatasys.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.  */
+
+#include "as.h"
+#include "safe-ctype.h"
+#include "subsegs.h"
+#include "opcode/xgate.h"
+#include "dwarf2dbg.h"
+#include "elf/xgate.h"
+
+const char comment_chars[] = ";!";
+const char line_comment_chars[] = "#*";
+const char line_separator_chars[] = "";
+const char EXP_CHARS[] = "eE";
+const char FLT_CHARS[] = "dD";
+
+#define SIXTEENTH_BIT  0x8000
+#define N_BITS_IN_WORD 16
+
+/* #define STATE_CONDITIONAL_BRANCH            (1) */
+#define STATE_PC_RELATIVE      (2)
+#define REGISTER_P(ptr)                (ptr == 'r')
+#define INCREMENT              01
+#define DECREMENT              02
+#define MAXREGISTER            07
+#define MINREGISTER            00
+
+#define OPTION_MMCU 'm'
+
+/* This macro has no side-effects.  */
+#define ENCODE_RELAX(what,length) (((what) << 2) + (length))
+
+/* what this is */
+struct xgate_opcode_handle
+{
+  int number_of_modes;
+  char *name;
+  struct xgate_opcode *opc0[MAX_OPCODES];
+};
+
+/*  LOCAL FUNCTIONS */
+static char *
+xgate_parse_exp (char *, expressionS *);
+static inline char *
+skip_whitespace (char *);
+static void
+get_default_target (void);
+static char *
+extract_word (char *, char *, int);
+static char *
+xgate_new_instruction (int size);
+unsigned short
+xgate_apply_operand (unsigned short, unsigned short *, unsigned short,
+    unsigned char);
+void
+xgate_operands (struct xgate_opcode *, char **);
+static unsigned int
+xgate_operand (struct xgate_opcode *, int *, int where, char **, char **);
+static struct xgate_opcode *
+xgate_find_match (struct xgate_opcode_handle *, int, unsigned int);
+static int
+cmp_opcode (struct xgate_opcode *, struct xgate_opcode *);
+unsigned int
+xgate_detect_format (char *);
+void
+xgate_print_syntax (char *);
+void
+xgate_print_table (void);
+
+/* LOCAL DATA */
+static struct hash_control *xgate_hash;
+
+/* Previous opcode.  */
+static unsigned int prev = 0;
+
+static unsigned char fixup_required = 0;
+
+/* Used to enable clipping of 16 bit operands into 8 bit constraints.  */
+static unsigned char macroClipping = 0;        
+
+static char oper_check;
+static char flag_print_insn_syntax = 0;
+static char flag_print_opcodes = 0;
+
+static int current_architecture;
+static const char *default_cpu;
+
+/* ELF flags to set in the output file header.  */
+static int elf_flags = E_XGATE_F64;
+
+/* This table describes how you change sizes for the various types of variable
+   size expressions.  This version only supports two kinds.  */
+
+/* The fields are:
+   How far Forward this mode will reach.
+   How far Backward this mode will reach.
+   How many bytes this mode will add to the size of the frag.
+   Which mode to go to if the offset won't fit in this one.  */
+
+relax_typeS md_relax_table[] =
+{
+  {1, 1, 0, 0},                        /* First entries aren't used.  */
+  {1, 1, 0, 0},                        /* For no good reason except.  */
+  {1, 1, 0, 0},                        /* that the VAX doesn't either.  */
+  {1, 1, 0, 0},
+  /* XGATE 9 and 10 bit pc rel todo complete and test */
+/*{(511), (-512), 0, ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD)},
+  {(1023), (-1024), 0, ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD)}, */
+  {0, 0, 0, 0}
+};
+
+/* XGATE's registers all are 16-bit general purpose.  They are numbered according to the specifications.  */
+typedef enum register_id
+{
+  REG_NONE = -1,
+  REG_R0 = 0,
+  REG_R1 = 1,
+  REG_R2 = 2,
+  REG_R3 = 3,
+  REG_R4 = 4,
+  REG_R5 = 5,
+  REG_R6 = 6,
+  REG_R7 = 7,
+  REG_PC = 8,
+  REG_CCR = 9
+} register_id;
+
+/* This table describes all the machine specific pseudo-ops the assembler
+   has to support.  The fields are: pseudo-op name without dot function to
+   call to execute this pseudo-op Integer arg to pass to the function.  */
+const pseudo_typeS md_pseudo_table[] =
+{
+  /* The following pseudo-ops are supported for MRI compatibility.  */
+  {0, 0, 0}
+};
+
+const char *md_shortopts = "m:";
+
+struct option md_longopts[] =
+{
+#define OPTION_PRINT_INSN_SYNTAX  (OPTION_MD_BASE + 0)
+  { "print-insn-syntax", no_argument, NULL, OPTION_PRINT_INSN_SYNTAX },
+
+#define OPTION_PRINT_OPCODES  (OPTION_MD_BASE + 1)
+  { "print-opcodes", no_argument, NULL, OPTION_PRINT_OPCODES },
+
+#define OPTION_GENERATE_EXAMPLE  (OPTION_MD_BASE + 2)
+  { "generate-example", no_argument, NULL, OPTION_GENERATE_EXAMPLE },
+
+#define OPTION_MSHORT  (OPTION_MD_BASE + 3)
+  { "mshort", no_argument, NULL, OPTION_MSHORT },
+
+#define OPTION_MLONG  (OPTION_MD_BASE + 4)
+  { "mlong", no_argument, NULL, OPTION_MLONG },
+
+#define OPTION_MSHORT_DOUBLE  (OPTION_MD_BASE + 5)
+  { "mshort-double", no_argument, NULL, OPTION_MSHORT_DOUBLE },
+
+#define OPTION_MLONG_DOUBLE  (OPTION_MD_BASE + 6)
+  { "mlong-double", no_argument, NULL, OPTION_MLONG_DOUBLE },
+
+  { NULL, no_argument, NULL, 0 }
+};
+
+size_t md_longopts_size = sizeof(md_longopts);
+
+char *
+md_atof (int type, char *litP, int *sizeP)
+{
+  return ieee_md_atof (type, litP, sizeP, TRUE);
+}
+
+int
+md_parse_option (int c, char *arg)
+{
+  switch (c)
+    {
+    case OPTION_MMCU:
+      if (strcasecmp (arg, "v1") == 0)
+       current_architecture = XGATE_V1;
+      else if (strcasecmp (arg, "v2") == 0)
+       current_architecture = XGATE_V2;
+      else if (strcasecmp (arg, "v3") == 0)
+       current_architecture = XGATE_V3;
+      else
+       as_bad (_(" architecture variant invalid"));
+      break;
+
+    case OPTION_PRINT_INSN_SYNTAX:
+      flag_print_insn_syntax = 1;
+      break;
+
+    case OPTION_PRINT_OPCODES:
+      flag_print_opcodes = 1;
+      break;
+
+    case OPTION_GENERATE_EXAMPLE:
+      flag_print_opcodes = 2;
+      break;
+
+    case OPTION_MSHORT:
+      elf_flags &= ~E_XGATE_I32;
+      break;
+
+    case OPTION_MLONG:
+      elf_flags |= E_XGATE_I32;
+      break;
+
+    case OPTION_MSHORT_DOUBLE:
+      elf_flags &= ~E_XGATE_F64;
+      break;
+
+    case OPTION_MLONG_DOUBLE:
+      elf_flags |= E_XGATE_F64;
+      break;
+
+    default:
+      return 0;
+    }
+  return 1;
+}
+
+const char *
+xgate_arch_format (void)
+{
+  get_default_target ();
+
+  if (current_architecture & cpuxgate)
+    return "elf32-xgate";
+
+  return "error";
+}
+
+static void
+get_default_target (void)
+{
+  const bfd_target *target;
+  bfd abfd;
+
+  if (current_architecture != 0)
+    return;
+
+  default_cpu = "unknown";
+  target = bfd_find_target (0, &abfd);
+
+  if (target && target->name)
+    {
+      if (strcmp (target->name, "elf32-xgate") == 0)
+        {
+          current_architecture = cpuxgate;
+          default_cpu = "XGATE V1";
+          return;
+        }
+
+      as_bad (_("Default target `%s' is not supported."), target->name);
+    }
+}
+
+void
+md_begin (void)
+{
+  struct xgate_opcode *xgate_opcode_ptr = NULL;
+  struct xgate_opcode *xgate_op_table = NULL;
+  struct xgate_opcode_handle *op_handles = 0;
+  char *prev_op_name = 0;
+  int handle_enum = 0;
+  unsigned int number_of_handle_rows = 0;
+  int i, j = 0;
+
+  /* Create a local copy of our opcode table
+     including an extra line for NULL termination.  */
+  xgate_op_table = (struct xgate_opcode *)
+    xmalloc ((xgate_num_opcodes + 1) * sizeof (struct xgate_opcode));
+
+  memset (xgate_op_table, 0,
+         sizeof(struct xgate_opcode) * (xgate_num_opcodes + 1));
+
+  for (xgate_opcode_ptr = (struct xgate_opcode*) xgate_opcodes, i = 0;
+      i < xgate_num_opcodes; i++)
+    xgate_op_table[i] = xgate_opcode_ptr[i];
+
+  qsort (xgate_op_table, xgate_num_opcodes, sizeof(struct xgate_opcode),
+        (int (*)(const void *, const void *)) cmp_opcode);
+
+  /* Calculate number of handles since this will be
+     smaller than the raw number of opcodes in the table.  */
+  for (xgate_opcode_ptr = xgate_op_table; xgate_opcode_ptr->name;
+      xgate_opcode_ptr++)
+    {
+      if (prev_op_name != 0)
+        {
+          if (strcmp (prev_op_name, xgate_opcode_ptr->name))
+           number_of_handle_rows++;
+        }
+      prev_op_name = xgate_opcode_ptr->name;
+    }
+
+  op_handles = (struct xgate_opcode_handle *)
+    xmalloc (sizeof(struct xgate_opcode_handle) * (number_of_handle_rows + 1));
+
+  /* Insert opcode names into hash table, aliasing duplicates.  */
+  xgate_hash = hash_new ();
+
+  for (xgate_opcode_ptr = xgate_op_table, i = 0, j = 0; i < xgate_num_opcodes;
+       i++, xgate_opcode_ptr++)
+    {
+      if (strcmp (prev_op_name, xgate_opcode_ptr->name) || i == 0)
+        {
+          handle_enum = 0;
+          if (i)
+           j++;
+
+          op_handles[j].name = xgate_opcode_ptr->name;
+          op_handles[j].opc0[0] = xgate_opcode_ptr;
+        }
+      else
+        {
+          handle_enum++;
+          op_handles[j].opc0[handle_enum] = xgate_opcode_ptr;
+        }
+      op_handles[j].number_of_modes = handle_enum;
+      prev_op_name = op_handles[j].name;
+    }
+
+  while (op_handles->name)
+    {
+      hash_insert (xgate_hash, op_handles->name, (char *) op_handles);
+      op_handles++;
+    }
+
+  if (flag_print_opcodes == 1)
+    xgate_print_table ();
+}
+
+void
+xgate_init_after_args (void)
+{
+}
+
+void
+md_show_usage (FILE * stream)
+{
+  get_default_target ();
+
+  fprintf (
+          stream,
+          _("\
+      Freescale XGATE co-processor options:\n                  \
+       -mshort                 use 16-bit int ABI (default)\n  \
+       -mlong                  use 32-bit int ABI\n            \
+       -mshort-double          use 32-bit double ABI\n                 \
+       -mlong-double           use 64-bit double ABI (default)\n\
+      --mxgate                 specify the processor variant[default %s]\n\
+      --print-insn-syntax     print the syntax of instruction in case of error\n\
+      --print-opcodes         print the list of instructions with syntax\n\
+      --generate-example      generate an example of each instruction"),
+          default_cpu);
+}
+
+enum bfd_architecture
+xgate_arch (void)
+{
+  get_default_target ();
+  return bfd_arch_xgate;
+}
+
+int
+xgate_mach (void)
+{
+  return 0;
+}
+
+void
+xgate_print_syntax (char *name)
+{
+  int i;
+
+  for (i = 0; i < xgate_num_opcodes; i++)
+    {
+      if (!strcmp (xgate_opcodes[i].name, name))
+        {
+          if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IDR))
+            printf ("\tFormat is %s\tRx, Rx, Rx+|-Rx|Rx\n",
+                   xgate_opcodes[i].name);
+          if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_INH))
+            printf ("\tFormat is %s\n", xgate_opcodes[i].name);
+          if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_TRI))
+            printf ("\tFormat is %s\tRx, Rx, Rx\n", xgate_opcodes[i].name);
+          if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_DYA))
+            printf ("\tFormat is %s\tRx, Rx\n", xgate_opcodes[i].name);
+          if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_DYA_MON)
+              || !strcmp (xgate_opcodes[i].constraints, XGATE_OP_MON))
+            printf ("\tFormat is %s\tRx\n", xgate_opcodes[i].name);
+          if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM3))
+            printf ("\tFormat is %s\t<3-bit value>\n", xgate_opcodes[i].name);
+          if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM4))
+            printf ("\tFormat is %s\t<4 -bit value>\n", xgate_opcodes[i].name);
+          if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM8))
+            printf ("\tFormat is %s\tRx, <8-bit value>\n",
+                   xgate_opcodes[i].name);
+          if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM16))
+            printf ("\tFormat is %s\tRx, <16-bit value>\n",
+                   xgate_opcodes[i].name);
+          if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_MON_R_C))
+            printf ("\tFormat is %s\tRx, CCR\n", xgate_opcodes[i].name);
+          if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_MON_C_R))
+            printf ("\tFormat is %s\tCCR, Rx\n", xgate_opcodes[i].name);
+          if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_MON_R_P))
+            printf ("\tFormat is %s\tRx, PC\n", xgate_opcodes[i].name);
+          if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM16mLDW))
+            printf ("\tFormat is %s\tRx, <16-bit value>\n",
+                   xgate_opcodes[i].name);
+        }
+    }
+}
+
+void
+xgate_print_table (void)
+{
+  int i;
+
+  for (i = 0; i < xgate_num_opcodes; i++)
+    xgate_print_syntax (xgate_opcodes[i].name);
+
+  return;
+}
+
+const char *
+xgate_listing_header (void)
+{
+  if (current_architecture & cpuxgate)
+    return "XGATE GAS ";
+
+  return "ERROR MC9S12X GAS ";
+}
+
+symbolS *
+md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
+{
+  return 0;
+}
+
+/* GAS will call this function for each section at the end of the assembly,
+   to permit the CPU backend to adjust the alignment of a section.  */
+
+valueT
+md_section_align (asection * seg, valueT addr)
+{
+  int align = bfd_get_section_alignment (stdoutput, seg);
+  return ((addr + (1 << align) - 1) & (-1 << align));
+}
+
+void
+md_assemble (char *input_line)
+{
+  struct xgate_opcode *opcode = 0;
+  struct xgate_opcode *macro_opcode = 0;
+  struct xgate_opcode_handle *opcode_handle = 0;
+  /* Caller expects it to be returned as it was passed.  */
+  char *saved_input_line = input_line;
+  char op_name[9] =  { 0 };
+  unsigned int sh_format = 0;
+  char *p = 0;
+
+  fixup_required = 0;
+  oper_check = 0; /* set error flags */
+  input_line = extract_word (input_line, op_name, sizeof(op_name));
+
+  /* Check to make sure we are not reading a bogus line.  */
+  if (!op_name[0])
+    as_bad (_("opcode missing or not found on input line"));
+
+  if (!(opcode_handle = (struct xgate_opcode_handle *) hash_find (xgate_hash,
+      op_name)))
+    {
+      as_bad (_("opcode %s not found in opcode hash table"), op_name);
+    }
+  else
+    {
+      /* Detect operand format so we can pull the proper opcode bin.  */
+      sh_format = xgate_detect_format (input_line);
+
+      opcode = xgate_find_match (opcode_handle, opcode_handle->number_of_modes,
+          sh_format);
+
+      if (!opcode)
+        {
+          as_bad (_("matching operands to opcode "));
+          xgate_print_syntax (opcode_handle->opc0[0]->name);
+        }
+      else if (opcode->size == 2)
+        {
+         /* Size is one word - assemble that native insn.  */
+          xgate_operands (opcode, &input_line);
+        }
+      else
+        {
+         /* Insn is a simplified instruction - expand it out.  */
+          macroClipping = 1;
+          unsigned int i;
+
+          /* skip past our ';' separator.  */
+          for (i = strlen (opcode->constraints), p = opcode->constraints; i > 0;
+              i--, p++)
+            {
+              if (*p == ';')
+                {
+                  p++;
+                  break;
+                }
+            }
+          input_line = skip_whitespace (input_line);
+          char *macro_inline = input_line;
+
+          /* Loop though the macro's opcode list and apply operands to each real opcode. */
+          for (i = 0; *p && i < (opcode->size / 2); i++)
+            {
+             /* Loop though macro operand list.  */
+              input_line = macro_inline; /* Rewind.  */
+              p = extract_word (p, op_name, 10);
+
+              if (!(opcode_handle = (struct xgate_opcode_handle *)
+                   hash_find (xgate_hash, op_name)))
+                {
+                  as_bad (
+                      _(": processing macro, real opcode handle not found in hash"));
+                  break;
+                }
+              else
+                {
+                  sh_format = xgate_detect_format (input_line);
+                  macro_opcode = xgate_find_match (opcode_handle,
+                      opcode_handle->number_of_modes, sh_format);
+                  xgate_operands (macro_opcode, &input_line);
+                }
+            }
+        }
+    }
+  macroClipping = 0;
+  input_line = saved_input_line;
+}
+
+/* Force truly undefined symbols to their maximum size, and generally set up
+   the frag list to be relaxed.  */
+
+int
+md_estimate_size_before_relax (fragS *fragp, asection *seg)
+{
+  /* If symbol is undefined or located in a different section,
+     select the largest supported relocation.  */
+  relax_substateT subtype;
+  relax_substateT rlx_state[] =
+    { 0, 2 };
+
+  for (subtype = 0; subtype < ARRAY_SIZE (rlx_state); subtype += 2)
+    {
+      if (fragp->fr_subtype == rlx_state[subtype]
+          && (!S_IS_DEFINED (fragp->fr_symbol)
+              || seg != S_GET_SEGMENT (fragp->fr_symbol)))
+        {
+          fragp->fr_subtype = rlx_state[subtype + 1];
+          break;
+        }
+    }
+
+  if (fragp->fr_subtype >= ARRAY_SIZE (md_relax_table))
+    abort ();
+
+  return md_relax_table[fragp->fr_subtype].rlx_length;
+}
+
+
+/* Relocation, relaxation and frag conversions.  */
+
+/* PC-relative offsets are relative to the start of the
+   next instruction.  That is, the address of the offset, plus its
+   size, since the offset is always the last part of the insn.  */
+
+long
+md_pcrel_from (fixS * fixP)
+{
+  return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
+}
+
+/* If while processing a fixup, a reloc really needs to be created
+   then it is done here.  */
+
+arelent *
+tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp)
+{
+  arelent * reloc;
+
+  reloc = (arelent *) xmalloc (sizeof(arelent));
+  reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof(asymbol *));
+  *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
+  reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
+
+  if (fixp->fx_r_type == 0)
+    {
+      reloc->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_16);
+    }
+  else
+    {
+      reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
+    }
+
+  if (reloc->howto == (reloc_howto_type *) NULL)
+    {
+      as_bad_where (fixp->fx_file, fixp->fx_line, _
+      ("Relocation %d is not supported by object file format."),
+          (int) fixp->fx_r_type);
+      return NULL;
+    }
+
+  /* Since we use Rel instead of Rela, encode the vtable entry to be
+     used in the relocation's section offset.  */
+  if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+    reloc->address = fixp->fx_offset;
+  reloc->addend = 0;
+  return reloc;
+}
+
+/* Patch the instruction with the resolved operand.  Elf relocation
+   info will also be generated to take care of linker/loader fixups.
+   The XGATE addresses only 16-bit addresses.The BFD_RELOC_32 is necessary
+   for the support of --gstabs.  */
+
+void
+md_apply_fix (fixS * fixP, valueT * valP, segT seg ATTRIBUTE_UNUSED)
+{
+  char *where;
+  long value = *valP;
+  int opcode = 0;
+  ldiv_t result;
+
+  /* If the fixup is done mark it done so no further symbol resolution will take place.  */
+  if (fixP->fx_addsy == (symbolS *) NULL)
+    {
+      fixP->fx_done = 1;
+    }
+
+  /* We don't actually support subtracting a symbol.  */
+  if (fixP->fx_subsy != (symbolS *) NULL)
+    as_bad_where (fixP->fx_file, fixP->fx_line, _("Expression too complex."));
+
+  where = fixP->fx_frag->fr_literal + fixP->fx_where;
+  opcode = bfd_getl16 (where);
+  int mask = 0;
+
+  switch (fixP->fx_r_type)
+    {
+    case R_XGATE_PCREL_9:
+      if (value < -512 || value > 511)
+       as_bad_where (fixP->fx_file, fixP->fx_line,
+                     _("Value %ld too large for 9-bit PC-relative branch."), value);
+      result = ldiv (value, 2); /* from bytes to words */
+      value = result.quot;
+      if (result.rem)
+       as_bad_where (fixP->fx_file, fixP->fx_line, _
+                     ("Value %ld not aligned by 2 for 9-bit PC-relative branch."), value);
+      mask = 0x1FF; /* Clip into 8-bit field FIXME I'm sure there is a more proper place for this */
+      value &= mask;
+      number_to_chars_bigendian (where, (opcode | value), 2);
+      break;
+    case R_XGATE_PCREL_10:
+      if (value < -1024 || value > 1023)
+       as_bad_where (fixP->fx_file, fixP->fx_line,
+                     _("Value %ld too large for 10-bit PC-relative branch."), value);
+      result = ldiv (value, 2); /* from bytes to words */
+      value = result.quot;
+      if (result.rem)
+       as_bad_where (fixP->fx_file, fixP->fx_line, _
+                     ("Value %ld not aligned by 2 for 10-bit PC-relative branch."), value);
+      mask = 0x3FF; /* Clip into 9-bit field FIXME I'm sure there is a more proper place for this */
+      value &= mask;
+      number_to_chars_bigendian (where, (opcode | value), 2);
+      break;
+    case BFD_RELOC_XGATE_IMM8_HI:
+      if (value < -65537 || value > 65535)
+       as_bad_where (fixP->fx_file, fixP->fx_line,
+                     _("Value out of 16-bit range."));
+      value >>= 8;
+      value &= 0x00ff;
+      bfd_putb16 ((bfd_vma) value | opcode, (void *) where);
+      break;
+    case BFD_RELOC_XGATE_24:
+    case BFD_RELOC_XGATE_IMM8_LO:
+      if (value < -65537 || value > 65535)
+       as_bad_where (fixP->fx_file, fixP->fx_line,
+                     _("Value out of 16-bit range."));
+      value &= 0x00ff;
+      bfd_putb16 ((bfd_vma) value | opcode, (void *) where);
+      break;
+    case BFD_RELOC_XGATE_IMM3:
+      if (value < 0 || value > 7)
+       as_bad_where (fixP->fx_file, fixP->fx_line,
+                     _("Value out of 3-bit range."));
+      value <<= 8; /* make big endian */
+      number_to_chars_bigendian (where, (opcode | value), 2);
+      break;
+    case BFD_RELOC_XGATE_IMM4:
+      if (value < 0 || value > 15)
+       as_bad_where (fixP->fx_file, fixP->fx_line,
+                     _("Value out of 4-bit range."));
+      value <<= 4; /* align the operand bits */
+      number_to_chars_bigendian (where, (opcode | value), 2);
+      break;
+    case BFD_RELOC_XGATE_IMM5:
+      if (value < 0 || value > 31)
+       as_bad_where (fixP->fx_file, fixP->fx_line,
+                     _("Value out of 5-bit range."));
+      value <<= 5; /* align the operand bits */
+      number_to_chars_bigendian (where, (opcode | value), 2);
+      break;
+    case BFD_RELOC_8:
+      ((bfd_byte *) where)[0] = (bfd_byte) value;
+      break;
+    case BFD_RELOC_32:
+      bfd_putb32 ((bfd_vma) value, (unsigned char *) where);
+      /* todo figure out how to make BFD_RELOC_16 the default */
+      break;
+    case BFD_RELOC_16:
+      bfd_putb16 ((bfd_vma) value, (unsigned char *) where);
+      break;
+    default:
+      as_fatal (_("Line %d: unknown relocation type: 0x%x."), fixP->fx_line,
+               fixP->fx_r_type);
+      break;
+    }
+}
+
+/* See whether we need to force a relocation into the output file.  */
+
+int
+tc_xgate_force_relocation (fixS * fixP)
+{
+  if (fixP->fx_r_type == BFD_RELOC_XGATE_RL_GROUP)
+    return 1;
+  return generic_force_reloc (fixP);
+}
+
+/* Here we decide which fixups can be adjusted to make them relative
+   to the beginning of the section instead of the symbol.  Basically
+   we need to make sure that the linker relaxation is done
+   correctly, so in some cases we force the original symbol to be
+   used.  */
+
+int
+tc_xgate_fix_adjustable (fixS * fixP)
+{
+  switch (fixP->fx_r_type)
+    {
+      /* For the linker relaxation to work correctly, these relocs
+        need to be on the symbol itself.  */
+    case BFD_RELOC_16:
+    case BFD_RELOC_XGATE_RL_JUMP:
+    case BFD_RELOC_XGATE_RL_GROUP:
+    case BFD_RELOC_VTABLE_INHERIT:
+    case BFD_RELOC_VTABLE_ENTRY:
+    case BFD_RELOC_32:
+      return 0;
+    default:
+      return 1;
+    }
+}
+
+void
+md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
+                asection * sec ATTRIBUTE_UNUSED,
+                fragS * fragP ATTRIBUTE_UNUSED)
+{
+  as_bad (("md_convert_frag not implemented yet"));
+  abort ();
+}
+
+/* Set the ELF specific flags.  */
+
+void
+xgate_elf_final_processing (void)
+{
+  elf_flags |= EF_XGATE_MACH;
+  elf_elfheader (stdoutput)->e_flags &= ~EF_XGATE_ABI;
+  elf_elfheader (stdoutput)->e_flags |= elf_flags;
+}
+
+static inline char *
+skip_whitespace (char *s)
+{
+  while (*s == ' ' || *s == '\t' || *s == '(' || *s == ')')
+    s++;
+
+  return s;
+}
+
+/* Extract a word (continuous alpha-numeric chars) from the input line.  */
+
+static char *
+extract_word (char *from, char *to, int limit)
+{
+  char *op_end;
+  int size = 0;
+
+  /* Drop leading whitespace.  */
+  from = skip_whitespace (from);
+  *to = 0;
+  /* Find the op code end.  */
+  for (op_end = from; *op_end != 0 && is_part_of_name (*op_end);)
+    {
+      to[size++] = *op_end++;
+      if (size + 1 >= limit)
+        break;
+    }
+  to[size] = 0;
+  return op_end;
+}
+
+static char *
+xgate_new_instruction (int size)
+{
+  char *f = frag_more (size);
+  dwarf2_emit_insn (size);
+  return f;
+}
+
+unsigned short
+xgate_apply_operand (unsigned short new_mask,
+                    unsigned short *availiable_mask_bits,
+                    unsigned short mask,
+                    unsigned char n_bits)
+{
+  unsigned short n_shifts;
+  unsigned int n_drop_bits;
+
+  /* Shift until you find an available operand bit "1" and record the number of shifts.  */
+  for (n_shifts = 0;
+       !(*availiable_mask_bits & SIXTEENTH_BIT) && n_shifts < 16;
+       n_shifts++)
+    *availiable_mask_bits <<= 1;
+
+  /* Shift for the number of bits your operand requires while bits are available.  */
+  for (n_drop_bits = n_bits;
+       n_drop_bits && (*availiable_mask_bits & SIXTEENTH_BIT);
+       --n_drop_bits)
+    *availiable_mask_bits <<= 1;
+
+  if (n_drop_bits)
+    as_bad (_(":operand has too many bits"));
+  *availiable_mask_bits >>= n_shifts + n_bits;
+  if ((n_drop_bits == 0) && (*availiable_mask_bits == 0))
+    {
+      oper_check = 1; /* flag operand check as good */
+    }
+  new_mask <<= N_BITS_IN_WORD - (n_shifts + n_bits);
+  mask |= new_mask;
+  return mask;
+}
+
+/* Parse ordinary expression.  */
+
+static char *
+xgate_parse_exp (char *s, expressionS * op)
+{
+  input_line_pointer = s;
+  expression(op);
+  if (op->X_op == O_absent)
+    as_bad (_("missing operand"));
+  return input_line_pointer;
+}
+
+/* For testing.  Comment out to prevent defined but not used warning
+
+static unsigned int
+xgate_get_constant(char *str, int max)
+{
+  expressionS ex;
+
+  str = skip_whitespace(str);
+  input_line_pointer = str;
+  expression (& ex);
+
+  if (ex.X_op != O_constant)
+    as_bad(_("constant value required"));
+
+  if (ex.X_add_number > max || ex.X_add_number < 0)
+    as_bad(_("number must be positive and less than %d"), max + 1);
+
+  return ex.X_add_number;
+}
+*/
+
+static int
+cmp_opcode (struct xgate_opcode *op1, struct xgate_opcode *op2)
+{
+  return strcmp (op1->name, op2->name);
+}
+
+/* Parse instruction operands.  */
+
+void
+xgate_operands (struct xgate_opcode *opcode, char **line)
+{
+  char *frag = xgate_new_instruction (opcode->size);
+  int where = frag - frag_now->fr_literal;
+  char *op = opcode->constraints;
+  unsigned int bin = (int) opcode->bin_opcode;
+  char *str = *line;
+  unsigned short oper_mask = 0;
+  int operand_bit_length = 0;
+  unsigned int operand = 0;
+  char n_operand_bits = 0;
+  char first_operand_equals_second = 0;
+  int i = 0;
+  char c = 0;
+
+  /* Generate available operand bits mask.  */
+  for (i = 0; (c = opcode->format[i]); i++)
+    {
+      if (ISDIGIT (c) || (c == 's'))
+        {
+          oper_mask <<= 1;
+        }
+      else
+        {
+          oper_mask <<= 1;
+          oper_mask += 1;
+          n_operand_bits++;
+        }
+    }
+
+  /* Opcode has operands.  */
+  /* Parse first operand.  */
+  if (*op)
+    {
+      if (*op == '=')
+        {
+          first_operand_equals_second = 1;
+          ++op;
+        }
+      operand = xgate_operand (opcode, &operand_bit_length, where, &op, &str);
+      ++op;
+      bin = xgate_apply_operand (operand, &oper_mask, bin, operand_bit_length);
+      /* Parse second operand.  */
+      if (*op)
+        {
+          if (*op == ',')
+            ++op;
+          str = skip_whitespace (str);
+          if (*str++ != ',')
+            {
+              if (first_operand_equals_second)
+                {
+                  bin = xgate_apply_operand (operand, &oper_mask, bin,
+                      operand_bit_length);
+                  ++op;
+                }
+              else
+                {
+                  as_bad (_("`,' required before second operand"));
+                }
+            }
+          else
+            {
+              str = skip_whitespace (str);
+              operand = xgate_operand (opcode, &operand_bit_length, where, &op,
+                  &str);
+              bin = xgate_apply_operand (operand, &oper_mask, bin,
+                  operand_bit_length);
+              ++op;
+            }
+        }
+
+      /* Parse the third register.  */
+      if (*op)
+        {
+          if (*op == ',')
+            ++op;
+          str = skip_whitespace (str);
+          if (*str++ != ',')
+            as_bad (_("`,' required before third operand"));
+          str = skip_whitespace (str);
+          operand = xgate_operand (opcode, &operand_bit_length, where, &op,
+              &str);
+          bin = xgate_apply_operand (operand, &oper_mask, bin,
+              operand_bit_length);
+        }
+    }
+  if (opcode->size == 2 && fixup_required)
+    {
+      bfd_putl16 (bin, frag);
+    }
+  else if ((opcode->sh_format & XG_PCREL))
+    {
+      /* Write our data to a frag for further processing.  */
+      bfd_putl16 (opcode->bin_opcode, frag); 
+    }
+  else
+    {
+      /* Apply operand mask(s)to bin opcode and write the output.  */
+      /* Since we are done write this frag in xgate BE format.  */
+      number_to_chars_bigendian (frag, bin, opcode->size); 
+    }
+  prev = bin;
+  *line = str;
+  return;
+}
+
+static unsigned int
+xgate_operand (struct xgate_opcode *opcode,
+              int *bit_width,
+              int where,
+              char **op_con,
+              char **line)
+{
+  expressionS op_expr;
+  fixS *fixp = 0;
+  char *op_constraint = *op_con;
+  unsigned int op_mask = 0;
+  char *str = skip_whitespace (*line);
+  char r_name[20] =
+    { 0 };
+  unsigned int pp_fix = 0;
+  unsigned short max_size = 0;
+  int i;
+
+  *bit_width = 0;
+  /* Reset.  */
+
+  switch (*op_constraint)
+    {
+    case '+': /* Indexed register operand +/- or plain r.  */
+      /* TODO should be able to combine with with case R.  */
+
+      /* Default to neither inc or dec.  */
+      pp_fix = 0;
+      *bit_width = 5;
+      str = skip_whitespace (str);
+      while (*str != ' ' && *str != '\t')
+       {
+         if (*str == '-')
+           pp_fix = DECREMENT;
+         else if (*str == '+')
+           pp_fix = INCREMENT;
+         else if (*str == 'r' || *str == 'R')
+           {
+             str = extract_word (str, r_name, sizeof(r_name));
+             if (ISDIGIT (r_name[1]))
+               {
+                 if (r_name[2] == '\0' && (r_name[1] - '0' < 8))
+                   op_mask = r_name[1] - '0';
+                 if (r_name[2] != '\0' && (r_name[1] - '0' > 7))
+                   as_bad (_(": expected register name r0-r7 read %s"), r_name);
+                 continue;
+               }
+           }
+         str++;
+       }
+      op_mask <<= 2;
+      op_mask |= pp_fix;
+      break;
+
+    case 'r': /* Register operand.  */
+      if (*str == 'r' || *str == 'R')
+       {
+         *bit_width = 3;
+         str = extract_word (str, r_name, sizeof(r_name));
+         op_mask = 0xff;
+         if (ISDIGIT (r_name[1]))
+           {
+             if (r_name[2] == '\0')
+               op_mask = r_name[1] - '0';
+             else if (r_name[1] != '0' && ISDIGIT (r_name[2])
+                      && r_name[3] == '\0')
+               op_mask = (r_name[1] - '0') * 10 + r_name[2] - '0';
+             if (op_mask > MAXREGISTER)
+               as_bad (_(": expected register name r0-r7 read %s "), r_name);
+           }
+       }
+      else
+       {
+         as_bad (_(": expected register name r0-r7 read %s "), r_name);
+       }
+      break;
+
+    case 'i': /* Immediate value or expression expected.  */
+      /* Advance the original format pointer.  */
+      (*op_con)++;
+      op_constraint++;
+      if (ISDIGIT (*op_constraint))
+       {
+         *bit_width = (int) *op_constraint - '0';
+       }
+      else if (*op_constraint == 'a')
+       {
+         *bit_width = 0x0A;
+       }
+      else if (*op_constraint == 'f')
+       {
+         *bit_width = 0x0F;
+       }
+      /* http://tigcc.ticalc.org/doc/gnuasm.html#SEC31 */
+      if (*str == '#')
+       str++;
+      str = xgate_parse_exp (str, &op_expr);
+      if (op_expr.X_op == O_constant)
+       {
+         if (!ISDIGIT (*op_constraint))
+           as_bad (
+                   _(":expected bit length with constraint type i(# immediate) read %c"),
+                   *op_constraint);
+         op_mask = op_expr.X_add_number;
+         if ((opcode->name[strlen (opcode->name) - 1] == 'l') && macroClipping)
+           {
+             op_mask &= 0x00FF;
+           }
+         else if ((opcode->name[strlen (opcode->name) - 1]) == 'h'
+                  && macroClipping)
+           {
+             op_mask >>= 8;
+           }
+
+         /* Make sure it fits.  */
+         for (i = *bit_width; i; i--)
+           {
+             max_size <<= 1;
+             max_size += 1;
+           }
+         if (op_mask > max_size)
+           as_bad (_(":operand value(%d) too big for constraint"), op_mask);
+       }
+      else
+       {
+         fixup_required = 1;
+         if (*op_constraint == '8')
+           {
+             if ((opcode->name[strlen (opcode->name) - 1] == 'l')
+                 && macroClipping)
+               {
+                 fixp = fix_new_exp (frag_now, where, 2, &op_expr, FALSE,
+                                     BFD_RELOC_XGATE_24);
+                 /* Should be BFD_RELOC_XGATE_IMM8_LO TODO fix.  */
+                 fixp->fx_pcrel_adjust = 0;
+               }
+             if ((opcode->name[strlen (opcode->name) - 1]) == 'h'
+                 && macroClipping)
+               {
+                 fixp = fix_new_exp (frag_now, where, 2, &op_expr, FALSE,
+                                     BFD_RELOC_XGATE_IMM8_HI);
+                 fixp->fx_pcrel_adjust = 0;
+               }
+             if (!fixp)
+                as_bad (_(":unknown relocation"));
+           }
+         else if (*op_constraint == '5')
+           {
+             fixp = fix_new_exp (frag_now, where, 2, &op_expr, FALSE,
+                                 BFD_RELOC_XGATE_IMM5);
+             fixp->fx_pcrel_adjust = 0;
+           }
+         else if (*op_constraint == '4')
+           {
+             fixp = fix_new_exp (frag_now, where, 2, &op_expr, FALSE,
+                                 BFD_RELOC_XGATE_IMM4);
+             fixp->fx_pcrel_adjust = 0;
+           }
+         else if (*op_constraint == '3')
+           {
+            fixp = fix_new_exp (frag_now, where, 2, &op_expr, FALSE,
+                BFD_RELOC_XGATE_IMM3);
+            fixp->fx_pcrel_adjust = 0;
+          }
+        else
+          {
+            as_bad (_(":unknown relocation constraint size"));
+          }
+      }
+    break;
+
+    case 'c': /* CCR register expected.  */
+    if (*str == 'c' || *str == 'C')
+      {
+        *bit_width = 0;
+        str = extract_word (str, r_name, sizeof(r_name));
+        if (!(strcmp (r_name, "ccr") || strcmp (r_name, "CCR")))
+          as_bad (_(": expected register name ccr read %s "), r_name);
+      }
+    else
+      {
+        as_bad (_(": expected character c or C  read %c"), *str);
+      }
+    break;
+
+    case 'p': /* PC register expected.  */
+      if (*str == 'p' || *str == 'P')
+       {
+         *bit_width = 0;
+         str = extract_word (str, r_name, sizeof(r_name));
+         if (!(strcmp (r_name, "pc") || strcmp (r_name, "PC")))
+           as_bad (_(": expected register name pc read %s "), r_name);
+       }
+      else
+       {
+         as_bad (_(": expected character p or P read %c "), *str);
+       }
+      break;
+
+    case 'b': /* Branch expected.  */
+      str = xgate_parse_exp (str, &op_expr);
+      (*op_con)++;
+      op_constraint++;
+      if (op_expr.X_op != O_register)
+       {
+         if (*op_constraint == '9')
+           {
+             /* mode == M68XG_OP_REL9 */
+             fixp = fix_new_exp (frag_now, where, 2, &op_expr, TRUE,
+                                 R_XGATE_PCREL_9);
+             fixp->fx_pcrel_adjust = 1;
+           }
+         else if (*op_constraint == 'a')
+           { /* mode == M68XG_OP_REL10 */
+             fixp = fix_new_exp (frag_now, where, 2, &op_expr, TRUE,
+                                 R_XGATE_PCREL_10);
+             fixp->fx_pcrel_adjust = 1;
+           }
+       }
+      else
+       {
+         as_fatal (_("Operand `%x' not recognized in fixup8."), op_expr.X_op);
+       }
+      break;
+
+    case '?':
+      break;
+
+    default:
+      as_bad (_("unknown constraint `%c'"), *op_constraint);
+      break;
+    }
+  *line = str;
+  return op_mask;
+}
+
+unsigned int
+xgate_detect_format (char *line_in)
+{
+  char num_operands = 0;
+  char *str = skip_whitespace (line_in);
+  int i = 0;
+  int j = 0;
+  char c = 0;
+  unsigned int stripped_length = 0;
+  char sh_format[10] =
+    { 0 }; /* Shorthand format.  */
+  char operands_stripped[3][20] =
+    {
+      { 0 }
+    };
+  /* Strings.  TODO maybe structure this.  */
+  char *i_string =
+    { "i" };
+  char *r_string =
+    { "r" };
+  char *r_r_string =
+    { "r,r" };
+  char *r_r_r_string =
+    { "r,r,r" };
+  char *r_i_string =
+    { "r,i" };
+  char *r_c_string =
+    { "r,c" };
+  char *c_r_string =
+    { "c,r" };
+  char *r_p_string =
+    { "r,p" };
+  char *r_r_i_string =
+    { "r,r,i" };
+
+  /* If the length is zero this is an inherent instruction.  */
+  if (strlen (str) == 0)
+    return XG_INH;
+
+  for (i = 0, j = 0, num_operands = 1; (c = TOLOWER (*str)) != 0; str++)
+    {
+      if (c == ' ' || c == '\t' || c == '(' || c == ')' || c == '-' || c == '+')
+       continue;
+
+      if (c == ',')
+        {
+          j++;
+          num_operands++;
+          i = 0;
+          continue;
+        }
+
+      if (i > MAX_DETECT_CHARS)
+       continue;
+
+      operands_stripped[j][i++] = c;
+    }
+
+  /* Process our substrings to see what we have.  */
+  for (i = 0, j = 0; num_operands > i; i++)
+    {
+      stripped_length = strlen (&operands_stripped[i][0]);
+
+      /* Add separator if we have more than one operand.  */
+      if (i > 0)
+       sh_format[j++] = ',';
+
+      /* Try to process by length first.  */
+      if (stripped_length > 3)
+        {
+          sh_format[j++] = 'i';
+        }
+      else if (stripped_length == 1)
+        {
+          sh_format[j++] = 'i';
+        }
+      else if (stripped_length == 2)
+        {
+          if (operands_stripped[i][0]
+              == 'r' && ISDIGIT (operands_stripped[i][1]))
+            {
+              sh_format[j++] = 'r';
+            }
+          else if (operands_stripped[i][0] == 'p'
+              && operands_stripped[i][1] == 'c')
+            {
+              sh_format[j++] = 'p';
+            }
+          else
+            {
+              sh_format[j++] = 'i';
+            }
+        }
+      else if (stripped_length == 3)
+        {
+          if (operands_stripped[i][0] == 'c'
+              && (operands_stripped[i][1] == 'c'
+                  && operands_stripped[i][2] == 'r'))
+            {
+              sh_format[j++] = 'c';
+            }
+          else if (operands_stripped[i][0] == '#')
+            {
+              sh_format[j++] = 'i';
+            }
+          else
+            {
+              sh_format[j++] = 'i';
+            }
+        }
+      else /* default to immediate */
+        {
+          sh_format[j++] = 'i';
+        }
+    }
+
+  /* See if we have a match.  */
+  if (!strcmp (i_string, sh_format) && num_operands == 1)
+    return XG_I;
+  if (!strcmp (r_i_string, sh_format) && num_operands == 2)
+    return XG_R_I;
+  if (!strcmp (r_r_r_string, sh_format) && num_operands == 3)
+    return XG_R_R_R;
+  if (!strcmp (r_r_string, sh_format) && num_operands == 2)
+    return XG_R_R;
+  if (!strcmp (r_string, sh_format) && num_operands == 1)
+    return XG_R;
+  if (!strcmp (r_c_string, sh_format) && num_operands == 2)
+    return XG_R_C;
+  if (!strcmp (c_r_string, sh_format) && num_operands == 2)
+    return XG_C_R;
+  if (!strcmp (r_p_string, sh_format) && num_operands == 2)
+    return XG_R_P;
+  if (!strcmp (r_r_i_string, sh_format) && num_operands == 3)
+    return XG_R_R_I;
+
+  return 0;
+}
+
+static struct xgate_opcode *
+xgate_find_match (struct xgate_opcode_handle *opcode_handle,
+                 int numberOfModes,
+                 unsigned int sh_format)
+{
+  int i;
+
+  if (numberOfModes == 0)
+    return opcode_handle->opc0[0];
+
+  for (i = 0; i <= numberOfModes; i++)
+    if (opcode_handle->opc0[i]->sh_format & sh_format)
+      return opcode_handle->opc0[i];
+
+  return NULL;
+}
diff --git a/gas/config/tc-xgate.h b/gas/config/tc-xgate.h
new file mode 100644 (file)
index 0000000..7f414e5
--- /dev/null
@@ -0,0 +1,111 @@
+/* tc-xgate.h -- Header file for tc-xgate.c.
+   Copyright 2010, 2011, 2012 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.  */
+
+#define TC_XGATE
+#define cpuxgate 1
+
+struct fix;
+
+/* Define TC_M68K so that we can use the MRI mode.  */
+#define TC_M68K
+
+#define TARGET_BYTES_BIG_ENDIAN 1
+
+/* Motorola assembler specs does not require '.' before pseudo-ops.  */
+#define NO_PSEUDO_DOT 1
+
+/* The target BFD architecture.  */
+#define TARGET_ARCH (xgate_arch ())
+extern enum bfd_architecture xgate_arch (void);
+
+#define TARGET_MACH (xgate_mach ())
+extern int xgate_mach (void);
+
+#define TARGET_FORMAT (xgate_arch_format ())
+extern const char *xgate_arch_format (void);
+
+#define LISTING_WORD_SIZE 1            /* A word is 1 bytes.  */
+#define LISTING_LHS_WIDTH 4            /* One word on the first line.  */
+#define LISTING_LHS_WIDTH_SECOND 4     /* One word on the second line.  */
+#define LISTING_LHS_CONT_LINES 4       /* And 4 lines max.  */
+#define LISTING_HEADER xgate_listing_header ()
+extern const char *xgate_listing_header (void);
+
+/* Permit temporary numeric labels.  */
+#define LOCAL_LABELS_FB 1
+
+#define tc_init_after_args xgate_init_after_args
+extern void xgate_init_after_args (void);
+
+#define md_parse_long_option xgate_parse_long_option
+extern int xgate_parse_long_option (char *);
+
+#define DWARF2_LINE_MIN_INSN_LENGTH 1
+
+/* Use 32-bit address to represent a symbol address so that we can
+   represent them with their page number.  */
+#define DWARF2_ADDR_SIZE(bfd) 4
+
+/* We don't need to handle .word strangely.  */
+#define WORKING_DOT_WORD
+
+#define md_number_to_chars           number_to_chars_bigendian
+
+/* Relax table to translate short relative branches (-128..127) into
+   absolute branches.  */
+#define TC_GENERIC_RELAX_TABLE md_relax_table
+extern struct relax_type md_relax_table[];
+
+/* GAS only handles relaxations for pc-relative data targeting addresses
+   in the same segment, we have to encode all other cases  */
+/* FIXME: impliment this.  */
+/* #define md_relax_frag(SEG, FRAGP, STRETCH)          \
+ ((FRAGP)->fr_symbol != NULL                           \
+  && S_GET_SEGMENT ((FRAGP)->fr_symbol) == (SEG)       \
+  ? relax_frag (SEG, FRAGP, STRETCH)                   \
+  : xgate_relax_frag (SEG, FRAGP, STRETCH))
+extern long xgate_relax_frag (segT, fragS*, long); */
+
+#define TC_HANDLES_FX_DONE
+
+#define DIFF_EXPR_OK           /* .-foo gets turned into PC relative relocs */
+
+/* Values passed to md_apply_fix don't include the symbol value.  */
+#define MD_APPLY_SYM_VALUE(FIX) 0
+
+/* No shared lib support, so we don't need to ensure externally
+   visible symbols can be overridden.  */
+#define EXTERN_FORCE_RELOC 0
+
+#define TC_FORCE_RELOCATION(fix) tc_xgate_force_relocation (fix)
+extern int tc_xgate_force_relocation (struct fix *);
+
+#define tc_fix_adjustable(X) tc_xgate_fix_adjustable(X)
+extern int tc_xgate_fix_adjustable (struct fix *);
+
+#define md_operand(x)
+
+#define elf_tc_final_processing        xgate_elf_final_processing
+extern void xgate_elf_final_processing (void);
+
+#if 0
+#define tc_print_statistics(FILE) xgate_print_statistics (FILE)
+extern void xgate_print_statistics (FILE *);
+#endif
index 781cc9d..99de3d7 100644 (file)
@@ -86,6 +86,7 @@ case ${cpu} in
   tilegx*)             cpu_type=tilegx endian=little ;;
   v850*)               cpu_type=v850 ;;
   x86_64*)             cpu_type=i386 arch=x86_64;;
+  xgate)               cpu_type=xgate ;;
   xtensa*)             cpu_type=xtensa arch=xtensa ;;
   *)                   cpu_type=${cpu} ;;
 esac
@@ -418,6 +419,8 @@ case ${generic_target} in
   vax-*-linux-*)                       fmt=elf em=linux ;;
 
   xstormy16-*-*)                       fmt=elf ;;
+  
+  xgate-*-*)                           fmt=elf ;;
 
   xtensa*-*-*)                         fmt=elf ;;
 
index 34ccae5..1fd3e1b 100644 (file)
@@ -72,6 +72,7 @@ CPU_DOCS = \
        c-tilepro.texi \
        c-vax.texi \
        c-v850.texi \
+       c-xgate.texi \
        c-xstormy16.texi \
        c-xtensa.texi \
        c-z80.texi \
index e9edb0e..375e513 100644 (file)
@@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/../bfd/acinclude.m4 \
        $(top_srcdir)/../config/depstand.m4 \
        $(top_srcdir)/../config/gettext-sister.m4 \
        $(top_srcdir)/../config/largefile.m4 \
+       $(top_srcdir)/../config/lcmessage.m4 \
        $(top_srcdir)/../config/lead-dot.m4 \
        $(top_srcdir)/../config/nls.m4 \
        $(top_srcdir)/../config/override.m4 \
@@ -312,6 +313,7 @@ CPU_DOCS = \
        c-tilepro.texi \
        c-vax.texi \
        c-v850.texi \
+       c-xgate.texi \
        c-xstormy16.texi \
        c-xtensa.texi \
        c-z80.texi \
index 63282f2..9a55441 100644 (file)
@@ -72,6 +72,7 @@
 @set TILEPRO
 @set V850
 @set VAX
+@set XGATE
 @set XSTORMY16
 @set XTENSA
 @set Z80
index a648f09..034cc92 100644 (file)
@@ -7029,6 +7029,9 @@ subject, see the hardware manufacturer's manual.
 @ifset V850
 * V850-Dependent::              V850 Dependent Features
 @end ifset
+@ifset XGATE
+* XGATE-Dependent::             XGATE Features
+@end ifset
 @ifset XSTORMY16
 * XSTORMY16-Dependent::         XStormy16 Dependent Features
 @end ifset
@@ -7256,6 +7259,10 @@ family.
 @include c-v850.texi
 @end ifset
 
+@ifset XGATE
+@include c-xgate.texi
+@end ifset
+
 @ifset XSTORMY16
 @include c-xstormy16.texi
 @end ifset
diff --git a/gas/doc/c-xgate.texi b/gas/doc/c-xgate.texi
new file mode 100644 (file)
index 0000000..dc802a0
--- /dev/null
@@ -0,0 +1,209 @@
+@c Copyright 2012
+@c Free Software Foundation, Inc.
+@c This is part of the GAS manual.
+@c For copying conditions, see the file as.texinfo.
+@ifset GENERIC
+@page
+@node XGATE-Dependent
+@chapter XGATE Dependent Features
+@end ifset
+@ifclear GENERIC
+@node Machine Dependencies
+@chapter XGATE Dependent Features
+@end ifclear
+
+@cindex XGATE support
+@menu
+* XGATE-Opts::                   XGATE Options
+* XGATE-Syntax::                 Syntax
+* XGATE-Directives::             Assembler Directives
+* XGATE-Float::                  Floating Point
+* XGATE-opcodes::                Opcodes
+@end menu
+
+@node XGATE-Opts
+@section XGATE Options
+
+@cindex options, XGATE
+@cindex XGATE options
+The Freescale XGATE version of @code{@value{AS}} has a few machine
+dependent options.
+
+@table @code
+
+@cindex @samp{-mshort}
+@item -mshort
+This option controls the ABI and indicates to use a 16-bit integer ABI.
+It has no effect on the assembled instructions.
+This is the default.
+
+@cindex @samp{-mlong}
+@item -mlong
+This option controls the ABI and indicates to use a 32-bit integer ABI.
+
+@cindex @samp{-mshort-double}
+@item -mshort-double
+This option controls the ABI and indicates to use a 32-bit float ABI.
+This is the default.
+
+@cindex @samp{-mlong-double}
+@item -mlong-double
+This option controls the ABI and indicates to use a 64-bit float ABI.
+
+@cindex @samp{--print-insn-syntax}
+@item --print-insn-syntax
+You can use the @samp{--print-insn-syntax} option to obtain the
+syntax description of the instruction when an error is detected.
+
+@cindex @samp{--print-opcodes}
+@item --print-opcodes
+The @samp{--print-opcodes} option prints the list of all the
+instructions with their syntax. Once the list is printed
+@code{@value{AS}} exits.
+
+@end table
+
+@node XGATE-Syntax
+@section Syntax
+
+@cindex XGATE syntax
+@cindex syntax, XGATE
+
+In XGATE RISC syntax, the instruction name comes first and it may
+be followed by up to three operands. Operands are separated by commas
+(@samp{,}). @code{@value{AS}} will complain if too many operands are specified
+for a given instruction. The same will happen if you specified too few
+ operands.
+
+@smallexample
+nop
+ldl  #23
+CMP  R1, R2
+@end smallexample
+
+@cindex line comment character, XGATE
+@cindex XGATE line comment character
+The presence of a @samp{;} character or a @samp{!} character anywhere
+on a line indicates the start of a comment that extends to the end of
+that line.
+
+A @samp{*} or a @samp{#} character at the start of a line also
+introduces a line comment, but these characters do not work elsewhere
+on the line.  If the first character of the line is a @samp{#} then as
+well as starting a comment, the line could also be logical line number
+directive (@pxref{Comments}) or a preprocessor control command
+(@pxref{Preprocessing}).
+
+@cindex line separator, XGATE
+@cindex statement separator, XGATE
+@cindex XGATE line separator
+The XGATE assembler does not currently support a line separator
+character.
+
+@cindex XGATE addressing modes
+@cindex addressing modes, XGATE
+The following addressing modes are understood for XGATE:
+@table @dfn
+@item Inherent
+@samp{}
+
+@item Immediate 3 Bit Wide
+@samp{#@var{number}}
+
+@item Immediate 4 Bit Wide
+@samp{#@var{number}}
+
+@item Immediate 8 Bit Wide
+@samp{#@var{number}}
+
+@item Monadic Addressing
+@samp{@var{reg}}
+
+@item Dyadic Addressing
+@samp{@var{reg}, @var{reg}}
+
+@item Triadic Addressing
+@samp{@var{reg}, @var{reg}, @var{reg}}
+
+@item Relative Addressing 9 Bit Wide
+@samp{*@var{symbol}}
+
+@item Relative Addressing 10 Bit Wide
+@samp{*@var{symbol}}
+
+@item Index Register plus Immediate Offset
+@samp{@var{reg}, (@var{reg}, #@var{number})}
+
+@item Index Register plus Register Offset
+@samp{@var{reg}, @var{reg}, @var{reg}}
+
+@item Index Register plus Register Offset with Post-increment
+@samp{@var{reg}, @var{reg}, @var{reg}+}
+
+@item Index Register plus Register Offset with Pre-decrement
+@samp{@var{reg}, @var{reg}, -@var{reg}}
+
+The register can be either @samp{R0}, @samp{R1}, @samp{R2}, @samp{R3},
+@samp{R4}, @samp{R5}, @samp{R6} or @samp{R7}.
+
+@end table
+
+Convience macro opcodes to deal with 16-bit values have been added.  
+
+@table @dfn
+
+@item Immediate 16 Bit Wide
+@samp{#@var{number}}, or @samp{*@var{symbol}}
+
+For example:
+
+@smallexample
+ldw R1, #1024
+ldw R3, timer
+ldw R1, (R1, #0)
+COM R1
+stw R2, (R1, #0)
+@end smallexample
+@end table
+
+@node XGATE-Directives
+@section Assembler Directives
+
+@cindex assembler directives, XGATE
+@cindex XGATE assembler directives
+
+The XGATE version of @code{@value{AS}} have the following
+specific assembler directives:
+
+@node XGATE-Float
+@section Floating Point
+
+@cindex floating point, XGATE
+@cindex XGATE floating point
+Packed decimal (P) format floating literals are not supported(yet).
+
+The floating point formats generated by directives are these.
+
+@table @code
+@cindex @code{float} directive, XGATE
+@item .float
+@code{Single} precision floating point constants.
+
+@cindex @code{double} directive, XGATE
+@item .double
+@code{Double} precision floating point constants.
+
+@cindex @code{extend} directive XGATE
+@cindex @code{ldouble} directive XGATE
+@item .extend
+@itemx .ldouble
+@code{Extended} precision (@code{long double}) floating point constants.
+@end table
+
+@need 2000
+@node XGATE-opcodes
+@section Opcodes
+
+@cindex XGATE opcodes
+@cindex instruction set, XGATE
+
index 76f3dc1..9d394a3 100644 (file)
@@ -1,3 +1,18 @@
+2012-05-03  Sean Keys  <skeys@ipdatasys.com>
+
+       * gas/all/gas.exp: Added xgate tex entry.
+       * gas/xgate/abi-xgate-16-32.d: Simple ABI flag test.
+       * gas/xgate/abi-xgate-16-64.d: Ditto
+       * gas/xgate/abi-xgate-32-32.d: Ditto
+       * gas/xgate/abi-xgate-32-64.d: Ditto
+       * gas/xgate/abi.s: Source file for ABI tests.
+       * gas/xgate/all_insns.d: Dump file for all instructions test.
+       * gas/xgate/all_insns.s: Source file for all instructions test.
+       * gas/xgate/insns-dwarf2.d: Dump file for dwarf2 test.
+       * gas/xgate/insns.d: Dump file for instructions test.
+       * gas/xgate/insns.s: Source file for instructions test.
+       * gas/xgate/xgate.exp: XGATE tests file.
+
 2012-04-27  David S. Miller  <davem@davemloft.net>
 
        * gas/sparc/sparc.exp: Run cfr test.
index 7026811..2cef5dd 100644 (file)
@@ -133,10 +133,10 @@ case $target_triplet in {
        # These targets fail redef2 because they disallow redefined
        # symbols on relocs.
        setup_xfail "m68hc1*-*-*" "m6811-*-*" "m6812-*-*"
-       setup_xfail "rx-*-*" "vax*-*-*" "z8k-*-*"
+       setup_xfail "rx-*-*" "vax*-*-*" "xgate*-*-*" "z8k-*-*"
        run_dump_test redef2
        setup_xfail "m68hc1*-*-*" "m6811-*-*" "m6812-*-*"
-       setup_xfail "rx-*-*" "vax*-*-*" "z8k-*-*"
+       setup_xfail "rx-*-*" "vax*-*-*" "xgate*-*-*" "z8k-*-*"
        # rs6000-aix disallows redefinition via .comm.
        setup_xfail "*-*-aix*"
        # SOM uses a different syntax for .comm
diff --git a/gas/testsuite/gas/xgate/abi-xgate-16-32.d b/gas/testsuite/gas/xgate/abi-xgate-16-32.d
new file mode 100644 (file)
index 0000000..a2368d8
--- /dev/null
@@ -0,0 +1,8 @@
+#objdump: -p
+#as:     -mshort-double
+#name:   Elf flags XGATE 16-bit int, 32-bit double
+#source:  abi.s
+
+.*: +file format elf32\-xgate
+private flags = 80:\[abi=16-bit int, 32-bit double, cpu=XGATE\]
+
diff --git a/gas/testsuite/gas/xgate/abi-xgate-16-64.d b/gas/testsuite/gas/xgate/abi-xgate-16-64.d
new file mode 100644 (file)
index 0000000..185cb6b
--- /dev/null
@@ -0,0 +1,7 @@
+#objdump: -p
+#as:     
+#name:   Elf flags XGATE 16-bit int, 64-bit double
+#source:  abi.s
+
+.*: +file format elf32\-xgate
+private flags = 82:\[abi=16-bit int, 64-bit double, cpu=XGATE\]
diff --git a/gas/testsuite/gas/xgate/abi-xgate-32-32.d b/gas/testsuite/gas/xgate/abi-xgate-32-32.d
new file mode 100644 (file)
index 0000000..5ba4b65
--- /dev/null
@@ -0,0 +1,7 @@
+#objdump: -p
+#as:     -mlong -mshort-double
+#name:   Elf flags XGATE 32-bit int, 32-bit double
+#source:  abi.s
+
+.*: +file format elf32\-xgate
+private flags = 81:\[abi=32-bit int, 32-bit double, cpu=XGATE\]
diff --git a/gas/testsuite/gas/xgate/abi-xgate-32-64.d b/gas/testsuite/gas/xgate/abi-xgate-32-64.d
new file mode 100644 (file)
index 0000000..e454c21
--- /dev/null
@@ -0,0 +1,7 @@
+#objdump: -p
+#as:     -mlong
+#name:   Elf flags XGATE 32-bit int, 64-bit double
+#source:  abi.s
+
+.*: +file format elf32\-xgate
+private flags = 83:\[abi=32-bit int, 64-bit double, cpu=XGATE\]
diff --git a/gas/testsuite/gas/xgate/abi.s b/gas/testsuite/gas/xgate/abi.s
new file mode 100644 (file)
index 0000000..a5016eb
--- /dev/null
@@ -0,0 +1,4 @@
+       .sect .text
+       .globl L1
+L1:
+       rts
diff --git a/gas/testsuite/gas/xgate/all_insns.d b/gas/testsuite/gas/xgate/all_insns.d
new file mode 100644 (file)
index 0000000..94690de
--- /dev/null
@@ -0,0 +1,130 @@
+#objdump: -d --prefix-addresses --reloc
+#as: 
+#name: all_insns
+
+# Test handling of basic instructions.
+
+.*: +file format elf32\-xgate
+
+Disassembly of section .text:
+0+0000 <L0> adc R1, R2, R3
+0+0002 <L1> bcc \*228  Abs\* 0x000000e6 <END_CODE>
+0+0004 <L2> add R4, R5, R6
+0+0006 <L3> addl R7, #0xe1
+0+0008 <L3\+0x2> addh R7, #0x00 Abs\* 0x000000e1 <L103\+0x1>
+0+000a <L4> addh R1, #0xff
+0+000c <L5> addl R2, #0xff Abs\* 0x0000ffff <END_CODE\+0xff19>
+0+000e <L6> addl R4, #0x44
+0+0010 <L6\+0x2> addh R4, #0x1f Abs\* 0x00001f44 <END_CODE\+0x1e5e>
+0+0012 <L7> and R3, R4, R5
+0+0014 <L8> andl R1, #0x04
+0+0016 <L8\+0x2> andh R1, #0x80 Abs\* 0x00008004 <END_CODE\+0x7f1e>
+0+0018 <L9> addl R5, #0xe6
+                       18: R_XGATE_IMM8_LO     .text
+0+001a <L9\+0x2> addh R5, #0x00 Abs\* 0x000000e6 <END_CODE>
+                       1a: R_XGATE_IMM8_HI     .text
+0+001c <L10> andl R7, #0xe6
+                       1c: R_XGATE_IMM8_LO     .text
+0+001e <L10\+0x2> andh R7, #0x00 Abs\* 0x000000e6 <END_CODE>
+                       1e: R_XGATE_IMM8_HI     .text
+0+0020 <L11> andl R4, #0x01
+0+0022 <L11\+0x2> andh R4, #0xff Abs\* 0x0000ff01 <END_CODE\+0xfe1b>
+0+0024 <L12> andl R3, #0x01
+0+0026 <L13> andh R6, #0xff Abs\* 0x0000ff01 <END_CODE\+0xfe1b>
+0+0028 <L14> asr R0, #0x03
+0+002a <L15> asr R1, R2
+0+002c <L16> bcc \*186  Abs\* 0x000000e6 <END_CODE>
+0+002e <L17> bcs \*184  Abs\* 0x000000e6 <END_CODE>
+0+0030 <L18> beq \*182  Abs\* 0x000000e6 <END_CODE>
+0+0032 <L19> bfext R3, R4, R5
+0+0034 <L20> bffo R6, R7
+0+0036 <L21> bfins R0, R1, R2
+0+0038 <L22> bfinsi R3, R4, R5
+0+003a <L23> bfinsx R6, R7, R0
+0+003c <L24> bge \*170  Abs\* 0x000000e6 <END_CODE>
+0+003e <L25> bgt \*168  Abs\* 0x000000e6 <END_CODE>
+0+0040 <L26> bhi \*166  Abs\* 0x000000e6 <END_CODE>
+0+0042 <L27> bcc \*164  Abs\* 0x000000e6 <END_CODE>
+0+0044 <L28> bith R1, #0x20
+0+0046 <L29> bitl R2, #0x00
+0+0048 <L30> ble \*158  Abs\* 0x000000e6 <END_CODE>
+0+004a <L31> bcs \*156  Abs\* 0x000000e6 <END_CODE>
+0+004c <L32> bls \*154  Abs\* 0x000000e6 <END_CODE>
+0+004e <L33> blt \*152  Abs\* 0x000000e6 <END_CODE>
+0+0050 <L34> bmi \*150  Abs\* 0x000000e6 <END_CODE>
+0+0052 <L35> bne \*148  Abs\* 0x000000e6 <END_CODE>
+0+0054 <L36> bpl \*146  Abs\* 0x000000e6 <END_CODE>
+0+0056 <L37> bra \*144  Abs\* 0x000000e6 <END_CODE>
+       ...
+0+005a <L39> bvc \*140  Abs\* 0x000000e6 <END_CODE>
+0+005c <L40> bvs \*138  Abs\* 0x000000e6 <END_CODE>
+0+005e <L41> sub R0, R1, R2
+0+0060 <L42> cmpl R3, #0xff
+0+0062 <L43> xnor R4, R0, R5
+0+0064 <L44> sbc R0, R6, R7
+0+0066 <L45> cmpl R1, #0xff Abs\* 0x0000ffdd <END_CODE\+0xfef7>
+0+0068 <L45\+0x2> cpch R1, #0xff
+0+006a <L46> cpch R2, #0xff Abs\* 0x0000ffff <END_CODE\+0xff19>
+0+006c <L47> csem #0x4
+0+006e <L48> csem R5
+0+0070 <L49> csl R6, #0x0b
+0+0072 <L50> csl R7, R0
+0+0074 <L51> csr R1, #0x02
+0+0076 <L52> csr R2, R3
+0+0078 <L53> jal R4
+0+007a <L54> ldb R5, \(R6, #0x14\)
+0+007c <L55> ldb R7, \(R0, R1\+\)
+0+007e <L56> ldb R7, \(R0, \-R1\)
+0+0080 <L57> ldb R0, \(R0, R0\)
+0+0082 <L58> ldh R1, #0xff
+0+0084 <L59> ldl R2, #0xff Abs\* 0x0000ffff <END_CODE\+0xff19>
+0+0086 <L60> ldl R3, #0xe6
+                       86: R_XGATE_IMM8_LO     .text
+0+0088 <L60\+0x2> ldh R3, #0x00 Abs\* 0x000000e6 <END_CODE>
+                       88: R_XGATE_IMM8_HI     .text
+0+008a <L61> ldw R4, \(R5, #0x14\)
+0+008c <L62> ldw R5, \(R6, R7\+\)
+0+008e <L63> ldw R5, \(R6, \-R7\)
+0+0090 <L64> ldw R1, \(R2, R4\)
+0+0092 <L65> lsl R1, #0x04
+0+0094 <L66> lsl R2, R3
+0+0096 <L67> lsr R4, #0x05
+0+0098 <L68> lsr R5, R6
+0+009a <L69> or R6, R0, R7
+0+009c <L70> sub R1, R0, R2
+0+009e <L71> nop
+0+00a0 <L72> or R1, R2, R3
+0+00a2 <L73> orh R4, #0xff
+0+00a4 <L74> orl R5, #0xff
+0+00a6 <L75> par R6
+0+00a8 <L76> rol R7, #0x06
+0+00aa <L77> rol R1, R2
+0+00ac <L78> ror R3, #0x05
+0+00ae <L79> ror R4, R5
+0+00b0 <L80> rts
+0+00b2 <L81> sbc R1, R2, R3
+0+00b4 <L82> ssem #0x4
+0+00b6 <L83> ssem R1
+0+00b8 <L84> sex R2
+0+00ba <L85> sif
+0+00bc <L86> sif R4
+0+00be <L87> stb R5, \(R6, #0x5\)
+0+00c0 <L88> stb R0, \(R0, R0\+\)
+0+00c2 <L89> stb R0, \(R0, \-R0\)
+0+00c4 <L90> stb R2, \(R0, R0\)
+0+00c6 <L91> stw R1, \(R2, #0x10\)
+0+00c8 <L92> stw R1, \(R2, R3\+\)
+0+00ca <L93> stw R1, \(R2, \-R3\)
+0+00cc <L94> stw R2, \(R3, R4\)
+0+00ce <L95> sub R3, R4, R6
+0+00d0 <L96> subl R4, #0xff
+0+00d2 <L96\+0x2> subh R4, #0xff Abs\* 0x0000ffff <END_CODE\+0xff19>
+0+00d4 <L97> subh R5, #0xff
+0+00d6 <L98> subl R6, #0xff Abs\* 0x0000ffff <END_CODE\+0xff19>
+0+00d8 <L99> tfr R7, PC
+0+00da <L100> tfr R7, CCR
+0+00dc <L101> tfr CCR, R7
+0+00de <L102> sub R0, R1, R0
+0+00e0 <L103> xnor R1, R2, R3
+0+00e2 <L104> xnorh R4, #0xff
+0+00e4 <L105> xnorl R5, #0xff
diff --git a/gas/testsuite/gas/xgate/all_insns.s b/gas/testsuite/gas/xgate/all_insns.s
new file mode 100644 (file)
index 0000000..20283e9
--- /dev/null
@@ -0,0 +1,111 @@
+# Example of XGATE instructions
+       .sect .text
+_start:
+L0:    adc r1, r2, r3
+L1:    bcc END_CODE
+L2:    add r4, r5, r6
+L3:    add r7 , #225
+L4:    addh r1, 255
+L5:    addl r2, #255
+L6:    add  r4, 8004
+L7:    and r3, r4, r5
+L8:    and r1, #0x8004
+L9:    add r5, END_CODE
+L10:    and r7, END_CODE
+L11:   and r4, #65281
+L12:    andl r3, #01
+L13:    andh r6, #255
+L14:    asr r0, #3
+L15:    asr r1, r2
+L16:    bcc END_CODE
+L17:    bcs END_CODE
+L18:    beq END_CODE
+L19:    bfext r3, r4, r5
+L20:    bffo r6, r7
+L21:    bfins r0, r1, r2
+L22:    bfinsi r3, r4, r5
+L23:    bfinsx r6, r7, r0
+L24:    bge END_CODE
+L25:    bgt END_CODE
+L26:    bhi END_CODE
+L27:    bhs END_CODE
+L28:    bith r1, #32
+L29:    bitl r2, #0
+L30:    ble  END_CODE
+L31:    blo END_CODE
+L32:    bls END_CODE
+L33:   blt END_CODE
+L34:   bmi END_CODE
+L35:    bne END_CODE
+L36:    bpl END_CODE
+L37:    bra END_CODE
+L38:    brk
+L39:    bvc END_CODE
+L40:    bvs END_CODE
+L41:    cmp r1, r2
+L42:    cmpl r3, #255
+L43:    com r4, r5
+L44:    cpc r6, r7
+L45:    cmp r1, #65535
+L46:    cpch r2, #255
+L47:    csem #4
+L48:    csem r5
+L49:    csl r6, #11
+L50:    csl r7, r0
+L51:    csr r1, #2
+L52:    csr r2, r3
+L53:    jal r4
+L54:    ldb r5, (r6, #20)
+L55:    ldb r7, (r0, r1+)
+L56:    ldb r7, (r0, -r1)
+L57:    ldb r0, (r0, r0)
+L58:    ldh r1, #255
+L59:    ldl r2, #255
+L60:   ldd r3, END_CODE
+L61:    ldw r4, (r5, #20)
+L62:    ldw r5, (r6, r7+)
+L63:    ldw r5, (r6, -r7)
+L64:    ldw r1, (r2, r4)
+L65:    lsl r1, #4
+L66:    lsl r2, r3
+L67:    lsr r4, #5
+L68:    lsr r5, r6
+L69:    mov r6, r7
+L70:    neg r1, r2
+L71:    nop
+L72:    or r1, r2, r3
+L73:    orh r4, #255
+L74:    orl r5, #255
+L75:    par r6
+L76:    rol r7, #6
+L77:    rol r1, r2
+L78:    ror r3, #5
+L79:    ror r4, r5
+L80:    rts
+L81:    sbc r1, r2, r3
+L82:    ssem #4
+L83:    ssem r1
+L84:    sex r2
+L85:    sif
+L86:    sif r4
+L87:    stb r5, (r6, #5)
+L88:    stb r0, (r0, r0+)
+L89:    stb r0, (r0, -r0)
+L90:    stb r2, (r0, r0)
+L91:    stw r1, (r2, #16)
+L92:    stw r1, (r2, r3+)
+L93:    stw r1, (r2, -r3)
+L94:    stw r2, (r3 ,r4)
+L95:    sub r3, r4, r6
+L96:    sub r4, #65535
+L97:    subh r5, #255
+L98:    subl r6, #255
+L99:    tfr r7, pc
+L100:   tfr r7,ccr
+L101:   tfr ccr, r7
+L102:   tst r1
+L103:   xnor r1, r2, r3
+L104:   xnorh r4, #255
+L105:   xnorl r5, #255  
+END_CODE:
+
diff --git a/gas/testsuite/gas/xgate/insns-dwarf2.d b/gas/testsuite/gas/xgate/insns-dwarf2.d
new file mode 100644 (file)
index 0000000..3a8e699
--- /dev/null
@@ -0,0 +1,84 @@
+#objdump: -S
+#as: -gdwarf2
+#name: Dwarf2 test on insns.s
+#source: insns.s
+
+# Test handling of basic instructions.
+
+.*: +file format elf32\-xgate
+
+Disassembly of section .text:
+
+0+0000 <_start>:
+       
+       .globl _start
+       .sect .text
+
+_start:
+       ldw R2, #block\+1024
+   0:  f2 00           ldl R2, #0x00
+   2:  fa 04           ldh R2, #0x04 Abs\* 0x400 <block_end>
+       ldw R3, #block
+   4:  f3 00           ldl R3, #0x00
+   6:  fb 00           ldh R3, #0x00 Abs\* 0x0 <_start>
+       ldw R1, #1
+   8:  f1 01           ldl R1, #0x01
+   a:  f9 00           ldh R1, #0x00 Abs\* 0x1 <_start\+0x1>
+
+0+000c <Loop>:
+Loop:  
+       bra test
+   c:  3c 04           bra \*10  Abs\* 0x16 <test>
+       nop
+   e:  01 00           nop
+       bne Loop
+  10:  25 fd           bne \*-4  Abs\* 0xc <Loop>
+
+0+0012 <Stop>:
+  12:  cd 03           subh R5, #0x03
+Stop:
+       
+       .byte 0xcd
+       .byte 3 
+       bra _start
+  14:  3f f5           bra \*-20  Abs\* 0x0 <_start>
+
+0+0016 <test>:
+
+test:
+       ldw R5, #2
+  16:  f5 02           ldl R5, #0x02
+  18:  fd 00           ldh R5, #0x00 Abs\* 0x2 <_start\+0x2>
+       bra test2
+  1a:  3c 01           bra \*4  Abs\* 0x1e <test2>
+       rts
+  1c:  02 00           rts
+
+0+001e <test2>:
+
+value = 23
+               
+       .globl test2
+test2:
+       ldw R3, #value
+  1e:  f3 17           ldl R3, #0x17
+  20:  fb 00           ldh R3, #0x00 Abs\* 0x17 <test\+0x1>
+       stw R4, \(R3, #0\)
+  22:  5c 60           stw R4, \(R3, #0x0\)
+       ldw R4, #24\+_start\-44
+  24:  f4 ec           ldl R4, #0xec
+  26:  fc ff           ldh R4, #0xff Abs\* 0xffec <block_end\+0xfbec>
+       bra Stop
+  28:  3f f4           bra \*-22  Abs\* 0x12 <Stop>
+
+0+002a <L1>:
+L1:    
+       ldw R1, test2
+  2a:  f1 1e           ldl R1, #0x1e
+  2c:  f9 00           ldh R1, #0x00 Abs\* 0x1e <test2>
+       ldw R2, test2
+  2e:  f2 1e           ldl R2, #0x1e
+  30:  fa 00           ldh R2, #0x00 Abs\* 0x1e <test2>
+       rts
+  32:  02 00           rts
+
diff --git a/gas/testsuite/gas/xgate/insns.d b/gas/testsuite/gas/xgate/insns.d
new file mode 100644 (file)
index 0000000..a7d4d58
--- /dev/null
@@ -0,0 +1,45 @@
+#objdump: -d --prefix-addresses --reloc
+#as: 
+#name: insns
+
+# Test handling of basic instructions.
+
+.*: +file format elf32\-xgate
+
+Disassembly of section .text:
+0+0000 <\_start> ldl R2, #0x00
+                       0: R_XGATE_IMM8_LO      .bss
+0+0002 <\_start\+0x2> ldh R2, #0x04 Abs\* 0x00000400 <block_end>
+                       2: R_XGATE_IMM8_HI      .bss
+0+0004 <\_start\+0x4> ldl R3, #0x00
+                       4: R_XGATE_IMM8_LO      .bss
+0+0006 <\_start\+0x6> ldh R3, #0x00 Abs\* 0x00000000 <\_start>
+                       6: R_XGATE_IMM8_HI      .bss
+0+0008 <\_start\+0x8> ldl R1, #0x01
+0+000a <\_start\+0xa> ldh R1, #0x00 Abs\* 0x00000001 <\_start\+0x1>
+0+000c <Loop> bra \*10  Abs\* 0x00000016 <test>
+0+000e <Loop\+0x2> nop
+0+0010 <Loop\+0x4> bne \*\-4  Abs\* 0x0000000c <Loop>
+0+0012 <Stop> subh R5, #0x03
+0+0014 <Stop\+0x2> bra \*\-20  Abs\* 0x00000000 <\_start>
+0+0016 <test> ldl R5, #0x02
+0+0018 <test\+0x2> ldh R5, #0x00 Abs\* 0x00000002 <\_start\+0x2>
+0+001a <test\+0x4> bra \*4  Abs\* 0x0000001e <test2>
+0+001c <test\+0x6> rts
+0+001e <test2> ldl R3, #0x17
+0+0020 <test2\+0x2> ldh R3, #0x00 Abs\* 0x00000017 <test\+0x1>
+0+0022 <test2\+0x4> stw R4, \(R3, #0x0\)
+0+0024 <test2\+0x6> ldl R4, #0xec
+                       24: R_XGATE_IMM8_LO     .text
+0+0026 <test2\+0x8> ldh R4, #0xff Abs\* 0x0000ffec <block_end\+0xfbec>
+                       26: R_XGATE_IMM8_HI     .text
+0+0028 <test2\+0xa> bra \*\-22  Abs\* 0x00000012 <Stop>
+0+002a <L1> ldl R1, #0x1e
+                       2a: R_XGATE_IMM8_LO     .text
+0+002c <L1\+0x2> ldh R1, #0x00 Abs\* 0x0000001e <test2>
+                       2c: R_XGATE_IMM8_HI     .text
+0+002e <L1\+0x4> ldl R2, #0x1e
+                       2e: R_XGATE_IMM8_LO     .text
+0+0030 <L1\+0x6> ldh R2, #0x00 Abs\* 0x0000001e <test2>
+                       30: R_XGATE_IMM8_HI     .text
+0+0032 <L1\+0x8> rts
diff --git a/gas/testsuite/gas/xgate/insns.s b/gas/testsuite/gas/xgate/insns.s
new file mode 100644 (file)
index 0000000..e359e68
--- /dev/null
@@ -0,0 +1,43 @@
+# Test for correct generation of XGATE insns.
+       
+       .globl _start
+       .sect .text
+
+_start:
+       ldw R2, #block+1024
+       ldw R3, #block
+       ldw R1, #1
+Loop:  
+       bra test
+       nop
+       bne Loop
+Stop:
+       
+       .byte 0xcd
+       .byte 3 
+       bra _start
+
+test:
+       ldw R5, #2
+       bra test2
+       rts
+
+value = 23
+               
+       .globl test2
+test2:
+       ldw R3, #value
+       stw R4, (R3, #0)
+       ldw R4, #24+_start-44
+       bra Stop
+L1:    
+       ldw R1, test2
+       ldw R2, test2
+       rts
+
+       .sect .data
+
+       .sect .bss
+block:
+       .space  1024
+block_end:
diff --git a/gas/testsuite/gas/xgate/xgate.exp b/gas/testsuite/gas/xgate/xgate.exp
new file mode 100644 (file)
index 0000000..1af5e76
--- /dev/null
@@ -0,0 +1,19 @@
+#
+# Some generic XGATE tests
+#
+
+if ![istarget "xgate-*-*"] then {
+       return
+}
+
+# ABI tests
+run_dump_test abi-xgate-16-64
+run_dump_test abi-xgate-16-32
+run_dump_test abi-xgate-32-64
+run_dump_test abi-xgate-32-32
+
+# Some XGATE tests
+run_dump_test insns-dwarf2
+run_dump_test all_insns
+run_dump_test insns
+
index e3b1788..7a747a7 100644 (file)
@@ -1,3 +1,9 @@
+2012-05-03  Sean Keys  <skeys@ipdatasys.com>
+
+       * dis-asm.h (print_insn_xgate): Define.
+       (print_insn_xgate): Ditto.
+       Added new files for XGATE port.
+
 2012-05-02  Cary Coutant  <ccoutant@google.com>
 
        * dwarf2.def: Remove DW_FORM_GNU_ref_index,
index c9cbfbb..203b113 100644 (file)
@@ -293,6 +293,7 @@ extern int print_insn_v850          (bfd_vma, disassemble_info *);
 extern int print_insn_vax              (bfd_vma, disassemble_info *);
 extern int print_insn_w65              (bfd_vma, disassemble_info *);
 extern int print_insn_xc16x            (bfd_vma, disassemble_info *);
+extern int print_insn_xgate             (bfd_vma, disassemble_info *);
 extern int print_insn_xstormy16                (bfd_vma, disassemble_info *);
 extern int print_insn_xtensa           (bfd_vma, disassemble_info *);
 extern int print_insn_z80              (bfd_vma, disassemble_info *);
index eb6edc5..ab9b2de 100644 (file)
@@ -1,3 +1,7 @@
+2012-05-03  Sean Keys  <skeys@ipdatasys.com>
+
+       * xgate.h: Mininal file to support XGATE relocations.
+
 2012-04-27  David S. Miller  <davem@davemloft.net>
 
        * sparc.h: Add new ELF_SPARC_HWCAP_* defines for crypto,
diff --git a/include/elf/xgate.h b/include/elf/xgate.h
new file mode 100644 (file)
index 0000000..33286a8
--- /dev/null
@@ -0,0 +1,77 @@
+/* XGATE ELF support for BFD.
+   Copyright 2010, 2011, 2012 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 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.  */
+
+#ifndef _ELF_XGATE_H
+#define _ELF_XGATE_H
+
+#include "elf/reloc-macros.h"
+
+/* Relocation types.  */
+START_RELOC_NUMBERS (elf_xgate_reloc_type)
+  RELOC_NUMBER (R_XGATE_NONE, 0)
+  RELOC_NUMBER (R_XGATE_8, 1)
+  RELOC_NUMBER (R_XGATE_PCREL_8, 2)
+  RELOC_NUMBER (R_XGATE_16, 3)
+  RELOC_NUMBER (R_XGATE_32, 4)
+  RELOC_NUMBER (R_XGATE_PCREL_16, 5)
+  /* These are GNU extensions to enable C++ vtable garbage collection.  */
+  RELOC_NUMBER (R_XGATE_GNU_VTINHERIT, 6)
+  RELOC_NUMBER (R_XGATE_GNU_VTENTRY, 7)
+
+  RELOC_NUMBER (R_XGATE_24, 8)
+  RELOC_NUMBER (R_XGATE_LO16, 9)
+  RELOC_NUMBER (R_XGATE_GPAGE, 10)
+  RELOC_NUMBER (R_XGATE_PCREL_9, 11)
+  RELOC_NUMBER (R_XGATE_PCREL_10, 12)
+  RELOC_NUMBER (R_XGATE_IMM8_LO, 13)
+  RELOC_NUMBER (R_XGATE_IMM8_HI, 14)
+  RELOC_NUMBER (R_XGATE_IMM3, 15)
+  RELOC_NUMBER (R_XGATE_IMM4, 16)
+  RELOC_NUMBER (R_XGATE_IMM5, 17)
+
+  /* GNU extension for linker relaxation.
+     Mark beginning of a jump instruction (any form).  */
+  RELOC_NUMBER (R_XGATE_RL_JUMP, 18)
+
+  /* Mark beginning of Gcc relaxation group instruction.  */
+  RELOC_NUMBER (R_XGATE_RL_GROUP, 19)
+END_RELOC_NUMBERS (R_XGATE_max)
+
+/* Processor specific flags for the ELF header e_flags field.  */
+
+/* ABI identification.  */
+#define EF_XGATE_ABI  0x00000000F
+
+/* Integers are 32-bit long.  */
+#define E_XGATE_I32   0x000000001
+
+/* Doubles are 64-bit long.  */
+#define E_XGATE_F64   0x000000002
+
+#define EF_XGATE_MACH_MASK  0xF0
+
+#define EF_XGATE_MACH       0x80 /* XGATE microcontroller.  */
+
+#define E_M68HCS12X_GLOBAL  0x100
+
+/* Identify interrupt handlers.  This is used by the debugger to
+   correctly compute the stack frame.  */
+#define STO_XGATE_INTERRUPT 0x40
+     
+#endif
index d4fb384..af70340 100644 (file)
@@ -1,3 +1,7 @@
+2012-05-03  Sean Keys  <skeys@ipdatasys.com>
+
+       * xgate.h: Header file for XGATE assembler.
+
 2012-04-27  David S. Miller  <davem@davemloft.net>
 
        * sparc.h: Document new arg code' )' for crypto RS3
diff --git a/include/opcode/xgate.h b/include/opcode/xgate.h
new file mode 100644 (file)
index 0000000..c516733
--- /dev/null
@@ -0,0 +1,120 @@
+/* xgate.h -- Freescale XGATE opcode list
+   Copyright 2010, 2011, 2012 Free Software Foundation, Inc.
+   Written by Sean Keys (skeys@ipdatasys.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. */
+
+#ifndef _OPCODE_XGATE_H
+#define _OPCODE_XGATE_H
+
+/* XGATE CCR flag definitions.  */
+#define XGATE_N_BIT   0x08     /* XGN - Sign Flag */
+#define XGATE_Z_BIT   0x04     /* XGZ - Zero Flag */
+#define XGATE_V_BIT   0x02     /* XGV - Overflow Flag */
+#define XGATE_C_BIT   0x01     /* XGC - Carry Flag */
+
+/* Access Detail Notation
+   V â€” Vector fetch: always an aligned word read, lasts for at least one RISC core cycle
+   P â€” Program word fetch: always an aligned word read, lasts for at least one RISC core cycle
+   r â€” 8-bit data read: lasts for at least one RISC core cycle
+   R â€” 16-bit data read: lasts for at least one RISC core cycle
+   w â€” 8-bit data write: lasts for at least one RISC core cycle
+   W â€” 16-bit data write: lasts for at least one RISC core cycle
+   A â€” Alignment cycle: no read or write, lasts for zero or one RISC core cycles
+   f â€” Free cycle: no read or write, lasts for one RISC core cycles.  */
+#define XGATE_CYCLE_V  0x01
+#define XGATE_CYCLE_P  0x02
+#define XGATE_CYCLE_r  0x04
+#define XGATE_CYCLE_R  0x08
+#define XGATE_CYCLE_w  0x10
+#define XGATE_CYCLE_W  0x20
+#define XGATE_CYCLE_A  0x40
+#define XGATE_CYCLE_f  0x80
+
+/* Opcode format abbreviations.  */
+#define XG_INH         0x0001  /* Inherent.  */
+#define XG_I           0x0002  /* 3-bit immediate address.  */
+#define XG_R_I         0x0004  /* Register followed by 4/8-bit immediate value.  */
+#define XG_R_R         0x0008  /* Register followed by a register.  */
+#define XG_R_R_R       0x0010  /* Register followed by two registers.  */
+#define XG_R           0x0020  /* Single register.  */
+#define XG_PC          0x0040  /* PC relative 10 or 11 bit.  */
+#define XG_R_C         0x0080  /* General register followed by ccr register.  */
+#define XG_C_R         0x0100  /* CCR register followed by a general register.  */
+#define XG_R_P         0x0200  /* General register followed by pc register.  */
+#define XG_R_R_I       0x0400  /* Two general registers followed by an immediate value.  */
+#define XG_PCREL       0x0800  /* Immediate value that is relative to the current pc.  */
+
+/* XGATE operand formats as stored in the XGATE_opcode table.
+   They are only used by GAS to recognize operands.  */
+#define XGATE_OP_INH           ""
+#define XGATE_OP_TRI           "r,r,r"
+#define XGATE_OP_DYA           "r,r"
+#define XGATE_OP_IMM16          "r,if"
+#define XGATE_OP_IMM8          "r,i8"
+#define XGATE_OP_IMM4           "r,i4"
+#define XGATE_OP_IMM3          "i3"
+#define XGATE_OP_MON           "r"
+#define XGATE_OP_MON_R_C       "r,c"
+#define XGATE_OP_MON_C_R       "c,r"
+#define XGATE_OP_MON_R_P       "r,p"
+#define XGATE_OP_IDR           "r,r,+"
+#define XGATE_OP_IDO5          "r,r,i5"
+#define XGATE_OP_REL9          "b9"
+#define XGATE_OP_REL10         "ba"
+#define XGATE_OP_DYA_MON       "=r,r"
+/* Macro definitions.  */
+#define XGATE_OP_IMM16mADD    "r,if; addl addh"
+#define XGATE_OP_IMM16mAND    "r,if; andl andh"
+#define XGATE_OP_IMM16mCPC    "r,if; cmpl cpch"
+#define XGATE_OP_IMM16mSUB    "r,if; subl subh"
+#define XGATE_OP_IMM16mLDW    "r,if; ldl ldh"
+
+/* CPU variant identification.  */
+#define XGATE_V1 0x1
+#define XGATE_V2 0x2
+#define XGATE_V3 0x4
+
+/* Max opcodes per opcode handle.  */
+#define MAX_OPCODES     0x05
+
+#define MAX_DETECT_CHARS 0x10
+
+/* The opcode table definitions.  */
+struct xgate_opcode
+{
+  char * name;                  /* Op-code name.  */
+  char * constraints;           /* Constraint chars.  */
+  char * format;                /* Bit definitions.  */
+  unsigned int sh_format;       /* Shorthand format mask.  */
+  unsigned int size;            /* Opcode size in bytes.  */
+  unsigned int bin_opcode;      /* Binary opcode with operands masked off.  */
+  unsigned char cycles_min;     /* Minimum cpu cycles needed.  */
+  unsigned char cycles_max;     /* Maximum cpu cycles needed.  */
+  unsigned char set_flags_mask; /* CCR flags set.  */
+  unsigned char clr_flags_mask; /* CCR flags cleared.  */
+  unsigned char chg_flags_mask; /* CCR flags changed.  */
+  unsigned char arch;           /* CPU variant.  */
+};
+
+/* The opcode table.  The table contains all the opcodes (all pages).
+   You can't rely on the order.  */
+extern const struct xgate_opcode xgate_opcodes[];
+extern const int xgate_num_opcodes;
+
+#endif /* _OPCODE_XGATE_H */
index 94aa546..ca5ae34 100644 (file)
@@ -1,3 +1,13 @@
+2012-05-03  Sean Keys  <skeys@ipdatasys.com>
+
+       * Makefile.am (ALL_EMULATIONS): Added new emulation for XGATE
+       and XGATE (elf).
+       * Makefile.in: Rebuild.
+       * configure.tgt: Recognize XGATE.
+       * scripttempl/elfxgate.sc: New file, mostly cloned from m68hc12.
+       * emulparams/xgateelf: New emulation, mostly cloned from m68hc12.
+       * NEWS: Mention new support.
+
 2012-04-26  Hans-Peter Nilsson  <hp@axis.com>
 
        Make bfd asserts cause linker errors.
index abb16aa..65bfdcf 100644 (file)
@@ -457,6 +457,7 @@ ALL_EMULATION_SOURCES = \
        evaxnbsd.c \
        evsta.c \
        ew65.c \
+       exgateelf.c \
        ez80.c \
        ez8001.c \
        ez8002.c
@@ -1911,6 +1912,10 @@ evsta.c: $(srcdir)/emulparams/vsta.sh \
 ew65.c: $(srcdir)/emulparams/w65.sh \
   $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/w65.sc ${GEN_DEPENDS}
        ${GENSCRIPTS} w65 "$(tdir_w65)"
+exgateelf.c: $(srcdir)/emulparams/xgateelf.sh \
+  $(srcdir)/emultempl/generic.em $(ELF_DEPS) \
+  $(srcdir)/scripttempl/elfxgate.sc ${GEN_DEPENDS}
+       ${GENSCRIPTS} xgateelf "$(tdir_xgate)"
 ez80.c: $(srcdir)/emulparams/z80.sh \
   $(srcdir)/emultempl/generic.em $(srcdir)/emultempl/z80.em \
   $(srcdir)/scripttempl/z80.sc ${GEN_DEPENDS}
index 2c001c7..a9fca38 100644 (file)
@@ -764,6 +764,7 @@ ALL_EMULATION_SOURCES = \
        evaxnbsd.c \
        evsta.c \
        ew65.c \
+       exgateelf.c \
        ez80.c \
        ez8001.c \
        ez8002.c
@@ -1413,6 +1414,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/evaxnbsd.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/evsta.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ew65.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exgateelf.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ez80.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ez8001.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ez8002.Po@am__quote@
@@ -3376,6 +3378,10 @@ evsta.c: $(srcdir)/emulparams/vsta.sh \
 ew65.c: $(srcdir)/emulparams/w65.sh \
   $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/w65.sc ${GEN_DEPENDS}
        ${GENSCRIPTS} w65 "$(tdir_w65)"
+exgateelf.c: $(srcdir)/emulparams/xgateelf.sh \
+  $(srcdir)/emultempl/generic.em $(ELF_DEPS) \
+  $(srcdir)/scripttempl/elfxgate.sc ${GEN_DEPENDS}
+       ${GENSCRIPTS} xgateelf "$(tdir_xgate)"
 ez80.c: $(srcdir)/emulparams/z80.sh \
   $(srcdir)/emultempl/generic.em $(srcdir)/emultempl/z80.em \
   $(srcdir)/scripttempl/z80.sc ${GEN_DEPENDS}
diff --git a/ld/NEWS b/ld/NEWS
index 162f598..0f1b7be 100644 (file)
--- a/ld/NEWS
+++ b/ld/NEWS
@@ -1,5 +1,7 @@
 -*- text -*-
 
+* Add support for the Freescale XGATE architecture.
+
 * Add option -f FILE on AIX (for response file).
 
 * Add support for the Renesas RL78 architecture.
index c36ec51..d7ad3ba 100644 (file)
@@ -703,6 +703,8 @@ xstormy16-*-*)              targ_emul=elf32xstormy16
                        ;;
 xtensa*-*-*)           targ_emul=elf32xtensa
                        ;;
+xgate-*-*)     targ_emul=xgateelf 
+                       ;;
 z80-*-coff)            targ_emul=z80
                        ;;
 z8k-*-coff)            targ_emul=z8002; targ_extra_emuls=z8001
diff --git a/ld/emulparams/xgateelf.sh b/ld/emulparams/xgateelf.sh
new file mode 100644 (file)
index 0000000..1f9253e
--- /dev/null
@@ -0,0 +1,18 @@
+MACHINE=
+SCRIPT_NAME=elfxgate
+OUTPUT_FORMAT="elf32-xgate"
+ROM_START_ADDR=0x08000
+ROM_SIZE=0x8000
+RAM_START_ADDR=0x01100
+RAM_SIZE=0x6F00
+EEPROM_START_ADDR=0x0800
+EEPROM_SIZE=2048
+TEXT_MEMORY=text
+DATA_MEMORY=data
+EEPROM_MEMORY=eeprom
+ARCH=xgate
+MAXPAGESIZE=32
+EMBEDDED=yes
+GENERIC_BOARD=no
+TEMPLATE_NAME=elf32
+EXTRA_EM_FILE=
diff --git a/ld/scripttempl/elfxgate.sc b/ld/scripttempl/elfxgate.sc
new file mode 100644 (file)
index 0000000..0774eb2
--- /dev/null
@@ -0,0 +1,463 @@
+#
+# Unusual variables checked by this code:
+#      NOP - four byte opcode for no-op (defaults to 0)
+#      DATA_ADDR - if end-of-text-plus-one-page isn't right for data start
+#      OTHER_READWRITE_SECTIONS - other than .data .bss .ctors .sdata ...
+#              (e.g., .PARISC.global)
+#      OTHER_SECTIONS - at the end
+#      EXECUTABLE_SYMBOLS - symbols that must be defined for an
+#              executable (e.g., _DYNAMIC_LINK)
+#      TEXT_START_SYMBOLS - symbols that appear at the start of the
+#              .text section.
+#      DATA_START_SYMBOLS - symbols that appear at the start of the
+#              .data section.
+#      OTHER_BSS_SYMBOLS - symbols that appear at the start of the
+#              .bss section besides __bss_start.
+#      EMBEDDED - whether this is for an embedded system. 
+#
+# When adding sections, do note that the names of some sections are used
+# when specifying the start address of the next.
+#
+test -z "$ENTRY" && ENTRY=_start
+test -z "${BIG_OUTPUT_FORMAT}" && BIG_OUTPUT_FORMAT=${OUTPUT_FORMAT}
+test -z "${LITTLE_OUTPUT_FORMAT}" && LITTLE_OUTPUT_FORMAT=${OUTPUT_FORMAT}
+if [ -z "$MACHINE" ]; then OUTPUT_ARCH=${ARCH}; else OUTPUT_ARCH=${ARCH}:${MACHINE}; fi
+test "$LD_FLAG" = "N" && DATA_ADDR=.
+
+CTOR=".ctors ${CONSTRUCTING-0} : 
+  {
+    ${CONSTRUCTING+ PROVIDE (__CTOR_LIST__ = .); }
+    ${CONSTRUCTING+${CTOR_START}}
+    KEEP (*(.ctors))
+
+    ${CONSTRUCTING+${CTOR_END}}
+    ${CONSTRUCTING+ PROVIDE(__CTOR_END__ = .); }
+  } ${RELOCATING+ > ${TEXT_MEMORY}}"
+
+DTOR="  .dtors ${CONSTRUCTING-0} :
+  {
+    ${CONSTRUCTING+ PROVIDE(__DTOR_LIST__ = .); }
+    KEEP (*(.dtors))
+    ${CONSTRUCTING+ PROVIDE(__DTOR_END__ = .); }
+  } ${RELOCATING+ > ${TEXT_MEMORY}}"
+
+
+VECTORS="
+  /* If the 'vectors_addr' symbol is defined, it indicates the start address
+     of interrupt vectors.  This depends on the 68HC11 operating mode:
+
+                       Addr
+     Single chip       0xffc0
+     Extended mode     0xffc0
+     Bootstrap         0x00c0
+     Test              0xbfc0
+
+     In general, the vectors address is 0xffc0.  This can be overriden 
+     with the '-defsym vectors_addr=0xbfc0' ld option.
+
+     Note: for the bootstrap mode, the interrupt vectors are at 0xbfc0 but
+     they are redirected to 0x00c0 by the internal PROM.  Application's vectors
+     must also consist of jump instructions (see Motorola's manual).  */
+
+  PROVIDE (_vectors_addr = DEFINED (vectors_addr) ? vectors_addr : 0xffc0);
+  .vectors DEFINED (vectors_addr) ? vectors_addr : 0xffc0 :
+  {
+    KEEP (*(.vectors))
+  }"
+
+#
+# We provide two emulations: a fixed on that defines some memory banks
+# and a configurable one that includes a user provided memory definition.
+#
+case $GENERIC_BOARD in
+  yes|1|YES)
+       MEMORY_DEF="
+/* Get memory banks definition from some user configuration file.
+   This file must be located in some linker directory (search path
+   with -L<dir>). See fixed memory banks emulation script.  */
+INCLUDE memory.x;
+"
+       ;;
+  *)
+MEMORY_DEF="
+/* Fixed definition of the available memory banks.
+   See generic emulation script for a user defined configuration.  */
+MEMORY
+{
+  page0 (rwx) : ORIGIN = 0x0, LENGTH = 256
+  text  (rx)  : ORIGIN = ${ROM_START_ADDR}, LENGTH = ${ROM_SIZE}
+  data        : ORIGIN = ${RAM_START_ADDR}, LENGTH = ${RAM_SIZE}
+  eeprom      : ORIGIN = ${EEPROM_START_ADDR}, LENGTH = ${EEPROM_SIZE}
+}
+
+/* Setup the stack on the top of the data memory bank.  */
+PROVIDE (_stack = ${RAM_START_ADDR} + ${RAM_SIZE} - 1);
+"
+       ;;
+esac
+
+STARTUP_CODE="
+    /* Startup code.  */
+    KEEP (*(.install0))        /* Section should setup the stack pointer.  */
+    KEEP (*(.install1))        /* Place holder for applications.  */
+    KEEP (*(.install2))        /* Optional installation of data sections in RAM.  */
+    KEEP (*(.install3))        /* Place holder for applications.  */
+    KEEP (*(.install4))        /* Section that calls the main.  */
+"
+
+FINISH_CODE="
+    /* Finish code.  */
+    KEEP (*(.fini0))   /* Beginning of finish code (_exit symbol).  */
+    KEEP (*(.fini1))   /* Place holder for applications.  */
+    KEEP (*(.fini2))   /* C++ destructors.  */
+    KEEP (*(.fini3))   /* Place holder for applications.  */
+    KEEP (*(.fini4))   /* Runtime exit.  */
+"
+
+PRE_COMPUTE_DATA_SIZE="
+/* SCz: this does not work yet... This is supposed to force the loading
+   of _map_data.o (from libgcc.a) when the .data section is not empty.
+   By doing so, this should bring the code that copies the .data section
+   from ROM to RAM at init time.
+
+  ___pre_comp_data_size = SIZEOF(.data);
+  __install_data_sections = ___pre_comp_data_size > 0 ?
+               __map_data_sections : 0;
+*/
+"
+
+INSTALL_RELOC="
+  .install0 0 : { *(.install0) }
+  .install1 0 : { *(.install1) }
+  .install2 0 : { *(.install2) }
+  .install3 0 : { *(.install3) }
+  .install4 0 : { *(.install4) }
+"
+
+FINISH_RELOC="
+  .fini0 0 : { *(.fini0) }
+  .fini1 0 : { *(.fini1) }
+  .fini2 0 : { *(.fini2) }
+  .fini3 0 : { *(.fini3) }
+  .fini4 0 : { *(.fini4) }
+"
+
+BSS_DATA_RELOC="
+  .data1 0 : { *(.data1) }
+
+  /* We want the small data sections together, so single-instruction offsets
+     can access them all, and initialized data all before uninitialized, so
+     we can shorten the on-disk segment size.  */
+  .sdata   0 : { *(.sdata) }
+  .sbss    0 : { *(.sbss) }
+  .scommon 0 : { *(.scommon) }
+"
+
+SOFT_REGS_RELOC="
+  .softregs 0 : { *(.softregs) }
+"
+
+cat <<EOF
+${RELOCATING+/* Linker script for 68HC12 executable (PROM).  */}
+${RELOCATING-/* Linker script for 68HC12 object file (ld -r).  */}
+
+OUTPUT_FORMAT("${OUTPUT_FORMAT}", "${BIG_OUTPUT_FORMAT}",
+             "${LITTLE_OUTPUT_FORMAT}")
+OUTPUT_ARCH(${OUTPUT_ARCH})
+${RELOCATING+ENTRY(${ENTRY})}
+
+${RELOCATING+${LIB_SEARCH_DIRS}}
+${RELOCATING+${EXECUTABLE_SYMBOLS}}
+${RELOCATING+${MEMORY_DEF}}
+
+SECTIONS
+{
+  .hash        ${RELOCATING-0} : { *(.hash)            }
+  .dynsym      ${RELOCATING-0} : { *(.dynsym)          }
+  .dynstr      ${RELOCATING-0} : { *(.dynstr)          }
+  .gnu.version         ${RELOCATING-0} : { *(.gnu.version) }
+  .gnu.version_d       ${RELOCATING-0} : { *(.gnu.version_d) }
+  .gnu.version_r       ${RELOCATING-0} : { *(.gnu.version_r) }
+
+  .rel.text    ${RELOCATING-0} :
+    {
+      *(.rel.text)
+      ${RELOCATING+*(.rel.text.*)}
+      ${RELOCATING+*(.rel.gnu.linkonce.t.*)}
+    }
+  .rela.text   ${RELOCATING-0} :
+    {
+      *(.rela.text)
+      ${RELOCATING+*(.rela.text.*)}
+      ${RELOCATING+*(.rela.gnu.linkonce.t.*)}
+    }
+  .rel.data    ${RELOCATING-0} :
+    {
+      *(.rel.data)
+      ${RELOCATING+*(.rel.data.*)}
+      ${RELOCATING+*(.rel.gnu.linkonce.d.*)}
+    }
+  .rela.data   ${RELOCATING-0} :
+    {
+      *(.rela.data)
+      ${RELOCATING+*(.rela.data.*)}
+      ${RELOCATING+*(.rela.gnu.linkonce.d.*)}
+    }
+  .rel.rodata  ${RELOCATING-0} :
+    {
+      *(.rel.rodata)
+      ${RELOCATING+*(.rel.rodata.*)}
+      ${RELOCATING+*(.rel.gnu.linkonce.r.*)}
+    }
+  .rela.rodata ${RELOCATING-0} :
+    {
+      *(.rela.rodata)
+      ${RELOCATING+*(.rela.rodata.*)}
+      ${RELOCATING+*(.rela.gnu.linkonce.r.*)}
+    }
+  .rel.sdata   ${RELOCATING-0} :
+    {
+      *(.rel.sdata)
+      ${RELOCATING+*(.rel.sdata.*)}
+      ${RELOCATING+*(.rel.gnu.linkonce.s.*)}
+    }
+  .rela.sdata   ${RELOCATING-0} :
+    {
+      *(.rela.sdata)
+      ${RELOCATING+*(.rela.sdata.*)}
+      ${RELOCATING+*(.rela.gnu.linkonce.s.*)}
+    }
+  .rel.sbss    ${RELOCATING-0} :
+    { 
+      *(.rel.sbss)
+      ${RELOCATING+*(.rel.sbss.*)}
+      ${RELOCATING+*(.rel.gnu.linkonce.sb.*)}
+    }
+  .rela.sbss   ${RELOCATING-0} :
+    {
+      *(.rela.sbss)
+      ${RELOCATING+*(.rela.sbss.*)}
+      ${RELOCATING+*(.rel.gnu.linkonce.sb.*)}
+    }
+  .rel.bss     ${RELOCATING-0} : 
+    { 
+      *(.rel.bss)
+      ${RELOCATING+*(.rel.bss.*)}
+      ${RELOCATING+*(.rel.gnu.linkonce.b.*)}
+    }
+  .rela.bss    ${RELOCATING-0} : 
+    { 
+      *(.rela.bss)
+      ${RELOCATING+*(.rela.bss.*)}
+      ${RELOCATING+*(.rela.gnu.linkonce.b.*)}
+    }
+  .rel.stext           ${RELOCATING-0} : { *(.rel.stest) }
+  .rela.stext          ${RELOCATING-0} : { *(.rela.stest) }
+  .rel.etext           ${RELOCATING-0} : { *(.rel.etest) }
+  .rela.etext          ${RELOCATING-0} : { *(.rela.etest) }
+  .rel.sdata           ${RELOCATING-0} : { *(.rel.sdata) }
+  .rela.sdata          ${RELOCATING-0} : { *(.rela.sdata) }
+  .rel.edata           ${RELOCATING-0} : { *(.rel.edata) }
+  .rela.edata          ${RELOCATING-0} : { *(.rela.edata) }
+  .rel.eit_v           ${RELOCATING-0} : { *(.rel.eit_v) }
+  .rela.eit_v          ${RELOCATING-0} : { *(.rela.eit_v) }
+  .rel.ebss            ${RELOCATING-0} : { *(.rel.ebss) }
+  .rela.ebss           ${RELOCATING-0} : { *(.rela.ebss) }
+  .rel.srodata         ${RELOCATING-0} : { *(.rel.srodata) }
+  .rela.srodata                ${RELOCATING-0} : { *(.rela.srodata) }
+  .rel.erodata         ${RELOCATING-0} : { *(.rel.erodata) }
+  .rela.erodata                ${RELOCATING-0} : { *(.rela.erodata) }
+  .rel.got             ${RELOCATING-0} : { *(.rel.got) }
+  .rela.got            ${RELOCATING-0} : { *(.rela.got) }
+  .rel.ctors           ${RELOCATING-0} : { *(.rel.ctors) }
+  .rela.ctors          ${RELOCATING-0} : { *(.rela.ctors) }
+  .rel.dtors           ${RELOCATING-0} : { *(.rel.dtors) }
+  .rela.dtors          ${RELOCATING-0} : { *(.rela.dtors) }
+  .rel.init            ${RELOCATING-0} : { *(.rel.init) }
+  .rela.init           ${RELOCATING-0} : { *(.rela.init) }
+  .rel.fini            ${RELOCATING-0} : { *(.rel.fini) }
+  .rela.fini           ${RELOCATING-0} : { *(.rela.fini) }
+  .rel.plt             ${RELOCATING-0} : { *(.rel.plt) }
+  .rela.plt            ${RELOCATING-0} : { *(.rela.plt) }
+
+  /* Concatenate .page0 sections.  Put them in the page0 memory bank
+     unless we are creating a relocatable file.  */
+  .page0 :
+  {
+    *(.page0)
+  } ${RELOCATING+ > page0}
+
+  /* Start of text section.  */
+  .stext ${RELOCATING-0} : 
+  {
+    *(.stext)
+  } ${RELOCATING+ > ${TEXT_MEMORY}}
+
+  .init        ${RELOCATING-0} :
+  {
+    *(.init) 
+  } ${RELOCATING+=${NOP-0}}
+
+  ${RELOCATING-${INSTALL_RELOC}}
+  ${RELOCATING-${FINISH_RELOC}}
+
+  .text ${RELOCATING-0}:
+  {
+    /* Put startup code at beginning so that _start keeps same address.  */
+    ${RELOCATING+${STARTUP_CODE}}
+
+    ${RELOCATING+*(.init)}
+    *(.text)
+    ${RELOCATING+*(.text.*)}
+    /* .gnu.warning sections are handled specially by elf32.em.  */
+    *(.gnu.warning)
+    ${RELOCATING+*(.gnu.linkonce.t.*)}
+    ${RELOCATING+*(.tramp)}
+    ${RELOCATING+*(.tramp.*)}
+
+    ${RELOCATING+${FINISH_CODE}}
+
+    ${RELOCATING+_etext = .;}
+    ${RELOCATING+PROVIDE (etext = .);}
+    ${RELOCATING+. = ALIGN(2);}
+  } ${RELOCATING+ > ${TEXT_MEMORY} =0xa7a7a7a7}
+
+  .eh_frame ${RELOCATING-0} :
+  {
+    KEEP (*(.eh_frame))
+  } ${RELOCATING+ > ${TEXT_MEMORY}}
+
+  .gcc_except_table ${RELOCATING-0} :
+  {
+    *(.gcc_except_table)
+  } ${RELOCATING+ > ${TEXT_MEMORY}}
+
+  .rodata  ${RELOCATING-0} :
+  {
+    *(.rodata)
+    ${RELOCATING+*(.rodata.*)}
+    ${RELOCATING+*(.gnu.linkonce.r*)}
+    ${RELOCATING+. = ALIGN(2);}
+  } ${RELOCATING+ > ${TEXT_MEMORY} =0xffffffff}
+
+  .rodata1 ${RELOCATING-0} :
+  {
+    *(.rodata1)
+    ${RELOCATING+. = ALIGN(2);}
+  } ${RELOCATING+ > ${TEXT_MEMORY} =0xffffffff}
+
+  /* Constructor and destructor tables are in ROM.  */
+  ${RELOCATING+${CTOR}}
+  ${RELOCATING+${DTOR}}
+
+  .jcr ${RELOCATING-0} :
+  {
+    KEEP (*(.jcr))
+  } ${RELOCATING+ > ${TEXT_MEMORY}}
+
+  /* Start of the data section image in ROM.  */
+  ${RELOCATING+__data_image = .;}
+  ${RELOCATING+PROVIDE (__data_image = .);}
+
+  /* All read-only sections that normally go in PROM must be above.
+     We construct the DATA image section in PROM at end of all these
+     read-only sections.  The data image must be copied at init time.
+     Refer to GNU ld, Section 3.6.8.2 Output Section LMA.  */
+  .data  ${RELOCATING-0} : ${RELOCATING+AT (__data_image)}
+  {
+    ${RELOCATING+__data_section_start = .;}
+    ${RELOCATING+PROVIDE (__data_section_start = .);}
+
+    ${RELOCATING+${DATA_START_SYMBOLS}}
+    ${RELOCATING+*(.sdata)}
+    *(.data)
+    ${RELOCATING+*(.data.*)}
+    ${RELOCATING+*(.data1)}
+    ${RELOCATING+*(.gnu.linkonce.d.*)}
+    ${CONSTRUCTING+CONSTRUCTORS}
+
+    ${RELOCATING+_edata  =  .;}
+    ${RELOCATING+PROVIDE (edata = .);}
+    ${RELOCATING+. = ALIGN(2);}
+  } ${RELOCATING+ > ${DATA_MEMORY} =0xffffffff}
+
+  ${RELOCATING+__data_section_size = SIZEOF(.data);}
+  ${RELOCATING+PROVIDE (__data_section_size = SIZEOF(.data));}
+  ${RELOCATING+__data_image_end = __data_image + __data_section_size;}
+
+  ${RELOCATING+${PRE_COMPUTE_DATA_SIZE}}
+
+  /* .install ${RELOCATING-0}:
+  {
+    . = _data_image_end;
+  } ${RELOCATING+ > ${TEXT_MEMORY}} */
+
+  /* Relocation for some bss and data sections.  */
+  ${RELOCATING-${BSS_DATA_RELOC}}
+  ${RELOCATING-${SOFT_REGS_RELOC}}
+
+  .bss ${RELOCATING-0} :
+  {
+    ${RELOCATING+__bss_start = .;}
+    ${RELOCATING+*(.softregs)}
+    ${RELOCATING+*(.sbss)}
+    ${RELOCATING+*(.scommon)}
+
+    *(.dynbss)
+    *(.bss)
+    ${RELOCATING+*(.bss.*)}
+    ${RELOCATING+*(.gnu.linkonce.b.*)}
+    *(COMMON)
+    ${RELOCATING+PROVIDE (_end = .);}
+  } ${RELOCATING+ > ${DATA_MEMORY}}
+  ${RELOCATING+__bss_size = SIZEOF(.bss);}
+  ${RELOCATING+PROVIDE (__bss_size = SIZEOF(.bss));}
+
+  .eeprom ${RELOCATING-0} :
+  {
+    *(.eeprom)
+    *(.eeprom.*)
+  } ${RELOCATING+ > ${EEPROM_MEMORY}}
+
+  ${RELOCATING+${VECTORS}}
+
+  /* Stabs debugging sections.  */
+  .stab                 0 : { *(.stab) }
+  .stabstr      0 : { *(.stabstr) }
+  .stab.excl    0 : { *(.stab.excl) }
+  .stab.exclstr         0 : { *(.stab.exclstr) }
+  .stab.index   0 : { *(.stab.index) }
+  .stab.indexstr 0 : { *(.stab.indexstr) }
+
+  .comment      0 : { *(.comment) }
+
+  /* DWARF debug sections.
+     Symbols in the DWARF debugging sections are relative to the beginning
+     of the section so we begin them at 0.
+     Treatment of DWARF debug section must be at end of the linker
+     script to avoid problems when there are undefined symbols. It's necessary
+     to avoid that the DWARF section is relocated before such undefined
+     symbols are found.  */
+
+  /* DWARF 1 */
+  .debug        0 : { *(.debug) }
+  .line                 0 : { *(.line) }
+
+  /* GNU DWARF 1 extensions */
+  .debug_srcinfo 0 : { *(.debug_srcinfo) }
+  .debug_sfnames 0 : { *(.debug_sfnames) }
+
+  /* DWARF 1.1 and DWARF 2 */
+  .debug_aranges  0 : { *(.debug_aranges) }
+  .debug_pubnames 0 : { *(.debug_pubnames) }
+
+  /* DWARF 2 */
+  .debug_info     0 : { *(.debug_info) *(.gnu.linkonce.wi.*) }
+  .debug_abbrev   0 : { *(.debug_abbrev) }
+  .debug_line     0 : { *(.debug_line) }
+  .debug_frame    0 : { *(.debug_frame) }
+  .debug_str      0 : { *(.debug_str) }
+  .debug_loc      0 : { *(.debug_loc) }
+  .debug_macinfo  0 : { *(.debug_macinfo) }
+}
+EOF
index 371d8f6..a43dd3d 100644 (file)
@@ -1,3 +1,14 @@
+2012-05-03  Sean Keys  <skeys@ipdatasys.com>
+
+       * Makefile.in, configure: regenerate
+       * disassemble.c (disassembler): Recognize ARCH_XGATE.
+       * xgate-dis.c (read_memory, print_insn, print_insn_xgate):
+       New functions.
+       * configure.in: Recognize xgate.
+       * xgate-dis.c, xgate-opc.c: New files for support of xgate
+       * Makefile.am (CFILES, ALL_MACHINES): New files for disassembly
+       and opcode generation for xgate.
+
 2012-04-30  DJ Delorie  <dj@redhat.com>
 
        * rx-decode.opc (MOV): Do not sign-extend immediates which are
index b377c4d..a43aa0d 100644 (file)
@@ -234,6 +234,8 @@ TARGET_LIBOPCODES_CFILES = \
        xstormy16-ibld.c \
        xstormy16-opc.c \
        xtensa-dis.c \
+       xgate-dis.c \
+       xgate-opc.c \
        z80-dis.c \
        z8k-dis.c
 
index 8ae4b84..f5035ea 100644 (file)
@@ -504,6 +504,8 @@ TARGET_LIBOPCODES_CFILES = \
        xstormy16-ibld.c \
        xstormy16-opc.c \
        xtensa-dis.c \
+       xgate-dis.c \
+       xgate-opc.c \
        z80-dis.c \
        z8k-dis.c
 
@@ -884,6 +886,8 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xc16x-dis.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xc16x-ibld.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xc16x-opc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xgate-dis.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xgate-opc.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xstormy16-asm.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xstormy16-desc.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xstormy16-dis.Plo@am__quote@
index cc69060..ec74346 100755 (executable)
@@ -12492,7 +12492,8 @@ if test x${all_targets} = xfalse ; then
        bfd_vax_arch)           ta="$ta vax-dis.lo" ;;
        bfd_w65_arch)           ta="$ta w65-dis.lo" ;;
        bfd_we32k_arch)         ;;
-       bfd_xc16x_arch)         ta="$ta xc16x-asm.lo xc16x-desc.lo xc16x-dis.lo xc16x-ibld.lo xc16x-opc.lo" using_cgen=yes ;;
+       bfd_xc16x_arch)         ta="$ta xc16x-asm.lo xc16x-desc.lo xc16x-dis.lo xc16x-ibld.lo xc16x-opc.lo" using_cgen=yes ;;
+       bfd_xgate_arch)         ta="$ta xgate-dis.lo xgate-opc.lo" ;;
        bfd_xstormy16_arch)     ta="$ta xstormy16-asm.lo xstormy16-desc.lo xstormy16-dis.lo xstormy16-ibld.lo xstormy16-opc.lo" using_cgen=yes ;;
        bfd_xtensa_arch)        ta="$ta xtensa-dis.lo" ;;
        bfd_z80_arch)           ta="$ta z80-dis.lo" ;;
index 6da3ef1..999379a 100644 (file)
@@ -306,7 +306,8 @@ if test x${all_targets} = xfalse ; then
        bfd_vax_arch)           ta="$ta vax-dis.lo" ;;
        bfd_w65_arch)           ta="$ta w65-dis.lo" ;;
        bfd_we32k_arch)         ;;
-       bfd_xc16x_arch)         ta="$ta xc16x-asm.lo xc16x-desc.lo xc16x-dis.lo xc16x-ibld.lo xc16x-opc.lo" using_cgen=yes ;;
+       bfd_xc16x_arch)         ta="$ta xc16x-asm.lo xc16x-desc.lo xc16x-dis.lo xc16x-ibld.lo xc16x-opc.lo" using_cgen=yes ;;
+       bfd_xgate_arch)         ta="$ta xgate-dis.lo xgate-opc.lo" ;;
        bfd_xstormy16_arch)     ta="$ta xstormy16-asm.lo xstormy16-desc.lo xstormy16-dis.lo xstormy16-ibld.lo xstormy16-opc.lo" using_cgen=yes ;;
        bfd_xtensa_arch)        ta="$ta xtensa-dis.lo" ;;
        bfd_z80_arch)           ta="$ta z80-dis.lo" ;;
index 43e1d53..7ff5f22 100644 (file)
@@ -91,6 +91,7 @@
 #define ARCH_w65
 #define ARCH_xstormy16
 #define ARCH_xc16x
+#define ARCH_xgate
 #define ARCH_xtensa
 #define ARCH_z80
 #define ARCH_z8k
@@ -430,6 +431,11 @@ disassembler (abfd)
       disassemble = print_insn_w65;
       break;
 #endif
+#ifdef ARCH_xgate
+    case bfd_arch_xgate:
+      disassemble = print_insn_xgate;
+      break;
+#endif
 #ifdef ARCH_xstormy16
     case bfd_arch_xstormy16:
       disassemble = print_insn_xstormy16;
diff --git a/opcodes/xgate-dis.c b/opcodes/xgate-dis.c
new file mode 100644 (file)
index 0000000..f703055
--- /dev/null
@@ -0,0 +1,403 @@
+/* xgate-dis.c -- Freescale XGATE disassembly
+   Copyright 2009, 2010, 2011
+   Free Software Foundation, Inc.
+   Written by Sean Keys (skeys@ipdatasys.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 <assert.h>
+#include "sysdep.h"
+#include "dis-asm.h"
+#include "opintl.h"
+#include "libiberty.h"
+#include "ansidecl.h"
+#include "opcode/xgate.h"
+
+#define XGATE_TWO_BYTES      0x02
+#define XGATE_NINE_BITS      0x1FF
+#define XGATE_TEN_BITS       0x3FF
+#define XGATE_NINE_SIGNBIT   0x100
+#define XGATE_TEN_SIGNBIT    0x200
+
+/* Structures */
+struct decodeInfo {
+  unsigned int operMask;
+  unsigned int operMasksRegisterBits;
+  struct xgate_opcode *opcodePTR;
+};
+
+/* Prototypes for local functions.  */
+static int
+print_insn( bfd_vma, struct disassemble_info *);
+static int
+read_memory( bfd_vma, bfd_byte*, int, struct disassemble_info *);
+static int
+ripBits(unsigned int *, int,
+    struct xgate_opcode *, unsigned int);
+int
+macro_search(char *, char *);
+struct decodeInfo *
+find_match(unsigned int raw_code);
+
+/* statics */
+static struct decodeInfo *decodeTable;
+static int initialized;
+static char previousOpName[10];
+static unsigned int perviousBin;
+
+/* Disassemble one instruction at address 'memaddr'.  Returns the number
+ of bytes used by that instruction.  */
+static int
+print_insn (bfd_vma memaddr, struct disassemble_info* info)
+{
+  int status;
+  unsigned int raw_code;
+  char *s = 0;
+  long bytesRead = 0;
+  int i = 0;
+  struct xgate_opcode *opcodePTR = (struct xgate_opcode*) xgate_opcodes;
+  struct decodeInfo *decodeTablePTR = 0;
+  struct decodeInfo *decodePTR = 0;
+  unsigned int operandRegisterBits = 0;
+  signed int relAddr = 0;
+  signed int operandOne = 0;
+  signed int operandTwo = 0;
+  bfd_byte buffer[4];
+  bfd_vma absAddress;
+
+  unsigned int operMaskReg = 0;
+  /* initialize our array of opcode masks and check them against our constant
+     table */
+  if (!initialized)
+    {
+      decodeTable = xmalloc(sizeof(struct decodeInfo) * xgate_num_opcodes);
+      for (i = 0, decodeTablePTR = decodeTable; i < xgate_num_opcodes;
+          i++, decodeTablePTR++, opcodePTR++)
+        {
+          unsigned int bin = 0;
+          unsigned int mask = 0;
+          for (s = opcodePTR->format; *s; s++)
+            {
+              bin <<= 1;
+              mask <<= 1;
+              operandRegisterBits <<= 1;
+              bin |= (*s == '1');
+              mask |= (*s == '0' || *s == '1');
+              operandRegisterBits |= (*s == 'r');
+            }
+          /* asserting will uncover inconsistencies in our table */
+          assert(
+              (s - opcodePTR->format) == 16 || (s - opcodePTR->format) == 32);
+          assert(opcodePTR->bin_opcode == bin);
+          decodeTablePTR->operMask = mask;
+          decodeTablePTR->operMasksRegisterBits = operandRegisterBits;
+          decodeTablePTR->opcodePTR = opcodePTR;
+        }
+      initialized = 1;
+    }
+  /* read 16 bits */
+  bytesRead += XGATE_TWO_BYTES;
+  status = read_memory(memaddr, buffer, XGATE_TWO_BYTES, info);
+  if (status == 0)
+    {
+      raw_code = buffer[0];
+      raw_code <<= 8;
+      raw_code += buffer[1];
+
+      decodePTR = find_match(raw_code);
+      if (decodePTR)
+        {
+          operMaskReg = decodePTR->operMasksRegisterBits;
+          (*info->fprintf_func)(info->stream, "%s", decodePTR->opcodePTR->name);
+          /* First we compare the shorthand format of the constraints. If we
+           still are unable to pinpoint the operands
+           we analyze the opcodes constraint string. */
+          switch (decodePTR->opcodePTR->sh_format)
+          {
+          case XG_R_C:
+            (*info->fprintf_func)(info->stream, " R%x, CCR",
+                (raw_code >> 8) & 0x7);
+            break;
+          case XG_C_R:
+            (*info->fprintf_func)(info->stream, " CCR, R%x",
+                (raw_code >> 8) & 0x7);
+            break;
+          case XG_R_P:
+            (*info->fprintf_func)(info->stream, " R%x, PC",
+                (raw_code >> 8) & 0x7);
+            break;
+          case XG_INH:
+            break;
+          case XG_R_R_R:
+            if (!strcmp(decodePTR->opcodePTR->constraints, XGATE_OP_TRI))
+              {
+                (*info->fprintf_func)(info->stream, " R%x, R%x, R%x",
+                    (raw_code >> 8) & 0x7, (raw_code >> 5) & 0x7,
+                    (raw_code >> 2) & 0x7);
+              }
+            else if (!strcmp(decodePTR->opcodePTR->constraints, XGATE_OP_IDR))
+              {
+                if (raw_code & 0x01)
+                  {
+                    (*info->fprintf_func)(info->stream, " R%x, (R%x, R%x+)",
+                        (raw_code >> 8) & 0x7, (raw_code >> 5) & 0x7,
+                        (raw_code >> 2) & 0x7);
+                  }
+                else if (raw_code & 0x02)
+                  {
+                    (*info->fprintf_func)(info->stream, " R%x, (R%x, -R%x)",
+                        (raw_code >> 8) & 0x7, (raw_code >> 5) & 0x7,
+                        (raw_code >> 2) & 0x7);
+                  }
+                else
+                  {
+                    (*info->fprintf_func)(info->stream, " R%x, (R%x, R%x)",
+                        (raw_code >> 8) & 0x7, (raw_code >> 5) & 0x7,
+                        (raw_code >> 2) & 0x7);
+                  }
+              }
+            else
+              {
+                (*info->fprintf_func)(info->stream, " unhandled mode %s",
+                    decodePTR->opcodePTR->constraints);
+              }
+            break;
+          case XG_R_R:
+            if (!strcmp(decodePTR->opcodePTR->constraints, XGATE_OP_DYA_MON))
+              {
+                operandOne = ripBits(&operMaskReg, 3, decodePTR->opcodePTR,
+                    raw_code);
+                operandTwo = ripBits(&operMaskReg, 3, decodePTR->opcodePTR,
+                    raw_code);
+                (*info->fprintf_func)(info->stream, " R%x, R%x", operandOne,
+                    operandTwo);
+              }
+            else if (!strcmp(decodePTR->opcodePTR->constraints, XGATE_OP_DYA))
+              {
+                operandOne = ripBits(&operMaskReg, 3, opcodePTR, raw_code);
+                operandTwo = ripBits(&operMaskReg, 3, opcodePTR, raw_code);
+                (*info->fprintf_func)(info->stream, " R%x, R%x", operandOne,
+                    operandTwo);
+              }
+            else
+              {
+                (*info->fprintf_func)(info->stream, " unhandled mode %s",
+                    opcodePTR->constraints);
+              }
+            break;
+          case XG_R_R_I:
+            (*info->fprintf_func)(info->stream, " R%x, (R%x, #0x%x)",
+                (raw_code >> 8) & 0x7, (raw_code >> 5) & 0x7, raw_code & 0x1f);
+            break;
+          case XG_R:
+            operandOne = ripBits(&operMaskReg, 3, decodePTR->opcodePTR,
+                raw_code);
+            (*info->fprintf_func)(info->stream, " R%x", operandOne);
+            break;
+          case XG_I | XG_PCREL:
+          if (!strcmp(decodePTR->opcodePTR->constraints, XGATE_OP_REL9))
+            {
+              /* if address is negative handle it accordingly */
+              if (raw_code & XGATE_NINE_SIGNBIT)
+                {
+                  relAddr = XGATE_NINE_BITS >> 1; /* clip sign bit */
+                  relAddr = ~relAddr; /* make signed */
+                  relAddr |= (raw_code & 0xFF) + 1; /* apply our value */
+                  relAddr <<= 1; /* multiply by two as per processor docs */
+                }
+              else
+                {
+                  relAddr = raw_code & 0xff;
+                  relAddr = (relAddr << 1) + 2;
+                }
+              (*info->fprintf_func)(info->stream, " *%d", relAddr);
+              (*info->fprintf_func)(info->stream, "  Abs* 0x");
+              (*info->print_address_func)(memaddr + relAddr, info);
+            }
+          else if (!strcmp(decodePTR->opcodePTR->constraints, XGATE_OP_REL10))
+            {
+              /* if address is negative handle it accordingly */
+              if (raw_code & XGATE_TEN_SIGNBIT)
+                {
+                  relAddr = XGATE_TEN_BITS >> 1; /* clip sign bit */
+                  relAddr = ~relAddr; /* make signed */
+                  relAddr |= (raw_code & 0x1FF) + 1; /* apply our value */
+                  relAddr <<= 1; /* multiply by two as per processor docs */
+                }
+              else
+                {
+                  relAddr = raw_code & 0x1FF;
+                  relAddr = (relAddr << 1) + 2;
+                }
+              (*info->fprintf_func)(info->stream, " *%d", relAddr);
+              (*info->fprintf_func)(info->stream, "  Abs* 0x");
+              (*info->print_address_func)(memaddr + relAddr, info);
+            }
+          else
+            {
+              (*info->fprintf_func)(info->stream,
+                  " Can't disassemble for mode) %s",
+                  decodePTR->opcodePTR->constraints);
+            }
+          break;
+          case XG_R_I:
+            if (!strcmp(decodePTR->opcodePTR->constraints, XGATE_OP_IMM4))
+              {
+                (*info->fprintf_func)(info->stream, " R%x, #0x%02x",
+                    (raw_code >> 8) & 0x7, (raw_code >> 4) & 0xF);
+              }
+            else if (!strcmp(decodePTR->opcodePTR->constraints, XGATE_OP_IMM8))
+              {
+                if (macro_search(decodePTR->opcodePTR->name, previousOpName) &&
+                    previousOpName[0])
+                  {
+                    absAddress = (0xFF & raw_code) << 8;
+                    absAddress |= perviousBin & 0xFF;
+                    (*info->fprintf_func)(info->stream, " R%x, #0x%02x Abs* 0x",
+                        (raw_code >> 8) & 0x7, raw_code & 0xff);
+                    (*info->print_address_func)(absAddress, info);
+                    previousOpName[0] = 0;
+                  }
+                else
+                  {
+                    strcpy(previousOpName, decodePTR->opcodePTR->name);
+                    (*info->fprintf_func)(info->stream, " R%x, #0x%02x",
+                        (raw_code >> 8) & 0x7, raw_code & 0xff);
+                  }
+              }
+            else
+              {
+                (*info->fprintf_func)(info->stream,
+                    " Can't disassemble for mode %s",
+                    decodePTR->opcodePTR->constraints);
+              }
+            break;
+          case XG_I:
+            (*info->fprintf_func)(info->stream, " #0x%x",
+                (raw_code >> 8) & 0x7);
+            break;
+          default:
+            (*info->fprintf_func)(info->stream, "address mode not found\t %x",
+                opcodePTR->bin_opcode);
+            break;
+          }
+          perviousBin = raw_code;
+        }
+      else
+        {
+          (*info->fprintf_func)(info->stream,
+              " unable to find opcode match #0%x", raw_code);
+        }
+    }
+  return bytesRead;
+}
+
+int
+print_insn_xgate (bfd_vma memaddr, struct disassemble_info* info)
+{
+  return print_insn (memaddr, info);
+}
+
+static int
+read_memory (bfd_vma memaddr, bfd_byte* buffer, int size,
+    struct disassemble_info* info)
+{
+  int status;
+  status = (*info->read_memory_func) (memaddr, buffer, size, info);
+  if (status != 0)
+    {
+      (*info->memory_error_func) (status, memaddr, info);
+      return -1;
+    }
+  return 0;
+}
+
+static int
+ripBits(unsigned int *operandBitsRemaining, int numBitsRequested,
+    struct xgate_opcode *opcodePTR, unsigned int memory)
+{
+  unsigned int currentBit;
+  int operand;
+  int numBitsFound;
+  for (operand = 0, numBitsFound = 0, currentBit = 1
+      << ((opcodePTR->size * 8) - 1);
+      (numBitsFound < numBitsRequested) && currentBit; currentBit >>= 1)
+    {
+      if(currentBit & *operandBitsRemaining) {
+         *operandBitsRemaining &= ~(currentBit); /* consume the current bit */
+         operand <<= 1; /* make room for our next bit */
+         numBitsFound++;
+         operand |= (currentBit & memory) > 0;
+     }
+  }
+  return operand;
+}
+
+int
+macro_search(char *currentName, char *lastName)
+{
+  int i;
+  int length = 0;
+  char *where;
+  for (i = 0; i < xgate_num_opcodes; i++)
+    {
+      where = strstr(xgate_opcodes[i].constraints, lastName);
+      if (where)
+        {
+          length = strlen(where);
+        }
+      if (length)
+        {
+          where = strstr(xgate_opcodes[i].constraints, currentName);
+          if (where)
+            {
+              length = strlen(where);
+              return 1;
+            }
+        }
+    }
+  return 0;
+}
+
+struct decodeInfo*
+find_match(unsigned int raw_code)
+{
+  struct decodeInfo *decodeTablePTR = 0;
+  int i;
+
+  for (i = 0, decodeTablePTR = decodeTable; i < xgate_num_opcodes;
+      i++, decodeTablePTR++)
+    {
+      if ((raw_code & decodeTablePTR->operMask)
+          == decodeTablePTR->opcodePTR->bin_opcode)
+        {
+          /* make sure we didn't run into a macro or alias */
+          if (decodeTablePTR->opcodePTR->cycles_min != 0)
+            {
+              return decodeTablePTR;
+              break;
+            }
+          else
+            {
+              continue;
+            }
+        }
+    }
+  return 0;
+}
diff --git a/opcodes/xgate-opc.c b/opcodes/xgate-opc.c
new file mode 100644 (file)
index 0000000..9b5fe07
--- /dev/null
@@ -0,0 +1,203 @@
+/* mc9xgate-opc.c -- Freescale XGATE opcode list
+   Copyright 1999, 2000, 2002, 2005, 2007 Free Software Foundation, Inc.
+   Written by Sean Keys (skeys@ipdatasys.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 <stdio.h>
+#include "ansidecl.h"
+#include "opcode/xgate.h"
+
+#define TABLE_SIZE(X)       (sizeof(X) / sizeof(X[0]))
+
+/* Combination of CCR flags.  */
+/* ORDER HI TO LOW NZVC */
+#define XGATE_NZ_BIT   XGATE_N_BIT|XGATE_Z_BIT
+#define XGATE_NV_BIT   XGATE_N_BIT|XGATE_V_BIT
+#define XGATE_NC_BIT   XGATE_N_BIT|XGATE_C_BIT
+#define XGATE_ZV_BIT   XGATE_Z_BIT|XGATE_V_BIT
+#define XGATE_ZC_BIT   XGATE_Z_BIT|XGATE_C_BIT
+#define XGATE_VC_BIT   XGATE_V_BIT|XGATE_C_BIT
+#define XGATE_NVC_BIT  XGATE_NV_BIT|XGATE_C_BIT
+#define XGATE_NZC_BIT  XGATE_NZ_BIT|XGATE_C_BIT
+#define XGATE_NZV_BIT  XGATE_N_BIT|XGATE_Z_BIT|XGATE_V_BIT
+#define XGATE_ZVC_BIT  XGATE_VC_BIT|XGATE_Z_BIT
+#define XGATE_NZVC_BIT XGATE_NZV_BIT|XGATE_C_BIT
+
+/* Flags when the insn only changes some CCR flags.  */
+#define CHG_NONE        0,0,0
+#define CHG_Z           0,0,XGATE_Z_BIT
+#define CHG_C           0,0,XGATE_C_BIT
+#define CHG_ZVC         0,0,XGATE_ZVC_BIT
+#define CHG_NZC         0,0,XGATE_NZC_BIT
+#define CHG_NZV         0,0,XGATE_NZV_BIT
+#define CHG_NZVC        0,0,(XGATE_NZVC_BIT)
+#define CHG_HNZVC       0,0,XGATE_HNZVC_BIT  // TODO DELETE
+#define CHG_ALL         0,0,0xff
+
+/* The insn clears and changes some flags.  */
+#define CLR_I           0,XG_I_BIT,0
+#define CLR_C           0,XGATE_C_BIT,0
+#define CLR_V           0,XGATE_V_BIT,0
+#define CLR_V_CHG_ZC    0,XGATE_V_BIT,XGATE_ZC_BIT
+#define CLR_V_CHG_NZ    0,XGATE_V_BIT,XGATE_NZ_BIT
+#define CLR_V_CHG_ZVC   0,XGATE_V_BIT,XGATE_ZVC_BIT
+#define CLR_N_CHG_ZVC   0,XGATE_N_BIT,XGATE_ZVC_BIT /* Used by lsr */
+#define CLR_VC_CHG_NZ   0,XGATE_VC_BIT,XGATE_NZ_BIT
+
+/* The insn sets some flags.  */
+#define SET_I                   XGATE_I_BIT,0,0
+#define SET_C                   XGATE_C_BIT,0,0
+#define SET_V                   XGATE_V_BIT,0,0
+#define SET_Z_CLR_NVC           XGATE_Z_BIT,XGATE_NVC_BIT,0
+#define SET_C_CLR_V_CHG_NZ      XGATE_C_BIT,XGATE_V_BIT,XGATE_NZ_BIT
+#define SET_Z_CHG_HNVC          XGATE_Z_BIT,0,XGATE_HNVC_BIT
+
+/* operand modes */
+#define OP_NONE         XGATE_OP_NONE
+#define OP_INH         XGATE_OP_INH
+#define OP_TRI         XGATE_OP_TRI
+#define OP_DYA         XGATE_OP_DYA
+#define OP_DM          XGATE_OP_DYA_MON
+#define OP_IMM3                XGATE_OP_IMM3
+#define OP_IMM4                XGATE_OP_IMM4
+#define OP_IMM8                XGATE_OP_IMM8
+#define OP_IMM16       XGATE_OP_IMM16
+#define OP_MON         XGATE_OP_MON
+#define OP_MON_R_C     XGATE_OP_MON_R_C
+#define OP_MON_C_R     XGATE_OP_MON_C_R
+#define OP_MON_R_P     XGATE_OP_MON_R_P
+#define OP_IDR         XGATE_OP_IDR
+#define OP_IDO5                XGATE_OP_IDO5
+#define OP_REL9                XGATE_OP_REL9
+#define OP_REL10       XGATE_OP_REL10
+/* macro operand modes */
+#define OP_mADD         XGATE_OP_IMM16mADD
+#define OP_mAND         XGATE_OP_IMM16mAND
+#define OP_mCPC         XGATE_OP_IMM16mCPC
+#define OP_mLDW         XGATE_OP_IMM16mLDW
+#define OP_mSUB         XGATE_OP_IMM16mSUB
+
+#define ALL       XGATE_V1|XGATE_V2|XGATE_V3
+#define XG_IP        XG_I|XG_PCREL
+
+const struct xgate_opcode xgate_opcodes[] = {
+/* Name -+                                                                         +-- CPU
+   Constraints --+                                                       +------------ CCR changes
+   Format ----------------+                                          +---------------- Max # cycles
+   Short Hand Format-------------------------+                    +------------------- Min # cycles
+   Size -----------------------------------------------+   +-------------------------- Opcode */
+    {   "adc",   OP_TRI, "00011rrrrrrrrr11", XG_R_R_R, 2, 0x1803, 1, 1, CHG_NZVC, ALL},
+    {   "add",   OP_TRI, "00011rrrrrrrrr10", XG_R_R_R, 2, 0x1802, 1, 1, CHG_NZVC, ALL},
+    {  "addh",  OP_IMM8, "11101rrriiiiiiii",   XG_R_I, 2, 0xE800, 1, 1, CHG_NZVC, ALL},
+    {  "addl",  OP_IMM8, "11100rrriiiiiiii",   XG_R_I, 2, 0xE000, 1, 1, CHG_NZVC, ALL},
+    {   "and",   OP_TRI, "00010rrrrrrrrr00", XG_R_R_R, 2, 0x1000, 1, 1,  CHG_NZV, ALL},
+    {  "andh",  OP_IMM8, "10001rrriiiiiiii",   XG_R_I, 2, 0x8800, 1, 1,  CHG_NZV, ALL},
+    {  "andl",  OP_IMM8, "10000rrriiiiiiii",   XG_R_I, 2, 0x8000, 1, 1,  CHG_NZV, ALL},
+    {   "asr",  OP_IMM4, "00001rrriiii1001",   XG_R_I, 2, 0x0809, 1, 1, CHG_NZVC, ALL},
+    {   "asr",   OP_DYA, "00001rrrrrr10001",   XG_R_R, 2, 0x0811, 1, 1, CHG_NZVC, ALL},
+    {   "bcc",  OP_REL9, "0010000iiiiiiiii",   XG_IP,  2, 0x2000, 1, 2, CHG_NONE, ALL},
+    {   "bcs",  OP_REL9, "0010001iiiiiiiii",   XG_IP,  2, 0x2200, 1, 2, CHG_NONE, ALL},
+    {   "beq",  OP_REL9, "0010011iiiiiiiii",   XG_IP,  2, 0x2600, 1, 2, CHG_NONE, ALL},
+    { "bfext",   OP_TRI, "01100rrrrrrrrr11", XG_R_R_R, 2, 0x6003, 1, 1,  CHG_NZV, ALL},
+    {  "bffo",   OP_DYA, "00001rrrrrr10000",   XG_R_R, 2, 0x0810, 1, 1, CHG_NZVC, ALL},
+    { "bfins",   OP_TRI, "01101rrrrrrrrr11", XG_R_R_R, 2, 0x6803, 1, 1,  CHG_NZV, ALL},
+    {"bfinsi",   OP_TRI, "01110rrrrrrrrr11", XG_R_R_R, 2, 0x7003, 1, 1,  CHG_NZV, ALL},
+    {"bfinsx",   OP_TRI, "01111rrrrrrrrr11", XG_R_R_R, 2, 0x7803, 1, 1,  CHG_NZV, ALL},
+    {   "bge",  OP_REL9, "0011010iiiiiiiii",   XG_IP,  2, 0x3400, 1, 2, CHG_NONE, ALL},
+    {   "bgt",  OP_REL9, "0011100iiiiiiiii",   XG_IP,  2, 0x3800, 1, 2, CHG_NONE, ALL},
+    {   "bhi",  OP_REL9, "0011000iiiiiiiii",   XG_IP,  2, 0x3000, 1, 2, CHG_NONE, ALL},
+    {  "bith",  OP_IMM8, "10011rrriiiiiiii",   XG_R_I, 2, 0x9800, 1, 1,  CHG_NZV, ALL},
+    {  "bitl",  OP_IMM8, "10010rrriiiiiiii",   XG_R_I, 2, 0x9000, 1, 1,  CHG_NZV, ALL},
+    {   "ble",  OP_REL9, "0011101iiiiiiiii",   XG_IP,  2, 0x3A00, 1, 2, CHG_NONE, ALL},
+    {   "bls",  OP_REL9, "0011001iiiiiiiii",   XG_IP,  2, 0x3200, 1, 2, CHG_NONE, ALL},
+    {   "blt",  OP_REL9, "0011011iiiiiiiii",   XG_IP,  2, 0x3600, 1, 2, CHG_NONE, ALL},
+    {   "bmi",  OP_REL9, "0010101iiiiiiiii",   XG_IP,  2, 0x2A00, 1, 2, CHG_NONE, ALL},
+    {   "bne",  OP_REL9, "0010010iiiiiiiii",   XG_IP,  2, 0x2400, 1, 2, CHG_NONE, ALL},
+    {   "bpl",  OP_REL9, "0010100iiiiiiiii",   XG_IP,  2, 0x2800, 1, 2, CHG_NONE, ALL},
+    {   "bra", OP_REL10, "001111iiiiiiiiii",   XG_IP,  2, 0x3C00, 2, 2, CHG_NONE, ALL},
+    {   "brk",   OP_INH, "0000000000000000",   XG_INH, 2, 0x0000, 1, 1, CHG_NONE, ALL},
+    {   "bvc",  OP_REL9, "0010110iiiiiiiii",   XG_IP,  2, 0x2C00, 1, 2, CHG_NONE, ALL},
+    {   "bvs",  OP_REL9, "0010111iiiiiiiii",   XG_IP,  2, 0x2E00, 1, 2, CHG_NONE, ALL},
+    {  "cmpl",  OP_IMM8, "11010rrriiiiiiii",   XG_R_I, 2, 0xD000, 1, 1, CHG_NZVC, ALL},
+    {  "cpch",  OP_IMM8, "11011rrriiiiiiii",   XG_R_I, 2, 0xD800, 1, 1, CHG_NZVC, ALL},
+    {  "csem",  OP_IMM3, "00000iii11110000",    XG_I , 2, 0x00F0, 1, 1, CHG_NONE, ALL},
+    {  "csem",   OP_MON, "00000rrr11110001",     XG_R, 2, 0x00F1, 1, 1, CHG_NONE, ALL},
+    {   "csl",  OP_IMM4, "00001rrriiii1010",   XG_R_I, 2, 0x080A, 1, 1, CHG_NZVC, ALL},
+    {   "csl",   OP_DYA, "00001rrrrrr10010",   XG_R_R, 2, 0x0812, 1, 1, CHG_NZVC, ALL},
+    {   "csr",  OP_IMM4, "00001rrriiii1011",   XG_R_I, 2, 0x080B, 1, 1, CHG_NZVC, ALL},
+    {   "csr",   OP_DYA, "00001rrrrrr10011",   XG_R_R, 2, 0x0813, 1, 1, CHG_NZVC, ALL},
+    {   "jal",   OP_MON, "00000rrr11110110",     XG_R, 2, 0x00F6, 2, 2, CHG_NONE, ALL},
+    {   "ldb",  OP_IDO5, "01000rrrrrriiiii", XG_R_R_I, 2, 0x4000, 2, 2, CHG_NONE, ALL},
+    {   "ldb",   OP_IDR, "01100rrrrrrrrrrr", XG_R_R_R, 2, 0x6000, 2, 2, CHG_NONE, ALL},
+    {   "ldh",  OP_IMM8, "11111rrriiiiiiii",   XG_R_I, 2, 0xF800, 1, 1, CHG_NONE, ALL},
+    {   "ldl",  OP_IMM8, "11110rrriiiiiiii",   XG_R_I, 2, 0xF000, 1, 1, CHG_NONE, ALL},
+    {   "ldw",  OP_IDO5, "01001rrrrrriiiii", XG_R_R_I, 2, 0x4800, 2, 2, CHG_NONE, ALL},
+    {   "ldw",   OP_IDR, "01101rrrrrrrrrrr", XG_R_R_R, 2, 0x6800, 2, 2, CHG_NONE, ALL},
+    {   "lsl",  OP_IMM4, "00001rrriiii1100",   XG_R_I, 2, 0x080C, 1, 1, CHG_NZVC, ALL},
+    {   "lsl",   OP_DYA, "00001rrrrrr10100",   XG_R_R, 2, 0x0814, 1, 1, CHG_NZVC, ALL},
+    {   "lsr",  OP_IMM4, "00001rrriiii1101",   XG_R_I, 2, 0x080D, 1, 1, CHG_NZVC, ALL},
+    {   "lsr",   OP_DYA, "00001rrrrrr10101",   XG_R_R, 2, 0x0815, 1, 1, CHG_NZVC, ALL},
+    {   "nop",   OP_INH, "0000000100000000",   XG_INH, 2, 0x0100, 1, 1, CHG_NONE, ALL},
+    {    "or",   OP_TRI, "00010rrrrrrrrr10", XG_R_R_R, 2, 0x1002, 1, 1,  CHG_NZV, ALL},
+    {   "orh",  OP_IMM8, "10101rrriiiiiiii",   XG_R_I, 2, 0xA800, 1, 1,  CHG_NZV, ALL},
+    {   "orl",  OP_IMM8, "10100rrriiiiiiii",   XG_R_I, 2, 0xA000, 1, 1,  CHG_NZV, ALL},
+    {   "par",   OP_MON, "00000rrr11110101",     XG_R, 2, 0x00F5, 1, 1,  CHG_NZV, ALL},
+    {   "rol",  OP_IMM4, "00001rrriiii1110",   XG_R_I, 2, 0x080E, 1, 1,  CHG_NZV, ALL},
+    {   "rol",   OP_DYA, "00001rrrrrr10110",   XG_R_R, 2, 0x0816, 1, 1,  CHG_NZV, ALL},
+    {   "ror",  OP_IMM4, "00001rrriiii1111",   XG_R_I, 2, 0x080F, 1, 1,  CHG_NZV, ALL},
+    {   "ror",   OP_DYA, "00001rrrrrr10111",   XG_R_R, 2, 0x0817, 1, 1,  CHG_NZV, ALL},
+    {   "rts",   OP_INH, "0000001000000000",   XG_INH, 2, 0x0200, 2, 2, CHG_NONE, ALL},
+    {   "sbc",   OP_TRI, "00011rrrrrrrrr01", XG_R_R_R, 2, 0x1801, 1, 1,  CHG_NZV, ALL},
+    {  "ssem",  OP_IMM3, "00000iii11110010",    XG_I , 2, 0x00F2, 2, 2,    CHG_C, ALL},
+    {  "ssem",   OP_MON, "00000rrr11110011",     XG_R, 2, 0x00F3, 2, 2,    CHG_C, ALL},
+    {   "sex",   OP_MON, "00000rrr11110100",     XG_R, 2, 0x00F4, 1, 1,  CHG_NZV, ALL},
+    {   "sif",   OP_INH, "0000001100000000",   XG_INH, 2, 0x0300, 2, 2, CHG_NONE, ALL},
+    {   "sif",   OP_MON, "00000rrr11110111",     XG_R, 2, 0x00F7, 2, 2, CHG_NONE, ALL},
+    {   "stb",  OP_IDO5, "01010rrrrrriiiii", XG_R_R_I, 2, 0x5000, 2, 2, CHG_NONE, ALL},
+    {   "stb",   OP_IDR, "01110rrrrrrrrrrr", XG_R_R_R, 2, 0x7000, 2, 2, CHG_NONE, ALL},
+    {   "stw",  OP_IDO5, "01011rrrrrriiiii", XG_R_R_I, 2, 0x5800, 2, 2, CHG_NONE, ALL},
+    {   "stw",   OP_IDR, "01111rrrrrrrrrrr", XG_R_R_R, 2, 0x7800, 2, 2, CHG_NONE, ALL},
+    {   "sub",   OP_TRI, "00011rrrrrrrrr00", XG_R_R_R, 2, 0x1800, 1, 1, CHG_NZVC, ALL},
+    {  "subh",  OP_IMM8, "11001rrriiiiiiii",   XG_R_I, 2, 0xC800, 1, 1, CHG_NZVC, ALL},
+    {  "subl",  OP_IMM8, "11000rrriiiiiiii",   XG_R_I, 2, 0xC000, 1, 1, CHG_NZVC, ALL},
+    {   "tfr",  OP_MON_R_C, "00000rrr11111000",XG_R_C, 2, 0x00F8, 1, 1, CHG_NONE, ALL},
+    {   "tfr",  OP_MON_C_R, "00000rrr11111001",XG_C_R, 2, 0x00F9, 1, 1, CHG_NONE, ALL},
+    {   "tfr",  OP_MON_R_P, "00000rrr11111010",XG_R_P, 2, 0x00FA, 1, 1, CHG_NONE, ALL},
+    {  "xnor",   OP_TRI, "00010rrrrrrrrr11", XG_R_R_R, 2, 0x1003, 1, 1,  CHG_NZV, ALL},
+    { "xnorh",  OP_IMM8, "10111rrriiiiiiii",   XG_R_I, 2, 0xB800, 1, 1,  CHG_NZV, ALL},
+    { "xnorl",  OP_IMM8, "10110rrriiiiiiii",   XG_R_I, 2, 0xB000, 1, 1,  CHG_NZV, ALL},
+    /*  macro and alias codes  */
+    {   "add", OP_mADD,  "----------------",   XG_R_I, 4,      0, 0, 0, CHG_NONE, ALL},
+    {   "and", OP_mAND,  "----------------",   XG_R_I, 4,      0, 0, 0, CHG_NONE, ALL},
+    {   "bhs",  OP_REL9, "0010000iiiiiiiii",   XG_IP,  2, 0x2000, 0, 0, CHG_NONE, ALL},
+    {   "blo",  OP_REL9, "0010001iiiiiiiii",   XG_IP,  2, 0x2200, 0, 0, CHG_NONE, ALL},
+    {   "cmp",  OP_mCPC, "----------------",   XG_R_I, 4,      0, 0, 0, CHG_NONE, ALL},
+    {   "cmp",   OP_DYA, "00011sssrrrrrr00",   XG_R_R, 2, 0x1800, 0, 0, CHG_NZVC, ALL},
+    {   "com",  OP_DM, "00010rrrsssrrr11",     XG_R_R, 2, 0x1003, 0, 0,  CHG_NZV, ALL},
+    {   "cpc",   OP_DYA, "00011sssrrrrrr01",   XG_R_R, 2, 0x1801, 0, 0, CHG_NZVC, ALL},
+    {   "ldd",  OP_mLDW, "----------------",   XG_R_I, 4,      0, 0, 0, CHG_NONE, ALL},
+    {   "ldw",  OP_mLDW, "----------------",   XG_R_I, 4,      0, 0, 0, CHG_NONE, ALL},
+    {   "mov",   OP_DYA, "00010rrrsssrrr10",   XG_R_R, 2, 0x1002, 0, 0, CHG_NZVC, ALL},
+    {   "neg",   OP_DYA, "00011rrrsssrrr00",   XG_R_R, 2, 0x1800, 0, 0, CHG_NZVC, ALL},
+    {   "sub",  OP_mSUB, "----------------",   XG_R_I, 4,      0, 0, 0, CHG_NONE, ALL},
+    {   "tst",   OP_MON, "00011sssrrrsss00",     XG_R, 2, 0x1800, 0, 0,  CHG_NZV, ALL}
+};
+
+const int xgate_num_opcodes = TABLE_SIZE (xgate_opcodes);