summaryrefslogtreecommitdiffstats
path: root/gas
diff options
context:
space:
mode:
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog20
-rw-r--r--gas/Makefile.am2
-rw-r--r--gas/Makefile.in17
-rw-r--r--gas/NEWS2
-rw-r--r--gas/config/obj-elf.c4
-rw-r--r--gas/config/tc-nios2.c3067
-rw-r--r--gas/config/tc-nios2.h125
-rw-r--r--gas/configure.tgt2
-rw-r--r--gas/doc/Makefile.am1
-rw-r--r--gas/doc/Makefile.in7
-rw-r--r--gas/doc/all.texi1
-rw-r--r--gas/doc/as.texinfo31
-rw-r--r--gas/doc/c-nios2.texi249
-rw-r--r--gas/testsuite/ChangeLog91
-rw-r--r--gas/testsuite/gas/nios2/add.d16
-rw-r--r--gas/testsuite/gas/nios2/add.s13
-rw-r--r--gas/testsuite/gas/nios2/align_fill.d23
-rw-r--r--gas/testsuite/gas/nios2/align_fill.s20
-rw-r--r--gas/testsuite/gas/nios2/align_text.d22
-rw-r--r--gas/testsuite/gas/nios2/align_text.s15
-rw-r--r--gas/testsuite/gas/nios2/and.d17
-rw-r--r--gas/testsuite/gas/nios2/and.s13
-rw-r--r--gas/testsuite/gas/nios2/branch.d21
-rw-r--r--gas/testsuite/gas/nios2/branch.s15
-rw-r--r--gas/testsuite/gas/nios2/break.d12
-rw-r--r--gas/testsuite/gas/nios2/break.s8
-rw-r--r--gas/testsuite/gas/nios2/bret.d8
-rw-r--r--gas/testsuite/gas/nios2/bret.s5
-rw-r--r--gas/testsuite/gas/nios2/cache.d17
-rw-r--r--gas/testsuite/gas/nios2/cache.s21
-rw-r--r--gas/testsuite/gas/nios2/call.d11
-rw-r--r--gas/testsuite/gas/nios2/call.s13
-rw-r--r--gas/testsuite/gas/nios2/call26.d76
-rw-r--r--gas/testsuite/gas/nios2/call26.s12
-rw-r--r--gas/testsuite/gas/nios2/cmp.d24
-rw-r--r--gas/testsuite/gas/nios2/cmp.s22
-rw-r--r--gas/testsuite/gas/nios2/comments.d26
-rw-r--r--gas/testsuite/gas/nios2/comments.s28
-rw-r--r--gas/testsuite/gas/nios2/complex.d12
-rw-r--r--gas/testsuite/gas/nios2/complex.s5
-rw-r--r--gas/testsuite/gas/nios2/ctl.d20
-rw-r--r--gas/testsuite/gas/nios2/ctl.s18
-rw-r--r--gas/testsuite/gas/nios2/custom.d13
-rw-r--r--gas/testsuite/gas/nios2/custom.s8
-rw-r--r--gas/testsuite/gas/nios2/etbt.d10
-rw-r--r--gas/testsuite/gas/nios2/etbt.s4
-rw-r--r--gas/testsuite/gas/nios2/flushda.d10
-rw-r--r--gas/testsuite/gas/nios2/flushda.s6
-rw-r--r--gas/testsuite/gas/nios2/illegal.l14
-rw-r--r--gas/testsuite/gas/nios2/illegal.s17
-rw-r--r--gas/testsuite/gas/nios2/jmp.d10
-rw-r--r--gas/testsuite/gas/nios2/jmp.s6
-rw-r--r--gas/testsuite/gas/nios2/ldb.d196
-rw-r--r--gas/testsuite/gas/nios2/ldb.s117
-rw-r--r--gas/testsuite/gas/nios2/ldh.d196
-rw-r--r--gas/testsuite/gas/nios2/ldh.s117
-rw-r--r--gas/testsuite/gas/nios2/ldw.d196
-rw-r--r--gas/testsuite/gas/nios2/ldw.s117
-rw-r--r--gas/testsuite/gas/nios2/lineseparator.d10
-rw-r--r--gas/testsuite/gas/nios2/lineseparator.s4
-rw-r--r--gas/testsuite/gas/nios2/mov.d11
-rw-r--r--gas/testsuite/gas/nios2/mov.s5
-rw-r--r--gas/testsuite/gas/nios2/movi.d13
-rw-r--r--gas/testsuite/gas/nios2/movi.s21
-rw-r--r--gas/testsuite/gas/nios2/movia.d18
-rw-r--r--gas/testsuite/gas/nios2/movia.s6
-rw-r--r--gas/testsuite/gas/nios2/mul.d19
-rw-r--r--gas/testsuite/gas/nios2/mul.s15
-rw-r--r--gas/testsuite/gas/nios2/nios2.exp75
-rw-r--r--gas/testsuite/gas/nios2/nor.d9
-rw-r--r--gas/testsuite/gas/nios2/nor.s5
-rw-r--r--gas/testsuite/gas/nios2/or.d11
-rw-r--r--gas/testsuite/gas/nios2/or.s7
-rw-r--r--gas/testsuite/gas/nios2/ret.d8
-rw-r--r--gas/testsuite/gas/nios2/ret.s5
-rw-r--r--gas/testsuite/gas/nios2/rol.d40
-rw-r--r--gas/testsuite/gas/nios2/rol.s15
-rw-r--r--gas/testsuite/gas/nios2/rotate.d17
-rw-r--r--gas/testsuite/gas/nios2/rotate.s13
-rw-r--r--gas/testsuite/gas/nios2/stb.d196
-rw-r--r--gas/testsuite/gas/nios2/stb.s117
-rw-r--r--gas/testsuite/gas/nios2/sth.d196
-rw-r--r--gas/testsuite/gas/nios2/sth.s117
-rw-r--r--gas/testsuite/gas/nios2/stw.d196
-rw-r--r--gas/testsuite/gas/nios2/stw.s117
-rw-r--r--gas/testsuite/gas/nios2/sub.d10
-rw-r--r--gas/testsuite/gas/nios2/sub.s4
-rw-r--r--gas/testsuite/gas/nios2/sync.d8
-rw-r--r--gas/testsuite/gas/nios2/sync.s5
-rw-r--r--gas/testsuite/gas/nios2/trap.d7
-rw-r--r--gas/testsuite/gas/nios2/trap.s3
-rw-r--r--gas/testsuite/gas/nios2/tret.d8
-rw-r--r--gas/testsuite/gas/nios2/tret.s5
-rw-r--r--gas/testsuite/gas/nios2/warn_noat.l5
-rw-r--r--gas/testsuite/gas/nios2/warn_noat.s8
-rw-r--r--gas/testsuite/gas/nios2/warn_nobreak.l9
-rw-r--r--gas/testsuite/gas/nios2/warn_nobreak.s12
-rw-r--r--gas/testsuite/gas/nios2/xor.d11
-rw-r--r--gas/testsuite/gas/nios2/xor.s7
99 files changed, 6534 insertions, 3 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index d064176ebd..01ac44d01f 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,23 @@
+2013-02-06 Sandra Loosemore <sandra@codesourcery.com>
+ Andrew Jenner <andrew@codesourcery.com>
+
+ Based on patches from Altera Corporation.
+
+ * Makefile.am (TARGET_CPU_CFILES): Add config/tc-nios2.c.
+ (TARGET_CPU_HFILES): Add config/tc-nios2.h.
+ * Makefile.in: Regenerated.
+ * configure.tgt: Add case for nios2*-linux*.
+ * config/obj-elf.c: Conditionally include elf/nios2.h.
+ * config/tc-nios2.c: New file.
+ * config/tc-nios2.h: New file.
+ * doc/Makefile.am (CPU_DOCS): Add c-nios2.texi.
+ * doc/Makefile.in: Regenerated.
+ * doc/all.texi: Set NIOSII.
+ * doc/as.texinfo (Overview): Add Nios II options.
+ (Machine Dependencies): Include c-nios2.texi.
+ * doc/c-nios2.texi: New file.
+ * NEWS: Note Altera Nios II support.
+
2013-02-06 Alan Modra <amodra@gmail.com>
PR gas/14255
diff --git a/gas/Makefile.am b/gas/Makefile.am
index 7729d4a7ce..5ed9d2a7f4 100644
--- a/gas/Makefile.am
+++ b/gas/Makefile.am
@@ -164,6 +164,7 @@ TARGET_CPU_CFILES = \
config/tc-moxie.c \
config/tc-msp430.c \
config/tc-mt.c \
+ config/tc-nios2.c \
config/tc-ns32k.c \
config/tc-openrisc.c \
config/tc-or32.c \
@@ -234,6 +235,7 @@ TARGET_CPU_HFILES = \
config/tc-mn10300.h \
config/tc-msp430.h \
config/tc-mt.h \
+ config/tc-nios2.h \
config/tc-ns32k.h \
config/tc-openrisc.h \
config/tc-or32.h \
diff --git a/gas/Makefile.in b/gas/Makefile.in
index c2a646ca48..c71e2844a1 100644
--- a/gas/Makefile.in
+++ b/gas/Makefile.in
@@ -433,6 +433,7 @@ TARGET_CPU_CFILES = \
config/tc-moxie.c \
config/tc-msp430.c \
config/tc-mt.c \
+ config/tc-nios2.c \
config/tc-ns32k.c \
config/tc-openrisc.c \
config/tc-or32.c \
@@ -503,6 +504,7 @@ TARGET_CPU_HFILES = \
config/tc-mn10300.h \
config/tc-msp430.h \
config/tc-mt.h \
+ config/tc-nios2.h \
config/tc-ns32k.h \
config/tc-openrisc.h \
config/tc-or32.h \
@@ -855,6 +857,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-moxie.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-msp430.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-mt.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-nios2.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-ns32k.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-openrisc.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-or32.Po@am__quote@
@@ -1468,6 +1471,20 @@ tc-mt.obj: config/tc-mt.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-mt.obj `if test -f 'config/tc-mt.c'; then $(CYGPATH_W) 'config/tc-mt.c'; else $(CYGPATH_W) '$(srcdir)/config/tc-mt.c'; fi`
+tc-nios2.o: config/tc-nios2.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tc-nios2.o -MD -MP -MF $(DEPDIR)/tc-nios2.Tpo -c -o tc-nios2.o `test -f 'config/tc-nios2.c' || echo '$(srcdir)/'`config/tc-nios2.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tc-nios2.Tpo $(DEPDIR)/tc-nios2.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='config/tc-nios2.c' object='tc-nios2.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-nios2.o `test -f 'config/tc-nios2.c' || echo '$(srcdir)/'`config/tc-nios2.c
+
+tc-nios2.obj: config/tc-nios2.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tc-nios2.obj -MD -MP -MF $(DEPDIR)/tc-nios2.Tpo -c -o tc-nios2.obj `if test -f 'config/tc-nios2.c'; then $(CYGPATH_W) 'config/tc-nios2.c'; else $(CYGPATH_W) '$(srcdir)/config/tc-nios2.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tc-nios2.Tpo $(DEPDIR)/tc-nios2.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='config/tc-nios2.c' object='tc-nios2.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-nios2.obj `if test -f 'config/tc-nios2.c'; then $(CYGPATH_W) 'config/tc-nios2.c'; else $(CYGPATH_W) '$(srcdir)/config/tc-nios2.c'; fi`
+
tc-ns32k.o: config/tc-ns32k.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tc-ns32k.o -MD -MP -MF $(DEPDIR)/tc-ns32k.Tpo -c -o tc-ns32k.o `test -f 'config/tc-ns32k.c' || echo '$(srcdir)/'`config/tc-ns32k.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tc-ns32k.Tpo $(DEPDIR)/tc-ns32k.Po
diff --git a/gas/NEWS b/gas/NEWS
index dbe88de66d..f453b4942f 100644
--- a/gas/NEWS
+++ b/gas/NEWS
@@ -1,5 +1,7 @@
-*- text -*-
+* Add support for Altera Nios II.
+
* Add support for the Imagination Technologies Meta processor.
* Add support for the v850e3v5.
diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c
index 64503283f5..3377261919 100644
--- a/gas/config/obj-elf.c
+++ b/gas/config/obj-elf.c
@@ -62,6 +62,10 @@
#include "elf/mep.h"
#endif
+#ifdef TC_NIOS2
+#include "elf/nios2.h"
+#endif
+
static void obj_elf_line (int);
static void obj_elf_size (int);
static void obj_elf_type (int);
diff --git a/gas/config/tc-nios2.c b/gas/config/tc-nios2.c
new file mode 100644
index 0000000000..841c45404d
--- /dev/null
+++ b/gas/config/tc-nios2.c
@@ -0,0 +1,3067 @@
+/* Altera Nios II assembler.
+ Copyright (C) 2012, 2013 Free Software Foundation, Inc.
+ Contributed by Nigel Gray (ngray@altera.com).
+ Contributed by Mentor Graphics, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+#include "as.h"
+#include "opcode/nios2.h"
+#include "elf/nios2.h"
+#include "tc-nios2.h"
+#include "bfd.h"
+#include "dwarf2dbg.h"
+#include "subsegs.h"
+#include "safe-ctype.h"
+#include "dw2gencfi.h"
+
+#ifndef OBJ_ELF
+/* We are not supporting any other target so we throw a compile time error. */
+OBJ_ELF not defined
+#endif
+
+/* We can choose our endianness at run-time, regardless of configuration. */
+extern int target_big_endian;
+
+/* This array holds the chars that always start a comment. If the
+ pre-processor is disabled, these aren't very useful. */
+const char 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 C style comments are always supported. */
+const char line_comment_chars[] = "#";
+
+/* This array holds machine specific line separator characters. */
+const char line_separator_chars[] = ";";
+
+/* Chars that can be used to separate mant from exp in floating point nums. */
+const char EXP_CHARS[] = "eE";
+
+/* Chars that mean this number is a floating point constant. */
+/* As in 0f12.456 */
+/* or 0d1.2345e12 */
+const char FLT_CHARS[] = "rRsSfFdDxXpP";
+
+/* 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. */
+
+/* Machine-dependent command-line options. */
+
+const char *md_shortopts = "r";
+
+struct option md_longopts[] = {
+#define OPTION_RELAX_ALL (OPTION_MD_BASE + 0)
+ {"relax-all", no_argument, NULL, OPTION_RELAX_ALL},
+#define OPTION_NORELAX (OPTION_MD_BASE + 1)
+ {"no-relax", no_argument, NULL, OPTION_NORELAX},
+#define OPTION_RELAX_SECTION (OPTION_MD_BASE + 2)
+ {"relax-section", no_argument, NULL, OPTION_RELAX_SECTION},
+#define OPTION_EB (OPTION_MD_BASE + 3)
+ {"EB", no_argument, NULL, OPTION_EB},
+#define OPTION_EL (OPTION_MD_BASE + 4)
+ {"EL", no_argument, NULL, OPTION_EL}
+};
+
+size_t md_longopts_size = sizeof (md_longopts);
+
+/* The assembler supports three different relaxation modes, controlled by
+ command-line options. */
+typedef enum
+{
+ relax_section = 0,
+ relax_none,
+ relax_all
+} relax_optionT;
+
+/* Struct contains all assembler options set with .set. */
+struct
+{
+ /* .set noat -> noat = 1 allows assembly code to use at without warning
+ and macro expansions generate a warning.
+ .set at -> noat = 0, assembly code using at warn but macro expansions
+ do not generate warnings. */
+ bfd_boolean noat;
+
+ /* .set nobreak -> nobreak = 1 allows assembly code to use ba,bt without
+ warning.
+ .set break -> nobreak = 0, assembly code using ba,bt warns. */
+ bfd_boolean nobreak;
+
+ /* .cmd line option -relax-all allows all branches and calls to be replaced
+ with longer versions.
+ -no-relax inhibits branch/call conversion.
+ The default value is relax_section, which relaxes branches within
+ a section. */
+ relax_optionT relax;
+
+} nios2_as_options = {FALSE, FALSE, relax_section};
+
+
+typedef struct nios2_insn_reloc
+{
+ /* Any expression in the instruction is parsed into this field,
+ which is passed to fix_new_exp() to generate a fixup. */
+ expressionS reloc_expression;
+
+ /* The type of the relocation to be applied. */
+ bfd_reloc_code_real_type reloc_type;
+
+ /* PC-relative. */
+ unsigned int reloc_pcrel;
+
+ /* The next relocation to be applied to the instruction. */
+ struct nios2_insn_reloc *reloc_next;
+} nios2_insn_relocS;
+
+/* This struct is used to hold state when assembling instructions. */
+typedef struct nios2_insn_info
+{
+ /* Assembled instruction. */
+ unsigned long insn_code;
+ /* Pointer to the relevant bit of the opcode table. */
+ const struct nios2_opcode *insn_nios2_opcode;
+ /* After parsing ptrs to the tokens in the instruction fill this array
+ it is terminated with a null pointer (hence the first +1).
+ The second +1 is because in some parts of the code the opcode
+ is not counted as a token, but still placed in this array. */
+ const char *insn_tokens[NIOS2_MAX_INSN_TOKENS + 1 + 1];
+
+ /* This holds information used to generate fixups
+ and eventually relocations if it is not null. */
+ nios2_insn_relocS *insn_reloc;
+} nios2_insn_infoS;
+
+/* This struct associates an argument assemble function with
+ an argument syntax string. Used by the assembler to find out
+ how to parse and assemble a set of instruction operands and
+ return the instruction field values. */
+typedef struct nios2_arg_info
+{
+ const char *args;
+ void (*assemble_args_func) (nios2_insn_infoS *insn_info);
+} nios2_arg_infoS;
+
+/* This struct is used to convert Nios II pseudo-ops into the
+ corresponding real op. */
+typedef struct nios2_ps_insn_info
+{
+ /* Map this pseudo_op... */
+ const char *pseudo_insn;
+
+ /* ...to this real instruction. */
+ const char *insn;
+
+ /* Call this function to modify the operands.... */
+ void (*arg_modifer_func) (char ** parsed_args, const char *arg, int num,
+ int start);
+
+ /* ...with these arguments. */
+ const char *arg_modifier;
+ int num;
+ int index;
+
+ /* If arg_modifier_func allocates new memory, provide this function
+ to free it afterwards. */
+ void (*arg_cleanup_func) (char **parsed_args, int num, int start);
+} nios2_ps_insn_infoS;
+
+/* Opcode hash table. */
+static struct hash_control *nios2_opcode_hash = NULL;
+#define nios2_opcode_lookup(NAME) \
+ ((struct nios2_opcode *) hash_find (nios2_opcode_hash, (NAME)))
+
+/* Register hash table. */
+static struct hash_control *nios2_reg_hash = NULL;
+#define nios2_reg_lookup(NAME) \
+ ((struct nios2_reg *) hash_find (nios2_reg_hash, (NAME)))
+
+/* Parse args hash table. */
+static struct hash_control *nios2_arg_hash = NULL;
+#define nios2_arg_lookup(NAME) \
+ ((nios2_arg_infoS *) hash_find (nios2_arg_hash, (NAME)))
+
+/* Pseudo-op hash table. */
+static struct hash_control *nios2_ps_hash = NULL;
+#define nios2_ps_lookup(NAME) \
+ ((nios2_ps_insn_infoS *) hash_find (nios2_ps_hash, (NAME)))
+
+/* The known current alignment of the current section. */
+static int nios2_current_align;
+static segT nios2_current_align_seg;
+
+static int nios2_auto_align_on = 1;
+
+/* The last seen label in the current section. This is used to auto-align
+ labels preceeding instructions. */
+static symbolS *nios2_last_label;
+
+#ifdef OBJ_ELF
+/* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
+symbolS *GOT_symbol;
+#endif
+
+
+/** Utility routines. */
+/* Function md_chars_to_number takes the sequence of
+ bytes in buf and returns the corresponding value
+ in an int. n must be 1, 2 or 4. */
+static valueT
+md_chars_to_number (char *buf, int n)
+{
+ int i;
+ valueT val;
+
+ gas_assert (n == 1 || n == 2 || n == 4);
+
+ val = 0;
+ if (target_big_endian)
+ for (i = 0; i < n; ++i)
+ val = val | ((buf[i] & 0xff) << 8 * (n - (i + 1)));
+ else
+ for (i = 0; i < n; ++i)
+ val = val | ((buf[i] & 0xff) << 8 * i);
+ return val;
+}
+
+
+/* This function turns a C long int, short int or char
+ into the series of bytes that represent the number
+ on the target machine. */
+void
+md_number_to_chars (char *buf, valueT val, int n)
+{
+ gas_assert (n == 1 || n == 2 || n == 4 || n == 8);
+ if (target_big_endian)
+ number_to_chars_bigendian (buf, val, n);
+ else
+ number_to_chars_littleendian (buf, val, n);
+}
+
+/* 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. */
+char *
+md_atof (int type, char *litP, int *sizeP)
+{
+ int prec;
+ LITTLENUM_TYPE words[4];
+ char *t;
+ int i;
+
+ switch (type)
+ {
+ case 'f':
+ prec = 2;
+ break;
+ case 'd':
+ prec = 4;
+ 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 * 2;
+
+ if (! target_big_endian)
+ for (i = prec - 1; i >= 0; i--, litP += 2)
+ md_number_to_chars (litP, (valueT) words[i], 2);
+ else
+ for (i = 0; i < prec; i++, litP += 2)
+ md_number_to_chars (litP, (valueT) words[i], 2);
+
+ return NULL;
+}
+
+/* Return true if STR starts with PREFIX, which should be a string literal. */
+#define strprefix(STR, PREFIX) \
+ (strncmp ((STR), PREFIX, strlen (PREFIX)) == 0)
+
+/* Return true if STR is prefixed with a control register name. */
+static int
+nios2_control_register_arg_p (const char *str)
+{
+ return (strprefix (str, "ctl")
+ || strprefix (str, "cpuid")
+ || strprefix (str, "status")
+ || strprefix (str, "estatus")
+ || strprefix (str, "bstatus")
+ || strprefix (str, "ienable")
+ || strprefix (str, "ipending")
+ || strprefix (str, "exception")
+ || strprefix (str, "pteaddr")
+ || strprefix (str, "tlbacc")
+ || strprefix (str, "tlbmisc")
+ || strprefix (str, "fstatus")
+ || strprefix (str, "config")
+ || strprefix (str, "mpubase")
+ || strprefix (str, "mpuacc")
+ || strprefix (str, "badaddr"));
+}
+
+/* Return true if STR is prefixed with a special relocation operator. */
+static int
+nios2_special_relocation_p (const char *str)
+{
+ return (strprefix (str, "%lo")
+ || strprefix (str, "%hi")
+ || strprefix (str, "%hiadj")
+ || strprefix (str, "%gprel")
+ || strprefix (str, "%got")
+ || strprefix (str, "%call")
+ || strprefix (str, "%gotoff_lo")
+ || strprefix (str, "%gotoff_hiadj")
+ || strprefix (str, "%tls_gd")
+ || strprefix (str, "%tls_ldm")
+ || strprefix (str, "%tls_ldo")
+ || strprefix (str, "%tls_ie")
+ || strprefix (str, "%tls_le")
+ || strprefix (str, "%gotoff"));
+}
+
+/* Checks whether the register name is a coprocessor
+ register - returns TRUE if it is, FALSE otherwise. */
+static bfd_boolean
+nios2_coproc_reg (const char *reg_name)
+{
+ gas_assert (reg_name != NULL);
+
+ /* Check that we do have a valid register name and that it is a
+ coprocessor register.
+ It must begin with c, not be a control register, and be a valid
+ register name. */
+ if (strprefix (reg_name, "c")
+ && !strprefix (reg_name, "ctl")
+ && hash_find (nios2_reg_hash, reg_name) != NULL)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+/* nop fill pattern for text section. */
+static char const nop[4] = { 0x3a, 0x88, 0x01, 0x00 };
+
+/* Handles all machine-dependent alignment needs. */
+static void
+nios2_align (int log_size, const char *pfill, symbolS *label)
+{
+ int align;
+ long max_alignment = 15;
+
+ /* The front end is prone to changing segments out from under us
+ temporarily when -g is in effect. */
+ int switched_seg_p = (nios2_current_align_seg != now_seg);
+
+ align = log_size;
+ if (align > max_alignment)
+ {
+ align = max_alignment;
+ as_bad (_("Alignment too large: %d. assumed"), align);
+ }
+ else if (align < 0)
+ {
+ as_warn (_("Alignment negative: 0 assumed"));
+ align = 0;
+ }
+
+ if (align != 0)
+ {
+ if (subseg_text_p (now_seg) && align >= 2)
+ {
+ /* First, make sure we're on a four-byte boundary, in case
+ someone has been putting .byte values the text section. */
+ if (nios2_current_align < 2 || switched_seg_p)
+ frag_align (2, 0, 0);
+
+ /* Now fill in the alignment pattern. */
+ if (pfill != NULL)
+ frag_align_pattern (align, pfill, sizeof nop, 0);
+ else
+ frag_align (align, 0, 0);
+ }
+ else
+ frag_align (align, 0, 0);
+
+ if (!switched_seg_p)
+ nios2_current_align = align;
+
+ /* If the last label was in a different section we can't align it. */
+ if (label != NULL && !switched_seg_p)
+ {
+ symbolS *sym;
+ int label_seen = FALSE;
+ struct frag *old_frag;
+ valueT old_value;
+ valueT new_value;
+
+ gas_assert (S_GET_SEGMENT (label) == now_seg);
+
+ old_frag = symbol_get_frag (label);
+ old_value = S_GET_VALUE (label);
+ new_value = (valueT) frag_now_fix ();
+
+ /* It is possible to have more than one label at a particular
+ address, especially if debugging is enabled, so we must
+ take care to adjust all the labels at this address in this
+ fragment. To save time we search from the end of the symbol
+ list, backwards, since the symbols we are interested in are
+ almost certainly the ones that were most recently added.
+ Also to save time we stop searching once we have seen at least
+ one matching label, and we encounter a label that is no longer
+ in the target fragment. Note, this search is guaranteed to
+ find at least one match when sym == label, so no special case
+ code is necessary. */
+ for (sym = symbol_lastP; sym != NULL; sym = symbol_previous (sym))
+ if (symbol_get_frag (sym) == old_frag
+ && S_GET_VALUE (sym) == old_value)
+ {
+ label_seen = TRUE;
+ symbol_set_frag (sym, frag_now);
+ S_SET_VALUE (sym, new_value);
+ }
+ else if (label_seen && symbol_get_frag (sym) != old_frag)
+ break;
+ }
+ record_alignment (now_seg, align);
+ }
+}
+
+
+/** Support for self-check mode. */
+
+/* Mode of the assembler. */
+typedef enum
+{
+ NIOS2_MODE_ASSEMBLE, /* Ordinary operation. */
+ NIOS2_MODE_TEST /* Hidden mode used for self testing. */
+} NIOS2_MODE;
+
+static NIOS2_MODE nios2_mode = NIOS2_MODE_ASSEMBLE;
+
+/* This function is used to in self-checking mode
+ to check the assembled instruction
+ opcode should be the assembled opcode, and exp_opcode
+ the parsed string representing the expected opcode. */
+static void
+nios2_check_assembly (unsigned int opcode, const char *exp_opcode)
+{
+ if (nios2_mode == NIOS2_MODE_TEST)
+ {
+ if (exp_opcode == NULL)
+ as_bad (_("expecting opcode string in self test mode"));
+ else if (opcode != strtoul (exp_opcode, NULL, 16))
+ as_bad (_("assembly 0x%08x, expected %s"), opcode, exp_opcode);
+ }
+}
+
+
+/** Support for machine-dependent assembler directives. */
+/* Handle the .align pseudo-op. This aligns to a power of two. It
+ also adjusts any current instruction label. We treat this the same
+ way the MIPS port does: .align 0 turns off auto alignment. */
+static void
+s_nios2_align (int ignore ATTRIBUTE_UNUSED)
+{
+ int align;
+ char fill;
+ const char *pfill = NULL;
+ long max_alignment = 15;
+
+ align = get_absolute_expression ();
+ if (align > max_alignment)
+ {
+ align = max_alignment;
+ as_bad (_("Alignment too large: %d. assumed"), align);
+ }
+ else if (align < 0)
+ {
+ as_warn (_("Alignment negative: 0 assumed"));
+ align = 0;
+ }
+
+ if (*input_line_pointer == ',')
+ {
+ input_line_pointer++;
+ fill = get_absolute_expression ();
+ pfill = (const char *) &fill;
+ }
+ else if (subseg_text_p (now_seg))
+ pfill = (const char *) &nop;
+ else
+ {
+ pfill = NULL;
+ nios2_last_label = NULL;
+ }
+
+ if (align != 0)
+ {
+ nios2_auto_align_on = 1;
+ nios2_align (align, pfill, nios2_last_label);
+ nios2_last_label = NULL;
+ }
+ else
+ nios2_auto_align_on = 0;
+
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the .text pseudo-op. This is like the usual one, but it
+ clears the saved last label and resets known alignment. */
+static void
+s_nios2_text (int i)
+{
+ s_text (i);
+ nios2_last_label = NULL;
+ nios2_current_align = 0;
+ nios2_current_align_seg = now_seg;
+}
+
+/* Handle the .data pseudo-op. This is like the usual one, but it
+ clears the saved last label and resets known alignment. */
+static void
+s_nios2_data (int i)
+{
+ s_data (i);
+ nios2_last_label = NULL;
+ nios2_current_align = 0;
+ nios2_current_align_seg = now_seg;
+}
+
+/* Handle the .section pseudo-op. This is like the usual one, but it
+ clears the saved last label and resets known alignment. */
+static void
+s_nios2_section (int ignore)
+{
+ obj_elf_section (ignore);
+ nios2_last_label = NULL;
+ nios2_current_align = 0;
+ nios2_current_align_seg = now_seg;
+}
+
+/* Explicitly unaligned cons. */
+static void
+s_nios2_ucons (int nbytes)
+{
+ int hold;
+ hold = nios2_auto_align_on;
+ nios2_auto_align_on = 0;
+ cons (nbytes);
+ nios2_auto_align_on = hold;
+}
+
+/* Handle the .sdata directive. */
+static void
+s_nios2_sdata (int ignore ATTRIBUTE_UNUSED)
+{
+ get_absolute_expression (); /* Ignored. */
+ subseg_new (".sdata", 0);
+ demand_empty_rest_of_line ();
+}
+
+/* .set sets assembler options eg noat/at and is also used
+ to set symbol values (.equ, .equiv ). */
+static void
+s_nios2_set (int equiv)
+{
+ char *directive = input_line_pointer;
+ char delim = get_symbol_end ();
+ char *endline = input_line_pointer;
+ *endline = delim;
+
+ /* We only want to handle ".set XXX" if the
+ user has tried ".set XXX, YYY" they are not
+ trying a directive. This prevents
+ us from polluting the name space. */
+ SKIP_WHITESPACE ();
+ if (is_end_of_line[(unsigned char) *input_line_pointer])
+ {
+ bfd_boolean done = TRUE;
+ *endline = 0;
+
+ if (!strcmp (directive, "noat"))
+ nios2_as_options.noat = TRUE;
+ else if (!strcmp (directive, "at"))
+ nios2_as_options.noat = FALSE;
+ else if (!strcmp (directive, "nobreak"))
+ nios2_as_options.nobreak = TRUE;
+ else if (!strcmp (directive, "break"))
+ nios2_as_options.nobreak = FALSE;
+ else if (!strcmp (directive, "norelax"))
+ nios2_as_options.relax = relax_none;
+ else if (!strcmp (directive, "relaxsection"))
+ nios2_as_options.relax = relax_section;
+ else if (!strcmp (directive, "relaxall"))
+ nios2_as_options.relax = relax_all;
+ else
+ done = FALSE;
+
+ if (done)
+ {
+ *endline = delim;
+ demand_empty_rest_of_line ();
+ return;
+ }
+ }
+
+ /* If we fall through to here, either we have ".set XXX, YYY"
+ or we have ".set XXX" where XXX is unknown or we have
+ a syntax error. */
+ input_line_pointer = directive;
+ *endline = delim;
+ s_set (equiv);
+}
+
+/* Machine-dependent assembler directives.
+ Format of each entry is:
+ { "directive", handler_func, param } */
+const pseudo_typeS md_pseudo_table[] = {
+ {"align", s_nios2_align, 0},
+ {"text", s_nios2_text, 0},
+ {"data", s_nios2_data, 0},
+ {"section", s_nios2_section, 0},
+ {"section.s", s_nios2_section, 0},
+ {"sect", s_nios2_section, 0},
+ {"sect.s", s_nios2_section, 0},
+ /* .dword and .half are included for compatibility with MIPS. */
+ {"dword", cons, 8},
+ {"half", cons, 2},
+ /* NIOS2 native word size is 4 bytes, so we override
+ the GAS default of 2. */
+ {"word", cons, 4},
+ /* Explicitly unaligned directives. */
+ {"2byte", s_nios2_ucons, 2},
+ {"4byte", s_nios2_ucons, 4},
+ {"8byte", s_nios2_ucons, 8},
+ {"16byte", s_nios2_ucons, 16},
+#ifdef OBJ_ELF
+ {"sdata", s_nios2_sdata, 0},
+#endif
+ {"set", s_nios2_set, 0},
+ {NULL, NULL, 0}
+};
+
+
+/** Relaxation support. */
+
+/* We support two relaxation modes: a limited PC-relative mode with
+ -relax-section (the default), and an absolute jump mode with -relax-all.
+
+ Nios II PC-relative branch instructions only support 16-bit offsets.
+ And, there's no good way to add a 32-bit constant to the PC without
+ using two registers.
+
+ To deal with this, for the pc-relative relaxation mode we convert
+ br label
+ into a series of 16-bit adds, like:
+ nextpc at
+ addi at, at, 32767
+ ...
+ addi at, at, remainder
+ jmp at
+
+ Similarly, conditional branches are converted from
+ b(condition) r, s, label
+ into a series like:
+ b(opposite condition) r, s, skip
+ nextpc at
+ addi at, at, 32767
+ ...
+ addi at, at, remainder
+ jmp at
+ skip:
+
+ The compiler can do a better job, either by converting the branch
+ directly into a JMP (going through the GOT for PIC) or by allocating
+ a second register for the 32-bit displacement.
+
+ For the -relax-all relaxation mode, the conversions are
+ movhi at, %hi(symbol+offset)
+ ori at, %lo(symbol+offset)
+ jmp at
+ and
+ b(opposite condition), r, s, skip
+ movhi at, %hi(symbol+offset)
+ ori at, %lo(symbol+offset)
+ jmp at
+ skip:
+ respectively.
+*/
+
+/* Arbitrarily limit the number of addis we can insert; we need to be able
+ to specify the maximum growth size for each frag that contains a
+ relaxable branch. There's no point in specifying a huge number here
+ since that means the assembler needs to allocate that much extra
+ memory for every branch, and almost no real code will ever need it.
+ Plus, as already noted a better solution is to just use a jmp, or
+ allocate a second register to hold a 32-bit displacement.
+ FIXME: Rather than making this a constant, it could be controlled by
+ a command-line argument. */
+#define RELAX_MAX_ADDI 32
+
+/* The fr_subtype field represents the target-specific relocation state.
+ It has type relax_substateT (unsigned int). We use it to track the
+ number of addis necessary, plus a bit to track whether this is a
+ conditional branch.
+ Regardless of the smaller RELAX_MAX_ADDI limit, we reserve 16 bits
+ in the fr_subtype to encode the number of addis so that the whole
+ theoretically-valid range is representable.
+ For the -relax-all mode, N = 0 represents an in-range branch and N = 1
+ represents a branch that needs to be relaxed. */
+#define UBRANCH (0 << 16)
+#define CBRANCH (1 << 16)
+#define IS_CBRANCH(SUBTYPE) ((SUBTYPE) & CBRANCH)
+#define IS_UBRANCH(SUBTYPE) (!IS_CBRANCH (SUBTYPE))
+#define UBRANCH_SUBTYPE(N) (UBRANCH | (N))
+#define CBRANCH_SUBTYPE(N) (CBRANCH | (N))
+#define SUBTYPE_ADDIS(SUBTYPE) ((SUBTYPE) & 0xffff)
+
+/* For the -relax-section mode, unconditional branches require 2 extra i
+ nstructions besides the addis, conditional branches require 3. */
+#define UBRANCH_ADDIS_TO_SIZE(N) (((N) + 2) * 4)
+#define CBRANCH_ADDIS_TO_SIZE(N) (((N) + 3) * 4)
+
+/* For the -relax-all mode, unconditional branches require 3 instructions
+ and conditional branches require 4. */
+#define UBRANCH_JUMP_SIZE 12
+#define CBRANCH_JUMP_SIZE 16
+
+/* Maximum sizes of relaxation sequences. */
+#define UBRANCH_MAX_SIZE \
+ (nios2_as_options.relax == relax_all \
+ ? UBRANCH_JUMP_SIZE \
+ : UBRANCH_ADDIS_TO_SIZE (RELAX_MAX_ADDI))
+#define CBRANCH_MAX_SIZE \
+ (nios2_as_options.relax == relax_all \
+ ? CBRANCH_JUMP_SIZE \
+ : CBRANCH_ADDIS_TO_SIZE (RELAX_MAX_ADDI))
+
+/* Register number of AT, the assembler temporary. */
+#define AT_REGNUM 1
+
+/* Determine how many bytes are required to represent the sequence
+ indicated by SUBTYPE. */
+static int
+nios2_relax_subtype_size (relax_substateT subtype)
+{
+ int n = SUBTYPE_ADDIS (subtype);
+ if (n == 0)
+ /* Regular conditional/unconditional branch instruction. */
+ return 4;
+ else if (nios2_as_options.relax == relax_all)
+ return (IS_CBRANCH (subtype) ? CBRANCH_JUMP_SIZE : UBRANCH_JUMP_SIZE);
+ else if (IS_CBRANCH (subtype))
+ return CBRANCH_ADDIS_TO_SIZE (n);
+ else
+ return UBRANCH_ADDIS_TO_SIZE (n);
+}
+
+/* Estimate size of fragp before relaxation.
+ This could also examine the offset in fragp and adjust
+ fragp->fr_subtype, but we will do that in nios2_relax_frag anyway. */
+int
+md_estimate_size_before_relax (fragS *fragp, segT segment ATTRIBUTE_UNUSED)
+{
+ return nios2_relax_subtype_size (fragp->fr_subtype);
+}
+
+/* Implement md_relax_frag, returning the change in size of the frag. */
+long
+nios2_relax_frag (segT segment, fragS *fragp, long stretch)
+{
+ addressT target = fragp->fr_offset;
+ relax_substateT subtype = fragp->fr_subtype;
+ symbolS *symbolp = fragp->fr_symbol;
+
+ if (symbolp)
+ {
+ fragS *sym_frag = symbol_get_frag (symbolp);
+ offsetT offset;
+ int n;
+
+ target += S_GET_VALUE (symbolp);
+
+ /* See comments in write.c:relax_frag about handling of stretch. */
+ if (stretch != 0
+ && sym_frag->relax_marker != fragp->relax_marker)
+ {
+ if (stretch < 0 || sym_frag->region == fragp->region)
+ target += stretch;
+ else if (target < fragp->fr_address)
+ target = fragp->fr_next->fr_address + stretch;
+ }
+
+ /* We subtract 4 because all pc relative branches are
+ from the next instruction. */
+ offset = target - fragp->fr_address - fragp->fr_fix - 4;
+ if (offset >= -32768 && offset <= 32764)
+ /* Fits in PC-relative branch. */
+ n = 0;
+ else if (nios2_as_options.relax == relax_all)
+ /* Convert to jump. */
+ n = 1;
+ else if (nios2_as_options.relax == relax_section
+ && S_GET_SEGMENT (symbolp) == segment
+ && S_IS_DEFINED (symbolp))
+ /* Attempt a PC-relative relaxation on a branch to a defined
+ symbol in the same segment. */
+ {
+ /* The relaxation for conditional branches is offset by 4
+ bytes because we insert the inverted branch around the
+ sequence. */
+ if (IS_CBRANCH (subtype))
+ offset = offset - 4;
+ if (offset > 0)
+ n = offset / 32767 + 1;
+ else
+ n = offset / -32768 + 1;
+
+ /* Bail out immediately if relaxation has failed. If we try to
+ defer the diagnostic to md_convert_frag, some pathological test
+ cases (e.g. gcc/testsuite/gcc.c-torture/compile/20001226-1.c)
+ apparently never converge. By returning 0 here we could pretend
+ to the caller that nothing has changed, but that leaves things
+ in an inconsistent state when we get to md_convert_frag. */
+ if (n > RELAX_MAX_ADDI)
+ {
+ as_bad_where (fragp->fr_file, fragp->fr_line,
+ _("branch offset out of range\n"));
+ as_fatal (_("branch relaxation failed\n"));
+ }
+ }
+ else
+ /* We cannot handle this case, diagnose overflow later. */
+ return 0;
+
+ if (IS_CBRANCH (subtype))
+ fragp->fr_subtype = CBRANCH_SUBTYPE (n);
+ else
+ fragp->fr_subtype = UBRANCH_SUBTYPE (n);
+
+ return (nios2_relax_subtype_size (fragp->fr_subtype)
+ - nios2_relax_subtype_size (subtype));
+ }
+
+ /* If we got here, it's probably an error. */
+ return 0;
+}
+
+
+/* Complete fragp using the data from the relaxation pass. */
+void
+md_convert_frag (bfd *headers ATTRIBUTE_UNUSED, segT segment ATTRIBUTE_UNUSED,
+ fragS *fragp)
+{
+ char *buffer = fragp->fr_literal + fragp->fr_fix;
+ relax_substateT subtype = fragp->fr_subtype;
+ int n = SUBTYPE_ADDIS (subtype);
+ addressT target = fragp->fr_offset;
+ symbolS *symbolp = fragp->fr_symbol;
+ offsetT offset;
+ unsigned int addend_mask, addi_mask;
+ offsetT addend, remainder;
+ int i;
+
+ /* If we didn't or can't relax, this is a regular branch instruction.
+ We just need to generate the fixup for the symbol and offset. */
+ if (n == 0)
+ {
+ fix_new (fragp, fragp->fr_fix, 4, fragp->fr_symbol, fragp->fr_offset, 1,
+ BFD_RELOC_16_PCREL);
+ fragp->fr_fix += 4;
+ return;
+ }
+
+ /* Replace the cbranch at fr_fix with one that has the opposite condition
+ in order to jump around the block of instructions we'll be adding. */
+ if (IS_CBRANCH (subtype))
+ {
+ unsigned int br_opcode;
+ int nbytes;
+
+ /* Account for the nextpc and jmp in the pc-relative case, or the two
+ load instructions and jump in the absolute case. */
+ if (nios2_as_options.relax == relax_section)
+ nbytes = (n + 2) * 4;
+ else
+ nbytes = 12;
+
+ br_opcode = md_chars_to_number (buffer, 4);
+ switch (br_opcode & OP_MASK_OP)
+ {
+ case OP_MATCH_BEQ:
+ br_opcode = (br_opcode & ~OP_MASK_OP) | OP_MATCH_BNE;
+ break;
+ case OP_MATCH_BNE:
+ br_opcode = (br_opcode & ~OP_MASK_OP) | OP_MATCH_BEQ ;
+ break;
+ case OP_MATCH_BGE:
+ br_opcode = (br_opcode & ~OP_MASK_OP) | OP_MATCH_BLT ;
+ break;
+ case OP_MATCH_BGEU:
+ br_opcode = (br_opcode & ~OP_MASK_OP) | OP_MATCH_BLTU ;
+ break;
+ case OP_MATCH_BLT:
+ br_opcode = (br_opcode & ~OP_MASK_OP) | OP_MATCH_BGE ;
+ break;
+ case OP_MATCH_BLTU:
+ br_opcode = (br_opcode & ~OP_MASK_OP) | OP_MATCH_BGEU ;
+ break;
+ default:
+ as_bad_where (fragp->fr_file, fragp->fr_line,
+ _("expecting conditional branch for relaxation\n"));
+ abort ();
+ }
+
+ br_opcode = br_opcode | (nbytes << OP_SH_IMM16);
+ md_number_to_chars (buffer, br_opcode, 4);
+ fragp->fr_fix += 4;
+ buffer += 4;
+ }
+
+ /* Load at for the PC-relative case. */
+ if (nios2_as_options.relax == relax_section)
+ {
+ /* Insert the nextpc instruction. */
+ md_number_to_chars (buffer,
+ OP_MATCH_NEXTPC | (AT_REGNUM << OP_SH_RRD), 4);
+ fragp->fr_fix += 4;
+ buffer += 4;
+
+ /* We need to know whether the offset is positive or negative. */
+ target += S_GET_VALUE (symbolp);
+ offset = target - fragp->fr_address - fragp->fr_fix;
+ if (offset > 0)
+ addend = 32767;
+ else
+ addend = -32768;
+ addend_mask = (((unsigned int)addend) & 0xffff) << OP_SH_IMM16;
+
+ /* Insert n-1 addi instructions. */
+ addi_mask = (OP_MATCH_ADDI
+ | (AT_REGNUM << OP_SH_IRD)
+ | (AT_REGNUM << OP_SH_IRS));
+ for (i = 0; i < n - 1; i ++)
+ {
+ md_number_to_chars (buffer, addi_mask | addend_mask, 4);
+ fragp->fr_fix += 4;
+ buffer += 4;
+ }
+
+ /* Insert the last addi instruction to hold the remainder. */
+ remainder = offset - addend * (n - 1);
+ gas_assert (remainder >= -32768 && remainder <= 32767);
+ addend_mask = (((unsigned int)remainder) & 0xffff) << OP_SH_IMM16;
+ md_number_to_chars (buffer, addi_mask | addend_mask, 4);
+ fragp->fr_fix += 4;
+ buffer += 4;
+ }
+
+ /* Load at for the absolute case. */
+ else
+ {
+ md_number_to_chars (buffer, OP_MATCH_ORHI | 0x00400000, 4);
+ fix_new (fragp, fragp->fr_fix, 4, fragp->fr_symbol, fragp->fr_offset,
+ 0, BFD_RELOC_NIOS2_HI16);
+ fragp->fr_fix += 4;
+ buffer += 4;
+ md_number_to_chars (buffer, OP_MATCH_ORI | 0x08400000, 4);
+ fix_new (fragp, fragp->fr_fix, 4, fragp->fr_symbol, fragp->fr_offset,
+ 0, BFD_RELOC_NIOS2_LO16);
+ fragp->fr_fix += 4;
+ buffer += 4;
+ }
+
+ /* Insert the jmp instruction. */
+ md_number_to_chars (buffer, OP_MATCH_JMP | (AT_REGNUM << OP_SH_RRS), 4);
+ fragp->fr_fix += 4;
+ buffer += 4;
+}
+
+
+/** Fixups and overflow checking. */
+
+/* Check a fixup for overflow. */
+static bfd_boolean
+nios2_check_overflow (valueT fixup, reloc_howto_type *howto)
+{
+ /* Apply the rightshift before checking for overflow. */
+ fixup = ((signed)fixup) >> howto->rightshift;
+
+ /* Check for overflow - return TRUE if overflow, FALSE if not. */
+ switch (howto->complain_on_overflow)
+ {
+ case complain_overflow_dont:
+ break;
+ case complain_overflow_bitfield:
+ if ((fixup >> howto->bitsize) != 0
+ && ((signed) fixup >> howto->bitsize) != -1)
+ return TRUE;
+ break;
+ case complain_overflow_signed:
+ if ((fixup & 0x80000000) > 0)
+ {
+ /* Check for negative overflow. */
+ if ((signed) fixup < ((signed) 0x80000000 >> howto->bitsize))
+ return TRUE;
+ }
+ else
+ {
+ /* Check for positive overflow. */
+ if (fixup >= ((unsigned) 1 << (howto->bitsize - 1)))
+ return TRUE;
+ }
+ break;
+ case complain_overflow_unsigned:
+ if ((fixup >> howto->bitsize) != 0)
+ return TRUE;
+ break;
+ default:
+ as_bad (_("error checking for overflow - broken assembler"));
+ break;
+ }
+ return FALSE;
+}
+
+/* Emit diagnostic for fixup overflow. */
+static void
+nios2_diagnose_overflow (valueT fixup, reloc_howto_type *howto,
+ fixS *fixP, valueT value)
+{
+ if (fixP->fx_r_type == BFD_RELOC_8
+ || fixP->fx_r_type == BFD_RELOC_16
+ || fixP->fx_r_type == BFD_RELOC_32)
+ /* These relocs are against data, not instructions. */
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("immediate value 0x%x truncated to 0x%x"),
+ (unsigned int) fixup,
+ (unsigned int) (~(~(valueT) 0 << howto->bitsize) & fixup));
+ else
+ {
+ /* What opcode is the instruction? This will determine
+ whether we check for overflow in immediate values
+ and what error message we get. */
+ const struct nios2_opcode *opcode;
+ enum overflow_type overflow_msg_type;
+ unsigned int range_min;
+ unsigned int range_max;
+ unsigned int address;
+ gas_assert (fixP->fx_size == 4);
+ opcode = nios2_find_opcode_hash (value);
+ gas_assert (opcode);
+ overflow_msg_type = opcode->overflow_msg;
+ switch (overflow_msg_type)
+ {
+ case call_target_overflow:
+ range_min
+ = ((fixP->fx_frag->fr_address + fixP->fx_where) & 0xf0000000);
+ range_max = range_min + 0x0fffffff;
+ address = fixup | range_min;
+
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("call target address 0x%08x out of range 0x%08x to 0x%08x"),
+ address, range_min, range_max);
+ break;
+ case branch_target_overflow:
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("branch offset %d out of range %d to %d"),
+ (int)fixup, -32768, 32767);
+ break;
+ case address_offset_overflow:
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("%s offset %d out of range %d to %d"),
+ opcode->name, (int)fixup, -32768, 32767);
+ break;
+ case signed_immed16_overflow:
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("immediate value %d out of range %d to %d"),
+ (int)fixup, -32768, 32767);
+ break;
+ case unsigned_immed16_overflow:
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("immediate value %u out of range %u to %u"),
+ (unsigned int)fixup, 0, 65535);
+ break;
+ case unsigned_immed5_overflow:
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("immediate value %u out of range %u to %u"),
+ (unsigned int)fixup, 0, 31);
+ break;
+ case custom_opcode_overflow:
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("custom instruction opcode %u out of range %u to %u"),
+ (unsigned int)fixup, 0, 255);
+ break;
+ default:
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("overflow in immediate argument"));
+ break;
+ }
+ }
+}
+
+/* Apply a fixup to the object file. */
+void
+md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
+{
+ /* Assert that the fixup is one we can handle. */
+ gas_assert (fixP != NULL && valP != NULL
+ && (fixP->fx_r_type == BFD_RELOC_8
+ || fixP->fx_r_type == BFD_RELOC_16
+ || fixP->fx_r_type == BFD_RELOC_32
+ || fixP->fx_r_type == BFD_RELOC_64
+ || fixP->fx_r_type == BFD_RELOC_NIOS2_S16
+ || fixP->fx_r_type == BFD_RELOC_NIOS2_U16
+ || fixP->fx_r_type == BFD_RELOC_16_PCREL
+ || fixP->fx_r_type == BFD_RELOC_NIOS2_CALL26
+ || fixP->fx_r_type == BFD_RELOC_NIOS2_IMM5
+ || fixP->fx_r_type == BFD_RELOC_NIOS2_CACHE_OPX
+ || fixP->fx_r_type == BFD_RELOC_NIOS2_IMM6
+ || fixP->fx_r_type == BFD_RELOC_NIOS2_IMM8
+ || fixP->fx_r_type == BFD_RELOC_NIOS2_HI16
+ || fixP->fx_r_type == BFD_RELOC_NIOS2_LO16
+ || fixP->fx_r_type == BFD_RELOC_NIOS2_HIADJ16
+ || fixP->fx_r_type == BFD_RELOC_NIOS2_GPREL
+ || fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+ || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY
+ || fixP->fx_r_type == BFD_RELOC_NIOS2_UJMP
+ || fixP->fx_r_type == BFD_RELOC_NIOS2_CJMP
+ || fixP->fx_r_type == BFD_RELOC_NIOS2_CALLR
+ || fixP->fx_r_type == BFD_RELOC_NIOS2_ALIGN
+ || fixP->fx_r_type == BFD_RELOC_NIOS2_GOT16
+ || fixP->fx_r_type == BFD_RELOC_NIOS2_CALL16
+ || fixP->fx_r_type == BFD_RELOC_NIOS2_GOTOFF_LO
+ || fixP->fx_r_type == BFD_RELOC_NIOS2_GOTOFF_HA
+ || fixP->fx_r_type == BFD_RELOC_NIOS2_TLS_GD16
+ || fixP->fx_r_type == BFD_RELOC_NIOS2_TLS_LDM16
+ || fixP->fx_r_type == BFD_RELOC_NIOS2_TLS_LDO16
+ || fixP->fx_r_type == BFD_RELOC_NIOS2_TLS_IE16
+ || fixP->fx_r_type == BFD_RELOC_NIOS2_TLS_LE16
+ || fixP->fx_r_type == BFD_RELOC_NIOS2_GOTOFF
+ || fixP->fx_r_type == BFD_RELOC_NIOS2_TLS_DTPREL
+ /* Add other relocs here as we generate them. */
+ ));
+
+ if (fixP->fx_r_type == BFD_RELOC_64)
+ {
+ /* We may reach here due to .8byte directives, but we never output
+ BFD_RELOC_64; it must be resolved. */
+ if (fixP->fx_addsy != NULL)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("cannot create 64-bit relocation"));
+ else
+ {
+ md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
+ *valP, 8);
+ fixP->fx_done = 1;
+ }
+ return;
+ }
+
+ /* The value passed in valP can be the value of a fully
+ resolved expression, or it can be the value of a partially
+ resolved expression. In the former case, both fixP->fx_addsy
+ and fixP->fx_subsy are NULL, and fixP->fx_offset == *valP, and
+ we can fix up the instruction that fixP relates to.
+ In the latter case, one or both of fixP->fx_addsy and
+ fixP->fx_subsy are not NULL, and fixP->fx_offset may or may not
+ equal *valP. We don't need to check for fixP->fx_subsy being null
+ because the generic part of the assembler generates an error if
+ it is not an absolute symbol. */
+ if (fixP->fx_addsy != NULL)
+ /* Partially resolved expression. */
+ {
+ fixP->fx_addnumber = fixP->fx_offset;
+ fixP->fx_done = 0;
+
+ switch (fixP->fx_r_type)
+ {
+ case BFD_RELOC_NIOS2_TLS_GD16:
+ case BFD_RELOC_NIOS2_TLS_LDM16:
+ case BFD_RELOC_NIOS2_TLS_LDO16:
+ case BFD_RELOC_NIOS2_TLS_IE16:
+ case BFD_RELOC_NIOS2_TLS_LE16:
+ case BFD_RELOC_NIOS2_TLS_DTPMOD:
+ case BFD_RELOC_NIOS2_TLS_DTPREL:
+ case BFD_RELOC_NIOS2_TLS_TPREL:
+ S_SET_THREAD_LOCAL (fixP->fx_addsy);
+ break;
+ default:
+ break;
+ }
+ }
+ else
+ /* Fully resolved fixup. */
+ {
+ reloc_howto_type *howto
+ = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
+
+ if (howto == NULL)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("relocation is not supported"));
+ else
+ {
+ valueT fixup = *valP;
+ valueT value;
+ char *buf;
+
+ /* If this is a pc-relative relocation, we need to
+ subtract the current offset within the object file
+ FIXME : for some reason fixP->fx_pcrel isn't 1 when it should be
+ so I'm using the howto structure instead to determine this. */
+ if (howto->pc_relative == 1)
+ fixup = fixup - (fixP->fx_frag->fr_address + fixP->fx_where + 4);
+
+ /* Get the instruction or data to be fixed up. */
+ buf = fixP->fx_frag->fr_literal + fixP->fx_where;
+ value = md_chars_to_number (buf, fixP->fx_size);
+
+ /* Check for overflow, emitting a diagnostic if necessary. */
+ if (nios2_check_overflow (fixup, howto))
+ nios2_diagnose_overflow (fixup, howto, fixP, value);
+
+ /* Apply the right shift. */
+ fixup = ((signed)fixup) >> howto->rightshift;
+
+ /* Truncate the fixup to right size. */
+ switch (fixP->fx_r_type)
+ {
+ case BFD_RELOC_NIOS2_HI16:
+ fixup = (fixup >> 16) & 0xFFFF;
+ break;
+ case BFD_RELOC_NIOS2_LO16:
+ fixup = fixup & 0xFFFF;
+ break;
+ case BFD_RELOC_NIOS2_HIADJ16:
+ fixup = ((fixup >> 16) & 0xFFFF) + ((fixup >> 15) & 0x01);
+ break;
+ default:
+ {
+ int n = sizeof (fixup) * 8 - howto->bitsize;
+ fixup = (fixup << n) >> n;
+ break;
+ }
+ }
+
+ /* Fix up the instruction. */
+ value = (value & ~howto->dst_mask) | (fixup << howto->bitpos);
+ md_number_to_chars (buf, value, fixP->fx_size);
+ }
+
+ fixP->fx_done = 1;
+ }
+
+ if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT)
+ {
+ fixP->fx_done = 0;
+ if (fixP->fx_addsy
+ && !S_IS_DEFINED (fixP->fx_addsy) && !S_IS_WEAK (fixP->fx_addsy))
+ S_SET_WEAK (fixP->fx_addsy);
+ }
+ else if (fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+ fixP->fx_done = 0;
+}
+
+
+
+/** Instruction parsing support. */
+
+/* Special relocation directive strings. */
+
+struct nios2_special_relocS
+{
+ const char *string;
+ bfd_reloc_code_real_type reloc_type;
+};
+
+struct nios2_special_relocS nios2_special_reloc[] = {
+ {"%hiadj", BFD_RELOC_NIOS2_HIADJ16},
+ {"%hi", BFD_RELOC_NIOS2_HI16},
+ {"%lo", BFD_RELOC_NIOS2_LO16},
+ {"%gprel", BFD_RELOC_NIOS2_GPREL},
+ {"%call", BFD_RELOC_NIOS2_CALL16},
+ {"%gotoff_lo", BFD_RELOC_NIOS2_GOTOFF_LO},
+ {"%gotoff_hiadj", BFD_RELOC_NIOS2_GOTOFF_HA},
+ {"%tls_gd", BFD_RELOC_NIOS2_TLS_GD16},
+ {"%tls_ldm", BFD_RELOC_NIOS2_TLS_LDM16},
+ {"%tls_ldo", BFD_RELOC_NIOS2_TLS_LDO16},
+ {"%tls_ie", BFD_RELOC_NIOS2_TLS_IE16},
+ {"%tls_le", BFD_RELOC_NIOS2_TLS_LE16},
+ {"%gotoff", BFD_RELOC_NIOS2_GOTOFF},
+ {"%got", BFD_RELOC_NIOS2_GOT16}
+};
+
+#define NIOS2_NUM_SPECIAL_RELOCS \
+ (sizeof(nios2_special_reloc)/sizeof(nios2_special_reloc[0]))
+const int nios2_num_special_relocs = NIOS2_NUM_SPECIAL_RELOCS;
+
+/* Creates a new nios2_insn_relocS and returns a pointer to it. */
+static nios2_insn_relocS *
+nios2_insn_reloc_new (bfd_reloc_code_real_type reloc_type, unsigned int pcrel)
+{
+ nios2_insn_relocS *retval;
+ retval = (nios2_insn_relocS *) malloc (sizeof (nios2_insn_relocS));
+ if (retval == NULL)
+ {
+ as_bad (_("can't create relocation"));
+ abort ();
+ }
+
+ /* Fill out the fields with default values. */
+ retval->reloc_next = NULL;
+ retval->reloc_type = reloc_type;
+ retval->reloc_pcrel = pcrel;
+ return retval;
+}
+
+/* Frees up memory previously allocated by nios2_insn_reloc_new(). */
+/* FIXME: this is never called; memory leak? */
+#if 0
+static void
+nios2_insn_reloc_destroy (nios2_insn_relocS *reloc)
+{
+ gas_assert (reloc != NULL);
+ free (reloc);
+}
+#endif
+
+/* The various nios2_assemble_* functions call this
+ function to generate an expression from a string representing an expression.
+ It then tries to evaluate the expression, and if it can, returns its value.
+ If not, it creates a new nios2_insn_relocS and stores the expression and
+ reloc_type for future use. */
+static unsigned long
+nios2_assemble_expression (const char *exprstr,
+ nios2_insn_infoS *insn,
+ nios2_insn_relocS *prev_reloc,
+ bfd_reloc_code_real_type reloc_type,
+ unsigned int pcrel)
+{
+ nios2_insn_relocS *reloc;
+ char *saved_line_ptr;
+ unsigned short value;
+ int i;
+
+ gas_assert (exprstr != NULL);
+ gas_assert (insn != NULL);
+
+ /* Check for relocation operators.
+ Change the relocation type and advance the ptr to the start of
+ the expression proper. */
+ for (i = 0; i < nios2_num_special_relocs; i++)
+ if (strstr (exprstr, nios2_special_reloc[i].string) != NULL)
+ {
+ reloc_type = nios2_special_reloc[i].reloc_type;
+ exprstr += strlen (nios2_special_reloc[i].string) + 1;
+
+ /* %lo and %hiadj have different meanings for PC-relative
+ expressions. */
+ if (pcrel)
+ {
+ if (reloc_type == BFD_RELOC_NIOS2_LO16)
+ reloc_type = BFD_RELOC_NIOS2_PCREL_LO;
+ if (reloc_type == BFD_RELOC_NIOS2_HIADJ16)
+ reloc_type = BFD_RELOC_NIOS2_PCREL_HA;
+ }
+
+ break;
+ }
+
+ /* We potentially have a relocation. */
+ reloc = nios2_insn_reloc_new (reloc_type, pcrel);
+ if (prev_reloc != NULL)
+ prev_reloc->reloc_next = reloc;
+ else
+ insn->insn_reloc = reloc;
+
+ /* Parse the expression string. */
+ saved_line_ptr = input_line_pointer;
+ input_line_pointer = (char *) exprstr;
+ expression (&reloc->reloc_expression);
+ input_line_pointer = saved_line_ptr;
+
+ /* This is redundant as the fixup will put this into
+ the instruction, but it is included here so that
+ self-test mode (-r) works. */
+ value = 0;
+ if (nios2_mode == NIOS2_MODE_TEST
+ && reloc->reloc_expression.X_op == O_constant)
+ value = reloc->reloc_expression.X_add_number;
+
+ return (unsigned long) value;
+}
+
+/* Argument assemble functions.
+ All take an instruction argument string, and a pointer
+ to an instruction opcode. Upon return the insn_opcode
+ has the relevant fields filled in to represent the arg
+ string. The return value is NULL if successful, or
+ an error message if an error was detected.
+
+ The naming conventions for these functions match the args template
+ in the nios2_opcode structure, as documented in include/opcode/nios2.h.
+ For example, nios2_assemble_args_dst is used for instructions with
+ "d,s,t" args.
+ See nios2_arg_info_structs below for the exact correspondence. */
+
+static void
+nios2_assemble_args_dst (nios2_insn_infoS *insn_info)
+{
+ if (insn_info->insn_tokens[1] != NULL
+ && insn_info->insn_tokens[2] != NULL
+ && insn_info->insn_tokens[3] != NULL)
+ {
+ struct nios2_reg *dst = nios2_reg_lookup (insn_info->insn_tokens[1]);
+ struct nios2_reg *src1 = nios2_reg_lookup (insn_info->insn_tokens[2]);
+ struct nios2_reg *src2 = nios2_reg_lookup (insn_info->insn_tokens[3]);
+
+ if (dst == NULL)
+ as_bad (_("unknown register %s"), insn_info->insn_tokens[1]);
+ else
+ SET_INSN_FIELD (RRD, insn_info->insn_code, dst->index);
+
+ if (src1 == NULL)
+ as_bad (_("unknown register %s"), insn_info->insn_tokens[2]);
+ else
+ SET_INSN_FIELD (RRS, insn_info->insn_code, src1->index);
+
+ if (src2 == NULL)
+ as_bad (_("unknown register %s"), insn_info->insn_tokens[3]);
+ else
+ SET_INSN_FIELD (RRT, insn_info->insn_code, src2->index);
+
+ nios2_check_assembly (insn_info->insn_code, insn_info->insn_tokens[4]);
+ }
+}
+
+static void
+nios2_assemble_args_tsi (nios2_insn_infoS *insn_info)
+{
+ if (insn_info->insn_tokens[1] != NULL &&
+ insn_info->insn_tokens[2] != NULL && insn_info->insn_tokens[3] != NULL)
+ {
+ struct nios2_reg *dst = nios2_reg_lookup (insn_info->insn_tokens[1]);
+ struct nios2_reg *src1 = nios2_reg_lookup (insn_info->insn_tokens[2]);
+ unsigned int src2
+ = nios2_assemble_expression (insn_info->insn_tokens[3], insn_info,
+ insn_info->insn_reloc, BFD_RELOC_NIOS2_S16,
+ 0);
+
+ if (dst == NULL)
+ as_bad (_("unknown register %s"), insn_info->insn_tokens[1]);
+ else
+ SET_INSN_FIELD (IRT, insn_info->insn_code, dst->index);
+
+ if (src1 == NULL)
+ as_bad (_("unknown register %s"), insn_info->insn_tokens[2]);
+ else
+ SET_INSN_FIELD (IRS, insn_info->insn_code, src1->index);
+
+ SET_INSN_FIELD (IMM16, insn_info->insn_code, src2);
+ nios2_check_assembly (insn_info->insn_code, insn_info->insn_tokens[4]);
+ SET_INSN_FIELD (IMM16, insn_info->insn_code, 0);
+ }
+}
+
+static void
+nios2_assemble_args_tsu (nios2_insn_infoS *insn_info)
+{
+ if (insn_info->insn_tokens[1] != NULL
+ && insn_info->insn_tokens[2] != NULL
+ && insn_info->insn_tokens[3] != NULL)
+ {
+ struct nios2_reg *dst = nios2_reg_lookup (insn_info->insn_tokens[1]);
+ struct nios2_reg *src1 = nios2_reg_lookup (insn_info->insn_tokens[2]);
+ unsigned int src2
+ = nios2_assemble_expression (insn_info->insn_tokens[3], insn_info,
+ insn_info->insn_reloc, BFD_RELOC_NIOS2_U16,
+ 0);
+
+ if (dst == NULL)
+ as_bad (_("unknown register %s"), insn_info->insn_tokens[1]);
+ else
+ SET_INSN_FIELD (IRT, insn_info->insn_code, dst->index);
+
+ if (src1 == NULL)
+ as_bad (_("unknown register %s"), insn_info->insn_tokens[2]);
+ else
+ SET_INSN_FIELD (IRS, insn_info->insn_code, src1->index);
+
+ SET_INSN_FIELD (IMM16, insn_info->insn_code, src2);
+ nios2_check_assembly (insn_info->insn_code, insn_info->insn_tokens[4]);
+ SET_INSN_FIELD (IMM16, insn_info->insn_code, 0);
+ }
+}
+
+static void
+nios2_assemble_args_sto (nios2_insn_infoS *insn_info)
+{
+ if (insn_info->insn_tokens[1] != NULL
+ && insn_info->insn_tokens[2] != NULL
+ && insn_info->insn_tokens[3] != NULL)
+ {
+ struct nios2_reg *dst = nios2_reg_lookup (insn_info->insn_tokens[1]);
+ struct nios2_reg *src1 = nios2_reg_lookup (insn_info->insn_tokens[2]);
+ unsigned int src2
+ = nios2_assemble_expression (insn_info->insn_tokens[3], insn_info,
+ insn_info->insn_reloc, BFD_RELOC_16_PCREL,
+ 1);
+
+ if (dst == NULL)
+ as_bad (_("unknown register %s"), insn_info->insn_tokens[1]);
+ else
+ SET_INSN_FIELD (IRS, insn_info->insn_code, dst->index);
+
+ if (src1 == NULL)
+ as_bad (_("unknown register %s"), insn_info->insn_tokens[2]);
+ else
+ SET_INSN_FIELD (IRT, insn_info->insn_code, src1->index);
+
+ SET_INSN_FIELD (IMM16, insn_info->insn_code, src2);
+ nios2_check_assembly (insn_info->insn_code, insn_info->insn_tokens[4]);
+ SET_INSN_FIELD (IMM16, insn_info->insn_code, 0);
+ }
+}
+
+static void
+nios2_assemble_args_o (nios2_insn_infoS *insn_info)
+{
+ if (insn_info->insn_tokens[1] != NULL)
+ {
+ unsigned long immed
+ = nios2_assemble_expression (insn_info->insn_tokens[1], insn_info,
+ insn_info->insn_reloc, BFD_RELOC_16_PCREL,
+ 1);
+ SET_INSN_FIELD (IMM16, insn_info->insn_code, immed);
+ nios2_check_assembly (insn_info->insn_code, insn_info->insn_tokens[2]);
+ SET_INSN_FIELD (IMM16, insn_info->insn_code, 0);
+ }
+}
+
+static void
+nios2_assemble_args_is (nios2_insn_infoS *insn_info)
+{
+ if (insn_info->insn_tokens[1] != NULL && insn_info->insn_tokens[2] != NULL)
+ {
+ struct nios2_reg *addr_src = nios2_reg_lookup (insn_info->insn_tokens[2]);
+ unsigned long immed
+ = nios2_assemble_expression (insn_info->insn_tokens[1], insn_info,
+ insn_info->insn_reloc, BFD_RELOC_NIOS2_S16,
+ 0);
+
+ SET_INSN_FIELD (IMM16, insn_info->insn_code, immed);
+
+ if (addr_src == NULL)
+ as_bad (_("unknown base register %s"), insn_info->insn_tokens[2]);
+ else
+ SET_INSN_FIELD (RRS, insn_info->insn_code, addr_src->index);
+
+ nios2_check_assembly (insn_info->insn_code, insn_info->insn_tokens[3]);
+ SET_INSN_FIELD (IMM16, insn_info->insn_code, 0);
+ }
+}
+
+static void
+nios2_assemble_args_m (nios2_insn_infoS *insn_info)
+{
+ if (insn_info->insn_tokens[1] != NULL)
+ {
+ unsigned long immed
+ = nios2_assemble_expression (insn_info->insn_tokens[1], insn_info,
+ insn_info->insn_reloc,
+ BFD_RELOC_NIOS2_CALL26, 0);
+
+ SET_INSN_FIELD (IMM26, insn_info->insn_code, immed);
+ nios2_check_assembly (insn_info->insn_code, insn_info->insn_tokens[2]);
+ SET_INSN_FIELD (IMM26, insn_info->insn_code, 0);
+ }
+}
+
+static void
+nios2_assemble_args_s (nios2_insn_infoS *insn_info)
+{
+ if (insn_info->insn_tokens[1] != NULL)
+ {
+ struct nios2_reg *src = nios2_reg_lookup (insn_info->insn_tokens[1]);
+ if (src == NULL)
+ as_bad (_("unknown register %s"), insn_info->insn_tokens[1]);
+ else
+ SET_INSN_FIELD (RRS, insn_info->insn_code, src->index);
+
+ nios2_check_assembly (insn_info->insn_code, insn_info->insn_tokens[2]);
+ }
+}
+
+static void
+nios2_assemble_args_tis (nios2_insn_infoS *insn_info)
+{
+ if (insn_info->insn_tokens[1] != NULL
+ && insn_info->insn_tokens[2] != NULL
+ && insn_info->insn_tokens[3] != NULL)
+ {
+ struct nios2_reg *dst = nios2_reg_lookup (insn_info->insn_tokens[1]);
+ struct nios2_reg *addr_src = nios2_reg_lookup (insn_info->insn_tokens[3]);
+ unsigned long immed
+ = nios2_assemble_expression (insn_info->insn_tokens[2], insn_info,
+ insn_info->insn_reloc, BFD_RELOC_NIOS2_S16,
+ 0);
+
+ if (addr_src == NULL)
+ as_bad (_("unknown register %s"), insn_info->insn_tokens[3]);
+ else
+ SET_INSN_FIELD (RRS, insn_info->insn_code, addr_src->index);
+
+ if (dst == NULL)
+ as_bad (_("unknown register %s"), insn_info->insn_tokens[1]);
+ else
+ SET_INSN_FIELD (RRT, insn_info->insn_code, dst->index);
+
+ SET_INSN_FIELD (IMM16, insn_info->insn_code, immed);
+ nios2_check_assembly (insn_info->insn_code, insn_info->insn_tokens[4]);
+ SET_INSN_FIELD (IMM16, insn_info->insn_code, 0);
+ }
+}
+
+static void
+nios2_assemble_args_dc (nios2_insn_infoS *insn_info)
+{
+ if (insn_info->insn_tokens[1] != NULL && insn_info->insn_tokens[2] != NULL)
+ {
+ struct nios2_reg *ctl = nios2_reg_lookup (insn_info->insn_tokens[2]);
+ struct nios2_reg *dst = nios2_reg_lookup (insn_info->insn_tokens[1]);
+
+ if (ctl == NULL)
+ as_bad (_("unknown register %s"), insn_info->insn_tokens[1]);
+ else
+ SET_INSN_FIELD (RCTL, insn_info->insn_code, ctl->index);
+
+ if (dst == NULL)
+ as_bad (_("unknown register %s"), insn_info->insn_tokens[2]);
+ else
+ SET_INSN_FIELD (RRD, insn_info->insn_code, dst->index);
+
+ nios2_check_assembly (insn_info->insn_code, insn_info->insn_tokens[3]);
+ }
+}
+
+static void
+nios2_assemble_args_cs (nios2_insn_infoS *insn_info)
+{
+ if (insn_info->insn_tokens[1] != NULL && insn_info->insn_tokens[2] != NULL)
+ {
+ struct nios2_reg *ctl = nios2_reg_lookup (insn_info->insn_tokens[1]);
+ struct nios2_reg *src = nios2_reg_lookup (insn_info->insn_tokens[2]);
+
+ if (ctl == NULL)
+ as_bad (_("unknown register %s"), insn_info->insn_tokens[1]);
+ else if (ctl->index == 4)
+ as_bad (_("ipending control register (ctl4) is read-only\n"));
+ else
+ SET_INSN_FIELD (RCTL, insn_info->insn_code, ctl->index);
+
+ if (src == NULL)
+ as_bad (_("unknown register %s"), insn_info->insn_tokens[2]);
+ else
+ SET_INSN_FIELD (RRS, insn_info->insn_code, src->index);
+
+ nios2_check_assembly (insn_info->insn_code, insn_info->insn_tokens[3]);
+ }
+}
+
+static void
+nios2_assemble_args_ldst (nios2_insn_infoS *insn_info)
+{
+ if (insn_info->insn_tokens[1] != NULL
+ && insn_info->insn_tokens[2] != NULL
+ && insn_info->insn_tokens[3] != NULL
+ && insn_info->insn_tokens[4] != NULL)
+ {
+ unsigned long custom_n
+ = nios2_assemble_expression (insn_info->insn_tokens[1], insn_info,
+ insn_info->insn_reloc,
+ BFD_RELOC_NIOS2_IMM8, 0);
+
+ struct nios2_reg *dst = nios2_reg_lookup (insn_info->insn_tokens[2]);
+ struct nios2_reg *src1 = nios2_reg_lookup (insn_info->insn_tokens[3]);
+ struct nios2_reg *src2 = nios2_reg_lookup (insn_info->insn_tokens[4]);
+
+ SET_INSN_FIELD (CUSTOM_N, insn_info->insn_code, custom_n);
+
+ if (dst == NULL)
+ as_bad (_("unknown register %s"), insn_info->insn_tokens[2]);
+ else
+ SET_INSN_FIELD (RRD, insn_info->insn_code, dst->index);
+
+ if (src1 == NULL)
+ as_bad (_("unknown register %s"), insn_info->insn_tokens[3]);
+ else
+ SET_INSN_FIELD (RRS, insn_info->insn_code, src1->index);
+
+ if (src2 == NULL)
+ as_bad (_("unknown register %s"), insn_info->insn_tokens[4]);
+ else
+ SET_INSN_FIELD (RRT, insn_info->insn_code, src2->index);
+
+ /* Set or clear the bits to indicate whether coprocessor registers are
+ used. */
+ if (nios2_coproc_reg (insn_info->insn_tokens[2]))
+ SET_INSN_FIELD (CUSTOM_C, insn_info->insn_code, 0);
+ else
+ SET_INSN_FIELD (CUSTOM_C, insn_info->insn_code, 1);
+
+ if (nios2_coproc_reg (insn_info->insn_tokens[3]))
+ SET_INSN_FIELD (CUSTOM_A, insn_info->insn_code, 0);
+ else
+ SET_INSN_FIELD (CUSTOM_A, insn_info->insn_code, 1);
+
+ if (nios2_coproc_reg (insn_info->insn_tokens[4]))
+ SET_INSN_FIELD (CUSTOM_B, insn_info->insn_code, 0);
+ else
+ SET_INSN_FIELD (CUSTOM_B, insn_info->insn_code, 1);
+
+ nios2_check_assembly (insn_info->insn_code, insn_info->insn_tokens[5]);
+ }
+}
+
+static void
+nios2_assemble_args_none (nios2_insn_infoS *insn_info ATTRIBUTE_UNUSED)
+{
+ /* Nothing to do. */
+}
+
+static void
+nios2_assemble_args_dsj (nios2_insn_infoS *insn_info)
+{
+ if (insn_info->insn_tokens[1] != NULL
+ && insn_info->insn_tokens[2] != NULL
+ && insn_info->insn_tokens[3] != NULL)
+ {
+ struct nios2_reg *dst = nios2_reg_lookup (insn_info->insn_tokens[1]);
+ struct nios2_reg *src1 = nios2_reg_lookup (insn_info->insn_tokens[2]);
+
+ /* A 5-bit constant expression. */
+ unsigned int src2 =
+ nios2_assemble_expression (insn_info->insn_tokens[3], insn_info,
+ insn_info->insn_reloc,
+ BFD_RELOC_NIOS2_IMM5, 0);
+
+ if (dst == NULL)
+ as_bad (_("unknown register %s"), insn_info->insn_tokens[1]);
+ else
+ SET_INSN_FIELD (RRD, insn_info->insn_code, dst->index);
+
+ if (src1 == NULL)
+ as_bad (_("unknown register %s"), insn_info->insn_tokens[2]);
+ else
+ SET_INSN_FIELD (RRS, insn_info->insn_code, src1->index);
+
+ SET_INSN_FIELD (IMM5, insn_info->insn_code, src2);
+ nios2_check_assembly (insn_info->insn_code, insn_info->insn_tokens[4]);
+ SET_INSN_FIELD (IMM5, insn_info->insn_code, 0);
+ }
+}
+
+static void
+nios2_assemble_args_d (nios2_insn_infoS *insn_info)
+{
+ if (insn_info->insn_tokens[1] != NULL)
+ {
+ struct nios2_reg *dst = nios2_reg_lookup (insn_info->insn_tokens[1]);
+
+ if (dst == NULL)
+ as_bad (_("unknown register %s"), insn_info->insn_tokens[1]);
+ else
+ SET_INSN_FIELD (RRD, insn_info->insn_code, dst->index);
+
+ nios2_check_assembly (insn_info->insn_code, insn_info->insn_tokens[2]);
+ }
+}
+
+static void
+nios2_assemble_args_b (nios2_insn_infoS *insn_info)
+{
+ unsigned int imm5 = 0;
+
+ if (insn_info->insn_tokens[1] != NULL)
+ {
+ /* A 5-bit constant expression. */
+ imm5 = nios2_assemble_expression (insn_info->insn_tokens[1],
+ insn_info, insn_info->insn_reloc,
+ BFD_RELOC_NIOS2_IMM5, 0);
+ SET_INSN_FIELD (TRAP_IMM5, insn_info->insn_code, imm5);
+ nios2_check_assembly (insn_info->insn_code, insn_info->insn_tokens[2]);
+ }
+
+ SET_INSN_FIELD (TRAP_IMM5, insn_info->insn_code, imm5);
+
+ nios2_check_assembly (insn_info->insn_code, insn_info->insn_tokens[2]);
+}
+
+/* This table associates pointers to functions that parse the arguments to an
+ instruction and fill in the relevant fields of the instruction. */
+const nios2_arg_infoS nios2_arg_info_structs[] = {
+ /* args, assemble_args_func */
+ {"d,s,t", nios2_assemble_args_dst},
+ {"d,s,t,E", nios2_assemble_args_dst},
+ {"t,s,i", nios2_assemble_args_tsi},
+ {"t,s,i,E", nios2_assemble_args_tsi},
+ {"t,s,u", nios2_assemble_args_tsu},
+ {"t,s,u,E", nios2_assemble_args_tsu},
+ {"s,t,o", nios2_assemble_args_sto},
+ {"s,t,o,E", nios2_assemble_args_sto},
+ {"o", nios2_assemble_args_o},
+ {"o,E", nios2_assemble_args_o},
+ {"s", nios2_assemble_args_s},
+ {"s,E", nios2_assemble_args_s},
+ {"", nios2_assemble_args_none},
+ {"E", nios2_assemble_args_none},
+ {"i(s)", nios2_assemble_args_is},
+ {"i(s)E", nios2_assemble_args_is},
+ {"m", nios2_assemble_args_m},
+ {"m,E", nios2_assemble_args_m},
+ {"t,i(s)", nios2_assemble_args_tis},
+ {"t,i(s)E", nios2_assemble_args_tis},
+ {"d,c", nios2_assemble_args_dc},
+ {"d,c,E", nios2_assemble_args_dc},
+ {"c,s", nios2_assemble_args_cs},
+ {"c,s,E", nios2_assemble_args_cs},
+ {"l,d,s,t", nios2_assemble_args_ldst},
+ {"l,d,s,t,E", nios2_assemble_args_ldst},
+ {"d,s,j", nios2_assemble_args_dsj},
+ {"d,s,j,E", nios2_assemble_args_dsj},
+ {"d", nios2_assemble_args_d},
+ {"d,E", nios2_assemble_args_d},
+ {"b", nios2_assemble_args_b},
+ {"b,E", nios2_assemble_args_b}
+};
+
+#define NIOS2_NUM_ARGS \
+ ((sizeof(nios2_arg_info_structs)/sizeof(nios2_arg_info_structs[0])))
+const int nios2_num_arg_info_structs = NIOS2_NUM_ARGS;
+
+/* The function consume_arg takes a pointer into a string
+ of instruction tokens (args) and a pointer into a string
+ representing the expected sequence of tokens and separators.
+ It checks whether the first argument in argstr is of the
+ expected type, throwing an error if it is not, and returns
+ the pointer argstr. */
+static char *
+nios2_consume_arg (nios2_insn_infoS *insn, char *argstr, const char *parsestr)
+{
+ char *temp;
+ int regno = -1;
+
+ switch (*parsestr)
+ {
+ case 'c':
+ if (!nios2_control_register_arg_p (argstr))
+ as_bad (_("expecting control register"));
+ break;
+ case 'd':
+ case 's':
+ case 't':
+
+ /* We check to make sure we don't have a control register. */
+ if (nios2_control_register_arg_p (argstr))
+ as_bad (_("illegal use of control register"));
+
+ /* And whether coprocessor registers are valid here. */
+ if (nios2_coproc_reg (argstr)
+ && insn->insn_nios2_opcode->match != OP_MATCH_CUSTOM)
+ as_bad (_("illegal use of coprocessor register\n"));
+
+ /* Extract a register number if the register is of the
+ form r[0-9]+, if it is a normal register, set
+ regno to its number (0-31), else set regno to -1. */
+ if (argstr[0] == 'r' && ISDIGIT (argstr[1]))
+ {
+ char *p = argstr;
+
+ ++p;
+ regno = 0;
+ do
+ {
+ regno *= 10;
+ regno += *p - '0';
+ ++p;
+ }
+ while (ISDIGIT (*p));
+ }
+ else
+ regno = -1;
+
+ /* And whether we are using at. */
+ if (!nios2_as_options.noat
+ && (regno == 1 || strprefix (argstr, "at")))
+ as_warn (_("Register at (r1) can sometimes be corrupted by assembler "
+ "optimizations.\n"
+ "Use .set noat to turn off those optimizations (and this "
+ "warning)."));
+
+ /* And whether we are using oci registers. */
+ if (!nios2_as_options.nobreak
+ && (regno == 25 || strprefix (argstr, "bt")))
+ as_warn (_("The debugger will corrupt bt (r25). If you don't need to "
+ "debug this\n"
+ "code then use .set nobreak to turn off this warning."));
+
+ if (!nios2_as_options.nobreak
+ && (regno == 30 || strprefix (argstr, "ba")))
+ as_warn (_("The debugger will corrupt ba (r30). If you don't need to "
+ "debug this\n"
+ "code then use .set nobreak to turn off this warning."));
+ break;
+ case 'i':
+ case 'u':
+ if (*argstr == '%')
+ {
+ if (nios2_special_relocation_p (argstr))
+ {
+ /* We zap the parentheses because we don't want them confused
+ with separators. */
+ temp = strchr (argstr, '(');
+ if (temp != NULL)
+ *temp = ' ';
+ temp = strchr (argstr, ')');
+ if (temp != NULL)
+ *temp = ' ';
+ }
+ else
+ as_bad (_("badly formed expression near %s"), argstr);
+ }
+ break;
+ case 'm':
+ case 'j':
+ case 'k':
+ case 'l':
+ case 'b':
+ /* We can't have %hi, %lo or %hiadj here. */
+ if (*argstr == '%')
+ as_bad (_("badly formed expression near %s"), argstr);
+ break;
+ default:
+ break;
+ }
+
+ return argstr;
+}
+
+/* The function consume_separator takes a pointer into a string
+ of instruction tokens (args) and a pointer into a string representing
+ the expected sequence of tokens and separators. It finds the first
+ instance of the character pointed to by separator in argstr, and
+ returns a pointer to the next element of argstr, which is the
+ following token in the sequence. */
+static char *
+nios2_consume_separator (char *argstr, const char *separator)
+{
+ char *p;
+
+ /* If we have a opcode reg, expr(reg) type instruction, and
+ * we are separating the expr from the (reg), we find the last
+ * (, just in case the expression has parentheses. */
+
+ if (*separator == '(')
+ p = strrchr (argstr, *separator);
+ else
+ p = strchr (argstr, *separator);
+
+ if (p != NULL)
+ *p++ = 0;
+ else
+ as_bad (_("expecting %c near %s"), *separator, argstr);
+ return p;
+}
+
+
+/* The principal argument parsing function which takes a string argstr
+ representing the instruction arguments for insn, and extracts the argument
+ tokens matching parsestr into parsed_args. */
+static void
+nios2_parse_args (nios2_insn_infoS *insn, char *argstr,
+ const char *parsestr, char **parsed_args)
+{
+ char *p;
+ char *end = NULL;
+ int i;
+ p = argstr;
+ i = 0;
+ bfd_boolean terminate = FALSE;
+
+ /* This rest of this function is it too fragile and it mostly works,
+ therefore special case this one. */
+ if (*parsestr == 0 && argstr != 0)
+ {
+ as_bad (_("too many arguments"));
+ parsed_args[0] = NULL;
+ return;
+ }
+
+ while (p != NULL && !terminate && i < NIOS2_MAX_INSN_TOKENS)
+ {
+ parsed_args[i] = nios2_consume_arg (insn, p, parsestr);
+ ++parsestr;
+ if (*parsestr != '\0')
+ {
+ p = nios2_consume_separator (p, parsestr);
+ ++parsestr;
+ }
+ else
+ {
+ /* Check that the argument string has no trailing arguments. */
+ /* If we've got a %lo etc relocation, we've zapped the parens with
+ spaces. */
+ if (nios2_special_relocation_p (p))
+ end = strpbrk (p, ",");
+ else
+ end = strpbrk (p, " ,");
+
+ if (end != NULL)
+ as_bad (_("too many arguments"));
+ }
+
+ if (*parsestr == '\0' || (p != NULL && *p == '\0'))
+ terminate = TRUE;
+ ++i;
+ }
+
+ parsed_args[i] = NULL;
+
+ if (*parsestr != '\0' && insn->insn_nios2_opcode->match != OP_MATCH_BREAK)
+ as_bad (_("missing argument"));
+}
+
+
+
+/** Support for pseudo-op parsing. These are macro-like opcodes that
+ expand into real insns by suitable fiddling with the operands. */
+
+/* Append the string modifier to the string contained in the argument at
+ parsed_args[ndx]. */
+static void
+nios2_modify_arg (char **parsed_args, const char *modifier,
+ int unused ATTRIBUTE_UNUSED, int ndx)
+{
+ char *tmp = parsed_args[ndx];
+
+ parsed_args[ndx]
+ = (char *) malloc (strlen (parsed_args[ndx]) + strlen (modifier) + 1);
+ strcpy (parsed_args[ndx], tmp);
+ strcat (parsed_args[ndx], modifier);
+}
+
+/* Modify parsed_args[ndx] by negating that argument. */
+static void
+nios2_negate_arg (char **parsed_args, const char *modifier ATTRIBUTE_UNUSED,
+ int unused ATTRIBUTE_UNUSED, int ndx)
+{
+ char *tmp = parsed_args[ndx];
+
+ parsed_args[ndx]
+ = (char *) malloc (strlen ("~(") + strlen (parsed_args[ndx]) +
+ strlen (")+1") + 1);
+
+ strcpy (parsed_args[ndx], "~(");
+ strcat (parsed_args[ndx], tmp);
+ strcat (parsed_args[ndx], ")+1");
+}
+
+/* The function nios2_swap_args swaps the pointers at indices index_1 and
+ index_2 in the array parsed_args[] - this is used for operand swapping
+ for comparison operations. */
+static void
+nios2_swap_args (char **parsed_args, const char *unused ATTRIBUTE_UNUSED,
+ int index_1, int index_2)
+{
+ char *tmp;
+ gas_assert (index_1 < NIOS2_MAX_INSN_TOKENS
+ && index_2 < NIOS2_MAX_INSN_TOKENS);
+ tmp = parsed_args[index_1];
+ parsed_args[index_1] = parsed_args[index_2];
+ parsed_args[index_2] = tmp;
+}
+
+/* This function appends the string appnd to the array of strings in
+ parsed_args num times starting at index start in the array. */
+static void
+nios2_append_arg (char **parsed_args, const char *appnd, int num,
+ int start)
+{
+ int i, count;
+ char *tmp;
+
+ gas_assert ((start + num) < NIOS2_MAX_INSN_TOKENS);
+
+ if (nios2_mode == NIOS2_MODE_TEST)
+ tmp = parsed_args[start];
+ else
+ tmp = NULL;
+
+ for (i = start, count = num; count > 0; ++i, --count)
+ parsed_args[i] = (char *) appnd;
+
+ gas_assert (i == (start + num));
+ parsed_args[i] = tmp;
+ parsed_args[i + 1] = NULL;
+}
+
+/* This function inserts the string insert num times in the array
+ parsed_args, starting at the index start. */
+static void
+nios2_insert_arg (char **parsed_args, const char *insert, int num,
+ int start)
+{
+ int i, count;
+
+ gas_assert ((start + num) < NIOS2_MAX_INSN_TOKENS);
+
+ /* Move the existing arguments up to create space. */
+ for (i = NIOS2_MAX_INSN_TOKENS; i - num >= start; --i)
+ parsed_args[i] = parsed_args[i - num];
+
+ for (i = start, count = num; count > 0; ++i, --count)
+ parsed_args[i] = (char *) insert;
+}
+
+/* Cleanup function to free malloc'ed arg strings. */
+static void
+nios2_free_arg (char **parsed_args, int num ATTRIBUTE_UNUSED, int start)
+{
+ if (parsed_args[start])
+ {
+ free (parsed_args[start]);
+ parsed_args[start] = NULL;
+ }
+}
+
+/* This function swaps the pseudo-op for a real op. */
+static nios2_ps_insn_infoS*
+nios2_translate_pseudo_insn (nios2_insn_infoS *insn)
+{
+
+ nios2_ps_insn_infoS *ps_insn;
+
+ /* Find which real insn the pseudo-op transates to and
+ switch the insn_info ptr to point to it. */
+ ps_insn = nios2_ps_lookup (insn->insn_nios2_opcode->name);
+
+ if (ps_insn != NULL)
+ {
+ insn->insn_nios2_opcode = nios2_opcode_lookup (ps_insn->insn);
+ insn->insn_tokens[0] = insn->insn_nios2_opcode->name;
+ /* Modify the args so they work with the real insn. */
+ ps_insn->arg_modifer_func ((char **) insn->insn_tokens,
+ ps_insn->arg_modifier, ps_insn->num,
+ ps_insn->index);
+ }
+ else
+ /* we cannot recover from this. */
+ as_fatal (_("unrecognized pseudo-instruction %s"),
+ ps_insn->pseudo_insn);
+ return ps_insn;
+}
+
+/* Invoke the cleanup handler for pseudo-insn ps_insn on insn. */
+static void
+nios2_cleanup_pseudo_insn (nios2_insn_infoS *insn,
+ nios2_ps_insn_infoS *ps_insn)
+{
+ if (ps_insn->arg_cleanup_func)
+ (ps_insn->arg_cleanup_func) ((char **) insn->insn_tokens,
+ ps_insn->num, ps_insn->index);
+}
+
+const nios2_ps_insn_infoS nios2_ps_insn_info_structs[] = {
+ /* pseudo-op, real-op, arg, arg_modifier_func, num, index, arg_cleanup_func */
+ {"mov", "add", nios2_append_arg, "zero", 1, 3, NULL},
+ {"movi", "addi", nios2_insert_arg, "zero", 1, 2, NULL},
+ {"movhi", "orhi", nios2_insert_arg, "zero", 1, 2, NULL},
+ {"movui", "ori", nios2_insert_arg, "zero", 1, 2, NULL},
+ {"movia", "orhi", nios2_insert_arg, "zero", 1, 2, NULL},
+ {"nop", "add", nios2_append_arg, "zero", 3, 1, NULL},
+ {"bgt", "blt", nios2_swap_args, "", 1, 2, NULL},
+ {"bgtu", "bltu", nios2_swap_args, "", 1, 2, NULL},
+ {"ble", "bge", nios2_swap_args, "", 1, 2, NULL},
+ {"bleu", "bgeu", nios2_swap_args, "", 1, 2, NULL},
+ {"cmpgt", "cmplt", nios2_swap_args, "", 2, 3, NULL},
+ {"cmpgtu", "cmpltu", nios2_swap_args, "", 2, 3, NULL},
+ {"cmple", "cmpge", nios2_swap_args, "", 2, 3, NULL},
+ {"cmpleu", "cmpgeu", nios2_swap_args, "", 2, 3, NULL},
+ {"cmpgti", "cmpgei", nios2_modify_arg, "+1", 0, 3, nios2_free_arg},
+ {"cmpgtui", "cmpgeui", nios2_modify_arg, "+1", 0, 3, nios2_free_arg},
+ {"cmplei", "cmplti", nios2_modify_arg, "+1", 0, 3, nios2_free_arg},
+ {"cmpleui", "cmpltui", nios2_modify_arg, "+1", 0, 3, nios2_free_arg},
+ {"subi", "addi", nios2_negate_arg, "", 0, 3, nios2_free_arg}
+ /* Add further pseudo-ops here. */
+};
+
+#define NIOS2_NUM_PSEUDO_INSNS \
+ ((sizeof(nios2_ps_insn_info_structs)/ \
+ sizeof(nios2_ps_insn_info_structs[0])))
+const int nios2_num_ps_insn_info_structs = NIOS2_NUM_PSEUDO_INSNS;
+
+
+/** Assembler output support. */
+
+static int
+can_evaluate_expr (nios2_insn_infoS *insn)
+{
+ /* Remove this check for null and the invalid insn "ori r9, 1234" seg faults. */
+ if (!insn->insn_reloc)
+ /* ??? Ideally we should do something other than as_fatal here as we can
+ continue to assemble.
+ However this function (actually the output_* functions) should not
+ have been called in the first place once an illegal instruction had
+ been encountered. */
+ as_fatal (_("Invalid instruction encountered, cannot recover. No assembly attempted."));
+
+ if (insn->insn_reloc->reloc_expression.X_op == O_constant)
+ return 1;
+
+ return 0;
+}
+
+static int
+get_expr_value (nios2_insn_infoS *insn)
+{
+ int value = 0;
+
+ if (insn->insn_reloc->reloc_expression.X_op == O_constant)
+ value = insn->insn_reloc->reloc_expression.X_add_number;
+ return value;
+}
+
+/* Output a normal instruction. */
+static void
+output_insn (nios2_insn_infoS *insn)
+{
+ char *f;
+ nios2_insn_relocS *reloc;
+
+ f = frag_more (4);
+ /* This allocates enough space for the instruction
+ and puts it in the current frag. */
+ md_number_to_chars (f, insn->insn_code, 4);
+ /* Emit debug info. */
+ dwarf2_emit_insn (4);
+ /* Create any fixups to be acted on later. */
+ for (reloc = insn->insn_reloc; reloc != NULL; reloc = reloc->reloc_next)
+ fix_new_exp (frag_now, f - frag_now->fr_literal, 4,
+ &reloc->reloc_expression, reloc->reloc_pcrel,
+ reloc->reloc_type);
+}
+
+/* Output an unconditional branch. */
+static void
+output_ubranch (nios2_insn_infoS *insn)
+{
+ nios2_insn_relocS *reloc = insn->insn_reloc;
+
+ /* If the reloc is NULL, there was an error assembling the branch. */
+ if (reloc != NULL)
+ {
+ symbolS *symp = reloc->reloc_expression.X_add_symbol;
+ offsetT offset = reloc->reloc_expression.X_add_number;
+ char *f;
+
+ /* Tag dwarf2 debug info to the address at the start of the insn.
+ We must do it before frag_var() below closes off the frag. */
+ dwarf2_emit_insn (0);
+
+ /* We create a machine dependent frag which can grow
+ to accommodate the largest possible instruction sequence
+ this may generate. */
+ f = frag_var (rs_machine_dependent,
+ UBRANCH_MAX_SIZE, 4, UBRANCH_SUBTYPE (0),
+ symp, offset, NULL);
+
+ md_number_to_chars (f, insn->insn_code, 4);
+
+ /* We leave fixup generation to md_convert_frag. */
+ }
+}
+
+/* Output a conditional branch. */
+static void
+output_cbranch (nios2_insn_infoS *insn)
+{
+ nios2_insn_relocS *reloc = insn->insn_reloc;
+
+ /* If the reloc is NULL, there was an error assembling the branch. */
+ if (reloc != NULL)
+ {
+ symbolS *symp = reloc->reloc_expression.X_add_symbol;
+ offsetT offset = reloc->reloc_expression.X_add_number;
+ char *f;
+
+ /* Tag dwarf2 debug info to the address at the start of the insn.
+ We must do it before frag_var() below closes off the frag. */
+ dwarf2_emit_insn (0);
+
+ /* We create a machine dependent frag which can grow
+ to accommodate the largest possible instruction sequence
+ this may generate. */
+ f = frag_var (rs_machine_dependent,
+ CBRANCH_MAX_SIZE, 4, CBRANCH_SUBTYPE (0),
+ symp, offset, NULL);
+
+ md_number_to_chars (f, insn->insn_code, 4);
+
+ /* We leave fixup generation to md_convert_frag. */
+ }
+}
+
+/* Output a call sequence. Since calls are not pc-relative for NIOS2,
+ but are page-relative, we cannot tell at any stage in assembly
+ whether a call will be out of range since a section may be linked
+ at any address. So if we are relaxing, we convert all call instructions
+ to long call sequences, and rely on the linker to relax them back to
+ short calls. */
+static void
+output_call (nios2_insn_infoS *insn)
+{
+ /* This allocates enough space for the instruction
+ and puts it in the current frag. */
+ char *f = frag_more (12);
+ nios2_insn_relocS *reloc = insn->insn_reloc;
+
+ md_number_to_chars (f, OP_MATCH_ORHI | 0x00400000, 4);
+ dwarf2_emit_insn (4);
+ fix_new_exp (frag_now, f - frag_now->fr_literal, 4,
+ &reloc->reloc_expression, 0, BFD_RELOC_NIOS2_HI16);
+ md_number_to_chars (f + 4, OP_MATCH_ORI | 0x08400000, 4);
+ dwarf2_emit_insn (4);
+ fix_new_exp (frag_now, f - frag_now->fr_literal + 4, 4,
+ &reloc->reloc_expression, 0, BFD_RELOC_NIOS2_LO16);
+ md_number_to_chars (f + 8, OP_MATCH_CALLR | 0x08000000, 4);
+ dwarf2_emit_insn (4);
+}
+
+/* Output an addi - will silently convert to
+ orhi if rA = r0 and (expr & 0xffff0000) == 0. */
+static void
+output_addi (nios2_insn_infoS *insn)
+{
+ if (can_evaluate_expr (insn))
+ {
+ int expr_val = get_expr_value (insn);
+ if (GET_INSN_FIELD (RRS, insn->insn_code) == 0
+ && (expr_val & 0xffff) == 0
+ && expr_val != 0)
+ {
+ /* We really want a movhi (orhi) here. */
+ insn->insn_code = (insn->insn_code & ~OP_MATCH_ADDI) | OP_MATCH_ORHI;
+ insn->insn_reloc->reloc_expression.X_add_number =
+ (insn->insn_reloc->reloc_expression.X_add_number >> 16) & 0xffff;
+ insn->insn_reloc->reloc_type = BFD_RELOC_NIOS2_U16;
+ }
+ }
+
+ /* Output an instruction. */
+ output_insn (insn);
+}
+
+static void
+output_andi (nios2_insn_infoS *insn)
+{
+ if (can_evaluate_expr (insn))
+ {
+ int expr_val = get_expr_value (insn);
+ if (expr_val != 0 && (expr_val & 0xffff) == 0)
+ {
+ /* We really want a movhi (orhi) here. */
+ insn->insn_code = (insn->insn_code & ~OP_MATCH_ANDI) | OP_MATCH_ANDHI;
+ insn->insn_reloc->reloc_expression.X_add_number =
+ (insn->insn_reloc->reloc_expression.X_add_number >> 16) & 0xffff;
+ insn->insn_reloc->reloc_type = BFD_RELOC_NIOS2_U16;
+ }
+ }
+
+ /* Output an instruction. */
+ output_insn (insn);
+}
+
+static void
+output_ori (nios2_insn_infoS *insn)
+{
+ if (can_evaluate_expr (insn))
+ {
+ int expr_val = get_expr_value (insn);
+ if (expr_val != 0 && (expr_val & 0xffff) == 0)
+ {
+ /* We really want a movhi (orhi) here. */
+ insn->insn_code = (insn->insn_code & ~OP_MATCH_ORI) | OP_MATCH_ORHI;
+ insn->insn_reloc->reloc_expression.X_add_number =
+ (insn->insn_reloc->reloc_expression.X_add_number >> 16) & 0xffff;
+ insn->insn_reloc->reloc_type = BFD_RELOC_NIOS2_U16;
+ }
+ }
+
+ /* Output an instruction. */
+ output_insn (insn);
+}
+
+static void
+output_xori (nios2_insn_infoS *insn)
+{
+ if (can_evaluate_expr (insn))
+ {
+ int expr_val = get_expr_value (insn);
+ if (expr_val != 0 && (expr_val & 0xffff) == 0)
+ {
+ /* We really want a movhi (orhi) here. */
+ insn->insn_code = (insn->insn_code & ~OP_MATCH_XORI) | OP_MATCH_XORHI;
+ insn->insn_reloc->reloc_expression.X_add_number =
+ (insn->insn_reloc->reloc_expression.X_add_number >> 16) & 0xffff;
+ insn->insn_reloc->reloc_type = BFD_RELOC_NIOS2_U16;
+ }
+ }
+
+ /* Output an instruction. */
+ output_insn (insn);
+}
+
+
+/* Output a movhi/addi pair for the movia pseudo-op. */
+static void
+output_movia (nios2_insn_infoS *insn)
+{
+ /* This allocates enough space for the instruction
+ and puts it in the current frag. */
+ char *f = frag_more (8);
+ nios2_insn_relocS *reloc = insn->insn_reloc;
+ unsigned long reg_index = GET_INSN_FIELD (IRT, insn->insn_code);
+
+ /* If the reloc is NULL, there was an error assembling the movia. */
+ if (reloc != NULL)
+ {
+ md_number_to_chars (f, insn->insn_code, 4);
+ dwarf2_emit_insn (4);
+ md_number_to_chars (f + 4,
+ (OP_MATCH_ADDI | (reg_index << OP_SH_IRT)
+ | (reg_index << OP_SH_IRS)),
+ 4);
+ dwarf2_emit_insn (4);
+ fix_new (frag_now, f - frag_now->fr_literal, 4,
+ reloc->reloc_expression.X_add_symbol,
+ reloc->reloc_expression.X_add_number, 0,
+ BFD_RELOC_NIOS2_HIADJ16);
+ fix_new (frag_now, f + 4 - frag_now->fr_literal, 4,
+ reloc->reloc_expression.X_add_symbol,
+ reloc->reloc_expression.X_add_number, 0, BFD_RELOC_NIOS2_LO16);
+ }
+}
+
+
+
+/** External interfaces. */
+
+/* The following functions are called by machine-independent parts of
+ the assembler. */
+int
+md_parse_option (int c, char *arg ATTRIBUTE_UNUSED)
+{
+ switch (c)
+ {
+ case 'r':
+ /* Hidden option for self-test mode. */
+ nios2_mode = NIOS2_MODE_TEST;
+ break;
+ case OPTION_RELAX_ALL:
+ nios2_as_options.relax = relax_all;
+ break;
+ case OPTION_NORELAX:
+ nios2_as_options.relax = relax_none;
+ break;
+ case OPTION_RELAX_SECTION:
+ nios2_as_options.relax = relax_section;
+ break;
+ case OPTION_EB:
+ target_big_endian = 1;
+ break;
+ case OPTION_EL:
+ target_big_endian = 0;
+ break;
+ default:
+ return 0;
+ break;
+ }
+
+ return 1;
+}
+
+/* Implement TARGET_FORMAT. We can choose to be big-endian or
+ little-endian at runtime based on a switch. */
+const char *
+nios2_target_format (void)
+{
+ return target_big_endian ? "elf32-bignios2" : "elf32-littlenios2";
+}
+
+/* Machine-dependent usage message. */
+void
+md_show_usage (FILE *stream)
+{
+ fprintf (stream, " NIOS2 options:\n"
+ " -relax-all replace all branch and call "
+ "instructions with jmp and callr sequences\n"
+ " -relax-section replace identified out of range "
+ "branches with jmp sequences (default)\n"
+ " -no-relax do not replace any branches or calls\n"
+ " -EB force big-endian byte ordering\n"
+ " -EL force little-endian byte ordering\n");
+}
+
+/* This function is called once, at assembler startup time.
+ It should set up all the tables, etc. that the MD part of the
+ assembler will need. */
+void
+md_begin (void)
+{
+ int i;
+ const char *inserted;
+
+ /* Create and fill a hashtable for the Nios II opcodes, registers and
+ arguments. */
+ nios2_opcode_hash = hash_new ();
+ nios2_reg_hash = hash_new ();
+ nios2_arg_hash = hash_new ();
+ nios2_ps_hash = hash_new ();
+
+ for (i = 0; i < NUMOPCODES; ++i)
+ {
+ inserted
+ = hash_insert (nios2_opcode_hash, nios2_opcodes[i].name,
+ (PTR) & nios2_opcodes[i]);
+ if (inserted != NULL)
+ {
+ fprintf (stderr, _("internal error: can't hash `%s': %s\n"),
+ nios2_opcodes[i].name, inserted);
+ /* Probably a memory allocation problem? Give up now. */
+ as_fatal (_("Broken assembler. No assembly attempted."));
+ }
+ }
+
+ for (i = 0; i < nios2_num_regs; ++i)
+ {
+ inserted
+ = hash_insert (nios2_reg_hash, nios2_regs[i].name,
+ (PTR) & nios2_regs[i]);
+ if (inserted != NULL)
+ {
+ fprintf (stderr, _("internal error: can't hash `%s': %s\n"),
+ nios2_regs[i].name, inserted);
+ /* Probably a memory allocation problem? Give up now. */
+ as_fatal (_("Broken assembler. No assembly attempted."));
+ }
+
+ }
+
+ for (i = 0; i < nios2_num_arg_info_structs; ++i)
+ {
+ inserted
+ = hash_insert (nios2_arg_hash, nios2_arg_info_structs[i].args,
+ (PTR) & nios2_arg_info_structs[i]);
+ if (inserted != NULL)
+ {
+ fprintf (stderr, _("internal error: can't hash `%s': %s\n"),
+ nios2_arg_info_structs[i].args, inserted);
+ /* Probably a memory allocation problem? Give up now. */
+ as_fatal (_("Broken assembler. No assembly attempted."));
+ }
+ }
+
+ for (i = 0; i < nios2_num_ps_insn_info_structs; ++i)
+ {
+ inserted
+ = hash_insert (nios2_ps_hash, nios2_ps_insn_info_structs[i].pseudo_insn,
+ (PTR) & nios2_ps_insn_info_structs[i]);
+ if (inserted != NULL)
+ {
+ fprintf (stderr, _("internal error: can't hash `%s': %s\n"),
+ nios2_ps_insn_info_structs[i].pseudo_insn, inserted);
+ /* Probably a memory allocation problem? Give up now. */
+ as_fatal (_("Broken assembler. No assembly attempted."));
+ }
+ }
+
+ /* Assembler option defaults. */
+ nios2_as_options.noat = FALSE;
+ nios2_as_options.nobreak = FALSE;
+
+ /* Debug information is incompatible with relaxation. */
+ if (debug_type != DEBUG_UNSPECIFIED)
+ nios2_as_options.relax = relax_none;
+
+ /* Initialize the alignment data. */
+ nios2_current_align_seg = now_seg;
+ nios2_last_label = NULL;
+ nios2_current_align = 0;
+}
+
+
+/* Assembles a single line of Nios II assembly language. */
+void
+md_assemble (char *op_str)
+{
+ char *argstr;
+ char *op_strdup = NULL;
+ nios2_arg_infoS *arg_info;
+ unsigned long saved_pinfo = 0;
+ nios2_insn_infoS thisinsn;
+ nios2_insn_infoS *insn = &thisinsn;
+
+ /* Make sure we are aligned on a 4-byte boundary. */
+ if (nios2_current_align < 2)
+ nios2_align (2, NULL, nios2_last_label);
+ else if (nios2_current_align > 2)
+ nios2_current_align = 2;
+ nios2_last_label = NULL;
+
+ /* We don't want to clobber to op_str
+ because we want to be able to use it in messages. */
+ op_strdup = strdup (op_str);
+ insn->insn_tokens[0] = strtok (op_strdup, " ");
+ argstr = strtok (NULL, "");
+
+ /* Assemble the opcode. */
+ insn->insn_nios2_opcode = nios2_opcode_lookup (insn->insn_tokens[0]);
+ insn->insn_reloc = NULL;
+
+ if (insn->insn_nios2_opcode != NULL)
+ {
+ nios2_ps_insn_infoS *ps_insn = NULL;
+ /* Set the opcode for the instruction. */
+ insn->insn_code = insn->insn_nios2_opcode->match;
+
+ /* Parse the arguments pointed to by argstr. */
+ if (nios2_mode == NIOS2_MODE_ASSEMBLE)
+ nios2_parse_args (insn, argstr, insn->insn_nios2_opcode->args,
+ (char **) &insn->insn_tokens[1]);
+ else
+ nios2_parse_args (insn, argstr, insn->insn_nios2_opcode->args_test,
+ (char **) &insn->insn_tokens[1]);
+
+ /* We need to preserve the MOVIA macro as this is clobbered by
+ translate_pseudo_insn. */
+ if (insn->insn_nios2_opcode->pinfo == NIOS2_INSN_MACRO_MOVIA)
+ saved_pinfo = NIOS2_INSN_MACRO_MOVIA;
+ /* If the instruction is an pseudo-instruction, we want to replace it
+ with its real equivalent, and then continue. */
+ if ((insn->insn_nios2_opcode->pinfo & NIOS2_INSN_MACRO)
+ == NIOS2_INSN_MACRO)
+ ps_insn = nios2_translate_pseudo_insn (insn);
+
+ /* Find the assemble function, and call it. */
+ arg_info = nios2_arg_lookup (insn->insn_nios2_opcode->args);
+ if (arg_info != NULL)
+ {
+ arg_info->assemble_args_func (insn);
+
+ if (nios2_as_options.relax != relax_none
+ && !nios2_as_options.noat
+ && insn->insn_nios2_opcode->pinfo & NIOS2_INSN_UBRANCH)
+ output_ubranch (insn);
+ else if (nios2_as_options.relax != relax_none
+ && !nios2_as_options.noat
+ && insn->insn_nios2_opcode->pinfo & NIOS2_INSN_CBRANCH)
+ output_cbranch (insn);
+ else if (nios2_as_options.relax == relax_all
+ && !nios2_as_options.noat
+ && insn->insn_nios2_opcode->pinfo & NIOS2_INSN_CALL
+ && insn->insn_reloc
+ && insn->insn_reloc->reloc_type == BFD_RELOC_NIOS2_CALL26)
+ output_call (insn);
+ else if (insn->insn_nios2_opcode->pinfo & NIOS2_INSN_ANDI)
+ output_andi (insn);
+ else if (insn->insn_nios2_opcode->pinfo & NIOS2_INSN_ORI)
+ output_ori (insn);
+ else if (insn->insn_nios2_opcode->pinfo & NIOS2_INSN_XORI)
+ output_xori (insn);
+ else if (insn->insn_nios2_opcode->pinfo & NIOS2_INSN_ADDI)
+ output_addi (insn);
+ else if (saved_pinfo == NIOS2_INSN_MACRO_MOVIA)
+ output_movia (insn);
+ else
+ output_insn (insn);
+ if (ps_insn)
+ nios2_cleanup_pseudo_insn (insn, ps_insn);
+ }
+ else
+ {
+ /* The assembler is broken. */
+ fprintf (stderr,
+ _("internal error: %s is not a valid argument syntax\n"),
+ insn->insn_nios2_opcode->args);
+ /* Probably a memory allocation problem. Give up now. */
+ as_fatal (_("Broken assembler. No assembly attempted."));
+ }
+ }
+ else
+ /* Unrecognised instruction - error. */
+ as_bad (_("unrecognised instruction %s"), insn->insn_tokens[0]);
+
+ /* Don't leak memory. */
+ free (op_strdup);
+}
+
+/* Round up section size. */
+valueT
+md_section_align (asection *seg ATTRIBUTE_UNUSED, valueT size)
+{
+ /* I think byte alignment is fine here. */
+ return size;
+}
+
+/* Implement TC_FORCE_RELOCATION. */
+int
+nios2_force_relocation (fixS *fixp)
+{
+ if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+ || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY
+ || fixp->fx_r_type == BFD_RELOC_NIOS2_ALIGN)
+ return 1;
+
+ return generic_force_reloc (fixp);
+}
+
+/* Implement tc_fix_adjustable. */
+int
+nios2_fix_adjustable (fixS *fixp)
+{
+ if (fixp->fx_addsy == NULL)
+ return 1;
+
+#ifdef OBJ_ELF
+ /* Prevent all adjustments to global symbols. */
+ if (OUTPUT_FLAVOR == bfd_target_elf_flavour
+ && (S_IS_EXTERNAL (fixp->fx_addsy) || S_IS_WEAK (fixp->fx_addsy)))
+ return 0;
+#endif
+ if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+ || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+ return 0;
+
+ /* Preserve relocations against symbols with function type. */
+ if (symbol_get_bfdsym (fixp->fx_addsy)->flags & BSF_FUNCTION)
+ return 0;
+
+ /* Don't allow symbols to be discarded on GOT related relocs. */
+ if (fixp->fx_r_type == BFD_RELOC_NIOS2_GOT16
+ || fixp->fx_r_type == BFD_RELOC_NIOS2_CALL16
+ || fixp->fx_r_type == BFD_RELOC_NIOS2_GOTOFF_LO
+ || fixp->fx_r_type == BFD_RELOC_NIOS2_GOTOFF_HA
+ || fixp->fx_r_type == BFD_RELOC_NIOS2_TLS_GD16
+ || fixp->fx_r_type == BFD_RELOC_NIOS2_TLS_LDM16
+ || fixp->fx_r_type == BFD_RELOC_NIOS2_TLS_LDO16
+ || fixp->fx_r_type == BFD_RELOC_NIOS2_TLS_IE16
+ || fixp->fx_r_type == BFD_RELOC_NIOS2_TLS_LE16
+ || fixp->fx_r_type == BFD_RELOC_NIOS2_TLS_DTPMOD
+ || fixp->fx_r_type == BFD_RELOC_NIOS2_TLS_DTPREL
+ || fixp->fx_r_type == BFD_RELOC_NIOS2_TLS_TPREL
+ || fixp->fx_r_type == BFD_RELOC_NIOS2_GOTOFF)
+ return 0;
+
+ return 1;
+}
+
+/* Implement tc_frob_symbol. This is called in adjust_reloc_syms;
+ it is used to remove *ABS* references from the symbol table. */
+int
+nios2_frob_symbol (symbolS *symp)
+{
+ if ((OUTPUT_FLAVOR == bfd_target_elf_flavour
+ && symp == section_symbol (absolute_section))
+ || !S_IS_DEFINED (symp))
+ return 1;
+ else
+ return 0;
+}
+
+/* The function tc_gen_reloc creates a relocation structure for the
+ fixup fixp, and returns a pointer to it. This structure is passed
+ to bfd_install_relocation so that it can be written to the object
+ file for linking. */
+arelent *
+tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
+{
+ arelent *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;
+ reloc->addend = fixp->fx_offset; /* fixp->fx_addnumber; */
+
+ if (fixp->fx_pcrel)
+ {
+ switch (fixp->fx_r_type)
+ {
+ case BFD_RELOC_16:
+ fixp->fx_r_type = BFD_RELOC_16_PCREL;
+ break;
+ case BFD_RELOC_NIOS2_LO16:
+ fixp->fx_r_type = BFD_RELOC_NIOS2_PCREL_LO;
+ break;
+ case BFD_RELOC_NIOS2_HIADJ16:
+ fixp->fx_r_type = BFD_RELOC_NIOS2_PCREL_HA;
+ break;
+ default:
+ break;
+ }
+ }
+
+ reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
+ if (reloc->howto == NULL)
+ {
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("can't represent relocation type %s"),
+ bfd_get_reloc_code_name (fixp->fx_r_type));
+
+ /* Set howto to a garbage value so that we can keep going. */
+ reloc->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_32);
+ gas_assert (reloc->howto != NULL);
+ }
+ return reloc;
+}
+
+long
+md_pcrel_from (fixS *fixP ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+/* Called just before the assembler exits. */
+void
+md_end ()
+{
+ /* FIXME - not yet implemented */
+}
+
+/* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
+ Otherwise we have no need to default values of symbols. */
+symbolS *
+md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
+{
+#ifdef OBJ_ELF
+ if (name[0] == '_' && name[1] == 'G'
+ && strcmp (name, GLOBAL_OFFSET_TABLE_NAME) == 0)
+ {
+ if (!GOT_symbol)
+ {
+ if (symbol_find (name))
+ as_bad ("GOT already in the symbol table");
+
+ GOT_symbol = symbol_new (name, undefined_section,
+ (valueT) 0, &zero_address_frag);
+ }
+
+ return GOT_symbol;
+ }
+#endif
+
+ return 0;
+}
+
+/* Implement tc_frob_label. */
+void
+nios2_frob_label (symbolS *lab)
+{
+ /* Emit dwarf information. */
+ dwarf2_emit_label (lab);
+
+ /* Update the label's address with the current output pointer. */
+ symbol_set_frag (lab, frag_now);
+ S_SET_VALUE (lab, (valueT) frag_now_fix ());
+
+ /* Record this label for future adjustment after we find out what
+ kind of data it references, and the required alignment therewith. */
+ nios2_last_label = lab;
+}
+
+/* Implement md_cons_align. */
+void
+nios2_cons_align (int size)
+{
+ int log_size = 0;
+ const char *pfill = NULL;
+
+ while ((size >>= 1) != 0)
+ ++log_size;
+
+ if (subseg_text_p (now_seg))
+ pfill = (const char *) &nop;
+ else
+ pfill = NULL;
+
+ if (nios2_auto_align_on)
+ nios2_align (log_size, pfill, NULL);
+
+ nios2_last_label = NULL;
+}
+
+/* Map 's' to SHF_NIOS2_GPREL. */
+/* This is from the Alpha code tc-alpha.c. */
+int
+nios2_elf_section_letter (int letter, char **ptr_msg)
+{
+ if (letter == 's')
+ return SHF_NIOS2_GPREL;
+
+ *ptr_msg = _("Bad .section directive: want a,s,w,x,M,S,G,T in string");
+ return -1;
+}
+
+/* Map SHF_ALPHA_GPREL to SEC_SMALL_DATA. */
+/* This is from the Alpha code tc-alpha.c. */
+flagword
+nios2_elf_section_flags (flagword flags, int attr, int type ATTRIBUTE_UNUSED)
+{
+ if (attr & SHF_NIOS2_GPREL)
+ flags |= SEC_SMALL_DATA;
+ return flags;
+}
+
+/* Implement TC_PARSE_CONS_EXPRESSION to handle %tls_ldo(...) */
+static int nios2_tls_ldo_reloc;
+
+void
+nios2_cons (expressionS *exp, int size)
+{
+ nios2_tls_ldo_reloc = 0;
+
+ SKIP_WHITESPACE ();
+ if (input_line_pointer[0] == '%')
+ {
+ if (strprefix (input_line_pointer + 1, "tls_ldo"))
+ {
+ if (size != 4)
+ as_bad (_("Illegal operands: %%tls_ldo in %d-byte data field"),
+ size);
+ else
+ {
+ input_line_pointer += 8;
+ nios2_tls_ldo_reloc = 1;
+ }
+ }
+ if (nios2_tls_ldo_reloc)
+ {
+ SKIP_WHITESPACE ();
+ if (input_line_pointer[0] != '(')
+ as_bad (_("Illegal operands: %%tls_ldo requires arguments in ()"));
+ else
+ {
+ int c;
+ char *end = ++input_line_pointer;
+ int npar = 0;
+
+ for (c = *end; !is_end_of_line[c]; end++, c = *end)
+ if (c == '(')
+ npar++;
+ else if (c == ')')
+ {
+ if (!npar)
+ break;
+ npar--;
+ }
+
+ if (c != ')')
+ as_bad (_("Illegal operands: %%tls_ldo requires arguments in ()"));
+ else
+ {
+ *end = '\0';
+ expression (exp);
+ *end = c;
+ if (input_line_pointer != end)
+ as_bad (_("Illegal operands: %%tls_ldo requires arguments in ()"));
+ else
+ {
+ input_line_pointer++;
+ SKIP_WHITESPACE ();
+ c = *input_line_pointer;
+ if (! is_end_of_line[c] && c != ',')
+ as_bad (_("Illegal operands: garbage after %%tls_ldo()"));
+ }
+ }
+ }
+ }
+ }
+ if (!nios2_tls_ldo_reloc)
+ expression (exp);
+}
+
+/* Implement TC_CONS_FIX_NEW. */
+void
+nios2_cons_fix_new (fragS *frag, int where, unsigned int nbytes,
+ expressionS *exp)
+{
+ bfd_reloc_code_real_type r;
+
+ r = (nbytes == 1 ? BFD_RELOC_8
+ : (nbytes == 2 ? BFD_RELOC_16
+ : (nbytes == 4 ? BFD_RELOC_32 : BFD_RELOC_64)));
+
+ if (nios2_tls_ldo_reloc)
+ r = BFD_RELOC_NIOS2_TLS_DTPREL;
+
+ fix_new_exp (frag, where, (int) nbytes, exp, 0, r);
+ nios2_tls_ldo_reloc = 0;
+}
+
+/* Implement HANDLE_ALIGN. */
+void
+nios2_handle_align (fragS *fragp)
+{
+ /* If we are expecting to relax in the linker, then we must output a
+ relocation to tell the linker we are aligning code. */
+ if (nios2_as_options.relax == relax_all
+ && (fragp->fr_type == rs_align || fragp->fr_type == rs_align_code)
+ && fragp->fr_address + fragp->fr_fix > 0
+ && fragp->fr_offset > 1
+ && now_seg != bss_section)
+ fix_new (fragp, fragp->fr_fix, 0, &abs_symbol, fragp->fr_offset, 0,
+ BFD_RELOC_NIOS2_ALIGN);
+}
+
+/* Implement tc_regname_to_dw2regnum, to convert REGNAME to a DWARF-2
+ register number. */
+int
+nios2_regname_to_dw2regnum (char *regname)
+{
+ struct nios2_reg *r = nios2_reg_lookup (regname);
+ if (r == NULL)
+ return -1;
+ return r->index;
+}
+
+/* Implement tc_cfi_frame_initial_instructions, to initialize the DWARF-2
+ unwind information for this procedure. */
+void
+nios2_frame_initial_instructions (void)
+{
+ cfi_add_CFA_def_cfa (27, 0);
+}
diff --git a/gas/config/tc-nios2.h b/gas/config/tc-nios2.h
new file mode 100644
index 0000000000..9e69194126
--- /dev/null
+++ b/gas/config/tc-nios2.h
@@ -0,0 +1,125 @@
+/* Definitions for Altera Nios II assembler.
+ Copyright (C) 2012, 2013 Free Software Foundation, Inc.
+ Contributed by Nigel Gray (ngray@altera.com).
+ Contributed by Mentor Graphics, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+#ifndef TC_NIOS2
+#define TC_NIOS2
+
+/* If unspecified, default to little endian. We can explicitly specify
+ * a big-endian default by configuring with --target=nios2eb-elf. We
+ * can override the default with the -EB and -EL options. */
+#ifndef TARGET_BYTES_BIG_ENDIAN
+#define TARGET_BYTES_BIG_ENDIAN 0
+#endif
+
+/* Words are big enough to hold addresses. */
+#define WORKING_DOT_WORD 1
+
+#ifdef OBJ_ELF
+extern const char *nios2_target_format (void);
+#define TARGET_FORMAT nios2_target_format ()
+#define TARGET_ARCH bfd_arch_nios2
+#endif
+
+/* A NIOS2 instruction consists of tokens and separator characters
+ the tokens are things like the instruction name (add, or jmp etc),
+ the register indices ($5, $7 etc), and constant expressions. The
+ separator characters are commas, brackets and space.
+ The instruction name is always separated from other tokens by a space
+ The maximum number of tokens in an instruction is 5 (the instruction name,
+ 3 arguments, and a 4th string representing the expected instructin opcode
+ after assembly. The latter is only used when the assemble is running in
+ self test mode, otherwise its presence will generate an error. */
+#define NIOS2_MAX_INSN_TOKENS 6
+
+/* There are no machine-specific operands so we #define this to nothing. */
+#define md_operand(x)
+
+/* Function prototypes exported to rest of GAS. */
+extern void md_assemble (char *op_str);
+extern void md_end (void);
+extern void md_begin (void);
+
+#define TC_FORCE_RELOCATION(fixp) nios2_force_relocation (fixp)
+extern int nios2_force_relocation (struct fix *);
+
+#define tc_fix_adjustable(fixp) nios2_fix_adjustable (fixp)
+extern int nios2_fix_adjustable (struct fix *);
+
+#define tc_frob_label(lab) nios2_frob_label (lab)
+extern void nios2_frob_label (symbolS *);
+
+#define tc_frob_symbol(symp, punt) punt = nios2_frob_symbol (symp) ? 1 : punt
+extern int nios2_frob_symbol (symbolS * symp);
+
+#define md_cons_align(nbytes) nios2_cons_align (nbytes)
+extern void nios2_cons_align (int);
+
+extern void md_convert_frag (bfd * headers, segT sec, fragS * fragP);
+
+/* When relaxing, we need to generate relocations for alignment
+ directives. */
+#define HANDLE_ALIGN(frag) nios2_handle_align (frag)
+extern void nios2_handle_align (fragS *);
+
+#define md_relax_frag nios2_relax_frag
+extern long nios2_relax_frag (segT segment, fragS * fragP, long stretch);
+
+#ifdef OBJ_ELF
+#define ELF_TC_SPECIAL_SECTIONS \
+ { ".sdata", SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_NIOS2_GPREL }, \
+ { ".sbss", SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_NIOS2_GPREL }, \
+ { ".lit4", SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_NIOS2_GPREL }, \
+ { ".lit8", SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_NIOS2_GPREL },
+
+/* Processor-specific section directives. */
+#define md_elf_section_letter nios2_elf_section_letter
+extern int nios2_elf_section_letter (int, char **);
+#define md_elf_section_flags nios2_elf_section_flags
+extern flagword nios2_elf_section_flags (flagword, int, int);
+#endif
+
+#define GLOBAL_OFFSET_TABLE_NAME "_GLOBAL_OFFSET_TABLE_"
+
+#define DIFF_EXPR_OK
+
+/* Nios2 ABI doesn't have 32-bit PCREL relocation, and, as relocations for
+ CFI information will be in section other than .text, we can't use PC-biased
+ relocs. */
+#define CFI_DIFF_EXPR_OK 0
+
+#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) nios2_cons (EXP, NBYTES)
+extern void nios2_cons (expressionS *exp, int size);
+
+#define TC_CONS_FIX_NEW nios2_cons_fix_new
+extern void nios2_cons_fix_new (struct frag *frag, int where,
+ unsigned int nbytes, struct expressionS *exp);
+
+/* We want .cfi_* pseudo-ops for generating unwind info. */
+#define TARGET_USE_CFIPOP 1
+#define DWARF2_DEFAULT_RETURN_COLUMN 31
+#define DWARF2_CIE_DATA_ALIGNMENT (-4)
+#define tc_regname_to_dw2regnum nios2_regname_to_dw2regnum
+extern int nios2_regname_to_dw2regnum (char *regname);
+#define tc_cfi_frame_initial_instructions nios2_frame_initial_instructions
+extern void nios2_frame_initial_instructions (void);
+
+#endif /* TC_NIOS2 */
diff --git a/gas/configure.tgt b/gas/configure.tgt
index 8454ab9a9e..9d498e81e8 100644
--- a/gas/configure.tgt
+++ b/gas/configure.tgt
@@ -350,6 +350,8 @@ case ${generic_target} in
msp430-*-*) fmt=elf ;;
+ nios2*-linux*) fmt=elf em=linux ;;
+
ns32k-pc532-mach*) fmt=aout em=pc532mach ;;
ns32k-pc532-ux*) fmt=aout em=pc532mach ;;
ns32k-pc532-lites*) fmt=aout em=nbsd532 ;;
diff --git a/gas/doc/Makefile.am b/gas/doc/Makefile.am
index b200378ba6..3d1e9339bc 100644
--- a/gas/doc/Makefile.am
+++ b/gas/doc/Makefile.am
@@ -74,6 +74,7 @@ CPU_DOCS = \
c-mmix.texi \
c-mt.texi \
c-msp430.texi \
+ c-nios2.texi \
c-ns32k.texi \
c-pdp11.texi \
c-pj.texi \
diff --git a/gas/doc/Makefile.in b/gas/doc/Makefile.in
index 9969ff4d33..4c3c4fb8f9 100644
--- a/gas/doc/Makefile.in
+++ b/gas/doc/Makefile.in
@@ -316,6 +316,7 @@ CPU_DOCS = \
c-mmix.texi \
c-mt.texi \
c-msp430.texi \
+ c-nios2.texi \
c-ns32k.texi \
c-pdp11.texi \
c-pj.texi \
@@ -410,17 +411,17 @@ as.info: as.texinfo $(as_TEXINFOS)
fi; \
rm -rf $$backupdir; exit $$rc
-as.dvi: as.texinfo $(as_TEXINFOS)
+as.dvi: as.texinfo $(as_TEXINFOS)
TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \
$(TEXI2DVI) -o $@ `test -f 'as.texinfo' || echo '$(srcdir)/'`as.texinfo
-as.pdf: as.texinfo $(as_TEXINFOS)
+as.pdf: as.texinfo $(as_TEXINFOS)
TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \
$(TEXI2PDF) -o $@ `test -f 'as.texinfo' || echo '$(srcdir)/'`as.texinfo
-as.html: as.texinfo $(as_TEXINFOS)
+as.html: as.texinfo $(as_TEXINFOS)
rm -rf $(@:.html=.htp)
if $(MAKEINFOHTML) $(AM_MAKEINFOHTMLFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \
-o $(@:.html=.htp) `test -f 'as.texinfo' || echo '$(srcdir)/'`as.texinfo; \
diff --git a/gas/doc/all.texi b/gas/doc/all.texi
index b213ad76b5..99dbf8ff72 100644
--- a/gas/doc/all.texi
+++ b/gas/doc/all.texi
@@ -58,6 +58,7 @@
@set MMIX
@set MS1
@set MSP430
+@set NIOSII
@set NS32K
@set PDP11
@set PJ
diff --git a/gas/doc/as.texinfo b/gas/doc/as.texinfo
index c976c05381..cafcb22c99 100644
--- a/gas/doc/as.texinfo
+++ b/gas/doc/as.texinfo
@@ -431,6 +431,12 @@ gcc(1), ld(1), and the Info entries for @file{binutils} and @file{ld}.
[@b{--no-expand}] [@b{--no-merge-gregs}] [@b{-x}]
[@b{--linker-allocated-gregs}]
@end ifset
+@ifset NIOSII
+
+@emph{Target Nios II options:}
+ [@b{-relax-all}] [@b{-relax-section}] [@b{-no-relax}]
+ [@b{-EB}] [@b{-EL}]
+@end ifset
@ifset PDP11
@emph{Target PDP11 options:}
@@ -1028,6 +1034,24 @@ unit coprocessor. The default is to assume an MMU for 68020 and up.
@end table
@end ifset
+@ifset NIOSII
+
+@ifclear man
+@xref{Nios II Options}, for the options available when @value{AS} is configured
+for an Altera Nios II processor.
+@end ifclear
+
+@ifset man
+@c man begin OPTIONS
+The following options are available when @value{AS} is configured for an
+Altera Nios II processor.
+@c man end
+@c man begin INCLUDE
+@include c-nios2.texi
+@c ended inside the included file
+@end ifset
+@end ifset
+
@ifset PDP11
For details about the PDP-11 machine dependent features options,
@@ -7059,6 +7083,9 @@ subject, see the hardware manufacturer's manual.
@ifset MSP430
* MSP430-Dependent:: MSP430 Dependent Features
@end ifset
+@ifset NIOSII
+* NiosII-Dependent:: Altera Nios II Dependent Features
+@end ifset
@ifset NS32K
* NS32K-Dependent:: NS32K Dependent Features
@end ifset
@@ -7270,6 +7297,10 @@ family.
@include c-msp430.texi
@end ifset
+@ifset NIOSII
+@include c-nios2.texi
+@end ifset
+
@ifset NS32K
@include c-ns32k.texi
@end ifset
diff --git a/gas/doc/c-nios2.texi b/gas/doc/c-nios2.texi
new file mode 100644
index 0000000000..1d45dd20b2
--- /dev/null
+++ b/gas/doc/c-nios2.texi
@@ -0,0 +1,249 @@
+@c Copyright 2012, 2013 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 NiosII-Dependent
+@chapter Nios II Dependent Features
+@end ifset
+@ifclear GENERIC
+@node Machine Dependencies
+@chapter Nios II Dependent Features
+@end ifclear
+
+@cindex Altera Nios II support
+@cindex Nios support
+@cindex Nios II support
+@menu
+* Nios II Options:: Options
+* Nios II Syntax:: Syntax
+* Nios II Relocations:: Relocations
+* Nios II Directives:: Nios II Machine Directives
+* Nios II Opcodes:: Opcodes
+@end menu
+
+@node Nios II Options
+@section Options
+@cindex Nios II options
+@cindex options for Nios II
+
+@c man begin OPTIONS
+@table @gcctabopt
+
+@cindex @code{relax-section} command line option, Nios II
+@item -relax-section
+Replace identified out-of-range branches with PC-relative @code{jmp}
+sequences when possible. The generated code sequences are suitable
+for use in position-independent code, but there is a practical limit
+on the extended branch range because of the length of the sequences.
+This option is the default.
+
+@cindex @code{relax-all} command line option, Nios II
+@item -relax-all
+Replace branch instructions not determinable to be in range
+and all call instructions with @code{jmp} and @code{callr} sequences
+(respectively). This option generates absolute relocations against the
+target symbols and is not appropriate for position-independent code.
+
+@cindex @code{no-relax} command line option, Nios II
+@item -no-relax
+Do not replace any branches or calls.
+
+@cindex @code{EB} command line option, Nios II
+@item -EB
+Generate big-endian output.
+
+@cindex @code{EL} command line option, Nios II
+@item -EL
+Generate little-endian output. This is the default.
+
+@end table
+@c man end
+
+@node Nios II Syntax
+@section Syntax
+@menu
+* Nios II Chars:: Special Characters
+@end menu
+
+
+@node Nios II Chars
+@subsection Special Characters
+
+@cindex line comment character, Nios II
+@cindex Nios II line comment character
+@cindex line separator character, Nios II
+@cindex Nios II line separator character
+@samp{#} is the line comment character.
+@samp{;} is the line separator character.
+
+
+@node Nios II Relocations
+@section Nios II Machine Relocations
+
+@cindex machine relocations, Nios II
+@cindex Nios II machine relocations
+
+@table @code
+@cindex @code{hiadj} directive, Nios II
+@item %hiadj(@var{expression})
+Extract the upper 16 bits of @var{expression} and add
+one if the 15th bit is set.
+
+The value of @code{%hiadj(@var{expression})} is:
+@smallexample
+((@var{expression} >> 16) & 0xffff) + ((@var{expression} >> 15) & 0x01)
+@end smallexample
+
+The @code{%hiadj} relocation is intended to be used with
+the @code{addi}, @code{ld} or @code{st} instructions
+along with a @code{%lo}, in order to load a 32-bit constant.
+
+@smallexample
+movhi r2, %hiadj(symbol)
+addi r2, r2, %lo(symbol)
+@end smallexample
+
+@cindex @code{hi} directive, Nios II
+@item %hi(@var{expression})
+Extract the upper 16 bits of @var{expression}.
+
+@cindex @code{lo} directive, Nios II
+@item %lo(@var{expression})
+Extract the lower 16 bits of @var{expression}.
+
+@cindex @code{gprel} directive, Nios II
+@item %gprel(@var{expression})
+Subtract the value of the symbol @code{_gp} from
+@var{expression}.
+
+The intention of the @code{%gprel} relocation is
+to have a fast small area of memory which only
+takes a 16-bit immediate to access.
+
+@smallexample
+ .section .sdata
+fastint:
+ .int 123
+ .section .text
+ ldw r4, %gprel(fastint)(gp)
+@end smallexample
+
+@cindex @code{call} directive, Nios II
+@cindex @code{got} directive, Nios II
+@cindex @code{gotoff} directive, Nios II
+@cindex @code{gotoff_lo} directive, Nios II
+@cindex @code{gotoff_hiadj} directive, Nios II
+@cindex @code{tls_gd} directive, Nios II
+@cindex @code{tls_ie} directive, Nios II
+@cindex @code{tls_le} directive, Nios II
+@cindex @code{tls_ldm} directive, Nios II
+@cindex @code{tls_ldo} directive, Nios II
+@item %call(@var{expression})
+@itemx %got(@var{expression})
+@itemx %gotoff(@var{expression})
+@itemx %gotoff_lo(@var{expression})
+@itemx %gotoff_hiadj(@var{expression})
+@itemx %tls_gd(@var{expression})
+@itemx %tls_ie(@var{expression})
+@itemx %tls_le(@var{expression})
+@itemx %tls_ldm(@var{expression})
+@itemx %tls_ldo(@var{expression})
+
+These relocations support the ABI for Linux Systems documented in the
+@cite{Nios II Processor Reference Handbook}.
+@end table
+
+
+@node Nios II Directives
+@section Nios II Machine Directives
+
+@cindex machine directives, Nios II
+@cindex Nios II machine directives
+
+@table @code
+
+@cindex @code{align} directive, Nios II
+@item .align @var{expression} [, @var{expression}]
+This is the generic @code{.align} directive, however
+this aligns to a power of two.
+
+@cindex @code{half} directive, Nios II
+@item .half @var{expression}
+Create an aligned constant 2 bytes in size.
+
+@cindex @code{word} directive, Nios II
+@item .word @var{expression}
+Create an aligned constant 4 bytes in size.
+
+@cindex @code{dword} directive, Nios II
+@item .dword @var{expression}
+Create an aligned constant 8 bytes in size.
+
+@cindex @code{2byte} directive, Nios II
+@item .2byte @var{expression}
+Create an unaligned constant 2 bytes in size.
+
+@cindex @code{4byte} directive, Nios II
+@item .4byte @var{expression}
+Create an unaligned constant 4 bytes in size.
+
+@cindex @code{8byte} directive, Nios II
+@item .8byte @var{expression}
+Create an unaligned constant 8 bytes in size.
+
+@cindex @code{16byte} directive, Nios II
+@item .16byte @var{expression}
+Create an unaligned constant 16 bytes in size.
+
+@cindex @code{set noat} directive, Nios II
+@item .set noat
+Allows assembly code to use @code{at} register without
+warning. Macro or relaxation expansions
+generate warnings.
+
+@cindex @code{set at} directive, Nios II
+@item .set at
+Assembly code using @code{at} register generates
+warnings, and macro expansion and relaxation are
+enabled.
+
+@cindex @code{set nobreak} directive, Nios II
+@item .set nobreak
+Allows assembly code to use @code{ba} and @code{bt}
+registers without warning.
+
+@cindex @code{set break} directive, Nios II
+@item .set break
+Turns warnings back on for using @code{ba} and @code{bt}
+registers.
+
+@cindex @code{set norelax} directive, Nios II
+@item .set norelax
+Do not replace any branches or calls.
+
+@cindex @code{set relaxsection} directive, Nios II
+@item .set relaxsection
+Replace identified out-of-range branches with
+@code{jmp} sequences (default).
+
+@cindex @code{set relaxall} directive, Nios II
+@item .set relaxsection
+Replace all branch and call instructions with
+@code{jmp} and @code{callr} sequences.
+
+@cindex @code{set} directive, Nios II
+@item .set @dots{}
+All other @code{.set} are the normal use.
+
+@end table
+
+@node Nios II Opcodes
+@section Opcodes
+
+@cindex Nios II opcodes
+@cindex opcodes for Nios II
+@code{@value{AS}} implements all the standard Nios II opcodes documented in the
+@cite{Nios II Processor Reference Handbook}, including the assembler
+pseudo-instructions.
diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog
index ab916891ed..e165af4136 100644
--- a/gas/testsuite/ChangeLog
+++ b/gas/testsuite/ChangeLog
@@ -1,3 +1,94 @@
+2013-02-06 Sandra Loosemore <sandra@codesourcery.com>
+ Andrew Jenner <andrew@codesourcery.com>
+
+ Based on patches from Altera Corporation.
+
+ * gas/nios2/add.d: New.
+ * gas/nios2/add.s: New.
+ * gas/nios2/align_fill.d: New.
+ * gas/nios2/align_fill.s: New.
+ * gas/nios2/align_text.d: New.
+ * gas/nios2/align_text.s: New.
+ * gas/nios2/and.d: New.
+ * gas/nios2/and.s: New.
+ * gas/nios2/branch.d: New.
+ * gas/nios2/branch.s: New.
+ * gas/nios2/break.d: New.
+ * gas/nios2/break.s: New.
+ * gas/nios2/bret.d: New.
+ * gas/nios2/bret.s: New.
+ * gas/nios2/cache.d: New.
+ * gas/nios2/cache.s: New.
+ * gas/nios2/call26.d: New.
+ * gas/nios2/call26.s: New.
+ * gas/nios2/call.d: New.
+ * gas/nios2/call.s: New.
+ * gas/nios2/cmp.d: New.
+ * gas/nios2/cmp.s: New.
+ * gas/nios2/comments.d: New.
+ * gas/nios2/comments.s: New.
+ * gas/nios2/complex.d: New.
+ * gas/nios2/complex.s: New.
+ * gas/nios2/ctl.d: New.
+ * gas/nios2/ctl.s: New.
+ * gas/nios2/custom.d: New.
+ * gas/nios2/custom.s: New.
+ * gas/nios2/etbt.d: New.
+ * gas/nios2/etbt.s: New.
+ * gas/nios2/flushda.d: New.
+ * gas/nios2/flushda.s: New.
+ * gas/nios2/illegal.l: New.
+ * gas/nios2/illegal.s: New.
+ * gas/nios2/jmp.d: New.
+ * gas/nios2/jmp.s: New.
+ * gas/nios2/ldb.d: New.
+ * gas/nios2/ldb.s: New.
+ * gas/nios2/ldh.d: New.
+ * gas/nios2/ldh.s: New.
+ * gas/nios2/ldw.d: New.
+ * gas/nios2/ldw.s: New.
+ * gas/nios2/lineseparator.d: New.
+ * gas/nios2/lineseparator.s: New.
+ * gas/nios2/mov.d: New.
+ * gas/nios2/movia.d: New.
+ * gas/nios2/movia.s: New.
+ * gas/nios2/movi.d: New.
+ * gas/nios2/movi.s: New.
+ * gas/nios2/mov.s: New.
+ * gas/nios2/mul.d: New.
+ * gas/nios2/mul.s: New.
+ * gas/nios2/nios2.exp: New.
+ * gas/nios2/nor.d: New.
+ * gas/nios2/nor.s: New.
+ * gas/nios2/or.d: New.
+ * gas/nios2/or.s: New.
+ * gas/nios2/ret.d: New.
+ * gas/nios2/ret.s: New.
+ * gas/nios2/rol.d: New.
+ * gas/nios2/rol.s: New.
+ * gas/nios2/rotate.d: New.
+ * gas/nios2/rotate.s: New.
+ * gas/nios2/stb.d: New.
+ * gas/nios2/stb.s: New.
+ * gas/nios2/sth.d: New.
+ * gas/nios2/sth.s: New.
+ * gas/nios2/stw.d: New.
+ * gas/nios2/stw.s: New.
+ * gas/nios2/sub.d: New.
+ * gas/nios2/sub.s: New.
+ * gas/nios2/sync.d: New.
+ * gas/nios2/sync.s: New.
+ * gas/nios2/trap.d: New.
+ * gas/nios2/trap.s: New.
+ * gas/nios2/tret.d: New.
+ * gas/nios2/tret.s: New.
+ * gas/nios2/warn_noat.l: New.
+ * gas/nios2/warn_noat.s: New.
+ * gas/nios2/warn_nobreak.l: New.
+ * gas/nios2/warn_nobreak.s: New.
+ * gas/nios2/xor.d: New.
+ * gas/nios2/xor.s: New.
+
2013-01-31 Tristan Gingold <gingold@adacore.com>
* gas/ppc/test1xcoff32.d: Updated.
diff --git a/gas/testsuite/gas/nios2/add.d b/gas/testsuite/gas/nios2/add.d
new file mode 100644
index 0000000000..ba3d27fb18
--- /dev/null
+++ b/gas/testsuite/gas/nios2/add.d
@@ -0,0 +1,16 @@
+#objdump: -dr --prefix-addresses
+#name: NIOS2 add
+
+# Test the add instruction
+
+.*: +file format elf32-littlenios2
+
+Disassembly of section .text:
+0+0000 <[^>]*> add r4,r4,r4
+0+0004 <[^>]*> addi r4,r4,32767
+0+0008 <[^>]*> addi r4,r4,-32768
+0+000c <[^>]*> addi r4,r4,0
+0+0010 <[^>]*> addi r4,r4,-1
+0+0014 <[^>]*> addi r4,r4,-1
+0+0018 <[^>]*> addi r4,r4,13398
+0+001c <[^>]*> nop
diff --git a/gas/testsuite/gas/nios2/add.s b/gas/testsuite/gas/nios2/add.s
new file mode 100644
index 0000000000..5b72a82741
--- /dev/null
+++ b/gas/testsuite/gas/nios2/add.s
@@ -0,0 +1,13 @@
+# Source file used to test the add and addi instructions.
+
+foo:
+ add r4,r4,r4
+ addi r4,r4,0x7fff
+ addi r4,r4,-0x8000
+ addi r4,r4,0x0
+ addi r4,r4,-0x01
+ subi r4,r4,0x01
+ addi r4,r4,0x3456
+
+# should disassemble to add r0,0,r0
+ nop
diff --git a/gas/testsuite/gas/nios2/align_fill.d b/gas/testsuite/gas/nios2/align_fill.d
new file mode 100644
index 0000000000..90a9e5fbaa
--- /dev/null
+++ b/gas/testsuite/gas/nios2/align_fill.d
@@ -0,0 +1,23 @@
+#objdump: -dr --prefix-addresses
+#name: NIOS2 align_fill
+
+# Test the and macro.
+
+.*: +file format elf32-littlenios2
+
+Disassembly of section .text:
+0+0000 <[^>]*> addi sp,sp,-8
+0+0004 <[^>]*> stw fp,4\(sp\)
+0+0008 <[^>]*> mov fp,sp
+0+000c <[^>]*> mov r3,zero
+0+0010 <[^>]*> nop
+0+0014 <[^>]*> nop
+0+0018 <[^>]*> nop
+0+001c <[^>]*> nop
+0+0020 <[^>]*> addi r3,r3,1
+0+0024 <[^>]*> cmplti r2,r3,100
+0+0028 <[^>]*> bne r2,zero,0+0020 <[^>*]*>
+0+002c <[^>]*> ldw fp,4\(sp\)
+0+0030 <[^>]*> addi sp,sp,8
+0+0034 <[^>]*> ret
+ ...
diff --git a/gas/testsuite/gas/nios2/align_fill.s b/gas/testsuite/gas/nios2/align_fill.s
new file mode 100644
index 0000000000..5683839546
--- /dev/null
+++ b/gas/testsuite/gas/nios2/align_fill.s
@@ -0,0 +1,20 @@
+ .file "a.c"
+ .section .text
+ .align 3
+ .global x
+ .type x, @function
+x:
+ addi sp, sp, -8
+ stw fp, 4(sp)
+ mov fp, sp
+ mov r3, zero
+ .align 5
+.L6:
+ addi r3, r3, 1
+ cmplti r2, r3, 100
+ bne r2, zero, .L6
+ ldw fp, 4(sp)
+ addi sp, sp, 8
+ ret
+ .size x, .-x
+ .ident "GCC: (GNU) 3.3.3 (Altera Nios II 1.0 b302)"
diff --git a/gas/testsuite/gas/nios2/align_text.d b/gas/testsuite/gas/nios2/align_text.d
new file mode 100644
index 0000000000..80611e76c6
--- /dev/null
+++ b/gas/testsuite/gas/nios2/align_text.d
@@ -0,0 +1,22 @@
+#objdump: -dr
+#name: NIOS2 align_test
+
+# Test alignment in text sections.
+
+.*: +file format elf32-littlenios2
+
+Disassembly of section .text:
+00000000 <label-0x20>:
+ 0: 00000000 call 0 <label-0x20>
+ 4: 0001883a nop
+ 8: 0001883a nop
+ c: 0001883a nop
+ 10: 0001883a nop
+ 14: 0001883a nop
+ 18: 0001883a nop
+ 1c: 0001883a nop
+
+00000020 <label>:
+ 20: 0001883a nop
+00000024 <label2>:
+ ...
diff --git a/gas/testsuite/gas/nios2/align_text.s b/gas/testsuite/gas/nios2/align_text.s
new file mode 100644
index 0000000000..d073b6f279
--- /dev/null
+++ b/gas/testsuite/gas/nios2/align_text.s
@@ -0,0 +1,15 @@
+ .asciz "" # empty string
+ .align 2
+
+ nop
+ nop
+ label:
+ .align 5
+ nop
+ label2:
+ .section mysection
+ .align 2
+
+
+
+
diff --git a/gas/testsuite/gas/nios2/and.d b/gas/testsuite/gas/nios2/and.d
new file mode 100644
index 0000000000..350ca6921e
--- /dev/null
+++ b/gas/testsuite/gas/nios2/and.d
@@ -0,0 +1,17 @@
+#objdump: -dr --prefix-addresses
+#name: NIOS2 and
+
+# Test the and macro.
+
+.*: +file format elf32-littlenios2
+
+Disassembly of section .text:
+0+0000 <[^>]*> and r4,r4,r4
+0+0004 <[^>]*> andi r4,r4,32767
+0+0008 <[^>]*> andi r4,r4,32768
+0+000c <[^>]*> andi r4,r4,65535
+0+0010 <[^>]*> andi r4,r4,0
+0+0014 <[^>]*> andhi r4,r4,32767
+0+0018 <[^>]*> andhi r4,r4,32768
+0+001c <[^>]*> andhi r4,r4,65535
+0+0020 <[^>]*> andhi r4,r4,0
diff --git a/gas/testsuite/gas/nios2/and.s b/gas/testsuite/gas/nios2/and.s
new file mode 100644
index 0000000000..946a8b881a
--- /dev/null
+++ b/gas/testsuite/gas/nios2/and.s
@@ -0,0 +1,13 @@
+# Source file used to test the and, andhi and andi instructions
+
+foo:
+ and r4,r4,r4
+ andi r4,r4,0x7fff
+ andi r4,r4,0x8000
+ andi r4,r4,0xffff
+ andi r4,r4,0x0
+ andhi r4,r4,0x7fff
+ andhi r4,r4,0x8000
+ andhi r4,r4,0xffff
+ andhi r4,r4,0x0
+
diff --git a/gas/testsuite/gas/nios2/branch.d b/gas/testsuite/gas/nios2/branch.d
new file mode 100644
index 0000000000..08d20f356d
--- /dev/null
+++ b/gas/testsuite/gas/nios2/branch.d
@@ -0,0 +1,21 @@
+#objdump: -dr --prefix-addresses
+#name: NIOS2 branch
+
+# Test the branch instructions.
+dump.o: file format elf32-littlenios2
+
+Disassembly of section .text:
+0+0000 <[^>]*> beq r4,r5,00000004 <text_label\+0x4>
+[ ]*0: R_NIOS2_PCREL16 text_label
+0+0004 <[^>]*> bge r4,r5,00000008 <text_label\+0x8>
+[ ]*4: R_NIOS2_PCREL16 text_label
+0+0008 <[^>]*> bgeu r4,r5,0000000c <text_label\+0xc>
+[ ]*8: R_NIOS2_PCREL16 text_label
+0+000c <[^>]*> blt r4,r5,00000010 <text_label\+0x10>
+[ ]*c: R_NIOS2_PCREL16 text_label
+0+0010 <[^>]*> bltu r4,r5,00000014 <text_label\+0x14>
+[ ]*10: R_NIOS2_PCREL16 text_label
+0+0014 <[^>]*> bne r4,r5,00000018 <text_label\+0x18>
+[ ]*14: R_NIOS2_PCREL16 text_label
+0+0018 <[^>]*> br 0000001c <text_label\+0x1c>
+[ ]*18: R_NIOS2_PCREL16 external_label
diff --git a/gas/testsuite/gas/nios2/branch.s b/gas/testsuite/gas/nios2/branch.s
new file mode 100644
index 0000000000..0853167ee0
--- /dev/null
+++ b/gas/testsuite/gas/nios2/branch.s
@@ -0,0 +1,15 @@
+# Source file used to test the beq macro.
+ .globl text_label
+ .text
+.set norelax
+text_label:
+ beq r4,r5,text_label
+ bge r4,r5,text_label
+ bgeu r4,r5,text_label
+ blt r4,r5,text_label
+ bltu r4,r5,text_label
+ bne r4,r5,text_label
+
+# Branch to an external label.
+ br external_label
+
diff --git a/gas/testsuite/gas/nios2/break.d b/gas/testsuite/gas/nios2/break.d
new file mode 100644
index 0000000000..be487bb3d4
--- /dev/null
+++ b/gas/testsuite/gas/nios2/break.d
@@ -0,0 +1,12 @@
+#objdump: -dr --prefix-addresses
+#name: NIOS2 break
+
+.*: +file format elf32-littlenios2
+
+Disassembly of section .text:
+0+0000 <[^>]*> break 0
+0+0004 <[^>]*> break 0
+0+0008 <[^>]*> break 31
+0+000c <[^>]*> break 14
+
+
diff --git a/gas/testsuite/gas/nios2/break.s b/gas/testsuite/gas/nios2/break.s
new file mode 100644
index 0000000000..88d3422e74
--- /dev/null
+++ b/gas/testsuite/gas/nios2/break.s
@@ -0,0 +1,8 @@
+# Source file used to test the 20-bit break instructions
+foo:
+ break
+ break 0
+ break 31
+ break 14
+
+
diff --git a/gas/testsuite/gas/nios2/bret.d b/gas/testsuite/gas/nios2/bret.d
new file mode 100644
index 0000000000..a12530b5f6
--- /dev/null
+++ b/gas/testsuite/gas/nios2/bret.d
@@ -0,0 +1,8 @@
+#objdump: -dr --prefix-addresses
+#name: NIOS2 bret
+
+.*: +file format elf32-littlenios2
+
+Disassembly of section .text:
+0+0000 <[^>]*> bret
+
diff --git a/gas/testsuite/gas/nios2/bret.s b/gas/testsuite/gas/nios2/bret.s
new file mode 100644
index 0000000000..d368e6441e
--- /dev/null
+++ b/gas/testsuite/gas/nios2/bret.s
@@ -0,0 +1,5 @@
+# Source file used to test the bret instructions
+foo:
+ bret
+
+
diff --git a/gas/testsuite/gas/nios2/cache.d b/gas/testsuite/gas/nios2/cache.d
new file mode 100644
index 0000000000..7c278d8db3
--- /dev/null
+++ b/gas/testsuite/gas/nios2/cache.d
@@ -0,0 +1,17 @@
+#objdump: -dr --prefix-addresses
+#name: NIOS2 cache
+
+.*: +file format elf32-littlenios2
+
+Disassembly of section .text:
+0+0000 <[^>]*> flushd -32768\(r6\)
+0+0004 <[^>]*> flushd 32767\(r6\)
+0+0008 <[^>]*> flushd 0\(r6\)
+0+000c <[^>]*> flushd -1\(r6\)
+0+0010 <[^>]*> flushd 0\(r6\)
+[ ]*10: R_NIOS2_S16 .text
+0+0014 <[^>]*> flushd 0\(r6\)
+[ ]*14: R_NIOS2_S16 external
+0+0018 <[^>]*> flushi r2
+0+001c <[^>]*> flushp
+
diff --git a/gas/testsuite/gas/nios2/cache.s b/gas/testsuite/gas/nios2/cache.s
new file mode 100644
index 0000000000..1701c191bc
--- /dev/null
+++ b/gas/testsuite/gas/nios2/cache.s
@@ -0,0 +1,21 @@
+# Source file used to test the cache instruction
+foo:
+ flushd -0x8000(r6)
+ flushd 0x7fff(r6)
+ flushd 0x0(r6)
+ flushd -0x0001(r6)
+
+# use symbol for offset
+ flushd foo(r6)
+
+# use external symbol
+ .global external
+ flushd external(r6)
+
+# flushi
+ flushi r2
+
+#flushp
+ flushp
+
+
diff --git a/gas/testsuite/gas/nios2/call.d b/gas/testsuite/gas/nios2/call.d
new file mode 100644
index 0000000000..cfa6aec905
--- /dev/null
+++ b/gas/testsuite/gas/nios2/call.d
@@ -0,0 +1,11 @@
+# objdump: -dr --prefix-addresses
+#name: NIOS2 call
+
+.*: +file format elf32-littlenios2
+
+Disassembly of section .text:
+0+0000 <[^>]*> call 00000000 <foo>
+[ ]*0: R_NIOS2_CALL26 .text\+0xc
+0+0004 <[^>]*> callr r10
+0+0008 <[^>]*> call 00000000 <foo>
+[ ]*8: R_NIOS2_CALL26 external
diff --git a/gas/testsuite/gas/nios2/call.s b/gas/testsuite/gas/nios2/call.s
new file mode 100644
index 0000000000..39409b7de0
--- /dev/null
+++ b/gas/testsuite/gas/nios2/call.s
@@ -0,0 +1,13 @@
+# Source file used to test the call and callr instructions
+.text
+.set norelax
+foo:
+ call func1
+ callr r10
+# use external symbol
+ .global external
+ call external
+func1:
+
+
+
diff --git a/gas/testsuite/gas/nios2/call26.d b/gas/testsuite/gas/nios2/call26.d
new file mode 100644
index 0000000000..63364ef670
--- /dev/null
+++ b/gas/testsuite/gas/nios2/call26.d
@@ -0,0 +1,76 @@
+#objdump: -dr --prefix-addresses
+#name: NIOS2 nios2-reloc-r-nios2-call26
+
+# Test the branch instructions.
+.*: +file format elf32-littlenios2
+
+Disassembly of section .text:
+[ ]*\.\.\.
+[ ]*0: R_NIOS2_CALL26 .text\+0x100
+[ ]*4: R_NIOS2_CALL26 globalfunc
+0+0008 <[^>]*> nop
+0+000c <[^>]*> nop
+0+0010 <[^>]*> nop
+0+0014 <[^>]*> nop
+0+0018 <[^>]*> nop
+0+001c <[^>]*> nop
+0+0020 <[^>]*> nop
+0+0024 <[^>]*> nop
+0+0028 <[^>]*> nop
+0+002c <[^>]*> nop
+0+0030 <[^>]*> nop
+0+0034 <[^>]*> nop
+0+0038 <[^>]*> nop
+0+003c <[^>]*> nop
+0+0040 <[^>]*> nop
+0+0044 <[^>]*> nop
+0+0048 <[^>]*> nop
+0+004c <[^>]*> nop
+0+0050 <[^>]*> nop
+0+0054 <[^>]*> nop
+0+0058 <[^>]*> nop
+0+005c <[^>]*> nop
+0+0060 <[^>]*> nop
+0+0064 <[^>]*> nop
+0+0068 <[^>]*> nop
+0+006c <[^>]*> nop
+0+0070 <[^>]*> nop
+0+0074 <[^>]*> nop
+0+0078 <[^>]*> nop
+0+007c <[^>]*> nop
+0+0080 <[^>]*> nop
+0+0084 <[^>]*> nop
+0+0088 <[^>]*> nop
+0+008c <[^>]*> nop
+0+0090 <[^>]*> nop
+0+0094 <[^>]*> nop
+0+0098 <[^>]*> nop
+0+009c <[^>]*> nop
+0+00a0 <[^>]*> nop
+0+00a4 <[^>]*> nop
+0+00a8 <[^>]*> nop
+0+00ac <[^>]*> nop
+0+00b0 <[^>]*> nop
+0+00b4 <[^>]*> nop
+0+00b8 <[^>]*> nop
+0+00bc <[^>]*> nop
+0+00c0 <[^>]*> nop
+0+00c4 <[^>]*> nop
+0+00c8 <[^>]*> nop
+0+00cc <[^>]*> nop
+0+00d0 <[^>]*> nop
+0+00d4 <[^>]*> nop
+0+00d8 <[^>]*> nop
+0+00dc <[^>]*> nop
+0+00e0 <[^>]*> nop
+0+00e4 <[^>]*> nop
+0+00e8 <[^>]*> nop
+0+00ec <[^>]*> nop
+0+00f0 <[^>]*> nop
+0+00f4 <[^>]*> nop
+0+00f8 <[^>]*> nop
+0+00fc <[^>]*> nop
+0+0100 <[^>]*> nop
+ ...
+
+
diff --git a/gas/testsuite/gas/nios2/call26.s b/gas/testsuite/gas/nios2/call26.s
new file mode 100644
index 0000000000..dd128a7030
--- /dev/null
+++ b/gas/testsuite/gas/nios2/call26.s
@@ -0,0 +1,12 @@
+# Test for Nios II 32-bit relocations
+
+.global globalfunc
+.text
+.set norelax
+start:
+ call localfunc
+ call globalfunc
+
+.align 8
+localfunc:
+ nop
diff --git a/gas/testsuite/gas/nios2/cmp.d b/gas/testsuite/gas/nios2/cmp.d
new file mode 100644
index 0000000000..43d9d68c85
--- /dev/null
+++ b/gas/testsuite/gas/nios2/cmp.d
@@ -0,0 +1,24 @@
+#objdump: -dr --prefix-addresses
+#name: NIOS2 cmp
+
+.*: +file format elf32-littlenios2
+
+Disassembly of section .text:
+0+0000 <[^>]*> cmpeq r11,r2,r3
+0+0004 <[^>]*> cmpge r11,r2,r3
+0+0008 <[^>]*> cmpgeu r11,r2,r3
+0+000c <[^>]*> cmplt r11,r2,r3
+0+0010 <[^>]*> cmpltu r11,r2,r3
+0+0014 <[^>]*> cmpne r11,r2,r3
+0+0018 <[^>]*> cmpgei r11,r2,0
+[ ]*18: R_NIOS2_S16 value
+0+001c <[^>]*> cmpgeui r11,r2,0
+[ ]*1c: R_NIOS2_U16 value\+0x200
+0+0020 <[^>]*> cmplti r11,r2,0
+[ ]*20: R_NIOS2_S16 value
+0+0024 <[^>]*> cmpltui r11,r2,0
+[ ]*24: R_NIOS2_U16 value\+0x200
+0+0028 <[^>]*> cmpgei r11,r2,32767
+0+002c <[^>]*> cmpgeui r11,r2,32768
+0+0030 <[^>]*> cmplti r11,r2,-32768
+0+0034 <[^>]*> cmpltui r11,r2,65535
diff --git a/gas/testsuite/gas/nios2/cmp.s b/gas/testsuite/gas/nios2/cmp.s
new file mode 100644
index 0000000000..6f7c15b443
--- /dev/null
+++ b/gas/testsuite/gas/nios2/cmp.s
@@ -0,0 +1,22 @@
+# Source file used to test the compare instructions
+foo:
+ cmpeq r11,r2,r3
+ cmpge r11,r2,r3
+ cmpgeu r11,r2,r3
+ cmplt r11,r2,r3
+ cmpltu r11,r2,r3
+ cmpne r11,r2,r3
+# test that cmp generates relocations correctly
+ cmpgei r11,r2,value
+ cmpgeui r11,r2,value+0x200
+ cmplti r11,r2,value
+ cmpltui r11,r2,value+0x200
+
+ cmpgei r11,r2,0x7fff
+ cmpgeui r11,r2,0x8000
+ cmplti r11,r2,-0x8000
+ cmpltui r11,r2,0xFFFF
+.global value
+
+
+
diff --git a/gas/testsuite/gas/nios2/comments.d b/gas/testsuite/gas/nios2/comments.d
new file mode 100644
index 0000000000..890dcc20db
--- /dev/null
+++ b/gas/testsuite/gas/nios2/comments.d
@@ -0,0 +1,26 @@
+#objdump: -dr --prefix-addresses
+#name: NIOS2 comments
+
+# Test the add instruction
+
+.*: +file format elf32-littlenios2
+
+Disassembly of section .text:
+0+0000 <[^>]*> br 0000001c <start>
+0+0004 <[^>]*> br 00000008 <abort>
+0+0008 <[^>]*> movui r3,0
+0+000c <[^>]*> movui r2,1
+0+0010 <[^>]*> movui r3,0
+0+0014 <[^>]*> movui r2,0
+0+0018 <[^>]*> br 00000044 <exit>
+0+001c <[^>]*> addi r2,r2,-4
+0+0020 <[^>]*> movui r11,1
+0+0024 <[^>]*> movui r5,0
+0+0028 <[^>]*> movui r6,0
+0+002c <[^>]*> br 00000030 <ldst>
+0+0030 <[^>]*> movui r2,61452
+0+0034 <[^>]*> movui r20,64206
+0+0038 <[^>]*> stw r20,0\(r2\)
+0+003c <[^>]*> ldw r21,0\(r2\)
+0+0040 <[^>]*> br 00000010 <end>
+0+0044 <[^>]*> br 00000044 <exit>
diff --git a/gas/testsuite/gas/nios2/comments.s b/gas/testsuite/gas/nios2/comments.s
new file mode 100644
index 0000000000..7ab2027829
--- /dev/null
+++ b/gas/testsuite/gas/nios2/comments.s
@@ -0,0 +1,28 @@
+.set norelax
+_main: br start
+trap:
+ br abort
+.globl _main
+abort: movui r3, 0x0
+ movui r2, 0x1
+
+end: movui r3, 0x0
+ movui r2, 0x0
+ br exit
+
+start:
+ addi r2, r2, -4 # test for ve numbers
+ movui r11, 0x1
+ ori r5, r0, %lo(0x0) # r5 = 0x0
+ ori r6, r0, %lo(0x0) # r6 = 0x0
+ br ldst
+
+ldst:
+ movui r2, 0xF00C
+ movui r20, 0xFACE
+ stw r20,(r2)
+ ldw r21, (r2)
+ br end
+
+
+exit: br exit
diff --git a/gas/testsuite/gas/nios2/complex.d b/gas/testsuite/gas/nios2/complex.d
new file mode 100644
index 0000000000..f32115b546
--- /dev/null
+++ b/gas/testsuite/gas/nios2/complex.d
@@ -0,0 +1,12 @@
+#objdump: -dr --prefix-addresses
+#name: NIOS2 complex
+
+# Test complex expression parsing
+
+.*: +file format elf32-littlenios2
+
+Disassembly of section .text:
+0+0000 <[^>]*> ldw r2,-1\(r3\)
+0+0004 <[^>]*> ldw r2,1\(r3\)
+0+0008 <[^>]*> ldw r2,0\(r3\)
+ 8: R_NIOS2_S16 stack_top-0x1
diff --git a/gas/testsuite/gas/nios2/complex.s b/gas/testsuite/gas/nios2/complex.s
new file mode 100644
index 0000000000..65141f9d62
--- /dev/null
+++ b/gas/testsuite/gas/nios2/complex.s
@@ -0,0 +1,5 @@
+foo:
+ ldw r2, (2-3)(r3)
+ ldw r2, 2 + (2-3)(r3)
+ ldw r2, 2 + (stack_top-3)(r3)
+
diff --git a/gas/testsuite/gas/nios2/ctl.d b/gas/testsuite/gas/nios2/ctl.d
new file mode 100644
index 0000000000..f698ce60be
--- /dev/null
+++ b/gas/testsuite/gas/nios2/ctl.d
@@ -0,0 +1,20 @@
+#objdump: -dr --prefix-addresses
+#name: NIOS2 ctl
+
+# Test the ctl instructions
+
+.*: +file format elf32-littlenios2
+
+Disassembly of section .text:
+0+0000 <[^>]*> rdctl r8,ctl31
+0+0004 <[^>]*> rdctl r8,ctl30
+0+0008 <[^>]*> rdctl r8,ctl29
+0+000c <[^>]*> rdctl r8,status
+0+0010 <[^>]*> rdctl r8,bstatus
+0+0014 <[^>]*> rdctl r8,estatus
+0+0018 <[^>]*> wrctl ctl31,r8
+0+001c <[^>]*> wrctl ctl30,r8
+0+0020 <[^>]*> wrctl ctl29,r8
+0+0024 <[^>]*> wrctl status,r8
+0+0028 <[^>]*> wrctl bstatus,r8
+0+002c <[^>]*> wrctl estatus,r8
diff --git a/gas/testsuite/gas/nios2/ctl.s b/gas/testsuite/gas/nios2/ctl.s
new file mode 100644
index 0000000000..dc6c98399c
--- /dev/null
+++ b/gas/testsuite/gas/nios2/ctl.s
@@ -0,0 +1,18 @@
+# Source file used to test the nor instruction
+
+foo:
+ rdctl r8,ctl31
+ rdctl r8,ctl30
+ rdctl r8,ctl29
+ rdctl r8,status
+ rdctl r8,bstatus
+ rdctl r8,estatus
+ wrctl ctl31,r8
+ wrctl ctl30,r8
+ wrctl ctl29,r8
+ wrctl status,r8
+ wrctl bstatus,r8
+ wrctl estatus,r8
+
+
+
diff --git a/gas/testsuite/gas/nios2/custom.d b/gas/testsuite/gas/nios2/custom.d
new file mode 100644
index 0000000000..c1e17beae9
--- /dev/null
+++ b/gas/testsuite/gas/nios2/custom.d
@@ -0,0 +1,13 @@
+#objdump: -dr --prefix-addresses
+#name: NIOS2 custom
+
+# Test the custom instruction
+
+.*: +file format elf32-littlenios2
+
+Disassembly of section .text:
+0+0000 <[^>]*> custom 0,r11,r2,r3
+0+0004 <[^>]*> custom 255,r11,r2,r3
+0+0008 <[^>]*> custom 150,c1,r2,r3
+0+000c <[^>]*> custom 24,c1,c2,r3
+0+0010 <[^>]*> custom 56,c1,c2,c3
diff --git a/gas/testsuite/gas/nios2/custom.s b/gas/testsuite/gas/nios2/custom.s
new file mode 100644
index 0000000000..903122ab45
--- /dev/null
+++ b/gas/testsuite/gas/nios2/custom.s
@@ -0,0 +1,8 @@
+# test progam for assembling user instructions
+
+foo:
+ custom 0, r11, r2, r3
+ custom 255, r11, r2, r3
+ custom 150, c1, r2, r3
+ custom 0x18, c1, c2, r3
+ custom 070, c1, c2, c3
diff --git a/gas/testsuite/gas/nios2/etbt.d b/gas/testsuite/gas/nios2/etbt.d
new file mode 100644
index 0000000000..58b8e32639
--- /dev/null
+++ b/gas/testsuite/gas/nios2/etbt.d
@@ -0,0 +1,10 @@
+#objdump: -dr --prefix-addresses
+#name: NIOS2 etbt
+
+# Test the et, bt registers
+
+.*: +file format elf32-littlenios2
+
+Disassembly of section .text:
+0+0000 <[^>]*> add et,bt,r6
+0+0004 <[^>]*> add et,bt,r6
diff --git a/gas/testsuite/gas/nios2/etbt.s b/gas/testsuite/gas/nios2/etbt.s
new file mode 100644
index 0000000000..3e5fc24a3e
--- /dev/null
+++ b/gas/testsuite/gas/nios2/etbt.s
@@ -0,0 +1,4 @@
+.set nobreak
+foo:
+ add r24, r25, r6
+ add et, bt, r6
diff --git a/gas/testsuite/gas/nios2/flushda.d b/gas/testsuite/gas/nios2/flushda.d
new file mode 100644
index 0000000000..f3b5e3ef56
--- /dev/null
+++ b/gas/testsuite/gas/nios2/flushda.d
@@ -0,0 +1,10 @@
+#objdump: -dr --prefix-addresses
+#name: NIOS2 flushda
+
+# Test the jmp instruction.
+
+.*: +file format elf32-littlenios2
+
+Disassembly of section .text:
+0+0000 <[^>]*> flushda 12\(r2\)
+
diff --git a/gas/testsuite/gas/nios2/flushda.s b/gas/testsuite/gas/nios2/flushda.s
new file mode 100644
index 0000000000..3a3247484b
--- /dev/null
+++ b/gas/testsuite/gas/nios2/flushda.s
@@ -0,0 +1,6 @@
+# Source file used to test the flushda instruction.
+.text
+.set nobreak
+foo:
+ flushda 12(r2)
+
diff --git a/gas/testsuite/gas/nios2/illegal.l b/gas/testsuite/gas/nios2/illegal.l
new file mode 100644
index 0000000000..6248567b95
--- /dev/null
+++ b/gas/testsuite/gas/nios2/illegal.l
@@ -0,0 +1,14 @@
+.*illegal.s: Assembler messages:
+.*illegal.s:5: Error: unknown register r56
+.*illegal.s:8: Error: expecting \( near 0x1000
+.*illegal.s:8: Error: missing argument
+.*illegal.s:9: Error: expecting \) near r5
+.*illegal.s:10: Error: expecting \( near 0x1000r5\)
+.*illegal.s:10: Error: missing argument
+.*illegal.s:11: Error: expecting \( near 0x1000,r5
+.*illegal.s:11: Error: missing argument
+.*illegal.s:12: Error: unknown register 0x1000
+.*illegal.s:14: Error: unrecognised instruction fop
+.*illegal.s:16: Error: too many arguments
+.*illegal.s:17: Error: too many arguments
+.*illegal.s:17: Error: unknown register r2,r4
diff --git a/gas/testsuite/gas/nios2/illegal.s b/gas/testsuite/gas/nios2/illegal.s
new file mode 100644
index 0000000000..75b6d89f20
--- /dev/null
+++ b/gas/testsuite/gas/nios2/illegal.s
@@ -0,0 +1,17 @@
+# Source file used to test illegal operands.
+
+foo:
+# Illegal registers
+ add r3,r4,r56
+ add r4,r0,r2
+# Illegal syntax
+ ldw r4,0x1000
+ ldw r4,0x1000(r5
+ ldw r4,0x1000r5)
+ ldw r4,0x1000,r5
+ ldw r4,(0x1000)r5
+# Illegal opcodes
+ fop r3,r4,r5
+# Extra operands
+ nop Crapola
+ add r2, r2, r2, r4
diff --git a/gas/testsuite/gas/nios2/jmp.d b/gas/testsuite/gas/nios2/jmp.d
new file mode 100644
index 0000000000..b8727b3140
--- /dev/null
+++ b/gas/testsuite/gas/nios2/jmp.d
@@ -0,0 +1,10 @@
+#objdump: -dr --prefix-addresses
+#name: NIOS2 jmp
+
+# Test the jmp instruction.
+
+.*: +file format elf32-littlenios2
+
+Disassembly of section .text:
+0+0000 <[^>]*> jmp bt
+
diff --git a/gas/testsuite/gas/nios2/jmp.s b/gas/testsuite/gas/nios2/jmp.s
new file mode 100644
index 0000000000..8d859f2b6c
--- /dev/null
+++ b/gas/testsuite/gas/nios2/jmp.s
@@ -0,0 +1,6 @@
+# Source file used to test the jmp instruction.
+.text
+.set nobreak
+foo:
+ jmp r25
+
diff --git a/gas/testsuite/gas/nios2/ldb.d b/gas/testsuite/gas/nios2/ldb.d
new file mode 100644
index 0000000000..5a417b814e
--- /dev/null
+++ b/gas/testsuite/gas/nios2/ldb.d
@@ -0,0 +1,196 @@
+#objdump: -dr --prefix-addresses
+#name: NIOS2 ldb
+
+# Test the ld instruction
+
+.*: +file format elf32-littlenios2
+
+Disassembly of section .text:
+0+0000 <[^>]*> ldb r4,0\(zero\)
+0+0004 <[^>]*> ldb r4,4\(zero\)
+0+0008 <[^>]*> ldb r4,32764\(zero\)
+0+000c <[^>]*> ldb r4,-32768\(zero\)
+0+0010 <[^>]*> ldb r4,0\(r5\)
+0+0014 <[^>]*> ldb r4,4\(r5\)
+0+0018 <[^>]*> ldb r4,32764\(r5\)
+0+001c <[^>]*> ldb r4,-32768\(r5\)
+0+0020 <[^>]*> ldb r4,0\(zero\)
+[ ]*20: R_NIOS2_S16 .data
+0+0024 <[^>]*> ldb r4,0\(zero\)
+[ ]*24: R_NIOS2_S16 big_external_data_label
+0+0028 <[^>]*> ldb r4,0\(zero\)
+[ ]*28: R_NIOS2_S16 small_external_data_label
+0+002c <[^>]*> ldb r4,0\(zero\)
+[ ]*2c: R_NIOS2_S16 big_external_common
+0+0030 <[^>]*> ldb r4,0\(zero\)
+[ ]*30: R_NIOS2_S16 small_external_common
+0+0034 <[^>]*> ldb r4,0\(zero\)
+[ ]*34: R_NIOS2_S16 .bss
+0+0038 <[^>]*> ldb r4,0\(zero\)
+[ ]*38: R_NIOS2_S16 .bss\+0x4000
+0+003c <[^>]*> ldb r4,0\(zero\)
+[ ]*3c: R_NIOS2_S16 .data\+0x4
+0+0040 <[^>]*> ldb r4,0\(zero\)
+[ ]*40: R_NIOS2_S16 big_external_data_label\+0x4
+0+0044 <[^>]*> ldb r4,0\(zero\)
+[ ]*44: R_NIOS2_S16 small_external_data_label\+0x4
+0+0048 <[^>]*> ldb r4,0\(zero\)
+[ ]*48: R_NIOS2_S16 big_external_common\+0x4
+0+004c <[^>]*> ldb r4,0\(zero\)
+[ ]*4c: R_NIOS2_S16 small_external_common\+0x4
+0+0050 <[^>]*> ldb r4,0\(zero\)
+[ ]*50: R_NIOS2_S16 .bss\+0x4
+0+0054 <[^>]*> ldb r4,0\(zero\)
+[ ]*54: R_NIOS2_S16 .bss\+0x4004
+0+0058 <[^>]*> ldb r4,0\(zero\)
+[ ]*58: R_NIOS2_S16 .data-0x8000
+0+005c <[^>]*> ldb r4,0\(zero\)
+[ ]*5c: R_NIOS2_S16 big_external_data_label-0x8000
+0+0060 <[^>]*> ldb r4,0\(zero\)
+[ ]*60: R_NIOS2_S16 small_external_data_label-0x8000
+0+0064 <[^>]*> ldb r4,0\(zero\)
+[ ]*64: R_NIOS2_S16 big_external_common-0x8000
+0+0068 <[^>]*> ldb r4,0\(zero\)
+[ ]*68: R_NIOS2_S16 small_external_common-0x8000
+0+006c <[^>]*> ldb r4,0\(zero\)
+[ ]*6c: R_NIOS2_S16 .bss-0x8000
+0+0070 <[^>]*> ldb r4,0\(zero\)
+[ ]*70: R_NIOS2_S16 .bss-0x4000
+0+0074 <[^>]*> ldb r4,0\(zero\)
+[ ]*74: R_NIOS2_S16 .data\+0x10000
+0+0078 <[^>]*> ldb r4,0\(r5\)
+[ ]*78: R_NIOS2_S16 .data
+0+007c <[^>]*> ldb r4,0\(r5\)
+[ ]*7c: R_NIOS2_S16 big_external_data_label
+0+0080 <[^>]*> ldb r4,0\(r5\)
+[ ]*80: R_NIOS2_S16 small_external_data_label
+0+0084 <[^>]*> ldb r4,0\(r5\)
+[ ]*84: R_NIOS2_S16 big_external_common
+0+0088 <[^>]*> ldb r4,0\(r5\)
+[ ]*88: R_NIOS2_S16 small_external_common
+0+008c <[^>]*> ldb r4,0\(r5\)
+[ ]*8c: R_NIOS2_S16 .bss
+0+0090 <[^>]*> ldb r4,0\(r5\)
+[ ]*90: R_NIOS2_S16 .bss\+0x4000
+0+0094 <[^>]*> ldb r4,0\(r5\)
+[ ]*94: R_NIOS2_S16 .data\+0x4
+0+0098 <[^>]*> ldb r4,0\(r5\)
+[ ]*98: R_NIOS2_S16 big_external_data_label\+0x4
+0+009c <[^>]*> ldb r4,0\(r5\)
+[ ]*9c: R_NIOS2_S16 small_external_data_label\+0x4
+0+00a0 <[^>]*> ldb r4,0\(r5\)
+[ ]*a0: R_NIOS2_S16 big_external_common\+0x4
+0+00a4 <[^>]*> ldb r4,0\(r5\)
+[ ]*a4: R_NIOS2_S16 small_external_common\+0x4
+0+00a8 <[^>]*> ldb r4,0\(r5\)
+[ ]*a8: R_NIOS2_S16 .bss\+0x4
+0+00ac <[^>]*> ldb r4,0\(r5\)
+[ ]*ac: R_NIOS2_S16 .bss\+0x4004
+0+00b0 <[^>]*> ldb r4,0\(r5\)
+[ ]*b0: R_NIOS2_S16 .data-0x8000
+0+00b4 <[^>]*> ldb r4,0\(r5\)
+[ ]*b4: R_NIOS2_S16 big_external_data_label-0x8000
+0+00b8 <[^>]*> ldb r4,0\(r5\)
+[ ]*b8: R_NIOS2_S16 small_external_data_label-0x8000
+0+00bc <[^>]*> ldb r4,0\(r5\)
+[ ]*bc: R_NIOS2_S16 big_external_common-0x8000
+0+00c0 <[^>]*> ldb r4,0\(r5\)
+[ ]*c0: R_NIOS2_S16 small_external_common-0x8000
+0+00c4 <[^>]*> ldb r4,0\(r5\)
+[ ]*c4: R_NIOS2_S16 .bss-0x8000
+0+00c8 <[^>]*> ldb r4,0\(r5\)
+[ ]*c8: R_NIOS2_S16 .bss-0x4000
+0+00cc <[^>]*> ldbio r4,0\(zero\)
+0+00d0 <[^>]*> ldbio r4,4\(zero\)
+0+00d4 <[^>]*> ldbio r4,32764\(zero\)
+0+00d8 <[^>]*> ldbio r4,-32768\(zero\)
+0+00dc <[^>]*> ldbio r4,0\(r5\)
+0+00e0 <[^>]*> ldbio r4,4\(r5\)
+0+00e4 <[^>]*> ldbio r4,32764\(r5\)
+0+00e8 <[^>]*> ldbio r4,-32768\(r5\)
+0+00ec <[^>]*> ldbio r4,0\(zero\)
+[ ]*ec: R_NIOS2_S16 .data
+0+00f0 <[^>]*> ldbio r4,0\(zero\)
+[ ]*f0: R_NIOS2_S16 big_external_data_label
+0+00f4 <[^>]*> ldbio r4,0\(zero\)
+[ ]*f4: R_NIOS2_S16 small_external_data_label
+0+00f8 <[^>]*> ldbio r4,0\(zero\)
+[ ]*f8: R_NIOS2_S16 big_external_common
+0+00fc <[^>]*> ldbio r4,0\(zero\)
+[ ]*fc: R_NIOS2_S16 small_external_common
+0+0100 <[^>]*> ldbio r4,0\(zero\)
+[ ]*100: R_NIOS2_S16 .bss
+0+0104 <[^>]*> ldbio r4,0\(zero\)
+[ ]*104: R_NIOS2_S16 .bss\+0x4000
+0+0108 <[^>]*> ldbio r4,0\(zero\)
+[ ]*108: R_NIOS2_S16 .data\+0x4
+0+010c <[^>]*> ldbio r4,0\(zero\)
+[ ]*10c: R_NIOS2_S16 big_external_data_label\+0x4
+0+0110 <[^>]*> ldbio r4,0\(zero\)
+[ ]*110: R_NIOS2_S16 small_external_data_label\+0x4
+0+0114 <[^>]*> ldbio r4,0\(zero\)
+[ ]*114: R_NIOS2_S16 big_external_common\+0x4
+0+0118 <[^>]*> ldbio r4,0\(zero\)
+[ ]*118: R_NIOS2_S16 small_external_common\+0x4
+0+011c <[^>]*> ldbio r4,0\(zero\)
+[ ]*11c: R_NIOS2_S16 .bss\+0x4
+0+0120 <[^>]*> ldbio r4,0\(zero\)
+[ ]*120: R_NIOS2_S16 .bss\+0x4004
+0+0124 <[^>]*> ldbio r4,0\(zero\)
+[ ]*124: R_NIOS2_S16 .data-0x8000
+0+0128 <[^>]*> ldbio r4,0\(zero\)
+[ ]*128: R_NIOS2_S16 big_external_data_label-0x8000
+0+012c <[^>]*> ldbio r4,0\(zero\)
+[ ]*12c: R_NIOS2_S16 small_external_data_label-0x8000
+0+0130 <[^>]*> ldbio r4,0\(zero\)
+[ ]*130: R_NIOS2_S16 big_external_common-0x8000
+0+0134 <[^>]*> ldbio r4,0\(zero\)
+[ ]*134: R_NIOS2_S16 small_external_common-0x8000
+0+0138 <[^>]*> ldbio r4,0\(zero\)
+[ ]*138: R_NIOS2_S16 .bss-0x8000
+0+013c <[^>]*> ldbio r4,0\(zero\)
+[ ]*13c: R_NIOS2_S16 .bss-0x4000
+0+0140 <[^>]*> ldbio r4,0\(zero\)
+[ ]*140: R_NIOS2_S16 .data\+0x10000
+0+0144 <[^>]*> ldbio r4,0\(r5\)
+[ ]*144: R_NIOS2_S16 .data
+0+0148 <[^>]*> ldbio r4,0\(r5\)
+[ ]*148: R_NIOS2_S16 big_external_data_label
+0+014c <[^>]*> ldbio r4,0\(r5\)
+[ ]*14c: R_NIOS2_S16 small_external_data_label
+0+0150 <[^>]*> ldbio r4,0\(r5\)
+[ ]*150: R_NIOS2_S16 big_external_common
+0+0154 <[^>]*> ldbio r4,0\(r5\)
+[ ]*154: R_NIOS2_S16 small_external_common
+0+0158 <[^>]*> ldbio r4,0\(r5\)
+[ ]*158: R_NIOS2_S16 .bss
+0+015c <[^>]*> ldbio r4,0\(r5\)
+[ ]*15c: R_NIOS2_S16 .bss\+0x4000
+0+0160 <[^>]*> ldbio r4,0\(r5\)
+[ ]*160: R_NIOS2_S16 .data\+0x4
+0+0164 <[^>]*> ldbio r4,0\(r5\)
+[ ]*164: R_NIOS2_S16 big_external_data_label\+0x4
+0+0168 <[^>]*> ldbio r4,0\(r5\)
+[ ]*168: R_NIOS2_S16 small_external_data_label\+0x4
+0+016c <[^>]*> ldbio r4,0\(r5\)
+[ ]*16c: R_NIOS2_S16 big_external_common\+0x4
+0+0170 <[^>]*> ldbio r4,0\(r5\)
+[ ]*170: R_NIOS2_S16 small_external_common\+0x4
+0+0174 <[^>]*> ldbio r4,0\(r5\)
+[ ]*174: R_NIOS2_S16 .bss\+0x4
+0+0178 <[^>]*> ldbio r4,0\(r5\)
+[ ]*178: R_NIOS2_S16 .bss\+0x4004
+0+017c <[^>]*> ldbio r4,0\(r5\)
+[ ]*17c: R_NIOS2_S16 .data-0x8000
+0+0180 <[^>]*> ldbio r4,0\(r5\)
+[ ]*180: R_NIOS2_S16 big_external_data_label-0x8000
+0+0184 <[^>]*> ldbio r4,0\(r5\)
+[ ]*184: R_NIOS2_S16 small_external_data_label-0x8000
+0+0188 <[^>]*> ldbio r4,0\(r5\)
+[ ]*188: R_NIOS2_S16 big_external_common-0x8000
+0+018c <[^>]*> ldbio r4,0\(r5\)
+[ ]*18c: R_NIOS2_S16 small_external_common-0x8000
+0+0190 <[^>]*> ldbio r4,0\(r5\)
+[ ]*190: R_NIOS2_S16 .bss-0x8000
+0+0194 <[^>]*> ldbio r4,0\(r5\)
+[ ]*194: R_NIOS2_S16 .bss-0x4000
diff --git a/gas/testsuite/gas/nios2/ldb.s b/gas/testsuite/gas/nios2/ldb.s
new file mode 100644
index 0000000000..71c51f1857
--- /dev/null
+++ b/gas/testsuite/gas/nios2/ldb.s
@@ -0,0 +1,117 @@
+ .data
+data_label:
+ .extern big_external_data_label,0x4000
+ .extern small_external_data_label,4
+ .comm big_external_common,0x4000
+ .comm small_external_common,4
+ .lcomm big_local_common,0x4000
+ .lcomm small_local_common,4
+
+# the small symbols should have space allocated in the sbss section
+# but this is not yet supported in the assembler, so space is allocated
+# in the .bss section and the relocations are not gp-relative. this will
+# be updated when gp-relative relocations are added
+ .text
+ ldb r4,0(r0)
+ ldb r4,4(r0)
+ ldb r4,0x7ffc(r0)
+ ldb r4,-0x8000(r0)
+ ldb r4,0(r5)
+ ldb r4,4(r5)
+ ldb r4,0x7ffc(r5)
+ ldb r4,-0x8000(r5)
+ ldb r4,data_label(r0)
+ ldb r4,big_external_data_label(r0)
+ ldb r4,small_external_data_label(r0)
+ ldb r4,big_external_common(r0)
+ ldb r4,small_external_common(r0)
+ ldb r4,big_local_common(r0)
+ ldb r4,small_local_common(r0)
+ ldb r4,data_label+4(r0)
+ ldb r4,big_external_data_label+4(r0)
+ ldb r4,small_external_data_label+4(r0)
+ ldb r4,big_external_common+4(r0)
+ ldb r4,small_external_common+4(r0)
+ ldb r4,big_local_common+4(r0)
+ ldb r4,small_local_common+4(r0)
+ ldb r4,data_label-0x8000(r0)
+ ldb r4,big_external_data_label-0x8000(r0)
+ ldb r4,small_external_data_label-0x8000(r0)
+ ldb r4,big_external_common-0x8000(r0)
+ ldb r4,small_external_common-0x8000(r0)
+ ldb r4,big_local_common-0x8000(r0)
+ ldb r4,small_local_common-0x8000(r0)
+ ldb r4,data_label+0x10000(r0)
+ ldb r4,data_label(r5)
+ ldb r4,big_external_data_label(r5)
+ ldb r4,small_external_data_label(r5)
+ ldb r4,big_external_common(r5)
+ ldb r4,small_external_common(r5)
+ ldb r4,big_local_common(r5)
+ ldb r4,small_local_common(r5)
+ ldb r4,data_label+4(r5)
+ ldb r4,big_external_data_label+4(r5)
+ ldb r4,small_external_data_label+4(r5)
+ ldb r4,big_external_common+4(r5)
+ ldb r4,small_external_common+4(r5)
+ ldb r4,big_local_common+4(r5)
+ ldb r4,small_local_common+4(r5)
+ ldb r4,data_label-0x8000(r5)
+ ldb r4,big_external_data_label-0x8000(r5)
+ ldb r4,small_external_data_label-0x8000(r5)
+ ldb r4,big_external_common-0x8000(r5)
+ ldb r4,small_external_common-0x8000(r5)
+ ldb r4,big_local_common-0x8000(r5)
+ ldb r4,small_local_common-0x8000(r5)
+
+ ldbio r4,0(r0)
+ ldbio r4,4(r0)
+ ldbio r4,0x7ffc(r0)
+ ldbio r4,-0x8000(r0)
+ ldbio r4,0(r5)
+ ldbio r4,4(r5)
+ ldbio r4,0x7ffc(r5)
+ ldbio r4,-0x8000(r5)
+ ldbio r4,data_label(r0)
+ ldbio r4,big_external_data_label(r0)
+ ldbio r4,small_external_data_label(r0)
+ ldbio r4,big_external_common(r0)
+ ldbio r4,small_external_common(r0)
+ ldbio r4,big_local_common(r0)
+ ldbio r4,small_local_common(r0)
+ ldbio r4,data_label+4(r0)
+ ldbio r4,big_external_data_label+4(r0)
+ ldbio r4,small_external_data_label+4(r0)
+ ldbio r4,big_external_common+4(r0)
+ ldbio r4,small_external_common+4(r0)
+ ldbio r4,big_local_common+4(r0)
+ ldbio r4,small_local_common+4(r0)
+ ldbio r4,data_label-0x8000(r0)
+ ldbio r4,big_external_data_label-0x8000(r0)
+ ldbio r4,small_external_data_label-0x8000(r0)
+ ldbio r4,big_external_common-0x8000(r0)
+ ldbio r4,small_external_common-0x8000(r0)
+ ldbio r4,big_local_common-0x8000(r0)
+ ldbio r4,small_local_common-0x8000(r0)
+ ldbio r4,data_label+0x10000(r0)
+ ldbio r4,data_label(r5)
+ ldbio r4,big_external_data_label(r5)
+ ldbio r4,small_external_data_label(r5)
+ ldbio r4,big_external_common(r5)
+ ldbio r4,small_external_common(r5)
+ ldbio r4,big_local_common(r5)
+ ldbio r4,small_local_common(r5)
+ ldbio r4,data_label+4(r5)
+ ldbio r4,big_external_data_label+4(r5)
+ ldbio r4,small_external_data_label+4(r5)
+ ldbio r4,big_external_common+4(r5)
+ ldbio r4,small_external_common+4(r5)
+ ldbio r4,big_local_common+4(r5)
+ ldbio r4,small_local_common+4(r5)
+ ldbio r4,data_label-0x8000(r5)
+ ldbio r4,big_external_data_label-0x8000(r5)
+ ldbio r4,small_external_data_label-0x8000(r5)
+ ldbio r4,big_external_common-0x8000(r5)
+ ldbio r4,small_external_common-0x8000(r5)
+ ldbio r4,big_local_common-0x8000(r5)
+ ldbio r4,small_local_common-0x8000(r5)
diff --git a/gas/testsuite/gas/nios2/ldh.d b/gas/testsuite/gas/nios2/ldh.d
new file mode 100644
index 0000000000..f030eef187
--- /dev/null
+++ b/gas/testsuite/gas/nios2/ldh.d
@@ -0,0 +1,196 @@
+#objdump: -dr --prefix-addresses
+#name: NIOS2 ldh
+
+# Test the ld instruction
+
+.*: +file format elf32-littlenios2
+
+Disassembly of section .text:
+0+0000 <[^>]*> ldh r4,0\(zero\)
+0+0004 <[^>]*> ldh r4,4\(zero\)
+0+0008 <[^>]*> ldh r4,32764\(zero\)
+0+000c <[^>]*> ldh r4,-32768\(zero\)
+0+0010 <[^>]*> ldh r4,0\(r5\)
+0+0014 <[^>]*> ldh r4,4\(r5\)
+0+0018 <[^>]*> ldh r4,32764\(r5\)
+0+001c <[^>]*> ldh r4,-32768\(r5\)
+0+0020 <[^>]*> ldh r4,0\(zero\)
+[ ]*20: R_NIOS2_S16 .data
+0+0024 <[^>]*> ldh r4,0\(zero\)
+[ ]*24: R_NIOS2_S16 big_external_data_label
+0+0028 <[^>]*> ldh r4,0\(zero\)
+[ ]*28: R_NIOS2_S16 small_external_data_label
+0+002c <[^>]*> ldh r4,0\(zero\)
+[ ]*2c: R_NIOS2_S16 big_external_common
+0+0030 <[^>]*> ldh r4,0\(zero\)
+[ ]*30: R_NIOS2_S16 small_external_common
+0+0034 <[^>]*> ldh r4,0\(zero\)
+[ ]*34: R_NIOS2_S16 .bss
+0+0038 <[^>]*> ldh r4,0\(zero\)
+[ ]*38: R_NIOS2_S16 .bss\+0x4000
+0+003c <[^>]*> ldh r4,0\(zero\)
+[ ]*3c: R_NIOS2_S16 .data\+0x4
+0+0040 <[^>]*> ldh r4,0\(zero\)
+[ ]*40: R_NIOS2_S16 big_external_data_label\+0x4
+0+0044 <[^>]*> ldh r4,0\(zero\)
+[ ]*44: R_NIOS2_S16 small_external_data_label\+0x4
+0+0048 <[^>]*> ldh r4,0\(zero\)
+[ ]*48: R_NIOS2_S16 big_external_common\+0x4
+0+004c <[^>]*> ldh r4,0\(zero\)
+[ ]*4c: R_NIOS2_S16 small_external_common\+0x4
+0+0050 <[^>]*> ldh r4,0\(zero\)
+[ ]*50: R_NIOS2_S16 .bss\+0x4
+0+0054 <[^>]*> ldh r4,0\(zero\)
+[ ]*54: R_NIOS2_S16 .bss\+0x4004
+0+0058 <[^>]*> ldh r4,0\(zero\)
+[ ]*58: R_NIOS2_S16 .data-0x8000
+0+005c <[^>]*> ldh r4,0\(zero\)
+[ ]*5c: R_NIOS2_S16 big_external_data_label-0x8000
+0+0060 <[^>]*> ldh r4,0\(zero\)
+[ ]*60: R_NIOS2_S16 small_external_data_label-0x8000
+0+0064 <[^>]*> ldh r4,0\(zero\)
+[ ]*64: R_NIOS2_S16 big_external_common-0x8000
+0+0068 <[^>]*> ldh r4,0\(zero\)
+[ ]*68: R_NIOS2_S16 small_external_common-0x8000
+0+006c <[^>]*> ldh r4,0\(zero\)
+[ ]*6c: R_NIOS2_S16 .bss-0x8000
+0+0070 <[^>]*> ldh r4,0\(zero\)
+[ ]*70: R_NIOS2_S16 .bss-0x4000
+0+0074 <[^>]*> ldh r4,0\(zero\)
+[ ]*74: R_NIOS2_S16 .data\+0x10000
+0+0078 <[^>]*> ldh r4,0\(r5\)
+[ ]*78: R_NIOS2_S16 .data
+0+007c <[^>]*> ldh r4,0\(r5\)
+[ ]*7c: R_NIOS2_S16 big_external_data_label
+0+0080 <[^>]*> ldh r4,0\(r5\)
+[ ]*80: R_NIOS2_S16 small_external_data_label
+0+0084 <[^>]*> ldh r4,0\(r5\)
+[ ]*84: R_NIOS2_S16 big_external_common
+0+0088 <[^>]*> ldh r4,0\(r5\)
+[ ]*88: R_NIOS2_S16 small_external_common
+0+008c <[^>]*> ldh r4,0\(r5\)
+[ ]*8c: R_NIOS2_S16 .bss
+0+0090 <[^>]*> ldh r4,0\(r5\)
+[ ]*90: R_NIOS2_S16 .bss\+0x4000
+0+0094 <[^>]*> ldh r4,0\(r5\)
+[ ]*94: R_NIOS2_S16 .data\+0x4
+0+0098 <[^>]*> ldh r4,0\(r5\)
+[ ]*98: R_NIOS2_S16 big_external_data_label\+0x4
+0+009c <[^>]*> ldh r4,0\(r5\)
+[ ]*9c: R_NIOS2_S16 small_external_data_label\+0x4
+0+00a0 <[^>]*> ldh r4,0\(r5\)
+[ ]*a0: R_NIOS2_S16 big_external_common\+0x4
+0+00a4 <[^>]*> ldh r4,0\(r5\)
+[ ]*a4: R_NIOS2_S16 small_external_common\+0x4
+0+00a8 <[^>]*> ldh r4,0\(r5\)
+[ ]*a8: R_NIOS2_S16 .bss\+0x4
+0+00ac <[^>]*> ldh r4,0\(r5\)
+[ ]*ac: R_NIOS2_S16 .bss\+0x4004
+0+00b0 <[^>]*> ldh r4,0\(r5\)
+[ ]*b0: R_NIOS2_S16 .data-0x8000
+0+00b4 <[^>]*> ldh r4,0\(r5\)
+[ ]*b4: R_NIOS2_S16 big_external_data_label-0x8000
+0+00b8 <[^>]*> ldh r4,0\(r5\)
+[ ]*b8: R_NIOS2_S16 small_external_data_label-0x8000
+0+00bc <[^>]*> ldh r4,0\(r5\)
+[ ]*bc: R_NIOS2_S16 big_external_common-0x8000
+0+00c0 <[^>]*> ldh r4,0\(r5\)
+[ ]*c0: R_NIOS2_S16 small_external_common-0x8000
+0+00c4 <[^>]*> ldh r4,0\(r5\)
+[ ]*c4: R_NIOS2_S16 .bss-0x8000
+0+00c8 <[^>]*> ldh r4,0\(r5\)
+[ ]*c8: R_NIOS2_S16 .bss-0x4000
+0+00cc <[^>]*> ldhio r4,0\(zero\)
+0+00d0 <[^>]*> ldhio r4,4\(zero\)
+0+00d4 <[^>]*> ldhio r4,32764\(zero\)
+0+00d8 <[^>]*> ldhio r4,-32768\(zero\)
+0+00dc <[^>]*> ldhio r4,0\(r5\)
+0+00e0 <[^>]*> ldhio r4,4\(r5\)
+0+00e4 <[^>]*> ldhio r4,32764\(r5\)
+0+00e8 <[^>]*> ldhio r4,-32768\(r5\)
+0+00ec <[^>]*> ldhio r4,0\(zero\)
+[ ]*ec: R_NIOS2_S16 .data
+0+00f0 <[^>]*> ldhio r4,0\(zero\)
+[ ]*f0: R_NIOS2_S16 big_external_data_label
+0+00f4 <[^>]*> ldhio r4,0\(zero\)
+[ ]*f4: R_NIOS2_S16 small_external_data_label
+0+00f8 <[^>]*> ldhio r4,0\(zero\)
+[ ]*f8: R_NIOS2_S16 big_external_common
+0+00fc <[^>]*> ldhio r4,0\(zero\)
+[ ]*fc: R_NIOS2_S16 small_external_common
+0+0100 <[^>]*> ldhio r4,0\(zero\)
+[ ]*100: R_NIOS2_S16 .bss
+0+0104 <[^>]*> ldhio r4,0\(zero\)
+[ ]*104: R_NIOS2_S16 .bss\+0x4000
+0+0108 <[^>]*> ldhio r4,0\(zero\)
+[ ]*108: R_NIOS2_S16 .data\+0x4
+0+010c <[^>]*> ldhio r4,0\(zero\)
+[ ]*10c: R_NIOS2_S16 big_external_data_label\+0x4
+0+0110 <[^>]*> ldhio r4,0\(zero\)
+[ ]*110: R_NIOS2_S16 small_external_data_label\+0x4
+0+0114 <[^>]*> ldhio r4,0\(zero\)
+[ ]*114: R_NIOS2_S16 big_external_common\+0x4
+0+0118 <[^>]*> ldhio r4,0\(zero\)
+[ ]*118: R_NIOS2_S16 small_external_common\+0x4
+0+011c <[^>]*> ldhio r4,0\(zero\)
+[ ]*11c: R_NIOS2_S16 .bss\+0x4
+0+0120 <[^>]*> ldhio r4,0\(zero\)
+[ ]*120: R_NIOS2_S16 .bss\+0x4004
+0+0124 <[^>]*> ldhio r4,0\(zero\)
+[ ]*124: R_NIOS2_S16 .data-0x8000
+0+0128 <[^>]*> ldhio r4,0\(zero\)
+[ ]*128: R_NIOS2_S16 big_external_data_label-0x8000
+0+012c <[^>]*> ldhio r4,0\(zero\)
+[ ]*12c: R_NIOS2_S16 small_external_data_label-0x8000
+0+0130 <[^>]*> ldhio r4,0\(zero\)
+[ ]*130: R_NIOS2_S16 big_external_common-0x8000
+0+0134 <[^>]*> ldhio r4,0\(zero\)
+[ ]*134: R_NIOS2_S16 small_external_common-0x8000
+0+0138 <[^>]*> ldhio r4,0\(zero\)
+[ ]*138: R_NIOS2_S16 .bss-0x8000
+0+013c <[^>]*> ldhio r4,0\(zero\)
+[ ]*13c: R_NIOS2_S16 .bss-0x4000
+0+0140 <[^>]*> ldhio r4,0\(zero\)
+[ ]*140: R_NIOS2_S16 .data\+0x10000
+0+0144 <[^>]*> ldhio r4,0\(r5\)
+[ ]*144: R_NIOS2_S16 .data
+0+0148 <[^>]*> ldhio r4,0\(r5\)
+[ ]*148: R_NIOS2_S16 big_external_data_label
+0+014c <[^>]*> ldhio r4,0\(r5\)
+[ ]*14c: R_NIOS2_S16 small_external_data_label
+0+0150 <[^>]*> ldhio r4,0\(r5\)
+[ ]*150: R_NIOS2_S16 big_external_common
+0+0154 <[^>]*> ldhio r4,0\(r5\)
+[ ]*154: R_NIOS2_S16 small_external_common
+0+0158 <[^>]*> ldhio r4,0\(r5\)
+[ ]*158: R_NIOS2_S16 .bss
+0+015c <[^>]*> ldhio r4,0\(r5\)
+[ ]*15c: R_NIOS2_S16 .bss\+0x4000
+0+0160 <[^>]*> ldhio r4,0\(r5\)
+[ ]*160: R_NIOS2_S16 .data\+0x4
+0+0164 <[^>]*> ldhio r4,0\(r5\)
+[ ]*164: R_NIOS2_S16 big_external_data_label\+0x4
+0+0168 <[^>]*> ldhio r4,0\(r5\)
+[ ]*168: R_NIOS2_S16 small_external_data_label\+0x4
+0+016c <[^>]*> ldhio r4,0\(r5\)
+[ ]*16c: R_NIOS2_S16 big_external_common\+0x4
+0+0170 <[^>]*> ldhio r4,0\(r5\)
+[ ]*170: R_NIOS2_S16 small_external_common\+0x4
+0+0174 <[^>]*> ldhio r4,0\(r5\)
+[ ]*174: R_NIOS2_S16 .bss\+0x4
+0+0178 <[^>]*> ldhio r4,0\(r5\)
+[ ]*178: R_NIOS2_S16 .bss\+0x4004
+0+017c <[^>]*> ldhio r4,0\(r5\)
+[ ]*17c: R_NIOS2_S16 .data-0x8000
+0+0180 <[^>]*> ldhio r4,0\(r5\)
+[ ]*180: R_NIOS2_S16 big_external_data_label-0x8000
+0+0184 <[^>]*> ldhio r4,0\(r5\)
+[ ]*184: R_NIOS2_S16 small_external_data_label-0x8000
+0+0188 <[^>]*> ldhio r4,0\(r5\)
+[ ]*188: R_NIOS2_S16 big_external_common-0x8000
+0+018c <[^>]*> ldhio r4,0\(r5\)
+[ ]*18c: R_NIOS2_S16 small_external_common-0x8000
+0+0190 <[^>]*> ldhio r4,0\(r5\)
+[ ]*190: R_NIOS2_S16 .bss-0x8000
+0+0194 <[^>]*> ldhio r4,0\(r5\)
+[ ]*194: R_NIOS2_S16 .bss-0x4000
diff --git a/gas/testsuite/gas/nios2/ldh.s b/gas/testsuite/gas/nios2/ldh.s
new file mode 100644
index 0000000000..87040eeb79
--- /dev/null
+++ b/gas/testsuite/gas/nios2/ldh.s
@@ -0,0 +1,117 @@
+ .data
+data_label:
+ .extern big_external_data_label,0x4000
+ .extern small_external_data_label,4
+ .comm big_external_common,0x4000
+ .comm small_external_common,4
+ .lcomm big_local_common,0x4000
+ .lcomm small_local_common,4
+
+# the small symbols should have space allocated in the sbss section
+# but this is not yet supported in the assembler, so space is allocated
+# in the .bss section and the relocations are not gp-relative. this will
+# be updated when gp-relative relocations are added
+ .text
+ ldh r4,0(r0)
+ ldh r4,4(r0)
+ ldh r4,0x7ffc(r0)
+ ldh r4,-0x8000(r0)
+ ldh r4,0(r5)
+ ldh r4,4(r5)
+ ldh r4,0x7ffc(r5)
+ ldh r4,-0x8000(r5)
+ ldh r4,data_label(r0)
+ ldh r4,big_external_data_label(r0)
+ ldh r4,small_external_data_label(r0)
+ ldh r4,big_external_common(r0)
+ ldh r4,small_external_common(r0)
+ ldh r4,big_local_common(r0)
+ ldh r4,small_local_common(r0)
+ ldh r4,data_label+4(r0)
+ ldh r4,big_external_data_label+4(r0)
+ ldh r4,small_external_data_label+4(r0)
+ ldh r4,big_external_common+4(r0)
+ ldh r4,small_external_common+4(r0)
+ ldh r4,big_local_common+4(r0)
+ ldh r4,small_local_common+4(r0)
+ ldh r4,data_label-0x8000(r0)
+ ldh r4,big_external_data_label-0x8000(r0)
+ ldh r4,small_external_data_label-0x8000(r0)
+ ldh r4,big_external_common-0x8000(r0)
+ ldh r4,small_external_common-0x8000(r0)
+ ldh r4,big_local_common-0x8000(r0)
+ ldh r4,small_local_common-0x8000(r0)
+ ldh r4,data_label+0x10000(r0)
+ ldh r4,data_label(r5)
+ ldh r4,big_external_data_label(r5)
+ ldh r4,small_external_data_label(r5)
+ ldh r4,big_external_common(r5)
+ ldh r4,small_external_common(r5)
+ ldh r4,big_local_common(r5)
+ ldh r4,small_local_common(r5)
+ ldh r4,data_label+4(r5)
+ ldh r4,big_external_data_label+4(r5)
+ ldh r4,small_external_data_label+4(r5)
+ ldh r4,big_external_common+4(r5)
+ ldh r4,small_external_common+4(r5)
+ ldh r4,big_local_common+4(r5)
+ ldh r4,small_local_common+4(r5)
+ ldh r4,data_label-0x8000(r5)
+ ldh r4,big_external_data_label-0x8000(r5)
+ ldh r4,small_external_data_label-0x8000(r5)
+ ldh r4,big_external_common-0x8000(r5)
+ ldh r4,small_external_common-0x8000(r5)
+ ldh r4,big_local_common-0x8000(r5)
+ ldh r4,small_local_common-0x8000(r5)
+
+ ldhio r4,0(r0)
+ ldhio r4,4(r0)
+ ldhio r4,0x7ffc(r0)
+ ldhio r4,-0x8000(r0)
+ ldhio r4,0(r5)
+ ldhio r4,4(r5)
+ ldhio r4,0x7ffc(r5)
+ ldhio r4,-0x8000(r5)
+ ldhio r4,data_label(r0)
+ ldhio r4,big_external_data_label(r0)
+ ldhio r4,small_external_data_label(r0)
+ ldhio r4,big_external_common(r0)
+ ldhio r4,small_external_common(r0)
+ ldhio r4,big_local_common(r0)
+ ldhio r4,small_local_common(r0)
+ ldhio r4,data_label+4(r0)
+ ldhio r4,big_external_data_label+4(r0)
+ ldhio r4,small_external_data_label+4(r0)
+ ldhio r4,big_external_common+4(r0)
+ ldhio r4,small_external_common+4(r0)
+ ldhio r4,big_local_common+4(r0)
+ ldhio r4,small_local_common+4(r0)
+ ldhio r4,data_label-0x8000(r0)
+ ldhio r4,big_external_data_label-0x8000(r0)
+ ldhio r4,small_external_data_label-0x8000(r0)
+ ldhio r4,big_external_common-0x8000(r0)
+ ldhio r4,small_external_common-0x8000(r0)
+ ldhio r4,big_local_common-0x8000(r0)
+ ldhio r4,small_local_common-0x8000(r0)
+ ldhio r4,data_label+0x10000(r0)
+ ldhio r4,data_label(r5)
+ ldhio r4,big_external_data_label(r5)
+ ldhio r4,small_external_data_label(r5)
+ ldhio r4,big_external_common(r5)
+ ldhio r4,small_external_common(r5)
+ ldhio r4,big_local_common(r5)
+ ldhio r4,small_local_common(r5)
+ ldhio r4,data_label+4(r5)
+ ldhio r4,big_external_data_label+4(r5)
+ ldhio r4,small_external_data_label+4(r5)
+ ldhio r4,big_external_common+4(r5)
+ ldhio r4,small_external_common+4(r5)
+ ldhio r4,big_local_common+4(r5)
+ ldhio r4,small_local_common+4(r5)
+ ldhio r4,data_label-0x8000(r5)
+ ldhio r4,big_external_data_label-0x8000(r5)
+ ldhio r4,small_external_data_label-0x8000(r5)
+ ldhio r4,big_external_common-0x8000(r5)
+ ldhio r4,small_external_common-0x8000(r5)
+ ldhio r4,big_local_common-0x8000(r5)
+ ldhio r4,small_local_common-0x8000(r5)
diff --git a/gas/testsuite/gas/nios2/ldw.d b/gas/testsuite/gas/nios2/ldw.d
new file mode 100644
index 0000000000..dc2571edb9
--- /dev/null
+++ b/gas/testsuite/gas/nios2/ldw.d
@@ -0,0 +1,196 @@
+#objdump: -dr --prefix-addresses
+#name: NIOS2 ldw
+
+# Test the ld instruction
+
+.*: +file format elf32-littlenios2
+
+Disassembly of section .text:
+0+0000 <[^>]*> ldw r4,0\(zero\)
+0+0004 <[^>]*> ldw r4,4\(zero\)
+0+0008 <[^>]*> ldw r4,32764\(zero\)
+0+000c <[^>]*> ldw r4,-32768\(zero\)
+0+0010 <[^>]*> ldw r4,0\(r5\)
+0+0014 <[^>]*> ldw r4,4\(r5\)
+0+0018 <[^>]*> ldw r4,32764\(r5\)
+0+001c <[^>]*> ldw r4,-32768\(r5\)
+0+0020 <[^>]*> ldw r4,0\(zero\)
+[ ]*20: R_NIOS2_S16 .data
+0+0024 <[^>]*> ldw r4,0\(zero\)
+[ ]*24: R_NIOS2_S16 big_external_data_label
+0+0028 <[^>]*> ldw r4,0\(zero\)
+[ ]*28: R_NIOS2_S16 small_external_data_label
+0+002c <[^>]*> ldw r4,0\(zero\)
+[ ]*2c: R_NIOS2_S16 big_external_common
+0+0030 <[^>]*> ldw r4,0\(zero\)
+[ ]*30: R_NIOS2_S16 small_external_common
+0+0034 <[^>]*> ldw r4,0\(zero\)
+[ ]*34: R_NIOS2_S16 .bss
+0+0038 <[^>]*> ldw r4,0\(zero\)
+[ ]*38: R_NIOS2_S16 .bss\+0x4000
+0+003c <[^>]*> ldw r4,0\(zero\)
+[ ]*3c: R_NIOS2_S16 .data\+0x4
+0+0040 <[^>]*> ldw r4,0\(zero\)
+[ ]*40: R_NIOS2_S16 big_external_data_label\+0x4
+0+0044 <[^>]*> ldw r4,0\(zero\)
+[ ]*44: R_NIOS2_S16 small_external_data_label\+0x4
+0+0048 <[^>]*> ldw r4,0\(zero\)
+[ ]*48: R_NIOS2_S16 big_external_common\+0x4
+0+004c <[^>]*> ldw r4,0\(zero\)
+[ ]*4c: R_NIOS2_S16 small_external_common\+0x4
+0+0050 <[^>]*> ldw r4,0\(zero\)
+[ ]*50: R_NIOS2_S16 .bss\+0x4
+0+0054 <[^>]*> ldw r4,0\(zero\)
+[ ]*54: R_NIOS2_S16 .bss\+0x4004
+0+0058 <[^>]*> ldw r4,0\(zero\)
+[ ]*58: R_NIOS2_S16 .data-0x8000
+0+005c <[^>]*> ldw r4,0\(zero\)
+[ ]*5c: R_NIOS2_S16 big_external_data_label-0x8000
+0+0060 <[^>]*> ldw r4,0\(zero\)
+[ ]*60: R_NIOS2_S16 small_external_data_label-0x8000
+0+0064 <[^>]*> ldw r4,0\(zero\)
+[ ]*64: R_NIOS2_S16 big_external_common-0x8000
+0+0068 <[^>]*> ldw r4,0\(zero\)
+[ ]*68: R_NIOS2_S16 small_external_common-0x8000
+0+006c <[^>]*> ldw r4,0\(zero\)
+[ ]*6c: R_NIOS2_S16 .bss-0x8000
+0+0070 <[^>]*> ldw r4,0\(zero\)
+[ ]*70: R_NIOS2_S16 .bss-0x4000
+0+0074 <[^>]*> ldw r4,0\(zero\)
+[ ]*74: R_NIOS2_S16 .data\+0x10000
+0+0078 <[^>]*> ldw r4,0\(r5\)
+[ ]*78: R_NIOS2_S16 .data
+0+007c <[^>]*> ldw r4,0\(r5\)
+[ ]*7c: R_NIOS2_S16 big_external_data_label
+0+0080 <[^>]*> ldw r4,0\(r5\)
+[ ]*80: R_NIOS2_S16 small_external_data_label
+0+0084 <[^>]*> ldw r4,0\(r5\)
+[ ]*84: R_NIOS2_S16 big_external_common
+0+0088 <[^>]*> ldw r4,0\(r5\)
+[ ]*88: R_NIOS2_S16 small_external_common
+0+008c <[^>]*> ldw r4,0\(r5\)
+[ ]*8c: R_NIOS2_S16 .bss
+0+0090 <[^>]*> ldw r4,0\(r5\)
+[ ]*90: R_NIOS2_S16 .bss\+0x4000
+0+0094 <[^>]*> ldw r4,0\(r5\)
+[ ]*94: R_NIOS2_S16 .data\+0x4
+0+0098 <[^>]*> ldw r4,0\(r5\)
+[ ]*98: R_NIOS2_S16 big_external_data_label\+0x4
+0+009c <[^>]*> ldw r4,0\(r5\)
+[ ]*9c: R_NIOS2_S16 small_external_data_label\+0x4
+0+00a0 <[^>]*> ldw r4,0\(r5\)
+[ ]*a0: R_NIOS2_S16 big_external_common\+0x4
+0+00a4 <[^>]*> ldw r4,0\(r5\)
+[ ]*a4: R_NIOS2_S16 small_external_common\+0x4
+0+00a8 <[^>]*> ldw r4,0\(r5\)
+[ ]*a8: R_NIOS2_S16 .bss\+0x4
+0+00ac <[^>]*> ldw r4,0\(r5\)
+[ ]*ac: R_NIOS2_S16 .bss\+0x4004
+0+00b0 <[^>]*> ldw r4,0\(r5\)
+[ ]*b0: R_NIOS2_S16 .data-0x8000
+0+00b4 <[^>]*> ldw r4,0\(r5\)
+[ ]*b4: R_NIOS2_S16 big_external_data_label-0x8000
+0+00b8 <[^>]*> ldw r4,0\(r5\)
+[ ]*b8: R_NIOS2_S16 small_external_data_label-0x8000
+0+00bc <[^>]*> ldw r4,0\(r5\)
+[ ]*bc: R_NIOS2_S16 big_external_common-0x8000
+0+00c0 <[^>]*> ldw r4,0\(r5\)
+[ ]*c0: R_NIOS2_S16 small_external_common-0x8000
+0+00c4 <[^>]*> ldw r4,0\(r5\)
+[ ]*c4: R_NIOS2_S16 .bss-0x8000
+0+00c8 <[^>]*> ldw r4,0\(r5\)
+[ ]*c8: R_NIOS2_S16 .bss-0x4000
+0+00cc <[^>]*> ldwio r4,0\(zero\)
+0+00d0 <[^>]*> ldwio r4,4\(zero\)
+0+00d4 <[^>]*> ldwio r4,32764\(zero\)
+0+00d8 <[^>]*> ldwio r4,-32768\(zero\)
+0+00dc <[^>]*> ldwio r4,0\(r5\)
+0+00e0 <[^>]*> ldwio r4,4\(r5\)
+0+00e4 <[^>]*> ldwio r4,32764\(r5\)
+0+00e8 <[^>]*> ldwio r4,-32768\(r5\)
+0+00ec <[^>]*> ldwio r4,0\(zero\)
+[ ]*ec: R_NIOS2_S16 .data
+0+00f0 <[^>]*> ldwio r4,0\(zero\)
+[ ]*f0: R_NIOS2_S16 big_external_data_label
+0+00f4 <[^>]*> ldwio r4,0\(zero\)
+[ ]*f4: R_NIOS2_S16 small_external_data_label
+0+00f8 <[^>]*> ldwio r4,0\(zero\)
+[ ]*f8: R_NIOS2_S16 big_external_common
+0+00fc <[^>]*> ldwio r4,0\(zero\)
+[ ]*fc: R_NIOS2_S16 small_external_common
+0+0100 <[^>]*> ldwio r4,0\(zero\)
+[ ]*100: R_NIOS2_S16 .bss
+0+0104 <[^>]*> ldwio r4,0\(zero\)
+[ ]*104: R_NIOS2_S16 .bss\+0x4000
+0+0108 <[^>]*> ldwio r4,0\(zero\)
+[ ]*108: R_NIOS2_S16 .data\+0x4
+0+010c <[^>]*> ldwio r4,0\(zero\)
+[ ]*10c: R_NIOS2_S16 big_external_data_label\+0x4
+0+0110 <[^>]*> ldwio r4,0\(zero\)
+[ ]*110: R_NIOS2_S16 small_external_data_label\+0x4
+0+0114 <[^>]*> ldwio r4,0\(zero\)
+[ ]*114: R_NIOS2_S16 big_external_common\+0x4
+0+0118 <[^>]*> ldwio r4,0\(zero\)
+[ ]*118: R_NIOS2_S16 small_external_common\+0x4
+0+011c <[^>]*> ldwio r4,0\(zero\)
+[ ]*11c: R_NIOS2_S16 .bss\+0x4
+0+0120 <[^>]*> ldwio r4,0\(zero\)
+[ ]*120: R_NIOS2_S16 .bss\+0x4004
+0+0124 <[^>]*> ldwio r4,0\(zero\)
+[ ]*124: R_NIOS2_S16 .data-0x8000
+0+0128 <[^>]*> ldwio r4,0\(zero\)
+[ ]*128: R_NIOS2_S16 big_external_data_label-0x8000
+0+012c <[^>]*> ldwio r4,0\(zero\)
+[ ]*12c: R_NIOS2_S16 small_external_data_label-0x8000
+0+0130 <[^>]*> ldwio r4,0\(zero\)
+[ ]*130: R_NIOS2_S16 big_external_common-0x8000
+0+0134 <[^>]*> ldwio r4,0\(zero\)
+[ ]*134: R_NIOS2_S16 small_external_common-0x8000
+0+0138 <[^>]*> ldwio r4,0\(zero\)
+[ ]*138: R_NIOS2_S16 .bss-0x8000
+0+013c <[^>]*> ldwio r4,0\(zero\)
+[ ]*13c: R_NIOS2_S16 .bss-0x4000
+0+0140 <[^>]*> ldwio r4,0\(zero\)
+[ ]*140: R_NIOS2_S16 .data\+0x10000
+0+0144 <[^>]*> ldwio r4,0\(r5\)
+[ ]*144: R_NIOS2_S16 .data
+0+0148 <[^>]*> ldwio r4,0\(r5\)
+[ ]*148: R_NIOS2_S16 big_external_data_label
+0+014c <[^>]*> ldwio r4,0\(r5\)
+[ ]*14c: R_NIOS2_S16 small_external_data_label
+0+0150 <[^>]*> ldwio r4,0\(r5\)
+[ ]*150: R_NIOS2_S16 big_external_common
+0+0154 <[^>]*> ldwio r4,0\(r5\)
+[ ]*154: R_NIOS2_S16 small_external_common
+0+0158 <[^>]*> ldwio r4,0\(r5\)
+[ ]*158: R_NIOS2_S16 .bss
+0+015c <[^>]*> ldwio r4,0\(r5\)
+[ ]*15c: R_NIOS2_S16 .bss\+0x4000
+0+0160 <[^>]*> ldwio r4,0\(r5\)
+[ ]*160: R_NIOS2_S16 .data\+0x4
+0+0164 <[^>]*> ldwio r4,0\(r5\)
+[ ]*164: R_NIOS2_S16 big_external_data_label\+0x4
+0+0168 <[^>]*> ldwio r4,0\(r5\)
+[ ]*168: R_NIOS2_S16 small_external_data_label\+0x4
+0+016c <[^>]*> ldwio r4,0\(r5\)
+[ ]*16c: R_NIOS2_S16 big_external_common\+0x4
+0+0170 <[^>]*> ldwio r4,0\(r5\)
+[ ]*170: R_NIOS2_S16 small_external_common\+0x4
+0+0174 <[^>]*> ldwio r4,0\(r5\)
+[ ]*174: R_NIOS2_S16 .bss\+0x4
+0+0178 <[^>]*> ldwio r4,0\(r5\)
+[ ]*178: R_NIOS2_S16 .bss\+0x4004
+0+017c <[^>]*> ldwio r4,0\(r5\)
+[ ]*17c: R_NIOS2_S16 .data-0x8000
+0+0180 <[^>]*> ldwio r4,0\(r5\)
+[ ]*180: R_NIOS2_S16 big_external_data_label-0x8000
+0+0184 <[^>]*> ldwio r4,0\(r5\)
+[ ]*184: R_NIOS2_S16 small_external_data_label-0x8000
+0+0188 <[^>]*> ldwio r4,0\(r5\)
+[ ]*188: R_NIOS2_S16 big_external_common-0x8000
+0+018c <[^>]*> ldwio r4,0\(r5\)
+[ ]*18c: R_NIOS2_S16 small_external_common-0x8000
+0+0190 <[^>]*> ldwio r4,0\(r5\)
+[ ]*190: R_NIOS2_S16 .bss-0x8000
+0+0194 <[^>]*> ldwio r4,0\(r5\)
+[ ]*194: R_NIOS2_S16 .bss-0x4000
diff --git a/gas/testsuite/gas/nios2/ldw.s b/gas/testsuite/gas/nios2/ldw.s
new file mode 100644
index 0000000000..cf6de19d21
--- /dev/null
+++ b/gas/testsuite/gas/nios2/ldw.s
@@ -0,0 +1,117 @@
+ .data
+data_label:
+ .extern big_external_data_label,0x4000
+ .extern small_external_data_label,4
+ .comm big_external_common,0x4000
+ .comm small_external_common,4
+ .lcomm big_local_common,0x4000
+ .lcomm small_local_common,4
+
+# the small symbols should have space allocated in the sbss section
+# but this is not yet supported in the assembler, so space is allocated
+# in the .bss section and the relocations are not gp-relative. this will
+# be updated when gp-relative relocations are added
+ .text
+ ldw r4,0(r0)
+ ldw r4,4(r0)
+ ldw r4,0x7ffc(r0)
+ ldw r4,-0x8000(r0)
+ ldw r4,0(r5)
+ ldw r4,4(r5)
+ ldw r4,0x7ffc(r5)
+ ldw r4,-0x8000(r5)
+ ldw r4,data_label(r0)
+ ldw r4,big_external_data_label(r0)
+ ldw r4,small_external_data_label(r0)
+ ldw r4,big_external_common(r0)
+ ldw r4,small_external_common(r0)
+ ldw r4,big_local_common(r0)
+ ldw r4,small_local_common(r0)
+ ldw r4,data_label+4(r0)
+ ldw r4,big_external_data_label+4(r0)
+ ldw r4,small_external_data_label+4(r0)
+ ldw r4,big_external_common+4(r0)
+ ldw r4,small_external_common+4(r0)
+ ldw r4,big_local_common+4(r0)
+ ldw r4,small_local_common+4(r0)
+ ldw r4,data_label-0x8000(r0)
+ ldw r4,big_external_data_label-0x8000(r0)
+ ldw r4,small_external_data_label-0x8000(r0)
+ ldw r4,big_external_common-0x8000(r0)
+ ldw r4,small_external_common-0x8000(r0)
+ ldw r4,big_local_common-0x8000(r0)
+ ldw r4,small_local_common-0x8000(r0)
+ ldw r4,data_label+0x10000(r0)
+ ldw r4,data_label(r5)
+ ldw r4,big_external_data_label(r5)
+ ldw r4,small_external_data_label(r5)
+ ldw r4,big_external_common(r5)
+ ldw r4,small_external_common(r5)
+ ldw r4,big_local_common(r5)
+ ldw r4,small_local_common(r5)
+ ldw r4,data_label+4(r5)
+ ldw r4,big_external_data_label+4(r5)
+ ldw r4,small_external_data_label+4(r5)
+ ldw r4,big_external_common+4(r5)
+ ldw r4,small_external_common+4(r5)
+ ldw r4,big_local_common+4(r5)
+ ldw r4,small_local_common+4(r5)
+ ldw r4,data_label-0x8000(r5)
+ ldw r4,big_external_data_label-0x8000(r5)
+ ldw r4,small_external_data_label-0x8000(r5)
+ ldw r4,big_external_common-0x8000(r5)
+ ldw r4,small_external_common-0x8000(r5)
+ ldw r4,big_local_common-0x8000(r5)
+ ldw r4,small_local_common-0x8000(r5)
+
+ ldwio r4,0(r0)
+ ldwio r4,4(r0)
+ ldwio r4,0x7ffc(r0)
+ ldwio r4,-0x8000(r0)
+ ldwio r4,0(r5)
+ ldwio r4,4(r5)
+ ldwio r4,0x7ffc(r5)
+ ldwio r4,-0x8000(r5)
+ ldwio r4,data_label(r0)
+ ldwio r4,big_external_data_label(r0)
+ ldwio r4,small_external_data_label(r0)
+ ldwio r4,big_external_common(r0)
+ ldwio r4,small_external_common(r0)
+ ldwio r4,big_local_common(r0)
+ ldwio r4,small_local_common(r0)
+ ldwio r4,data_label+4(r0)
+ ldwio r4,big_external_data_label+4(r0)
+ ldwio r4,small_external_data_label+4(r0)
+ ldwio r4,big_external_common+4(r0)
+ ldwio r4,small_external_common+4(r0)
+ ldwio r4,big_local_common+4(r0)
+ ldwio r4,small_local_common+4(r0)
+ ldwio r4,data_label-0x8000(r0)
+ ldwio r4,big_external_data_label-0x8000(r0)
+ ldwio r4,small_external_data_label-0x8000(r0)
+ ldwio r4,big_external_common-0x8000(r0)
+ ldwio r4,small_external_common-0x8000(r0)
+ ldwio r4,big_local_common-0x8000(r0)
+ ldwio r4,small_local_common-0x8000(r0)
+ ldwio r4,data_label+0x10000(r0)
+ ldwio r4,data_label(r5)
+ ldwio r4,big_external_data_label(r5)
+ ldwio r4,small_external_data_label(r5)
+ ldwio r4,big_external_common(r5)
+ ldwio r4,small_external_common(r5)
+ ldwio r4,big_local_common(r5)
+ ldwio r4,small_local_common(r5)
+ ldwio r4,data_label+4(r5)
+ ldwio r4,big_external_data_label+4(r5)
+ ldwio r4,small_external_data_label+4(r5)
+ ldwio r4,big_external_common+4(r5)
+ ldwio r4,small_external_common+4(r5)
+ ldwio r4,big_local_common+4(r5)
+ ldwio r4,small_local_common+4(r5)
+ ldwio r4,data_label-0x8000(r5)
+ ldwio r4,big_external_data_label-0x8000(r5)
+ ldwio r4,small_external_data_label-0x8000(r5)
+ ldwio r4,big_external_common-0x8000(r5)
+ ldwio r4,small_external_common-0x8000(r5)
+ ldwio r4,big_local_common-0x8000(r5)
+ ldwio r4,small_local_common-0x8000(r5)
diff --git a/gas/testsuite/gas/nios2/lineseparator.d b/gas/testsuite/gas/nios2/lineseparator.d
new file mode 100644
index 0000000000..09c66ea0c8
--- /dev/null
+++ b/gas/testsuite/gas/nios2/lineseparator.d
@@ -0,0 +1,10 @@
+#objdump: -dr --prefix-addresses
+#name: NIOS2 lineseparator
+
+# Test the add instruction
+
+.*: +file format elf32-littlenios2
+
+Disassembly of section .text:
+0x0+0000 mov r5,r4
+0x0+0004 mov r4,r5
diff --git a/gas/testsuite/gas/nios2/lineseparator.s b/gas/testsuite/gas/nios2/lineseparator.s
new file mode 100644
index 0000000000..d16efc35eb
--- /dev/null
+++ b/gas/testsuite/gas/nios2/lineseparator.s
@@ -0,0 +1,4 @@
+mov r5, r4 ; mov r4, r5
+
+
+
diff --git a/gas/testsuite/gas/nios2/mov.d b/gas/testsuite/gas/nios2/mov.d
new file mode 100644
index 0000000000..13bf6db80a
--- /dev/null
+++ b/gas/testsuite/gas/nios2/mov.d
@@ -0,0 +1,11 @@
+#objdump: -dr --prefix-addresses
+#name: NIOS2 mov
+
+# Test the mov instruction
+
+.*: +file format elf32-littlenios2
+
+Disassembly of section .text:
+0+0000 <[^>]*> movz \$4,\$5,\$6
+0+0004 <[^>]*> movnz \$4,\$5,\$6
+
diff --git a/gas/testsuite/gas/nios2/mov.s b/gas/testsuite/gas/nios2/mov.s
new file mode 100644
index 0000000000..a66aaeb983
--- /dev/null
+++ b/gas/testsuite/gas/nios2/mov.s
@@ -0,0 +1,5 @@
+# Source file used to test the movz and movnz instructions
+
+foo:
+ movz $4,$5,$6
+ movnz $4,$5,$6
diff --git a/gas/testsuite/gas/nios2/movi.d b/gas/testsuite/gas/nios2/movi.d
new file mode 100644
index 0000000000..9e35c7b9d2
--- /dev/null
+++ b/gas/testsuite/gas/nios2/movi.d
@@ -0,0 +1,13 @@
+#objdump: -dr --prefix-addresses
+#name: NIOS2 movi
+
+# Test implicit conversion of movi/movhi etc
+.*: file format elf32-littlenios2
+
+Disassembly of section .text:
+0+0000 <[^>]*> movi r2,32
+0+0004 <[^>]*> movhi r2,8192
+0+0008 <[^>]*> movhi r2,65535
+0+000c <[^>]*> orhi r2,r5,65535
+0+0010 <[^>]*> xorhi r2,r10,65535
+0+0014 <[^>]*> andhi r2,r15,65535
diff --git a/gas/testsuite/gas/nios2/movi.s b/gas/testsuite/gas/nios2/movi.s
new file mode 100644
index 0000000000..07d9fed2bd
--- /dev/null
+++ b/gas/testsuite/gas/nios2/movi.s
@@ -0,0 +1,21 @@
+# Source file used to test silent conversion of
+# movi to orhi etc
+
+foo:
+# this doesn't get converted
+movi r2, 0x20
+
+# this does
+movi r2, 0x20000000
+
+# addi should convert only if the source register is r0
+addi r2, r0, 0xffff0000
+# but we can't test for non-conversion because the value would
+# be out of range
+
+# logical ops should convert for any register
+ori r2, r5, 0xffff0000
+xori r2, r10, 0xffff0000
+andi r2, r15, 0xffff0000
+
+
diff --git a/gas/testsuite/gas/nios2/movia.d b/gas/testsuite/gas/nios2/movia.d
new file mode 100644
index 0000000000..c255ace41b
--- /dev/null
+++ b/gas/testsuite/gas/nios2/movia.d
@@ -0,0 +1,18 @@
+#objdump: -dr --prefix-addresses
+#name: NIOS2 movia
+
+# Test the movia instruction
+
+.*: +file format elf32-littlenios2
+
+Disassembly of section .text:
+0+0000 <[^>]*> movhi r2,32897
+0+0004 <[^>]*> addi r2,r2,-32640
+0+0008 <[^>]*> movhi r3,0
+ 8: R_NIOS2_HIADJ16 sym-0x80000000
+0+000c <[^>]*> addi r3,r3,0
+ c: R_NIOS2_LO16 sym-0x80000000
+0+0010 <[^>]*> movhi r4,0
+ 10: R_NIOS2_HIADJ16 sym-0x7fffffff
+0+0014 <[^>]*> addi r4,r4,0
+ 14: R_NIOS2_LO16 sym-0x7fffffff
diff --git a/gas/testsuite/gas/nios2/movia.s b/gas/testsuite/gas/nios2/movia.s
new file mode 100644
index 0000000000..fe1d56cfef
--- /dev/null
+++ b/gas/testsuite/gas/nios2/movia.s
@@ -0,0 +1,6 @@
+# Test program for movia reg, immed32 macro
+
+foo:
+ movia r2, 0x80808080
+ movia r3, sym + 0x80000000
+ movia r4, sym - 0x7fffffff
diff --git a/gas/testsuite/gas/nios2/mul.d b/gas/testsuite/gas/nios2/mul.d
new file mode 100644
index 0000000000..79e86d1801
--- /dev/null
+++ b/gas/testsuite/gas/nios2/mul.d
@@ -0,0 +1,19 @@
+#objdump: -dr --prefix-addresses
+#name: NIOS2 mul
+
+# Test the mul macro.
+
+.*: +file format elf32-littlenios2
+
+Disassembly of section .text:
+0+0000 <[^>]*> mul r4,r5,r6
+0+0004 <[^>]*> muli r4,r5,0
+0+0008 <[^>]*> muli r4,r5,1
+0+000c <[^>]*> muli r4,r5,-32768
+0+0010 <[^>]*> muli r4,r5,32767
+0+0014 <[^>]*> muli r4,r5,0
+[ ]*14: R_NIOS2_S16 undefined_symbol
+0+0018 <[^>]*> muli r4,r5,16448
+0+001c <[^>]*> mulxss r4,r5,r6
+0+0020 <[^>]*> mulxsu r4,r5,r6
+0+0024 <[^>]*> mulxuu r4,r5,r6
diff --git a/gas/testsuite/gas/nios2/mul.s b/gas/testsuite/gas/nios2/mul.s
new file mode 100644
index 0000000000..3e47bc7b96
--- /dev/null
+++ b/gas/testsuite/gas/nios2/mul.s
@@ -0,0 +1,15 @@
+# Source file used to test the mul macro.
+
+foo:
+ mul r4,r5,r6
+ muli r4,r5,0
+ muli r4,r5,1
+ muli r4,r5,-0x8000
+ muli r4,r5,0x7fff
+ muli r4,r5,undefined_symbol
+ muli r4,r5,defined_symbol
+ mulxss r4,r5,r6
+ mulxsu r4,r5,r6
+ mulxuu r4,r5,r6
+.data
+.set defined_symbol, 0x4040
diff --git a/gas/testsuite/gas/nios2/nios2.exp b/gas/testsuite/gas/nios2/nios2.exp
new file mode 100644
index 0000000000..9390e8b434
--- /dev/null
+++ b/gas/testsuite/gas/nios2/nios2.exp
@@ -0,0 +1,75 @@
+#
+# Some generic Nios II tests
+#
+
+proc run_list_test { name } {
+ global srcdir subdir
+ set testname "NIOS2 $name"
+ set file $srcdir/$subdir/$name
+ gas_run ${name}.s "" ">&dump.out"
+ if { [regexp_diff "dump.out" "${file}.l"] } then {
+ fail $testname
+ verbose "output is [file_contents "dump.out"]" 2
+ return
+ }
+ pass $testname
+}
+
+if { [istarget nios2-*-*] } then {
+
+ run_dump_test "add"
+ run_dump_test "and"
+ run_dump_test "align_fill"
+ run_dump_test "align_text"
+
+ run_dump_test "branch"
+
+ run_dump_test "break"
+ run_dump_test "bret"
+ run_dump_test "cache"
+
+ run_dump_test "call"
+ run_dump_test "call26"
+
+ run_dump_test "cmp"
+
+ run_dump_test "jmp"
+ run_dump_test "ldw"
+ run_dump_test "ldh"
+ run_dump_test "ldb"
+
+ run_dump_test "flushda"
+
+ run_dump_test "mul"
+
+ run_dump_test "nor"
+ run_dump_test "or"
+
+ run_dump_test "ctl"
+ run_dump_test "ret"
+ run_dump_test "rotate"
+
+ run_dump_test "stw"
+ run_dump_test "sth"
+ run_dump_test "stb"
+
+ run_dump_test "sub"
+ run_dump_test "sync"
+ run_dump_test "trap"
+ run_dump_test "tret"
+
+ run_dump_test "custom"
+ run_dump_test "xor"
+ run_dump_test "movia"
+
+ run_dump_test "complex"
+ run_dump_test "comments"
+ run_dump_test "etbt"
+ run_dump_test "lineseparator"
+ run_dump_test "movi"
+
+ run_list_test "illegal"
+ run_list_test "warn_nobreak"
+ run_list_test "warn_noat"
+
+}
diff --git a/gas/testsuite/gas/nios2/nor.d b/gas/testsuite/gas/nios2/nor.d
new file mode 100644
index 0000000000..fab8e6914d
--- /dev/null
+++ b/gas/testsuite/gas/nios2/nor.d
@@ -0,0 +1,9 @@
+#objdump: -dr --prefix-addresses
+#name: NIOS2 nor
+
+# Test the nor instruction
+
+.*: +file format elf32-littlenios2
+
+Disassembly of section .text:
+0+0000 <[^>]*> nor r6,r8,r10
diff --git a/gas/testsuite/gas/nios2/nor.s b/gas/testsuite/gas/nios2/nor.s
new file mode 100644
index 0000000000..da7825478d
--- /dev/null
+++ b/gas/testsuite/gas/nios2/nor.s
@@ -0,0 +1,5 @@
+# Source file used to test the nor instruction
+
+foo:
+ nor r6,r8,r10
+
diff --git a/gas/testsuite/gas/nios2/or.d b/gas/testsuite/gas/nios2/or.d
new file mode 100644
index 0000000000..e5035bc502
--- /dev/null
+++ b/gas/testsuite/gas/nios2/or.d
@@ -0,0 +1,11 @@
+#objdump: -dr --prefix-addresses
+#name: NIOS2 or
+
+# Test the nor instruction
+
+.*: +file format elf32-littlenios2
+
+Disassembly of section .text:
+0+0000 <[^>]*> or r6,r8,r10
+0+0004 <[^>]*> orhi r6,r7,65535
+0+0008 <[^>]*> ori r6,r7,65535
diff --git a/gas/testsuite/gas/nios2/or.s b/gas/testsuite/gas/nios2/or.s
new file mode 100644
index 0000000000..675df17055
--- /dev/null
+++ b/gas/testsuite/gas/nios2/or.s
@@ -0,0 +1,7 @@
+# Source file used to test the nor instruction
+
+foo:
+ or r6,r8,r10
+ orhi r6,r7,0xffff
+ ori r6,r7,0xffff
+
diff --git a/gas/testsuite/gas/nios2/ret.d b/gas/testsuite/gas/nios2/ret.d
new file mode 100644
index 0000000000..b0719317c5
--- /dev/null
+++ b/gas/testsuite/gas/nios2/ret.d
@@ -0,0 +1,8 @@
+#objdump: -dr --prefix-addresses
+#name: NIOS2 ret
+
+.*: +file format elf32-littlenios2
+
+Disassembly of section .text:
+0+0000 <[^>]*> ret
+
diff --git a/gas/testsuite/gas/nios2/ret.s b/gas/testsuite/gas/nios2/ret.s
new file mode 100644
index 0000000000..69b76bc551
--- /dev/null
+++ b/gas/testsuite/gas/nios2/ret.s
@@ -0,0 +1,5 @@
+# Source file used to test the ret instructions
+foo:
+ ret
+
+
diff --git a/gas/testsuite/gas/nios2/rol.d b/gas/testsuite/gas/nios2/rol.d
new file mode 100644
index 0000000000..2128dd5704
--- /dev/null
+++ b/gas/testsuite/gas/nios2/rol.d
@@ -0,0 +1,40 @@
+#objdump: -dr --prefix-addresses -mmips:3000
+#as: -march=r3000 -mtune=r3000
+#name: MIPS R3000 rol
+
+# Test the rol and ror macros.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> negu at,a1
+0+0004 <[^>]*> srlv at,a0,at
+0+0008 <[^>]*> sllv a0,a0,a1
+0+000c <[^>]*> or a0,a0,at
+0+0010 <[^>]*> negu at,a2
+0+0014 <[^>]*> srlv at,a1,at
+0+0018 <[^>]*> sllv a0,a1,a2
+0+001c <[^>]*> or a0,a0,at
+0+0020 <[^>]*> sll at,a0,0x1
+0+0024 <[^>]*> srl a0,a0,0x1f
+0+0028 <[^>]*> or a0,a0,at
+0+002c <[^>]*> sll at,a1,0x1
+0+0030 <[^>]*> srl a0,a1,0x1f
+0+0034 <[^>]*> or a0,a0,at
+0+0038 <[^>]*> srl a0,a1,0x0
+0+003c <[^>]*> negu at,a1
+0+0040 <[^>]*> sllv at,a0,at
+0+0044 <[^>]*> srlv a0,a0,a1
+0+0048 <[^>]*> or a0,a0,at
+0+004c <[^>]*> negu at,a2
+0+0050 <[^>]*> sllv at,a1,at
+0+0054 <[^>]*> srlv a0,a1,a2
+0+0058 <[^>]*> or a0,a0,at
+0+005c <[^>]*> srl at,a0,0x1
+0+0060 <[^>]*> sll a0,a0,0x1f
+0+0064 <[^>]*> or a0,a0,at
+0+0068 <[^>]*> srl at,a1,0x1
+0+006c <[^>]*> sll a0,a1,0x1f
+0+0070 <[^>]*> or a0,a0,at
+0+0074 <[^>]*> srl a0,a1,0x0
+ ...
diff --git a/gas/testsuite/gas/nios2/rol.s b/gas/testsuite/gas/nios2/rol.s
new file mode 100644
index 0000000000..988d7021c4
--- /dev/null
+++ b/gas/testsuite/gas/nios2/rol.s
@@ -0,0 +1,15 @@
+# Source file used to test the rol and ror macros.
+
+foo:
+ rol $4,$5
+ rol $4,$5,$6
+ rol $4,1
+ rol $4,$5,1
+ rol $4,$5,0
+
+ ror $4,$5
+ ror $4,$5,$6
+ ror $4,1
+ ror $4,$5,1
+ ror $4,$5,0
+ .space 8
diff --git a/gas/testsuite/gas/nios2/rotate.d b/gas/testsuite/gas/nios2/rotate.d
new file mode 100644
index 0000000000..0f54f43a46
--- /dev/null
+++ b/gas/testsuite/gas/nios2/rotate.d
@@ -0,0 +1,17 @@
+#objdump: -dr --prefix-addresses
+#name: NIOS2 rotate
+
+# Test the and macro.
+
+.*: +file format elf32-littlenios2
+
+Disassembly of section .text:
+0+0000 <[^>]*> rol r4,r4,r4
+0+0004 <[^>]*> roli r4,r4,31
+0+0008 <[^>]*> ror r4,r4,r4
+0+000c <[^>]*> sll r4,r4,r4
+0+0010 <[^>]*> slli r4,r4,24
+0+0014 <[^>]*> sra r4,r4,r4
+0+0018 <[^>]*> srai r4,r4,10
+0+001c <[^>]*> srl r4,r4,r4
+0+0020 <[^>]*> srli r4,r4,5
diff --git a/gas/testsuite/gas/nios2/rotate.s b/gas/testsuite/gas/nios2/rotate.s
new file mode 100644
index 0000000000..a960e192b6
--- /dev/null
+++ b/gas/testsuite/gas/nios2/rotate.s
@@ -0,0 +1,13 @@
+# test Nios II rotate instructions
+
+.text
+foo:
+ rol r4,r4,r4
+ roli r4,r4,31
+ ror r4,r4,r4
+ sll r4,r4,r4
+ slli r4,r4,24
+ sra r4,r4,r4
+ srai r4,r4,10
+ srl r4,r4,r4
+ srli r4,r4,5
diff --git a/gas/testsuite/gas/nios2/stb.d b/gas/testsuite/gas/nios2/stb.d
new file mode 100644
index 0000000000..e3b48181f4
--- /dev/null
+++ b/gas/testsuite/gas/nios2/stb.d
@@ -0,0 +1,196 @@
+#objdump: -dr --prefix-addresses
+#name: NIOS2 stb
+
+# Test the ld instruction
+
+.*: +file format elf32-littlenios2
+
+Disassembly of section .text:
+0+0000 <[^>]*> stb r4,0\(zero\)
+0+0004 <[^>]*> stb r4,4\(zero\)
+0+0008 <[^>]*> stb r4,32764\(zero\)
+0+000c <[^>]*> stb r4,-32768\(zero\)
+0+0010 <[^>]*> stb r4,0\(r5\)
+0+0014 <[^>]*> stb r4,4\(r5\)
+0+0018 <[^>]*> stb r4,32764\(r5\)
+0+001c <[^>]*> stb r4,-32768\(r5\)
+0+0020 <[^>]*> stb r4,0\(zero\)
+[ ]*20: R_NIOS2_S16 .data
+0+0024 <[^>]*> stb r4,0\(zero\)
+[ ]*24: R_NIOS2_S16 big_external_data_label
+0+0028 <[^>]*> stb r4,0\(zero\)
+[ ]*28: R_NIOS2_S16 small_external_data_label
+0+002c <[^>]*> stb r4,0\(zero\)
+[ ]*2c: R_NIOS2_S16 big_external_common
+0+0030 <[^>]*> stb r4,0\(zero\)
+[ ]*30: R_NIOS2_S16 small_external_common
+0+0034 <[^>]*> stb r4,0\(zero\)
+[ ]*34: R_NIOS2_S16 .bss
+0+0038 <[^>]*> stb r4,0\(zero\)
+[ ]*38: R_NIOS2_S16 .bss\+0x4000
+0+003c <[^>]*> stb r4,0\(zero\)
+[ ]*3c: R_NIOS2_S16 .data\+0x4
+0+0040 <[^>]*> stb r4,0\(zero\)
+[ ]*40: R_NIOS2_S16 big_external_data_label\+0x4
+0+0044 <[^>]*> stb r4,0\(zero\)
+[ ]*44: R_NIOS2_S16 small_external_data_label\+0x4
+0+0048 <[^>]*> stb r4,0\(zero\)
+[ ]*48: R_NIOS2_S16 big_external_common\+0x4
+0+004c <[^>]*> stb r4,0\(zero\)
+[ ]*4c: R_NIOS2_S16 small_external_common\+0x4
+0+0050 <[^>]*> stb r4,0\(zero\)
+[ ]*50: R_NIOS2_S16 .bss\+0x4
+0+0054 <[^>]*> stb r4,0\(zero\)
+[ ]*54: R_NIOS2_S16 .bss\+0x4004
+0+0058 <[^>]*> stb r4,0\(zero\)
+[ ]*58: R_NIOS2_S16 .data-0x8000
+0+005c <[^>]*> stb r4,0\(zero\)
+[ ]*5c: R_NIOS2_S16 big_external_data_label-0x8000
+0+0060 <[^>]*> stb r4,0\(zero\)
+[ ]*60: R_NIOS2_S16 small_external_data_label-0x8000
+0+0064 <[^>]*> stb r4,0\(zero\)
+[ ]*64: R_NIOS2_S16 big_external_common-0x8000
+0+0068 <[^>]*> stb r4,0\(zero\)
+[ ]*68: R_NIOS2_S16 small_external_common-0x8000
+0+006c <[^>]*> stb r4,0\(zero\)
+[ ]*6c: R_NIOS2_S16 .bss-0x8000
+0+0070 <[^>]*> stb r4,0\(zero\)
+[ ]*70: R_NIOS2_S16 .bss-0x4000
+0+0074 <[^>]*> stb r4,0\(zero\)
+[ ]*74: R_NIOS2_S16 .data\+0x10000
+0+0078 <[^>]*> stb r4,0\(r5\)
+[ ]*78: R_NIOS2_S16 .data
+0+007c <[^>]*> stb r4,0\(r5\)
+[ ]*7c: R_NIOS2_S16 big_external_data_label
+0+0080 <[^>]*> stb r4,0\(r5\)
+[ ]*80: R_NIOS2_S16 small_external_data_label
+0+0084 <[^>]*> stb r4,0\(r5\)
+[ ]*84: R_NIOS2_S16 big_external_common
+0+0088 <[^>]*> stb r4,0\(r5\)
+[ ]*88: R_NIOS2_S16 small_external_common
+0+008c <[^>]*> stb r4,0\(r5\)
+[ ]*8c: R_NIOS2_S16 .bss
+0+0090 <[^>]*> stb r4,0\(r5\)
+[ ]*90: R_NIOS2_S16 .bss\+0x4000
+0+0094 <[^>]*> stb r4,0\(r5\)
+[ ]*94: R_NIOS2_S16 .data\+0x4
+0+0098 <[^>]*> stb r4,0\(r5\)
+[ ]*98: R_NIOS2_S16 big_external_data_label\+0x4
+0+009c <[^>]*> stb r4,0\(r5\)
+[ ]*9c: R_NIOS2_S16 small_external_data_label\+0x4
+0+00a0 <[^>]*> stb r4,0\(r5\)
+[ ]*a0: R_NIOS2_S16 big_external_common\+0x4
+0+00a4 <[^>]*> stb r4,0\(r5\)
+[ ]*a4: R_NIOS2_S16 small_external_common\+0x4
+0+00a8 <[^>]*> stb r4,0\(r5\)
+[ ]*a8: R_NIOS2_S16 .bss\+0x4
+0+00ac <[^>]*> stb r4,0\(r5\)
+[ ]*ac: R_NIOS2_S16 .bss\+0x4004
+0+00b0 <[^>]*> stb r4,0\(r5\)
+[ ]*b0: R_NIOS2_S16 .data-0x8000
+0+00b4 <[^>]*> stb r4,0\(r5\)
+[ ]*b4: R_NIOS2_S16 big_external_data_label-0x8000
+0+00b8 <[^>]*> stb r4,0\(r5\)
+[ ]*b8: R_NIOS2_S16 small_external_data_label-0x8000
+0+00bc <[^>]*> stb r4,0\(r5\)
+[ ]*bc: R_NIOS2_S16 big_external_common-0x8000
+0+00c0 <[^>]*> stb r4,0\(r5\)
+[ ]*c0: R_NIOS2_S16 small_external_common-0x8000
+0+00c4 <[^>]*> stb r4,0\(r5\)
+[ ]*c4: R_NIOS2_S16 .bss-0x8000
+0+00c8 <[^>]*> stb r4,0\(r5\)
+[ ]*c8: R_NIOS2_S16 .bss-0x4000
+0+00cc <[^>]*> stbio r4,0\(zero\)
+0+00d0 <[^>]*> stbio r4,4\(zero\)
+0+00d4 <[^>]*> stbio r4,32764\(zero\)
+0+00d8 <[^>]*> stbio r4,-32768\(zero\)
+0+00dc <[^>]*> stbio r4,0\(r5\)
+0+00e0 <[^>]*> stbio r4,4\(r5\)
+0+00e4 <[^>]*> stbio r4,32764\(r5\)
+0+00e8 <[^>]*> stbio r4,-32768\(r5\)
+0+00ec <[^>]*> stbio r4,0\(zero\)
+[ ]*ec: R_NIOS2_S16 .data
+0+00f0 <[^>]*> stbio r4,0\(zero\)
+[ ]*f0: R_NIOS2_S16 big_external_data_label
+0+00f4 <[^>]*> stbio r4,0\(zero\)
+[ ]*f4: R_NIOS2_S16 small_external_data_label
+0+00f8 <[^>]*> stbio r4,0\(zero\)
+[ ]*f8: R_NIOS2_S16 big_external_common
+0+00fc <[^>]*> stbio r4,0\(zero\)
+[ ]*fc: R_NIOS2_S16 small_external_common
+0+0100 <[^>]*> stbio r4,0\(zero\)
+[ ]*100: R_NIOS2_S16 .bss
+0+0104 <[^>]*> stbio r4,0\(zero\)
+[ ]*104: R_NIOS2_S16 .bss\+0x4000
+0+0108 <[^>]*> stbio r4,0\(zero\)
+[ ]*108: R_NIOS2_S16 .data\+0x4
+0+010c <[^>]*> stbio r4,0\(zero\)
+[ ]*10c: R_NIOS2_S16 big_external_data_label\+0x4
+0+0110 <[^>]*> stbio r4,0\(zero\)
+[ ]*110: R_NIOS2_S16 small_external_data_label\+0x4
+0+0114 <[^>]*> stbio r4,0\(zero\)
+[ ]*114: R_NIOS2_S16 big_external_common\+0x4
+0+0118 <[^>]*> stbio r4,0\(zero\)
+[ ]*118: R_NIOS2_S16 small_external_common\+0x4
+0+011c <[^>]*> stbio r4,0\(zero\)
+[ ]*11c: R_NIOS2_S16 .bss\+0x4
+0+0120 <[^>]*> stbio r4,0\(zero\)
+[ ]*120: R_NIOS2_S16 .bss\+0x4004
+0+0124 <[^>]*> stbio r4,0\(zero\)
+[ ]*124: R_NIOS2_S16 .data-0x8000
+0+0128 <[^>]*> stbio r4,0\(zero\)
+[ ]*128: R_NIOS2_S16 big_external_data_label-0x8000
+0+012c <[^>]*> stbio r4,0\(zero\)
+[ ]*12c: R_NIOS2_S16 small_external_data_label-0x8000
+0+0130 <[^>]*> stbio r4,0\(zero\)
+[ ]*130: R_NIOS2_S16 big_external_common-0x8000
+0+0134 <[^>]*> stbio r4,0\(zero\)
+[ ]*134: R_NIOS2_S16 small_external_common-0x8000
+0+0138 <[^>]*> stbio r4,0\(zero\)
+[ ]*138: R_NIOS2_S16 .bss-0x8000
+0+013c <[^>]*> stbio r4,0\(zero\)
+[ ]*13c: R_NIOS2_S16 .bss-0x4000
+0+0140 <[^>]*> stbio r4,0\(zero\)
+[ ]*140: R_NIOS2_S16 .data\+0x10000
+0+0144 <[^>]*> stbio r4,0\(r5\)
+[ ]*144: R_NIOS2_S16 .data
+0+0148 <[^>]*> stbio r4,0\(r5\)
+[ ]*148: R_NIOS2_S16 big_external_data_label
+0+014c <[^>]*> stbio r4,0\(r5\)
+[ ]*14c: R_NIOS2_S16 small_external_data_label
+0+0150 <[^>]*> stbio r4,0\(r5\)
+[ ]*150: R_NIOS2_S16 big_external_common
+0+0154 <[^>]*> stbio r4,0\(r5\)
+[ ]*154: R_NIOS2_S16 small_external_common
+0+0158 <[^>]*> stbio r4,0\(r5\)
+[ ]*158: R_NIOS2_S16 .bss
+0+015c <[^>]*> stbio r4,0\(r5\)
+[ ]*15c: R_NIOS2_S16 .bss\+0x4000
+0+0160 <[^>]*> stbio r4,0\(r5\)
+[ ]*160: R_NIOS2_S16 .data\+0x4
+0+0164 <[^>]*> stbio r4,0\(r5\)
+[ ]*164: R_NIOS2_S16 big_external_data_label\+0x4
+0+0168 <[^>]*> stbio r4,0\(r5\)
+[ ]*168: R_NIOS2_S16 small_external_data_label\+0x4
+0+016c <[^>]*> stbio r4,0\(r5\)
+[ ]*16c: R_NIOS2_S16 big_external_common\+0x4
+0+0170 <[^>]*> stbio r4,0\(r5\)
+[ ]*170: R_NIOS2_S16 small_external_common\+0x4
+0+0174 <[^>]*> stbio r4,0\(r5\)
+[ ]*174: R_NIOS2_S16 .bss\+0x4
+0+0178 <[^>]*> stbio r4,0\(r5\)
+[ ]*178: R_NIOS2_S16 .bss\+0x4004
+0+017c <[^>]*> stbio r4,0\(r5\)
+[ ]*17c: R_NIOS2_S16 .data-0x8000
+0+0180 <[^>]*> stbio r4,0\(r5\)
+[ ]*180: R_NIOS2_S16 big_external_data_label-0x8000
+0+0184 <[^>]*> stbio r4,0\(r5\)
+[ ]*184: R_NIOS2_S16 small_external_data_label-0x8000
+0+0188 <[^>]*> stbio r4,0\(r5\)
+[ ]*188: R_NIOS2_S16 big_external_common-0x8000
+0+018c <[^>]*> stbio r4,0\(r5\)
+[ ]*18c: R_NIOS2_S16 small_external_common-0x8000
+0+0190 <[^>]*> stbio r4,0\(r5\)
+[ ]*190: R_NIOS2_S16 .bss-0x8000
+0+0194 <[^>]*> stbio r4,0\(r5\)
+[ ]*194: R_NIOS2_S16 .bss-0x4000
diff --git a/gas/testsuite/gas/nios2/stb.s b/gas/testsuite/gas/nios2/stb.s
new file mode 100644
index 0000000000..8078e9413b
--- /dev/null
+++ b/gas/testsuite/gas/nios2/stb.s
@@ -0,0 +1,117 @@
+ .data
+data_label:
+ .extern big_external_data_label,0x4000
+ .extern small_external_data_label,4
+ .comm big_external_common,0x4000
+ .comm small_external_common,4
+ .lcomm big_local_common,0x4000
+ .lcomm small_local_common,4
+
+# the small symbols should have space allocated in the sbss section
+# but this is not yet supported in the assembler, so space is allocated
+# in the .bss section and the relocations are not gp-relative. this will
+# be updated when gp-relative relocations are added
+ .text
+ stb r4,0(r0)
+ stb r4,4(r0)
+ stb r4,0x7ffc(r0)
+ stb r4,-0x8000(r0)
+ stb r4,0(r5)
+ stb r4,4(r5)
+ stb r4,0x7ffc(r5)
+ stb r4,-0x8000(r5)
+ stb r4,data_label(r0)
+ stb r4,big_external_data_label(r0)
+ stb r4,small_external_data_label(r0)
+ stb r4,big_external_common(r0)
+ stb r4,small_external_common(r0)
+ stb r4,big_local_common(r0)
+ stb r4,small_local_common(r0)
+ stb r4,data_label+4(r0)
+ stb r4,big_external_data_label+4(r0)
+ stb r4,small_external_data_label+4(r0)
+ stb r4,big_external_common+4(r0)
+ stb r4,small_external_common+4(r0)
+ stb r4,big_local_common+4(r0)
+ stb r4,small_local_common+4(r0)
+ stb r4,data_label-0x8000(r0)
+ stb r4,big_external_data_label-0x8000(r0)
+ stb r4,small_external_data_label-0x8000(r0)
+ stb r4,big_external_common-0x8000(r0)
+ stb r4,small_external_common-0x8000(r0)
+ stb r4,big_local_common-0x8000(r0)
+ stb r4,small_local_common-0x8000(r0)
+ stb r4,data_label+0x10000(r0)
+ stb r4,data_label(r5)
+ stb r4,big_external_data_label(r5)
+ stb r4,small_external_data_label(r5)
+ stb r4,big_external_common(r5)
+ stb r4,small_external_common(r5)
+ stb r4,big_local_common(r5)
+ stb r4,small_local_common(r5)
+ stb r4,data_label+4(r5)
+ stb r4,big_external_data_label+4(r5)
+ stb r4,small_external_data_label+4(r5)
+ stb r4,big_external_common+4(r5)
+ stb r4,small_external_common+4(r5)
+ stb r4,big_local_common+4(r5)
+ stb r4,small_local_common+4(r5)
+ stb r4,data_label-0x8000(r5)
+ stb r4,big_external_data_label-0x8000(r5)
+ stb r4,small_external_data_label-0x8000(r5)
+ stb r4,big_external_common-0x8000(r5)
+ stb r4,small_external_common-0x8000(r5)
+ stb r4,big_local_common-0x8000(r5)
+ stb r4,small_local_common-0x8000(r5)
+
+ stbio r4,0(r0)
+ stbio r4,4(r0)
+ stbio r4,0x7ffc(r0)
+ stbio r4,-0x8000(r0)
+ stbio r4,0(r5)
+ stbio r4,4(r5)
+ stbio r4,0x7ffc(r5)
+ stbio r4,-0x8000(r5)
+ stbio r4,data_label(r0)
+ stbio r4,big_external_data_label(r0)
+ stbio r4,small_external_data_label(r0)
+ stbio r4,big_external_common(r0)
+ stbio r4,small_external_common(r0)
+ stbio r4,big_local_common(r0)
+ stbio r4,small_local_common(r0)
+ stbio r4,data_label+4(r0)
+ stbio r4,big_external_data_label+4(r0)
+ stbio r4,small_external_data_label+4(r0)
+ stbio r4,big_external_common+4(r0)
+ stbio r4,small_external_common+4(r0)
+ stbio r4,big_local_common+4(r0)
+ stbio r4,small_local_common+4(r0)
+ stbio r4,data_label-0x8000(r0)
+ stbio r4,big_external_data_label-0x8000(r0)
+ stbio r4,small_external_data_label-0x8000(r0)
+ stbio r4,big_external_common-0x8000(r0)
+ stbio r4,small_external_common-0x8000(r0)
+ stbio r4,big_local_common-0x8000(r0)
+ stbio r4,small_local_common-0x8000(r0)
+ stbio r4,data_label+0x10000(r0)
+ stbio r4,data_label(r5)
+ stbio r4,big_external_data_label(r5)
+ stbio r4,small_external_data_label(r5)
+ stbio r4,big_external_common(r5)
+ stbio r4,small_external_common(r5)
+ stbio r4,big_local_common(r5)
+ stbio r4,small_local_common(r5)
+ stbio r4,data_label+4(r5)
+ stbio r4,big_external_data_label+4(r5)
+ stbio r4,small_external_data_label+4(r5)
+ stbio r4,big_external_common+4(r5)
+ stbio r4,small_external_common+4(r5)
+ stbio r4,big_local_common+4(r5)
+ stbio r4,small_local_common+4(r5)
+ stbio r4,data_label-0x8000(r5)
+ stbio r4,big_external_data_label-0x8000(r5)
+ stbio r4,small_external_data_label-0x8000(r5)
+ stbio r4,big_external_common-0x8000(r5)
+ stbio r4,small_external_common-0x8000(r5)
+ stbio r4,big_local_common-0x8000(r5)
+ stbio r4,small_local_common-0x8000(r5)
diff --git a/gas/testsuite/gas/nios2/sth.d b/gas/testsuite/gas/nios2/sth.d
new file mode 100644
index 0000000000..76d58d4c85
--- /dev/null
+++ b/gas/testsuite/gas/nios2/sth.d
@@ -0,0 +1,196 @@
+#objdump: -dr --prefix-addresses
+#name: NIOS2 sth
+
+# Test the ld instruction
+
+.*: +file format elf32-littlenios2
+
+Disassembly of section .text:
+0+0000 <[^>]*> sth r4,0\(zero\)
+0+0004 <[^>]*> sth r4,4\(zero\)
+0+0008 <[^>]*> sth r4,32764\(zero\)
+0+000c <[^>]*> sth r4,-32768\(zero\)
+0+0010 <[^>]*> sth r4,0\(r5\)
+0+0014 <[^>]*> sth r4,4\(r5\)
+0+0018 <[^>]*> sth r4,32764\(r5\)
+0+001c <[^>]*> sth r4,-32768\(r5\)
+0+0020 <[^>]*> sth r4,0\(zero\)
+[ ]*20: R_NIOS2_S16 .data
+0+0024 <[^>]*> sth r4,0\(zero\)
+[ ]*24: R_NIOS2_S16 big_external_data_label
+0+0028 <[^>]*> sth r4,0\(zero\)
+[ ]*28: R_NIOS2_S16 small_external_data_label
+0+002c <[^>]*> sth r4,0\(zero\)
+[ ]*2c: R_NIOS2_S16 big_external_common
+0+0030 <[^>]*> sth r4,0\(zero\)
+[ ]*30: R_NIOS2_S16 small_external_common
+0+0034 <[^>]*> sth r4,0\(zero\)
+[ ]*34: R_NIOS2_S16 .bss
+0+0038 <[^>]*> sth r4,0\(zero\)
+[ ]*38: R_NIOS2_S16 .bss\+0x4000
+0+003c <[^>]*> sth r4,0\(zero\)
+[ ]*3c: R_NIOS2_S16 .data\+0x4
+0+0040 <[^>]*> sth r4,0\(zero\)
+[ ]*40: R_NIOS2_S16 big_external_data_label\+0x4
+0+0044 <[^>]*> sth r4,0\(zero\)
+[ ]*44: R_NIOS2_S16 small_external_data_label\+0x4
+0+0048 <[^>]*> sth r4,0\(zero\)
+[ ]*48: R_NIOS2_S16 big_external_common\+0x4
+0+004c <[^>]*> sth r4,0\(zero\)
+[ ]*4c: R_NIOS2_S16 small_external_common\+0x4
+0+0050 <[^>]*> sth r4,0\(zero\)
+[ ]*50: R_NIOS2_S16 .bss\+0x4
+0+0054 <[^>]*> sth r4,0\(zero\)
+[ ]*54: R_NIOS2_S16 .bss\+0x4004
+0+0058 <[^>]*> sth r4,0\(zero\)
+[ ]*58: R_NIOS2_S16 .data-0x8000
+0+005c <[^>]*> sth r4,0\(zero\)
+[ ]*5c: R_NIOS2_S16 big_external_data_label-0x8000
+0+0060 <[^>]*> sth r4,0\(zero\)
+[ ]*60: R_NIOS2_S16 small_external_data_label-0x8000
+0+0064 <[^>]*> sth r4,0\(zero\)
+[ ]*64: R_NIOS2_S16 big_external_common-0x8000
+0+0068 <[^>]*> sth r4,0\(zero\)
+[ ]*68: R_NIOS2_S16 small_external_common-0x8000
+0+006c <[^>]*> sth r4,0\(zero\)
+[ ]*6c: R_NIOS2_S16 .bss-0x8000
+0+0070 <[^>]*> sth r4,0\(zero\)
+[ ]*70: R_NIOS2_S16 .bss-0x4000
+0+0074 <[^>]*> sth r4,0\(zero\)
+[ ]*74: R_NIOS2_S16 .data\+0x10000
+0+0078 <[^>]*> sth r4,0\(r5\)
+[ ]*78: R_NIOS2_S16 .data
+0+007c <[^>]*> sth r4,0\(r5\)
+[ ]*7c: R_NIOS2_S16 big_external_data_label
+0+0080 <[^>]*> sth r4,0\(r5\)
+[ ]*80: R_NIOS2_S16 small_external_data_label
+0+0084 <[^>]*> sth r4,0\(r5\)
+[ ]*84: R_NIOS2_S16 big_external_common
+0+0088 <[^>]*> sth r4,0\(r5\)
+[ ]*88: R_NIOS2_S16 small_external_common
+0+008c <[^>]*> sth r4,0\(r5\)
+[ ]*8c: R_NIOS2_S16 .bss
+0+0090 <[^>]*> sth r4,0\(r5\)
+[ ]*90: R_NIOS2_S16 .bss\+0x4000
+0+0094 <[^>]*> sth r4,0\(r5\)
+[ ]*94: R_NIOS2_S16 .data\+0x4
+0+0098 <[^>]*> sth r4,0\(r5\)
+[ ]*98: R_NIOS2_S16 big_external_data_label\+0x4
+0+009c <[^>]*> sth r4,0\(r5\)
+[ ]*9c: R_NIOS2_S16 small_external_data_label\+0x4
+0+00a0 <[^>]*> sth r4,0\(r5\)
+[ ]*a0: R_NIOS2_S16 big_external_common\+0x4
+0+00a4 <[^>]*> sth r4,0\(r5\)
+[ ]*a4: R_NIOS2_S16 small_external_common\+0x4
+0+00a8 <[^>]*> sth r4,0\(r5\)
+[ ]*a8: R_NIOS2_S16 .bss\+0x4
+0+00ac <[^>]*> sth r4,0\(r5\)
+[ ]*ac: R_NIOS2_S16 .bss\+0x4004
+0+00b0 <[^>]*> sth r4,0\(r5\)
+[ ]*b0: R_NIOS2_S16 .data-0x8000
+0+00b4 <[^>]*> sth r4,0\(r5\)
+[ ]*b4: R_NIOS2_S16 big_external_data_label-0x8000
+0+00b8 <[^>]*> sth r4,0\(r5\)
+[ ]*b8: R_NIOS2_S16 small_external_data_label-0x8000
+0+00bc <[^>]*> sth r4,0\(r5\)
+[ ]*bc: R_NIOS2_S16 big_external_common-0x8000
+0+00c0 <[^>]*> sth r4,0\(r5\)
+[ ]*c0: R_NIOS2_S16 small_external_common-0x8000
+0+00c4 <[^>]*> sth r4,0\(r5\)
+[ ]*c4: R_NIOS2_S16 .bss-0x8000
+0+00c8 <[^>]*> sth r4,0\(r5\)
+[ ]*c8: R_NIOS2_S16 .bss-0x4000
+0+00cc <[^>]*> sthio r4,0\(zero\)
+0+00d0 <[^>]*> sthio r4,4\(zero\)
+0+00d4 <[^>]*> sthio r4,32764\(zero\)
+0+00d8 <[^>]*> sthio r4,-32768\(zero\)
+0+00dc <[^>]*> sthio r4,0\(r5\)
+0+00e0 <[^>]*> sthio r4,4\(r5\)
+0+00e4 <[^>]*> sthio r4,32764\(r5\)
+0+00e8 <[^>]*> sthio r4,-32768\(r5\)
+0+00ec <[^>]*> sthio r4,0\(zero\)
+[ ]*ec: R_NIOS2_S16 .data
+0+00f0 <[^>]*> sthio r4,0\(zero\)
+[ ]*f0: R_NIOS2_S16 big_external_data_label
+0+00f4 <[^>]*> sthio r4,0\(zero\)
+[ ]*f4: R_NIOS2_S16 small_external_data_label
+0+00f8 <[^>]*> sthio r4,0\(zero\)
+[ ]*f8: R_NIOS2_S16 big_external_common
+0+00fc <[^>]*> sthio r4,0\(zero\)
+[ ]*fc: R_NIOS2_S16 small_external_common
+0+0100 <[^>]*> sthio r4,0\(zero\)
+[ ]*100: R_NIOS2_S16 .bss
+0+0104 <[^>]*> sthio r4,0\(zero\)
+[ ]*104: R_NIOS2_S16 .bss\+0x4000
+0+0108 <[^>]*> sthio r4,0\(zero\)
+[ ]*108: R_NIOS2_S16 .data\+0x4
+0+010c <[^>]*> sthio r4,0\(zero\)
+[ ]*10c: R_NIOS2_S16 big_external_data_label\+0x4
+0+0110 <[^>]*> sthio r4,0\(zero\)
+[ ]*110: R_NIOS2_S16 small_external_data_label\+0x4
+0+0114 <[^>]*> sthio r4,0\(zero\)
+[ ]*114: R_NIOS2_S16 big_external_common\+0x4
+0+0118 <[^>]*> sthio r4,0\(zero\)
+[ ]*118: R_NIOS2_S16 small_external_common\+0x4
+0+011c <[^>]*> sthio r4,0\(zero\)
+[ ]*11c: R_NIOS2_S16 .bss\+0x4
+0+0120 <[^>]*> sthio r4,0\(zero\)
+[ ]*120: R_NIOS2_S16 .bss\+0x4004
+0+0124 <[^>]*> sthio r4,0\(zero\)
+[ ]*124: R_NIOS2_S16 .data-0x8000
+0+0128 <[^>]*> sthio r4,0\(zero\)
+[ ]*128: R_NIOS2_S16 big_external_data_label-0x8000
+0+012c <[^>]*> sthio r4,0\(zero\)
+[ ]*12c: R_NIOS2_S16 small_external_data_label-0x8000
+0+0130 <[^>]*> sthio r4,0\(zero\)
+[ ]*130: R_NIOS2_S16 big_external_common-0x8000
+0+0134 <[^>]*> sthio r4,0\(zero\)
+[ ]*134: R_NIOS2_S16 small_external_common-0x8000
+0+0138 <[^>]*> sthio r4,0\(zero\)
+[ ]*138: R_NIOS2_S16 .bss-0x8000
+0+013c <[^>]*> sthio r4,0\(zero\)
+[ ]*13c: R_NIOS2_S16 .bss-0x4000
+0+0140 <[^>]*> sthio r4,0\(zero\)
+[ ]*140: R_NIOS2_S16 .data\+0x10000
+0+0144 <[^>]*> sthio r4,0\(r5\)
+[ ]*144: R_NIOS2_S16 .data
+0+0148 <[^>]*> sthio r4,0\(r5\)
+[ ]*148: R_NIOS2_S16 big_external_data_label
+0+014c <[^>]*> sthio r4,0\(r5\)
+[ ]*14c: R_NIOS2_S16 small_external_data_label
+0+0150 <[^>]*> sthio r4,0\(r5\)
+[ ]*150: R_NIOS2_S16 big_external_common
+0+0154 <[^>]*> sthio r4,0\(r5\)
+[ ]*154: R_NIOS2_S16 small_external_common
+0+0158 <[^>]*> sthio r4,0\(r5\)
+[ ]*158: R_NIOS2_S16 .bss
+0+015c <[^>]*> sthio r4,0\(r5\)
+[ ]*15c: R_NIOS2_S16 .bss\+0x4000
+0+0160 <[^>]*> sthio r4,0\(r5\)
+[ ]*160: R_NIOS2_S16 .data\+0x4
+0+0164 <[^>]*> sthio r4,0\(r5\)
+[ ]*164: R_NIOS2_S16 big_external_data_label\+0x4
+0+0168 <[^>]*> sthio r4,0\(r5\)
+[ ]*168: R_NIOS2_S16 small_external_data_label\+0x4
+0+016c <[^>]*> sthio r4,0\(r5\)
+[ ]*16c: R_NIOS2_S16 big_external_common\+0x4
+0+0170 <[^>]*> sthio r4,0\(r5\)
+[ ]*170: R_NIOS2_S16 small_external_common\+0x4
+0+0174 <[^>]*> sthio r4,0\(r5\)
+[ ]*174: R_NIOS2_S16 .bss\+0x4
+0+0178 <[^>]*> sthio r4,0\(r5\)
+[ ]*178: R_NIOS2_S16 .bss\+0x4004
+0+017c <[^>]*> sthio r4,0\(r5\)
+[ ]*17c: R_NIOS2_S16 .data-0x8000
+0+0180 <[^>]*> sthio r4,0\(r5\)
+[ ]*180: R_NIOS2_S16 big_external_data_label-0x8000
+0+0184 <[^>]*> sthio r4,0\(r5\)
+[ ]*184: R_NIOS2_S16 small_external_data_label-0x8000
+0+0188 <[^>]*> sthio r4,0\(r5\)
+[ ]*188: R_NIOS2_S16 big_external_common-0x8000
+0+018c <[^>]*> sthio r4,0\(r5\)
+[ ]*18c: R_NIOS2_S16 small_external_common-0x8000
+0+0190 <[^>]*> sthio r4,0\(r5\)
+[ ]*190: R_NIOS2_S16 .bss-0x8000
+0+0194 <[^>]*> sthio r4,0\(r5\)
+[ ]*194: R_NIOS2_S16 .bss-0x4000
diff --git a/gas/testsuite/gas/nios2/sth.s b/gas/testsuite/gas/nios2/sth.s
new file mode 100644
index 0000000000..4b9390bb5c
--- /dev/null
+++ b/gas/testsuite/gas/nios2/sth.s
@@ -0,0 +1,117 @@
+ .data
+data_label:
+ .extern big_external_data_label,0x4000
+ .extern small_external_data_label,4
+ .comm big_external_common,0x4000
+ .comm small_external_common,4
+ .lcomm big_local_common,0x4000
+ .lcomm small_local_common,4
+
+# the small symbols should have space allocated in the sbss section
+# but this is not yet supported in the assembler, so space is allocated
+# in the .bss section and the relocations are not gp-relative. this will
+# be updated when gp-relative relocations are added
+ .text
+ sth r4,0(r0)
+ sth r4,4(r0)
+ sth r4,0x7ffc(r0)
+ sth r4,-0x8000(r0)
+ sth r4,0(r5)
+ sth r4,4(r5)
+ sth r4,0x7ffc(r5)
+ sth r4,-0x8000(r5)
+ sth r4,data_label(r0)
+ sth r4,big_external_data_label(r0)
+ sth r4,small_external_data_label(r0)
+ sth r4,big_external_common(r0)
+ sth r4,small_external_common(r0)
+ sth r4,big_local_common(r0)
+ sth r4,small_local_common(r0)
+ sth r4,data_label+4(r0)
+ sth r4,big_external_data_label+4(r0)
+ sth r4,small_external_data_label+4(r0)
+ sth r4,big_external_common+4(r0)
+ sth r4,small_external_common+4(r0)
+ sth r4,big_local_common+4(r0)
+ sth r4,small_local_common+4(r0)
+ sth r4,data_label-0x8000(r0)
+ sth r4,big_external_data_label-0x8000(r0)
+ sth r4,small_external_data_label-0x8000(r0)
+ sth r4,big_external_common-0x8000(r0)
+ sth r4,small_external_common-0x8000(r0)
+ sth r4,big_local_common-0x8000(r0)
+ sth r4,small_local_common-0x8000(r0)
+ sth r4,data_label+0x10000(r0)
+ sth r4,data_label(r5)
+ sth r4,big_external_data_label(r5)
+ sth r4,small_external_data_label(r5)
+ sth r4,big_external_common(r5)
+ sth r4,small_external_common(r5)
+ sth r4,big_local_common(r5)
+ sth r4,small_local_common(r5)
+ sth r4,data_label+4(r5)
+ sth r4,big_external_data_label+4(r5)
+ sth r4,small_external_data_label+4(r5)
+ sth r4,big_external_common+4(r5)
+ sth r4,small_external_common+4(r5)
+ sth r4,big_local_common+4(r5)
+ sth r4,small_local_common+4(r5)
+ sth r4,data_label-0x8000(r5)
+ sth r4,big_external_data_label-0x8000(r5)
+ sth r4,small_external_data_label-0x8000(r5)
+ sth r4,big_external_common-0x8000(r5)
+ sth r4,small_external_common-0x8000(r5)
+ sth r4,big_local_common-0x8000(r5)
+ sth r4,small_local_common-0x8000(r5)
+
+ sthio r4,0(r0)
+ sthio r4,4(r0)
+ sthio r4,0x7ffc(r0)
+ sthio r4,-0x8000(r0)
+ sthio r4,0(r5)
+ sthio r4,4(r5)
+ sthio r4,0x7ffc(r5)
+ sthio r4,-0x8000(r5)
+ sthio r4,data_label(r0)
+ sthio r4,big_external_data_label(r0)
+ sthio r4,small_external_data_label(r0)
+ sthio r4,big_external_common(r0)
+ sthio r4,small_external_common(r0)
+ sthio r4,big_local_common(r0)
+ sthio r4,small_local_common(r0)
+ sthio r4,data_label+4(r0)
+ sthio r4,big_external_data_label+4(r0)
+ sthio r4,small_external_data_label+4(r0)
+ sthio r4,big_external_common+4(r0)
+ sthio r4,small_external_common+4(r0)
+ sthio r4,big_local_common+4(r0)
+ sthio r4,small_local_common+4(r0)
+ sthio r4,data_label-0x8000(r0)
+ sthio r4,big_external_data_label-0x8000(r0)
+ sthio r4,small_external_data_label-0x8000(r0)
+ sthio r4,big_external_common-0x8000(r0)
+ sthio r4,small_external_common-0x8000(r0)
+ sthio r4,big_local_common-0x8000(r0)
+ sthio r4,small_local_common-0x8000(r0)
+ sthio r4,data_label+0x10000(r0)
+ sthio r4,data_label(r5)
+ sthio r4,big_external_data_label(r5)
+ sthio r4,small_external_data_label(r5)
+ sthio r4,big_external_common(r5)
+ sthio r4,small_external_common(r5)
+ sthio r4,big_local_common(r5)
+ sthio r4,small_local_common(r5)
+ sthio r4,data_label+4(r5)
+ sthio r4,big_external_data_label+4(r5)
+ sthio r4,small_external_data_label+4(r5)
+ sthio r4,big_external_common+4(r5)
+ sthio r4,small_external_common+4(r5)
+ sthio r4,big_local_common+4(r5)
+ sthio r4,small_local_common+4(r5)
+ sthio r4,data_label-0x8000(r5)
+ sthio r4,big_external_data_label-0x8000(r5)
+ sthio r4,small_external_data_label-0x8000(r5)
+ sthio r4,big_external_common-0x8000(r5)
+ sthio r4,small_external_common-0x8000(r5)
+ sthio r4,big_local_common-0x8000(r5)
+ sthio r4,small_local_common-0x8000(r5)
diff --git a/gas/testsuite/gas/nios2/stw.d b/gas/testsuite/gas/nios2/stw.d
new file mode 100644
index 0000000000..6dcf4e58e0
--- /dev/null
+++ b/gas/testsuite/gas/nios2/stw.d
@@ -0,0 +1,196 @@
+#objdump: -dr --prefix-addresses
+#name: NIOS2 stw
+
+# Test the ld instruction
+
+.*: +file format elf32-littlenios2
+
+Disassembly of section .text:
+0+0000 <[^>]*> stw r4,0\(zero\)
+0+0004 <[^>]*> stw r4,4\(zero\)
+0+0008 <[^>]*> stw r4,32764\(zero\)
+0+000c <[^>]*> stw r4,-32768\(zero\)
+0+0010 <[^>]*> stw r4,0\(r5\)
+0+0014 <[^>]*> stw r4,4\(r5\)
+0+0018 <[^>]*> stw r4,32764\(r5\)
+0+001c <[^>]*> stw r4,-32768\(r5\)
+0+0020 <[^>]*> stw r4,0\(zero\)
+[ ]*20: R_NIOS2_S16 .data
+0+0024 <[^>]*> stw r4,0\(zero\)
+[ ]*24: R_NIOS2_S16 big_external_data_label
+0+0028 <[^>]*> stw r4,0\(zero\)
+[ ]*28: R_NIOS2_S16 small_external_data_label
+0+002c <[^>]*> stw r4,0\(zero\)
+[ ]*2c: R_NIOS2_S16 big_external_common
+0+0030 <[^>]*> stw r4,0\(zero\)
+[ ]*30: R_NIOS2_S16 small_external_common
+0+0034 <[^>]*> stw r4,0\(zero\)
+[ ]*34: R_NIOS2_S16 .bss
+0+0038 <[^>]*> stw r4,0\(zero\)
+[ ]*38: R_NIOS2_S16 .bss\+0x4000
+0+003c <[^>]*> stw r4,0\(zero\)
+[ ]*3c: R_NIOS2_S16 .data\+0x4
+0+0040 <[^>]*> stw r4,0\(zero\)
+[ ]*40: R_NIOS2_S16 big_external_data_label\+0x4
+0+0044 <[^>]*> stw r4,0\(zero\)
+[ ]*44: R_NIOS2_S16 small_external_data_label\+0x4
+0+0048 <[^>]*> stw r4,0\(zero\)
+[ ]*48: R_NIOS2_S16 big_external_common\+0x4
+0+004c <[^>]*> stw r4,0\(zero\)
+[ ]*4c: R_NIOS2_S16 small_external_common\+0x4
+0+0050 <[^>]*> stw r4,0\(zero\)
+[ ]*50: R_NIOS2_S16 .bss\+0x4
+0+0054 <[^>]*> stw r4,0\(zero\)
+[ ]*54: R_NIOS2_S16 .bss\+0x4004
+0+0058 <[^>]*> stw r4,0\(zero\)
+[ ]*58: R_NIOS2_S16 .data-0x8000
+0+005c <[^>]*> stw r4,0\(zero\)
+[ ]*5c: R_NIOS2_S16 big_external_data_label-0x8000
+0+0060 <[^>]*> stw r4,0\(zero\)
+[ ]*60: R_NIOS2_S16 small_external_data_label-0x8000
+0+0064 <[^>]*> stw r4,0\(zero\)
+[ ]*64: R_NIOS2_S16 big_external_common-0x8000
+0+0068 <[^>]*> stw r4,0\(zero\)
+[ ]*68: R_NIOS2_S16 small_external_common-0x8000
+0+006c <[^>]*> stw r4,0\(zero\)
+[ ]*6c: R_NIOS2_S16 .bss-0x8000
+0+0070 <[^>]*> stw r4,0\(zero\)
+[ ]*70: R_NIOS2_S16 .bss-0x4000
+0+0074 <[^>]*> stw r4,0\(zero\)
+[ ]*74: R_NIOS2_S16 .data\+0x10000
+0+0078 <[^>]*> stw r4,0\(r5\)
+[ ]*78: R_NIOS2_S16 .data
+0+007c <[^>]*> stw r4,0\(r5\)
+[ ]*7c: R_NIOS2_S16 big_external_data_label
+0+0080 <[^>]*> stw r4,0\(r5\)
+[ ]*80: R_NIOS2_S16 small_external_data_label
+0+0084 <[^>]*> stw r4,0\(r5\)
+[ ]*84: R_NIOS2_S16 big_external_common
+0+0088 <[^>]*> stw r4,0\(r5\)
+[ ]*88: R_NIOS2_S16 small_external_common
+0+008c <[^>]*> stw r4,0\(r5\)
+[ ]*8c: R_NIOS2_S16 .bss
+0+0090 <[^>]*> stw r4,0\(r5\)
+[ ]*90: R_NIOS2_S16 .bss\+0x4000
+0+0094 <[^>]*> stw r4,0\(r5\)
+[ ]*94: R_NIOS2_S16 .data\+0x4
+0+0098 <[^>]*> stw r4,0\(r5\)
+[ ]*98: R_NIOS2_S16 big_external_data_label\+0x4
+0+009c <[^>]*> stw r4,0\(r5\)
+[ ]*9c: R_NIOS2_S16 small_external_data_label\+0x4
+0+00a0 <[^>]*> stw r4,0\(r5\)
+[ ]*a0: R_NIOS2_S16 big_external_common\+0x4
+0+00a4 <[^>]*> stw r4,0\(r5\)
+[ ]*a4: R_NIOS2_S16 small_external_common\+0x4
+0+00a8 <[^>]*> stw r4,0\(r5\)
+[ ]*a8: R_NIOS2_S16 .bss\+0x4
+0+00ac <[^>]*> stw r4,0\(r5\)
+[ ]*ac: R_NIOS2_S16 .bss\+0x4004
+0+00b0 <[^>]*> stw r4,0\(r5\)
+[ ]*b0: R_NIOS2_S16 .data-0x8000
+0+00b4 <[^>]*> stw r4,0\(r5\)
+[ ]*b4: R_NIOS2_S16 big_external_data_label-0x8000
+0+00b8 <[^>]*> stw r4,0\(r5\)
+[ ]*b8: R_NIOS2_S16 small_external_data_label-0x8000
+0+00bc <[^>]*> stw r4,0\(r5\)
+[ ]*bc: R_NIOS2_S16 big_external_common-0x8000
+0+00c0 <[^>]*> stw r4,0\(r5\)
+[ ]*c0: R_NIOS2_S16 small_external_common-0x8000
+0+00c4 <[^>]*> stw r4,0\(r5\)
+[ ]*c4: R_NIOS2_S16 .bss-0x8000
+0+00c8 <[^>]*> stw r4,0\(r5\)
+[ ]*c8: R_NIOS2_S16 .bss-0x4000
+0+00cc <[^>]*> stwio r4,0\(zero\)
+0+00d0 <[^>]*> stwio r4,4\(zero\)
+0+00d4 <[^>]*> stwio r4,32764\(zero\)
+0+00d8 <[^>]*> stwio r4,-32768\(zero\)
+0+00dc <[^>]*> stwio r4,0\(r5\)
+0+00e0 <[^>]*> stwio r4,4\(r5\)
+0+00e4 <[^>]*> stwio r4,32764\(r5\)
+0+00e8 <[^>]*> stwio r4,-32768\(r5\)
+0+00ec <[^>]*> stwio r4,0\(zero\)
+[ ]*ec: R_NIOS2_S16 .data
+0+00f0 <[^>]*> stwio r4,0\(zero\)
+[ ]*f0: R_NIOS2_S16 big_external_data_label
+0+00f4 <[^>]*> stwio r4,0\(zero\)
+[ ]*f4: R_NIOS2_S16 small_external_data_label
+0+00f8 <[^>]*> stwio r4,0\(zero\)
+[ ]*f8: R_NIOS2_S16 big_external_common
+0+00fc <[^>]*> stwio r4,0\(zero\)
+[ ]*fc: R_NIOS2_S16 small_external_common
+0+0100 <[^>]*> stwio r4,0\(zero\)
+[ ]*100: R_NIOS2_S16 .bss
+0+0104 <[^>]*> stwio r4,0\(zero\)
+[ ]*104: R_NIOS2_S16 .bss\+0x4000
+0+0108 <[^>]*> stwio r4,0\(zero\)
+[ ]*108: R_NIOS2_S16 .data\+0x4
+0+010c <[^>]*> stwio r4,0\(zero\)
+[ ]*10c: R_NIOS2_S16 big_external_data_label\+0x4
+0+0110 <[^>]*> stwio r4,0\(zero\)
+[ ]*110: R_NIOS2_S16 small_external_data_label\+0x4
+0+0114 <[^>]*> stwio r4,0\(zero\)
+[ ]*114: R_NIOS2_S16 big_external_common\+0x4
+0+0118 <[^>]*> stwio r4,0\(zero\)
+[ ]*118: R_NIOS2_S16 small_external_common\+0x4
+0+011c <[^>]*> stwio r4,0\(zero\)
+[ ]*11c: R_NIOS2_S16 .bss\+0x4
+0+0120 <[^>]*> stwio r4,0\(zero\)
+[ ]*120: R_NIOS2_S16 .bss\+0x4004
+0+0124 <[^>]*> stwio r4,0\(zero\)
+[ ]*124: R_NIOS2_S16 .data-0x8000
+0+0128 <[^>]*> stwio r4,0\(zero\)
+[ ]*128: R_NIOS2_S16 big_external_data_label-0x8000
+0+012c <[^>]*> stwio r4,0\(zero\)
+[ ]*12c: R_NIOS2_S16 small_external_data_label-0x8000
+0+0130 <[^>]*> stwio r4,0\(zero\)
+[ ]*130: R_NIOS2_S16 big_external_common-0x8000
+0+0134 <[^>]*> stwio r4,0\(zero\)
+[ ]*134: R_NIOS2_S16 small_external_common-0x8000
+0+0138 <[^>]*> stwio r4,0\(zero\)
+[ ]*138: R_NIOS2_S16 .bss-0x8000
+0+013c <[^>]*> stwio r4,0\(zero\)
+[ ]*13c: R_NIOS2_S16 .bss-0x4000
+0+0140 <[^>]*> stwio r4,0\(zero\)
+[ ]*140: R_NIOS2_S16 .data\+0x10000
+0+0144 <[^>]*> stwio r4,0\(r5\)
+[ ]*144: R_NIOS2_S16 .data
+0+0148 <[^>]*> stwio r4,0\(r5\)
+[ ]*148: R_NIOS2_S16 big_external_data_label
+0+014c <[^>]*> stwio r4,0\(r5\)
+[ ]*14c: R_NIOS2_S16 small_external_data_label
+0+0150 <[^>]*> stwio r4,0\(r5\)
+[ ]*150: R_NIOS2_S16 big_external_common
+0+0154 <[^>]*> stwio r4,0\(r5\)
+[ ]*154: R_NIOS2_S16 small_external_common
+0+0158 <[^>]*> stwio r4,0\(r5\)
+[ ]*158: R_NIOS2_S16 .bss
+0+015c <[^>]*> stwio r4,0\(r5\)
+[ ]*15c: R_NIOS2_S16 .bss\+0x4000
+0+0160 <[^>]*> stwio r4,0\(r5\)
+[ ]*160: R_NIOS2_S16 .data\+0x4
+0+0164 <[^>]*> stwio r4,0\(r5\)
+[ ]*164: R_NIOS2_S16 big_external_data_label\+0x4
+0+0168 <[^>]*> stwio r4,0\(r5\)
+[ ]*168: R_NIOS2_S16 small_external_data_label\+0x4
+0+016c <[^>]*> stwio r4,0\(r5\)
+[ ]*16c: R_NIOS2_S16 big_external_common\+0x4
+0+0170 <[^>]*> stwio r4,0\(r5\)
+[ ]*170: R_NIOS2_S16 small_external_common\+0x4
+0+0174 <[^>]*> stwio r4,0\(r5\)
+[ ]*174: R_NIOS2_S16 .bss\+0x4
+0+0178 <[^>]*> stwio r4,0\(r5\)
+[ ]*178: R_NIOS2_S16 .bss\+0x4004
+0+017c <[^>]*> stwio r4,0\(r5\)
+[ ]*17c: R_NIOS2_S16 .data-0x8000
+0+0180 <[^>]*> stwio r4,0\(r5\)
+[ ]*180: R_NIOS2_S16 big_external_data_label-0x8000
+0+0184 <[^>]*> stwio r4,0\(r5\)
+[ ]*184: R_NIOS2_S16 small_external_data_label-0x8000
+0+0188 <[^>]*> stwio r4,0\(r5\)
+[ ]*188: R_NIOS2_S16 big_external_common-0x8000
+0+018c <[^>]*> stwio r4,0\(r5\)
+[ ]*18c: R_NIOS2_S16 small_external_common-0x8000
+0+0190 <[^>]*> stwio r4,0\(r5\)
+[ ]*190: R_NIOS2_S16 .bss-0x8000
+0+0194 <[^>]*> stwio r4,0\(r5\)
+[ ]*194: R_NIOS2_S16 .bss-0x4000
diff --git a/gas/testsuite/gas/nios2/stw.s b/gas/testsuite/gas/nios2/stw.s
new file mode 100644
index 0000000000..fa5c72fdfa
--- /dev/null
+++ b/gas/testsuite/gas/nios2/stw.s
@@ -0,0 +1,117 @@
+ .data
+data_label:
+ .extern big_external_data_label,0x4000
+ .extern small_external_data_label,4
+ .comm big_external_common,0x4000
+ .comm small_external_common,4
+ .lcomm big_local_common,0x4000
+ .lcomm small_local_common,4
+
+# the small symbols should have space allocated in the sbss section
+# but this is not yet supported in the assembler, so space is allocated
+# in the .bss section and the relocations are not gp-relative. this will
+# be updated when gp-relative relocations are added
+ .text
+ stw r4,0(r0)
+ stw r4,4(r0)
+ stw r4,0x7ffc(r0)
+ stw r4,-0x8000(r0)
+ stw r4,0(r5)
+ stw r4,4(r5)
+ stw r4,0x7ffc(r5)
+ stw r4,-0x8000(r5)
+ stw r4,data_label(r0)
+ stw r4,big_external_data_label(r0)
+ stw r4,small_external_data_label(r0)
+ stw r4,big_external_common(r0)
+ stw r4,small_external_common(r0)
+ stw r4,big_local_common(r0)
+ stw r4,small_local_common(r0)
+ stw r4,data_label+4(r0)
+ stw r4,big_external_data_label+4(r0)
+ stw r4,small_external_data_label+4(r0)
+ stw r4,big_external_common+4(r0)
+ stw r4,small_external_common+4(r0)
+ stw r4,big_local_common+4(r0)
+ stw r4,small_local_common+4(r0)
+ stw r4,data_label-0x8000(r0)
+ stw r4,big_external_data_label-0x8000(r0)
+ stw r4,small_external_data_label-0x8000(r0)
+ stw r4,big_external_common-0x8000(r0)
+ stw r4,small_external_common-0x8000(r0)
+ stw r4,big_local_common-0x8000(r0)
+ stw r4,small_local_common-0x8000(r0)
+ stw r4,data_label+0x10000(r0)
+ stw r4,data_label(r5)
+ stw r4,big_external_data_label(r5)
+ stw r4,small_external_data_label(r5)
+ stw r4,big_external_common(r5)
+ stw r4,small_external_common(r5)
+ stw r4,big_local_common(r5)
+ stw r4,small_local_common(r5)
+ stw r4,data_label+4(r5)
+ stw r4,big_external_data_label+4(r5)
+ stw r4,small_external_data_label+4(r5)
+ stw r4,big_external_common+4(r5)
+ stw r4,small_external_common+4(r5)
+ stw r4,big_local_common+4(r5)
+ stw r4,small_local_common+4(r5)
+ stw r4,data_label-0x8000(r5)
+ stw r4,big_external_data_label-0x8000(r5)
+ stw r4,small_external_data_label-0x8000(r5)
+ stw r4,big_external_common-0x8000(r5)
+ stw r4,small_external_common-0x8000(r5)
+ stw r4,big_local_common-0x8000(r5)
+ stw r4,small_local_common-0x8000(r5)
+
+ stwio r4,0(r0)
+ stwio r4,4(r0)
+ stwio r4,0x7ffc(r0)
+ stwio r4,-0x8000(r0)
+ stwio r4,0(r5)
+ stwio r4,4(r5)
+ stwio r4,0x7ffc(r5)
+ stwio r4,-0x8000(r5)
+ stwio r4,data_label(r0)
+ stwio r4,big_external_data_label(r0)
+ stwio r4,small_external_data_label(r0)
+ stwio r4,big_external_common(r0)
+ stwio r4,small_external_common(r0)
+ stwio r4,big_local_common(r0)
+ stwio r4,small_local_common(r0)
+ stwio r4,data_label+4(r0)
+ stwio r4,big_external_data_label+4(r0)
+ stwio r4,small_external_data_label+4(r0)
+ stwio r4,big_external_common+4(r0)
+ stwio r4,small_external_common+4(r0)
+ stwio r4,big_local_common+4(r0)
+ stwio r4,small_local_common+4(r0)
+ stwio r4,data_label-0x8000(r0)
+ stwio r4,big_external_data_label-0x8000(r0)
+ stwio r4,small_external_data_label-0x8000(r0)
+ stwio r4,big_external_common-0x8000(r0)
+ stwio r4,small_external_common-0x8000(r0)
+ stwio r4,big_local_common-0x8000(r0)
+ stwio r4,small_local_common-0x8000(r0)
+ stwio r4,data_label+0x10000(r0)
+ stwio r4,data_label(r5)
+ stwio r4,big_external_data_label(r5)
+ stwio r4,small_external_data_label(r5)
+ stwio r4,big_external_common(r5)
+ stwio r4,small_external_common(r5)
+ stwio r4,big_local_common(r5)
+ stwio r4,small_local_common(r5)
+ stwio r4,data_label+4(r5)
+ stwio r4,big_external_data_label+4(r5)
+ stwio r4,small_external_data_label+4(r5)
+ stwio r4,big_external_common+4(r5)
+ stwio r4,small_external_common+4(r5)
+ stwio r4,big_local_common+4(r5)
+ stwio r4,small_local_common+4(r5)
+ stwio r4,data_label-0x8000(r5)
+ stwio r4,big_external_data_label-0x8000(r5)
+ stwio r4,small_external_data_label-0x8000(r5)
+ stwio r4,big_external_common-0x8000(r5)
+ stwio r4,small_external_common-0x8000(r5)
+ stwio r4,big_local_common-0x8000(r5)
+ stwio r4,small_local_common-0x8000(r5)
diff --git a/gas/testsuite/gas/nios2/sub.d b/gas/testsuite/gas/nios2/sub.d
new file mode 100644
index 0000000000..69b02856fe
--- /dev/null
+++ b/gas/testsuite/gas/nios2/sub.d
@@ -0,0 +1,10 @@
+#objdump: -dr --prefix-addresses
+#name: NIOS2 sub
+
+# Test the add instruction
+
+.*: +file format elf32-littlenios2
+
+Disassembly of section .text:
+0+0000 <[^>]*> sub r4,r4,r4
+
diff --git a/gas/testsuite/gas/nios2/sub.s b/gas/testsuite/gas/nios2/sub.s
new file mode 100644
index 0000000000..34f00da770
--- /dev/null
+++ b/gas/testsuite/gas/nios2/sub.s
@@ -0,0 +1,4 @@
+# Source file used to test the add and addi instructions.
+
+foo:
+ sub r4,r4,r4
diff --git a/gas/testsuite/gas/nios2/sync.d b/gas/testsuite/gas/nios2/sync.d
new file mode 100644
index 0000000000..f0949e2438
--- /dev/null
+++ b/gas/testsuite/gas/nios2/sync.d
@@ -0,0 +1,8 @@
+#objdump: -dr --prefix-addresses
+#name: NIOS2 sync
+
+.*: +file format elf32-littlenios2
+
+Disassembly of section \.text:
+0+0000 <foo> sync
+
diff --git a/gas/testsuite/gas/nios2/sync.s b/gas/testsuite/gas/nios2/sync.s
new file mode 100644
index 0000000000..fe05d47167
--- /dev/null
+++ b/gas/testsuite/gas/nios2/sync.s
@@ -0,0 +1,5 @@
+# Source file used to test the sync instructions
+foo:
+ sync
+
+
diff --git a/gas/testsuite/gas/nios2/trap.d b/gas/testsuite/gas/nios2/trap.d
new file mode 100644
index 0000000000..003ff69a58
--- /dev/null
+++ b/gas/testsuite/gas/nios2/trap.d
@@ -0,0 +1,7 @@
+#objdump: -dr --prefix-addresses
+#name: NIOS2 trap
+
+.*: +file format elf32-littlenios2
+
+Disassembly of section .text:
+0+0000 <[^>]*> trap
diff --git a/gas/testsuite/gas/nios2/trap.s b/gas/testsuite/gas/nios2/trap.s
new file mode 100644
index 0000000000..1eb3c7e890
--- /dev/null
+++ b/gas/testsuite/gas/nios2/trap.s
@@ -0,0 +1,3 @@
+# Source file used to test the ret instructions
+foo:
+ trap
diff --git a/gas/testsuite/gas/nios2/tret.d b/gas/testsuite/gas/nios2/tret.d
new file mode 100644
index 0000000000..48e2b51989
--- /dev/null
+++ b/gas/testsuite/gas/nios2/tret.d
@@ -0,0 +1,8 @@
+#objdump: -dr --prefix-addresses
+#name: NIOS2 tret
+
+.*: +file format elf32-littlenios2
+
+Disassembly of section .text:
+0+0000 <[^>]*> eret
+
diff --git a/gas/testsuite/gas/nios2/tret.s b/gas/testsuite/gas/nios2/tret.s
new file mode 100644
index 0000000000..42179f1fe1
--- /dev/null
+++ b/gas/testsuite/gas/nios2/tret.s
@@ -0,0 +1,5 @@
+# Source file used to test the ret instructions
+foo:
+ eret
+
+
diff --git a/gas/testsuite/gas/nios2/warn_noat.l b/gas/testsuite/gas/nios2/warn_noat.l
new file mode 100644
index 0000000000..6bc5150f88
--- /dev/null
+++ b/gas/testsuite/gas/nios2/warn_noat.l
@@ -0,0 +1,5 @@
+.*warn_noat.s: Assembler messages:
+.*warn_noat.s:2: Warning: Register at \(r1\) can sometimes be corrupted by assembler optimizations.
+Use .set noat to turn off those optimizations \(and this warning\).
+.*warn_noat.s:8: Warning: Register at \(r1\) can sometimes be corrupted by assembler optimizations.
+Use .set noat to turn off those optimizations \(and this warning\).
diff --git a/gas/testsuite/gas/nios2/warn_noat.s b/gas/testsuite/gas/nios2/warn_noat.s
new file mode 100644
index 0000000000..e99126e6f0
--- /dev/null
+++ b/gas/testsuite/gas/nios2/warn_noat.s
@@ -0,0 +1,8 @@
+.set noat, 2 # This should not cause warning for at to be turned off
+add at, r2, r2
+.set noat # this should turn the warnings off
+add at, r2, r2
+.set at, 3 # this should not turn the warnings on
+add at, r2, r2
+.set at # this should turn the warnings on
+add at, r2, r2
diff --git a/gas/testsuite/gas/nios2/warn_nobreak.l b/gas/testsuite/gas/nios2/warn_nobreak.l
new file mode 100644
index 0000000000..539813d683
--- /dev/null
+++ b/gas/testsuite/gas/nios2/warn_nobreak.l
@@ -0,0 +1,9 @@
+.*warn_nobreak.s: Assembler messages:
+.*warn_nobreak.s:2: Warning: The debugger will corrupt ba \(r30\). If you don't need to debug this
+code then use .set nobreak to turn off this warning.
+.*warn_nobreak.s:3: Warning: The debugger will corrupt bt \(r25\). If you don't need to debug this
+code then use .set nobreak to turn off this warning.
+.*warn_nobreak.s:11: Warning: The debugger will corrupt ba \(r30\). If you don't need to debug this
+code then use .set nobreak to turn off this warning.
+.*warn_nobreak.s:12: Warning: The debugger will corrupt bt \(r25\). If you don't need to debug this
+code then use .set nobreak to turn off this warning.
diff --git a/gas/testsuite/gas/nios2/warn_nobreak.s b/gas/testsuite/gas/nios2/warn_nobreak.s
new file mode 100644
index 0000000000..8e495c06de
--- /dev/null
+++ b/gas/testsuite/gas/nios2/warn_nobreak.s
@@ -0,0 +1,12 @@
+.set nobreak , 2 # This should not cause warning for ba, bt to be turned off
+add ba, r2, r2
+add bt, r2, r2
+.set nobreak # this should turn the warnings off
+add ba, r3, r4
+add bt, r3, r4
+.set break, 3 # this should not turn the warnings on
+add ba, r3, r4
+add bt, r3, r4
+.set break # this should turn the warnings on
+add ba, r3, r4
+add bt, r3, r4
diff --git a/gas/testsuite/gas/nios2/xor.d b/gas/testsuite/gas/nios2/xor.d
new file mode 100644
index 0000000000..de137dc3ab
--- /dev/null
+++ b/gas/testsuite/gas/nios2/xor.d
@@ -0,0 +1,11 @@
+#objdump: -dr --prefix-addresses
+#name: NIOS2 xor
+
+# Test the nor instruction
+
+.*: +file format elf32-littlenios2
+
+Disassembly of section .text:
+0+0000 <[^>]*> xor r6,r8,r10
+0+0004 <[^>]*> xorhi r6,r7,65535
+0+0008 <[^>]*> xori r6,r7,65535
diff --git a/gas/testsuite/gas/nios2/xor.s b/gas/testsuite/gas/nios2/xor.s
new file mode 100644
index 0000000000..2c558f77f0
--- /dev/null
+++ b/gas/testsuite/gas/nios2/xor.s
@@ -0,0 +1,7 @@
+# Source file used to test the nor instruction
+
+foo:
+ xor r6,r8,r10
+ xorhi r6,r7,0xffff
+ xori r6,r7,0xffff
+
OpenPOWER on IntegriCloud