172062f5744557e270a38192554c3126ea5f97434Tim Northover//===-- AArch64MCTargetDesc.cpp - AArch64 Target Descriptions -------------===//
272062f5744557e270a38192554c3126ea5f97434Tim Northover//
372062f5744557e270a38192554c3126ea5f97434Tim Northover//                     The LLVM Compiler Infrastructure
472062f5744557e270a38192554c3126ea5f97434Tim Northover//
572062f5744557e270a38192554c3126ea5f97434Tim Northover// This file is distributed under the University of Illinois Open Source
672062f5744557e270a38192554c3126ea5f97434Tim Northover// License. See LICENSE.TXT for details.
772062f5744557e270a38192554c3126ea5f97434Tim Northover//
872062f5744557e270a38192554c3126ea5f97434Tim Northover//===----------------------------------------------------------------------===//
972062f5744557e270a38192554c3126ea5f97434Tim Northover//
1072062f5744557e270a38192554c3126ea5f97434Tim Northover// This file provides AArch64 specific target descriptions.
1172062f5744557e270a38192554c3126ea5f97434Tim Northover//
1272062f5744557e270a38192554c3126ea5f97434Tim Northover//===----------------------------------------------------------------------===//
1372062f5744557e270a38192554c3126ea5f97434Tim Northover
1472062f5744557e270a38192554c3126ea5f97434Tim Northover#include "AArch64MCTargetDesc.h"
1572062f5744557e270a38192554c3126ea5f97434Tim Northover#include "AArch64ELFStreamer.h"
1672062f5744557e270a38192554c3126ea5f97434Tim Northover#include "AArch64MCAsmInfo.h"
1772062f5744557e270a38192554c3126ea5f97434Tim Northover#include "InstPrinter/AArch64InstPrinter.h"
1872062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/ADT/APInt.h"
1972062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/MC/MCCodeGenInfo.h"
2072062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/MC/MCInstrAnalysis.h"
2172062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/MC/MCInstrInfo.h"
2272062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/MC/MCRegisterInfo.h"
2372062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/MC/MCStreamer.h"
2472062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/MC/MCSubtargetInfo.h"
2572062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/Support/TargetRegistry.h"
2672062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/Support/ErrorHandling.h"
2772062f5744557e270a38192554c3126ea5f97434Tim Northover
2872062f5744557e270a38192554c3126ea5f97434Tim Northover#define GET_REGINFO_MC_DESC
2972062f5744557e270a38192554c3126ea5f97434Tim Northover#include "AArch64GenRegisterInfo.inc"
3072062f5744557e270a38192554c3126ea5f97434Tim Northover
3172062f5744557e270a38192554c3126ea5f97434Tim Northover#define GET_INSTRINFO_MC_DESC
3272062f5744557e270a38192554c3126ea5f97434Tim Northover#include "AArch64GenInstrInfo.inc"
3372062f5744557e270a38192554c3126ea5f97434Tim Northover
3472062f5744557e270a38192554c3126ea5f97434Tim Northover#define GET_SUBTARGETINFO_MC_DESC
3572062f5744557e270a38192554c3126ea5f97434Tim Northover#include "AArch64GenSubtargetInfo.inc"
3672062f5744557e270a38192554c3126ea5f97434Tim Northover
3772062f5744557e270a38192554c3126ea5f97434Tim Northoverusing namespace llvm;
3872062f5744557e270a38192554c3126ea5f97434Tim Northover
3972062f5744557e270a38192554c3126ea5f97434Tim NorthoverMCSubtargetInfo *AArch64_MC::createAArch64MCSubtargetInfo(StringRef TT,
4072062f5744557e270a38192554c3126ea5f97434Tim Northover                                                          StringRef CPU,
4172062f5744557e270a38192554c3126ea5f97434Tim Northover                                                          StringRef FS) {
4272062f5744557e270a38192554c3126ea5f97434Tim Northover  MCSubtargetInfo *X = new MCSubtargetInfo();
4372062f5744557e270a38192554c3126ea5f97434Tim Northover  InitAArch64MCSubtargetInfo(X, TT, CPU, "");
4472062f5744557e270a38192554c3126ea5f97434Tim Northover  return X;
4572062f5744557e270a38192554c3126ea5f97434Tim Northover}
4672062f5744557e270a38192554c3126ea5f97434Tim Northover
4772062f5744557e270a38192554c3126ea5f97434Tim Northover
4872062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic MCInstrInfo *createAArch64MCInstrInfo() {
4972062f5744557e270a38192554c3126ea5f97434Tim Northover  MCInstrInfo *X = new MCInstrInfo();
5072062f5744557e270a38192554c3126ea5f97434Tim Northover  InitAArch64MCInstrInfo(X);
5172062f5744557e270a38192554c3126ea5f97434Tim Northover  return X;
5272062f5744557e270a38192554c3126ea5f97434Tim Northover}
5372062f5744557e270a38192554c3126ea5f97434Tim Northover
5472062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic MCRegisterInfo *createAArch64MCRegisterInfo(StringRef Triple) {
5572062f5744557e270a38192554c3126ea5f97434Tim Northover  MCRegisterInfo *X = new MCRegisterInfo();
5672062f5744557e270a38192554c3126ea5f97434Tim Northover  InitAArch64MCRegisterInfo(X, AArch64::X30);
5772062f5744557e270a38192554c3126ea5f97434Tim Northover  return X;
5872062f5744557e270a38192554c3126ea5f97434Tim Northover}
5972062f5744557e270a38192554c3126ea5f97434Tim Northover
6072062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic MCAsmInfo *createAArch64MCAsmInfo(const Target &T, StringRef TT) {
6172062f5744557e270a38192554c3126ea5f97434Tim Northover  Triple TheTriple(TT);
6272062f5744557e270a38192554c3126ea5f97434Tim Northover
6372062f5744557e270a38192554c3126ea5f97434Tim Northover  MCAsmInfo *MAI = new AArch64ELFMCAsmInfo();
6472062f5744557e270a38192554c3126ea5f97434Tim Northover  MachineLocation Dst(MachineLocation::VirtualFP);
6572062f5744557e270a38192554c3126ea5f97434Tim Northover  MachineLocation Src(AArch64::XSP, 0);
6672062f5744557e270a38192554c3126ea5f97434Tim Northover  MAI->addInitialFrameState(0, Dst, Src);
6772062f5744557e270a38192554c3126ea5f97434Tim Northover
6872062f5744557e270a38192554c3126ea5f97434Tim Northover  return MAI;
6972062f5744557e270a38192554c3126ea5f97434Tim Northover}
7072062f5744557e270a38192554c3126ea5f97434Tim Northover
7172062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic MCCodeGenInfo *createAArch64MCCodeGenInfo(StringRef TT, Reloc::Model RM,
7272062f5744557e270a38192554c3126ea5f97434Tim Northover                                                 CodeModel::Model CM,
7372062f5744557e270a38192554c3126ea5f97434Tim Northover                                                 CodeGenOpt::Level OL) {
7472062f5744557e270a38192554c3126ea5f97434Tim Northover  MCCodeGenInfo *X = new MCCodeGenInfo();
7572062f5744557e270a38192554c3126ea5f97434Tim Northover  if (RM == Reloc::Default || RM == Reloc::DynamicNoPIC) {
7672062f5744557e270a38192554c3126ea5f97434Tim Northover    // On ELF platforms the default static relocation model has a smart enough
7772062f5744557e270a38192554c3126ea5f97434Tim Northover    // linker to cope with referencing external symbols defined in a shared
7872062f5744557e270a38192554c3126ea5f97434Tim Northover    // library. Hence DynamicNoPIC doesn't need to be promoted to PIC.
7972062f5744557e270a38192554c3126ea5f97434Tim Northover    RM = Reloc::Static;
8072062f5744557e270a38192554c3126ea5f97434Tim Northover  }
8172062f5744557e270a38192554c3126ea5f97434Tim Northover
8272062f5744557e270a38192554c3126ea5f97434Tim Northover  if (CM == CodeModel::Default)
8372062f5744557e270a38192554c3126ea5f97434Tim Northover    CM = CodeModel::Small;
8472062f5744557e270a38192554c3126ea5f97434Tim Northover
8572062f5744557e270a38192554c3126ea5f97434Tim Northover  X->InitMCCodeGenInfo(RM, CM, OL);
8672062f5744557e270a38192554c3126ea5f97434Tim Northover  return X;
8772062f5744557e270a38192554c3126ea5f97434Tim Northover}
8872062f5744557e270a38192554c3126ea5f97434Tim Northover
8972062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic MCStreamer *createMCStreamer(const Target &T, StringRef TT,
9072062f5744557e270a38192554c3126ea5f97434Tim Northover                                    MCContext &Ctx, MCAsmBackend &MAB,
9172062f5744557e270a38192554c3126ea5f97434Tim Northover                                    raw_ostream &OS,
9272062f5744557e270a38192554c3126ea5f97434Tim Northover                                    MCCodeEmitter *Emitter,
9372062f5744557e270a38192554c3126ea5f97434Tim Northover                                    bool RelaxAll,
9472062f5744557e270a38192554c3126ea5f97434Tim Northover                                    bool NoExecStack) {
9572062f5744557e270a38192554c3126ea5f97434Tim Northover  Triple TheTriple(TT);
9672062f5744557e270a38192554c3126ea5f97434Tim Northover
9772062f5744557e270a38192554c3126ea5f97434Tim Northover  return createAArch64ELFStreamer(Ctx, MAB, OS, Emitter, RelaxAll, NoExecStack);
9872062f5744557e270a38192554c3126ea5f97434Tim Northover}
9972062f5744557e270a38192554c3126ea5f97434Tim Northover
10072062f5744557e270a38192554c3126ea5f97434Tim Northover
10172062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic MCInstPrinter *createAArch64MCInstPrinter(const Target &T,
10272062f5744557e270a38192554c3126ea5f97434Tim Northover                                                 unsigned SyntaxVariant,
10372062f5744557e270a38192554c3126ea5f97434Tim Northover                                                 const MCAsmInfo &MAI,
10472062f5744557e270a38192554c3126ea5f97434Tim Northover                                                 const MCInstrInfo &MII,
10572062f5744557e270a38192554c3126ea5f97434Tim Northover                                                 const MCRegisterInfo &MRI,
10672062f5744557e270a38192554c3126ea5f97434Tim Northover                                                 const MCSubtargetInfo &STI) {
10772062f5744557e270a38192554c3126ea5f97434Tim Northover  if (SyntaxVariant == 0)
10872062f5744557e270a38192554c3126ea5f97434Tim Northover    return new AArch64InstPrinter(MAI, MII, MRI, STI);
10972062f5744557e270a38192554c3126ea5f97434Tim Northover  return 0;
11072062f5744557e270a38192554c3126ea5f97434Tim Northover}
11172062f5744557e270a38192554c3126ea5f97434Tim Northover
11272062f5744557e270a38192554c3126ea5f97434Tim Northovernamespace {
11372062f5744557e270a38192554c3126ea5f97434Tim Northover
11472062f5744557e270a38192554c3126ea5f97434Tim Northoverclass AArch64MCInstrAnalysis : public MCInstrAnalysis {
11572062f5744557e270a38192554c3126ea5f97434Tim Northoverpublic:
11672062f5744557e270a38192554c3126ea5f97434Tim Northover  AArch64MCInstrAnalysis(const MCInstrInfo *Info) : MCInstrAnalysis(Info) {}
11772062f5744557e270a38192554c3126ea5f97434Tim Northover
11872062f5744557e270a38192554c3126ea5f97434Tim Northover  virtual bool isUnconditionalBranch(const MCInst &Inst) const {
11972062f5744557e270a38192554c3126ea5f97434Tim Northover    if (Inst.getOpcode() == AArch64::Bcc
12072062f5744557e270a38192554c3126ea5f97434Tim Northover        && Inst.getOperand(0).getImm() == A64CC::AL)
12172062f5744557e270a38192554c3126ea5f97434Tim Northover      return true;
12272062f5744557e270a38192554c3126ea5f97434Tim Northover    return MCInstrAnalysis::isUnconditionalBranch(Inst);
12372062f5744557e270a38192554c3126ea5f97434Tim Northover  }
12472062f5744557e270a38192554c3126ea5f97434Tim Northover
12572062f5744557e270a38192554c3126ea5f97434Tim Northover  virtual bool isConditionalBranch(const MCInst &Inst) const {
12672062f5744557e270a38192554c3126ea5f97434Tim Northover    if (Inst.getOpcode() == AArch64::Bcc
12772062f5744557e270a38192554c3126ea5f97434Tim Northover        && Inst.getOperand(0).getImm() == A64CC::AL)
12872062f5744557e270a38192554c3126ea5f97434Tim Northover      return false;
12972062f5744557e270a38192554c3126ea5f97434Tim Northover    return MCInstrAnalysis::isConditionalBranch(Inst);
13072062f5744557e270a38192554c3126ea5f97434Tim Northover  }
13172062f5744557e270a38192554c3126ea5f97434Tim Northover
13272062f5744557e270a38192554c3126ea5f97434Tim Northover  uint64_t evaluateBranch(const MCInst &Inst, uint64_t Addr,
13372062f5744557e270a38192554c3126ea5f97434Tim Northover                          uint64_t Size) const {
13472062f5744557e270a38192554c3126ea5f97434Tim Northover    unsigned LblOperand = Inst.getOpcode() == AArch64::Bcc ? 1 : 0;
13572062f5744557e270a38192554c3126ea5f97434Tim Northover    // FIXME: We only handle PCRel branches for now.
13672062f5744557e270a38192554c3126ea5f97434Tim Northover    if (Info->get(Inst.getOpcode()).OpInfo[LblOperand].OperandType
13772062f5744557e270a38192554c3126ea5f97434Tim Northover        != MCOI::OPERAND_PCREL)
13872062f5744557e270a38192554c3126ea5f97434Tim Northover      return -1ULL;
13972062f5744557e270a38192554c3126ea5f97434Tim Northover
14072062f5744557e270a38192554c3126ea5f97434Tim Northover    int64_t Imm = Inst.getOperand(LblOperand).getImm();
14172062f5744557e270a38192554c3126ea5f97434Tim Northover
14272062f5744557e270a38192554c3126ea5f97434Tim Northover    return Addr + Imm;
14372062f5744557e270a38192554c3126ea5f97434Tim Northover  }
14472062f5744557e270a38192554c3126ea5f97434Tim Northover};
14572062f5744557e270a38192554c3126ea5f97434Tim Northover
14672062f5744557e270a38192554c3126ea5f97434Tim Northover}
14772062f5744557e270a38192554c3126ea5f97434Tim Northover
14872062f5744557e270a38192554c3126ea5f97434Tim Northoverstatic MCInstrAnalysis *createAArch64MCInstrAnalysis(const MCInstrInfo *Info) {
14972062f5744557e270a38192554c3126ea5f97434Tim Northover  return new AArch64MCInstrAnalysis(Info);
15072062f5744557e270a38192554c3126ea5f97434Tim Northover}
15172062f5744557e270a38192554c3126ea5f97434Tim Northover
15272062f5744557e270a38192554c3126ea5f97434Tim Northover
15372062f5744557e270a38192554c3126ea5f97434Tim Northover
15472062f5744557e270a38192554c3126ea5f97434Tim Northoverextern "C" void LLVMInitializeAArch64TargetMC() {
15572062f5744557e270a38192554c3126ea5f97434Tim Northover  // Register the MC asm info.
15672062f5744557e270a38192554c3126ea5f97434Tim Northover  RegisterMCAsmInfoFn A(TheAArch64Target, createAArch64MCAsmInfo);
15772062f5744557e270a38192554c3126ea5f97434Tim Northover
15872062f5744557e270a38192554c3126ea5f97434Tim Northover  // Register the MC codegen info.
15972062f5744557e270a38192554c3126ea5f97434Tim Northover  TargetRegistry::RegisterMCCodeGenInfo(TheAArch64Target,
16072062f5744557e270a38192554c3126ea5f97434Tim Northover                                        createAArch64MCCodeGenInfo);
16172062f5744557e270a38192554c3126ea5f97434Tim Northover
16272062f5744557e270a38192554c3126ea5f97434Tim Northover  // Register the MC instruction info.
16372062f5744557e270a38192554c3126ea5f97434Tim Northover  TargetRegistry::RegisterMCInstrInfo(TheAArch64Target,
16472062f5744557e270a38192554c3126ea5f97434Tim Northover                                      createAArch64MCInstrInfo);
16572062f5744557e270a38192554c3126ea5f97434Tim Northover
16672062f5744557e270a38192554c3126ea5f97434Tim Northover  // Register the MC register info.
16772062f5744557e270a38192554c3126ea5f97434Tim Northover  TargetRegistry::RegisterMCRegInfo(TheAArch64Target,
16872062f5744557e270a38192554c3126ea5f97434Tim Northover                                    createAArch64MCRegisterInfo);
16972062f5744557e270a38192554c3126ea5f97434Tim Northover
17072062f5744557e270a38192554c3126ea5f97434Tim Northover  // Register the MC subtarget info.
17172062f5744557e270a38192554c3126ea5f97434Tim Northover  using AArch64_MC::createAArch64MCSubtargetInfo;
17272062f5744557e270a38192554c3126ea5f97434Tim Northover  TargetRegistry::RegisterMCSubtargetInfo(TheAArch64Target,
17372062f5744557e270a38192554c3126ea5f97434Tim Northover                                          createAArch64MCSubtargetInfo);
17472062f5744557e270a38192554c3126ea5f97434Tim Northover
17572062f5744557e270a38192554c3126ea5f97434Tim Northover  // Register the MC instruction analyzer.
17672062f5744557e270a38192554c3126ea5f97434Tim Northover  TargetRegistry::RegisterMCInstrAnalysis(TheAArch64Target,
17772062f5744557e270a38192554c3126ea5f97434Tim Northover                                          createAArch64MCInstrAnalysis);
17872062f5744557e270a38192554c3126ea5f97434Tim Northover
17972062f5744557e270a38192554c3126ea5f97434Tim Northover  // Register the MC Code Emitter
18072062f5744557e270a38192554c3126ea5f97434Tim Northover  TargetRegistry::RegisterMCCodeEmitter(TheAArch64Target,
18172062f5744557e270a38192554c3126ea5f97434Tim Northover                                        createAArch64MCCodeEmitter);
18272062f5744557e270a38192554c3126ea5f97434Tim Northover
18372062f5744557e270a38192554c3126ea5f97434Tim Northover  // Register the asm backend.
18472062f5744557e270a38192554c3126ea5f97434Tim Northover  TargetRegistry::RegisterMCAsmBackend(TheAArch64Target,
18572062f5744557e270a38192554c3126ea5f97434Tim Northover                                       createAArch64AsmBackend);
18672062f5744557e270a38192554c3126ea5f97434Tim Northover
18772062f5744557e270a38192554c3126ea5f97434Tim Northover  // Register the object streamer.
18872062f5744557e270a38192554c3126ea5f97434Tim Northover  TargetRegistry::RegisterMCObjectStreamer(TheAArch64Target,
18972062f5744557e270a38192554c3126ea5f97434Tim Northover                                           createMCStreamer);
19072062f5744557e270a38192554c3126ea5f97434Tim Northover
19172062f5744557e270a38192554c3126ea5f97434Tim Northover  // Register the MCInstPrinter.
19272062f5744557e270a38192554c3126ea5f97434Tim Northover  TargetRegistry::RegisterMCInstPrinter(TheAArch64Target,
19372062f5744557e270a38192554c3126ea5f97434Tim Northover                                        createAArch64MCInstPrinter);
19472062f5744557e270a38192554c3126ea5f97434Tim Northover}
195