1249259Sdim//===-- AArch64MCTargetDesc.cpp - AArch64 Target Descriptions -------------===// 2249259Sdim// 3249259Sdim// The LLVM Compiler Infrastructure 4249259Sdim// 5249259Sdim// This file is distributed under the University of Illinois Open Source 6249259Sdim// License. See LICENSE.TXT for details. 7249259Sdim// 8249259Sdim//===----------------------------------------------------------------------===// 9249259Sdim// 10249259Sdim// This file provides AArch64 specific target descriptions. 11249259Sdim// 12249259Sdim//===----------------------------------------------------------------------===// 13249259Sdim 14249259Sdim#include "AArch64MCTargetDesc.h" 15249259Sdim#include "AArch64ELFStreamer.h" 16249259Sdim#include "AArch64MCAsmInfo.h" 17249259Sdim#include "InstPrinter/AArch64InstPrinter.h" 18249259Sdim#include "llvm/ADT/APInt.h" 19249259Sdim#include "llvm/MC/MCCodeGenInfo.h" 20249259Sdim#include "llvm/MC/MCInstrAnalysis.h" 21249259Sdim#include "llvm/MC/MCInstrInfo.h" 22249259Sdim#include "llvm/MC/MCRegisterInfo.h" 23249259Sdim#include "llvm/MC/MCStreamer.h" 24249259Sdim#include "llvm/MC/MCSubtargetInfo.h" 25249259Sdim#include "llvm/Support/TargetRegistry.h" 26249259Sdim#include "llvm/Support/ErrorHandling.h" 27249259Sdim 28249259Sdim#define GET_REGINFO_MC_DESC 29249259Sdim#include "AArch64GenRegisterInfo.inc" 30249259Sdim 31249259Sdim#define GET_INSTRINFO_MC_DESC 32249259Sdim#include "AArch64GenInstrInfo.inc" 33249259Sdim 34249259Sdim#define GET_SUBTARGETINFO_MC_DESC 35249259Sdim#include "AArch64GenSubtargetInfo.inc" 36249259Sdim 37249259Sdimusing namespace llvm; 38249259Sdim 39249259SdimMCSubtargetInfo *AArch64_MC::createAArch64MCSubtargetInfo(StringRef TT, 40249259Sdim StringRef CPU, 41249259Sdim StringRef FS) { 42249259Sdim MCSubtargetInfo *X = new MCSubtargetInfo(); 43263508Sdim InitAArch64MCSubtargetInfo(X, TT, CPU, FS); 44249259Sdim return X; 45249259Sdim} 46249259Sdim 47249259Sdim 48249259Sdimstatic MCInstrInfo *createAArch64MCInstrInfo() { 49249259Sdim MCInstrInfo *X = new MCInstrInfo(); 50249259Sdim InitAArch64MCInstrInfo(X); 51249259Sdim return X; 52249259Sdim} 53249259Sdim 54249259Sdimstatic MCRegisterInfo *createAArch64MCRegisterInfo(StringRef Triple) { 55249259Sdim MCRegisterInfo *X = new MCRegisterInfo(); 56249259Sdim InitAArch64MCRegisterInfo(X, AArch64::X30); 57249259Sdim return X; 58249259Sdim} 59249259Sdim 60263508Sdimstatic MCAsmInfo *createAArch64MCAsmInfo(const MCRegisterInfo &MRI, 61263508Sdim StringRef TT) { 62249259Sdim Triple TheTriple(TT); 63249259Sdim 64249259Sdim MCAsmInfo *MAI = new AArch64ELFMCAsmInfo(); 65263508Sdim unsigned Reg = MRI.getDwarfRegNum(AArch64::XSP, true); 66263508Sdim MCCFIInstruction Inst = MCCFIInstruction::createDefCfa(0, Reg, 0); 67263508Sdim MAI->addInitialFrameState(Inst); 68249259Sdim 69249259Sdim return MAI; 70249259Sdim} 71249259Sdim 72249259Sdimstatic MCCodeGenInfo *createAArch64MCCodeGenInfo(StringRef TT, Reloc::Model RM, 73249259Sdim CodeModel::Model CM, 74249259Sdim CodeGenOpt::Level OL) { 75249259Sdim MCCodeGenInfo *X = new MCCodeGenInfo(); 76249259Sdim if (RM == Reloc::Default || RM == Reloc::DynamicNoPIC) { 77249259Sdim // On ELF platforms the default static relocation model has a smart enough 78249259Sdim // linker to cope with referencing external symbols defined in a shared 79249259Sdim // library. Hence DynamicNoPIC doesn't need to be promoted to PIC. 80249259Sdim RM = Reloc::Static; 81249259Sdim } 82249259Sdim 83249259Sdim if (CM == CodeModel::Default) 84249259Sdim CM = CodeModel::Small; 85251662Sdim else if (CM == CodeModel::JITDefault) { 86251662Sdim // The default MCJIT memory managers make no guarantees about where they can 87251662Sdim // find an executable page; JITed code needs to be able to refer to globals 88251662Sdim // no matter how far away they are. 89251662Sdim CM = CodeModel::Large; 90251662Sdim } 91249259Sdim 92249259Sdim X->InitMCCodeGenInfo(RM, CM, OL); 93249259Sdim return X; 94249259Sdim} 95249259Sdim 96249259Sdimstatic MCStreamer *createMCStreamer(const Target &T, StringRef TT, 97249259Sdim MCContext &Ctx, MCAsmBackend &MAB, 98249259Sdim raw_ostream &OS, 99249259Sdim MCCodeEmitter *Emitter, 100249259Sdim bool RelaxAll, 101249259Sdim bool NoExecStack) { 102249259Sdim Triple TheTriple(TT); 103249259Sdim 104249259Sdim return createAArch64ELFStreamer(Ctx, MAB, OS, Emitter, RelaxAll, NoExecStack); 105249259Sdim} 106249259Sdim 107249259Sdim 108249259Sdimstatic MCInstPrinter *createAArch64MCInstPrinter(const Target &T, 109249259Sdim unsigned SyntaxVariant, 110249259Sdim const MCAsmInfo &MAI, 111249259Sdim const MCInstrInfo &MII, 112249259Sdim const MCRegisterInfo &MRI, 113249259Sdim const MCSubtargetInfo &STI) { 114249259Sdim if (SyntaxVariant == 0) 115249259Sdim return new AArch64InstPrinter(MAI, MII, MRI, STI); 116249259Sdim return 0; 117249259Sdim} 118249259Sdim 119249259Sdimnamespace { 120249259Sdim 121249259Sdimclass AArch64MCInstrAnalysis : public MCInstrAnalysis { 122249259Sdimpublic: 123249259Sdim AArch64MCInstrAnalysis(const MCInstrInfo *Info) : MCInstrAnalysis(Info) {} 124249259Sdim 125249259Sdim virtual bool isUnconditionalBranch(const MCInst &Inst) const { 126249259Sdim if (Inst.getOpcode() == AArch64::Bcc 127249259Sdim && Inst.getOperand(0).getImm() == A64CC::AL) 128249259Sdim return true; 129249259Sdim return MCInstrAnalysis::isUnconditionalBranch(Inst); 130249259Sdim } 131249259Sdim 132249259Sdim virtual bool isConditionalBranch(const MCInst &Inst) const { 133249259Sdim if (Inst.getOpcode() == AArch64::Bcc 134249259Sdim && Inst.getOperand(0).getImm() == A64CC::AL) 135249259Sdim return false; 136249259Sdim return MCInstrAnalysis::isConditionalBranch(Inst); 137249259Sdim } 138249259Sdim 139263508Sdim bool evaluateBranch(const MCInst &Inst, uint64_t Addr, 140263508Sdim uint64_t Size, uint64_t &Target) const { 141249259Sdim unsigned LblOperand = Inst.getOpcode() == AArch64::Bcc ? 1 : 0; 142249259Sdim // FIXME: We only handle PCRel branches for now. 143249259Sdim if (Info->get(Inst.getOpcode()).OpInfo[LblOperand].OperandType 144249259Sdim != MCOI::OPERAND_PCREL) 145263508Sdim return false; 146249259Sdim 147249259Sdim int64_t Imm = Inst.getOperand(LblOperand).getImm(); 148263508Sdim Target = Addr + Imm; 149263508Sdim return true; 150249259Sdim } 151249259Sdim}; 152249259Sdim 153249259Sdim} 154249259Sdim 155249259Sdimstatic MCInstrAnalysis *createAArch64MCInstrAnalysis(const MCInstrInfo *Info) { 156249259Sdim return new AArch64MCInstrAnalysis(Info); 157249259Sdim} 158249259Sdim 159249259Sdim 160249259Sdim 161249259Sdimextern "C" void LLVMInitializeAArch64TargetMC() { 162249259Sdim // Register the MC asm info. 163249259Sdim RegisterMCAsmInfoFn A(TheAArch64Target, createAArch64MCAsmInfo); 164249259Sdim 165249259Sdim // Register the MC codegen info. 166249259Sdim TargetRegistry::RegisterMCCodeGenInfo(TheAArch64Target, 167249259Sdim createAArch64MCCodeGenInfo); 168249259Sdim 169249259Sdim // Register the MC instruction info. 170249259Sdim TargetRegistry::RegisterMCInstrInfo(TheAArch64Target, 171249259Sdim createAArch64MCInstrInfo); 172249259Sdim 173249259Sdim // Register the MC register info. 174249259Sdim TargetRegistry::RegisterMCRegInfo(TheAArch64Target, 175249259Sdim createAArch64MCRegisterInfo); 176249259Sdim 177249259Sdim // Register the MC subtarget info. 178249259Sdim using AArch64_MC::createAArch64MCSubtargetInfo; 179249259Sdim TargetRegistry::RegisterMCSubtargetInfo(TheAArch64Target, 180249259Sdim createAArch64MCSubtargetInfo); 181249259Sdim 182249259Sdim // Register the MC instruction analyzer. 183249259Sdim TargetRegistry::RegisterMCInstrAnalysis(TheAArch64Target, 184249259Sdim createAArch64MCInstrAnalysis); 185249259Sdim 186249259Sdim // Register the MC Code Emitter 187249259Sdim TargetRegistry::RegisterMCCodeEmitter(TheAArch64Target, 188249259Sdim createAArch64MCCodeEmitter); 189249259Sdim 190249259Sdim // Register the asm backend. 191249259Sdim TargetRegistry::RegisterMCAsmBackend(TheAArch64Target, 192249259Sdim createAArch64AsmBackend); 193249259Sdim 194249259Sdim // Register the object streamer. 195249259Sdim TargetRegistry::RegisterMCObjectStreamer(TheAArch64Target, 196249259Sdim createMCStreamer); 197249259Sdim 198249259Sdim // Register the MCInstPrinter. 199249259Sdim TargetRegistry::RegisterMCInstPrinter(TheAArch64Target, 200249259Sdim createAArch64MCInstPrinter); 201249259Sdim} 202