brintos

brintos / llvm-project-archived public Read only

0
0
Text · 19.8 KiB · 0cb4ba1 Raw
629 lines · cpp
1//===- bolt/Core/MCPlusBuilder.cpp - Interface for MCPlus -----------------===//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 implements the MCPlusBuilder class.10//11//===----------------------------------------------------------------------===//12 13#include "bolt/Core/MCPlusBuilder.h"14#include "bolt/Core/MCPlus.h"15#include "bolt/Utils/CommandLineOpts.h"16#include "llvm/MC/MCContext.h"17#include "llvm/MC/MCInst.h"18#include "llvm/MC/MCInstrAnalysis.h"19#include "llvm/MC/MCInstrDesc.h"20#include "llvm/MC/MCInstrInfo.h"21#include "llvm/MC/MCRegisterInfo.h"22#include "llvm/Support/CommandLine.h"23#include "llvm/Support/Debug.h"24#include <cstdint>25 26#define DEBUG_TYPE "mcplus"27 28using namespace llvm;29using namespace bolt;30using namespace MCPlus;31 32namespace opts {33cl::opt<bool>34    TerminalHLT("terminal-x86-hlt",35                cl::desc("Assume that execution stops at x86 HLT instruction"),36                cl::init(true), cl::Hidden, cl::cat(BoltCategory));37 38cl::opt<bool>39    TerminalTrap("terminal-trap",40                 cl::desc("Assume that execution stops at trap instruction"),41                 cl::init(true), cl::Hidden, cl::cat(BoltCategory));42}43 44bool MCPlusBuilder::equals(const MCInst &A, const MCInst &B,45                           CompFuncTy Comp) const {46  if (A.getOpcode() != B.getOpcode())47    return false;48 49  unsigned NumOperands = MCPlus::getNumPrimeOperands(A);50  if (NumOperands != MCPlus::getNumPrimeOperands(B))51    return false;52 53  for (unsigned Index = 0; Index < NumOperands; ++Index)54    if (!equals(A.getOperand(Index), B.getOperand(Index), Comp))55      return false;56 57  return true;58}59 60bool MCPlusBuilder::equals(const MCOperand &A, const MCOperand &B,61                           CompFuncTy Comp) const {62  if (A.isReg()) {63    if (!B.isReg())64      return false;65    return A.getReg() == B.getReg();66  } else if (A.isImm()) {67    if (!B.isImm())68      return false;69    return A.getImm() == B.getImm();70  } else if (A.isSFPImm()) {71    if (!B.isSFPImm())72      return false;73    return A.getSFPImm() == B.getSFPImm();74  } else if (A.isDFPImm()) {75    if (!B.isDFPImm())76      return false;77    return A.getDFPImm() == B.getDFPImm();78  } else if (A.isExpr()) {79    if (!B.isExpr())80      return false;81    return equals(*A.getExpr(), *B.getExpr(), Comp);82  } else {83    llvm_unreachable("unexpected operand kind");84    return false;85  }86}87 88bool MCPlusBuilder::equals(const MCExpr &A, const MCExpr &B,89                           CompFuncTy Comp) const {90  if (A.getKind() != B.getKind())91    return false;92 93  switch (A.getKind()) {94  case MCExpr::Constant: {95    const auto &ConstA = cast<MCConstantExpr>(A);96    const auto &ConstB = cast<MCConstantExpr>(B);97    return ConstA.getValue() == ConstB.getValue();98  }99 100  case MCExpr::SymbolRef: {101    const MCSymbolRefExpr &SymbolA = cast<MCSymbolRefExpr>(A);102    const MCSymbolRefExpr &SymbolB = cast<MCSymbolRefExpr>(B);103    return SymbolA.getKind() == SymbolB.getKind() &&104           Comp(&SymbolA.getSymbol(), &SymbolB.getSymbol());105  }106 107  case MCExpr::Unary: {108    const auto &UnaryA = cast<MCUnaryExpr>(A);109    const auto &UnaryB = cast<MCUnaryExpr>(B);110    return UnaryA.getOpcode() == UnaryB.getOpcode() &&111           equals(*UnaryA.getSubExpr(), *UnaryB.getSubExpr(), Comp);112  }113 114  case MCExpr::Binary: {115    const auto &BinaryA = cast<MCBinaryExpr>(A);116    const auto &BinaryB = cast<MCBinaryExpr>(B);117    return BinaryA.getOpcode() == BinaryB.getOpcode() &&118           equals(*BinaryA.getLHS(), *BinaryB.getLHS(), Comp) &&119           equals(*BinaryA.getRHS(), *BinaryB.getRHS(), Comp);120  }121 122  case MCExpr::Specifier: {123    const auto &TargetExprA = cast<MCSpecifierExpr>(A);124    const auto &TargetExprB = cast<MCSpecifierExpr>(B);125    return equals(TargetExprA, TargetExprB, Comp);126  }127  case MCExpr::Target:128    llvm_unreachable("Not implemented");129  }130 131  llvm_unreachable("Invalid expression kind!");132}133 134bool MCPlusBuilder::equals(const MCSpecifierExpr &A, const MCSpecifierExpr &B,135                           CompFuncTy Comp) const {136  llvm_unreachable("target-specific expressions are unsupported");137}138 139bool MCPlusBuilder::isTerminator(const MCInst &Inst) const {140  if (isX86HLT(Inst))141    return opts::TerminalHLT;142 143  if (Info->get(Inst.getOpcode()).isTrap())144    return opts::TerminalTrap;145 146  return Analysis->isTerminator(Inst);147}148 149void MCPlusBuilder::setTailCall(MCInst &Inst) const {150  assert(!hasAnnotation(Inst, MCAnnotation::kTailCall));151  setAnnotationOpValue(Inst, MCAnnotation::kTailCall, true);152}153 154bool MCPlusBuilder::isTailCall(const MCInst &Inst) const {155  if (hasAnnotation(Inst, MCAnnotation::kTailCall))156    return true;157  if (getConditionalTailCall(Inst))158    return true;159  return false;160}161 162void MCPlusBuilder::setNegateRAState(MCInst &Inst) const {163  assert(!hasAnnotation(Inst, MCAnnotation::kNegateState));164  setAnnotationOpValue(Inst, MCAnnotation::kNegateState, true);165}166 167bool MCPlusBuilder::hasNegateRAState(const MCInst &Inst) const {168  return hasAnnotation(Inst, MCAnnotation::kNegateState);169}170 171void MCPlusBuilder::setRememberState(MCInst &Inst) const {172  assert(!hasAnnotation(Inst, MCAnnotation::kRememberState));173  setAnnotationOpValue(Inst, MCAnnotation::kRememberState, true);174}175 176bool MCPlusBuilder::hasRememberState(const MCInst &Inst) const {177  return hasAnnotation(Inst, MCAnnotation::kRememberState);178}179 180void MCPlusBuilder::setRestoreState(MCInst &Inst) const {181  assert(!hasAnnotation(Inst, MCAnnotation::kRestoreState));182  setAnnotationOpValue(Inst, MCAnnotation::kRestoreState, true);183}184 185bool MCPlusBuilder::hasRestoreState(const MCInst &Inst) const {186  return hasAnnotation(Inst, MCAnnotation::kRestoreState);187}188 189void MCPlusBuilder::setRAState(MCInst &Inst, bool State) const {190  assert(!hasAnnotation(Inst, MCAnnotation::kRASigned));191  assert(!hasAnnotation(Inst, MCAnnotation::kRAUnsigned));192  if (State)193    setAnnotationOpValue(Inst, MCAnnotation::kRASigned, true);194  else195    setAnnotationOpValue(Inst, MCAnnotation::kRAUnsigned, true);196}197 198std::optional<bool> MCPlusBuilder::getRAState(const MCInst &Inst) const {199  if (hasAnnotation(Inst, MCAnnotation::kRASigned))200    return true;201  if (hasAnnotation(Inst, MCAnnotation::kRAUnsigned))202    return false;203  return std::nullopt;204}205 206std::optional<MCLandingPad> MCPlusBuilder::getEHInfo(const MCInst &Inst) const {207  if (!isCall(Inst))208    return std::nullopt;209  std::optional<int64_t> LPSym =210      getAnnotationOpValue(Inst, MCAnnotation::kEHLandingPad);211  if (!LPSym)212    return std::nullopt;213  std::optional<int64_t> Action =214      getAnnotationOpValue(Inst, MCAnnotation::kEHAction);215  if (!Action)216    return std::nullopt;217 218  return std::make_pair(reinterpret_cast<const MCSymbol *>(*LPSym),219                        static_cast<uint64_t>(*Action));220}221 222void MCPlusBuilder::addEHInfo(MCInst &Inst, const MCLandingPad &LP) const {223  if (isCall(Inst)) {224    assert(!getEHInfo(Inst));225    setAnnotationOpValue(Inst, MCAnnotation::kEHLandingPad,226                         reinterpret_cast<int64_t>(LP.first));227    setAnnotationOpValue(Inst, MCAnnotation::kEHAction,228                         static_cast<int64_t>(LP.second));229  }230}231 232bool MCPlusBuilder::updateEHInfo(MCInst &Inst, const MCLandingPad &LP) const {233  if (!isInvoke(Inst))234    return false;235 236  setAnnotationOpValue(Inst, MCAnnotation::kEHLandingPad,237                       reinterpret_cast<int64_t>(LP.first));238  setAnnotationOpValue(Inst, MCAnnotation::kEHAction,239                       static_cast<int64_t>(LP.second));240  return true;241}242 243int64_t MCPlusBuilder::getGnuArgsSize(const MCInst &Inst) const {244  std::optional<int64_t> Value =245      getAnnotationOpValue(Inst, MCAnnotation::kGnuArgsSize);246  if (!Value)247    return -1LL;248  return *Value;249}250 251void MCPlusBuilder::addGnuArgsSize(MCInst &Inst, int64_t GnuArgsSize) const {252  assert(GnuArgsSize >= 0 && "cannot set GNU_args_size to negative value");253  assert(getGnuArgsSize(Inst) == -1LL && "GNU_args_size already set");254  assert(isInvoke(Inst) && "GNU_args_size can only be set for invoke");255 256  setAnnotationOpValue(Inst, MCAnnotation::kGnuArgsSize, GnuArgsSize);257}258 259uint64_t MCPlusBuilder::getJumpTable(const MCInst &Inst) const {260  std::optional<int64_t> Value =261      getAnnotationOpValue(Inst, MCAnnotation::kJumpTable);262  if (!Value)263    return 0;264  return *Value;265}266 267uint16_t MCPlusBuilder::getJumpTableIndexReg(const MCInst &Inst) const {268  return getAnnotationAs<uint16_t>(Inst, "JTIndexReg");269}270 271bool MCPlusBuilder::setJumpTable(MCInst &Inst, uint64_t Value,272                                 uint16_t IndexReg, AllocatorIdTy AllocId) {273  if (!isIndirectBranch(Inst))274    return false;275  setAnnotationOpValue(Inst, MCAnnotation::kJumpTable, Value);276  getOrCreateAnnotationAs<uint16_t>(Inst, "JTIndexReg", AllocId) = IndexReg;277  return true;278}279 280bool MCPlusBuilder::unsetJumpTable(MCInst &Inst) const {281  if (!getJumpTable(Inst))282    return false;283  removeAnnotation(Inst, MCAnnotation::kJumpTable);284  removeAnnotation(Inst, "JTIndexReg");285  return true;286}287 288std::optional<uint64_t>289MCPlusBuilder::getConditionalTailCall(const MCInst &Inst) const {290  std::optional<int64_t> Value =291      getAnnotationOpValue(Inst, MCAnnotation::kConditionalTailCall);292  if (!Value)293    return std::nullopt;294  return static_cast<uint64_t>(*Value);295}296 297bool MCPlusBuilder::setConditionalTailCall(MCInst &Inst, uint64_t Dest) const {298  if (!isConditionalBranch(Inst))299    return false;300 301  setAnnotationOpValue(Inst, MCAnnotation::kConditionalTailCall, Dest);302  return true;303}304 305bool MCPlusBuilder::unsetConditionalTailCall(MCInst &Inst) const {306  if (!getConditionalTailCall(Inst))307    return false;308  removeAnnotation(Inst, MCAnnotation::kConditionalTailCall);309  return true;310}311 312std::optional<uint32_t> MCPlusBuilder::getOffset(const MCInst &Inst) const {313  std::optional<int64_t> Value =314      getAnnotationOpValue(Inst, MCAnnotation::kOffset);315  if (!Value)316    return std::nullopt;317  return static_cast<uint32_t>(*Value);318}319 320uint32_t MCPlusBuilder::getOffsetWithDefault(const MCInst &Inst,321                                             uint32_t Default) const {322  if (std::optional<uint32_t> Offset = getOffset(Inst))323    return *Offset;324  return Default;325}326 327bool MCPlusBuilder::setOffset(MCInst &Inst, uint32_t Offset) const {328  setAnnotationOpValue(Inst, MCAnnotation::kOffset, Offset);329  return true;330}331 332bool MCPlusBuilder::clearOffset(MCInst &Inst) const {333  if (!hasAnnotation(Inst, MCAnnotation::kOffset))334    return false;335  removeAnnotation(Inst, MCAnnotation::kOffset);336  return true;337}338 339MCSymbol *MCPlusBuilder::getInstLabel(const MCInst &Inst) const {340  if (std::optional<int64_t> Label =341          getAnnotationOpValue(Inst, MCAnnotation::kLabel))342    return reinterpret_cast<MCSymbol *>(*Label);343  return nullptr;344}345 346MCSymbol *MCPlusBuilder::getOrCreateInstLabel(MCInst &Inst, const Twine &Name,347                                              MCContext *Ctx) const {348  MCSymbol *Label = getInstLabel(Inst);349  if (Label)350    return Label;351 352  Label = Ctx->createNamedTempSymbol(Name);353  setAnnotationOpValue(Inst, MCAnnotation::kLabel,354                       reinterpret_cast<int64_t>(Label));355  return Label;356}357 358void MCPlusBuilder::setInstLabel(MCInst &Inst, MCSymbol *Label) const {359  assert(!getInstLabel(Inst) && "Instruction already has assigned label.");360  setAnnotationOpValue(Inst, MCAnnotation::kLabel,361                       reinterpret_cast<int64_t>(Label));362}363 364std::optional<uint32_t> MCPlusBuilder::getSize(const MCInst &Inst) const {365  if (std::optional<int64_t> Value =366          getAnnotationOpValue(Inst, MCAnnotation::kSize))367    return static_cast<uint32_t>(*Value);368  return std::nullopt;369}370 371void MCPlusBuilder::setSize(MCInst &Inst, uint32_t Size) const {372  setAnnotationOpValue(Inst, MCAnnotation::kSize, Size);373}374 375bool MCPlusBuilder::isDynamicBranch(const MCInst &Inst) const {376  if (!hasAnnotation(Inst, MCAnnotation::kDynamicBranch))377    return false;378  assert(isBranch(Inst) && "Branch expected.");379  return true;380}381 382std::optional<uint32_t>383MCPlusBuilder::getDynamicBranchID(const MCInst &Inst) const {384  if (std::optional<int64_t> Value =385          getAnnotationOpValue(Inst, MCAnnotation::kDynamicBranch)) {386    assert(isBranch(Inst) && "Branch expected.");387    return static_cast<uint32_t>(*Value);388  }389  return std::nullopt;390}391 392void MCPlusBuilder::setDynamicBranch(MCInst &Inst, uint32_t ID) const {393  assert(isBranch(Inst) && "Branch expected.");394  setAnnotationOpValue(Inst, MCAnnotation::kDynamicBranch, ID);395}396 397bool MCPlusBuilder::hasAnnotation(const MCInst &Inst, unsigned Index) const {398  return (bool)getAnnotationOpValue(Inst, Index);399}400 401bool MCPlusBuilder::removeAnnotation(MCInst &Inst, unsigned Index) const {402  std::optional<unsigned> FirstAnnotationOp = getFirstAnnotationOpIndex(Inst);403  if (!FirstAnnotationOp)404    return false;405 406  for (unsigned I = Inst.getNumOperands() - 1; I >= *FirstAnnotationOp; --I) {407    const int64_t ImmValue = Inst.getOperand(I).getImm();408    if (extractAnnotationIndex(ImmValue) == Index) {409      Inst.erase(Inst.begin() + I);410      return true;411    }412  }413  return false;414}415 416void MCPlusBuilder::stripAnnotations(MCInst &Inst, bool KeepTC) const {417  KeepTC &= hasAnnotation(Inst, MCAnnotation::kTailCall);418 419  removeAnnotations(Inst);420 421  if (KeepTC)422    setTailCall(Inst);423}424 425void MCPlusBuilder::printAnnotations(const MCInst &Inst, raw_ostream &OS,426                                     bool PrintMemData) const {427  std::optional<unsigned> FirstAnnotationOp = getFirstAnnotationOpIndex(Inst);428  if (!FirstAnnotationOp)429    return;430 431  for (unsigned I = *FirstAnnotationOp; I < Inst.getNumOperands(); ++I) {432    const int64_t Imm = Inst.getOperand(I).getImm();433    const unsigned Index = extractAnnotationIndex(Imm);434    const int64_t Value = extractAnnotationValue(Imm);435    const auto *Annotation = reinterpret_cast<const MCAnnotation *>(Value);436    if (Index >= MCAnnotation::kGeneric) {437      std::string AnnotationName =438          AnnotationNames[Index - MCAnnotation::kGeneric];439      if (!PrintMemData && AnnotationName == "MemoryAccessProfile")440        continue;441      OS << " # " << AnnotationName << ": ";442      Annotation->print(OS);443    }444  }445}446 447void MCPlusBuilder::getClobberedRegs(const MCInst &Inst,448                                     BitVector &Regs) const {449  if (isPrefix(Inst) || isCFI(Inst))450    return;451 452  const MCInstrDesc &InstInfo = Info->get(Inst.getOpcode());453 454  for (MCPhysReg ImplicitDef : InstInfo.implicit_defs())455    Regs |= getAliases(ImplicitDef, /*OnlySmaller=*/false);456 457  for (const MCOperand &Operand : defOperands(Inst)) {458    assert(Operand.isReg());459    Regs |= getAliases(Operand.getReg(), /*OnlySmaller=*/false);460  }461}462 463void MCPlusBuilder::getTouchedRegs(const MCInst &Inst, BitVector &Regs) const {464  if (isPrefix(Inst) || isCFI(Inst))465    return;466 467  const MCInstrDesc &InstInfo = Info->get(Inst.getOpcode());468 469  for (MCPhysReg ImplicitDef : InstInfo.implicit_defs())470    Regs |= getAliases(ImplicitDef, /*OnlySmaller=*/false);471  for (MCPhysReg ImplicitUse : InstInfo.implicit_uses())472    Regs |= getAliases(ImplicitUse, /*OnlySmaller=*/false);473 474  for (unsigned I = 0, E = Inst.getNumOperands(); I != E; ++I) {475    if (!Inst.getOperand(I).isReg())476      continue;477    Regs |= getAliases(Inst.getOperand(I).getReg(), /*OnlySmaller=*/false);478  }479}480 481void MCPlusBuilder::getWrittenRegs(const MCInst &Inst, BitVector &Regs) const {482  if (isPrefix(Inst) || isCFI(Inst))483    return;484 485  const MCInstrDesc &InstInfo = Info->get(Inst.getOpcode());486 487  for (MCPhysReg ImplicitDef : InstInfo.implicit_defs())488    Regs |= getAliases(ImplicitDef, /*OnlySmaller=*/true);489 490  for (const MCOperand &Operand : defOperands(Inst)) {491    assert(Operand.isReg());492    Regs |= getAliases(Operand.getReg(), /*OnlySmaller=*/true);493  }494}495 496void MCPlusBuilder::getUsedRegs(const MCInst &Inst, BitVector &Regs) const {497  if (isPrefix(Inst) || isCFI(Inst))498    return;499 500  const MCInstrDesc &InstInfo = Info->get(Inst.getOpcode());501 502  for (MCPhysReg ImplicitUse : InstInfo.implicit_uses())503    Regs |= getAliases(ImplicitUse, /*OnlySmaller=*/true);504 505  for (const MCOperand &Operand : useOperands(Inst)) {506    if (!Operand.isReg())507      continue;508    Regs |= getAliases(Operand.getReg(), /*OnlySmaller=*/true);509  }510}511 512void MCPlusBuilder::getSrcRegs(const MCInst &Inst, BitVector &Regs) const {513  if (isPrefix(Inst) || isCFI(Inst))514    return;515 516  if (isCall(Inst)) {517    BitVector CallRegs = BitVector(Regs.size(), false);518    getCalleeSavedRegs(CallRegs);519    CallRegs.flip();520    Regs |= CallRegs;521    return;522  }523 524  if (isReturn(Inst)) {525    getDefaultLiveOut(Regs);526    return;527  }528 529  if (isRep(Inst))530    getRepRegs(Regs);531 532  const MCInstrDesc &InstInfo = Info->get(Inst.getOpcode());533 534  for (MCPhysReg ImplicitUse : InstInfo.implicit_uses())535    Regs |= getAliases(ImplicitUse, /*OnlySmaller=*/true);536 537  for (const MCOperand &Operand : useOperands(Inst))538    if (Operand.isReg())539      Regs |= getAliases(Operand.getReg(), /*OnlySmaller=*/true);540}541 542bool MCPlusBuilder::hasDefOfPhysReg(const MCInst &MI, unsigned Reg) const {543  const MCInstrDesc &InstInfo = Info->get(MI.getOpcode());544  return InstInfo.hasDefOfPhysReg(MI, Reg, *RegInfo);545}546 547bool MCPlusBuilder::hasUseOfPhysReg(const MCInst &MI, unsigned Reg) const {548  const MCInstrDesc &InstInfo = Info->get(MI.getOpcode());549  for (int I = InstInfo.NumDefs; I < InstInfo.NumOperands; ++I)550    if (MI.getOperand(I).isReg() && MI.getOperand(I).getReg() &&551        RegInfo->isSubRegisterEq(Reg, MI.getOperand(I).getReg()))552      return true;553  for (MCPhysReg ImplicitUse : InstInfo.implicit_uses()) {554    if (ImplicitUse == Reg || RegInfo->isSubRegister(Reg, ImplicitUse))555      return true;556  }557  return false;558}559 560const BitVector &MCPlusBuilder::getAliases(MCPhysReg Reg,561                                           bool OnlySmaller) const {562  if (OnlySmaller)563    return SmallerAliasMap[Reg];564  return AliasMap[Reg];565}566 567void MCPlusBuilder::initAliases() {568  assert(AliasMap.size() == 0 && SmallerAliasMap.size() == 0);569  // Build alias map570  for (MCPhysReg I = 0, E = RegInfo->getNumRegs(); I != E; ++I) {571    BitVector BV(RegInfo->getNumRegs(), false);572    BV.set(I);573    AliasMap.emplace_back(BV);574    SmallerAliasMap.emplace_back(BV);575  }576 577  // Cache all aliases for each register578  for (MCPhysReg I = 1, E = RegInfo->getNumRegs(); I != E; ++I) {579    for (MCRegAliasIterator AI(I, RegInfo, true); AI.isValid(); ++AI)580      AliasMap[I].set(*AI);581  }582 583  // Propagate smaller alias info upwards. Skip reg 0 (mapped to NoRegister)584  for (MCPhysReg I = 1, E = RegInfo->getNumRegs(); I < E; ++I)585    for (MCSubRegIterator SI(I, RegInfo); SI.isValid(); ++SI)586      SmallerAliasMap[I] |= SmallerAliasMap[*SI];587 588  LLVM_DEBUG({589    dbgs() << "Dumping reg alias table:\n";590    for (MCPhysReg I = 0, E = RegInfo->getNumRegs(); I != E; ++I) {591      dbgs() << "Reg " << I << ": ";592      const BitVector &BV = AliasMap[I];593      int Idx = BV.find_first();594      while (Idx != -1) {595        dbgs() << Idx << " ";596        Idx = BV.find_next(Idx);597      }598      dbgs() << "\n";599    }600  });601}602 603void MCPlusBuilder::initSizeMap() {604  SizeMap.resize(RegInfo->getNumRegs());605  // Build size map606  for (auto RC : RegInfo->regclasses())607    for (MCPhysReg Reg : RC)608      SizeMap[Reg] = RC.getSizeInBits() / 8;609}610 611bool MCPlusBuilder::setOperandToSymbolRef(MCInst &Inst, int OpNum,612                                          const MCSymbol *Symbol,613                                          int64_t Addend, MCContext *Ctx,614                                          uint32_t RelType) const {615  MCOperand Operand;616  if (!Addend) {617    Operand = MCOperand::createExpr(getTargetExprFor(618        Inst, MCSymbolRefExpr::create(Symbol, *Ctx), *Ctx, RelType));619  } else {620    Operand = MCOperand::createExpr(getTargetExprFor(621        Inst,622        MCBinaryExpr::createAdd(MCSymbolRefExpr::create(Symbol, *Ctx),623                                MCConstantExpr::create(Addend, *Ctx), *Ctx),624        *Ctx, RelType));625  }626  Inst.getOperand(OpNum) = Operand;627  return true;628}629