/* Disassemble Motorolla M*Core instructions.
   Copyright (C) 1993, 1999 Free Software Foundation, Inc.

This program 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 2 of the License, or
(at your option) any later version.

This program 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */

#include <stdio.h>
#define STATIC_TABLE
#define DEFINE_TABLE

#include "mcore-opc.h"
#include "dis-asm.h"

/* Mask for each mcore_opclass: */
static const unsigned short imsk[] =
{
    /* O0  */ 0xFFFF,
    /* OT  */ 0xFFFC,
    /* O1  */ 0xFFF0,
    /* OC  */ 0xFFE0,
    /* O2  */ 0xFF00,
    /* X1  */ 0xFFF0,
    /* OI  */ 0xFE00,
    /* OB  */ 0xFE00,
	      
    /* OMa */ 0xFFF0,
    /* SI  */ 0xFE00,
    /* I7  */ 0xF800,
    /* LS  */ 0xF000,
    /* BR  */ 0xF800,
    /* BL  */ 0xFF00,
    /* LR  */ 0xF000,
    /* LJ  */ 0xFF00,
	      
    /* RM  */ 0xFFF0,
    /* RQ  */ 0xFFF0,
    /* JSR */ 0xFFF0,
    /* JMP */ 0xFFF0,
    /* OBRa*/ 0xFFF0,
    /* OBRb*/ 0xFF80,
    /* OBRc*/ 0xFF00,
    /* OBR2*/ 0xFE00,
	      
    /* O1R1*/ 0xFFF0,
    /* OMb */ 0xFF80,
    /* OMc */ 0xFF00,
    /* SIa */ 0xFE00,

    /* JC  */ 0,		/* JC,JU,JL don't appear in object */
    /* JU  */ 0,
    /* JL  */ 0,
    /* RSI */ 0,
    /* DO21*/ 0,
    /* OB2 */ 0 		/* OB2 won't appear in object. */
};

static const char * grname[] =
{
 "r0",  "r1",  "r2",  "r3",  "r4",  "r5",  "r6",  "r7",
 "r8",  "r9", "r10", "r11", "r12", "r13", "r14", "r15"
};

static const char X[] = "??";

static const char * crname[] =
{
  "psr",  "vbr", "epsr", "fpsr", "epc",  "fpc",  "ss0",  "ss1",
  "ss2",  "ss3", "ss4",  "gcr",  "gsr",     X,      X,      X,
     X,      X,      X,      X,      X,     X,      X,      X,
     X,      X,      X,      X,      X,     X,      X,      X
};

static const unsigned isiz[] = { 2, 0, 1, 0 };

int 
print_insn_mcore (memaddr, info)
     bfd_vma memaddr;
     struct disassemble_info * info;
{
  unsigned char       ibytes[4];
  fprintf_ftype       fprintf = info->fprintf_func;
  void *              stream = info->stream;
  unsigned short      inst;
  mcore_opcode_info * op;
  int                 status;

  info->bytes_per_chunk = 2;

  status = info->read_memory_func (memaddr, ibytes, 2, info);

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

    inst = (ibytes[0] << 8) | ibytes[1];

  /* Just a linear search of the table.  */
  for (op = mcore_table; op->name != 0; op ++)
    if (op->inst == (inst & imsk[op->opclass]))
      break;

  if (op->name == 0)
    fprintf (stream, ".short 0x%04x", inst);
  else
    {
      const char * name = grname[inst & 0x0F];
      
      fprintf (stream, "%s", op->name);
      
      switch (op->opclass)
	{
	case O0: break;
	case OT: fprintf (stream, "\t%d", inst & 0x3); break;
	case O1:
	case JMP:
	case JSR: fprintf (stream, "\t%s", name); break;
	case OC:  fprintf (stream, "\t%s, %s", name, crname[(inst >> 4) & 0x1F]); break;
	case O1R1: fprintf (stream, "\t%s, r1", name); break;
	case O2: fprintf (stream, "\t%s, %s", name, grname[(inst >> 4) & 0xF]); break;
	case X1: fprintf (stream, "\tr1, %s", name); break;
	case OI: fprintf (stream, "\t%s, %d", name, ((inst >> 4) & 0x1F) + 1); break;
	case RM: fprintf (stream, "\t%s-r15, (r0)", name); break;
	case RQ: fprintf (stream, "\tr4-r7, (%s)", name); break;
	case OB:
	case OBRa:
	case OBRb:
	case OBRc:
	case SI:
	case SIa:
	case OMa:
	case OMb:
	case OMc: fprintf (stream, "\t%s, %d", name, (inst >> 4) & 0x1F); break;
	case I7: fprintf (stream, "\t%s, %d", name, (inst >> 4) & 0x7F); break;
	case LS: fprintf (stream, "\t%s, (%s, %d)", grname[(inst >> 8) & 0xF],
			  name, ((inst >> 4) & 0xF) << isiz[(inst >> 13) & 3]);
	  break;
	  
	case BR:
	  {
	    long val = inst & 0x3FF;
	    
	    if (inst & 0x400)
	      val |= 0xFFFFFC00;
	    
	    fprintf (stream, "\t0x%x", memaddr + 2 + (val<<1));
	    
	    if (strcmp (op->name, "bsr") == 0)
	      {
		/* for bsr, we'll try to get a symbol for the target */
		val = memaddr + 2 + (val << 1);
		
		if (info->print_address_func && val != 0)
		  {
		    fprintf (stream, "\t// ");
		    info->print_address_func (val, info);
		  }
	      }
	  }
	  break;
	  
	case BL:
	  {
	    long val;
	    val = (inst & 0x000F);
	    fprintf (stream, "\t%s, 0x%x",
		    grname[(inst >> 4) & 0xF], memaddr - (val << 1));
	  }
	  break;
	  
	case LR:
	  {
	    unsigned long val;
	    
	    val = (memaddr + 2 + ((inst & 0xFF) << 2)) & 0xFFFFFFFC;
	    
	    status = info->read_memory_func (val, ibytes, 4, info);
	    if (status != 0) 
	      {
		info->memory_error_func (status, memaddr, info);
		break;
	      }
	    
	      val = (ibytes[0] << 24) | (ibytes[1] << 16)
		| (ibytes[2] << 8) | (ibytes[3]);
	    
	    /* Removed [] around literal value to match ABI syntax 12/95.  */
	    fprintf (stream, "\t%s, 0x%X", grname[(inst >> 8) & 0xF], val);

	    if (val == 0)
	      fprintf (stream, "\t// from address pool at 0x%x",
		       (memaddr + 2 + ((inst & 0xFF) << 2)) & 0xFFFFFFFC);
	  }
	  break;
	  
	case LJ:
	  {
	    unsigned long val;
	    
	    val = (memaddr + 2 + ((inst & 0xFF) << 2)) & 0xFFFFFFFC;
	    
	    status = info->read_memory_func (val, ibytes, 4, info);
	    if (status != 0) 
	      {
		info->memory_error_func (status, memaddr, info);
		break;
	      }

	      val = (ibytes[0] << 24) | (ibytes[1] << 16)
		| (ibytes[2] << 8) | (ibytes[3]);
	    
	    /* Removed [] around literal value to match ABI syntax 12/95.  */
	    fprintf (stream, "\t0x%X", val);
	    /* For jmpi/jsri, we'll try to get a symbol for the target.  */
	    if (info->print_address_func && val != 0)
	      {
		fprintf (stream, "\t// ");
		info->print_address_func (val, info);
	      }
	    else
	      {
		fprintf (stream, "\t// from address pool at 0x%x",
			 (memaddr + 2 + ((inst & 0xFF) << 2)) & 0xFFFFFFFC);
	      }
	  }
	  break;
	  
	default:
	  /* if the disassembler lags the instruction set */
	  fprintf (stream, "\tundecoded operands, inst is 0x%04x", inst);
	  break;
	}
    }
  
  /* Say how many bytes we consumed? */
  return 2;
}
