/* tc-m32r.c -- Assembler for the Mitsubishi M32R.
   Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation.

   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 2, 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, 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.  */

#include <stdio.h>
#include <ctype.h>
#include "as.h"
#include "subsegs.h"     
#include "symcat.h"
#include "opcodes/m32r-desc.h"
#include "opcodes/m32r-opc.h"
#include "cgen.h"

/* Linked list of symbols that are debugging symbols to be defined as the
   beginning of the current instruction.  */
typedef struct sym_link
{
  struct sym_link *next;
  symbolS	  *symbol;
} sym_linkS;

static sym_linkS *debug_sym_link = (sym_linkS *)0;
  
/* 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];
  sym_linkS		*debug_sym_link;
}
m32r_insn;

/* prev_insn.insn is non-null if last insn was a 16 bit insn on a 32 bit
   boundary (i.e. was the first of two 16 bit insns).  */
static m32r_insn	prev_insn;

/* Non-zero if we've seen a relaxable insn since the last 32 bit
   alignment request.  */
static int seen_relaxable_p = 0;

/* Non-zero if -relax specified, in which case sufficient relocs are output
   for the linker to do relaxing.
   We do simple forms of relaxing internally, but they are always done.
   This flag does not apply to them.  */
static int m32r_relax;

#if 0 /* not supported yet */
/* If non-NULL, pointer to cpu description file to read.
   This allows runtime additions to the assembler.  */
static const char * m32r_cpu_desc;
#endif

/* Non-zero if warn when a high/shigh reloc has no matching low reloc.
   Each high/shigh reloc must be paired with it's low cousin in order to
   properly calculate the addend in a relocatable link (since there is a
   potential carry from the low to the high/shigh).
   This option is off by default though for user-written assembler code it
   might make sense to make the default be on (i.e. have gcc pass a flag
   to turn it off).  This warning must not be on for GCC created code as
   optimization may delete the low but not the high/shigh (at least we
   shouldn't assume or require it to).  */
static int warn_unmatched_high = 0;


/* stuff for .scomm symbols.  */
static segT     sbss_section;
static asection scom_section;
static asymbol  scom_symbol;

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

/* 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 m32r_hi_fixup
{
  struct m32r_hi_fixup * next;  /* Next HI fixup.  */
  fixS *                 fixp;  /* This fixup.  */
  segT                   seg;   /* The section this fixup is in.  */

};

/* The list of unmatched HI relocs.  */

static struct m32r_hi_fixup * m32r_hi_fixup_list;



#define M32R_SHORTOPTS ""
const char * md_shortopts = M32R_SHORTOPTS;

struct option md_longopts[] =
{

  /* Sigh.  I guess all warnings must now have both variants.  */
#define OPTION_WARN_UNMATCHED (OPTION_MD_BASE + 4)
  {"warn-unmatched-high", no_argument, NULL, OPTION_WARN_UNMATCHED},
  {"Wuh", no_argument, NULL, OPTION_WARN_UNMATCHED},
#define OPTION_NO_WARN_UNMATCHED (OPTION_MD_BASE + 5)
  {"no-warn-unmatched-high", no_argument, NULL, OPTION_WARN_UNMATCHED},
  {"Wnuh", no_argument, NULL, OPTION_WARN_UNMATCHED},

#if 0 /* not supported yet */
#define OPTION_RELAX  (OPTION_MD_BASE + 6)
  {"relax", no_argument, NULL, OPTION_RELAX},
#define OPTION_CPU_DESC (OPTION_MD_BASE + 7)
  {"cpu-desc", required_argument, NULL, OPTION_CPU_DESC},
#endif

  {NULL, no_argument, NULL, 0}
};
size_t md_longopts_size = sizeof (md_longopts);

int
md_parse_option (c, arg)
     int    c;
     char * arg;
{
  switch (c)
    {

    case OPTION_WARN_UNMATCHED:
      warn_unmatched_high = 1;
      break;

    case OPTION_NO_WARN_UNMATCHED:
      warn_unmatched_high = 0;
      break;
      
#if 0 /* not supported yet */
    case OPTION_RELAX:
      m32r_relax = 1;
      break;
    case OPTION_CPU_DESC:
      m32r_cpu_desc = arg;
      break;
#endif

    default:
      if (arg)
	fprintf (stderr, _("%s: unrecognised command line option: -%c\n"), myname, c);
      else
	fprintf (stderr, _("%s: unrecognised command line option: -%c%s\n"), myname, c, arg);
      return 0;
    }
  return 1;
}

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


  fprintf (stream, _("\
  -warn-unmatched-high    warn when an (s)high reloc has no matching low reloc\n"));
  fprintf (stream, _("\
  -no-warn-unmatched-high do not warn about missing low relocs\n"));
  fprintf (stream, _("\
  -Wuh                    synonym for -warn-unmatched-high\n"));
  fprintf (stream, _("\
  -Wnuh                   synonym for -no-warn-unmatched-high\n"));

#if 0
  fprintf (stream, _("\
  -relax                 create linker relaxable code\n"));
  fprintf (stream, _("\
  -cpu-desc              provide runtime cpu description file\n"));
#endif
} 

static void fill_insn PARAMS ((int));
static void m32r_scomm PARAMS ((int));
static void debug_sym PARAMS ((int));
static void expand_debug_syms PARAMS ((sym_linkS *, int));

/* Set by md_assemble for use by m32r_fill_insn.  */
static subsegT prev_subseg;
static segT prev_seg;

/* The target specific pseudo-ops which we support.  */
const pseudo_typeS md_pseudo_table[] =
{
  { "word",	cons,		4 },
  { "fillinsn", fill_insn,	0 },
  { "scomm",	m32r_scomm,	0 },
  { "debugsym",	debug_sym,	0 },
  { NULL, NULL, 0 }
};

/* FIXME: Should be machine generated.  */
#define NOP_INSN 0x7000
#define PAR_NOP_INSN 0xf000 /* can only be used in 2nd slot */

/* When we align the .text section, insert the correct NOP pattern.
   N is the power of 2 alignment.  LEN is the length of pattern FILL.
   MAX is the maximum number of characters to skip when doing the alignment,
   or 0 if there is no maximum.  */

int
m32r_do_align (n, fill, len, max)
     int          n;
     const char * fill;
     int          len;
     int          max;
{
  /* Only do this if the fill pattern wasn't specified.  */
  if (fill == NULL
      && subseg_text_p (now_seg)
      /* Only do this special handling if aligning to at least a
	 4 byte boundary.  */
      && n > 1
     /* Only do this special handling if we're allowed to emit at
	 least two bytes.  */
      && (max == 0 || max > 1))
    {
      static const unsigned char nop_pattern[] = { 0xf0, 0x00 };

#if 0
      /* First align to a 2 byte boundary, in case there is an odd .byte.  */
      /* FIXME: How much memory will cause gas to use when assembling a big
	 program?  Perhaps we can avoid the frag_align call?  */
      frag_align (1, 0, 0);
#endif
      /* Next align to a 4 byte boundary (we know n >= 2) using a parallel
	 nop.  */
      frag_align_pattern (2, nop_pattern, sizeof nop_pattern, 0);
      /* If doing larger alignments use a repeating sequence of appropriate
	 nops.  */
      if (n > 2)
	{
	  static const unsigned char multi_nop_pattern[] =
	  { 0x70, 0x00, 0xf0, 0x00 };
	  frag_align_pattern (n, multi_nop_pattern, sizeof multi_nop_pattern,
			      max ? max - 2 : 0);
	}
      
      prev_insn.insn = NULL;
      return 1;
    }

  return 0;
}

/* If the last instruction was the first of 2 16 bit insns,
   output a nop to move the PC to a 32 bit boundary.

   This is done via an alignment specification since branch relaxing
   may make it unnecessary.

   Internally, we need to output one of these each time a 32 bit insn is
   seen after an insn that is relaxable.  */

static void
fill_insn (ignore)
     int ignore;
{
  (void) m32r_do_align (2, NULL, 0, 0);
  prev_insn.insn = NULL;
  seen_relaxable_p = 0;
}

/* Record the symbol so that when we output the insn, we can create
   a symbol that is at the start of the instruction.  This is used
   to emit the label for the start of a breakpoint without causing
   the assembler to emit a NOP if the previous instruction was a
   16 bit instruction.  */

static void
debug_sym (ignore)
     int ignore;
{
  register char *name;
  register char delim;
  register char *end_name;
  register symbolS *symbolP;
  register sym_linkS *link;

  name = input_line_pointer;
  delim = get_symbol_end ();
  end_name = input_line_pointer;
 
  if ((symbolP = symbol_find (name)) == NULL
      && (symbolP = md_undefined_symbol (name)) == NULL)
    {
      symbolP = symbol_new (name, undefined_section, 0, &zero_address_frag);
    }

  symbol_table_insert (symbolP);
  if (S_IS_DEFINED (symbolP) && S_GET_SEGMENT (symbolP) != reg_section)
    /* xgettext:c-format */
    as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP));

  else
    {
      link = (sym_linkS *) xmalloc (sizeof (sym_linkS));
      link->symbol = symbolP;
      link->next = debug_sym_link;
      debug_sym_link = link;
      symbol_get_obj (symbolP)->local = 1;
    }

  *end_name = delim;
  demand_empty_rest_of_line ();
}

/* Second pass to expanding the debug symbols, go through linked
   list of symbols and reassign the address.  */

static void
expand_debug_syms (syms, align)
     sym_linkS *syms;
     int align;
{
  char *save_input_line = input_line_pointer;
  sym_linkS *next_syms;

  if (!syms)
    return;

  (void) m32r_do_align (align, NULL, 0, 0);
  for (; syms != (sym_linkS *)0; syms = next_syms)
    {
      symbolS *symbolP = syms->symbol;
      next_syms = syms->next;
      input_line_pointer = ".\n";
      pseudo_set (symbolP);
      free ((char *)syms);
    }

  input_line_pointer = save_input_line;
}

/* Cover function to fill_insn called after a label and at end of assembly.
   The result is always 1: we're called in a conditional to see if the
   current line is a label.  */

int
m32r_fill_insn (done)
     int done;
{
  if (prev_seg != NULL)
    {
      segT    seg    = now_seg;
      subsegT subseg = now_subseg;

      subseg_set (prev_seg, prev_subseg);
      
      fill_insn (0);

      subseg_set (seg, subseg);
    }

  if (done && debug_sym_link)
    {
      expand_debug_syms (debug_sym_link, 1);
      debug_sym_link = (sym_linkS *)0;
    }

  return 1;
}

void
md_begin ()
{
  flagword applicable;
  segT     seg;
  subsegT  subseg;

  /* Initialize the `cgen' interface.  */
  
  /* Set the machine number and endian.  */
  gas_cgen_cpu_desc = m32r_cgen_cpu_open (CGEN_CPU_OPEN_MACHS, 0,
					  CGEN_CPU_OPEN_ENDIAN,
					  CGEN_ENDIAN_BIG,
					  CGEN_CPU_OPEN_END);
  m32r_cgen_init_asm (gas_cgen_cpu_desc);

  /* The operand instance table is used during optimization to determine
     which insns can be executed in parallel.  It is also used to give
     warnings regarding operand interference in parallel insns.  */
  m32r_cgen_init_opinst_table (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);

#if 0 /* not supported yet */
  /* If a runtime cpu description file was provided, parse it.  */
  if (m32r_cpu_desc != NULL)
    {
      const char * errmsg;

      errmsg = cgen_read_cpu_file (gas_cgen_cpu_desc, m32r_cpu_desc);
      if (errmsg != NULL)
	as_bad ("%s: %s", m32r_cpu_desc, errmsg);
    }
#endif

  /* Save the current subseg so we can restore it [it's the default one and
     we don't want the initial section to be .sbss].  */
  seg    = now_seg;
  subseg = now_subseg;

  /* The sbss section is for local .scomm symbols.  */
  sbss_section = subseg_new (".sbss", 0);
  
  /* This is copied from perform_an_assembly_pass.  */
  applicable = bfd_applicable_section_flags (stdoutput);
  bfd_set_section_flags (stdoutput, sbss_section, applicable & SEC_ALLOC);
  
#if 0 /* What does this do? [see perform_an_assembly_pass]  */
  seg_info (bss_section)->bss = 1;
#endif

  subseg_set (seg, subseg);

  /* We must construct a fake section similar to bfd_com_section
     but with the name .scommon.  */
  scom_section                = bfd_com_section;
  scom_section.name           = ".scommon";
  scom_section.output_section = & scom_section;
  scom_section.symbol         = & scom_symbol;
  scom_section.symbol_ptr_ptr = & scom_section.symbol;
  scom_symbol                 = * bfd_com_section.symbol;
  scom_symbol.name            = ".scommon";
  scom_symbol.section         = & scom_section;

}



void
md_assemble (str)
     char * str;
{
  m32r_insn insn;
  char *    errmsg;
  char *    str2 = NULL;

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

  
  insn.debug_sym_link = debug_sym_link;
  debug_sym_link = (sym_linkS *)0;

  insn.insn = m32r_cgen_assemble_insn
    (gas_cgen_cpu_desc, str, & insn.fields, insn.buffer, & errmsg);
  
  if (!insn.insn)
    {
      as_bad (errmsg);
      return;
    }

  
  if (CGEN_INSN_BITSIZE (insn.insn) == 32)
    {
      /* 32 bit insns must live on 32 bit boundaries.  */
      if (prev_insn.insn || seen_relaxable_p)
	{
	  /* ??? If calling fill_insn too many times turns us into a memory
	     pig, can we call a fn to assemble a nop instead of
	     !seen_relaxable_p?  */
	  fill_insn (0);
	}

      expand_debug_syms (insn.debug_sym_link, 2);

      /* 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
    {
      int on_32bit_boundary_p;

      if (CGEN_INSN_BITSIZE (insn.insn) != 16)
	abort();

      insn.orig_insn = insn.insn;

      /* Compute whether we're on a 32 bit boundary or not.
	 prev_insn.insn is NULL when we're on a 32 bit boundary.  */
      on_32bit_boundary_p = prev_insn.insn == NULL;


      expand_debug_syms (insn.debug_sym_link, 1);

      {
	int i;
	finished_insnS fi;

	/* Ensure each pair of 16 bit insns is in the same frag.  */
	frag_grow (4);

	gas_cgen_finish_insn (insn.orig_insn, insn.buffer,
			      CGEN_FIELDS_BITSIZE (& insn.fields),
			      1 /*relax_p*/, &fi);
	insn.addr = fi.addr;
	insn.frag = fi.frag;
	insn.num_fixups = fi.num_fixups;
	for (i = 0; i < fi.num_fixups; ++i)
	  insn.fixups[i] = fi.fixups[i];
      }


      /* Keep track of whether we've seen a pair of 16 bit insns.
	 prev_insn.insn is NULL when we're on a 32 bit boundary.  */
      if (on_32bit_boundary_p)
	prev_insn = insn;
      else
	prev_insn.insn = NULL;
      
      /* If the insn needs the following one to be on a 32 bit boundary
	 (e.g. subroutine calls), fill this insn's slot.  */
      if (on_32bit_boundary_p
	  && CGEN_INSN_ATTR_VALUE (insn.orig_insn, CGEN_INSN_FILL_SLOT) != 0)
	fill_insn (0);

      /* If this is a relaxable insn (can be replaced with a larger version)
	 mark the fact so that we can emit an alignment directive for a
	 following 32 bit insn if we see one.   */
      if (CGEN_INSN_ATTR_VALUE (insn.orig_insn, CGEN_INSN_RELAXABLE) != 0)
	seen_relaxable_p = 1;
    }

  /* Set these so m32r_fill_insn can use them.  */
  prev_seg    = now_seg;
  prev_subseg = now_subseg;
}

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

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

valueT
md_section_align (segment, size)
     segT   segment;
     valueT size;
{
  int align = bfd_get_section_alignment (stdoutput, segment);
  return ((size + (1 << align) - 1) & (-1 << align));
}

symbolS *
md_undefined_symbol (name)
  char * name;
{
  return 0;
}

/* .scomm pseudo-op handler.

   This is a new pseudo-op to handle putting objects in .scommon.
   By doing this the linker won't need to do any work and more importantly
   it removes the implicit -G arg necessary to correctly link the object file.
*/

static void
m32r_scomm (ignore)
     int ignore;
{
  register char *    name;
  register char      c;
  register char *    p;
  offsetT            size;
  register symbolS * symbolP;
  offsetT            align;
  int                align2;

  name = input_line_pointer;
  c = get_symbol_end ();

  /* just after name is now '\0' */
  p = input_line_pointer;
  * p = c;
  SKIP_WHITESPACE ();
  if (* input_line_pointer != ',')
    {
      as_bad (_("Expected comma after symbol-name: rest of line ignored."));
      ignore_rest_of_line ();
      return;
    }

  input_line_pointer ++;		/* skip ',' */
  if ((size = get_absolute_expression ()) < 0)
    {
      /* xgettext:c-format */
      as_warn (_(".SCOMMon length (%ld.) <0! Ignored."), (long) size);
      ignore_rest_of_line ();
      return;
    }

  /* The third argument to .scomm is the alignment.  */
  if (* input_line_pointer != ',')
    align = 8;
  else
    {
      ++ input_line_pointer;
      align = get_absolute_expression ();
      if (align <= 0)
	{
	  as_warn (_("ignoring bad alignment"));
	  align = 8;
	}
    }
  /* Convert to a power of 2 alignment.  */
  if (align)
    {
      for (align2 = 0; (align & 1) == 0; align >>= 1, ++ align2)
	continue;
      if (align != 1)
	{
	  as_bad (_("Common alignment not a power of 2"));
	  ignore_rest_of_line ();
	  return;
	}
    }
  else
    align2 = 0;

  * p = 0;
  symbolP = symbol_find_or_make (name);
  * p = c;

  if (S_IS_DEFINED (symbolP))
    {
      /* xgettext:c-format */
      as_bad (_("Ignoring attempt to re-define symbol `%s'."),
	      S_GET_NAME (symbolP));
      ignore_rest_of_line ();
      return;
    }

  if (S_GET_VALUE (symbolP) && S_GET_VALUE (symbolP) != (valueT) size)
    {
      /* xgettext:c-format */
      as_bad (_("Length of .scomm \"%s\" is already %ld. Not changed to %ld."),
	      S_GET_NAME (symbolP),
	      (long) S_GET_VALUE (symbolP),
	      (long) size);

      ignore_rest_of_line ();
      return;
    }

  if (symbol_get_obj (symbolP)->local)
    {
      segT   old_sec    = now_seg;
      int    old_subsec = now_subseg;
      char * pfrag;

      record_alignment (sbss_section, align2);
      subseg_set (sbss_section, 0);
      
      if (align2)
	frag_align (align2, 0, 0);
      
      if (S_GET_SEGMENT (symbolP) == sbss_section)
	symbol_get_frag (symbolP)->fr_symbol = 0;
      
      symbol_set_frag (symbolP, frag_now);
      
      pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP, size,
			(char *) 0);
      * pfrag = 0;
      S_SET_SIZE (symbolP, size);
      S_SET_SEGMENT (symbolP, sbss_section);
      S_CLEAR_EXTERNAL (symbolP);
      subseg_set (old_sec, old_subsec);
    }
  else
    {
      S_SET_VALUE (symbolP, (valueT) size);
      S_SET_ALIGN (symbolP, align2);
      S_SET_EXTERNAL (symbolP);
      S_SET_SEGMENT (symbolP, & scom_section);
    }

  demand_empty_rest_of_line ();
}

/* 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, 0},

  /* 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 -> 10 bit range.
     This doesn't handle a branch in the right slot at the border:
     the "& -4" isn't taken into account.  It's not important enough to
     complicate things over it, so we subtract an extra 2 (or + 2 in -ve
     case).  */
  {511 - 2 - 2, -512 - 2 + 2, 0, 2 },
  /* 32 bit insn, 24 bit disp -> 26 bit range.  */
  {0x2000000 - 1 - 2, -0x2000000 - 2, 2, 0 },
  /* Same thing, but with leading nop for alignment.  */
  {0x2000000 - 1 - 2, -0x2000000 - 2, 4, 0 }
};

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

  /* Keep 32 bit insns aligned on 32 bit boundaries.  */
  if (fragP->fr_subtype == 2)
    {
      if ((address & 3) != 0)
	{
	  fragP->fr_subtype = 3;
	  growth = 2;
	}
    }
  else if (fragP->fr_subtype == 3)
    {
      if ((address & 3) == 0)
	{
	  fragP->fr_subtype = 2;
	  growth = -2;
	}
    }
  else
    {
      growth = relax_frag (fragP, stretch);

      /* Long jump on odd halfword boundary?  */
      if (fragP->fr_subtype == 2 && (address & 3) != 0)
	{
	  fragP->fr_subtype = 3;
	  growth += 2;
	}
    }

  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 (fragP, segment)
     fragS * fragP;
     segT    segment;
{
  int    old_fr_fix = fragP->fr_fix;

  /* 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)
    {
      /* The symbol is undefined in this segment.
	 Change the relaxation subtype to the max allowable and leave
	 all further handling to md_convert_frag.  */
      fragP->fr_subtype = 2;

#if 0 /* Can't use this, but leave in for illustration.  */     
      /* Change 16 bit insn to 32 bit insn.  */
      fragP->fr_opcode[0] |= 0x80;

      /* Increase known (fixed) size of fragment.  */
      fragP->fr_fix += 2;

      /* Create a relocation for it.  */
      fix_new (fragP, old_fr_fix, 4,
	       fragP->fr_symbol,
	       fragP->fr_offset, 1 /* pcrel */,
	       /* FIXME: Can't use a real BFD reloc here.
		  gas_cgen_md_apply_fix3 can't handle it.  */
	       BFD_RELOC_M32R_26_PCREL);

      /* Mark this fragment as finished.  */
      frag_wane (fragP);
#else
      {
	const CGEN_INSN * insn;
	int               i;

	/* Update the recorded insn.
	   Fortunately we don't have to look very far.
	   FIXME: Change this to record in the instruction the next higher
	   relaxable insn to use.  */
	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_RELAX))
	      break;
	  }
	if (i == 4)
	  abort ();

	fragP->fr_cgen.insn = insn;
	return 2;
      }
#endif
    }

  return (fragP->fr_var + fragP->fr_fix - old_fr_fix);
} 

/* *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 (abfd, sec, fragP)
  bfd *   abfd;
  segT    sec;
  fragS * fragP;
{
  char * opcode;
  char * displacement;
  int    target_address;
  int    opcode_address;
  int    extension;
  int    addend;

  opcode = fragP->fr_opcode;

  /* Address opcode resides at in file space.  */
  opcode_address = fragP->fr_address + fragP->fr_fix - 2;

  switch (fragP->fr_subtype)
    {
    case 1 :
      extension = 0;
      displacement = & opcode[1];
      break;
    case 2 :
      opcode[0] |= 0x80;
      extension = 2;
      displacement = & opcode[1];
      break;
    case 3 :
      opcode[2] = opcode[0] | 0x80;
      md_number_to_chars (opcode, PAR_NOP_INSN, 2);
      opcode_address += 2;
      extension = 4;
      displacement = & opcode[3];
      break;
    default :
      abort ();
    }

  if (S_GET_SEGMENT (fragP->fr_symbol) != sec)
    {
      /* symbol must be resolved by linker */
      if (fragP->fr_offset & 3)
	as_warn (_("Addend to unresolved symbol not on word boundary."));
      addend = fragP->fr_offset >> 2;
    }
  else
    {
      /* Address we want to reach in file space.  */
      target_address = S_GET_VALUE (fragP->fr_symbol) + fragP->fr_offset;
      target_address += symbol_get_frag (fragP->fr_symbol)->fr_address;
      addend = (target_address - (opcode_address & -4)) >> 2;
    }

  /* 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)
    {
      assert (fragP->fr_subtype != 1);
      assert (fragP->fr_cgen.insn != 0);
      gas_cgen_record_fixup (fragP,
			     /* Offset of branch insn in frag.  */
			     fragP->fr_fix + extension - 4,
			     fragP->fr_cgen.insn,
			     4 /*length*/,
			     /* FIXME: quick hack */
#if 0
			     cgen_operand_lookup_by_num (gas_cgen_cpu_desc,
							 fragP->fr_cgen.opindex),
#else
			     cgen_operand_lookup_by_num (gas_cgen_cpu_desc,
							 M32R_OPERAND_DISP24),
#endif
			     fragP->fr_cgen.opinfo,
			     fragP->fr_symbol, fragP->fr_offset);
    }

#define SIZE_FROM_RELAX_STATE(n) ((n) == 1 ? 1 : 3)

  md_number_to_chars (displacement, (valueT) addend,
		      SIZE_FROM_RELAX_STATE (fragP->fr_subtype));

  fragP->fr_fix += extension;
}

/* Functions concerning relocs.  */

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

long
md_pcrel_from_section (fixP, sec)
     fixS * fixP;
     segT   sec;
{
  if (fixP->fx_addsy != (symbolS *) NULL
      && (! S_IS_DEFINED (fixP->fx_addsy)
	  || S_GET_SEGMENT (fixP->fx_addsy) != sec))
    {
      /* The symbol is undefined (or is defined but not in this section).
	 Let the linker figure it out.  */
      return 0;
    }

  return (fixP->fx_frag->fr_address + fixP->fx_where) & -4L;
}

/* 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 (insn, operand, fixP)
     const CGEN_INSN *    insn;
     const CGEN_OPERAND * operand;
     fixS *               fixP;
{
  switch (operand->type)
    {
    case M32R_OPERAND_DISP8 : return  BFD_RELOC_M32R_10_PCREL;
    case M32R_OPERAND_DISP16 : return BFD_RELOC_M32R_18_PCREL;
    case M32R_OPERAND_DISP24 : return BFD_RELOC_M32R_26_PCREL;
    case M32R_OPERAND_UIMM24 : return BFD_RELOC_M32R_24;
    case M32R_OPERAND_HI16 :
    case M32R_OPERAND_SLO16 :
    case M32R_OPERAND_ULO16 :
      /* If low/high/shigh/sda was used, it is recorded in `opinfo'.  */
      if (fixP->fx_cgen.opinfo != 0)
	return fixP->fx_cgen.opinfo;
      break;
    default : /* avoid -Wall warning */
      break;
    }
  return BFD_RELOC_NONE;
}

/* Record a HI16 reloc for later matching with its LO16 cousin.  */

static void
m32r_record_hi16 (reloc_type, fixP, seg)
     int    reloc_type;
     fixS * fixP;
     segT   seg;
{
  struct m32r_hi_fixup * hi_fixup;

  assert (reloc_type == BFD_RELOC_M32R_HI16_SLO
	  || reloc_type == BFD_RELOC_M32R_HI16_ULO);

  hi_fixup = ((struct m32r_hi_fixup *)
	      xmalloc (sizeof (struct m32r_hi_fixup)));
  hi_fixup->fixp = fixP;
  hi_fixup->seg  = now_seg;
  hi_fixup->next = m32r_hi_fixup_list;
  
  m32r_hi_fixup_list = hi_fixup;
}

/* Called while parsing an instruction to create a fixup.
   We need to check for HI16 relocs and queue them up for later sorting.  */

fixS *
m32r_cgen_record_fixup_exp (frag, where, insn, length, operand, opinfo, exp)
     fragS *              frag;
     int                  where;
     const CGEN_INSN *    insn;
     int                  length;
     const CGEN_OPERAND * operand;
     int                  opinfo;
     expressionS *        exp;
{
  fixS * fixP = gas_cgen_record_fixup_exp (frag, where, insn, length,
					   operand, opinfo, exp);

  switch (operand->type)
    {
    case M32R_OPERAND_HI16 :
      /* If low/high/shigh/sda was used, it is recorded in `opinfo'.  */
      if (fixP->fx_cgen.opinfo == BFD_RELOC_M32R_HI16_SLO
	  || fixP->fx_cgen.opinfo == BFD_RELOC_M32R_HI16_ULO)
	m32r_record_hi16 (fixP->fx_cgen.opinfo, fixP, now_seg);
      break;
    default : /* avoid -Wall warning */
      break;
    }

  return fixP;
}

/* Return BFD reloc type from opinfo field in a fixS.
   It's tricky using fx_r_type in m32r_frob_file because the values
   are BFD_RELOC_UNUSED + operand number.  */
#define FX_OPINFO_R_TYPE(f) ((f)->fx_cgen.opinfo)

/* Sort any unmatched HI16 relocs so that they immediately precede
   the corresponding LO16 reloc.  This is called before md_apply_fix and
   tc_gen_reloc.  */

void
m32r_frob_file ()
{
  struct m32r_hi_fixup * l;

  for (l = m32r_hi_fixup_list; l != NULL; l = l->next)
    {
      segment_info_type * seginfo;
      int                 pass;

      assert (FX_OPINFO_R_TYPE (l->fixp) == BFD_RELOC_M32R_HI16_SLO
	      || FX_OPINFO_R_TYPE (l->fixp) == BFD_RELOC_M32R_HI16_ULO);

      /* Check quickly whether the next fixup happens to be a matching low.  */
      if (l->fixp->fx_next != NULL
	  && FX_OPINFO_R_TYPE (l->fixp->fx_next) == BFD_RELOC_M32R_LO16
	  && l->fixp->fx_addsy == l->fixp->fx_next->fx_addsy
	  && l->fixp->fx_offset == l->fixp->fx_next->fx_offset)
	continue;

      /* Look through the fixups for this segment for a matching `low'.
         When we find one, move the high/shigh just in front of it.  We do
         this in two passes.  In the first pass, we try to find a
         unique `low'.  In the second pass, we permit multiple high's
         relocs for a single `low'.  */
      seginfo = seg_info (l->seg);
      for (pass = 0; pass < 2; pass++)
	{
	  fixS * f;
	  fixS * prev;

	  prev = NULL;
	  for (f = seginfo->fix_root; f != NULL; f = f->fx_next)
	    {
	      /* Check whether this is a `low' fixup which matches l->fixp.  */
	      if (FX_OPINFO_R_TYPE (f) == BFD_RELOC_M32R_LO16
		  && f->fx_addsy == l->fixp->fx_addsy
		  && f->fx_offset == l->fixp->fx_offset
		  && (pass == 1
		      || prev == NULL
		      || (FX_OPINFO_R_TYPE (prev) != BFD_RELOC_M32R_HI16_SLO
			  && FX_OPINFO_R_TYPE (prev) != BFD_RELOC_M32R_HI16_ULO)
		      || prev->fx_addsy != f->fx_addsy
		      || prev->fx_offset !=  f->fx_offset))
		{
		  fixS ** pf;

		  /* Move l->fixp before f.  */
		  for (pf = &seginfo->fix_root;
		       * pf != l->fixp;
		       pf = & (* pf)->fx_next)
		    assert (* pf != NULL);

		  * pf = l->fixp->fx_next;

		  l->fixp->fx_next = f;
		  if (prev == NULL)
		    seginfo->fix_root = l->fixp;
		  else
		    prev->fx_next = l->fixp;

		  break;
		}

	      prev = f;
	    }

	  if (f != NULL)
	    break;

	  if (pass == 1
	      && warn_unmatched_high)
	    as_warn_where (l->fixp->fx_file, l->fixp->fx_line,
			   _("Unmatched high/shigh reloc"));
	}
    }
}

/* See whether we need to force a relocation into the output file.
   This is used to force out switch and PC relative relocations when
   relaxing.  */

int
m32r_force_relocation (fix)
     fixS * fix;
{
  if (fix->fx_r_type == BFD_RELOC_VTABLE_INHERIT
      || fix->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
    return 1;

  if (! m32r_relax)
    return 0;

  return (fix->fx_pcrel
	  || 0 /* ??? */);
}

/* Write a value out to the object file, using the appropriate endianness.  */

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

/* Turn a string in input_line_pointer into a floating point constant of type
   type, and store the appropriate bytes in *litP.  The number of LITTLENUMS
   emitted is stored in *sizeP .  An error message is returned, or NULL on OK.
*/

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

char *
md_atof (type, litP, sizeP)
     char type;
     char *litP;
     int *sizeP;
{
  int              i;
  int              prec;
  LITTLENUM_TYPE   words [MAX_LITTLENUMS];
  char *           t;
  char *           atof_ieee ();

  switch (type)
    {
    case 'f':
    case 'F':
    case 's':
    case 'S':
      prec = 2;
      break;

    case 'd':
    case 'D':
    case 'r':
    case 'R':
      prec = 4;
      break;

   /* FIXME: Some targets allow other format chars for bigger sizes here.  */

    default:
      * sizeP = 0;
      return _("Bad call to md_atof()");
    }

  t = atof_ieee (input_line_pointer, type, words);
  if (t)
    input_line_pointer = t;
  * sizeP = prec * sizeof (LITTLENUM_TYPE);

  if (target_big_endian)
    {
      for (i = 0; i < prec; i++)
	{
	  md_number_to_chars (litP, (valueT) words[i],
			      sizeof (LITTLENUM_TYPE));
	  litP += sizeof (LITTLENUM_TYPE);
	}
    }
  else
    {
      for (i = prec - 1; i >= 0; i--)
	{
	  md_number_to_chars (litP, (valueT) words[i],
			      sizeof (LITTLENUM_TYPE));
	  litP += sizeof (LITTLENUM_TYPE);
	}
    }
     
  return 0;
}

void
m32r_elf_section_change_hook ()
{
  /* If we have reached the end of a section and we have just emitted a
     16 bit insn, then emit a nop to make sure that the section ends on
     a 32 bit boundary.  */
  
  if (prev_insn.insn || seen_relaxable_p)
    (void) m32r_fill_insn (0);
}

boolean
m32r_fix_adjustable (fixP)
   fixS *fixP;
{

  if (fixP->fx_addsy == NULL)
    return 1;
  
  /* Prevent all adjustments to global symbols. */
  if (S_IS_EXTERN (fixP->fx_addsy))
    return 0;
  if (S_IS_WEAK (fixP->fx_addsy))
    return 0;
  
  /* We need the symbol name for the VTABLE entries */
  if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
      || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
    return 0;

  return 1;
}
