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