blob: 7d10a1e4ee787a6deb3eea2c5ef54cda7e77d944 [file] [log] [blame]
Stephen Hinescfcb2242016-03-08 00:18:09 -08001//===- 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
25namespace mcld {
26
27//===----------------------------------------------------------------------===//
28// AArch64CA53Erratum835769Stub
29//===----------------------------------------------------------------------===//
30AArch64CA53Erratum835769Stub::AArch64CA53Erratum835769Stub() {
31}
32
33/// for doClone
34AArch64CA53Erratum835769Stub::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
43AArch64CA53Erratum835769Stub::~AArch64CA53Erratum835769Stub() {
44}
45
46bool 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
85Stub* AArch64CA53Erratum835769Stub::doClone() {
86 return new AArch64CA53Erratum835769Stub(getData(),
87 size(),
88 "erratum_835769_veneer",
89 fixup_begin(),
90 fixup_end());
91}
92
93} // namespace mcld