/* Disassemble z8000 code.
   Copyright (C) 1992-2019 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"

#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.  */
  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)
{
  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_index < z8k_table[tabl_index].length * 2 && nibl_matched;
	   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)
{
  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)
{
  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 = (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 = (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);
}
