summarylogtreecommitdiffstats
path: root/msp430-dis.c.patch
diff options
context:
space:
mode:
Diffstat (limited to 'msp430-dis.c.patch')
-rw-r--r--msp430-dis.c.patch890
1 files changed, 890 insertions, 0 deletions
diff --git a/msp430-dis.c.patch b/msp430-dis.c.patch
new file mode 100644
index 000000000000..95f210691b15
--- /dev/null
+++ b/msp430-dis.c.patch
@@ -0,0 +1,890 @@
+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 */