1*480093f4SDimitry Andric //===-- VETargetMachine.cpp - Define TargetMachine for VE -----------------===// 2*480093f4SDimitry Andric // 3*480093f4SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*480093f4SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*480093f4SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*480093f4SDimitry Andric // 7*480093f4SDimitry Andric //===----------------------------------------------------------------------===// 8*480093f4SDimitry Andric // 9*480093f4SDimitry Andric // 10*480093f4SDimitry Andric //===----------------------------------------------------------------------===// 11*480093f4SDimitry Andric 12*480093f4SDimitry Andric #include "VETargetMachine.h" 13*480093f4SDimitry Andric #include "VE.h" 14*480093f4SDimitry Andric #include "VETargetTransformInfo.h" 15*480093f4SDimitry Andric #include "llvm/CodeGen/Passes.h" 16*480093f4SDimitry Andric #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" 17*480093f4SDimitry Andric #include "llvm/CodeGen/TargetPassConfig.h" 18*480093f4SDimitry Andric #include "llvm/IR/LegacyPassManager.h" 19*480093f4SDimitry Andric #include "llvm/Support/TargetRegistry.h" 20*480093f4SDimitry Andric 21*480093f4SDimitry Andric using namespace llvm; 22*480093f4SDimitry Andric 23*480093f4SDimitry Andric #define DEBUG_TYPE "ve" 24*480093f4SDimitry Andric 25*480093f4SDimitry Andric extern "C" void LLVMInitializeVETarget() { 26*480093f4SDimitry Andric // Register the target. 27*480093f4SDimitry Andric RegisterTargetMachine<VETargetMachine> X(getTheVETarget()); 28*480093f4SDimitry Andric } 29*480093f4SDimitry Andric 30*480093f4SDimitry Andric static std::string computeDataLayout(const Triple &T) { 31*480093f4SDimitry Andric // Aurora VE is little endian 32*480093f4SDimitry Andric std::string Ret = "e"; 33*480093f4SDimitry Andric 34*480093f4SDimitry Andric // Use ELF mangling 35*480093f4SDimitry Andric Ret += "-m:e"; 36*480093f4SDimitry Andric 37*480093f4SDimitry Andric // Alignments for 64 bit integers. 38*480093f4SDimitry Andric Ret += "-i64:64"; 39*480093f4SDimitry Andric 40*480093f4SDimitry Andric // VE supports 32 bit and 64 bits integer on registers 41*480093f4SDimitry Andric Ret += "-n32:64"; 42*480093f4SDimitry Andric 43*480093f4SDimitry Andric // Stack alignment is 64 bits 44*480093f4SDimitry Andric Ret += "-S64"; 45*480093f4SDimitry Andric 46*480093f4SDimitry Andric return Ret; 47*480093f4SDimitry Andric } 48*480093f4SDimitry Andric 49*480093f4SDimitry Andric static Reloc::Model getEffectiveRelocModel(Optional<Reloc::Model> RM) { 50*480093f4SDimitry Andric if (!RM.hasValue()) 51*480093f4SDimitry Andric return Reloc::Static; 52*480093f4SDimitry Andric return *RM; 53*480093f4SDimitry Andric } 54*480093f4SDimitry Andric 55*480093f4SDimitry Andric class VEELFTargetObjectFile : public TargetLoweringObjectFileELF { 56*480093f4SDimitry Andric void Initialize(MCContext &Ctx, const TargetMachine &TM) override { 57*480093f4SDimitry Andric TargetLoweringObjectFileELF::Initialize(Ctx, TM); 58*480093f4SDimitry Andric InitializeELF(TM.Options.UseInitArray); 59*480093f4SDimitry Andric } 60*480093f4SDimitry Andric }; 61*480093f4SDimitry Andric 62*480093f4SDimitry Andric static std::unique_ptr<TargetLoweringObjectFile> createTLOF() { 63*480093f4SDimitry Andric return std::make_unique<VEELFTargetObjectFile>(); 64*480093f4SDimitry Andric } 65*480093f4SDimitry Andric 66*480093f4SDimitry Andric /// Create an Aurora VE architecture model 67*480093f4SDimitry Andric VETargetMachine::VETargetMachine(const Target &T, const Triple &TT, 68*480093f4SDimitry Andric StringRef CPU, StringRef FS, 69*480093f4SDimitry Andric const TargetOptions &Options, 70*480093f4SDimitry Andric Optional<Reloc::Model> RM, 71*480093f4SDimitry Andric Optional<CodeModel::Model> CM, 72*480093f4SDimitry Andric CodeGenOpt::Level OL, bool JIT) 73*480093f4SDimitry Andric : LLVMTargetMachine(T, computeDataLayout(TT), TT, CPU, FS, Options, 74*480093f4SDimitry Andric getEffectiveRelocModel(RM), 75*480093f4SDimitry Andric getEffectiveCodeModel(CM, CodeModel::Small), OL), 76*480093f4SDimitry Andric TLOF(createTLOF()), Subtarget(TT, CPU, FS, *this) { 77*480093f4SDimitry Andric initAsmInfo(); 78*480093f4SDimitry Andric } 79*480093f4SDimitry Andric 80*480093f4SDimitry Andric VETargetMachine::~VETargetMachine() {} 81*480093f4SDimitry Andric 82*480093f4SDimitry Andric TargetTransformInfo VETargetMachine::getTargetTransformInfo(const Function &F) { 83*480093f4SDimitry Andric return TargetTransformInfo(VETTIImpl(this, F)); 84*480093f4SDimitry Andric } 85*480093f4SDimitry Andric 86*480093f4SDimitry Andric namespace { 87*480093f4SDimitry Andric /// VE Code Generator Pass Configuration Options. 88*480093f4SDimitry Andric class VEPassConfig : public TargetPassConfig { 89*480093f4SDimitry Andric public: 90*480093f4SDimitry Andric VEPassConfig(VETargetMachine &TM, PassManagerBase &PM) 91*480093f4SDimitry Andric : TargetPassConfig(TM, PM) {} 92*480093f4SDimitry Andric 93*480093f4SDimitry Andric VETargetMachine &getVETargetMachine() const { 94*480093f4SDimitry Andric return getTM<VETargetMachine>(); 95*480093f4SDimitry Andric } 96*480093f4SDimitry Andric 97*480093f4SDimitry Andric bool addInstSelector() override; 98*480093f4SDimitry Andric }; 99*480093f4SDimitry Andric } // namespace 100*480093f4SDimitry Andric 101*480093f4SDimitry Andric TargetPassConfig *VETargetMachine::createPassConfig(PassManagerBase &PM) { 102*480093f4SDimitry Andric return new VEPassConfig(*this, PM); 103*480093f4SDimitry Andric } 104*480093f4SDimitry Andric 105*480093f4SDimitry Andric bool VEPassConfig::addInstSelector() { 106*480093f4SDimitry Andric addPass(createVEISelDag(getVETargetMachine())); 107*480093f4SDimitry Andric return false; 108*480093f4SDimitry Andric } 109