blob: def420de1989db1fadb9d8b5a8c09c5edc97a055 [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"
Eugene Zelenko50156892016-12-17 01:17:18 +000018#include "MCTargetDesc/HexagonMCInstrInfo.h"
Eugene Zelenko58655bb2016-12-17 01:09:05 +000019#include "MCTargetDesc/HexagonMCTargetDesc.h"
20#include "llvm/ADT/StringRef.h"
Colin LeMahieube99a022015-06-17 03:06:16 +000021#include "llvm/MC/MCContext.h"
Eugene Zelenko58655bb2016-12-17 01:09:05 +000022#include "llvm/MC/MCDwarf.h"
Colin LeMahieu2c769202014-11-06 17:05:51 +000023#include "llvm/MC/MCELFStreamer.h"
Tony Linthicumb3705e02011-12-15 22:29:08 +000024#include "llvm/MC/MCInstrInfo.h"
25#include "llvm/MC/MCRegisterInfo.h"
Jyotsna Verma7503a622013-02-20 16:13:27 +000026#include "llvm/MC/MCStreamer.h"
Tony Linthicumb3705e02011-12-15 22:29:08 +000027#include "llvm/MC/MCSubtargetInfo.h"
Colin LeMahieube99a022015-06-17 03:06:16 +000028#include "llvm/Support/ELF.h"
Craig Topperc4965bc2012-02-05 07:21:30 +000029#include "llvm/Support/ErrorHandling.h"
Eugene Zelenko58655bb2016-12-17 01:09:05 +000030#include "llvm/Support/raw_ostream.h"
Tony Linthicumb3705e02011-12-15 22:29:08 +000031#include "llvm/Support/TargetRegistry.h"
Eugene Zelenko58655bb2016-12-17 01:09:05 +000032#include <cassert>
33#include <cstdint>
34#include <new>
35#include <string>
Tony Linthicumb3705e02011-12-15 22:29:08 +000036
Chandler Carruthd174b722014-04-22 02:03:14 +000037using namespace llvm;
38
Tony Linthicumb3705e02011-12-15 22:29:08 +000039#define GET_INSTRINFO_MC_DESC
40#include "HexagonGenInstrInfo.inc"
41
42#define GET_SUBTARGETINFO_MC_DESC
43#include "HexagonGenSubtargetInfo.inc"
44
45#define GET_REGINFO_MC_DESC
46#include "HexagonGenRegisterInfo.inc"
47
Colin LeMahieu7cd08922015-11-09 04:07:48 +000048cl::opt<bool> llvm::HexagonDisableCompound
49 ("mno-compound",
50 cl::desc("Disable looking for compound instructions for Hexagon"));
51
52cl::opt<bool> llvm::HexagonDisableDuplex
53 ("mno-pairing",
54 cl::desc("Disable looking for duplex instructions for Hexagon"));
55
Krzysztof Parzyszek64d4e2b2016-04-20 21:17:40 +000056static cl::opt<bool> HexagonV4ArchVariant("mv4", cl::Hidden, cl::init(false),
57 cl::desc("Build for Hexagon V4"));
58
59static cl::opt<bool> HexagonV5ArchVariant("mv5", cl::Hidden, cl::init(false),
60 cl::desc("Build for Hexagon V5"));
61
62static cl::opt<bool> HexagonV55ArchVariant("mv55", cl::Hidden, cl::init(false),
63 cl::desc("Build for Hexagon V55"));
64
65static cl::opt<bool> HexagonV60ArchVariant("mv60", cl::Hidden, cl::init(false),
66 cl::desc("Build for Hexagon V60"));
67
Krzysztof Parzyszek64d4e2b2016-04-20 21:17:40 +000068static StringRef DefaultArch = "hexagonv60";
69
70static StringRef HexagonGetArchVariant() {
71 if (HexagonV4ArchVariant)
72 return "hexagonv4";
73 if (HexagonV5ArchVariant)
74 return "hexagonv5";
75 if (HexagonV55ArchVariant)
76 return "hexagonv55";
77 if (HexagonV60ArchVariant)
78 return "hexagonv60";
79 return "";
80}
81
Krzysztof Parzyszek75e74ee2016-08-19 14:09:47 +000082StringRef Hexagon_MC::selectHexagonCPU(const Triple &TT, StringRef CPU) {
Krzysztof Parzyszek64d4e2b2016-04-20 21:17:40 +000083 StringRef ArchV = HexagonGetArchVariant();
84 if (!ArchV.empty() && !CPU.empty()) {
85 if (ArchV != CPU)
86 report_fatal_error("conflicting architectures specified.");
87 return CPU;
88 }
89 if (ArchV.empty()) {
90 if (CPU.empty())
91 CPU = DefaultArch;
92 return CPU;
93 }
94 return ArchV;
Krzysztof Parzyszek759a7d02015-12-14 15:03:54 +000095}
96
Colin LeMahieuf08a3cc2015-02-19 17:38:39 +000097MCInstrInfo *llvm::createHexagonMCInstrInfo() {
Tony Linthicumb3705e02011-12-15 22:29:08 +000098 MCInstrInfo *X = new MCInstrInfo();
99 InitHexagonMCInstrInfo(X);
100 return X;
101}
102
Daniel Sanders50f17232015-09-15 16:17:27 +0000103static MCRegisterInfo *createHexagonMCRegisterInfo(const Triple &TT) {
Tony Linthicumb3705e02011-12-15 22:29:08 +0000104 MCRegisterInfo *X = new MCRegisterInfo();
Krzysztof Parzyszek3e282292016-04-25 21:05:19 +0000105 InitHexagonMCRegisterInfo(X, Hexagon::R31);
Tony Linthicumb3705e02011-12-15 22:29:08 +0000106 return X;
107}
108
Daniel Sanders50f17232015-09-15 16:17:27 +0000109static MCSubtargetInfo *
110createHexagonMCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS) {
Krzysztof Parzyszek75e74ee2016-08-19 14:09:47 +0000111 CPU = Hexagon_MC::selectHexagonCPU(TT, CPU);
Krzysztof Parzyszek759a7d02015-12-14 15:03:54 +0000112 return createHexagonMCSubtargetInfoImpl(TT, CPU, FS);
Tony Linthicumb3705e02011-12-15 22:29:08 +0000113}
114
Colin LeMahieube99a022015-06-17 03:06:16 +0000115namespace {
Eugene Zelenko58655bb2016-12-17 01:09:05 +0000116
Colin LeMahieud2158752015-06-18 20:43:50 +0000117class HexagonTargetAsmStreamer : public HexagonTargetStreamer {
Colin LeMahieud2158752015-06-18 20:43:50 +0000118public:
119 HexagonTargetAsmStreamer(MCStreamer &S,
Colin LeMahieufa389722015-06-18 21:03:13 +0000120 formatted_raw_ostream &, bool,
121 MCInstPrinter &)
122 : HexagonTargetStreamer(S) {}
Eugene Zelenko58655bb2016-12-17 01:09:05 +0000123
Colin LeMahieud2158752015-06-18 20:43:50 +0000124 void prettyPrintAsm(MCInstPrinter &InstPrinter, raw_ostream &OS,
125 const MCInst &Inst, const MCSubtargetInfo &STI) override {
126 assert(HexagonMCInstrInfo::isBundle(Inst));
127 assert(HexagonMCInstrInfo::bundleSize(Inst) <= HEXAGON_PACKET_SIZE);
128 std::string Buffer;
129 {
130 raw_string_ostream TempStream(Buffer);
131 InstPrinter.printInst(&Inst, TempStream, "", STI);
132 }
133 StringRef Contents(Buffer);
134 auto PacketBundle = Contents.rsplit('\n');
135 auto HeadTail = PacketBundle.first.split('\n');
Colin LeMahieub7a5f9f2015-11-10 00:22:00 +0000136 StringRef Separator = "\n";
137 StringRef Indent = "\t\t";
138 OS << "\t{\n";
139 while (!HeadTail.first.empty()) {
140 StringRef InstTxt;
Colin LeMahieud2158752015-06-18 20:43:50 +0000141 auto Duplex = HeadTail.first.split('\v');
Colin LeMahieub7a5f9f2015-11-10 00:22:00 +0000142 if (!Duplex.second.empty()) {
143 OS << Indent << Duplex.first << Separator;
144 InstTxt = Duplex.second;
145 } else if (!HeadTail.first.trim().startswith("immext")) {
146 InstTxt = Duplex.first;
Colin LeMahieud2158752015-06-18 20:43:50 +0000147 }
Colin LeMahieub7a5f9f2015-11-10 00:22:00 +0000148 if (!InstTxt.empty())
149 OS << Indent << InstTxt << Separator;
Colin LeMahieud2158752015-06-18 20:43:50 +0000150 HeadTail = HeadTail.second.split('\n');
Colin LeMahieud2158752015-06-18 20:43:50 +0000151 }
Colin LeMahieub7a5f9f2015-11-10 00:22:00 +0000152 OS << "\t}" << PacketBundle.second;
Colin LeMahieud2158752015-06-18 20:43:50 +0000153 }
154};
Colin LeMahieud2158752015-06-18 20:43:50 +0000155
Colin LeMahieube99a022015-06-17 03:06:16 +0000156class HexagonTargetELFStreamer : public HexagonTargetStreamer {
157public:
Colin LeMahieube99a022015-06-17 03:06:16 +0000158 HexagonTargetELFStreamer(MCStreamer &S, MCSubtargetInfo const &STI)
159 : HexagonTargetStreamer(S) {
160 auto Bits = STI.getFeatureBits();
Krzysztof Parzyszeke6ee4812016-04-25 12:49:47 +0000161 unsigned Flags = 0;
162 if (Bits[Hexagon::ArchV60])
163 Flags = ELF::EF_HEXAGON_MACH_V60;
164 else if (Bits[Hexagon::ArchV55])
165 Flags = ELF::EF_HEXAGON_MACH_V55;
166 else if (Bits[Hexagon::ArchV5])
Colin LeMahieube99a022015-06-17 03:06:16 +0000167 Flags = ELF::EF_HEXAGON_MACH_V5;
Krzysztof Parzyszeke6ee4812016-04-25 12:49:47 +0000168 else if (Bits[Hexagon::ArchV4])
Colin LeMahieube99a022015-06-17 03:06:16 +0000169 Flags = ELF::EF_HEXAGON_MACH_V4;
170 getStreamer().getAssembler().setELFHeaderEFlags(Flags);
171 }
Eugene Zelenko58655bb2016-12-17 01:09:05 +0000172
173 MCELFStreamer &getStreamer() {
174 return static_cast<MCELFStreamer &>(Streamer);
175 }
176
Colin LeMahieube99a022015-06-17 03:06:16 +0000177 void EmitCommonSymbolSorted(MCSymbol *Symbol, uint64_t Size,
178 unsigned ByteAlignment,
179 unsigned AccessSize) override {
180 HexagonMCELFStreamer &HexagonELFStreamer =
181 static_cast<HexagonMCELFStreamer &>(getStreamer());
182 HexagonELFStreamer.HexagonMCEmitCommonSymbol(Symbol, Size, ByteAlignment,
183 AccessSize);
184 }
Eugene Zelenko58655bb2016-12-17 01:09:05 +0000185
Colin LeMahieube99a022015-06-17 03:06:16 +0000186 void EmitLocalCommonSymbolSorted(MCSymbol *Symbol, uint64_t Size,
187 unsigned ByteAlignment,
188 unsigned AccessSize) override {
189 HexagonMCELFStreamer &HexagonELFStreamer =
190 static_cast<HexagonMCELFStreamer &>(getStreamer());
191 HexagonELFStreamer.HexagonMCEmitLocalCommonSymbol(
192 Symbol, Size, ByteAlignment, AccessSize);
193 }
194};
Eugene Zelenko58655bb2016-12-17 01:09:05 +0000195
196} // end anonymous namespace
Colin LeMahieube99a022015-06-17 03:06:16 +0000197
Rafael Espindola227144c2013-05-13 01:16:13 +0000198static MCAsmInfo *createHexagonMCAsmInfo(const MCRegisterInfo &MRI,
Daniel Sanders50f17232015-09-15 16:17:27 +0000199 const Triple &TT) {
Rafael Espindola140a8372013-05-10 18:16:59 +0000200 MCAsmInfo *MAI = new HexagonMCAsmInfo(TT);
Tony Linthicumb3705e02011-12-15 22:29:08 +0000201
202 // VirtualFP = (R30 + #0).
Sid Manning7da3f9a2014-10-03 13:18:11 +0000203 MCCFIInstruction Inst =
204 MCCFIInstruction::createDefCfa(nullptr, Hexagon::R30, 0);
Rafael Espindola227144c2013-05-13 01:16:13 +0000205 MAI->addInitialFrameState(Inst);
Tony Linthicumb3705e02011-12-15 22:29:08 +0000206
207 return MAI;
208}
209
Daniel Sanders50f17232015-09-15 16:17:27 +0000210static MCInstPrinter *createHexagonMCInstPrinter(const Triple &T,
Eric Christopherf8019402015-03-31 00:10:04 +0000211 unsigned SyntaxVariant,
Sid Manning12cd21a2014-10-15 18:27:40 +0000212 const MCAsmInfo &MAI,
213 const MCInstrInfo &MII,
Eric Christopherf8019402015-03-31 00:10:04 +0000214 const MCRegisterInfo &MRI) {
Eric Christopherfbe80f52015-04-09 19:20:37 +0000215 if (SyntaxVariant == 0)
Colin LeMahieube99a022015-06-17 03:06:16 +0000216 return (new HexagonInstPrinter(MAI, MII, MRI));
Eric Christopherfbe80f52015-04-09 19:20:37 +0000217 else
Colin LeMahieube99a022015-06-17 03:06:16 +0000218 return nullptr;
219}
220
Benjamin Kramere7800ca2015-06-23 14:51:40 +0000221static MCTargetStreamer *createMCAsmTargetStreamer(MCStreamer &S,
222 formatted_raw_ostream &OS,
223 MCInstPrinter *InstPrint,
224 bool IsVerboseAsm) {
Colin LeMahieud2158752015-06-18 20:43:50 +0000225 return new HexagonTargetAsmStreamer(S, OS, IsVerboseAsm, *InstPrint);
226}
227
Daniel Sanders50f17232015-09-15 16:17:27 +0000228static MCStreamer *createMCStreamer(Triple const &T, MCContext &Context,
Colin LeMahieube99a022015-06-17 03:06:16 +0000229 MCAsmBackend &MAB, raw_pwrite_stream &OS,
230 MCCodeEmitter *Emitter, bool RelaxAll) {
231 return createHexagonELFStreamer(Context, MAB, OS, Emitter);
232}
233
234static MCTargetStreamer *
235createHexagonObjectTargetStreamer(MCStreamer &S, MCSubtargetInfo const &STI) {
236 return new HexagonTargetELFStreamer(S, STI);
Sid Manning12cd21a2014-10-15 18:27:40 +0000237}
Tony Linthicumb3705e02011-12-15 22:29:08 +0000238
239// Force static initialization.
240extern "C" void LLVMInitializeHexagonTargetMC() {
241 // Register the MC asm info.
Mehdi Aminif42454b2016-10-09 23:00:34 +0000242 RegisterMCAsmInfoFn X(getTheHexagonTarget(), createHexagonMCAsmInfo);
Tony Linthicumb3705e02011-12-15 22:29:08 +0000243
Tony Linthicumb3705e02011-12-15 22:29:08 +0000244 // Register the MC instruction info.
Mehdi Aminif42454b2016-10-09 23:00:34 +0000245 TargetRegistry::RegisterMCInstrInfo(getTheHexagonTarget(),
Sid Manning7da3f9a2014-10-03 13:18:11 +0000246 createHexagonMCInstrInfo);
Tony Linthicumb3705e02011-12-15 22:29:08 +0000247
248 // Register the MC register info.
Mehdi Aminif42454b2016-10-09 23:00:34 +0000249 TargetRegistry::RegisterMCRegInfo(getTheHexagonTarget(),
Tony Linthicumb3705e02011-12-15 22:29:08 +0000250 createHexagonMCRegisterInfo);
251
252 // Register the MC subtarget info.
Mehdi Aminif42454b2016-10-09 23:00:34 +0000253 TargetRegistry::RegisterMCSubtargetInfo(getTheHexagonTarget(),
Tony Linthicumb3705e02011-12-15 22:29:08 +0000254 createHexagonMCSubtargetInfo);
Sid Manning7da3f9a2014-10-03 13:18:11 +0000255
256 // Register the MC Code Emitter
Mehdi Aminif42454b2016-10-09 23:00:34 +0000257 TargetRegistry::RegisterMCCodeEmitter(getTheHexagonTarget(),
Sid Manning7da3f9a2014-10-03 13:18:11 +0000258 createHexagonMCCodeEmitter);
Sid Manning12cd21a2014-10-15 18:27:40 +0000259
Colin LeMahieua6750772015-06-03 17:34:16 +0000260 // Register the asm backend
Mehdi Aminif42454b2016-10-09 23:00:34 +0000261 TargetRegistry::RegisterMCAsmBackend(getTheHexagonTarget(),
Colin LeMahieua6750772015-06-03 17:34:16 +0000262 createHexagonAsmBackend);
263
Colin LeMahieube99a022015-06-17 03:06:16 +0000264 // Register the obj streamer
Mehdi Aminif42454b2016-10-09 23:00:34 +0000265 TargetRegistry::RegisterELFStreamer(getTheHexagonTarget(), createMCStreamer);
Colin LeMahieube99a022015-06-17 03:06:16 +0000266
Colin LeMahieud2158752015-06-18 20:43:50 +0000267 // Register the asm streamer
Mehdi Aminif42454b2016-10-09 23:00:34 +0000268 TargetRegistry::RegisterAsmTargetStreamer(getTheHexagonTarget(),
Colin LeMahieud2158752015-06-18 20:43:50 +0000269 createMCAsmTargetStreamer);
270
Sid Manning12cd21a2014-10-15 18:27:40 +0000271 // Register the MC Inst Printer
Mehdi Aminif42454b2016-10-09 23:00:34 +0000272 TargetRegistry::RegisterMCInstPrinter(getTheHexagonTarget(),
Sid Manning12cd21a2014-10-15 18:27:40 +0000273 createHexagonMCInstPrinter);
Colin LeMahieube99a022015-06-17 03:06:16 +0000274
275 TargetRegistry::RegisterObjectTargetStreamer(
Mehdi Aminif42454b2016-10-09 23:00:34 +0000276 getTheHexagonTarget(), createHexagonObjectTargetStreamer);
Tony Linthicumb3705e02011-12-15 22:29:08 +0000277}