/* tc-epiphany.c -- Assembler for the Adapteva EPIPHANY
   Copyright 2009, 2011 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)
    {
      /* The s_align_ptwo function expects that we are just after a .align
	 directive and it will either try and read the align value or stop
	 if end of line so we must fake it out so it thinks we are at the
	 end of the line.  */
      char *old_input_line_pointer = input_line_pointer;

      input_line_pointer = "\n";
      s_align_ptwo (1);
      force_code_align = FALSE;

      /* Restore.  */
      input_line_pointer = old_input_line_pointer;
    }
}

static void
epiphany_elf_section_text (int i)
{
  char *old_input_line_pointer;

  obj_elf_text (i);

  /* The s_align_ptwo function expects that we are just after a .align
     directive and it will either try and read the align value or stop if
     end of line so we must fake it out so it thinks we are at the end of
     the line.  */
  old_input_line_pointer = input_line_pointer;
  input_line_pointer = "\n";
  s_align_ptwo (1);
  force_code_align = FALSE;
  /* Restore.  */
  input_line_pointer = old_input_line_pointer;
}

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

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

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

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

      md_assemble ("mov r15,4");
      md_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;
	  md_assemble (buff);
	}
      return;
    }
  else if (pop && regmask)
    {
      char buff[20];
      int i,p;

      md_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);
	    md_assemble (buff);
	  }
      return;
    }

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

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

    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

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;
}
