/* Disassemble moxie instructions.
   Copyright 2009, 2012
   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 program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */

#include "sysdep.h"
#include <stdio.h>

#define STATIC_TABLE
#define DEFINE_TABLE

#include "opcode/moxie.h"
#include "dis-asm.h"

static fprintf_ftype fpr;
static void *stream;

/* Macros to extract operands from the instruction word.  */
#define OP_A(i) ((i >> 4) & 0xf)
#define OP_B(i) (i & 0xf)
#define INST2OFFSET(o) ((((signed short)((o & ((1<<10)-1))<<6))>>6)<<1)

static const char * reg_names[16] =
  { "$fp", "$sp", "$r0", "$r1", "$r2", "$r3", "$r4", "$r5",
    "$r6", "$r7", "$r8", "$r9", "$r10", "$r11", "$r12", "$r13" };

int
print_insn_moxie (bfd_vma addr, struct disassemble_info * info)
{
  int length = 2;
  int status;
  stream = info->stream;
  const moxie_opc_info_t * opcode;
  bfd_byte buffer[4];
  unsigned short iword;
  fpr = info->fprintf_func;

  if ((status = info->read_memory_func (addr, buffer, 2, info)))
    goto fail;
  iword = bfd_getb16 (buffer);

  /* Form 1 instructions have the high bit set to 0.  */
  if ((iword & (1<<15)) == 0)
    {
      /* Extract the Form 1 opcode.  */
      opcode = &moxie_form1_opc_info[iword >> 8];
      switch (opcode->itype)
	{
	case MOXIE_F1_NARG:
	  fpr (stream, "%s", opcode->name);
	  break;
	case MOXIE_F1_A:
	  fpr (stream, "%s\t%s", opcode->name,
	       reg_names[OP_A(iword)]);
	  break;
	case MOXIE_F1_AB:
	  fpr (stream, "%s\t%s, %s", opcode->name,
	       reg_names[OP_A(iword)],
	       reg_names[OP_B(iword)]);
	  break;
	case MOXIE_F1_A4:
	  {
	    unsigned imm;
	    if ((status = info->read_memory_func (addr + 2, buffer, 4, info)))
	      goto fail;
	    imm = bfd_getb32 (buffer);
	    fpr (stream, "%s\t%s, 0x%x", opcode->name,
		 reg_names[OP_A(iword)], imm);
	    length = 6;
	  }
	  break;
	case MOXIE_F1_4:
	  {
	    unsigned imm;
	    if ((status = info->read_memory_func (addr + 2, buffer, 4, info)))
	      goto fail;
	    imm = bfd_getb32 (buffer);
	    fpr (stream, "%s\t0x%x", opcode->name, imm);
	    length = 6;
	  }
	  break;
	case MOXIE_F1_M:
	  {
	    unsigned imm;
	    if ((status = info->read_memory_func (addr + 2, buffer, 4, info)))
	      goto fail;
	    imm = bfd_getb32 (buffer);
	    fpr (stream, "%s\t", opcode->name);
	    info->print_address_func ((bfd_vma) imm, info);
	    length = 6;
	  }
	  break;
	case MOXIE_F1_AiB:
	  fpr (stream, "%s\t(%s), %s", opcode->name,
	       reg_names[OP_A(iword)], reg_names[OP_B(iword)]);
	  break;
	case MOXIE_F1_ABi:
	  fpr (stream, "%s\t%s, (%s)", opcode->name,
	       reg_names[OP_A(iword)], reg_names[OP_B(iword)]);
	  break;
	case MOXIE_F1_4A:
	  {
	    unsigned imm;
	    if ((status = info->read_memory_func (addr + 2, buffer, 4, info)))
	      goto fail;
	    imm = bfd_getb32 (buffer);
	    fpr (stream, "%s\t0x%x, %s",
		 opcode->name, imm, reg_names[OP_A(iword)]);
	    length = 6;
	  }
	  break;
	case MOXIE_F1_AiB4:
	  {
	    unsigned imm;
	    if ((status = info->read_memory_func (addr+2, buffer, 4, info)))
	      goto fail;
	    imm = bfd_getb32 (buffer);
	    fpr (stream, "%s\t0x%x(%s), %s", opcode->name,
		 imm,
		 reg_names[OP_A(iword)],
		 reg_names[OP_B(iword)]);
	    length = 6;
	  }
	  break;
	case MOXIE_F1_ABi4:
	  {
	    unsigned imm;
	    if ((status = info->read_memory_func (addr+2, buffer, 4, info)))
	      goto fail;
	    imm = bfd_getb32 (buffer);
	    fpr (stream, "%s\t%s, 0x%x(%s)",
		 opcode->name,
		 reg_names[OP_A(iword)],
		 imm,
		 reg_names[OP_B(iword)]);
	    length = 6;
	  }
	  break;
	default:
	  abort ();
	}
    }
  else if ((iword & (1<<14)) == 0)
    {
      /* Extract the Form 2 opcode.  */
      opcode = &moxie_form2_opc_info[(iword >> 12) & 3];
      switch (opcode->itype)
	{
	case MOXIE_F2_A8V:
	  fpr (stream, "%s\t%s, 0x%x",
	       opcode->name,
	       reg_names[(iword >> 8) & 0xf],
	       iword & ((1 << 8) - 1));
	  break;
	case MOXIE_F2_NARG:
	  fpr (stream, "%s", opcode->name);
	  break;
	default:
	  abort();
	}
    }
  else
    {
      /* Extract the Form 3 opcode.  */
      opcode = &moxie_form3_opc_info[(iword >> 10) & 15];
      switch (opcode->itype)
	{
	case MOXIE_F3_PCREL:
	  fpr (stream, "%s\t", opcode->name);
	  info->print_address_func ((bfd_vma) (addr + INST2OFFSET(iword)), 
				    info);
	  break;
	default:
	  abort();
	}
    }

  return length;

 fail:
  info->memory_error_func (status, addr, info);
  return -1;
}
