1 //===-- HexagonMCTargetDesc.cpp - Hexagon Target Descriptions -------------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file provides Hexagon specific target descriptions.
11 //===----------------------------------------------------------------------===//
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"
43 #include <unordered_map>
47 #define GET_INSTRINFO_MC_DESC
48 #include "HexagonGenInstrInfo.inc"
50 #define GET_SUBTARGETINFO_MC_DESC
51 #include "HexagonGenSubtargetInfo.inc"
53 #define GET_REGINFO_MC_DESC
54 #include "HexagonGenRegisterInfo.inc"
56 cl::opt
<bool> llvm::HexagonDisableCompound
58 cl::desc("Disable looking for compound instructions for Hexagon"));
60 cl::opt
<bool> llvm::HexagonDisableDuplex
62 cl::desc("Disable looking for duplex instructions for Hexagon"));
64 namespace { // These flags are to be deprecated
65 cl::opt
<bool> MV5("mv5", cl::Hidden
, cl::desc("Build for Hexagon V5"),
67 cl::opt
<bool> MV55("mv55", cl::Hidden
, cl::desc("Build for Hexagon V55"),
69 cl::opt
<bool> MV60("mv60", cl::Hidden
, cl::desc("Build for Hexagon V60"),
71 cl::opt
<bool> MV62("mv62", cl::Hidden
, cl::desc("Build for Hexagon V62"),
73 cl::opt
<bool> MV65("mv65", cl::Hidden
, cl::desc("Build for Hexagon V65"),
75 cl::opt
<bool> MV66("mv66", cl::Hidden
, cl::desc("Build for Hexagon V66"),
77 cl::opt
<bool> MV67("mv67", cl::Hidden
, cl::desc("Build for Hexagon V67"),
79 cl::opt
<bool> MV67T("mv67t", cl::Hidden
, cl::desc("Build for Hexagon V67T"),
81 cl::opt
<bool> MV68("mv68", cl::Hidden
, cl::desc("Build for Hexagon V68"),
84 cl::opt
<Hexagon::ArchEnum
>
86 cl::desc("Enable Hexagon Vector eXtensions"),
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
);
101 DisableHVX("mno-hvx", cl::Hidden
,
102 cl::desc("Disable Hexagon Vector eXtensions"));
105 static StringRef DefaultArch
= "hexagonv60";
107 static StringRef
HexagonGetArchVariant() {
123 return "hexagonv67t";
129 StringRef
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.");
148 unsigned llvm::HexagonGetLastSlot() { return HexagonItinerariesV5FU::SLOT3
; }
150 unsigned llvm::HexagonConvertUnits(unsigned ItinUnits
, unsigned *Lanes
) {
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
);
188 return (*Lanes
= 0, CVI_NONE
);
193 namespace HexagonFUnits
{
194 bool isSlot0Only(unsigned units
) {
195 return HexagonItinerariesV62FU::SLOT0
== units
;
197 } // namespace HexagonFUnits
202 class HexagonTargetAsmStreamer
: public HexagonTargetStreamer
{
204 HexagonTargetAsmStreamer(MCStreamer
&S
,
205 formatted_raw_ostream
&OS
,
208 : HexagonTargetStreamer(S
) {}
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
);
217 raw_string_ostream
TempStream(Buffer
);
218 InstPrinter
.printInst(&Inst
, Address
, "", STI
, TempStream
);
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";
226 while (!HeadTail
.first
.empty()) {
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
;
235 if (!InstTxt
.empty())
236 OS
<< Indent
<< InstTxt
<< Separator
;
237 HeadTail
= HeadTail
.second
.split('\n');
240 if (HexagonMCInstrInfo::isMemReorderDisabled(Inst
))
241 OS
<< "\n\t} :mem_noshuf" << PacketBundle
.second
;
243 OS
<< "\t}" << PacketBundle
.second
;
247 class HexagonTargetELFStreamer
: public HexagonTargetStreamer
{
249 MCELFStreamer
&getStreamer() {
250 return static_cast<MCELFStreamer
&>(Streamer
);
252 HexagonTargetELFStreamer(MCStreamer
&S
, MCSubtargetInfo
const &STI
)
253 : HexagonTargetStreamer(S
) {
254 MCAssembler
&MCA
= getStreamer().getAssembler();
255 MCA
.setELFHeaderEFlags(Hexagon_MC::GetELFFlags(STI
));
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
,
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
);
278 } // end anonymous namespace
280 llvm::MCInstrInfo
*llvm::createHexagonMCInstrInfo() {
281 MCInstrInfo
*X
= new MCInstrInfo();
282 InitHexagonMCInstrInfo(X
);
286 static MCRegisterInfo
*createHexagonMCRegisterInfo(const Triple
&TT
) {
287 MCRegisterInfo
*X
= new MCRegisterInfo();
288 InitHexagonMCRegisterInfo(X
, Hexagon::R31
);
292 static MCAsmInfo
*createHexagonMCAsmInfo(const MCRegisterInfo
&MRI
,
294 const MCTargetOptions
&Options
) {
295 MCAsmInfo
*MAI
= new HexagonMCAsmInfo(TT
);
297 // VirtualFP = (R30 + #0).
298 MCCFIInstruction Inst
= MCCFIInstruction::cfiDefCfa(
299 nullptr, MRI
.getDwarfRegNum(Hexagon::R30
, true), 0);
300 MAI
->addInitialFrameState(Inst
);
305 static MCInstPrinter
*createHexagonMCInstPrinter(const Triple
&T
,
306 unsigned SyntaxVariant
,
307 const MCAsmInfo
&MAI
,
308 const MCInstrInfo
&MII
,
309 const MCRegisterInfo
&MRI
)
311 if (SyntaxVariant
== 0)
312 return new HexagonInstPrinter(MAI
, MII
, MRI
);
317 static MCTargetStreamer
*
318 createMCAsmTargetStreamer(MCStreamer
&S
, formatted_raw_ostream
&OS
,
319 MCInstPrinter
*IP
, bool IsVerboseAsm
) {
320 return new HexagonTargetAsmStreamer(S
, OS
, IsVerboseAsm
, *IP
);
323 static 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
,
328 return createHexagonELFStreamer(T
, Context
, std::move(MAB
), std::move(OW
),
332 static MCTargetStreamer
*
333 createHexagonObjectTargetStreamer(MCStreamer
&S
, const MCSubtargetInfo
&STI
) {
334 return new HexagonTargetELFStreamer(S
, STI
);
337 static void LLVM_ATTRIBUTE_UNUSED
clearFeature(MCSubtargetInfo
* STI
, uint64_t F
) {
338 if (STI
->getFeatureBits()[F
])
339 STI
->ToggleFeature(F
);
342 static bool LLVM_ATTRIBUTE_UNUSED
checkFeature(MCSubtargetInfo
* STI
, uint64_t F
) {
343 return STI
->getFeatureBits()[F
];
347 std::string
selectHexagonFS(StringRef CPU
, StringRef FS
) {
348 SmallVector
<StringRef
, 3> Result
;
350 Result
.push_back(FS
);
353 case Hexagon::ArchEnum::V5
:
354 case Hexagon::ArchEnum::V55
:
356 case Hexagon::ArchEnum::V60
:
357 Result
.push_back("+hvxv60");
359 case Hexagon::ArchEnum::V62
:
360 Result
.push_back("+hvxv62");
362 case Hexagon::ArchEnum::V65
:
363 Result
.push_back("+hvxv65");
365 case Hexagon::ArchEnum::V66
:
366 Result
.push_back("+hvxv66");
368 case Hexagon::ArchEnum::V67
:
369 Result
.push_back("+hvxv67");
371 case Hexagon::ArchEnum::V68
:
372 Result
.push_back("+hvxv68");
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"));
385 case Hexagon::ArchEnum::NoArch
:
386 // Sentinel if -mhvx isn't specified
389 return join(Result
.begin(), Result
.end(), ",");
393 static bool isCPUValid(const std::string
&CPU
) {
394 return Hexagon::CpuTable
.find(CPU
) != Hexagon::CpuTable
.cend();
398 std::pair
<std::string
, std::string
> selectCPUAndFS(StringRef CPU
,
400 std::pair
<std::string
, std::string
> Result
;
401 Result
.first
= std::string(Hexagon_MC::selectHexagonCPU(CPU
));
402 Result
.second
= selectHexagonFS(Result
.first
, FS
);
405 std::mutex ArchSubtargetMutex
;
406 std::unordered_map
<std::string
, std::unique_ptr
<MCSubtargetInfo
const>>
410 MCSubtargetInfo
const *
411 Hexagon_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())
416 return Existing
->second
.get();
419 FeatureBitset
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
,
433 for (unsigned F
: {ExtensionHVX
, ExtensionHVX64B
, ExtensionHVX128B
}) {
439 bool HasHvxVer
= false;
440 for (unsigned F
: {ExtensionHVXV60
, ExtensionHVXV62
, ExtensionHVXV65
,
441 ExtensionHVXV66
, ExtensionHVXV67
, ExtensionHVXV68
}) {
449 if (!UseHvx
|| HasHvxVer
)
452 // HasHvxVer is false, and UseHvx is true.
455 FB
.set(ExtensionHVXV68
);
458 FB
.set(ExtensionHVXV67
);
461 FB
.set(ExtensionHVXV66
);
464 FB
.set(ExtensionHVXV65
);
467 FB
.set(ExtensionHVXV62
);
470 FB
.set(ExtensionHVXV60
);
476 MCSubtargetInfo
*Hexagon_MC::createHexagonMCSubtargetInfo(const Triple
&TT
,
479 std::pair
<std::string
, std::string
> Features
= selectCPUAndFS(CPU
, FS
);
480 StringRef CPUName
= Features
.first
;
481 StringRef ArchFS
= Features
.second
;
483 MCSubtargetInfo
*X
= createHexagonMCSubtargetInfoImpl(
484 TT
, CPUName
, /*TuneCPU*/ CPUName
, ArchFS
);
485 if (X
!= nullptr && (CPUName
== "hexagonv67t"))
486 addArchSubtarget(X
, ArchFS
);
488 if (CPU
.equals("help"))
491 if (!isCPUValid(CPUName
.str())) {
492 errs() << "error: invalid CPU \"" << CPUName
.str().c_str()
497 if (HexagonDisableDuplex
) {
498 llvm::FeatureBitset Features
= X
->getFeatureBits();
499 X
->setFeatureBits(Features
.reset(Hexagon::FeatureDuplex
));
502 X
->setFeatureBits(completeHVXFeatures(X
->getFeatureBits()));
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");
510 llvm::FeatureBitset Features
= X
->getFeatureBits();
511 X
->setFeatureBits(Features
.set(Hexagon::ExtensionZReg
));
517 void Hexagon_MC::addArchSubtarget(MCSubtargetInfo
const *STI
,
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
);
530 unsigned 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
},
543 auto F
= ElfFlags
.find(STI
.getCPU());
544 assert(F
!= ElfFlags
.end() && "Unrecognized Architecture");
548 llvm::ArrayRef
<MCPhysReg
> Hexagon_MC::GetVectRegRev() {
549 return makeArrayRef(VectRegRev
);
553 class HexagonMCInstrAnalysis
: public MCInstrAnalysis
{
555 HexagonMCInstrAnalysis(MCInstrInfo
const *Info
) : MCInstrAnalysis(Info
) {}
557 bool isUnconditionalBranch(MCInst
const &Inst
) const override
{
558 //assert(!HexagonMCInstrInfo::isBundle(Inst));
559 return MCInstrAnalysis::isUnconditionalBranch(Inst
);
562 bool isConditionalBranch(MCInst
const &Inst
) const override
{
563 //assert(!HexagonMCInstrInfo::isBundle(Inst));
564 return MCInstrAnalysis::isConditionalBranch(Inst
);
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
)))
573 //assert(!HexagonMCInstrInfo::isBundle(Inst));
574 if(!HexagonMCInstrInfo::isExtendable(*Info
, Inst
))
576 auto const &Extended(HexagonMCInstrInfo::getExtendableOperand(*Info
, Inst
));
577 assert(Extended
.isExpr());
579 if(!Extended
.getExpr()->evaluateAsAbsolute(Value
))
587 static MCInstrAnalysis
*createHexagonMCInstrAnalysis(const MCInstrInfo
*Info
) {
588 return new HexagonMCInstrAnalysis(Info
);
591 // Force static initialization.
592 extern "C" LLVM_EXTERNAL_VISIBILITY
void LLVMInitializeHexagonTargetMC() {
593 // Register the MC asm info.
594 RegisterMCAsmInfoFn
X(getTheHexagonTarget(), createHexagonMCAsmInfo
);
596 // Register the MC instruction info.
597 TargetRegistry::RegisterMCInstrInfo(getTheHexagonTarget(),
598 createHexagonMCInstrInfo
);
600 // Register the MC register info.
601 TargetRegistry::RegisterMCRegInfo(getTheHexagonTarget(),
602 createHexagonMCRegisterInfo
);
604 // Register the MC subtarget info.
605 TargetRegistry::RegisterMCSubtargetInfo(getTheHexagonTarget(),
606 Hexagon_MC::createHexagonMCSubtargetInfo
);
608 // Register the MC Code Emitter
609 TargetRegistry::RegisterMCCodeEmitter(getTheHexagonTarget(),
610 createHexagonMCCodeEmitter
);
612 // Register the asm backend
613 TargetRegistry::RegisterMCAsmBackend(getTheHexagonTarget(),
614 createHexagonAsmBackend
);
617 // Register the MC instruction analyzer.
618 TargetRegistry::RegisterMCInstrAnalysis(getTheHexagonTarget(),
619 createHexagonMCInstrAnalysis
);
621 // Register the obj streamer
622 TargetRegistry::RegisterELFStreamer(getTheHexagonTarget(),
625 // Register the obj target streamer
626 TargetRegistry::RegisterObjectTargetStreamer(getTheHexagonTarget(),
627 createHexagonObjectTargetStreamer
);
629 // Register the asm streamer
630 TargetRegistry::RegisterAsmTargetStreamer(getTheHexagonTarget(),
631 createMCAsmTargetStreamer
);
633 // Register the MC Inst Printer
634 TargetRegistry::RegisterMCInstPrinter(getTheHexagonTarget(),
635 createHexagonMCInstPrinter
);