aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlo Bramini <carlo_bramini@users.sourceforge.net>2020-02-06 22:50:26 +0000
committerAndrew Burgess <andrew.burgess@embecosm.com>2020-02-06 22:50:26 +0000
commit69b1ffdb01106ed84a41a80f6ad2d9c26c4f45a9 (patch)
tree284c914e9ea392b7d0c682e09a9838d0b53b6f30
parent1d5d29e73f4b5f1af4df5b6e39ccf2fa722acead (diff)
downloadfsf-binutils-gdb-69b1ffdb01106ed84a41a80f6ad2d9c26c4f45a9.zip
fsf-binutils-gdb-69b1ffdb01106ed84a41a80f6ad2d9c26c4f45a9.tar.gz
fsf-binutils-gdb-69b1ffdb01106ed84a41a80f6ad2d9c26c4f45a9.tar.bz2
sim/aarch64: Fix register ordering bug in blr (PR sim/25318)
A comment in the implementation of blr says: /* The pseudo code in the spec says we update LR before fetching. the value from the rn. */ With 'rn' being the register holding the destination address. This may have been true at one point, but the ISA manual now clearly shows the destination register being read before the link register is written. This commit updates the implementation of blr to match. sim/aarch64/ChangeLog: PR sim/25318 * simulator.c (blr): Read destination register before calling aarch64_save_LR. Change-Id: Icb1c556064e3d9c807ac28440475caa205ab1064
-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))
{