/* 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) ((value >> 26) & 0xff)

/* 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_OR1K_GOT_AHI16 },
  { 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;
      }
    else if (strncasecmp (str, "got", 3) == 0)
      {
	str += 3;
	cls = RCLASS_GOT;
      }

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

/* -- */
