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 cl::opt<bool> MV68("mv68", cl::Hidden, cl::desc("Build for Hexagon V68"), 82 cl::init(false)); 83 84 cl::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 100 static cl::opt<bool> 101 DisableHVX("mno-hvx", cl::Hidden, 102 cl::desc("Disable Hexagon Vector eXtensions")); 103 104 105 static StringRef DefaultArch = "hexagonv60"; 106 107 static 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 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."); 138 return CPU; 139 } 140 if (ArchV.empty()) { 141 if (CPU.empty()) 142 CPU = DefaultArch; 143 return CPU; 144 } 145 return ArchV; 146 } 147 148 unsigned llvm::HexagonGetLastSlot() { return HexagonItinerariesV5FU::SLOT3; } 149 150 unsigned 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 192 namespace llvm { 193 namespace HexagonFUnits { 194 bool isSlot0Only(unsigned units) { 195 return HexagonItinerariesV62FU::SLOT0 == units; 196 } 197 } // namespace HexagonFUnits 198 } // namespace llvm 199 200 namespace { 201 202 class HexagonTargetAsmStreamer : public HexagonTargetStreamer { 203 public: 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 247 class HexagonTargetELFStreamer : public HexagonTargetStreamer { 248 public: 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 280 llvm::MCInstrInfo *llvm::createHexagonMCInstrInfo() { 281 MCInstrInfo *X = new MCInstrInfo(); 282 InitHexagonMCInstrInfo(X); 283 return X; 284 } 285 286 static MCRegisterInfo *createHexagonMCRegisterInfo(const Triple &TT) { 287 MCRegisterInfo *X = new MCRegisterInfo(); 288 InitHexagonMCRegisterInfo(X, Hexagon::R31); 289 return X; 290 } 291 292 static 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 305 static 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 317 static MCTargetStreamer * 318 createMCAsmTargetStreamer(MCStreamer &S, formatted_raw_ostream &OS, 319 MCInstPrinter *IP, bool IsVerboseAsm) { 320 return new HexagonTargetAsmStreamer(S, OS, IsVerboseAsm, *IP); 321 } 322 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, 327 bool RelaxAll) { 328 return createHexagonELFStreamer(T, Context, std::move(MAB), std::move(OW), 329 std::move(Emitter)); 330 } 331 332 static MCTargetStreamer * 333 createHexagonObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) { 334 return new HexagonTargetELFStreamer(S, STI); 335 } 336 337 static void LLVM_ATTRIBUTE_UNUSED clearFeature(MCSubtargetInfo* STI, uint64_t F) { 338 if (STI->getFeatureBits()[F]) 339 STI->ToggleFeature(F); 340 } 341 342 static bool LLVM_ATTRIBUTE_UNUSED checkFeature(MCSubtargetInfo* STI, uint64_t F) { 343 return STI->getFeatureBits()[F]; 344 } 345 346 namespace { 347 std::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 393 static bool isCPUValid(const std::string &CPU) { 394 return Hexagon::CpuTable.find(CPU) != Hexagon::CpuTable.cend(); 395 } 396 397 namespace { 398 std::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 } 405 std::mutex ArchSubtargetMutex; 406 std::unordered_map<std::string, std::unique_ptr<MCSubtargetInfo const>> 407 ArchSubtarget; 408 } // namespace 409 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()) 415 return nullptr; 416 return Existing->second.get(); 417 } 418 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, 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 476 MCSubtargetInfo *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 517 void 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 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}, 541 }; 542 543 auto F = ElfFlags.find(STI.getCPU()); 544 assert(F != ElfFlags.end() && "Unrecognized Architecture"); 545 return F->second; 546 } 547 548 llvm::ArrayRef<MCPhysReg> Hexagon_MC::GetVectRegRev() { 549 return makeArrayRef(VectRegRev); 550 } 551 552 namespace { 553 class HexagonMCInstrAnalysis : public MCInstrAnalysis { 554 public: 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 587 static MCInstrAnalysis *createHexagonMCInstrAnalysis(const MCInstrInfo *Info) { 588 return new HexagonMCInstrAnalysis(Info); 589 } 590 591 // Force static initialization. 592 extern "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