Home | History | Annotate | Download | only in AArch64
      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