This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: [msp430-elf] Interrupt vector corrupted?
- From: Nick Clifton <nickc at redhat dot com>
- To: Orlando Arias <orlandoarias at gmail dot com>, DJ Delorie <dj at redhat dot com>
- Cc: binutils at sourceware dot org
- Date: Tue, 19 Apr 2016 11:54:07 +0100
- Subject: Re: [msp430-elf] Interrupt vector corrupted?
- Authentication-results: sourceware.org; auth=none
- References: <xnega2s1ym dot fsf at greed dot delorie dot com> <5715BB4B dot 8090105 at gmail dot com>
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 */