blob: a907cdd0562d38c08fc0c3593b699e1be4cd0bed [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 Zelenko58655bb2016-12-17 01:09:05 +000014#include "HexagonTargetStreamer.h"
Colin LeMahieuff062612014-11-20 21:56:35 +000015#include "MCTargetDesc/HexagonInstPrinter.h"
Eugene Zelenko58655bb2016-12-17 01:09:05 +000016#include "MCTargetDesc/HexagonMCAsmInfo.h"
17#include "MCTargetDesc/HexagonMCELFStreamer.h"
18#include "MCTargetDesc/HexagonMCTargetDesc.h"
19#include "llvm/ADT/StringRef.h"
Colin LeMahieube99a022015-06-17 03:06:16 +000020#include "llvm/MC/MCContext.h"
Eugene Zelenko58655bb2016-12-17 01:09:05 +000021#include "llvm/MC/MCDwarf.h"
Colin LeMahieu2c769202014-11-06 17:05:51 +000022#include "llvm/MC/MCELFStreamer.h"
Tony Linthicumb3705e02011-12-15 22:29:08 +000023#include "llvm/MC/MCInstrInfo.h"
24#include "llvm/MC/MCRegisterInfo.h"
Jyotsna Verma7503a622013-02-20 16:13:27 +000025#include "llvm/MC/MCStreamer.h"
Tony Linthicumb3705e02011-12-15 22:29:08 +000026#include "llvm/MC/MCSubtargetInfo.h"
Colin LeMahieube99a022015-06-17 03:06:16 +000027#include "llvm/Support/ELF.h"
Craig Topperc4965bc2012-02-05 07:21:30 +000028#include "llvm/Support/ErrorHandling.h"
Eugene Zelenko58655bb2016-12-17 01:09:05 +000029#include "llvm/Support/raw_ostream.h"
Tony Linthicumb3705e02011-12-15 22:29:08 +000030#include "llvm/Support/TargetRegistry.h"
Eugene Zelenko58655bb2016-12-17 01:09:05 +000031#include <cassert>
32#include <cstdint>
33#include <new>
34#include <string>
Tony Linthicumb3705e02011-12-15 22:29:08 +000035
Chandler Carruthd174b722014-04-22 02:03:14 +000036using namespace llvm;
37
Tony Linthicumb3705e02011-12-15 22:29:08 +000038#define GET_INSTRINFO_MC_DESC
39#include "HexagonGenInstrInfo.inc"
40
41#define GET_SUBTARGETINFO_MC_DESC
42#include "HexagonGenSubtargetInfo.inc"
43
44#define GET_REGINFO_MC_DESC
45#include "HexagonGenRegisterInfo.inc"
46
Colin LeMahieu7cd08922015-11-09 04:07:48 +000047cl::opt<bool> llvm::HexagonDisableCompound
48 ("mno-compound",
49 cl::desc("Disable looking for compound instructions for Hexagon"));
50
51cl::opt<bool> llvm::HexagonDisableDuplex
52 ("mno-pairing",
53 cl::desc("Disable looking for duplex instructions for Hexagon"));
54
Krzysztof Parzyszek64d4e2b2016-04-20 21:17:40 +000055static cl::opt<bool> HexagonV4ArchVariant("mv4", cl::Hidden, cl::init(false),
56 cl::desc("Build for Hexagon V4"));
57
58static cl::opt<bool> HexagonV5ArchVariant("mv5", cl::Hidden, cl::init(false),
59 cl::desc("Build for Hexagon V5"));
60
61static cl::opt<bool> HexagonV55ArchVariant("mv55", cl::Hidden, cl::init(false),
62 cl::desc("Build for Hexagon V55"));
63
64static cl::opt<bool> HexagonV60ArchVariant("mv60", cl::Hidden, cl::init(false),
65 cl::desc("Build for Hexagon V60"));
66
Krzysztof Parzyszek64d4e2b2016-04-20 21:17:40 +000067static StringRef DefaultArch = "hexagonv60";
68
69static StringRef HexagonGetArchVariant() {
70 if (HexagonV4ArchVariant)
71 return "hexagonv4";
72 if (HexagonV5ArchVariant)
73 return "hexagonv5";
74 if (HexagonV55ArchVariant)
75 return "hexagonv55";
76 if (HexagonV60ArchVariant)
77 return "hexagonv60";
78 return "";
79}
80
Krzysztof Parzyszek75e74ee2016-08-19 14:09:47 +000081StringRef Hexagon_MC::selectHexagonCPU(const Triple &TT, StringRef CPU) {
Krzysztof Parzyszek64d4e2b2016-04-20 21:17:40 +000082 StringRef ArchV = HexagonGetArchVariant();
83 if (!ArchV.empty() && !CPU.empty()) {
84 if (ArchV != CPU)
85 report_fatal_error("conflicting architectures specified.");
86 return CPU;
87 }
88 if (ArchV.empty()) {
89 if (CPU.empty())
90 CPU = DefaultArch;
91 return CPU;
92 }
93 return ArchV;
Krzysztof Parzyszek759a7d02015-12-14 15:03:54 +000094}
95
Colin LeMahieuf08a3cc2015-02-19 17:38:39 +000096MCInstrInfo *llvm::createHexagonMCInstrInfo() {
Tony Linthicumb3705e02011-12-15 22:29:08 +000097 MCInstrInfo *X = new MCInstrInfo();
98 InitHexagonMCInstrInfo(X);
99 return X;
100}
101
Daniel Sanders50f17232015-09-15 16:17:27 +0000102static MCRegisterInfo *createHexagonMCRegisterInfo(const Triple &TT) {
Tony Linthicumb3705e02011-12-15 22:29:08 +0000103 MCRegisterInfo *X = new MCRegisterInfo();
Krzysztof Parzyszek3e282292016-04-25 21:05:19 +0000104 InitHexagonMCRegisterInfo(X, Hexagon::R31);
Tony Linthicumb3705e02011-12-15 22:29:08 +0000105 return X;
106}
107
Daniel Sanders50f17232015-09-15 16:17:27 +0000108static MCSubtargetInfo *
109createHexagonMCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS) {
Krzysztof Parzyszek75e74ee2016-08-19 14:09:47 +0000110 CPU = Hexagon_MC::selectHexagonCPU(TT, CPU);
Krzysztof Parzyszek759a7d02015-12-14 15:03:54 +0000111 return createHexagonMCSubtargetInfoImpl(TT, CPU, FS);
Tony Linthicumb3705e02011-12-15 22:29:08 +0000112}
113
Colin LeMahieube99a022015-06-17 03:06:16 +0000114namespace {
Eugene Zelenko58655bb2016-12-17 01:09:05 +0000115
Colin LeMahieud2158752015-06-18 20:43:50 +0000116class HexagonTargetAsmStreamer : public HexagonTargetStreamer {
Colin LeMahieud2158752015-06-18 20:43:50 +0000117public:
118 HexagonTargetAsmStreamer(MCStreamer &S,
Colin LeMahieufa389722015-06-18 21:03:13 +0000119 formatted_raw_ostream &, bool,
120 MCInstPrinter &)
121 : HexagonTargetStreamer(S) {}
Eugene Zelenko58655bb2016-12-17 01:09:05 +0000122
Colin LeMahieud2158752015-06-18 20:43:50 +0000123 void prettyPrintAsm(MCInstPrinter &InstPrinter, raw_ostream &OS,
124 const MCInst &Inst, const MCSubtargetInfo &STI) override {
125 assert(HexagonMCInstrInfo::isBundle(Inst));
126 assert(HexagonMCInstrInfo::bundleSize(Inst) <= HEXAGON_PACKET_SIZE);
127 std::string Buffer;
128 {
129 raw_string_ostream TempStream(Buffer);
130 InstPrinter.printInst(&Inst, TempStream, "", STI);
131 }
132 StringRef Contents(Buffer);
133 auto PacketBundle = Contents.rsplit('\n');
134 auto HeadTail = PacketBundle.first.split('\n');
Colin LeMahieub7a5f9f2015-11-10 00:22:00 +0000135 StringRef Separator = "\n";
136 StringRef Indent = "\t\t";
137 OS << "\t{\n";
138 while (!HeadTail.first.empty()) {
139 StringRef InstTxt;
Colin LeMahieud2158752015-06-18 20:43:50 +0000140 auto Duplex = HeadTail.first.split('\v');
Colin LeMahieub7a5f9f2015-11-10 00:22:00 +0000141 if (!Duplex.second.empty()) {
142 OS << Indent << Duplex.first << Separator;
143 InstTxt = Duplex.second;
144 } else if (!HeadTail.first.trim().startswith("immext")) {
145 InstTxt = Duplex.first;
Colin LeMahieud2158752015-06-18 20:43:50 +0000146 }
Colin LeMahieub7a5f9f2015-11-10 00:22:00 +0000147 if (!InstTxt.empty())
148 OS << Indent << InstTxt << Separator;
Colin LeMahieud2158752015-06-18 20:43:50 +0000149 HeadTail = HeadTail.second.split('\n');
Colin LeMahieud2158752015-06-18 20:43:50 +0000150 }
Colin LeMahieub7a5f9f2015-11-10 00:22:00 +0000151 OS << "\t}" << PacketBundle.second;
Colin LeMahieud2158752015-06-18 20:43:50 +0000152 }
153};
Colin LeMahieud2158752015-06-18 20:43:50 +0000154
Colin LeMahieube99a022015-06-17 03:06:16 +0000155class HexagonTargetELFStreamer : public HexagonTargetStreamer {
156public:
Colin LeMahieube99a022015-06-17 03:06:16 +0000157 HexagonTargetELFStreamer(MCStreamer &S, MCSubtargetInfo const &STI)
158 : HexagonTargetStreamer(S) {
159 auto Bits = STI.getFeatureBits();
Krzysztof Parzyszeke6ee4812016-04-25 12:49:47 +0000160 unsigned Flags = 0;
161 if (Bits[Hexagon::ArchV60])
162 Flags = ELF::EF_HEXAGON_MACH_V60;
163 else if (Bits[Hexagon::ArchV55])
164 Flags = ELF::EF_HEXAGON_MACH_V55;
165 else if (Bits[Hexagon::ArchV5])
Colin LeMahieube99a022015-06-17 03:06:16 +0000166 Flags = ELF::EF_HEXAGON_MACH_V5;
Krzysztof Parzyszeke6ee4812016-04-25 12:49:47 +0000167 else if (Bits[Hexagon::ArchV4])
Colin LeMahieube99a022015-06-17 03:06:16 +0000168 Flags = ELF::EF_HEXAGON_MACH_V4;
169 getStreamer().getAssembler().setELFHeaderEFlags(Flags);
170 }
Eugene Zelenko58655bb2016-12-17 01:09:05 +0000171
172 MCELFStreamer &getStreamer() {
173 return static_cast<MCELFStreamer &>(Streamer);
174 }
175
Colin LeMahieube99a022015-06-17 03:06:16 +0000176 void EmitCommonSymbolSorted(MCSymbol *Symbol, uint64_t Size,
177 unsigned ByteAlignment,
178 unsigned AccessSize) override {
179 HexagonMCELFStreamer &HexagonELFStreamer =
180 static_cast<HexagonMCELFStreamer &>(getStreamer());
181 HexagonELFStreamer.HexagonMCEmitCommonSymbol(Symbol, Size, ByteAlignment,
182 AccessSize);
183 }
Eugene Zelenko58655bb2016-12-17 01:09:05 +0000184
Colin LeMahieube99a022015-06-17 03:06:16 +0000185 void EmitLocalCommonSymbolSorted(MCSymbol *Symbol, uint64_t Size,
186 unsigned ByteAlignment,
187 unsigned AccessSize) override {
188 HexagonMCELFStreamer &HexagonELFStreamer =
189 static_cast<HexagonMCELFStreamer &>(getStreamer());
190 HexagonELFStreamer.HexagonMCEmitLocalCommonSymbol(
191 Symbol, Size, ByteAlignment, AccessSize);
192 }
193};
Eugene Zelenko58655bb2016-12-17 01:09:05 +0000194
195} // end anonymous namespace
Colin LeMahieube99a022015-06-17 03:06:16 +0000196
Rafael Espindola227144c2013-05-13 01:16:13 +0000197static MCAsmInfo *createHexagonMCAsmInfo(const MCRegisterInfo &MRI,
Daniel Sanders50f17232015-09-15 16:17:27 +0000198 const Triple &TT) {
Rafael Espindola140a8372013-05-10 18:16:59 +0000199 MCAsmInfo *MAI = new HexagonMCAsmInfo(TT);
Tony Linthicumb3705e02011-12-15 22:29:08 +0000200
201 // VirtualFP = (R30 + #0).
Sid Manning7da3f9a2014-10-03 13:18:11 +0000202 MCCFIInstruction Inst =
203 MCCFIInstruction::createDefCfa(nullptr, Hexagon::R30, 0);
Rafael Espindola227144c2013-05-13 01:16:13 +0000204 MAI->addInitialFrameState(Inst);
Tony Linthicumb3705e02011-12-15 22:29:08 +0000205
206 return MAI;
207}
208
Daniel Sanders50f17232015-09-15 16:17:27 +0000209static MCInstPrinter *createHexagonMCInstPrinter(const Triple &T,
Eric Christopherf8019402015-03-31 00:10:04 +0000210 unsigned SyntaxVariant,
Sid Manning12cd21a2014-10-15 18:27:40 +0000211 const MCAsmInfo &MAI,
212 const MCInstrInfo &MII,
Eric Christopherf8019402015-03-31 00:10:04 +0000213 const MCRegisterInfo &MRI) {
Eric Christopherfbe80f52015-04-09 19:20:37 +0000214 if (SyntaxVariant == 0)
Colin LeMahieube99a022015-06-17 03:06:16 +0000215 return (new HexagonInstPrinter(MAI, MII, MRI));
Eric Christopherfbe80f52015-04-09 19:20:37 +0000216 else
Colin LeMahieube99a022015-06-17 03:06:16 +0000217 return nullptr;
218}
219
Benjamin Kramere7800ca2015-06-23 14:51:40 +0000220static MCTargetStreamer *createMCAsmTargetStreamer(MCStreamer &S,
221 formatted_raw_ostream &OS,
222 MCInstPrinter *InstPrint,
223 bool IsVerboseAsm) {
Colin LeMahieud2158752015-06-18 20:43:50 +0000224 return new HexagonTargetAsmStreamer(S, OS, IsVerboseAsm, *InstPrint);
225}
226
Daniel Sanders50f17232015-09-15 16:17:27 +0000227static MCStreamer *createMCStreamer(Triple const &T, MCContext &Context,
Colin LeMahieube99a022015-06-17 03:06:16 +0000228 MCAsmBackend &MAB, raw_pwrite_stream &OS,
229 MCCodeEmitter *Emitter, bool RelaxAll) {
230 return createHexagonELFStreamer(Context, MAB, OS, Emitter);
231}
232
233static MCTargetStreamer *
234createHexagonObjectTargetStreamer(MCStreamer &S, MCSubtargetInfo const &STI) {
235 return new HexagonTargetELFStreamer(S, STI);
Sid Manning12cd21a2014-10-15 18:27:40 +0000236}
Tony Linthicumb3705e02011-12-15 22:29:08 +0000237
238// Force static initialization.
239extern "C" void LLVMInitializeHexagonTargetMC() {
240 // Register the MC asm info.
Mehdi Aminif42454b2016-10-09 23:00:34 +0000241 RegisterMCAsmInfoFn X(getTheHexagonTarget(), createHexagonMCAsmInfo);
Tony Linthicumb3705e02011-12-15 22:29:08 +0000242
Tony Linthicumb3705e02011-12-15 22:29:08 +0000243 // Register the MC instruction info.
Mehdi Aminif42454b2016-10-09 23:00:34 +0000244 TargetRegistry::RegisterMCInstrInfo(getTheHexagonTarget(),
Sid Manning7da3f9a2014-10-03 13:18:11 +0000245 createHexagonMCInstrInfo);
Tony Linthicumb3705e02011-12-15 22:29:08 +0000246
247 // Register the MC register info.
Mehdi Aminif42454b2016-10-09 23:00:34 +0000248 TargetRegistry::RegisterMCRegInfo(getTheHexagonTarget(),
Tony Linthicumb3705e02011-12-15 22:29:08 +0000249 createHexagonMCRegisterInfo);
250
251 // Register the MC subtarget info.
Mehdi Aminif42454b2016-10-09 23:00:34 +0000252 TargetRegistry::RegisterMCSubtargetInfo(getTheHexagonTarget(),
Tony Linthicumb3705e02011-12-15 22:29:08 +0000253 createHexagonMCSubtargetInfo);
Sid Manning7da3f9a2014-10-03 13:18:11 +0000254
255 // Register the MC Code Emitter
Mehdi Aminif42454b2016-10-09 23:00:34 +0000256 TargetRegistry::RegisterMCCodeEmitter(getTheHexagonTarget(),
Sid Manning7da3f9a2014-10-03 13:18:11 +0000257 createHexagonMCCodeEmitter);
Sid Manning12cd21a2014-10-15 18:27:40 +0000258
Colin LeMahieua6750772015-06-03 17:34:16 +0000259 // Register the asm backend
Mehdi Aminif42454b2016-10-09 23:00:34 +0000260 TargetRegistry::RegisterMCAsmBackend(getTheHexagonTarget(),
Colin LeMahieua6750772015-06-03 17:34:16 +0000261 createHexagonAsmBackend);
262
Colin LeMahieube99a022015-06-17 03:06:16 +0000263 // Register the obj streamer
Mehdi Aminif42454b2016-10-09 23:00:34 +0000264 TargetRegistry::RegisterELFStreamer(getTheHexagonTarget(), createMCStreamer);
Colin LeMahieube99a022015-06-17 03:06:16 +0000265
Colin LeMahieud2158752015-06-18 20:43:50 +0000266 // Register the asm streamer
Mehdi Aminif42454b2016-10-09 23:00:34 +0000267 TargetRegistry::RegisterAsmTargetStreamer(getTheHexagonTarget(),
Colin LeMahieud2158752015-06-18 20:43:50 +0000268 createMCAsmTargetStreamer);
269
Sid Manning12cd21a2014-10-15 18:27:40 +0000270 // Register the MC Inst Printer
Mehdi Aminif42454b2016-10-09 23:00:34 +0000271 TargetRegistry::RegisterMCInstPrinter(getTheHexagonTarget(),
Sid Manning12cd21a2014-10-15 18:27:40 +0000272 createHexagonMCInstPrinter);
Colin LeMahieube99a022015-06-17 03:06:16 +0000273
274 TargetRegistry::RegisterObjectTargetStreamer(
Mehdi Aminif42454b2016-10-09 23:00:34 +0000275 getTheHexagonTarget(), createHexagonObjectTargetStreamer);
Tony Linthicumb3705e02011-12-15 22:29:08 +0000276}