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