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 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 94