Add Visium support to gas
authorEric Botcazou <ebotcazou@gcc.gnu.org>
Sat, 6 Dec 2014 15:42:26 +0000 (16:42 +0100)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Sat, 6 Dec 2014 15:42:26 +0000 (16:42 +0100)
gas/
* 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.
gas/testsuite/
* gas/elf/elf.exp: Skip ifunc-1 for Visium.
* gas/visium/: New directory.

36 files changed:
gas/ChangeLog
gas/Makefile.am
gas/Makefile.in
gas/config/tc-visium.c [new file with mode: 0644]
gas/config/tc-visium.h [new file with mode: 0644]
gas/configure.tgt
gas/doc/Makefile.am
gas/doc/Makefile.in
gas/doc/all.texi
gas/doc/as.texinfo
gas/doc/c-visium.texi [new file with mode: 0644]
gas/po/POTFILES.in
gas/testsuite/ChangeLog
gas/testsuite/gas/elf/elf.exp
gas/testsuite/gas/visium/allinsn_def.d [new file with mode: 0644]
gas/testsuite/gas/visium/allinsn_def.s [new file with mode: 0644]
gas/testsuite/gas/visium/allinsn_gr5.d [new file with mode: 0644]
gas/testsuite/gas/visium/allinsn_gr5.s [new file with mode: 0644]
gas/testsuite/gas/visium/allinsn_gr6.d [new file with mode: 0644]
gas/testsuite/gas/visium/allinsn_gr6.s [new file with mode: 0644]
gas/testsuite/gas/visium/basereg.s [new file with mode: 0644]
gas/testsuite/gas/visium/brr-1.d [new file with mode: 0644]
gas/testsuite/gas/visium/brr-1.s [new file with mode: 0644]
gas/testsuite/gas/visium/brr-2.d [new file with mode: 0644]
gas/testsuite/gas/visium/brr-2.s [new file with mode: 0644]
gas/testsuite/gas/visium/brr_backward.s [new file with mode: 0644]
gas/testsuite/gas/visium/brr_forward.s [new file with mode: 0644]
gas/testsuite/gas/visium/error.exp [new file with mode: 0644]
gas/testsuite/gas/visium/fcmp.s [new file with mode: 0644]
gas/testsuite/gas/visium/high-1.d [new file with mode: 0644]
gas/testsuite/gas/visium/high-1.s [new file with mode: 0644]
gas/testsuite/gas/visium/immed-1.d [new file with mode: 0644]
gas/testsuite/gas/visium/immed-1.s [new file with mode: 0644]
gas/testsuite/gas/visium/rela-1.d [new file with mode: 0644]
gas/testsuite/gas/visium/rela-1.s [new file with mode: 0644]
gas/testsuite/gas/visium/visium.exp [new file with mode: 0644]

index 3508468..2fed961 100644 (file)
@@ -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.
index 55c86b2..f65225f 100644 (file)
@@ -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 \
index 5dc250f..c7b3597 100644 (file)
@@ -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 (file)
index 0000000..d44b6e9
--- /dev/null
@@ -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 (file)
index 0000000..6e1f791
--- /dev/null
@@ -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)
index d07d445..853988a 100644 (file)
@@ -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 ;;
index c2ddc02..2c179e4 100644 (file)
@@ -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 \
index 2db5121..4b5f4b7 100644 (file)
@@ -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 \
index 94b88bf..c578000 100644 (file)
@@ -74,6 +74,7 @@
 @set TILEPRO
 @set V850
 @set VAX
+@set VISIUM
 @set XGATE
 @set XSTORMY16
 @set XTENSA
index 243851b..17ae245 100644 (file)
@@ -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 (file)
index 0000000..bc05a8e
--- /dev/null
@@ -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
index d1fd07f..3514075 100644 (file)
@@ -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
index 5903720..63d58fe 100644 (file)
@@ -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.
index af5dbb2..291c2a7 100644 (file)
@@ -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 (file)
index 0000000..0a0170d
--- /dev/null
@@ -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 (file)
index 0000000..10e8b7f
--- /dev/null
@@ -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 (file)
index 0000000..49ba3ab
--- /dev/null
@@ -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 (file)
index 0000000..f4a9b30
--- /dev/null
@@ -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 (file)
index 0000000..bb198ec
--- /dev/null
@@ -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 (file)
index 0000000..32953fb
--- /dev/null
@@ -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 (file)
index 0000000..a875671
--- /dev/null
@@ -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 (file)
index 0000000..28b5f4b
--- /dev/null
@@ -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 (file)
index 0000000..34d5490
--- /dev/null
@@ -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 (file)
index 0000000..48d9ef5
--- /dev/null
@@ -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 (file)
index 0000000..34d5490
--- /dev/null
@@ -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 (file)
index 0000000..a601bd2
--- /dev/null
@@ -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 (file)
index 0000000..ee00f4e
--- /dev/null
@@ -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 (file)
index 0000000..f06287d
--- /dev/null
@@ -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 (file)
index 0000000..713af4f
--- /dev/null
@@ -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 (file)
index 0000000..167d2ea
--- /dev/null
@@ -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 (file)
index 0000000..aaf570c
--- /dev/null
@@ -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 (file)
index 0000000..d19cda0
--- /dev/null
@@ -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 (file)
index 0000000..9711430
--- /dev/null
@@ -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 (file)
index 0000000..274f5f8
--- /dev/null
@@ -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 (file)
index 0000000..28e1d1e
--- /dev/null
@@ -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 (file)
index 0000000..c54d738
--- /dev/null
@@ -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"
+}