diff options
Diffstat (limited to 'gas')
99 files changed, 6534 insertions, 3 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index d064176..01ac44d 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 7729d4a..5ed9d2a 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 c2a646c..c71e284 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 @@ -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 6450328..3377261 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 0000000..841c454 --- /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 0000000..9e69194 --- /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 8454ab9..9d498e8 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 b200378..3d1e933 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 9969ff4..4c3c4fb 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 b213ad7..99dbf8f 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 c976c05..cafcb22 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 0000000..1d45dd2 --- /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 ab91689..e165af4 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 0000000..ba3d27f --- /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 0000000..5b72a82 --- /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 0000000..90a9e5f --- /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 0000000..5683839 --- /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 0000000..80611e7 --- /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 0000000..d073b6f --- /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 0000000..350ca69 --- /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 0000000..946a8b8 --- /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 0000000..08d20f3 --- /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 0000000..0853167 --- /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 0000000..be487bb --- /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 0000000..88d3422 --- /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 0000000..a12530b --- /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 0000000..d368e64 --- /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 0000000..7c278d8 --- /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 0000000..1701c19 --- /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 0000000..cfa6aec --- /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 0000000..39409b7 --- /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 0000000..63364ef --- /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 0000000..dd128a7 --- /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 0000000..43d9d68 --- /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 0000000..6f7c15b --- /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 0000000..890dcc2 --- /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 0000000..7ab2027 --- /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 0000000..f32115b --- /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 0000000..65141f9 --- /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 0000000..f698ce6 --- /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 0000000..dc6c983 --- /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 0000000..c1e17be --- /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 0000000..903122a --- /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 0000000..58b8e32 --- /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 0000000..3e5fc24 --- /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 0000000..f3b5e3e --- /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 0000000..3a32474 --- /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 0000000..6248567 --- /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 0000000..75b6d89 --- /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 0000000..b8727b3 --- /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 0000000..8d859f2 --- /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 0000000..5a417b8 --- /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 0000000..71c51f1 --- /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 0000000..f030eef --- /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 0000000..87040ee --- /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 0000000..dc2571e --- /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 0000000..cf6de19 --- /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 0000000..09c66ea --- /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 0000000..d16efc3 --- /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 0000000..13bf6db --- /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 0000000..a66aaeb --- /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 0000000..9e35c7b --- /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 0000000..07d9fed --- /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 0000000..c255ace --- /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 0000000..fe1d56c --- /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 0000000..79e86d1 --- /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 0000000..3e47bc7 --- /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 0000000..9390e8b --- /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 0000000..fab8e69 --- /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 0000000..da78254 --- /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 0000000..e5035bc --- /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 0000000..675df17 --- /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 0000000..b071931 --- /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 0000000..69b76bc --- /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 0000000..2128dd5 --- /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 0000000..988d702 --- /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 0000000..0f54f43 --- /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 0000000..a960e19 --- /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 0000000..e3b4818 --- /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 0000000..8078e94 --- /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 0000000..76d58d4 --- /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 0000000..4b9390b --- /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 0000000..6dcf4e5 --- /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 0000000..fa5c72f --- /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 0000000..69b0285 --- /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 0000000..34f00da --- /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 0000000..f0949e2 --- /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 0000000..fe05d47 --- /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 0000000..003ff69 --- /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 0000000..1eb3c7e --- /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 0000000..48e2b51 --- /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 0000000..42179f1 --- /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 0000000..6bc5150 --- /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 0000000..e99126e --- /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 0000000..539813d --- /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 0000000..8e495c0 --- /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 0000000..de137dc --- /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 0000000..2c558f7 --- /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 + |