10b57cec5SDimitry Andric //===-- HexagonMCTargetDesc.cpp - Hexagon Target Descriptions -------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file provides Hexagon specific target descriptions. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 13349cc55cSDimitry Andric #include "MCTargetDesc/HexagonMCTargetDesc.h" 1481ad6265SDimitry Andric #include "HexagonDepArch.h" 150b57cec5SDimitry Andric #include "HexagonTargetStreamer.h" 160b57cec5SDimitry Andric #include "MCTargetDesc/HexagonInstPrinter.h" 170b57cec5SDimitry Andric #include "MCTargetDesc/HexagonMCAsmInfo.h" 180b57cec5SDimitry Andric #include "MCTargetDesc/HexagonMCELFStreamer.h" 190b57cec5SDimitry Andric #include "MCTargetDesc/HexagonMCInstrInfo.h" 200b57cec5SDimitry Andric #include "TargetInfo/HexagonTargetInfo.h" 210b57cec5SDimitry Andric #include "llvm/ADT/StringExtras.h" 220b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 230b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELF.h" 240b57cec5SDimitry Andric #include "llvm/MC/MCAsmBackend.h" 2581ad6265SDimitry Andric #include "llvm/MC/MCAssembler.h" 260b57cec5SDimitry Andric #include "llvm/MC/MCCodeEmitter.h" 270b57cec5SDimitry Andric #include "llvm/MC/MCContext.h" 280b57cec5SDimitry Andric #include "llvm/MC/MCDwarf.h" 290b57cec5SDimitry Andric #include "llvm/MC/MCELFStreamer.h" 300b57cec5SDimitry Andric #include "llvm/MC/MCInstrAnalysis.h" 310b57cec5SDimitry Andric #include "llvm/MC/MCInstrInfo.h" 320b57cec5SDimitry Andric #include "llvm/MC/MCObjectWriter.h" 330b57cec5SDimitry Andric #include "llvm/MC/MCRegisterInfo.h" 340b57cec5SDimitry Andric #include "llvm/MC/MCStreamer.h" 350b57cec5SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h" 36349cc55cSDimitry Andric #include "llvm/MC/TargetRegistry.h" 370b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 38*0fca6ea1SDimitry Andric #include "llvm/Support/HexagonAttributes.h" 390b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 400b57cec5SDimitry Andric #include <cassert> 410b57cec5SDimitry Andric #include <cstdint> 425ffd83dbSDimitry Andric #include <mutex> 430b57cec5SDimitry Andric #include <new> 440b57cec5SDimitry Andric #include <string> 455ffd83dbSDimitry Andric #include <unordered_map> 460b57cec5SDimitry Andric 470b57cec5SDimitry Andric using namespace llvm; 480b57cec5SDimitry Andric 490b57cec5SDimitry Andric #define GET_INSTRINFO_MC_DESC 50753f127fSDimitry Andric #define ENABLE_INSTR_PREDICATE_VERIFIER 510b57cec5SDimitry Andric #include "HexagonGenInstrInfo.inc" 520b57cec5SDimitry Andric 530b57cec5SDimitry Andric #define GET_SUBTARGETINFO_MC_DESC 540b57cec5SDimitry Andric #include "HexagonGenSubtargetInfo.inc" 550b57cec5SDimitry Andric 560b57cec5SDimitry Andric #define GET_REGINFO_MC_DESC 570b57cec5SDimitry Andric #include "HexagonGenRegisterInfo.inc" 580b57cec5SDimitry Andric 590b57cec5SDimitry Andric cl::opt<bool> llvm::HexagonDisableCompound 600b57cec5SDimitry Andric ("mno-compound", 610b57cec5SDimitry Andric cl::desc("Disable looking for compound instructions for Hexagon")); 620b57cec5SDimitry Andric 630b57cec5SDimitry Andric cl::opt<bool> llvm::HexagonDisableDuplex 640b57cec5SDimitry Andric ("mno-pairing", 650b57cec5SDimitry Andric cl::desc("Disable looking for duplex instructions for Hexagon")); 660b57cec5SDimitry Andric 670b57cec5SDimitry Andric namespace { // These flags are to be deprecated 680b57cec5SDimitry Andric cl::opt<bool> MV5("mv5", cl::Hidden, cl::desc("Build for Hexagon V5"), 690b57cec5SDimitry Andric cl::init(false)); 700b57cec5SDimitry Andric cl::opt<bool> MV55("mv55", cl::Hidden, cl::desc("Build for Hexagon V55"), 710b57cec5SDimitry Andric cl::init(false)); 720b57cec5SDimitry Andric cl::opt<bool> MV60("mv60", cl::Hidden, cl::desc("Build for Hexagon V60"), 730b57cec5SDimitry Andric cl::init(false)); 740b57cec5SDimitry Andric cl::opt<bool> MV62("mv62", cl::Hidden, cl::desc("Build for Hexagon V62"), 750b57cec5SDimitry Andric cl::init(false)); 760b57cec5SDimitry Andric cl::opt<bool> MV65("mv65", cl::Hidden, cl::desc("Build for Hexagon V65"), 770b57cec5SDimitry Andric cl::init(false)); 780b57cec5SDimitry Andric cl::opt<bool> MV66("mv66", cl::Hidden, cl::desc("Build for Hexagon V66"), 790b57cec5SDimitry Andric cl::init(false)); 805ffd83dbSDimitry Andric cl::opt<bool> MV67("mv67", cl::Hidden, cl::desc("Build for Hexagon V67"), 815ffd83dbSDimitry Andric cl::init(false)); 825ffd83dbSDimitry Andric cl::opt<bool> MV67T("mv67t", cl::Hidden, cl::desc("Build for Hexagon V67T"), 835ffd83dbSDimitry Andric cl::init(false)); 84fe6060f1SDimitry Andric cl::opt<bool> MV68("mv68", cl::Hidden, cl::desc("Build for Hexagon V68"), 85fe6060f1SDimitry Andric cl::init(false)); 860eae32dcSDimitry Andric cl::opt<bool> MV69("mv69", cl::Hidden, cl::desc("Build for Hexagon V69"), 870eae32dcSDimitry Andric cl::init(false)); 88bdd1243dSDimitry Andric cl::opt<bool> MV71("mv71", cl::Hidden, cl::desc("Build for Hexagon V71"), 89bdd1243dSDimitry Andric cl::init(false)); 90bdd1243dSDimitry Andric cl::opt<bool> MV71T("mv71t", cl::Hidden, cl::desc("Build for Hexagon V71T"), 91bdd1243dSDimitry Andric cl::init(false)); 92bdd1243dSDimitry Andric cl::opt<bool> MV73("mv73", cl::Hidden, cl::desc("Build for Hexagon V73"), 93bdd1243dSDimitry Andric cl::init(false)); 94bdd1243dSDimitry Andric } // namespace 950b57cec5SDimitry Andric 96bdd1243dSDimitry Andric cl::opt<Hexagon::ArchEnum> EnableHVX( 97bdd1243dSDimitry Andric "mhvx", cl::desc("Enable Hexagon Vector eXtensions"), 98bdd1243dSDimitry Andric cl::values(clEnumValN(Hexagon::ArchEnum::V60, "v60", "Build for HVX v60"), 990b57cec5SDimitry Andric clEnumValN(Hexagon::ArchEnum::V62, "v62", "Build for HVX v62"), 1000b57cec5SDimitry Andric clEnumValN(Hexagon::ArchEnum::V65, "v65", "Build for HVX v65"), 1010b57cec5SDimitry Andric clEnumValN(Hexagon::ArchEnum::V66, "v66", "Build for HVX v66"), 1025ffd83dbSDimitry Andric clEnumValN(Hexagon::ArchEnum::V67, "v67", "Build for HVX v67"), 103fe6060f1SDimitry Andric clEnumValN(Hexagon::ArchEnum::V68, "v68", "Build for HVX v68"), 1040eae32dcSDimitry Andric clEnumValN(Hexagon::ArchEnum::V69, "v69", "Build for HVX v69"), 105bdd1243dSDimitry Andric clEnumValN(Hexagon::ArchEnum::V71, "v71", "Build for HVX v71"), 106bdd1243dSDimitry Andric clEnumValN(Hexagon::ArchEnum::V73, "v73", "Build for HVX v73"), 1070b57cec5SDimitry Andric // Sentinel for no value specified. 1080b57cec5SDimitry Andric clEnumValN(Hexagon::ArchEnum::Generic, "", "")), 1090b57cec5SDimitry Andric // Sentinel for flag not present. 1100b57cec5SDimitry Andric cl::init(Hexagon::ArchEnum::NoArch), cl::ValueOptional); 1110b57cec5SDimitry Andric 1120b57cec5SDimitry Andric static cl::opt<bool> 1130b57cec5SDimitry Andric DisableHVX("mno-hvx", cl::Hidden, 1140b57cec5SDimitry Andric cl::desc("Disable Hexagon Vector eXtensions")); 1150b57cec5SDimitry Andric 1160eae32dcSDimitry Andric static cl::opt<bool> 1170eae32dcSDimitry Andric EnableHvxIeeeFp("mhvx-ieee-fp", cl::Hidden, 1180eae32dcSDimitry Andric cl::desc("Enable HVX IEEE floating point extensions")); 1190eae32dcSDimitry Andric static cl::opt<bool> EnableHexagonCabac 1200eae32dcSDimitry Andric ("mcabac", cl::desc("tbd"), cl::init(false)); 1210b57cec5SDimitry Andric 1220b57cec5SDimitry Andric static StringRef DefaultArch = "hexagonv60"; 1230b57cec5SDimitry Andric 1240b57cec5SDimitry Andric static StringRef HexagonGetArchVariant() { 1250b57cec5SDimitry Andric if (MV5) 1260b57cec5SDimitry Andric return "hexagonv5"; 1270b57cec5SDimitry Andric if (MV55) 1280b57cec5SDimitry Andric return "hexagonv55"; 1290b57cec5SDimitry Andric if (MV60) 1300b57cec5SDimitry Andric return "hexagonv60"; 1310b57cec5SDimitry Andric if (MV62) 1320b57cec5SDimitry Andric return "hexagonv62"; 1330b57cec5SDimitry Andric if (MV65) 1340b57cec5SDimitry Andric return "hexagonv65"; 1350b57cec5SDimitry Andric if (MV66) 1360b57cec5SDimitry Andric return "hexagonv66"; 1375ffd83dbSDimitry Andric if (MV67) 1385ffd83dbSDimitry Andric return "hexagonv67"; 1395ffd83dbSDimitry Andric if (MV67T) 1405ffd83dbSDimitry Andric return "hexagonv67t"; 141fe6060f1SDimitry Andric if (MV68) 142fe6060f1SDimitry Andric return "hexagonv68"; 1430eae32dcSDimitry Andric if (MV69) 1440eae32dcSDimitry Andric return "hexagonv69"; 145bdd1243dSDimitry Andric if (MV71) 146bdd1243dSDimitry Andric return "hexagonv71"; 147bdd1243dSDimitry Andric if (MV71T) 148bdd1243dSDimitry Andric return "hexagonv71t"; 149bdd1243dSDimitry Andric if (MV73) 150bdd1243dSDimitry Andric return "hexagonv73"; 1510b57cec5SDimitry Andric return ""; 1520b57cec5SDimitry Andric } 1530b57cec5SDimitry Andric 1540b57cec5SDimitry Andric StringRef Hexagon_MC::selectHexagonCPU(StringRef CPU) { 1550b57cec5SDimitry Andric StringRef ArchV = HexagonGetArchVariant(); 1560b57cec5SDimitry Andric if (!ArchV.empty() && !CPU.empty()) { 1575ffd83dbSDimitry Andric // Tiny cores have a "t" suffix that is discarded when creating a secondary 1585ffd83dbSDimitry Andric // non-tiny subtarget. See: addArchSubtarget 1595ffd83dbSDimitry Andric std::pair<StringRef, StringRef> ArchP = ArchV.split('t'); 1605ffd83dbSDimitry Andric std::pair<StringRef, StringRef> CPUP = CPU.split('t'); 161*0fca6ea1SDimitry Andric if (ArchP.first != CPUP.first) 1620b57cec5SDimitry Andric report_fatal_error("conflicting architectures specified."); 1630b57cec5SDimitry Andric return CPU; 1640b57cec5SDimitry Andric } 1650b57cec5SDimitry Andric if (ArchV.empty()) { 1660b57cec5SDimitry Andric if (CPU.empty()) 1670b57cec5SDimitry Andric CPU = DefaultArch; 1680b57cec5SDimitry Andric return CPU; 1690b57cec5SDimitry Andric } 1700b57cec5SDimitry Andric return ArchV; 1710b57cec5SDimitry Andric } 1720b57cec5SDimitry Andric 1730b57cec5SDimitry Andric unsigned llvm::HexagonGetLastSlot() { return HexagonItinerariesV5FU::SLOT3; } 1740b57cec5SDimitry Andric 1755ffd83dbSDimitry Andric unsigned llvm::HexagonConvertUnits(unsigned ItinUnits, unsigned *Lanes) { 1765ffd83dbSDimitry Andric enum { 1775ffd83dbSDimitry Andric CVI_NONE = 0, 1785ffd83dbSDimitry Andric CVI_XLANE = 1 << 0, 1795ffd83dbSDimitry Andric CVI_SHIFT = 1 << 1, 1805ffd83dbSDimitry Andric CVI_MPY0 = 1 << 2, 1815ffd83dbSDimitry Andric CVI_MPY1 = 1 << 3, 1825ffd83dbSDimitry Andric CVI_ZW = 1 << 4 1835ffd83dbSDimitry Andric }; 1845ffd83dbSDimitry Andric 1855ffd83dbSDimitry Andric if (ItinUnits == HexagonItinerariesV62FU::CVI_ALL || 1865ffd83dbSDimitry Andric ItinUnits == HexagonItinerariesV62FU::CVI_ALL_NOMEM) 1875ffd83dbSDimitry Andric return (*Lanes = 4, CVI_XLANE); 1885ffd83dbSDimitry Andric else if (ItinUnits & HexagonItinerariesV62FU::CVI_MPY01 && 1895ffd83dbSDimitry Andric ItinUnits & HexagonItinerariesV62FU::CVI_XLSHF) 1905ffd83dbSDimitry Andric return (*Lanes = 2, CVI_XLANE | CVI_MPY0); 1915ffd83dbSDimitry Andric else if (ItinUnits & HexagonItinerariesV62FU::CVI_MPY01) 1925ffd83dbSDimitry Andric return (*Lanes = 2, CVI_MPY0); 1935ffd83dbSDimitry Andric else if (ItinUnits & HexagonItinerariesV62FU::CVI_XLSHF) 1945ffd83dbSDimitry Andric return (*Lanes = 2, CVI_XLANE); 1955ffd83dbSDimitry Andric else if (ItinUnits & HexagonItinerariesV62FU::CVI_XLANE && 1965ffd83dbSDimitry Andric ItinUnits & HexagonItinerariesV62FU::CVI_SHIFT && 1975ffd83dbSDimitry Andric ItinUnits & HexagonItinerariesV62FU::CVI_MPY0 && 1985ffd83dbSDimitry Andric ItinUnits & HexagonItinerariesV62FU::CVI_MPY1) 1995ffd83dbSDimitry Andric return (*Lanes = 1, CVI_XLANE | CVI_SHIFT | CVI_MPY0 | CVI_MPY1); 2005ffd83dbSDimitry Andric else if (ItinUnits & HexagonItinerariesV62FU::CVI_XLANE && 2015ffd83dbSDimitry Andric ItinUnits & HexagonItinerariesV62FU::CVI_SHIFT) 2025ffd83dbSDimitry Andric return (*Lanes = 1, CVI_XLANE | CVI_SHIFT); 2035ffd83dbSDimitry Andric else if (ItinUnits & HexagonItinerariesV62FU::CVI_MPY0 && 2045ffd83dbSDimitry Andric ItinUnits & HexagonItinerariesV62FU::CVI_MPY1) 2055ffd83dbSDimitry Andric return (*Lanes = 1, CVI_MPY0 | CVI_MPY1); 2065ffd83dbSDimitry Andric else if (ItinUnits == HexagonItinerariesV62FU::CVI_ZW) 2075ffd83dbSDimitry Andric return (*Lanes = 1, CVI_ZW); 2085ffd83dbSDimitry Andric else if (ItinUnits == HexagonItinerariesV62FU::CVI_XLANE) 2095ffd83dbSDimitry Andric return (*Lanes = 1, CVI_XLANE); 2105ffd83dbSDimitry Andric else if (ItinUnits == HexagonItinerariesV62FU::CVI_SHIFT) 2115ffd83dbSDimitry Andric return (*Lanes = 1, CVI_SHIFT); 2125ffd83dbSDimitry Andric 2135ffd83dbSDimitry Andric return (*Lanes = 0, CVI_NONE); 2145ffd83dbSDimitry Andric } 2155ffd83dbSDimitry Andric 2165ffd83dbSDimitry Andric 2175ffd83dbSDimitry Andric namespace llvm { 2185ffd83dbSDimitry Andric namespace HexagonFUnits { 2195ffd83dbSDimitry Andric bool isSlot0Only(unsigned units) { 2205ffd83dbSDimitry Andric return HexagonItinerariesV62FU::SLOT0 == units; 2215ffd83dbSDimitry Andric } 2225ffd83dbSDimitry Andric } // namespace HexagonFUnits 2235ffd83dbSDimitry Andric } // namespace llvm 2245ffd83dbSDimitry Andric 2250b57cec5SDimitry Andric namespace { 2260b57cec5SDimitry Andric 2270b57cec5SDimitry Andric class HexagonTargetAsmStreamer : public HexagonTargetStreamer { 228*0fca6ea1SDimitry Andric formatted_raw_ostream &OS; 229*0fca6ea1SDimitry Andric 2300b57cec5SDimitry Andric public: 231*0fca6ea1SDimitry Andric HexagonTargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS, 2320b57cec5SDimitry Andric MCInstPrinter &IP) 233*0fca6ea1SDimitry Andric : HexagonTargetStreamer(S), OS(OS) {} 2340b57cec5SDimitry Andric 235480093f4SDimitry Andric void prettyPrintAsm(MCInstPrinter &InstPrinter, uint64_t Address, 236480093f4SDimitry Andric const MCInst &Inst, const MCSubtargetInfo &STI, 237480093f4SDimitry Andric raw_ostream &OS) override { 2380b57cec5SDimitry Andric assert(HexagonMCInstrInfo::isBundle(Inst)); 2390b57cec5SDimitry Andric assert(HexagonMCInstrInfo::bundleSize(Inst) <= HEXAGON_PACKET_SIZE); 2400b57cec5SDimitry Andric std::string Buffer; 2410b57cec5SDimitry Andric { 2420b57cec5SDimitry Andric raw_string_ostream TempStream(Buffer); 243480093f4SDimitry Andric InstPrinter.printInst(&Inst, Address, "", STI, TempStream); 2440b57cec5SDimitry Andric } 2450b57cec5SDimitry Andric StringRef Contents(Buffer); 2460b57cec5SDimitry Andric auto PacketBundle = Contents.rsplit('\n'); 2470b57cec5SDimitry Andric auto HeadTail = PacketBundle.first.split('\n'); 2480b57cec5SDimitry Andric StringRef Separator = "\n"; 2490b57cec5SDimitry Andric StringRef Indent = "\t"; 2500b57cec5SDimitry Andric OS << "\t{\n"; 2510b57cec5SDimitry Andric while (!HeadTail.first.empty()) { 2520b57cec5SDimitry Andric StringRef InstTxt; 2530b57cec5SDimitry Andric auto Duplex = HeadTail.first.split('\v'); 2540b57cec5SDimitry Andric if (!Duplex.second.empty()) { 2550b57cec5SDimitry Andric OS << Indent << Duplex.first << Separator; 2560b57cec5SDimitry Andric InstTxt = Duplex.second; 2575f757f3fSDimitry Andric } else if (!HeadTail.first.trim().starts_with("immext")) { 2580b57cec5SDimitry Andric InstTxt = Duplex.first; 2590b57cec5SDimitry Andric } 2600b57cec5SDimitry Andric if (!InstTxt.empty()) 2610b57cec5SDimitry Andric OS << Indent << InstTxt << Separator; 2620b57cec5SDimitry Andric HeadTail = HeadTail.second.split('\n'); 2630b57cec5SDimitry Andric } 2640b57cec5SDimitry Andric 2650b57cec5SDimitry Andric if (HexagonMCInstrInfo::isMemReorderDisabled(Inst)) 2660b57cec5SDimitry Andric OS << "\n\t} :mem_noshuf" << PacketBundle.second; 2670b57cec5SDimitry Andric else 2680b57cec5SDimitry Andric OS << "\t}" << PacketBundle.second; 2690b57cec5SDimitry Andric } 270*0fca6ea1SDimitry Andric 271*0fca6ea1SDimitry Andric void finish() override { finishAttributeSection(); } 272*0fca6ea1SDimitry Andric 273*0fca6ea1SDimitry Andric void finishAttributeSection() override {} 274*0fca6ea1SDimitry Andric 275*0fca6ea1SDimitry Andric void emitAttribute(unsigned Attribute, unsigned Value) override { 276*0fca6ea1SDimitry Andric OS << "\t.attribute\t" << Attribute << ", " << Twine(Value); 277*0fca6ea1SDimitry Andric if (getStreamer().isVerboseAsm()) { 278*0fca6ea1SDimitry Andric StringRef Name = ELFAttrs::attrTypeAsString( 279*0fca6ea1SDimitry Andric Attribute, HexagonAttrs::getHexagonAttributeTags()); 280*0fca6ea1SDimitry Andric if (!Name.empty()) 281*0fca6ea1SDimitry Andric OS << "\t// " << Name; 282*0fca6ea1SDimitry Andric } 283*0fca6ea1SDimitry Andric OS << "\n"; 284*0fca6ea1SDimitry Andric } 2850b57cec5SDimitry Andric }; 2860b57cec5SDimitry Andric 2870b57cec5SDimitry Andric class HexagonTargetELFStreamer : public HexagonTargetStreamer { 2880b57cec5SDimitry Andric public: 2890b57cec5SDimitry Andric MCELFStreamer &getStreamer() { 2900b57cec5SDimitry Andric return static_cast<MCELFStreamer &>(Streamer); 2910b57cec5SDimitry Andric } 2920b57cec5SDimitry Andric HexagonTargetELFStreamer(MCStreamer &S, MCSubtargetInfo const &STI) 2930b57cec5SDimitry Andric : HexagonTargetStreamer(S) { 294*0fca6ea1SDimitry Andric getStreamer().getWriter().setELFHeaderEFlags(Hexagon_MC::GetELFFlags(STI)); 2950b57cec5SDimitry Andric } 2960b57cec5SDimitry Andric 2975ffd83dbSDimitry Andric void emitCommonSymbolSorted(MCSymbol *Symbol, uint64_t Size, 2980b57cec5SDimitry Andric unsigned ByteAlignment, 2990b57cec5SDimitry Andric unsigned AccessSize) override { 3000b57cec5SDimitry Andric HexagonMCELFStreamer &HexagonELFStreamer = 3010b57cec5SDimitry Andric static_cast<HexagonMCELFStreamer &>(getStreamer()); 302bdd1243dSDimitry Andric HexagonELFStreamer.HexagonMCEmitCommonSymbol( 303bdd1243dSDimitry Andric Symbol, Size, Align(ByteAlignment), AccessSize); 3040b57cec5SDimitry Andric } 3050b57cec5SDimitry Andric 3065ffd83dbSDimitry Andric void emitLocalCommonSymbolSorted(MCSymbol *Symbol, uint64_t Size, 3070b57cec5SDimitry Andric unsigned ByteAlignment, 3080b57cec5SDimitry Andric unsigned AccessSize) override { 3090b57cec5SDimitry Andric HexagonMCELFStreamer &HexagonELFStreamer = 3100b57cec5SDimitry Andric static_cast<HexagonMCELFStreamer &>(getStreamer()); 3110b57cec5SDimitry Andric HexagonELFStreamer.HexagonMCEmitLocalCommonSymbol( 312bdd1243dSDimitry Andric Symbol, Size, Align(ByteAlignment), AccessSize); 3130b57cec5SDimitry Andric } 314*0fca6ea1SDimitry Andric 315*0fca6ea1SDimitry Andric void finish() override { finishAttributeSection(); } 316*0fca6ea1SDimitry Andric 317*0fca6ea1SDimitry Andric void reset() override { AttributeSection = nullptr; } 318*0fca6ea1SDimitry Andric 319*0fca6ea1SDimitry Andric private: 320*0fca6ea1SDimitry Andric MCSection *AttributeSection = nullptr; 321*0fca6ea1SDimitry Andric 322*0fca6ea1SDimitry Andric void finishAttributeSection() override { 323*0fca6ea1SDimitry Andric MCELFStreamer &S = getStreamer(); 324*0fca6ea1SDimitry Andric if (S.Contents.empty()) 325*0fca6ea1SDimitry Andric return; 326*0fca6ea1SDimitry Andric 327*0fca6ea1SDimitry Andric S.emitAttributesSection("hexagon", ".hexagon.attributes", 328*0fca6ea1SDimitry Andric ELF::SHT_HEXAGON_ATTRIBUTES, AttributeSection); 329*0fca6ea1SDimitry Andric } 330*0fca6ea1SDimitry Andric 331*0fca6ea1SDimitry Andric void emitAttribute(uint32_t Attribute, uint32_t Value) override { 332*0fca6ea1SDimitry Andric getStreamer().setAttributeItem(Attribute, Value, 333*0fca6ea1SDimitry Andric /*OverwriteExisting=*/true); 334*0fca6ea1SDimitry Andric } 3350b57cec5SDimitry Andric }; 3360b57cec5SDimitry Andric 3370b57cec5SDimitry Andric } // end anonymous namespace 3380b57cec5SDimitry Andric 3390b57cec5SDimitry Andric llvm::MCInstrInfo *llvm::createHexagonMCInstrInfo() { 3400b57cec5SDimitry Andric MCInstrInfo *X = new MCInstrInfo(); 3410b57cec5SDimitry Andric InitHexagonMCInstrInfo(X); 3420b57cec5SDimitry Andric return X; 3430b57cec5SDimitry Andric } 3440b57cec5SDimitry Andric 3450b57cec5SDimitry Andric static MCRegisterInfo *createHexagonMCRegisterInfo(const Triple &TT) { 3460b57cec5SDimitry Andric MCRegisterInfo *X = new MCRegisterInfo(); 347bdd1243dSDimitry Andric InitHexagonMCRegisterInfo(X, Hexagon::R31, /*DwarfFlavour=*/0, 348bdd1243dSDimitry Andric /*EHFlavour=*/0, /*PC=*/Hexagon::PC); 3490b57cec5SDimitry Andric return X; 3500b57cec5SDimitry Andric } 3510b57cec5SDimitry Andric 3520b57cec5SDimitry Andric static MCAsmInfo *createHexagonMCAsmInfo(const MCRegisterInfo &MRI, 353480093f4SDimitry Andric const Triple &TT, 354480093f4SDimitry Andric const MCTargetOptions &Options) { 3550b57cec5SDimitry Andric MCAsmInfo *MAI = new HexagonMCAsmInfo(TT); 3560b57cec5SDimitry Andric 3570b57cec5SDimitry Andric // VirtualFP = (R30 + #0). 3585ffd83dbSDimitry Andric MCCFIInstruction Inst = MCCFIInstruction::cfiDefCfa( 3595ffd83dbSDimitry Andric nullptr, MRI.getDwarfRegNum(Hexagon::R30, true), 0); 3600b57cec5SDimitry Andric MAI->addInitialFrameState(Inst); 3610b57cec5SDimitry Andric 3620b57cec5SDimitry Andric return MAI; 3630b57cec5SDimitry Andric } 3640b57cec5SDimitry Andric 3650b57cec5SDimitry Andric static MCInstPrinter *createHexagonMCInstPrinter(const Triple &T, 3660b57cec5SDimitry Andric unsigned SyntaxVariant, 3670b57cec5SDimitry Andric const MCAsmInfo &MAI, 3680b57cec5SDimitry Andric const MCInstrInfo &MII, 3690b57cec5SDimitry Andric const MCRegisterInfo &MRI) 3700b57cec5SDimitry Andric { 3710b57cec5SDimitry Andric if (SyntaxVariant == 0) 3720b57cec5SDimitry Andric return new HexagonInstPrinter(MAI, MII, MRI); 3730b57cec5SDimitry Andric else 3740b57cec5SDimitry Andric return nullptr; 3750b57cec5SDimitry Andric } 3760b57cec5SDimitry Andric 377*0fca6ea1SDimitry Andric static MCTargetStreamer *createMCAsmTargetStreamer(MCStreamer &S, 378*0fca6ea1SDimitry Andric formatted_raw_ostream &OS, 379*0fca6ea1SDimitry Andric MCInstPrinter *IP) { 380*0fca6ea1SDimitry Andric return new HexagonTargetAsmStreamer(S, OS, *IP); 3810b57cec5SDimitry Andric } 3820b57cec5SDimitry Andric 3830b57cec5SDimitry Andric static MCStreamer *createMCStreamer(Triple const &T, MCContext &Context, 3840b57cec5SDimitry Andric std::unique_ptr<MCAsmBackend> &&MAB, 3850b57cec5SDimitry Andric std::unique_ptr<MCObjectWriter> &&OW, 386*0fca6ea1SDimitry Andric std::unique_ptr<MCCodeEmitter> &&Emitter) { 3870b57cec5SDimitry Andric return createHexagonELFStreamer(T, Context, std::move(MAB), std::move(OW), 3880b57cec5SDimitry Andric std::move(Emitter)); 3890b57cec5SDimitry Andric } 3900b57cec5SDimitry Andric 3910b57cec5SDimitry Andric static MCTargetStreamer * 3920b57cec5SDimitry Andric createHexagonObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) { 3930b57cec5SDimitry Andric return new HexagonTargetELFStreamer(S, STI); 3940b57cec5SDimitry Andric } 3950b57cec5SDimitry Andric 396bdd1243dSDimitry Andric static MCTargetStreamer *createHexagonNullTargetStreamer(MCStreamer &S) { 397bdd1243dSDimitry Andric return new HexagonTargetStreamer(S); 398bdd1243dSDimitry Andric } 399bdd1243dSDimitry Andric 4000b57cec5SDimitry Andric static void LLVM_ATTRIBUTE_UNUSED clearFeature(MCSubtargetInfo* STI, uint64_t F) { 40106c3fb27SDimitry Andric if (STI->hasFeature(F)) 4020b57cec5SDimitry Andric STI->ToggleFeature(F); 4030b57cec5SDimitry Andric } 4040b57cec5SDimitry Andric 4050b57cec5SDimitry Andric static bool LLVM_ATTRIBUTE_UNUSED checkFeature(MCSubtargetInfo* STI, uint64_t F) { 40606c3fb27SDimitry Andric return STI->hasFeature(F); 4070b57cec5SDimitry Andric } 4080b57cec5SDimitry Andric 4090b57cec5SDimitry Andric namespace { 4100b57cec5SDimitry Andric std::string selectHexagonFS(StringRef CPU, StringRef FS) { 4110b57cec5SDimitry Andric SmallVector<StringRef, 3> Result; 4120b57cec5SDimitry Andric if (!FS.empty()) 4130b57cec5SDimitry Andric Result.push_back(FS); 4140b57cec5SDimitry Andric 4150b57cec5SDimitry Andric switch (EnableHVX) { 4160b57cec5SDimitry Andric case Hexagon::ArchEnum::V5: 4170b57cec5SDimitry Andric case Hexagon::ArchEnum::V55: 4180b57cec5SDimitry Andric break; 4190b57cec5SDimitry Andric case Hexagon::ArchEnum::V60: 4200b57cec5SDimitry Andric Result.push_back("+hvxv60"); 4210b57cec5SDimitry Andric break; 4220b57cec5SDimitry Andric case Hexagon::ArchEnum::V62: 4230b57cec5SDimitry Andric Result.push_back("+hvxv62"); 4240b57cec5SDimitry Andric break; 4250b57cec5SDimitry Andric case Hexagon::ArchEnum::V65: 4260b57cec5SDimitry Andric Result.push_back("+hvxv65"); 4270b57cec5SDimitry Andric break; 4280b57cec5SDimitry Andric case Hexagon::ArchEnum::V66: 4290b57cec5SDimitry Andric Result.push_back("+hvxv66"); 4300b57cec5SDimitry Andric break; 4315ffd83dbSDimitry Andric case Hexagon::ArchEnum::V67: 4325ffd83dbSDimitry Andric Result.push_back("+hvxv67"); 4335ffd83dbSDimitry Andric break; 434fe6060f1SDimitry Andric case Hexagon::ArchEnum::V68: 435fe6060f1SDimitry Andric Result.push_back("+hvxv68"); 436fe6060f1SDimitry Andric break; 4370eae32dcSDimitry Andric case Hexagon::ArchEnum::V69: 4380eae32dcSDimitry Andric Result.push_back("+hvxv69"); 4390eae32dcSDimitry Andric break; 440bdd1243dSDimitry Andric case Hexagon::ArchEnum::V71: 441bdd1243dSDimitry Andric Result.push_back("+hvxv71"); 442bdd1243dSDimitry Andric break; 443bdd1243dSDimitry Andric case Hexagon::ArchEnum::V73: 444bdd1243dSDimitry Andric Result.push_back("+hvxv73"); 445bdd1243dSDimitry Andric break; 4460b57cec5SDimitry Andric case Hexagon::ArchEnum::Generic:{ 4470b57cec5SDimitry Andric Result.push_back(StringSwitch<StringRef>(CPU) 4480b57cec5SDimitry Andric .Case("hexagonv60", "+hvxv60") 4490b57cec5SDimitry Andric .Case("hexagonv62", "+hvxv62") 4500b57cec5SDimitry Andric .Case("hexagonv65", "+hvxv65") 4515ffd83dbSDimitry Andric .Case("hexagonv66", "+hvxv66") 4525ffd83dbSDimitry Andric .Case("hexagonv67", "+hvxv67") 453fe6060f1SDimitry Andric .Case("hexagonv67t", "+hvxv67") 4540eae32dcSDimitry Andric .Case("hexagonv68", "+hvxv68") 455bdd1243dSDimitry Andric .Case("hexagonv69", "+hvxv69") 456bdd1243dSDimitry Andric .Case("hexagonv71", "+hvxv71") 457bdd1243dSDimitry Andric .Case("hexagonv71t", "+hvxv71") 458bdd1243dSDimitry Andric .Case("hexagonv73", "+hvxv73")); 4590b57cec5SDimitry Andric break; 4600b57cec5SDimitry Andric } 4610b57cec5SDimitry Andric case Hexagon::ArchEnum::NoArch: 4625ffd83dbSDimitry Andric // Sentinel if -mhvx isn't specified 4630b57cec5SDimitry Andric break; 4640b57cec5SDimitry Andric } 4650eae32dcSDimitry Andric if (EnableHvxIeeeFp) 4660eae32dcSDimitry Andric Result.push_back("+hvx-ieee-fp"); 4670eae32dcSDimitry Andric if (EnableHexagonCabac) 4680eae32dcSDimitry Andric Result.push_back("+cabac"); 4690eae32dcSDimitry Andric 4700b57cec5SDimitry Andric return join(Result.begin(), Result.end(), ","); 4710b57cec5SDimitry Andric } 4720b57cec5SDimitry Andric } 4730b57cec5SDimitry Andric 47481ad6265SDimitry Andric static bool isCPUValid(StringRef CPU) { 47581ad6265SDimitry Andric return Hexagon::getCpu(CPU).has_value(); 4760b57cec5SDimitry Andric } 4770b57cec5SDimitry Andric 4780b57cec5SDimitry Andric namespace { 4790b57cec5SDimitry Andric std::pair<std::string, std::string> selectCPUAndFS(StringRef CPU, 4800b57cec5SDimitry Andric StringRef FS) { 4810b57cec5SDimitry Andric std::pair<std::string, std::string> Result; 4825ffd83dbSDimitry Andric Result.first = std::string(Hexagon_MC::selectHexagonCPU(CPU)); 4830b57cec5SDimitry Andric Result.second = selectHexagonFS(Result.first, FS); 4840b57cec5SDimitry Andric return Result; 4850b57cec5SDimitry Andric } 4865ffd83dbSDimitry Andric std::mutex ArchSubtargetMutex; 4875ffd83dbSDimitry Andric std::unordered_map<std::string, std::unique_ptr<MCSubtargetInfo const>> 4885ffd83dbSDimitry Andric ArchSubtarget; 4895ffd83dbSDimitry Andric } // namespace 4905ffd83dbSDimitry Andric 4915ffd83dbSDimitry Andric MCSubtargetInfo const * 4925ffd83dbSDimitry Andric Hexagon_MC::getArchSubtarget(MCSubtargetInfo const *STI) { 4935ffd83dbSDimitry Andric std::lock_guard<std::mutex> Lock(ArchSubtargetMutex); 4945ffd83dbSDimitry Andric auto Existing = ArchSubtarget.find(std::string(STI->getCPU())); 4955ffd83dbSDimitry Andric if (Existing == ArchSubtarget.end()) 4965ffd83dbSDimitry Andric return nullptr; 4975ffd83dbSDimitry Andric return Existing->second.get(); 4980b57cec5SDimitry Andric } 4990b57cec5SDimitry Andric 5000b57cec5SDimitry Andric FeatureBitset Hexagon_MC::completeHVXFeatures(const FeatureBitset &S) { 5010b57cec5SDimitry Andric using namespace Hexagon; 5020b57cec5SDimitry Andric // Make sure that +hvx-length turns hvx on, and that "hvx" alone 5030b57cec5SDimitry Andric // turns on hvxvNN, corresponding to the existing ArchVNN. 5040b57cec5SDimitry Andric FeatureBitset FB = S; 5050b57cec5SDimitry Andric unsigned CpuArch = ArchV5; 506bdd1243dSDimitry Andric for (unsigned F : {ArchV73, ArchV71, ArchV69, ArchV68, ArchV67, ArchV66, 507bdd1243dSDimitry Andric ArchV65, ArchV62, ArchV60, ArchV55, ArchV5}) { 5080b57cec5SDimitry Andric if (!FB.test(F)) 5090b57cec5SDimitry Andric continue; 5100b57cec5SDimitry Andric CpuArch = F; 5110b57cec5SDimitry Andric break; 5120b57cec5SDimitry Andric } 5130b57cec5SDimitry Andric bool UseHvx = false; 5140b57cec5SDimitry Andric for (unsigned F : {ExtensionHVX, ExtensionHVX64B, ExtensionHVX128B}) { 5150b57cec5SDimitry Andric if (!FB.test(F)) 5160b57cec5SDimitry Andric continue; 5170b57cec5SDimitry Andric UseHvx = true; 5180b57cec5SDimitry Andric break; 5190b57cec5SDimitry Andric } 5200b57cec5SDimitry Andric bool HasHvxVer = false; 5210b57cec5SDimitry Andric for (unsigned F : {ExtensionHVXV60, ExtensionHVXV62, ExtensionHVXV65, 5220eae32dcSDimitry Andric ExtensionHVXV66, ExtensionHVXV67, ExtensionHVXV68, 523bdd1243dSDimitry Andric ExtensionHVXV69, ExtensionHVXV71, ExtensionHVXV73}) { 5240b57cec5SDimitry Andric if (!FB.test(F)) 5250b57cec5SDimitry Andric continue; 5260b57cec5SDimitry Andric HasHvxVer = true; 5270b57cec5SDimitry Andric UseHvx = true; 5280b57cec5SDimitry Andric break; 5290b57cec5SDimitry Andric } 5300b57cec5SDimitry Andric 5310b57cec5SDimitry Andric if (!UseHvx || HasHvxVer) 5320b57cec5SDimitry Andric return FB; 5330b57cec5SDimitry Andric 5340b57cec5SDimitry Andric // HasHvxVer is false, and UseHvx is true. 5350b57cec5SDimitry Andric switch (CpuArch) { 536bdd1243dSDimitry Andric case ArchV73: 537bdd1243dSDimitry Andric FB.set(ExtensionHVXV73); 538bdd1243dSDimitry Andric [[fallthrough]]; 539bdd1243dSDimitry Andric case ArchV71: 540bdd1243dSDimitry Andric FB.set(ExtensionHVXV71); 541bdd1243dSDimitry Andric [[fallthrough]]; 5420eae32dcSDimitry Andric case ArchV69: 5430eae32dcSDimitry Andric FB.set(ExtensionHVXV69); 544bdd1243dSDimitry Andric [[fallthrough]]; 545fe6060f1SDimitry Andric case ArchV68: 546fe6060f1SDimitry Andric FB.set(ExtensionHVXV68); 547bdd1243dSDimitry Andric [[fallthrough]]; 5485ffd83dbSDimitry Andric case ArchV67: 5495ffd83dbSDimitry Andric FB.set(ExtensionHVXV67); 550bdd1243dSDimitry Andric [[fallthrough]]; 5510b57cec5SDimitry Andric case ArchV66: 5520b57cec5SDimitry Andric FB.set(ExtensionHVXV66); 553bdd1243dSDimitry Andric [[fallthrough]]; 5540b57cec5SDimitry Andric case ArchV65: 5550b57cec5SDimitry Andric FB.set(ExtensionHVXV65); 556bdd1243dSDimitry Andric [[fallthrough]]; 5570b57cec5SDimitry Andric case ArchV62: 5580b57cec5SDimitry Andric FB.set(ExtensionHVXV62); 559bdd1243dSDimitry Andric [[fallthrough]]; 5600b57cec5SDimitry Andric case ArchV60: 5610b57cec5SDimitry Andric FB.set(ExtensionHVXV60); 5620b57cec5SDimitry Andric break; 5630b57cec5SDimitry Andric } 5640b57cec5SDimitry Andric return FB; 5650b57cec5SDimitry Andric } 5660b57cec5SDimitry Andric 5670b57cec5SDimitry Andric MCSubtargetInfo *Hexagon_MC::createHexagonMCSubtargetInfo(const Triple &TT, 5680b57cec5SDimitry Andric StringRef CPU, 5690b57cec5SDimitry Andric StringRef FS) { 5700b57cec5SDimitry Andric std::pair<std::string, std::string> Features = selectCPUAndFS(CPU, FS); 5710b57cec5SDimitry Andric StringRef CPUName = Features.first; 5720b57cec5SDimitry Andric StringRef ArchFS = Features.second; 5730b57cec5SDimitry Andric 574e8d8bef9SDimitry Andric MCSubtargetInfo *X = createHexagonMCSubtargetInfoImpl( 575e8d8bef9SDimitry Andric TT, CPUName, /*TuneCPU*/ CPUName, ArchFS); 576bdd1243dSDimitry Andric if (X != nullptr && (CPUName == "hexagonv67t" || CPUName == "hexagon71t")) 5775ffd83dbSDimitry Andric addArchSubtarget(X, ArchFS); 5785ffd83dbSDimitry Andric 579*0fca6ea1SDimitry Andric if (CPU == "help") 5805ffd83dbSDimitry Andric exit(0); 5815ffd83dbSDimitry Andric 5820b57cec5SDimitry Andric if (!isCPUValid(CPUName.str())) { 5830b57cec5SDimitry Andric errs() << "error: invalid CPU \"" << CPUName.str().c_str() 5840b57cec5SDimitry Andric << "\" specified\n"; 5850b57cec5SDimitry Andric return nullptr; 5860b57cec5SDimitry Andric } 5870b57cec5SDimitry Andric 58804eeddc0SDimitry Andric // Add qfloat subtarget feature by default to v68 and above 58904eeddc0SDimitry Andric // unless explicitely disabled 59004eeddc0SDimitry Andric if (checkFeature(X, Hexagon::ExtensionHVXV68) && 591cb14a3feSDimitry Andric !ArchFS.contains("-hvx-qfloat")) { 59204eeddc0SDimitry Andric llvm::FeatureBitset Features = X->getFeatureBits(); 59304eeddc0SDimitry Andric X->setFeatureBits(Features.set(Hexagon::ExtensionHVXQFloat)); 59404eeddc0SDimitry Andric } 59504eeddc0SDimitry Andric 5960b57cec5SDimitry Andric if (HexagonDisableDuplex) { 5970b57cec5SDimitry Andric llvm::FeatureBitset Features = X->getFeatureBits(); 5988bcb0991SDimitry Andric X->setFeatureBits(Features.reset(Hexagon::FeatureDuplex)); 5990b57cec5SDimitry Andric } 6000b57cec5SDimitry Andric 6010b57cec5SDimitry Andric X->setFeatureBits(completeHVXFeatures(X->getFeatureBits())); 6025ffd83dbSDimitry Andric 6035ffd83dbSDimitry Andric // The Z-buffer instructions are grandfathered in for current 6045ffd83dbSDimitry Andric // architectures but omitted for new ones. Future instruction 6055ffd83dbSDimitry Andric // sets may introduce new/conflicting z-buffer instructions. 6065ffd83dbSDimitry Andric const bool ZRegOnDefault = 6075ffd83dbSDimitry Andric (CPUName == "hexagonv67") || (CPUName == "hexagonv66"); 6085ffd83dbSDimitry Andric if (ZRegOnDefault) { 6095ffd83dbSDimitry Andric llvm::FeatureBitset Features = X->getFeatureBits(); 6105ffd83dbSDimitry Andric X->setFeatureBits(Features.set(Hexagon::ExtensionZReg)); 6115ffd83dbSDimitry Andric } 6125ffd83dbSDimitry Andric 6130b57cec5SDimitry Andric return X; 6140b57cec5SDimitry Andric } 6150b57cec5SDimitry Andric 616bdd1243dSDimitry Andric void Hexagon_MC::addArchSubtarget(MCSubtargetInfo const *STI, StringRef FS) { 6175ffd83dbSDimitry Andric assert(STI != nullptr); 6185ffd83dbSDimitry Andric if (STI->getCPU().contains("t")) { 6195ffd83dbSDimitry Andric auto ArchSTI = createHexagonMCSubtargetInfo( 6205ffd83dbSDimitry Andric STI->getTargetTriple(), 6215ffd83dbSDimitry Andric STI->getCPU().substr(0, STI->getCPU().size() - 1), FS); 6225ffd83dbSDimitry Andric std::lock_guard<std::mutex> Lock(ArchSubtargetMutex); 6235ffd83dbSDimitry Andric ArchSubtarget[std::string(STI->getCPU())] = 6245ffd83dbSDimitry Andric std::unique_ptr<MCSubtargetInfo const>(ArchSTI); 6255ffd83dbSDimitry Andric } 6265ffd83dbSDimitry Andric } 6275ffd83dbSDimitry Andric 628*0fca6ea1SDimitry Andric std::optional<unsigned> 629*0fca6ea1SDimitry Andric Hexagon_MC::getHVXVersion(const FeatureBitset &Features) { 630*0fca6ea1SDimitry Andric for (auto Arch : {Hexagon::ExtensionHVXV73, Hexagon::ExtensionHVXV71, 631*0fca6ea1SDimitry Andric Hexagon::ExtensionHVXV69, Hexagon::ExtensionHVXV68, 632*0fca6ea1SDimitry Andric Hexagon::ExtensionHVXV67, Hexagon::ExtensionHVXV66, 633*0fca6ea1SDimitry Andric Hexagon::ExtensionHVXV65, Hexagon::ExtensionHVXV62, 634*0fca6ea1SDimitry Andric Hexagon::ExtensionHVXV60}) 635*0fca6ea1SDimitry Andric if (Features.test(Arch)) 636*0fca6ea1SDimitry Andric return Arch; 637*0fca6ea1SDimitry Andric return {}; 638*0fca6ea1SDimitry Andric } 639*0fca6ea1SDimitry Andric 640*0fca6ea1SDimitry Andric unsigned Hexagon_MC::getArchVersion(const FeatureBitset &Features) { 641*0fca6ea1SDimitry Andric for (auto Arch : 642*0fca6ea1SDimitry Andric {Hexagon::ArchV73, Hexagon::ArchV71, Hexagon::ArchV69, Hexagon::ArchV68, 643*0fca6ea1SDimitry Andric Hexagon::ArchV67, Hexagon::ArchV66, Hexagon::ArchV65, Hexagon::ArchV62, 644*0fca6ea1SDimitry Andric Hexagon::ArchV60, Hexagon::ArchV55, Hexagon::ArchV5}) 645*0fca6ea1SDimitry Andric if (Features.test(Arch)) 646*0fca6ea1SDimitry Andric return Arch; 647*0fca6ea1SDimitry Andric llvm_unreachable("Expected arch v5-v73"); 648*0fca6ea1SDimitry Andric return 0; 649*0fca6ea1SDimitry Andric } 650*0fca6ea1SDimitry Andric 6510b57cec5SDimitry Andric unsigned Hexagon_MC::GetELFFlags(const MCSubtargetInfo &STI) { 65281ad6265SDimitry Andric return StringSwitch<unsigned>(STI.getCPU()) 65381ad6265SDimitry Andric .Case("generic", llvm::ELF::EF_HEXAGON_MACH_V5) 65481ad6265SDimitry Andric .Case("hexagonv5", llvm::ELF::EF_HEXAGON_MACH_V5) 65581ad6265SDimitry Andric .Case("hexagonv55", llvm::ELF::EF_HEXAGON_MACH_V55) 65681ad6265SDimitry Andric .Case("hexagonv60", llvm::ELF::EF_HEXAGON_MACH_V60) 65781ad6265SDimitry Andric .Case("hexagonv62", llvm::ELF::EF_HEXAGON_MACH_V62) 65881ad6265SDimitry Andric .Case("hexagonv65", llvm::ELF::EF_HEXAGON_MACH_V65) 65981ad6265SDimitry Andric .Case("hexagonv66", llvm::ELF::EF_HEXAGON_MACH_V66) 66081ad6265SDimitry Andric .Case("hexagonv67", llvm::ELF::EF_HEXAGON_MACH_V67) 66181ad6265SDimitry Andric .Case("hexagonv67t", llvm::ELF::EF_HEXAGON_MACH_V67T) 66281ad6265SDimitry Andric .Case("hexagonv68", llvm::ELF::EF_HEXAGON_MACH_V68) 663bdd1243dSDimitry Andric .Case("hexagonv69", llvm::ELF::EF_HEXAGON_MACH_V69) 664bdd1243dSDimitry Andric .Case("hexagonv71", llvm::ELF::EF_HEXAGON_MACH_V71) 665bdd1243dSDimitry Andric .Case("hexagonv71t", llvm::ELF::EF_HEXAGON_MACH_V71T) 666bdd1243dSDimitry Andric .Case("hexagonv73", llvm::ELF::EF_HEXAGON_MACH_V73); 6670b57cec5SDimitry Andric } 6680b57cec5SDimitry Andric 6695ffd83dbSDimitry Andric llvm::ArrayRef<MCPhysReg> Hexagon_MC::GetVectRegRev() { 670bdd1243dSDimitry Andric return ArrayRef(VectRegRev); 6715ffd83dbSDimitry Andric } 6725ffd83dbSDimitry Andric 6730b57cec5SDimitry Andric namespace { 6740b57cec5SDimitry Andric class HexagonMCInstrAnalysis : public MCInstrAnalysis { 6750b57cec5SDimitry Andric public: 6760b57cec5SDimitry Andric HexagonMCInstrAnalysis(MCInstrInfo const *Info) : MCInstrAnalysis(Info) {} 6770b57cec5SDimitry Andric 6780b57cec5SDimitry Andric bool isUnconditionalBranch(MCInst const &Inst) const override { 6790b57cec5SDimitry Andric //assert(!HexagonMCInstrInfo::isBundle(Inst)); 6800b57cec5SDimitry Andric return MCInstrAnalysis::isUnconditionalBranch(Inst); 6810b57cec5SDimitry Andric } 6820b57cec5SDimitry Andric 6830b57cec5SDimitry Andric bool isConditionalBranch(MCInst const &Inst) const override { 6840b57cec5SDimitry Andric //assert(!HexagonMCInstrInfo::isBundle(Inst)); 6850b57cec5SDimitry Andric return MCInstrAnalysis::isConditionalBranch(Inst); 6860b57cec5SDimitry Andric } 6870b57cec5SDimitry Andric 6880b57cec5SDimitry Andric bool evaluateBranch(MCInst const &Inst, uint64_t Addr, 6890b57cec5SDimitry Andric uint64_t Size, uint64_t &Target) const override { 6905ffd83dbSDimitry Andric if (!(isCall(Inst) || isUnconditionalBranch(Inst) || 6915ffd83dbSDimitry Andric isConditionalBranch(Inst))) 6925ffd83dbSDimitry Andric return false; 6935ffd83dbSDimitry Andric 6940b57cec5SDimitry Andric //assert(!HexagonMCInstrInfo::isBundle(Inst)); 6950b57cec5SDimitry Andric if (!HexagonMCInstrInfo::isExtendable(*Info, Inst)) 6960b57cec5SDimitry Andric return false; 6970b57cec5SDimitry Andric auto const &Extended(HexagonMCInstrInfo::getExtendableOperand(*Info, Inst)); 6980b57cec5SDimitry Andric assert(Extended.isExpr()); 6990b57cec5SDimitry Andric int64_t Value; 7000b57cec5SDimitry Andric if (!Extended.getExpr()->evaluateAsAbsolute(Value)) 7010b57cec5SDimitry Andric return false; 7020b57cec5SDimitry Andric Target = Value; 7030b57cec5SDimitry Andric return true; 7040b57cec5SDimitry Andric } 7050b57cec5SDimitry Andric }; 7060b57cec5SDimitry Andric } 7070b57cec5SDimitry Andric 7080b57cec5SDimitry Andric static MCInstrAnalysis *createHexagonMCInstrAnalysis(const MCInstrInfo *Info) { 7090b57cec5SDimitry Andric return new HexagonMCInstrAnalysis(Info); 7100b57cec5SDimitry Andric } 7110b57cec5SDimitry Andric 7120b57cec5SDimitry Andric // Force static initialization. 713480093f4SDimitry Andric extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeHexagonTargetMC() { 7140b57cec5SDimitry Andric // Register the MC asm info. 7150b57cec5SDimitry Andric RegisterMCAsmInfoFn X(getTheHexagonTarget(), createHexagonMCAsmInfo); 7160b57cec5SDimitry Andric 7170b57cec5SDimitry Andric // Register the MC instruction info. 7180b57cec5SDimitry Andric TargetRegistry::RegisterMCInstrInfo(getTheHexagonTarget(), 7190b57cec5SDimitry Andric createHexagonMCInstrInfo); 7200b57cec5SDimitry Andric 7210b57cec5SDimitry Andric // Register the MC register info. 7220b57cec5SDimitry Andric TargetRegistry::RegisterMCRegInfo(getTheHexagonTarget(), 7230b57cec5SDimitry Andric createHexagonMCRegisterInfo); 7240b57cec5SDimitry Andric 7250b57cec5SDimitry Andric // Register the MC subtarget info. 726bdd1243dSDimitry Andric TargetRegistry::RegisterMCSubtargetInfo( 727bdd1243dSDimitry Andric getTheHexagonTarget(), Hexagon_MC::createHexagonMCSubtargetInfo); 7280b57cec5SDimitry Andric 7290b57cec5SDimitry Andric // Register the MC Code Emitter 7300b57cec5SDimitry Andric TargetRegistry::RegisterMCCodeEmitter(getTheHexagonTarget(), 7310b57cec5SDimitry Andric createHexagonMCCodeEmitter); 7320b57cec5SDimitry Andric 7330b57cec5SDimitry Andric // Register the asm backend 7340b57cec5SDimitry Andric TargetRegistry::RegisterMCAsmBackend(getTheHexagonTarget(), 7350b57cec5SDimitry Andric createHexagonAsmBackend); 7360b57cec5SDimitry Andric 7370b57cec5SDimitry Andric // Register the MC instruction analyzer. 7380b57cec5SDimitry Andric TargetRegistry::RegisterMCInstrAnalysis(getTheHexagonTarget(), 7390b57cec5SDimitry Andric createHexagonMCInstrAnalysis); 7400b57cec5SDimitry Andric 7410b57cec5SDimitry Andric // Register the obj streamer 742bdd1243dSDimitry Andric TargetRegistry::RegisterELFStreamer(getTheHexagonTarget(), createMCStreamer); 7430b57cec5SDimitry Andric 7440b57cec5SDimitry Andric // Register the obj target streamer 745bdd1243dSDimitry Andric TargetRegistry::RegisterObjectTargetStreamer( 746bdd1243dSDimitry Andric getTheHexagonTarget(), createHexagonObjectTargetStreamer); 7470b57cec5SDimitry Andric 7480b57cec5SDimitry Andric // Register the asm streamer 7490b57cec5SDimitry Andric TargetRegistry::RegisterAsmTargetStreamer(getTheHexagonTarget(), 7500b57cec5SDimitry Andric createMCAsmTargetStreamer); 7510b57cec5SDimitry Andric 752bdd1243dSDimitry Andric // Register the null streamer 753bdd1243dSDimitry Andric TargetRegistry::RegisterNullTargetStreamer(getTheHexagonTarget(), 754bdd1243dSDimitry Andric createHexagonNullTargetStreamer); 755bdd1243dSDimitry Andric 7560b57cec5SDimitry Andric // Register the MC Inst Printer 7570b57cec5SDimitry Andric TargetRegistry::RegisterMCInstPrinter(getTheHexagonTarget(), 7580b57cec5SDimitry Andric createHexagonMCInstPrinter); 7590b57cec5SDimitry Andric } 760