aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--opcodes/ChangeLog6
-rw-r--r--opcodes/arm-dis.c28
2 files changed, 30 insertions, 4 deletions
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index b6a9acc..6a1db6d 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,3 +1,9 @@
+2012-08-24 Matthew Gretton-Dann <matthew.gretton-dann@arm.com
+
+ * arm-dis.c (COND_UNCOND): New constant.
+ (print_insn_coprocessor): Add support for %u format specifier.
+ (print_insn_neon): Likewise.
+
2012-08-21 David S. Miller <davem@davemloft.net>
* sparc-opc.c (4-argument crypto instructions): Fix encoding using
diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c
index 74d78cb..532a6c8 100644
--- a/opcodes/arm-dis.c
+++ b/opcodes/arm-dis.c
@@ -92,7 +92,8 @@ struct opcode16
%c print condition code (always bits 28-31 in ARM mode)
%q print shifter argument
- %u print condition code (unconditional in ARM mode)
+ %u print condition code (unconditional in ARM mode,
+ UNPREDICTABLE if not AL in Thumb)
%A print address for ldc/stc/ldf/stf instruction
%B print vstm/vldm register list
%I print cirrus signed shift immediate: bits 0..3|4..6
@@ -519,6 +520,8 @@ static const struct opcode32 coprocessor_opcodes[] =
%% %
%c print condition code
+ %u print condition code (unconditional in ARM mode,
+ UNPREDICTABLE if not AL in Thumb)
%A print v{st,ld}[1234] operands
%B print v{st,ld}[1234] any one operands
%C print v{st,ld}[1234] single->all operands
@@ -1692,6 +1695,9 @@ static unsigned int ifthen_next_state;
/* The address of the insn for which the IT state is valid. */
static bfd_vma ifthen_address;
#define IFTHEN_COND ((ifthen_state >> 4) & 0xf)
+/* Indicates that the current Conditional state is unconditional or outside
+ an IT block. */
+#define COND_UNCOND 16
/* Functions. */
@@ -1870,7 +1876,7 @@ print_insn_coprocessor (bfd_vma pc,
if (ifthen_state)
cond = IFTHEN_COND;
else
- cond = 16;
+ cond = COND_UNCOND;
}
else
{
@@ -1879,13 +1885,13 @@ print_insn_coprocessor (bfd_vma pc,
if ((given & 0xf0000000) == 0xf0000000)
{
mask |= 0xf0000000;
- cond = 16;
+ cond = COND_UNCOND;
}
else
{
cond = (given >> 28) & 0xf;
if (cond == 0xe)
- cond = 16;
+ cond = COND_UNCOND;
}
}
@@ -1979,6 +1985,11 @@ print_insn_coprocessor (bfd_vma pc,
}
break;
+ case 'u':
+ if (cond != COND_UNCOND)
+ is_unpredictable = TRUE;
+
+ /* Fall through. */
case 'c':
func (stream, "%s", arm_conditional[cond]);
break;
@@ -2488,6 +2499,7 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
if ((given & insn->mask) == insn->value)
{
signed long value_in_comment = 0;
+ bfd_boolean is_unpredictable = FALSE;
const char *c;
for (c = insn->assembler; *c; c++)
@@ -2500,6 +2512,11 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
func (stream, "%%");
break;
+ case 'u':
+ if (thumb && ifthen_state)
+ is_unpredictable = TRUE;
+
+ /* Fall through. */
case 'c':
if (thumb && ifthen_state)
func (stream, "%s", arm_conditional[IFTHEN_COND]);
@@ -2913,6 +2930,9 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
if (value_in_comment > 32 || value_in_comment < -16)
func (stream, "\t; 0x%lx", value_in_comment);
+ if (is_unpredictable)
+ func (stream, UNPREDICTABLE_INSTRUCTION);
+
return TRUE;
}
}