/* Disassemble z8000 code.
   Copyright (C) 1992-2021 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"
#include "disassemble.h"
#include "libiberty.h"

#define DEFINE_TABLE
#include "z8k-opc.h"

#include <setjmp.h>

typedef struct
{
  /* These are all indexed by nibble number (i.e only every other entry
     of bytes is used, and every 4th entry of words).  */
  unsigned char nibbles[24];
  unsigned char bytes[24];
  unsigned short words[24];

  /* Nibble number of first word not yet fetched.  */
  unsigned int max_fetched;
  bfd_vma insn_start;
  OPCODES_SIGJMP_BUF bailout;

  int tabl_index;
  char instr_asmsrc[80];
  unsigned long arg_reg[0x0f];
  unsigned long immediate;
  unsigned long displacement;
  unsigned long address;
  unsigned long cond_code;
  unsigned long ctrl_code;
  unsigned long flags;
  unsigned long interrupts;
}
instr_data_s;

/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
   to ADDR (exclusive) are valid.  Returns 1 for success, longjmps
   on error.  */
#define FETCH_DATA(info, nibble) \
  ((nibble) < ((instr_data_s *) (info->private_data))->max_fetched \
   ? 1 : fetch_data ((info), (nibble)))

static int
fetch_data (struct disassemble_info *info, int nibble)
{
  unsigned char mybuf[20];
  int status;
  instr_data_s *priv = (instr_data_s *) info->private_data;

  if ((nibble % 4) != 0)
    abort ();

  status = (*info->read_memory_func) (priv->insn_start,
				      (bfd_byte *) mybuf,
				      nibble / 2,
				      info);
  if (status != 0)
    {
      (*info->memory_error_func) (status, priv->insn_start, info);
      OPCODES_SIGLONGJMP (priv->bailout, 1);
    }

  {
    int i;
    unsigned char *p = mybuf;

    for (i = 0; i < nibble;)
      {
	priv->words[i] = (p[0] << 8) | p[1];

	priv->bytes[i] = *p;
	priv->nibbles[i++] = *p >> 4;
	priv->nibbles[i++] = *p & 0xf;

	++p;
	priv->bytes[i] = *p;
	priv->nibbles[i++] = *p >> 4;
	priv->nibbles[i++] = *p & 0xf;

	++p;
      }
  }
  priv->max_fetched = nibble;
  return 1;
}

static char *codes[16] =
  {
    "f",
    "lt",
    "le",
    "ule",
    "ov/pe",
    "mi",
    "eq",
    "c/ult",
    "t",
    "ge",
    "gt",
    "ugt",
    "nov/po",
    "pl",
    "ne",
    "nc/uge"
  };

static char *ctrl_names[8] =
  {
    "<invld>",
    "flags",
    "fcw",
    "refresh",
    "psapseg",
    "psapoff",
    "nspseg",
    "nspoff"
  };

static int seg_length;
int z8k_lookup_instr (unsigned char *, disassemble_info *);
static void output_instr (instr_data_s *, unsigned long, disassemble_info *);
static void unpack_instr (instr_data_s *, int, disassemble_info *);
static void unparse_instr (instr_data_s *, int);

static int
print_insn_z8k (bfd_vma addr, disassemble_info *info, int is_segmented)
{
  instr_data_s instr_data;

  info->private_data = (PTR) &instr_data;
  instr_data.max_fetched = 0;
  instr_data.insn_start = addr;
  if (OPCODES_SIGSETJMP (instr_data.bailout) != 0)
    /* Error return.  */
    return -1;

  info->bytes_per_chunk = 2;
  info->bytes_per_line = 6;
  info->display_endian = BFD_ENDIAN_BIG;

  instr_data.tabl_index = z8k_lookup_instr (instr_data.nibbles, info);
  if (instr_data.tabl_index >= 0)
    {
      unpack_instr (&instr_data, is_segmented, info);
      unparse_instr (&instr_data, is_segmented);
      output_instr (&instr_data, addr, info);
      return z8k_table[instr_data.tabl_index].length + seg_length;
    }
  else
    {
      FETCH_DATA (info, 4);
      (*info->fprintf_func) (info->stream, ".word %02x%02x",
			     instr_data.bytes[0], instr_data.bytes[2]);
      return 2;
    }
}

int
print_insn_z8001 (bfd_vma addr, disassemble_info *info)
{
  return print_insn_z8k (addr, info, 1);
}

int
print_insn_z8002 (bfd_vma addr, disassemble_info *info)
{
  return print_insn_z8k (addr, info, 0);
}

int
z8k_lookup_instr (unsigned char *nibbles, disassemble_info *info)
{
  unsigned int nibl_index, tabl_index;
  int nibl_matched;
  int need_fetch = 0;
  unsigned short instr_nibl;
  unsigned short tabl_datum, datum_class, datum_value;

  nibl_matched = 0;
  tabl_index = 0;
  FETCH_DATA (info, 4);
  while (!nibl_matched && z8k_table[tabl_index].name)
    {
      nibl_matched = 1;
      for (nibl_index = 0;
	   nibl_matched
	     && nibl_index < ARRAY_SIZE (z8k_table[0].byte_info)
	     && nibl_index < z8k_table[tabl_index].length * 2;
	   nibl_index++)
	{
	  if ((nibl_index % 4) == 0)
            {
              /* Fetch data only if it isn't already there.  */
              if (nibl_index >= 4 || (nibl_index < 4 && need_fetch))
                FETCH_DATA (info, nibl_index + 4);   /* Fetch one word at a time.  */
              if (nibl_index < 4)
                need_fetch = 0;
              else
                need_fetch = 1;
            }
	  instr_nibl = nibbles[nibl_index];

	  tabl_datum = z8k_table[tabl_index].byte_info[nibl_index];
	  datum_class = tabl_datum & CLASS_MASK;
	  datum_value = ~CLASS_MASK & tabl_datum;

	  switch (datum_class)
	    {
	    case CLASS_BIT:
	      if (datum_value != instr_nibl)
		nibl_matched = 0;
	      break;
	    case CLASS_IGNORE:
	      break;
	    case CLASS_00II:
	      if (!((~instr_nibl) & 0x4))
		nibl_matched = 0;
	      break;
	    case CLASS_01II:
	      if (!(instr_nibl & 0x4))
		nibl_matched = 0;
	      break;
	    case CLASS_0CCC:
	      if (!((~instr_nibl) & 0x8))
		nibl_matched = 0;
	      break;
	    case CLASS_1CCC:
	      if (!(instr_nibl & 0x8))
		nibl_matched = 0;
	      break;
	    case CLASS_0DISP7:
	      if (!((~instr_nibl) & 0x8))
		nibl_matched = 0;
	      nibl_index += 1;
	      break;
	    case CLASS_1DISP7:
	      if (!(instr_nibl & 0x8))
		nibl_matched = 0;
	      nibl_index += 1;
	      break;
	    case CLASS_REGN0:
	      if (instr_nibl == 0)
		nibl_matched = 0;
	      break;
	    case CLASS_BIT_1OR2:
	      if ((instr_nibl | 0x2) != (datum_value | 0x2))
		nibl_matched = 0;
	      break;
	    default:
	      break;
	    }
	}

      if (nibl_matched)
	return tabl_index;

      tabl_index++;
    }
  return -1;
}

static void
output_instr (instr_data_s *instr_data,
              unsigned long addr ATTRIBUTE_UNUSED,
              disassemble_info *info)
{
  unsigned int num_bytes;
  char out_str[100];

  out_str[0] = 0;

  num_bytes = (z8k_table[instr_data->tabl_index].length + seg_length) * 2;
  FETCH_DATA (info, num_bytes);

  strcat (out_str, instr_data->instr_asmsrc);

  (*info->fprintf_func) (info->stream, "%s", out_str);
}

static void
unpack_instr (instr_data_s *instr_data, int is_segmented, disassemble_info *info)
{
  unsigned int nibl_count, loop;
  unsigned short instr_nibl, instr_byte, instr_word;
  long instr_long;
  unsigned int tabl_datum, datum_class;
  unsigned short datum_value;

  nibl_count = 0;
  loop = 0;
  seg_length = 0;

  while (z8k_table[instr_data->tabl_index].byte_info[loop] != 0)
    {
      FETCH_DATA (info, nibl_count + 4 - (nibl_count % 4));
      instr_nibl = instr_data->nibbles[nibl_count];
      instr_byte = instr_data->bytes[nibl_count & ~1];
      instr_word = instr_data->words[nibl_count & ~3];

      tabl_datum = z8k_table[instr_data->tabl_index].byte_info[loop];
      datum_class = tabl_datum & CLASS_MASK;
      datum_value = tabl_datum & ~CLASS_MASK;

      switch (datum_class)
	{
	case CLASS_DISP:
	  switch (datum_value)
	    {
	    case ARG_DISP16:
	      instr_data->displacement = instr_data->insn_start + 4
		+ (signed short) (instr_word & 0xffff);
	      nibl_count += 3;
	      break;
	    case ARG_DISP12:
	      if (instr_word & 0x800)
		/* Negative 12 bit displacement.  */
		instr_data->displacement = instr_data->insn_start + 2
		  - (signed short) ((instr_word & 0xfff) | 0xf000) * 2;
	      else
		instr_data->displacement = instr_data->insn_start + 2
		  - (instr_word & 0x0fff) * 2;

	      nibl_count += 2;
	      break;
	    default:
	      break;
	    }
	  break;
	case CLASS_IMM:
	  switch (datum_value)
	    {
	    case ARG_IMM4:
	      instr_data->immediate = instr_nibl;
	      break;
	    case ARG_NIM4:
	      instr_data->immediate = (- instr_nibl) & 0xf;
	      break;
	    case ARG_NIM8:
	      instr_data->immediate = (- instr_byte) & 0xff;
	      nibl_count += 1;
	      break;
	    case ARG_IMM8:
	      instr_data->immediate = instr_byte;
	      nibl_count += 1;
	      break;
	    case ARG_IMM16:
	      instr_data->immediate = instr_word;
	      nibl_count += 3;
	      break;
	    case ARG_IMM32:
	      FETCH_DATA (info, nibl_count + 8);
	      instr_long = ((unsigned) instr_data->words[nibl_count] << 16
			    | instr_data->words[nibl_count + 4]);
	      instr_data->immediate = instr_long;
	      nibl_count += 7;
	      break;
	    case ARG_IMMN:
	      instr_data->immediate = instr_nibl - 1;
	      break;
	    case ARG_IMM4M1:
	      instr_data->immediate = instr_nibl + 1;
	      break;
	    case ARG_IMM_1:
	      instr_data->immediate = 1;
	      break;
	    case ARG_IMM_2:
	      instr_data->immediate = 2;
	      break;
	    case ARG_IMM2:
	      instr_data->immediate = instr_nibl & 0x3;
	      break;
	    default:
	      break;
	    }
	  break;
	case CLASS_CC:
	  instr_data->cond_code = instr_nibl;
	  break;
	case CLASS_ADDRESS:
	  if (is_segmented)
	    {
	      if (instr_nibl & 0x8)
		{
		  FETCH_DATA (info, nibl_count + 8);
		  instr_long = ((unsigned) instr_data->words[nibl_count] << 16
				| instr_data->words[nibl_count + 4]);
		  instr_data->address = ((instr_word & 0x7f00) << 16
					 | (instr_long & 0xffff));
		  nibl_count += 7;
		  seg_length = 2;
		}
	      else
		{
		  instr_data->address = ((instr_word & 0x7f00) << 16
					 | (instr_word & 0x00ff));
		  nibl_count += 3;
		}
	    }
	  else
	    {
	      instr_data->address = instr_word;
	      nibl_count += 3;
	    }
	  break;
	case CLASS_0CCC:
	case CLASS_1CCC:
	  instr_data->ctrl_code = instr_nibl & 0x7;
	  break;
	case CLASS_0DISP7:
	  instr_data->displacement =
	    instr_data->insn_start + 2 - (instr_byte & 0x7f) * 2;
	  nibl_count += 1;
	  break;
	case CLASS_1DISP7:
	  instr_data->displacement =
	    instr_data->insn_start + 2 - (instr_byte & 0x7f) * 2;
	  nibl_count += 1;
	  break;
	case CLASS_01II:
	  instr_data->interrupts = instr_nibl & 0x3;
	  break;
	case CLASS_00II:
	  instr_data->interrupts = instr_nibl & 0x3;
	  break;
	case CLASS_IGNORE:
	case CLASS_BIT:
	  instr_data->ctrl_code = instr_nibl & 0x7;
	  break;
	case CLASS_FLAGS:
	  instr_data->flags = instr_nibl;
	  break;
	case CLASS_REG:
	  instr_data->arg_reg[datum_value] = instr_nibl;
	  break;
	case CLASS_REGN0:
	  instr_data->arg_reg[datum_value] = instr_nibl;
	  break;
	case CLASS_DISP8:
	  instr_data->displacement =
	    instr_data->insn_start + 2 + (signed char) instr_byte * 2;
	  nibl_count += 1;
	  break;
        case CLASS_BIT_1OR2:
          instr_data->immediate = ((instr_nibl >> 1) & 0x1) + 1;
          nibl_count += 1;
	  break;
	default:
	  abort ();
	  break;
	}

      loop += 1;
      nibl_count += 1;
    }
}

static void
print_intr(char *tmp_str, unsigned long interrupts)
{
  int comma = 0;

  *tmp_str = 0;
  if (! (interrupts & 2))
    {
      strcat (tmp_str, "vi");
      comma = 1;
    }
  if (! (interrupts & 1))
    {
      if (comma) strcat (tmp_str, ",");
      strcat (tmp_str, "nvi");
    }
}

static void
print_flags(char *tmp_str, unsigned long flags)
{
  int comma = 0;

  *tmp_str = 0;
  if (flags & 8)
    {
      strcat (tmp_str, "c");
      comma = 1;
    }
  if (flags & 4)
    {
      if (comma) strcat (tmp_str, ",");
      strcat (tmp_str, "z");
      comma = 1;
    }
  if (flags & 2)
    {
      if (comma) strcat (tmp_str, ",");
      strcat (tmp_str, "s");
      comma = 1;
    }
  if (flags & 1)
    {
      if (comma) strcat (tmp_str, ",");
      strcat (tmp_str, "p");
    }
}

static void
unparse_instr (instr_data_s *instr_data, int is_segmented)
{
  unsigned short datum_value;
  unsigned int tabl_datum, datum_class;
  int loop, loop_limit;
  char out_str[80], tmp_str[25];

  sprintf (out_str, "%s\t", z8k_table[instr_data->tabl_index].name);

  loop_limit = z8k_table[instr_data->tabl_index].noperands;
  for (loop = 0; loop < loop_limit; loop++)
    {
      if (loop)
	strcat (out_str, ",");

      tabl_datum = z8k_table[instr_data->tabl_index].arg_info[loop];
      datum_class = tabl_datum & CLASS_MASK;
      datum_value = tabl_datum & ~CLASS_MASK;

      switch (datum_class)
	{
	case CLASS_X:
          sprintf (tmp_str, "0x%0lx(r%ld)", instr_data->address,
                   instr_data->arg_reg[datum_value]);
	  strcat (out_str, tmp_str);
	  break;
	case CLASS_BA:
          if (is_segmented)
            sprintf (tmp_str, "rr%ld(#0x%lx)", instr_data->arg_reg[datum_value],
                     instr_data->immediate);
          else
            sprintf (tmp_str, "r%ld(#0x%lx)", instr_data->arg_reg[datum_value],
                     instr_data->immediate);
	  strcat (out_str, tmp_str);
	  break;
	case CLASS_BX:
          if (is_segmented)
            sprintf (tmp_str, "rr%ld(r%ld)", instr_data->arg_reg[datum_value],
                     instr_data->arg_reg[ARG_RX]);
          else
            sprintf (tmp_str, "r%ld(r%ld)", instr_data->arg_reg[datum_value],
                     instr_data->arg_reg[ARG_RX]);
	  strcat (out_str, tmp_str);
	  break;
	case CLASS_DISP:
	  sprintf (tmp_str, "0x%0lx", instr_data->displacement);
	  strcat (out_str, tmp_str);
	  break;
	case CLASS_IMM:
	  if (datum_value == ARG_IMM2)	/* True with EI/DI instructions only.  */
	    {
	      print_intr (tmp_str, instr_data->interrupts);
	      strcat (out_str, tmp_str);
	      break;
	    }
	  sprintf (tmp_str, "#0x%0lx", instr_data->immediate);
	  strcat (out_str, tmp_str);
	  break;
	case CLASS_CC:
	  sprintf (tmp_str, "%s", codes[instr_data->cond_code]);
	  strcat (out_str, tmp_str);
	  break;
	case CLASS_CTRL:
	  sprintf (tmp_str, "%s", ctrl_names[instr_data->ctrl_code]);
	  strcat (out_str, tmp_str);
	  break;
	case CLASS_DA:
	case CLASS_ADDRESS:
	  sprintf (tmp_str, "0x%0lx", instr_data->address);
	  strcat (out_str, tmp_str);
	  break;
	case CLASS_IR:
	  if (is_segmented)
	    sprintf (tmp_str, "@rr%ld", instr_data->arg_reg[datum_value]);
	  else
	    sprintf (tmp_str, "@r%ld", instr_data->arg_reg[datum_value]);
	  strcat (out_str, tmp_str);
	  break;
	case CLASS_IRO:
          sprintf (tmp_str, "@r%ld", instr_data->arg_reg[datum_value]);
	  strcat (out_str, tmp_str);
	  break;
	case CLASS_FLAGS:
	  print_flags(tmp_str, instr_data->flags);
	  strcat (out_str, tmp_str);
	  break;
	case CLASS_REG_BYTE:
	  if (instr_data->arg_reg[datum_value] >= 0x8)
	    sprintf (tmp_str, "rl%ld",
		     instr_data->arg_reg[datum_value] - 0x8);
	  else
	    sprintf (tmp_str, "rh%ld", instr_data->arg_reg[datum_value]);
	  strcat (out_str, tmp_str);
	  break;
	case CLASS_REG_WORD:
	  sprintf (tmp_str, "r%ld", instr_data->arg_reg[datum_value]);
	  strcat (out_str, tmp_str);
	  break;
	case CLASS_REG_QUAD:
	  sprintf (tmp_str, "rq%ld", instr_data->arg_reg[datum_value]);
	  strcat (out_str, tmp_str);
	  break;
	case CLASS_REG_LONG:
	  sprintf (tmp_str, "rr%ld", instr_data->arg_reg[datum_value]);
	  strcat (out_str, tmp_str);
	  break;
	case CLASS_PR:
	  if (is_segmented)
	    sprintf (tmp_str, "rr%ld", instr_data->arg_reg[datum_value]);
	  else
	    sprintf (tmp_str, "r%ld", instr_data->arg_reg[datum_value]);
	  strcat (out_str, tmp_str);
	  break;
	default:
	  abort ();
	  break;
	}
    }

  strcpy (instr_data->instr_asmsrc, out_str);
}
