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