/* Disassembler code for CRIS.
   Copyright 2000, 2001 Free Software Foundation, Inc.
   Contributed by Axis Communications AB, Lund, Sweden.
   Written by Hans-Peter Nilsson.

This file is part of the GNU binutils and GDB, the GNU debugger.

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, 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 "dis-asm.h"
#include "sysdep.h"
#include "opcode/cris.h"
#include "libiberty.h"

/* No instruction will be disassembled longer than this.  In theory, and
   in silicon, address prefixes can be cascaded.  In practice, cascading
   is not used by GCC, and not supported by the assembler.  */
#ifndef MAX_BYTES_PER_CRIS_INSN
#define MAX_BYTES_PER_CRIS_INSN 8
#endif

/* Whether or not to decode prefixes, folding it into the following
   instruction.  FIXME: Make this optional later.  */
#ifndef PARSE_PREFIX
#define PARSE_PREFIX 1
#endif

/* Sometimes we prefix all registers with this character.  */
#define REGISTER_PREFIX_CHAR '$'

/* Whether or not to trace the following sequence:
   sub* X,r%d
   bound* Y,r%d
   adds.w [pc+r%d.w],pc

   This is the assembly form of a switch-statement in C.
   The "sub is optional.  If there is none, then X will be zero.
   X is the value of the first case,
   Y is the number of cases (including default).

   This results in case offsets printed on the form:
    case N: -> case_address
   where N is an estimation on the corresponding 'case' operand in C,
   and case_address is where execution of that case continues after the
   sequence presented above.

   The old style of output was to print the offsets as instructions,
   which made it hard to follow "case"-constructs in the disassembly,
   and caused a lot of annoying warnings about undefined instructions.

   FIXME: Make this optional later.  */
#ifndef TRACE_CASE
#define TRACE_CASE 1
#endif

/* Value of first element in switch.  */
static long case_offset = 0;

/* How many more case-offsets to print.  */
static long case_offset_counter = 0;

/* Number of case offsets.  */
static long no_of_case_offsets = 0;

/* Candidate for next case_offset.  */
static long last_immediate = 0;

static int number_of_bits PARAMS ((unsigned int));
static char *format_hex PARAMS ((unsigned long, char *));
static char *format_dec PARAMS ((long, char *, int));
static char *format_reg PARAMS ((int, char *, boolean));
static int cris_constraint PARAMS ((const char *, unsigned int,
				    unsigned int));
static unsigned bytes_to_skip PARAMS ((unsigned int,
				       const struct cris_opcode *));
static char *print_flags PARAMS ((unsigned int, char *));
static void print_with_operands
  PARAMS ((const struct cris_opcode *, unsigned int, unsigned char *,
	   bfd_vma, disassemble_info *, const struct cris_opcode *,
	   unsigned int, unsigned char *, boolean));
static const struct cris_spec_reg *spec_reg_info PARAMS ((unsigned int));
static int print_insn_cris_generic
  PARAMS ((bfd_vma, disassemble_info *, boolean));
static int print_insn_cris_with_register_prefix
  PARAMS ((bfd_vma, disassemble_info *));
static int print_insn_cris_without_register_prefix
  PARAMS ((bfd_vma, disassemble_info *));
static const struct cris_opcode *get_opcode_entry
  PARAMS ((unsigned int, unsigned int));

/* Return the descriptor of a special register.
   FIXME: Depend on a CPU-version specific argument when all machinery
   is in place.  */

static const struct cris_spec_reg *
spec_reg_info (sreg)
     unsigned int sreg;
{
  int i;
  for (i = 0; cris_spec_regs[i].name != NULL; i++)
    {
      if (cris_spec_regs[i].number == sreg)
	return &cris_spec_regs[i];
    }

  return NULL;
}

/* Return the number of bits in the argument.  */

static int
number_of_bits (val)
     unsigned int val;
{
  int bits;

  for (bits = 0; val != 0; val &= val - 1)
    bits++;

  return bits;
}

/* Get an entry in the opcode-table.  */

static const struct cris_opcode *
get_opcode_entry (insn, prefix_insn)
     unsigned int insn;
     unsigned int prefix_insn;
{
  /* For non-prefixed insns, we keep a table of pointers, indexed by the
     insn code.  Each entry is initialized when found to be NULL.  */
  static const struct cris_opcode **opc_table = NULL;

  const struct cris_opcode *max_matchedp = NULL;
  const struct cris_opcode **prefix_opc_table = NULL;

  /* We hold a table for each prefix that need to be handled differently.  */
  static const struct cris_opcode **dip_prefixes = NULL;
  static const struct cris_opcode **bdapq_m1_prefixes = NULL;
  static const struct cris_opcode **bdapq_m2_prefixes = NULL;
  static const struct cris_opcode **bdapq_m4_prefixes = NULL;
  static const struct cris_opcode **rest_prefixes = NULL;

  /* Allocate and clear the opcode-table.  */
  if (opc_table == NULL)
    {
      opc_table = xmalloc (65536 * sizeof (opc_table[0]));
      memset (opc_table, 0, 65536 * sizeof (const struct cris_opcode *));

      dip_prefixes
	= xmalloc (65536 * sizeof (const struct cris_opcode **));
      memset (dip_prefixes, 0, 65536 * sizeof (dip_prefixes[0]));

      bdapq_m1_prefixes
	= xmalloc (65536 * sizeof (const struct cris_opcode **));
      memset (bdapq_m1_prefixes, 0, 65536 * sizeof (bdapq_m1_prefixes[0]));

      bdapq_m2_prefixes
	= xmalloc (65536 * sizeof (const struct cris_opcode **));
      memset (bdapq_m2_prefixes, 0, 65536 * sizeof (bdapq_m2_prefixes[0]));

      bdapq_m4_prefixes
	= xmalloc (65536 * sizeof (const struct cris_opcode **));
      memset (bdapq_m4_prefixes, 0, 65536 * sizeof (bdapq_m4_prefixes[0]));

      rest_prefixes
	= xmalloc (65536 * sizeof (const struct cris_opcode **));
      memset (rest_prefixes, 0, 65536 * sizeof (rest_prefixes[0]));
    }

  /* Get the right table if this is a prefix.
     This code is connected to cris_constraints in that it knows what
     prefixes play a role in recognition of patterns; the necessary
     state is reflected by which table is used.  If constraints
     involving match or non-match of prefix insns are changed, then this
     probably needs changing too.  */
  if (prefix_insn != NO_CRIS_PREFIX)
    {
      const struct cris_opcode *popcodep
	= (opc_table[prefix_insn] != NULL
	   ? opc_table[prefix_insn]
	   : get_opcode_entry (prefix_insn, NO_CRIS_PREFIX));

      if (popcodep == NULL)
	return NULL;

      if (popcodep->match == BDAP_QUICK_OPCODE)
	{
	  /* Since some offsets are recognized with "push" macros, we
	     have to have different tables for them.  */
	  int offset = (prefix_insn & 255);

	  if (offset > 127)
	    offset -= 256;

	  switch (offset)
	    {
	    case -4:
	      prefix_opc_table = bdapq_m4_prefixes;
	      break;

	    case -2:
	      prefix_opc_table = bdapq_m2_prefixes;
	      break;

	    case -1:
	      prefix_opc_table = bdapq_m1_prefixes;
	      break;

	    default:
	      prefix_opc_table = rest_prefixes;
	      break;
	    }
	}
      else if (popcodep->match == DIP_OPCODE)
	/* We don't allow postincrement when the prefix is DIP, so use a
	   different table for DIP.  */
	prefix_opc_table = dip_prefixes;
      else
	prefix_opc_table = rest_prefixes;
    }

  if (prefix_insn != NO_CRIS_PREFIX
      && prefix_opc_table[insn] != NULL)
    max_matchedp = prefix_opc_table[insn];
  else if (prefix_insn == NO_CRIS_PREFIX && opc_table[insn] != NULL)
    max_matchedp = opc_table[insn];
  else
    {
      const struct cris_opcode *opcodep;
      int max_level_of_match = -1;

      for (opcodep = cris_opcodes;
	   opcodep->name != NULL;
	   opcodep++)
	{
	  int level_of_match;

	  /* We give a double lead for bits matching the template in
	     cris_opcodes.  Not even, because then "move p8,r10" would
	     be given 2 bits lead over "clear.d r10".  When there's a
	     tie, the first entry in the table wins.  This is
	     deliberate, to avoid a more complicated recognition
	     formula.  */
	  if ((opcodep->match & insn) == opcodep->match
	      && (opcodep->lose & insn) == 0
	      && ((level_of_match
		   = cris_constraint (opcodep->args,
				      insn,
				      prefix_insn))
		  >= 0)
	      && ((level_of_match
		   += 2 * number_of_bits (opcodep->match
					  | opcodep->lose))
			  > max_level_of_match))
		    {
		      max_matchedp = opcodep;
		      max_level_of_match = level_of_match;

		      /* If there was a full match, never mind looking
			 further.  */
		      if (level_of_match >= 2 * 16)
			break;
		    }
		}
      /* Fill in the new entry.

	 If there are changes to the opcode-table involving prefixes, and
	 disassembly then does not work correctly, try removing the
	 else-clause below that fills in the prefix-table.  If that
	 helps, you need to change the prefix_opc_table setting above, or
	 something related.  */
      if (prefix_insn == NO_CRIS_PREFIX)
	opc_table[insn] = max_matchedp;
      else
	prefix_opc_table[insn] = max_matchedp;
    }

  return max_matchedp;
}

/* Format number as hex with a leading "0x" into outbuffer.  */

static char *
format_hex (number, outbuffer)
     unsigned long number;
     char *outbuffer;
{
  /* Obfuscate to avoid warning on 32-bit host, but properly truncate
     negative numbers on >32-bit hosts.  */
  if (sizeof (number) > 4)
    number &= (1 << (sizeof (number) > 4 ? 32 : 1)) - 1;

  sprintf (outbuffer, "0x%lx", number);

  /* Save this value for the "case" support.  */
  if (TRACE_CASE)
    last_immediate = number;

  return outbuffer + strlen (outbuffer);
}

/* Format number as decimal into outbuffer.  Parameter signedp says
   whether the number should be formatted as signed (!= 0) or
   unsigned (== 0).  */

static char *
format_dec (number, outbuffer, signedp)
     long number;
     char *outbuffer;
     int signedp;
{
  last_immediate = number;
  sprintf (outbuffer, signedp ? "%ld" : "%lu", number);

  return outbuffer + strlen (outbuffer);
}

/* Format the name of the general register regno into outbuffer.  */

static char *
format_reg (regno, outbuffer_start, with_reg_prefix)
     int regno;
     char *outbuffer_start;
     boolean with_reg_prefix;
{
  char *outbuffer = outbuffer_start;

  if (with_reg_prefix)
    *outbuffer++ = REGISTER_PREFIX_CHAR;

  switch (regno)
    {
    case 15:
      strcpy (outbuffer, "pc");
      break;

    case 14:
      strcpy (outbuffer, "sp");
      break;

    default:
      sprintf (outbuffer, "r%d", regno);
      break;
    }

  return outbuffer_start + strlen (outbuffer_start);
}

/* Return -1 if the constraints of a bitwise-matched instruction say
   that there is no match.  Otherwise return a nonnegative number
   indicating the confidence in the match (higher is better).  */

static int
cris_constraint (cs, insn, prefix_insn)
     const char *cs;
     unsigned int insn;
     unsigned int prefix_insn;
{
  int retval = 0;
  int tmp;
  int prefix_ok = 0;

  const char *s;
  for (s = cs; *s; s++)
    switch (*s)
      {
      case '!':
	/* Do not recognize "pop" if there's a prefix.  */
	if (prefix_insn != NO_CRIS_PREFIX)
	  return -1;
	break;

      case 'M':
	/* Size modifier for "clear", i.e. special register 0, 4 or 8.
	   Check that it is one of them.  Only special register 12 could
	   be mismatched, but checking for matches is more logical than
	   checking for mismatches when there are only a few cases.  */
	tmp = ((insn >> 12) & 0xf);
	if (tmp != 0 && tmp != 4 && tmp != 8)
	  return -1;
	break;

      case 'm':
	if ((insn & 0x30) == 0x30)
	  return -1;
	break;

      case 'S':
	/* A prefix operand without side-effect.  */
	if (prefix_insn != NO_CRIS_PREFIX && (insn & 0x400) == 0)
	  {
	    prefix_ok = 1;
	    break;
	  }
	else
	  return -1;

      case 's':
      case 'y':
	/* If this is a prefixed insn with postincrement (side-effect),
	   the prefix must not be DIP.  */
	if (prefix_insn != NO_CRIS_PREFIX)
	  {
	    if (insn & 0x400)
	      {
		const struct cris_opcode *prefix_opcodep
		  = get_opcode_entry (prefix_insn, NO_CRIS_PREFIX);

		if (prefix_opcodep->match == DIP_OPCODE)
		  return -1;
	      }

	    prefix_ok = 1;
	  }
	break;

      case 'B':
	/* If we don't fall through, then the prefix is ok.  */
	prefix_ok = 1;

	/* A "push" prefix.  Check for valid "push" size.
	   In case of special register, it may be != 4.  */
	if (prefix_insn != NO_CRIS_PREFIX)
	  {
	    /* Match the prefix insn to BDAPQ.  */
	    const struct cris_opcode *prefix_opcodep
	      = get_opcode_entry (prefix_insn, NO_CRIS_PREFIX);

	    if (prefix_opcodep->match == BDAP_QUICK_OPCODE)
	      {
		int pushsize = (prefix_insn & 255);

		if (pushsize > 127)
		  pushsize -= 256;

		if (s[1] == 'P')
		  {
		    unsigned int spec_reg = (insn >> 12) & 15;
		    const struct cris_spec_reg *sregp
		      = spec_reg_info (spec_reg);

		    /* For a special-register, the "prefix size" must
		       match the size of the register.  */
		    if (sregp && sregp->reg_size == (unsigned int) -pushsize)
		      break;
		  }
		else if (s[1] == 'R')
		  {
		    if ((insn & 0x30) == 0x20 && pushsize == -4)
		      break;
		  }
		/* FIXME:  Should abort here; next constraint letter
		   *must* be 'P' or 'R'.  */
	      }
	  }
	return -1;

      case 'D':
	retval = (((insn >> 12) & 15) == (insn & 15));
	if (!retval)
	  return -1;
	else
	  retval += 4;
	break;

      case 'P':
	{
	  const struct cris_spec_reg *sregp
	    = spec_reg_info ((insn >> 12) & 15);

	  /* Since we match four bits, we will give a value of 4-1 = 3
	     in a match.  If there is a corresponding exact match of a
	     special register in another pattern, it will get a value of
	     4, which will be higher.  This should be correct in that an
	     exact pattern would match better than a general pattern.

	     Note that there is a reason for not returning zero; the
	     pattern for "clear" is partly  matched in the bit-pattern
	     (the two lower bits must be zero), while the bit-pattern
	     for a move from a special register is matched in the
	     register constraint.  */

	  if (sregp != NULL)
	    {
	      retval += 3;
	      break;
	    }
	  else
	    return -1;
	}
      }

  if (prefix_insn != NO_CRIS_PREFIX && ! prefix_ok)
    return -1;

  return retval;
}

/* Return the length of an instruction.  */

static unsigned
bytes_to_skip (insn, matchedp)
     unsigned int insn;
     const struct cris_opcode *matchedp;
{
  /* Each insn is a word plus "immediate" operands.  */
  unsigned to_skip = 2;
  const char *template = matchedp->args;
  const char *s;

  for (s = template; *s; s++)
    if (*s == 's' && (insn & 0x400) && (insn & 15) == 15)
      {
	/* Immediate via [pc+], so we have to check the size of the
	   operand.  */
	int mode_size = 1 << ((insn >> 4) & (*template == 'z' ? 1 : 3));

	if (matchedp->imm_oprnd_size == SIZE_FIX_32)
	  to_skip += 4;
	else if (matchedp->imm_oprnd_size == SIZE_SPEC_REG)
	  {
	    const struct cris_spec_reg *sregp
	      = spec_reg_info ((insn >> 12) & 15);

	    /* FIXME: Improve error handling; should have been caught
	       earlier.  */
	    if (sregp == NULL)
	      return 2;

	    /* PC is incremented by two, not one, for a byte.  */
	    to_skip += (sregp->reg_size + 1) & ~1;
	  }
	else
	  to_skip += (mode_size + 1) & ~1;
      }
    else if (*s == 'b')
      to_skip += 2;

  return to_skip;
}

/* Print condition code flags.  */

static char *
print_flags (insn, cp)
     unsigned int insn;
     char *cp;
{
  /* Use the v8 (Etrax 100) flag definitions for disassembly.
     The differences with v0 (Etrax 1..4) vs. Svinto are:
     v0 'd' <=> v8 'm'
     v0 'e' <=> v8 'b'.  */
  static const char fnames[] = "cvznxibm";

  unsigned char flagbits = (((insn >> 8) & 0xf0) | (insn & 15));
  int i;

  for (i = 0; i < 8; i++)
    if (flagbits & (1 << i))
      *cp++ = fnames[i];

  return cp;
}

/* Print out an insn with its operands, and update the info->insn_type
   fields.  The prefix_opcodep and the rest hold a prefix insn that is
   supposed to be output as an address mode.  */

static void
print_with_operands (opcodep, insn, buffer, addr, info, prefix_opcodep,
		     prefix_insn, prefix_buffer, with_reg_prefix)
     const struct cris_opcode *opcodep;
     unsigned int insn;
     unsigned char *buffer;
     bfd_vma addr;
     disassemble_info *info;

     /* If a prefix insn was before this insn (and is supposed to be
	output as an address), here is a description of it.  */
     const struct cris_opcode *prefix_opcodep;
     unsigned int prefix_insn;
     unsigned char *prefix_buffer;
     boolean with_reg_prefix;
{
  /* Get a buffer of somewhat reasonable size where we store
     intermediate parts of the insn.  */
  char temp[sizeof (".d [$r13=$r12-2147483648],$r10") * 2];
  char *tp = temp;
  static const char mode_char[] = "bwd?";
  const char *s;
  const char *cs;

  /* Print out the name first thing we do.  */
  (*info->fprintf_func) (info->stream, "%s", opcodep->name);

  cs = opcodep->args;
  s = cs;

  /* Ignore any prefix indicator.  */
  if (*s == 'p')
    s++;

  if (*s == 'm' || *s == 'M' || *s == 'z')
    {
      *tp++ = '.';

      /* Get the size-letter.  */
      *tp++ = *s == 'M'
	? (insn & 0x8000 ? 'd'
	   : insn & 0x4000 ? 'w' : 'b')
	: mode_char[(insn >> 4) & (*s == 'z' ? 1 : 3)];

      /* Ignore the size and the space character that follows.  */
      s += 2;
    }

  /* Add a space if this isn't a long-branch, because for those will add
     the condition part of the name later.  */
  if (opcodep->match != (BRANCH_PC_LOW + BRANCH_INCR_HIGH * 256))
    *tp++ = ' ';

  /* Fill in the insn-type if deducible from the name (and there's no
     better way).  */
  if (opcodep->name[0] == 'j')
    {
      if (strncmp (opcodep->name, "jsr", 3) == 0)
	/* It's "jsr" or "jsrc".  */
	info->insn_type = dis_jsr;
      else
	/* Any other jump-type insn is considered a branch.  */
	info->insn_type = dis_branch;
    }

  /* We might know some more fields right now.  */
  info->branch_delay_insns = opcodep->delayed;

  /* Handle operands.  */
  for (; *s; s++)
    {
    switch (*s)
      {
      case ',':
	*tp++ = *s;
	break;

      case '!':
	/* Ignore at this point; used at earlier stages to avoid recognition
	   if there's a prefixes at something that in other ways looks like
	   a "pop".  */
	break;

      case 'B':
	/* This was the prefix that made this a "push".  We've already
	   handled it by recognizing it, so signal that the prefix is
	   handled by setting it to NULL.  */
	prefix_opcodep = NULL;
	break;

      case 'D':
      case 'r':
	tp = format_reg (insn & 15, tp, with_reg_prefix);
	break;

      case 'R':
	tp = format_reg ((insn >> 12) & 15, tp, with_reg_prefix);
	break;

      case 'y':
      case 'S':
      case 's':
	/* Any "normal" memory operand.  */
	if ((insn & 0x400) && (insn & 15) == 15)
	  {
	    /* We're looking at [pc+], i.e. we need to output an immediate
	       number, where the size can depend on different things.  */
	    long number;
	    int signedp
	      = ((*cs == 'z' && (insn & 0x20))
		 || opcodep->match == BDAP_QUICK_OPCODE);
	    int nbytes;

	    if (opcodep->imm_oprnd_size == SIZE_FIX_32)
	      nbytes = 4;
	    else if (opcodep->imm_oprnd_size == SIZE_SPEC_REG)
	      {
		const struct cris_spec_reg *sregp
		  = spec_reg_info ((insn >> 12) & 15);

		/* A NULL return should have been as a non-match earlier,
		   so catch it as an internal error in the error-case
		   below.  */
		if (sregp == NULL)
		  /* Whatever non-valid size.  */
		  nbytes = 42;
		else
		  /* PC is always incremented by a multiple of two.  */
		  nbytes = (sregp->reg_size + 1) & ~1;
	      }
	    else
	      {
		int mode_size = 1 << ((insn >> 4) & (*cs == 'z' ? 1 : 3));

		if (mode_size == 1)
		  nbytes = 2;
		else
		  nbytes = mode_size;
	      }

	    switch (nbytes)
	      {
	      case 1:
		number = buffer[2];
		if (signedp && number > 127)
		  number -= 256;
		break;

	      case 2:
		number = buffer[2] + buffer[3] * 256;
		if (signedp && number > 32767)
		  number -= 65536;
		break;

	      case 4:
		number
		  = buffer[2] + buffer[3] * 256 + buffer[4] * 65536
		  + buffer[5] * 0x1000000;
		break;

	      default:
		strcpy (tp, "bug");
		tp += 3;
		number = 42;
	      }

	    if ((*cs == 'z' && (insn & 0x20))
		|| (opcodep->match == BDAP_QUICK_OPCODE
		    && (nbytes <= 2 || buffer[1 + nbytes] == 0)))
	      tp = format_dec (number, tp, signedp);
	    else
	      {
		unsigned int highbyte = (number >> 24) & 0xff;

		/* Either output this as an address or as a number.  If it's
		   a dword with the same high-byte as the address of the
		   insn, assume it's an address, and also if it's a non-zero
		   non-0xff high-byte.  If this is a jsr or a jump, then
		   it's definitely an address.  */
		if (nbytes == 4
		    && (highbyte == ((addr >> 24) & 0xff)
			|| (highbyte != 0 && highbyte != 0xff)
			|| info->insn_type == dis_branch
			|| info->insn_type == dis_jsr))
		  {
		    /* Finish off and output previous formatted bytes.  */
		    *tp = 0;
		    tp = temp;
		    if (temp[0])
		      (*info->fprintf_func) (info->stream, "%s", temp);

		    (*info->print_address_func) ((bfd_vma) number, info);

		    info->target = number;
		  }
		else
		  tp = format_hex (number, tp);
	      }
	  }
	else
	  {
	    /* Not an immediate number.  Then this is a (possibly
	       prefixed) memory operand.  */
	    if (info->insn_type != dis_nonbranch)
	      {
		int mode_size
		  = 1 << ((insn >> 4)
			  & (opcodep->args[0] == 'z' ? 1 : 3));
		int size;
		info->insn_type = dis_dref;
		info->flags |= CRIS_DIS_FLAG_MEMREF;

		if (opcodep->imm_oprnd_size == SIZE_FIX_32)
		  size = 4;
		else if (opcodep->imm_oprnd_size == SIZE_SPEC_REG)
		  {
		    const struct cris_spec_reg *sregp
		      = spec_reg_info ((insn >> 12) & 15);

		    /* FIXME: Improve error handling; should have been caught
		       earlier.  */
		    if (sregp == NULL)
		      size = 4;
		    else
		      size = sregp->reg_size;
		  }
		else
		  size = mode_size;

		info->data_size = size;
	      }

	    *tp++ = '[';

	    if (prefix_opcodep
		/* We don't match dip with a postincremented field
		   as a side-effect address mode.  */
		&& ((insn & 0x400) == 0
		    || prefix_opcodep->match != DIP_OPCODE))
	      {
		if (insn & 0x400)
		  {
		    tp = format_reg (insn & 15, tp, with_reg_prefix);
		    *tp++ = '=';
		  }


		/* We mainly ignore the prefix format string when the
		   address-mode syntax is output.  */
		switch (prefix_opcodep->match)
		  {
		  case DIP_OPCODE:
		    /* It's [r], [r+] or [pc+].  */
		    if ((prefix_insn & 0x400) && (prefix_insn & 15) == 15)
		      {
			/* It's [pc+].  This cannot possibly be anything
			   but an address.  */
			unsigned long number
			  = prefix_buffer[2] + prefix_buffer[3] * 256
			  + prefix_buffer[4] * 65536
			  + prefix_buffer[5] * 0x1000000;

			info->target = (bfd_vma) number;

			/* Finish off and output previous formatted
			   data.  */
			*tp = 0;
			tp = temp;
			if (temp[0])
			  (*info->fprintf_func) (info->stream, "%s", temp);

			(*info->print_address_func) ((bfd_vma) number, info);
		      }
		    else
		      {
			/* For a memref in an address, we use target2.
			   In this case, target is zero.  */
			info->flags
			  |= (CRIS_DIS_FLAG_MEM_TARGET2_IS_REG
			      | CRIS_DIS_FLAG_MEM_TARGET2_MEM);

			info->target2 = prefix_insn & 15;

			*tp++ = '[';
			tp = format_reg (prefix_insn & 15, tp,
					 with_reg_prefix);
			if (prefix_insn & 0x400)
			  *tp++ = '+';
			*tp++ = ']';
		      }
		    break;

		  case BDAP_QUICK_OPCODE:
		    {
		      int number;

		      number = prefix_buffer[0];
		      if (number > 127)
			number -= 256;

		      /* Output "reg+num" or, if num < 0, "reg-num".  */
		      tp = format_reg ((prefix_insn >> 12) & 15, tp,
				       with_reg_prefix);
		      if (number >= 0)
			*tp++ = '+';
		      tp = format_dec (number, tp, 1);

		      info->flags |= CRIS_DIS_FLAG_MEM_TARGET_IS_REG;
		      info->target = (prefix_insn >> 12) & 15;
		      info->target2 = (bfd_vma) number;
		      break;
		    }

		  case BIAP_OPCODE:
		    /* Output "r+R.m".  */
		    tp = format_reg (prefix_insn & 15, tp, with_reg_prefix);
		    *tp++ = '+';
		    tp = format_reg ((prefix_insn >> 12) & 15, tp,
				     with_reg_prefix);
		    *tp++ = '.';
		    *tp++ = mode_char[(prefix_insn >> 4) & 3];

		    info->flags
		      |= (CRIS_DIS_FLAG_MEM_TARGET2_IS_REG
			  | CRIS_DIS_FLAG_MEM_TARGET_IS_REG

			  | ((prefix_insn & 0x8000)
			     ? CRIS_DIS_FLAG_MEM_TARGET2_MULT4
			     : ((prefix_insn & 0x8000)
				? CRIS_DIS_FLAG_MEM_TARGET2_MULT2 : 0)));

		    /* Is it the casejump?  It's a "adds.w [pc+r%d.w],pc".  */
		    if (insn == 0xf83f && (prefix_insn & ~0xf000) == 0x55f)
		      /* Then start interpreting data as offsets.  */
		      case_offset_counter = no_of_case_offsets;
		    break;

		  case BDAP_INDIR_OPCODE:
		    /* Output "r+s.m", or, if "s" is [pc+], "r+s" or
		       "r-s".  */
		    tp = format_reg ((prefix_insn >> 12) & 15, tp,
				     with_reg_prefix);

		    if ((prefix_insn & 0x400) && (prefix_insn & 15) == 15)
		      {
			long number;
			unsigned int nbytes;

			/* It's a value.  Get its size.  */
			int mode_size = 1 << ((prefix_insn >> 4) & 3);

			if (mode_size == 1)
			  nbytes = 2;
			else
			  nbytes = mode_size;

			switch (nbytes)
			  {
			  case 1:
			    number = prefix_buffer[2];
			    if (number > 127)
			      number -= 256;
			    break;

			  case 2:
			    number = prefix_buffer[2] + prefix_buffer[3] * 256;
			    if (number > 32767)
			      number -= 65536;
			    break;

			  case 4:
			    number
			      = prefix_buffer[2] + prefix_buffer[3] * 256
			      + prefix_buffer[4] * 65536
			      + prefix_buffer[5] * 0x1000000;
			    break;

			  default:
			    strcpy (tp, "bug");
			    tp += 3;
			    number = 42;
			  }

			info->flags |= CRIS_DIS_FLAG_MEM_TARGET_IS_REG;
			info->target2 = (bfd_vma) number;

			/* If the size is dword, then assume it's an
			   address.  */
			if (nbytes == 4)
			  {
			    /* Finish off and output previous formatted
			       bytes.  */
			    *tp++ = '+';
			    *tp = 0;
			    tp = temp;
			    (*info->fprintf_func) (info->stream, "%s", temp);

			    (*info->print_address_func) ((bfd_vma) number, info);
			  }
			else
			  {
			    if (number >= 0)
			      *tp++ = '+';
			    tp = format_dec (number, tp, 1);
			  }
		      }
		    else
		      {
			/* Output "r+[R].m" or "r+[R+].m".  */
			*tp++ = '+';
			*tp++ = '[';
			tp = format_reg (prefix_insn & 15, tp,
					 with_reg_prefix);
			if (prefix_insn & 0x400)
			  *tp++ = '+';
			*tp++ = ']';
			*tp++ = '.';
			*tp++ = mode_char[(prefix_insn >> 4) & 3];

			info->flags
			  |= (CRIS_DIS_FLAG_MEM_TARGET2_IS_REG
			      | CRIS_DIS_FLAG_MEM_TARGET2_MEM
			      | CRIS_DIS_FLAG_MEM_TARGET_IS_REG

			      | (((prefix_insn >> 4) == 2)
				 ? 0
				 : (((prefix_insn >> 4) & 3) == 1
				    ? CRIS_DIS_FLAG_MEM_TARGET2_MEM_WORD
				    : CRIS_DIS_FLAG_MEM_TARGET2_MEM_BYTE)));
		      }
		    break;

		  default:
		    (*info->fprintf_func) (info->stream, "?prefix-bug");
		  }

		/* To mark that the prefix is used, reset it.  */
		prefix_opcodep = NULL;
	      }
	    else
	      {
		tp = format_reg (insn & 15, tp, with_reg_prefix);

		info->flags |= CRIS_DIS_FLAG_MEM_TARGET_IS_REG;
		info->target = insn & 15;

		if (insn & 0x400)
		  *tp++ = '+';
	      }
	    *tp++ = ']';
	  }
	break;

      case 'x':
	tp = format_reg ((insn >> 12) & 15, tp, with_reg_prefix);
	*tp++ = '.';
	*tp++ = mode_char[(insn >> 4) & 3];
	break;

      case 'I':
	tp = format_dec (insn & 63, tp, 0);
	break;

      case 'b':
	{
	  int where = buffer[2] + buffer[3] * 256;

	  if (where > 32767)
	    where -= 65536;

	  where += addr + 4;

	  if (insn == BA_PC_INCR_OPCODE)
	    info->insn_type = dis_branch;
	  else
	    info->insn_type = dis_condbranch;

	  info->target = (bfd_vma) where;

	  *tp = 0;
	  tp = temp;
	  (*info->fprintf_func) (info->stream, "%s%s ",
				 temp, cris_cc_strings[insn >> 12]);

	  (*info->print_address_func) ((bfd_vma) where, info);
	}
      break;

    case 'c':
      tp = format_dec (insn & 31, tp, 0);
      break;

    case 'C':
      tp = format_dec (insn & 15, tp, 0);
      break;

    case 'o':
      {
	long offset = insn & 0xfe;

	if (insn & 1)
	  offset |= ~0xff;

	if (opcodep->match == BA_QUICK_OPCODE)
	  info->insn_type = dis_branch;
	else
	  info->insn_type = dis_condbranch;

	info->target = (bfd_vma) (addr + 2 + offset);
	*tp = 0;
	tp = temp;
	(*info->fprintf_func) (info->stream, "%s", temp);

	(*info->print_address_func) ((bfd_vma) (addr + 2 + offset), info);
      }
      break;

    case 'O':
      {
	long number = buffer[0];

	if (number > 127)
	  number = number - 256;

	tp = format_dec (number, tp, 1);
	*tp++ = ',';
	tp = format_reg ((insn >> 12) & 15, tp, with_reg_prefix);
      }
      break;

    case 'f':
      tp = print_flags (insn, tp);
      break;

    case 'i':
      tp = format_dec ((insn & 32) ? (insn & 31) | ~31 : insn & 31, tp, 1);
      break;

    case 'P':
      {
	const struct cris_spec_reg *sregp
	  = spec_reg_info ((insn >> 12) & 15);

	if (sregp->name == NULL)
	  /* Should have been caught as a non-match eariler.  */
	  *tp++ = '?';
	else
	  {
	    if (with_reg_prefix)
	      *tp++ = REGISTER_PREFIX_CHAR;
	    strcpy (tp, sregp->name);
	    tp += strlen (tp);
	  }
      }
      break;

    default:
      strcpy (tp, "???");
      tp += 3;
    }
  }

  *tp = 0;

  if (prefix_opcodep)
    (*info->fprintf_func) (info->stream, " (OOPS unused prefix \"%s: %s\")",
			   prefix_opcodep->name, prefix_opcodep->args);

  (*info->fprintf_func) (info->stream, "%s", temp);

  /* Get info for matching case-tables, if we don't have any active.
     We assume that the last constant seen is used; either in the insn
     itself or in a "move.d const,rN, sub.d rN,rM"-like sequence.  */
  if (TRACE_CASE && case_offset_counter == 0)
    {
      if (strncmp (opcodep->name, "sub", 3) == 0)
	case_offset = last_immediate;

      /* It could also be an "add", if there are negative case-values.  */
      else if (strncmp (opcodep->name, "add", 3) == 0)
	{
	  /* The first case is the negated operand to the add.  */
	  case_offset = -last_immediate;
	}
      /* A bound insn will tell us the number of cases.  */
      else if (strncmp (opcodep->name, "bound", 5) == 0)
	{
	  no_of_case_offsets = last_immediate + 1;
	}
      /* A jump or jsr or branch breaks the chain of insns for a
	 case-table, so assume default first-case again.  */
      else if (info->insn_type == dis_jsr
	       || info->insn_type == dis_branch
	       || info->insn_type == dis_condbranch)
	case_offset = 0;
    }
}


/* Print the CRIS instruction at address memaddr on stream.  Returns
   length of the instruction, in bytes.  Prefix register names with `$' if
   WITH_REG_PREFIX.  */

static int
print_insn_cris_generic (memaddr, info, with_reg_prefix)
     bfd_vma memaddr;
     disassemble_info *info;
     boolean with_reg_prefix;
{
  int nbytes;
  unsigned int insn;
  const struct cris_opcode *matchedp;
  int advance = 0;

  /* No instruction will be disassembled as longer than this number of
     bytes; stacked prefixes will not be expanded.  */
  unsigned char buffer[MAX_BYTES_PER_CRIS_INSN];
  unsigned char *bufp;
  int status = 0;
  bfd_vma addr;

  /* There will be an "out of range" error after the last instruction.
     Reading pairs of bytes in decreasing number, we hope that we will get
     at least the amount that we will consume.

     If we can't get any data, or we do not get enough data, we print
     the error message.  */

  for (nbytes = MAX_BYTES_PER_CRIS_INSN; nbytes > 0; nbytes -= 2)
    {
      status = (*info->read_memory_func) (memaddr, buffer, nbytes, info);
      if (status == 0)
	break;
    }

  /* If we did not get all we asked for, then clear the rest.
     Hopefully this makes a reproducible result in case of errors.  */
  if (nbytes != MAX_BYTES_PER_CRIS_INSN)
    memset (buffer + nbytes, 0, MAX_BYTES_PER_CRIS_INSN - nbytes);

  addr = memaddr;
  bufp = buffer;

  /* Set some defaults for the insn info.  */
  info->insn_info_valid = 1;
  info->branch_delay_insns = 0;
  info->data_size = 0;
  info->insn_type = dis_nonbranch;
  info->flags = 0;
  info->target = 0;
  info->target2 = 0;

  /* If we got any data, disassemble it.  */
  if (nbytes != 0)
    {
      matchedp = NULL;

      insn = bufp[0] + bufp[1] * 256;

      /* If we're in a case-table, don't disassemble the offsets.  */
      if (TRACE_CASE && case_offset_counter != 0)
	{
	  info->insn_type = dis_noninsn;
	  advance += 2;

	  /* If to print data as offsets, then shortcut here.  */
	  (*info->fprintf_func) (info->stream, "case %d%s: -> ",
				 case_offset + no_of_case_offsets
				 - case_offset_counter,
				 case_offset_counter == 1 ? "/default" :
				 "");

	  (*info->print_address_func) ((bfd_vma)
				       ((short) (insn)
					+ (long) (addr
						  - (no_of_case_offsets
						     - case_offset_counter)
						  * 2)), info);
	  case_offset_counter--;

	  /* The default case start (without a "sub" or "add") must be
	     zero.  */
	  if (case_offset_counter == 0)
	    case_offset = 0;
	}
      else if (insn == 0)
	{
	  /* We're often called to disassemble zeroes.  While this is a
	     valid "bcc .+2" insn, it is also useless enough and enough
	     of a nuiscance that we will just output "bcc .+2" for it
	     and signal it as a noninsn.  */
	  (*info->fprintf_func) (info->stream, "bcc .+2");
	  info->insn_type = dis_noninsn;
	  advance += 2;
	}
      else
	{
	  const struct cris_opcode *prefix_opcodep = NULL;
	  unsigned char *prefix_buffer = bufp;
	  unsigned int prefix_insn = insn;
	  int prefix_size = 0;

	  matchedp = get_opcode_entry (insn, NO_CRIS_PREFIX);

	  /* Check if we're supposed to write out prefixes as address
	     modes and if this was a prefix.  */
	  if (matchedp != NULL && PARSE_PREFIX && matchedp->args[0] == 'p')
	    {
	      /* If it's a prefix, put it into the prefix vars and get the
		 main insn.  */
	      prefix_size = bytes_to_skip (prefix_insn, matchedp);
	      prefix_opcodep = matchedp;

	      insn = bufp[prefix_size] + bufp[prefix_size + 1] * 256;
	      matchedp = get_opcode_entry (insn, prefix_insn);

	      if (matchedp != NULL)
		{
		  addr += prefix_size;
		  bufp += prefix_size;
		  advance += prefix_size;
		}
	      else
		{
		  /* The "main" insn wasn't valid, at least not when
		     prefixed.  Put back things enough to output the
		     prefix insn only, as a normal insn.  */
		  matchedp = prefix_opcodep;
		  insn = prefix_insn;
		  prefix_opcodep = NULL;
		}
	    }

	  if (matchedp == NULL)
	    {
	      (*info->fprintf_func) (info->stream, "??0x%lx", insn);
	      advance += 2;

	      info->insn_type = dis_noninsn;
	    }
	  else
	    {
	      advance += bytes_to_skip (insn, matchedp);

	      /* The info_type and assorted fields will be set according
		 to the operands.   */
	      print_with_operands (matchedp, insn, bufp, addr, info,
				   prefix_opcodep, prefix_insn,
				   prefix_buffer, with_reg_prefix);
	    }
	}
    }
  else
    info->insn_type = dis_noninsn;

  /* If we read less than MAX_BYTES_PER_CRIS_INSN, i.e. we got an error
     status when reading that much, and the insn decoding indicated a
     length exceeding what we read, there is an error.  */
  if (status != 0 && (nbytes == 0 || advance > nbytes))
    {
      (*info->memory_error_func) (status, memaddr, info);
      return -1;
    }

  /* Max supported insn size with one folded prefix insn.  */
  info->bytes_per_line = MAX_BYTES_PER_CRIS_INSN;

  /* I would like to set this to a fixed value larger than the actual
     number of bytes to print in order to avoid spaces between bytes,
     but objdump.c (2.9.1) does not like that, so we print 16-bit
     chunks, which is the next choice.  */
  info->bytes_per_chunk = 2;

  /* Printing bytes in order of increasing addresses makes sense,
     especially on a little-endian target.
     This is completely the opposite of what you think; setting this to
     BFD_ENDIAN_LITTLE will print bytes in order N..0 rather than the 0..N
     we want.  */
  info->display_endian = BFD_ENDIAN_BIG;

  return advance;
}

/* Disassemble, prefixing register names with `$'.  */

static int
print_insn_cris_with_register_prefix (vma, info)
     bfd_vma vma;
     disassemble_info *info;
{
  return print_insn_cris_generic (vma, info, true);
}

/* Disassemble, no prefixes on register names.  */

static int
print_insn_cris_without_register_prefix (vma, info)
     bfd_vma vma;
     disassemble_info *info;
{
  return print_insn_cris_generic (vma, info, false);
}

/* Return a disassembler-function that prints registers with a `$' prefix,
   or one that prints registers without a prefix.  */

disassembler_ftype
cris_get_disassembler (abfd)
     bfd *abfd;
{
  /* If there's no bfd in sight, we return what is valid as input in all
     contexts if fed back to the assembler: disassembly *with* register
     prefix.  */
  if (abfd == NULL || bfd_get_symbol_leading_char (abfd) == 0)
    return print_insn_cris_with_register_prefix;

  return print_insn_cris_without_register_prefix;
}

/*
 * Local variables:
 * eval: (c-set-style "gnu")
 * indent-tabs-mode: t
 * End:
 */
