Home | History | Annotate | Download | only in MCTargetDesc
      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 StringRef HEXAGON_MC::selectHexagonCPU(const Triple &TT, StringRef CPU) {
     52   if (CPU.empty())
     53     CPU = "hexagonv60";
     54   return CPU;
     55 }
     56 
     57 MCInstrInfo *llvm::createHexagonMCInstrInfo() {
     58   MCInstrInfo *X = new MCInstrInfo();
     59   InitHexagonMCInstrInfo(X);
     60   return X;
     61 }
     62 
     63 static MCRegisterInfo *createHexagonMCRegisterInfo(const Triple &TT) {
     64   MCRegisterInfo *X = new MCRegisterInfo();
     65   InitHexagonMCRegisterInfo(X, Hexagon::R0);
     66   return X;
     67 }
     68 
     69 static MCSubtargetInfo *
     70 createHexagonMCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS) {
     71   CPU = HEXAGON_MC::selectHexagonCPU(TT, CPU);
     72   return createHexagonMCSubtargetInfoImpl(TT, CPU, FS);
     73 }
     74 
     75 namespace {
     76 class HexagonTargetAsmStreamer : public HexagonTargetStreamer {
     77 public:
     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 
    115 namespace {
    116 class HexagonTargetELFStreamer : public HexagonTargetStreamer {
    117 public:
    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 
    150 static 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 
    162 static 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 
    173 static 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 
    184 static 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 
    191 static 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 
    197 static MCTargetStreamer *
    198 createHexagonObjectTargetStreamer(MCStreamer &S, MCSubtargetInfo const &STI) {
    199   return new HexagonTargetELFStreamer(S, STI);
    200 }
    201 
    202 // Force static initialization.
    203 extern "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