This patch adds emulation support for the adr instruction.
Signed-off-by: Alexander Graf <[email protected]>
---
target-arm/translate-a64.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index bc91324..00eda0f 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -943,6 +943,27 @@ static void handle_insg(DisasContext *s, uint32_t insn)
simd_st(cpu_reg(rn), freg_offs_d + idx, size);
}
+/* PC relative address calculation */
+static void handle_adr(DisasContext *s, uint32_t insn)
+{
+ int reg = get_reg(insn);
+ int is_page = get_bits(insn, 31, 1);
+ uint64_t imm;
+ uint64_t base;
+
+ imm = get_sbits(insn, 5, 19) << 2;
+ imm |= get_bits(insn, 29, 2);
+
+ base = s->pc - 4;
+ if (is_page) {
+ /* ADRP (page based) */
+ base &= ~0xFFFULL;
+ imm <<= 12;
+ }
+
+ tcg_gen_movi_i64(cpu_reg(reg), base + imm);
+}
+
/* SIMD ORR */
static void handle_simdorr(DisasContext *s, uint32_t insn)
{
@@ -1365,6 +1386,9 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
unallocated_encoding(s);
}
break;
+ case 0x10:
+ handle_adr(s, insn);
+ break;
default:
unallocated_encoding(s);
break;
--
1.7.12.4