SENTINEL_GENERIC_START
} opcode_sentinels;
-#define UNDEFINED_INSTRUCTION "undefined instruction %0-31x"
+#define UNDEFINED_INSTRUCTION "undefined instruction %0-31x"
+#define UNPREDICTABLE_INSTRUCTION "\t; <UNPREDICTABLE>"
/* Common coprocessor opcodes shared between Arm and Thumb-2. */
%a print address for ldr/str instruction
%s print address for ldr/str halfword/signextend instruction
+ %S like %s but allow UNPREDICTABLE addressing
%b print branch destination
%c print condition code (always bits 28-31)
%m print register mask for ldm/stm instruction
{ARM_EXT_V6T2, 0x07c0001f, 0x0fe0007f, "bfc%c\t%12-15r, %E"},
{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, 0x0f300090, "ldr%6's%5?hbt%c\t%12-15r, %s"},
+ {ARM_EXT_V6T2, 0x006000b0, 0x0f7000f0, "strht%c\t%12-15r, %S"},
+ {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"},
}
}
+#define W_BIT 21
+#define I_BIT 22
+#define U_BIT 23
+#define P_BIT 24
+
+#define WRITEBACK_BIT_SET (given & (1 << W_BIT))
+#define IMMEDIATE_BIT_SET (given & (1 << I_BIT))
+#define NEGATIVE_BIT_SET ((given & (1 << U_BIT)) == 0)
+#define PRE_BIT_SET (given & (1 << P_BIT))
+
/* Print one coprocessor instruction on INFO->STREAM.
Return TRUE if the instuction matched, FALSE if this is not a
recognised coprocessor instruction. */
func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
value_in_comment = offset * 4;
- if ((given & 0x00800000) == 0)
+ if (NEGATIVE_BIT_SET)
value_in_comment = - value_in_comment;
- if ((given & (1 << 24)) != 0)
+ if (PRE_BIT_SET)
{
if (offset)
func (stream, ", #%d]%s",
value_in_comment,
- ((given & 0x00200000) != 0 ? "!" : ""));
+ WRITEBACK_BIT_SET ? "!" : "");
else
func (stream, "]");
}
{
func (stream, "]");
- if (given & (1 << 21))
+ if (WRITEBACK_BIT_SET)
{
if (offset)
func (stream, ", #%d", value_in_comment);
{
int rn = (given >> 16) & 0xf;
int offset = (given & 0xff) * 4;
- int add = (given >> 23) & 1;
func (stream, "[%s", arm_regnames[rn]);
if (offset)
{
- if (!add)
- offset = -offset;
+ if (NEGATIVE_BIT_SET)
+ offset = - offset;
func (stream, ", #%d", offset);
if (rn != 15)
value_in_comment = offset;
if (multiplier > 1)
{
value_in_comment = offset * multiplier;
- if ((given & 0x00800000) == 0)
+ if (NEGATIVE_BIT_SET)
value_in_comment = - value_in_comment;
}
if (offset)
{
- if ((given & 0x01000000) != 0)
+ if (PRE_BIT_SET)
func (stream, ", #%s%d]%s",
- ((given & 0x00800000) == 0 ? "-" : ""),
+ NEGATIVE_BIT_SET ? "-" : "",
offset * multiplier,
- ((given & 0x00200000) != 0 ? "!" : ""));
+ WRITEBACK_BIT_SET ? "!" : "");
else
func (stream, "], #%s%d",
- ((given & 0x00800000) == 0 ? "-" : ""),
+ NEGATIVE_BIT_SET ? "-" : "",
offset * multiplier);
}
else
case 'r':
{
int imm4 = (given >> 4) & 0xf;
- int puw_bits = ((given >> 22) & 6) | ((given >> 21) & 1);
- int ubit = (given >> 23) & 1;
+ int puw_bits = ((given >> 22) & 6) | ((given >> W_BIT) & 1);
+ int ubit = ! NEGATIVE_BIT_SET;
const char *rm = arm_regnames [given & 0xf];
const char *rn = arm_regnames [(given >> 16) & 0xf];
func (stream, "[pc");
- if (given & 0x01000000)
+ if (PRE_BIT_SET)
{
- if ((given & 0x00800000) == 0)
+ if (NEGATIVE_BIT_SET)
offset = - offset;
/* Pre-indexed. */
being used. Probably a very dangerous thing
for the programmer to do, but who are we to
argue ? */
- if (given & 0x00200000)
+ if (WRITEBACK_BIT_SET)
func (stream, "!");
}
- else
+ else /* Post indexed. */
{
- /* Post indexed. */
func (stream, "], #%d", offset);
- /* ie ignore the offset. */
+ /* Ie ignore the offset. */
offset = pc + 8;
}
{
func (stream, "[%s",
arm_regnames[(given >> 16) & 0xf]);
- if ((given & 0x01000000) != 0)
+
+ if (PRE_BIT_SET)
{
if ((given & 0x02000000) == 0)
{
offset = given & 0xfff;
if (offset)
func (stream, ", #%s%d",
- (((given & 0x00800000) == 0)
- ? "-" : ""), offset);
+ NEGATIVE_BIT_SET ? "-" : "", offset);
}
else
{
func (stream, ", %s",
- (((given & 0x00800000) == 0)
- ? "-" : ""));
+ NEGATIVE_BIT_SET ? "-" : "");
arm_decode_shift (given, func, stream, TRUE);
}
func (stream, "]%s",
- ((given & 0x00200000) != 0) ? "!" : "");
+ WRITEBACK_BIT_SET ? "!" : "");
}
else
{
offset = given & 0xfff;
if (offset)
func (stream, "], #%s%d",
- (((given & 0x00800000) == 0)
- ? "-" : ""), offset);
+ NEGATIVE_BIT_SET ? "-" : "", offset);
else
func (stream, "]");
}
else
{
func (stream, "], %s",
- (((given & 0x00800000) == 0)
- ? "-" : ""));
+ NEGATIVE_BIT_SET ? "-" : "");
arm_decode_shift (given, func, stream, TRUE);
}
}
valbytes[3] = (value >> 24) & 0xff;
floatformat_to_double
- (&floatformat_ieee_single_little, valbytes,
- &fvalue);
+ (& floatformat_ieee_single_little, valbytes,
+ & fvalue);
func (stream, "#%.7g\t; 0x%.8lx", fvalue,
value);
}
else
func (stream, "#%ld\t; 0x%.8lx",
- (long) ((value & 0x80000000)
- ? value | ~0xffffffffl : value), value);
+ (long) (NEGATIVE_BIT_SET ? value | ~0xffffffffL : value),
+ value);
break;
case 64:
{
if (*c == '%')
{
+ bfd_boolean allow_unpredictable = FALSE;
+
switch (*++c)
{
case '%':
case 'P':
/* Set P address bit and use normal address
printing routine. */
- value_in_comment = print_arm_address (pc, info, given | (1 << 24));
+ value_in_comment = print_arm_address (pc, info, given | (1 << P_BIT));
break;
+ case 'S':
+ allow_unpredictable = TRUE;
case 's':
if ((given & 0x004f0000) == 0x004f0000)
{
/* PC relative with immediate offset. */
int offset = ((given & 0xf00) >> 4) | (given & 0xf);
- if ((given & 0x00800000) == 0)
- offset = -offset;
+ if (NEGATIVE_BIT_SET)
+ offset = - offset;
func (stream, "[pc, #%d]\t; ", offset);
info->print_address_func (offset + pc + 8, info);
}
else
{
- bfd_boolean negative = (given & 0x00800000) == 0;
int offset = ((given & 0xf00) >> 4) | (given & 0xf);
- if (negative)
- offset = -offset;
+ if (NEGATIVE_BIT_SET)
+ offset = - offset;
func (stream, "[%s",
arm_regnames[(given >> 16) & 0xf]);
- if ((given & 0x01000000) != 0)
+ if (PRE_BIT_SET)
{
/* Pre-indexed. */
- if ((given & 0x00400000) == 0x00400000)
+ if (IMMEDIATE_BIT_SET)
{
- /* Immediate. */
if (offset)
func (stream, ", #%d", offset);
value_in_comment = offset;
}
- else
- {
- /* Register. */
- func (stream, ", %s%s", negative ? "-" : "",
- arm_regnames[given & 0xf]);
- }
+ else /* Register. */
+ func (stream, ", %s%s",
+ NEGATIVE_BIT_SET ? "-" : "",
+ arm_regnames[given & 0xf]);
func (stream, "]%s",
- ((given & 0x00200000) != 0) ? "!" : "");
+ WRITEBACK_BIT_SET ? "!" : "");
}
- else
+ else /* Post-indexed. */
{
- /* Post-indexed. */
- if ((given & 0x00400000) == 0x00400000)
+ if (IMMEDIATE_BIT_SET)
{
- /* Immediate. */
if (offset)
func (stream, "], #%d", offset);
else
value_in_comment = offset;
}
- else
- {
- /* Register. */
- func (stream, "], %s%s", negative ? "-" : "",
- arm_regnames[given & 0xf]);
- }
+ else /* Register. */
+ func (stream, "], %s%s",
+ NEGATIVE_BIT_SET ? "-" : "",
+ arm_regnames[given & 0xf]);
+
+ if (WRITEBACK_BIT_SET && ! allow_unpredictable)
+ func (stream, UNPREDICTABLE_INSTRUCTION);
}
}
break;
int offset = given & 0xff;
value_in_comment = offset * 4;
- if ((given & 0x00800000) == 0)
+ if (NEGATIVE_BIT_SET)
value_in_comment = - value_in_comment;
func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
- if ((given & (1 << 24)) != 0)
+ if (PRE_BIT_SET)
{
if (offset)
func (stream, ", #%d]%s",
value_in_comment,
- ((given & 0x00200000) != 0 ? "!" : ""));
+ WRITEBACK_BIT_SET ? "!" : "");
else
func (stream, "]");
}
{
func (stream, "]");
- if (given & (1 << 21))
+ if (WRITEBACK_BIT_SET)
{
if (offset)
func (stream, ", #%d", value_in_comment);
bfd_vma address;
bfd_vma offset = 0;
- if (given & 0x00800000)
+ if (! NEGATIVE_BIT_SET)
/* Is signed, hi bits should be ones. */
offset = (-1) ^ 0x00ffffff;
switch (mod)
{
case 0: imm = imm8; break;
- case 1: imm = ((imm8<<16) | imm8); break;
- case 2: imm = ((imm8<<24) | (imm8 << 8)); break;
- case 3: imm = ((imm8<<24) | (imm8 << 16) | (imm8 << 8) | imm8); break;
+ case 1: imm = ((imm8 << 16) | imm8); break;
+ case 2: imm = ((imm8 << 24) | (imm8 << 8)); break;
+ case 3: imm = ((imm8 << 24) | (imm8 << 16) | (imm8 << 8) | imm8); break;
default:
mod = (bits & 0xf80) >> 7;
imm8 = (bits & 0x07f) | 0x80;
case 'a':
{
unsigned int Rn = (given & 0x000f0000) >> 16;
- unsigned int U = (given & 0x00800000) >> 23;
+ unsigned int U = ! NEGATIVE_BIT_SET;
unsigned int op = (given & 0x00000f00) >> 8;
unsigned int i12 = (given & 0x00000fff);
unsigned int i8 = (given & 0x000000ff);
case 'A':
{
- unsigned int P = (given & 0x01000000) >> 24;
- unsigned int U = (given & 0x00800000) >> 23;
- unsigned int W = (given & 0x00400000) >> 21;
+ unsigned int U = ! NEGATIVE_BIT_SET;
+ unsigned int W = WRITEBACK_BIT_SET;
unsigned int Rn = (given & 0x000f0000) >> 16;
unsigned int off = (given & 0x000000ff);
func (stream, "[%s", arm_regnames[Rn]);
- if (P)
+
+ if (PRE_BIT_SET)
{
if (off || !U)
{
shift |= (given & 0x000000c0u) >> 6;
shift |= (given & 0x00007000u) >> 10;
- if (given & 0x00200000u)
+ if (WRITEBACK_BIT_SET)
func (stream, ", asr #%u", shift);
else if (shift)
func (stream, ", lsl #%u", shift);