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

/* -- */
