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,7 +255,8 @@ msp430_singleoperand (disassemble_info *info,
|
|||
if (regd == 0)
|
||||
{
|
||||
/* PC relative. */
|
||||
dst = msp430dis_opcode (addr + 2, info);
|
||||
if (msp430dis_opcode_signed (addr + 2, info, &dst, comm))
|
||||
{
|
||||
cmd_len += 2;
|
||||
*cycles = 4;
|
||||
sprintf (op, "0x%04x", dst);
|
||||
|
@ -207,10 +270,12 @@ msp430_singleoperand (disassemble_info *info,
|
|||
(long)((addr + 2 + dst) & 0xfffff));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (regd == 2)
|
||||
{
|
||||
/* Absolute. */
|
||||
dst = msp430dis_opcode (addr + 2, info);
|
||||
if (msp430dis_opcode_signed (addr + 2, info, &dst, comm))
|
||||
{
|
||||
cmd_len += 2;
|
||||
*cycles = 4;
|
||||
sprintf (op, "&0x%04x", PS (dst));
|
||||
|
@ -220,9 +285,11 @@ msp430_singleoperand (disassemble_info *info,
|
|||
sprintf (op, "&0x%05x", dst & 0xfffff);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dst = msp430dis_opcode (addr + 2, info);
|
||||
if (msp430dis_opcode_signed (addr + 2, info, &dst, comm))
|
||||
{
|
||||
cmd_len += 2;
|
||||
*cycles = 4;
|
||||
if (extended_dst)
|
||||
|
@ -231,11 +298,10 @@ msp430_singleoperand (disassemble_info *info,
|
|||
if (dst & 0x80000)
|
||||
dst |= -1U << 20;
|
||||
}
|
||||
else if (dst & 0x8000)
|
||||
dst |= -1U << 16;
|
||||
sprintf (op, "%d(r%d)", dst, regd);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: /* rrc, push, call, swpb, rra, sxt, push, call, reti etc... */
|
||||
|
@ -264,7 +330,8 @@ msp430_singleoperand (disassemble_info *info,
|
|||
{
|
||||
*cycles = 3;
|
||||
/* absolute. @pc+ */
|
||||
dst = msp430dis_opcode (addr + 2, info);
|
||||
if (msp430dis_opcode_signed (addr + 2, info, &dst, comm))
|
||||
{
|
||||
cmd_len += 2;
|
||||
sprintf (op, "#%d", dst);
|
||||
if (dst > 9 || dst < 0)
|
||||
|
@ -279,6 +346,7 @@ msp430_singleoperand (disassemble_info *info,
|
|||
sprintf (comm, "#0x%05x", dst);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
* cycles = print_as3_reg_name (regd, op, comm, 1, 1, 3);
|
||||
}
|
||||
|
@ -288,7 +356,8 @@ msp430_singleoperand (disassemble_info *info,
|
|||
if (regd == 0)
|
||||
{
|
||||
/* PC relative. */
|
||||
dst = msp430dis_opcode (addr + 2, info);
|
||||
if (msp430dis_opcode_signed (addr + 2, info, &dst, comm))
|
||||
{
|
||||
cmd_len += 2;
|
||||
sprintf (op, "0x%04x", PS (dst));
|
||||
sprintf (comm, "PC rel. 0x%04x",
|
||||
|
@ -301,10 +370,12 @@ msp430_singleoperand (disassemble_info *info,
|
|||
(long)((addr + 2 + dst) & 0xfffff));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (regd == 2)
|
||||
{
|
||||
/* Absolute. */
|
||||
dst = msp430dis_opcode (addr + 2, info);
|
||||
if (msp430dis_opcode_signed (addr + 2, info, &dst, comm))
|
||||
{
|
||||
cmd_len += 2;
|
||||
sprintf (op, "&0x%04x", PS (dst));
|
||||
if (extended_dst)
|
||||
|
@ -313,6 +384,7 @@ msp430_singleoperand (disassemble_info *info,
|
|||
sprintf (op, "&0x%05x", dst & 0xfffff);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (regd == 3)
|
||||
{
|
||||
*cycles = 1;
|
||||
|
@ -322,7 +394,8 @@ msp430_singleoperand (disassemble_info *info,
|
|||
else
|
||||
{
|
||||
/* Indexed. */
|
||||
dst = msp430dis_opcode (addr + 2, info);
|
||||
if (msp430dis_opcode_signed (addr + 2, info, &dst, comm))
|
||||
{
|
||||
cmd_len += 2;
|
||||
if (extended_dst)
|
||||
{
|
||||
|
@ -330,13 +403,12 @@ msp430_singleoperand (disassemble_info *info,
|
|||
if (dst & 0x80000)
|
||||
dst |= -1U << 20;
|
||||
}
|
||||
else if (dst & 0x8000)
|
||||
dst |= -1U << 16;
|
||||
sprintf (op, "%d(r%d)", dst, regd);
|
||||
if (dst > 9 || dst < 0)
|
||||
sprintf (comm, "%05x", dst);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 3: /* Jumps. */
|
||||
|
@ -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,7 +494,8 @@ msp430_doubleoperand (disassemble_info *info,
|
|||
if (regd == 0)
|
||||
{
|
||||
/* PC relative, Symbolic. */
|
||||
dst = msp430dis_opcode (addr + 2, info);
|
||||
if (msp430dis_opcode_signed (addr + 2, info, &dst, comm1))
|
||||
{
|
||||
cmd_len += 4;
|
||||
*cycles = 6;
|
||||
sprintf (op1, "0x%04x", PS (dst));
|
||||
|
@ -437,14 +511,21 @@ msp430_doubleoperand (disassemble_info *info,
|
|||
(long)((addr + 2 + dst) & 0xfffff));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (regd == 2)
|
||||
{
|
||||
/* Absolute. */
|
||||
dst = msp430dis_opcode (addr + 2, info);
|
||||
if (msp430dis_opcode_signed (addr + 2, info, &dst, comm1))
|
||||
{
|
||||
int src;
|
||||
|
||||
/* 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))
|
||||
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));
|
||||
|
@ -454,18 +535,18 @@ msp430_doubleoperand (disassemble_info *info,
|
|||
sprintf (op1, "&0x%05x", dst & 0xfffff);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Indexed. */
|
||||
dst = msp430dis_opcode (addr + 2, info);
|
||||
if (msp430dis_opcode_signed (addr + 2, info, &dst, comm1))
|
||||
{
|
||||
if (extension_word)
|
||||
{
|
||||
dst |= extended_dst << 16;
|
||||
if (dst & 0x80000)
|
||||
dst |= -1U << 20;
|
||||
}
|
||||
else if (dst & 0x8000)
|
||||
dst |= -1U << 16;
|
||||
cmd_len += 4;
|
||||
*cycles = 6;
|
||||
sprintf (op1, "%d(r%d)", dst, regd);
|
||||
|
@ -473,6 +554,7 @@ msp430_doubleoperand (disassemble_info *info,
|
|||
sprintf (comm1, "#0x%05x", dst);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*op2 = 0;
|
||||
*comm2 = 0;
|
||||
|
@ -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,13 +596,15 @@ msp430_doubleoperand (disassemble_info *info,
|
|||
{
|
||||
*cycles = 3;
|
||||
/* Absolute. @pc+. */
|
||||
dst = msp430dis_opcode (addr + 2, info);
|
||||
if (msp430dis_opcode_signed (addr + 2, info, &dst, comm1))
|
||||
{
|
||||
cmd_len += 2;
|
||||
sprintf (op1, "#%d", dst);
|
||||
if (dst > 9 || dst < 0)
|
||||
sprintf (comm1, "#0x%04x", PS (dst));
|
||||
if (extension_word)
|
||||
{
|
||||
dst &= 0xffff;
|
||||
dst |= extended_src << 16;
|
||||
if (dst & 0x80000)
|
||||
dst |= -1U << 20;
|
||||
|
@ -529,6 +613,7 @@ msp430_doubleoperand (disassemble_info *info,
|
|||
sprintf (comm1, "0x%05x", dst & 0xfffff);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
* cycles = print_as3_reg_name (regs, op1, comm1, 1, 1, 2);
|
||||
}
|
||||
|
@ -538,13 +623,15 @@ msp430_doubleoperand (disassemble_info *info,
|
|||
{
|
||||
*cycles = 4;
|
||||
/* PC relative. */
|
||||
dst = msp430dis_opcode (addr + 2, info);
|
||||
if (msp430dis_opcode_signed (addr + 2, info, &dst, comm1))
|
||||
{
|
||||
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;
|
||||
|
@ -553,21 +640,25 @@ msp430_doubleoperand (disassemble_info *info,
|
|||
(long) ((addr + 2 + dst) & 0xfffff));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (regs == 2)
|
||||
{
|
||||
*cycles = 2;
|
||||
/* Absolute. */
|
||||
dst = msp430dis_opcode (addr + 2, info);
|
||||
if (msp430dis_opcode_signed (addr + 2, info, &dst, comm1))
|
||||
{
|
||||
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)
|
||||
{
|
||||
*cycles = 1;
|
||||
|
@ -578,21 +669,22 @@ msp430_doubleoperand (disassemble_info *info,
|
|||
{
|
||||
*cycles = 3;
|
||||
/* Indexed. */
|
||||
dst = msp430dis_opcode (addr + 2, info);
|
||||
if (msp430dis_opcode_signed (addr + 2, info, &dst, comm1))
|
||||
{
|
||||
cmd_len += 2;
|
||||
if (extension_word)
|
||||
{
|
||||
dst &= 0xffff;
|
||||
dst |= extended_src << 16;
|
||||
if (dst & 0x80000)
|
||||
dst |= -1U << 20;
|
||||
}
|
||||
else if (dst & 0x8000)
|
||||
dst |= -1U << 16;
|
||||
sprintf (op1, "%d(r%d)", dst, regs);
|
||||
if (dst > 9 || dst < -9)
|
||||
sprintf (comm1, "0x%05x", dst);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Destination. Special care needed on addr + XXXX. */
|
||||
|
||||
|
@ -621,7 +713,8 @@ msp430_doubleoperand (disassemble_info *info,
|
|||
{
|
||||
/* PC relative. */
|
||||
*cycles += 1;
|
||||
dst = msp430dis_opcode (addr + cmd_len, info);
|
||||
if (msp430dis_opcode_signed (addr + cmd_len, info, &dst, comm2))
|
||||
{
|
||||
sprintf (op2, "0x%04x", PS (dst));
|
||||
sprintf (comm2, "PC rel. 0x%04x",
|
||||
PS ((short) addr + cmd_len + dst));
|
||||
|
@ -634,12 +727,14 @@ msp430_doubleoperand (disassemble_info *info,
|
|||
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);
|
||||
if (msp430dis_opcode_signed (addr + cmd_len, info, &dst, comm2))
|
||||
{
|
||||
cmd_len += 2;
|
||||
sprintf (op2, "&0x%04x", PS (dst));
|
||||
if (extension_word)
|
||||
|
@ -648,12 +743,12 @@ msp430_doubleoperand (disassemble_info *info,
|
|||
sprintf (op2, "&0x%05x", dst & 0xfffff);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dst = msp430dis_opcode (addr + cmd_len, info);
|
||||
if (msp430dis_opcode_signed (addr + cmd_len, info, &dst, comm2))
|
||||
{
|
||||
cmd_len += 2;
|
||||
if (dst & 0x8000)
|
||||
dst |= -1U << 16;
|
||||
if (dst > 9 || dst < 0)
|
||||
sprintf (comm2, "0x%04x", PS (dst));
|
||||
if (extension_word)
|
||||
|
@ -667,6 +762,7 @@ msp430_doubleoperand (disassemble_info *info,
|
|||
sprintf (op2, "%d(r%d)", dst, regd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cmd_len;
|
||||
}
|
||||
|
@ -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);
|
||||
if (msp430dis_opcode_unsigned (addr + 2, info, &udst, comm1))
|
||||
{
|
||||
cmd_len += 2;
|
||||
sprintf (op1, "#0x%04x", PS (dst));
|
||||
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);
|
||||
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);
|
||||
if (msp430dis_opcode_unsigned (addr + 2, info, &udst, comm1))
|
||||
{
|
||||
cmd_len += 2;
|
||||
sprintf (op1, "&0x%04x", PS (dst));
|
||||
sprintf (op1, "&0x%04x", PS (udst));
|
||||
}
|
||||
}
|
||||
else if (regs == 3)
|
||||
{
|
||||
|
@ -756,13 +859,13 @@ msp430_branchinstr (disassemble_info *info,
|
|||
else
|
||||
{
|
||||
/* Indexed. */
|
||||
dst = msp430dis_opcode (addr + 2, info);
|
||||
if (msp430dis_opcode_signed (addr + 2, info, &dst, comm1))
|
||||
{
|
||||
cmd_len += 2;
|
||||
if (dst & 0x8000)
|
||||
dst |= -1U << 16;
|
||||
sprintf (op1, "%d(r%d)", dst, regs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cmd_len;
|
||||
}
|
||||
|
@ -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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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,9 +1127,8 @@ 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;
|
||||
if (msp430dis_opcode_signed (addr + 2, info, &n, comm1))
|
||||
{
|
||||
sprintf (op1, "%d(r%d)", n, reg);
|
||||
if (n > 9 || n < 0)
|
||||
{
|
||||
|
@ -1023,24 +1138,27 @@ print_insn_msp430 (bfd_vma addr, disassemble_info *info)
|
|||
else
|
||||
sprintf (comm1, "0x%05x", n);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 6: /* MOVA Rsrc, &abs20 */
|
||||
cmd_len = 4;
|
||||
reg <<= 16;
|
||||
reg |= msp430dis_opcode (addr + 2, info);
|
||||
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;
|
||||
if (msp430dis_opcode_signed (addr + 2, info, &n, comm2))
|
||||
{
|
||||
sprintf (op2, "%d(r%d)", n, reg);
|
||||
if (n > 9 || n < 0)
|
||||
{
|
||||
|
@ -1050,12 +1168,15 @@ print_insn_msp430 (bfd_vma addr, disassemble_info *info)
|
|||
else
|
||||
sprintf (comm2, "0x%05x", n);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 8: /* MOVA #imm20, Rdst */
|
||||
cmd_len = 4;
|
||||
n <<= 16;
|
||||
n |= msp430dis_opcode (addr + 2, info);
|
||||
if (msp430dis_opcode_unsigned (addr + 2, info, &bits, comm1))
|
||||
{
|
||||
n |= bits;
|
||||
if (n & 0x80000)
|
||||
n |= -1U << 20;
|
||||
sprintf (op1, "#%d", n);
|
||||
|
@ -1063,6 +1184,7 @@ print_insn_msp430 (bfd_vma addr, disassemble_info *info)
|
|||
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