/* tc-ip2k.c -- Assembler for the Scenix IP2xxx.
   Copyright (C) 2000-2021 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"

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

  literal_prefix_dollar_hex = true;
}


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_section_alignment (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),
			       gas_cgen_cpu_desc->insn_endian);
      /* 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;
}

