/* Disassemble moxie instructions.
   Copyright 2009
   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 <stdio.h>
#include "sysdep.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;
}
