/* Disassemble Xilinx microblaze instructions.

   Copyright (C) 2009-2024 Free Software Foundation, Inc.

   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"
#define STATIC_TABLE
#define DEFINE_TABLE

#include "disassemble.h"
#include <strings.h>
#include "microblaze-opc.h"
#include "microblaze-dis.h"

#define get_field_rd(buf, instr)   get_field (buf, instr, RD_MASK, RD_LOW)
#define get_field_r1(buf, instr)   get_field (buf, instr, RA_MASK, RA_LOW)
#define get_field_r2(buf, instr)   get_field (buf, instr, RB_MASK, RB_LOW)
#define get_int_field_imm(instr)   ((instr & IMM_MASK) >> IMM_LOW)
#define get_int_field_r1(instr)    ((instr & RA_MASK) >> RA_LOW)

#define NUM_STRBUFS 4
#define STRBUF_SIZE 25

struct string_buf
{
  unsigned int which;
  char str[NUM_STRBUFS][STRBUF_SIZE];
};

static inline char *
strbuf (struct string_buf *buf)
{
#ifdef ENABLE_CHECKING
  if (buf->which >= NUM_STRBUFS)
    abort ();
#endif
  return buf->str[buf->which++];
}

static char *
get_field (struct string_buf *buf, long instr, long mask, unsigned short low)
{
  char *p = strbuf (buf);

  sprintf (p, "%s%d", register_prefix, (int)((instr & mask) >> low));
  return p;
}

static char *
get_field_imm (struct string_buf *buf, long instr)
{
  char *p = strbuf (buf);

  sprintf (p, "%d", (short)((instr & IMM_MASK) >> IMM_LOW));
  return p;
}

static char *
get_field_imm5 (struct string_buf *buf, long instr)
{
  char *p = strbuf (buf);

  sprintf (p, "%d", (short)((instr & IMM5_MASK) >> IMM_LOW));
  return p;
}

static char *
get_field_imm5_mbar (struct string_buf *buf, long instr)
{
  char *p = strbuf (buf);

  sprintf (p, "%d", (short)((instr & IMM5_MBAR_MASK) >> IMM_MBAR));
  return p;
}

static char *
get_field_immw (struct string_buf *buf, long instr)
{
  char *p = strbuf (buf);

  if (instr & 0x00004000)
    sprintf (p, "%d", (short)(((instr & IMM5_WIDTH_MASK)
				>> IMM_WIDTH_LOW))); /* bsefi */
  else
    sprintf (p, "%d", (short)(((instr & IMM5_WIDTH_MASK) >>
				IMM_WIDTH_LOW) - ((instr & IMM5_MASK) >>
				IMM_LOW) + 1)); /* bsifi */
  return p;
}

static char *
get_field_rfsl (struct string_buf *buf, long instr)
{
  char *p = strbuf (buf);

  sprintf (p, "%s%d", fsl_register_prefix,
	   (short)((instr & RFSL_MASK) >> IMM_LOW));
  return p;
}

static char *
get_field_imm15 (struct string_buf *buf, long instr)
{
  char *p = strbuf (buf);

  sprintf (p, "%d", (short)((instr & IMM15_MASK) >> IMM_LOW));
  return p;
}

static char *
get_field_special (struct string_buf *buf, long instr,
		   const struct op_code_struct *op)
{
  char *p = strbuf (buf);
  char *spr;

  switch ((((instr & IMM_MASK) >> IMM_LOW) ^ op->immval_mask))
    {
    case REG_MSR_MASK :
      spr = "msr";
      break;
    case REG_PC_MASK :
      spr = "pc";
      break;
    case REG_EAR_MASK :
      spr = "ear";
      break;
    case REG_ESR_MASK :
      spr = "esr";
      break;
    case REG_FSR_MASK :
      spr = "fsr";
      break;
    case REG_BTR_MASK :
      spr = "btr";
      break;
    case REG_EDR_MASK :
      spr = "edr";
      break;
    case REG_PID_MASK :
      spr = "pid";
      break;
    case REG_ZPR_MASK :
      spr = "zpr";
      break;
    case REG_TLBX_MASK :
      spr = "tlbx";
      break;
    case REG_TLBLO_MASK :
      spr = "tlblo";
      break;
    case REG_TLBHI_MASK :
      spr = "tlbhi";
      break;
    case REG_TLBSX_MASK :
      spr = "tlbsx";
      break;
    case REG_SHR_MASK :
      spr = "shr";
      break;
    case REG_SLR_MASK :
      spr = "slr";
      break;
    default :
      if (((((instr & IMM_MASK) >> IMM_LOW) ^ op->immval_mask) & 0xE000)
	  == REG_PVR_MASK)
	{
	  sprintf (p, "%spvr%d", register_prefix,
		   (unsigned short)(((instr & IMM_MASK) >> IMM_LOW)
				    ^ op->immval_mask) ^ REG_PVR_MASK);
	  return p;
	}
      else
	spr = "pc";
      break;
    }

   sprintf (p, "%s%s", register_prefix, spr);
   return p;
}

static unsigned long
read_insn_microblaze (bfd_vma memaddr,
		      struct disassemble_info *info,
		      const struct op_code_struct **opr)
{
  unsigned char       ibytes[4];
  int                 status;
  const struct op_code_struct *op;
  unsigned long inst;

  status = info->read_memory_func (memaddr, ibytes, 4, info);

  if (status != 0)
    {
      info->memory_error_func (status, memaddr, info);
      return 0;
    }

  if (info->endian == BFD_ENDIAN_BIG)
    inst = (((unsigned) ibytes[0] << 24) | (ibytes[1] << 16)
	    | (ibytes[2] << 8) | ibytes[3]);
  else if (info->endian == BFD_ENDIAN_LITTLE)
    inst = (((unsigned) ibytes[3] << 24) | (ibytes[2] << 16)
	    | (ibytes[1] << 8) | ibytes[0]);
  else
    abort ();

  /* Just a linear search of the table.  */
  for (op = microblaze_opcodes; op->name != 0; op ++)
    if (op->bit_sequence == (inst & op->opcode_mask))
      break;

  *opr = op;
  return inst;
}


int
print_insn_microblaze (bfd_vma memaddr, struct disassemble_info * info)
{
  fprintf_ftype print_func = info->fprintf_func;
  void *stream = info->stream;
  unsigned long inst, prev_inst;
  const struct op_code_struct *op, *pop;
  int immval = 0;
  bool immfound = false;
  static bfd_vma prev_insn_addr = -1;	/* Init the prev insn addr.  */
  static int prev_insn_vma = -1;	/* Init the prev insn vma.  */
  int curr_insn_vma = info->buffer_vma;
  struct string_buf buf;

  buf.which = 0;
  info->bytes_per_chunk = 4;

  inst = read_insn_microblaze (memaddr, info, &op);
  if (inst == 0)
    return -1;

  if (prev_insn_vma == curr_insn_vma)
    {
      if (memaddr-(info->bytes_per_chunk) == prev_insn_addr)
	{
	  prev_inst = read_insn_microblaze (prev_insn_addr, info, &pop);
	  if (prev_inst == 0)
	    return -1;
	  if (pop->instr == imm)
	    {
	      immval = (get_int_field_imm (prev_inst) << 16) & 0xffff0000;
	      immfound = true;
	    }
	  else
	    {
	      immval = 0;
	      immfound = false;
	    }
	}
    }

  /* Make curr insn as prev insn.  */
  prev_insn_addr = memaddr;
  prev_insn_vma = curr_insn_vma;

  if (op->name == NULL)
    print_func (stream, ".long 0x%04x", (unsigned int) inst);
  else
    {
      print_func (stream, "%s", op->name);

      switch (op->inst_type)
	{
	case INST_TYPE_RD_R1_R2:
	  print_func (stream, "\t%s, %s, %s", get_field_rd (&buf, inst),
		      get_field_r1 (&buf, inst), get_field_r2 (&buf, inst));
	  break;
	case INST_TYPE_RD_R1_IMM:
	  print_func (stream, "\t%s, %s, %s", get_field_rd (&buf, inst),
		      get_field_r1 (&buf, inst), get_field_imm (&buf, inst));
	  if (info->print_address_func && get_int_field_r1 (inst) == 0
	      && info->symbol_at_address_func)
	    {
	      if (immfound)
		immval |= (get_int_field_imm (inst) & 0x0000ffff);
	      else
		{
		  immval = get_int_field_imm (inst);
		  if (immval & 0x8000)
		    immval |= 0xFFFF0000;
		}
	      if (immval > 0 && info->symbol_at_address_func (immval, info))
		{
		  print_func (stream, "\t// ");
		  info->print_address_func (immval, info);
		}
	    }
	  break;
	case INST_TYPE_RD_R1_IMM5:
	  print_func (stream, "\t%s, %s, %s", get_field_rd (&buf, inst),
		      get_field_r1 (&buf, inst), get_field_imm5 (&buf, inst));
	  break;
	case INST_TYPE_RD_RFSL:
	  print_func (stream, "\t%s, %s", get_field_rd (&buf, inst),
		      get_field_rfsl (&buf, inst));
	  break;
	case INST_TYPE_R1_RFSL:
	  print_func (stream, "\t%s, %s", get_field_r1 (&buf, inst),
		      get_field_rfsl (&buf, inst));
	  break;
	case INST_TYPE_RD_SPECIAL:
	  print_func (stream, "\t%s, %s", get_field_rd (&buf, inst),
		      get_field_special (&buf, inst, op));
	  break;
	case INST_TYPE_SPECIAL_R1:
	  print_func (stream, "\t%s, %s", get_field_special (&buf, inst, op),
		      get_field_r1 (&buf, inst));
	  break;
	case INST_TYPE_RD_R1:
	  print_func (stream, "\t%s, %s", get_field_rd (&buf, inst),
		      get_field_r1 (&buf, inst));
	  break;
	case INST_TYPE_R1_R2:
	  print_func (stream, "\t%s, %s", get_field_r1 (&buf, inst),
		      get_field_r2 (&buf, inst));
	  break;
	case INST_TYPE_R1_IMM:
	  print_func (stream, "\t%s, %s", get_field_r1 (&buf, inst),
		      get_field_imm (&buf, inst));
	  /* The non-pc relative instructions are returns, which shouldn't
	     have a label printed.  */
	  if (info->print_address_func && op->inst_offset_type == INST_PC_OFFSET
	      && info->symbol_at_address_func)
	    {
	      if (immfound)
		immval |= (get_int_field_imm (inst) & 0x0000ffff);
	      else
		{
		  immval = get_int_field_imm (inst);
		  if (immval & 0x8000)
		    immval |= 0xFFFF0000;
		}
	      immval += memaddr;
	      if (immval > 0 && info->symbol_at_address_func (immval, info))
		{
		  print_func (stream, "\t// ");
		  info->print_address_func (immval, info);
		}
	      else
		{
		  print_func (stream, "\t\t// ");
		  print_func (stream, "%x", immval);
		}
	    }
	  break;
	case INST_TYPE_RD_IMM:
	  print_func (stream, "\t%s, %s", get_field_rd (&buf, inst),
		      get_field_imm (&buf, inst));
	  if (info->print_address_func && info->symbol_at_address_func)
	    {
	      if (immfound)
		immval |= (get_int_field_imm (inst) & 0x0000ffff);
	      else
		{
		  immval = get_int_field_imm (inst);
		  if (immval & 0x8000)
		    immval |= 0xFFFF0000;
		}
	      if (op->inst_offset_type == INST_PC_OFFSET)
		immval += (int) memaddr;
	      if (info->symbol_at_address_func (immval, info))
		{
		  print_func (stream, "\t// ");
		  info->print_address_func (immval, info);
		}
	    }
	  break;
	case INST_TYPE_IMM:
	  print_func (stream, "\t%s", get_field_imm (&buf, inst));
	  if (info->print_address_func && info->symbol_at_address_func
	      && op->instr != imm)
	    {
	      if (immfound)
		immval |= (get_int_field_imm (inst) & 0x0000ffff);
	      else
		{
		  immval = get_int_field_imm (inst);
		  if (immval & 0x8000)
		    immval |= 0xFFFF0000;
		}
	      if (op->inst_offset_type == INST_PC_OFFSET)
		immval += (int) memaddr;
	      if (immval > 0 && info->symbol_at_address_func (immval, info))
		{
		  print_func (stream, "\t// ");
		  info->print_address_func (immval, info);
		}
	      else if (op->inst_offset_type == INST_PC_OFFSET)
		{
		  print_func (stream, "\t\t// ");
		  print_func (stream, "%x", immval);
		}
	    }
	  break;
	case INST_TYPE_RD_R2:
	  print_func (stream, "\t%s, %s", get_field_rd (&buf, inst),
		      get_field_r2 (&buf, inst));
	  break;
	case INST_TYPE_R2:
	  print_func (stream, "\t%s", get_field_r2 (&buf, inst));
	  break;
	case INST_TYPE_R1:
	  print_func (stream, "\t%s", get_field_r1 (&buf, inst));
	  break;
	case INST_TYPE_R1_R2_SPECIAL:
	  print_func (stream, "\t%s, %s", get_field_r1 (&buf, inst),
		      get_field_r2 (&buf, inst));
	  break;
	case INST_TYPE_RD_IMM15:
	  print_func (stream, "\t%s, %s", get_field_rd (&buf, inst),
		      get_field_imm15 (&buf, inst));
	  break;
	  /* For mbar insn.  */
	case INST_TYPE_IMM5:
	  print_func (stream, "\t%s", get_field_imm5_mbar (&buf, inst));
	  break;
	  /* For mbar 16 or sleep insn.  */
	case INST_TYPE_NONE:
	  break;
	  /* For bit field insns.  */
	case INST_TYPE_RD_R1_IMMW_IMMS:
	  print_func (stream, "\t%s, %s, %s, %s",
		      get_field_rd (&buf, inst),
		      get_field_r1 (&buf, inst),
		      get_field_immw (&buf, inst),
		      get_field_imm5 (&buf, inst));
	  break;
	  /* For tuqula instruction */
	case INST_TYPE_RD:
	  print_func (stream, "\t%s", get_field_rd (&buf, inst));
	  break;
	case INST_TYPE_RFSL:
	  print_func (stream, "\t%s", get_field_rfsl (&buf, inst));
	  break;
	default:
	  /* If the disassembler lags the instruction set.  */
	  print_func (stream, "\tundecoded operands, inst is 0x%04x",
		      (unsigned int) inst);
	  break;
	}
    }

  /* Say how many bytes we consumed.  */
  return 4;
}

enum microblaze_instr
get_insn_microblaze (long inst,
  		     bool *isunsignedimm,
  		     enum microblaze_instr_type *insn_type,
  		     short *delay_slots)
{
  const struct op_code_struct *op;
  *isunsignedimm = false;

  /* Just a linear search of the table.  */
  for (op = microblaze_opcodes; op->name != 0; op ++)
    if (op->bit_sequence == (inst & op->opcode_mask))
      break;

  if (op->name == 0)
    return invalid_inst;
  else
    {
      *isunsignedimm = (op->inst_type == INST_TYPE_RD_R1_UNSIGNED_IMM);
      *insn_type = op->instr_type;
      *delay_slots = op->delay_slots;
      return op->instr;
    }
}

enum microblaze_instr
microblaze_decode_insn (long insn, int *rd, int *ra, int *rb, int *immed)
{
  enum microblaze_instr op;
  bool t1;
  enum microblaze_instr_type t2;
  short t3;

  op = get_insn_microblaze (insn, &t1, &t2, &t3);
  *rd = (insn & RD_MASK) >> RD_LOW;
  *ra = (insn & RA_MASK) >> RA_LOW;
  *rb = (insn & RB_MASK) >> RB_LOW;
  t3 = (insn & IMM_MASK) >> IMM_LOW;
  *immed = (int) t3;
  return (op);
}

unsigned long
microblaze_get_target_address (long inst, bool immfound, int immval,
			       long pcval, long r1val, long r2val,
			       bool *targetvalid,
			       bool *unconditionalbranch)
{
  const struct op_code_struct *op;
  long targetaddr = 0;

  *unconditionalbranch = false;
  /* Just a linear search of the table.  */
  for (op = microblaze_opcodes; op->name != 0; op ++)
    if (op->bit_sequence == (inst & op->opcode_mask))
      break;

  if (op->name == 0)
    {
      *targetvalid = false;
    }
  else if (op->instr_type == branch_inst)
    {
      switch (op->inst_type)
	{
        case INST_TYPE_R2:
          *unconditionalbranch = true;
        /* Fall through.  */
        case INST_TYPE_RD_R2:
        case INST_TYPE_R1_R2:
          targetaddr = r2val;
          *targetvalid = true;
          if (op->inst_offset_type == INST_PC_OFFSET)
	    targetaddr += pcval;
          break;
        case INST_TYPE_IMM:
          *unconditionalbranch = true;
        /* Fall through.  */
        case INST_TYPE_RD_IMM:
        case INST_TYPE_R1_IMM:
          if (immfound)
	    {
	      targetaddr = (immval << 16) & 0xffff0000;
	      targetaddr |= (get_int_field_imm (inst) & 0x0000ffff);
	    }
	  else
	    {
	      targetaddr = get_int_field_imm (inst);
	      if (targetaddr & 0x8000)
	        targetaddr |= 0xFFFF0000;
            }
          if (op->inst_offset_type == INST_PC_OFFSET)
	    targetaddr += pcval;
          *targetvalid = true;
          break;
	default:
	  *targetvalid = false;
	  break;
        }
    }
  else if (op->instr_type == return_inst)
    {
      if (immfound)
	{
	  targetaddr = (immval << 16) & 0xffff0000;
	  targetaddr |= (get_int_field_imm (inst) & 0x0000ffff);
	}
      else
	{
	  targetaddr = get_int_field_imm (inst);
	  if (targetaddr & 0x8000)
	    targetaddr |= 0xFFFF0000;
	}
      targetaddr += r1val;
      *targetvalid = true;
    }
  else
    *targetvalid = false;
  return targetaddr;
}
