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