blob: 52c61eb6e5d5883ec747ebfab47fe455233fbe8d [file] [log] [blame]
Craig Topperf3f66502012-03-17 09:39:20 +00001//===-- HexagonMCTargetDesc.cpp - Hexagon Target Descriptions -------------===//
Tony Linthicumb3705e02011-12-15 22:29:08 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
Craig Topperbc3168b2012-03-17 09:28:37 +000010// This file provides Hexagon specific target descriptions.
Tony Linthicumb3705e02011-12-15 22:29:08 +000011//
12//===----------------------------------------------------------------------===//
13
Eugene Zelenko401f3812016-12-17 01:29:35 +000014#include "Hexagon.h"
Eugene Zelenko58655bb2016-12-17 01:09:05 +000015#include "HexagonTargetStreamer.h"
Colin LeMahieuff062612014-11-20 21:56:35 +000016#include "MCTargetDesc/HexagonInstPrinter.h"
Eugene Zelenko58655bb2016-12-17 01:09:05 +000017#include "MCTargetDesc/HexagonMCAsmInfo.h"
18#include "MCTargetDesc/HexagonMCELFStreamer.h"
Eugene Zelenko50156892016-12-17 01:17:18 +000019#include "MCTargetDesc/HexagonMCInstrInfo.h"
Eugene Zelenko58655bb2016-12-17 01:09:05 +000020#include "MCTargetDesc/HexagonMCTargetDesc.h"
21#include "llvm/ADT/StringRef.h"
Colin LeMahieube99a022015-06-17 03:06:16 +000022#include "llvm/MC/MCContext.h"
Eugene Zelenko58655bb2016-12-17 01:09:05 +000023#include "llvm/MC/MCDwarf.h"
Colin LeMahieu2c769202014-11-06 17:05:51 +000024#include "llvm/MC/MCELFStreamer.h"
Krzysztof Parzyszek8cdfe8e2017-02-06 19:35:46 +000025#include "llvm/MC/MCInstrAnalysis.h"
Tony Linthicumb3705e02011-12-15 22:29:08 +000026#include "llvm/MC/MCInstrInfo.h"
27#include "llvm/MC/MCRegisterInfo.h"
Jyotsna Verma7503a622013-02-20 16:13:27 +000028#include "llvm/MC/MCStreamer.h"
Tony Linthicumb3705e02011-12-15 22:29:08 +000029#include "llvm/MC/MCSubtargetInfo.h"
Colin LeMahieube99a022015-06-17 03:06:16 +000030#include "llvm/Support/ELF.h"
Craig Topperc4965bc2012-02-05 07:21:30 +000031#include "llvm/Support/ErrorHandling.h"
Eugene Zelenko58655bb2016-12-17 01:09:05 +000032#include "llvm/Support/raw_ostream.h"
Tony Linthicumb3705e02011-12-15 22:29:08 +000033#include "llvm/Support/TargetRegistry.h"
Eugene Zelenko58655bb2016-12-17 01:09:05 +000034#include <cassert>
35#include <cstdint>
36#include <new>
37#include <string>
Tony Linthicumb3705e02011-12-15 22:29:08 +000038
Chandler Carruthd174b722014-04-22 02:03:14 +000039using namespace llvm;
40
Tony Linthicumb3705e02011-12-15 22:29:08 +000041#define GET_INSTRINFO_MC_DESC
42#include "HexagonGenInstrInfo.inc"
43
44#define GET_SUBTARGETINFO_MC_DESC
45#include "HexagonGenSubtargetInfo.inc"
46
47#define GET_REGINFO_MC_DESC
48#include "HexagonGenRegisterInfo.inc"
49
Colin LeMahieu7cd08922015-11-09 04:07:48 +000050cl::opt<bool> llvm::HexagonDisableCompound
51 ("mno-compound",
52 cl::desc("Disable looking for compound instructions for Hexagon"));
53
54cl::opt<bool> llvm::HexagonDisableDuplex
55 ("mno-pairing",
56 cl::desc("Disable looking for duplex instructions for Hexagon"));
57
Krzysztof Parzyszek64d4e2b2016-04-20 21:17:40 +000058static cl::opt<bool> HexagonV4ArchVariant("mv4", cl::Hidden, cl::init(false),
59 cl::desc("Build for Hexagon V4"));
60
61static cl::opt<bool> HexagonV5ArchVariant("mv5", cl::Hidden, cl::init(false),
62 cl::desc("Build for Hexagon V5"));
63
64static cl::opt<bool> HexagonV55ArchVariant("mv55", cl::Hidden, cl::init(false),
65 cl::desc("Build for Hexagon V55"));
66
67static cl::opt<bool> HexagonV60ArchVariant("mv60", cl::Hidden, cl::init(false),
68 cl::desc("Build for Hexagon V60"));
69
Krzysztof Parzyszek64d4e2b2016-04-20 21:17:40 +000070static StringRef DefaultArch = "hexagonv60";
71
72static StringRef HexagonGetArchVariant() {
73 if (HexagonV4ArchVariant)
74 return "hexagonv4";
75 if (HexagonV5ArchVariant)
76 return "hexagonv5";
77 if (HexagonV55ArchVariant)
78 return "hexagonv55";
79 if (HexagonV60ArchVariant)
80 return "hexagonv60";
81 return "";
82}
83
Krzysztof Parzyszek75e74ee2016-08-19 14:09:47 +000084StringRef Hexagon_MC::selectHexagonCPU(const Triple &TT, StringRef CPU) {
Krzysztof Parzyszek64d4e2b2016-04-20 21:17:40 +000085 StringRef ArchV = HexagonGetArchVariant();
86 if (!ArchV.empty() && !CPU.empty()) {
87 if (ArchV != CPU)
88 report_fatal_error("conflicting architectures specified.");
89 return CPU;
90 }
91 if (ArchV.empty()) {
92 if (CPU.empty())
93 CPU = DefaultArch;
94 return CPU;
95 }
96 return ArchV;
Krzysztof Parzyszek759a7d02015-12-14 15:03:54 +000097}
98
Krzysztof Parzyszek8cdfe8e2017-02-06 19:35:46 +000099unsigned HexagonGetLastSlot() {
100 return HexagonItinerariesV4FU::SLOT3;
Tony Linthicumb3705e02011-12-15 22:29:08 +0000101}
102
Tony Linthicumb3705e02011-12-15 22:29:08 +0000103
Colin LeMahieube99a022015-06-17 03:06:16 +0000104namespace {
Eugene Zelenko58655bb2016-12-17 01:09:05 +0000105
Colin LeMahieud2158752015-06-18 20:43:50 +0000106class HexagonTargetAsmStreamer : public HexagonTargetStreamer {
Colin LeMahieud2158752015-06-18 20:43:50 +0000107public:
108 HexagonTargetAsmStreamer(MCStreamer &S,
Krzysztof Parzyszek8cdfe8e2017-02-06 19:35:46 +0000109 formatted_raw_ostream &OS,
110 bool isVerboseAsm,
111 MCInstPrinter &IP)
Colin LeMahieufa389722015-06-18 21:03:13 +0000112 : HexagonTargetStreamer(S) {}
Eugene Zelenko58655bb2016-12-17 01:09:05 +0000113
Colin LeMahieud2158752015-06-18 20:43:50 +0000114 void prettyPrintAsm(MCInstPrinter &InstPrinter, raw_ostream &OS,
115 const MCInst &Inst, const MCSubtargetInfo &STI) override {
116 assert(HexagonMCInstrInfo::isBundle(Inst));
117 assert(HexagonMCInstrInfo::bundleSize(Inst) <= HEXAGON_PACKET_SIZE);
118 std::string Buffer;
119 {
120 raw_string_ostream TempStream(Buffer);
121 InstPrinter.printInst(&Inst, TempStream, "", STI);
122 }
123 StringRef Contents(Buffer);
124 auto PacketBundle = Contents.rsplit('\n');
125 auto HeadTail = PacketBundle.first.split('\n');
Colin LeMahieub7a5f9f2015-11-10 00:22:00 +0000126 StringRef Separator = "\n";
127 StringRef Indent = "\t\t";
128 OS << "\t{\n";
129 while (!HeadTail.first.empty()) {
130 StringRef InstTxt;
Colin LeMahieud2158752015-06-18 20:43:50 +0000131 auto Duplex = HeadTail.first.split('\v');
Colin LeMahieub7a5f9f2015-11-10 00:22:00 +0000132 if (!Duplex.second.empty()) {
133 OS << Indent << Duplex.first << Separator;
134 InstTxt = Duplex.second;
135 } else if (!HeadTail.first.trim().startswith("immext")) {
136 InstTxt = Duplex.first;
Colin LeMahieud2158752015-06-18 20:43:50 +0000137 }
Colin LeMahieub7a5f9f2015-11-10 00:22:00 +0000138 if (!InstTxt.empty())
139 OS << Indent << InstTxt << Separator;
Colin LeMahieud2158752015-06-18 20:43:50 +0000140 HeadTail = HeadTail.second.split('\n');
Colin LeMahieud2158752015-06-18 20:43:50 +0000141 }
Colin LeMahieub7a5f9f2015-11-10 00:22:00 +0000142 OS << "\t}" << PacketBundle.second;
Colin LeMahieud2158752015-06-18 20:43:50 +0000143 }
144};
Colin LeMahieud2158752015-06-18 20:43:50 +0000145
Colin LeMahieube99a022015-06-17 03:06:16 +0000146class HexagonTargetELFStreamer : public HexagonTargetStreamer {
147public:
Eugene Zelenko58655bb2016-12-17 01:09:05 +0000148 MCELFStreamer &getStreamer() {
149 return static_cast<MCELFStreamer &>(Streamer);
150 }
Krzysztof Parzyszek8cdfe8e2017-02-06 19:35:46 +0000151 HexagonTargetELFStreamer(MCStreamer &S, MCSubtargetInfo const &STI)
152 : HexagonTargetStreamer(S) {
153 MCAssembler &MCA = getStreamer().getAssembler();
154 MCA.setELFHeaderEFlags(Hexagon_MC::GetELFFlags(STI));
155 }
156
Eugene Zelenko58655bb2016-12-17 01:09:05 +0000157
Colin LeMahieube99a022015-06-17 03:06:16 +0000158 void EmitCommonSymbolSorted(MCSymbol *Symbol, uint64_t Size,
159 unsigned ByteAlignment,
160 unsigned AccessSize) override {
161 HexagonMCELFStreamer &HexagonELFStreamer =
162 static_cast<HexagonMCELFStreamer &>(getStreamer());
163 HexagonELFStreamer.HexagonMCEmitCommonSymbol(Symbol, Size, ByteAlignment,
164 AccessSize);
165 }
Eugene Zelenko58655bb2016-12-17 01:09:05 +0000166
Colin LeMahieube99a022015-06-17 03:06:16 +0000167 void EmitLocalCommonSymbolSorted(MCSymbol *Symbol, uint64_t Size,
168 unsigned ByteAlignment,
169 unsigned AccessSize) override {
170 HexagonMCELFStreamer &HexagonELFStreamer =
171 static_cast<HexagonMCELFStreamer &>(getStreamer());
172 HexagonELFStreamer.HexagonMCEmitLocalCommonSymbol(
173 Symbol, Size, ByteAlignment, AccessSize);
174 }
175};
Eugene Zelenko58655bb2016-12-17 01:09:05 +0000176
177} // end anonymous namespace
Colin LeMahieube99a022015-06-17 03:06:16 +0000178
Krzysztof Parzyszek8cdfe8e2017-02-06 19:35:46 +0000179llvm::MCInstrInfo *llvm::createHexagonMCInstrInfo() {
180 MCInstrInfo *X = new MCInstrInfo();
181 InitHexagonMCInstrInfo(X);
182 return X;
183}
184
185static MCRegisterInfo *createHexagonMCRegisterInfo(const Triple &TT) {
186 MCRegisterInfo *X = new MCRegisterInfo();
187 InitHexagonMCRegisterInfo(X, Hexagon::R31);
188 return X;
189}
190
Rafael Espindola227144c2013-05-13 01:16:13 +0000191static MCAsmInfo *createHexagonMCAsmInfo(const MCRegisterInfo &MRI,
Daniel Sanders50f17232015-09-15 16:17:27 +0000192 const Triple &TT) {
Rafael Espindola140a8372013-05-10 18:16:59 +0000193 MCAsmInfo *MAI = new HexagonMCAsmInfo(TT);
Tony Linthicumb3705e02011-12-15 22:29:08 +0000194
195 // VirtualFP = (R30 + #0).
Sid Manning7da3f9a2014-10-03 13:18:11 +0000196 MCCFIInstruction Inst =
Krzysztof Parzyszek8cdfe8e2017-02-06 19:35:46 +0000197 MCCFIInstruction::createDefCfa(nullptr,
198 MRI.getDwarfRegNum(Hexagon::R30, true), 0);
Rafael Espindola227144c2013-05-13 01:16:13 +0000199 MAI->addInitialFrameState(Inst);
Tony Linthicumb3705e02011-12-15 22:29:08 +0000200
201 return MAI;
202}
203
Daniel Sanders50f17232015-09-15 16:17:27 +0000204static MCInstPrinter *createHexagonMCInstPrinter(const Triple &T,
Eric Christopherf8019402015-03-31 00:10:04 +0000205 unsigned SyntaxVariant,
Sid Manning12cd21a2014-10-15 18:27:40 +0000206 const MCAsmInfo &MAI,
207 const MCInstrInfo &MII,
Krzysztof Parzyszek8cdfe8e2017-02-06 19:35:46 +0000208 const MCRegisterInfo &MRI)
209{
Eric Christopherfbe80f52015-04-09 19:20:37 +0000210 if (SyntaxVariant == 0)
Krzysztof Parzyszek8cdfe8e2017-02-06 19:35:46 +0000211 return new HexagonInstPrinter(MAI, MII, MRI);
Eric Christopherfbe80f52015-04-09 19:20:37 +0000212 else
Colin LeMahieube99a022015-06-17 03:06:16 +0000213 return nullptr;
214}
215
Krzysztof Parzyszek8cdfe8e2017-02-06 19:35:46 +0000216static MCTargetStreamer *
217createMCAsmTargetStreamer(MCStreamer &S, formatted_raw_ostream &OS,
218 MCInstPrinter *IP, bool IsVerboseAsm) {
219 return new HexagonTargetAsmStreamer(S, OS, IsVerboseAsm, *IP);
Colin LeMahieud2158752015-06-18 20:43:50 +0000220}
221
Krzysztof Parzyszek8cdfe8e2017-02-06 19:35:46 +0000222static MCStreamer *createMCStreamer(Triple const &T,
223 MCContext &Context,
224 MCAsmBackend &MAB,
225 raw_pwrite_stream &OS,
226 MCCodeEmitter *Emitter,
227 bool RelaxAll) {
228 return createHexagonELFStreamer(T, Context, MAB, OS, Emitter);
Colin LeMahieube99a022015-06-17 03:06:16 +0000229}
230
231static MCTargetStreamer *
Krzysztof Parzyszek8cdfe8e2017-02-06 19:35:46 +0000232createHexagonObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) {
Colin LeMahieube99a022015-06-17 03:06:16 +0000233 return new HexagonTargetELFStreamer(S, STI);
Sid Manning12cd21a2014-10-15 18:27:40 +0000234}
Tony Linthicumb3705e02011-12-15 22:29:08 +0000235
Krzysztof Parzyszek8cdfe8e2017-02-06 19:35:46 +0000236static void LLVM_ATTRIBUTE_UNUSED clearFeature(MCSubtargetInfo* STI, uint64_t F) {
237 uint64_t FB = STI->getFeatureBits().to_ullong();
238 if (FB & (1ULL << F))
239 STI->ToggleFeature(F);
240}
241
242static bool LLVM_ATTRIBUTE_UNUSED checkFeature(MCSubtargetInfo* STI, uint64_t F) {
243 uint64_t FB = STI->getFeatureBits().to_ullong();
244 return (FB & (1ULL << F)) != 0;
245}
246
247StringRef Hexagon_MC::ParseHexagonTriple(const Triple &TT, StringRef CPU) {
248 StringRef CPUName = Hexagon_MC::selectHexagonCPU(TT, CPU);
249 StringRef FS = "";
250 if (CPUName.equals_lower("hexagonv60"))
251 FS = "+hvx";
252 return FS;
253}
254
255static bool isCPUValid(std::string CPU)
256{
257 std::vector<std::string> table
258 {
259 "hexagonv4",
260 "hexagonv5",
261 "hexagonv55",
262 "hexagonv60",
263 };
264
265 return std::find(table.begin(), table.end(), CPU) != table.end();
266}
267
268MCSubtargetInfo *Hexagon_MC::createHexagonMCSubtargetInfo(const Triple &TT,
269 StringRef CPU,
270 StringRef FS) {
271 StringRef ArchFS = (FS.size()) ? FS : Hexagon_MC::ParseHexagonTriple(TT, CPU);
272 StringRef CPUName = Hexagon_MC::selectHexagonCPU(TT, CPU);
273 if (!isCPUValid(CPUName.str()))
274 {
275 errs() << "error: invalid CPU \"" << CPUName.str().c_str() << "\" specified\n";
276 return nullptr;
277 }
278
279 MCSubtargetInfo *X = createHexagonMCSubtargetInfoImpl(TT, CPUName, ArchFS);
280 if (X->getFeatureBits()[Hexagon::ExtensionHVXDbl]) {
281 llvm::FeatureBitset Features = X->getFeatureBits();
282 X->setFeatureBits(Features.set(Hexagon::ExtensionHVX));
283 }
284 return X;
285}
286
287unsigned Hexagon_MC::GetELFFlags(const MCSubtargetInfo &STI) {
288 static std::map<StringRef,unsigned> ElfFlags = {
289 {"hexagonv4", ELF::EF_HEXAGON_MACH_V4},
290 {"hexagonv5", ELF::EF_HEXAGON_MACH_V5},
291 {"hexagonv55", ELF::EF_HEXAGON_MACH_V55},
292 {"hexagonv60", ELF::EF_HEXAGON_MACH_V60},
293 };
294
295 auto F = ElfFlags.find(STI.getCPU());
296 assert(F != ElfFlags.end() && "Unrecognized Architecture");
297 return F->second;
298}
299
300namespace {
301class HexagonMCInstrAnalysis : public MCInstrAnalysis {
302public:
303 HexagonMCInstrAnalysis(MCInstrInfo const *Info) : MCInstrAnalysis(Info) {}
304
305 bool isUnconditionalBranch(MCInst const &Inst) const override {
306 //assert(!HexagonMCInstrInfo::isBundle(Inst));
307 return MCInstrAnalysis::isUnconditionalBranch(Inst);
308 }
309
310 bool isConditionalBranch(MCInst const &Inst) const override {
311 //assert(!HexagonMCInstrInfo::isBundle(Inst));
312 return MCInstrAnalysis::isConditionalBranch(Inst);
313 }
314
315 bool evaluateBranch(MCInst const &Inst, uint64_t Addr,
316 uint64_t Size, uint64_t &Target) const override {
317 //assert(!HexagonMCInstrInfo::isBundle(Inst));
318 if(!HexagonMCInstrInfo::isExtendable(*Info, Inst))
319 return false;
320 auto const &Extended(HexagonMCInstrInfo::getExtendableOperand(*Info, Inst));
321 assert(Extended.isExpr());
322 int64_t Value;
323 if(!Extended.getExpr()->evaluateAsAbsolute(Value))
324 return false;
325 Target = Value;
326 return true;
327 }
328};
329}
330
331static MCInstrAnalysis *createHexagonMCInstrAnalysis(const MCInstrInfo *Info) {
332 return new HexagonMCInstrAnalysis(Info);
333}
334
Tony Linthicumb3705e02011-12-15 22:29:08 +0000335// Force static initialization.
336extern "C" void LLVMInitializeHexagonTargetMC() {
337 // Register the MC asm info.
Mehdi Aminif42454b2016-10-09 23:00:34 +0000338 RegisterMCAsmInfoFn X(getTheHexagonTarget(), createHexagonMCAsmInfo);
Tony Linthicumb3705e02011-12-15 22:29:08 +0000339
Tony Linthicumb3705e02011-12-15 22:29:08 +0000340 // Register the MC instruction info.
Mehdi Aminif42454b2016-10-09 23:00:34 +0000341 TargetRegistry::RegisterMCInstrInfo(getTheHexagonTarget(),
Sid Manning7da3f9a2014-10-03 13:18:11 +0000342 createHexagonMCInstrInfo);
Tony Linthicumb3705e02011-12-15 22:29:08 +0000343
344 // Register the MC register info.
Mehdi Aminif42454b2016-10-09 23:00:34 +0000345 TargetRegistry::RegisterMCRegInfo(getTheHexagonTarget(),
Tony Linthicumb3705e02011-12-15 22:29:08 +0000346 createHexagonMCRegisterInfo);
347
348 // Register the MC subtarget info.
Mehdi Aminif42454b2016-10-09 23:00:34 +0000349 TargetRegistry::RegisterMCSubtargetInfo(getTheHexagonTarget(),
Krzysztof Parzyszek8cdfe8e2017-02-06 19:35:46 +0000350 Hexagon_MC::createHexagonMCSubtargetInfo);
Sid Manning7da3f9a2014-10-03 13:18:11 +0000351
352 // Register the MC Code Emitter
Mehdi Aminif42454b2016-10-09 23:00:34 +0000353 TargetRegistry::RegisterMCCodeEmitter(getTheHexagonTarget(),
Sid Manning7da3f9a2014-10-03 13:18:11 +0000354 createHexagonMCCodeEmitter);
Sid Manning12cd21a2014-10-15 18:27:40 +0000355
Colin LeMahieua6750772015-06-03 17:34:16 +0000356 // Register the asm backend
Mehdi Aminif42454b2016-10-09 23:00:34 +0000357 TargetRegistry::RegisterMCAsmBackend(getTheHexagonTarget(),
Colin LeMahieua6750772015-06-03 17:34:16 +0000358 createHexagonAsmBackend);
359
Krzysztof Parzyszek8cdfe8e2017-02-06 19:35:46 +0000360
361 // Register the MC instruction analyzer.
362 TargetRegistry::RegisterMCInstrAnalysis(getTheHexagonTarget(),
363 createHexagonMCInstrAnalysis);
364
Colin LeMahieube99a022015-06-17 03:06:16 +0000365 // Register the obj streamer
Krzysztof Parzyszek8cdfe8e2017-02-06 19:35:46 +0000366 TargetRegistry::RegisterELFStreamer(getTheHexagonTarget(),
367 createMCStreamer);
368
369 // Register the obj target streamer
370 TargetRegistry::RegisterObjectTargetStreamer(getTheHexagonTarget(),
371 createHexagonObjectTargetStreamer);
Colin LeMahieube99a022015-06-17 03:06:16 +0000372
Colin LeMahieud2158752015-06-18 20:43:50 +0000373 // Register the asm streamer
Mehdi Aminif42454b2016-10-09 23:00:34 +0000374 TargetRegistry::RegisterAsmTargetStreamer(getTheHexagonTarget(),
Colin LeMahieud2158752015-06-18 20:43:50 +0000375 createMCAsmTargetStreamer);
376
Sid Manning12cd21a2014-10-15 18:27:40 +0000377 // Register the MC Inst Printer
Mehdi Aminif42454b2016-10-09 23:00:34 +0000378 TargetRegistry::RegisterMCInstPrinter(getTheHexagonTarget(),
Sid Manning12cd21a2014-10-15 18:27:40 +0000379 createHexagonMCInstPrinter);
Tony Linthicumb3705e02011-12-15 22:29:08 +0000380}