+2015-09-21 Pierre Langlois <pierre.langlois@arm.com>
+
+ * aarch64-tdep.c (aarch64_analyze_prologue): New is_adrp
+ variable. Call aarch64_decode_adr instead of
+ aarch64_decode_adrp.
+ * arch/aarch64-insn.h (aarch64_decode_adrp): Delete.
+ (aarch64_decode_adr): New function declaration.
+ * arch/aarch64-insn.c (aarch64_decode_adrp): Delete.
+ (aarch64_decode_adr): New function, factored out from
+ aarch64_decode_adrp to decode both adr and adrp instructions.
+
2015-09-21 Pierre Langlois <pierre.langlois@arm.com>
* Makefile.in (ALL_64_TARGET_OBS): Add aarch64-insn.o.
int is_cbnz;
int is_tbnz;
unsigned bit;
+ int is_adrp;
int32_t offset;
insn = read_memory_unsigned_integer (start, 4, byte_order_for_code);
if (aarch64_decode_add_sub_imm (start, insn, &rd, &rn, &imm))
regs[rd] = pv_add_constant (regs[rn], imm);
- else if (aarch64_decode_adrp (start, insn, &rd))
+ else if (aarch64_decode_adr (start, insn, &is_adrp, &rd, &offset)
+ && is_adrp)
regs[rd] = pv_unknown ();
else if (aarch64_decode_b (start, insn, &is_link, &offset))
{
return (insn & mask) == pattern;
}
-/* Decode an opcode if it represents an ADRP instruction.
+/* Decode an opcode if it represents an ADR or ADRP instruction.
ADDR specifies the address of the opcode.
INSN specifies the opcode to test.
+ IS_ADRP receives the 'op' field from the decoded instruction.
RD receives the 'rd' field from the decoded instruction.
+ OFFSET receives the 'immhi:immlo' field from the decoded instruction.
Return 1 if the opcodes matches and is decoded, otherwise 0. */
int
-aarch64_decode_adrp (CORE_ADDR addr, uint32_t insn, unsigned *rd)
+aarch64_decode_adr (CORE_ADDR addr, uint32_t insn, int *is_adrp,
+ unsigned *rd, int32_t *offset)
{
- if (decode_masked_match (insn, 0x9f000000, 0x90000000))
+ /* adr 0ii1 0000 iiii iiii iiii iiii iiir rrrr */
+ /* adrp 1ii1 0000 iiii iiii iiii iiii iiir rrrr */
+ if (decode_masked_match (insn, 0x1f000000, 0x10000000))
{
+ uint32_t immlo = (insn >> 29) & 0x3;
+ int32_t immhi = extract_signed_bitfield (insn, 19, 5) << 2;
+
+ *is_adrp = (insn >> 31) & 0x1;
*rd = (insn >> 0) & 0x1f;
+ if (*is_adrp)
+ {
+ /* The ADRP instruction has an offset with a -/+ 4GB range,
+ encoded as (immhi:immlo * 4096). */
+ *offset = (immhi | immlo) * 4096;
+ }
+ else
+ *offset = (immhi | immlo);
+
if (aarch64_debug)
{
- debug_printf ("decode: 0x%s 0x%x adrp x%u, #?\n",
- core_addr_to_string_nz (addr), insn, *rd);
+ debug_printf ("decode: 0x%s 0x%x %s x%u, #?\n",
+ core_addr_to_string_nz (addr), insn,
+ *is_adrp ? "adrp" : "adr", *rd);
}
return 1;
}
extern int aarch64_debug;
-int aarch64_decode_adrp (CORE_ADDR addr, uint32_t insn, unsigned *rd);
+int aarch64_decode_adr (CORE_ADDR addr, uint32_t insn, int *is_adrp,
+ unsigned *rd, int32_t *offset);
int aarch64_decode_b (CORE_ADDR addr, uint32_t insn, int *is_bl,
int32_t *offset);