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