summaryrefslogtreecommitdiffstats
path: root/contrib/binutils/opcodes/arm-dis.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/binutils/opcodes/arm-dis.c')
-rw-r--r--contrib/binutils/opcodes/arm-dis.c68
1 files changed, 46 insertions, 22 deletions
diff --git a/contrib/binutils/opcodes/arm-dis.c b/contrib/binutils/opcodes/arm-dis.c
index a3e7112..686b18a 100644
--- a/contrib/binutils/opcodes/arm-dis.c
+++ b/contrib/binutils/opcodes/arm-dis.c
@@ -60,6 +60,8 @@ static arm_regname regnames[] =
{
{ "raw" , "Select raw register names",
{ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}},
+ { "gcc", "Select register names used by GCC",
+ { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc" }},
{ "std", "Select register names used in ARM's ISA documentation",
{ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc" }},
{ "apcs", "Select register names used in the APCS",
@@ -70,7 +72,7 @@ static arm_regname regnames[] =
{ "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL", "FP", "IP", "SP", "LR", "PC" }}
};
-/* Default to standard register name set. */
+/* Default to GCC register name set. */
static unsigned int regname_selected = 1;
#define NUM_ARM_REGNAMES NUM_ELEM (regnames)
@@ -419,28 +421,39 @@ print_insn_arm (pc, info, given)
}
break;
+ case 'B':
+ /* Print ARM V5 BLX(1) address: pc+25 bits. */
+ {
+ bfd_vma address;
+ bfd_vma offset = 0;
+
+ if (given & 0x00800000)
+ /* Is signed, hi bits should be ones. */
+ offset = (-1) ^ 0x00ffffff;
+
+ /* Offset is (SignExtend(offset field)<<2). */
+ offset += given & 0x00ffffff;
+ offset <<= 2;
+ address = offset + pc + 8;
+
+ if (given & 0x01000000)
+ /* H bit allows addressing to 2-byte boundaries. */
+ address += 2;
+
+ info->print_address_func (address, info);
+ }
+ break;
+
case 'C':
- switch (given & 0x000f0000)
- {
- default:
- func (stream, "_???");
- break;
- case 0x90000:
- func (stream, "_all");
- break;
- case 0x10000:
- func (stream, "_c");
- break;
- case 0x20000:
- func (stream, "_x");
- break;
- case 0x40000:
- func (stream, "_s");
- break;
- case 0x80000:
- func (stream, "_f");
- break;
- }
+ func (stream, "_");
+ if (given & 0x80000)
+ func (stream, "f");
+ if (given & 0x40000)
+ func (stream, "s");
+ if (given & 0x20000)
+ func (stream, "x");
+ if (given & 0x10000)
+ func (stream, "c");
break;
case 'F':
@@ -658,6 +671,9 @@ print_insn_thumb (pc, info, given)
info->bytes_per_chunk = 4;
info->bytes_per_line = 4;
+ if ((given & 0x10000000) == 0)
+ func (stream, "blx\t");
+ else
func (stream, "bl\t");
info->print_address_func (BDISP23 (given) * 2 + pc + 4, info);
@@ -1027,6 +1043,14 @@ print_insn (pc, info, little)
given = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3]);
}
+ if (info->flags & INSN_HAS_RELOC)
+ /* If the instruction has a reloc associated with it, then
+ the offset field in the instruction will actually be the
+ addend for the reloc. (We are using REL type relocs).
+ In such cases, we can ignore the pc when computing
+ addresses, since the addend is not currently pc-relative. */
+ pc = 0;
+
if (is_thumb)
status = print_insn_thumb (pc, info, given);
else
OpenPOWER on IntegriCloud