1 //===-- HexagonMCTargetDesc.cpp - Hexagon Target Descriptions -------------===//
2 //
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 //
10 // This file provides Hexagon specific target descriptions.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "HexagonMCTargetDesc.h"
15 #include "Hexagon.h"
16 #include "HexagonMCAsmInfo.h"
17 #include "HexagonMCELFStreamer.h"
18 #include "MCTargetDesc/HexagonInstPrinter.h"
19 #include "llvm/MC/MCContext.h"
20 #include "llvm/MC/MCELFStreamer.h"
21 #include "llvm/MC/MCInstrInfo.h"
22 #include "llvm/MC/MCObjectStreamer.h"
23 #include "llvm/MC/MCRegisterInfo.h"
24 #include "llvm/MC/MCStreamer.h"
25 #include "llvm/MC/MCSubtargetInfo.h"
26 #include "llvm/MC/MachineLocation.h"
27 #include "llvm/Support/ELF.h"
28 #include "llvm/Support/ErrorHandling.h"
29 #include "llvm/Support/TargetRegistry.h"
30
31 using namespace llvm;
32
33 #define GET_INSTRINFO_MC_DESC
34 #include "HexagonGenInstrInfo.inc"
35
36 #define GET_SUBTARGETINFO_MC_DESC
37 #include "HexagonGenSubtargetInfo.inc"
38
39 #define GET_REGINFO_MC_DESC
40 #include "HexagonGenRegisterInfo.inc"
41
42 cl::opt<bool> llvm::HexagonDisableCompound
43 ("mno-compound",
44 cl::desc("Disable looking for compound instructions for Hexagon"));
45
46 cl::opt<bool> llvm::HexagonDisableDuplex
47 ("mno-pairing",
48 cl::desc("Disable looking for duplex instructions for Hexagon"));
49
50 static cl::opt<bool> HexagonV4ArchVariant("mv4", cl::Hidden, cl::init(false),
51 cl::desc("Build for Hexagon V4"));
52
53 static cl::opt<bool> HexagonV5ArchVariant("mv5", cl::Hidden, cl::init(false),
54 cl::desc("Build for Hexagon V5"));
55
56 static cl::opt<bool> HexagonV55ArchVariant("mv55", cl::Hidden, cl::init(false),
57 cl::desc("Build for Hexagon V55"));
58
59 static cl::opt<bool> HexagonV60ArchVariant("mv60", cl::Hidden, cl::init(false),
60 cl::desc("Build for Hexagon V60"));
61
62
63 static StringRef DefaultArch = "hexagonv60";
64
HexagonGetArchVariant()65 static StringRef HexagonGetArchVariant() {
66 if (HexagonV4ArchVariant)
67 return "hexagonv4";
68 if (HexagonV5ArchVariant)
69 return "hexagonv5";
70 if (HexagonV55ArchVariant)
71 return "hexagonv55";
72 if (HexagonV60ArchVariant)
73 return "hexagonv60";
74 return "";
75 }
76
selectHexagonCPU(const Triple & TT,StringRef CPU)77 StringRef HEXAGON_MC::selectHexagonCPU(const Triple &TT, StringRef CPU) {
78 StringRef ArchV = HexagonGetArchVariant();
79 if (!ArchV.empty() && !CPU.empty()) {
80 if (ArchV != CPU)
81 report_fatal_error("conflicting architectures specified.");
82 return CPU;
83 }
84 if (ArchV.empty()) {
85 if (CPU.empty())
86 CPU = DefaultArch;
87 return CPU;
88 }
89 return ArchV;
90 }
91
createHexagonMCInstrInfo()92 MCInstrInfo *llvm::createHexagonMCInstrInfo() {
93 MCInstrInfo *X = new MCInstrInfo();
94 InitHexagonMCInstrInfo(X);
95 return X;
96 }
97
createHexagonMCRegisterInfo(const Triple & TT)98 static MCRegisterInfo *createHexagonMCRegisterInfo(const Triple &TT) {
99 MCRegisterInfo *X = new MCRegisterInfo();
100 InitHexagonMCRegisterInfo(X, Hexagon::R31);
101 return X;
102 }
103
104 static MCSubtargetInfo *
createHexagonMCSubtargetInfo(const Triple & TT,StringRef CPU,StringRef FS)105 createHexagonMCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS) {
106 CPU = HEXAGON_MC::selectHexagonCPU(TT, CPU);
107 return createHexagonMCSubtargetInfoImpl(TT, CPU, FS);
108 }
109
110 namespace {
111 class HexagonTargetAsmStreamer : public HexagonTargetStreamer {
112 public:
HexagonTargetAsmStreamer(MCStreamer & S,formatted_raw_ostream &,bool,MCInstPrinter &)113 HexagonTargetAsmStreamer(MCStreamer &S,
114 formatted_raw_ostream &, bool,
115 MCInstPrinter &)
116 : HexagonTargetStreamer(S) {}
prettyPrintAsm(MCInstPrinter & InstPrinter,raw_ostream & OS,const MCInst & Inst,const MCSubtargetInfo & STI)117 void prettyPrintAsm(MCInstPrinter &InstPrinter, raw_ostream &OS,
118 const MCInst &Inst, const MCSubtargetInfo &STI) override {
119 assert(HexagonMCInstrInfo::isBundle(Inst));
120 assert(HexagonMCInstrInfo::bundleSize(Inst) <= HEXAGON_PACKET_SIZE);
121 std::string Buffer;
122 {
123 raw_string_ostream TempStream(Buffer);
124 InstPrinter.printInst(&Inst, TempStream, "", STI);
125 }
126 StringRef Contents(Buffer);
127 auto PacketBundle = Contents.rsplit('\n');
128 auto HeadTail = PacketBundle.first.split('\n');
129 StringRef Separator = "\n";
130 StringRef Indent = "\t\t";
131 OS << "\t{\n";
132 while (!HeadTail.first.empty()) {
133 StringRef InstTxt;
134 auto Duplex = HeadTail.first.split('\v');
135 if (!Duplex.second.empty()) {
136 OS << Indent << Duplex.first << Separator;
137 InstTxt = Duplex.second;
138 } else if (!HeadTail.first.trim().startswith("immext")) {
139 InstTxt = Duplex.first;
140 }
141 if (!InstTxt.empty())
142 OS << Indent << InstTxt << Separator;
143 HeadTail = HeadTail.second.split('\n');
144 }
145 OS << "\t}" << PacketBundle.second;
146 }
147 };
148 }
149
150 namespace {
151 class HexagonTargetELFStreamer : public HexagonTargetStreamer {
152 public:
getStreamer()153 MCELFStreamer &getStreamer() {
154 return static_cast<MCELFStreamer &>(Streamer);
155 }
HexagonTargetELFStreamer(MCStreamer & S,MCSubtargetInfo const & STI)156 HexagonTargetELFStreamer(MCStreamer &S, MCSubtargetInfo const &STI)
157 : HexagonTargetStreamer(S) {
158 auto Bits = STI.getFeatureBits();
159 unsigned Flags = 0;
160 if (Bits[Hexagon::ArchV60])
161 Flags = ELF::EF_HEXAGON_MACH_V60;
162 else if (Bits[Hexagon::ArchV55])
163 Flags = ELF::EF_HEXAGON_MACH_V55;
164 else if (Bits[Hexagon::ArchV5])
165 Flags = ELF::EF_HEXAGON_MACH_V5;
166 else if (Bits[Hexagon::ArchV4])
167 Flags = ELF::EF_HEXAGON_MACH_V4;
168 getStreamer().getAssembler().setELFHeaderEFlags(Flags);
169 }
EmitCommonSymbolSorted(MCSymbol * Symbol,uint64_t Size,unsigned ByteAlignment,unsigned AccessSize)170 void EmitCommonSymbolSorted(MCSymbol *Symbol, uint64_t Size,
171 unsigned ByteAlignment,
172 unsigned AccessSize) override {
173 HexagonMCELFStreamer &HexagonELFStreamer =
174 static_cast<HexagonMCELFStreamer &>(getStreamer());
175 HexagonELFStreamer.HexagonMCEmitCommonSymbol(Symbol, Size, ByteAlignment,
176 AccessSize);
177 }
EmitLocalCommonSymbolSorted(MCSymbol * Symbol,uint64_t Size,unsigned ByteAlignment,unsigned AccessSize)178 void EmitLocalCommonSymbolSorted(MCSymbol *Symbol, uint64_t Size,
179 unsigned ByteAlignment,
180 unsigned AccessSize) override {
181 HexagonMCELFStreamer &HexagonELFStreamer =
182 static_cast<HexagonMCELFStreamer &>(getStreamer());
183 HexagonELFStreamer.HexagonMCEmitLocalCommonSymbol(
184 Symbol, Size, ByteAlignment, AccessSize);
185 }
186 };
187 }
188
createHexagonMCAsmInfo(const MCRegisterInfo & MRI,const Triple & TT)189 static MCAsmInfo *createHexagonMCAsmInfo(const MCRegisterInfo &MRI,
190 const Triple &TT) {
191 MCAsmInfo *MAI = new HexagonMCAsmInfo(TT);
192
193 // VirtualFP = (R30 + #0).
194 MCCFIInstruction Inst =
195 MCCFIInstruction::createDefCfa(nullptr, Hexagon::R30, 0);
196 MAI->addInitialFrameState(Inst);
197
198 return MAI;
199 }
200
createHexagonMCInstPrinter(const Triple & T,unsigned SyntaxVariant,const MCAsmInfo & MAI,const MCInstrInfo & MII,const MCRegisterInfo & MRI)201 static MCInstPrinter *createHexagonMCInstPrinter(const Triple &T,
202 unsigned SyntaxVariant,
203 const MCAsmInfo &MAI,
204 const MCInstrInfo &MII,
205 const MCRegisterInfo &MRI) {
206 if (SyntaxVariant == 0)
207 return (new HexagonInstPrinter(MAI, MII, MRI));
208 else
209 return nullptr;
210 }
211
createMCAsmTargetStreamer(MCStreamer & S,formatted_raw_ostream & OS,MCInstPrinter * InstPrint,bool IsVerboseAsm)212 static MCTargetStreamer *createMCAsmTargetStreamer(MCStreamer &S,
213 formatted_raw_ostream &OS,
214 MCInstPrinter *InstPrint,
215 bool IsVerboseAsm) {
216 return new HexagonTargetAsmStreamer(S, OS, IsVerboseAsm, *InstPrint);
217 }
218
createMCStreamer(Triple const & T,MCContext & Context,MCAsmBackend & MAB,raw_pwrite_stream & OS,MCCodeEmitter * Emitter,bool RelaxAll)219 static MCStreamer *createMCStreamer(Triple const &T, MCContext &Context,
220 MCAsmBackend &MAB, raw_pwrite_stream &OS,
221 MCCodeEmitter *Emitter, bool RelaxAll) {
222 return createHexagonELFStreamer(Context, MAB, OS, Emitter);
223 }
224
225 static MCTargetStreamer *
createHexagonObjectTargetStreamer(MCStreamer & S,MCSubtargetInfo const & STI)226 createHexagonObjectTargetStreamer(MCStreamer &S, MCSubtargetInfo const &STI) {
227 return new HexagonTargetELFStreamer(S, STI);
228 }
229
230 // Force static initialization.
LLVMInitializeHexagonTargetMC()231 extern "C" void LLVMInitializeHexagonTargetMC() {
232 // Register the MC asm info.
233 RegisterMCAsmInfoFn X(TheHexagonTarget, createHexagonMCAsmInfo);
234
235 // Register the MC instruction info.
236 TargetRegistry::RegisterMCInstrInfo(TheHexagonTarget,
237 createHexagonMCInstrInfo);
238
239 // Register the MC register info.
240 TargetRegistry::RegisterMCRegInfo(TheHexagonTarget,
241 createHexagonMCRegisterInfo);
242
243 // Register the MC subtarget info.
244 TargetRegistry::RegisterMCSubtargetInfo(TheHexagonTarget,
245 createHexagonMCSubtargetInfo);
246
247 // Register the MC Code Emitter
248 TargetRegistry::RegisterMCCodeEmitter(TheHexagonTarget,
249 createHexagonMCCodeEmitter);
250
251 // Register the asm backend
252 TargetRegistry::RegisterMCAsmBackend(TheHexagonTarget,
253 createHexagonAsmBackend);
254
255 // Register the obj streamer
256 TargetRegistry::RegisterELFStreamer(TheHexagonTarget, createMCStreamer);
257
258 // Register the asm streamer
259 TargetRegistry::RegisterAsmTargetStreamer(TheHexagonTarget,
260 createMCAsmTargetStreamer);
261
262 // Register the MC Inst Printer
263 TargetRegistry::RegisterMCInstPrinter(TheHexagonTarget,
264 createHexagonMCInstPrinter);
265
266 TargetRegistry::RegisterObjectTargetStreamer(
267 TheHexagonTarget, createHexagonObjectTargetStreamer);
268 }
269