diff options
Diffstat (limited to 'msp430-dis.c.patch')
-rw-r--r-- | msp430-dis.c.patch | 890 |
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 */ |