/*-
   tc-pj.c -- Assemble code for Pico Java
   Copyright 1999, 2000 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 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.  */

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

#include "as.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 (ignore)
     int ignore ATTRIBUTE_UNUSED;
{
  target_big_endian = 0;
}

static void
big (ignore)
     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 (op)
     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 (s, op)
     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 (frag, where, nbytes, exp)
     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 (x)
     char 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 (opcode, str)
     pj_opc_info_t *opcode ATTRIBUTE_UNUSED;
     char *str;
{
  int mod = 0;
  char *b = frag_more (6);
  expressionS arg;

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

  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 inidicated with an opcode of -1.  */

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

  fake->opcode = -1;
  fake->opcode_next = -1;
  fake->name = (const char *) 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 (new, old)
     const char *new;
     const char *old;
{
  hash_insert (opcode_hash_control, new,
	       (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 ()
{
  const pj_opc_info_t *opcode;
  opcode_hash_control = hash_new ();

  /* Insert names into hash table.  */
  for (opcode = pj_opc_info; opcode->name; opcode++)
    hash_insert (opcode_hash_control, opcode->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 (str)
     char *str;
{
  unsigned char *op_start;
  unsigned char *op_end;

#if 0
  pj_operan_info operand[3];
#endif
  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.  */
  for (op_start = op_end = (unsigned char *) (str);
       *op_end && !is_end_of_line[*op_end] && *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;
    }

  if (opcode->opcode == -1)
    {
      /* It's a fake opcode.  Dig out the args and pretend that was
         what we were passed.  */
      ((void (*) ()) opcode->name) (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");

}

/* 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.  */

char *
md_atof (type, litP, sizeP)
     int type;
     char *litP;
     int *sizeP;
{
  int prec;
  LITTLENUM_TYPE words[4];
  char *t;
  int i;

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

    case 'd':
      prec = 4;
      break;

    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 * 2;

  if (!target_big_endian)
    {
      for (i = prec - 1; i >= 0; i--)
	{
	  md_number_to_chars (litP, (valueT) words[i], 2);
	  litP += 2;
	}
    }
  else
    {
      for (i = 0; i < prec; i++)
	{
	  md_number_to_chars (litP, (valueT) words[i], 2);
	  litP += 2;
	}
    }

  return NULL;
}

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 (c, arg)
     int c;
     char *arg ATTRIBUTE_UNUSED;
{
  switch (c)
    {
    case OPTION_LITTLE:
      little ();
      break;
    case OPTION_BIG:
      big ();
      break;
    default:
      return 0;
    }
  return 1;
}

void
md_show_usage (stream)
     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.  */

int
md_apply_fix (fixP, valp)
     fixS *fixP;
     valueT *valp;
{
  char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
  long val = *valp;
  long max, min;
  int shift;

  /* adjust_reloc_syms won't convert a reloc against a weak symbol
     into a reloc against a section, but bfd_install_relocation will
     screw up if the symbol is defined, so we have to adjust val here
     to avoid the screw up later.  */

  if (fixP->fx_addsy != NULL && S_IS_WEAK (fixP->fx_addsy))
    val -= S_GET_VALUE (fixP->fx_addsy);

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

    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"));

  return 0;
}

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

void
md_number_to_chars (ptr, use, nbytes)
     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 (section, fixp)
     asection *section ATTRIBUTE_UNUSED;
     fixS *fixp;
{
  arelent *rel;
  bfd_reloc_code_real_type r_type;

  rel = (arelent *) xmalloc (sizeof (arelent));
  rel->sym_ptr_ptr = (asymbol **) 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);
      assert (rel->howto != NULL);
    }

  return rel;
}
