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