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