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