/* Disassembly routines for TMS320C30 architecture
   Copyright (C) 1998-2019 Free Software Foundation, Inc.
   Contributed by Steven Haworth (steve@pm.cse.rmit.edu.au)

   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 file; see the file COPYING.  If not, write to the
   Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */

#include "sysdep.h"
#include <errno.h>
#include <math.h>
#include "disassemble.h"
#include "opcode/tic30.h"

#define NORMAL_INSN   1
#define PARALLEL_INSN 2

/* Gets the type of instruction based on the top 2 or 3 bits of the
   instruction word.  */
#define GET_TYPE(insn) (insn & 0x80000000 ? insn & 0xC0000000 : insn & 0xE0000000)

/* Instruction types.  */
#define TWO_OPERAND_1 0x00000000
#define TWO_OPERAND_2 0x40000000
#define THREE_OPERAND 0x20000000
#define PAR_STORE     0xC0000000
#define MUL_ADDS      0x80000000
#define BRANCHES      0x60000000

/* Specific instruction id bits.  */
#define NORMAL_IDEN    0x1F800000
#define PAR_STORE_IDEN 0x3E000000
#define MUL_ADD_IDEN   0x2C000000
#define BR_IMM_IDEN    0x1F000000
#define BR_COND_IDEN   0x1C3F0000

/* Addressing modes.  */
#define AM_REGISTER 0x00000000
#define AM_DIRECT   0x00200000
#define AM_INDIRECT 0x00400000
#define AM_IMM      0x00600000

#define P_FIELD 0x03000000

#define REG_AR0 0x08
#define LDP_INSN 0x08700000

/* TMS320C30 program counter for current instruction.  */
static unsigned int _pc;

struct instruction
{
  int type;
  insn_template *tm;
  partemplate *ptm;
};

static int
get_tic30_instruction (unsigned long insn_word, struct instruction *insn)
{
  switch (GET_TYPE (insn_word))
    {
    case TWO_OPERAND_1:
    case TWO_OPERAND_2:
    case THREE_OPERAND:
      insn->type = NORMAL_INSN;
      {
	insn_template *current_optab = (insn_template *) tic30_optab;

	for (; current_optab < tic30_optab_end; current_optab++)
	  {
	    if (GET_TYPE (current_optab->base_opcode) == GET_TYPE (insn_word))
	      {
		if (current_optab->operands == 0)
		  {
		    if (current_optab->base_opcode == insn_word)
		      {
			insn->tm = current_optab;
			break;
		      }
		  }
		else if ((current_optab->base_opcode & NORMAL_IDEN) == (insn_word & NORMAL_IDEN))
		  {
		    insn->tm = current_optab;
		    break;
		  }
	      }
	  }
      }
      break;

    case PAR_STORE:
      insn->type = PARALLEL_INSN;
      {
	partemplate *current_optab = (partemplate *) tic30_paroptab;

	for (; current_optab < tic30_paroptab_end; current_optab++)
	  {
	    if (GET_TYPE (current_optab->base_opcode) == GET_TYPE (insn_word))
	      {
		if ((current_optab->base_opcode & PAR_STORE_IDEN)
		    == (insn_word & PAR_STORE_IDEN))
		  {
		    insn->ptm = current_optab;
		    break;
		  }
	      }
	  }
      }
      break;

    case MUL_ADDS:
      insn->type = PARALLEL_INSN;
      {
	partemplate *current_optab = (partemplate *) tic30_paroptab;

	for (; current_optab < tic30_paroptab_end; current_optab++)
	  {
	    if (GET_TYPE (current_optab->base_opcode) == GET_TYPE (insn_word))
	      {
		if ((current_optab->base_opcode & MUL_ADD_IDEN)
		    == (insn_word & MUL_ADD_IDEN))
		  {
		    insn->ptm = current_optab;
		    break;
		  }
	      }
	  }
      }
      break;

    case BRANCHES:
      insn->type = NORMAL_INSN;
      {
	insn_template *current_optab = (insn_template *) tic30_optab;

	for (; current_optab < tic30_optab_end; current_optab++)
	  {
	    if (GET_TYPE (current_optab->base_opcode) == GET_TYPE (insn_word))
	      {
		if (current_optab->operand_types[0] & Imm24)
		  {
		    if ((current_optab->base_opcode & BR_IMM_IDEN)
			== (insn_word & BR_IMM_IDEN))
		      {
			insn->tm = current_optab;
			break;
		      }
		  }
		else if (current_optab->operands > 0)
		  {
		    if ((current_optab->base_opcode & BR_COND_IDEN)
			== (insn_word & BR_COND_IDEN))
		      {
			insn->tm = current_optab;
			break;
		      }
		  }
		else
		  {
		    if ((current_optab->base_opcode & (BR_COND_IDEN | 0x00800000))
			== (insn_word & (BR_COND_IDEN | 0x00800000)))
		      {
			insn->tm = current_optab;
			break;
		      }
		  }
	      }
	  }
      }
      break;
    default:
      return 0;
    }
  return 1;
}

#define OPERAND_BUFFER_LEN 15

static int
get_register_operand (unsigned char fragment, char *buffer)
{
  const reg *current_reg = tic30_regtab;

  if (buffer == NULL)
    return 0;
  for (; current_reg < tic30_regtab_end; current_reg++)
    {
      if ((fragment & 0x1F) == current_reg->opcode)
	{
	  strncpy (buffer, current_reg->name, OPERAND_BUFFER_LEN);
	  buffer[OPERAND_BUFFER_LEN - 1] = 0;
	  return 1;
	}
    }
  return 0;
}

static int
get_indirect_operand (unsigned short fragment,
		      int size,
		      char *buffer)
{
  unsigned char mod;
  unsigned arnum;
  unsigned char disp;

  if (buffer == NULL)
    return 0;
  /* Determine which bits identify the sections of the indirect
     operand based on the size in bytes.  */
  switch (size)
    {
    case 1:
      mod = (fragment & 0x00F8) >> 3;
      arnum = (fragment & 0x0007);
      disp = 0;
      break;
    case 2:
      mod = (fragment & 0xF800) >> 11;
      arnum = (fragment & 0x0700) >> 8;
      disp = (fragment & 0x00FF);
      break;
    default:
      return 0;
    }
  {
    const ind_addr_type *current_ind = tic30_indaddr_tab;

    for (; current_ind < tic30_indaddrtab_end; current_ind++)
      {
	if (current_ind->modfield == mod)
	  {
	    if (current_ind->displacement == IMPLIED_DISP && size == 2)
	      continue;

	    else
	      {
		size_t i, len;
		int bufcnt;

		len = strlen (current_ind->syntax);

		for (i = 0, bufcnt = 0; i < len; i++, bufcnt++)
		  {
		    buffer[bufcnt] = current_ind->syntax[i];

		    if (bufcnt > 0
			&& bufcnt < OPERAND_BUFFER_LEN - 1
			&& buffer[bufcnt - 1] == 'a'
			&& buffer[bufcnt] == 'r')
		      buffer[++bufcnt] = arnum + '0';
		    
		    if (bufcnt < OPERAND_BUFFER_LEN - 1
			&& buffer[bufcnt] == '('
			&& current_ind->displacement == DISP_REQUIRED)
		      {
			snprintf (buffer + (bufcnt + 1),
				 OPERAND_BUFFER_LEN - (bufcnt + 1),
				 "%u", disp);
			bufcnt += strlen (buffer + (bufcnt + 1));
		      }
		  }
		buffer[bufcnt + 1] = '\0';
		break;
	      }
	  }
      }
  }
  return 1;
}

static int
cnvt_tmsfloat_ieee (unsigned long tmsfloat, int size, float *ieeefloat)
{
  unsigned long exponent, sign, mant;
  union
  {
    unsigned long l;
    float f;
  } val;

  if (size == 2)
    {
      if ((tmsfloat & 0x0000F000) == 0x00008000)
	tmsfloat = 0x80000000;
      else
	{
	  tmsfloat <<= 16;
	  tmsfloat = (long) tmsfloat >> 4;
	}
    }
  exponent = tmsfloat & 0xFF000000;
  if (exponent == 0x80000000)
    {
      *ieeefloat = 0.0;
      return 1;
    }
  exponent += 0x7F000000;
  sign = (tmsfloat & 0x00800000) << 8;
  mant = tmsfloat & 0x007FFFFF;
  if (exponent == 0xFF000000)
    {
      if (mant == 0)
	*ieeefloat = ERANGE;
#ifdef HUGE_VALF
      if (sign == 0)
	*ieeefloat = HUGE_VALF;
      else
	*ieeefloat = -HUGE_VALF;
#else
      if (sign == 0)
	*ieeefloat = 1.0 / 0.0;
      else
	*ieeefloat = -1.0 / 0.0;
#endif
      return 1;
    }
  exponent >>= 1;
  if (sign)
    {
      mant = (~mant) & 0x007FFFFF;
      mant += 1;
      exponent += mant & 0x00800000;
      exponent &= 0x7F800000;
      mant &= 0x007FFFFF;
    }
  if (tmsfloat == 0x80000000)
    sign = mant = exponent = 0;
  tmsfloat = sign | exponent | mant;
  val.l = tmsfloat;
  *ieeefloat = val.f;
  return 1;
}

static int
print_two_operand (disassemble_info *info,
		   unsigned long insn_word,
		   struct instruction *insn)
{
  char name[12];
  char operand[2][OPERAND_BUFFER_LEN] =
  {
    {0},
    {0}
  };
  float f_number;

  if (insn->tm == NULL)
    return 0;
  strcpy (name, insn->tm->name);
  if (insn->tm->opcode_modifier == AddressMode)
    {
      int src_op, dest_op;
      /* Determine whether instruction is a store or a normal instruction.  */
      if ((insn->tm->operand_types[1] & (Direct | Indirect))
	  == (Direct | Indirect))
	{
	  src_op = 1;
	  dest_op = 0;
	}
      else
	{
	  src_op = 0;
	  dest_op = 1;
	}
      /* Get the destination register.  */
      if (insn->tm->operands == 2)
	get_register_operand ((insn_word & 0x001F0000) >> 16, operand[dest_op]);
      /* Get the source operand based on addressing mode.  */
      switch (insn_word & AddressMode)
	{
	case AM_REGISTER:
	  /* Check for the NOP instruction before getting the operand.  */
	  if ((insn->tm->operand_types[0] & NotReq) == 0)
	    get_register_operand ((insn_word & 0x0000001F), operand[src_op]);
	  break;
	case AM_DIRECT:
	  sprintf (operand[src_op], "@0x%lX", (insn_word & 0x0000FFFF));
	  break;
	case AM_INDIRECT:
	  get_indirect_operand ((insn_word & 0x0000FFFF), 2, operand[src_op]);
	  break;
	case AM_IMM:
	  /* Get the value of the immediate operand based on variable type.  */
	  switch (insn->tm->imm_arg_type)
	    {
	    case Imm_Float:
	      cnvt_tmsfloat_ieee ((insn_word & 0x0000FFFF), 2, &f_number);
	      sprintf (operand[src_op], "%2.2f", f_number);
	      break;
	    case Imm_SInt:
	      sprintf (operand[src_op], "%d", (short) (insn_word & 0x0000FFFF));
	      break;
	    case Imm_UInt:
	      sprintf (operand[src_op], "%lu", (insn_word & 0x0000FFFF));
	      break;
	    default:
	      return 0;
	    }
	  /* Handle special case for LDP instruction.  */
	  if ((insn_word & 0xFFFFFF00) == LDP_INSN)
	    {
	      strcpy (name, "ldp");
	      sprintf (operand[0], "0x%06lX", (insn_word & 0x000000FF) << 16);
	      operand[1][0] = '\0';
	    }
	}
    }
  /* Handle case for stack and rotate instructions.  */
  else if (insn->tm->operands == 1)
    {
      if (insn->tm->opcode_modifier == StackOp)
	get_register_operand ((insn_word & 0x001F0000) >> 16, operand[0]);
    }
  /* Output instruction to stream.  */
  info->fprintf_func (info->stream, "   %s %s%c%s", name,
		      operand[0][0] ? operand[0] : "",
		      operand[1][0] ? ',' : ' ',
		      operand[1][0] ? operand[1] : "");
  return 1;
}

static int
print_three_operand (disassemble_info *info,
		     unsigned long insn_word,
		     struct instruction *insn)
{
  char operand[3][OPERAND_BUFFER_LEN] =
  {
    {0},
    {0},
    {0}
  };

  if (insn->tm == NULL)
    return 0;
  switch (insn_word & AddressMode)
    {
    case AM_REGISTER:
      get_register_operand ((insn_word & 0x000000FF), operand[0]);
      get_register_operand ((insn_word & 0x0000FF00) >> 8, operand[1]);
      break;
    case AM_DIRECT:
      get_register_operand ((insn_word & 0x000000FF), operand[0]);
      get_indirect_operand ((insn_word & 0x0000FF00) >> 8, 1, operand[1]);
      break;
    case AM_INDIRECT:
      get_indirect_operand ((insn_word & 0x000000FF), 1, operand[0]);
      get_register_operand ((insn_word & 0x0000FF00) >> 8, operand[1]);
      break;
    case AM_IMM:
      get_indirect_operand ((insn_word & 0x000000FF), 1, operand[0]);
      get_indirect_operand ((insn_word & 0x0000FF00) >> 8, 1, operand[1]);
      break;
    default:
      return 0;
    }
  if (insn->tm->operands == 3)
    get_register_operand ((insn_word & 0x001F0000) >> 16, operand[2]);
  info->fprintf_func (info->stream, "   %s %s,%s%c%s", insn->tm->name,
		      operand[0], operand[1],
		      operand[2][0] ? ',' : ' ',
		      operand[2][0] ? operand[2] : "");
  return 1;
}

static int
print_par_insn (disassemble_info *info,
		unsigned long insn_word,
		struct instruction *insn)
{
  size_t i, len;
  char *name1, *name2;
  char operand[2][3][OPERAND_BUFFER_LEN] =
  {
    {
      {0},
      {0},
      {0}
    },
    {
      {0},
      {0},
      {0}
    }
  };

  if (insn->ptm == NULL)
    return 0;
  /* Parse out the names of each of the parallel instructions from the
     q_insn1_insn2 format.  */
  name1 = (char *) strdup (insn->ptm->name + 2);
  name2 = "";
  len = strlen (name1);
  for (i = 0; i < len; i++)
    {
      if (name1[i] == '_')
	{
	  name2 = &name1[i + 1];
	  name1[i] = '\0';
	  break;
	}
    }
  /* Get the operands of the instruction based on the operand order.  */
  switch (insn->ptm->oporder)
    {
    case OO_4op1:
      get_indirect_operand ((insn_word & 0x000000FF), 1, operand[0][0]);
      get_indirect_operand ((insn_word & 0x0000FF00) >> 8, 1, operand[1][1]);
      get_register_operand ((insn_word >> 16) & 0x07, operand[1][0]);
      get_register_operand ((insn_word >> 22) & 0x07, operand[0][1]);
      break;
    case OO_4op2:
      get_indirect_operand ((insn_word & 0x000000FF), 1, operand[0][0]);
      get_indirect_operand ((insn_word & 0x0000FF00) >> 8, 1, operand[1][0]);
      get_register_operand ((insn_word >> 19) & 0x07, operand[1][1]);
      get_register_operand ((insn_word >> 22) & 0x07, operand[0][1]);
      break;
    case OO_4op3:
      get_indirect_operand ((insn_word & 0x000000FF), 1, operand[0][1]);
      get_indirect_operand ((insn_word & 0x0000FF00) >> 8, 1, operand[1][1]);
      get_register_operand ((insn_word >> 16) & 0x07, operand[1][0]);
      get_register_operand ((insn_word >> 22) & 0x07, operand[0][0]);
      break;
    case OO_5op1:
      get_indirect_operand ((insn_word & 0x000000FF), 1, operand[0][0]);
      get_indirect_operand ((insn_word & 0x0000FF00) >> 8, 1, operand[1][1]);
      get_register_operand ((insn_word >> 16) & 0x07, operand[1][0]);
      get_register_operand ((insn_word >> 19) & 0x07, operand[0][1]);
      get_register_operand ((insn_word >> 22) & 0x07, operand[0][2]);
      break;
    case OO_5op2:
      get_indirect_operand ((insn_word & 0x000000FF), 1, operand[0][1]);
      get_indirect_operand ((insn_word & 0x0000FF00) >> 8, 1, operand[1][1]);
      get_register_operand ((insn_word >> 16) & 0x07, operand[1][0]);
      get_register_operand ((insn_word >> 19) & 0x07, operand[0][0]);
      get_register_operand ((insn_word >> 22) & 0x07, operand[0][2]);
      break;
    case OO_PField:
      if (insn_word & 0x00800000)
	get_register_operand (0x01, operand[0][2]);
      else
	get_register_operand (0x00, operand[0][2]);
      if (insn_word & 0x00400000)
	get_register_operand (0x03, operand[1][2]);
      else
	get_register_operand (0x02, operand[1][2]);
      switch (insn_word & P_FIELD)
	{
	case 0x00000000:
	  get_indirect_operand ((insn_word & 0x000000FF), 1, operand[0][1]);
	  get_indirect_operand ((insn_word & 0x0000FF00) >> 8, 1, operand[0][0]);
	  get_register_operand ((insn_word >> 16) & 0x07, operand[1][1]);
	  get_register_operand ((insn_word >> 19) & 0x07, operand[1][0]);
	  break;
	case 0x01000000:
	  get_indirect_operand ((insn_word & 0x000000FF), 1, operand[1][0]);
	  get_indirect_operand ((insn_word & 0x0000FF00) >> 8, 1, operand[0][0]);
	  get_register_operand ((insn_word >> 16) & 0x07, operand[1][1]);
	  get_register_operand ((insn_word >> 19) & 0x07, operand[0][1]);
	  break;
	case 0x02000000:
	  get_indirect_operand ((insn_word & 0x000000FF), 1, operand[1][1]);
	  get_indirect_operand ((insn_word & 0x0000FF00) >> 8, 1, operand[1][0]);
	  get_register_operand ((insn_word >> 16) & 0x07, operand[0][1]);
	  get_register_operand ((insn_word >> 19) & 0x07, operand[0][0]);
	  break;
	case 0x03000000:
	  get_indirect_operand ((insn_word & 0x000000FF), 1, operand[1][1]);
	  get_indirect_operand ((insn_word & 0x0000FF00) >> 8, 1, operand[0][0]);
	  get_register_operand ((insn_word >> 16) & 0x07, operand[1][0]);
	  get_register_operand ((insn_word >> 19) & 0x07, operand[0][1]);
	  break;
	}
      break;
    default:
      return 0;
    }
  info->fprintf_func (info->stream, "   %s %s,%s%c%s", name1,
		      operand[0][0], operand[0][1],
		      operand[0][2][0] ? ',' : ' ',
		      operand[0][2][0] ? operand[0][2] : "");
  info->fprintf_func (info->stream, "\n\t\t\t|| %s %s,%s%c%s", name2,
		      operand[1][0], operand[1][1],
		      operand[1][2][0] ? ',' : ' ',
		      operand[1][2][0] ? operand[1][2] : "");
  free (name1);
  return 1;
}

static int
print_branch (disassemble_info *info,
	      unsigned long insn_word,
	      struct instruction *insn)
{
  char operand[2][OPERAND_BUFFER_LEN] =
  {
    {0},
    {0}
  };
  unsigned long address;
  int print_label = 0;

  if (insn->tm == NULL)
    return 0;
  /* Get the operands for 24-bit immediate jumps.  */
  if (insn->tm->operand_types[0] & Imm24)
    {
      address = insn_word & 0x00FFFFFF;
      sprintf (operand[0], "0x%lX", address);
      print_label = 1;
    }
  /* Get the operand for the trap instruction.  */
  else if (insn->tm->operand_types[0] & IVector)
    {
      address = insn_word & 0x0000001F;
      sprintf (operand[0], "0x%lX", address);
    }
  else
    {
      address = insn_word & 0x0000FFFF;
      /* Get the operands for the DB instructions.  */
      if (insn->tm->operands == 2)
	{
	  get_register_operand (((insn_word & 0x01C00000) >> 22) + REG_AR0, operand[0]);
	  if (insn_word & PCRel)
	    {
	      sprintf (operand[1], "%d", (short) address);
	      print_label = 1;
	    }
	  else
	    get_register_operand (insn_word & 0x0000001F, operand[1]);
	}
      /* Get the operands for the standard branches.  */
      else if (insn->tm->operands == 1)
	{
	  if (insn_word & PCRel)
	    {
	      address = (short) address;
	      sprintf (operand[0], "%ld", address);
	      print_label = 1;
	    }
	  else
	    get_register_operand (insn_word & 0x0000001F, operand[0]);
	}
    }
  info->fprintf_func (info->stream, "   %s %s%c%s", insn->tm->name,
		      operand[0][0] ? operand[0] : "",
		      operand[1][0] ? ',' : ' ',
		      operand[1][0] ? operand[1] : "");
  /* Print destination of branch in relation to current symbol.  */
  if (print_label && info->symbols)
    {
      asymbol *sym = *info->symbols;

      if ((insn->tm->opcode_modifier == PCRel) && (insn_word & PCRel))
	{
	  address = (_pc + 1 + (short) address) - ((sym->section->vma + sym->value) / 4);
	  /* Check for delayed instruction, if so adjust destination.  */
	  if (insn_word & 0x00200000)
	    address += 2;
	}
      else
	{
	  address -= ((sym->section->vma + sym->value) / 4);
	}
      if (address == 0)
	info->fprintf_func (info->stream, " <%s>", sym->name);
      else
	info->fprintf_func (info->stream, " <%s %c %lu>", sym->name,
			    ((short) address < 0) ? '-' : '+',
			    address);
    }
  return 1;
}

int
print_insn_tic30 (bfd_vma pc, disassemble_info *info)
{
  unsigned long insn_word;
  struct instruction insn = { 0, NULL, NULL };
  bfd_vma bufaddr = pc - info->buffer_vma;

  /* Obtain the current instruction word from the buffer.  */
  insn_word = (*(info->buffer + bufaddr) << 24) | (*(info->buffer + bufaddr + 1) << 16) |
    (*(info->buffer + bufaddr + 2) << 8) | *(info->buffer + bufaddr + 3);
  _pc = pc / 4;
  /* Get the instruction refered to by the current instruction word
     and print it out based on its type.  */
  if (!get_tic30_instruction (insn_word, &insn))
    return -1;
  switch (GET_TYPE (insn_word))
    {
    case TWO_OPERAND_1:
    case TWO_OPERAND_2:
      if (!print_two_operand (info, insn_word, &insn))
	return -1;
      break;
    case THREE_OPERAND:
      if (!print_three_operand (info, insn_word, &insn))
	return -1;
      break;
    case PAR_STORE:
    case MUL_ADDS:
      if (!print_par_insn (info, insn_word, &insn))
	return -1;
      break;
    case BRANCHES:
      if (!print_branch (info, insn_word, &insn))
	return -1;
      break;
    }
  return 4;
}
