100c6e984SKazushi (Jam) Marukawa //===-- VETargetMachine.cpp - Define TargetMachine for VE -----------------===//
200c6e984SKazushi (Jam) Marukawa //
300c6e984SKazushi (Jam) Marukawa // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
400c6e984SKazushi (Jam) Marukawa // See https://llvm.org/LICENSE.txt for license information.
500c6e984SKazushi (Jam) Marukawa // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
600c6e984SKazushi (Jam) Marukawa //
700c6e984SKazushi (Jam) Marukawa //===----------------------------------------------------------------------===//
800c6e984SKazushi (Jam) Marukawa //
900c6e984SKazushi (Jam) Marukawa //
1000c6e984SKazushi (Jam) Marukawa //===----------------------------------------------------------------------===//
1100c6e984SKazushi (Jam) Marukawa 
1200c6e984SKazushi (Jam) Marukawa #include "VETargetMachine.h"
13d8816261SKazushi (Jam) Marukawa #include "TargetInfo/VETargetInfo.h"
1400c6e984SKazushi (Jam) Marukawa #include "VE.h"
15064859bdSKazushi (Jam) Marukawa #include "VETargetTransformInfo.h"
16064859bdSKazushi (Jam) Marukawa #include "llvm/CodeGen/Passes.h"
17064859bdSKazushi (Jam) Marukawa #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
18064859bdSKazushi (Jam) Marukawa #include "llvm/CodeGen/TargetPassConfig.h"
19064859bdSKazushi (Jam) Marukawa #include "llvm/IR/LegacyPassManager.h"
2089b57061SReid Kleckner #include "llvm/MC/TargetRegistry.h"
2100c6e984SKazushi (Jam) Marukawa 
2200c6e984SKazushi (Jam) Marukawa using namespace llvm;
2300c6e984SKazushi (Jam) Marukawa 
2400c6e984SKazushi (Jam) Marukawa #define DEBUG_TYPE "ve"
2500c6e984SKazushi (Jam) Marukawa 
LLVMInitializeVETarget()261eb812e0SSergei Trofimovich extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeVETarget() {
2700c6e984SKazushi (Jam) Marukawa   // Register the target.
2800c6e984SKazushi (Jam) Marukawa   RegisterTargetMachine<VETargetMachine> X(getTheVETarget());
2900c6e984SKazushi (Jam) Marukawa }
3000c6e984SKazushi (Jam) Marukawa 
computeDataLayout(const Triple & T)3100c6e984SKazushi (Jam) Marukawa static std::string computeDataLayout(const Triple &T) {
3200c6e984SKazushi (Jam) Marukawa   // Aurora VE is little endian
3300c6e984SKazushi (Jam) Marukawa   std::string Ret = "e";
3400c6e984SKazushi (Jam) Marukawa 
3500c6e984SKazushi (Jam) Marukawa   // Use ELF mangling
3600c6e984SKazushi (Jam) Marukawa   Ret += "-m:e";
3700c6e984SKazushi (Jam) Marukawa 
3800c6e984SKazushi (Jam) Marukawa   // Alignments for 64 bit integers.
3900c6e984SKazushi (Jam) Marukawa   Ret += "-i64:64";
4000c6e984SKazushi (Jam) Marukawa 
4100c6e984SKazushi (Jam) Marukawa   // VE supports 32 bit and 64 bits integer on registers
4200c6e984SKazushi (Jam) Marukawa   Ret += "-n32:64";
4300c6e984SKazushi (Jam) Marukawa 
44df3bda04SKazushi (Jam) Marukawa   // Stack alignment is 128 bits
45df3bda04SKazushi (Jam) Marukawa   Ret += "-S128";
4600c6e984SKazushi (Jam) Marukawa 
4733eac0f2SKazushi (Jam) Marukawa   // Vector alignments are 64 bits
4833eac0f2SKazushi (Jam) Marukawa   // Need to define all of them.  Otherwise, each alignment becomes
4933eac0f2SKazushi (Jam) Marukawa   // the size of each data by default.
5033eac0f2SKazushi (Jam) Marukawa   Ret += "-v64:64:64"; // for v2f32
5133eac0f2SKazushi (Jam) Marukawa   Ret += "-v128:64:64";
5233eac0f2SKazushi (Jam) Marukawa   Ret += "-v256:64:64";
5333eac0f2SKazushi (Jam) Marukawa   Ret += "-v512:64:64";
5433eac0f2SKazushi (Jam) Marukawa   Ret += "-v1024:64:64";
5533eac0f2SKazushi (Jam) Marukawa   Ret += "-v2048:64:64";
5633eac0f2SKazushi (Jam) Marukawa   Ret += "-v4096:64:64";
5733eac0f2SKazushi (Jam) Marukawa   Ret += "-v8192:64:64";
5833eac0f2SKazushi (Jam) Marukawa   Ret += "-v16384:64:64"; // for v256f64
5933eac0f2SKazushi (Jam) Marukawa 
6000c6e984SKazushi (Jam) Marukawa   return Ret;
6100c6e984SKazushi (Jam) Marukawa }
6200c6e984SKazushi (Jam) Marukawa 
getEffectiveRelocModel(Optional<Reloc::Model> RM)6300c6e984SKazushi (Jam) Marukawa static Reloc::Model getEffectiveRelocModel(Optional<Reloc::Model> RM) {
64*129b531cSKazu Hirata   return RM.value_or(Reloc::Static);
6500c6e984SKazushi (Jam) Marukawa }
6600c6e984SKazushi (Jam) Marukawa 
67064859bdSKazushi (Jam) Marukawa class VEELFTargetObjectFile : public TargetLoweringObjectFileELF {
Initialize(MCContext & Ctx,const TargetMachine & TM)68064859bdSKazushi (Jam) Marukawa   void Initialize(MCContext &Ctx, const TargetMachine &TM) override {
69064859bdSKazushi (Jam) Marukawa     TargetLoweringObjectFileELF::Initialize(Ctx, TM);
70064859bdSKazushi (Jam) Marukawa     InitializeELF(TM.Options.UseInitArray);
71064859bdSKazushi (Jam) Marukawa   }
72064859bdSKazushi (Jam) Marukawa };
73064859bdSKazushi (Jam) Marukawa 
createTLOF()74064859bdSKazushi (Jam) Marukawa static std::unique_ptr<TargetLoweringObjectFile> createTLOF() {
75064859bdSKazushi (Jam) Marukawa   return std::make_unique<VEELFTargetObjectFile>();
76064859bdSKazushi (Jam) Marukawa }
77064859bdSKazushi (Jam) Marukawa 
7800c6e984SKazushi (Jam) Marukawa /// Create an Aurora VE architecture model
VETargetMachine(const Target & T,const Triple & TT,StringRef CPU,StringRef FS,const TargetOptions & Options,Optional<Reloc::Model> RM,Optional<CodeModel::Model> CM,CodeGenOpt::Level OL,bool JIT)79064859bdSKazushi (Jam) Marukawa VETargetMachine::VETargetMachine(const Target &T, const Triple &TT,
80064859bdSKazushi (Jam) Marukawa                                  StringRef CPU, StringRef FS,
81064859bdSKazushi (Jam) Marukawa                                  const TargetOptions &Options,
82064859bdSKazushi (Jam) Marukawa                                  Optional<Reloc::Model> RM,
83064859bdSKazushi (Jam) Marukawa                                  Optional<CodeModel::Model> CM,
84064859bdSKazushi (Jam) Marukawa                                  CodeGenOpt::Level OL, bool JIT)
85064859bdSKazushi (Jam) Marukawa     : LLVMTargetMachine(T, computeDataLayout(TT), TT, CPU, FS, Options,
8600c6e984SKazushi (Jam) Marukawa                         getEffectiveRelocModel(RM),
87064859bdSKazushi (Jam) Marukawa                         getEffectiveCodeModel(CM, CodeModel::Small), OL),
88d53840adSSimon Moll       TLOF(createTLOF()),
89d53840adSSimon Moll       Subtarget(TT, std::string(CPU), std::string(FS), *this) {
90064859bdSKazushi (Jam) Marukawa   initAsmInfo();
91064859bdSKazushi (Jam) Marukawa }
9200c6e984SKazushi (Jam) Marukawa 
933a3cb929SKazu Hirata VETargetMachine::~VETargetMachine() = default;
94064859bdSKazushi (Jam) Marukawa 
95c4b1a63aSJameson Nash TargetTransformInfo
getTargetTransformInfo(const Function & F) const96c4b1a63aSJameson Nash VETargetMachine::getTargetTransformInfo(const Function &F) const {
97064859bdSKazushi (Jam) Marukawa   return TargetTransformInfo(VETTIImpl(this, F));
98064859bdSKazushi (Jam) Marukawa }
99064859bdSKazushi (Jam) Marukawa 
100064859bdSKazushi (Jam) Marukawa namespace {
101064859bdSKazushi (Jam) Marukawa /// VE Code Generator Pass Configuration Options.
102064859bdSKazushi (Jam) Marukawa class VEPassConfig : public TargetPassConfig {
103064859bdSKazushi (Jam) Marukawa public:
VEPassConfig(VETargetMachine & TM,PassManagerBase & PM)104064859bdSKazushi (Jam) Marukawa   VEPassConfig(VETargetMachine &TM, PassManagerBase &PM)
105064859bdSKazushi (Jam) Marukawa       : TargetPassConfig(TM, PM) {}
106064859bdSKazushi (Jam) Marukawa 
getVETargetMachine() const107064859bdSKazushi (Jam) Marukawa   VETargetMachine &getVETargetMachine() const {
108064859bdSKazushi (Jam) Marukawa     return getTM<VETargetMachine>();
109064859bdSKazushi (Jam) Marukawa   }
110064859bdSKazushi (Jam) Marukawa 
111f32992adSKazushi (Jam) Marukawa   void addIRPasses() override;
112064859bdSKazushi (Jam) Marukawa   bool addInstSelector() override;
1131c00d096SSimon Moll   void addPreEmitPass() override;
114064859bdSKazushi (Jam) Marukawa };
115064859bdSKazushi (Jam) Marukawa } // namespace
116064859bdSKazushi (Jam) Marukawa 
createPassConfig(PassManagerBase & PM)117064859bdSKazushi (Jam) Marukawa TargetPassConfig *VETargetMachine::createPassConfig(PassManagerBase &PM) {
118064859bdSKazushi (Jam) Marukawa   return new VEPassConfig(*this, PM);
119064859bdSKazushi (Jam) Marukawa }
120064859bdSKazushi (Jam) Marukawa 
addIRPasses()121f32992adSKazushi (Jam) Marukawa void VEPassConfig::addIRPasses() {
122f32992adSKazushi (Jam) Marukawa   // VE requires atomic expand pass.
123f32992adSKazushi (Jam) Marukawa   addPass(createAtomicExpandPass());
124f32992adSKazushi (Jam) Marukawa   TargetPassConfig::addIRPasses();
125f32992adSKazushi (Jam) Marukawa }
126f32992adSKazushi (Jam) Marukawa 
addInstSelector()127064859bdSKazushi (Jam) Marukawa bool VEPassConfig::addInstSelector() {
128064859bdSKazushi (Jam) Marukawa   addPass(createVEISelDag(getVETargetMachine()));
129064859bdSKazushi (Jam) Marukawa   return false;
130064859bdSKazushi (Jam) Marukawa }
1311c00d096SSimon Moll 
addPreEmitPass()1321c00d096SSimon Moll void VEPassConfig::addPreEmitPass() {
1331c00d096SSimon Moll   // LVLGen should be called after scheduling and register allocation
1341c00d096SSimon Moll   addPass(createLVLGenPass());
1351c00d096SSimon Moll }
136