Improve the MSP430 disassembler's handling of memory read errors.
PR target/20150 * msp430-dis.c (msp430dis_read_two_bytes): New function. (msp430dis_opcode_unsigned): New function. (msp430dis_opcode_signed): New function. (msp430_singleoperand): Use the new opcode reading functions. Only disassenmble bytes if they were successfully read. (msp430_doubleoperand): Likewise. (msp430_branchinstr): Likewise. (msp430x_callx_instr): Likewise. (print_insn_msp430): Check that it is safe to read bytes before attempting disassembly. Use the new opcode reading functions.
This commit is contained in:
parent
51415b9f30
commit
77d66e7b30
2 changed files with 408 additions and 272 deletions
|
@ -1,3 +1,17 @@
|
|||
2016-05-27 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
PR target/20150
|
||||
* msp430-dis.c (msp430dis_read_two_bytes): New function.
|
||||
(msp430dis_opcode_unsigned): New function.
|
||||
(msp430dis_opcode_signed): New function.
|
||||
(msp430_singleoperand): Use the new opcode reading functions.
|
||||
Only disassenmble bytes if they were successfully read.
|
||||
(msp430_doubleoperand): Likewise.
|
||||
(msp430_branchinstr): Likewise.
|
||||
(msp430x_callx_instr): Likewise.
|
||||
(print_insn_msp430): Check that it is safe to read bytes before
|
||||
attempting disassembly. Use the new opcode reading functions.
|
||||
|
||||
2016-05-26 Peter Bergner <bergner@vnet.ibm.com>
|
||||
|
||||
* ppc-opc.c (CY): New define. Document it.
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "dis-asm.h"
|
||||
#include "opintl.h"
|
||||
|
@ -36,19 +37,80 @@
|
|||
|
||||
#define PS(x) (0xffff & (x))
|
||||
|
||||
static unsigned short
|
||||
msp430dis_opcode (bfd_vma addr, disassemble_info *info)
|
||||
static bfd_boolean
|
||||
msp430dis_read_two_bytes (bfd_vma addr,
|
||||
disassemble_info * info,
|
||||
bfd_byte * buffer,
|
||||
char * comm)
|
||||
{
|
||||
bfd_byte buffer[2];
|
||||
int status;
|
||||
|
||||
status = info->read_memory_func (addr, buffer, 2, info);
|
||||
if (status != 0)
|
||||
if (status == 0)
|
||||
return TRUE;
|
||||
|
||||
/* PR 20150: A status of EIO means that there were no more bytes left
|
||||
to read in the current section. This can happen when disassembling
|
||||
interrupt vectors for example. Avoid cluttering the output with
|
||||
unhelpful error messages in this case. */
|
||||
if (status == EIO)
|
||||
{
|
||||
if (comm)
|
||||
sprintf (comm, _("Warning: disassembly unreliable - not enough bytes available"));
|
||||
}
|
||||
else
|
||||
{
|
||||
info->memory_error_func (status, addr, info);
|
||||
return -1;
|
||||
if (comm)
|
||||
sprintf (comm, _("Error: read from memory failed"));
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static bfd_boolean
|
||||
msp430dis_opcode_unsigned (bfd_vma addr,
|
||||
disassemble_info * info,
|
||||
unsigned short * return_val,
|
||||
char * comm)
|
||||
{
|
||||
bfd_byte buffer[2];
|
||||
|
||||
if (msp430dis_read_two_bytes (addr, info, buffer, comm))
|
||||
{
|
||||
* return_val = bfd_getl16 (buffer);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
* return_val = 0;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static bfd_boolean
|
||||
msp430dis_opcode_signed (bfd_vma addr,
|
||||
disassemble_info * info,
|
||||
signed int * return_val,
|
||||
char * comm)
|
||||
{
|
||||
bfd_byte buffer[2];
|
||||
|
||||
if (msp430dis_read_two_bytes (addr, info, buffer, comm))
|
||||
{
|
||||
int status;
|
||||
|
||||
status = bfd_getl_signed_16 (buffer);
|
||||
if (status & 0x8000)
|
||||
status |= -1U << 16;
|
||||
* return_val = status;
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
* return_val = 0;
|
||||
return FALSE;
|
||||
}
|
||||
return bfd_getl16 (buffer);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -193,47 +255,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 +330,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 +356,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 +394,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 +424,7 @@ msp430_singleoperand (disassemble_info *info,
|
|||
*cycles = 2;
|
||||
return 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
cmd_len = 0;
|
||||
}
|
||||
|
@ -409,7 +482,7 @@ msp430_doubleoperand (disassemble_info *info,
|
|||
/* Register mode. */
|
||||
if (regd == 3)
|
||||
{
|
||||
strcpy (comm1, _("Illegal as emulation instr"));
|
||||
strcpy (comm1, _("Warning: illegal as emulation instr"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -421,56 +494,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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -484,7 +566,7 @@ msp430_doubleoperand (disassemble_info *info,
|
|||
if (ad == 0 && regd == 3)
|
||||
{
|
||||
/* R2/R3 are illegal as dest: may be data section. */
|
||||
strcpy (comm1, _("Illegal as 2-op instr"));
|
||||
strcpy (comm1, _("Warning: illegal as 2-op instr"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -514,19 +596,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 +623,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 +669,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 +713,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 +779,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 +816,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 +832,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 +859,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 +883,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 +894,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,32 +916,38 @@ 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:
|
||||
strcpy (comm1, _("unrecognised CALLA addressing mode"));
|
||||
strcpy (comm1, _("Warning: unrecognised CALLA addressing mode"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -855,9 +966,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 +988,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 +1073,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 +1111,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 +1127,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 */
|
||||
|
@ -1107,7 +1229,7 @@ print_insn_msp430 (bfd_vma addr, disassemble_info *info)
|
|||
else
|
||||
{
|
||||
bc = ".?";
|
||||
sprintf (comm2, _("Reserved use of A/L and B/W bits detected"));
|
||||
sprintf (comm2, _("Warning: reserved use of A/L and B/W bits detected"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1124,7 +1246,7 @@ print_insn_msp430 (bfd_vma addr, disassemble_info *info)
|
|||
if (insn & BYTE_OPERATION)
|
||||
{
|
||||
bc = ".?";
|
||||
sprintf (comm2, _("Reserved use of A/L and B/W bits detected"));
|
||||
sprintf (comm2, _("Warning: reserved use of A/L and B/W bits detected"));
|
||||
}
|
||||
else if (extension_word & BYTE_OPERATION)
|
||||
bc = ".w";
|
||||
|
@ -1145,7 +1267,7 @@ print_insn_msp430 (bfd_vma addr, disassemble_info *info)
|
|||
else
|
||||
{
|
||||
bc = ".?";
|
||||
sprintf (comm2, _("Reserved use of A/L and B/W bits detected"));
|
||||
sprintf (comm2, _("Warning: reserved use of A/L and B/W bits detected"));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
Loading…
Reference in a new issue