This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [msp430-elf] Interrupt vector corrupted?


Hi Orlando,

  First of all, it is best to report problems like this using the binutils
  bugzilla system.  That way we can keep track of the issue and refer back
  to it later if needed.

> The reason I am asking is because I am seeing extra data being added to
> the section and I am experiencing the microcontroller crash 

  The attached patch will stop objdump from displaying extra bytes in the 
  disassembly of the interrupt vector.  But, as DJ indicated, this is not
  the source of the problem you are experiencing.  Objdump was just displaying
  a couple of random bytes because of some poor coding which did not take
  into account the possibility of an attempt to read beyond the end of a
  section.  In practice however interrupt vector 47 really is only 2 bytes
  long, and there are no extraneous values being installed into the vector
  table.

  You can check this by examining the executable using readelf.  For example:

  % readelf --wide -S a.out

  [ 1] __interrupt_vector_47 PROGBITS        0000ffdc 0003d0 000002 00  AX  0   0  1
                                                              ^^^^^
                                                             the size
  % readelf -x1 a.out

  Hex dump of section '__interrupt_vector_47':
    0x0000ffdc c445                                .E



> As an addendum, I should add that the microcontroller resets when
> attempting to execute the ISR. The behaviour can not be replicated with
> USCI_A0_VECTOR [of course, enabling proper interrupts in either case].

  So does this mean that if you use USCI_A0_VECTOR your program works,
  but if you use USCI_A1_VECTOR it does not ?  I am not an MSP430 MCU
  expert, but to me this indicates that there is some kind of hardware
  based problem with using the A1 vector.

Cheers
  Nick
diff --git a/opcodes/msp430-dis.c b/opcodes/msp430-dis.c
index 676a2d8..c7490e9 100644
--- a/opcodes/msp430-dis.c
+++ b/opcodes/msp430-dis.c
@@ -36,8 +36,11 @@
 
 #define PS(x)   (0xffff & (x))
 
-static unsigned short
-msp430dis_opcode (bfd_vma addr, disassemble_info *info)
+static bfd_boolean
+msp430dis_opcode_unsigned (bfd_vma addr,
+			   disassemble_info *info,
+			   unsigned short * return_val,
+			   char * comm)
 {
   bfd_byte buffer[2];
   int status;
@@ -46,9 +49,38 @@ msp430dis_opcode (bfd_vma addr, disassemble_info *info)
   if (status != 0)
     {
       info->memory_error_func (status, addr, info);
-      return -1;
+      if (comm)
+	sprintf (comm, _("<memory read failed>"));
+      * return_val = 0;
+      return FALSE;
     }
-  return bfd_getl16 (buffer);
+  * return_val = bfd_getl16 (buffer);
+  return TRUE;
+}
+
+static bfd_boolean
+msp430dis_opcode_signed (bfd_vma addr,
+			 disassemble_info *info,
+			 signed int * return_val,
+			 char * comm)
+{
+  bfd_byte buffer[2];
+  int status;
+
+  status = info->read_memory_func (addr, buffer, 2, info);
+  if (status != 0)
+    {
+      info->memory_error_func (status, addr, info);
+      if (comm)
+	sprintf (comm, _("<memory read failed>"));
+      * return_val = 0;
+      return FALSE;
+    }
+  status = bfd_getl_signed_16 (buffer);
+  if (status & 0x8000)
+    status |= -1U << 16;
+  * return_val = status;
+  return TRUE;
 }
 
 static int
@@ -193,47 +225,51 @@ msp430_singleoperand (disassemble_info *info,
 	  if (regd == 0)
 	    {
 	      /* PC relative.  */
-	      dst = msp430dis_opcode (addr + 2, info);
-	      cmd_len += 2;
-	      *cycles = 4;
-	      sprintf (op, "0x%04x", dst);
-	      sprintf (comm, "PC rel. abs addr 0x%04x",
-		       PS ((short) (addr + 2) + dst));
-	      if (extended_dst)
+	      if (msp430dis_opcode_signed (addr + 2, info, &dst, comm))
 		{
-		  dst |= extended_dst << 16;
-		  sprintf (op, "0x%05x", dst);
-		  sprintf (comm, "PC rel. abs addr 0x%05lx",
-			   (long)((addr + 2 + dst) & 0xfffff));
+		  cmd_len += 2;
+		  *cycles = 4;
+		  sprintf (op, "0x%04x", dst);
+		  sprintf (comm, "PC rel. abs addr 0x%04x",
+			   PS ((short) (addr + 2) + dst));
+		  if (extended_dst)
+		    {
+		      dst |= extended_dst << 16;
+		      sprintf (op, "0x%05x", dst);
+		      sprintf (comm, "PC rel. abs addr 0x%05lx",
+			       (long)((addr + 2 + dst) & 0xfffff));
+		    }
 		}
 	    }
 	  else if (regd == 2)
 	    {
 	      /* Absolute.  */
-	      dst = msp430dis_opcode (addr + 2, info);
-	      cmd_len += 2;
-	      *cycles = 4;
-	      sprintf (op, "&0x%04x", PS (dst));
-	      if (extended_dst)
+	      if (msp430dis_opcode_signed (addr + 2, info, &dst, comm))
 		{
-		  dst |= extended_dst << 16;
-		  sprintf (op, "&0x%05x", dst & 0xfffff);
+		  cmd_len += 2;
+		  *cycles = 4;
+		  sprintf (op, "&0x%04x", PS (dst));
+		  if (extended_dst)
+		    {
+		      dst |= extended_dst << 16;
+		      sprintf (op, "&0x%05x", dst & 0xfffff);
+		    }
 		}
 	    }
 	  else
 	    {
-	      dst = msp430dis_opcode (addr + 2, info);
-	      cmd_len += 2;
-	      *cycles = 4;
-	      if (extended_dst)
+	      if (msp430dis_opcode_signed (addr + 2, info, &dst, comm))
 		{
-		  dst |= extended_dst << 16;
-		  if (dst & 0x80000)
-		    dst |= -1U << 20;
+		  cmd_len += 2;
+		  *cycles = 4;
+		  if (extended_dst)
+		    {
+		      dst |= extended_dst << 16;
+		      if (dst & 0x80000)
+			dst |= -1U << 20;
+		    }
+		  sprintf (op, "%d(r%d)", dst, regd);
 		}
-	      else if (dst & 0x8000)
-		dst |= -1U << 16;
-	      sprintf (op, "%d(r%d)", dst, regd);
 	    }
 	}
       break;
@@ -264,19 +300,21 @@ msp430_singleoperand (disassemble_info *info,
 	    {
 	      *cycles = 3;
 	      /* absolute. @pc+ */
-	      dst = msp430dis_opcode (addr + 2, info);
-	      cmd_len += 2;
-	      sprintf (op, "#%d", dst);
-	      if (dst > 9 || dst < 0)
-		sprintf (comm, "#0x%04x", PS (dst));
-	      if (extended_dst)
+	      if (msp430dis_opcode_signed (addr + 2, info, &dst, comm))
 		{
-		  dst |= extended_dst << 16;
-		  if (dst & 0x80000)
-		    dst |= -1U << 20;
+		  cmd_len += 2;
 		  sprintf (op, "#%d", dst);
 		  if (dst > 9 || dst < 0)
-		    sprintf (comm, "#0x%05x", dst);
+		    sprintf (comm, "#0x%04x", PS (dst));
+		  if (extended_dst)
+		    {
+		      dst |= extended_dst << 16;
+		      if (dst & 0x80000)
+			dst |= -1U << 20;
+		      sprintf (op, "#%d", dst);
+		      if (dst > 9 || dst < 0)
+			sprintf (comm, "#0x%05x", dst);
+		    }
 		}
 	    }
 	  else
@@ -288,29 +326,33 @@ msp430_singleoperand (disassemble_info *info,
 	  if (regd == 0)
 	    {
 	      /* PC relative.  */
-	      dst = msp430dis_opcode (addr + 2, info);
-	      cmd_len += 2;
-	      sprintf (op, "0x%04x", PS (dst));
-	      sprintf (comm, "PC rel. 0x%04x",
-		       PS ((short) addr + 2 + dst));
-	      if (extended_dst)
+	      if (msp430dis_opcode_signed (addr + 2, info, &dst, comm))
 		{
-		  dst |= extended_dst << 16;
-		  sprintf (op, "0x%05x", dst & 0xffff);
-		  sprintf (comm, "PC rel. 0x%05lx",
-			   (long)((addr + 2 + dst) & 0xfffff));
+		  cmd_len += 2;
+		  sprintf (op, "0x%04x", PS (dst));
+		  sprintf (comm, "PC rel. 0x%04x",
+			   PS ((short) addr + 2 + dst));
+		  if (extended_dst)
+		    {
+		      dst |= extended_dst << 16;
+		      sprintf (op, "0x%05x", dst & 0xffff);
+		      sprintf (comm, "PC rel. 0x%05lx",
+			       (long)((addr + 2 + dst) & 0xfffff));
+		    }
 		}
 	    }
 	  else if (regd == 2)
 	    {
 	      /* Absolute.  */
-	      dst = msp430dis_opcode (addr + 2, info);
-	      cmd_len += 2;
-	      sprintf (op, "&0x%04x", PS (dst));
-	      if (extended_dst)
+	      if (msp430dis_opcode_signed (addr + 2, info, &dst, comm))
 		{
-		  dst |= extended_dst << 16;
-		  sprintf (op, "&0x%05x", dst & 0xfffff);
+		  cmd_len += 2;
+		  sprintf (op, "&0x%04x", PS (dst));
+		  if (extended_dst)
+		    {
+		      dst |= extended_dst << 16;
+		      sprintf (op, "&0x%05x", dst & 0xfffff);
+		    }
 		}
 	    }
 	  else if (regd == 3)
@@ -322,19 +364,19 @@ msp430_singleoperand (disassemble_info *info,
 	  else
 	    {
 	      /* Indexed.  */
-	      dst = msp430dis_opcode (addr + 2, info);
-	      cmd_len += 2;
-	      if (extended_dst)
+	      if (msp430dis_opcode_signed (addr + 2, info, &dst, comm))
 		{
-		  dst |= extended_dst << 16;
-		  if (dst & 0x80000)
-		    dst |= -1U << 20;
+		  cmd_len += 2;
+		  if (extended_dst)
+		    {
+		      dst |= extended_dst << 16;
+		      if (dst & 0x80000)
+			dst |= -1U << 20;
+		    }
+		  sprintf (op, "%d(r%d)", dst, regd);
+		  if (dst > 9 || dst < 0)
+		    sprintf (comm, "%05x", dst);
 		}
-	      else if (dst & 0x8000)
-		dst |= -1U << 16;
-	      sprintf (op, "%d(r%d)", dst, regd);
-	      if (dst > 9 || dst < 0)
-		sprintf (comm, "%05x", dst);
 	    }
 	}
       break;
@@ -352,6 +394,7 @@ msp430_singleoperand (disassemble_info *info,
       *cycles = 2;
       return 2;
       break;
+
     default:
       cmd_len = 0;
     }
@@ -421,56 +464,65 @@ msp430_doubleoperand (disassemble_info *info,
 	  if (regd == 0)
 	    {
 	      /* PC relative, Symbolic.  */
-	      dst = msp430dis_opcode (addr + 2, info);
-	      cmd_len += 4;
-	      *cycles = 6;
-	      sprintf (op1, "0x%04x", PS (dst));
-	      sprintf (comm1, "PC rel. 0x%04x",
-		       PS ((short) addr + 2 + dst));
-	      if (extension_word)
+	      if (msp430dis_opcode_signed (addr + 2, info, &dst, comm1))
 		{
-		  dst |= extended_dst << 16;
-		  if (dst & 0x80000)
-		    dst |= -1U << 20;
-		  sprintf (op1, "0x%05x", dst & 0xfffff);
-		  sprintf (comm1, "PC rel. 0x%05lx",
-			   (long)((addr + 2 + dst) & 0xfffff));
+		  cmd_len += 4;
+		  *cycles = 6;
+		  sprintf (op1, "0x%04x", PS (dst));
+		  sprintf (comm1, "PC rel. 0x%04x",
+			   PS ((short) addr + 2 + dst));
+		  if (extension_word)
+		    {
+		      dst |= extended_dst << 16;
+		      if (dst & 0x80000)
+			dst |= -1U << 20;
+		      sprintf (op1, "0x%05x", dst & 0xfffff);
+		      sprintf (comm1, "PC rel. 0x%05lx",
+			       (long)((addr + 2 + dst) & 0xfffff));
+		    }
 		}
 	    }
 	  else if (regd == 2)
 	    {
 	      /* Absolute.  */
-	      dst = msp430dis_opcode (addr + 2, info);
-	      /* If the 'src' field is not the same as the dst
-		 then this is not an rla instruction.  */
-	      if (dst != msp430dis_opcode (addr + 4, info))
-		return 0;
-	      cmd_len += 4;
-	      *cycles = 6;
-	      sprintf (op1, "&0x%04x", PS (dst));
-	      if (extension_word)
+	      if (msp430dis_opcode_signed (addr + 2, info, &dst, comm1))
 		{
-		  dst |= extended_dst << 16;
-		  sprintf (op1, "&0x%05x", dst & 0xfffff);
+		  int src;
+
+		  /* If the 'src' field is not the same as the dst
+		     then this is not an rla instruction.  */
+		  if (msp430dis_opcode_signed (addr + 4, info, &src, comm2))
+		    {
+		      if (src != dst)
+			return 0;
+		    }
+		  cmd_len += 4;
+		  *cycles = 6;
+		  sprintf (op1, "&0x%04x", PS (dst));
+		  if (extension_word)
+		    {
+		      dst |= extended_dst << 16;
+		      sprintf (op1, "&0x%05x", dst & 0xfffff);
+		    }
 		}
 	    }
 	  else
 	    {
 	      /* Indexed.  */
-	      dst = msp430dis_opcode (addr + 2, info);
-	      if (extension_word)
+	      if (msp430dis_opcode_signed (addr + 2, info, &dst, comm1))
 		{
-		  dst |= extended_dst << 16;
-		  if (dst & 0x80000)
-		    dst |= -1U << 20;
+		  if (extension_word)
+		    {
+		      dst |= extended_dst << 16;
+		      if (dst & 0x80000)
+			dst |= -1U << 20;
+		    }
+		  cmd_len += 4;
+		  *cycles = 6;
+		  sprintf (op1, "%d(r%d)", dst, regd);
+		  if (dst > 9 || dst < -9)
+		    sprintf (comm1, "#0x%05x", dst);
 		}
-	      else if (dst & 0x8000)
-		dst |= -1U << 16;
-	      cmd_len += 4;
-	      *cycles = 6;
-	      sprintf (op1, "%d(r%d)", dst, regd);
-	      if (dst > 9 || dst < -9)
-		sprintf (comm1, "#0x%05x", dst);
 	    }
 	}
 
@@ -514,19 +566,22 @@ msp430_doubleoperand (disassemble_info *info,
 	{
 	  *cycles = 3;
 	  /* Absolute. @pc+.  */
-	  dst = msp430dis_opcode (addr + 2, info);
-	  cmd_len += 2;
-	  sprintf (op1, "#%d", dst);
-	  if (dst > 9 || dst < 0)
-	    sprintf (comm1, "#0x%04x", PS (dst));
-	  if (extension_word)
+	  if (msp430dis_opcode_signed (addr + 2, info, &dst, comm1))
 	    {
-	      dst |= extended_src << 16;
-	      if (dst & 0x80000)
-		dst |= -1U << 20;
+	      cmd_len += 2;
 	      sprintf (op1, "#%d", dst);
 	      if (dst > 9 || dst < 0)
-		sprintf (comm1, "0x%05x", dst & 0xfffff);
+		sprintf (comm1, "#0x%04x", PS (dst));
+	      if (extension_word)
+		{
+		  dst &= 0xffff;
+		  dst |= extended_src << 16;
+		  if (dst & 0x80000)
+		    dst |= -1U << 20;
+		  sprintf (op1, "#%d", dst);
+		  if (dst > 9 || dst < 0)
+		    sprintf (comm1, "0x%05x", dst & 0xfffff);
+		}
 	    }
 	}
       else
@@ -538,34 +593,40 @@ msp430_doubleoperand (disassemble_info *info,
 	{
 	  *cycles = 4;
 	  /* PC relative.  */
-	  dst = msp430dis_opcode (addr + 2, info);
-	  cmd_len += 2;
-	  sprintf (op1, "0x%04x", PS (dst));
-	  sprintf (comm1, "PC rel. 0x%04x",
-		   PS ((short) addr + 2 + dst));
-	  if (extension_word)
+	  if (msp430dis_opcode_signed (addr + 2, info, &dst, comm1))
 	    {
-	      dst |= extended_src << 16;
-	      if (dst & 0x80000)
-		dst |= -1U << 20;
-	      sprintf (op1, "0x%05x", dst & 0xfffff);
-	      sprintf (comm1, "PC rel. 0x%05lx",
-		       (long) ((addr + 2 + dst) & 0xfffff));
+	      cmd_len += 2;
+	      sprintf (op1, "0x%04x", PS (dst));
+	      sprintf (comm1, "PC rel. 0x%04x",
+		       PS ((short) addr + 2 + dst));
+	      if (extension_word)
+		{
+		  dst &= 0xffff;
+		  dst |= extended_src << 16;
+		  if (dst & 0x80000)
+		    dst |= -1U << 20;
+		  sprintf (op1, "0x%05x", dst & 0xfffff);
+		  sprintf (comm1, "PC rel. 0x%05lx",
+			   (long) ((addr + 2 + dst) & 0xfffff));
+		}
 	    }
 	}
       else if (regs == 2)
 	{
 	  *cycles = 2;
 	  /* Absolute.  */
-	  dst = msp430dis_opcode (addr + 2, info);
-	  cmd_len += 2;
-	  sprintf (op1, "&0x%04x", PS (dst));
-	  sprintf (comm1, "0x%04x", PS (dst));
-	  if (extension_word)
+	  if (msp430dis_opcode_signed (addr + 2, info, &dst, comm1))
 	    {
-	      dst |= extended_src << 16;
-	      sprintf (op1, "&0x%05x", dst & 0xfffff);
-	      * comm1 = 0;
+	      cmd_len += 2;
+	      sprintf (op1, "&0x%04x", PS (dst));
+	      sprintf (comm1, "0x%04x", PS (dst));
+	      if (extension_word)
+		{
+		  dst &= 0xffff;
+		  dst |= extended_src << 16;
+		  sprintf (op1, "&0x%05x", dst & 0xfffff);
+		  * comm1 = 0;
+		}
 	    }
 	}
       else if (regs == 3)
@@ -578,19 +639,20 @@ msp430_doubleoperand (disassemble_info *info,
 	{
 	  *cycles = 3;
 	  /* Indexed.  */
-	  dst = msp430dis_opcode (addr + 2, info);
-	  cmd_len += 2;
-	  if (extension_word)
+	  if (msp430dis_opcode_signed (addr + 2, info, &dst, comm1))
 	    {
-	      dst |= extended_src << 16;
-	      if (dst & 0x80000)
-		dst |= -1U << 20;
+	      cmd_len += 2;
+	      if (extension_word)
+		{
+		  dst &= 0xffff;
+		  dst |= extended_src << 16;
+		  if (dst & 0x80000)
+		    dst |= -1U << 20;
+		}
+	      sprintf (op1, "%d(r%d)", dst, regs);
+	      if (dst > 9 || dst < -9)
+		sprintf (comm1, "0x%05x", dst);
 	    }
-	  else if (dst & 0x8000)
-	    dst |= -1U << 16;
-	  sprintf (op1, "%d(r%d)", dst, regs);
-	  if (dst > 9 || dst < -9)
-	    sprintf (comm1, "0x%05x", dst);
 	}
     }
 
@@ -621,50 +683,54 @@ msp430_doubleoperand (disassemble_info *info,
 	{
 	  /* PC relative.  */
 	  *cycles += 1;
-	  dst = msp430dis_opcode (addr + cmd_len, info);
-	  sprintf (op2, "0x%04x", PS (dst));
-	  sprintf (comm2, "PC rel. 0x%04x",
-		   PS ((short) addr + cmd_len + dst));
-	  if (extension_word)
+	  if (msp430dis_opcode_signed (addr + cmd_len, info, &dst, comm2))
 	    {
-	      dst |= extended_dst << 16;
-	      if (dst & 0x80000)
-		dst |= -1U << 20;
-	      sprintf (op2, "0x%05x", dst & 0xfffff);
-	      sprintf (comm2, "PC rel. 0x%05lx",
-		       (long)((addr + cmd_len + dst) & 0xfffff));
+	      sprintf (op2, "0x%04x", PS (dst));
+	      sprintf (comm2, "PC rel. 0x%04x",
+		       PS ((short) addr + cmd_len + dst));
+	      if (extension_word)
+		{
+		  dst |= extended_dst << 16;
+		  if (dst & 0x80000)
+		    dst |= -1U << 20;
+		  sprintf (op2, "0x%05x", dst & 0xfffff);
+		  sprintf (comm2, "PC rel. 0x%05lx",
+			   (long)((addr + cmd_len + dst) & 0xfffff));
+		}
 	    }
 	  cmd_len += 2;
 	}
       else if (regd == 2)
 	{
 	  /* Absolute.  */
-	  dst = msp430dis_opcode (addr + cmd_len, info);
-	  cmd_len += 2;
-	  sprintf (op2, "&0x%04x", PS (dst));
-	  if (extension_word)
+	  if (msp430dis_opcode_signed (addr + cmd_len, info, &dst, comm2))
 	    {
-	      dst |= extended_dst << 16;
-	      sprintf (op2, "&0x%05x", dst & 0xfffff);
+	      cmd_len += 2;
+	      sprintf (op2, "&0x%04x", PS (dst));
+	      if (extension_word)
+		{
+		  dst |= extended_dst << 16;
+		  sprintf (op2, "&0x%05x", dst & 0xfffff);
+		}
 	    }
 	}
       else
 	{
-	  dst = msp430dis_opcode (addr + cmd_len, info);
-	  cmd_len += 2;
-	  if (dst & 0x8000)
-	    dst |= -1U << 16;
-	  if (dst > 9 || dst < 0)
-	    sprintf (comm2, "0x%04x", PS (dst));
-	  if (extension_word)
+	  if (msp430dis_opcode_signed (addr + cmd_len, info, &dst, comm2))
 	    {
-	      dst |= extended_dst << 16;
-	      if (dst & 0x80000)
-		dst |= -1U << 20;
+	      cmd_len += 2;
 	      if (dst > 9 || dst < 0)
-		sprintf (comm2, "0x%05x", dst & 0xfffff);
+		sprintf (comm2, "0x%04x", PS (dst));
+	      if (extension_word)
+		{
+		  dst |= extended_dst << 16;
+		  if (dst & 0x80000)
+		    dst |= -1U << 20;
+		  if (dst > 9 || dst < 0)
+		    sprintf (comm2, "0x%05x", dst & 0xfffff);
+		}
+	      sprintf (op2, "%d(r%d)", dst, regd);
 	    }
-	  sprintf (op2, "%d(r%d)", dst, regd);
 	}
     }
 
@@ -683,7 +749,8 @@ msp430_branchinstr (disassemble_info *info,
   int regs = 0, regd = 0;
   int as = 0;
   int cmd_len = 2;
-  short dst = 0;
+  int dst = 0;
+  unsigned short udst = 0;
 
   regd = insn & 0x0f;
   regs = (insn & 0x0f00) >> 8;
@@ -719,9 +786,11 @@ msp430_branchinstr (disassemble_info *info,
 	{
 	  /* Absolute. @pc+  */
 	  *cycles = 3;
-	  dst = msp430dis_opcode (addr + 2, info);
-	  cmd_len += 2;
-	  sprintf (op1, "#0x%04x", PS (dst));
+	  if (msp430dis_opcode_unsigned (addr + 2, info, &udst, comm1))
+	    {
+	      cmd_len += 2;
+	      sprintf (op1, "#0x%04x", PS (udst));
+	    }
 	}
       else
 	* cycles = print_as3_reg_name (regs, op1, comm1, 1, 1, 2);
@@ -733,19 +802,23 @@ msp430_branchinstr (disassemble_info *info,
       if (regs == 0)
 	{
 	  /* PC relative.  */
-	  dst = msp430dis_opcode (addr + 2, info);
-	  cmd_len += 2;
-	  (*cycles)++;
-	  sprintf (op1, "0x%04x", PS (dst));
-	  sprintf (comm1, "PC rel. 0x%04x",
-		   PS ((short) addr + 2 + dst));
+	  if (msp430dis_opcode_signed (addr + 2, info, &dst, comm1))
+	    {
+	      cmd_len += 2;
+	      (*cycles)++;
+	      sprintf (op1, "0x%04x", PS (dst));
+	      sprintf (comm1, "PC rel. 0x%04x",
+		       PS ((short) addr + 2 + dst));
+	    }
 	}
       else if (regs == 2)
 	{
 	  /* Absolute.  */
-	  dst = msp430dis_opcode (addr + 2, info);
-	  cmd_len += 2;
-	  sprintf (op1, "&0x%04x", PS (dst));
+	  if (msp430dis_opcode_unsigned (addr + 2, info, &udst, comm1))
+	    {
+	      cmd_len += 2;
+	      sprintf (op1, "&0x%04x", PS (udst));
+	    }
 	}
       else if (regs == 3)
 	{
@@ -756,11 +829,11 @@ msp430_branchinstr (disassemble_info *info,
       else
 	{
 	  /* Indexed.  */
-	  dst = msp430dis_opcode (addr + 2, info);
-	  cmd_len += 2;
-	  if (dst & 0x8000)
-	    dst |= -1U << 16;
-	  sprintf (op1, "%d(r%d)", dst, regs);
+	  if (msp430dis_opcode_signed (addr + 2, info, &dst, comm1))
+	    {
+	      cmd_len += 2;
+	      sprintf (op1, "%d(r%d)", dst, regs);
+	    }
 	}
     }
 
@@ -780,7 +853,7 @@ msp430x_calla_instr (disassemble_info * info,
   int            am = (insn & 0xf0) >> 4;
   int            cmd_len = 2;
   unsigned short udst = 0;
-  short          dst = 0;
+  int            dst = 0;
 
   switch (am)
     {
@@ -791,13 +864,15 @@ msp430x_calla_instr (disassemble_info * info,
 
     case 5: /* CALLA x(Rdst) */
       *cycles = 3;
-      dst = msp430dis_opcode (addr + 2, info);
-      cmd_len += 2;
-      sprintf (op1, "%d(r%d)", dst, reg);
-      if (reg == 0)
-	sprintf (comm1, "PC rel. 0x%05lx", (long) (addr + 2 + dst));
-      else
-	sprintf (comm1, "0x%05x", dst);
+      if (msp430dis_opcode_signed (addr + 2, info, &dst, comm1))
+	{
+	  cmd_len += 2;
+	  sprintf (op1, "%d(r%d)", dst, reg);
+	  if (reg == 0)
+	    sprintf (comm1, "PC rel. 0x%05lx", (long) (addr + 2 + dst));
+	  else
+	    sprintf (comm1, "0x%05x", dst);
+	}
       break;
 
     case 6: /* CALLA @Rdst */
@@ -811,28 +886,34 @@ msp430x_calla_instr (disassemble_info * info,
       break;
 
     case 8: /* CALLA &abs20 */
-      udst = msp430dis_opcode (addr + 2, info);
-      cmd_len += 2;
-      *cycles = 4;
-      sprintf (op1, "&%d", (ureg << 16) + udst);
-      sprintf (comm1, "0x%05x", (ureg << 16) + udst);
+      if (msp430dis_opcode_unsigned (addr + 2, info, &udst, comm1))
+	{
+	  cmd_len += 2;
+	  *cycles = 4;
+	  sprintf (op1, "&%d", (ureg << 16) + udst);
+	  sprintf (comm1, "0x%05x", (ureg << 16) + udst);
+	}
       break;
 
     case 9: /* CALLA pcrel-sym */
-      dst = msp430dis_opcode (addr + 2, info);
-      cmd_len += 2;
-      *cycles = 4;
-      sprintf (op1, "%d(PC)", (reg << 16) + dst);
-      sprintf (comm1, "PC rel. 0x%05lx",
-	       (long) (addr + 2 + dst + (reg << 16)));
+      if (msp430dis_opcode_signed (addr + 2, info, &dst, comm1))
+	{
+	  cmd_len += 2;
+	  *cycles = 4;
+	  sprintf (op1, "%d(PC)", (reg << 16) + dst);
+	  sprintf (comm1, "PC rel. 0x%05lx",
+		   (long) (addr + 2 + dst + (reg << 16)));
+	}
       break;
 
     case 11: /* CALLA #imm20 */
-      udst = msp430dis_opcode (addr + 2, info);
-      cmd_len += 2;
-      *cycles = 4;
-      sprintf (op1, "#%d", (ureg << 16) + udst);
-      sprintf (comm1, "0x%05x", (ureg << 16) + udst);
+      if (msp430dis_opcode_unsigned (addr + 2, info, &udst, comm1))
+	{
+	  cmd_len += 2;
+	  *cycles = 4;
+	  sprintf (op1, "#%d", (ureg << 16) + udst);
+	  sprintf (comm1, "0x%05x", (ureg << 16) + udst);
+	}
       break;
 
     default:
@@ -855,9 +936,9 @@ print_insn_msp430 (bfd_vma addr, disassemble_info *info)
   int cycles = 0;
   char *bc = "";
   unsigned short extension_word = 0;
+  unsigned short bits;
 
-  insn = msp430dis_opcode (addr, info);
-  if (insn == (unsigned short) -1)
+  if (! msp430dis_opcode_unsigned (addr, info, &insn, NULL))
     {
       prin (stream, ".word	0xffff;	????");
       return 2;
@@ -877,8 +958,7 @@ print_insn_msp430 (bfd_vma addr, disassemble_info *info)
     {
       extension_word = insn;
       addr += 2;
-      insn = msp430dis_opcode (addr, info);
-      if (insn == (unsigned short) -1)
+      if (! msp430dis_opcode_unsigned (addr, info, &insn, NULL))
 	{
 	  prin (stream, ".word	0x%04x, 0xffff;	????",
 		extension_word);
@@ -963,10 +1043,13 @@ print_insn_msp430 (bfd_vma addr, disassemble_info *info)
 	      else
 		{
 		  n <<= 16;
-		  n |= msp430dis_opcode (addr + 2, info);
-		  sprintf (op1, "#%d", n);
-		  if (n > 9 || n < 0)
-		    sprintf (comm1, "0x%05x", n);
+		  if (msp430dis_opcode_unsigned (addr + 2, info, &bits, comm1))
+		    {
+		      n |= bits;
+		      sprintf (op1, "#%d", n);
+		      if (n > 9 || n < 0)
+			sprintf (comm1, "0x%05x", n);
+		    }
 		  cmd_len = 4;
 		}
 	      sprintf (op2, "r%d", reg);
@@ -998,12 +1081,15 @@ print_insn_msp430 (bfd_vma addr, disassemble_info *info)
 		case 2: /* MOVA &abs20, Rdst */
 		  cmd_len = 4;
 		  n <<= 16;
-		  n |= msp430dis_opcode (addr + 2, info);
-		  sprintf (op1, "&%d", n);
-		  if (n > 9 || n < 0)
-		    sprintf (comm1, "0x%05x", n);
-		  if (strcmp (opcode->name, "bra") != 0)
-		    sprintf (op2, "r%d", reg);
+		  if (msp430dis_opcode_unsigned (addr + 2, info, &bits, comm1))
+		    {
+		      n |= bits;
+		      sprintf (op1, "&%d", n);
+		      if (n > 9 || n < 0)
+			sprintf (comm1, "0x%05x", n);
+		      if (strcmp (opcode->name, "bra") != 0)
+			sprintf (op2, "r%d", reg);
+		    }
 		  break;
 
 		case 3: /* MOVA x(Rsrc), Rdst */
@@ -1011,58 +1097,64 @@ print_insn_msp430 (bfd_vma addr, disassemble_info *info)
 		  if (strcmp (opcode->name, "bra") != 0)
 		    sprintf (op2, "r%d", reg);
 		  reg = n;
-		  n = msp430dis_opcode (addr + 2, info);
-		  if (n & 0x8000)
-		    n |= -1U << 16;
-		  sprintf (op1, "%d(r%d)", n, reg);
-		  if (n > 9 || n < 0)
+		  if (msp430dis_opcode_signed (addr + 2, info, &n, comm1))
 		    {
-		      if (reg == 0)
-			sprintf (comm1, "PC rel. 0x%05lx",
-				 (long) (addr + 2 + n));
-		      else
-			sprintf (comm1, "0x%05x", n);
+		      sprintf (op1, "%d(r%d)", n, reg);
+		      if (n > 9 || n < 0)
+			{
+			  if (reg == 0)
+			    sprintf (comm1, "PC rel. 0x%05lx",
+				     (long) (addr + 2 + n));
+			  else
+			    sprintf (comm1, "0x%05x", n);
+			}
 		    }
 		  break;
 
 		case 6: /* MOVA Rsrc, &abs20 */
 		  cmd_len = 4;
 		  reg <<= 16;
-		  reg |= msp430dis_opcode (addr + 2, info);
-		  sprintf (op1, "r%d", n);
-		  sprintf (op2, "&%d", reg);
-		  if (reg > 9 || reg < 0)
-		    sprintf (comm2, "0x%05x", reg);
+		  if (msp430dis_opcode_unsigned (addr + 2, info, &bits, comm2))
+		    {
+		      reg |= bits;
+		      sprintf (op1, "r%d", n);
+		      sprintf (op2, "&%d", reg);
+		      if (reg > 9 || reg < 0)
+			sprintf (comm2, "0x%05x", reg);
+		    }
 		  break;
 
 		case 7: /* MOVA Rsrc, x(Rdst) */
 		  cmd_len = 4;
 		  sprintf (op1, "r%d", n);
-		  n = msp430dis_opcode (addr + 2, info);
-		  if (n & 0x8000)
-		    n |= -1U << 16;
-		  sprintf (op2, "%d(r%d)", n, reg);
-		  if (n > 9 || n < 0)
+		  if (msp430dis_opcode_signed (addr + 2, info, &n, comm2))
 		    {
-		      if (reg == 0)
-			sprintf (comm2, "PC rel. 0x%05lx",
-				 (long) (addr + 2 + n));
-		      else
-			sprintf (comm2, "0x%05x", n);
+		      sprintf (op2, "%d(r%d)", n, reg);
+		      if (n > 9 || n < 0)
+			{
+			  if (reg == 0)
+			    sprintf (comm2, "PC rel. 0x%05lx",
+				     (long) (addr + 2 + n));
+			  else
+			    sprintf (comm2, "0x%05x", n);
+			}
 		    }
 		  break;
 
 		case 8: /* MOVA #imm20, Rdst */
 		  cmd_len = 4;
 		  n <<= 16;
-		  n |= msp430dis_opcode (addr + 2, info);
-		  if (n & 0x80000)
-		    n |= -1U << 20;
-		  sprintf (op1, "#%d", n);
-		  if (n > 9 || n < 0)
-		    sprintf (comm1, "0x%05x", n);
-		  if (strcmp (opcode->name, "bra") != 0)
-		    sprintf (op2, "r%d", reg);
+		  if (msp430dis_opcode_unsigned (addr + 2, info, &bits, comm1))
+		    {
+		      n |= bits;
+		      if (n & 0x80000)
+			n |= -1U << 20;
+		      sprintf (op1, "#%d", n);
+		      if (n > 9 || n < 0)
+			sprintf (comm1, "0x%05x", n);
+		      if (strcmp (opcode->name, "bra") != 0)
+			sprintf (op2, "r%d", reg);
+		    }
 		  break;
 
 		case 12: /* MOVA Rsrc, Rdst */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]