/* tc-xstormy16.c -- Assembler for the Sanyo XSTORMY16.
   Copyright 2000, 2001, 2002, 2003 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 "as.h"
#include "subsegs.h"
#include "symcat.h"
#include "opcodes/xstormy16-desc.h"
#include "opcodes/xstormy16-opc.h"
#include "cgen.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];
}
xstormy16_insn;

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

#define O_fptr_symbol	(O_max + 1)

#define XSTORMY16_SHORTOPTS ""
const char * md_shortopts = XSTORMY16_SHORTOPTS;

struct option md_longopts[] =
{
  {NULL, no_argument, NULL, 0}
};
size_t md_longopts_size = sizeof (md_longopts);

int
md_parse_option (c, arg)
     int    c ATTRIBUTE_UNUSED;
     char * arg ATTRIBUTE_UNUSED;
{
  return 0;
}

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

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

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

  /* Set the machine number and endian.  */
  gas_cgen_cpu_desc = xstormy16_cgen_cpu_open (CGEN_CPU_OPEN_MACHS, 0,
					  CGEN_CPU_OPEN_ENDIAN,
					  CGEN_ENDIAN_LITTLE,
					  CGEN_CPU_OPEN_END);
  xstormy16_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);
}

void
md_assemble (str)
     char * str;
{
  xstormy16_insn insn;
  char *    errmsg;

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

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

  if (!insn.insn)
    {
      as_bad (errmsg);
      return;
    }

  /* Doesn't really matter what we pass for RELAX_P here.  */
  gas_cgen_finish_insn (insn.insn, insn.buffer,
			CGEN_FIELDS_BITSIZE (& insn.fields), 0, NULL);
}

void
md_operand (e)
     expressionS * e;
{
  if (*input_line_pointer != '@')
    return;

  if (strncmp (input_line_pointer+1, "fptr", 4) == 0)
    {
      input_line_pointer += 5;
      SKIP_WHITESPACE ();
      if (*input_line_pointer != '(')
	{
	  as_bad ("Expected '('");
	  goto err;
	}
      input_line_pointer++;

      expression (e);

      if (*input_line_pointer != ')')
	{
	  as_bad ("Missing ')'");
	  goto err;
	}
      input_line_pointer++;

      if (e->X_op != O_symbol)
	as_bad ("Not a symbolic expression");
      else
        e->X_op = O_fptr_symbol;
    }

  return;
 err:
  ignore_rest_of_line ();
}

/* Called while parsing data to create a fixup.
   Create BFD_RELOC_XSTORMY16_FPTR16 relocations.  */

void
xstormy16_cons_fix_new (f, where, nbytes, exp)
     fragS *f;
     int where;
     int nbytes;
     expressionS *exp;
{
  bfd_reloc_code_real_type code;
  fixS *fix;

  if (exp->X_op == O_fptr_symbol)
    {
      if (nbytes != 2)
	{
	  as_bad ("unsupported fptr fixup size %d", nbytes);
	  return;
	}
      exp->X_op = O_symbol;
      code = BFD_RELOC_XSTORMY16_FPTR16;
    }
  else if (nbytes == 1)
    code = BFD_RELOC_8;
  else if (nbytes == 2)
    code = BFD_RELOC_16;
  else if (nbytes == 4)
    code = BFD_RELOC_32;
  else
    {
      as_bad ("unsupported fixup size %d", nbytes);
      return;
    }

  fix = fix_new_exp (f, where, nbytes, exp, 0, code);
}

/* Called while parsing an instruction to create a fixup.
   Create BFD_RELOC_XSTORMY16_FPTR16 relocations.  */

fixS *
xstormy16_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;
  operatorT op = exp->X_op;

  if (op == O_fptr_symbol)
    exp->X_op = O_symbol;

  fixP = gas_cgen_record_fixup_exp (frag, where, insn, length,
				    operand, opinfo, exp);

  if (op == O_fptr_symbol)
    {
      if (operand->type != XSTORMY16_OPERAND_IMM16)
	as_bad ("unsupported fptr fixup");
      else
	{
	  fixP->fx_r_type = BFD_RELOC_XSTORMY16_FPTR16;
	  fixP->fx_where += 2;
	}
    }

  return fixP;
}

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 ATTRIBUTE_UNUSED;
{
  return 0;
}

/* 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 ATTRIBUTE_UNUSED;
     segT    segment ATTRIBUTE_UNUSED;
{
  /* No assembler relaxation is defined (or necessary) for this port.  */
  abort ();
}

/* *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 ATTRIBUTE_UNUSED;
  segT    sec ATTRIBUTE_UNUSED;
  fragS * fragP ATTRIBUTE_UNUSED;
{
  /* No assembler relaxation is defined (or necessary) for this port.  */
  abort ();
}

/* 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;
}

/* 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 ATTRIBUTE_UNUSED;
     const CGEN_OPERAND * operand;
     fixS *               fixP;
{
  switch (operand->type)
    {
    case XSTORMY16_OPERAND_IMM2:
    case XSTORMY16_OPERAND_IMM3:
    case XSTORMY16_OPERAND_IMM3B:
    case XSTORMY16_OPERAND_IMM4:
    case XSTORMY16_OPERAND_HMEM8:
      return BFD_RELOC_NONE;

    case XSTORMY16_OPERAND_IMM12:
      fixP->fx_where += 2;
      return BFD_RELOC_XSTORMY16_12;

    case XSTORMY16_OPERAND_IMM8:
    case XSTORMY16_OPERAND_LMEM8:
      return fixP->fx_pcrel ? BFD_RELOC_8_PCREL : BFD_RELOC_8;

    case XSTORMY16_OPERAND_IMM16:
      /* This might have been processed at parse time.  */
      fixP->fx_where += 2;
      if (fixP->fx_cgen.opinfo && fixP->fx_cgen.opinfo != BFD_RELOC_NONE)
	return fixP->fx_cgen.opinfo;
      return fixP->fx_pcrel ? BFD_RELOC_16_PCREL : BFD_RELOC_16;

    case XSTORMY16_OPERAND_ABS24:
      return BFD_RELOC_XSTORMY16_24;

    case XSTORMY16_OPERAND_REL8_4:
      fixP->fx_addnumber -= 2;
    case XSTORMY16_OPERAND_REL8_2:
      fixP->fx_addnumber -= 2;
      fixP->fx_pcrel = 1;
      return BFD_RELOC_8_PCREL;

    case XSTORMY16_OPERAND_REL12:
      fixP->fx_where += 2;
      /* Fall through...  */
    case XSTORMY16_OPERAND_REL12A:
      fixP->fx_addnumber -= 2;
      fixP->fx_pcrel = 1;
      return BFD_RELOC_XSTORMY16_REL_12;

    default : /* avoid -Wall warning */
      abort ();
    }
}

/* 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
xstormy16_force_relocation (fix)
     fixS * fix;
{
  if (fix->fx_r_type == BFD_RELOC_XSTORMY16_FPTR16)
    return 1;

  return generic_force_reloc (fix);
}

/* Return true if a relocation against a symbol may be replaced with
   a relocation against section+offset.  */

bfd_boolean
xstormy16_fix_adjustable (fixP)
   fixS * fixP;
{
  /* 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;

  if (fixP->fx_r_type == BFD_RELOC_XSTORMY16_FPTR16)
    return 0;

  return 1;
}

/* This is a copy of gas_cgen_md_apply_fix3, with some enhancements to
   do various things that would not be valid for all ports.  */

void
xstormy16_md_apply_fix3 (fixP, valueP, seg)
     fixS *   fixP;
     valueT * valueP;
     segT     seg ATTRIBUTE_UNUSED;
{
  char *where = fixP->fx_frag->fr_literal + fixP->fx_where;
  valueT value = *valueP;
  /* Canonical name, since used a lot.  */
  CGEN_CPU_DESC cd = gas_cgen_cpu_desc;

  /* md_cgen_lookup_reloc() will adjust this to compensate for where
     in the opcode the relocation happens, for pcrel relocations.  We
     have no other way of keeping track of what this offset needs to
     be.  */
  fixP->fx_addnumber = 0;

  /* This port has pc-relative relocs and DIFF_EXPR_OK defined, so
     it must deal with turning a BFD_RELOC_{8,16,32,64} into a
     BFD_RELOC_*_PCREL for the case of

	.word something-.
  */
  if (fixP->fx_pcrel)
    switch (fixP->fx_r_type)
      {
      case BFD_RELOC_8:
	fixP->fx_r_type = BFD_RELOC_8_PCREL;
	break;
      case BFD_RELOC_16:
	fixP->fx_r_type = BFD_RELOC_16_PCREL;
	break;
      case BFD_RELOC_32:
	fixP->fx_r_type = BFD_RELOC_32_PCREL;
	break;
      case BFD_RELOC_64:
	fixP->fx_r_type = BFD_RELOC_64_PCREL;
	break;
      default:
	break;
      }

  if (fixP->fx_addsy == (symbolS *) NULL)
    fixP->fx_done = 1;

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

  if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
    {
      int opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED;
      const CGEN_OPERAND *operand = cgen_operand_lookup_by_num (cd, opindex);
      const char *errmsg;
      bfd_reloc_code_real_type reloc_type;
      CGEN_FIELDS *fields = alloca (CGEN_CPU_SIZEOF_FIELDS (cd));
      const CGEN_INSN *insn = fixP->fx_cgen.insn;

      /* If the reloc has been fully resolved finish the operand here.  */
      /* FIXME: This duplicates the capabilities of code in BFD.  */
      if (fixP->fx_done)
	{
	  CGEN_CPU_SET_FIELDS_BITSIZE (cd) (fields, CGEN_INSN_BITSIZE (insn));
	  CGEN_CPU_SET_VMA_OPERAND (cd) (cd, opindex, fields, (bfd_vma) value);

#if CGEN_INT_INSN_P
	  {
	    CGEN_INSN_INT insn_value =
	      cgen_get_insn_value (cd, where, CGEN_INSN_BITSIZE (insn));

	    /* ??? 0 is passed for `pc'.  */
	    errmsg = CGEN_CPU_INSERT_OPERAND (cd) (cd, opindex, fields,
						   &insn_value, (bfd_vma) 0);
	    cgen_put_insn_value (cd, where, CGEN_INSN_BITSIZE (insn),
				 insn_value);
	  }
#else
	  /* ??? 0 is passed for `pc'.  */
	  errmsg = CGEN_CPU_INSERT_OPERAND (cd) (cd, opindex, fields, where,
						 (bfd_vma) 0);
#endif
	  if (errmsg)
	    as_bad_where (fixP->fx_file, fixP->fx_line, "%s", errmsg);
	}

      if (fixP->fx_done)
	return;

      /* The operand isn't fully resolved.  Determine a BFD reloc value
	 based on the operand information and leave it to
	 bfd_install_relocation.  Note that this doesn't work when
	 !partial_inplace.  */

      reloc_type = md_cgen_lookup_reloc (insn, operand, fixP);
      if (reloc_type != BFD_RELOC_NONE)
	{
	  fixP->fx_r_type = reloc_type;
	}
      else
	{
	  as_bad_where (fixP->fx_file, fixP->fx_line,
			_("unresolved expression that must be resolved"));
	  fixP->fx_done = 1;
	  return;
	}
    }
  else if (fixP->fx_done)
    {
      /* We're finished with this fixup.  Install it because
	 bfd_install_relocation won't be called to do it.  */
      switch (fixP->fx_r_type)
	{
	case BFD_RELOC_8:
	  md_number_to_chars (where, value, 1);
	  break;
	case BFD_RELOC_16:
	  md_number_to_chars (where, value, 2);
	  break;
	case BFD_RELOC_32:
	  md_number_to_chars (where, value, 4);
	  break;
	case BFD_RELOC_64:
	  md_number_to_chars (where, value, 8);
	  break;
	default:
	  as_bad_where (fixP->fx_file, fixP->fx_line,
			_("internal error: can't install fix for reloc type %d (`%s')"),
			fixP->fx_r_type, bfd_get_reloc_code_name (fixP->fx_r_type));
	  break;
	}
    }
  else
    {
      /* bfd_install_relocation will be called to finish things up.  */
    }

  /* This is a RELA port.  Thus, it does not need to store a
     value if it is going to make a reloc.  What's more, when
     assembling a line like

     .byte global-0x7f00

     we'll get a spurious error message if we try to stuff 0x7f00 into
     the byte.  */
  if (! fixP->fx_done)
    *valueP = 0;

  /* Tuck `value' away for use by tc_gen_reloc.
     See the comment describing fx_addnumber in write.h.
     This field is misnamed (or misused :-).  */
  fixP->fx_addnumber += value;
}


/* 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;
{
  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              prec;
  LITTLENUM_TYPE   words [MAX_LITTLENUMS];
  LITTLENUM_TYPE   *wordP;
  char *           t;

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

    case 'd':
    case 'D':
      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);

  *sizeP = prec * sizeof (LITTLENUM_TYPE);
  /* This loops outputs the LITTLENUMs in REVERSE order; in accord with
     the littleendianness of the processor.  */
  for (wordP = words + prec - 1; prec--;)
    {
      md_number_to_chars (litP, (valueT) (*wordP--), sizeof (LITTLENUM_TYPE));
      litP += sizeof (LITTLENUM_TYPE);
    }

  return 0;
}
