sim/aarch64: Fix register ordering bug in blr (PR sim/25318)
authorCarlo Bramini <carlo_bramini@users.sourceforge.net>
Thu, 6 Feb 2020 22:50:26 +0000 (22:50 +0000)
committerAndrew Burgess <andrew.burgess@embecosm.com>
Thu, 6 Feb 2020 22:50:26 +0000 (22:50 +0000)
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

sim/aarch64/ChangeLog
sim/aarch64/simulator.c

index 9ab81ad5cc65bbf1f22f5cafbf862add902abb58..1b907b94c9c506d50540aca4a2234089ca5db82d 100644 (file)
@@ -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.
index 84919d6b1fcd3c64e3cf031bd5b4c439018f1f68..5f16a69478c8cb0edab4f85274c489cec0b23ad2 100644 (file)
@@ -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))
     {