/* Disassembler code for CRX.
   Copyright 2004, 2005, 2006, 2007 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 "dis-asm.h"
#include "sysdep.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)	    \
  (n_bits == 32 ? (((a) >> (offs)) & 0xffffffffL)   \
  : (((a) >> (offs)) & ((1 << (n_bits)) -1)))

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

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

static int get_number_of_operands (void);
static argtype getargtype     (operand_type);
static int getbits	      (operand_type);
static char *getregname	      (reg);
static char *getcopregname    (copreg, reg_type);
static char * getprocregname  (int);
static char *gettrapstring    (unsigned);
static char *getcinvstring    (unsigned);
static void getregliststring  (int, char *, enum REG_ARG_TYPE);
static wordU get_word_at_PC   (bfd_vma, struct disassemble_info *);
static void get_words_at_PC   (bfd_vma, struct disassemble_info *);
static unsigned long build_mask (void);
static int powerof2	      (int);
static int match_opcode	      (void);
static void make_instruction  (void);
static void print_arguments   (ins *, bfd_vma, struct disassemble_info *);
static void print_arg	      (argument *, bfd_vma, struct disassemble_info *);

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

static int
get_number_of_operands (void)
{
  int i;

  for (i = 0; instruction->operands[i].op_type && i < MAX_OPERANDS; 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.  */

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

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

void
getregliststring (int mask, char *string, enum REG_ARG_TYPE core_cop)
{
  char temp_string[5];
  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 long
build_mask (void)
{
  unsigned int print_flags;
  unsigned long 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 long mask;

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

  /* 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)
{
  LONGLONG longdisp, mask;
  int sign_flag = 0;
  int relative = 0;
  bfd_vma number;
  int op_index = 0;
  char string[200];
  PTR 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);
	    }
	  else
            {
              getregliststring (a->constant, string, reg_arg_type);
              func (stream, "%s", string);
            }
        }
      else
	func (stream, "$0x%lx", a->constant);
      break;

    case arg_idxr:
      func (stream, "0x%lx(%s,%s,%d)", a->constant, 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, 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 & ((LONGLONG)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 (memaddr, info)
     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] << 16 || 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;
}
