aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gas/ChangeLog12
-rw-r--r--gas/Makefile.am6
-rw-r--r--gas/Makefile.in41
-rw-r--r--gas/config/tc-visium.c2308
-rw-r--r--gas/config/tc-visium.h79
-rw-r--r--gas/configure.tgt3
-rw-r--r--gas/doc/Makefile.am3
-rw-r--r--gas/doc/Makefile.in3
-rw-r--r--gas/doc/all.texi1
-rw-r--r--gas/doc/as.texinfo56
-rw-r--r--gas/doc/c-visium.texi90
-rw-r--r--gas/po/POTFILES.in2
-rw-r--r--gas/testsuite/ChangeLog5
-rw-r--r--gas/testsuite/gas/elf/elf.exp3
-rw-r--r--gas/testsuite/gas/visium/allinsn_def.d134
-rw-r--r--gas/testsuite/gas/visium/allinsn_def.s157
-rw-r--r--gas/testsuite/gas/visium/allinsn_gr5.d153
-rw-r--r--gas/testsuite/gas/visium/allinsn_gr5.s179
-rw-r--r--gas/testsuite/gas/visium/allinsn_gr6.d159
-rw-r--r--gas/testsuite/gas/visium/allinsn_gr6.s185
-rw-r--r--gas/testsuite/gas/visium/basereg.s20
-rw-r--r--gas/testsuite/gas/visium/brr-1.d16
-rw-r--r--gas/testsuite/gas/visium/brr-1.s9
-rw-r--r--gas/testsuite/gas/visium/brr-2.d18
-rw-r--r--gas/testsuite/gas/visium/brr-2.s9
-rw-r--r--gas/testsuite/gas/visium/brr_backward.s15
-rw-r--r--gas/testsuite/gas/visium/brr_forward.s16
-rw-r--r--gas/testsuite/gas/visium/error.exp35
-rw-r--r--gas/testsuite/gas/visium/fcmp.s11
-rw-r--r--gas/testsuite/gas/visium/high-1.d19
-rw-r--r--gas/testsuite/gas/visium/high-1.s11
-rw-r--r--gas/testsuite/gas/visium/immed-1.d17
-rw-r--r--gas/testsuite/gas/visium/immed-1.s10
-rw-r--r--gas/testsuite/gas/visium/rela-1.d18
-rw-r--r--gas/testsuite/gas/visium/rela-1.s20
-rw-r--r--gas/testsuite/gas/visium/visium.exp32
36 files changed, 3824 insertions, 31 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 3508468..2fed961 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,15 @@
+2014-12-06 Eric Botcazou <ebotcazou@adacore.com>
+
+ * configure.tgt: Add Visium support.
+ * Makefile.am (TARGET_CPU_CFILES): Move config/tc-vax.c around
+ and add config/tc-visium.c.
+ (TARGET_CPU_HFILES): Move config/tc-vax.h around and add
+ config/tc-visium.h.
+ * Makefile.in: Regenerate.
+ * config/tc-visium.c: New file.
+ * config/tc-visium.h: Likewise.
+ * po/POTFILES.in: Regenerate.
+
2014-11-28 Sandra Loosemore <sandra@codesourcery.com>
* config/tc-nios2.c (can_evaluate_expr, get_expr_value): Delete.
diff --git a/gas/Makefile.am b/gas/Makefile.am
index 55c86b2..f65225f 100644
--- a/gas/Makefile.am
+++ b/gas/Makefile.am
@@ -185,8 +185,9 @@ TARGET_CPU_CFILES = \
config/tc-tic6x.c \
config/tc-tilegx.c \
config/tc-tilepro.c \
- config/tc-vax.c \
config/tc-v850.c \
+ config/tc-vax.c \
+ config/tc-visium.c \
config/tc-xstormy16.c \
config/tc-xc16x.c \
config/tc-xgate.c \
@@ -256,8 +257,9 @@ TARGET_CPU_HFILES = \
config/tc-tic6x.h \
config/tc-tilegx.h \
config/tc-tilepro.h \
- config/tc-vax.h \
config/tc-v850.h \
+ config/tc-vax.h \
+ config/tc-visium.h \
config/tc-xstormy16.h \
config/tc-xc16x.h \
config/tc-xgate.h \
diff --git a/gas/Makefile.in b/gas/Makefile.in
index 5dc250f..c7b3597 100644
--- a/gas/Makefile.in
+++ b/gas/Makefile.in
@@ -454,8 +454,9 @@ TARGET_CPU_CFILES = \
config/tc-tic6x.c \
config/tc-tilegx.c \
config/tc-tilepro.c \
- config/tc-vax.c \
config/tc-v850.c \
+ config/tc-vax.c \
+ config/tc-visium.c \
config/tc-xstormy16.c \
config/tc-xc16x.c \
config/tc-xgate.c \
@@ -525,8 +526,9 @@ TARGET_CPU_HFILES = \
config/tc-tic6x.h \
config/tc-tilegx.h \
config/tc-tilepro.h \
- config/tc-vax.h \
config/tc-v850.h \
+ config/tc-vax.h \
+ config/tc-visium.h \
config/tc-xstormy16.h \
config/tc-xc16x.h \
config/tc-xgate.h \
@@ -882,6 +884,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-tilepro.Po@am__quote@
@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-visium.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@
@@ -1767,6 +1770,20 @@ tc-tilepro.obj: config/tc-tilepro.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-tilepro.obj `if test -f 'config/tc-tilepro.c'; then $(CYGPATH_W) 'config/tc-tilepro.c'; else $(CYGPATH_W) '$(srcdir)/config/tc-tilepro.c'; fi`
+tc-v850.o: config/tc-v850.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tc-v850.o -MD -MP -MF $(DEPDIR)/tc-v850.Tpo -c -o tc-v850.o `test -f 'config/tc-v850.c' || echo '$(srcdir)/'`config/tc-v850.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tc-v850.Tpo $(DEPDIR)/tc-v850.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='config/tc-v850.c' object='tc-v850.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-v850.o `test -f 'config/tc-v850.c' || echo '$(srcdir)/'`config/tc-v850.c
+
+tc-v850.obj: config/tc-v850.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tc-v850.obj -MD -MP -MF $(DEPDIR)/tc-v850.Tpo -c -o tc-v850.obj `if test -f 'config/tc-v850.c'; then $(CYGPATH_W) 'config/tc-v850.c'; else $(CYGPATH_W) '$(srcdir)/config/tc-v850.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tc-v850.Tpo $(DEPDIR)/tc-v850.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='config/tc-v850.c' object='tc-v850.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-v850.obj `if test -f 'config/tc-v850.c'; then $(CYGPATH_W) 'config/tc-v850.c'; else $(CYGPATH_W) '$(srcdir)/config/tc-v850.c'; fi`
+
tc-vax.o: config/tc-vax.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tc-vax.o -MD -MP -MF $(DEPDIR)/tc-vax.Tpo -c -o tc-vax.o `test -f 'config/tc-vax.c' || echo '$(srcdir)/'`config/tc-vax.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tc-vax.Tpo $(DEPDIR)/tc-vax.Po
@@ -1781,19 +1798,19 @@ tc-vax.obj: config/tc-vax.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-vax.obj `if test -f 'config/tc-vax.c'; then $(CYGPATH_W) 'config/tc-vax.c'; else $(CYGPATH_W) '$(srcdir)/config/tc-vax.c'; fi`
-tc-v850.o: config/tc-v850.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tc-v850.o -MD -MP -MF $(DEPDIR)/tc-v850.Tpo -c -o tc-v850.o `test -f 'config/tc-v850.c' || echo '$(srcdir)/'`config/tc-v850.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tc-v850.Tpo $(DEPDIR)/tc-v850.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='config/tc-v850.c' object='tc-v850.o' libtool=no @AMDEPBACKSLASH@
+tc-visium.o: config/tc-visium.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tc-visium.o -MD -MP -MF $(DEPDIR)/tc-visium.Tpo -c -o tc-visium.o `test -f 'config/tc-visium.c' || echo '$(srcdir)/'`config/tc-visium.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tc-visium.Tpo $(DEPDIR)/tc-visium.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='config/tc-visium.c' object='tc-visium.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-v850.o `test -f 'config/tc-v850.c' || echo '$(srcdir)/'`config/tc-v850.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tc-visium.o `test -f 'config/tc-visium.c' || echo '$(srcdir)/'`config/tc-visium.c
-tc-v850.obj: config/tc-v850.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tc-v850.obj -MD -MP -MF $(DEPDIR)/tc-v850.Tpo -c -o tc-v850.obj `if test -f 'config/tc-v850.c'; then $(CYGPATH_W) 'config/tc-v850.c'; else $(CYGPATH_W) '$(srcdir)/config/tc-v850.c'; fi`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tc-v850.Tpo $(DEPDIR)/tc-v850.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='config/tc-v850.c' object='tc-v850.obj' libtool=no @AMDEPBACKSLASH@
+tc-visium.obj: config/tc-visium.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tc-visium.obj -MD -MP -MF $(DEPDIR)/tc-visium.Tpo -c -o tc-visium.obj `if test -f 'config/tc-visium.c'; then $(CYGPATH_W) 'config/tc-visium.c'; else $(CYGPATH_W) '$(srcdir)/config/tc-visium.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tc-visium.Tpo $(DEPDIR)/tc-visium.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='config/tc-visium.c' object='tc-visium.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-v850.obj `if test -f 'config/tc-v850.c'; then $(CYGPATH_W) 'config/tc-v850.c'; else $(CYGPATH_W) '$(srcdir)/config/tc-v850.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tc-visium.obj `if test -f 'config/tc-visium.c'; then $(CYGPATH_W) 'config/tc-visium.c'; else $(CYGPATH_W) '$(srcdir)/config/tc-visium.c'; fi`
tc-xstormy16.o: config/tc-xstormy16.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tc-xstormy16.o -MD -MP -MF $(DEPDIR)/tc-xstormy16.Tpo -c -o tc-xstormy16.o `test -f 'config/tc-xstormy16.c' || echo '$(srcdir)/'`config/tc-xstormy16.c
diff --git a/gas/config/tc-visium.c b/gas/config/tc-visium.c
new file mode 100644
index 0000000..d44b6e9
--- /dev/null
+++ b/gas/config/tc-visium.c
@@ -0,0 +1,2308 @@
+/* This is the machine dependent code of the Visium Assembler.
+
+ Copyright (C) 2005-2014 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 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include "as.h"
+#include "safe-ctype.h"
+#include "subsegs.h"
+#include "obstack.h"
+
+#include "opcode/visium.h"
+#include "elf/visium.h"
+#include "dwarf2dbg.h"
+#include "dw2gencfi.h"
+
+/* Relocations and fixups:
+
+ There are two different cases where an instruction or data
+ directive operand requires relocation, or fixup.
+
+ 1. Relative branch instructions, take an 16-bit signed word
+ offset. The formula for computing the offset is this:
+
+ offset = (destination - pc) / 4
+
+ Branch instructions never branch to a label not declared
+ locally, so the actual offset can always be computed by the assembler.
+ However, we provide a relocation type to support this.
+
+ 2. Load literal instructions, such as MOVIU, which take a 16-bit
+ literal operand. The literal may be the top or bottom half of
+ a 32-bit value computed by the assembler, or by the linker. We provide
+ two relocation types here.
+
+ 3. Data items (long, word and byte) preset with a value computed by
+ the linker. */
+
+
+/* This string holds the chars that always start a comment. If the
+ pre-processor is disabled, these aren't very useful. The macro
+ tc_comment_chars points to this. */
+const char *visium_comment_chars = "!;";
+
+/* This array holds the chars that only start a comment at the beginning
+ of a line. If the line seems to have the form '# 123 filename' .line
+ and .file directives will appear in the pre-processed output. Note that
+ input_file.c hand checks for '#' at the beginning of the first line of
+ the input file. This is because the compiler outputs #NO_APP at the
+ beginning of its output. Also note that comments like this one will
+ always work. */
+const char line_comment_chars[] = "#!;";
+const char line_separator_chars[] = "";
+
+/* Chars that can be used to separate mantissa from exponent in floating point
+ numbers. */
+const char EXP_CHARS[] = "eE";
+
+/* Chars that mean this number is a floating point constant, as in
+ "0f12.456" or "0d1.2345e12".
+
+ ...Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
+ changed in read.c. Ideally it shouldn't have to know about it at all,
+ but nothing is ideal around here. */
+const char FLT_CHARS[] = "rRsSfFdDxXeE";
+
+/* The size of a relocation record. */
+const int md_reloc_size = 8;
+
+/* The architecture for which we are assembling. */
+enum visium_arch_val
+{
+ VISIUM_ARCH_DEF,
+ VISIUM_ARCH_MCM24,
+ VISIUM_ARCH_MCM,
+ VISIUM_ARCH_GR6
+};
+
+static enum visium_arch_val visium_arch = VISIUM_ARCH_DEF;
+
+/* The opcode architecture for which we are assembling. In contrast to the
+ previous one, this only determines which instructions are supported. */
+static enum visium_opcode_arch_val visium_opcode_arch = VISIUM_OPCODE_ARCH_DEF;
+
+/* Flags to set in the ELF header e_flags field. */
+static flagword visium_flags = 0;
+
+/* More than this number of nops in an alignment op gets a branch instead. */
+static unsigned int nop_limit = 5;
+
+
+/* Translate internal representation of relocation info to BFD target
+ format. */
+arelent *
+tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
+{
+ arelent *reloc;
+ bfd_reloc_code_real_type code;
+
+ 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;
+
+ switch (fixp->fx_r_type)
+ {
+ case BFD_RELOC_8:
+ case BFD_RELOC_16:
+ case BFD_RELOC_32:
+ case BFD_RELOC_8_PCREL:
+ case BFD_RELOC_16_PCREL:
+ case BFD_RELOC_32_PCREL:
+ case BFD_RELOC_VISIUM_HI16:
+ case BFD_RELOC_VISIUM_LO16:
+ case BFD_RELOC_VISIUM_IM16:
+ case BFD_RELOC_VISIUM_REL16:
+ case BFD_RELOC_VISIUM_HI16_PCREL:
+ case BFD_RELOC_VISIUM_LO16_PCREL:
+ case BFD_RELOC_VISIUM_IM16_PCREL:
+ case BFD_RELOC_VTABLE_INHERIT:
+ case BFD_RELOC_VTABLE_ENTRY:
+ code = fixp->fx_r_type;
+ break;
+ default:
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ "internal error: unknown relocation type %d (`%s')",
+ fixp->fx_r_type,
+ bfd_get_reloc_code_name (fixp->fx_r_type));
+ return 0;
+ }
+
+ reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
+ if (reloc->howto == 0)
+ {
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ "internal error: can't export reloc type %d (`%s')",
+ fixp->fx_r_type, bfd_get_reloc_code_name (code));
+ return 0;
+ }
+
+ /* Write the addend. */
+ if (reloc->howto->pc_relative == 0)
+ reloc->addend = fixp->fx_addnumber;
+ else
+ reloc->addend = fixp->fx_offset;
+
+ return reloc;
+}
+
+extern char *input_line_pointer;
+
+
+static void s_bss (int);
+static void visium_rdata (int);
+
+static void visium_update_parity_bit (char *);
+static char *parse_exp (char *, expressionS *);
+
+/* These are the back-ends for the various machine dependent pseudo-ops. */
+void demand_empty_rest_of_line (void);
+
+
+static void
+s_bss (int ignore ATTRIBUTE_UNUSED)
+{
+ /* We don't support putting frags in the BSS segment, we fake it
+ by marking in_bss, then looking at s_skip for clues. */
+
+ subseg_set (bss_section, 0);
+ demand_empty_rest_of_line ();
+}
+
+
+/* This table describes all the machine specific pseudo-ops the assembler
+ has to support. The fields are:
+
+ 1: Pseudo-op name without dot.
+ 2: Function to call to execute this pseudo-op.
+ 3: Integer arg to pass to the function. */
+const pseudo_typeS md_pseudo_table[] =
+{
+ {"bss", s_bss, 0},
+ {"skip", s_space, 0},
+ {"align", s_align_bytes, 0},
+ {"noopt", s_ignore, 0},
+ {"optim", s_ignore, 0},
+ {"rdata", visium_rdata, 0},
+ {"rodata", visium_rdata, 0},
+ {0, 0, 0}
+};
+
+
+static void
+visium_rdata (int xxx)
+{
+ char *save_line = input_line_pointer;
+ static char section[] = ".rodata\n";
+
+ /* Just pretend this is .section .rodata */
+ input_line_pointer = section;
+ obj_elf_section (xxx);
+ input_line_pointer = save_line;
+}
+
+/* Align 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_number_to_chars (char *buf, valueT val, int n)
+{
+ number_to_chars_bigendian (buf, val, n);
+}
+
+symbolS *
+md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+/* The parse options. */
+const char *md_shortopts = "m:";
+
+struct option md_longopts[] =
+{
+ {NULL, no_argument, NULL, 0}
+};
+
+size_t md_longopts_size = sizeof (md_longopts);
+
+struct visium_option_table
+{
+ char *option; /* Option name to match. */
+ char *help; /* Help information. */
+ int *var; /* Variable to change. */
+ int value; /* To what to change it. */
+ char *deprecated; /* If non-null, print this message. */
+};
+
+static struct visium_option_table visium_opts[] =
+{
+ {NULL, NULL, NULL, 0, NULL}
+};
+
+struct visium_arch_option_table
+{
+ char *name;
+ enum visium_arch_val value;
+};
+
+static struct visium_arch_option_table visium_archs[] =
+{
+ {"mcm24", VISIUM_ARCH_MCM24},
+ {"mcm", VISIUM_ARCH_MCM},
+ {"gr5", VISIUM_ARCH_MCM},
+ {"gr6", VISIUM_ARCH_GR6},
+ {NULL, 0}
+};
+
+struct visium_long_option_table
+{
+ char *option; /* Substring to match. */
+ char *help; /* Help information. */
+ int (*func) (char *subopt); /* Function to decode sub-option. */
+ char *deprecated; /* If non-null, print this message. */
+};
+
+static int
+visium_parse_arch (char *str)
+{
+ struct visium_arch_option_table *opt;
+
+ if (strlen (str) == 0)
+ {
+ as_bad ("missing architecture name `%s'", str);
+ return 0;
+ }
+
+
+ for (opt = visium_archs; opt->name != NULL; opt++)
+ if (strcmp (opt->name, str) == 0)
+ {
+ visium_arch = opt->value;
+ return 1;
+ }
+
+ as_bad ("unknown architecture `%s'\n", str);
+ return 0;
+}
+
+static struct visium_long_option_table visium_long_opts[] =
+{
+ {"mtune=", "<arch_name>\t assemble for architecture <arch name>",
+ visium_parse_arch, NULL},
+ {NULL, NULL, NULL, NULL}
+};
+
+int
+md_parse_option (int c, char *arg)
+{
+ struct visium_option_table *opt;
+ struct visium_long_option_table *lopt;
+
+ switch (c)
+ {
+ case 'a':
+ /* Listing option. Just ignore these, we don't support additional
+ ones. */
+ return 0;
+
+ default:
+ for (opt = visium_opts; opt->option != NULL; opt++)
+ {
+ if (c == opt->option[0]
+ && ((arg == NULL && opt->option[1] == 0)
+ || strcmp (arg, opt->option + 1) == 0))
+ {
+ /* If the option is deprecated, tell the user. */
+ if (opt->deprecated != NULL)
+ as_tsktsk ("option `-%c%s' is deprecated: %s", c,
+ arg ? arg : "", opt->deprecated);
+
+ if (opt->var != NULL)
+ *opt->var = opt->value;
+
+ return 1;
+ }
+ }
+
+ for (lopt = visium_long_opts; lopt->option != NULL; lopt++)
+ {
+ /* These options are expected to have an argument. */
+ if (c == lopt->option[0]
+ && arg != NULL
+ && strncmp (arg, lopt->option + 1,
+ strlen (lopt->option + 1)) == 0)
+ {
+ /* If the option is deprecated, tell the user. */
+ if (lopt->deprecated != NULL)
+ as_tsktsk ("option `-%c%s' is deprecated: %s", c, arg,
+ lopt->deprecated);
+
+ /* Call the sup-option parser. */
+ return lopt->func (arg + strlen (lopt->option) - 1);
+ }
+ }
+
+ return 0;
+ }
+
+ return 1;
+}
+
+void
+md_show_usage (FILE * fp)
+{
+ struct visium_option_table *opt;
+ struct visium_long_option_table *lopt;
+
+ fprintf (fp, " Visium-specific assembler options:\n");
+
+ for (opt = visium_opts; opt->option != NULL; opt++)
+ if (opt->help != NULL)
+ fprintf (fp, " -%-23s%s\n", opt->option, opt->help);
+
+ for (lopt = visium_long_opts; lopt->option != NULL; lopt++)
+ if (lopt->help != NULL)
+ fprintf (fp, " -%s%s\n", lopt->option, lopt->help);
+
+}
+
+/* Interface to relax_segment. */
+
+/* Return the estimate of the size of a machine dependent frag
+ before any relaxing is done. It may also create any necessary
+ relocations. */
+int
+md_estimate_size_before_relax (fragS * fragP,
+ segT segment ATTRIBUTE_UNUSED)
+{
+ fragP->fr_var = 4;
+ return 4;
+}
+
+/* Get the address of a symbol during relaxation. From tc-arm.c. */
+static addressT
+relaxed_symbol_addr (fragS *fragp, long stretch)
+{
+ fragS *sym_frag;
+ addressT addr;
+ symbolS *sym;
+
+ sym = fragp->fr_symbol;
+ sym_frag = symbol_get_frag (sym);
+ know (S_GET_SEGMENT (sym) != absolute_section
+ || sym_frag == &zero_address_frag);
+ addr = S_GET_VALUE (sym) + fragp->fr_offset;
+
+ /* If frag has yet to be reached on this pass, assume it will
+ move by STRETCH just as we did. If this is not so, it will
+ be because some frag between grows, and that will force
+ another pass. */
+ if (stretch != 0
+ && sym_frag->relax_marker != fragp->relax_marker)
+ {
+ fragS *f;
+
+ /* Adjust stretch for any alignment frag. Note that if have
+ been expanding the earlier code, the symbol may be
+ defined in what appears to be an earlier frag. FIXME:
+ This doesn't handle the fr_subtype field, which specifies
+ a maximum number of bytes to skip when doing an
+ alignment. */
+ for (f = fragp; f != NULL && f != sym_frag; f = f->fr_next)
+ {
+ if (f->fr_type == rs_align || f->fr_type == rs_align_code)
+ {
+ if (stretch < 0)
+ stretch = - ((- stretch)
+ & ~ ((1 << (int) f->fr_offset) - 1));
+ else
+ stretch &= ~ ((1 << (int) f->fr_offset) - 1);
+ if (stretch == 0)
+ break;
+ }
+ }
+ if (f != NULL)
+ addr += stretch;
+ }
+
+ return addr;
+}
+
+/* Relax a machine dependent frag. This returns the amount by which
+ the current size of the frag should change. */
+int
+visium_relax_frag (asection *sec, fragS *fragP, long stretch)
+{
+ int old_size, new_size;
+ addressT addr;
+
+ /* We only handle relaxation for the BRR instruction. */
+ gas_assert (fragP->fr_subtype == mode_ci);
+
+ if (!S_IS_DEFINED (fragP->fr_symbol)
+ || sec != S_GET_SEGMENT (fragP->fr_symbol)
+ || S_IS_WEAK (fragP->fr_symbol))
+ return 0;
+
+ old_size = fragP->fr_var;
+ addr = relaxed_symbol_addr (fragP, stretch);
+
+ /* If the target is the address of the instruction, we'll insert a NOP. */
+ if (addr == fragP->fr_address + fragP->fr_fix)
+ new_size = 8;
+ else
+ new_size = 4;
+
+ fragP->fr_var = new_size;
+ return new_size - old_size;
+}
+
+/* Convert a machine dependent frag. */
+void
+md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED, segT sec ATTRIBUTE_UNUSED,
+ fragS * fragP)
+{
+ char *buf = fragP->fr_literal + fragP->fr_fix;
+ expressionS exp;
+ fixS *fixP;
+
+ /* We only handle relaxation for the BRR instruction. */
+ gas_assert (fragP->fr_subtype == mode_ci);
+
+ /* Insert the NOP if requested. */
+ if (fragP->fr_var == 8)
+ {
+ memcpy (buf + 4, buf, 4);
+ memset (buf, 0, 4);
+ fragP->fr_fix += 4;
+ }
+
+ exp.X_op = O_symbol;
+ exp.X_add_symbol = fragP->fr_symbol;
+ exp.X_add_number = fragP->fr_offset;
+
+ /* Now we can create the relocation at the correct offset. */
+ fixP = fix_new_exp (fragP, fragP->fr_fix, 4, &exp, 1, BFD_RELOC_VISIUM_REL16);
+ fixP->fx_file = fragP->fr_file;
+ fixP->fx_line = fragP->fr_line;
+ fragP->fr_fix += 4;
+ fragP->fr_var = 0;
+}
+
+/* The location from which a PC relative jump should be calculated,
+ given a PC relative jump reloc. */
+long
+visium_pcrel_from_section (fixS *fixP, segT sec)
+{
+ if (fixP->fx_addsy != (symbolS *) NULL
+ && (!S_IS_DEFINED (fixP->fx_addsy)
+ || S_GET_SEGMENT (fixP->fx_addsy) != sec))
+ {
+ /* The symbol is undefined (or is defined but not in this section).
+ Let the linker figure it out. */
+ return 0;
+ }
+
+ /* Return the address of the instruction. */
+ return fixP->fx_where + fixP->fx_frag->fr_address;
+}
+
+/* Indicate whether a fixup against a locally defined
+ symbol should be adjusted to be against the section
+ symbol. */
+bfd_boolean
+visium_fix_adjustable (fixS *fix)
+{
+ /* We need the symbol name for the VTABLE entries. */
+ return (fix->fx_r_type != BFD_RELOC_VTABLE_INHERIT
+ && fix->fx_r_type != BFD_RELOC_VTABLE_ENTRY);
+}
+
+/* Update the parity bit of the 4-byte instruction in BUF. */
+static void
+visium_update_parity_bit (char *buf)
+{
+ int p1 = (buf[0] & 0x7f) ^ buf[1] ^ buf[2] ^ buf[3];
+ int p2 = 0;
+ int i;
+
+ for (i = 1; i <= 8; i++)
+ {
+ p2 ^= (p1 & 1);
+ p1 >>= 1;
+ }
+
+ buf[0] = (buf[0] & 0x7f) | ((p2 << 7) & 0x80);
+}
+
+/* This is called from HANDLE_ALIGN in write.c. Fill in the contents
+ of an rs_align_code fragment. */
+void
+visium_handle_align (fragS *fragP)
+{
+ valueT count
+ = fragP->fr_next->fr_address - (fragP->fr_address + fragP->fr_fix);
+ valueT fix = count & 3;
+ char *p = fragP->fr_literal + fragP->fr_fix;
+
+ if (fix)
+ {
+ memset (p, 0, fix);
+ p += fix;
+ count -= fix;
+ fragP->fr_fix += fix;
+ }
+
+ if (count == 0)
+ return;
+
+ fragP->fr_var = 4;
+
+ if (count > 4 * nop_limit && count <= 131068)
+ {
+ struct frag *rest;
+
+ /* Make a branch, then follow with nops. Insert another
+ frag to handle the nops. */
+ md_number_to_chars (p, 0x78000000 + (count >> 2), 4);
+ visium_update_parity_bit (p);
+
+ rest = xmalloc (SIZEOF_STRUCT_FRAG + 4);
+ memcpy (rest, fragP, SIZEOF_STRUCT_FRAG);
+ fragP->fr_next = rest;
+ rest->fr_address += rest->fr_fix + 4;
+ rest->fr_fix = 0;
+ /* If we leave the next frag as rs_align_code we'll come here
+ again, resulting in a bunch of branches rather than a
+ branch followed by nops. */
+ rest->fr_type = rs_align;
+ p = rest->fr_literal;
+ }
+
+ memset (p, 0, 4);
+}
+
+/* Apply a fixS to the frags, now that we know the value it ought to
+ hold. */
+void
+md_apply_fix (fixS * fixP, valueT * value, segT segment)
+{
+ char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
+ offsetT val;
+ long insn;
+
+ val = *value;
+
+ gas_assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
+
+ /* Remember value for tc_gen_reloc. */
+ fixP->fx_addnumber = val;
+
+ /* Since DIFF_EXPR_OK is defined, .-foo gets turned into PC
+ relative relocs. If this has happened, a non-PC relative
+ reloc must be reinstalled with its PC relative version here. */
+ if (fixP->fx_pcrel)
+ {
+ switch (fixP->fx_r_type)
+ {
+ case BFD_RELOC_8:
+ fixP->fx_r_type = BFD_RELOC_8_PCREL;
+ break;
+ case BFD_RELOC_16:
+ fixP->fx_r_type = BFD_RELOC_16_PCREL;
+ break;
+ case BFD_RELOC_32:
+ fixP->fx_r_type = BFD_RELOC_32_PCREL;
+ break;
+ case BFD_RELOC_VISIUM_HI16:
+ fixP->fx_r_type = BFD_RELOC_VISIUM_HI16_PCREL;
+ break;
+ case BFD_RELOC_VISIUM_LO16:
+ fixP->fx_r_type = BFD_RELOC_VISIUM_LO16_PCREL;
+ break;
+ case BFD_RELOC_VISIUM_IM16:
+ fixP->fx_r_type = BFD_RELOC_VISIUM_IM16_PCREL;
+ break;
+ default:
+ break;
+ }
+ }
+
+ /* If this is a data relocation, just output VAL. */
+ switch (fixP->fx_r_type)
+ {
+ case BFD_RELOC_8:
+ case BFD_RELOC_8_PCREL:
+ md_number_to_chars (buf, val, 1);
+ break;
+ case BFD_RELOC_16:
+ case BFD_RELOC_16_PCREL:
+ md_number_to_chars (buf, val, 2);
+ break;
+ case BFD_RELOC_32:
+ case BFD_RELOC_32_PCREL:
+ md_number_to_chars (buf, val, 4);
+ break;
+ case BFD_RELOC_VTABLE_INHERIT:
+ case BFD_RELOC_VTABLE_ENTRY:
+ fixP->fx_done = 0;
+ break;
+ default:
+ /* It's a relocation against an instruction. */
+ insn = bfd_getb32 ((unsigned char *) buf);
+
+ switch (fixP->fx_r_type)
+ {
+ case BFD_RELOC_VISIUM_REL16:
+ if (fixP->fx_addsy == NULL
+ || (S_IS_DEFINED (fixP->fx_addsy)
+ && S_GET_SEGMENT (fixP->fx_addsy) == segment))
+ {
+ if (val > 0x1fffc || val < -0x20000)
+ as_bad_where
+ (fixP->fx_file, fixP->fx_line,
+ "16-bit word displacement out of range: value = %d",
+ (int) val);
+ val = (val >> 2);
+
+ insn = (insn & 0xffff0000) | (val & 0x0000ffff);
+ }
+ break;
+
+ case BFD_RELOC_VISIUM_HI16:
+ case BFD_RELOC_VISIUM_HI16_PCREL:
+ if (fixP->fx_addsy == NULL)
+ insn = (insn & 0xffff0000) | ((val >> 16) & 0x0000ffff);
+ break;
+
+ case BFD_RELOC_VISIUM_LO16:
+ case BFD_RELOC_VISIUM_LO16_PCREL:
+ if (fixP->fx_addsy == NULL)
+ insn = (insn & 0xffff0000) | (val & 0x0000ffff);
+ break;
+
+ case BFD_RELOC_VISIUM_IM16:
+ case BFD_RELOC_VISIUM_IM16_PCREL:
+ if (fixP->fx_addsy == NULL)
+ {
+ if ((val & 0xffff0000) != 0)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ "16-bit immediate out of range: value = %d",
+ (int) val);
+
+ insn = (insn & 0xffff0000) | val;
+ }
+ break;
+
+ case BFD_RELOC_NONE:
+ default:
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ "bad or unhandled relocation type: 0x%02x",
+ fixP->fx_r_type);
+ break;
+ }
+
+ bfd_putb32 (insn, (unsigned char *) buf);
+ visium_update_parity_bit (buf);
+ break;
+ }
+
+ /* Are we finished with this relocation now? */
+ if (fixP->fx_addsy == NULL)
+ fixP->fx_done = 1;
+}
+
+char *
+parse_exp (char *s, expressionS * op)
+{
+ char *save = input_line_pointer;
+ char *new;
+
+ if (!s)
+ {
+ return s;
+ }
+
+ input_line_pointer = s;
+ expression (op);
+ new = input_line_pointer;
+ input_line_pointer = save;
+ return new;
+}
+
+/* If the given string is a Visium opcode mnemonic return the code
+ otherwise return -1. Use binary chop to find matching entry. */
+static int
+get_opcode (int *code, enum addressing_mode *mode, char *flags, char *mnem)
+{
+ int l = 0;
+ int r = sizeof (opcode_table) / sizeof (struct opcode_entry) - 1;
+
+ do
+ {
+ int mid = (l + r) / 2;
+ int ans = strcmp (mnem, opcode_table[mid].mnem);
+
+ if (ans < 0)
+ r = mid - 1;
+ else if (ans > 0)
+ l = mid + 1;
+ else
+ {
+ *code = opcode_table[mid].code;
+ *mode = opcode_table[mid].mode;
+ *flags = opcode_table[mid].flags;
+
+ return 0;
+ }
+ }
+ while (l <= r);
+
+ return -1;
+}
+
+/* This function is called when the assembler starts up. It is called
+ after the options have been parsed and the output file has been
+ opened. */
+void
+md_begin (void)
+{
+ switch (visium_arch)
+ {
+ case VISIUM_ARCH_DEF:
+ break;
+ case VISIUM_ARCH_MCM24:
+ visium_opcode_arch = VISIUM_OPCODE_ARCH_GR5;
+ visium_flags |= EF_VISIUM_ARCH_MCM24;
+ break;
+ case VISIUM_ARCH_MCM:
+ visium_opcode_arch = VISIUM_OPCODE_ARCH_GR5;
+ visium_flags |= EF_VISIUM_ARCH_MCM;
+ break;
+ case VISIUM_ARCH_GR6:
+ visium_opcode_arch = VISIUM_OPCODE_ARCH_GR6;
+ visium_flags |= EF_VISIUM_ARCH_MCM | EF_VISIUM_ARCH_GR6;
+ nop_limit = 2;
+ break;
+ default:
+ gas_assert (0);
+ }
+
+ bfd_set_private_flags (stdoutput, visium_flags);
+}
+
+/* This is identical to the md_atof in m68k.c. I think this is right,
+ but I'm not sure.
+
+ Turn a string in input_line_pointer into a floating point constant of type
+ type, and store the appropriate bytes in *litP. The number of LITTLENUMS
+ emitted is stored in *sizeP . An error message is returned,
+ or NULL on OK. */
+
+/* Equal to MAX_PRECISION in atof-ieee.c. */
+#define MAX_LITTLENUMS 6
+
+char *
+md_atof (int type, char *litP, int *sizeP)
+{
+ int i, prec;
+ LITTLENUM_TYPE words[MAX_LITTLENUMS];
+ char *t;
+
+ switch (type)
+ {
+ case 'f':
+ case 'F':
+ case 's':
+ case 'S':
+ prec = 2;
+ break;
+
+ case 'd':
+ case 'D':
+ case 'r':
+ case 'R':
+ prec = 4;
+ break;
+
+ case 'x':
+ case 'X':
+ prec = 6;
+ break;
+
+ case 'p':
+ case 'P':
+ prec = 6;
+ break;
+
+ default:
+ *sizeP = 0;
+ return "Bad call to MD_ATOF()";
+ }
+
+ t = atof_ieee (input_line_pointer, type, words);
+ if (t)
+ input_line_pointer = t;
+ *sizeP = prec * sizeof (LITTLENUM_TYPE);
+
+ if (target_big_endian)
+ {
+ for (i = 0; i < prec; i++)
+ {
+ md_number_to_chars (litP, (valueT) words[i],
+ sizeof (LITTLENUM_TYPE));
+ litP += sizeof (LITTLENUM_TYPE);
+ }
+ }
+ else
+ {
+ for (i = prec - 1; i >= 0; i--)
+ {
+ md_number_to_chars (litP, (valueT) words[i],
+ sizeof (LITTLENUM_TYPE));
+ litP += sizeof (LITTLENUM_TYPE);
+ }
+ }
+
+ return 0;
+}
+
+static inline char *
+skip_space (char *s)
+{
+ while (*s == ' ' || *s == '\t')
+ ++s;
+
+ return s;
+}
+
+static int
+parse_gen_reg (char **sptr, int *rptr)
+{
+ char *s = skip_space (*sptr);
+ char buf[10];
+ int cnt;
+ int l, r;
+
+ cnt = 0;
+ memset (buf, '\0', 10);
+ while ((ISALNUM (*s)) && cnt < 10)
+ buf[cnt++] = TOLOWER (*s++);
+
+ l = 0;
+ r = sizeof (gen_reg_table) / sizeof (struct reg_entry) - 1;
+
+ do
+ {
+ int mid = (l + r) / 2;
+ int ans = strcmp (buf, gen_reg_table[mid].name);
+
+ if (ans < 0)
+ r = mid - 1;
+ else if (ans > 0)
+ l = mid + 1;
+ else
+ {
+ *rptr = gen_reg_table[mid].code;
+ *sptr = s;
+ return 0;
+ }
+ }
+ while (l <= r);
+
+ return -1;
+}
+
+static int
+parse_fp_reg (char **sptr, int *rptr)
+{
+ char *s = skip_space (*sptr);
+ char buf[10];
+ int cnt;
+ int l, r;
+
+ cnt = 0;
+ memset (buf, '\0', 10);
+ while ((ISALNUM (*s)) && cnt < 10)
+ buf[cnt++] = TOLOWER (*s++);
+
+ l = 0;
+ r = sizeof (fp_reg_table) / sizeof (struct reg_entry) - 1;
+
+ do
+ {
+ int mid = (l + r) / 2;
+ int ans = strcmp (buf, fp_reg_table[mid].name);
+
+ if (ans < 0)
+ r = mid - 1;
+ else if (ans > 0)
+ l = mid + 1;
+ else
+ {
+ *rptr = fp_reg_table[mid].code;
+ *sptr = s;
+ return 0;
+ }
+ }
+ while (l <= r);
+
+ return -1;
+}
+
+static int
+parse_cc (char **sptr, int *rptr)
+{
+ char *s = skip_space (*sptr);
+ char buf[10];
+ int cnt;
+ int l, r;
+
+ cnt = 0;
+ memset (buf, '\0', 10);
+ while ((ISALNUM (*s)) && cnt < 10)
+ buf[cnt++] = TOLOWER (*s++);
+
+ l = 0;
+ r = sizeof (cc_table) / sizeof (struct cc_entry) - 1;
+
+ do
+ {
+ int mid = (l + r) / 2;
+ int ans = strcmp (buf, cc_table[mid].name);
+
+ if (ans < 0)
+ r = mid - 1;
+ else if (ans > 0)
+ l = mid + 1;
+ else
+ {
+ *rptr = cc_table[mid].code;
+ *sptr = s;
+ return 0;
+ }
+ }
+ while (l <= r);
+
+ return -1;
+}
+
+/* Previous dest is the destination register number of the instruction
+ before the current one. */
+static int previous_dest = 0;
+static int previous_mode = 0;
+static int condition_code = 0;
+static int this_dest = 0;
+static int this_mode = 0;
+
+
+/* This is the main function in this file. It takes a line of assembly language
+ source code and assembles it. Note, labels and pseudo ops have already
+ been removed, so too has leading white space. */
+void
+md_assemble (char *str0)
+{
+ char *str = str0;
+ int cnt;
+ char mnem[10];
+ int opcode;
+ enum addressing_mode amode;
+ char arch_flags;
+ int ans;
+
+ char *output;
+ int reloc = 0;
+ relax_substateT relax = 0;
+ expressionS e1;
+ int r1, r2, r3;
+ int cc;
+ int indx;
+
+ /* Initialize the expression. */
+ e1.X_op = O_absent;
+
+ /* Initialize destination register.
+ If the instruction we just looked at is in the delay slot of an
+ unconditional branch, then there is no index hazard. */
+ if ((previous_mode == mode_cad || previous_mode == mode_ci)
+ && condition_code == 15)
+ this_dest = 0;
+
+ previous_dest = this_dest;
+ previous_mode = this_mode;
+ this_dest = 0;
+
+ /* Drop leading whitespace (probably not required). */
+ while (*str == ' ')
+ str++;
+
+ /* Get opcode mnemonic and make sure it's in lower case. */
+ cnt = 0;
+ memset (mnem, '\0', 10);
+ while ((ISALNUM (*str) || *str == '.' || *str == '_') && cnt < 10)
+ mnem[cnt++] = TOLOWER (*str++);
+
+ /* Look up mnemonic in opcode table, and get the code,
+ the instruction format, and the flags that indicate
+ which family members support this mnenonic. */
+ if (get_opcode (&opcode, &amode, &arch_flags, mnem) < 0)
+ {
+ as_bad ("Unknown instruction mnenonic `%s'", mnem);
+ return;
+ }
+
+ if ((VISIUM_OPCODE_ARCH_MASK (visium_opcode_arch) & arch_flags) == 0)
+ {
+ as_bad ("Architecture mismatch on `%s'", mnem);
+ return;
+ }
+
+ this_mode = amode;
+
+ switch (amode)
+ {
+ case mode_d:
+ /* register :=
+ Example:
+ readmda r1 */
+ ans = parse_gen_reg (&str, &r1);
+ if (ans < 0)
+ {
+ as_bad ("Dest register required");
+ return;
+ }
+ opcode |= (r1 << 10);
+ this_dest = r1;
+ break;
+
+ case mode_a:
+ /* op= register
+ Example: asld r1 */
+ ans = parse_gen_reg (&str, &r1);
+ if (ans < 0)
+ {
+ as_bad ("SourceA register required");
+ return;
+ }
+ opcode |= (r1 << 16);
+ break;
+
+ case mode_ab:
+ /* register * register
+ Example:
+ mults r1,r2 */
+ ans = parse_gen_reg (&str, &r1);
+ if (ans < 0)
+ {
+ as_bad ("SourceA register required");
+ return;
+ }
+ str = skip_space (str);
+ if (*str == ',')
+ {
+ str++;
+ ans = parse_gen_reg (&str, &r2);
+ if (ans < 0)
+ {
+ as_bad ("SourceB register required");
+ return;
+ }
+ opcode |= (r1 << 16) | (r2 << 4);
+ }
+ else
+ {
+ as_bad ("SourceB register required");
+ return;
+ }
+ break;
+
+ case mode_da:
+ /* register := register
+ Example:
+ extb.l r1,r2 */
+ ans = parse_gen_reg (&str, &r1);
+ if (ans < 0)
+ {
+ as_bad ("Dest register required");
+ return;
+ }
+ str = skip_space (str);
+ if (*str == ',')
+ {
+ str++;
+ ans = parse_gen_reg (&str, &r2);
+ if (ans < 0)
+ {
+ as_bad ("SourceA register required");
+ return;
+ }
+ opcode |= (r1 << 10) | (r2 << 16);
+ }
+ else
+ {
+ as_bad ("SourceB register required");
+ return;
+ }
+ this_dest = r1;
+ break;
+
+ case mode_dab:
+ /* register := register * register
+ Example:
+ add.l r1,r2,r3 */
+ ans = parse_gen_reg (&str, &r1);
+ if (ans < 0)
+ {
+ as_bad ("Dest register required");
+ return;
+ }
+ str = skip_space (str);
+ if (*str == ',')
+ {
+ str++;
+ ans = parse_gen_reg (&str, &r2);
+ if (ans < 0)
+ {
+ as_bad ("SourceA register required");
+ return;
+ }
+ str = skip_space (str);
+ if (*str == ',')
+ {
+ str++;
+ ans = parse_gen_reg (&str, &r3);
+ if (ans < 0)
+ {
+ as_bad ("SourceB register required");
+ return;
+ }
+
+ /* Got three regs, assemble instruction. */
+ opcode |= (r1 << 10) | (r2 << 16) | (r3 << 4);
+ }
+ else
+ {
+ as_bad ("SourceA register required");
+ return;
+ }
+ }
+ else
+ {
+ as_bad ("Dest register required");
+ return;
+ }
+ this_dest = r1;
+ break;
+
+ case mode_iab:
+ /* 5-bit immediate * register * register
+ Example:
+ eamwrite 3,r1,r2 */
+ str = parse_exp (str, &e1);
+ str = skip_space (str);
+ if (e1.X_op != O_absent && *str == ',')
+ {
+ int eam_op = e1.X_add_number;
+
+ str = skip_space (str + 1);
+ ans = parse_gen_reg (&str, &r2);
+ if (ans < 0)
+ {
+ as_bad ("SourceA register required");
+ return;
+ }
+ str = skip_space (str);
+ if (*str == ',')
+ {
+ str++;
+ ans = parse_gen_reg (&str, &r3);
+ if (ans < 0)
+ {
+ as_bad ("SourceB register required");
+ return;
+ }
+
+ /* Got three operands, assemble instruction. */
+ if (eam_op < 0 || eam_op > 31)
+ {
+ as_bad ("eam_op out of range");
+ }
+ opcode |= ((eam_op & 0x1f) << 10) | (r2 << 16) | (r3 << 4);
+ }
+ }
+ else
+ {
+ as_bad ("EAM_OP required");
+ return;
+ }
+ break;
+
+ case mode_0ab:
+ /* zero * register * register
+ Example:
+ cmp.l r1,r2 */
+ ans = parse_gen_reg (&str, &r1);
+ if (ans < 0)
+ {
+ as_bad ("SourceA register required");
+ return;
+ }
+ str = skip_space (str);
+ if (*str == ',')
+ {
+ str++;
+ ans = parse_gen_reg (&str, &r2);
+ if (ans < 0)
+ {
+ as_bad ("SourceB register required");
+ return;
+ }
+ opcode |= (r1 << 16) | (r2 << 4);
+ }
+ else
+ {
+ as_bad ("SourceB register required");
+ return;
+ }
+ break;
+
+ case mode_da0:
+ /* register * register * zero
+ Example:
+ move.l r1,r2 */
+ ans = parse_gen_reg (&str, &r1);
+ if (ans < 0)
+ {
+ as_bad ("Dest register required");
+ return;
+ }
+ str = skip_space (str);
+ if (*str == ',')
+ {
+ str++;
+ ans = parse_gen_reg (&str, &r2);
+ if (ans < 0)
+ {
+ as_bad ("SourceA register required");
+ return;
+ }
+ opcode |= (r1 << 10) | (r2 << 16);
+ }
+ else
+ {
+ as_bad ("SourceA register required");
+ return;
+ }
+ this_dest = r1;
+ break;
+
+ case mode_cad:
+ /* condition * register * register
+ Example:
+ bra tr,r1,r2 */
+ ans = parse_cc (&str, &cc);
+ if (ans < 0)
+ {
+ as_bad ("condition code required");
+ return;
+ }
+
+ str = skip_space (str);
+ if (*str == ',')
+ {
+ str = skip_space (str + 1);
+ ans = parse_gen_reg (&str, &r2);
+ if (ans < 0)
+ {
+ as_bad ("SourceA register required");
+ return;
+ }
+ str = skip_space (str);
+ if (*str == ',')
+ {
+ str++;
+ ans = parse_gen_reg (&str, &r3);
+ if (ans < 0)
+ {
+ as_bad ("Dest register required");
+ return;
+ }
+
+ /* Got three operands, assemble instruction. */
+ opcode |= (cc << 27) | (r2 << 16) | (r3 << 10);
+ }
+ else
+ {
+ as_bad ("Dest register required");
+ return;
+ }
+ }
+ else
+ {
+ as_bad ("SourceA register required");
+ return;
+ }
+
+ if (previous_mode == mode_cad || previous_mode == mode_ci)
+ as_bad ("branch instruction in delay slot");
+
+ this_dest = r3;
+ condition_code = cc;
+ break;
+
+ case mode_das:
+ /* register := register * 5-bit imediate/register shift count
+ Example:
+ asl.l r1,r2,4 */
+ ans = parse_gen_reg (&str, &r1);
+ if (ans < 0)
+ {
+ as_bad ("Dest register required");
+ return;
+ }
+ str = skip_space (str);
+ if (*str == ',')
+ {
+ str++;
+ ans = parse_gen_reg (&str, &r2);
+ if (ans < 0)
+ {
+ as_bad ("SourceA register required");
+ return;
+ }
+ str = skip_space (str);
+ if (*str == ',')
+ {
+ str++;
+ ans = parse_gen_reg (&str, &r3);
+ if (ans == 0)
+ {
+ opcode |= (r1 << 10) | (r2 << 16) | (r3 << 4);
+ }
+ else
+ {
+ str = parse_exp (str, &e1);
+ if (e1.X_op == O_constant)
+ {
+ int imm = e1.X_add_number;
+
+ if (imm < 0 || imm > 31)
+ as_bad ("immediate value out of range");
+
+ opcode |=
+ (r1 << 10) | (r2 << 16) | (1 << 9) | ((imm & 0x1f) <<
+ 4);
+ }
+ else
+ {
+ as_bad ("immediate operand required");
+ return;
+ }
+ }
+ }
+ }
+ else
+ {
+ as_bad ("SourceA register required");
+ return;
+ }
+ this_dest = r1;
+ break;
+
+ case mode_di:
+ /* register := 5-bit immediate
+ Example:
+ eamread r1,3 */
+ ans = parse_gen_reg (&str, &r1);
+ if (ans < 0)
+ {
+ as_bad ("Dest register required");
+ return;
+ }
+ str = skip_space (str);
+ if (*str == ',')
+ {
+ str++;
+ str = parse_exp (str, &e1);
+ if (e1.X_op == O_constant)
+ {
+ int opnd2 = e1.X_add_number;
+
+ if (opnd2 < 0 || opnd2 > 31)
+ {
+ as_bad ("immediate operand out of range");
+ return;
+ }
+ opcode |= (r1 << 10) | ((opnd2 & 0x1f) << 4);
+ }
+ else
+ {
+ as_bad ("immediate operand required");
+ return;
+ }
+ }
+ else
+ {
+ as_bad ("immediate operand required");
+ return;
+ }
+ this_dest = r1;
+ break;
+
+ case mode_ir:
+ /* 5-bit immediate * register, e.g. trace 1,r1 */
+ str = parse_exp (str, &e1);
+ str = skip_space (str);
+ if (e1.X_op == O_constant && *str == ',')
+ {
+ int opnd1 = e1.X_add_number;
+
+ str = skip_space (str + 1);
+ ans = parse_gen_reg (&str, &r2);
+ if (ans < 0)
+ {
+ as_bad ("SourceA register required");
+ return;
+ }
+
+ /* Got two operands, assemble instruction. */
+ if (opnd1 < 0 || opnd1 > 31)
+ {
+ as_bad ("1st operand out of range");
+ }
+ opcode |= ((opnd1 & 0x1f) << 10) | (r2 << 16);
+ }
+ else
+ {
+ as_bad ("Immediate operand required");
+ return;
+ }
+ break;
+
+ case mode_ai:
+ /* register *= 16-bit unsigned immediate
+ Example:
+ addi r1,123 */
+ ans = parse_gen_reg (&str, &r1);
+ if (ans < 0)
+ {
+ as_bad ("Dest register required");
+ return;
+ }
+ opcode |= (r1 << 16);
+
+ str = skip_space (str);
+ if (*str != ',')
+ {
+ as_bad ("immediate value missing");
+ return;
+ }
+ this_dest = r1;
+
+ /* fall through... */
+
+ case mode_i:
+ /* MOVIL/WRTL traditionally get an implicit "%l" applied
+ to their immediate value. For other opcodes, unless
+ the immediate value is decorated with "%u" or "%l"
+ it must be in the range 0 .. 65535. */
+ if ((opcode & 0x7fe00000) == 0x04800000
+ || (opcode & 0x7fe00000) == 0x05000000)
+ reloc = BFD_RELOC_VISIUM_LO16;
+ else
+ reloc = BFD_RELOC_VISIUM_IM16;
+
+ str = skip_space (str + 1);
+
+ if (*str == '%')
+ {
+ if (str[1] == 'u')
+ reloc = BFD_RELOC_VISIUM_HI16;
+ else if (str[1] == 'l')
+ reloc = BFD_RELOC_VISIUM_LO16;
+ else
+ {
+ as_bad ("bad char after %%");
+ return;
+ }
+
+ str += 2;
+ }
+ str = parse_exp (str, &e1);
+ if (e1.X_op != O_absent)
+ {
+ if (e1.X_op == O_constant)
+ {
+ int imm = e1.X_add_number;
+
+ if (reloc == BFD_RELOC_VISIUM_HI16)
+ opcode |= ((imm >> 16) & 0xffff);
+ else if (reloc == BFD_RELOC_VISIUM_LO16)
+ opcode |= (imm & 0xffff);
+ else
+ {
+ if (imm < 0 || imm > 0xffff)
+ as_bad ("immediate value out of range");
+
+ opcode |= (imm & 0xffff);
+ }
+ /* No relocation is needed. */
+ reloc = 0;
+ }
+ }
+ else
+ {
+ as_bad ("immediate value missing");
+ return;
+ }
+ break;
+
+ case mode_bax:
+ /* register * register * 5-bit immediate,
+ SourceB * SourceA * Index
+ Examples
+ write.l (r1),r2
+ write.l 3(r1),r2 */
+ str = skip_space (str);
+
+ indx = 0;
+ if (*str != '(')
+ {
+ str = parse_exp (str, &e1);
+ if (e1.X_op == O_constant)
+ {
+ indx = e1.X_add_number;
+
+ if (indx < 0 || indx > 31)
+ {
+ as_bad ("Index out of range");
+ return;
+ }
+ }
+ else
+ {
+ as_bad ("Index(SourceA) required");
+ return;
+ }
+ }
+
+ str = skip_space (str);
+
+ if (*str != '(')
+ {
+ as_bad ("Index(SourceA) required");
+ return;
+ }
+
+ str = skip_space (str + 1);
+
+ ans = parse_gen_reg (&str, &r1);
+ if (ans < 0)
+ {
+ as_bad ("SourceA register required");
+ return;
+ }
+ str = skip_space (str);
+ if (*str != ')')
+ {
+ as_bad ("(SourceA) required");
+ return;
+ }
+ str = skip_space (str + 1);
+
+ if (*str == ',')
+ {
+ str = skip_space (str + 1);
+ ans = parse_gen_reg (&str, &r2);
+ if (ans < 0)
+ {
+ as_bad ("SourceB register required");
+ return;
+ }
+ }
+ else
+ {
+ as_bad ("SourceB register required");
+ return;
+ }
+
+ opcode |= (r1 << 16) | (r2 << 4) | ((indx & 0x1f) << 10);
+
+ if (indx != 0 && previous_mode == mode_cad)
+ {
+ /* We're in a delay slot.
+ If the base reg is the destination of the branch, then issue
+ an error message.
+ Otherwise it is safe to use the base and index. */
+ if (previous_dest != 0 && r1 == previous_dest)
+ {
+ as_bad ("base register not ready");
+ return;
+ }
+ }
+ else if (previous_dest != 0
+ && r1 == previous_dest
+ && (visium_arch == VISIUM_ARCH_MCM
+ || visium_arch == VISIUM_ARCH_MCM24
+ || (visium_arch == VISIUM_ARCH_DEF && indx != 0)))
+ {
+ as_warn ("base register not ready, NOP inserted.");
+ /* Insert a NOP before the write instruction. */
+ output = frag_more (4);
+ memset (output, 0, 4);
+ }
+ break;
+
+ case mode_dax:
+ /* register := register * 5-bit immediate
+ Examples:
+ read.b r1,(r2)
+ read.w r1,3(r2) */
+ ans = parse_gen_reg (&str, &r1);
+ if (ans < 0)
+ {
+ as_bad ("Dest register required");
+ return;
+ }
+ str = skip_space (str);
+ if (*str != ',')
+ {
+ as_bad ("SourceA required");
+ return;
+ }
+ str = skip_space (str + 1);
+
+ indx = 0;
+ if (*str != '(')
+ {
+ str = parse_exp (str, &e1);
+ if (e1.X_op == O_constant)
+ {
+ indx = e1.X_add_number;
+
+ if (indx < 0 || indx > 31)
+ {
+ as_bad ("Index out of range");
+ return;
+ }
+ }
+ else
+ {
+ as_bad ("Immediate 0 to 31 required");
+ return;
+ }
+ }
+ if (*str != '(')
+ {
+ as_bad ("(SourceA) required");
+ return;
+ }
+ str++;
+ ans = parse_gen_reg (&str, &r2);
+ if (ans < 0)
+ {
+ as_bad ("SourceA register required");
+ return;
+ }
+ str = skip_space (str);
+ if (*str != ')')
+ {
+ as_bad ("(SourceA) required");
+ return;
+ }
+ str++;
+ opcode |= (r1 << 10) | (r2 << 16) | ((indx & 0x1f) << 4);
+ this_dest = r1;
+
+ if (indx != 0 && previous_mode == mode_cad)
+ {
+ /* We're in a delay slot.
+ If the base reg is the destination of the branch, then issue
+ an error message.
+ Otherwise it is safe to use the base and index. */
+ if (previous_dest != 0 && r2 == previous_dest)
+ {
+ as_bad ("base register not ready");
+ return;
+ }
+ }
+ else if (previous_dest != 0
+ && r2 == previous_dest
+ && (visium_arch == VISIUM_ARCH_MCM
+ || visium_arch == VISIUM_ARCH_MCM24
+ || (visium_arch == VISIUM_ARCH_DEF && indx != 0)))
+ {
+ as_warn ("base register not ready, NOP inserted.");
+ /* Insert a NOP before the read instruction. */
+ output = frag_more (4);
+ memset (output, 0, 4);
+ }
+ break;
+
+ case mode_s:
+ /* special mode
+ Example:
+ nop */
+ str = skip_space (str);
+ break;
+
+ case mode_ci:
+ /* condition * 16-bit signed word displacement
+ Example:
+ brr L1 */
+ ans = parse_cc (&str, &cc);
+ if (ans < 0)
+ {
+ as_bad ("condition code required");
+ return;
+ }
+ opcode |= (cc << 27);
+
+ str = skip_space (str);
+ if (*str == ',')
+ {
+ str = skip_space (str + 1);
+ str = parse_exp (str, &e1);
+ if (e1.X_op != O_absent)
+ {
+ if (e1.X_op == O_constant)
+ {
+ int imm = e1.X_add_number;
+
+ if (imm < -32768 || imm > 32767)
+ as_bad ("immediate value out of range");
+
+ /* The GR6 doesn't correctly handle a 0 displacement
+ so we insert a NOP and change it to -1. */
+ if (imm == 0 && cc != 0 && visium_arch == VISIUM_ARCH_GR6)
+ {
+ output = frag_more (4);
+ memset (output, 0, 4);
+ imm = -1;
+ }
+
+ opcode |= (imm & 0xffff);
+ }
+ else if (e1.X_op == O_symbol)
+ {
+ /* The GR6 doesn't correctly handle a 0 displacement
+ so the instruction requires relaxation. */
+ if (cc != 0 && visium_arch == VISIUM_ARCH_GR6)
+ relax = amode;
+ else
+ reloc = BFD_RELOC_VISIUM_REL16;
+ }
+ else
+ {
+ as_bad ("immediate value missing");
+ return;
+ }
+ }
+ else
+ {
+ as_bad ("immediate value missing");
+ return;
+ }
+ }
+ else
+ {
+ as_bad ("immediate value missing");
+ return;
+ }
+
+ if (previous_mode == mode_cad || previous_mode == mode_ci)
+ as_bad ("branch instruction in delay slot");
+
+ condition_code = cc;
+ break;
+
+ case mode_fdab:
+ /* float := float * float
+ Example
+ fadd f4,f3,f2 */
+ ans = parse_fp_reg (&str, &r1);
+ if (ans < 0)
+ {
+ as_bad ("floating point destination register required");
+ return;
+ }
+ str = skip_space (str);
+ if (*str == ',')
+ {
+ str++;
+ ans = parse_fp_reg (&str, &r2);
+ if (ans < 0)
+ {
+ as_bad ("floating point SourceA register required");
+ return;
+ }
+ str = skip_space (str);
+ if (*str == ',')
+ {
+ str++;
+ ans = parse_fp_reg (&str, &r3);
+ if (ans < 0)
+ {
+ as_bad ("floating point SourceB register required");
+ return;
+ }
+
+ /* Got 3 floating regs, assemble instruction. */
+ opcode |= (r1 << 10) | (r2 << 16) | (r3 << 4);
+ }
+ else
+ {
+ as_bad ("floating point SourceB register required");
+ return;
+ }
+ }
+ else
+ {
+ as_bad ("floating point SourceA register required");
+ return;
+ }
+ break;
+
+ case mode_ifdab:
+ /* 4-bit immediate * float * float * float
+ Example
+ fpinst 10,f1,f2,f3 */
+ str = parse_exp (str, &e1);
+ str = skip_space (str);
+ if (e1.X_op != O_absent && *str == ',')
+ {
+ int finst = e1.X_add_number;
+
+ str = skip_space (str + 1);
+ ans = parse_fp_reg (&str, &r1);
+ if (ans < 0)
+ {
+ as_bad ("floating point destination register required");
+ return;
+ }
+ str = skip_space (str);
+ if (*str == ',')
+ {
+ str++;
+ ans = parse_fp_reg (&str, &r2);
+ if (ans < 0)
+ {
+ as_bad ("floating point SourceA register required");
+ return;
+ }
+ str = skip_space (str);
+ if (*str == ',')
+ {
+ str++;
+ ans = parse_fp_reg (&str, &r3);
+ if (ans < 0)
+ {
+ as_bad ("floating point SourceB register required");
+ return;
+ }
+
+ /* Got immediate and 3 floating regs,
+ assemble instruction. */
+ if (finst < 0 || finst > 15)
+ as_bad ("finst out of range");
+
+ opcode |=
+ ((finst & 0xf) << 27) | (r1 << 10) | (r2 << 16) | (r3 <<
+ 4);
+ }
+ else
+ {
+ as_bad ("floating point SourceB register required");
+ return;
+ }
+ }
+ else
+ {
+ as_bad ("floating point SourceA register required");
+ return;
+ }
+ }
+ else
+ {
+ as_bad ("finst missing");
+ return;
+ }
+ break;
+
+ case mode_idfab:
+ /* 4-bit immediate * register * float * float
+ Example
+ fpuread 4,r25,f2,f3 */
+ str = parse_exp (str, &e1);
+ str = skip_space (str);
+ if (e1.X_op != O_absent && *str == ',')
+ {
+ int finst = e1.X_add_number;
+
+ str = skip_space (str + 1);
+ ans = parse_gen_reg (&str, &r1);
+ if (ans < 0)
+ {
+ as_bad ("destination general register required");
+ return;
+ }
+ str = skip_space (str);
+ if (*str == ',')
+ {
+ str++;
+ ans = parse_fp_reg (&str, &r2);
+ if (ans < 0)
+ {
+ as_bad ("floating point SourceA register required");
+ return;
+ }
+ str = skip_space (str);
+ if (*str == ',')
+ {
+ str++;
+ ans = parse_fp_reg (&str, &r3);
+ if (ans < 0)
+ {
+ as_bad ("floating point SourceB register required");
+ return;
+ }
+
+ /* Got immediate and 3 floating regs,
+ assemble instruction. */
+ if (finst < 0 || finst > 15)
+ as_bad ("finst out of range");
+
+ opcode |=
+ ((finst & 0xf) << 27) | (r1 << 10) | (r2 << 16) | (r3 <<
+ 4);
+ }
+ else
+ {
+ as_bad ("floating point SourceB register required");
+ return;
+ }
+ }
+ else
+ {
+ as_bad ("floating point SourceA register required");
+ return;
+ }
+ }
+ else
+ {
+ as_bad ("finst missing");
+ return;
+ }
+ break;
+
+ case mode_fda:
+ /* float := float
+ Example
+ fsqrt f4,f3 */
+ ans = parse_fp_reg (&str, &r1);
+ if (ans < 0)
+ {
+ as_bad ("floating point destination register required");
+ return;
+ }
+ str = skip_space (str);
+ if (*str == ',')
+ {
+ str++;
+ ans = parse_fp_reg (&str, &r2);
+ if (ans < 0)
+ {
+ as_bad ("floating point source register required");
+ return;
+ }
+
+ /* Got 2 floating regs, assemble instruction. */
+ opcode |= (r1 << 10) | (r2 << 16);
+ }
+ else
+ {
+ as_bad ("floating point source register required");
+ return;
+ }
+ break;
+
+ case mode_fdra:
+ /* float := register
+ Example
+ fload f15,r6 */
+ ans = parse_fp_reg (&str, &r1);
+ if (ans < 0)
+ {
+ as_bad ("floating point destination register required");
+ return;
+ }
+ str = skip_space (str);
+ if (*str == ',')
+ {
+ str++;
+ ans = parse_gen_reg (&str, &r2);
+ if (ans < 0)
+ {
+ as_bad ("SourceA general register required");
+ return;
+ }
+
+ /* Got 2 regs, assemble instruction. */
+ opcode |= (r1 << 10) | (r2 << 16);
+ }
+ else
+ {
+ as_bad ("SourceA general register required");
+ return;
+ }
+ break;
+
+ case mode_rdfab:
+ /* register := float * float
+ Example
+ fcmp r0,f4,f8
+ For the GR6, register must be r0 and can be omitted. */
+ ans = parse_gen_reg (&str, &r1);
+ if (ans < 0)
+ {
+ if (visium_opcode_arch == VISIUM_OPCODE_ARCH_GR5)
+ {
+ as_bad ("Dest general register required");
+ return;
+ }
+ r1 = 0;
+ }
+ else
+ {
+ if (r1 != 0 && visium_opcode_arch != VISIUM_OPCODE_ARCH_GR5)
+ {
+ as_bad ("FCMP/FCMPE can only use r0 as Dest register");
+ return;
+ }
+
+ str = skip_space (str);
+ if (*str == ',')
+ str++;
+ else
+ {
+ as_bad ("floating point SourceA register required");
+ return;
+ }
+ }
+
+ ans = parse_fp_reg (&str, &r2);
+ if (ans < 0)
+ {
+ as_bad ("floating point SourceA register required");
+ return;
+ }
+ str = skip_space (str);
+ if (*str == ',')
+ {
+ str++;
+ ans = parse_fp_reg (&str, &r3);
+ if (ans < 0)
+ {
+ as_bad ("floating point SourceB register required");
+ return;
+ }
+
+ /* Got 3 regs, assemble instruction. */
+ opcode |= (r1 << 10) | (r2 << 16) | (r3 << 4);
+ }
+
+ this_dest = r1;
+ break;
+
+ case mode_rdfa:
+ /* register := float
+ Example
+ fstore r5,f12 */
+ ans = parse_gen_reg (&str, &r1);
+ if (ans < 0)
+ {
+ as_bad ("Dest general register required");
+ return;
+ }
+ str = skip_space (str);
+ if (*str == ',')
+ {
+ str++;
+ ans = parse_fp_reg (&str, &r2);
+ if (ans < 0)
+ {
+ as_bad ("floating point source register required");
+ return;
+ }
+
+ /* Got 2 regs, assemble instruction. */
+ opcode |= (r1 << 10) | (r2 << 16);
+ }
+ else
+ {
+ as_bad ("floating point source register required");
+ return;
+ }
+
+ this_dest = r1;
+ break;
+
+ case mode_rrr:
+ /* register register register, all sources and destinations
+ Example:
+ bmd r1,r2,r3 */
+
+ ans = parse_gen_reg (&str, &r1);
+ if (ans < 0)
+ {
+ as_bad ("destination address register required");
+ return;
+ }
+ str = skip_space (str);
+ if (*str == ',')
+ {
+ str++;
+ ans = parse_gen_reg (&str, &r2);
+ if (ans < 0)
+ {
+ as_bad ("source address register required");
+ return;
+ }
+ str = skip_space (str);
+ if (*str == ',')
+ {
+ str++;
+ ans = parse_gen_reg (&str, &r3);
+ if (ans < 0)
+ {
+ as_bad ("count register required");
+ return;
+ }
+
+ /* We insist on three registers but the opcode can only use
+ r1,r2,r3. */
+ if (r1 != 1 || r2 != 2 || r3 != 3)
+ {
+ as_bad ("BMI/BMD can only use format op r1,r2,r3");
+ return;
+ }
+
+ /* Opcode is unmodified by what comes out of the table. */
+ }
+ else
+ {
+ as_bad ("register required");
+ return;
+ }
+ }
+ else
+ {
+ as_bad ("register required");
+ return;
+ }
+
+ this_dest = r1;
+ break;
+
+ default:
+ break;
+ }
+
+ if (relax)
+ output = frag_var (rs_machine_dependent, 8, 4, relax, e1.X_add_symbol,
+ e1.X_add_number, NULL);
+ else
+ output = frag_more (4);
+
+ /* Build the 32-bit instruction in a host-endian-neutral fashion. */
+ output[0] = (opcode >> 24) & 0xff;
+ output[1] = (opcode >> 16) & 0xff;
+ output[2] = (opcode >> 8) & 0xff;
+ output[3] = (opcode >> 0) & 0xff;
+
+ if (relax)
+ /* The size of the instruction is unknown, so tie the debug info to the
+ start of the instruction. */
+ dwarf2_emit_insn (0);
+ else
+ {
+ if (reloc)
+ fix_new_exp (frag_now, output - frag_now->fr_literal, 4, &e1,
+ reloc == BFD_RELOC_VISIUM_REL16, reloc);
+ else
+ visium_update_parity_bit (output);
+
+ dwarf2_emit_insn (4);
+ }
+
+ if (*str != '\0')
+ as_bad ("junk after instruction");
+}
+
+void
+visium_cfi_frame_initial_instructions (void)
+{
+ /* The CFA is in SP on function entry. */
+ cfi_add_CFA_def_cfa (23, 0);
+}
+
+int
+visium_regname_to_dw2regnum (char *regname)
+{
+ if (!regname[0])
+ return -1;
+
+ if (regname[0] == 'f' && regname[1] == 'p' && !regname[2])
+ return 22;
+
+ if (regname[0] == 's' && regname[1] == 'p' && !regname[2])
+ return 23;
+
+ if (regname[0] == 'm' && regname[1] == 'd' && !regname[3])
+ switch (regname[2])
+ {
+ case 'b': return 32;
+ case 'a': return 33;
+ case 'c': return 34;
+ default : return -1;
+ }
+
+ if (regname[0] == 'f' || regname[0] == 'r')
+ {
+ char *p;
+ unsigned int regnum = strtoul (regname + 1, &p, 10);
+ if (*p)
+ return -1;
+ if (regnum >= (regname[0] == 'f' ? 16 : 32))
+ return -1;
+ if (regname[0] == 'f')
+ regnum += 35;
+ return regnum;
+ }
+
+ return -1;
+}
diff --git a/gas/config/tc-visium.h b/gas/config/tc-visium.h
new file mode 100644
index 0000000..6e1f791
--- /dev/null
+++ b/gas/config/tc-visium.h
@@ -0,0 +1,79 @@
+/* tc-visium.h -- Header file for tc-visium.c.
+
+ Copyright (C) 2005-2014 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 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#define TC_VISIUM
+
+#define LISTING_HEADER "VISIUM GAS "
+
+/* The target BFD architecture. */
+#define TARGET_ARCH bfd_arch_visium
+
+#define TARGET_BYTES_BIG_ENDIAN 1
+
+#define TARGET_FORMAT "elf32-visium"
+
+/* Permit temporary numeric labels. */
+#define LOCAL_LABELS_FB 1
+
+/* .-foo gets turned into PC relative relocs. */
+#define DIFF_EXPR_OK
+
+/* We don't support external symbols overriding. */
+#define EXTERN_FORCE_RELOC 0
+
+/* We don't need to handle .word strangely. */
+#define WORKING_DOT_WORD
+
+#define tc_fix_adjustable(FIXP) visium_fix_adjustable (FIXP)
+extern bfd_boolean visium_fix_adjustable (struct fix *);
+
+#define HANDLE_ALIGN(FRAGP) \
+ if ((FRAGP)->fr_type == rs_align_code) \
+ visium_handle_align (FRAGP);
+extern void visium_handle_align (struct frag *);
+
+#define md_relax_frag(segment, fragp, stretch) \
+ visium_relax_frag (segment, fragp, stretch)
+extern int visium_relax_frag (asection *, struct frag *, long);
+
+/* Call md_pcrel_from_section, not md_pcrel_from. */
+#define MD_PCREL_FROM_SECTION(FIXP, SEC) visium_pcrel_from_section (FIXP, SEC)
+extern long visium_pcrel_from_section (struct fix *, segT);
+
+/* Values passed to md_apply_fix3 don't include the symbol value. */
+#define MD_APPLY_SYM_VALUE(FIX) 0
+
+#define md_operand(x)
+
+#define tc_comment_chars visium_comment_chars
+extern const char *visium_comment_chars;
+
+#define TARGET_USE_CFIPOP 1
+
+#define tc_cfi_frame_initial_instructions visium_cfi_frame_initial_instructions
+extern void visium_cfi_frame_initial_instructions (void);
+
+#define tc_regname_to_dw2regnum visium_regname_to_dw2regnum
+extern int visium_regname_to_dw2regnum (char *regname);
+
+#define DWARF2_LINE_MIN_INSN_LENGTH 4
+#define DWARF2_DEFAULT_RETURN_COLUMN 21
+#define DWARF2_CIE_DATA_ALIGNMENT (-4)
diff --git a/gas/configure.tgt b/gas/configure.tgt
index d07d445..853988a 100644
--- a/gas/configure.tgt
+++ b/gas/configure.tgt
@@ -107,6 +107,7 @@ case ${cpu} in
tilegx*be) cpu_type=tilegx endian=big ;;
tilegx*) cpu_type=tilegx endian=little ;;
v850*) cpu_type=v850 ;;
+ visium) cpu_type=visium endian=big ;;
x86_64*) cpu_type=i386 arch=x86_64;;
xgate) cpu_type=xgate ;;
xtensa*) cpu_type=xtensa arch=xtensa ;;
@@ -453,6 +454,8 @@ case ${generic_target} in
vax-*-netbsdelf*) fmt=elf em=nbsd ;;
vax-*-linux-*) fmt=elf em=linux ;;
+ visium-*-elf) fmt=elf ;;
+
xstormy16-*-*) fmt=elf ;;
xgate-*-*) fmt=elf ;;
diff --git a/gas/doc/Makefile.am b/gas/doc/Makefile.am
index c2ddc02..2c179e4 100644
--- a/gas/doc/Makefile.am
+++ b/gas/doc/Makefile.am
@@ -91,8 +91,9 @@ CPU_DOCS = \
c-tic6x.texi \
c-tilegx.texi \
c-tilepro.texi \
- c-vax.texi \
c-v850.texi \
+ c-vax.texi \
+ c-visium.texi \
c-xgate.texi \
c-xstormy16.texi \
c-xtensa.texi \
diff --git a/gas/doc/Makefile.in b/gas/doc/Makefile.in
index 2db5121..4b5f4b7 100644
--- a/gas/doc/Makefile.in
+++ b/gas/doc/Makefile.in
@@ -333,8 +333,9 @@ CPU_DOCS = \
c-tic6x.texi \
c-tilegx.texi \
c-tilepro.texi \
- c-vax.texi \
c-v850.texi \
+ c-vax.texi \
+ c-visium.texi \
c-xgate.texi \
c-xstormy16.texi \
c-xtensa.texi \
diff --git a/gas/doc/all.texi b/gas/doc/all.texi
index 94b88bf..c578000 100644
--- a/gas/doc/all.texi
+++ b/gas/doc/all.texi
@@ -74,6 +74,7 @@
@set TILEPRO
@set V850
@set VAX
+@set VISIUM
@set XGATE
@set XSTORMY16
@set XTENSA
diff --git a/gas/doc/as.texinfo b/gas/doc/as.texinfo
index 243851b..17ae245 100644
--- a/gas/doc/as.texinfo
+++ b/gas/doc/as.texinfo
@@ -529,7 +529,6 @@ gcc(1), ld(1), and the Info entries for @file{binutils} and @file{ld}.
[@b{-mcpu=54[123589]}|@b{-mcpu=54[56]lp}] [@b{-mfar-mode}|@b{-mf}]
[@b{-merrors-to-file} @var{<filename>}|@b{-me} @var{<filename>}]
@end ifset
-
@ifset TIC6X
@emph{Target TIC6X options:}
@@ -545,7 +544,11 @@ gcc(1), ld(1), and the Info entries for @file{binutils} and @file{ld}.
@ifset TILEPRO
@c TILEPro has no machine-dependent assembler options
@end ifset
+@ifset VISIUM
+@emph{Target Visium options:}
+ [@b{-mtune=@var{arch}}]
+@end ifset
@ifset XTENSA
@emph{Target Xtensa options:}
@@ -555,7 +558,6 @@ gcc(1), ld(1), and the Info entries for @file{binutils} and @file{ld}.
[@b{--rename-section} @var{oldname}=@var{newname}]
[@b{--[no-]trampolines}]
@end ifset
-
@ifset Z80
@emph{Target Z80 options:}
@@ -567,8 +569,8 @@ gcc(1), ld(1), and the Info entries for @file{binutils} and @file{ld}.
[@b{ -forbid-undocumented-instructions}] [@b{-Fud}]
[@b{ -forbid-unportable-instructions}] [@b{-Fup}]
@end ifset
-
@ifset Z8000
+
@c Z8000 has no machine-dependent assembler options
@end ifset
@@ -1638,6 +1640,25 @@ processor.
@end ifset
+@ifset VISIUM
+
+@ifclear man
+@xref{Visium Options}, for the options available when @value{AS} is configured
+for a Visium processor.
+@end ifclear
+
+@ifset man
+@c man begin OPTIONS
+The following option is available when @value{AS} is configured for a Visium
+processor.
+@c man end
+@c man begin INCLUDE
+@include c-visium.texi
+@c ended inside the included file
+@end ifset
+
+@end ifset
+
@ifset XTENSA
@ifclear man
@@ -7268,6 +7289,12 @@ subject, see the hardware manufacturer's manual.
@ifset V850
* V850-Dependent:: V850 Dependent Features
@end ifset
+@ifset VAX
+* Vax-Dependent:: VAX Dependent Features
+@end ifset
+@ifset VISIUM
+* Visium-Dependent:: Visium Dependent Features
+@end ifset
@ifset XGATE
* XGATE-Dependent:: XGATE Features
@end ifset
@@ -7283,9 +7310,6 @@ subject, see the hardware manufacturer's manual.
@ifset Z8000
* Z8000-Dependent:: Z8000 Dependent Features
@end ifset
-@ifset VAX
-* Vax-Dependent:: VAX Dependent Features
-@end ifset
@end menu
@lowersections
@@ -7498,20 +7522,16 @@ family.
@include c-tilepro.texi
@end ifset
-@ifset Z80
-@include c-z80.texi
-@end ifset
-
-@ifset Z8000
-@include c-z8k.texi
+@ifset V850
+@include c-v850.texi
@end ifset
@ifset VAX
@include c-vax.texi
@end ifset
-@ifset V850
-@include c-v850.texi
+@ifset VISIUM
+@include c-visium.texi
@end ifset
@ifset XGATE
@@ -7526,6 +7546,14 @@ family.
@include c-xtensa.texi
@end ifset
+@ifset Z80
+@include c-z80.texi
+@end ifset
+
+@ifset Z8000
+@include c-z8k.texi
+@end ifset
+
@ifset GENERIC
@c reverse effect of @down at top of generic Machine-Dep chapter
@raisesections
diff --git a/gas/doc/c-visium.texi b/gas/doc/c-visium.texi
new file mode 100644
index 0000000..bc05a8e
--- /dev/null
+++ b/gas/doc/c-visium.texi
@@ -0,0 +1,90 @@
+@c Copyright (C) 2014 Free Software Foundation, Inc.
+@c This is part of the GAS manual.
+@c For copying conditions, see the file as.texinfo.
+@c man end
+
+@ifset GENERIC
+@page
+@node Visium-Dependent
+@chapter Visium Dependent Features
+@end ifset
+
+@ifclear GENERIC
+@node Machine Dependencies
+@chapter Visium Dependent Features
+@end ifclear
+
+@cindex Visium support
+@menu
+* Visium Options:: Options
+* Visium Syntax:: Syntax
+* Visium Opcodes:: Opcodes
+@end menu
+
+@node Visium Options
+@section Options
+@cindex Visium options
+@cindex options for Visium
+
+The Visium assembler implements one machine-specific option:
+
+@c man begin OPTIONS
+@table @gcctabopt
+@cindex @code{-mtune=@var{arch}} command line option, Visium
+@item -mtune=@var{arch}
+This option specifies the target architecture. If an attempt is made to
+assemble an instruction that will not execute on the target architecture,
+the assembler will issue an error message.
+
+The following names are recognized:
+@code{mcm24}
+@code{mcm}
+@code{gr5}
+@code{gr6}
+@end table
+@c man end
+
+@node Visium Syntax
+@section Syntax
+
+@menu
+* Visium Characters:: Special Characters
+* Visium Registers:: Register Names
+@end menu
+
+@node Visium Characters
+@subsection Special Characters
+
+@cindex line comment character, Visium
+@cindex Visium line comment character
+Line comments are introduced either by the @samp{!} character or by the
+@samp{;} character appearing anywhere on a line.
+
+A hash character (@samp{#}) as the first character on a line also
+marks the start of a line comment, but in this case it could also be a
+logical line number directive (@pxref{Comments}) or a preprocessor
+control command (@pxref{Preprocessing}).
+
+@cindex line separator, Visium
+@cindex statement separator, Visium
+@cindex Visium line separator
+The Visium assembler does not currently support a line separator character.
+
+@node Visium Registers
+@subsection Register Names
+@cindex Visium registers
+@cindex register names, Visium
+Registers can be specified either by using their canonical mnemonic names
+or by using their alias if they have one, for example @samp{sp}.
+
+@node Visium Opcodes
+@section Opcodes
+All the standard opcodes of the architecture are implemented, along with the
+following three pseudo-instructions: @code{cmp}, @code{cmpc}, @code{move}.
+
+In addition, the following two illegal opcodes are implemented and used by the simulation:
+
+@example
+stop 5-bit immediate, SourceA
+trace 5-bit immediate, SourceA
+@end example
diff --git a/gas/po/POTFILES.in b/gas/po/POTFILES.in
index d1fd07f..3514075 100644
--- a/gas/po/POTFILES.in
+++ b/gas/po/POTFILES.in
@@ -161,6 +161,8 @@ config/tc-v850.c
config/tc-v850.h
config/tc-vax.c
config/tc-vax.h
+config/tc-visium.c
+config/tc-visium.h
config/tc-xc16x.c
config/tc-xc16x.h
config/tc-xgate.c
diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog
index 5903720..63d58fe 100644
--- a/gas/testsuite/ChangeLog
+++ b/gas/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2014-12-06 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gas/elf/elf.exp: Skip ifunc-1 for Visium.
+ * gas/visium/: New directory.
+
2014-11-30 Alan Modra <amodra@gmail.com>
* gas/ppc/a2.d: Update for mftb change.
diff --git a/gas/testsuite/gas/elf/elf.exp b/gas/testsuite/gas/elf/elf.exp
index af5dbb2..291c2a7 100644
--- a/gas/testsuite/gas/elf/elf.exp
+++ b/gas/testsuite/gas/elf/elf.exp
@@ -172,11 +172,12 @@ if { [is_elf_format] } then {
run_dump_test "symver"
# No indirect functions on non-GNU targets.
- # The MSP port sets the ELF header's OSABI field to ELFOSABI_STANDALONE.
+ # The Visium and MSP set the ELF header's OSABI field to ELFOSABI_STANDALONE.
# The non-eabi ARM ports sets it to ELFOSABI_ARM.
# So for these targets we cannot include an IFUNC symbol type
# in the symbol type test.
if { [istarget "*-*-hpux*"]
+ || [istarget "visium-*-*"]
|| [istarget "msp*-*-*"]
|| [istarget "arm*-*-*"]} then {
# hppa64 has a non-standard common directive
diff --git a/gas/testsuite/gas/visium/allinsn_def.d b/gas/testsuite/gas/visium/allinsn_def.d
new file mode 100644
index 0000000..0a0170d
--- /dev/null
+++ b/gas/testsuite/gas/visium/allinsn_def.d
@@ -0,0 +1,134 @@
+#as:
+#objdump: -dzr
+#name: allinsn_def
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+0000000 <begin>:
+ 0: 03 e2 00 14 write.l 0\(r2\),r1
+ 4: 03 e2 00 14 write.l 0\(r2\),r1
+ 8: 83 e1 04 22 write.w 1\(r1\),r2
+ c: 03 e3 7c 71 write.b 31\(r3\),r7
+ 10: 03 e4 00 71 write.b 0\(r4\),r7
+ 14: 03 e4 80 54 mults r4,r5
+ 18: 83 e7 fc a4 eamwrite 31,r7,r10
+ 1c: 83 ee 90 f4 writemd r14,r15
+ 20: 83 e9 94 04 writemdc r9
+ 24: 03 e5 88 04 divs r5
+ 28: 83 e6 8c 04 divu r6
+ 2c: 83 ea 98 04 divds r10
+ 30: 83 eb 9c 04 divdu r11
+ 34: 83 ec a4 04 asrd r12
+ 38: 03 ed a8 04 lsrd r13
+ 3c: 83 ee ac 04 asld r14
+ 40: 82 80 00 04 dsi
+ 44: 83 e7 80 84 mults r7,r8
+ 48: 03 e9 84 a4 multu r9,r10
+ 4c: 02 a0 00 04 eni
+ 50: 82 80 00 04 dsi
+ 54: 82 fe 01 d4 rfi
+
+0+0000058 <nsrel>:
+ 58: 00 00 00 00 nop
+ 5c: 07 a0 00 04 rflag r0
+ 60: 08 00 ff fe brr eq,-2
+ 64: 07 a0 00 04 rflag r0
+ 68: 90 00 ff fc brr cs,-4
+ 6c: 07 a0 00 04 rflag r0
+ 70: 18 00 ff fa brr os,-6
+ 74: 07 a0 00 04 rflag r0
+ 78: 20 00 00 1c brr ns,\+28
+ 7c: 07 a0 00 04 rflag r0
+ 80: a8 00 00 1a brr ne,\+26
+ 84: 07 a0 00 04 rflag r0
+ 88: 30 00 00 18 brr cc,\+24
+ 8c: 07 a0 00 04 rflag r0
+ 90: 38 00 00 16 brr oc,\+22
+ 94: 07 a0 00 04 rflag r0
+ 98: c0 00 00 14 brr nc,\+20
+ 9c: 07 a0 00 04 rflag r0
+ a0: 48 00 00 12 brr ge,\+18
+ a4: 07 a0 00 04 rflag r0
+ a8: d0 00 00 10 brr gt,\+16
+ ac: 07 a0 00 04 rflag r0
+ b0: 58 00 00 0e brr hi,\+14
+ b4: 07 a0 00 04 rflag r0
+ b8: 60 00 00 0c brr le,\+12
+ bc: 07 a0 00 04 rflag r0
+ c0: e8 00 00 0a brr ls,\+10
+ c4: 07 a0 00 04 rflag r0
+ c8: 70 00 00 08 brr lt,\+8
+ cc: 07 a0 00 04 rflag r0
+ d0: 78 00 00 06 brr tr,\+6
+ d4: 07 a0 00 04 rflag r0
+ d8: 08 00 ff e0 brr eq,-32
+ dc: 00 00 00 00 nop
+ e0: 00 00 00 00 nop
+ e4: 00 00 00 00 nop
+
+0+00000e8 <sreg>:
+ e8: 86 20 00 14 adc.l r0,r0,r1
+ ec: 86 20 08 32 adc.w r2,r0,r3
+ f0: 86 20 10 51 adc.b r4,r0,r5
+ f4: 86 00 08 14 add.l r2,r0,r1
+ f8: 06 04 14 32 add.w r5,r4,r3
+ fc: 86 07 1c 61 add.b r7,r7,r6
+ 100: 87 40 08 14 and.l r2,r0,r1
+ 104: 07 44 14 32 and.w r5,r4,r3
+ 108: 87 47 1c 61 and.b r7,r7,r6
+ 10c: 06 e3 10 44 asl.l r4,r3,r4
+ 110: 86 e5 1a 02 asl.w r6,r5,0
+ 114: 06 e5 1a 12 asl.w r6,r5,1
+ 118: 06 e7 23 f1 asl.b r8,r7,31
+ 11c: 86 a3 10 44 asr.l r4,r3,r4
+ 120: 06 a5 1a 02 asr.w r6,r5,0
+ 124: 86 a5 1a 12 asr.w r6,r5,1
+ 128: 86 a7 23 f1 asr.b r8,r7,31
+ 12c: 0f 89 28 04 bra eq,r9,r10
+ 130: 07 a0 00 04 rflag r0
+ 134: af 87 04 04 bra ne,r7,r1
+ 138: 07 e0 ae 04 readmda r11
+ 13c: 07 e0 b3 f4 eamread r12,31
+ 140: 87 cd 30 04 extb.l r12,r13
+ 144: 87 cf 38 02 extb.w r14,r15
+ 148: 87 c1 00 01 extb.b r0,r1
+ 14c: 86 83 08 04 extw.l r2,r3
+ 150: 86 85 10 02 extw.w r4,r5
+ 154: 86 c7 18 84 lsr.l r6,r7,r8
+ 158: 06 ca 26 02 lsr.w r9,r10,0
+ 15c: 86 ca 26 12 lsr.w r9,r10,1
+ 160: 86 ca 27 f1 lsr.b r9,r10,31
+ 164: 87 6c 2c 04 not.l r11,r12
+ 168: 07 6e 34 02 not.w r13,r14
+ 16c: 07 6a 3c 01 not.b r15,r10
+ 170: 07 26 14 74 or.l r5,r6,r7
+ 174: 07 29 20 a2 or.w r8,r9,r10
+ 178: 87 22 04 31 or.b r1,r2,r3
+ 17c: 87 e5 12 04 read.l r4,0\(r5\)
+ 180: 87 e5 12 04 read.l r4,0\(r5\)
+ 184: 07 e7 1a 12 read.w r6,1\(r7\)
+ 188: 07 e9 23 f1 read.b r8,31\(r9\)
+ 18c: 87 e9 1a 11 read.b r6,1\(r9\)
+ 190: 87 e0 aa 04 readmda r10
+ 194: 87 e0 ae 14 readmdb r11
+ 198: 07 e0 c6 24 readmdc r17
+ 19c: 87 a0 10 04 rflag r4
+ 1a0: 87 a0 1c 04 rflag r7
+ 1a4: 86 45 10 64 sub.l r4,r5,r6
+ 1a8: 06 48 1c 92 sub.w r7,r8,r9
+ 1ac: 06 41 00 21 cmp.b r1,r2
+ 1b0: 06 65 10 64 subc.l r4,r5,r6
+ 1b4: 86 68 1c 92 subc.w r7,r8,r9
+ 1b8: 86 61 00 21 cmpc.b r1,r2
+ 1bc: 07 03 10 24 xor.l r4,r3,r2
+ 1c0: 87 06 14 72 xor.w r5,r6,r7
+ 1c4: 07 09 04 81 xor.b r1,r9,r8
+ 1c8: 04 07 ff ff addi r7,65535
+ 1cc: 04 87 80 00 movil r7,0x8000
+ 1d0: 84 a7 7f ff moviu r7,0x7FFF
+ 1d4: 04 c6 00 01 moviq r6,1
+ 1d8: 84 47 ff ff subi r7,65535
+ 1dc: ff 86 00 04 bra tr,r6,r0
+ 1e0: 86 00 00 04 add.l r0,r0,r0
diff --git a/gas/testsuite/gas/visium/allinsn_def.s b/gas/testsuite/gas/visium/allinsn_def.s
new file mode 100644
index 0000000..10e8b7f
--- /dev/null
+++ b/gas/testsuite/gas/visium/allinsn_def.s
@@ -0,0 +1,157 @@
+begin:
+ write.l (r2),r1
+ write.l 0(r2),r1
+ write.w 1(r1),r2
+ write.b 31(r3),r7
+ write.b (r4),r7
+
+ eamwrite 0,r4,r5
+ eamwrite 31,r7,r10
+
+ writemd r14,r15
+
+ writemdc r9
+
+ divs r5
+ divu r6
+ divds r10
+ divdu r11
+
+ asrd r12
+ lsrd r13
+ asld r14
+
+ dsi
+
+ mults r7,r8
+ multu r9,r10
+
+ eni
+ dsi
+ rfi
+
+
+nsrel:
+ brr fa,nsrel
+ rflag r0
+ brr eq,nsrel
+ rflag r0
+ brr cs,nsrel
+ rflag r0
+ brr os,nsrel
+ rflag r0
+ brr ns,sreg
+ rflag r0
+ brr ne,sreg
+ rflag r0
+ brr cc,sreg
+ rflag r0
+ brr oc,sreg
+ rflag r0
+ brr nc,sreg
+ rflag r0
+ brr ge,sreg
+ rflag r0
+ brr gt,sreg
+ rflag r0
+ brr hi,sreg
+ rflag r0
+ brr le,sreg
+ rflag r0
+ brr ls,sreg
+ rflag r0
+ brr lt,sreg
+ rflag r0
+ brr tr,sreg
+ rflag r0
+ brr eq,nsrel
+ nop
+ brr fa,.
+ nop
+
+
+sreg:
+ adc.l r0,r0,r1
+ adc.w r2,r0,r3
+ adc.b r4,r0,r5
+
+ add.l r2,r0,r1
+ add.w r5,r4,r3
+ add.b r7,r7,r6
+
+ and.l r2,r0,r1
+ and.w r5,r4,r3
+ and.b r7,r7,r6
+
+ asl.l r4,r3,r4
+ asl.w r6,r5,0
+ asl.w r6,r5,1
+ asl.b r8,r7,31
+
+ asr.l r4,r3,r4
+ asr.w r6,r5,0
+ asr.w r6,r5,1
+ asr.b r8,r7,31
+
+ bra eq,r9,r10
+ rflag r0
+ bra ne,r7,r1
+
+ eamread r11,0
+ eamread r12,31
+
+ extb.l r12,r13
+ extb.w r14,r15
+ extb.b r0,r1
+
+ extw.l r2,r3
+ extw.w r4,r5
+
+ lsr.l r6,r7,r8
+ lsr.w r9,r10,0
+ lsr.w r9,r10,1
+ lsr.b r9,r10,31
+
+ not.l r11,r12
+ not.w r13,r14
+ not.b r15,r10
+
+ or.l r5,r6,r7
+ or.w r8,r9,r10
+ or.b r1,r2,r3
+
+ read.l r4,(r5)
+ read.l r4,0(r5)
+ read.w r6,1(r7)
+ read.b r8,31(r9)
+ read.b r6,1(r9)
+
+ readmda r10
+ readmdb r11
+ readmdc r17
+
+ rflag r4
+ rflag r7
+
+ sub.l r4,r5,r6
+ sub.w r7,r8,r9
+ sub.b r0,r1,r2
+
+ subc.l r4,r5,r6
+ subc.w r7,r8,r9
+ subc.b r0,r1,r2
+
+ xor.l r4,r3,r2
+ xor.w r5,r6,r7
+ xor.b r1,r9,r8
+
+ addi r7,65535
+ movil r7,32768
+ moviu r7,32767
+ moviq r6,1
+ subi r7,65535
+
+ bra tr,r6,r0
+ add.l r0,r0,r0
+
+ .end
diff --git a/gas/testsuite/gas/visium/allinsn_gr5.d b/gas/testsuite/gas/visium/allinsn_gr5.d
new file mode 100644
index 0000000..49ba3ab
--- /dev/null
+++ b/gas/testsuite/gas/visium/allinsn_gr5.d
@@ -0,0 +1,153 @@
+#as: -mtune=gr5
+#objdump: -dzr
+#name: allinsn_gr5
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+0000000 <begin>:
+ 0: 03 e2 00 14 write.l 0\(r2\),r1
+ 4: 03 e2 00 14 write.l 0\(r2\),r1
+ 8: 83 e1 04 22 write.w 1\(r1\),r2
+ c: 03 e3 7c 71 write.b 31\(r3\),r7
+ 10: 03 e4 00 71 write.b 0\(r4\),r7
+ 14: 03 e4 80 54 mults r4,r5
+ 18: 83 e7 fc a4 eamwrite 31,r7,r10
+ 1c: 83 ee 90 f4 writemd r14,r15
+ 20: 83 e9 94 04 writemdc r9
+ 24: 03 e5 88 04 divs r5
+ 28: 83 e6 8c 04 divu r6
+ 2c: 83 ea 98 04 divds r10
+ 30: 83 eb 9c 04 divdu r11
+ 34: 83 ec a4 04 asrd r12
+ 38: 03 ed a8 04 lsrd r13
+ 3c: 83 ee ac 04 asld r14
+ 40: 82 80 00 04 dsi
+ 44: 83 e7 80 84 mults r7,r8
+ 48: 03 e9 84 a4 multu r9,r10
+ 4c: 02 a0 00 04 eni
+ 50: 82 80 00 04 dsi
+ 54: 82 fe 01 d4 rfi
+
+0+0000058 <nsrel>:
+ 58: 00 00 00 00 nop
+ 5c: 07 a0 00 04 rflag r0
+ 60: 08 00 ff fe brr eq,-2
+ 64: 07 a0 00 04 rflag r0
+ 68: 90 00 ff fc brr cs,-4
+ 6c: 07 a0 00 04 rflag r0
+ 70: 18 00 ff fa brr os,-6
+ 74: 07 a0 00 04 rflag r0
+ 78: 20 00 00 1c brr ns,\+28
+ 7c: 07 a0 00 04 rflag r0
+ 80: a8 00 00 1a brr ne,\+26
+ 84: 07 a0 00 04 rflag r0
+ 88: 30 00 00 18 brr cc,\+24
+ 8c: 07 a0 00 04 rflag r0
+ 90: 38 00 00 16 brr oc,\+22
+ 94: 07 a0 00 04 rflag r0
+ 98: c0 00 00 14 brr nc,\+20
+ 9c: 07 a0 00 04 rflag r0
+ a0: 48 00 00 12 brr ge,\+18
+ a4: 07 a0 00 04 rflag r0
+ a8: d0 00 00 10 brr gt,\+16
+ ac: 07 a0 00 04 rflag r0
+ b0: 58 00 00 0e brr hi,\+14
+ b4: 07 a0 00 04 rflag r0
+ b8: 60 00 00 0c brr le,\+12
+ bc: 07 a0 00 04 rflag r0
+ c0: e8 00 00 0a brr ls,\+10
+ c4: 07 a0 00 04 rflag r0
+ c8: 70 00 00 08 brr lt,\+8
+ cc: 07 a0 00 04 rflag r0
+ d0: 78 00 00 06 brr tr,\+6
+ d4: 07 a0 00 04 rflag r0
+ d8: 08 00 ff e0 brr eq,-32
+ dc: 00 00 00 00 nop
+ e0: 00 00 00 00 nop
+ e4: 00 00 00 00 nop
+
+0+00000e8 <sreg>:
+ e8: 86 20 00 14 adc.l r0,r0,r1
+ ec: 86 20 08 32 adc.w r2,r0,r3
+ f0: 86 20 10 51 adc.b r4,r0,r5
+ f4: 86 00 08 14 add.l r2,r0,r1
+ f8: 06 04 14 32 add.w r5,r4,r3
+ fc: 86 07 1c 61 add.b r7,r7,r6
+ 100: 87 40 08 14 and.l r2,r0,r1
+ 104: 07 44 14 32 and.w r5,r4,r3
+ 108: 87 47 1c 61 and.b r7,r7,r6
+ 10c: 06 e3 10 44 asl.l r4,r3,r4
+ 110: 86 e5 1a 02 asl.w r6,r5,0
+ 114: 06 e5 1a 12 asl.w r6,r5,1
+ 118: 06 e7 23 f1 asl.b r8,r7,31
+ 11c: 86 a3 10 44 asr.l r4,r3,r4
+ 120: 06 a5 1a 02 asr.w r6,r5,0
+ 124: 86 a5 1a 12 asr.w r6,r5,1
+ 128: 86 a7 23 f1 asr.b r8,r7,31
+ 12c: 0f 89 28 04 bra eq,r9,r10
+ 130: 07 a0 00 04 rflag r0
+ 134: af 87 04 04 bra ne,r7,r1
+ 138: 07 e0 ae 04 readmda r11
+ 13c: 07 e0 b3 f4 eamread r12,31
+ 140: 87 cd 30 04 extb.l r12,r13
+ 144: 87 cf 38 02 extb.w r14,r15
+ 148: 87 c1 00 01 extb.b r0,r1
+ 14c: 86 83 08 04 extw.l r2,r3
+ 150: 86 85 10 02 extw.w r4,r5
+ 154: 86 c7 18 84 lsr.l r6,r7,r8
+ 158: 06 ca 26 02 lsr.w r9,r10,0
+ 15c: 86 ca 26 12 lsr.w r9,r10,1
+ 160: 86 ca 27 f1 lsr.b r9,r10,31
+ 164: 87 6c 2c 04 not.l r11,r12
+ 168: 07 6e 34 02 not.w r13,r14
+ 16c: 07 6a 3c 01 not.b r15,r10
+ 170: 07 26 14 74 or.l r5,r6,r7
+ 174: 07 29 20 a2 or.w r8,r9,r10
+ 178: 87 22 04 31 or.b r1,r2,r3
+ 17c: 87 e5 12 04 read.l r4,0\(r5\)
+ 180: 87 e5 12 04 read.l r4,0\(r5\)
+ 184: 07 e7 1a 12 read.w r6,1\(r7\)
+ 188: 07 e9 23 f1 read.b r8,31\(r9\)
+ 18c: 87 e9 1a 11 read.b r6,1\(r9\)
+ 190: 87 e0 aa 04 readmda r10
+ 194: 87 e0 ae 14 readmdb r11
+ 198: 07 e0 c6 24 readmdc r17
+ 19c: 87 a0 10 04 rflag r4
+ 1a0: 87 a0 1c 04 rflag r7
+ 1a4: 86 45 10 64 sub.l r4,r5,r6
+ 1a8: 06 48 1c 92 sub.w r7,r8,r9
+ 1ac: 06 41 00 21 cmp.b r1,r2
+ 1b0: 06 65 10 64 subc.l r4,r5,r6
+ 1b4: 86 68 1c 92 subc.w r7,r8,r9
+ 1b8: 86 61 00 21 cmpc.b r1,r2
+ 1bc: 07 03 10 24 xor.l r4,r3,r2
+ 1c0: 87 06 14 72 xor.w r5,r6,r7
+ 1c4: 07 09 04 81 xor.b r1,r9,r8
+ 1c8: 04 07 ff ff addi r7,65535
+ 1cc: 04 87 80 00 movil r7,0x8000
+ 1d0: 84 a7 7f ff moviu r7,0x7FFF
+ 1d4: 04 c6 00 01 moviq r6,1
+ 1d8: 84 47 ff ff subi r7,65535
+ 1dc: ff 86 00 04 bra tr,r6,r0
+ 1e0: 86 00 00 04 add.l r0,r0,r0
+ 1e4: d3 e3 84 5c fpinst 10,f1,f3,f5
+ 1e8: db e4 88 6c fpinst 11,f2,f4,f6
+ 1ec: 7b ed ac fc fpinst 15,f11,f13,f15
+ 1f0: 8f ef e6 ec fpuread 1,r25,f15,f14
+ 1f4: 3b e3 9c 0c fabs f7,f3
+ 1f8: 0b e6 b0 ec fadd f12,f6,f14
+ 1fc: 8b e6 b0 0c fadd f12,f6,f0
+ 200: 63 e6 b0 0c fmove f12,f6
+ 204: b3 e3 9c 0c fneg f7,f3
+ 208: 93 e0 8c 9c fsub f3,f0,f9
+ 20c: 1b e2 84 3c fmult f1,f2,f3
+ 210: 23 eb a8 cc fdiv f10,f11,f12
+ 214: 2b e9 8c 0c fsqrt f3,f9
+ 218: 43 e4 94 0c ftoi f5,f4
+ 21c: 4b e8 9c 0c itof f7,f8
+ 220: 03 ff b4 0c fload f13,r31
+ 224: 07 e7 e6 0c fstore r25,f7
+ 228: d7 ef 8a 0c fcmp r2,f15,f0
+ 22c: df ef 86 1c fcmpe r1,f15,f1
diff --git a/gas/testsuite/gas/visium/allinsn_gr5.s b/gas/testsuite/gas/visium/allinsn_gr5.s
new file mode 100644
index 0000000..f4a9b30
--- /dev/null
+++ b/gas/testsuite/gas/visium/allinsn_gr5.s
@@ -0,0 +1,179 @@
+begin:
+ write.l (r2),r1
+ write.l 0(r2),r1
+ write.w 1(r1),r2
+ write.b 31(r3),r7
+ write.b (r4),r7
+
+ eamwrite 0,r4,r5
+ eamwrite 31,r7,r10
+
+ writemd r14,r15
+
+ writemdc r9
+
+ divs r5
+ divu r6
+ divds r10
+ divdu r11
+
+ asrd r12
+ lsrd r13
+ asld r14
+
+ dsi
+
+ mults r7,r8
+ multu r9,r10
+
+ eni
+ dsi
+ rfi
+
+
+nsrel:
+ brr fa,nsrel
+ rflag r0
+ brr eq,nsrel
+ rflag r0
+ brr cs,nsrel
+ rflag r0
+ brr os,nsrel
+ rflag r0
+ brr ns,sreg
+ rflag r0
+ brr ne,sreg
+ rflag r0
+ brr cc,sreg
+ rflag r0
+ brr oc,sreg
+ rflag r0
+ brr nc,sreg
+ rflag r0
+ brr ge,sreg
+ rflag r0
+ brr gt,sreg
+ rflag r0
+ brr hi,sreg
+ rflag r0
+ brr le,sreg
+ rflag r0
+ brr ls,sreg
+ rflag r0
+ brr lt,sreg
+ rflag r0
+ brr tr,sreg
+ rflag r0
+ brr eq,nsrel
+ nop
+ brr fa,.
+ nop
+
+
+sreg:
+ adc.l r0,r0,r1
+ adc.w r2,r0,r3
+ adc.b r4,r0,r5
+
+ add.l r2,r0,r1
+ add.w r5,r4,r3
+ add.b r7,r7,r6
+
+ and.l r2,r0,r1
+ and.w r5,r4,r3
+ and.b r7,r7,r6
+
+ asl.l r4,r3,r4
+ asl.w r6,r5,0
+ asl.w r6,r5,1
+ asl.b r8,r7,31
+
+ asr.l r4,r3,r4
+ asr.w r6,r5,0
+ asr.w r6,r5,1
+ asr.b r8,r7,31
+
+ bra eq,r9,r10
+ rflag r0
+ bra ne,r7,r1
+
+ eamread r11,0
+ eamread r12,31
+
+ extb.l r12,r13
+ extb.w r14,r15
+ extb.b r0,r1
+
+ extw.l r2,r3
+ extw.w r4,r5
+
+ lsr.l r6,r7,r8
+ lsr.w r9,r10,0
+ lsr.w r9,r10,1
+ lsr.b r9,r10,31
+
+ not.l r11,r12
+ not.w r13,r14
+ not.b r15,r10
+
+ or.l r5,r6,r7
+ or.w r8,r9,r10
+ or.b r1,r2,r3
+
+ read.l r4,(r5)
+ read.l r4,0(r5)
+ read.w r6,1(r7)
+ read.b r8,31(r9)
+ read.b r6,1(r9)
+
+
+ readmda r10
+ readmdb r11
+ readmdc r17
+
+ rflag r4
+ rflag r7
+
+ sub.l r4,r5,r6
+ sub.w r7,r8,r9
+ sub.b r0,r1,r2
+
+ subc.l r4,r5,r6
+ subc.w r7,r8,r9
+ subc.b r0,r1,r2
+
+ xor.l r4,r3,r2
+ xor.w r5,r6,r7
+ xor.b r1,r9,r8
+
+ addi r7,65535
+ movil r7,32768
+ moviu r7,32767
+ moviq r6,1
+ subi r7,65535
+
+ bra tr,r6,r0
+ add.l r0,r0,r0
+
+
+ fpinst 10,f1,f3,f5
+ fpinst 11,f2,f4,f6
+ fpinst 15,f11,f13,f15
+ fpuread 1,r25,f15,f14
+ fabs f7,f3
+ fadd f12,f6,f14
+ fadd f12,f6,f0
+ fmove f12,f6
+ fneg f7,f3
+ fsub f3,f0,f9
+ fmult f1,f2,f3
+ fdiv f10,f11,f12
+ fsqrt f3,f9
+ ftoi f5,f4
+ itof f7,f8
+ fload f13,r31
+ fstore r25,f7
+ fcmp r2,f15,f0
+ fcmpe r1,f15,f1
+
+ .end
diff --git a/gas/testsuite/gas/visium/allinsn_gr6.d b/gas/testsuite/gas/visium/allinsn_gr6.d
new file mode 100644
index 0000000..bb198ec
--- /dev/null
+++ b/gas/testsuite/gas/visium/allinsn_gr6.d
@@ -0,0 +1,159 @@
+#as: -mtune=gr6
+#objdump: -dzr
+#name: allinsn_gr6
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+0000000 <begin>:
+ 0: 03 e2 00 14 write.l 0\(r2\),r1
+ 4: 03 e2 00 14 write.l 0\(r2\),r1
+ 8: 83 e1 04 22 write.w 1\(r1\),r2
+ c: 03 e3 7c 71 write.b 31\(r3\),r7
+ 10: 03 e4 00 71 write.b 0\(r4\),r7
+ 14: 03 e4 80 54 mults r4,r5
+ 18: 83 e7 fc a4 eamwrite 31,r7,r10
+ 1c: 83 ee 90 f4 writemd r14,r15
+ 20: 83 e9 94 04 writemdc r9
+ 24: 03 e5 88 04 divs r5
+ 28: 83 e6 8c 04 divu r6
+ 2c: 83 ea 98 04 divds r10
+ 30: 83 eb 9c 04 divdu r11
+ 34: 83 ec a4 04 asrd r12
+ 38: 03 ed a8 04 lsrd r13
+ 3c: 83 ee ac 04 asld r14
+ 40: 82 80 00 04 dsi
+ 44: 83 e7 80 84 mults r7,r8
+ 48: 03 e9 84 a4 multu r9,r10
+ 4c: 02 a0 00 04 eni
+ 50: 82 80 00 04 dsi
+ 54: 82 fe 01 d4 rfi
+
+0+0000058 <nsrel>:
+ 58: 00 00 00 00 nop
+ 5c: 07 a0 00 04 rflag r0
+ 60: 08 00 ff fe brr eq,-2
+ 64: 07 a0 00 04 rflag r0
+ 68: 90 00 ff fc brr cs,-4
+ 6c: 07 a0 00 04 rflag r0
+ 70: 18 00 ff fa brr os,-6
+ 74: 07 a0 00 04 rflag r0
+ 78: 20 00 00 1c brr ns,\+28
+ 7c: 07 a0 00 04 rflag r0
+ 80: a8 00 00 1a brr ne,\+26
+ 84: 07 a0 00 04 rflag r0
+ 88: 30 00 00 18 brr cc,\+24
+ 8c: 07 a0 00 04 rflag r0
+ 90: 38 00 00 16 brr oc,\+22
+ 94: 07 a0 00 04 rflag r0
+ 98: c0 00 00 14 brr nc,\+20
+ 9c: 07 a0 00 04 rflag r0
+ a0: 48 00 00 12 brr ge,\+18
+ a4: 07 a0 00 04 rflag r0
+ a8: d0 00 00 10 brr gt,\+16
+ ac: 07 a0 00 04 rflag r0
+ b0: 58 00 00 0e brr hi,\+14
+ b4: 07 a0 00 04 rflag r0
+ b8: 60 00 00 0c brr le,\+12
+ bc: 07 a0 00 04 rflag r0
+ c0: e8 00 00 0a brr ls,\+10
+ c4: 07 a0 00 04 rflag r0
+ c8: 70 00 00 08 brr lt,\+8
+ cc: 07 a0 00 04 rflag r0
+ d0: 78 00 00 06 brr tr,\+6
+ d4: 07 a0 00 04 rflag r0
+ d8: 08 00 ff e0 brr eq,-32
+ dc: 00 00 00 00 nop
+ e0: 00 00 00 00 nop
+ e4: 00 00 00 00 nop
+
+0+00000e8 <sreg>:
+ e8: 86 20 00 14 adc.l r0,r0,r1
+ ec: 86 20 08 32 adc.w r2,r0,r3
+ f0: 86 20 10 51 adc.b r4,r0,r5
+ f4: 86 00 08 14 add.l r2,r0,r1
+ f8: 06 04 14 32 add.w r5,r4,r3
+ fc: 86 07 1c 61 add.b r7,r7,r6
+ 100: 87 40 08 14 and.l r2,r0,r1
+ 104: 07 44 14 32 and.w r5,r4,r3
+ 108: 87 47 1c 61 and.b r7,r7,r6
+ 10c: 06 e3 10 44 asl.l r4,r3,r4
+ 110: 86 e5 1a 02 asl.w r6,r5,0
+ 114: 06 e5 1a 12 asl.w r6,r5,1
+ 118: 06 e7 23 f1 asl.b r8,r7,31
+ 11c: 86 a3 10 44 asr.l r4,r3,r4
+ 120: 06 a5 1a 02 asr.w r6,r5,0
+ 124: 86 a5 1a 12 asr.w r6,r5,1
+ 128: 86 a7 23 f1 asr.b r8,r7,31
+ 12c: 0f 89 28 04 bra eq,r9,r10
+ 130: 07 a0 00 04 rflag r0
+ 134: af 87 04 04 bra ne,r7,r1
+ 138: 07 e0 ae 04 readmda r11
+ 13c: 07 e0 b3 f4 eamread r12,31
+ 140: 87 cd 30 04 extb.l r12,r13
+ 144: 87 cf 38 02 extb.w r14,r15
+ 148: 87 c1 00 01 extb.b r0,r1
+ 14c: 86 83 08 04 extw.l r2,r3
+ 150: 86 85 10 02 extw.w r4,r5
+ 154: 86 c7 18 84 lsr.l r6,r7,r8
+ 158: 06 ca 26 02 lsr.w r9,r10,0
+ 15c: 86 ca 26 12 lsr.w r9,r10,1
+ 160: 86 ca 27 f1 lsr.b r9,r10,31
+ 164: 87 6c 2c 04 not.l r11,r12
+ 168: 07 6e 34 02 not.w r13,r14
+ 16c: 07 6a 3c 01 not.b r15,r10
+ 170: 07 26 14 74 or.l r5,r6,r7
+ 174: 07 29 20 a2 or.w r8,r9,r10
+ 178: 87 22 04 31 or.b r1,r2,r3
+ 17c: 87 e5 12 04 read.l r4,0\(r5\)
+ 180: 87 e5 12 04 read.l r4,0\(r5\)
+ 184: 07 e7 1a 12 read.w r6,1\(r7\)
+ 188: 07 e9 23 f1 read.b r8,31\(r9\)
+ 18c: 87 e9 1a 11 read.b r6,1\(r9\)
+ 190: 87 e0 aa 04 readmda r10
+ 194: 87 e0 ae 14 readmdb r11
+ 198: 07 e0 c6 24 readmdc r17
+ 19c: 87 a0 10 04 rflag r4
+ 1a0: 87 a0 1c 04 rflag r7
+ 1a4: 86 45 10 64 sub.l r4,r5,r6
+ 1a8: 06 48 1c 92 sub.w r7,r8,r9
+ 1ac: 06 41 00 21 cmp.b r1,r2
+ 1b0: 06 65 10 64 subc.l r4,r5,r6
+ 1b4: 86 68 1c 92 subc.w r7,r8,r9
+ 1b8: 86 61 00 21 cmpc.b r1,r2
+ 1bc: 07 03 10 24 xor.l r4,r3,r2
+ 1c0: 87 06 14 72 xor.w r5,r6,r7
+ 1c4: 07 09 04 81 xor.b r1,r9,r8
+ 1c8: 04 07 ff ff addi r7,65535
+ 1cc: 04 87 80 00 movil r7,0x8000
+ 1d0: 84 a7 7f ff moviu r7,0x7FFF
+ 1d4: 04 c6 00 01 moviq r6,1
+ 1d8: 84 47 ff ff subi r7,65535
+ 1dc: ff 86 00 04 bra tr,r6,r0
+ 1e0: 86 00 00 04 add.l r0,r0,r0
+ 1e4: d3 e3 84 5c fpinst 10,f1,f3,f5
+ 1e8: db e4 88 6c fpinst 11,f2,f4,f6
+ 1ec: 7b ed ac fc fpinst 15,f11,f13,f15
+ 1f0: 8f ef e6 ec fpuread 1,r25,f15,f14
+ 1f4: 3b e3 9c 0c fabs f7,f3
+ 1f8: 0b e6 b0 ec fadd f12,f6,f14
+ 1fc: 8b e6 b0 0c fadd f12,f6,f0
+ 200: 63 e6 b0 0c fmove f12,f6
+ 204: b3 e3 9c 0c fneg f7,f3
+ 208: 93 e0 8c 9c fsub f3,f0,f9
+ 20c: 1b e2 84 3c fmult f1,f2,f3
+ 210: 23 eb a8 cc fdiv f10,f11,f12
+ 214: 2b e9 8c 0c fsqrt f3,f9
+ 218: 43 e4 94 0c ftoi f5,f4
+ 21c: 4b e8 9c 0c itof f7,f8
+ 220: 03 ff b4 0c fload f13,r31
+ 224: 07 e7 e6 0c fstore r25,f7
+ 228: 57 ef 82 0c fcmp r0,f15,f0
+ 22c: 5f ef 82 1c fcmpe r0,f15,f1
+ 230: 57 ef 82 0c fcmp r0,f15,f0
+ 234: 5f ef 82 1c fcmpe r0,f15,f1
+ 238: 02 63 00 04 bmd r1,r2,r3
+ 23c: 82 23 00 04 bmi r1,r2,r3
+ 240: 85 00 80 00 wrtl 0x8000
+ 244: 05 20 7f ff wrtu 0x7FFF
diff --git a/gas/testsuite/gas/visium/allinsn_gr6.s b/gas/testsuite/gas/visium/allinsn_gr6.s
new file mode 100644
index 0000000..32953fb
--- /dev/null
+++ b/gas/testsuite/gas/visium/allinsn_gr6.s
@@ -0,0 +1,185 @@
+begin:
+ write.l (r2),r1
+ write.l 0(r2),r1
+ write.w 1(r1),r2
+ write.b 31(r3),r7
+ write.b (r4),r7
+
+ eamwrite 0,r4,r5
+ eamwrite 31,r7,r10
+
+ writemd r14,r15
+
+ writemdc r9
+
+ divs r5
+ divu r6
+ divds r10
+ divdu r11
+
+ asrd r12
+ lsrd r13
+ asld r14
+
+ dsi
+
+ mults r7,r8
+ multu r9,r10
+
+ eni
+ dsi
+ rfi
+
+
+nsrel:
+ brr fa,nsrel
+ rflag r0
+ brr eq,nsrel
+ rflag r0
+ brr cs,nsrel
+ rflag r0
+ brr os,nsrel
+ rflag r0
+ brr ns,sreg
+ rflag r0
+ brr ne,sreg
+ rflag r0
+ brr cc,sreg
+ rflag r0
+ brr oc,sreg
+ rflag r0
+ brr nc,sreg
+ rflag r0
+ brr ge,sreg
+ rflag r0
+ brr gt,sreg
+ rflag r0
+ brr hi,sreg
+ rflag r0
+ brr le,sreg
+ rflag r0
+ brr ls,sreg
+ rflag r0
+ brr lt,sreg
+ rflag r0
+ brr tr,sreg
+ rflag r0
+ brr eq,nsrel
+ nop
+ brr fa,.
+ nop
+
+
+sreg:
+ adc.l r0,r0,r1
+ adc.w r2,r0,r3
+ adc.b r4,r0,r5
+
+ add.l r2,r0,r1
+ add.w r5,r4,r3
+ add.b r7,r7,r6
+
+ and.l r2,r0,r1
+ and.w r5,r4,r3
+ and.b r7,r7,r6
+
+ asl.l r4,r3,r4
+ asl.w r6,r5,0
+ asl.w r6,r5,1
+ asl.b r8,r7,31
+
+ asr.l r4,r3,r4
+ asr.w r6,r5,0
+ asr.w r6,r5,1
+ asr.b r8,r7,31
+
+ bra eq,r9,r10
+ rflag r0
+ bra ne,r7,r1
+
+ eamread r11,0
+ eamread r12,31
+
+ extb.l r12,r13
+ extb.w r14,r15
+ extb.b r0,r1
+
+ extw.l r2,r3
+ extw.w r4,r5
+
+ lsr.l r6,r7,r8
+ lsr.w r9,r10,0
+ lsr.w r9,r10,1
+ lsr.b r9,r10,31
+
+ not.l r11,r12
+ not.w r13,r14
+ not.b r15,r10
+
+ or.l r5,r6,r7
+ or.w r8,r9,r10
+ or.b r1,r2,r3
+
+ read.l r4,(r5)
+ read.l r4,0(r5)
+ read.w r6,1(r7)
+ read.b r8,31(r9)
+ read.b r6,1(r9)
+
+ readmda r10
+ readmdb r11
+ readmdc r17
+
+ rflag r4
+ rflag r7
+
+ sub.l r4,r5,r6
+ sub.w r7,r8,r9
+ sub.b r0,r1,r2
+
+ subc.l r4,r5,r6
+ subc.w r7,r8,r9
+ subc.b r0,r1,r2
+
+ xor.l r4,r3,r2
+ xor.w r5,r6,r7
+ xor.b r1,r9,r8
+
+ addi r7,65535
+ movil r7,32768
+ moviu r7,32767
+ moviq r6,1
+ subi r7,65535
+
+ bra tr,r6,r0
+ add.l r0,r0,r0
+
+
+ fpinst 10,f1,f3,f5
+ fpinst 11,f2,f4,f6
+ fpinst 15,f11,f13,f15
+ fpuread 1,r25,f15,f14
+ fabs f7,f3
+ fadd f12,f6,f14
+ fadd f12,f6,f0
+ fmove f12,f6
+ fneg f7,f3
+ fsub f3,f0,f9
+ fmult f1,f2,f3
+ fdiv f10,f11,f12
+ fsqrt f3,f9
+ ftoi f5,f4
+ itof f7,f8
+ fload f13,r31
+ fstore r25,f7
+ fcmp r0,f15,f0
+ fcmpe r0,f15,f1
+ fcmp f15,f0
+ fcmpe f15,f1
+
+ bmd r1,r2,r3
+ bmi r1,r2,r3
+
+ wrtl 32768
+ wrtu 32767
+ .end
diff --git a/gas/testsuite/gas/visium/basereg.s b/gas/testsuite/gas/visium/basereg.s
new file mode 100644
index 0000000..a875671
--- /dev/null
+++ b/gas/testsuite/gas/visium/basereg.s
@@ -0,0 +1,20 @@
+; Test error messages where targets are out of range.
+
+; { dg-do assemble }
+; { dg-options "-mtune=mcm" }
+
+ .text
+foo:
+ fstore r4,f15
+ read.b r6,1(r4) ; { dg-error "base register not ready" "r4 not ready" }
+ readmdc r5
+ read.w r7,31(r5) ; { dg-error "base register not ready" "r5 not ready" }
+ fcmp r6,f4,f5
+ read.l r8,13(r6) ; { dg-error "base register not ready" "r6 not ready" }
+ move.b r7,r0
+ write.b 2(r7),r0 ; { dg-error "base register not ready" "r7 not ready" }
+ move.w r8,r0
+ write.w 2(r8),r0 ; { dg-error "base register not ready" "r8 not ready" }
+ move.l r9,r0
+ write.b 2(r9),r0 ; { dg-error "base register not ready" "r9 not ready" }
+ .end
diff --git a/gas/testsuite/gas/visium/brr-1.d b/gas/testsuite/gas/visium/brr-1.d
new file mode 100644
index 0000000..28b5f4b
--- /dev/null
+++ b/gas/testsuite/gas/visium/brr-1.d
@@ -0,0 +1,16 @@
+#as:
+#objdump: -d
+#name: brr-1
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+00000000 <foo>:
+ 0: 78 00 00 00 brr tr,\+0
+ 4: 84 c1 00 01 moviq r1,1
+ 8: 78 00 00 00 brr tr,\+0
+ c: 84 c1 00 02 moviq r1,2
+ 10: 78 00 ff fc brr tr,-4
+ 14: 84 c1 00 04 moviq r1,4
+ 18: 00 00 00 00 nop
diff --git a/gas/testsuite/gas/visium/brr-1.s b/gas/testsuite/gas/visium/brr-1.s
new file mode 100644
index 0000000..34d5490
--- /dev/null
+++ b/gas/testsuite/gas/visium/brr-1.s
@@ -0,0 +1,9 @@
+ .text
+foo:
+ brr tr,foo
+ moviq r1,1
+ brr tr,0
+ moviq r1,2
+ brr tr,foo
+ moviq r1,4
+ brr fa,.
diff --git a/gas/testsuite/gas/visium/brr-2.d b/gas/testsuite/gas/visium/brr-2.d
new file mode 100644
index 0000000..48d9ef5
--- /dev/null
+++ b/gas/testsuite/gas/visium/brr-2.d
@@ -0,0 +1,18 @@
+#as: -mtune=gr6
+#objdump: -d
+#name: brr-2
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+00000000 <foo>:
+ 0: 00 00 00 00 nop
+ 4: 78 00 ff ff brr tr,-1
+ 8: 84 c1 00 01 moviq r1,1
+ c: 00 00 00 00 nop
+ 10: 78 00 ff ff brr tr,-1
+ 14: 84 c1 00 02 moviq r1,2
+ 18: 78 00 ff fa brr tr,-6
+ 1c: 84 c1 00 04 moviq r1,4
+ 20: 00 00 00 00 nop
diff --git a/gas/testsuite/gas/visium/brr-2.s b/gas/testsuite/gas/visium/brr-2.s
new file mode 100644
index 0000000..34d5490
--- /dev/null
+++ b/gas/testsuite/gas/visium/brr-2.s
@@ -0,0 +1,9 @@
+ .text
+foo:
+ brr tr,foo
+ moviq r1,1
+ brr tr,0
+ moviq r1,2
+ brr tr,foo
+ moviq r1,4
+ brr fa,.
diff --git a/gas/testsuite/gas/visium/brr_backward.s b/gas/testsuite/gas/visium/brr_backward.s
new file mode 100644
index 0000000..a601bd2
--- /dev/null
+++ b/gas/testsuite/gas/visium/brr_backward.s
@@ -0,0 +1,15 @@
+; Test error messages where targets are out of range.
+
+; { dg-do assemble }
+
+ .text
+L1:
+ .rept 32768
+ nop
+ .endr
+ brr tr,L1
+L2:
+ .rept 32769
+ nop
+ .endr
+ brr tr,L2 ; { dg-error "out of range" "out of range brr" }
diff --git a/gas/testsuite/gas/visium/brr_forward.s b/gas/testsuite/gas/visium/brr_forward.s
new file mode 100644
index 0000000..ee00f4e
--- /dev/null
+++ b/gas/testsuite/gas/visium/brr_forward.s
@@ -0,0 +1,16 @@
+; Test error messages when targets are out of range
+
+; { dg-do assemble }
+
+ .text
+ brr tr,L1
+ .rept 32766
+ nop
+ .endr
+L1:
+ brr tr,L2 ; { dg-error "out of range" "out of range brr" }
+ .rept 32767
+ nop
+ .endr
+L2:
+ .end
diff --git a/gas/testsuite/gas/visium/error.exp b/gas/testsuite/gas/visium/error.exp
new file mode 100644
index 0000000..f06287d
--- /dev/null
+++ b/gas/testsuite/gas/visium/error.exp
@@ -0,0 +1,35 @@
+# Expect script for Visium tests.
+# Copyright (C) 2014 Free Software Foundation, Inc.
+#
+# This file is part of the GNU Binutils.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+# MA 02110-1301, USA.
+
+# Test assembler warnings and errors.
+
+if [istarget visium-*-*] {
+
+ load_lib gas-dg.exp
+
+ dg-init
+
+ dg-runtest "$srcdir/$subdir/brr_backward.s" "" ""
+ dg-runtest "$srcdir/$subdir/brr_forward.s" "" ""
+ dg-runtest "$srcdir/$subdir/basereg.s" "" ""
+ dg-runtest "$srcdir/$subdir/fcmp.s" "" ""
+
+ dg-finish
+}
diff --git a/gas/testsuite/gas/visium/fcmp.s b/gas/testsuite/gas/visium/fcmp.s
new file mode 100644
index 0000000..713af4f
--- /dev/null
+++ b/gas/testsuite/gas/visium/fcmp.s
@@ -0,0 +1,11 @@
+; Test error messages for new syntax of FCMP/FCMPE
+
+; { dg-do assemble }
+; { dg-options "-mtune=gr6" }
+
+ .text
+foo:
+ fcmp r1, f1, f2 ; { dg-error "can only use r0 as Dest register" }
+ fcmp r0, f1, f2
+ fcmp f1, f2
+ .end
diff --git a/gas/testsuite/gas/visium/high-1.d b/gas/testsuite/gas/visium/high-1.d
new file mode 100644
index 0000000..167d2ea
--- /dev/null
+++ b/gas/testsuite/gas/visium/high-1.d
@@ -0,0 +1,19 @@
+#as:
+#objdump: -dr
+#name: high-1
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+0000000 <foo>:
+ 0: 84 a4 00 01 moviu r4,0x0001
+ 0: R_VISIUM_HI16 .text\+0x10000
+ 4: 84 84 00 00 movil r4,0x0000
+ 4: R_VISIUM_LO16 .text\+0x10000
+ 8: 84 a4 12 34 moviu r4,0x1234
+ c: 84 84 87 65 movil r4,0x8765
+ 10: 04 a4 00 00 moviu r4,0x0000
+ 10: R_VISIUM_HI16 .text\+0x18
+ 14: 84 84 00 18 movil r4,0x0018
+ 14: R_VISIUM_LO16 .text\+0x18
diff --git a/gas/testsuite/gas/visium/high-1.s b/gas/testsuite/gas/visium/high-1.s
new file mode 100644
index 0000000..aaf570c
--- /dev/null
+++ b/gas/testsuite/gas/visium/high-1.s
@@ -0,0 +1,11 @@
+; Test %hi/%lo handling.
+
+foo:
+ moviu r4,%u(foo+0x10000)
+ movil r4,%l(foo+0x10000)
+
+ moviu r4,%u 0x12348765
+ movil r4,%l 0x12348765
+
+ moviu r4,%u .+8
+ movil r4,%l .+4
diff --git a/gas/testsuite/gas/visium/immed-1.d b/gas/testsuite/gas/visium/immed-1.d
new file mode 100644
index 0000000..d19cda0
--- /dev/null
+++ b/gas/testsuite/gas/visium/immed-1.d
@@ -0,0 +1,17 @@
+#as:
+#objdump: -dr
+#name: immed-1
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+0000000 <bar>:
+ 0: 04 c1 00 00 moviq r1,0
+ 4: 84 41 00 0c subi r1,12
+ 8: 04 01 00 00 addi r1,0
+ 8: R_VISIUM_IM16 \.text
+ c: 84 c4 ff ec moviq r4,65516
+ \.\.\.
+ 1010: 04 c6 00 08 moviq r6,8
+ 1014: 04 c7 00 e4 moviq r7,228
diff --git a/gas/testsuite/gas/visium/immed-1.s b/gas/testsuite/gas/visium/immed-1.s
new file mode 100644
index 0000000..9711430
--- /dev/null
+++ b/gas/testsuite/gas/visium/immed-1.s
@@ -0,0 +1,10 @@
+! Tests for complex immediate expressions.
+ .text
+bar:
+ moviq r1, 0
+ subi r1, (. - bar + 8)
+ addi r1, bar
+ moviq r4, (bar - . -8) & 0xffff
+ .space 4096
+ moviq r6, (. - bar - 8) & 0xff
+ moviq r7, (bar - . -8) & 0xff
diff --git a/gas/testsuite/gas/visium/rela-1.d b/gas/testsuite/gas/visium/rela-1.d
new file mode 100644
index 0000000..274f5f8
--- /dev/null
+++ b/gas/testsuite/gas/visium/rela-1.d
@@ -0,0 +1,18 @@
+#as:
+#objdump: -dr
+#name: rela-1
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+0000000 <text>:
+ 0: f8 00 00 04 brr tr,\+4
+ 0: R_VISIUM_PC16 .text2\+0x10
+ 4: 00 00 00 00 nop
+ 8: 84 a6 00 00 moviu r6,0x0000
+ 8: R_VISIUM_HI16 .text2\+0x10
+ c: 84 86 00 10 movil r6,0x0010
+ c: R_VISIUM_LO16 .text2\+0x10
+ 10: ff 86 00 04 bra tr,r6,r0
+ 14: 00 00 00 00 nop
diff --git a/gas/testsuite/gas/visium/rela-1.s b/gas/testsuite/gas/visium/rela-1.s
new file mode 100644
index 0000000..28e1d1e
--- /dev/null
+++ b/gas/testsuite/gas/visium/rela-1.s
@@ -0,0 +1,20 @@
+
+ .section .text
+text:
+ brr tr,label
+ nop
+ moviu r6, %u label
+ movil r6, %l label
+ bra tr,r6,r0
+ nop
+
+ .section .text2
+text2:
+ nop
+ nop
+ nop
+ nop
+label:
+ .end
+
+
diff --git a/gas/testsuite/gas/visium/visium.exp b/gas/testsuite/gas/visium/visium.exp
new file mode 100644
index 0000000..c54d738
--- /dev/null
+++ b/gas/testsuite/gas/visium/visium.exp
@@ -0,0 +1,32 @@
+# Expect script for Visium tests.
+# Copyright (C) 2014 Free Software Foundation, Inc.
+#
+# This file is part of the GNU Binutils.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+# MA 02110-1301, USA.
+
+# Visium assembler testsuite.
+
+if [istarget visium-*-*] {
+ run_dump_test "allinsn_def"
+ run_dump_test "allinsn_gr5"
+ run_dump_test "allinsn_gr6"
+ run_dump_test "brr-1"
+ run_dump_test "brr-2"
+ run_dump_test "high-1"
+ run_dump_test "immed-1"
+ run_dump_test "rela-1"
+}