You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
94 lines
2.8 KiB
94 lines
2.8 KiB
//===- AArch64CA53Erratum835769Stub.cpp -----------------------------------===//
|
|
//
|
|
// The MCLinker Project
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "AArch64CA53Erratum835769Stub.h"
|
|
#include "AArch64InsnHelpers.h"
|
|
|
|
#include "mcld/Fragment/FragmentRef.h"
|
|
#include "mcld/Fragment/Relocation.h"
|
|
#include "mcld/IRBuilder.h"
|
|
#include "mcld/LD/BranchIsland.h"
|
|
#include "mcld/LD/LDSymbol.h"
|
|
#include "mcld/LD/ResolveInfo.h"
|
|
|
|
#include <llvm/ADT/StringExtras.h>
|
|
#include <llvm/Support/ELF.h>
|
|
|
|
#include <cassert>
|
|
|
|
namespace mcld {
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// AArch64CA53Erratum835769Stub
|
|
//===----------------------------------------------------------------------===//
|
|
AArch64CA53Erratum835769Stub::AArch64CA53Erratum835769Stub() {
|
|
}
|
|
|
|
/// for doClone
|
|
AArch64CA53Erratum835769Stub::AArch64CA53Erratum835769Stub(
|
|
const uint32_t* pData,
|
|
size_t pSize,
|
|
const char* pName,
|
|
const_fixup_iterator pBegin,
|
|
const_fixup_iterator pEnd)
|
|
: AArch64CA53ErratumStub(pData, pSize, pName, pBegin, pEnd) {
|
|
}
|
|
|
|
AArch64CA53Erratum835769Stub::~AArch64CA53Erratum835769Stub() {
|
|
}
|
|
|
|
bool AArch64CA53Erratum835769Stub::isMyDuty(const FragmentRef& pFragRef) const {
|
|
unsigned rt;
|
|
unsigned rt2;
|
|
bool is_pair;
|
|
bool is_load;
|
|
ErratumSequence code;
|
|
pFragRef.memcpy(&code, sizeof(ErratumSequence), 0);
|
|
|
|
if (AArch64InsnHelpers::isMLXL(code.insns[1]) &&
|
|
AArch64InsnHelpers::isMemOp(code.insns[0], rt, rt2, is_pair, is_load)) {
|
|
// Any SIMD memory op is independent of the subsequent MLA by definition of
|
|
// the erratum.
|
|
if (AArch64InsnHelpers::getBit(code.insns[0], 26) != 0) {
|
|
return true;
|
|
}
|
|
|
|
// If not SIMD, check for integer memory ops and MLA relationship.
|
|
unsigned ra = AArch64InsnHelpers::getRa(code.insns[1]);
|
|
unsigned rm = AArch64InsnHelpers::getRm(code.insns[1]);
|
|
unsigned rn = AArch64InsnHelpers::getRn(code.insns[1]);
|
|
|
|
// If this is a load and there's a true(RAW) dependency, we are safe and
|
|
// this is not an erratum sequence.
|
|
if (is_load &&
|
|
((rt == ra) ||
|
|
(rt == rm) ||
|
|
(rt == rn) ||
|
|
(is_pair && ((rt2 == ra) || (rt2 == rm) || (rt2 == rn))))) {
|
|
return false;
|
|
}
|
|
|
|
// We conservatively put out stubs for all other cases (including
|
|
// writebacks).
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
Stub* AArch64CA53Erratum835769Stub::doClone() {
|
|
return new AArch64CA53Erratum835769Stub(getData(),
|
|
size(),
|
|
"erratum_835769_veneer",
|
|
fixup_begin(),
|
|
fixup_end());
|
|
}
|
|
|
|
} // namespace mcld
|