aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sim/aarch64/ChangeLog6
-rw-r--r--sim/aarch64/simulator.c7
2 files changed, 9 insertions, 4 deletions
diff --git a/sim/aarch64/ChangeLog b/sim/aarch64/ChangeLog
index 9ab81ad..1b907b9 100644
--- a/sim/aarch64/ChangeLog
+++ b/sim/aarch64/ChangeLog
@@ -1,3 +1,9 @@
+2020-02-06 Carlo Bramini <carlo_bramini@users.sourceforge.net>
+
+ PR sim/25318
+ * simulator.c (blr): Read destination register before calling
+ aarch64_save_LR.
+
2019-03-28 Andrew Burgess <andrew.burgess@embecosm.com>
* cpustate.c: Add 'libiberty.h' include.
diff --git a/sim/aarch64/simulator.c b/sim/aarch64/simulator.c
index 84919d6..5f16a69 100644
--- a/sim/aarch64/simulator.c
+++ b/sim/aarch64/simulator.c
@@ -13437,13 +13437,12 @@ br (sim_cpu *cpu)
static void
blr (sim_cpu *cpu)
{
- unsigned rn = INSTR (9, 5);
+ /* Ensure we read the destination before we write LR. */
+ uint64_t target = aarch64_get_reg_u64 (cpu, INSTR (9, 5), NO_SP);
TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
- /* The pseudo code in the spec says we update LR before fetching.
- the value from the rn. */
aarch64_save_LR (cpu);
- aarch64_set_next_PC (cpu, aarch64_get_reg_u64 (cpu, rn, NO_SP));
+ aarch64_set_next_PC (cpu, target);
if (TRACE_BRANCH_P (cpu))
{