/* i370-dis.c -- Disassemble Instruction 370 (ESA/390) instructions
   Copyright (C) 1994-2016 Free Software Foundation, Inc.
   PowerPC version written by Ian Lance Taylor, Cygnus Support
   Rewritten for i370 ESA/390 support by Linas Vepstas <linas@linas.org>

   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 "dis-asm.h"
#include "opcode/i370.h"

/* This file provides several disassembler functions, all of which use
   the disassembler interface defined in dis-asm.h.  */

int
print_insn_i370 (bfd_vma memaddr, struct disassemble_info *info)
{
  bfd_byte buffer[8];
  int status;
  i370_insn_t insn;
  const struct i370_opcode *opcode;
  const struct i370_opcode *opcode_end;

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

  /* Cast the bytes into the insn (in a host-endian indep way).  */
  insn.i[0] = (buffer[0] << 24) & 0xff000000;
  insn.i[0] |= (buffer[1] << 16) & 0xff0000;
  insn.i[0] |= (buffer[2] << 8) & 0xff00;
  insn.i[0] |= buffer[3]  & 0xff;
  insn.i[1] = (buffer[4] << 24) & 0xff000000;
  insn.i[1] |= (buffer[5] << 16) & 0xff0000;

  /* Find the first match in the opcode table.  We could speed this up
     a bit by doing a binary search on the major opcode.  */
  opcode_end = i370_opcodes + i370_num_opcodes;
  for (opcode = i370_opcodes; opcode < opcode_end; opcode++)
    {
      const unsigned char *opindex;
      const struct i370_operand *operand;
      i370_insn_t masked;
      int invalid;

      /* Mask off operands, and look for a match ... */
      masked = insn;
      if (2 == opcode->len)
        {
          masked.i[0] >>= 16;
          masked.i[0] &= 0xffff;
        }
      masked.i[0] &= opcode->mask.i[0];
      if (masked.i[0] != opcode->opcode.i[0])
	continue;

      if (6 == opcode->len)
        {
          masked.i[1] &= opcode->mask.i[1];
          if (masked.i[1] != opcode->opcode.i[1])
	    continue;
        }

      /* Found a match.  adjust a tad.  */
      if (2 == opcode->len)
        {
          insn.i[0] >>= 16;
          insn.i[0] &= 0xffff;
        }

      /* Make two passes over the operands.  First see if any of them
         have extraction functions, and, if they do, make sure the
         instruction is valid.  */
      invalid = 0;
      for (opindex = opcode->operands; *opindex != 0; opindex++)
        {
          operand = i370_operands + *opindex;
          if (operand->extract)
            (*operand->extract) (insn, &invalid);
        }
      if (invalid)
	continue;

      /* The instruction is valid.  */
      (*info->fprintf_func) (info->stream, "%s", opcode->name);
      if (opcode->operands[0] != 0)
        (*info->fprintf_func) (info->stream, "\t");

      /* Now extract and print the operands.  */
      for (opindex = opcode->operands; *opindex != 0; opindex++)
        {
          long value;

          operand = i370_operands + *opindex;

          /* Extract the value from the instruction.  */
          if (operand->extract)
            value = (*operand->extract) (insn, (int *) NULL);
          else
	    value = (insn.i[0] >> operand->shift) & ((1 << operand->bits) - 1);

          /* Print the operand as directed by the flags.  */
          if ((operand->flags & I370_OPERAND_OPTIONAL) != 0)
            {
              if (value)
                (*info->fprintf_func) (info->stream, "(r%ld)", value);
            }
          else if ((operand->flags & I370_OPERAND_SBASE) != 0)
            {
              (*info->fprintf_func) (info->stream, "(r%ld)", value);
            }
          else if ((operand->flags & I370_OPERAND_INDEX) != 0)
            {
              if (value)
                (*info->fprintf_func) (info->stream, "(r%ld,", value);
              else
                (*info->fprintf_func) (info->stream, "(,");
            }
          else if ((operand->flags & I370_OPERAND_LENGTH) != 0)
            {
              (*info->fprintf_func) (info->stream, "(%ld,", value);
            }
          else if ((operand->flags & I370_OPERAND_BASE) != 0)
            (*info->fprintf_func) (info->stream, "r%ld)", value);
          else if ((operand->flags & I370_OPERAND_GPR) != 0)
            (*info->fprintf_func) (info->stream, "r%ld,", value);
          else if ((operand->flags & I370_OPERAND_FPR) != 0)
            (*info->fprintf_func) (info->stream, "f%ld,", value);
          else if ((operand->flags & I370_OPERAND_RELATIVE) != 0)
            (*info->fprintf_func) (info->stream, "%ld", value);
          else
            (*info->fprintf_func) (info->stream, " %ld, ", value);
        }

      return opcode->len;
    }

  /* We could not find a match.  */
  (*info->fprintf_func) (info->stream, ".short 0x%02x%02x", buffer[0], buffer[1]);

  return 2;
}
