/* Disassemble Xilinx microblaze instructions.

   Copyright (C) 2009-2025 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 |= (~0xFFFF);
		}
	      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 |= (~0xFFFF);
		}
	      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 |= (~0xFFFF);
		}
	      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 |= (~0xFFFF);
		}
	      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) & (~0xffff);
	      targetaddr |= (get_int_field_imm (inst) & 0x0000ffff);
	    }
	  else
	    {
	      targetaddr = get_int_field_imm (inst);
	      if (targetaddr & 0x8000)
		targetaddr |= (~0xFFFF);
            }
          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) & (~0xffff);
	  targetaddr |= (get_int_field_imm (inst) & 0x0000ffff);
	}
      else
	{
	  targetaddr = get_int_field_imm (inst);
	  if (targetaddr & 0x8000)
	    targetaddr |= (~0xFFFF);
	}
      targetaddr += r1val;
      *targetvalid = true;
    }
  else
    *targetvalid = false;
  return targetaddr;
}
