[Hexagon] Fixing store instructions and reenabling a few more 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 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     StringRef Separator = "\n";
91     StringRef Indent = "\t\t";
92     OS << "\t{\n";
93     while (!HeadTail.first.empty()) {
94       StringRef InstTxt;
95       auto Duplex = HeadTail.first.split('\v');
96       if (!Duplex.second.empty()) {
97         OS << Indent << Duplex.first << Separator;
98         InstTxt = Duplex.second;
99       } else if (!HeadTail.first.trim().startswith("immext")) {
100         InstTxt = Duplex.first;
101       }
102       if (!InstTxt.empty())
103         OS << Indent << InstTxt << Separator;
104       HeadTail = HeadTail.second.split('\n');
105     }
106     OS << "\t}" << PacketBundle.second;
107   }
108 };
109 }
110
111 namespace {
112 class HexagonTargetELFStreamer : public HexagonTargetStreamer {
113 public:
114   MCELFStreamer &getStreamer() {
115     return static_cast<MCELFStreamer &>(Streamer);
116   }
117   HexagonTargetELFStreamer(MCStreamer &S, MCSubtargetInfo const &STI)
118       : HexagonTargetStreamer(S) {
119     auto Bits = STI.getFeatureBits();
120     unsigned Flags;
121     if (Bits.to_ullong() & llvm::Hexagon::ArchV5)
122       Flags = ELF::EF_HEXAGON_MACH_V5;
123     else
124       Flags = ELF::EF_HEXAGON_MACH_V4;
125     getStreamer().getAssembler().setELFHeaderEFlags(Flags);
126   }
127   void EmitCommonSymbolSorted(MCSymbol *Symbol, uint64_t Size,
128                               unsigned ByteAlignment,
129                               unsigned AccessSize) override {
130     HexagonMCELFStreamer &HexagonELFStreamer =
131         static_cast<HexagonMCELFStreamer &>(getStreamer());
132     HexagonELFStreamer.HexagonMCEmitCommonSymbol(Symbol, Size, ByteAlignment,
133                                                  AccessSize);
134   }
135   void EmitLocalCommonSymbolSorted(MCSymbol *Symbol, uint64_t Size,
136                                    unsigned ByteAlignment,
137                                    unsigned AccessSize) override {
138     HexagonMCELFStreamer &HexagonELFStreamer =
139         static_cast<HexagonMCELFStreamer &>(getStreamer());
140     HexagonELFStreamer.HexagonMCEmitLocalCommonSymbol(
141         Symbol, Size, ByteAlignment, AccessSize);
142   }
143 };
144 }
145
146 static MCAsmInfo *createHexagonMCAsmInfo(const MCRegisterInfo &MRI,
147                                          const Triple &TT) {
148   MCAsmInfo *MAI = new HexagonMCAsmInfo(TT);
149
150   // VirtualFP = (R30 + #0).
151   MCCFIInstruction Inst =
152       MCCFIInstruction::createDefCfa(nullptr, Hexagon::R30, 0);
153   MAI->addInitialFrameState(Inst);
154
155   return MAI;
156 }
157
158 static MCCodeGenInfo *createHexagonMCCodeGenInfo(const Triple &TT,
159                                                  Reloc::Model RM,
160                                                  CodeModel::Model CM,
161                                                  CodeGenOpt::Level OL) {
162   MCCodeGenInfo *X = new MCCodeGenInfo();
163   // For the time being, use static relocations, since there's really no
164   // support for PIC yet.
165   X->initMCCodeGenInfo(Reloc::Static, CM, OL);
166   return X;
167 }
168
169 static MCInstPrinter *createHexagonMCInstPrinter(const Triple &T,
170                                                  unsigned SyntaxVariant,
171                                                  const MCAsmInfo &MAI,
172                                                  const MCInstrInfo &MII,
173                                                  const MCRegisterInfo &MRI) {
174   if (SyntaxVariant == 0)
175     return (new HexagonInstPrinter(MAI, MII, MRI));
176   else
177     return nullptr;
178 }
179
180 static MCTargetStreamer *createMCAsmTargetStreamer(MCStreamer &S,
181                                                    formatted_raw_ostream &OS,
182                                                    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 }