/* TI PRU disassemble routines
   Copyright (C) 2014-2021 Free Software Foundation, Inc.
   Contributed by Dimitar Dimitrov <dimitar@dinux.eu>

   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 "disassemble.h"
#include "opcode/pru.h"
#include "libiberty.h"
#include <string.h>
#include <assert.h>

/* No symbol table is available when this code runs out in an embedded
   system as when it is used for disassembler support in a monitor.  */
#if !defined (EMBEDDED_ENV)
#define SYMTAB_AVAILABLE 1
#include "elf-bfd.h"
#include "elf/pru.h"
#endif

/* Length of PRU instruction in bytes.  */
#define INSNLEN 4

/* Return a pointer to an pru_opcode struct for a given instruction
   opcode, or NULL if there is an error.  */
const struct pru_opcode *
pru_find_opcode (unsigned long opcode)
{
  const struct pru_opcode *p;
  const struct pru_opcode *op = NULL;
  const struct pru_opcode *pseudo_op = NULL;

  for (p = pru_opcodes; p < &pru_opcodes[NUMOPCODES]; p++)
    {
      if ((p->mask & opcode) == p->match)
	{
	  if ((p->pinfo & PRU_INSN_MACRO) == PRU_INSN_MACRO)
	    pseudo_op = p;
	  else if ((p->pinfo & PRU_INSN_LDI32) == PRU_INSN_LDI32)
	    /* ignore - should be caught with regular patterns */;
	  else
	    op = p;
	}
    }

  return pseudo_op ? pseudo_op : op;
}

/* There are 32 regular registers, each with 8 possible subfield selectors.  */
#define NUMREGNAMES (32 * 8)

static void
pru_print_insn_arg_reg (unsigned int r, unsigned int sel,
			disassemble_info *info)
{
  unsigned int i = r * RSEL_NUM_ITEMS + sel;
  assert (i < (unsigned int)pru_num_regs);
  assert (i < NUMREGNAMES);
  (*info->fprintf_func) (info->stream, "%s", pru_regs[i].name);
}

/* The function pru_print_insn_arg uses the character pointed
   to by ARGPTR to determine how it print the next token or separator
   character in the arguments to an instruction.  */
static int
pru_print_insn_arg (const char *argptr,
		      unsigned long opcode, bfd_vma address,
		      disassemble_info *info)
{
  long offs = 0;
  unsigned long i = 0;
  unsigned long io = 0;

  switch (*argptr)
    {
    case ',':
      (*info->fprintf_func) (info->stream, "%c ", *argptr);
      break;
    case 'd':
      pru_print_insn_arg_reg (GET_INSN_FIELD (RD, opcode),
			      GET_INSN_FIELD (RDSEL, opcode),
			      info);
      break;
    case 'D':
      /* The first 4 values for RDB and RSEL are the same, so we
	 can reuse some code.  */
      pru_print_insn_arg_reg (GET_INSN_FIELD (RD, opcode),
			      GET_INSN_FIELD (RDB, opcode),
			      info);
      break;
    case 's':
      pru_print_insn_arg_reg (GET_INSN_FIELD (RS1, opcode),
			      GET_INSN_FIELD (RS1SEL, opcode),
			      info);
      break;
    case 'S':
      pru_print_insn_arg_reg (GET_INSN_FIELD (RS1, opcode),
			      RSEL_31_0,
			      info);
      break;
    case 'b':
      io = GET_INSN_FIELD (IO, opcode);

      if (io)
	{
	  i = GET_INSN_FIELD (IMM8, opcode);
	  (*info->fprintf_func) (info->stream, "%ld", i);
	}
      else
	{
	pru_print_insn_arg_reg (GET_INSN_FIELD (RS2, opcode),
				GET_INSN_FIELD (RS2SEL, opcode),
				info);
	}
      break;
    case 'B':
      io = GET_INSN_FIELD (IO, opcode);

      if (io)
	{
	  i = GET_INSN_FIELD (IMM8, opcode) + 1;
	  (*info->fprintf_func) (info->stream, "%ld", i);
	}
      else
	{
	pru_print_insn_arg_reg (GET_INSN_FIELD (RS2, opcode),
				GET_INSN_FIELD (RS2SEL, opcode),
				info);
	}
      break;
    case 'j':
      io = GET_INSN_FIELD (IO, opcode);

      if (io)
	{
	  /* For the sake of pretty-printing, dump text addresses with
	     their "virtual" offset that we use for distinguishing
	     PMEM vs DMEM. This is needed for printing the correct text
	     labels.  */
	  bfd_vma text_offset = address & ~0x3fffff;
	  i = GET_INSN_FIELD (IMM16, opcode) * 4;
	  (*info->print_address_func) (i + text_offset, info);
	}
      else
	{
	  pru_print_insn_arg_reg (GET_INSN_FIELD (RS2, opcode),
				GET_INSN_FIELD (RS2SEL, opcode),
				info);
	}
      break;
    case 'W':
      i = GET_INSN_FIELD (IMM16, opcode);
      (*info->fprintf_func) (info->stream, "%ld", i);
      break;
    case 'o':
      offs = GET_BROFF_SIGNED (opcode) * 4;
      (*info->print_address_func) (address + offs, info);
      break;
    case 'O':
      offs = GET_INSN_FIELD (LOOP_JMPOFFS, opcode) * 4;
      (*info->print_address_func) (address + offs, info);
      break;
    case 'l':
      i = GET_BURSTLEN (opcode);
      if (i < LSSBBO_BYTECOUNT_R0_BITS7_0)
	(*info->fprintf_func) (info->stream, "%ld", i + 1);
      else
	{
	  i -= LSSBBO_BYTECOUNT_R0_BITS7_0;
	  (*info->fprintf_func) (info->stream, "r0.b%ld", i);
	}
      break;
    case 'n':
      i = GET_INSN_FIELD (XFR_LENGTH, opcode);
      if (i < LSSBBO_BYTECOUNT_R0_BITS7_0)
	(*info->fprintf_func) (info->stream, "%ld", i + 1);
      else
	{
	  i -= LSSBBO_BYTECOUNT_R0_BITS7_0;
	  (*info->fprintf_func) (info->stream, "r0.b%ld", i);
	}
      break;
    case 'c':
      i = GET_INSN_FIELD (CB, opcode);
      (*info->fprintf_func) (info->stream, "%ld", i);
      break;
    case 'w':
      i = GET_INSN_FIELD (WAKEONSTATUS, opcode);
      (*info->fprintf_func) (info->stream, "%ld", i);
      break;
    case 'x':
      i = GET_INSN_FIELD (XFR_WBA, opcode);
      (*info->fprintf_func) (info->stream, "%ld", i);
      break;
    default:
      (*info->fprintf_func) (info->stream, "unknown");
      break;
    }
  return 0;
}

/* pru_disassemble does all the work of disassembling a PRU
   instruction opcode.  */
static int
pru_disassemble (bfd_vma address, unsigned long opcode,
		   disassemble_info *info)
{
  const struct pru_opcode *op;

  info->bytes_per_line = INSNLEN;
  info->bytes_per_chunk = INSNLEN;
  info->display_endian = info->endian;
  info->insn_info_valid = 1;
  info->branch_delay_insns = 0;
  info->data_size = 0;
  info->insn_type = dis_nonbranch;
  info->target = 0;
  info->target2 = 0;

  /* Find the major opcode and use this to disassemble
     the instruction and its arguments.  */
  op = pru_find_opcode (opcode);

  if (op != NULL)
    {
      (*info->fprintf_func) (info->stream, "%s", op->name);

      const char *argstr = op->args;
      if (argstr != NULL && *argstr != '\0')
	{
	  (*info->fprintf_func) (info->stream, "\t");
	  while (*argstr != '\0')
	    {
	      pru_print_insn_arg (argstr, opcode, address, info);
	      ++argstr;
	    }
	}
    }
  else
    {
      /* Handle undefined instructions.  */
      info->insn_type = dis_noninsn;
      (*info->fprintf_func) (info->stream, "0x%lx", opcode);
    }
  /* Tell the caller how far to advance the program counter.  */
  return INSNLEN;
}


/* print_insn_pru is the main disassemble function for PRU.  */
int
print_insn_pru (bfd_vma address, disassemble_info *info)
{
  bfd_byte buffer[INSNLEN];
  int status;

  status = (*info->read_memory_func) (address, buffer, INSNLEN, info);
  if (status == 0)
    {
      unsigned long insn;
      insn = (unsigned long) bfd_getl32 (buffer);
      status = pru_disassemble (address, insn, info);
    }
  else
    {
      (*info->memory_error_func) (status, address, info);
      status = -1;
    }
  return status;
}
