/* 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., 675 Mass Ave, Cambridge, MA 02139, 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,

/* start-sanitize-m340 */
  /* MULSH */ 0xFF00,
/* end-sanitize-m340 */
		 
    /* 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;
    }

/* start-sanitize-m340 */
  if (info->endian == BFD_ENDIAN_BIG)
/* end-sanitize-m340 */
    inst = (ibytes[0] << 8) | ibytes[1];
/* start-sanitize-m340 */
  else if (info->endian == BFD_ENDIAN_LITTLE)
    inst = (ibytes[1] << 8) | ibytes[0];
  else
    abort ();
/* end-sanitize-m340 */

  /* 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;
/* start-sanitize-m340 */
	case MULSH:
/* end-sanitize-m340 */
	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;
	      }
	    
/* start-sanitize-m340 */
	    if (info->endian == BFD_ENDIAN_LITTLE)
	      val = (ibytes[3] << 24) | (ibytes[2] << 16)
		| (ibytes[1] << 8) | (ibytes[0]);
	    else
/* end-sanitize-m340 */
	      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;
	      }

/* start-sanitize-m340 */
	    if (info->endian == BFD_ENDIAN_LITTLE)
	      val = (ibytes[3] << 24) | (ibytes[2] << 16)
		| (ibytes[1] << 8) | (ibytes[0]);
	    else
/* end-sanitize-m340 */
	      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;
}
