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