Go to the documentation of this file.
43 #include <unordered_map>
47 #define GET_INSTRINFO_MC_DESC
48 #include "HexagonGenInstrInfo.inc"
50 #define GET_SUBTARGETINFO_MC_DESC
51 #include "HexagonGenSubtargetInfo.inc"
53 #define GET_REGINFO_MC_DESC
54 #include "HexagonGenRegisterInfo.inc"
58 cl::desc(
"Disable looking for compound instructions for Hexagon"));
62 cl::desc(
"Disable looking for duplex instructions for Hexagon"));
86 cl::desc(
"Enable Hexagon Vector eXtensions"),
102 cl::desc(
"Disable Hexagon Vector eXtensions"));
123 return "hexagonv67t";
134 std::pair<StringRef,StringRef> ArchP = ArchV.
split(
't');
135 std::pair<StringRef,StringRef> CPUP = CPU.
split(
't');
136 if (!ArchP.first.equals(CPUP.first))
160 if (ItinUnits == HexagonItinerariesV62FU::CVI_ALL ||
161 ItinUnits == HexagonItinerariesV62FU::CVI_ALL_NOMEM)
162 return (*Lanes = 4, CVI_XLANE);
163 else if (ItinUnits & HexagonItinerariesV62FU::CVI_MPY01 &&
164 ItinUnits & HexagonItinerariesV62FU::CVI_XLSHF)
165 return (*Lanes = 2, CVI_XLANE | CVI_MPY0);
166 else if (ItinUnits & HexagonItinerariesV62FU::CVI_MPY01)
167 return (*Lanes = 2, CVI_MPY0);
168 else if (ItinUnits & HexagonItinerariesV62FU::CVI_XLSHF)
169 return (*Lanes = 2, CVI_XLANE);
170 else if (ItinUnits & HexagonItinerariesV62FU::CVI_XLANE &&
171 ItinUnits & HexagonItinerariesV62FU::CVI_SHIFT &&
172 ItinUnits & HexagonItinerariesV62FU::CVI_MPY0 &&
173 ItinUnits & HexagonItinerariesV62FU::CVI_MPY1)
174 return (*Lanes = 1, CVI_XLANE | CVI_SHIFT | CVI_MPY0 | CVI_MPY1);
175 else if (ItinUnits & HexagonItinerariesV62FU::CVI_XLANE &&
176 ItinUnits & HexagonItinerariesV62FU::CVI_SHIFT)
177 return (*Lanes = 1, CVI_XLANE | CVI_SHIFT);
178 else if (ItinUnits & HexagonItinerariesV62FU::CVI_MPY0 &&
179 ItinUnits & HexagonItinerariesV62FU::CVI_MPY1)
180 return (*Lanes = 1, CVI_MPY0 | CVI_MPY1);
181 else if (ItinUnits == HexagonItinerariesV62FU::CVI_ZW)
182 return (*Lanes = 1, CVI_ZW);
183 else if (ItinUnits == HexagonItinerariesV62FU::CVI_XLANE)
184 return (*Lanes = 1, CVI_XLANE);
185 else if (ItinUnits == HexagonItinerariesV62FU::CVI_SHIFT)
186 return (*Lanes = 1, CVI_SHIFT);
188 return (*Lanes = 0, CVI_NONE);
193 namespace HexagonFUnits {
195 return HexagonItinerariesV62FU::SLOT0 == units;
210 void prettyPrintAsm(
MCInstPrinter &InstPrinter, uint64_t Address,
218 InstPrinter.
printInst(&Inst, Address,
"", STI, TempStream);
221 auto PacketBundle = Contents.rsplit(
'\n');
222 auto HeadTail = PacketBundle.first.split(
'\n');
226 while (!HeadTail.first.empty()) {
228 auto Duplex = HeadTail.first.
split(
'\v');
229 if (!Duplex.second.empty()) {
230 OS << Indent << Duplex.first << Separator;
231 InstTxt = Duplex.second;
232 }
else if (!HeadTail.first.trim().startswith(
"immext")) {
233 InstTxt = Duplex.first;
235 if (!InstTxt.
empty())
236 OS << Indent << InstTxt << Separator;
237 HeadTail = HeadTail.second.
split(
'\n');
241 OS <<
"\n\t} :mem_noshuf" << PacketBundle.second;
243 OS <<
"\t}" << PacketBundle.second;
261 unsigned AccessSize)
override {
270 unsigned AccessSize)
override {
282 InitHexagonMCInstrInfo(
X);
288 InitHexagonMCRegisterInfo(
X, Hexagon::R31);
299 nullptr,
MRI.getDwarfRegNum(Hexagon::R30,
true), 0);
306 unsigned SyntaxVariant,
311 if (SyntaxVariant == 0)
320 return new HexagonTargetAsmStreamer(
S, OS, IsVerboseAsm, *
IP);
324 std::unique_ptr<MCAsmBackend> &&MAB,
325 std::unique_ptr<MCObjectWriter> &&OW,
326 std::unique_ptr<MCCodeEmitter> &&Emitter,
334 return new HexagonTargetELFStreamer(
S, STI);
357 Result.push_back(
"+hvxv60");
360 Result.push_back(
"+hvxv62");
363 Result.push_back(
"+hvxv65");
366 Result.push_back(
"+hvxv66");
369 Result.push_back(
"+hvxv67");
372 Result.push_back(
"+hvxv68");
376 .Case(
"hexagonv60",
"+hvxv60")
377 .Case(
"hexagonv62",
"+hvxv62")
378 .Case(
"hexagonv65",
"+hvxv65")
379 .Case(
"hexagonv66",
"+hvxv66")
380 .Case(
"hexagonv67",
"+hvxv67")
381 .Case(
"hexagonv67t",
"+hvxv67")
382 .Case(
"hexagonv68",
"+hvxv68"));
398 std::pair<std::string, std::string> selectCPUAndFS(
StringRef CPU,
400 std::pair<std::string, std::string>
Result;
405 std::mutex ArchSubtargetMutex;
406 std::unordered_map<std::string, std::unique_ptr<MCSubtargetInfo const>>
412 std::lock_guard<std::mutex>
Lock(ArchSubtargetMutex);
413 auto Existing = ArchSubtarget.find(std::string(STI->
getCPU()));
414 if (Existing == ArchSubtarget.end())
416 return Existing->second.get();
420 using namespace Hexagon;
424 unsigned CpuArch = ArchV5;
425 for (
unsigned F : {ArchV68, ArchV67, ArchV66, ArchV65, ArchV62, ArchV60,
433 for (
unsigned F : {ExtensionHVX, ExtensionHVX64B, ExtensionHVX128B}) {
439 bool HasHvxVer =
false;
440 for (
unsigned F : {ExtensionHVXV60, ExtensionHVXV62, ExtensionHVXV65,
441 ExtensionHVXV66, ExtensionHVXV67, ExtensionHVXV68}) {
449 if (!UseHvx || HasHvxVer)
455 FB.
set(ExtensionHVXV68);
458 FB.
set(ExtensionHVXV67);
461 FB.
set(ExtensionHVXV66);
464 FB.
set(ExtensionHVXV65);
467 FB.
set(ExtensionHVXV62);
470 FB.
set(ExtensionHVXV60);
479 std::pair<std::string, std::string> Features = selectCPUAndFS(CPU,
FS);
484 TT, CPUName, CPUName, ArchFS);
485 if (
X !=
nullptr && (CPUName ==
"hexagonv67t"))
492 errs() <<
"error: invalid CPU \"" << CPUName.
str().c_str()
499 X->setFeatureBits(Features.
reset(Hexagon::FeatureDuplex));
507 const bool ZRegOnDefault =
508 (CPUName ==
"hexagonv67") || (CPUName ==
"hexagonv66");
511 X->setFeatureBits(Features.
set(Hexagon::ExtensionZReg));
524 std::lock_guard<std::mutex>
Lock(ArchSubtargetMutex);
525 ArchSubtarget[std::string(STI->
getCPU())] =
526 std::unique_ptr<MCSubtargetInfo const>(ArchSTI);
531 static std::map<StringRef,unsigned> ElfFlags = {
543 auto F = ElfFlags.find(STI.
getCPU());
544 assert(
F != ElfFlags.end() &&
"Unrecognized Architecture");
562 bool isConditionalBranch(
MCInst const &Inst)
const override {
567 bool evaluateBranch(
MCInst const &Inst, uint64_t
Addr,
568 uint64_t
Size, uint64_t &
Target)
const override {
570 isConditionalBranch(Inst)))
577 assert(Extended.isExpr());
579 if(!Extended.getExpr()->evaluateAsAbsolute(
Value))
588 return new HexagonMCInstrAnalysis(
Info);
unsigned HexagonConvertUnits(unsigned ItinUnits, unsigned *Lanes)
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
static StringRef HexagonGetArchVariant()
static MCStreamer * createMCStreamer(Triple const &T, MCContext &Context, std::unique_ptr< MCAsmBackend > &&MAB, std::unique_ptr< MCObjectWriter > &&OW, std::unique_ptr< MCCodeEmitter > &&Emitter, bool RelaxAll)
cl::opt< bool > HexagonDisableCompound
MCCodeEmitter * createHexagonMCCodeEmitter(const MCInstrInfo &MCII, const MCRegisterInfo &MRI, MCContext &MCT)
Context object for machine code objects.
A raw_ostream that writes to an std::string.
Target - Wrapper for Target specific information.
This class is intended to be used as a base class for asm properties and features specific to the tar...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
unsigned GetELFFlags(const MCSubtargetInfo &STI)
static void RegisterAsmTargetStreamer(Target &T, Target::AsmTargetStreamerCtorTy Fn)
static void RegisterMCInstrAnalysis(Target &T, Target::MCInstrAnalysisCtorFnTy Fn)
RegisterMCInstrAnalysis - Register a MCInstrAnalysis implementation for the given target.
static MCInstPrinter * createHexagonMCInstPrinter(const Triple &T, unsigned SyntaxVariant, const MCAsmInfo &MAI, const MCInstrInfo &MII, const MCRegisterInfo &MRI)
Triple - Helper class for working with autoconf configuration names.
void addArchSubtarget(MCSubtargetInfo const *STI, StringRef FS)
static bool isCPUValid(const std::string &CPU)
Prints bundles as a newline separated list of individual instructions Duplexes are separated by a ver...
Container class for subtarget features.
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
Instances of this class represent a single low-level machine instruction.
#define LLVM_ATTRIBUTE_UNUSED
static void RegisterMCInstPrinter(Target &T, Target::MCInstPrinterCtorTy Fn)
RegisterMCInstPrinter - Register a MCInstPrinter implementation for the given target.
const MCSubtargetInfo * getArchSubtarget(MCSubtargetInfo const *STI)
virtual void printInst(const MCInst *MI, uint64_t Address, StringRef Annot, const MCSubtargetInfo &STI, raw_ostream &OS)=0
Print the specified MCInst to the specified raw_ostream.
LLVM_NODISCARD StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
bool isMemReorderDisabled(MCInst const &MCI)
Streaming machine code generation interface.
MCStreamer * createHexagonELFStreamer(Triple const &TT, MCContext &Context, std::unique_ptr< MCAsmBackend > MAB, std::unique_ptr< MCObjectWriter > OW, std::unique_ptr< MCCodeEmitter > CE)
cl::opt< bool > HexagonDisableDuplex
LLVM_NODISCARD std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
const Triple & getTargetTriple() const
bool isBundle(MCInst const &MCI)
const FeatureBitset & getFeatureBits() const
virtual bool isUnconditionalBranch(const MCInst &Inst) const
LLVM_NODISCARD bool contains(StringRef Other) const
Return true if the given string is a substring of *this, and false otherwise.
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
This class implements an extremely fast bulk output stream that can only output to a stream.
Target specific streamer interface.
Analysis containing CSE Info
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
RegisterMCAsmInfoFn - Helper template for registering a target assembly info implementation.
size_t bundleSize(MCInst const &MCI)
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
LLVM_NODISCARD bool equals(StringRef RHS) const
equals - Check for string equality, this is more efficient than compare() when the relative ordering ...
FeatureBitset ToggleFeature(uint64_t FB)
Toggle a feature and return the re-computed feature bits.
llvm::ArrayRef< MCPhysReg > GetVectRegRev()
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
static void RegisterMCAsmBackend(Target &T, Target::MCAsmBackendCtorTy Fn)
RegisterMCAsmBackend - Register a MCAsmBackend implementation for the given target.
MCInstrInfo * createHexagonMCInstrInfo()
virtual bool isConditionalBranch(const MCInst &Inst) const
This is an instance of a target assembly language printer that converts an MCInst to valid target ass...
#define LLVM_EXTERNAL_VISIBILITY
static MCAsmInfo * createHexagonMCAsmInfo(const MCRegisterInfo &MRI, const Triple &TT, const MCTargetOptions &Options)
MCRegisterInfo * createHexagonMCRegisterInfo(StringRef TT)
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
static bool LLVM_ATTRIBUTE_UNUSED checkFeature(MCSubtargetInfo *STI, uint64_t F)
static void RegisterObjectTargetStreamer(Target &T, Target::ObjectTargetStreamerCtorTy Fn)
initializer< Ty > init(const Ty &Val)
unsigned HexagonGetLastSlot()
void setELFHeaderEFlags(unsigned Flags)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static MCCFIInstruction cfiDefCfa(MCSymbol *L, unsigned Register, int Offset)
.cfi_def_cfa defines a rule for computing CFA as: take address from Register and add Offset to it.
void addInitialFrameState(const MCCFIInstruction &Inst)
static void RegisterMCSubtargetInfo(Target &T, Target::MCSubtargetInfoCtorFnTy Fn)
RegisterMCSubtargetInfo - Register a MCSubtargetInfo implementation for the given target.
Target & getTheHexagonTarget()
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
static const std::map< std::string, ArchEnum > CpuTable
StringRef - Represent a constant reference to a string, i.e.
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
constexpr FeatureBitset & reset(unsigned I)
unsigned const MachineRegisterInfo * MRI
static bool isUnconditionalBranch(Instruction *Term)
bool isSlot0Only(unsigned units)
static void RegisterMCInstrInfo(Target &T, Target::MCInstrInfoCtorFnTy Fn)
RegisterMCInstrInfo - Register a MCInstrInfo implementation for the given target.
static void RegisterMCCodeEmitter(Target &T, Target::MCCodeEmitterCtorTy Fn)
RegisterMCCodeEmitter - Register a MCCodeEmitter implementation for the given target.
Interface to description of machine instruction set.
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeHexagonTargetMC()
static void RegisterMCRegInfo(Target &T, Target::MCRegInfoCtorFnTy Fn)
RegisterMCRegInfo - Register a MCRegisterInfo implementation for the given target.
static cl::opt< bool > DisableHVX("mno-hvx", cl::Hidden, cl::desc("Disable Hexagon Vector eXtensions"))
static void RegisterELFStreamer(Target &T, Target::ELFStreamerCtorTy Fn)
const MCOperand & getExtendableOperand(MCInstrInfo const &MCII, MCInst const &MCI)
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
MCSubtargetInfo * createHexagonMCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS)
Create a Hexagon MCSubtargetInfo instance.
static MCInstrAnalysis * createHexagonMCInstrAnalysis(const MCInstrInfo *Info)
constexpr bool test(unsigned I) const
StringRef selectHexagonCPU(StringRef CPU)
static MCTargetStreamer * createMCAsmTargetStreamer(MCStreamer &S, formatted_raw_ostream &OS, MCInstPrinter *IP, bool IsVerboseAsm)
static void LLVM_ATTRIBUTE_UNUSED clearFeature(MCSubtargetInfo *STI, uint64_t F)
static StringRef DefaultArch
declare void exit(i32) noreturn nounwind This compiles into
static MCTargetStreamer * createHexagonObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI)
A switch()-like statement whose cases are string literals.
FeatureBitset completeHVXFeatures(const FeatureBitset &FB)
void HexagonMCEmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment, unsigned AccessSize)
#define HEXAGON_PACKET_SIZE
LLVM_NODISCARD size_t size() const
size - Get the string size.
MCAsmBackend * createHexagonAsmBackend(const Target &T, const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, const MCTargetOptions &Options)
Generic base class for all target subtargets.
LLVM Value Representation.
void HexagonMCEmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment, unsigned AccessSize)
bool isExtendable(MCInstrInfo const &MCII, MCInst const &MCI)