summaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2012-05-03 13:11:53 +0000
committerNick Clifton <nickc@redhat.com>2012-05-03 13:11:53 +0000
commit6e09faca46425a456a7f322a8ad7c9fb86e78530 (patch)
treeadb22825d41d0c33b1d915101b324c51ce4f0ff2 /gas
parent71d18c24d5352ac603d023fde7e491d54f171c96 (diff)
downloadbinutils-redhat-6e09faca46425a456a7f322a8ad7c9fb86e78530.tar.gz
Add support for Motorola XGATE embedded CPU
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog15
-rw-r--r--gas/Makefile.am2
-rw-r--r--gas/Makefile.in18
-rw-r--r--gas/NEWS2
-rw-r--r--gas/config/tc-xgate.c1416
-rw-r--r--gas/config/tc-xgate.h111
-rw-r--r--gas/configure.tgt3
-rw-r--r--gas/doc/Makefile.am1
-rw-r--r--gas/doc/Makefile.in2
-rw-r--r--gas/doc/all.texi1
-rw-r--r--gas/doc/as.texinfo7
-rw-r--r--gas/doc/c-xgate.texi209
-rw-r--r--gas/testsuite/ChangeLog15
-rw-r--r--gas/testsuite/gas/all/gas.exp4
-rw-r--r--gas/testsuite/gas/xgate/abi-xgate-16-32.d8
-rw-r--r--gas/testsuite/gas/xgate/abi-xgate-16-64.d7
-rw-r--r--gas/testsuite/gas/xgate/abi-xgate-32-32.d7
-rw-r--r--gas/testsuite/gas/xgate/abi-xgate-32-64.d7
-rw-r--r--gas/testsuite/gas/xgate/abi.s4
-rw-r--r--gas/testsuite/gas/xgate/all_insns.d130
-rw-r--r--gas/testsuite/gas/xgate/all_insns.s111
-rw-r--r--gas/testsuite/gas/xgate/insns-dwarf2.d84
-rw-r--r--gas/testsuite/gas/xgate/insns.d45
-rw-r--r--gas/testsuite/gas/xgate/insns.s43
-rw-r--r--gas/testsuite/gas/xgate/xgate.exp19
25 files changed, 2269 insertions, 2 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index dfbdb28588..e04a49f7ce 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -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.
diff --git a/gas/Makefile.am b/gas/Makefile.am
index 8f7b7cd60e..80a2fd0d6f 100644
--- a/gas/Makefile.am
+++ b/gas/Makefile.am
@@ -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 \
diff --git a/gas/Makefile.in b/gas/Makefile.in
index 39af3e8c14..672de79dd6 100644
--- a/gas/Makefile.in
+++ b/gas/Makefile.in
@@ -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
diff --git a/gas/NEWS b/gas/NEWS
index 6e2abffc2d..e8dcf507d5 100644
--- 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
index 0000000000..954acdc367
--- /dev/null
+++ b/gas/config/tc-xgate.c
@@ -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
index 0000000000..7f414e5831
--- /dev/null
+++ b/gas/config/tc-xgate.h
@@ -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
diff --git a/gas/configure.tgt b/gas/configure.tgt
index 781cc9dd02..99de3d74c4 100644
--- a/gas/configure.tgt
+++ b/gas/configure.tgt
@@ -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 ;;
diff --git a/gas/doc/Makefile.am b/gas/doc/Makefile.am
index 34ccae5c5a..1fd3e1b4fe 100644
--- a/gas/doc/Makefile.am
+++ b/gas/doc/Makefile.am
@@ -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 \
diff --git a/gas/doc/Makefile.in b/gas/doc/Makefile.in
index e9edb0ea6f..375e513bbd 100644
--- a/gas/doc/Makefile.in
+++ b/gas/doc/Makefile.in
@@ -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 \
diff --git a/gas/doc/all.texi b/gas/doc/all.texi
index 63282f2390..9a55441cb3 100644
--- a/gas/doc/all.texi
+++ b/gas/doc/all.texi
@@ -72,6 +72,7 @@
@set TILEPRO
@set V850
@set VAX
+@set XGATE
@set XSTORMY16
@set XTENSA
@set Z80
diff --git a/gas/doc/as.texinfo b/gas/doc/as.texinfo
index a648f094a2..034cc92fe4 100644
--- a/gas/doc/as.texinfo
+++ b/gas/doc/as.texinfo
@@ -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
index 0000000000..dc802a01f7
--- /dev/null
+++ b/gas/doc/c-xgate.texi
@@ -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
+
diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog
index 76f3dc1ee0..9d394a3da1 100644
--- a/gas/testsuite/ChangeLog
+++ b/gas/testsuite/ChangeLog
@@ -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.
diff --git a/gas/testsuite/gas/all/gas.exp b/gas/testsuite/gas/all/gas.exp
index 7026811e84..2cef5ddd59 100644
--- a/gas/testsuite/gas/all/gas.exp
+++ b/gas/testsuite/gas/all/gas.exp
@@ -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
index 0000000000..a2368d8704
--- /dev/null
+++ b/gas/testsuite/gas/xgate/abi-xgate-16-32.d
@@ -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
index 0000000000..185cb6b472
--- /dev/null
+++ b/gas/testsuite/gas/xgate/abi-xgate-16-64.d
@@ -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
index 0000000000..5ba4b650d9
--- /dev/null
+++ b/gas/testsuite/gas/xgate/abi-xgate-32-32.d
@@ -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
index 0000000000..e454c219e3
--- /dev/null
+++ b/gas/testsuite/gas/xgate/abi-xgate-32-64.d
@@ -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
index 0000000000..a5016ebe63
--- /dev/null
+++ b/gas/testsuite/gas/xgate/abi.s
@@ -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
index 0000000000..94690de93b
--- /dev/null
+++ b/gas/testsuite/gas/xgate/all_insns.d
@@ -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
index 0000000000..20283e939b
--- /dev/null
+++ b/gas/testsuite/gas/xgate/all_insns.s
@@ -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
index 0000000000..3a8e6992aa
--- /dev/null
+++ b/gas/testsuite/gas/xgate/insns-dwarf2.d
@@ -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
index 0000000000..a7d4d58ba1
--- /dev/null
+++ b/gas/testsuite/gas/xgate/insns.d
@@ -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
index 0000000000..e359e683fb
--- /dev/null
+++ b/gas/testsuite/gas/xgate/insns.s
@@ -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
index 0000000000..1af5e76224
--- /dev/null
+++ b/gas/testsuite/gas/xgate/xgate.exp
@@ -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
+