/* tc-epiphany.c -- Assembler for the Adapteva EPIPHANY
   Copyright (C) 2009-2016 Free Software Foundation, Inc.
   Contributed by Embecosm on behalf of Adapteva, 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 "subsegs.h"
#include "symcat.h"
#include "opcodes/epiphany-desc.h"
#include "opcodes/epiphany-opc.h"
#include "cgen.h"
#include "elf/common.h"
#include "elf/epiphany.h"
#include "dwarf2dbg.h"
#include "libbfd.h"

/* Structure to hold all of the different components describing
   an individual instruction.  */
typedef struct
{
  const CGEN_INSN *	insn;
  const CGEN_INSN *	orig_insn;
  CGEN_FIELDS		fields;
#if CGEN_INT_INSN_P
  CGEN_INSN_INT         buffer [1];
#define INSN_VALUE(buf) (*(buf))
#else
  unsigned char         buffer [CGEN_MAX_INSN_SIZE];
#define INSN_VALUE(buf) (buf)
#endif
  char *		addr;
  fragS *		frag;
  int                   num_fixups;
  fixS *                fixups [GAS_CGEN_MAX_FIXUPS];
  int                   indices [MAX_OPERAND_INSTANCES];
}
epiphany_insn;

const char comment_chars[]        = ";";
const char line_comment_chars[]   = "#";
const char line_separator_chars[] = "`";
const char EXP_CHARS[]            = "eE";
const char FLT_CHARS[]            = "fFdD";

/* Flag to detect when switching to code section where insn alignment is
   implied.  */
static bfd_boolean force_code_align = FALSE;

static void
epiphany_elf_section_rtn (int i)
{
  obj_elf_section (i);

  if (force_code_align)
    {
      do_align (1, NULL, 0, 0);
      force_code_align = FALSE;
    }
}

static void
epiphany_elf_section_text (int i)
{
  obj_elf_text (i);

  do_align (1, NULL, 0, 0);
  force_code_align = FALSE;
}

/* The target specific pseudo-ops which we support.  */
const pseudo_typeS md_pseudo_table[] =
{
    { "text",   epiphany_elf_section_text,  0 },
    { "sect",   epiphany_elf_section_rtn,   0 },
    /* .word should be 32 bits.  */
    { "word",       cons, 4 },
    { "cpu",        s_ignore,         0 },
    { "thumb_func", s_ignore,         0 },
    { "code",       s_ignore,         0 },
    { NULL,         NULL,             0 }
};



enum options
{
  OPTION_CPU_EPIPHANY = OPTION_MD_BASE,
  OPTION_CPU_EPIPHANY16
};

struct option md_longopts[] =
{
  { "mepiphany ",  no_argument, NULL, OPTION_CPU_EPIPHANY },
  { "mepiphany16", no_argument, NULL, OPTION_CPU_EPIPHANY16 },
  { NULL,          no_argument, NULL, 0 },
};

size_t md_longopts_size = sizeof (md_longopts);

const char * md_shortopts = "";

int
md_parse_option (int c ATTRIBUTE_UNUSED, const char * arg ATTRIBUTE_UNUSED)
{
  return 0;	/* No target-specific options.  */
}

void
md_show_usage (FILE * stream)
{
  fprintf (stream, _("EPIPHANY specific command line options:\n"));
}


void
md_begin (void)
{
  /* Initialize the `cgen' interface.  */

  /* Set the machine number and endian.  */
  gas_cgen_cpu_desc = epiphany_cgen_cpu_open (CGEN_CPU_OPEN_MACHS,
					   bfd_mach_epiphany32,
					   CGEN_CPU_OPEN_ENDIAN,
					   CGEN_ENDIAN_LITTLE,
					   CGEN_CPU_OPEN_END);
  epiphany_cgen_init_asm (gas_cgen_cpu_desc);

  /* This is a callback from cgen to gas to parse operands.  */
  cgen_set_parse_operand_fn (gas_cgen_cpu_desc, gas_cgen_parse_operand);

  /* Set the machine type.  */
  bfd_default_set_arch_mach (stdoutput, bfd_arch_epiphany, bfd_mach_epiphany32);
}

valueT
md_section_align (segT segment, valueT size)
{
  int align = bfd_get_section_alignment (stdoutput, segment);

  return ((size + (1 << align) - 1) & -(1 << align));
}


/* Functions concerning relocs.  */

long
md_pcrel_from (fixS *fixP ATTRIBUTE_UNUSED)
{
  abort ();
}

/* Write a value out to the object file, using the appropriate endianness.  */

void
md_number_to_chars (char * buf, valueT val, int n)
{
  number_to_chars_littleendian (buf, val, n);
}

int
epiphany_elf_section_flags (int flags,
			    int attr ATTRIBUTE_UNUSED,
			    int type ATTRIBUTE_UNUSED)
{
  /* This is used to detect when the section changes to an executable section.
     This function is called by the elf section processing.  When we note an
     executable section specifier we set an internal flag to denote when
     word alignment should be forced.  */
  if (flags & SEC_CODE)
    force_code_align = TRUE;

  return flags;
}

/* Non-zero if we are generating PIC code.  */
int pic_code;

/* Epiphany er_flags.  */
static int epiphany_flags = 0;

/* Relocations against symbols are done in two
   parts, with a HI relocation and a LO relocation.  Each relocation
   has only 16 bits of space to store an addend.  This means that in
   order for the linker to handle carries correctly, it must be able
   to locate both the HI and the LO relocation.  This means that the
   relocations must appear in order in the relocation table.

   In order to implement this, we keep track of each unmatched HI
   relocation.  We then sort them so that they immediately precede the
   corresponding LO relocation.  */

struct epiphany_hi_fixup
{
  /* Next HI fixup.  */
  struct epiphany_hi_fixup *next;

  /* This fixup.  */
  fixS *fixp;

  /* The section this fixup is in.  */
  segT seg;
};


#define GOT_NAME "_GLOBAL_OFFSET_TABLE_"
static symbolS * GOT_symbol;

static inline bfd_boolean
epiphany_PIC_related_p (symbolS *sym)
{
  expressionS *exp;

  if (! sym)
    return FALSE;

  if (sym == GOT_symbol)
    return TRUE;

  exp = symbol_get_value_expression (sym);

  return (exp->X_op == O_PIC_reloc
	  || exp->X_md == BFD_RELOC_EPIPHANY_SIMM24
	  || exp->X_md == BFD_RELOC_EPIPHANY_SIMM8
	  || epiphany_PIC_related_p (exp->X_add_symbol)
	  || epiphany_PIC_related_p (exp->X_op_symbol));
}

/* Perform target dependent relocations that are done at compile time.
   There aren't very many of these.  */

void
epiphany_apply_fix (fixS *fixP, valueT *valP, segT seg)
{
  if (fixP->fx_addsy == (symbolS *) NULL)
    fixP->fx_done = 1;

  if (((int) fixP->fx_r_type < (int) BFD_RELOC_UNUSED)
      && fixP->fx_done)
    {
      /* Install EPIPHANY-dependent relocations HERE because nobody else
	 will.  */
      char *where = fixP->fx_frag->fr_literal + fixP->fx_where;
      unsigned char *insn = (unsigned char *)where;
      valueT value = * valP;

      switch (fixP->fx_r_type)
	{
	default:
	  break;

	case BFD_RELOC_NONE:
	  return;

	case BFD_RELOC_EPIPHANY_SIMM11:
	  where[0] = where[0] | ((value & 1) << 7);
	  where[1] = where[1] | ((value & 6) >> 1);
	  where[2] = (value >> 3) & 0xff;
	  return;

	case BFD_RELOC_EPIPHANY_IMM11:
	  where[0] = where[0] | ((value & 1) << 7);
	  where[1] = where[1] | ((value & 6) >> 1);
	  where[2] = (value >> 3) & 0xff;
	  return;

	case BFD_RELOC_EPIPHANY_SIMM8:
	  md_number_to_chars (where+1, value>>1, 1);
	  return;

	case BFD_RELOC_EPIPHANY_SIMM24:
	  md_number_to_chars (where+1, value>>1, 3);
	  return;

	case BFD_RELOC_EPIPHANY_HIGH:
	  value >>= 16;
	  /* fall thru */
	case BFD_RELOC_EPIPHANY_LOW:
	  value = (((value & 0xff) << 5) | insn[0])
	    | (insn[1] << 8)
	    | ((value & 0xff00) << 12)
	    | (insn[2] << 16);
	  md_number_to_chars (where, value, 3);
	  return;
	}
    }

  /* Just do the default if we can't special case.  */
  return gas_cgen_md_apply_fix (fixP, valP, seg);
}


/* This is called from HANDLE_ALIGN in write.c.  Fill in the contents
   of an rs_align_code fragment.  0x01a2 is 16-bit pattern for a "nop".  */

static const unsigned char nop_pattern[] = { 0xa2, 0x01 };

void
epiphany_handle_align (fragS *fragp)
{
  int bytes, fix;
  char *p;

  if (fragp->fr_type != rs_align_code)
    return;

  bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
  p = fragp->fr_literal + fragp->fr_fix;
  fix = 0;

  if (bytes & 1)
    {
      fix = 1;
      *p++ = 0;
      bytes--;
    }

  if (bytes & 2)
    {
      memcpy (p, nop_pattern, 2);
      p += 2;
      bytes -= 2;
      fix += 2;
    }
  fragp->fr_fix += fix;
}

/* Read a comma separated incrementing list of register names
   and form a bit mask of upto 15 registers 0..14.  */

static const char *
parse_reglist (const char * s, int * mask)
{
  int regmask = 0;

  while (*s)
    {
      long value;

      while (*s == ' ')
	++s;

      /* Parse a list with "," or "}" as limiters.  */
      const char *errmsg
	= cgen_parse_keyword (gas_cgen_cpu_desc, &s,
			      &epiphany_cgen_opval_gr_names, &value);
      if (errmsg)
	return errmsg;

      if (value > 15)
	return _("register number too large for push/pop");

      regmask |= 1 << value;
      if (regmask < *mask)
	return _("register is out of order");
      *mask |= regmask;

      while (*s==' ')
	++s;

      if (*s == '}')
	return NULL;
      else if (*s++ == ',')
	continue;
      else
	return _("bad register list");
    }

  return _("malformed reglist in push/pop");
}


/* Assemble an instruction,  push and pop pseudo instructions should have
   already been expanded.  */

static void
epiphany_assemble (const char *str)
    {
  epiphany_insn insn;
  char *errmsg = 0;

  memset (&insn, 0, sizeof (insn));

  /* Initialize GAS's cgen interface for a new instruction.  */
  gas_cgen_init_parse ();

  insn.insn = epiphany_cgen_assemble_insn
    (gas_cgen_cpu_desc, str, &insn.fields, insn.buffer, & errmsg);

  if (!insn.insn)
    {
      as_bad ("%s", errmsg);
      return;
    }

  if (CGEN_INSN_BITSIZE (insn.insn) == 32)
    {
      /* Doesn't really matter what we pass for RELAX_P here.  */
      gas_cgen_finish_insn (insn.insn, insn.buffer,
			    CGEN_FIELDS_BITSIZE (&insn.fields), 1, NULL);
    }
  else
    {
      if (CGEN_INSN_BITSIZE (insn.insn) != 16)
	abort ();

      insn.orig_insn = insn.insn;

      gas_cgen_finish_insn (insn.orig_insn, insn.buffer,
			    CGEN_FIELDS_BITSIZE (&insn.fields),
			    1 /* relax_p  */, NULL);
    }

  /* Checks for behavioral restrictions on LD/ST instructions.  */
#define DISPMOD _("destination register modified by displacement-post-modified address")
#define LDSTODD _("ldrd/strd requires even:odd register pair")

  /* Helper macros for spliting apart instruction fields.  */
#define ADDR_POST_MODIFIED(i) (((i) >> 25) & 0x1)
#define ADDR_SIZE(i)          (((i) >>  5) &   3)
#define ADDR_LOADSTORE(i)     (((i) >>  4) & 0x1)

  switch (insn.buffer[0] & 0xf)
    {
      /* Post-modify registers cannot be destinations.  */
    case OP4_LDSTR16P:
      {
	if (ADDR_LOADSTORE (insn.buffer[0]) ==  OP_LOAD)
	  if (insn.fields.f_rd == insn.fields.f_rn /* Postmodify dest.  */
	      || (insn.fields.f_rd+1 == insn.fields.f_rn
		  && ADDR_SIZE (insn.buffer[0]) == OPW_DOUBLE))
	    {
	      as_bad ("%s", DISPMOD);
	      return;
	    }
	if ((insn.fields.f_rd & 1) /* Odd-numbered register...  */
	    && insn.fields.f_wordsize == OPW_DOUBLE) /* ...and 64 bit transfer.  */
	  {
	    as_bad ("%s", LDSTODD);
	    return;
	  }
	break;
      }

    case OP4_LDSTRP:
      {
	if (ADDR_LOADSTORE (insn.buffer[0]) == OP_LOAD) /* A load.  */
	  if (insn.fields.f_rd6 == insn.fields.f_rn6 /* Postmodify dest.  */
	      /* Check for regpair postindexed.  */
	      || (insn.fields.f_rd6 + 1 == insn.fields.f_rn6
		  && ADDR_SIZE (insn.buffer[0]) == OPW_DOUBLE))
	    {
	      as_bad ("%s", DISPMOD);
	      return;
	    }
	if ((insn.fields.f_rd6 & 1) && ADDR_SIZE (insn.buffer[0]) == OPW_DOUBLE)
	  /* Lsb of RD odd and 64 bit transfer.  */
	  {
	    as_bad ("%s", LDSTODD);
	    return;
	  }
	break;
      }

    case OP4_LDSTR16X:
    case OP4_LDSTR16D:
      {
	/* Check for unaligned load/store double.  */
	if ((insn.fields.f_rd & 1) && ADDR_SIZE (insn.buffer[0]) == OPW_DOUBLE)
	  /* Lsb of RD odd and 64 bit transfer.  */
	  {
	    as_bad ("%s", LDSTODD);
	    return;
	  }
	break;
      }

    case OP4_LDSTRD:
      {
	/* Check for load to post-modified register.  */
	if (ADDR_LOADSTORE (insn.buffer[0]) == OP_LOAD /* A load.  */
	    && ADDR_POST_MODIFIED (insn.buffer[0]) == PMOD_POST /* Post-mod.  */
	    && (insn.fields.f_rd6 == insn.fields.f_rn6
		|| (insn.fields.f_rd6+1 == insn.fields.f_rn6
		    && ADDR_SIZE (insn.buffer[0]) == OPW_DOUBLE)))
	  {
	    as_bad ("%s", DISPMOD);
	    return;
	  }
      }
      /* fall-thru.  */

    case OP4_LDSTRX:
      {
	/* Check for unaligned load/store double.  */
	if ((insn.fields.f_rd6 & 1) && ADDR_SIZE (insn.buffer[0]) == OPW_DOUBLE)
	  {
	    as_bad ("%s", LDSTODD);
	    return;
	  }
	break;
      }

    default:
      break;
    }
}

void
md_assemble (char *str)
{
  const char * pperr = 0;
  int regmask=0, push=0, pop=0;

  /* Special-case push/pop instruction macros.  */
  if (0 == strncmp (str, "push {", 6))
    {
      char * s = str + 6;
      push = 1;
      pperr = parse_reglist (s, &regmask);
    }
  else if (0 == strncmp (str, "pop {", 5))
    {
      char * s = str + 5;
      pop = 1;
      pperr = parse_reglist (s, &regmask);
    }

  if (pperr)
    {
      as_bad ("%s", pperr);
      return;
    }

  if (push && regmask)
    {
      char buff[20];
      int i,p ATTRIBUTE_UNUSED;

      epiphany_assemble ("mov r15,4");
      epiphany_assemble ("sub sp,sp,r15");

      for (i = 0, p = 1; i <= 15; ++i, regmask >>= 1)
	{
	  if (regmask == 1)
	    sprintf (buff, "str r%d,[sp]", i); /* Last one.  */
	  else if (regmask & 1)
	    sprintf (buff, "str r%d,[sp],-r15", i);
	  else
	    continue;
	  epiphany_assemble (buff);
	}
      return;
    }
  else if (pop && regmask)
    {
      char buff[20];
      int i,p;

      epiphany_assemble ("mov r15,4");

      for (i = 15, p = 1 << 15; i >= 0; --i, p >>= 1)
	if (regmask & p)
	  {
	    sprintf (buff, "ldr r%d,[sp],+r15", i);
	    epiphany_assemble (buff);
	  }
      return;
    }

  epiphany_assemble (str);
}

/* The syntax in the manual says constants begin with '#'.
   We just ignore it.  */

void
md_operand (expressionS *expressionP)
{
  if (*input_line_pointer == '#')
    {
      input_line_pointer++;
      expression (expressionP);
    }
}

symbolS *
md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
{
  return NULL;
}

/* Interface to relax_segment.  */

/* FIXME: Build table by hand, get it working, then machine generate.  */

const relax_typeS md_relax_table[] =
{
  /* The fields are:
     1) most positive reach of this state,
     2) most negative reach of this state,
     3) how many bytes this mode will add to the size of the current frag
     4) which index into the table to try if we can't fit into this one.  */

  /* The first entry must be unused because an `rlx_more' value of zero ends
     each list.  */
  {1, 1, 0, EPIPHANY_RELAX_NONE},
  {0, 0, 0, EPIPHANY_RELAX_NONE},    /* Also a dummy entry to indicate we need to expand codes.  */

  /* The displacement used by GAS is from the end of the 2 byte insn,
     so we subtract 2 from the following.  */
  /* 16 bit insn, 8 bit disp -> +127 words, -128 words.  */
  {0x00000100 - 1 - 2, -0x00000100 - 2, 0, EPIPHANY_RELAX_BRANCH_LONG },
  /* 32 bit insn, 24 bit disp -> 25 bit range.  */
  {0x01000000 - 1 - 2, -0x01000000 - 2, 2, EPIPHANY_RELAX_NONE },

  /* addi/subi 3 bits -4..+3.  */
  {    3,           -4,0, EPIPHANY_RELAX_ARITH_SIMM11 },
  /* addi/subi 11 bits.  */
  {  1023,       -1024,2, EPIPHANY_RELAX_NONE },

  /* mov r,imm8.  */
  {   255,           0,0, EPIPHANY_RELAX_MOV_IMM16 },
  /* mov r,imm16. */
  { 65535,           0,2, EPIPHANY_RELAX_NONE },

  /* ld/st rd,[rn,imm3].  */
  {     7,           0,0, EPIPHANY_RELAX_LDST_IMM11},
  /* ld/st rd,[rn,imm11].  */
  {  2047,           0,2, EPIPHANY_RELAX_NONE }

};

static const EPIPHANY_RELAX_TYPES relax_insn[] =
{
  EPIPHANY_RELAX_BRANCH_SHORT,	/* OP4_BRANCH16 */
  EPIPHANY_RELAX_NONE,		/* OP4_LDSTR16X */
  EPIPHANY_RELAX_NONE,		/* OP4_FLOW16 */
  EPIPHANY_RELAX_ARITH_SIMM3,	/* OP4_IMM16 - special */
  EPIPHANY_RELAX_LDST_IMM3,	/* OP4_LDSTR16D */
  EPIPHANY_RELAX_NONE,		/* OP4_LDSTR126P */
  EPIPHANY_RELAX_NONE,		/* OP4_LSHIFT16 */
  EPIPHANY_RELAX_NONE,		/* OP4_DSP16 */
  EPIPHANY_RELAX_BRANCH_LONG,	/* OP4_BRANCH */
  EPIPHANY_RELAX_NONE,		/* OP4_LDSTRX */
  EPIPHANY_RELAX_NONE,		/* OP4_ALU16 */
  EPIPHANY_RELAX_ARITH_SIMM11,	/* OP4_IMM32 - special */
  EPIPHANY_RELAX_LDST_IMM11,	/* OP4_LDSTRD */
  EPIPHANY_RELAX_NONE,		/* OP4_LDSTRP */
  EPIPHANY_RELAX_NONE,		/* OP4_ASHIFT16 */
  EPIPHANY_RELAX_NONE		/* OP4_MISC */
};

long
epiphany_relax_frag (segT segment, fragS *fragP, long stretch)
{
  /* Address of branch insn.  */
  long address ATTRIBUTE_UNUSED = fragP->fr_address + fragP->fr_fix - 2;
  long growth = 0;

  if (fragP->fr_subtype == EPIPHANY_RELAX_NEED_RELAXING)
    {
      EPIPHANY_RELAX_TYPES subtype = relax_insn [*fragP->fr_opcode & 0xf];

      /* Special cases add/sub vs mov immediates.  */
      if (subtype == EPIPHANY_RELAX_ARITH_SIMM3)
	{
	  if ((*fragP->fr_opcode & 0x10) == 0)
	    subtype = EPIPHANY_RELAX_MOV_IMM8;
	}
      else if (subtype == EPIPHANY_RELAX_ARITH_SIMM11)
	{
	  if ((*fragP->fr_opcode & 0x10) == 0)
	    subtype = EPIPHANY_RELAX_MOV_IMM16;
	}

      /* Remember refinements for the future.  */
      fragP->fr_subtype = subtype;
    }

  growth = relax_frag (segment, fragP, stretch);

  return growth;
}

/* Return an initial guess of the length by which a fragment must grow to
   hold a branch to reach its destination.
   Also updates fr_type/fr_subtype as necessary.

   Called just before doing relaxation.
   Any symbol that is now undefined will not become defined.
   The guess for fr_var is ACTUALLY the growth beyond fr_fix.
   Whatever we do to grow fr_fix or fr_var contributes to our returned value.
   Although it may not be explicit in the frag, pretend fr_var starts
   with a 0 value.  */

int
md_estimate_size_before_relax (fragS *fragP, segT segment)
{
  /* The only thing we have to handle here are symbols outside of the
     current segment.  They may be undefined or in a different segment in
     which case linker scripts may place them anywhere.
     However, we can't finish the fragment here and emit the reloc as insn
     alignment requirements may move the insn about.  */
  if (S_GET_SEGMENT (fragP->fr_symbol) != segment
      || S_IS_EXTERNAL (fragP->fr_symbol)
      || S_IS_WEAK (fragP->fr_symbol))
    {
      /* The symbol is undefined in this segment.  Change the
	 relaxation subtype to the max allowable and leave all further
	 handling to md_convert_frag.  */

      EPIPHANY_RELAX_TYPES subtype;
      /* We haven't relaxed this at all, so the relaxation type may be
	 completely wrong.  Set the subtype correctly.  */
      epiphany_relax_frag (segment, fragP, 0);
      subtype = fragP->fr_subtype;

      switch (subtype)
	{
	case EPIPHANY_RELAX_LDST_IMM3:
	  subtype = EPIPHANY_RELAX_LDST_IMM11;
	  break;
	case EPIPHANY_RELAX_BRANCH_SHORT:
	  subtype = EPIPHANY_RELAX_BRANCH_LONG;
	  break;
	case EPIPHANY_RELAX_MOV_IMM8:
	  subtype = EPIPHANY_RELAX_MOV_IMM16;
	  break;
	case EPIPHANY_RELAX_ARITH_SIMM3:
	  subtype = EPIPHANY_RELAX_ARITH_SIMM11;
	  break;

	default:
	  break;
	}

      fragP->fr_subtype = subtype;

      {
	const CGEN_INSN *insn;
	int i;

	/* Update the recorded insn.  */

	for (i = 0, insn = fragP->fr_cgen.insn; i < 4; i++, insn++)
	  {
	    if ((strcmp (CGEN_INSN_MNEMONIC (insn),
			 CGEN_INSN_MNEMONIC (fragP->fr_cgen.insn))
		 == 0)
		&& CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXED))
	      break;
	  }

	if (i == 4)
	  abort ();

	fragP->fr_cgen.insn = insn;
      }
    }

  return md_relax_table[fragP->fr_subtype].rlx_length;
}

/* *FRAGP has been relaxed to its final size, and now needs to have
   the bytes inside it modified to conform to the new size.

   Called after relaxation is finished.
   fragP->fr_type == rs_machine_dependent.
   fragP->fr_subtype is the subtype of what the address relaxed to.  */

void
md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
		 segT sec,
		 fragS *fragP)
{
  char *opcode;
  char *displacement;
  int target_address;
  int opcode_address;
  int extension;
  int addend;
  int opindx = -1;

  opcode = fragP->fr_opcode;

  /* Address opcode resides at in file space.  */
  opcode_address = fragP->fr_address + fragP->fr_fix - 2;
  extension = 0;
  displacement = &opcode[1];

  /* Set up any addend necessary for branches.  */
  if (S_GET_SEGMENT (fragP->fr_symbol) != sec
      || S_IS_EXTERNAL (fragP->fr_symbol)
      || S_IS_WEAK (fragP->fr_symbol))
    {
      /* Symbol must be resolved by linker.  */
      if (fragP->fr_offset & 1)
	as_warn (_("Addend to unresolved symbol not on word boundary."));
      addend = 0;
    }
  else
    {
      /* Address we want to reach in file space.  */
      target_address = S_GET_VALUE (fragP->fr_symbol) + fragP->fr_offset;
      addend = (target_address - (opcode_address & -2));
    }

  /* Do all the housekeeping for frag conversions. */
  switch (fragP->fr_subtype)
    {
    case EPIPHANY_RELAX_ARITH_SIMM11:
      *opcode |= OP4_IMM32;
      displacement = &opcode[0];
      extension += 3;

      addend
	= (((addend & 0x7) << 7)
	   | opcode[0]
	   | ((addend & 0x7f8) << 13)
	   | (opcode[1] << 8)
	   | (opcode[2] << 16));

      opindx = EPIPHANY_OPERAND_SIMM11;
      break;

    case EPIPHANY_RELAX_BRANCH_LONG:
      /* Branches differ only in low nibble of instruction being 8 not 0.
	 24 bit displacement goes to bytes 1..3 .  */
      *opcode |= OP4_BRANCH;
      extension += 2;

      addend >>= 1;		/* Convert to word offset.  */
      opindx = EPIPHANY_OPERAND_SIMM24;
      break;

    case EPIPHANY_RELAX_MOV_IMM16:
      *opcode |=  OP4_IMM32;
      extension += 3;

      addend
	= (((addend & 0xff00) << 12)
	   | (opcode[2] << 16)
	   | ((addend & 0x00ff) << 5)
	   | (opcode[1] << 8)
	   | opcode[0]);
      displacement = &opcode[0];
      opindx = EPIPHANY_OPERAND_IMM16;
      break;

    case EPIPHANY_RELAX_LDST_IMM11:
      *opcode |= OP4_LDSTRD;
      displacement = &opcode[0];
      extension += 3;

      if (addend < 0)
	/* Convert twos-complement address value to sign-magnitude.  */
	addend = (-addend & 0x7ff) | 0x800;

      addend
	= (((addend & 0x7) << 5)
	   | opcode[0]
	   | ((addend & 0xff8) << 13)
	   | (opcode[1] << 8)
	   | (opcode[2] << 16));

      opindx = EPIPHANY_OPERAND_DISP11;
      break;

    case EPIPHANY_RELAX_ARITH_SIMM3:
      addend = ((addend & 7) << 5) | opcode[0];
      opindx = EPIPHANY_OPERAND_SIMM3;
      break;

    case EPIPHANY_RELAX_LDST_IMM3:
      addend = ((addend & 7) << 5) | opcode[0];
      opindx = EPIPHANY_OPERAND_DISP3;
      break;

    case EPIPHANY_RELAX_BRANCH_SHORT:
      addend >>= 1;		/* Convert to a word offset.  */
      displacement = & opcode[1];
      opindx = EPIPHANY_OPERAND_SIMM8;
      break;

    case EPIPHANY_RELAX_MOV_IMM8:
      addend
	= (((addend & 0xff) << 5)
	   | opcode[0]
	   | (opcode[1] << 8));
      opindx = EPIPHANY_OPERAND_IMM8;
      break;

    case EPIPHANY_RELAX_NONE:
    case EPIPHANY_RELAX_NEED_RELAXING:
    default:			/* Anything else?  */
      as_bad ("unrecognized fragment subtype");
      break;
    }

  /* Create a relocation for symbols that must be resolved by the linker.
     Otherwise output the completed insn.  */

  if (S_GET_SEGMENT (fragP->fr_symbol) != sec
      || S_IS_EXTERNAL (fragP->fr_symbol)
      || S_IS_WEAK (fragP->fr_symbol))
    {
      fixS *fixP;
      const CGEN_OPERAND *operand
	= cgen_operand_lookup_by_num (gas_cgen_cpu_desc, opindx);
      bfd_reloc_code_real_type reloc_type;

      gas_assert (fragP->fr_cgen.insn != 0);

      reloc_type = md_cgen_lookup_reloc (fragP->fr_cgen.insn, operand, NULL);

      fixP = gas_cgen_record_fixup (fragP,
				    /* Offset of insn in frag.  */
				    (opcode - fragP->fr_literal),
				    fragP->fr_cgen.insn,
				    CGEN_INSN_BITSIZE (fragP->fr_cgen.insn) / 8,
				    operand,
				    reloc_type,
				    fragP->fr_symbol, fragP->fr_offset);
      fixP->fx_r_type = fixP->fx_cgen.opinfo;
    }

  md_number_to_chars (displacement, (valueT) addend, extension + 1);

  fragP->fr_fix += (extension & -2); /* 0,2 or 4 bytes added.  */
}


/* Functions concerning relocs.  */

/* The location from which a PC relative jump should be calculated,
   given a PC relative reloc.  */

long
md_pcrel_from_section (fixS *fixP, segT sec)
{
  if (fixP->fx_addsy != (symbolS *) NULL
      && (!S_IS_DEFINED (fixP->fx_addsy)
	  || (S_GET_SEGMENT (fixP->fx_addsy) != sec)
	  || S_IS_EXTERNAL (fixP->fx_addsy)
	  || S_IS_WEAK (fixP->fx_addsy)))
    return 0;

  return fixP->fx_frag->fr_address + fixP->fx_where;
}

/* Return the bfd reloc type for OPERAND of INSN at fixup FIXP.
   Returns BFD_RELOC_NONE if no reloc type can be found.
   *FIXP may be modified if desired.  */

bfd_reloc_code_real_type
md_cgen_lookup_reloc (const CGEN_INSN *insn ATTRIBUTE_UNUSED,
		      const CGEN_OPERAND *operand,
		      fixS *fixP ATTRIBUTE_UNUSED)
{
  switch (operand->type)
    {
    case EPIPHANY_OPERAND_SIMM11:
      return BFD_RELOC_EPIPHANY_SIMM11;
    case EPIPHANY_OPERAND_DISP11:
      return BFD_RELOC_EPIPHANY_IMM11;

    case EPIPHANY_OPERAND_SIMM8:
      return BFD_RELOC_EPIPHANY_SIMM8;
    case EPIPHANY_OPERAND_SIMM24:
      return BFD_RELOC_EPIPHANY_SIMM24;

    case EPIPHANY_OPERAND_IMM8:
      return BFD_RELOC_EPIPHANY_IMM8;

    case EPIPHANY_OPERAND_IMM16:
      if (0 == strcmp ("movt", CGEN_INSN_MNEMONIC (insn)))
	return BFD_RELOC_EPIPHANY_HIGH;
      else if (0 == strcmp ("mov", CGEN_INSN_MNEMONIC (insn)))
	return BFD_RELOC_EPIPHANY_LOW;
      else
	as_bad ("unknown imm16 operand");
      /* fall-thru */

    default:
      break;
    }
  return BFD_RELOC_NONE;
}

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

/* Equal to MAX_PRECISION in atof-ieee.c.  */
#define MAX_LITTLENUMS 6

const char *
md_atof (int type, char *litP, int *sizeP)
{
  return ieee_md_atof (type, litP, sizeP, FALSE);
}

/* Return true if can adjust the reloc to be relative to its section
   (such as .data) instead of relative to some symbol.  */

bfd_boolean
epiphany_fix_adjustable (fixS *fixP)
{
 bfd_reloc_code_real_type reloc_type;

  if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
    {
      const CGEN_INSN *insn = fixP->fx_cgen.insn;
      int opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED;
      const CGEN_OPERAND *operand =
	cgen_operand_lookup_by_num (gas_cgen_cpu_desc, opindex);

      reloc_type = md_cgen_lookup_reloc (insn, operand, fixP);
    }
  else
    reloc_type = fixP->fx_r_type;

  if (fixP->fx_addsy == NULL)
    return TRUE;

  /* Prevent all adjustments to global symbols.  */
  if (S_IS_EXTERNAL (fixP->fx_addsy))
    return FALSE;

  if (S_IS_WEAK (fixP->fx_addsy))
    return FALSE;

  if (pic_code
      && (reloc_type == BFD_RELOC_EPIPHANY_SIMM24
	  || reloc_type == BFD_RELOC_EPIPHANY_SIMM8
	  || reloc_type == BFD_RELOC_EPIPHANY_HIGH
	  || reloc_type == BFD_RELOC_EPIPHANY_LOW))
    return FALSE;

  /* Since we don't use partial_inplace, we must not reduce symbols in
     mergable sections to their section symbol.  */
  if ((S_GET_SEGMENT (fixP->fx_addsy)->flags & SEC_MERGE) != 0)
    return FALSE;

  return TRUE;
}

void
epiphany_elf_final_processing (void)
{
  elf_elfheader (stdoutput)->e_flags |= epiphany_flags;
}

int
epiphany_cgen_parse_fix_exp (int opinfo, expressionS *exp ATTRIBUTE_UNUSED)
{
  LITTLENUM_TYPE words[2];

  switch (opinfo)
    {
    case BFD_RELOC_EPIPHANY_LOW:
    case BFD_RELOC_EPIPHANY_HIGH:
      break;
    default:
      return opinfo;
    }

  /* Doing a %LOW or %HIGH.  */
  switch (exp->X_op)
    {
    default:
      return opinfo;
    case O_big:				/* Bignum.  */
      if (exp->X_add_number > 0)	/* Integer value too large.  */
	return opinfo;
    }

  /* Convert to SP number.  */
  gen_to_words (words, 2, 8L);
  exp->X_add_number = words[1] | (words[0] << 16);
  exp->X_op = O_constant;
  return opinfo;
}
