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 45 using 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 56 cl::opt<bool> llvm::HexagonDisableCompound 57 ("mno-compound", 58 cl::desc("Disable looking for compound instructions for Hexagon")); 59 60 cl::opt<bool> llvm::HexagonDisableDuplex 61 ("mno-pairing", 62 cl::desc("Disable looking for duplex instructions for Hexagon")); 63 64 namespace { // These flags are to be deprecated 65 cl::opt<bool> MV5("mv5", cl::Hidden, cl::desc("Build for Hexagon V5"), 66 cl::init(false)); 67 cl::opt<bool> MV55("mv55", cl::Hidden, cl::desc("Build for Hexagon V55"), 68 cl::init(false)); 69 cl::opt<bool> MV60("mv60", cl::Hidden, cl::desc("Build for Hexagon V60"), 70 cl::init(false)); 71 cl::opt<bool> MV62("mv62", cl::Hidden, cl::desc("Build for Hexagon V62"), 72 cl::init(false)); 73 cl::opt<bool> MV65("mv65", cl::Hidden, cl::desc("Build for Hexagon V65"), 74 cl::init(false)); 75 cl::opt<bool> MV66("mv66", cl::Hidden, cl::desc("Build for Hexagon V66"), 76 cl::init(false)); 77 cl::opt<bool> MV67("mv67", cl::Hidden, cl::desc("Build for Hexagon V67"), 78 cl::init(false)); 79 cl::opt<bool> MV67T("mv67t", cl::Hidden, cl::desc("Build for Hexagon V67T"), 80 cl::init(false)); 81 82 cl::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 97 static cl::opt<bool> 98 DisableHVX("mno-hvx", cl::Hidden, 99 cl::desc("Disable Hexagon Vector eXtensions")); 100 101 102 static StringRef DefaultArch = "hexagonv60"; 103 104 static 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 124 StringRef 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 143 unsigned llvm::HexagonGetLastSlot() { return HexagonItinerariesV5FU::SLOT3; } 144 145 unsigned 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 187 namespace llvm { 188 namespace HexagonFUnits { 189 bool isSlot0Only(unsigned units) { 190 return HexagonItinerariesV62FU::SLOT0 == units; 191 } 192 } // namespace HexagonFUnits 193 } // namespace llvm 194 195 namespace { 196 197 class HexagonTargetAsmStreamer : public HexagonTargetStreamer { 198 public: 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 242 class HexagonTargetELFStreamer : public HexagonTargetStreamer { 243 public: 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 275 llvm::MCInstrInfo *llvm::createHexagonMCInstrInfo() { 276 MCInstrInfo *X = new MCInstrInfo(); 277 InitHexagonMCInstrInfo(X); 278 return X; 279 } 280 281 static MCRegisterInfo *createHexagonMCRegisterInfo(const Triple &TT) { 282 MCRegisterInfo *X = new MCRegisterInfo(); 283 InitHexagonMCRegisterInfo(X, Hexagon::R31); 284 return X; 285 } 286 287 static 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 300 static 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 312 static MCTargetStreamer * 313 createMCAsmTargetStreamer(MCStreamer &S, formatted_raw_ostream &OS, 314 MCInstPrinter *IP, bool IsVerboseAsm) { 315 return new HexagonTargetAsmStreamer(S, OS, IsVerboseAsm, *IP); 316 } 317 318 static 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 327 static MCTargetStreamer * 328 createHexagonObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) { 329 return new HexagonTargetELFStreamer(S, STI); 330 } 331 332 static void LLVM_ATTRIBUTE_UNUSED clearFeature(MCSubtargetInfo* STI, uint64_t F) { 333 if (STI->getFeatureBits()[F]) 334 STI->ToggleFeature(F); 335 } 336 337 static bool LLVM_ATTRIBUTE_UNUSED checkFeature(MCSubtargetInfo* STI, uint64_t F) { 338 return STI->getFeatureBits()[F]; 339 } 340 341 namespace { 342 std::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 384 static bool isCPUValid(const std::string &CPU) { 385 return Hexagon::CpuTable.find(CPU) != Hexagon::CpuTable.cend(); 386 } 387 388 namespace { 389 std::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 } 396 std::mutex ArchSubtargetMutex; 397 std::unordered_map<std::string, std::unique_ptr<MCSubtargetInfo const>> 398 ArchSubtarget; 399 } // namespace 400 401 MCSubtargetInfo const * 402 Hexagon_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 410 FeatureBitset 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 464 MCSubtargetInfo *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 504 void 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 517 unsigned 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 534 llvm::ArrayRef<MCPhysReg> Hexagon_MC::GetVectRegRev() { 535 return makeArrayRef(VectRegRev); 536 } 537 538 namespace { 539 class HexagonMCInstrAnalysis : public MCInstrAnalysis { 540 public: 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 573 static MCInstrAnalysis *createHexagonMCInstrAnalysis(const MCInstrInfo *Info) { 574 return new HexagonMCInstrAnalysis(Info); 575 } 576 577 // Force static initialization. 578 extern "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