| /* Disassemble MN10300 instructions. | 
 |    Copyright (C) 1996-2024 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> | 
 | #include "opcode/mn10300.h" | 
 | #include "disassemble.h" | 
 | #include "opintl.h" | 
 |  | 
 | #define HAVE_AM33_2 (info->mach == AM33_2) | 
 | #define HAVE_AM33   (info->mach == AM33 || HAVE_AM33_2) | 
 | #define HAVE_AM30   (info->mach == AM30) | 
 |  | 
 | static void | 
 | disassemble (bfd_vma memaddr, | 
 | 	     struct disassemble_info *info, | 
 | 	     unsigned long insn, | 
 | 	     unsigned int size) | 
 | { | 
 |   struct mn10300_opcode *op = (struct mn10300_opcode *) mn10300_opcodes; | 
 |   const struct mn10300_operand *operand; | 
 |   bfd_byte buffer[4]; | 
 |   unsigned long extension = 0; | 
 |   int status, match = 0; | 
 |  | 
 |   /* Find the opcode.  */ | 
 |   while (op->name) | 
 |     { | 
 |       int mysize, extra_shift; | 
 |  | 
 |       if (op->format == FMT_S0) | 
 | 	mysize = 1; | 
 |       else if (op->format == FMT_S1 | 
 | 	       || op->format == FMT_D0) | 
 | 	mysize = 2; | 
 |       else if (op->format == FMT_S2 | 
 | 	       || op->format == FMT_D1) | 
 | 	mysize = 3; | 
 |       else if (op->format == FMT_S4) | 
 | 	mysize = 5; | 
 |       else if (op->format == FMT_D2) | 
 | 	mysize = 4; | 
 |       else if (op->format == FMT_D3) | 
 | 	mysize = 5; | 
 |       else if (op->format == FMT_D4) | 
 | 	mysize = 6; | 
 |       else if (op->format == FMT_D6) | 
 | 	mysize = 3; | 
 |       else if (op->format == FMT_D7 || op->format == FMT_D10) | 
 | 	mysize = 4; | 
 |       else if (op->format == FMT_D8) | 
 | 	mysize = 6; | 
 |       else if (op->format == FMT_D9) | 
 | 	mysize = 7; | 
 |       else | 
 | 	mysize = 7; | 
 |  | 
 |       if ((op->mask & insn) == op->opcode | 
 | 	  && size == (unsigned int) mysize | 
 | 	  && (op->machine == 0 | 
 | 	      || (op->machine == AM33_2 && HAVE_AM33_2) | 
 | 	      || (op->machine == AM33 && HAVE_AM33) | 
 | 	      || (op->machine == AM30 && HAVE_AM30))) | 
 | 	{ | 
 | 	  const unsigned char *opindex_ptr; | 
 | 	  unsigned int nocomma; | 
 | 	  int paren = 0; | 
 |  | 
 | 	  if (op->format == FMT_D1 || op->format == FMT_S1) | 
 | 	    extra_shift = 8; | 
 | 	  else if (op->format == FMT_D2 || op->format == FMT_D4 | 
 | 		   || op->format == FMT_S2 || op->format == FMT_S4 | 
 | 		   || op->format == FMT_S6 || op->format == FMT_D5) | 
 | 	    extra_shift = 16; | 
 | 	  else if (op->format == FMT_D7 | 
 | 		   || op->format == FMT_D8 | 
 | 		   || op->format == FMT_D9) | 
 | 	    extra_shift = 8; | 
 | 	  else | 
 | 	    extra_shift = 0; | 
 |  | 
 | 	  if (size == 1 || size == 2) | 
 | 	    extension = 0; | 
 |  | 
 | 	  else if (size == 3 | 
 | 		   && (op->format == FMT_D1 | 
 | 		       || op->opcode == 0xdf0000 | 
 | 		       || op->opcode == 0xde0000)) | 
 | 	    extension = 0; | 
 |  | 
 | 	  else if (size == 3 | 
 | 		   && op->format == FMT_D6) | 
 | 	    extension = 0; | 
 |  | 
 | 	  else if (size == 3) | 
 | 	    { | 
 | 	      insn &= 0xff0000; | 
 | 	      status = (*info->read_memory_func) (memaddr + 1, buffer, 2, info); | 
 | 	      if (status != 0) | 
 | 		{ | 
 | 		  (*info->memory_error_func) (status, memaddr, info); | 
 | 		  return; | 
 | 		} | 
 |  | 
 | 	      insn |= bfd_getl16 (buffer); | 
 | 	      extension = 0; | 
 | 	    } | 
 | 	  else if (size == 4 | 
 | 		   && (op->opcode == 0xfaf80000 | 
 | 		       || op->opcode == 0xfaf00000 | 
 | 		       || op->opcode == 0xfaf40000)) | 
 | 	    extension = 0; | 
 |  | 
 | 	  else if (size == 4 | 
 | 		   && (op->format == FMT_D7 | 
 | 		       || op->format == FMT_D10)) | 
 | 	    extension = 0; | 
 |  | 
 | 	  else if (size == 4) | 
 | 	    { | 
 | 	      insn &= 0xffff0000; | 
 | 	      status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info); | 
 | 	      if (status != 0) | 
 | 		{ | 
 | 		  (*info->memory_error_func) (status, memaddr, info); | 
 | 		  return; | 
 | 		} | 
 |  | 
 | 	      insn |= bfd_getl16 (buffer); | 
 | 	      extension = 0; | 
 | 	    } | 
 | 	  else if (size == 5 && op->opcode == 0xdc000000) | 
 | 	    { | 
 | 	      unsigned long temp = 0; | 
 |  | 
 | 	      status = (*info->read_memory_func) (memaddr + 1, buffer, 4, info); | 
 | 	      if (status != 0) | 
 | 		{ | 
 | 		  (*info->memory_error_func) (status, memaddr, info); | 
 | 		  return; | 
 | 		} | 
 | 	      temp |= bfd_getl32 (buffer); | 
 |  | 
 | 	      insn &= 0xff000000; | 
 | 	      insn |= (temp & 0xffffff00) >> 8; | 
 | 	      extension = temp & 0xff; | 
 | 	    } | 
 | 	  else if (size == 5 && op->format == FMT_D3) | 
 | 	    { | 
 | 	      status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info); | 
 | 	      if (status != 0) | 
 | 		{ | 
 | 		  (*info->memory_error_func) (status, memaddr, info); | 
 | 		  return; | 
 | 		} | 
 | 	      insn &= 0xffff0000; | 
 | 	      insn |= bfd_getl16 (buffer); | 
 |  | 
 | 	      status = (*info->read_memory_func) (memaddr + 4, buffer, 1, info); | 
 | 	      if (status != 0) | 
 | 		{ | 
 | 		  (*info->memory_error_func) (status, memaddr, info); | 
 | 		  return; | 
 | 		} | 
 | 	      extension = *(unsigned char *) buffer; | 
 | 	    } | 
 | 	  else if (size == 5) | 
 | 	    { | 
 | 	      unsigned long temp = 0; | 
 |  | 
 | 	      status = (*info->read_memory_func) (memaddr + 1, buffer, 2, info); | 
 | 	      if (status != 0) | 
 | 		{ | 
 | 		  (*info->memory_error_func) (status, memaddr, info); | 
 | 		  return; | 
 | 		} | 
 | 	      temp |= bfd_getl16 (buffer); | 
 |  | 
 | 	      insn &= 0xff0000ff; | 
 | 	      insn |= temp << 8; | 
 |  | 
 | 	      status = (*info->read_memory_func) (memaddr + 4, buffer, 1, info); | 
 | 	      if (status != 0) | 
 | 		{ | 
 | 		  (*info->memory_error_func) (status, memaddr, info); | 
 | 		  return; | 
 | 		} | 
 | 	      extension = *(unsigned char *) buffer; | 
 | 	    } | 
 | 	  else if (size == 6 && op->format == FMT_D8) | 
 | 	    { | 
 | 	      insn &= 0xffffff00; | 
 | 	      status = (*info->read_memory_func) (memaddr + 5, buffer, 1, info); | 
 | 	      if (status != 0) | 
 | 		{ | 
 | 		  (*info->memory_error_func) (status, memaddr, info); | 
 | 		  return; | 
 | 		} | 
 | 	      insn |= *(unsigned char *) buffer; | 
 |  | 
 | 	      status = (*info->read_memory_func) (memaddr + 3, buffer, 2, info); | 
 | 	      if (status != 0) | 
 | 		{ | 
 | 		  (*info->memory_error_func) (status, memaddr, info); | 
 | 		  return; | 
 | 		} | 
 | 	      extension = bfd_getl16 (buffer); | 
 | 	    } | 
 | 	  else if (size == 6) | 
 | 	    { | 
 | 	      unsigned long temp = 0; | 
 |  | 
 | 	      status = (*info->read_memory_func) (memaddr + 2, buffer, 4, info); | 
 | 	      if (status != 0) | 
 | 		{ | 
 | 		  (*info->memory_error_func) (status, memaddr, info); | 
 | 		  return; | 
 | 		} | 
 | 	      temp |= bfd_getl32 (buffer); | 
 |  | 
 | 	      insn &= 0xffff0000; | 
 | 	      insn |= (temp >> 16) & 0xffff; | 
 | 	      extension = temp & 0xffff; | 
 | 	    } | 
 | 	  else if (size == 7 && op->format == FMT_D9) | 
 | 	    { | 
 | 	      insn &= 0xffffff00; | 
 | 	      status = (*info->read_memory_func) (memaddr + 3, buffer, 4, info); | 
 | 	      if (status != 0) | 
 | 		{ | 
 | 		  (*info->memory_error_func) (status, memaddr, info); | 
 | 		  return; | 
 | 		} | 
 | 	      extension = bfd_getl32 (buffer); | 
 | 	      insn |= (extension & 0xff000000) >> 24; | 
 | 	      extension &= 0xffffff; | 
 | 	    } | 
 | 	  else if (size == 7 && op->opcode == 0xdd000000) | 
 | 	    { | 
 | 	      unsigned long temp = 0; | 
 |  | 
 | 	      status = (*info->read_memory_func) (memaddr + 1, buffer, 4, info); | 
 | 	      if (status != 0) | 
 | 		{ | 
 | 		  (*info->memory_error_func) (status, memaddr, info); | 
 | 		  return; | 
 | 		} | 
 | 	      temp |= bfd_getl32 (buffer); | 
 |  | 
 | 	      insn &= 0xff000000; | 
 | 	      insn |= (temp >> 8) & 0xffffff; | 
 | 	      extension = (temp & 0xff) << 16; | 
 |  | 
 | 	      status = (*info->read_memory_func) (memaddr + 5, buffer, 2, info); | 
 | 	      if (status != 0) | 
 | 		{ | 
 | 		  (*info->memory_error_func) (status, memaddr, info); | 
 | 		  return; | 
 | 		} | 
 | 	      extension |= bfd_getb16 (buffer); | 
 | 	    } | 
 | 	  else if (size == 7) | 
 | 	    { | 
 | 	      unsigned long temp = 0; | 
 |  | 
 | 	      status = (*info->read_memory_func) (memaddr + 2, buffer, 4, info); | 
 | 	      if (status != 0) | 
 | 		{ | 
 | 		  (*info->memory_error_func) (status, memaddr, info); | 
 | 		  return; | 
 | 		} | 
 | 	      temp |= bfd_getl32 (buffer); | 
 |  | 
 | 	      insn &= 0xffff0000; | 
 | 	      insn |= (temp >> 16) & 0xffff; | 
 | 	      extension = (temp & 0xffff) << 8; | 
 |  | 
 | 	      status = (*info->read_memory_func) (memaddr + 6, buffer, 1, info); | 
 | 	      if (status != 0) | 
 | 		{ | 
 | 		  (*info->memory_error_func) (status, memaddr, info); | 
 | 		  return; | 
 | 		} | 
 | 	      extension |= *(unsigned char *) buffer; | 
 | 	    } | 
 |  | 
 | 	  match = 1; | 
 | 	  (*info->fprintf_func) (info->stream, "%s\t", op->name); | 
 |  | 
 | 	  /* Now print the operands.  */ | 
 | 	  for (opindex_ptr = op->operands, nocomma = 1; | 
 | 	       *opindex_ptr != 0; | 
 | 	       opindex_ptr++) | 
 | 	    { | 
 | 	      unsigned long value; | 
 |  | 
 | 	      operand = &mn10300_operands[*opindex_ptr]; | 
 |  | 
 | 	      /* If this operand is a PLUS (autoincrement), then do not emit | 
 | 		 a comma before emitting the plus.  */ | 
 | 	      if ((operand->flags & MN10300_OPERAND_PLUS) != 0) | 
 | 		nocomma = 1; | 
 |  | 
 | 	      if ((operand->flags & MN10300_OPERAND_DREG) != 0 | 
 | 		  || (operand->flags & MN10300_OPERAND_AREG) != 0 | 
 | 		  || (operand->flags & MN10300_OPERAND_RREG) != 0 | 
 | 		  || (operand->flags & MN10300_OPERAND_XRREG) != 0) | 
 | 		value = ((insn >> (operand->shift + extra_shift)) | 
 | 			 & ((1 << operand->bits) - 1)); | 
 | 	      else if ((operand->flags & MN10300_OPERAND_SPLIT) != 0) | 
 | 		{ | 
 | 		  unsigned long temp; | 
 |  | 
 | 		  value = insn & ((1 << operand->bits) - 1); | 
 | 		  value <<= (32 - operand->bits); | 
 | 		  temp = extension >> operand->shift; | 
 | 		  temp &= ((1 << (32 - operand->bits)) - 1); | 
 | 		  value |= temp; | 
 | 		  value = ((value ^ (((unsigned long) 1) << 31)) | 
 | 			   - (((unsigned long) 1) << 31)); | 
 | 		} | 
 | 	      else if ((operand->flags & MN10300_OPERAND_24BIT) != 0) | 
 | 		{ | 
 | 		  unsigned long temp; | 
 |  | 
 | 		  value = insn & ((1 << operand->bits) - 1); | 
 | 		  value <<= (24 - operand->bits); | 
 | 		  temp = extension >> operand->shift; | 
 | 		  temp &= ((1 << (24 - operand->bits)) - 1); | 
 | 		  value |= temp; | 
 | 		  if ((operand->flags & MN10300_OPERAND_SIGNED) != 0) | 
 | 		    value = ((value & 0xffffff) ^ 0x800000) - 0x800000; | 
 | 		} | 
 | 	      else if ((operand->flags & (MN10300_OPERAND_FSREG | 
 | 					  | MN10300_OPERAND_FDREG))) | 
 | 		{ | 
 | 		  /* See m10300-opc.c just before #define FSM0 for an | 
 | 		     explanation of these variables.  Note that | 
 | 		     FMT-implied shifts are not taken into account for | 
 | 		     FP registers.  */ | 
 | 		  unsigned long mask_low, mask_high; | 
 | 		  int shl_low, shr_high, shl_high; | 
 |  | 
 | 		  switch (operand->bits) | 
 | 		    { | 
 | 		    case 5: | 
 | 		      /* Handle regular FP registers.  */ | 
 | 		      if (operand->shift >= 0) | 
 | 			{ | 
 | 			  /* This is an `m' register.  */ | 
 | 			  shl_low = operand->shift; | 
 | 			  shl_high = 8 + (8 & shl_low) + (shl_low & 4) / 4; | 
 | 			} | 
 | 		      else | 
 | 			{ | 
 | 			  /* This is an `n' register.  */ | 
 | 			  shl_low = -operand->shift; | 
 | 			  shl_high = shl_low / 4; | 
 | 			} | 
 | 		      mask_low = 0x0f; | 
 | 		      mask_high = 0x10; | 
 | 		      shr_high = 4; | 
 | 		      break; | 
 |  | 
 | 		    case 3: | 
 | 		      /* Handle accumulators.  */ | 
 | 		      shl_low = -operand->shift; | 
 | 		      shl_high = 0; | 
 | 		      mask_low = 0x03; | 
 | 		      mask_high = 0x04; | 
 | 		      shr_high = 2; | 
 | 		      break; | 
 |  | 
 | 		    default: | 
 | 		      abort (); | 
 | 		    } | 
 | 		  value = ((((insn >> shl_high) << shr_high) & mask_high) | 
 | 			   | ((insn >> shl_low) & mask_low)); | 
 | 		} | 
 | 	      else if ((operand->flags & MN10300_OPERAND_EXTENDED) != 0) | 
 | 		value = ((extension >> (operand->shift)) | 
 | 			 & ((1 << operand->bits) - 1)); | 
 |  | 
 | 	      else | 
 | 		value = ((insn >> (operand->shift)) | 
 | 			 & ((1 << operand->bits) - 1)); | 
 |  | 
 | 	      if ((operand->flags & MN10300_OPERAND_SIGNED) != 0 | 
 | 		  /* These are properly extended by the code above.  */ | 
 | 		  && ((operand->flags & MN10300_OPERAND_24BIT) == 0)) | 
 | 		value = ((value ^ (((unsigned long) 1) << (operand->bits - 1))) | 
 | 			 - (((unsigned long) 1) << (operand->bits - 1))); | 
 |  | 
 | 	      if (!nocomma | 
 | 		  && (!paren | 
 | 		      || ((operand->flags & MN10300_OPERAND_PAREN) == 0))) | 
 | 		(*info->fprintf_func) (info->stream, ","); | 
 |  | 
 | 	      nocomma = 0; | 
 |  | 
 | 	      if ((operand->flags & MN10300_OPERAND_DREG) != 0) | 
 | 		(*info->fprintf_func) (info->stream, "d%d", (int) value); | 
 |  | 
 | 	      else if ((operand->flags & MN10300_OPERAND_AREG) != 0) | 
 | 		(*info->fprintf_func) (info->stream, "a%d", (int) value); | 
 |  | 
 | 	      else if ((operand->flags & MN10300_OPERAND_SP) != 0) | 
 | 		(*info->fprintf_func) (info->stream, "sp"); | 
 |  | 
 | 	      else if ((operand->flags & MN10300_OPERAND_PSW) != 0) | 
 | 		(*info->fprintf_func) (info->stream, "psw"); | 
 |  | 
 | 	      else if ((operand->flags & MN10300_OPERAND_MDR) != 0) | 
 | 		(*info->fprintf_func) (info->stream, "mdr"); | 
 |  | 
 | 	      else if ((operand->flags & MN10300_OPERAND_RREG) != 0) | 
 | 		{ | 
 | 		  if (value < 8) | 
 | 		    (*info->fprintf_func) (info->stream, "r%d", (int) value); | 
 | 		  else if (value < 12) | 
 | 		    (*info->fprintf_func) (info->stream, "a%d", (int) value - 8); | 
 | 		  else | 
 | 		    (*info->fprintf_func) (info->stream, "d%d", (int) value - 12); | 
 | 		} | 
 |  | 
 | 	      else if ((operand->flags & MN10300_OPERAND_XRREG) != 0) | 
 | 		{ | 
 | 		  if (value == 0) | 
 | 		    (*info->fprintf_func) (info->stream, "sp"); | 
 | 		  else | 
 | 		    (*info->fprintf_func) (info->stream, "xr%d", (int) value); | 
 | 		} | 
 |  | 
 | 	      else if ((operand->flags & MN10300_OPERAND_FSREG) != 0) | 
 | 		(*info->fprintf_func) (info->stream, "fs%d", (int) value); | 
 |  | 
 | 	      else if ((operand->flags & MN10300_OPERAND_FDREG) != 0) | 
 | 		(*info->fprintf_func) (info->stream, "fd%d", (int) value); | 
 |  | 
 | 	      else if ((operand->flags & MN10300_OPERAND_FPCR) != 0) | 
 | 		(*info->fprintf_func) (info->stream, "fpcr"); | 
 |  | 
 | 	      else if ((operand->flags & MN10300_OPERAND_USP) != 0) | 
 | 		(*info->fprintf_func) (info->stream, "usp"); | 
 |  | 
 | 	      else if ((operand->flags & MN10300_OPERAND_SSP) != 0) | 
 | 		(*info->fprintf_func) (info->stream, "ssp"); | 
 |  | 
 | 	      else if ((operand->flags & MN10300_OPERAND_MSP) != 0) | 
 | 		(*info->fprintf_func) (info->stream, "msp"); | 
 |  | 
 | 	      else if ((operand->flags & MN10300_OPERAND_PC) != 0) | 
 | 		(*info->fprintf_func) (info->stream, "pc"); | 
 |  | 
 | 	      else if ((operand->flags & MN10300_OPERAND_EPSW) != 0) | 
 | 		(*info->fprintf_func) (info->stream, "epsw"); | 
 |  | 
 | 	      else if ((operand->flags & MN10300_OPERAND_PLUS) != 0) | 
 | 		(*info->fprintf_func) (info->stream, "+"); | 
 |  | 
 | 	      else if ((operand->flags & MN10300_OPERAND_PAREN) != 0) | 
 | 		{ | 
 | 		  if (paren) | 
 | 		    (*info->fprintf_func) (info->stream, ")"); | 
 | 		  else | 
 | 		    { | 
 | 		      (*info->fprintf_func) (info->stream, "("); | 
 | 		      nocomma = 1; | 
 | 		    } | 
 | 		  paren = !paren; | 
 | 		} | 
 |  | 
 | 	      else if ((operand->flags & MN10300_OPERAND_PCREL) != 0) | 
 | 		(*info->print_address_func) ((long) value + memaddr, info); | 
 |  | 
 | 	      else if ((operand->flags & MN10300_OPERAND_MEMADDR) != 0) | 
 | 		(*info->print_address_func) (value, info); | 
 |  | 
 | 	      else if ((operand->flags & MN10300_OPERAND_REG_LIST) != 0) | 
 | 		{ | 
 | 		  int comma = 0; | 
 |  | 
 | 		  (*info->fprintf_func) (info->stream, "["); | 
 | 		  if (value & 0x80) | 
 | 		    { | 
 | 		      (*info->fprintf_func) (info->stream, "d2"); | 
 | 		      comma = 1; | 
 | 		    } | 
 |  | 
 | 		  if (value & 0x40) | 
 | 		    { | 
 | 		      if (comma) | 
 | 			(*info->fprintf_func) (info->stream, ","); | 
 | 		      (*info->fprintf_func) (info->stream, "d3"); | 
 | 		      comma = 1; | 
 | 		    } | 
 |  | 
 | 		  if (value & 0x20) | 
 | 		    { | 
 | 		      if (comma) | 
 | 			(*info->fprintf_func) (info->stream, ","); | 
 | 		      (*info->fprintf_func) (info->stream, "a2"); | 
 | 		      comma = 1; | 
 | 		    } | 
 |  | 
 | 		  if (value & 0x10) | 
 | 		    { | 
 | 		      if (comma) | 
 | 			(*info->fprintf_func) (info->stream, ","); | 
 | 		      (*info->fprintf_func) (info->stream, "a3"); | 
 | 		      comma = 1; | 
 | 		    } | 
 |  | 
 | 		  if (value & 0x08) | 
 | 		    { | 
 | 		      if (comma) | 
 | 			(*info->fprintf_func) (info->stream, ","); | 
 | 		      (*info->fprintf_func) (info->stream, "other"); | 
 | 		      comma = 1; | 
 | 		    } | 
 |  | 
 | 		  if (value & 0x04) | 
 | 		    { | 
 | 		      if (comma) | 
 | 			(*info->fprintf_func) (info->stream, ","); | 
 | 		      (*info->fprintf_func) (info->stream, "exreg0"); | 
 | 		      comma = 1; | 
 | 		    } | 
 | 		  if (value & 0x02) | 
 | 		    { | 
 | 		      if (comma) | 
 | 			(*info->fprintf_func) (info->stream, ","); | 
 | 		      (*info->fprintf_func) (info->stream, "exreg1"); | 
 | 		      comma = 1; | 
 | 		    } | 
 | 		  if (value & 0x01) | 
 | 		    { | 
 | 		      if (comma) | 
 | 			(*info->fprintf_func) (info->stream, ","); | 
 | 		      (*info->fprintf_func) (info->stream, "exother"); | 
 | 		      comma = 1; | 
 | 		    } | 
 | 		  (*info->fprintf_func) (info->stream, "]"); | 
 | 		} | 
 |  | 
 | 	      else | 
 | 		(*info->fprintf_func) (info->stream, "%ld", (long) value); | 
 | 	    } | 
 | 	  /* All done. */ | 
 | 	  break; | 
 | 	} | 
 |       op++; | 
 |     } | 
 |  | 
 |   if (!match) | 
 |     /* xgettext:c-format */ | 
 |     (*info->fprintf_func) (info->stream, _("unknown\t0x%04lx"), insn); | 
 | } | 
 |  | 
 | int | 
 | print_insn_mn10300 (bfd_vma memaddr, struct disassemble_info *info) | 
 | { | 
 |   int status; | 
 |   bfd_byte buffer[4]; | 
 |   unsigned long insn; | 
 |   unsigned int consume; | 
 |  | 
 |   /* First figure out how big the opcode is.  */ | 
 |   status = (*info->read_memory_func) (memaddr, buffer, 1, info); | 
 |   if (status != 0) | 
 |     { | 
 |       (*info->memory_error_func) (status, memaddr, info); | 
 |       return -1; | 
 |     } | 
 |   insn = *(unsigned char *) buffer; | 
 |  | 
 |   /* These are one byte insns.  */ | 
 |   if ((insn & 0xf3) == 0x00 | 
 |       || (insn & 0xf0) == 0x10 | 
 |       || (insn & 0xfc) == 0x3c | 
 |       || (insn & 0xf3) == 0x41 | 
 |       || (insn & 0xf3) == 0x40 | 
 |       || (insn & 0xfc) == 0x50 | 
 |       || (insn & 0xfc) == 0x54 | 
 |       || (insn & 0xf0) == 0x60 | 
 |       || (insn & 0xf0) == 0x70 | 
 |       || ((insn & 0xf0) == 0x80 | 
 | 	  && (insn & 0x0c) >> 2 != (insn & 0x03)) | 
 |       || ((insn & 0xf0) == 0x90 | 
 | 	  && (insn & 0x0c) >> 2 != (insn & 0x03)) | 
 |       || ((insn & 0xf0) == 0xa0 | 
 | 	  && (insn & 0x0c) >> 2 != (insn & 0x03)) | 
 |       || ((insn & 0xf0) == 0xb0 | 
 | 	  && (insn & 0x0c) >> 2 != (insn & 0x03)) | 
 |       || (insn & 0xff) == 0xcb | 
 |       || (insn & 0xfc) == 0xd0 | 
 |       || (insn & 0xfc) == 0xd4 | 
 |       || (insn & 0xfc) == 0xd8 | 
 |       || (insn & 0xf0) == 0xe0 | 
 |       || (insn & 0xff) == 0xff) | 
 |     { | 
 |       consume = 1; | 
 |     } | 
 |  | 
 |   /* These are two byte insns.  */ | 
 |   else if ((insn & 0xf0) == 0x80 | 
 | 	   || (insn & 0xf0) == 0x90 | 
 | 	   || (insn & 0xf0) == 0xa0 | 
 | 	   || (insn & 0xf0) == 0xb0 | 
 | 	   || (insn & 0xfc) == 0x20 | 
 | 	   || (insn & 0xfc) == 0x28 | 
 | 	   || (insn & 0xf3) == 0x43 | 
 | 	   || (insn & 0xf3) == 0x42 | 
 | 	   || (insn & 0xfc) == 0x58 | 
 | 	   || (insn & 0xfc) == 0x5c | 
 | 	   || ((insn & 0xf0) == 0xc0 | 
 | 	       && (insn & 0xff) != 0xcb | 
 | 	       && (insn & 0xff) != 0xcc | 
 | 	       && (insn & 0xff) != 0xcd) | 
 | 	   || (insn & 0xff) == 0xf0 | 
 | 	   || (insn & 0xff) == 0xf1 | 
 | 	   || (insn & 0xff) == 0xf2 | 
 | 	   || (insn & 0xff) == 0xf3 | 
 | 	   || (insn & 0xff) == 0xf4 | 
 | 	   || (insn & 0xff) == 0xf5 | 
 | 	   || (insn & 0xff) == 0xf6) | 
 |     { | 
 |       status = (*info->read_memory_func) (memaddr, buffer, 2, info); | 
 |       if (status != 0) | 
 | 	{ | 
 | 	  (*info->memory_error_func) (status, memaddr, info); | 
 | 	  return -1; | 
 | 	} | 
 |       insn = bfd_getb16 (buffer); | 
 |       consume = 2; | 
 |     } | 
 |  | 
 |   /* These are three byte insns.  */ | 
 |   else if ((insn & 0xff) == 0xf8 | 
 | 	   || (insn & 0xff) == 0xcc | 
 | 	   || (insn & 0xff) == 0xf9 | 
 | 	   || (insn & 0xf3) == 0x01 | 
 | 	   || (insn & 0xf3) == 0x02 | 
 | 	   || (insn & 0xf3) == 0x03 | 
 | 	   || (insn & 0xfc) == 0x24 | 
 | 	   || (insn & 0xfc) == 0x2c | 
 | 	   || (insn & 0xfc) == 0x30 | 
 | 	   || (insn & 0xfc) == 0x34 | 
 | 	   || (insn & 0xfc) == 0x38 | 
 | 	   || (insn & 0xff) == 0xde | 
 | 	   || (insn & 0xff) == 0xdf | 
 | 	   || (insn & 0xff) == 0xf9 | 
 | 	   || (insn & 0xff) == 0xcc) | 
 |     { | 
 |       status = (*info->read_memory_func) (memaddr, buffer, 2, info); | 
 |       if (status != 0) | 
 | 	{ | 
 | 	  (*info->memory_error_func) (status, memaddr, info); | 
 | 	  return -1; | 
 | 	} | 
 |       insn = bfd_getb16 (buffer); | 
 |       insn <<= 8; | 
 |       status = (*info->read_memory_func) (memaddr + 2, buffer, 1, info); | 
 |       if (status != 0) | 
 | 	{ | 
 | 	  (*info->memory_error_func) (status, memaddr, info); | 
 | 	  return -1; | 
 | 	} | 
 |       insn |= *(unsigned char *) buffer; | 
 |       consume = 3; | 
 |     } | 
 |  | 
 |   /* These are four byte insns.  */ | 
 |   else if ((insn & 0xff) == 0xfa | 
 | 	   || (insn & 0xff) == 0xf7 | 
 | 	   || (insn & 0xff) == 0xfb) | 
 |     { | 
 |       status = (*info->read_memory_func) (memaddr, buffer, 4, info); | 
 |       if (status != 0) | 
 | 	{ | 
 | 	  (*info->memory_error_func) (status, memaddr, info); | 
 | 	  return -1; | 
 | 	} | 
 |       insn = bfd_getb32 (buffer); | 
 |       consume = 4; | 
 |     } | 
 |  | 
 |   /* These are five byte insns.  */ | 
 |   else if ((insn & 0xff) == 0xcd | 
 | 	   || (insn & 0xff) == 0xdc) | 
 |     { | 
 |       status = (*info->read_memory_func) (memaddr, buffer, 4, info); | 
 |       if (status != 0) | 
 | 	{ | 
 | 	  (*info->memory_error_func) (status, memaddr, info); | 
 | 	  return -1; | 
 | 	} | 
 |       insn = bfd_getb32 (buffer); | 
 |       consume = 5; | 
 |     } | 
 |  | 
 |   /* These are six byte insns.  */ | 
 |   else if ((insn & 0xff) == 0xfd | 
 | 	   || (insn & 0xff) == 0xfc) | 
 |     { | 
 |       status = (*info->read_memory_func) (memaddr, buffer, 4, info); | 
 |       if (status != 0) | 
 | 	{ | 
 | 	  (*info->memory_error_func) (status, memaddr, info); | 
 | 	  return -1; | 
 | 	} | 
 |  | 
 |       insn = bfd_getb32 (buffer); | 
 |       consume = 6; | 
 |     } | 
 |  | 
 |   /* Else its a seven byte insns (in theory).  */ | 
 |   else | 
 |     { | 
 |       status = (*info->read_memory_func) (memaddr, buffer, 4, info); | 
 |       if (status != 0) | 
 | 	{ | 
 | 	  (*info->memory_error_func) (status, memaddr, info); | 
 | 	  return -1; | 
 | 	} | 
 |  | 
 |       insn = bfd_getb32 (buffer); | 
 |       consume = 7; | 
 |       /* Handle the 5-byte extended instruction codes.  */ | 
 |       if ((insn & 0xfff80000) == 0xfe800000) | 
 | 	consume = 5; | 
 |     } | 
 |  | 
 |   disassemble (memaddr, info, insn, consume); | 
 |  | 
 |   return consume; | 
 | } |