/* OpenRISC 1000 opcode support.  -*- C -*-
   Copyright 2000-2014 Free Software Foundation, Inc.

   Originally ontributed for OR32 by Red Hat Inc;

   This file is part of the GNU Binutils.

   This program 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 of the License, or
   (at your option) any later version.

   This program 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 this program; if not, see <http://www.gnu.org/licenses/>. */

/* This file is an addendum to or1k.cpu.  Heavy use of C code isn't
   appropriate in .cpu files, so it resides here.  This especially applies
   to assembly/disassembly where parsing/printing can be quite involved.
   Such things aren't really part of the specification of the cpu, per se,
   so .cpu files provide the general framework and .opc files handle the
   nitty-gritty details as necessary.

   Each section is delimited with start and end markers.

   <arch>-opc.h additions use: "-- opc.h"
   <arch>-opc.c additions use: "-- opc.c"
   <arch>-asm.c additions use: "-- asm.c"
   <arch>-dis.c additions use: "-- dis.c"
   <arch>-ibd.h additions use: "-- ibd.h"  */

/* -- opc.h */

#undef  CGEN_DIS_HASH_SIZE
#define CGEN_DIS_HASH_SIZE 256
#undef  CGEN_DIS_HASH
#define CGEN_DIS_HASH(buffer, value) (((unsigned char *) (buffer))[0] >> 2)

/* Check applicability of instructions against machines.  */
#define CGEN_VALIDATE_INSN_SUPPORTED

extern int or1k_cgen_insn_supported (CGEN_CPU_DESC, const CGEN_INSN *);

/* -- */

/* -- opc.c */

/* Special check to ensure that instruction exists for given machine.  */

int
or1k_cgen_insn_supported (CGEN_CPU_DESC cd, const CGEN_INSN *insn)
{
  int machs = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_MACH);

  /* No mach attribute?  Assume it's supported for all machs.  */
  if (machs == 0)
    return 1;

  return ((machs & cd->machs) != 0);
}

/* -- */

/* -- asm.c */

static const char * MISSING_CLOSING_PARENTHESIS = N_("missing `)'");
static const char * INVALID_STORE_RELOC = N_("relocation invalid for store");
static const char * INVALID_RELOC_TYPE = N_("internal relocation type invalid");

#define CGEN_VERBOSE_ASSEMBLER_ERRORS

static const char *
parse_disp26 (CGEN_CPU_DESC cd,
	      const char ** strp,
	      int opindex,
	      int opinfo ATTRIBUTE_UNUSED,
	      enum cgen_parse_operand_result * resultp,
	      bfd_vma * valuep)
{
  const char *str = *strp;
  const char *errmsg = NULL;
  bfd_reloc_code_real_type reloc = BFD_RELOC_OR1K_REL_26;

  if (strncasecmp (str, "plta(", 5) == 0)
    {
      *strp = str + 5;
      reloc = BFD_RELOC_OR1K_PLTA26;
    }
  else if (strncasecmp (str, "plt(", 4) == 0)
    {
      *strp = str + 4;
      reloc = BFD_RELOC_OR1K_PLT26;
    }

  errmsg = cgen_parse_address (cd, strp, opindex, reloc, resultp, valuep);

  if (reloc != BFD_RELOC_OR1K_REL_26)
    {
      if (**strp != ')')
	errmsg = MISSING_CLOSING_PARENTHESIS;
      else
	++*strp;
    }

  return errmsg;
}

static const char *
parse_disp21 (CGEN_CPU_DESC cd,
	      const char ** strp,
	      int opindex,
	      int opinfo ATTRIBUTE_UNUSED,
	      enum cgen_parse_operand_result * resultp,
	      bfd_vma * valuep)
{
  const char *str = *strp;
  const char *errmsg = NULL;
  bfd_reloc_code_real_type reloc = BFD_RELOC_OR1K_PCREL_PG21;

  if (strncasecmp (str, "got(", 4) == 0)
    {
      *strp = str + 4;
      reloc = BFD_RELOC_OR1K_GOT_PG21;
    }
  else if (strncasecmp (str, "tlsgd(", 6) == 0)
    {
      *strp = str + 6;
      reloc = BFD_RELOC_OR1K_TLS_GD_PG21;
    }
  else if (strncasecmp (str, "tlsldm(", 7) == 0)
    {
      *strp = str + 7;
      reloc = BFD_RELOC_OR1K_TLS_LDM_PG21;
    }
  else if (strncasecmp (str, "gottp(", 6) == 0)
    {
      *strp = str + 6;
      reloc = BFD_RELOC_OR1K_TLS_IE_PG21;
    }

  errmsg = cgen_parse_address (cd, strp, opindex, reloc, resultp, valuep);

  if (reloc != BFD_RELOC_OR1K_PCREL_PG21)
    {
      if (**strp != ')')
	errmsg = MISSING_CLOSING_PARENTHESIS;
      else
	++*strp;
    }

  return errmsg;
}

enum or1k_rclass
{
  RCLASS_DIRECT   = 0,
  RCLASS_GOT      = 1,
  RCLASS_GOTPC    = 2,
  RCLASS_GOTOFF   = 3,
  RCLASS_TLSGD    = 4,
  RCLASS_TLSLDM   = 5,
  RCLASS_DTPOFF   = 6,
  RCLASS_GOTTPOFF = 7,
  RCLASS_TPOFF    = 8,
};

enum or1k_rtype
{
  RTYPE_LO = 0,
  RTYPE_SLO = 1,
  RTYPE_PO = 2,
  RTYPE_SPO = 3,
  RTYPE_HI = 4,
  RTYPE_AHI = 5,
};

#define RCLASS_SHIFT 3
#define RTYPE_MASK   7

static const bfd_reloc_code_real_type or1k_imm16_relocs[][6] = {
  { BFD_RELOC_LO16,
    BFD_RELOC_OR1K_SLO16,
    BFD_RELOC_OR1K_LO13,
    BFD_RELOC_OR1K_SLO13,
    BFD_RELOC_HI16,
    BFD_RELOC_HI16_S, },
  { BFD_RELOC_OR1K_GOT16,
    BFD_RELOC_UNUSED,
    BFD_RELOC_OR1K_GOT_LO13,
    BFD_RELOC_UNUSED,
    BFD_RELOC_UNUSED,
    BFD_RELOC_UNUSED },
  { BFD_RELOC_OR1K_GOTPC_LO16,
    BFD_RELOC_UNUSED,
    BFD_RELOC_UNUSED,
    BFD_RELOC_UNUSED,
    BFD_RELOC_OR1K_GOTPC_HI16,
    BFD_RELOC_UNUSED },
  { BFD_RELOC_LO16_GOTOFF,
    BFD_RELOC_OR1K_GOTOFF_SLO16,
    BFD_RELOC_UNUSED,
    BFD_RELOC_UNUSED,
    BFD_RELOC_HI16_GOTOFF,
    BFD_RELOC_HI16_S_GOTOFF },
  { BFD_RELOC_OR1K_TLS_GD_LO16,
    BFD_RELOC_UNUSED,
    BFD_RELOC_OR1K_TLS_GD_LO13,
    BFD_RELOC_UNUSED,
    BFD_RELOC_OR1K_TLS_GD_HI16,
    BFD_RELOC_UNUSED },
  { BFD_RELOC_OR1K_TLS_LDM_LO16,
    BFD_RELOC_UNUSED,
    BFD_RELOC_OR1K_TLS_LDM_LO13,
    BFD_RELOC_UNUSED,
    BFD_RELOC_OR1K_TLS_LDM_HI16,
    BFD_RELOC_UNUSED },
  { BFD_RELOC_OR1K_TLS_LDO_LO16,
    BFD_RELOC_UNUSED,
    BFD_RELOC_UNUSED,
    BFD_RELOC_UNUSED,
    BFD_RELOC_OR1K_TLS_LDO_HI16,
    BFD_RELOC_UNUSED },
  { BFD_RELOC_OR1K_TLS_IE_LO16,
    BFD_RELOC_UNUSED,
    BFD_RELOC_OR1K_TLS_IE_LO13,
    BFD_RELOC_UNUSED,
    BFD_RELOC_OR1K_TLS_IE_HI16,
    BFD_RELOC_OR1K_TLS_IE_AHI16 },
  { BFD_RELOC_OR1K_TLS_LE_LO16,
    BFD_RELOC_OR1K_TLS_LE_SLO16,
    BFD_RELOC_UNUSED,
    BFD_RELOC_UNUSED,
    BFD_RELOC_OR1K_TLS_LE_HI16,
    BFD_RELOC_OR1K_TLS_LE_AHI16 },
};

static int
parse_reloc (const char **strp)
{
    const char *str = *strp;
    enum or1k_rclass cls = RCLASS_DIRECT;
    enum or1k_rtype typ;

    if (strncasecmp (str, "got(", 4) == 0)
      {
	*strp = str + 4;
	return (RCLASS_GOT << RCLASS_SHIFT) | RTYPE_LO;
      }
    if (strncasecmp (str, "gotpo(", 6) == 0)
      {
	*strp = str + 6;
	return (RCLASS_GOT << RCLASS_SHIFT) | RTYPE_PO;
      }
    if (strncasecmp (str, "gottppo(", 8) == 0)
      {
	*strp = str + 8;
	return (RCLASS_GOTTPOFF << RCLASS_SHIFT) | RTYPE_PO;
      }

    if (strncasecmp (str, "gotpc", 5) == 0)
      {
	str += 5;
	cls = RCLASS_GOTPC;
      }
    else if (strncasecmp (str, "gotoff", 6) == 0)
      {
	str += 6;
	cls = RCLASS_GOTOFF;
      }
    else if (strncasecmp (str, "tlsgd", 5) == 0)
      {
	str += 5;
	cls = RCLASS_TLSGD;
      }
    else if (strncasecmp (str, "tlsldm", 6) == 0)
      {
	str += 6;
	cls = RCLASS_TLSLDM;
      }
    else if (strncasecmp (str, "dtpoff", 6) == 0)
      {
	str += 6;
	cls = RCLASS_DTPOFF;
      }
    else if (strncasecmp (str, "gottpoff", 8) == 0)
      {
	str += 8;
	cls = RCLASS_GOTTPOFF;
      }
    else if (strncasecmp (str, "tpoff", 5) == 0)
      {
	str += 5;
	cls = RCLASS_TPOFF;
      }

    if (strncasecmp (str, "hi(", 3) == 0)
      {
	str += 3;
	typ = RTYPE_HI;
      }
    else if (strncasecmp (str, "lo(", 3) == 0)
      {
	str += 3;
	typ = RTYPE_LO;
      }
    else if (strncasecmp (str, "ha(", 3) == 0)
      {
	str += 3;
	typ = RTYPE_AHI;
      }
    else if (strncasecmp (str, "po(", 3) == 0 && cls != RCLASS_GOTTPOFF)
      {
	str += 3;
	typ = RTYPE_PO;
      }
    else
      return -1;

    *strp = str;
    return (cls << RCLASS_SHIFT) | typ;
}

static const char *
parse_imm16 (CGEN_CPU_DESC cd, const char **strp, int opindex,
	     long *valuep, int splitp)
{
  const char *errmsg;
  enum cgen_parse_operand_result result_type;
  bfd_reloc_code_real_type reloc = BFD_RELOC_UNUSED;
  enum or1k_rtype reloc_type;
  int reloc_code;
  bfd_vma ret;

  if (**strp == '#')
    ++*strp;

  reloc_code = parse_reloc (strp);
  reloc_type = reloc_code & RTYPE_MASK;
  if (reloc_code >= 0)
    {
      enum or1k_rclass reloc_class = reloc_code >> RCLASS_SHIFT;
      if (splitp)
	{
	  if ((reloc_type == RTYPE_LO || reloc_type == RTYPE_PO)
	      && reloc_class != RCLASS_GOT)
	    /* If split we or up the type to RTYPE_SLO or RTYPE_SPO.  */
	    reloc_type |= 1;
	  else
	    return INVALID_STORE_RELOC;
	}
      reloc = or1k_imm16_relocs[reloc_class][reloc_type];
    }

  if (reloc != BFD_RELOC_UNUSED)
    {
      bfd_vma value;

      errmsg = cgen_parse_address (cd, strp, opindex, reloc,
				   &result_type, &value);
      if (**strp != ')')
	errmsg = MISSING_CLOSING_PARENTHESIS;
      ++*strp;

      ret = value;

      if (errmsg == NULL && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
	switch (reloc_type)
	  {
	  case RTYPE_AHI:
	    ret += 0x8000;
	    /* FALLTHRU */
	  case RTYPE_HI:
	    ret >>= 16;
	    /* FALLTHRU */
	  case RTYPE_LO:
	  case RTYPE_SLO:
	    ret &= 0xffff;
	    ret = (ret ^ 0x8000) - 0x8000;
	    break;
	  case RTYPE_PO:
	  case RTYPE_SPO:
	    ret &= 0x1fff;
	    break;
	  default:
	    errmsg = INVALID_RELOC_TYPE;
	  }
    }
  else
    {
      long value;
      errmsg = cgen_parse_signed_integer (cd, strp, opindex, &value);
      ret = value;
    }

  if (errmsg == NULL)
    *valuep = ret;

  return errmsg;
}

static const char *
parse_simm16 (CGEN_CPU_DESC cd, const char **strp, int opindex, long *valuep)
{
  return parse_imm16(cd, strp, opindex, (long *) valuep, 0);
}

static const char *
parse_simm16_split (CGEN_CPU_DESC cd, const char **strp, int opindex,
		    long *valuep)
{
  return parse_imm16(cd, strp, opindex, (long *) valuep, 1);
}

static const char *
parse_uimm16 (CGEN_CPU_DESC cd, const char **strp, int opindex,
	      unsigned long *valuep)
{
  const char *errmsg = parse_imm16(cd, strp, opindex, (long *) valuep, 0);
  if (errmsg == NULL)
    *valuep &= 0xffff;
  return errmsg;
}

static const char *
parse_uimm16_split (CGEN_CPU_DESC cd, const char **strp, int opindex,
		    unsigned long *valuep)
{
  const char *errmsg = parse_imm16(cd, strp, opindex, (long *) valuep, 1);
  if (errmsg == NULL)
    *valuep &= 0xffff;
  return errmsg;
}

/* Parse register pairs with syntax rA,rB to a flag + rA value.  */

static const char *
parse_regpair (CGEN_CPU_DESC cd, const char **strp,
	       int opindex ATTRIBUTE_UNUSED, unsigned long *valuep)
{
  long reg1_index;
  long reg2_index;
  const char *errmsg;

  /* The first part should just be a register.  */
  errmsg = cgen_parse_keyword (cd, strp, &or1k_cgen_opval_h_gpr,
			       &reg1_index);

  /* If that worked skip the comma separator.  */
  if (errmsg == NULL)
    {
      if (**strp == ',')
	++*strp;
      else
	errmsg = "Unexpected character, expected ','";
    }

  /* If that worked the next part is just another register.  */
  if (errmsg == NULL)
    errmsg = cgen_parse_keyword (cd, strp, &or1k_cgen_opval_h_gpr,
				 &reg2_index);

  /* Validate the register pair is valid and create the output value.  */
  if (errmsg == NULL)
    {
      int regoffset = reg2_index - reg1_index;

      if (regoffset == 1 || regoffset == 2)
	{
	  unsigned short offsetmask;
	  unsigned short value;

	  offsetmask = ((regoffset == 2 ? 1 : 0) << 5);
	  value = offsetmask | reg1_index;

	  *valuep = value;
	}
      else
	errmsg = "Invalid register pair, offset not 1 or 2.";
    }

  return errmsg;
}

/* -- */

/* -- dis.c */

static void
print_regpair (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
	       void * dis_info,
	       long value,
	       unsigned int attrs ATTRIBUTE_UNUSED,
	       bfd_vma pc ATTRIBUTE_UNUSED,
	       int length ATTRIBUTE_UNUSED)
{
  disassemble_info *info = dis_info;
  char reg1_index;
  char reg2_index;

  reg1_index = value & 0x1f;
  reg2_index = reg1_index + ((value & (1 << 5)) ? 2 : 1);

  (*info->fprintf_func) (info->stream, "r%d,r%d", reg1_index, reg2_index);
}

/* -- */

/* -- ibd.h */

/* -- */
