/* mmix-dis.c -- Disassemble MMIX instructions.
   Copyright (C) 2000-2019 Free Software Foundation, Inc.
   Written by Hans-Peter Nilsson (hp@bitrange.com)

   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 <stdio.h>
#include "opcode/mmix.h"
#include "disassemble.h"
#include "libiberty.h"
#include "bfd.h"
#include "opintl.h"

#define BAD_CASE(x)						\
  do								\
   {								\
     opcodes_error_handler (_("bad case %d (%s) in %s:%d"),	\
			    x, #x, __FILE__, __LINE__);		\
     abort ();							\
   }								\
 while (0)

#define FATAL_DEBUG						\
 do								\
   {								\
     opcodes_error_handler (_("internal: non-debugged code "	\
			      "(test-case missing): %s:%d"),	\
			    __FILE__, __LINE__);		\
     abort ();							\
   }								\
 while (0)

#define ROUND_MODE(n)					\
 ((n) == 1 ? "ROUND_OFF" : (n) == 2 ? "ROUND_UP" :	\
  (n) == 3 ? "ROUND_DOWN" : (n) == 4 ? "ROUND_NEAR" :	\
  _("(unknown)"))

#define INSN_IMMEDIATE_BIT (IMM_OFFSET_BIT << 24)
#define INSN_BACKWARD_OFFSET_BIT (1 << 24)

#define MAX_REG_NAME_LEN       256
#define MAX_SPEC_REG_NAME_LEN  32
struct mmix_dis_info
 {
   const char *reg_name[MAX_REG_NAME_LEN];
   const char *spec_reg_name[MAX_SPEC_REG_NAME_LEN];

   /* Waste a little memory so we don't have to allocate each separately.
      We could have an array with static contents for these, but on the
      other hand, we don't have to.  */
   char basic_reg_name[MAX_REG_NAME_LEN][sizeof ("$255")];
 };

/* Initialize a target-specific array in INFO.  */

static bfd_boolean
initialize_mmix_dis_info (struct disassemble_info *info)
{
  struct mmix_dis_info *minfop = malloc (sizeof (struct mmix_dis_info));
  long i;

  if (minfop == NULL)
    return FALSE;

  memset (minfop, 0, sizeof (*minfop));

  /* Initialize register names from register symbols.  If there's no
     register section, then there are no register symbols.  */
  if ((info->section != NULL && info->section->owner != NULL)
      || (info->symbols != NULL
	  && info->symbols[0] != NULL
	  && bfd_asymbol_bfd (info->symbols[0]) != NULL))
    {
      bfd *abfd = info->section && info->section->owner != NULL
	? info->section->owner
	: bfd_asymbol_bfd (info->symbols[0]);
      asection *reg_section = bfd_get_section_by_name (abfd, "*REG*");

      if (reg_section != NULL)
	{
	  /* The returned symcount *does* include the ending NULL.  */
	  long symsize = bfd_get_symtab_upper_bound (abfd);
	  asymbol **syms = malloc (symsize);
	  long nsyms;

	  if (syms == NULL)
	    {
	      FATAL_DEBUG;
	      free (minfop);
	      return FALSE;
	    }
	  nsyms = bfd_canonicalize_symtab (abfd, syms);

	  /* We use the first name for a register.  If this is MMO, then
	     it's the name with the first sequence number, presumably the
	     first in the source.  */
	  for (i = 0; i < nsyms && syms[i] != NULL; i++)
	    {
	      if (syms[i]->section == reg_section
		  && syms[i]->value < MAX_REG_NAME_LEN
		  && minfop->reg_name[syms[i]->value] == NULL)
		minfop->reg_name[syms[i]->value] = syms[i]->name;
	    }
	}
    }

  /* Fill in the rest with the canonical names.  */
  for (i = 0; i < MAX_REG_NAME_LEN; i++)
    if (minfop->reg_name[i] == NULL)
      {
	sprintf (minfop->basic_reg_name[i], "$%ld", i);
	minfop->reg_name[i] = minfop->basic_reg_name[i];
      }

  /* We assume it's actually a one-to-one mapping of number-to-name.  */
  for (i = 0; mmix_spec_regs[i].name != NULL; i++)
    minfop->spec_reg_name[mmix_spec_regs[i].number] = mmix_spec_regs[i].name;

  info->private_data = (void *) minfop;
  return TRUE;
}

/* A table indexed by the first byte is constructed as we disassemble each
   tetrabyte.  The contents is a pointer into mmix_insns reflecting the
   first found entry with matching match-bits and lose-bits.  Further
   entries are considered one after one until the operand constraints
   match or the match-bits and lose-bits do not match.  Normally a
   "further entry" will just show that there was no other match.  */

static const struct mmix_opcode *
get_opcode (unsigned long insn)
{
  static const struct mmix_opcode **opcodes = NULL;
  const struct mmix_opcode *opcodep = mmix_opcodes;
  unsigned int opcode_part = (insn >> 24) & 255;

  if (opcodes == NULL)
    opcodes = xcalloc (256, sizeof (struct mmix_opcode *));

  opcodep = opcodes[opcode_part];
  if (opcodep == NULL
      || (opcodep->match & insn) != opcodep->match
      || (opcodep->lose & insn) != 0)
    {
      /* Search through the table.  */
      for (opcodep = mmix_opcodes; opcodep->name != NULL; opcodep++)
	{
	  /* FIXME: Break out this into an initialization function.  */
	  if ((opcodep->match & (opcode_part << 24)) == opcode_part
	      && (opcodep->lose & (opcode_part << 24)) == 0)
	    opcodes[opcode_part] = opcodep;

	  if ((opcodep->match & insn) == opcodep->match
	      && (opcodep->lose & insn) == 0)
	    break;
	}
    }

  if (opcodep->name == NULL)
    return NULL;

  /* Check constraints.  If they don't match, loop through the next opcode
     entries.  */
  do
    {
      switch (opcodep->operands)
	{
	  /* These have no restraint on what can be in the lower three
	     bytes.  */
	case mmix_operands_regs:
	case mmix_operands_reg_yz:
	case mmix_operands_regs_z_opt:
	case mmix_operands_regs_z:
	case mmix_operands_jmp:
	case mmix_operands_pushgo:
	case mmix_operands_pop:
	case mmix_operands_sync:
	case mmix_operands_x_regs_z:
	case mmix_operands_neg:
	case mmix_operands_pushj:
	case mmix_operands_regaddr:
	case mmix_operands_get:
	case mmix_operands_set:
	case mmix_operands_save:
	case mmix_operands_unsave:
	case mmix_operands_xyz_opt:
	  return opcodep;

	  /* For a ROUND_MODE, the middle byte must be 0..4.  */
	case mmix_operands_roundregs_z:
	case mmix_operands_roundregs:
	  {
	    int midbyte = (insn >> 8) & 255;

	    if (midbyte <= 4)
	      return opcodep;
	  }
	break;

	case mmix_operands_put:
	  /* A "PUT".  If it is "immediate", then no restrictions,
	     otherwise we have to make sure the register number is < 32.  */
	  if ((insn & INSN_IMMEDIATE_BIT)
	      || ((insn >> 16) & 255) < 32)
	    return opcodep;
	  break;

	case mmix_operands_resume:
	  /* Middle bytes must be zero.  */
	  if ((insn & 0x00ffff00) == 0)
	    return opcodep;
	  break;

	default:
	  BAD_CASE (opcodep->operands);
	}

      opcodep++;
    }
  while ((opcodep->match & insn) == opcodep->match
	 && (opcodep->lose & insn) == 0);

  /* If we got here, we had no match.  */
  return NULL;
}

static inline const char *
get_reg_name (const struct mmix_dis_info * minfop, unsigned int x)
{
  if (x >= MAX_REG_NAME_LEN)
    return _("*illegal*");
  return minfop->reg_name[x];
}

static inline const char *
get_spec_reg_name (const struct mmix_dis_info * minfop, unsigned int x)
{
  if (x >= MAX_SPEC_REG_NAME_LEN)
    return _("*illegal*");
  return minfop->spec_reg_name[x];
}

/* The main disassembly function.  */

int
print_insn_mmix (bfd_vma memaddr, struct disassemble_info *info)
{
  unsigned char buffer[4];
  unsigned long insn;
  unsigned int x, y, z;
  const struct mmix_opcode *opcodep;
  int status = (*info->read_memory_func) (memaddr, buffer, 4, info);
  struct mmix_dis_info *minfop;

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

  /* FIXME: Is -1 suitable?  */
  if (info->private_data == NULL
      && ! initialize_mmix_dis_info (info))
    return -1;

  minfop = (struct mmix_dis_info *) info->private_data;
  x = buffer[1];
  y = buffer[2];
  z = buffer[3];

  insn = bfd_getb32 (buffer);

  opcodep = get_opcode (insn);

  if (opcodep == NULL)
    {
      (*info->fprintf_func) (info->stream, _("*unknown*"));
      return 4;
    }

  (*info->fprintf_func) (info->stream, "%s ", opcodep->name);

  /* Present bytes in the order they are laid out in memory.  */
  info->display_endian = BFD_ENDIAN_BIG;

  info->insn_info_valid = 1;
  info->bytes_per_chunk = 4;
  info->branch_delay_insns = 0;
  info->target = 0;
  switch (opcodep->type)
    {
    case mmix_type_normal:
    case mmix_type_memaccess_block:
      info->insn_type = dis_nonbranch;
      break;

    case mmix_type_branch:
      info->insn_type = dis_branch;
      break;

    case mmix_type_condbranch:
      info->insn_type = dis_condbranch;
      break;

    case mmix_type_memaccess_octa:
      info->insn_type = dis_dref;
      info->data_size = 8;
      break;

    case mmix_type_memaccess_tetra:
      info->insn_type = dis_dref;
      info->data_size = 4;
      break;

    case mmix_type_memaccess_wyde:
      info->insn_type = dis_dref;
      info->data_size = 2;
      break;

    case mmix_type_memaccess_byte:
      info->insn_type = dis_dref;
      info->data_size = 1;
      break;

    case mmix_type_jsr:
      info->insn_type = dis_jsr;
      break;

    default:
      BAD_CASE(opcodep->type);
    }

  switch (opcodep->operands)
    {
    case mmix_operands_regs:
      /*  All registers: "$X,$Y,$Z".  */
      (*info->fprintf_func) (info->stream, "%s,%s,%s",
			     get_reg_name (minfop, x),
			     get_reg_name (minfop, y),
			     get_reg_name (minfop, z));
      break;

    case mmix_operands_reg_yz:
      /* Like SETH - "$X,YZ".  */
      (*info->fprintf_func) (info->stream, "%s,0x%x",
			     get_reg_name (minfop, x), y * 256 + z);
      break;

    case mmix_operands_regs_z_opt:
    case mmix_operands_regs_z:
    case mmix_operands_pushgo:
      /* The regular "$X,$Y,$Z|Z".  */
      if (insn & INSN_IMMEDIATE_BIT)
	(*info->fprintf_func) (info->stream, "%s,%s,%d",
			       get_reg_name (minfop, x),
			       get_reg_name (minfop, y), z);
      else
	(*info->fprintf_func) (info->stream, "%s,%s,%s",
			       get_reg_name (minfop, x),
			       get_reg_name (minfop, y),
			       get_reg_name (minfop, z));
      break;

    case mmix_operands_jmp:
      /* Address; only JMP.  */
      {
	bfd_signed_vma offset = (x * 65536 + y * 256 + z) * 4;

	if (insn & INSN_BACKWARD_OFFSET_BIT)
	  offset -= (256 * 65536) * 4;

	info->target = memaddr + offset;
	(*info->print_address_func) (memaddr + offset, info);
      }
      break;

    case mmix_operands_roundregs_z:
      /* Two registers, like FLOT, possibly with rounding: "$X,$Z|Z"
	 "$X,ROUND_MODE,$Z|Z".  */
      if (y != 0)
	{
	  if (insn & INSN_IMMEDIATE_BIT)
	    (*info->fprintf_func) (info->stream, "%s,%s,%d",
				   get_reg_name (minfop, x),
				   ROUND_MODE (y), z);
	  else
	    (*info->fprintf_func) (info->stream, "%s,%s,%s",
				   get_reg_name (minfop, x),
				   ROUND_MODE (y),
				   get_reg_name (minfop, z));
	}
      else
	{
	  if (insn & INSN_IMMEDIATE_BIT)
	    (*info->fprintf_func) (info->stream, "%s,%d",
				   get_reg_name (minfop, x), z);
	  else
	    (*info->fprintf_func) (info->stream, "%s,%s",
				   get_reg_name (minfop, x),
				   get_reg_name (minfop, z));
	}
      break;

    case mmix_operands_pop:
      /* Like POP - "X,YZ".  */
      (*info->fprintf_func) (info->stream, "%d,%d", x, y*256 + z);
      break;

    case mmix_operands_roundregs:
      /* Two registers, possibly with rounding: "$X,$Z" or
	 "$X,ROUND_MODE,$Z".  */
      if (y != 0)
	(*info->fprintf_func) (info->stream, "%s,%s,%s",
			       get_reg_name (minfop, x),
			       ROUND_MODE (y),
			       get_reg_name (minfop, z));
      else
	(*info->fprintf_func) (info->stream, "%s,%s",
			       get_reg_name (minfop, x),
			       get_reg_name (minfop, z));
      break;

    case mmix_operands_sync:
	/* Like SYNC - "XYZ".  */
      (*info->fprintf_func) (info->stream, "%u",
			     x * 65536 + y * 256 + z);
      break;

    case mmix_operands_x_regs_z:
      /* Like SYNCD - "X,$Y,$Z|Z".  */
      if (insn & INSN_IMMEDIATE_BIT)
	(*info->fprintf_func) (info->stream, "%d,%s,%d",
			       x, get_reg_name (minfop, y), z);
      else
	(*info->fprintf_func) (info->stream, "%d,%s,%s",
			       x, get_reg_name (minfop, y),
			       get_reg_name (minfop, z));
      break;

    case mmix_operands_neg:
      /* Like NEG and NEGU - "$X,Y,$Z|Z".  */
      if (insn & INSN_IMMEDIATE_BIT)
	(*info->fprintf_func) (info->stream, "%s,%d,%d",
			       get_reg_name (minfop, x), y, z);
      else
	(*info->fprintf_func) (info->stream, "%s,%d,%s",
			       get_reg_name (minfop, x), y,
			       get_reg_name (minfop, z));
      break;

    case mmix_operands_pushj:
    case mmix_operands_regaddr:
      /* Like GETA or branches - "$X,Address".  */
      {
	bfd_signed_vma offset = (y * 256 + z) * 4;

	if (insn & INSN_BACKWARD_OFFSET_BIT)
	  offset -= 65536 * 4;

	info->target = memaddr + offset;

	(*info->fprintf_func) (info->stream, "%s,", get_reg_name (minfop, x));
	(*info->print_address_func) (memaddr + offset, info);
      }
      break;

    case mmix_operands_get:
      /* GET - "X,spec_reg".  */
      (*info->fprintf_func) (info->stream, "%s,%s",
			     get_reg_name (minfop, x),
			     get_spec_reg_name (minfop, z));
      break;

    case mmix_operands_put:
      /* PUT - "spec_reg,$Z|Z".  */
      if (insn & INSN_IMMEDIATE_BIT)
	(*info->fprintf_func) (info->stream, "%s,%d",
			       get_spec_reg_name (minfop, x), z);
      else
	(*info->fprintf_func) (info->stream, "%s,%s",
			       get_spec_reg_name (minfop, x),
			       get_reg_name (minfop, z));
      break;

    case mmix_operands_set:
      /*  Two registers, "$X,$Y".  */
      (*info->fprintf_func) (info->stream, "%s,%s",
			     get_reg_name (minfop, x),
			     get_reg_name (minfop, y));
      break;

    case mmix_operands_save:
      /* SAVE - "$X,0".  */
      (*info->fprintf_func) (info->stream, "%s,0", minfop->reg_name[x]);
      break;

    case mmix_operands_unsave:
      /* UNSAVE - "0,$Z".  */
      (*info->fprintf_func) (info->stream, "0,%s", minfop->reg_name[z]);
      break;

    case mmix_operands_xyz_opt:
      /* Like SWYM or TRAP - "X,Y,Z".  */
      (*info->fprintf_func) (info->stream, "%d,%d,%d", x, y, z);
      break;

    case mmix_operands_resume:
      /* Just "Z", like RESUME.  */
      (*info->fprintf_func) (info->stream, "%d", z);
      break;

    default:
      (*info->fprintf_func) (info->stream, _("*unknown operands type: %d*"),
			     opcodep->operands);
      break;
    }

  return 4;
}
