/* Altera Nios II assembler.
   Copyright (C) 2012-2015 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;

  /* Constant bits masked into insn_code for self-check mode.  */
  unsigned long constant_bits;
  
  /* 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 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)))


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


/* 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 fr_var (4 for 32-bit insns) because all pc relative
	 branches are from the next instruction.  */
      offset = target - fragp->fr_address - fragp->fr_fix - fragp->fr_var;
      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;
      unsigned int old_op, new_op;
      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);
      old_op = GET_IW_R1_OP (br_opcode);
      switch (old_op)
	{
	case R1_OP_BEQ:
	  new_op = R1_OP_BNE;
	  break;
	case R1_OP_BNE:
	  new_op = R1_OP_BEQ;
	  break;
	case R1_OP_BGE:
	  new_op = R1_OP_BLT;
	  break;
	case R1_OP_BGEU:
	  new_op = R1_OP_BLTU;
	  break;
	case R1_OP_BLT:
	  new_op = R1_OP_BGE;
	  break;
	case R1_OP_BLTU:
	  new_op = R1_OP_BGEU;
	  break;
	default:
	  as_bad_where (fragp->fr_file, fragp->fr_line,
			_("expecting conditional branch for relaxation\n"));
	  abort ();
	}

      br_opcode = (br_opcode & ~IW_R1_OP_SHIFTED_MASK) | SET_IW_R1_OP (new_op);
      br_opcode = br_opcode | SET_IW_I_IMM16 (nbytes);
      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,
			  MATCH_R1_NEXTPC | SET_IW_R_C (AT_REGNUM), 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 = SET_IW_I_IMM16 ((unsigned int)addend);

      /* Insert n-1 addi instructions.  */
      addi_mask = (MATCH_R1_ADDI
		   | SET_IW_I_B (AT_REGNUM)
		   | SET_IW_I_A (AT_REGNUM));
      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 = SET_IW_I_IMM16 ((unsigned int)remainder);
      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,
			  (MATCH_R1_ORHI | SET_IW_I_B (AT_REGNUM)
			   | SET_IW_I_A (0)),
			  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,
			  (MATCH_R1_ORI | SET_IW_I_B (AT_REGNUM)
			   | SET_IW_I_A (AT_REGNUM)),
			  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, MATCH_R1_JMP | SET_IW_R_A (AT_REGNUM), 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;

      opcode = nios2_find_opcode_hash (value, bfd_get_mach (stdoutput));
      gas_assert (opcode);
      gas_assert (fixP->fx_size == opcode->size);
      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
		  || fixP->fx_r_type == BFD_RELOC_NIOS2_CALL26_NOAT
		  || fixP->fx_r_type == BFD_RELOC_NIOS2_GOT_LO
		  || fixP->fx_r_type == BFD_RELOC_NIOS2_GOT_HA
		  || fixP->fx_r_type == BFD_RELOC_NIOS2_CALL_LO
		  || fixP->fx_r_type == BFD_RELOC_NIOS2_CALL_HA
		  /* 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
			     + fixP->fx_size);

	  /* 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))
		       & 0xFFFF);
	      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. */

/* General internal error routine.  */

static void
bad_opcode (const struct nios2_opcode *op)
{
  fprintf (stderr, _("internal error: broken opcode descriptor for `%s %s'\n"),
	   op->name, op->args);
  as_fatal (_("Broken assembler.  No assembly attempted."));
}

/* Special relocation directive strings.  */

struct nios2_special_relocS
{
  const char *string;
  bfd_reloc_code_real_type reloc_type;
};

/* This table is sorted so that prefix strings are listed after the longer
   strings that include them -- e.g., %got after %got_hiadj, etc.  */

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_lo", BFD_RELOC_NIOS2_CALL_LO},
  {"%call_hiadj", BFD_RELOC_NIOS2_CALL_HA},
  {"%call", BFD_RELOC_NIOS2_CALL16},
  {"%gotoff_lo", BFD_RELOC_NIOS2_GOTOFF_LO},
  {"%gotoff_hiadj", BFD_RELOC_NIOS2_GOTOFF_HA},
  {"%gotoff", BFD_RELOC_NIOS2_GOTOFF},
  {"%got_hiadj", BFD_RELOC_NIOS2_GOT_HA},
  {"%got_lo", BFD_RELOC_NIOS2_GOT_LO},
  {"%got", BFD_RELOC_NIOS2_GOT16},
  {"%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},
};

#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

/* Look up a register name and validate it for the given regtype.
   Return the register mapping or NULL on failure.  */
static struct nios2_reg *
nios2_parse_reg (const char *token, unsigned long regtype)
{
  struct nios2_reg *reg = nios2_reg_lookup (token);

  if (reg == NULL)
    {
      as_bad (_("unknown register %s"), token);
      return NULL;
    }

  /* Matched a register, but is it the wrong type?  */
  if (!(regtype & reg->regtype))
    {
      if (regtype & REG_CONTROL)
	as_bad (_("expecting control register"));
      else if (reg->regtype & REG_CONTROL)
	as_bad (_("illegal use of control register"));
      else if (reg->regtype & REG_COPROCESSOR)
	as_bad (_("illegal use of coprocessor register"));
      else
	as_bad (_("invalid register %s"), token);
      return NULL;
    }

  /* Warn for explicit use of special registers.  */
  if (reg->regtype & REG_NORMAL)
    {
      if (!nios2_as_options.noat && reg->index == 1)
	as_warn (_("Register at (r1) can sometimes be corrupted by "
		   "assembler optimizations.\n"
		   "Use .set noat to turn off those optimizations "
		   "(and this warning)."));
      if (!nios2_as_options.nobreak && reg->index == 25)
	as_warn (_("The debugger will corrupt bt (r25).\n"
		   "If you don't need to debug this "
		   "code use .set nobreak to turn off this warning."));
      if (!nios2_as_options.nobreak && reg->index == 30)
	as_warn (_("The debugger will corrupt sstatus/ba (r30).\n"
		   "If you don't need to debug this "
		   "code use .set nobreak to turn off this warning."));
    }

  return reg;
}

/* 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,
			   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);
  reloc->reloc_next = insn->insn_reloc;
  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.  */
static void 
nios2_assemble_arg_c (const char *token, nios2_insn_infoS *insn)
{
  struct nios2_reg *reg = nios2_parse_reg (token, REG_CONTROL);
  const struct nios2_opcode *op = insn->insn_nios2_opcode;

  if (reg == NULL)
    return;

  switch (op->format)
    {
    case iw_r_type:
      insn->insn_code |= SET_IW_R_IMM5 (reg->index);
      break;
    default:
      bad_opcode (op);
    }
}

static void 
nios2_assemble_arg_d (const char *token, nios2_insn_infoS *insn)
{
  const struct nios2_opcode *op = insn->insn_nios2_opcode;
  unsigned long regtype = REG_NORMAL;
  struct nios2_reg *reg;

  if (op->format == iw_custom_type)
    regtype |= REG_COPROCESSOR;
  reg = nios2_parse_reg (token, regtype);
  if (reg == NULL)
    return;

  switch (op->format)
    {
    case iw_r_type:
      insn->insn_code |= SET_IW_R_C (reg->index);
      break;
    case iw_custom_type:
      insn->insn_code |= SET_IW_CUSTOM_C (reg->index);
      if (reg->regtype & REG_COPROCESSOR)
	insn->insn_code |= SET_IW_CUSTOM_READC (0);
      else
	insn->insn_code |= SET_IW_CUSTOM_READC (1);
      break;
    default:
      bad_opcode (op);
    }
}

static void 
nios2_assemble_arg_s (const char *token, nios2_insn_infoS *insn)
{
  const struct nios2_opcode *op = insn->insn_nios2_opcode;
  unsigned long regtype = REG_NORMAL;
  struct nios2_reg *reg;

  if (op->format == iw_custom_type)
    regtype |= REG_COPROCESSOR;
  reg = nios2_parse_reg (token, regtype);
  if (reg == NULL)
    return;

  switch (op->format)
    {
    case iw_r_type:
      insn->insn_code |= SET_IW_R_A (reg->index);
      break;
    case iw_i_type:
      insn->insn_code |= SET_IW_I_A (reg->index);
      break;
    case iw_custom_type:
      insn->insn_code |= SET_IW_CUSTOM_A (reg->index);
      if (reg->regtype & REG_COPROCESSOR)
	insn->insn_code |= SET_IW_CUSTOM_READA (0);
      else
	insn->insn_code |= SET_IW_CUSTOM_READA (1);
      break;
    default:
      bad_opcode (op);
    }
}

static void 
nios2_assemble_arg_t (const char *token, nios2_insn_infoS *insn)
{
  const struct nios2_opcode *op = insn->insn_nios2_opcode;
  unsigned long regtype = REG_NORMAL;
  struct nios2_reg *reg;

  if (op->format == iw_custom_type)
    regtype |= REG_COPROCESSOR;
  reg = nios2_parse_reg (token, regtype);
  if (reg == NULL)
    return;

  switch (op->format)
    {
    case iw_r_type:
      insn->insn_code |= SET_IW_R_B (reg->index);
      break;
    case iw_i_type:
      insn->insn_code |= SET_IW_I_B (reg->index);
      break;
    case iw_custom_type:
      insn->insn_code |= SET_IW_CUSTOM_B (reg->index);
      if (reg->regtype & REG_COPROCESSOR)
	insn->insn_code |= SET_IW_CUSTOM_READB (0);
      else
	insn->insn_code |= SET_IW_CUSTOM_READB (1);
      break;
    default:
      bad_opcode (op);
    }
}

static void 
nios2_assemble_arg_i (const char *token, nios2_insn_infoS *insn)
{
  const struct nios2_opcode *op = insn->insn_nios2_opcode;
  unsigned int val;

  switch (op->format)
    {
    case iw_i_type:
      val = nios2_assemble_expression (token, insn,
				       BFD_RELOC_NIOS2_S16, 0);
      insn->constant_bits |= SET_IW_I_IMM16 (val);
      break;
    default:
      bad_opcode (op);
    }
}

static void 
nios2_assemble_arg_u (const char *token, nios2_insn_infoS *insn)
{
  const struct nios2_opcode *op = insn->insn_nios2_opcode;
  unsigned int val;

  switch (op->format)
    {
    case iw_i_type:
      val = nios2_assemble_expression (token, insn,
				       BFD_RELOC_NIOS2_U16, 0);
      insn->constant_bits |= SET_IW_I_IMM16 (val);
      break;
    default:
      bad_opcode (op);
    }
}

static void 
nios2_assemble_arg_o (const char *token, nios2_insn_infoS *insn)
{
  const struct nios2_opcode *op = insn->insn_nios2_opcode;
  unsigned int val;

  switch (op->format)
    {
    case iw_i_type:
      val = nios2_assemble_expression (token, insn,
				       BFD_RELOC_16_PCREL, 1);
      insn->constant_bits |= SET_IW_I_IMM16 (val);
      break;
    default:
      bad_opcode (op);
    }
}

static void 
nios2_assemble_arg_j (const char *token, nios2_insn_infoS *insn)
{
  const struct nios2_opcode *op = insn->insn_nios2_opcode;
  unsigned int val;

  switch (op->format)
    {
    case iw_r_type:
      val = nios2_assemble_expression (token, insn,
				       BFD_RELOC_NIOS2_IMM5, 0);
      insn->constant_bits |= SET_IW_R_IMM5 (val);
      break;
    default:
      bad_opcode (op);
    }
}

static void 
nios2_assemble_arg_l (const char *token, nios2_insn_infoS *insn)
{
  const struct nios2_opcode *op = insn->insn_nios2_opcode;
  unsigned int val;

  switch (op->format)
    {
    case iw_custom_type:
      val = nios2_assemble_expression (token, insn,
				       BFD_RELOC_NIOS2_IMM8, 0);
      insn->constant_bits |= SET_IW_CUSTOM_N (val);
      break;
    default:
      bad_opcode (op);
    }
}

static void 
nios2_assemble_arg_m (const char *token, nios2_insn_infoS *insn)
{
  const struct nios2_opcode *op = insn->insn_nios2_opcode;
  unsigned int val;

  switch (op->format)
    {
    case iw_j_type:
      val = nios2_assemble_expression (token, insn,
				       (nios2_as_options.noat
					? BFD_RELOC_NIOS2_CALL26_NOAT
					: BFD_RELOC_NIOS2_CALL26),
				       0);
      insn->constant_bits |= SET_IW_J_IMM26 (val);
      break;
    default:
      bad_opcode (op);
    }
}

static void
nios2_assemble_args (nios2_insn_infoS *insn)
{
  const struct nios2_opcode *op = insn->insn_nios2_opcode;
  const char *argptr;
  unsigned int tokidx, ntok;

  /* Make sure there are enough arguments.  */
  ntok = (op->pinfo & NIOS2_INSN_OPTARG) ? op->num_args - 1 : op->num_args;
  for (tokidx = 1; tokidx <= ntok; tokidx++)
    if (insn->insn_tokens[tokidx] == NULL)
      {
	as_bad ("missing argument");
	return;
      }

  for (argptr = op->args, tokidx = 1;
       *argptr && insn->insn_tokens[tokidx];
       argptr++)
    switch (*argptr)
      {
      case ',':
      case '(':
      case ')':
	break;

      case 'c':
	nios2_assemble_arg_c (insn->insn_tokens[tokidx++], insn);
	break;
	
      case 'd':
	nios2_assemble_arg_d (insn->insn_tokens[tokidx++], insn);
	break;
	
      case 's':
	nios2_assemble_arg_s (insn->insn_tokens[tokidx++], insn);
	break;
	
      case 't':
	nios2_assemble_arg_t (insn->insn_tokens[tokidx++], insn);
	break;
	
      case 'i':
	nios2_assemble_arg_i (insn->insn_tokens[tokidx++], insn);
	break;
	
      case 'u':
	nios2_assemble_arg_u (insn->insn_tokens[tokidx++], insn);
	break;
	
      case 'o':
	nios2_assemble_arg_o (insn->insn_tokens[tokidx++], insn);
	break;
	
      case 'j':
	nios2_assemble_arg_j (insn->insn_tokens[tokidx++], insn);
	break;
	
      case 'l':
	nios2_assemble_arg_l (insn->insn_tokens[tokidx++], insn);
	break;
	
      case 'm':
	nios2_assemble_arg_m (insn->insn_tokens[tokidx++], insn);
	break;
	
      default:
	bad_opcode (op);
	break;
      }

  /* Perform argument checking.  */  
  nios2_check_assembly (insn->insn_code | insn->constant_bits,
			insn->insn_tokens[tokidx]);
}


/* 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 (char *argstr, const char *parsestr)
{
  char *temp;
  
  switch (*parsestr)
    {
    case 'c':
    case 'd':
    case 's':
    case 't':
      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':
      /* We can't have %hi, %lo or %hiadj here.  */
      if (*argstr == '%')
	as_bad (_("badly formed expression near %s"), argstr);
      break;
    case 'o':
    case 'E':
      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;
  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 (p, parsestr);
      ++parsestr;
      while (*parsestr == '(' || *parsestr == ')' || *parsestr == ',')
	{
	  char *context = p;
	  p = nios2_consume_separator (p, parsestr);
	  /* Check for missing separators.  */
	  if (!p && !(insn->insn_nios2_opcode->pinfo & NIOS2_INSN_OPTARG))
	    {
	      as_bad (_("expecting %c near %s"), *parsestr, context);
	      break;
	    }
	  ++parsestr;
	}

      if (*parsestr == '\0')
	{
	  /* Check that the argument string has no trailing arguments.  */
	  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;
}



/** 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.  */

/* Output a normal instruction.  */
static void
output_insn (nios2_insn_infoS *insn)
{
  char *f;
  nios2_insn_relocS *reloc; 
  f = frag_more (insn->insn_nios2_opcode->size);
  /* This allocates enough space for the instruction
     and puts it in the current frag.  */
  md_number_to_chars (f, insn->insn_code, insn->insn_nios2_opcode->size);
  /* Emit debug info.  */
  dwarf2_emit_insn (insn->insn_nios2_opcode->size);
  /* 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,
		 insn->insn_nios2_opcode->size,
		 &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, insn->insn_nios2_opcode->size,
		    UBRANCH_SUBTYPE (0), symp, offset, NULL);

      md_number_to_chars (f, insn->insn_code, insn->insn_nios2_opcode->size);

      /* 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, insn->insn_nios2_opcode->size,
		    CBRANCH_SUBTYPE (0), symp, offset, NULL);

      md_number_to_chars (f, insn->insn_code, insn->insn_nios2_opcode->size);

      /* 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,
		      (MATCH_R1_ORHI | SET_IW_I_B (AT_REGNUM)
		       | SET_IW_I_A (0)),
		      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,
		      (MATCH_R1_ORI | SET_IW_I_B (AT_REGNUM)
		       | SET_IW_I_A (AT_REGNUM)),
		      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, MATCH_R1_CALLR | SET_IW_R_A (AT_REGNUM), 4);
  dwarf2_emit_insn (4);
}

/* 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_IW_I_B (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);
      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);
      md_number_to_chars (f + 4,
			  (MATCH_R1_ADDI | SET_IW_I_A (reg_index)
			   | SET_IW_I_B (reg_index)),
			  4);
      dwarf2_emit_insn (4);
      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_ps_hash = hash_new ();

  for (i = 0; i < nios2_num_opcodes; ++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_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;
  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;
      insn->constant_bits = 0;

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

      /* Assemble the parsed arguments into the instruction word.  */
      nios2_assemble_args (insn);

      /* Handle relaxation and other transformations.  */
      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)
		   || (insn->insn_reloc->reloc_type
		       == BFD_RELOC_NIOS2_CALL26_NOAT)))
	output_call (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
    /* 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
      || fixp->fx_r_type == BFD_RELOC_NIOS2_GOT_LO
      || fixp->fx_r_type == BFD_RELOC_NIOS2_GOT_HA
      || fixp->fx_r_type == BFD_RELOC_NIOS2_CALL_LO
      || fixp->fx_r_type == BFD_RELOC_NIOS2_CALL_HA
      )
    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(...) */
bfd_reloc_code_real_type
nios2_cons (expressionS *exp, int size)
{
  bfd_reloc_code_real_type nios2_tls_ldo_reloc = BFD_RELOC_NONE;

  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 = BFD_RELOC_NIOS2_TLS_DTPREL;
	    }
	}
      if (nios2_tls_ldo_reloc != BFD_RELOC_NONE)
	{
	  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 == BFD_RELOC_NONE)
    expression (exp);
  return nios2_tls_ldo_reloc;
}

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