/* TI PRU assembler.
   Copyright (C) 2014-2017 Free Software Foundation, Inc.
   Contributed by Dimitar Dimitrov <dimitar@dinux.eu>
   Based on tc-nios2.c

   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 "bfd_stdint.h"
#include "opcode/pru.h"
#include "elf/pru.h"
#include "tc-pru.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.  */
  #error "OBJ_ELF not defined"
#endif

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

/* Machine-dependent command-line options.  */

struct pru_opt_s
{
  /* -mno-link-relax / -mlink-relax: generate (or not)
     relocations for linker relaxation.  */
  bfd_boolean link_relax;

  /* -mno-warn-regname-label: do not output a warning that a label name
     matches a register name.  */
  bfd_boolean warn_regname_label;
};

static struct pru_opt_s pru_opt = { TRUE, TRUE };

const char *md_shortopts = "r";

enum options
{
  OPTION_LINK_RELAX = OPTION_MD_BASE + 1,
  OPTION_NO_LINK_RELAX,
  OPTION_NO_WARN_REGNAME_LABEL,
};

struct option md_longopts[] = {
  { "mlink-relax",  no_argument, NULL, OPTION_LINK_RELAX  },
  { "mno-link-relax",  no_argument, NULL, OPTION_NO_LINK_RELAX  },
  { "mno-warn-regname-label",  no_argument, NULL,
    OPTION_NO_WARN_REGNAME_LABEL  },
  { NULL, no_argument, NULL, 0 }
};

size_t md_longopts_size = sizeof (md_longopts);

typedef struct pru_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 pru_insn_reloc *reloc_next;
} pru_insn_relocS;

/* This struct is used to hold state when assembling instructions.  */
typedef struct pru_insn_info
{
  /* Assembled instruction.  */
  unsigned long insn_code;
  /* Used for assembling LDI32.  */
  unsigned long ldi32_imm32;

  /* Pointer to the relevant bit of the opcode table.  */
  const struct pru_opcode *insn_pru_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[PRU_MAX_INSN_TOKENS + 1 + 1];

  /* This holds information used to generate fixups
     and eventually relocations if it is not null.  */
  pru_insn_relocS *insn_reloc;
} pru_insn_infoS;

/* Opcode hash table.  */
static struct hash_control *pru_opcode_hash = NULL;
#define pru_opcode_lookup(NAME) \
  ((struct pru_opcode *) hash_find (pru_opcode_hash, (NAME)))

/* Register hash table.  */
static struct hash_control *pru_reg_hash = NULL;
#define pru_reg_lookup(NAME) \
  ((struct pru_reg *) hash_find (pru_reg_hash, (NAME)))

/* The known current alignment of the current section.  */
static int pru_current_align;
static segT pru_current_align_seg;

static int pru_auto_align_on = 1;

/* The last seen label in the current section.  This is used to auto-align
   labels preceeding instructions.  */
static symbolS *pru_last_label;


/** 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, 4 or 8.  */
static uint64_t
md_chars_to_number (char *buf, int n)
{
  int i;
  uint64_t val;

  gas_assert (n == 1 || n == 2 || n == 4 || n == 8);

  val = 0;
  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);
  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.  */
const char *
md_atof (int type, char *litP, int *sizeP)
{
  return ieee_md_atof (type, litP, sizeP, FALSE);
}

/* Return true if STR starts with PREFIX, which should be a string literal.  */
#define strprefix(STR, PREFIX) \
  (strncmp ((STR), PREFIX, strlen (PREFIX)) == 0)

/* nop fill pattern for text section.  */
static char const nop[4] = { 0xe0, 0xe0, 0xe0, 0x12 };

/* Handles all machine-dependent alignment needs.  */
static void
pru_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 = (pru_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 (pru_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)
	pru_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
{
  PRU_MODE_ASSEMBLE,		/* Ordinary operation.  */
  PRU_MODE_TEST		/* Hidden mode used for self testing.  */
} PRU_MODE;

static PRU_MODE pru_mode = PRU_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
pru_check_assembly (unsigned int opcode, const char *exp_opcode)
{
  if (pru_mode == PRU_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_pru_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;
      pru_last_label = NULL;
    }

  if (align != 0)
    {
      pru_auto_align_on = 1;
      pru_align (align, pfill, pru_last_label);
      pru_last_label = NULL;
    }
  else
    pru_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_pru_text (int i)
{
  s_text (i);
  pru_last_label = NULL;
  pru_current_align = 0;
  pru_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_pru_data (int i)
{
  s_data (i);
  pru_last_label = NULL;
  pru_current_align = 0;
  pru_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_pru_section (int ignore)
{
  obj_elf_section (ignore);
  pru_last_label = NULL;
  pru_current_align = 0;
  pru_current_align_seg = now_seg;
}

/* Explicitly unaligned cons.  */
static void
s_pru_ucons (int nbytes)
{
  int hold;
  hold = pru_auto_align_on;
  pru_auto_align_on = 0;
  cons (nbytes);
  pru_auto_align_on = hold;
}

/* .set sets assembler options.  */
static void
s_pru_set (int equiv)
{
  char *save = input_line_pointer;
  char *directive;
  char delim = get_symbol_name (&directive);
  char *endline = input_line_pointer;

  (void) restore_line_pointer (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, "no_warn_regname_label"))
	  pru_opt.warn_regname_label = FALSE;
      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 = save;
  s_set (equiv);
}

/* Machine-dependent assembler directives.
   Format of each entry is:
   { "directive", handler_func, param }	 */
const pseudo_typeS md_pseudo_table[] = {
  {"align", s_pru_align, 0},
  {"text", s_pru_text, 0},
  {"data", s_pru_data, 0},
  {"section", s_pru_section, 0},
  {"section.s", s_pru_section, 0},
  {"sect", s_pru_section, 0},
  {"sect.s", s_pru_section, 0},
  /* .dword and .half are included for compatibility with MIPS.  */
  {"dword", cons, 8},
  {"half", cons, 2},
  /* PRU native word size is 4 bytes, so we override
     the GAS default of 2.  */
  {"word", cons, 4},
  /* Explicitly unaligned directives.  */
  {"2byte", s_pru_ucons, 2},
  {"4byte", s_pru_ucons, 4},
  {"8byte", s_pru_ucons, 8},
  {"16byte", s_pru_ucons, 16},
  {"set", s_pru_set, 0},
  {NULL, NULL, 0}
};


int
md_estimate_size_before_relax (fragS *fragp ATTRIBUTE_UNUSED,
			       asection *seg ATTRIBUTE_UNUSED)
{
  abort ();
  return 0;
}

void
md_convert_frag (bfd *headers ATTRIBUTE_UNUSED, segT segment ATTRIBUTE_UNUSED,
		 fragS *fragp ATTRIBUTE_UNUSED)
{
  abort ();
}


static bfd_boolean
relaxable_section (asection *sec)
{
  return ((sec->flags & SEC_DEBUGGING) == 0
	  && (sec->flags & SEC_CODE) != 0
	  && (sec->flags & SEC_ALLOC) != 0);
}

/* Does whatever the xtensa port does.  */
int
pru_validate_fix_sub (fixS *fix)
{
  segT add_symbol_segment, sub_symbol_segment;

  /* The difference of two symbols should be resolved by the assembler when
     linkrelax is not set.  If the linker may relax the section containing
     the symbols, then an Xtensa DIFF relocation must be generated so that
     the linker knows to adjust the difference value.  */
  if (!linkrelax || fix->fx_addsy == NULL)
    return 0;

  /* Make sure both symbols are in the same segment, and that segment is
     "normal" and relaxable.  If the segment is not "normal", then the
     fix is not valid.  If the segment is not "relaxable", then the fix
     should have been handled earlier.  */
  add_symbol_segment = S_GET_SEGMENT (fix->fx_addsy);
  if (! SEG_NORMAL (add_symbol_segment)
      || ! relaxable_section (add_symbol_segment))
    return 0;

  sub_symbol_segment = S_GET_SEGMENT (fix->fx_subsy);
  return (sub_symbol_segment == add_symbol_segment);
}

/* TC_FORCE_RELOCATION hook.  */

/* If linkrelax is turned on, and the symbol to relocate
   against is in a relaxable segment, don't compute the value -
   generate a relocation instead.  */
int
pru_force_relocation (fixS *fix)
{
  if (linkrelax && fix->fx_addsy
      && relaxable_section (S_GET_SEGMENT (fix->fx_addsy)))
    return 1;

  return generic_force_reloc (fix);
}



/** Fixups and overflow checking.  */

/* Check a fixup for overflow.  */
static bfd_reloc_status_type
pru_check_overflow (valueT fixup, reloc_howto_type *howto)
{
  bfd_reloc_status_type ret;

  ret = bfd_check_overflow (howto->complain_on_overflow,
			    howto->bitsize,
			    howto->rightshift,
			    bfd_get_reloc_size (howto) * 8,
			    fixup);

  return ret;
}

/* Emit diagnostic for fixup overflow.  */
static void
pru_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 pru_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 = pru_find_opcode (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 qbranch_target_overflow:
	  as_bad_where (fixP->fx_file, fixP->fx_line,
			_("quick branch offset %d out of range %d to %d"),
			(int)fixup, -((1<<9) * 4), (1 << 9) * 4);
	  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_immed32_overflow:
	  as_bad_where (fixP->fx_file, fixP->fx_line,
			_("immediate value %llu out of range %u to %lu"),
			(unsigned long long)fixup, 0, 0xfffffffflu);
	  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;
	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)
{
  unsigned char *where;
  valueT value = *valP;
  long n;

  /* 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_PRU_LDI32
		  || fixP->fx_r_type == BFD_RELOC_PRU_U16
		  || fixP->fx_r_type == BFD_RELOC_PRU_U16_PMEMIMM
		  || fixP->fx_r_type == BFD_RELOC_PRU_S10_PCREL
		  || fixP->fx_r_type == BFD_RELOC_PRU_U8_PCREL
		  || fixP->fx_r_type == BFD_RELOC_PRU_32_PMEM
		  || fixP->fx_r_type == BFD_RELOC_PRU_16_PMEM
		  /* 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;
    }

  /* gas_assert (had_errors () || !fixP->fx_subsy); */

  /* In general, fix instructions with immediate
     constants.  But leave LDI32 for the linker,
     which is prepared to shorten insns.  */
  if (fixP->fx_addsy == (symbolS *) NULL
      && fixP->fx_r_type != BFD_RELOC_PRU_LDI32)
    fixP->fx_done = 1;

  else if (fixP->fx_pcrel)
    {
      segT s = S_GET_SEGMENT (fixP->fx_addsy);

      if (s == seg || s == absolute_section)
	{
	  /* Blindly copied from AVR, but I don't understand why
	     this is needed in the first place.  Fail hard to catch
	     when this curious code snippet is utilized.  */
	  as_bad_where (fixP->fx_file, fixP->fx_line,
			_("unexpected PC relative expression"));
	  value += S_GET_VALUE (fixP->fx_addsy);
	  fixP->fx_done = 1;
	}
    }
  else if (linkrelax && fixP->fx_subsy)
    {
      /* For a subtraction relocation expression, generate one
	 of the DIFF relocs, with the value being the difference.
	 Note that a sym1 - sym2 expression is adjusted into a
	 section_start_sym + sym4_offset_from_section_start - sym1
	 expression.  fixP->fx_addsy holds the section start symbol,
	 fixP->fx_offset holds sym2's offset, and fixP->fx_subsy
	 holds sym1.  Calculate the current difference and write value,
	 but leave fx_offset as is - during relaxation,
	 fx_offset - value gives sym1's value.  */

      offsetT diffval;	/* valueT is unsigned, so use offsetT.  */

      diffval = S_GET_VALUE (fixP->fx_addsy)
		+ fixP->fx_offset - S_GET_VALUE (fixP->fx_subsy);

      switch (fixP->fx_r_type)
	{
	case BFD_RELOC_8:
	  fixP->fx_r_type = BFD_RELOC_PRU_GNU_DIFF8;
	  break;
	case BFD_RELOC_16:
	  fixP->fx_r_type = BFD_RELOC_PRU_GNU_DIFF16;
	  break;
	case BFD_RELOC_32:
	  fixP->fx_r_type = BFD_RELOC_PRU_GNU_DIFF32;
	  break;
	case BFD_RELOC_PRU_16_PMEM:
	  fixP->fx_r_type = BFD_RELOC_PRU_GNU_DIFF16_PMEM;
	  if (diffval % 4)
	    as_bad_where (fixP->fx_file, fixP->fx_line,
			  _("residual low bits in pmem diff relocation"));
	  diffval /= 4;
	  break;
	case BFD_RELOC_PRU_32_PMEM:
	  fixP->fx_r_type = BFD_RELOC_PRU_GNU_DIFF32_PMEM;
	  if (diffval % 4)
	    as_bad_where (fixP->fx_file, fixP->fx_line,
			  _("residual low bits in pmem diff relocation"));
	  diffval /= 4;
	  break;
	default:
	  as_bad_where (fixP->fx_file, fixP->fx_line,
			_("expression too complex"));
	  break;
	}

      value = *valP = diffval;

      fixP->fx_subsy = NULL;
  }
  /* We don't actually support subtracting a symbol.  */
  if (fixP->fx_subsy != (symbolS *) NULL)
    as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex"));

  /* For the DIFF relocs, write the value into the object file while still
     keeping fx_done FALSE, as both the difference (recorded in the object file)
     and the sym offset (part of fixP) are needed at link relax time.  */
  where = (unsigned char *) fixP->fx_frag->fr_literal + fixP->fx_where;
  switch (fixP->fx_r_type)
    {
    case BFD_RELOC_PRU_GNU_DIFF8:
      *where = value;
      break;
    case BFD_RELOC_PRU_GNU_DIFF16:
    case BFD_RELOC_PRU_GNU_DIFF16_PMEM:
      bfd_putl16 ((bfd_vma) value, where);
      break;
    case BFD_RELOC_PRU_GNU_DIFF32:
    case BFD_RELOC_PRU_GNU_DIFF32_PMEM:
      bfd_putl32 ((bfd_vma) value, where);
      break;
    default:
      break;
    }

  if (fixP->fx_done)
    /* 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 = value;
	  uint64_t insn;
	  char *buf;

	  /* Get the instruction or data to be fixed up.  */
	  buf = fixP->fx_frag->fr_literal + fixP->fx_where;
	  insn = md_chars_to_number (buf, fixP->fx_size);

	  /* Check for overflow, emitting a diagnostic if necessary.  */
	  if (pru_check_overflow (fixup, howto) != bfd_reloc_ok)
	    pru_diagnose_overflow (fixup, howto, fixP, insn);

	  /* Apply the right shift.  */
	  fixup = ((offsetT)fixup) >> howto->rightshift;

	  /* Truncate the fixup to right size.  */
	  n = sizeof (fixup) * 8 - howto->bitsize;
	  fixup = (fixup << n) >> n;

	  /* Fix up the instruction.  Non-contiguous bitfields need
	     special handling.  */
	  if (fixP->fx_r_type == BFD_RELOC_PRU_LDI32)
	    {
	      /* As the only 64-bit "insn", LDI32 needs special handling. */
	      uint32_t insn1 = insn & 0xffffffff;
	      uint32_t insn2 = insn >> 32;
	      SET_INSN_FIELD (IMM16, insn1, fixup & 0xffff);
	      SET_INSN_FIELD (IMM16, insn2, fixup >> 16);

	      md_number_to_chars (buf, insn1, 4);
	      md_number_to_chars (buf + 4, insn2, 4);
	    }
	  else
	    {
	      if (fixP->fx_r_type == BFD_RELOC_PRU_S10_PCREL)
		SET_BROFF_URAW (insn, fixup);
	      else
		insn = (insn & ~howto->dst_mask) | (fixup << howto->bitpos);
	      md_number_to_chars (buf, insn, 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.  */

/* Creates a new pru_insn_relocS and returns a pointer to it.  */
static pru_insn_relocS *
pru_insn_reloc_new (bfd_reloc_code_real_type reloc_type, unsigned int pcrel)
{
  pru_insn_relocS *retval;
  retval = XNEW (pru_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 pru_insn_reloc_new ().  */
static void
pru_insn_reloc_destroy (pru_insn_relocS *reloc)
{
  pru_insn_relocS *next;

  while (reloc)
    {
      next = reloc->reloc_next;
      free (reloc);
      reloc = next;
    }
}

/* The various pru_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 pru_insn_relocS and stores the expression and
   reloc_type for future use.  */
static unsigned long
pru_assemble_expression (const char *exprstr,
			   pru_insn_infoS *insn,
			   pru_insn_relocS *prev_reloc,
			   bfd_reloc_code_real_type reloc_type,
			   unsigned int pcrel)
{
  expressionS *ep;
  pru_insn_relocS *reloc;
  char *saved_line_ptr;
  unsigned short value;

  gas_assert (exprstr != NULL);
  gas_assert (insn != NULL);

  /* We use this blank keyword to distinguish register from
     label operands.  */
  if (strstr (exprstr, "%label") != NULL)
    {
      exprstr += strlen ("%label") + 1;
    }

  /* Check for pmem relocation operator.
     Change the relocation type and advance the ptr to the start of
     the expression proper.  */
  if (strstr (exprstr, "%pmem") != NULL)
    {
      reloc_type = BFD_RELOC_PRU_U16_PMEMIMM;
      exprstr += strlen ("%pmem") + 1;
    }

  /* We potentially have a relocation.  */
  reloc = pru_insn_reloc_new (reloc_type, pcrel);
  if (prev_reloc != NULL)
    prev_reloc->reloc_next = reloc;
  else
    insn->insn_reloc = reloc;

  /* Parse the expression string.  */
  ep = &reloc->reloc_expression;
  saved_line_ptr = input_line_pointer;
  input_line_pointer = (char *) exprstr;
  SKIP_WHITESPACE ();
  expression (ep);
  SKIP_WHITESPACE ();
  if (*input_line_pointer)
    as_bad (_("trailing garbage after expression: %s"), input_line_pointer);
  input_line_pointer = saved_line_ptr;


  if (ep->X_op == O_illegal || ep->X_op == O_absent)
    as_bad (_("expected expression, got %s"), exprstr);

  /* 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 (pru_mode == PRU_MODE_TEST && ep->X_op == O_constant)
    value = ep->X_add_number;

  return (unsigned long) value;
}

/* Try to parse a non-relocatable expression.  */
static unsigned long
pru_assemble_noreloc_expression (const char *exprstr)
{
  expressionS exp;
  char *saved_line_ptr;
  unsigned long val;

  gas_assert (exprstr != NULL);

  saved_line_ptr = input_line_pointer;
  input_line_pointer = (char *) exprstr;
  SKIP_WHITESPACE ();
  expression (&exp);
  SKIP_WHITESPACE ();
  if (*input_line_pointer)
    as_bad (_("trailing garbage after expression: %s"), input_line_pointer);
  input_line_pointer = saved_line_ptr;

  val = 0;
  if (exp.X_op != O_constant)
    as_bad (_("expected constant expression, got %s"), exprstr);
  else
    val = exp.X_add_number;

  return val;
}

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

static void
pru_assemble_arg_d (pru_insn_infoS *insn_info, const char *argstr)
{
  struct pru_reg *dst = pru_reg_lookup (argstr);

  if (dst == NULL)
    as_bad (_("unknown register %s"), argstr);
  else
    {
      SET_INSN_FIELD (RD, insn_info->insn_code, dst->index);
      SET_INSN_FIELD (RDSEL, insn_info->insn_code, dst->regsel);
    }
}

static void
pru_assemble_arg_D (pru_insn_infoS *insn_info, const char *argstr)
{
  struct pru_reg *dst;

  /* The leading & before an address register is optional.  */
  if (*argstr == '&')
    argstr++;

  dst = pru_reg_lookup (argstr);

  if (dst == NULL)
    as_bad (_("unknown register %s"), argstr);
  else
    {
      unsigned long rxb = 0;

      switch (dst->regsel)
	{
	case RSEL_31_0: rxb = 0; break;	/* whole register defaults to .b0  */
	case RSEL_7_0: rxb = 0; break;
	case RSEL_15_8: rxb = 1; break;
	case RSEL_23_16: rxb = 2; break;
	case RSEL_31_24: rxb = 3; break;
	default:
	  as_bad (_("data transfer register cannot be halfword"));
	}

      SET_INSN_FIELD (RD, insn_info->insn_code, dst->index);
      SET_INSN_FIELD (RDB, insn_info->insn_code, rxb);
    }
}

static void
pru_assemble_arg_R (pru_insn_infoS *insn_info, const char *argstr)
{
  struct pru_reg *dst = pru_reg_lookup (argstr);

  if (dst == NULL)
    as_bad (_("unknown register %s"), argstr);
  else
    {
      if (dst->regsel != RSEL_31_0)
	{
	  as_bad (_("destination register must be full-word"));
	}

      SET_INSN_FIELD (RD, insn_info->insn_code, dst->index);
      SET_INSN_FIELD (RDSEL, insn_info->insn_code, dst->regsel);
    }
}

static void
pru_assemble_arg_s (pru_insn_infoS *insn_info, const char *argstr)
{
  struct pru_reg *src1 = pru_reg_lookup (argstr);

  if (src1 == NULL)
    as_bad (_("unknown register %s"), argstr);
  else
    {
      SET_INSN_FIELD (RS1, insn_info->insn_code, src1->index);
      SET_INSN_FIELD (RS1SEL, insn_info->insn_code, src1->regsel);
    }
}

static void
pru_assemble_arg_S (pru_insn_infoS *insn_info, const char *argstr)
{
  struct pru_reg *src1 = pru_reg_lookup (argstr);

  if (src1 == NULL)
    as_bad (_("unknown register %s"), argstr);
  else
    {
      if (src1->regsel != RSEL_31_0)
	as_bad (_("cannot use partial register %s for addressing"), argstr);
      SET_INSN_FIELD (RS1, insn_info->insn_code, src1->index);
    }
}

static void
pru_assemble_arg_b (pru_insn_infoS *insn_info, const char *argstr)
{
  struct pru_reg *src2 = pru_reg_lookup (argstr);
  if (src2 == NULL)
    {
      unsigned long imm8 = pru_assemble_noreloc_expression (argstr);
      SET_INSN_FIELD (IMM8, insn_info->insn_code, imm8);
      SET_INSN_FIELD (IO, insn_info->insn_code, 1);
    }
  else
    {
      SET_INSN_FIELD (IO, insn_info->insn_code, 0);
      SET_INSN_FIELD (RS2, insn_info->insn_code, src2->index);
      SET_INSN_FIELD (RS2SEL, insn_info->insn_code, src2->regsel);
    }

}

static void
pru_assemble_arg_B (pru_insn_infoS *insn_info, const char *argstr)
{
  struct pru_reg *src2 = pru_reg_lookup (argstr);
  if (src2 == NULL)
    {
      unsigned long imm8;
      imm8 = pru_assemble_noreloc_expression (argstr);
      if (!imm8 || imm8 > 0xff)
	as_bad (_("loop count constant %ld is out of range [1..%d]"),
		imm8, 0xff);
      /* Note: HW expects the immediate loop count field
	 to be one less than the actual loop count.  */
      SET_INSN_FIELD (IMM8, insn_info->insn_code, imm8 - 1);
      SET_INSN_FIELD (IO, insn_info->insn_code, 1);
    }
  else
    {
      SET_INSN_FIELD (IO, insn_info->insn_code, 0);
      SET_INSN_FIELD (RS2, insn_info->insn_code, src2->index);
      SET_INSN_FIELD (RS2SEL, insn_info->insn_code, src2->regsel);
    }
}

static void
pru_assemble_arg_i (pru_insn_infoS *insn_info, const char *argstr)
{
  unsigned long imm32;

  /* We must not generate PRU_LDI32 relocation if relaxation is disabled in
     GAS. Consider the following scenario: GAS relaxation is disabled, so
     DIFF* expressions are fixed and not emitted as relocations. Then if LD
     has relaxation enabled, it may shorten LDI32 but will not update
     accordingly the DIFF expressions.  */
  if (pru_opt.link_relax)
    imm32 = pru_assemble_expression (argstr, insn_info,
				     insn_info->insn_reloc,
				     BFD_RELOC_PRU_LDI32, 0);
  else
    imm32 = pru_assemble_noreloc_expression (argstr);

  /* QUIRK: LDI must clear IO bit high, even though it has immediate arg. */
  SET_INSN_FIELD (IO, insn_info->insn_code, 0);
  SET_INSN_FIELD (IMM16, insn_info->insn_code, imm32 & 0xffff);
  insn_info->ldi32_imm32 = imm32;
}

static void
pru_assemble_arg_j (pru_insn_infoS *insn_info, const char *argstr)
{
  struct pru_reg *src2 = pru_reg_lookup (argstr);

  if (src2 == NULL)
    {
      unsigned long imm16 = pru_assemble_expression (argstr, insn_info,
						     insn_info->insn_reloc,
						     BFD_RELOC_PRU_U16_PMEMIMM,
						     0);
      SET_INSN_FIELD (IMM16, insn_info->insn_code, imm16);
      SET_INSN_FIELD (IO, insn_info->insn_code, 1);
    }
  else
    {
      SET_INSN_FIELD (IO, insn_info->insn_code, 0);
      SET_INSN_FIELD (RS2, insn_info->insn_code, src2->index);
      SET_INSN_FIELD (RS2SEL, insn_info->insn_code, src2->regsel);
    }
}

static void
pru_assemble_arg_W (pru_insn_infoS *insn_info, const char *argstr)
{
  unsigned long imm16 = pru_assemble_expression (argstr, insn_info,
						 insn_info->insn_reloc,
						 BFD_RELOC_PRU_U16, 0);
  /* QUIRK: LDI must clear IO bit high, even though it has immediate arg.  */
  SET_INSN_FIELD (IO, insn_info->insn_code, 0);
  SET_INSN_FIELD (IMM16, insn_info->insn_code, imm16);
}

static void
pru_assemble_arg_o (pru_insn_infoS *insn_info, const char *argstr)
{
  unsigned long imm10 = pru_assemble_expression (argstr, insn_info,
						 insn_info->insn_reloc,
						 BFD_RELOC_PRU_S10_PCREL, 1);
  SET_BROFF_URAW (insn_info->insn_code, imm10);
}

static void
pru_assemble_arg_O (pru_insn_infoS *insn_info, const char *argstr)
{
  unsigned long imm8 = pru_assemble_expression (argstr, insn_info,
						insn_info->insn_reloc,
						BFD_RELOC_PRU_U8_PCREL, 1);
  SET_INSN_FIELD (LOOP_JMPOFFS, insn_info->insn_code, imm8);
}

static void
pru_assemble_arg_l (pru_insn_infoS *insn_info, const char *argstr)
{
  unsigned long burstlen = 0;
  struct pru_reg *blreg = pru_reg_lookup (argstr);

  if (blreg == NULL)
    {
      burstlen = pru_assemble_noreloc_expression (argstr);
      if (!burstlen || burstlen > LSSBBO_BYTECOUNT_R0_BITS7_0)
	as_bad (_("byte count constant %ld is out of range [1..%d]"),
		burstlen, LSSBBO_BYTECOUNT_R0_BITS7_0);
      burstlen--;
    }
  else
    {
      if (blreg->index != 0)
	as_bad (_("only r0 can be used as byte count register"));
      else if (blreg->regsel > RSEL_31_24)
	as_bad (_("only r0.bX byte fields of r0 can be used as byte count"));
      else
	burstlen = LSSBBO_BYTECOUNT_R0_BITS7_0 + blreg->regsel;
    }
    SET_BURSTLEN (insn_info->insn_code, burstlen);
}

static void
pru_assemble_arg_n (pru_insn_infoS *insn_info, const char *argstr)
{
  unsigned long burstlen = 0;
  struct pru_reg *blreg = pru_reg_lookup (argstr);

  if (blreg == NULL)
    {
      burstlen = pru_assemble_noreloc_expression (argstr);
      if (!burstlen || burstlen > LSSBBO_BYTECOUNT_R0_BITS7_0)
	as_bad (_("byte count constant %ld is out of range [1..%d]"),
		burstlen, LSSBBO_BYTECOUNT_R0_BITS7_0);
      burstlen--;
    }
  else
    {
      if (blreg->index != 0)
	as_bad (_("only r0 can be used as byte count register"));
      else if (blreg->regsel > RSEL_31_24)
	as_bad (_("only r0.bX byte fields of r0 can be used as byte count"));
      else
	burstlen = LSSBBO_BYTECOUNT_R0_BITS7_0 + blreg->regsel;
    }
    SET_INSN_FIELD (XFR_LENGTH, insn_info->insn_code, burstlen);
}

static void
pru_assemble_arg_c (pru_insn_infoS *insn_info, const char *argstr)
{
  unsigned long cb = pru_assemble_noreloc_expression (argstr);

  if (cb > 31)
    as_bad (_("invalid constant table offset %ld"), cb);
  else
    SET_INSN_FIELD (CB, insn_info->insn_code, cb);
}

static void
pru_assemble_arg_w (pru_insn_infoS *insn_info, const char *argstr)
{
  unsigned long wk = pru_assemble_noreloc_expression (argstr);

  if (wk != 0 && wk != 1)
    as_bad (_("invalid WakeOnStatus %ld"), wk);
  else
    SET_INSN_FIELD (WAKEONSTATUS, insn_info->insn_code, wk);
}

static void
pru_assemble_arg_x (pru_insn_infoS *insn_info, const char *argstr)
{
  unsigned long wba = pru_assemble_noreloc_expression (argstr);

  if (wba > 255)
    as_bad (_("invalid XFR WideBus Address %ld"), wba);
  else
    SET_INSN_FIELD (XFR_WBA, insn_info->insn_code, wba);
}

/* 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 *
pru_consume_arg (char *argstr, const char *parsestr)
{
  char *temp;

  switch (*parsestr)
    {
    case 'W':
      if (*argstr == '%')
	{
	  if (strprefix (argstr, "%pmem") || strprefix (argstr, "%label"))
	    {
	      /* 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 'j':
    case 'o':
    case 'O':
      if (*argstr == '%')
	{
	  /* Only 'j' really requires %label for distinguishing registers
	     from labels, but we include 'o' and 'O' here to avoid
	     confusing assembler programmers. Thus for completeness all
	     jump operands can be prefixed with %label.  */
	  if (strprefix (argstr, "%label"))
	    {
	      /* 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 'b':
    case 'B':
    case 'c':
    case 'd':
    case 'D':
    case 'E':
    case 'i':
    case 's':
    case 'S':
    case 'l':
    case 'n':
    case 'R':
    case 'w':
    case 'x':
      /* We can't have %pmem here.  */
      if (*argstr == '%')
	as_bad (_("badly formed expression near %s"), argstr);
      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 *
pru_consume_separator (char *argstr, const char *separator)
{
  char *p;

  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
pru_parse_args (pru_insn_infoS *insn ATTRIBUTE_UNUSED, 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 < PRU_MAX_INSN_TOKENS)
    {
      parsed_args[i] = pru_consume_arg (p, parsestr);
      ++parsestr;
      if (*parsestr != '\0')
	{
	  p = pru_consume_separator (p, parsestr);
	  ++parsestr;
	}
      else
	{
	  /* Check that the argument string has no trailing arguments.  */
	  /* If we've got a %pmem relocation, we've zapped the parens with
	     spaces.  */
	  if (strprefix (p, "%pmem") || strprefix (p, "%label"))
	    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;

  /* There are no instructions with optional arguments; complain.  */
  if (*parsestr != '\0')
    as_bad (_("missing argument"));
}


/** Assembler output support.  */

/* Output a normal instruction.  */
static void
output_insn (pru_insn_infoS *insn)
{
  char *f;
  pru_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 two LDI instructions from LDI32 macro */
static void
output_insn_ldi32 (pru_insn_infoS *insn)
{
  char *f;
  pru_insn_relocS *reloc;
  unsigned long insn2;

  f = frag_more (8);
  md_number_to_chars (f, insn->insn_code, 4);

  insn2 = insn->insn_code;
  SET_INSN_FIELD (IMM16, insn2, insn->ldi32_imm32 >> 16);
  SET_INSN_FIELD (RDSEL, insn2, RSEL_31_16);
  md_number_to_chars (f + 4, insn2, 4);

  /* Emit debug info.  */
  dwarf2_emit_insn (8);

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


/** External interfaces.  */

/* The following functions are called by machine-independent parts of
   the assembler.  */
int
md_parse_option (int c, const char *arg ATTRIBUTE_UNUSED)
{
  switch (c)
    {
    case 'r':
      /* Hidden option for self-test mode.  */
      pru_mode = PRU_MODE_TEST;
      break;
    case OPTION_LINK_RELAX:
      pru_opt.link_relax = TRUE;
      break;
    case OPTION_NO_LINK_RELAX:
      pru_opt.link_relax = FALSE;
      break;
    case OPTION_NO_WARN_REGNAME_LABEL:
      pru_opt.warn_regname_label = FALSE;
      break;
    default:
      return 0;
      break;
    }

  return 1;
}

const char *
pru_target_format (void)
{
  return "elf32-pru";
}

/* Machine-dependent usage message.  */
void
md_show_usage (FILE *stream)
{
  fprintf (stream,
    _("PRU options:\n"
      "  -mlink-relax     generate relocations for linker relaxation (default).\n"
      "  -mno-link-relax  don't generate relocations for linker relaxation.\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 PRU opcodes, registers and
     arguments.  */
  pru_opcode_hash = hash_new ();
  pru_reg_hash = hash_new ();

  for (i = 0; i < NUMOPCODES; ++i)
    {
      inserted
	= hash_insert (pru_opcode_hash, pru_opcodes[i].name,
		       (PTR) & pru_opcodes[i]);
      if (inserted != NULL)
	{
	  fprintf (stderr, _("internal error: can't hash `%s': %s\n"),
		   pru_opcodes[i].name, inserted);
	  /* Probably a memory allocation problem?  Give up now.  */
	  as_fatal (_("Broken assembler.  No assembly attempted."));
	}
    }

  for (i = 0; i < pru_num_regs; ++i)
    {
      inserted
	= hash_insert (pru_reg_hash, pru_regs[i].name,
		       (PTR) & pru_regs[i]);
      if (inserted != NULL)
	{
	  fprintf (stderr, _("internal error: can't hash `%s': %s\n"),
		   pru_regs[i].name, inserted);
	  /* Probably a memory allocation problem?  Give up now.  */
	  as_fatal (_("Broken assembler.  No assembly attempted."));
	}

    }

  linkrelax = pru_opt.link_relax;
  /* Initialize the alignment data.  */
  pru_current_align_seg = now_seg;
  pru_last_label = NULL;
  pru_current_align = 0;
}


/* Assembles a single line of PRU assembly language.  */
void
md_assemble (char *op_str)
{
  char *argstr;
  char *op_strdup = NULL;
  pru_insn_infoS thisinsn;
  pru_insn_infoS *insn = &thisinsn;

  /* Make sure we are aligned on a 4-byte boundary.  */
  if (pru_current_align < 2)
    pru_align (2, NULL, pru_last_label);
  else if (pru_current_align > 2)
    pru_current_align = 2;
  pru_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_pru_opcode = pru_opcode_lookup (insn->insn_tokens[0]);
  insn->insn_reloc = NULL;

  if (insn->insn_pru_opcode != NULL)
    {
      const char *argsfmt = insn->insn_pru_opcode->args;
      const char **argtk = &insn->insn_tokens[1];
      const char *argp;

      /* Set the opcode for the instruction.  */
      insn->insn_code = insn->insn_pru_opcode->match;

      if (pru_mode == PRU_MODE_TEST)
	{
	  /* Add the "expected" instruction parameter used for validation.  */
	  argsfmt = malloc (strlen (argsfmt) + 3);
	  sprintf ((char *)argsfmt, "%s,E", insn->insn_pru_opcode->args);
	}
      pru_parse_args (insn, argstr, argsfmt,
		      (char **) &insn->insn_tokens[1]);

      for (argp = argsfmt; !had_errors () && *argp && *argtk; ++argp)
	{
	  gas_assert (argtk <= &insn->insn_tokens[PRU_MAX_INSN_TOKENS]);

	  switch (*argp)
	    {
	    case ',':
	      continue;

	    case 'd':
	      pru_assemble_arg_d (insn, *argtk++);
	      continue;
	    case 'D':
	      pru_assemble_arg_D (insn, *argtk++);
	      continue;
	    case 'R':
	      pru_assemble_arg_R (insn, *argtk++);
	      continue;
	    case 's':
	      pru_assemble_arg_s (insn, *argtk++);
	      continue;
	    case 'S':
	      pru_assemble_arg_S (insn, *argtk++);
	      continue;
	    case 'b':
	      pru_assemble_arg_b (insn, *argtk++);
	      continue;
	    case 'B':
	      pru_assemble_arg_B (insn, *argtk++);
	      continue;
	    case 'i':
	      pru_assemble_arg_i (insn, *argtk++);
	      continue;
	    case 'j':
	      pru_assemble_arg_j (insn, *argtk++);
	      continue;
	    case 'W':
	      pru_assemble_arg_W (insn, *argtk++);
	      continue;
	    case 'o':
	      pru_assemble_arg_o (insn, *argtk++);
	      continue;
	    case 'O':
	      pru_assemble_arg_O (insn, *argtk++);
	      continue;
	    case 'l':
	      pru_assemble_arg_l (insn, *argtk++);
	      continue;
	    case 'n':
	      pru_assemble_arg_n (insn, *argtk++);
	      continue;
	    case 'c':
	      pru_assemble_arg_c (insn, *argtk++);
	      continue;
	    case 'w':
	      pru_assemble_arg_w (insn, *argtk++);
	      continue;
	    case 'x':
	      pru_assemble_arg_x (insn, *argtk++);
	      continue;

	    case 'E':
	      pru_check_assembly (insn->insn_code, *argtk++);
	    default:
	      BAD_CASE (*argp);
	    }
	}

      if (*argp && !had_errors ())
	as_bad (_("missing argument"));

      if (!had_errors ())
	{
	  if (insn->insn_pru_opcode->pinfo & PRU_INSN_LDI32)
	    {
	      output_insn_ldi32 (insn);
	    }
	  else
	    {
	      output_insn (insn);
	    }
	}

      if (pru_mode == PRU_MODE_TEST)
	free ((char *)argsfmt);
    }
  else
    /* Unrecognised instruction - error.  */
    as_bad (_("unrecognised instruction %s"), insn->insn_tokens[0]);

  /* Don't leak memory.  */
  pru_insn_reloc_destroy (insn->insn_reloc);
  free (op_strdup);
}

/* Round up section size.  */
valueT
md_section_align (asection *seg, valueT addr)
{
  int align = bfd_get_section_alignment (stdoutput, seg);
  return ((addr + (1 << align) - 1) & (-((valueT) 1 << align)));
}

/* Implement tc_fix_adjustable.  */
int
pru_fix_adjustable (fixS *fixp)
{
  if (fixp->fx_addsy == NULL)
    return 1;

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

  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;

  return 1;
}

/* 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 = XNEW (arelent);
  reloc->sym_ptr_ptr = XNEW (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; */

  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 fixP->fx_where + fixP->fx_frag->fr_address;
}

/* Called just before the assembler exits.  */
void
md_end (void)
{
  hash_die (pru_opcode_hash);
  hash_die (pru_reg_hash);
}

symbolS *
md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
{
  return NULL;
}

/* Implement tc_frob_label.  */
void
pru_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.  */
  pru_last_label = lab;

  if (pru_opt.warn_regname_label && pru_reg_lookup (S_GET_NAME (lab)))
    as_warn (_("Label \"%s\" matches a CPU register name"), S_GET_NAME (lab));
}

static inline char *
skip_space (char *s)
{
  while (*s == ' ' || *s == '\t')
    ++s;
  return s;
}

/* Parse special CONS expression: pmem (expression).  Idea from AVR.

   Used to catch and mark code (program memory) in constant expression
   relocations.  Return non-zero for program memory.  */

int
pru_parse_cons_expression (expressionS *exp, int nbytes)
{
  int is_pmem = FALSE;
  char *tmp;

  tmp = input_line_pointer = skip_space (input_line_pointer);

  if (nbytes == 4 || nbytes == 2)
    {
      const char *pmem_str = "%pmem";
      int len = strlen (pmem_str);

      if (strncasecmp (input_line_pointer, pmem_str, len) == 0)
	{
	  input_line_pointer = skip_space (input_line_pointer + len);

	  if (*input_line_pointer == '(')
	    {
	      input_line_pointer = skip_space (input_line_pointer + 1);
	      is_pmem = TRUE;
	      expression (exp);

	      if (*input_line_pointer == ')')
		++input_line_pointer;
	      else
		{
		  as_bad (_("`)' required"));
		  is_pmem = FALSE;
		}

	      return is_pmem;
	    }

	  input_line_pointer = tmp;
	}
    }

  expression (exp);

  return is_pmem;
}

/* Implement TC_CONS_FIX_NEW.  */
void
pru_cons_fix_new (fragS *frag, int where, unsigned int nbytes,
		    expressionS *exp, const int is_pmem)
{
  bfd_reloc_code_real_type r;

  switch (nbytes | (!!is_pmem << 8))
    {
    case 1 | (0 << 8): r = BFD_RELOC_8; break;
    case 2 | (0 << 8): r = BFD_RELOC_16; break;
    case 4 | (0 << 8): r = BFD_RELOC_32; break;
    case 8 | (0 << 8): r = BFD_RELOC_64; break;
    case 2 | (1 << 8): r = BFD_RELOC_PRU_16_PMEM; break;
    case 4 | (1 << 8): r = BFD_RELOC_PRU_32_PMEM; break;
    default:
      as_bad (_("illegal %s relocation size: %d"),
	      is_pmem ? "text" : "data", nbytes);
      return;
    }

  fix_new_exp (frag, where, (int) nbytes, exp, 0, r);
}

/* Implement tc_regname_to_dw2regnum, to convert REGNAME to a DWARF-2
   register number.  */
int
pru_regname_to_dw2regnum (char *regname)
{
  struct pru_reg *r = pru_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
pru_frame_initial_instructions (void)
{
  const unsigned fp_regno = 4;
  cfi_add_CFA_def_cfa (fp_regno, 0);
}

bfd_boolean
pru_allow_local_subtract (expressionS * left,
			     expressionS * right,
			     segT section)
{
  /* If we are not in relaxation mode, subtraction is OK.  */
  if (!linkrelax)
    return TRUE;

  /* If the symbols are not in a code section then they are OK.  */
  if ((section->flags & SEC_CODE) == 0)
    return TRUE;

  if (left->X_add_symbol == right->X_add_symbol)
    return TRUE;

  /* We have to assume that there may be instructions between the
     two symbols and that relaxation may increase the distance between
     them.  */
  return FALSE;
}
