/* tc-pj.c -- Assemble code for Pico Java
   Copyright 1999, 2000, 2001, 2002, 2003, 2005, 2007, 2009, 2010
   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.  */

/* Contributed by Steve Chamberlain of Transmeta <sac@pobox.com>.  */

#include "as.h"
#include "safe-ctype.h"
#include "opcode/pj.h"

extern const pj_opc_info_t pj_opc_info[512];

const char comment_chars[]        = "!/";
const char line_separator_chars[] = ";";
const char line_comment_chars[]   = "/!#";

static int pending_reloc;
static struct hash_control *opcode_hash_control;

static void
little (int ignore ATTRIBUTE_UNUSED)
{
  target_big_endian = 0;
}

static void
big (int ignore ATTRIBUTE_UNUSED)
{
  target_big_endian = 1;
}

const pseudo_typeS md_pseudo_table[] =
{
  {"ml",    little, 0},
  {"mb",    big,    0},
  {0, 0, 0}
};

const char FLT_CHARS[] = "rRsSfFdDxXpP";
const char EXP_CHARS[] = "eE";

void
md_operand (expressionS *op)
{
  if (strncmp (input_line_pointer, "%hi16", 5) == 0)
    {
      if (pending_reloc)
	as_bad (_("confusing relocation expressions"));
      pending_reloc = BFD_RELOC_PJ_CODE_HI16;
      input_line_pointer += 5;
      expression (op);
    }

  if (strncmp (input_line_pointer, "%lo16", 5) == 0)
    {
      if (pending_reloc)
	as_bad (_("confusing relocation expressions"));
      pending_reloc = BFD_RELOC_PJ_CODE_LO16;
      input_line_pointer += 5;
      expression (op);
    }
}

/* Parse an expression and then restore the input line pointer.  */

static char *
parse_exp_save_ilp (char *s, expressionS *op)
{
  char *save = input_line_pointer;

  input_line_pointer = s;
  expression (op);
  s = input_line_pointer;
  input_line_pointer = save;
  return s;
}

/* This is called by emit_expr via TC_CONS_FIX_NEW when creating a
   reloc for a cons.  We could use the definition there, except that
   we want to handle magic pending reloc expressions specially.  */

void
pj_cons_fix_new_pj (fragS *frag, int where, int nbytes, expressionS *exp)
{
  static int rv[5][2] =
  { { 0, 0 },
    { BFD_RELOC_8, BFD_RELOC_8 },
    { BFD_RELOC_PJ_CODE_DIR16, BFD_RELOC_16 },
    { 0, 0 },
    { BFD_RELOC_PJ_CODE_DIR32, BFD_RELOC_32 }};

  fix_new_exp (frag, where, nbytes, exp, 0,
	       pending_reloc ? pending_reloc
	       : rv[nbytes][(now_seg->flags & SEC_CODE) ? 0 : 1]);

  pending_reloc = 0;
}

/* Turn a reloc description character from the pj-opc.h table into
   code which BFD can handle.  */

static int
c_to_r (int x)
{
  switch (x)
    {
    case O_R8:
      return BFD_RELOC_8_PCREL;
    case O_U8:
    case O_8:
      return BFD_RELOC_8;
    case O_R16:
      return BFD_RELOC_PJ_CODE_REL16;
    case O_U16:
    case O_16:
      return BFD_RELOC_PJ_CODE_DIR16;
    case O_R32:
      return BFD_RELOC_PJ_CODE_REL32;
    case O_32:
      return BFD_RELOC_PJ_CODE_DIR32;
    }
  abort ();
  return 0;
}

/* Handler for the ipush fake opcode,
   turns ipush <foo> into sipush lo16<foo>, sethi hi16<foo>.  */

static void
ipush_code (pj_opc_info_t *opcode ATTRIBUTE_UNUSED, char *str)
{
  char *b = frag_more (6);
  expressionS arg;

  b[0] = 0x11;
  b[3] = 0xed;
  parse_exp_save_ilp (str + 1, &arg);
  if (pending_reloc)
    {
      as_bad (_("can't have relocation for ipush"));
      pending_reloc = 0;
    }

  fix_new_exp (frag_now, b - frag_now->fr_literal + 1, 2,
	       &arg, 0, BFD_RELOC_PJ_CODE_DIR16);
  fix_new_exp (frag_now, b - frag_now->fr_literal + 4, 2,
	       &arg, 0, BFD_RELOC_PJ_CODE_HI16);
}

/* Insert names into the opcode table which are really mini macros,
   not opcodes.  The fakeness is indicated with an opcode of -1.  */

static void
fake_opcode (const char *name,
	     void (*func) (struct pj_opc_info_t *, char *))
{
  pj_opc_info_t * fake = xmalloc (sizeof (pj_opc_info_t));

  fake->opcode = -1;
  fake->opcode_next = -1;
  fake->u.func = func;
  hash_insert (opcode_hash_control, name, (char *) fake);
}

/* Enter another entry into the opcode hash table so the same opcode
   can have another name.  */

static void
alias (const char *new_name, const char *old)
{
  hash_insert (opcode_hash_control, new_name,
	       (char *) hash_find (opcode_hash_control, old));
}

/* This function is called once, at assembler startup time.  It sets
   up the hash table with all the opcodes in it, and also initializes
   some aliases for compatibility with other assemblers.  */

void
md_begin (void)
{
  const pj_opc_info_t *opcode;
  opcode_hash_control = hash_new ();

  /* Insert names into hash table.  */
  for (opcode = pj_opc_info; opcode->u.name; opcode++)
    hash_insert (opcode_hash_control, opcode->u.name, (char *) opcode);

  /* Insert the only fake opcode.  */
  fake_opcode ("ipush", ipush_code);

  /* Add some aliases for opcode names.  */
  alias ("ifeq_s", "ifeq");
  alias ("ifne_s", "ifne");
  alias ("if_icmpge_s", "if_icmpge");
  alias ("if_icmpne_s", "if_icmpne");
  alias ("if_icmpeq_s", "if_icmpeq");
  alias ("if_icmpgt_s", "if_icmpgt");
  alias ("goto_s", "goto");

  bfd_set_arch_mach (stdoutput, TARGET_ARCH, 0);
}

/* This is the guts of the machine-dependent assembler.  STR points to
   a machine dependent instruction.  This function is supposed to emit
   the frags/bytes it assembles to.  */

void
md_assemble (char *str)
{
  char *op_start;
  char *op_end;

  pj_opc_info_t *opcode;
  char *output;
  int idx = 0;
  char pend;

  int nlen = 0;

  /* Drop leading whitespace.  */
  while (*str == ' ')
    str++;

  /* Find the op code end.  */
  op_start = str;
  for (op_end = str;
       *op_end && !is_end_of_line[*op_end & 0xff] && *op_end != ' ';
       op_end++)
    nlen++;

  pend = *op_end;
  *op_end = 0;

  if (nlen == 0)
    as_bad (_("can't find opcode "));

  opcode = (pj_opc_info_t *) hash_find (opcode_hash_control, op_start);
  *op_end = pend;

  if (opcode == NULL)
    {
      as_bad (_("unknown opcode %s"), op_start);
      return;
    }

  dwarf2_emit_insn (0);
  if (opcode->opcode == -1)
    {
      /* It's a fake opcode.  Dig out the args and pretend that was
         what we were passed.  */
      (*opcode->u.func) (opcode, op_end);
    }
  else
    {
      int an;

      output = frag_more (opcode->len);
      output[idx++] = opcode->opcode;

      if (opcode->opcode_next != -1)
	output[idx++] = opcode->opcode_next;

      for (an = 0; opcode->arg[an]; an++)
	{
	  expressionS arg;

	  if (*op_end == ',' && an != 0)
	    op_end++;

	  if (*op_end == 0)
	    as_bad (_("expected expresssion"));

	  op_end = parse_exp_save_ilp (op_end, &arg);

	  fix_new_exp (frag_now,
		       output - frag_now->fr_literal + idx,
		       ASIZE (opcode->arg[an]),
		       &arg,
		       PCREL (opcode->arg[an]),
		       pending_reloc ? pending_reloc : c_to_r (opcode->arg[an]));

	  idx += ASIZE (opcode->arg[an]);
	  pending_reloc = 0;
	}

      while (ISSPACE (*op_end))
	op_end++;

      if (*op_end != 0)
	as_warn (_("extra stuff on line ignored"));

    }

  if (pending_reloc)
    as_bad (_("Something forgot to clean up\n"));
}

char *
md_atof (int type, char *litP, int *sizeP)
{
  return ieee_md_atof (type, litP, sizeP, target_big_endian);
}

const char *md_shortopts = "";

struct option md_longopts[] =
{
#define OPTION_LITTLE (OPTION_MD_BASE)
#define OPTION_BIG    (OPTION_LITTLE + 1)

  {"little", no_argument, NULL, OPTION_LITTLE},
  {"big", no_argument, NULL, OPTION_BIG},
  {NULL, no_argument, NULL, 0}
};
size_t md_longopts_size = sizeof (md_longopts);

int
md_parse_option (int c, char *arg ATTRIBUTE_UNUSED)
{
  switch (c)
    {
    case OPTION_LITTLE:
      little (0);
      break;
    case OPTION_BIG:
      big (0);
      break;
    default:
      return 0;
    }
  return 1;
}

void
md_show_usage (FILE *stream)
{
  fprintf (stream, _("\
PJ options:\n\
-little			generate little endian code\n\
-big			generate big endian code\n"));
}

/* Apply a fixup to the object file.  */

void
md_apply_fix (fixS *fixP, valueT * valP, segT seg ATTRIBUTE_UNUSED)
{
  char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
  long val = *valP;
  long max, min;

  max = min = 0;
  switch (fixP->fx_r_type)
    {
    case BFD_RELOC_VTABLE_INHERIT:
    case BFD_RELOC_VTABLE_ENTRY:
      fixP->fx_done = 0;
      return;

    case BFD_RELOC_PJ_CODE_REL16:
      if (val < -0x8000 || val >= 0x7fff)
	as_bad_where (fixP->fx_file, fixP->fx_line, _("pcrel too far"));
      buf[0] |= (val >> 8) & 0xff;
      buf[1] = val & 0xff;
      break;

    case BFD_RELOC_PJ_CODE_HI16:
      *buf++ = val >> 24;
      *buf++ = val >> 16;
      fixP->fx_addnumber = val & 0xffff;
      break;

    case BFD_RELOC_PJ_CODE_DIR16:
    case BFD_RELOC_PJ_CODE_LO16:
      *buf++ = val >> 8;
      *buf++ = val >> 0;

      max = 0xffff;
      min = -0xffff;
      break;

    case BFD_RELOC_8:
      max = 0xff;
      min = -0xff;
      *buf++ = val;
      break;

    case BFD_RELOC_PJ_CODE_DIR32:
      *buf++ = val >> 24;
      *buf++ = val >> 16;
      *buf++ = val >> 8;
      *buf++ = val >> 0;
      break;

    case BFD_RELOC_32:
      if (target_big_endian)
	{
	  *buf++ = val >> 24;
	  *buf++ = val >> 16;
	  *buf++ = val >> 8;
	  *buf++ = val >> 0;
	}
      else
	{
	  *buf++ = val >> 0;
	  *buf++ = val >> 8;
	  *buf++ = val >> 16;
	  *buf++ = val >> 24;
	}
      break;

    case BFD_RELOC_16:
      if (target_big_endian)
	{
	  *buf++ = val >> 8;
	  *buf++ = val >> 0;
	}
      else
	{
	  *buf++ = val >> 0;
	  *buf++ = val >> 8;
	}
      break;

    default:
      abort ();
    }

  if (max != 0 && (val < min || val > max))
    as_bad_where (fixP->fx_file, fixP->fx_line, _("offset out of range"));

  if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
    fixP->fx_done = 1;
}

/* Put number into target byte order.  Always put values in an
   executable section into big endian order.  */

void
md_number_to_chars (char *ptr, valueT use, int nbytes)
{
  if (target_big_endian || now_seg->flags & SEC_CODE)
    number_to_chars_bigendian (ptr, use, nbytes);
  else
    number_to_chars_littleendian (ptr, use, nbytes);
}

/* Translate internal representation of relocation info to BFD target
   format.  */

arelent *
tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
{
  arelent *rel;
  bfd_reloc_code_real_type r_type;

  rel = xmalloc (sizeof (arelent));
  rel->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
  *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
  rel->address = fixp->fx_frag->fr_address + fixp->fx_where;

  r_type = fixp->fx_r_type;
  rel->addend = fixp->fx_addnumber;
  rel->howto = bfd_reloc_type_lookup (stdoutput, r_type);

  if (rel->howto == NULL)
    {
      as_bad_where (fixp->fx_file, fixp->fx_line,
		    _("Cannot represent relocation type %s"),
		    bfd_get_reloc_code_name (r_type));
      /* Set howto to a garbage value so that we can keep going.  */
      rel->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_32);
      gas_assert (rel->howto != NULL);
    }

  return rel;
}
