/* 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_ds (nios2_insn_infoS * insn_info)
{
  if (insn_info->insn_tokens[1] != NULL && insn_info->insn_tokens[2] != NULL)
    {
      struct nios2_reg *dst = nios2_reg_lookup (insn_info->insn_tokens[1]);
      struct nios2_reg *src = nios2_reg_lookup (insn_info->insn_tokens[2]);

      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 (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},
  {"d,s", nios2_assemble_args_ds},
  {"d,s,E", nios2_assemble_args_ds},
  {"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 'l':
    case 'b':
      /* We can't have %hi, %lo or %hiadj here.  */
      if (*argstr == '%')
	as_bad (_("badly formed expression near %s"), argstr);
      break;
    case 'o':
      break;
    default:
      BAD_CASE (*parsestr);
      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);
}
