brintos

brintos / llvm-project-archived public Read only

0
0
Text · 123.5 KiB · 7c24c2c Raw
3616 lines · cpp
1//===- bolt/Target/X86/X86MCPlusBuilder.cpp -------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file provides X86-specific MCPlus builder.10//11//===----------------------------------------------------------------------===//12 13#include "MCTargetDesc/X86BaseInfo.h"14#include "MCTargetDesc/X86EncodingOptimization.h"15#include "MCTargetDesc/X86MCTargetDesc.h"16#include "X86MCSymbolizer.h"17#include "bolt/Core/MCPlus.h"18#include "bolt/Core/MCPlusBuilder.h"19#include "llvm/BinaryFormat/ELF.h"20#include "llvm/MC/MCContext.h"21#include "llvm/MC/MCInst.h"22#include "llvm/MC/MCInstBuilder.h"23#include "llvm/MC/MCInstrInfo.h"24#include "llvm/MC/MCRegister.h"25#include "llvm/MC/MCRegisterInfo.h"26#include "llvm/Support/CommandLine.h"27#include "llvm/Support/DataExtractor.h"28#include "llvm/Support/Debug.h"29#include "llvm/Support/Errc.h"30#include "llvm/Support/ErrorHandling.h"31#include "llvm/Support/ErrorOr.h"32#include <set>33 34#define DEBUG_TYPE "mcplus"35 36using namespace llvm;37using namespace bolt;38 39namespace opts {40 41extern cl::OptionCategory BoltOptCategory;42 43static cl::opt<bool> X86StripRedundantAddressSize(44    "x86-strip-redundant-address-size",45    cl::desc("Remove redundant Address-Size override prefix"), cl::init(true),46    cl::cat(BoltOptCategory));47 48} // namespace opts49 50namespace {51 52bool isMOVSX64rm32(const MCInst &Inst) {53  return Inst.getOpcode() == X86::MOVSX64rm32;54}55 56bool isADD64rr(const MCInst &Inst) { return Inst.getOpcode() == X86::ADD64rr; }57 58bool isADDri(const MCInst &Inst) {59  return Inst.getOpcode() == X86::ADD64ri32 ||60         Inst.getOpcode() == X86::ADD64ri8;61}62 63// Create instruction to increment contents of target by 164static InstructionListType createIncMemory(const MCSymbol *Target,65                                           MCContext *Ctx) {66  InstructionListType Insts;67  Insts.emplace_back();68  Insts.back().setOpcode(X86::LOCK_INC64m);69  Insts.back().clear();70  Insts.back().addOperand(MCOperand::createReg(X86::RIP));        // BaseReg71  Insts.back().addOperand(MCOperand::createImm(1));               // ScaleAmt72  Insts.back().addOperand(MCOperand::createReg(X86::NoRegister)); // IndexReg73 74  Insts.back().addOperand(75      MCOperand::createExpr(MCSymbolRefExpr::create(Target,76                                                    *Ctx))); // Displacement77  Insts.back().addOperand(78      MCOperand::createReg(X86::NoRegister)); // AddrSegmentReg79  return Insts;80}81 82#define GET_INSTRINFO_OPERAND_TYPES_ENUM83#define GET_INSTRINFO_OPERAND_TYPE84#define GET_INSTRINFO_MEM_OPERAND_SIZE85#include "X86GenInstrInfo.inc"86 87class X86MCPlusBuilder : public MCPlusBuilder {88public:89  using MCPlusBuilder::MCPlusBuilder;90 91  std::unique_ptr<MCSymbolizer>92  createTargetSymbolizer(BinaryFunction &Function,93                         bool CreateNewSymbols) const override {94    return std::make_unique<X86MCSymbolizer>(Function, CreateNewSymbols);95  }96 97  bool isBranch(const MCInst &Inst) const override {98    return Analysis->isBranch(Inst) && !isTailCall(Inst);99  }100 101  bool isNoop(const MCInst &Inst) const override {102    return X86::isNOP(Inst.getOpcode());103  }104 105  unsigned getCondCode(const MCInst &Inst) const override {106    unsigned Opcode = Inst.getOpcode();107    if (X86::isJCC(Opcode))108      return Inst.getOperand(Info->get(Opcode).NumOperands - 1).getImm();109    return X86::COND_INVALID;110  }111 112  unsigned getInvertedCondCode(unsigned CC) const override {113    switch (CC) {114    default: return X86::COND_INVALID;115    case X86::COND_E:  return X86::COND_NE;116    case X86::COND_NE: return X86::COND_E;117    case X86::COND_L:  return X86::COND_GE;118    case X86::COND_LE: return X86::COND_G;119    case X86::COND_G:  return X86::COND_LE;120    case X86::COND_GE: return X86::COND_L;121    case X86::COND_B:  return X86::COND_AE;122    case X86::COND_BE: return X86::COND_A;123    case X86::COND_A:  return X86::COND_BE;124    case X86::COND_AE: return X86::COND_B;125    case X86::COND_S:  return X86::COND_NS;126    case X86::COND_NS: return X86::COND_S;127    case X86::COND_P:  return X86::COND_NP;128    case X86::COND_NP: return X86::COND_P;129    case X86::COND_O:  return X86::COND_NO;130    case X86::COND_NO: return X86::COND_O;131    }132  }133 134  unsigned getCondCodesLogicalOr(unsigned CC1, unsigned CC2) const override {135    enum DecodedCondCode : uint8_t {136      DCC_EQUAL = 0x1,137      DCC_GREATER = 0x2,138      DCC_LESSER = 0x4,139      DCC_GREATER_OR_LESSER = 0x6,140      DCC_UNSIGNED = 0x8,141      DCC_SIGNED = 0x10,142      DCC_INVALID = 0x20,143    };144 145    auto decodeCondCode = [&](unsigned CC) -> uint8_t {146      switch (CC) {147      default: return DCC_INVALID;148      case X86::COND_E: return DCC_EQUAL;149      case X86::COND_NE: return DCC_GREATER | DCC_LESSER;150      case X86::COND_L: return DCC_LESSER | DCC_SIGNED;151      case X86::COND_LE: return DCC_EQUAL | DCC_LESSER | DCC_SIGNED;152      case X86::COND_G: return DCC_GREATER | DCC_SIGNED;153      case X86::COND_GE: return DCC_GREATER | DCC_EQUAL | DCC_SIGNED;154      case X86::COND_B: return DCC_LESSER | DCC_UNSIGNED;155      case X86::COND_BE: return DCC_EQUAL | DCC_LESSER | DCC_UNSIGNED;156      case X86::COND_A: return DCC_GREATER | DCC_UNSIGNED;157      case X86::COND_AE: return DCC_GREATER | DCC_EQUAL | DCC_UNSIGNED;158      }159    };160 161    uint8_t DCC = decodeCondCode(CC1) | decodeCondCode(CC2);162 163    if (DCC & DCC_INVALID)164      return X86::COND_INVALID;165 166    if (DCC & DCC_SIGNED && DCC & DCC_UNSIGNED)167      return X86::COND_INVALID;168 169    switch (DCC) {170    default: return X86::COND_INVALID;171    case DCC_EQUAL | DCC_LESSER | DCC_SIGNED: return X86::COND_LE;172    case DCC_EQUAL | DCC_LESSER | DCC_UNSIGNED: return X86::COND_BE;173    case DCC_EQUAL | DCC_GREATER | DCC_SIGNED: return X86::COND_GE;174    case DCC_EQUAL | DCC_GREATER | DCC_UNSIGNED: return X86::COND_AE;175    case DCC_GREATER | DCC_LESSER | DCC_SIGNED: return X86::COND_NE;176    case DCC_GREATER | DCC_LESSER | DCC_UNSIGNED: return X86::COND_NE;177    case DCC_GREATER | DCC_LESSER: return X86::COND_NE;178    case DCC_EQUAL | DCC_SIGNED: return X86::COND_E;179    case DCC_EQUAL | DCC_UNSIGNED: return X86::COND_E;180    case DCC_EQUAL: return X86::COND_E;181    case DCC_LESSER | DCC_SIGNED: return X86::COND_L;182    case DCC_LESSER | DCC_UNSIGNED: return X86::COND_B;183    case DCC_GREATER | DCC_SIGNED: return X86::COND_G;184    case DCC_GREATER | DCC_UNSIGNED: return X86::COND_A;185    }186  }187 188  bool isValidCondCode(unsigned CC) const override {189    return (CC != X86::COND_INVALID);190  }191 192  bool isBreakpoint(const MCInst &Inst) const override {193    return Inst.getOpcode() == X86::INT3;194  }195 196  bool isPrefix(const MCInst &Inst) const override {197    const MCInstrDesc &Desc = Info->get(Inst.getOpcode());198    return X86II::isPrefix(Desc.TSFlags);199  }200 201  bool isRep(const MCInst &Inst) const override {202    return Inst.getFlags() == X86::IP_HAS_REPEAT;203  }204 205  bool deleteREPPrefix(MCInst &Inst) const override {206    if (Inst.getFlags() == X86::IP_HAS_REPEAT) {207      Inst.setFlags(0);208      return true;209    }210    return false;211  }212 213  bool isIndirectCall(const MCInst &Inst) const override {214    return isCall(Inst) &&215           ((getMemoryOperandNo(Inst) != -1) || Inst.getOperand(0).isReg());216  }217 218  bool isPop(const MCInst &Inst) const override {219    return getPopSize(Inst) == 0 ? false : true;220  }221 222  bool isEpilogue(const BinaryBasicBlock &BB) const override {223    return ::llvm::any_of(BB, [&](const MCInst &Instr) {224      return isLeave(Instr) || isPop(Instr);225    });226  }227 228  bool isTerminateBranch(const MCInst &Inst) const override {229    return Inst.getOpcode() == X86::ENDBR32 || Inst.getOpcode() == X86::ENDBR64;230  }231 232  bool isX86HLT(const MCInst &Inst) const override {233    return Inst.getOpcode() == X86::HLT;234  }235 236  int getPopSize(const MCInst &Inst) const override {237    switch (Inst.getOpcode()) {238    case X86::POP16r:239    case X86::POP16rmm:240    case X86::POP16rmr:241    case X86::POPF16:242    case X86::POPA16:243    case X86::POPDS16:244    case X86::POPES16:245    case X86::POPFS16:246    case X86::POPGS16:247    case X86::POPSS16:248      return 2;249    case X86::POP32r:250    case X86::POP32rmm:251    case X86::POP32rmr:252    case X86::POPA32:253    case X86::POPDS32:254    case X86::POPES32:255    case X86::POPF32:256    case X86::POPFS32:257    case X86::POPGS32:258    case X86::POPSS32:259      return 4;260    case X86::POP64r:261    case X86::POP64rmm:262    case X86::POP64rmr:263    case X86::POPF64:264    case X86::POPFS64:265    case X86::POPGS64:266      return 8;267    }268    return 0;269  }270 271  bool isPush(const MCInst &Inst) const override {272    return getPushSize(Inst) == 0 ? false : true;273  }274 275  int getPushSize(const MCInst &Inst) const override {276    switch (Inst.getOpcode()) {277    case X86::PUSH16i8:278    case X86::PUSH16r:279    case X86::PUSH16rmm:280    case X86::PUSH16rmr:281    case X86::PUSHA16:282    case X86::PUSHCS16:283    case X86::PUSHDS16:284    case X86::PUSHES16:285    case X86::PUSHF16:286    case X86::PUSHFS16:287    case X86::PUSHGS16:288    case X86::PUSHSS16:289    case X86::PUSH16i:290      return 2;291    case X86::PUSH32i8:292    case X86::PUSH32r:293    case X86::PUSH32rmm:294    case X86::PUSH32rmr:295    case X86::PUSHA32:296    case X86::PUSHCS32:297    case X86::PUSHDS32:298    case X86::PUSHES32:299    case X86::PUSHF32:300    case X86::PUSHFS32:301    case X86::PUSHGS32:302    case X86::PUSHSS32:303    case X86::PUSH32i:304      return 4;305    case X86::PUSH64i32:306    case X86::PUSH64i8:307    case X86::PUSH64r:308    case X86::PUSH64rmm:309    case X86::PUSH64rmr:310    case X86::PUSHF64:311    case X86::PUSHFS64:312    case X86::PUSHGS64:313      return 8;314    }315    return 0;316  }317 318  bool isSUB(const MCInst &Inst) const override {319    return X86::isSUB(Inst.getOpcode());320  }321 322  bool isLEA64r(const MCInst &Inst) const override {323    return Inst.getOpcode() == X86::LEA64r;324  }325 326  bool isLeave(const MCInst &Inst) const override {327    return Inst.getOpcode() == X86::LEAVE || Inst.getOpcode() == X86::LEAVE64;328  }329 330  bool isMoveMem2Reg(const MCInst &Inst) const override {331    switch (Inst.getOpcode()) {332    case X86::MOV16rm:333    case X86::MOV32rm:334    case X86::MOV64rm:335      return true;336    }337    return false;338  }339 340  bool isUnsupportedInstruction(const MCInst &Inst) const override {341    switch (Inst.getOpcode()) {342    default:343      return false;344 345    case X86::LOOP:346    case X86::LOOPE:347    case X86::LOOPNE:348    case X86::JECXZ:349    case X86::JRCXZ:350      // These have a short displacement, and therefore (often) break after351      // basic block relayout.352      return true;353    }354  }355 356  bool mayLoad(const MCInst &Inst) const override {357    if (isPop(Inst))358      return true;359 360    int MemOpNo = getMemoryOperandNo(Inst);361    const MCInstrDesc &MCII = Info->get(Inst.getOpcode());362 363    if (MemOpNo == -1)364      return false;365 366    return MCII.mayLoad();367  }368 369  bool mayStore(const MCInst &Inst) const override {370    if (isPush(Inst))371      return true;372 373    int MemOpNo = getMemoryOperandNo(Inst);374    const MCInstrDesc &MCII = Info->get(Inst.getOpcode());375 376    if (MemOpNo == -1)377      return false;378 379    return MCII.mayStore();380  }381 382  bool isCleanRegXOR(const MCInst &Inst) const override {383    switch (Inst.getOpcode()) {384    case X86::XOR16rr:385    case X86::XOR32rr:386    case X86::XOR64rr:387      break;388    default:389      return false;390    }391    return (Inst.getOperand(0).getReg() == Inst.getOperand(2).getReg());392  }393 394  bool isPacked(const MCInst &Inst) const override {395    const MCInstrDesc &Desc = Info->get(Inst.getOpcode());396    return (Desc.TSFlags & X86II::OpPrefixMask) == X86II::PD;397  }398 399  bool shouldRecordCodeRelocation(uint32_t RelType) const override {400    switch (RelType) {401    case ELF::R_X86_64_8:402    case ELF::R_X86_64_16:403    case ELF::R_X86_64_32:404    case ELF::R_X86_64_32S:405    case ELF::R_X86_64_64:406    case ELF::R_X86_64_PC8:407    case ELF::R_X86_64_PC32:408    case ELF::R_X86_64_PC64:409    case ELF::R_X86_64_GOTPC64:410    case ELF::R_X86_64_GOTPCRELX:411    case ELF::R_X86_64_REX_GOTPCRELX:412      return true;413    case ELF::R_X86_64_PLT32:414    case ELF::R_X86_64_GOTPCREL:415    case ELF::R_X86_64_TPOFF32:416    case ELF::R_X86_64_GOTTPOFF:417      return false;418    default:419      llvm_unreachable("Unexpected x86 relocation type in code");420    }421  }422 423  StringRef getTrapFillValue() const override { return StringRef("\314", 1); }424 425  struct IndJmpMatcherFrag1 : MCInstMatcher {426    std::unique_ptr<MCInstMatcher> Base;427    std::unique_ptr<MCInstMatcher> Scale;428    std::unique_ptr<MCInstMatcher> Index;429    std::unique_ptr<MCInstMatcher> Offset;430 431    IndJmpMatcherFrag1(std::unique_ptr<MCInstMatcher> Base,432                       std::unique_ptr<MCInstMatcher> Scale,433                       std::unique_ptr<MCInstMatcher> Index,434                       std::unique_ptr<MCInstMatcher> Offset)435        : Base(std::move(Base)), Scale(std::move(Scale)),436          Index(std::move(Index)), Offset(std::move(Offset)) {}437 438    bool match(const MCRegisterInfo &MRI, MCPlusBuilder &MIB,439               MutableArrayRef<MCInst> InInstrWindow, int OpNum) override {440      if (!MCInstMatcher::match(MRI, MIB, InInstrWindow, OpNum))441        return false;442 443      if (CurInst->getOpcode() != X86::JMP64m)444        return false;445 446      int MemOpNo = MIB.getMemoryOperandNo(*CurInst);447      if (MemOpNo == -1)448        return false;449 450      if (!Base->match(MRI, MIB, this->InstrWindow, MemOpNo + X86::AddrBaseReg))451        return false;452      if (!Scale->match(MRI, MIB, this->InstrWindow,453                        MemOpNo + X86::AddrScaleAmt))454        return false;455      if (!Index->match(MRI, MIB, this->InstrWindow,456                        MemOpNo + X86::AddrIndexReg))457        return false;458      if (!Offset->match(MRI, MIB, this->InstrWindow, MemOpNo + X86::AddrDisp))459        return false;460      return true;461    }462 463    void annotate(MCPlusBuilder &MIB, StringRef Annotation) override {464      MIB.addAnnotation(*CurInst, Annotation, true);465      Base->annotate(MIB, Annotation);466      Scale->annotate(MIB, Annotation);467      Index->annotate(MIB, Annotation);468      Offset->annotate(MIB, Annotation);469    }470  };471 472  std::unique_ptr<MCInstMatcher>473  matchIndJmp(std::unique_ptr<MCInstMatcher> Base,474              std::unique_ptr<MCInstMatcher> Scale,475              std::unique_ptr<MCInstMatcher> Index,476              std::unique_ptr<MCInstMatcher> Offset) const override {477    return std::unique_ptr<MCInstMatcher>(478        new IndJmpMatcherFrag1(std::move(Base), std::move(Scale),479                               std::move(Index), std::move(Offset)));480  }481 482  struct IndJmpMatcherFrag2 : MCInstMatcher {483    std::unique_ptr<MCInstMatcher> Reg;484 485    IndJmpMatcherFrag2(std::unique_ptr<MCInstMatcher> Reg)486        : Reg(std::move(Reg)) {}487 488    bool match(const MCRegisterInfo &MRI, MCPlusBuilder &MIB,489               MutableArrayRef<MCInst> InInstrWindow, int OpNum) override {490      if (!MCInstMatcher::match(MRI, MIB, InInstrWindow, OpNum))491        return false;492 493      if (CurInst->getOpcode() != X86::JMP64r)494        return false;495 496      return Reg->match(MRI, MIB, this->InstrWindow, 0);497    }498 499    void annotate(MCPlusBuilder &MIB, StringRef Annotation) override {500      MIB.addAnnotation(*CurInst, Annotation, true);501      Reg->annotate(MIB, Annotation);502    }503  };504 505  std::unique_ptr<MCInstMatcher>506  matchIndJmp(std::unique_ptr<MCInstMatcher> Target) const override {507    return std::unique_ptr<MCInstMatcher>(508        new IndJmpMatcherFrag2(std::move(Target)));509  }510 511  struct LoadMatcherFrag1 : MCInstMatcher {512    std::unique_ptr<MCInstMatcher> Base;513    std::unique_ptr<MCInstMatcher> Scale;514    std::unique_ptr<MCInstMatcher> Index;515    std::unique_ptr<MCInstMatcher> Offset;516 517    LoadMatcherFrag1(std::unique_ptr<MCInstMatcher> Base,518                     std::unique_ptr<MCInstMatcher> Scale,519                     std::unique_ptr<MCInstMatcher> Index,520                     std::unique_ptr<MCInstMatcher> Offset)521        : Base(std::move(Base)), Scale(std::move(Scale)),522          Index(std::move(Index)), Offset(std::move(Offset)) {}523 524    bool match(const MCRegisterInfo &MRI, MCPlusBuilder &MIB,525               MutableArrayRef<MCInst> InInstrWindow, int OpNum) override {526      if (!MCInstMatcher::match(MRI, MIB, InInstrWindow, OpNum))527        return false;528 529      if (CurInst->getOpcode() != X86::MOV64rm &&530          CurInst->getOpcode() != X86::MOVSX64rm32)531        return false;532 533      int MemOpNo = MIB.getMemoryOperandNo(*CurInst);534      if (MemOpNo == -1)535        return false;536 537      if (!Base->match(MRI, MIB, this->InstrWindow, MemOpNo + X86::AddrBaseReg))538        return false;539      if (!Scale->match(MRI, MIB, this->InstrWindow,540                        MemOpNo + X86::AddrScaleAmt))541        return false;542      if (!Index->match(MRI, MIB, this->InstrWindow,543                        MemOpNo + X86::AddrIndexReg))544        return false;545      if (!Offset->match(MRI, MIB, this->InstrWindow, MemOpNo + X86::AddrDisp))546        return false;547      return true;548    }549 550    void annotate(MCPlusBuilder &MIB, StringRef Annotation) override {551      MIB.addAnnotation(*CurInst, Annotation, true);552      Base->annotate(MIB, Annotation);553      Scale->annotate(MIB, Annotation);554      Index->annotate(MIB, Annotation);555      Offset->annotate(MIB, Annotation);556    }557  };558 559  std::unique_ptr<MCInstMatcher>560  matchLoad(std::unique_ptr<MCInstMatcher> Base,561            std::unique_ptr<MCInstMatcher> Scale,562            std::unique_ptr<MCInstMatcher> Index,563            std::unique_ptr<MCInstMatcher> Offset) const override {564    return std::unique_ptr<MCInstMatcher>(565        new LoadMatcherFrag1(std::move(Base), std::move(Scale),566                             std::move(Index), std::move(Offset)));567  }568 569  struct AddMatcher : MCInstMatcher {570    std::unique_ptr<MCInstMatcher> A;571    std::unique_ptr<MCInstMatcher> B;572 573    AddMatcher(std::unique_ptr<MCInstMatcher> A,574               std::unique_ptr<MCInstMatcher> B)575        : A(std::move(A)), B(std::move(B)) {}576 577    bool match(const MCRegisterInfo &MRI, MCPlusBuilder &MIB,578               MutableArrayRef<MCInst> InInstrWindow, int OpNum) override {579      if (!MCInstMatcher::match(MRI, MIB, InInstrWindow, OpNum))580        return false;581 582      if (CurInst->getOpcode() == X86::ADD64rr ||583          CurInst->getOpcode() == X86::ADD64rr_DB ||584          CurInst->getOpcode() == X86::ADD64rr_REV) {585        if (!A->match(MRI, MIB, this->InstrWindow, 1)) {586          if (!B->match(MRI, MIB, this->InstrWindow, 1))587            return false;588          return A->match(MRI, MIB, this->InstrWindow, 2);589        }590 591        if (B->match(MRI, MIB, this->InstrWindow, 2))592          return true;593 594        if (!B->match(MRI, MIB, this->InstrWindow, 1))595          return false;596        return A->match(MRI, MIB, this->InstrWindow, 2);597      }598 599      return false;600    }601 602    void annotate(MCPlusBuilder &MIB, StringRef Annotation) override {603      MIB.addAnnotation(*CurInst, Annotation, true);604      A->annotate(MIB, Annotation);605      B->annotate(MIB, Annotation);606    }607  };608 609  std::unique_ptr<MCInstMatcher>610  matchAdd(std::unique_ptr<MCInstMatcher> A,611           std::unique_ptr<MCInstMatcher> B) const override {612    return std::unique_ptr<MCInstMatcher>(613        new AddMatcher(std::move(A), std::move(B)));614  }615 616  struct LEAMatcher : MCInstMatcher {617    std::unique_ptr<MCInstMatcher> Target;618 619    LEAMatcher(std::unique_ptr<MCInstMatcher> Target)620        : Target(std::move(Target)) {}621 622    bool match(const MCRegisterInfo &MRI, MCPlusBuilder &MIB,623               MutableArrayRef<MCInst> InInstrWindow, int OpNum) override {624      if (!MCInstMatcher::match(MRI, MIB, InInstrWindow, OpNum))625        return false;626 627      if (CurInst->getOpcode() != X86::LEA64r)628        return false;629 630      if (CurInst->getOperand(1 + X86::AddrScaleAmt).getImm() != 1 ||631          CurInst->getOperand(1 + X86::AddrIndexReg).getReg() !=632              X86::NoRegister ||633          (CurInst->getOperand(1 + X86::AddrBaseReg).getReg() !=634               X86::NoRegister &&635           CurInst->getOperand(1 + X86::AddrBaseReg).getReg() != X86::RIP))636        return false;637 638      return Target->match(MRI, MIB, this->InstrWindow, 1 + X86::AddrDisp);639    }640 641    void annotate(MCPlusBuilder &MIB, StringRef Annotation) override {642      MIB.addAnnotation(*CurInst, Annotation, true);643      Target->annotate(MIB, Annotation);644    }645  };646 647  std::unique_ptr<MCInstMatcher>648  matchLoadAddr(std::unique_ptr<MCInstMatcher> Target) const override {649    return std::unique_ptr<MCInstMatcher>(new LEAMatcher(std::move(Target)));650  }651 652  bool hasPCRelOperand(const MCInst &Inst) const override {653    for (const MCOperand &Operand : Inst)654      if (Operand.isReg() && Operand.getReg() == X86::RIP)655        return true;656    return false;657  }658 659  int getMemoryOperandNo(const MCInst &Inst) const override {660    unsigned Opcode = Inst.getOpcode();661    const MCInstrDesc &Desc = Info->get(Opcode);662    int MemOpNo = X86II::getMemoryOperandNo(Desc.TSFlags);663    if (MemOpNo >= 0)664      MemOpNo += X86II::getOperandBias(Desc);665    return MemOpNo;666  }667 668  bool hasEVEXEncoding(const MCInst &Inst) const override {669    const MCInstrDesc &Desc = Info->get(Inst.getOpcode());670    return (Desc.TSFlags & X86II::EncodingMask) == X86II::EVEX;671  }672 673  std::optional<X86MemOperand>674  evaluateX86MemoryOperand(const MCInst &Inst) const override {675    int MemOpNo = getMemoryOperandNo(Inst);676    if (MemOpNo < 0)677      return std::nullopt;678    unsigned MemOpOffset = static_cast<unsigned>(MemOpNo);679 680    if (MemOpOffset + X86::AddrSegmentReg >= MCPlus::getNumPrimeOperands(Inst))681      return std::nullopt;682 683    const MCOperand &Base = Inst.getOperand(MemOpOffset + X86::AddrBaseReg);684    const MCOperand &Scale = Inst.getOperand(MemOpOffset + X86::AddrScaleAmt);685    const MCOperand &Index = Inst.getOperand(MemOpOffset + X86::AddrIndexReg);686    const MCOperand &Disp = Inst.getOperand(MemOpOffset + X86::AddrDisp);687    const MCOperand &Segment =688        Inst.getOperand(MemOpOffset + X86::AddrSegmentReg);689 690    // Make sure it is a well-formed memory operand.691    if (!Base.isReg() || !Scale.isImm() || !Index.isReg() ||692        (!Disp.isImm() && !Disp.isExpr()) || !Segment.isReg())693      return std::nullopt;694 695    X86MemOperand MO;696    MO.BaseRegNum = Base.getReg();697    MO.ScaleImm = Scale.getImm();698    MO.IndexRegNum = Index.getReg();699    MO.DispImm = Disp.isImm() ? Disp.getImm() : 0;700    MO.DispExpr = Disp.isExpr() ? Disp.getExpr() : nullptr;701    MO.SegRegNum = Segment.getReg();702    return MO;703  }704 705  bool evaluateMemOperandTarget(const MCInst &Inst, uint64_t &Target,706                                uint64_t Address,707                                uint64_t Size) const override {708    std::optional<X86MemOperand> MO = evaluateX86MemoryOperand(Inst);709    if (!MO)710      return false;711 712    // Make sure it's a well-formed addressing we can statically evaluate.713    if ((MO->BaseRegNum != X86::RIP && MO->BaseRegNum != X86::NoRegister) ||714        MO->IndexRegNum != X86::NoRegister ||715        MO->SegRegNum != X86::NoRegister || MO->DispExpr)716      return false;717 718    Target = MO->DispImm;719    if (MO->BaseRegNum == X86::RIP) {720      assert(Size != 0 && "instruction size required in order to statically "721                          "evaluate RIP-relative address");722      Target += Address + Size;723    }724    return true;725  }726 727  MCInst::iterator getMemOperandDisp(MCInst &Inst) const override {728    int MemOpNo = getMemoryOperandNo(Inst);729    if (MemOpNo < 0)730      return Inst.end();731    return Inst.begin() + (MemOpNo + X86::AddrDisp);732  }733 734  bool replaceMemOperandDisp(MCInst &Inst, MCOperand Operand) const override {735    MCOperand *OI = getMemOperandDisp(Inst);736    if (OI == Inst.end())737      return false;738    *OI = Operand;739    return true;740  }741 742  /// Get the registers used as function parameters.743  /// This function is specific to the x86_64 abi on Linux.744  BitVector getRegsUsedAsParams() const override {745    BitVector Regs = BitVector(RegInfo->getNumRegs(), false);746    Regs |= getAliases(X86::RSI);747    Regs |= getAliases(X86::RDI);748    Regs |= getAliases(X86::RDX);749    Regs |= getAliases(X86::RCX);750    Regs |= getAliases(X86::R8);751    Regs |= getAliases(X86::R9);752    return Regs;753  }754 755  void getCalleeSavedRegs(BitVector &Regs) const override {756    Regs |= getAliases(X86::RBX);757    Regs |= getAliases(X86::RBP);758    Regs |= getAliases(X86::R12);759    Regs |= getAliases(X86::R13);760    Regs |= getAliases(X86::R14);761    Regs |= getAliases(X86::R15);762  }763 764  void getDefaultDefIn(BitVector &Regs) const override {765    assert(Regs.size() >= RegInfo->getNumRegs() &&766           "The size of BitVector is less than RegInfo->getNumRegs().");767    Regs.set(X86::RAX);768    Regs.set(X86::RCX);769    Regs.set(X86::RDX);770    Regs.set(X86::RSI);771    Regs.set(X86::RDI);772    Regs.set(X86::R8);773    Regs.set(X86::R9);774    Regs.set(X86::XMM0);775    Regs.set(X86::XMM1);776    Regs.set(X86::XMM2);777    Regs.set(X86::XMM3);778    Regs.set(X86::XMM4);779    Regs.set(X86::XMM5);780    Regs.set(X86::XMM6);781    Regs.set(X86::XMM7);782  }783 784  void getDefaultLiveOut(BitVector &Regs) const override {785    assert(Regs.size() >= RegInfo->getNumRegs() &&786           "The size of BitVector is less than RegInfo->getNumRegs().");787    Regs |= getAliases(X86::RAX);788    Regs |= getAliases(X86::RDX);789    Regs |= getAliases(X86::RCX);790    Regs |= getAliases(X86::XMM0);791    Regs |= getAliases(X86::XMM1);792  }793 794  void getGPRegs(BitVector &Regs, bool IncludeAlias) const override {795    if (IncludeAlias) {796      Regs |= getAliases(X86::RAX);797      Regs |= getAliases(X86::RBX);798      Regs |= getAliases(X86::RBP);799      Regs |= getAliases(X86::RSI);800      Regs |= getAliases(X86::RDI);801      Regs |= getAliases(X86::RDX);802      Regs |= getAliases(X86::RCX);803      Regs |= getAliases(X86::R8);804      Regs |= getAliases(X86::R9);805      Regs |= getAliases(X86::R10);806      Regs |= getAliases(X86::R11);807      Regs |= getAliases(X86::R12);808      Regs |= getAliases(X86::R13);809      Regs |= getAliases(X86::R14);810      Regs |= getAliases(X86::R15);811      return;812    }813    Regs.set(X86::RAX);814    Regs.set(X86::RBX);815    Regs.set(X86::RBP);816    Regs.set(X86::RSI);817    Regs.set(X86::RDI);818    Regs.set(X86::RDX);819    Regs.set(X86::RCX);820    Regs.set(X86::R8);821    Regs.set(X86::R9);822    Regs.set(X86::R10);823    Regs.set(X86::R11);824    Regs.set(X86::R12);825    Regs.set(X86::R13);826    Regs.set(X86::R14);827    Regs.set(X86::R15);828  }829 830  void getClassicGPRegs(BitVector &Regs) const override {831    Regs |= getAliases(X86::RAX);832    Regs |= getAliases(X86::RBX);833    Regs |= getAliases(X86::RBP);834    Regs |= getAliases(X86::RSI);835    Regs |= getAliases(X86::RDI);836    Regs |= getAliases(X86::RDX);837    Regs |= getAliases(X86::RCX);838  }839 840  void getRepRegs(BitVector &Regs) const override {841    Regs |= getAliases(X86::RCX);842  }843 844  MCPhysReg getAliasSized(MCPhysReg Reg, uint8_t Size) const override {845    Reg = getX86SubSuperRegister(Reg, Size * 8);846    assert((Reg != X86::NoRegister) && "Invalid register");847    return Reg;848  }849 850  bool isUpper8BitReg(MCPhysReg Reg) const override {851    switch (Reg) {852    case X86::AH:853    case X86::BH:854    case X86::CH:855    case X86::DH:856      return true;857    default:858      return false;859    }860  }861 862  bool cannotUseREX(const MCInst &Inst) const override {863    switch (Inst.getOpcode()) {864    case X86::MOV8mr_NOREX:865    case X86::MOV8rm_NOREX:866    case X86::MOV8rr_NOREX:867    case X86::MOVSX32rm8_NOREX:868    case X86::MOVSX32rr8_NOREX:869    case X86::MOVZX32rm8_NOREX:870    case X86::MOVZX32rr8_NOREX:871    case X86::MOV8mr:872    case X86::MOV8rm:873    case X86::MOV8rr:874    case X86::MOVSX32rm8:875    case X86::MOVSX32rr8:876    case X86::MOVZX32rm8:877    case X86::MOVZX32rr8:878    case X86::TEST8ri:879      for (const MCOperand &Operand : MCPlus::primeOperands(Inst)) {880        if (!Operand.isReg())881          continue;882        if (isUpper8BitReg(Operand.getReg()))883          return true;884      }885      [[fallthrough]];886    default:887      return false;888    }889  }890 891  static uint8_t getMemDataSize(const MCInst &Inst, int MemOpNo) {892    using namespace llvm::X86;893    int OpType = getOperandType(Inst.getOpcode(), MemOpNo);894    return getMemOperandSize(OpType) / 8;895  }896 897  /// Classifying a stack access as *not* "SIMPLE" here means we don't know how898  /// to change this instruction memory access. It will disable any changes to899  /// the stack layout, so we can't do the most aggressive form of shrink900  /// wrapping. We must do so in a way that keeps the original stack layout.901  /// Otherwise you need to adjust the offset of all instructions accessing the902  /// stack: we can't do that anymore because there is one instruction that is903  /// not simple. There are other implications as well. We have heuristics to904  /// detect when a register is callee-saved and thus eligible for shrink905  /// wrapping. If you are restoring a register using a non-simple stack access,906  /// then it is classified as NOT callee-saved, and it disables shrink wrapping907  /// for *that* register (but not for others).908  ///909  /// Classifying a stack access as "size 0" or detecting an indexed memory910  /// access (to address a vector, for example) here means we know there is a911  /// stack access, but we can't quite understand how wide is the access in912  /// bytes. This is very serious because we can't understand how memory913  /// accesses alias with each other for this function. This will essentially914  /// disable not only shrink wrapping but all frame analysis, it will fail it915  /// as "we don't understand this function and we give up on it".916  bool isStackAccess(const MCInst &Inst, bool &IsLoad, bool &IsStore,917                     bool &IsStoreFromReg, MCPhysReg &Reg, int32_t &SrcImm,918                     uint16_t &StackPtrReg, int64_t &StackOffset, uint8_t &Size,919                     bool &IsSimple, bool &IsIndexed) const override {920    // Detect simple push/pop cases first921    if (int Sz = getPushSize(Inst)) {922      IsLoad = false;923      IsStore = true;924      IsStoreFromReg = true;925      StackPtrReg = X86::RSP;926      StackOffset = -Sz;927      Size = Sz;928      IsSimple = true;929      if (Inst.getOperand(0).isImm())930        SrcImm = Inst.getOperand(0).getImm();931      else if (Inst.getOperand(0).isReg())932        Reg = Inst.getOperand(0).getReg();933      else934        IsSimple = false;935 936      return true;937    }938    if (int Sz = getPopSize(Inst)) {939      IsLoad = true;940      IsStore = false;941      if (Inst.getNumOperands() == 0 || !Inst.getOperand(0).isReg()) {942        IsSimple = false;943      } else {944        Reg = Inst.getOperand(0).getReg();945        IsSimple = true;946      }947      StackPtrReg = X86::RSP;948      StackOffset = 0;949      Size = Sz;950      return true;951    }952 953    struct InstInfo {954      // Size in bytes that Inst loads from memory.955      uint8_t DataSize;956      bool IsLoad;957      bool IsStore;958      bool StoreFromReg;959      bool Simple;960    };961 962    InstInfo I;963    int MemOpNo = getMemoryOperandNo(Inst);964    const MCInstrDesc &MCII = Info->get(Inst.getOpcode());965    // If it is not dealing with a memory operand, we discard it966    if (MemOpNo == -1 || MCII.isCall())967      return false;968 969    switch (Inst.getOpcode()) {970    default: {971      bool IsLoad = MCII.mayLoad();972      bool IsStore = MCII.mayStore();973      // Is it LEA? (deals with memory but is not loading nor storing)974      if (!IsLoad && !IsStore) {975        I = {0, IsLoad, IsStore, false, false};976        break;977      }978      uint8_t Sz = getMemDataSize(Inst, MemOpNo);979      I = {Sz, IsLoad, IsStore, false, false};980      break;981    }982    // Report simple stack accesses983    case X86::MOV8rm: I = {1, true, false, false, true}; break;984    case X86::MOV16rm: I = {2, true, false, false, true}; break;985    case X86::MOV32rm: I = {4, true, false, false, true}; break;986    case X86::MOV64rm: I = {8, true, false, false, true}; break;987    case X86::MOV8mr: I = {1, false, true, true, true};  break;988    case X86::MOV16mr: I = {2, false, true, true, true};  break;989    case X86::MOV32mr: I = {4, false, true, true, true};  break;990    case X86::MOV64mr: I = {8, false, true, true, true};  break;991    case X86::MOV8mi: I = {1, false, true, false, true}; break;992    case X86::MOV16mi: I = {2, false, true, false, true}; break;993    case X86::MOV32mi: I = {4, false, true, false, true}; break;994    } // end switch (Inst.getOpcode())995 996    std::optional<X86MemOperand> MO = evaluateX86MemoryOperand(Inst);997    if (!MO) {998      LLVM_DEBUG(dbgs() << "Evaluate failed on ");999      LLVM_DEBUG(Inst.dump());1000      return false;1001    }1002 1003    // Make sure it's a stack access1004    if (MO->BaseRegNum != X86::RBP && MO->BaseRegNum != X86::RSP)1005      return false;1006 1007    IsLoad = I.IsLoad;1008    IsStore = I.IsStore;1009    IsStoreFromReg = I.StoreFromReg;1010    Size = I.DataSize;1011    IsSimple = I.Simple;1012    StackPtrReg = MO->BaseRegNum;1013    StackOffset = MO->DispImm;1014    IsIndexed =1015        MO->IndexRegNum != X86::NoRegister || MO->SegRegNum != X86::NoRegister;1016 1017    if (!I.Simple)1018      return true;1019 1020    // Retrieve related register in simple MOV from/to stack operations.1021    unsigned MemOpOffset = static_cast<unsigned>(MemOpNo);1022    if (I.IsLoad) {1023      MCOperand RegOpnd = Inst.getOperand(0);1024      assert(RegOpnd.isReg() && "unexpected destination operand");1025      Reg = RegOpnd.getReg();1026    } else if (I.IsStore) {1027      MCOperand SrcOpnd =1028          Inst.getOperand(MemOpOffset + X86::AddrSegmentReg + 1);1029      if (I.StoreFromReg) {1030        assert(SrcOpnd.isReg() && "unexpected source operand");1031        Reg = SrcOpnd.getReg();1032      } else {1033        assert(SrcOpnd.isImm() && "unexpected source operand");1034        SrcImm = SrcOpnd.getImm();1035      }1036    }1037 1038    return true;1039  }1040 1041  void changeToPushOrPop(MCInst &Inst) const override {1042    assert(!isPush(Inst) && !isPop(Inst));1043 1044    struct InstInfo {1045      // Size in bytes that Inst loads from memory.1046      uint8_t DataSize;1047      bool IsLoad;1048      bool StoreFromReg;1049    };1050 1051    InstInfo I;1052    switch (Inst.getOpcode()) {1053    default: {1054      llvm_unreachable("Unhandled opcode");1055      return;1056    }1057    case X86::MOV16rm: I = {2, true, false}; break;1058    case X86::MOV32rm: I = {4, true, false}; break;1059    case X86::MOV64rm: I = {8, true, false}; break;1060    case X86::MOV16mr: I = {2, false, true};  break;1061    case X86::MOV32mr: I = {4, false, true};  break;1062    case X86::MOV64mr: I = {8, false, true};  break;1063    case X86::MOV16mi: I = {2, false, false}; break;1064    case X86::MOV32mi: I = {4, false, false}; break;1065    } // end switch (Inst.getOpcode())1066 1067    std::optional<X86MemOperand> MO = evaluateX86MemoryOperand(Inst);1068    if (!MO) {1069      llvm_unreachable("Evaluate failed");1070      return;1071    }1072    // Make sure it's a stack access1073    if (MO->BaseRegNum != X86::RBP && MO->BaseRegNum != X86::RSP) {1074      llvm_unreachable("Not a stack access");1075      return;1076    }1077 1078    unsigned MemOpOffset = getMemoryOperandNo(Inst);1079    unsigned NewOpcode = 0;1080    if (I.IsLoad) {1081      switch (I.DataSize) {1082      case 2: NewOpcode = X86::POP16r; break;1083      case 4: NewOpcode = X86::POP32r; break;1084      case 8: NewOpcode = X86::POP64r; break;1085      default:1086        llvm_unreachable("Unexpected size");1087      }1088      unsigned RegOpndNum = Inst.getOperand(0).getReg();1089      Inst.clear();1090      Inst.setOpcode(NewOpcode);1091      Inst.addOperand(MCOperand::createReg(RegOpndNum));1092    } else {1093      MCOperand SrcOpnd =1094          Inst.getOperand(MemOpOffset + X86::AddrSegmentReg + 1);1095      if (I.StoreFromReg) {1096        switch (I.DataSize) {1097        case 2: NewOpcode = X86::PUSH16r; break;1098        case 4: NewOpcode = X86::PUSH32r; break;1099        case 8: NewOpcode = X86::PUSH64r; break;1100        default:1101          llvm_unreachable("Unexpected size");1102        }1103        assert(SrcOpnd.isReg() && "Unexpected source operand");1104        unsigned RegOpndNum = SrcOpnd.getReg();1105        Inst.clear();1106        Inst.setOpcode(NewOpcode);1107        Inst.addOperand(MCOperand::createReg(RegOpndNum));1108      } else {1109        switch (I.DataSize) {1110        case 2: NewOpcode = X86::PUSH16i8; break;1111        case 4: NewOpcode = X86::PUSH32i8; break;1112        case 8: NewOpcode = X86::PUSH64i32; break;1113        default:1114          llvm_unreachable("Unexpected size");1115        }1116        assert(SrcOpnd.isImm() && "Unexpected source operand");1117        int64_t SrcImm = SrcOpnd.getImm();1118        Inst.clear();1119        Inst.setOpcode(NewOpcode);1120        Inst.addOperand(MCOperand::createImm(SrcImm));1121      }1122    }1123  }1124 1125  bool isStackAdjustment(const MCInst &Inst) const override {1126    switch (Inst.getOpcode()) {1127    default:1128      return false;1129    case X86::SUB64ri32:1130    case X86::SUB64ri8:1131    case X86::ADD64ri32:1132    case X86::ADD64ri8:1133    case X86::LEA64r:1134      break;1135    }1136 1137    return any_of(defOperands(Inst), [](const MCOperand &Op) {1138      return Op.isReg() && Op.getReg() == X86::RSP;1139    });1140  }1141 1142  bool1143  evaluateStackOffsetExpr(const MCInst &Inst, int64_t &Output,1144                          std::pair<MCPhysReg, int64_t> Input1,1145                          std::pair<MCPhysReg, int64_t> Input2) const override {1146 1147    auto getOperandVal = [&](MCPhysReg Reg) -> ErrorOr<int64_t> {1148      if (Reg == Input1.first)1149        return Input1.second;1150      if (Reg == Input2.first)1151        return Input2.second;1152      return make_error_code(errc::result_out_of_range);1153    };1154 1155    switch (Inst.getOpcode()) {1156    default:1157      return false;1158 1159    case X86::SUB64ri32:1160    case X86::SUB64ri8:1161      if (!Inst.getOperand(2).isImm())1162        return false;1163      if (ErrorOr<int64_t> InputVal =1164              getOperandVal(Inst.getOperand(1).getReg()))1165        Output = *InputVal - Inst.getOperand(2).getImm();1166      else1167        return false;1168      break;1169    case X86::ADD64ri32:1170    case X86::ADD64ri8:1171      if (!Inst.getOperand(2).isImm())1172        return false;1173      if (ErrorOr<int64_t> InputVal =1174              getOperandVal(Inst.getOperand(1).getReg()))1175        Output = *InputVal + Inst.getOperand(2).getImm();1176      else1177        return false;1178      break;1179    case X86::ADD64i32:1180      if (!Inst.getOperand(0).isImm())1181        return false;1182      if (ErrorOr<int64_t> InputVal = getOperandVal(X86::RAX))1183        Output = *InputVal + Inst.getOperand(0).getImm();1184      else1185        return false;1186      break;1187 1188    case X86::LEA64r: {1189      std::optional<X86MemOperand> MO = evaluateX86MemoryOperand(Inst);1190      if (!MO)1191        return false;1192 1193      if (MO->BaseRegNum == X86::NoRegister ||1194          MO->IndexRegNum != X86::NoRegister ||1195          MO->SegRegNum != X86::NoRegister || MO->DispExpr)1196        return false;1197 1198      if (ErrorOr<int64_t> InputVal = getOperandVal(MO->BaseRegNum))1199        Output = *InputVal + MO->DispImm;1200      else1201        return false;1202 1203      break;1204    }1205    }1206    return true;1207  }1208 1209  bool isRegToRegMove(const MCInst &Inst, MCPhysReg &From,1210                      MCPhysReg &To) const override {1211    switch (Inst.getOpcode()) {1212    default:1213      return false;1214    case X86::LEAVE:1215    case X86::LEAVE64:1216      To = getStackPointer();1217      From = getFramePointer();1218      return true;1219    case X86::MOV64rr:1220      To = Inst.getOperand(0).getReg();1221      From = Inst.getOperand(1).getReg();1222      return true;1223    }1224  }1225 1226  MCPhysReg getStackPointer() const override { return X86::RSP; }1227  MCPhysReg getFramePointer() const override { return X86::RBP; }1228  MCPhysReg getFlagsReg() const override { return X86::EFLAGS; }1229 1230  bool escapesVariable(const MCInst &Inst,1231                       bool HasFramePointer) const override {1232    int MemOpNo = getMemoryOperandNo(Inst);1233    const MCInstrDesc &MCII = Info->get(Inst.getOpcode());1234    const unsigned NumDefs = MCII.getNumDefs();1235    static BitVector SPBPAliases(BitVector(getAliases(X86::RSP)) |=1236                                 getAliases(X86::RBP));1237    static BitVector SPAliases(getAliases(X86::RSP));1238 1239    // FIXME: PUSH can be technically a leak, but let's ignore this for now1240    // because a lot of harmless prologue code will spill SP to the stack.1241    // Unless push is clearly pushing an object address to the stack as1242    // demonstrated by having a MemOp.1243    bool IsPush = isPush(Inst);1244    if (IsPush && MemOpNo == -1)1245      return false;1246 1247    // We use this to detect LEA (has memop but does not access mem)1248    bool AccessMem = MCII.mayLoad() || MCII.mayStore();1249    bool DoesLeak = false;1250    for (int I = 0, E = MCPlus::getNumPrimeOperands(Inst); I != E; ++I) {1251      // Ignore if SP/BP is used to dereference memory -- that's fine1252      if (MemOpNo != -1 && !IsPush && AccessMem && I >= MemOpNo &&1253          I <= MemOpNo + 5)1254        continue;1255      // Ignore if someone is writing to SP/BP1256      if (I < static_cast<int>(NumDefs))1257        continue;1258 1259      const MCOperand &Operand = Inst.getOperand(I);1260      if (HasFramePointer && Operand.isReg() && SPBPAliases[Operand.getReg()]) {1261        DoesLeak = true;1262        break;1263      }1264      if (!HasFramePointer && Operand.isReg() && SPAliases[Operand.getReg()]) {1265        DoesLeak = true;1266        break;1267      }1268    }1269 1270    // If potential leak, check if it is not just writing to itself/sp/bp1271    if (DoesLeak) {1272      DoesLeak = !any_of(defOperands(Inst), [&](const MCOperand &Operand) {1273        assert(Operand.isReg());1274        MCPhysReg Reg = Operand.getReg();1275        return HasFramePointer ? SPBPAliases[Reg] : SPAliases[Reg];1276      });1277    }1278    return DoesLeak;1279  }1280 1281  bool addToImm(MCInst &Inst, int64_t &Amt, MCContext *Ctx) const override {1282    unsigned ImmOpNo = -1U;1283    int MemOpNo = getMemoryOperandNo(Inst);1284    if (MemOpNo != -1)1285      ImmOpNo = MemOpNo + X86::AddrDisp;1286    else1287      for (unsigned Index = 0; Index < MCPlus::getNumPrimeOperands(Inst);1288           ++Index)1289        if (Inst.getOperand(Index).isImm())1290          ImmOpNo = Index;1291    if (ImmOpNo == -1U)1292      return false;1293 1294    MCOperand &Operand = Inst.getOperand(ImmOpNo);1295    Amt += Operand.getImm();1296    Operand.setImm(Amt);1297    // Check for the need for relaxation1298    if (int64_t(Amt) == int64_t(int8_t(Amt)))1299      return true;1300 1301    // Relax instruction1302    switch (Inst.getOpcode()) {1303    case X86::SUB64ri8:1304      Inst.setOpcode(X86::SUB64ri32);1305      break;1306    case X86::ADD64ri8:1307      Inst.setOpcode(X86::ADD64ri32);1308      break;1309    default:1310      // No need for relaxation1311      break;1312    }1313    return true;1314  }1315 1316  /// TODO: this implementation currently works for the most common opcodes that1317  /// load from memory. It can be extended to work with memory store opcodes as1318  /// well as more memory load opcodes.1319  bool replaceMemOperandWithImm(MCInst &Inst, StringRef ConstantData,1320                                uint64_t Offset) const override {1321    enum CheckSignExt : uint8_t {1322      NOCHECK = 0,1323      CHECK8,1324      CHECK32,1325    };1326 1327    using CheckList = std::vector<std::pair<CheckSignExt, unsigned>>;1328    struct InstInfo {1329      // Size in bytes that Inst loads from memory.1330      uint8_t DataSize;1331 1332      // True when the target operand has to be duplicated because the opcode1333      // expects a LHS operand.1334      bool HasLHS;1335 1336      // List of checks and corresponding opcodes to be used. We try to use the1337      // smallest possible immediate value when various sizes are available,1338      // hence we may need to check whether a larger constant fits in a smaller1339      // immediate.1340      CheckList Checks;1341    };1342 1343    InstInfo I;1344 1345    switch (Inst.getOpcode()) {1346    default: {1347      switch (getPopSize(Inst)) {1348      case 2:            I = {2, false, {{NOCHECK, X86::MOV16ri}}};  break;1349      case 4:            I = {4, false, {{NOCHECK, X86::MOV32ri}}};  break;1350      case 8:            I = {8, false, {{CHECK32, X86::MOV64ri32},1351                                         {NOCHECK, X86::MOV64rm}}};  break;1352      default:           return false;1353      }1354      break;1355    }1356 1357    // MOV1358    case X86::MOV8rm:      I = {1, false, {{NOCHECK, X86::MOV8ri}}};   break;1359    case X86::MOV16rm:     I = {2, false, {{NOCHECK, X86::MOV16ri}}};  break;1360    case X86::MOV32rm:     I = {4, false, {{NOCHECK, X86::MOV32ri}}};  break;1361    case X86::MOV64rm:     I = {8, false, {{CHECK32, X86::MOV64ri32},1362                                           {NOCHECK, X86::MOV64rm}}};  break;1363 1364    // MOVZX1365    case X86::MOVZX16rm8:  I = {1, false, {{NOCHECK, X86::MOV16ri}}};  break;1366    case X86::MOVZX32rm8:  I = {1, false, {{NOCHECK, X86::MOV32ri}}};  break;1367    case X86::MOVZX32rm16: I = {2, false, {{NOCHECK, X86::MOV32ri}}};  break;1368 1369    // CMP1370    case X86::CMP8rm:      I = {1, false, {{NOCHECK, X86::CMP8ri}}};   break;1371    case X86::CMP16rm:     I = {2, false, {{CHECK8,  X86::CMP16ri8},1372                                           {NOCHECK, X86::CMP16ri}}};  break;1373    case X86::CMP32rm:     I = {4, false, {{CHECK8,  X86::CMP32ri8},1374                                           {NOCHECK, X86::CMP32ri}}};  break;1375    case X86::CMP64rm:     I = {8, false, {{CHECK8,  X86::CMP64ri8},1376                                           {CHECK32, X86::CMP64ri32},1377                                           {NOCHECK, X86::CMP64rm}}};  break;1378 1379    // TEST1380    case X86::TEST8mr:     I = {1, false, {{NOCHECK, X86::TEST8ri}}};  break;1381    case X86::TEST16mr:    I = {2, false, {{NOCHECK, X86::TEST16ri}}}; break;1382    case X86::TEST32mr:    I = {4, false, {{NOCHECK, X86::TEST32ri}}}; break;1383    case X86::TEST64mr:    I = {8, false, {{CHECK32, X86::TEST64ri32},1384                                           {NOCHECK, X86::TEST64mr}}}; break;1385 1386    // ADD1387    case X86::ADD8rm:      I = {1, true,  {{NOCHECK, X86::ADD8ri}}};   break;1388    case X86::ADD16rm:     I = {2, true,  {{CHECK8,  X86::ADD16ri8},1389                                           {NOCHECK, X86::ADD16ri}}};  break;1390    case X86::ADD32rm:     I = {4, true,  {{CHECK8,  X86::ADD32ri8},1391                                           {NOCHECK, X86::ADD32ri}}};  break;1392    case X86::ADD64rm:     I = {8, true,  {{CHECK8,  X86::ADD64ri8},1393                                           {CHECK32, X86::ADD64ri32},1394                                           {NOCHECK, X86::ADD64rm}}};  break;1395 1396    // SUB1397    case X86::SUB8rm:      I = {1, true,  {{NOCHECK, X86::SUB8ri}}};   break;1398    case X86::SUB16rm:     I = {2, true,  {{CHECK8,  X86::SUB16ri8},1399                                           {NOCHECK, X86::SUB16ri}}};  break;1400    case X86::SUB32rm:     I = {4, true,  {{CHECK8,  X86::SUB32ri8},1401                                           {NOCHECK, X86::SUB32ri}}};  break;1402    case X86::SUB64rm:     I = {8, true,  {{CHECK8,  X86::SUB64ri8},1403                                           {CHECK32, X86::SUB64ri32},1404                                           {NOCHECK, X86::SUB64rm}}};  break;1405 1406    // AND1407    case X86::AND8rm:      I = {1, true,  {{NOCHECK, X86::AND8ri}}};   break;1408    case X86::AND16rm:     I = {2, true,  {{CHECK8,  X86::AND16ri8},1409                                           {NOCHECK, X86::AND16ri}}};  break;1410    case X86::AND32rm:     I = {4, true,  {{CHECK8,  X86::AND32ri8},1411                                           {NOCHECK, X86::AND32ri}}};  break;1412    case X86::AND64rm:     I = {8, true,  {{CHECK8,  X86::AND64ri8},1413                                           {CHECK32, X86::AND64ri32},1414                                           {NOCHECK, X86::AND64rm}}};  break;1415 1416    // OR1417    case X86::OR8rm:       I = {1, true,  {{NOCHECK, X86::OR8ri}}};    break;1418    case X86::OR16rm:      I = {2, true,  {{CHECK8,  X86::OR16ri8},1419                                           {NOCHECK, X86::OR16ri}}};   break;1420    case X86::OR32rm:      I = {4, true,  {{CHECK8,  X86::OR32ri8},1421                                           {NOCHECK, X86::OR32ri}}};   break;1422    case X86::OR64rm:      I = {8, true,  {{CHECK8,  X86::OR64ri8},1423                                           {CHECK32, X86::OR64ri32},1424                                           {NOCHECK, X86::OR64rm}}};   break;1425 1426    // XOR1427    case X86::XOR8rm:      I = {1, true,  {{NOCHECK, X86::XOR8ri}}};   break;1428    case X86::XOR16rm:     I = {2, true,  {{CHECK8,  X86::XOR16ri8},1429                                           {NOCHECK, X86::XOR16ri}}};  break;1430    case X86::XOR32rm:     I = {4, true,  {{CHECK8,  X86::XOR32ri8},1431                                           {NOCHECK, X86::XOR32ri}}};  break;1432    case X86::XOR64rm:     I = {8, true,  {{CHECK8,  X86::XOR64ri8},1433                                           {CHECK32, X86::XOR64ri32},1434                                           {NOCHECK, X86::XOR64rm}}};  break;1435    }1436 1437    // Compute the immediate value.1438    assert(Offset + I.DataSize <= ConstantData.size() &&1439           "invalid offset for given constant data");1440    int64_t ImmVal =1441        DataExtractor(ConstantData, true, 8).getSigned(&Offset, I.DataSize);1442 1443    // Compute the new opcode.1444    unsigned NewOpcode = 0;1445    for (const std::pair<CheckSignExt, unsigned> &Check : I.Checks) {1446      NewOpcode = Check.second;1447      if (Check.first == NOCHECK)1448        break;1449      if (Check.first == CHECK8 && isInt<8>(ImmVal))1450        break;1451      if (Check.first == CHECK32 && isInt<32>(ImmVal))1452        break;1453    }1454    if (NewOpcode == Inst.getOpcode())1455      return false;1456 1457    // Modify the instruction.1458    MCOperand ImmOp = MCOperand::createImm(ImmVal);1459    uint32_t TargetOpNum = 0;1460    // Test instruction does not follow the regular pattern of putting the1461    // memory reference of a load (5 MCOperands) last in the list of operands.1462    // Since it is not modifying the register operand, it is not treated as1463    // a destination operand and it is not the first operand as it is in the1464    // other instructions we treat here.1465    if (NewOpcode == X86::TEST8ri || NewOpcode == X86::TEST16ri ||1466        NewOpcode == X86::TEST32ri || NewOpcode == X86::TEST64ri32)1467      TargetOpNum = getMemoryOperandNo(Inst) + X86::AddrNumOperands;1468 1469    MCOperand TargetOp = Inst.getOperand(TargetOpNum);1470    Inst.clear();1471    Inst.setOpcode(NewOpcode);1472    Inst.addOperand(TargetOp);1473    if (I.HasLHS)1474      Inst.addOperand(TargetOp);1475    Inst.addOperand(ImmOp);1476 1477    return true;1478  }1479 1480  /// TODO: this implementation currently works for the most common opcodes that1481  /// load from memory. It can be extended to work with memory store opcodes as1482  /// well as more memory load opcodes.1483  bool replaceMemOperandWithReg(MCInst &Inst, MCPhysReg RegNum) const override {1484    unsigned NewOpcode;1485 1486    switch (Inst.getOpcode()) {1487    default: {1488      switch (getPopSize(Inst)) {1489      case 2:            NewOpcode = X86::MOV16rr; break;1490      case 4:            NewOpcode = X86::MOV32rr; break;1491      case 8:            NewOpcode = X86::MOV64rr; break;1492      default:           return false;1493      }1494      break;1495    }1496 1497    // MOV1498    case X86::MOV8rm:      NewOpcode = X86::MOV8rr;   break;1499    case X86::MOV16rm:     NewOpcode = X86::MOV16rr;  break;1500    case X86::MOV32rm:     NewOpcode = X86::MOV32rr;  break;1501    case X86::MOV64rm:     NewOpcode = X86::MOV64rr;  break;1502    }1503 1504    // Modify the instruction.1505    MCOperand RegOp = MCOperand::createReg(RegNum);1506    MCOperand TargetOp = Inst.getOperand(0);1507    Inst.clear();1508    Inst.setOpcode(NewOpcode);1509    Inst.addOperand(TargetOp);1510    Inst.addOperand(RegOp);1511 1512    return true;1513  }1514 1515  bool isRedundantMove(const MCInst &Inst) const override {1516    switch (Inst.getOpcode()) {1517    default:1518      return false;1519 1520    // MOV1521    case X86::MOV8rr:1522    case X86::MOV16rr:1523    case X86::MOV32rr:1524    case X86::MOV64rr:1525      break;1526    }1527 1528    assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg());1529    return Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg();1530  }1531 1532  bool requiresAlignedAddress(const MCInst &Inst) const override {1533    const MCInstrDesc &Desc = Info->get(Inst.getOpcode());1534    for (unsigned int I = 0; I < Desc.getNumOperands(); ++I) {1535      const MCOperandInfo &Op = Desc.operands()[I];1536      if (Op.OperandType != MCOI::OPERAND_REGISTER)1537        continue;1538      if (Op.RegClass == X86::VR128RegClassID)1539        return true;1540    }1541    return false;1542  }1543 1544  bool convertJmpToTailCall(MCInst &Inst) override {1545    if (isTailCall(Inst))1546      return false;1547 1548    int NewOpcode;1549    switch (Inst.getOpcode()) {1550    default:1551      return false;1552    case X86::JMP_1:1553    case X86::JMP_2:1554    case X86::JMP_4:1555      NewOpcode = X86::JMP_4;1556      break;1557    case X86::JMP16m:1558    case X86::JMP32m:1559    case X86::JMP64m:1560      NewOpcode = X86::JMP32m;1561      break;1562    case X86::JMP16r:1563    case X86::JMP32r:1564    case X86::JMP64r:1565      NewOpcode = X86::JMP32r;1566      break;1567    }1568 1569    Inst.setOpcode(NewOpcode);1570    setTailCall(Inst);1571    return true;1572  }1573 1574  bool convertTailCallToJmp(MCInst &Inst) override {1575    int NewOpcode;1576    switch (Inst.getOpcode()) {1577    default:1578      return false;1579    case X86::JMP_4:1580      NewOpcode = X86::JMP_1;1581      break;1582    case X86::JMP32m:1583      NewOpcode = X86::JMP64m;1584      break;1585    case X86::JMP32r:1586      NewOpcode = X86::JMP64r;1587      break;1588    }1589 1590    Inst.setOpcode(NewOpcode);1591    removeAnnotation(Inst, MCPlus::MCAnnotation::kTailCall);1592    clearOffset(Inst);1593    return true;1594  }1595 1596  bool convertTailCallToCall(MCInst &Inst) override {1597    int NewOpcode;1598    switch (Inst.getOpcode()) {1599    default:1600      return false;1601    case X86::JMP_4:1602      NewOpcode = X86::CALL64pcrel32;1603      break;1604    case X86::JMP32m:1605      NewOpcode = X86::CALL64m;1606      break;1607    case X86::JMP32r:1608      NewOpcode = X86::CALL64r;1609      break;1610    }1611 1612    Inst.setOpcode(NewOpcode);1613    removeAnnotation(Inst, MCPlus::MCAnnotation::kTailCall);1614    return true;1615  }1616 1617  InstructionListType createIndirectPLTCall(MCInst &&DirectCall,1618                                            const MCSymbol *TargetLocation,1619                                            MCContext *Ctx) override {1620    assert((DirectCall.getOpcode() == X86::CALL64pcrel32 ||1621            (DirectCall.getOpcode() == X86::JMP_4 && isTailCall(DirectCall))) &&1622           "64-bit direct (tail) call instruction expected");1623 1624    InstructionListType Code;1625    // Create a new indirect call by converting the previous direct call.1626    MCInst Inst = DirectCall;1627    const auto NewOpcode =1628        (Inst.getOpcode() == X86::CALL64pcrel32) ? X86::CALL64m : X86::JMP32m;1629    Inst.setOpcode(NewOpcode);1630 1631    // Replace the first operand and preserve auxiliary operands of1632    // the instruction.1633    Inst.erase(Inst.begin());1634    Inst.insert(Inst.begin(),1635                MCOperand::createReg(X86::NoRegister)); // AddrSegmentReg1636    Inst.insert(Inst.begin(),1637                MCOperand::createExpr( // Displacement1638                    MCSymbolRefExpr::create(TargetLocation, *Ctx)));1639    Inst.insert(Inst.begin(),1640                MCOperand::createReg(X86::NoRegister)); // IndexReg1641    Inst.insert(Inst.begin(),1642                MCOperand::createImm(1));               // ScaleAmt1643    Inst.insert(Inst.begin(),1644                MCOperand::createReg(X86::RIP));        // BaseReg1645 1646    Code.emplace_back(Inst);1647    return Code;1648  }1649 1650  void convertIndirectCallToLoad(MCInst &Inst, MCPhysReg Reg) override {1651    bool IsTailCall = isTailCall(Inst);1652    if (IsTailCall)1653      removeAnnotation(Inst, MCPlus::MCAnnotation::kTailCall);1654    if (Inst.getOpcode() == X86::CALL64m ||1655        (Inst.getOpcode() == X86::JMP32m && IsTailCall)) {1656      Inst.setOpcode(X86::MOV64rm);1657      Inst.insert(Inst.begin(), MCOperand::createReg(Reg));1658      return;1659    }1660    if (Inst.getOpcode() == X86::CALL64r ||1661        (Inst.getOpcode() == X86::JMP32r && IsTailCall)) {1662      Inst.setOpcode(X86::MOV64rr);1663      Inst.insert(Inst.begin(), MCOperand::createReg(Reg));1664      return;1665    }1666    LLVM_DEBUG(Inst.dump());1667    llvm_unreachable("not implemented");1668  }1669 1670  bool shortenInstruction(MCInst &Inst,1671                          const MCSubtargetInfo &STI) const override {1672    unsigned OldOpcode = Inst.getOpcode();1673    unsigned NewOpcode = OldOpcode;1674 1675    int MemOpNo = getMemoryOperandNo(Inst);1676 1677    // Check and remove redundant Address-Size override prefix.1678    if (opts::X86StripRedundantAddressSize) {1679      uint64_t TSFlags = Info->get(OldOpcode).TSFlags;1680      unsigned Flags = Inst.getFlags();1681 1682      if (!X86_MC::needsAddressSizeOverride(Inst, STI, MemOpNo, TSFlags) &&1683          Flags & X86::IP_HAS_AD_SIZE)1684        Inst.setFlags(Flags ^ X86::IP_HAS_AD_SIZE);1685    }1686 1687    // Check and remove EIZ/RIZ. These cases represent ambiguous cases where1688    // SIB byte is present, but no index is used and modrm alone should have1689    // been enough. Converting to NoRegister effectively removes the SIB byte.1690    if (MemOpNo >= 0) {1691      MCOperand &IndexOp =1692          Inst.getOperand(static_cast<unsigned>(MemOpNo) + X86::AddrIndexReg);1693      if (IndexOp.getReg() == X86::EIZ || IndexOp.getReg() == X86::RIZ)1694        IndexOp = MCOperand::createReg(X86::NoRegister);1695    }1696 1697    if (isBranch(Inst)) {1698      NewOpcode = getShortBranchOpcode(OldOpcode);1699    } else if (OldOpcode == X86::MOV64ri) {1700      if (Inst.getOperand(MCPlus::getNumPrimeOperands(Inst) - 1).isImm()) {1701        const int64_t Imm =1702            Inst.getOperand(MCPlus::getNumPrimeOperands(Inst) - 1).getImm();1703        if (int64_t(Imm) == int64_t(int32_t(Imm)))1704          NewOpcode = X86::MOV64ri32;1705      }1706    } else {1707      // If it's arithmetic instruction check if signed operand fits in 1 byte.1708      const unsigned ShortOpcode = X86::getOpcodeForShortImmediateForm(OldOpcode);1709      if (ShortOpcode != OldOpcode &&1710          Inst.getOperand(MCPlus::getNumPrimeOperands(Inst) - 1).isImm()) {1711        int64_t Imm =1712            Inst.getOperand(MCPlus::getNumPrimeOperands(Inst) - 1).getImm();1713        if (int64_t(Imm) == int64_t(int8_t(Imm)))1714          NewOpcode = ShortOpcode;1715      }1716    }1717 1718    if (NewOpcode == OldOpcode)1719      return false;1720 1721    Inst.setOpcode(NewOpcode);1722    return true;1723  }1724 1725  bool1726  convertMoveToConditionalMove(MCInst &Inst, unsigned CC, bool AllowStackMemOp,1727                               bool AllowBasePtrStackMemOp) const override {1728    // - Register-register moves are OK1729    // - Stores are filtered out by opcode (no store CMOV)1730    // - Non-stack loads are prohibited (generally unsafe)1731    // - Stack loads are OK if AllowStackMemOp is true1732    // - Stack loads with RBP are OK if AllowBasePtrStackMemOp is true1733    if (mayLoad(Inst)) {1734      // If stack memory operands are not allowed, no loads are allowed1735      if (!AllowStackMemOp)1736        return false;1737 1738      // If stack memory operands are allowed, check if it's a load from stack1739      bool IsLoad, IsStore, IsStoreFromReg, IsSimple, IsIndexed;1740      MCPhysReg Reg;1741      int32_t SrcImm;1742      uint16_t StackPtrReg;1743      int64_t StackOffset;1744      uint8_t Size;1745      bool IsStackAccess =1746          isStackAccess(Inst, IsLoad, IsStore, IsStoreFromReg, Reg, SrcImm,1747                        StackPtrReg, StackOffset, Size, IsSimple, IsIndexed);1748      // Prohibit non-stack-based loads1749      if (!IsStackAccess)1750        return false;1751      // If stack memory operands are allowed, check if it's RBP-based1752      if (!AllowBasePtrStackMemOp &&1753          RegInfo->isSubRegisterEq(X86::RBP, StackPtrReg))1754        return false;1755    }1756 1757    unsigned NewOpcode = 0;1758    switch (Inst.getOpcode()) {1759    case X86::MOV16rr:1760      NewOpcode = X86::CMOV16rr;1761      break;1762    case X86::MOV16rm:1763      NewOpcode = X86::CMOV16rm;1764      break;1765    case X86::MOV32rr:1766      NewOpcode = X86::CMOV32rr;1767      break;1768    case X86::MOV32rm:1769      NewOpcode = X86::CMOV32rm;1770      break;1771    case X86::MOV64rr:1772      NewOpcode = X86::CMOV64rr;1773      break;1774    case X86::MOV64rm:1775      NewOpcode = X86::CMOV64rm;1776      break;1777    default:1778      return false;1779    }1780    Inst.setOpcode(NewOpcode);1781    // Insert CC at the end of prime operands, before annotations1782    Inst.insert(Inst.begin() + MCPlus::getNumPrimeOperands(Inst),1783                MCOperand::createImm(CC));1784    // CMOV is a 3-operand MCInst, so duplicate the destination as src11785    Inst.insert(Inst.begin(), Inst.getOperand(0));1786    return true;1787  }1788 1789  bool lowerTailCall(MCInst &Inst) override {1790    if (Inst.getOpcode() == X86::JMP_4 && isTailCall(Inst)) {1791      Inst.setOpcode(X86::JMP_1);1792      removeAnnotation(Inst, MCPlus::MCAnnotation::kTailCall);1793      return true;1794    }1795    return false;1796  }1797 1798  const MCSymbol *getTargetSymbol(const MCInst &Inst,1799                                  unsigned OpNum = 0) const override {1800    if (OpNum >= MCPlus::getNumPrimeOperands(Inst))1801      return nullptr;1802 1803    const MCOperand &Op = Inst.getOperand(OpNum);1804    if (!Op.isExpr())1805      return nullptr;1806 1807    return MCPlusBuilder::getTargetSymbol(Op.getExpr());1808  }1809 1810  bool analyzeBranch(InstructionIterator Begin, InstructionIterator End,1811                     const MCSymbol *&TBB, const MCSymbol *&FBB,1812                     MCInst *&CondBranch,1813                     MCInst *&UncondBranch) const override {1814    auto I = End;1815 1816    // Bottom-up analysis1817    while (I != Begin) {1818      --I;1819 1820      // Ignore nops and CFIs1821      if (isPseudo(*I))1822        continue;1823 1824      // Stop when we find the first non-terminator1825      if (!isTerminator(*I))1826        break;1827 1828      if (!isBranch(*I))1829        break;1830 1831      // Handle unconditional branches.1832      if ((I->getOpcode() == X86::JMP_1 || I->getOpcode() == X86::JMP_2 ||1833           I->getOpcode() == X86::JMP_4) &&1834          !isTailCall(*I)) {1835        // If any code was seen after this unconditional branch, we've seen1836        // unreachable code. Ignore them.1837        CondBranch = nullptr;1838        UncondBranch = &*I;1839        const MCSymbol *Sym = getTargetSymbol(*I);1840        assert(Sym != nullptr &&1841               "Couldn't extract BB symbol from jump operand");1842        TBB = Sym;1843        continue;1844      }1845 1846      // Ignore indirect branches1847      if (getCondCode(*I) == X86::COND_INVALID)1848        return false;1849 1850      if (CondBranch == nullptr) {1851        const MCSymbol *TargetBB = getTargetSymbol(*I);1852        if (TargetBB == nullptr) {1853          // Unrecognized branch target1854          return false;1855        }1856        FBB = TBB;1857        TBB = TargetBB;1858        CondBranch = &*I;1859        continue;1860      }1861 1862      llvm_unreachable("multiple conditional branches in one BB");1863    }1864    return true;1865  }1866 1867  /// Analyzes PIC-style jump table code template and return identified1868  /// IndirectBranchType, MemLocInstr (all cases) and FixedEntryLoadInstr1869  /// (POSSIBLE_PIC_FIXED_BRANCH case).1870  template <typename Itr>1871  std::tuple<IndirectBranchType, MCInst *, MCInst *>1872  analyzePICJumpTable(Itr II, Itr IE, MCPhysReg R1, MCPhysReg R2) const {1873    // Analyze PIC-style jump table code template:1874    //1875    //    lea PIC_JUMP_TABLE(%rip), {%r1|%r2}     <- MemLocInstr1876    //    mov ({%r1|%r2}, %index, 4), {%r2|%r1}1877    //    add %r2, %r11878    //    jmp *%r11879    //1880    // or a fixed indirect jump template:1881    //1882    //    movslq En(%rip), {%r2|%r1}              <- FixedEntryLoadInstr1883    //    lea PIC_JUMP_TABLE(%rip), {%r1|%r2}     <- MemLocInstr1884    //    add %r2, %r11885    //    jmp *%r11886    //1887    // (with any irrelevant instructions in-between)1888    //1889    // When we call this helper we've already determined %r1 and %r2, and1890    // reverse instruction iterator \p II is pointing to the ADD instruction.1891    //1892    // PIC jump table looks like following:1893    //1894    //   JT:  ----------1895    //    E1:| L1 - JT  |1896    //       |----------|1897    //    E2:| L2 - JT  |1898    //       |----------|1899    //       |          |1900    //          ......1901    //    En:| Ln - JT  |1902    //        ----------1903    //1904    // Where L1, L2, ..., Ln represent labels in the function.1905    //1906    // The actual relocations in the table will be of the form:1907    //1908    //   Ln - JT1909    //    = (Ln - En) + (En - JT)1910    //    = R_X86_64_PC32(Ln) + En - JT1911    //    = R_X86_64_PC32(Ln + offsetof(En))1912    //1913    auto isRIPRel = [&](X86MemOperand &MO) {1914      // NB: DispExpr should be set1915      return MO.DispExpr != nullptr &&1916             MO.BaseRegNum == RegInfo->getProgramCounter() &&1917             MO.IndexRegNum == X86::NoRegister &&1918             MO.SegRegNum == X86::NoRegister;1919    };1920    auto isIndexed = [](X86MemOperand &MO, MCPhysReg R) {1921      // NB: IndexRegNum should be set.1922      return MO.IndexRegNum != X86::NoRegister && MO.BaseRegNum == R &&1923             MO.ScaleImm == 4 && MO.DispImm == 0 &&1924             MO.SegRegNum == X86::NoRegister;1925    };1926    LLVM_DEBUG(dbgs() << "Checking for PIC jump table\n");1927    MCInst *FirstInstr = nullptr;1928    MCInst *SecondInstr = nullptr;1929    enum {1930      NOMATCH = 0,1931      MATCH_JUMP_TABLE,1932      MATCH_FIXED_BRANCH,1933    } MatchingState = NOMATCH;1934    while (++II != IE) {1935      MCInst &Instr = *II;1936      const MCInstrDesc &InstrDesc = Info->get(Instr.getOpcode());1937      if (!InstrDesc.hasDefOfPhysReg(Instr, R1, *RegInfo) &&1938          !InstrDesc.hasDefOfPhysReg(Instr, R2, *RegInfo)) {1939        // Ignore instructions that don't affect R1, R2 registers.1940        continue;1941      }1942      const bool IsMOVSXInstr = isMOVSX64rm32(Instr);1943      const bool IsLEAInstr = isLEA64r(Instr);1944      if (MatchingState == NOMATCH) {1945        if (IsMOVSXInstr)1946          MatchingState = MATCH_JUMP_TABLE;1947        else if (IsLEAInstr)1948          MatchingState = MATCH_FIXED_BRANCH;1949        else1950          break;1951 1952        // Check if the first instruction is setting %r1 or %r2. In canonical1953        // form lea sets %r1 and mov sets %r2. If it's the opposite - rename so1954        // we have to only check a single form.1955        unsigned DestReg = Instr.getOperand(0).getReg();1956        MCPhysReg &ExpectReg = MatchingState == MATCH_JUMP_TABLE ? R2 : R1;1957        if (DestReg != ExpectReg)1958          std::swap(R1, R2);1959        if (DestReg != ExpectReg)1960          break;1961 1962        // Verify operands1963        std::optional<X86MemOperand> MO = evaluateX86MemoryOperand(Instr);1964        if (!MO)1965          break;1966        if ((MatchingState == MATCH_JUMP_TABLE && isIndexed(*MO, R1)) ||1967            (MatchingState == MATCH_FIXED_BRANCH && isRIPRel(*MO)))1968          FirstInstr = &Instr;1969        else1970          break;1971      } else {1972        unsigned ExpectReg = MatchingState == MATCH_JUMP_TABLE ? R1 : R2;1973        if (!InstrDesc.hasDefOfPhysReg(Instr, ExpectReg, *RegInfo))1974          continue;1975        if ((MatchingState == MATCH_JUMP_TABLE && !IsLEAInstr) ||1976            (MatchingState == MATCH_FIXED_BRANCH && !IsMOVSXInstr))1977          break;1978        if (Instr.getOperand(0).getReg() != ExpectReg)1979          break;1980 1981        // Verify operands.1982        std::optional<X86MemOperand> MO = evaluateX86MemoryOperand(Instr);1983        if (!MO)1984          break;1985        if (!isRIPRel(*MO))1986          break;1987        SecondInstr = &Instr;1988        break;1989      }1990    }1991 1992    if (!SecondInstr)1993      return std::make_tuple(IndirectBranchType::UNKNOWN, nullptr, nullptr);1994 1995    if (MatchingState == MATCH_FIXED_BRANCH) {1996      LLVM_DEBUG(dbgs() << "checking potential fixed indirect branch\n");1997      return std::make_tuple(IndirectBranchType::POSSIBLE_PIC_FIXED_BRANCH,1998                             FirstInstr, SecondInstr);1999    }2000    LLVM_DEBUG(dbgs() << "checking potential PIC jump table\n");2001    return std::make_tuple(IndirectBranchType::POSSIBLE_PIC_JUMP_TABLE,2002                           SecondInstr, nullptr);2003  }2004 2005  IndirectBranchType2006  analyzeIndirectBranch(MCInst &Instruction, InstructionIterator Begin,2007                        InstructionIterator End, const unsigned PtrSize,2008                        MCInst *&MemLocInstrOut, unsigned &BaseRegNumOut,2009                        unsigned &IndexRegNumOut, int64_t &DispValueOut,2010                        const MCExpr *&DispExprOut, MCInst *&PCRelBaseOut,2011                        MCInst *&FixedEntryLoadInst) const override {2012    // Try to find a (base) memory location from where the address for2013    // the indirect branch is loaded. For X86-64 the memory will be specified2014    // in the following format:2015    //2016    //   {%rip}/{%basereg} + Imm + IndexReg * Scale2017    //2018    // We are interested in the cases where Scale == sizeof(uintptr_t) and2019    // the contents of the memory are presumably an array of pointers to code.2020    //2021    // Normal jump table:2022    //2023    //    jmp *(JUMP_TABLE, %index, Scale)        <- MemLocInstr2024    //2025    //    or2026    //2027    //    mov (JUMP_TABLE, %index, Scale), %r1    <- MemLocInstr2028    //    ...2029    //    jmp %r12030    //2031    // We handle PIC-style jump tables separately.2032    //2033    MemLocInstrOut = nullptr;2034    BaseRegNumOut = X86::NoRegister;2035    IndexRegNumOut = X86::NoRegister;2036    DispValueOut = 0;2037    DispExprOut = nullptr;2038    FixedEntryLoadInst = nullptr;2039 2040    std::reverse_iterator<InstructionIterator> II(End);2041    std::reverse_iterator<InstructionIterator> IE(Begin);2042 2043    IndirectBranchType Type = IndirectBranchType::UNKNOWN;2044 2045    // An instruction referencing memory used by jump instruction (directly or2046    // via register). This location could be an array of function pointers2047    // in case of indirect tail call, or a jump table.2048    MCInst *MemLocInstr = nullptr;2049 2050    if (MCPlus::getNumPrimeOperands(Instruction) == 1) {2051      // If the indirect jump is on register - try to detect if the2052      // register value is loaded from a memory location.2053      assert(Instruction.getOperand(0).isReg() && "register operand expected");2054      const unsigned R1 = Instruction.getOperand(0).getReg();2055      // Check if one of the previous instructions defines the jump-on register.2056      for (auto PrevII = II; PrevII != IE; ++PrevII) {2057        MCInst &PrevInstr = *PrevII;2058        const MCInstrDesc &PrevInstrDesc = Info->get(PrevInstr.getOpcode());2059 2060        if (!PrevInstrDesc.hasDefOfPhysReg(PrevInstr, R1, *RegInfo))2061          continue;2062 2063        if (isMoveMem2Reg(PrevInstr)) {2064          MemLocInstr = &PrevInstr;2065          break;2066        }2067        if (isADD64rr(PrevInstr)) {2068          unsigned R2 = PrevInstr.getOperand(2).getReg();2069          if (R1 == R2)2070            return IndirectBranchType::UNKNOWN;2071          std::tie(Type, MemLocInstr, FixedEntryLoadInst) =2072              analyzePICJumpTable(PrevII, IE, R1, R2);2073          break;2074        }2075        return IndirectBranchType::UNKNOWN;2076      }2077      if (!MemLocInstr) {2078        // No definition seen for the register in this function so far. Could be2079        // an input parameter - which means it is an external code reference.2080        // It also could be that the definition happens to be in the code that2081        // we haven't processed yet. Since we have to be conservative, return2082        // as UNKNOWN case.2083        return IndirectBranchType::UNKNOWN;2084      }2085    } else {2086      MemLocInstr = &Instruction;2087    }2088 2089    const MCRegister RIPRegister = RegInfo->getProgramCounter();2090 2091    // Analyze the memory location.2092    std::optional<X86MemOperand> MO = evaluateX86MemoryOperand(*MemLocInstr);2093    if (!MO)2094      return IndirectBranchType::UNKNOWN;2095 2096    BaseRegNumOut = MO->BaseRegNum;2097    IndexRegNumOut = MO->IndexRegNum;2098    DispValueOut = MO->DispImm;2099    DispExprOut = MO->DispExpr;2100 2101    if ((MO->BaseRegNum != X86::NoRegister && MO->BaseRegNum != RIPRegister) ||2102        MO->SegRegNum != X86::NoRegister)2103      return IndirectBranchType::UNKNOWN;2104 2105    if (MemLocInstr == &Instruction &&2106        (!MO->ScaleImm || MO->IndexRegNum == X86::NoRegister)) {2107      MemLocInstrOut = MemLocInstr;2108      return IndirectBranchType::POSSIBLE_FIXED_BRANCH;2109    }2110 2111    switch (Type) {2112    case IndirectBranchType::POSSIBLE_PIC_JUMP_TABLE:2113      if (MO->ScaleImm != 1 || MO->BaseRegNum != RIPRegister)2114        return IndirectBranchType::UNKNOWN;2115      break;2116    case IndirectBranchType::POSSIBLE_PIC_FIXED_BRANCH:2117      break;2118    default:2119      if (MO->ScaleImm != PtrSize)2120        return IndirectBranchType::UNKNOWN;2121    }2122 2123    MemLocInstrOut = MemLocInstr;2124 2125    return Type;2126  }2127 2128  /// Analyze a callsite to see if it could be a virtual method call.  This only2129  /// checks to see if the overall pattern is satisfied, it does not guarantee2130  /// that the callsite is a true virtual method call.2131  /// The format of virtual method calls that are recognized is one of the2132  /// following:2133  ///2134  ///  Form 1: (found in debug code)2135  ///    add METHOD_OFFSET, %VtableReg2136  ///    mov (%VtableReg), %MethodReg2137  ///    ...2138  ///    call or jmp *%MethodReg2139  ///2140  ///  Form 2:2141  ///    mov METHOD_OFFSET(%VtableReg), %MethodReg2142  ///    ...2143  ///    call or jmp *%MethodReg2144  ///2145  ///  Form 3:2146  ///    ...2147  ///    call or jmp *METHOD_OFFSET(%VtableReg)2148  ///2149  bool analyzeVirtualMethodCall(InstructionIterator ForwardBegin,2150                                InstructionIterator ForwardEnd,2151                                std::vector<MCInst *> &MethodFetchInsns,2152                                unsigned &VtableRegNum, unsigned &MethodRegNum,2153                                uint64_t &MethodOffset) const override {2154    VtableRegNum = X86::NoRegister;2155    MethodRegNum = X86::NoRegister;2156    MethodOffset = 0;2157 2158    std::reverse_iterator<InstructionIterator> Itr(ForwardEnd);2159    std::reverse_iterator<InstructionIterator> End(ForwardBegin);2160 2161    MCInst &CallInst = *Itr++;2162    assert(isIndirectBranch(CallInst) || isCall(CallInst));2163 2164    // The call can just be jmp offset(reg)2165    if (std::optional<X86MemOperand> MO = evaluateX86MemoryOperand(CallInst)) {2166      if (!MO->DispExpr && MO->BaseRegNum != X86::RIP &&2167          MO->BaseRegNum != X86::RBP && MO->BaseRegNum != X86::NoRegister) {2168        MethodRegNum = MO->BaseRegNum;2169        if (MO->ScaleImm == 1 && MO->IndexRegNum == X86::NoRegister &&2170            MO->SegRegNum == X86::NoRegister) {2171          VtableRegNum = MethodRegNum;2172          MethodOffset = MO->DispImm;2173          MethodFetchInsns.push_back(&CallInst);2174          return true;2175        }2176      }2177      return false;2178    }2179    if (CallInst.getOperand(0).isReg())2180      MethodRegNum = CallInst.getOperand(0).getReg();2181    else2182      return false;2183 2184    if (MethodRegNum == X86::RIP || MethodRegNum == X86::RBP) {2185      VtableRegNum = X86::NoRegister;2186      MethodRegNum = X86::NoRegister;2187      return false;2188    }2189 2190    // find load from vtable, this may or may not include the method offset2191    while (Itr != End) {2192      MCInst &CurInst = *Itr++;2193      const MCInstrDesc &Desc = Info->get(CurInst.getOpcode());2194      if (Desc.hasDefOfPhysReg(CurInst, MethodRegNum, *RegInfo)) {2195        if (!mayLoad(CurInst))2196          return false;2197        if (std::optional<X86MemOperand> MO =2198                evaluateX86MemoryOperand(CurInst)) {2199          if (!MO->DispExpr && MO->ScaleImm == 1 &&2200              MO->BaseRegNum != X86::RIP && MO->BaseRegNum != X86::RBP &&2201              MO->BaseRegNum != X86::NoRegister &&2202              MO->IndexRegNum == X86::NoRegister &&2203              MO->SegRegNum == X86::NoRegister) {2204            VtableRegNum = MO->BaseRegNum;2205            MethodOffset = MO->DispImm;2206            MethodFetchInsns.push_back(&CurInst);2207            if (MethodOffset != 0)2208              return true;2209            break;2210          }2211        }2212        return false;2213      }2214    }2215 2216    if (!VtableRegNum)2217      return false;2218 2219    // look for any adds affecting the method register.2220    while (Itr != End) {2221      MCInst &CurInst = *Itr++;2222      const MCInstrDesc &Desc = Info->get(CurInst.getOpcode());2223      if (Desc.hasDefOfPhysReg(CurInst, VtableRegNum, *RegInfo)) {2224        if (isADDri(CurInst)) {2225          assert(!MethodOffset);2226          MethodOffset = CurInst.getOperand(2).getImm();2227          MethodFetchInsns.insert(MethodFetchInsns.begin(), &CurInst);2228          break;2229        }2230      }2231    }2232 2233    return true;2234  }2235 2236  void createStackPointerIncrement(MCInst &Inst, int Size,2237                                   bool NoFlagsClobber) const override {2238    if (NoFlagsClobber) {2239      Inst.setOpcode(X86::LEA64r);2240      Inst.clear();2241      Inst.addOperand(MCOperand::createReg(X86::RSP));2242      Inst.addOperand(MCOperand::createReg(X86::RSP));        // BaseReg2243      Inst.addOperand(MCOperand::createImm(1));               // ScaleAmt2244      Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // IndexReg2245      Inst.addOperand(MCOperand::createImm(-Size));           // Displacement2246      Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // AddrSegmentReg2247      return;2248    }2249    Inst.setOpcode(X86::SUB64ri8);2250    Inst.clear();2251    Inst.addOperand(MCOperand::createReg(X86::RSP));2252    Inst.addOperand(MCOperand::createReg(X86::RSP));2253    Inst.addOperand(MCOperand::createImm(Size));2254  }2255 2256  void createStackPointerDecrement(MCInst &Inst, int Size,2257                                   bool NoFlagsClobber) const override {2258    if (NoFlagsClobber) {2259      Inst.setOpcode(X86::LEA64r);2260      Inst.clear();2261      Inst.addOperand(MCOperand::createReg(X86::RSP));2262      Inst.addOperand(MCOperand::createReg(X86::RSP));        // BaseReg2263      Inst.addOperand(MCOperand::createImm(1));               // ScaleAmt2264      Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // IndexReg2265      Inst.addOperand(MCOperand::createImm(Size));            // Displacement2266      Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // AddrSegmentReg2267      return;2268    }2269    Inst.setOpcode(X86::ADD64ri8);2270    Inst.clear();2271    Inst.addOperand(MCOperand::createReg(X86::RSP));2272    Inst.addOperand(MCOperand::createReg(X86::RSP));2273    Inst.addOperand(MCOperand::createImm(Size));2274  }2275 2276  void createSaveToStack(MCInst &Inst, const MCPhysReg &StackReg, int Offset,2277                         const MCPhysReg &SrcReg, int Size) const override {2278    unsigned NewOpcode;2279    switch (Size) {2280    default:2281      llvm_unreachable("Invalid operand size");2282      return;2283    case 2:      NewOpcode = X86::MOV16mr; break;2284    case 4:      NewOpcode = X86::MOV32mr; break;2285    case 8:      NewOpcode = X86::MOV64mr; break;2286    }2287    Inst.setOpcode(NewOpcode);2288    Inst.clear();2289    Inst.addOperand(MCOperand::createReg(StackReg));        // BaseReg2290    Inst.addOperand(MCOperand::createImm(1));               // ScaleAmt2291    Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // IndexReg2292    Inst.addOperand(MCOperand::createImm(Offset));          // Displacement2293    Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // AddrSegmentReg2294    Inst.addOperand(MCOperand::createReg(SrcReg));2295  }2296 2297  void createRestoreFromStack(MCInst &Inst, const MCPhysReg &StackReg,2298                              int Offset, const MCPhysReg &DstReg,2299                              int Size) const override {2300    return createLoad(Inst, StackReg, /*Scale=*/1, /*IndexReg=*/X86::NoRegister,2301                      Offset, nullptr, /*AddrSegmentReg=*/X86::NoRegister,2302                      DstReg, Size);2303  }2304 2305  void createLoad(MCInst &Inst, const MCPhysReg &BaseReg, int64_t Scale,2306                  const MCPhysReg &IndexReg, int64_t Offset,2307                  const MCExpr *OffsetExpr, const MCPhysReg &AddrSegmentReg,2308                  const MCPhysReg &DstReg, int Size) const override {2309    unsigned NewOpcode;2310    switch (Size) {2311    default:2312      llvm_unreachable("Invalid operand size");2313      return;2314    case 2:      NewOpcode = X86::MOV16rm; break;2315    case 4:      NewOpcode = X86::MOV32rm; break;2316    case 8:      NewOpcode = X86::MOV64rm; break;2317    }2318    Inst.setOpcode(NewOpcode);2319    Inst.clear();2320    Inst.addOperand(MCOperand::createReg(DstReg));2321    Inst.addOperand(MCOperand::createReg(BaseReg));2322    Inst.addOperand(MCOperand::createImm(Scale));2323    Inst.addOperand(MCOperand::createReg(IndexReg));2324    if (OffsetExpr)2325      Inst.addOperand(MCOperand::createExpr(OffsetExpr)); // Displacement2326    else2327      Inst.addOperand(MCOperand::createImm(Offset)); // Displacement2328    Inst.addOperand(MCOperand::createReg(AddrSegmentReg)); // AddrSegmentReg2329  }2330 2331  InstructionListType createLoadImmediate(const MCPhysReg Dest,2332                                          uint64_t Imm) const override {2333    InstructionListType Insts;2334    Insts.emplace_back();2335    Insts.back().setOpcode(X86::MOV64ri32);2336    Insts.back().clear();2337    Insts.back().addOperand(MCOperand::createReg(Dest));2338    Insts.back().addOperand(MCOperand::createImm(Imm));2339    return Insts;2340  }2341 2342  void createIJmp32Frag(SmallVectorImpl<MCInst> &Insts,2343                        const MCOperand &BaseReg, const MCOperand &Scale,2344                        const MCOperand &IndexReg, const MCOperand &Offset,2345                        const MCOperand &TmpReg) const override {2346    // The code fragment we emit here is:2347    //2348    //  mov32 (%base, %index, scale), %tmpreg2349    //  ijmp *(%tmpreg)2350    //2351    MCInst IJmp;2352    IJmp.setOpcode(X86::JMP64r);2353    IJmp.addOperand(TmpReg);2354 2355    MCInst Load;2356    Load.setOpcode(X86::MOV32rm);2357    Load.addOperand(TmpReg);2358    Load.addOperand(BaseReg);2359    Load.addOperand(Scale);2360    Load.addOperand(IndexReg);2361    Load.addOperand(Offset);2362    Load.addOperand(MCOperand::createReg(X86::NoRegister));2363 2364    Insts.push_back(Load);2365    Insts.push_back(IJmp);2366  }2367 2368  void createNoop(MCInst &Inst) const override {2369    Inst.setOpcode(X86::NOOP);2370    Inst.clear();2371  }2372 2373  void createReturn(MCInst &Inst) const override {2374    Inst.setOpcode(X86::RET64);2375    Inst.clear();2376  }2377 2378  InstructionListType createInlineMemcpy(bool ReturnEnd) const override {2379    InstructionListType Code;2380    if (ReturnEnd)2381      Code.emplace_back(MCInstBuilder(X86::LEA64r)2382                            .addReg(X86::RAX)2383                            .addReg(X86::RDI)2384                            .addImm(1)2385                            .addReg(X86::RDX)2386                            .addImm(0)2387                            .addReg(X86::NoRegister));2388    else2389      Code.emplace_back(MCInstBuilder(X86::MOV64rr)2390                            .addReg(X86::RAX)2391                            .addReg(X86::RDI));2392 2393    Code.emplace_back(MCInstBuilder(X86::MOV32rr)2394                          .addReg(X86::ECX)2395                          .addReg(X86::EDX));2396    Code.emplace_back(MCInstBuilder(X86::REP_MOVSB_64));2397 2398    return Code;2399  }2400 2401  InstructionListType createOneByteMemcpy() const override {2402    InstructionListType Code;2403    Code.emplace_back(MCInstBuilder(X86::MOV8rm)2404                          .addReg(X86::CL)2405                          .addReg(X86::RSI)2406                          .addImm(0)2407                          .addReg(X86::NoRegister)2408                          .addImm(0)2409                          .addReg(X86::NoRegister));2410    Code.emplace_back(MCInstBuilder(X86::MOV8mr)2411                          .addReg(X86::RDI)2412                          .addImm(0)2413                          .addReg(X86::NoRegister)2414                          .addImm(0)2415                          .addReg(X86::NoRegister)2416                          .addReg(X86::CL));2417    Code.emplace_back(MCInstBuilder(X86::MOV64rr)2418                          .addReg(X86::RAX)2419                          .addReg(X86::RDI));2420    return Code;2421  }2422 2423  InstructionListType createCmpJE(MCPhysReg RegNo, int64_t Imm,2424                                  const MCSymbol *Target,2425                                  MCContext *Ctx) const override {2426    InstructionListType Code;2427    Code.emplace_back(MCInstBuilder(X86::CMP64ri8)2428                          .addReg(RegNo)2429                          .addImm(Imm));2430    Code.emplace_back(MCInstBuilder(X86::JCC_1)2431                          .addExpr(MCSymbolRefExpr::create(Target, *Ctx))2432                          .addImm(X86::COND_E));2433    return Code;2434  }2435 2436  InstructionListType createCmpJNE(MCPhysReg RegNo, int64_t Imm,2437                                   const MCSymbol *Target,2438                                   MCContext *Ctx) const override {2439    InstructionListType Code;2440    Code.emplace_back(MCInstBuilder(X86::CMP64ri8).addReg(RegNo).addImm(Imm));2441    Code.emplace_back(MCInstBuilder(X86::JCC_1)2442                          .addExpr(MCSymbolRefExpr::create(Target, *Ctx))2443                          .addImm(X86::COND_NE));2444    return Code;2445  }2446 2447  std::optional<Relocation>2448  createRelocation(const MCFixup &Fixup,2449                   const MCAsmBackend &MAB) const override {2450    MCFixupKindInfo FKI = MAB.getFixupKindInfo(Fixup.getKind());2451 2452    assert(FKI.TargetOffset == 0 && "0-bit relocation offset expected");2453    const uint64_t RelOffset = Fixup.getOffset();2454    auto [RelSymbol, RelAddend] = extractFixupExpr(Fixup);2455 2456    uint32_t RelType;2457    if (Fixup.isPCRel()) {2458      switch (FKI.TargetSize) {2459      default:2460        return std::nullopt;2461      case  8: RelType = ELF::R_X86_64_PC8; break;2462      case 16: RelType = ELF::R_X86_64_PC16; break;2463      case 32: RelType = ELF::R_X86_64_PC32; break;2464      case 64: RelType = ELF::R_X86_64_PC64; break;2465      }2466      // Adjust PC-relative fixup offsets, which are calculated from the start2467      // of the next instruction.2468      RelAddend -= FKI.TargetSize / 8;2469    } else {2470      switch (FKI.TargetSize) {2471      default:2472        return std::nullopt;2473      case  8: RelType = ELF::R_X86_64_8; break;2474      case 16: RelType = ELF::R_X86_64_16; break;2475      case 32: RelType = ELF::R_X86_64_32; break;2476      case 64: RelType = ELF::R_X86_64_64; break;2477      }2478    }2479 2480    return Relocation({RelOffset, RelSymbol, RelType, RelAddend, 0});2481  }2482 2483  bool replaceImmWithSymbolRef(MCInst &Inst, const MCSymbol *Symbol,2484                               int64_t Addend, MCContext *Ctx, int64_t &Value,2485                               uint32_t RelType) const override {2486    unsigned ImmOpNo = -1U;2487 2488    for (unsigned Index = 0; Index < MCPlus::getNumPrimeOperands(Inst);2489         ++Index) {2490      if (Inst.getOperand(Index).isImm()) {2491        ImmOpNo = Index;2492        // TODO: this is a bit hacky.  It finds the correct operand by2493        // searching for a specific immediate value.  If no value is2494        // provided it defaults to the last immediate operand found.2495        // This could lead to unexpected results if the instruction2496        // has more than one immediate with the same value.2497        if (Inst.getOperand(ImmOpNo).getImm() == Value)2498          break;2499      }2500    }2501 2502    if (ImmOpNo == -1U)2503      return false;2504 2505    Value = Inst.getOperand(ImmOpNo).getImm();2506 2507    setOperandToSymbolRef(Inst, ImmOpNo, Symbol, Addend, Ctx, RelType);2508 2509    return true;2510  }2511 2512  bool replaceRegWithImm(MCInst &Inst, unsigned Register,2513                         int64_t Imm) const override {2514 2515    enum CheckSignExt : uint8_t {2516      NOCHECK = 0,2517      CHECK8,2518      CHECK32,2519    };2520 2521    using CheckList = std::vector<std::pair<CheckSignExt, unsigned>>;2522    struct InstInfo {2523      // Size in bytes that Inst loads from memory.2524      uint8_t DataSize;2525 2526      // True when the target operand has to be duplicated because the opcode2527      // expects a LHS operand.2528      bool HasLHS;2529 2530      // List of checks and corresponding opcodes to be used. We try to use the2531      // smallest possible immediate value when various sizes are available,2532      // hence we may need to check whether a larger constant fits in a smaller2533      // immediate.2534      CheckList Checks;2535    };2536 2537    InstInfo I;2538 2539    switch (Inst.getOpcode()) {2540    default: {2541      switch (getPushSize(Inst)) {2542 2543      case 2: I = {2, false, {{CHECK8, X86::PUSH16i8}, {NOCHECK, X86::PUSH16i}}}; break;2544      case 4: I = {4, false, {{CHECK8, X86::PUSH32i8}, {NOCHECK, X86::PUSH32i}}}; break;2545      case 8: I = {8, false, {{CHECK8, X86::PUSH64i8},2546                              {CHECK32, X86::PUSH64i32},2547                              {NOCHECK, Inst.getOpcode()}}}; break;2548      default: return false;2549      }2550      break;2551    }2552 2553    // MOV2554    case X86::MOV8rr:       I = {1, false, {{NOCHECK, X86::MOV8ri}}}; break;2555    case X86::MOV16rr:      I = {2, false, {{NOCHECK, X86::MOV16ri}}}; break;2556    case X86::MOV32rr:      I = {4, false, {{NOCHECK, X86::MOV32ri}}}; break;2557    case X86::MOV64rr:      I = {8, false, {{CHECK32, X86::MOV64ri32},2558                                            {NOCHECK, X86::MOV64ri}}}; break;2559 2560    case X86::MOV8mr:       I = {1, false, {{NOCHECK, X86::MOV8mi}}}; break;2561    case X86::MOV16mr:      I = {2, false, {{NOCHECK, X86::MOV16mi}}}; break;2562    case X86::MOV32mr:      I = {4, false, {{NOCHECK, X86::MOV32mi}}}; break;2563    case X86::MOV64mr:      I = {8, false, {{CHECK32, X86::MOV64mi32},2564                                            {NOCHECK, X86::MOV64mr}}}; break;2565 2566    // MOVZX2567    case X86::MOVZX16rr8:   I = {1, false, {{NOCHECK, X86::MOV16ri}}}; break;2568    case X86::MOVZX32rr8:   I = {1, false, {{NOCHECK, X86::MOV32ri}}}; break;2569    case X86::MOVZX32rr16:  I = {2, false, {{NOCHECK, X86::MOV32ri}}}; break;2570 2571    // CMP2572    case X86::CMP8rr:       I = {1, false, {{NOCHECK, X86::CMP8ri}}}; break;2573    case X86::CMP16rr:      I = {2, false, {{CHECK8, X86::CMP16ri8},2574                                            {NOCHECK, X86::CMP16ri}}}; break;2575    case X86::CMP32rr:      I = {4, false, {{CHECK8, X86::CMP32ri8},2576                                            {NOCHECK, X86::CMP32ri}}}; break;2577    case X86::CMP64rr:      I = {8, false, {{CHECK8, X86::CMP64ri8},2578                                            {CHECK32, X86::CMP64ri32},2579                                            {NOCHECK, X86::CMP64rr}}}; break;2580 2581    // TEST2582    case X86::TEST8rr:      I = {1, false, {{NOCHECK, X86::TEST8ri}}}; break;2583    case X86::TEST16rr:     I = {2, false, {{NOCHECK, X86::TEST16ri}}}; break;2584    case X86::TEST32rr:     I = {4, false, {{NOCHECK, X86::TEST32ri}}}; break;2585    case X86::TEST64rr:     I = {8, false, {{CHECK32, X86::TEST64ri32},2586                                            {NOCHECK, X86::TEST64rr}}}; break;2587 2588    // ADD2589    case X86::ADD8rr:       I = {1, true, {{NOCHECK, X86::ADD8ri}}}; break;2590    case X86::ADD16rr:      I = {2, true, {{CHECK8, X86::ADD16ri8},2591                                           {NOCHECK, X86::ADD16ri}}}; break;2592    case X86::ADD32rr:      I = {4, true, {{CHECK8, X86::ADD32ri8},2593                                           {NOCHECK, X86::ADD32ri}}}; break;2594    case X86::ADD64rr:      I = {8, true, {{CHECK8, X86::ADD64ri8},2595                                           {CHECK32, X86::ADD64ri32},2596                                           {NOCHECK, X86::ADD64rr}}}; break;2597 2598    // SUB2599    case X86::SUB8rr:       I = {1, true, {{NOCHECK, X86::SUB8ri}}}; break;2600    case X86::SUB16rr:      I = {2, true, {{CHECK8, X86::SUB16ri8},2601                                           {NOCHECK, X86::SUB16ri}}}; break;2602    case X86::SUB32rr:      I = {4, true, {{CHECK8, X86::SUB32ri8},2603                                           {NOCHECK, X86::SUB32ri}}}; break;2604    case X86::SUB64rr:      I = {8, true, {{CHECK8, X86::SUB64ri8},2605                                           {CHECK32, X86::SUB64ri32},2606                                           {NOCHECK, X86::SUB64rr}}}; break;2607 2608    // AND2609    case X86::AND8rr:       I = {1, true, {{NOCHECK, X86::AND8ri}}}; break;2610    case X86::AND16rr:      I = {2, true, {{CHECK8, X86::AND16ri8},2611                                           {NOCHECK, X86::AND16ri}}}; break;2612    case X86::AND32rr:      I = {4, true, {{CHECK8, X86::AND32ri8},2613                                           {NOCHECK, X86::AND32ri}}}; break;2614    case X86::AND64rr:      I = {8, true, {{CHECK8, X86::AND64ri8},2615                                           {CHECK32, X86::AND64ri32},2616                                           {NOCHECK, X86::AND64rr}}}; break;2617 2618    // OR2619    case X86::OR8rr:        I = {1, true, {{NOCHECK, X86::OR8ri}}}; break;2620    case X86::OR16rr:       I = {2, true, {{CHECK8, X86::OR16ri8},2621                                           {NOCHECK, X86::OR16ri}}}; break;2622    case X86::OR32rr:       I = {4, true, {{CHECK8, X86::OR32ri8},2623                                           {NOCHECK, X86::OR32ri}}}; break;2624    case X86::OR64rr:       I = {8, true, {{CHECK8, X86::OR64ri8},2625                                           {CHECK32, X86::OR64ri32},2626                                           {NOCHECK, X86::OR64rr}}}; break;2627 2628    // XOR2629    case X86::XOR8rr:       I = {1, true, {{NOCHECK, X86::XOR8ri}}}; break;2630    case X86::XOR16rr:      I = {2, true, {{CHECK8, X86::XOR16ri8},2631                                           {NOCHECK, X86::XOR16ri}}}; break;2632    case X86::XOR32rr:      I = {4, true, {{CHECK8, X86::XOR32ri8},2633                                           {NOCHECK, X86::XOR32ri}}}; break;2634    case X86::XOR64rr:      I = {8, true, {{CHECK8, X86::XOR64ri8},2635                                           {CHECK32, X86::XOR64ri32},2636                                           {NOCHECK, X86::XOR64rr}}}; break;2637    }2638 2639    // Compute the new opcode.2640    unsigned NewOpcode = 0;2641    for (const std::pair<CheckSignExt, unsigned> &Check : I.Checks) {2642      NewOpcode = Check.second;2643      if (Check.first == NOCHECK)2644        break;2645      if (Check.first == CHECK8 && isInt<8>(Imm))2646        break;2647      if (Check.first == CHECK32 && isInt<32>(Imm))2648        break;2649    }2650    if (NewOpcode == Inst.getOpcode())2651      return false;2652 2653    const MCInstrDesc &InstDesc = Info->get(Inst.getOpcode());2654 2655    unsigned NumFound = 0;2656    for (unsigned Index = InstDesc.getNumDefs() + (I.HasLHS ? 1 : 0),2657                  E = InstDesc.getNumOperands();2658         Index != E; ++Index)2659      if (Inst.getOperand(Index).isReg() &&2660          Inst.getOperand(Index).getReg() == Register)2661        NumFound++;2662 2663    if (NumFound != 1)2664      return false;2665 2666    MCOperand TargetOp = Inst.getOperand(0);2667    Inst.clear();2668    Inst.setOpcode(NewOpcode);2669    Inst.addOperand(TargetOp);2670    if (I.HasLHS)2671      Inst.addOperand(TargetOp);2672    Inst.addOperand(MCOperand::createImm(Imm));2673 2674    return true;2675  }2676 2677  bool replaceRegWithReg(MCInst &Inst, unsigned ToReplace,2678                         unsigned ReplaceWith) const override {2679 2680    // Get the HasLHS value so that iteration can be done2681    bool HasLHS;2682    if (X86::isAND(Inst.getOpcode()) || X86::isADD(Inst.getOpcode()) ||2683        X86::isSUB(Inst.getOpcode())) {2684      HasLHS = true;2685    } else if (isPop(Inst) || isPush(Inst) || X86::isCMP(Inst.getOpcode()) ||2686               X86::isTEST(Inst.getOpcode())) {2687      HasLHS = false;2688    } else {2689      switch (Inst.getOpcode()) {2690      case X86::MOV8rr:2691      case X86::MOV8rm:2692      case X86::MOV8mr:2693      case X86::MOV8ri:2694      case X86::MOV16rr:2695      case X86::MOV16rm:2696      case X86::MOV16mr:2697      case X86::MOV16ri:2698      case X86::MOV32rr:2699      case X86::MOV32rm:2700      case X86::MOV32mr:2701      case X86::MOV32ri:2702      case X86::MOV64rr:2703      case X86::MOV64rm:2704      case X86::MOV64mr:2705      case X86::MOV64ri:2706      case X86::MOVZX16rr8:2707      case X86::MOVZX32rr8:2708      case X86::MOVZX32rr16:2709      case X86::MOVSX32rm8:2710      case X86::MOVSX32rr8:2711      case X86::MOVSX64rm32:2712      case X86::LEA64r:2713        HasLHS = false;2714        break;2715      default:2716        return false;2717      }2718    }2719 2720    const MCInstrDesc &InstDesc = Info->get(Inst.getOpcode());2721 2722    bool FoundOne = false;2723 2724    // Iterate only through src operands that aren't also dest operands2725    for (unsigned Index = InstDesc.getNumDefs() + (HasLHS ? 1 : 0),2726                  E = InstDesc.getNumOperands();2727         Index != E; ++Index) {2728      BitVector RegAliases = getAliases(ToReplace, true);2729      if (!Inst.getOperand(Index).isReg() ||2730          !RegAliases.test(Inst.getOperand(Index).getReg()))2731        continue;2732      // Resize register if needed2733      unsigned SizedReplaceWith = getAliasSized(2734          ReplaceWith, getRegSize(Inst.getOperand(Index).getReg()));2735      MCOperand NewOperand = MCOperand::createReg(SizedReplaceWith);2736      Inst.getOperand(Index) = NewOperand;2737      FoundOne = true;2738    }2739 2740    // Return true if at least one operand was replaced2741    return FoundOne;2742  }2743 2744  void createUncondBranch(MCInst &Inst, const MCSymbol *TBB,2745                          MCContext *Ctx) const override {2746    Inst.clear();2747    Inst.setOpcode(X86::JMP_1);2748    Inst.clear();2749    Inst.addOperand(MCOperand::createExpr(MCSymbolRefExpr::create(TBB, *Ctx)));2750  }2751 2752  void createLongUncondBranch(MCInst &Inst, const MCSymbol *Target,2753                              MCContext *Ctx) const override {2754    Inst.setOpcode(X86::JMP_4);2755    Inst.clear();2756    Inst.addOperand(2757        MCOperand::createExpr(MCSymbolRefExpr::create(Target, *Ctx)));2758  }2759 2760  void createCall(MCInst &Inst, const MCSymbol *Target,2761                  MCContext *Ctx) override {2762    Inst.setOpcode(X86::CALL64pcrel32);2763    Inst.clear();2764    Inst.addOperand(2765        MCOperand::createExpr(MCSymbolRefExpr::create(Target, *Ctx)));2766  }2767 2768  void createTailCall(MCInst &Inst, const MCSymbol *Target,2769                      MCContext *Ctx) override {2770    return createDirectCall(Inst, Target, Ctx, /*IsTailCall*/ true);2771  }2772 2773  void createLongTailCall(InstructionListType &Seq, const MCSymbol *Target,2774                          MCContext *Ctx) override {2775    Seq.clear();2776    Seq.emplace_back();2777    createDirectCall(Seq.back(), Target, Ctx, /*IsTailCall*/ true);2778  }2779 2780  void createTrap(MCInst &Inst) const override {2781    Inst.clear();2782    Inst.setOpcode(X86::TRAP);2783  }2784 2785  void createCondBranch(MCInst &Inst, const MCSymbol *Target, unsigned CC,2786                        MCContext *Ctx) const override {2787    Inst.setOpcode(X86::JCC_1);2788    Inst.clear();2789    Inst.addOperand(2790        MCOperand::createExpr(MCSymbolRefExpr::create(Target, *Ctx)));2791    Inst.addOperand(MCOperand::createImm(CC));2792  }2793 2794  void createLongCondBranch(MCInst &Inst, const MCSymbol *Target, unsigned CC,2795                            MCContext *Ctx) const override {2796    Inst.setOpcode(X86::JCC_4);2797    Inst.clear();2798    Inst.addOperand(2799        MCOperand::createExpr(MCSymbolRefExpr::create(Target, *Ctx)));2800    Inst.addOperand(MCOperand::createImm(CC));2801  }2802 2803  void reverseBranchCondition(MCInst &Inst, const MCSymbol *TBB,2804                              MCContext *Ctx) const override {2805    unsigned InvCC = getInvertedCondCode(getCondCode(Inst));2806    assert(InvCC != X86::COND_INVALID && "invalid branch instruction");2807    Inst.getOperand(Info->get(Inst.getOpcode()).NumOperands - 1).setImm(InvCC);2808    Inst.getOperand(0) =2809        MCOperand::createExpr(MCSymbolRefExpr::create(TBB, *Ctx));2810  }2811 2812  bool replaceBranchCondition(MCInst &Inst, const MCSymbol *TBB, MCContext *Ctx,2813                              unsigned CC) const override {2814    if (CC == X86::COND_INVALID)2815      return false;2816    Inst.getOperand(Info->get(Inst.getOpcode()).NumOperands - 1).setImm(CC);2817    Inst.getOperand(0) =2818        MCOperand::createExpr(MCSymbolRefExpr::create(TBB, *Ctx));2819    return true;2820  }2821 2822  unsigned getCanonicalBranchCondCode(unsigned CC) const override {2823    switch (CC) {2824    default:           return X86::COND_INVALID;2825 2826    case X86::COND_E:  return X86::COND_E;2827    case X86::COND_NE: return X86::COND_E;2828 2829    case X86::COND_L:  return X86::COND_L;2830    case X86::COND_GE: return X86::COND_L;2831 2832    case X86::COND_LE: return X86::COND_G;2833    case X86::COND_G:  return X86::COND_G;2834 2835    case X86::COND_B:  return X86::COND_B;2836    case X86::COND_AE: return X86::COND_B;2837 2838    case X86::COND_BE: return X86::COND_A;2839    case X86::COND_A:  return X86::COND_A;2840 2841    case X86::COND_S:  return X86::COND_S;2842    case X86::COND_NS: return X86::COND_S;2843 2844    case X86::COND_P:  return X86::COND_P;2845    case X86::COND_NP: return X86::COND_P;2846 2847    case X86::COND_O:  return X86::COND_O;2848    case X86::COND_NO: return X86::COND_O;2849    }2850  }2851 2852  void replaceBranchTarget(MCInst &Inst, const MCSymbol *TBB,2853                           MCContext *Ctx) const override {2854    assert((isCall(Inst) || isBranch(Inst)) && !isIndirectBranch(Inst) &&2855           "Invalid instruction");2856    Inst.getOperand(0) =2857        MCOperand::createExpr(MCSymbolRefExpr::create(TBB, *Ctx));2858  }2859 2860  MCPhysReg getX86R11() const override { return X86::R11; }2861 2862  unsigned getShortBranchOpcode(unsigned Opcode) const override {2863    switch (Opcode) {2864    default:2865      return Opcode;2866    case X86::JMP_2:2867      return X86::JMP_1;2868    case X86::JMP_4:2869      return X86::JMP_1;2870    case X86::JCC_2:2871      return X86::JCC_1;2872    case X86::JCC_4:2873      return X86::JCC_1;2874    }2875  }2876 2877  MCPhysReg getIntArgRegister(unsigned ArgNo) const override {2878    // FIXME: this should depend on the calling convention.2879    switch (ArgNo) {2880    case 0:   return X86::RDI;2881    case 1:   return X86::RSI;2882    case 2:   return X86::RDX;2883    case 3:   return X86::RCX;2884    case 4:   return X86::R8;2885    case 5:   return X86::R9;2886    default:  return getNoRegister();2887    }2888  }2889 2890  void createPause(MCInst &Inst) const override {2891    Inst.clear();2892    Inst.setOpcode(X86::PAUSE);2893  }2894 2895  void createLfence(MCInst &Inst) const override {2896    Inst.clear();2897    Inst.setOpcode(X86::LFENCE);2898  }2899 2900  void createDirectCall(MCInst &Inst, const MCSymbol *Target, MCContext *Ctx,2901                        bool IsTailCall) override {2902    Inst.clear();2903    Inst.setOpcode(IsTailCall ? X86::JMP_4 : X86::CALL64pcrel32);2904    Inst.addOperand(2905        MCOperand::createExpr(MCSymbolRefExpr::create(Target, *Ctx)));2906    if (IsTailCall)2907      setTailCall(Inst);2908  }2909 2910  void createShortJmp(InstructionListType &Seq, const MCSymbol *Target,2911                      MCContext *Ctx, bool IsTailCall) override {2912    Seq.clear();2913    MCInst Inst;2914    Inst.setOpcode(X86::JMP_1);2915    Inst.addOperand(2916        MCOperand::createExpr(MCSymbolRefExpr::create(Target, *Ctx)));2917    if (IsTailCall)2918      setTailCall(Inst);2919    Seq.emplace_back(Inst);2920  }2921 2922  bool isConditionalMove(const MCInst &Inst) const override {2923    unsigned OpCode = Inst.getOpcode();2924    return (OpCode == X86::CMOV16rr || OpCode == X86::CMOV32rr ||2925            OpCode == X86::CMOV64rr);2926  }2927 2928  bool isBranchOnMem(const MCInst &Inst) const override {2929    unsigned OpCode = Inst.getOpcode();2930    if (OpCode == X86::CALL64m || (OpCode == X86::JMP32m && isTailCall(Inst)) ||2931        OpCode == X86::JMP64m)2932      return true;2933 2934    return false;2935  }2936 2937  bool isBranchOnReg(const MCInst &Inst) const override {2938    unsigned OpCode = Inst.getOpcode();2939    if (OpCode == X86::CALL64r || (OpCode == X86::JMP32r && isTailCall(Inst)) ||2940        OpCode == X86::JMP64r)2941      return true;2942 2943    return false;2944  }2945 2946  void createPushRegister(MCInst &Inst, MCPhysReg Reg,2947                          unsigned Size) const override {2948    Inst.clear();2949    unsigned NewOpcode = 0;2950    if (Reg == X86::EFLAGS) {2951      switch (Size) {2952      case 2: NewOpcode = X86::PUSHF16;  break;2953      case 4: NewOpcode = X86::PUSHF32;  break;2954      case 8: NewOpcode = X86::PUSHF64;  break;2955      default:2956        llvm_unreachable("Unexpected size");2957      }2958      Inst.setOpcode(NewOpcode);2959      return;2960    }2961    switch (Size) {2962    case 2: NewOpcode = X86::PUSH16r;  break;2963    case 4: NewOpcode = X86::PUSH32r;  break;2964    case 8: NewOpcode = X86::PUSH64r;  break;2965    default:2966      llvm_unreachable("Unexpected size");2967    }2968    Inst.setOpcode(NewOpcode);2969    Inst.addOperand(MCOperand::createReg(Reg));2970  }2971 2972  void createPopRegister(MCInst &Inst, MCPhysReg Reg,2973                         unsigned Size) const override {2974    Inst.clear();2975    unsigned NewOpcode = 0;2976    if (Reg == X86::EFLAGS) {2977      switch (Size) {2978      case 2: NewOpcode = X86::POPF16;  break;2979      case 4: NewOpcode = X86::POPF32;  break;2980      case 8: NewOpcode = X86::POPF64;  break;2981      default:2982        llvm_unreachable("Unexpected size");2983      }2984      Inst.setOpcode(NewOpcode);2985      return;2986    }2987    switch (Size) {2988    case 2: NewOpcode = X86::POP16r;  break;2989    case 4: NewOpcode = X86::POP32r;  break;2990    case 8: NewOpcode = X86::POP64r;  break;2991    default:2992      llvm_unreachable("Unexpected size");2993    }2994    Inst.setOpcode(NewOpcode);2995    Inst.addOperand(MCOperand::createReg(Reg));2996  }2997 2998  void createPushFlags(MCInst &Inst, unsigned Size) const override {2999    return createPushRegister(Inst, X86::EFLAGS, Size);3000  }3001 3002  void createPopFlags(MCInst &Inst, unsigned Size) const override {3003    return createPopRegister(Inst, X86::EFLAGS, Size);3004  }3005 3006  void createAddRegImm(MCInst &Inst, MCPhysReg Reg, int64_t Value,3007                       unsigned Size) const {3008    unsigned int Opcode;3009    switch (Size) {3010    case 1: Opcode = X86::ADD8ri; break;3011    case 2: Opcode = X86::ADD16ri; break;3012    case 4: Opcode = X86::ADD32ri; break;3013    default:3014      llvm_unreachable("Unexpected size");3015    }3016    Inst.setOpcode(Opcode);3017    Inst.clear();3018    Inst.addOperand(MCOperand::createReg(Reg));3019    Inst.addOperand(MCOperand::createReg(Reg));3020    Inst.addOperand(MCOperand::createImm(Value));3021  }3022 3023  void createClearRegWithNoEFlagsUpdate(MCInst &Inst, MCPhysReg Reg,3024                                        unsigned Size) const {3025    unsigned int Opcode;3026    switch (Size) {3027    case 1: Opcode = X86::MOV8ri; break;3028    case 2: Opcode = X86::MOV16ri; break;3029    case 4: Opcode = X86::MOV32ri; break;3030    // Writing to a 32-bit register always zeros the upper 32 bits of the3031    // full-width register3032    case 8:3033      Opcode = X86::MOV32ri;3034      Reg = getAliasSized(Reg, 4);3035      break;3036    default:3037      llvm_unreachable("Unexpected size");3038    }3039    Inst.setOpcode(Opcode);3040    Inst.clear();3041    Inst.addOperand(MCOperand::createReg(Reg));3042    Inst.addOperand(MCOperand::createImm(0));3043  }3044 3045  void createX86SaveOVFlagToRegister(MCInst &Inst, MCPhysReg Reg) const {3046    Inst.setOpcode(X86::SETCCr);3047    Inst.clear();3048    Inst.addOperand(MCOperand::createReg(Reg));3049    Inst.addOperand(MCOperand::createImm(X86::COND_O));3050  }3051 3052  void createX86Lahf(MCInst &Inst) const {3053    Inst.setOpcode(X86::LAHF);3054    Inst.clear();3055  }3056 3057  void createX86Sahf(MCInst &Inst) const {3058    Inst.setOpcode(X86::SAHF);3059    Inst.clear();3060  }3061 3062  InstructionListType createInstrIncMemory(const MCSymbol *Target,3063                                           MCContext *Ctx, bool IsLeaf,3064                                           unsigned CodePointerSize) override {3065    InstructionListType Instrs(IsLeaf ? 13 : 11);3066    unsigned int I = 0;3067 3068    // Don't clobber application red zone (ABI dependent)3069    if (IsLeaf)3070      createStackPointerIncrement(Instrs[I++], 128,3071                                  /*NoFlagsClobber=*/true);3072 3073    // Performance improvements based on the optimization discussed at3074    // https://reviews.llvm.org/D66293075    // LAHF/SAHF are used instead of PUSHF/POPF3076    // PUSHF3077    createPushRegister(Instrs[I++], X86::RAX, 8);3078    createClearRegWithNoEFlagsUpdate(Instrs[I++], X86::RAX, 8);3079    createX86Lahf(Instrs[I++]);3080    createPushRegister(Instrs[I++], X86::RAX, 8);3081    createClearRegWithNoEFlagsUpdate(Instrs[I++], X86::RAX, 8);3082    createX86SaveOVFlagToRegister(Instrs[I++], X86::AL);3083    // LOCK INC3084    InstructionListType IncMem = createIncMemory(Target, Ctx);3085    assert(IncMem.size() == 1 && "Invalid IncMem size");3086    std::copy(IncMem.begin(), IncMem.end(), Instrs.begin() + I);3087    I += IncMem.size();3088    // POPF3089    createAddRegImm(Instrs[I++], X86::AL, 127, 1);3090    createPopRegister(Instrs[I++], X86::RAX, 8);3091    createX86Sahf(Instrs[I++]);3092    createPopRegister(Instrs[I++], X86::RAX, 8);3093 3094    if (IsLeaf)3095      createStackPointerDecrement(Instrs[I], 128,3096                                  /*NoFlagsClobber=*/true);3097    return Instrs;3098  }3099 3100  void createSwap(MCInst &Inst, MCPhysReg Source, MCPhysReg MemBaseReg,3101                  int64_t Disp) const {3102    Inst.setOpcode(X86::XCHG64rm);3103    Inst.clear();3104    Inst.addOperand(MCOperand::createReg(Source));3105    Inst.addOperand(MCOperand::createReg(Source));3106    Inst.addOperand(MCOperand::createReg(MemBaseReg));      // BaseReg3107    Inst.addOperand(MCOperand::createImm(1));               // ScaleAmt3108    Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // IndexReg3109    Inst.addOperand(MCOperand::createImm(Disp));            // Displacement3110    Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // AddrSegmentReg3111  }3112 3113  void createIndirectBranch(MCInst &Inst, MCPhysReg MemBaseReg,3114                            int64_t Disp) const {3115    Inst.setOpcode(X86::JMP64m);3116    Inst.clear();3117    Inst.addOperand(MCOperand::createReg(MemBaseReg));      // BaseReg3118    Inst.addOperand(MCOperand::createImm(1));               // ScaleAmt3119    Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // IndexReg3120    Inst.addOperand(MCOperand::createImm(Disp));            // Displacement3121    Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // AddrSegmentReg3122  }3123 3124  InstructionListType createInstrumentedIndirectCall(MCInst &&CallInst,3125                                                     MCSymbol *HandlerFuncAddr,3126                                                     int CallSiteID,3127                                                     MCContext *Ctx) override {3128    // Check if the target address expression used in the original indirect call3129    // uses the stack pointer, which we are going to clobber.3130    static BitVector SPAliases(getAliases(X86::RSP));3131    bool UsesSP = any_of(useOperands(CallInst), [&](const MCOperand &Op) {3132      return Op.isReg() && SPAliases[Op.getReg()];3133    });3134 3135    InstructionListType Insts;3136    MCPhysReg TempReg = getIntArgRegister(0);3137    // Code sequence used to enter indirect call instrumentation helper:3138    //   push %rdi3139    //   add $8, %rsp       ;; $rsp may be used in target, so fix it to prev val3140    //   movq target, %rdi  ;; via convertIndirectCallTargetToLoad3141    //   sub $8, %rsp       ;; restore correct stack value3142    //   push %rdi3143    //   movq $CallSiteID, %rdi3144    //   push %rdi3145    //   callq/jmp HandlerFuncAddr3146    Insts.emplace_back();3147    createPushRegister(Insts.back(), TempReg, 8);3148    if (UsesSP) { // Only adjust SP if we really need to3149      Insts.emplace_back();3150      createStackPointerDecrement(Insts.back(), 8, /*NoFlagsClobber=*/false);3151    }3152    Insts.emplace_back(CallInst);3153    // Insts.back() and CallInst now share the same annotation instruction.3154    // Strip it from Insts.back(), only preserving tail call annotation.3155    stripAnnotations(Insts.back(), /*KeepTC=*/true);3156    convertIndirectCallToLoad(Insts.back(), TempReg);3157    if (UsesSP) {3158      Insts.emplace_back();3159      createStackPointerIncrement(Insts.back(), 8, /*NoFlagsClobber=*/false);3160    }3161    Insts.emplace_back();3162    createPushRegister(Insts.back(), TempReg, 8);3163    InstructionListType LoadImm = createLoadImmediate(TempReg, CallSiteID);3164    Insts.insert(Insts.end(), LoadImm.begin(), LoadImm.end());3165    Insts.emplace_back();3166    createPushRegister(Insts.back(), TempReg, 8);3167 3168    MCInst &NewCallInst = Insts.emplace_back();3169    createDirectCall(NewCallInst, HandlerFuncAddr, Ctx, isTailCall(CallInst));3170 3171    // Carry over metadata including tail call marker if present.3172    stripAnnotations(NewCallInst);3173    moveAnnotations(std::move(CallInst), NewCallInst);3174 3175    return Insts;3176  }3177 3178  InstructionListType createInstrumentedIndCallHandlerExitBB() const override {3179    const MCPhysReg TempReg = getIntArgRegister(0);3180    // We just need to undo the sequence created for every ind call in3181    // instrumentIndirectTarget(), which can be accomplished minimally with:3182    //   popfq3183    //   pop %rdi3184    //   add $16, %rsp3185    //   xchg (%rsp), %rdi3186    //   jmp *-8(%rsp)3187    InstructionListType Insts(5);3188    createPopFlags(Insts[0], 8);3189    createPopRegister(Insts[1], TempReg, 8);3190    createStackPointerDecrement(Insts[2], 16, /*NoFlagsClobber=*/false);3191    createSwap(Insts[3], TempReg, X86::RSP, 0);3192    createIndirectBranch(Insts[4], X86::RSP, -8);3193    return Insts;3194  }3195 3196  InstructionListType3197  createInstrumentedIndTailCallHandlerExitBB() const override {3198    const MCPhysReg TempReg = getIntArgRegister(0);3199    // Same thing as above, but for tail calls3200    //   popfq3201    //   add $16, %rsp3202    //   pop %rdi3203    //   jmp *-16(%rsp)3204    InstructionListType Insts(4);3205    createPopFlags(Insts[0], 8);3206    createStackPointerDecrement(Insts[1], 16, /*NoFlagsClobber=*/false);3207    createPopRegister(Insts[2], TempReg, 8);3208    createIndirectBranch(Insts[3], X86::RSP, -16);3209    return Insts;3210  }3211 3212  InstructionListType3213  createInstrumentedIndCallHandlerEntryBB(const MCSymbol *InstrTrampoline,3214                                          const MCSymbol *IndCallHandler,3215                                          MCContext *Ctx) override {3216    const MCPhysReg TempReg = getIntArgRegister(0);3217    // Code sequence used to check whether InstrTampoline was initialized3218    // and call it if so, returns via IndCallHandler.3219    //   pushfq3220    //   mov    InstrTrampoline,%rdi3221    //   cmp    $0x0,%rdi3222    //   je     IndCallHandler3223    //   callq  *%rdi3224    //   jmpq   IndCallHandler3225    InstructionListType Insts;3226    Insts.emplace_back();3227    createPushFlags(Insts.back(), 8);3228    Insts.emplace_back();3229    createMove(Insts.back(), InstrTrampoline, TempReg, Ctx);3230    InstructionListType cmpJmp = createCmpJE(TempReg, 0, IndCallHandler, Ctx);3231    Insts.insert(Insts.end(), cmpJmp.begin(), cmpJmp.end());3232    Insts.emplace_back();3233    Insts.back().setOpcode(X86::CALL64r);3234    Insts.back().addOperand(MCOperand::createReg(TempReg));3235    Insts.emplace_back();3236    createDirectCall(Insts.back(), IndCallHandler, Ctx, /*IsTailCall*/ true);3237    return Insts;3238  }3239 3240  InstructionListType createNumCountersGetter(MCContext *Ctx) const override {3241    InstructionListType Insts(2);3242    MCSymbol *NumLocs = Ctx->getOrCreateSymbol("__bolt_num_counters");3243    createMove(Insts[0], NumLocs, X86::EAX, Ctx);3244    createReturn(Insts[1]);3245    return Insts;3246  }3247 3248  InstructionListType3249  createInstrLocationsGetter(MCContext *Ctx) const override {3250    InstructionListType Insts(2);3251    MCSymbol *Locs = Ctx->getOrCreateSymbol("__bolt_instr_locations");3252    createLea(Insts[0], Locs, X86::EAX, Ctx);3253    createReturn(Insts[1]);3254    return Insts;3255  }3256 3257  InstructionListType createInstrTablesGetter(MCContext *Ctx) const override {3258    InstructionListType Insts(2);3259    MCSymbol *Locs = Ctx->getOrCreateSymbol("__bolt_instr_tables");3260    createLea(Insts[0], Locs, X86::EAX, Ctx);3261    createReturn(Insts[1]);3262    return Insts;3263  }3264 3265  InstructionListType createInstrNumFuncsGetter(MCContext *Ctx) const override {3266    InstructionListType Insts(2);3267    MCSymbol *NumFuncs = Ctx->getOrCreateSymbol("__bolt_instr_num_funcs");3268    createMove(Insts[0], NumFuncs, X86::EAX, Ctx);3269    createReturn(Insts[1]);3270    return Insts;3271  }3272 3273  InstructionListType createSymbolTrampoline(const MCSymbol *TgtSym,3274                                             MCContext *Ctx) override {3275    InstructionListType Insts(1);3276    createUncondBranch(Insts[0], TgtSym, Ctx);3277    return Insts;3278  }3279 3280  BlocksVectorTy indirectCallPromotion(3281      const MCInst &CallInst,3282      const std::vector<std::pair<MCSymbol *, uint64_t>> &Targets,3283      const std::vector<std::pair<MCSymbol *, uint64_t>> &VtableSyms,3284      const std::vector<MCInst *> &MethodFetchInsns,3285      const bool MinimizeCodeSize, MCContext *Ctx) override {3286    const bool IsTailCall = isTailCall(CallInst);3287    const bool IsJumpTable = getJumpTable(CallInst) != 0;3288    BlocksVectorTy Results;3289 3290    // Label for the current code block.3291    MCSymbol *NextTarget = nullptr;3292 3293    // The join block which contains all the instructions following CallInst.3294    // MergeBlock remains null if CallInst is a tail call.3295    MCSymbol *MergeBlock = nullptr;3296 3297    unsigned FuncAddrReg = X86::R10;3298 3299    const bool LoadElim = !VtableSyms.empty();3300    assert((!LoadElim || VtableSyms.size() == Targets.size()) &&3301           "There must be a vtable entry for every method "3302           "in the targets vector.");3303 3304    if (MinimizeCodeSize && !LoadElim) {3305      std::set<unsigned> UsedRegs;3306 3307      for (unsigned int I = 0; I < MCPlus::getNumPrimeOperands(CallInst); ++I) {3308        const MCOperand &Op = CallInst.getOperand(I);3309        if (Op.isReg())3310          UsedRegs.insert(Op.getReg());3311      }3312 3313      if (UsedRegs.count(X86::R10) == 0)3314        FuncAddrReg = X86::R10;3315      else if (UsedRegs.count(X86::R11) == 0)3316        FuncAddrReg = X86::R11;3317      else3318        return Results;3319    }3320 3321    const auto jumpToMergeBlock = [&](InstructionListType &NewCall) {3322      assert(MergeBlock);3323      NewCall.push_back(CallInst);3324      MCInst &Merge = NewCall.back();3325      Merge.clear();3326      createUncondBranch(Merge, MergeBlock, Ctx);3327    };3328 3329    for (unsigned int i = 0; i < Targets.size(); ++i) {3330      Results.emplace_back(NextTarget, InstructionListType());3331      InstructionListType *NewCall = &Results.back().second;3332 3333      if (MinimizeCodeSize && !LoadElim) {3334        // Load the call target into FuncAddrReg.3335        NewCall->push_back(CallInst); // Copy CallInst in order to get SMLoc3336        MCInst &Target = NewCall->back();3337        Target.clear();3338        Target.setOpcode(X86::MOV64ri32);3339        Target.addOperand(MCOperand::createReg(FuncAddrReg));3340        if (Targets[i].first) {3341          // Is this OK?3342          Target.addOperand(MCOperand::createExpr(3343              MCSymbolRefExpr::create(Targets[i].first, *Ctx)));3344        } else {3345          const uint64_t Addr = Targets[i].second;3346          // Immediate address is out of sign extended 32 bit range.3347          if (int64_t(Addr) != int64_t(int32_t(Addr)))3348            return BlocksVectorTy();3349 3350          Target.addOperand(MCOperand::createImm(Addr));3351        }3352 3353        // Compare current call target to a specific address.3354        NewCall->push_back(CallInst);3355        MCInst &Compare = NewCall->back();3356        Compare.clear();3357        if (isBranchOnReg(CallInst))3358          Compare.setOpcode(X86::CMP64rr);3359        else if (CallInst.getOpcode() == X86::CALL64pcrel32)3360          Compare.setOpcode(X86::CMP64ri32);3361        else3362          Compare.setOpcode(X86::CMP64rm);3363 3364        Compare.addOperand(MCOperand::createReg(FuncAddrReg));3365 3366        // TODO: Would be preferable to only load this value once.3367        for (unsigned i = 0;3368             i < Info->get(CallInst.getOpcode()).getNumOperands(); ++i)3369          if (!CallInst.getOperand(i).isInst())3370            Compare.addOperand(CallInst.getOperand(i));3371      } else {3372        // Compare current call target to a specific address.3373        NewCall->push_back(CallInst);3374        MCInst &Compare = NewCall->back();3375        Compare.clear();3376        if (isBranchOnReg(CallInst))3377          Compare.setOpcode(X86::CMP64ri32);3378        else3379          Compare.setOpcode(X86::CMP64mi32);3380 3381        // Original call address.3382        for (unsigned i = 0;3383             i < Info->get(CallInst.getOpcode()).getNumOperands(); ++i)3384          if (!CallInst.getOperand(i).isInst())3385            Compare.addOperand(CallInst.getOperand(i));3386 3387        // Target address.3388        if (Targets[i].first || LoadElim) {3389          const MCSymbol *Sym =3390              LoadElim ? VtableSyms[i].first : Targets[i].first;3391          const uint64_t Addend = LoadElim ? VtableSyms[i].second : 0;3392          const MCExpr *Expr = MCSymbolRefExpr::create(Sym, *Ctx);3393          if (Addend)3394            Expr = MCBinaryExpr::createAdd(3395                Expr, MCConstantExpr::create(Addend, *Ctx), *Ctx);3396          Compare.addOperand(MCOperand::createExpr(Expr));3397        } else {3398          const uint64_t Addr = Targets[i].second;3399          // Immediate address is out of sign extended 32 bit range.3400          if (int64_t(Addr) != int64_t(int32_t(Addr)))3401            return BlocksVectorTy();3402 3403          Compare.addOperand(MCOperand::createImm(Addr));3404        }3405      }3406 3407      // jump to next target compare.3408      NextTarget =3409          Ctx->createNamedTempSymbol(); // generate label for the next block3410      NewCall->push_back(CallInst);3411 3412      if (IsJumpTable) {3413        MCInst &Je = NewCall->back();3414 3415        // Jump to next compare if target addresses don't match.3416        Je.clear();3417        Je.setOpcode(X86::JCC_1);3418        if (Targets[i].first)3419          Je.addOperand(MCOperand::createExpr(3420              MCSymbolRefExpr::create(Targets[i].first, *Ctx)));3421        else3422          Je.addOperand(MCOperand::createImm(Targets[i].second));3423 3424        Je.addOperand(MCOperand::createImm(X86::COND_E));3425        assert(!isInvoke(CallInst));3426      } else {3427        MCInst &Jne = NewCall->back();3428 3429        // Jump to next compare if target addresses don't match.3430        Jne.clear();3431        Jne.setOpcode(X86::JCC_1);3432        Jne.addOperand(3433            MCOperand::createExpr(MCSymbolRefExpr::create(NextTarget, *Ctx)));3434        Jne.addOperand(MCOperand::createImm(X86::COND_NE));3435 3436        // Call specific target directly.3437        Results.emplace_back(Ctx->createNamedTempSymbol(),3438                             InstructionListType());3439        NewCall = &Results.back().second;3440        NewCall->push_back(CallInst);3441        MCInst &CallOrJmp = NewCall->back();3442 3443        CallOrJmp.clear();3444 3445        if (MinimizeCodeSize && !LoadElim) {3446          CallOrJmp.setOpcode(IsTailCall ? X86::JMP32r : X86::CALL64r);3447          CallOrJmp.addOperand(MCOperand::createReg(FuncAddrReg));3448        } else {3449          CallOrJmp.setOpcode(IsTailCall ? X86::JMP_4 : X86::CALL64pcrel32);3450 3451          if (Targets[i].first)3452            CallOrJmp.addOperand(MCOperand::createExpr(3453                MCSymbolRefExpr::create(Targets[i].first, *Ctx)));3454          else3455            CallOrJmp.addOperand(MCOperand::createImm(Targets[i].second));3456        }3457        if (IsTailCall)3458          setTailCall(CallOrJmp);3459 3460        if (CallOrJmp.getOpcode() == X86::CALL64r ||3461            CallOrJmp.getOpcode() == X86::CALL64pcrel32) {3462          if (std::optional<uint32_t> Offset = getOffset(CallInst))3463            // Annotated as duplicated call3464            setOffset(CallOrJmp, *Offset);3465        }3466 3467        if (isInvoke(CallInst) && !isInvoke(CallOrJmp)) {3468          // Copy over any EH or GNU args size information from the original3469          // call.3470          std::optional<MCPlus::MCLandingPad> EHInfo = getEHInfo(CallInst);3471          if (EHInfo)3472            addEHInfo(CallOrJmp, *EHInfo);3473          int64_t GnuArgsSize = getGnuArgsSize(CallInst);3474          if (GnuArgsSize >= 0)3475            addGnuArgsSize(CallOrJmp, GnuArgsSize);3476        }3477 3478        if (!IsTailCall) {3479          // The fallthrough block for the most common target should be3480          // the merge block.3481          if (i == 0) {3482            // Fallthrough to merge block.3483            MergeBlock = Ctx->createNamedTempSymbol();3484          } else {3485            // Insert jump to the merge block if we are not doing a fallthrough.3486            jumpToMergeBlock(*NewCall);3487          }3488        }3489      }3490    }3491 3492    // Cold call block.3493    Results.emplace_back(NextTarget, InstructionListType());3494    InstructionListType &NewCall = Results.back().second;3495    for (const MCInst *Inst : MethodFetchInsns)3496      if (Inst != &CallInst)3497        NewCall.push_back(*Inst);3498    NewCall.push_back(CallInst);3499 3500    // Jump to merge block from cold call block3501    if (!IsTailCall && !IsJumpTable) {3502      jumpToMergeBlock(NewCall);3503 3504      // Record merge block3505      Results.emplace_back(MergeBlock, InstructionListType());3506    }3507 3508    return Results;3509  }3510 3511  BlocksVectorTy jumpTablePromotion(3512      const MCInst &IJmpInst,3513      const std::vector<std::pair<MCSymbol *, uint64_t>> &Targets,3514      const std::vector<MCInst *> &TargetFetchInsns,3515      MCContext *Ctx) const override {3516    assert(getJumpTable(IJmpInst) != 0);3517    uint16_t IndexReg = getAnnotationAs<uint16_t>(IJmpInst, "JTIndexReg");3518    if (IndexReg == 0)3519      return BlocksVectorTy();3520 3521    BlocksVectorTy Results;3522 3523    // Label for the current code block.3524    MCSymbol *NextTarget = nullptr;3525 3526    for (unsigned int i = 0; i < Targets.size(); ++i) {3527      Results.emplace_back(NextTarget, InstructionListType());3528      InstructionListType *CurBB = &Results.back().second;3529 3530      // Compare current index to a specific index.3531      CurBB->emplace_back(MCInst());3532      MCInst &CompareInst = CurBB->back();3533      CompareInst.setLoc(IJmpInst.getLoc());3534      CompareInst.setOpcode(X86::CMP64ri32);3535      CompareInst.addOperand(MCOperand::createReg(IndexReg));3536 3537      const uint64_t CaseIdx = Targets[i].second;3538      // Immediate address is out of sign extended 32 bit range.3539      if (int64_t(CaseIdx) != int64_t(int32_t(CaseIdx)))3540        return BlocksVectorTy();3541 3542      CompareInst.addOperand(MCOperand::createImm(CaseIdx));3543      shortenInstruction(CompareInst, *Ctx->getSubtargetInfo());3544 3545      // jump to next target compare.3546      NextTarget =3547          Ctx->createNamedTempSymbol(); // generate label for the next block3548      CurBB->push_back(MCInst());3549 3550      MCInst &JEInst = CurBB->back();3551      JEInst.setLoc(IJmpInst.getLoc());3552 3553      // Jump to target if indices match3554      JEInst.setOpcode(X86::JCC_1);3555      JEInst.addOperand(MCOperand::createExpr(3556          MCSymbolRefExpr::create(Targets[i].first, *Ctx)));3557      JEInst.addOperand(MCOperand::createImm(X86::COND_E));3558    }3559 3560    // Cold call block.3561    Results.emplace_back(NextTarget, InstructionListType());3562    InstructionListType &CurBB = Results.back().second;3563    for (const MCInst *Inst : TargetFetchInsns)3564      if (Inst != &IJmpInst)3565        CurBB.push_back(*Inst);3566 3567    CurBB.push_back(IJmpInst);3568 3569    return Results;3570  }3571 3572private:3573  void createMove(MCInst &Inst, const MCSymbol *Src, unsigned Reg,3574                  MCContext *Ctx) const {3575    Inst.setOpcode(X86::MOV64rm);3576    Inst.clear();3577    Inst.addOperand(MCOperand::createReg(Reg));3578    Inst.addOperand(MCOperand::createReg(X86::RIP));        // BaseReg3579    Inst.addOperand(MCOperand::createImm(1));               // ScaleAmt3580    Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // IndexReg3581    Inst.addOperand(3582        MCOperand::createExpr(MCSymbolRefExpr::create(Src,3583                                                      *Ctx))); // Displacement3584    Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // AddrSegmentReg3585  }3586 3587  void createLea(MCInst &Inst, const MCSymbol *Src, unsigned Reg,3588                 MCContext *Ctx) const {3589    Inst.setOpcode(X86::LEA64r);3590    Inst.clear();3591    Inst.addOperand(MCOperand::createReg(Reg));3592    Inst.addOperand(MCOperand::createReg(X86::RIP));        // BaseReg3593    Inst.addOperand(MCOperand::createImm(1));               // ScaleAmt3594    Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // IndexReg3595    Inst.addOperand(3596        MCOperand::createExpr(MCSymbolRefExpr::create(Src,3597                                                      *Ctx))); // Displacement3598    Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // AddrSegmentReg3599  }3600};3601 3602} // namespace3603 3604namespace llvm {3605namespace bolt {3606 3607MCPlusBuilder *createX86MCPlusBuilder(const MCInstrAnalysis *Analysis,3608                                      const MCInstrInfo *Info,3609                                      const MCRegisterInfo *RegInfo,3610                                      const MCSubtargetInfo *STI) {3611  return new X86MCPlusBuilder(Analysis, Info, RegInfo, STI);3612}3613 3614} // namespace bolt3615} // namespace llvm3616