[Hexagon] Enabling ASM parsing on Hexagon backend and adding instruction parsing...
[oota-llvm.git] / lib / Target / Hexagon / MCTargetDesc / HexagonMCTargetDesc.cpp
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/MCCodeGenInfo.h"
20 #include "llvm/MC/MCContext.h"
21 #include "llvm/MC/MCELFStreamer.h"
22 #include "llvm/MC/MCInstrInfo.h"
23 #include "llvm/MC/MCObjectStreamer.h"
24 #include "llvm/MC/MCRegisterInfo.h"
25 #include "llvm/MC/MCStreamer.h"
26 #include "llvm/MC/MCSubtargetInfo.h"
27 #include "llvm/MC/MachineLocation.h"
28 #include "llvm/Support/ELF.h"
29 #include "llvm/Support/ErrorHandling.h"
30 #include "llvm/Support/TargetRegistry.h"
31
32 using namespace llvm;
33
34 #define GET_INSTRINFO_MC_DESC
35 #include "HexagonGenInstrInfo.inc"
36
37 #define GET_SUBTARGETINFO_MC_DESC
38 #include "HexagonGenSubtargetInfo.inc"
39
40 #define GET_REGINFO_MC_DESC
41 #include "HexagonGenRegisterInfo.inc"
42
43 cl::opt<bool> llvm::HexagonDisableCompound
44   ("mno-compound",
45    cl::desc("Disable looking for compound instructions for Hexagon"));
46
47 cl::opt<bool> llvm::HexagonDisableDuplex
48   ("mno-pairing",
49    cl::desc("Disable looking for duplex instructions for Hexagon"));
50
51 MCInstrInfo *llvm::createHexagonMCInstrInfo() {
52   MCInstrInfo *X = new MCInstrInfo();
53   InitHexagonMCInstrInfo(X);
54   return X;
55 }
56
57 static MCRegisterInfo *createHexagonMCRegisterInfo(const Triple &TT) {
58   MCRegisterInfo *X = new MCRegisterInfo();
59   InitHexagonMCRegisterInfo(X, Hexagon::R0);
60   return X;
61 }
62
63 static MCSubtargetInfo *
64 createHexagonMCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS) {
65   StringRef CPUName = CPU;
66   if (CPU.empty())
67     CPUName = "hexagonv5";
68   return createHexagonMCSubtargetInfoImpl(TT, CPUName, FS);
69 }
70
71 namespace {
72 class HexagonTargetAsmStreamer : public HexagonTargetStreamer {
73 public:
74   HexagonTargetAsmStreamer(MCStreamer &S,
75                            formatted_raw_ostream &, bool,
76                            MCInstPrinter &)
77       : HexagonTargetStreamer(S) {}
78   void prettyPrintAsm(MCInstPrinter &InstPrinter, raw_ostream &OS,
79                       const MCInst &Inst, const MCSubtargetInfo &STI) override {
80     assert(HexagonMCInstrInfo::isBundle(Inst));
81     assert(HexagonMCInstrInfo::bundleSize(Inst) <= HEXAGON_PACKET_SIZE);
82     std::string Buffer;
83     {
84       raw_string_ostream TempStream(Buffer);
85       InstPrinter.printInst(&Inst, TempStream, "", STI);
86     }
87     StringRef Contents(Buffer);
88     auto PacketBundle = Contents.rsplit('\n');
89     auto HeadTail = PacketBundle.first.split('\n');
90     auto Preamble = "\t{\n\t\t";
91     auto Separator = "";
92     while(!HeadTail.first.empty()) {
93       OS << Separator;
94       StringRef Inst;
95       auto Duplex = HeadTail.first.split('\v');
96       if(!Duplex.second.empty()){
97         OS << Duplex.first << "\n";
98         Inst = Duplex.second;
99       }
100       else {
101         if(!HeadTail.first.startswith("immext"))
102           Inst = Duplex.first;
103       }
104       OS << Preamble;
105       OS << Inst;
106       HeadTail = HeadTail.second.split('\n');
107       Preamble = "";
108       Separator = "\n\t\t";
109     }
110     if(HexagonMCInstrInfo::bundleSize(Inst) != 0)
111       OS << "\n\t}" << PacketBundle.second;
112   }
113 };
114 }
115
116 namespace {
117 class HexagonTargetELFStreamer : public HexagonTargetStreamer {
118 public:
119   MCELFStreamer &getStreamer() {
120     return static_cast<MCELFStreamer &>(Streamer);
121   }
122   HexagonTargetELFStreamer(MCStreamer &S, MCSubtargetInfo const &STI)
123       : HexagonTargetStreamer(S) {
124     auto Bits = STI.getFeatureBits();
125     unsigned Flags;
126     if (Bits.to_ullong() & llvm::Hexagon::ArchV5)
127       Flags = ELF::EF_HEXAGON_MACH_V5;
128     else
129       Flags = ELF::EF_HEXAGON_MACH_V4;
130     getStreamer().getAssembler().setELFHeaderEFlags(Flags);
131   }
132   void EmitCommonSymbolSorted(MCSymbol *Symbol, uint64_t Size,
133                               unsigned ByteAlignment,
134                               unsigned AccessSize) override {
135     HexagonMCELFStreamer &HexagonELFStreamer =
136         static_cast<HexagonMCELFStreamer &>(getStreamer());
137     HexagonELFStreamer.HexagonMCEmitCommonSymbol(Symbol, Size, ByteAlignment,
138                                                  AccessSize);
139   }
140   void EmitLocalCommonSymbolSorted(MCSymbol *Symbol, uint64_t Size,
141                                    unsigned ByteAlignment,
142                                    unsigned AccessSize) override {
143     HexagonMCELFStreamer &HexagonELFStreamer =
144         static_cast<HexagonMCELFStreamer &>(getStreamer());
145     HexagonELFStreamer.HexagonMCEmitLocalCommonSymbol(
146         Symbol, Size, ByteAlignment, AccessSize);
147   }
148 };
149 }
150
151 static MCAsmInfo *createHexagonMCAsmInfo(const MCRegisterInfo &MRI,
152                                          const Triple &TT) {
153   MCAsmInfo *MAI = new HexagonMCAsmInfo(TT);
154
155   // VirtualFP = (R30 + #0).
156   MCCFIInstruction Inst =
157       MCCFIInstruction::createDefCfa(nullptr, Hexagon::R30, 0);
158   MAI->addInitialFrameState(Inst);
159
160   return MAI;
161 }
162
163 static MCCodeGenInfo *createHexagonMCCodeGenInfo(const Triple &TT,
164                                                  Reloc::Model RM,
165                                                  CodeModel::Model CM,
166                                                  CodeGenOpt::Level OL) {
167   MCCodeGenInfo *X = new MCCodeGenInfo();
168   // For the time being, use static relocations, since there's really no
169   // support for PIC yet.
170   X->initMCCodeGenInfo(Reloc::Static, CM, OL);
171   return X;
172 }
173
174 static MCInstPrinter *createHexagonMCInstPrinter(const Triple &T,
175                                                  unsigned SyntaxVariant,
176                                                  const MCAsmInfo &MAI,
177                                                  const MCInstrInfo &MII,
178                                                  const MCRegisterInfo &MRI) {
179   if (SyntaxVariant == 0)
180     return (new HexagonInstPrinter(MAI, MII, MRI));
181   else
182     return nullptr;
183 }
184
185 static MCTargetStreamer *createMCAsmTargetStreamer(MCStreamer &S,
186                                                    formatted_raw_ostream &OS,
187                                                    MCInstPrinter *InstPrint,
188                                                    bool IsVerboseAsm) {
189   return new HexagonTargetAsmStreamer(S,  OS, IsVerboseAsm, *InstPrint);
190 }
191
192 static MCStreamer *createMCStreamer(Triple const &T, MCContext &Context,
193                                     MCAsmBackend &MAB, raw_pwrite_stream &OS,
194                                     MCCodeEmitter *Emitter, bool RelaxAll) {
195   return createHexagonELFStreamer(Context, MAB, OS, Emitter);
196 }
197
198 static MCTargetStreamer *
199 createHexagonObjectTargetStreamer(MCStreamer &S, MCSubtargetInfo const &STI) {
200   return new HexagonTargetELFStreamer(S, STI);
201 }
202
203 // Force static initialization.
204 extern "C" void LLVMInitializeHexagonTargetMC() {
205   // Register the MC asm info.
206   RegisterMCAsmInfoFn X(TheHexagonTarget, createHexagonMCAsmInfo);
207
208   // Register the MC codegen info.
209   TargetRegistry::RegisterMCCodeGenInfo(TheHexagonTarget,
210                                         createHexagonMCCodeGenInfo);
211
212   // Register the MC instruction info.
213   TargetRegistry::RegisterMCInstrInfo(TheHexagonTarget,
214                                       createHexagonMCInstrInfo);
215
216   // Register the MC register info.
217   TargetRegistry::RegisterMCRegInfo(TheHexagonTarget,
218                                     createHexagonMCRegisterInfo);
219
220   // Register the MC subtarget info.
221   TargetRegistry::RegisterMCSubtargetInfo(TheHexagonTarget,
222                                           createHexagonMCSubtargetInfo);
223
224   // Register the MC Code Emitter
225   TargetRegistry::RegisterMCCodeEmitter(TheHexagonTarget,
226                                         createHexagonMCCodeEmitter);
227
228   // Register the asm backend
229   TargetRegistry::RegisterMCAsmBackend(TheHexagonTarget,
230                                        createHexagonAsmBackend);
231
232   // Register the obj streamer
233   TargetRegistry::RegisterELFStreamer(TheHexagonTarget, createMCStreamer);
234
235   // Register the asm streamer
236   TargetRegistry::RegisterAsmTargetStreamer(TheHexagonTarget,
237                                             createMCAsmTargetStreamer);
238
239   // Register the MC Inst Printer
240   TargetRegistry::RegisterMCInstPrinter(TheHexagonTarget,
241                                         createHexagonMCInstPrinter);
242
243   TargetRegistry::RegisterObjectTargetStreamer(
244       TheHexagonTarget, createHexagonObjectTargetStreamer);
245 }