-//===-- AArch64MCTargetDesc.cpp - AArch64 Target Descriptions -------------===//
+//===-- AArch64MCTargetDesc.cpp - AArch64 Target Descriptions ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
#include "AArch64ELFStreamer.h"
#include "AArch64MCAsmInfo.h"
#include "InstPrinter/AArch64InstPrinter.h"
-#include "llvm/ADT/APInt.h"
#include "llvm/MC/MCCodeGenInfo.h"
-#include "llvm/MC/MCInstrAnalysis.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCStreamer.h"
using namespace llvm;
-#define GET_REGINFO_MC_DESC
-#include "AArch64GenRegisterInfo.inc"
-
#define GET_INSTRINFO_MC_DESC
#include "AArch64GenInstrInfo.inc"
#define GET_SUBTARGETINFO_MC_DESC
#include "AArch64GenSubtargetInfo.inc"
-MCSubtargetInfo *AArch64_MC::createAArch64MCSubtargetInfo(StringRef TT,
- StringRef CPU,
- StringRef FS) {
- MCSubtargetInfo *X = new MCSubtargetInfo();
- InitAArch64MCSubtargetInfo(X, TT, CPU, FS);
- return X;
-}
-
+#define GET_REGINFO_MC_DESC
+#include "AArch64GenRegisterInfo.inc"
static MCInstrInfo *createAArch64MCInstrInfo() {
MCInstrInfo *X = new MCInstrInfo();
return X;
}
-static MCRegisterInfo *createAArch64MCRegisterInfo(StringRef Triple) {
+static MCSubtargetInfo *createAArch64MCSubtargetInfo(const TargetTuple &TT,
+ StringRef CPU,
+ StringRef FS) {
+ if (CPU.empty())
+ CPU = "generic";
+
+ return createAArch64MCSubtargetInfoImpl(TT, CPU, FS);
+}
+
+static MCRegisterInfo *createAArch64MCRegisterInfo(const TargetTuple &TT) {
MCRegisterInfo *X = new MCRegisterInfo();
- InitAArch64MCRegisterInfo(X, AArch64::X30);
+ InitAArch64MCRegisterInfo(X, AArch64::LR);
return X;
}
static MCAsmInfo *createAArch64MCAsmInfo(const MCRegisterInfo &MRI,
- StringRef TT) {
- Triple TheTriple(TT);
+ const TargetTuple &TT) {
+ MCAsmInfo *MAI;
+ if (TT.isOSBinFormatMachO())
+ MAI = new AArch64MCAsmInfoDarwin();
+ else {
+ assert(TT.isOSBinFormatELF() && "Only expect Darwin or ELF");
+ MAI = new AArch64MCAsmInfoELF(TT);
+ }
- MCAsmInfo *MAI = new AArch64ELFMCAsmInfo(TT);
- unsigned Reg = MRI.getDwarfRegNum(AArch64::XSP, true);
+ // Initial state of the frame pointer is SP.
+ unsigned Reg = MRI.getDwarfRegNum(AArch64::SP, true);
MCCFIInstruction Inst = MCCFIInstruction::createDefCfa(nullptr, Reg, 0);
MAI->addInitialFrameState(Inst);
return MAI;
}
-static MCCodeGenInfo *createAArch64MCCodeGenInfo(StringRef TT, Reloc::Model RM,
+static MCCodeGenInfo *createAArch64MCCodeGenInfo(const TargetTuple &TT,
+ Reloc::Model RM,
CodeModel::Model CM,
CodeGenOpt::Level OL) {
- MCCodeGenInfo *X = new MCCodeGenInfo();
- if (RM == Reloc::Default || RM == Reloc::DynamicNoPIC) {
- // On ELF platforms the default static relocation model has a smart enough
- // linker to cope with referencing external symbols defined in a shared
- // library. Hence DynamicNoPIC doesn't need to be promoted to PIC.
- RM = Reloc::Static;
- }
+ assert((TT.isOSBinFormatELF() || TT.isOSBinFormatMachO()) &&
+ "Only expect Darwin and ELF targets");
if (CM == CodeModel::Default)
CM = CodeModel::Small;
- else if (CM == CodeModel::JITDefault) {
- // The default MCJIT memory managers make no guarantees about where they can
- // find an executable page; JITed code needs to be able to refer to globals
- // no matter how far away they are.
+ // The default MCJIT memory managers make no guarantees about where they can
+ // find an executable page; JITed code needs to be able to refer to globals
+ // no matter how far away they are.
+ else if (CM == CodeModel::JITDefault)
CM = CodeModel::Large;
- }
+ else if (CM != CodeModel::Small && CM != CodeModel::Large)
+ report_fatal_error(
+ "Only small and large code models are allowed on AArch64");
+
+ // AArch64 Darwin is always PIC.
+ if (TT.isOSDarwin())
+ RM = Reloc::PIC_;
+ // On ELF platforms the default static relocation model has a smart enough
+ // linker to cope with referencing external symbols defined in a shared
+ // library. Hence DynamicNoPIC doesn't need to be promoted to PIC.
+ else if (RM == Reloc::Default || RM == Reloc::DynamicNoPIC)
+ RM = Reloc::Static;
- X->InitMCCodeGenInfo(RM, CM, OL);
+ MCCodeGenInfo *X = new MCCodeGenInfo();
+ X->initMCCodeGenInfo(RM, CM, OL);
return X;
}
-static MCStreamer *createMCStreamer(const Target &T, StringRef TT,
- MCContext &Ctx, MCAsmBackend &MAB,
- raw_ostream &OS,
- MCCodeEmitter *Emitter,
- const MCSubtargetInfo &STI,
- bool RelaxAll,
- bool NoExecStack) {
- Triple TheTriple(TT);
-
- return createAArch64ELFStreamer(Ctx, MAB, OS, Emitter, RelaxAll, NoExecStack);
-}
-
-
-static MCInstPrinter *createAArch64MCInstPrinter(const Target &T,
+static MCInstPrinter *createAArch64MCInstPrinter(const TargetTuple &TT,
unsigned SyntaxVariant,
const MCAsmInfo &MAI,
const MCInstrInfo &MII,
- const MCRegisterInfo &MRI,
- const MCSubtargetInfo &STI) {
+ const MCRegisterInfo &MRI) {
if (SyntaxVariant == 0)
- return new AArch64InstPrinter(MAI, MII, MRI, STI);
+ return new AArch64InstPrinter(MAI, MII, MRI);
+ if (SyntaxVariant == 1)
+ return new AArch64AppleInstPrinter(MAI, MII, MRI);
+
return nullptr;
}
-namespace {
+static MCStreamer *createELFStreamer(const TargetTuple &TT, MCContext &Ctx,
+ MCAsmBackend &TAB, raw_pwrite_stream &OS,
+ MCCodeEmitter *Emitter, bool RelaxAll) {
+ return createAArch64ELFStreamer(Ctx, TAB, OS, Emitter, RelaxAll);
+}
-class AArch64MCInstrAnalysis : public MCInstrAnalysis {
-public:
- AArch64MCInstrAnalysis(const MCInstrInfo *Info) : MCInstrAnalysis(Info) {}
+static MCStreamer *createMachOStreamer(MCContext &Ctx, MCAsmBackend &TAB,
+ raw_pwrite_stream &OS,
+ MCCodeEmitter *Emitter, bool RelaxAll,
+ bool DWARFMustBeAtTheEnd) {
+ return createMachOStreamer(Ctx, TAB, OS, Emitter, RelaxAll,
+ DWARFMustBeAtTheEnd,
+ /*LabelSections*/ true);
+}
- bool isUnconditionalBranch(const MCInst &Inst) const override {
- if (Inst.getOpcode() == AArch64::Bcc
- && Inst.getOperand(0).getImm() == A64CC::AL)
- return true;
- return MCInstrAnalysis::isUnconditionalBranch(Inst);
- }
+// Force static initialization.
+extern "C" void LLVMInitializeAArch64TargetMC() {
+ for (Target *T :
+ {&TheAArch64leTarget, &TheAArch64beTarget, &TheARM64Target}) {
+ // Register the MC asm info.
+ RegisterMCAsmInfoFn X(*T, createAArch64MCAsmInfo);
- bool isConditionalBranch(const MCInst &Inst) const override {
- if (Inst.getOpcode() == AArch64::Bcc
- && Inst.getOperand(0).getImm() == A64CC::AL)
- return false;
- return MCInstrAnalysis::isConditionalBranch(Inst);
- }
+ // Register the MC codegen info.
+ TargetRegistry::RegisterMCCodeGenInfo(*T, createAArch64MCCodeGenInfo);
- bool evaluateBranch(const MCInst &Inst, uint64_t Addr,
- uint64_t Size, uint64_t &Target) const override {
- unsigned LblOperand = Inst.getOpcode() == AArch64::Bcc ? 1 : 0;
- // FIXME: We only handle PCRel branches for now.
- if (Info->get(Inst.getOpcode()).OpInfo[LblOperand].OperandType
- != MCOI::OPERAND_PCREL)
- return false;
-
- int64_t Imm = Inst.getOperand(LblOperand).getImm();
- Target = Addr + Imm;
- return true;
- }
-};
+ // Register the MC instruction info.
+ TargetRegistry::RegisterMCInstrInfo(*T, createAArch64MCInstrInfo);
-}
+ // Register the MC register info.
+ TargetRegistry::RegisterMCRegInfo(*T, createAArch64MCRegisterInfo);
-static MCInstrAnalysis *createAArch64MCInstrAnalysis(const MCInstrInfo *Info) {
- return new AArch64MCInstrAnalysis(Info);
-}
+ // Register the MC subtarget info.
+ TargetRegistry::RegisterMCSubtargetInfo(*T, createAArch64MCSubtargetInfo);
+ // Register the MC Code Emitter
+ TargetRegistry::RegisterMCCodeEmitter(*T, createAArch64MCCodeEmitter);
+ // Register the obj streamers.
+ TargetRegistry::RegisterELFStreamer(*T, createELFStreamer);
+ TargetRegistry::RegisterMachOStreamer(*T, createMachOStreamer);
-extern "C" void LLVMInitializeAArch64TargetMC() {
- // Register the MC asm info.
- RegisterMCAsmInfoFn A(TheAArch64leTarget, createAArch64MCAsmInfo);
- RegisterMCAsmInfoFn B(TheAArch64beTarget, createAArch64MCAsmInfo);
-
- // Register the MC codegen info.
- TargetRegistry::RegisterMCCodeGenInfo(TheAArch64leTarget,
- createAArch64MCCodeGenInfo);
- TargetRegistry::RegisterMCCodeGenInfo(TheAArch64beTarget,
- createAArch64MCCodeGenInfo);
-
- // Register the MC instruction info.
- TargetRegistry::RegisterMCInstrInfo(TheAArch64leTarget,
- createAArch64MCInstrInfo);
- TargetRegistry::RegisterMCInstrInfo(TheAArch64beTarget,
- createAArch64MCInstrInfo);
-
- // Register the MC register info.
- TargetRegistry::RegisterMCRegInfo(TheAArch64leTarget,
- createAArch64MCRegisterInfo);
- TargetRegistry::RegisterMCRegInfo(TheAArch64beTarget,
- createAArch64MCRegisterInfo);
-
- // Register the MC subtarget info.
- using AArch64_MC::createAArch64MCSubtargetInfo;
- TargetRegistry::RegisterMCSubtargetInfo(TheAArch64leTarget,
- createAArch64MCSubtargetInfo);
- TargetRegistry::RegisterMCSubtargetInfo(TheAArch64beTarget,
- createAArch64MCSubtargetInfo);
-
- // Register the MC instruction analyzer.
- TargetRegistry::RegisterMCInstrAnalysis(TheAArch64leTarget,
- createAArch64MCInstrAnalysis);
- TargetRegistry::RegisterMCInstrAnalysis(TheAArch64beTarget,
- createAArch64MCInstrAnalysis);
-
- // Register the MC Code Emitter
- TargetRegistry::RegisterMCCodeEmitter(TheAArch64leTarget,
- createAArch64MCCodeEmitter);
- TargetRegistry::RegisterMCCodeEmitter(TheAArch64beTarget,
- createAArch64MCCodeEmitter);
+ // Register the obj target streamer.
+ TargetRegistry::RegisterObjectTargetStreamer(
+ *T, createAArch64ObjectTargetStreamer);
+
+ // Register the asm streamer.
+ TargetRegistry::RegisterAsmTargetStreamer(*T,
+ createAArch64AsmTargetStreamer);
+ // Register the MCInstPrinter.
+ TargetRegistry::RegisterMCInstPrinter(*T, createAArch64MCInstPrinter);
+ }
// Register the asm backend.
- TargetRegistry::RegisterMCAsmBackend(TheAArch64leTarget,
- createAArch64leAsmBackend);
+ for (Target *T : {&TheAArch64leTarget, &TheARM64Target})
+ TargetRegistry::RegisterMCAsmBackend(*T, createAArch64leAsmBackend);
TargetRegistry::RegisterMCAsmBackend(TheAArch64beTarget,
createAArch64beAsmBackend);
-
- // Register the object streamer.
- TargetRegistry::RegisterMCObjectStreamer(TheAArch64leTarget,
- createMCStreamer);
- TargetRegistry::RegisterMCObjectStreamer(TheAArch64beTarget,
- createMCStreamer);
-
- // Register the MCInstPrinter.
- TargetRegistry::RegisterMCInstPrinter(TheAArch64leTarget,
- createAArch64MCInstPrinter);
- TargetRegistry::RegisterMCInstPrinter(TheAArch64beTarget,
- createAArch64MCInstPrinter);
}