1 //===-- AArch64MCTargetDesc.cpp - AArch64 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 AArch64 specific target descriptions. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "AArch64MCTargetDesc.h" 15 #include "AArch64ELFStreamer.h" 16 #include "AArch64MCAsmInfo.h" 17 #include "InstPrinter/AArch64InstPrinter.h" 18 #include "llvm/ADT/APInt.h" 19 #include "llvm/MC/MCCodeGenInfo.h" 20 #include "llvm/MC/MCInstrAnalysis.h" 21 #include "llvm/MC/MCInstrInfo.h" 22 #include "llvm/MC/MCRegisterInfo.h" 23 #include "llvm/MC/MCStreamer.h" 24 #include "llvm/MC/MCSubtargetInfo.h" 25 #include "llvm/Support/ErrorHandling.h" 26 #include "llvm/Support/TargetRegistry.h" 27 28 #define GET_REGINFO_MC_DESC 29 #include "AArch64GenRegisterInfo.inc" 30 31 #define GET_INSTRINFO_MC_DESC 32 #include "AArch64GenInstrInfo.inc" 33 34 #define GET_SUBTARGETINFO_MC_DESC 35 #include "AArch64GenSubtargetInfo.inc" 36 37 using namespace llvm; 38 39 MCSubtargetInfo *AArch64_MC::createAArch64MCSubtargetInfo(StringRef TT, 40 StringRef CPU, 41 StringRef FS) { 42 MCSubtargetInfo *X = new MCSubtargetInfo(); 43 InitAArch64MCSubtargetInfo(X, TT, CPU, FS); 44 return X; 45 } 46 47 48 static MCInstrInfo *createAArch64MCInstrInfo() { 49 MCInstrInfo *X = new MCInstrInfo(); 50 InitAArch64MCInstrInfo(X); 51 return X; 52 } 53 54 static MCRegisterInfo *createAArch64MCRegisterInfo(StringRef Triple) { 55 MCRegisterInfo *X = new MCRegisterInfo(); 56 InitAArch64MCRegisterInfo(X, AArch64::X30); 57 return X; 58 } 59 60 static MCAsmInfo *createAArch64MCAsmInfo(const MCRegisterInfo &MRI, 61 StringRef TT) { 62 Triple TheTriple(TT); 63 64 MCAsmInfo *MAI = new AArch64ELFMCAsmInfo(); 65 unsigned Reg = MRI.getDwarfRegNum(AArch64::XSP, true); 66 MCCFIInstruction Inst = MCCFIInstruction::createDefCfa(0, Reg, 0); 67 MAI->addInitialFrameState(Inst); 68 69 return MAI; 70 } 71 72 static MCCodeGenInfo *createAArch64MCCodeGenInfo(StringRef TT, Reloc::Model RM, 73 CodeModel::Model CM, 74 CodeGenOpt::Level OL) { 75 MCCodeGenInfo *X = new MCCodeGenInfo(); 76 if (RM == Reloc::Default || RM == Reloc::DynamicNoPIC) { 77 // On ELF platforms the default static relocation model has a smart enough 78 // linker to cope with referencing external symbols defined in a shared 79 // library. Hence DynamicNoPIC doesn't need to be promoted to PIC. 80 RM = Reloc::Static; 81 } 82 83 if (CM == CodeModel::Default) 84 CM = CodeModel::Small; 85 else if (CM == CodeModel::JITDefault) { 86 // The default MCJIT memory managers make no guarantees about where they can 87 // find an executable page; JITed code needs to be able to refer to globals 88 // no matter how far away they are. 89 CM = CodeModel::Large; 90 } 91 92 X->InitMCCodeGenInfo(RM, CM, OL); 93 return X; 94 } 95 96 static MCStreamer *createMCStreamer(const Target &T, StringRef TT, 97 MCContext &Ctx, MCAsmBackend &MAB, 98 raw_ostream &OS, 99 MCCodeEmitter *Emitter, 100 const MCSubtargetInfo &STI, 101 bool RelaxAll, 102 bool NoExecStack) { 103 Triple TheTriple(TT); 104 105 return createAArch64ELFStreamer(Ctx, MAB, OS, Emitter, RelaxAll, NoExecStack); 106 } 107 108 109 static MCInstPrinter *createAArch64MCInstPrinter(const Target &T, 110 unsigned SyntaxVariant, 111 const MCAsmInfo &MAI, 112 const MCInstrInfo &MII, 113 const MCRegisterInfo &MRI, 114 const MCSubtargetInfo &STI) { 115 if (SyntaxVariant == 0) 116 return new AArch64InstPrinter(MAI, MII, MRI, STI); 117 return 0; 118 } 119 120 namespace { 121 122 class AArch64MCInstrAnalysis : public MCInstrAnalysis { 123 public: 124 AArch64MCInstrAnalysis(const MCInstrInfo *Info) : MCInstrAnalysis(Info) {} 125 126 virtual bool isUnconditionalBranch(const MCInst &Inst) const { 127 if (Inst.getOpcode() == AArch64::Bcc 128 && Inst.getOperand(0).getImm() == A64CC::AL) 129 return true; 130 return MCInstrAnalysis::isUnconditionalBranch(Inst); 131 } 132 133 virtual bool isConditionalBranch(const MCInst &Inst) const { 134 if (Inst.getOpcode() == AArch64::Bcc 135 && Inst.getOperand(0).getImm() == A64CC::AL) 136 return false; 137 return MCInstrAnalysis::isConditionalBranch(Inst); 138 } 139 140 bool evaluateBranch(const MCInst &Inst, uint64_t Addr, 141 uint64_t Size, uint64_t &Target) const { 142 unsigned LblOperand = Inst.getOpcode() == AArch64::Bcc ? 1 : 0; 143 // FIXME: We only handle PCRel branches for now. 144 if (Info->get(Inst.getOpcode()).OpInfo[LblOperand].OperandType 145 != MCOI::OPERAND_PCREL) 146 return false; 147 148 int64_t Imm = Inst.getOperand(LblOperand).getImm(); 149 Target = Addr + Imm; 150 return true; 151 } 152 }; 153 154 } 155 156 static MCInstrAnalysis *createAArch64MCInstrAnalysis(const MCInstrInfo *Info) { 157 return new AArch64MCInstrAnalysis(Info); 158 } 159 160 161 162 extern "C" void LLVMInitializeAArch64TargetMC() { 163 // Register the MC asm info. 164 RegisterMCAsmInfoFn A(TheAArch64Target, createAArch64MCAsmInfo); 165 166 // Register the MC codegen info. 167 TargetRegistry::RegisterMCCodeGenInfo(TheAArch64Target, 168 createAArch64MCCodeGenInfo); 169 170 // Register the MC instruction info. 171 TargetRegistry::RegisterMCInstrInfo(TheAArch64Target, 172 createAArch64MCInstrInfo); 173 174 // Register the MC register info. 175 TargetRegistry::RegisterMCRegInfo(TheAArch64Target, 176 createAArch64MCRegisterInfo); 177 178 // Register the MC subtarget info. 179 using AArch64_MC::createAArch64MCSubtargetInfo; 180 TargetRegistry::RegisterMCSubtargetInfo(TheAArch64Target, 181 createAArch64MCSubtargetInfo); 182 183 // Register the MC instruction analyzer. 184 TargetRegistry::RegisterMCInstrAnalysis(TheAArch64Target, 185 createAArch64MCInstrAnalysis); 186 187 // Register the MC Code Emitter 188 TargetRegistry::RegisterMCCodeEmitter(TheAArch64Target, 189 createAArch64MCCodeEmitter); 190 191 // Register the asm backend. 192 TargetRegistry::RegisterMCAsmBackend(TheAArch64Target, 193 createAArch64AsmBackend); 194 195 // Register the object streamer. 196 TargetRegistry::RegisterMCObjectStreamer(TheAArch64Target, 197 createMCStreamer); 198 199 // Register the MCInstPrinter. 200 TargetRegistry::RegisterMCInstPrinter(TheAArch64Target, 201 createAArch64MCInstPrinter); 202 } 203