1 //===- AArch64CA53Erratum835769Stub.cpp -----------------------------------===//
2 //
3 // The MCLinker Project
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "AArch64CA53Erratum835769Stub.h"
11 #include "AArch64InsnHelpers.h"
12
13 #include "mcld/Fragment/FragmentRef.h"
14 #include "mcld/Fragment/Relocation.h"
15 #include "mcld/IRBuilder.h"
16 #include "mcld/LD/BranchIsland.h"
17 #include "mcld/LD/LDSymbol.h"
18 #include "mcld/LD/ResolveInfo.h"
19
20 #include <llvm/ADT/StringExtras.h>
21 #include <llvm/Support/ELF.h>
22
23 #include <cassert>
24
25 namespace mcld {
26
27 //===----------------------------------------------------------------------===//
28 // AArch64CA53Erratum835769Stub
29 //===----------------------------------------------------------------------===//
AArch64CA53Erratum835769Stub()30 AArch64CA53Erratum835769Stub::AArch64CA53Erratum835769Stub() {
31 }
32
33 /// for doClone
AArch64CA53Erratum835769Stub(const uint32_t * pData,size_t pSize,const char * pName,const_fixup_iterator pBegin,const_fixup_iterator pEnd)34 AArch64CA53Erratum835769Stub::AArch64CA53Erratum835769Stub(
35 const uint32_t* pData,
36 size_t pSize,
37 const char* pName,
38 const_fixup_iterator pBegin,
39 const_fixup_iterator pEnd)
40 : AArch64CA53ErratumStub(pData, pSize, pName, pBegin, pEnd) {
41 }
42
~AArch64CA53Erratum835769Stub()43 AArch64CA53Erratum835769Stub::~AArch64CA53Erratum835769Stub() {
44 }
45
isMyDuty(const FragmentRef & pFragRef) const46 bool AArch64CA53Erratum835769Stub::isMyDuty(const FragmentRef& pFragRef) const {
47 unsigned rt;
48 unsigned rt2;
49 bool is_pair;
50 bool is_load;
51 ErratumSequence code;
52 pFragRef.memcpy(&code, sizeof(ErratumSequence), 0);
53
54 if (AArch64InsnHelpers::isMLXL(code.insns[1]) &&
55 AArch64InsnHelpers::isMemOp(code.insns[0], rt, rt2, is_pair, is_load)) {
56 // Any SIMD memory op is independent of the subsequent MLA by definition of
57 // the erratum.
58 if (AArch64InsnHelpers::getBit(code.insns[0], 26) != 0) {
59 return true;
60 }
61
62 // If not SIMD, check for integer memory ops and MLA relationship.
63 unsigned ra = AArch64InsnHelpers::getRa(code.insns[1]);
64 unsigned rm = AArch64InsnHelpers::getRm(code.insns[1]);
65 unsigned rn = AArch64InsnHelpers::getRn(code.insns[1]);
66
67 // If this is a load and there's a true(RAW) dependency, we are safe and
68 // this is not an erratum sequence.
69 if (is_load &&
70 ((rt == ra) ||
71 (rt == rm) ||
72 (rt == rn) ||
73 (is_pair && ((rt2 == ra) || (rt2 == rm) || (rt2 == rn))))) {
74 return false;
75 }
76
77 // We conservatively put out stubs for all other cases (including
78 // writebacks).
79 return true;
80 }
81
82 return false;
83 }
84
doClone()85 Stub* AArch64CA53Erratum835769Stub::doClone() {
86 return new AArch64CA53Erratum835769Stub(getData(),
87 size(),
88 "erratum_835769_veneer",
89 fixup_begin(),
90 fixup_end());
91 }
92
93 } // namespace mcld
94