• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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