/* tc-ip2k.c -- Assembler for the Scenix IP2xxx.
   Copyright (C) 2000-2016 Free Software Foundation, 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/ip2k-desc.h"
#include "opcodes/ip2k-opc.h"
#include "cgen.h"
#include "elf/common.h"
#include "elf/ip2k.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];
}
ip2k_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";

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

/* Mach selected from command line.  */
static int ip2k_mach = 0;
static unsigned ip2k_mach_bitmask = 0;


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

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

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

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

/* The target specific pseudo-ops which we support.  */
const pseudo_typeS md_pseudo_table[] =
{
    { "text",   ip2k_elf_section_text,  0 },
    { "sect",   ip2k_elf_section_rtn,   0 },
    { NULL, 	NULL,			0 }
};



enum options
{
  OPTION_CPU_IP2022 = OPTION_MD_BASE,
  OPTION_CPU_IP2022EXT
};

struct option md_longopts[] =
{
  { "mip2022",     no_argument, NULL, OPTION_CPU_IP2022 },
  { "mip2022ext",  no_argument, NULL, OPTION_CPU_IP2022EXT },
  { 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)
{
  switch (c)
    {
    case OPTION_CPU_IP2022:
      ip2k_mach = bfd_mach_ip2022;
      ip2k_mach_bitmask = 1 << MACH_IP2022;
      break;

    case OPTION_CPU_IP2022EXT:
      ip2k_mach = bfd_mach_ip2022ext;
      ip2k_mach_bitmask = 1 << MACH_IP2022EXT;
      break;

    default:
      return 0;
    }

  return 1;
}

void
md_show_usage (FILE * stream)
{
  fprintf (stream, _("IP2K specific command line options:\n"));
  fprintf (stream, _("  -mip2022               restrict to IP2022 insns \n"));
  fprintf (stream, _("  -mip2022ext            permit extended IP2022 insn\n"));
}

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

  /* Set the machine number and endian.  */
  gas_cgen_cpu_desc = ip2k_cgen_cpu_open (CGEN_CPU_OPEN_MACHS,
					  ip2k_mach_bitmask,
					  CGEN_CPU_OPEN_ENDIAN,
					  CGEN_ENDIAN_BIG,
					  CGEN_CPU_OPEN_END);
  ip2k_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_ip2k, ip2k_mach);
}


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

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

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

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

  /* Check for special relocation required by SKIP instructions.  */
  if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_SKIPA))
    /* Unconditional skip has a 1-bit relocation of the current pc, so
       that we emit either sb pcl.0 or snb pcl.0 depending on whether
       the PCL (pc + 2) >> 1 is odd or even.  */
    {
      enum cgen_parse_operand_result result_type;
      bfd_vma value;
      const char *curpc_plus_2 = ".+2";
      const char *err;

      err = cgen_parse_address (gas_cgen_cpu_desc, & curpc_plus_2,
				IP2K_OPERAND_ADDR16CJP,
				BFD_RELOC_IP2K_PC_SKIP,
				& result_type, & value);
      if (err)
	{
	  as_bad ("%s", err);
	  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), 1, NULL);
}

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

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


symbolS *
md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
{
    return 0;
}

int
md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED,
			       segT    segment ATTRIBUTE_UNUSED)
{
  as_fatal (_("relaxation not supported\n"));
  return 1;
}


/* *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   ATTRIBUTE_UNUSED,
		 fragS * fragP ATTRIBUTE_UNUSED)
{
}


/* Functions concerning relocs.  */

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


/* 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)
{
  bfd_reloc_code_real_type result;

  result = BFD_RELOC_NONE;

  switch (operand->type)
    {
    case IP2K_OPERAND_FR:
    case IP2K_OPERAND_ADDR16L:
    case IP2K_OPERAND_ADDR16H:
    case IP2K_OPERAND_LIT8:
      /* These may have been processed at parse time.  */
      if (fixP->fx_cgen.opinfo != 0)
	result = fixP->fx_cgen.opinfo;
      fixP->fx_no_overflow = 1;
      break;

    case IP2K_OPERAND_ADDR16CJP:
      result = fixP->fx_cgen.opinfo;
      if (result == 0 || result == BFD_RELOC_NONE)
	result = BFD_RELOC_IP2K_ADDR16CJP;
      fixP->fx_no_overflow = 1;
      break;

    case IP2K_OPERAND_ADDR16P:
      result = BFD_RELOC_IP2K_PAGE3;
      fixP->fx_no_overflow = 1;
      break;

    default:
      result = BFD_RELOC_NONE;
      break;
    }

  return result;
}


/* 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_bigendian (buf, val, n);
}

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


/* See whether we need to force a relocation into the output file.
   Force most of them, since the linker's bfd relocation engine
   understands range limits better than gas' cgen fixup engine.
   Consider the case of a fixup intermediate value being larger than
   the instruction it will be eventually encoded within.  */

int
ip2k_force_relocation (fixS * fix)
{
  switch (fix->fx_r_type)
    {
    case BFD_RELOC_IP2K_FR9:
    case BFD_RELOC_IP2K_FR_OFFSET:
    case BFD_RELOC_IP2K_BANK:
    case BFD_RELOC_IP2K_ADDR16CJP:
    case BFD_RELOC_IP2K_PAGE3:
    case BFD_RELOC_IP2K_LO8DATA:
    case BFD_RELOC_IP2K_HI8DATA:
    case BFD_RELOC_IP2K_EX8DATA:
    case BFD_RELOC_IP2K_LO8INSN:
    case BFD_RELOC_IP2K_HI8INSN:
    case BFD_RELOC_IP2K_PC_SKIP:
    case BFD_RELOC_IP2K_TEXT:
      return 1;

    case BFD_RELOC_16:
      if (fix->fx_subsy && S_IS_DEFINED (fix->fx_subsy)
	  && fix->fx_addsy && S_IS_DEFINED (fix->fx_addsy)
	  && (S_GET_SEGMENT (fix->fx_addsy)->flags & SEC_CODE))
	{
	  fix->fx_r_type = BFD_RELOC_IP2K_TEXT;
	  return 0;
	}
      break;

    default:
      break;
    }

  return generic_force_reloc (fix);
}

void
ip2k_apply_fix (fixS *fixP, valueT *valueP, segT seg)
{
  if (fixP->fx_r_type == BFD_RELOC_IP2K_TEXT
      && ! fixP->fx_addsy
      && ! fixP->fx_subsy)
    {
      *valueP = ((int)(* valueP)) / 2;
      fixP->fx_r_type = BFD_RELOC_16;
    }
  else if (fixP->fx_r_type == BFD_RELOC_UNUSED + IP2K_OPERAND_FR)
    {
      /* Must be careful when we are fixing up an FR.  We could be
	 fixing up an offset to (SP) or (DP) in which case we don't
	 want to step on the top 2 bits of the FR operand.  The
	 gas_cgen_md_apply_fix doesn't know any better and overwrites
	 the entire operand.  We counter this by adding the bits
	 to the new value.  */
      char *where = fixP->fx_frag->fr_literal + fixP->fx_where;

      /* Canonical name, since used a lot.  */
      CGEN_CPU_DESC cd = gas_cgen_cpu_desc;
      CGEN_INSN_INT insn_value
	= cgen_get_insn_value (cd, (unsigned char *) where,
			       CGEN_INSN_BITSIZE (fixP->fx_cgen.insn));
      /* Preserve (DP) or (SP) specification.  */
      *valueP += (insn_value & 0x180);
    }

  gas_cgen_md_apply_fix (fixP, valueP, seg);
}

int
ip2k_elf_section_flags (flagword flags,
			bfd_vma 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 = 1;

  return flags;
}

