/* 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);
}
