/* tc-mt.c -- Assembler for the Morpho Technologies mt .
   Copyright (C) 2005, 2006, 2007, 2010 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 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, 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.  */

#include "as.h"
#include "dwarf2dbg.h"
#include "subsegs.h"     
#include "symcat.h"
#include "opcodes/mt-desc.h"
#include "opcodes/mt-opc.h"
#include "cgen.h"
#include "elf/common.h"
#include "elf/mt.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];
}
mt_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";

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



static int no_scheduling_restrictions = 0;

struct option md_longopts[] = 
{
#define OPTION_NO_SCHED_REST	(OPTION_MD_BASE)
  { "nosched",	   no_argument, NULL, OPTION_NO_SCHED_REST },
#define OPTION_MARCH		(OPTION_MD_BASE + 1)
  { "march", required_argument, NULL, OPTION_MARCH},
  { NULL,	   no_argument, NULL, 0 },
};
size_t md_longopts_size = sizeof (md_longopts);

const char * md_shortopts = "";

/* Mach selected from command line.  */
static int mt_mach = bfd_mach_ms1;
static unsigned mt_mach_bitmask = 1 << MACH_MS1;

/* Flags to set in the elf header */
static flagword mt_flags = EF_MT_CPU_MRISC;

/* The architecture to use.  */
enum mt_architectures
  {
    ms1_64_001,
    ms1_16_002,
    ms1_16_003,
    ms2
  };

/* MT architecture we are using for this output file.  */
static enum mt_architectures mt_arch = ms1_16_002;

int
md_parse_option (int c ATTRIBUTE_UNUSED, char * arg)
{
  switch (c)
    {
    case OPTION_MARCH:
      if (strcmp (arg, "ms1-64-001") == 0)
 	{
 	  mt_flags = (mt_flags & ~EF_MT_CPU_MASK) | EF_MT_CPU_MRISC;
 	  mt_mach = bfd_mach_ms1;
 	  mt_mach_bitmask = 1 << MACH_MS1;
 	  mt_arch = ms1_64_001;
 	}
      else if (strcmp (arg, "ms1-16-002") == 0)
 	{
 	  mt_flags = (mt_flags & ~EF_MT_CPU_MASK) | EF_MT_CPU_MRISC;
 	  mt_mach = bfd_mach_ms1;
 	  mt_mach_bitmask = 1 << MACH_MS1;
 	  mt_arch = ms1_16_002;
 	}
      else if (strcmp (arg, "ms1-16-003") == 0)
 	{
 	  mt_flags = (mt_flags & ~EF_MT_CPU_MASK) | EF_MT_CPU_MRISC2;
 	  mt_mach = bfd_mach_mrisc2;
 	  mt_mach_bitmask = 1 << MACH_MS1_003;
 	  mt_arch = ms1_16_003;
 	}
      else if (strcmp (arg, "ms2") == 0)
 	{
 	  mt_flags = (mt_flags & ~EF_MT_CPU_MASK) | EF_MT_CPU_MS2;
 	  mt_mach = bfd_mach_mrisc2;
 	  mt_mach_bitmask = 1 << MACH_MS2;
 	  mt_arch = ms2;
 	}
    case OPTION_NO_SCHED_REST:
      no_scheduling_restrictions = 1;
      break;
    default:
      return 0;
    }

  return 1;
}


void
md_show_usage (FILE * stream)
{
  fprintf (stream, _("MT specific command line options:\n"));
  fprintf (stream, _("  -march=ms1-64-001         allow ms1-64-001 instructions\n"));
  fprintf (stream, _("  -march=ms1-16-002         allow ms1-16-002 instructions (default)\n"));
  fprintf (stream, _("  -march=ms1-16-003         allow ms1-16-003 instructions\n"));
  fprintf (stream, _("  -march=ms2                allow ms2 instructions \n"));
  fprintf (stream, _("  -nosched                  disable scheduling restrictions\n"));
}


void
md_begin (void)
{
  /* Initialize the `cgen' interface.  */
  
  /* Set the machine number and endian.  */
  gas_cgen_cpu_desc = mt_cgen_cpu_open (CGEN_CPU_OPEN_MACHS, mt_mach_bitmask,
					CGEN_CPU_OPEN_ENDIAN,
					CGEN_ENDIAN_BIG,
					CGEN_CPU_OPEN_END);
  mt_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 ELF flags if desired. */
  if (mt_flags)
    bfd_set_private_flags (stdoutput, mt_flags);

  /* Set the machine type.  */
  bfd_default_set_arch_mach (stdoutput, bfd_arch_mt, mt_mach);
}

void
md_assemble (char * str)
{
  static long delayed_load_register = 0;
  static long prev_delayed_load_register = 0;
  static int last_insn_had_delay_slot = 0;
  static int last_insn_in_noncond_delay_slot = 0;
  static int last_insn_has_load_delay = 0;
  static int last_insn_was_memory_access = 0;
  static int last_insn_was_io_insn = 0;
  static int last_insn_was_arithmetic_or_logic = 0;
  static int last_insn_was_branch_insn = 0;
  static int last_insn_was_conditional_branch_insn = 0;

  mt_insn insn;
  char * errmsg;

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

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

  if (!insn.insn)
    {
      as_bad ("%s", 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), 1, NULL);


  /* Handle Scheduling Restrictions.  */
  if (!no_scheduling_restrictions)
    {
      /* Detect consecutive Memory Accesses.  */
      if (last_insn_was_memory_access
	  && CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_MEMORY_ACCESS)
	  && mt_mach == ms1_64_001)
	as_warn (_("instruction %s may not follow another memory access instruction."),
		 CGEN_INSN_NAME (insn.insn));

      /* Detect consecutive I/O Instructions.  */
      else if (last_insn_was_io_insn
	       && CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_IO_INSN))
	as_warn (_("instruction %s may not follow another I/O instruction."),
		 CGEN_INSN_NAME (insn.insn));

      /* Detect consecutive branch instructions.  */
      else if (last_insn_was_branch_insn
	       && CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_BR_INSN))
	as_warn (_("%s may not occupy the delay slot of another branch insn."),
		 CGEN_INSN_NAME (insn.insn));

      /* Detect data dependencies on delayed loads: memory and input insns.  */
      if (last_insn_has_load_delay && delayed_load_register)
	{
	  if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRSR1)
	      && insn.fields.f_sr1 == delayed_load_register)
	    as_warn (_("operand references R%ld of previous load."),
		     insn.fields.f_sr1);

	  if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRSR2)
	      && insn.fields.f_sr2 == delayed_load_register)
	    as_warn (_("operand references R%ld of previous load."),
		     insn.fields.f_sr2);
	}

      /* Detect JAL/RETI hazard */
      if (mt_mach == ms2
	  && CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_JAL_HAZARD))
	{
	  if ((CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRSR1)
	       && insn.fields.f_sr1 == delayed_load_register)
	      || (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRSR2)
		  && insn.fields.f_sr2 == delayed_load_register))
	    as_warn (_("operand references R%ld of previous instrutcion."),
		     delayed_load_register);
	  else if ((CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRSR1)
		    && insn.fields.f_sr1 == prev_delayed_load_register)
		   || (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRSR2)
		       && insn.fields.f_sr2 == prev_delayed_load_register))
	    as_warn (_("operand references R%ld of instructcion before previous."),
		     prev_delayed_load_register);
	}
      
      /* Detect data dependency between conditional branch instruction
         and an immediately preceding arithmetic or logical instruction.  */
      if (last_insn_was_arithmetic_or_logic
	  && !last_insn_in_noncond_delay_slot
	  && (delayed_load_register != 0)
	  && CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_BR_INSN)
	  && mt_arch == ms1_64_001)
	{
	  if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRSR1)
	      && insn.fields.f_sr1 == delayed_load_register)
	    as_warn (_("conditional branch or jal insn's operand references R%ld of previous arithmetic or logic insn."),
		     insn.fields.f_sr1);

	  if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRSR2)
	      && insn.fields.f_sr2 == delayed_load_register)
	    as_warn (_("conditional branch or jal insn's operand references R%ld of previous arithmetic or logic insn."),
		     insn.fields.f_sr2);
	}
    }

  /* Keep track of details of this insn for processing next insn.  */
  last_insn_in_noncond_delay_slot = last_insn_was_branch_insn
    && !last_insn_was_conditional_branch_insn;

  last_insn_had_delay_slot =
    CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_DELAY_SLOT);
  (void) last_insn_had_delay_slot;

  last_insn_has_load_delay =
    CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_LOAD_DELAY);

  last_insn_was_memory_access =
    CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_MEMORY_ACCESS);

  last_insn_was_io_insn =
    CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_IO_INSN);

  last_insn_was_arithmetic_or_logic =
    CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_AL_INSN);

  last_insn_was_branch_insn =
    CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_BR_INSN);
  
  last_insn_was_conditional_branch_insn =
  CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_BR_INSN)
    && CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRSR2);
  
  prev_delayed_load_register = delayed_load_register;
  
  if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRDR))
     delayed_load_register = insn.fields.f_dr; 
  else if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRDRRR))
     delayed_load_register = insn.fields.f_drrr; 
  else  /* Insns has no destination register.  */
     delayed_load_register = 0; 

  /* Generate dwarf2 line numbers.  */
  dwarf2_emit_insn (4); 
}

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 NULL;
}

int
md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED,
			       segT    segment ATTRIBUTE_UNUSED)
{
  as_fatal (_("md_estimate_size_before_relax\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_section (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 the address of the opcode - cgen adjusts for opcode size
     itself, to be consistent with the disassembler, which must do
     so.  */
  return fixP->fx_where + fixP->fx_frag->fr_address;
}


/* 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 MT_OPERAND_IMM16O:
      result = BFD_RELOC_16_PCREL;
      fixP->fx_pcrel = 1;
      /* fixP->fx_no_overflow = 1; */
      break;
    case MT_OPERAND_IMM16:
    case MT_OPERAND_IMM16Z:
      /* 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 MT_OPERAND_LOOPSIZE:
      result = BFD_RELOC_MT_PCINSN8;
      fixP->fx_pcrel = 1;
      /* Adjust for the delay slot, which is not part of the loop  */
      fixP->fx_offset -= 8;
      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);
}

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

/* See whether we need to force a relocation into the output file.  */

int
mt_force_relocation (fixS * fixp ATTRIBUTE_UNUSED)
{
  return 0;
}

void
mt_apply_fix (fixS *fixP, valueT *valueP, segT seg)
{
  if ((fixP->fx_pcrel != 0) && (fixP->fx_r_type == BFD_RELOC_32))
    fixP->fx_r_type = BFD_RELOC_32_PCREL;

  gas_cgen_md_apply_fix (fixP, valueP, seg);
}

bfd_boolean
mt_fix_adjustable (fixS * fixP)
{
  if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
    {
      const CGEN_INSN *insn = NULL;
      int opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED;
      const CGEN_OPERAND *operand;

      operand = cgen_operand_lookup_by_num(gas_cgen_cpu_desc, opindex);
      md_cgen_lookup_reloc (insn, operand, fixP);
    }

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