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