This is the mail archive of the mailing list for the binutils project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[COMMITTED][gold, aarch64] Skip ERRATUM 843419 fix if the sequences have been relaxed by TLS optimization

Yup, let's change "return  false;" -> "return true;" (and add proper comments).

Thanks, done.
Also, I assume this relaxation-changing-instructions behavior should
not break erratum 835769?

I think it won't break 835769.

For 835769, it's LD/ST followed by multiply accumulation, this won't exist
in TLS sequence if it's not allowed to be scheduled like in GCC.  In LLVM,
I am not sure.
Given 835769 doesn't have the optimized shortcut like 843419, and there is no
assertion inside it, so even if TLS sequence be scheduled that qualifies the
erratum 835769 and the ld instruction relaxed (this do happen in some TLS
model), the only consequence is we install unnecessary branch-to-stub.
This is OK with me (with Han's suggested changes). It doesn't look
like this is related to any outstanding PR, but if it is, please add
the PR number to the ChangeLog.


I committed attached patch with updated comments and minor tweak.

2017-06-15  Jiong Wang  <>

        * (Insn_utilities::is_mrs_tpidr_el0): New method.
        (AArch64_relobj<size, big_endian>::try_fix_erratum_843419_optimized):
        Return ture for some TLS relaxed sequences.

diff --git a/gold/ b/gold/
index 2470986..7309ded 100644
--- a/gold/
+++ b/gold/
@@ -110,6 +110,10 @@ public:
   is_adrp(const Insntype insn)
   { return (insn & 0x9F000000) == 0x90000000; }
+  static bool
+  is_mrs_tpidr_el0(const Insntype insn)
+  { return (insn & 0xFFFFFFE0) == 0xd53bd040; }
   static unsigned int
   aarch64_rm(const Insntype insn)
   { return aarch64_bits(insn, 16, 5); }
@@ -2010,9 +2014,32 @@ AArch64_relobj<size, big_endian>::try_fix_erratum_843419_optimized(
   E843419_stub<size, big_endian>* e843419_stub =
     reinterpret_cast<E843419_stub<size, big_endian>*>(stub);
   AArch64_address pc = pview.address + e843419_stub->adrp_sh_offset();
-  Insntype* adrp_view = reinterpret_cast<Insntype*>(
-    pview.view + e843419_stub->adrp_sh_offset());
+  unsigned int adrp_offset = e843419_stub->adrp_sh_offset ();
+  Insntype* adrp_view = reinterpret_cast<Insntype*>(pview.view + adrp_offset);
   Insntype adrp_insn = adrp_view[0];
+  // If the instruction at adrp_sh_offset is "mrs R, tpidr_el0", it may come
+  // from IE -> LE relaxation etc.  This is a side-effect of TLS relaxation that
+  // ADRP has been turned into MRS, there is no erratum risk anymore.
+  // Therefore, we return true to avoid doing unnecessary branch-to-stub.
+  if (Insn_utilities::is_mrs_tpidr_el0(adrp_insn))
+    return true;
+  // If the instruction at adrp_sh_offset is not ADRP and the instruction before
+  // it is "mrs R, tpidr_el0", it may come from LD -> LE relaxation etc.
+  // Like the above case, there is no erratum risk any more, we can safely
+  // return true.
+  if (!Insn_utilities::is_adrp(adrp_insn) && adrp_offset)
+    {
+      Insntype* prev_view
+	= reinterpret_cast<Insntype*>(pview.view + adrp_offset - 4);
+      Insntype prev_insn = prev_view[0];
+      if (Insn_utilities::is_mrs_tpidr_el0(prev_insn))
+	return true;
+    }
+  /* If we reach here, the first instruction must be ADRP.  */
   // Get adrp 33-bit signed imm value.
   int64_t adrp_imm = Insn_utilities::

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]