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 //===----------------------------------------------------------------------===// 30 AArch64CA53Erratum835769Stub::AArch64CA53Erratum835769Stub() { 31 } 32 33 /// for doClone 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 43 AArch64CA53Erratum835769Stub::~AArch64CA53Erratum835769Stub() { 44 } 45 46 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 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