1//===-- HexagonMCTargetDesc.cpp - Hexagon Target Descriptions -------------===//
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-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file provides Hexagon specific target descriptions.
10//
11//===----------------------------------------------------------------------===//
12
13#include "HexagonArch.h"
14#include "HexagonTargetStreamer.h"
15#include "MCTargetDesc/HexagonInstPrinter.h"
16#include "MCTargetDesc/HexagonMCAsmInfo.h"
17#include "MCTargetDesc/HexagonMCELFStreamer.h"
18#include "MCTargetDesc/HexagonMCInstrInfo.h"
19#include "MCTargetDesc/HexagonMCTargetDesc.h"
20#include "TargetInfo/HexagonTargetInfo.h"
21#include "llvm/ADT/StringExtras.h"
22#include "llvm/ADT/StringRef.h"
23#include "llvm/BinaryFormat/ELF.h"
24#include "llvm/MC/MCAsmBackend.h"
25#include "llvm/MC/MCCodeEmitter.h"
26#include "llvm/MC/MCContext.h"
27#include "llvm/MC/MCDwarf.h"
28#include "llvm/MC/MCELFStreamer.h"
29#include "llvm/MC/MCInstrAnalysis.h"
30#include "llvm/MC/MCInstrInfo.h"
31#include "llvm/MC/MCObjectWriter.h"
32#include "llvm/MC/MCRegisterInfo.h"
33#include "llvm/MC/MCStreamer.h"
34#include "llvm/MC/MCSubtargetInfo.h"
35#include "llvm/Support/ErrorHandling.h"
36#include "llvm/Support/TargetRegistry.h"
37#include "llvm/Support/raw_ostream.h"
38#include <cassert>
39#include <cstdint>
40#include <mutex>
41#include <new>
42#include <string>
43#include <unordered_map>
44
45using namespace llvm;
46
47#define GET_INSTRINFO_MC_DESC
48#include "HexagonGenInstrInfo.inc"
49
50#define GET_SUBTARGETINFO_MC_DESC
51#include "HexagonGenSubtargetInfo.inc"
52
53#define GET_REGINFO_MC_DESC
54#include "HexagonGenRegisterInfo.inc"
55
56cl::opt<bool> llvm::HexagonDisableCompound
57  ("mno-compound",
58   cl::desc("Disable looking for compound instructions for Hexagon"));
59
60cl::opt<bool> llvm::HexagonDisableDuplex
61  ("mno-pairing",
62   cl::desc("Disable looking for duplex instructions for Hexagon"));
63
64namespace { // These flags are to be deprecated
65cl::opt<bool> MV5("mv5", cl::Hidden, cl::desc("Build for Hexagon V5"),
66                  cl::init(false));
67cl::opt<bool> MV55("mv55", cl::Hidden, cl::desc("Build for Hexagon V55"),
68                   cl::init(false));
69cl::opt<bool> MV60("mv60", cl::Hidden, cl::desc("Build for Hexagon V60"),
70                   cl::init(false));
71cl::opt<bool> MV62("mv62", cl::Hidden, cl::desc("Build for Hexagon V62"),
72                   cl::init(false));
73cl::opt<bool> MV65("mv65", cl::Hidden, cl::desc("Build for Hexagon V65"),
74                   cl::init(false));
75cl::opt<bool> MV66("mv66", cl::Hidden, cl::desc("Build for Hexagon V66"),
76                   cl::init(false));
77cl::opt<bool> MV67("mv67", cl::Hidden, cl::desc("Build for Hexagon V67"),
78                   cl::init(false));
79cl::opt<bool> MV67T("mv67t", cl::Hidden, cl::desc("Build for Hexagon V67T"),
80                    cl::init(false));
81cl::opt<bool> MV68("mv68", cl::Hidden, cl::desc("Build for Hexagon V68"),
82                   cl::init(false));
83
84cl::opt<Hexagon::ArchEnum>
85    EnableHVX("mhvx",
86      cl::desc("Enable Hexagon Vector eXtensions"),
87      cl::values(
88        clEnumValN(Hexagon::ArchEnum::V60, "v60", "Build for HVX v60"),
89        clEnumValN(Hexagon::ArchEnum::V62, "v62", "Build for HVX v62"),
90        clEnumValN(Hexagon::ArchEnum::V65, "v65", "Build for HVX v65"),
91        clEnumValN(Hexagon::ArchEnum::V66, "v66", "Build for HVX v66"),
92        clEnumValN(Hexagon::ArchEnum::V67, "v67", "Build for HVX v67"),
93        clEnumValN(Hexagon::ArchEnum::V68, "v68", "Build for HVX v68"),
94        // Sentinel for no value specified.
95        clEnumValN(Hexagon::ArchEnum::Generic, "", "")),
96      // Sentinel for flag not present.
97      cl::init(Hexagon::ArchEnum::NoArch), cl::ValueOptional);
98} // namespace
99
100static cl::opt<bool>
101  DisableHVX("mno-hvx", cl::Hidden,
102             cl::desc("Disable Hexagon Vector eXtensions"));
103
104
105static StringRef DefaultArch = "hexagonv60";
106
107static StringRef HexagonGetArchVariant() {
108  if (MV5)
109    return "hexagonv5";
110  if (MV55)
111    return "hexagonv55";
112  if (MV60)
113    return "hexagonv60";
114  if (MV62)
115    return "hexagonv62";
116  if (MV65)
117    return "hexagonv65";
118  if (MV66)
119    return "hexagonv66";
120  if (MV67)
121    return "hexagonv67";
122  if (MV67T)
123    return "hexagonv67t";
124  if (MV68)
125    return "hexagonv68";
126  return "";
127}
128
129StringRef Hexagon_MC::selectHexagonCPU(StringRef CPU) {
130  StringRef ArchV = HexagonGetArchVariant();
131  if (!ArchV.empty() && !CPU.empty()) {
132    // Tiny cores have a "t" suffix that is discarded when creating a secondary
133    // non-tiny subtarget.  See: addArchSubtarget
134    std::pair<StringRef,StringRef> ArchP = ArchV.split('t');
135    std::pair<StringRef,StringRef> CPUP = CPU.split('t');
136    if (!ArchP.first.equals(CPUP.first))
137        report_fatal_error("conflicting architectures specified.");
138    return CPU;
139  }
140  if (ArchV.empty()) {
141    if (CPU.empty())
142      CPU = DefaultArch;
143    return CPU;
144  }
145  return ArchV;
146}
147
148unsigned llvm::HexagonGetLastSlot() { return HexagonItinerariesV5FU::SLOT3; }
149
150unsigned llvm::HexagonConvertUnits(unsigned ItinUnits, unsigned *Lanes) {
151  enum {
152    CVI_NONE = 0,
153    CVI_XLANE = 1 << 0,
154    CVI_SHIFT = 1 << 1,
155    CVI_MPY0 = 1 << 2,
156    CVI_MPY1 = 1 << 3,
157    CVI_ZW = 1 << 4
158  };
159
160  if (ItinUnits == HexagonItinerariesV62FU::CVI_ALL ||
161      ItinUnits == HexagonItinerariesV62FU::CVI_ALL_NOMEM)
162    return (*Lanes = 4, CVI_XLANE);
163  else if (ItinUnits & HexagonItinerariesV62FU::CVI_MPY01 &&
164           ItinUnits & HexagonItinerariesV62FU::CVI_XLSHF)
165    return (*Lanes = 2, CVI_XLANE | CVI_MPY0);
166  else if (ItinUnits & HexagonItinerariesV62FU::CVI_MPY01)
167    return (*Lanes = 2, CVI_MPY0);
168  else if (ItinUnits & HexagonItinerariesV62FU::CVI_XLSHF)
169    return (*Lanes = 2, CVI_XLANE);
170  else if (ItinUnits & HexagonItinerariesV62FU::CVI_XLANE &&
171           ItinUnits & HexagonItinerariesV62FU::CVI_SHIFT &&
172           ItinUnits & HexagonItinerariesV62FU::CVI_MPY0 &&
173           ItinUnits & HexagonItinerariesV62FU::CVI_MPY1)
174    return (*Lanes = 1, CVI_XLANE | CVI_SHIFT | CVI_MPY0 | CVI_MPY1);
175  else if (ItinUnits & HexagonItinerariesV62FU::CVI_XLANE &&
176           ItinUnits & HexagonItinerariesV62FU::CVI_SHIFT)
177    return (*Lanes = 1, CVI_XLANE | CVI_SHIFT);
178  else if (ItinUnits & HexagonItinerariesV62FU::CVI_MPY0 &&
179           ItinUnits & HexagonItinerariesV62FU::CVI_MPY1)
180    return (*Lanes = 1, CVI_MPY0 | CVI_MPY1);
181  else if (ItinUnits == HexagonItinerariesV62FU::CVI_ZW)
182    return (*Lanes = 1, CVI_ZW);
183  else if (ItinUnits == HexagonItinerariesV62FU::CVI_XLANE)
184    return (*Lanes = 1, CVI_XLANE);
185  else if (ItinUnits == HexagonItinerariesV62FU::CVI_SHIFT)
186    return (*Lanes = 1, CVI_SHIFT);
187
188  return (*Lanes = 0, CVI_NONE);
189}
190
191
192namespace llvm {
193namespace HexagonFUnits {
194bool isSlot0Only(unsigned units) {
195  return HexagonItinerariesV62FU::SLOT0 == units;
196}
197} // namespace HexagonFUnits
198} // namespace llvm
199
200namespace {
201
202class HexagonTargetAsmStreamer : public HexagonTargetStreamer {
203public:
204  HexagonTargetAsmStreamer(MCStreamer &S,
205                           formatted_raw_ostream &OS,
206                           bool isVerboseAsm,
207                           MCInstPrinter &IP)
208      : HexagonTargetStreamer(S) {}
209
210  void prettyPrintAsm(MCInstPrinter &InstPrinter, uint64_t Address,
211                      const MCInst &Inst, const MCSubtargetInfo &STI,
212                      raw_ostream &OS) override {
213    assert(HexagonMCInstrInfo::isBundle(Inst));
214    assert(HexagonMCInstrInfo::bundleSize(Inst) <= HEXAGON_PACKET_SIZE);
215    std::string Buffer;
216    {
217      raw_string_ostream TempStream(Buffer);
218      InstPrinter.printInst(&Inst, Address, "", STI, TempStream);
219    }
220    StringRef Contents(Buffer);
221    auto PacketBundle = Contents.rsplit('\n');
222    auto HeadTail = PacketBundle.first.split('\n');
223    StringRef Separator = "\n";
224    StringRef Indent = "\t";
225    OS << "\t{\n";
226    while (!HeadTail.first.empty()) {
227      StringRef InstTxt;
228      auto Duplex = HeadTail.first.split('\v');
229      if (!Duplex.second.empty()) {
230        OS << Indent << Duplex.first << Separator;
231        InstTxt = Duplex.second;
232      } else if (!HeadTail.first.trim().startswith("immext")) {
233        InstTxt = Duplex.first;
234      }
235      if (!InstTxt.empty())
236        OS << Indent << InstTxt << Separator;
237      HeadTail = HeadTail.second.split('\n');
238    }
239
240    if (HexagonMCInstrInfo::isMemReorderDisabled(Inst))
241      OS << "\n\t} :mem_noshuf" << PacketBundle.second;
242    else
243      OS << "\t}" << PacketBundle.second;
244  }
245};
246
247class HexagonTargetELFStreamer : public HexagonTargetStreamer {
248public:
249  MCELFStreamer &getStreamer() {
250    return static_cast<MCELFStreamer &>(Streamer);
251  }
252  HexagonTargetELFStreamer(MCStreamer &S, MCSubtargetInfo const &STI)
253      : HexagonTargetStreamer(S) {
254    MCAssembler &MCA = getStreamer().getAssembler();
255    MCA.setELFHeaderEFlags(Hexagon_MC::GetELFFlags(STI));
256  }
257
258
259  void emitCommonSymbolSorted(MCSymbol *Symbol, uint64_t Size,
260                              unsigned ByteAlignment,
261                              unsigned AccessSize) override {
262    HexagonMCELFStreamer &HexagonELFStreamer =
263        static_cast<HexagonMCELFStreamer &>(getStreamer());
264    HexagonELFStreamer.HexagonMCEmitCommonSymbol(Symbol, Size, ByteAlignment,
265                                                 AccessSize);
266  }
267
268  void emitLocalCommonSymbolSorted(MCSymbol *Symbol, uint64_t Size,
269                                   unsigned ByteAlignment,
270                                   unsigned AccessSize) override {
271    HexagonMCELFStreamer &HexagonELFStreamer =
272        static_cast<HexagonMCELFStreamer &>(getStreamer());
273    HexagonELFStreamer.HexagonMCEmitLocalCommonSymbol(
274        Symbol, Size, ByteAlignment, AccessSize);
275  }
276};
277
278} // end anonymous namespace
279
280llvm::MCInstrInfo *llvm::createHexagonMCInstrInfo() {
281  MCInstrInfo *X = new MCInstrInfo();
282  InitHexagonMCInstrInfo(X);
283  return X;
284}
285
286static MCRegisterInfo *createHexagonMCRegisterInfo(const Triple &TT) {
287  MCRegisterInfo *X = new MCRegisterInfo();
288  InitHexagonMCRegisterInfo(X, Hexagon::R31);
289  return X;
290}
291
292static MCAsmInfo *createHexagonMCAsmInfo(const MCRegisterInfo &MRI,
293                                         const Triple &TT,
294                                         const MCTargetOptions &Options) {
295  MCAsmInfo *MAI = new HexagonMCAsmInfo(TT);
296
297  // VirtualFP = (R30 + #0).
298  MCCFIInstruction Inst = MCCFIInstruction::cfiDefCfa(
299      nullptr, MRI.getDwarfRegNum(Hexagon::R30, true), 0);
300  MAI->addInitialFrameState(Inst);
301
302  return MAI;
303}
304
305static MCInstPrinter *createHexagonMCInstPrinter(const Triple &T,
306                                                 unsigned SyntaxVariant,
307                                                 const MCAsmInfo &MAI,
308                                                 const MCInstrInfo &MII,
309                                                 const MCRegisterInfo &MRI)
310{
311  if (SyntaxVariant == 0)
312    return new HexagonInstPrinter(MAI, MII, MRI);
313  else
314    return nullptr;
315}
316
317static MCTargetStreamer *
318createMCAsmTargetStreamer(MCStreamer &S, formatted_raw_ostream &OS,
319                          MCInstPrinter *IP, bool IsVerboseAsm) {
320  return new HexagonTargetAsmStreamer(S, OS, IsVerboseAsm, *IP);
321}
322
323static MCStreamer *createMCStreamer(Triple const &T, MCContext &Context,
324                                    std::unique_ptr<MCAsmBackend> &&MAB,
325                                    std::unique_ptr<MCObjectWriter> &&OW,
326                                    std::unique_ptr<MCCodeEmitter> &&Emitter,
327                                    bool RelaxAll) {
328  return createHexagonELFStreamer(T, Context, std::move(MAB), std::move(OW),
329                                  std::move(Emitter));
330}
331
332static MCTargetStreamer *
333createHexagonObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) {
334  return new HexagonTargetELFStreamer(S, STI);
335}
336
337static void LLVM_ATTRIBUTE_UNUSED clearFeature(MCSubtargetInfo* STI, uint64_t F) {
338  if (STI->getFeatureBits()[F])
339    STI->ToggleFeature(F);
340}
341
342static bool LLVM_ATTRIBUTE_UNUSED checkFeature(MCSubtargetInfo* STI, uint64_t F) {
343  return STI->getFeatureBits()[F];
344}
345
346namespace {
347std::string selectHexagonFS(StringRef CPU, StringRef FS) {
348  SmallVector<StringRef, 3> Result;
349  if (!FS.empty())
350    Result.push_back(FS);
351
352  switch (EnableHVX) {
353  case Hexagon::ArchEnum::V5:
354  case Hexagon::ArchEnum::V55:
355    break;
356  case Hexagon::ArchEnum::V60:
357    Result.push_back("+hvxv60");
358    break;
359  case Hexagon::ArchEnum::V62:
360    Result.push_back("+hvxv62");
361    break;
362  case Hexagon::ArchEnum::V65:
363    Result.push_back("+hvxv65");
364    break;
365  case Hexagon::ArchEnum::V66:
366    Result.push_back("+hvxv66");
367    break;
368  case Hexagon::ArchEnum::V67:
369    Result.push_back("+hvxv67");
370    break;
371  case Hexagon::ArchEnum::V68:
372    Result.push_back("+hvxv68");
373    break;
374  case Hexagon::ArchEnum::Generic:{
375    Result.push_back(StringSwitch<StringRef>(CPU)
376             .Case("hexagonv60", "+hvxv60")
377             .Case("hexagonv62", "+hvxv62")
378             .Case("hexagonv65", "+hvxv65")
379             .Case("hexagonv66", "+hvxv66")
380             .Case("hexagonv67", "+hvxv67")
381             .Case("hexagonv67t", "+hvxv67")
382             .Case("hexagonv68", "+hvxv68"));
383    break;
384  }
385  case Hexagon::ArchEnum::NoArch:
386    // Sentinel if -mhvx isn't specified
387    break;
388  }
389  return join(Result.begin(), Result.end(), ",");
390}
391}
392
393static bool isCPUValid(const std::string &CPU) {
394  return Hexagon::CpuTable.find(CPU) != Hexagon::CpuTable.cend();
395}
396
397namespace {
398std::pair<std::string, std::string> selectCPUAndFS(StringRef CPU,
399                                                   StringRef FS) {
400  std::pair<std::string, std::string> Result;
401  Result.first = std::string(Hexagon_MC::selectHexagonCPU(CPU));
402  Result.second = selectHexagonFS(Result.first, FS);
403  return Result;
404}
405std::mutex ArchSubtargetMutex;
406std::unordered_map<std::string, std::unique_ptr<MCSubtargetInfo const>>
407    ArchSubtarget;
408} // namespace
409
410MCSubtargetInfo const *
411Hexagon_MC::getArchSubtarget(MCSubtargetInfo const *STI) {
412  std::lock_guard<std::mutex> Lock(ArchSubtargetMutex);
413  auto Existing = ArchSubtarget.find(std::string(STI->getCPU()));
414  if (Existing == ArchSubtarget.end())
415    return nullptr;
416  return Existing->second.get();
417}
418
419FeatureBitset Hexagon_MC::completeHVXFeatures(const FeatureBitset &S) {
420  using namespace Hexagon;
421  // Make sure that +hvx-length turns hvx on, and that "hvx" alone
422  // turns on hvxvNN, corresponding to the existing ArchVNN.
423  FeatureBitset FB = S;
424  unsigned CpuArch = ArchV5;
425  for (unsigned F : {ArchV68, ArchV67, ArchV66, ArchV65, ArchV62, ArchV60,
426                     ArchV55, ArchV5}) {
427    if (!FB.test(F))
428      continue;
429    CpuArch = F;
430    break;
431  }
432  bool UseHvx = false;
433  for (unsigned F : {ExtensionHVX, ExtensionHVX64B, ExtensionHVX128B}) {
434    if (!FB.test(F))
435      continue;
436    UseHvx = true;
437    break;
438  }
439  bool HasHvxVer = false;
440  for (unsigned F : {ExtensionHVXV60, ExtensionHVXV62, ExtensionHVXV65,
441                     ExtensionHVXV66, ExtensionHVXV67, ExtensionHVXV68}) {
442    if (!FB.test(F))
443      continue;
444    HasHvxVer = true;
445    UseHvx = true;
446    break;
447  }
448
449  if (!UseHvx || HasHvxVer)
450    return FB;
451
452  // HasHvxVer is false, and UseHvx is true.
453  switch (CpuArch) {
454    case ArchV68:
455      FB.set(ExtensionHVXV68);
456      LLVM_FALLTHROUGH;
457    case ArchV67:
458      FB.set(ExtensionHVXV67);
459      LLVM_FALLTHROUGH;
460    case ArchV66:
461      FB.set(ExtensionHVXV66);
462      LLVM_FALLTHROUGH;
463    case ArchV65:
464      FB.set(ExtensionHVXV65);
465      LLVM_FALLTHROUGH;
466    case ArchV62:
467      FB.set(ExtensionHVXV62);
468      LLVM_FALLTHROUGH;
469    case ArchV60:
470      FB.set(ExtensionHVXV60);
471      break;
472  }
473  return FB;
474}
475
476MCSubtargetInfo *Hexagon_MC::createHexagonMCSubtargetInfo(const Triple &TT,
477                                                          StringRef CPU,
478                                                          StringRef FS) {
479  std::pair<std::string, std::string> Features = selectCPUAndFS(CPU, FS);
480  StringRef CPUName = Features.first;
481  StringRef ArchFS = Features.second;
482
483  MCSubtargetInfo *X = createHexagonMCSubtargetInfoImpl(
484      TT, CPUName, /*TuneCPU*/ CPUName, ArchFS);
485  if (X != nullptr && (CPUName == "hexagonv67t"))
486    addArchSubtarget(X, ArchFS);
487
488  if (CPU.equals("help"))
489      exit(0);
490
491  if (!isCPUValid(CPUName.str())) {
492    errs() << "error: invalid CPU \"" << CPUName.str().c_str()
493           << "\" specified\n";
494    return nullptr;
495  }
496
497  if (HexagonDisableDuplex) {
498    llvm::FeatureBitset Features = X->getFeatureBits();
499    X->setFeatureBits(Features.reset(Hexagon::FeatureDuplex));
500  }
501
502  X->setFeatureBits(completeHVXFeatures(X->getFeatureBits()));
503
504  // The Z-buffer instructions are grandfathered in for current
505  // architectures but omitted for new ones.  Future instruction
506  // sets may introduce new/conflicting z-buffer instructions.
507  const bool ZRegOnDefault =
508      (CPUName == "hexagonv67") || (CPUName == "hexagonv66");
509  if (ZRegOnDefault) {
510    llvm::FeatureBitset Features = X->getFeatureBits();
511    X->setFeatureBits(Features.set(Hexagon::ExtensionZReg));
512  }
513
514  return X;
515}
516
517void Hexagon_MC::addArchSubtarget(MCSubtargetInfo const *STI,
518                                  StringRef FS) {
519  assert(STI != nullptr);
520  if (STI->getCPU().contains("t")) {
521    auto ArchSTI = createHexagonMCSubtargetInfo(
522        STI->getTargetTriple(),
523        STI->getCPU().substr(0, STI->getCPU().size() - 1), FS);
524    std::lock_guard<std::mutex> Lock(ArchSubtargetMutex);
525    ArchSubtarget[std::string(STI->getCPU())] =
526        std::unique_ptr<MCSubtargetInfo const>(ArchSTI);
527  }
528}
529
530unsigned Hexagon_MC::GetELFFlags(const MCSubtargetInfo &STI) {
531  static std::map<StringRef,unsigned> ElfFlags = {
532    {"hexagonv5",  ELF::EF_HEXAGON_MACH_V5},
533    {"hexagonv55", ELF::EF_HEXAGON_MACH_V55},
534    {"hexagonv60", ELF::EF_HEXAGON_MACH_V60},
535    {"hexagonv62", ELF::EF_HEXAGON_MACH_V62},
536    {"hexagonv65", ELF::EF_HEXAGON_MACH_V65},
537    {"hexagonv66", ELF::EF_HEXAGON_MACH_V66},
538    {"hexagonv67", ELF::EF_HEXAGON_MACH_V67},
539    {"hexagonv67t", ELF::EF_HEXAGON_MACH_V67T},
540    {"hexagonv68", ELF::EF_HEXAGON_MACH_V68},
541  };
542
543  auto F = ElfFlags.find(STI.getCPU());
544  assert(F != ElfFlags.end() && "Unrecognized Architecture");
545  return F->second;
546}
547
548llvm::ArrayRef<MCPhysReg> Hexagon_MC::GetVectRegRev() {
549  return makeArrayRef(VectRegRev);
550}
551
552namespace {
553class HexagonMCInstrAnalysis : public MCInstrAnalysis {
554public:
555  HexagonMCInstrAnalysis(MCInstrInfo const *Info) : MCInstrAnalysis(Info) {}
556
557  bool isUnconditionalBranch(MCInst const &Inst) const override {
558    //assert(!HexagonMCInstrInfo::isBundle(Inst));
559    return MCInstrAnalysis::isUnconditionalBranch(Inst);
560  }
561
562  bool isConditionalBranch(MCInst const &Inst) const override {
563    //assert(!HexagonMCInstrInfo::isBundle(Inst));
564    return MCInstrAnalysis::isConditionalBranch(Inst);
565  }
566
567  bool evaluateBranch(MCInst const &Inst, uint64_t Addr,
568                      uint64_t Size, uint64_t &Target) const override {
569    if (!(isCall(Inst) || isUnconditionalBranch(Inst) ||
570          isConditionalBranch(Inst)))
571      return false;
572
573    //assert(!HexagonMCInstrInfo::isBundle(Inst));
574    if(!HexagonMCInstrInfo::isExtendable(*Info, Inst))
575      return false;
576    auto const &Extended(HexagonMCInstrInfo::getExtendableOperand(*Info, Inst));
577    assert(Extended.isExpr());
578    int64_t Value;
579    if(!Extended.getExpr()->evaluateAsAbsolute(Value))
580      return false;
581    Target = Value;
582    return true;
583  }
584};
585}
586
587static MCInstrAnalysis *createHexagonMCInstrAnalysis(const MCInstrInfo *Info) {
588  return new HexagonMCInstrAnalysis(Info);
589}
590
591// Force static initialization.
592extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeHexagonTargetMC() {
593  // Register the MC asm info.
594  RegisterMCAsmInfoFn X(getTheHexagonTarget(), createHexagonMCAsmInfo);
595
596  // Register the MC instruction info.
597  TargetRegistry::RegisterMCInstrInfo(getTheHexagonTarget(),
598                                      createHexagonMCInstrInfo);
599
600  // Register the MC register info.
601  TargetRegistry::RegisterMCRegInfo(getTheHexagonTarget(),
602                                    createHexagonMCRegisterInfo);
603
604  // Register the MC subtarget info.
605  TargetRegistry::RegisterMCSubtargetInfo(getTheHexagonTarget(),
606    Hexagon_MC::createHexagonMCSubtargetInfo);
607
608  // Register the MC Code Emitter
609  TargetRegistry::RegisterMCCodeEmitter(getTheHexagonTarget(),
610                                        createHexagonMCCodeEmitter);
611
612  // Register the asm backend
613  TargetRegistry::RegisterMCAsmBackend(getTheHexagonTarget(),
614                                       createHexagonAsmBackend);
615
616
617  // Register the MC instruction analyzer.
618  TargetRegistry::RegisterMCInstrAnalysis(getTheHexagonTarget(),
619                                          createHexagonMCInstrAnalysis);
620
621  // Register the obj streamer
622  TargetRegistry::RegisterELFStreamer(getTheHexagonTarget(),
623                                      createMCStreamer);
624
625  // Register the obj target streamer
626  TargetRegistry::RegisterObjectTargetStreamer(getTheHexagonTarget(),
627                                      createHexagonObjectTargetStreamer);
628
629  // Register the asm streamer
630  TargetRegistry::RegisterAsmTargetStreamer(getTheHexagonTarget(),
631                                            createMCAsmTargetStreamer);
632
633  // Register the MC Inst Printer
634  TargetRegistry::RegisterMCInstPrinter(getTheHexagonTarget(),
635                                        createHexagonMCInstPrinter);
636}
637