/* Disassembler code for CRX.
   Copyright (C) 2004-2022 Free Software Foundation, Inc.
   Contributed by Tomer Levi, NSC, Israel.
   Written by Tomer Levi.

   This file is part of the GNU opcodes library.

   This library 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.

   It 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, write to the Free Software
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */

#include "sysdep.h"
#include "disassemble.h"
#include "opcode/crx.h"

/* String to print when opcode was not matched.  */
#define ILLEGAL	"illegal"
  /* Escape to 16-bit immediate.  */
#define ESCAPE_16_BIT  0xE

/* Extract 'n_bits' from 'a' starting from offset 'offs'.  */
#define EXTRACT(a, offs, n_bits)	    \
  (((a) >> (offs)) & ((2ull << (n_bits - 1)) - 1))

/* Set Bit Mask - a mask to set all bits starting from offset 'offs'.  */
#define SBM(offs)  ((-1u << (offs)) & 0xffffffff)

typedef unsigned long dwordU;
typedef unsigned short wordU;

typedef struct
{
  dwordU val;
  int nbits;
} parameter;

/* Structure to hold valid 'cinv' instruction options.  */

typedef struct
  {
    /* Cinv printed string.  */
    char *str;
    /* Value corresponding to the string.  */
    unsigned int value;
  }
cinv_entry;

/* CRX 'cinv' options.  */
static const cinv_entry crx_cinvs[] =
{
  {"[i]", 2}, {"[i,u]", 3}, {"[d]", 4}, {"[d,u]", 5},
  {"[d,i]", 6}, {"[d,i,u]", 7}, {"[b]", 8},
  {"[b,i]", 10}, {"[b,i,u]", 11}, {"[b,d]", 12},
  {"[b,d,u]", 13}, {"[b,d,i]", 14}, {"[b,d,i,u]", 15}
};

/* Enum to distinguish different registers argument types.  */
typedef enum REG_ARG_TYPE
  {
    /* General purpose register (r<N>).  */
    REG_ARG = 0,
    /* User register (u<N>).  */
    USER_REG_ARG,
    /* CO-Processor register (c<N>).  */
    COP_ARG,
    /* CO-Processor special register (cs<N>).  */
    COPS_ARG
  }
REG_ARG_TYPE;

/* Number of valid 'cinv' instruction options.  */
static int NUMCINVS = ((sizeof crx_cinvs)/(sizeof crx_cinvs[0]));
/* Current opcode table entry we're disassembling.  */
static const inst *instruction;
/* Current instruction we're disassembling.  */
static ins currInsn;
/* The current instruction is read into 3 consecutive words.  */
static wordU words[3];
/* Contains all words in appropriate order.  */
static ULONGLONG allWords;
/* Holds the current processed argument number.  */
static int processing_argument_number;
/* Nonzero means a CST4 instruction.  */
static int cst4flag;
/* Nonzero means the instruction's original size is
   incremented (escape sequence is used).  */
static int size_changed;


/* Retrieve the number of operands for the current assembled instruction.  */

static int
get_number_of_operands (void)
{
  int i;

  for (i = 0; i < MAX_OPERANDS && instruction->operands[i].op_type; i++)
    ;

  return i;
}

/* Return the bit size for a given operand.  */

static int
getbits (operand_type op)
{
  if (op < MAX_OPRD)
    return crx_optab[op].bit_size;
  else
    return 0;
}

/* Return the argument type of a given operand.  */

static argtype
getargtype (operand_type op)
{
  if (op < MAX_OPRD)
    return crx_optab[op].arg_type;
  else
    return nullargs;
}

/* Given the trap index in dispatch table, return its name.
   This routine is used when disassembling the 'excp' instruction.  */

static char *
gettrapstring (unsigned int trap_index)
{
  const trap_entry *trap;

  for (trap = crx_traps; trap < crx_traps + NUMTRAPS; trap++)
    if (trap->entry == trap_index)
      return trap->name;

  return ILLEGAL;
}

/* Given a 'cinv' instruction constant operand, return its corresponding string.
   This routine is used when disassembling the 'cinv' instruction.  */

static char *
getcinvstring (unsigned int num)
{
  const cinv_entry *cinv;

  for (cinv = crx_cinvs; cinv < (crx_cinvs + NUMCINVS); cinv++)
    if (cinv->value == num)
      return cinv->str;

  return ILLEGAL;
}

/* Given a register enum value, retrieve its name.  */

static char *
getregname (reg r)
{
  const reg_entry * regentry = &crx_regtab[r];

  if (regentry->type != CRX_R_REGTYPE)
    return ILLEGAL;
  else
    return regentry->name;
}

/* Given a coprocessor register enum value, retrieve its name.  */

static char *
getcopregname (copreg r, reg_type type)
{
  const reg_entry * regentry;

  if (type == CRX_C_REGTYPE)
    regentry = &crx_copregtab[r];
  else if (type == CRX_CS_REGTYPE)
    regentry = &crx_copregtab[r+(cs0-c0)];
  else
    return ILLEGAL;

  return regentry->name;
}


/* Getting a processor register name.  */

static char *
getprocregname (int reg_index)
{
  const reg_entry *r;

  for (r = crx_regtab; r < crx_regtab + NUMREGS; r++)
    if (r->image == reg_index)
      return r->name;

  return "ILLEGAL REGISTER";
}

/* Get the power of two for a given integer.  */

static int
powerof2 (int x)
{
  int product, i;

  for (i = 0, product = 1; i < x; i++)
    product *= 2;

  return product;
}

/* Transform a register bit mask to a register list.  */

static void
getregliststring (int mask, char *string, enum REG_ARG_TYPE core_cop)
{
  char temp_string[16];
  int i;

  string[0] = '{';
  string[1] = '\0';


  /* A zero mask means HI/LO registers.  */
  if (mask == 0)
    {
      if (core_cop == USER_REG_ARG)
	strcat (string, "ulo,uhi");
      else
	strcat (string, "lo,hi");
    }
  else
    {
      for (i = 0; i < 16; i++)
	{
	  if (mask & 0x1)
	    {
	      switch (core_cop)
	      {
	      case REG_ARG:
		sprintf (temp_string, "r%d", i);
		break;
	      case USER_REG_ARG:
		sprintf (temp_string, "u%d", i);
		break;
	      case COP_ARG:
		sprintf (temp_string, "c%d", i);
		break;
	      case COPS_ARG:
		sprintf (temp_string, "cs%d", i);
		break;
	      default:
		break;
	      }
	      strcat (string, temp_string);
	      if (mask & 0xfffe)
		strcat (string, ",");
	    }
	  mask >>= 1;
	}
    }

  strcat (string, "}");
}

/* START and END are relating 'allWords' struct, which is 48 bits size.

			  START|--------|END
	    +---------+---------+---------+---------+
	    |	      |	   V    |     A	  |   L	    |
	    +---------+---------+---------+---------+
	    	      0		16	  32	    48
    words		  [0]	    [1]	      [2]	*/

static parameter
makelongparameter (ULONGLONG val, int start, int end)
{
  parameter p;

  p.val = (dwordU) EXTRACT(val, 48 - end, end - start);
  p.nbits = end - start;
  return p;
}

/* Build a mask of the instruction's 'constant' opcode,
   based on the instruction's printing flags.  */

static unsigned int
build_mask (void)
{
  unsigned int print_flags;
  unsigned int mask;

  print_flags = instruction->flags & FMT_CRX;
  switch (print_flags)
    {
      case FMT_1:
	mask = 0xF0F00000;
	break;
      case FMT_2:
	mask = 0xFFF0FF00;
	break;
      case FMT_3:
	mask = 0xFFF00F00;
	break;
      case FMT_4:
	mask = 0xFFF0F000;
	break;
      case FMT_5:
	mask = 0xFFF0FFF0;
	break;
      default:
	mask = SBM(instruction->match_bits);
	break;
    }

  return mask;
}

/* Search for a matching opcode. Return 1 for success, 0 for failure.  */

static int
match_opcode (void)
{
  unsigned int mask;

  /* The instruction 'constant' opcode doewsn't exceed 32 bits.  */
  unsigned int doubleWord = words[1] + ((unsigned) words[0] << 16);

  /* Start searching from end of instruction table.  */
  instruction = &crx_instruction[NUMOPCODES - 2];

  /* Loop over instruction table until a full match is found.  */
  while (instruction >= crx_instruction)
    {
      mask = build_mask ();
      if ((doubleWord & mask) == BIN(instruction->match, instruction->match_bits))
	return 1;
      else
	instruction--;
    }
  return 0;
}

/* Set the proper parameter value for different type of arguments.  */

static void
make_argument (argument * a, int start_bits)
{
  int inst_bit_size, total_size;
  parameter p;

  if ((instruction->size == 3) && a->size >= 16)
    inst_bit_size = 48;
  else
    inst_bit_size = 32;

  switch (a->type)
    {
    case arg_copr:
    case arg_copsr:
      p = makelongparameter (allWords, inst_bit_size - (start_bits + a->size),
			     inst_bit_size - start_bits);
      a->cr = p.val;
      break;

    case arg_r:
      p = makelongparameter (allWords, inst_bit_size - (start_bits + a->size),
			     inst_bit_size - start_bits);
      a->r = p.val;
      break;

    case arg_ic:
      p = makelongparameter (allWords, inst_bit_size - (start_bits + a->size),
			     inst_bit_size - start_bits);

      if ((p.nbits == 4) && cst4flag)
	{
	  if (IS_INSN_TYPE (CMPBR_INS) && (p.val == ESCAPE_16_BIT))
	    {
	      /* A special case, where the value is actually stored
		 in the last 4 bits.  */
	      p = makelongparameter (allWords, 44, 48);
	      /* The size of the instruction should be incremented.  */
	      size_changed = 1;
	    }

	  if (p.val == 6)
	    p.val = -1;
	  else if (p.val == 13)
	    p.val = 48;
	  else if (p.val == 5)
	    p.val = -4;
	  else if (p.val == 10)
	    p.val = 32;
	  else if (p.val == 11)
	    p.val = 20;
	  else if (p.val == 9)
	    p.val = 16;
	}

      a->constant = p.val;
      break;

    case arg_idxr:
      a->scale = 0;
      total_size = a->size + 10;  /* sizeof(rbase + ridx + scl2) = 10.  */
      p = makelongparameter (allWords, inst_bit_size - total_size,
			     inst_bit_size - (total_size - 4));
      a->r = p.val;
      p = makelongparameter (allWords, inst_bit_size - (total_size - 4),
			     inst_bit_size - (total_size - 8));
      a->i_r = p.val;
      p = makelongparameter (allWords, inst_bit_size - (total_size - 8),
			     inst_bit_size - (total_size - 10));
      a->scale = p.val;
      p = makelongparameter (allWords, inst_bit_size - (total_size - 10),
			     inst_bit_size);
      a->constant = p.val;
      break;

    case arg_rbase:
      p = makelongparameter (allWords, inst_bit_size - (start_bits + 4),
			     inst_bit_size - start_bits);
      a->r = p.val;
      break;

    case arg_cr:
      if (a->size <= 8)
	{
	  p = makelongparameter (allWords, inst_bit_size - (start_bits + 4),
				 inst_bit_size - start_bits);
	  a->r = p.val;
	  /* Case for opc4 r dispu rbase.  */
	  p = makelongparameter (allWords, inst_bit_size - (start_bits + 8),
				 inst_bit_size - (start_bits + 4));
	}
      else
	{
	  /* The 'rbase' start_bits is always relative to a 32-bit data type.  */
	  p = makelongparameter (allWords, 32 - (start_bits + 4),
				 32 - start_bits);
	  a->r = p.val;
	  p = makelongparameter (allWords, 32 - start_bits,
				 inst_bit_size);
	}
      if ((p.nbits == 4) && cst4flag)
	{
	  if (instruction->flags & DISPUW4)
	    p.val *= 2;
	  else if (instruction->flags & DISPUD4)
	    p.val *= 4;
	}
      a->constant = p.val;
      break;

    case arg_c:
      p = makelongparameter (allWords, inst_bit_size - (start_bits + a->size),
			     inst_bit_size - start_bits);
      a->constant = p.val;
      break;
    default:
      break;
    }
}

/*  Print a single argument.  */

static void
print_arg (argument *a, bfd_vma memaddr, struct disassemble_info *info)
{
  ULONGLONG longdisp, mask;
  int sign_flag = 0;
  int relative = 0;
  bfd_vma number;
  int op_index = 0;
  char string[200];
  void *stream = info->stream;
  fprintf_ftype func = info->fprintf_func;

  switch (a->type)
    {
    case arg_copr:
      func (stream, "%s", getcopregname (a->cr, CRX_C_REGTYPE));
      break;

    case arg_copsr:
      func (stream, "%s", getcopregname (a->cr, CRX_CS_REGTYPE));
      break;

    case arg_r:
      if (IS_INSN_MNEMONIC ("mtpr") || IS_INSN_MNEMONIC ("mfpr"))
	func (stream, "%s", getprocregname (a->r));
      else
	func (stream, "%s", getregname (a->r));
      break;

    case arg_ic:
      if (IS_INSN_MNEMONIC ("excp"))
	func (stream, "%s", gettrapstring (a->constant));

      else if (IS_INSN_MNEMONIC ("cinv"))
	func (stream, "%s", getcinvstring (a->constant));

      else if (INST_HAS_REG_LIST)
	{
	  REG_ARG_TYPE reg_arg_type = IS_INSN_TYPE (COP_REG_INS) ?
	    COP_ARG : IS_INSN_TYPE (COPS_REG_INS) ?
	    COPS_ARG : (instruction->flags & USER_REG) ?
	    USER_REG_ARG : REG_ARG;

	  if ((reg_arg_type == COP_ARG) || (reg_arg_type == COPS_ARG))
	    {
	      /*  Check for proper argument number.  */
	      if (processing_argument_number == 2)
		{
		  getregliststring (a->constant, string, reg_arg_type);
		  func (stream, "%s", string);
		}
	      else
		func (stream, "$0x%lx", a->constant & 0xffffffff);
	    }
	  else
	    {
	      getregliststring (a->constant, string, reg_arg_type);
	      func (stream, "%s", string);
	    }
	}
      else
	func (stream, "$0x%lx", a->constant & 0xffffffff);
      break;

    case arg_idxr:
      func (stream, "0x%lx(%s,%s,%d)", a->constant & 0xffffffff,
	    getregname (a->r), getregname (a->i_r), powerof2 (a->scale));
      break;

    case arg_rbase:
      func (stream, "(%s)", getregname (a->r));
      break;

    case arg_cr:
      func (stream, "0x%lx(%s)", a->constant & 0xffffffff, getregname (a->r));

      if (IS_INSN_TYPE (LD_STOR_INS_INC))
	func (stream, "+");
      break;

    case arg_c:
      /* Removed the *2 part as because implicit zeros are no more required.
	 Have to fix this as this needs a bit of extension in terms of branchins.
	 Have to add support for cmp and branch instructions.  */
      if (IS_INSN_TYPE (BRANCH_INS) || IS_INSN_MNEMONIC ("bal")
	  || IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (DCR_BRANCH_INS)
	  || IS_INSN_TYPE (COP_BRANCH_INS))
	{
	  relative = 1;
	  longdisp = a->constant;
	  longdisp <<= 1;

	  switch (a->size)
	    {
	    case 8:
	    case 16:
	    case 24:
	    case 32:
	      mask = ((LONGLONG) 1 << a->size) - 1;
	      if (longdisp & ((ULONGLONG) 1 << a->size))
		{
		  sign_flag = 1;
		  longdisp = ~(longdisp) + 1;
		}
	      a->constant = (unsigned long int) (longdisp & mask);
	      break;
	    default:
	      func (stream,
		    "Wrong offset used in branch/bal instruction");
	      break;
	    }

	}
      /* For branch Neq instruction it is 2*offset + 2.  */
      else if (IS_INSN_TYPE (BRANCH_NEQ_INS))
	a->constant = 2 * a->constant + 2;
      else if (IS_INSN_TYPE (LD_STOR_INS_INC)
	       || IS_INSN_TYPE (LD_STOR_INS)
	       || IS_INSN_TYPE (STOR_IMM_INS)
	       || IS_INSN_TYPE (CSTBIT_INS))
	{
	  op_index = instruction->flags & REVERSE_MATCH ? 0 : 1;
	  if (instruction->operands[op_index].op_type == abs16)
	    a->constant |= 0xFFFF0000;
	}
      func (stream, "%s", "0x");
      number = (relative ? memaddr : 0)
	+ (sign_flag ? -a->constant : a->constant);
      (*info->print_address_func) (number, info);
      break;
    default:
      break;
    }
}

/* Print all the arguments of CURRINSN instruction.  */

static void
print_arguments (ins *currentInsn, bfd_vma memaddr, struct disassemble_info *info)
{
  int i;

  for (i = 0; i < currentInsn->nargs; i++)
    {
      processing_argument_number = i;

      print_arg (&currentInsn->arg[i], memaddr, info);

      if (i != currentInsn->nargs - 1)
	info->fprintf_func (info->stream, ", ");
    }
}

/* Build the instruction's arguments.  */

static void
make_instruction (void)
{
  int i;
  unsigned int shift;

  for (i = 0; i < currInsn.nargs; i++)
    {
      argument a;

      memset (&a, 0, sizeof (a));
      a.type = getargtype (instruction->operands[i].op_type);
      if (instruction->operands[i].op_type == cst4
	  || instruction->operands[i].op_type == rbase_dispu4)
	cst4flag = 1;
      a.size = getbits (instruction->operands[i].op_type);
      shift = instruction->operands[i].shift;

      make_argument (&a, shift);
      currInsn.arg[i] = a;
    }

  /* Calculate instruction size (in bytes).  */
  currInsn.size = instruction->size + (size_changed ? 1 : 0);
  /* Now in bits.  */
  currInsn.size *= 2;
}

/* Retrieve a single word from a given memory address.  */

static wordU
get_word_at_PC (bfd_vma memaddr, struct disassemble_info *info)
{
  bfd_byte buffer[4];
  int status;
  wordU insn = 0;

  status = info->read_memory_func (memaddr, buffer, 2, info);

  if (status == 0)
    insn = (wordU) bfd_getl16 (buffer);

  return insn;
}

/* Retrieve multiple words (3) from a given memory address.  */

static void
get_words_at_PC (bfd_vma memaddr, struct disassemble_info *info)
{
  int i;
  bfd_vma mem;

  for (i = 0, mem = memaddr; i < 3; i++, mem += 2)
    words[i] = get_word_at_PC (mem, info);

  allWords =
    ((ULONGLONG) words[0] << 32) + ((unsigned long) words[1] << 16) + words[2];
}

/* Prints the instruction by calling print_arguments after proper matching.  */

int
print_insn_crx (bfd_vma memaddr, struct disassemble_info *info)
{
  int is_decoded;     /* Nonzero means instruction has a match.  */

  /* Initialize global variables.  */
  cst4flag = 0;
  size_changed = 0;

  /* Retrieve the encoding from current memory location.  */
  get_words_at_PC (memaddr, info);
  /* Find a matching opcode in table.  */
  is_decoded = match_opcode ();
  /* If found, print the instruction's mnemonic and arguments.  */
  if (is_decoded > 0 && (words[0] != 0 || words[1] != 0))
    {
      info->fprintf_func (info->stream, "%s", instruction->mnemonic);
      if ((currInsn.nargs = get_number_of_operands ()) != 0)
	info->fprintf_func (info->stream, "\t");
      make_instruction ();
      print_arguments (&currInsn, memaddr, info);
      return currInsn.size;
    }

  /* No match found.  */
  info->fprintf_func (info->stream,"%s ",ILLEGAL);
  return 2;
}
