public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 0/6] binutils port for the Visium
@ 2014-12-03 23:29 Eric Botcazou
  2014-12-03 23:36 ` [PATCH 1/6] Update from upstream config repo Eric Botcazou
                   ` (6 more replies)
  0 siblings, 7 replies; 17+ messages in thread
From: Eric Botcazou @ 2014-12-03 23:29 UTC (permalink / raw)
  To: binutils; +Cc: Eric Botcazou

From: Eric Botcazou <ebotcazou@gcc.gnu.org>

Hi,

on behalf of Controls and Data Services, AdaCore would like to contribute a
port of the binutils to the Visium.  This is a 32-bit RISC architecture with
an Extended Arithmetic Module implementing some 64-bit operations and an FPU
designed for embedded systems.  The ultimate goal is to contribute a port of
the entire toolchain with simulator, debugger, compiler and embedded libc.

The bulk of the port had been written by employees of CDS or companies that
are now part of CDS, and AdaCore contributed enhancements and modifications
on top of it.  Both companies have a copyright assignment on file with the
FSF for the various components of the toolchain.

The binutils port is split into 6 patches (config, opcodes, bfd, binutils, gas
and ld) and 'make check' reports 0 failures for a visium-elf target configured 
with --disable-gdb after they are applied (on a x86_64-linux host).

OK for the mainline?


Eric Botcazou (6):
  Update from upstream config repo
  Add Visium support to opcodes
  Add Visium support to bfd
  Add Visium support to binutils
  Add Visium support to gas
  Add Visium support to ld

 bfd/Makefile.am                             |    4 +
 bfd/Makefile.in                             |    6 +
 bfd/archures.c                              |    4 +
 bfd/bfd-in2.h                               |   11 +
 bfd/config.bfd                              |    5 +
 bfd/configure                               |    1 +
 bfd/configure.ac                            |    1 +
 bfd/cpu-visium.c                            |   41 +
 bfd/elf32-visium.c                          |  959 +++++++++++
 bfd/libbfd.h                                |    7 +
 bfd/po/SRC-POTFILES.in                      |    2 +
 bfd/reloc.c                                 |   17 +
 bfd/targets.c                               |    3 +
 binutils/readelf.c                          |   23 +
 binutils/testsuite/binutils-all/objcopy.exp |    1 +
 config.sub                                  |    4 +-
 gas/Makefile.am                             |    6 +-
 gas/Makefile.in                             |   41 +-
 gas/config/tc-visium.c                      | 2328 +++++++++++++++++++++++++++
 gas/config/tc-visium.h                      |   79 +
 gas/configure.tgt                           |    3 +
 gas/po/POTFILES.in                          |    2 +
 gas/testsuite/gas/elf/elf.exp               |    3 +-
 gas/testsuite/gas/visium/allinsn.exp        |    7 +
 gas/testsuite/gas/visium/allinsn_def.d      |  134 ++
 gas/testsuite/gas/visium/allinsn_def.s      |  157 ++
 gas/testsuite/gas/visium/allinsn_gr5.d      |  153 ++
 gas/testsuite/gas/visium/allinsn_gr5.s      |  179 ++
 gas/testsuite/gas/visium/allinsn_gr6.d      |  159 ++
 gas/testsuite/gas/visium/allinsn_gr6.s      |  185 +++
 gas/testsuite/gas/visium/basereg.s          |   20 +
 gas/testsuite/gas/visium/brr-1.d            |   16 +
 gas/testsuite/gas/visium/brr-1.s            |    9 +
 gas/testsuite/gas/visium/brr-2.d            |   18 +
 gas/testsuite/gas/visium/brr-2.s            |    9 +
 gas/testsuite/gas/visium/brr_backward.s     |   15 +
 gas/testsuite/gas/visium/brr_forward.s      |   16 +
 gas/testsuite/gas/visium/error.exp          |   35 +
 gas/testsuite/gas/visium/fcmp.s             |   11 +
 gas/testsuite/gas/visium/high-1.d           |   19 +
 gas/testsuite/gas/visium/high-1.s           |   11 +
 gas/testsuite/gas/visium/immed-1.d          |   17 +
 gas/testsuite/gas/visium/immed-1.s          |   10 +
 gas/testsuite/gas/visium/rela-1.d           |   18 +
 gas/testsuite/gas/visium/rela-1.s           |   20 +
 gas/testsuite/gas/visium/visium.exp         |   29 +
 include/dis-asm.h                           |    1 +
 include/elf/common.h                        |    1 +
 include/elf/visium.h                        |   51 +
 include/opcode/visium.h                     |  337 ++++
 ld/Makefile.am                              |    4 +
 ld/Makefile.in                              |    5 +
 ld/configure.tgt                            |    2 +
 ld/emulparams/elf32visium.sh                |    9 +
 ld/scripttempl/visium.sc                    |  181 +++
 ld/testsuite/ld-elf/eh-frame-hdr.d          |    2 +-
 ld/testsuite/ld-elf/eh5.d                   |    2 +-
 ld/testsuite/ld-elf/flags1.d                |    4 +-
 ld/testsuite/ld-elf/pr14926.d               |    2 +-
 ld/testsuite/ld-elf/sec-to-seg.exp          |    1 +
 ld/testsuite/ld-visium/brr_x_backward.d     |    4 +
 ld/testsuite/ld-visium/brr_x_backward1.s    |    6 +
 ld/testsuite/ld-visium/brr_x_backward2.s    |    7 +
 ld/testsuite/ld-visium/brr_x_forward.d      |    4 +
 ld/testsuite/ld-visium/brr_x_forward1.s     |    7 +
 ld/testsuite/ld-visium/brr_x_forward2.s     |    6 +
 ld/testsuite/ld-visium/brr_x_seg.s          |    9 +
 ld/testsuite/ld-visium/brr_x_seg1.d         |    3 +
 ld/testsuite/ld-visium/brr_x_seg2.d         |    3 +
 ld/testsuite/ld-visium/imm_x_seg.d          |    3 +
 ld/testsuite/ld-visium/imm_x_seg.s          |    8 +
 ld/testsuite/ld-visium/ld1.ld               |    9 +
 ld/testsuite/ld-visium/ld2.ld               |    9 +
 ld/testsuite/ld-visium/ld3.ld               |    9 +
 ld/testsuite/ld-visium/reloc.d              |   14 +
 ld/testsuite/ld-visium/reloc1.s             |   24 +
 ld/testsuite/ld-visium/reloc2.s             |   12 +
 ld/testsuite/ld-visium/visium.exp           |   30 +
 ld/testsuite/lib/ld-lib.exp                 |    1 +
 opcodes/Makefile.am                         |    2 +
 opcodes/Makefile.in                         |    4 +
 opcodes/configure                           |    1 +
 opcodes/configure.ac                        |    1 +
 opcodes/disassemble.c                       |    6 +
 opcodes/po/POTFILES.in                      |    2 +
 opcodes/visium-dis.c                        |  834 ++++++++++
 opcodes/visium-opc.c                        |   23 +
 87 files changed, 6420 insertions(+), 21 deletions(-)
 create mode 100644 bfd/cpu-visium.c
 create mode 100644 bfd/elf32-visium.c
 create mode 100644 gas/config/tc-visium.c
 create mode 100644 gas/config/tc-visium.h
 create mode 100644 gas/testsuite/gas/visium/allinsn.exp
 create mode 100644 gas/testsuite/gas/visium/allinsn_def.d
 create mode 100644 gas/testsuite/gas/visium/allinsn_def.s
 create mode 100644 gas/testsuite/gas/visium/allinsn_gr5.d
 create mode 100644 gas/testsuite/gas/visium/allinsn_gr5.s
 create mode 100644 gas/testsuite/gas/visium/allinsn_gr6.d
 create mode 100644 gas/testsuite/gas/visium/allinsn_gr6.s
 create mode 100644 gas/testsuite/gas/visium/basereg.s
 create mode 100644 gas/testsuite/gas/visium/brr-1.d
 create mode 100644 gas/testsuite/gas/visium/brr-1.s
 create mode 100644 gas/testsuite/gas/visium/brr-2.d
 create mode 100644 gas/testsuite/gas/visium/brr-2.s
 create mode 100644 gas/testsuite/gas/visium/brr_backward.s
 create mode 100644 gas/testsuite/gas/visium/brr_forward.s
 create mode 100644 gas/testsuite/gas/visium/error.exp
 create mode 100644 gas/testsuite/gas/visium/fcmp.s
 create mode 100644 gas/testsuite/gas/visium/high-1.d
 create mode 100644 gas/testsuite/gas/visium/high-1.s
 create mode 100644 gas/testsuite/gas/visium/immed-1.d
 create mode 100644 gas/testsuite/gas/visium/immed-1.s
 create mode 100644 gas/testsuite/gas/visium/rela-1.d
 create mode 100644 gas/testsuite/gas/visium/rela-1.s
 create mode 100644 gas/testsuite/gas/visium/visium.exp
 create mode 100644 include/elf/visium.h
 create mode 100644 include/opcode/visium.h
 create mode 100644 ld/emulparams/elf32visium.sh
 create mode 100644 ld/scripttempl/visium.sc
 create mode 100644 ld/testsuite/ld-visium/brr_x_backward.d
 create mode 100644 ld/testsuite/ld-visium/brr_x_backward1.s
 create mode 100644 ld/testsuite/ld-visium/brr_x_backward2.s
 create mode 100644 ld/testsuite/ld-visium/brr_x_forward.d
 create mode 100644 ld/testsuite/ld-visium/brr_x_forward1.s
 create mode 100644 ld/testsuite/ld-visium/brr_x_forward2.s
 create mode 100644 ld/testsuite/ld-visium/brr_x_seg.s
 create mode 100644 ld/testsuite/ld-visium/brr_x_seg1.d
 create mode 100644 ld/testsuite/ld-visium/brr_x_seg2.d
 create mode 100644 ld/testsuite/ld-visium/imm_x_seg.d
 create mode 100644 ld/testsuite/ld-visium/imm_x_seg.s
 create mode 100644 ld/testsuite/ld-visium/ld1.ld
 create mode 100644 ld/testsuite/ld-visium/ld2.ld
 create mode 100644 ld/testsuite/ld-visium/ld3.ld
 create mode 100644 ld/testsuite/ld-visium/reloc.d
 create mode 100644 ld/testsuite/ld-visium/reloc1.s
 create mode 100644 ld/testsuite/ld-visium/reloc2.s
 create mode 100644 ld/testsuite/ld-visium/visium.exp
 create mode 100644 opcodes/visium-dis.c
 create mode 100644 opcodes/visium-opc.c

-- 
1.7.7

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 4/6] Add Visium support to binutils
  2014-12-03 23:29 [PATCH 0/6] binutils port for the Visium Eric Botcazou
  2014-12-03 23:36 ` [PATCH 1/6] Update from upstream config repo Eric Botcazou
  2014-12-03 23:36 ` [PATCH 6/6] Add Visium support to ld Eric Botcazou
@ 2014-12-03 23:36 ` Eric Botcazou
  2014-12-03 23:46 ` [PATCH 3/6] Add Visium support to bfd Eric Botcazou
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 17+ messages in thread
From: Eric Botcazou @ 2014-12-03 23:36 UTC (permalink / raw)
  To: binutils; +Cc: Eric Botcazou

From: Eric Botcazou <ebotcazou@gcc.gnu.org>

binutils/ChangeLog

2014-12-03  Eric Botcazou  <ebotcazou@adacore.com>

	* readelf.c: Include elf/visium.h.
	(guess_is_rela): Deal with EM_VISIUM.
	(dump_relocations): Likewise.
	(get_machine_name): Likewise.
	(get_machine_flags): Likewise.
	(get_osabi_name): Likewise.
	(is_32bit_abs_reloc): Likewise.
	(is_32bit_pcrel_reloc): Likewise.
	(is_16bit_abs_reloc): Likewise.

binutils/testsuite/ChangeLog

2014-12-03  Eric Botcazou  <ebotcazou@adacore.com>

	* binutils-all/objcopy.exp: Skip strip-10 for Visium.

---
 binutils/readelf.c                          |   23 +++++++++++++++++++++++
 binutils/testsuite/binutils-all/objcopy.exp |    1 +
 2 files changed, 24 insertions(+), 0 deletions(-)

diff --git a/binutils/readelf.c b/binutils/readelf.c
index 2004752..db9290f 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -149,6 +149,7 @@
 #include "elf/tilepro.h"
 #include "elf/v850.h"
 #include "elf/vax.h"
+#include "elf/visium.h"
 #include "elf/x86-64.h"
 #include "elf/xc16x.h"
 #include "elf/xgate.h"
@@ -754,6 +755,7 @@ guess_is_rela (unsigned int e_machine)
     case EM_V850:
     case EM_CYGNUS_V850:
     case EM_VAX:
+    case EM_VISIUM:
     case EM_X86_64:
     case EM_L1OM:
     case EM_K1OM:
@@ -1344,6 +1346,10 @@ dump_relocations (FILE * file,
 	  rtype = elf_vax_reloc_type (type);
 	  break;
 
+	case EM_VISIUM:
+	  rtype = elf_visium_reloc_type (type);
+	  break;
+
 	case EM_ADAPTEVA_EPIPHANY:
 	  rtype = elf_epiphany_reloc_type (type);
 	  break;
@@ -2123,6 +2129,7 @@ get_machine_name (unsigned e_machine)
     case EM_SVX:		return "Silicon Graphics SVx";
     case EM_ST19:		return "STMicroelectronics ST19 8-bit microcontroller";
     case EM_VAX:		return "Digital VAX";
+    case EM_VISIUM:		return "CDS VISIUMcore processor";
     case EM_AVR_OLD:
     case EM_AVR:		return "Atmel AVR 8-bit microcontroller";
     case EM_CRIS:		return "Axis Communications 32-bit embedded processor";
@@ -3137,6 +3144,15 @@ get_machine_flags (unsigned e_flags, unsigned e_machine)
 	    strcat (buf, ", G-Float");
 	  break;
 
+        case EM_VISIUM:
+	  if (e_flags & EF_VISIUM_ARCH_MCM)
+	    strcat (buf, ", mcm");
+	  else if (e_flags & EF_VISIUM_ARCH_MCM24)
+	    strcat (buf, ", mcm24");
+	  if (e_flags & EF_VISIUM_ARCH_GR6)
+	    strcat (buf, ", gr6");
+	  break;
+
 	case EM_RL78:
 	  if (e_flags & E_FLAG_RL78_G10)
 	    strcat (buf, ", G10");
@@ -3233,6 +3249,7 @@ get_osabi_name (unsigned int osabi)
 
 	  case EM_MSP430:
 	  case EM_MSP430_OLD:
+	  case EM_VISIUM:
 	    switch (osabi)
 	      {
 	      case ELFOSABI_STANDALONE:	return _("Standalone App");
@@ -10966,6 +10983,8 @@ is_32bit_abs_reloc (unsigned int reloc_type)
       return reloc_type == 0x33; /* R_V810_WORD.  */
     case EM_VAX:
       return reloc_type == 1; /* R_VAX_32.  */
+    case EM_VISIUM:
+      return reloc_type == 3;  /* R_VISIUM_32. */
     case EM_X86_64:
     case EM_L1OM:
     case EM_K1OM:
@@ -11033,6 +11052,8 @@ is_32bit_pcrel_reloc (unsigned int reloc_type)
       return reloc_type == 6; /* R_TILEGX_32_PCREL.  */
     case EM_TILEPRO:
       return reloc_type == 4; /* R_TILEPRO_32_PCREL.  */
+    case EM_VISIUM:
+      return reloc_type == 6;  /* R_VISIUM_32_PCREL */
     case EM_X86_64:
     case EM_L1OM:
     case EM_K1OM:
@@ -11190,6 +11211,8 @@ is_16bit_abs_reloc (unsigned int reloc_type)
     case EM_CYGNUS_MN10300:
     case EM_MN10300:
       return reloc_type == 2; /* R_MN10300_16.  */
+    case EM_VISIUM:
+      return reloc_type == 2; /* R_VISIUM_16. */
     case EM_XGATE:
       return reloc_type == 3; /* R_XGATE_16.  */
     default:
diff --git a/binutils/testsuite/binutils-all/objcopy.exp b/binutils/testsuite/binutils-all/objcopy.exp
index 49d466d..c83825a 100644
--- a/binutils/testsuite/binutils-all/objcopy.exp
+++ b/binutils/testsuite/binutils-all/objcopy.exp
@@ -956,6 +956,7 @@ if [is_elf_format] {
     # Non-EABI ARM targets will set OSABI to ARM
     if { ![istarget "*-*-hpux*"]
 	 && ![istarget "msp*-*-*"]
+	 && ![istarget "visium-*-*"]
          && !([istarget "arm*-*-*"] && ![istarget "arm-*-*eabi*"])} {
 	run_dump_test "strip-10"
     }
-- 
1.7.7

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 1/6] Update from upstream config repo
  2014-12-03 23:29 [PATCH 0/6] binutils port for the Visium Eric Botcazou
@ 2014-12-03 23:36 ` Eric Botcazou
  2014-12-03 23:36 ` [PATCH 6/6] Add Visium support to ld Eric Botcazou
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 17+ messages in thread
From: Eric Botcazou @ 2014-12-03 23:36 UTC (permalink / raw)
  To: binutils; +Cc: Eric Botcazou

From: Eric Botcazou <ebotcazou@gcc.gnu.org>

ChangeLog

2014-12-03  Eric Botcazou  <ebotcazou@adacore.com>

	* config.sub: Update from upstream config repo.

---
 config.sub |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/config.sub b/config.sub
index 7cc68ba..7ffe373 100755
--- a/config.sub
+++ b/config.sub
@@ -2,7 +2,7 @@
 # Configuration validation subroutine script.
 #   Copyright 1992-2014 Free Software Foundation, Inc.
 
-timestamp='2014-09-26'
+timestamp='2014-12-03'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -313,6 +313,7 @@ case $basic_machine in
 	| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
 	| ubicom32 \
 	| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
+	| visium \
 	| we32k \
 	| x86 | xc16x | xstormy16 | xtensa \
 	| z8k | z80)
@@ -440,6 +441,7 @@ case $basic_machine in
 	| ubicom32-* \
 	| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
 	| vax-* \
+	| visium-* \
 	| we32k-* \
 	| x86-* | x86_64-* | xc16x-* | xps100-* \
 	| xstormy16-* | xtensa*-* \
-- 
1.7.7

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 6/6] Add Visium support to ld
  2014-12-03 23:29 [PATCH 0/6] binutils port for the Visium Eric Botcazou
  2014-12-03 23:36 ` [PATCH 1/6] Update from upstream config repo Eric Botcazou
@ 2014-12-03 23:36 ` Eric Botcazou
  2014-12-03 23:36 ` [PATCH 4/6] Add Visium support to binutils Eric Botcazou
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 17+ messages in thread
From: Eric Botcazou @ 2014-12-03 23:36 UTC (permalink / raw)
  To: binutils; +Cc: Eric Botcazou

From: Eric Botcazou <ebotcazou@gcc.gnu.org>

ld/ChangeLog

2014-12-03  Eric Botcazou  <ebotcazou@adacore.com>

	* configure.tgt: Add Visium support.
	* Makefile.am (ALL_EMULATION_SOURCES): Add eelf32visium.c.
	(eelf32visium.c): New rule.
	* Makefile.in: Regenerate.
	* emulparams/elf32visium.sh: New file.
	* scripttempl/visium.sc: Likewise.

ld/testsuite/ChangeLog

2014-12-03  Eric Botcazou  <ebotcazou@adacore.com>

	* lib/ld-lib.exp (check_shared_lib_support): Return 0 for Visium.
	* ld-visium/: New directory.

---
 ld/Makefile.am                           |    4 +
 ld/Makefile.in                           |    5 +
 ld/configure.tgt                         |    2 +
 ld/emulparams/elf32visium.sh             |    9 ++
 ld/scripttempl/visium.sc                 |  181 ++++++++++++++++++++++++++++++
 ld/testsuite/ld-elf/eh-frame-hdr.d       |    2 +-
 ld/testsuite/ld-elf/eh5.d                |    2 +-
 ld/testsuite/ld-elf/flags1.d             |    4 +-
 ld/testsuite/ld-elf/pr14926.d            |    2 +-
 ld/testsuite/ld-elf/sec-to-seg.exp       |    1 +
 ld/testsuite/ld-visium/brr_x_backward.d  |    4 +
 ld/testsuite/ld-visium/brr_x_backward1.s |    6 +
 ld/testsuite/ld-visium/brr_x_backward2.s |    7 +
 ld/testsuite/ld-visium/brr_x_forward.d   |    4 +
 ld/testsuite/ld-visium/brr_x_forward1.s  |    7 +
 ld/testsuite/ld-visium/brr_x_forward2.s  |    6 +
 ld/testsuite/ld-visium/brr_x_seg.s       |    9 ++
 ld/testsuite/ld-visium/brr_x_seg1.d      |    3 +
 ld/testsuite/ld-visium/brr_x_seg2.d      |    3 +
 ld/testsuite/ld-visium/imm_x_seg.d       |    3 +
 ld/testsuite/ld-visium/imm_x_seg.s       |    8 ++
 ld/testsuite/ld-visium/ld1.ld            |    9 ++
 ld/testsuite/ld-visium/ld2.ld            |    9 ++
 ld/testsuite/ld-visium/ld3.ld            |    9 ++
 ld/testsuite/ld-visium/reloc.d           |   14 +++
 ld/testsuite/ld-visium/reloc1.s          |   24 ++++
 ld/testsuite/ld-visium/reloc2.s          |   12 ++
 ld/testsuite/ld-visium/visium.exp        |   30 +++++
 ld/testsuite/lib/ld-lib.exp              |    1 +
 29 files changed, 375 insertions(+), 5 deletions(-)
 create mode 100644 ld/emulparams/elf32visium.sh
 create mode 100644 ld/scripttempl/visium.sc
 create mode 100644 ld/testsuite/ld-visium/brr_x_backward.d
 create mode 100644 ld/testsuite/ld-visium/brr_x_backward1.s
 create mode 100644 ld/testsuite/ld-visium/brr_x_backward2.s
 create mode 100644 ld/testsuite/ld-visium/brr_x_forward.d
 create mode 100644 ld/testsuite/ld-visium/brr_x_forward1.s
 create mode 100644 ld/testsuite/ld-visium/brr_x_forward2.s
 create mode 100644 ld/testsuite/ld-visium/brr_x_seg.s
 create mode 100644 ld/testsuite/ld-visium/brr_x_seg1.d
 create mode 100644 ld/testsuite/ld-visium/brr_x_seg2.d
 create mode 100644 ld/testsuite/ld-visium/imm_x_seg.d
 create mode 100644 ld/testsuite/ld-visium/imm_x_seg.s
 create mode 100644 ld/testsuite/ld-visium/ld1.ld
 create mode 100644 ld/testsuite/ld-visium/ld2.ld
 create mode 100644 ld/testsuite/ld-visium/ld3.ld
 create mode 100644 ld/testsuite/ld-visium/reloc.d
 create mode 100644 ld/testsuite/ld-visium/reloc1.s
 create mode 100644 ld/testsuite/ld-visium/reloc2.s
 create mode 100644 ld/testsuite/ld-visium/visium.exp

diff --git a/ld/Makefile.am b/ld/Makefile.am
index 9575f1f..3639d50 100644
--- a/ld/Makefile.am
+++ b/ld/Makefile.am
@@ -264,6 +264,7 @@ ALL_EMULATION_SOURCES = \
 	eelf32tilegx_be.c \
 	eelf32tilepro.c \
 	eelf32vax.c \
+	eelf32visium.c \
 	eelf32xc16x.c \
 	eelf32xc16xl.c \
 	eelf32xc16xs.c \
@@ -1231,6 +1232,9 @@ eelf32tilepro.c: $(srcdir)/emulparams/elf32tilepro.sh \
 eelf32vax.c: $(srcdir)/emulparams/elf32vax.sh \
   $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
 
+eelf32visium.c: $(srcdir)/emulparams/elf32visium.sh \
+  $(ELF_DEPS) $(srcdir)/scripttempl/visium.sc ${GEN_DEPENDS}
+
 eelf32xc16x.c: $(srcdir)/emulparams/elf32xc16x.sh \
   $(ELF_DEPS) $(srcdir)/emultempl/needrelax.em \
   $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
diff --git a/ld/Makefile.in b/ld/Makefile.in
index 9f56ca1..20d10a1 100644
--- a/ld/Makefile.in
+++ b/ld/Makefile.in
@@ -572,6 +572,7 @@ ALL_EMULATION_SOURCES = \
 	eelf32tilegx_be.c \
 	eelf32tilepro.c \
 	eelf32vax.c \
+	eelf32visium.c \
 	eelf32xc16x.c \
 	eelf32xc16xl.c \
 	eelf32xc16xs.c \
@@ -1190,6 +1191,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32tilegx_be.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32tilepro.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32vax.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32visium.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32xc16x.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32xc16xl.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32xc16xs.Po@am__quote@
@@ -2672,6 +2674,9 @@ eelf32tilepro.c: $(srcdir)/emulparams/elf32tilepro.sh \
 eelf32vax.c: $(srcdir)/emulparams/elf32vax.sh \
   $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
 
+eelf32visium.c: $(srcdir)/emulparams/elf32visium.sh \
+  $(ELF_DEPS) $(srcdir)/scripttempl/visium.sc ${GEN_DEPENDS}
+
 eelf32xc16x.c: $(srcdir)/emulparams/elf32xc16x.sh \
   $(ELF_DEPS) $(srcdir)/emultempl/needrelax.em \
   $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
diff --git a/ld/configure.tgt b/ld/configure.tgt
index 24e36d1..2f7744a 100644
--- a/ld/configure.tgt
+++ b/ld/configure.tgt
@@ -755,6 +755,8 @@ vax-*-netbsdaout* | vax-*-netbsd*)
 			targ_extra_emuls=elf32vax ;;
 vax-*-linux-*)  	targ_emul=elf32vax
 			;;
+visium-*-elf)		targ_emul=elf32visium
+			;;
 w65-*-*)		targ_emul=w65
 			;;
 xc16x-*-elf)		targ_emul=elf32xc16x
diff --git a/ld/emulparams/elf32visium.sh b/ld/emulparams/elf32visium.sh
new file mode 100644
index 0000000..17cf4b9
--- /dev/null
+++ b/ld/emulparams/elf32visium.sh
@@ -0,0 +1,9 @@
+SCRIPT_NAME=visium
+OUTPUT_FORMAT="elf32-visium"
+TEXT_START_ADDR=0x00000000
+MAXPAGESIZE=0x10000
+NONPAGED_TEXT_START_ADDR=0x10000
+ARCH=visium
+MACHINE=
+TEMPLATE_NAME=elf32
+DYNAMIC_LINK=FALSE
diff --git a/ld/scripttempl/visium.sc b/ld/scripttempl/visium.sc
new file mode 100644
index 0000000..60338b1
--- /dev/null
+++ b/ld/scripttempl/visium.sc
@@ -0,0 +1,181 @@
+# Copyright (C) 2014 Free Software Foundation, Inc.
+# 
+# Copying and distribution of this file, with or without modification,
+# are permitted in any medium without royalty provided the copyright
+# notice and this notice are preserved.
+
+#  Many sections come in three flavours.  There is the 'real' section,
+#  like ".data".  Then there are the per-procedure or per-variable
+#  sections, generated by -ffunction-sections and -fdata-sections in GCC,
+#  and useful for --gc-sections, which for a variable "foo" might be
+#  ".data.foo".  Then there are the linkonce sections, for which the linker
+#  eliminates duplicates, which are named like ".gnu.linkonce.d.foo".
+#  The exact correspondences are:
+#
+#  Section	Linkonce section
+#  .text	.gnu.linkonce.t.foo
+#  .rodata	.gnu.linkonce.r.foo
+#  .data	.gnu.linkonce.d.foo
+#  .bss		.gnu.linkonce.b.foo
+#  .sdata	.gnu.linkonce.s.foo
+#  .sbss	.gnu.linkonce.sb.foo
+#  .sdata2	.gnu.linkonce.s2.foo
+#  .sbss2	.gnu.linkonce.sb2.foo
+#  .debug_info	.gnu.linkonce.wi.foo
+#  .tdata	.gnu.linkonce.td.foo
+#  .tbss	.gnu.linkonce.tb.foo
+#  .lrodata	.gnu.linkonce.lr.foo
+#  .ldata	.gnu.linkonce.l.foo
+#  .lbss	.gnu.linkonce.lb.foo
+#
+#  Each of these can also have corresponding .rel.* and .rela.* sections.
+
+test -z "$ENTRY" && ENTRY=__start
+cat <<EOF
+OUTPUT_FORMAT("${OUTPUT_FORMAT}")
+
+ENTRY(${ENTRY})
+
+/* Start and end of main stack. Assumes 256K of RAM.  */
+${RELOCATING+ _estack = 0xe0040000 - 4;}
+${RELOCATING+ _sstack = 0xe0040000 - 64K;}
+
+/* End of heap.  */
+${RELOCATING+ _eheap = _sstack - 4;}
+
+
+MEMORY
+{
+  init    : ORIGIN = 0x00000000, LENGTH = 0x0003fffc
+  scr     : ORIGIN = 0x0003fffc, LENGTH = 0x00000004
+  rom     : ORIGIN = 0x00044000, LENGTH = 0x1ffbc000
+  ram     : ORIGIN = 0xe0000000, LENGTH = 0x10000000
+  saferam : ORIGIN = 0xf0000000, LENGTH = 0x10000000
+}
+
+
+SECTIONS
+{
+  .init ${RELOCATING-0} : {
+    KEEP (*(.init))
+    KEEP (*(.fini))
+    ${RELOCATING+ _einit  =  .;}
+  } ${RELOCATING+ > init}
+
+  .text ${RELOCATING-0} : {
+    ${RELOCATING+ _ftext  =  .;}
+    *(.text)
+    ${RELOCATING+*(.text.*)}
+    ${RELOCATING+*(.gnu.linkonce.t.*)}
+    ${RELOCATING+ _etext  =  .;}
+  } ${RELOCATING+ > rom}
+
+  .ctors ${RELOCATING-0} : {
+    ${CONSTRUCTING+ . = ALIGN(4);}
+    ${CONSTRUCTING+ __CTOR_LIST__ = .;}
+    /* gcc uses crtbegin.o to find the start of
+       the constructors, so we make sure it is
+       first.  Because this is a wildcard, it
+       doesn't matter if the user does not
+       actually link against crtbegin.o; the
+       linker won't look for a file to match a
+       wildcard.  The wildcard also means that it
+       doesn't matter which directory crtbegin.o
+       is in.  */
+
+    KEEP (*crtbegin*.o(.ctors))
+
+    /* We don't want to include the .ctor section from
+       from the crtend.o file until after the sorted ctors.
+       The .ctor section from the crtend file contains the
+       end of ctors marker and it must be last.  */
+
+    KEEP (*(EXCLUDE_FILE (*crtend*.o) .ctors))
+    KEEP (*(SORT(.ctors.*)))
+    KEEP (*(.ctors))
+    ${CONSTRUCTING+ __CTOR_END__ = .;}
+  } ${RELOCATING+ > rom}
+
+  .dtors ${RELOCATING-0} : {
+    ${CONSTRUCTING+ __DTOR_LIST__ = .;}
+    KEEP (*crtbegin*.o(.dtors))
+    KEEP (*(EXCLUDE_FILE (*crtend*.o) .dtors))
+    KEEP (*(SORT(.dtors.*)))
+    KEEP (*(.dtors))
+    ${CONSTRUCTING+ __DTOR_END__ = .;}
+  } ${RELOCATING+ > rom}
+  .rodata ${RELOCATING-0} : {
+    ${RELOCATING+ . = ALIGN(4);}
+    ${RELOCATING+ _srdata  =  .;}
+    *(.rdata)
+    *(.rodata)
+    ${RELOCATING+*(.rodata.*)}
+    ${RELOCATING+*(.gnu.linkonce.r.*)}
+    ${RELOCATING+ . = ALIGN(4);}
+    ${RELOCATING+ _erdata  =  .;}
+  } ${RELOCATING+ > rom}
+
+  .eh_frame ${RELOCATING-0} :
+  {
+    ${RELOCATING+PROVIDE (__eh_frame_begin = .);}
+    *(.eh_frame)
+    ${RELOCATING+ LONG (0);}
+    ${RELOCATING+PROVIDE (__eh_frame_end = .);}
+  } ${RELOCATING+ > rom}
+  .gcc_except_table ${RELOCATING-0} : { *(.gcc_except_table) } ${RELOCATING+ > rom}
+  .jcr ${RELOCATING-0} : { *(.jcr) } ${RELOCATING+ > rom}
+
+  .data ${RELOCATING-0} : {
+    ${RELOCATING+ . = ALIGN(4);}
+    ${RELOCATING+ _sdata  =  .;}
+    *(.data)
+    ${RELOCATING+*(.data.*)}
+    ${RELOCATING+*(.gnu.linkonce.d.*)}
+    ${RELOCATING+ . = ALIGN(4);}
+    ${RELOCATING+ _edata  =  .;}
+  } ${RELOCATING+ > ram}
+  .bss ${RELOCATING-0} : { 					
+    ${RELOCATING+ . = ALIGN(4);}
+    ${RELOCATING+ __bss_start = .;}
+    *(.bss)
+    ${RELOCATING+*(.bss.*)}
+    ${RELOCATING+*(.gnu.linkonce.b.*)}
+    *(COMMON)
+    ${RELOCATING+ . = ALIGN(4);}
+    ${RELOCATING+ __bss_end = .;}
+    ${RELOCATING+ _sheap = .;}
+  } ${RELOCATING+ > ram}
+
+  saferam ${RELOCATING-0} : {
+    *(saferam)
+    ${RELOCATING+ . = ALIGN(4);}
+    ${RELOCATING+ unitidentry = .;}
+  } ${RELOCATING+ > saferam}
+
+  /* Stabs debugging sections.  */
+  .stab          0 : { *(.stab) }
+  .stabstr       0 : { *(.stabstr) }
+  .stab.excl     0 : { *(.stab.excl) }
+  .stab.exclstr  0 : { *(.stab.exclstr) }
+  .stab.index    0 : { *(.stab.index) }
+  .stab.indexstr 0 : { *(.stab.indexstr) }
+
+  .comment       0 : { *(.comment) }
+
+EOF
+
+. $srcdir/scripttempl/DWARF.sc
+
+cat <<EOF
+}
+
+/* Provide a default address for the simulated file-I/O device.  */
+PROVIDE (_sim_fileio_register = 0x2fff0000);
+
+/* Provide a default address for the simulated command line device.  */
+PROVIDE (_sim_cmdline_header = 0x2ffe0000);
+
+/* Provide a default address for the simulated 1 MHz clock.  */
+PROVIDE (_sim_clock = 0x20002100);
+
+EOF
diff --git a/ld/testsuite/ld-elf/eh-frame-hdr.d b/ld/testsuite/ld-elf/eh-frame-hdr.d
index 45a890d..4214ed5 100644
--- a/ld/testsuite/ld-elf/eh-frame-hdr.d
+++ b/ld/testsuite/ld-elf/eh-frame-hdr.d
@@ -2,7 +2,7 @@
 #ld: -e _start --eh-frame-hdr
 #objdump: -hw
 #target: cfi
-#xfail: avr*-*-* or1k-*-*
+#xfail: avr*-*-* or1k-*-* visium-*-*
 # avr doesn't support shared libraries.
 #...
   [0-9] .eh_frame_hdr 0*[12][048c] .*
diff --git a/ld/testsuite/ld-elf/eh5.d b/ld/testsuite/ld-elf/eh5.d
index 29dcdf9..1a5148c 100644
--- a/ld/testsuite/ld-elf/eh5.d
+++ b/ld/testsuite/ld-elf/eh5.d
@@ -4,7 +4,7 @@
 #ld:
 #readelf: -wf
 #target: cfi
-#notarget: alpha* hppa64* tile*
+#notarget: alpha* hppa64* tile* visium*
 
 Contents of the .eh_frame section:
 
diff --git a/ld/testsuite/ld-elf/flags1.d b/ld/testsuite/ld-elf/flags1.d
index 63c2e3a..e7c6b4f 100644
--- a/ld/testsuite/ld-elf/flags1.d
+++ b/ld/testsuite/ld-elf/flags1.d
@@ -3,9 +3,9 @@
 #objcopy_linked_file: --set-section-flags .post_text_reserve=contents,alloc,load,readonly,code
 #readelf: -l --wide
 #xfail: "avr-*-*" "dlx-*-*" "h8300-*-*" "i960-*-*" "ip2k-*-*" "m32r-*-*"
-#xfail: "moxie-*-*" "mt-*-*" "*-*-nacl*"
+#xfail: "moxie-*-*" "mt-*-*" "visium-*-*" "*-*-nacl*"
 #xfail: "*-*-hpux*" "hppa*64*-*-*"
-# Fails on the AVR, DLX, H8300, I960, IP2K, M32R, MOXIE, MT,
+# Fails on the AVR, DLX, H8300, I960, IP2K, M32R, MOXIE, MT, VISIUM
 #  and all NaCl targets,
 #  because the two sections are not merged into one segment.
 #  (There is no good reason why they have to be).
diff --git a/ld/testsuite/ld-elf/pr14926.d b/ld/testsuite/ld-elf/pr14926.d
index 148c8b4..4f7fef4 100644
--- a/ld/testsuite/ld-elf/pr14926.d
+++ b/ld/testsuite/ld-elf/pr14926.d
@@ -1,6 +1,6 @@
 #ld: -Ttext=0x60
 #readelf: -S --wide
-#notarget: d10v-*-* msp*-*-* xstormy*-*-*
+#notarget: d10v-*-* msp*-*-* visium-*-* xstormy*-*-*
 # the above targets use memory regions that don't allow 0x60 for .text
 
 #...
diff --git a/ld/testsuite/ld-elf/sec-to-seg.exp b/ld/testsuite/ld-elf/sec-to-seg.exp
index 612dd0c..30bf756 100644
--- a/ld/testsuite/ld-elf/sec-to-seg.exp
+++ b/ld/testsuite/ld-elf/sec-to-seg.exp
@@ -86,6 +86,7 @@ if {    [istarget avr-*-*]
      || [istarget moxie-*-*]
      || [istarget msp430-*-*]
      || [istarget mt-*-*]
+     || [istarget visium-*-*]
     } {
     set B_test_same_seg 0
 } else {
diff --git a/ld/testsuite/ld-visium/brr_x_backward.d b/ld/testsuite/ld-visium/brr_x_backward.d
new file mode 100644
index 0000000..543e912
--- /dev/null
+++ b/ld/testsuite/ld-visium/brr_x_backward.d
@@ -0,0 +1,4 @@
+#source: brr_x_backward1.s
+#source: brr_x_backward2.s
+#ld:
+#error: relocation truncated to fit: R_VISIUM_PC16
diff --git a/ld/testsuite/ld-visium/brr_x_backward1.s b/ld/testsuite/ld-visium/brr_x_backward1.s
new file mode 100644
index 0000000..03542f2
--- /dev/null
+++ b/ld/testsuite/ld-visium/brr_x_backward1.s
@@ -0,0 +1,6 @@
+	.text
+	.global	start
+start:
+	.global	L1,L2
+L1:	nop
+L2:
diff --git a/ld/testsuite/ld-visium/brr_x_backward2.s b/ld/testsuite/ld-visium/brr_x_backward2.s
new file mode 100644
index 0000000..ef15268bf
--- /dev/null
+++ b/ld/testsuite/ld-visium/brr_x_backward2.s
@@ -0,0 +1,7 @@
+	.text
+	.rept	32767
+	nop
+	.endr
+	brr	tr,L1
+	nop
+	brr	tr,L2
diff --git a/ld/testsuite/ld-visium/brr_x_forward.d b/ld/testsuite/ld-visium/brr_x_forward.d
new file mode 100644
index 0000000..29adf74
--- /dev/null
+++ b/ld/testsuite/ld-visium/brr_x_forward.d
@@ -0,0 +1,4 @@
+#source: brr_x_forward1.s
+#source: brr_x_forward2.s
+#ld:
+#error: relocation truncated to fit: R_VISIUM_PC16
diff --git a/ld/testsuite/ld-visium/brr_x_forward1.s b/ld/testsuite/ld-visium/brr_x_forward1.s
new file mode 100644
index 0000000..34fddf8
--- /dev/null
+++ b/ld/testsuite/ld-visium/brr_x_forward1.s
@@ -0,0 +1,7 @@
+	.text
+	brr	tr,L1
+	nop
+	brr	tr,L2
+	.rept	32765
+	nop
+	.endr
diff --git a/ld/testsuite/ld-visium/brr_x_forward2.s b/ld/testsuite/ld-visium/brr_x_forward2.s
new file mode 100644
index 0000000..65e3dae
--- /dev/null
+++ b/ld/testsuite/ld-visium/brr_x_forward2.s
@@ -0,0 +1,6 @@
+	.global start
+	.global	L1,L2
+	.text
+start:
+L1:	nop
+L2:
diff --git a/ld/testsuite/ld-visium/brr_x_seg.s b/ld/testsuite/ld-visium/brr_x_seg.s
new file mode 100644
index 0000000..8a55711
--- /dev/null
+++ b/ld/testsuite/ld-visium/brr_x_seg.s
@@ -0,0 +1,9 @@
+	.text
+	nop
+	brr	tr,L1
+	nop
+	.data
+	.global	start
+start:
+	.long	0
+L1:
diff --git a/ld/testsuite/ld-visium/brr_x_seg1.d b/ld/testsuite/ld-visium/brr_x_seg1.d
new file mode 100644
index 0000000..ace1028
--- /dev/null
+++ b/ld/testsuite/ld-visium/brr_x_seg1.d
@@ -0,0 +1,3 @@
+#source: brr_x_seg.s
+#ld: -T ld1.ld
+#error: relocation truncated to fit: R_VISIUM_PC16
diff --git a/ld/testsuite/ld-visium/brr_x_seg2.d b/ld/testsuite/ld-visium/brr_x_seg2.d
new file mode 100644
index 0000000..9441d86
--- /dev/null
+++ b/ld/testsuite/ld-visium/brr_x_seg2.d
@@ -0,0 +1,3 @@
+#source: brr_x_seg.s
+#ld: -T ld2.ld
+#error: relocation truncated to fit: R_VISIUM_PC16
diff --git a/ld/testsuite/ld-visium/imm_x_seg.d b/ld/testsuite/ld-visium/imm_x_seg.d
new file mode 100644
index 0000000..d52fb7e
--- /dev/null
+++ b/ld/testsuite/ld-visium/imm_x_seg.d
@@ -0,0 +1,3 @@
+#source: imm_x_seg.s
+#ld: -T ld3.ld
+#error: relocation truncated to fit: R_VISIUM_IM16_PCREL
diff --git a/ld/testsuite/ld-visium/imm_x_seg.s b/ld/testsuite/ld-visium/imm_x_seg.s
new file mode 100644
index 0000000..d490b6f
--- /dev/null
+++ b/ld/testsuite/ld-visium/imm_x_seg.s
@@ -0,0 +1,8 @@
+	.section seg1
+foo:
+	nop
+	moviq	r6,bar-foo
+
+	.section seg2
+bar:
+	.end
diff --git a/ld/testsuite/ld-visium/ld1.ld b/ld/testsuite/ld-visium/ld1.ld
new file mode 100644
index 0000000..fc33cf8
--- /dev/null
+++ b/ld/testsuite/ld-visium/ld1.ld
@@ -0,0 +1,9 @@
+SECTIONS
+{
+  .text 0x10000 : {
+    *(.text)
+  }
+  .data 0x30000 : {
+    *(.data)
+  }
+}
diff --git a/ld/testsuite/ld-visium/ld2.ld b/ld/testsuite/ld-visium/ld2.ld
new file mode 100644
index 0000000..74f399a
--- /dev/null
+++ b/ld/testsuite/ld-visium/ld2.ld
@@ -0,0 +1,9 @@
+SECTIONS
+{
+  .text 0x30004 : {
+    *(.text)
+  }
+  .data 0x10000 : {
+    *(.data)
+  }
+}
diff --git a/ld/testsuite/ld-visium/ld3.ld b/ld/testsuite/ld-visium/ld3.ld
new file mode 100644
index 0000000..e3934cd
--- /dev/null
+++ b/ld/testsuite/ld-visium/ld3.ld
@@ -0,0 +1,9 @@
+SECTIONS
+{
+  seg1 0x10000 : {
+    *(seg1)
+  }
+  seg2 0x20000 : {
+    *(seg2)
+  }
+}
diff --git a/ld/testsuite/ld-visium/reloc.d b/ld/testsuite/ld-visium/reloc.d
new file mode 100644
index 0000000..bca5817
--- /dev/null
+++ b/ld/testsuite/ld-visium/reloc.d
@@ -0,0 +1,14 @@
+#source: reloc1.s
+#source: reloc2.s
+#ld: -T ld1.ld
+#objdump: -s
+
+.*: +file format .*
+
+Contents of section .text:
+ 10000 00000000 7800000a 84c20034 8482003c  ....x......4...<
+ 10010 84a20001 84c20002 0442002c 84020002  .........B.,....
+ 10020 0482002c 84a20002 84c21000           ...,........    
+Contents of section .data:
+ 30000 00140014 00000014 0001002c 0002002c  ...........,...,
+ 30010 10001010                             ....            
diff --git a/ld/testsuite/ld-visium/reloc1.s b/ld/testsuite/ld-visium/reloc1.s
new file mode 100644
index 0000000..41be3de
--- /dev/null
+++ b/ld/testsuite/ld-visium/reloc1.s
@@ -0,0 +1,24 @@
+	.data
+foo:
+	.byte	0
+	.byte	data1-foo
+	.word	data1-foo
+	.long	data1-foo
+	.long	text1
+	.long	text2
+	.word	abs1
+	.word	abs1+0x10
+	.text
+bar:
+	nop
+	brr	tr,text1
+	moviq	r2,text1-bar+8
+	movil	r2,%l text2-bar+16
+	moviu	r2,%u text2-bar+16
+	moviq	r2,%u text2
+	subi	r2,%l text2
+	addi	r2,%u text2
+	movil	r2, text2	; with movil, the %l may be omitted
+	moviu	r2,%u text2
+	moviq	r2,abs1
+	.end
diff --git a/ld/testsuite/ld-visium/reloc2.s b/ld/testsuite/ld-visium/reloc2.s
new file mode 100644
index 0000000..517d977
--- /dev/null
+++ b/ld/testsuite/ld-visium/reloc2.s
@@ -0,0 +1,12 @@
+	.global	abs1
+abs1 = 0x1000
+
+	.data
+	.global data1
+data1:
+	.text
+	.global text1
+text1:
+	.global text2
+text2 = . + 65536
+	.end
diff --git a/ld/testsuite/ld-visium/visium.exp b/ld/testsuite/ld-visium/visium.exp
new file mode 100644
index 0000000..c61467c
--- /dev/null
+++ b/ld/testsuite/ld-visium/visium.exp
@@ -0,0 +1,30 @@
+# 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 linker testsuite.
+
+if [istarget visium-*-*] {
+    run_dump_test "brr_x_backward"
+    run_dump_test "brr_x_forward"
+    run_dump_test "brr_x_seg1"
+    run_dump_test "brr_x_seg2"
+    run_dump_test "imm_x_seg"
+    run_dump_test "reloc"
+}
diff --git a/ld/testsuite/lib/ld-lib.exp b/ld/testsuite/lib/ld-lib.exp
index 870cd12..1d112d6 100644
--- a/ld/testsuite/lib/ld-lib.exp
+++ b/ld/testsuite/lib/ld-lib.exp
@@ -1652,6 +1652,7 @@ proc check_shared_lib_support { } {
 	 && ![istarget rx-*-*]
 	 && ![istarget spu-*-*]
 	 && ![istarget v850*-*-*]
+	 && ![istarget visium-*-*]
 	 && ![istarget xstormy16-*-*]
 	 && ![istarget *-*-irix*]
 	 && ![istarget *-*-rtems] } {
-- 
1.7.7

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 3/6] Add Visium support to bfd
  2014-12-03 23:29 [PATCH 0/6] binutils port for the Visium Eric Botcazou
                   ` (2 preceding siblings ...)
  2014-12-03 23:36 ` [PATCH 4/6] Add Visium support to binutils Eric Botcazou
@ 2014-12-03 23:46 ` Eric Botcazou
  2014-12-04  0:45   ` Alan Modra
  2014-12-03 23:46 ` [PATCH 2/6] Add Visium support to opcodes Eric Botcazou
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 17+ messages in thread
From: Eric Botcazou @ 2014-12-03 23:46 UTC (permalink / raw)
  To: binutils; +Cc: Eric Botcazou

From: Eric Botcazou <ebotcazou@gcc.gnu.org>

bfd/ChangeLog

2014-12-03  Eric Botcazou  <ebotcazou@adacore.com>

	* config.bfd: Add Visium support.
	* configure.ac: Likewise.
	* configure: Regenerate.
	* Makefile.am (ALL_MACHINES): Add cpu-visium.lo.
	(ALL_MACHINES_CFILES): Add cpu-visium.c.
	(BFD32_BACKENDS): Add elf32-visium.lo.
	(BFD32_BACKENDS_CFILES): Add elf32-visium.c.
	* Makefile.in: Regenerate.
	* archures.c (DESCRIPTION): Add Visium support.
	(bfd_visium_arch): Declare.
	(bfd_archures_list): Add bfd_visium_arch.
	* reloc.c: Add Visium relocations.
	* targets.c (visium_elf32_vec): Declare.
	(_bfd_target_vector): Add visium_elf32_vec.
	* bfd-in2.h: Regenerate.
	* libbfd.h: Likewise.
	* cpu-visium.c: New file.
	* elf32-visium.c: Likewise.
	* po/SRC-POTFILES.in: Add cpu-visium.c and elf32-visium.c.

include/elf/ChangeLog

2014-12-03  Eric Botcazou  <ebotcazou@adacore.com>

	* common.h (EM_VISIUM): Define.
	* visium.h: New file.

---
 bfd/Makefile.am        |    4 +
 bfd/Makefile.in        |    6 +
 bfd/archures.c         |    4 +
 bfd/bfd-in2.h          |   11 +
 bfd/config.bfd         |    5 +
 bfd/configure          |    1 +
 bfd/configure.ac       |    1 +
 bfd/cpu-visium.c       |   41 ++
 bfd/elf32-visium.c     |  959 ++++++++++++++++++++++++++++++++++++++++++++++++
 bfd/libbfd.h           |    7 +
 bfd/po/SRC-POTFILES.in |    2 +
 bfd/reloc.c            |   17 +
 bfd/targets.c          |    3 +
 include/elf/common.h   |    1 +
 include/elf/visium.h   |   51 +++
 15 files changed, 1113 insertions(+), 0 deletions(-)
 create mode 100644 bfd/cpu-visium.c
 create mode 100644 bfd/elf32-visium.c
 create mode 100644 include/elf/visium.h

diff --git a/bfd/Makefile.am b/bfd/Makefile.am
index 6f64f06..cea3794 100644
--- a/bfd/Makefile.am
+++ b/bfd/Makefile.am
@@ -159,6 +159,7 @@ ALL_MACHINES = \
 	cpu-v850.lo \
 	cpu-v850_rh850.lo \
 	cpu-vax.lo \
+	cpu-visium.lo \
 	cpu-w65.lo \
 	cpu-we32k.lo \
 	cpu-xc16x.lo \
@@ -243,6 +244,7 @@ ALL_MACHINES_CFILES = \
 	cpu-v850.c \
 	cpu-v850_rh850.c \
 	cpu-vax.c \
+	cpu-visium.c \
 	cpu-w65.c \
 	cpu-we32k.c \
 	cpu-xc16x.c \
@@ -364,6 +366,7 @@ BFD32_BACKENDS = \
 	elf32-tilepro.lo \
 	elf32-v850.lo \
 	elf32-vax.lo \
+	elf32-visium.lo \
 	elf32-xc16x.lo \
 	elf32-xgate.lo \
 	elf32-xstormy16.lo \
@@ -551,6 +554,7 @@ BFD32_BACKENDS_CFILES = \
 	elf32-tilepro.c \
 	elf32-v850.c \
 	elf32-vax.c \
+	elf32-visium.c \
 	elf32-xc16x.c \
 	elf32-xgate.c \
 	elf32-xstormy16.c \
diff --git a/bfd/Makefile.in b/bfd/Makefile.in
index 2c385d5..fbad166 100644
--- a/bfd/Makefile.in
+++ b/bfd/Makefile.in
@@ -460,6 +460,7 @@ ALL_MACHINES = \
 	cpu-v850.lo \
 	cpu-v850_rh850.lo \
 	cpu-vax.lo \
+	cpu-visium.lo \
 	cpu-w65.lo \
 	cpu-we32k.lo \
 	cpu-xc16x.lo \
@@ -544,6 +545,7 @@ ALL_MACHINES_CFILES = \
 	cpu-v850.c \
 	cpu-v850_rh850.c \
 	cpu-vax.c \
+	cpu-visium.c \
 	cpu-w65.c \
 	cpu-we32k.c \
 	cpu-xc16x.c \
@@ -666,6 +668,7 @@ BFD32_BACKENDS = \
 	elf32-tilepro.lo \
 	elf32-v850.lo \
 	elf32-vax.lo \
+	elf32-visium.lo \
 	elf32-xc16x.lo \
 	elf32-xgate.lo \
 	elf32-xstormy16.lo \
@@ -853,6 +856,7 @@ BFD32_BACKENDS_CFILES = \
 	elf32-tilepro.c \
 	elf32-v850.c \
 	elf32-vax.c \
+	elf32-visium.c \
 	elf32-xc16x.c \
 	elf32-xgate.c \
 	elf32-xstormy16.c \
@@ -1371,6 +1375,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-v850.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-v850_rh850.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-vax.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-visium.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-w65.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-we32k.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-xc16x.Plo@am__quote@
@@ -1456,6 +1461,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-tilepro.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-v850.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-vax.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-visium.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-xc16x.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-xgate.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-xstormy16.Plo@am__quote@
diff --git a/bfd/archures.c b/bfd/archures.c
index 5e069b2..067e654 100644
--- a/bfd/archures.c
+++ b/bfd/archures.c
@@ -497,6 +497,8 @@ DESCRIPTION
 .#define bfd_mach_aarch64_ilp32	32
 .  bfd_arch_nios2,
 .#define bfd_mach_nios2	0
+.  bfd_arch_visium,	{* Visium *}
+.#define bfd_mach_visium	1
 .  bfd_arch_last
 .  };
 */
@@ -616,6 +618,7 @@ extern const bfd_arch_info_type bfd_tilepro_arch;
 extern const bfd_arch_info_type bfd_v850_arch;
 extern const bfd_arch_info_type bfd_v850_rh850_arch;
 extern const bfd_arch_info_type bfd_vax_arch;
+extern const bfd_arch_info_type bfd_visium_arch;
 extern const bfd_arch_info_type bfd_w65_arch;
 extern const bfd_arch_info_type bfd_we32k_arch;
 extern const bfd_arch_info_type bfd_xstormy16_arch;
@@ -702,6 +705,7 @@ static const bfd_arch_info_type * const bfd_archures_list[] =
     &bfd_v850_arch,
     &bfd_v850_rh850_arch,
     &bfd_vax_arch,
+    &bfd_visium_arch,
     &bfd_w65_arch,
     &bfd_we32k_arch,
     &bfd_xstormy16_arch,
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index ed7be29..94546b4 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -2284,6 +2284,8 @@ enum bfd_architecture
 #define bfd_mach_aarch64_ilp32 32
   bfd_arch_nios2,
 #define bfd_mach_nios2 0
+  bfd_arch_visium,     /* Visium */
+#define bfd_mach_visium        1
   bfd_arch_last
   };
 
@@ -6067,6 +6069,15 @@ assembler and not (currently) written to any object files.  */
 
 /* Adapteva EPIPHANY - 8 bit immediate for 16 bit mov instruction.  */
   BFD_RELOC_EPIPHANY_IMM8,
+
+/* Visium Relocations.  */
+  BFD_RELOC_VISIUM_HI16,
+  BFD_RELOC_VISIUM_LO16,
+  BFD_RELOC_VISIUM_IM16,
+  BFD_RELOC_VISIUM_REL16,
+  BFD_RELOC_VISIUM_HI16_PCREL,
+  BFD_RELOC_VISIUM_LO16_PCREL,
+  BFD_RELOC_VISIUM_IM16_PCREL,
   BFD_RELOC_UNUSED };
 
 typedef enum bfd_reloc_code_real bfd_reloc_code_real_type;
diff --git a/bfd/config.bfd b/bfd/config.bfd
index 7bcb92a..a9627f8 100644
--- a/bfd/config.bfd
+++ b/bfd/config.bfd
@@ -127,6 +127,7 @@ spu*)            targ_archs=bfd_spu_arch ;;
 tilegx*)	 targ_archs=bfd_tilegx_arch ;;
 tilepro*)	 targ_archs=bfd_tilepro_arch ;;
 v850*)		 targ_archs="bfd_v850_arch bfd_v850_rh850_arch" ;;
+visium*)	 targ_archs=bfd_visium_arch ;;
 x86_64*)	 targ_archs=bfd_i386_arch ;;
 xtensa*)	 targ_archs=bfd_xtensa_arch ;;
 xgate)		 targ_archs=bfd_xgate_arch ;;
@@ -1657,6 +1658,10 @@ case "${targ}" in
     targ_defvec=vax_elf32_vec
     ;;
 
+  visium-*-elf)
+    targ_defvec=visium_elf32_vec
+    ;;
+ 
   we32k-*-*)
     targ_defvec=we32k_coff_vec
     ;;
diff --git a/bfd/configure b/bfd/configure
index 86f58e2..3bb0cf7 100755
--- a/bfd/configure
+++ b/bfd/configure
@@ -15597,6 +15597,7 @@ do
     vax_aout_bsd_vec)		 tb="$tb vaxbsd.lo aout32.lo" ;;
     vax_aout_nbsd_vec)		 tb="$tb vaxnetbsd.lo aout32.lo" ;;
     vax_elf32_vec)		 tb="$tb elf32-vax.lo elf32.lo $elf" ;;
+    visium_elf32_vec)		 tb="$tb elf32-visium.lo elf32.lo $elf" ;;
     w65_coff_vec)		 tb="$tb coff-w65.lo reloc16.lo" ;;
     we32k_coff_vec)		 tb="$tb coff-we32k.lo" ;;
     x86_64_coff_vec)		 tb="$tb coff-x86_64.lo cofflink.lo"; target_size=64 ;;
diff --git a/bfd/configure.ac b/bfd/configure.ac
index ba98e39..f960740 100644
--- a/bfd/configure.ac
+++ b/bfd/configure.ac
@@ -998,6 +998,7 @@ do
     vax_aout_bsd_vec)		 tb="$tb vaxbsd.lo aout32.lo" ;;
     vax_aout_nbsd_vec)		 tb="$tb vaxnetbsd.lo aout32.lo" ;;
     vax_elf32_vec)		 tb="$tb elf32-vax.lo elf32.lo $elf" ;;
+    visium_elf32_vec)		 tb="$tb elf32-visium.lo elf32.lo $elf" ;;
     w65_coff_vec)		 tb="$tb coff-w65.lo reloc16.lo" ;;
     we32k_coff_vec)		 tb="$tb coff-we32k.lo" ;;
     x86_64_coff_vec)		 tb="$tb coff-x86_64.lo cofflink.lo"; target_size=64 ;;
diff --git a/bfd/cpu-visium.c b/bfd/cpu-visium.c
new file mode 100644
index 0000000..011bc40
--- /dev/null
+++ b/bfd/cpu-visium.c
@@ -0,0 +1,41 @@
+/* BFD support for the Visium processor.
+
+   Copyright (C) 2003-2014 Free Software Foundation, Inc.
+
+   This file is part of BFD, the Binary File Descriptor library.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street - Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+const bfd_arch_info_type bfd_visium_arch =
+{
+  32,				/* bits per word */
+  32,				/* bits per address */
+  8,				/* bits per byte */
+  bfd_arch_visium,		/* architecture */
+  bfd_mach_visium,		/* machine */
+  "visium",			/* architecture name */
+  "visium",			/* printable name */
+  2,				/* section align power */
+  TRUE,				/* the default ? */
+  bfd_default_compatible,	/* architecture comparison fn */
+  bfd_default_scan,		/* string to architecture convert fn */
+  bfd_arch_default_fill,	/* default fill */
+  NULL				/* next in list */
+};
diff --git a/bfd/elf32-visium.c b/bfd/elf32-visium.c
new file mode 100644
index 0000000..be276dd
--- /dev/null
+++ b/bfd/elf32-visium.c
@@ -0,0 +1,959 @@
+/* Visium-specific support for 32-bit ELF.
+
+   Copyright (C) 2003-2014 Free Software Foundation, Inc.
+
+   This file is part of BFD, the Binary File Descriptor library.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street - Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/visium.h"
+
+static reloc_howto_type *visium_reloc_type_lookup
+  (bfd *, bfd_reloc_code_real_type);
+static void visium_info_to_howto_rela (bfd *, arelent *, Elf_Internal_Rela *);
+static bfd_boolean visium_elf_relocate_section
+  (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
+   Elf_Internal_Rela *, Elf_Internal_Sym *, asection **);
+static asection *visium_elf_gc_mark_hook
+  (asection * sec, struct bfd_link_info *, Elf_Internal_Rela *,
+   struct elf_link_hash_entry *, Elf_Internal_Sym *);
+static bfd_boolean visium_elf_check_relocs
+  (bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *);
+static bfd_reloc_status_type visium_elf_howto_parity_reloc
+  (bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **);
+
+static reloc_howto_type visium_elf_howto_table[] = {
+  /* This reloc does nothing.  */
+  HOWTO (R_VISIUM_NONE,		/* type */
+	 0,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 32,			/* bitsize */
+	 FALSE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_bitfield,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* special_function */
+	 "R_VISIUM_NONE",	/* name */
+	 FALSE,			/* partial_inplace */
+	 0,			/* src_mask */
+	 0,			/* dst_mask */
+	 FALSE),		/* pcrel_offset */
+
+  /* A 8 bit absolute relocation.  */
+  HOWTO (R_VISIUM_8,		/* type */
+	 0,			/* rightshift */
+	 0,			/* size (0 = byte, 1 = short, 2 = long) */
+	 8,			/* bitsize */
+	 FALSE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_bitfield,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* special_function */
+	 "R_VISIUM_8",		/* name */
+	 FALSE,			/* partial_inplace */
+	 0x00,			/* src_mask */
+	 0xff,			/* dst_mask */
+	 FALSE),		/* pcrel_offset */
+
+  /* A 16 bit absolute relocation.  */
+  HOWTO (R_VISIUM_16,		/* type */
+	 0,			/* rightshift */
+	 1,			/* size (0 = byte, 1 = short, 2 = long) */
+	 16,			/* bitsize */
+	 FALSE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_bitfield,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* special_function */
+	 "R_VISIUM_16",		/* name */
+	 FALSE,			/* partial_inplace */
+	 0x0000,		/* src_mask */
+	 0xffff,		/* dst_mask */
+	 FALSE),		/* pcrel_offset */
+
+  /* A 32 bit absolute relocation.  */
+  HOWTO (R_VISIUM_32,		/* type */
+	 0,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 32,			/* bitsize */
+	 FALSE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_bitfield,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* special_function */
+	 "R_VISIUM_32",		/* name */
+	 FALSE,			/* partial_inplace */
+	 0x00000000,		/* src_mask */
+	 0xffffffff,		/* dst_mask */
+	 FALSE),		/* pcrel_offset */
+
+
+  /* A 8 bit PC relative relocation.  */
+  HOWTO (R_VISIUM_8_PCREL,		/* type */
+	 0,			/* rightshift */
+	 0,			/* size (0 = byte, 1 = short, 2 = long) */
+	 8,			/* bitsize */
+	 TRUE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_bitfield,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* special_function */
+	 "R_VISIUM_8_PCREL",	/* name */
+	 FALSE,			/* partial_inplace */
+	 0x00,			/* src_mask */
+	 0xff,			/* dst_mask */
+	 TRUE),			/* pcrel_offset */
+
+  /* A 16 bit PC relative relocation.  */
+  HOWTO (R_VISIUM_16_PCREL,	/* type */
+	 0,			/* rightshift */
+	 1,			/* size (0 = byte, 1 = short, 2 = long) */
+	 16,			/* bitsize */
+	 TRUE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_bitfield,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* special_function */
+	 "R_VISIUM_16_PCREL",	/* name */
+	 FALSE,			/* partial inplace */
+	 0x0000,		/* src_mask */
+	 0xffff,		/* dst_mask */
+	 TRUE),			/* pcrel_offset */
+
+  /* A 32-bit PC relative relocation.  */
+  HOWTO (R_VISIUM_32_PCREL,	/* type */
+	 0,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 32,			/* bitsize */
+	 TRUE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_bitfield,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* special_function */
+	 "R_VISIUM_32_PCREL",	/* name */
+	 FALSE,			/* partial_inplace */
+	 0,			/* src_mask */
+	 0xffffffff,		/* dst_mask */
+	 TRUE),			/* pcrel_offset */
+
+  /* A 16-bit PC word relative offset, relative to start of instruction
+     and always in the second half of the instruction.  */
+  HOWTO (R_VISIUM_PC16,		/* type */
+	 2,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 16,			/* bitsize */
+	 TRUE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_signed,	/* complain_on_overflow */
+	 visium_elf_howto_parity_reloc,	/* special_function */
+	 "R_VISIUM_PC16",	/* name */
+	 FALSE,			/* partial_inplace */
+	 0x00000000,		/* src_mask */
+	 0x0000ffff,		/* dst_mask */
+	 TRUE),			/* pcrel_offset */
+
+  /* The high 16 bits of symbol value.  */
+  HOWTO (R_VISIUM_HI16,		/* type */
+	 16,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 16,			/* bitsize */
+	 FALSE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_dont,	/* complain_on_overflow */
+	 visium_elf_howto_parity_reloc,	/* special_function */
+	 "R_VISIUM_HI16",	/* name */
+	 FALSE,			/* partial_inplace */
+	 0x00000000,		/* src_mask */
+	 0x0000ffff,		/* dst_mask */
+	 FALSE),		/* pcrel_offset */
+
+  /* The low 16 bits of symbol value.  */
+  HOWTO (R_VISIUM_LO16,		/* type */
+	 0,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 16,			/* bitsize */
+	 FALSE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_dont,	/* complain_on_overflow */
+	 visium_elf_howto_parity_reloc,	/* special_function */
+	 "R_VISIUM_LO16",	/* name */
+	 FALSE,			/* partial_inplace */
+	 0x00000000,		/* src_mask */
+	 0x0000ffff,		/* dst_mask */
+	 FALSE),		/* pcrel_offset */
+
+  /* A 16 bit immediate value.  */
+  HOWTO (R_VISIUM_IM16,		/* type */
+	 0,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 16,			/* bitsize */
+	 FALSE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_unsigned,	/* complain_on_overflow */
+	 visium_elf_howto_parity_reloc,	/* special_function */
+	 "R_VISIUM_IM16",	/* name */
+	 FALSE,			/* partial_inplace */
+	 0x0000000,		/* src_mask */
+	 0x000ffff,		/* dst_mask */
+	 FALSE),		/* pcrel_offset */
+
+  /* The high 16 bits of symbol value, pc relative.  */
+  HOWTO (R_VISIUM_HI16_PCREL,	/* type */
+	 16,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 16,			/* bitsize */
+	 TRUE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_dont,	/* complain_on_overflow */
+	 visium_elf_howto_parity_reloc,	/* special_function */
+	 "R_VISIUM_HI16_PCREL",	/* name */
+	 FALSE,			/* partial_inplace */
+	 0x00000000,		/* src_mask */
+	 0x0000ffff,		/* dst_mask */
+	 TRUE),			/* pcrel_offset */
+
+  /* The low 16 bits of symbol value, pc relative.  */
+  HOWTO (R_VISIUM_LO16_PCREL,	/* type */
+	 0,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 16,			/* bitsize */
+	 TRUE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_dont,	/* complain_on_overflow */
+	 visium_elf_howto_parity_reloc,	/* special_function */
+	 "R_VISIUM_LO16_PCREL",	/* name */
+	 FALSE,			/* partial_inplace */
+	 0x00000000,		/* src_mask */
+	 0x0000ffff,		/* dst_mask */
+	 TRUE),			/* pcrel_offset */
+
+  /* A 16 bit immediate value, pc relative.  */
+  HOWTO (R_VISIUM_IM16_PCREL,	/* type */
+	 0,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 16,			/* bitsize */
+	 TRUE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_unsigned,	/* complain_on_overflow */
+	 visium_elf_howto_parity_reloc,	/* special_function */
+	 "R_VISIUM_IM16_PCREL",	/* name */
+	 FALSE,			/* partial_inplace */
+	 0x0000000,		/* src_mask */
+	 0x000ffff,		/* dst_mask */
+	 TRUE),			/* pcrel_offset */
+
+};
+
+/* GNU extension to record C++ vtable hierarchy.  */
+static reloc_howto_type visium_elf_vtinherit_howto =
+  HOWTO (R_VISIUM_GNU_VTINHERIT,      /* type */
+	 0,			   /* rightshift */
+	 2,			   /* size (0 = byte, 1 = short, 2 = long) */
+	 0,			   /* bitsize */
+	 FALSE,			   /* pc_relative */
+	 0,			   /* bitpos */
+	 complain_overflow_dont,   /* complain_on_overflow */
+	 NULL,			   /* special_function */
+	 "R_VISIUM_GNU_VTINHERIT", /* name */
+	 FALSE,			   /* partial_inplace */
+	 0,			   /* src_mask */
+	 0,			   /* dst_mask */
+	 FALSE);		   /* pcrel_offset */
+
+/* GNU extension to record C++ vtable member usage.  */
+static reloc_howto_type visium_elf_vtentry_howto =
+  HOWTO (R_VISIUM_GNU_VTENTRY,	   /* type */
+	 0,			   /* rightshift */
+	 2,			   /* size (0 = byte, 1 = short, 2 = long) */
+	 0,			   /* bitsize */
+	 FALSE,			   /* pc_relative */
+	 0,			   /* bitpos */
+	 complain_overflow_dont,   /* complain_on_overflow */
+	 NULL,			   /* special_function */
+	 "R_VISIUM_GNU_VTENTRY",   /* name */
+	 FALSE,			   /* partial_inplace */
+	 0,			   /* src_mask */
+	 0,			   /* dst_mask */
+	 FALSE);		   /* pcrel_offset */
+
+/* Map BFD reloc types to VISIUM ELF reloc types.  */
+struct visium_reloc_map
+{
+  bfd_reloc_code_real_type bfd_reloc_val;
+  unsigned int visium_reloc_val;
+};
+
+static const struct visium_reloc_map visium_reloc_map[] = {
+  {BFD_RELOC_NONE, 		R_VISIUM_NONE},
+  {BFD_RELOC_8, 		R_VISIUM_8},
+  {BFD_RELOC_16,		R_VISIUM_16},
+  {BFD_RELOC_32, 		R_VISIUM_32},
+  {BFD_RELOC_8_PCREL,		R_VISIUM_8_PCREL},
+  {BFD_RELOC_16_PCREL,		R_VISIUM_16_PCREL},
+  {BFD_RELOC_32_PCREL,		R_VISIUM_32_PCREL},
+  {BFD_RELOC_VISIUM_REL16,	R_VISIUM_PC16},
+  {BFD_RELOC_VISIUM_HI16,	R_VISIUM_HI16},
+  {BFD_RELOC_VISIUM_LO16,	R_VISIUM_LO16},
+  {BFD_RELOC_VISIUM_IM16,	R_VISIUM_IM16},
+  {BFD_RELOC_VISIUM_HI16_PCREL,	R_VISIUM_HI16_PCREL},
+  {BFD_RELOC_VISIUM_LO16_PCREL,	R_VISIUM_LO16_PCREL},
+  {BFD_RELOC_VISIUM_IM16_PCREL,	R_VISIUM_IM16_PCREL},
+  {BFD_RELOC_VTABLE_INHERIT,	R_VISIUM_GNU_VTINHERIT},
+  {BFD_RELOC_VTABLE_ENTRY,	R_VISIUM_GNU_VTENTRY},
+};
+
+static bfd_vma
+visium_set_even_parity (bfd_vma insn)
+{
+  bfd_vma p = 0;
+  int i;
+
+  for (i = 0; i < 31; i++)
+    {
+      p += insn & 1;
+      insn >>= 1;
+    }
+
+  return p << 31;
+}
+
+/* This "special function" will only be used when the input and
+   output files have different formats ie. when generating S-records
+   directly using "--oformat srec". Otherwise we use
+   _bfd_final_link_relocate which uses a howto structure, but does
+   not use the special_function field.
+
+   It sets instruction parity to even. This cannot be done by a howto.  */
+
+static bfd_reloc_status_type
+visium_elf_howto_parity_reloc (bfd * input_bfd, arelent *reloc_entry,
+			       asymbol *symbol, PTR data,
+			       asection *input_section, bfd *output_bfd,
+			       char **error_message ATTRIBUTE_UNUSED)
+{
+  bfd_reloc_status_type ret;
+  bfd_vma relocation;
+  bfd_byte *inplace_address;
+  bfd_vma insn;
+  const bfd_vma signmask = 0xffff8000;
+
+  /* This part is from bfd_elf_generic_reloc.
+     If we're relocating, and this an external symbol, we don't want
+     to change anything.  */
+  if (output_bfd != (bfd *) NULL && (symbol->flags & BSF_SECTION_SYM) == 0)
+    {
+      reloc_entry->address += input_section->output_offset;
+      return bfd_reloc_ok;
+    }
+
+  /* Now do the reloc in the usual way.  */
+
+  /* Sanity check the address (offset in section).  */
+  if (reloc_entry->address > bfd_get_section_limit (input_bfd, input_section))
+    return bfd_reloc_outofrange;
+
+  ret = bfd_reloc_ok;
+  if (bfd_is_und_section (symbol->section) && output_bfd == (bfd *) NULL)
+    ret = bfd_reloc_undefined;
+
+  if (bfd_is_com_section (symbol->section) || output_bfd != (bfd *) NULL)
+    relocation = 0;
+  else
+    relocation = symbol->value;
+
+  /* Only do this for a final link.  */
+  if (output_bfd == (bfd *) NULL)
+    {
+      relocation += symbol->section->output_section->vma;
+      relocation += symbol->section->output_offset;
+    }
+
+  relocation += reloc_entry->addend;
+  inplace_address = (bfd_byte *) data + reloc_entry->address;
+  insn = bfd_get_32 (input_bfd, inplace_address);
+
+  if (reloc_entry->howto->pc_relative)
+    {
+      relocation -= input_section->output_section->vma
+	+ input_section->output_offset;
+      relocation -= reloc_entry->address;
+    }
+
+  switch (reloc_entry->howto->type)
+    {
+    case R_VISIUM_PC16:
+      relocation >>= 2;
+      if (ret == bfd_reloc_ok && (relocation & signmask) != 0
+	  && (relocation & signmask) != signmask)
+	ret = bfd_reloc_overflow;
+      relocation &= 0xffff;
+      break;
+    case R_VISIUM_HI16:
+    case R_VISIUM_HI16_PCREL:
+      relocation = (relocation >> 16) & 0xffff;
+      break;
+    case R_VISIUM_LO16:
+    case R_VISIUM_LO16_PCREL:
+      relocation &= 0xffff;
+      break;
+    case R_VISIUM_IM16:
+    case R_VISIUM_IM16_PCREL:
+      if (ret == bfd_reloc_ok && (relocation & 0xffff0000) != 0)
+	ret = bfd_reloc_overflow;
+      relocation &= 0xffff;
+      break;
+    }
+  insn = (insn & 0x7fff0000) | relocation;
+  insn |= visium_set_even_parity (insn);
+  bfd_put_32 (input_bfd, insn, inplace_address);
+
+  if (output_bfd != (bfd *) NULL)
+    reloc_entry->address += input_section->output_offset;
+
+  return ret;
+}
+
+static reloc_howto_type *
+visium_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+			  bfd_reloc_code_real_type code)
+{
+  /* Note that the visium_elf_howto_table is indexed by the R_
+     constants. Thus, the order that the howto records appear in the
+     table *must* match the order of the relocation types defined in
+     include/elf/visium.h.  */
+  switch (code)
+    {
+    case BFD_RELOC_NONE:
+      return &visium_elf_howto_table[(int) R_VISIUM_NONE];
+    case BFD_RELOC_8:
+      return &visium_elf_howto_table[(int) R_VISIUM_8];
+    case BFD_RELOC_16:
+      return &visium_elf_howto_table[(int) R_VISIUM_16];
+    case BFD_RELOC_32:
+      return &visium_elf_howto_table[(int) R_VISIUM_32];
+    case BFD_RELOC_8_PCREL:
+      return &visium_elf_howto_table[(int) R_VISIUM_8_PCREL];
+    case BFD_RELOC_16_PCREL:
+      return &visium_elf_howto_table[(int) R_VISIUM_16_PCREL];
+    case BFD_RELOC_32_PCREL:
+      return &visium_elf_howto_table[(int) R_VISIUM_32_PCREL];
+    case BFD_RELOC_VISIUM_REL16:
+      return &visium_elf_howto_table[(int) R_VISIUM_PC16];
+    case BFD_RELOC_VISIUM_HI16:
+      return &visium_elf_howto_table[(int) R_VISIUM_HI16];
+    case BFD_RELOC_VISIUM_LO16:
+      return &visium_elf_howto_table[(int) R_VISIUM_LO16];
+    case BFD_RELOC_VISIUM_IM16:
+      return &visium_elf_howto_table[(int) R_VISIUM_IM16];
+    case BFD_RELOC_VISIUM_HI16_PCREL:
+      return &visium_elf_howto_table[(int) R_VISIUM_HI16_PCREL];
+    case BFD_RELOC_VISIUM_LO16_PCREL:
+      return &visium_elf_howto_table[(int) R_VISIUM_LO16_PCREL];
+    case BFD_RELOC_VISIUM_IM16_PCREL:
+      return &visium_elf_howto_table[(int) R_VISIUM_IM16_PCREL];
+    case BFD_RELOC_VTABLE_INHERIT:
+      return &visium_elf_vtinherit_howto;
+    case BFD_RELOC_VTABLE_ENTRY:
+      return &visium_elf_vtentry_howto;
+    default:
+      /* Pacify gcc -Wall.  */
+      return NULL;
+    }
+}
+
+static reloc_howto_type *
+visium_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
+{
+  unsigned int i;
+
+  for (i = 0;
+       i < (sizeof (visium_elf_howto_table)
+	    / sizeof (visium_elf_howto_table[0])); i++)
+    if (visium_elf_howto_table[i].name != NULL
+	&& strcasecmp (visium_elf_howto_table[i].name, r_name) == 0)
+      return &visium_elf_howto_table[i];
+
+  if (strcasecmp (visium_elf_vtinherit_howto.name, r_name) == 0)
+    return &visium_elf_vtinherit_howto;
+  if (strcasecmp (visium_elf_vtentry_howto.name, r_name) == 0)
+    return &visium_elf_vtentry_howto;
+
+  return NULL;
+}
+
+/* Perform a single relocation.  By default we use the standard BFD
+   routines.  */
+
+static bfd_reloc_status_type
+visium_final_link_relocate (reloc_howto_type *howto, bfd *input_bfd,
+			    asection *input_section, bfd_byte *contents,
+			    Elf_Internal_Rela *rel, bfd_vma relocation)
+{
+  return _bfd_final_link_relocate (howto, input_bfd, input_section,
+				   contents, rel->r_offset,
+				   relocation, rel->r_addend);
+}
+
+/* Set the howto pointer for a VISIUM ELF reloc.  */
+
+static void
+visium_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr,
+			   Elf_Internal_Rela *dst)
+{
+  unsigned int r_type;
+
+  r_type = ELF32_R_TYPE (dst->r_info);
+  switch (r_type)
+    {
+    case R_VISIUM_GNU_VTINHERIT:
+      cache_ptr->howto = &visium_elf_vtinherit_howto;
+      break;
+
+    case R_VISIUM_GNU_VTENTRY:
+      cache_ptr->howto = &visium_elf_vtentry_howto;
+      break;
+
+    default:
+      cache_ptr->howto = &visium_elf_howto_table[r_type];
+      break;
+    }
+}
+
+/* Look through the relocs for a section during the first phase.
+   Since we don't do .gots or .plts, we just need to consider the
+   virtual table relocs for gc.  */
+
+static bfd_boolean
+visium_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
+			asection *sec, const Elf_Internal_Rela *relocs)
+{
+  Elf_Internal_Shdr *symtab_hdr;
+  struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
+  const Elf_Internal_Rela *rel;
+  const Elf_Internal_Rela *rel_end;
+
+  if (info->relocatable)
+    return TRUE;
+
+  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+  sym_hashes = elf_sym_hashes (abfd);
+  sym_hashes_end =
+    sym_hashes + symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
+  if (!elf_bad_symtab (abfd))
+    sym_hashes_end -= symtab_hdr->sh_info;
+
+  rel_end = relocs + sec->reloc_count;
+  for (rel = relocs; rel < rel_end; rel++)
+    {
+      struct elf_link_hash_entry *h;
+      unsigned long r_symndx;
+
+      r_symndx = ELF32_R_SYM (rel->r_info);
+      if (r_symndx < symtab_hdr->sh_info)
+	h = NULL;
+      else
+	{
+	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+	  while (h->root.type == bfd_link_hash_indirect
+		 || h->root.type == bfd_link_hash_warning)
+	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
+	}
+
+      switch (ELF32_R_TYPE (rel->r_info))
+	{
+	  /* This relocation describes the C++ object vtable hierarchy.
+	     Reconstruct it for later use during GC.  */
+	case R_VISIUM_GNU_VTINHERIT:
+	  if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
+	    return FALSE;
+	  break;
+
+	  /* This relocation describes which C++ vtable entries are actually
+	     used.  Record for later use during GC.  */
+	case R_VISIUM_GNU_VTENTRY:
+	  if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+	    return FALSE;
+	  break;
+	}
+    }
+
+  return TRUE;
+}
+
+/* Relocate a VISIUM ELF section.
+
+   There is some attempt to make this function usable for many architectures,
+   both USE_REL and USE_RELA ['twould be nice if such a critter existed],
+   if only to serve as a learning tool.
+
+   The RELOCATE_SECTION function is called by the new ELF backend linker
+   to handle the relocations for a section.
+
+   The relocs are always passed as Rela structures; if the section
+   actually uses Rel structures, the r_addend field will always be
+   zero.
+
+   This function is responsible for adjusting the section contents as
+   necessary, and (if using Rela relocs and generating a relocatable
+   output file) adjusting the reloc addend as necessary.
+
+   This function does not have to worry about setting the reloc
+   address or the reloc symbol index.
+
+   LOCAL_SYMS is a pointer to the swapped in local symbols.
+
+   LOCAL_SECTIONS is an array giving the section in the input file
+   corresponding to the st_shndx field of each local symbol.
+
+   The global hash table entry for the global symbols can be found
+   via elf_sym_hashes (input_bfd).
+
+   When generating relocatable output, this function must handle
+   STB_LOCAL/STT_SECTION symbols specially.  The output symbol is
+   going to be the section symbol corresponding to the output
+   section, which means that the addend must be adjusted
+   accordingly.  */
+
+static bfd_boolean
+visium_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
+			     struct bfd_link_info *info, bfd *input_bfd,
+			     asection *input_section, bfd_byte *contents,
+			     Elf_Internal_Rela *relocs,
+			     Elf_Internal_Sym *local_syms,
+			     asection **local_sections)
+{
+  Elf_Internal_Shdr *symtab_hdr;
+  struct elf_link_hash_entry **sym_hashes;
+  Elf_Internal_Rela *rel;
+  Elf_Internal_Rela *relend;
+
+  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+  sym_hashes = elf_sym_hashes (input_bfd);
+  relend = relocs + input_section->reloc_count;
+
+  for (rel = relocs; rel < relend; rel++)
+    {
+      reloc_howto_type *howto;
+      unsigned long r_symndx;
+      Elf_Internal_Sym *sym;
+      asection *sec;
+      struct elf_link_hash_entry *h;
+      bfd_vma relocation;
+      bfd_reloc_status_type r;
+      const char *name = NULL;
+      int r_type;
+      bfd_vma insn;
+
+      r_type = ELF32_R_TYPE (rel->r_info);
+
+      if (r_type == R_VISIUM_GNU_VTINHERIT || r_type == R_VISIUM_GNU_VTENTRY)
+	continue;
+
+      r_symndx = ELF32_R_SYM (rel->r_info);
+
+      howto = visium_elf_howto_table + ELF32_R_TYPE (rel->r_info);
+      h = NULL;
+      sym = NULL;
+      sec = NULL;
+
+      if (r_symndx < symtab_hdr->sh_info)
+	{
+	  /* This is a local symbol.  */
+	  sym = local_syms + r_symndx;
+	  sec = local_sections[r_symndx];
+	  relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
+
+	  name = bfd_elf_string_from_elf_section
+	    (input_bfd, symtab_hdr->sh_link, sym->st_name);
+	  name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
+	}
+      else
+	{
+	  bfd_boolean unresolved_reloc;
+	  bfd_boolean warned, ignored;
+
+	  RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+				   r_symndx, symtab_hdr, sym_hashes,
+				   h, sec, relocation,
+				   unresolved_reloc, warned, ignored);
+
+	  name = h->root.root.string;
+	}
+
+      if (sec != NULL && discarded_section (sec))
+	{
+	  /* For relocs against symbols from removed linkonce sections,
+	     or sections discarded by a linker script, we just want the
+	     section contents zeroed.  Avoid any special processing.  */
+	  _bfd_clear_contents (howto, input_bfd, input_section,
+			       contents + rel->r_offset);
+
+	  rel->r_info = 0;
+	  rel->r_addend = 0;
+	  continue;
+	}
+
+      if (info->relocatable)
+	continue;
+
+      switch (r_type)
+	{
+	case R_VISIUM_PC16:
+	case R_VISIUM_HI16:
+	case R_VISIUM_LO16:
+	case R_VISIUM_IM16:
+	case R_VISIUM_HI16_PCREL:
+	case R_VISIUM_LO16_PCREL:
+	case R_VISIUM_IM16_PCREL:
+	  r = visium_final_link_relocate (howto, input_bfd, input_section,
+				       contents, rel, relocation);
+	  /* For instruction relocations, the parity needs correcting.  */
+	  if (r == bfd_reloc_ok)
+	    {
+	      insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
+	      insn = (insn & 0x7fffffff) | visium_set_even_parity (insn);
+	      bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
+	    }
+	  break;
+
+	default:
+	  r = visium_final_link_relocate (howto, input_bfd, input_section,
+				       contents, rel, relocation);
+	  break;
+	}
+
+      if (r != bfd_reloc_ok)
+	{
+	  const char *msg = (const char *) NULL;
+
+	  switch (r)
+	    {
+	    case bfd_reloc_overflow:
+	      r = info->callbacks->reloc_overflow
+		(info, (h ? &h->root : NULL), name, howto->name, (bfd_vma) 0,
+		 input_bfd, input_section, rel->r_offset);
+	      break;
+
+	    case bfd_reloc_undefined:
+	      r = info->callbacks->undefined_symbol
+		(info, name, input_bfd, input_section, rel->r_offset, TRUE);
+	      break;
+
+	    case bfd_reloc_outofrange:
+	      msg = _("internal error: out of range error");
+	      break;
+
+	    case bfd_reloc_notsupported:
+	      msg = _("internal error: unsupported relocation error");
+	      break;
+
+	    case bfd_reloc_dangerous:
+	      msg = _("internal error: dangerous relocation");
+	      break;
+
+	    default:
+	      msg = _("internal error: unknown error");
+	      break;
+	    }
+
+	  if (msg)
+	    r = info->callbacks->warning
+	      (info, msg, name, input_bfd, input_section, rel->r_offset);
+
+	  if (!r)
+	    return FALSE;
+	}
+    }
+
+  return TRUE;
+}
+
+/* This function is called during section gc to discover the section a
+   to which a particular relocation refers.  */
+
+/* Return the section that should be marked against GC for a given
+   relocation.  */
+
+static asection *
+visium_elf_gc_mark_hook (asection *sec, struct bfd_link_info *info,
+			 Elf_Internal_Rela *rel, struct elf_link_hash_entry *h,
+			 Elf_Internal_Sym *sym)
+{
+  if (h != NULL)
+    switch (ELF32_R_TYPE (rel->r_info))
+      {
+      case R_VISIUM_GNU_VTINHERIT:
+      case R_VISIUM_GNU_VTENTRY:
+	return NULL;
+      }
+
+  return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
+}
+
+static void
+visium_elf_post_process_headers (bfd *abfd,
+				 struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+  Elf_Internal_Ehdr *i_ehdrp;	/* ELF file header, internal form.  */
+
+  i_ehdrp = elf_elfheader (abfd);
+  i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_STANDALONE;
+  i_ehdrp->e_ident[EI_ABIVERSION] = 1;
+}
+
+/* Function to set the ELF flag bits.  */
+
+static bfd_boolean
+visium_elf_set_private_flags (bfd *abfd, flagword flags)
+{
+  elf_elfheader (abfd)->e_flags = flags;
+  elf_flags_init (abfd) = TRUE;
+  return TRUE;
+}
+
+/* Copy backend specific data from one object module to another.  */
+
+static bfd_boolean
+visium_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
+{
+  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
+    return TRUE;
+
+  BFD_ASSERT (!elf_flags_init (obfd)
+	      || elf_elfheader (obfd)->e_flags ==
+	      elf_elfheader (ibfd)->e_flags);
+
+  elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
+  elf_flags_init (obfd) = TRUE;
+
+  /* Copy object attributes.  */
+  _bfd_elf_copy_obj_attributes (ibfd, obfd);
+
+  return TRUE;
+}
+
+/* Merge backend specific data from an object
+   file to the output object file when linking.  */
+
+static bfd_boolean
+visium_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
+{
+  flagword old_flags;
+  flagword new_flags;
+  flagword mismatch;
+  const char *opt_arch = NULL;
+  const char *new_opt_with = NULL;
+  const char *old_opt_with = NULL;
+  const char *with = "with";
+  const char *without = "without";
+  const char *mcm = "mcm";
+  const char *mcm24 = "mcm24";
+  const char *gr6 = "gr6";
+
+  new_flags = elf_elfheader (ibfd)->e_flags;
+  old_flags = elf_elfheader (obfd)->e_flags;
+
+  if (!elf_flags_init (obfd))
+    {
+      /* First call, no flags set.  */
+      elf_flags_init (obfd) = TRUE;
+      elf_elfheader (obfd)->e_flags = new_flags;
+    }
+  else
+    {
+      mismatch = (new_flags ^ old_flags)
+	& (EF_VISIUM_ARCH_MCM | EF_VISIUM_ARCH_MCM24 | EF_VISIUM_ARCH_GR6);
+      if (mismatch & EF_VISIUM_ARCH_GR6)
+	{
+	  opt_arch = gr6;
+	  new_opt_with = new_flags & EF_VISIUM_ARCH_GR6 ? with : without;
+	  old_opt_with = old_flags & EF_VISIUM_ARCH_GR6 ? with : without;
+	}
+      else if (mismatch & EF_VISIUM_ARCH_MCM)
+	{
+	  opt_arch = mcm;
+	  new_opt_with = new_flags & EF_VISIUM_ARCH_MCM ? with : without;
+	  old_opt_with = old_flags & EF_VISIUM_ARCH_MCM ? with : without;
+	}
+      else if (mismatch & EF_VISIUM_ARCH_MCM24)
+	{
+	  opt_arch = mcm24;
+	  new_opt_with = new_flags & EF_VISIUM_ARCH_MCM24 ? with : without;
+	  old_opt_with = old_flags & EF_VISIUM_ARCH_MCM24 ? with : without;
+	}
+
+      if (mismatch)
+	_bfd_error_handler
+	  (_
+	   ("%s: compiled %s -mtune=%s and linked with modules"
+	    " compiled %s -mtune=%s"),
+	   bfd_get_filename (ibfd), new_opt_with, opt_arch, old_opt_with,
+	   opt_arch);
+    }
+
+  return TRUE;
+}
+
+static bfd_boolean
+visium_elf_print_private_bfd_data (bfd *abfd, void *ptr)
+{
+  FILE *file = (FILE *) ptr;
+  flagword flags;
+
+  BFD_ASSERT (abfd != NULL && ptr != NULL);
+
+  /* Print normal ELF private data.  */
+  _bfd_elf_print_private_bfd_data (abfd, ptr);
+
+  flags = elf_elfheader (abfd)->e_flags;
+  fprintf (file, _("private flags = 0x%lx:"), (long) flags);
+
+  if (flags & EF_VISIUM_ARCH_GR6)
+    fprintf (file, " -mtune=gr6");
+  else if (flags & EF_VISIUM_ARCH_MCM)
+    fprintf (file, " -mtune=mcm");
+  else if (flags & EF_VISIUM_ARCH_MCM24)
+    fprintf (file, " -mtune=mcm24");
+
+  fputc ('\n', file);
+  return TRUE;
+}
+
+#define ELF_ARCH		bfd_arch_visium
+#define ELF_MACHINE_CODE	EM_VISIUM
+#define ELF_MAXPAGESIZE		1
+
+#define TARGET_BIG_SYM		visium_elf32_vec
+#define TARGET_BIG_NAME		"elf32-visium"
+
+#define elf_info_to_howto_rel			NULL
+#define elf_info_to_howto			visium_info_to_howto_rela
+#define elf_backend_relocate_section		visium_elf_relocate_section
+#define elf_backend_gc_mark_hook		visium_elf_gc_mark_hook
+#define elf_backend_check_relocs		visium_elf_check_relocs
+#define elf_backend_rela_normal			1
+
+#define elf_backend_can_gc_sections		1
+
+#define bfd_elf32_bfd_reloc_type_lookup		visium_reloc_type_lookup
+#define bfd_elf32_bfd_reloc_name_lookup		visium_reloc_name_lookup
+
+#define bfd_elf32_bfd_set_private_flags		visium_elf_set_private_flags
+#define bfd_elf32_bfd_copy_private_bfd_data	visium_elf_copy_private_bfd_data
+#define bfd_elf32_bfd_merge_private_bfd_data	visium_elf_merge_private_bfd_data
+#define bfd_elf32_bfd_print_private_bfd_data	visium_elf_print_private_bfd_data
+#define elf_backend_post_process_headers	visium_elf_post_process_headers
+
+#include "elf32-target.h"
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index a1923c8..14ee8c6 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -2955,6 +2955,13 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
   "BFD_RELOC_EPIPHANY_SIMM11",
   "BFD_RELOC_EPIPHANY_IMM11",
   "BFD_RELOC_EPIPHANY_IMM8",
+  "BFD_RELOC_VISIUM_HI16",
+  "BFD_RELOC_VISIUM_LO16",
+  "BFD_RELOC_VISIUM_IM16",
+  "BFD_RELOC_VISIUM_REL16",
+  "BFD_RELOC_VISIUM_HI16_PCREL",
+  "BFD_RELOC_VISIUM_LO16_PCREL",
+  "BFD_RELOC_VISIUM_IM16_PCREL",
  "@@overflow: BFD_RELOC_UNUSED@@",
 };
 #endif
diff --git a/bfd/po/SRC-POTFILES.in b/bfd/po/SRC-POTFILES.in
index 3e5cbd0..169412f 100644
--- a/bfd/po/SRC-POTFILES.in
+++ b/bfd/po/SRC-POTFILES.in
@@ -134,6 +134,7 @@ cpu-tilepro.c
 cpu-v850.c
 cpu-v850_rh850.c
 cpu-vax.c
+cpu-visium.c
 cpu-w65.c
 cpu-we32k.c
 cpu-xc16x.c
@@ -222,6 +223,7 @@ elf32-tilegx.c
 elf32-tilepro.c
 elf32-v850.c
 elf32-vax.c
+elf32-visium.c
 elf32-xc16x.c
 elf32-xgate.c
 elf32-xstormy16.c
diff --git a/bfd/reloc.c b/bfd/reloc.c
index 89e46f3..d902a9b 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -7301,6 +7301,7 @@ ENUMX
   BFD_RELOC_TILEGX_IMM8_Y1_TLS_ADD
 ENUMDOC
   Tilera TILE-Gx Relocations.
+
 ENUM
   BFD_RELOC_EPIPHANY_SIMM8
 ENUMDOC
@@ -7330,6 +7331,22 @@ ENUM
 ENUMDOC
   Adapteva EPIPHANY - 8 bit immediate for 16 bit mov instruction.
 
+ENUM
+  BFD_RELOC_VISIUM_HI16
+ENUMX
+  BFD_RELOC_VISIUM_LO16
+ENUMX
+  BFD_RELOC_VISIUM_IM16
+ENUMX
+  BFD_RELOC_VISIUM_REL16
+ENUMX
+  BFD_RELOC_VISIUM_HI16_PCREL
+ENUMX
+  BFD_RELOC_VISIUM_LO16_PCREL
+ENUMX
+  BFD_RELOC_VISIUM_IM16_PCREL
+ENUMDOC
+  Visium Relocations.
 
 ENDSENUM
   BFD_RELOC_UNUSED
diff --git a/bfd/targets.c b/bfd/targets.c
index 6a282ea..71e59e0 100644
--- a/bfd/targets.c
+++ b/bfd/targets.c
@@ -876,6 +876,7 @@ extern const bfd_target vax_aout_1knbsd_vec;
 extern const bfd_target vax_aout_bsd_vec;
 extern const bfd_target vax_aout_nbsd_vec;
 extern const bfd_target vax_elf32_vec;
+extern const bfd_target visium_elf32_vec;
 extern const bfd_target w65_coff_vec;
 extern const bfd_target we32k_coff_vec;
 extern const bfd_target x86_64_coff_vec;
@@ -1385,6 +1386,8 @@ static const bfd_target * const _bfd_target_vector[] =
 	&vax_aout_nbsd_vec,
 	&vax_elf32_vec,
 
+	&visium_elf32_vec,
+
 	&w65_coff_vec,
 
 	&we32k_coff_vec,
diff --git a/include/elf/common.h b/include/elf/common.h
index e8ae3ac..1d68f80 100644
--- a/include/elf/common.h
+++ b/include/elf/common.h
@@ -301,6 +301,7 @@
 #define EM_INTEL207	207	/* Reserved by Intel */
 #define EM_INTEL208	208	/* Reserved by Intel */
 #define EM_INTEL209	209	/* Reserved by Intel */
+#define EM_VISIUM	221	/* Controls and Data Services VISIUMcore processor */
 
 /* If it is necessary to assign new unofficial EM_* values, please pick large
    random numbers (0x8523, 0xa7f2, etc.) to minimize the chances of collision
diff --git a/include/elf/visium.h b/include/elf/visium.h
new file mode 100644
index 0000000..8de57a6
--- /dev/null
+++ b/include/elf/visium.h
@@ -0,0 +1,51 @@
+/* Visium ELF support for BFD.
+
+   Copyright (C) 2002-2014 Free Software Foundation, Inc.
+
+   This file is part of BFD, the Binary File Descriptor library.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+#ifndef _ELF_VISIUM_H
+#define _ELF_VISIUM_H
+
+#include "elf/reloc-macros.h"
+
+/* Processor specific flags for the ELF header e_flags field.  */
+#define EF_VISIUM_ARCH_MCM   0x01
+#define EF_VISIUM_ARCH_MCM24 0x02
+#define EF_VISIUM_ARCH_GR6   0x04
+
+/* Relocations.  */
+START_RELOC_NUMBERS (elf_visium_reloc_type)
+  RELOC_NUMBER (R_VISIUM_NONE, 0)
+  RELOC_NUMBER (R_VISIUM_8, 1)
+  RELOC_NUMBER (R_VISIUM_16, 2)
+  RELOC_NUMBER (R_VISIUM_32, 3)
+  RELOC_NUMBER (R_VISIUM_8_PCREL, 4)
+  RELOC_NUMBER (R_VISIUM_16_PCREL, 5)
+  RELOC_NUMBER (R_VISIUM_32_PCREL, 6)
+  RELOC_NUMBER (R_VISIUM_PC16, 7)
+  RELOC_NUMBER (R_VISIUM_HI16, 8)
+  RELOC_NUMBER (R_VISIUM_LO16, 9)
+  RELOC_NUMBER (R_VISIUM_IM16, 10)
+  RELOC_NUMBER (R_VISIUM_HI16_PCREL, 11)
+  RELOC_NUMBER (R_VISIUM_LO16_PCREL, 12)
+  RELOC_NUMBER (R_VISIUM_IM16_PCREL, 13)
+  RELOC_NUMBER (R_VISIUM_GNU_VTINHERIT, 200)
+  RELOC_NUMBER (R_VISIUM_GNU_VTENTRY, 201)
+END_RELOC_NUMBERS(R_VISIUM_max)
+
+#endif /* _ELF_VISIUM_H */
-- 
1.7.7

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 2/6] Add Visium support to opcodes
  2014-12-03 23:29 [PATCH 0/6] binutils port for the Visium Eric Botcazou
                   ` (3 preceding siblings ...)
  2014-12-03 23:46 ` [PATCH 3/6] Add Visium support to bfd Eric Botcazou
@ 2014-12-03 23:46 ` Eric Botcazou
  2014-12-04  0:48 ` [PATCH 0/6] binutils port for the Visium Alan Modra
  2014-12-04 12:09 ` [PATCH 5/6] Add Visium support to gas Eric Botcazou
  6 siblings, 0 replies; 17+ messages in thread
From: Eric Botcazou @ 2014-12-03 23:46 UTC (permalink / raw)
  To: binutils; +Cc: Eric Botcazou

From: Eric Botcazou <ebotcazou@gcc.gnu.org>

include/ChangeLog

2014-12-03  Eric Botcazou  <ebotcazou@adacore.com>

	* dis-asm.h (print_insn_visium): Declare.

include/opcode/ChangeLog

2014-12-03  Eric Botcazou  <ebotcazou@adacore.com>

	* visium.h: New file.

opcodes/ChangeLog

2014-12-03  Eric Botcazou  <ebotcazou@adacore.com>

	* configure.ac: Add Visium support.
	* configure: Regenerate.
	* Makefile.am (TARGET_LIBOPCODES_CFILES): Add visium-dis.c and
	visium-opc.c.
	* Makefile.in: Regenerate.
	* disassemble.c (ARCH_visium): Define if ARCH_all.
	(disassembler): Deal with bfd_arch_visium if ARCH_visium.
	* visium-dis.c: New file.
	* visium-opc.c: Likewise.
	* po/POTFILES.in: Add visium-dis.c and visium-opc.c.

---
 include/dis-asm.h       |    1 +
 include/opcode/visium.h |  337 +++++++++++++++++++
 opcodes/Makefile.am     |    2 +
 opcodes/Makefile.in     |    4 +
 opcodes/configure       |    1 +
 opcodes/configure.ac    |    1 +
 opcodes/disassemble.c   |    6 +
 opcodes/po/POTFILES.in  |    2 +
 opcodes/visium-dis.c    |  834 +++++++++++++++++++++++++++++++++++++++++++++++
 opcodes/visium-opc.c    |   23 ++
 10 files changed, 1211 insertions(+), 0 deletions(-)
 create mode 100644 include/opcode/visium.h
 create mode 100644 opcodes/visium-dis.c
 create mode 100644 opcodes/visium-opc.c

diff --git a/include/dis-asm.h b/include/dis-asm.h
index 1b653b5..7260d59 100644
--- a/include/dis-asm.h
+++ b/include/dis-asm.h
@@ -295,6 +295,7 @@ extern int print_insn_tilegx		(bfd_vma, disassemble_info *);
 extern int print_insn_tilepro		(bfd_vma, disassemble_info *);
 extern int print_insn_v850		(bfd_vma, disassemble_info *);
 extern int print_insn_vax		(bfd_vma, disassemble_info *);
+extern int print_insn_visium		(bfd_vma, disassemble_info *);
 extern int print_insn_w65		(bfd_vma, disassemble_info *);
 extern int print_insn_xc16x		(bfd_vma, disassemble_info *);
 extern int print_insn_xgate             (bfd_vma, disassemble_info *);
diff --git a/include/opcode/visium.h b/include/opcode/visium.h
new file mode 100644
index 0000000..037439d
--- /dev/null
+++ b/include/opcode/visium.h
@@ -0,0 +1,337 @@
+/* Opcode table header for Visium.
+
+   Copyright (C) 2003-2014 Free Software Foundation.
+
+   This file is part of GDB, GAS, and GNU binutils.
+
+   GDB, GAS and the GNU binutils are free software; you can redistribute
+   them and/or modify them under the terms of the GNU General Public
+   License as published by the Free Software Foundation; either version 3,
+   or (at your option) any later version.
+
+   GDB, GAS, and the GNU binutils are distributed in the hope that they
+   will be useful, but WITHOUT ANY WARRANTY; without even the implied
+   warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+   the GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this file; see the file COPYING3.  If not, write to the Free
+   Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+enum visium_opcode_arch_val
+{
+  VISIUM_OPCODE_ARCH_DEF = 0,
+  VISIUM_OPCODE_ARCH_GR5,
+  VISIUM_OPCODE_ARCH_GR6,
+  VISIUM_OPCODE_ARCH_BAD
+};
+
+/* The highest architecture in the table.  */
+#define VISIUM_OPCODE_ARCH_MAX (VISIUM_OPCODE_ARCH_BAD - 1)
+
+/* Given an enum visium_opcode_arch_val, return the bitmask to use in
+   insn encoding/decoding.  */
+#define VISIUM_OPCODE_ARCH_MASK(arch) (1 << (arch))
+
+/* Some defines to make life easy.  */
+#define MASK_DEF VISIUM_OPCODE_ARCH_MASK (VISIUM_OPCODE_ARCH_DEF)
+#define MASK_GR5 VISIUM_OPCODE_ARCH_MASK (VISIUM_OPCODE_ARCH_GR5)
+#define MASK_GR6 VISIUM_OPCODE_ARCH_MASK (VISIUM_OPCODE_ARCH_GR6)
+
+/* Bit masks of architectures supporting the insn.  */
+#define def (MASK_DEF | MASK_GR5 | MASK_GR6)
+#define gr5 (MASK_GR5 | MASK_GR6)
+#define gr6 (MASK_GR6)
+
+/* The condition code field is not used (zero) for most instructions.
+   BRR and BRA make normal use of it. Floating point instructions use
+   it as a sub-opcode.  */
+#define CC_MASK (0xf << 27)
+
+/* It seems a shame not to use these bits in a class 0 instruction,
+   since they could be used to extend the range of the branch.  */
+#define CLASS0_UNUSED_MASK (0x1f << 16)
+
+/* For class 1 instructions the following bit is unused.  */
+#define CLASS1_UNUSED_MASK (1 << 9)
+
+/* For class 1 instructions this field gives the index for a write
+   instruction, the specific operation for an EAM instruction, or
+   the floating point destination register for a floating point
+   instruction.  */
+#define CLASS1_INDEX_MASK (0x1f << 10)
+
+/* For class 3 instructions the following field gives the destination
+   general register.  */
+#define CLASS3_DEST_MASK (0x1f << 10)
+
+/* For class 1 and class 3 instructions the following bit selects an
+   EAM write/read rather than a memory write/read.  */
+#define EAM_SELECT_MASK (1 << 15)
+
+/* Floating point instructions are distinguished from general EAM
+   instructions by the following bit.  */
+#define FP_SELECT_MASK (1 << 3)
+
+/* For both class 1 and class 3 the following fields give, where
+   appropriate the srcA and srcB registers whether floating point
+   or general.  */
+#define SRCA_MASK (0x1f << 16)
+#define SRCB_MASK (0x1f << 4)
+
+/* The class 3 interrupt bit. It turns a BRA into a SYS1, and an
+   RFLAG into a SYS2. This bit should not be set in the user's
+   class 3 instructions. This bit is also used in class 3
+   to distinguish between floating point and other EAM operations.
+   (see FP_SELECT_MASK).  */
+#define CLASS3_INT (1 << 3)
+
+/* Class 3 shift instructions use this bit to indicate that the
+   srcB field is a 5 bit immediate shift count rather than a
+   register number.  */
+#define CLASS3_SOURCEB_IMMED (1 << 9)
+
+#define BMD 0x02630004
+#define BMI 0x82230004
+#define DSI 0x82800004
+#define ENI 0x02a00004
+#define RFI 0x82fe01d4
+
+struct reg_entry
+{
+  char *name;
+  unsigned char code;
+};
+
+const struct reg_entry gen_reg_table[] =
+{
+  {"fp", 0x16},
+  {"r0", 0x0},
+  {"r1", 0x1},
+  {"r10", 0xA},
+  {"r11", 0xB},
+  {"r12", 0xC},
+  {"r13", 0xD},
+  {"r14", 0xE},
+  {"r15", 0xF},
+  {"r16", 0x10},
+  {"r17", 0x11},
+  {"r18", 0x12},
+  {"r19", 0x13},
+  {"r2", 0x2},
+  {"r20", 0x14},
+  {"r21", 0x15},
+  {"r22", 0x16},
+  {"r23", 0x17},
+  {"r24", 0x18},
+  {"r25", 0x19},
+  {"r26", 0x1a},
+  {"r27", 0x1b},
+  {"r28", 0x1c},
+  {"r29", 0x1d},
+  {"r3", 0x3},
+  {"r30", 0x1e},
+  {"r31", 0x1f},
+  {"r4", 0x4},
+  {"r5", 0x5},
+  {"r6", 0x6},
+  {"r7", 0x7},
+  {"r8", 0x8},
+  {"r9", 0x9},
+  {"sp", 0x17},
+};
+
+const struct reg_entry fp_reg_table[] =
+{
+  {"f0", 0x0},
+  {"f1", 0x1},
+  {"f10", 0xa},
+  {"f11", 0xb},
+  {"f12", 0xc},
+  {"f13", 0xd},
+  {"f14", 0xe},
+  {"f15", 0xf},
+  {"f2", 0x2},
+  {"f3", 0x3},
+  {"f4", 0x4},
+  {"f5", 0x5},
+  {"f6", 0x6},
+  {"f7", 0x7},
+  {"f8", 0x8},
+  {"f9", 0x9},
+};
+
+const struct cc_entry
+{
+  char *name;
+  int code;
+} cc_table [] =
+{
+  {"cc", 6},
+  {"cs", 2},
+  {"eq", 1},
+  {"fa", 0},
+  {"ge", 9},
+  {"gt", 10},
+  {"hi", 11},
+  {"le", 12},
+  {"ls", 13},
+  {"lt", 14},
+  {"nc", 8},
+  {"ne", 5},
+  {"ns", 4},
+  {"oc", 7},
+  {"os", 3},
+  {"tr", 15},
+};
+
+enum addressing_mode
+{
+  mode_d,	/* register := */
+  mode_a,	/* op= register */
+  mode_da,	/* register := register */
+  mode_ab,	/* register * register */
+  mode_dab,	/* register := register * register */
+  mode_iab,	/* 5-bit immediate * register * register */
+  mode_0ab,	/* zero * register * register */
+  mode_da0,	/* register := register * zero */
+  mode_cad,	/* condition * register * register */
+  mode_das,	/* register := register * 5-bit immed/register shift count */
+  mode_di,	/* register := 5-bit immediate */
+  mode_ir,	/* 5-bit immediate * register */
+  mode_ai,	/* register 16-bit unsigned immediate */
+  mode_i,	/* 16-bit unsigned immediate */
+  mode_bax,	/* register * register * 5-bit immediate */
+  mode_dax,	/* register := register * 5-bit immediate */
+  mode_s,	/* special mode */
+  mode_sr,	/* special mode with register */
+  mode_ci,	/* condition * 16-bit signed word displacement */
+  mode_fdab,	/* float := float * float */
+  mode_ifdab,	/* fpinst: 4-bit immediate * float * float * float */
+  mode_idfab,	/* fpuread: 4-bit immediate * register * float * float */
+  mode_fda,	/* float := float */
+  mode_fdra,	/* float := register */
+  mode_rdfab,	/* register := float * float */
+  mode_rdfa,	/* register := float */
+  mode_rrr,	/* 3 register sources and destinations (block move) */
+};
+
+#define class0 (0<<25)
+#define class1 (1<<25)
+#define class2 (2<<25)
+#define class3 (3<<25)
+
+static const struct opcode_entry
+{
+  char *mnem;
+  enum addressing_mode mode;
+  unsigned code;
+  char flags;
+}
+opcode_table[] =
+{
+  { "adc.b",    mode_dab,  class3|(1<<21)|(1), def },
+  { "adc.l",    mode_dab,  class3|(1<<21)|(4), def },
+  { "adc.w",    mode_dab,  class3|(1<<21)|(2), def },
+  { "add.b",    mode_dab,  class3|(0<<21)|(1), def },
+  { "add.l",    mode_dab,  class3|(0<<21)|(4), def },
+  { "add.w",    mode_dab,  class3|(0<<21)|(2), def },
+  { "addi",     mode_ai,   class2, def },
+  { "and.b",    mode_dab,  class3|(10<<21)|(1), def},
+  { "and.l",    mode_dab,  class3|(10<<21)|(4), def },
+  { "and.w",    mode_dab,  class3|(10<<21)|(2), def },
+  { "asl.b",    mode_das,  class3|(7<<21)|(1), def },
+  { "asl.l",    mode_das,  class3|(7<<21)|(4), def },
+  { "asl.w",    mode_das,  class3|(7<<21)|(2), def },
+  { "asld",     mode_a,    class1|(15<<21)|(1<<15)|(11<<10)|(4), def },
+  { "asr.b",    mode_das,  class3|(5<<21)|(1), def },
+  { "asr.l",    mode_das,  class3|(5<<21)|(4), def },
+  { "asr.w",    mode_das,  class3|(5<<21)|(2), def },
+  { "asrd",     mode_a,    class1|(15<<21)|(1<<15)|(9<<10)|(4), def },
+  { "bmd",      mode_rrr,  class1|(3<<21)|(3<<16)|(4), gr6 },
+  { "bmi",      mode_rrr,  class1|(1<<21)|(3<<16)|(4), gr6 }, 
+  { "bra",      mode_cad,  class3|(12<<21)|(4), def },
+  { "brr",      mode_ci,   class0, def },
+  { "cmp.b",    mode_0ab,  class3|(2<<21)|(1), def },
+  { "cmp.l",    mode_0ab,  class3|(2<<21)|(4), def },
+  { "cmp.w",    mode_0ab,  class3|(2<<21)|(2), def },
+  { "cmpc.b",   mode_0ab,  class3|(3<<21)|(1), def },
+  { "cmpc.l",   mode_0ab,  class3|(3<<21)|(4), def },
+  { "cmpc.w",   mode_0ab,  class3|(3<<21)|(2), def },
+  { "divds",    mode_a,    class1|(15<<21)|(1<<15)|(6<<10)|(4), def },
+  { "divdu",    mode_a,    class1|(15<<21)|(1<<15)|(7<<10)|(4), def },
+  { "divs",     mode_a,    class1|(15<<21)|(1<<15)|(2<<10)|(4), def },
+  { "divu",     mode_a,    class1|(15<<21)|(1<<15)|(3<<10)|(4), def },
+  { "dsi",      mode_s,    class1|(4<<21)|(4), def },
+  { "eamread",  mode_di,   class3|(15<<21)|(1<<15)|(1<<9)|(4), def },
+  { "eamwrite", mode_iab,  class1|(15<<21)|(1<<15)|(4), def },
+  { "eni",      mode_s,    class1|(5<<21)|(4), def },
+  { "extb.b",   mode_da,   class3|(14<<21)|(1), def },
+  { "extb.l",   mode_da,   class3|(14<<21)|(4), def },
+  { "extb.w",   mode_da,   class3|(14<<21)|(2), def },
+  { "extw.l",   mode_da,   class3|(4<<21)|(4), def },
+  { "extw.w",   mode_da,   class3|(4<<21)|(2), def },
+  { "fabs",     mode_fda,  class1|(7<<27)|(15<<21)|(1<<15)|(1<<3)|(4), gr5 },
+  { "fadd",     mode_fdab, class1|(1<<27)|(15<<21)|(1<<15)|(1<<3)|(4), gr5 },
+  { "fcmp",     mode_rdfab,class3|(10<<27)|(15<<21)|(1<<15)|(1<<9)|(1<<3)|(4), gr5 },
+  { "fcmpe",    mode_rdfab,class3|(11<<27)|(15<<21)|(1<<15)|(1<<9)|(1<<3)|(4), gr5 },
+  { "fdiv",     mode_fdab, class1|(4<<27)|(15<<21)|(1<<15)|(1<<3)|(4), gr5 },
+  { "fload",    mode_fdra, class1|(15<<21)|(1<<15)|(1<<3)|(4), gr5 },
+  { "fmove",    mode_fda,  class1|(12<<27)|(15<<21)|(1<<15)|(1<<3)|(4), gr5},
+  { "fmult",    mode_fdab, class1|(3<<27)|(15<<21)|(1<<15)|(1<<3)|(4), gr5 },
+  { "fneg",     mode_fda,  class1|(6<<27)|(15<<21)|(1<<15)|(1<<3)|(4), gr5 },
+  { "fpinst",   mode_ifdab,class1|(15<<21)|(1<<15)|(1<<3)|(4), gr5 },
+  { "fpuread",  mode_idfab,class3|(15<<21)|(1<<15)|(1<<9)|(1<<3)|(4), gr5 },
+  { "fsqrt",    mode_fda,  class1|(5<<27)|(15<<21)|(1<<15)|(1<<3)|(4), gr5 },
+  { "fstore",   mode_rdfa, class3|(15<<21)|(1<<15)|(1<<9)|(1<<3)|(4), gr5 },
+  { "fsub",     mode_fdab, class1|(2<<27)|(15<<21)|(1<<15)|(1<<3)|(4), gr5 },
+  { "ftoi",     mode_fda,  class1|(8<<27)|(15<<21)|(1<<15)|(1<<3)|(4), gr5 },
+  { "itof",     mode_fda,  class1|(9<<27)|(15<<21)|(1<<15)|(1<<3)|(4), gr5 },
+  { "lsr.b",    mode_das,  class3|(6<<21)|(1), def },
+  { "lsr.l",    mode_das,  class3|(6<<21)|(4), def },
+  { "lsr.w",    mode_das,  class3|(6<<21)|(2), def },
+  { "lsrd",     mode_a,    class1|(15<<21)|(1<<15)|(10<<10)|(4), def },
+  { "move.b",   mode_da0,  class3|(9<<21)|(1), def },
+  { "move.l",   mode_da0,  class3|(9<<21)|(4), def },
+  { "move.w",   mode_da0,  class3|(9<<21)|(2), def },
+  { "movil",    mode_ai,   class2|(4<<21), def },
+  { "moviq",    mode_ai,   class2|(6<<21), def },
+  { "moviu",    mode_ai,   class2|(5<<21), def },
+  { "mults",    mode_ab,   class1|(15<<21)|(1<<15)|(0<<10)|(4), def },
+  { "multu",    mode_ab,   class1|(15<<21)|(1<<15)|(1<<10)|(4), def },
+  { "nop",      mode_s,    class0, def },
+  { "not.b",    mode_da,   class3|(11<<21)|(1), def },
+  { "not.l",    mode_da,   class3|(11<<21)|(4), def },
+  { "not.w",    mode_da,   class3|(11<<21)|(2), def },
+  { "or.b",     mode_dab,  class3|(9<<21)|(1), def },
+  { "or.l",     mode_dab,  class3|(9<<21)|(4), def },
+  { "or.w",     mode_dab,  class3|(9<<21)|(2), def },
+  { "read.b",   mode_dax,  class3|(15<<21)|(1<<9)|(1), def },
+  { "read.l",   mode_dax,  class3|(15<<21)|(1<<9)|(4), def },
+  { "read.w",   mode_dax,  class3|(15<<21)|(1<<9)|(2), def },
+  { "readmda",  mode_d,    class3|(15<<21)|(1<<15)|(1<<9)|(4), def },
+  { "readmdb",  mode_d,    class3|(15<<21)|(1<<15)|(1<<9)|(1<<4)|(4), def },
+  { "readmdc",  mode_d,    class3|(15<<21)|(1<<15)|(1<<9)|(2<<4)|(4), def },
+  { "rfi",      mode_s,    class1|(7<<21)|(30<<16)|(29<<4)|(4), def },
+  { "rflag",    mode_d,    class3|(13<<21)|(4), def },
+  { "stop",     mode_ir,   class1|(0<<21)|(4), def },
+  { "sub.b",    mode_dab,  class3|(2<<21)|(1), def },
+  { "sub.l",    mode_dab,  class3|(2<<21)|(4), def },
+  { "sub.w",    mode_dab,  class3|(2<<21)|(2), def },
+  { "subc.b",   mode_dab,  class3|(3<<21)|(1), def },
+  { "subc.l",   mode_dab,  class3|(3<<21)|(4), def },
+  { "subc.w",   mode_dab,  class3|(3<<21)|(2), def },
+  { "subi",     mode_ai,   class2|(2<<21), def },
+  { "trace",    mode_ir,   class1|(13<<21), def },
+  { "write.b",  mode_bax,  class1|(15<<21)|(1), def },
+  { "write.l",  mode_bax,  class1|(15<<21)|(4), def },
+  { "write.w",  mode_bax,  class1|(15<<21)|(2), def },
+  { "writemd",  mode_ab,   class1|(15<<21)|(1<<15)|(4<<10)|(4), def },
+  { "writemdc", mode_a,    class1|(15<<21)|(1<<15)|(5<<10)|(4), def },
+  { "wrtl",     mode_i,    class2|(8<<21), gr6 },
+  { "wrtu",     mode_i,    class2|(9<<21), gr6 },
+  { "xor.b",    mode_dab,  class3|(8<<21)|(1), def },
+  { "xor.l",    mode_dab,  class3|(8<<21)|(4), def },
+  { "xor.w",    mode_dab,  class3|(8<<21)|(2), def },
+};
diff --git a/opcodes/Makefile.am b/opcodes/Makefile.am
index 4acc436..9b76239 100644
--- a/opcodes/Makefile.am
+++ b/opcodes/Makefile.am
@@ -250,6 +250,8 @@ TARGET_LIBOPCODES_CFILES = \
 	v850-dis.c \
 	v850-opc.c \
 	vax-dis.c \
+	visium-dis.c \
+	visium-opc.c \
 	w65-dis.c \
 	xc16x-asm.c \
 	xc16x-desc.c \
diff --git a/opcodes/Makefile.in b/opcodes/Makefile.in
index 46ef017..4f02d81 100644
--- a/opcodes/Makefile.in
+++ b/opcodes/Makefile.in
@@ -523,6 +523,8 @@ TARGET_LIBOPCODES_CFILES = \
 	v850-dis.c \
 	v850-opc.c \
 	vax-dis.c \
+	visium-dis.c \
+	visium-opc.c \
 	w65-dis.c \
 	xc16x-asm.c \
 	xc16x-desc.c \
@@ -923,6 +925,8 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/v850-dis.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/v850-opc.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vax-dis.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/visium-dis.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/visium-opc.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/w65-dis.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xc16x-asm.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xc16x-desc.Plo@am__quote@
diff --git a/opcodes/configure b/opcodes/configure
index 7f13699..c97bdf6 100755
--- a/opcodes/configure
+++ b/opcodes/configure
@@ -12626,6 +12626,7 @@ if test x${all_targets} = xfalse ; then
 	bfd_v850ea_arch)	ta="$ta v850-opc.lo v850-dis.lo" ;;
 	bfd_v850_rh850_arch)	ta="$ta v850-opc.lo v850-dis.lo" ;;
 	bfd_vax_arch)		ta="$ta vax-dis.lo" ;;
+	bfd_visium_arch)	ta="$ta visium-dis.lo visium-opc.lo" ;;
 	bfd_w65_arch)		ta="$ta w65-dis.lo" ;;
 	bfd_we32k_arch)		;;
 	bfd_xc16x_arch)		ta="$ta xc16x-asm.lo xc16x-desc.lo xc16x-dis.lo xc16x-ibld.lo xc16x-opc.lo" using_cgen=yes ;;
diff --git a/opcodes/configure.ac b/opcodes/configure.ac
index b93e855..39eb2fb 100644
--- a/opcodes/configure.ac
+++ b/opcodes/configure.ac
@@ -343,6 +343,7 @@ if test x${all_targets} = xfalse ; then
 	bfd_v850ea_arch)	ta="$ta v850-opc.lo v850-dis.lo" ;;
 	bfd_v850_rh850_arch)	ta="$ta v850-opc.lo v850-dis.lo" ;;
 	bfd_vax_arch)		ta="$ta vax-dis.lo" ;;
+	bfd_visium_arch)	ta="$ta visium-dis.lo visium-opc.lo" ;;
 	bfd_w65_arch)		ta="$ta w65-dis.lo" ;;
 	bfd_we32k_arch)		;;
 	bfd_xc16x_arch)		ta="$ta xc16x-asm.lo xc16x-desc.lo xc16x-dis.lo xc16x-ibld.lo xc16x-opc.lo" using_cgen=yes ;;
diff --git a/opcodes/disassemble.c b/opcodes/disassemble.c
index 0a0814e..63103bb 100644
--- a/opcodes/disassemble.c
+++ b/opcodes/disassemble.c
@@ -89,6 +89,7 @@
 #define ARCH_tilepro
 #define ARCH_v850
 #define ARCH_vax
+#define ARCH_visium
 #define ARCH_w65
 #define ARCH_xstormy16
 #define ARCH_xc16x
@@ -493,6 +494,11 @@ disassembler (abfd)
       disassemble = print_insn_vax;
       break;
 #endif
+#ifdef ARCH_visium
+     case bfd_arch_visium:
+       disassemble = print_insn_visium;
+       break;
+#endif
 #ifdef ARCH_frv
     case bfd_arch_frv:
       disassemble = print_insn_frv;
diff --git a/opcodes/po/POTFILES.in b/opcodes/po/POTFILES.in
index 0212748..8e8e122 100644
--- a/opcodes/po/POTFILES.in
+++ b/opcodes/po/POTFILES.in
@@ -207,6 +207,8 @@ tilepro-opc.c
 v850-dis.c
 v850-opc.c
 vax-dis.c
+visium-dis.c
+visium-opc.c
 w65-dis.c
 w65-opc.h
 xc16x-asm.c
diff --git a/opcodes/visium-dis.c b/opcodes/visium-dis.c
new file mode 100644
index 0000000..96be972
--- /dev/null
+++ b/opcodes/visium-dis.c
@@ -0,0 +1,834 @@
+/* Single instruction disassembler for the Visium.
+
+   Copyright (C) 2002-2014 Free Software Foundation, Inc.
+
+   This file is part of the GNU opcodes library.
+
+   This library is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   It is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "sysdep.h"
+#include "dis-asm.h"
+#include "opcode/visium.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <setjmp.h>
+
+/* Maximum length of an instruction.  */
+#define MAXLEN 4
+
+struct private
+{
+  /* Points to first byte not fetched.  */
+  bfd_byte *max_fetched;
+  bfd_byte the_buffer[MAXLEN];
+  bfd_vma insn_start;
+  jmp_buf bailout;
+};
+
+/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
+   to ADDR (exclusive) are valid.  Returns 1 for success, longjmps
+   on error.  */
+#define FETCH_DATA(info, addr) \
+  ((addr) <= ((struct private *)(info->private_data))->max_fetched \
+   ? 1 : fetch_data ((info), (addr)))
+
+static int fetch_data (struct disassemble_info *info, bfd_byte * addr);
+
+static int
+fetch_data (struct disassemble_info *info, bfd_byte *addr)
+{
+  int status;
+  struct private *priv = (struct private *) info->private_data;
+  bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
+
+  status = (*info->read_memory_func) (start,
+				      priv->max_fetched,
+				      addr - priv->max_fetched, info);
+  if (status != 0)
+    {
+      (*info->memory_error_func) (status, start, info);
+      longjmp (priv->bailout, 1);
+    }
+  else
+    priv->max_fetched = addr;
+  return 1;
+}
+
+static char *size_names[] = { "?", "b", "w", "?", "l", "?", "?", "?" };
+
+static char *cc_names[] =
+{
+  "fa", "eq", "cs", "os", "ns", "ne", "cc", "oc",
+  "nc", "ge", "gt", "hi", "le", "ls", "lt", "tr"
+};
+
+/* Disassemble non-storage relative instructions.  */
+
+static int
+disassem_class0 (disassemble_info *info, unsigned int ins)
+{
+  int opcode = (ins >> 21) & 0x000f;
+
+  if (ins & CLASS0_UNUSED_MASK)
+    goto illegal_opcode;
+
+  switch (opcode)
+    {
+    case 0:
+      /* BRR instruction.  */
+      {
+	unsigned cbf = (ins >> 27) & 0x000f;
+	int displacement = ((int) (ins << 16)) >> 16;
+
+	if (ins == 0)
+	  (*info->fprintf_func) (info->stream, "nop");
+	else
+	  (*info->fprintf_func) (info->stream, "brr     %s,%+d",
+				 cc_names[cbf], displacement);
+      }
+      break;
+    case 1:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    case 2:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    case 3:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    case 4:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    case 5:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    case 6:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    case 7:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    case 8:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    case 9:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    case 10:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    case 11:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    case 12:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    case 13:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    case 14:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    case 15:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    }
+  return 0;
+
+illegal_opcode:
+  return -1;
+}
+
+/* Disassemble non-storage register class instructions.   */
+
+static int
+disassem_class1 (disassemble_info *info, unsigned int ins)
+{
+  int opcode = (ins >> 21) & 0xf;
+  int source_a = (ins >> 16) & 0x1f;
+  int source_b = (ins >> 4) & 0x1f;
+  int indx = (ins >> 10) & 0x1f;
+
+  int size = ins & 0x7;
+
+  if (ins & CLASS1_UNUSED_MASK)
+    goto illegal_opcode;
+
+  switch (opcode)
+    {
+    case 0:
+      /* Stop.  */
+      (*info->fprintf_func) (info->stream, "stop");
+      break;
+    case 1:
+      /* BMI - Block Move Indirect.  */
+      if (ins != BMI)
+	goto illegal_opcode;
+
+      (*info->fprintf_func) (info->stream, "bmi     r1,r2,r3");
+      break;
+    case 2:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    case 3:
+      /* BMD - Block Move Direct.  */
+      if (ins != BMD)
+	goto illegal_opcode;
+
+      (*info->fprintf_func) (info->stream, "bmd     r1,r2,r3");
+      break;
+    case 4:
+      /* DSI - Disable Interrupts.  */
+      if (ins != DSI)
+	goto illegal_opcode;
+
+      (*info->fprintf_func) (info->stream, "dsi");
+      break;
+
+    case 5:
+      /* ENI - Enable Interrupts.  */
+      if (ins != ENI)
+	goto illegal_opcode;
+
+      (*info->fprintf_func) (info->stream, "eni");
+      break;
+
+    case 6:
+      /* Illegal opcode (was EUT).  */
+      goto illegal_opcode;
+      break;
+    case 7:
+      /* RFI - Return from Interrupt.  */
+      if (ins != RFI)
+	goto illegal_opcode;
+
+      (*info->fprintf_func) (info->stream, "rfi");
+      break;
+    case 8:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    case 9:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    case 10:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    case 11:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    case 12:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    case 13:
+      goto illegal_opcode;
+      break;
+    case 14:
+      goto illegal_opcode;
+      break;
+    case 15:
+      if (ins & EAM_SELECT_MASK)
+	{
+	  /* Extension arithmetic module write */
+	  int fp_ins = (ins >> 27) & 0xf;
+
+	  if (size != 4)
+	    goto illegal_opcode;
+
+	  if (ins & FP_SELECT_MASK)
+	    {
+	      /* Which floating point instructions don't need a fsrcB
+	         register.  */
+	      const int no_fsrcb[16] = { 1, 0, 0, 0, 0, 1, 1, 1,
+		1, 1, 0, 0, 1, 0, 0, 0
+	      };
+	      if (no_fsrcb[fp_ins] && source_b)
+		goto illegal_opcode;
+
+	      /* Check that none of the floating register register numbers
+	         is higher than 15. (If this is fload, then srcA is a
+	         general register.  */
+	      if (ins & ((1 << 14) | (1 << 8)) || (fp_ins && ins & (1 << 20)))
+		goto illegal_opcode;
+
+	      switch (fp_ins)
+		{
+		case 0:
+		  (*info->fprintf_func) (info->stream, "fload   f%d,r%d",
+					 indx, source_a);
+		  break;
+		case 1:
+		  (*info->fprintf_func) (info->stream, "fadd    f%d,f%d,f%d",
+					 indx, source_a, source_b);
+		  break;
+		case 2:
+		  (*info->fprintf_func) (info->stream, "fsub    f%d,f%d,f%d",
+					 indx, source_a, source_b);
+		  break;
+		case 3:
+		  (*info->fprintf_func) (info->stream, "fmult   f%d,f%d,f%d",
+					 indx, source_a, source_b);
+		  break;
+		case 4:
+		  (*info->fprintf_func) (info->stream, "fdiv    f%d,f%d,f%d",
+					 indx, source_a, source_b);
+		  break;
+		case 5:
+		  (*info->fprintf_func) (info->stream, "fsqrt   f%d,f%d",
+					 indx, source_a);
+		  break;
+		case 6:
+		  (*info->fprintf_func) (info->stream, "fneg    f%d,f%d",
+					 indx, source_a);
+		  break;
+		case 7:
+		  (*info->fprintf_func) (info->stream, "fabs    f%d,f%d",
+					 indx, source_a);
+		  break;
+		case 8:
+		  (*info->fprintf_func) (info->stream, "ftoi    f%d,f%d",
+					 indx, source_a);
+		  break;
+		case 9:
+		  (*info->fprintf_func) (info->stream, "itof    f%d,f%d",
+					 indx, source_a);
+		  break;
+		case 12:
+		  (*info->fprintf_func) (info->stream, "fmove   f%d,f%d",
+					 indx, source_a);
+		  break;
+		default:
+		  (*info->fprintf_func) (info->stream,
+					 "fpinst  %d,f%d,f%d,f%d", fp_ins,
+					 indx, source_a, source_b);
+		  break;
+		}
+	    }
+	  else
+	    {
+	      /* Which EAM operations do not need a srcB register.  */
+	      const int no_srcb[32] =
+	      { 0, 0, 1, 1, 0, 1, 1, 1,
+		0, 1, 1, 1, 0, 0, 0, 0,
+		0, 0, 0, 0, 0, 0, 0, 0,
+		0, 0, 0, 0, 0, 0, 0, 0
+	      };
+
+	      if (no_srcb[indx] && source_b)
+		goto illegal_opcode;
+
+	      if (fp_ins)
+		goto illegal_opcode;
+
+	      switch (indx)
+		{
+		case 0:
+		  (*info->fprintf_func) (info->stream, "mults   r%d,r%d",
+					 source_a, source_b);
+		  break;
+		case 1:
+		  (*info->fprintf_func) (info->stream, "multu   r%d,r%d",
+					 source_a, source_b);
+		  break;
+		case 2:
+		  (*info->fprintf_func) (info->stream, "divs    r%d",
+					 source_a);
+		  break;
+		case 3:
+		  (*info->fprintf_func) (info->stream, "divu    r%d",
+					 source_a);
+		  break;
+		case 4:
+		  (*info->fprintf_func) (info->stream, "writemd r%d,r%d",
+					 source_a, source_b);
+		  break;
+		case 5:
+		  (*info->fprintf_func) (info->stream, "writemdc r%d",
+					 source_a);
+		  break;
+		case 6:
+		  (*info->fprintf_func) (info->stream, "divds   r%d",
+					 source_a);
+		  break;
+		case 7:
+		  (*info->fprintf_func) (info->stream, "divdu   r%d",
+					 source_a);
+		  break;
+		case 9:
+		  (*info->fprintf_func) (info->stream, "asrd    r%d",
+					 source_a);
+		  break;
+		case 10:
+		  (*info->fprintf_func) (info->stream, "lsrd    r%d",
+					 source_a);
+		  break;
+		case 11:
+		  (*info->fprintf_func) (info->stream, "asld    r%d",
+					 source_a);
+		  break;
+		default:
+		  (*info->fprintf_func) (info->stream,
+					 "eamwrite %d,r%d,r%d", indx,
+					 source_a, source_b);
+		  break;
+		}
+	    }
+	}
+      else
+	{
+	  /* WRITE - write to memory.  */
+	  (*info->fprintf_func) (info->stream, "write.%s %d(r%d),r%d",
+				 size_names[size], indx, source_a, source_b);
+	}
+      break;
+    }
+
+  return 0;
+
+illegal_opcode:
+  return -1;
+}
+
+/* Disassemble storage immediate class instructions.   */
+
+static int
+disassem_class2 (disassemble_info *info, unsigned int ins)
+{
+  int opcode = (ins >> 21) & 0xf;
+  int source_a = (ins >> 16) & 0x1f;
+  unsigned immediate = ins & 0x0000ffff;
+
+  if (ins & CC_MASK)
+    goto illegal_opcode;
+
+  switch (opcode)
+    {
+    case 0:
+      /* ADDI instruction.  */
+      (*info->fprintf_func) (info->stream, "addi    r%d,%d", source_a,
+			     immediate);
+      break;
+    case 1:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    case 2:
+      /* SUBI instruction.  */
+      (*info->fprintf_func) (info->stream, "subi    r%d,%d", source_a,
+			     immediate);
+      break;
+    case 3:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    case 4:
+      /* MOVIL instruction.  */
+      (*info->fprintf_func) (info->stream, "movil   r%d,0x%04X", source_a,
+			     immediate);
+      break;
+    case 5:
+      /* MOVIU instruction.  */
+      (*info->fprintf_func) (info->stream, "moviu   r%d,0x%04X", source_a,
+			     immediate);
+      break;
+    case 6:
+      /* MOVIQ instruction.  */
+      (*info->fprintf_func) (info->stream, "moviq   r%d,%u", source_a,
+			     immediate);
+      break;
+    case 7:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    case 8:
+      /* WRTL instruction.  */
+      if (source_a != 0)
+	goto illegal_opcode;
+
+      (*info->fprintf_func) (info->stream, "wrtl    0x%04X", immediate);
+      break;
+    case 9:
+      /* WRTU instruction.  */
+      if (source_a != 0)
+	goto illegal_opcode;
+
+      (*info->fprintf_func) (info->stream, "wrtu    0x%04X", immediate);
+      break;
+    case 10:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    case 11:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    case 12:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    case 13:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    case 14:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    case 15:
+      /* Illegal opcode.  */
+      goto illegal_opcode;
+      break;
+    }
+
+  return 0;
+
+illegal_opcode:
+  return -1;
+}
+
+/* Disassemble storage register class instructions.  */
+
+static int
+disassem_class3 (disassemble_info *info, unsigned int ins)
+{
+  int opcode = (ins >> 21) & 0xf;
+  int source_b = (ins >> 4) & 0x1f;
+  int source_a = (ins >> 16) & 0x1f;
+  int size = ins & 0x7;
+  int dest = (ins >> 10) & 0x1f;
+
+  /* Those instructions that don't have a srcB register.  */
+  const int no_srcb[16] =
+  { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0 };
+
+  /* These are instructions which can take an immediate srcB value.  */
+  const int srcb_immed[16] =
+  { 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1 };
+
+  /* User opcodes should not provide a non-zero srcB register
+     when none is required. Only a BRA or floating point
+     instruction should have a non-zero condition code field.
+     Only a WRITE or EAMWRITE (opcode 15) should select an EAM
+     or floating point operation.  Note that FP_SELECT_MASK is
+     the same bit (bit 3) as the interrupt bit which
+     distinguishes SYS1 from BRA and SYS2 from RFLAG.  */
+  if ((no_srcb[opcode] && source_b)
+      || (!srcb_immed[opcode] && ins & CLASS3_SOURCEB_IMMED)
+      || (opcode != 12 && opcode != 15 && ins & CC_MASK)
+      || (opcode != 15 && ins & (EAM_SELECT_MASK | FP_SELECT_MASK)))
+    goto illegal_opcode;
+
+
+  switch (opcode)
+    {
+    case 0:
+      /* ADD instruction.  */
+      (*info->fprintf_func) (info->stream, "add.%s   r%d,r%d,r%d",
+			     size_names[size], dest, source_a, source_b);
+      break;
+    case 1:
+      /* ADC instruction.  */
+      (*info->fprintf_func) (info->stream, "adc.%s   r%d,r%d,r%d",
+			     size_names[size], dest, source_a, source_b);
+      break;
+    case 2:
+      /* SUB instruction.  */
+      if (dest == 0)
+	(*info->fprintf_func) (info->stream, "cmp.%s   r%d,r%d",
+			       size_names[size], source_a, source_b);
+      else
+	(*info->fprintf_func) (info->stream, "sub.%s   r%d,r%d,r%d",
+			       size_names[size], dest, source_a, source_b);
+      break;
+    case 3:
+      /* SUBC instruction.  */
+      if (dest == 0)
+	(*info->fprintf_func) (info->stream, "cmpc.%s  r%d,r%d",
+			       size_names[size], source_a, source_b);
+      else
+	(*info->fprintf_func) (info->stream, "subc.%s  r%d,r%d,r%d",
+			       size_names[size], dest, source_a, source_b);
+      break;
+    case 4:
+      /* EXTW instruction.  */
+      if (size == 1)
+	goto illegal_opcode;
+
+      (*info->fprintf_func) (info->stream, "extw.%s  r%d,r%d",
+			     size_names[size], dest, source_a);
+      break;
+    case 5:
+      /* ASR instruction.  */
+      if (ins & CLASS3_SOURCEB_IMMED)
+	(*info->fprintf_func) (info->stream, "asr.%s   r%d,r%d,%d",
+			       size_names[size], dest, source_a, source_b);
+      else
+	(*info->fprintf_func) (info->stream, "asr.%s   r%d,r%d,r%d",
+			       size_names[size], dest, source_a, source_b);
+      break;
+    case 6:
+      /* LSR instruction.  */
+      if (ins & CLASS3_SOURCEB_IMMED)
+	(*info->fprintf_func) (info->stream, "lsr.%s   r%d,r%d,%d",
+			       size_names[size], dest, source_a, source_b);
+      else
+	(*info->fprintf_func) (info->stream, "lsr.%s   r%d,r%d,r%d",
+			       size_names[size], dest, source_a, source_b);
+      break;
+    case 7:
+      /* ASL instruction.  */
+      if (ins & CLASS3_SOURCEB_IMMED)
+	(*info->fprintf_func) (info->stream, "asl.%s   r%d,r%d,%d",
+			       size_names[size], dest, source_a, source_b);
+      else
+	(*info->fprintf_func) (info->stream, "asl.%s   r%d,r%d,r%d",
+			       size_names[size], dest, source_a, source_b);
+      break;
+    case 8:
+      /* XOR instruction.  */
+      (*info->fprintf_func) (info->stream, "xor.%s   r%d,r%d,r%d",
+			     size_names[size], dest, source_a, source_b);
+      break;
+    case 9:
+      /* OR instruction.  */
+      if (source_b == 0)
+	(*info->fprintf_func) (info->stream, "move.%s  r%d,r%d",
+			       size_names[size], dest, source_a);
+      else
+	(*info->fprintf_func) (info->stream, "or.%s    r%d,r%d,r%d",
+			       size_names[size], dest, source_a, source_b);
+      break;
+    case 10:
+      /* AND instruction.  */
+      (*info->fprintf_func) (info->stream, "and.%s   r%d,r%d,r%d",
+			     size_names[size], dest, source_a, source_b);
+      break;
+    case 11:
+      /* NOT instruction.  */
+      (*info->fprintf_func) (info->stream, "not.%s   r%d,r%d",
+			     size_names[size], dest, source_a);
+      break;
+    case 12:
+      /* BRA instruction.  */
+      {
+	unsigned cbf = (ins >> 27) & 0x000f;
+
+	if (size != 4)
+	  goto illegal_opcode;
+
+	(*info->fprintf_func) (info->stream, "bra     %s,r%d,r%d",
+			       cc_names[cbf], source_a, dest);
+      }
+      break;
+    case 13:
+      /* RFLAG instruction.  */
+      if (source_a || size != 4)
+	goto illegal_opcode;
+
+      (*info->fprintf_func) (info->stream, "rflag   r%d", dest);
+      break;
+    case 14:
+      /* EXTB instruction.  */
+      (*info->fprintf_func) (info->stream, "extb.%s  r%d,r%d",
+			     size_names[size], dest, source_a);
+      break;
+    case 15:
+      if (!(ins & CLASS3_SOURCEB_IMMED))
+	goto illegal_opcode;
+
+      if (ins & EAM_SELECT_MASK)
+	{
+	  /* Extension arithmetic module read.  */
+	  int fp_ins = (ins >> 27) & 0xf;
+
+	  if (size != 4)
+	    goto illegal_opcode;
+
+	  if (ins & FP_SELECT_MASK)
+	    {
+	      /* Check fsrcA <= 15 and fsrcB <= 15.  */
+	      if (ins & ((1 << 20) | (1 << 8)))
+		goto illegal_opcode;
+
+	      switch (fp_ins)
+		{
+		case 0:
+		  if (source_b)
+		    goto illegal_opcode;
+
+		  (*info->fprintf_func) (info->stream, "fstore  r%d,f%d",
+					 dest, source_a);
+		  break;
+		case 10:
+		  (*info->fprintf_func) (info->stream, "fcmp    r%d,f%d,f%d",
+					 dest, source_a, source_b);
+		  break;
+		case 11:
+		  (*info->fprintf_func) (info->stream, "fcmpe   r%d,f%d,f%d",
+					 dest, source_a, source_b);
+		  break;
+		default:
+		  (*info->fprintf_func) (info->stream,
+					 "fpuread %d,r%d,f%d,f%d", fp_ins,
+					 dest, source_a, source_b);
+		  break;
+		}
+	    }
+	  else
+	    {
+	      if (fp_ins || source_a)
+		goto illegal_opcode;
+
+	      switch (source_b)
+		{
+		case 0:
+		  (*info->fprintf_func) (info->stream, "readmda r%d", dest);
+		  break;
+		case 1:
+		  (*info->fprintf_func) (info->stream, "readmdb r%d", dest);
+		  break;
+		case 2:
+		  (*info->fprintf_func) (info->stream, "readmdc r%d", dest);
+		  break;
+		default:
+		  (*info->fprintf_func) (info->stream, "eamread r%d,%d",
+					 dest, source_b);
+		  break;
+		}
+	    }
+	}
+      else
+	{
+	  if (ins & FP_SELECT_MASK)
+	    goto illegal_opcode;
+
+	  /* READ instruction.  */
+	  (*info->fprintf_func) (info->stream, "read.%s  r%d,%d(r%d)",
+				 size_names[size], dest, source_b, source_a);
+	}
+      break;
+    }
+
+  return 0;
+
+illegal_opcode:
+  return -1;
+
+}
+
+/* Print the visium instruction at address addr in debugged memory,
+   on info->stream. Return length of the instruction, in bytes.  */
+
+int
+print_insn_visium (bfd_vma addr, disassemble_info *info)
+{
+  unsigned ins;
+  unsigned p1, p2;
+  int ans;
+  int i;
+
+  /* Stuff copied from m68k-dis.c.  */
+  struct private priv;
+  bfd_byte *buffer = priv.the_buffer;
+  info->private_data = (PTR) & priv;
+  priv.max_fetched = priv.the_buffer;
+  priv.insn_start = addr;
+  if (setjmp (priv.bailout) != 0)
+    {
+      /* Error return.  */
+      return -1;
+    }
+
+  /* We do return this info.  */
+  info->insn_info_valid = 1;
+
+  /* Assume non branch insn.  */
+  info->insn_type = dis_nonbranch;
+
+  /* Assume no delay.  */
+  info->branch_delay_insns = 0;
+
+  /* Assume no target known.  */
+  info->target = 0;
+
+  /* Get 32-bit instruction word.  */
+  FETCH_DATA (info, buffer + 4);
+  ins = buffer[0] << 24;
+  ins |= buffer[1] << 16;
+  ins |= buffer[2] << 8;
+  ins |= buffer[3];
+
+  ans = 0;
+
+  p1 = buffer[0] ^ buffer[1] ^ buffer[2] ^ buffer[3];
+  p2 = 0;
+  for (i = 0; i < 8; i++)
+    {
+      p2 += p1 & 1;
+      p1 >>= 1;
+    }
+
+  /* Decode the instruction.  */
+  if (p2 & 1)
+    ans = -1;
+  else
+    {
+      switch ((ins >> 25) & 0x3)
+	{
+	case 0:
+	  ans = disassem_class0 (info, ins);
+	  break;
+	case 1:
+	  ans = disassem_class1 (info, ins);
+	  break;
+	case 2:
+	  ans = disassem_class2 (info, ins);
+	  break;
+	case 3:
+	  ans = disassem_class3 (info, ins);
+	  break;
+	}
+    }
+
+  if (ans != 0)
+    (*info->fprintf_func) (info->stream, "err");
+
+  /* Return number of bytes consumed (always 4 for the Visium).  */
+  return 4;
+}
diff --git a/opcodes/visium-opc.c b/opcodes/visium-opc.c
new file mode 100644
index 0000000..742452c
--- /dev/null
+++ b/opcodes/visium-opc.c
@@ -0,0 +1,23 @@
+/* Opcode table for the Visium.
+
+   Copyright (C) 2002-2014 Free Software Foundation, Inc.
+
+   This file is part of the GNU opcodes library.
+
+   This library is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   It is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "ansidecl.h"
+#include "opcode/visium.h"
-- 
1.7.7

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 3/6] Add Visium support to bfd
  2014-12-03 23:46 ` [PATCH 3/6] Add Visium support to bfd Eric Botcazou
@ 2014-12-04  0:45   ` Alan Modra
  2014-12-05 10:21     ` Eric Botcazou
  0 siblings, 1 reply; 17+ messages in thread
From: Alan Modra @ 2014-12-04  0:45 UTC (permalink / raw)
  To: Eric Botcazou; +Cc: binutils, Eric Botcazou

On Wed, Dec 03, 2014 at 06:29:09PM -0500, Eric Botcazou wrote:
> +static bfd_vma
> +visium_set_even_parity (bfd_vma insn)
> +{
> +  bfd_vma p = 0;
> +  int i;
> +
> +  for (i = 0; i < 31; i++)
> +    {
> +      p += insn & 1;
> +      insn >>= 1;
> +    }
> +
> +  return p << 31;
> +}

Lose "set_" in the name, you're not setting anything here.
Also p ^= might save some future trouble, since bfd_vma can be 64-bit.

> +  sym_hashes_end =
> +    sym_hashes + symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
> +  if (!elf_bad_symtab (abfd))
> +    sym_hashes_end -= symtab_hdr->sh_info;

You won't ever have elf_bad_symtab set and in any case, sym_hashes_end
looks to be unused.

> +   There is some attempt to make this function usable for many architectures,
> +   both USE_REL and USE_RELA ['twould be nice if such a critter existed],
> +   if only to serve as a learning tool.

Really?

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 0/6] binutils port for the Visium
  2014-12-03 23:29 [PATCH 0/6] binutils port for the Visium Eric Botcazou
                   ` (4 preceding siblings ...)
  2014-12-03 23:46 ` [PATCH 2/6] Add Visium support to opcodes Eric Botcazou
@ 2014-12-04  0:48 ` Alan Modra
  2014-12-04 12:09 ` [PATCH 5/6] Add Visium support to gas Eric Botcazou
  6 siblings, 0 replies; 17+ messages in thread
From: Alan Modra @ 2014-12-04  0:48 UTC (permalink / raw)
  To: Eric Botcazou; +Cc: binutils, Eric Botcazou

On Wed, Dec 03, 2014 at 06:29:06PM -0500, Eric Botcazou wrote:
> OK for the mainline?

OK, with those minor things I noted in my reply to 3/6 fixed.

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 5/6] Add Visium support to gas
  2014-12-03 23:29 [PATCH 0/6] binutils port for the Visium Eric Botcazou
                   ` (5 preceding siblings ...)
  2014-12-04  0:48 ` [PATCH 0/6] binutils port for the Visium Alan Modra
@ 2014-12-04 12:09 ` Eric Botcazou
  2014-12-04 15:17   ` Joseph Myers
  2014-12-05  2:26   ` Alan Modra
  6 siblings, 2 replies; 17+ messages in thread
From: Eric Botcazou @ 2014-12-04 12:09 UTC (permalink / raw)
  To: binutils; +Cc: Eric Botcazou

From: Eric Botcazou <ebotcazou@gcc.gnu.org>

gas/ChangeLog

2014-12-03  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: Add config/tc-visium.c and config/tc-visium.h.

gas/testsuite/ChangeLog

2014-12-03  Eric Botcazou  <ebotcazou@adacore.com>

	* gas/elf/elf.exp: Skip ifunc-1 for Visium.
	* gas/visium/: New directory.

---
 gas/Makefile.am                         |    6 +-
 gas/Makefile.in                         |   41 +-
 gas/config/tc-visium.c                  | 2328 +++++++++++++++++++++++++++++++
 gas/config/tc-visium.h                  |   79 ++
 gas/configure.tgt                       |    3 +
 gas/po/POTFILES.in                      |    2 +
 gas/testsuite/gas/elf/elf.exp           |    3 +-
 gas/testsuite/gas/visium/allinsn.exp    |    7 +
 gas/testsuite/gas/visium/allinsn_def.d  |  134 ++
 gas/testsuite/gas/visium/allinsn_def.s  |  157 +++
 gas/testsuite/gas/visium/allinsn_gr5.d  |  153 ++
 gas/testsuite/gas/visium/allinsn_gr5.s  |  179 +++
 gas/testsuite/gas/visium/allinsn_gr6.d  |  159 +++
 gas/testsuite/gas/visium/allinsn_gr6.s  |  185 +++
 gas/testsuite/gas/visium/basereg.s      |   20 +
 gas/testsuite/gas/visium/brr-1.d        |   16 +
 gas/testsuite/gas/visium/brr-1.s        |    9 +
 gas/testsuite/gas/visium/brr-2.d        |   18 +
 gas/testsuite/gas/visium/brr-2.s        |    9 +
 gas/testsuite/gas/visium/brr_backward.s |   15 +
 gas/testsuite/gas/visium/brr_forward.s  |   16 +
 gas/testsuite/gas/visium/error.exp      |   35 +
 gas/testsuite/gas/visium/fcmp.s         |   11 +
 gas/testsuite/gas/visium/high-1.d       |   19 +
 gas/testsuite/gas/visium/high-1.s       |   11 +
 gas/testsuite/gas/visium/immed-1.d      |   17 +
 gas/testsuite/gas/visium/immed-1.s      |   10 +
 gas/testsuite/gas/visium/rela-1.d       |   18 +
 gas/testsuite/gas/visium/rela-1.s       |   20 +
 gas/testsuite/gas/visium/visium.exp     |   29 +
 30 files changed, 3694 insertions(+), 15 deletions(-)
 create mode 100644 gas/config/tc-visium.c
 create mode 100644 gas/config/tc-visium.h
 create mode 100644 gas/testsuite/gas/visium/allinsn.exp
 create mode 100644 gas/testsuite/gas/visium/allinsn_def.d
 create mode 100644 gas/testsuite/gas/visium/allinsn_def.s
 create mode 100644 gas/testsuite/gas/visium/allinsn_gr5.d
 create mode 100644 gas/testsuite/gas/visium/allinsn_gr5.s
 create mode 100644 gas/testsuite/gas/visium/allinsn_gr6.d
 create mode 100644 gas/testsuite/gas/visium/allinsn_gr6.s
 create mode 100644 gas/testsuite/gas/visium/basereg.s
 create mode 100644 gas/testsuite/gas/visium/brr-1.d
 create mode 100644 gas/testsuite/gas/visium/brr-1.s
 create mode 100644 gas/testsuite/gas/visium/brr-2.d
 create mode 100644 gas/testsuite/gas/visium/brr-2.s
 create mode 100644 gas/testsuite/gas/visium/brr_backward.s
 create mode 100644 gas/testsuite/gas/visium/brr_forward.s
 create mode 100644 gas/testsuite/gas/visium/error.exp
 create mode 100644 gas/testsuite/gas/visium/fcmp.s
 create mode 100644 gas/testsuite/gas/visium/high-1.d
 create mode 100644 gas/testsuite/gas/visium/high-1.s
 create mode 100644 gas/testsuite/gas/visium/immed-1.d
 create mode 100644 gas/testsuite/gas/visium/immed-1.s
 create mode 100644 gas/testsuite/gas/visium/rela-1.d
 create mode 100644 gas/testsuite/gas/visium/rela-1.s
 create mode 100644 gas/testsuite/gas/visium/visium.exp

diff --git a/gas/Makefile.am b/gas/Makefile.am
index 55c86b2..f65225f 100644
--- a/gas/Makefile.am
+++ b/gas/Makefile.am
@@ -185,8 +185,9 @@ TARGET_CPU_CFILES = \
 	config/tc-tic6x.c \
 	config/tc-tilegx.c \
 	config/tc-tilepro.c \
-	config/tc-vax.c \
 	config/tc-v850.c \
+	config/tc-vax.c \
+	config/tc-visium.c \
 	config/tc-xstormy16.c \
 	config/tc-xc16x.c \
 	config/tc-xgate.c \
@@ -256,8 +257,9 @@ TARGET_CPU_HFILES = \
 	config/tc-tic6x.h \
 	config/tc-tilegx.h \
 	config/tc-tilepro.h \
-	config/tc-vax.h \
 	config/tc-v850.h \
+	config/tc-vax.h \
+	config/tc-visium.h \
 	config/tc-xstormy16.h \
 	config/tc-xc16x.h \
 	config/tc-xgate.h \
diff --git a/gas/Makefile.in b/gas/Makefile.in
index 5dc250f..c7b3597 100644
--- a/gas/Makefile.in
+++ b/gas/Makefile.in
@@ -454,8 +454,9 @@ TARGET_CPU_CFILES = \
 	config/tc-tic6x.c \
 	config/tc-tilegx.c \
 	config/tc-tilepro.c \
-	config/tc-vax.c \
 	config/tc-v850.c \
+	config/tc-vax.c \
+	config/tc-visium.c \
 	config/tc-xstormy16.c \
 	config/tc-xc16x.c \
 	config/tc-xgate.c \
@@ -525,8 +526,9 @@ TARGET_CPU_HFILES = \
 	config/tc-tic6x.h \
 	config/tc-tilegx.h \
 	config/tc-tilepro.h \
-	config/tc-vax.h \
 	config/tc-v850.h \
+	config/tc-vax.h \
+	config/tc-visium.h \
 	config/tc-xstormy16.h \
 	config/tc-xc16x.h \
 	config/tc-xgate.h \
@@ -882,6 +884,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-tilepro.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-v850.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-vax.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-visium.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-xc16x.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-xgate.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-xstormy16.Po@am__quote@
@@ -1767,6 +1770,20 @@ tc-tilepro.obj: config/tc-tilepro.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tc-tilepro.obj `if test -f 'config/tc-tilepro.c'; then $(CYGPATH_W) 'config/tc-tilepro.c'; else $(CYGPATH_W) '$(srcdir)/config/tc-tilepro.c'; fi`
 
+tc-v850.o: config/tc-v850.c
+@am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tc-v850.o -MD -MP -MF $(DEPDIR)/tc-v850.Tpo -c -o tc-v850.o `test -f 'config/tc-v850.c' || echo '$(srcdir)/'`config/tc-v850.c
+@am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/tc-v850.Tpo $(DEPDIR)/tc-v850.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='config/tc-v850.c' object='tc-v850.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tc-v850.o `test -f 'config/tc-v850.c' || echo '$(srcdir)/'`config/tc-v850.c
+
+tc-v850.obj: config/tc-v850.c
+@am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tc-v850.obj -MD -MP -MF $(DEPDIR)/tc-v850.Tpo -c -o tc-v850.obj `if test -f 'config/tc-v850.c'; then $(CYGPATH_W) 'config/tc-v850.c'; else $(CYGPATH_W) '$(srcdir)/config/tc-v850.c'; fi`
+@am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/tc-v850.Tpo $(DEPDIR)/tc-v850.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='config/tc-v850.c' object='tc-v850.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tc-v850.obj `if test -f 'config/tc-v850.c'; then $(CYGPATH_W) 'config/tc-v850.c'; else $(CYGPATH_W) '$(srcdir)/config/tc-v850.c'; fi`
+
 tc-vax.o: config/tc-vax.c
 @am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tc-vax.o -MD -MP -MF $(DEPDIR)/tc-vax.Tpo -c -o tc-vax.o `test -f 'config/tc-vax.c' || echo '$(srcdir)/'`config/tc-vax.c
 @am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/tc-vax.Tpo $(DEPDIR)/tc-vax.Po
@@ -1781,19 +1798,19 @@ tc-vax.obj: config/tc-vax.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tc-vax.obj `if test -f 'config/tc-vax.c'; then $(CYGPATH_W) 'config/tc-vax.c'; else $(CYGPATH_W) '$(srcdir)/config/tc-vax.c'; fi`
 
-tc-v850.o: config/tc-v850.c
-@am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tc-v850.o -MD -MP -MF $(DEPDIR)/tc-v850.Tpo -c -o tc-v850.o `test -f 'config/tc-v850.c' || echo '$(srcdir)/'`config/tc-v850.c
-@am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/tc-v850.Tpo $(DEPDIR)/tc-v850.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='config/tc-v850.c' object='tc-v850.o' libtool=no @AMDEPBACKSLASH@
+tc-visium.o: config/tc-visium.c
+@am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tc-visium.o -MD -MP -MF $(DEPDIR)/tc-visium.Tpo -c -o tc-visium.o `test -f 'config/tc-visium.c' || echo '$(srcdir)/'`config/tc-visium.c
+@am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/tc-visium.Tpo $(DEPDIR)/tc-visium.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='config/tc-visium.c' object='tc-visium.o' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tc-v850.o `test -f 'config/tc-v850.c' || echo '$(srcdir)/'`config/tc-v850.c
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tc-visium.o `test -f 'config/tc-visium.c' || echo '$(srcdir)/'`config/tc-visium.c
 
-tc-v850.obj: config/tc-v850.c
-@am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tc-v850.obj -MD -MP -MF $(DEPDIR)/tc-v850.Tpo -c -o tc-v850.obj `if test -f 'config/tc-v850.c'; then $(CYGPATH_W) 'config/tc-v850.c'; else $(CYGPATH_W) '$(srcdir)/config/tc-v850.c'; fi`
-@am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/tc-v850.Tpo $(DEPDIR)/tc-v850.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='config/tc-v850.c' object='tc-v850.obj' libtool=no @AMDEPBACKSLASH@
+tc-visium.obj: config/tc-visium.c
+@am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tc-visium.obj -MD -MP -MF $(DEPDIR)/tc-visium.Tpo -c -o tc-visium.obj `if test -f 'config/tc-visium.c'; then $(CYGPATH_W) 'config/tc-visium.c'; else $(CYGPATH_W) '$(srcdir)/config/tc-visium.c'; fi`
+@am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/tc-visium.Tpo $(DEPDIR)/tc-visium.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='config/tc-visium.c' object='tc-visium.obj' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tc-v850.obj `if test -f 'config/tc-v850.c'; then $(CYGPATH_W) 'config/tc-v850.c'; else $(CYGPATH_W) '$(srcdir)/config/tc-v850.c'; fi`
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tc-visium.obj `if test -f 'config/tc-visium.c'; then $(CYGPATH_W) 'config/tc-visium.c'; else $(CYGPATH_W) '$(srcdir)/config/tc-visium.c'; fi`
 
 tc-xstormy16.o: config/tc-xstormy16.c
 @am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tc-xstormy16.o -MD -MP -MF $(DEPDIR)/tc-xstormy16.Tpo -c -o tc-xstormy16.o `test -f 'config/tc-xstormy16.c' || echo '$(srcdir)/'`config/tc-xstormy16.c
diff --git a/gas/config/tc-visium.c b/gas/config/tc-visium.c
new file mode 100644
index 0000000..f3a9816
--- /dev/null
+++ b/gas/config/tc-visium.c
@@ -0,0 +1,2328 @@
+/* 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. We use this, rather than the usual
+   comment_chars, so that the --bitwise-or option will work.  */
+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);
+}
+
+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 & 0x01;
+      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;
+	  /* Pacify gcc -Wall.  */
+	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
+	      || (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)
+	    {
+	      insn = (insn & 0xffff0000) | ((val >> 16) & 0x0000ffff);
+	    }
+	  else
+	    {
+	      /* FIXME: Need comment explaining why we do this.  */
+	      insn = (insn & 0xffff0000);
+	    }
+	  break;
+
+	case BFD_RELOC_VISIUM_LO16:
+	case BFD_RELOC_VISIUM_LO16_PCREL:
+	  if (!fixP->fx_addsy)
+	    {
+	      insn = (insn & 0xffff0000) | (val & 0x0000ffff);
+	    }
+	  else
+	    {
+	      /* FIXME: Need comment explaining why we do this.  */
+	      insn = (insn & 0xffff0000);
+	    }
+	  break;
+
+	case BFD_RELOC_VISIUM_IM16:
+	case BFD_RELOC_VISIUM_IM16_PCREL:
+	  if (!fixP->fx_addsy)
+	    {
+	      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;
+	    }
+	  else
+	    {
+	      /* FIXME: Need comment explaining why we do this.  */
+	      insn = (insn & 0xffff0000);
+	    }
+	  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 == 0 && !fixP->fx_pcrel)
+    fixP->fx_done = 1;
+}
+
+char *
+parse_exp (char *s, expressionS * op)
+{
+  char *save = input_line_pointer;
+  char *new;
+
+  if (!s)
+    {
+      return s;
+    }
+
+  input_line_pointer = s;
+  expression (op);
+  new = input_line_pointer;
+  input_line_pointer = save;
+  return new;
+}
+
+/* If the given string is a Visium opcode mnemonic return the code
+   otherwise return -1. Use binary chop to find matching entry.  */
+static int
+get_opcode (int *code, enum addressing_mode *mode, char *flags, char *mnem)
+{
+  int l = 0;
+  int r = sizeof (opcode_table) / sizeof (struct opcode_entry) - 1;
+
+  do
+    {
+      int mid = (l + r) / 2;
+      int ans = strcmp (mnem, opcode_table[mid].mnem);
+
+      if (ans < 0)
+	r = mid - 1;
+      else if (ans > 0)
+	l = mid + 1;
+      else
+	{
+	  *code = opcode_table[mid].code;
+	  *mode = opcode_table[mid].mode;
+	  *flags = opcode_table[mid].flags;
+
+	  return 0;
+	}
+    }
+  while (l <= r);
+
+  return -1;
+}
+
+/* This function is called when the assembler starts up. It is called
+   after the options have been parsed and the output file has been
+   opened.  */
+void
+md_begin (void)
+{
+  switch (visium_arch)
+    {
+    case VISIUM_ARCH_DEF:
+      break;
+    case VISIUM_ARCH_MCM24:
+      visium_opcode_arch = VISIUM_OPCODE_ARCH_GR5;
+      visium_flags |= EF_VISIUM_ARCH_MCM24;
+      break;
+    case VISIUM_ARCH_MCM:
+      visium_opcode_arch = VISIUM_OPCODE_ARCH_GR5;
+      visium_flags |= EF_VISIUM_ARCH_MCM;
+      break;
+    case VISIUM_ARCH_GR6:
+      visium_opcode_arch = VISIUM_OPCODE_ARCH_GR6;
+      visium_flags |= EF_VISIUM_ARCH_MCM | EF_VISIUM_ARCH_GR6;
+      nop_limit = 2;
+      break;
+    default:
+      gas_assert (0);
+    }
+
+  bfd_set_private_flags (stdoutput, visium_flags);
+}
+
+/* This is identical to the md_atof in m68k.c.  I think this is right,
+   but I'm not sure.
+
+   Turn a string in input_line_pointer into a floating point constant of type
+   type, and store the appropriate bytes in *litP.  The number of LITTLENUMS
+   emitted is stored in *sizeP .  An error message is returned,
+   or NULL on OK.  */
+
+/* Equal to MAX_PRECISION in atof-ieee.c.  */
+#define MAX_LITTLENUMS 6
+
+char *
+md_atof (int type, char *litP, int *sizeP)
+{
+  int i, prec;
+  LITTLENUM_TYPE words[MAX_LITTLENUMS];
+  char *t;
+
+  switch (type)
+    {
+    case 'f':
+    case 'F':
+    case 's':
+    case 'S':
+      prec = 2;
+      break;
+
+    case 'd':
+    case 'D':
+    case 'r':
+    case 'R':
+      prec = 4;
+      break;
+
+    case 'x':
+    case 'X':
+      prec = 6;
+      break;
+
+    case 'p':
+    case 'P':
+      prec = 6;
+      break;
+
+    default:
+      *sizeP = 0;
+      return "Bad call to MD_ATOF()";
+    }
+
+  t = atof_ieee (input_line_pointer, type, words);
+  if (t)
+    input_line_pointer = t;
+  *sizeP = prec * sizeof (LITTLENUM_TYPE);
+
+  if (target_big_endian)
+    {
+      for (i = 0; i < prec; i++)
+	{
+	  md_number_to_chars (litP, (valueT) words[i],
+			      sizeof (LITTLENUM_TYPE));
+	  litP += sizeof (LITTLENUM_TYPE);
+	}
+    }
+  else
+    {
+      for (i = prec - 1; i >= 0; i--)
+	{
+	  md_number_to_chars (litP, (valueT) words[i],
+			      sizeof (LITTLENUM_TYPE));
+	  litP += sizeof (LITTLENUM_TYPE);
+	}
+    }
+
+  return 0;
+}
+
+static inline char *
+skip_space (char *s)
+{
+  while (*s == ' ' || *s == '\t')
+    ++s;
+
+  return s;
+}
+
+static int
+parse_gen_reg (char **sptr, int *rptr)
+{
+  char *s = skip_space (*sptr);
+  char buf[10];
+  int cnt;
+  int l, r;
+
+  cnt = 0;
+  memset (buf, '\0', 10);
+  while ((ISALNUM (*s)) && cnt < 10)
+    buf[cnt++] = TOLOWER (*s++);
+
+  l = 0;
+  r = sizeof (gen_reg_table) / sizeof (struct reg_entry) - 1;
+
+  do
+    {
+      int mid = (l + r) / 2;
+      int ans = strcmp (buf, gen_reg_table[mid].name);
+
+      if (ans < 0)
+	r = mid - 1;
+      else if (ans > 0)
+	l = mid + 1;
+      else
+	{
+	  *rptr = gen_reg_table[mid].code;
+	  *sptr = s;
+	  return 0;
+	}
+    }
+  while (l <= r);
+
+  return -1;
+}
+
+static int
+parse_fp_reg (char **sptr, int *rptr)
+{
+  char *s = skip_space (*sptr);
+  char buf[10];
+  int cnt;
+  int l, r;
+
+  cnt = 0;
+  memset (buf, '\0', 10);
+  while ((ISALNUM (*s)) && cnt < 10)
+    buf[cnt++] = TOLOWER (*s++);
+
+  l = 0;
+  r = sizeof (fp_reg_table) / sizeof (struct reg_entry) - 1;
+
+  do
+    {
+      int mid = (l + r) / 2;
+      int ans = strcmp (buf, fp_reg_table[mid].name);
+
+      if (ans < 0)
+	r = mid - 1;
+      else if (ans > 0)
+	l = mid + 1;
+      else
+	{
+	  *rptr = fp_reg_table[mid].code;
+	  *sptr = s;
+	  return 0;
+	}
+    }
+  while (l <= r);
+
+  return -1;
+}
+
+static int
+parse_cc (char **sptr, int *rptr)
+{
+  char *s = skip_space (*sptr);
+  char buf[10];
+  int cnt;
+  int l, r;
+
+  cnt = 0;
+  memset (buf, '\0', 10);
+  while ((ISALNUM (*s)) && cnt < 10)
+    buf[cnt++] = TOLOWER (*s++);
+
+  l = 0;
+  r = sizeof (cc_table) / sizeof (struct cc_entry) - 1;
+
+  do
+    {
+      int mid = (l + r) / 2;
+      int ans = strcmp (buf, cc_table[mid].name);
+
+      if (ans < 0)
+	r = mid - 1;
+      else if (ans > 0)
+	l = mid + 1;
+      else
+	{
+	  *rptr = cc_table[mid].code;
+	  *sptr = s;
+	  return 0;
+	}
+    }
+  while (l <= r);
+
+  return -1;
+}
+
+/* Previous dest is the destination register number of the instruction
+   before the current one.  */
+static int previous_dest = 0;
+static int previous_mode = 0;
+static int condition_code = 0;
+static int this_dest = 0;
+static int this_mode = 0;
+
+
+/* This is the main function in this file. It takes a line of assembly language
+   source code and assembles it. Note, labels and pseudo ops have already
+   been removed, so too has leading white space. */
+void
+md_assemble (char *str0)
+{
+  char *str = str0;
+  int cnt;
+  char mnem[10];
+  int opcode;
+  enum addressing_mode amode;
+  char arch_flags;
+  int ans;
+
+  char *output;
+  int reloc = 0;
+  relax_substateT relax = 0;
+  expressionS e1;
+  int r1, r2, r3;
+  int cc;
+  int indx;
+
+  /* Initialize the expression.  */
+  e1.X_op = O_absent;
+
+  /* Initialize destination register.
+     If the instruction we just looked at is in the delay slot of an
+     unconditional branch, then there is no index hazard.  */
+  if ((previous_mode == mode_cad || previous_mode == mode_ci)
+      && condition_code == 15)
+    this_dest = 0;
+
+  previous_dest = this_dest;
+  previous_mode = this_mode;
+  this_dest = 0;
+
+  /* Drop leading whitespace (probably not required).  */
+  while (*str == ' ')
+    str++;
+
+  /* Get opcode mnemonic and make sure it's in lower case.  */
+  cnt = 0;
+  memset (mnem, '\0', 10);
+  while ((ISALNUM (*str) || *str == '.' || *str == '_') && cnt < 10)
+    mnem[cnt++] = TOLOWER (*str++);
+
+  /* Look up mnemonic in opcode table, and get the code,
+     the instruction format, and the flags that indicate
+     which family members support this mnenonic.  */
+  if (get_opcode (&opcode, &amode, &arch_flags, mnem) < 0)
+    {
+      as_bad ("Unknown instruction mnenonic `%s'", mnem);
+      return;
+    }
+
+  if ((VISIUM_OPCODE_ARCH_MASK (visium_opcode_arch) & arch_flags) == 0)
+    {
+      as_bad ("Architecture mismatch on `%s'", mnem);
+      return;
+    }
+
+  this_mode = amode;
+
+  switch (amode)
+    {
+    case mode_d:
+      /* register :=
+         Example:
+         readmda r1  */
+      ans = parse_gen_reg (&str, &r1);
+      if (ans < 0)
+	{
+	  as_bad ("Dest register required");
+	  return;
+	}
+      opcode |= (r1 << 10);
+      this_dest = r1;
+      break;
+
+    case mode_a:
+      /* op= register
+         Example: asld r1  */
+      ans = parse_gen_reg (&str, &r1);
+      if (ans < 0)
+	{
+	  as_bad ("SourceA register required");
+	  return;
+	}
+      opcode |= (r1 << 16);
+      break;
+
+    case mode_ab:
+      /* register * register
+         Example:
+         mults r1,r2  */
+      ans = parse_gen_reg (&str, &r1);
+      if (ans < 0)
+	{
+	  as_bad ("SourceA register required");
+	  return;
+	}
+      str = skip_space (str);
+      if (*str == ',')
+	{
+	  str++;
+	  ans = parse_gen_reg (&str, &r2);
+	  if (ans < 0)
+	    {
+	      as_bad ("SourceB register required");
+	      return;
+	    }
+	  opcode |= (r1 << 16) | (r2 << 4);
+	}
+      else
+	{
+	  as_bad ("SourceB register required");
+	  return;
+	}
+      break;
+
+    case mode_da:
+      /* register := register
+         Example:
+         extb.l  r1,r2  */
+      ans = parse_gen_reg (&str, &r1);
+      if (ans < 0)
+	{
+	  as_bad ("Dest register required");
+	  return;
+	}
+      str = skip_space (str);
+      if (*str == ',')
+	{
+	  str++;
+	  ans = parse_gen_reg (&str, &r2);
+	  if (ans < 0)
+	    {
+	      as_bad ("SourceA register required");
+	      return;
+	    }
+	  opcode |= (r1 << 10) | (r2 << 16);
+	}
+      else
+	{
+	  as_bad ("SourceB register required");
+	  return;
+	}
+      this_dest = r1;
+      break;
+
+    case mode_dab:
+      /* register := register * register
+         Example:
+         add.l r1,r2,r3  */
+      ans = parse_gen_reg (&str, &r1);
+      if (ans < 0)
+	{
+	  as_bad ("Dest register required");
+	  return;
+	}
+      str = skip_space (str);
+      if (*str == ',')
+	{
+	  str++;
+	  ans = parse_gen_reg (&str, &r2);
+	  if (ans < 0)
+	    {
+	      as_bad ("SourceA register required");
+	      return;
+	    }
+	  str = skip_space (str);
+	  if (*str == ',')
+	    {
+	      str++;
+	      ans = parse_gen_reg (&str, &r3);
+	      if (ans < 0)
+		{
+		  as_bad ("SourceB register required");
+		  return;
+		}
+
+	      /* Got three regs, assemble instruction.  */
+	      opcode |= (r1 << 10) | (r2 << 16) | (r3 << 4);
+	    }
+	  else
+	    {
+	      as_bad ("SourceA register required");
+	      return;
+	    }
+	}
+      else
+	{
+	  as_bad ("Dest register required");
+	  return;
+	}
+      this_dest = r1;
+      break;
+
+    case mode_iab:
+      /* 5-bit immediate * register * register
+         Example:
+         eamwrite 3,r1,r2  */
+      str = parse_exp (str, &e1);
+      str = skip_space (str);
+      if (e1.X_op != O_absent && *str == ',')
+	{
+	  int eam_op = e1.X_add_number;
+
+	  str = skip_space (str + 1);
+	  ans = parse_gen_reg (&str, &r2);
+	  if (ans < 0)
+	    {
+	      as_bad ("SourceA register required");
+	      return;
+	    }
+	  str = skip_space (str);
+	  if (*str == ',')
+	    {
+	      str++;
+	      ans = parse_gen_reg (&str, &r3);
+	      if (ans < 0)
+		{
+		  as_bad ("SourceB register required");
+		  return;
+		}
+
+	      /* Got three operands, assemble instruction.  */
+	      if (eam_op < 0 || eam_op > 31)
+		{
+		  as_bad ("eam_op out of range");
+		}
+	      opcode |= ((eam_op & 0x1f) << 10) | (r2 << 16) | (r3 << 4);
+	    }
+	}
+      else
+	{
+	  as_bad ("EAM_OP required");
+	  return;
+	}
+      break;
+
+    case mode_0ab:
+      /* zero * register * register
+         Example:
+         cmp.l  r1,r2 */
+      ans = parse_gen_reg (&str, &r1);
+      if (ans < 0)
+	{
+	  as_bad ("SourceA register required");
+	  return;
+	}
+      str = skip_space (str);
+      if (*str == ',')
+	{
+	  str++;
+	  ans = parse_gen_reg (&str, &r2);
+	  if (ans < 0)
+	    {
+	      as_bad ("SourceB register required");
+	      return;
+	    }
+	  opcode |= (r1 << 16) | (r2 << 4);
+	}
+      else
+	{
+	  as_bad ("SourceB register required");
+	  return;
+	}
+      break;
+
+    case mode_da0:
+      /* register * register * zero
+         Example:
+         move.l  r1,r2  */
+      ans = parse_gen_reg (&str, &r1);
+      if (ans < 0)
+	{
+	  as_bad ("Dest register required");
+	  return;
+	}
+      str = skip_space (str);
+      if (*str == ',')
+	{
+	  str++;
+	  ans = parse_gen_reg (&str, &r2);
+	  if (ans < 0)
+	    {
+	      as_bad ("SourceA register required");
+	      return;
+	    }
+	  opcode |= (r1 << 10) | (r2 << 16);
+	}
+      else
+	{
+	  as_bad ("SourceA register required");
+	  return;
+	}
+      this_dest = r1;
+      break;
+
+    case mode_cad:
+      /* condition * register * register
+         Example:
+         bra  tr,r1,r2  */
+      ans = parse_cc (&str, &cc);
+      if (ans < 0)
+	{
+	  as_bad ("condition code required");
+	  return;
+	}
+
+      str = skip_space (str);
+      if (*str == ',')
+	{
+	  str = skip_space (str + 1);
+	  ans = parse_gen_reg (&str, &r2);
+	  if (ans < 0)
+	    {
+	      as_bad ("SourceA register required");
+	      return;
+	    }
+	  str = skip_space (str);
+	  if (*str == ',')
+	    {
+	      str++;
+	      ans = parse_gen_reg (&str, &r3);
+	      if (ans < 0)
+		{
+		  as_bad ("Dest register required");
+		  return;
+		}
+
+	      /* Got three operands, assemble instruction.  */
+	      opcode |= (cc << 27) | (r2 << 16) | (r3 << 10);
+	    }
+	  else
+	    {
+	      as_bad ("Dest register required");
+	      return;
+	    }
+	}
+      else
+	{
+	  as_bad ("SourceA register required");
+	  return;
+	}
+
+      if (previous_mode == mode_cad || previous_mode == mode_ci)
+	as_bad ("branch instruction in delay slot");
+
+      this_dest = r3;
+      condition_code = cc;
+      break;
+
+    case mode_das:
+      /* register := register * 5-bit imediate/register shift count
+         Example:
+         asl.l  r1,r2,4  */
+      ans = parse_gen_reg (&str, &r1);
+      if (ans < 0)
+	{
+	  as_bad ("Dest register required");
+	  return;
+	}
+      str = skip_space (str);
+      if (*str == ',')
+	{
+	  str++;
+	  ans = parse_gen_reg (&str, &r2);
+	  if (ans < 0)
+	    {
+	      as_bad ("SourceA register required");
+	      return;
+	    }
+	  str = skip_space (str);
+	  if (*str == ',')
+	    {
+	      str++;
+	      ans = parse_gen_reg (&str, &r3);
+	      if (ans == 0)
+		{
+		  opcode |= (r1 << 10) | (r2 << 16) | (r3 << 4);
+		}
+	      else
+		{
+		  str = parse_exp (str, &e1);
+		  if (e1.X_op == O_constant)
+		    {
+		      int imm = e1.X_add_number;
+
+		      if (imm < 0 || imm > 31)
+			as_bad ("immediate value out of range");
+
+		      opcode |=
+			(r1 << 10) | (r2 << 16) | (1 << 9) | ((imm & 0x1f) <<
+							      4);
+		    }
+		  else
+		    {
+		      as_bad ("immediate operand required");
+		      return;
+		    }
+		}
+	    }
+	}
+      else
+	{
+	  as_bad ("SourceA register required");
+	  return;
+	}
+      this_dest = r1;
+      break;
+
+    case mode_di:
+      /* register := 5-bit immediate
+         Example:
+         eamread r1,3  */
+      ans = parse_gen_reg (&str, &r1);
+      if (ans < 0)
+	{
+	  as_bad ("Dest register required");
+	  return;
+	}
+      str = skip_space (str);
+      if (*str == ',')
+	{
+	  str++;
+	  str = parse_exp (str, &e1);
+	  if (e1.X_op == O_constant)
+	    {
+	      int opnd2 = e1.X_add_number;
+
+	      if (opnd2 < 0 || opnd2 > 31)
+		{
+		  as_bad ("immediate operand out of range");
+		  return;
+		}
+	      opcode |= (r1 << 10) | ((opnd2 & 0x1f) << 4);
+	    }
+	  else
+	    {
+	      as_bad ("immediate operand required");
+	      return;
+	    }
+	}
+      else
+	{
+	  as_bad ("immediate operand required");
+	  return;
+	}
+      this_dest = r1;
+      break;
+
+    case mode_ir:
+      /* 5-bit immediate * register, e.g. trace 1,r1  */
+      str = parse_exp (str, &e1);
+      str = skip_space (str);
+      if (e1.X_op == O_constant && *str == ',')
+	{
+	  int opnd1 = e1.X_add_number;
+
+	  str = skip_space (str + 1);
+	  ans = parse_gen_reg (&str, &r2);
+	  if (ans < 0)
+	    {
+	      as_bad ("SourceA register required");
+	      return;
+	    }
+
+	  /* Got two operands, assemble instruction.  */
+	  if (opnd1 < 0 || opnd1 > 31)
+	    {
+	      as_bad ("1st operand out of range");
+	    }
+	  opcode |= ((opnd1 & 0x1f) << 10) | (r2 << 16);
+	}
+      else
+	{
+	  as_bad ("Immediate operand required");
+	  return;
+	}
+      break;
+
+    case mode_ai:
+      /* register *= 16-bit unsigned immediate
+         Example:
+         addi  r1,123  */
+      ans = parse_gen_reg (&str, &r1);
+      if (ans < 0)
+	{
+	  as_bad ("Dest register required");
+	  return;
+	}
+      opcode |= (r1 << 16);
+
+      str = skip_space (str);
+      if (*str != ',')
+	{
+	  as_bad ("immediate value missing");
+	  return;
+	}
+      this_dest = r1;
+
+      /* fall through...  */
+
+    case mode_i:
+      /* MOVIL/WRTL traditionally get an implicit "%l" applied
+	 to their immediate value.  For other opcodes, unless
+	 the immediate value is decorated with "%u" or "%l"
+	 it must be in the range 0 .. 65535.  */
+      if ((opcode & 0x7fe00000) == 0x04800000
+	  || (opcode & 0x7fe00000) == 0x05000000)
+	reloc = BFD_RELOC_VISIUM_LO16;
+      else
+	reloc = BFD_RELOC_VISIUM_IM16;
+
+      str = skip_space (str + 1);
+
+      if (*str == '%')
+	{
+	  if (str[1] == 'u')
+	    reloc = BFD_RELOC_VISIUM_HI16;
+	  else if (str[1] == 'l')
+	    reloc = BFD_RELOC_VISIUM_LO16;
+	  else
+	    {
+	      as_bad ("bad char after %%");
+	      return;
+	    }
+
+	  str += 2;
+	}
+      str = parse_exp (str, &e1);
+      if (e1.X_op != O_absent)
+	{
+	  if (e1.X_op == O_constant)
+	    {
+	      int imm = e1.X_add_number;
+
+	      if (reloc == BFD_RELOC_VISIUM_HI16)
+		opcode |= ((imm >> 16) & 0xffff);
+	      else if (reloc == BFD_RELOC_VISIUM_LO16)
+		opcode |= (imm & 0xffff);
+	      else
+		{
+		  if (imm < 0 || imm > 0xffff)
+		    as_bad ("immediate value out of range");
+
+		  opcode |= (imm & 0xffff);
+		}
+	      /* No relocation is needed.  */
+	      reloc = 0;
+	    }
+	}
+      else
+	{
+	  as_bad ("immediate value missing");
+	  return;
+	}
+      break;
+
+    case mode_bax:
+      /* register * register * 5-bit immediate,
+         SourceB * SourceA * Index
+         Examples
+         write.l (r1),r2
+         write.l 3(r1),r2  */
+      str = skip_space (str);
+
+      indx = 0;
+      if (*str != '(')
+	{
+	  str = parse_exp (str, &e1);
+	  if (e1.X_op == O_constant)
+	    {
+	      indx = e1.X_add_number;
+
+	      if (indx < 0 || indx > 31)
+		{
+		  as_bad ("Index out of range");
+		  return;
+		}
+	    }
+	  else
+	    {
+	      as_bad ("Index(SourceA) required");
+	      return;
+	    }
+	}
+
+      str = skip_space (str);
+
+      if (*str != '(')
+	{
+	  as_bad ("Index(SourceA) required");
+	  return;
+	}
+
+      str = skip_space (str + 1);
+
+      ans = parse_gen_reg (&str, &r1);
+      if (ans < 0)
+	{
+	  as_bad ("SourceA register required");
+	  return;
+	}
+      str = skip_space (str);
+      if (*str != ')')
+	{
+	  as_bad ("(SourceA) required");
+	  return;
+	}
+      str = skip_space (str + 1);
+
+      if (*str == ',')
+	{
+	  str = skip_space (str + 1);
+	  ans = parse_gen_reg (&str, &r2);
+	  if (ans < 0)
+	    {
+	      as_bad ("SourceB register required");
+	      return;
+	    }
+	}
+      else
+	{
+	  as_bad ("SourceB register required");
+	  return;
+	}
+
+      opcode |= (r1 << 16) | (r2 << 4) | ((indx & 0x1f) << 10);
+
+      if (indx != 0 && previous_mode == mode_cad)
+	{
+	  /* We're in a delay slot.
+	     If the base reg is the destination of the branch, then issue
+	     an error message.
+	     Otherwise it is safe to use the base and index.  */
+	  if (previous_dest != 0 && r1 == previous_dest)
+	    {
+	      as_bad ("base register not ready");
+	      return;
+	    }
+	}
+      else if (previous_dest != 0
+	       && r1 == previous_dest
+	       && (visium_arch == VISIUM_ARCH_MCM
+		   || visium_arch == VISIUM_ARCH_MCM24
+		   || (visium_arch == VISIUM_ARCH_DEF && indx != 0)))
+	{
+	  as_warn ("base register not ready, NOP inserted.");
+	  /* Insert a NOP before the write instruction.  */
+	  output = frag_more (4);
+	  memset (output, 0, 4);
+	}
+      break;
+
+    case mode_dax:
+      /*  register := register * 5-bit immediate
+         Examples:
+         read.b  r1,(r2)
+         read.w  r1,3(r2)  */
+      ans = parse_gen_reg (&str, &r1);
+      if (ans < 0)
+	{
+	  as_bad ("Dest register required");
+	  return;
+	}
+      str = skip_space (str);
+      if (*str != ',')
+	{
+	  as_bad ("SourceA required");
+	  return;
+	}
+      str = skip_space (str + 1);
+
+      indx = 0;
+      if (*str != '(')
+	{
+	  str = parse_exp (str, &e1);
+	  if (e1.X_op == O_constant)
+	    {
+	      indx = e1.X_add_number;
+
+	      if (indx < 0 || indx > 31)
+		{
+		  as_bad ("Index out of range");
+		  return;
+		}
+	    }
+	  else
+	    {
+	      as_bad ("Immediate 0 to 31 required");
+	      return;
+	    }
+	}
+      if (*str != '(')
+	{
+	  as_bad ("(SourceA) required");
+	  return;
+	}
+      str++;
+      ans = parse_gen_reg (&str, &r2);
+      if (ans < 0)
+	{
+	  as_bad ("SourceA register required");
+	  return;
+	}
+      str = skip_space (str);
+      if (*str != ')')
+	{
+	  as_bad ("(SourceA) required");
+	  return;
+	}
+      str++;
+      opcode |= (r1 << 10) | (r2 << 16) | ((indx & 0x1f) << 4);
+      this_dest = r1;
+
+      if (indx != 0 && previous_mode == mode_cad)
+	{
+	  /* We're in a delay slot.
+	     If the base reg is the destination of the branch, then issue
+	     an error message.
+	     Otherwise it is safe to use the base and index.  */
+	  if (previous_dest != 0 && r2 == previous_dest)
+	    {
+	      as_bad ("base register not ready");
+	      return;
+	    }
+	}
+      else if (previous_dest != 0
+	       && r2 == previous_dest
+	       && (visium_arch == VISIUM_ARCH_MCM
+		   || visium_arch == VISIUM_ARCH_MCM24
+		   || (visium_arch == VISIUM_ARCH_DEF && indx != 0)))
+	{
+	  as_warn ("base register not ready, NOP inserted.");
+	  /* Insert a NOP before the read instruction.  */
+	  output = frag_more (4);
+	  memset (output, 0, 4);
+	}
+      break;
+
+    case mode_s:
+      /* special mode
+         Example:
+         nop  */
+      str = skip_space (str);
+      break;
+
+    case mode_ci:
+      /* condition * 16-bit signed word displacement
+         Example:
+         brr L1  */
+      ans = parse_cc (&str, &cc);
+      if (ans < 0)
+	{
+	  as_bad ("condition code required");
+	  return;
+	}
+      opcode |= (cc << 27);
+
+      str = skip_space (str);
+      if (*str == ',')
+	{
+	  str = skip_space (str + 1);
+	  str = parse_exp (str, &e1);
+	  if (e1.X_op != O_absent)
+	    {
+	      if (e1.X_op == O_constant)
+		{
+		  int imm = e1.X_add_number;
+
+		  if (imm < -32768 || imm > 32767)
+		    as_bad ("immediate value out of range");
+
+		  /* The GR6 doesn't correctly handle a 0 displacement
+		     so we insert a NOP and change it to -1.  */
+		  if (imm == 0 && cc != 0 && visium_arch == VISIUM_ARCH_GR6)
+		    {
+		      output = frag_more (4);
+		      memset (output, 0, 4);
+		      imm = -1;
+		    }
+
+		  opcode |= (imm & 0xffff);
+		}
+	      else if (e1.X_op == O_symbol)
+		{
+		  /* The GR6 doesn't correctly handle a 0 displacement
+		     so the instruction requires relaxation.  */
+		  if (cc != 0 && visium_arch == VISIUM_ARCH_GR6)
+		    relax = amode;
+		  else
+		    reloc = BFD_RELOC_VISIUM_REL16;
+		}
+	      else
+		{
+		  as_bad ("immediate value missing");
+		  return;
+		}
+	    }
+	  else
+	    {
+	      as_bad ("immediate value missing");
+	      return;
+	    }
+	}
+      else
+	{
+	  as_bad ("immediate value missing");
+	  return;
+	}
+
+      if (previous_mode == mode_cad || previous_mode == mode_ci)
+	as_bad ("branch instruction in delay slot");
+
+      condition_code = cc;
+      break;
+
+    case mode_fdab:
+      /* float := float * float
+         Example
+         fadd    f4,f3,f2  */
+      ans = parse_fp_reg (&str, &r1);
+      if (ans < 0)
+	{
+	  as_bad ("floating point destination register required");
+	  return;
+	}
+      str = skip_space (str);
+      if (*str == ',')
+	{
+	  str++;
+	  ans = parse_fp_reg (&str, &r2);
+	  if (ans < 0)
+	    {
+	      as_bad ("floating point SourceA register required");
+	      return;
+	    }
+	  str = skip_space (str);
+	  if (*str == ',')
+	    {
+	      str++;
+	      ans = parse_fp_reg (&str, &r3);
+	      if (ans < 0)
+		{
+		  as_bad ("floating point SourceB register required");
+		  return;
+		}
+
+	      /* Got 3 floating regs, assemble instruction.  */
+	      opcode |= (r1 << 10) | (r2 << 16) | (r3 << 4);
+	    }
+	  else
+	    {
+	      as_bad ("floating point SourceB register required");
+	      return;
+	    }
+	}
+      else
+	{
+	  as_bad ("floating point SourceA register required");
+	  return;
+	}
+      break;
+
+    case mode_ifdab:
+      /* 4-bit immediate * float * float * float
+         Example
+         fpinst   10,f1,f2,f3  */
+      str = parse_exp (str, &e1);
+      str = skip_space (str);
+      if (e1.X_op != O_absent && *str == ',')
+	{
+	  int finst = e1.X_add_number;
+
+	  str = skip_space (str + 1);
+	  ans = parse_fp_reg (&str, &r1);
+	  if (ans < 0)
+	    {
+	      as_bad ("floating point destination register required");
+	      return;
+	    }
+	  str = skip_space (str);
+	  if (*str == ',')
+	    {
+	      str++;
+	      ans = parse_fp_reg (&str, &r2);
+	      if (ans < 0)
+		{
+		  as_bad ("floating point SourceA register required");
+		  return;
+		}
+	      str = skip_space (str);
+	      if (*str == ',')
+		{
+		  str++;
+		  ans = parse_fp_reg (&str, &r3);
+		  if (ans < 0)
+		    {
+		      as_bad ("floating point SourceB register required");
+		      return;
+		    }
+
+		  /* Got immediate and 3 floating regs,
+		     assemble instruction.  */
+		  if (finst < 0 || finst > 15)
+		    as_bad ("finst out of range");
+
+		  opcode |=
+		    ((finst & 0xf) << 27) | (r1 << 10) | (r2 << 16) | (r3 <<
+								       4);
+		}
+	      else
+		{
+		  as_bad ("floating point SourceB register required");
+		  return;
+		}
+	    }
+	  else
+	    {
+	      as_bad ("floating point SourceA register required");
+	      return;
+	    }
+	}
+      else
+	{
+	  as_bad ("finst missing");
+	  return;
+	}
+      break;
+
+    case mode_idfab:
+      /* 4-bit immediate * register * float * float
+         Example
+         fpuread   4,r25,f2,f3  */
+      str = parse_exp (str, &e1);
+      str = skip_space (str);
+      if (e1.X_op != O_absent && *str == ',')
+	{
+	  int finst = e1.X_add_number;
+
+	  str = skip_space (str + 1);
+	  ans = parse_gen_reg (&str, &r1);
+	  if (ans < 0)
+	    {
+	      as_bad ("destination general register required");
+	      return;
+	    }
+	  str = skip_space (str);
+	  if (*str == ',')
+	    {
+	      str++;
+	      ans = parse_fp_reg (&str, &r2);
+	      if (ans < 0)
+		{
+		  as_bad ("floating point SourceA register required");
+		  return;
+		}
+	      str = skip_space (str);
+	      if (*str == ',')
+		{
+		  str++;
+		  ans = parse_fp_reg (&str, &r3);
+		  if (ans < 0)
+		    {
+		      as_bad ("floating point SourceB register required");
+		      return;
+		    }
+
+		  /* Got immediate and 3 floating regs,
+		     assemble instruction.  */
+		  if (finst < 0 || finst > 15)
+		    as_bad ("finst out of range");
+
+		  opcode |=
+		    ((finst & 0xf) << 27) | (r1 << 10) | (r2 << 16) | (r3 <<
+								       4);
+		}
+	      else
+		{
+		  as_bad ("floating point SourceB register required");
+		  return;
+		}
+	    }
+	  else
+	    {
+	      as_bad ("floating point SourceA register required");
+	      return;
+	    }
+	}
+      else
+	{
+	  as_bad ("finst missing");
+	  return;
+	}
+      break;
+
+    case mode_fda:
+      /* float := float
+         Example
+         fsqrt    f4,f3  */
+      ans = parse_fp_reg (&str, &r1);
+      if (ans < 0)
+	{
+	  as_bad ("floating point destination register required");
+	  return;
+	}
+      str = skip_space (str);
+      if (*str == ',')
+	{
+	  str++;
+	  ans = parse_fp_reg (&str, &r2);
+	  if (ans < 0)
+	    {
+	      as_bad ("floating point source register required");
+	      return;
+	    }
+
+	  /* Got 2 floating regs, assemble instruction.  */
+	  opcode |= (r1 << 10) | (r2 << 16);
+	}
+      else
+	{
+	  as_bad ("floating point source register required");
+	  return;
+	}
+      break;
+
+    case mode_fdra:
+      /* float := register
+         Example
+         fload   f15,r6  */
+      ans = parse_fp_reg (&str, &r1);
+      if (ans < 0)
+	{
+	  as_bad ("floating point destination register required");
+	  return;
+	}
+      str = skip_space (str);
+      if (*str == ',')
+	{
+	  str++;
+	  ans = parse_gen_reg (&str, &r2);
+	  if (ans < 0)
+	    {
+	      as_bad ("SourceA general register required");
+	      return;
+	    }
+
+	  /* Got 2 regs, assemble instruction.  */
+	  opcode |= (r1 << 10) | (r2 << 16);
+	}
+      else
+	{
+	  as_bad ("SourceA general register required");
+	  return;
+	}
+      break;
+
+    case mode_rdfab:
+      /* register := float * float
+         Example
+         fcmp    r0,f4,f8
+         For the GR6, register must be r0 and can be omitted.  */
+      ans = parse_gen_reg (&str, &r1);
+      if (ans < 0)
+	{
+	  if (visium_opcode_arch == VISIUM_OPCODE_ARCH_GR5)
+	    {
+	      as_bad ("Dest general register required");
+	      return;
+	    }
+	  r1 = 0;
+	}
+      else
+	{
+	  if (r1 != 0 && visium_opcode_arch != VISIUM_OPCODE_ARCH_GR5)
+	    {
+	      as_bad ("FCMP/FCMPE can only use r0 as Dest register");
+	      return;
+	     }
+
+	  str = skip_space (str);
+	  if (*str == ',')
+	    str++;
+	  else
+	    {
+	      as_bad ("floating point SourceA register required");
+	      return;
+	    }
+	}
+
+      ans = parse_fp_reg (&str, &r2);
+      if (ans < 0)
+	{
+	  as_bad ("floating point SourceA register required");
+	  return;
+	}
+      str = skip_space (str);
+      if (*str == ',')
+	{
+	  str++;
+	  ans = parse_fp_reg (&str, &r3);
+	  if (ans < 0)
+	    {
+	      as_bad ("floating point SourceB register required");
+	      return;
+	    }
+
+	  /* Got 3 regs, assemble instruction.  */
+	  opcode |= (r1 << 10) | (r2 << 16) | (r3 << 4);
+	}
+
+      this_dest = r1;
+      break;
+
+    case mode_rdfa:
+      /* register := float
+         Example
+         fstore r5,f12  */
+      ans = parse_gen_reg (&str, &r1);
+      if (ans < 0)
+	{
+	  as_bad ("Dest general register required");
+	  return;
+	}
+      str = skip_space (str);
+      if (*str == ',')
+	{
+	  str++;
+	  ans = parse_fp_reg (&str, &r2);
+	  if (ans < 0)
+	    {
+	      as_bad ("floating point source register required");
+	      return;
+	    }
+
+	  /* Got 2 regs, assemble instruction.  */
+	  opcode |= (r1 << 10) | (r2 << 16);
+	}
+      else
+	{
+	  as_bad ("floating point source register required");
+	  return;
+	}
+
+      this_dest = r1;
+      break;
+
+    case mode_rrr:
+      /* register register register, all sources and destinations 
+         Example:
+         bmd   r1,r2,r3  */
+
+      ans = parse_gen_reg (&str, &r1);
+      if (ans < 0)
+	{
+	  as_bad ("destination address register required");
+	  return;
+	}
+      str = skip_space (str);
+      if (*str == ',')
+	{
+	  str++;
+	  ans = parse_gen_reg (&str, &r2);
+	  if (ans < 0)
+	    {
+	      as_bad ("source address register required");
+	      return;
+	    }
+	  str = skip_space (str);
+	  if (*str == ',')
+	    {
+	      str++;
+	      ans = parse_gen_reg (&str, &r3);
+	      if (ans < 0)
+		{
+		  as_bad ("count register required");
+		  return;
+		}
+
+	      /* We insist on three registers but the opcode can only use
+		 r1,r2,r3.  */
+	      if (r1 != 1 || r2 != 2 || r3 != 3)
+		{
+		  as_bad ("BMI/BMD can only use format op r1,r2,r3"); 
+		  return;
+		}
+
+	      /* Opcode is unmodified by what comes out of the table.  */
+	    }
+	  else
+	    {
+	      as_bad ("register required");
+	      return;
+	    }
+	}
+      else
+	{
+	  as_bad ("register required");
+	  return;
+	}
+
+      this_dest = r1;
+      break;
+
+    default:
+      break;
+    }
+
+  if (relax)
+    output = frag_var (rs_machine_dependent, 8, 4, relax, e1.X_add_symbol,
+		       e1.X_add_number, NULL);
+  else
+    output = frag_more (4);
+
+  /* Build the 32-bit instruction in a host-endian-neutral fashion.  */
+  output[0] = (opcode >> 24) & 0xff;
+  output[1] = (opcode >> 16) & 0xff;
+  output[2] = (opcode >> 8) & 0xff;
+  output[3] = (opcode >> 0) & 0xff;
+
+  if (relax)
+    /* The size of the instruction is unknown, so tie the debug info to the
+       start of the instruction.  */
+    dwarf2_emit_insn (0);
+  else
+    {
+      if (reloc)
+	fix_new_exp (frag_now, output - frag_now->fr_literal, 4, &e1,
+		     reloc == BFD_RELOC_VISIUM_REL16, reloc);
+      else
+	visium_update_parity_bit (output);
+
+      dwarf2_emit_insn (4);
+    }
+
+  if (*str != '\0')
+    as_bad ("junk after instruction");
+}
+
+void
+visium_cfi_frame_initial_instructions (void)
+{
+  /* The CFA is in SP on function entry.  */
+  cfi_add_CFA_def_cfa (23, 0);
+}
+
+int
+visium_regname_to_dw2regnum (char *regname)
+{
+  if (!regname[0])
+    return -1;
+
+  if (regname[0] == 'f' && regname[1] == 'p' && !regname[2])
+    return 22;
+
+  if (regname[0] == 's' && regname[1] == 'p' && !regname[2])
+    return 23;
+
+  if (regname[0] == 'm' && regname[1] == 'd' && !regname[3])
+    switch (regname[2])
+      {
+      case 'b': return 32;
+      case 'a': return 33;
+      case 'c': return 34;
+      default : return -1;
+      }
+
+  if (regname[0] == 'f' || regname[0] == 'r')
+    {
+      char *p;
+      unsigned int regnum = strtoul (regname + 1, &p, 10);
+      if (*p)
+	return -1;
+      if (regnum >= (regname[0] == 'f' ? 16 : 32))
+	return -1;
+      if (regname[0] == 'f')
+	regnum += 35;
+      return regnum;
+    }
+
+  return -1;
+}
diff --git a/gas/config/tc-visium.h b/gas/config/tc-visium.h
new file mode 100644
index 0000000..6e1f791
--- /dev/null
+++ b/gas/config/tc-visium.h
@@ -0,0 +1,79 @@
+/* tc-visium.h -- Header file for tc-visium.c.
+
+   Copyright (C) 2005-2014 Free Software Foundation, Inc.
+
+   This file is part of GAS, the GNU Assembler.
+
+   GAS is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   GAS is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GAS; see the file COPYING.  If not, write to
+   the Free Software Foundation, 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA. */
+
+#define TC_VISIUM
+
+#define LISTING_HEADER "VISIUM GAS "
+
+/* The target BFD architecture.  */
+#define TARGET_ARCH bfd_arch_visium
+
+#define TARGET_BYTES_BIG_ENDIAN 1
+
+#define TARGET_FORMAT "elf32-visium"
+
+/* Permit temporary numeric labels.  */
+#define LOCAL_LABELS_FB 1
+
+/* .-foo gets turned into PC relative relocs.  */
+#define DIFF_EXPR_OK
+
+/* We don't support external symbols overriding.  */
+#define EXTERN_FORCE_RELOC 0
+
+/* We don't need to handle .word strangely.  */
+#define WORKING_DOT_WORD
+
+#define tc_fix_adjustable(FIXP) visium_fix_adjustable (FIXP)
+extern bfd_boolean visium_fix_adjustable (struct fix *);
+
+#define HANDLE_ALIGN(FRAGP)		 \
+  if ((FRAGP)->fr_type == rs_align_code) \
+    visium_handle_align (FRAGP);
+extern void visium_handle_align (struct frag *);
+
+#define md_relax_frag(segment, fragp, stretch) \
+  visium_relax_frag (segment, fragp, stretch)
+extern int visium_relax_frag (asection *, struct frag *, long);
+
+/* Call md_pcrel_from_section, not md_pcrel_from.  */
+#define MD_PCREL_FROM_SECTION(FIXP, SEC) visium_pcrel_from_section (FIXP, SEC)
+extern long visium_pcrel_from_section (struct fix *, segT);
+
+/* Values passed to md_apply_fix3 don't include the symbol value.  */
+#define MD_APPLY_SYM_VALUE(FIX) 0
+
+#define md_operand(x)
+
+#define tc_comment_chars visium_comment_chars
+extern const char *visium_comment_chars;
+
+#define TARGET_USE_CFIPOP 1
+
+#define tc_cfi_frame_initial_instructions visium_cfi_frame_initial_instructions
+extern void visium_cfi_frame_initial_instructions (void);
+
+#define tc_regname_to_dw2regnum visium_regname_to_dw2regnum
+extern int visium_regname_to_dw2regnum (char *regname);
+
+#define DWARF2_LINE_MIN_INSN_LENGTH     4
+#define DWARF2_DEFAULT_RETURN_COLUMN    21
+#define DWARF2_CIE_DATA_ALIGNMENT       (-4)
diff --git a/gas/configure.tgt b/gas/configure.tgt
index d07d445..853988a 100644
--- a/gas/configure.tgt
+++ b/gas/configure.tgt
@@ -107,6 +107,7 @@ case ${cpu} in
   tilegx*be)		cpu_type=tilegx endian=big ;;
   tilegx*)		cpu_type=tilegx endian=little ;;
   v850*)		cpu_type=v850 ;;
+  visium)		cpu_type=visium endian=big ;;
   x86_64*)		cpu_type=i386 arch=x86_64;;
   xgate)		cpu_type=xgate ;;
   xtensa*)		cpu_type=xtensa arch=xtensa ;;
@@ -453,6 +454,8 @@ case ${generic_target} in
   vax-*-netbsdelf*)			fmt=elf em=nbsd ;;
   vax-*-linux-*)			fmt=elf em=linux ;;
 
+  visium-*-elf)				fmt=elf ;;
+
   xstormy16-*-*)			fmt=elf ;;
   
   xgate-*-*)    			fmt=elf ;;
diff --git a/gas/po/POTFILES.in b/gas/po/POTFILES.in
index d1fd07f..3514075 100644
--- a/gas/po/POTFILES.in
+++ b/gas/po/POTFILES.in
@@ -161,6 +161,8 @@ config/tc-v850.c
 config/tc-v850.h
 config/tc-vax.c
 config/tc-vax.h
+config/tc-visium.c
+config/tc-visium.h
 config/tc-xc16x.c
 config/tc-xc16x.h
 config/tc-xgate.c
diff --git a/gas/testsuite/gas/elf/elf.exp b/gas/testsuite/gas/elf/elf.exp
index af5dbb2..291c2a7 100644
--- a/gas/testsuite/gas/elf/elf.exp
+++ b/gas/testsuite/gas/elf/elf.exp
@@ -172,11 +172,12 @@ if { [is_elf_format] } then {
     run_dump_test "symver"
 
     # No indirect functions on non-GNU targets.
-    # The MSP port sets the ELF header's OSABI field to ELFOSABI_STANDALONE.
+    # The Visium and MSP set the ELF header's OSABI field to ELFOSABI_STANDALONE.
     # The non-eabi ARM ports sets it to ELFOSABI_ARM.
     # So for these targets we cannot include an IFUNC symbol type
     # in the symbol type test.
     if { [istarget "*-*-hpux*"]
+	 || [istarget "visium-*-*"]
 	 || [istarget "msp*-*-*"]
 	 || [istarget "arm*-*-*"]} then {
 	# hppa64 has a non-standard common directive

-- 
1.7.7

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 5/6] Add Visium support to gas
  2014-12-04 12:09 ` [PATCH 5/6] Add Visium support to gas Eric Botcazou
@ 2014-12-04 15:17   ` Joseph Myers
  2014-12-05 12:03     ` Eric Botcazou
  2014-12-05  2:26   ` Alan Modra
  1 sibling, 1 reply; 17+ messages in thread
From: Joseph Myers @ 2014-12-04 15:17 UTC (permalink / raw)
  To: Eric Botcazou; +Cc: binutils, Eric Botcazou

This patch appears to be missing .texi documentation for machine-specific 
assembler command-line options.  
(<https://sourceware.org/ml/binutils/2010-11/msg00397.html> discusses how 
to arrange such documentation to get it into the relevant places in the 
manual, including the generated manpage, without duplicating it in the 
sources.)

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 5/6] Add Visium support to gas
  2014-12-04 12:09 ` [PATCH 5/6] Add Visium support to gas Eric Botcazou
  2014-12-04 15:17   ` Joseph Myers
@ 2014-12-05  2:26   ` Alan Modra
  2014-12-05 12:30     ` Eric Botcazou
  1 sibling, 1 reply; 17+ messages in thread
From: Alan Modra @ 2014-12-05  2:26 UTC (permalink / raw)
  To: Eric Botcazou; +Cc: binutils, Eric Botcazou

On Thu, Dec 04, 2014 at 07:08:33AM -0500, Eric Botcazou wrote:
> +void
> +md_apply_fix (fixS * fixP, valueT * value, segT segment)
[snip]
> +	case BFD_RELOC_VISIUM_HI16:
> +	case BFD_RELOC_VISIUM_HI16_PCREL:
> +	  if (!fixP->fx_addsy)
> +	    {
> +	      insn = (insn & 0xffff0000) | ((val >> 16) & 0x0000ffff);
> +	    }
> +	  else
> +	    {
> +	      /* FIXME: Need comment explaining why we do this.  */
> +	      insn = (insn & 0xffff0000);
> +	    }
> +	  break;

Heh.  I'd like an explanation too.  :)  If the clearing is necessary
it indicates to me that you have a bug somewhere in md_assemble
setting the field non-zero..

BTW, since your target is rela, you don't need to write to the field
if you're emitting a reloc (which will happen if fx_done is clear on
exit from md_apply_fix).  It's cleaner to leave the field zero rather
than writing in the addend.

Also, I don't see any check on fx_subsy.  You should emit an error if
fx_subsy is present and not handled.

> +  /* Are we finished with this relocation now?  */
> +  if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
> +    fixP->fx_done = 1;

That !fixP->fx_pcrel lools suspicious.  Why punt all pcrel to the
linker?

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 3/6] Add Visium support to bfd
  2014-12-04  0:45   ` Alan Modra
@ 2014-12-05 10:21     ` Eric Botcazou
  0 siblings, 0 replies; 17+ messages in thread
From: Eric Botcazou @ 2014-12-05 10:21 UTC (permalink / raw)
  To: binutils; +Cc: Alan Modra

> Lose "set_" in the name, you're not setting anything here.

Renamed into visium_parity_bit.

> Also p ^= might save some future trouble, since bfd_vma can be 64-bit.

Right, I agree that the ^= idiom is clearly superior here.  Also changed in 
the assembler (visium_update_parity_bit).

> > +  sym_hashes_end =
> > +    sym_hashes + symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
> > +  if (!elf_bad_symtab (abfd))
> > +    sym_hashes_end -= symtab_hdr->sh_info;
> 
> You won't ever have elf_bad_symtab set and in any case, sym_hashes_end
> looks to be unused.

Removed.

> > +   There is some attempt to make this function usable for many
> > architectures, +   both USE_REL and USE_RELA ['twould be nice if such a
> > critter existed], +   if only to serve as a learning tool.
> 
> Really?

No. :-)  Head comment ditched (and ATTRIBUTE_UNUSED removed from output_bfd).

Thanks for the review.

-- 
Eric Botcazou

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 5/6] Add Visium support to gas
  2014-12-04 15:17   ` Joseph Myers
@ 2014-12-05 12:03     ` Eric Botcazou
  2014-12-06 16:00       ` Eric Botcazou
  0 siblings, 1 reply; 17+ messages in thread
From: Eric Botcazou @ 2014-12-05 12:03 UTC (permalink / raw)
  To: Joseph Myers; +Cc: binutils

[-- Attachment #1: Type: text/plain, Size: 1044 bytes --]

> This patch appears to be missing .texi documentation for machine-specific
> assembler command-line options.
> (<https://sourceware.org/ml/binutils/2010-11/msg00397.html> discusses how
> to arrange such documentation to get it into the relevant places in the
> manual, including the generated manpage, without duplicating it in the
> sources.)

Sorry about that.  Attached is the missing patch for gas/doc.

gas/ChangeLog

	* doc/Makefile.am (CPU_DOCS): Move c-vax.texi and add c-visium.texi.
	* doc/Makefile.in: Regenerate.
	* doc/all.texi (CPUs of interest): Add VISIUM.
	* doc/as.texinfo (Overview): Add VISIUM case.
	(Options): Likewise.
	(Machine Dependent Features): Likewise.  Reorder entries.
	* doc/c-visium.texi: New file.


 Makefile.am   |    3 ++-
 Makefile.in   |    3 ++-
 all.texi      |    1 +
 as.texinfo    |   56 ++++++++++++++++++++++++++++++++++++++++++--------------
 c-visium.texi |   58 
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 105 insertions(+), 16 deletions(-)

-- 
Eric Botcazou

[-- Attachment #2: gas_doc.diff --]
[-- Type: text/x-patch, Size: 5533 bytes --]

diff --git a/gas/doc/Makefile.am b/gas/doc/Makefile.am
index c2ddc02..2c179e4 100644
--- a/gas/doc/Makefile.am
+++ b/gas/doc/Makefile.am
@@ -91,8 +91,9 @@ CPU_DOCS = \
         c-tic6x.texi \
 	c-tilegx.texi \
 	c-tilepro.texi \
-	c-vax.texi \
 	c-v850.texi \
+	c-vax.texi \
+	c-visium.texi \
 	c-xgate.texi \
 	c-xstormy16.texi \
 	c-xtensa.texi \
diff --git a/gas/doc/Makefile.in b/gas/doc/Makefile.in
index 2db5121..4b5f4b7 100644
--- a/gas/doc/Makefile.in
+++ b/gas/doc/Makefile.in
@@ -333,8 +333,9 @@ CPU_DOCS = \
         c-tic6x.texi \
 	c-tilegx.texi \
 	c-tilepro.texi \
-	c-vax.texi \
 	c-v850.texi \
+	c-vax.texi \
+	c-visium.texi \
 	c-xgate.texi \
 	c-xstormy16.texi \
 	c-xtensa.texi \
diff --git a/gas/doc/all.texi b/gas/doc/all.texi
index 94b88bf..c578000 100644
--- a/gas/doc/all.texi
+++ b/gas/doc/all.texi
@@ -74,6 +74,7 @@
 @set TILEPRO
 @set V850
 @set VAX
+@set VISIUM
 @set XGATE
 @set XSTORMY16
 @set XTENSA
diff --git a/gas/doc/as.texinfo b/gas/doc/as.texinfo
index 243851b..17ae245 100644
--- a/gas/doc/as.texinfo
+++ b/gas/doc/as.texinfo
@@ -529,7 +529,6 @@ gcc(1), ld(1), and the Info entries for @file{binutils} and @file{ld}.
  [@b{-mcpu=54[123589]}|@b{-mcpu=54[56]lp}] [@b{-mfar-mode}|@b{-mf}]
  [@b{-merrors-to-file} @var{<filename>}|@b{-me} @var{<filename>}]
 @end ifset
-
 @ifset TIC6X
 
 @emph{Target TIC6X options:}
@@ -545,7 +544,11 @@ gcc(1), ld(1), and the Info entries for @file{binutils} and @file{ld}.
 @ifset TILEPRO
 @c TILEPro has no machine-dependent assembler options
 @end ifset
+@ifset VISIUM
 
+@emph{Target Visium options:}
+   [@b{-mtune=@var{arch}}]
+@end ifset
 @ifset XTENSA
 
 @emph{Target Xtensa options:}
@@ -555,7 +558,6 @@ gcc(1), ld(1), and the Info entries for @file{binutils} and @file{ld}.
  [@b{--rename-section} @var{oldname}=@var{newname}]
  [@b{--[no-]trampolines}]
 @end ifset
-
 @ifset Z80
 
 @emph{Target Z80 options:}
@@ -567,8 +569,8 @@ gcc(1), ld(1), and the Info entries for @file{binutils} and @file{ld}.
   [@b{ -forbid-undocumented-instructions}] [@b{-Fud}]
   [@b{ -forbid-unportable-instructions}] [@b{-Fup}]
 @end ifset
-
 @ifset Z8000
+
 @c Z8000 has no machine-dependent assembler options
 @end ifset
 
@@ -1638,6 +1640,25 @@ processor.
 
 @end ifset
 
+@ifset VISIUM
+
+@ifclear man
+@xref{Visium Options}, for the options available when @value{AS} is configured
+for a Visium processor.
+@end ifclear
+
+@ifset man
+@c man begin OPTIONS
+The following option is available when @value{AS} is configured for a Visium
+processor.
+@c man end
+@c man begin INCLUDE
+@include c-visium.texi
+@c ended inside the included file
+@end ifset
+
+@end ifset
+
 @ifset XTENSA
 
 @ifclear man
@@ -7268,6 +7289,12 @@ subject, see the hardware manufacturer's manual.
 @ifset V850
 * V850-Dependent::              V850 Dependent Features
 @end ifset
+@ifset VAX
+* Vax-Dependent::               VAX Dependent Features
+@end ifset
+@ifset VISIUM
+* Visium-Dependent::            Visium Dependent Features
+@end ifset
 @ifset XGATE
 * XGATE-Dependent::             XGATE Features
 @end ifset
@@ -7283,9 +7310,6 @@ subject, see the hardware manufacturer's manual.
 @ifset Z8000
 * Z8000-Dependent::             Z8000 Dependent Features
 @end ifset
-@ifset VAX
-* Vax-Dependent::               VAX Dependent Features
-@end ifset
 @end menu
 
 @lowersections
@@ -7498,20 +7522,16 @@ family.
 @include c-tilepro.texi
 @end ifset
 
-@ifset Z80
-@include c-z80.texi
-@end ifset
-
-@ifset Z8000
-@include c-z8k.texi
+@ifset V850
+@include c-v850.texi
 @end ifset
 
 @ifset VAX
 @include c-vax.texi
 @end ifset
 
-@ifset V850
-@include c-v850.texi
+@ifset VISIUM
+@include c-visium.texi
 @end ifset
 
 @ifset XGATE
@@ -7526,6 +7546,14 @@ family.
 @include c-xtensa.texi
 @end ifset
 
+@ifset Z80
+@include c-z80.texi
+@end ifset
+
+@ifset Z8000
+@include c-z8k.texi
+@end ifset
+
 @ifset GENERIC
 @c reverse effect of @down at top of generic Machine-Dep chapter
 @raisesections
diff --git a/gas/doc/c-visium.texi b/gas/doc/c-visium.texi
new file mode 100644
index 0000000..9982608
--- /dev/null
+++ b/gas/doc/c-visium.texi
@@ -0,0 +1,58 @@
+@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
+@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 Registers::                 Register Names
+@end menu
+
+@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}.

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 5/6] Add Visium support to gas
  2014-12-05  2:26   ` Alan Modra
@ 2014-12-05 12:30     ` Eric Botcazou
  2014-12-06  3:04       ` Alan Modra
  0 siblings, 1 reply; 17+ messages in thread
From: Eric Botcazou @ 2014-12-05 12:30 UTC (permalink / raw)
  To: Alan Modra; +Cc: binutils

> Heh.  I'd like an explanation too.  :)  If the clearing is necessary
> it indicates to me that you have a bug somewhere in md_assemble
> setting the field non-zero..

Removed.

> BTW, since your target is rela, you don't need to write to the field
> if you're emitting a reloc (which will happen if fx_done is clear on
> exit from md_apply_fix).  It's cleaner to leave the field zero rather
> than writing in the addend.
> 
> Also, I don't see any check on fx_subsy.  You should emit an error if
> fx_subsy is present and not handled.

Neither tc-i386.c nor tc-sparc.c does that though.

> > +  /* Are we finished with this relocation now?  */
> > +  if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
> > +    fixP->fx_done = 1;
> 
> That !fixP->fx_pcrel lools suspicious.  Why punt all pcrel to the
> linker?

Because tc-sparc.c does exactly the same?  Removed.

-- 
Eric Botcazou

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 5/6] Add Visium support to gas
  2014-12-05 12:30     ` Eric Botcazou
@ 2014-12-06  3:04       ` Alan Modra
  2014-12-06 16:00         ` Eric Botcazou
  0 siblings, 1 reply; 17+ messages in thread
From: Alan Modra @ 2014-12-06  3:04 UTC (permalink / raw)
  To: Eric Botcazou; +Cc: binutils

On Fri, Dec 05, 2014 at 01:27:38PM +0100, Eric Botcazou wrote:
> > Also, I don't see any check on fx_subsy.  You should emit an error if
> > fx_subsy is present and not handled.
> 
> Neither tc-i386.c nor tc-sparc.c does that though.

Hmm.  Looks like TC_VALIDATE_FIX_SUB will cause a complaint, so this
isn't necessary.  This patch is OK, so I think the whole series can be
committed.

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 5/6] Add Visium support to gas
  2014-12-05 12:03     ` Eric Botcazou
@ 2014-12-06 16:00       ` Eric Botcazou
  0 siblings, 0 replies; 17+ messages in thread
From: Eric Botcazou @ 2014-12-06 16:00 UTC (permalink / raw)
  To: binutils; +Cc: Joseph Myers

> Sorry about that.  Attached is the missing patch for gas/doc.
> 
> gas/ChangeLog
> 
> 	* doc/Makefile.am (CPU_DOCS): Move c-vax.texi and add c-visium.texi.
> 	* doc/Makefile.in: Regenerate.
> 	* doc/all.texi (CPUs of interest): Add VISIUM.
> 	* doc/as.texinfo (Overview): Add VISIUM case.
> 	(Options): Likewise.
> 	(Machine Dependent Features): Likewise.  Reorder entries.
> 	* doc/c-visium.texi: New file.

I installed a more complete version of doc/c-visium.texi.

-- 
Eric Botcazou

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 5/6] Add Visium support to gas
  2014-12-06  3:04       ` Alan Modra
@ 2014-12-06 16:00         ` Eric Botcazou
  0 siblings, 0 replies; 17+ messages in thread
From: Eric Botcazou @ 2014-12-06 16:00 UTC (permalink / raw)
  To: Alan Modra; +Cc: binutils

> Hmm.  Looks like TC_VALIDATE_FIX_SUB will cause a complaint, so this
> isn't necessary.  This patch is OK, so I think the whole series can be
> committed.

Done.  Thanks a lot for the speedy review!

-- 
Eric Botcazou

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2014-12-06 16:00 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-12-03 23:29 [PATCH 0/6] binutils port for the Visium Eric Botcazou
2014-12-03 23:36 ` [PATCH 1/6] Update from upstream config repo Eric Botcazou
2014-12-03 23:36 ` [PATCH 6/6] Add Visium support to ld Eric Botcazou
2014-12-03 23:36 ` [PATCH 4/6] Add Visium support to binutils Eric Botcazou
2014-12-03 23:46 ` [PATCH 3/6] Add Visium support to bfd Eric Botcazou
2014-12-04  0:45   ` Alan Modra
2014-12-05 10:21     ` Eric Botcazou
2014-12-03 23:46 ` [PATCH 2/6] Add Visium support to opcodes Eric Botcazou
2014-12-04  0:48 ` [PATCH 0/6] binutils port for the Visium Alan Modra
2014-12-04 12:09 ` [PATCH 5/6] Add Visium support to gas Eric Botcazou
2014-12-04 15:17   ` Joseph Myers
2014-12-05 12:03     ` Eric Botcazou
2014-12-06 16:00       ` Eric Botcazou
2014-12-05  2:26   ` Alan Modra
2014-12-05 12:30     ` Eric Botcazou
2014-12-06  3:04       ` Alan Modra
2014-12-06 16:00         ` Eric Botcazou

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).