aboutsummaryrefslogtreecommitdiff
path: root/opcodes
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2009-11-17 17:20:26 +0000
committerNick Clifton <nickc@redhat.com>2009-11-17 17:20:26 +0000
commitaefd8a406ce2c3fb7917a232357181d9629b4323 (patch)
treec134a4935d1d4a4bca0e4f044808b61216625aff /opcodes
parent9e3c6df6645d115d2bd5bc11e40c50f03049ebaa (diff)
downloadfsf-binutils-gdb-aefd8a406ce2c3fb7917a232357181d9629b4323.zip
fsf-binutils-gdb-aefd8a406ce2c3fb7917a232357181d9629b4323.tar.gz
fsf-binutils-gdb-aefd8a406ce2c3fb7917a232357181d9629b4323.tar.bz2
* gas/arm/vfma1.d: Only run on ELF based targets.
PR binutils/10924 * gas/arm/arch4t-eabi.d: Update expected disassembly. * gas/arm/arch4t.d: Likewise. * gas/arm/archv6t2.d: Likewise. * gas/arm/arm7t.d: Likewise. * gas/arm/inst.d: Likewise. * gas/arm/xscale.d: Likewise. PR binutils/10924 * arm-dis.c (arm_opcodes): Add patterns to match undefined LDRB instruction variants. Add pattern for MRS variant that was being confused with CMP. (arm_decode_shift): Place error message in a comment. (print_insn_arm): Note that writing back to the PC is unpredictable. Only print 'p' variants of cmp/cmn/teq/tst instructions if decoding for pre-V6 architectures.
Diffstat (limited to 'opcodes')
-rw-r--r--opcodes/ChangeLog12
-rw-r--r--opcodes/arm-dis.c44
2 files changed, 43 insertions, 13 deletions
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index 7f3dee9..ebe6acf 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,3 +1,15 @@
+2009-11-17 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/10924
+ * arm-dis.c (arm_opcodes): Add patterns to match undefined LDRB
+ instruction variants. Add pattern for MRS variant that was being
+ confused with CMP.
+ (arm_decode_shift): Place error message in a comment.
+ (print_insn_arm): Note that writing back to the PC is
+ unpredictable.
+ Only print 'p' variants of cmp/cmn/teq/tst instructions if
+ decoding for pre-V6 architectures.
+
2009-11-17 Edward Nevill <edward.nevill@arm.com>
* arm-dis.c (print_insn_thumb32): Handle undefined instruction.
diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c
index ba19f7c..e59cc6c 100644
--- a/opcodes/arm-dis.c
+++ b/opcodes/arm-dis.c
@@ -56,7 +56,7 @@ struct opcode32
struct opcode16
{
unsigned long arch; /* Architecture defining this insn. */
- unsigned short value, mask; /* Recognise insn if (op&mask)==value. */
+ unsigned short value, mask; /* Recognise insn if (op & mask) == value. */
const char *assembler; /* How to disassemble this insn. */
};
@@ -112,7 +112,7 @@ enum opcode_sentinel_enum
SENTINEL_GENERIC_START
} opcode_sentinels;
-#define UNDEFINED_INSTRUCTION "undefined instruction %0-31x"
+#define UNDEFINED_INSTRUCTION "\t\t; <UNDEFINED> instruction: %0-31x"
#define UNPREDICTABLE_INSTRUCTION "\t; <UNPREDICTABLE>"
/* Common coprocessor opcodes shared between Arm and Thumb-2. */
@@ -825,7 +825,10 @@ static const struct opcode32 arm_opcodes[] =
{ARM_EXT_V6T2, 0x07c00010, 0x0fe00070, "bfi%c\t%12-15r, %0-3r, %E"},
{ARM_EXT_V6T2, 0x00600090, 0x0ff000f0, "mls%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
{ARM_EXT_V6T2, 0x006000b0, 0x0f7000f0, "strht%c\t%12-15r, %S"},
+
+ {ARM_EXT_V6T2, 0x00300090, 0x0f3000f0, UNDEFINED_INSTRUCTION },
{ARM_EXT_V6T2, 0x00300090, 0x0f300090, "ldr%6's%5?hbt%c\t%12-15r, %S"},
+
{ARM_EXT_V6T2, 0x03000000, 0x0ff00000, "movw%c\t%12-15r, %V"},
{ARM_EXT_V6T2, 0x03400000, 0x0ff00000, "movt%c\t%12-15r, %V"},
{ARM_EXT_V6T2, 0x06ff0f30, 0x0fff0ff0, "rbit%c\t%12-15r, %0-3r"},
@@ -1022,7 +1025,10 @@ static const struct opcode32 arm_opcodes[] =
{ARM_EXT_V1, 0x06400000, 0x0e500010, "strb%c\t%12-15r, %a"},
{ARM_EXT_V1, 0x004000b0, 0x0e5000f0, "strh%c\t%12-15r, %s"},
{ARM_EXT_V1, 0x000000b0, 0x0e500ff0, "strh%c\t%12-15r, %s"},
+
+ {ARM_EXT_V1, 0x00500090, 0x0e5000f0, UNDEFINED_INSTRUCTION},
{ARM_EXT_V1, 0x00500090, 0x0e500090, "ldr%6's%5?hb%c\t%12-15r, %s"},
+ {ARM_EXT_V1, 0x00100090, 0x0e500ff0, UNDEFINED_INSTRUCTION},
{ARM_EXT_V1, 0x00100090, 0x0e500f90, "ldr%6's%5?hb%c\t%12-15r, %s"},
{ARM_EXT_V1, 0x02000000, 0x0fe00000, "and%20's%c\t%12-15r, %16-19r, %o"},
@@ -1069,6 +1075,7 @@ static const struct opcode32 arm_opcodes[] =
{ARM_EXT_V1, 0x01200010, 0x0fe00090, "teq%p%c\t%16-19r, %o"},
{ARM_EXT_V1, 0x03400000, 0x0fe00000, "cmp%p%c\t%16-19r, %o"},
+ {ARM_EXT_V3, 0x01400000, 0x0ff00010, "mrs%c\t%12-15r, %22?SCPSR"},
{ARM_EXT_V1, 0x01400000, 0x0fe00010, "cmp%p%c\t%16-19r, %o"},
{ARM_EXT_V1, 0x01400010, 0x0fe00090, "cmp%p%c\t%16-19r, %o"},
@@ -1693,7 +1700,7 @@ arm_decode_shift (long given, fprintf_ftype func, void *stream,
func (stream, ", #%d", amount);
}
else if ((given & 0x80) == 0x80)
- func (stream, ", <illegal shifter operand>");
+ func (stream, "\t; <illegal shifter operand>");
else if (print_shift)
func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
arm_regnames[(given & 0xf00) >> 8]);
@@ -2862,8 +2869,16 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
if (NEGATIVE_BIT_SET)
offset = - offset;
- func (stream, "[pc, #%d]\t; ", offset);
- info->print_address_func (offset + pc + 8, info);
+ if (PRE_BIT_SET)
+ {
+ func (stream, "[pc, #%d]\t; ", offset);
+ info->print_address_func (offset + pc + 8, info);
+ }
+ else
+ {
+ func (stream, "[pc], #%d", offset);
+ func (stream, UNPREDICTABLE_INSTRUCTION);
+ }
}
else
{
@@ -2880,8 +2895,8 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
/* Pre-indexed. */
if (IMMEDIATE_BIT_SET)
{
- if (offset)
- func (stream, ", #%d", offset);
+ /* PR 10924: Offset must be printed, even if it is zero. */
+ func (stream, ", #%d", offset);
value_in_comment = offset;
}
else /* Register. */
@@ -2896,11 +2911,8 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
{
if (IMMEDIATE_BIT_SET)
{
- if (offset)
- func (stream, "], #%d", offset);
- else
- func (stream, "]");
-
+ /* PR 10924: Offset must be printed, even if it is zero. */
+ func (stream, "], #%d", offset);
value_in_comment = offset;
}
else /* Register. */
@@ -2966,7 +2978,13 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
case 'p':
if ((given & 0x0000f000) == 0x0000f000)
- func (stream, "p");
+ {
+ /* The p-variants of tst/cmp/cmn/teq are the pre-V6
+ mechanism for setting PSR flag bits. They are
+ obsolete in V6 onwards. */
+ if (((((arm_feature_set *) info->private_data)->core) & ARM_EXT_V6) == 0)
+ func (stream, "p");
+ }
break;
case 't':